From 0bfcf658db23161491cde8f00f13b55a0d480f1a Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 24 Feb 2020 18:33:59 +0100 Subject: [PATCH 001/197] Allow multiple spaces after attribute in location header --- app/hlds/hlds.tatsu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/hlds/hlds.tatsu b/app/hlds/hlds.tatsu index 62538b2..6bc8e0d 100644 --- a/app/hlds/hlds.tatsu +++ b/app/hlds/hlds.tatsu @@ -22,7 +22,7 @@ location_header = ; location_attribute = - n '\t' key:identifier ' ' value:string + n '\t' key:identifier s value:string ; location = >location_header items:{ block } ; -- 2.43.4 From e54a89e12cc7bdab71bf614eda59309d7d1bfd6d Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 24 Feb 2020 21:04:57 +0100 Subject: [PATCH 002/197] Change `telephone` to `phone` --- app/hlds/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index a5e3e24..a6e452d 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -47,7 +47,7 @@ class HldsSemanticActions: dishes=dishes, osm=attributes.get("osm"), address=attributes.get("address"), - telephone=attributes.get("telephone"), + telephone=attributes.get("phone"), website=attributes.get("website"), ) -- 2.43.4 From 841f98bd51a5849850607aed381137d7e5fb3483 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 24 Feb 2020 21:05:15 +0100 Subject: [PATCH 003/197] Add HLDS documentation --- data/README.md | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 data/README.md diff --git a/data/README.md b/data/README.md new file mode 100644 index 0000000..c489a4a --- /dev/null +++ b/data/README.md @@ -0,0 +1,99 @@ +# HLDS data format + +HLDS is the Haldis Language for Describing Servings. It defines the menu you see when ordering in +Haldis. + +There is syntax highlighting support for editors in `etc/` in the Haldis repository. + +## Indentation +Indentation requires hard **tabs**. Spaces will not work. + +## Identifiers +You must choose an identifier for each location, dish, choice and option. Identifiers may consist +of numbers, hyphens, underscores and lowercase letters. + +* Good: `my_identifier-007` +* Bad: ~~`My Identifié 007`~~ + +## Locations + +A HLDS file consists of one or more locations. Each location starts with a header, which enclosed +in "fences" of at least three equal signs. The first line of the header contains the ID and name of +the location. Further lines contain the metadata of the location, such as the phone number and +OpenStreetMap element. In the future, the phone number and such will be fetched from OpenStreetMap. + +```hlds +========================== +ocean_garden: Ocean Garden + osm https://www.openstreetmap.org/node/2275105003 + phone +32 9 222 72 74 + address Zwijnaardsesteenweg 399, 9000 Gent + website http://oceangarden.byethost3.com/ + # Comments are allowed too! +========================== +``` + +## Dishes + +A location consists of dishes. Spaces can be used to align the elements of your dish (but that's +not required). + +```hlds +dish cheeseburger: Cheeseburger € 2.9 +dish assortment: Twijfelaar € 3 +``` + +## Inline choices +Dishes can contain choices. There are two types: +* `single_choice` is a required choice where the user must choose one option. +* `multi_choice` is an optional choice where the user can choose zero or more options. + +```hlds +dish fries: Frietjes + single_choice size: Formaat + extra_small: Extra small € 1.8 + small: Small € 2 + medium: Medium € 2.5 + large: Large € 3.3 + multi_choice sauce: Saus + ketchup: Ketchup € 1.4 + mayo: Mayonaise € 1.4 + bicky: Bickysaus € 1.4 + stew: Stoofvleessaus € 1.9 +``` + +## Common choices +Choices that are used more than once, can be declared once and referenced in multiple dishes. + +```hlds +bami_nasi: Bami of nasi + bami: Bami + nasi: Nasi + +dish wok3: Studentenwok 3 kip bami/nasi zonder saus € 6 + single_choice bami_nasi + +dish wok5: Studentenwok 5 babi pangang € 6 + single_choice bami_nasi +``` + +## Descriptions +You can add descriptions to dishes, choices and options. Separate name and description with ` -- `. + +```hlds +dish dishid: Name -- This is a description € 3 +``` + +## Tags + +**Note:** HLDS tags are not supported in Haldis yet. You can ignore them. + +You can add tags after ` :: `. Tags are `{identifier}`. You can use tags to attach more information +about a dish or option in a structured way. For example: `{has_meat}` signals to vegetarians that +they should avoid this. + +The order is always id, name, description, tags, price (not all have to be present of course). + +```hlds +dish dishid: Name -- This is a description :: {has_meat} € 3 +``` -- 2.43.4 From 5c08ecca1b444e17c61bfdf931858a301f0abac5 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 24 Feb 2020 21:54:16 +0100 Subject: [PATCH 004/197] Rename VS Code syntax directory --- etc/{hlds => vscode}/.vscodeignore | 0 etc/{hlds => vscode}/CHANGELOG.md | 0 etc/{hlds => vscode}/README.md | 0 etc/{hlds => vscode}/hlds.vsix | Bin etc/{hlds => vscode}/language-configuration.json | 0 etc/{hlds => vscode}/package.json | 0 etc/{hlds => vscode}/syntaxes/hlds.tmLanguage.json | 0 etc/{hlds => vscode}/syntaxes/injections.json | 0 etc/{hlds => vscode}/vsc-extension-quickstart.md | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename etc/{hlds => vscode}/.vscodeignore (100%) rename etc/{hlds => vscode}/CHANGELOG.md (100%) rename etc/{hlds => vscode}/README.md (100%) rename etc/{hlds => vscode}/hlds.vsix (100%) rename etc/{hlds => vscode}/language-configuration.json (100%) rename etc/{hlds => vscode}/package.json (100%) rename etc/{hlds => vscode}/syntaxes/hlds.tmLanguage.json (100%) rename etc/{hlds => vscode}/syntaxes/injections.json (100%) rename etc/{hlds => vscode}/vsc-extension-quickstart.md (100%) diff --git a/etc/hlds/.vscodeignore b/etc/vscode/.vscodeignore similarity index 100% rename from etc/hlds/.vscodeignore rename to etc/vscode/.vscodeignore diff --git a/etc/hlds/CHANGELOG.md b/etc/vscode/CHANGELOG.md similarity index 100% rename from etc/hlds/CHANGELOG.md rename to etc/vscode/CHANGELOG.md diff --git a/etc/hlds/README.md b/etc/vscode/README.md similarity index 100% rename from etc/hlds/README.md rename to etc/vscode/README.md diff --git a/etc/hlds/hlds.vsix b/etc/vscode/hlds.vsix similarity index 100% rename from etc/hlds/hlds.vsix rename to etc/vscode/hlds.vsix diff --git a/etc/hlds/language-configuration.json b/etc/vscode/language-configuration.json similarity index 100% rename from etc/hlds/language-configuration.json rename to etc/vscode/language-configuration.json diff --git a/etc/hlds/package.json b/etc/vscode/package.json similarity index 100% rename from etc/hlds/package.json rename to etc/vscode/package.json diff --git a/etc/hlds/syntaxes/hlds.tmLanguage.json b/etc/vscode/syntaxes/hlds.tmLanguage.json similarity index 100% rename from etc/hlds/syntaxes/hlds.tmLanguage.json rename to etc/vscode/syntaxes/hlds.tmLanguage.json diff --git a/etc/hlds/syntaxes/injections.json b/etc/vscode/syntaxes/injections.json similarity index 100% rename from etc/hlds/syntaxes/injections.json rename to etc/vscode/syntaxes/injections.json diff --git a/etc/hlds/vsc-extension-quickstart.md b/etc/vscode/vsc-extension-quickstart.md similarity index 100% rename from etc/hlds/vsc-extension-quickstart.md rename to etc/vscode/vsc-extension-quickstart.md -- 2.43.4 From 825521867e123ba812a18e781e12ac2d048b8e26 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Mon, 24 Feb 2020 22:27:13 +0100 Subject: [PATCH 005/197] Update fritoloog --- data/fritoloog.hlds | 72 ++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 24 deletions(-) diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds index 393639b..fb763db 100644 --- a/data/fritoloog.hlds +++ b/data/fritoloog.hlds @@ -1,6 +1,9 @@ ============================ fritoloog: Fritoloog - osm https://www.openstreetmap.org/node/5813542646 + osm https://www.openstreetmap.org/node/5813542646 + address Voskenslaan 413, 9000 Gent + website https://defritoloog.be + # Op bovenstaande website kan men ook online orderen ============================ dish fries: Frietjes :: {has_meat} @@ -25,7 +28,6 @@ sauce: Saus other: Andere (in commentaar) extra_cheese: Extra kaas - # FIXME extra kaas waarop? no_extra_cheese: Nee yes_extra_cheese: Ja € 0.2 @@ -56,32 +58,54 @@ dish satay: Saté :: {has_meat} € 2.7 dish grisley: Grisley :: {has_meat} € 2.7 dish flemish_stew: Stoofvlees :: {has_meat} € 4.5 dish meatballs_tomato_sauce: Balletjes in tomatensaus :: {has_meat} € 4.5 -dish hamburger: Hamburger :: {has_meat} € 2.6 -dish cheeseburger: Cheeseburger :: {has_meat} € 2.9 -dish chicken_burger: Chickenburger :: {has_meat} € 3.2 -dish bicky_burger: Bickyburger :: {has_meat} € 2.9 -dish bicky_rib: Bicky Rib :: {has_meat} € 3.5 -dish bicky_royal: Bicky Royal :: {has_meat} € 4.3 -dish bicky_chicken: Bicky Chicken :: {has_meat} € 3.2 -dish bicky_wrap: Bicky Wrap :: {has_meat} € 3 dish assortment: Twijfelaar :: {has_meat} € 3 -dish chili_cheese: Chili cheese :: {has_meat} € 2.7 - # FIXME zit hier vlees in? +# Burgers +dish hamburger: Hamburger :: {has_meat} € 2.6 + single_choice extra_cheese +dish samuraiburger: Samuraiburger :: {has_meat} € 2.6 + single_choice extra_cheese +dish joppieburger: Joppieburger :: {has_meat} € 2.6 + single_choice extra_cheese +dish cheeseburger: Cheeseburger :: {has_meat} € 2.9 + single_choice extra_cheese +dish chicken_burger: Chickenburger :: {has_meat} € 3.2 + single_choice extra_cheese +dish bicky_burger: Bickyburger :: {has_meat} € 2.9 + single_choice extra_cheese +dish bicky_rib: Bicky Rib :: {has_meat} € 3.5 + single_choice extra_cheese +dish bicky_royal: Bicky Royal :: {has_meat} € 4.3 + single_choice extra_cheese +dish bicky_chicken: Bicky Chicken :: {has_meat} € 3.2 + single_choice extra_cheese +dish bicky_wrap: Bicky Wrap :: {has_meat} € 3 + single_choice extra_cheese -dish fish_burger: Fishburger :: {has_fish} € 3 -dish cod_stick: Kabeljauwstick :: {has_fish} € 2.5 -dish shrimp_croquette: Garnaalkroket :: {has_fish} € 2 +dish grill_burger: Burger op de grill :: {has_meat} € 5.5 + single_choice soort: Soort burger # FIXME maybe change this desciption + keizer_karel: Keizer Karel + walter_de_buck: Walter De Buck + john_massis: John Massis € 0.5 + pierke_pierlala: Pierke Pierlala € 0.5 + van_eyck: Van Eyck € 0.5 -dish mozarella_sticks: Mozarellasticks € 3 -dish cheese_croquette: Kaaskroket € 1.5 -dish veggi_burger: Veggieburger € 3.2 -dish cheese_souflesse: Kaassouflesse € 1.5 + +dish chili_cheese: Chili cheese :: € 2.7 + +dish fish_burger: Fishburger :: {has_fish} € 3 +dish cod_stick: Kabeljauwstick :: {has_fish} € 2.5 +dish shrimp_croquette: Garnaalkroket :: {has_fish} € 2 + +dish mozarella_sticks: Mozarellasticks :: € 3 +dish cheese_croquette: Kaaskroket :: € 1.5 +dish veggi_burger: Veggieburger :: € 3.2 +dish cheese_souflesse: Kaassouflesse :: € 1.5 # https://www.vangeloven.com/merk/souflesse -dish bonita: Bonita € 2 +dish bonita: Bonita :: € 2 # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentesnack-vries-bonita/ -dish sajoera: Sajoera € 2 +dish sajoera: Sajoera :: € 2 # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentekroket-vries-sajoera/ -dish veg_cheese_disc: Groenten-kaasschijf € 2.4 -dish mini_spring_rolls: Mini-loempia's € 3 -dish bami: Bami € 2 +dish veg_cheese_disc: Groenten-kaasschijf :: € 2.4 +dish mini_spring_rolls: Mini-loempia's :: € 3 +dish bami: Bami :: € 2 -- 2.43.4 From ea06fe72e2e7ca596da34faeb0661f68a2b96e11 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Mon, 24 Feb 2020 22:57:11 +0100 Subject: [PATCH 006/197] Add primadonna --- data/primadonna.hlds | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 data/primadonna.hlds diff --git a/data/primadonna.hlds b/data/primadonna.hlds new file mode 100644 index 0000000..7cd8442 --- /dev/null +++ b/data/primadonna.hlds @@ -0,0 +1,41 @@ +======================== +primadonna: Primadonna + address Overpoortstraat 46, 9000 Gent + website https://primadonnagent.be + phone +32 475 40 13 00 +======================== + +dish peperoni: Peperoni :: € 5.75 +dish basis_pizza: Basis pizza :: € 4.5 +dish parma: Parma :: € 5.75 +dish margarita: Margharita :: € 4.5 +dish fungi: Funghi :: € 5.5 +dish mamma_mia: Mamma mia :: € 5.5 +dish napoletana: Napoletana :: € 5.75 +dish exotic: Exotic :: € 5.75 +dish siciliana: Siciliana: :: € 5.75 +dish michelangelo: Michelangelo :: € 5.75 +dish roma: Roma :: € 5.75 +dish torno: Torno :: € 5.75 +dish bolognese: Bolognese :: € 6 +dish hawai: Hawai :: € 7 +dish cipolla: Cipolla :: € 7 +dish dolce_vita: Dolce vita :: € 7 +dish valentino: Valentino :: € 7 +dish vegateriana: Vegateriana :: € 7.7 +dish la_donna: La donna :: € 7.7 +dish tropical: Tropical :: € 7.7 +dish quattro_stagioni: Quattro Stagioni :: € 7.7 +dish romana: Romana :: € 7.7 +dish diabolo: Diabolo :: € 7.7 +dish turkish: Turkish :: € 7.7 +dish cesar: Cesar :: € 7.7 +dish calzone: Calzone :: € 8 +dish calzone_vegetariana: Calzone Vegetariana :: € 8 +dish quattro_formaggi: Quattro Formaggi :: € 8 +dish frutti_di_mare: Frutti di mare :: € 8 +dish gerookte_ham_en_rucola: Gerookte ham en rucola :: € 8 +dish van_de_chef: Van de chef :: € 9 +dish milano: Milano :: € 9 +dish soronto: Soronto :: € 9.7 +dish primma_donna: Primma Donna :: € 9.7 -- 2.43.4 From 57d65661de20bd281e866c1e4b9f78fae6aec2f1 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 00:24:12 +0100 Subject: [PATCH 007/197] Correct small typos in Prima Donna --- data/{primadonna.hlds => prima_donna.hlds} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename data/{primadonna.hlds => prima_donna.hlds} (90%) diff --git a/data/primadonna.hlds b/data/prima_donna.hlds similarity index 90% rename from data/primadonna.hlds rename to data/prima_donna.hlds index 7cd8442..8ea3af1 100644 --- a/data/primadonna.hlds +++ b/data/prima_donna.hlds @@ -1,5 +1,5 @@ ======================== -primadonna: Primadonna +prima_donna: Prima Donna address Overpoortstraat 46, 9000 Gent website https://primadonnagent.be phone +32 475 40 13 00 @@ -13,9 +13,9 @@ dish fungi: Funghi :: € 5.5 dish mamma_mia: Mamma mia :: € 5.5 dish napoletana: Napoletana :: € 5.75 dish exotic: Exotic :: € 5.75 -dish siciliana: Siciliana: :: € 5.75 +dish siciliana: Siciliana :: € 5.75 dish michelangelo: Michelangelo :: € 5.75 -dish roma: Roma :: € 5.75 +dish roma: Roma :: € 5.75 dish torno: Torno :: € 5.75 dish bolognese: Bolognese :: € 6 dish hawai: Hawai :: € 7 @@ -38,4 +38,4 @@ dish gerookte_ham_en_rucola: Gerookte ham en rucola :: € 8 dish van_de_chef: Van de chef :: € 9 dish milano: Milano :: € 9 dish soronto: Soronto :: € 9.7 -dish primma_donna: Primma Donna :: € 9.7 +dish prima_donna: Prima Donna :: € 9.7 -- 2.43.4 From 38e10257d2ab591880b883e56e18778c53310f63 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 16:29:43 +0100 Subject: [PATCH 008/197] Drop product ID migration Actually really really a lot of work and almost no benefit. --- .../9159a6fed021_initial_haldis_support.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/app/migrations/versions/9159a6fed021_initial_haldis_support.py b/app/migrations/versions/9159a6fed021_initial_haldis_support.py index 7bbae08..5e4406f 100644 --- a/app/migrations/versions/9159a6fed021_initial_haldis_support.py +++ b/app/migrations/versions/9159a6fed021_initial_haldis_support.py @@ -47,10 +47,6 @@ LOCATION_LEGACY_TO_HLDS = { 30: "kebab_anadolu", } -DISH_LEGACY_TO_HLDS = { - # TODO -} - def upgrade(): # First the simple actions @@ -86,19 +82,11 @@ def upgrade(): column("price", sa.Integer) ) # Construct and execute queries - new_dish_id = [ - order_item.update() - .where(order_item.c.product_id == old_id) - .values(dish_id=new_id) - for old_id, new_id in DISH_LEGACY_TO_HLDS.items() - ] - dish_name_and_price_from_product = text(""" + op.execute(text(""" UPDATE order_item SET dish_name = (SELECT product.name FROM product WHERE product.id = order_item.product_id), price = (SELECT product.price FROM product WHERE product.id = order_item.product_id)""" - ) - for query in chain(new_dish_id, [dish_name_and_price_from_product]): - op.execute(query) + )) # Historical product data migrated, drop obsolete column and table op.execute(text("ALTER TABLE order_item DROP FOREIGN KEY order_item_ibfk_3")) op.drop_column("order_item", "product_id") -- 2.43.4 From d911cb573b850d40ab11f64eccf2b30508d4848d Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 16:43:57 +0100 Subject: [PATCH 009/197] Add veggie in name of Fritoloog dishes While tags are not yet supported, this is useful. --- data/fritoloog.hlds | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds index fb763db..c8bdb1b 100644 --- a/data/fritoloog.hlds +++ b/data/fritoloog.hlds @@ -91,21 +91,20 @@ dish grill_burger: Burger op de grill :: {has_meat} € 5.5 van_eyck: Van Eyck € 0.5 -dish chili_cheese: Chili cheese :: € 2.7 - dish fish_burger: Fishburger :: {has_fish} € 3 dish cod_stick: Kabeljauwstick :: {has_fish} € 2.5 dish shrimp_croquette: Garnaalkroket :: {has_fish} € 2 -dish mozarella_sticks: Mozarellasticks :: € 3 -dish cheese_croquette: Kaaskroket :: € 1.5 -dish veggi_burger: Veggieburger :: € 3.2 -dish cheese_souflesse: Kaassouflesse :: € 1.5 +dish chili_cheese: Chili cheese (veggie) :: € 2.7 +dish mozarella_sticks: Mozarellasticks (veggie) :: € 3 +dish cheese_croquette: Kaaskroket (veggie) :: € 1.5 +dish veggi_burger: Veggieburger :: € 3.2 +dish cheese_souflesse: Kaassouflesse (veggie) :: € 1.5 # https://www.vangeloven.com/merk/souflesse -dish bonita: Bonita :: € 2 +dish bonita: Bonita (veggie) :: € 2 # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentesnack-vries-bonita/ -dish sajoera: Sajoera :: € 2 +dish sajoera: Sajoera (veggie) :: € 2 # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentekroket-vries-sajoera/ -dish veg_cheese_disc: Groenten-kaasschijf :: € 2.4 -dish mini_spring_rolls: Mini-loempia's :: € 3 -dish bami: Bami :: € 2 +dish veg_cheese_disc: Groenten-kaasschijf (veggie) :: € 2.4 +dish mini_spring_rolls: Mini-loempia's (veggie) :: € 3 +dish bami: Bami (veggie) :: € 2 -- 2.43.4 From a62e2bd9f7ff31abf220b750d80aed7b25e45f7f Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 17:51:14 +0100 Subject: [PATCH 010/197] Remove admin view --- app/admin.py | 36 ------------------------------------ app/app.py | 3 --- app/templates/layout.html | 3 --- 3 files changed, 42 deletions(-) delete mode 100644 app/admin.py diff --git a/app/admin.py b/app/admin.py deleted file mode 100644 index 0ba2810..0000000 --- a/app/admin.py +++ /dev/null @@ -1,36 +0,0 @@ -"Haldis admin related views and models" - -import flask_login as login -from flask import Flask -from flask_admin import Admin -from flask_admin.contrib.sqla import ModelView -from flask_sqlalchemy import SQLAlchemy - -from models import Order, OrderItem, OrderItemChoice, User - - -class ModelBaseView(ModelView): - "Base model for admin related things" - # pylint: disable=R0201, R0903 - def is_accessible(self) -> bool: - "Check if the user has admin permission" - if login.current_user.is_anonymous(): - return False - return login.current_user.is_admin() - - -class UserAdminModel(ModelBaseView): - "Model for user admin" - # pylint: disable=R0903 - column_searchable_list = ("username",) - inline_models = None - - -def init_admin(app: Flask, database: SQLAlchemy) -> None: - "Initialize the admin related things in the app." - admin = Admin(app, name="Haldis", url="/admin", template_mode="bootstrap3") - - admin.add_view(UserAdminModel(User, database.session)) - admin.add_view(ModelBaseView(Order, database.session)) - admin.add_view(ModelBaseView(OrderItem, database.session)) - admin.add_view(ModelBaseView(OrderItemChoice, database.session)) diff --git a/app/app.py b/app/app.py index a760064..51888a3 100755 --- a/app/app.py +++ b/app/app.py @@ -15,7 +15,6 @@ from flask_migrate import Migrate, MigrateCommand from flask_oauthlib.client import OAuth, OAuthException from flask_script import Manager, Server -from admin import init_admin from login import init_login from models import db from models.anonymous_user import AnonymouseUser @@ -75,8 +74,6 @@ def register_plugins(app: Flask) -> Manager: app_manager = Manager(app) app_manager.add_command("db", MigrateCommand) app_manager.add_command("runserver", Server(port=8000)) - # Add admin interface - init_admin(app, db) # Init login manager login_manager = LoginManager() diff --git a/app/templates/layout.html b/app/templates/layout.html index 7e4bce1..707b9ab 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -9,9 +9,6 @@ ('general_bp.about', 'About'), ('stats_blueprint.stats', 'Stats'), ] -%} -{% if not current_user.is_anonymous() and current_user.is_admin() -%} - {% set navbar = navbar + [('admin.index', 'Admin')] -%} -{% endif -%} {% set active_page = active_page|default('index') -%} {% block title %} -- 2.43.4 From 646858aac33713e7105ddb437dc0971147727531 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 17:51:53 +0100 Subject: [PATCH 011/197] Populate HLDS data version field --- app/hlds/definitions.py | 9 +++++++-- app/views/order.py | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 4267ff4..56d1182 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -2,15 +2,20 @@ from os import path from typing import List +import subprocess from .parser import parse_all_directory from .models import Location -__all__ = ["location_definitions"] +__all__ = ["location_definitions", "location_definition_version"] + +# pylint: disable=invalid-name # TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674 DATA_DIR = path.join(path.dirname(__file__), "..", "..", "data") -# pylint: disable=invalid-name location_definitions: List[Location] = parse_all_directory(DATA_DIR) location_definitions.sort(key=lambda l: l.name) + +proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, check=True) +location_definition_version = proc.stdout diff --git a/app/views/order.py b/app/views/order.py index aa67663..88e7fd3 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -11,7 +11,7 @@ from flask_login import current_user, login_required from forms import AnonOrderItemForm, OrderForm, OrderItemForm from models import Order, OrderItem, User, db -from hlds.definitions import location_definitions +from hlds.definitions import location_definitions, location_definition_version from notification import post_order_to_webhook from utils import ignore_none @@ -157,6 +157,7 @@ def order_item_create(order_id: int) -> typing.Any: item = OrderItem() form.populate_obj(item) + item.hlds_data_version = location_definition_version item.order_id = order_id if not current_user.is_anonymous(): item.user_id = current_user.id -- 2.43.4 From 0bdb17277ff8a523e10ebeec62b60619265a2118 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 18:26:41 +0100 Subject: [PATCH 012/197] Improve Prima Donna --- data/prima_donna.hlds | 68 +++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/data/prima_donna.hlds b/data/prima_donna.hlds index 8ea3af1..9b9eb00 100644 --- a/data/prima_donna.hlds +++ b/data/prima_donna.hlds @@ -5,37 +5,37 @@ prima_donna: Prima Donna phone +32 475 40 13 00 ======================== -dish peperoni: Peperoni :: € 5.75 -dish basis_pizza: Basis pizza :: € 4.5 -dish parma: Parma :: € 5.75 -dish margarita: Margharita :: € 4.5 -dish fungi: Funghi :: € 5.5 -dish mamma_mia: Mamma mia :: € 5.5 -dish napoletana: Napoletana :: € 5.75 -dish exotic: Exotic :: € 5.75 -dish siciliana: Siciliana :: € 5.75 -dish michelangelo: Michelangelo :: € 5.75 -dish roma: Roma :: € 5.75 -dish torno: Torno :: € 5.75 -dish bolognese: Bolognese :: € 6 -dish hawai: Hawai :: € 7 -dish cipolla: Cipolla :: € 7 -dish dolce_vita: Dolce vita :: € 7 -dish valentino: Valentino :: € 7 -dish vegateriana: Vegateriana :: € 7.7 -dish la_donna: La donna :: € 7.7 -dish tropical: Tropical :: € 7.7 -dish quattro_stagioni: Quattro Stagioni :: € 7.7 -dish romana: Romana :: € 7.7 -dish diabolo: Diabolo :: € 7.7 -dish turkish: Turkish :: € 7.7 -dish cesar: Cesar :: € 7.7 -dish calzone: Calzone :: € 8 -dish calzone_vegetariana: Calzone Vegetariana :: € 8 -dish quattro_formaggi: Quattro Formaggi :: € 8 -dish frutti_di_mare: Frutti di mare :: € 8 -dish gerookte_ham_en_rucola: Gerookte ham en rucola :: € 8 -dish van_de_chef: Van de chef :: € 9 -dish milano: Milano :: € 9 -dish soronto: Soronto :: € 9.7 -dish prima_donna: Prima Donna :: € 9.7 +dish basic_pizza: Basispizza :: € 4.5 +dish margarita: Pizza margharita :: € 4.5 +dish pepperoni: Pizza pepperoni :: € 5.75 +dish parma: Pizza Parma :: € 5.75 +dish fungi: Pizza funghi :: € 5.5 +dish mamma_mia: Pizza mamma mia :: € 5.5 +dish napoletana: Pizza Napoletana :: € 5.75 +dish exotic: Pizza exotic :: € 5.75 +dish siciliana: Pizza Siciliana :: € 5.75 +dish michelangelo: Pizza Michelangelo :: € 5.75 +dish roma: Pizza Roma :: € 5.75 +dish torno: Pizza torno :: € 5.75 +dish bolognese: Pizza bolognese :: € 6 +dish hawaii: Pizza hawaï :: € 7 +dish cipolla: Pizza cipolla :: € 7 +dish dolce_vita: Pizza dolce vita :: € 7 +dish valentino: Pizza valentino :: € 7 +dish vegateriana: Pizza vegateriana :: € 7.7 +dish la_donna: Pizza la donna :: € 7.7 +dish tropical: Pizza tropical :: € 7.7 +dish quattro_stagioni: Pizza quattro stagioni :: € 7.7 +dish romana: Pizza Romana :: € 7.7 +dish diabolo: Pizza diabolo :: € 7.7 +dish turkish: Pizza Turkish :: € 7.7 +dish cesar: Pizza Cesar :: € 7.7 +dish calzone: Pizza calzone :: € 8 +dish calzone_vegetariana: Pizza calzone Vegetariana :: € 8 +dish quattro_formaggi: Pizza quattro formaggi :: € 8 +dish frutti_di_mare: Pizza frutti di mare :: € 8 +dish gerookte_ham_en_rucola: Pizza gerookte ham en rucola :: € 8 +dish van_de_chef: Pizza van de chef :: € 9 +dish milano: Pizza Milano :: € 9 +dish soronto: Pizza soronto :: € 9.7 +dish prima_donna: Pizza Prima Donna :: € 9.7 -- 2.43.4 From 1246284f9b6a1329bdcb69f039df2b2fa14acac1 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 18:26:56 +0100 Subject: [PATCH 013/197] Add Simpizza --- data/simpizza.hlds | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 data/simpizza.hlds diff --git a/data/simpizza.hlds b/data/simpizza.hlds new file mode 100644 index 0000000..f423331 --- /dev/null +++ b/data/simpizza.hlds @@ -0,0 +1,84 @@ +============================ +simpizza: Simpizza + osm https://www.openstreetmap.org/node/5803560353 + address De Pintelaan 252, 9000 Gent + website https://www.simpizza.be/ + # Op bovenstaande website kan men ook online orderen +============================ + +dish garlic_bread: Lookbroodjes natuur € 2.2 +dish chicken_fingers: Kippenvingers :: {has_meat} € 3 +dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 8.5 + +size: Grootte + small: Small -- 27 cm € 9.95 + medium: Medium -- 30 cm € 12.95 + large: Large -- 37 cm € 15.95 + +# Pizza +dish margherita: Pizza margherita -- Veggie + single_choice size +dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} + single_choice size +dish hawaii: Pizza hawaï :: {has_meat} + single_choice size +dish popeye: Pizza popeye -- Veggie + single_choice size +dish pepperoni: Pizza pepperoni :: {has_meat} + single_choice size +dish seafood: Pizza seafood :: {has_meat} + single_choice size +dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} + single_choice size +dish salmon_delight: Pizza salmon delight :: {has_meat} + single_choice size +dish full_option: Pizza full option :: {has_meat} + single_choice size +dish pitza_kebab: Pitza kebab :: {has_meat} + single_choice size +dish multi_cheese: Pizza multi cheese -- Veggie + single_choice size +dish 4_seasons: Pizza 4 seasons :: {has_meat} + single_choice size +dish mega_fish: Pizza mega fish :: {has_meat} + single_choice size +dish creamy_multi_cheese: Pizza creamy multi cheese -- Veggie + single_choice size +dish green_fiesta: Pizza green fiësta :: {has_meat} + single_choice size +dish veggie: Pizza veggie + single_choice size +dish meat_lovers: Pizza meat lovers :: {has_meat} + single_choice size +dish scampi_mampi: Pizza scampi mampi :: {has_meat} + single_choice size +dish tabasco: Pizza tabasco :: {has_meat} + single_choice size +dish funky_chicken: Pizza funky chicken :: {has_meat} + single_choice size +dish chicken_time: Pizza chicken time :: {has_meat} + single_choice size +dish creamy_chicken: Pizza creamy chicken :: {has_meat} + single_choice size +dish spicy_chicken: Pizza spicy Chicken :: {has_meat} + single_choice size +dish meatballs: Pizza meatballs :: {has_meat} + single_choice size +dish tuna: Pizza tuna :: {has_meat} + single_choice size +dish anchovy: Pizza anchovy :: {has_meat} + single_choice size +dish calzone: Pizza calzone :: {has_meat} + single_choice size +dish hot_bolognese: Pizza hot bolognese :: {has_meat} + single_choice size +dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} + single_choice size +dish bbq_chicken: Pizza chicken barbecue :: {has_meat} + single_choice size +dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} + single_choice size +dish bbq_bacon: Pizza barbecue bacon :: {has_meat} + single_choice size +dish bbq_special: Pizza barbecue special :: {has_meat} + single_choice size -- 2.43.4 From 36bdee36892b75be5f42255456dc1e4137739bf1 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 18:47:30 +0100 Subject: [PATCH 014/197] Improve Simpizza --- data/simpizza.hlds | 107 ++++++++++++++++++++++++++++++--------------- 1 file changed, 72 insertions(+), 35 deletions(-) diff --git a/data/simpizza.hlds b/data/simpizza.hlds index f423331..73468bd 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -6,79 +6,116 @@ simpizza: Simpizza # Op bovenstaande website kan men ook online orderen ============================ -dish garlic_bread: Lookbroodjes natuur € 2.2 -dish chicken_fingers: Kippenvingers :: {has_meat} € 3 -dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 8.5 +dish garlic_bread: Lookbroodjes natuur € 2.2 +dish garlic_bread_cheese: Lookbroodjes kaas € 2.5 +dish garlic_bread_cheese_ham: Lookbroodjes kaas en ham :: {has_meat} € 3 +dish garlic_bread_cheese_tomato: Lookbroodjes kaas en tomaat € 3 +dish garlic_bread_cheese_salami: Lookbroodjes kaas en salami :: {has_meat} € 3 + +dish baguette_oven: Baguette in de oven € 3 +dish chicken_fingers: Kippenvingers :: {has_meat} € 3 +dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 8.5 size: Grootte small: Small -- 27 cm € 9.95 medium: Medium -- 30 cm € 12.95 large: Large -- 37 cm € 15.95 -# Pizza -dish margherita: Pizza margherita -- Veggie +garlic_sauce: Looksaus + no_garlic_sauce: Zonder looksaus + yes_garlic_sauce: Met looksaus (prijs onzeker) € 0.75 + +dish margherita: Pizza margherita -- Veggie single_choice size -dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} + single_choice garlic_sauce +dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} single_choice size -dish hawaii: Pizza hawaï :: {has_meat} + single_choice garlic_sauce +dish hawaii: Pizza Hawaï :: {has_meat} single_choice size -dish popeye: Pizza popeye -- Veggie + single_choice garlic_sauce +dish popeye: Pizza Popeye -- Veggie single_choice size -dish pepperoni: Pizza pepperoni :: {has_meat} + single_choice garlic_sauce +dish pepperoni: Pizza pepperoni :: {has_meat} single_choice size -dish seafood: Pizza seafood :: {has_meat} + single_choice garlic_sauce +dish seafood: Pizza seafood :: {has_meat} single_choice size -dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} + single_choice garlic_sauce +dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} single_choice size -dish salmon_delight: Pizza salmon delight :: {has_meat} + single_choice garlic_sauce +dish salmon_delight: Pizza salmon delight :: {has_meat} single_choice size -dish full_option: Pizza full option :: {has_meat} + single_choice garlic_sauce +dish full_option: Pizza full option :: {has_meat} single_choice size -dish pitza_kebab: Pitza kebab :: {has_meat} + single_choice garlic_sauce +dish pitza_kebab: Pitza kebab -- Heeft al looksaus :: {has_meat} single_choice size -dish multi_cheese: Pizza multi cheese -- Veggie +dish multi_cheese: Pizza multi cheese -- Veggie single_choice size -dish 4_seasons: Pizza 4 seasons :: {has_meat} + single_choice garlic_sauce +dish 4_seasons: Pizza 4 seasons :: {has_meat} single_choice size -dish mega_fish: Pizza mega fish :: {has_meat} + single_choice garlic_sauce +dish mega_fish: Pizza mega fish :: {has_meat} single_choice size + single_choice garlic_sauce dish creamy_multi_cheese: Pizza creamy multi cheese -- Veggie single_choice size -dish green_fiesta: Pizza green fiësta :: {has_meat} +dish green_fiesta: Pizza green fiësta -- Heeft al looksaus :: {has_meat} single_choice size dish veggie: Pizza veggie single_choice size -dish meat_lovers: Pizza meat lovers :: {has_meat} + single_choice garlic_sauce +dish meat_lovers: Pizza meat lovers :: {has_meat} single_choice size -dish scampi_mampi: Pizza scampi mampi :: {has_meat} + single_choice garlic_sauce +dish scampi_mampi: Pizza scampi mampi :: {has_meat} single_choice size -dish tabasco: Pizza tabasco :: {has_meat} + single_choice garlic_sauce +dish tabasco: Pizza tabasco :: {has_meat} single_choice size -dish funky_chicken: Pizza funky chicken :: {has_meat} + single_choice garlic_sauce +dish funky_chicken: Pizza funky chicken :: {has_meat} single_choice size -dish chicken_time: Pizza chicken time :: {has_meat} + single_choice garlic_sauce +dish chicken_time: Pizza chicken time :: {has_meat} single_choice size -dish creamy_chicken: Pizza creamy chicken :: {has_meat} + single_choice garlic_sauce +dish creamy_chicken: Pizza creamy chicken -- Heeft al looksaus :: {has_meat} single_choice size -dish spicy_chicken: Pizza spicy Chicken :: {has_meat} +dish spicy_chicken: Pizza spicy chicken -- Heeft al looksaus :: {has_meat} single_choice size -dish meatballs: Pizza meatballs :: {has_meat} +dish meatballs: Pizza meatballs :: {has_meat} single_choice size -dish tuna: Pizza tuna :: {has_meat} + single_choice garlic_sauce +dish tuna: Pizza tuna :: {has_meat} single_choice size -dish anchovy: Pizza anchovy :: {has_meat} + single_choice garlic_sauce +dish anchovy: Pizza anchovy :: {has_meat} single_choice size -dish calzone: Pizza calzone :: {has_meat} + single_choice garlic_sauce +dish calzone: Pizza calzone :: {has_meat} single_choice size -dish hot_bolognese: Pizza hot bolognese :: {has_meat} + single_choice garlic_sauce +dish hot_bolognese: Pizza hot bolognese :: {has_meat} single_choice size -dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} + single_choice garlic_sauce +dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} single_choice size -dish bbq_chicken: Pizza chicken barbecue :: {has_meat} + single_choice garlic_sauce +dish curry: Pizza curry -- Heeft al looksaus :: {has_meat} single_choice size -dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} +dish bbq_chicken: Pizza chicken barbecue :: {has_meat} single_choice size -dish bbq_bacon: Pizza barbecue bacon :: {has_meat} + single_choice garlic_sauce +dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} single_choice size -dish bbq_special: Pizza barbecue special :: {has_meat} + single_choice garlic_sauce +dish bbq_bacon: Pizza barbecue bacon -- Heeft al looksaus :: {has_meat} + single_choice size +dish bbq_special: Pizza barbecue special -- Heeft al looksaus :: {has_meat} single_choice size -- 2.43.4 From 2892a7dc258b621f4954b8004476d93693b0a123 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 25 Feb 2020 19:05:21 +0100 Subject: [PATCH 015/197] Add no_text options --- app/hlds/parser.py | 2 +- app/views/order.py | 2 +- data/fitchen.hlds | 6 +++--- data/fritoloog.hlds | 4 ++-- data/simpizza.hlds | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index a6e452d..7728909 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -85,7 +85,7 @@ class HldsSemanticActions: name=ast["name"], description=ast["description"], price=ast["price"] or 0, - tags=ast["tags"], + tags=ast["tags"] or [], ) noindent_choice_entry = indent_choice_entry diff --git a/app/views/order.py b/app/views/order.py index 88e7fd3..843c50f 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -170,7 +170,7 @@ def order_item_create(order_id: int) -> typing.Any: return option.name except AttributeError: return ", ".join(o.name for o in option) - comments = [_name(option) for option in chosen if option] + comments = [_name(option) for option in chosen if option and "no_text" not in option.tags] if item.comment: comments.append("Comment: " + item.comment) item.comment = "; ".join(comments) diff --git a/data/fitchen.hlds b/data/fitchen.hlds index 3689c82..502ffcb 100644 --- a/data/fitchen.hlds +++ b/data/fitchen.hlds @@ -16,7 +16,7 @@ bowl_wrap: Bowl of wrap red_beet_wrap: Rodebietenwrap € 0.99 veggie: Vegetarische opties - meat: Niet vegetarisch :: {has_meat} + meat: Niet vegetarisch :: {has_meat} {no_text} tofu: Vegetarisch met tofu tempeh: Vegetarisch met tempeh -- Gekruide tempeh avocado: Vegetarisch met avocado @@ -24,7 +24,7 @@ veggie: Vegetarische opties vegan: Veganistisch veggie_on_veggie_dish: Vegetarische opties - veggie: Vegetarisch (met standaard eiwitgerief van gerecht) + veggie: Vegetarisch (met standaard eiwitgerief van gerecht) :: {no_text} tofu: Vegetarisch met tofu tempeh: Vegetarisch met tempeh -- Gekruide tempeh avocado: Vegetarisch met avocado @@ -32,7 +32,7 @@ veggie_on_veggie_dish: Vegetarische opties vegan: Veganistisch veggie_on_vegan_dish: Vegetarische opties - vegan: Veganistisch + vegan: Veganistisch :: {no_text} tofu: Vegetarisch met tofu tempeh: Vegetarisch met tempeh -- Gekruide tempeh avocado: Vegetarisch met avocado diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds index c8bdb1b..8abfbf9 100644 --- a/data/fritoloog.hlds +++ b/data/fritoloog.hlds @@ -28,8 +28,8 @@ sauce: Saus other: Andere (in commentaar) extra_cheese: Extra kaas - no_extra_cheese: Nee - yes_extra_cheese: Ja € 0.2 + no_extra_cheese: Geen extra kaas :: {no_text} + yes_extra_cheese: Extra kaas € 0.2 dish chicken_fingers: Kippenvingers :: {has_meat} € 3 dish nuggiz: Nuggiz :: {has_meat} € 3 diff --git a/data/simpizza.hlds b/data/simpizza.hlds index 73468bd..cbd9313 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -22,7 +22,7 @@ size: Grootte large: Large -- 37 cm € 15.95 garlic_sauce: Looksaus - no_garlic_sauce: Zonder looksaus + no_garlic_sauce: Geen extra looksaus :: {no_text} yes_garlic_sauce: Met looksaus (prijs onzeker) € 0.75 dish margherita: Pizza margherita -- Veggie -- 2.43.4 From 02cea73a6c6f34ab8a26155499279178280d0e71 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Feb 2020 17:52:18 +0100 Subject: [PATCH 016/197] Add separate dish for sweetsour meat balls --- data/ocean_garden.hlds | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 0c173cb..0e302e9 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -40,6 +40,10 @@ dish wok1: Studentenwok 1 met saus € 6 single_choice meat single_choice sauce +dish wok1_balls: Studentenwok 1 met kip-/varkensballetjes en zoetzuur € 6 + single_choice bami_nasi + single_choice meat + dish wok2: Studentenwok 2 kip/varken bami/mihoen zonder saus € 6 single_choice bami_mihoen single_choice meat -- 2.43.4 From ccb034ef7ffcd5ffb5b556ae95d602be2bc79b6d Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Feb 2020 18:05:56 +0100 Subject: [PATCH 017/197] Fix bug on anonymous order view Change to temporary message --- app/forms.py | 2 +- app/templates/order.html | 4 ++++ app/views/order.py | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/forms.py b/app/forms.py index f57dc0c..999c0ca 100644 --- a/app/forms.py +++ b/app/forms.py @@ -60,7 +60,7 @@ class OrderItemForm(Form): else: return "from {}".format(euro_string(price_range[0])) - def populate(self, location: Location, dish_id: Optional[str]) -> None: + def populate(self, location: Location) -> None: self.dish_id.choices = [ (dish.id, (dish.name + ": " + self.format_price_range(dish.price_range()))) for dish in location.dishes diff --git a/app/templates/order.html b/app/templates/order.html index ade38f3..0c74e1f 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -42,6 +42,9 @@ {% if form -%}

Order:

+{% if current_user.is_anonymous() %} +
Sorry, anonymous ordering is currently broken. Please log in to order.
+{% else %}
Choose for me @@ -90,6 +93,7 @@ {{ form.submit_button(class='btn btn-primary') }}
+{% endif %} {%- endif %} diff --git a/app/views/order.py b/app/views/order.py index 843c50f..0c2d3a1 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -60,7 +60,7 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: form = AnonOrderItemForm() if current_user.is_anonymous() \ else OrderItemForm() if order.location: - form.populate(order.location, None) + form.populate(order.location) if order.is_closed(): form = None total_price = sum([o.price for o in order.items]) @@ -130,7 +130,7 @@ def order_item_create(order_id: int) -> typing.Any: if dish_id and not location.dish_by_id(dish_id): abort(404) form.dish_id.data = dish_id - form.populate(current_order.location, dish_id) + form.populate(current_order.location) # If the form was not submitted (GET request), the form had errors, # or the dish was changed: show form again -- 2.43.4 From e15b0850060229be7ea1e221a40e81f3c4d17ee2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Feb 2020 20:16:50 +0100 Subject: [PATCH 018/197] Add message about options appearing on submit --- app/templates/order.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/templates/order.html b/app/templates/order.html index 0c74e1f..8a684ab 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -91,6 +91,9 @@ {% endif %}
{{ form.submit_button(class='btn btn-primary') }} + {% if not dish %} +
If the chosen dish has options, they will be shown when you press submit, before adding the item to the order.
+ {% endif %}
{% endif %} -- 2.43.4 From 729dab2ba4f663cdff006615815c7f2169e216fa Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Feb 2020 21:25:51 +0100 Subject: [PATCH 019/197] Fix anonymous ordering and dish change --- app/forms.py | 17 ++++++++---- app/templates/order.html | 12 +++----- app/views/order.py | 59 ++++++++++++++++++++++++---------------- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/app/forms.py b/app/forms.py index 999c0ca..115a80a 100644 --- a/app/forms.py +++ b/app/forms.py @@ -3,7 +3,7 @@ from datetime import datetime, timedelta from typing import Optional -from flask import session +from flask import session, request from flask_login import current_user from flask_wtf import FlaskForm as Form from wtforms import (DateTimeField, SelectField, SelectMultipleField, StringField, SubmitField, @@ -65,6 +65,8 @@ class OrderItemForm(Form): (dish.id, (dish.name + ": " + self.format_price_range(dish.price_range()))) for dish in location.dishes ] + if not self.is_submitted() and self.comment.data is None: + self.comment.data = request.args.get("comment") class AnonOrderItemForm(OrderItemForm): @@ -72,7 +74,7 @@ class AnonOrderItemForm(OrderItemForm): Class which defines the form for a new Item in an Order For Users who aren't logged in """ - name = StringField("Name", validators=[validators.required()]) + user_name = StringField("Name", validators=[validators.required()]) def populate(self, location: Location) -> None: """ @@ -80,8 +82,11 @@ class AnonOrderItemForm(OrderItemForm): the name of the anon user """ OrderItemForm.populate(self, location) - if self.name.data is None: - self.name.data = session.get("anon_name", None) + if not self.is_submitted(): + if self.user_name.data is None: + self.user_name.data = request.args.get("user_name") + if self.user_name.data is None: + self.user_name.data = session.get("anon_name", None) def validate(self) -> bool: "Check if the provided anon_name is not already taken" @@ -90,8 +95,8 @@ class AnonOrderItemForm(OrderItemForm): return False # check if we have a user with this name - user = User.query.filter_by(username=self.name.data).first() + user = User.query.filter_by(username=self.user_name.data).first() if user is not None: - self.name.errors.append("Name already in use") + self.user_name.errors.append("Name already in use") return False return True diff --git a/app/templates/order.html b/app/templates/order.html index 8a684ab..7d091a7 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -42,9 +42,6 @@ {% if form -%}

Order:

-{% if current_user.is_anonymous() %} -
Sorry, anonymous ordering is currently broken. Please log in to order.
-{% else %}
Choose for me @@ -83,10 +80,10 @@
{% if current_user.is_anonymous() %} -
- {{ form.name.label(class='control-label') }} - {{ form.name(class='form-control', placeholder='Fill in your name...') }} - {{ util.render_form_field_errors(form.name) }} +
+ {{ form.user_name.label(class='control-label') }} + {{ form.user_name(class='form-control', placeholder='Fill in your name...') }} + {{ util.render_form_field_errors(form.user_name) }}
{% endif %}
@@ -96,7 +93,6 @@ {% endif %}
-{% endif %}
{%- endif %} diff --git a/app/views/order.py b/app/views/order.py index 0c2d3a1..faa2778 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -129,32 +129,40 @@ def order_item_create(order_id: int) -> typing.Any: dish_id = form.dish_id.data if form.is_submitted() else request.args.get("dish") if dish_id and not location.dish_by_id(dish_id): abort(404) - form.dish_id.data = dish_id + if not form.is_submitted(): + form.dish_id.data = dish_id form.populate(current_order.location) - # If the form was not submitted (GET request), the form had errors, - # or the dish was changed: show form again - dish_was_changed = request.form.get("form_for_dish_id") and request.form["form_for_dish_id"] != dish_id - if not form.validate_on_submit() or dish_was_changed: + if form.is_submitted(): + form_for_dish = request.form.get("form_for_dish_id") + dish_was_changed = form_for_dish is not None and form_for_dish != dish_id + + # The form's validation tests that dish_id is valid and gives a friendly error if it's not + choices = location.dish_by_id(form.dish_id.data).choices + chosen = [ + ( + choice.option_by_id(request.form.get("choice_" + choice.id)) + if choice_type == "single_choice" else + list(ignore_none(request.form.getlist("choice_" + choice.id, type=choice.option_by_id))) + ) + for (choice_type, choice) in choices + ] + all_choices_present = all(x is not None for x in chosen) + + if dish_was_changed or not all_choices_present: + user_name = form.user_name.data if form.user_name.validate(form) else None + comment = form.comment.data if form.comment.validate(form) else None + + return redirect(url_for("order_bp.order_item_create", + order_id=order_id, dish=form.dish_id.data, + user_name=user_name, comment=comment)) + + # If the form was not submitted (GET request) or the form had errors: show form again + if not form.validate_on_submit(): return order_from_id(order_id, form=form, dish_id=dish_id) # Form was submitted and is valid - # The form's validation tests that dish_id is valid and gives a friendly error if it's not - choices = location.dish_by_id(form.dish_id.data).choices - chosen = [ - ( - choice.option_by_id(request.form.get("choice_" + choice.id)) - if choice_type == "single_choice" else - list(ignore_none(request.form.getlist("choice_" + choice.id, type=choice.option_by_id))) - ) - for (choice_type, choice) in choices - ] - all_choices_present = all(x is not None for x in chosen) - if not all_choices_present: - return redirect(url_for("order_bp.order_item_create", - order_id=order_id, dish=form.dish_id.data)) - item = OrderItem() form.populate_obj(item) item.hlds_data_version = location_definition_version @@ -162,15 +170,18 @@ def order_item_create(order_id: int) -> typing.Any: if not current_user.is_anonymous(): item.user_id = current_user.id else: - session["anon_name"] = item.name + session["anon_name"] = item.user_name # XXX Temporary until OrderItemChoice is used def _name(option): + no_text_tag = "no_text" try: + if not option or no_text_tag in option.tags: + return None return option.name except AttributeError: - return ", ".join(o.name for o in option) - comments = [_name(option) for option in chosen if option and "no_text" not in option.tags] + return ", ".join(o.name for o in option if no_text_tag not in o.tags) + comments = list(ignore_none(_name(option) for option in chosen)) if item.comment: comments.append("Comment: " + item.comment) item.comment = "; ".join(comments) @@ -221,7 +232,7 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]: ).all() else: items = OrderItem.query.filter( - (OrderItem.name == user_name) & (OrderItem.order_id == order_id) + (OrderItem.user_name == user_name) & (OrderItem.order_id == order_id) ).all() current_order = Order.query.filter(Order.id == order_id).first() for item in items: -- 2.43.4 From d9685b00d98174e4d85a549dc59870d40d5e264b Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Feb 2020 21:33:41 +0100 Subject: [PATCH 020/197] Fix stats view Toss unused FatDish model. --- app/fatmodels.py | 18 ------------------ app/views/stats.py | 3 +-- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/app/fatmodels.py b/app/fatmodels.py index 2ab2f29..7757db1 100644 --- a/app/fatmodels.py +++ b/app/fatmodels.py @@ -48,21 +48,3 @@ class FatUser(User, FatModel): class FatOrderItem(OrderItem, FatModel): pass - - -class FatDish(Dish, FatModel): - @classmethod - def top4(cls) -> None: - top4 = ( - OrderItem.query - .join(Order) - .group_by(Order.location_id, OrderItem.dish_id) - .with_entities( - Order.location_id, OrderItem.dish_id, func.count( - OrderItem.dish_id).label("count") - ) - .order_by(desc("count")) - .limit(4) - ) - for top in top4: - print(top) diff --git a/app/views/stats.py b/app/views/stats.py index 7204db9..19ef0a2 100644 --- a/app/views/stats.py +++ b/app/views/stats.py @@ -3,7 +3,7 @@ from flask import Blueprint from flask import current_app as app from flask import render_template -from fatmodels import FatLocation, FatOrder, FatOrderItem, FatDish, FatUser +from fatmodels import FatLocation, FatOrder, FatOrderItem, FatUser stats_blueprint = Blueprint("stats_blueprint", __name__) @@ -17,7 +17,6 @@ def stats() -> str: "locations": FatLocation.amount(), "users": FatUser.amount(), "orderitems": FatOrderItem.amount(), - "products": FatDish.amount(), } } return render_template("stats.html", data=data) -- 2.43.4 From 2b4b706e9457de6e31fabec8e74407152ed09bac Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 11:04:07 +0100 Subject: [PATCH 021/197] Overhaul Ocean Garden menu --- data/ocean_garden.hlds | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 0e302e9..2903605 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -30,30 +30,36 @@ sauce: Saus mushroom: Champignon -- Saus met champignon, wortel en wat andere groentjes malaysian: A la Maleisië -- Licht pikante saus -meat: Vlees - chicken: Kip :: {has_meat} - pork: Varken :: {has_meat} - -dish wok1: Studentenwok 1 met saus € 6 +dish wok5: Babi pangang -- Geroosterd varkensvlees :: {has_meat} € 6 + single_choice bami_nasi + +dish wok1_chicken: Kip met saus :: {has_meat} € 6 single_choice bami_nasi - single_choice meat single_choice sauce -dish wok1_balls: Studentenwok 1 met kip-/varkensballetjes en zoetzuur € 6 +dish wok1_pork: Varken met saus :: {has_meat} € 6 single_choice bami_nasi - single_choice meat + single_choice sauce -dish wok2: Studentenwok 2 kip/varken bami/mihoen zonder saus € 6 +dish wok1_breaded_chicken: Kippenballetjes zoetzuur :: {has_meat} € 6 + single_choice bami_nasi + +dish wok1_breaded_pork: Varkensballetjes zoetzuur :: {has_meat} € 6 + single_choice bami_nasi + +dish wok2_chicken: Wok 2: kip zonder saus -- Met bami of mihoen :: {has_meat} € 6 single_choice bami_mihoen - single_choice meat -dish wok3: Studentenwok 3 kip bami/nasi zonder saus :: {has_meat} € 6 +dish wok2_pork: Wok 2: varken zonder saus -- Met bami of mihoen :: {has_meat} € 6 + single_choice bami_mihoen + +dish wok3_chicken: Wok 3: kip zonder saus -- Met bami of nasi :: {has_meat} € 6 single_choice bami_nasi -dish wok4: Vegetarische studentenwok 4 met saus € 6 +dish wok3_pork: Wok 3: varken zonder saus -- Met bami of nasi :: {has_meat} € 6 + single_choice bami_nasi + +dish wok4: Vegetarische wok € 6 single_choice bami_nasi single_choice sauce - -dish wok5: Studentenwok 5 babi pangang -- Geroosterd varkensvlees :: {has_meat} € 6 - single_choice bami_nasi -- 2.43.4 From cb8d640502a0fc4cb1fb7434a21faba5d0862765 Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 11:16:39 +0100 Subject: [PATCH 022/197] Add Ocean Garden standard vegetarian dishes --- data/ocean_garden.hlds | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 2903605..3b5b993 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -31,6 +31,7 @@ sauce: Saus malaysian: A la Maleisië -- Licht pikante saus +# Student woks dish wok5: Babi pangang -- Geroosterd varkensvlees :: {has_meat} € 6 single_choice bami_nasi @@ -63,3 +64,11 @@ dish wok3_pork: Wok 3: varken zonder saus -- Met bami of nasi :: {has_meat} € dish wok4: Vegetarische wok € 6 single_choice bami_nasi single_choice sauce + +# Vegetarian dishes +dish chop_choy: 76. Chop Choy (veggie) -- Sojascheuten, met gebakken rijst € 9 +dish tjap_tjoy: 77. Tjap Tjoy (veggie) -- Diverse groenten met gebakken rijst, veggie € 9 +dish mihoen_veggies: 78. Mihoen met diverse groenten (veggie) -- Rijstnoedels € 10 +dish chau_ming_veggies: 79. Chau ming met diverse groenten (veggie) -- Eiernoedels € 10 +dish tau_foe_ma_po: 80. Tau Foe met ma-po-saus (veggie) -- Met gebakken rijst € 11.5 +dish tau_foe_mushrooms: 81. Tau Foe met Chinese champignons (veggie) -- Met gebakken rijst € 11.5 -- 2.43.4 From bba3a0cd3aa925c233743693b8f47ee214d0c3f5 Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 11:21:16 +0100 Subject: [PATCH 023/197] Fix bug in ordering --- app/views/order.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/order.py b/app/views/order.py index faa2778..8b407cf 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -150,7 +150,10 @@ def order_item_create(order_id: int) -> typing.Any: all_choices_present = all(x is not None for x in chosen) if dish_was_changed or not all_choices_present: - user_name = form.user_name.data if form.user_name.validate(form) else None + try: + user_name = form.user_name.data if form.user_name.validate(form) else None + except AttributeError: + user_name = None comment = form.comment.data if form.comment.validate(form) else None return redirect(url_for("order_bp.order_item_create", -- 2.43.4 From 8e414afe45d86b4eceeebbe24dbeebc0b3836474 Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 18:06:11 +0100 Subject: [PATCH 024/197] Refactor Ocean Garden again For clearer balls --- data/ocean_garden.hlds | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 3b5b993..abc6ec9 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -24,7 +24,6 @@ sauce: Saus gonboa: Gon-boa -- Pikante kruidensaus uit het westen van China curry: Curry sweetsour: Zoetzuur - sweetsour_and_balls: Zoetzuur, met bolletjes ipv bami/nasi/mihoen -- Nasi/mihoen worden vervangen door gepaneerde bolletjes € 3 oyster: Oester :: {has_fish} pepper: Pepersaus mushroom: Champignon -- Saus met champignon, wortel en wat andere groentjes @@ -61,10 +60,16 @@ dish wok3_chicken: Wok 3: kip zonder saus -- Met bami of nasi :: {has_meat} € dish wok3_pork: Wok 3: varken zonder saus -- Met bami of nasi :: {has_meat} € 6 single_choice bami_nasi -dish wok4: Vegetarische wok € 6 +dish wok4: Vegetarisch met saus € 6 single_choice bami_nasi single_choice sauce +dish wok_with_balls: Studentenwok met zoetzuur en gepaneerde balletjes -- Geen bami of nasi € 9 + single_choice meat: Vlees + chicken: Kip :: {has_meat} + pork: Varken :: {has_meat} + vege: Vegetarisch + # Vegetarian dishes dish chop_choy: 76. Chop Choy (veggie) -- Sojascheuten, met gebakken rijst € 9 dish tjap_tjoy: 77. Tjap Tjoy (veggie) -- Diverse groenten met gebakken rijst, veggie € 9 -- 2.43.4 From 11fc7093f38e7019764a04aa03d1cddbad8d9c06 Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 18:35:19 +0100 Subject: [PATCH 025/197] Hopefully clarify --- data/ocean_garden.hlds | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index abc6ec9..237a9a9 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -64,11 +64,9 @@ dish wok4: Vegetarisch met saus € 6 single_choice bami_nasi single_choice sauce -dish wok_with_balls: Studentenwok met zoetzuur en gepaneerde balletjes -- Geen bami of nasi € 9 - single_choice meat: Vlees - chicken: Kip :: {has_meat} - pork: Varken :: {has_meat} - vege: Vegetarisch +dish wok1_chicken_with_balls: Kip zoetzuur en gepaneerde balletjes -- Geen bami of nasi :: {has_meat} € 9 +dish wok1_pork_with_balls: Varken zoetzuur en gepaneerde balletjes -- Geen bami of nasi :: {has_meat} € 9 +dish wok4_with_balls: Vegetarisch zoetzuur en gepaneerde balletjes -- Geen bami of nasi € 9 # Vegetarian dishes dish chop_choy: 76. Chop Choy (veggie) -- Sojascheuten, met gebakken rijst € 9 -- 2.43.4 From b7552ce080fc22fe7035ac7ccc3478d3a42248aa Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 27 Feb 2020 19:06:27 +0100 Subject: [PATCH 026/197] Correct menu of Ocean Garden We phoned and saw what's possible and what not --- data/ocean_garden.hlds | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 237a9a9..00510ae 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -34,40 +34,30 @@ sauce: Saus dish wok5: Babi pangang -- Geroosterd varkensvlees :: {has_meat} € 6 single_choice bami_nasi -dish wok1_chicken: Kip met saus :: {has_meat} € 6 +dish wok1_chicken: Kip met saus :: {has_meat} € 6 + single_choice bami_nasi + single_choice sauce +dish wok1_pork: Varken met saus :: {has_meat} € 6 single_choice bami_nasi single_choice sauce -dish wok1_pork: Varken met saus :: {has_meat} € 6 +dish wok1_breaded_chicken: Kippenballetjes zoetzuur :: {has_meat} € 6 single_choice bami_nasi - single_choice sauce - -dish wok1_breaded_chicken: Kippenballetjes zoetzuur :: {has_meat} € 6 +dish wok1_breaded_pork: Varkensballetjes zoetzuur :: {has_meat} € 6 single_choice bami_nasi -dish wok1_breaded_pork: Varkensballetjes zoetzuur :: {has_meat} € 6 - single_choice bami_nasi - -dish wok2_chicken: Wok 2: kip zonder saus -- Met bami of mihoen :: {has_meat} € 6 +dish wok2_chicken: Wok 2: kip zonder saus -- Met bami of mihoen :: {has_meat} € 6 + single_choice bami_mihoen +dish wok2_pork: Wok 2: varken zonder saus -- Met bami of mihoen :: {has_meat} € 6 single_choice bami_mihoen -dish wok2_pork: Wok 2: varken zonder saus -- Met bami of mihoen :: {has_meat} € 6 - single_choice bami_mihoen - -dish wok3_chicken: Wok 3: kip zonder saus -- Met bami of nasi :: {has_meat} € 6 - single_choice bami_nasi - -dish wok3_pork: Wok 3: varken zonder saus -- Met bami of nasi :: {has_meat} € 6 - single_choice bami_nasi +dish wok3_chicken: Wok 3: kip met rijst zonder saus :: {has_meat} € 6 +dish wok3_pork: Wok 3: varken met rijst zonder saus :: {has_meat} € 6 dish wok4: Vegetarisch met saus € 6 single_choice bami_nasi single_choice sauce -dish wok1_chicken_with_balls: Kip zoetzuur en gepaneerde balletjes -- Geen bami of nasi :: {has_meat} € 9 -dish wok1_pork_with_balls: Varken zoetzuur en gepaneerde balletjes -- Geen bami of nasi :: {has_meat} € 9 -dish wok4_with_balls: Vegetarisch zoetzuur en gepaneerde balletjes -- Geen bami of nasi € 9 - # Vegetarian dishes dish chop_choy: 76. Chop Choy (veggie) -- Sojascheuten, met gebakken rijst € 9 dish tjap_tjoy: 77. Tjap Tjoy (veggie) -- Diverse groenten met gebakken rijst, veggie € 9 -- 2.43.4 From aa331b6843f992c596fb1e0e3315ec7a7b779164 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 28 Feb 2020 13:43:39 +0100 Subject: [PATCH 027/197] Fix error when anonymous name has accidentally been allowed to be None --- app/models/order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/order.py b/app/models/order.py index a964cf9..360604c 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -52,7 +52,7 @@ class Order(db.Model): ) user["paid"] = user.get("paid", True) and item.paid user["dishes"] = user.get("dishes", []) + [item.dish_name] - group[item.get_name()] = user + group[str(item.get_name())] = user return group -- 2.43.4 From 649b3d4ac5ee21c42b62d0d4e510c81533523b34 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 28 Feb 2020 19:37:21 +0100 Subject: [PATCH 028/197] Update Simpizza --- data/simpizza.hlds | 70 ++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/data/simpizza.hlds b/data/simpizza.hlds index cbd9313..11872fb 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -25,97 +25,101 @@ garlic_sauce: Looksaus no_garlic_sauce: Geen extra looksaus :: {no_text} yes_garlic_sauce: Met looksaus (prijs onzeker) € 0.75 -dish margherita: Pizza margherita -- Veggie +dish margherita: Pizza margherita (veggie) single_choice size single_choice garlic_sauce -dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} +dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} single_choice size single_choice garlic_sauce -dish hawaii: Pizza Hawaï :: {has_meat} +dish hawaii: Pizza Hawaï :: {has_meat} single_choice size single_choice garlic_sauce -dish popeye: Pizza Popeye -- Veggie +dish popeye: Pizza Popeye (veggie) single_choice size single_choice garlic_sauce -dish pepperoni: Pizza pepperoni :: {has_meat} +dish pepperoni: Pizza pepperoni :: {has_meat} single_choice size single_choice garlic_sauce -dish seafood: Pizza seafood :: {has_meat} +dish seafood: Pizza seafood :: {has_meat} single_choice size single_choice garlic_sauce -dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} +dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} single_choice size single_choice garlic_sauce -dish salmon_delight: Pizza salmon delight :: {has_meat} +dish salmon_delight: Pizza salmon delight :: {has_meat} single_choice size single_choice garlic_sauce -dish full_option: Pizza full option :: {has_meat} +dish full_option: Pizza full option :: {has_meat} single_choice size single_choice garlic_sauce -dish pitza_kebab: Pitza kebab -- Heeft al looksaus :: {has_meat} +dish pitza_kebab: Pitza kebab -- Heeft al potje looksaus :: {has_meat} single_choice size -dish multi_cheese: Pizza multi cheese -- Veggie +dish multi_cheese: Pizza multi cheese (veggie) single_choice size single_choice garlic_sauce -dish 4_seasons: Pizza 4 seasons :: {has_meat} +dish 4_seasons: Pizza 4 seasons :: {has_meat} single_choice size single_choice garlic_sauce -dish mega_fish: Pizza mega fish :: {has_meat} +dish mega_fish: Pizza mega fish :: {has_meat} single_choice size single_choice garlic_sauce -dish creamy_multi_cheese: Pizza creamy multi cheese -- Veggie +dish creamy_multi_cheese: Pizza creamy multi cheese (veggie) single_choice size -dish green_fiesta: Pizza green fiësta -- Heeft al looksaus :: {has_meat} +dish green_fiesta: Pizza green fiësta -- Heeft al potje looksaus :: {has_meat} single_choice size dish veggie: Pizza veggie single_choice size single_choice garlic_sauce -dish meat_lovers: Pizza meat lovers :: {has_meat} +dish meat_lovers: Pizza meat lovers :: {has_meat} single_choice size single_choice garlic_sauce -dish scampi_mampi: Pizza scampi mampi :: {has_meat} +dish meat_lovers_deluxe: Pizza meat lovers deluxe -- Heeft al swirl van looksaus :: {has_meat} € 2 + single_choice size +dish scampi_mampi: Pizza scampi mampi :: {has_meat} single_choice size single_choice garlic_sauce -dish tabasco: Pizza tabasco :: {has_meat} +dish tabasco: Pizza tabasco :: {has_meat} single_choice size single_choice garlic_sauce -dish funky_chicken: Pizza funky chicken :: {has_meat} +dish funky_chicken: Pizza funky chicken :: {has_meat} single_choice size single_choice garlic_sauce -dish chicken_time: Pizza chicken time :: {has_meat} +dish chicken_time: Pizza chicken time :: {has_meat} single_choice size single_choice garlic_sauce -dish creamy_chicken: Pizza creamy chicken -- Heeft al looksaus :: {has_meat} +dish creamy_chicken: Pizza creamy chicken -- Heeft al potje looksaus :: {has_meat} single_choice size -dish spicy_chicken: Pizza spicy chicken -- Heeft al looksaus :: {has_meat} +dish spicy_chicken: Pizza spicy chicken -- Heeft al potje looksaus :: {has_meat} single_choice size -dish meatballs: Pizza meatballs :: {has_meat} +dish meatballs: Pizza meatballs :: {has_meat} single_choice size single_choice garlic_sauce -dish tuna: Pizza tuna :: {has_meat} +dish tuna: Pizza tuna :: {has_meat} single_choice size single_choice garlic_sauce -dish anchovy: Pizza anchovy :: {has_meat} +dish anchovy: Pizza anchovy :: {has_meat} single_choice size single_choice garlic_sauce -dish calzone: Pizza calzone :: {has_meat} +dish calzone: Pizza calzone :: {has_meat} single_choice size single_choice garlic_sauce -dish hot_bolognese: Pizza hot bolognese :: {has_meat} +dish hot_bolognese: Pizza hot bolognese :: {has_meat} single_choice size single_choice garlic_sauce -dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} +dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} single_choice size single_choice garlic_sauce -dish curry: Pizza curry -- Heeft al looksaus :: {has_meat} +dish curry: Pizza curry -- Heeft al potje looksaus :: {has_meat} single_choice size -dish bbq_chicken: Pizza chicken barbecue :: {has_meat} +dish bbq_chicken: Pizza chicken barbecue :: {has_meat} single_choice size single_choice garlic_sauce -dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} +dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} single_choice size single_choice garlic_sauce -dish bbq_bacon: Pizza barbecue bacon -- Heeft al looksaus :: {has_meat} +dish bbq_bacon: Pizza barbecue bacon -- Heeft al potje looksaus :: {has_meat} single_choice size -dish bbq_special: Pizza barbecue special -- Heeft al looksaus :: {has_meat} +dish bbq_special: Pizza barbecue special -- Heeft al potje looksaus :: {has_meat} + single_choice size +dish bbq_merguez: Pizza merguez -- Heeft al swirl van looksaus :: {has_meat} single_choice size -- 2.43.4 From 8aa50d1bd9581bdae4747b77ae891ae1799203da Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 00:07:19 +0100 Subject: [PATCH 029/197] Improve HLDS documentation --- data/README.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/data/README.md b/data/README.md index c489a4a..51aee8c 100644 --- a/data/README.md +++ b/data/README.md @@ -9,15 +9,15 @@ There is syntax highlighting support for editors in `etc/` in the Haldis reposit Indentation requires hard **tabs**. Spaces will not work. ## Identifiers -You must choose an identifier for each location, dish, choice and option. Identifiers may consist -of numbers, hyphens, underscores and lowercase letters. +You must choose an identifier for each location, dish, choice, option and tag. Identifiers may +consist of numbers, hyphens, underscores and lowercase letters of the alphabet (a through z). -* Good: `my_identifier-007` -* Bad: ~~`My Identifié 007`~~ +* Allowed: `0-my_identifier` +* Disallowed: ~~`0 My Identifié`~~ ## Locations -A HLDS file consists of one or more locations. Each location starts with a header, which enclosed +A HLDS file consists of one or more locations. Each location starts with a header, which is enclosed in "fences" of at least three equal signs. The first line of the header contains the ID and name of the location. Further lines contain the metadata of the location, such as the phone number and OpenStreetMap element. In the future, the phone number and such will be fetched from OpenStreetMap. @@ -86,7 +86,7 @@ dish dishid: Name -- This is a description € 3 ## Tags -**Note:** HLDS tags are not supported in Haldis yet. You can ignore them. +**Note:** Only the `{no_text}` tag is supported at this moment. You can ignore other tags for now. You can add tags after ` :: `. Tags are `{identifier}`. You can use tags to attach more information about a dish or option in a structured way. For example: `{has_meat}` signals to vegetarians that @@ -97,3 +97,14 @@ The order is always id, name, description, tags, price (not all have to be prese ```hlds dish dishid: Name -- This is a description :: {has_meat} € 3 ``` + +The `{no_text}` tag signals that an option is not to be shown in a dish's description. This is +useful for choices that have a default that needs not be read when ordering. + +```hlds +veggie: Vegetarische opties + meat: Niet vegetarisch :: {has_meat} {no_text} + tofu: Vegetarisch met tofu + falafel: Vegetarisch met falafel + vegan: Veganistisch +``` -- 2.43.4 From 172d5d1e085eea4da0f1e4c3876aa4e685e35a27 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 15:40:14 +0100 Subject: [PATCH 030/197] Fix dish change detection once and for all --- app/templates/order.html | 2 +- app/views/order.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 7d091a7..cc3bba6 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -53,8 +53,8 @@ {{ util.render_form_field_errors(form.dish_id) }} + {% if dish and dish.choices %} - {% for (choice_type, choice) in dish.choices %}

diff --git a/app/views/order.py b/app/views/order.py index 8b407cf..c19a7c8 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -134,8 +134,8 @@ def order_item_create(order_id: int) -> typing.Any: form.populate(current_order.location) if form.is_submitted(): - form_for_dish = request.form.get("form_for_dish_id") - dish_was_changed = form_for_dish is not None and form_for_dish != dish_id + form_for_dish = request.form["form_for_dish"] + dish_was_changed = form_for_dish != "" and form_for_dish != dish_id # The form's validation tests that dish_id is valid and gives a friendly error if it's not choices = location.dish_by_id(form.dish_id.data).choices -- 2.43.4 From b44d34003db6acfb9abda73414b81eac1b4549af Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 17:23:20 +0100 Subject: [PATCH 031/197] Make whitespace match convention Convention according to our EditorConfig. --- .editorconfig | 5 +- README.md | 12 +- app/database/muhscheme.txt | 52 +- .../css/bootstrap-datetimepicker.min.css | 478 +- app/static/css/bootstrap.css | 7400 ++++++++--------- app/static/css/bootstrap.min.css | 10 +- app/static/css/darkmode.css | 60 +- app/static/css/leaflet.css | 1270 +-- app/static/css/main.css | 258 +- app/static/css/map.css | 8 +- app/static/css/print.css | 28 +- .../css/themes/highPerformance/darkmode.css | 18 +- .../themes/highPerformance/dataPrivacy.css | 6 +- .../css/themes/highPerformance/halloween.css | 20 +- .../css/themes/highPerformance/kerstmis.css | 682 +- .../css/themes/highPerformance/kerstmis.scss | 360 +- .../css/themes/highPerformance/lightmode.css | 16 +- .../themes/highPerformance/sinterklaas.css | 20 +- .../css/themes/lowPerformance/darkmode.css | 18 +- .../css/themes/lowPerformance/dataPrivacy.css | 6 +- .../css/themes/lowPerformance/halloween.css | 20 +- .../css/themes/lowPerformance/kerstmis.css | 548 +- .../css/themes/lowPerformance/kerstmis.scss | 290 +- .../css/themes/lowPerformance/lightmode.css | 16 +- .../css/themes/lowPerformance/sinterklaas.css | 20 +- .../fonts/glyphicons-halflings-regular.svg | 2 +- app/static/js/bootstrap-datetimepicker.min.js | 14 +- app/static/js/bootstrap.min.js | 10 +- app/static/js/customThemes.js | 18 +- app/static/js/leaflet.js | 8 +- app/static/js/map.js | 96 +- app/static/js/theme.js | 15 +- app/static/js/timer.js | 64 +- app/templates/about.html | 4 +- app/templates/errors/401.html | 12 +- app/templates/errors/404.html | 12 +- app/templates/home.html | 62 +- app/templates/layout.html | 128 +- app/templates/location.html | 92 +- app/templates/locations.html | 44 +- app/templates/maps.html | 27 +- app/templates/order.html | 356 +- app/templates/order_edit.html | 131 +- app/templates/order_items.html | 66 +- app/templates/orders.html | 161 +- app/templates/profile.html | 26 +- app/templates/stats.html | 22 +- app/templates/utils.html | 30 +- app/views/themes.yml | 32 +- etc/vscode/language-configuration.json | 58 +- etc/vscode/package.json | 58 +- etc/vscode/syntaxes/injections.json | 68 +- first-setup.sh | 6 +- 53 files changed, 6623 insertions(+), 6620 deletions(-) diff --git a/.editorconfig b/.editorconfig index 6596fa2..7a5daa9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,6 +8,9 @@ end_of_line = lf insert_final_newline = true indent_style = tab -[*.py] +[*.py,*.py.*] indent_style = space indent_size = 4 + +[*.el] +indent_style = space diff --git a/README.md b/README.md index 8ee5972..785f9a9 100644 --- a/README.md +++ b/README.md @@ -15,30 +15,30 @@ Be lazier today! There is a special script to get started with the project. Just run it in the root of the project. - ./first-setup.sh + ./first-setup.sh This will create a virtual environment, install the necessary dependencies and will give you the option to seed the database. If you are using a database other then sqlite you will first need to configure the correct URI to the database in the generated 'config.py' file. Afterwards upgrade the database to the latest version using - cd app - python3 app.py db upgrade + cd app + python3 app.py db upgrade You can now still seed the database by running - ./populate-db.sh + ./populate-db.sh in the root folder of the project. Activate the virtual environment using - source venv/bin/activate + source venv/bin/activate Finally run the webserver with - python3 app/app.py runserver + python3 app/app.py runserver Make sure to use localhost instead of 127.0.0.1 if you want to be able to login. diff --git a/app/database/muhscheme.txt b/app/database/muhscheme.txt index 711c142..173ff3c 100644 --- a/app/database/muhscheme.txt +++ b/app/database/muhscheme.txt @@ -3,35 +3,35 @@ to automatically generate anything. For the latest version, check the files in a user - username - is_admin - bias + username + is_admin + bias order - id - courier_id - location_id HLDS identifier - location_name this allows historical orders to keep the same location name - starttime - stoptime - public + id + courier_id + location_id HLDS identifier + location_name this allows historical orders to keep the same location name + starttime + stoptime + public order_item - id - order_id - user_id - user_name for users who are not logged in - dish_id HLDS identifier - dish_name ) this allows historical orders to keep their correct name and price - price ) - paid - comment - hlds_data_version Git commit hash to identify HLDS data version + id + order_id + user_id + user_name for users who are not logged in + dish_id HLDS identifier + dish_name ) this allows historical orders to keep their correct name and price + price ) + paid + comment + hlds_data_version Git commit hash to identify HLDS data version order_item_choice - id - order_item_id - choice_id HLDS identifier - kind single_choice/multi_choice - name - value just a textual description of the chosen values + id + order_item_id + choice_id HLDS identifier + kind single_choice/multi_choice + name + value just a textual description of the chosen values diff --git a/app/static/css/bootstrap-datetimepicker.min.css b/app/static/css/bootstrap-datetimepicker.min.css index c702161..d65292b 100755 --- a/app/static/css/bootstrap-datetimepicker.min.css +++ b/app/static/css/bootstrap-datetimepicker.min.css @@ -1,366 +1,366 @@ /*! - * Datetimepicker for Bootstrap 3 - * ! version : 4.7.14 - * https://github.com/Eonasdan/bootstrap-datetimepicker/ - */ +* Datetimepicker for Bootstrap 3 +* ! version : 4.7.14 +* https://github.com/Eonasdan/bootstrap-datetimepicker/ +*/ .bootstrap-datetimepicker-widget { - list-style: none; + list-style: none; } .bootstrap-datetimepicker-widget.dropdown-menu { - margin: 2px 0; - padding: 4px; - width: 19em; + margin: 2px 0; + padding: 4px; + width: 19em; } @media (min-width: 768px) { - .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { - width: 38em; - } + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } } @media (min-width: 992px) { - .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { - width: 38em; - } + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } } @media (min-width: 1200px) { - .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { - width: 38em; - } + .bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs { + width: 38em; + } } .bootstrap-datetimepicker-widget.dropdown-menu:before, .bootstrap-datetimepicker-widget.dropdown-menu:after { - content: ''; - display: inline-block; - position: absolute; + content: ''; + display: inline-block; + position: absolute; } .bootstrap-datetimepicker-widget.dropdown-menu.bottom:before { - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid #cccccc; - border-bottom-color: rgba(0, 0, 0, 0.2); - top: -7px; - left: 7px; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #cccccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + top: -7px; + left: 7px; } .bootstrap-datetimepicker-widget.dropdown-menu.bottom:after { - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid white; - top: -6px; - left: 8px; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + top: -6px; + left: 8px; } .bootstrap-datetimepicker-widget.dropdown-menu.top:before { - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-top: 7px solid #cccccc; - border-top-color: rgba(0, 0, 0, 0.2); - bottom: -7px; - left: 6px; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-top: 7px solid #cccccc; + border-top-color: rgba(0, 0, 0, 0.2); + bottom: -7px; + left: 6px; } .bootstrap-datetimepicker-widget.dropdown-menu.top:after { - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-top: 6px solid white; - bottom: -6px; - left: 7px; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid white; + bottom: -6px; + left: 7px; } .bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before { - left: auto; - right: 6px; + left: auto; + right: 6px; } .bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after { - left: auto; - right: 7px; + left: auto; + right: 7px; } .bootstrap-datetimepicker-widget .list-unstyled { - margin: 0; + margin: 0; } .bootstrap-datetimepicker-widget a[data-action] { - padding: 6px 0; + padding: 6px 0; } .bootstrap-datetimepicker-widget a[data-action]:active { - box-shadow: none; + box-shadow: none; } .bootstrap-datetimepicker-widget .timepicker-hour, .bootstrap-datetimepicker-widget .timepicker-minute, .bootstrap-datetimepicker-widget .timepicker-second { - width: 54px; - font-weight: bold; - font-size: 1.2em; - margin: 0; + width: 54px; + font-weight: bold; + font-size: 1.2em; + margin: 0; } .bootstrap-datetimepicker-widget button[data-action] { - padding: 6px; + padding: 6px; } .bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Increment Hours"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Increment Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Increment Minutes"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Increment Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Decrement Hours"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Decrement Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Decrement Minutes"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Decrement Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Show Hours"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Show Hours"; } .bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Show Minutes"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Show Minutes"; } .bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Toggle AM/PM"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Toggle AM/PM"; } .bootstrap-datetimepicker-widget .btn[data-action="clear"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Clear the picker"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Clear the picker"; } .bootstrap-datetimepicker-widget .btn[data-action="today"]::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Set the date to today"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Set the date to today"; } .bootstrap-datetimepicker-widget .picker-switch { - text-align: center; + text-align: center; } .bootstrap-datetimepicker-widget .picker-switch::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Toggle Date and Time Screens"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Toggle Date and Time Screens"; } .bootstrap-datetimepicker-widget .picker-switch td { - padding: 0; - margin: 0; - height: auto; - width: auto; - line-height: inherit; + padding: 0; + margin: 0; + height: auto; + width: auto; + line-height: inherit; } .bootstrap-datetimepicker-widget .picker-switch td span { - line-height: 2.5; - height: 2.5em; - width: 100%; + line-height: 2.5; + height: 2.5em; + width: 100%; } .bootstrap-datetimepicker-widget table { - width: 100%; - margin: 0; + width: 100%; + margin: 0; } .bootstrap-datetimepicker-widget table td, .bootstrap-datetimepicker-widget table th { - text-align: center; - border-radius: 4px; + text-align: center; + border-radius: 4px; } .bootstrap-datetimepicker-widget table th { - height: 20px; - line-height: 20px; - width: 20px; + height: 20px; + line-height: 20px; + width: 20px; } .bootstrap-datetimepicker-widget table th.picker-switch { - width: 145px; + width: 145px; } .bootstrap-datetimepicker-widget table th.disabled, .bootstrap-datetimepicker-widget table th.disabled:hover { - background: none; - color: #777777; - cursor: not-allowed; + background: none; + color: #777777; + cursor: not-allowed; } .bootstrap-datetimepicker-widget table th.prev::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Previous Month"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Previous Month"; } .bootstrap-datetimepicker-widget table th.next::after { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; - content: "Next Month"; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; + content: "Next Month"; } .bootstrap-datetimepicker-widget table thead tr:first-child th { - cursor: pointer; + cursor: pointer; } .bootstrap-datetimepicker-widget table thead tr:first-child th:hover { - background: #eeeeee; + background: #eeeeee; } .bootstrap-datetimepicker-widget table td { - height: 54px; - line-height: 54px; - width: 54px; + height: 54px; + line-height: 54px; + width: 54px; } .bootstrap-datetimepicker-widget table td.cw { - font-size: .8em; - height: 20px; - line-height: 20px; - color: #777777; + font-size: .8em; + height: 20px; + line-height: 20px; + color: #777777; } .bootstrap-datetimepicker-widget table td.day { - height: 20px; - line-height: 20px; - width: 20px; + height: 20px; + line-height: 20px; + width: 20px; } .bootstrap-datetimepicker-widget table td.day:hover, .bootstrap-datetimepicker-widget table td.hour:hover, .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td.second:hover { - background: #eeeeee; - cursor: pointer; + background: #eeeeee; + cursor: pointer; } .bootstrap-datetimepicker-widget table td.old, .bootstrap-datetimepicker-widget table td.new { - color: #777777; + color: #777777; } .bootstrap-datetimepicker-widget table td.today { - position: relative; + position: relative; } .bootstrap-datetimepicker-widget table td.today:before { - content: ''; - display: inline-block; - border: 0 0 7px 7px solid transparent; - border-bottom-color: #337ab7; - border-top-color: rgba(0, 0, 0, 0.2); - position: absolute; - bottom: 4px; - right: 4px; + content: ''; + display: inline-block; + border: 0 0 7px 7px solid transparent; + border-bottom-color: #337ab7; + border-top-color: rgba(0, 0, 0, 0.2); + position: absolute; + bottom: 4px; + right: 4px; } .bootstrap-datetimepicker-widget table td.active, .bootstrap-datetimepicker-widget table td.active:hover { - background-color: #337ab7; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #337ab7; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .bootstrap-datetimepicker-widget table td.active.today:before { - border-bottom-color: #fff; + border-bottom-color: #fff; } .bootstrap-datetimepicker-widget table td.disabled, .bootstrap-datetimepicker-widget table td.disabled:hover { - background: none; - color: #777777; - cursor: not-allowed; + background: none; + color: #777777; + cursor: not-allowed; } .bootstrap-datetimepicker-widget table td span { - display: inline-block; - width: 54px; - height: 54px; - line-height: 54px; - margin: 2px 1.5px; - cursor: pointer; - border-radius: 4px; + display: inline-block; + width: 54px; + height: 54px; + line-height: 54px; + margin: 2px 1.5px; + cursor: pointer; + border-radius: 4px; } .bootstrap-datetimepicker-widget table td span:hover { - background: #eeeeee; + background: #eeeeee; } .bootstrap-datetimepicker-widget table td span.active { - background-color: #337ab7; - color: #ffffff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #337ab7; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .bootstrap-datetimepicker-widget table td span.old { - color: #777777; + color: #777777; } .bootstrap-datetimepicker-widget table td span.disabled, .bootstrap-datetimepicker-widget table td span.disabled:hover { - background: none; - color: #777777; - cursor: not-allowed; + background: none; + color: #777777; + cursor: not-allowed; } .bootstrap-datetimepicker-widget.usetwentyfour td.hour { - height: 27px; - line-height: 27px; + height: 27px; + line-height: 27px; } .input-group.date .input-group-addon { - cursor: pointer; + cursor: pointer; } .sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; } diff --git a/app/static/css/bootstrap.css b/app/static/css/bootstrap.css index d22c365..cbb8329 100644 --- a/app/static/css/bootstrap.css +++ b/app/static/css/bootstrap.css @@ -1,18 +1,18 @@ /*! - * bootswatch v3.3.4+1 - * Homepage: http://bootswatch.com - * Copyright 2012-2015 Thomas Park - * Licensed under MIT - * Based on Bootstrap +* bootswatch v3.3.4+1 +* Homepage: http://bootswatch.com +* Copyright 2012-2015 Thomas Park +* Licensed under MIT +* Based on Bootstrap */ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ html { - font-family: sans-serif; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; } body { - margin: 0; + margin: 0; } article, aside, @@ -27,1151 +27,1151 @@ menu, nav, section, summary { - display: block; + display: block; } audio, canvas, progress, video { - display: inline-block; - vertical-align: baseline; + display: inline-block; + vertical-align: baseline; } audio:not([controls]) { - display: none; - height: 0; + display: none; + height: 0; } [hidden], template { - display: none; + display: none; } a { - background-color: transparent; + background-color: transparent; } a:active, a:hover { - outline: 0; + outline: 0; } abbr[title] { - border-bottom: 1px dotted; + border-bottom: 1px dotted; } b, strong { - font-weight: bold; + font-weight: bold; } dfn { - font-style: italic; + font-style: italic; } h1 { - font-size: 2em; - margin: 0.67em 0; + font-size: 2em; + margin: 0.67em 0; } mark { - background: #ff0; - color: #000; + background: #ff0; + color: #000; } small { - font-size: 80%; + font-size: 80%; } sub, sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } sup { - top: -0.5em; + top: -0.5em; } sub { - bottom: -0.25em; + bottom: -0.25em; } img { - border: 0; + border: 0; } svg:not(:root) { - overflow: hidden; + overflow: hidden; } figure { - margin: 1em 40px; + margin: 1em 40px; } hr { - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; - height: 0; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; + height: 0; } pre { - overflow: auto; + overflow: auto; } code, kbd, pre, samp { - font-family: monospace, monospace; - font-size: 1em; + font-family: monospace, monospace; + font-size: 1em; } button, input, optgroup, select, textarea { - color: inherit; - font: inherit; - margin: 0; + color: inherit; + font: inherit; + margin: 0; } button { - overflow: visible; + overflow: visible; } button, select { - text-transform: none; + text-transform: none; } button, html input[type="button"], input[type="reset"], input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; + -webkit-appearance: button; + cursor: pointer; } button[disabled], html input[disabled] { - cursor: default; + cursor: default; } button::-moz-focus-inner, input::-moz-focus-inner { - border: 0; - padding: 0; + border: 0; + padding: 0; } input { - line-height: normal; + line-height: normal; } input[type="checkbox"], input[type="radio"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { - height: auto; + height: auto; } input[type="search"] { - -webkit-appearance: textfield; - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; - box-sizing: content-box; + -webkit-appearance: textfield; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; + -webkit-appearance: none; } fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; } legend { - border: 0; - padding: 0; + border: 0; + padding: 0; } textarea { - overflow: auto; + overflow: auto; } optgroup { - font-weight: bold; + font-weight: bold; } table { - border-collapse: collapse; - border-spacing: 0; + border-collapse: collapse; + border-spacing: 0; } td, th { - padding: 0; + padding: 0; } /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ @media print { - *, - *:before, - *:after { - background: transparent !important; - color: #000 !important; - -webkit-box-shadow: none !important; - box-shadow: none !important; - text-shadow: none !important; - } - a, - a:visited { - text-decoration: underline; - } - a[href]:after { - content: " (" attr(href) ")"; - } - abbr[title]:after { - content: " (" attr(title) ")"; - } - a[href^="#"]:after, - a[href^="javascript:"]:after { - content: ""; - } - pre, - blockquote { - border: 1px solid #999; - page-break-inside: avoid; - } - thead { - display: table-header-group; - } - tr, - img { - page-break-inside: avoid; - } - img { - max-width: 100% !important; - } - p, - h2, - h3 { - orphans: 3; - widows: 3; - } - h2, - h3 { - page-break-after: avoid; - } - select { - background: #fff !important; - } - .navbar { - display: none; - } - .btn > .caret, - .dropup > .btn > .caret { - border-top-color: #000 !important; - } - .label { - border: 1px solid #000; - } - .table { - border-collapse: collapse !important; - } - .table td, - .table th { - background-color: #fff !important; - } - .table-bordered th, - .table-bordered td { - border: 1px solid #ddd !important; - } + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } } @font-face { - font-family: 'Glyphicons Halflings'; - src: url('../fonts/glyphicons-halflings-regular.eot'); - src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); } .glyphicon { - position: relative; - top: 1px; - display: inline-block; - font-family: 'Glyphicons Halflings'; - font-style: normal; - font-weight: normal; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { - content: "\2a"; + content: "\2a"; } .glyphicon-plus:before { - content: "\2b"; + content: "\2b"; } .glyphicon-euro:before, .glyphicon-eur:before { - content: "\20ac"; + content: "\20ac"; } .glyphicon-minus:before { - content: "\2212"; + content: "\2212"; } .glyphicon-cloud:before { - content: "\2601"; + content: "\2601"; } .glyphicon-envelope:before { - content: "\2709"; + content: "\2709"; } .glyphicon-pencil:before { - content: "\270f"; + content: "\270f"; } .glyphicon-glass:before { - content: "\e001"; + content: "\e001"; } .glyphicon-music:before { - content: "\e002"; + content: "\e002"; } .glyphicon-search:before { - content: "\e003"; + content: "\e003"; } .glyphicon-heart:before { - content: "\e005"; + content: "\e005"; } .glyphicon-star:before { - content: "\e006"; + content: "\e006"; } .glyphicon-star-empty:before { - content: "\e007"; + content: "\e007"; } .glyphicon-user:before { - content: "\e008"; + content: "\e008"; } .glyphicon-film:before { - content: "\e009"; + content: "\e009"; } .glyphicon-th-large:before { - content: "\e010"; + content: "\e010"; } .glyphicon-th:before { - content: "\e011"; + content: "\e011"; } .glyphicon-th-list:before { - content: "\e012"; + content: "\e012"; } .glyphicon-ok:before { - content: "\e013"; + content: "\e013"; } .glyphicon-remove:before { - content: "\e014"; + content: "\e014"; } .glyphicon-zoom-in:before { - content: "\e015"; + content: "\e015"; } .glyphicon-zoom-out:before { - content: "\e016"; + content: "\e016"; } .glyphicon-off:before { - content: "\e017"; + content: "\e017"; } .glyphicon-signal:before { - content: "\e018"; + content: "\e018"; } .glyphicon-cog:before { - content: "\e019"; + content: "\e019"; } .glyphicon-trash:before { - content: "\e020"; + content: "\e020"; } .glyphicon-home:before { - content: "\e021"; + content: "\e021"; } .glyphicon-file:before { - content: "\e022"; + content: "\e022"; } .glyphicon-time:before { - content: "\e023"; + content: "\e023"; } .glyphicon-road:before { - content: "\e024"; + content: "\e024"; } .glyphicon-download-alt:before { - content: "\e025"; + content: "\e025"; } .glyphicon-download:before { - content: "\e026"; + content: "\e026"; } .glyphicon-upload:before { - content: "\e027"; + content: "\e027"; } .glyphicon-inbox:before { - content: "\e028"; + content: "\e028"; } .glyphicon-play-circle:before { - content: "\e029"; + content: "\e029"; } .glyphicon-repeat:before { - content: "\e030"; + content: "\e030"; } .glyphicon-refresh:before { - content: "\e031"; + content: "\e031"; } .glyphicon-list-alt:before { - content: "\e032"; + content: "\e032"; } .glyphicon-lock:before { - content: "\e033"; + content: "\e033"; } .glyphicon-flag:before { - content: "\e034"; + content: "\e034"; } .glyphicon-headphones:before { - content: "\e035"; + content: "\e035"; } .glyphicon-volume-off:before { - content: "\e036"; + content: "\e036"; } .glyphicon-volume-down:before { - content: "\e037"; + content: "\e037"; } .glyphicon-volume-up:before { - content: "\e038"; + content: "\e038"; } .glyphicon-qrcode:before { - content: "\e039"; + content: "\e039"; } .glyphicon-barcode:before { - content: "\e040"; + content: "\e040"; } .glyphicon-tag:before { - content: "\e041"; + content: "\e041"; } .glyphicon-tags:before { - content: "\e042"; + content: "\e042"; } .glyphicon-book:before { - content: "\e043"; + content: "\e043"; } .glyphicon-bookmark:before { - content: "\e044"; + content: "\e044"; } .glyphicon-print:before { - content: "\e045"; + content: "\e045"; } .glyphicon-camera:before { - content: "\e046"; + content: "\e046"; } .glyphicon-font:before { - content: "\e047"; + content: "\e047"; } .glyphicon-bold:before { - content: "\e048"; + content: "\e048"; } .glyphicon-italic:before { - content: "\e049"; + content: "\e049"; } .glyphicon-text-height:before { - content: "\e050"; + content: "\e050"; } .glyphicon-text-width:before { - content: "\e051"; + content: "\e051"; } .glyphicon-align-left:before { - content: "\e052"; + content: "\e052"; } .glyphicon-align-center:before { - content: "\e053"; + content: "\e053"; } .glyphicon-align-right:before { - content: "\e054"; + content: "\e054"; } .glyphicon-align-justify:before { - content: "\e055"; + content: "\e055"; } .glyphicon-list:before { - content: "\e056"; + content: "\e056"; } .glyphicon-indent-left:before { - content: "\e057"; + content: "\e057"; } .glyphicon-indent-right:before { - content: "\e058"; + content: "\e058"; } .glyphicon-facetime-video:before { - content: "\e059"; + content: "\e059"; } .glyphicon-picture:before { - content: "\e060"; + content: "\e060"; } .glyphicon-map-marker:before { - content: "\e062"; + content: "\e062"; } .glyphicon-adjust:before { - content: "\e063"; + content: "\e063"; } .glyphicon-tint:before { - content: "\e064"; + content: "\e064"; } .glyphicon-edit:before { - content: "\e065"; + content: "\e065"; } .glyphicon-share:before { - content: "\e066"; + content: "\e066"; } .glyphicon-check:before { - content: "\e067"; + content: "\e067"; } .glyphicon-move:before { - content: "\e068"; + content: "\e068"; } .glyphicon-step-backward:before { - content: "\e069"; + content: "\e069"; } .glyphicon-fast-backward:before { - content: "\e070"; + content: "\e070"; } .glyphicon-backward:before { - content: "\e071"; + content: "\e071"; } .glyphicon-play:before { - content: "\e072"; + content: "\e072"; } .glyphicon-pause:before { - content: "\e073"; + content: "\e073"; } .glyphicon-stop:before { - content: "\e074"; + content: "\e074"; } .glyphicon-forward:before { - content: "\e075"; + content: "\e075"; } .glyphicon-fast-forward:before { - content: "\e076"; + content: "\e076"; } .glyphicon-step-forward:before { - content: "\e077"; + content: "\e077"; } .glyphicon-eject:before { - content: "\e078"; + content: "\e078"; } .glyphicon-chevron-left:before { - content: "\e079"; + content: "\e079"; } .glyphicon-chevron-right:before { - content: "\e080"; + content: "\e080"; } .glyphicon-plus-sign:before { - content: "\e081"; + content: "\e081"; } .glyphicon-minus-sign:before { - content: "\e082"; + content: "\e082"; } .glyphicon-remove-sign:before { - content: "\e083"; + content: "\e083"; } .glyphicon-ok-sign:before { - content: "\e084"; + content: "\e084"; } .glyphicon-question-sign:before { - content: "\e085"; + content: "\e085"; } .glyphicon-info-sign:before { - content: "\e086"; + content: "\e086"; } .glyphicon-screenshot:before { - content: "\e087"; + content: "\e087"; } .glyphicon-remove-circle:before { - content: "\e088"; + content: "\e088"; } .glyphicon-ok-circle:before { - content: "\e089"; + content: "\e089"; } .glyphicon-ban-circle:before { - content: "\e090"; + content: "\e090"; } .glyphicon-arrow-left:before { - content: "\e091"; + content: "\e091"; } .glyphicon-arrow-right:before { - content: "\e092"; + content: "\e092"; } .glyphicon-arrow-up:before { - content: "\e093"; + content: "\e093"; } .glyphicon-arrow-down:before { - content: "\e094"; + content: "\e094"; } .glyphicon-share-alt:before { - content: "\e095"; + content: "\e095"; } .glyphicon-resize-full:before { - content: "\e096"; + content: "\e096"; } .glyphicon-resize-small:before { - content: "\e097"; + content: "\e097"; } .glyphicon-exclamation-sign:before { - content: "\e101"; + content: "\e101"; } .glyphicon-gift:before { - content: "\e102"; + content: "\e102"; } .glyphicon-leaf:before { - content: "\e103"; + content: "\e103"; } .glyphicon-fire:before { - content: "\e104"; + content: "\e104"; } .glyphicon-eye-open:before { - content: "\e105"; + content: "\e105"; } .glyphicon-eye-close:before { - content: "\e106"; + content: "\e106"; } .glyphicon-warning-sign:before { - content: "\e107"; + content: "\e107"; } .glyphicon-plane:before { - content: "\e108"; + content: "\e108"; } .glyphicon-calendar:before { - content: "\e109"; + content: "\e109"; } .glyphicon-random:before { - content: "\e110"; + content: "\e110"; } .glyphicon-comment:before { - content: "\e111"; + content: "\e111"; } .glyphicon-magnet:before { - content: "\e112"; + content: "\e112"; } .glyphicon-chevron-up:before { - content: "\e113"; + content: "\e113"; } .glyphicon-chevron-down:before { - content: "\e114"; + content: "\e114"; } .glyphicon-retweet:before { - content: "\e115"; + content: "\e115"; } .glyphicon-shopping-cart:before { - content: "\e116"; + content: "\e116"; } .glyphicon-folder-close:before { - content: "\e117"; + content: "\e117"; } .glyphicon-folder-open:before { - content: "\e118"; + content: "\e118"; } .glyphicon-resize-vertical:before { - content: "\e119"; + content: "\e119"; } .glyphicon-resize-horizontal:before { - content: "\e120"; + content: "\e120"; } .glyphicon-hdd:before { - content: "\e121"; + content: "\e121"; } .glyphicon-bullhorn:before { - content: "\e122"; + content: "\e122"; } .glyphicon-bell:before { - content: "\e123"; + content: "\e123"; } .glyphicon-certificate:before { - content: "\e124"; + content: "\e124"; } .glyphicon-thumbs-up:before { - content: "\e125"; + content: "\e125"; } .glyphicon-thumbs-down:before { - content: "\e126"; + content: "\e126"; } .glyphicon-hand-right:before { - content: "\e127"; + content: "\e127"; } .glyphicon-hand-left:before { - content: "\e128"; + content: "\e128"; } .glyphicon-hand-up:before { - content: "\e129"; + content: "\e129"; } .glyphicon-hand-down:before { - content: "\e130"; + content: "\e130"; } .glyphicon-circle-arrow-right:before { - content: "\e131"; + content: "\e131"; } .glyphicon-circle-arrow-left:before { - content: "\e132"; + content: "\e132"; } .glyphicon-circle-arrow-up:before { - content: "\e133"; + content: "\e133"; } .glyphicon-circle-arrow-down:before { - content: "\e134"; + content: "\e134"; } .glyphicon-globe:before { - content: "\e135"; + content: "\e135"; } .glyphicon-wrench:before { - content: "\e136"; + content: "\e136"; } .glyphicon-tasks:before { - content: "\e137"; + content: "\e137"; } .glyphicon-filter:before { - content: "\e138"; + content: "\e138"; } .glyphicon-briefcase:before { - content: "\e139"; + content: "\e139"; } .glyphicon-fullscreen:before { - content: "\e140"; + content: "\e140"; } .glyphicon-dashboard:before { - content: "\e141"; + content: "\e141"; } .glyphicon-paperclip:before { - content: "\e142"; + content: "\e142"; } .glyphicon-heart-empty:before { - content: "\e143"; + content: "\e143"; } .glyphicon-link:before { - content: "\e144"; + content: "\e144"; } .glyphicon-phone:before { - content: "\e145"; + content: "\e145"; } .glyphicon-pushpin:before { - content: "\e146"; + content: "\e146"; } .glyphicon-usd:before { - content: "\e148"; + content: "\e148"; } .glyphicon-gbp:before { - content: "\e149"; + content: "\e149"; } .glyphicon-sort:before { - content: "\e150"; + content: "\e150"; } .glyphicon-sort-by-alphabet:before { - content: "\e151"; + content: "\e151"; } .glyphicon-sort-by-alphabet-alt:before { - content: "\e152"; + content: "\e152"; } .glyphicon-sort-by-order:before { - content: "\e153"; + content: "\e153"; } .glyphicon-sort-by-order-alt:before { - content: "\e154"; + content: "\e154"; } .glyphicon-sort-by-attributes:before { - content: "\e155"; + content: "\e155"; } .glyphicon-sort-by-attributes-alt:before { - content: "\e156"; + content: "\e156"; } .glyphicon-unchecked:before { - content: "\e157"; + content: "\e157"; } .glyphicon-expand:before { - content: "\e158"; + content: "\e158"; } .glyphicon-collapse-down:before { - content: "\e159"; + content: "\e159"; } .glyphicon-collapse-up:before { - content: "\e160"; + content: "\e160"; } .glyphicon-log-in:before { - content: "\e161"; + content: "\e161"; } .glyphicon-flash:before { - content: "\e162"; + content: "\e162"; } .glyphicon-log-out:before { - content: "\e163"; + content: "\e163"; } .glyphicon-new-window:before { - content: "\e164"; + content: "\e164"; } .glyphicon-record:before { - content: "\e165"; + content: "\e165"; } .glyphicon-save:before { - content: "\e166"; + content: "\e166"; } .glyphicon-open:before { - content: "\e167"; + content: "\e167"; } .glyphicon-saved:before { - content: "\e168"; + content: "\e168"; } .glyphicon-import:before { - content: "\e169"; + content: "\e169"; } .glyphicon-export:before { - content: "\e170"; + content: "\e170"; } .glyphicon-send:before { - content: "\e171"; + content: "\e171"; } .glyphicon-floppy-disk:before { - content: "\e172"; + content: "\e172"; } .glyphicon-floppy-saved:before { - content: "\e173"; + content: "\e173"; } .glyphicon-floppy-remove:before { - content: "\e174"; + content: "\e174"; } .glyphicon-floppy-save:before { - content: "\e175"; + content: "\e175"; } .glyphicon-floppy-open:before { - content: "\e176"; + content: "\e176"; } .glyphicon-credit-card:before { - content: "\e177"; + content: "\e177"; } .glyphicon-transfer:before { - content: "\e178"; + content: "\e178"; } .glyphicon-cutlery:before { - content: "\e179"; + content: "\e179"; } .glyphicon-header:before { - content: "\e180"; + content: "\e180"; } .glyphicon-compressed:before { - content: "\e181"; + content: "\e181"; } .glyphicon-earphone:before { - content: "\e182"; + content: "\e182"; } .glyphicon-phone-alt:before { - content: "\e183"; + content: "\e183"; } .glyphicon-tower:before { - content: "\e184"; + content: "\e184"; } .glyphicon-stats:before { - content: "\e185"; + content: "\e185"; } .glyphicon-sd-video:before { - content: "\e186"; + content: "\e186"; } .glyphicon-hd-video:before { - content: "\e187"; + content: "\e187"; } .glyphicon-subtitles:before { - content: "\e188"; + content: "\e188"; } .glyphicon-sound-stereo:before { - content: "\e189"; + content: "\e189"; } .glyphicon-sound-dolby:before { - content: "\e190"; + content: "\e190"; } .glyphicon-sound-5-1:before { - content: "\e191"; + content: "\e191"; } .glyphicon-sound-6-1:before { - content: "\e192"; + content: "\e192"; } .glyphicon-sound-7-1:before { - content: "\e193"; + content: "\e193"; } .glyphicon-copyright-mark:before { - content: "\e194"; + content: "\e194"; } .glyphicon-registration-mark:before { - content: "\e195"; + content: "\e195"; } .glyphicon-cloud-download:before { - content: "\e197"; + content: "\e197"; } .glyphicon-cloud-upload:before { - content: "\e198"; + content: "\e198"; } .glyphicon-tree-conifer:before { - content: "\e199"; + content: "\e199"; } .glyphicon-tree-deciduous:before { - content: "\e200"; + content: "\e200"; } .glyphicon-cd:before { - content: "\e201"; + content: "\e201"; } .glyphicon-save-file:before { - content: "\e202"; + content: "\e202"; } .glyphicon-open-file:before { - content: "\e203"; + content: "\e203"; } .glyphicon-level-up:before { - content: "\e204"; + content: "\e204"; } .glyphicon-copy:before { - content: "\e205"; + content: "\e205"; } .glyphicon-paste:before { - content: "\e206"; + content: "\e206"; } .glyphicon-alert:before { - content: "\e209"; + content: "\e209"; } .glyphicon-equalizer:before { - content: "\e210"; + content: "\e210"; } .glyphicon-king:before { - content: "\e211"; + content: "\e211"; } .glyphicon-queen:before { - content: "\e212"; + content: "\e212"; } .glyphicon-pawn:before { - content: "\e213"; + content: "\e213"; } .glyphicon-bishop:before { - content: "\e214"; + content: "\e214"; } .glyphicon-knight:before { - content: "\e215"; + content: "\e215"; } .glyphicon-baby-formula:before { - content: "\e216"; + content: "\e216"; } .glyphicon-tent:before { - content: "\26fa"; + content: "\26fa"; } .glyphicon-blackboard:before { - content: "\e218"; + content: "\e218"; } .glyphicon-bed:before { - content: "\e219"; + content: "\e219"; } .glyphicon-apple:before { - content: "\f8ff"; + content: "\f8ff"; } .glyphicon-erase:before { - content: "\e221"; + content: "\e221"; } .glyphicon-hourglass:before { - content: "\231b"; + content: "\231b"; } .glyphicon-lamp:before { - content: "\e223"; + content: "\e223"; } .glyphicon-duplicate:before { - content: "\e224"; + content: "\e224"; } .glyphicon-piggy-bank:before { - content: "\e225"; + content: "\e225"; } .glyphicon-scissors:before { - content: "\e226"; + content: "\e226"; } .glyphicon-bitcoin:before { - content: "\e227"; + content: "\e227"; } .glyphicon-btc:before { - content: "\e227"; + content: "\e227"; } .glyphicon-xbt:before { - content: "\e227"; + content: "\e227"; } .glyphicon-yen:before { - content: "\00a5"; + content: "\00a5"; } .glyphicon-jpy:before { - content: "\00a5"; + content: "\00a5"; } .glyphicon-ruble:before { - content: "\20bd"; + content: "\20bd"; } .glyphicon-rub:before { - content: "\20bd"; + content: "\20bd"; } .glyphicon-scale:before { - content: "\e230"; + content: "\e230"; } .glyphicon-ice-lolly:before { - content: "\e231"; + content: "\e231"; } .glyphicon-ice-lolly-tasted:before { - content: "\e232"; + content: "\e232"; } .glyphicon-education:before { - content: "\e233"; + content: "\e233"; } .glyphicon-option-horizontal:before { - content: "\e234"; + content: "\e234"; } .glyphicon-option-vertical:before { - content: "\e235"; + content: "\e235"; } .glyphicon-menu-hamburger:before { - content: "\e236"; + content: "\e236"; } .glyphicon-modal-window:before { - content: "\e237"; + content: "\e237"; } .glyphicon-oil:before { - content: "\e238"; + content: "\e238"; } .glyphicon-grain:before { - content: "\e239"; + content: "\e239"; } .glyphicon-sunglasses:before { - content: "\e240"; + content: "\e240"; } .glyphicon-text-size:before { - content: "\e241"; + content: "\e241"; } .glyphicon-text-color:before { - content: "\e242"; + content: "\e242"; } .glyphicon-text-background:before { - content: "\e243"; + content: "\e243"; } .glyphicon-object-align-top:before { - content: "\e244"; + content: "\e244"; } .glyphicon-object-align-bottom:before { - content: "\e245"; + content: "\e245"; } .glyphicon-object-align-horizontal:before { - content: "\e246"; + content: "\e246"; } .glyphicon-object-align-left:before { - content: "\e247"; + content: "\e247"; } .glyphicon-object-align-vertical:before { - content: "\e248"; + content: "\e248"; } .glyphicon-object-align-right:before { - content: "\e249"; + content: "\e249"; } .glyphicon-triangle-right:before { - content: "\e250"; + content: "\e250"; } .glyphicon-triangle-left:before { - content: "\e251"; + content: "\e251"; } .glyphicon-triangle-bottom:before { - content: "\e252"; + content: "\e252"; } .glyphicon-triangle-top:before { - content: "\e253"; + content: "\e253"; } .glyphicon-console:before { - content: "\e254"; + content: "\e254"; } .glyphicon-superscript:before { - content: "\e255"; + content: "\e255"; } .glyphicon-subscript:before { - content: "\e256"; + content: "\e256"; } .glyphicon-menu-left:before { - content: "\e257"; + content: "\e257"; } .glyphicon-menu-right:before { - content: "\e258"; + content: "\e258"; } .glyphicon-menu-down:before { - content: "\e259"; + content: "\e259"; } .glyphicon-menu-up:before { - content: "\e260"; + content: "\e260"; } * { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } *:before, *:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } html { - font-size: 10px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { - font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - line-height: 1.846; - color: #666666; - background-color: #ffffff; + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 1.846; + color: #666666; + background-color: #ffffff; } input, button, select, textarea { - font-family: inherit; - font-size: inherit; - line-height: inherit; + font-family: inherit; + font-size: inherit; + line-height: inherit; } a { - color: #2196f3; - text-decoration: none; + color: #2196f3; + text-decoration: none; } a:hover, a:focus { - color: #0a6ebd; - text-decoration: underline; + color: #0a6ebd; + text-decoration: underline; } a:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } figure { - margin: 0; + margin: 0; } img { - vertical-align: middle; + vertical-align: middle; } .img-responsive, .thumbnail > img, .thumbnail a > img, .carousel-inner > .item > img, .carousel-inner > .item > a > img { - display: block; - max-width: 100%; - height: auto; + display: block; + max-width: 100%; + height: auto; } .img-rounded { - border-radius: 3px; + border-radius: 3px; } .img-thumbnail { - padding: 4px; - line-height: 1.846; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 3px; - -webkit-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; - display: inline-block; - max-width: 100%; - height: auto; + padding: 4px; + line-height: 1.846; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 3px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; } .img-circle { - border-radius: 50%; + border-radius: 50%; } hr { - margin-top: 23px; - margin-bottom: 23px; - border: 0; - border-top: 1px solid #eeeeee; + margin-top: 23px; + margin-bottom: 23px; + border: 0; + border-top: 1px solid #eeeeee; } .sr-only { - position: absolute; - width: 1px; - height: 1px; - margin: -1px; - padding: 0; - overflow: hidden; - clip: rect(0, 0, 0, 0); - border: 0; + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - margin: 0; - overflow: visible; - clip: auto; + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; } [role="button"] { - cursor: pointer; + cursor: pointer; } h1, h2, @@ -1185,10 +1185,10 @@ h6, .h4, .h5, .h6 { - font-family: inherit; - font-weight: 400; - line-height: 1.1; - color: #444444; + font-family: inherit; + font-weight: 400; + line-height: 1.1; + color: #444444; } h1 small, h2 small, @@ -1214,9 +1214,9 @@ h6 .small, .h4 .small, .h5 .small, .h6 .small { - font-weight: normal; - line-height: 1; - color: #bbbbbb; + font-weight: normal; + line-height: 1; + color: #bbbbbb; } h1, .h1, @@ -1224,8 +1224,8 @@ h2, .h2, h3, .h3 { - margin-top: 23px; - margin-bottom: 11.5px; + margin-top: 23px; + margin-bottom: 11.5px; } h1 small, .h1 small, @@ -1239,7 +1239,7 @@ h2 .small, .h2 .small, h3 .small, .h3 .small { - font-size: 65%; + font-size: 65%; } h4, .h4, @@ -1247,8 +1247,8 @@ h5, .h5, h6, .h6 { - margin-top: 11.5px; - margin-bottom: 11.5px; + margin-top: 11.5px; + margin-bottom: 11.5px; } h4 small, .h4 small, @@ -1262,241 +1262,241 @@ h5 .small, .h5 .small, h6 .small, .h6 .small { - font-size: 75%; + font-size: 75%; } h1, .h1 { - font-size: 56px; + font-size: 56px; } h2, .h2 { - font-size: 45px; + font-size: 45px; } h3, .h3 { - font-size: 34px; + font-size: 34px; } h4, .h4 { - font-size: 24px; + font-size: 24px; } h5, .h5 { - font-size: 20px; + font-size: 20px; } h6, .h6 { - font-size: 14px; + font-size: 14px; } p { - margin: 0 0 11.5px; + margin: 0 0 11.5px; } .lead { - margin-bottom: 23px; - font-size: 14px; - font-weight: 300; - line-height: 1.4; + margin-bottom: 23px; + font-size: 14px; + font-weight: 300; + line-height: 1.4; } @media (min-width: 768px) { - .lead { - font-size: 19.5px; - } + .lead { + font-size: 19.5px; + } } small, .small { - font-size: 92%; + font-size: 92%; } mark, .mark { - background-color: #ffe0b2; - padding: .2em; + background-color: #ffe0b2; + padding: .2em; } .text-left { - text-align: left; + text-align: left; } .text-right { - text-align: right; + text-align: right; } .text-center { - text-align: center; + text-align: center; } .text-justify { - text-align: justify; + text-align: justify; } .text-nowrap { - white-space: nowrap; + white-space: nowrap; } .text-lowercase { - text-transform: lowercase; + text-transform: lowercase; } .text-uppercase { - text-transform: uppercase; + text-transform: uppercase; } .text-capitalize { - text-transform: capitalize; + text-transform: capitalize; } .text-muted { - color: #bbbbbb; + color: #bbbbbb; } .text-primary { - color: #2196f3; + color: #2196f3; } a.text-primary:hover { - color: #0c7cd5; + color: #0c7cd5; } .text-success { - color: #4caf50; + color: #4caf50; } a.text-success:hover { - color: #3d8b40; + color: #3d8b40; } .text-info { - color: #9c27b0; + color: #9c27b0; } a.text-info:hover { - color: #771e86; + color: #771e86; } .text-warning { - color: #ff9800; + color: #ff9800; } a.text-warning:hover { - color: #cc7a00; + color: #cc7a00; } .text-danger { - color: #e51c23; + color: #e51c23; } a.text-danger:hover { - color: #b9151b; + color: #b9151b; } .bg-primary { - color: #fff; - background-color: #2196f3; + color: #fff; + background-color: #2196f3; } a.bg-primary:hover { - background-color: #0c7cd5; + background-color: #0c7cd5; } .bg-success { - background-color: #dff0d8; + background-color: #dff0d8; } a.bg-success:hover { - background-color: #c1e2b3; + background-color: #c1e2b3; } .bg-info { - background-color: #e1bee7; + background-color: #e1bee7; } a.bg-info:hover { - background-color: #d099d9; + background-color: #d099d9; } .bg-warning { - background-color: #ffe0b2; + background-color: #ffe0b2; } a.bg-warning:hover { - background-color: #ffcb7f; + background-color: #ffcb7f; } .bg-danger { - background-color: #f9bdbb; + background-color: #f9bdbb; } a.bg-danger:hover { - background-color: #f5908c; + background-color: #f5908c; } .page-header { - padding-bottom: 10.5px; - margin: 46px 0 23px; - border-bottom: 1px solid #eeeeee; + padding-bottom: 10.5px; + margin: 46px 0 23px; + border-bottom: 1px solid #eeeeee; } ul, ol { - margin-top: 0; - margin-bottom: 11.5px; + margin-top: 0; + margin-bottom: 11.5px; } ul ul, ol ul, ul ol, ol ol { - margin-bottom: 0; + margin-bottom: 0; } .list-unstyled { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } .list-inline { - padding-left: 0; - list-style: none; - margin-left: -5px; + padding-left: 0; + list-style: none; + margin-left: -5px; } .list-inline > li { - display: inline-block; - padding-left: 5px; - padding-right: 5px; + display: inline-block; + padding-left: 5px; + padding-right: 5px; } dl { - margin-top: 0; - margin-bottom: 23px; + margin-top: 0; + margin-bottom: 23px; } dt, dd { - line-height: 1.846; + line-height: 1.846; } dt { - font-weight: bold; + font-weight: bold; } dd { - margin-left: 0; + margin-left: 0; } @media (min-width: 768px) { - .dl-horizontal dt { - float: left; - width: 160px; - clear: left; - text-align: right; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - .dl-horizontal dd { - margin-left: 180px; - } + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } } abbr[title], abbr[data-original-title] { - cursor: help; - border-bottom: 1px dotted #bbbbbb; + cursor: help; + border-bottom: 1px dotted #bbbbbb; } .initialism { - font-size: 90%; - text-transform: uppercase; + font-size: 90%; + text-transform: uppercase; } blockquote { - padding: 11.5px 23px; - margin: 0 0 23px; - font-size: 16.25px; - border-left: 5px solid #eeeeee; + padding: 11.5px 23px; + margin: 0 0 23px; + font-size: 16.25px; + border-left: 5px solid #eeeeee; } blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { - margin-bottom: 0; + margin-bottom: 0; } blockquote footer, blockquote small, blockquote .small { - display: block; - font-size: 80%; - line-height: 1.846; - color: #bbbbbb; + display: block; + font-size: 80%; + line-height: 1.846; + color: #bbbbbb; } blockquote footer:before, blockquote small:before, blockquote .small:before { - content: '\2014 \00A0'; + content: '\2014 \00A0'; } .blockquote-reverse, blockquote.pull-right { - padding-right: 15px; - padding-left: 0; - border-right: 5px solid #eeeeee; - border-left: 0; - text-align: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; + text-align: right; } .blockquote-reverse footer:before, blockquote.pull-right footer:before, @@ -1504,7 +1504,7 @@ blockquote.pull-right footer:before, blockquote.pull-right small:before, .blockquote-reverse .small:before, blockquote.pull-right .small:before { - content: ''; + content: ''; } .blockquote-reverse footer:after, blockquote.pull-right footer:after, @@ -1512,750 +1512,750 @@ blockquote.pull-right footer:after, blockquote.pull-right small:after, .blockquote-reverse .small:after, blockquote.pull-right .small:after { - content: '\00A0 \2014'; + content: '\00A0 \2014'; } address { - margin-bottom: 23px; - font-style: normal; - line-height: 1.846; + margin-bottom: 23px; + font-style: normal; + line-height: 1.846; } code, kbd, pre, samp { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; } code { - padding: 2px 4px; - font-size: 90%; - color: #c7254e; - background-color: #f9f2f4; - border-radius: 3px; + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 3px; } kbd { - padding: 2px 4px; - font-size: 90%; - color: #ffffff; - background-color: #333333; - border-radius: 3px; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); + padding: 2px 4px; + font-size: 90%; + color: #ffffff; + background-color: #333333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); } kbd kbd { - padding: 0; - font-size: 100%; - font-weight: bold; - -webkit-box-shadow: none; - box-shadow: none; + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; } pre { - display: block; - padding: 11px; - margin: 0 0 11.5px; - font-size: 12px; - line-height: 1.846; - word-break: break-all; - word-wrap: break-word; - color: #212121; - background-color: #f5f5f5; - border: 1px solid #cccccc; - border-radius: 3px; + display: block; + padding: 11px; + margin: 0 0 11.5px; + font-size: 12px; + line-height: 1.846; + word-break: break-all; + word-wrap: break-word; + color: #212121; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 3px; } pre code { - padding: 0; - font-size: inherit; - color: inherit; - white-space: pre-wrap; - background-color: transparent; - border-radius: 0; + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; } .pre-scrollable { - max-height: 340px; - overflow-y: scroll; + max-height: 340px; + overflow-y: scroll; } .container { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } @media (min-width: 768px) { - .container { - width: 750px; - } + .container { + width: 750px; + } } @media (min-width: 992px) { - .container { - width: 970px; - } + .container { + width: 970px; + } } @media (min-width: 1200px) { - .container { - width: 1170px; - } + .container { + width: 1170px; + } } .container-fluid { - margin-right: auto; - margin-left: auto; - padding-left: 15px; - padding-right: 15px; + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; } .row { - margin-left: -15px; - margin-right: -15px; + margin-left: -15px; + margin-right: -15px; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { - position: relative; - min-height: 1px; - padding-left: 15px; - padding-right: 15px; + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { - float: left; + float: left; } .col-xs-12 { - width: 100%; + width: 100%; } .col-xs-11 { - width: 91.66666667%; + width: 91.66666667%; } .col-xs-10 { - width: 83.33333333%; + width: 83.33333333%; } .col-xs-9 { - width: 75%; + width: 75%; } .col-xs-8 { - width: 66.66666667%; + width: 66.66666667%; } .col-xs-7 { - width: 58.33333333%; + width: 58.33333333%; } .col-xs-6 { - width: 50%; + width: 50%; } .col-xs-5 { - width: 41.66666667%; + width: 41.66666667%; } .col-xs-4 { - width: 33.33333333%; + width: 33.33333333%; } .col-xs-3 { - width: 25%; + width: 25%; } .col-xs-2 { - width: 16.66666667%; + width: 16.66666667%; } .col-xs-1 { - width: 8.33333333%; + width: 8.33333333%; } .col-xs-pull-12 { - right: 100%; + right: 100%; } .col-xs-pull-11 { - right: 91.66666667%; + right: 91.66666667%; } .col-xs-pull-10 { - right: 83.33333333%; + right: 83.33333333%; } .col-xs-pull-9 { - right: 75%; + right: 75%; } .col-xs-pull-8 { - right: 66.66666667%; + right: 66.66666667%; } .col-xs-pull-7 { - right: 58.33333333%; + right: 58.33333333%; } .col-xs-pull-6 { - right: 50%; + right: 50%; } .col-xs-pull-5 { - right: 41.66666667%; + right: 41.66666667%; } .col-xs-pull-4 { - right: 33.33333333%; + right: 33.33333333%; } .col-xs-pull-3 { - right: 25%; + right: 25%; } .col-xs-pull-2 { - right: 16.66666667%; + right: 16.66666667%; } .col-xs-pull-1 { - right: 8.33333333%; + right: 8.33333333%; } .col-xs-pull-0 { - right: auto; + right: auto; } .col-xs-push-12 { - left: 100%; + left: 100%; } .col-xs-push-11 { - left: 91.66666667%; + left: 91.66666667%; } .col-xs-push-10 { - left: 83.33333333%; + left: 83.33333333%; } .col-xs-push-9 { - left: 75%; + left: 75%; } .col-xs-push-8 { - left: 66.66666667%; + left: 66.66666667%; } .col-xs-push-7 { - left: 58.33333333%; + left: 58.33333333%; } .col-xs-push-6 { - left: 50%; + left: 50%; } .col-xs-push-5 { - left: 41.66666667%; + left: 41.66666667%; } .col-xs-push-4 { - left: 33.33333333%; + left: 33.33333333%; } .col-xs-push-3 { - left: 25%; + left: 25%; } .col-xs-push-2 { - left: 16.66666667%; + left: 16.66666667%; } .col-xs-push-1 { - left: 8.33333333%; + left: 8.33333333%; } .col-xs-push-0 { - left: auto; + left: auto; } .col-xs-offset-12 { - margin-left: 100%; + margin-left: 100%; } .col-xs-offset-11 { - margin-left: 91.66666667%; + margin-left: 91.66666667%; } .col-xs-offset-10 { - margin-left: 83.33333333%; + margin-left: 83.33333333%; } .col-xs-offset-9 { - margin-left: 75%; + margin-left: 75%; } .col-xs-offset-8 { - margin-left: 66.66666667%; + margin-left: 66.66666667%; } .col-xs-offset-7 { - margin-left: 58.33333333%; + margin-left: 58.33333333%; } .col-xs-offset-6 { - margin-left: 50%; + margin-left: 50%; } .col-xs-offset-5 { - margin-left: 41.66666667%; + margin-left: 41.66666667%; } .col-xs-offset-4 { - margin-left: 33.33333333%; + margin-left: 33.33333333%; } .col-xs-offset-3 { - margin-left: 25%; + margin-left: 25%; } .col-xs-offset-2 { - margin-left: 16.66666667%; + margin-left: 16.66666667%; } .col-xs-offset-1 { - margin-left: 8.33333333%; + margin-left: 8.33333333%; } .col-xs-offset-0 { - margin-left: 0%; + margin-left: 0%; } @media (min-width: 768px) { - .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { - float: left; - } - .col-sm-12 { - width: 100%; - } - .col-sm-11 { - width: 91.66666667%; - } - .col-sm-10 { - width: 83.33333333%; - } - .col-sm-9 { - width: 75%; - } - .col-sm-8 { - width: 66.66666667%; - } - .col-sm-7 { - width: 58.33333333%; - } - .col-sm-6 { - width: 50%; - } - .col-sm-5 { - width: 41.66666667%; - } - .col-sm-4 { - width: 33.33333333%; - } - .col-sm-3 { - width: 25%; - } - .col-sm-2 { - width: 16.66666667%; - } - .col-sm-1 { - width: 8.33333333%; - } - .col-sm-pull-12 { - right: 100%; - } - .col-sm-pull-11 { - right: 91.66666667%; - } - .col-sm-pull-10 { - right: 83.33333333%; - } - .col-sm-pull-9 { - right: 75%; - } - .col-sm-pull-8 { - right: 66.66666667%; - } - .col-sm-pull-7 { - right: 58.33333333%; - } - .col-sm-pull-6 { - right: 50%; - } - .col-sm-pull-5 { - right: 41.66666667%; - } - .col-sm-pull-4 { - right: 33.33333333%; - } - .col-sm-pull-3 { - right: 25%; - } - .col-sm-pull-2 { - right: 16.66666667%; - } - .col-sm-pull-1 { - right: 8.33333333%; - } - .col-sm-pull-0 { - right: auto; - } - .col-sm-push-12 { - left: 100%; - } - .col-sm-push-11 { - left: 91.66666667%; - } - .col-sm-push-10 { - left: 83.33333333%; - } - .col-sm-push-9 { - left: 75%; - } - .col-sm-push-8 { - left: 66.66666667%; - } - .col-sm-push-7 { - left: 58.33333333%; - } - .col-sm-push-6 { - left: 50%; - } - .col-sm-push-5 { - left: 41.66666667%; - } - .col-sm-push-4 { - left: 33.33333333%; - } - .col-sm-push-3 { - left: 25%; - } - .col-sm-push-2 { - left: 16.66666667%; - } - .col-sm-push-1 { - left: 8.33333333%; - } - .col-sm-push-0 { - left: auto; - } - .col-sm-offset-12 { - margin-left: 100%; - } - .col-sm-offset-11 { - margin-left: 91.66666667%; - } - .col-sm-offset-10 { - margin-left: 83.33333333%; - } - .col-sm-offset-9 { - margin-left: 75%; - } - .col-sm-offset-8 { - margin-left: 66.66666667%; - } - .col-sm-offset-7 { - margin-left: 58.33333333%; - } - .col-sm-offset-6 { - margin-left: 50%; - } - .col-sm-offset-5 { - margin-left: 41.66666667%; - } - .col-sm-offset-4 { - margin-left: 33.33333333%; - } - .col-sm-offset-3 { - margin-left: 25%; - } - .col-sm-offset-2 { - margin-left: 16.66666667%; - } - .col-sm-offset-1 { - margin-left: 8.33333333%; - } - .col-sm-offset-0 { - margin-left: 0%; - } + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } } @media (min-width: 992px) { - .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { - float: left; - } - .col-md-12 { - width: 100%; - } - .col-md-11 { - width: 91.66666667%; - } - .col-md-10 { - width: 83.33333333%; - } - .col-md-9 { - width: 75%; - } - .col-md-8 { - width: 66.66666667%; - } - .col-md-7 { - width: 58.33333333%; - } - .col-md-6 { - width: 50%; - } - .col-md-5 { - width: 41.66666667%; - } - .col-md-4 { - width: 33.33333333%; - } - .col-md-3 { - width: 25%; - } - .col-md-2 { - width: 16.66666667%; - } - .col-md-1 { - width: 8.33333333%; - } - .col-md-pull-12 { - right: 100%; - } - .col-md-pull-11 { - right: 91.66666667%; - } - .col-md-pull-10 { - right: 83.33333333%; - } - .col-md-pull-9 { - right: 75%; - } - .col-md-pull-8 { - right: 66.66666667%; - } - .col-md-pull-7 { - right: 58.33333333%; - } - .col-md-pull-6 { - right: 50%; - } - .col-md-pull-5 { - right: 41.66666667%; - } - .col-md-pull-4 { - right: 33.33333333%; - } - .col-md-pull-3 { - right: 25%; - } - .col-md-pull-2 { - right: 16.66666667%; - } - .col-md-pull-1 { - right: 8.33333333%; - } - .col-md-pull-0 { - right: auto; - } - .col-md-push-12 { - left: 100%; - } - .col-md-push-11 { - left: 91.66666667%; - } - .col-md-push-10 { - left: 83.33333333%; - } - .col-md-push-9 { - left: 75%; - } - .col-md-push-8 { - left: 66.66666667%; - } - .col-md-push-7 { - left: 58.33333333%; - } - .col-md-push-6 { - left: 50%; - } - .col-md-push-5 { - left: 41.66666667%; - } - .col-md-push-4 { - left: 33.33333333%; - } - .col-md-push-3 { - left: 25%; - } - .col-md-push-2 { - left: 16.66666667%; - } - .col-md-push-1 { - left: 8.33333333%; - } - .col-md-push-0 { - left: auto; - } - .col-md-offset-12 { - margin-left: 100%; - } - .col-md-offset-11 { - margin-left: 91.66666667%; - } - .col-md-offset-10 { - margin-left: 83.33333333%; - } - .col-md-offset-9 { - margin-left: 75%; - } - .col-md-offset-8 { - margin-left: 66.66666667%; - } - .col-md-offset-7 { - margin-left: 58.33333333%; - } - .col-md-offset-6 { - margin-left: 50%; - } - .col-md-offset-5 { - margin-left: 41.66666667%; - } - .col-md-offset-4 { - margin-left: 33.33333333%; - } - .col-md-offset-3 { - margin-left: 25%; - } - .col-md-offset-2 { - margin-left: 16.66666667%; - } - .col-md-offset-1 { - margin-left: 8.33333333%; - } - .col-md-offset-0 { - margin-left: 0%; - } + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } } @media (min-width: 1200px) { - .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { - float: left; - } - .col-lg-12 { - width: 100%; - } - .col-lg-11 { - width: 91.66666667%; - } - .col-lg-10 { - width: 83.33333333%; - } - .col-lg-9 { - width: 75%; - } - .col-lg-8 { - width: 66.66666667%; - } - .col-lg-7 { - width: 58.33333333%; - } - .col-lg-6 { - width: 50%; - } - .col-lg-5 { - width: 41.66666667%; - } - .col-lg-4 { - width: 33.33333333%; - } - .col-lg-3 { - width: 25%; - } - .col-lg-2 { - width: 16.66666667%; - } - .col-lg-1 { - width: 8.33333333%; - } - .col-lg-pull-12 { - right: 100%; - } - .col-lg-pull-11 { - right: 91.66666667%; - } - .col-lg-pull-10 { - right: 83.33333333%; - } - .col-lg-pull-9 { - right: 75%; - } - .col-lg-pull-8 { - right: 66.66666667%; - } - .col-lg-pull-7 { - right: 58.33333333%; - } - .col-lg-pull-6 { - right: 50%; - } - .col-lg-pull-5 { - right: 41.66666667%; - } - .col-lg-pull-4 { - right: 33.33333333%; - } - .col-lg-pull-3 { - right: 25%; - } - .col-lg-pull-2 { - right: 16.66666667%; - } - .col-lg-pull-1 { - right: 8.33333333%; - } - .col-lg-pull-0 { - right: auto; - } - .col-lg-push-12 { - left: 100%; - } - .col-lg-push-11 { - left: 91.66666667%; - } - .col-lg-push-10 { - left: 83.33333333%; - } - .col-lg-push-9 { - left: 75%; - } - .col-lg-push-8 { - left: 66.66666667%; - } - .col-lg-push-7 { - left: 58.33333333%; - } - .col-lg-push-6 { - left: 50%; - } - .col-lg-push-5 { - left: 41.66666667%; - } - .col-lg-push-4 { - left: 33.33333333%; - } - .col-lg-push-3 { - left: 25%; - } - .col-lg-push-2 { - left: 16.66666667%; - } - .col-lg-push-1 { - left: 8.33333333%; - } - .col-lg-push-0 { - left: auto; - } - .col-lg-offset-12 { - margin-left: 100%; - } - .col-lg-offset-11 { - margin-left: 91.66666667%; - } - .col-lg-offset-10 { - margin-left: 83.33333333%; - } - .col-lg-offset-9 { - margin-left: 75%; - } - .col-lg-offset-8 { - margin-left: 66.66666667%; - } - .col-lg-offset-7 { - margin-left: 58.33333333%; - } - .col-lg-offset-6 { - margin-left: 50%; - } - .col-lg-offset-5 { - margin-left: 41.66666667%; - } - .col-lg-offset-4 { - margin-left: 33.33333333%; - } - .col-lg-offset-3 { - margin-left: 25%; - } - .col-lg-offset-2 { - margin-left: 16.66666667%; - } - .col-lg-offset-1 { - margin-left: 8.33333333%; - } - .col-lg-offset-0 { - margin-left: 0%; - } + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } } table { - background-color: transparent; + background-color: transparent; } caption { - padding-top: 8px; - padding-bottom: 8px; - color: #bbbbbb; - text-align: left; + padding-top: 8px; + padding-bottom: 8px; + color: #bbbbbb; + text-align: left; } th { - text-align: left; + text-align: left; } .table { - width: 100%; - max-width: 100%; - margin-bottom: 23px; + width: 100%; + max-width: 100%; + margin-bottom: 23px; } .table > thead > tr > th, .table > tbody > tr > th, @@ -2263,14 +2263,14 @@ th { .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td { - padding: 8px; - line-height: 1.846; - vertical-align: top; - border-top: 1px solid #dddddd; + padding: 8px; + line-height: 1.846; + vertical-align: top; + border-top: 1px solid #dddddd; } .table > thead > tr > th { - vertical-align: bottom; - border-bottom: 2px solid #dddddd; + vertical-align: bottom; + border-bottom: 2px solid #dddddd; } .table > caption + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > th, @@ -2278,13 +2278,13 @@ th { .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > td { - border-top: 0; + border-top: 0; } .table > tbody + tbody { - border-top: 2px solid #dddddd; + border-top: 2px solid #dddddd; } .table .table { - background-color: #ffffff; + background-color: #ffffff; } .table-condensed > thead > tr > th, .table-condensed > tbody > tr > th, @@ -2292,10 +2292,10 @@ th { .table-condensed > thead > tr > td, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > td { - padding: 5px; + padding: 5px; } .table-bordered { - border: 1px solid #dddddd; + border: 1px solid #dddddd; } .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, @@ -2303,28 +2303,28 @@ th { .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td { - border: 1px solid #dddddd; + border: 1px solid #dddddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { - border-bottom-width: 2px; + border-bottom-width: 2px; } .table-striped > tbody > tr:nth-of-type(odd) { - background-color: #f9f9f9; + background-color: #f9f9f9; } .table-hover > tbody > tr:hover { - background-color: #f5f5f5; + background-color: #f5f5f5; } table col[class*="col-"] { - position: static; - float: none; - display: table-column; + position: static; + float: none; + display: table-column; } table td[class*="col-"], table th[class*="col-"] { - position: static; - float: none; - display: table-cell; + position: static; + float: none; + display: table-cell; } .table > thead > tr > td.active, .table > tbody > tr > td.active, @@ -2338,14 +2338,14 @@ table th[class*="col-"] { .table > thead > tr.active > th, .table > tbody > tr.active > th, .table > tfoot > tr.active > th { - background-color: #f5f5f5; + background-color: #f5f5f5; } .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th { - background-color: #e8e8e8; + background-color: #e8e8e8; } .table > thead > tr > td.success, .table > tbody > tr > td.success, @@ -2359,14 +2359,14 @@ table th[class*="col-"] { .table > thead > tr.success > th, .table > tbody > tr.success > th, .table > tfoot > tr.success > th { - background-color: #dff0d8; + background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th { - background-color: #d0e9c6; + background-color: #d0e9c6; } .table > thead > tr > td.info, .table > tbody > tr > td.info, @@ -2380,14 +2380,14 @@ table th[class*="col-"] { .table > thead > tr.info > th, .table > tbody > tr.info > th, .table > tfoot > tr.info > th { - background-color: #e1bee7; + background-color: #e1bee7; } .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th { - background-color: #d8abe0; + background-color: #d8abe0; } .table > thead > tr > td.warning, .table > tbody > tr > td.warning, @@ -2401,14 +2401,14 @@ table th[class*="col-"] { .table > thead > tr.warning > th, .table > tbody > tr.warning > th, .table > tfoot > tr.warning > th { - background-color: #ffe0b2; + background-color: #ffe0b2; } .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th { - background-color: #ffd699; + background-color: #ffd699; } .table > thead > tr > td.danger, .table > tbody > tr > td.danger, @@ -2422,245 +2422,245 @@ table th[class*="col-"] { .table > thead > tr.danger > th, .table > tbody > tr.danger > th, .table > tfoot > tr.danger > th { - background-color: #f9bdbb; + background-color: #f9bdbb; } .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th { - background-color: #f7a6a4; + background-color: #f7a6a4; } .table-responsive { - overflow-x: auto; - min-height: 0.01%; + overflow-x: auto; + min-height: 0.01%; } @media screen and (max-width: 767px) { - .table-responsive { - width: 100%; - margin-bottom: 17.25px; - overflow-y: hidden; - -ms-overflow-style: -ms-autohiding-scrollbar; - border: 1px solid #dddddd; - } - .table-responsive > .table { - margin-bottom: 0; - } - .table-responsive > .table > thead > tr > th, - .table-responsive > .table > tbody > tr > th, - .table-responsive > .table > tfoot > tr > th, - .table-responsive > .table > thead > tr > td, - .table-responsive > .table > tbody > tr > td, - .table-responsive > .table > tfoot > tr > td { - white-space: nowrap; - } - .table-responsive > .table-bordered { - border: 0; - } - .table-responsive > .table-bordered > thead > tr > th:first-child, - .table-responsive > .table-bordered > tbody > tr > th:first-child, - .table-responsive > .table-bordered > tfoot > tr > th:first-child, - .table-responsive > .table-bordered > thead > tr > td:first-child, - .table-responsive > .table-bordered > tbody > tr > td:first-child, - .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; - } - .table-responsive > .table-bordered > thead > tr > th:last-child, - .table-responsive > .table-bordered > tbody > tr > th:last-child, - .table-responsive > .table-bordered > tfoot > tr > th:last-child, - .table-responsive > .table-bordered > thead > tr > td:last-child, - .table-responsive > .table-bordered > tbody > tr > td:last-child, - .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; - } - .table-responsive > .table-bordered > tbody > tr:last-child > th, - .table-responsive > .table-bordered > tfoot > tr:last-child > th, - .table-responsive > .table-bordered > tbody > tr:last-child > td, - .table-responsive > .table-bordered > tfoot > tr:last-child > td { - border-bottom: 0; - } + .table-responsive { + width: 100%; + margin-bottom: 17.25px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #dddddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } } fieldset { - padding: 0; - margin: 0; - border: 0; - min-width: 0; + padding: 0; + margin: 0; + border: 0; + min-width: 0; } legend { - display: block; - width: 100%; - padding: 0; - margin-bottom: 23px; - font-size: 19.5px; - line-height: inherit; - color: #212121; - border: 0; - border-bottom: 1px solid #e5e5e5; + display: block; + width: 100%; + padding: 0; + margin-bottom: 23px; + font-size: 19.5px; + line-height: inherit; + color: #212121; + border: 0; + border-bottom: 1px solid #e5e5e5; } label { - display: inline-block; - max-width: 100%; - margin-bottom: 5px; - font-weight: bold; + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; } input[type="search"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { - margin: 4px 0 0; - margin-top: 1px \9; - line-height: normal; + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; } input[type="file"] { - display: block; + display: block; } input[type="range"] { - display: block; - width: 100%; + display: block; + width: 100%; } select[multiple], select[size] { - height: auto; + height: auto; } input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } output { - display: block; - padding-top: 7px; - font-size: 13px; - line-height: 1.846; - color: #666666; + display: block; + padding-top: 7px; + font-size: 13px; + line-height: 1.846; + color: #666666; } .form-control { - display: block; - width: 100%; - height: 37px; - padding: 6px 16px; - font-size: 13px; - line-height: 1.846; - color: #666666; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 3px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; - -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; - transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + display: block; + width: 100%; + height: 37px; + padding: 6px 16px; + font-size: 13px; + line-height: 1.846; + color: #666666; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; } .form-control:focus { - border-color: #66afe9; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); - box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); } .form-control::-moz-placeholder { - color: #bbbbbb; - opacity: 1; + color: #bbbbbb; + opacity: 1; } .form-control:-ms-input-placeholder { - color: #bbbbbb; + color: #bbbbbb; } .form-control::-webkit-input-placeholder { - color: #bbbbbb; + color: #bbbbbb; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { - background-color: transparent; - opacity: 1; + background-color: transparent; + opacity: 1; } .form-control[disabled], fieldset[disabled] .form-control { - cursor: not-allowed; + cursor: not-allowed; } textarea.form-control { - height: auto; + height: auto; } input[type="search"] { - -webkit-appearance: none; + -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { - input[type="date"], - input[type="time"], - input[type="datetime-local"], - input[type="month"] { - line-height: 37px; - } - input[type="date"].input-sm, - input[type="time"].input-sm, - input[type="datetime-local"].input-sm, - input[type="month"].input-sm, - .input-group-sm input[type="date"], - .input-group-sm input[type="time"], - .input-group-sm input[type="datetime-local"], - .input-group-sm input[type="month"] { - line-height: 30px; - } - input[type="date"].input-lg, - input[type="time"].input-lg, - input[type="datetime-local"].input-lg, - input[type="month"].input-lg, - .input-group-lg input[type="date"], - .input-group-lg input[type="time"], - .input-group-lg input[type="datetime-local"], - .input-group-lg input[type="month"] { - line-height: 45px; - } + input[type="date"], + input[type="time"], + input[type="datetime-local"], + input[type="month"] { + line-height: 37px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 30px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 45px; + } } .form-group { - margin-bottom: 15px; + margin-bottom: 15px; } .radio, .checkbox { - position: relative; - display: block; - margin-top: 10px; - margin-bottom: 10px; + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; } .radio label, .checkbox label { - min-height: 23px; - padding-left: 20px; - margin-bottom: 0; - font-weight: normal; - cursor: pointer; + min-height: 23px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; } .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { - position: absolute; - margin-left: -20px; - margin-top: 4px \9; + position: absolute; + margin-left: -20px; + margin-top: 4px \9; } .radio + .radio, .checkbox + .checkbox { - margin-top: -5px; + margin-top: -5px; } .radio-inline, .checkbox-inline { - position: relative; - display: inline-block; - padding-left: 20px; - margin-bottom: 0; - vertical-align: middle; - font-weight: normal; - cursor: pointer; + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; } .radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline { - margin-top: 0; - margin-left: 10px; + margin-top: 0; + margin-left: 10px; } input[type="radio"][disabled], input[type="checkbox"][disabled], @@ -2668,132 +2668,132 @@ input[type="radio"].disabled, input[type="checkbox"].disabled, fieldset[disabled] input[type="radio"], fieldset[disabled] input[type="checkbox"] { - cursor: not-allowed; + cursor: not-allowed; } .radio-inline.disabled, .checkbox-inline.disabled, fieldset[disabled] .radio-inline, fieldset[disabled] .checkbox-inline { - cursor: not-allowed; + cursor: not-allowed; } .radio.disabled label, .checkbox.disabled label, fieldset[disabled] .radio label, fieldset[disabled] .checkbox label { - cursor: not-allowed; + cursor: not-allowed; } .form-control-static { - padding-top: 7px; - padding-bottom: 7px; - margin-bottom: 0; - min-height: 36px; + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; + min-height: 36px; } .form-control-static.input-lg, .form-control-static.input-sm { - padding-left: 0; - padding-right: 0; + padding-left: 0; + padding-right: 0; } .input-sm { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } select.input-sm { - height: 30px; - line-height: 30px; + height: 30px; + line-height: 30px; } textarea.input-sm, select[multiple].input-sm { - height: auto; + height: auto; } .form-group-sm .form-control { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } select.form-group-sm .form-control { - height: 30px; - line-height: 30px; + height: 30px; + line-height: 30px; } textarea.form-group-sm .form-control, select[multiple].form-group-sm .form-control { - height: auto; + height: auto; } .form-group-sm .form-control-static { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - min-height: 35px; + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + min-height: 35px; } .input-lg { - height: 45px; - padding: 10px 16px; - font-size: 17px; - line-height: 1.3333333; - border-radius: 3px; + height: 45px; + padding: 10px 16px; + font-size: 17px; + line-height: 1.3333333; + border-radius: 3px; } select.input-lg { - height: 45px; - line-height: 45px; + height: 45px; + line-height: 45px; } textarea.input-lg, select[multiple].input-lg { - height: auto; + height: auto; } .form-group-lg .form-control { - height: 45px; - padding: 10px 16px; - font-size: 17px; - line-height: 1.3333333; - border-radius: 3px; + height: 45px; + padding: 10px 16px; + font-size: 17px; + line-height: 1.3333333; + border-radius: 3px; } select.form-group-lg .form-control { - height: 45px; - line-height: 45px; + height: 45px; + line-height: 45px; } textarea.form-group-lg .form-control, select[multiple].form-group-lg .form-control { - height: auto; + height: auto; } .form-group-lg .form-control-static { - height: 45px; - padding: 10px 16px; - font-size: 17px; - line-height: 1.3333333; - min-height: 40px; + height: 45px; + padding: 10px 16px; + font-size: 17px; + line-height: 1.3333333; + min-height: 40px; } .has-feedback { - position: relative; + position: relative; } .has-feedback .form-control { - padding-right: 46.25px; + padding-right: 46.25px; } .form-control-feedback { - position: absolute; - top: 0; - right: 0; - z-index: 2; - display: block; - width: 37px; - height: 37px; - line-height: 37px; - text-align: center; - pointer-events: none; + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 37px; + height: 37px; + line-height: 37px; + text-align: center; + pointer-events: none; } .input-lg + .form-control-feedback { - width: 45px; - height: 45px; - line-height: 45px; + width: 45px; + height: 45px; + line-height: 45px; } .input-sm + .form-control-feedback { - width: 30px; - height: 30px; - line-height: 30px; + width: 30px; + height: 30px; + line-height: 30px; } .has-success .help-block, .has-success .control-label, @@ -2805,25 +2805,25 @@ select[multiple].form-group-lg .form-control { .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label { - color: #4caf50; + color: #4caf50; } .has-success .form-control { - border-color: #4caf50; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + border-color: #4caf50; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-success .form-control:focus { - border-color: #3d8b40; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; + border-color: #3d8b40; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; } .has-success .input-group-addon { - color: #4caf50; - border-color: #4caf50; - background-color: #dff0d8; + color: #4caf50; + border-color: #4caf50; + background-color: #dff0d8; } .has-success .form-control-feedback { - color: #4caf50; + color: #4caf50; } .has-warning .help-block, .has-warning .control-label, @@ -2835,25 +2835,25 @@ select[multiple].form-group-lg .form-control { .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label { - color: #ff9800; + color: #ff9800; } .has-warning .form-control { - border-color: #ff9800; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + border-color: #ff9800; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-warning .form-control:focus { - border-color: #cc7a00; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; + border-color: #cc7a00; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; } .has-warning .input-group-addon { - color: #ff9800; - border-color: #ff9800; - background-color: #ffe0b2; + color: #ff9800; + border-color: #ff9800; + background-color: #ffe0b2; } .has-warning .form-control-feedback { - color: #ff9800; + color: #ff9800; } .has-error .help-block, .has-error .control-label, @@ -2865,144 +2865,144 @@ select[multiple].form-group-lg .form-control { .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label { - color: #e51c23; + color: #e51c23; } .has-error .form-control { - border-color: #e51c23; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + border-color: #e51c23; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-error .form-control:focus { - border-color: #b9151b; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; + border-color: #b9151b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; } .has-error .input-group-addon { - color: #e51c23; - border-color: #e51c23; - background-color: #f9bdbb; + color: #e51c23; + border-color: #e51c23; + background-color: #f9bdbb; } .has-error .form-control-feedback { - color: #e51c23; + color: #e51c23; } .has-feedback label ~ .form-control-feedback { - top: 28px; + top: 28px; } .has-feedback label.sr-only ~ .form-control-feedback { - top: 0; + top: 0; } .help-block { - display: block; - margin-top: 5px; - margin-bottom: 10px; - color: #a6a6a6; + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #a6a6a6; } @media (min-width: 768px) { - .form-inline .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .form-inline .form-control-static { - display: inline-block; - } - .form-inline .input-group { - display: inline-table; - vertical-align: middle; - } - .form-inline .input-group .input-group-addon, - .form-inline .input-group .input-group-btn, - .form-inline .input-group .form-control { - width: auto; - } - .form-inline .input-group > .form-control { - width: 100%; - } - .form-inline .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio, - .form-inline .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .form-inline .radio label, - .form-inline .checkbox label { - padding-left: 0; - } - .form-inline .radio input[type="radio"], - .form-inline .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .form-inline .has-feedback .form-control-feedback { - top: 0; - } + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } } .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { - margin-top: 0; - margin-bottom: 0; - padding-top: 7px; + margin-top: 0; + margin-bottom: 0; + padding-top: 7px; } .form-horizontal .radio, .form-horizontal .checkbox { - min-height: 30px; + min-height: 30px; } .form-horizontal .form-group { - margin-left: -15px; - margin-right: -15px; + margin-left: -15px; + margin-right: -15px; } @media (min-width: 768px) { - .form-horizontal .control-label { - text-align: right; - margin-bottom: 0; - padding-top: 7px; - } + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 7px; + } } .form-horizontal .has-feedback .form-control-feedback { - right: 15px; + right: 15px; } @media (min-width: 768px) { - .form-horizontal .form-group-lg .control-label { - padding-top: 14.333333px; - } + .form-horizontal .form-group-lg .control-label { + padding-top: 14.333333px; + } } @media (min-width: 768px) { - .form-horizontal .form-group-sm .control-label { - padding-top: 6px; - } + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } } .btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - padding: 6px 16px; - font-size: 13px; - line-height: 1.846; - border-radius: 3px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 6px 16px; + font-size: 13px; + line-height: 1.846; + border-radius: 3px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } .btn:focus, .btn:active:focus, @@ -3010,37 +3010,37 @@ select[multiple].form-group-lg .form-control { .btn.focus, .btn:active.focus, .btn.active.focus { - outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; } .btn:hover, .btn:focus, .btn.focus { - color: #666666; - text-decoration: none; + color: #666666; + text-decoration: none; } .btn:active, .btn.active { - outline: 0; - background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { - cursor: not-allowed; - pointer-events: none; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; + cursor: not-allowed; + pointer-events: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; } .btn-default { - color: #666666; - background-color: #ffffff; - border-color: #eeeeee; + color: #666666; + background-color: #ffffff; + border-color: #eeeeee; } .btn-default:hover, .btn-default:focus, @@ -3048,14 +3048,14 @@ fieldset[disabled] .btn { .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { - color: #666666; - background-color: #e6e6e6; - border-color: #cfcfcf; + color: #666666; + background-color: #e6e6e6; + border-color: #cfcfcf; } .btn-default:active, .btn-default.active, .open > .dropdown-toggle.btn-default { - background-image: none; + background-image: none; } .btn-default.disabled, .btn-default[disabled], @@ -3075,17 +3075,17 @@ fieldset[disabled] .btn-default:active, .btn-default.disabled.active, .btn-default[disabled].active, fieldset[disabled] .btn-default.active { - background-color: #ffffff; - border-color: #eeeeee; + background-color: #ffffff; + border-color: #eeeeee; } .btn-default .badge { - color: #ffffff; - background-color: #666666; + color: #ffffff; + background-color: #666666; } .btn-primary { - color: #ffffff; - background-color: #2196f3; - border-color: transparent; + color: #ffffff; + background-color: #2196f3; + border-color: transparent; } .btn-primary:hover, .btn-primary:focus, @@ -3093,14 +3093,14 @@ fieldset[disabled] .btn-default.active { .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #0c7cd5; - border-color: rgba(0, 0, 0, 0); + color: #ffffff; + background-color: #0c7cd5; + border-color: rgba(0, 0, 0, 0); } .btn-primary:active, .btn-primary.active, .open > .dropdown-toggle.btn-primary { - background-image: none; + background-image: none; } .btn-primary.disabled, .btn-primary[disabled], @@ -3120,17 +3120,17 @@ fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { - background-color: #2196f3; - border-color: transparent; + background-color: #2196f3; + border-color: transparent; } .btn-primary .badge { - color: #2196f3; - background-color: #ffffff; + color: #2196f3; + background-color: #ffffff; } .btn-success { - color: #ffffff; - background-color: #4caf50; - border-color: transparent; + color: #ffffff; + background-color: #4caf50; + border-color: transparent; } .btn-success:hover, .btn-success:focus, @@ -3138,14 +3138,14 @@ fieldset[disabled] .btn-primary.active { .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #3d8b40; - border-color: rgba(0, 0, 0, 0); + color: #ffffff; + background-color: #3d8b40; + border-color: rgba(0, 0, 0, 0); } .btn-success:active, .btn-success.active, .open > .dropdown-toggle.btn-success { - background-image: none; + background-image: none; } .btn-success.disabled, .btn-success[disabled], @@ -3165,17 +3165,17 @@ fieldset[disabled] .btn-success:active, .btn-success.disabled.active, .btn-success[disabled].active, fieldset[disabled] .btn-success.active { - background-color: #4caf50; - border-color: transparent; + background-color: #4caf50; + border-color: transparent; } .btn-success .badge { - color: #4caf50; - background-color: #ffffff; + color: #4caf50; + background-color: #ffffff; } .btn-info { - color: #ffffff; - background-color: #9c27b0; - border-color: transparent; + color: #ffffff; + background-color: #9c27b0; + border-color: transparent; } .btn-info:hover, .btn-info:focus, @@ -3183,14 +3183,14 @@ fieldset[disabled] .btn-success.active { .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #771e86; - border-color: rgba(0, 0, 0, 0); + color: #ffffff; + background-color: #771e86; + border-color: rgba(0, 0, 0, 0); } .btn-info:active, .btn-info.active, .open > .dropdown-toggle.btn-info { - background-image: none; + background-image: none; } .btn-info.disabled, .btn-info[disabled], @@ -3210,17 +3210,17 @@ fieldset[disabled] .btn-info:active, .btn-info.disabled.active, .btn-info[disabled].active, fieldset[disabled] .btn-info.active { - background-color: #9c27b0; - border-color: transparent; + background-color: #9c27b0; + border-color: transparent; } .btn-info .badge { - color: #9c27b0; - background-color: #ffffff; + color: #9c27b0; + background-color: #ffffff; } .btn-warning { - color: #ffffff; - background-color: #ff9800; - border-color: transparent; + color: #ffffff; + background-color: #ff9800; + border-color: transparent; } .btn-warning:hover, .btn-warning:focus, @@ -3228,14 +3228,14 @@ fieldset[disabled] .btn-info.active { .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #cc7a00; - border-color: rgba(0, 0, 0, 0); + color: #ffffff; + background-color: #cc7a00; + border-color: rgba(0, 0, 0, 0); } .btn-warning:active, .btn-warning.active, .open > .dropdown-toggle.btn-warning { - background-image: none; + background-image: none; } .btn-warning.disabled, .btn-warning[disabled], @@ -3255,17 +3255,17 @@ fieldset[disabled] .btn-warning:active, .btn-warning.disabled.active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning.active { - background-color: #ff9800; - border-color: transparent; + background-color: #ff9800; + border-color: transparent; } .btn-warning .badge { - color: #ff9800; - background-color: #ffffff; + color: #ff9800; + background-color: #ffffff; } .btn-danger { - color: #ffffff; - background-color: #e51c23; - border-color: transparent; + color: #ffffff; + background-color: #e51c23; + border-color: transparent; } .btn-danger:hover, .btn-danger:focus, @@ -3273,14 +3273,14 @@ fieldset[disabled] .btn-warning.active { .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #b9151b; - border-color: rgba(0, 0, 0, 0); + color: #ffffff; + background-color: #b9151b; + border-color: rgba(0, 0, 0, 0); } .btn-danger:active, .btn-danger.active, .open > .dropdown-toggle.btn-danger { - background-image: none; + background-image: none; } .btn-danger.disabled, .btn-danger[disabled], @@ -3300,265 +3300,265 @@ fieldset[disabled] .btn-danger:active, .btn-danger.disabled.active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger.active { - background-color: #e51c23; - border-color: transparent; + background-color: #e51c23; + border-color: transparent; } .btn-danger .badge { - color: #e51c23; - background-color: #ffffff; + color: #e51c23; + background-color: #ffffff; } .btn-link { - color: #2196f3; - font-weight: normal; - border-radius: 0; + color: #2196f3; + font-weight: normal; + border-radius: 0; } .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; } .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { - border-color: transparent; + border-color: transparent; } .btn-link:hover, .btn-link:focus { - color: #0a6ebd; - text-decoration: underline; - background-color: transparent; + color: #0a6ebd; + text-decoration: underline; + background-color: transparent; } .btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:focus { - color: #bbbbbb; - text-decoration: none; + color: #bbbbbb; + text-decoration: none; } .btn-lg, .btn-group-lg > .btn { - padding: 10px 16px; - font-size: 17px; - line-height: 1.3333333; - border-radius: 3px; + padding: 10px 16px; + font-size: 17px; + line-height: 1.3333333; + border-radius: 3px; } .btn-sm, .btn-group-sm > .btn { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } .btn-xs, .btn-group-xs > .btn { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } .btn-block { - display: block; - width: 100%; + display: block; + width: 100%; } .btn-block + .btn-block { - margin-top: 5px; + margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { - width: 100%; + width: 100%; } .fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; } .fade.in { - opacity: 1; + opacity: 1; } .collapse { - display: none; + display: none; } .collapse.in { - display: block; + display: block; } tr.collapse.in { - display: table-row; + display: table-row; } tbody.collapse.in { - display: table-row-group; + display: table-row-group; } .collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - -o-transition-duration: 0.35s; - transition-duration: 0.35s; - -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; + -webkit-transition-duration: 0.35s; + -o-transition-duration: 0.35s; + transition-duration: 0.35s; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; } .caret { - display: inline-block; - width: 0; - height: 0; - margin-left: 2px; - vertical-align: middle; - border-top: 4px dashed; - border-right: 4px solid transparent; - border-left: 4px solid transparent; + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } .dropup, .dropdown { - position: relative; + position: relative; } .dropdown-toggle:focus { - outline: 0; + outline: 0; } .dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - list-style: none; - font-size: 13px; - text-align: left; - background-color: #ffffff; - border: 1px solid #cccccc; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 3px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - -webkit-background-clip: padding-box; - background-clip: padding-box; + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 13px; + text-align: left; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 3px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + -webkit-background-clip: padding-box; + background-clip: padding-box; } .dropdown-menu.pull-right { - right: 0; - left: auto; + right: 0; + left: auto; } .dropdown-menu .divider { - height: 1px; - margin: 10.5px 0; - overflow: hidden; - background-color: #e5e5e5; + height: 1px; + margin: 10.5px 0; + overflow: hidden; + background-color: #e5e5e5; } .dropdown-menu > li > a { - display: block; - padding: 3px 20px; - clear: both; - font-weight: normal; - line-height: 1.846; - color: #666666; - white-space: nowrap; + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.846; + color: #666666; + white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { - text-decoration: none; - color: #141414; - background-color: #eeeeee; + text-decoration: none; + color: #141414; + background-color: #eeeeee; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { - color: #ffffff; - text-decoration: none; - outline: 0; - background-color: #2196f3; + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #2196f3; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { - color: #bbbbbb; + color: #bbbbbb; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { - text-decoration: none; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); - cursor: not-allowed; + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; } .open > .dropdown-menu { - display: block; + display: block; } .open > a { - outline: 0; + outline: 0; } .dropdown-menu-right { - left: auto; - right: 0; + left: auto; + right: 0; } .dropdown-menu-left { - left: 0; - right: auto; + left: 0; + right: auto; } .dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.846; - color: #bbbbbb; - white-space: nowrap; + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.846; + color: #bbbbbb; + white-space: nowrap; } .dropdown-backdrop { - position: fixed; - left: 0; - right: 0; - bottom: 0; - top: 0; - z-index: 990; + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; } .pull-right > .dropdown-menu { - right: 0; - left: auto; + right: 0; + left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { - border-top: 0; - border-bottom: 4px solid; - content: ""; + border-top: 0; + border-bottom: 4px solid; + content: ""; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px; + top: auto; + bottom: 100%; + margin-bottom: 2px; } @media (min-width: 768px) { - .navbar-right .dropdown-menu { - left: auto; - right: 0; - } - .navbar-right .dropdown-menu-left { - left: 0; - right: auto; - } + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } } .btn-group, .btn-group-vertical { - position: relative; - display: inline-block; - vertical-align: middle; + position: relative; + display: inline-block; + vertical-align: middle; } .btn-group > .btn, .btn-group-vertical > .btn { - position: relative; - float: left; + position: relative; + float: left; } .btn-group > .btn:hover, .btn-group-vertical > .btn:hover, @@ -3568,186 +3568,186 @@ tbody.collapse.in { .btn-group-vertical > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn.active { - z-index: 2; + z-index: 2; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { - margin-left: -1px; + margin-left: -1px; } .btn-toolbar { - margin-left: -5px; + margin-left: -5px; } .btn-toolbar .btn-group, .btn-toolbar .input-group { - float: left; + float: left; } .btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group { - margin-left: 5px; + margin-left: 5px; } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { - border-radius: 0; + border-radius: 0; } .btn-group > .btn:first-child { - margin-left: 0; + margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { - border-bottom-right-radius: 0; - border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-top-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; } .btn-group > .btn-group { - float: left; + float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; + border-radius: 0; } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-top-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { - outline: 0; + outline: 0; } .btn-group > .btn + .dropdown-toggle { - padding-left: 8px; - padding-right: 8px; + padding-left: 8px; + padding-right: 8px; } .btn-group > .btn-lg + .dropdown-toggle { - padding-left: 12px; - padding-right: 12px; + padding-left: 12px; + padding-right: 12px; } .btn-group.open .dropdown-toggle { - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } .btn-group.open .dropdown-toggle.btn-link { - -webkit-box-shadow: none; - box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } .btn .caret { - margin-left: 0; + margin-left: 0; } .btn-lg .caret { - border-width: 5px 5px 0; - border-bottom-width: 0; + border-width: 5px 5px 0; + border-bottom-width: 0; } .dropup .btn-lg .caret { - border-width: 0 5px 5px; + border-width: 0 5px 5px; } .btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn { - display: block; - float: none; - width: 100%; - max-width: 100%; + display: block; + float: none; + width: 100%; + max-width: 100%; } .btn-group-vertical > .btn-group > .btn { - float: none; + float: none; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { - margin-top: -1px; - margin-left: 0; + margin-top: -1px; + margin-left: 0; } .btn-group-vertical > .btn:not(:first-child):not(:last-child) { - border-radius: 0; + border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { - border-top-right-radius: 3px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; + border-top-right-radius: 3px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { - border-bottom-left-radius: 3px; - border-top-right-radius: 0; - border-top-left-radius: 0; + border-bottom-left-radius: 3px; + border-top-right-radius: 0; + border-top-left-radius: 0; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { - border-radius: 0; + border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { - border-top-right-radius: 0; - border-top-left-radius: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; } .btn-group-justified { - display: table; - width: 100%; - table-layout: fixed; - border-collapse: separate; + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; } .btn-group-justified > .btn, .btn-group-justified > .btn-group { - float: none; - display: table-cell; - width: 1%; + float: none; + display: table-cell; + width: 1%; } .btn-group-justified > .btn-group .btn { - width: 100%; + width: 100%; } .btn-group-justified > .btn-group .dropdown-menu { - left: auto; + left: auto; } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; } .input-group { - position: relative; - display: table; - border-collapse: separate; + position: relative; + display: table; + border-collapse: separate; } .input-group[class*="col-"] { - float: none; - padding-left: 0; - padding-right: 0; + float: none; + padding-left: 0; + padding-right: 0; } .input-group .form-control { - position: relative; - z-index: 2; - float: left; - width: 100%; - margin-bottom: 0; + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; } .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { - height: 45px; - padding: 10px 16px; - font-size: 17px; - line-height: 1.3333333; - border-radius: 3px; + height: 45px; + padding: 10px 16px; + font-size: 17px; + line-height: 1.3333333; + border-radius: 3px; } select.input-group-lg > .form-control, select.input-group-lg > .input-group-addon, select.input-group-lg > .input-group-btn > .btn { - height: 45px; - line-height: 45px; + height: 45px; + line-height: 45px; } textarea.input-group-lg > .form-control, textarea.input-group-lg > .input-group-addon, @@ -3755,22 +3755,22 @@ textarea.input-group-lg > .input-group-btn > .btn, select[multiple].input-group-lg > .form-control, select[multiple].input-group-lg > .input-group-addon, select[multiple].input-group-lg > .input-group-btn > .btn { - height: auto; + height: auto; } .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn { - height: 30px; - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; } select.input-group-sm > .form-control, select.input-group-sm > .input-group-addon, select.input-group-sm > .input-group-btn > .btn { - height: 30px; - line-height: 30px; + height: 30px; + line-height: 30px; } textarea.input-group-sm > .form-control, textarea.input-group-sm > .input-group-addon, @@ -3778,48 +3778,48 @@ textarea.input-group-sm > .input-group-btn > .btn, select[multiple].input-group-sm > .form-control, select[multiple].input-group-sm > .input-group-addon, select[multiple].input-group-sm > .input-group-btn > .btn { - height: auto; + height: auto; } .input-group-addon, .input-group-btn, .input-group .form-control { - display: table-cell; + display: table-cell; } .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { - border-radius: 0; + border-radius: 0; } .input-group-addon, .input-group-btn { - width: 1%; - white-space: nowrap; - vertical-align: middle; + width: 1%; + white-space: nowrap; + vertical-align: middle; } .input-group-addon { - padding: 6px 16px; - font-size: 13px; - font-weight: normal; - line-height: 1; - color: #666666; - text-align: center; - background-color: transparent; - border: 1px solid transparent; - border-radius: 3px; + padding: 6px 16px; + font-size: 13px; + font-weight: normal; + line-height: 1; + color: #666666; + text-align: center; + background-color: transparent; + border: 1px solid transparent; + border-radius: 3px; } .input-group-addon.input-sm { - padding: 5px 10px; - font-size: 12px; - border-radius: 3px; + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; } .input-group-addon.input-lg { - padding: 10px 16px; - font-size: 17px; - border-radius: 3px; + padding: 10px 16px; + font-size: 17px; + border-radius: 3px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { - margin-top: 0; + margin-top: 0; } .input-group .form-control:first-child, .input-group-addon:first-child, @@ -3828,11 +3828,11 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-top-right-radius: 0; + border-bottom-right-radius: 0; + border-top-right-radius: 0; } .input-group-addon:first-child { - border-right: 0; + border-right: 0; } .input-group .form-control:last-child, .input-group-addon:last-child, @@ -3841,812 +3841,812 @@ select[multiple].input-group-sm > .input-group-btn > .btn { .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { - border-bottom-left-radius: 0; - border-top-left-radius: 0; + border-bottom-left-radius: 0; + border-top-left-radius: 0; } .input-group-addon:last-child { - border-left: 0; + border-left: 0; } .input-group-btn { - position: relative; - font-size: 0; - white-space: nowrap; + position: relative; + font-size: 0; + white-space: nowrap; } .input-group-btn > .btn { - position: relative; + position: relative; } .input-group-btn > .btn + .btn { - margin-left: -1px; + margin-left: -1px; } .input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active { - z-index: 2; + z-index: 2; } .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group { - margin-right: -1px; + margin-right: -1px; } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { - margin-left: -1px; + margin-left: -1px; } .nav { - margin-bottom: 0; - padding-left: 0; - list-style: none; + margin-bottom: 0; + padding-left: 0; + list-style: none; } .nav > li { - position: relative; - display: block; + position: relative; + display: block; } .nav > li > a { - position: relative; - display: block; - padding: 10px 15px; + position: relative; + display: block; + padding: 10px 15px; } .nav > li > a:hover, .nav > li > a:focus { - text-decoration: none; - background-color: #eeeeee; + text-decoration: none; + background-color: #eeeeee; } .nav > li.disabled > a { - color: #bbbbbb; + color: #bbbbbb; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { - color: #bbbbbb; - text-decoration: none; - background-color: transparent; - cursor: not-allowed; + color: #bbbbbb; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { - background-color: #eeeeee; - border-color: #2196f3; + background-color: #eeeeee; + border-color: #2196f3; } .nav .nav-divider { - height: 1px; - margin: 10.5px 0; - overflow: hidden; - background-color: #e5e5e5; + height: 1px; + margin: 10.5px 0; + overflow: hidden; + background-color: #e5e5e5; } .nav > li > a > img { - max-width: none; + max-width: none; } .nav-tabs { - border-bottom: 1px solid transparent; + border-bottom: 1px solid transparent; } .nav-tabs > li { - float: left; - margin-bottom: -1px; + float: left; + margin-bottom: -1px; } .nav-tabs > li > a { - margin-right: 2px; - line-height: 1.846; - border: 1px solid transparent; - border-radius: 3px 3px 0 0; + margin-right: 2px; + line-height: 1.846; + border: 1px solid transparent; + border-radius: 3px 3px 0 0; } .nav-tabs > li > a:hover { - border-color: #eeeeee #eeeeee transparent; + border-color: #eeeeee #eeeeee transparent; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { - color: #666666; - background-color: transparent; - border: 1px solid transparent; - border-bottom-color: transparent; - cursor: default; + color: #666666; + background-color: transparent; + border: 1px solid transparent; + border-bottom-color: transparent; + cursor: default; } .nav-tabs.nav-justified { - width: 100%; - border-bottom: 0; + width: 100%; + border-bottom: 0; } .nav-tabs.nav-justified > li { - float: none; + float: none; } .nav-tabs.nav-justified > li > a { - text-align: center; - margin-bottom: 5px; + text-align: center; + margin-bottom: 5px; } .nav-tabs.nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; + top: auto; + left: auto; } @media (min-width: 768px) { - .nav-tabs.nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-tabs.nav-justified > li > a { - margin-bottom: 0; - } + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } } .nav-tabs.nav-justified > li > a { - margin-right: 0; - border-radius: 3px; + margin-right: 0; + border-radius: 3px; } .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { - border: 1px solid transparent; + border: 1px solid transparent; } @media (min-width: 768px) { - .nav-tabs.nav-justified > li > a { - border-bottom: 1px solid transparent; - border-radius: 3px 3px 0 0; - } - .nav-tabs.nav-justified > .active > a, - .nav-tabs.nav-justified > .active > a:hover, - .nav-tabs.nav-justified > .active > a:focus { - border-bottom-color: #ffffff; - } + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid transparent; + border-radius: 3px 3px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #ffffff; + } } .nav-pills > li { - float: left; + float: left; } .nav-pills > li > a { - border-radius: 3px; + border-radius: 3px; } .nav-pills > li + li { - margin-left: 2px; + margin-left: 2px; } .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { - color: #ffffff; - background-color: #2196f3; + color: #ffffff; + background-color: #2196f3; } .nav-stacked > li { - float: none; + float: none; } .nav-stacked > li + li { - margin-top: 2px; - margin-left: 0; + margin-top: 2px; + margin-left: 0; } .nav-justified { - width: 100%; + width: 100%; } .nav-justified > li { - float: none; + float: none; } .nav-justified > li > a { - text-align: center; - margin-bottom: 5px; + text-align: center; + margin-bottom: 5px; } .nav-justified > .dropdown .dropdown-menu { - top: auto; - left: auto; + top: auto; + left: auto; } @media (min-width: 768px) { - .nav-justified > li { - display: table-cell; - width: 1%; - } - .nav-justified > li > a { - margin-bottom: 0; - } + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } } .nav-tabs-justified { - border-bottom: 0; + border-bottom: 0; } .nav-tabs-justified > li > a { - margin-right: 0; - border-radius: 3px; + margin-right: 0; + border-radius: 3px; } .nav-tabs-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus { - border: 1px solid transparent; + border: 1px solid transparent; } @media (min-width: 768px) { - .nav-tabs-justified > li > a { - border-bottom: 1px solid transparent; - border-radius: 3px 3px 0 0; - } - .nav-tabs-justified > .active > a, - .nav-tabs-justified > .active > a:hover, - .nav-tabs-justified > .active > a:focus { - border-bottom-color: #ffffff; - } + .nav-tabs-justified > li > a { + border-bottom: 1px solid transparent; + border-radius: 3px 3px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #ffffff; + } } .tab-content > .tab-pane { - display: none; + display: none; } .tab-content > .active { - display: block; + display: block; } .nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-right-radius: 0; - border-top-left-radius: 0; + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; } .navbar { - position: relative; - min-height: 64px; - margin-bottom: 23px; - border: 1px solid transparent; + position: relative; + min-height: 64px; + margin-bottom: 23px; + border: 1px solid transparent; } @media (min-width: 768px) { - .navbar { - border-radius: 3px; - } + .navbar { + border-radius: 3px; + } } @media (min-width: 768px) { - .navbar-header { - float: left; - } + .navbar-header { + float: left; + } } .navbar-collapse { - overflow-x: visible; - padding-right: 15px; - padding-left: 15px; - border-top: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); - -webkit-overflow-scrolling: touch; + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; } .navbar-collapse.in { - overflow-y: auto; + overflow-y: auto; } @media (min-width: 768px) { - .navbar-collapse { - width: auto; - border-top: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - .navbar-collapse.collapse { - display: block !important; - height: auto !important; - padding-bottom: 0; - overflow: visible !important; - } - .navbar-collapse.in { - overflow-y: visible; - } - .navbar-fixed-top .navbar-collapse, - .navbar-static-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - padding-left: 0; - padding-right: 0; - } + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { - max-height: 340px; + max-height: 340px; } @media (max-device-width: 480px) and (orientation: landscape) { - .navbar-fixed-top .navbar-collapse, - .navbar-fixed-bottom .navbar-collapse { - max-height: 200px; - } + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } } .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { - margin-right: -15px; - margin-left: -15px; + margin-right: -15px; + margin-left: -15px; } @media (min-width: 768px) { - .container > .navbar-header, - .container-fluid > .navbar-header, - .container > .navbar-collapse, - .container-fluid > .navbar-collapse { - margin-right: 0; - margin-left: 0; - } + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } } .navbar-static-top { - z-index: 1000; - border-width: 0 0 1px; + z-index: 1000; + border-width: 0 0 1px; } @media (min-width: 768px) { - .navbar-static-top { - border-radius: 0; - } + .navbar-static-top { + border-radius: 0; + } } .navbar-fixed-top, .navbar-fixed-bottom { - position: fixed; - right: 0; - left: 0; - z-index: 1030; + position: fixed; + right: 0; + left: 0; + z-index: 1030; } @media (min-width: 768px) { - .navbar-fixed-top, - .navbar-fixed-bottom { - border-radius: 0; - } + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } } .navbar-fixed-top { - top: 0; - border-width: 0 0 1px; + top: 0; + border-width: 0 0 1px; } .navbar-fixed-bottom { - bottom: 0; - margin-bottom: 0; - border-width: 1px 0 0; + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; } .navbar-brand { - float: left; - padding: 20.5px 15px; - font-size: 17px; - line-height: 23px; - height: 64px; + float: left; + padding: 20.5px 15px; + font-size: 17px; + line-height: 23px; + height: 64px; } .navbar-brand:hover, .navbar-brand:focus { - text-decoration: none; + text-decoration: none; } .navbar-brand > img { - display: block; + display: block; } @media (min-width: 768px) { - .navbar > .container .navbar-brand, - .navbar > .container-fluid .navbar-brand { - margin-left: -15px; - } + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } } .navbar-toggle { - position: relative; - float: right; - margin-right: 15px; - padding: 9px 10px; - margin-top: 15px; - margin-bottom: 15px; - background-color: transparent; - background-image: none; - border: 1px solid transparent; - border-radius: 3px; + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 15px; + margin-bottom: 15px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 3px; } .navbar-toggle:focus { - outline: 0; + outline: 0; } .navbar-toggle .icon-bar { - display: block; - width: 22px; - height: 2px; - border-radius: 1px; + display: block; + width: 22px; + height: 2px; + border-radius: 1px; } .navbar-toggle .icon-bar + .icon-bar { - margin-top: 4px; + margin-top: 4px; } @media (min-width: 768px) { - .navbar-toggle { - display: none; - } + .navbar-toggle { + display: none; + } } .navbar-nav { - margin: 10.25px -15px; + margin: 10.25px -15px; } .navbar-nav > li > a { - padding-top: 10px; - padding-bottom: 10px; - line-height: 23px; + padding-top: 10px; + padding-bottom: 10px; + line-height: 23px; } @media (max-width: 767px) { - .navbar-nav .open .dropdown-menu { - position: static; - float: none; - width: auto; - margin-top: 0; - background-color: transparent; - border: 0; - -webkit-box-shadow: none; - box-shadow: none; - } - .navbar-nav .open .dropdown-menu > li > a, - .navbar-nav .open .dropdown-menu .dropdown-header { - padding: 5px 15px 5px 25px; - } - .navbar-nav .open .dropdown-menu > li > a { - line-height: 23px; - } - .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-nav .open .dropdown-menu > li > a:focus { - background-image: none; - } + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 23px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } } @media (min-width: 768px) { - .navbar-nav { - float: left; - margin: 0; - } - .navbar-nav > li { - float: left; - } - .navbar-nav > li > a { - padding-top: 20.5px; - padding-bottom: 20.5px; - } + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 20.5px; + padding-bottom: 20.5px; + } } .navbar-form { - margin-left: -15px; - margin-right: -15px; - padding: 10px 15px; - border-top: 1px solid transparent; - border-bottom: 1px solid transparent; - -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); - margin-top: 13.5px; - margin-bottom: 13.5px; + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 13.5px; + margin-bottom: 13.5px; } @media (min-width: 768px) { - .navbar-form .form-group { - display: inline-block; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .navbar-form .form-control-static { - display: inline-block; - } - .navbar-form .input-group { - display: inline-table; - vertical-align: middle; - } - .navbar-form .input-group .input-group-addon, - .navbar-form .input-group .input-group-btn, - .navbar-form .input-group .form-control { - width: auto; - } - .navbar-form .input-group > .form-control { - width: 100%; - } - .navbar-form .control-label { - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio, - .navbar-form .checkbox { - display: inline-block; - margin-top: 0; - margin-bottom: 0; - vertical-align: middle; - } - .navbar-form .radio label, - .navbar-form .checkbox label { - padding-left: 0; - } - .navbar-form .radio input[type="radio"], - .navbar-form .checkbox input[type="checkbox"] { - position: relative; - margin-left: 0; - } - .navbar-form .has-feedback .form-control-feedback { - top: 0; - } + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } } @media (max-width: 767px) { - .navbar-form .form-group { - margin-bottom: 5px; - } - .navbar-form .form-group:last-child { - margin-bottom: 0; - } + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } } @media (min-width: 768px) { - .navbar-form { - width: auto; - border: 0; - margin-left: 0; - margin-right: 0; - padding-top: 0; - padding-bottom: 0; - -webkit-box-shadow: none; - box-shadow: none; - } + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } } .navbar-nav > li > .dropdown-menu { - margin-top: 0; - border-top-right-radius: 0; - border-top-left-radius: 0; + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { - margin-bottom: 0; - border-top-right-radius: 3px; - border-top-left-radius: 3px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; + margin-bottom: 0; + border-top-right-radius: 3px; + border-top-left-radius: 3px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; } .navbar-btn { - margin-top: 13.5px; - margin-bottom: 13.5px; + margin-top: 13.5px; + margin-bottom: 13.5px; } .navbar-btn.btn-sm { - margin-top: 17px; - margin-bottom: 17px; + margin-top: 17px; + margin-bottom: 17px; } .navbar-btn.btn-xs { - margin-top: 21px; - margin-bottom: 21px; + margin-top: 21px; + margin-bottom: 21px; } .navbar-text { - margin-top: 20.5px; - margin-bottom: 20.5px; + margin-top: 20.5px; + margin-bottom: 20.5px; } @media (min-width: 768px) { - .navbar-text { - float: left; - margin-left: 15px; - margin-right: 15px; - } + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; + } } @media (min-width: 768px) { - .navbar-left { - float: left !important; - } - .navbar-right { - float: right !important; - margin-right: -15px; - } - .navbar-right ~ .navbar-right { - margin-right: 0; - } + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } } .navbar-default { - background-color: #ffffff; - border-color: transparent; + background-color: #ffffff; + border-color: transparent; } .navbar-default .navbar-brand { - color: #666666; + color: #666666; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { - color: #212121; - background-color: transparent; + color: #212121; + background-color: transparent; } .navbar-default .navbar-text { - color: #bbbbbb; + color: #bbbbbb; } .navbar-default .navbar-nav > li > a { - color: #666666; + color: #666666; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { - color: #212121; - background-color: transparent; + color: #212121; + background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { - color: #212121; - background-color: #eeeeee; + color: #212121; + background-color: #eeeeee; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { - color: #cccccc; - background-color: transparent; + color: #cccccc; + background-color: transparent; } .navbar-default .navbar-toggle { - border-color: transparent; + border-color: transparent; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { - background-color: transparent; + background-color: transparent; } .navbar-default .navbar-toggle .icon-bar { - background-color: rgba(0, 0, 0, 0.5); + background-color: rgba(0, 0, 0, 0.5); } .navbar-default .navbar-collapse, .navbar-default .navbar-form { - border-color: transparent; + border-color: transparent; } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { - background-color: #eeeeee; - color: #212121; + background-color: #eeeeee; + color: #212121; } @media (max-width: 767px) { - .navbar-default .navbar-nav .open .dropdown-menu > li > a { - color: #666666; - } - .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { - color: #212121; - background-color: transparent; - } - .navbar-default .navbar-nav .open .dropdown-menu > .active > a, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #212121; - background-color: #eeeeee; - } - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #cccccc; - background-color: transparent; - } + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #666666; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #212121; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #212121; + background-color: #eeeeee; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } } .navbar-default .navbar-link { - color: #666666; + color: #666666; } .navbar-default .navbar-link:hover { - color: #212121; + color: #212121; } .navbar-default .btn-link { - color: #666666; + color: #666666; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { - color: #212121; + color: #212121; } .navbar-default .btn-link[disabled]:hover, fieldset[disabled] .navbar-default .btn-link:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:focus { - color: #cccccc; + color: #cccccc; } .navbar-inverse { - background-color: #2196f3; - border-color: transparent; + background-color: #2196f3; + border-color: transparent; } .navbar-inverse .navbar-brand { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { - color: #ffffff; - background-color: transparent; + color: #ffffff; + background-color: transparent; } .navbar-inverse .navbar-text { - color: #bbbbbb; + color: #bbbbbb; } .navbar-inverse .navbar-nav > li > a { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { - color: #ffffff; - background-color: transparent; + color: #ffffff; + background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { - color: #ffffff; - background-color: #0c7cd5; + color: #ffffff; + background-color: #0c7cd5; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { - color: #444444; - background-color: transparent; + color: #444444; + background-color: transparent; } .navbar-inverse .navbar-toggle { - border-color: transparent; + border-color: transparent; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { - background-color: transparent; + background-color: transparent; } .navbar-inverse .navbar-toggle .icon-bar { - background-color: rgba(0, 0, 0, 0.5); + background-color: rgba(0, 0, 0, 0.5); } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { - border-color: #0c84e4; + border-color: #0c84e4; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { - background-color: #0c7cd5; - color: #ffffff; + background-color: #0c7cd5; + color: #ffffff; } @media (max-width: 767px) { - .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { - border-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu .divider { - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { - color: #b2dbfb; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { - color: #ffffff; - background-color: transparent; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { - color: #ffffff; - background-color: #0c7cd5; - } - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, - .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { - color: #444444; - background-color: transparent; - } + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #b2dbfb; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #ffffff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #ffffff; + background-color: #0c7cd5; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444444; + background-color: transparent; + } } .navbar-inverse .navbar-link { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .navbar-link:hover { - color: #ffffff; + color: #ffffff; } .navbar-inverse .btn-link { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { - color: #ffffff; + color: #ffffff; } .navbar-inverse .btn-link[disabled]:hover, fieldset[disabled] .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:focus { - color: #444444; + color: #444444; } .breadcrumb { - padding: 8px 15px; - margin-bottom: 23px; - list-style: none; - background-color: #f5f5f5; - border-radius: 3px; + padding: 8px 15px; + margin-bottom: 23px; + list-style: none; + background-color: #f5f5f5; + border-radius: 3px; } .breadcrumb > li { - display: inline-block; + display: inline-block; } .breadcrumb > li + li:before { - content: "/\00a0"; - padding: 0 5px; - color: #cccccc; + content: "/\00a0"; + padding: 0 5px; + color: #cccccc; } .breadcrumb > .active { - color: #bbbbbb; + color: #bbbbbb; } .pagination { - display: inline-block; - padding-left: 0; - margin: 23px 0; - border-radius: 3px; + display: inline-block; + padding-left: 0; + margin: 23px 0; + border-radius: 3px; } .pagination > li { - display: inline; + display: inline; } .pagination > li > a, .pagination > li > span { - position: relative; - float: left; - padding: 6px 16px; - line-height: 1.846; - text-decoration: none; - color: #2196f3; - background-color: #ffffff; - border: 1px solid #dddddd; - margin-left: -1px; + position: relative; + float: left; + padding: 6px 16px; + line-height: 1.846; + text-decoration: none; + color: #2196f3; + background-color: #ffffff; + border: 1px solid #dddddd; + margin-left: -1px; } .pagination > li:first-child > a, .pagination > li:first-child > span { - margin-left: 0; - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; + margin-left: 0; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; } .pagination > li:last-child > a, .pagination > li:last-child > span { - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; } .pagination > li > a:hover, .pagination > li > span:hover, .pagination > li > a:focus, .pagination > li > span:focus { - color: #0a6ebd; - background-color: #eeeeee; - border-color: #dddddd; + color: #0a6ebd; + background-color: #eeeeee; + border-color: #dddddd; } .pagination > .active > a, .pagination > .active > span, @@ -4654,11 +4654,11 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .active > span:hover, .pagination > .active > a:focus, .pagination > .active > span:focus { - z-index: 2; - color: #ffffff; - background-color: #2196f3; - border-color: #2196f3; - cursor: default; + z-index: 2; + color: #ffffff; + background-color: #2196f3; + border-color: #2196f3; + cursor: default; } .pagination > .disabled > span, .pagination > .disabled > span:hover, @@ -4666,528 +4666,528 @@ fieldset[disabled] .navbar-inverse .btn-link:focus { .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { - color: #bbbbbb; - background-color: #ffffff; - border-color: #dddddd; - cursor: not-allowed; + color: #bbbbbb; + background-color: #ffffff; + border-color: #dddddd; + cursor: not-allowed; } .pagination-lg > li > a, .pagination-lg > li > span { - padding: 10px 16px; - font-size: 17px; + padding: 10px 16px; + font-size: 17px; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; } .pagination-sm > li > a, .pagination-sm > li > span { - padding: 5px 10px; - font-size: 12px; + padding: 5px 10px; + font-size: 12px; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { - border-bottom-left-radius: 3px; - border-top-left-radius: 3px; + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { - border-bottom-right-radius: 3px; - border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; } .pager { - padding-left: 0; - margin: 23px 0; - list-style: none; - text-align: center; + padding-left: 0; + margin: 23px 0; + list-style: none; + text-align: center; } .pager li { - display: inline; + display: inline; } .pager li > a, .pager li > span { - display: inline-block; - padding: 5px 14px; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 15px; + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { - text-decoration: none; - background-color: #eeeeee; + text-decoration: none; + background-color: #eeeeee; } .pager .next > a, .pager .next > span { - float: right; + float: right; } .pager .previous > a, .pager .previous > span { - float: left; + float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { - color: #bbbbbb; - background-color: #ffffff; - cursor: not-allowed; + color: #bbbbbb; + background-color: #ffffff; + cursor: not-allowed; } .label { - display: inline; - padding: .2em .6em .3em; - font-size: 75%; - font-weight: bold; - line-height: 1; - color: #ffffff; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: .25em; + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; } a.label:hover, a.label:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; + color: #ffffff; + text-decoration: none; + cursor: pointer; } .label:empty { - display: none; + display: none; } .btn .label { - position: relative; - top: -1px; + position: relative; + top: -1px; } .label-default { - background-color: #bbbbbb; + background-color: #bbbbbb; } .label-default[href]:hover, .label-default[href]:focus { - background-color: #a2a2a2; + background-color: #a2a2a2; } .label-primary { - background-color: #2196f3; + background-color: #2196f3; } .label-primary[href]:hover, .label-primary[href]:focus { - background-color: #0c7cd5; + background-color: #0c7cd5; } .label-success { - background-color: #4caf50; + background-color: #4caf50; } .label-success[href]:hover, .label-success[href]:focus { - background-color: #3d8b40; + background-color: #3d8b40; } .label-info { - background-color: #9c27b0; + background-color: #9c27b0; } .label-info[href]:hover, .label-info[href]:focus { - background-color: #771e86; + background-color: #771e86; } .label-warning { - background-color: #ff9800; + background-color: #ff9800; } .label-warning[href]:hover, .label-warning[href]:focus { - background-color: #cc7a00; + background-color: #cc7a00; } .label-danger { - background-color: #e51c23; + background-color: #e51c23; } .label-danger[href]:hover, .label-danger[href]:focus { - background-color: #b9151b; + background-color: #b9151b; } .badge { - display: inline-block; - min-width: 10px; - padding: 3px 7px; - font-size: 12px; - font-weight: normal; - color: #ffffff; - line-height: 1; - vertical-align: baseline; - white-space: nowrap; - text-align: center; - background-color: #bbbbbb; - border-radius: 10px; + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: normal; + color: #ffffff; + line-height: 1; + vertical-align: baseline; + white-space: nowrap; + text-align: center; + background-color: #bbbbbb; + border-radius: 10px; } .badge:empty { - display: none; + display: none; } .btn .badge { - position: relative; - top: -1px; + position: relative; + top: -1px; } .btn-xs .badge, .btn-group-xs > .btn .badge { - top: 0; - padding: 1px 5px; + top: 0; + padding: 1px 5px; } a.badge:hover, a.badge:focus { - color: #ffffff; - text-decoration: none; - cursor: pointer; + color: #ffffff; + text-decoration: none; + cursor: pointer; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { - color: #2196f3; - background-color: #ffffff; + color: #2196f3; + background-color: #ffffff; } .list-group-item > .badge { - float: right; + float: right; } .list-group-item > .badge + .badge { - margin-right: 5px; + margin-right: 5px; } .nav-pills > li > a > .badge { - margin-left: 3px; + margin-left: 3px; } .jumbotron { - padding: 30px 15px; - margin-bottom: 30px; - color: inherit; - background-color: #f9f9f9; + padding: 30px 15px; + margin-bottom: 30px; + color: inherit; + background-color: #f9f9f9; } .jumbotron h1, .jumbotron .h1 { - color: #444444; + color: #444444; } .jumbotron p { - margin-bottom: 15px; - font-size: 20px; - font-weight: 200; + margin-bottom: 15px; + font-size: 20px; + font-weight: 200; } .jumbotron > hr { - border-top-color: #e0e0e0; + border-top-color: #e0e0e0; } .container .jumbotron, .container-fluid .jumbotron { - border-radius: 3px; + border-radius: 3px; } .jumbotron .container { - max-width: 100%; + max-width: 100%; } @media screen and (min-width: 768px) { - .jumbotron { - padding: 48px 0; - } - .container .jumbotron, - .container-fluid .jumbotron { - padding-left: 60px; - padding-right: 60px; - } - .jumbotron h1, - .jumbotron .h1 { - font-size: 58.5px; - } + .jumbotron { + padding: 48px 0; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 58.5px; + } } .thumbnail { - display: block; - padding: 4px; - margin-bottom: 23px; - line-height: 1.846; - background-color: #ffffff; - border: 1px solid #dddddd; - border-radius: 3px; - -webkit-transition: border 0.2s ease-in-out; - -o-transition: border 0.2s ease-in-out; - transition: border 0.2s ease-in-out; + display: block; + padding: 4px; + margin-bottom: 23px; + line-height: 1.846; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 3px; + -webkit-transition: border 0.2s ease-in-out; + -o-transition: border 0.2s ease-in-out; + transition: border 0.2s ease-in-out; } .thumbnail > img, .thumbnail a > img { - margin-left: auto; - margin-right: auto; + margin-left: auto; + margin-right: auto; } a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { - border-color: #2196f3; + border-color: #2196f3; } .thumbnail .caption { - padding: 9px; - color: #666666; + padding: 9px; + color: #666666; } .alert { - padding: 15px; - margin-bottom: 23px; - border: 1px solid transparent; - border-radius: 3px; + padding: 15px; + margin-bottom: 23px; + border: 1px solid transparent; + border-radius: 3px; } .alert h4 { - margin-top: 0; - color: inherit; + margin-top: 0; + color: inherit; } .alert .alert-link { - font-weight: bold; + font-weight: bold; } .alert > p, .alert > ul { - margin-bottom: 0; + margin-bottom: 0; } .alert > p + p { - margin-top: 5px; + margin-top: 5px; } .alert-dismissable, .alert-dismissible { - padding-right: 35px; + padding-right: 35px; } .alert-dismissable .close, .alert-dismissible .close { - position: relative; - top: -2px; - right: -21px; - color: inherit; + position: relative; + top: -2px; + right: -21px; + color: inherit; } .alert-success { - background-color: #dff0d8; - border-color: #d6e9c6; - color: #4caf50; + background-color: #dff0d8; + border-color: #d6e9c6; + color: #4caf50; } .alert-success hr { - border-top-color: #c9e2b3; + border-top-color: #c9e2b3; } .alert-success .alert-link { - color: #3d8b40; + color: #3d8b40; } .alert-info { - background-color: #e1bee7; - border-color: #cba4dd; - color: #9c27b0; + background-color: #e1bee7; + border-color: #cba4dd; + color: #9c27b0; } .alert-info hr { - border-top-color: #c191d6; + border-top-color: #c191d6; } .alert-info .alert-link { - color: #771e86; + color: #771e86; } .alert-warning { - background-color: #ffe0b2; - border-color: #ffc599; - color: #ff9800; + background-color: #ffe0b2; + border-color: #ffc599; + color: #ff9800; } .alert-warning hr { - border-top-color: #ffb67f; + border-top-color: #ffb67f; } .alert-warning .alert-link { - color: #cc7a00; + color: #cc7a00; } .alert-danger { - background-color: #f9bdbb; - border-color: #f7a4af; - color: #e51c23; + background-color: #f9bdbb; + border-color: #f7a4af; + color: #e51c23; } .alert-danger hr { - border-top-color: #f58c9a; + border-top-color: #f58c9a; } .alert-danger .alert-link { - color: #b9151b; + color: #b9151b; } @-webkit-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } @-o-keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } @keyframes progress-bar-stripes { - from { - background-position: 40px 0; - } - to { - background-position: 0 0; - } + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } } .progress { - overflow: hidden; - height: 23px; - margin-bottom: 23px; - background-color: #f5f5f5; - border-radius: 3px; - -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); - box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + overflow: hidden; + height: 23px; + margin-bottom: 23px; + background-color: #f5f5f5; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } .progress-bar { - float: left; - width: 0%; - height: 100%; - font-size: 12px; - line-height: 23px; - color: #ffffff; - text-align: center; - background-color: #2196f3; - -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); - -webkit-transition: width 0.6s ease; - -o-transition: width 0.6s ease; - transition: width 0.6s ease; + float: left; + width: 0%; + height: 100%; + font-size: 12px; + line-height: 23px; + color: #ffffff; + text-align: center; + background-color: #2196f3; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; } .progress-striped .progress-bar, .progress-bar-striped { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - -webkit-background-size: 40px 40px; - background-size: 40px 40px; + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { - -webkit-animation: progress-bar-stripes 2s linear infinite; - -o-animation: progress-bar-stripes 2s linear infinite; - animation: progress-bar-stripes 2s linear infinite; + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { - background-color: #4caf50; + background-color: #4caf50; } .progress-striped .progress-bar-success { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-info { - background-color: #9c27b0; + background-color: #9c27b0; } .progress-striped .progress-bar-info { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-warning { - background-color: #ff9800; + background-color: #ff9800; } .progress-striped .progress-bar-warning { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-danger { - background-color: #e51c23; + background-color: #e51c23; } .progress-striped .progress-bar-danger { - background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .media { - margin-top: 15px; + margin-top: 15px; } .media:first-child { - margin-top: 0; + margin-top: 0; } .media, .media-body { - zoom: 1; - overflow: hidden; + zoom: 1; + overflow: hidden; } .media-body { - width: 10000px; + width: 10000px; } .media-object { - display: block; + display: block; } .media-right, .media > .pull-right { - padding-left: 10px; + padding-left: 10px; } .media-left, .media > .pull-left { - padding-right: 10px; + padding-right: 10px; } .media-left, .media-right, .media-body { - display: table-cell; - vertical-align: top; + display: table-cell; + vertical-align: top; } .media-middle { - vertical-align: middle; + vertical-align: middle; } .media-bottom { - vertical-align: bottom; + vertical-align: bottom; } .media-heading { - margin-top: 0; - margin-bottom: 5px; + margin-top: 0; + margin-bottom: 5px; } .media-list { - padding-left: 0; - list-style: none; + padding-left: 0; + list-style: none; } .list-group { - margin-bottom: 20px; - padding-left: 0; + margin-bottom: 20px; + padding-left: 0; } .list-group-item { - position: relative; - display: block; - padding: 10px 15px; - margin-bottom: -1px; - background-color: #ffffff; - border: 1px solid #dddddd; + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; } .list-group-item:first-child { - border-top-right-radius: 3px; - border-top-left-radius: 3px; + border-top-right-radius: 3px; + border-top-left-radius: 3px; } .list-group-item:last-child { - margin-bottom: 0; - border-bottom-right-radius: 3px; - border-bottom-left-radius: 3px; + margin-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; } a.list-group-item { - color: #555555; + color: #555555; } a.list-group-item .list-group-item-heading { - color: #333333; + color: #333333; } a.list-group-item:hover, a.list-group-item:focus { - text-decoration: none; - color: #555555; - background-color: #f5f5f5; + text-decoration: none; + color: #555555; + background-color: #f5f5f5; } .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { - background-color: #eeeeee; - color: #bbbbbb; - cursor: not-allowed; + background-color: #eeeeee; + color: #bbbbbb; + cursor: not-allowed; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading { - color: inherit; + color: inherit; } .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { - color: #bbbbbb; + color: #bbbbbb; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { - z-index: 2; - color: #ffffff; - background-color: #2196f3; - border-color: #2196f3; + z-index: 2; + color: #ffffff; + background-color: #2196f3; + border-color: #2196f3; } .list-group-item.active .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading, @@ -5198,198 +5198,198 @@ a.list-group-item:focus { .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading > .small { - color: inherit; + color: inherit; } .list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text { - color: #e3f2fd; + color: #e3f2fd; } .list-group-item-success { - color: #4caf50; - background-color: #dff0d8; + color: #4caf50; + background-color: #dff0d8; } a.list-group-item-success { - color: #4caf50; + color: #4caf50; } a.list-group-item-success .list-group-item-heading { - color: inherit; + color: inherit; } a.list-group-item-success:hover, a.list-group-item-success:focus { - color: #4caf50; - background-color: #d0e9c6; + color: #4caf50; + background-color: #d0e9c6; } a.list-group-item-success.active, a.list-group-item-success.active:hover, a.list-group-item-success.active:focus { - color: #fff; - background-color: #4caf50; - border-color: #4caf50; + color: #fff; + background-color: #4caf50; + border-color: #4caf50; } .list-group-item-info { - color: #9c27b0; - background-color: #e1bee7; + color: #9c27b0; + background-color: #e1bee7; } a.list-group-item-info { - color: #9c27b0; + color: #9c27b0; } a.list-group-item-info .list-group-item-heading { - color: inherit; + color: inherit; } a.list-group-item-info:hover, a.list-group-item-info:focus { - color: #9c27b0; - background-color: #d8abe0; + color: #9c27b0; + background-color: #d8abe0; } a.list-group-item-info.active, a.list-group-item-info.active:hover, a.list-group-item-info.active:focus { - color: #fff; - background-color: #9c27b0; - border-color: #9c27b0; + color: #fff; + background-color: #9c27b0; + border-color: #9c27b0; } .list-group-item-warning { - color: #ff9800; - background-color: #ffe0b2; + color: #ff9800; + background-color: #ffe0b2; } a.list-group-item-warning { - color: #ff9800; + color: #ff9800; } a.list-group-item-warning .list-group-item-heading { - color: inherit; + color: inherit; } a.list-group-item-warning:hover, a.list-group-item-warning:focus { - color: #ff9800; - background-color: #ffd699; + color: #ff9800; + background-color: #ffd699; } a.list-group-item-warning.active, a.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus { - color: #fff; - background-color: #ff9800; - border-color: #ff9800; + color: #fff; + background-color: #ff9800; + border-color: #ff9800; } .list-group-item-danger { - color: #e51c23; - background-color: #f9bdbb; + color: #e51c23; + background-color: #f9bdbb; } a.list-group-item-danger { - color: #e51c23; + color: #e51c23; } a.list-group-item-danger .list-group-item-heading { - color: inherit; + color: inherit; } a.list-group-item-danger:hover, a.list-group-item-danger:focus { - color: #e51c23; - background-color: #f7a6a4; + color: #e51c23; + background-color: #f7a6a4; } a.list-group-item-danger.active, a.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus { - color: #fff; - background-color: #e51c23; - border-color: #e51c23; + color: #fff; + background-color: #e51c23; + border-color: #e51c23; } .list-group-item-heading { - margin-top: 0; - margin-bottom: 5px; + margin-top: 0; + margin-bottom: 5px; } .list-group-item-text { - margin-bottom: 0; - line-height: 1.3; + margin-bottom: 0; + line-height: 1.3; } .panel { - margin-bottom: 23px; - background-color: #ffffff; - border: 1px solid transparent; - border-radius: 3px; - -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + margin-bottom: 23px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 3px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); } .panel-body { - padding: 15px; + padding: 15px; } .panel-heading { - padding: 10px 15px; - border-bottom: 1px solid transparent; - border-top-right-radius: 2px; - border-top-left-radius: 2px; + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 2px; + border-top-left-radius: 2px; } .panel-heading > .dropdown .dropdown-toggle { - color: inherit; + color: inherit; } .panel-title { - margin-top: 0; - margin-bottom: 0; - font-size: 15px; - color: inherit; + margin-top: 0; + margin-bottom: 0; + font-size: 15px; + color: inherit; } .panel-title > a, .panel-title > small, .panel-title > .small, .panel-title > small > a, .panel-title > .small > a { - color: inherit; + color: inherit; } .panel-footer { - padding: 10px 15px; - background-color: #f5f5f5; - border-top: 1px solid #dddddd; - border-bottom-right-radius: 2px; - border-bottom-left-radius: 2px; + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 2px; + border-bottom-left-radius: 2px; } .panel > .list-group, .panel > .panel-collapse > .list-group { - margin-bottom: 0; + margin-bottom: 0; } .panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item { - border-width: 1px 0; - border-radius: 0; + border-width: 1px 0; + border-radius: 0; } .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { - border-top: 0; - border-top-right-radius: 2px; - border-top-left-radius: 2px; + border-top: 0; + border-top-right-radius: 2px; + border-top-left-radius: 2px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { - border-bottom: 0; - border-bottom-right-radius: 2px; - border-bottom-left-radius: 2px; + border-bottom: 0; + border-bottom-right-radius: 2px; + border-bottom-left-radius: 2px; } .panel-heading + .list-group .list-group-item:first-child { - border-top-width: 0; + border-top-width: 0; } .list-group + .panel-footer { - border-top-width: 0; + border-top-width: 0; } .panel > .table, .panel > .table-responsive > .table, .panel > .panel-collapse > .table { - margin-bottom: 0; + margin-bottom: 0; } .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { - padding-left: 15px; - padding-right: 15px; + padding-left: 15px; + padding-right: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { - border-top-right-radius: 2px; - border-top-left-radius: 2px; + border-top-right-radius: 2px; + border-top-left-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { - border-top-left-radius: 2px; - border-top-right-radius: 2px; + border-top-left-radius: 2px; + border-top-right-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, @@ -5399,7 +5399,7 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { - border-top-left-radius: 2px; + border-top-left-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, @@ -5409,19 +5409,19 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { - border-top-right-radius: 2px; + border-top-right-radius: 2px; } .panel > .table:last-child, .panel > .table-responsive:last-child > .table:last-child { - border-bottom-right-radius: 2px; - border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + border-bottom-left-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, @@ -5431,7 +5431,7 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { - border-bottom-left-radius: 2px; + border-bottom-left-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, @@ -5441,21 +5441,21 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { - border-bottom-right-radius: 2px; + border-bottom-right-radius: 2px; } .panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { - border-top: 1px solid #dddddd; + border-top: 1px solid #dddddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { - border-top: 0; + border-top: 0; } .panel > .table-bordered, .panel > .table-responsive > .table-bordered { - border: 0; + border: 0; } .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, @@ -5469,7 +5469,7 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { - border-left: 0; + border-left: 0; } .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, @@ -5483,7 +5483,7 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { - border-right: 0; + border-right: 0; } .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, @@ -5493,7 +5493,7 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { - border-bottom: 0; + border-bottom: 0; } .panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, @@ -5503,785 +5503,785 @@ a.list-group-item-danger.active:focus { .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { - border-bottom: 0; + border-bottom: 0; } .panel > .table-responsive { - border: 0; - margin-bottom: 0; + border: 0; + margin-bottom: 0; } .panel-group { - margin-bottom: 23px; + margin-bottom: 23px; } .panel-group .panel { - margin-bottom: 0; - border-radius: 3px; + margin-bottom: 0; + border-radius: 3px; } .panel-group .panel + .panel { - margin-top: 5px; + margin-top: 5px; } .panel-group .panel-heading { - border-bottom: 0; + border-bottom: 0; } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { - border-top: 1px solid #dddddd; + border-top: 1px solid #dddddd; } .panel-group .panel-footer { - border-top: 0; + border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { - border-bottom: 1px solid #dddddd; + border-bottom: 1px solid #dddddd; } .panel-default { - border-color: #dddddd; + border-color: #dddddd; } .panel-default > .panel-heading { - color: #212121; - background-color: #f5f5f5; - border-color: #dddddd; + color: #212121; + background-color: #f5f5f5; + border-color: #dddddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #dddddd; + border-top-color: #dddddd; } .panel-default > .panel-heading .badge { - color: #f5f5f5; - background-color: #212121; + color: #f5f5f5; + background-color: #212121; } .panel-default > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #dddddd; + border-bottom-color: #dddddd; } .panel-primary { - border-color: #2196f3; + border-color: #2196f3; } .panel-primary > .panel-heading { - color: #ffffff; - background-color: #2196f3; - border-color: #2196f3; + color: #ffffff; + background-color: #2196f3; + border-color: #2196f3; } .panel-primary > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #2196f3; + border-top-color: #2196f3; } .panel-primary > .panel-heading .badge { - color: #2196f3; - background-color: #ffffff; + color: #2196f3; + background-color: #ffffff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #2196f3; + border-bottom-color: #2196f3; } .panel-success { - border-color: #d6e9c6; + border-color: #d6e9c6; } .panel-success > .panel-heading { - color: #ffffff; - background-color: #4caf50; - border-color: #d6e9c6; + color: #ffffff; + background-color: #4caf50; + border-color: #d6e9c6; } .panel-success > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #d6e9c6; + border-top-color: #d6e9c6; } .panel-success > .panel-heading .badge { - color: #4caf50; - background-color: #ffffff; + color: #4caf50; + background-color: #ffffff; } .panel-success > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #d6e9c6; + border-bottom-color: #d6e9c6; } .panel-info { - border-color: #cba4dd; + border-color: #cba4dd; } .panel-info > .panel-heading { - color: #ffffff; - background-color: #9c27b0; - border-color: #cba4dd; + color: #ffffff; + background-color: #9c27b0; + border-color: #cba4dd; } .panel-info > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #cba4dd; + border-top-color: #cba4dd; } .panel-info > .panel-heading .badge { - color: #9c27b0; - background-color: #ffffff; + color: #9c27b0; + background-color: #ffffff; } .panel-info > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #cba4dd; + border-bottom-color: #cba4dd; } .panel-warning { - border-color: #ffc599; + border-color: #ffc599; } .panel-warning > .panel-heading { - color: #ffffff; - background-color: #ff9800; - border-color: #ffc599; + color: #ffffff; + background-color: #ff9800; + border-color: #ffc599; } .panel-warning > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #ffc599; + border-top-color: #ffc599; } .panel-warning > .panel-heading .badge { - color: #ff9800; - background-color: #ffffff; + color: #ff9800; + background-color: #ffffff; } .panel-warning > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #ffc599; + border-bottom-color: #ffc599; } .panel-danger { - border-color: #f7a4af; + border-color: #f7a4af; } .panel-danger > .panel-heading { - color: #ffffff; - background-color: #e51c23; - border-color: #f7a4af; + color: #ffffff; + background-color: #e51c23; + border-color: #f7a4af; } .panel-danger > .panel-heading + .panel-collapse > .panel-body { - border-top-color: #f7a4af; + border-top-color: #f7a4af; } .panel-danger > .panel-heading .badge { - color: #e51c23; - background-color: #ffffff; + color: #e51c23; + background-color: #ffffff; } .panel-danger > .panel-footer + .panel-collapse > .panel-body { - border-bottom-color: #f7a4af; + border-bottom-color: #f7a4af; } .embed-responsive { - position: relative; - display: block; - height: 0; - padding: 0; - overflow: hidden; + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; } .embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video { - position: absolute; - top: 0; - left: 0; - bottom: 0; - height: 100%; - width: 100%; - border: 0; + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; } .embed-responsive-16by9 { - padding-bottom: 56.25%; + padding-bottom: 56.25%; } .embed-responsive-4by3 { - padding-bottom: 75%; + padding-bottom: 75%; } .well { - min-height: 20px; - padding: 19px; - margin-bottom: 20px; - background-color: #f9f9f9; - border: 1px solid transparent; - border-radius: 3px; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f9f9f9; + border: 1px solid transparent; + border-radius: 3px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); } .well blockquote { - border-color: #ddd; - border-color: rgba(0, 0, 0, 0.15); + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); } .well-lg { - padding: 24px; - border-radius: 3px; + padding: 24px; + border-radius: 3px; } .well-sm { - padding: 9px; - border-radius: 3px; + padding: 9px; + border-radius: 3px; } .close { - float: right; - font-size: 19.5px; - font-weight: normal; - line-height: 1; - color: #000000; - text-shadow: none; - opacity: 0.2; - filter: alpha(opacity=20); + float: right; + font-size: 19.5px; + font-weight: normal; + line-height: 1; + color: #000000; + text-shadow: none; + opacity: 0.2; + filter: alpha(opacity=20); } .close:hover, .close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); } button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; } .modal-open { - overflow: hidden; + overflow: hidden; } .modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - -webkit-overflow-scrolling: touch; - outline: 0; + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; } .modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; } .modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); } .modal-open .modal { - overflow-x: hidden; - overflow-y: auto; + overflow-x: hidden; + overflow-y: auto; } .modal-dialog { - position: relative; - width: auto; - margin: 10px; + position: relative; + width: auto; + margin: 10px; } .modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid transparent; - border-radius: 3px; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -webkit-background-clip: padding-box; - background-clip: padding-box; - outline: 0; + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid transparent; + border-radius: 3px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + -webkit-background-clip: padding-box; + background-clip: padding-box; + outline: 0; } .modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; } .modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); + opacity: 0; + filter: alpha(opacity=0); } .modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); + opacity: 0.5; + filter: alpha(opacity=50); } .modal-header { - padding: 15px; - border-bottom: 1px solid transparent; - min-height: 16.846px; + padding: 15px; + border-bottom: 1px solid transparent; + min-height: 16.846px; } .modal-header .close { - margin-top: -2px; + margin-top: -2px; } .modal-title { - margin: 0; - line-height: 1.846; + margin: 0; + line-height: 1.846; } .modal-body { - position: relative; - padding: 15px; + position: relative; + padding: 15px; } .modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid transparent; + padding: 15px; + text-align: right; + border-top: 1px solid transparent; } .modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; + margin-left: 5px; + margin-bottom: 0; } .modal-footer .btn-group .btn + .btn { - margin-left: -1px; + margin-left: -1px; } .modal-footer .btn-block + .btn-block { - margin-left: 0; + margin-left: 0; } .modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; } @media (min-width: 768px) { - .modal-dialog { - width: 600px; - margin: 30px auto; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } - .modal-sm { - width: 300px; - } + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } } @media (min-width: 992px) { - .modal-lg { - width: 900px; - } + .modal-lg { + width: 900px; + } } .tooltip { - position: absolute; - z-index: 1070; - display: block; - font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 12px; - font-weight: normal; - line-height: 1.4; - opacity: 0; - filter: alpha(opacity=0); + position: absolute; + z-index: 1070; + display: block; + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 12px; + font-weight: normal; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); } .tooltip.in { - opacity: 0.9; - filter: alpha(opacity=90); + opacity: 0.9; + filter: alpha(opacity=90); } .tooltip.top { - margin-top: -3px; - padding: 5px 0; + margin-top: -3px; + padding: 5px 0; } .tooltip.right { - margin-left: 3px; - padding: 0 5px; + margin-left: 3px; + padding: 0 5px; } .tooltip.bottom { - margin-top: 3px; - padding: 5px 0; + margin-top: 3px; + padding: 5px 0; } .tooltip.left { - margin-left: -3px; - padding: 0 5px; + margin-left: -3px; + padding: 0 5px; } .tooltip-inner { - max-width: 200px; - padding: 3px 8px; - color: #ffffff; - text-align: center; - text-decoration: none; - background-color: #727272; - border-radius: 3px; + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #727272; + border-radius: 3px; } .tooltip-arrow { - position: absolute; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } .tooltip.top .tooltip-arrow { - bottom: 0; - left: 50%; - margin-left: -5px; - border-width: 5px 5px 0; - border-top-color: #727272; + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #727272; } .tooltip.top-left .tooltip-arrow { - bottom: 0; - right: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #727272; + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #727272; } .tooltip.top-right .tooltip-arrow { - bottom: 0; - left: 5px; - margin-bottom: -5px; - border-width: 5px 5px 0; - border-top-color: #727272; + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #727272; } .tooltip.right .tooltip-arrow { - top: 50%; - left: 0; - margin-top: -5px; - border-width: 5px 5px 5px 0; - border-right-color: #727272; + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #727272; } .tooltip.left .tooltip-arrow { - top: 50%; - right: 0; - margin-top: -5px; - border-width: 5px 0 5px 5px; - border-left-color: #727272; + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #727272; } .tooltip.bottom .tooltip-arrow { - top: 0; - left: 50%; - margin-left: -5px; - border-width: 0 5px 5px; - border-bottom-color: #727272; + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #727272; } .tooltip.bottom-left .tooltip-arrow { - top: 0; - right: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #727272; + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #727272; } .tooltip.bottom-right .tooltip-arrow { - top: 0; - left: 5px; - margin-top: -5px; - border-width: 0 5px 5px; - border-bottom-color: #727272; + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #727272; } .popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: none; - max-width: 276px; - padding: 1px; - font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: normal; - line-height: 1.846; - text-align: left; - background-color: #ffffff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid transparent; - border-radius: 3px; - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - white-space: normal; + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1.846; + text-align: left; + background-color: #ffffff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid transparent; + border-radius: 3px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + white-space: normal; } .popover.top { - margin-top: -10px; + margin-top: -10px; } .popover.right { - margin-left: 10px; + margin-left: 10px; } .popover.bottom { - margin-top: 10px; + margin-top: 10px; } .popover.left { - margin-left: -10px; + margin-left: -10px; } .popover-title { - margin: 0; - padding: 8px 14px; - font-size: 13px; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-radius: 2px 2px 0 0; + margin: 0; + padding: 8px 14px; + font-size: 13px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 2px 2px 0 0; } .popover-content { - padding: 9px 14px; + padding: 9px 14px; } .popover > .arrow, .popover > .arrow:after { - position: absolute; - display: block; - width: 0; - height: 0; - border-color: transparent; - border-style: solid; + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; } .popover > .arrow { - border-width: 11px; + border-width: 11px; } .popover > .arrow:after { - border-width: 10px; - content: ""; + border-width: 10px; + content: ""; } .popover.top > .arrow { - left: 50%; - margin-left: -11px; - border-bottom-width: 0; - border-top-color: rgba(0, 0, 0, 0); - border-top-color: rgba(0, 0, 0, 0.075); - bottom: -11px; + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: rgba(0, 0, 0, 0); + border-top-color: rgba(0, 0, 0, 0.075); + bottom: -11px; } .popover.top > .arrow:after { - content: " "; - bottom: 1px; - margin-left: -10px; - border-bottom-width: 0; - border-top-color: #ffffff; + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; } .popover.right > .arrow { - top: 50%; - left: -11px; - margin-top: -11px; - border-left-width: 0; - border-right-color: rgba(0, 0, 0, 0); - border-right-color: rgba(0, 0, 0, 0.075); + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: rgba(0, 0, 0, 0); + border-right-color: rgba(0, 0, 0, 0.075); } .popover.right > .arrow:after { - content: " "; - left: 1px; - bottom: -10px; - border-left-width: 0; - border-right-color: #ffffff; + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; } .popover.bottom > .arrow { - left: 50%; - margin-left: -11px; - border-top-width: 0; - border-bottom-color: rgba(0, 0, 0, 0); - border-bottom-color: rgba(0, 0, 0, 0.075); - top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: rgba(0, 0, 0, 0); + border-bottom-color: rgba(0, 0, 0, 0.075); + top: -11px; } .popover.bottom > .arrow:after { - content: " "; - top: 1px; - margin-left: -10px; - border-top-width: 0; - border-bottom-color: #ffffff; + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; } .popover.left > .arrow { - top: 50%; - right: -11px; - margin-top: -11px; - border-right-width: 0; - border-left-color: rgba(0, 0, 0, 0); - border-left-color: rgba(0, 0, 0, 0.075); + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: rgba(0, 0, 0, 0); + border-left-color: rgba(0, 0, 0, 0.075); } .popover.left > .arrow:after { - content: " "; - right: 1px; - border-right-width: 0; - border-left-color: #ffffff; - bottom: -10px; + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; } .carousel { - position: relative; + position: relative; } .carousel-inner { - position: relative; - overflow: hidden; - width: 100%; + position: relative; + overflow: hidden; + width: 100%; } .carousel-inner > .item { - display: none; - position: relative; - -webkit-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { - line-height: 1; + line-height: 1; } @media all and (transform-3d), (-webkit-transform-3d) { - .carousel-inner > .item { - -webkit-transition: -webkit-transform 0.6s ease-in-out; - -o-transition: -o-transform 0.6s ease-in-out; - transition: transform 0.6s ease-in-out; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - -webkit-perspective: 1000; - perspective: 1000; - } - .carousel-inner > .item.next, - .carousel-inner > .item.active.right { - -webkit-transform: translate3d(100%, 0, 0); - transform: translate3d(100%, 0, 0); - left: 0; - } - .carousel-inner > .item.prev, - .carousel-inner > .item.active.left { - -webkit-transform: translate3d(-100%, 0, 0); - transform: translate3d(-100%, 0, 0); - left: 0; - } - .carousel-inner > .item.next.left, - .carousel-inner > .item.prev.right, - .carousel-inner > .item.active { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - left: 0; - } + .carousel-inner > .item { + -webkit-transition: -webkit-transform 0.6s ease-in-out; + -o-transition: -o-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000; + perspective: 1000; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + left: 0; + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + left: 0; + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + left: 0; + } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { - display: block; + display: block; } .carousel-inner > .active { - left: 0; + left: 0; } .carousel-inner > .next, .carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; + position: absolute; + top: 0; + width: 100%; } .carousel-inner > .next { - left: 100%; + left: 100%; } .carousel-inner > .prev { - left: -100%; + left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { - left: 0; + left: 0; } .carousel-inner > .active.left { - left: -100%; + left: -100%; } .carousel-inner > .active.right { - left: 100%; + left: 100%; } .carousel-control { - position: absolute; - top: 0; - left: 0; - bottom: 0; - width: 15%; - opacity: 0.5; - filter: alpha(opacity=50); - font-size: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } .carousel-control.left { - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); } .carousel-control.right { - left: auto; - right: 0; - background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); - background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); } .carousel-control:hover, .carousel-control:focus { - outline: 0; - color: #ffffff; - text-decoration: none; - opacity: 0.9; - filter: alpha(opacity=90); + outline: 0; + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); } .carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { - position: absolute; - top: 50%; - z-index: 5; - display: inline-block; + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { - left: 50%; - margin-left: -10px; + left: 50%; + margin-left: -10px; } .carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { - right: 50%; - margin-right: -10px; + right: 50%; + margin-right: -10px; } .carousel-control .icon-prev, .carousel-control .icon-next { - width: 20px; - height: 20px; - margin-top: -10px; - line-height: 1; - font-family: serif; + width: 20px; + height: 20px; + margin-top: -10px; + line-height: 1; + font-family: serif; } .carousel-control .icon-prev:before { - content: '\2039'; + content: '\2039'; } .carousel-control .icon-next:before { - content: '\203a'; + content: '\203a'; } .carousel-indicators { - position: absolute; - bottom: 10px; - left: 50%; - z-index: 15; - width: 60%; - margin-left: -30%; - padding-left: 0; - list-style: none; - text-align: center; + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; } .carousel-indicators li { - display: inline-block; - width: 10px; - height: 10px; - margin: 1px; - text-indent: -999px; - border: 1px solid #ffffff; - border-radius: 10px; - cursor: pointer; - background-color: #000 \9; - background-color: rgba(0, 0, 0, 0); + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #ffffff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); } .carousel-indicators .active { - margin: 0; - width: 12px; - height: 12px; - background-color: #ffffff; + margin: 0; + width: 12px; + height: 12px; + background-color: #ffffff; } .carousel-caption { - position: absolute; - left: 15%; - right: 15%; - bottom: 20px; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #ffffff; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } .carousel-caption .btn { - text-shadow: none; + text-shadow: none; } @media screen and (min-width: 768px) { - .carousel-control .glyphicon-chevron-left, - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-prev, - .carousel-control .icon-next { - width: 30px; - height: 30px; - margin-top: -15px; - font-size: 30px; - } - .carousel-control .glyphicon-chevron-left, - .carousel-control .icon-prev { - margin-left: -15px; - } - .carousel-control .glyphicon-chevron-right, - .carousel-control .icon-next { - margin-right: -15px; - } - .carousel-caption { - left: 20%; - right: 20%; - padding-bottom: 30px; - } - .carousel-indicators { - bottom: 20px; - } + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } } .clearfix:before, .clearfix:after, @@ -6313,8 +6313,8 @@ button.close { .panel-body:after, .modal-footer:before, .modal-footer:after { - content: " "; - display: table; + content: " "; + display: table; } .clearfix:after, .dl-horizontal dd:after, @@ -6331,49 +6331,49 @@ button.close { .pager:after, .panel-body:after, .modal-footer:after { - clear: both; + clear: both; } .center-block { - display: block; - margin-left: auto; - margin-right: auto; + display: block; + margin-left: auto; + margin-right: auto; } .pull-right { - float: right !important; + float: right !important; } .pull-left { - float: left !important; + float: left !important; } .hide { - display: none !important; + display: none !important; } .show { - display: block !important; + display: block !important; } .invisible { - visibility: hidden; + visibility: hidden; } .text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; } .hidden { - display: none !important; + display: none !important; } .affix { - position: fixed; + position: fixed; } @-ms-viewport { - width: device-width; + width: device-width; } .visible-xs, .visible-sm, .visible-md, .visible-lg { - display: none !important; + display: none !important; } .visible-xs-block, .visible-xs-inline, @@ -6387,408 +6387,408 @@ button.close { .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { - display: none !important; + display: none !important; } @media (max-width: 767px) { - .visible-xs { - display: block !important; - } - table.visible-xs { - display: table; - } - tr.visible-xs { - display: table-row !important; - } - th.visible-xs, - td.visible-xs { - display: table-cell !important; - } + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } } @media (max-width: 767px) { - .visible-xs-block { - display: block !important; - } + .visible-xs-block { + display: block !important; + } } @media (max-width: 767px) { - .visible-xs-inline { - display: inline !important; - } + .visible-xs-inline { + display: inline !important; + } } @media (max-width: 767px) { - .visible-xs-inline-block { - display: inline-block !important; - } + .visible-xs-inline-block { + display: inline-block !important; + } } @media (min-width: 768px) and (max-width: 991px) { - .visible-sm { - display: block !important; - } - table.visible-sm { - display: table; - } - tr.visible-sm { - display: table-row !important; - } - th.visible-sm, - td.visible-sm { - display: table-cell !important; - } + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } } @media (min-width: 768px) and (max-width: 991px) { - .visible-sm-block { - display: block !important; - } + .visible-sm-block { + display: block !important; + } } @media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline { - display: inline !important; - } + .visible-sm-inline { + display: inline !important; + } } @media (min-width: 768px) and (max-width: 991px) { - .visible-sm-inline-block { - display: inline-block !important; - } + .visible-sm-inline-block { + display: inline-block !important; + } } @media (min-width: 992px) and (max-width: 1199px) { - .visible-md { - display: block !important; - } - table.visible-md { - display: table; - } - tr.visible-md { - display: table-row !important; - } - th.visible-md, - td.visible-md { - display: table-cell !important; - } + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } } @media (min-width: 992px) and (max-width: 1199px) { - .visible-md-block { - display: block !important; - } + .visible-md-block { + display: block !important; + } } @media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline { - display: inline !important; - } + .visible-md-inline { + display: inline !important; + } } @media (min-width: 992px) and (max-width: 1199px) { - .visible-md-inline-block { - display: inline-block !important; - } + .visible-md-inline-block { + display: inline-block !important; + } } @media (min-width: 1200px) { - .visible-lg { - display: block !important; - } - table.visible-lg { - display: table; - } - tr.visible-lg { - display: table-row !important; - } - th.visible-lg, - td.visible-lg { - display: table-cell !important; - } + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } } @media (min-width: 1200px) { - .visible-lg-block { - display: block !important; - } + .visible-lg-block { + display: block !important; + } } @media (min-width: 1200px) { - .visible-lg-inline { - display: inline !important; - } + .visible-lg-inline { + display: inline !important; + } } @media (min-width: 1200px) { - .visible-lg-inline-block { - display: inline-block !important; - } + .visible-lg-inline-block { + display: inline-block !important; + } } @media (max-width: 767px) { - .hidden-xs { - display: none !important; - } + .hidden-xs { + display: none !important; + } } @media (min-width: 768px) and (max-width: 991px) { - .hidden-sm { - display: none !important; - } + .hidden-sm { + display: none !important; + } } @media (min-width: 992px) and (max-width: 1199px) { - .hidden-md { - display: none !important; - } + .hidden-md { + display: none !important; + } } @media (min-width: 1200px) { - .hidden-lg { - display: none !important; - } + .hidden-lg { + display: none !important; + } } .visible-print { - display: none !important; + display: none !important; } @media print { - .visible-print { - display: block !important; - } - table.visible-print { - display: table; - } - tr.visible-print { - display: table-row !important; - } - th.visible-print, - td.visible-print { - display: table-cell !important; - } + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } } .visible-print-block { - display: none !important; + display: none !important; } @media print { - .visible-print-block { - display: block !important; - } + .visible-print-block { + display: block !important; + } } .visible-print-inline { - display: none !important; + display: none !important; } @media print { - .visible-print-inline { - display: inline !important; - } + .visible-print-inline { + display: inline !important; + } } .visible-print-inline-block { - display: none !important; + display: none !important; } @media print { - .visible-print-inline-block { - display: inline-block !important; - } + .visible-print-inline-block { + display: inline-block !important; + } } @media print { - .hidden-print { - display: none !important; - } + .hidden-print { + display: none !important; + } } .navbar { - border: none; - -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + border: none; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } .navbar-brand { - font-size: 24px; + font-size: 24px; } .navbar-inverse .form-control { - color: #fff; + color: #fff; } .navbar-inverse .form-control::-moz-placeholder { - color: #b2dbfb; - opacity: 1; + color: #b2dbfb; + opacity: 1; } .navbar-inverse .form-control:-ms-input-placeholder { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .form-control::-webkit-input-placeholder { - color: #b2dbfb; + color: #b2dbfb; } .navbar-inverse .form-control[type=text] { - -webkit-box-shadow: inset 0 -1px 0 #b2dbfb; - box-shadow: inset 0 -1px 0 #b2dbfb; + -webkit-box-shadow: inset 0 -1px 0 #b2dbfb; + box-shadow: inset 0 -1px 0 #b2dbfb; } .navbar-inverse .form-control[type=text]:focus { - -webkit-box-shadow: inset 0 -2px 0 #ffffff; - box-shadow: inset 0 -2px 0 #ffffff; + -webkit-box-shadow: inset 0 -2px 0 #ffffff; + box-shadow: inset 0 -2px 0 #ffffff; } .navbar-nav > li > .dropdown-menu { - margin-top: 2px; + margin-top: 2px; } .btn-default { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-default:hover, .btn-default:active:hover, .btn-default:focus { - background-color: #f0f0f0; + background-color: #f0f0f0; } .btn-default:active { - background-color: #f0f0f0; - background-image: -webkit-radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); - background-image: -o-radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); - background-image: radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #f0f0f0; + background-image: -webkit-radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); + background-image: -o-radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); + background-image: radial-gradient(circle, #f0f0f0 10%, #ffffff 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn-primary { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-primary:hover, .btn-primary:active:hover, .btn-primary:focus { - background-color: #0d87e9; + background-color: #0d87e9; } .btn-primary:active { - background-color: #0d87e9; - background-image: -webkit-radial-gradient(circle, #0d87e9 10%, #2196f3 11%); - background-image: -o-radial-gradient(circle, #0d87e9 10%, #2196f3 11%); - background-image: radial-gradient(circle, #0d87e9 10%, #2196f3 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #0d87e9; + background-image: -webkit-radial-gradient(circle, #0d87e9 10%, #2196f3 11%); + background-image: -o-radial-gradient(circle, #0d87e9 10%, #2196f3 11%); + background-image: radial-gradient(circle, #0d87e9 10%, #2196f3 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn-success { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-success:hover, .btn-success:active:hover, .btn-success:focus { - background-color: #439a46; + background-color: #439a46; } .btn-success:active { - background-color: #439a46; - background-image: -webkit-radial-gradient(circle, #439a46 10%, #4caf50 11%); - background-image: -o-radial-gradient(circle, #439a46 10%, #4caf50 11%); - background-image: radial-gradient(circle, #439a46 10%, #4caf50 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #439a46; + background-image: -webkit-radial-gradient(circle, #439a46 10%, #4caf50 11%); + background-image: -o-radial-gradient(circle, #439a46 10%, #4caf50 11%); + background-image: radial-gradient(circle, #439a46 10%, #4caf50 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn-info { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-info:hover, .btn-info:active:hover, .btn-info:focus { - background-color: #862197; + background-color: #862197; } .btn-info:active { - background-color: #862197; - background-image: -webkit-radial-gradient(circle, #862197 10%, #9c27b0 11%); - background-image: -o-radial-gradient(circle, #862197 10%, #9c27b0 11%); - background-image: radial-gradient(circle, #862197 10%, #9c27b0 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #862197; + background-image: -webkit-radial-gradient(circle, #862197 10%, #9c27b0 11%); + background-image: -o-radial-gradient(circle, #862197 10%, #9c27b0 11%); + background-image: radial-gradient(circle, #862197 10%, #9c27b0 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn-warning { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-warning:hover, .btn-warning:active:hover, .btn-warning:focus { - background-color: #e08600; + background-color: #e08600; } .btn-warning:active { - background-color: #e08600; - background-image: -webkit-radial-gradient(circle, #e08600 10%, #ff9800 11%); - background-image: -o-radial-gradient(circle, #e08600 10%, #ff9800 11%); - background-image: radial-gradient(circle, #e08600 10%, #ff9800 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #e08600; + background-image: -webkit-radial-gradient(circle, #e08600 10%, #ff9800 11%); + background-image: -o-radial-gradient(circle, #e08600 10%, #ff9800 11%); + background-image: radial-gradient(circle, #e08600 10%, #ff9800 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn-danger { - -webkit-background-size: 200% 200%; - background-size: 200%; - background-position: 50%; + -webkit-background-size: 200% 200%; + background-size: 200%; + background-position: 50%; } .btn-danger:hover, .btn-danger:active:hover, .btn-danger:focus { - background-color: #cb171e; + background-color: #cb171e; } .btn-danger:active { - background-color: #cb171e; - background-image: -webkit-radial-gradient(circle, #cb171e 10%, #e51c23 11%); - background-image: -o-radial-gradient(circle, #cb171e 10%, #e51c23 11%); - background-image: radial-gradient(circle, #cb171e 10%, #e51c23 11%); - background-repeat: no-repeat; - -webkit-background-size: 1000% 1000%; - background-size: 1000%; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); - box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + background-color: #cb171e; + background-image: -webkit-radial-gradient(circle, #cb171e 10%, #e51c23 11%); + background-image: -o-radial-gradient(circle, #cb171e 10%, #e51c23 11%); + background-image: radial-gradient(circle, #cb171e 10%, #e51c23 11%); + background-repeat: no-repeat; + -webkit-background-size: 1000% 1000%; + background-size: 1000%; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.3); } .btn { - text-transform: uppercase; - border-right: none; - border-bottom: none; - -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); - box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; + text-transform: uppercase; + border-right: none; + border-bottom: none; + -webkit-box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); + box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3); + -webkit-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; } .btn-link { - -webkit-box-shadow: none; - box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } .btn-link:hover, .btn-link:focus { - color: #2196f3; - text-decoration: none; + color: #2196f3; + text-decoration: none; } .btn-default.disabled { - border: 1px solid #eeeeee; + border: 1px solid #eeeeee; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { - margin-left: 0; + margin-left: 0; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { - margin-top: 0; + margin-top: 0; } body { - -webkit-font-smoothing: antialiased; - letter-spacing: .1px; - text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + letter-spacing: .1px; + text-rendering: optimizeLegibility; } p { - margin: 0 0 1em; + margin: 0 0 1em; } input, button { - -webkit-font-smoothing: antialiased; - letter-spacing: .1px; - text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + letter-spacing: .1px; + text-rendering: optimizeLegibility; } a { - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; + -webkit-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; } label { - font-weight: normal; + font-weight: normal; } textarea, textarea.form-control, @@ -6802,13 +6802,13 @@ input[type=number], [type=email].form-control, [type=tel].form-control, [contenteditable].form-control { - padding: 0; - border: none; - border-radius: 0; - -webkit-appearance: none; - -webkit-box-shadow: inset 0 -1px 0 #dddddd; - box-shadow: inset 0 -1px 0 #dddddd; - font-size: 16px; + padding: 0; + border: none; + border-radius: 0; + -webkit-appearance: none; + -webkit-box-shadow: inset 0 -1px 0 #dddddd; + box-shadow: inset 0 -1px 0 #dddddd; + font-size: 16px; } textarea:focus, textarea.form-control:focus, @@ -6822,8 +6822,8 @@ input[type=number]:focus, [type=email].form-control:focus, [type=tel].form-control:focus, [contenteditable].form-control:focus { - -webkit-box-shadow: inset 0 -2px 0 #2196f3; - box-shadow: inset 0 -2px 0 #2196f3; + -webkit-box-shadow: inset 0 -2px 0 #2196f3; + box-shadow: inset 0 -2px 0 #2196f3; } textarea[disabled], textarea.form-control[disabled], @@ -6849,9 +6849,9 @@ input[type=number][readonly], [type=email].form-control[readonly], [type=tel].form-control[readonly], [contenteditable].form-control[readonly] { - -webkit-box-shadow: none; - box-shadow: none; - border-bottom: 1px dotted #ddd; + -webkit-box-shadow: none; + box-shadow: none; + border-bottom: 1px dotted #ddd; } textarea.input-sm, textarea.form-control.input-sm, @@ -6865,7 +6865,7 @@ input[type=number].input-sm, [type=email].form-control.input-sm, [type=tel].form-control.input-sm, [contenteditable].form-control.input-sm { - font-size: 12px; + font-size: 12px; } textarea.input-lg, textarea.form-control.input-lg, @@ -6879,54 +6879,54 @@ input[type=number].input-lg, [type=email].form-control.input-lg, [type=tel].form-control.input-lg, [contenteditable].form-control.input-lg { - font-size: 17px; + font-size: 17px; } select, select.form-control { - border: 0; - border-radius: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; - padding-left: 0; - padding-right: 0\9; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); - -webkit-background-size: 13px 13px; - background-size: 13px; - background-repeat: no-repeat; - background-position: right center; - -webkit-box-shadow: inset 0 -1px 0 #dddddd; - box-shadow: inset 0 -1px 0 #dddddd; - font-size: 16px; - line-height: 1.5; + border: 0; + border-radius: 0; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding-left: 0; + padding-right: 0\9; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); + -webkit-background-size: 13px 13px; + background-size: 13px; + background-repeat: no-repeat; + background-position: right center; + -webkit-box-shadow: inset 0 -1px 0 #dddddd; + box-shadow: inset 0 -1px 0 #dddddd; + font-size: 16px; + line-height: 1.5; } select::-ms-expand, select.form-control::-ms-expand { - display: none; + display: none; } select.input-sm, select.form-control.input-sm { - font-size: 12px; + font-size: 12px; } select.input-lg, select.form-control.input-lg { - font-size: 17px; + font-size: 17px; } select:focus, select.form-control:focus { - -webkit-box-shadow: inset 0 -2px 0 #2196f3; - box-shadow: inset 0 -2px 0 #2196f3; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); + -webkit-box-shadow: inset 0 -2px 0 #2196f3; + box-shadow: inset 0 -2px 0 #2196f3; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); } select[multiple], select.form-control[multiple] { - background: none; + background: none; } .radio label, .radio-inline label, .checkbox label, .checkbox-inline label { - padding-left: 25px; + padding-left: 25px; } .radio input[type="radio"], .radio-inline input[type="radio"], @@ -6936,25 +6936,25 @@ select.form-control[multiple] { .radio-inline input[type="checkbox"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { - margin-left: -25px; + margin-left: -25px; } input[type="radio"], .radio input[type="radio"], .radio-inline input[type="radio"] { - position: relative; - margin-top: 5px; - margin-right: 4px; - vertical-align: -4px; - border: none; - background-color: transparent; - -webkit-appearance: none; - appearance: none; - cursor: pointer; + position: relative; + margin-top: 5px; + margin-right: 4px; + vertical-align: -4px; + border: none; + background-color: transparent; + -webkit-appearance: none; + appearance: none; + cursor: pointer; } input[type="radio"]:focus, .radio input[type="radio"]:focus, .radio-inline input[type="radio"]:focus { - outline: none; + outline: none; } input[type="radio"]:before, .radio input[type="radio"]:before, @@ -6962,50 +6962,50 @@ input[type="radio"]:before, input[type="radio"]:after, .radio input[type="radio"]:after, .radio-inline input[type="radio"]:after { - content: ""; - display: block; - width: 18px; - height: 18px; - margin-top: -3px; - border-radius: 50%; - -webkit-transition: 240ms; - -o-transition: 240ms; - transition: 240ms; + content: ""; + display: block; + width: 18px; + height: 18px; + margin-top: -3px; + border-radius: 50%; + -webkit-transition: 240ms; + -o-transition: 240ms; + transition: 240ms; } input[type="radio"]:before, .radio input[type="radio"]:before, .radio-inline input[type="radio"]:before { - position: absolute; - left: 0; - top: 0; - background-color: #2196f3; - -webkit-transform: scale(0); - -ms-transform: scale(0); - -o-transform: scale(0); - transform: scale(0); + position: absolute; + left: 0; + top: 0; + background-color: #2196f3; + -webkit-transform: scale(0); + -ms-transform: scale(0); + -o-transform: scale(0); + transform: scale(0); } input[type="radio"]:after, .radio input[type="radio"]:after, .radio-inline input[type="radio"]:after { - border: 2px solid #666666; + border: 2px solid #666666; } input[type="radio"]:checked:before, .radio input[type="radio"]:checked:before, .radio-inline input[type="radio"]:checked:before { - -webkit-transform: scale(0.5); - -ms-transform: scale(0.5); - -o-transform: scale(0.5); - transform: scale(0.5); + -webkit-transform: scale(0.5); + -ms-transform: scale(0.5); + -o-transform: scale(0.5); + transform: scale(0.5); } input[type="radio"]:disabled:checked:before, .radio input[type="radio"]:disabled:checked:before, .radio-inline input[type="radio"]:disabled:checked:before { - background-color: #bbbbbb; + background-color: #bbbbbb; } input[type="radio"]:checked:after, .radio input[type="radio"]:checked:after, .radio-inline input[type="radio"]:checked:after { - border-color: #2196f3; + border-color: #2196f3; } input[type="radio"]:disabled:after, .radio input[type="radio"]:disabled:after, @@ -7013,244 +7013,244 @@ input[type="radio"]:disabled:after, input[type="radio"]:disabled:checked:after, .radio input[type="radio"]:disabled:checked:after, .radio-inline input[type="radio"]:disabled:checked:after { - border-color: #bbbbbb; + border-color: #bbbbbb; } input[type="checkbox"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { - position: relative; - vertical-align: -4px; - border: none; - -webkit-appearance: none; - appearance: none; - cursor: pointer; + position: relative; + vertical-align: -4px; + border: none; + -webkit-appearance: none; + appearance: none; + cursor: pointer; } input[type="checkbox"]:focus, .checkbox input[type="checkbox"]:focus, .checkbox-inline input[type="checkbox"]:focus { - outline: none; + outline: none; } input[type="checkbox"]:after, .checkbox input[type="checkbox"]:after, .checkbox-inline input[type="checkbox"]:after { - content: ""; - display: block; - width: 18px; - height: 18px; - margin-top: -2px; - margin-right: 5px; - border: 2px solid #666666; - border-radius: 2px; - -webkit-transition: 240ms; - -o-transition: 240ms; - transition: 240ms; + content: ""; + display: block; + width: 18px; + height: 18px; + margin-top: -2px; + margin-right: 5px; + border: 2px solid #666666; + border-radius: 2px; + -webkit-transition: 240ms; + -o-transition: 240ms; + transition: 240ms; } input[type="checkbox"]:checked:before, .checkbox input[type="checkbox"]:checked:before, .checkbox-inline input[type="checkbox"]:checked:before { - content: ""; - position: absolute; - top: 0; - left: 6px; - display: table; - width: 6px; - height: 12px; - border: 2px solid #fff; - border-top-width: 0; - border-left-width: 0; - -webkit-transform: rotate(45deg); - -ms-transform: rotate(45deg); - -o-transform: rotate(45deg); - transform: rotate(45deg); + content: ""; + position: absolute; + top: 0; + left: 6px; + display: table; + width: 6px; + height: 12px; + border: 2px solid #fff; + border-top-width: 0; + border-left-width: 0; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); } input[type="checkbox"]:checked:after, .checkbox input[type="checkbox"]:checked:after, .checkbox-inline input[type="checkbox"]:checked:after { - background-color: #2196f3; - border-color: #2196f3; + background-color: #2196f3; + border-color: #2196f3; } input[type="checkbox"]:disabled:after, .checkbox input[type="checkbox"]:disabled:after, .checkbox-inline input[type="checkbox"]:disabled:after { - border-color: #bbbbbb; + border-color: #bbbbbb; } input[type="checkbox"]:disabled:checked:after, .checkbox input[type="checkbox"]:disabled:checked:after, .checkbox-inline input[type="checkbox"]:disabled:checked:after { - background-color: #bbbbbb; - border-color: transparent; + background-color: #bbbbbb; + border-color: transparent; } .has-warning input:not([type=checkbox]), .has-warning .form-control, .has-warning input:not([type=checkbox]):focus, .has-warning .form-control:focus { - -webkit-box-shadow: inset 0 -2px 0 #ff9800; - box-shadow: inset 0 -2px 0 #ff9800; + -webkit-box-shadow: inset 0 -2px 0 #ff9800; + box-shadow: inset 0 -2px 0 #ff9800; } .has-error input:not([type=checkbox]), .has-error .form-control, .has-error input:not([type=checkbox]):focus, .has-error .form-control:focus { - -webkit-box-shadow: inset 0 -2px 0 #e51c23; - box-shadow: inset 0 -2px 0 #e51c23; + -webkit-box-shadow: inset 0 -2px 0 #e51c23; + box-shadow: inset 0 -2px 0 #e51c23; } .has-success input:not([type=checkbox]), .has-success .form-control, .has-success input:not([type=checkbox]):focus, .has-success .form-control:focus { - -webkit-box-shadow: inset 0 -2px 0 #4caf50; - box-shadow: inset 0 -2px 0 #4caf50; + -webkit-box-shadow: inset 0 -2px 0 #4caf50; + box-shadow: inset 0 -2px 0 #4caf50; } .nav-tabs > li > a, .nav-tabs > li > a:focus { - margin-right: 0; - background-color: transparent; - border: none; - color: #666666; - -webkit-box-shadow: inset 0 -1px 0 #dddddd; - box-shadow: inset 0 -1px 0 #dddddd; - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; + margin-right: 0; + background-color: transparent; + border: none; + color: #666666; + -webkit-box-shadow: inset 0 -1px 0 #dddddd; + box-shadow: inset 0 -1px 0 #dddddd; + -webkit-transition: all 0.2s; + -o-transition: all 0.2s; + transition: all 0.2s; } .nav-tabs > li > a:hover, .nav-tabs > li > a:focus:hover { - background-color: transparent; - -webkit-box-shadow: inset 0 -2px 0 #2196f3; - box-shadow: inset 0 -2px 0 #2196f3; - color: #2196f3; + background-color: transparent; + -webkit-box-shadow: inset 0 -2px 0 #2196f3; + box-shadow: inset 0 -2px 0 #2196f3; + color: #2196f3; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:focus { - border: none; - -webkit-box-shadow: inset 0 -2px 0 #2196f3; - box-shadow: inset 0 -2px 0 #2196f3; - color: #2196f3; + border: none; + -webkit-box-shadow: inset 0 -2px 0 #2196f3; + box-shadow: inset 0 -2px 0 #2196f3; + color: #2196f3; } .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus:hover { - border: none; - color: #2196f3; + border: none; + color: #2196f3; } .nav-tabs > li.disabled > a { - -webkit-box-shadow: inset 0 -1px 0 #dddddd; - box-shadow: inset 0 -1px 0 #dddddd; + -webkit-box-shadow: inset 0 -1px 0 #dddddd; + box-shadow: inset 0 -1px 0 #dddddd; } .nav-tabs.nav-justified > li > a, .nav-tabs.nav-justified > li > a:hover, .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover { - border: none; + border: none; } .nav-tabs .dropdown-menu { - margin-top: 0; + margin-top: 0; } .dropdown-menu { - border: none; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + border: none; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .alert { - border: none; - color: #fff; + border: none; + color: #fff; } .alert-success { - background-color: #4caf50; + background-color: #4caf50; } .alert-info { - background-color: #9c27b0; + background-color: #9c27b0; } .alert-warning { - background-color: #ff9800; + background-color: #ff9800; } .alert-danger { - background-color: #e51c23; + background-color: #e51c23; } .alert a:not(.close), .alert .alert-link { - color: #fff; - font-weight: bold; + color: #fff; + font-weight: bold; } .alert .close { - color: #fff; + color: #fff; } .badge { - padding: 3px 6px 5px; + padding: 3px 6px 5px; } .progress { - position: relative; - z-index: 1; - height: 6px; - border-radius: 0; - -webkit-box-shadow: none; - box-shadow: none; + position: relative; + z-index: 1; + height: 6px; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; } .progress-bar { - -webkit-box-shadow: none; - box-shadow: none; + -webkit-box-shadow: none; + box-shadow: none; } .progress-bar:last-child { - border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; } .progress-bar:last-child:before { - display: block; - content: ""; - position: absolute; - width: 100%; - height: 100%; - left: 0; - right: 0; - z-index: -1; - background-color: #cae6fc; + display: block; + content: ""; + position: absolute; + width: 100%; + height: 100%; + left: 0; + right: 0; + z-index: -1; + background-color: #cae6fc; } .progress-bar-success:last-child.progress-bar:before { - background-color: #c7e7c8; + background-color: #c7e7c8; } .progress-bar-info:last-child.progress-bar:before { - background-color: #edc9f3; + background-color: #edc9f3; } .progress-bar-warning:last-child.progress-bar:before { - background-color: #ffe0b3; + background-color: #ffe0b3; } .progress-bar-danger:last-child.progress-bar:before { - background-color: #f28e92; + background-color: #f28e92; } .close { - font-size: 34px; - font-weight: 300; - line-height: 24px; - opacity: 0.6; + font-size: 34px; + font-weight: 300; + line-height: 24px; + opacity: 0.6; } .close:hover { - opacity: 1; + opacity: 1; } .list-group-item { - padding: 15px; + padding: 15px; } .list-group-item-text { - color: #bbbbbb; + color: #bbbbbb; } .well { - border-radius: 0; - -webkit-box-shadow: none; - box-shadow: none; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; } .panel { - border: none; - border-radius: 2px; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + border: none; + border-radius: 2px; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .panel-heading { - border-bottom: none; + border-bottom: none; } .panel-footer { - border-top: none; + border-top: none; } .popover { - border: none; - -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + border: none; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .carousel-caption h1, .carousel-caption h2, @@ -7258,5 +7258,5 @@ input[type="checkbox"]:disabled:checked:after, .carousel-caption h4, .carousel-caption h5, .carousel-caption h6 { - color: inherit; + color: inherit; } diff --git a/app/static/css/bootstrap.min.css b/app/static/css/bootstrap.min.css index 3cb4548..bda9f39 100644 --- a/app/static/css/bootstrap.min.css +++ b/app/static/css/bootstrap.min.css @@ -1,6 +1,6 @@ - * bootswatch v3.3.4+1 - * Homepage: http://bootswatch.com - * Copyright 2012-2015 Thomas Park - * Licensed under MIT - * Based on Bootstrap +/* bootswatch v3.3.4+1 +* Homepage: http://bootswatch.com +* Copyright 2012-2015 Thomas Park +* Licensed under MIT +* Based on Bootstrap *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:1.846;color:#666666;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#2196f3;text-decoration:none}a:hover,a:focus{color:#0a6ebd;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:3px}.img-thumbnail{padding:4px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:23px;margin-bottom:23px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:400;line-height:1.1;color:#444444}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#bbbbbb}h1,.h1,h2,.h2,h3,.h3{margin-top:23px;margin-bottom:11.5px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:11.5px;margin-bottom:11.5px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:56px}h2,.h2{font-size:45px}h3,.h3{font-size:34px}h4,.h4{font-size:24px}h5,.h5{font-size:20px}h6,.h6{font-size:14px}p{margin:0 0 11.5px}.lead{margin-bottom:23px;font-size:14px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:19.5px}}small,.small{font-size:92%}mark,.mark{background-color:#ffe0b2;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#bbbbbb}.text-primary{color:#2196f3}a.text-primary:hover{color:#0c7cd5}.text-success{color:#4caf50}a.text-success:hover{color:#3d8b40}.text-info{color:#9c27b0}a.text-info:hover{color:#771e86}.text-warning{color:#ff9800}a.text-warning:hover{color:#cc7a00}.text-danger{color:#e51c23}a.text-danger:hover{color:#b9151b}.bg-primary{color:#fff;background-color:#2196f3}a.bg-primary:hover{background-color:#0c7cd5}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#e1bee7}a.bg-info:hover{background-color:#d099d9}.bg-warning{background-color:#ffe0b2}a.bg-warning:hover{background-color:#ffcb7f}.bg-danger{background-color:#f9bdbb}a.bg-danger:hover{background-color:#f5908c}.page-header{padding-bottom:10.5px;margin:46px 0 23px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:11.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:23px}dt,dd{line-height:1.846}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #bbbbbb}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:11.5px 23px;margin:0 0 23px;font-size:16.25px;border-left:5px solid #eeeeee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.846;color:#bbbbbb}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:23px;font-style:normal;line-height:1.846}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:3px}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:11px;margin:0 0 11.5px;font-size:12px;line-height:1.846;word-break:break-all;word-wrap:break-word;color:#212121;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:3px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#bbbbbb;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:23px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.846;vertical-align:top;border-top:1px solid #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #dddddd}.table .table{background-color:#ffffff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#e1bee7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#d8abe0}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#ffe0b2}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#ffd699}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f9bdbb}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#f7a6a4}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:17.25px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:23px;font-size:19.5px;line-height:inherit;color:#212121;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:13px;line-height:1.846;color:#666666}.form-control{display:block;width:100%;height:37px;padding:6px 16px;font-size:13px;line-height:1.846;color:#666666;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#bbbbbb;opacity:1}.form-control:-ms-input-placeholder{color:#bbbbbb}.form-control::-webkit-input-placeholder{color:#bbbbbb}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:transparent;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:37px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:45px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:23px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:36px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.form-group-sm .form-control{height:30px;line-height:30px}textarea.form-group-sm .form-control,select[multiple].form-group-sm .form-control{height:auto}.form-group-sm .form-control-static{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;min-height:35px}.input-lg{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}select.input-lg{height:45px;line-height:45px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}select.form-group-lg .form-control{height:45px;line-height:45px}textarea.form-group-lg .form-control,select[multiple].form-group-lg .form-control{height:auto}.form-group-lg .form-control-static{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;min-height:40px}.has-feedback{position:relative}.has-feedback .form-control{padding-right:46.25px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:37px;height:37px;line-height:37px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:45px;height:45px;line-height:45px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#4caf50}.has-success .form-control{border-color:#4caf50;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#3d8b40;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94}.has-success .input-group-addon{color:#4caf50;border-color:#4caf50;background-color:#dff0d8}.has-success .form-control-feedback{color:#4caf50}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#ff9800}.has-warning .form-control{border-color:#ff9800;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#cc7a00;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166}.has-warning .input-group-addon{color:#ff9800;border-color:#ff9800;background-color:#ffe0b2}.has-warning .form-control-feedback{color:#ff9800}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#e51c23}.has-error .form-control{border-color:#e51c23;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#b9151b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c}.has-error .input-group-addon{color:#e51c23;border-color:#e51c23;background-color:#f9bdbb}.has-error .form-control-feedback{color:#e51c23}.has-feedback label~.form-control-feedback{top:28px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#a6a6a6}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:30px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.333333px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 16px;font-size:13px;line-height:1.846;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#666666;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#666666;background-color:#ffffff;border-color:#eeeeee}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#666666;background-color:#e6e6e6;border-color:#cfcfcf}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#ffffff;border-color:#eeeeee}.btn-default .badge{color:#ffffff;background-color:#666666}.btn-primary{color:#ffffff;background-color:#2196f3;border-color:transparent}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#0c7cd5;border-color:rgba(0,0,0,0)}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#2196f3;border-color:transparent}.btn-primary .badge{color:#2196f3;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#4caf50;border-color:transparent}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#3d8b40;border-color:rgba(0,0,0,0)}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#4caf50;border-color:transparent}.btn-success .badge{color:#4caf50;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#9c27b0;border-color:transparent}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#771e86;border-color:rgba(0,0,0,0)}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#9c27b0;border-color:transparent}.btn-info .badge{color:#9c27b0;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#ff9800;border-color:transparent}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#cc7a00;border-color:rgba(0,0,0,0)}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#ff9800;border-color:transparent}.btn-warning .badge{color:#ff9800;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#e51c23;border-color:transparent}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#b9151b;border-color:rgba(0,0,0,0)}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#e51c23;border-color:transparent}.btn-danger .badge{color:#e51c23;background-color:#ffffff}.btn-link{color:#2196f3;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#0a6ebd;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#bbbbbb;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.846;color:#666666;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#141414;background-color:#eeeeee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#2196f3}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#bbbbbb}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.846;color:#bbbbbb;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:3px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:17px;line-height:1.3333333;border-radius:3px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 16px;font-size:13px;font-weight:normal;line-height:1;color:#666666;text-align:center;background-color:transparent;border:1px solid transparent;border-radius:3px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:17px;border-radius:3px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee}.nav>li.disabled>a{color:#bbbbbb}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#bbbbbb;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#2196f3}.nav .nav-divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid transparent}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.846;border:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee transparent}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#666666;background-color:transparent;border:1px solid transparent;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:3px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#ffffff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:3px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#2196f3}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:3px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:64px;margin-bottom:23px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:3px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:20.5px 15px;font-size:17px;line-height:23px;height:64px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:15px;margin-bottom:15px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:10.25px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:23px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:23px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:20.5px;padding-bottom:20.5px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:13.5px;margin-bottom:13.5px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:3px;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:13.5px;margin-bottom:13.5px}.navbar-btn.btn-sm{margin-top:17px;margin-bottom:17px}.navbar-btn.btn-xs{margin-top:21px;margin-bottom:21px}.navbar-text{margin-top:20.5px;margin-bottom:20.5px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#ffffff;border-color:transparent}.navbar-default .navbar-brand{color:#666666}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#212121;background-color:transparent}.navbar-default .navbar-text{color:#bbbbbb}.navbar-default .navbar-nav>li>a{color:#666666}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#212121;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#212121;background-color:#eeeeee}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#eeeeee;color:#212121}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#666666}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#212121;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#212121;background-color:#eeeeee}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#666666}.navbar-default .navbar-link:hover{color:#212121}.navbar-default .btn-link{color:#666666}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#212121}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc}.navbar-inverse{background-color:#2196f3;border-color:transparent}.navbar-inverse .navbar-brand{color:#b2dbfb}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#bbbbbb}.navbar-inverse .navbar-nav>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#0c7cd5}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#0c84e4}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#0c7cd5;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#0c7cd5}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444444;background-color:transparent}}.navbar-inverse .navbar-link{color:#b2dbfb}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#b2dbfb}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444444}.breadcrumb{padding:8px 15px;margin-bottom:23px;list-style:none;background-color:#f5f5f5;border-radius:3px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#bbbbbb}.pagination{display:inline-block;padding-left:0;margin:23px 0;border-radius:3px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 16px;line-height:1.846;text-decoration:none;color:#2196f3;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#0a6ebd;background-color:#eeeeee;border-color:#dddddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#ffffff;background-color:#2196f3;border-color:#2196f3;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#bbbbbb;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:17px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:23px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#bbbbbb;background-color:#ffffff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#bbbbbb}.label-default[href]:hover,.label-default[href]:focus{background-color:#a2a2a2}.label-primary{background-color:#2196f3}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#0c7cd5}.label-success{background-color:#4caf50}.label-success[href]:hover,.label-success[href]:focus{background-color:#3d8b40}.label-info{background-color:#9c27b0}.label-info[href]:hover,.label-info[href]:focus{background-color:#771e86}.label-warning{background-color:#ff9800}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#cc7a00}.label-danger{background-color:#e51c23}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#b9151b}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:normal;color:#ffffff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#bbbbbb;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#2196f3;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#f9f9f9}.jumbotron h1,.jumbotron .h1{color:#444444}.jumbotron p{margin-bottom:15px;font-size:20px;font-weight:200}.jumbotron>hr{border-top-color:#e0e0e0}.container .jumbotron,.container-fluid .jumbotron{border-radius:3px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:58.5px}}.thumbnail{display:block;padding:4px;margin-bottom:23px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#2196f3}.thumbnail .caption{padding:9px;color:#666666}.alert{padding:15px;margin-bottom:23px;border:1px solid transparent;border-radius:3px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#4caf50}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#3d8b40}.alert-info{background-color:#e1bee7;border-color:#cba4dd;color:#9c27b0}.alert-info hr{border-top-color:#c191d6}.alert-info .alert-link{color:#771e86}.alert-warning{background-color:#ffe0b2;border-color:#ffc599;color:#ff9800}.alert-warning hr{border-top-color:#ffb67f}.alert-warning .alert-link{color:#cc7a00}.alert-danger{background-color:#f9bdbb;border-color:#f7a4af;color:#e51c23}.alert-danger hr{border-top-color:#f58c9a}.alert-danger .alert-link{color:#b9151b}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:23px;margin-bottom:23px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:23px;color:#ffffff;text-align:center;background-color:#2196f3;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#4caf50}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#9c27b0}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#ff9800}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#e51c23}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}a.list-group-item{color:#555555}a.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#bbbbbb;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#bbbbbb}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#2196f3;border-color:#2196f3}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e3f2fd}.list-group-item-success{color:#4caf50;background-color:#dff0d8}a.list-group-item-success{color:#4caf50}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#4caf50;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#4caf50;border-color:#4caf50}.list-group-item-info{color:#9c27b0;background-color:#e1bee7}a.list-group-item-info{color:#9c27b0}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#9c27b0;background-color:#d8abe0}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#9c27b0;border-color:#9c27b0}.list-group-item-warning{color:#ff9800;background-color:#ffe0b2}a.list-group-item-warning{color:#ff9800}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#ff9800;background-color:#ffd699}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#ff9800;border-color:#ff9800}.list-group-item-danger{color:#e51c23;background-color:#f9bdbb}a.list-group-item-danger{color:#e51c23}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#e51c23;background-color:#f7a6a4}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#e51c23;border-color:#e51c23}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:23px;background-color:#ffffff;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:2px;border-top-left-radius:2px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:15px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:2px;border-top-left-radius:2px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:2px;border-top-left-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:2px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:2px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #dddddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:23px}.panel-group .panel{margin-bottom:0;border-radius:3px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#212121;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#212121}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#2196f3}.panel-primary>.panel-heading{color:#ffffff;background-color:#2196f3;border-color:#2196f3}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#2196f3}.panel-primary>.panel-heading .badge{color:#2196f3;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#2196f3}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#ffffff;background-color:#4caf50;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#4caf50;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#cba4dd}.panel-info>.panel-heading{color:#ffffff;background-color:#9c27b0;border-color:#cba4dd}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#cba4dd}.panel-info>.panel-heading .badge{color:#9c27b0;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#cba4dd}.panel-warning{border-color:#ffc599}.panel-warning>.panel-heading{color:#ffffff;background-color:#ff9800;border-color:#ffc599}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ffc599}.panel-warning>.panel-heading .badge{color:#ff9800;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ffc599}.panel-danger{border-color:#f7a4af}.panel-danger>.panel-heading{color:#ffffff;background-color:#e51c23;border-color:#f7a4af}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#f7a4af}.panel-danger>.panel-heading .badge{color:#e51c23;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#f7a4af}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f9f9f9;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:3px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:19.5px;font-weight:normal;line-height:1;color:#000000;text-shadow:none;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#ffffff;border:1px solid #999999;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid transparent;min-height:16.846px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.846}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:normal;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#727272;border-radius:3px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#727272}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#727272}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1.846;text-align:left;background-color:#ffffff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:2px 2px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:rgba(0,0,0,0);border-top-color:rgba(0,0,0,0.075);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:rgba(0,0,0,0);border-right-color:rgba(0,0,0,0.075)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,0);border-bottom-color:rgba(0,0,0,0.075);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:rgba(0,0,0,0);border-left-color:rgba(0,0,0,0.075)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.navbar{border:none;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.3);box-shadow:0 1px 2px rgba(0,0,0,0.3)}.navbar-brand{font-size:24px}.navbar-inverse .form-control{color:#fff}.navbar-inverse .form-control::-moz-placeholder{color:#b2dbfb;opacity:1}.navbar-inverse .form-control:-ms-input-placeholder{color:#b2dbfb}.navbar-inverse .form-control::-webkit-input-placeholder{color:#b2dbfb}.navbar-inverse .form-control[type=text]{-webkit-box-shadow:inset 0 -1px 0 #b2dbfb;box-shadow:inset 0 -1px 0 #b2dbfb}.navbar-inverse .form-control[type=text]:focus{-webkit-box-shadow:inset 0 -2px 0 #fff;box-shadow:inset 0 -2px 0 #fff}.navbar-nav>li>.dropdown-menu{margin-top:2px}.btn-default{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-default:hover,.btn-default:active:hover,.btn-default:focus{background-color:#f0f0f0}.btn-default:active{background-color:#f0f0f0;background-image:-webkit-radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-image:-o-radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-image:radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-primary{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-primary:hover,.btn-primary:active:hover,.btn-primary:focus{background-color:#0d87e9}.btn-primary:active{background-color:#0d87e9;background-image:-webkit-radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-image:-o-radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-image:radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-success{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-success:hover,.btn-success:active:hover,.btn-success:focus{background-color:#439a46}.btn-success:active{background-color:#439a46;background-image:-webkit-radial-gradient(circle, #439a46 10%, #4caf50 11%);background-image:-o-radial-gradient(circle, #439a46 10%, #4caf50 11%);background-image:radial-gradient(circle, #439a46 10%, #4caf50 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-info{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-info:hover,.btn-info:active:hover,.btn-info:focus{background-color:#862197}.btn-info:active{background-color:#862197;background-image:-webkit-radial-gradient(circle, #862197 10%, #9c27b0 11%);background-image:-o-radial-gradient(circle, #862197 10%, #9c27b0 11%);background-image:radial-gradient(circle, #862197 10%, #9c27b0 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-warning{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-warning:hover,.btn-warning:active:hover,.btn-warning:focus{background-color:#e08600}.btn-warning:active{background-color:#e08600;background-image:-webkit-radial-gradient(circle, #e08600 10%, #ff9800 11%);background-image:-o-radial-gradient(circle, #e08600 10%, #ff9800 11%);background-image:radial-gradient(circle, #e08600 10%, #ff9800 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-danger{-webkit-background-size:200% 200%;background-size:200%;background-position:50%}.btn-danger:hover,.btn-danger:active:hover,.btn-danger:focus{background-color:#cb171e}.btn-danger:active{background-color:#cb171e;background-image:-webkit-radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-image:-o-radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-image:radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn{text-transform:uppercase;border-right:none;border-bottom:none;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,0.3);box-shadow:1px 1px 2px rgba(0,0,0,0.3);-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn-link:hover,.btn-link:focus{color:#2196f3;text-decoration:none}.btn-default.disabled{border:1px solid #eeeeee}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:0}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:0}body{-webkit-font-smoothing:antialiased;letter-spacing:.1px;text-rendering:optimizeLegibility}p{margin:0 0 1em}input,button{-webkit-font-smoothing:antialiased;letter-spacing:.1px;text-rendering:optimizeLegibility}a{-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}label{font-weight:normal}textarea,textarea.form-control,input.form-control,input[type=text],input[type=password],input[type=email],input[type=number],[type=text].form-control,[type=password].form-control,[type=email].form-control,[type=tel].form-control,[contenteditable].form-control{padding:0;border:none;border-radius:0;-webkit-appearance:none;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px}textarea:focus,textarea.form-control:focus,input.form-control:focus,input[type=text]:focus,input[type=password]:focus,input[type=email]:focus,input[type=number]:focus,[type=text].form-control:focus,[type=password].form-control:focus,[type=email].form-control:focus,[type=tel].form-control:focus,[contenteditable].form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3}textarea[disabled],textarea.form-control[disabled],input.form-control[disabled],input[type=text][disabled],input[type=password][disabled],input[type=email][disabled],input[type=number][disabled],[type=text].form-control[disabled],[type=password].form-control[disabled],[type=email].form-control[disabled],[type=tel].form-control[disabled],[contenteditable].form-control[disabled],textarea[readonly],textarea.form-control[readonly],input.form-control[readonly],input[type=text][readonly],input[type=password][readonly],input[type=email][readonly],input[type=number][readonly],[type=text].form-control[readonly],[type=password].form-control[readonly],[type=email].form-control[readonly],[type=tel].form-control[readonly],[contenteditable].form-control[readonly]{-webkit-box-shadow:none;box-shadow:none;border-bottom:1px dotted #ddd}textarea.input-sm,textarea.form-control.input-sm,input.form-control.input-sm,input[type=text].input-sm,input[type=password].input-sm,input[type=email].input-sm,input[type=number].input-sm,[type=text].form-control.input-sm,[type=password].form-control.input-sm,[type=email].form-control.input-sm,[type=tel].form-control.input-sm,[contenteditable].form-control.input-sm{font-size:12px}textarea.input-lg,textarea.form-control.input-lg,input.form-control.input-lg,input[type=text].input-lg,input[type=password].input-lg,input[type=email].input-lg,input[type=number].input-lg,[type=text].form-control.input-lg,[type=password].form-control.input-lg,[type=email].form-control.input-lg,[type=tel].form-control.input-lg,[contenteditable].form-control.input-lg{font-size:17px}select,select.form-control{border:0;border-radius:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;padding-left:0;padding-right:0\9;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=);-webkit-background-size:13px 13px;background-size:13px;background-repeat:no-repeat;background-position:right center;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px;line-height:1.5}select::-ms-expand,select.form-control::-ms-expand{display:none}select.input-sm,select.form-control.input-sm{font-size:12px}select.input-lg,select.form-control.input-lg{font-size:17px}select:focus,select.form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=)}select[multiple],select.form-control[multiple]{background:none}.radio label,.radio-inline label,.checkbox label,.checkbox-inline label{padding-left:25px}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="radio"],.checkbox-inline input[type="radio"],.radio input[type="checkbox"],.radio-inline input[type="checkbox"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{margin-left:-25px}input[type="radio"],.radio input[type="radio"],.radio-inline input[type="radio"]{position:relative;margin-top:5px;margin-right:4px;vertical-align:-4px;border:none;background-color:transparent;-webkit-appearance:none;appearance:none;cursor:pointer}input[type="radio"]:focus,.radio input[type="radio"]:focus,.radio-inline input[type="radio"]:focus{outline:none}input[type="radio"]:before,.radio input[type="radio"]:before,.radio-inline input[type="radio"]:before,input[type="radio"]:after,.radio input[type="radio"]:after,.radio-inline input[type="radio"]:after{content:"";display:block;width:18px;height:18px;margin-top:-3px;border-radius:50%;-webkit-transition:240ms;-o-transition:240ms;transition:240ms}input[type="radio"]:before,.radio input[type="radio"]:before,.radio-inline input[type="radio"]:before{position:absolute;left:0;top:0;background-color:#2196f3;-webkit-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0)}input[type="radio"]:after,.radio input[type="radio"]:after,.radio-inline input[type="radio"]:after{border:2px solid #666666}input[type="radio"]:checked:before,.radio input[type="radio"]:checked:before,.radio-inline input[type="radio"]:checked:before{-webkit-transform:scale(.5);-ms-transform:scale(.5);-o-transform:scale(.5);transform:scale(.5)}input[type="radio"]:disabled:checked:before,.radio input[type="radio"]:disabled:checked:before,.radio-inline input[type="radio"]:disabled:checked:before{background-color:#bbbbbb}input[type="radio"]:checked:after,.radio input[type="radio"]:checked:after,.radio-inline input[type="radio"]:checked:after{border-color:#2196f3}input[type="radio"]:disabled:after,.radio input[type="radio"]:disabled:after,.radio-inline input[type="radio"]:disabled:after,input[type="radio"]:disabled:checked:after,.radio input[type="radio"]:disabled:checked:after,.radio-inline input[type="radio"]:disabled:checked:after{border-color:#bbbbbb}input[type="checkbox"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:relative;vertical-align:-4px;border:none;-webkit-appearance:none;appearance:none;cursor:pointer}input[type="checkbox"]:focus,.checkbox input[type="checkbox"]:focus,.checkbox-inline input[type="checkbox"]:focus{outline:none}input[type="checkbox"]:after,.checkbox input[type="checkbox"]:after,.checkbox-inline input[type="checkbox"]:after{content:"";display:block;width:18px;height:18px;margin-top:-2px;margin-right:5px;border:2px solid #666666;border-radius:2px;-webkit-transition:240ms;-o-transition:240ms;transition:240ms}input[type="checkbox"]:checked:before,.checkbox input[type="checkbox"]:checked:before,.checkbox-inline input[type="checkbox"]:checked:before{content:"";position:absolute;top:0;left:6px;display:table;width:6px;height:12px;border:2px solid #fff;border-top-width:0;border-left-width:0;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}input[type="checkbox"]:checked:after,.checkbox input[type="checkbox"]:checked:after,.checkbox-inline input[type="checkbox"]:checked:after{background-color:#2196f3;border-color:#2196f3}input[type="checkbox"]:disabled:after,.checkbox input[type="checkbox"]:disabled:after,.checkbox-inline input[type="checkbox"]:disabled:after{border-color:#bbbbbb}input[type="checkbox"]:disabled:checked:after,.checkbox input[type="checkbox"]:disabled:checked:after,.checkbox-inline input[type="checkbox"]:disabled:checked:after{background-color:#bbbbbb;border-color:transparent}.has-warning input:not([type=checkbox]),.has-warning .form-control,.has-warning input:not([type=checkbox]):focus,.has-warning .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #ff9800;box-shadow:inset 0 -2px 0 #ff9800}.has-error input:not([type=checkbox]),.has-error .form-control,.has-error input:not([type=checkbox]):focus,.has-error .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #e51c23;box-shadow:inset 0 -2px 0 #e51c23}.has-success input:not([type=checkbox]),.has-success .form-control,.has-success input:not([type=checkbox]):focus,.has-success .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #4caf50;box-shadow:inset 0 -2px 0 #4caf50}.nav-tabs>li>a,.nav-tabs>li>a:focus{margin-right:0;background-color:transparent;border:none;color:#666666;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.nav-tabs>li>a:hover,.nav-tabs>li>a:focus:hover{background-color:transparent;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus{border:none;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus:hover{border:none;color:#2196f3}.nav-tabs>li.disabled>a{-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd}.nav-tabs.nav-justified>li>a,.nav-tabs.nav-justified>li>a:hover,.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover{border:none}.nav-tabs .dropdown-menu{margin-top:0}.dropdown-menu{border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.alert{border:none;color:#fff}.alert-success{background-color:#4caf50}.alert-info{background-color:#9c27b0}.alert-warning{background-color:#ff9800}.alert-danger{background-color:#e51c23}.alert a:not(.close),.alert .alert-link{color:#fff;font-weight:bold}.alert .close{color:#fff}.badge{padding:3px 6px 5px}.progress{position:relative;z-index:1;height:6px;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress-bar:last-child{border-radius:0 3px 3px 0}.progress-bar:last-child:before{display:block;content:"";position:absolute;width:100%;height:100%;left:0;right:0;z-index:-1;background-color:#cae6fc}.progress-bar-success:last-child.progress-bar:before{background-color:#c7e7c8}.progress-bar-info:last-child.progress-bar:before{background-color:#edc9f3}.progress-bar-warning:last-child.progress-bar:before{background-color:#ffe0b3}.progress-bar-danger:last-child.progress-bar:before{background-color:#f28e92}.close{font-size:34px;font-weight:300;line-height:24px;opacity:0.6}.close:hover{opacity:1}.list-group-item{padding:15px}.list-group-item-text{color:#bbbbbb}.well{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.panel{border:none;border-radius:2px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.panel-heading{border-bottom:none}.panel-footer{border-top:none}.popover{border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.carousel-caption h1,.carousel-caption h2,.carousel-caption h3,.carousel-caption h4,.carousel-caption h5,.carousel-caption h6{color:inherit} diff --git a/app/static/css/darkmode.css b/app/static/css/darkmode.css index 7b5130b..41481be 100644 --- a/app/static/css/darkmode.css +++ b/app/static/css/darkmode.css @@ -1,16 +1,16 @@ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; + --dGray1:#8E8E93; + --dGray2:#636366; + --dGray3:#48484A; + --dGray4:#3A3A3C; + --dGray5:#2C2C2E; + --dGray6:#1C1C1E; + --dBlue:#0A84FF; } .table-hover tbody tr:hover{ - background-color: var(--dGray3); + background-color: var(--dGray3); } body{ background-color: var(--dGray5); @@ -20,8 +20,8 @@ a { color: var(--dBlue); } .btn-primary { - color: var(--dGray6); - background-color: var(--dBlue); + color: var(--dGray6); + background-color: var(--dBlue); } .navbar { @@ -59,23 +59,23 @@ h1, h2, h3, h4, h5, h6{ border-bottom: 2px solid var(--dGray2); } .navbar-toggle .icon-bar { - background-color: var(--dGray0); - opacity: 0.5; + background-color: var(--dGray0); + opacity: 0.5; } .select2-container--default .select2-selection--single{ - background-color: var(--dGray3); - color: var(--dGray0); + background-color: var(--dGray3); + color: var(--dGray0); } .select2-container--default .select2-selection--single .select2-selection__rendered{ - color: var(--dGray0); + color: var(--dGray0); } .select2-results__option{ - background-color: var(--dGray5); - color: var(--dGray0); + background-color: var(--dGray5); + color: var(--dGray0); } .select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: var(--dGray4); - color: var(--dGray0); + background-color: var(--dGray4); + color: var(--dGray0); } .bootstrap-datetimepicker-widget table thead tr:first-child th:hover, .bootstrap-datetimepicker-widget table td.day:hover, @@ -83,28 +83,28 @@ h1, h2, h3, h4, h5, h6{ .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td span:hover, .bootstrap-datetimepicker-widget table td.second:hover { - background: var(--dGray4); + background: var(--dGray4); } .select2-container--default .select2-results__option[aria-selected=true]{ - background-color: var(--dBlue); - color: var(--dGray0); + background-color: var(--dBlue); + color: var(--dGray0); } .select2-search{ - background-color: var(--dGray2); + background-color: var(--dGray2); } .select2-search input{ - background-color: var(--dGray0); + background-color: var(--dGray0); } .dropdown-menu{ - background-color: var(--dGray5); + background-color: var(--dGray5); } .form-control{ - color: var(--dGray0); + color: var(--dGray0); } .form-control::placeholder{ - color: var(--dGray2); + color: var(--dGray2); } .enter_darkmode>a { - text-align: center; -} \ No newline at end of file + text-align: center; +} diff --git a/app/static/css/leaflet.css b/app/static/css/leaflet.css index a0932d5..70802f3 100644 --- a/app/static/css/leaflet.css +++ b/app/static/css/leaflet.css @@ -1,635 +1,635 @@ -/* required styles */ - -.leaflet-pane, -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow, -.leaflet-tile-container, -.leaflet-pane > svg, -.leaflet-pane > canvas, -.leaflet-zoom-box, -.leaflet-image-layer, -.leaflet-layer { - position: absolute; - left: 0; - top: 0; - } -.leaflet-container { - overflow: hidden; - } -.leaflet-tile, -.leaflet-marker-icon, -.leaflet-marker-shadow { - -webkit-user-select: none; - -moz-user-select: none; - user-select: none; - -webkit-user-drag: none; - } -/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ -.leaflet-safari .leaflet-tile { - image-rendering: -webkit-optimize-contrast; - } -/* hack that prevents hw layers "stretching" when loading new tiles */ -.leaflet-safari .leaflet-tile-container { - width: 1600px; - height: 1600px; - -webkit-transform-origin: 0 0; - } -.leaflet-marker-icon, -.leaflet-marker-shadow { - display: block; - } -/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ -/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ -.leaflet-container .leaflet-overlay-pane svg, -.leaflet-container .leaflet-marker-pane img, -.leaflet-container .leaflet-shadow-pane img, -.leaflet-container .leaflet-tile-pane img, -.leaflet-container img.leaflet-image-layer, -.leaflet-container .leaflet-tile { - max-width: none !important; - max-height: none !important; - } - -.leaflet-container.leaflet-touch-zoom { - -ms-touch-action: pan-x pan-y; - touch-action: pan-x pan-y; - } -.leaflet-container.leaflet-touch-drag { - -ms-touch-action: pinch-zoom; - /* Fallback for FF which doesn't support pinch-zoom */ - touch-action: none; - touch-action: pinch-zoom; -} -.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { - -ms-touch-action: none; - touch-action: none; -} -.leaflet-container { - -webkit-tap-highlight-color: transparent; -} -.leaflet-container a { - -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); -} -.leaflet-tile { - filter: inherit; - visibility: hidden; - } -.leaflet-tile-loaded { - visibility: inherit; - } -.leaflet-zoom-box { - width: 0; - height: 0; - -moz-box-sizing: border-box; - box-sizing: border-box; - z-index: 800; - } -/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ -.leaflet-overlay-pane svg { - -moz-user-select: none; - } - -.leaflet-pane { z-index: 400; } - -.leaflet-tile-pane { z-index: 200; } -.leaflet-overlay-pane { z-index: 400; } -.leaflet-shadow-pane { z-index: 500; } -.leaflet-marker-pane { z-index: 600; } -.leaflet-tooltip-pane { z-index: 650; } -.leaflet-popup-pane { z-index: 700; } - -.leaflet-map-pane canvas { z-index: 100; } -.leaflet-map-pane svg { z-index: 200; } - -.leaflet-vml-shape { - width: 1px; - height: 1px; - } -.lvml { - behavior: url(#default#VML); - display: inline-block; - position: absolute; - } - - -/* control positioning */ - -.leaflet-control { - position: relative; - z-index: 800; - pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ - pointer-events: auto; - } -.leaflet-top, -.leaflet-bottom { - position: absolute; - z-index: 1000; - pointer-events: none; - } -.leaflet-top { - top: 0; - } -.leaflet-right { - right: 0; - } -.leaflet-bottom { - bottom: 0; - } -.leaflet-left { - left: 0; - } -.leaflet-control { - float: left; - clear: both; - } -.leaflet-right .leaflet-control { - float: right; - } -.leaflet-top .leaflet-control { - margin-top: 10px; - } -.leaflet-bottom .leaflet-control { - margin-bottom: 10px; - } -.leaflet-left .leaflet-control { - margin-left: 10px; - } -.leaflet-right .leaflet-control { - margin-right: 10px; - } - - -/* zoom and fade animations */ - -.leaflet-fade-anim .leaflet-tile { - will-change: opacity; - } -.leaflet-fade-anim .leaflet-popup { - opacity: 0; - -webkit-transition: opacity 0.2s linear; - -moz-transition: opacity 0.2s linear; - transition: opacity 0.2s linear; - } -.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { - opacity: 1; - } -.leaflet-zoom-animated { - -webkit-transform-origin: 0 0; - -ms-transform-origin: 0 0; - transform-origin: 0 0; - } -.leaflet-zoom-anim .leaflet-zoom-animated { - will-change: transform; - } -.leaflet-zoom-anim .leaflet-zoom-animated { - -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); - -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); - transition: transform 0.25s cubic-bezier(0,0,0.25,1); - } -.leaflet-zoom-anim .leaflet-tile, -.leaflet-pan-anim .leaflet-tile { - -webkit-transition: none; - -moz-transition: none; - transition: none; - } - -.leaflet-zoom-anim .leaflet-zoom-hide { - visibility: hidden; - } - - -/* cursors */ - -.leaflet-interactive { - cursor: pointer; - } -.leaflet-grab { - cursor: -webkit-grab; - cursor: -moz-grab; - cursor: grab; - } -.leaflet-crosshair, -.leaflet-crosshair .leaflet-interactive { - cursor: crosshair; - } -.leaflet-popup-pane, -.leaflet-control { - cursor: auto; - } -.leaflet-dragging .leaflet-grab, -.leaflet-dragging .leaflet-grab .leaflet-interactive, -.leaflet-dragging .leaflet-marker-draggable { - cursor: move; - cursor: -webkit-grabbing; - cursor: -moz-grabbing; - cursor: grabbing; - } - -/* marker & overlays interactivity */ -.leaflet-marker-icon, -.leaflet-marker-shadow, -.leaflet-image-layer, -.leaflet-pane > svg path, -.leaflet-tile-container { - pointer-events: none; - } - -.leaflet-marker-icon.leaflet-interactive, -.leaflet-image-layer.leaflet-interactive, -.leaflet-pane > svg path.leaflet-interactive { - pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ - pointer-events: auto; - } - -/* visual tweaks */ - -.leaflet-container { - background: #ddd; - outline: 0; - } -.leaflet-container a { - color: #0078A8; - } -.leaflet-container a.leaflet-active { - outline: 2px solid orange; - } -.leaflet-zoom-box { - border: 2px dotted #38f; - background: rgba(255,255,255,0.5); - } - - -/* general typography */ -.leaflet-container { - font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; - } - - -/* general toolbar styles */ - -.leaflet-bar { - box-shadow: 0 1px 5px rgba(0,0,0,0.65); - border-radius: 4px; - } -.leaflet-bar a, -.leaflet-bar a:hover { - background-color: #fff; - border-bottom: 1px solid #ccc; - width: 26px; - height: 26px; - line-height: 26px; - display: block; - text-align: center; - text-decoration: none; - color: black; - } -.leaflet-bar a, -.leaflet-control-layers-toggle { - background-position: 50% 50%; - background-repeat: no-repeat; - display: block; - } -.leaflet-bar a:hover { - background-color: #f4f4f4; - } -.leaflet-bar a:first-child { - border-top-left-radius: 4px; - border-top-right-radius: 4px; - } -.leaflet-bar a:last-child { - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-bottom: none; - } -.leaflet-bar a.leaflet-disabled { - cursor: default; - background-color: #f4f4f4; - color: #bbb; - } - -.leaflet-touch .leaflet-bar a { - width: 30px; - height: 30px; - line-height: 30px; - } -.leaflet-touch .leaflet-bar a:first-child { - border-top-left-radius: 2px; - border-top-right-radius: 2px; - } -.leaflet-touch .leaflet-bar a:last-child { - border-bottom-left-radius: 2px; - border-bottom-right-radius: 2px; - } - -/* zoom control */ - -.leaflet-control-zoom-in, -.leaflet-control-zoom-out { - font: bold 18px 'Lucida Console', Monaco, monospace; - text-indent: 1px; - } - -.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { - font-size: 22px; - } - - -/* layers control */ - -.leaflet-control-layers { - box-shadow: 0 1px 5px rgba(0,0,0,0.4); - background: #fff; - border-radius: 5px; - } -.leaflet-control-layers-toggle { - background-image: url(images/layers.png); - width: 36px; - height: 36px; - } -.leaflet-retina .leaflet-control-layers-toggle { - background-image: url(images/layers-2x.png); - background-size: 26px 26px; - } -.leaflet-touch .leaflet-control-layers-toggle { - width: 44px; - height: 44px; - } -.leaflet-control-layers .leaflet-control-layers-list, -.leaflet-control-layers-expanded .leaflet-control-layers-toggle { - display: none; - } -.leaflet-control-layers-expanded .leaflet-control-layers-list { - display: block; - position: relative; - } -.leaflet-control-layers-expanded { - padding: 6px 10px 6px 6px; - color: #333; - background: #fff; - } -.leaflet-control-layers-scrollbar { - overflow-y: scroll; - overflow-x: hidden; - padding-right: 5px; - } -.leaflet-control-layers-selector { - margin-top: 2px; - position: relative; - top: 1px; - } -.leaflet-control-layers label { - display: block; - } -.leaflet-control-layers-separator { - height: 0; - border-top: 1px solid #ddd; - margin: 5px -10px 5px -6px; - } - -/* Default icon URLs */ -.leaflet-default-icon-path { - background-image: url(images/marker-icon.png); - } - - -/* attribution and scale controls */ - -.leaflet-container .leaflet-control-attribution { - background: #fff; - background: rgba(255, 255, 255, 0.7); - margin: 0; - } -.leaflet-control-attribution, -.leaflet-control-scale-line { - padding: 0 5px; - color: #333; - } -.leaflet-control-attribution a { - text-decoration: none; - } -.leaflet-control-attribution a:hover { - text-decoration: underline; - } -.leaflet-container .leaflet-control-attribution, -.leaflet-container .leaflet-control-scale { - font-size: 11px; - } -.leaflet-left .leaflet-control-scale { - margin-left: 5px; - } -.leaflet-bottom .leaflet-control-scale { - margin-bottom: 5px; - } -.leaflet-control-scale-line { - border: 2px solid #777; - border-top: none; - line-height: 1.1; - padding: 2px 5px 1px; - font-size: 11px; - white-space: nowrap; - overflow: hidden; - -moz-box-sizing: border-box; - box-sizing: border-box; - - background: #fff; - background: rgba(255, 255, 255, 0.5); - } -.leaflet-control-scale-line:not(:first-child) { - border-top: 2px solid #777; - border-bottom: none; - margin-top: -2px; - } -.leaflet-control-scale-line:not(:first-child):not(:last-child) { - border-bottom: 2px solid #777; - } - -.leaflet-touch .leaflet-control-attribution, -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - box-shadow: none; - } -.leaflet-touch .leaflet-control-layers, -.leaflet-touch .leaflet-bar { - border: 2px solid rgba(0,0,0,0.2); - background-clip: padding-box; - } - - -/* popup */ - -.leaflet-popup { - position: absolute; - text-align: center; - margin-bottom: 20px; - } -.leaflet-popup-content-wrapper { - padding: 1px; - text-align: left; - border-radius: 12px; - } -.leaflet-popup-content { - margin: 13px 19px; - line-height: 1.4; - } -.leaflet-popup-content p { - margin: 18px 0; - } -.leaflet-popup-tip-container { - width: 40px; - height: 20px; - position: absolute; - left: 50%; - margin-left: -20px; - overflow: hidden; - pointer-events: none; - } -.leaflet-popup-tip { - width: 17px; - height: 17px; - padding: 1px; - - margin: -10px auto 0; - - -webkit-transform: rotate(45deg); - -moz-transform: rotate(45deg); - -ms-transform: rotate(45deg); - transform: rotate(45deg); - } -.leaflet-popup-content-wrapper, -.leaflet-popup-tip { - background: white; - color: #333; - box-shadow: 0 3px 14px rgba(0,0,0,0.4); - } -.leaflet-container a.leaflet-popup-close-button { - position: absolute; - top: 0; - right: 0; - padding: 4px 4px 0 0; - border: none; - text-align: center; - width: 18px; - height: 14px; - font: 16px/14px Tahoma, Verdana, sans-serif; - color: #c3c3c3; - text-decoration: none; - font-weight: bold; - background: transparent; - } -.leaflet-container a.leaflet-popup-close-button:hover { - color: #999; - } -.leaflet-popup-scrolled { - overflow: auto; - border-bottom: 1px solid #ddd; - border-top: 1px solid #ddd; - } - -.leaflet-oldie .leaflet-popup-content-wrapper { - zoom: 1; - } -.leaflet-oldie .leaflet-popup-tip { - width: 24px; - margin: 0 auto; - - -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; - filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); - } -.leaflet-oldie .leaflet-popup-tip-container { - margin-top: -1px; - } - -.leaflet-oldie .leaflet-control-zoom, -.leaflet-oldie .leaflet-control-layers, -.leaflet-oldie .leaflet-popup-content-wrapper, -.leaflet-oldie .leaflet-popup-tip { - border: 1px solid #999; - } - - -/* div icon */ - -.leaflet-div-icon { - background: #fff; - border: 1px solid #666; - } - - -/* Tooltip */ -/* Base styles for the element that has a tooltip */ -.leaflet-tooltip { - position: absolute; - padding: 6px; - background-color: #fff; - border: 1px solid #fff; - border-radius: 3px; - color: #222; - white-space: nowrap; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - pointer-events: none; - box-shadow: 0 1px 3px rgba(0,0,0,0.4); - } -.leaflet-tooltip.leaflet-clickable { - cursor: pointer; - pointer-events: auto; - } -.leaflet-tooltip-top:before, -.leaflet-tooltip-bottom:before, -.leaflet-tooltip-left:before, -.leaflet-tooltip-right:before { - position: absolute; - pointer-events: none; - border: 6px solid transparent; - background: transparent; - content: ""; - } - -/* Directions */ - -.leaflet-tooltip-bottom { - margin-top: 6px; -} -.leaflet-tooltip-top { - margin-top: -6px; -} -.leaflet-tooltip-bottom:before, -.leaflet-tooltip-top:before { - left: 50%; - margin-left: -6px; - } -.leaflet-tooltip-top:before { - bottom: 0; - margin-bottom: -12px; - border-top-color: #fff; - } -.leaflet-tooltip-bottom:before { - top: 0; - margin-top: -12px; - margin-left: -6px; - border-bottom-color: #fff; - } -.leaflet-tooltip-left { - margin-left: -6px; -} -.leaflet-tooltip-right { - margin-left: 6px; -} -.leaflet-tooltip-left:before, -.leaflet-tooltip-right:before { - top: 50%; - margin-top: -6px; - } -.leaflet-tooltip-left:before { - right: 0; - margin-right: -12px; - border-left-color: #fff; - } -.leaflet-tooltip-right:before { - left: 0; - margin-left: -12px; - border-right-color: #fff; - } +/* required styles */ + +.leaflet-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-container, +.leaflet-pane > svg, +.leaflet-pane > canvas, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; + } +/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ +.leaflet-safari .leaflet-tile { + image-rendering: -webkit-optimize-contrast; + } +/* hack that prevents hw layers "stretching" when loading new tiles */ +.leaflet-safari .leaflet-tile-container { + width: 1600px; + height: 1600px; + -webkit-transform-origin: 0 0; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ +/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ +.leaflet-container .leaflet-overlay-pane svg, +.leaflet-container .leaflet-marker-pane img, +.leaflet-container .leaflet-shadow-pane img, +.leaflet-container .leaflet-tile-pane img, +.leaflet-container img.leaflet-image-layer, +.leaflet-container .leaflet-tile { + max-width: none !important; + max-height: none !important; + } + +.leaflet-container.leaflet-touch-zoom { + -ms-touch-action: pan-x pan-y; + touch-action: pan-x pan-y; + } +.leaflet-container.leaflet-touch-drag { + -ms-touch-action: pinch-zoom; + /* Fallback for FF which doesn't support pinch-zoom */ + touch-action: none; + touch-action: pinch-zoom; +} +.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { + -ms-touch-action: none; + touch-action: none; +} +.leaflet-container { + -webkit-tap-highlight-color: transparent; +} +.leaflet-container a { + -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); +} +.leaflet-tile { + filter: inherit; + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } +.leaflet-zoom-box { + width: 0; + height: 0; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 800; + } +/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ +.leaflet-overlay-pane svg { + -moz-user-select: none; + } + +.leaflet-pane { z-index: 400; } + +.leaflet-tile-pane { z-index: 200; } +.leaflet-overlay-pane { z-index: 400; } +.leaflet-shadow-pane { z-index: 500; } +.leaflet-marker-pane { z-index: 600; } +.leaflet-tooltip-pane { z-index: 650; } +.leaflet-popup-pane { z-index: 700; } + +.leaflet-map-pane canvas { z-index: 100; } +.leaflet-map-pane svg { z-index: 200; } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + + +/* control positioning */ + +.leaflet-control { + position: relative; + z-index: 800; + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + + +/* zoom and fade animations */ + +.leaflet-fade-anim .leaflet-tile { + will-change: opacity; + } +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } +.leaflet-zoom-animated { + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + will-change: transform; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); + transition: transform 0.25s cubic-bezier(0,0,0.25,1); + } +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; + } + + +/* cursors */ + +.leaflet-interactive { + cursor: pointer; + } +.leaflet-grab { + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; + } +.leaflet-crosshair, +.leaflet-crosshair .leaflet-interactive { + cursor: crosshair; + } +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; + } +.leaflet-dragging .leaflet-grab, +.leaflet-dragging .leaflet-grab .leaflet-interactive, +.leaflet-dragging .leaflet-marker-draggable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; + } + +/* marker & overlays interactivity */ +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-image-layer, +.leaflet-pane > svg path, +.leaflet-tile-container { + pointer-events: none; + } + +.leaflet-marker-icon.leaflet-interactive, +.leaflet-image-layer.leaflet-interactive, +.leaflet-pane > svg path.leaflet-interactive { + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } + +/* visual tweaks */ + +.leaflet-container { + background: #ddd; + outline: 0; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-container a.leaflet-active { + outline: 2px solid orange; + } +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255,255,255,0.5); + } + + +/* general typography */ +.leaflet-container { + font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + } + + +/* general toolbar styles */ + +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0,0,0,0.65); + border-radius: 4px; + } +.leaflet-bar a, +.leaflet-bar a:hover { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; + } +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-bar a:hover { + background-color: #f4f4f4; + } +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; + } +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; + } + +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; + } +.leaflet-touch .leaflet-bar a:first-child { + border-top-left-radius: 2px; + border-top-right-radius: 2px; + } +.leaflet-touch .leaflet-bar a:last-child { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + } + +/* zoom control */ + +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; + } + +.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { + font-size: 22px; + } + + +/* layers control */ + +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0,0,0,0.4); + background: #fff; + border-radius: 5px; + } +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; + } +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; + } +.leaflet-control-layers-scrollbar { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 5px; + } +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +/* Default icon URLs */ +.leaflet-default-icon-path { + background-image: url(images/marker-icon.png); + } + + +/* attribution and scale controls */ + +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.7); + margin: 0; + } +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; + } +.leaflet-control-attribution a { + text-decoration: none; + } +.leaflet-control-attribution a:hover { + text-decoration: underline; + } +.leaflet-container .leaflet-control-attribution, +.leaflet-container .leaflet-control-scale { + font-size: 11px; + } +.leaflet-left .leaflet-control-scale { + margin-left: 5px; + } +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; + } +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + font-size: 11px; + white-space: nowrap; + overflow: hidden; + -moz-box-sizing: border-box; + box-sizing: border-box; + + background: #fff; + background: rgba(255, 255, 255, 0.5); + } +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; + } +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; + } + +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; + } +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0,0,0,0.2); + background-clip: padding-box; + } + + +/* popup */ + +.leaflet-popup { + position: absolute; + text-align: center; + margin-bottom: 20px; + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; + } +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; + } +.leaflet-popup-content p { + margin: 18px 0; + } +.leaflet-popup-tip-container { + width: 40px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -20px; + overflow: hidden; + pointer-events: none; + } +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + + margin: -10px auto 0; + + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + color: #333; + box-shadow: 0 3px 14px rgba(0,0,0,0.4); + } +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + padding: 4px 4px 0 0; + border: none; + text-align: center; + width: 18px; + height: 14px; + font: 16px/14px Tahoma, Verdana, sans-serif; + color: #c3c3c3; + text-decoration: none; + font-weight: bold; + background: transparent; + } +.leaflet-container a.leaflet-popup-close-button:hover { + color: #999; + } +.leaflet-popup-scrolled { + overflow: auto; + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + } + +.leaflet-oldie .leaflet-popup-content-wrapper { + zoom: 1; + } +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + } +.leaflet-oldie .leaflet-popup-tip-container { + margin-top: -1px; + } + +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; + } + + +/* div icon */ + +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; + } + + +/* Tooltip */ +/* Base styles for the element that has a tooltip */ +.leaflet-tooltip { + position: absolute; + padding: 6px; + background-color: #fff; + border: 1px solid #fff; + border-radius: 3px; + color: #222; + white-space: nowrap; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; + box-shadow: 0 1px 3px rgba(0,0,0,0.4); + } +.leaflet-tooltip.leaflet-clickable { + cursor: pointer; + pointer-events: auto; + } +.leaflet-tooltip-top:before, +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + position: absolute; + pointer-events: none; + border: 6px solid transparent; + background: transparent; + content: ""; + } + +/* Directions */ + +.leaflet-tooltip-bottom { + margin-top: 6px; +} +.leaflet-tooltip-top { + margin-top: -6px; +} +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-top:before { + left: 50%; + margin-left: -6px; + } +.leaflet-tooltip-top:before { + bottom: 0; + margin-bottom: -12px; + border-top-color: #fff; + } +.leaflet-tooltip-bottom:before { + top: 0; + margin-top: -12px; + margin-left: -6px; + border-bottom-color: #fff; + } +.leaflet-tooltip-left { + margin-left: -6px; +} +.leaflet-tooltip-right { + margin-left: 6px; +} +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + top: 50%; + margin-top: -6px; + } +.leaflet-tooltip-left:before { + right: 0; + margin-right: -12px; + border-left-color: #fff; + } +.leaflet-tooltip-right:before { + left: 0; + margin-left: -12px; + border-right-color: #fff; + } diff --git a/app/static/css/main.css b/app/static/css/main.css index fe2b0d2..52d9881 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -1,198 +1,198 @@ /* Custom CSS */ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; - --FontFamily:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; - --FontSize:13px; + --dGray1:#8E8E93; + --dGray2:#636366; + --dGray3:#48484A; + --dGray4:#3A3A3C; + --dGray5:#2C2C2E; + --dGray6:#1C1C1E; + --dBlue:#0A84FF; + --FontFamily:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; + --FontSize:13px; } html { - height: 100%; + height: 100%; } body { - padding-top: 70px; - background-color: var(--dGray5); - color: var(--dGray1); - height: 100%; - font-family: var(--FontFamily); - font-size: var(--FontSize); + padding-top: 70px; + background-color: var(--dGray5); + color: var(--dGray1); + height: 100%; + font-family: var(--FontFamily); + font-size: var(--FontSize); } .background{ - position: absolute; - z-index: -1000; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-size: cover; - background-repeat: no-repeat; - background-position: center; - -webkit-filter: blur(2px) brightness(50%); - -moz-filter: blur(2px) brightness(50%); - -o-filter: blur(2px) brightness(50%); - -ms-filter: blur(2px) brightness(50%); - filter: blur(2px) brightness(50%); + position: absolute; + z-index: -1000; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + -webkit-filter: blur(2px) brightness(50%); + -moz-filter: blur(2px) brightness(50%); + -o-filter: blur(2px) brightness(50%); + -ms-filter: blur(2px) brightness(50%); + filter: blur(2px) brightness(50%); } .padding-top { - padding-top: 10px; + padding-top: 10px; } .darker { - background-color: #fafafa; - margin-top: 10px; - padding-bottom: 5px; + background-color: #fafafa; + margin-top: 10px; + padding-bottom: 5px; } @media (min-width: 992px) { - .align-bottom { - margin-top: 2.5em; - } + .align-bottom { + margin-top: 2.5em; + } } .full-width { - width: 100%; + width: 100%; } .showcase { - font-size: 16px; - line-height: 1.2; + font-size: 16px; + line-height: 1.2; } .showcase { - padding: 0; - max-width: 500px; - margin: 0 auto; + padding: 0; + max-width: 500px; + margin: 0 auto; } .showcase h1 { - font-size: 200%; - margin: 0 ; - padding: 0.4em 0 0.2em; - border-bottom: 1px dashed var(--dGray1); - text-align: center; + font-size: 200%; + margin: 0 ; + padding: 0.4em 0 0.2em; + border-bottom: 1px dashed var(--dGray1); + text-align: center; } .showcase h2 { - font-size: 110%; - font-weight: bold; - margin-bottom: 0.6em; + font-size: 110%; + font-weight: bold; + margin-bottom: 0.6em; } .showcase .open-order-warning { - font-size: 150%; - text-align: center; - padding: 1em 0.5em; - background-color: rgba(255, 0, 0, 0.1); + font-size: 150%; + text-align: center; + padding: 1em 0.5em; + background-color: rgba(255, 0, 0, 0.1); } .showcase .dish { - padding: 0 0.5em; + padding: 0 0.5em; } @media (min-width: 500px) { - .showcase .dish { - padding: 0 1em; - } + .showcase .dish { + padding: 0 1em; + } } .showcase .quantity { - font-size: 110%; + font-size: 110%; } .showcase .comments { - padding-left: 2em; + padding-left: 2em; } .showcase .comments li { - margin: 0.5em 0 0; + margin: 0.5em 0 0; } .showcase .total { - border-top: 1px dashed var(--dGray1); - text-align: center; - padding: 0.5em 0; - margin-top: 1.3em; + border-top: 1px dashed var(--dGray1); + text-align: center; + padding: 0.5em 0; + margin-top: 1.3em; } .order_row { - background: var(--dGray4); + background: var(--dGray4); } .time_data{ - display: flex; - justify-content: space-between; + display: flex; + justify-content: space-between; } @media(min-width: 768px) and (max-width: 991px){ - /* Make sure the small map in the location page has the same with as the block above */ - .sm-no-side-padding { - padding-left: 0px; - padding-right: 0px; - } + /* Make sure the small map in the location page has the same with as the block above */ + .sm-no-side-padding { + padding-left: 0px; + padding-right: 0px; + } } @media(min-width: 992px){ - .md-no-right-padding { - padding-right: 0px; - } + .md-no-right-padding { + padding-right: 0px; + } } /* Add clickable box */ div.box:hover { - cursor: hand; - cursor: pointer; - opacity: .9; - box-shadow: 2px 4px 4px -1px #888888; + cursor: hand; + cursor: pointer; + opacity: .9; + box-shadow: 2px 4px 4px -1px #888888; } a.divLink { - position: absolute; - width: 100%; - height: 100%; - top: 0; - left: 0; - text-decoration: none; - /* Makes sure the link doesn't get underlined */ - z-index: 10; - /* raises anchor tag above everything else in div */ - background-color: white; - /*workaround to make clickable in IE */ - opacity: 0; - /*workaround to make clickable in IE */ - filter: alpha(opacity=0); - /*workaround to make clickable in IE */ + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + text-decoration: none; + /* Makes sure the link doesn't get underlined */ + z-index: 10; + /* raises anchor tag above everything else in div */ + background-color: white; + /*workaround to make clickable in IE */ + opacity: 0; + /*workaround to make clickable in IE */ + filter: alpha(opacity=0); + /*workaround to make clickable in IE */ } .footerWrapper { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - margin: 0 -1rem; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + margin: 0 -1rem; } .footerWrapper>div{ - margin: 0 1rem; + margin: 0 1rem; } .hidden { - display: none; + display: none; } .table-hover tbody tr:hover{ - background-color: var(--dGray3); + background-color: var(--dGray3); } a { color: var(--dBlue); } .btn-primary { - color: var(--dGray6); - background-color: var(--dBlue); + color: var(--dGray6); + background-color: var(--dBlue); } .navbar { @@ -230,23 +230,23 @@ h1, h2, h3, h4, h5, h6{ border-bottom: 2px solid var(--dGray2); } .navbar-toggle .icon-bar { - background-color: var(--dGray0); - opacity: 0.5; + background-color: var(--dGray0); + opacity: 0.5; } .select2-container--default .select2-selection--single{ - background-color: var(--dGray3); - color: var(--dGray0); + background-color: var(--dGray3); + color: var(--dGray0); } .select2-container--default .select2-selection--single .select2-selection__rendered{ - color: var(--dGray0); + color: var(--dGray0); } .select2-results__option{ - background-color: var(--dGray5); - color: var(--dGray0); + background-color: var(--dGray5); + color: var(--dGray0); } .select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: var(--dGray4); - color: var(--dGray0); + background-color: var(--dGray4); + color: var(--dGray0); } .bootstrap-datetimepicker-widget table thead tr:first-child th:hover, .bootstrap-datetimepicker-widget table td.day:hover, @@ -254,39 +254,39 @@ h1, h2, h3, h4, h5, h6{ .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td span:hover, .bootstrap-datetimepicker-widget table td.second:hover { - background: var(--dGray4); + background: var(--dGray4); } .select2-container--default .select2-results__option[aria-selected=true]{ - background-color: var(--dBlue); - color: var(--dGray0); + background-color: var(--dBlue); + color: var(--dGray0); } .select2-search{ - background-color: var(--dGray2); + background-color: var(--dGray2); } .select2-selection--multiple .select2-search{ - background-color: transparent; + background-color: transparent; } .select2-selection--multiple .select2-search{ - background-color: transparent; + background-color: transparent; } .select2-selection--multiple .select2-search.select2-search--inline .select2-search__field{ - border: 1px solid #ccc; - padding-left: 0.3em; - box-sizing: content-box; + border: 1px solid #ccc; + padding-left: 0.3em; + box-sizing: content-box; } .select2-search input{ - background-color: var(--dGray0); + background-color: var(--dGray0); } .dropdown-menu{ - background-color: var(--dGray5); + background-color: var(--dGray5); } .form-control{ - color: var(--dGray0); + color: var(--dGray0); } .form-control::placeholder{ - color: var(--dGray2); + color: var(--dGray2); } .enter_darkmode>a { - text-align: center; + text-align: center; } diff --git a/app/static/css/map.css b/app/static/css/map.css index 46adeb4..ecb5da7 100644 --- a/app/static/css/map.css +++ b/app/static/css/map.css @@ -1,9 +1,9 @@ .large-map { - min-height: 400px; - height: 600px; + min-height: 400px; + height: 600px; } .small-map { - min-height: 150px; - height: 250px; + min-height: 150px; + height: 250px; } diff --git a/app/static/css/print.css b/app/static/css/print.css index 945bb21..c51d13a 100644 --- a/app/static/css/print.css +++ b/app/static/css/print.css @@ -1,15 +1,15 @@ @media print { - nav, form, footer, .btn, #form, #debts { - display: none; - } - #items { - display: flex; - } - #items-list { - order: 2; - } - #items-ordered { - order: 1; - margin-right: 50px; - } -} \ No newline at end of file + nav, form, footer, .btn, #form, #debts { + display: none; + } + #items { + display: flex; + } + #items-list { + order: 2; + } + #items-ordered { + order: 1; + margin-right: 50px; + } +} diff --git a/app/static/css/themes/highPerformance/darkmode.css b/app/static/css/themes/highPerformance/darkmode.css index 324f4a0..7a1dc46 100644 --- a/app/static/css/themes/highPerformance/darkmode.css +++ b/app/static/css/themes/highPerformance/darkmode.css @@ -1,12 +1,12 @@ /*Darkmode*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; -} \ No newline at end of file + --dGray1:#8E8E93; + --dGray2:#636366; + --dGray3:#48484A; + --dGray4:#3A3A3C; + --dGray5:#2C2C2E; + --dGray6:#1C1C1E; + --dBlue:#0A84FF; +} diff --git a/app/static/css/themes/highPerformance/dataPrivacy.css b/app/static/css/themes/highPerformance/dataPrivacy.css index cc063f7..b9c300c 100644 --- a/app/static/css/themes/highPerformance/dataPrivacy.css +++ b/app/static/css/themes/highPerformance/dataPrivacy.css @@ -1,4 +1,4 @@ .background { - background-image: url("https://kelder.zeus.ugent.be/webcam/video/mjpg.cgi?profileid=2"); - background-size: contain; -} \ No newline at end of file + background-image: url("https://kelder.zeus.ugent.be/webcam/video/mjpg.cgi?profileid=2"); + background-size: contain; +} diff --git a/app/static/css/themes/highPerformance/halloween.css b/app/static/css/themes/highPerformance/halloween.css index 580ed15..baa23d8 100644 --- a/app/static/css/themes/highPerformance/halloween.css +++ b/app/static/css/themes/highPerformance/halloween.css @@ -1,16 +1,16 @@ /*halloween*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#FFEB65; - --dGray1:#F28705; - --dGray2:#F25C05; - --dGray3:#F27405; - --dGray4:#8C3D0F; - --dGray5:#260101; - --dGray6:#260101; - --dBlue:#D91604; + --dGray1:#F28705; + --dGray2:#F25C05; + --dGray3:#F27405; + --dGray4:#8C3D0F; + --dGray5:#260101; + --dGray6:#260101; + --dBlue:#D91604; } .table-hover tbody tr:hover{ - background-image: url("static/images/themes/halloween/Halloween.jpeg"); -} \ No newline at end of file + background-image: url("static/images/themes/halloween/Halloween.jpeg"); +} diff --git a/app/static/css/themes/highPerformance/kerstmis.css b/app/static/css/themes/highPerformance/kerstmis.css index 7f4bede..c7934c2 100644 --- a/app/static/css/themes/highPerformance/kerstmis.css +++ b/app/static/css/themes/highPerformance/kerstmis.css @@ -11,524 +11,524 @@ Enige discretie is aangeraden. */ /*high performance kerstmis*/ :root { - /*Darkmode colors*/ - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } + /*Darkmode colors*/ + --dGray0:#F28705; + --dGray1:white; + --dGray2:#590212; + --dGray3:#590212; + --dGray4:#274001; + --dGray5:#274001; + --dGray6:#F2778D; + --dBlue:#F2778D; } body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_regular.ttf"); - font-weight: normal; } + font-family: Radikal; + src: url("static/fonts/radikal_regular.ttf"); + font-weight: normal; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_light.ttf"); - font-weight: 200; } + font-family: Radikal; + src: url("static/fonts/radikal_light.ttf"); + font-weight: 200; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_medium.ttf"); - font-weight: medium; } + font-family: Radikal; + src: url("static/fonts/radikal_medium.ttf"); + font-weight: medium; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_bold.ttf"); - font-weight: bold; } + font-family: Radikal; + src: url("static/fonts/radikal_bold.ttf"); + font-weight: bold; } .btn { - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg, #F53030, #F58B9E); } + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg, #F53030, #F58B9E); } .btn:hover { - background-image: linear-gradient(-40deg, #A81111, #FF4B33); } + background-image: linear-gradient(-40deg, #A81111, #FF4B33); } .navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - text-transform: capitalize; } + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + text-transform: capitalize; } .nav > li > a { - padding-left: 1vw; - padding-right: 1vw; } + padding-left: 1vw; + padding-right: 1vw; } .main { - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; } + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; } .navbar .container { - width: 100%; - padding: 0 4vw; } + width: 100%; + padding: 0 4vw; } @media (min-width: 768px) { - .container { - width: 100%; } } + .container { + width: 100%; } } @media (min-width: 992px) { - .main .container, .main .orders { - width: 970px; } } + .main .container, .main .orders { + width: 970px; } } @media (min-width: 1200px) { - .main .container, .main .orders { - width: 1170px; } } + .main .container, .main .orders { + width: 1170px; } } .main { - padding-top: 2.5rem; } + padding-top: 2.5rem; } .order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; } + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; } .order_row { - background: transparent; } + background: transparent; } .order_data h5 { - max-width: 60%; - padding-bottom: 3rem; } + max-width: 60%; + padding-bottom: 3rem; } .expand_button { - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; } + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; } .hi_im_haldis h2 { - display: none; } + display: none; } .hi_im_haldis h3 { - width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - text-align: center; } + width: 100%; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + text-align: center; } .hi_im_haldis { - background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); - border-radius: 0; - width: 100%; } + background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); + border-radius: 0; + width: 100%; } .hi_im_haldis_wrapper { - width: 100%; } + width: 100%; } .darker:nth-child(even) { - background-color: #B62937; - border-radius: 2rem; } + background-color: #B62937; + border-radius: 2rem; } .darker:nth-child(odd) { - background-color: #821C25; - border-radius: 2rem; } + background-color: #821C25; + border-radius: 2rem; } .darker { - padding: 1rem; } + padding: 1rem; } .order_row:nth-child(even) .order_data { - background-color: #B62937; - border-radius: 2rem; } + background-color: #B62937; + border-radius: 2rem; } .order_row:nth-child(odd) .order_data { - background-color: #821C25; - border-radius: 2rem; } + background-color: #821C25; + border-radius: 2rem; } .order_row h5 { - font-weight: bold; } + font-weight: bold; } .order_row { - margin-bottom: 3rem; } + margin-bottom: 3rem; } h3 { - padding-bottom: 1rem; } + padding-bottom: 1rem; } .home_sir { - font-weight: bold; - color: #F45D68; } + font-weight: bold; + color: #F45D68; } .expand_button_wrapper { - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; } + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; } .time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; } + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; } .navbar .navbar-nav .active a { - color: #ff9bae; - border-bottom: 1px solid #ff9bae; - padding-bottom: 1rem; } + color: #ff9bae; + border-bottom: 1px solid #ff9bae; + padding-bottom: 1rem; } .navbar-nav { - padding-left: 2rem; } + padding-left: 2rem; } .jumbotron, .darker { - display: flex; - flex-direction: column; - border-radius: 4rem; } + display: flex; + flex-direction: column; + border-radius: 4rem; } .row > div > h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; } + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; } .row > div > .amount_of_orders { - font-weight: lighter; - font-size: 1.6rem; } + font-weight: lighter; + font-size: 1.6rem; } .row > div .time { - font-weight: lighter; } + font-weight: lighter; } .jumbotron { - background-color: transparent; } + background-color: transparent; } .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { - background-color: transparent; } + background-color: transparent; } .background { - -webkit-filter: blur(0px) brightness(80%); - -moz-filter: blur(0px) brightness(80%); - -o-filter: blur(0px) brightness(80%); - -ms-filter: blur(0px) brightness(80%); - filter: blur(0px) brightness(80%); - position: fixed; - top: 0; - left: 0; } + -webkit-filter: blur(0px) brightness(80%); + -moz-filter: blur(0px) brightness(80%); + -o-filter: blur(0px) brightness(80%); + -ms-filter: blur(0px) brightness(80%); + filter: blur(0px) brightness(80%); + position: fixed; + top: 0; + left: 0; } footer a { - color: #69E8FF; } + color: #69E8FF; } footer { - position: fixed; - bottom: 0; - width: 100%; - background: #CB3444; - height: 5rem; - display: flex; - align-items: center; } + position: fixed; + bottom: 0; + width: 100%; + background: #CB3444; + height: 5rem; + display: flex; + align-items: center; } footer > hr { - display: none; } + display: none; } #mapid { - width: 100%; } + width: 100%; } .order_overview, .order_order, .order_items, .order_ordered, .order_depts { - padding: 1rem 5rem 3rem 5rem; } + padding: 1rem 5rem 3rem 5rem; } .order_overview { - width: 100%; } + width: 100%; } .order_depts { - width: 100%; - margin-bottom: 10rem; } + width: 100%; + margin-bottom: 10rem; } .location_data, .location_products { - width: 100%; } + width: 100%; } .location_products { - margin-bottom: 10rem; } + margin-bottom: 10rem; } .locations_locations { - padding: 1rem 5rem 3rem 5rem; } + padding: 1rem 5rem 3rem 5rem; } .background_wrapper { - position: absolute; - left: 0; - bottom: 5rem; - width: 100%; - height: 100%; - overflow: hidden; } + position: absolute; + left: 0; + bottom: 5rem; + width: 100%; + height: 100%; + overflow: hidden; } .christmas_background { - z-index: -101; - width: 300%; - height: 300%; - background: linear-gradient(-45deg, #2F0000, #C20A12); - animation: gradientBG 19s ease infinite; } + z-index: -101; + width: 300%; + height: 300%; + background: linear-gradient(-45deg, #2F0000, #C20A12); + animation: gradientBG 19s ease infinite; } .sled { - width: 15rem; - height: 15rem; - transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - background-image: url("static/images/themes/kerstmis/sled.svg"); } + width: 15rem; + height: 15rem; + transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + background-image: url("static/images/themes/kerstmis/sled.svg"); } .sled_wrapper { - top: 0.5rem; - left: -7.5rem; - position: absolute; - transform: translate(-50vw, 40vh) rotate(0deg); - width: 15rem; - height: 15rem; - animation: sled 29s ease-in-out infinite; } + top: 0.5rem; + left: -7.5rem; + position: absolute; + transform: translate(-50vw, 40vh) rotate(0deg); + width: 15rem; + height: 15rem; + animation: sled 29s ease-in-out infinite; } .train_button:checked ~ .sled_wrapper:hover { - animation-play-state: paused; } + animation-play-state: paused; } .train_button:checked ~ .sled_wrapper:hover .sled { - transform: translateY(100vh) rotate(90deg); } + transform: translateY(100vh) rotate(90deg); } .snowman_wrapper { - height: 17rem; - width: 10rem; - position: absolute; - bottom: 15rem; - left: -12rem; - animation: snowman 37s ease infinite; - transform-origin: right bottom; } + height: 17rem; + width: 10rem; + position: absolute; + bottom: 15rem; + left: -12rem; + animation: snowman 37s ease infinite; + transform-origin: right bottom; } .snowman_head { - position: absolute; - top: 0; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_head.svg"); - animation: snowman_head 2s ease infinite; } + position: absolute; + top: 0; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_head.svg"); + animation: snowman_head 2s ease infinite; } .snowman_body { - position: absolute; - top: 9.5rem; - left: 0.5rem; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } + position: absolute; + top: 9.5rem; + left: 0.5rem; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } .train_button:checked ~ .merry_christmas { - position: absolute; - top: 0; - width: 100%; - height: 100%; - background-position: center; - background-image: url("static/images/themes/kerstmis/merry_christmas.svg"); - background-size: 25vw; - background-repeat: no-repeat; - animation: merry_christmas 5s ease infinite; } + position: absolute; + top: 0; + width: 100%; + height: 100%; + background-position: center; + background-image: url("static/images/themes/kerstmis/merry_christmas.svg"); + background-size: 25vw; + background-repeat: no-repeat; + animation: merry_christmas 5s ease infinite; } .train_button { - position: absolute; - transform: scaleX(20) scaleY(8) translateX(-100rem); - bottom: 5.5rem; - left: 7rem; - animation: follow_train 47s linear infinite; - opacity: 0; } + position: absolute; + transform: scaleX(20) scaleY(8) translateX(-100rem); + bottom: 5.5rem; + left: 7rem; + animation: follow_train 47s linear infinite; + opacity: 0; } .train_wrapper { - position: absolute; - bottom: 0.5rem; - transform: translateX(-80vw); - animation: train 47s linear infinite; } + position: absolute; + bottom: 0.5rem; + transform: translateX(-80vw); + animation: train 47s linear infinite; } .wheel_big, .wheel_small { - position: absolute; - bottom: -0.4rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/wheel.svg"); } + position: absolute; + bottom: -0.4rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/wheel.svg"); } .train { - position: absolute; - bottom: 0.5rem; - left: 30rem; - width: 30rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/train.svg"); - animation: whobble 1s linear alternate-reverse infinite; } + position: absolute; + bottom: 0.5rem; + left: 30rem; + width: 30rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/train.svg"); + animation: whobble 1s linear alternate-reverse infinite; } .wheel_big { - width: 3.2rem; - height: 3.2rem; } + width: 3.2rem; + height: 3.2rem; } .wheel_small { - width: 2.5rem; - height: 2.5rem; } + width: 2.5rem; + height: 2.5rem; } .train .wheel1 { - animation: turn 2s linear infinite; - left: 3.5rem; } + animation: turn 2s linear infinite; + left: 3.5rem; } .train .wheel2 { - animation: turn 2s linear infinite, -0.1s; - left: 7rem; } + animation: turn 2s linear infinite, -0.1s; + left: 7rem; } .train .wheel3 { - animation: turn 2s linear infinite -0.3s; - left: 10.5rem; } + animation: turn 2s linear infinite -0.3s; + left: 10.5rem; } .train .wheel4 { - animation: turn 1.5s linear infinite -0.5s; - left: 13.9rem; } + animation: turn 1.5s linear infinite -0.5s; + left: 13.9rem; } .train .wheel5 { - animation: turn 1.5s linear infinite -0.7s; - left: 16.6rem; } + animation: turn 1.5s linear infinite -0.7s; + left: 16.6rem; } .zeus_wagon, .mc_wagon { - position: absolute; - bottom: 1.25rem; - width: 30rem; - height: 7.5rem; - background-repeat: no-repeat; - background-size: contain; - animation: whobble 1s linear alternate-reverse infinite; } + position: absolute; + bottom: 1.25rem; + width: 30rem; + height: 7.5rem; + background-repeat: no-repeat; + background-size: contain; + animation: whobble 1s linear alternate-reverse infinite; } .mc_wagon { - background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); - left: 0rem; } + background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); + left: 0rem; } .zeus_wagon { - background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); - left: 15rem; } + background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); + left: 15rem; } .zeus_wagon .wheel1, .mc_wagon .wheel1 { - animation: turn 2s linear infinite; - bottom: -1.1rem; - left: 2.2rem; } + animation: turn 2s linear infinite; + bottom: -1.1rem; + left: 2.2rem; } .zeus_wagon .wheel2, .mc_wagon .wheel2 { - animation: turn 2s linear infinite, -0.1s; - bottom: -1.1rem; - left: 5.75rem; } + animation: turn 2s linear infinite, -0.1s; + bottom: -1.1rem; + left: 5.75rem; } .zeus_wagon .wheel3, .mc_wagon .wheel3 { - animation: turn 2s linear infinite -0.3s; - bottom: -1.1rem; - left: 9.3rem; } + animation: turn 2s linear infinite -0.3s; + bottom: -1.1rem; + left: 9.3rem; } .snow { - border-radius: 50%; - opacity: 0.8; - position: absolute; - top: -100vh; - animation-name: fall; - animation-timing-function: linear; - animation-iteration-count: infinite; } + border-radius: 50%; + opacity: 0.8; + position: absolute; + top: -100vh; + animation-name: fall; + animation-timing-function: linear; + animation-iteration-count: infinite; } .layer1 { - width: 1rem; - height: 1rem; - filter: blur(1.5px); - box-shadow: 71vw 89.7vh 0 -0.13rem#fff,37.6vw 73.2vh 0 -0.46rem#fff,31.1vw 76.6vh 0 -0.42rem#fff,41.5vw 94vh 0 -0.3rem#fff,76.7vw 28.6vh 0 -0.18rem#fff,21.7vw 70.7vh 0 -0.34rem#fff,14.6vw 72.9vh 0 -0.04rem#fff,72vw 50vh 0 -0.12rem#fff,89.6vw 90.4vh 0 -0.45rem#fff,49.7vw 21.5vh 0 -0.02rem#fff,15.8vw 87.2vh 0 -0.04rem#fff,46.3vw 85.9vh 0 -0.24rem#fff,91.6vw 7.4vh 0 -0.11rem#fff,83.3vw 60.5vh 0 -0.06rem#fff,15.2vw 3.2vh 0 -0.31rem#fff,52.9vw 54.1vh 0 -0.48rem#fff,58.9vw 42.1vh 0 -0.07rem#fff,40.7vw 10.5vh 0 -0.25rem#fff,53.7vw 74.5vh 0 -0.33rem#fff,89vw 50.9vh 0 -0.2rem#fff,35vw 22.6vh 0 -0.2rem#fff,18.9vw 66.4vh 0 -0.33rem#fff,66.8vw 22.9vh 0 -0.05rem#fff,34.3vw 46.9vh 0 -0.26rem#fff,72.9vw 33.1vh 0 -0.25rem#fff,23.2vw 2.5vh 0 -0.16rem#fff,60.3vw 21.6vh 0 -0.35rem#fff,14.3vw 0.6vh 0 -0.09rem#fff,95.6vw 72.2vh 0 -0.03rem#fff,4vw 28.6vh 0 -0.17rem#fff,40.8vw 67.7vh 0 -0.16rem#fff,85vw 88.1vh 0 -0.41rem#fff,37.4vw 50.1vh 0 -0.07rem#fff,50.8vw 39.8vh 0 -0.01rem#fff,14.4vw 95.1vh 0 -0.23rem#fff,77.7vw 10.2vh 0 -0.14rem#fff,35.1vw 59vh 0 -0.03rem#fff,45.8vw 42.4vh 0 -0.37rem#fff,48.3vw 51.3vh 0 -0.45rem#fff,98.3vw 5.8vh 0 -0.26rem#fff,2.4vw 88vh 0 -0.17rem#fff,16vw 49.1vh 0 -0.39rem#fff,76.6vw 42.6vh 0 -0.25rem#fff,17.2vw 44.5vh 0 -0.1rem#fff,51.2vw 73.7vh 0 -0.33rem#fff,31.7vw 59.2vh 0 -0.47rem#fff,32.4vw 68.9vh 0 -0.07rem#fff,3.7vw 94.8vh 0 -0.33rem#fff,55.3vw 3.8vh 0 -0.24rem#fff,25.3vw 81.2vh 0 -0.21rem#fff,68.2vw 97.6vh 0 -0.27rem#fff,43.4vw 56.5vh 0 -0.06rem#fff,40.6vw 98.7vh 0 -0.49rem#fff,41.2vw 37.2vh 0 -0.22rem#fff,66.7vw 21.2vh 0 -0.32rem#fff,3.6vw 75.9vh 0 -0.04rem#fff,66.2vw 71.2vh 0 -0.33rem#fff,30.6vw 59.9vh 0 -0.02rem#fff,22.6vw 72.1vh 0 -0.02rem#fff,93.9vw 9.7vh 0 -0.19rem#fff,99.1vw 73.3vh 0 -0.07rem#fff,48.4vw 94.2vh 0 -0.33rem#fff,44.1vw 55.1vh 0 -0.35rem#fff,98.3vw 34vh 0 -0.07rem#fff,85.1vw 30.4vh 0 -0.42rem#fff,65.2vw 21.4vh 0 -0.05rem#fff,72.1vw 92.9vh 0 -0.48rem#fff,25.8vw 53.6vh 0 -0.02rem#fff,13.8vw 12.7vh 0 -0.26rem#fff,79.4vw 94.9vh 0 -0.06rem#fff,41.8vw 56.2vh 0 -0.31rem#fff,67.4vw 20.2vh 0 -0.34rem#fff,35.6vw 88.7vh 0 -0.1rem#fff,12.5vw 20.1vh 0 -0.06rem#fff,30.3vw 32.7vh 0 -0.34rem#fff,51.4vw 84.2vh 0 -0.15rem#fff,16.2vw 80.1vh 0 -0.31rem#fff,6.1vw 14.1vh 0 -0.41rem#fff,86.6vw 55.9vh 0 -0.41rem#fff,43.5vw 75.9vh 0 -0.45rem#fff,77.5vw 20.4vh 0 -0.12rem#fff,67.7vw 97.6vh 0 -0.08rem#fff,0.8vw 18.1vh 0 -0.33rem#fff,60.6vw 21.3vh 0 -0.19rem#fff,70.2vw 79.3vh 0 -0.26rem#fff,50.8vw 68.8vh 0 -0.35rem#fff,53.9vw 12.5vh 0 -0.39rem#fff,76.4vw 45.9vh 0 -0.12rem#fff,11.5vw 58.7vh 0 -0.31rem#fff,76.3vw 74.7vh 0 -0.4rem#fff,4.7vw 46.7vh 0 -0.39rem#fff,54.5vw 63.6vh 0 -0.28rem#fff,51.6vw 65.9vh 0 -0.3rem#fff,65.9vw 47.6vh 0 -0.08rem#fff,91.6vw 58.8vh 0 -0.12rem#fff,26.9vw 71.6vh 0 -0.36rem#fff,59.7vw 71.2vh 0 -0.37rem#fff,47.1vw 16.2vh 0 -0.14rem#fff,72.4vw 45.7vh 0 -0.06rem#fff,30.8vw 39.3vh 0 -0.38rem#fff; - animation-duration: 18s; } + width: 1rem; + height: 1rem; + filter: blur(1.5px); + box-shadow: 71vw 89.7vh 0 -0.13rem#fff,37.6vw 73.2vh 0 -0.46rem#fff,31.1vw 76.6vh 0 -0.42rem#fff,41.5vw 94vh 0 -0.3rem#fff,76.7vw 28.6vh 0 -0.18rem#fff,21.7vw 70.7vh 0 -0.34rem#fff,14.6vw 72.9vh 0 -0.04rem#fff,72vw 50vh 0 -0.12rem#fff,89.6vw 90.4vh 0 -0.45rem#fff,49.7vw 21.5vh 0 -0.02rem#fff,15.8vw 87.2vh 0 -0.04rem#fff,46.3vw 85.9vh 0 -0.24rem#fff,91.6vw 7.4vh 0 -0.11rem#fff,83.3vw 60.5vh 0 -0.06rem#fff,15.2vw 3.2vh 0 -0.31rem#fff,52.9vw 54.1vh 0 -0.48rem#fff,58.9vw 42.1vh 0 -0.07rem#fff,40.7vw 10.5vh 0 -0.25rem#fff,53.7vw 74.5vh 0 -0.33rem#fff,89vw 50.9vh 0 -0.2rem#fff,35vw 22.6vh 0 -0.2rem#fff,18.9vw 66.4vh 0 -0.33rem#fff,66.8vw 22.9vh 0 -0.05rem#fff,34.3vw 46.9vh 0 -0.26rem#fff,72.9vw 33.1vh 0 -0.25rem#fff,23.2vw 2.5vh 0 -0.16rem#fff,60.3vw 21.6vh 0 -0.35rem#fff,14.3vw 0.6vh 0 -0.09rem#fff,95.6vw 72.2vh 0 -0.03rem#fff,4vw 28.6vh 0 -0.17rem#fff,40.8vw 67.7vh 0 -0.16rem#fff,85vw 88.1vh 0 -0.41rem#fff,37.4vw 50.1vh 0 -0.07rem#fff,50.8vw 39.8vh 0 -0.01rem#fff,14.4vw 95.1vh 0 -0.23rem#fff,77.7vw 10.2vh 0 -0.14rem#fff,35.1vw 59vh 0 -0.03rem#fff,45.8vw 42.4vh 0 -0.37rem#fff,48.3vw 51.3vh 0 -0.45rem#fff,98.3vw 5.8vh 0 -0.26rem#fff,2.4vw 88vh 0 -0.17rem#fff,16vw 49.1vh 0 -0.39rem#fff,76.6vw 42.6vh 0 -0.25rem#fff,17.2vw 44.5vh 0 -0.1rem#fff,51.2vw 73.7vh 0 -0.33rem#fff,31.7vw 59.2vh 0 -0.47rem#fff,32.4vw 68.9vh 0 -0.07rem#fff,3.7vw 94.8vh 0 -0.33rem#fff,55.3vw 3.8vh 0 -0.24rem#fff,25.3vw 81.2vh 0 -0.21rem#fff,68.2vw 97.6vh 0 -0.27rem#fff,43.4vw 56.5vh 0 -0.06rem#fff,40.6vw 98.7vh 0 -0.49rem#fff,41.2vw 37.2vh 0 -0.22rem#fff,66.7vw 21.2vh 0 -0.32rem#fff,3.6vw 75.9vh 0 -0.04rem#fff,66.2vw 71.2vh 0 -0.33rem#fff,30.6vw 59.9vh 0 -0.02rem#fff,22.6vw 72.1vh 0 -0.02rem#fff,93.9vw 9.7vh 0 -0.19rem#fff,99.1vw 73.3vh 0 -0.07rem#fff,48.4vw 94.2vh 0 -0.33rem#fff,44.1vw 55.1vh 0 -0.35rem#fff,98.3vw 34vh 0 -0.07rem#fff,85.1vw 30.4vh 0 -0.42rem#fff,65.2vw 21.4vh 0 -0.05rem#fff,72.1vw 92.9vh 0 -0.48rem#fff,25.8vw 53.6vh 0 -0.02rem#fff,13.8vw 12.7vh 0 -0.26rem#fff,79.4vw 94.9vh 0 -0.06rem#fff,41.8vw 56.2vh 0 -0.31rem#fff,67.4vw 20.2vh 0 -0.34rem#fff,35.6vw 88.7vh 0 -0.1rem#fff,12.5vw 20.1vh 0 -0.06rem#fff,30.3vw 32.7vh 0 -0.34rem#fff,51.4vw 84.2vh 0 -0.15rem#fff,16.2vw 80.1vh 0 -0.31rem#fff,6.1vw 14.1vh 0 -0.41rem#fff,86.6vw 55.9vh 0 -0.41rem#fff,43.5vw 75.9vh 0 -0.45rem#fff,77.5vw 20.4vh 0 -0.12rem#fff,67.7vw 97.6vh 0 -0.08rem#fff,0.8vw 18.1vh 0 -0.33rem#fff,60.6vw 21.3vh 0 -0.19rem#fff,70.2vw 79.3vh 0 -0.26rem#fff,50.8vw 68.8vh 0 -0.35rem#fff,53.9vw 12.5vh 0 -0.39rem#fff,76.4vw 45.9vh 0 -0.12rem#fff,11.5vw 58.7vh 0 -0.31rem#fff,76.3vw 74.7vh 0 -0.4rem#fff,4.7vw 46.7vh 0 -0.39rem#fff,54.5vw 63.6vh 0 -0.28rem#fff,51.6vw 65.9vh 0 -0.3rem#fff,65.9vw 47.6vh 0 -0.08rem#fff,91.6vw 58.8vh 0 -0.12rem#fff,26.9vw 71.6vh 0 -0.36rem#fff,59.7vw 71.2vh 0 -0.37rem#fff,47.1vw 16.2vh 0 -0.14rem#fff,72.4vw 45.7vh 0 -0.06rem#fff,30.8vw 39.3vh 0 -0.38rem#fff; + animation-duration: 18s; } .layer1.a { - animation-delay: -9s; } + animation-delay: -9s; } .layer2 { - width: 0.8rem; - height: 0.8rem; - filter: blur(3px); - box-shadow: 71.8vw 15.9vh 0 -0.3rem#fff,4.2vw 8.1vh 0 -0.41rem#fff,67.5vw 49.2vh 0 -0.28rem#fff,72vw 97.8vh 0 -0.22rem#fff,78.1vw 28vh 0 -0.41rem#fff,34.2vw 51.7vh 0 -0.47rem#fff,37.9vw 76.5vh 0 -0.39rem#fff,92.6vw 36.3vh 0 -0.22rem#fff,59.9vw 8.6vh 0 -0.07rem#fff,32.5vw 74vh 0 -0.07rem#fff,75.7vw 81.6vh 0 -0.12rem#fff,1.7vw 18.5vh 0 -0.2rem#fff,12.3vw 64.7vh 0 -0.37rem#fff,83.9vw 47vh 0 -0.12rem#fff,33.8vw 21.3vh 0 -0.14rem#fff,6.5vw 92.5vh 0 -0.29rem#fff,72.2vw 60.8vh 0 -0.17rem#fff,38.4vw 16vh 0 -0.17rem#fff,23.9vw 58.4vh 0 -0.32rem#fff,40.2vw 52.4vh 0 -0.23rem#fff,48.9vw 74.6vh 0 -0.03rem#fff,61.5vw 36.1vh 0 -0.49rem#fff,60.9vw 94.5vh 0 -0.42rem#fff,2.8vw 59.7vh 0 -0.27rem#fff,62.6vw 32.4vh 0 -0.45rem#fff,91.3vw 18vh 0 -0.09rem#fff,35.9vw 35.5vh 0 -0.11rem#fff,60.2vw 95.5vh 0 -0.21rem#fff,19.8vw 46.5vh 0 -0.09rem#fff,57.7vw 20.7vh 0 -0.03rem#fff,69.8vw 33.8vh 0 -0.34rem#fff,69.1vw 71.5vh 0 -0.45rem#fff,70.5vw 87.9vh 0 -0.5rem#fff,77vw 34.9vh 0 -0.43rem#fff,35.6vw 28.7vh 0 -0.14rem#fff,28.6vw 22.7vh 0 -0.47rem#fff,46.3vw 7.1vh 0 -0.06rem#fff,66.6vw 92.6vh 0 -0.32rem#fff,96.5vw 19.1vh 0 -0.12rem#fff,24.6vw 45.5vh 0 -0.27rem#fff,71.6vw 85.8vh 0 -0.16rem#fff,1.1vw 44.9vh 0 -0.36rem#fff,94.4vw 84.2vh 0 -0.19rem#fff,92.2vw 20.2vh 0 -0.27rem#fff,42.5vw 66.1vh 0 -0.46rem#fff,70.8vw 98.4vh 0 -0.01rem#fff,71.7vw 99vh 0 -0.19rem#fff,0.2vw 34.1vh 0 -0.22rem#fff,87.3vw 30.7vh 0 -0.09rem#fff,80.3vw 93.8vh 0 -0.41rem#fff,72.2vw 8.3vh 0 -0.09rem#fff,27.1vw 46.1vh 0 -0.15rem#fff,10.2vw 93.6vh 0 -0.42rem#fff,76vw 51.5vh 0 -0.26rem#fff,28.7vw 76.3vh 0 -0.11rem#fff,85.1vw 21.2vh 0 -0.46rem#fff,25.9vw 82.2vh 0 -0.34rem#fff,32.3vw 69.8vh 0 -0.29rem#fff,97.3vw 56.8vh 0 -0.26rem#fff,48.2vw 29.6vh 0 -0.28rem#fff,76.2vw 61.9vh 0 -0.1rem#fff,62vw 96vh 0 -0.01rem#fff,76vw 79.9vh 0 -0.36rem#fff,59.9vw 86.8vh 0 -0.22rem#fff,72.8vw 92.3vh 0 -0.02rem#fff,62.7vw 55.9vh 0 -0.46rem#fff,81.1vw 53.3vh 0 -0.09rem#fff,42.4vw 20.2vh 0 -0.15rem#fff,72.7vw 95.8vh 0 -0.26rem#fff,67.6vw 11vh 0 -0.08rem#fff,62.5vw 99vh 0 -0.17rem#fff,52.7vw 46.1vh 0 -0.35rem#fff,49.7vw 73vh 0 -0.33rem#fff,1.9vw 25.1vh 0 -0.06rem#fff,25.6vw 11.6vh 0 -0.43rem#fff,9.7vw 28.4vh 0 -0.11rem#fff,52.1vw 87.4vh 0 -0.45rem#fff,94.6vw 3.6vh 0 -0.37rem#fff,67.5vw 67vh 0 -0.29rem#fff,45.4vw 34.9vh 0 -0.02rem#fff,41.6vw 99.6vh 0 -0.34rem#fff,26.3vw 53vh 0 -0.01rem#fff,41.2vw 73.7vh 0 -0.36rem#fff,6.9vw 29.5vh 0 -0.17rem#fff,25.1vw 39.2vh 0 -0.2rem#fff,93.2vw 58.2vh 0 -0.3rem#fff,93.2vw 58.2vh 0 -0.31rem#fff,91.7vw 29vh 0 -0.01rem#fff,90.1vw 25.4vh 0 -0.23rem#fff,12.2vw 98.7vh 0 -0.33rem#fff,88vw 73.3vh 0 -0.29rem#fff,91.5vw 61vh 0 -0.43rem#fff,96.1vw 70.8vh 0 -0.21rem#fff,98.2vw 55.4vh 0 -0.27rem#fff,15.2vw 59vh 0 -0.34rem#fff,66.3vw 83.5vh 0 -0.05rem#fff,49vw 8.5vh 0 -0.47rem#fff,93.3vw 91.7vh 0 -0.17rem#fff,15.4vw 35.4vh 0 -0.47rem#fff,14.3vw 48.5vh 0 -0.44rem#fff; - animation-duration: 24s; } + width: 0.8rem; + height: 0.8rem; + filter: blur(3px); + box-shadow: 71.8vw 15.9vh 0 -0.3rem#fff,4.2vw 8.1vh 0 -0.41rem#fff,67.5vw 49.2vh 0 -0.28rem#fff,72vw 97.8vh 0 -0.22rem#fff,78.1vw 28vh 0 -0.41rem#fff,34.2vw 51.7vh 0 -0.47rem#fff,37.9vw 76.5vh 0 -0.39rem#fff,92.6vw 36.3vh 0 -0.22rem#fff,59.9vw 8.6vh 0 -0.07rem#fff,32.5vw 74vh 0 -0.07rem#fff,75.7vw 81.6vh 0 -0.12rem#fff,1.7vw 18.5vh 0 -0.2rem#fff,12.3vw 64.7vh 0 -0.37rem#fff,83.9vw 47vh 0 -0.12rem#fff,33.8vw 21.3vh 0 -0.14rem#fff,6.5vw 92.5vh 0 -0.29rem#fff,72.2vw 60.8vh 0 -0.17rem#fff,38.4vw 16vh 0 -0.17rem#fff,23.9vw 58.4vh 0 -0.32rem#fff,40.2vw 52.4vh 0 -0.23rem#fff,48.9vw 74.6vh 0 -0.03rem#fff,61.5vw 36.1vh 0 -0.49rem#fff,60.9vw 94.5vh 0 -0.42rem#fff,2.8vw 59.7vh 0 -0.27rem#fff,62.6vw 32.4vh 0 -0.45rem#fff,91.3vw 18vh 0 -0.09rem#fff,35.9vw 35.5vh 0 -0.11rem#fff,60.2vw 95.5vh 0 -0.21rem#fff,19.8vw 46.5vh 0 -0.09rem#fff,57.7vw 20.7vh 0 -0.03rem#fff,69.8vw 33.8vh 0 -0.34rem#fff,69.1vw 71.5vh 0 -0.45rem#fff,70.5vw 87.9vh 0 -0.5rem#fff,77vw 34.9vh 0 -0.43rem#fff,35.6vw 28.7vh 0 -0.14rem#fff,28.6vw 22.7vh 0 -0.47rem#fff,46.3vw 7.1vh 0 -0.06rem#fff,66.6vw 92.6vh 0 -0.32rem#fff,96.5vw 19.1vh 0 -0.12rem#fff,24.6vw 45.5vh 0 -0.27rem#fff,71.6vw 85.8vh 0 -0.16rem#fff,1.1vw 44.9vh 0 -0.36rem#fff,94.4vw 84.2vh 0 -0.19rem#fff,92.2vw 20.2vh 0 -0.27rem#fff,42.5vw 66.1vh 0 -0.46rem#fff,70.8vw 98.4vh 0 -0.01rem#fff,71.7vw 99vh 0 -0.19rem#fff,0.2vw 34.1vh 0 -0.22rem#fff,87.3vw 30.7vh 0 -0.09rem#fff,80.3vw 93.8vh 0 -0.41rem#fff,72.2vw 8.3vh 0 -0.09rem#fff,27.1vw 46.1vh 0 -0.15rem#fff,10.2vw 93.6vh 0 -0.42rem#fff,76vw 51.5vh 0 -0.26rem#fff,28.7vw 76.3vh 0 -0.11rem#fff,85.1vw 21.2vh 0 -0.46rem#fff,25.9vw 82.2vh 0 -0.34rem#fff,32.3vw 69.8vh 0 -0.29rem#fff,97.3vw 56.8vh 0 -0.26rem#fff,48.2vw 29.6vh 0 -0.28rem#fff,76.2vw 61.9vh 0 -0.1rem#fff,62vw 96vh 0 -0.01rem#fff,76vw 79.9vh 0 -0.36rem#fff,59.9vw 86.8vh 0 -0.22rem#fff,72.8vw 92.3vh 0 -0.02rem#fff,62.7vw 55.9vh 0 -0.46rem#fff,81.1vw 53.3vh 0 -0.09rem#fff,42.4vw 20.2vh 0 -0.15rem#fff,72.7vw 95.8vh 0 -0.26rem#fff,67.6vw 11vh 0 -0.08rem#fff,62.5vw 99vh 0 -0.17rem#fff,52.7vw 46.1vh 0 -0.35rem#fff,49.7vw 73vh 0 -0.33rem#fff,1.9vw 25.1vh 0 -0.06rem#fff,25.6vw 11.6vh 0 -0.43rem#fff,9.7vw 28.4vh 0 -0.11rem#fff,52.1vw 87.4vh 0 -0.45rem#fff,94.6vw 3.6vh 0 -0.37rem#fff,67.5vw 67vh 0 -0.29rem#fff,45.4vw 34.9vh 0 -0.02rem#fff,41.6vw 99.6vh 0 -0.34rem#fff,26.3vw 53vh 0 -0.01rem#fff,41.2vw 73.7vh 0 -0.36rem#fff,6.9vw 29.5vh 0 -0.17rem#fff,25.1vw 39.2vh 0 -0.2rem#fff,93.2vw 58.2vh 0 -0.3rem#fff,93.2vw 58.2vh 0 -0.31rem#fff,91.7vw 29vh 0 -0.01rem#fff,90.1vw 25.4vh 0 -0.23rem#fff,12.2vw 98.7vh 0 -0.33rem#fff,88vw 73.3vh 0 -0.29rem#fff,91.5vw 61vh 0 -0.43rem#fff,96.1vw 70.8vh 0 -0.21rem#fff,98.2vw 55.4vh 0 -0.27rem#fff,15.2vw 59vh 0 -0.34rem#fff,66.3vw 83.5vh 0 -0.05rem#fff,49vw 8.5vh 0 -0.47rem#fff,93.3vw 91.7vh 0 -0.17rem#fff,15.4vw 35.4vh 0 -0.47rem#fff,14.3vw 48.5vh 0 -0.44rem#fff; + animation-duration: 24s; } .layer2.a { - animation-delay: -12s; } + animation-delay: -12s; } .layer3 { - width: 0.6rem; - height: 0.6rem; - filter: blur(6px); - box-shadow: 23.4vw 84.5vh 0 -0.38rem#fff,47.1vw 27.7vh 0 -0.23rem#fff,57.9vw 71.8vh 0 -0.09rem#fff,99vw 88.7vh 0 -0.37rem#fff,69vw 41.3vh 0 -0.14rem#fff,44.7vw 79.1vh 0 -0.4rem#fff,53.2vw 22.3vh 0 -0.5rem#fff,37.8vw 79.6vh 0 -0.08rem#fff,46.1vw 40.6vh 0 -0.2rem#fff,9.8vw 50.6vh 0 -0.05rem#fff,45.6vw 13.3vh 0 -0.02rem#fff,23.3vw 18.3vh 0 -0.32rem#fff,38.4vw 20.4vh 0 -0.22rem#fff,37.5vw 34.1vh 0 -0.21rem#fff,31vw 96.9vh 0 -0.1rem#fff,6.8vw 99vh 0 -0.49rem#fff,19.7vw 13.4vh 0 -0.28rem#fff,24vw 16.4vh 0 -0.09rem#fff,98.6vw 17.6vh 0 -0.08rem#fff,5.2vw 26.8vh 0 -0.35rem#fff,60.5vw 57.7vh 0 -0.34rem#fff,63.4vw 34.1vh 0 -0.46rem#fff,62.2vw 9.9vh 0 -0.13rem#fff,31.8vw 40vh 0 -0.19rem#fff,28vw 68.9vh 0 -0.33rem#fff,74.5vw 21.3vh 0 -0.32rem#fff,30.8vw 29.5vh 0 -0.25rem#fff,80.3vw 28vh 0 -0.12rem#fff,88.7vw 47.8vh 0 -0.33rem#fff,7.9vw 70.8vh 0 -0.46rem#fff,26.6vw 49.2vh 0 -0.04rem#fff,98.4vw 42.8vh 0 -0.09rem#fff,62.5vw 64.5vh 0 -0.48rem#fff,60.7vw 92.5vh 0 -0.13rem#fff,2.8vw 99.2vh 0 -0.49rem#fff,81.4vw 21.3vh 0 -0.4rem#fff,83.4vw 47.1vh 0 -0.46rem#fff,79.2vw 2.6vh 0 -0.17rem#fff,17.7vw 3.1vh 0 -0.12rem#fff,66.4vw 98.4vh 0 -0.34rem#fff,59.5vw 51.1vh 0 -0.2rem#fff,5.8vw 28.2vh 0 -0.41rem#fff,9.7vw 54vh 0 -0.48rem#fff,24.1vw 98.3vh 0 -0.29rem#fff,9.7vw 73.1vh 0 -0.44rem#fff,10vw 53.7vh 0 -0.5rem#fff,37.7vw 16.1vh 0 -0.31rem#fff,43.9vw 51.8vh 0 -0.29rem#fff,70.8vw 54vh 0 -0.19rem#fff,61.5vw 91vh 0 -0.41rem#fff,87.1vw 13.1vh 0 -0.22rem#fff,89.6vw 34.1vh 0 -0.25rem#fff,52.8vw 38.1vh 0 -0.33rem#fff,88.4vw 79.4vh 0 -0.22rem#fff,84.4vw 84.6vh 0 -0.1rem#fff,69.4vw 8.7vh 0 -0.46rem#fff,8.8vw 73.7vh 0 -0.19rem#fff,89.3vw 14.7vh 0 -0.1rem#fff,100vw 72.7vh 0 -0.2rem#fff,16.9vw 93.8vh 0 -0.22rem#fff,90.7vw 36.1vh 0 -0.43rem#fff,46.6vw 49.6vh 0 -0.21rem#fff,57.3vw 72.3vh 0 -0.03rem#fff,49.7vw 2vh 0 -0.15rem#fff,67vw 96.2vh 0 -0.47rem#fff,86vw 71.7vh 0 -0.11rem#fff,66vw 65.8vh 0 -0.32rem#fff,85.2vw 7.6vh 0 -0.12rem#fff,95.9vw 49.4vh 0 -0.15rem#fff,33.2vw 66.6vh 0 -0.14rem#fff,75.4vw 26.3vh 0 -0.02rem#fff,52.7vw 56vh 0 -0.11rem#fff,37.7vw 77vh 0 -0.18rem#fff,26.3vw 59.9vh 0 -0.18rem#fff,88.2vw 74.6vh 0 -0.39rem#fff,89.5vw 61.2vh 0 -0.48rem#fff,62vw 79.5vh 0 -0.4rem#fff,98.7vw 3.9vh 0 -0.01rem#fff,63.3vw 32vh 0 -0.43rem#fff,49.6vw 28.5vh 0 -0.09rem#fff,70vw 87vh 0 -0.05rem#fff,38.3vw 67.3vh 0 -0.49rem#fff,41.8vw 82.5vh 0 -0.36rem#fff,85.8vw 74vh 0 -0.07rem#fff,82.3vw 48.8vh 0 -0.11rem#fff,35.2vw 79.8vh 0 -0.4rem#fff,73.3vw 72.4vh 0 -0.36rem#fff,62.4vw 30.5vh 0 -0.14rem#fff,48.5vw 51.9vh 0 -0.03rem#fff,74.6vw 51.1vh 0 -0.35rem#fff,62.6vw 12.8vh 0 -0.33rem#fff,10vw 72.1vh 0 -0.2rem#fff,59vw 50.5vh 0 -0.04rem#fff,79.1vw 60.1vh 0 -0.34rem#fff,77.5vw 45.1vh 0 -0.23rem#fff,53vw 77.3vh 0 -0.4rem#fff,46.8vw 52.1vh 0 -0.44rem#fff,60.7vw 81vh 0 -0.17rem#fff,86.2vw 53.9vh 0 -0.01rem#fff,85.8vw 79.2vh 0 -0.39rem#fff; - animation-duration: 30s; } + width: 0.6rem; + height: 0.6rem; + filter: blur(6px); + box-shadow: 23.4vw 84.5vh 0 -0.38rem#fff,47.1vw 27.7vh 0 -0.23rem#fff,57.9vw 71.8vh 0 -0.09rem#fff,99vw 88.7vh 0 -0.37rem#fff,69vw 41.3vh 0 -0.14rem#fff,44.7vw 79.1vh 0 -0.4rem#fff,53.2vw 22.3vh 0 -0.5rem#fff,37.8vw 79.6vh 0 -0.08rem#fff,46.1vw 40.6vh 0 -0.2rem#fff,9.8vw 50.6vh 0 -0.05rem#fff,45.6vw 13.3vh 0 -0.02rem#fff,23.3vw 18.3vh 0 -0.32rem#fff,38.4vw 20.4vh 0 -0.22rem#fff,37.5vw 34.1vh 0 -0.21rem#fff,31vw 96.9vh 0 -0.1rem#fff,6.8vw 99vh 0 -0.49rem#fff,19.7vw 13.4vh 0 -0.28rem#fff,24vw 16.4vh 0 -0.09rem#fff,98.6vw 17.6vh 0 -0.08rem#fff,5.2vw 26.8vh 0 -0.35rem#fff,60.5vw 57.7vh 0 -0.34rem#fff,63.4vw 34.1vh 0 -0.46rem#fff,62.2vw 9.9vh 0 -0.13rem#fff,31.8vw 40vh 0 -0.19rem#fff,28vw 68.9vh 0 -0.33rem#fff,74.5vw 21.3vh 0 -0.32rem#fff,30.8vw 29.5vh 0 -0.25rem#fff,80.3vw 28vh 0 -0.12rem#fff,88.7vw 47.8vh 0 -0.33rem#fff,7.9vw 70.8vh 0 -0.46rem#fff,26.6vw 49.2vh 0 -0.04rem#fff,98.4vw 42.8vh 0 -0.09rem#fff,62.5vw 64.5vh 0 -0.48rem#fff,60.7vw 92.5vh 0 -0.13rem#fff,2.8vw 99.2vh 0 -0.49rem#fff,81.4vw 21.3vh 0 -0.4rem#fff,83.4vw 47.1vh 0 -0.46rem#fff,79.2vw 2.6vh 0 -0.17rem#fff,17.7vw 3.1vh 0 -0.12rem#fff,66.4vw 98.4vh 0 -0.34rem#fff,59.5vw 51.1vh 0 -0.2rem#fff,5.8vw 28.2vh 0 -0.41rem#fff,9.7vw 54vh 0 -0.48rem#fff,24.1vw 98.3vh 0 -0.29rem#fff,9.7vw 73.1vh 0 -0.44rem#fff,10vw 53.7vh 0 -0.5rem#fff,37.7vw 16.1vh 0 -0.31rem#fff,43.9vw 51.8vh 0 -0.29rem#fff,70.8vw 54vh 0 -0.19rem#fff,61.5vw 91vh 0 -0.41rem#fff,87.1vw 13.1vh 0 -0.22rem#fff,89.6vw 34.1vh 0 -0.25rem#fff,52.8vw 38.1vh 0 -0.33rem#fff,88.4vw 79.4vh 0 -0.22rem#fff,84.4vw 84.6vh 0 -0.1rem#fff,69.4vw 8.7vh 0 -0.46rem#fff,8.8vw 73.7vh 0 -0.19rem#fff,89.3vw 14.7vh 0 -0.1rem#fff,100vw 72.7vh 0 -0.2rem#fff,16.9vw 93.8vh 0 -0.22rem#fff,90.7vw 36.1vh 0 -0.43rem#fff,46.6vw 49.6vh 0 -0.21rem#fff,57.3vw 72.3vh 0 -0.03rem#fff,49.7vw 2vh 0 -0.15rem#fff,67vw 96.2vh 0 -0.47rem#fff,86vw 71.7vh 0 -0.11rem#fff,66vw 65.8vh 0 -0.32rem#fff,85.2vw 7.6vh 0 -0.12rem#fff,95.9vw 49.4vh 0 -0.15rem#fff,33.2vw 66.6vh 0 -0.14rem#fff,75.4vw 26.3vh 0 -0.02rem#fff,52.7vw 56vh 0 -0.11rem#fff,37.7vw 77vh 0 -0.18rem#fff,26.3vw 59.9vh 0 -0.18rem#fff,88.2vw 74.6vh 0 -0.39rem#fff,89.5vw 61.2vh 0 -0.48rem#fff,62vw 79.5vh 0 -0.4rem#fff,98.7vw 3.9vh 0 -0.01rem#fff,63.3vw 32vh 0 -0.43rem#fff,49.6vw 28.5vh 0 -0.09rem#fff,70vw 87vh 0 -0.05rem#fff,38.3vw 67.3vh 0 -0.49rem#fff,41.8vw 82.5vh 0 -0.36rem#fff,85.8vw 74vh 0 -0.07rem#fff,82.3vw 48.8vh 0 -0.11rem#fff,35.2vw 79.8vh 0 -0.4rem#fff,73.3vw 72.4vh 0 -0.36rem#fff,62.4vw 30.5vh 0 -0.14rem#fff,48.5vw 51.9vh 0 -0.03rem#fff,74.6vw 51.1vh 0 -0.35rem#fff,62.6vw 12.8vh 0 -0.33rem#fff,10vw 72.1vh 0 -0.2rem#fff,59vw 50.5vh 0 -0.04rem#fff,79.1vw 60.1vh 0 -0.34rem#fff,77.5vw 45.1vh 0 -0.23rem#fff,53vw 77.3vh 0 -0.4rem#fff,46.8vw 52.1vh 0 -0.44rem#fff,60.7vw 81vh 0 -0.17rem#fff,86.2vw 53.9vh 0 -0.01rem#fff,85.8vw 79.2vh 0 -0.39rem#fff; + animation-duration: 30s; } .layer3.a { - animation-delay: -15s; } + animation-delay: -15s; } @keyframes fall { - 100% { - transform: translateY(200vh); } } + 100% { + transform: translateY(200vh); } } @keyframes gradientBG { - 0% { - transform: translate(-10%, -10%); } - 50% { - transform: translate(-60%, -60%); } - 100% { - transform: translate(-10%, -10%); } } + 0% { + transform: translate(-10%, -10%); } + 50% { + transform: translate(-60%, -60%); } + 100% { + transform: translate(-10%, -10%); } } @keyframes sled { - 0% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 4% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 20% { - transform: translate(50vw, 10vh) rotate(20deg); } - 36% { - transform: translate(150vw, 40vh) rotate(40deg); } - 100% { - transform: translate(150vw, 40vh) rotate(40deg); } } + 0% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 4% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 20% { + transform: translate(50vw, 10vh) rotate(20deg); } + 36% { + transform: translate(150vw, 40vh) rotate(40deg); } + 100% { + transform: translate(150vw, 40vh) rotate(40deg); } } @keyframes train { - 0% { - transform: translateX(-80rem); } - 55% { - transform: translateX(-80rem); } - 85% { - transform: translateX(100vw); } - 100% { - transform: translateX(100vw); } } + 0% { + transform: translateX(-80rem); } + 55% { + transform: translateX(-80rem); } + 85% { + transform: translateX(100vw); } + 100% { + transform: translateX(100vw); } } @keyframes follow_train { - 0% { - transform: translateX(-80rem) scaleX(20) scaleY(8); } - 55% { - transform: translateX(-80rem) scaleX(20) scaleY(8); } - 85% { - transform: translateX(100vw) scaleX(20) scaleY(8); } - 100% { - transform: translateX(100vw) scaleX(20) scaleY(8); } } + 0% { + transform: translateX(-80rem) scaleX(20) scaleY(8); } + 55% { + transform: translateX(-80rem) scaleX(20) scaleY(8); } + 85% { + transform: translateX(100vw) scaleX(20) scaleY(8); } + 100% { + transform: translateX(100vw) scaleX(20) scaleY(8); } } @keyframes turn { - 100% { - transform: rotate(360deg); } } + 100% { + transform: rotate(360deg); } } @keyframes whobble { - 100% { - transform: translateY(0.5vh); } } + 100% { + transform: translateY(0.5vh); } } @keyframes snowman { - 0% { - transform: rotate(0); } - 20% { - transform: rotate(0); } - 30% { - transform: rotate(80deg); } - 54% { - transform: rotate(80deg); } - 68% { - transform: rotate(0); } - 100% { - transform: rotate(0); } } + 0% { + transform: rotate(0); } + 20% { + transform: rotate(0); } + 30% { + transform: rotate(80deg); } + 54% { + transform: rotate(80deg); } + 68% { + transform: rotate(0); } + 100% { + transform: rotate(0); } } @keyframes snowman_head { - 0% { - transform: rotate(-3deg); } - 50% { - transform: rotate(3deg); } - 100% { - transform: rotate(-3deg); } } + 0% { + transform: rotate(-3deg); } + 50% { + transform: rotate(3deg); } + 100% { + transform: rotate(-3deg); } } @keyframes merry_christmas { - 0% { - opacity: 0.8; } - 50% { - opacity: 0.6; } - 100% { - opacity: 0.8; } } + 0% { + opacity: 0.8; } + 50% { + opacity: 0.6; } + 100% { + opacity: 0.8; } } /*# sourceMappingURL=kerstmis.css.map */ diff --git a/app/static/css/themes/highPerformance/kerstmis.scss b/app/static/css/themes/highPerformance/kerstmis.scss index 62c10c8..d6d390c 100644 --- a/app/static/css/themes/highPerformance/kerstmis.scss +++ b/app/static/css/themes/highPerformance/kerstmis.scss @@ -20,71 +20,71 @@ Enige discretie is aangeraden. --dGray4:#274001; --dGray5:#274001; --dGray6:#F2778D; - --dBlue:#F2778D; - } - body{ - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; - } - @font-face { + --dBlue:#F2778D; + } + body{ + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; + } + @font-face { font-family: Radikal; src: url('static/fonts/radikal_regular.ttf'); font-weight: normal; } - @font-face { + @font-face { font-family: Radikal; src: url('static/fonts/radikal_light.ttf'); font-weight: 200; - } - @font-face { + } + @font-face { font-family: Radikal; src: url('static/fonts/radikal_medium.ttf'); font-weight: medium; - } - @font-face { + } + @font-face { font-family: Radikal; src: url('static/fonts/radikal_bold.ttf'); font-weight: bold; - } - .btn{ - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg,#F53030, #F58B9E); - } + } + .btn{ + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg,#F53030, #F58B9E); + } - .btn:hover{ + .btn:hover{ background-image: linear-gradient(-40deg, #A81111, #FF4B33); - } - .navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; + } + .navbar { + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; background-color: transparent; -webkit-box-shadow: none; box-shadow: none; text-transform: capitalize; - } - .nav>li>a { - padding-left: 1vw; - padding-right: 1vw; - } + } + .nav>li>a { + padding-left: 1vw; + padding-right: 1vw; + } - .main{ - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; - } + .main{ + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; + } - .navbar .container{ - width: 100%; - padding: 0 4vw; - } + .navbar .container{ + width: 100%; + padding: 0 4vw; + } @media (min-width: 768px){ .container { @@ -99,143 +99,143 @@ Enige discretie is aangeraden. @media (min-width: 1200px){ .main .container, .main .orders { - width: 1170px; + width: 1170px; } } - .main{ - padding-top: 2.5rem; - } - .order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; - } - .order_row { + .main{ + padding-top: 2.5rem; + } + .order_data { + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; + } + .order_row { background: transparent; - } - .order_data h5{ - max-width: 60%; - padding-bottom: 3rem; - } - .expand_button{ - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; - } + } + .order_data h5{ + max-width: 60%; + padding-bottom: 3rem; + } + .expand_button{ + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; + } - .hi_im_haldis h2{ - display: none; - } + .hi_im_haldis h2{ + display: none; + } - .hi_im_haldis h3 { + .hi_im_haldis h3 { width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; text-align: center; - } + } - .hi_im_haldis { + .hi_im_haldis { background: linear-gradient(70deg,rgba(203, 52, 68,0.8), rgba(135, 32, 44,0.8)); border-radius: 0; - width: 100%; - } + width: 100%; + } - .hi_im_haldis_wrapper { - width: 100%; - } - .darker:nth-child(even){ + .hi_im_haldis_wrapper { + width: 100%; + } + .darker:nth-child(even){ background-color: #B62937; border-radius: 2rem; - } - .darker:nth-child(odd){ + } + .darker:nth-child(odd){ background-color: #821C25; border-radius: 2rem; - } - .darker{ - padding: 1rem; - } - .order_row:nth-child(even) .order_data { + } + .darker{ + padding: 1rem; + } + .order_row:nth-child(even) .order_data { background-color: #B62937; border-radius: 2rem; - } - .order_row:nth-child(odd) .order_data { + } + .order_row:nth-child(odd) .order_data { background-color: #821C25; border-radius: 2rem; - } + } - .order_row h5{ - font-weight: bold; - } - .order_row{ - margin-bottom: 3rem; - } - h3{ - padding-bottom: 1rem; - } + .order_row h5{ + font-weight: bold; + } + .order_row{ + margin-bottom: 3rem; + } + h3{ + padding-bottom: 1rem; + } - .home_sir { - font-weight: bold; - color: #F45D68; - } + .home_sir { + font-weight: bold; + color: #F45D68; + } - .expand_button_wrapper{ - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; - } + .expand_button_wrapper{ + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; + } - .time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; - } - - .navbar .navbar-nav .active a{ - color: rgb(255, 155, 174); - border-bottom: 1px solid rgb(255, 155, 174); - padding-bottom: 1rem; - } + .time_data { + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; + } - .navbar-nav{ - padding-left: 2rem; - } + .navbar .navbar-nav .active a{ + color: rgb(255, 155, 174); + border-bottom: 1px solid rgb(255, 155, 174); + padding-bottom: 1rem; + } - .jumbotron, .darker { + .navbar-nav{ + padding-left: 2rem; + } + + .jumbotron, .darker { display: flex; - flex-direction: column; - border-radius: 4rem; - } + flex-direction: column; + border-radius: 4rem; + } - .row>div>h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; - } + .row>div>h5 { + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; + } - .row>div>.amount_of_orders{ - font-weight: lighter; - font-size: 1.6rem; - } - .row>div .time{ - font-weight: lighter; - } + .row>div>.amount_of_orders{ + font-weight: lighter; + font-size: 1.6rem; + } + .row>div .time{ + font-weight: lighter; + } - .jumbotron { + .jumbotron { background-color: transparent; } - - .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover{ + + .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover{ background-color: transparent; - } - - .background { + } + + .background { -webkit-filter: blur(0px) brightness(80%); -moz-filter: blur(0px) brightness(80%); -o-filter: blur(0px) brightness(80%); @@ -493,53 +493,53 @@ $s1:""; $s2:""; $s3:""; @for $i from 1 through 100 { - $s1: $s1 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; - $s2: $s2 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; - $s3: $s3 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; - @if $i < 100 { - $s1: $s1 + ","; - $s2: $s2 + ","; - $s3: $s3 + ","; - } + $s1: $s1 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; + $s2: $s2 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; + $s3: $s3 + random(1000)*0.1vw + " " + random(1000)*0.1vh + " " + 0 + " " + random(50)*-0.01rem + #fff; + @if $i < 100 { + $s1: $s1 + ","; + $s2: $s2 + ","; + $s3: $s3 + ","; + } } .snow { - border-radius: 50%; - opacity: 0.8; - position: absolute; - top:-100vh; - animation-name: fall; - animation-timing-function: linear; - animation-iteration-count: infinite; + border-radius: 50%; + opacity: 0.8; + position: absolute; + top:-100vh; + animation-name: fall; + animation-timing-function: linear; + animation-iteration-count: infinite; } .layer1 { - width: 1rem; - height: 1rem; - filter:blur(1.5px); - box-shadow: #{$s1}; - animation-duration: 18s; + width: 1rem; + height: 1rem; + filter:blur(1.5px); + box-shadow: #{$s1}; + animation-duration: 18s; } .layer1.a { - animation-delay: -9s; + animation-delay: -9s; } .layer2 { - width: 0.8rem; - height: 0.8rem; - filter:blur(3px); - box-shadow: #{$s2}; - animation-duration: 24s; + width: 0.8rem; + height: 0.8rem; + filter:blur(3px); + box-shadow: #{$s2}; + animation-duration: 24s; } .layer2.a { - animation-delay: -12s; + animation-delay: -12s; } .layer3 { - width: 0.6rem; - height: 0.6rem; - filter:blur(6px); - box-shadow: #{$s3}; - animation-duration: 30s; + width: 0.6rem; + height: 0.6rem; + filter:blur(6px); + box-shadow: #{$s3}; + animation-duration: 30s; } .layer3.a { - animation-delay: -15s; + animation-delay: -15s; } @keyframes fall { 100% {transform: translateY(200vh); } diff --git a/app/static/css/themes/highPerformance/lightmode.css b/app/static/css/themes/highPerformance/lightmode.css index 841e7e9..591e0ea 100644 --- a/app/static/css/themes/highPerformance/lightmode.css +++ b/app/static/css/themes/highPerformance/lightmode.css @@ -1,12 +1,12 @@ /*lightmode*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#444444; - --dGray1:#666666; - --dGray2:#212121; - --dGray3:#ffffff; - --dGray4:#f9f9f9; - --dGray5:#ffffff; - --dGray6:#ffffff; - --dBlue:#0A84FF; + --dGray1:#666666; + --dGray2:#212121; + --dGray3:#ffffff; + --dGray4:#f9f9f9; + --dGray5:#ffffff; + --dGray6:#ffffff; + --dBlue:#0A84FF; } diff --git a/app/static/css/themes/highPerformance/sinterklaas.css b/app/static/css/themes/highPerformance/sinterklaas.css index 66e8d40..6febc5f 100644 --- a/app/static/css/themes/highPerformance/sinterklaas.css +++ b/app/static/css/themes/highPerformance/sinterklaas.css @@ -1,16 +1,16 @@ /*sinterklaas*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#F2EB80; - --dGray1:#F2EF05; - --dGray2:#F2EF05; - --dGray3:#177EBF; - --dGray4:#0C6AA6; - --dGray5:#F20505; - --dGray6:#F50B00; - --dBlue:#35F546; + --dGray1:#F2EF05; + --dGray2:#F2EF05; + --dGray3:#177EBF; + --dGray4:#0C6AA6; + --dGray5:#F20505; + --dGray6:#F50B00; + --dBlue:#35F546; } .background{ - background-image: url("static/images/themes/sinterklaas/Sinterklaas.jpg"); -} \ No newline at end of file + background-image: url("static/images/themes/sinterklaas/Sinterklaas.jpg"); +} diff --git a/app/static/css/themes/lowPerformance/darkmode.css b/app/static/css/themes/lowPerformance/darkmode.css index 324f4a0..7a1dc46 100644 --- a/app/static/css/themes/lowPerformance/darkmode.css +++ b/app/static/css/themes/lowPerformance/darkmode.css @@ -1,12 +1,12 @@ /*Darkmode*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; -} \ No newline at end of file + --dGray1:#8E8E93; + --dGray2:#636366; + --dGray3:#48484A; + --dGray4:#3A3A3C; + --dGray5:#2C2C2E; + --dGray6:#1C1C1E; + --dBlue:#0A84FF; +} diff --git a/app/static/css/themes/lowPerformance/dataPrivacy.css b/app/static/css/themes/lowPerformance/dataPrivacy.css index cc063f7..b9c300c 100644 --- a/app/static/css/themes/lowPerformance/dataPrivacy.css +++ b/app/static/css/themes/lowPerformance/dataPrivacy.css @@ -1,4 +1,4 @@ .background { - background-image: url("https://kelder.zeus.ugent.be/webcam/video/mjpg.cgi?profileid=2"); - background-size: contain; -} \ No newline at end of file + background-image: url("https://kelder.zeus.ugent.be/webcam/video/mjpg.cgi?profileid=2"); + background-size: contain; +} diff --git a/app/static/css/themes/lowPerformance/halloween.css b/app/static/css/themes/lowPerformance/halloween.css index 580ed15..baa23d8 100644 --- a/app/static/css/themes/lowPerformance/halloween.css +++ b/app/static/css/themes/lowPerformance/halloween.css @@ -1,16 +1,16 @@ /*halloween*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#FFEB65; - --dGray1:#F28705; - --dGray2:#F25C05; - --dGray3:#F27405; - --dGray4:#8C3D0F; - --dGray5:#260101; - --dGray6:#260101; - --dBlue:#D91604; + --dGray1:#F28705; + --dGray2:#F25C05; + --dGray3:#F27405; + --dGray4:#8C3D0F; + --dGray5:#260101; + --dGray6:#260101; + --dBlue:#D91604; } .table-hover tbody tr:hover{ - background-image: url("static/images/themes/halloween/Halloween.jpeg"); -} \ No newline at end of file + background-image: url("static/images/themes/halloween/Halloween.jpeg"); +} diff --git a/app/static/css/themes/lowPerformance/kerstmis.css b/app/static/css/themes/lowPerformance/kerstmis.css index b0c6902..fce2b41 100644 --- a/app/static/css/themes/lowPerformance/kerstmis.css +++ b/app/static/css/themes/lowPerformance/kerstmis.css @@ -11,432 +11,432 @@ Enige discretie is aangeraden. */ /*low performance kerstmis*/ :root { - /*Darkmode colors*/ - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } + /*Darkmode colors*/ + --dGray0:#F28705; + --dGray1:white; + --dGray2:#590212; + --dGray3:#590212; + --dGray4:#274001; + --dGray5:#274001; + --dGray6:#F2778D; + --dBlue:#F2778D; } body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_regular.ttf"); - font-weight: normal; } + font-family: Radikal; + src: url("static/fonts/radikal_regular.ttf"); + font-weight: normal; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_light.ttf"); - font-weight: 200; } + font-family: Radikal; + src: url("static/fonts/radikal_light.ttf"); + font-weight: 200; } @font-face { - font-family: Radikal; - src: url("static/fonts/radikal_bold.ttf"); - font-weight: bold; } + font-family: Radikal; + src: url("static/fonts/radikal_bold.ttf"); + font-weight: bold; } .btn { - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg, #F53030, #F58B9E); } + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg, #F53030, #F58B9E); } .btn:hover { - background-image: linear-gradient(-40deg, #A81111, #FF4B33); } + background-image: linear-gradient(-40deg, #A81111, #FF4B33); } .navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - text-transform: capitalize; } + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + text-transform: capitalize; } .nav > li > a { - padding-left: 1vw; - padding-right: 1vw; } + padding-left: 1vw; + padding-right: 1vw; } .main { - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; } + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; } .navbar .container { - width: 100%; - padding: 0 4vw; } + width: 100%; + padding: 0 4vw; } @media (min-width: 768px) { - .container { - width: 100%; } } + .container { + width: 100%; } } @media (min-width: 992px) { - .main .container, .main .orders { - width: 970px; } } + .main .container, .main .orders { + width: 970px; } } @media (min-width: 1200px) { - .main .container, .main .orders { - width: 1170px; } } + .main .container, .main .orders { + width: 1170px; } } .main { - padding-top: 2.5rem; } + padding-top: 2.5rem; } .order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; } + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; } .order_data h5 { - max-width: 60%; - padding-bottom: 3rem; } + max-width: 60%; + padding-bottom: 3rem; } .expand_button { - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; } + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; } .hi_im_haldis h2 { - display: none; } + display: none; } .hi_im_haldis h3 { - width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - text-align: center; } + width: 100%; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + text-align: center; } .hi_im_haldis { - background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); - border-radius: 0; - width: 100%; } + background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); + border-radius: 0; + width: 100%; } .hi_im_haldis_wrapper { - width: 100%; } + width: 100%; } .darker:nth-child(even) { - background-color: #B62937; - border-radius: 2rem; } + background-color: #B62937; + border-radius: 2rem; } .darker:nth-child(odd) { - background-color: #821C25; - border-radius: 2rem; } + background-color: #821C25; + border-radius: 2rem; } .darker { - padding: 1rem; } + padding: 1rem; } .order_row:nth-child(even) .order_data { - background-color: #B62937; - border-radius: 2rem; } + background-color: #B62937; + border-radius: 2rem; } .order_row { - background: transparent; } + background: transparent; } .order_row:nth-child(odd) .order_data { - background-color: #821C25; - border-radius: 2rem; } + background-color: #821C25; + border-radius: 2rem; } .order_row h5 { - font-weight: bold; } + font-weight: bold; } .order_row { - margin-bottom: 3rem; } + margin-bottom: 3rem; } h3 { - padding-bottom: 1rem; } + padding-bottom: 1rem; } .home_sir { - font-weight: bold; - color: #F45D68; } + font-weight: bold; + color: #F45D68; } .expand_button_wrapper { - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; } + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; } .time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; } + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; } .navbar .navbar-nav .active a { - color: #ff9bae; - border-bottom: 1px solid #ff9bae; - padding-bottom: 1rem; } + color: #ff9bae; + border-bottom: 1px solid #ff9bae; + padding-bottom: 1rem; } .navbar-nav { - padding-left: 2rem; } + padding-left: 2rem; } .jumbotron, .darker { - display: flex; - flex-direction: column; - border-radius: 4rem; } + display: flex; + flex-direction: column; + border-radius: 4rem; } .row > div > h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; } + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; } .row > div > .amount_of_orders { - font-weight: lighter; - font-size: 1.6rem; } + font-weight: lighter; + font-size: 1.6rem; } .row > div .time { - font-weight: lighter; } + font-weight: lighter; } .jumbotron { - background-color: transparent; } + background-color: transparent; } .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { - background-color: transparent; } + background-color: transparent; } .background { - -webkit-filter: blur(0px) brightness(80%); - -moz-filter: blur(0px) brightness(80%); - -o-filter: blur(0px) brightness(80%); - -ms-filter: blur(0px) brightness(80%); - filter: blur(0px) brightness(80%); - position: fixed; - top: 0; - left: 0; } + -webkit-filter: blur(0px) brightness(80%); + -moz-filter: blur(0px) brightness(80%); + -o-filter: blur(0px) brightness(80%); + -ms-filter: blur(0px) brightness(80%); + filter: blur(0px) brightness(80%); + position: fixed; + top: 0; + left: 0; } footer a { - color: #69E8FF; } + color: #69E8FF; } footer { - position: fixed; - bottom: 0; - width: 100%; - background: #CB3444; - height: 5rem; - display: flex; - align-items: center; } + position: fixed; + bottom: 0; + width: 100%; + background: #CB3444; + height: 5rem; + display: flex; + align-items: center; } footer > hr { - display: none; } + display: none; } #mapid { - width: 100%; } + width: 100%; } .order_overview, .order_order, .order_items, .order_ordered, .order_depts { - padding: 1rem 5rem 3rem 5rem; } + padding: 1rem 5rem 3rem 5rem; } .order_overview { - width: 100%; } + width: 100%; } .order_depts { - width: 100%; - margin-bottom: 10rem; } + width: 100%; + margin-bottom: 10rem; } .location_data, .location_products { - width: 100%; } + width: 100%; } .location_products { - margin-bottom: 10rem; } + margin-bottom: 10rem; } .locations_locations { - padding: 1rem 5rem 3rem 5rem; } + padding: 1rem 5rem 3rem 5rem; } .background_wrapper { - position: absolute; - left: 0; - bottom: 5rem; - width: 100%; - height: 100%; - overflow: hidden; } + position: absolute; + left: 0; + bottom: 5rem; + width: 100%; + height: 100%; + overflow: hidden; } .christmas_background { - z-index: -101; - width: 300%; - height: 300%; - background: linear-gradient(-45deg, #2F0000, #C20A12); } + z-index: -101; + width: 300%; + height: 300%; + background: linear-gradient(-45deg, #2F0000, #C20A12); } .sled { - width: 15rem; - height: 15rem; - transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - background-image: url("static/images/themes/kerstmis/sled.svg"); } + width: 15rem; + height: 15rem; + transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + background-image: url("static/images/themes/kerstmis/sled.svg"); } .sled_wrapper { - top: 0.5rem; - left: -7.5rem; - position: absolute; - transform: translate(-50vw, 40vh) rotate(0deg); - width: 15rem; - height: 15rem; - animation: sled 29s ease-in-out infinite; } + top: 0.5rem; + left: -7.5rem; + position: absolute; + transform: translate(-50vw, 40vh) rotate(0deg); + width: 15rem; + height: 15rem; + animation: sled 29s ease-in-out infinite; } .snowman_wrapper { - height: 17rem; - width: 10rem; - position: absolute; - bottom: 15rem; - left: -12rem; - animation: snowman 37s ease infinite; - transform-origin: right bottom; } + height: 17rem; + width: 10rem; + position: absolute; + bottom: 15rem; + left: -12rem; + animation: snowman 37s ease infinite; + transform-origin: right bottom; } .snowman_head { - position: absolute; - top: 0; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_head.svg"); - animation: snowman_head 2s ease infinite; } + position: absolute; + top: 0; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_head.svg"); + animation: snowman_head 2s ease infinite; } .snowman_body { - position: absolute; - top: 9.5rem; - left: 0.5rem; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } + position: absolute; + top: 9.5rem; + left: 0.5rem; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } .train_button { - visibility: hidden; } + visibility: hidden; } .train_wrapper { - position: absolute; - bottom: 0.5rem; - transform: translateX(-80vw); - animation: train 47s linear infinite; } + position: absolute; + bottom: 0.5rem; + transform: translateX(-80vw); + animation: train 47s linear infinite; } .wheel_big, .wheel_small { - position: absolute; - bottom: -0.4rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/wheel.svg"); } + position: absolute; + bottom: -0.4rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/wheel.svg"); } .train { - position: absolute; - bottom: 0.5rem; - left: 30rem; - width: 30rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/train.svg"); - animation: whobble 1s linear alternate-reverse infinite; } + position: absolute; + bottom: 0.5rem; + left: 30rem; + width: 30rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/train.svg"); + animation: whobble 1s linear alternate-reverse infinite; } .wheel_big { - width: 3.2rem; - height: 3.2rem; } + width: 3.2rem; + height: 3.2rem; } .wheel_small { - width: 2.5rem; - height: 2.5rem; } + width: 2.5rem; + height: 2.5rem; } .train .wheel1 { - animation: turn 2s linear infinite; - left: 3.5rem; } + animation: turn 2s linear infinite; + left: 3.5rem; } .train .wheel2 { - animation: turn 2s linear infinite, -0.1s; - left: 7rem; } + animation: turn 2s linear infinite, -0.1s; + left: 7rem; } .train .wheel3 { - animation: turn 2s linear infinite -0.3s; - left: 10.5rem; } + animation: turn 2s linear infinite -0.3s; + left: 10.5rem; } .train .wheel4 { - animation: turn 1.5s linear infinite -0.5s; - left: 13.9rem; } + animation: turn 1.5s linear infinite -0.5s; + left: 13.9rem; } .train .wheel5 { - animation: turn 1.5s linear infinite -0.7s; - left: 16.6rem; } + animation: turn 1.5s linear infinite -0.7s; + left: 16.6rem; } .zeus_wagon, .mc_wagon { - position: absolute; - bottom: 1.25rem; - width: 30rem; - height: 7.5rem; - background-repeat: no-repeat; - background-size: contain; - animation: whobble 1s linear alternate-reverse infinite; } + position: absolute; + bottom: 1.25rem; + width: 30rem; + height: 7.5rem; + background-repeat: no-repeat; + background-size: contain; + animation: whobble 1s linear alternate-reverse infinite; } .mc_wagon { - background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); - left: 0rem; } + background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); + left: 0rem; } .zeus_wagon { - background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); - left: 15rem; } + background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); + left: 15rem; } .zeus_wagon .wheel1, .mc_wagon .wheel1 { - animation: turn 2s linear infinite; - bottom: -1.1rem; - left: 2.2rem; } + animation: turn 2s linear infinite; + bottom: -1.1rem; + left: 2.2rem; } .zeus_wagon .wheel2, .mc_wagon .wheel2 { - animation: turn 2s linear infinite, -0.1s; - bottom: -1.1rem; - left: 5.75rem; } + animation: turn 2s linear infinite, -0.1s; + bottom: -1.1rem; + left: 5.75rem; } .zeus_wagon .wheel3, .mc_wagon .wheel3 { - animation: turn 2s linear infinite -0.3s; - bottom: -1.1rem; - left: 9.3rem; } + animation: turn 2s linear infinite -0.3s; + bottom: -1.1rem; + left: 9.3rem; } @keyframes sled { - 0% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 4% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 20% { - transform: translate(50vw, 10vh) rotate(20deg); } - 36% { - transform: translate(150vw, 40vh) rotate(40deg); } - 100% { - transform: translate(150vw, 40vh) rotate(40deg); } } + 0% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 4% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 20% { + transform: translate(50vw, 10vh) rotate(20deg); } + 36% { + transform: translate(150vw, 40vh) rotate(40deg); } + 100% { + transform: translate(150vw, 40vh) rotate(40deg); } } @keyframes train { - 0% { - transform: translateX(-80rem); } - 55% { - transform: translateX(-80rem); } - 85% { - transform: translateX(100vw); } - 100% { - transform: translateX(100vw); } } + 0% { + transform: translateX(-80rem); } + 55% { + transform: translateX(-80rem); } + 85% { + transform: translateX(100vw); } + 100% { + transform: translateX(100vw); } } @keyframes turn { - 100% { - transform: rotate(360deg); } } + 100% { + transform: rotate(360deg); } } @keyframes whobble { - 100% { - transform: translateY(0.5vh); } } + 100% { + transform: translateY(0.5vh); } } @keyframes snowman { - 0% { - transform: rotate(0); } - 20% { - transform: rotate(0); } - 30% { - transform: rotate(80deg); } - 54% { - transform: rotate(80deg); } - 68% { - transform: rotate(0); } - 100% { - transform: rotate(0); } } + 0% { + transform: rotate(0); } + 20% { + transform: rotate(0); } + 30% { + transform: rotate(80deg); } + 54% { + transform: rotate(80deg); } + 68% { + transform: rotate(0); } + 100% { + transform: rotate(0); } } @keyframes snowman_head { - 0% { - transform: rotate(-3deg); } - 50% { - transform: rotate(3deg); } - 100% { - transform: rotate(-3deg); } } + 0% { + transform: rotate(-3deg); } + 50% { + transform: rotate(3deg); } + 100% { + transform: rotate(-3deg); } } /*# sourceMappingURL=kerstmis.css.map */ diff --git a/app/static/css/themes/lowPerformance/kerstmis.scss b/app/static/css/themes/lowPerformance/kerstmis.scss index 9831784..bc6c735 100644 --- a/app/static/css/themes/lowPerformance/kerstmis.scss +++ b/app/static/css/themes/lowPerformance/kerstmis.scss @@ -20,66 +20,66 @@ Enige discretie is aangeraden. --dGray4:#274001; --dGray5:#274001; --dGray6:#F2778D; - --dBlue:#F2778D; - } - body{ - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; - } - @font-face { + --dBlue:#F2778D; + } + body{ + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; + } + @font-face { font-family: Radikal; src: url('static/fonts/radikal_regular.ttf'); font-weight: normal; } - @font-face { + @font-face { font-family: Radikal; src: url('static/fonts/radikal_light.ttf'); font-weight: 200; - } - @font-face { + } + @font-face { font-family: Radikal; src: url('static/fonts/radikal_bold.ttf'); font-weight: bold; - } - .btn{ - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg,#F53030, #F58B9E); - } + } + .btn{ + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg,#F53030, #F58B9E); + } - .btn:hover{ + .btn:hover{ background-image: linear-gradient(-40deg, #A81111, #FF4B33); - } - .navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; + } + .navbar { + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; background-color: transparent; -webkit-box-shadow: none; box-shadow: none; text-transform: capitalize; - } - .nav>li>a { - padding-left: 1vw; - padding-right: 1vw; - } + } + .nav>li>a { + padding-left: 1vw; + padding-right: 1vw; + } - .main{ - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; - } + .main{ + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; + } - .navbar .container{ - width: 100%; - padding: 0 4vw; - } + .navbar .container{ + width: 100%; + padding: 0 4vw; + } @media (min-width: 768px){ .container { @@ -94,145 +94,145 @@ Enige discretie is aangeraden. @media (min-width: 1200px){ .main .container, .main .orders { - width: 1170px; + width: 1170px; } } - .main{ - padding-top: 2.5rem; - } - .order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; - } - .order_data h5{ - max-width: 60%; - padding-bottom: 3rem; - } - .expand_button{ - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; - } + .main{ + padding-top: 2.5rem; + } + .order_data { + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; + } + .order_data h5{ + max-width: 60%; + padding-bottom: 3rem; + } + .expand_button{ + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; + } - .hi_im_haldis h2{ - display: none; - } + .hi_im_haldis h2{ + display: none; + } - .hi_im_haldis h3 { + .hi_im_haldis h3 { width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; text-align: center; - } + } - .hi_im_haldis { + .hi_im_haldis { background: linear-gradient(70deg,rgba(203, 52, 68,0.8), rgba(135, 32, 44,0.8)); border-radius: 0; - width: 100%; - } + width: 100%; + } - .hi_im_haldis_wrapper { - width: 100%; - } - .darker:nth-child(even){ + .hi_im_haldis_wrapper { + width: 100%; + } + .darker:nth-child(even){ background-color: #B62937; border-radius: 2rem; - } - .darker:nth-child(odd){ + } + .darker:nth-child(odd){ background-color: #821C25; border-radius: 2rem; - } - .darker{ - padding: 1rem; - } - .order_row:nth-child(even) .order_data { + } + .darker{ + padding: 1rem; + } + .order_row:nth-child(even) .order_data { background-color: #B62937; border-radius: 2rem; - } + } - .order_row { + .order_row { background: transparent; - } + } - .order_row:nth-child(odd) .order_data { + .order_row:nth-child(odd) .order_data { background-color: #821C25; border-radius: 2rem; - } + } - .order_row h5{ - font-weight: bold; - } - .order_row{ - margin-bottom: 3rem; - } - h3{ - padding-bottom: 1rem; - } + .order_row h5{ + font-weight: bold; + } + .order_row{ + margin-bottom: 3rem; + } + h3{ + padding-bottom: 1rem; + } - .home_sir { - font-weight: bold; - color: #F45D68; - } + .home_sir { + font-weight: bold; + color: #F45D68; + } - .expand_button_wrapper{ - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; - } + .expand_button_wrapper{ + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; + } - .time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; - } - - .navbar .navbar-nav .active a{ - color: rgb(255, 155, 174); - border-bottom: 1px solid rgb(255, 155, 174); - padding-bottom: 1rem; - } + .time_data { + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; + } - .navbar-nav{ - padding-left: 2rem; - } + .navbar .navbar-nav .active a{ + color: rgb(255, 155, 174); + border-bottom: 1px solid rgb(255, 155, 174); + padding-bottom: 1rem; + } - .jumbotron, .darker { + .navbar-nav{ + padding-left: 2rem; + } + + .jumbotron, .darker { display: flex; - flex-direction: column; - border-radius: 4rem; - } + flex-direction: column; + border-radius: 4rem; + } - .row>div>h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; - } + .row>div>h5 { + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; + } - .row>div>.amount_of_orders{ - font-weight: lighter; - font-size: 1.6rem; - } - .row>div .time{ - font-weight: lighter; - } + .row>div>.amount_of_orders{ + font-weight: lighter; + font-size: 1.6rem; + } + .row>div .time{ + font-weight: lighter; + } - .jumbotron { + .jumbotron { background-color: transparent; } - - .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover{ + + .navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover{ background-color: transparent; - } - - .background { + } + + .background { -webkit-filter: blur(0px) brightness(80%); -moz-filter: blur(0px) brightness(80%); -o-filter: blur(0px) brightness(80%); diff --git a/app/static/css/themes/lowPerformance/lightmode.css b/app/static/css/themes/lowPerformance/lightmode.css index 841e7e9..591e0ea 100644 --- a/app/static/css/themes/lowPerformance/lightmode.css +++ b/app/static/css/themes/lowPerformance/lightmode.css @@ -1,12 +1,12 @@ /*lightmode*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#444444; - --dGray1:#666666; - --dGray2:#212121; - --dGray3:#ffffff; - --dGray4:#f9f9f9; - --dGray5:#ffffff; - --dGray6:#ffffff; - --dBlue:#0A84FF; + --dGray1:#666666; + --dGray2:#212121; + --dGray3:#ffffff; + --dGray4:#f9f9f9; + --dGray5:#ffffff; + --dGray6:#ffffff; + --dBlue:#0A84FF; } diff --git a/app/static/css/themes/lowPerformance/sinterklaas.css b/app/static/css/themes/lowPerformance/sinterklaas.css index 66e8d40..6febc5f 100644 --- a/app/static/css/themes/lowPerformance/sinterklaas.css +++ b/app/static/css/themes/lowPerformance/sinterklaas.css @@ -1,16 +1,16 @@ /*sinterklaas*/ :root { - /*Darkmode colors*/ + /*Darkmode colors*/ --dGray0:#F2EB80; - --dGray1:#F2EF05; - --dGray2:#F2EF05; - --dGray3:#177EBF; - --dGray4:#0C6AA6; - --dGray5:#F20505; - --dGray6:#F50B00; - --dBlue:#35F546; + --dGray1:#F2EF05; + --dGray2:#F2EF05; + --dGray3:#177EBF; + --dGray4:#0C6AA6; + --dGray5:#F20505; + --dGray6:#F50B00; + --dBlue:#35F546; } .background{ - background-image: url("static/images/themes/sinterklaas/Sinterklaas.jpg"); -} \ No newline at end of file + background-image: url("static/images/themes/sinterklaas/Sinterklaas.jpg"); +} diff --git a/app/static/fonts/glyphicons-halflings-regular.svg b/app/static/fonts/glyphicons-halflings-regular.svg index 94fb549..187805a 100644 --- a/app/static/fonts/glyphicons-halflings-regular.svg +++ b/app/static/fonts/glyphicons-halflings-regular.svg @@ -285,4 +285,4 @@ - \ No newline at end of file + diff --git a/app/static/js/bootstrap-datetimepicker.min.js b/app/static/js/bootstrap-datetimepicker.min.js index a60af89..3ef24ea 100755 --- a/app/static/js/bootstrap-datetimepicker.min.js +++ b/app/static/js/bootstrap-datetimepicker.min.js @@ -1,8 +1,8 @@ /*! version : 4.7.14 - ========================================================= - bootstrap-datetimejs - https://github.com/Eonasdan/bootstrap-datetimepicker - Copyright (c) 2015 Jonathan Peterson - ========================================================= - */ -!function(a){"use strict";if("function"==typeof define&&define.amd)define(["jquery","moment"],a);else if("object"==typeof exports)a(require("jquery"),require("moment"));else{if("undefined"==typeof jQuery)throw"bootstrap-datetimepicker requires jQuery to be loaded first";if("undefined"==typeof moment)throw"bootstrap-datetimepicker requires Moment.js to be loaded first";a(jQuery,moment)}}(function(a,b){"use strict";if(!b)throw new Error("bootstrap-datetimepicker requires Moment.js to be loaded first");var c=function(c,d){var e,f,g,h,i,j={},k=b().startOf("d"),l=k.clone(),m=!0,n=!1,o=!1,p=0,q=[{clsName:"days",navFnc:"M",navStep:1},{clsName:"months",navFnc:"y",navStep:1},{clsName:"years",navFnc:"y",navStep:10}],r=["days","months","years"],s=["top","bottom","auto"],t=["left","right","auto"],u=["default","top","bottom"],v={up:38,38:"up",down:40,40:"down",left:37,37:"left",right:39,39:"right",tab:9,9:"tab",escape:27,27:"escape",enter:13,13:"enter",pageUp:33,33:"pageUp",pageDown:34,34:"pageDown",shift:16,16:"shift",control:17,17:"control",space:32,32:"space",t:84,84:"t","delete":46,46:"delete"},w={},x=function(a){if("string"!=typeof a||a.length>1)throw new TypeError("isEnabled expects a single character string parameter");switch(a){case"y":return-1!==g.indexOf("Y");case"M":return-1!==g.indexOf("M");case"d":return-1!==g.toLowerCase().indexOf("d");case"h":case"H":return-1!==g.toLowerCase().indexOf("h");case"m":return-1!==g.indexOf("m");case"s":return-1!==g.indexOf("s");default:return!1}},y=function(){return x("h")||x("m")||x("s")},z=function(){return x("y")||x("M")||x("d")},A=function(){var b=a("").append(a("").append(a("").addClass("prev").attr("data-action","previous").append(a("").addClass(d.icons.previous))).append(a("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",d.calendarWeeks?"6":"5")).append(a("").addClass("next").attr("data-action","next").append(a("").addClass(d.icons.next)))),c=a("").append(a("").append(a("").attr("colspan",d.calendarWeeks?"8":"7")));return[a("
").addClass("datepicker-days").append(a("").addClass("table-condensed").append(b).append(a(""))),a("
").addClass("datepicker-months").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone())),a("
").addClass("datepicker-years").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone()))]},B=function(){var b=a(""),c=a(""),e=a("");return x("h")&&(b.append(a("
").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementHours").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-hour").attr("data-time-component","hours").attr("data-action","showHours"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementHours").append(a("").addClass(d.icons.down))))),x("m")&&(x("h")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementMinutes").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-minute").attr("data-time-component","minutes").attr("data-action","showMinutes"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementMinutes").append(a("").addClass(d.icons.down))))),x("s")&&(x("m")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementSeconds").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-second").attr("data-time-component","seconds").attr("data-action","showSeconds"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementSeconds").append(a("").addClass(d.icons.down))))),f||(b.append(a("").addClass("separator")),c.append(a("").append(a("").addClass("separator"))),a("
").addClass("timepicker-picker").append(a("").addClass("table-condensed").append([b,c,e]))},C=function(){var b=a("
").addClass("timepicker-hours").append(a("
").addClass("table-condensed")),c=a("
").addClass("timepicker-minutes").append(a("
").addClass("table-condensed")),d=a("
").addClass("timepicker-seconds").append(a("
").addClass("table-condensed")),e=[B()];return x("h")&&e.push(b),x("m")&&e.push(c),x("s")&&e.push(d),e},D=function(){var b=[];return d.showTodayButton&&b.push(a("
").append(a("").attr("data-action","today").append(a("").addClass(d.icons.today)))),!d.sideBySide&&z()&&y()&&b.push(a("").append(a("").attr("data-action","togglePicker").append(a("").addClass(d.icons.time)))),d.showClear&&b.push(a("").append(a("").attr("data-action","clear").append(a("").addClass(d.icons.clear)))),d.showClose&&b.push(a("").append(a("").attr("data-action","close").append(a("").addClass(d.icons.close)))),a("").addClass("table-condensed").append(a("").append(a("").append(b)))},E=function(){var b=a("
").addClass("bootstrap-datetimepicker-widget dropdown-menu"),c=a("
").addClass("datepicker").append(A()),e=a("
").addClass("timepicker").append(C()),g=a("
    ").addClass("list-unstyled"),h=a("
  • ").addClass("picker-switch"+(d.collapse?" accordion-toggle":"")).append(D());return d.inline&&b.removeClass("dropdown-menu"),f&&b.addClass("usetwentyfour"),d.sideBySide&&z()&&y()?(b.addClass("timepicker-sbs"),b.append(a("
    ").addClass("row").append(c.addClass("col-sm-6")).append(e.addClass("col-sm-6"))),b.append(h),b):("top"===d.toolbarPlacement&&g.append(h),z()&&g.append(a("
  • ").addClass(d.collapse&&y()?"collapse in":"").append(c)),"default"===d.toolbarPlacement&&g.append(h),y()&&g.append(a("
  • ").addClass(d.collapse&&z()?"collapse":"").append(e)),"bottom"===d.toolbarPlacement&&g.append(h),b.append(g))},F=function(){var b,e={};return b=c.is("input")||d.inline?c.data():c.find("input").data(),b.dateOptions&&b.dateOptions instanceof Object&&(e=a.extend(!0,e,b.dateOptions)),a.each(d,function(a){var c="date"+a.charAt(0).toUpperCase()+a.slice(1);void 0!==b[c]&&(e[a]=b[c])}),e},G=function(){var b,e=(n||c).position(),f=(n||c).offset(),g=d.widgetPositioning.vertical,h=d.widgetPositioning.horizontal;if(d.widgetParent)b=d.widgetParent.append(o);else if(c.is("input"))b=c.parent().append(o);else{if(d.inline)return void(b=c.append(o));b=c,c.children().first().after(o)}if("auto"===g&&(g=f.top+1.5*o.height()>=a(window).height()+a(window).scrollTop()&&o.height()+c.outerHeight()a(window).width()?"right":"left"),"top"===g?o.addClass("top").removeClass("bottom"):o.addClass("bottom").removeClass("top"),"right"===h?o.addClass("pull-right"):o.removeClass("pull-right"),"relative"!==b.css("position")&&(b=b.parents().filter(function(){return"relative"===a(this).css("position")}).first()),0===b.length)throw new Error("datetimepicker component should be placed within a relative positioned container");o.css({top:"top"===g?"auto":e.top+c.outerHeight(),bottom:"top"===g?e.top+c.outerHeight():"auto",left:"left"===h?b.css("padding-left"):"auto",right:"left"===h?"auto":b.width()-c.outerWidth()})},H=function(a){"dp.change"===a.type&&(a.date&&a.date.isSame(a.oldDate)||!a.date&&!a.oldDate)||c.trigger(a)},I=function(a){o&&(a&&(i=Math.max(p,Math.min(2,i+a))),o.find(".datepicker > div").hide().filter(".datepicker-"+q[i].clsName).show())},J=function(){var b=a("
"),c=l.clone().startOf("w");for(d.calendarWeeks===!0&&b.append(a(""),d.calendarWeeks&&e.append('"),i.push(e)),f="",c.isBefore(l,"M")&&(f+=" old"),c.isAfter(l,"M")&&(f+=" new"),c.isSame(k,"d")&&!m&&(f+=" active"),M(c,"d")||(f+=" disabled"),c.isSame(b(),"d")&&(f+=" today"),(0===c.day()||6===c.day())&&(f+=" weekend"),e.append('"),c.add(1,"d");g.find("tbody").empty().append(i),O(),P()}},R=function(){var b=o.find(".timepicker-hours table"),c=l.clone().startOf("d"),d=[],e=a("");for(l.hour()>11&&!f&&c.hour(12);c.isSame(l,"d")&&(f||l.hour()<12&&c.hour()<12||l.hour()>11);)c.hour()%4===0&&(e=a(""),d.push(e)),e.append('"),c.add(1,"h");b.empty().append(d)},S=function(){for(var b=o.find(".timepicker-minutes table"),c=l.clone().startOf("h"),e=[],f=a(""),g=1===d.stepping?5:d.stepping;l.isSame(c,"h");)c.minute()%(4*g)===0&&(f=a(""),e.push(f)),f.append('"),c.add(g,"m");b.empty().append(e)},T=function(){for(var b=o.find(".timepicker-seconds table"),c=l.clone().startOf("m"),d=[],e=a("");l.isSame(c,"m");)c.second()%20===0&&(e=a(""),d.push(e)),e.append('"),c.add(5,"s");b.empty().append(d)},U=function(){var a=o.find(".timepicker span[data-time-component]");f||o.find(".timepicker [data-action=togglePeriod]").text(k.format("A")),a.filter("[data-time-component=hours]").text(k.format(f?"HH":"hh")),a.filter("[data-time-component=minutes]").text(k.format("mm")),a.filter("[data-time-component=seconds]").text(k.format("ss")),R(),S(),T()},V=function(){o&&(Q(),U())},W=function(a){var b=m?null:k;return a?(a=a.clone().locale(d.locale),1!==d.stepping&&a.minutes(Math.round(a.minutes()/d.stepping)*d.stepping%60).seconds(0),void(M(a)?(k=a,l=k.clone(),e.val(k.format(g)),c.data("date",k.format(g)),V(),m=!1,H({type:"dp.change",date:k.clone(),oldDate:b})):(d.keepInvalid||e.val(m?"":k.format(g)),H({type:"dp.error",date:a})))):(m=!0,e.val(""),c.data("date",""),H({type:"dp.change",date:null,oldDate:b}),void V())},X=function(){var b=!1;return o?(o.find(".collapse").each(function(){var c=a(this).data("collapse");return c&&c.transitioning?(b=!0,!1):!0}),b?j:(n&&n.hasClass("btn")&&n.toggleClass("active"),o.hide(),a(window).off("resize",G),o.off("click","[data-action]"),o.off("mousedown",!1),o.remove(),o=!1,H({type:"dp.hide",date:k.clone()}),j)):j},Y=function(){W(null)},Z={next:function(){l.add(q[i].navStep,q[i].navFnc),Q()},previous:function(){l.subtract(q[i].navStep,q[i].navFnc),Q()},pickerSwitch:function(){I(1)},selectMonth:function(b){var c=a(b.target).closest("tbody").find("span").index(a(b.target));l.month(c),i===p?(W(k.clone().year(l.year()).month(l.month())),d.inline||X()):(I(-1),Q())},selectYear:function(b){var c=parseInt(a(b.target).text(),10)||0;l.year(c),i===p?(W(k.clone().year(l.year())),d.inline||X()):(I(-1),Q())},selectDay:function(b){var c=l.clone();a(b.target).is(".old")&&c.subtract(1,"M"),a(b.target).is(".new")&&c.add(1,"M"),W(c.date(parseInt(a(b.target).text(),10))),y()||d.keepOpen||d.inline||X()},incrementHours:function(){W(k.clone().add(1,"h"))},incrementMinutes:function(){W(k.clone().add(d.stepping,"m"))},incrementSeconds:function(){W(k.clone().add(1,"s"))},decrementHours:function(){W(k.clone().subtract(1,"h"))},decrementMinutes:function(){W(k.clone().subtract(d.stepping,"m"))},decrementSeconds:function(){W(k.clone().subtract(1,"s"))},togglePeriod:function(){W(k.clone().add(k.hours()>=12?-12:12,"h"))},togglePicker:function(b){var c,e=a(b.target),f=e.closest("ul"),g=f.find(".in"),h=f.find(".collapse:not(.in)");if(g&&g.length){if(c=g.data("collapse"),c&&c.transitioning)return;g.collapse?(g.collapse("hide"),h.collapse("show")):(g.removeClass("in"),h.addClass("in")),e.is("span")?e.toggleClass(d.icons.time+" "+d.icons.date):e.find("span").toggleClass(d.icons.time+" "+d.icons.date)}},showPicker:function(){o.find(".timepicker > div:not(.timepicker-picker)").hide(),o.find(".timepicker .timepicker-picker").show()},showHours:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-hours").show()},showMinutes:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-minutes").show()},showSeconds:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-seconds").show()},selectHour:function(b){var c=parseInt(a(b.target).text(),10);f||(k.hours()>=12?12!==c&&(c+=12):12===c&&(c=0)),W(k.clone().hours(c)),Z.showPicker.call(j)},selectMinute:function(b){W(k.clone().minutes(parseInt(a(b.target).text(),10))),Z.showPicker.call(j)},selectSecond:function(b){W(k.clone().seconds(parseInt(a(b.target).text(),10))),Z.showPicker.call(j)},clear:Y,today:function(){W(b())},close:X},$=function(b){return a(b.currentTarget).is(".disabled")?!1:(Z[a(b.currentTarget).data("action")].apply(j,arguments),!1)},_=function(){var c,f={year:function(a){return a.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(a){return a.date(1).hours(0).seconds(0).minutes(0)},day:function(a){return a.hours(0).seconds(0).minutes(0)},hour:function(a){return a.seconds(0).minutes(0)},minute:function(a){return a.seconds(0)}};return e.prop("disabled")||!d.ignoreReadonly&&e.prop("readonly")||o?j:(d.useCurrent&&m&&(e.is("input")&&0===e.val().trim().length||d.inline)&&(c=b(),"string"==typeof d.useCurrent&&(c=f[d.useCurrent](c)),W(c)),o=E(),J(),N(),o.find(".timepicker-hours").hide(),o.find(".timepicker-minutes").hide(),o.find(".timepicker-seconds").hide(),V(),I(),a(window).on("resize",G),o.on("click","[data-action]",$),o.on("mousedown",!1),n&&n.hasClass("btn")&&n.toggleClass("active"),o.show(),G(),e.is(":focus")||e.focus(),H({type:"dp.show"}),j)},ab=function(){return o?X():_()},bb=function(a){return a=b.isMoment(a)||a instanceof Date?b(a):b(a,h,d.useStrict),a.locale(d.locale),a},cb=function(a){var b,c,e,f,g=null,h=[],i={},k=a.which,l="p";w[k]=l;for(b in w)w.hasOwnProperty(b)&&w[b]===l&&(h.push(b),parseInt(b,10)!==k&&(i[b]=!0));for(b in d.keyBinds)if(d.keyBinds.hasOwnProperty(b)&&"function"==typeof d.keyBinds[b]&&(e=b.split(" "),e.length===h.length&&v[k]===e[e.length-1])){for(f=!0,c=e.length-2;c>=0;c--)if(!(v[e[c]]in i)){f=!1;break}if(f){g=d.keyBinds[b];break}}g&&(g.call(j,o),a.stopPropagation(),a.preventDefault())},db=function(a){w[a.which]="r",a.stopPropagation(),a.preventDefault()},eb=function(b){var c=a(b.target).val().trim(),d=c?bb(c):null;return W(d),b.stopImmediatePropagation(),!1},fb=function(){e.on({change:eb,blur:d.debug?"":X,keydown:cb,keyup:db}),c.is("input")?e.on({focus:_}):n&&(n.on("click",ab),n.on("mousedown",!1))},gb=function(){e.off({change:eb,blur:X,keydown:cb,keyup:db}),c.is("input")?e.off({focus:_}):n&&(n.off("click",ab),n.off("mousedown",!1))},hb=function(b){var c={};return a.each(b,function(){var a=bb(this);a.isValid()&&(c[a.format("YYYY-MM-DD")]=!0)}),Object.keys(c).length?c:!1},ib=function(){var a=d.format||"L LT";g=a.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){var b=k.localeData().longDateFormat(a)||a;return b.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){return k.localeData().longDateFormat(a)||a})}),h=d.extraFormats?d.extraFormats.slice():[],h.indexOf(a)<0&&h.indexOf(g)<0&&h.push(g),f=g.toLowerCase().indexOf("a")<1&&g.indexOf("h")<1,x("y")&&(p=2),x("M")&&(p=1),x("d")&&(p=0),i=Math.max(p,i),m||W(k)};if(j.destroy=function(){X(),gb(),c.removeData("DateTimePicker"),c.removeData("date")},j.toggle=ab,j.show=_,j.hide=X,j.disable=function(){return X(),n&&n.hasClass("btn")&&n.addClass("disabled"),e.prop("disabled",!0),j},j.enable=function(){return n&&n.hasClass("btn")&&n.removeClass("disabled"),e.prop("disabled",!1),j},j.ignoreReadonly=function(a){if(0===arguments.length)return d.ignoreReadonly;if("boolean"!=typeof a)throw new TypeError("ignoreReadonly () expects a boolean parameter");return d.ignoreReadonly=a,j},j.options=function(b){if(0===arguments.length)return a.extend(!0,{},d);if(!(b instanceof Object))throw new TypeError("options() options parameter should be an object");return a.extend(!0,d,b),a.each(d,function(a,b){if(void 0===j[a])throw new TypeError("option "+a+" is not recognized!");j[a](b)}),j},j.date=function(a){if(0===arguments.length)return m?null:k.clone();if(!(null===a||"string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");return W(null===a?null:bb(a)),j},j.format=function(a){if(0===arguments.length)return d.format;if("string"!=typeof a&&("boolean"!=typeof a||a!==!1))throw new TypeError("format() expects a sting or boolean:false parameter "+a);return d.format=a,g&&ib(),j},j.dayViewHeaderFormat=function(a){if(0===arguments.length)return d.dayViewHeaderFormat;if("string"!=typeof a)throw new TypeError("dayViewHeaderFormat() expects a string parameter");return d.dayViewHeaderFormat=a,j},j.extraFormats=function(a){if(0===arguments.length)return d.extraFormats;if(a!==!1&&!(a instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");return d.extraFormats=a,h&&ib(),j},j.disabledDates=function(b){if(0===arguments.length)return d.disabledDates?a.extend({},d.disabledDates):d.disabledDates;if(!b)return d.disabledDates=!1,V(),j;if(!(b instanceof Array))throw new TypeError("disabledDates() expects an array parameter");return d.disabledDates=hb(b),d.enabledDates=!1,V(),j},j.enabledDates=function(b){if(0===arguments.length)return d.enabledDates?a.extend({},d.enabledDates):d.enabledDates;if(!b)return d.enabledDates=!1,V(),j;if(!(b instanceof Array))throw new TypeError("enabledDates() expects an array parameter");return d.enabledDates=hb(b),d.disabledDates=!1,V(),j},j.daysOfWeekDisabled=function(a){if(0===arguments.length)return d.daysOfWeekDisabled.splice(0);if(!(a instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");return d.daysOfWeekDisabled=a.reduce(function(a,b){return b=parseInt(b,10),b>6||0>b||isNaN(b)?a:(-1===a.indexOf(b)&&a.push(b),a)},[]).sort(),V(),j},j.maxDate=function(a){if(0===arguments.length)return d.maxDate?d.maxDate.clone():d.maxDate;if("boolean"==typeof a&&a===!1)return d.maxDate=!1,V(),j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("maxDate() Could not parse date parameter: "+a);if(d.minDate&&c.isBefore(d.minDate))throw new TypeError("maxDate() date parameter is before options.minDate: "+c.format(g));return d.maxDate=c,d.maxDate.isBefore(a)&&W(d.maxDate),l.isAfter(c)&&(l=c.clone()),V(),j},j.minDate=function(a){if(0===arguments.length)return d.minDate?d.minDate.clone():d.minDate;if("boolean"==typeof a&&a===!1)return d.minDate=!1,V(),j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("minDate() Could not parse date parameter: "+a);if(d.maxDate&&c.isAfter(d.maxDate))throw new TypeError("minDate() date parameter is after options.maxDate: "+c.format(g));return d.minDate=c,d.minDate.isAfter(a)&&W(d.minDate),l.isBefore(c)&&(l=c.clone()),V(),j},j.defaultDate=function(a){if(0===arguments.length)return d.defaultDate?d.defaultDate.clone():d.defaultDate;if(!a)return d.defaultDate=!1,j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("defaultDate() Could not parse date parameter: "+a);if(!M(c))throw new TypeError("defaultDate() date passed is invalid according to component setup validations");return d.defaultDate=c,d.defaultDate&&""===e.val().trim()&&void 0===e.attr("placeholder")&&W(d.defaultDate),j},j.locale=function(a){if(0===arguments.length)return d.locale;if(!b.localeData(a))throw new TypeError("locale() locale "+a+" is not loaded from moment locales!");return d.locale=a,k.locale(d.locale),l.locale(d.locale),g&&ib(),o&&(X(),_()),j},j.stepping=function(a){return 0===arguments.length?d.stepping:(a=parseInt(a,10),(isNaN(a)||1>a)&&(a=1),d.stepping=a,j)},j.useCurrent=function(a){var b=["year","month","day","hour","minute"];if(0===arguments.length)return d.useCurrent;if("boolean"!=typeof a&&"string"!=typeof a)throw new TypeError("useCurrent() expects a boolean or string parameter");if("string"==typeof a&&-1===b.indexOf(a.toLowerCase()))throw new TypeError("useCurrent() expects a string parameter of "+b.join(", "));return d.useCurrent=a,j},j.collapse=function(a){if(0===arguments.length)return d.collapse;if("boolean"!=typeof a)throw new TypeError("collapse() expects a boolean parameter");return d.collapse===a?j:(d.collapse=a,o&&(X(),_()),j)},j.icons=function(b){if(0===arguments.length)return a.extend({},d.icons);if(!(b instanceof Object))throw new TypeError("icons() expects parameter to be an Object");return a.extend(d.icons,b),o&&(X(),_()),j},j.useStrict=function(a){if(0===arguments.length)return d.useStrict;if("boolean"!=typeof a)throw new TypeError("useStrict() expects a boolean parameter");return d.useStrict=a,j},j.sideBySide=function(a){if(0===arguments.length)return d.sideBySide;if("boolean"!=typeof a)throw new TypeError("sideBySide() expects a boolean parameter");return d.sideBySide=a,o&&(X(),_()),j},j.viewMode=function(a){if(0===arguments.length)return d.viewMode;if("string"!=typeof a)throw new TypeError("viewMode() expects a string parameter");if(-1===r.indexOf(a))throw new TypeError("viewMode() parameter must be one of ("+r.join(", ")+") value");return d.viewMode=a,i=Math.max(r.indexOf(a),p),I(),j},j.toolbarPlacement=function(a){if(0===arguments.length)return d.toolbarPlacement;if("string"!=typeof a)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===u.indexOf(a))throw new TypeError("toolbarPlacement() parameter must be one of ("+u.join(", ")+") value");return d.toolbarPlacement=a,o&&(X(),_()),j},j.widgetPositioning=function(b){if(0===arguments.length)return a.extend({},d.widgetPositioning);if("[object Object]"!=={}.toString.call(b))throw new TypeError("widgetPositioning() expects an object variable");if(b.horizontal){if("string"!=typeof b.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(b.horizontal=b.horizontal.toLowerCase(),-1===t.indexOf(b.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+t.join(", ")+")");d.widgetPositioning.horizontal=b.horizontal}if(b.vertical){if("string"!=typeof b.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(b.vertical=b.vertical.toLowerCase(),-1===s.indexOf(b.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+s.join(", ")+")");d.widgetPositioning.vertical=b.vertical}return V(),j},j.calendarWeeks=function(a){if(0===arguments.length)return d.calendarWeeks;if("boolean"!=typeof a)throw new TypeError("calendarWeeks() expects parameter to be a boolean value");return d.calendarWeeks=a,V(),j},j.showTodayButton=function(a){if(0===arguments.length)return d.showTodayButton;if("boolean"!=typeof a)throw new TypeError("showTodayButton() expects a boolean parameter");return d.showTodayButton=a,o&&(X(),_()),j},j.showClear=function(a){if(0===arguments.length)return d.showClear;if("boolean"!=typeof a)throw new TypeError("showClear() expects a boolean parameter");return d.showClear=a,o&&(X(),_()),j},j.widgetParent=function(b){if(0===arguments.length)return d.widgetParent;if("string"==typeof b&&(b=a(b)),null!==b&&"string"!=typeof b&&!(b instanceof a))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");return d.widgetParent=b,o&&(X(),_()),j},j.keepOpen=function(a){if(0===arguments.length)return d.keepOpen;if("boolean"!=typeof a)throw new TypeError("keepOpen() expects a boolean parameter");return d.keepOpen=a,j},j.inline=function(a){if(0===arguments.length)return d.inline;if("boolean"!=typeof a)throw new TypeError("inline() expects a boolean parameter");return d.inline=a,j},j.clear=function(){return Y(),j},j.keyBinds=function(a){return d.keyBinds=a,j},j.debug=function(a){if("boolean"!=typeof a)throw new TypeError("debug() expects a boolean parameter");return d.debug=a,j},j.showClose=function(a){if(0===arguments.length)return d.showClose;if("boolean"!=typeof a)throw new TypeError("showClose() expects a boolean parameter");return d.showClose=a,j},j.keepInvalid=function(a){if(0===arguments.length)return d.keepInvalid;if("boolean"!=typeof a)throw new TypeError("keepInvalid() expects a boolean parameter");return d.keepInvalid=a,j},j.datepickerInput=function(a){if(0===arguments.length)return d.datepickerInput;if("string"!=typeof a)throw new TypeError("datepickerInput() expects a string parameter");return d.datepickerInput=a,j},c.is("input"))e=c;else if(e=c.find(d.datepickerInput),0===e.size())e=c.find("input");else if(!e.is("input"))throw new Error('CSS class "'+d.datepickerInput+'" cannot be applied to non input element');if(c.hasClass("input-group")&&(n=c.find(0===c.find(".datepickerbutton").size()?'[class^="input-group-"]':".datepickerbutton")),!d.inline&&!e.is("input"))throw new Error("Could not initialize DateTimePicker without an input element");return a.extend(!0,d,F()),j.options(d),ib(),fb(),e.prop("disabled")&&j.disable(),e.is("input")&&0!==e.val().trim().length?W(bb(e.val().trim())):d.defaultDate&&void 0===e.attr("placeholder")&&W(d.defaultDate),d.inline&&_(),j};a.fn.datetimepicker=function(b){return this.each(function(){var d=a(this);d.data("DateTimePicker")||(b=a.extend(!0,{},a.fn.datetimepicker.defaults,b),d.data("DateTimePicker",c(d,b)))})},a.fn.datetimepicker.defaults={format:!1,dayViewHeaderFormat:"MMMM YYYY",extraFormats:!1,stepping:1,minDate:!1,maxDate:!1,useCurrent:!0,collapse:!0,locale:b.locale(),defaultDate:!1,disabledDates:!1,enabledDates:!1,icons:{time:"glyphicon glyphicon-time",date:"glyphicon glyphicon-calendar",up:"glyphicon glyphicon-chevron-up",down:"glyphicon glyphicon-chevron-down",previous:"glyphicon glyphicon-chevron-left",next:"glyphicon glyphicon-chevron-right",today:"glyphicon glyphicon-screenshot",clear:"glyphicon glyphicon-trash",close:"glyphicon glyphicon-remove"},useStrict:!1,sideBySide:!1,daysOfWeekDisabled:[],calendarWeeks:!1,viewMode:"days",toolbarPlacement:"default",showTodayButton:!1,showClear:!1,showClose:!1,widgetPositioning:{horizontal:"auto",vertical:"auto"},widgetParent:null,ignoreReadonly:!1,keepOpen:!1,inline:!1,keepInvalid:!1,datepickerInput:".datepickerinput",keyBinds:{up:function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().subtract(7,"d"):c.clone().add(1,"m"))}},down:function(a){if(!a)return void this.show();var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().add(7,"d"):c.clone().subtract(1,"m"))},"control up":function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().subtract(1,"y"):c.clone().add(1,"h"))}},"control down":function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().add(1,"y"):c.clone().subtract(1,"h"))}},left:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().subtract(1,"d"))}},right:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().add(1,"d"))}},pageUp:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().subtract(1,"M"))}},pageDown:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().add(1,"M"))}},enter:function(){this.hide()},escape:function(){this.hide()},"control space":function(a){a.find(".timepicker").is(":visible")&&a.find('.btn[data-action="togglePeriod"]').click()},t:function(){this.date(b())},"delete":function(){this.clear()}},debug:!1}}); \ No newline at end of file +========================================================= +bootstrap-datetimejs +https://github.com/Eonasdan/bootstrap-datetimepicker +Copyright (c) 2015 Jonathan Peterson +========================================================= +*/ +!function(a){"use strict";if("function"==typeof define&&define.amd)define(["jquery","moment"],a);else if("object"==typeof exports)a(require("jquery"),require("moment"));else{if("undefined"==typeof jQuery)throw"bootstrap-datetimepicker requires jQuery to be loaded first";if("undefined"==typeof moment)throw"bootstrap-datetimepicker requires Moment.js to be loaded first";a(jQuery,moment)}}(function(a,b){"use strict";if(!b)throw new Error("bootstrap-datetimepicker requires Moment.js to be loaded first");var c=function(c,d){var e,f,g,h,i,j={},k=b().startOf("d"),l=k.clone(),m=!0,n=!1,o=!1,p=0,q=[{clsName:"days",navFnc:"M",navStep:1},{clsName:"months",navFnc:"y",navStep:1},{clsName:"years",navFnc:"y",navStep:10}],r=["days","months","years"],s=["top","bottom","auto"],t=["left","right","auto"],u=["default","top","bottom"],v={up:38,38:"up",down:40,40:"down",left:37,37:"left",right:39,39:"right",tab:9,9:"tab",escape:27,27:"escape",enter:13,13:"enter",pageUp:33,33:"pageUp",pageDown:34,34:"pageDown",shift:16,16:"shift",control:17,17:"control",space:32,32:"space",t:84,84:"t","delete":46,46:"delete"},w={},x=function(a){if("string"!=typeof a||a.length>1)throw new TypeError("isEnabled expects a single character string parameter");switch(a){case"y":return-1!==g.indexOf("Y");case"M":return-1!==g.indexOf("M");case"d":return-1!==g.toLowerCase().indexOf("d");case"h":case"H":return-1!==g.toLowerCase().indexOf("h");case"m":return-1!==g.indexOf("m");case"s":return-1!==g.indexOf("s");default:return!1}},y=function(){return x("h")||x("m")||x("s")},z=function(){return x("y")||x("M")||x("d")},A=function(){var b=a("").append(a("").append(a("").append(a("").append(a("]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"
").addClass("cw").text("#"));c.isBefore(l.clone().endOf("w"));)b.append(a("").addClass("dow").text(c.format("dd"))),c.add(1,"d");o.find(".datepicker-days thead").append(b)},K=function(a){return d.disabledDates[a.format("YYYY-MM-DD")]===!0},L=function(a){return d.enabledDates[a.format("YYYY-MM-DD")]===!0},M=function(a,b){return a.isValid()?d.disabledDates&&K(a)&&"M"!==b?!1:d.enabledDates&&!L(a)&&"M"!==b?!1:d.minDate&&a.isBefore(d.minDate,b)?!1:d.maxDate&&a.isAfter(d.maxDate,b)?!1:"d"===b&&-1!==d.daysOfWeekDisabled.indexOf(a.day())?!1:!0:!1},N=function(){for(var b=[],c=l.clone().startOf("y").hour(12);c.isSame(l,"y");)b.push(a("").attr("data-action","selectMonth").addClass("month").text(c.format("MMM"))),c.add(1,"M");o.find(".datepicker-months td").empty().append(b)},O=function(){var b=o.find(".datepicker-months"),c=b.find("th"),d=b.find("tbody").find("span");b.find(".disabled").removeClass("disabled"),M(l.clone().subtract(1,"y"),"y")||c.eq(0).addClass("disabled"),c.eq(1).text(l.year()),M(l.clone().add(1,"y"),"y")||c.eq(2).addClass("disabled"),d.removeClass("active"),k.isSame(l,"y")&&d.eq(k.month()).addClass("active"),d.each(function(b){M(l.clone().month(b),"M")||a(this).addClass("disabled")})},P=function(){var a=o.find(".datepicker-years"),b=a.find("th"),c=l.clone().subtract(5,"y"),e=l.clone().add(6,"y"),f="";for(a.find(".disabled").removeClass("disabled"),d.minDate&&d.minDate.isAfter(c,"y")&&b.eq(0).addClass("disabled"),b.eq(1).text(c.year()+"-"+e.year()),d.maxDate&&d.maxDate.isBefore(e,"y")&&b.eq(2).addClass("disabled");!c.isAfter(e,"y");)f+=''+c.year()+"",c.add(1,"y");a.find("td").html(f)},Q=function(){var c,e,f,g=o.find(".datepicker-days"),h=g.find("th"),i=[];if(z()){for(g.find(".disabled").removeClass("disabled"),h.eq(1).text(l.format(d.dayViewHeaderFormat)),M(l.clone().subtract(1,"M"),"M")||h.eq(0).addClass("disabled"),M(l.clone().add(1,"M"),"M")||h.eq(2).addClass("disabled"),c=l.clone().startOf("M").startOf("week");!l.clone().endOf("M").endOf("w").isBefore(c,"d");)0===c.weekday()&&(e=a("
'+c.week()+"'+c.date()+"
'+c.format(f?"HH":"hh")+"
'+c.format("mm")+"
'+c.format("ss")+"
").addClass("prev").attr("data-action","previous").append(a("").addClass(d.icons.previous))).append(a("").addClass("picker-switch").attr("data-action","pickerSwitch").attr("colspan",d.calendarWeeks?"6":"5")).append(a("").addClass("next").attr("data-action","next").append(a("").addClass(d.icons.next)))),c=a("
").attr("colspan",d.calendarWeeks?"8":"7")));return[a("
").addClass("datepicker-days").append(a("").addClass("table-condensed").append(b).append(a(""))),a("
").addClass("datepicker-months").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone())),a("
").addClass("datepicker-years").append(a("
").addClass("table-condensed").append(b.clone()).append(c.clone()))]},B=function(){var b=a(""),c=a(""),e=a("");return x("h")&&(b.append(a(" -- 2.43.4 From 8cefb48768cffc31e7d0e0bd05f252933bade75b Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 01:42:03 +0200 Subject: [PATCH 093/197] Collapse other dishes, save expanded dish in hash --- app/templates/order.html | 73 ++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index c0a9f80..6f1d8d2 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -65,7 +65,7 @@

Add item to order

{% for dish in order.location.dishes %} -
+ {{ form.csrf_token }} @@ -187,7 +187,7 @@
-

Ordering at {{ order.location_name }}

+

About {{ order.location_name }}

{% if order.location.telephone %}
Telephone
@@ -338,8 +338,7 @@ section.single_column { grid-template-columns: unset; } .description { - color: #888; - margin-left: 1em; + margin-bottom: 10px; } header { margin-bottom: 25px; @@ -461,20 +460,74 @@ summary { line-height: 1.2; margin: 0.6em 0; } -summary .dish_name { - white-space: nowrap; -} summary .dish_name, summary:before { align-self: flex-start; +} +details[open] summary .dish_name { + font-weight: bold; +} +details[open] { + background-color: var(--gray5); + margin-left: -10px; + margin-right: -10px; + margin-bottom: 5px; + padding-left: 10px; + padding-right: 10px; + padding-bottom: 10px; +} + +.select2-container--default .select2-selection--multiple .select2-selection__rendered { + padding: 0 3px; +} +.select2-container .select2-selection--multiple { + min-height: 20px; + line-height: 1; +} +.select2-container .select2-search--inline .select2-search__field { + margin-top: 3px; +} +.select2-container--default .select2-selection--multiple .select2-selection__choice { + margin-top: 4px; +} +.select2-container li { + margin: 0; +} +.select2-selection--multiple .select2-search.select2-search--inline .select2-search__field:not(:focus) { + border-color: transparent; + box-shadow: none; } {% endblock %} {% block scripts %} {{ super() }} - +{% endif %} {% endblock %} -- 2.43.4 From c23a11bfdb3fff3522179658bf110365fd2c6783 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 02:01:07 +0200 Subject: [PATCH 094/197] Fix flow quirks in "order information" section --- app/templates/order.html | 85 +++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 6f1d8d2..03d2b67 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -135,43 +135,47 @@

Order information

-
Location
-
- {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %} -
+
+
Order opens
+
{{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
-
Courier
-
- {% if order.courier == None %} - {% if not current_user.is_anonymous() %} - - - - {% else %}No-one{% endif %} - {% else %} - {{ order.courier.username }} - {% endif %} -
+
Order closes
+
+ {% if order.stoptime %} + {% set stoptimefmt = ( + "%H:%M" if order.stoptime.date() == order.starttime.date() + else "%Y-%m-%d, %H:%M" + ) %} + {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) + {% else %} + Never + {% endif %} +
+
-
Order opens
-
{{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
+
+
Location
+
+ {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
-
Order closes
-
- {% if order.stoptime %} - {% set stoptimefmt = ( - "%H:%M" if order.stoptime.date() == order.starttime.date() - else "%Y-%m-%d, %H:%M" - ) %} - {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) - {% else %} - Never - {% endif %} -
+
Courier
+
+ {% if order.courier == None %} + {% if not current_user.is_anonymous() %} +
+ + + {% else %}No-one{% endif %} + {% else %} + {{ order.courier.username }} + {% endif %} +
+
@@ -190,16 +194,21 @@

About {{ order.location_name }}

{% if order.location.telephone %} + {% endif %} {% if order.location.website %} + {% endif %} {% if order.location.address or order.location.osm %} +
Location
{% if order.location.osm %} @@ -208,6 +217,7 @@ {{ order.location.address }} {% endif %}
+
{% endif %}
@@ -364,8 +374,11 @@ h3 { margin-bottom: 30px; } -#order_info dl { - column-width: 150px; +@media (min-width: 1200px) { + #order_info dl { + display: grid; + grid-template-columns: 1fr 1fr; + } } #from_favourites ul, #my_items ul, #per_person ul { -- 2.43.4 From d3e6c1b08cddeedc782ae54548e1e98d3f8387ba Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 02:07:50 +0200 Subject: [PATCH 095/197] Use columns in order info faster, align prices in menu --- app/templates/order.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 03d2b67..3e4e40d 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -82,7 +82,7 @@ {% if dish.tags %} {{ dish.tags | join(", ") }}{% endif %} --> - {{ dish.price_range() | price_range }} + {{ dish.price_range() | price_range }} {% if dish.description %}
{{ dish.description }}
{% endif %} {% for (choice_type, choice) in dish.choices %} @@ -374,7 +374,7 @@ h3 { margin-bottom: 30px; } -@media (min-width: 1200px) { +@media (min-width: 500px) { #order_info dl { display: grid; grid-template-columns: 1fr 1fr; -- 2.43.4 From 342e94a7bff6c0d5832be7591ac91484908be724 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 02:10:45 +0200 Subject: [PATCH 096/197] Remove aligned price in menu and my_items --- app/templates/order.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 3e4e40d..ef219d5 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -40,7 +40,7 @@ {%- endif %} - {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %} {{ item.price | euro }} + {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %} {{ item.price | euro }} {% endfor %} @@ -82,7 +82,7 @@ {% if dish.tags %} {{ dish.tags | join(", ") }}{% endif %} --> - {{ dish.price_range() | price_range }} + {{ dish.price_range() | price_range }} {% if dish.description %}
{{ dish.description }}
{% endif %} {% for (choice_type, choice) in dish.choices %} -- 2.43.4 From 695331dd1a140c8ee9da1d0fc94c7a55850e6d20 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 02:18:43 +0200 Subject: [PATCH 097/197] Fix margin in ordered dishes, less bold --- app/templates/order.html | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index ef219d5..5216b98 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -232,7 +232,7 @@

Ordered dishes

{% for dish_name, dish_order_items in order.group_by_dish() -%} {% set has_comments = dish_order_items | map(attribute="comment") | any -%} -
+

{{ dish_order_items | length }} × {{ dish_name }} @@ -361,6 +361,11 @@ h3 { font-size: 150%; font-weight: 500; } +h4 { + margin-bottom: 0.6em; + font-size: 110%; + font-weight: 500; +} .location { font-size: 150%; font-weight: 500; @@ -392,12 +397,6 @@ dl { margin-bottom: 0; } -.box h4 { - font-size: 110%; - font-weight: bold; - margin-bottom: 0.6em; -} - .spacecake { display: flex; align-items: flex-end; @@ -426,10 +425,6 @@ li { #per_dish .comments li { } -#per_dish .dish.no_comments { - display: flex; - align-items: flex-end; -} #per_dish .dish.no_comments h4 { margin-bottom: 0; line-height: inherit; -- 2.43.4 From 787669823c18825d97d2ff86e094e185e94a187a Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 13 Oct 2020 02:27:31 +0200 Subject: [PATCH 098/197] Improve spacing between items in ordered dishes --- app/templates/order.html | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 5216b98..bd333f3 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -362,7 +362,7 @@ h3 { font-weight: 500; } h4 { - margin-bottom: 0.6em; + margin-bottom: 0.5em; font-size: 110%; font-weight: 500; } @@ -415,20 +415,26 @@ dl { li { line-height: 1.5; - margin: 0.5em 0; + margin: 0.4em 0; } #my_items li form { align-self: flex-start; } -#per_dish .comments li { +#per_dish ul { + margin-bottom: 0; +} +#per_dish h4 { + margin-top: 0; } - #per_dish .dish.no_comments h4 { margin-bottom: 0; line-height: inherit; } +#per_dish .dish { + margin-bottom: 13px; +} #per_dish .item_for { color: var(--gray2); text-align: right; -- 2.43.4 From f5a830336221e76943ecc45ebdbeaa0af47083a4 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Fri, 4 Dec 2020 05:17:34 +0100 Subject: [PATCH 099/197] Don't crash when the theme does not have any options Hotfix for prod, pushing straight to master --- app/views/general.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/general.py b/app/views/general.py index 8a50d2b..5511856 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -124,7 +124,7 @@ def current_theme_js(): response = make_response(rf''' var currentTheme = {json.dumps(cur_theme['file'])}; -var currentThemeOptions = {json.dumps(cur_theme['options'])}; +var currentThemeOptions = {json.dumps(cur_theme.get('options', []))}; ''') response.headers["Content-Type"] = "text/javascript" -- 2.43.4 From ec7c8ed40b1e918a9d418d602162aa0b8427492d Mon Sep 17 00:00:00 2001 From: redfast00 Date: Fri, 4 Dec 2020 20:20:41 +0100 Subject: [PATCH 100/197] Update dependencies to fix bug in werkzeug --- requirements.txt | 72 +++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5c0337c..316de30 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,45 +4,47 @@ # # pip-compile # -alembic==1.0.8 # via flask-migrate -appdirs==1.4.3 # via black -attrs==19.1.0 # via black -black==19.10b0 +alembic==1.4.3 # via flask-migrate +appdirs==1.4.4 # via black +black==20.8b1 # via -r requirements.in blinker==1.4 # via flask-debugtoolbar -certifi==2019.3.9 # via requests +cachelib==0.1.1 # via flask-oauthlib +certifi==2020.11.8 # via requests chardet==3.0.4 # via requests -click==7.0 # via black, flask -dominate==2.3.5 # via flask-bootstrap -flask-admin==1.5.3 -flask-bootstrap==3.3.7.1 -flask-debugtoolbar==0.10.1 -flask-login==0.4.1 -flask-migrate==2.4.0 -flask-oauthlib==0.9.5 -flask-script==2.0.6 -flask-sqlalchemy==2.3.2 -flask-wtf==0.14.2 -flask==1.0.2 -idna==2.8 # via requests -itsdangerous==1.1.0 # via flask, flask-debugtoolbar -jinja2==2.10.1 # via flask -mako==1.0.8 # via alembic -markupsafe==1.1.1 # via jinja2, mako +click==7.1.2 # via black, flask +dominate==2.6.0 # via flask-bootstrap +flask-admin==1.5.7 # via -r requirements.in +flask-bootstrap==3.3.7.1 # via -r requirements.in +flask-debugtoolbar==0.11.0 # via -r requirements.in +flask-login==0.5.0 # via -r requirements.in +flask-migrate==2.5.3 # via -r requirements.in +flask-oauthlib==0.9.6 # via -r requirements.in +flask-script==2.0.6 # via -r requirements.in +flask-sqlalchemy==2.4.4 # via -r requirements.in, flask-migrate +flask-wtf==0.14.3 # via -r requirements.in +flask==1.1.2 # via -r requirements.in, flask-admin, flask-bootstrap, flask-debugtoolbar, flask-login, flask-migrate, flask-oauthlib, flask-script, flask-sqlalchemy, flask-wtf +idna==2.10 # via requests +itsdangerous==1.1.0 # via flask, flask-debugtoolbar, flask-wtf +jinja2==2.11.2 # via flask +mako==1.1.3 # via alembic +markupsafe==1.1.1 # via jinja2, mako, wtforms +mypy-extensions==0.4.3 # via black oauthlib==2.1.0 # via flask-oauthlib, requests-oauthlib -pathspec==0.7.0 # via black -pymysql==0.9.3 -python-dateutil==2.8.0 # via alembic +pathspec==0.8.1 # via black +pymysql==0.10.1 # via -r requirements.in +python-dateutil==2.8.1 # via alembic python-editor==1.0.4 # via alembic -pyyaml==5.3 -regex==2020.1.8 # via black +pyyaml==5.3.1 # via -r requirements.in +regex==2020.11.13 # via black requests-oauthlib==1.1.0 # via flask-oauthlib -requests==2.21.0 # via requests-oauthlib -six==1.12.0 # via python-dateutil -sqlalchemy==1.3.2 # via alembic, flask-sqlalchemy -tatsu==4.4.0 -toml==0.10.0 # via black +requests==2.25.0 # via requests-oauthlib +six==1.15.0 # via python-dateutil +sqlalchemy==1.3.20 # via alembic, flask-sqlalchemy +tatsu==5.5.0 # via -r requirements.in +toml==0.10.2 # via black typed-ast==1.4.1 # via black -urllib3==1.24.2 # via requests +typing-extensions==3.7.4.3 # via black +urllib3==1.26.2 # via requests visitor==0.1.3 # via flask-bootstrap -werkzeug==0.15.3 # via flask, flask-debugtoolbar -wtforms==2.2.1 # via flask-admin, flask-wtf +werkzeug==1.0.1 # via flask, flask-debugtoolbar +wtforms==2.3.3 # via flask-admin, flask-wtf -- 2.43.4 From fad23fbeda04b661b3b2a0af4cc3fc9a5bd13097 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Fri, 4 Dec 2020 20:21:12 +0100 Subject: [PATCH 101/197] Add option to download menus, make DB creation easier --- app/database/create_database.py | 14 +++++--------- first-setup.sh | 10 ++++++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/database/create_database.py b/app/database/create_database.py index e614cad..5460776 100644 --- a/app/database/create_database.py +++ b/app/database/create_database.py @@ -31,14 +31,10 @@ def add_all() -> None: def recreate_from_scratch() -> None: "Recreate a completely new database" - confirmation = "Are you very very sure? (Will delete previous entries!) (y/N) " - if input(confirmation).lower() in yes: - print("Resetting the database!") - db.drop_all() - db.create_all() - add_to_current() - else: - print("You cancelled.") + print("Resetting the database!") + db.drop_all() + db.create_all() + add_to_current() def add_to_current() -> None: @@ -75,7 +71,7 @@ def setup_database(): # type: None "Start the database interaction script" print("Database modification script!") print("=============================\n\n") - if check_if_overwrite(): + if (not db.engine.table_names()) or check_if_overwrite(): recreate_from_scratch() else: add_to_current() diff --git a/first-setup.sh b/first-setup.sh index a2e7c52..31e4c47 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -40,4 +40,14 @@ fi echo -e "${B} Seeding database ${E}" ./populate-db.sh +if [ ! -d "menus" ]; then + echo -en "${B} Do you want to use the Zeus HLDS menus? If not, you will have to clone your own menu repository. (Y/n) ${E}" + read confirm + if [ "$confirm" = n ]; then + echo "Not cloning the Zeus HLDS menus" + else + git clone https://git.zeus.gent/haldis/menus.git + fi +fi + echo -e "${B} Activate your venv using 'source venv/bin/activate'.\nThen run the development server with 'python app/app.py runserver' ${E}" -- 2.43.4 From 65d6de21fa8297cc0be60d8d4ee0dbf41741f6f3 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 18 Jun 2021 15:05:11 +0200 Subject: [PATCH 102/197] Change no courier text from "No-one" to "no-one yet" --- app/templates/order.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/order.html b/app/templates/order.html index bd333f3..4f75ed1 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -170,7 +170,7 @@
- {% else %}No-one{% endif %} + {% else %}No-one yet{% endif %} {% else %} {{ order.courier.username }} {% endif %} -- 2.43.4 From cc9343ccbc30694114eeaa7de7672eefbaaaa080 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 19 Jun 2021 01:06:07 +0200 Subject: [PATCH 103/197] Update dependencies TatSu 5.5.0 is yanked. Add Flask constraints because the newer versions changed stuff. --- requirements.in | 12 ++-- requirements.txt | 158 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 120 insertions(+), 50 deletions(-) diff --git a/requirements.in b/requirements.in index 6bd107f..36c6ea3 100644 --- a/requirements.in +++ b/requirements.in @@ -1,14 +1,14 @@ -Flask +Flask<2 Flask-Login Flask-Bootstrap -Flask-SQLAlchemy +Flask-SQLAlchemy<3 Flask-DebugToolbar Flask-WTF Flask-OAuthlib -Flask-Admin -Flask-Migrate -Flask-Script +Flask-Admin<2 +Flask-Migrate<3 +Flask-Script<3 black pymysql pyyaml -tatsu +tatsu<5.6 # >=5.6 needs Python >=3.8 diff --git a/requirements.txt b/requirements.txt index 316de30..bbca76b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,47 +4,117 @@ # # pip-compile # -alembic==1.4.3 # via flask-migrate -appdirs==1.4.4 # via black -black==20.8b1 # via -r requirements.in -blinker==1.4 # via flask-debugtoolbar -cachelib==0.1.1 # via flask-oauthlib -certifi==2020.11.8 # via requests -chardet==3.0.4 # via requests -click==7.1.2 # via black, flask -dominate==2.6.0 # via flask-bootstrap -flask-admin==1.5.7 # via -r requirements.in -flask-bootstrap==3.3.7.1 # via -r requirements.in -flask-debugtoolbar==0.11.0 # via -r requirements.in -flask-login==0.5.0 # via -r requirements.in -flask-migrate==2.5.3 # via -r requirements.in -flask-oauthlib==0.9.6 # via -r requirements.in -flask-script==2.0.6 # via -r requirements.in -flask-sqlalchemy==2.4.4 # via -r requirements.in, flask-migrate -flask-wtf==0.14.3 # via -r requirements.in -flask==1.1.2 # via -r requirements.in, flask-admin, flask-bootstrap, flask-debugtoolbar, flask-login, flask-migrate, flask-oauthlib, flask-script, flask-sqlalchemy, flask-wtf -idna==2.10 # via requests -itsdangerous==1.1.0 # via flask, flask-debugtoolbar, flask-wtf -jinja2==2.11.2 # via flask -mako==1.1.3 # via alembic -markupsafe==1.1.1 # via jinja2, mako, wtforms -mypy-extensions==0.4.3 # via black -oauthlib==2.1.0 # via flask-oauthlib, requests-oauthlib -pathspec==0.8.1 # via black -pymysql==0.10.1 # via -r requirements.in -python-dateutil==2.8.1 # via alembic -python-editor==1.0.4 # via alembic -pyyaml==5.3.1 # via -r requirements.in -regex==2020.11.13 # via black -requests-oauthlib==1.1.0 # via flask-oauthlib -requests==2.25.0 # via requests-oauthlib -six==1.15.0 # via python-dateutil -sqlalchemy==1.3.20 # via alembic, flask-sqlalchemy -tatsu==5.5.0 # via -r requirements.in -toml==0.10.2 # via black -typed-ast==1.4.1 # via black -typing-extensions==3.7.4.3 # via black -urllib3==1.26.2 # via requests -visitor==0.1.3 # via flask-bootstrap -werkzeug==1.0.1 # via flask, flask-debugtoolbar -wtforms==2.3.3 # via flask-admin, flask-wtf +alembic==1.6.5 + # via flask-migrate +appdirs==1.4.4 + # via black +black==21.6b0 + # via -r requirements.in +blinker==1.4 + # via flask-debugtoolbar +cachelib==0.1.1 + # via flask-oauthlib +certifi==2021.5.30 + # via requests +chardet==4.0.0 + # via requests +click==7.1.2 + # via + # black + # flask +dominate==2.6.0 + # via flask-bootstrap +flask-admin==1.5.8 + # via -r requirements.in +flask-bootstrap==3.3.7.1 + # via -r requirements.in +flask-debugtoolbar==0.11.0 + # via -r requirements.in +flask-login==0.5.0 + # via -r requirements.in +flask-migrate==2.7.0 + # via -r requirements.in +flask-oauthlib==0.9.6 + # via -r requirements.in +flask-script==2.0.6 + # via -r requirements.in +flask-sqlalchemy==2.5.1 + # via + # -r requirements.in + # flask-migrate +flask-wtf==0.15.1 + # via -r requirements.in +flask==1.1.4 + # via + # -r requirements.in + # flask-admin + # flask-bootstrap + # flask-debugtoolbar + # flask-login + # flask-migrate + # flask-oauthlib + # flask-script + # flask-sqlalchemy + # flask-wtf +greenlet==1.1.0 + # via sqlalchemy +idna==2.10 + # via requests +itsdangerous==1.1.0 + # via + # flask + # flask-debugtoolbar + # flask-wtf +jinja2==2.11.3 + # via flask +mako==1.1.4 + # via alembic +markupsafe==2.0.1 + # via + # jinja2 + # mako + # wtforms +mypy-extensions==0.4.3 + # via black +oauthlib==2.1.0 + # via + # flask-oauthlib + # requests-oauthlib +pathspec==0.8.1 + # via black +pymysql==1.0.2 + # via -r requirements.in +python-dateutil==2.8.1 + # via alembic +python-editor==1.0.4 + # via alembic +pyyaml==5.4.1 + # via -r requirements.in +regex==2021.4.4 + # via black +requests-oauthlib==1.1.0 + # via flask-oauthlib +requests==2.25.1 + # via requests-oauthlib +six==1.16.0 + # via python-dateutil +sqlalchemy==1.4.18 + # via + # alembic + # flask-sqlalchemy +tatsu==4.4.0 + # via -r requirements.in +toml==0.10.2 + # via black +urllib3==1.26.5 + # via requests +visitor==0.1.3 + # via flask-bootstrap +werkzeug==1.0.1 + # via + # flask + # flask-debugtoolbar +wtforms==2.3.3 + # via + # flask-admin + # flask-wtf -- 2.43.4 From 90ea53d20e52afd9f124b9778ac717b4f302d59d Mon Sep 17 00:00:00 2001 From: redfast00 Date: Sat, 24 Jul 2021 17:45:19 +0200 Subject: [PATCH 104/197] Change komoot API from .de to .io --- app/static/js/map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/static/js/map.js b/app/static/js/map.js index c97776c..f3a82f3 100644 --- a/app/static/js/map.js +++ b/app/static/js/map.js @@ -4,7 +4,7 @@ L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { }).addTo(map); -let base_request_uri = "https://photon.komoot.de/api/?limit=1&q="; +let base_request_uri = "https://photon.komoot.io/api/?limit=1&q="; function performRequest(url, location, success_callback) { var request = new XMLHttpRequest(); -- 2.43.4 From 00cdc587b03112ba7423c972851efefc3d997674 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sun, 20 Jun 2021 21:47:24 +0200 Subject: [PATCH 105/197] Add space at bottom in show view On big orders the bottom of the page was awkward. --- app/static/css/main.css | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 8d17488..504882a 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -63,12 +63,9 @@ body { .showcase { font-size: 16px; line-height: 1.2; -} - -.showcase { padding: 0; max-width: 500px; - margin: 0 auto; + margin: 0 auto 70px; } .showcase h1 { -- 2.43.4 From 58d270e58203c335a211dbee424e048a1bf9523a Mon Sep 17 00:00:00 2001 From: Midgard Date: Sun, 20 Jun 2021 22:08:41 +0200 Subject: [PATCH 106/197] HLDS: change :: to double space and require it Require double space before tags and price, like in the plain text accounting format of ledger. This makes it easier to differentiate between prices mentioned in descriptions and the price for the dish. --- app/hlds/hlds.tatsu | 12 +++++++----- etc/vim/ftplugin.vim | 1 + etc/vim/syntax.vim | 5 +++-- etc/vscode/syntaxes/hlds.tmLanguage.json | 11 +++-------- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/app/hlds/hlds.tatsu b/app/hlds/hlds.tatsu index b4d47b8..08c859c 100644 --- a/app/hlds/hlds.tatsu +++ b/app/hlds/hlds.tatsu @@ -29,10 +29,12 @@ location = >location_header items:{ block } ; attributes = - name:/[^\n#]*?(?= +-- | +:: | +€ | *\n| *#)/ - [ s '--' ~ s description:/[^\n#]*?(?= +:: | +€ | *\n| *#)/ ] - [ s '::' {s ('{' tags+:identifier '}')} ] - [ [ s '::' ~ ] s price:price ] + name:/[^\n#]*?(?= +-- | | *\n| *#)/ + [ s '--' ~ s description:/[^\n#]*?(?= | *\n| *#)/ ] + [ / {2,}/ ~ + [ {[ s ] ('{' tags+:identifier '}')} / +|$/ ] + [ price:price ] + ] ; @@ -73,7 +75,7 @@ indent_choice_block = ; -s = / +/ ; +s = / +/ ; n = '\n' {{'\t'} '\n'} ; @name diff --git a/etc/vim/ftplugin.vim b/etc/vim/ftplugin.vim index bbd8967..edcbd4d 100644 --- a/etc/vim/ftplugin.vim +++ b/etc/vim/ftplugin.vim @@ -1 +1,2 @@ setlocal noexpandtab +setlocal softtabstop=0 diff --git a/etc/vim/syntax.vim b/etc/vim/syntax.vim index f9d2629..5b783cd 100644 --- a/etc/vim/syntax.vim +++ b/etc/vim/syntax.vim @@ -25,8 +25,9 @@ syn keyword hldsChoiceType single_choice multi_choice nextgroup=hldsBlockIdAf syn match hldsBlockId "^[a-z0-9_-]\+: " syn match hldsBlockIdAftrKywrd "[a-z0-9_-]\+: " contained -syn match hldsTag " {[a-z0-9_-]\+}" -syn match hldsPrice "€ *[0-9]\+\(\.[0-9]\+\|\)" +syn match _doubleSpace " \+" nextgroup=hldsTag,hldsPrice +syn match hldsTag "{[a-z0-9_-]\+}\( \|$\)" contained nextgroup=hldsTag,hldsPrice +syn match hldsPrice "€ *[0-9]\+\(\.[0-9]\+\|\)\( \|$\)" contained syn match hldsComment "#.*$" contains=hldsTodo,@Spell syn keyword hldsTodo FIXME NOTE NOTES TODO XXX contained diff --git a/etc/vscode/syntaxes/hlds.tmLanguage.json b/etc/vscode/syntaxes/hlds.tmLanguage.json index cfbe47a..02f52b2 100644 --- a/etc/vscode/syntaxes/hlds.tmLanguage.json +++ b/etc/vscode/syntaxes/hlds.tmLanguage.json @@ -33,13 +33,8 @@ "tags": { "patterns": [ { - "match": "(::)\\s*({[a-zA-Z-_]*}\\s*)*", - "name": "markup.italic", - "captures": { - "1": { - "name": "markup.bold" - } - } + "match": " +( +{[a-zA-Z-_]*})*", + "name": "markup.italic" } ] }, @@ -94,4 +89,4 @@ } }, "scopeName": "source.hlds" -} \ No newline at end of file +} -- 2.43.4 From 1ff8ceb5217dfb93ddad674974f821d66b3b352b Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 21 Jun 2021 00:46:29 +0200 Subject: [PATCH 107/197] Improve design Remove main CSS from shop view page. Make it theme independent and maximize contrast. Improve spacing in "add item" list. Refactor old term "showcase" to "shop_view" in code. --- app/static/css/main.css | 55 -------------------- app/static/css/shop_view.css | 93 ++++++++++++++++++++++++++++++++++ app/templates/order.html | 23 +++++---- app/templates/order_items.html | 6 +-- app/views/order.py | 2 +- 5 files changed, 108 insertions(+), 71 deletions(-) create mode 100644 app/static/css/shop_view.css diff --git a/app/static/css/main.css b/app/static/css/main.css index 504882a..6dba497 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -60,61 +60,6 @@ body { width: 100%; } -.showcase { - font-size: 16px; - line-height: 1.2; - padding: 0; - max-width: 500px; - margin: 0 auto 70px; -} - -.showcase h1 { - font-size: 200%; - margin: 0 ; - padding: 0.4em 0 0.2em; - border-bottom: 1px dashed var(--gray1); - text-align: center; -} -.showcase h2 { - font-size: 110%; - font-weight: bold; - margin-bottom: 0.6em; -} - -.showcase .open-order-warning { - font-size: 150%; - text-align: center; - padding: 1em 0.5em; - background-color: rgba(255, 0, 0, 0.1); -} - -.showcase .dish { - padding: 0 0.5em; -} -@media (min-width: 500px) { - .showcase .dish { - padding: 0 1em; - } -} - -.showcase .quantity { - font-size: 110%; -} - -.showcase .comments { - padding-left: 2em; -} -.showcase .comments li { - margin: 0.5em 0 0; -} - -.showcase .total { - border-top: 1px dashed var(--gray1); - text-align: center; - padding: 0.5em 0; - margin-top: 1.3em; -} - .time_data{ display: flex; justify-content: space-between; diff --git a/app/static/css/shop_view.css b/app/static/css/shop_view.css new file mode 100644 index 0000000..ed75a75 --- /dev/null +++ b/app/static/css/shop_view.css @@ -0,0 +1,93 @@ +:root { + --bg: #eee; + --ticketBg: #fff; + --fg: #000; + --dashes: 1px dashed #444; + --fontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; + --fontSize: 16px; +} + +html, body { + margin: 0; + padding: 0; +} + +body { + background: var(--bg); + color: var(--fg); + font-family: var(--fontFamily); + font-size: var(--fontSize); + line-height: 1.2; +} + +.ticket { + background: var(--ticketBg); + font-size: 16px; + padding: 0; + max-width: 500px; + margin: 25px auto; + margin: 7vh auto; + box-shadow: 0 0.15em 0.3em rgba(0, 0, 0, 0.2); +} + +@media (max-width: 500px) { + body { + background: var(--ticketBg); + } + .ticket { + margin: 0; + box-shadow: none; + } +} + +h1 { + font-size: 200%; + margin: 0 ; + padding: 0.3em 0 0.3em; + border-bottom: var(--dashes); + text-align: center; +} +h2 { + font-size: 110%; + font-weight: bold; + margin-bottom: 0.6em; +} + +.open-order-warning { + font-size: 150%; + text-align: center; + padding: 1em 0.5em; + background-color: rgba(255, 0, 0, 0.1); +} + +.dish { + padding: 0 0.5em; +} +@media (min-width: 500px) { + .dish { + padding: 0 1em; + } +} + +.quantity { + font-size: 110%; +} + +.comments { + padding-left: 2em; +} +.comments li { + margin: 0.5em 0 0; +} + +.total { + border-top: var(--dashes); + text-align: center; + padding: 0.5em 0; + margin-top: 1.3em; +} + +.time_data{ + display: flex; + justify-content: space-between; +} diff --git a/app/templates/order.html b/app/templates/order.html index 4f75ed1..eecef70 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -256,7 +256,7 @@

@@ -313,9 +313,7 @@ @@ -472,7 +470,8 @@ li { summary { line-height: 1.2; - margin: 0.6em 0; + margin: 0 -10px; + padding: 4px 10px; } summary .dish_name, summary:before { align-self: flex-start; @@ -480,14 +479,16 @@ summary .dish_name, summary:before { details[open] summary .dish_name { font-weight: bold; } +details { + margin: 0 -10px; + padding: 0 10px; +} details[open] { background-color: var(--gray5); - margin-left: -10px; - margin-right: -10px; - margin-bottom: 5px; - padding-left: 10px; - padding-right: 10px; - padding-bottom: 10px; + padding-bottom: 5px; +} +details:not([open]) summary:hover { + background-color: var(--gray5); } .select2-container--default .select2-selection--multiple .select2-selection__rendered { diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 6d73795..6d633fb 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -7,9 +7,7 @@ Haldis - Order {{ order.id }} {% block styles %} {{ super() }} - - - + {% endblock %} {% block scripts %} @@ -23,7 +21,7 @@ Haldis - Order {{ order.id }} {% block content -%} {{ utils.flashed_messages(container=True) }} -
+

Haldis order {{ order.id }}

{% if not order.is_closed() %} diff --git a/app/views/order.py b/app/views/order.py index a8646b6..177c195 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -88,7 +88,7 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: @order_bp.route("//items") -def items_showcase(order_id: int) -> str: +def items_shop_view(order_id: int) -> str: "Generate order items view from id" order = Order.query.filter(Order.id == order_id).first() if order is None: -- 2.43.4 From 16bd9243d48f158de1a30683c72210778a84e5e9 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 21 Jun 2021 02:05:11 +0200 Subject: [PATCH 108/197] Aggregate comments --- app/models/order.py | 34 +++++++++++++++++++++------------- app/static/css/shop_view.css | 18 +++++++++++++++++- app/templates/order.html | 21 ++++++++++++++------- app/templates/order_items.html | 13 ++++++++----- 4 files changed, 60 insertions(+), 26 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 9b0c721..ec5d3fb 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -1,6 +1,7 @@ "Script for everything Order related in the database" import typing from datetime import datetime +from collections import defaultdict from utils import first from hlds.definitions import location_definitions @@ -69,23 +70,30 @@ class Order(db.Model): return list(sorted(group.items(), key=lambda t: (t[0] or "", t[1] or ""))) - def group_by_dish(self) -> typing.List[typing.Tuple[str, typing.List]]: + def group_by_dish(self) \ + -> typing.List[typing.Tuple[str, int, typing.List[typing.Tuple[typing.List[str], typing.List]]]]: "Group items of an Order by dish" - group: typing.Dict[str, typing.List] = dict() + group: typing.Dict[str, typing.Dict[str, typing.List]] = \ + defaultdict(lambda: defaultdict(list)) for item in self.items: - if item.dish_name not in group: - group[item.dish_name] = [] + group[item.dish_name][item.comment].append(item) - group[item.dish_name].append(item) - - for _dish_name, order_items in group.items(): - order_items.sort(key=lambda order_item: ( - (order_item.comment or " No comment") + - (order_item.for_name or "") - )) - - return list(sorted(group.items())) + return sorted( + ( + dish_name, + # Amount of items of this dish + sum(map(len, comment_group.values())), + sorted( + ( + (list(map(str.strip, comment.split(";"))) if comment else []), + sorted(items, key=lambda x: (x.for_name or "")) + ) + for comment, items in comment_group.items() + ) + ) + for dish_name, comment_group in group.items() + ) def is_closed(self) -> bool: return self.stoptime and datetime.now() > self.stoptime diff --git a/app/static/css/shop_view.css b/app/static/css/shop_view.css index ed75a75..4ef8b29 100644 --- a/app/static/css/shop_view.css +++ b/app/static/css/shop_view.css @@ -74,12 +74,28 @@ h2 { } .comments { - padding-left: 2em; + padding-left: 1.5em; + list-style-type: none; } .comments li { margin: 0.5em 0 0; } +.comment_part { + background-color: #f7f7f7; + border: 1px solid #ddd; + padding: 0.1em 0.5em; + margin-top: 2px; + margin-right: 0.4em; + border-radius: 1em; + display: inline-block; +} +.comment_part_separator { + display: inline-block; + width: 0; + overflow: hidden; +} + .total { border-top: var(--dashes); text-align: center; diff --git a/app/templates/order.html b/app/templates/order.html index eecef70..52f2720 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -230,24 +230,27 @@

Ordered dishes

- {% for dish_name, dish_order_items in order.group_by_dish() -%} - {% set has_comments = dish_order_items | map(attribute="comment") | any -%} + {% for dish_name, dish_quantity, dish_comment_groups in order.group_by_dish() -%} + {% set has_comments = dish_comment_groups | length > 1 or (dish_comment_groups | map("first") | any) -%}

- {{ dish_order_items | length }} × + {{ dish_quantity }} × {{ dish_name }}

{% if has_comments -%}
    - {% for item in dish_order_items -%} -
  • {% if item["comment"] %}{{ item["comment"] }} + {% for comment, items in dish_comment_groups -%} +
  • {{ items | length }} × + {% if comment %} + {% set semicolon = joiner(";") %} + {% for comment_part in comment %}{{ semicolon() }} {{ comment_part }}{% endfor %} {% else %}No comment - {% endif %} for {{ item.for_name }}
  • + {% endif %} for {{ items | map(attribute="for_name") | join(", ") }} {% endfor %}
{% else %} - for {{ dish_order_items | map(attribute="for_name") | join(", ") }} + for {{ dish_comment_groups[0][1] | map(attribute="for_name") | join(", ") }} {%- endif %}

@@ -437,6 +440,10 @@ li { color: var(--gray2); text-align: right; } +#per_dish .comments { + padding-left: 1.5em; + list-style-type: none; +} #per_person li { diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 6d633fb..388c1ad 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -31,13 +31,16 @@ Haldis - Order {{ order.id }}
{% endif %} - {% for dish_name, dish_order_items in order.group_by_dish() -%} + {% for dish_name, dish_quantity, dish_comment_groups in order.group_by_dish() -%}
-

{{ dish_order_items | length }} × {{ dish_name }}

- {% if dish_order_items | map(attribute="comment") | any -%} +

{{ dish_quantity }} × {{ dish_name }}

+ {% if dish_comment_groups | map("first") | any -%}
    - {% for item in dish_order_items -%} -
  • {% if item["comment"] %}{{ item["comment"] }} + {% for comment, items in dish_comment_groups -%} +
  • {{ items | length }} × + {% if comment %} + {% set semicolon = joiner(";") %} + {% for comment_part in comment %}{{ semicolon() }} {{ comment_part }}{% endfor %} {% else %}No comment {% endif %}
  • {% endfor %} -- 2.43.4 From e82742eb620e0fcd200613897db12f27cef8880e Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 21 Jun 2021 02:08:32 +0200 Subject: [PATCH 109/197] Remove pills introduced in previous commit --- app/models/order.py | 7 ++----- app/templates/order.html | 7 +++---- app/templates/order_items.html | 4 +--- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index ec5d3fb..b990f04 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -71,7 +71,7 @@ class Order(db.Model): return list(sorted(group.items(), key=lambda t: (t[0] or "", t[1] or ""))) def group_by_dish(self) \ - -> typing.List[typing.Tuple[str, int, typing.List[typing.Tuple[typing.List[str], typing.List]]]]: + -> typing.List[typing.Tuple[str, int, typing.List[typing.Tuple[str, typing.List]]]]: "Group items of an Order by dish" group: typing.Dict[str, typing.Dict[str, typing.List]] = \ defaultdict(lambda: defaultdict(list)) @@ -85,10 +85,7 @@ class Order(db.Model): # Amount of items of this dish sum(map(len, comment_group.values())), sorted( - ( - (list(map(str.strip, comment.split(";"))) if comment else []), - sorted(items, key=lambda x: (x.for_name or "")) - ) + (comment, sorted(items, key=lambda x: (x.for_name or ""))) for comment, items in comment_group.items() ) ) diff --git a/app/templates/order.html b/app/templates/order.html index 52f2720..3e3b4cb 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -241,10 +241,9 @@ {% if has_comments -%}
      {% for comment, items in dish_comment_groups -%} -
    • {{ items | length }} × - {% if comment %} - {% set semicolon = joiner(";") %} - {% for comment_part in comment %}{{ semicolon() }} {{ comment_part }}{% endfor %} +
    • + {{ items | length }} × + {% if comment %}{{ comment }} {% else %}No comment {% endif %} for {{ items | map(attribute="for_name") | join(", ") }}
    • {% endfor %} diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 388c1ad..2339824 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -38,9 +38,7 @@ Haldis - Order {{ order.id }}
        {% for comment, items in dish_comment_groups -%}
      • {{ items | length }} × - {% if comment %} - {% set semicolon = joiner(";") %} - {% for comment_part in comment %}{{ semicolon() }} {{ comment_part }}{% endfor %} + {% if comment %}{{ comment }} {% else %}No comment {% endif %}
      • {% endfor %} -- 2.43.4 From 4a96c0c2860ff21ca81448663c581f5df1109300 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 17 Jul 2021 20:33:07 +0200 Subject: [PATCH 110/197] Correct phone URL, add phone URL on location --- app/templates/location.html | 4 ++-- app/templates/order.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/location.html b/app/templates/location.html index f41c032..9a9ff6b 100644 --- a/app/templates/location.html +++ b/app/templates/location.html @@ -7,8 +7,8 @@

        {{ location.name }}

        - {% if location.address %} {{ location.address }}
        {% endif %} - {% if location.telephone %}{{ location.telephone }}
        {% endif %} + {% if location.address %}{{ location.address }}
        {% endif %} + {% if location.telephone %}{{ location.telephone }}
        {% endif %} {% if location.website %} {{ location.website }}
        {% endif %} {% if location.osm %} {{ location.osm }}
        {% endif %} {% if not current_user.is_anonymous() %} diff --git a/app/templates/order.html b/app/templates/order.html index 3e3b4cb..996bf80 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -196,7 +196,7 @@ {% if order.location.telephone %} {% endif %} -- 2.43.4 From adcc0dd69e690c882085c7d1b0ef074cf8545d1b Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 17 Jul 2021 20:41:59 +0200 Subject: [PATCH 111/197] Confine li spacing to .main --- app/templates/order.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/order.html b/app/templates/order.html index 996bf80..8ac6f4e 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -413,7 +413,7 @@ dl { margin: 0.3em 0.5em; } -li { +.main li { line-height: 1.5; margin: 0.4em 0; } -- 2.43.4 From 02a82621b71fe4d72e1d42ca6a25d37598769463 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 17 Jul 2021 20:52:36 +0200 Subject: [PATCH 112/197] Improve footer: improve spacing, https URL --- app/static/css/main.css | 7 ++++++- app/templates/layout.html | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 6dba497..e8418ce 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -146,8 +146,13 @@ a { .navbar-default .navbar-brand:focus { color: var(--gray0); } -hr{ +hr { border-top: 1px solid var(--gray2); + margin: 0; + margin-bottom: 23px; +} +footer { + padding: 23px 0; } h1, h2, h3, h4, h5, h6{ diff --git a/app/templates/layout.html b/app/templates/layout.html index d825bf1..392963d 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -84,7 +84,7 @@ Haldis - {{ active_page|capitalize }}
        -- 2.43.4 From 326b5d6b5f3454571d0cb835db7e9d841e3d16ee Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 24 Jul 2021 17:48:08 +0200 Subject: [PATCH 113/197] Set secure and samesite --- app/static/js/theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/static/js/theme.js b/app/static/js/theme.js index 8f693d9..dc240f8 100644 --- a/app/static/js/theme.js +++ b/app/static/js/theme.js @@ -6,7 +6,7 @@ const YEAR = 60 * 60 * 24 * 365; const storeCookieAndReload = (name, value) => { - document.cookie = name + " = " + value + "; Path=/; Max-Age=" + (50 * YEAR); + document.cookie = name + " = " + value + "; Path=/; Secure; SameSite=strict; Max-Age=" + (50 * YEAR); location.reload(); } -- 2.43.4 From 4cbc4473de89957438fc65deff4eaef4993e9c32 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 15 Sep 2021 21:14:21 +0200 Subject: [PATCH 114/197] Add custom item to each location --- app/hlds/parser.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index c1bb88d..3f46b3e 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -57,6 +57,15 @@ class HldsSemanticActions: for option in first_single_choice.options: option.price += dish.price dish.price = 0 + dishes = list(dishes) + dishes.append(Dish( + "custom", + name="Vrije keuze", + description="Zet wat je wil in comment", + price=0, + tags=[], + choices=[], + )) attributes = {att["key"]: att["value"] for att in ast["attributes"]} -- 2.43.4 From 9e3578425fbbf4c0ee54c9761a12824d63ac6fdc Mon Sep 17 00:00:00 2001 From: maartenvn Date: Thu, 28 Oct 2021 23:35:57 +0200 Subject: [PATCH 115/197] feat(pwa): add PWA support --- app/static/browserconfig.xml | 9 ++++++ app/static/icons/android-chrome-192x192.png | Bin 0 -> 13871 bytes app/static/icons/android-chrome-256x256.png | Bin 0 -> 16844 bytes app/static/icons/apple-touch-icon.png | Bin 0 -> 13249 bytes app/static/icons/favicon-16x16.png | Bin 0 -> 6365 bytes app/static/icons/favicon-32x32.png | Bin 0 -> 6937 bytes app/static/icons/favicon.ico | Bin 0 -> 13294 bytes app/static/icons/mstile-150x150.png | Bin 0 -> 5890 bytes app/static/icons/safari-pinned-tab.svg | 32 ++++++++++++++++++++ app/static/js/pwa.js | 23 ++++++++++++++ app/static/js/sw.js | 13 ++++++++ app/static/manifest.json | 22 ++++++++++++++ app/templates/layout.html | 24 ++++++++++++++- 13 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 app/static/browserconfig.xml create mode 100644 app/static/icons/android-chrome-192x192.png create mode 100644 app/static/icons/android-chrome-256x256.png create mode 100644 app/static/icons/apple-touch-icon.png create mode 100644 app/static/icons/favicon-16x16.png create mode 100644 app/static/icons/favicon-32x32.png create mode 100644 app/static/icons/favicon.ico create mode 100644 app/static/icons/mstile-150x150.png create mode 100644 app/static/icons/safari-pinned-tab.svg create mode 100644 app/static/js/pwa.js create mode 100644 app/static/js/sw.js create mode 100644 app/static/manifest.json diff --git a/app/static/browserconfig.xml b/app/static/browserconfig.xml new file mode 100644 index 0000000..adc1b7a --- /dev/null +++ b/app/static/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #1c1c1c + + + diff --git a/app/static/icons/android-chrome-192x192.png b/app/static/icons/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..3bfc79e4abaab52bae83db7d2e7e97ceca98a897 GIT binary patch literal 13871 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 literal 0 HcmV?d00001 diff --git a/app/static/icons/android-chrome-256x256.png b/app/static/icons/android-chrome-256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..b7edfffd94d415fd130c5397b149bb04786f295b GIT binary patch literal 16844 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 G3i>~OA*|d0 literal 0 HcmV?d00001 diff --git a/app/static/icons/apple-touch-icon.png b/app/static/icons/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..6fe2039b186a6c8fb485ef01a182cefc9ea26315 GIT binary patch literal 13249 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 literal 0 HcmV?d00001 diff --git a/app/static/icons/favicon-16x16.png b/app/static/icons/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..93c2159ecaca332011ceeea298bdf79925fb79e6 GIT binary patch literal 6365 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 ZfL$sQzf*bPtfv+LH6?AuT6vqu{{sa#wDkZ0 literal 0 HcmV?d00001 diff --git a/app/static/icons/favicon.ico b/app/static/icons/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..12646e588d14b119f146456a83e6e27a0dd19a0d GIT binary patch literal 13294 zcmeHN2UJwY8vacL=~Zy|URaierAP-w1Qb-TcOznXU;_QS%d?dL*4hJDQ5$*%rc&bG<1cf0*811T$Ozx1 zcWdyD1FwMtEQ3Z|`YXy9;TH55PH7k#F~Yyr99R|wu47Pr*}qX^=`HN$Ifd}Ejp;S) z^PjfAgptPKkUe-;`UixhYcgk5BU1_S4yTJ*1S>N0VBY!!xo`3t+DNnT0D32 z8A_8&__A_5qEmV$e(}RYl%zaIW#W?FgapOXtE3;hc}&7C8!ORnXB}R;U5pmV#XNo` z!tb)93NPMzjAkii*d@Lm4Sd5$rwSBD28cgGdv8>Uenj}|dHj}1&v>lLadm{hg2yl6 z@NcZZZf@fg%O(()84E{L{pcpz?rgwYk18-b{|RpYx`DqJLcf%$iyqGa<6R9|!rSu-2O(m##% zPdjio+GQfoAG1xx_+A`hr&vUXbUFVeTPjfN!(6fxV#VQplkFxM)*T&Mp-2U_zKg$_Q7 zr+fH4V39SoM9s)6sIsZ8|I_5dX)L{ojHQ!e@}HXn`NulJIql=8Icd!~OM2E!@pMnK z3^1tY7uP<22)}MXxRcqdz8EF?CPV`g4AqyC3<{6@>pc zG7wio=dziK<+nBAZpt}7&aMxtuX@myL;U%x2nEiANp=SvqC?~B(7-2Dv2{-qe$p>Or$MN;wy1Fr zxVT9<3f#sjw(ckV#wK(w;m(p)E)+ZbNsga%r~1l5WNdo#y2n^7AsJ9CIbaF1t%Ebp zTec1*<`&3`%~5OadASU8x@W;ZC}w4aB9REgm#jfo4=-dG#feKZgn#MkSS);8g5HBh z5H=y|%-GkAUppih86y!o_42?U3+`j`C!g}M#%8~xiFl;N0(fheSR-{u@R-k1_!_U7dA*twr`m#?D4 zb1cPhAGXNv`sc`aOu+p|Pd2xcef14m**YNC$J?5NP{`oSuty__1f$P+!-kZNa@q=*7v)+u#w!`V+QhVnZ85@gygWjtFpQV$7GjbXNui&aet4@7x=8ay1k}6_hy96 ze`B)Dt&^pV1D^i!n|ASVmG#7v=)7Mj*7*RtP`oo_e*wO%ZXZ9_{wi^hl?%9`g=X}gPdjU(zD>%q)F0QA9w9MCT z6F52Z@*R$M?mcWX{^O!j%sO%s{in@F3u`-`3oK_}={&|I?w;eEL~4nn{3c`iz8oxk zMDpBf37!;};iw6((IyaY#3W~XNZz=sj`ZKHpC8b=?LwcSqflfjk>mb7IizR2&7%0N z=YSy?9hZXFfBXq+YU}wvIZkrid>yjPaWiPnLVQw6|3&2Azy-_KVvpYB$FRo#mHy*= z3?XsR-q{sH=0)LYvS&qQmAGWp2Eza6p3iuhwR3LRxP5;^NaPZFe?HRGY+Don^yzRzdzs)wf+|9-Tj+i0q#33F(q$G-1l7k)mfhLzn$dw zw|_1Kt?)CjbN60QNvH=)8+%ZtT#b^`_HyXc-xoBJ>S0#cTwqxSNbdk^WDK%9FTv1j z8tC_%1rr0N1BpH8Oy2_suNOghUKw<=?*|4BKA;tL8r=JM1N}ct{WpMZdJU9SRDo6! z-8(n~{a*<$t81ulmilJl!NbQ8c(@!yVpCuwmS93To%z5_Y6(T9Ww0hL1tN|Y!R>;( zK>zE4T6`V#i=a900?;=lpqYd~{D*|i+o*3LR8`l4o_`WBtPzc21bQiTVAyvm=mzcp zgQeGjzJUN~S|tn}H4fZ7y}-iS1`hn|C8)&JfbQtkAaEWC6k`D)!%)8r+<*8KYU}FY z)WvJynD{f8nVG?}lIJjJUnS(^%3x}6D0Ch9F(}73fXnhTkh$+5oH%5_Q=#2@WJ?k*Ue^~^9K_OtCj?g8x2G%8Ph7n`^;J}$HVCXU&oIfcCjl_Dm za_xIC3O`KaG0?5|crbAHhw9ooptucW=9hv&|5>21;uqMTlMCUIi{YO)@4)21=|IXG z#1b>m3O)n^Yd6R_nhRmaNUh0bveGa(q+tjBXIW0|qNKde>wHIRn7urgWpg{tZ@+t)Orv)w%ZB#t zVEQtd_`>@vn>VWi_%d0q$-z$SK3qnKnJDQzLCJ~R%%iAlKbkIT)bWwXCvuSka4jLpxt947C5wc~TRl6NTtRAyH zDtPu6?-`$qXs3ZBXkx1Q1V4wv_NkXl)L(5d^mu&gXP;(dNJpgVE%SKgdCxFNO-Up~`JhF1krA1K-{ETBZe0E*AIzl| za7uO-gd>-LZt!RD!J#S`Pl>+Q1BwfQ=G^mSi=27ea^>3_&3+OcML|Egj_i^*dD}YjKs7KHPGBq&y=^MI8~@!3bhrY_@@xF~#v6HNE0x-|s&Kb5 zWZrjgsnG4I->d(ymhuqa5hI=1ma^I)GjnijDUWsOWN$jQrTpG-)qXmy%C-)k-d@Hn z&)p5WT2E*-p8IG^54KfVpywme`=Gg^uS$2}K&JtH8#}P+EV485Q&$?JCa=)$Z6WS4 e&aulVf4;2NZLo%ktLsp$KAO~^!-e^S5B>wz4~WD7 literal 0 HcmV?d00001 diff --git a/app/static/icons/mstile-150x150.png b/app/static/icons/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..78c6e1edb30deb99deab5ea5f969eb5cceb4f1df GIT binary patch literal 5890 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

        HdtR4At6`g`6DaJQh zB>%>U`I$=&dE1tz&?w>3x0=Xt<)GQH@uZ)!;qDK-+`*3{9gh}I_DY*gd~wWHqmfy$ z>scp_-pmu#u;t*iwZsP@J8Ioq$t)74C*T75FF`Mrh1<>FD;tu>{U8yApd->D$db{c znjSw*lew_pYa>3hz4%>Ab?XQHS$+n6u}Yv-gFhsVh-J}=egvX%x!tw&rONUl=XP%g z`iR6sa!oW)IlS8cG&|}UP^pYrj|H0g_uWAZ4sQb5f_(+DZXiY< zI8o1l?kUpPc)$6Y{`mFdPg&b;(4a<%JX;vZDw|npO_`KZIvU?%E<28$5qy9peohz> z5F4tjos@Y^eA~o>UA~J6NC{QWEa*t^oQCpqITvB56D9SLQR-Qbp(+I1GGY)J32^~1SOyH;dS3Mlv1# z0}d6GM3)UdsK$U}=;w5Q_i#6`n|KJNp8rf3u+2c@d87n+kJ|$9R8?E$i;`97e*u_2 B=AQrn literal 0 HcmV?d00001 diff --git a/app/static/icons/safari-pinned-tab.svg b/app/static/icons/safari-pinned-tab.svg new file mode 100644 index 0000000..ccb92a2 --- /dev/null +++ b/app/static/icons/safari-pinned-tab.svg @@ -0,0 +1,32 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + + + + + diff --git a/app/static/js/pwa.js b/app/static/js/pwa.js new file mode 100644 index 0000000..54ad55d --- /dev/null +++ b/app/static/js/pwa.js @@ -0,0 +1,23 @@ +/** + * PWA (progressive web app) support + */ +function ready() { + // Make sure the browser supports service workers + if ("serviceWorker" in navigator) { + // Register a new service worker. + navigator.serviceWorker + .register("/static/js/sw.js") + .then((registration) => { + console.log( + "[PWA] Service worker registered with scope: ", + registration.scope + ); + }) + .catch((error) => { + console.error("[PWA] Service worker registration failed: ", error); + }); + } +} + +// Load on document load +document.addEventListener("DOMContentLoaded", ready); diff --git a/app/static/js/sw.js b/app/static/js/sw.js new file mode 100644 index 0000000..9a4fdab --- /dev/null +++ b/app/static/js/sw.js @@ -0,0 +1,13 @@ +// Service worker for PWA support + +// Install Hook +// Triggered when the PWA is installed by the browser. +self.addEventListener("install", () => { + console.log("[Service Worker] Installed"); +}); + +// Activate Hook +// Triggered when the PWA is activated by the browser. +self.addEventListener("activate", () => { + console.log("[Service Worker] Activated"); +}); diff --git a/app/static/manifest.json b/app/static/manifest.json new file mode 100644 index 0000000..3343e3c --- /dev/null +++ b/app/static/manifest.json @@ -0,0 +1,22 @@ +{ + "name": "Haldis", + "short_name": "Haldis", + "description": "Zeus WPI's drink ordering system", + "theme_color": "#ff6600", + "background_color": "#1c1c1c", + "display": "standalone", + "scope": "/", + "start_url": "/", + "icons": [ + { + "src": "/static/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/static/icons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/app/templates/layout.html b/app/templates/layout.html index 392963d..72b85b7 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -9,13 +9,15 @@ ('general_bp.about', 'About'), ('stats_blueprint.stats', 'Stats'), ] -%} + {% if current_user.is_admin() -%} {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} + {% set active_page = active_page|default('index') -%} {% block title %} -Haldis - {{ active_page|capitalize }} + Haldis - {{ active_page|capitalize }} {% if title %} - {{ title }} {% endif %} @@ -33,6 +35,26 @@ Haldis - {{ active_page|capitalize }} + +{% endblock %} + +{% block head %} + {{ super() }} + + + + + + + + + + + + + + + {% endblock %} {% block navbar %} -- 2.43.4 From c5da63b23e8ba26236a2c02ede8bcecb4f2224ba Mon Sep 17 00:00:00 2001 From: maartenvn Date: Thu, 28 Oct 2021 23:52:21 +0200 Subject: [PATCH 116/197] fix(pwa): correct description & theme color --- app/static/manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/static/manifest.json b/app/static/manifest.json index 3343e3c..43e70d2 100644 --- a/app/static/manifest.json +++ b/app/static/manifest.json @@ -1,8 +1,8 @@ { "name": "Haldis", "short_name": "Haldis", - "description": "Zeus WPI's drink ordering system", - "theme_color": "#ff6600", + "description": "Zeus WPI's food ordering system", + "theme_color": "#ff7f00", "background_color": "#1c1c1c", "display": "standalone", "scope": "/", -- 2.43.4 From 1f7ddcdb330127f312bfd63f5a14603fee2927c2 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Wed, 26 Jan 2022 07:51:33 +0100 Subject: [PATCH 117/197] Rip out Airbrake --- app/app.py | 25 ------------------------- app/config.example.py | 2 -- first-setup.sh | 8 -------- 3 files changed, 35 deletions(-) diff --git a/app/app.py b/app/app.py index 1070142..d1abfbc 100755 --- a/app/app.py +++ b/app/app.py @@ -6,10 +6,6 @@ from logging.handlers import TimedRotatingFileHandler import typing from datetime import datetime -try: - import airbrake -except ImportError: - airbrake = None from flask import Flask, render_template from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension @@ -28,7 +24,6 @@ from zeus import init_oauth def register_plugins(app: Flask) -> Manager: - "Register Airbrake and logrotation plugins" # pylint: disable=W0612 if not app.debug: timedFileHandler = TimedRotatingFileHandler( @@ -41,26 +36,6 @@ def register_plugins(app: Flask) -> Manager: loglogger.addHandler(timedFileHandler) app.logger.addHandler(timedFileHandler) - if app.config["AIRBRAKE_ID"]: - if airbrake is None: - raise Exception( - "Airbrake support was requested (AIRBRAKE_ID is present in config), " - "but could not import airbrake. Make sure `airbrake` is installed" - ) - - airbrakelogger = logging.getLogger("airbrake") - - airbrake_obj = airbrake.Airbrake( - project_id=app.config["AIRBRAKE_ID"], api_key=app.config["AIRBRAKE_KEY"] - ) - # Change URL in a hacky way to make this work for our errbit - airbrake_obj._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=protected-access - airbrake_obj.project_id - ) - - airbrakelogger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake_obj)) - app.logger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake_obj)) - # Initialize SQLAlchemy db.init_app(app) diff --git a/app/config.example.py b/app/config.example.py index ea5a560..191ce24 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -13,5 +13,3 @@ class Configuration: LOGFILE = "haldis.log" ZEUS_KEY = "tomtest" ZEUS_SECRET = "blargh" - AIRBRAKE_ID = "" - AIRBRAKE_KEY = "" diff --git a/first-setup.sh b/first-setup.sh index 31e4c47..dbb4155 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -22,14 +22,6 @@ pip install pip-tools echo -e "${B} Downloading dependencies ${E}" pip-sync -echo -en "${B} Do you want to install support for the Airbrake API for error logging? If you don't have an Errbit server or Airbrake account, answer no. (y/N) ${E}" -read confirm -if [ "$confirm" = y ]; then - pip install airbrake -else - echo "Not installing airbrake" -fi - if [ ! -f app/config.py ]; then echo -e "${B} Copying config template. All custom config options can be set in the config.py file ${E}" cp app/config.example.py app/config.py -- 2.43.4 From 4924f22b4808a1975518873aefbc3b69246822ef Mon Sep 17 00:00:00 2001 From: Francis Begyn Date: Tue, 19 Apr 2022 19:17:27 +0200 Subject: [PATCH 118/197] make shell scripts portable The current shell scripts call `/bin/bash`. This won't work on certain systems (`nixos` for example :eyes:). By switching to `/usr/bin/env bash` these scripts become portable. As long as `bash` environment is present on a system, the scripts will work. --- first-setup.sh | 2 +- parse_hlds.sh | 2 +- populate-db.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/first-setup.sh b/first-setup.sh index dbb4155..0622dda 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail # A simple file to run all instructions from the README ## this should be run in the root of the repository diff --git a/parse_hlds.sh b/parse_hlds.sh index b0c3188..f9b7898 100755 --- a/parse_hlds.sh +++ b/parse_hlds.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail # args = map(lambda arg: arg if x[0] in "/-" else pwd+arg, sys.argv[1:]) diff --git a/populate-db.sh b/populate-db.sh index 400ce2e..4c0aff4 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")/app" -- 2.43.4 From b573841e49bd18e67500351536579dbc6d9fccf1 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 19:57:27 +0200 Subject: [PATCH 119/197] Fix python version in first-setup script --- .python-version | 2 +- README.md | 1 + first-setup.sh | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.python-version b/.python-version index 678fd88..a9f8d1b 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.5.3 \ No newline at end of file +3.9.11 diff --git a/README.md b/README.md index ad467b5..26ba6b6 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Be lazier today! ## Local setup There is a special script to get started with the project. Just run it in the root of the project. +Note: this script might require you to install a certain python version, you can do this using your favorite tool e.g. [pyenv](https://github.com/pyenv/pyenv#simple-python-version-management-pyenv) ./first-setup.sh diff --git a/first-setup.sh b/first-setup.sh index dbb4155..954b32e 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -10,8 +10,10 @@ B="\n${bold}" E="${normal}" if [ ! -d "venv" ]; then - echo -e "${B} No venv found, creating a new one ${E}" - python3 -m venv venv + PYTHON_VERSION=$(cat .python-version) + echo -e "${B} No venv found, creating a new one with version ${PYTHON_VERSION} ${E}" + pip install virtualenv + virtualenv -p $PYTHON_VERSION venv fi source venv/bin/activate -- 2.43.4 From ee65544031a446aa5424c92afa1658ef6585a054 Mon Sep 17 00:00:00 2001 From: Maxime <12089026+mcbloch@users.noreply.github.com> Date: Tue, 19 Apr 2022 20:10:22 +0200 Subject: [PATCH 120/197] Update to use the exact server version --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index a9f8d1b..2009c7d 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.9.11 +3.9.2 -- 2.43.4 From c5e9067d59c29c57542dac5d931280aafe7e9427 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Tue, 19 Apr 2022 20:19:23 +0200 Subject: [PATCH 121/197] use module instead of installed bin --- first-setup.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/first-setup.sh b/first-setup.sh index 954b32e..68eb601 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -12,8 +12,7 @@ E="${normal}" if [ ! -d "venv" ]; then PYTHON_VERSION=$(cat .python-version) echo -e "${B} No venv found, creating a new one with version ${PYTHON_VERSION} ${E}" - pip install virtualenv - virtualenv -p $PYTHON_VERSION venv + python3 -m virtualenv -p $PYTHON_VERSION venv fi source venv/bin/activate -- 2.43.4 From ba1b37f5fe57611a95acc1b2c39ff300c16aff3b Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 20:40:06 +0200 Subject: [PATCH 122/197] Update populate-db to be less hacky --- populate-db.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/populate-db.sh b/populate-db.sh index 400ce2e..5d7157c 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -3,5 +3,5 @@ set -euo pipefail cd "$(dirname "$0")/app" cp database/* . -../venv/bin/python create_database.py setup_database +env python create_database.py setup_database rm -f add_* create_database.py muhscheme.txt -- 2.43.4 From 2123d7d1a3af99e826c411023fd16c884169ea14 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Tue, 19 Apr 2022 21:31:40 +0200 Subject: [PATCH 123/197] fix the weird copying of files --- app/{database => }/add_admins.py | 5 +++-- app/app.py | 3 ++- app/{database => }/create_database.py | 14 ++++++++------ populate-db.sh | 3 +-- 4 files changed, 14 insertions(+), 11 deletions(-) rename app/{database => }/add_admins.py (84%) rename app/{database => }/create_database.py (86%) diff --git a/app/database/add_admins.py b/app/add_admins.py similarity index 84% rename from app/database/add_admins.py rename to app/add_admins.py index f47dfe0..661c880 100644 --- a/app/database/add_admins.py +++ b/app/add_admins.py @@ -1,10 +1,11 @@ -"Script for adding users as admin to Haldis." +"""Script for adding users as admin to Haldis.""" + from app import db from models import User def add() -> None: - "Add users as admin." + """Add users as admin.""" feli = User() feli.configure("feliciaan", True, 0) db.session.add(feli) diff --git a/app/app.py b/app/app.py index d1abfbc..0273c47 100755 --- a/app/app.py +++ b/app/app.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 -"Main Haldis script" +"""Main Haldis script""" + import logging from logging.handlers import TimedRotatingFileHandler import typing diff --git a/app/database/create_database.py b/app/create_database.py similarity index 86% rename from app/database/create_database.py rename to app/create_database.py index 5460776..e11305b 100644 --- a/app/database/create_database.py +++ b/app/create_database.py @@ -1,5 +1,7 @@ -"Script for interaction and changes to the database" +"""Script for interaction and changes to the database""" + import add_admins + from app import db, app_manager entry_sets = { @@ -11,13 +13,13 @@ no = ["no", "n"] def commit() -> None: - "Commit all the things to the database" + """Commit all the things to the database""" db.session.commit() print("Committing successful") def check_if_overwrite() -> bool: - "Check if the user wants to overwrite the previous database" + """Check if the user wants to overwrite the previous database""" answer = input("Do you want to overwrite the previous database? (y/N) ") return answer.lower() in yes @@ -30,7 +32,7 @@ def add_all() -> None: def recreate_from_scratch() -> None: - "Recreate a completely new database" + """Recreate a completely new database""" print("Resetting the database!") db.drop_all() db.create_all() @@ -38,7 +40,7 @@ def recreate_from_scratch() -> None: def add_to_current() -> None: - "Add things to the current database" + """Add things to the current database""" available = [entry_set for entry_set in entry_sets] def add_numbers() -> str: @@ -68,7 +70,7 @@ def add_to_current() -> None: @app_manager.command def setup_database(): # type: None - "Start the database interaction script" + """Start the database interaction script""" print("Database modification script!") print("=============================\n\n") if (not db.engine.table_names()) or check_if_overwrite(): diff --git a/populate-db.sh b/populate-db.sh index 5d7157c..7735440 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -2,6 +2,5 @@ set -euo pipefail cd "$(dirname "$0")/app" -cp database/* . + env python create_database.py setup_database -rm -f add_* create_database.py muhscheme.txt -- 2.43.4 From 1cdd22c1c0bfe893bbc1cf2b532a9f762eb8d431 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 21:08:08 +0200 Subject: [PATCH 124/197] Add fail-under to pylint --- .pylintrc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.pylintrc b/.pylintrc index 1f6b81c..ca0b539 100644 --- a/.pylintrc +++ b/.pylintrc @@ -5,6 +5,8 @@ # run arbitrary code. extension-pkg-whitelist= +fail-under=9 + # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS @@ -28,7 +30,7 @@ limit-inference-results=100 # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. -load-plugins= +load-plugins=pylint_flask_sqlalchemy,pylint_flask # Pickle collected data for later comparisons. persistent=yes @@ -60,7 +62,7 @@ confidence= # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use "--disable=all --enable=classes # --disable=W". -disable=E0401,E0611,C0103,W0511,W0611 +disable=E0401,E0611,C0103,W0511,W0611,C0415 # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option -- 2.43.4 From 5e29f2a5f7d86b14f34cd5b30e74570cc1698038 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 22:03:00 +0200 Subject: [PATCH 125/197] Fix formatting --- app/__init__.py | 0 app/add_admins.py | 2 +- app/admin.py | 29 ++++-- app/app.py | 18 ++-- app/create_database.py | 10 +- app/fatmodels.py | 5 +- app/forms.py | 19 +--- app/hlds/__init__.py | 2 +- app/hlds/definitions.py | 6 +- app/hlds/models.py | 73 ++++++++------- app/hlds/parser.py | 29 +++--- app/login.py | 3 +- app/migrations/env.py | 2 - .../9159a6fed021_initial_haldis_support.py | 91 +++++++++++++------ app/models/order.py | 31 ++++--- app/models/orderitem.py | 27 +++--- app/models/orderitemchoice.py | 5 +- app/models/user.py | 2 +- app/notification.py | 7 +- app/parse_hlds.py | 2 - app/utils.py | 4 +- app/views/debug.py | 4 +- app/views/general.py | 83 +++++++++-------- app/views/order.py | 31 +++---- app/views/stats.py | 3 +- app/zeus.py | 15 ++- 26 files changed, 272 insertions(+), 231 deletions(-) create mode 100644 app/__init__.py diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/add_admins.py b/app/add_admins.py index 661c880..3e71c60 100644 --- a/app/add_admins.py +++ b/app/add_admins.py @@ -1,7 +1,7 @@ """Script for adding users as admin to Haldis.""" +from models import User from app import db -from models import User def add() -> None: diff --git a/app/admin.py b/app/admin.py index 553ec7d..8c7acac 100644 --- a/app/admin.py +++ b/app/admin.py @@ -3,7 +3,6 @@ from flask import Flask from flask_admin import Admin from flask_admin.contrib.sqla import ModelView from flask_sqlalchemy import SQLAlchemy - from models import Order, OrderItem, OrderItemChoice, User @@ -26,8 +25,10 @@ class OrderAdminModel(ModelBaseView): column_default_sort = ("starttime", True) column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] column_labels = { - "starttime": "Start Time", "stoptime": "Closing Time", - "location_id": "HLDS Location ID"} + "starttime": "Start Time", + "stoptime": "Closing Time", + "location_id": "HLDS Location ID", + } form_excluded_columns = ["items", "courier_id"] can_delete = False @@ -36,13 +37,25 @@ class OrderItemAdminModel(ModelBaseView): # pylint: disable=too-few-public-methods column_default_sort = ("order_id", True) column_list = [ - "order_id", "order.location_name", "user_name", "user", "dish_name", "dish_id", "comment", "price", "paid", - "hlds_data_version" + "order_id", + "order.location_name", + "user_name", + "user", + "dish_name", + "dish_id", + "comment", + "price", + "paid", + "hlds_data_version", ] column_labels = { - "order_id": "Order", "order.location_name": "Order's Location", - "user_name": "Anon. User", "user_id": "Registered User", - "hlds_data_version": "HLDS Data Version", "dish_id": "HLDS Dish ID"} + "order_id": "Order", + "order.location_name": "Order's Location", + "user_name": "Anon. User", + "user_id": "Registered User", + "hlds_data_version": "HLDS Data Version", + "dish_id": "HLDS Dish ID", + } def init_admin(app: Flask, database: SQLAlchemy) -> None: diff --git a/app/app.py b/app/app.py index 0273c47..0df5cf6 100755 --- a/app/app.py +++ b/app/app.py @@ -3,10 +3,11 @@ """Main Haldis script""" import logging -from logging.handlers import TimedRotatingFileHandler import typing from datetime import datetime +from logging.handlers import TimedRotatingFileHandler +from admin import init_admin from flask import Flask, render_template from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension @@ -14,10 +15,8 @@ from flask_login import LoginManager from flask_migrate import Migrate, MigrateCommand from flask_oauthlib.client import OAuth, OAuthException from flask_script import Manager, Server -from markupsafe import Markup - -from admin import init_admin from login import init_login +from markupsafe import Markup from models import db from models.anonymous_user import AnonymouseUser from utils import euro_string, price_range_string @@ -69,7 +68,8 @@ def register_plugins(app: Flask) -> Manager: # Make cookies more secure app.config.update( - SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SAMESITE="Lax", + SESSION_COOKIE_HTTPONLY=True, + SESSION_COOKIE_SAMESITE="Lax", ) if not app.debug: @@ -95,11 +95,11 @@ def add_routes(application: Flask) -> None: # import views # TODO convert to blueprint # import views.stats # TODO convert to blueprint - from views.order import order_bp - from views.general import general_bp - from views.stats import stats_blueprint - from views.debug import debug_bp from login import auth_bp + from views.debug import debug_bp + from views.general import general_bp + from views.order import order_bp + from views.stats import stats_blueprint from zeus import oauth_bp application.register_blueprint(general_bp, url_prefix="/") diff --git a/app/create_database.py b/app/create_database.py index e11305b..a583eb6 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -2,7 +2,7 @@ import add_admins -from app import db, app_manager +from app import app_manager, db entry_sets = { "admins": add_admins.add, @@ -27,7 +27,7 @@ def check_if_overwrite() -> bool: def add_all() -> None: "Add all possible entries in the entry_sets to the database" for entry_set, function in entry_sets.items(): - print("Adding {}.".format(entry_set)) + print(f"Adding {entry_set}.") function() @@ -45,14 +45,14 @@ def add_to_current() -> None: def add_numbers() -> str: return " ".join( - ["{}({}), ".format(loc, i) for i, loc in enumerate(available)] + [f"{loc}({i}), " for i, loc in enumerate(available)] ).rstrip(", ") while input("Do you still want to add something? (Y/n) ").lower() not in no: print( "What do you want to add? (Use numbers, or A for all, or C for cancel) " ) - answer = input("Available: {} : ".format(add_numbers())) + answer = input(f"Available: {add_numbers()} : ") if answer.lower() == "a": add_all() available = [] @@ -60,7 +60,7 @@ def add_to_current() -> None: pass elif answer.isnumeric() and answer in [str(x) for x in range(len(available))]: answer_index = int(answer) - print("Adding {}.".format(available[answer_index])) + print(f"Adding {available[answer_index]}.") entry_sets[str(available[answer_index])]() del available[answer_index] else: diff --git a/app/fatmodels.py b/app/fatmodels.py index d8c614f..a2d349e 100644 --- a/app/fatmodels.py +++ b/app/fatmodels.py @@ -1,10 +1,9 @@ import typing -from sqlalchemy.sql import desc, func - from hlds.definitions import location_definitions -from hlds.models import Location, Dish +from hlds.models import Dish, Location from models import Order, OrderItem, User +from sqlalchemy.sql import desc, func class FatModel: diff --git a/app/forms.py b/app/forms.py index 1317c21..d50c9f1 100644 --- a/app/forms.py +++ b/app/forms.py @@ -1,25 +1,16 @@ "Script for everything form related in Haldis" from datetime import datetime, timedelta - from typing import Optional -from flask import session, request +from flask import request, session from flask_login import current_user from flask_wtf import FlaskForm as Form -from wtforms import ( - DateTimeField, - SelectField, - SelectMultipleField, - StringField, - SubmitField, - FieldList, - validators, -) - -from utils import euro_string, price_range_string from hlds.definitions import location_definitions -from hlds.models import Location, Dish, Choice +from hlds.models import Choice, Dish, Location from models import User +from utils import euro_string, price_range_string +from wtforms import (DateTimeField, FieldList, SelectField, + SelectMultipleField, StringField, SubmitField, validators) class OrderForm(Form): diff --git a/app/hlds/__init__.py b/app/hlds/__init__.py index bef79a6..cc0a8a3 100644 --- a/app/hlds/__init__.py +++ b/app/hlds/__init__.py @@ -6,4 +6,4 @@ These are not imported in this module's init, to avoid opening the definition fi parser on them when testing other code in this module, or when testing the parser on other files. """ -from .models import Location, Choice, Option +from .models import Choice, Location, Option diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 0da89aa..961d14b 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -1,11 +1,11 @@ # Import this class to load the standard HLDS definitions +import subprocess from os import path from typing import List -import subprocess -from .parser import parse_all_directory -from .models import Location +from .models import Location +from .parser import parse_all_directory __all__ = ["location_definitions", "location_definition_version"] diff --git a/app/hlds/models.py b/app/hlds/models.py index 93d8fde..b85559c 100644 --- a/app/hlds/models.py +++ b/app/hlds/models.py @@ -1,26 +1,28 @@ #!/usr/bin/env python3 # pylint: disable=too-few-public-methods -from typing import Iterable, List, Tuple, Mapping, Any, Optional +from typing import Any, Iterable, List, Mapping, Optional, Tuple + from utils import euro_string, first def _format_tags(tags: Iterable[str]) -> str: - return " :: {}".format(" ".join(["{" + tag + "}" for tag in tags])) \ - if tags \ - else "" + # pylint: disable=consider-using-f-string + return " :: {}".format(" ".join(["{" + tag + "}" + for tag in tags])) if tags else "" def _format_price(price: int) -> str: - return " {}".format(euro_string(price)) if price else "" + return f" {euro_string(price)}" if price else "" def _format_type_and_choice(type_and_choice): type_, choice = type_and_choice - return "{} {}".format(type_, choice) + return f"{type_} {choice}" class Option: + def __init__(self, id_, *, name, description, price, tags): self.id: str = id_ self.name: str = name @@ -29,15 +31,17 @@ class Option: self.tags: List[str] = tags def __str__(self): + # pylint: disable=consider-using-f-string return "{0.id}: {0.name}{1}{2}{3}".format( self, - " -- {}".format(self.description) if self.description else "", + f" -- {self.description}" if self.description else "", _format_tags(self.tags), _format_price(self.price), ) class Choice: + def __init__(self, id_, *, name, description, options): self.id: str = id_ self.name: str = name @@ -48,7 +52,7 @@ class Choice: def __str__(self): return "{0.id}: {0.name}{1}\n\t\t{2}".format( self, - " -- {}".format(self.description) if self.description else "", + f" -- {self.description}" if self.description else "", "\n\t\t".join(map(str, self.options)), ) @@ -57,6 +61,7 @@ class Choice: class Dish: + def __init__(self, id_, *, name, description, price, tags, choices): self.id: str = id_ self.name: str = name @@ -70,7 +75,7 @@ class Dish: def __str__(self): return "dish {0.id}: {0.name}{1}{2}{3}\n\t{4}".format( self, - " -- {}".format(self.description) if self.description else "", + f" -- {self.description}" if self.description else "", _format_tags(self.tags), _format_price(self.price), "\n\t".join(map(_format_type_and_choice, self.choices)), @@ -86,14 +91,20 @@ class Dish: return sum( f(option.price for option in choice.options) for (choice_type, choice) in self.choices - if choice_type == "single_choice" - ) + if choice_type == "single_choice") class Location: - def __init__( - self, id_, *, name, dishes, osm=None, address=None, telephone=None, website=None - ): + + def __init__(self, + id_, + *, + name, + dishes, + osm=None, + address=None, + telephone=None, + website=None): self.id: str = id_ self.name: str = name self.osm: Optional[str] = osm @@ -107,24 +118,18 @@ class Location: return first(filter(lambda d: d.id == dish_id, self.dishes)) def __str__(self): - return ( - "============================\n" - "{0.id}: {0.name}" - "{1}\n" - "============================\n" - "\n" - "{2}" - ).format( - self, - "".join( - "\n\t{} {}".format(k, v) - for k, v in ( - ("osm", self.osm), - ("address", self.address), - ("telephone", self.telephone), - ("website", self.website), + return ("============================\n" + "{0.id}: {0.name}" + "{1}\n" + "============================\n" + "\n" + "{2}").format( + self, + "".join(f"\n\t{k} {v}" for k, v in ( + ("osm", self.osm), + ("address", self.address), + ("telephone", self.telephone), + ("website", self.website), + ) if v is not None), + "\n".join(map(str, self.dishes)), ) - if v is not None - ), - "\n".join(map(str, self.dishes)), - ) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index 3f46b3e..21956e2 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -1,16 +1,17 @@ #!/usr/bin/env python3 -from glob import glob -from os import path import itertools from copy import deepcopy -from typing import Iterable, List, Union, Tuple +from glob import glob +from os import path +from typing import Iterable, List, Tuple, Union + from tatsu import parse as tatsu_parse from tatsu.ast import AST from tatsu.exceptions import SemanticError -from .models import Location, Choice, Option, Dish from utils import first +from .models import Choice, Dish, Location, Option # TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674 with open(path.join(path.dirname(__file__), "hlds.tatsu")) as fh: @@ -58,14 +59,16 @@ class HldsSemanticActions: option.price += dish.price dish.price = 0 dishes = list(dishes) - dishes.append(Dish( - "custom", - name="Vrije keuze", - description="Zet wat je wil in comment", - price=0, - tags=[], - choices=[], - )) + dishes.append( + Dish( + "custom", + name="Vrije keuze", + description="Zet wat je wil in comment", + price=0, + tags=[], + choices=[], + ) + ) attributes = {att["key"]: att["value"] for att in ast["attributes"]} @@ -145,7 +148,7 @@ def parse(menu: str) -> List[Location]: def parse_file(filename: str) -> List[Location]: - with open(filename, "r") as file_handle: + with open(filename) as file_handle: return parse(file_handle.read()) diff --git a/app/login.py b/app/login.py index 984ee4f..a7382fa 100644 --- a/app/login.py +++ b/app/login.py @@ -1,9 +1,8 @@ "Script for everything related to logging in and out" from flask import Blueprint, abort, redirect, session, url_for from flask_login import current_user, logout_user -from werkzeug.wrappers import Response - from models import User +from werkzeug.wrappers import Response from zeus import zeus_login auth_bp = Blueprint("auth_bp", __name__) diff --git a/app/migrations/env.py b/app/migrations/env.py index af87ade..819a4f3 100644 --- a/app/migrations/env.py +++ b/app/migrations/env.py @@ -1,10 +1,8 @@ "Script that runs migrations online or offline" -from __future__ import with_statement from logging.config import fileConfig from alembic import context - # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel diff --git a/app/migrations/versions/9159a6fed021_initial_haldis_support.py b/app/migrations/versions/9159a6fed021_initial_haldis_support.py index 5e4406f..710feb2 100644 --- a/app/migrations/versions/9159a6fed021_initial_haldis_support.py +++ b/app/migrations/versions/9159a6fed021_initial_haldis_support.py @@ -12,11 +12,11 @@ revision = "9159a6fed021" down_revision = "150252c1cdb1" from itertools import chain -from alembic import op -import sqlalchemy as sa -from sqlalchemy.sql import table, column, text +import sqlalchemy as sa +from alembic import op from hlds.definitions import location_definitions +from sqlalchemy.sql import column, table, text LOCATION_LEGACY_TO_HLDS = { 2: "blauw_kotje", @@ -50,71 +50,106 @@ LOCATION_LEGACY_TO_HLDS = { def upgrade(): # First the simple actions - op.create_table("order_item_choice", + op.create_table( + "order_item_choice", sa.Column("id", sa.Integer, nullable=False), sa.Column("choice_id", sa.String(length=64), nullable=True), sa.Column("order_item_id", sa.Integer, nullable=False), sa.Column("kind", sa.String(length=1), nullable=False), sa.Column("name", sa.String(length=120), nullable=True), sa.Column("value", sa.String(length=120), nullable=True), - sa.ForeignKeyConstraint(["order_item_id"], ["order_item.id"], ), - sa.PrimaryKeyConstraint("id") + sa.ForeignKeyConstraint( + ["order_item_id"], + ["order_item.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.add_column( + "order_item", + sa.Column("hlds_data_version", sa.String(length=40), nullable=True), + ) + op.alter_column( + "order", "courrier_id", new_column_name="courier_id", type_=sa.Integer + ) + op.alter_column( + "order_item", + "extra", + new_column_name="comment", + existing_type=sa.String(254), + type_=sa.Text, + ) + op.alter_column( + "order_item", "name", new_column_name="user_name", type_=sa.String(120) ) - op.add_column("order_item", sa.Column("hlds_data_version", sa.String(length=40), nullable=True)) - op.alter_column("order", "courrier_id", new_column_name="courier_id", type_=sa.Integer) - op.alter_column("order_item", "extra", new_column_name="comment", - existing_type=sa.String(254), type_=sa.Text) - op.alter_column("order_item", "name", new_column_name="user_name", type_=sa.String(120)) - #---------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------- # Migrate historical product data to order items # First create the new columns we will populate - op.add_column("order_item", sa.Column("dish_id", sa.String(length=64), nullable=True)) - op.add_column("order_item", sa.Column("dish_name", sa.String(length=120), nullable=True)) + op.add_column( + "order_item", sa.Column("dish_id", sa.String(length=64), nullable=True) + ) + op.add_column( + "order_item", sa.Column("dish_name", sa.String(length=120), nullable=True) + ) op.add_column("order_item", sa.Column("price", sa.Integer(), nullable=True)) # Brief, ad-hoc table constructs just for our UPDATE statement, see # https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations.execute - order_item = table("order_item", + order_item = table( + "order_item", column("product_id", sa.Integer), column("dish_id", sa.String), column("dish_name", sa.String), - column("price", sa.Integer) + column("price", sa.Integer), ) # Construct and execute queries - op.execute(text(""" + op.execute( + text( + """ UPDATE order_item SET dish_name = (SELECT product.name FROM product WHERE product.id = order_item.product_id), price = (SELECT product.price FROM product WHERE product.id = order_item.product_id)""" - )) + ) + ) # Historical product data migrated, drop obsolete column and table op.execute(text("ALTER TABLE order_item DROP FOREIGN KEY order_item_ibfk_3")) op.drop_column("order_item", "product_id") op.drop_table("product") - #---------------------------------------------------------------------------------------------- + # ---------------------------------------------------------------------------------------------- # Migrate historical location data to orders op.execute(text("ALTER TABLE `order` DROP FOREIGN KEY order_ibfk_2")) - op.alter_column("order", "location_id", new_column_name="legacy_location_id", - type_=sa.Integer, nullable=True) - op.add_column("order", sa.Column("location_id", sa.String(length=64), nullable=True)) - op.add_column("order", sa.Column("location_name", sa.String(length=128), nullable=True)) + op.alter_column( + "order", + "location_id", + new_column_name="legacy_location_id", + type_=sa.Integer, + nullable=True, + ) + op.add_column( + "order", sa.Column("location_id", sa.String(length=64), nullable=True) + ) + op.add_column( + "order", sa.Column("location_name", sa.String(length=128), nullable=True) + ) # Brief, ad-hoc table constructs just for our UPDATE statement, see # https://alembic.sqlalchemy.org/en/latest/ops.html#alembic.operations.Operations.execute - order = table("order", + order = table( + "order", column("legacy_location_id", sa.Integer), column("location_id", sa.String), - column("location_name", sa.String) + column("location_name", sa.String), ) # Construct and execute queries new_location_id = [ order.update() - .where(order.c.legacy_location_id == old_id) - .values(location_id=new_id) + .where(order.c.legacy_location_id == old_id) + .values(location_id=new_id) for old_id, new_id in LOCATION_LEGACY_TO_HLDS.items() ] - location_name_from_location = text(""" + location_name_from_location = text( + """ UPDATE `order` SET location_name = (SELECT location.name FROM location WHERE location.id = `order`.legacy_location_id)""" diff --git a/app/models/order.py b/app/models/order.py index b990f04..b738c45 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -1,10 +1,11 @@ "Script for everything Order related in the database" import typing -from datetime import datetime from collections import defaultdict +from datetime import datetime -from utils import first from hlds.definitions import location_definitions +from utils import first + from .database import db from .user import User @@ -31,9 +32,9 @@ class Order(db.Model): def __repr__(self) -> str: # pylint: disable=R1705 if self.location: - return "Order %d @ %s" % (self.id, self.location.name or "None") + return f"Order {self.id} @ {self.location.name or 'None'}" else: - return "Order %d" % (self.id) + return f"Order {self.id}" def update_from_hlds(self) -> None: """ @@ -46,19 +47,21 @@ class Order(db.Model): self.location_name = self.location.name def for_user(self, anon=None, user=None) -> typing.List: + "Get the items for a certain user" return list( filter( (lambda i: i.user == user) if user is not None else (lambda i: i.user_name == anon), - self.items + self.items, ) ) def group_by_user(self) -> typing.List[typing.Tuple[str, typing.List]]: "Group items of an Order by user" - group: typing.Dict[str, typing.List] = dict() + group: typing.Dict[str, typing.List] = {} + # pylint: disable=E1133 for item in self.items: if item.for_name not in group: group[item.for_name] = [] @@ -70,12 +73,17 @@ class Order(db.Model): return list(sorted(group.items(), key=lambda t: (t[0] or "", t[1] or ""))) - def group_by_dish(self) \ - -> typing.List[typing.Tuple[str, int, typing.List[typing.Tuple[str, typing.List]]]]: + def group_by_dish( + self, + ) -> typing.List[ + typing.Tuple[str, int, typing.List[typing.Tuple[str, typing.List]]] + ]: "Group items of an Order by dish" - group: typing.Dict[str, typing.Dict[str, typing.List]] = \ - defaultdict(lambda: defaultdict(list)) + group: typing.Dict[str, typing.Dict[str, typing.List]] = defaultdict( + lambda: defaultdict(list) + ) + # pylint: disable=E1133 for item in self.items: group[item.dish_name][item.comment].append(item) @@ -87,12 +95,13 @@ class Order(db.Model): sorted( (comment, sorted(items, key=lambda x: (x.for_name or ""))) for comment, items in comment_group.items() - ) + ), ) for dish_name, comment_group in group.items() ) def is_closed(self) -> bool: + "Return whether or not the order is closed" return self.stoptime and datetime.now() > self.stoptime def can_close(self, user_id: int) -> bool: diff --git a/app/models/orderitem.py b/app/models/orderitem.py index 253cd85..b865b51 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -1,8 +1,9 @@ "Script for everything OrderItem related in the database" from datetime import datetime -from utils import first from hlds.definitions import location_definitions +from utils import first + from .database import db from .order import Order from .user import User @@ -21,20 +22,20 @@ class OrderItem(db.Model): comment = db.Column(db.Text(), nullable=True) hlds_data_version = db.Column(db.String(40), nullable=True) - choices = db.relationship("OrderItemChoice", backref="order_item", lazy="dynamic") + choices = db.relationship("OrderItemChoice", + backref="order_item", + lazy="dynamic") def __getattr__(self, name): if name == "dish": - location_id = ( - Order.query.filter(Order.id == self.order_id).first().location_id - ) + location_id = (Order.query.filter( + Order.id == self.order_id).first().location_id) location = first( - filter(lambda l: l.id == location_id, location_definitions) - ) + filter(lambda l: l.id == location_id, location_definitions)) if location: - return first(filter(lambda d: d.id == self.dish_id, location.dishes)) - else: - raise ValueError("No Location found with id: " + location_id) + return first( + filter(lambda d: d.id == self.dish_id, location.dishes)) + raise ValueError(f"No Location found with id: {location_id}") raise AttributeError() @property @@ -45,11 +46,7 @@ class OrderItem(db.Model): return self.user_name def __repr__(self) -> str: - return "Order %d: %s wants %s" % ( - self.order_id or 0, - self.for_name, - self.dish_name or "None", - ) + return "Order {self.order_id or 0}: {self.for_name} wants {self.dish_name or 'None'}" def update_from_hlds(self) -> None: """ diff --git a/app/models/orderitemchoice.py b/app/models/orderitemchoice.py index d87c802..3bcd609 100644 --- a/app/models/orderitemchoice.py +++ b/app/models/orderitemchoice.py @@ -1,3 +1,4 @@ +"Script for everything OrderItemChoice related in the database" from datetime import datetime from .database import db @@ -5,6 +6,7 @@ from .orderitem import OrderItem class OrderItemChoice(db.Model): + "Class used for configuring the OrderItemChoice model in the database" id = db.Column(db.Integer, primary_key=True) choice_id = db.Column(db.String(64), nullable=True) order_item_id = db.Column( @@ -16,7 +18,8 @@ class OrderItemChoice(db.Model): # pylint: disable=attribute-defined-outside-init def configure(self, order: OrderItem) -> None: + "Set the orderitem" self.order = order def __repr__(self) -> str: - return "{}: {}".format(self.name, self.value) + return f"{self.name}: {self.value}" diff --git a/app/models/user.py b/app/models/user.py index 35596d1..8e78b2f 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -39,4 +39,4 @@ class User(db.Model): return str(self.id) def __repr__(self) -> str: - return "%s" % self.username + return f"{self.username}" diff --git a/app/notification.py b/app/notification.py index 59d6c3d..fa97045 100644 --- a/app/notification.py +++ b/app/notification.py @@ -16,7 +16,7 @@ def webhook_text(order: Order) -> typing.Optional[str]: return None if order.courier is not None: - # pylint: disable=C0301 + # pylint: disable=C0301, C0209 return " {3} is going to {1}, order <{0}|here>! Deadline in {2} minutes!".format( url_for("order_bp.order_from_id", order_id=order.id, _external=True), order.location_name, @@ -24,6 +24,7 @@ def webhook_text(order: Order) -> typing.Optional[str]: order.courier.username.title(), ) + # pylint: disable=C0209 return " New order for {}. Deadline in {} minutes. <{}|Open here.>".format( order.location_name, remaining_minutes(order.stoptime), @@ -43,7 +44,7 @@ class WebhookSenderThread(Thread): "Extension of the Thread class, which sends a webhook for the notification" def __init__(self, message: str, url: str) -> None: - super(WebhookSenderThread, self).__init__() + super().__init__() self.message = message self.url = url @@ -64,4 +65,4 @@ def remaining_minutes(value) -> str: if delta.total_seconds() < 0: return "0" minutes = delta.total_seconds() // 60 - return "%02d" % minutes + return f"{minutes:02}" diff --git a/app/parse_hlds.py b/app/parse_hlds.py index ac58c44..d55a271 100755 --- a/app/parse_hlds.py +++ b/app/parse_hlds.py @@ -1,9 +1,7 @@ #!/usr/bin/env python3 -from tatsu.util import asjson from hlds.parser import parse_files - USAGE = """{0} [filename]... Parse HLDS files, print as JSON diff --git a/app/utils.py b/app/utils.py index 60a382f..5ec5133 100644 --- a/app/utils.py +++ b/app/utils.py @@ -9,9 +9,9 @@ def euro_string(value: int) -> str: """ euro, cents = divmod(value, 100) if cents: - return "€ {}.{:02}".format(euro, cents) + return f"€ {euro}.{cents:02}" else: - return "€ {}".format(euro) + return f"€ {euro}" def price_range_string(price_range, include_upper=False): diff --git a/app/views/debug.py b/app/views/debug.py index aed320d..ea0930b 100644 --- a/app/views/debug.py +++ b/app/views/debug.py @@ -17,12 +17,12 @@ def list_routes() -> str: for rule in app.url_map.iter_rules(): options = {} for arg in rule.arguments: - options[arg] = "[{0}]".format(arg) + options[arg] = f"[{arg}]" print(rule.endpoint) methods = ",".join(rule.methods) url = url_for(rule.endpoint, **options) line = urllib.parse.unquote( - "{:50s} {:20s} {}".format(rule.endpoint, methods, url) + f"{rule.endpoint:50s} {methods:20s} {url}" ) output.append(line) diff --git a/app/views/general.py b/app/views/general.py index 5511856..42753b6 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -1,32 +1,26 @@ "Script to generate the general views of Haldis" +import json import os from datetime import datetime, timedelta - -import yaml from typing import Optional -from flask import Flask, render_template, make_response -from flask import request, jsonify -from flask import Blueprint, abort +import yaml +from flask import Blueprint, Flask, abort from flask import current_app as app -from flask import send_from_directory, url_for +from flask import (jsonify, make_response, render_template, request, + send_from_directory, url_for) from flask_login import login_required - -from utils import first from hlds.definitions import location_definitions from hlds.models import Location from models import Order - +from utils import first # import views from views.order import get_orders -import json -from flask import jsonify - general_bp = Blueprint("general_bp", __name__) -with open(os.path.join(os.path.dirname(__file__), "themes.yml"), "r") as _stream: +with open(os.path.join(os.path.dirname(__file__), "themes.yml")) as _stream: _theme_data = yaml.safe_load(_stream) THEME_OPTIONS = _theme_data["options"] THEMES = _theme_data["themes"] @@ -37,7 +31,7 @@ def home() -> str: "Generate the home view" prev_day = datetime.now() - timedelta(days=1) recently_closed = get_orders( - ((Order.stoptime > prev_day) & (Order.stoptime < datetime.now())) + (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) ) return render_template( "home.html", orders=get_orders(), recently_closed=recently_closed @@ -60,7 +54,7 @@ def is_theme_active(theme, now): return start_datetime <= now <= end_datetime - raise Exception("Unknown theme type {}".format(theme_type)) + raise Exception(f"Unknown theme type {theme_type}") def get_theme_css(theme, options): @@ -71,13 +65,18 @@ def get_theme_css(theme, options): for option in theme.get("options", []): theme_name = theme["name"] - assert option in THEME_OPTIONS, f"Theme `{theme_name}` uses undefined option `{option}`" + assert ( + option in THEME_OPTIONS + ), f"Theme `{theme_name}` uses undefined option `{option}`" chosen_value = options[option] possible_values = list(THEME_OPTIONS[option].keys()) - value = chosen_value if chosen_value in possible_values \ + value = ( + chosen_value + if chosen_value in possible_values else THEME_OPTIONS[option]["_default"] + ) filename += "_" + value @@ -119,13 +118,15 @@ def current_theme_js(): themes = get_active_themes() selected_theme_name = request.cookies.get("theme", None) - matching_theme = first((t for t in themes if t["file"] == selected_theme_name)) + matching_theme = first(t for t in themes if t["file"] == selected_theme_name) cur_theme = matching_theme or themes[-1] - response = make_response(rf''' + response = make_response( + rf""" var currentTheme = {json.dumps(cur_theme['file'])}; var currentThemeOptions = {json.dumps(cur_theme.get('options', []))}; -''') +""" + ) response.headers["Content-Type"] = "text/javascript" # Theme name that is not valid at this moment: delete cookie @@ -166,25 +167,27 @@ def location_dish(location_id, dish_id) -> str: dish = loc.dish_by_id(dish_id) if dish is None: abort(404) - return jsonify([ - { - "type": c[0], - "id": c[1].id, - "name": c[1].name, - "description": c[1].description, - "options": [ - { - "id": o.id, - "name": o.name, - "description": o.description, - "price": o.price, - "tags": o.tags, - } - for o in c[1].options - ], - } - for c in dish.choices - ]) + return jsonify( + [ + { + "type": c[0], + "id": c[1].id, + "name": c[1].name, + "description": c[1].description, + "options": [ + { + "id": o.id, + "name": o.name, + "description": o.description, + "price": o.price, + "tags": o.tags, + } + for o in c[1].options + ], + } + for c in dish.choices + ] + ) @general_bp.route("/about/") @@ -204,7 +207,7 @@ def profile() -> str: def favicon() -> str: "Generate the favicon" # pylint: disable=R1705 - if not get_orders((Order.stoptime > datetime.now())): + if not get_orders(Order.stoptime > datetime.now()): return send_from_directory( os.path.join(app.root_path, "static"), "favicon.ico", diff --git a/app/views/order.py b/app/views/order.py index 177c195..49ca679 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -3,27 +3,16 @@ import random import typing from datetime import datetime -from werkzeug.wrappers import Response - # from flask import current_app as app -from flask import ( - Blueprint, - abort, - flash, - redirect, - render_template, - request, - session, - url_for, - wrappers, -) +from flask import (Blueprint, abort, flash, redirect, render_template, request, + session, url_for, wrappers) from flask_login import current_user, login_required - from forms import AnonOrderItemForm, OrderForm, OrderItemForm +from hlds.definitions import location_definition_version, location_definitions from models import Order, OrderItem, User, db -from hlds.definitions import location_definitions, location_definition_version from notification import post_order_to_webhook from utils import ignore_none +from werkzeug.wrappers import Response order_bp = Blueprint("order_bp", "order") @@ -72,8 +61,8 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: form.populate(order.location) if order.is_closed(): form = None - total_price = sum([o.price for o in order.items]) - debts = sum([o.price for o in order.items if not o.paid]) + total_price = sum(o.price for o in order.items) + debts = sum(o.price for o in order.items if not o.paid) dish = order.location.dish_by_id(dish_id) if order.location else None @@ -96,7 +85,7 @@ def items_shop_view(order_id: int) -> str: if current_user.is_anonymous() and not order.public: flash("Please login to see this order.", "info") abort(401) - total_price = sum([o.price for o in order.items]) + total_price = sum(o.price for o in order.items) return render_template("order_items.html", order=order, total_price=total_price) @@ -138,7 +127,9 @@ def order_item_create(order_id: int) -> typing.Any: abort(404) form = AnonOrderItemForm() if current_user.is_anonymous() else OrderItemForm() - dish_id = request.form["dish_id"] if form.is_submitted() else request.args.get("dish") + dish_id = ( + request.form["dish_id"] if form.is_submitted() else request.args.get("dish") + ) if dish_id and not location.dish_by_id(dish_id): abort(404) if not form.is_submitted(): @@ -347,6 +338,6 @@ def get_orders(expression=None) -> typing.List[Order]: else: order_list = Order.query.filter( # pylint: disable=C0121 - (expression & (Order.public == True)) + expression & (Order.public == True) ).all() return order_list diff --git a/app/views/stats.py b/app/views/stats.py index 19ef0a2..863c4ae 100644 --- a/app/views/stats.py +++ b/app/views/stats.py @@ -1,10 +1,9 @@ "Script to generate the stats related views of Haldis" +from fatmodels import FatLocation, FatOrder, FatOrderItem, FatUser from flask import Blueprint from flask import current_app as app from flask import render_template -from fatmodels import FatLocation, FatOrder, FatOrderItem, FatUser - stats_blueprint = Blueprint("stats_blueprint", __name__) diff --git a/app/zeus.py b/app/zeus.py index bbb58d2..ebc16ab 100644 --- a/app/zeus.py +++ b/app/zeus.py @@ -1,12 +1,12 @@ "Script containing everything specific to ZeusWPI" import typing -from flask import Blueprint, current_app, flash, redirect, request, session, url_for +from flask import (Blueprint, current_app, flash, redirect, request, session, + url_for) from flask_login import login_user from flask_oauthlib.client import OAuth, OAuthException -from werkzeug.wrappers import Response - from models import User, db +from werkzeug.wrappers import Response oauth_bp = Blueprint("oauth_bp", __name__) @@ -14,8 +14,7 @@ oauth_bp = Blueprint("oauth_bp", __name__) def zeus_login(): "Log in using ZeusWPI" return current_app.zeus.authorize( - callback=url_for("oauth_bp.authorized", _external=True) - ) + callback=url_for("oauth_bp.authorized", _external=True)) @oauth_bp.route("/login/zeus/authorized") @@ -25,10 +24,8 @@ def authorized() -> typing.Any: "Check authorized status" resp = current_app.zeus.authorized_response() if resp is None: - return "Access denied: reason=%s error=%s" % ( - request.args["error"], - request.args["error_description"], - ) + # pylint: disable=C0301 + return f"Access denied: reason={request.args['error']} error={request.args['error_description']}" if isinstance(resp, OAuthException): return f"Access denied: {resp.message}
        {resp.data}" -- 2.43.4 From 781e4cd45b87fcf6db76d90963401519aa9e9760 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 22:05:38 +0200 Subject: [PATCH 126/197] Add requirements for running pylint --- pylint-requirement.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 pylint-requirement.txt diff --git a/pylint-requirement.txt b/pylint-requirement.txt new file mode 100644 index 0000000..3f622c3 --- /dev/null +++ b/pylint-requirement.txt @@ -0,0 +1,2 @@ +pylint-flask +pylint-flask-sqlalchemy -- 2.43.4 From 492d1ca91cc95c5f1fd86fbc88df5286bb95db71 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 20:08:29 +0200 Subject: [PATCH 127/197] Update script to read admins from configuration file --- app/add_admins.py | 23 ++++++----------------- app/config.example.py | 1 + 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/app/add_admins.py b/app/add_admins.py index 3e71c60..b3f8112 100644 --- a/app/add_admins.py +++ b/app/add_admins.py @@ -2,24 +2,13 @@ from models import User from app import db +from models import User +from config import Configuration def add() -> None: """Add users as admin.""" - feli = User() - feli.configure("feliciaan", True, 0) - db.session.add(feli) - - destro = User() - destro.configure("destro", True, 0) - db.session.add(destro) - - iepoev = User() - iepoev.configure("iepoev", True, 1) - db.session.add(iepoev) - - flynn = User() - flynn.configure("flynn", True, 0) - db.session.add(flynn) - - # To future developers, add yourself here + for username in Configuration.HALDIS_ADMINS: + user = User() + user.configure(username, True, 0) + db.session.add(user) diff --git a/app/config.example.py b/app/config.example.py index 191ce24..daac1ab 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -8,6 +8,7 @@ class Configuration: SQLALCHEMY_DATABASE_URI = "sqlite:///haldis.db" SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = True + HALDIS_ADMIN_USERS = [] SECRET_KEY = "" SLACK_WEBHOOK = None LOGFILE = "haldis.log" -- 2.43.4 From d59ad9abba81f98161306670a804104a29311095 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 20:33:53 +0200 Subject: [PATCH 128/197] Add readme documentation about the admin user --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26ba6b6..d5876d6 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Afterwards upgrade the database to the latest version using cd app python3 app.py db upgrade -You can now still seed the database by running +You can now still seed the database by running, note that you might want to put your name in the `HALDIS_ADMIN_USERS` in `app/config.py` ./populate-db.sh -- 2.43.4 From e93460743a1ec63cb06448b74c469839a0184b83 Mon Sep 17 00:00:00 2001 From: Jan-Pieter Baert Date: Tue, 19 Apr 2022 23:20:03 +0200 Subject: [PATCH 129/197] Fix pylint on everything Except hlds related files because that's a mess --- .pylintrc | 2 +- app/admin.py | 6 +++++ app/app.py | 61 +++++++++++++++++++++--------------------- app/create_database.py | 2 +- app/fatmodels.py | 23 +++++++++++----- app/forms.py | 1 + app/parse_hlds.py | 1 + app/utils.py | 5 ++-- 8 files changed, 60 insertions(+), 41 deletions(-) diff --git a/.pylintrc b/.pylintrc index ca0b539..fd2a27f 100644 --- a/.pylintrc +++ b/.pylintrc @@ -5,7 +5,7 @@ # run arbitrary code. extension-pkg-whitelist= -fail-under=9 +fail-under=9.58 # Add files or directories to the blacklist. They should be base names, not # paths. diff --git a/app/admin.py b/app/admin.py index 8c7acac..24b7d99 100644 --- a/app/admin.py +++ b/app/admin.py @@ -1,3 +1,4 @@ +"Module for everything related to Admin users" import flask_login as login from flask import Flask from flask_admin import Admin @@ -7,12 +8,15 @@ from models import Order, OrderItem, OrderItemChoice, User class ModelBaseView(ModelView): + "Class for the base view of the model" # pylint: disable=too-few-public-methods, no-self-use def is_accessible(self) -> bool: + "Function to check if the logged in user is an admin" return login.current_user.is_admin() class UserAdminModel(ModelBaseView): + "Class for the model of a UserAdmin" # pylint: disable=too-few-public-methods column_searchable_list = ("username",) column_editable_list = ("username",) @@ -21,6 +25,7 @@ class UserAdminModel(ModelBaseView): class OrderAdminModel(ModelBaseView): + "Class for the model of a OrderAdmin" # pylint: disable=too-few-public-methods column_default_sort = ("starttime", True) column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] @@ -34,6 +39,7 @@ class OrderAdminModel(ModelBaseView): class OrderItemAdminModel(ModelBaseView): + "Class for the model of a OrderItemAdmin" # pylint: disable=too-few-public-methods column_default_sort = ("order_id", True) column_list = [ diff --git a/app/app.py b/app/app.py index 0df5cf6..eacdd70 100755 --- a/app/app.py +++ b/app/app.py @@ -23,69 +23,70 @@ from utils import euro_string, price_range_string from zeus import init_oauth -def register_plugins(app: Flask) -> Manager: +def register_plugins(_app: Flask) -> Manager: + "Register the plugins to the app" # pylint: disable=W0612 - if not app.debug: + if not _app.debug: timedFileHandler = TimedRotatingFileHandler( - app.config["LOGFILE"], when="midnight", backupCount=100 + _app.config["LOGFILE"], when="midnight", backupCount=100 ) timedFileHandler.setLevel(logging.DEBUG) loglogger = logging.getLogger("werkzeug") loglogger.setLevel(logging.DEBUG) loglogger.addHandler(timedFileHandler) - app.logger.addHandler(timedFileHandler) + _app.logger.addHandler(timedFileHandler) # Initialize SQLAlchemy - db.init_app(app) + db.init_app(_app) # Initialize Flask-Migrate - migrate = Migrate(app, db) - app_manager = Manager(app) - app_manager.add_command("db", MigrateCommand) - app_manager.add_command("runserver", Server(port=8000)) - init_admin(app, db) + migrate = Migrate(_app, db) + _app_manager = Manager(_app) + _app_manager.add_command("db", MigrateCommand) + _app_manager.add_command("runserver", Server(port=8000)) + init_admin(_app, db) # Init login manager login_manager = LoginManager() - login_manager.init_app(app) + login_manager.init_app(_app) login_manager.anonymous_user = AnonymouseUser - init_login(app) + init_login(_app) # Add oauth - zeus = init_oauth(app) - app.zeus = zeus + zeus = init_oauth(_app) + _app.zeus = zeus # Load the bootstrap local cdn - Bootstrap(app) - app.config["BOOTSTRAP_SERVE_LOCAL"] = True + Bootstrap(_app) + _app.config["BOOTSTRAP_SERVE_LOCAL"] = True # use our own bootstrap theme - app.extensions["bootstrap"]["cdns"]["bootstrap"] = StaticCDN() + _app.extensions["bootstrap"]["cdns"]["bootstrap"] = StaticCDN() # Load the flask debug toolbar - toolbar = DebugToolbarExtension(app) + toolbar = DebugToolbarExtension(_app) # Make cookies more secure - app.config.update( + _app.config.update( SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SAMESITE="Lax", ) - if not app.debug: - app.config.update(SESSION_COOKIE_SECURE=True) + if not _app.debug: + _app.config.update(SESSION_COOKIE_SECURE=True) - return app_manager + return _app_manager -def add_handlers(app: Flask) -> None: +def add_handlers(_app: Flask) -> None: "Add handlers for 4xx error codes" # pylint: disable=W0612,W0613 - @app.errorhandler(404) + @_app.errorhandler(404) def handle404(e) -> typing.Tuple[str, int]: return render_template("errors/404.html"), 404 - @app.errorhandler(401) + @_app.errorhandler(401) def handle401(e) -> typing.Tuple[str, int]: return render_template("errors/401.html"), 401 @@ -112,7 +113,7 @@ def add_routes(application: Flask) -> None: application.register_blueprint(debug_bp, url_prefix="/debug") -def add_template_filters(app: Flask) -> None: +def add_template_filters(_app: Flask) -> None: "Add functions which can be used in the templates" # pylint: disable=W0612 @app.template_filter("countdown") @@ -144,10 +145,10 @@ def add_template_filters(app: Flask) -> None: def current_year(_value: typing.Any) -> str: return str(datetime.now().year) - app.template_filter("euro")(euro_string) - app.template_filter("price_range")(price_range_string) - app.template_filter("any")(any) - app.template_filter("all")(all) + _app.template_filter("euro")(euro_string) + _app.template_filter("price_range")(price_range_string) + _app.template_filter("any")(any) + _app.template_filter("all")(all) app = Flask(__name__) diff --git a/app/create_database.py b/app/create_database.py index a583eb6..df07727 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -41,7 +41,7 @@ def recreate_from_scratch() -> None: def add_to_current() -> None: """Add things to the current database""" - available = [entry_set for entry_set in entry_sets] + available = list(entry_sets) def add_numbers() -> str: return " ".join( diff --git a/app/fatmodels.py b/app/fatmodels.py index a2d349e..fd6cf8c 100644 --- a/app/fatmodels.py +++ b/app/fatmodels.py @@ -1,3 +1,4 @@ +"Module used for everything related to the fat versions of models" import typing from hlds.definitions import location_definitions @@ -7,16 +8,24 @@ from sqlalchemy.sql import desc, func class FatModel: + "General class for the fat version of models" + @classmethod def all(cls): + "Function to query all" + # pylint: disable=E1101 return cls.query.all() @classmethod def amount(cls): + "Function to query the amount" + # pylint: disable=E1101 return cls.query.count() class FatLocation(Location, FatModel): + "Fat version of the Location model" + @classmethod def all(cls): return location_definitions @@ -27,6 +36,7 @@ class FatLocation(Location, FatModel): class FatOrder(Order, FatModel): + "Fat version of the Order model" # It's hard to add the unique user constraint, # as DISTINCT seems to apply after a GROUP BY and aggregate @@ -34,16 +44,15 @@ class FatOrder(Order, FatModel): # even if they get reduced by the disctinct afterwards. @classmethod def items_per_order(cls): - return ( - Order.query.join(OrderItem) - .group_by(Order.id) - .with_entities(Order.id, func.count(OrderItem.user_id).label("total")) - ) + "Function to get the total of all items per order" + return (Order.query.join(OrderItem).group_by(Order.id).with_entities( + Order.id, + func.count(OrderItem.user_id).label("total"))) class FatUser(User, FatModel): - pass + "Fat version of the User model" class FatOrderItem(OrderItem, FatModel): - pass + "Fat version of the OrderItem model" diff --git a/app/forms.py b/app/forms.py index d50c9f1..4d5a1c2 100644 --- a/app/forms.py +++ b/app/forms.py @@ -50,6 +50,7 @@ class OrderItemForm(Form): submit_button = SubmitField("Submit") def populate(self, location: Location) -> None: + "Populate the order item form" self.dish_id.choices = [(dish.id, dish.name) for dish in location.dishes] if not self.is_submitted() and self.comment.data is None: self.comment.data = request.args.get("comment") diff --git a/app/parse_hlds.py b/app/parse_hlds.py index d55a271..ca2d535 100755 --- a/app/parse_hlds.py +++ b/app/parse_hlds.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +"Module used for parsing the HLDS files" from hlds.parser import parse_files diff --git a/app/utils.py b/app/utils.py index 5ec5133..91c9793 100644 --- a/app/utils.py +++ b/app/utils.py @@ -10,11 +10,11 @@ def euro_string(value: int) -> str: euro, cents = divmod(value, 100) if cents: return f"€ {euro}.{cents:02}" - else: - return f"€ {euro}" + return f"€ {euro}" def price_range_string(price_range, include_upper=False): + "Convert a price range to a string formatted euro" if price_range[0] == price_range[1]: return euro_string(price_range[0]) return ("{}—{}" if include_upper else "from {}").format( @@ -33,4 +33,5 @@ def first(iterable: Iterable, default=None): def ignore_none(iterable: Iterable): + "Filter to ignore None objects" return filter(lambda x: x is not None, iterable) -- 2.43.4 From ae77adc54e53056b624738718e95064c66bdd729 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Tue, 19 Apr 2022 23:59:23 +0200 Subject: [PATCH 130/197] Add flask factory to scope app variable --- app/app.py | 91 ++++++++++++++++++++++++++++------------------------ app/forms.py | 2 +- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/app/app.py b/app/app.py index eacdd70..8a7cc64 100755 --- a/app/app.py +++ b/app/app.py @@ -23,76 +23,77 @@ from utils import euro_string, price_range_string from zeus import init_oauth -def register_plugins(_app: Flask) -> Manager: - "Register the plugins to the app" +def register_plugins(app: Flask) -> Manager: + """Register the plugins to the app""" # pylint: disable=W0612 - if not _app.debug: + if not app.debug: timedFileHandler = TimedRotatingFileHandler( - _app.config["LOGFILE"], when="midnight", backupCount=100 + app.config["LOGFILE"], when="midnight", backupCount=100 ) timedFileHandler.setLevel(logging.DEBUG) loglogger = logging.getLogger("werkzeug") loglogger.setLevel(logging.DEBUG) loglogger.addHandler(timedFileHandler) - _app.logger.addHandler(timedFileHandler) + app.logger.addHandler(timedFileHandler) # Initialize SQLAlchemy - db.init_app(_app) + db.init_app(app) # Initialize Flask-Migrate - migrate = Migrate(_app, db) - _app_manager = Manager(_app) - _app_manager.add_command("db", MigrateCommand) - _app_manager.add_command("runserver", Server(port=8000)) - init_admin(_app, db) + migrate = Migrate(app, db) + app_manager = Manager(app) + app_manager.add_command("db", MigrateCommand) + app_manager.add_command("runserver", Server(port=8000)) + init_admin(app, db) # Init login manager login_manager = LoginManager() - login_manager.init_app(_app) + login_manager.init_app(app) login_manager.anonymous_user = AnonymouseUser - init_login(_app) + init_login(app) # Add oauth - zeus = init_oauth(_app) - _app.zeus = zeus + zeus = init_oauth(app) + app.zeus = zeus # Load the bootstrap local cdn - Bootstrap(_app) - _app.config["BOOTSTRAP_SERVE_LOCAL"] = True + Bootstrap(app) + app.config["BOOTSTRAP_SERVE_LOCAL"] = True # use our own bootstrap theme - _app.extensions["bootstrap"]["cdns"]["bootstrap"] = StaticCDN() + app.extensions["bootstrap"]["cdns"]["bootstrap"] = StaticCDN() # Load the flask debug toolbar - toolbar = DebugToolbarExtension(_app) + toolbar = DebugToolbarExtension(app) # Make cookies more secure - _app.config.update( + app.config.update( SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SAMESITE="Lax", ) - if not _app.debug: - _app.config.update(SESSION_COOKIE_SECURE=True) + if not app.debug: + app.config.update(SESSION_COOKIE_SECURE=True) - return _app_manager + return app_manager -def add_handlers(_app: Flask) -> None: - "Add handlers for 4xx error codes" +def add_handlers(app: Flask) -> None: + """Add handlers for 4xx error codes""" + # pylint: disable=W0612,W0613 - @_app.errorhandler(404) + @app.errorhandler(404) def handle404(e) -> typing.Tuple[str, int]: return render_template("errors/404.html"), 404 - @_app.errorhandler(401) + @app.errorhandler(401) def handle401(e) -> typing.Tuple[str, int]: return render_template("errors/401.html"), 401 def add_routes(application: Flask) -> None: - "Add all routes to Haldis" + """Add all routes to Haldis""" # import views # TODO convert to blueprint # import views.stats # TODO convert to blueprint @@ -113,8 +114,9 @@ def add_routes(application: Flask) -> None: application.register_blueprint(debug_bp, url_prefix="/debug") -def add_template_filters(_app: Flask) -> None: - "Add functions which can be used in the templates" +def add_template_filters(app: Flask) -> None: + """Add functions which can be used in the templates""" + # pylint: disable=W0612 @app.template_filter("countdown") def countdown( @@ -145,23 +147,28 @@ def add_template_filters(_app: Flask) -> None: def current_year(_value: typing.Any) -> str: return str(datetime.now().year) - _app.template_filter("euro")(euro_string) - _app.template_filter("price_range")(price_range_string) - _app.template_filter("any")(any) - _app.template_filter("all")(all) + app.template_filter("euro")(euro_string) + app.template_filter("price_range")(price_range_string) + app.template_filter("any")(any) + app.template_filter("all")(all) -app = Flask(__name__) +def create_app(): + """Initializer for the Flask app object""" + app = Flask(__name__) -# Load the config file -app.config.from_object("config.Configuration") + # Load the config file + app.config.from_object("config.Configuration") -app_manager = register_plugins(app) -add_handlers(app) -add_routes(app) -add_template_filters(app) + app_manager = register_plugins(app) + add_handlers(app) + add_routes(app) + add_template_filters(app) + + return app_manager # For usage when you directly call the script with python if __name__ == "__main__": - app_manager.run() + app_mgr = create_app() + app_mgr.run() diff --git a/app/forms.py b/app/forms.py index 4d5a1c2..e259563 100644 --- a/app/forms.py +++ b/app/forms.py @@ -77,7 +77,7 @@ class AnonOrderItemForm(OrderItemForm): self.user_name.data = session.get("anon_name", None) def validate(self) -> bool: - "Check if the provided anon_name is not already taken" + """Check if the provided anon_name is not already taken""" rv = OrderForm.validate(self) if not rv: return False -- 2.43.4 From cc0c271a22b33241c268e25a12a1ef373ed5d45d Mon Sep 17 00:00:00 2001 From: mcbloch Date: Wed, 20 Apr 2022 01:27:52 +0200 Subject: [PATCH 131/197] Add working microsoft login flow --- .tool-versions | 1 + app/app.py | 14 ++++--- app/{ => auth}/login.py | 18 +++------ app/auth/microsoft.py | 77 +++++++++++++++++++++++++++++++++++++++ app/{ => auth}/zeus.py | 26 ++++++++----- app/config.example.py | 4 +- app/create_database.py | 4 +- app/models/user.py | 11 ++++-- app/templates/layout.html | 3 +- first-setup.sh | 2 +- requirements.in | 1 + requirements.txt | 34 +++++++++-------- 12 files changed, 145 insertions(+), 50 deletions(-) create mode 100644 .tool-versions rename app/{ => auth}/login.py (67%) create mode 100644 app/auth/microsoft.py rename app/{ => auth}/zeus.py (78%) diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..6826aa8 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.9.2 diff --git a/app/app.py b/app/app.py index 8a7cc64..72415f6 100755 --- a/app/app.py +++ b/app/app.py @@ -13,14 +13,13 @@ from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager from flask_migrate import Migrate, MigrateCommand -from flask_oauthlib.client import OAuth, OAuthException from flask_script import Manager, Server -from login import init_login +from auth.login import init_login from markupsafe import Markup from models import db from models.anonymous_user import AnonymouseUser from utils import euro_string, price_range_string -from zeus import init_oauth +from auth.zeus import init_oauth def register_plugins(app: Flask) -> Manager: @@ -97,18 +96,21 @@ def add_routes(application: Flask) -> None: # import views # TODO convert to blueprint # import views.stats # TODO convert to blueprint - from login import auth_bp + from auth.login import auth_bp + from auth.microsoft import auth_microsoft_bp + from auth.zeus import auth_zeus_bp from views.debug import debug_bp from views.general import general_bp from views.order import order_bp from views.stats import stats_blueprint - from zeus import oauth_bp application.register_blueprint(general_bp, url_prefix="/") application.register_blueprint(order_bp, url_prefix="/order") application.register_blueprint(stats_blueprint, url_prefix="/stats") application.register_blueprint(auth_bp, url_prefix="/") - application.register_blueprint(oauth_bp, url_prefix="/") + application.register_blueprint(auth_microsoft_bp, + url_prefix="/users/auth/microsoft_graph_auth") # "/auth/microsoft") + application.register_blueprint(auth_zeus_bp, url_prefix="/auth/zeus") if application.debug: application.register_blueprint(debug_bp, url_prefix="/debug") diff --git a/app/login.py b/app/auth/login.py similarity index 67% rename from app/login.py rename to app/auth/login.py index a7382fa..0cc621f 100644 --- a/app/login.py +++ b/app/auth/login.py @@ -1,31 +1,25 @@ -"Script for everything related to logging in and out" +"""Script for everything related to logging in and out""" from flask import Blueprint, abort, redirect, session, url_for from flask_login import current_user, logout_user from models import User from werkzeug.wrappers import Response -from zeus import zeus_login auth_bp = Blueprint("auth_bp", __name__) def init_login(app) -> None: - "Initialize the login" + """Initialize the login""" + # pylint: disable=W0612 @app.login_manager.user_loader def load_user(userid) -> User: - "Load the user" + """Load the user""" return User.query.filter_by(id=userid).first() -@auth_bp.route("/login") -def login(): - "Function to handle a user trying to log in" - return zeus_login() - - @auth_bp.route("/logout") def logout() -> Response: - "Function to handle a user trying to log out" + """Function to handle a user trying to log out""" if "zeus_token" in session: session.pop("zeus_token", None) logout_user() @@ -33,6 +27,6 @@ def logout() -> Response: def before_request() -> None: - "Function for what has to be done before a request" + """Function for what has to be done before a request""" if current_user.is_anonymous() or not current_user.is_allowed(): abort(401) diff --git a/app/auth/microsoft.py b/app/auth/microsoft.py new file mode 100644 index 0000000..d754a34 --- /dev/null +++ b/app/auth/microsoft.py @@ -0,0 +1,77 @@ +import typing + +from flask import Blueprint, url_for, request, redirect, flash, Response +from flask_login import login_user +from microsoftgraph.client import Client + +from config import Configuration +from models import User, db + +auth_microsoft_bp = Blueprint("auth_microsoft_bp", __name__) + +client = Client(Configuration.MICROSOFT_AUTH_ID, + Configuration.MICROSOFT_AUTH_SECRET, + account_type='common') # by default common, thus account_type is optional parameter. + + +def microsoft_login(): + """Log in using Microsoft""" + scope = ["openid", "profile", "User.Read", "User.Read.All"] + url = client.authorization_url(url_for("auth_microsoft_bp.authorized", _external=True), scope, state=None) + return redirect(url) + + +@auth_microsoft_bp.route("/login") +def login(): + """Function to handle a user trying to log in""" + return microsoft_login() + + +@auth_microsoft_bp.route("callback") # "/authorized") +def authorized() -> typing.Any: + # type is 'typing.Union[str, Response]', but this errors due to + # https://github.com/python/mypy/issues/7187 + """Check authorized status""" + + oauth_code = request.args['code'] + + resp = client.exchange_code(url_for("auth_microsoft_bp.authorized", _external=True), oauth_code) + + # access_token = resp.data['access_token'] + # id_token = resp.data['id_token'] + # expires_in = resp.data['expires_in'] + + client.set_token(resp.data) + + resp = client.users.get_me() + print(resp.data) + + username = resp.data['userPrincipalName'] + microsoft_uuid = resp.data['id'] + + user = User.query.filter_by(username=username).first() + + if username and user: + return login_and_redirect_user(user) + elif username: + # TODO Save 'ugent_username' or something similar + user = create_user(username, microsoft_uuid) + return login_and_redirect_user(user) + + flash("You're not allowed to enter, please contact a system administrator") + return redirect(url_for("general_bp.home")) + + +def login_and_redirect_user(user) -> Response: + """Log in the user and then redirect them""" + login_user(user) + return redirect(url_for("general_bp.home")) + + +def create_user(username, microsoft_uuid) -> User: + """Create a temporary user if it is needed""" + user = User() + user.configure(username, False, 1, microsoft_uuid) + db.session.add(user) + db.session.commit() + return user diff --git a/app/zeus.py b/app/auth/zeus.py similarity index 78% rename from app/zeus.py rename to app/auth/zeus.py index ebc16ab..35f6ec0 100644 --- a/app/zeus.py +++ b/app/auth/zeus.py @@ -4,24 +4,30 @@ import typing from flask import (Blueprint, current_app, flash, redirect, request, session, url_for) from flask_login import login_user -from flask_oauthlib.client import OAuth, OAuthException +from flask_oauthlib.client import OAuth, OAuthException, OAuthRemoteApp from models import User, db from werkzeug.wrappers import Response -oauth_bp = Blueprint("oauth_bp", __name__) +auth_zeus_bp = Blueprint("auth_zeus_bp", __name__) def zeus_login(): - "Log in using ZeusWPI" + """Log in using ZeusWPI""" return current_app.zeus.authorize( - callback=url_for("oauth_bp.authorized", _external=True)) + callback=url_for("auth_zeus_bp.authorized", _external=True)) -@oauth_bp.route("/login/zeus/authorized") +@auth_zeus_bp.route("/login") +def login(): + """Function to handle a user trying to log in""" + return zeus_login() + + +@auth_zeus_bp.route("/authorized") def authorized() -> typing.Any: # type is 'typing.Union[str, Response]', but this errors due to # https://github.com/python/mypy/issues/7187 - "Check authorized status" + """Check authorized status""" resp = current_app.zeus.authorized_response() if resp is None: # pylint: disable=C0301 @@ -45,8 +51,8 @@ def authorized() -> typing.Any: return redirect(url_for("general_bp.home")) -def init_oauth(app): - "Initialize the OAuth for ZeusWPI" +def init_oauth(app) -> OAuthRemoteApp: + """Initialize the OAuth for ZeusWPI""" oauth = OAuth(app) zeus = oauth.remote_app( @@ -69,13 +75,13 @@ def init_oauth(app): def login_and_redirect_user(user) -> Response: - "Log in the user and then redirect them" + """Log in the user and then redirect them""" login_user(user) return redirect(url_for("general_bp.home")) def create_user(username) -> User: - "Create a temporary user if it is needed" + """Create a temporary user if it is needed""" user = User() user.configure(username, False, 1) db.session.add(user) diff --git a/app/config.example.py b/app/config.example.py index daac1ab..5c1110a 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -1,4 +1,4 @@ -"An example for a Haldis config" +"""An example for a Haldis config""" # config @@ -14,3 +14,5 @@ class Configuration: LOGFILE = "haldis.log" ZEUS_KEY = "tomtest" ZEUS_SECRET = "blargh" + MICROSOFT_AUTH_ID = "" + MICROSOFT_AUTH_SECRET = "" diff --git a/app/create_database.py b/app/create_database.py index df07727..58ed446 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -2,7 +2,9 @@ import add_admins -from app import app_manager, db +from app import create_app, db + +app_manager = create_app() entry_sets = { "admins": add_admins.add, diff --git a/app/models/user.py b/app/models/user.py index 8e78b2f..8467048 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -3,11 +3,15 @@ from models import db class User(db.Model): - "Class used for configuring the User model in the database" + """Class used for configuring the User model in the database""" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) admin = db.Column(db.Boolean) bias = db.Column(db.Integer) + # Microsoft OAUTH info + microsoft_uuid = db.Column(db.String(120), unique=True) + ugent_username = db.Column(db.String(80), unique=True) + # Relations runs = db.relation( "Order", backref="courier", @@ -16,11 +20,12 @@ class User(db.Model): ) orderItems = db.relationship("OrderItem", backref="user", lazy="dynamic") - def configure(self, username: str, admin: bool, bias: int) -> None: - "Configure the User" + def configure(self, username: str, admin: bool, bias: int, microsoft_uuid: str = None) -> None: + """Configure the User""" self.username = username self.admin = admin self.bias = bias + self.microsoft_uuid = microsoft_uuid # pylint: disable=C0111, R0201 def is_authenticated(self) -> bool: diff --git a/app/templates/layout.html b/app/templates/layout.html index 72b85b7..9ba62c9 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -81,7 +81,8 @@

").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementHours").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-hour").attr("data-time-component","hours").attr("data-action","showHours"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementHours").append(a("").addClass(d.icons.down))))),x("m")&&(x("h")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementMinutes").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-minute").attr("data-time-component","minutes").attr("data-action","showMinutes"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementMinutes").append(a("").addClass(d.icons.down))))),x("s")&&(x("m")&&(b.append(a("").addClass("separator")),c.append(a("").addClass("separator").html(":")),e.append(a("").addClass("separator"))),b.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","incrementSeconds").append(a("").addClass(d.icons.up)))),c.append(a("").append(a("").addClass("timepicker-second").attr("data-time-component","seconds").attr("data-action","showSeconds"))),e.append(a("").append(a("").attr({href:"#",tabindex:"-1"}).addClass("btn").attr("data-action","decrementSeconds").append(a("").addClass(d.icons.down))))),f||(b.append(a("").addClass("separator")),c.append(a("").append(a("").addClass("separator"))),a("
").addClass("timepicker-picker").append(a("").addClass("table-condensed").append([b,c,e]))},C=function(){var b=a("
").addClass("timepicker-hours").append(a("
").addClass("table-condensed")),c=a("
").addClass("timepicker-minutes").append(a("
").addClass("table-condensed")),d=a("
").addClass("timepicker-seconds").append(a("
").addClass("table-condensed")),e=[B()];return x("h")&&e.push(b),x("m")&&e.push(c),x("s")&&e.push(d),e},D=function(){var b=[];return d.showTodayButton&&b.push(a(" - {%- endfor %} diff --git a/app/utils.py b/app/utils.py index f0b4245..cf2e02b 100644 --- a/app/utils.py +++ b/app/utils.py @@ -9,6 +9,11 @@ def euro_string(value: int) -> str: """ return "€ {}.{:02}".format(*divmod(value, 100)) +def price_range_string(price_range, include_upper=False): + if price_range[0] == price_range[1]: + return euro_string(price_range[0]) + return ("{}—{}" if include_upper else "from {}").format(*map(euro_string, price_range)) + def first(iterable: Iterable, default=None): """ -- 2.43.4 From 79c0056ff0dc2325a2970e3745ca32d3b584ecad Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 21:56:32 +0100 Subject: [PATCH 039/197] Fix incorrect selector in editorconfig --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 7a5daa9..893c1a0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ end_of_line = lf insert_final_newline = true indent_style = tab -[*.py,*.py.*] +[*.{py,py.*}] indent_style = space indent_size = 4 -- 2.43.4 From a860998858e70207c7a9bfede24bcce216d440c2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 22:26:00 +0100 Subject: [PATCH 040/197] Add choices to location view --- app/static/css/main.css | 4 ++++ app/templates/location.html | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 52d9881..10a54ab 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -290,3 +290,7 @@ h1, h2, h3, h4, h5, h6{ .enter_darkmode>a { text-align: center; } + +.dish-choices { + color: var(--dGray2); +} diff --git a/app/templates/location.html b/app/templates/location.html index 34f7453..5080a30 100644 --- a/app/templates/location.html +++ b/app/templates/location.html @@ -32,7 +32,17 @@ {% for dish in location.dishes -%} - + {%- endfor %} -- 2.43.4 From c52ba3b6d90382792eb182092f6e5ff49fa097c6 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 22:26:17 +0100 Subject: [PATCH 041/197] Stop parsing names at comment marker --- app/hlds/hlds.tatsu | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/hlds/hlds.tatsu b/app/hlds/hlds.tatsu index 6bc8e0d..b4d47b8 100644 --- a/app/hlds/hlds.tatsu +++ b/app/hlds/hlds.tatsu @@ -29,8 +29,8 @@ location = >location_header items:{ block } ; attributes = - name:/[^\n]*?(?= +-- | +:: | +€ |\n)/ - [ s '--' ~ s description:/[^\n]*?(?= +:: | +€ |\n)/ ] + name:/[^\n#]*?(?= +-- | +:: | +€ | *\n| *#)/ + [ s '--' ~ s description:/[^\n#]*?(?= +:: | +€ | *\n| *#)/ ] [ s '::' {s ('{' tags+:identifier '}')} ] [ [ s '::' ~ ] s price:price ] ; @@ -78,7 +78,7 @@ n = '\n' {{'\t'} '\n'} ; @name identifier = /[a-z0-9_-]+/ ; -string = /[^\n]+/ ; +string = /[^\n#]+/ ; choice_type = 'single_choice' | 'multi_choice' ; int = /[0-9]+/ ; -- 2.43.4 From 648f8da63b2af6ee6213ca73d834fd52eb416f11 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 23:12:16 +0100 Subject: [PATCH 042/197] Add S5 --- data/s5.hlds | 190 ++++++++++++++++++++++++++++++++++++++++++++ data/s5_generate.py | 89 +++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 data/s5.hlds create mode 100755 data/s5_generate.py diff --git a/data/s5.hlds b/data/s5.hlds new file mode 100644 index 0000000..eda521c --- /dev/null +++ b/data/s5.hlds @@ -0,0 +1,190 @@ +============================ +s5: S5 + osm https://www.openstreetmap.org/node/3752879366 + address Krijgslaan 281, 9000 Gent + website https://www.ugent.be/student/nl/meer-dan-studeren/resto/restos/restocampussterre.htm +============================ + +dish sandwich_kaas: Broodje Kaas -- Kaas, ei, komkommer, sla, tomaat en mayonaise + single_choice sandwich: Broodje + small_white: Klein wit € 1.40 + small_brown: Klein bruin € 1.40 + large_white: Groot wit € 2.10 + large_brown: Groot bruin € 2.10 + quattro: Quattro € 2.10 + +dish sandwich_kruidenkaas: Broodje Kruidenkaas -- Kruidenkaas, ei, komkommer, sla en tomaat + single_choice sandwich: Broodje + small_white: Klein wit € 1.40 + small_brown: Klein bruin € 1.40 + large_white: Groot wit € 2.10 + large_brown: Groot bruin € 2.10 + quattro: Quattro € 2.10 + +dish sandwich_kipcurry: Broodje Kip curry -- Kip curry, ei, komkommer, sla en tomaat + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.20 + large_brown: Groot bruin € 2.20 + quattro: Quattro € 2.20 + +dish sandwich_kipcurryhawa: Broodje Kip curry Hawaï -- Kip curry, ananas, ei, komkommer, sla en tomaat + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.20 + large_brown: Groot bruin € 2.20 + quattro: Quattro € 2.20 + +dish sandwich_vissalade: Broodje Vissalade -- Duurzame vissalade, tomaat, sla, komkommer en ei + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.30 + large_brown: Groot bruin € 2.30 + quattro: Quattro € 2.30 + +dish sandwich_ham: Broodje Ham -- Ham, ei, komkommer, sla, tomaat en mayonaise + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.30 + large_brown: Groot bruin € 2.30 + quattro: Quattro € 2.30 + +dish sandwich_prepare: Broodje Preparé -- Preparé, ei, komkommer, sla en tomaat + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.30 + large_brown: Groot bruin € 2.30 + quattro: Quattro € 2.30 + +dish sandwich_springbreak: Broodje Spring break -- Erwten-munt spread, komkommer, radijs, sla, croutons, cocktailsaus + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.40 + large_brown: Groot bruin € 2.40 + quattro: Quattro € 2.40 + +dish sandwich_argenteuil: Broodje Argenteuil -- Ham, asperge, ei, komkommer, sla, tomaat en mayonaise + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.40 + large_brown: Groot bruin € 2.40 + quattro: Quattro € 2.40 + +dish sandwich_brie: Broodje Brie -- Brie, honing, pijnboompitten, sla + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.50 + large_brown: Groot bruin € 2.50 + quattro: Quattro € 2.50 + +dish sandwich_caesar: Broodje Caesar -- Kippenreepjes, Gran Moravia kaasschilfers, croutons, sla en caesardressing + single_choice sandwich: Broodje + small_white: Klein wit € 1.50 + small_brown: Klein bruin € 1.50 + large_white: Groot wit € 2.50 + large_brown: Groot bruin € 2.50 + quattro: Quattro € 2.50 + +dish sandwich_martino: Broodje Martino -- Preparé, augurk, tomaat, mosterd en tabasco + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.40 + large_brown: Groot bruin € 2.40 + quattro: Quattro € 2.40 + +dish sandwich_maison: Broodje Maison -- Ham, kaas, augurk, ei, sla, tomaat, cocktailsaus en mayonaise + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.40 + large_brown: Groot bruin € 2.40 + quattro: Quattro € 2.40 + +dish sandwich_tropical: Broodje Tropical -- Ham, kaas, ananas, ei, sla, cocktailsaus + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.40 + large_brown: Groot bruin € 2.40 + quattro: Quattro € 2.40 + +dish sandwich_groentespread: Broodje Groentespread -- Weekelijks wisselende groentespread + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.60 + large_brown: Groot bruin € 2.60 + quattro: Quattro € 2.60 + +dish sandwich_gerooktezalmmetkruidenkaas: Broodje Gerookte zalm met kruidenkaas -- Gerookte zalm, kruidenkaas en ui + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.60 + large_brown: Groot bruin € 2.60 + quattro: Quattro € 2.60 + +dish sandwich_toscane: Broodje Toscane -- Mozzarella, prosciutto ham, sla en tomatensalsa + single_choice sandwich: Broodje + small_white: Klein wit € 1.60 + small_brown: Klein bruin € 1.60 + large_white: Groot wit € 2.70 + large_brown: Groot bruin € 2.70 + quattro: Quattro € 2.70 + +dish sandwich_geitenkaas: Broodje Geitenkaas -- Geitenkaas, appel, honing en sla + single_choice sandwich: Broodje + small_white: Klein wit € 1.70 + small_brown: Klein bruin € 1.70 + large_white: Groot wit € 2.60 + large_brown: Groot bruin € 2.60 + quattro: Quattro € 2.60 + +dish sandwich_tomaatmozzarella: Broodje Tomaat-mozzarella -- Mozzarella, tomaat, basilicumpesto en sla + single_choice sandwich: Broodje + small_white: Klein wit € 1.70 + small_brown: Klein bruin € 1.70 + large_white: Groot wit € 2.60 + large_brown: Groot bruin € 2.60 + quattro: Quattro € 2.60 + +dish sandwich_hoevebroodje: Broodje Hoevebroodje -- Geitenkaas, appel, honing, gebakken spek en sla + single_choice sandwich: Broodje + small_white: Klein wit € 1.70 + small_brown: Klein bruin € 1.70 + large_white: Groot wit € 2.60 + large_brown: Groot bruin € 2.60 + quattro: Quattro € 2.60 + +dish yoghurt: Natuuryoghurt € 0.4 +dish yofu: Plantaardige yofu € 1 +dish yoghurt_muesli: Yoghurt met muesli € 1 +dish greek_fruit_yoghurt: Griekse vruchtenyoghurt € 1.4 +dish chocolate_mousse: Chocomousse € 1.4 +dish speculoos_mousse: Speculaasmousse € 1.4 +dish soy_dessert: Soja dessert € 0.7 +dish tiramisu: Tiramisu € 1.4 +dish muffin: Muffin € 1 +dish donut: Donut € 1 +dish ice_variation: IJsvariatie € 2.3 +dish fruit: Fruit € 0.5 +dish nuts_fruit: Nuts & fruit € 1.5 + +dish chocolate_milk: Koude chocolademelk € 0.8 +dish juice: Fruitsap 20 cl Fair Trade € 0.8 +dish water: Bruisend water 50 cl € 0.8 +dish perfumed_water: Gearomatiseerd water 50 cl € 1 +dish bionade: Bionade € 1.5 +dish finley: Finley € 1 +dish iced_coffee: IJskoffie € 2 +dish iced_tea: IJsthee € 2 +dish smoothie: Smoothie € 2 diff --git a/data/s5_generate.py b/data/s5_generate.py new file mode 100755 index 0000000..05dda68 --- /dev/null +++ b/data/s5_generate.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 + +print("""============================ +s5: S5 + osm https://www.openstreetmap.org/node/3752879366 + address Krijgslaan 281, 9000 Gent + website https://www.ugent.be/student/nl/meer-dan-studeren/resto/restos/restocampussterre.htm +============================""") + +# Paste menu from https://www.ugent.be/student/nl/meer-dan-studeren/resto/broodjes/overzicht.htm +# here +MENU = [l.split("\t") for l in """ +Spring break Erwten-munt spread, komkommer, radijs, sla, croutons, cocktailsaus € 1,50 € 2,40 +Groentespread Weekelijks wisselende groentespread € 1,60 € 2,60 +Brie Brie, honing, pijnboompitten, sla € 1,50 € 2,50 +Geitenkaas Geitenkaas, appel, honing en sla € 1,70 € 2,60 +Kaas Kaas, ei, komkommer, sla, tomaat en mayonaise € 1,40 € 2,10 +Kruidenkaas Kruidenkaas, ei, komkommer, sla en tomaat € 1,40 € 2,10 +Tomaat-mozzarella Mozzarella, tomaat, basilicumpesto en sla € 1,70 € 2,60 +Kip curry Kip curry, ei, komkommer, sla en tomaat € 1,50 € 2,20 +Kip curry Hawaï Kip curry, ananas, ei, komkommer, sla en tomaat € 1,50 € 2,20 +Caesar Kippenreepjes, Gran Moravia kaasschilfers, croutons, sla en caesardressing € 1,50 € 2,50 +Gerookte zalm met kruidenkaas Gerookte zalm, kruidenkaas en ui € 1,60 € 2,60 +Vissalade Duurzame vissalade, tomaat, sla, komkommer en ei € 1,50 € 2,30 +Ham Ham, ei, komkommer, sla, tomaat en mayonaise € 1,50 € 2,30 +Preparé Preparé, ei, komkommer, sla en tomaat € 1,50 € 2,30 +Martino Preparé, augurk, tomaat, mosterd en tabasco € 1,60 € 2,40 +Hoevebroodje Geitenkaas, appel, honing, gebakken spek en sla € 1,70 € 2,60 +Maison Ham, kaas, augurk, ei, sla, tomaat, cocktailsaus en mayonaise € 1,60 € 2,40 +Tropical Ham, kaas, ananas, ei, sla, cocktailsaus € 1,60 € 2,40 +Toscane Mozzarella, prosciutto ham, sla en tomatensalsa € 1,60 € 2,70 +Argenteuil Ham, asperge, ei, komkommer, sla, tomaat en mayonaise € 1,50 € 2,40 +""".strip().split("\n")] +# Sort by price. This fails if price is not always exactly "€ x,xx" but whatever +MENU.sort(key=lambda dish: dish[2] + dish[3]) + +SANDWICHES = [ + [ # First price + ("small_white", "Klein wit "), + ("small_brown", "Klein bruin"), + ], + [ # Second price + ("large_white", "Groot wit "), + ("large_brown", "Groot bruin"), + ("quattro", " Quattro "), + ] +] + +def name_to_id(name): + return "".join(filter( + lambda c: ord("a") <= ord(c) <= ord("z"), + name.lower().replace("é", "e") + )) + +for dish in MENU: + print() + name, description = dish[0], dish[1] + prices = [p.replace(",", ".") for p in dish[2:]] + + print("dish sandwich_{}: Broodje {} -- {}".format(name_to_id(name), name, description)) + print("\tsingle_choice sandwich: Broodje") + for sandwiches, price in zip(SANDWICHES, prices): + for sw_id, sw_name in sandwiches: + print("\t\t{}: {} {}".format(sw_id, sw_name, price)) + +print(""" +dish yoghurt: Natuuryoghurt € 0.4 +dish yofu: Plantaardige yofu € 1 +dish yoghurt_muesli: Yoghurt met muesli € 1 +dish greek_fruit_yoghurt: Griekse vruchtenyoghurt € 1.4 +dish chocolate_mousse: Chocomousse € 1.4 +dish speculoos_mousse: Speculaasmousse € 1.4 +dish soy_dessert: Soja dessert € 0.7 +dish tiramisu: Tiramisu € 1.4 +dish muffin: Muffin € 1 +dish donut: Donut € 1 +dish ice_variation: IJsvariatie € 2.3 +dish fruit: Fruit € 0.5 +dish nuts_fruit: Nuts & fruit € 1.5 + +dish chocolate_milk: Koude chocolademelk € 0.8 +dish juice: Fruitsap 20 cl Fair Trade € 0.8 +dish water: Bruisend water 50 cl € 0.8 +dish perfumed_water: Gearomatiseerd water 50 cl € 1 +dish bionade: Bionade € 1.5 +dish finley: Finley € 1 +dish iced_coffee: IJskoffie € 2 +dish iced_tea: IJsthee € 2 +dish smoothie: Smoothie € 2""") -- 2.43.4 From e434aad3b8876618fcd9c9a5fe14cef25eaf2b68 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 2 Mar 2020 17:16:51 +0100 Subject: [PATCH 043/197] Creamy multi cheese doesn't have garlic sauce --- data/simpizza.hlds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/simpizza.hlds b/data/simpizza.hlds index bf7d3b2..42a744c 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -80,7 +80,7 @@ dish multi_cheese: Pizza multi cheese (veggie) -- Gorgonzola, fe dish creamy_multi_cheese: Pizza creamy multi cheese (veggie) -- Roomsaus, gorgonzola, feta, mozzarella, extra kaas single_choice size single_choice base - multi_choice sauce_no_garlic + multi_choice sauce dish 4_seasons: Pizza 4 seasons -- Ham, salami, champignons, paprika :: {has_meat} single_choice size single_choice base -- 2.43.4 From f60c1d180ce095b8f8218186f420f110c6140fe1 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 3 Mar 2020 16:21:01 +0100 Subject: [PATCH 044/197] Stub for choice selection --- app/templates/order.html | 44 ++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index e456ae3..b223ab2 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -54,24 +54,26 @@ - {% if dish and dish.choices %} - {% for (choice_type, choice) in dish.choices %} -
-
- -
- {% endfor %} - {% endif %} +
+ {% if dish and dish.choices %} + {% for (choice_type, choice) in dish.choices %} +
+
+ +
+ {% endfor %} + {% endif %} +
{{ form.comment.label(class='control-label') }}
@@ -202,5 +204,11 @@ var choice = options[index] select.val(choice.value).trigger("change") } + + function updateChoices() { + var dish_id = $("#dish_id").val(); + $("#dish_choices").html("Choices for " + dish_id); + } + $("#dish_id").on("change", updateChoices); {% endblock %} -- 2.43.4 From b8eb40e448c0f9e19e708551ebc22875a63be92c Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 4 Mar 2020 21:04:16 +0100 Subject: [PATCH 045/197] Add JSON representation for dish --- app/views/general.py | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/app/views/general.py b/app/views/general.py index 146809d..c04cc32 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -3,7 +3,7 @@ import os from datetime import datetime, timedelta import yaml -import typing +from typing import Optional from flask import Flask, render_template, make_response from flask import request, jsonify @@ -19,6 +19,9 @@ from models import Order # import views from views.order import get_orders +import json +from flask import jsonify + general_bp = Blueprint("general_bp", __name__) @@ -131,6 +134,35 @@ def location(location_id) -> str: return render_template("location.html", location=loc, title=loc.name) +@general_bp.route("/location//") +def location_dish(location_id, dish_id) -> str: + loc: Optional[Location] = first(filter(lambda l: l.id == location_id, location_definitions)) + if loc is None: + abort(404) + dish = loc.dish_by_id(dish_id) + if dish is None: + abort(404) + return jsonify([ + { + "type": c[0], + "id": c[1].id, + "name": c[1].name, + "description": c[1].description, + "options": [ + { + "id": o.id, + "name": o.name, + "description": o.description, + "price": o.price, + "tags": o.tags + } + for o in c[1].options + ] + } + for c in dish.choices + ]) + + @general_bp.route("/about/") def about() -> str: "Generate the about view" -- 2.43.4 From 54dc1f23bfbfd2ac0f61acfc1c298e4cf40910f8 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 4 Mar 2020 22:07:33 +0100 Subject: [PATCH 046/197] Show choices immediately when changing dish --- app/static/css/main.css | 4 +-- app/templates/order.html | 63 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 10a54ab..80ad07a 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -291,6 +291,6 @@ h1, h2, h3, h4, h5, h6{ text-align: center; } -.dish-choices { - color: var(--dGray2); +#dish_choices { + margin: 0.5em 1em 1.5em; } diff --git a/app/templates/order.html b/app/templates/order.html index b223ab2..8099c18 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -193,11 +193,11 @@ {{ super() }} {% endblock %} -- 2.43.4 From 0f9a816eea220f61caf4cd3aa35632d5a6cb3029 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 4 Mar 2020 22:35:55 +0100 Subject: [PATCH 047/197] Make choice updating after dish change smoother --- app/static/css/main.css | 4 ++++ app/templates/order.html | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 80ad07a..d5dc8b6 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -293,4 +293,8 @@ h1, h2, h3, h4, h5, h6{ #dish_choices { margin: 0.5em 1em 1.5em; + transition: opacity 0.2s; +} +#dish_choices.loading { + opacity: 0.2; } diff --git a/app/templates/order.html b/app/templates/order.html index 8099c18..e0bf1d8 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -207,10 +207,14 @@ {% if order.location %} function updateChoices() { + $("#submit-reveals-options-msg").hide(0); + $dish_choices = $("#dish_choices"); + $dish_choices.addClass("loading"); + var dish_id = $("#dish_id").val(); var url = "{{ url_for('general_bp.location_dish', location_id=order.location.id, dish_id='DISHID') }}".replace("DISHID", encodeURI(dish_id)); - $dish_choices = $("#dish_choices"); $dish_choices.find("select").attr("disabled", "disabled"); + $.get(url) .done(function(data) { $dish_choices.html(""); @@ -254,8 +258,11 @@ ); choiceSelect.select2({"sorter": sortArg}); } + $dish_choices.removeClass("loading"); }).fail(function() { $("#dish_choices").html("Could not load choices"); + $dish_choices.removeClass("loading"); + $("#submit-reveals-options-msg").show(0); }); } $("#dish_id").on("change", updateChoices); -- 2.43.4 From aba8301758588b9a2879ec7e6f82c531a4144888 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 4 Mar 2020 22:56:45 +0100 Subject: [PATCH 048/197] Better condition for moving price to options There's no point in doing this for Ocean Garden's stuff that has a fixed price. --- app/hlds/parser.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index 7728909..29d8aeb 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -25,15 +25,16 @@ def filter_instance(cls, iterable): class HldsSemanticActions: def location(self, ast) -> Location: choices = {choice.id: choice for choice in filter_instance(Choice, ast["items_"])} - dishes = filter_instance(Dish, ast["items_"]) + dishes: Iterable[Dish] = filter_instance(Dish, ast["items_"]) for dish in dishes: for i, choice in enumerate(dish.choices): if not isinstance(choice[1], Choice): dish.choices[i] = (dish.choices[i][0], deepcopy(choices[choice[1]])) - # Move the base price to the first single choice if there is any + # Move the base price to the first single_choice if the dish has a fixed price first_single_choice = first(c[1] for c in dish.choices if c[0] == "single_choice") - if dish.price and first_single_choice: + price_range = dish.price_range() + if dish.price and price_range[0] != price_range[1] and first_single_choice: for option in first_single_choice.options: option.price += dish.price dish.price = 0 -- 2.43.4 From 289b36b918594ca8a9819f818ac94e8e060d3175 Mon Sep 17 00:00:00 2001 From: Midgard Date: Thu, 5 Mar 2020 00:37:16 +0100 Subject: [PATCH 049/197] Correct timer behaviour, reload when time up --- app/app.py | 30 ++++++++----- app/static/js/timer.js | 78 +++++++++++++++++++++------------- app/templates/order.html | 6 ++- app/templates/order_items.html | 7 ++- app/templates/utils.html | 2 +- 5 files changed, 78 insertions(+), 45 deletions(-) diff --git a/app/app.py b/app/app.py index 6595a52..2d7b63c 100755 --- a/app/app.py +++ b/app/app.py @@ -14,6 +14,7 @@ from flask_login import LoginManager from flask_migrate import Migrate, MigrateCommand from flask_oauthlib.client import OAuth, OAuthException from flask_script import Manager, Server +from markupsafe import Markup from login import init_login from models import db @@ -146,17 +147,24 @@ def add_template_filters(app: Flask) -> None: # pylint: disable=W0612 @app.template_filter("countdown") def countdown(value, only_positive: bool = True, - show_text: bool = True) -> str: - "A function which returns time until the order is done" - delta = value - datetime.now() - if delta.total_seconds() < 0 and only_positive: - return "closed" - hours, remainder = divmod(delta.seconds, 3600) - minutes, seconds = divmod(remainder, 60) - time = "%02d:%02d:%02d" % (hours, minutes, seconds) - if show_text: - return f"{time} left" - return time + show_text: bool = True, reload: bool = True) -> str: + delta = int(value.timestamp() - datetime.now().timestamp()) + if delta < 0 and only_positive: + text = "closed" + else: + carry, seconds = divmod(delta, 60) + carry, minutes = divmod(carry, 60) + days, hours = divmod(carry, 24) + + days_text = f"{days} days, " if days else "" + + appendix = " left" if show_text else "" + text = f"{days_text}{hours:02d}:{minutes:02d}:{seconds:02d}{appendix}" + + reload_str = "yes" if reload else "no" + + return Markup(f"" + + text + "") @app.template_filter("year") def current_year(_value: typing.Any) -> str: diff --git a/app/static/js/timer.js b/app/static/js/timer.js index 127230c..baa4e35 100644 --- a/app/static/js/timer.js +++ b/app/static/js/timer.js @@ -1,36 +1,56 @@ -/** -* Created by feliciaan on 30/03/15. -*/ +var haldisCountdownStart = new Date(); $.ready(function(){ - $('.time').each(function() { - var timeEl = $( this ); - var time = timeEl.text().split(' ')[0].split(':'); + $(".time").each(function() { + var timeEl = $(this); - if (timeEl.text().indexOf('closed') < 0) { - window.setInterval(function () { - time = my_tick(time); - if (time !== "closed") { - timeS = ("0" + time[0]).slice(-2) + ":" + ("0" + time[1]).slice(-2) + ":" + ("0" + time[2]).slice(-2) + " left"; + var delta = parseInt(timeEl.data("seconds"), 10); + var end = new Date(haldisCountdownStart.getTime() + delta * 1000); + + var now = new Date(); + var delta = Math.floor((end - now) / 1000); + if (delta <= 0) { + timeEl.html("closed"); + return; + } + + function zeroPad(value) { + return ("0" + value).slice(-2) + } + + var intervalId; + + function update() { + var now = new Date(); + var delta = Math.floor((end - now) / 1000); + if (delta <= 0) { + window.clearInterval(intervalId); + if (timeEl.data("reload") === "yes") { + $("#form").slideUp(); + timeEl.html("closed, refreshing page..."); + window.setTimeout(function () { + window.location.reload(); + }, 2000); } else { - timeS = "closed" + timeEl.html("closed"); } - timeEl.html(timeS); - }, 1000); - } - }); + return; + } - function my_tick(time) { - if (time[2] > 0) { - time[2] = time[2] - 1; - } else if(time[1] > 0) { - time[2] = 59; - time[1] = time[1] - 1; - } else if(time[0] > 0) { - time[1] = 59; - time[0] = time[0] - 1; - } else { - return "closed"; + var seconds = delta % 60; + var carry = Math.floor(delta / 60); + var minutes = carry % 60; + carry = Math.floor(carry / 60); + var hours = carry % 24; + var days = Math.floor(carry / 24); + + var text = ""; + if (days) text = days + " days, "; + text += zeroPad(hours) + ":" + zeroPad(minutes) + ":" + zeroPad(seconds); + text += " left"; + + timeEl.html(text); } - return time; - } + intervalId = window.setInterval(update, 1000); + update(); + }); }()); diff --git a/app/templates/order.html b/app/templates/order.html index e0bf1d8..4dba8fe 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -35,7 +35,7 @@ {% endif %} start: {{ order.starttime.strftime("%d/%m/%Y %H:%M") }}
{% if order.stoptime %} - closing time: {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) + closing time: {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) {% else %}open{% endif %}
total price: {{ total_price|euro }} {% if courier_or_admin %}- remaining debts: {{ debts|euro }}{% endif %}
@@ -193,6 +193,7 @@ {{ super() }} + {% endblock %} {% block content -%} @@ -25,8 +28,8 @@ Haldis - Order {{ order.id }} {% if not order.is_closed() %}
- {{ order.stoptime|countdown }}
- Refresh page when closed! + {{ order.stoptime|countdown }} +
Refresh page when closed!
{% endif %} diff --git a/app/templates/utils.html b/app/templates/utils.html index d835c04..6a34e0f 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -5,7 +5,7 @@ {{ order.items.count() }} orders

{% if order.stoptime %} - Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} + Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} {% else %}open{% endif %}

-- 2.43.4 From 1fa38d08c682c82f82a1f4988988a58835082748 Mon Sep 17 00:00:00 2001 From: Midgard Date: Tue, 10 Mar 2020 18:39:11 +0100 Subject: [PATCH 050/197] Sort comments in order views --- app/models/order.py | 8 ++++++-- app/templates/order_items.html | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 360604c..d4f3fcf 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -56,15 +56,19 @@ class Order(db.Model): return group - def group_by_dish(self) -> typing.Dict[str, typing.Any]: + def group_by_dish(self, sort_comments=False) -> typing.Dict[str, typing.Dict[str, typing.Any]]: "Group items of an Order by dish" - group: typing.Dict[str, typing.Any] = dict() + group: typing.Dict[str, typing.Dict[str, typing.Any]] = dict() for item in self.items: dish = group.get(item.dish_name, dict()) dish["count"] = dish.get("count", 0) + 1 dish["comments"] = dish.get("comments", []) + [item.comment] group[item.dish_name] = dish + if sort_comments: + for _dish_name, dish_props in group.items(): + dish_props["comments"].sort() + return group def is_closed(self) -> bool: diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 12b0231..917c4aa 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -33,7 +33,7 @@ Haldis - Order {{ order.id }}
{% endif %} - {% for key, value in order.group_by_dish().items() -%} + {% for key, value in order.group_by_dish(True).items() -%}

{{ value["count"] }} × {{ key }}

{% if value["comments"]|any -%} -- 2.43.4 From 323a24ece6ccd36933af5e02bac18e152684b9a7 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sun, 21 Jun 2020 22:02:25 +0200 Subject: [PATCH 051/197] Add set -euo pipefail! --- first-setup.sh | 1 + populate-db.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/first-setup.sh b/first-setup.sh index b9f9585..d419c44 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # A simple file to run all instructions from the README ## this should be run in the root of the repository diff --git a/populate-db.sh b/populate-db.sh index 8318bd8..800b53b 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail cd app cp database/* . -- 2.43.4 From 5d6db78e6e1647371139ef8d1f1a1f2ce9d2fd2b Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 22 Jun 2020 18:43:52 +0200 Subject: [PATCH 052/197] Strip newline from HLDS data version --- app/hlds/definitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 56d1182..385e16d 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -18,4 +18,4 @@ location_definitions: List[Location] = parse_all_directory(DATA_DIR) location_definitions.sort(key=lambda l: l.name) proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, check=True) -location_definition_version = proc.stdout +location_definition_version = proc.stdout.decode().strip() -- 2.43.4 From 6282eed349dc56a11e201ccb01d673cb8f021486 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 22 Jun 2020 19:22:47 +0200 Subject: [PATCH 053/197] Improve app.py It should always create and expose the app object for uWSGI. --- app/app.py | 33 +++++++++++++-------------------- app/database/create_database.py | 7 +++---- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/app/app.py b/app/app.py index 2d7b63c..9bf0eaa 100755 --- a/app/app.py +++ b/app/app.py @@ -23,26 +23,9 @@ from utils import euro_string, price_range_string from zeus import init_oauth -def create_app() -> Manager: - "Create the Haldis application" - app = Flask(__name__) - - # Load the config file - app.config.from_object("config.Configuration") - - app_manager = register_plugins(app) - add_handlers(app) - add_routes(app) - add_template_filters(app) - - # TODO do we need to return and then run the manager? - return app_manager - - def register_plugins(app: Flask) -> Manager: - "Register all the plugins to Haldis" + "Register Airbrake and logrotation plugins" # pylint: disable=W0612 - # Register Airbrake and enable the logrotation if not app.debug: timedFileHandler = TimedRotatingFileHandler( app.config["LOGFILE"], when="midnight", backupCount=100 @@ -175,7 +158,17 @@ def add_template_filters(app: Flask) -> None: app.template_filter("any")(any) +app = Flask(__name__) + +# Load the config file +app.config.from_object("config.Configuration") + +app_manager = register_plugins(app) +add_handlers(app) +add_routes(app) +add_template_filters(app) + + # For usage when you directly call the script with python if __name__ == "__main__": - manager = create_app() - manager.run() + app_manager.run() diff --git a/app/database/create_database.py b/app/database/create_database.py index b7f4bb1..199c3aa 100644 --- a/app/database/create_database.py +++ b/app/database/create_database.py @@ -1,6 +1,6 @@ "Script for interaction and changes to the database" import add_admins -from app import db, create_app +from app import db, app_manager entry_sets = { "admins": add_admins.add, @@ -69,9 +69,8 @@ def add_to_current() -> None: print("Not a valid answer.") print("Thank you for adding, come again!") -manager = create_app() -@manager.command +@app_manager.command def setup_database(): #type: None "Start the database interaction script" print("Database modification script!") @@ -83,4 +82,4 @@ def setup_database(): #type: None commit() -manager.run() +app_manager.run() -- 2.43.4 From d904f3c5628fd20a652907d9ac7853b68df9335e Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 10:42:16 +0200 Subject: [PATCH 054/197] Make Airbrake optional --- app/app.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/app/app.py b/app/app.py index 9bf0eaa..91e52bb 100755 --- a/app/app.py +++ b/app/app.py @@ -6,7 +6,10 @@ from logging.handlers import TimedRotatingFileHandler import typing from datetime import datetime -from airbrake import Airbrake, AirbrakeHandler +try: + import airbrake +except ImportError: + airbrake = None from flask import Flask, render_template from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension @@ -37,18 +40,25 @@ def register_plugins(app: Flask) -> Manager: loglogger.addHandler(timedFileHandler) app.logger.addHandler(timedFileHandler) - airbrakelogger = logging.getLogger("airbrake") + if app.config["AIRBRAKE_ID"]: + if airbrake is None: + raise Exception( + "Airbrake support was requested (AIRBRAKE_ID is present in config), " + "but could not import airbrake. Make sure it's installed" + ) - # Airbrake - airbrake = Airbrake(project_id=app.config["AIRBRAKE_ID"], - api_key=app.config["AIRBRAKE_KEY"]) - # ugly hack to make this work for out errbit - airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=W0212 - airbrake.project_id - ) + airbrakelogger = logging.getLogger("airbrake") - airbrakelogger.addHandler(AirbrakeHandler(airbrake=airbrake)) - app.logger.addHandler(AirbrakeHandler(airbrake=airbrake)) + # Airbrake + airbrake = airbrake.Airbrake(project_id=app.config["AIRBRAKE_ID"], + api_key=app.config["AIRBRAKE_KEY"]) + # ugly hack to make this work for out errbit + airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=W0212 + airbrake.project_id + ) + + airbrakelogger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake)) + app.logger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake)) # Initialize SQLAlchemy db.init_app(app) -- 2.43.4 From fd5b432837790a0ef31c8c67b92a760533d8c229 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 11:06:27 +0200 Subject: [PATCH 055/197] Make Airbrake/Errbit support optional --- app/app.py | 11 ++++++----- first-setup.sh | 10 +++++++++- requirements.in | 1 - requirements.txt | 3 +-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/app.py b/app/app.py index 91e52bb..8ae89ee 100755 --- a/app/app.py +++ b/app/app.py @@ -44,16 +44,17 @@ def register_plugins(app: Flask) -> Manager: if airbrake is None: raise Exception( "Airbrake support was requested (AIRBRAKE_ID is present in config), " - "but could not import airbrake. Make sure it's installed" + "but could not import airbrake. Make sure `airbrake` is installed" ) airbrakelogger = logging.getLogger("airbrake") # Airbrake - airbrake = airbrake.Airbrake(project_id=app.config["AIRBRAKE_ID"], - api_key=app.config["AIRBRAKE_KEY"]) - # ugly hack to make this work for out errbit - airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=W0212 + airbrake = airbrake.Airbrake( + project_id=app.config["AIRBRAKE_ID"], api_key=app.config["AIRBRAKE_KEY"] + ) + # Change URL in a hacky way to make this work for our errbit + airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=protected-access airbrake.project_id ) diff --git a/first-setup.sh b/first-setup.sh index d419c44..868db65 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -22,6 +22,14 @@ pip install pip-tools echo -e "${B} Downloading dependencies ${E}" pip-sync +echo -en "${B} Do you want to install support for the Airbrake API for error logging? If you don't have an Errbit server or Airbrake account, answer no. (y/N) ${E}" +read confirm +if [ "$confirm" = y ]; then + pip install airbrake +else + echo "Not installing airbrake" +fi + echo -e "${B} Copying config template. All custom config options can be set in the config.py file ${E}" cd app cp config.example.py config.py @@ -30,4 +38,4 @@ cd .. echo -e "${B} Seeding database ${E}" ./populate-db.sh -echo -e "${B} Activate your venv using 'source venv/bin/activate'.\nThen run the server with 'python app/app.py runserver' ${E}" +echo -e "${B} Activate your venv using 'source venv/bin/activate'.\nThen run the development server with 'python app/app.py runserver' ${E}" diff --git a/requirements.in b/requirements.in index 8c56874..6bd107f 100644 --- a/requirements.in +++ b/requirements.in @@ -3,7 +3,6 @@ Flask-Login Flask-Bootstrap Flask-SQLAlchemy Flask-DebugToolbar -airbrake Flask-WTF Flask-OAuthlib Flask-Admin diff --git a/requirements.txt b/requirements.txt index 88dd801..5c0337c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,6 @@ # # pip-compile # -airbrake==2.1.2 alembic==1.0.8 # via flask-migrate appdirs==1.4.3 # via black attrs==19.1.0 # via black @@ -37,7 +36,7 @@ python-editor==1.0.4 # via alembic pyyaml==5.3 regex==2020.1.8 # via black requests-oauthlib==1.1.0 # via flask-oauthlib -requests==2.21.0 # via airbrake, requests-oauthlib +requests==2.21.0 # via requests-oauthlib six==1.12.0 # via python-dateutil sqlalchemy==1.3.2 # via alembic, flask-sqlalchemy tatsu==4.4.0 -- 2.43.4 From 42ac9031e671a24697f5e95af982325689d8b906 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 11:10:05 +0200 Subject: [PATCH 056/197] Avoid overwriting config, make DB script robuster --- first-setup.sh | 10 ++++++---- populate-db.sh | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/first-setup.sh b/first-setup.sh index 868db65..a2e7c52 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -30,10 +30,12 @@ else echo "Not installing airbrake" fi -echo -e "${B} Copying config template. All custom config options can be set in the config.py file ${E}" -cd app -cp config.example.py config.py -cd .. +if [ ! -f app/config.py ]; then + echo -e "${B} Copying config template. All custom config options can be set in the config.py file ${E}" + cp app/config.example.py app/config.py +else + echo -e "${B} Found existing config.py, not copying config teplate ${E}" +fi echo -e "${B} Seeding database ${E}" ./populate-db.sh diff --git a/populate-db.sh b/populate-db.sh index 800b53b..400ce2e 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -1,7 +1,7 @@ #!/bin/bash set -euo pipefail -cd app +cd "$(dirname "$0")/app" cp database/* . -python create_database.py setup_database -rm -f add_* create_database.py muhscheme +../venv/bin/python create_database.py setup_database +rm -f add_* create_database.py muhscheme.txt -- 2.43.4 From 588ffdadfb18b9ab4d434d150e369e2612f46677 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 11:32:39 +0200 Subject: [PATCH 057/197] Add production deployment docs --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 785f9a9..67ea409 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,16 @@ Run `pip-compile --upgrade` For more information about managing the dependencies see [jazzband/pip-tools: A set of tools to keep your pinned Python dependencies fresh.](https://github.com/jazzband/pip-tools) +## Production +To prepare the application in a production environment, follow the same steps as for *Local setup* up to and including `./populate-db.sh`. + +Set DEBUG to False in `app/config.py`. + +See [Flask's deployment documentation](https://flask.palletsprojects.com/en/1.1.x/deploying/#self-hosted-options). + +Set the server's Python interpreter to `/path/to/haldis/venv/bin/python`. Doing `source venv/bin/activate` is not necessary when that binary is used. + + ## Authors * **Feliciaan De Palmenaer** - *Initial work* - [Github](https://github.com/feliciaan) -- 2.43.4 From 4f7ffc0e3d20912e966161a2f3660cb2a9b79e5f Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 11:40:15 +0200 Subject: [PATCH 058/197] Reformat with black --- app/app.py | 17 ++++--- app/database/create_database.py | 2 +- app/fatmodels.py | 6 +-- app/forms.py | 16 ++++--- app/hlds/models.py | 42 +++++++++-------- app/hlds/parser.py | 31 +++++++------ app/migrations/env.py | 1 + app/models/order.py | 17 ++++--- app/models/orderitem.py | 12 ++--- app/models/orderitemchoice.py | 4 +- app/notification.py | 3 +- app/parse_hlds.py | 1 + app/passenger_wsgi.py | 1 + app/utils.py | 5 ++- app/views/general.py | 51 +++++++++++---------- app/views/order.py | 80 ++++++++++++++++++++++----------- app/zeus.py | 3 +- data/s5_generate.py | 43 +++++++++++------- 18 files changed, 204 insertions(+), 131 deletions(-) diff --git a/app/app.py b/app/app.py index 8ae89ee..40990cf 100755 --- a/app/app.py +++ b/app/app.py @@ -92,8 +92,7 @@ def register_plugins(app: Flask) -> Manager: # Make cookies more secure app.config.update( - SESSION_COOKIE_HTTPONLY=True, - SESSION_COOKIE_SAMESITE='Lax', + SESSION_COOKIE_HTTPONLY=True, SESSION_COOKIE_SAMESITE="Lax", ) if not app.debug: @@ -140,15 +139,16 @@ def add_template_filters(app: Flask) -> None: "Add functions which can be used in the templates" # pylint: disable=W0612 @app.template_filter("countdown") - def countdown(value, only_positive: bool = True, - show_text: bool = True, reload: bool = True) -> str: + def countdown( + value, only_positive: bool = True, show_text: bool = True, reload: bool = True + ) -> str: delta = int(value.timestamp() - datetime.now().timestamp()) if delta < 0 and only_positive: text = "closed" else: carry, seconds = divmod(delta, 60) carry, minutes = divmod(carry, 60) - days, hours = divmod(carry, 24) + days, hours = divmod(carry, 24) days_text = f"{days} days, " if days else "" @@ -157,8 +157,11 @@ def add_template_filters(app: Flask) -> None: reload_str = "yes" if reload else "no" - return Markup(f"" + - text + "") + return Markup( + f"" + + text + + "" + ) @app.template_filter("year") def current_year(_value: typing.Any) -> str: diff --git a/app/database/create_database.py b/app/database/create_database.py index 199c3aa..e614cad 100644 --- a/app/database/create_database.py +++ b/app/database/create_database.py @@ -71,7 +71,7 @@ def add_to_current() -> None: @app_manager.command -def setup_database(): #type: None +def setup_database(): # type: None "Start the database interaction script" print("Database modification script!") print("=============================\n\n") diff --git a/app/fatmodels.py b/app/fatmodels.py index 7757db1..d8c614f 100644 --- a/app/fatmodels.py +++ b/app/fatmodels.py @@ -36,9 +36,9 @@ class FatOrder(Order, FatModel): @classmethod def items_per_order(cls): return ( - Order.query.join(OrderItem).group_by(Order.id) - .with_entities(Order.id, - func.count(OrderItem.user_id).label("total")) + Order.query.join(OrderItem) + .group_by(Order.id) + .with_entities(Order.id, func.count(OrderItem.user_id).label("total")) ) diff --git a/app/forms.py b/app/forms.py index cf92c6b..92be9c5 100644 --- a/app/forms.py +++ b/app/forms.py @@ -6,8 +6,15 @@ from typing import Optional from flask import session, request from flask_login import current_user from flask_wtf import FlaskForm as Form -from wtforms import (DateTimeField, SelectField, SelectMultipleField, StringField, SubmitField, - FieldList, validators) +from wtforms import ( + DateTimeField, + SelectField, + SelectMultipleField, + StringField, + SubmitField, + FieldList, + validators, +) from utils import euro_string, price_range_string from hlds.definitions import location_definitions @@ -39,9 +46,7 @@ class OrderForm(Form): (0, None), (current_user.id, current_user.username), ] - self.location_id.choices = [ - (l.id, l.name) for l in location_definitions - ] + self.location_id.choices = [(l.id, l.name) for l in location_definitions] if self.stoptime.data is None: self.stoptime.data = datetime.now() + timedelta(hours=1) @@ -67,6 +72,7 @@ class AnonOrderItemForm(OrderItemForm): Class which defines the form for a new Item in an Order For Users who aren't logged in """ + user_name = StringField("Name", validators=[validators.required()]) def populate(self, location: Location) -> None: diff --git a/app/hlds/models.py b/app/hlds/models.py index 6d83abb..93d8fde 100644 --- a/app/hlds/models.py +++ b/app/hlds/models.py @@ -6,11 +6,9 @@ from utils import euro_string, first def _format_tags(tags: Iterable[str]) -> str: - return ( - " :: {}".format(" ".join(["{" + tag + "}" for tag in tags])) - if tags else - "" - ) + return " :: {}".format(" ".join(["{" + tag + "}" for tag in tags])) \ + if tags \ + else "" def _format_price(price: int) -> str: @@ -35,7 +33,7 @@ class Option: self, " -- {}".format(self.description) if self.description else "", _format_tags(self.tags), - _format_price(self.price) + _format_price(self.price), ) @@ -51,7 +49,7 @@ class Choice: return "{0.id}: {0.name}{1}\n\t\t{2}".format( self, " -- {}".format(self.description) if self.description else "", - "\n\t\t".join(map(str, self.options)) + "\n\t\t".join(map(str, self.options)), ) def option_by_id(self, option_id: str) -> Optional[Option]: @@ -75,12 +73,14 @@ class Dish: " -- {}".format(self.description) if self.description else "", _format_tags(self.tags), _format_price(self.price), - "\n\t".join(map(_format_type_and_choice, self.choices)) + "\n\t".join(map(_format_type_and_choice, self.choices)), ) def price_range(self) -> Tuple[int, int]: - return (self.price + self._sum_f_option_prices(min), - self.price + self._sum_f_option_prices(max)) + return ( + self.price + self._sum_f_option_prices(min), + self.price + self._sum_f_option_prices(max), + ) def _sum_f_option_prices(self, f): return sum( @@ -91,7 +91,9 @@ class Dish: class Location: - def __init__(self, id_, *, name, dishes, osm=None, address=None, telephone=None, website=None): + def __init__( + self, id_, *, name, dishes, osm=None, address=None, telephone=None, website=None + ): self.id: str = id_ self.name: str = name self.osm: Optional[str] = osm @@ -114,11 +116,15 @@ class Location: "{2}" ).format( self, - "".join("\n\t{} {}".format(k, v) for k, v in ( - ("osm", self.osm), - ("address", self.address), - ("telephone", self.telephone), - ("website", self.website), - ) if v is not None), - "\n".join(map(str, self.dishes)) + "".join( + "\n\t{} {}".format(k, v) + for k, v in ( + ("osm", self.osm), + ("address", self.address), + ("telephone", self.telephone), + ("website", self.website), + ) + if v is not None + ), + "\n".join(map(str, self.dishes)), ) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index 29d8aeb..55c9fb5 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -24,7 +24,9 @@ def filter_instance(cls, iterable): # pylint: disable=no-self-use class HldsSemanticActions: def location(self, ast) -> Location: - choices = {choice.id: choice for choice in filter_instance(Choice, ast["items_"])} + choices = { + choice.id: choice for choice in filter_instance(Choice, ast["items_"]) + } dishes: Iterable[Dish] = filter_instance(Dish, ast["items_"]) for dish in dishes: for i, choice in enumerate(dish.choices): @@ -32,7 +34,9 @@ class HldsSemanticActions: dish.choices[i] = (dish.choices[i][0], deepcopy(choices[choice[1]])) # Move the base price to the first single_choice if the dish has a fixed price - first_single_choice = first(c[1] for c in dish.choices if c[0] == "single_choice") + first_single_choice = first( + c[1] for c in dish.choices if c[0] == "single_choice" + ) price_range = dish.price_range() if dish.price and price_range[0] != price_range[1] and first_single_choice: for option in first_single_choice.options: @@ -41,7 +45,6 @@ class HldsSemanticActions: attributes = {att["key"]: att["value"] for att in ast["attributes"]} - return Location( ast["id"], name=ast["name"], @@ -64,7 +67,9 @@ class HldsSemanticActions: def choice_block(self, ast) -> Choice: if ast["price"] or ast["tags"]: - raise SemanticError("Choice blocks cannot have price or tags, put them on each of its options instead") + raise SemanticError( + "Choice blocks cannot have price or tags, put them on each of its options instead" + ) return Choice( ast["id"], @@ -76,8 +81,8 @@ class HldsSemanticActions: def indent_choice_block(self, ast) -> Tuple[str, Union[Choice, AST]]: return ( (ast["type"], self.choice_block(ast)) - if ast["kind"] == "declaration" else - (ast["type"], ast["id"]) + if ast["kind"] == "declaration" + else (ast["type"], ast["id"]) ) def indent_choice_entry(self, ast) -> Option: @@ -92,18 +97,18 @@ class HldsSemanticActions: noindent_choice_entry = indent_choice_entry def price(self, ast) -> int: - return ( - 100 * int(ast["value_unit"]) + - ( - 0 if not ast["value_cents"] else - 10 * int(ast["value_cents"]) if len(ast["value_cents"]) == 1 else - int(ast["value_cents"]) - ) + return 100 * int(ast["value_unit"]) + ( + 0 + if not ast["value_cents"] + else 10 * int(ast["value_cents"]) + if len(ast["value_cents"]) == 1 + else int(ast["value_cents"]) ) def _default(self, ast): return ast + SEMANTICS = HldsSemanticActions() diff --git a/app/migrations/env.py b/app/migrations/env.py index 3cd65b9..af87ade 100644 --- a/app/migrations/env.py +++ b/app/migrations/env.py @@ -4,6 +4,7 @@ from __future__ import with_statement from logging.config import fileConfig from alembic import context + # add your model's MetaData object here # for 'autogenerate' support # from myapp import mymodel diff --git a/app/models/order.py b/app/models/order.py index d4f3fcf..219650a 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -22,7 +22,9 @@ class Order(db.Model): def __getattr__(self, name): if name == "location": - return first(filter(lambda l: l.id == self.location_id, location_definitions)) + return first( + filter(lambda l: l.id == self.location_id, location_definitions) + ) raise AttributeError() def __repr__(self) -> str: @@ -37,7 +39,9 @@ class Order(db.Model): Update the location name from the HLDS definition. User should commit after running this to make the change persistent. """ - assert self.location_id, "location_id must be configured before updating from HLDS" + assert ( + self.location_id + ), "location_id must be configured before updating from HLDS" self.location_name = self.location.name def group_by_user(self) -> typing.Dict[str, typing.Any]: @@ -46,17 +50,16 @@ class Order(db.Model): for item in self.items: user = group.get(item.get_name(), dict()) user["total"] = user.get("total", 0) + item.price - user["to_pay"] = ( - user.get("to_pay", 0) + - item.price if not item.paid else 0 - ) + user["to_pay"] = user.get("to_pay", 0) + item.price if not item.paid else 0 user["paid"] = user.get("paid", True) and item.paid user["dishes"] = user.get("dishes", []) + [item.dish_name] group[str(item.get_name())] = user return group - def group_by_dish(self, sort_comments=False) -> typing.Dict[str, typing.Dict[str, typing.Any]]: + def group_by_dish( + self, sort_comments=False + ) -> typing.Dict[str, typing.Dict[str, typing.Any]]: "Group items of an Order by dish" group: typing.Dict[str, typing.Dict[str, typing.Any]] = dict() for item in self.items: diff --git a/app/models/orderitem.py b/app/models/orderitem.py index 02952a6..a078086 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -17,9 +17,7 @@ class OrderItem(db.Model): dish_id = db.Column(db.String(64), nullable=True) dish_name = db.Column(db.String(120), nullable=True) price = db.Column(db.Integer, nullable=True) - paid = db.Column( - db.Boolean, default=False, nullable=True - ) + paid = db.Column(db.Boolean, default=False, nullable=True) comment = db.Column(db.Text(), nullable=True) hlds_data_version = db.Column(db.String(40), nullable=True) @@ -27,8 +25,12 @@ class OrderItem(db.Model): def __getattr__(self, name): if name == "dish": - location_id = Order.query.filter(Order.id == self.order_id).first().location_id - location = first(filter(lambda l: l.id == location_id, location_definitions)) + location_id = ( + Order.query.filter(Order.id == self.order_id).first().location_id + ) + location = first( + filter(lambda l: l.id == location_id, location_definitions) + ) if location: return first(filter(lambda d: d.id == self.dish_id, location.dishes)) else: diff --git a/app/models/orderitemchoice.py b/app/models/orderitemchoice.py index e56afaa..d87c802 100644 --- a/app/models/orderitemchoice.py +++ b/app/models/orderitemchoice.py @@ -7,7 +7,9 @@ from .orderitem import OrderItem class OrderItemChoice(db.Model): id = db.Column(db.Integer, primary_key=True) choice_id = db.Column(db.String(64), nullable=True) - order_item_id = db.Column(db.Integer, db.ForeignKey("order_item.id"), nullable=False) + order_item_id = db.Column( + db.Integer, db.ForeignKey("order_item.id"), nullable=False + ) kind = db.Column(db.String(1), nullable=False) name = db.Column(db.String(120), nullable=True) value = db.Column(db.String(120), nullable=True) diff --git a/app/notification.py b/app/notification.py index 1218aa9..59d6c3d 100644 --- a/app/notification.py +++ b/app/notification.py @@ -35,8 +35,7 @@ def post_order_to_webhook(order: Order) -> None: "Function that sends the notification for the order" message = webhook_text(order) if message: - webhookthread = WebhookSenderThread( - message, app.config["SLACK_WEBHOOK"]) + webhookthread = WebhookSenderThread(message, app.config["SLACK_WEBHOOK"]) webhookthread.start() diff --git a/app/parse_hlds.py b/app/parse_hlds.py index 8fb08ee..ac58c44 100755 --- a/app/parse_hlds.py +++ b/app/parse_hlds.py @@ -24,6 +24,7 @@ def main(filenames): if __name__ == "__main__": import sys + args = sys.argv[1:] if "-h" in args or "--help" in args: print(USAGE.format(sys.argv[0]), file=sys.stderr) diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index ad4cdd2..e2a2ec5 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -10,6 +10,7 @@ if sys.executable != INTERP: sys.path.append(os.getcwd()) from app import create_app + application = create_app().app # For running on the server with passenger etc diff --git a/app/utils.py b/app/utils.py index cf2e02b..e2b7417 100644 --- a/app/utils.py +++ b/app/utils.py @@ -9,10 +9,13 @@ def euro_string(value: int) -> str: """ return "€ {}.{:02}".format(*divmod(value, 100)) + def price_range_string(price_range, include_upper=False): if price_range[0] == price_range[1]: return euro_string(price_range[0]) - return ("{}—{}" if include_upper else "from {}").format(*map(euro_string, price_range)) + return ("{}—{}" if include_upper else "from {}").format( + *map(euro_string, price_range) + ) def first(iterable: Iterable, default=None): diff --git a/app/views/general.py b/app/views/general.py index c04cc32..3b6ae40 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -16,6 +16,7 @@ from utils import first from hlds.definitions import location_definitions from hlds.models import Location from models import Order + # import views from views.order import get_orders @@ -43,7 +44,7 @@ def get_css_dict(css_path): # Open the YAML file with all the themes. path = os.path.join(app.root_path, "views/themes.yml") - with open(path, 'r') as stream: + with open(path, "r") as stream: data = yaml.safe_load(stream) # Build a dictionary from the YAML file with all the themes and their attributes. themes = {} @@ -57,46 +58,46 @@ def get_css_dict(css_path): # Check each theme in the dictionary and return the first one that is "correct" for key, theme in themes.items(): - if theme['type'] == 'static-date': - start_day, start_month = theme['start'].split('/') - start_date = datetime(year=current_year, day=int( - start_day), month=int(start_month)) + if theme["type"] == "static-date": + start_day, start_month = theme["start"].split("/") + start_date = datetime(year=current_year, day=int(start_day), month=int(start_month)) - end_day, end_month = theme['end'].split('/') + end_day, end_month = theme["end"].split("/") if int(start_month) > int(end_month): current_year += 1 - end_date = datetime( - year=current_year, day=int(end_day), month=int(end_month)) + end_date = datetime(year=current_year, day=int(end_day), month=int(end_month)) if start_date <= current_date <= end_date: - path = os.path.join(app.root_path, css_path, theme['file']) + path = os.path.join(app.root_path, css_path, theme["file"]) themes_dict[key] = path - themes_dict['darkmode'] = os.path.join( - app.root_path, "static/css/themes/lowPerformance/darkmode.css") - themes_dict['lightmode'] = os.path.join( - app.root_path, "static/css/themes/lowPerformance/lightmode.css") + themes_dict["darkmode"] = os.path.join( + app.root_path, "static/css/themes/lowPerformance/darkmode.css" + ) + themes_dict["lightmode"] = os.path.join( + app.root_path, "static/css/themes/lowPerformance/lightmode.css" + ) return themes_dict def css_list(): "Generate the list of names of all the currently available themes" - if request.cookies.get('performance', '') == 'highPerformance': - css_path = 'static/css/themes/highPerformance/' + if request.cookies.get("performance", "") == "highPerformance": + css_path = "static/css/themes/highPerformance/" else: - css_path = 'static/css/themes/lowPerformance/' + css_path = "static/css/themes/lowPerformance/" return list(get_css_dict(css_path).keys()) @general_bp.route("/css") def css(): "Generate the css" - if request.cookies.get('performance', '') == 'highPerformance': - css_path = 'static/css/themes/highPerformance/' + if request.cookies.get("performance", "") == "highPerformance": + css_path = "static/css/themes/highPerformance/" else: - css_path = 'static/css/themes/lowPerformance/' + css_path = "static/css/themes/lowPerformance/" - cookie_theme = request.cookies.get('theme', '') + cookie_theme = request.cookies.get("theme", "") themes_dict = get_css_dict(css_path) @@ -108,7 +109,7 @@ def css(): f = open(path) response = make_response(f.read()) - response.headers['Content-Type'] = 'text/css' + response.headers["Content-Type"] = "text/css" f.close() return response @@ -136,7 +137,9 @@ def location(location_id) -> str: @general_bp.route("/location//") def location_dish(location_id, dish_id) -> str: - loc: Optional[Location] = first(filter(lambda l: l.id == location_id, location_definitions)) + loc: Optional[Location] = first( + filter(lambda l: l.id == location_id, location_definitions) + ) if loc is None: abort(404) dish = loc.dish_by_id(dish_id) @@ -154,10 +157,10 @@ def location_dish(location_id, dish_id) -> str: "name": o.name, "description": o.description, "price": o.price, - "tags": o.tags + "tags": o.tags, } for o in c[1].options - ] + ], } for c in dish.choices ]) diff --git a/app/views/order.py b/app/views/order.py index c19a7c8..b4cbe5c 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -4,9 +4,19 @@ import typing from datetime import datetime from werkzeug.wrappers import Response + # from flask import current_app as app -from flask import (Blueprint, abort, flash, redirect, render_template, request, - session, url_for, wrappers) +from flask import ( + Blueprint, + abort, + flash, + redirect, + render_template, + request, + session, + url_for, + wrappers, +) from flask_login import current_user, login_required from forms import AnonOrderItemForm, OrderForm, OrderItemForm @@ -57,8 +67,7 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: flash("Please login to see this order.", "info") abort(401) if form is None: - form = AnonOrderItemForm() if current_user.is_anonymous() \ - else OrderItemForm() + form = AnonOrderItemForm() if current_user.is_anonymous() else OrderItemForm() if order.location: form.populate(order.location) if order.is_closed(): @@ -68,8 +77,14 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: dish = order.location.dish_by_id(dish_id) if order.location else None - return render_template("order.html", order=order, form=form, - total_price=total_price, debts=debts, dish=dish) + return render_template( + "order.html", + order=order, + form=form, + total_price=total_price, + debts=debts, + dish=dish, + ) @order_bp.route("//items") @@ -90,8 +105,7 @@ def items_showcase(order_id: int) -> str: def order_edit(order_id: int) -> typing.Union[str, Response]: "Generate order edit view from id" order = Order.query.filter(Order.id == order_id).first() - if current_user.id is not order.courier_id and \ - not current_user.is_admin(): + if current_user.id is not order.courier_id and not current_user.is_admin(): abort(401) if order is None: abort(404) @@ -102,8 +116,7 @@ def order_edit(order_id: int) -> typing.Union[str, Response]: order.update_from_hlds() db.session.commit() return redirect(url_for("order_bp.order_from_id", order_id=order.id)) - return render_template("order_edit.html", form=orderForm, - order_id=order_id) + return render_template("order_edit.html", form=orderForm, order_id=order_id) @order_bp.route("//create", methods=["GET", "POST"]) @@ -123,8 +136,7 @@ def order_item_create(order_id: int) -> typing.Any: # If location doesn't exist any more, adding items is nonsensical if not location: abort(404) - form = AnonOrderItemForm() if current_user.is_anonymous() \ - else OrderItemForm() + form = AnonOrderItemForm() if current_user.is_anonymous() else OrderItemForm() dish_id = form.dish_id.data if form.is_submitted() else request.args.get("dish") if dish_id and not location.dish_by_id(dish_id): @@ -142,8 +154,14 @@ def order_item_create(order_id: int) -> typing.Any: chosen = [ ( choice.option_by_id(request.form.get("choice_" + choice.id)) - if choice_type == "single_choice" else - list(ignore_none(request.form.getlist("choice_" + choice.id, type=choice.option_by_id))) + if choice_type == "single_choice" + else list( + ignore_none( + request.form.getlist( + "choice_" + choice.id, type=choice.option_by_id + ) + ) + ) ) for (choice_type, choice) in choices ] @@ -151,14 +169,22 @@ def order_item_create(order_id: int) -> typing.Any: if dish_was_changed or not all_choices_present: try: - user_name = form.user_name.data if form.user_name.validate(form) else None + user_name = ( + form.user_name.data if form.user_name.validate(form) else None + ) except AttributeError: user_name = None comment = form.comment.data if form.comment.validate(form) else None - return redirect(url_for("order_bp.order_item_create", - order_id=order_id, dish=form.dish_id.data, - user_name=user_name, comment=comment)) + return redirect( + url_for( + "order_bp.order_item_create", + order_id=order_id, + dish=form.dish_id.data, + user_name=user_name, + comment=comment, + ) + ) # If the form was not submitted (GET request) or the form had errors: show form again if not form.validate_on_submit(): @@ -184,6 +210,7 @@ def order_item_create(order_id: int) -> typing.Any: return option.name except AttributeError: return ", ".join(o.name for o in option if no_text_tag not in o.tags) + comments = list(ignore_none(_name(option) for option in chosen)) if item.comment: comments.append("Comment: " + item.comment) @@ -198,6 +225,7 @@ def order_item_create(order_id: int) -> typing.Any: return option.price or 0 except AttributeError: return sum(o.price or 0 for o in option) + item.price += sum(_price(option) for option in chosen) db.session.add(item) @@ -216,8 +244,7 @@ def item_paid(order_id: int, item_id: int) -> typing.Optional[Response]: if item.order.courier_id == user_id or current_user.admin: item.paid = True db.session.commit() - flash("Paid %s by %s" % (item.dish_name, item.get_name()), - "success") + flash("Paid %s by %s" % (item.dish_name, item.get_name()), "success") return redirect(url_for("order_bp.order_from_id", order_id=order_id)) abort(404) @@ -244,8 +271,7 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]: for item in items: item.paid = True db.session.commit() - flash("Paid %d items for %s" % - (len(items), item.get_name()), "success") + flash("Paid %d items for %s" % (len(items), item.get_name()), "success") return redirect(url_for("order_bp.order_from_id", order_id=order_id)) abort(404) @@ -293,7 +319,9 @@ def close_order(order_id: int) -> typing.Optional[Response]: order = Order.query.filter(Order.id == order_id).first() if order is None: abort(404) - if (current_user.id == order.courier_id or current_user.is_admin()) and not order.is_closed(): + if ( + current_user.id == order.courier_id or current_user.is_admin() + ) and not order.is_closed(): order.stoptime = datetime.now() if order.courier_id == 0 or order.courier_id is None: courier = select_user(order.items) @@ -332,7 +360,8 @@ def get_orders(expression=None) -> typing.List[Order]: order_list: typing.List[OrderForm] = [] if expression is None: expression = (datetime.now() > Order.starttime) & ( - Order.stoptime > datetime.now() + Order.stoptime + > datetime.now() # pylint: disable=C0121 ) | (Order.stoptime == None) if not current_user.is_anonymous(): @@ -340,5 +369,6 @@ def get_orders(expression=None) -> typing.List[Order]: else: order_list = Order.query.filter( # pylint: disable=C0121 - (expression & (Order.public == True))).all() + (expression & (Order.public == True)) + ).all() return order_list diff --git a/app/zeus.py b/app/zeus.py index 4b49d74..bbb58d2 100644 --- a/app/zeus.py +++ b/app/zeus.py @@ -1,8 +1,7 @@ "Script containing everything specific to ZeusWPI" import typing -from flask import (Blueprint, current_app, flash, redirect, request, session, - url_for) +from flask import Blueprint, current_app, flash, redirect, request, session, url_for from flask_login import login_user from flask_oauthlib.client import OAuth, OAuthException from werkzeug.wrappers import Response diff --git a/data/s5_generate.py b/data/s5_generate.py index 05dda68..60e3725 100755 --- a/data/s5_generate.py +++ b/data/s5_generate.py @@ -1,15 +1,19 @@ #!/usr/bin/env python3 -print("""============================ +print( + """============================ s5: S5 osm https://www.openstreetmap.org/node/3752879366 address Krijgslaan 281, 9000 Gent website https://www.ugent.be/student/nl/meer-dan-studeren/resto/restos/restocampussterre.htm -============================""") +============================""" +) # Paste menu from https://www.ugent.be/student/nl/meer-dan-studeren/resto/broodjes/overzicht.htm # here -MENU = [l.split("\t") for l in """ +MENU = [ + l.split("\t") + for l in """ Spring break Erwten-munt spread, komkommer, radijs, sla, croutons, cocktailsaus € 1,50 € 2,40 Groentespread Weekelijks wisselende groentespread € 1,60 € 2,60 Brie Brie, honing, pijnboompitten, sla € 1,50 € 2,50 @@ -30,40 +34,44 @@ Maison Ham, kaas, augurk, ei, sla, tomaat, cocktailsaus en mayonaise € 1,60 Tropical Ham, kaas, ananas, ei, sla, cocktailsaus € 1,60 € 2,40 Toscane Mozzarella, prosciutto ham, sla en tomatensalsa € 1,60 € 2,70 Argenteuil Ham, asperge, ei, komkommer, sla, tomaat en mayonaise € 1,50 € 2,40 -""".strip().split("\n")] +""".strip().split( + "\n" + ) +] # Sort by price. This fails if price is not always exactly "€ x,xx" but whatever MENU.sort(key=lambda dish: dish[2] + dish[3]) SANDWICHES = [ - [ # First price - ("small_white", "Klein wit "), - ("small_brown", "Klein bruin"), - ], - [ # Second price + [("small_white", "Klein wit "), ("small_brown", "Klein bruin"),], # First price + [ # Second price ("large_white", "Groot wit "), ("large_brown", "Groot bruin"), ("quattro", " Quattro "), - ] + ], ] + def name_to_id(name): - return "".join(filter( - lambda c: ord("a") <= ord(c) <= ord("z"), - name.lower().replace("é", "e") - )) + return "".join( + filter(lambda c: ord("a") <= ord(c) <= ord("z"), name.lower().replace("é", "e")) + ) + for dish in MENU: print() name, description = dish[0], dish[1] prices = [p.replace(",", ".") for p in dish[2:]] - print("dish sandwich_{}: Broodje {} -- {}".format(name_to_id(name), name, description)) + print( + "dish sandwich_{}: Broodje {} -- {}".format(name_to_id(name), name, description) + ) print("\tsingle_choice sandwich: Broodje") for sandwiches, price in zip(SANDWICHES, prices): for sw_id, sw_name in sandwiches: print("\t\t{}: {} {}".format(sw_id, sw_name, price)) -print(""" +print( + """ dish yoghurt: Natuuryoghurt € 0.4 dish yofu: Plantaardige yofu € 1 dish yoghurt_muesli: Yoghurt met muesli € 1 @@ -86,4 +94,5 @@ dish bionade: Bionade € 1.5 dish finley: Finley € 1 dish iced_coffee: IJskoffie € 2 dish iced_tea: IJsthee € 2 -dish smoothie: Smoothie € 2""") +dish smoothie: Smoothie € 2""" +) -- 2.43.4 From ff57afca9a551a64131e3c6b29c2a4810f898e52 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 17 Jul 2020 13:17:53 +0200 Subject: [PATCH 059/197] Fix themes --- .editorconfig | 4 + .gitignore | 1 + app/static/css/themes/Makefile | 23 + app/static/css/themes/christmas_heavy.css | 548 ++++++++++++++++++ app/static/css/themes/christmas_heavy.css.map | 9 + .../kerstmis.scss => christmas_heavy.scss} | 3 - .../css/themes/christmas_lightweight.css | 451 ++++++++++++++ .../css/themes/christmas_lightweight.css.map | 9 + ...rstmis.scss => christmas_lightweight.scss} | 3 - .../{highPerformance => }/dataPrivacy.css | 0 .../{highPerformance => }/halloween.css | 4 +- .../kerstmis.scssc | Bin 151099 -> 0 bytes .../style.scssc | Bin 123278 -> 0 bytes .../kerstmis.scssc | Bin 154957 -> 0 bytes .../css/themes/highPerformance/darkmode.css | 12 - .../css/themes/highPerformance/kerstmis.css | 534 ----------------- .../themes/highPerformance/kerstmis.css.map | 7 - .../kerstmis.scssc | Bin 151099 -> 0 bytes .../style.scssc | Bin 123278 -> 0 bytes .../kerstmis.scssc | Bin 116620 -> 0 bytes .../css/themes/lowPerformance/dataPrivacy.css | 4 - .../css/themes/lowPerformance/halloween.css | 16 - .../css/themes/lowPerformance/kerstmis.css | 442 -------------- .../themes/lowPerformance/kerstmis.css.map | 7 - .../css/themes/lowPerformance/lightmode.css | 12 - .../css/themes/lowPerformance/sinterklaas.css | 16 - .../darkmode.css => plain_darkmode.css} | 2 - .../lightmode.css => plain_lightmode.css} | 2 - .../{highPerformance => }/sinterklaas.css | 2 - app/static/js/customThemes.js | 11 - app/static/js/theme.js | 96 ++- app/templates/layout.html | 6 +- app/templates/profile.html | 9 +- app/views/general.py | 141 +++-- app/views/themes.yml | 58 +- 35 files changed, 1242 insertions(+), 1190 deletions(-) create mode 100644 app/static/css/themes/Makefile create mode 100644 app/static/css/themes/christmas_heavy.css create mode 100644 app/static/css/themes/christmas_heavy.css.map rename app/static/css/themes/{highPerformance/kerstmis.scss => christmas_heavy.scss} (99%) create mode 100644 app/static/css/themes/christmas_lightweight.css create mode 100644 app/static/css/themes/christmas_lightweight.css.map rename app/static/css/themes/{lowPerformance/kerstmis.scss => christmas_lightweight.scss} (99%) rename app/static/css/themes/{highPerformance => }/dataPrivacy.css (100%) rename app/static/css/themes/{highPerformance => }/halloween.css (88%) delete mode 100644 app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc delete mode 100644 app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc delete mode 100644 app/static/css/themes/highPerformance/.sass-cache/f007f33e9ca31bc5d2b8605323eaf3b5d0e7edd6/kerstmis.scssc delete mode 100644 app/static/css/themes/highPerformance/darkmode.css delete mode 100644 app/static/css/themes/highPerformance/kerstmis.css delete mode 100644 app/static/css/themes/highPerformance/kerstmis.css.map delete mode 100644 app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc delete mode 100644 app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc delete mode 100644 app/static/css/themes/lowPerformance/.sass-cache/f753b8fc673d85d43055d969da28457bcafb24b8/kerstmis.scssc delete mode 100644 app/static/css/themes/lowPerformance/dataPrivacy.css delete mode 100644 app/static/css/themes/lowPerformance/halloween.css delete mode 100644 app/static/css/themes/lowPerformance/kerstmis.css delete mode 100644 app/static/css/themes/lowPerformance/kerstmis.css.map delete mode 100644 app/static/css/themes/lowPerformance/lightmode.css delete mode 100644 app/static/css/themes/lowPerformance/sinterklaas.css rename app/static/css/themes/{lowPerformance/darkmode.css => plain_darkmode.css} (82%) rename app/static/css/themes/{highPerformance/lightmode.css => plain_lightmode.css} (82%) rename app/static/css/themes/{highPerformance => }/sinterklaas.css (87%) delete mode 100644 app/static/js/customThemes.js diff --git a/.editorconfig b/.editorconfig index 893c1a0..59db1ab 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,5 +12,9 @@ indent_style = tab indent_style = space indent_size = 4 +[*.{yml,yaml}] +indent_style = space +indent_size = 2 + [*.el] indent_style = space diff --git a/.gitignore b/.gitignore index c2b1e82..e3056d3 100644 --- a/.gitignore +++ b/.gitignore @@ -73,4 +73,5 @@ tmp/ .tern-port # Do not add scss cache +.sass-cache *.sass-cache diff --git a/app/static/css/themes/Makefile b/app/static/css/themes/Makefile new file mode 100644 index 0000000..93dd726 --- /dev/null +++ b/app/static/css/themes/Makefile @@ -0,0 +1,23 @@ +# Find a SASS preprocessor +SASS := $(shell command -v sass 2>/dev/null) +ifndef SASS +SASS := $(shell command -v sassc 2>/dev/null) +endif +ifndef SASS +$(error No SASS preprocessor found) +endif + +SASSFLAGS := --sourcemap=auto -- + +.PHONY: all clean + +# Detect SCSS files, use their CSS counterparts as `all` target +SCSS_FILES := $(wildcard *.scss) +all: $(SCSS_FILES:%.scss=%.css) + +# Teach Make how to convert SCSS to CSS +%.css: %.scss + $(SASS) $(SASSFLAGS) $< $@ + +clean: + rm -rf $(SCSS_FILES:%.scss=%.css) $(SCSS_FILES:%.scss=%.css.map) diff --git a/app/static/css/themes/christmas_heavy.css b/app/static/css/themes/christmas_heavy.css new file mode 100644 index 0000000..fec71d9 --- /dev/null +++ b/app/static/css/themes/christmas_heavy.css @@ -0,0 +1,548 @@ +@charset "UTF-8"; +/* +¡¡¡ OPGELET !!! +Deze css bevat lelijke code. +Dit komt doordat bootstrap lelijk en oud is. +Ik zal later proberen de css te verbeteren en bootstrap weg te gooien. +Enige discretie is aangeraden. + +---=§[ Arnhoudt ]§=--- + +*/ +:root { + --dGray0:#F28705; + --dGray1:white; + --dGray2:#590212; + --dGray3:#590212; + --dGray4:#274001; + --dGray5:#274001; + --dGray6:#F2778D; + --dBlue:#F2778D; } + +body { + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_regular.ttf"); + font-weight: normal; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_light.ttf"); + font-weight: 200; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_medium.ttf"); + font-weight: medium; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_bold.ttf"); + font-weight: bold; } + +.btn { + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg, #F53030, #F58B9E); } + +.btn:hover { + background-image: linear-gradient(-40deg, #A81111, #FF4B33); } + +.navbar { + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + text-transform: capitalize; } + +.nav > li > a { + padding-left: 1vw; + padding-right: 1vw; } + +.main { + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; } + +.navbar .container { + width: 100%; + padding: 0 4vw; } + +@media (min-width: 768px) { + .container { + width: 100%; } } + +@media (min-width: 992px) { + .main .container, .main .orders { + width: 970px; } } + +@media (min-width: 1200px) { + .main .container, .main .orders { + width: 1170px; } } + +.main { + padding-top: 2.5rem; } + +.order_data { + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; } + +.order_row { + background: transparent; } + +.order_data h5 { + max-width: 60%; + padding-bottom: 3rem; } + +.expand_button { + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; } + +.hi_im_haldis h2 { + display: none; } + +.hi_im_haldis h3 { + width: 100%; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + text-align: center; } + +.hi_im_haldis { + background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); + border-radius: 0; + width: 100%; } + +.hi_im_haldis_wrapper { + width: 100%; } + +.darker:nth-child(even) { + background-color: #B62937; + border-radius: 2rem; } + +.darker:nth-child(odd) { + background-color: #821C25; + border-radius: 2rem; } + +.darker { + padding: 1rem; } + +.order_row:nth-child(even) .order_data { + background-color: #B62937; + border-radius: 2rem; } + +.order_row:nth-child(odd) .order_data { + background-color: #821C25; + border-radius: 2rem; } + +.order_row h5 { + font-weight: bold; } + +.order_row { + margin-bottom: 3rem; } + +h3 { + padding-bottom: 1rem; } + +.home_sir { + font-weight: bold; + color: #F45D68; } + +.expand_button_wrapper { + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; } + +.time_data { + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; } + +.navbar .navbar-nav .active a { + color: #ff9bae; + border-bottom: 1px solid #ff9bae; + padding-bottom: 1rem; } + +.navbar-nav { + padding-left: 2rem; } + +.jumbotron, .darker { + display: flex; + flex-direction: column; + border-radius: 4rem; } + +.row > div > h5 { + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; } + +.row > div > .amount_of_orders { + font-weight: lighter; + font-size: 1.6rem; } + +.row > div .time { + font-weight: lighter; } + +.jumbotron { + background-color: transparent; } + +.navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { + background-color: transparent; } + +.background { + -webkit-filter: blur(0px) brightness(80%); + -moz-filter: blur(0px) brightness(80%); + -o-filter: blur(0px) brightness(80%); + -ms-filter: blur(0px) brightness(80%); + filter: blur(0px) brightness(80%); + position: fixed; + top: 0; + left: 0; } + +footer a { + color: #69E8FF; } + +footer { + position: fixed; + bottom: 0; + width: 100%; + background: #CB3444; + height: 5rem; + display: flex; + align-items: center; } + +footer > hr { + display: none; } + +#mapid { + width: 100%; } + +.order_overview, .order_order, .order_items, .order_ordered, .order_depts { + padding: 1rem 5rem 3rem 5rem; } + +.order_overview { + width: 100%; } + +.order_depts { + width: 100%; + margin-bottom: 10rem; } + +.location_data, .location_products { + width: 100%; } + +.location_products { + margin-bottom: 10rem; } + +.locations_locations { + padding: 1rem 5rem 3rem 5rem; } + +.background_wrapper { + position: absolute; + left: 0; + bottom: 5rem; + width: 100%; + height: 100%; + overflow: hidden; } + +.christmas_background { + z-index: -101; + width: 300%; + height: 300%; + background: linear-gradient(-45deg, #2F0000, #C20A12); + animation: gradientBG 19s ease infinite; } + +.sled { + width: 15rem; + height: 15rem; + transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + background-image: url("static/images/themes/kerstmis/sled.svg"); } + +.sled_wrapper { + top: 0.5rem; + left: -7.5rem; + position: absolute; + transform: translate(-50vw, 40vh) rotate(0deg); + width: 15rem; + height: 15rem; + animation: sled 29s ease-in-out infinite; } + +.train_button:checked ~ .sled_wrapper:hover { + animation-play-state: paused; } + +.train_button:checked ~ .sled_wrapper:hover .sled { + transform: translateY(100vh) rotate(90deg); } + +.snowman_wrapper { + height: 17rem; + width: 10rem; + position: absolute; + bottom: 15rem; + left: -12rem; + animation: snowman 37s ease infinite; + transform-origin: right bottom; } + +.snowman_head { + position: absolute; + top: 0; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_head.svg"); + animation: snowman_head 2s ease infinite; } + +.snowman_body { + position: absolute; + top: 9.5rem; + left: 0.5rem; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } + +.train_button:checked ~ .merry_christmas { + position: absolute; + top: 0; + width: 100%; + height: 100%; + background-position: center; + background-image: url("static/images/themes/kerstmis/merry_christmas.svg"); + background-size: 25vw; + background-repeat: no-repeat; + animation: merry_christmas 5s ease infinite; } + +.train_button { + position: absolute; + transform: scaleX(20) scaleY(8) translateX(-100rem); + bottom: 5.5rem; + left: 7rem; + animation: follow_train 47s linear infinite; + opacity: 0; } + +.train_wrapper { + position: absolute; + bottom: 0.5rem; + transform: translateX(-80vw); + animation: train 47s linear infinite; } + +.wheel_big, .wheel_small { + position: absolute; + bottom: -0.4rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/wheel.svg"); } + +.train { + position: absolute; + bottom: 0.5rem; + left: 30rem; + width: 30rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/train.svg"); + animation: whobble 1s linear alternate-reverse infinite; } + +.wheel_big { + width: 3.2rem; + height: 3.2rem; } + +.wheel_small { + width: 2.5rem; + height: 2.5rem; } + +.train .wheel1 { + animation: turn 2s linear infinite; + left: 3.5rem; } + +.train .wheel2 { + animation: turn 2s linear infinite, -0.1s; + left: 7rem; } + +.train .wheel3 { + animation: turn 2s linear infinite -0.3s; + left: 10.5rem; } + +.train .wheel4 { + animation: turn 1.5s linear infinite -0.5s; + left: 13.9rem; } + +.train .wheel5 { + animation: turn 1.5s linear infinite -0.7s; + left: 16.6rem; } + +.zeus_wagon, .mc_wagon { + position: absolute; + bottom: 1.25rem; + width: 30rem; + height: 7.5rem; + background-repeat: no-repeat; + background-size: contain; + animation: whobble 1s linear alternate-reverse infinite; } + +.mc_wagon { + background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); + left: 0rem; } + +.zeus_wagon { + background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); + left: 15rem; } + +.zeus_wagon .wheel1, .mc_wagon .wheel1 { + animation: turn 2s linear infinite; + bottom: -1.1rem; + left: 2.2rem; } + +.zeus_wagon .wheel2, .mc_wagon .wheel2 { + animation: turn 2s linear infinite, -0.1s; + bottom: -1.1rem; + left: 5.75rem; } + +.zeus_wagon .wheel3, .mc_wagon .wheel3 { + animation: turn 2s linear infinite -0.3s; + bottom: -1.1rem; + left: 9.3rem; } + +.snow { + border-radius: 50%; + opacity: 0.8; + position: absolute; + top: -100vh; + animation-name: fall; + animation-timing-function: linear; + animation-iteration-count: infinite; } + +.layer1 { + width: 1rem; + height: 1rem; + filter: blur(1.5px); + box-shadow: 95.5vw 70.4vh 0 -0.48rem#fff,87.9vw 28.3vh 0 -0.3rem#fff,48.4vw 63.8vh 0 -0.16rem#fff,55.2vw 23.5vh 0 -0.28rem#fff,43.2vw 62.6vh 0 -0.32rem#fff,5vw 16.6vh 0 -0.42rem#fff,34.4vw 88.5vh 0 -0.08rem#fff,63.3vw 27.4vh 0 -0.26rem#fff,58.1vw 21.3vh 0 -0.21rem#fff,58.2vw 56.7vh 0 -0.29rem#fff,81.1vw 47.1vh 0 -0.27rem#fff,89.6vw 19.1vh 0 -0.23rem#fff,76vw 67.1vh 0 -0.16rem#fff,50.8vw 26.8vh 0 -0.43rem#fff,59.1vw 73.6vh 0 -0.11rem#fff,48.2vw 55.3vh 0 -0.09rem#fff,28.1vw 65.2vh 0 -0.13rem#fff,48.3vw 77.8vh 0 -0.31rem#fff,21vw 86.9vh 0 -0.03rem#fff,8.5vw 46.7vh 0 -0.37rem#fff,65.2vw 10.1vh 0 -0.04rem#fff,16.3vw 76.3vh 0 -0.33rem#fff,36.8vw 80.3vh 0 -0.05rem#fff,64.1vw 25.3vh 0 -0.15rem#fff,69vw 4.4vh 0 -0.37rem#fff,20.6vw 59.8vh 0 -0.05rem#fff,92.5vw 58.8vh 0 -0.3rem#fff,89.3vw 76.2vh 0 -0.24rem#fff,16.4vw 77.7vh 0 -0.32rem#fff,93.4vw 49.7vh 0 -0.25rem#fff,75.7vw 50.5vh 0 -0.36rem#fff,53.8vw 45.1vh 0 -0.2rem#fff,25.2vw 42.9vh 0 -0.41rem#fff,21.7vw 63.5vh 0 -0.36rem#fff,76.8vw 29vh 0 -0.11rem#fff,27.4vw 56.2vh 0 -0.25rem#fff,10.7vw 87.3vh 0 -0.37rem#fff,71.9vw 5.2vh 0 -0.09rem#fff,64.9vw 31.5vh 0 -0.13rem#fff,24vw 21.4vh 0 -0.33rem#fff,54.9vw 18vh 0 -0.48rem#fff,4.4vw 37.8vh 0 -0.23rem#fff,58.3vw 93.1vh 0 -0.41rem#fff,56.1vw 58.2vh 0 -0.42rem#fff,17.1vw 17.4vh 0 -0.3rem#fff,69.6vw 50.9vh 0 -0.04rem#fff,81.1vw 8.8vh 0 -0.12rem#fff,69.9vw 6.2vh 0 -0.31rem#fff,86vw 17.9vh 0 -0.16rem#fff,27.7vw 14.1vh 0 -0.37rem#fff,46.9vw 10.9vh 0 -0.07rem#fff,58.3vw 93.4vh 0 -0.14rem#fff,98.9vw 1.1vh 0 -0.17rem#fff,82.5vw 36.2vh 0 -0.41rem#fff,28vw 0.5vh 0 -0.06rem#fff,0.4vw 21.8vh 0 -0.5rem#fff,70.4vw 47.8vh 0 -0.31rem#fff,16vw 42.2vh 0 -0.11rem#fff,42.1vw 14.1vh 0 -0.23rem#fff,49.3vw 67.7vh 0 -0.43rem#fff,46.2vw 69vh 0 -0.13rem#fff,23.2vw 88vh 0 -0.45rem#fff,93.2vw 88.3vh 0 -0.5rem#fff,17.3vw 22vh 0 -0.14rem#fff,57.6vw 6.5vh 0 -0.44rem#fff,26.5vw 88.2vh 0 -0.14rem#fff,85.4vw 14.8vh 0 -0.32rem#fff,33.1vw 44.2vh 0 -0.15rem#fff,1.3vw 6.4vh 0 -0.12rem#fff,1.8vw 58.5vh 0 -0.21rem#fff,85.5vw 74.1vh 0 -0.43rem#fff,82.9vw 4.4vh 0 -0.35rem#fff,94.6vw 55.2vh 0 -0.1rem#fff,7.1vw 5.1vh 0 -0.29rem#fff,47.1vw 95.8vh 0 -0.13rem#fff,69.3vw 35.3vh 0 -0.1rem#fff,8.3vw 83vh 0 -0.02rem#fff,90.8vw 47vh 0 -0.21rem#fff,85.2vw 35.3vh 0 -0.06rem#fff,80.1vw 13.6vh 0 -0.07rem#fff,52vw 37vh 0 -0.11rem#fff,75.7vw 26.3vh 0 -0.16rem#fff,51.3vw 7.7vh 0 -0.46rem#fff,35.2vw 18.6vh 0 -0.09rem#fff,69.4vw 21.3vh 0 -0.05rem#fff,16.1vw 66.8vh 0 -0.14rem#fff,80.3vw 4vh 0 -0.25rem#fff,31.1vw 78.7vh 0 -0.08rem#fff,26.9vw 45.3vh 0 -0.01rem#fff,38.3vw 11.4vh 0 -0.47rem#fff,46.7vw 10.2vh 0 -0.44rem#fff,15.5vw 2.9vh 0 -0.35rem#fff,97.8vw 19.8vh 0 -0.24rem#fff,60.8vw 94.7vh 0 -0.12rem#fff,46.1vw 66vh 0 -0.45rem#fff,59.6vw 65vh 0 -0.33rem#fff,30.5vw 44.4vh 0 -0.18rem#fff,78.2vw 55.6vh 0 -0.07rem#fff,69.5vw 61.9vh 0 -0.11rem#fff,53.4vw 38.3vh 0 -0.11rem#fff; + animation-duration: 18s; } + +.layer1.a { + animation-delay: -9s; } + +.layer2 { + width: 0.8rem; + height: 0.8rem; + filter: blur(3px); + box-shadow: 89.1vw 69.4vh 0 -0.15rem#fff,19.2vw 77.1vh 0 -0.35rem#fff,52.3vw 3.8vh 0 -0.04rem#fff,69.5vw 14.1vh 0 -0.25rem#fff,75.5vw 74.6vh 0 -0.44rem#fff,13.6vw 48vh 0 -0.36rem#fff,62.5vw 17.4vh 0 -0.2rem#fff,53.5vw 44.1vh 0 -0.41rem#fff,58.2vw 63vh 0 -0.28rem#fff,64.3vw 54.3vh 0 -0.42rem#fff,38.3vw 92.4vh 0 -0.36rem#fff,89.4vw 6.5vh 0 -0.06rem#fff,92.9vw 11.4vh 0 -0.06rem#fff,8.4vw 33.7vh 0 -0.25rem#fff,84.1vw 44.5vh 0 -0.02rem#fff,58.2vw 87.2vh 0 -0.43rem#fff,64.8vw 34.8vh 0 -0.33rem#fff,46.1vw 31.1vh 0 -0.4rem#fff,11.3vw 61.1vh 0 -0.33rem#fff,50.9vw 4.5vh 0 -0.3rem#fff,43.6vw 97.2vh 0 -0.43rem#fff,24.7vw 62.9vh 0 -0.12rem#fff,5.2vw 40.3vh 0 -0.45rem#fff,48.2vw 21.6vh 0 -0.45rem#fff,28.4vw 48.3vh 0 -0.18rem#fff,35vw 16.7vh 0 -0.09rem#fff,29.5vw 65.1vh 0 -0.11rem#fff,65.7vw 59.2vh 0 -0.15rem#fff,28vw 80.1vh 0 -0.4rem#fff,20.4vw 33.1vh 0 -0.1rem#fff,11.1vw 70.2vh 0 -0.4rem#fff,37.4vw 92.5vh 0 -0.49rem#fff,38.5vw 90.5vh 0 -0.12rem#fff,97.3vw 34.4vh 0 -0.07rem#fff,14.7vw 10.4vh 0 -0.23rem#fff,98.2vw 54.5vh 0 -0.3rem#fff,23.4vw 44vh 0 -0.17rem#fff,4.8vw 21.2vh 0 -0.26rem#fff,27vw 63.3vh 0 -0.27rem#fff,93.4vw 67.2vh 0 -0.16rem#fff,86.2vw 82vh 0 -0.02rem#fff,61.4vw 50vh 0 -0.41rem#fff,43.9vw 68.4vh 0 -0.49rem#fff,46.6vw 6.3vh 0 -0.18rem#fff,69.8vw 94.2vh 0 -0.03rem#fff,17.1vw 31.7vh 0 -0.39rem#fff,88vw 76.3vh 0 -0.13rem#fff,90.8vw 27.8vh 0 -0.5rem#fff,16.5vw 86vh 0 -0.24rem#fff,48.4vw 50vh 0 -0.12rem#fff,0.2vw 9.7vh 0 -0.29rem#fff,70.6vw 13.2vh 0 -0.34rem#fff,75.4vw 46.7vh 0 -0.02rem#fff,41.9vw 63.2vh 0 -0.09rem#fff,81.2vw 32.4vh 0 -0.44rem#fff,62.1vw 38.9vh 0 -0.29rem#fff,83.8vw 8.6vh 0 -0.46rem#fff,60.4vw 96.9vh 0 -0.37rem#fff,80.7vw 83.8vh 0 -0.14rem#fff,91.1vw 35.7vh 0 -0.45rem#fff,19.8vw 9.6vh 0 -0.11rem#fff,56.3vw 28.3vh 0 -0.11rem#fff,49.7vw 27.6vh 0 -0.21rem#fff,92.2vw 61.1vh 0 -0.37rem#fff,10.7vw 18.8vh 0 -0.04rem#fff,44.4vw 77.2vh 0 -0.41rem#fff,42.3vw 53.9vh 0 -0.32rem#fff,16vw 19.5vh 0 -0.02rem#fff,40.8vw 60.8vh 0 -0.23rem#fff,6.5vw 77.1vh 0 -0.41rem#fff,78.2vw 98.6vh 0 -0.5rem#fff,70.3vw 88vh 0 -0.34rem#fff,21.4vw 45.7vh 0 -0.2rem#fff,79.3vw 27.8vh 0 -0.16rem#fff,20.5vw 91.9vh 0 -0.1rem#fff,44vw 20.7vh 0 -0.05rem#fff,20.2vw 58.5vh 0 -0.18rem#fff,0.4vw 57.7vh 0 -0.44rem#fff,29.8vw 96.4vh 0 -0.41rem#fff,66vw 94.4vh 0 -0.01rem#fff,25.4vw 74.6vh 0 -0.37rem#fff,89.7vw 38.4vh 0 -0.04rem#fff,32vw 64vh 0 -0.4rem#fff,79.9vw 73.7vh 0 -0.45rem#fff,92.8vw 72.3vh 0 -0.46rem#fff,50.5vw 54.5vh 0 -0.47rem#fff,77.8vw 38.2vh 0 -0.29rem#fff,73.9vw 61.4vh 0 -0.17rem#fff,88.1vw 91.1vh 0 -0.37rem#fff,20.4vw 32.5vh 0 -0.39rem#fff,68.5vw 97.8vh 0 -0.42rem#fff,62.7vw 53.2vh 0 -0.11rem#fff,65.4vw 70.8vh 0 -0.14rem#fff,31.3vw 5.3vh 0 -0.12rem#fff,39.2vw 78vh 0 -0.48rem#fff,50vw 44.2vh 0 -0.01rem#fff,16.9vw 20.6vh 0 -0.05rem#fff,61.3vw 5.1vh 0 -0.48rem#fff,18.6vw 65.8vh 0 -0.35rem#fff,88.4vw 67.2vh 0 -0.5rem#fff; + animation-duration: 24s; } + +.layer2.a { + animation-delay: -12s; } + +.layer3 { + width: 0.6rem; + height: 0.6rem; + filter: blur(6px); + box-shadow: 12.2vw 53.5vh 0 -0.46rem#fff,38.8vw 53vh 0 -0.18rem#fff,48vw 42vh 0 -0.4rem#fff,89.7vw 31vh 0 -0.36rem#fff,67vw 60.1vh 0 -0.3rem#fff,69vw 14.5vh 0 -0.49rem#fff,6.7vw 91.1vh 0 -0.18rem#fff,13.2vw 34.7vh 0 -0.48rem#fff,70.4vw 67.8vh 0 -0.36rem#fff,85.1vw 82.5vh 0 -0.05rem#fff,16.8vw 7.6vh 0 -0.19rem#fff,6.2vw 34.2vh 0 -0.16rem#fff,8.9vw 68.8vh 0 -0.32rem#fff,58.5vw 28.3vh 0 -0.3rem#fff,41.7vw 74.1vh 0 -0.34rem#fff,10.3vw 79.8vh 0 -0.26rem#fff,8.3vw 24.6vh 0 -0.05rem#fff,33.1vw 85.4vh 0 -0.41rem#fff,20.3vw 16.9vh 0 -0.02rem#fff,21.1vw 50.7vh 0 -0.36rem#fff,14.9vw 17vh 0 -0.05rem#fff,45.8vw 17vh 0 -0.21rem#fff,25.6vw 0.8vh 0 -0.31rem#fff,35.4vw 53.4vh 0 -0.22rem#fff,19.2vw 79.1vh 0 -0.35rem#fff,74.5vw 60.8vh 0 -0.25rem#fff,88.9vw 89.9vh 0 -0.48rem#fff,48.7vw 7.2vh 0 -0.13rem#fff,88.1vw 84.1vh 0 -0.12rem#fff,63.2vw 82.3vh 0 -0.06rem#fff,99.9vw 46.2vh 0 -0.47rem#fff,92vw 59.8vh 0 -0.12rem#fff,1.6vw 8.8vh 0 -0.23rem#fff,79.8vw 2vh 0 -0.5rem#fff,58.2vw 22.4vh 0 -0.34rem#fff,47.6vw 7.3vh 0 -0.06rem#fff,28.1vw 71vh 0 -0.18rem#fff,14.2vw 77.1vh 0 -0.43rem#fff,95.5vw 68.6vh 0 -0.43rem#fff,6.7vw 8.1vh 0 -0.1rem#fff,60.2vw 36.7vh 0 -0.31rem#fff,25.8vw 27vh 0 -0.42rem#fff,1vw 60vh 0 -0.42rem#fff,64.2vw 19.1vh 0 -0.23rem#fff,80.9vw 88.8vh 0 -0.03rem#fff,3.6vw 60.1vh 0 -0.08rem#fff,30.1vw 10.9vh 0 -0.44rem#fff,38.5vw 26.3vh 0 -0.45rem#fff,44.3vw 38.8vh 0 -0.1rem#fff,16.2vw 45.5vh 0 -0.14rem#fff,90.6vw 6.6vh 0 -0.23rem#fff,15.8vw 52.6vh 0 -0.45rem#fff,30.2vw 2.7vh 0 -0.4rem#fff,3.8vw 40.1vh 0 -0.48rem#fff,10.7vw 82.2vh 0 -0.4rem#fff,90.5vw 73.3vh 0 -0.16rem#fff,72.9vw 48.3vh 0 -0.14rem#fff,17.7vw 25.7vh 0 -0.07rem#fff,84.6vw 82.3vh 0 -0.3rem#fff,69.9vw 71.5vh 0 -0.05rem#fff,34.6vw 45.9vh 0 -0.1rem#fff,81.3vw 12.5vh 0 -0.1rem#fff,58.3vw 11.4vh 0 -0.48rem#fff,17.7vw 7vh 0 -0.18rem#fff,67.5vw 27.8vh 0 -0.4rem#fff,92.1vw 63.6vh 0 -0.42rem#fff,92vw 97.7vh 0 -0.3rem#fff,7.3vw 28.6vh 0 -0.22rem#fff,93.4vw 39.8vh 0 -0.04rem#fff,27.4vw 56.7vh 0 -0.08rem#fff,2.5vw 39.9vh 0 -0.47rem#fff,61.1vw 38.3vh 0 -0.29rem#fff,42.4vw 41.2vh 0 -0.14rem#fff,85.8vw 26vh 0 -0.44rem#fff,95.9vw 70vh 0 -0.19rem#fff,77.4vw 52.9vh 0 -0.15rem#fff,54.9vw 1.2vh 0 -0.4rem#fff,47.1vw 44.2vh 0 -0.2rem#fff,60vw 66.7vh 0 -0.41rem#fff,88.2vw 72vh 0 -0.05rem#fff,77.2vw 74.3vh 0 -0.31rem#fff,77.7vw 63.2vh 0 -0.1rem#fff,15.9vw 61.7vh 0 -0.19rem#fff,13.9vw 23.5vh 0 -0.4rem#fff,81.2vw 18.9vh 0 -0.17rem#fff,20.1vw 44.6vh 0 -0.47rem#fff,59vw 4vh 0 -0.44rem#fff,6vw 40vh 0 -0.34rem#fff,12.2vw 77vh 0 -0.26rem#fff,9.5vw 20.3vh 0 -0.01rem#fff,52.6vw 58.7vh 0 -0.17rem#fff,89.5vw 32.6vh 0 -0.03rem#fff,0.2vw 83.9vh 0 -0.3rem#fff,42.3vw 73.3vh 0 -0.03rem#fff,0.5vw 15.7vh 0 -0.17rem#fff,58.1vw 98.2vh 0 -0.01rem#fff,95.7vw 4.3vh 0 -0.01rem#fff,82.7vw 57.7vh 0 -0.18rem#fff,99.6vw 2.6vh 0 -0.12rem#fff,44.5vw 68.3vh 0 -0.02rem#fff; + animation-duration: 30s; } + +.layer3.a { + animation-delay: -15s; } + +@keyframes fall { + 100% { + transform: translateY(200vh); } } + +@keyframes gradientBG { + 0% { + transform: translate(-10%, -10%); } + 50% { + transform: translate(-60%, -60%); } + 100% { + transform: translate(-10%, -10%); } } + +@keyframes sled { + 0% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 4% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 20% { + transform: translate(50vw, 10vh) rotate(20deg); } + 36% { + transform: translate(150vw, 40vh) rotate(40deg); } + 100% { + transform: translate(150vw, 40vh) rotate(40deg); } } + +@keyframes train { + 0% { + transform: translateX(-80rem); } + 55% { + transform: translateX(-80rem); } + 85% { + transform: translateX(100vw); } + 100% { + transform: translateX(100vw); } } + +@keyframes follow_train { + 0% { + transform: translateX(-80rem) scaleX(20) scaleY(8); } + 55% { + transform: translateX(-80rem) scaleX(20) scaleY(8); } + 85% { + transform: translateX(100vw) scaleX(20) scaleY(8); } + 100% { + transform: translateX(100vw) scaleX(20) scaleY(8); } } + +@keyframes turn { + 100% { + transform: rotate(360deg); } } + +@keyframes whobble { + 100% { + transform: translateY(0.5vh); } } + +@keyframes snowman { + 0% { + transform: rotate(0); } + 20% { + transform: rotate(0); } + 30% { + transform: rotate(80deg); } + 54% { + transform: rotate(80deg); } + 68% { + transform: rotate(0); } + 100% { + transform: rotate(0); } } + +@keyframes snowman_head { + 0% { + transform: rotate(-3deg); } + 50% { + transform: rotate(3deg); } + 100% { + transform: rotate(-3deg); } } + +@keyframes merry_christmas { + 0% { + opacity: 0.8; } + 50% { + opacity: 0.6; } + 100% { + opacity: 0.8; } } + +/*# sourceMappingURL=christmas_heavy.css.map */ \ No newline at end of file diff --git a/app/static/css/themes/christmas_heavy.css.map b/app/static/css/themes/christmas_heavy.css.map new file mode 100644 index 0000000..6b24b60 --- /dev/null +++ b/app/static/css/themes/christmas_heavy.css.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "file": "christmas_heavy.css", + "sources": [ + "christmas_heavy.scss" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/app/static/css/themes/highPerformance/kerstmis.scss b/app/static/css/themes/christmas_heavy.scss similarity index 99% rename from app/static/css/themes/highPerformance/kerstmis.scss rename to app/static/css/themes/christmas_heavy.scss index d6d390c..f21dcf7 100644 --- a/app/static/css/themes/highPerformance/kerstmis.scss +++ b/app/static/css/themes/christmas_heavy.scss @@ -9,10 +9,7 @@ Enige discretie is aangeraden. */ - -/*high performance kerstmis*/ :root { - /*Darkmode colors*/ --dGray0:#F28705; --dGray1:white; --dGray2:#590212; diff --git a/app/static/css/themes/christmas_lightweight.css b/app/static/css/themes/christmas_lightweight.css new file mode 100644 index 0000000..e96e389 --- /dev/null +++ b/app/static/css/themes/christmas_lightweight.css @@ -0,0 +1,451 @@ +@charset "UTF-8"; +/* +¡¡¡ OPGELET !!! +Deze css bevat lelijke code. +Dit komt doordat bootstrap lelijk en oud is. +Ik zal later proberen de css te verbeteren en bootstrap weg te gooien. +Enige discretie is aangeraden. + +---=§[ Arnhoudt ]§=--- + +*/ +:root { + --dGray0:#F28705; + --dGray1:white; + --dGray2:#590212; + --dGray3:#590212; + --dGray4:#274001; + --dGray5:#274001; + --dGray6:#F2778D; + --dBlue:#F2778D; } + +body { + height: 100%; + font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; + background-color: #2F0000; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_regular.ttf"); + font-weight: normal; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_light.ttf"); + font-weight: 200; } + +@font-face { + font-family: Radikal; + src: url("static/fonts/radikal_bold.ttf"); + font-weight: bold; } + +.btn { + border-radius: 5rem; + color: white; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + background-image: linear-gradient(-40deg, #F53030, #F58B9E); } + +.btn:hover { + background-image: linear-gradient(-40deg, #A81111, #FF4B33); } + +.navbar { + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + padding: 1.5rem; + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; + text-transform: capitalize; } + +.nav > li > a { + padding-left: 1vw; + padding-right: 1vw; } + +.main { + height: 90vh; + overflow: scroll; + padding-left: 0; + padding-right: 0; + width: 100%; + display: flex; + align-items: center; + flex-direction: column; } + +.navbar .container { + width: 100%; + padding: 0 4vw; } + +@media (min-width: 768px) { + .container { + width: 100%; } } + +@media (min-width: 992px) { + .main .container, .main .orders { + width: 970px; } } + +@media (min-width: 1200px) { + .main .container, .main .orders { + width: 1170px; } } + +.main { + padding-top: 2.5rem; } + +.order_data { + display: flex; + flex-direction: row; + width: 100%; + justify-content: space-between; + padding: 0 3rem; + align-items: baseline; } + +.order_data h5 { + max-width: 60%; + padding-bottom: 3rem; } + +.expand_button { + padding: 1rem 0rem; + margin-top: -1rem; + width: 70%; + margin-bottom: 1.5rem; } + +.hi_im_haldis h2 { + display: none; } + +.hi_im_haldis h3 { + width: 100%; + font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; + text-align: center; } + +.hi_im_haldis { + background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); + border-radius: 0; + width: 100%; } + +.hi_im_haldis_wrapper { + width: 100%; } + +.darker:nth-child(even) { + background-color: #B62937; + border-radius: 2rem; } + +.darker:nth-child(odd) { + background-color: #821C25; + border-radius: 2rem; } + +.darker { + padding: 1rem; } + +.order_row:nth-child(even) .order_data { + background-color: #B62937; + border-radius: 2rem; } + +.order_row { + background: transparent; } + +.order_row:nth-child(odd) .order_data { + background-color: #821C25; + border-radius: 2rem; } + +.order_row h5 { + font-weight: bold; } + +.order_row { + margin-bottom: 3rem; } + +h3 { + padding-bottom: 1rem; } + +.home_sir { + font-weight: bold; + color: #F45D68; } + +.expand_button_wrapper { + margin-top: -1rem; + width: 100%; + display: flex; + justify-content: center; } + +.time_data { + text-align: right; + display: flex; + flex-direction: column; + justify-self: right; } + +.navbar .navbar-nav .active a { + color: #ff9bae; + border-bottom: 1px solid #ff9bae; + padding-bottom: 1rem; } + +.navbar-nav { + padding-left: 2rem; } + +.jumbotron, .darker { + display: flex; + flex-direction: column; + border-radius: 4rem; } + +.row > div > h5 { + font-weight: bold; + padding-top: 1.5rem; + font-size: 2.5rem; } + +.row > div > .amount_of_orders { + font-weight: lighter; + font-size: 1.6rem; } + +.row > div .time { + font-weight: lighter; } + +.jumbotron { + background-color: transparent; } + +.navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { + background-color: transparent; } + +.background { + -webkit-filter: blur(0px) brightness(80%); + -moz-filter: blur(0px) brightness(80%); + -o-filter: blur(0px) brightness(80%); + -ms-filter: blur(0px) brightness(80%); + filter: blur(0px) brightness(80%); + position: fixed; + top: 0; + left: 0; } + +footer a { + color: #69E8FF; } + +footer { + position: fixed; + bottom: 0; + width: 100%; + background: #CB3444; + height: 5rem; + display: flex; + align-items: center; } + +footer > hr { + display: none; } + +#mapid { + width: 100%; } + +.order_overview, .order_order, .order_items, .order_ordered, .order_depts { + padding: 1rem 5rem 3rem 5rem; } + +.order_overview { + width: 100%; } + +.order_depts { + width: 100%; + margin-bottom: 10rem; } + +.location_data, .location_products { + width: 100%; } + +.location_products { + margin-bottom: 10rem; } + +.locations_locations { + padding: 1rem 5rem 3rem 5rem; } + +.background_wrapper { + position: absolute; + left: 0; + bottom: 5rem; + width: 100%; + height: 100%; + overflow: hidden; } + +.christmas_background { + z-index: -101; + width: 300%; + height: 300%; + background: linear-gradient(-45deg, #2F0000, #C20A12); } + +.sled { + width: 15rem; + height: 15rem; + transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; + background-repeat: no-repeat; + background-position: center; + background-size: contain; + background-image: url("static/images/themes/kerstmis/sled.svg"); } + +.sled_wrapper { + top: 0.5rem; + left: -7.5rem; + position: absolute; + transform: translate(-50vw, 40vh) rotate(0deg); + width: 15rem; + height: 15rem; + animation: sled 29s ease-in-out infinite; } + +.snowman_wrapper { + height: 17rem; + width: 10rem; + position: absolute; + bottom: 15rem; + left: -12rem; + animation: snowman 37s ease infinite; + transform-origin: right bottom; } + +.snowman_head { + position: absolute; + top: 0; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_head.svg"); + animation: snowman_head 2s ease infinite; } + +.snowman_body { + position: absolute; + top: 9.5rem; + left: 0.5rem; + width: 10rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } + +.train_button { + visibility: hidden; } + +.train_wrapper { + position: absolute; + bottom: 0.5rem; + transform: translateX(-80vw); + animation: train 47s linear infinite; } + +.wheel_big, .wheel_small { + position: absolute; + bottom: -0.4rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/wheel.svg"); } + +.train { + position: absolute; + bottom: 0.5rem; + left: 30rem; + width: 30rem; + height: 10rem; + background-repeat: no-repeat; + background-size: contain; + background-image: url("static/images/themes/kerstmis/train.svg"); + animation: whobble 1s linear alternate-reverse infinite; } + +.wheel_big { + width: 3.2rem; + height: 3.2rem; } + +.wheel_small { + width: 2.5rem; + height: 2.5rem; } + +.train .wheel1 { + animation: turn 2s linear infinite; + left: 3.5rem; } + +.train .wheel2 { + animation: turn 2s linear infinite, -0.1s; + left: 7rem; } + +.train .wheel3 { + animation: turn 2s linear infinite -0.3s; + left: 10.5rem; } + +.train .wheel4 { + animation: turn 1.5s linear infinite -0.5s; + left: 13.9rem; } + +.train .wheel5 { + animation: turn 1.5s linear infinite -0.7s; + left: 16.6rem; } + +.zeus_wagon, .mc_wagon { + position: absolute; + bottom: 1.25rem; + width: 30rem; + height: 7.5rem; + background-repeat: no-repeat; + background-size: contain; + animation: whobble 1s linear alternate-reverse infinite; } + +.mc_wagon { + background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); + left: 0rem; } + +.zeus_wagon { + background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); + left: 15rem; } + +.zeus_wagon .wheel1, .mc_wagon .wheel1 { + animation: turn 2s linear infinite; + bottom: -1.1rem; + left: 2.2rem; } + +.zeus_wagon .wheel2, .mc_wagon .wheel2 { + animation: turn 2s linear infinite, -0.1s; + bottom: -1.1rem; + left: 5.75rem; } + +.zeus_wagon .wheel3, .mc_wagon .wheel3 { + animation: turn 2s linear infinite -0.3s; + bottom: -1.1rem; + left: 9.3rem; } + +@keyframes sled { + 0% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 4% { + transform: translate(-50rem, 40vh) rotate(0deg); } + 20% { + transform: translate(50vw, 10vh) rotate(20deg); } + 36% { + transform: translate(150vw, 40vh) rotate(40deg); } + 100% { + transform: translate(150vw, 40vh) rotate(40deg); } } + +@keyframes train { + 0% { + transform: translateX(-80rem); } + 55% { + transform: translateX(-80rem); } + 85% { + transform: translateX(100vw); } + 100% { + transform: translateX(100vw); } } + +@keyframes turn { + 100% { + transform: rotate(360deg); } } + +@keyframes whobble { + 100% { + transform: translateY(0.5vh); } } + +@keyframes snowman { + 0% { + transform: rotate(0); } + 20% { + transform: rotate(0); } + 30% { + transform: rotate(80deg); } + 54% { + transform: rotate(80deg); } + 68% { + transform: rotate(0); } + 100% { + transform: rotate(0); } } + +@keyframes snowman_head { + 0% { + transform: rotate(-3deg); } + 50% { + transform: rotate(3deg); } + 100% { + transform: rotate(-3deg); } } + +/*# sourceMappingURL=christmas_lightweight.css.map */ \ No newline at end of file diff --git a/app/static/css/themes/christmas_lightweight.css.map b/app/static/css/themes/christmas_lightweight.css.map new file mode 100644 index 0000000..5e25b2d --- /dev/null +++ b/app/static/css/themes/christmas_lightweight.css.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "file": "christmas_lightweight.css", + "sources": [ + "christmas_lightweight.scss" + ], + "names": [], + "mappings": ";AAAA;;;;;;;;;EASE;AAEF,AAAA,KAAK,CAAC;EACL,QAAQ,CAAA,OAAC;EACT,QAAQ,CAAA,KAAC;EACT,QAAQ,CAAA,OAAC;EACT,QAAQ,CAAA,OAAC;EACT,QAAQ,CAAA,OAAC;EACT,QAAQ,CAAA,OAAC;EACT,QAAQ,CAAA,OAAC;EACT,OAAO,CAAA,OAAC,GACP;;AACD,AAAA,IAAI,CAAA;EACH,MAAM,EAAE,IAAI;EACZ,WAAW,EAAE,8DAA8D;EAC3E,gBAAgB,EAAE,OAAO,GACzB;;AACD,UAAU;EACV,WAAW,EAAE,OAAO;EACpB,GAAG,EAAE,uCAAuC;EAC5C,WAAW,EAAE,MAAM;;AAEnB,UAAU;EACV,WAAW,EAAE,OAAO;EACpB,GAAG,EAAE,qCAAqC;EAC1C,WAAW,EAAE,GAAG;;AAEhB,UAAU;EACV,WAAW,EAAE,OAAO;EACpB,GAAG,EAAE,oCAAoC;EACzC,WAAW,EAAE,IAAI;;AAEjB,AAAA,IAAI,CAAA;EACH,aAAa,EAAE,IAAI;EACnB,KAAK,EAAE,KAAK;EACZ,WAAW,EAAE,wDAAwD;EACrE,gBAAgB,EAAE,yCAAwC,GAC1D;;AAED,AAAA,IAAI,AAAA,MAAM,CAAA;EACV,gBAAgB,EAAE,yCAAyC,GAC1D;;AACD,AAAA,OAAO,CAAC;EACP,WAAW,EAAE,wDAAwD;EACrE,OAAO,EAAE,MAAM;EAChB,gBAAgB,EAAE,WAAW;EAC7B,kBAAkB,EAAE,IAAI;EACxB,UAAU,EAAE,IAAI;EAChB,cAAc,EAAE,UAAU,GACzB;;AACD,AAAA,IAAI,GAAC,EAAE,GAAC,CAAC,CAAC;EACT,YAAY,EAAE,GAAG;EACjB,aAAa,EAAE,GAAG,GAClB;;AAED,AAAA,KAAK,CAAA;EACJ,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,MAAM;EAChB,YAAY,EAAE,CAAC;EACf,aAAa,EAAE,CAAC;EAChB,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM;EACnB,cAAc,EAAE,MAAM,GACtB;;AAED,AAAA,OAAO,CAAC,UAAU,CAAA;EACjB,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,KAAK,GACd;;AAEF,MAAM,EAAE,SAAS,EAAE,KAAK;EACvB,AAAA,UAAU,CAAC;IACV,KAAK,EAAE,IAAI,GACX;;AAEF,MAAM,EAAE,SAAS,EAAE,KAAK;EACvB,AAAA,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;IAC/B,KAAK,EAAE,KAAK,GACZ;;AAGF,MAAM,EAAE,SAAS,EAAE,MAAM;EACxB,AAAA,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC;IAC9B,KAAK,EAAE,MAAM,GACd;;AAID,AAAA,KAAK,CAAA;EACJ,WAAW,EAAE,MAAM,GACnB;;AACD,AAAA,WAAW,CAAC;EACX,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,KAAK,EAAE,IAAI;EACX,eAAe,EAAE,aAAa;EAC9B,OAAO,EAAE,MAAM;EACf,WAAW,EAAE,QAAQ,GACrB;;AACD,AAAA,WAAW,CAAC,EAAE,CAAA;EACb,SAAS,EAAE,GAAG;EACd,cAAc,EAAE,IAAI,GACpB;;AACD,AAAA,cAAc,CAAA;EACb,OAAO,EAAE,SAAS;EAClB,UAAU,EAAE,KAAK;EACjB,KAAK,EAAE,GAAG;EACV,aAAa,EAAE,MAAM,GACrB;;AAED,AAAA,aAAa,CAAC,EAAE,CAAA;EACf,OAAO,EAAE,IAAI,GACb;;AAED,AAAA,aAAa,CAAC,EAAE,CAAC;EACjB,KAAK,EAAE,IAAI;EACX,WAAW,EAAE,wDAAwD;EACrE,UAAU,EAAE,MAAM,GACjB;;AAED,AAAA,aAAa,CAAC;EACd,UAAU,EAAE,sEAAmE;EAC/E,aAAa,EAAE,CAAC;EACf,KAAK,EAAE,IAAI,GACX;;AAED,AAAA,qBAAqB,CAAC;EACrB,KAAK,EAAE,IAAI,GACX;;AACD,AAAA,OAAO,AAAA,UAAW,CAAA,IAAI,EAAC;EACvB,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,IAAI,GAClB;;AACD,AAAA,OAAO,AAAA,UAAW,CAAA,GAAG,EAAC;EACtB,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,IAAI,GAClB;;AACD,AAAA,OAAO,CAAA;EACN,OAAO,EAAE,IAAI,GACb;;AACD,AAAA,UAAU,AAAA,UAAW,CAAA,IAAI,EAAE,WAAW,CAAC;EACvC,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,IAAI,GAClB;;AAED,AAAA,UAAU,CAAC;EACX,UAAU,EAAE,WAAW,GACtB;;AAED,AAAA,UAAU,AAAA,UAAW,CAAA,GAAG,EAAE,WAAW,CAAC;EACtC,gBAAgB,EAAE,OAAO;EACzB,aAAa,EAAE,IAAI,GAClB;;AAED,AAAA,UAAU,CAAC,EAAE,CAAA;EACZ,WAAW,EAAE,IAAI,GACjB;;AACD,AAAA,UAAU,CAAA;EACT,aAAa,EAAE,IAAI,GACnB;;AACD,AAAA,EAAE,CAAA;EACD,cAAc,EAAE,IAAI,GACpB;;AAED,AAAA,SAAS,CAAC;EACT,WAAW,EAAE,IAAI;EACjB,KAAK,EAAE,OAAO,GACd;;AAED,AAAA,sBAAsB,CAAA;EACrB,UAAU,EAAE,KAAK;EACjB,KAAK,EAAE,IAAI;EACX,OAAO,EAAE,IAAI;EACb,eAAe,EAAE,MAAM,GACvB;;AAED,AAAA,UAAU,CAAC;EACV,UAAU,EAAE,KAAK;EACjB,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,MAAM;EACtB,YAAY,EAAE,KAAK,GACnB;;AAED,AAAA,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;EAC5B,KAAK,EAAE,OAAkB;EACzB,aAAa,EAAE,GAAG,CAAC,KAAK,CAAC,OAAkB;EAC3C,cAAc,EAAE,IAAI,GACpB;;AAED,AAAA,WAAW,CAAA;EACV,YAAY,EAAE,IAAI,GAClB;;AAED,AAAA,UAAU,EAAE,OAAO,CAAC;EACpB,OAAO,EAAE,IAAI;EACZ,cAAc,EAAE,MAAM;EACtB,aAAa,EAAE,IAAI,GACnB;;AAED,AAAA,IAAI,GAAC,GAAG,GAAC,EAAE,CAAC;EACX,WAAW,EAAE,IAAI;EACjB,WAAW,EAAE,MAAM;EACnB,SAAS,EAAE,MAAM,GACjB;;AAED,AAAA,IAAI,GAAC,GAAG,GAAC,iBAAiB,CAAA;EACzB,WAAW,EAAE,OAAO;EACpB,SAAS,EAAE,MAAM,GACjB;;AACD,AAAA,IAAI,GAAC,GAAG,CAAC,KAAK,CAAA;EACb,WAAW,EAAE,OAAO,GACpB;;AAED,AAAA,UAAU,CAAC;EACX,gBAAgB,EAAE,WAAW,GAC7B;;AAEA,AAAA,eAAe,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,eAAe,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,AAAA,MAAM,CAAA;EAClF,gBAAgB,EAAE,WAAW,GAC5B;;AAED,AAAA,WAAW,CAAC;EACZ,cAAc,EAAE,SAAS,CAAC,eAAe;EACzC,WAAW,EAAE,SAAS,CAAC,eAAe;EACtC,SAAS,EAAE,SAAS,CAAC,eAAe;EACpC,UAAU,EAAE,SAAS,CAAC,eAAe;EACrC,MAAM,EAAE,SAAS,CAAC,eAAe;EACjC,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC,GACP;;AAED,AAAA,MAAM,CAAC,CAAC,CAAA;EACP,KAAK,EAAE,OAAO,GACd;;AAED,AAAA,MAAM,CAAA;EACL,QAAQ,EAAE,KAAK;EACf,MAAM,EAAE,CAAC;EACT,KAAK,EAAE,IAAI;EACX,UAAU,EAAC,OAAO;EAClB,MAAM,EAAE,IAAI;EACZ,OAAO,EAAE,IAAI;EACb,WAAW,EAAE,MAAM,GACnB;;AAED,AAAA,MAAM,GAAC,EAAE,CAAA;EACR,OAAO,EAAE,IAAI,GACb;;AAED,AAAA,MAAM,CAAC;EACN,KAAK,EAAE,IAAI,GACX;;AAED,AAAA,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;EACzE,OAAO,EAAE,mBAAmB,GAC5B;;AAED,AAAA,eAAe,CAAA;EACd,KAAK,EAAE,IAAI,GACX;;AAED,AAAA,YAAY,CAAC;EACZ,KAAK,EAAE,IAAI;EACX,aAAa,EAAE,KAAK,GACpB;;AAED,AAAA,cAAc,EAAE,kBAAkB,CAAC;EAClC,KAAK,EAAE,IAAI,GACX;;AAED,AAAA,kBAAkB,CAAC;EAClB,aAAa,EAAE,KAAK,GACpB;;AAED,AAAA,oBAAoB,CAAC;EACpB,OAAO,EAAE,mBAAmB,GAC5B;;AAED,AAAA,mBAAmB,CAAC;EACnB,QAAQ,EAAE,QAAQ;EAClB,IAAI,EAAE,CAAC;EACP,MAAM,EAAE,IAAI;EACZ,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,QAAQ,EAAE,MAAM,GAChB;;AAED,AAAA,qBAAqB,CAAA;EACpB,OAAO,EAAE,IAAI;EACb,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;EACZ,UAAU,EAAE,yCAAyC,GACrD;;AAED,AAAA,KAAK,CAAC;EACL,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,KAAK;EACb,UAAU,EAAE,iDAAiD;EAC7D,iBAAiB,EAAE,SAAS;EAC5B,mBAAmB,EAAE,MAAM;EAC3B,eAAe,EAAE,OAAO;EACxB,gBAAgB,EAAE,6CAA6C,GAC/D;;AAED,AAAA,aAAa,CAAA;EACZ,GAAG,EAAE,MAAM;EACX,IAAI,EAAE,OAAO;EACb,QAAQ,EAAE,QAAQ;EAClB,SAAS,EAAE,sBAAsB,CAAC,YAAY;EAC9C,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,KAAK;EACb,SAAS,EAAE,6BAA6B,GACxC;;AAED,AAAA,gBAAgB,CAAA;EACf,MAAM,EAAE,KAAK;EACb,KAAK,EAAE,KAAK;EACZ,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,IAAI,EAAE,MAAM;EACZ,SAAS,EAAE,yBAAyB;EACpC,gBAAgB,EAAE,YAAY,GAC9B;;AAED,AAAA,aAAa,CAAA;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,CAAC;EACN,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,KAAK;EACb,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,gBAAgB,EAAE,qDAAqD;EACvE,SAAS,EAAE,6BAA6B,GACxC;;AACD,AAAA,aAAa,CAAA;EACZ,QAAQ,EAAE,QAAQ;EAClB,GAAG,EAAE,MAAM;EACX,IAAI,EAAE,MAAM;EACZ,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,KAAK;EACb,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,gBAAgB,EAAE,qDAAqD,GACvE;;AAED,AAAA,aAAa,CAAC;EACb,UAAU,EAAE,MAAM,GAClB;;AAED,AAAA,cAAc,CAAA;EACb,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,MAAM;EACd,SAAS,EAAE,iBAAiB;EAC5B,SAAS,EAAE,yBAAyB,GACpC;;AACD,AAAA,UAAU,EAAE,YAAY,CAAC;EACxB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,OAAO;EACf,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,gBAAgB,EAAE,8CAA8C,GAEhE;;AACD,AAAA,MAAM,CAAC;EACN,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,MAAM;EACd,IAAI,EAAE,KAAK;EACX,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,KAAK;EACb,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,gBAAgB,EAAE,8CAA8C;EAChE,SAAS,EAAE,4CAA4C,GACvD;;AAED,AAAA,UAAU,CAAC;EACV,KAAK,EAAE,MAAM;EACb,MAAM,EAAE,MAAM,GACd;;AAED,AAAA,YAAY,CAAC;EACZ,KAAK,EAAE,MAAM;EACb,MAAM,EAAE,MAAM,GACd;;AAED,AAAA,MAAM,CAAC,OAAO,CAAC;EACd,SAAS,EAAE,uBAAuB;EAClC,IAAI,EAAE,MAAM,GACZ;;AAED,AAAA,MAAM,CAAC,OAAO,CAAA;EACb,SAAS,EAAE,8BAA8B;EACzC,IAAI,EAAE,IAAI,GACV;;AAED,AAAA,MAAM,CAAC,OAAO,CAAA;EACb,SAAS,EAAE,6BAA6B;EACxC,IAAI,EAAE,OAAO,GACb;;AAED,AAAA,MAAM,CAAC,OAAO,CAAA;EACb,SAAS,EAAE,+BAA+B;EAC1C,IAAI,EAAE,OAAO,GACb;;AAED,AAAA,MAAM,CAAC,OAAO,CAAA;EACb,SAAS,EAAE,+BAA+B;EAC1C,IAAI,EAAE,OAAO,GACb;;AAED,AAAA,WAAW,EAAE,SAAS,CAAC;EACtB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,OAAO;EACf,KAAK,EAAE,KAAK;EACZ,MAAM,EAAE,MAAM;EACd,iBAAiB,EAAE,SAAS;EAC5B,eAAe,EAAE,OAAO;EACxB,SAAS,EAAE,4CAA4C,GACvD;;AAED,AAAA,SAAS,CAAC;EACT,gBAAgB,EAAE,iDAAiD;EACnE,IAAI,EAAE,IAAI,GACV;;AAED,AAAA,WAAW,CAAC;EACX,gBAAgB,EAAE,mDAAmD;EACrE,IAAI,EAAE,KAAK,GACX;;AAED,AAAA,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC;EACtC,SAAS,EAAE,uBAAuB;EAClC,MAAM,EAAE,OAAO;EACf,IAAI,EAAE,MAAM,GACZ;;AAED,AAAA,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAA;EACrC,SAAS,EAAE,8BAA8B;EACzC,MAAM,EAAE,OAAO;EACf,IAAI,EAAE,OAAO,GACb;;AAED,AAAA,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAA;EACrC,SAAS,EAAE,6BAA6B;EACxC,MAAM,EAAE,OAAO;EACf,IAAI,EAAE,MAAM,GACZ;;AAED,UAAU,CAAV,IAAU;EACT,EAAE;IACD,SAAS,EAAE,uBAAuB,CAAC,YAAY;EAEhD,EAAE;IACD,SAAS,EAAE,uBAAuB,CAAC,YAAY;EAEhD,GAAG;IACF,SAAS,EAAE,qBAAoB,CAAC,aAAa;EAE9C,GAAG;IACF,SAAS,EAAE,sBAAqB,CAAC,aAAa;EAE/C,IAAI;IACH,SAAS,EAAE,sBAAqB,CAAC,aAAa;;AAIhD,UAAU,CAAV,KAAU;EACT,EAAE;IACD,SAAS,EAAE,kBAAkB;EAE9B,GAAG;IACF,SAAS,EAAE,kBAAkB;EAE9B,GAAG;IACF,SAAS,EAAE,iBAAiB;EAE7B,IAAI;IACH,SAAS,EAAE,iBAAiB;;AAK9B,UAAU,CAAV,IAAU;EACT,IAAI;IACH,SAAS,EAAE,cAAc;;AAI3B,UAAU,CAAV,OAAU;EACT,IAAI;IACH,SAAS,EAAE,iBAAiB;;AAI9B,UAAU,CAAV,OAAU;EACT,EAAE;IACD,SAAS,EAAE,SAAU;EAEtB,GAAG;IACF,SAAS,EAAE,SAAU;EAEtB,GAAG;IACF,SAAS,EAAE,aAAa;EAEzB,GAAG;IACF,SAAS,EAAE,aAAa;EAEzB,GAAG;IACF,SAAS,EAAE,SAAU;EAEtB,IAAI;IACH,SAAS,EAAE,SAAU;;AAGvB,UAAU,CAAV,YAAU;EACT,EAAE;IACD,SAAS,EAAE,aAAa;EAEzB,GAAG;IACF,SAAS,EAAE,YAAY;EAExB,IAAI;IACH,SAAS,EAAE,aAAa" +} \ No newline at end of file diff --git a/app/static/css/themes/lowPerformance/kerstmis.scss b/app/static/css/themes/christmas_lightweight.scss similarity index 99% rename from app/static/css/themes/lowPerformance/kerstmis.scss rename to app/static/css/themes/christmas_lightweight.scss index bc6c735..73bd16d 100644 --- a/app/static/css/themes/lowPerformance/kerstmis.scss +++ b/app/static/css/themes/christmas_lightweight.scss @@ -9,10 +9,7 @@ Enige discretie is aangeraden. */ - -/*low performance kerstmis*/ :root { - /*Darkmode colors*/ --dGray0:#F28705; --dGray1:white; --dGray2:#590212; diff --git a/app/static/css/themes/highPerformance/dataPrivacy.css b/app/static/css/themes/dataPrivacy.css similarity index 100% rename from app/static/css/themes/highPerformance/dataPrivacy.css rename to app/static/css/themes/dataPrivacy.css diff --git a/app/static/css/themes/highPerformance/halloween.css b/app/static/css/themes/halloween.css similarity index 88% rename from app/static/css/themes/highPerformance/halloween.css rename to app/static/css/themes/halloween.css index baa23d8..8d07136 100644 --- a/app/static/css/themes/highPerformance/halloween.css +++ b/app/static/css/themes/halloween.css @@ -1,7 +1,4 @@ -/*halloween*/ - :root { - /*Darkmode colors*/ --dGray0:#FFEB65; --dGray1:#F28705; --dGray2:#F25C05; @@ -11,6 +8,7 @@ --dGray6:#260101; --dBlue:#D91604; } + .table-hover tbody tr:hover{ background-image: url("static/images/themes/halloween/Halloween.jpeg"); } diff --git a/app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc b/app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc deleted file mode 100644 index 80cd6645d73044f67230bdc22607b27c95d9f1e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151099 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
;ibgBX9cV;rlv)qkn)SO_G= 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 diff --git a/app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc b/app/static/css/themes/highPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc deleted file mode 100644 index 2cf0dc0a25e23c50630a2c1f40022f67a815b938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123278 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 G`u_o*YzMdi diff --git a/app/static/css/themes/highPerformance/.sass-cache/f007f33e9ca31bc5d2b8605323eaf3b5d0e7edd6/kerstmis.scssc b/app/static/css/themes/highPerformance/.sass-cache/f007f33e9ca31bc5d2b8605323eaf3b5d0e7edd6/kerstmis.scssc deleted file mode 100644 index 1f15a0dc66603bb855fb0e7e165a170ab1d6159e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154957 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 diff --git a/app/static/css/themes/highPerformance/darkmode.css b/app/static/css/themes/highPerformance/darkmode.css deleted file mode 100644 index 7a1dc46..0000000 --- a/app/static/css/themes/highPerformance/darkmode.css +++ /dev/null @@ -1,12 +0,0 @@ -/*Darkmode*/ -:root { - /*Darkmode colors*/ - --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; -} diff --git a/app/static/css/themes/highPerformance/kerstmis.css b/app/static/css/themes/highPerformance/kerstmis.css deleted file mode 100644 index c7934c2..0000000 --- a/app/static/css/themes/highPerformance/kerstmis.css +++ /dev/null @@ -1,534 +0,0 @@ -@charset "UTF-8"; -/* -¡¡¡ OPGELET !!! -Deze css bevat lelijke code. -Dit komt doordat bootstrap lelijk en oud is. -Ik zal later proberen de css te verbeteren en bootstrap weg te gooien. -Enige discretie is aangeraden. - ----=§[ Arnhoudt ]§=--- - -*/ -/*high performance kerstmis*/ -:root { - /*Darkmode colors*/ - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } - -body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } - -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_regular.ttf"); - font-weight: normal; } -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_light.ttf"); - font-weight: 200; } -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_medium.ttf"); - font-weight: medium; } -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_bold.ttf"); - font-weight: bold; } -.btn { - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg, #F53030, #F58B9E); } - -.btn:hover { - background-image: linear-gradient(-40deg, #A81111, #FF4B33); } - -.navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - text-transform: capitalize; } - -.nav > li > a { - padding-left: 1vw; - padding-right: 1vw; } - -.main { - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; } - -.navbar .container { - width: 100%; - padding: 0 4vw; } - -@media (min-width: 768px) { - .container { - width: 100%; } } -@media (min-width: 992px) { - .main .container, .main .orders { - width: 970px; } } -@media (min-width: 1200px) { - .main .container, .main .orders { - width: 1170px; } } -.main { - padding-top: 2.5rem; } - -.order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; } - -.order_row { - background: transparent; } - -.order_data h5 { - max-width: 60%; - padding-bottom: 3rem; } - -.expand_button { - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; } - -.hi_im_haldis h2 { - display: none; } - -.hi_im_haldis h3 { - width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - text-align: center; } - -.hi_im_haldis { - background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); - border-radius: 0; - width: 100%; } - -.hi_im_haldis_wrapper { - width: 100%; } - -.darker:nth-child(even) { - background-color: #B62937; - border-radius: 2rem; } - -.darker:nth-child(odd) { - background-color: #821C25; - border-radius: 2rem; } - -.darker { - padding: 1rem; } - -.order_row:nth-child(even) .order_data { - background-color: #B62937; - border-radius: 2rem; } - -.order_row:nth-child(odd) .order_data { - background-color: #821C25; - border-radius: 2rem; } - -.order_row h5 { - font-weight: bold; } - -.order_row { - margin-bottom: 3rem; } - -h3 { - padding-bottom: 1rem; } - -.home_sir { - font-weight: bold; - color: #F45D68; } - -.expand_button_wrapper { - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; } - -.time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; } - -.navbar .navbar-nav .active a { - color: #ff9bae; - border-bottom: 1px solid #ff9bae; - padding-bottom: 1rem; } - -.navbar-nav { - padding-left: 2rem; } - -.jumbotron, .darker { - display: flex; - flex-direction: column; - border-radius: 4rem; } - -.row > div > h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; } - -.row > div > .amount_of_orders { - font-weight: lighter; - font-size: 1.6rem; } - -.row > div .time { - font-weight: lighter; } - -.jumbotron { - background-color: transparent; } - -.navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { - background-color: transparent; } - -.background { - -webkit-filter: blur(0px) brightness(80%); - -moz-filter: blur(0px) brightness(80%); - -o-filter: blur(0px) brightness(80%); - -ms-filter: blur(0px) brightness(80%); - filter: blur(0px) brightness(80%); - position: fixed; - top: 0; - left: 0; } - -footer a { - color: #69E8FF; } - -footer { - position: fixed; - bottom: 0; - width: 100%; - background: #CB3444; - height: 5rem; - display: flex; - align-items: center; } - -footer > hr { - display: none; } - -#mapid { - width: 100%; } - -.order_overview, .order_order, .order_items, .order_ordered, .order_depts { - padding: 1rem 5rem 3rem 5rem; } - -.order_overview { - width: 100%; } - -.order_depts { - width: 100%; - margin-bottom: 10rem; } - -.location_data, .location_products { - width: 100%; } - -.location_products { - margin-bottom: 10rem; } - -.locations_locations { - padding: 1rem 5rem 3rem 5rem; } - -.background_wrapper { - position: absolute; - left: 0; - bottom: 5rem; - width: 100%; - height: 100%; - overflow: hidden; } - -.christmas_background { - z-index: -101; - width: 300%; - height: 300%; - background: linear-gradient(-45deg, #2F0000, #C20A12); - animation: gradientBG 19s ease infinite; } - -.sled { - width: 15rem; - height: 15rem; - transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - background-image: url("static/images/themes/kerstmis/sled.svg"); } - -.sled_wrapper { - top: 0.5rem; - left: -7.5rem; - position: absolute; - transform: translate(-50vw, 40vh) rotate(0deg); - width: 15rem; - height: 15rem; - animation: sled 29s ease-in-out infinite; } - -.train_button:checked ~ .sled_wrapper:hover { - animation-play-state: paused; } - -.train_button:checked ~ .sled_wrapper:hover .sled { - transform: translateY(100vh) rotate(90deg); } - -.snowman_wrapper { - height: 17rem; - width: 10rem; - position: absolute; - bottom: 15rem; - left: -12rem; - animation: snowman 37s ease infinite; - transform-origin: right bottom; } - -.snowman_head { - position: absolute; - top: 0; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_head.svg"); - animation: snowman_head 2s ease infinite; } - -.snowman_body { - position: absolute; - top: 9.5rem; - left: 0.5rem; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } - -.train_button:checked ~ .merry_christmas { - position: absolute; - top: 0; - width: 100%; - height: 100%; - background-position: center; - background-image: url("static/images/themes/kerstmis/merry_christmas.svg"); - background-size: 25vw; - background-repeat: no-repeat; - animation: merry_christmas 5s ease infinite; } - -.train_button { - position: absolute; - transform: scaleX(20) scaleY(8) translateX(-100rem); - bottom: 5.5rem; - left: 7rem; - animation: follow_train 47s linear infinite; - opacity: 0; } - -.train_wrapper { - position: absolute; - bottom: 0.5rem; - transform: translateX(-80vw); - animation: train 47s linear infinite; } - -.wheel_big, .wheel_small { - position: absolute; - bottom: -0.4rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/wheel.svg"); } - -.train { - position: absolute; - bottom: 0.5rem; - left: 30rem; - width: 30rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/train.svg"); - animation: whobble 1s linear alternate-reverse infinite; } - -.wheel_big { - width: 3.2rem; - height: 3.2rem; } - -.wheel_small { - width: 2.5rem; - height: 2.5rem; } - -.train .wheel1 { - animation: turn 2s linear infinite; - left: 3.5rem; } - -.train .wheel2 { - animation: turn 2s linear infinite, -0.1s; - left: 7rem; } - -.train .wheel3 { - animation: turn 2s linear infinite -0.3s; - left: 10.5rem; } - -.train .wheel4 { - animation: turn 1.5s linear infinite -0.5s; - left: 13.9rem; } - -.train .wheel5 { - animation: turn 1.5s linear infinite -0.7s; - left: 16.6rem; } - -.zeus_wagon, .mc_wagon { - position: absolute; - bottom: 1.25rem; - width: 30rem; - height: 7.5rem; - background-repeat: no-repeat; - background-size: contain; - animation: whobble 1s linear alternate-reverse infinite; } - -.mc_wagon { - background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); - left: 0rem; } - -.zeus_wagon { - background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); - left: 15rem; } - -.zeus_wagon .wheel1, .mc_wagon .wheel1 { - animation: turn 2s linear infinite; - bottom: -1.1rem; - left: 2.2rem; } - -.zeus_wagon .wheel2, .mc_wagon .wheel2 { - animation: turn 2s linear infinite, -0.1s; - bottom: -1.1rem; - left: 5.75rem; } - -.zeus_wagon .wheel3, .mc_wagon .wheel3 { - animation: turn 2s linear infinite -0.3s; - bottom: -1.1rem; - left: 9.3rem; } - -.snow { - border-radius: 50%; - opacity: 0.8; - position: absolute; - top: -100vh; - animation-name: fall; - animation-timing-function: linear; - animation-iteration-count: infinite; } - -.layer1 { - width: 1rem; - height: 1rem; - filter: blur(1.5px); - box-shadow: 71vw 89.7vh 0 -0.13rem#fff,37.6vw 73.2vh 0 -0.46rem#fff,31.1vw 76.6vh 0 -0.42rem#fff,41.5vw 94vh 0 -0.3rem#fff,76.7vw 28.6vh 0 -0.18rem#fff,21.7vw 70.7vh 0 -0.34rem#fff,14.6vw 72.9vh 0 -0.04rem#fff,72vw 50vh 0 -0.12rem#fff,89.6vw 90.4vh 0 -0.45rem#fff,49.7vw 21.5vh 0 -0.02rem#fff,15.8vw 87.2vh 0 -0.04rem#fff,46.3vw 85.9vh 0 -0.24rem#fff,91.6vw 7.4vh 0 -0.11rem#fff,83.3vw 60.5vh 0 -0.06rem#fff,15.2vw 3.2vh 0 -0.31rem#fff,52.9vw 54.1vh 0 -0.48rem#fff,58.9vw 42.1vh 0 -0.07rem#fff,40.7vw 10.5vh 0 -0.25rem#fff,53.7vw 74.5vh 0 -0.33rem#fff,89vw 50.9vh 0 -0.2rem#fff,35vw 22.6vh 0 -0.2rem#fff,18.9vw 66.4vh 0 -0.33rem#fff,66.8vw 22.9vh 0 -0.05rem#fff,34.3vw 46.9vh 0 -0.26rem#fff,72.9vw 33.1vh 0 -0.25rem#fff,23.2vw 2.5vh 0 -0.16rem#fff,60.3vw 21.6vh 0 -0.35rem#fff,14.3vw 0.6vh 0 -0.09rem#fff,95.6vw 72.2vh 0 -0.03rem#fff,4vw 28.6vh 0 -0.17rem#fff,40.8vw 67.7vh 0 -0.16rem#fff,85vw 88.1vh 0 -0.41rem#fff,37.4vw 50.1vh 0 -0.07rem#fff,50.8vw 39.8vh 0 -0.01rem#fff,14.4vw 95.1vh 0 -0.23rem#fff,77.7vw 10.2vh 0 -0.14rem#fff,35.1vw 59vh 0 -0.03rem#fff,45.8vw 42.4vh 0 -0.37rem#fff,48.3vw 51.3vh 0 -0.45rem#fff,98.3vw 5.8vh 0 -0.26rem#fff,2.4vw 88vh 0 -0.17rem#fff,16vw 49.1vh 0 -0.39rem#fff,76.6vw 42.6vh 0 -0.25rem#fff,17.2vw 44.5vh 0 -0.1rem#fff,51.2vw 73.7vh 0 -0.33rem#fff,31.7vw 59.2vh 0 -0.47rem#fff,32.4vw 68.9vh 0 -0.07rem#fff,3.7vw 94.8vh 0 -0.33rem#fff,55.3vw 3.8vh 0 -0.24rem#fff,25.3vw 81.2vh 0 -0.21rem#fff,68.2vw 97.6vh 0 -0.27rem#fff,43.4vw 56.5vh 0 -0.06rem#fff,40.6vw 98.7vh 0 -0.49rem#fff,41.2vw 37.2vh 0 -0.22rem#fff,66.7vw 21.2vh 0 -0.32rem#fff,3.6vw 75.9vh 0 -0.04rem#fff,66.2vw 71.2vh 0 -0.33rem#fff,30.6vw 59.9vh 0 -0.02rem#fff,22.6vw 72.1vh 0 -0.02rem#fff,93.9vw 9.7vh 0 -0.19rem#fff,99.1vw 73.3vh 0 -0.07rem#fff,48.4vw 94.2vh 0 -0.33rem#fff,44.1vw 55.1vh 0 -0.35rem#fff,98.3vw 34vh 0 -0.07rem#fff,85.1vw 30.4vh 0 -0.42rem#fff,65.2vw 21.4vh 0 -0.05rem#fff,72.1vw 92.9vh 0 -0.48rem#fff,25.8vw 53.6vh 0 -0.02rem#fff,13.8vw 12.7vh 0 -0.26rem#fff,79.4vw 94.9vh 0 -0.06rem#fff,41.8vw 56.2vh 0 -0.31rem#fff,67.4vw 20.2vh 0 -0.34rem#fff,35.6vw 88.7vh 0 -0.1rem#fff,12.5vw 20.1vh 0 -0.06rem#fff,30.3vw 32.7vh 0 -0.34rem#fff,51.4vw 84.2vh 0 -0.15rem#fff,16.2vw 80.1vh 0 -0.31rem#fff,6.1vw 14.1vh 0 -0.41rem#fff,86.6vw 55.9vh 0 -0.41rem#fff,43.5vw 75.9vh 0 -0.45rem#fff,77.5vw 20.4vh 0 -0.12rem#fff,67.7vw 97.6vh 0 -0.08rem#fff,0.8vw 18.1vh 0 -0.33rem#fff,60.6vw 21.3vh 0 -0.19rem#fff,70.2vw 79.3vh 0 -0.26rem#fff,50.8vw 68.8vh 0 -0.35rem#fff,53.9vw 12.5vh 0 -0.39rem#fff,76.4vw 45.9vh 0 -0.12rem#fff,11.5vw 58.7vh 0 -0.31rem#fff,76.3vw 74.7vh 0 -0.4rem#fff,4.7vw 46.7vh 0 -0.39rem#fff,54.5vw 63.6vh 0 -0.28rem#fff,51.6vw 65.9vh 0 -0.3rem#fff,65.9vw 47.6vh 0 -0.08rem#fff,91.6vw 58.8vh 0 -0.12rem#fff,26.9vw 71.6vh 0 -0.36rem#fff,59.7vw 71.2vh 0 -0.37rem#fff,47.1vw 16.2vh 0 -0.14rem#fff,72.4vw 45.7vh 0 -0.06rem#fff,30.8vw 39.3vh 0 -0.38rem#fff; - animation-duration: 18s; } - -.layer1.a { - animation-delay: -9s; } - -.layer2 { - width: 0.8rem; - height: 0.8rem; - filter: blur(3px); - box-shadow: 71.8vw 15.9vh 0 -0.3rem#fff,4.2vw 8.1vh 0 -0.41rem#fff,67.5vw 49.2vh 0 -0.28rem#fff,72vw 97.8vh 0 -0.22rem#fff,78.1vw 28vh 0 -0.41rem#fff,34.2vw 51.7vh 0 -0.47rem#fff,37.9vw 76.5vh 0 -0.39rem#fff,92.6vw 36.3vh 0 -0.22rem#fff,59.9vw 8.6vh 0 -0.07rem#fff,32.5vw 74vh 0 -0.07rem#fff,75.7vw 81.6vh 0 -0.12rem#fff,1.7vw 18.5vh 0 -0.2rem#fff,12.3vw 64.7vh 0 -0.37rem#fff,83.9vw 47vh 0 -0.12rem#fff,33.8vw 21.3vh 0 -0.14rem#fff,6.5vw 92.5vh 0 -0.29rem#fff,72.2vw 60.8vh 0 -0.17rem#fff,38.4vw 16vh 0 -0.17rem#fff,23.9vw 58.4vh 0 -0.32rem#fff,40.2vw 52.4vh 0 -0.23rem#fff,48.9vw 74.6vh 0 -0.03rem#fff,61.5vw 36.1vh 0 -0.49rem#fff,60.9vw 94.5vh 0 -0.42rem#fff,2.8vw 59.7vh 0 -0.27rem#fff,62.6vw 32.4vh 0 -0.45rem#fff,91.3vw 18vh 0 -0.09rem#fff,35.9vw 35.5vh 0 -0.11rem#fff,60.2vw 95.5vh 0 -0.21rem#fff,19.8vw 46.5vh 0 -0.09rem#fff,57.7vw 20.7vh 0 -0.03rem#fff,69.8vw 33.8vh 0 -0.34rem#fff,69.1vw 71.5vh 0 -0.45rem#fff,70.5vw 87.9vh 0 -0.5rem#fff,77vw 34.9vh 0 -0.43rem#fff,35.6vw 28.7vh 0 -0.14rem#fff,28.6vw 22.7vh 0 -0.47rem#fff,46.3vw 7.1vh 0 -0.06rem#fff,66.6vw 92.6vh 0 -0.32rem#fff,96.5vw 19.1vh 0 -0.12rem#fff,24.6vw 45.5vh 0 -0.27rem#fff,71.6vw 85.8vh 0 -0.16rem#fff,1.1vw 44.9vh 0 -0.36rem#fff,94.4vw 84.2vh 0 -0.19rem#fff,92.2vw 20.2vh 0 -0.27rem#fff,42.5vw 66.1vh 0 -0.46rem#fff,70.8vw 98.4vh 0 -0.01rem#fff,71.7vw 99vh 0 -0.19rem#fff,0.2vw 34.1vh 0 -0.22rem#fff,87.3vw 30.7vh 0 -0.09rem#fff,80.3vw 93.8vh 0 -0.41rem#fff,72.2vw 8.3vh 0 -0.09rem#fff,27.1vw 46.1vh 0 -0.15rem#fff,10.2vw 93.6vh 0 -0.42rem#fff,76vw 51.5vh 0 -0.26rem#fff,28.7vw 76.3vh 0 -0.11rem#fff,85.1vw 21.2vh 0 -0.46rem#fff,25.9vw 82.2vh 0 -0.34rem#fff,32.3vw 69.8vh 0 -0.29rem#fff,97.3vw 56.8vh 0 -0.26rem#fff,48.2vw 29.6vh 0 -0.28rem#fff,76.2vw 61.9vh 0 -0.1rem#fff,62vw 96vh 0 -0.01rem#fff,76vw 79.9vh 0 -0.36rem#fff,59.9vw 86.8vh 0 -0.22rem#fff,72.8vw 92.3vh 0 -0.02rem#fff,62.7vw 55.9vh 0 -0.46rem#fff,81.1vw 53.3vh 0 -0.09rem#fff,42.4vw 20.2vh 0 -0.15rem#fff,72.7vw 95.8vh 0 -0.26rem#fff,67.6vw 11vh 0 -0.08rem#fff,62.5vw 99vh 0 -0.17rem#fff,52.7vw 46.1vh 0 -0.35rem#fff,49.7vw 73vh 0 -0.33rem#fff,1.9vw 25.1vh 0 -0.06rem#fff,25.6vw 11.6vh 0 -0.43rem#fff,9.7vw 28.4vh 0 -0.11rem#fff,52.1vw 87.4vh 0 -0.45rem#fff,94.6vw 3.6vh 0 -0.37rem#fff,67.5vw 67vh 0 -0.29rem#fff,45.4vw 34.9vh 0 -0.02rem#fff,41.6vw 99.6vh 0 -0.34rem#fff,26.3vw 53vh 0 -0.01rem#fff,41.2vw 73.7vh 0 -0.36rem#fff,6.9vw 29.5vh 0 -0.17rem#fff,25.1vw 39.2vh 0 -0.2rem#fff,93.2vw 58.2vh 0 -0.3rem#fff,93.2vw 58.2vh 0 -0.31rem#fff,91.7vw 29vh 0 -0.01rem#fff,90.1vw 25.4vh 0 -0.23rem#fff,12.2vw 98.7vh 0 -0.33rem#fff,88vw 73.3vh 0 -0.29rem#fff,91.5vw 61vh 0 -0.43rem#fff,96.1vw 70.8vh 0 -0.21rem#fff,98.2vw 55.4vh 0 -0.27rem#fff,15.2vw 59vh 0 -0.34rem#fff,66.3vw 83.5vh 0 -0.05rem#fff,49vw 8.5vh 0 -0.47rem#fff,93.3vw 91.7vh 0 -0.17rem#fff,15.4vw 35.4vh 0 -0.47rem#fff,14.3vw 48.5vh 0 -0.44rem#fff; - animation-duration: 24s; } - -.layer2.a { - animation-delay: -12s; } - -.layer3 { - width: 0.6rem; - height: 0.6rem; - filter: blur(6px); - box-shadow: 23.4vw 84.5vh 0 -0.38rem#fff,47.1vw 27.7vh 0 -0.23rem#fff,57.9vw 71.8vh 0 -0.09rem#fff,99vw 88.7vh 0 -0.37rem#fff,69vw 41.3vh 0 -0.14rem#fff,44.7vw 79.1vh 0 -0.4rem#fff,53.2vw 22.3vh 0 -0.5rem#fff,37.8vw 79.6vh 0 -0.08rem#fff,46.1vw 40.6vh 0 -0.2rem#fff,9.8vw 50.6vh 0 -0.05rem#fff,45.6vw 13.3vh 0 -0.02rem#fff,23.3vw 18.3vh 0 -0.32rem#fff,38.4vw 20.4vh 0 -0.22rem#fff,37.5vw 34.1vh 0 -0.21rem#fff,31vw 96.9vh 0 -0.1rem#fff,6.8vw 99vh 0 -0.49rem#fff,19.7vw 13.4vh 0 -0.28rem#fff,24vw 16.4vh 0 -0.09rem#fff,98.6vw 17.6vh 0 -0.08rem#fff,5.2vw 26.8vh 0 -0.35rem#fff,60.5vw 57.7vh 0 -0.34rem#fff,63.4vw 34.1vh 0 -0.46rem#fff,62.2vw 9.9vh 0 -0.13rem#fff,31.8vw 40vh 0 -0.19rem#fff,28vw 68.9vh 0 -0.33rem#fff,74.5vw 21.3vh 0 -0.32rem#fff,30.8vw 29.5vh 0 -0.25rem#fff,80.3vw 28vh 0 -0.12rem#fff,88.7vw 47.8vh 0 -0.33rem#fff,7.9vw 70.8vh 0 -0.46rem#fff,26.6vw 49.2vh 0 -0.04rem#fff,98.4vw 42.8vh 0 -0.09rem#fff,62.5vw 64.5vh 0 -0.48rem#fff,60.7vw 92.5vh 0 -0.13rem#fff,2.8vw 99.2vh 0 -0.49rem#fff,81.4vw 21.3vh 0 -0.4rem#fff,83.4vw 47.1vh 0 -0.46rem#fff,79.2vw 2.6vh 0 -0.17rem#fff,17.7vw 3.1vh 0 -0.12rem#fff,66.4vw 98.4vh 0 -0.34rem#fff,59.5vw 51.1vh 0 -0.2rem#fff,5.8vw 28.2vh 0 -0.41rem#fff,9.7vw 54vh 0 -0.48rem#fff,24.1vw 98.3vh 0 -0.29rem#fff,9.7vw 73.1vh 0 -0.44rem#fff,10vw 53.7vh 0 -0.5rem#fff,37.7vw 16.1vh 0 -0.31rem#fff,43.9vw 51.8vh 0 -0.29rem#fff,70.8vw 54vh 0 -0.19rem#fff,61.5vw 91vh 0 -0.41rem#fff,87.1vw 13.1vh 0 -0.22rem#fff,89.6vw 34.1vh 0 -0.25rem#fff,52.8vw 38.1vh 0 -0.33rem#fff,88.4vw 79.4vh 0 -0.22rem#fff,84.4vw 84.6vh 0 -0.1rem#fff,69.4vw 8.7vh 0 -0.46rem#fff,8.8vw 73.7vh 0 -0.19rem#fff,89.3vw 14.7vh 0 -0.1rem#fff,100vw 72.7vh 0 -0.2rem#fff,16.9vw 93.8vh 0 -0.22rem#fff,90.7vw 36.1vh 0 -0.43rem#fff,46.6vw 49.6vh 0 -0.21rem#fff,57.3vw 72.3vh 0 -0.03rem#fff,49.7vw 2vh 0 -0.15rem#fff,67vw 96.2vh 0 -0.47rem#fff,86vw 71.7vh 0 -0.11rem#fff,66vw 65.8vh 0 -0.32rem#fff,85.2vw 7.6vh 0 -0.12rem#fff,95.9vw 49.4vh 0 -0.15rem#fff,33.2vw 66.6vh 0 -0.14rem#fff,75.4vw 26.3vh 0 -0.02rem#fff,52.7vw 56vh 0 -0.11rem#fff,37.7vw 77vh 0 -0.18rem#fff,26.3vw 59.9vh 0 -0.18rem#fff,88.2vw 74.6vh 0 -0.39rem#fff,89.5vw 61.2vh 0 -0.48rem#fff,62vw 79.5vh 0 -0.4rem#fff,98.7vw 3.9vh 0 -0.01rem#fff,63.3vw 32vh 0 -0.43rem#fff,49.6vw 28.5vh 0 -0.09rem#fff,70vw 87vh 0 -0.05rem#fff,38.3vw 67.3vh 0 -0.49rem#fff,41.8vw 82.5vh 0 -0.36rem#fff,85.8vw 74vh 0 -0.07rem#fff,82.3vw 48.8vh 0 -0.11rem#fff,35.2vw 79.8vh 0 -0.4rem#fff,73.3vw 72.4vh 0 -0.36rem#fff,62.4vw 30.5vh 0 -0.14rem#fff,48.5vw 51.9vh 0 -0.03rem#fff,74.6vw 51.1vh 0 -0.35rem#fff,62.6vw 12.8vh 0 -0.33rem#fff,10vw 72.1vh 0 -0.2rem#fff,59vw 50.5vh 0 -0.04rem#fff,79.1vw 60.1vh 0 -0.34rem#fff,77.5vw 45.1vh 0 -0.23rem#fff,53vw 77.3vh 0 -0.4rem#fff,46.8vw 52.1vh 0 -0.44rem#fff,60.7vw 81vh 0 -0.17rem#fff,86.2vw 53.9vh 0 -0.01rem#fff,85.8vw 79.2vh 0 -0.39rem#fff; - animation-duration: 30s; } - -.layer3.a { - animation-delay: -15s; } - -@keyframes fall { - 100% { - transform: translateY(200vh); } } -@keyframes gradientBG { - 0% { - transform: translate(-10%, -10%); } - 50% { - transform: translate(-60%, -60%); } - 100% { - transform: translate(-10%, -10%); } } -@keyframes sled { - 0% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 4% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 20% { - transform: translate(50vw, 10vh) rotate(20deg); } - 36% { - transform: translate(150vw, 40vh) rotate(40deg); } - 100% { - transform: translate(150vw, 40vh) rotate(40deg); } } -@keyframes train { - 0% { - transform: translateX(-80rem); } - 55% { - transform: translateX(-80rem); } - 85% { - transform: translateX(100vw); } - 100% { - transform: translateX(100vw); } } -@keyframes follow_train { - 0% { - transform: translateX(-80rem) scaleX(20) scaleY(8); } - 55% { - transform: translateX(-80rem) scaleX(20) scaleY(8); } - 85% { - transform: translateX(100vw) scaleX(20) scaleY(8); } - 100% { - transform: translateX(100vw) scaleX(20) scaleY(8); } } -@keyframes turn { - 100% { - transform: rotate(360deg); } } -@keyframes whobble { - 100% { - transform: translateY(0.5vh); } } -@keyframes snowman { - 0% { - transform: rotate(0); } - 20% { - transform: rotate(0); } - 30% { - transform: rotate(80deg); } - 54% { - transform: rotate(80deg); } - 68% { - transform: rotate(0); } - 100% { - transform: rotate(0); } } -@keyframes snowman_head { - 0% { - transform: rotate(-3deg); } - 50% { - transform: rotate(3deg); } - 100% { - transform: rotate(-3deg); } } -@keyframes merry_christmas { - 0% { - opacity: 0.8; } - 50% { - opacity: 0.6; } - 100% { - opacity: 0.8; } } - -/*# sourceMappingURL=kerstmis.css.map */ diff --git a/app/static/css/themes/highPerformance/kerstmis.css.map b/app/static/css/themes/highPerformance/kerstmis.css.map deleted file mode 100644 index 6fb0d4b..0000000 --- a/app/static/css/themes/highPerformance/kerstmis.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ -"version": 3, -"mappings": "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", -"sources": ["kerstmis.scss"], -"names": [], -"file": "kerstmis.css" -} \ No newline at end of file diff --git a/app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc b/app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/kerstmis.scssc deleted file mode 100644 index 80cd6645d73044f67230bdc22607b27c95d9f1e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 151099 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
;ibgBX9cV;rlv)qkn)SO_G= z(f0*d?-U639}Ky)KHoSY!^oX@Hc3ZJ(5rb; zVe<-NF#R%+4ukaT^G+SG8O@nmlH%x30{R7Fp+WR_7@`rLlU64UOI||jO~YQXAq_K6 zXEiLLC(*F3@Kp`Nr$M=1VKfXAo`$_bYM4pN^L*l>!A{;=na20M()NzkuUA4FZnFZ) zdBhmjuONn7X!bBjzqWc++*J#n|4K=UqY-wyn%(mHw!WU$_bOjpuLAkF{)O_LRl5B- zyzw5!V6u=HB(AHyDq0+mGyq9)R0xP`6klb*^LglnGcyqR%O24>xPVkq~u zGaKCmF&JYKgLt3xs%VFbkp>_sj;4rrH`IZNkt_Npb4AjuxGUNr20Ij(?}sw+d~l@u zferZ~d>UND4;Vjz3C~ab0Ephj^iYL6bYrx_PmH?j8k`Q$1$^p74e2$Uc zdw9!2ZLZ6LZ<+4gwf9PF=i5Bg7$a!YY*dg~G;qAntD+7Z=6M`A-cJLETM_8y zrl-)`8GS$Gd%quoX58{Il=GFTFy}!G#+Jk&&VSvjqOBn#4M0*HeJsFvFCpa*`%M2Z zaLHB#Owv&kW;%$$rYsVJnEotd+Eh_j1X7aX==X_f7AO3G8S$Gi&Mq3nu9$Aj!k1JJ4%C3JSn)=@}tVtZ^fJ=)izu z0`Kg>C)Rmsk2~s^JdN$9jeExtp@L8ulXS<+l28+Pv9q%-FNql5efxo_!_xu&LBFq_w#NeCu9cl&yfBNKv2`tG(D+c`8f zdB;?;VJmIt4OaNp`Mv>KWVU0H?wDHGc7hm8eIy2{PlfSms;IV;k_4;Iq(0}ycHZbS z|3)B#*^Wu(*-j9HF)uNQ`7?}pQ$@9%lq3l7iFsx_ueTh;(F+)&R2yzP!>R3{Mr$Jt zELa3bnx9y|?z7b`HU z@Bal_ahr~PCg~Qs!}=b?V8MpOpf3MO#+#|4E|#Yx!A01iF8>M3K^(n?AxdfSF26ZF zwE-v6{CK0l4s--H!fw(~>@kv@LbRvbpeNs)>p}hS!#uH07YZ)Oy3nLO`Px?Yj0uvJ z+sHLEZ8aM^du1a=P2ZgS0eU@MeKXW&(l<$W(_f;iz4&Q0#`#Ix>sD`n5?W+_+9dP* zbP$8NDv3dQ`x(ZksiOMnl%zO%hV<5%>qcUnxA@Gz1;}82+9dP*bP$6vFENPuzhcar zDypAONrEe}iFxLy-)uR6IW$9*YQv3oPta&hm~$>{_HDT~>qR~0fm~~H>*dCpAmq0u zn>3eevRyS&5GH%GY{XdW+mb(7lYJWy#bj@i<2Dw@eHd|ktLtfr8e097?Q?6gKLsr^ zlQqdalMP}pt(6$0wU@Hd$W&2HHYF*JE@Kz6+YxpnCi~Mq^FIw_Fq1XOJd+J#Fy<(wLT_29j4ySKlzokJSVJ*!(o!yR3 z0{-#cvYSmSyJw8Zqw zB=htuh{3vAVvv4)r&mSQuau-XdT~g<-flUFqx%`6lo;2qQKw(QSS_>7m{qQKZb-TC zY3TQN8a={<*ZJ?1oo|wE3p&&J-JGgY&WrZF%L>nS|GS_qcBaZCb6%wgW3Zl(7}Wi* z@T$1kg173Ck`za;40ZoIEeCP5#t@~Zeq|-%XZrSrRK@7%}#2~((^{S{_BPmJn zCK2&%l+G+OqSnxPn%`iEQd79fUp_7lyNlhf-1Vx<^k;#VUs%5}u%%mk8c{5iXAHjp zoxwsMlk}Hv*|GWFkC6YOuN1!sEwLlyCYfgpK@8SE5`&atWRPZGeWr>#we5|4DM@e* z8jS|b7~E|`nX_fuA;b^*On(rXXO>`+&NRc85X4|iOAKPVz?e2wR7*%nf;-RxOy`{K z4d3tA_e(z8zXSxZSwVi4O?jBQgzU9Lcj# ze09CDjyJB%LQnfikE1=0AdD*tc%_Ofqj~8^mDD zOAKQEZH#$S#Vy=;%%>#5Rn){hb9f)N9KgZ{LzG^EJG@*Lmyh{mxbTGbB1} z-VaB-Q6T0^fZ~Mrw*n_#r)KCN@NZZ>w4=vw00rzt43l*B?H|^K9cnWe9fOa4-D?kd z_fO`aGbd%xotcIS@eC4%h~PSln!Yc2TbwAj5SykPKom zw<58~t$c$y0aHbdpG_f<28Zm(tvLO#n-ShSn8j=5Cl8a`Pw%U?+V{cT(#>*h7{0Ms zsa00s8jqHzK%3J(fbTte*OK;6($#5wzv-*dZvvTYsnI0ed&;b%55h+d;d61VMy(q7 zzHb=!3bHmR_qv#!j_=tfg3Mem8@-9EgS5CDn+T%cEYaPT8xvLX#zu}!1kooX`ZT9q zvxy*(^K&Tq{Q?MVqBt72D)5ae^BvIQAYT0fS#wSJtZAiPS-@8hg20}tWPlZ83t};2 zGwR{6$kl)=?s1=z1a~?R_bh_>nB@Qte>3MLM=&12Y)c~;6S;J^HxmdaKC%9o#a-vs zhfl+B{0TE0W5S!XeFEgchGUa-lbU4G#!gpt@p%pHMCvE4^z69%N$d%VU`^6F%CaHTFgo^4kw zVHF&2$6=c_$qBm=de8=apIW~fu(>-v4I1z%t-&EiovGJNYi{nj8HCDWSZd8E9VR@b z`xMk?N@tQTC`y!$#els{mp^TL%j(;wp%oV5m}K74U=V{HHINvjZ|`8*VXCO1O-fQ6 z{VeGl^R^rMEJWY$`uzVcP{RDJN#;$LgBZ--BnI*S%Zz_hMfJBSNpbWm0sd`hXFmJA z)y)g43bwrbN38#a+j6pNLO=fR$V`pkowq;w|Yz3JY! zI6rIEz6fK!#UcU!180!*)Sl`Q7H&xu$z1Qz4N$~YgVx2j#XDkPBx1zIWuuCpX?!c}l z2R2?_X{^=TvyH`Bc3Hj+njl!hpsAxj``m{7nR&WPf7Vq)j(^Xeg&Rs@zzc&?0Dsg~ zlhU=ZgYx(^qF5-;wS5kHh`BbCbW1@=aJH_~8^iEPujSw;yZZjv>WKAje+-Q=?`D#D zbHX47({hPHTE5J*+*DBwJS7P}8A@92yj!k;PmUi5M<}27S^qo|K?ZJ;c?KTDV600F zV*M$`x~ZZXcuEp{Ih0su2L3tA0em`?AxeGW2ENl8cmcOEgEQjH3O)}~{&Yh|ZJzGZ zsJm)NHEQ#;A8QSm%~(5^>k3{PFsP@Ef$(Xt-9I(6D@=F>{HM^T%z#bO1)-TKeSU1x z!GQnF>VP%iKf}gIi%l}mfP)xJizNnW@qcGJXR4?MoRSnrzYx;mKeZgh(a$hMDKxId zqi#|k)Zi}W@_(^@J!W%xd>Xp`FHHYq!t4LP0BNxPH^~l5I$gfeunj+A4lAAZ;%m7l z|3xcCs|a6&R@rRRB(JqAiptt%5QELOB?c+NpRjH-Rn*yLN>UvCX-ELg)r+? z%+tQp3amzU)rcFxO}NAM9z%_Io10xV;8x{L1F$m@<|44U*%kaA+C4DvH%oY9b1EAST*YFD~2AxUVI8jQjsOYNu-1SAK z`yP`dVD}||vU}6dLVe~rP4Y#;X^C4+&W-2%lJz^*bAAb0WuDU{^E_t|gLzJgL7wxT zt<+h4ri$u0QR&tuHu&ZByF0eP zgHI!hh4Kc`FM~XoDww2;Fp?mOeO7+w*qO@QscL&{v0AfJ9h~jIaJcl?NzivXw=ghQ zTTA@>E%^N#*bQ!!aHDgRzVGZl+12;gR@hcu{u(G_`@<&bmUTNE0SE%QZ=OR#{0L=w z1b{IzI)~@;>XlZqHtVzVsAFgIbvQ<)ANTA(lwJo7k`EHG*J-68!o5JfUT)lb+{n!Y znR3ca>G9HwN+)rTHb{skjqLMA53&o#K`dsChAD?d*7&2$c1#s@m&z0ZX>s&AvPL%} z-8Qz;cm}siCBW)bO{M8k#EV>VPT4+hTt^poSx3jq|UB zf9osZ-vUX@Xid_sp>$BfAduVM>@z@aZ~8nbVUUO$oDv!$_6XfklrRXyh6n=$L2dfs zjFcOugu&-MX=I-dD`60eDWRl=l<*r&2~Cx4M6S06Z3=-jI2;yG!qKsn*7?`MulQQ{ z6`+ajHJYSU9;M%cKqh1(7>&$jaIc?O}{IY*@YZjtUg%@okjh7U$6ciT5*>^^qHhw zSO5EDRmn{czRAw=QoUZe=hpmf^2F%cv7f4{HZeJit zR;Y%O>L}A0Jizj`^{+b&yCo>|wBLq!`=Tp&$EjK20=d}rPkb8Y)n79!T$u2dHNFP* z-7y}h;&-rE;qu?UIM8oaE0PoJ!@Cb0zU$D@qbM5VINkf{U$>oN*C@V@&5&A|q?_G_ z?I?)B)JkHIT78PCm8k-vPvcxqtx}TW=+hy!`kLh+j(&|HN^xzMF*{a-*5tk+G_3C75O^T}Zsu=F}y{Hqn3?e>3#cGz%X zl6k{L5QBBQ#Gr2fI_o4;MIA0ulH%x}sM{UmL*82?C9dy52l{V5%m0Rrlct-bo4bTH zJ&3_rmKelxKZ`_66*n+>nx2vb$FoQ(j^$o%=Kgn|>3@gjSqGS;TQvwX9mHTvOAKQA zGRCy2;T#2lUs}q>L_rM3 zyu={p_cG>96?Hn2k^~2{0?ZFBSIl{waFj4G6F#l-O`q#;Li>yylazbRS+0W^jBANO zTp#h8QT03}DUNOpaNXM(@^ATUe+&3zXUI)b?h0ht4q`C2B?htm5M$d^A$R2mgeggJ z^l*Uf{4W@*cPvDk`aJGU4xd*hX}7=@v~&%|Nx+985zILeBz2rqk=CA+;#%Z93Bio0 zCM>}rk#3v$67y4X804cl9P2Vc;*n*!BX0+Eh=FpV#3<_9$cUait{qm|l9Gk-XqPR? zh!KR8MvUp>BUSSw`J34mHAOsrNYYNwNdN)Du{T8K7+d&*h0${|`UW}N+)RyJd(&W; zzIiaDZ?9wehIKTXO9;VtQh&^ef%MJDhZOFW3>4+)9^e``w0otzn!XUK$B)H})7M(z z)zx|P#$oZ;LVxK7c%9Te4V}1oW6GC2p5PFgj3`YLLM1TmTysVxdWbWkEhNS?pfou= z(n!+ID})`80>cynVI2%9#D`elVI3{pAj0D4!>)gwLV$EgA>PA4J*jbph|_Bw&9R`< z)yf$-N0i*LjejWxZ!@p7D1~L|QjXOkIHTgvLXz{vJ5#*00SpMBy9awv9(Rr?eH?ML zhPN?B*4L`r+cEQAck949T1A1auhr{l?a{P4>3nA*s*b$wV7#Us)3uDJMZ32J+ciEr zA;U9J$P@;O>Dy^GoH5YO_vT-M-|IHPVZnT=y$}u)qao6BYq5|cTsWqo!cMiU?|! z57y}3#7rMga0t!Q6lg+d3Z`XLxA`ROGuhESXL(?2c@FM2SZgPzoyEdXG)hvn`T;q7 zjlk5%oj++XOg}sr(vLBwA6UnEYcHg}oeQnewhZHtW9IC3-e_uYZ4DcS z0>c>hV2JTs8RJ+-TW?JW0m9-a4lv$viA0$_M%y#oLk^!mni{ziNDYQ@@4*oF4>Rtu zj*C>hZnuQR(IWxwdx>IpWSEB>5yfEIg&*OrS6~?P9t<%*&zQ$LY7~Q|FhPo=g#h!N z7Y-&T(onwpfr1sMrIj_`SycKfs8{#Rg_1Uwj$z^j=Au#W2UuoM<-bsfnn<5!H|0VJnKoUqt1G<6l%xOdr3VU`yGAbbl5vwnqeMtgm1)jo^MoO z81o(sG5-<9Jl0WtBbK6X{Ahsr&c0FM{;~}BkRyB}rt^HG0>ilXV2JzAFz&IA>Km~X zed99$?t|;;bmCe6Ecnr((%s@FsVR46IP-Dv{WA-dB{U!~*vm7bgB){Cp5iG?i#w}I z_m%E9)1{uC1*5f;J^)9ylcmK6pB^YZ1lKJ+46fi2`1d$$vYj}#Yk2q6(Fyn`huE7v zVyA4FnS9JV`9iecSl>sXwNYs8V%ORoQxmsMPUW<=-)pVJTT`yY(nRG>VVN2`tMIOh zcbG6dhAEO~n(D!kras4QBPLC1dml+Dp2d1D)p1U0q+GAAl=Y)9*DRUaM&K2<+wU$+ z9&QyXV3z3$Kgw5|C$W@kR!$~Oy`9z3Jhc4gCX`GWb9)db^O9o9KRk4us@3Lwstrn zcK|CaHkvDisl+Kjs8^VQh1X`IU2azjlaxEwSZhP2fUnq<5f|j(xlyY#z-JOvJdm$VbbtmNE$6B4Xoo1wtBXMr9fC5wFA<)gh`|GIZJ)3_1cUuAcw!!6=7Ol!;#r) zHkDEzZZ!%YW5V!YNEokV!oWIi{m&Bymcq*farCNyFfL%i(67B2o`-93%GKoC<5DfI z%dh}B{5XAtY4?U(ctBNPm?S(HlEmwoB(RP1u1A8BE7pr;~6v5#W*1 zVRJk&x;`U7$T6=_kzHZ>F7h(^0cs7)9icWgc2J4JE*aLbB2A$5i9wa&I@`J7{FEIA8jyi+JQk+3o0_^9ltL-uYQDG`wQG>}d zPLn$pFeI7NOfpzUH47|7vp7SNVIe2PU=(tGl8swl zY{o;*iE$X0s`c5qwRXEvFU~Jl;A;X4g_jjXC>ppj$}Ydz1FA4mC3|VxIUu@GaPre8 zAmumi45uw&g&Wg5cam!B{K`AqYQt9GDC^4%YP!eg=n4hO8M*>D0d+~0yL!Ppx`l0+ z`4arFq9}RMG!%(w8qAZCj1%@fU2SbYgZl?HH$8C9fb1f`|i6wm2Hl+9iqAF;Gv8T=5UAL-7-1 zKvnhUWA<7ur)DAbKiHl6W3}GZA0J_h5co2@TxCr3K~o<@AHfg zPqVqpyKuZ!Z=6{v*Tr&?@6j@cV=f3i1%_7YVUY<|IPD@+@_2$nXr9?Z9bvYZcB`bO zbHpN3PH22E_{LfEJQAg~KgbcGF{blEV+DpOg$F}QaeyfW)=@)aEXC0HASp$+^P-6` z_qSxYha534!ZbCfthg#LjC&7;xW9*Sk9E{}5tib-=opdXxZl7k(~*n}AV;h+VLES> zNr7Q9@L)&=FJdylI_fGDmf|YY$$$(xo|#p5S8vU*4>`gBFr8-r3Jhc4gCX{7jD4)5 z8UU7}0jvbr@377~G&VUEHh?(8J>-aGR!mcKiUBAvjC&7;xPKYr9_y&ftXPW6tS={W zoB`y`jIT-^d13ls{&ADrGE#vYF)POO%`||AM@j{TNyUR9sl0|s1?#9IC6?ky`PzU~ zE~JImu?ActnQjGU-oxIGS4-LO1Acx;W7-3p|Uo^XXq`)wFcrYZ7 zw=sEO9d%<0OL1fBr$`=bl>i1&iX3iWpx)rhBL~=+N+XBmN;$c{CpT=^o_PdD`J+9= z48Vhp8Is2n976MA2B;%q2249SBryZKPjv&s#@!@I8#q9Y7&b7SH*6>{OeZ`T(uq&7 z?!!9juz{sGYilXV2Jy#Fz&IA8Zcog226iPH8`2>acX8V6kI0i1mQL z(vQ_BaIAAYIO?2RS?6FKHG08Pj9%hE=j6q>yLi-LPf&I`R{cOm+K?mSTukTf{wOd^ zG9C;`=3yootfR)cSc-A(BP1CX*Fm5|aow-5A;JrQ!g1YPW8rLYfjhGtL~$KG0+HB5 z8;k3b#}gbv^Wr+FBjP$t)2N1n?Bmgxl6 zQR6x+#klS%(g`=j>2clAVeQn>BN^r)M+A46cH1!F5lw+%%zH4z{0}nbv5p$tVJQZ8 zKNMiT(_(;n6@I%;T(r5M_Nl*n;*e@;T%7i6RXIU=;hbY5tyz%XfeFeHu7Flk^NHMGT23~iqY zNMpmH?F%!KfE*FpVmdFhRbZGTJQ$M1UolBw9W}JYQVeaM4M^hK655)$KnZOh%Lo#3 zL}-iYu0mS{i-op`)op02z_HGG+>pANB4z5FO&8M6bc9W+p)HnTXxj(Z7}@t2?cH%E zh@t@Q3D)CYq{9QaG4&L~N~PI6J4^4i2V=YL&hDJ-?(hOu>;3QoKJFb}fY>uRQ*=Ry z8weD;Yf~OgfEOg~a$@p$fw+*okTRlI7-;BhK}1U^($SssC-*2{|I{#B^TR zslYHz_Fzbp_cKk#I%?R7r5JY3kS04B=wWAYIq}6Az9C0MoS1fFVL0McU>M&X4Do%G z@r`xVh!aaO;=DV+cc++ZK)JQ#B^l-+M}%CM&I`8{7{pkRx8r z!?ZgG6t)8eh6%%iAz^$E69(2%U(Lf(d^PW-0by(`%s9|_15FIz9P1wsj{4{ItbeeM8fjoDMjCGj^iOvI@xatf`ZkH& z37yM`7IH*1jA{4zps<=MFiZ>{42j`qnHaE+8VzG9M#Jw6h~b>flIAngfE+PP!gSs& zNr7R~@L)(9zrv(}b<|lBmf|ewLjh^zt*l<>86Lcoo_lA-LPj`{BNkUNJw=uiRuu(? z3CDvW;rtF04%Sf@SFscqS3gCuh0o{xnh5#?fbbd?ahW7(qg==lQ7)$QqFe=r>4XPEI`K8ueOO10 za^PxF}aWBMj3jdhdFuHD9h(9t)lizBD~dyQy?<9L;YjJ^$FQEmP(yAM=^e zsG5-zHOt86Lpgk~)4SNVJ2rlPn+Z&^GIo%sZCs=ytz7HI}}-I0S*b&C1&oyk~$S@3Rt)E zvt}?>0u=@C29K7apvB<1cLfy)UsJLWVb86=F)Kxm9UNKd^W2x+jVYLG>gRM13RYkk{~iqS{{Z73>!=eGEX9e*g8}|K z?1Bs^=b=w!c!wOZ2ZHJC)FI)%S6~?L9t`pRU5t0EqwaxVDei%k1H9*kG>eTIT(dcg zgKl9zoQkYf>y>h|(|&O+BOJ&PAq}SULK+2z3CDvW;WU|Wu#RdNSc-0Obw)@BJ*R-BaJN_-y^?rm;T*&_ z6wW=%;sG!2;o;oQG@LurEU&Is!e8si#B)26c#b~QI5DI8^*vfd5cHOMz^6anqyj{V@M- zibL#fidIHskh8Pu7V0BRyOk~z$E872PtSG;niM=1@gOa30-wf|%80MPv2OI>s2jh) zx)JNBjvY(UvHy9f8|mF(oONVe`&H{1?%J82f*dj2VLI!?z} zQk2R+l2n+>2M-dw$5l3rtn@?retvZD_@7G=xY}L$56C%9f1~SEPgK4=Rey%?3 zaEAKP4mXe^h8s-h4L1r5(?}17H1az4X_yG>sKX7G;&5|4t<-io+zgLRjPJM8Ou7F0 zWJUmxBgPv{I~xdx=L!rHfCobYILHKmb=2_&OL4q86cE5US${p7kp|?5^;b+g_Z^mo z0>h-?!H_hLF==2Ob^R4fasBn)fHb;Wl<#n#;Zqq&K#o|K$F#J{?9nv^hDpMMAxWHM zlE6An1-Ge?b){n0*89bTuoan;7@b) z!Hp2s?JXRD>kMux7541Ik#4X!)T-9tYHN5qdlMUizb7MK$k|zCOkkQ_rA}vKU_hbK z`y$4XH_-6WdnlQ(Aw_nqh6!4DtRBRm$d1!5>tURRZF4(LCy&Ee2|tp**%fyv5+f$2 zog+0~>Rg>Gc{$0>j+l@mModiSjhG4y>pc&KRPevD4#PU?h>4{*V*U(MK|4w9af0?A zGWj9oiUZ~c1N?Vb%Nv}gMQIr=d~b$%$PtTq zn9e(2qQEfbJs4vCw;A(TM_tUrQe4dYM1c8Dhig>s|6_)G$PuS&Fr9b4M1f)4doaZP zA2aT;j(WNVOYwBg=L6h#JY56V$%I42|0}~jW8Z@z_Wzc#k9Abd z$5Pb%uLRgXC!yjiGSYw?5h`LjFH}@um^3^XlE$}~G_Z~uDq<;yikqm8n>lPaRD5Md z5|AT8MNH>~iV6&qga<>C*bc#;9gMJ!8Y*HbhKf4^k~puSB8CJ?sQ9Xk1R+O+ikR*y zR8+87sEAnIhKdRt>lF`gH|FMQ_$`BU$E93@ zk6_m!o`h@s;p=CeKZWw@jPM~xEJ|Ve2*uXnIiCW<1m(eyppGy>VI6f*3QKWO>Q)jI zi-;lWqpc!+gCRv&WQu@w)ZraVad=-MMR4qQ z9Nu;Qe<;I0k+CV2J-G8UI*E9pAAO$M>_uKQjc-4>E)oGEh%%xFKv; zS7g;$UTAgnM|v;@h?ebKFL@ly0DdHYv&H~L!Wb|uW6ti4VM;r)@EQ`KH3rBL#(?QO zV^Cn2GI%hg3~yomhILe9z*01Zw~{h+YYZy?ug&leIl>q)oo5UR4CCK}A^zXb_{Tb` zF<>bg!v~0eW(=SoWDKumpq}1vV@P+W(_M<>>yQ4T2e?~#3#VN4cwG;Mz!p95aleHj zTy9Iq0qf|l377(=8fb9o89OEK)w!@#7ip zAxA7UU|PDp>|9fUVcdH##QoP8_gF_=XuwijX!tsD&&&^0hRp972I{GjZhpxJ64z;d zZ`_#q;p1WRqwh6#*Mw?*$>U&n@FV$~9qOP+m>;I)kh3oH+pU=2-U4ipO@_XG_MfTu ztQA6zutH2vR4c?%w89%`@wF=})K2dGM22_B5jKcv8HZLjQs-F{gdAalnBJFTf(i^%Ll1`3 zu*x(B>!>D(rD%drkQ#Png2R*Qfv~q^*oPcpg_xE-lC?qwhOzI#5c^Lv_OXs?g;!5tPmd$TVX;D*iCm$s8*Ofp5PFgXN6ElSRtlm zpRa2qycVr+avWZ}@=4tFId-VPFh%rWND<%7bO!6Fc8H~D zhwmXp?9vXW#}9{hKmKcmeaI1Zh-uj;Svyo<82cU!vHz=#eXOI}A(o;Y{u;5*>=1N^ z?C?zt)YB>54rh9?!*^`V4)O7@9VX;}<#gACYKO_=2@auob_jKZ9b#Jc`8l-1gCRTo zS?WG(hma%e5Yu^fsK78q^k7I4|BmSl)=}*cOVJMho)oc5J3KIcAZ&;4%&-qR!VWPl z`y^|J3Jhc4gCX|&U?FT zGv%d59S)JM%qKsEJ*p>2N8Pjd0FdyW9*h#=eY=E`JdQZpQJAfQ#;%)mHx8Or8+es4 z(4>)JLV;(bkSUB5(^radNqp#G1GlXFTt*uqN1TSiG-0(3=@C{LjpL;1b}taby6(F zb<(>70_e17q@DNrv3~~P$;~wj%tK?Xk+_w_ozVnum`cc{U zW%!32(fgQ|E2ddztiUk-Js9Hu3C2IxQF|XtvG-2}_&+B{Lf)T|2IPn%A(+lP5~9E` zX?QRsjqhR7z&dV0(mNW4rBFMLUK)_bhL41NAR`IL5l2EWop&Tefnk#HU`P`GiAe(M zI0xiO0!v|CHjaKIAc?#M{f!LKFr9b!K!IU`@?c0%Z()MMI%+V7r5Mb; zl?26R6)?zBG;xfMv;&?C9a$}SFl)^idgpwEECv< z$9DyeDX0fW3i^9Ym#~g{j0j7Cz&QG!q@XUq>97qopd5JorHniwM@%&^owoq4z%brD z7~=hljCZV~PBpL;ry74ryffnjttI39B?jtgGdIp{Y^ovV7pi#%<`*C8!9dykB6%E4 z6MiIrvjz%9!ay-C4{l}ag&bj{n3f8WjX)I`#=HkZ z%wNx#$2zKwVkz3_4a7XNQBYj6(SK()>M1n0(VLl#+QS-bS-@rq^R>$Zna!(!`F><$ z=8KPq*X-yJM|Vv?*pb?cSq^~Nv>n2e$H6yzq%U28$ncek8oF!Jb*pLeTCd4-!qs(x ztG!+m#^V90$=|HsgCgPgFg-@Lo&+Xvd6Yd9nHR~f<7mo9NmH#8gB%gGVmj|=iUPxI z&VwPFJLNhj!a6P>^P+n!#h|rDHs@s0dC_BRa(ptp2Knn50YHwJ_F~%2Il@7a0>cF0 z!H@u6$^?LQ)M+o4;i-=-RtXix$8fU^joB`*7HJ+@VuCw z5Hw|@9R-G&o(Dsw_l)bK2x9X#*w%=kfNwfz$r_8~{OUQFk0ekm}FeGi7%|7XTN)=^zAmZIzZ z7h<2eUa%c4M*8`sGJ$GEGu9tCTTyK)}TrXq_*Nf>5xZZW2Li-fytM$B)BRnsr^G=~DFwF8i z7_z)u;DU6~wCZ^+VR3YX?qJ=x=lyg>0FWa*FQ)T6uL8pa;K7gp9%KT*I;!WzQuMqJ z1q9H+^TKz`ro$2c?`F7%9N~B|ofq>eFpPT-hPW>??y-*Qc(D{6?;LT@94}Z7Io@#w z>RA*x-r|+V%dJ+ic%oUU6pJq?H>+iM&GLc9LS>|M1Kcj$!byB_Fs?kg+H8~#43uEH zc@X{{+qDUo9Fn^Oj-=nb{tPv2)fjSiRtKG0V|tik7g(JxZjG1L%FTt!!bEX6UaB?b z%C!ma9uNhW$yDMtN-s(2Pa@*keA1uEkPbP5bW97Bk(JFx&#Y?!p9Bnj>s*Dx~;?w0Oe2WLZb~JDTv}Li`Sg|6%XRy={ z`9@KW!R0P=bMj~-tsy-K_kEVz)kb}|I1)EZ zqP_rTzBF7~?&@#xnh>fr&mnG_7sYG!1$h5?zR|2K%+|{*6*5~h(*8k4wvZ!SI;P#) zX?m-WqZ?LR61wST$05T`V+HO1mXokokhlfx=;;4_PPVJf$6Tl*6pEOeLW)F3XggR6 z7Q3Gnv995risYT*L@)Nkn;|LHaBq=!59J^frk}OY<+;mwIBf9-(c*o@!FF|}(vlq# zM<4c?mX8^exvw~|3JT~y`ELKo8%2ZWNn$Z^*P9F2U(#PI^4sHa0$Hd5%cFb1YjqQ?Hbsu@R^d8%pPlmI+o;v`xy|HDk21UVv3!gMB1 zI_Kk>LI`v8NJv-Vk%Gm-BgD!HkNk1%OlDk5azLk)23d534azVlH5d169Gzt55_p1{ z3xDcf|Eb=BA_r+Fu}A_7iZC4virlktlp*K*2Su)VK{^YHko2yCA_a>DMTm9of+D3s z78GHFGQtshD7e!fL_Wc3~Ql~ z$U%taSx6+CcOen29QGO#B>)%_(MHxEWkMpz5g`$#&wogy5W+$tB&4g5NWo$u5n`RY zkVt8eg+$n3FeGx%#?e19a|t}b%!NPotp8MRA(4Z$nu#Q^kO#-z77`&FTO|%?+B`*Iur` z?iaQ=8aFHD+U&UjyCiPGekX2v!X*jKI#2)->pxy;Zw7*w%dO>?ZaNA~8vadp#als0 zja4JR*3+B#7N_N2ZsXop1<90a1H~cO->$7ehowTY)m~t7i^T`lR^}?r!O~ULYU%QL zXYsp*Fw z!8>zjX}d^YRN4`5E$xg)N|ym|=~gqeTHI1=CkkR=z`o?87xPCA)f2`-IvfXqBOm^8 zkWIrS*!|ryWR8QRWu-y)6ZrUJIBzHUfShfxwNJ!gTJT|rDP7ShT{%#?N|X5Ub`v@q zD!`$Gy|^A}Kz*YsdnZa`6Qyw>J_lgMhYvIHNiZkAWcr&CUy_aDOMU{Cf07X&xI*G_7$__@dSs^yyK}*M;uSZv^!#zycqz_ z&c2MbW3B;*+L~j{@f4@Jif?{t-9Zb9PfMNAlU>Nfr3^D&H#yr;9YE|3+tO=IljXR$XFu#*NtUG4H&#)W@7VY<8 zr4;@uBL&D2H_c$0npJLPP+*u8JQ$L~7nl^Vj(XD!mcr}IarEazj&lN6IVr#?I0)Ou z7T4hYc2?b62N9-krrruGh62Mx;=zzezRE;`b=*Bao>gEe z5Ee)O*jXev#W2Dcn{TYu+hLJxt=1Q-Fp)@9Nb1R#GD3kIArwrzwb`&x6c{EH4~B&D z+^d~e!aAx@uoQ*z9qw8n7dpU*O2^i}pGn#qX?egfJYFlGtu&L4vfaI@lx?;L9X7yG8;z;(j_z=UvdH zz%T{yU`PS>G6ldoqr{+R6AYw`fnnTxFvR^4 z#y!?iU)sS^d|mR^5cjZ30aH}x0O-8+z+7!D$@flMFZRRjzHaAt%j%Q(v^{bPg=r3` z=ig-H1UWma?7QZeX7BOo7Y8X=(6Lqn5z9p<_7HH`^(b&m_8uI`{>4o8SVxsTmZIjp zBq00IxyF-Yt>yAUI{7fcO7Z&88T@0ojL?7&*@Da74lk_CRp9%!l?iwSVx_v!DA_Y+ ziATZ>)#N91!QW=O0CL2QX_%H>0JaXxPvu2WjR{ypIM*KuD~!scrYZ0S296h9VdHF5LgO?#nG!s5bOmp7=~!1y^?`?!xJBA zN79jYyo@r_##(q8_pW~Peu_8N{=FG%ZQ14o155(5&4SU*jnd_tOIN^pt)(n=CFWgK zw|HPuFuK?wIC(t5AvA9YhB_R-o!fYT3SyC=g zmeOrcZz|mm|K2fCx^u#;w<=gH7DFs{V<2D|jSY)kfn#F#;7IIS3T_<4I;z;Q6xFVu z&TKig3&mok#`eh;A6}9Ox==Ot>B#3HM4ST&$ypKv;?)&{YB9b{_&w?GKG_|C|vq zcF1!H^*KF+pG*CwtGhu@pm~2@(Vgfx!9G`1V`OV|arCAK%gtXli{S z5UJQ1J#nC=vr7rk#2A7y=E9O-_Y$9t`Qo<4i}ej&r1*j$kRqKragE2*`>eD6{e4XASVt8*mZI9d zKOpw*VxYutU<^bqq%R{@$PqCRrnMO8h1X|dAO(@dK#1tZ;m$FT0>^~w!I5x3&V-9~ z)EEd$F$VgrfN;Byfu<)~=*Q&*FUp7*azqS->AV<7fnkF1U`P;u!~}tLoa{a0#!`%d zK1YIJF%UR^8sC}>)EgA|_?E^%)9Z_YNIjn$1($&^yZ0Cuh0#z0Uc20lzX z^Xxqa3VulMJ2E-~IU)wabY2Xkz%U*0U`R)vbB&vgVIAj4JsrVPjDeo(RMu_Eft*N3 z{x{PRPku&6id*4?%a&uiw#BC^XBXi}Xr+ahj=+oOw8u?yzH+p5)k(N*#oP^(oPoJI z6SwvonX$`=Fzp|?VM})-Z8%rkg5~YxZW=stK)WcTSO^REmB-Pjy}gub-*2&TD?OKB zcT%S4qynfHP?1W+j$BCBZYOX|%QtP5*}HiTZ_g!M!43xv8QBUH!{20M@_LwXZyCv6*r#*m*7uFj%5)ZK4eGl>Yv*S> z=(~c)^c`vGR^Jskrtcmc>HD8C)xmNlD>a{fqIJSM^A(Fm{lOi z5z*5HiRO0^Jq@&Kl?4_z!RfU8xanfgurR&Oxaoz%rN>S}h(r;4SMig*#|+{p|K^Lq z8T#lK#6g#2WCS_F$S~~=FS59#r)SZ~*wvV0Zs^-0=NAL}?LlarPIkx@>2xu?p;L)} z6uOy#Al4ociy__A2}8|B+eNT2*oYFkv%vmZn_Xgk&5LWUP;+ zn?0<90?YW2$4f6Noy02wyOc^6A{-SeaLjEWcMgu+#uU2+0_&)51543uOz(1>k=p=s zBe(I7%x!pP$cM=-`?Xp3Wu7f#`u|_Hd^z!J{T<{8TgG(ImV0`(M_X3fVz!KQc4f;7 z7PDo_?K6)a}Uh~+HDu6{UMRv>(-WFf+~tiUl__9!A-ekrqMtfSg8 zmZB}cEM&`IZe+_x7^r84+?M;N)CG+zJ!8i7I%jxY4a{sg9HP|tpZ6;2<}hSY**g_u6iR@nFBPMJJ2gfDF}JG_QiwRQ+O!VWRb zq~zIQmw~O)4x9a9JJNO(J5;ck!XcJigYQ1DWgKPfa6h+0g${Nj6w=`|wL`G3VBO^G z5V7RQD(z5#@Wqma2-~3o$L!Ffi0p94?^V?f5drORn1yQ;*@C5z9sVw}L(hV^9d=p( z+U*%4rq{UuwBF&cYeT%2c(sNIIl>SzyLXR*V)T5rB?Vv{r9@8VFrCU8x;FunHaHL1?WnGSSR6W8{)T8%> z^ay&I^ysw=)YAZ=M~75B+UMyJrq?+a=&VO)*L8mMb0a-wg$g+$`k6^|p^NBe`(mS3Yn++wDF`~`sT`))83f_H z2ToCSc0RoaLx(fMf*di3VOnZUdT^+xXFCjH3Lev7q$M+mG3gAo=HZ?}HoP;pY}fhN zw+gpR(Z`pR#>d=305-l)L}E%*r(j+0VND1u5KM-V@S(}AX{5^-*?b5hW87y`+CJp9 zeOR=;K0YQrtfIg&9qi_03ORnCW+B1>t^&ur64cmPb#UaBUU02Pwd$1+0lm@-nc9LaieeZv9>OYEOc4-^NgS|3<7O`bfYSJ0H*8?z^5YrGz^P!dBM68k9Yu(d z9s&TRZT9UAZ2OQHwAaT6Ti``3=_q6XppfJDX%-@E+zK2sZjT}|?yoXC#5$^RV<{T< zKQdJ#;|B91<9wx|iLN+*v{o)_ptiYONb`gmq)OE9+LUm?j_= z6Ztu`Zl!T%-Pm|n)~#SM>qe~eV%vSP{#ZsXkRvYC#WZ_S zRu2ypET(LTCC)A(ppEZA?xx4A zvO$hew&!=PY{O@k8*_8D3Ojt>rM^Aj=^Lhd)i<{{6AXD4;o5S3>83o&4c~d6Nps-f z^Me`bK#mx*Fx}OdrC>3YL#)i0rR>isa7^VqI8wPcG3~%Qs>)$0s@$7HDhItpD)+q% z)ayN8_lpgCiyV6w@cHqbezu zqLO|(q@>WZq@?d-pk9yj5WB;1+!uO!gXwk7pU;)vJVu;ZJAxdcH<%9UO;68u&>IDh z=?&7-t==ebOm93m(wl!`U5s^9y}?q{n|}`J4fHJO&F2`X*W*HOrqyHIFY@#T)8|ZY z*ldg+UGc)H!9zTnI!XLl?SUK-O<~&IaM9u9qk_eHAF*U)rh5$qj`h9=N4U{y*CLFCqSH??aC0eN1=N`wAB8 zeZ=av_Z2wS`yL$i{#~r2u#VdMSc<)WG}QahKh*ns7^v58qW2FR(heSdm)HB4K4-nZ zzF4D7oY{Vd95H5KIyh$Z^lXPQL&0NugS2!zW+-q>Z#+2Cn>y=atfT4;mZIJ?LV5!| zOM3G#1NC~G>rJOw_`Ih$nC|tQNoE$lKE+ue)~w<{j!+y-2NkEMXFDj4g2xmGY3WvR z6gZ|h9vmso>scRT9aV9#6cy(UA;p27CB=D)fqFge&!mpiW42QuN6e%a6BX)WrD%IP zlbT(wl=}e{d&);;4-O}v8-Z3z3qaK*PS2OZ~9HF$BmZMy{+uYN$9h6qV zV@iv(bUR8aa7<}EI8xeAF#WUBQ%b{(#=IpwJkrq7wP zV-a$<%2OlutZ_k(2$3-DJ_XPrKvu9==OdO>L_I)O;8^E-aMbz#!1@X6sGX0c*!f=# zbv|?tb^h-&P_Nr~=XVR#_-y4MB3{GqN}9cU1jRtF$QI1o(BeoGxlPtSI6APOGS zA*7{S2cp0+9rEBvhpxE6?PFsdRfn(?b?8d=G7?R)pp!|5zQJ_J>wJIITcXEor$CMv z^}ajNrY=Uk3*a-)&9k%f%gri$TDzQF7i!kBHpADHyI4nTdwPrM4g+6LAJkmSFbp~3 zHfBt_>r}&waS9CUaSw)i{8rZESZ9>h|Gdiuu@tYxjYB;S;-Ma&V4$AZxYy_~WSsGY zkLeCWMy~J=;Le4yLH8}!Cy8XMZIB~`kLf(&D=9t;WpMNCduM-@JnqVP|Kgb(5& z;Xj{&dSc_k@8q(d@}!UH4lX-a`sUo}3EX6J(tnz0w$g_jA$?5eNne3s()VCU`fE&3 zSVxsUmZJ1eholeUA?YtNP)}^Wvun{~RsfJAoZU;4en_2NdMhVSx{IBrfLwDbG-(7bWuDRx#!88g2M8dwDgjSg6zsjkSeBwKYC?>{Q{Ya;;$6YZg|UjkyYZ z5WTRFptmc9)0O6213iU-HW#%}rO+fNp5Yu1;c>2~48AAS2RkU2QGXW!u9;J!Vz>e6z11?Y!#u?Ykh zo*o?7x984s^OVU2*5I>gEhroq8(X-$Sw1^a+9Wd=3Jb38Nq}J`VwF>1F1`CCk!oPEkg|kl&4ipN@ z6~j)kV6NDO`h~(`quw4{EU#2+XN!eL;F8o+<=Wl{SK+g)<-Nx%ON~nMxA5q(y?2!B z3*}}R{#&cgHLH7XYr<#Y_O{@D-LY1sSzRpI*5VX&zG7q*Y5|&VHRp?kwPx+c8(MIi zRCRuzsn^&wl>$OEri=LCAOvUxpp1;$!H1tJbAG&17EWO$rln8FBYs0 zdrE_9PRLTPc1dg!(*UwOO;|F`PT24 zy|MSkF}z-3@9v{B(-YGZdkgU6(Cvrs0;Mpz4Sx*%#pMP#1mL1;yu$9=4o$*82Jq_X0nB~Z#ln1fwb}+-eG2L)ZoqJMq*gsrPIyZR8mm|Nk|2ZM|(HSNLs#8qN<`ljNlZZTQulUPIY-~H&&}c4jJ>?zT6dyKO&L~qzSd5H<(5U z=?{4h`Bj=SF+G#1D+<)$dR8L8AagiGZ#jTmj9JYdRd#rqun!hSwcBlACKk3p$RFW%gkq)vuSIPPE|Im zd|DQMMAuBxt_nw?!vEMG{9|}k#gD)tsGj*)HG2S;Upsqtk?g?pX*5%Gk$dN!kM#|b zWAa;aY=>~`o>wCw2J4b=my3xJAXbq{Fd8H6XM_(E&k#@Vb2DR7g*mX=PC9_mCj4jA zCyRAyqw{iikEYz*7IU)lrtunJ+yrM=6*7bbFRg=Z3Q?I14gGDu0*viujR0y5oE*T5 zI8!spet-&W;oZErf43Z1$I_s$AYUCMMlE0z_5JagGQ(bQnPvO8(Om%sgMr_P0CLnowIH z2vMS=!n(Xn9ZN<}Li31iKR?W@Qp=K6NO?NAV9-l_!lmWy!luS?hVISR5@tV9&`T*{2RZ-K4@f*aYQx~bv#pI0A0QUxqm zaqSSAS{MNgqM|4B$@z!(S-;=M5KZc(I;k5{kb9}qdXn|uEw@0yO|jVvusdI&3YnA8 z0t9eH;sF&7_eK5y)v;cm|GFd2_}vj-LzM||L6qcLl`}c1S_yuoGwQc_p5yuK8g6R8 zqiV`=8!_5ug~EdXX~!V(?p4jREaqq@u{dJa`JYw@0N<}sfdct)Vxoi_Is!SfjTmLU z99AZ(hVT96>h3`!(){77(cwd0$b zpO)uVE25DeSNM6V<5(iaJ2fmj5j{;4i7l$*3*k+N@?nyZs#FWRJrS~iQV||F%{&cd zh}Da=lq-`j%lymlkm-L+K$r8j4s=Atbwr#(aJrlAOY%L$j?=-}C5UDEf-R5!&mCBZ zNBUT3XO7$3>piABg&T25a}1JNtC8z!rmCbOs>CJ;z8%O-C?*>n7(s=5v_ae`;Dj&s{8T*2LuCda4S!jI8*4|Uc02Hx-uI%?5@lW@dK1G$~} zu^NfEQa$|tWC)RC8FEzZYg@UeOP}liO89)}$-ZKvI6Alm@AB#HtcIYIu?I{t&;fV% zyz@=I*g1%asX>O5Zwev4zi17vo`caLs$!&h>AU2YvkegHs zAE+i-#S$OkVd_5w$@F36wt?*F@v9AbOT`ZDL?l9$o0FzNn^YA6{Cvy$C65mNDkxvU z)z@M#v!xlAr`PerGS6?P*9Bs@d@r$^aofs2MI`FQwm$K7rAdsQlz)gDVT7G-U0yaZ zqQe1iNM4_KY$M6DBstz%;b!6{U2bFItXZqFD*8<6%s{-6cnVXd)s2 z(e*l<^dvA{0~Jju=ksl~4vRWA&!a@3vIZ-9m({D4G)H}K$P@tBpV4v*T# zb?n;UjXZcmDaZ-l*L+`2A7(e)m{@(WU!S#wBu>TAw5Y$!L%(1DJ<49Lygnr!3NMIO z!U|_gR!ywYhm0d`eb*Wl?`x|_rdV6X8W=VKV@I8wI@xlZdro562e4$NV%Lo;qU&8> z@ufD_w(cMvSv_i87@hd~!Y?$)wsps`ZOmfXpUY%&cJ>yZseESqi5>K<`MEHQ?Pg^X zvs+^0_hv~qBY@kqJw+4gkNL%*te9_BR7mtL{tCBp|A3Qc_}_48=`Qu$H<>@cY?ywJ zcW-_%=ZnRHx@NRgN=v0p@P7DG87-Cl2}}K2EQrB>^LSe0>sc3qp>y=lV?yn`!`Pjt zEl92hL{_!d>41`4f>|Y7G568YA#G^6&`7G9DC46oWIA@<2~EWnDpPtzbo~k%oY+H; z7W=hq_}WlbABHB!7I&3w*4WiShjrp*gP;P{Z@#72NULgv!r_2UXdKo}1hjGsit7_@ zGa?wE(P-E6H{s8}L2sYxc+B?}4eV`SAzHY#W7 zKAu@Cmgx~J)4sp@5iAqx?I=04A4$XrD|@avT`|)?=c74nMKe2sX4dmpKZYj7eC)+D!g(yV4uh#)OAP>eZwO4)L-6_^RL8vO(jO`eo?hc6N5=+Z zXSy5Vj|_%I92*^ihPU;I)0W;*0Q?TbmgW?2?H^nGnYrn)g}En2uVHd6F@AxOP>omR zwDXhSPSXwAX?$1ENgO*qIb@)%+*rD8!bO$JPwZFG4&IzN63@_UrSKDX%(#w(2uK6k zfs)6Rks_}oE-!R4>qtyB3N?Lh*>fna6*s3-aa6RPp8J|b%y!N0~= zwd}Wm@dx1-#?P$Ppoukf0uSl;N=et-FpcOpb&Bbs&rq3EgN{hfgB1#{-okSDgc*wO qpS>%?w`>J&Veb;s8Wu6%UH+HiC%p|@?x+4KxSQG@>Alq1zyAv#Kf`bU diff --git a/app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc b/app/static/css/themes/lowPerformance/.sass-cache/06e1af29809e921b9cdcfb5d5a159c7f3b45df89/style.scssc deleted file mode 100644 index 2cf0dc0a25e23c50630a2c1f40022f67a815b938..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123278 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 G`u_o*YzMdi diff --git a/app/static/css/themes/lowPerformance/.sass-cache/f753b8fc673d85d43055d969da28457bcafb24b8/kerstmis.scssc b/app/static/css/themes/lowPerformance/.sass-cache/f753b8fc673d85d43055d969da28457bcafb24b8/kerstmis.scssc deleted file mode 100644 index 426ed7c84121ab2c8138864c2f921301e5d53c38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116620 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 ib0v%Q@L;;9bc@-tl^N`^8Wys3&NQI diff --git a/app/static/css/themes/lowPerformance/dataPrivacy.css b/app/static/css/themes/lowPerformance/dataPrivacy.css deleted file mode 100644 index b9c300c..0000000 --- a/app/static/css/themes/lowPerformance/dataPrivacy.css +++ /dev/null @@ -1,4 +0,0 @@ -.background { - background-image: url("https://kelder.zeus.ugent.be/webcam/video/mjpg.cgi?profileid=2"); - background-size: contain; -} diff --git a/app/static/css/themes/lowPerformance/halloween.css b/app/static/css/themes/lowPerformance/halloween.css deleted file mode 100644 index baa23d8..0000000 --- a/app/static/css/themes/lowPerformance/halloween.css +++ /dev/null @@ -1,16 +0,0 @@ -/*halloween*/ - -:root { - /*Darkmode colors*/ - --dGray0:#FFEB65; - --dGray1:#F28705; - --dGray2:#F25C05; - --dGray3:#F27405; - --dGray4:#8C3D0F; - --dGray5:#260101; - --dGray6:#260101; - --dBlue:#D91604; -} -.table-hover tbody tr:hover{ - background-image: url("static/images/themes/halloween/Halloween.jpeg"); -} diff --git a/app/static/css/themes/lowPerformance/kerstmis.css b/app/static/css/themes/lowPerformance/kerstmis.css deleted file mode 100644 index fce2b41..0000000 --- a/app/static/css/themes/lowPerformance/kerstmis.css +++ /dev/null @@ -1,442 +0,0 @@ -@charset "UTF-8"; -/* -¡¡¡ OPGELET !!! -Deze css bevat lelijke code. -Dit komt doordat bootstrap lelijk en oud is. -Ik zal later proberen de css te verbeteren en bootstrap weg te gooien. -Enige discretie is aangeraden. - ----=§[ Arnhoudt ]§=--- - -*/ -/*low performance kerstmis*/ -:root { - /*Darkmode colors*/ - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } - -body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } - -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_regular.ttf"); - font-weight: normal; } -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_light.ttf"); - font-weight: 200; } -@font-face { - font-family: Radikal; - src: url("static/fonts/radikal_bold.ttf"); - font-weight: bold; } -.btn { - border-radius: 5rem; - color: white; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - background-image: linear-gradient(-40deg, #F53030, #F58B9E); } - -.btn:hover { - background-image: linear-gradient(-40deg, #A81111, #FF4B33); } - -.navbar { - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - padding: 1.5rem; - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; - text-transform: capitalize; } - -.nav > li > a { - padding-left: 1vw; - padding-right: 1vw; } - -.main { - height: 90vh; - overflow: scroll; - padding-left: 0; - padding-right: 0; - width: 100%; - display: flex; - align-items: center; - flex-direction: column; } - -.navbar .container { - width: 100%; - padding: 0 4vw; } - -@media (min-width: 768px) { - .container { - width: 100%; } } -@media (min-width: 992px) { - .main .container, .main .orders { - width: 970px; } } -@media (min-width: 1200px) { - .main .container, .main .orders { - width: 1170px; } } -.main { - padding-top: 2.5rem; } - -.order_data { - display: flex; - flex-direction: row; - width: 100%; - justify-content: space-between; - padding: 0 3rem; - align-items: baseline; } - -.order_data h5 { - max-width: 60%; - padding-bottom: 3rem; } - -.expand_button { - padding: 1rem 0rem; - margin-top: -1rem; - width: 70%; - margin-bottom: 1.5rem; } - -.hi_im_haldis h2 { - display: none; } - -.hi_im_haldis h3 { - width: 100%; - font-family: Arial Rounded MT Bold,Helvetica Rounded,Arial,sans-serif; - text-align: center; } - -.hi_im_haldis { - background: linear-gradient(70deg, rgba(203, 52, 68, 0.8), rgba(135, 32, 44, 0.8)); - border-radius: 0; - width: 100%; } - -.hi_im_haldis_wrapper { - width: 100%; } - -.darker:nth-child(even) { - background-color: #B62937; - border-radius: 2rem; } - -.darker:nth-child(odd) { - background-color: #821C25; - border-radius: 2rem; } - -.darker { - padding: 1rem; } - -.order_row:nth-child(even) .order_data { - background-color: #B62937; - border-radius: 2rem; } - -.order_row { - background: transparent; } - -.order_row:nth-child(odd) .order_data { - background-color: #821C25; - border-radius: 2rem; } - -.order_row h5 { - font-weight: bold; } - -.order_row { - margin-bottom: 3rem; } - -h3 { - padding-bottom: 1rem; } - -.home_sir { - font-weight: bold; - color: #F45D68; } - -.expand_button_wrapper { - margin-top: -1rem; - width: 100%; - display: flex; - justify-content: center; } - -.time_data { - text-align: right; - display: flex; - flex-direction: column; - justify-self: right; } - -.navbar .navbar-nav .active a { - color: #ff9bae; - border-bottom: 1px solid #ff9bae; - padding-bottom: 1rem; } - -.navbar-nav { - padding-left: 2rem; } - -.jumbotron, .darker { - display: flex; - flex-direction: column; - border-radius: 4rem; } - -.row > div > h5 { - font-weight: bold; - padding-top: 1.5rem; - font-size: 2.5rem; } - -.row > div > .amount_of_orders { - font-weight: lighter; - font-size: 1.6rem; } - -.row > div .time { - font-weight: lighter; } - -.jumbotron { - background-color: transparent; } - -.navbar-default .navbar-nav .active a, .navbar-default .navbar-nav .active a:hover { - background-color: transparent; } - -.background { - -webkit-filter: blur(0px) brightness(80%); - -moz-filter: blur(0px) brightness(80%); - -o-filter: blur(0px) brightness(80%); - -ms-filter: blur(0px) brightness(80%); - filter: blur(0px) brightness(80%); - position: fixed; - top: 0; - left: 0; } - -footer a { - color: #69E8FF; } - -footer { - position: fixed; - bottom: 0; - width: 100%; - background: #CB3444; - height: 5rem; - display: flex; - align-items: center; } - -footer > hr { - display: none; } - -#mapid { - width: 100%; } - -.order_overview, .order_order, .order_items, .order_ordered, .order_depts { - padding: 1rem 5rem 3rem 5rem; } - -.order_overview { - width: 100%; } - -.order_depts { - width: 100%; - margin-bottom: 10rem; } - -.location_data, .location_products { - width: 100%; } - -.location_products { - margin-bottom: 10rem; } - -.locations_locations { - padding: 1rem 5rem 3rem 5rem; } - -.background_wrapper { - position: absolute; - left: 0; - bottom: 5rem; - width: 100%; - height: 100%; - overflow: hidden; } - -.christmas_background { - z-index: -101; - width: 300%; - height: 300%; - background: linear-gradient(-45deg, #2F0000, #C20A12); } - -.sled { - width: 15rem; - height: 15rem; - transition: transform 2s ease-in 5s, rotate 1s ease-in-out 2s; - background-repeat: no-repeat; - background-position: center; - background-size: contain; - background-image: url("static/images/themes/kerstmis/sled.svg"); } - -.sled_wrapper { - top: 0.5rem; - left: -7.5rem; - position: absolute; - transform: translate(-50vw, 40vh) rotate(0deg); - width: 15rem; - height: 15rem; - animation: sled 29s ease-in-out infinite; } - -.snowman_wrapper { - height: 17rem; - width: 10rem; - position: absolute; - bottom: 15rem; - left: -12rem; - animation: snowman 37s ease infinite; - transform-origin: right bottom; } - -.snowman_head { - position: absolute; - top: 0; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_head.svg"); - animation: snowman_head 2s ease infinite; } - -.snowman_body { - position: absolute; - top: 9.5rem; - left: 0.5rem; - width: 10rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/snowman_body.svg"); } - -.train_button { - visibility: hidden; } - -.train_wrapper { - position: absolute; - bottom: 0.5rem; - transform: translateX(-80vw); - animation: train 47s linear infinite; } - -.wheel_big, .wheel_small { - position: absolute; - bottom: -0.4rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/wheel.svg"); } - -.train { - position: absolute; - bottom: 0.5rem; - left: 30rem; - width: 30rem; - height: 10rem; - background-repeat: no-repeat; - background-size: contain; - background-image: url("static/images/themes/kerstmis/train.svg"); - animation: whobble 1s linear alternate-reverse infinite; } - -.wheel_big { - width: 3.2rem; - height: 3.2rem; } - -.wheel_small { - width: 2.5rem; - height: 2.5rem; } - -.train .wheel1 { - animation: turn 2s linear infinite; - left: 3.5rem; } - -.train .wheel2 { - animation: turn 2s linear infinite, -0.1s; - left: 7rem; } - -.train .wheel3 { - animation: turn 2s linear infinite -0.3s; - left: 10.5rem; } - -.train .wheel4 { - animation: turn 1.5s linear infinite -0.5s; - left: 13.9rem; } - -.train .wheel5 { - animation: turn 1.5s linear infinite -0.7s; - left: 16.6rem; } - -.zeus_wagon, .mc_wagon { - position: absolute; - bottom: 1.25rem; - width: 30rem; - height: 7.5rem; - background-repeat: no-repeat; - background-size: contain; - animation: whobble 1s linear alternate-reverse infinite; } - -.mc_wagon { - background-image: url("static/images/themes/kerstmis/mc_wagon.svg"); - left: 0rem; } - -.zeus_wagon { - background-image: url("static/images/themes/kerstmis/zeus_wagon.svg"); - left: 15rem; } - -.zeus_wagon .wheel1, .mc_wagon .wheel1 { - animation: turn 2s linear infinite; - bottom: -1.1rem; - left: 2.2rem; } - -.zeus_wagon .wheel2, .mc_wagon .wheel2 { - animation: turn 2s linear infinite, -0.1s; - bottom: -1.1rem; - left: 5.75rem; } - -.zeus_wagon .wheel3, .mc_wagon .wheel3 { - animation: turn 2s linear infinite -0.3s; - bottom: -1.1rem; - left: 9.3rem; } - -@keyframes sled { - 0% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 4% { - transform: translate(-50rem, 40vh) rotate(0deg); } - 20% { - transform: translate(50vw, 10vh) rotate(20deg); } - 36% { - transform: translate(150vw, 40vh) rotate(40deg); } - 100% { - transform: translate(150vw, 40vh) rotate(40deg); } } -@keyframes train { - 0% { - transform: translateX(-80rem); } - 55% { - transform: translateX(-80rem); } - 85% { - transform: translateX(100vw); } - 100% { - transform: translateX(100vw); } } -@keyframes turn { - 100% { - transform: rotate(360deg); } } -@keyframes whobble { - 100% { - transform: translateY(0.5vh); } } -@keyframes snowman { - 0% { - transform: rotate(0); } - 20% { - transform: rotate(0); } - 30% { - transform: rotate(80deg); } - 54% { - transform: rotate(80deg); } - 68% { - transform: rotate(0); } - 100% { - transform: rotate(0); } } -@keyframes snowman_head { - 0% { - transform: rotate(-3deg); } - 50% { - transform: rotate(3deg); } - 100% { - transform: rotate(-3deg); } } - -/*# sourceMappingURL=kerstmis.css.map */ diff --git a/app/static/css/themes/lowPerformance/kerstmis.css.map b/app/static/css/themes/lowPerformance/kerstmis.css.map deleted file mode 100644 index f76a3d4..0000000 --- a/app/static/css/themes/lowPerformance/kerstmis.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ -"version": 3, -"mappings": "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", -"sources": ["kerstmis.scss"], -"names": [], -"file": "kerstmis.css" -} \ No newline at end of file diff --git a/app/static/css/themes/lowPerformance/lightmode.css b/app/static/css/themes/lowPerformance/lightmode.css deleted file mode 100644 index 591e0ea..0000000 --- a/app/static/css/themes/lowPerformance/lightmode.css +++ /dev/null @@ -1,12 +0,0 @@ -/*lightmode*/ -:root { - /*Darkmode colors*/ - --dGray0:#444444; - --dGray1:#666666; - --dGray2:#212121; - --dGray3:#ffffff; - --dGray4:#f9f9f9; - --dGray5:#ffffff; - --dGray6:#ffffff; - --dBlue:#0A84FF; -} diff --git a/app/static/css/themes/lowPerformance/sinterklaas.css b/app/static/css/themes/lowPerformance/sinterklaas.css deleted file mode 100644 index 6febc5f..0000000 --- a/app/static/css/themes/lowPerformance/sinterklaas.css +++ /dev/null @@ -1,16 +0,0 @@ -/*sinterklaas*/ -:root { - /*Darkmode colors*/ - --dGray0:#F2EB80; - --dGray1:#F2EF05; - --dGray2:#F2EF05; - --dGray3:#177EBF; - --dGray4:#0C6AA6; - --dGray5:#F20505; - --dGray6:#F50B00; - --dBlue:#35F546; -} - -.background{ - background-image: url("static/images/themes/sinterklaas/Sinterklaas.jpg"); -} diff --git a/app/static/css/themes/lowPerformance/darkmode.css b/app/static/css/themes/plain_darkmode.css similarity index 82% rename from app/static/css/themes/lowPerformance/darkmode.css rename to app/static/css/themes/plain_darkmode.css index 7a1dc46..3b5d50f 100644 --- a/app/static/css/themes/lowPerformance/darkmode.css +++ b/app/static/css/themes/plain_darkmode.css @@ -1,6 +1,4 @@ -/*Darkmode*/ :root { - /*Darkmode colors*/ --dGray0:#D0D0D8; --dGray1:#8E8E93; --dGray2:#636366; diff --git a/app/static/css/themes/highPerformance/lightmode.css b/app/static/css/themes/plain_lightmode.css similarity index 82% rename from app/static/css/themes/highPerformance/lightmode.css rename to app/static/css/themes/plain_lightmode.css index 591e0ea..4713231 100644 --- a/app/static/css/themes/highPerformance/lightmode.css +++ b/app/static/css/themes/plain_lightmode.css @@ -1,6 +1,4 @@ -/*lightmode*/ :root { - /*Darkmode colors*/ --dGray0:#444444; --dGray1:#666666; --dGray2:#212121; diff --git a/app/static/css/themes/highPerformance/sinterklaas.css b/app/static/css/themes/sinterklaas.css similarity index 87% rename from app/static/css/themes/highPerformance/sinterklaas.css rename to app/static/css/themes/sinterklaas.css index 6febc5f..56c32a7 100644 --- a/app/static/css/themes/highPerformance/sinterklaas.css +++ b/app/static/css/themes/sinterklaas.css @@ -1,6 +1,4 @@ -/*sinterklaas*/ :root { - /*Darkmode colors*/ --dGray0:#F2EB80; --dGray1:#F2EF05; --dGray2:#F2EF05; diff --git a/app/static/js/customThemes.js b/app/static/js/customThemes.js deleted file mode 100644 index a605f26..0000000 --- a/app/static/js/customThemes.js +++ /dev/null @@ -1,11 +0,0 @@ -function changeTheme() { - // Get the selected theme for the dropdown - var themes_select = document.getElementById("themes_select"); - var selected_theme = themes_select.options[themes_select.selectedIndex].text; - - // Update the theme cookie - document.cookie = "theme=" + escape(selected_theme) + "; Path=/;" - - // Finally reload the page to let the new theme take effect - location.reload(); -} diff --git a/app/static/js/theme.js b/app/static/js/theme.js index 9d582a3..8f693d9 100644 --- a/app/static/js/theme.js +++ b/app/static/js/theme.js @@ -1,34 +1,82 @@ { - const init = () =>{ - document.cookie.split('; ').forEach(itCookie = cookie =>{ // TODO (Arnhoudt) Fix shitty way of doing things - if(cookie.split("=")[0] == "theme" && cookie.split("=")[1] == "darkmode"){ - document.querySelector(".toggleDarkmode").innerHTML = "Enter lightmode" - document.querySelector(".toggleDarkmode").id = "lightmode"; - } + const COOKIE_THEME = "theme"; + const COOKIE_ATMOSPHERE = "theme_atmosphere"; + const COOKIE_PERFORMANCE = "theme_performance"; - if(cookie.split("=")[0] == "theme" && cookie.split("=")[1] == "customTheme"){ - document.querySelector(".background").innerHTML = '
'; - } - if(cookie.split("=")[0] == "performance" && cookie.split("=")[1] == "highPerformance" && document.querySelector(".changePerformance")){ - document.querySelector(".changePerformance").innerHTML = "enable low performance"; - document.querySelector(".changePerformance").id = "lowPerformance"; - } - }); - document.querySelectorAll('.changeThemeButton').forEach(changeThemeButton= e => {e.addEventListener(`click`, handleClickChangeTheme)}); - document.querySelectorAll('.changePerformance').forEach(changeThemeButton= e => {e.addEventListener(`click`, handleClickChangePerformance)}); - } + const YEAR = 60 * 60 * 24 * 365; - const handleClickChangePerformance = e => { - document.cookie = "performance = "+e.currentTarget.id+";path=/"; + const storeCookieAndReload = (name, value) => { + document.cookie = name + " = " + value + "; Path=/; Max-Age=" + (50 * YEAR); location.reload(); } - const handleClickChangeTheme = e =>{ - document.cookie = "theme = "+e.currentTarget.id+";path=/"; - location.reload(); + const radio = (name, options, current) => { + let container = document.createElement("div"); + + for (let option in options) { + if (!options.hasOwnProperty(option)) continue; + + let input = document.createElement("input"); + input.type = "radio"; + input.name = name; + input.value = option; + input.id = `${name}-${option}`; + if (option === current) input.setAttribute("checked", "checked"); + input.addEventListener("change", e => storeCookieAndReload(name, e.currentTarget.value)); + + let label = document.createElement("label"); + label.setAttribute("for", `${name}-${option}`); + label.innerText = options[option]; + + let span = document.createElement("span"); + span.append(input, " ", label, " "); + container.appendChild(span); + } + + return container; + }; + + const init = () => { + let cookies = {}; + document.cookie.split('; ') + .map(cookieDefStr => cookieDefStr.split("=", 2)) + .forEach(cookiePair => { cookies[cookiePair[0]] = cookiePair[1]; }); + + if (window.currentTheme === "plain") { + let a = document.createElement("a"); + a.href = "javascript:void(0)"; + + if (cookies[COOKIE_ATMOSPHERE] == "darkmode") { + a.innerHTML = "Enter light mode" + a.addEventListener("click", () => storeCookieAndReload(COOKIE_ATMOSPHERE, "lightmode")); + } else { + a.innerHTML = "Enter dark mode" + a.addEventListener("click", () => storeCookieAndReload(COOKIE_ATMOSPHERE, "darkmode")); + } + + document.getElementById("themeChange").innerHTML = ""; + document.getElementById("themeChange").appendChild(a); + } + + + if (window.currentTheme === "christmas") { + document.querySelector(".background").innerHTML = '
'; + } + + + if (document.querySelector(".changePerformance") && window.currentThemeOptions.includes("performance")) { + document.querySelector(".changePerformance").appendChild( + radio(COOKIE_PERFORMANCE, {heavy: "Heavy", lightweight: "Lightweight"}, cookies[COOKIE_PERFORMANCE]) + ); + } + + if (document.getElementById("themes_select")) { + let themes_select = document.getElementById("themes_select"); + themes_select.value = cookies["theme"] || ""; + + themes_select.addEventListener("change", () => storeCookieAndReload(COOKIE_THEME, themes_select.value)); + } } - - init(); } diff --git a/app/templates/layout.html b/app/templates/layout.html index cddb82a..854b255 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -21,15 +21,15 @@ Haldis - {{ active_page|capitalize }} {% block styles %} {{ super() }} - + {% endblock %} {% block scripts %} {{ super() }} + - {% endblock %} {% block navbar %} @@ -80,7 +80,7 @@ Haldis - {{ active_page|capitalize }} diff --git a/app/templates/profile.html b/app/templates/profile.html index c9b1715..bd317a1 100644 --- a/app/templates/profile.html +++ b/app/templates/profile.html @@ -4,15 +4,14 @@ {% block container %}

{{ current_user.username }}

Themes

-

enable custom themes

-

enable high performance

- + {% for theme in themes_list %} - + {% endfor %}

+

{% endblock %} diff --git a/app/views/general.py b/app/views/general.py index 3b6ae40..8a50d2b 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -26,6 +26,12 @@ from flask import jsonify general_bp = Blueprint("general_bp", __name__) +with open(os.path.join(os.path.dirname(__file__), "themes.yml"), "r") as _stream: + _theme_data = yaml.safe_load(_stream) + THEME_OPTIONS = _theme_data["options"] + THEMES = _theme_data["themes"] + + @general_bp.route("/") def home() -> str: "Generate the home view" @@ -38,79 +44,94 @@ def home() -> str: ) -def get_css_dict(css_path): - "Generate the dictionary with all the currently available themes and their names" - themes_dict = dict() +def is_theme_active(theme, now): + theme_type = theme["type"] - # Open the YAML file with all the themes. - path = os.path.join(app.root_path, "views/themes.yml") - with open(path, "r") as stream: - data = yaml.safe_load(stream) - # Build a dictionary from the YAML file with all the themes and their attributes. - themes = {} - for item in data: - key = list(item.keys())[0] - themes[key] = item[key] + if theme_type == "static": + return True - # Get the current date. - current_date = datetime.now() - current_year = current_date.year + if theme_type == "seasonal": + start_day, start_month = map(int, theme["start"].split("/")) + start_datetime = datetime(year=now.year, day=start_day, month=start_month) - # Check each theme in the dictionary and return the first one that is "correct" - for key, theme in themes.items(): - if theme["type"] == "static-date": - start_day, start_month = theme["start"].split("/") - start_date = datetime(year=current_year, day=int(start_day), month=int(start_month)) + end_day, end_month = map(int, theme["end"].split("/")) + end_year = now.year + (1 if start_month > end_month else 0) + end_datetime = datetime(year=end_year, day=end_day, month=end_month) - end_day, end_month = theme["end"].split("/") - if int(start_month) > int(end_month): - current_year += 1 - end_date = datetime(year=current_year, day=int(end_day), month=int(end_month)) + return start_datetime <= now <= end_datetime - if start_date <= current_date <= end_date: - path = os.path.join(app.root_path, css_path, theme["file"]) - themes_dict[key] = path - themes_dict["darkmode"] = os.path.join( - app.root_path, "static/css/themes/lowPerformance/darkmode.css" - ) - themes_dict["lightmode"] = os.path.join( - app.root_path, "static/css/themes/lowPerformance/lightmode.css" - ) - - return themes_dict + raise Exception("Unknown theme type {}".format(theme_type)) -def css_list(): - "Generate the list of names of all the currently available themes" - if request.cookies.get("performance", "") == "highPerformance": - css_path = "static/css/themes/highPerformance/" - else: - css_path = "static/css/themes/lowPerformance/" - return list(get_css_dict(css_path).keys()) +def get_theme_css(theme, options): + # Build filename + # Each option's chosen value is appended, to get something like mytheme_darkmode_heavy.css + + filename = theme["file"] + + for option in theme.get("options", []): + theme_name = theme["name"] + assert option in THEME_OPTIONS, f"Theme `{theme_name}` uses undefined option `{option}`" + + chosen_value = options[option] + possible_values = list(THEME_OPTIONS[option].keys()) + + value = chosen_value if chosen_value in possible_values \ + else THEME_OPTIONS[option]["_default"] + + filename += "_" + value + + filename += ".css" + + theme_css_dir = "static/css/themes/" + return os.path.join(app.root_path, theme_css_dir, filename) -@general_bp.route("/css") -def css(): - "Generate the css" - if request.cookies.get("performance", "") == "highPerformance": - css_path = "static/css/themes/highPerformance/" - else: - css_path = "static/css/themes/lowPerformance/" +def get_active_themes(): + now = datetime.now() + return [theme for theme in THEMES if is_theme_active(theme, now)] - cookie_theme = request.cookies.get("theme", "") - themes_dict = get_css_dict(css_path) +@general_bp.route("/theme.css") +def theme_css(): + "Send appropriate CSS for current theme" + themes = get_active_themes() - # TODO: Fix to work with default cookie value [customTheme] - if cookie_theme == "customTheme": - path = f"{css_path}ligtmode.css" - else: - path = themes_dict[cookie_theme] + theme_name = request.cookies.get("theme", None) + theme = first((t for t in themes if t["file"] == theme_name), default=themes[-1]) - f = open(path) - response = make_response(f.read()) + options = { + name: request.cookies.get("theme_" + name, None) + for name in ["atmosphere", "performance"] + } + + path = get_theme_css(theme, options) + + with open(path) as f: + response = make_response(f.read()) response.headers["Content-Type"] = "text/css" - f.close() + + return response + + +@general_bp.route("/current_theme.js") +def current_theme_js(): + themes = get_active_themes() + + selected_theme_name = request.cookies.get("theme", None) + matching_theme = first((t for t in themes if t["file"] == selected_theme_name)) + cur_theme = matching_theme or themes[-1] + + response = make_response(rf''' +var currentTheme = {json.dumps(cur_theme['file'])}; +var currentThemeOptions = {json.dumps(cur_theme['options'])}; +''') + response.headers["Content-Type"] = "text/javascript" + + # Theme name that is not valid at this moment: delete cookie + if matching_theme is None: + response.delete_cookie("theme", path="/") + return response @@ -176,7 +197,7 @@ def about() -> str: @login_required def profile() -> str: "Generate the profile view" - return render_template("profile.html", themes_list=css_list()) + return render_template("profile.html", themes_list=get_active_themes()) @general_bp.route("/favicon.ico") diff --git a/app/views/themes.yml b/app/views/themes.yml index 824b689..cf1951f 100644 --- a/app/views/themes.yml +++ b/app/views/themes.yml @@ -1,22 +1,36 @@ -# Seasonal themes for Haldis -- lightmode: - file: lightmode.css - type: default -- darkmode: - file: darkmode.css - type: default -- halloween: - file: halloween.css - type: static-date - start: 21/10 - end: 10/11 -- sinterklaas: - file: sinterklaas.css - type: static-date - start: 28/11 - end: 5/12 -- kerstmis: - file: kerstmis.css - type: static-date - start: 6/12 - end: 06/01 +options: + atmosphere: + lightmode: Light mode + darkmode: Dark mode + _default: lightmode + + performance: + heavy: Heavy + lightweight: Lightweight + _default: heavy + +themes: +- name: Plain + file: plain + type: static + options: [atmosphere] + +# Seasonal themes +- name: Halloween + file: halloween + type: seasonal + start: 24/10 + end: 1/11 + +- name: Sinterklaas + file: sinterklaas + type: seasonal + start: 28/11 + end: 5/12 + +- name: Christmas + file: christmas + type: seasonal + start: 6/12 + end: 6/01 + options: [performance] -- 2.43.4 From dc1596ee7174483c02aa0f8f87f75f0342f797e0 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 03:38:55 +0200 Subject: [PATCH 060/197] Fix shadowed variable name --- app/app.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/app.py b/app/app.py index 40990cf..42f018d 100755 --- a/app/app.py +++ b/app/app.py @@ -49,17 +49,16 @@ def register_plugins(app: Flask) -> Manager: airbrakelogger = logging.getLogger("airbrake") - # Airbrake - airbrake = airbrake.Airbrake( + airbrake_obj = airbrake.Airbrake( project_id=app.config["AIRBRAKE_ID"], api_key=app.config["AIRBRAKE_KEY"] ) # Change URL in a hacky way to make this work for our errbit - airbrake._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=protected-access - airbrake.project_id + airbrake_obj._api_url = "http://errbit.awesomepeople.tv/api/v3/projects/{}/notices".format( # pylint: disable=protected-access + airbrake_obj.project_id ) - airbrakelogger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake)) - app.logger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake)) + airbrakelogger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake_obj)) + app.logger.addHandler(airbrake.AirbrakeHandler(airbrake=airbrake_obj)) # Initialize SQLAlchemy db.init_app(app) -- 2.43.4 From 8a01e74323162ba96183bf7dc748de426b5cf3b8 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 03:54:33 +0200 Subject: [PATCH 061/197] Fix Passenger startup script --- app/passenger_wsgi.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index e2a2ec5..7fe947b 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -9,9 +9,7 @@ if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) sys.path.append(os.getcwd()) -from app import create_app - -application = create_app().app +from app import app as application # For running on the server with passenger etc if __name__ == "__main__": -- 2.43.4 From 2d3ae10f907a219976fdee169fbf6ecf948a2894 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 04:13:20 +0200 Subject: [PATCH 062/197] Better document Passenger file to avoid surprises --- app/passenger_wsgi.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index 7fe947b..9d3ebd1 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -1,14 +1,23 @@ #!/usr/bin/env python3 -"Script to run Haldis on a server" +""" +Used by Zeus in production. +This script makes Haldis acceptable to Phusion Passenger assuming a setup like on Zeus servers. +""" + +# pylint: disable=wrong-import-position import os import sys +# User has the virtual environment in ~/env/ INTERP = os.path.expanduser("~/env/bin/python3") if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv) sys.path.append(os.getcwd()) + +# Phusion Passenger expects this file to be called `passenger_wsgi.py` +# and the WSGI object to be called `application` from app import app as application # For running on the server with passenger etc -- 2.43.4 From 5e944755ee48c8251e528e6436bad24c182dc16b Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 16:17:21 +0200 Subject: [PATCH 063/197] Remove authors section A lot of people have contributed to Haldis, it doesn't make sense to mention just one individual in the README. Contributors are visible in the Git history. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 67ea409..ad467b5 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,3 @@ Set DEBUG to False in `app/config.py`. See [Flask's deployment documentation](https://flask.palletsprojects.com/en/1.1.x/deploying/#self-hosted-options). Set the server's Python interpreter to `/path/to/haldis/venv/bin/python`. Doing `source venv/bin/activate` is not necessary when that binary is used. - - -## Authors - -* **Feliciaan De Palmenaer** - *Initial work* - [Github](https://github.com/feliciaan) -- 2.43.4 From 67df1cebff770829e5d988150bd3f964ad5b05b6 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 20:09:03 +0200 Subject: [PATCH 064/197] Update link to zeus.gent and https --- app/templates/layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/layout.html b/app/templates/layout.html index 854b255..b19d9b7 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -79,7 +79,7 @@ Haldis - {{ active_page|capitalize }}
-
Made with ❤ by Zeus WPI
+
Made with ❤ by Zeus WPI
-- 2.43.4 From 65fa6441b132c244ab796014efaa3a4d215fd43f Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 18 Jul 2020 23:50:49 +0200 Subject: [PATCH 065/197] Remove incorrect comment The comment says that mypy gives a "Missing return statement" but it links to an issue on the mypy bug tracker about the same error message reported after exhaustive enum matching. This is a completely different situation, here the "Missing return statement" is warranted: this part of the code is reachable so an explicit `return None` is wanted for this function that returns an Optional. --- app/views/order.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/views/order.py b/app/views/order.py index b4cbe5c..adcf56b 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -330,9 +330,6 @@ def close_order(order_id: int) -> typing.Optional[Response]: order.courier_id = courier.id db.session.commit() return redirect(url_for("order_bp.order_from_id", order_id=order_id)) - # The line below is to make sure mypy doesn't say - # "Missing return statement" - # https://github.com/python/mypy/issues/4223 return None -- 2.43.4 From 84957f317553e62ff94b65374e2ed6173c8b3281 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 24 Jul 2020 12:42:39 +0200 Subject: [PATCH 066/197] Fix theme on order items page --- app/templates/order_items.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 917c4aa..5dcb488 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -8,7 +8,7 @@ Haldis - Order {{ order.id }} {% block styles %} {{ super() }} - + {% endblock %} -- 2.43.4 From c61b323f8c65267619d7fe6340bb0feae23cf0d7 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 27 Jul 2020 00:51:14 +0200 Subject: [PATCH 067/197] Add chopsticks to Ocean Garden menu --- data/ocean_garden.hlds | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 7f57b39..1544e8a 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -67,3 +67,5 @@ dish mihoen_veggies: 78. Mihoen met diverse groenten (veggie) -- Rijstnoe dish chau_ming_veggies: 79. Chau ming met diverse groenten (veggie) -- Eiernoedels € 10 dish tau_foe_ma_po: 80. Tau Foe met ma-po-saus (veggie) -- Met gebakken rijst € 11.5 dish tau_foe_mushrooms: 81. Tau Foe met Chinese champignons (veggie) -- Met gebakken rijst € 11.5 + +dish chopsticks: Stokjes -- 2.43.4 From aa1cd97773d6d184a7dee939ebfbe9d82f1e84d4 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 29 Jul 2020 21:01:47 +0200 Subject: [PATCH 068/197] Revert "Remove admin view" This reverts commit a62e2bd9f7ff31abf220b750d80aed7b25e45f7f. --- app/admin.py | 36 ++++++++++++++++++++++++++++++++++++ app/app.py | 3 +++ app/templates/layout.html | 3 +++ 3 files changed, 42 insertions(+) create mode 100644 app/admin.py diff --git a/app/admin.py b/app/admin.py new file mode 100644 index 0000000..0ba2810 --- /dev/null +++ b/app/admin.py @@ -0,0 +1,36 @@ +"Haldis admin related views and models" + +import flask_login as login +from flask import Flask +from flask_admin import Admin +from flask_admin.contrib.sqla import ModelView +from flask_sqlalchemy import SQLAlchemy + +from models import Order, OrderItem, OrderItemChoice, User + + +class ModelBaseView(ModelView): + "Base model for admin related things" + # pylint: disable=R0201, R0903 + def is_accessible(self) -> bool: + "Check if the user has admin permission" + if login.current_user.is_anonymous(): + return False + return login.current_user.is_admin() + + +class UserAdminModel(ModelBaseView): + "Model for user admin" + # pylint: disable=R0903 + column_searchable_list = ("username",) + inline_models = None + + +def init_admin(app: Flask, database: SQLAlchemy) -> None: + "Initialize the admin related things in the app." + admin = Admin(app, name="Haldis", url="/admin", template_mode="bootstrap3") + + admin.add_view(UserAdminModel(User, database.session)) + admin.add_view(ModelBaseView(Order, database.session)) + admin.add_view(ModelBaseView(OrderItem, database.session)) + admin.add_view(ModelBaseView(OrderItemChoice, database.session)) diff --git a/app/app.py b/app/app.py index 42f018d..e5e4f22 100755 --- a/app/app.py +++ b/app/app.py @@ -19,6 +19,7 @@ from flask_oauthlib.client import OAuth, OAuthException from flask_script import Manager, Server from markupsafe import Markup +from admin import init_admin from login import init_login from models import db from models.anonymous_user import AnonymouseUser @@ -68,6 +69,8 @@ def register_plugins(app: Flask) -> Manager: app_manager = Manager(app) app_manager.add_command("db", MigrateCommand) app_manager.add_command("runserver", Server(port=8000)) + # Add admin interface + init_admin(app, db) # Init login manager login_manager = LoginManager() diff --git a/app/templates/layout.html b/app/templates/layout.html index b19d9b7..ede4835 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -9,6 +9,9 @@ ('general_bp.about', 'About'), ('stats_blueprint.stats', 'Stats'), ] -%} +{% if not current_user.is_anonymous() and current_user.is_admin() -%} + {% set navbar = navbar + [('admin.index', 'Admin')] -%} +{% endif -%} {% set active_page = active_page|default('index') -%} {% block title %} -- 2.43.4 From f6753172ec9f3c64e32e0141dd3a3c62d4e473d2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 29 Jul 2020 23:14:57 +0200 Subject: [PATCH 069/197] Polish the admin interface a bit --- app/admin.py | 37 ++++++++++++++++++++++------------ app/app.py | 1 - app/templates/admin/index.html | 8 ++++++++ app/templates/layout.html | 4 ++-- 4 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 app/templates/admin/index.html diff --git a/app/admin.py b/app/admin.py index 0ba2810..4ba9d99 100644 --- a/app/admin.py +++ b/app/admin.py @@ -1,5 +1,3 @@ -"Haldis admin related views and models" - import flask_login as login from flask import Flask from flask_admin import Admin @@ -10,27 +8,40 @@ from models import Order, OrderItem, OrderItemChoice, User class ModelBaseView(ModelView): - "Base model for admin related things" - # pylint: disable=R0201, R0903 + # pylint: disable=too-few-public-methods, no-self-use def is_accessible(self) -> bool: - "Check if the user has admin permission" - if login.current_user.is_anonymous(): - return False return login.current_user.is_admin() class UserAdminModel(ModelBaseView): - "Model for user admin" - # pylint: disable=R0903 + # pylint: disable=too-few-public-methods column_searchable_list = ("username",) + column_editable_list = ("username",) + column_default_sort = "username" inline_models = None +class OrderAdminModel(ModelBaseView): + # pylint: disable=too-few-public-methods + column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] + column_labels = { + "starttime": "Start time", "stoptime": "Closing time", + "location_name": "Location name", "location_id": "HLDS location ID", + "courier": "Courier"} + form_excluded_columns = ["items", "courier_id"] + column_default_sort = ("starttime", True) + can_delete = False + + +class OrderItemAdminModel(ModelBaseView): + # pylint: disable=too-few-public-methods + column_default_sort = ("order_id", True) + + def init_admin(app: Flask, database: SQLAlchemy) -> None: - "Initialize the admin related things in the app." + "Register admin views with Flask app." admin = Admin(app, name="Haldis", url="/admin", template_mode="bootstrap3") admin.add_view(UserAdminModel(User, database.session)) - admin.add_view(ModelBaseView(Order, database.session)) - admin.add_view(ModelBaseView(OrderItem, database.session)) - admin.add_view(ModelBaseView(OrderItemChoice, database.session)) + admin.add_view(OrderAdminModel(Order, database.session)) + admin.add_view(OrderItemAdminModel(OrderItem, database.session)) diff --git a/app/app.py b/app/app.py index e5e4f22..1a3dd98 100755 --- a/app/app.py +++ b/app/app.py @@ -69,7 +69,6 @@ def register_plugins(app: Flask) -> Manager: app_manager = Manager(app) app_manager.add_command("db", MigrateCommand) app_manager.add_command("runserver", Server(port=8000)) - # Add admin interface init_admin(app, db) # Init login manager diff --git a/app/templates/admin/index.html b/app/templates/admin/index.html new file mode 100644 index 0000000..fea67c3 --- /dev/null +++ b/app/templates/admin/index.html @@ -0,0 +1,8 @@ +{% extends 'admin/master.html' %} + +{% block body %} +

To edit the metadata of an order, go to Order. There is +no link from an order to the ordered items, so…

+

To edit or delete items from orders, go straight to Order Item.

+

To edit locations and their menus, edit the HLDS data files in the repository and submit a pull/merge request.

+{% endblock %} diff --git a/app/templates/layout.html b/app/templates/layout.html index ede4835..d825bf1 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -9,8 +9,8 @@ ('general_bp.about', 'About'), ('stats_blueprint.stats', 'Stats'), ] -%} -{% if not current_user.is_anonymous() and current_user.is_admin() -%} - {% set navbar = navbar + [('admin.index', 'Admin')] -%} +{% if current_user.is_admin() -%} + {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} {% set active_page = active_page|default('index') -%} -- 2.43.4 From 7464ee4ea40f7fdba1467e828a87358ba6b0302e Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 29 Jul 2020 23:26:07 +0200 Subject: [PATCH 070/197] Improve order and order item admin views --- app/admin.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/admin.py b/app/admin.py index 4ba9d99..553ec7d 100644 --- a/app/admin.py +++ b/app/admin.py @@ -23,19 +23,26 @@ class UserAdminModel(ModelBaseView): class OrderAdminModel(ModelBaseView): # pylint: disable=too-few-public-methods + column_default_sort = ("starttime", True) column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] column_labels = { - "starttime": "Start time", "stoptime": "Closing time", - "location_name": "Location name", "location_id": "HLDS location ID", - "courier": "Courier"} + "starttime": "Start Time", "stoptime": "Closing Time", + "location_id": "HLDS Location ID"} form_excluded_columns = ["items", "courier_id"] - column_default_sort = ("starttime", True) can_delete = False class OrderItemAdminModel(ModelBaseView): # pylint: disable=too-few-public-methods column_default_sort = ("order_id", True) + column_list = [ + "order_id", "order.location_name", "user_name", "user", "dish_name", "dish_id", "comment", "price", "paid", + "hlds_data_version" + ] + column_labels = { + "order_id": "Order", "order.location_name": "Order's Location", + "user_name": "Anon. User", "user_id": "Registered User", + "hlds_data_version": "HLDS Data Version", "dish_id": "HLDS Dish ID"} def init_admin(app: Flask, database: SQLAlchemy) -> None: -- 2.43.4 From cd67eab29b4740462185a070bddbc198a26bf324 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 8 Aug 2020 15:43:58 +0200 Subject: [PATCH 071/197] Remove colons after some titles Some titles had a colon, some hadn't. Titles don't need colons. --- app/templates/home.html | 4 ++-- app/templates/order.html | 2 +- app/templates/order_edit.html | 2 +- app/templates/orders.html | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/templates/home.html b/app/templates/home.html index b196e4f..12c0d14 100644 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -13,7 +13,7 @@
{% if orders|count > 0 -%} -

Open orders:

+

Open orders

{% for order in orders %} {{ util.render_order(order) }} {% endfor %} @@ -28,7 +28,7 @@
{% if recently_closed|count > 0 -%} -

Recently closed orders:

+

Recently closed orders

{% for order in recently_closed %} {{ util.render_order(order) }} {% endfor %} diff --git a/app/templates/order.html b/app/templates/order.html index 4dba8fe..25a3f8a 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -41,7 +41,7 @@
{% if form -%}
-

Order:

+

Order

Choose for me diff --git a/app/templates/order_edit.html b/app/templates/order_edit.html index 8ba1cc4..2667a9c 100644 --- a/app/templates/order_edit.html +++ b/app/templates/order_edit.html @@ -8,7 +8,7 @@
{% if not current_user.is_anonymous() %}
-

Edit order:

+

Edit order

diff --git a/app/templates/orders.html b/app/templates/orders.html index 5531654..e472461 100644 --- a/app/templates/orders.html +++ b/app/templates/orders.html @@ -8,7 +8,7 @@
{% if orders|count > 0 -%} -

Open orders:

+

Open orders

{% for order in orders %} {{ util.render_order(order) }} {% endfor %} @@ -23,7 +23,7 @@
{% if not current_user.is_anonymous() %}
-

Create new order:

+

Create new order

-- 2.43.4 From b1f3d786e8d14f6fac9ecb0e9db44c6b69879d16 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Fri, 21 Aug 2020 21:02:21 +0200 Subject: [PATCH 072/197] Remove print statements polluting our logs --- app/models/order.py | 1 - app/views/order.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 219650a..6ad5b5f 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -84,7 +84,6 @@ class Order(db.Model): user = None if user_id: user = User.query.filter_by(id=user_id).first() - print(user) if self.courier_id == user_id or (user and user.is_admin()): return True return False diff --git a/app/views/order.py b/app/views/order.py index adcf56b..0187722 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -265,8 +265,6 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]: (OrderItem.user_name == user_name) & (OrderItem.order_id == order_id) ).all() current_order = Order.query.filter(Order.id == order_id).first() - for item in items: - print(item) if current_order.courier_id == current_user.id or current_user.admin: for item in items: item.paid = True @@ -285,7 +283,6 @@ def delete_item(order_id: int, item_id: int) -> typing.Any: item = OrderItem.query.filter(OrderItem.id == item_id).first() user_id = None if not current_user.is_anonymous(): - print("%s tries to delete orders" % (current_user.username)) user_id = current_user.id if item.can_delete(order_id, user_id, session.get("anon_name", "")): dish_name = item.dish_name @@ -325,7 +322,6 @@ def close_order(order_id: int) -> typing.Optional[Response]: order.stoptime = datetime.now() if order.courier_id == 0 or order.courier_id is None: courier = select_user(order.items) - print(courier) if courier is not None: order.courier_id = courier.id db.session.commit() -- 2.43.4 From 52f85c420f7c24d05769ac4cadca73669e788801 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Aug 2020 19:09:53 +0200 Subject: [PATCH 073/197] Change to AGPL --- LICENSE | 673 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 673 insertions(+) diff --git a/LICENSE b/LICENSE index e887355..96685a4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,676 @@ +This software is licensed under the GNU Affero Public License. +Previous versions were licensed under the MIT license, which you can find at the bottom of this +document. + + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. + + + + + +A previous version of Haldis, upon which this one is based, is available under the MIT license. +Portions of this codebase remain in the current Haldis version. + The MIT License (MIT) Copyright (c) 2015 Zeus WPI -- 2.43.4 From 0ee1a0ea1210363e0e04df34e78048abccb56c9b Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Aug 2020 19:14:23 +0200 Subject: [PATCH 074/197] Remove unnecessary description in Ocean Garden --- data/ocean_garden.hlds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 1544e8a..12f571f 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -48,9 +48,9 @@ dish wok1_breaded_chicken: Kippenballetjes zoetzuur :: {has_meat} € 6 dish wok1_breaded_pork: Varkensballetjes zoetzuur :: {has_meat} € 6 single_choice bami_nasi -dish wok2_chicken: Wok 2: kip zonder saus -- Met bami of mihoen :: {has_meat} € 6 +dish wok2_chicken: Wok 2: kip zonder saus :: {has_meat} € 6 single_choice bami_mihoen -dish wok2_pork: Wok 2: varken zonder saus -- Met bami of mihoen :: {has_meat} € 6 +dish wok2_pork: Wok 2: varken zonder saus :: {has_meat} € 6 single_choice bami_mihoen dish wok3_chicken: Wok 3: kip met rijst zonder saus :: {has_meat} € 6 -- 2.43.4 From b25705250dee633e98f41090a02c2941dea69f90 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 26 Aug 2020 19:29:26 +0200 Subject: [PATCH 075/197] Update Fitchen menu --- data/fitchen.hlds | 197 +++++++--------------------------------------- 1 file changed, 30 insertions(+), 167 deletions(-) diff --git a/data/fitchen.hlds b/data/fitchen.hlds index f7f0dad..a17cc0a 100644 --- a/data/fitchen.hlds +++ b/data/fitchen.hlds @@ -4,7 +4,7 @@ fitchen: Fitchen website https://www.fitchen.be/ address Vlaanderenstraat 129, 9000 Gent phone +32 9 310 44 62 - # Menu: https://www.fitchen.be/wp-content/uploads/2019/12/FITCHEN_gids_02122019_3web.pdf + # Menu: https://www.fitchen.be/wp-content/uploads/2020/06/Fitchen-Menu-Zomer-2020.pdf ============================================= size: Grootte @@ -15,203 +15,66 @@ size: Grootte bowl_wrap: Bowl of wrap bowl: Bowl -- Wegwerpschaal wrap: Volkorenwrap - avocado_wrap: Avocadowrap € 0.99 - red_beet_wrap: Rodebietenwrap € 0.99 - -veggie: Vegetarische opties - meat: Niet vegetarisch :: {has_meat} {no_text} - tofu: Vegetarisch met tofu - tempeh: Vegetarisch met tempeh -- Gekruide tempeh - avocado: Vegetarisch met avocado - falafel: Vegetarisch met falafel - vegan: Veganistisch - -veggie_on_veggie_dish: Vegetarische opties - veggie: Vegetarisch (met standaard eiwitgerief van gerecht) :: {no_text} - tofu: Vegetarisch met tofu - tempeh: Vegetarisch met tempeh -- Gekruide tempeh - avocado: Vegetarisch met avocado - falafel: Vegetarisch met falafel - vegan: Veganistisch - -veggie_on_vegan_dish: Vegetarische opties - vegan: Veganistisch :: {no_text} - tofu: Vegetarisch met tofu - tempeh: Vegetarisch met tempeh -- Gekruide tempeh - avocado: Vegetarisch met avocado - falafel: Vegetarisch met falafel - -extra_dressing: Extra dressings/toppings - spicy_dressing: Spicy dressing € 0.99 - curry_dressing: Currydressing € 0.99 - mustard_dressing: Mosterddressing € 0.99 - basil-pesto_dressing: Basilicum-pestodressing € 0.99 - vegan_spicy_dressing: Vegan spicy dressing € 0.99 - vegan_cheese: Vegan kaas € 0.50 - vegan_curry_coconut_sauce: Vegan curry-kokosnootsaus € 1.99 - vegan_tomato_sauce: Vegan tomatensaus € 0.99 - vegan_ratatouille: Vegan ratatouille € 1.99 - olive_oil: Olijfolie € 0.50 - parmesan: Parmezaan € 0.50 - -extra_carbs: Extra koolhydraten - quinoa: Quinoa € 1.99 - brown_rice: Bruine rijst € 1.99 - whole_wheat_pasta: Volkorenpasta € 1.99 - sweet_potato: Zoete aardappel € 1.99 - side_whole_wheat_wrap: Volkorenwrap on the side € 0.99 - side_avocado_wrap: Avocadowrap on the side € 0.99 - side_red_beet_wrap: Rodebietenwrap on the side € 0.99 - -extra_protein: Extra eiwitten - chicken: Kip € 2.99 - lean_beef: Mager rundvlees € 2.99 - tofu: Tofu € 2.99 - falafel: Falafel € 2.99 - spiced_tempeh: Gekruide tempeh € 2.99 - salmon: Zalm € 2.99 - -extra_vegs: Extra groenten/zaden - avocado: Avocado € 1.99 - mashed_broccoli: Broccolipuree (100% groente) € 1.99 - baby_spinach: Babyspinazie € 0.99 - salad_mix: Slamix € 0.99 - iceberg_lettuce: IJsbergsla € 0.99 - cherry_tomatoes: Kerstomaten € 0.99 - black_olives: Zwarte olijven € 0.50 - white_onion: Witte ui € 0.50 - red_onion: Rode ui € 0.50 - bell_pepper: Paprika € 0.50 - corn: Maïs € 0.50 - edamame_beans: Edamamebonen € 0.50 - radish: Radijs € 0.50 - cucumber: Komkommer € 0.50 - flaxseed: Lijnzaad € 0.50 - sesame_seeds: Sesamzaad € 0.50 - pumpkin_seeds: Pompoenzaad € 0.50 - -dish vegan_avocado_spring: Vegan avocado spring -- Gekruide tempeh, quinoa, avocado, rode ui, komkommer, kerstomaten, babyspinazie, lijnzaad, vegan spicy dressing - single_choice bowl_wrap - single_choice size - single_choice veggie_on_vegan_dish - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs +# Veggie/vegan dish sunset_beach: Sunset beach -- Tofu, bruine rijst, slamix, Fitchens currydressing single_choice bowl_wrap single_choice size - single_choice veggie_on_veggie_dish - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs - -dish vegan_fitalian: Vegan fitalian -- Babyspinazie, volkorenpasta, vegan tomatensaus, tofu, kerstomaten, vegan kaas - single_choice bowl_wrap - single_choice size - single_choice veggie_on_vegan_dish - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs dish hot_tempeh: Hot tempeh -- Gekruide tempeh, quinoa, slamix, Fitchens spicy dressing single_choice bowl_wrap single_choice size - single_choice veggie_on_veggie_dish - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs -dish indian_summer: Indian summer -- Kip, bruine rijst, slamix, Fitchens currydressing +dish vegan_avocado_spring: Vegan avocado spring -- Gekruide tempeh, quinoa, avocado, rode ui, komkommer, kerstomaten, babyspinazie, lijnzaad, vegan spicy dressing + single_choice bowl_wrap + single_choice size + +dish vegan_healthy_wave: Vegan healthy wave -- Tofu, quinoa, mango, edamamebonen, avocado, zwarte bonen, kerstomaten, ijsbergsla, vegan notendressing, pindakruimels + single_choice bowl_wrap + single_choice size + + +# Kip +dish avocado_chick: Avocado chick -- Kip, zoete aardappel, ijsbergsla, paprika, avocado, parmezaan, maïs, Fitchens mosterddressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs dish spicy_chicken: Spicy chicken -- Kip, quinoa, slamix, Fitchens spicy dressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs -dish avocado_chick: Avocado chick -- Kip, zoete aardappel, ijsbergsla, paprika, avocado, parmezaan, maïs, Fitchens mosterddressing +dish indian_summer: Indian summer -- Kip, bruine rijst, slamix, Fitchens currydressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs dish olive_garden: Olive garden -- Kip, volkorenpasta, babyspinazie, kerstomaten, parmezaan, zwarte olijven, Fitchens basilicum-pestodressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs +dish healthy_wave: Vegan healthy wave -- Kip, quinoa, mango, edamamebonen, avocado, zwarte bonen, kerstomaten, ijsbergsla, vegan notendressing, pindakruimels + single_choice bowl_wrap + single_choice size + + +# Rund dish spicy_mexican: Spicy Mexican -- Mager rundvlees, quinoa, ijsbergsla, avocado, parmezaan, maïs, paprika, Fitchens spicy dressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs - -dish fitalian: Fitalian -- Mager rundvlees, volkorenpasta, tomatensaus met groenten, parmezaan, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs - -dish iron_man: Iron man -- Mager rundvlees, volkorenpasta, kerstomaten, parmezaan, zwarte olijven, babyspinazie, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs dish beefcake: Beefcake -- Mager rundvlees, zoete aardappel, slamix, Fitchens mosterddressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs + +dish iron_man: Iron man -- Mager rundvlees, volkorenpasta, kerstomaten, parmezaan, zwarte olijven, babyspinazie, Fitchens basilicum-pestodressing + single_choice bowl_wrap + single_choice size + + +# Vis +dish captain: Captain -- Gerookte zalm, volkorenpasta, witte ui, babyspinazie, kerstomaten, Fitchens basilicum-pestodressing + single_choice bowl_wrap + single_choice size dish slim_fish: Slim fish -- Gerookte zalm, bruine rijst, babyspinazie, radijs, edamamebonen, komkommer, maïs, avocado, sesamzaad, Fitchens spicy dressing single_choice bowl_wrap single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs - -dish captain: Captain -- Gerookte zalm, volkorenpasta, witte ui, babyspinazie, kerstomaten, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - single_choice veggie - multi_choice extra_dressing - multi_choice extra_carbs - multi_choice extra_protein - multi_choice extra_vegs -- 2.43.4 From 65ed818875b285f4d47a536c320b732aaf75c7d7 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 14 Aug 2020 04:57:02 +0200 Subject: [PATCH 076/197] Start redesign of order page --- app/app.py | 1 + app/models/order.py | 55 ++- app/models/orderitem.py | 5 +- app/static/css/main.css | 76 ++-- app/static/css/themes/plain_lightmode.css | 12 +- app/templates/order.html | 488 ++++++++++++++++------ app/templates/order_items.html | 10 +- app/templates/utils.html | 2 +- app/utils.py | 6 +- app/views/order.py | 17 +- 10 files changed, 446 insertions(+), 226 deletions(-) diff --git a/app/app.py b/app/app.py index 1a3dd98..1070142 100755 --- a/app/app.py +++ b/app/app.py @@ -171,6 +171,7 @@ def add_template_filters(app: Flask) -> None: app.template_filter("euro")(euro_string) app.template_filter("price_range")(price_range_string) app.template_filter("any")(any) + app.template_filter("all")(all) app = Flask(__name__) diff --git a/app/models/order.py b/app/models/order.py index 6ad5b5f..705470f 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -44,35 +44,48 @@ class Order(db.Model): ), "location_id must be configured before updating from HLDS" self.location_name = self.location.name - def group_by_user(self) -> typing.Dict[str, typing.Any]: + def for_user(self, anon=None, user=None) -> typing.List: + return list( + filter( + (lambda i: i.user == user) + if user is not None + else (lambda i: i.user_name == anon), + self.items + ) + ) + + def group_by_user(self) -> typing.List[typing.Tuple[str, typing.List]]: "Group items of an Order by user" - group: typing.Dict[str, typing.Any] = dict() + group: typing.Dict[str, typing.List] = dict() + for item in self.items: - user = group.get(item.get_name(), dict()) - user["total"] = user.get("total", 0) + item.price - user["to_pay"] = user.get("to_pay", 0) + item.price if not item.paid else 0 - user["paid"] = user.get("paid", True) and item.paid - user["dishes"] = user.get("dishes", []) + [item.dish_name] - group[str(item.get_name())] = user + if item.for_name not in group: + group[item.for_name] = [] - return group + group[item.for_name].append(item) - def group_by_dish( - self, sort_comments=False - ) -> typing.Dict[str, typing.Dict[str, typing.Any]]: + for _user_name, order_items in group.items(): + order_items.sort(key=lambda order_item: order_item.comment or "") + + return list(sorted(group.items())) + + def group_by_dish(self) -> typing.List[typing.Tuple[str, typing.List]]: "Group items of an Order by dish" - group: typing.Dict[str, typing.Dict[str, typing.Any]] = dict() + group: typing.Dict[str, typing.List] = dict() + for item in self.items: - dish = group.get(item.dish_name, dict()) - dish["count"] = dish.get("count", 0) + 1 - dish["comments"] = dish.get("comments", []) + [item.comment] - group[item.dish_name] = dish + if item.dish_name not in group: + group[item.dish_name] = [] - if sort_comments: - for _dish_name, dish_props in group.items(): - dish_props["comments"].sort() + group[item.dish_name].append(item) - return group + for _dish_name, order_items in group.items(): + order_items.sort(key=lambda order_item: ( + (order_item.comment or " No comment") + + (order_item.for_name) + )) + + return list(sorted(group.items())) def is_closed(self) -> bool: return self.stoptime and datetime.now() > self.stoptime diff --git a/app/models/orderitem.py b/app/models/orderitem.py index a078086..253cd85 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -37,7 +37,8 @@ class OrderItem(db.Model): raise ValueError("No Location found with id: " + location_id) raise AttributeError() - def get_name(self) -> str: + @property + def for_name(self) -> str: "Get the name of the user which 'owns' the item" if self.user_id is not None and self.user_id > 0: return self.user.username @@ -46,7 +47,7 @@ class OrderItem(db.Model): def __repr__(self) -> str: return "Order %d: %s wants %s" % ( self.order_id or 0, - self.get_name(), + self.for_name, self.dish_name or "None", ) diff --git a/app/static/css/main.css b/app/static/css/main.css index d5dc8b6..2fd83df 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -1,16 +1,15 @@ -/* Custom CSS */ :root { - /*Darkmode colors*/ - --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; - --FontFamily:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; - --FontSize:13px; + /* Darkmode colors */ + --dGray0: #D0D0D8; + --dGray1: #8E8E93; + --dGray2: #636366; + --dGray3: #48484A; + --dGray4: #3A3A3C; + --dGray5: #2C2C2E; + --dGray6: #1C1C1E; + --dBlue: #0A84FF; + --FontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; + --FontSize: 13px; } html { @@ -26,7 +25,7 @@ body { font-size: var(--FontSize); } -.background{ +.background { position: absolute; z-index: -1000; top: 0; @@ -47,12 +46,6 @@ body { padding-top: 10px; } -.darker { - background-color: #fafafa; - margin-top: 10px; - padding-bottom: 5px; -} - @media (min-width: 992px) { .align-bottom { margin-top: 2.5em; @@ -121,10 +114,6 @@ body { margin-top: 1.3em; } -.order_row { - background: var(--dGray4); -} - .time_data{ display: flex; justify-content: space-between; @@ -144,14 +133,6 @@ body { } } -/* Add clickable box */ -div.box:hover { - cursor: hand; - cursor: pointer; - opacity: .9; - box-shadow: 2px 4px 4px -1px #888888; -} - a.divLink { position: absolute; width: 100%; @@ -198,18 +179,25 @@ a { .navbar { background-color: var(--dGray6); } -.navbar-default .navbar-nav .active a{ - background-color: var(--dGray4); +.navbar-default .navbar-nav .active a { + background-color: var(--dGray5); color: var(--dGray1); } -.navbar-default .navbar-nav .active a:hover{ - background-color: var(--dGray3); +.navbar-default .navbar-nav .active a:hover, +.navbar-default .navbar-nav .active a:focus, +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + background-color: var(--dGray4); color: var(--dGray0); } -.navbar-default .navbar-nav li a,.navbar-default .navbar-brand{ +.navbar-default .navbar-nav li a, +.navbar-default .navbar-brand { color: var(--dGray1); } -.navbar-default .navbar-nav li a:hover,.navbar-default .navbar-brand:hover{ +.navbar-default .navbar-nav li a:hover, +.navbar-default .navbar-nav li a:focus, +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { color: var(--dGray0); } hr{ @@ -220,9 +208,16 @@ h1, h2, h3, h4, h5, h6{ color: var(--dGray1); } -.jumbotron, .darker { - background-color: var(--dGray4); +.jumbotron, .darker, .order_row { + background: var(--dGray4); } + +.darker { + margin-top: 10px; + padding-top: 5px; + padding-bottom: 5px; +} + .table tbody tr td { border-top: 1px solid var(--dGray3); } @@ -287,9 +282,6 @@ h1, h2, h3, h4, h5, h6{ .form-control::placeholder{ color: var(--dGray2); } -.enter_darkmode>a { - text-align: center; -} #dish_choices { margin: 0.5em 1em 1.5em; diff --git a/app/static/css/themes/plain_lightmode.css b/app/static/css/themes/plain_lightmode.css index 4713231..cb6baf7 100644 --- a/app/static/css/themes/plain_lightmode.css +++ b/app/static/css/themes/plain_lightmode.css @@ -1,10 +1,10 @@ :root { - --dGray0:#444444; - --dGray1:#666666; - --dGray2:#212121; - --dGray3:#ffffff; - --dGray4:#f9f9f9; - --dGray5:#ffffff; + --dGray0:#212121; + --dGray1:#444444; + --dGray2:#666666; + --dGray3:#cccccc; + --dGray4:#f1f1f1; + --dGray5:#f8f8f8; --dGray6:#ffffff; --dBlue:#0A84FF; } diff --git a/app/templates/order.html b/app/templates/order.html index 25a3f8a..2cbfc65 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -1,82 +1,123 @@ {% extends "layout.html" %} {% set active_page = "orders" -%} -{% set order_items = order.group_by_user() -%} +{% if current_user.is_anonymous() %} + {% set my_items = order.for_user(anon=session.get("anon_name", "")) %} +{% else %} + {% set my_items = order.for_user(user=current_user) %} +{% endif %} {% set courier_or_admin = not current_user.is_anonymous() and (current_user.is_admin() or current_user.id == order.courier_id) -%} {% import "utils.html" as util %} {% block container %} -
-
-

Order {{ order.id }} -
- {% if order.can_close(current_user.id) -%} - - - - {% endif %}{% if courier_or_admin %} - Edit - {%- endif %} -

- courier: {{ order.courier.username }} - {% if order.courier == None and not current_user.is_anonymous() %} -
- - - {% endif %} -
- location: {% if order.location %} +
+

Order {{ order.id }}

+ +
+ {% if order.location %} {{ order.location_name }} {% else %} {{ order.location_name }} - {% endif %}
- {% if order.location.telephone != None %} - telephone: {{ order.location.telephone }}
{% endif %} - start: {{ order.starttime.strftime("%d/%m/%Y %H:%M") }}
- {% if order.stoptime %} - closing time: {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) - {% else %}open{% endif %}
- total price: {{ total_price|euro }} {% if courier_or_admin %}- remaining debts: {{ debts|euro }}{% endif %}
- {% if form -%} -
-

Order

+
+ +
+
+

Order information

+
+
Location
+
+ {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
+ +
Delivery at
+
+ Zeuskelder TODO +
+ +
Courier
+
+ {% if order.courier == None %} + {% if not current_user.is_anonymous() %} +
+ + + {% else %}No-one{% endif %} + {% else %} + {{ order.courier.username }} + {% endif %} +
+ +
+
+
Opens
+
{{ order.starttime.strftime("%d/%m/%Y %H:%M") }}
+ +
Closes
+
+ {% if order.stoptime %} + {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) + {% else %} + Never + {% endif %} +
+
+ +
+ {% if order.can_close(current_user.id) -%} +
+ + + {% endif %} + {% if courier_or_admin %} + Edit + {%- endif %} +
+
{% if form %}
+

Add item to order

+
- - Choose for me - {{ form.csrf_token }} + +
- {{ form.dish_id.label(class='control-label') }}
+ {{ form.dish_id.label }}
{{ form.dish_id(class='form-control select') }} {{ util.render_form_field_errors(form.dish_id) }}
-
{% if dish and dish.choices %} - {% for (choice_type, choice) in dish.choices %} -
-
- -
- {% endfor %} + {% for (choice_type, choice) in dish.choices %} +
+
+ +
+ {% endfor %} {% endif %}
- {{ form.comment.label(class='control-label') }}
+ {{ form.comment.label }}
{{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} {{ util.render_form_field_errors(form.comment) }}
@@ -89,98 +130,165 @@
{% endif %}
+ Random + {{ form.submit_button(class='btn btn-primary') }} {% if not dish %}
If the chosen dish has options, they will be shown when you press submit, before adding the item to the order.
{% endif %}
-
- {%- endif %} -
-
-
-

Items

-
").append(a("").attr("data-action","today").append(a("").addClass(d.icons.today)))),!d.sideBySide&&z()&&y()&&b.push(a("").append(a("").attr("data-action","togglePicker").append(a("").addClass(d.icons.time)))),d.showClear&&b.push(a("").append(a("").attr("data-action","clear").append(a("").addClass(d.icons.clear)))),d.showClose&&b.push(a("").append(a("").attr("data-action","close").append(a("").addClass(d.icons.close)))),a("").addClass("table-condensed").append(a("").append(a("").append(b)))},E=function(){var b=a("
").addClass("bootstrap-datetimepicker-widget dropdown-menu"),c=a("
").addClass("datepicker").append(A()),e=a("
").addClass("timepicker").append(C()),g=a("
    ").addClass("list-unstyled"),h=a("
  • ").addClass("picker-switch"+(d.collapse?" accordion-toggle":"")).append(D());return d.inline&&b.removeClass("dropdown-menu"),f&&b.addClass("usetwentyfour"),d.sideBySide&&z()&&y()?(b.addClass("timepicker-sbs"),b.append(a("
    ").addClass("row").append(c.addClass("col-sm-6")).append(e.addClass("col-sm-6"))),b.append(h),b):("top"===d.toolbarPlacement&&g.append(h),z()&&g.append(a("
  • ").addClass(d.collapse&&y()?"collapse in":"").append(c)),"default"===d.toolbarPlacement&&g.append(h),y()&&g.append(a("
  • ").addClass(d.collapse&&z()?"collapse":"").append(e)),"bottom"===d.toolbarPlacement&&g.append(h),b.append(g))},F=function(){var b,e={};return b=c.is("input")||d.inline?c.data():c.find("input").data(),b.dateOptions&&b.dateOptions instanceof Object&&(e=a.extend(!0,e,b.dateOptions)),a.each(d,function(a){var c="date"+a.charAt(0).toUpperCase()+a.slice(1);void 0!==b[c]&&(e[a]=b[c])}),e},G=function(){var b,e=(n||c).position(),f=(n||c).offset(),g=d.widgetPositioning.vertical,h=d.widgetPositioning.horizontal;if(d.widgetParent)b=d.widgetParent.append(o);else if(c.is("input"))b=c.parent().append(o);else{if(d.inline)return void(b=c.append(o));b=c,c.children().first().after(o)}if("auto"===g&&(g=f.top+1.5*o.height()>=a(window).height()+a(window).scrollTop()&&o.height()+c.outerHeight()a(window).width()?"right":"left"),"top"===g?o.addClass("top").removeClass("bottom"):o.addClass("bottom").removeClass("top"),"right"===h?o.addClass("pull-right"):o.removeClass("pull-right"),"relative"!==b.css("position")&&(b=b.parents().filter(function(){return"relative"===a(this).css("position")}).first()),0===b.length)throw new Error("datetimepicker component should be placed within a relative positioned container");o.css({top:"top"===g?"auto":e.top+c.outerHeight(),bottom:"top"===g?e.top+c.outerHeight():"auto",left:"left"===h?b.css("padding-left"):"auto",right:"left"===h?"auto":b.width()-c.outerWidth()})},H=function(a){"dp.change"===a.type&&(a.date&&a.date.isSame(a.oldDate)||!a.date&&!a.oldDate)||c.trigger(a)},I=function(a){o&&(a&&(i=Math.max(p,Math.min(2,i+a))),o.find(".datepicker > div").hide().filter(".datepicker-"+q[i].clsName).show())},J=function(){var b=a("
"),c=l.clone().startOf("w");for(d.calendarWeeks===!0&&b.append(a(""),d.calendarWeeks&&e.append('"),i.push(e)),f="",c.isBefore(l,"M")&&(f+=" old"),c.isAfter(l,"M")&&(f+=" new"),c.isSame(k,"d")&&!m&&(f+=" active"),M(c,"d")||(f+=" disabled"),c.isSame(b(),"d")&&(f+=" today"),(0===c.day()||6===c.day())&&(f+=" weekend"),e.append('"),c.add(1,"d");g.find("tbody").empty().append(i),O(),P()}},R=function(){var b=o.find(".timepicker-hours table"),c=l.clone().startOf("d"),d=[],e=a("");for(l.hour()>11&&!f&&c.hour(12);c.isSame(l,"d")&&(f||l.hour()<12&&c.hour()<12||l.hour()>11);)c.hour()%4===0&&(e=a(""),d.push(e)),e.append('"),c.add(1,"h");b.empty().append(d)},S=function(){for(var b=o.find(".timepicker-minutes table"),c=l.clone().startOf("h"),e=[],f=a(""),g=1===d.stepping?5:d.stepping;l.isSame(c,"h");)c.minute()%(4*g)===0&&(f=a(""),e.push(f)),f.append('"),c.add(g,"m");b.empty().append(e)},T=function(){for(var b=o.find(".timepicker-seconds table"),c=l.clone().startOf("m"),d=[],e=a("");l.isSame(c,"m");)c.second()%20===0&&(e=a(""),d.push(e)),e.append('"),c.add(5,"s");b.empty().append(d)},U=function(){var a=o.find(".timepicker span[data-time-component]");f||o.find(".timepicker [data-action=togglePeriod]").text(k.format("A")),a.filter("[data-time-component=hours]").text(k.format(f?"HH":"hh")),a.filter("[data-time-component=minutes]").text(k.format("mm")),a.filter("[data-time-component=seconds]").text(k.format("ss")),R(),S(),T()},V=function(){o&&(Q(),U())},W=function(a){var b=m?null:k;return a?(a=a.clone().locale(d.locale),1!==d.stepping&&a.minutes(Math.round(a.minutes()/d.stepping)*d.stepping%60).seconds(0),void(M(a)?(k=a,l=k.clone(),e.val(k.format(g)),c.data("date",k.format(g)),V(),m=!1,H({type:"dp.change",date:k.clone(),oldDate:b})):(d.keepInvalid||e.val(m?"":k.format(g)),H({type:"dp.error",date:a})))):(m=!0,e.val(""),c.data("date",""),H({type:"dp.change",date:null,oldDate:b}),void V())},X=function(){var b=!1;return o?(o.find(".collapse").each(function(){var c=a(this).data("collapse");return c&&c.transitioning?(b=!0,!1):!0}),b?j:(n&&n.hasClass("btn")&&n.toggleClass("active"),o.hide(),a(window).off("resize",G),o.off("click","[data-action]"),o.off("mousedown",!1),o.remove(),o=!1,H({type:"dp.hide",date:k.clone()}),j)):j},Y=function(){W(null)},Z={next:function(){l.add(q[i].navStep,q[i].navFnc),Q()},previous:function(){l.subtract(q[i].navStep,q[i].navFnc),Q()},pickerSwitch:function(){I(1)},selectMonth:function(b){var c=a(b.target).closest("tbody").find("span").index(a(b.target));l.month(c),i===p?(W(k.clone().year(l.year()).month(l.month())),d.inline||X()):(I(-1),Q())},selectYear:function(b){var c=parseInt(a(b.target).text(),10)||0;l.year(c),i===p?(W(k.clone().year(l.year())),d.inline||X()):(I(-1),Q())},selectDay:function(b){var c=l.clone();a(b.target).is(".old")&&c.subtract(1,"M"),a(b.target).is(".new")&&c.add(1,"M"),W(c.date(parseInt(a(b.target).text(),10))),y()||d.keepOpen||d.inline||X()},incrementHours:function(){W(k.clone().add(1,"h"))},incrementMinutes:function(){W(k.clone().add(d.stepping,"m"))},incrementSeconds:function(){W(k.clone().add(1,"s"))},decrementHours:function(){W(k.clone().subtract(1,"h"))},decrementMinutes:function(){W(k.clone().subtract(d.stepping,"m"))},decrementSeconds:function(){W(k.clone().subtract(1,"s"))},togglePeriod:function(){W(k.clone().add(k.hours()>=12?-12:12,"h"))},togglePicker:function(b){var c,e=a(b.target),f=e.closest("ul"),g=f.find(".in"),h=f.find(".collapse:not(.in)");if(g&&g.length){if(c=g.data("collapse"),c&&c.transitioning)return;g.collapse?(g.collapse("hide"),h.collapse("show")):(g.removeClass("in"),h.addClass("in")),e.is("span")?e.toggleClass(d.icons.time+" "+d.icons.date):e.find("span").toggleClass(d.icons.time+" "+d.icons.date)}},showPicker:function(){o.find(".timepicker > div:not(.timepicker-picker)").hide(),o.find(".timepicker .timepicker-picker").show()},showHours:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-hours").show()},showMinutes:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-minutes").show()},showSeconds:function(){o.find(".timepicker .timepicker-picker").hide(),o.find(".timepicker .timepicker-seconds").show()},selectHour:function(b){var c=parseInt(a(b.target).text(),10);f||(k.hours()>=12?12!==c&&(c+=12):12===c&&(c=0)),W(k.clone().hours(c)),Z.showPicker.call(j)},selectMinute:function(b){W(k.clone().minutes(parseInt(a(b.target).text(),10))),Z.showPicker.call(j)},selectSecond:function(b){W(k.clone().seconds(parseInt(a(b.target).text(),10))),Z.showPicker.call(j)},clear:Y,today:function(){W(b())},close:X},$=function(b){return a(b.currentTarget).is(".disabled")?!1:(Z[a(b.currentTarget).data("action")].apply(j,arguments),!1)},_=function(){var c,f={year:function(a){return a.month(0).date(1).hours(0).seconds(0).minutes(0)},month:function(a){return a.date(1).hours(0).seconds(0).minutes(0)},day:function(a){return a.hours(0).seconds(0).minutes(0)},hour:function(a){return a.seconds(0).minutes(0)},minute:function(a){return a.seconds(0)}};return e.prop("disabled")||!d.ignoreReadonly&&e.prop("readonly")||o?j:(d.useCurrent&&m&&(e.is("input")&&0===e.val().trim().length||d.inline)&&(c=b(),"string"==typeof d.useCurrent&&(c=f[d.useCurrent](c)),W(c)),o=E(),J(),N(),o.find(".timepicker-hours").hide(),o.find(".timepicker-minutes").hide(),o.find(".timepicker-seconds").hide(),V(),I(),a(window).on("resize",G),o.on("click","[data-action]",$),o.on("mousedown",!1),n&&n.hasClass("btn")&&n.toggleClass("active"),o.show(),G(),e.is(":focus")||e.focus(),H({type:"dp.show"}),j)},ab=function(){return o?X():_()},bb=function(a){return a=b.isMoment(a)||a instanceof Date?b(a):b(a,h,d.useStrict),a.locale(d.locale),a},cb=function(a){var b,c,e,f,g=null,h=[],i={},k=a.which,l="p";w[k]=l;for(b in w)w.hasOwnProperty(b)&&w[b]===l&&(h.push(b),parseInt(b,10)!==k&&(i[b]=!0));for(b in d.keyBinds)if(d.keyBinds.hasOwnProperty(b)&&"function"==typeof d.keyBinds[b]&&(e=b.split(" "),e.length===h.length&&v[k]===e[e.length-1])){for(f=!0,c=e.length-2;c>=0;c--)if(!(v[e[c]]in i)){f=!1;break}if(f){g=d.keyBinds[b];break}}g&&(g.call(j,o),a.stopPropagation(),a.preventDefault())},db=function(a){w[a.which]="r",a.stopPropagation(),a.preventDefault()},eb=function(b){var c=a(b.target).val().trim(),d=c?bb(c):null;return W(d),b.stopImmediatePropagation(),!1},fb=function(){e.on({change:eb,blur:d.debug?"":X,keydown:cb,keyup:db}),c.is("input")?e.on({focus:_}):n&&(n.on("click",ab),n.on("mousedown",!1))},gb=function(){e.off({change:eb,blur:X,keydown:cb,keyup:db}),c.is("input")?e.off({focus:_}):n&&(n.off("click",ab),n.off("mousedown",!1))},hb=function(b){var c={};return a.each(b,function(){var a=bb(this);a.isValid()&&(c[a.format("YYYY-MM-DD")]=!0)}),Object.keys(c).length?c:!1},ib=function(){var a=d.format||"L LT";g=a.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){var b=k.localeData().longDateFormat(a)||a;return b.replace(/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,function(a){return k.localeData().longDateFormat(a)||a})}),h=d.extraFormats?d.extraFormats.slice():[],h.indexOf(a)<0&&h.indexOf(g)<0&&h.push(g),f=g.toLowerCase().indexOf("a")<1&&g.indexOf("h")<1,x("y")&&(p=2),x("M")&&(p=1),x("d")&&(p=0),i=Math.max(p,i),m||W(k)};if(j.destroy=function(){X(),gb(),c.removeData("DateTimePicker"),c.removeData("date")},j.toggle=ab,j.show=_,j.hide=X,j.disable=function(){return X(),n&&n.hasClass("btn")&&n.addClass("disabled"),e.prop("disabled",!0),j},j.enable=function(){return n&&n.hasClass("btn")&&n.removeClass("disabled"),e.prop("disabled",!1),j},j.ignoreReadonly=function(a){if(0===arguments.length)return d.ignoreReadonly;if("boolean"!=typeof a)throw new TypeError("ignoreReadonly () expects a boolean parameter");return d.ignoreReadonly=a,j},j.options=function(b){if(0===arguments.length)return a.extend(!0,{},d);if(!(b instanceof Object))throw new TypeError("options() options parameter should be an object");return a.extend(!0,d,b),a.each(d,function(a,b){if(void 0===j[a])throw new TypeError("option "+a+" is not recognized!");j[a](b)}),j},j.date=function(a){if(0===arguments.length)return m?null:k.clone();if(!(null===a||"string"==typeof a||b.isMoment(a)||a instanceof Date))throw new TypeError("date() parameter must be one of [null, string, moment or Date]");return W(null===a?null:bb(a)),j},j.format=function(a){if(0===arguments.length)return d.format;if("string"!=typeof a&&("boolean"!=typeof a||a!==!1))throw new TypeError("format() expects a sting or boolean:false parameter "+a);return d.format=a,g&&ib(),j},j.dayViewHeaderFormat=function(a){if(0===arguments.length)return d.dayViewHeaderFormat;if("string"!=typeof a)throw new TypeError("dayViewHeaderFormat() expects a string parameter");return d.dayViewHeaderFormat=a,j},j.extraFormats=function(a){if(0===arguments.length)return d.extraFormats;if(a!==!1&&!(a instanceof Array))throw new TypeError("extraFormats() expects an array or false parameter");return d.extraFormats=a,h&&ib(),j},j.disabledDates=function(b){if(0===arguments.length)return d.disabledDates?a.extend({},d.disabledDates):d.disabledDates;if(!b)return d.disabledDates=!1,V(),j;if(!(b instanceof Array))throw new TypeError("disabledDates() expects an array parameter");return d.disabledDates=hb(b),d.enabledDates=!1,V(),j},j.enabledDates=function(b){if(0===arguments.length)return d.enabledDates?a.extend({},d.enabledDates):d.enabledDates;if(!b)return d.enabledDates=!1,V(),j;if(!(b instanceof Array))throw new TypeError("enabledDates() expects an array parameter");return d.enabledDates=hb(b),d.disabledDates=!1,V(),j},j.daysOfWeekDisabled=function(a){if(0===arguments.length)return d.daysOfWeekDisabled.splice(0);if(!(a instanceof Array))throw new TypeError("daysOfWeekDisabled() expects an array parameter");return d.daysOfWeekDisabled=a.reduce(function(a,b){return b=parseInt(b,10),b>6||0>b||isNaN(b)?a:(-1===a.indexOf(b)&&a.push(b),a)},[]).sort(),V(),j},j.maxDate=function(a){if(0===arguments.length)return d.maxDate?d.maxDate.clone():d.maxDate;if("boolean"==typeof a&&a===!1)return d.maxDate=!1,V(),j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("maxDate() Could not parse date parameter: "+a);if(d.minDate&&c.isBefore(d.minDate))throw new TypeError("maxDate() date parameter is before options.minDate: "+c.format(g));return d.maxDate=c,d.maxDate.isBefore(a)&&W(d.maxDate),l.isAfter(c)&&(l=c.clone()),V(),j},j.minDate=function(a){if(0===arguments.length)return d.minDate?d.minDate.clone():d.minDate;if("boolean"==typeof a&&a===!1)return d.minDate=!1,V(),j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("minDate() Could not parse date parameter: "+a);if(d.maxDate&&c.isAfter(d.maxDate))throw new TypeError("minDate() date parameter is after options.maxDate: "+c.format(g));return d.minDate=c,d.minDate.isAfter(a)&&W(d.minDate),l.isBefore(c)&&(l=c.clone()),V(),j},j.defaultDate=function(a){if(0===arguments.length)return d.defaultDate?d.defaultDate.clone():d.defaultDate;if(!a)return d.defaultDate=!1,j;"string"==typeof a&&("now"===a||"moment"===a)&&(a=b());var c=bb(a);if(!c.isValid())throw new TypeError("defaultDate() Could not parse date parameter: "+a);if(!M(c))throw new TypeError("defaultDate() date passed is invalid according to component setup validations");return d.defaultDate=c,d.defaultDate&&""===e.val().trim()&&void 0===e.attr("placeholder")&&W(d.defaultDate),j},j.locale=function(a){if(0===arguments.length)return d.locale;if(!b.localeData(a))throw new TypeError("locale() locale "+a+" is not loaded from moment locales!");return d.locale=a,k.locale(d.locale),l.locale(d.locale),g&&ib(),o&&(X(),_()),j},j.stepping=function(a){return 0===arguments.length?d.stepping:(a=parseInt(a,10),(isNaN(a)||1>a)&&(a=1),d.stepping=a,j)},j.useCurrent=function(a){var b=["year","month","day","hour","minute"];if(0===arguments.length)return d.useCurrent;if("boolean"!=typeof a&&"string"!=typeof a)throw new TypeError("useCurrent() expects a boolean or string parameter");if("string"==typeof a&&-1===b.indexOf(a.toLowerCase()))throw new TypeError("useCurrent() expects a string parameter of "+b.join(", "));return d.useCurrent=a,j},j.collapse=function(a){if(0===arguments.length)return d.collapse;if("boolean"!=typeof a)throw new TypeError("collapse() expects a boolean parameter");return d.collapse===a?j:(d.collapse=a,o&&(X(),_()),j)},j.icons=function(b){if(0===arguments.length)return a.extend({},d.icons);if(!(b instanceof Object))throw new TypeError("icons() expects parameter to be an Object");return a.extend(d.icons,b),o&&(X(),_()),j},j.useStrict=function(a){if(0===arguments.length)return d.useStrict;if("boolean"!=typeof a)throw new TypeError("useStrict() expects a boolean parameter");return d.useStrict=a,j},j.sideBySide=function(a){if(0===arguments.length)return d.sideBySide;if("boolean"!=typeof a)throw new TypeError("sideBySide() expects a boolean parameter");return d.sideBySide=a,o&&(X(),_()),j},j.viewMode=function(a){if(0===arguments.length)return d.viewMode;if("string"!=typeof a)throw new TypeError("viewMode() expects a string parameter");if(-1===r.indexOf(a))throw new TypeError("viewMode() parameter must be one of ("+r.join(", ")+") value");return d.viewMode=a,i=Math.max(r.indexOf(a),p),I(),j},j.toolbarPlacement=function(a){if(0===arguments.length)return d.toolbarPlacement;if("string"!=typeof a)throw new TypeError("toolbarPlacement() expects a string parameter");if(-1===u.indexOf(a))throw new TypeError("toolbarPlacement() parameter must be one of ("+u.join(", ")+") value");return d.toolbarPlacement=a,o&&(X(),_()),j},j.widgetPositioning=function(b){if(0===arguments.length)return a.extend({},d.widgetPositioning);if("[object Object]"!=={}.toString.call(b))throw new TypeError("widgetPositioning() expects an object variable");if(b.horizontal){if("string"!=typeof b.horizontal)throw new TypeError("widgetPositioning() horizontal variable must be a string");if(b.horizontal=b.horizontal.toLowerCase(),-1===t.indexOf(b.horizontal))throw new TypeError("widgetPositioning() expects horizontal parameter to be one of ("+t.join(", ")+")");d.widgetPositioning.horizontal=b.horizontal}if(b.vertical){if("string"!=typeof b.vertical)throw new TypeError("widgetPositioning() vertical variable must be a string");if(b.vertical=b.vertical.toLowerCase(),-1===s.indexOf(b.vertical))throw new TypeError("widgetPositioning() expects vertical parameter to be one of ("+s.join(", ")+")");d.widgetPositioning.vertical=b.vertical}return V(),j},j.calendarWeeks=function(a){if(0===arguments.length)return d.calendarWeeks;if("boolean"!=typeof a)throw new TypeError("calendarWeeks() expects parameter to be a boolean value");return d.calendarWeeks=a,V(),j},j.showTodayButton=function(a){if(0===arguments.length)return d.showTodayButton;if("boolean"!=typeof a)throw new TypeError("showTodayButton() expects a boolean parameter");return d.showTodayButton=a,o&&(X(),_()),j},j.showClear=function(a){if(0===arguments.length)return d.showClear;if("boolean"!=typeof a)throw new TypeError("showClear() expects a boolean parameter");return d.showClear=a,o&&(X(),_()),j},j.widgetParent=function(b){if(0===arguments.length)return d.widgetParent;if("string"==typeof b&&(b=a(b)),null!==b&&"string"!=typeof b&&!(b instanceof a))throw new TypeError("widgetParent() expects a string or a jQuery object parameter");return d.widgetParent=b,o&&(X(),_()),j},j.keepOpen=function(a){if(0===arguments.length)return d.keepOpen;if("boolean"!=typeof a)throw new TypeError("keepOpen() expects a boolean parameter");return d.keepOpen=a,j},j.inline=function(a){if(0===arguments.length)return d.inline;if("boolean"!=typeof a)throw new TypeError("inline() expects a boolean parameter");return d.inline=a,j},j.clear=function(){return Y(),j},j.keyBinds=function(a){return d.keyBinds=a,j},j.debug=function(a){if("boolean"!=typeof a)throw new TypeError("debug() expects a boolean parameter");return d.debug=a,j},j.showClose=function(a){if(0===arguments.length)return d.showClose;if("boolean"!=typeof a)throw new TypeError("showClose() expects a boolean parameter");return d.showClose=a,j},j.keepInvalid=function(a){if(0===arguments.length)return d.keepInvalid;if("boolean"!=typeof a)throw new TypeError("keepInvalid() expects a boolean parameter");return d.keepInvalid=a,j},j.datepickerInput=function(a){if(0===arguments.length)return d.datepickerInput;if("string"!=typeof a)throw new TypeError("datepickerInput() expects a string parameter");return d.datepickerInput=a,j},c.is("input"))e=c;else if(e=c.find(d.datepickerInput),0===e.size())e=c.find("input");else if(!e.is("input"))throw new Error('CSS class "'+d.datepickerInput+'" cannot be applied to non input element');if(c.hasClass("input-group")&&(n=c.find(0===c.find(".datepickerbutton").size()?'[class^="input-group-"]':".datepickerbutton")),!d.inline&&!e.is("input"))throw new Error("Could not initialize DateTimePicker without an input element");return a.extend(!0,d,F()),j.options(d),ib(),fb(),e.prop("disabled")&&j.disable(),e.is("input")&&0!==e.val().trim().length?W(bb(e.val().trim())):d.defaultDate&&void 0===e.attr("placeholder")&&W(d.defaultDate),d.inline&&_(),j};a.fn.datetimepicker=function(b){return this.each(function(){var d=a(this);d.data("DateTimePicker")||(b=a.extend(!0,{},a.fn.datetimepicker.defaults,b),d.data("DateTimePicker",c(d,b)))})},a.fn.datetimepicker.defaults={format:!1,dayViewHeaderFormat:"MMMM YYYY",extraFormats:!1,stepping:1,minDate:!1,maxDate:!1,useCurrent:!0,collapse:!0,locale:b.locale(),defaultDate:!1,disabledDates:!1,enabledDates:!1,icons:{time:"glyphicon glyphicon-time",date:"glyphicon glyphicon-calendar",up:"glyphicon glyphicon-chevron-up",down:"glyphicon glyphicon-chevron-down",previous:"glyphicon glyphicon-chevron-left",next:"glyphicon glyphicon-chevron-right",today:"glyphicon glyphicon-screenshot",clear:"glyphicon glyphicon-trash",close:"glyphicon glyphicon-remove"},useStrict:!1,sideBySide:!1,daysOfWeekDisabled:[],calendarWeeks:!1,viewMode:"days",toolbarPlacement:"default",showTodayButton:!1,showClear:!1,showClose:!1,widgetPositioning:{horizontal:"auto",vertical:"auto"},widgetParent:null,ignoreReadonly:!1,keepOpen:!1,inline:!1,keepInvalid:!1,datepickerInput:".datepickerinput",keyBinds:{up:function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().subtract(7,"d"):c.clone().add(1,"m"))}},down:function(a){if(!a)return void this.show();var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().add(7,"d"):c.clone().subtract(1,"m"))},"control up":function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().subtract(1,"y"):c.clone().add(1,"h"))}},"control down":function(a){if(a){var c=this.date()||b();this.date(a.find(".datepicker").is(":visible")?c.clone().add(1,"y"):c.clone().subtract(1,"h"))}},left:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().subtract(1,"d"))}},right:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().add(1,"d"))}},pageUp:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().subtract(1,"M"))}},pageDown:function(a){if(a){var c=this.date()||b();a.find(".datepicker").is(":visible")&&this.date(c.clone().add(1,"M"))}},enter:function(){this.hide()},escape:function(){this.hide()},"control space":function(a){a.find(".timepicker").is(":visible")&&a.find('.btn[data-action="togglePeriod"]').click()},t:function(){this.date(b())},"delete":function(){this.clear()}},debug:!1}}); diff --git a/app/static/js/bootstrap.min.js b/app/static/js/bootstrap.min.js index c8f82e5..fabb33c 100644 --- a/app/static/js/bootstrap.min.js +++ b/app/static/js/bootstrap.min.js @@ -1,7 +1,7 @@ /*! - * Bootstrap v3.3.4 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ +* Bootstrap v3.3.4 (http://getbootstrap.com) +* Copyright 2011-2015 Twitter, Inc. +* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) +*/ if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.4",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.4",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.4",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.4",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.4",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport),this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-mp.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.4",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.4",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file +var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.4",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a(document.body).height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); diff --git a/app/static/js/customThemes.js b/app/static/js/customThemes.js index 9737685..a605f26 100644 --- a/app/static/js/customThemes.js +++ b/app/static/js/customThemes.js @@ -1,11 +1,11 @@ function changeTheme() { - // Get the selected theme for the dropdown - var themes_select = document.getElementById("themes_select"); - var selected_theme = themes_select.options[themes_select.selectedIndex].text; + // Get the selected theme for the dropdown + var themes_select = document.getElementById("themes_select"); + var selected_theme = themes_select.options[themes_select.selectedIndex].text; - // Update the theme cookie - document.cookie = "theme=" + escape(selected_theme) + "; Path=/;" - - // Finally reload the page to let the new theme take effect - location.reload(); -} \ No newline at end of file + // Update the theme cookie + document.cookie = "theme=" + escape(selected_theme) + "; Path=/;" + + // Finally reload the page to let the new theme take effect + location.reload(); +} diff --git a/app/static/js/leaflet.js b/app/static/js/leaflet.js index 576a90e..033424d 100644 --- a/app/static/js/leaflet.js +++ b/app/static/js/leaflet.js @@ -1,5 +1,5 @@ /* @preserve - * Leaflet 1.4.0+Detached: 3337f36d2a2d2b33946779057619b31f674ff5dc.3337f36, a JS library for interactive maps. http://leafletjs.com - * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade - */ -!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e=0}function A(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function I(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(te,n,!1):"touchmove"===i?t.removeEventListener(ie,n,!1):"touchend"===i&&(t.removeEventListener(ee,n,!1),t.removeEventListener(ne,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(oe.indexOf(t.target.tagName)<0))return;Pt(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(te,o,!1),re||(document.documentElement.addEventListener(te,R,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,D,!0),document.documentElement.addEventListener(ne,D,!0),re=!0)}function R(t){se[t.pointerId]=t,ae++}function N(t){se[t.pointerId]&&(se[t.pointerId]=t)}function D(t){delete se[t.pointerId],ae--}function j(t,i){t.touches=[];for(var e in se)t.touches.push(se[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(ie,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ee,n,!1),t.addEventListener(ne,n,!1)}function F(t,i,e){function n(t){var i;if(Vi){if(!bi||"mouse"===t.pointerType)return;i=ae}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Vi){if(!bi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[le+he+e]=n,t[le+ue+e]=o,t[le+"dblclick"+e]=i,t.addEventListener(he,n,!1),t.addEventListener(ue,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[le+he+i],n=t[le+ue+i],o=t[le+"dblclick"+i];return t.removeEventListener(he,e,!1),t.removeEventListener(ue,n,!1),bi||t.removeEventListener("dblclick",o,!1),this}function V(t){return"string"==typeof t?document.getElementById(t):t}function q(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function G(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function K(t){var i=t.parentNode;i&&i.removeChild(t)}function Y(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function X(t){var i=t.parentNode;i&&i.lastChild!==t&&i.appendChild(t)}function J(t){var i=t.parentNode;i&&i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function $(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=et(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function Q(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;n100&&n<500||t.target._simulatedClick&&!t._simulated?Lt(t):(ge=e,i(t))}function Zt(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=At(t,e),t=kt(t,e)}function Et(t,i,e){return Math.sqrt(Dt(t,i,e,!0))}function kt(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8Array:Array)(e);n[0]=n[e-1]=1,Bt(t,n,i,0,e-1);var o,s=[];for(o=0;oh&&(s=r,h=a);h>e&&(i[s]=1,Bt(t,i,e,n,s),Bt(t,i,e,s,o))}function At(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;ni&&(e.push(t[n]),o=n);return oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function Nt(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Dt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function jt(t){return!oi(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Wt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),jt(t)}function Ht(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=_i(this.x),this.y=_i(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng1,Xi=!!document.createElement("canvas").getContext,Ji=!(!document.createElementNS||!E("svg").createSVGRect),$i=!Ji&&function(){try{var t=document.createElement("div");t.innerHTML='';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),Qi=(Object.freeze||Object)({ie:Pi,ielt9:Li,edge:bi,webkit:Ti,android:zi,android23:Mi,androidStock:Si,opera:Zi,chrome:Ei,gecko:ki,safari:Bi,phantom:Ai,opera12:Ii,win:Oi,ie3d:Ri,webkit3d:Ni,gecko3d:Di,any3d:ji,mobile:Wi,mobileWebkit:Hi,mobileWebkit3d:Fi,msPointer:Ui,pointer:Vi,touch:qi,mobileOpera:Gi,mobileGecko:Ki,retina:Yi,canvas:Xi,svg:Ji,vml:$i}),te=Ui?"MSPointerDown":"pointerdown",ie=Ui?"MSPointerMove":"pointermove",ee=Ui?"MSPointerUp":"pointerup",ne=Ui?"MSPointerCancel":"pointercancel",oe=["INPUT","SELECT","OPTION"],se={},re=!1,ae=0,he=Ui?"MSPointerDown":Vi?"pointerdown":"touchstart",ue=Ui?"MSPointerUp":Vi?"pointerup":"touchend",le="_leaflet_",ce=st(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),_e=st(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===_e||"OTransition"===_e?_e+"End":"transitionend";if("onselectstart"in document)fi=function(){mt(window,"selectstart",Pt)},gi=function(){ft(window,"selectstart",Pt)};else{var pe=st(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);fi=function(){if(pe){var t=document.documentElement.style;vi=t[pe],t[pe]="none"}},gi=function(){pe&&(document.documentElement.style[pe]=vi,vi=void 0)}}var me,fe,ge,ve=(Object.freeze||Object)({TRANSFORM:ce,TRANSITION:_e,TRANSITION_END:de,get:V,getStyle:q,create:G,remove:K,empty:Y,toFront:X,toBack:J,hasClass:$,addClass:Q,removeClass:tt,setClass:it,getClass:et,setOpacity:nt,testProp:st,setTransform:rt,setPosition:at,getPosition:ht,disableTextSelection:fi,enableTextSelection:gi,disableImageDrag:ut,enableImageDrag:lt,preventOutline:ct,restoreOutline:_t,getSizedParentNode:dt,getScale:pt}),ye="_leaflet_events",xe=Oi&&Ei?2*window.devicePixelRatio:ki?window.devicePixelRatio:1,we={},Pe=(Object.freeze||Object)({on:mt,off:ft,stopPropagation:yt,disableScrollPropagation:xt,disableClickPropagation:wt,preventDefault:Pt,stop:Lt,getMousePosition:bt,getWheelDelta:Tt,fakeStop:zt,skipped:Mt,isExternalTarget:Ct,addListener:mt,removeListener:ft}),Le=ci.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=ht(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;ithis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e=w((i=i||{}).paddingTopLeft||i.padding||[0,0]),n=w(i.paddingBottomRight||i.padding||[0,0]),o=this.getCenter(),s=this.project(o),r=this.project(t),a=this.getPixelBounds(),h=a.getSize().divideBy(2),u=b([a.min.add(e),a.max.subtract(n)]);if(!u.contains(r)){this._enforcingBounds=!0;var l=s.subtract(r),c=w(r.x+l.x,r.y+l.y);(r.xu.max.x)&&(c.x=s.x-l.x,l.x>0?c.x+=h.x-e.x:c.x-=h.x-n.x),(r.yu.max.y)&&(c.y=s.y-l.y,l.y>0?c.y+=h.y-e.y:c.y-=h.y-n.y),this.panTo(this.unproject(c),i),this._enforcingBounds=!1}return this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(2*t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),K(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(g(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)K(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=G("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=ji?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return bt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=V(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");mt(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&ji,Q(t,"leaflet-container"+(qi?" leaflet-touch":"")+(Yi?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(Bi?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=q(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),at(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(Q(t.markerPane,"leaflet-zoom-hide"),Q(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){at(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){at(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?ft:mt;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),ji&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!Ct(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!Ct(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!Mt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||ct(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&Pt(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=ji?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){tt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=G("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=ce,e=this._proxy.style[i];rt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();rt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){K(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,Q(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&tt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Te=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return Q(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(K(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),ze=function(t){return new Te(t)};be.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=G("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=G("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)K(this._controlCorners[t]);K(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Me=Te.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),mt(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),Ce=Te.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=G("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=G("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),wt(s),mt(s,"click",Lt),mt(s,"click",o,this),mt(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";tt(this._zoomInButton,i),tt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&Q(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&Q(this._zoomInButton,i)}});be.mergeOptions({zoomControl:!0}),be.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new Ce,this.addControl(this.zoomControl))});var Se=Te.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=G("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=G("div",i,e)),t.imperial&&(this._iScale=G("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ze=Te.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=G("div","leaflet-control-attribution"),wt(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});be.mergeOptions({attributionControl:!0}),be.addInitHook(function(){this.options.attributionControl&&(new Ze).addTo(this)});Te.Layers=Me,Te.Zoom=Ce,Te.Scale=Se,Te.Attribution=Ze,ze.layers=function(t,i,e){return new Me(t,i,e)},ze.zoom=function(t){return new Ce(t)},ze.scale=function(t){return new Se(t)},ze.attribution=function(t){return new Ze(t)};var Ee=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ee.addTo=function(t,i){return t.addHandler(i,this),this};var ke,Be={Events:li},Ae=qi?"touchstart mousedown":"mousedown",Ie={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Oe={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Re=ci.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(mt(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Re._dragging===this&&this.finishDrag(),ft(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!$(this._element,"leaflet-zoom-anim")&&!(Re._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Re._dragging=this,this._preventOutline&&ct(this._element),ut(),fi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t,e=dt(this._element);this._startPoint=new x(i.clientX,i.clientY),this._parentScale=pt(e),mt(document,Oe[t.type],this._onMove,this),mt(document,Ie[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY)._subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},He=(Object.freeze||Object)({LonLat:je,Mercator:We,SphericalMercator:mi}),Fe=i({},pi,{code:"EPSG:3395",projection:We,transformation:function(){var t=.5/(Math.PI*We.R);return Z(t,.5,-t,.5)}()}),Ue=i({},pi,{code:"EPSG:4326",projection:je,transformation:Z(1/180,1,-1/180,.5)}),Ve=i({},di,{projection:je,transformation:Z(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});di.Earth=pi,di.EPSG3395=Fe,di.EPSG3857=yi,di.EPSG900913=xi,di.EPSG4326=Ue,di.Simple=Ve;var qe=ci.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});be.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?oi(t)?t:[t]:[]).length;ithis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return jt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=jt(t),n=0,o=t.length;n=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){nn.prototype._setLatLngs.call(this,t),jt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return jt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;ot.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||nn.prototype._containsPoint.call(this,t,!0)}}),sn=Ke.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=oi(t)?t:t.features;if(o){for(i=0,e=o.length;i0?o:[i.src]}else{oi(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;ao?(i.height=o+"px",Q(t,"leaflet-popup-scrolled")):tt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();at(this._container,i.add(e))},_adjustPan:function(){if(this.options.autoPan){this._map._panAnim&&this._map._panAnim.stop();var t=this._map,i=parseInt(q(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(ht(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Lt(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});be.mergeOptions({closePopupOnClick:!0}),be.include({openPopup:function(t,i,e){return t instanceof cn||(t=new cn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),qe.include({bindPopup:function(t,i){return t instanceof cn?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new cn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof qe||(i=t,t=this),t instanceof Ke)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Lt(t),i instanceof Qe?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var _n=ln.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){ln.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){ln.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=ln.prototype.getEvents.call(this);return qi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=G("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||en&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1this.options.maxZoom||void 0!==this.options.minZoom&&o1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_e.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(K(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){Q(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&nt(t,this.options.opacity),zi&&!Mi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),at(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(nt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(Q(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),mn=pn.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Yi&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),zi||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url===t&&void 0===i&&(i=!0),this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return mt(n,"load",e(this._tileOnLoad,this,i,n)),mt(n,"error",e(this._tileOnError,this,i,n)),(this.options.crossOrigin||""===this.options.crossOrigin)&&(n.crossOrigin=!0===this.options.crossOrigin?"":this.options.crossOrigin),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Yi?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=si,K(i),delete this._tiles[t]))},_removeTile:function(t){var i=this._tiles[t];if(i)return Si||i.el.setAttribute("src",si),pn.prototype._removeTile.call(this,t)},_tileReady:function(t,i,e){if(this._map&&(!e||e.getAttribute("src")!==si))return pn.prototype._tileReady.call(this,t,i,e)}}),fn=mn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Yi?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,mn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===Ue?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=mn.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});mn.WMS=fn,Jt.wms=function(t,i){return new fn(t,i)};var gn=qe.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&Q(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=ht(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);ji?rt(this._container,a,e):at(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),vn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){gn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");mt(t,"mousemove",o(this._onMouseMove,32,this),this),mt(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),mt(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){g(this._redrawRequest),delete this._ctx,K(this._container),ft(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Yi?2:1;at(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Yi&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){gn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,o=i.prev;e?e.prev=o:this._drawLast=o,o?o.next=e:this._drawFirst=e,delete t._order,delete this._layers[n(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if("string"==typeof t.options.dashArray){var i,e,n=t.options.dashArray.split(/[, ]+/),o=[];for(e=0;e')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),xn={_initContainer:function(){this._container=G("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(gn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=yn("shape");Q(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=yn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;K(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=yn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=oi(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=yn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){X(t._container)},_bringToBack:function(t){J(t._container)}},wn=$i?yn:E,Pn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=wn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=wn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){K(this._container),ft(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),at(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=wn("path");t.options.className&&Q(i,t.options.className),t.options.interactive&&Q(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){K(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){X(t._path)},_bringToBack:function(t){J(t._path)}});$i&&Pn.include(xn),be.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this._createRenderer()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&$t(t)||Qt(t)}});var Ln=on.extend({initialize:function(t,i){on.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Pn.create=wn,Pn.pointsToPath=k,sn.geometryToLayer=Ft,sn.coordsToLatLng=Ut,sn.coordsToLatLngs=Vt,sn.latLngToCoords=qt,sn.latLngsToCoords=Gt,sn.getFeature=Kt,sn.asFeature=Yt,be.mergeOptions({boxZoom:!0});var bn=Ee.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){mt(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){ft(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){K(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),fi(),ut(),this._startPoint=this._map.mouseEventToContainerPoint(t),mt(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=G("div","leaflet-zoom-box",this._container),Q(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();at(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(K(this._box),tt(this._container,"leaflet-crosshair")),gi(),lt(),ft(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});be.addInitHook("addHandler","boxZoom",bn),be.mergeOptions({doubleClickZoom:!0});var Tn=Ee.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});be.addInitHook("addHandler","doubleClickZoom",Tn),be.mergeOptions({dragging:!0,inertia:!Mi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var zn=Ee.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Re(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}Q(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){tt(this._map._container,"leaflet-grab"),tt(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.xi.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});be.addInitHook("addHandler","scrollWheelZoom",Cn),be.mergeOptions({tap:!0,tapTolerance:15});var Sn=Ee.extend({addHooks:function(){mt(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){ft(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(Pt(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&Q(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),mt(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),ft(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&tt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});qi&&!Vi&&be.addInitHook("addHandler","tap",Sn),be.mergeOptions({touchZoom:qi&&!Mi,bounceAtZoomLimits:!0});var Zn=Ee.extend({addHooks:function(){Q(this._map._container,"leaflet-touch-zoom"),mt(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){tt(this._map._container,"leaflet-touch-zoom"),ft(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),mt(document,"touchmove",this._onTouchMove,this),mt(document,"touchend",this._onTouchEnd,this),Pt(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoomi.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),Pt(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),ft(document,"touchmove",this._onTouchMove),ft(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});be.addInitHook("addHandler","touchZoom",Zn),be.BoxZoom=bn,be.DoubleClickZoom=Tn,be.Drag=zn,be.Keyboard=Mn,be.ScrollWheelZoom=Cn,be.Tap=Sn,be.TouchZoom=Zn,Object.freeze=ti,t.version="1.4.0+HEAD.3337f36",t.Control=Te,t.control=ze,t.Browser=Qi,t.Evented=ci,t.Mixin=Be,t.Util=ui,t.Class=v,t.Handler=Ee,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=Pe,t.DomUtil=ve,t.PosAnimation=Le,t.Draggable=Re,t.LineUtil=Ne,t.PolyUtil=De,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=S,t.transformation=Z,t.Projection=He,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=di,t.GeoJSON=sn,t.geoJSON=Xt,t.geoJson=an,t.Layer=qe,t.LayerGroup=Ge,t.layerGroup=function(t,i){return new Ge(t,i)},t.FeatureGroup=Ke,t.featureGroup=function(t){return new Ke(t)},t.ImageOverlay=hn,t.imageOverlay=function(t,i,e){return new hn(t,i,e)},t.VideoOverlay=un,t.videoOverlay=function(t,i,e){return new un(t,i,e)},t.DivOverlay=ln,t.Popup=cn,t.popup=function(t,i){return new cn(t,i)},t.Tooltip=_n,t.tooltip=function(t,i){return new _n(t,i)},t.Icon=Ye,t.icon=function(t){return new Ye(t)},t.DivIcon=dn,t.divIcon=function(t){return new dn(t)},t.Marker=$e,t.marker=function(t,i){return new $e(t,i)},t.TileLayer=mn,t.tileLayer=Jt,t.GridLayer=pn,t.gridLayer=function(t){return new pn(t)},t.SVG=Pn,t.svg=Qt,t.Renderer=gn,t.Canvas=vn,t.canvas=$t,t.Path=Qe,t.CircleMarker=tn,t.circleMarker=function(t,i){return new tn(t,i)},t.Circle=en,t.circle=function(t,i,e){return new en(t,i,e)},t.Polyline=nn,t.polyline=function(t,i){return new nn(t,i)},t.Polygon=on,t.polygon=function(t,i){return new on(t,i)},t.Rectangle=Ln,t.rectangle=function(t,i){return new Ln(t,i)},t.Map=be,t.map=function(t,i){return new be(t,i)};var En=window.L;t.noConflict=function(){return window.L=En,this},window.L=t}); \ No newline at end of file +* Leaflet 1.4.0+Detached: 3337f36d2a2d2b33946779057619b31f674ff5dc.3337f36, a JS library for interactive maps. http://leafletjs.com +* (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade +*/ +!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e=0}function A(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function I(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(te,n,!1):"touchmove"===i?t.removeEventListener(ie,n,!1):"touchend"===i&&(t.removeEventListener(ee,n,!1),t.removeEventListener(ne,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(oe.indexOf(t.target.tagName)<0))return;Pt(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(te,o,!1),re||(document.documentElement.addEventListener(te,R,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,D,!0),document.documentElement.addEventListener(ne,D,!0),re=!0)}function R(t){se[t.pointerId]=t,ae++}function N(t){se[t.pointerId]&&(se[t.pointerId]=t)}function D(t){delete se[t.pointerId],ae--}function j(t,i){t.touches=[];for(var e in se)t.touches.push(se[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(ie,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ee,n,!1),t.addEventListener(ne,n,!1)}function F(t,i,e){function n(t){var i;if(Vi){if(!bi||"mouse"===t.pointerType)return;i=ae}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Vi){if(!bi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[le+he+e]=n,t[le+ue+e]=o,t[le+"dblclick"+e]=i,t.addEventListener(he,n,!1),t.addEventListener(ue,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[le+he+i],n=t[le+ue+i],o=t[le+"dblclick"+i];return t.removeEventListener(he,e,!1),t.removeEventListener(ue,n,!1),bi||t.removeEventListener("dblclick",o,!1),this}function V(t){return"string"==typeof t?document.getElementById(t):t}function q(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function G(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function K(t){var i=t.parentNode;i&&i.removeChild(t)}function Y(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function X(t){var i=t.parentNode;i&&i.lastChild!==t&&i.appendChild(t)}function J(t){var i=t.parentNode;i&&i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function $(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=et(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function Q(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;n100&&n<500||t.target._simulatedClick&&!t._simulated?Lt(t):(ge=e,i(t))}function Zt(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=At(t,e),t=kt(t,e)}function Et(t,i,e){return Math.sqrt(Dt(t,i,e,!0))}function kt(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8Array:Array)(e);n[0]=n[e-1]=1,Bt(t,n,i,0,e-1);var o,s=[];for(o=0;oh&&(s=r,h=a);h>e&&(i[s]=1,Bt(t,i,e,n,s),Bt(t,i,e,s,o))}function At(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;ni&&(e.push(t[n]),o=n);return oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function Nt(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Dt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function jt(t){return!oi(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Wt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),jt(t)}function Ht(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=_i(this.x),this.y=_i(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng1,Xi=!!document.createElement("canvas").getContext,Ji=!(!document.createElementNS||!E("svg").createSVGRect),$i=!Ji&&function(){try{var t=document.createElement("div");t.innerHTML='';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),Qi=(Object.freeze||Object)({ie:Pi,ielt9:Li,edge:bi,webkit:Ti,android:zi,android23:Mi,androidStock:Si,opera:Zi,chrome:Ei,gecko:ki,safari:Bi,phantom:Ai,opera12:Ii,win:Oi,ie3d:Ri,webkit3d:Ni,gecko3d:Di,any3d:ji,mobile:Wi,mobileWebkit:Hi,mobileWebkit3d:Fi,msPointer:Ui,pointer:Vi,touch:qi,mobileOpera:Gi,mobileGecko:Ki,retina:Yi,canvas:Xi,svg:Ji,vml:$i}),te=Ui?"MSPointerDown":"pointerdown",ie=Ui?"MSPointerMove":"pointermove",ee=Ui?"MSPointerUp":"pointerup",ne=Ui?"MSPointerCancel":"pointercancel",oe=["INPUT","SELECT","OPTION"],se={},re=!1,ae=0,he=Ui?"MSPointerDown":Vi?"pointerdown":"touchstart",ue=Ui?"MSPointerUp":Vi?"pointerup":"touchend",le="_leaflet_",ce=st(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),_e=st(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===_e||"OTransition"===_e?_e+"End":"transitionend";if("onselectstart"in document)fi=function(){mt(window,"selectstart",Pt)},gi=function(){ft(window,"selectstart",Pt)};else{var pe=st(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);fi=function(){if(pe){var t=document.documentElement.style;vi=t[pe],t[pe]="none"}},gi=function(){pe&&(document.documentElement.style[pe]=vi,vi=void 0)}}var me,fe,ge,ve=(Object.freeze||Object)({TRANSFORM:ce,TRANSITION:_e,TRANSITION_END:de,get:V,getStyle:q,create:G,remove:K,empty:Y,toFront:X,toBack:J,hasClass:$,addClass:Q,removeClass:tt,setClass:it,getClass:et,setOpacity:nt,testProp:st,setTransform:rt,setPosition:at,getPosition:ht,disableTextSelection:fi,enableTextSelection:gi,disableImageDrag:ut,enableImageDrag:lt,preventOutline:ct,restoreOutline:_t,getSizedParentNode:dt,getScale:pt}),ye="_leaflet_events",xe=Oi&&Ei?2*window.devicePixelRatio:ki?window.devicePixelRatio:1,we={},Pe=(Object.freeze||Object)({on:mt,off:ft,stopPropagation:yt,disableScrollPropagation:xt,disableClickPropagation:wt,preventDefault:Pt,stop:Lt,getMousePosition:bt,getWheelDelta:Tt,fakeStop:zt,skipped:Mt,isExternalTarget:Ct,addListener:mt,removeListener:ft}),Le=ci.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=ht(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;ithis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e=w((i=i||{}).paddingTopLeft||i.padding||[0,0]),n=w(i.paddingBottomRight||i.padding||[0,0]),o=this.getCenter(),s=this.project(o),r=this.project(t),a=this.getPixelBounds(),h=a.getSize().divideBy(2),u=b([a.min.add(e),a.max.subtract(n)]);if(!u.contains(r)){this._enforcingBounds=!0;var l=s.subtract(r),c=w(r.x+l.x,r.y+l.y);(r.xu.max.x)&&(c.x=s.x-l.x,l.x>0?c.x+=h.x-e.x:c.x-=h.x-n.x),(r.yu.max.y)&&(c.y=s.y-l.y,l.y>0?c.y+=h.y-e.y:c.y-=h.y-n.y),this.panTo(this.unproject(c),i),this._enforcingBounds=!1}return this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(2*t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),K(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(g(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)K(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=G("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=ji?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return bt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=V(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");mt(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&ji,Q(t,"leaflet-container"+(qi?" leaflet-touch":"")+(Yi?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(Bi?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=q(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),at(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(Q(t.markerPane,"leaflet-zoom-hide"),Q(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){at(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){at(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?ft:mt;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),ji&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!Ct(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!Ct(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!Mt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||ct(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&Pt(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=ji?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){tt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=G("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=ce,e=this._proxy.style[i];rt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();rt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){K(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,Q(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&tt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Te=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return Q(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(K(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),ze=function(t){return new Te(t)};be.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=G("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=G("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)K(this._controlCorners[t]);K(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Me=Te.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),mt(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),Ce=Te.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=G("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=G("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),wt(s),mt(s,"click",Lt),mt(s,"click",o,this),mt(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";tt(this._zoomInButton,i),tt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&Q(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&Q(this._zoomInButton,i)}});be.mergeOptions({zoomControl:!0}),be.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new Ce,this.addControl(this.zoomControl))});var Se=Te.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=G("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=G("div",i,e)),t.imperial&&(this._iScale=G("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ze=Te.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=G("div","leaflet-control-attribution"),wt(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});be.mergeOptions({attributionControl:!0}),be.addInitHook(function(){this.options.attributionControl&&(new Ze).addTo(this)});Te.Layers=Me,Te.Zoom=Ce,Te.Scale=Se,Te.Attribution=Ze,ze.layers=function(t,i,e){return new Me(t,i,e)},ze.zoom=function(t){return new Ce(t)},ze.scale=function(t){return new Se(t)},ze.attribution=function(t){return new Ze(t)};var Ee=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ee.addTo=function(t,i){return t.addHandler(i,this),this};var ke,Be={Events:li},Ae=qi?"touchstart mousedown":"mousedown",Ie={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Oe={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Re=ci.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(mt(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Re._dragging===this&&this.finishDrag(),ft(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!$(this._element,"leaflet-zoom-anim")&&!(Re._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Re._dragging=this,this._preventOutline&&ct(this._element),ut(),fi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t,e=dt(this._element);this._startPoint=new x(i.clientX,i.clientY),this._parentScale=pt(e),mt(document,Oe[t.type],this._onMove,this),mt(document,Ie[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY)._subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},He=(Object.freeze||Object)({LonLat:je,Mercator:We,SphericalMercator:mi}),Fe=i({},pi,{code:"EPSG:3395",projection:We,transformation:function(){var t=.5/(Math.PI*We.R);return Z(t,.5,-t,.5)}()}),Ue=i({},pi,{code:"EPSG:4326",projection:je,transformation:Z(1/180,1,-1/180,.5)}),Ve=i({},di,{projection:je,transformation:Z(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});di.Earth=pi,di.EPSG3395=Fe,di.EPSG3857=yi,di.EPSG900913=xi,di.EPSG4326=Ue,di.Simple=Ve;var qe=ci.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});be.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?oi(t)?t:[t]:[]).length;ithis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return jt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=jt(t),n=0,o=t.length;n=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){nn.prototype._setLatLngs.call(this,t),jt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return jt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;ot.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||nn.prototype._containsPoint.call(this,t,!0)}}),sn=Ke.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=oi(t)?t:t.features;if(o){for(i=0,e=o.length;i0?o:[i.src]}else{oi(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;ao?(i.height=o+"px",Q(t,"leaflet-popup-scrolled")):tt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();at(this._container,i.add(e))},_adjustPan:function(){if(this.options.autoPan){this._map._panAnim&&this._map._panAnim.stop();var t=this._map,i=parseInt(q(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(ht(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Lt(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});be.mergeOptions({closePopupOnClick:!0}),be.include({openPopup:function(t,i,e){return t instanceof cn||(t=new cn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),qe.include({bindPopup:function(t,i){return t instanceof cn?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new cn(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof qe||(i=t,t=this),t instanceof Ke)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Lt(t),i instanceof Qe?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var _n=ln.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){ln.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){ln.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=ln.prototype.getEvents.call(this);return qi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=G("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||en&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1this.options.maxZoom||void 0!==this.options.minZoom&&o1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_e.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(K(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){Q(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&nt(t,this.options.opacity),zi&&!Mi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),at(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(nt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(Q(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),mn=pn.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Yi&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),zi||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url===t&&void 0===i&&(i=!0),this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return mt(n,"load",e(this._tileOnLoad,this,i,n)),mt(n,"error",e(this._tileOnError,this,i,n)),(this.options.crossOrigin||""===this.options.crossOrigin)&&(n.crossOrigin=!0===this.options.crossOrigin?"":this.options.crossOrigin),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Yi?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=si,K(i),delete this._tiles[t]))},_removeTile:function(t){var i=this._tiles[t];if(i)return Si||i.el.setAttribute("src",si),pn.prototype._removeTile.call(this,t)},_tileReady:function(t,i,e){if(this._map&&(!e||e.getAttribute("src")!==si))return pn.prototype._tileReady.call(this,t,i,e)}}),fn=mn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Yi?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,mn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===Ue?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=mn.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});mn.WMS=fn,Jt.wms=function(t,i){return new fn(t,i)};var gn=qe.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&Q(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=ht(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);ji?rt(this._container,a,e):at(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),vn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){gn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");mt(t,"mousemove",o(this._onMouseMove,32,this),this),mt(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),mt(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){g(this._redrawRequest),delete this._ctx,K(this._container),ft(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Yi?2:1;at(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Yi&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){gn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,o=i.prev;e?e.prev=o:this._drawLast=o,o?o.next=e:this._drawFirst=e,delete t._order,delete this._layers[n(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if("string"==typeof t.options.dashArray){var i,e,n=t.options.dashArray.split(/[, ]+/),o=[];for(e=0;e')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),xn={_initContainer:function(){this._container=G("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(gn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=yn("shape");Q(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=yn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;K(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=yn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=oi(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=yn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){X(t._container)},_bringToBack:function(t){J(t._container)}},wn=$i?yn:E,Pn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=wn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=wn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){K(this._container),ft(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),at(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=wn("path");t.options.className&&Q(i,t.options.className),t.options.interactive&&Q(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){K(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){X(t._path)},_bringToBack:function(t){J(t._path)}});$i&&Pn.include(xn),be.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this._createRenderer()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&$t(t)||Qt(t)}});var Ln=on.extend({initialize:function(t,i){on.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Pn.create=wn,Pn.pointsToPath=k,sn.geometryToLayer=Ft,sn.coordsToLatLng=Ut,sn.coordsToLatLngs=Vt,sn.latLngToCoords=qt,sn.latLngsToCoords=Gt,sn.getFeature=Kt,sn.asFeature=Yt,be.mergeOptions({boxZoom:!0});var bn=Ee.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){mt(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){ft(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){K(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),fi(),ut(),this._startPoint=this._map.mouseEventToContainerPoint(t),mt(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=G("div","leaflet-zoom-box",this._container),Q(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();at(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(K(this._box),tt(this._container,"leaflet-crosshair")),gi(),lt(),ft(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});be.addInitHook("addHandler","boxZoom",bn),be.mergeOptions({doubleClickZoom:!0});var Tn=Ee.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});be.addInitHook("addHandler","doubleClickZoom",Tn),be.mergeOptions({dragging:!0,inertia:!Mi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var zn=Ee.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Re(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}Q(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){tt(this._map._container,"leaflet-grab"),tt(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.xi.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});be.addInitHook("addHandler","scrollWheelZoom",Cn),be.mergeOptions({tap:!0,tapTolerance:15});var Sn=Ee.extend({addHooks:function(){mt(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){ft(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(Pt(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&Q(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),mt(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),ft(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&tt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});qi&&!Vi&&be.addInitHook("addHandler","tap",Sn),be.mergeOptions({touchZoom:qi&&!Mi,bounceAtZoomLimits:!0});var Zn=Ee.extend({addHooks:function(){Q(this._map._container,"leaflet-touch-zoom"),mt(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){tt(this._map._container,"leaflet-touch-zoom"),ft(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),mt(document,"touchmove",this._onTouchMove,this),mt(document,"touchend",this._onTouchEnd,this),Pt(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoomi.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),Pt(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),ft(document,"touchmove",this._onTouchMove),ft(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});be.addInitHook("addHandler","touchZoom",Zn),be.BoxZoom=bn,be.DoubleClickZoom=Tn,be.Drag=zn,be.Keyboard=Mn,be.ScrollWheelZoom=Cn,be.Tap=Sn,be.TouchZoom=Zn,Object.freeze=ti,t.version="1.4.0+HEAD.3337f36",t.Control=Te,t.control=ze,t.Browser=Qi,t.Evented=ci,t.Mixin=Be,t.Util=ui,t.Class=v,t.Handler=Ee,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=Pe,t.DomUtil=ve,t.PosAnimation=Le,t.Draggable=Re,t.LineUtil=Ne,t.PolyUtil=De,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=S,t.transformation=Z,t.Projection=He,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=di,t.GeoJSON=sn,t.geoJSON=Xt,t.geoJson=an,t.Layer=qe,t.LayerGroup=Ge,t.layerGroup=function(t,i){return new Ge(t,i)},t.FeatureGroup=Ke,t.featureGroup=function(t){return new Ke(t)},t.ImageOverlay=hn,t.imageOverlay=function(t,i,e){return new hn(t,i,e)},t.VideoOverlay=un,t.videoOverlay=function(t,i,e){return new un(t,i,e)},t.DivOverlay=ln,t.Popup=cn,t.popup=function(t,i){return new cn(t,i)},t.Tooltip=_n,t.tooltip=function(t,i){return new _n(t,i)},t.Icon=Ye,t.icon=function(t){return new Ye(t)},t.DivIcon=dn,t.divIcon=function(t){return new dn(t)},t.Marker=$e,t.marker=function(t,i){return new $e(t,i)},t.TileLayer=mn,t.tileLayer=Jt,t.GridLayer=pn,t.gridLayer=function(t){return new pn(t)},t.SVG=Pn,t.svg=Qt,t.Renderer=gn,t.Canvas=vn,t.canvas=$t,t.Path=Qe,t.CircleMarker=tn,t.circleMarker=function(t,i){return new tn(t,i)},t.Circle=en,t.circle=function(t,i,e){return new en(t,i,e)},t.Polyline=nn,t.polyline=function(t,i){return new nn(t,i)},t.Polygon=on,t.polygon=function(t,i){return new on(t,i)},t.Rectangle=Ln,t.rectangle=function(t,i){return new Ln(t,i)},t.Map=be,t.map=function(t,i){return new be(t,i)};var En=window.L;t.noConflict=function(){return window.L=En,this},window.L=t}); diff --git a/app/static/js/map.js b/app/static/js/map.js index 18344df..c97776c 100644 --- a/app/static/js/map.js +++ b/app/static/js/map.js @@ -1,69 +1,69 @@ var map = L.map('mapid'); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { - attribution: '© OpenStreetMap contributors' + attribution: '© OpenStreetMap contributors' }).addTo(map); let base_request_uri = "https://photon.komoot.de/api/?limit=1&q="; function performRequest(url, location, success_callback) { - var request = new XMLHttpRequest(); - request.open('GET', url, true); - request.onload = function() { - if (this.status >= 200 && this.status < 400) { - // Success! - var data = JSON.parse(this.response); - success_callback(location, data); - } else { - // We reached our target server, but it returned an error - } - }; - request.onerror = function() { - console.log("Error requestion location coordinates"); - // There was a connection error of some sort - }; - request.send(); + var request = new XMLHttpRequest(); + request.open('GET', url, true); + request.onload = function() { + if (this.status >= 200 && this.status < 400) { + // Success! + var data = JSON.parse(this.response); + success_callback(location, data); + } else { + // We reached our target server, but it returned an error + } + }; + request.onerror = function() { + console.log("Error requestion location coordinates"); + // There was a connection error of some sort + }; + request.send(); } let marker_icon = L.icon({ - iconUrl: "/static/images/marker-icon.png", - shadowUrl: "/static/images/marker-shadow.png", - iconAnchor: [12, 41] + iconUrl: "/static/images/marker-icon.png", + shadowUrl: "/static/images/marker-shadow.png", + iconAnchor: [12, 41] }); let callback = function OSMCallBack(location, data) { - let lat, lon; - if (data.features.length >= 1) { - let place = data.features[0].properties; - lat = data.features[0].geometry.coordinates[1]; - lon = data.features[0].geometry.coordinates[0]; + let lat, lon; + if (data.features.length >= 1) { + let place = data.features[0].properties; + lat = data.features[0].geometry.coordinates[1]; + lon = data.features[0].geometry.coordinates[0]; - let marker = L.marker([lat, lon], { - icon: marker_icon - }).addTo(map) - .bindPopup(location.name + ', ' + location.address, {offset: new L.Point(0, -16)}).on('click', function () { - let win = window.open(location.url, '_blank'); - win.focus(); - }); + let marker = L.marker([lat, lon], { + icon: marker_icon + }).addTo(map) + .bindPopup(location.name + ', ' + location.address, {offset: new L.Point(0, -16)}).on('click', function () { + let win = window.open(location.url, '_blank'); + win.focus(); + }); - marker.on('mouseover', function(env) { - marker.openPopup(); - }); - marker.on('mouseout', function(env) { - marker.closePopup(); - }); + marker.on('mouseover', function(env) { + marker.openPopup(); + }); + marker.on('mouseout', function(env) { + marker.closePopup(); + }); - if (location.center) { - map.setView([lat, lon], 14); - } - } else { - console.log(`Location ${JSON.stringify(location, null, 2)} returned no features, are you sure this is a valid address?`); - } + if (location.center) { + map.setView([lat, lon], 14); + } + } else { + console.log(`Location ${JSON.stringify(location, null, 2)} returned no features, are you sure this is a valid address?`); + } }; function loadmap(locations) { - for (let loc of locations) { - let request_uri = base_request_uri + loc.address; - performRequest(request_uri, loc, callback); - } + for (let loc of locations) { + let request_uri = base_request_uri + loc.address; + performRequest(request_uri, loc, callback); + } } diff --git a/app/static/js/theme.js b/app/static/js/theme.js index c780f1c..9d582a3 100644 --- a/app/static/js/theme.js +++ b/app/static/js/theme.js @@ -1,14 +1,13 @@ - { const init = () =>{ - document.cookie.split('; ').forEach(itCookie = cookie =>{ //I know that this is a shitty way of fixing things... But I'll try to fix it in the future. + document.cookie.split('; ').forEach(itCookie = cookie =>{ // TODO (Arnhoudt) Fix shitty way of doing things if(cookie.split("=")[0] == "theme" && cookie.split("=")[1] == "darkmode"){ document.querySelector(".toggleDarkmode").innerHTML = "Enter lightmode" document.querySelector(".toggleDarkmode").id = "lightmode"; } - + if(cookie.split("=")[0] == "theme" && cookie.split("=")[1] == "customTheme"){ - document.querySelector(".background").innerHTML = '
'; + document.querySelector(".background").innerHTML = '
'; } if(cookie.split("=")[0] == "performance" && cookie.split("=")[1] == "highPerformance" && document.querySelector(".changePerformance")){ document.querySelector(".changePerformance").innerHTML = "enable low performance"; @@ -20,16 +19,16 @@ } const handleClickChangePerformance = e => { - document.cookie = "performance = "+e.currentTarget.id+";path=/"; + document.cookie = "performance = "+e.currentTarget.id+";path=/"; location.reload(); } const handleClickChangeTheme = e =>{ - document.cookie = "theme = "+e.currentTarget.id+";path=/"; + document.cookie = "theme = "+e.currentTarget.id+";path=/"; location.reload(); } - + init(); -} \ No newline at end of file +} diff --git a/app/static/js/timer.js b/app/static/js/timer.js index 05aaca1..127230c 100644 --- a/app/static/js/timer.js +++ b/app/static/js/timer.js @@ -1,36 +1,36 @@ /** - * Created by feliciaan on 30/03/15. - */ +* Created by feliciaan on 30/03/15. +*/ $.ready(function(){ - $('.time').each(function() { - var timeEl = $( this ); - var time = timeEl.text().split(' ')[0].split(':'); + $('.time').each(function() { + var timeEl = $( this ); + var time = timeEl.text().split(' ')[0].split(':'); - if (timeEl.text().indexOf('closed') < 0) { - window.setInterval(function () { - time = my_tick(time); - if (time !== "closed") { - timeS = ("0" + time[0]).slice(-2) + ":" + ("0" + time[1]).slice(-2) + ":" + ("0" + time[2]).slice(-2) + " left"; - } else { - timeS = "closed" - } - timeEl.html(timeS); - }, 1000); - } - }); + if (timeEl.text().indexOf('closed') < 0) { + window.setInterval(function () { + time = my_tick(time); + if (time !== "closed") { + timeS = ("0" + time[0]).slice(-2) + ":" + ("0" + time[1]).slice(-2) + ":" + ("0" + time[2]).slice(-2) + " left"; + } else { + timeS = "closed" + } + timeEl.html(timeS); + }, 1000); + } + }); - function my_tick(time) { - if (time[2] > 0) { - time[2] = time[2] - 1; - } else if(time[1] > 0) { - time[2] = 59; - time[1] = time[1] - 1; - } else if(time[0] > 0) { - time[1] = 59; - time[0] = time[0] - 1; - } else { - return "closed"; - } - return time; - } -}()); \ No newline at end of file + function my_tick(time) { + if (time[2] > 0) { + time[2] = time[2] - 1; + } else if(time[1] > 0) { + time[2] = 59; + time[1] = time[1] - 1; + } else if(time[0] > 0) { + time[1] = 59; + time[0] = time[0] - 1; + } else { + return "closed"; + } + return time; + } +}()); diff --git a/app/templates/about.html b/app/templates/about.html index 3ba431d..b811d72 100644 --- a/app/templates/about.html +++ b/app/templates/about.html @@ -2,6 +2,6 @@ {% set active_page = "about" -%} {% block container %} -

About

-

Haldis is your friendly neighbourhood servant. He exists so lazy fucks like you and me don't need to keep tabs of who is ordering what from where.

+

About

+

Haldis is your friendly neighbourhood servant. He exists so lazy fucks like you and me don't need to keep tabs of who is ordering what from where.

{% endblock %} diff --git a/app/templates/errors/401.html b/app/templates/errors/401.html index ba80436..50ed43a 100644 --- a/app/templates/errors/401.html +++ b/app/templates/errors/401.html @@ -1,9 +1,9 @@ {% extends "layout.html" -%} {% block container %} -
-

Unauthorized

-

You're not authorized to look to this page!

-

Go somewhere nice

-
-{% endblock %} \ No newline at end of file +
+

Unauthorized

+

You're not authorized to look to this page!

+

Go somewhere nice

+
+{% endblock %} diff --git a/app/templates/errors/404.html b/app/templates/errors/404.html index 76437e2..11d79d0 100644 --- a/app/templates/errors/404.html +++ b/app/templates/errors/404.html @@ -1,9 +1,9 @@ {% extends "layout.html" -%} {% block container %} -
-

Page Not Found

-

What you were looking for is just not there.

-

Go somewhere nice

-
-{% endblock %} \ No newline at end of file +
+

Page Not Found

+

What you were looking for is just not there.

+

Go somewhere nice

+
+{% endblock %} diff --git a/app/templates/home.html b/app/templates/home.html index 7940944..b196e4f 100644 --- a/app/templates/home.html +++ b/app/templates/home.html @@ -4,35 +4,35 @@ {% import "utils.html" as util -%} {% block container %} -
-
-

Hi, I'm Haldis

-

What would you like to eat?

-
-
-
-
- {% if orders|count > 0 -%} -

Open orders:

- {% for order in orders %} - {{ util.render_order(order) }} - {% endfor %} - {% else %} -

No orders available.

- {% if not current_user.is_anonymous() %} - To create an order, fill in the form here. - {% else %} - Login to create an order, or ask someone else. - {% endif %} - {%- endif %} -
-
- {% if recently_closed|count > 0 -%} -

Recently closed orders:

- {% for order in recently_closed %} - {{ util.render_order(order) }} - {% endfor %} - {%- endif %} -
-
+
+
+

Hi, I'm Haldis

+

What would you like to eat?

+
+
+
+
+ {% if orders|count > 0 -%} +

Open orders:

+ {% for order in orders %} + {{ util.render_order(order) }} + {% endfor %} + {% else %} +

No orders available.

+ {% if not current_user.is_anonymous() %} + To create an order, fill in the form here. + {% else %} + Login to create an order, or ask someone else. + {% endif %} + {%- endif %} +
+
+ {% if recently_closed|count > 0 -%} +

Recently closed orders:

+ {% for order in recently_closed %} + {{ util.render_order(order) }} + {% endfor %} + {%- endif %} +
+
{% endblock %} diff --git a/app/templates/layout.html b/app/templates/layout.html index 707b9ab..cddb82a 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -2,87 +2,87 @@ {% import "bootstrap/utils.html" as utils %} {% set navbar = [ - ('general_bp.home', 'Home'), - ('order_bp.orders', 'Orders'), - ('general_bp.locations', 'Locations'), - ('general_bp.map_view', 'Map'), - ('general_bp.about', 'About'), - ('stats_blueprint.stats', 'Stats'), + ('general_bp.home', 'Home'), + ('order_bp.orders', 'Orders'), + ('general_bp.locations', 'Locations'), + ('general_bp.map_view', 'Map'), + ('general_bp.about', 'About'), + ('stats_blueprint.stats', 'Stats'), ] -%} {% set active_page = active_page|default('index') -%} {% block title %} Haldis - {{ active_page|capitalize }} - {% if title %} - - {{ title }} - {% endif %} + {% if title %} + - {{ title }} + {% endif %} {% endblock %} {% block styles %} - {{ super() }} - - - + {{ super() }} + + + {% endblock %} {% block scripts %} - {{ super() }} - - - + {{ super() }} + + + {% endblock %} {% block navbar %} -
-
- +
+
+ {% endblock %} {% block content -%} - {{ utils.flashed_messages(container=True) }} + {{ utils.flashed_messages(container=True) }} -
- {% block container -%} - {%- endblock %} -
+
+ {% block container -%} + {%- endblock %} +
- + {%- endblock %} diff --git a/app/templates/location.html b/app/templates/location.html index 9a9560a..2cfa19b 100644 --- a/app/templates/location.html +++ b/app/templates/location.html @@ -5,40 +5,40 @@ {% block container %}
-
-

{{ location.name }}

- {% if location.address %} {{ location.address }}
{% endif %} - {% if location.telephone %}{{ location.telephone }}
{% endif %} - {% if location.website %} {{ location.website }}
{% endif %} - {% if location.osm %} {{ location.osm }}
{% endif %} - {% if not current_user.is_anonymous() %} - Create order - {% endif %} -
-
- {% if location.address %} -
- {% endif %} -
+
+

{{ location.name }}

+ {% if location.address %} {{ location.address }}
{% endif %} + {% if location.telephone %}{{ location.telephone }}
{% endif %} + {% if location.website %} {{ location.website }}
{% endif %} + {% if location.osm %} {{ location.osm }}
{% endif %} + {% if not current_user.is_anonymous() %} + Create order + {% endif %} +
+
+ {% if location.address %} +
+ {% endif %} +
-
-

Products

-
").addClass("cw").text("#"));c.isBefore(l.clone().endOf("w"));)b.append(a("").addClass("dow").text(c.format("dd"))),c.add(1,"d");o.find(".datepicker-days thead").append(b)},K=function(a){return d.disabledDates[a.format("YYYY-MM-DD")]===!0},L=function(a){return d.enabledDates[a.format("YYYY-MM-DD")]===!0},M=function(a,b){return a.isValid()?d.disabledDates&&K(a)&&"M"!==b?!1:d.enabledDates&&!L(a)&&"M"!==b?!1:d.minDate&&a.isBefore(d.minDate,b)?!1:d.maxDate&&a.isAfter(d.maxDate,b)?!1:"d"===b&&-1!==d.daysOfWeekDisabled.indexOf(a.day())?!1:!0:!1},N=function(){for(var b=[],c=l.clone().startOf("y").hour(12);c.isSame(l,"y");)b.push(a("").attr("data-action","selectMonth").addClass("month").text(c.format("MMM"))),c.add(1,"M");o.find(".datepicker-months td").empty().append(b)},O=function(){var b=o.find(".datepicker-months"),c=b.find("th"),d=b.find("tbody").find("span");b.find(".disabled").removeClass("disabled"),M(l.clone().subtract(1,"y"),"y")||c.eq(0).addClass("disabled"),c.eq(1).text(l.year()),M(l.clone().add(1,"y"),"y")||c.eq(2).addClass("disabled"),d.removeClass("active"),k.isSame(l,"y")&&d.eq(k.month()).addClass("active"),d.each(function(b){M(l.clone().month(b),"M")||a(this).addClass("disabled")})},P=function(){var a=o.find(".datepicker-years"),b=a.find("th"),c=l.clone().subtract(5,"y"),e=l.clone().add(6,"y"),f="";for(a.find(".disabled").removeClass("disabled"),d.minDate&&d.minDate.isAfter(c,"y")&&b.eq(0).addClass("disabled"),b.eq(1).text(c.year()+"-"+e.year()),d.maxDate&&d.maxDate.isBefore(e,"y")&&b.eq(2).addClass("disabled");!c.isAfter(e,"y");)f+=''+c.year()+"",c.add(1,"y");a.find("td").html(f)},Q=function(){var c,e,f,g=o.find(".datepicker-days"),h=g.find("th"),i=[];if(z()){for(g.find(".disabled").removeClass("disabled"),h.eq(1).text(l.format(d.dayViewHeaderFormat)),M(l.clone().subtract(1,"M"),"M")||h.eq(0).addClass("disabled"),M(l.clone().add(1,"M"),"M")||h.eq(2).addClass("disabled"),c=l.clone().startOf("M").startOf("week");!l.clone().endOf("M").endOf("w").isBefore(c,"d");)0===c.weekday()&&(e=a("
'+c.week()+"'+c.date()+"
'+c.format(f?"HH":"hh")+"
'+c.format("mm")+"
'+c.format("ss")+"
- - - - - {% for dish in location.dishes -%} - - - - - {%- endfor %} - -
NameDescriptionPrice
{{ dish.name or dish.id }}{{ dish.description or "" }}{{ dish.price|euro }} -
- +
+

Products

+ + + + + + {% for dish in location.dishes -%} + + + + + {%- endfor %} + +
NameDescriptionPrice
{{ dish.name or dish.id }}{{ dish.description or "" }}{{ dish.price|euro }} +
+
{% endblock %} @@ -49,23 +49,19 @@ {% endblock %} {% block scripts %} -{{super()}} +{{ super() }} {% if location.address %} - - - + + + {% endif %} {% endblock %} diff --git a/app/templates/locations.html b/app/templates/locations.html index 03d8c99..0dc7d82 100644 --- a/app/templates/locations.html +++ b/app/templates/locations.html @@ -5,27 +5,27 @@ {% block container %}
-
-

Locations

- - - - - - {% for loc in locations -%} - - - - - - {%- endfor %} - -
NameAddress
{{ loc.name }}{{ loc.address }} - {{ loc.website }} - {% if not current_user.is_anonymous() %} - Create order - {% endif %} -
-
+
+

Locations

+ + + + + + {% for loc in locations -%} + + + + + + {%- endfor %} + +
NameAddress
{{ loc.name }}{{ loc.address }} + {{ loc.website }} + {% if not current_user.is_anonymous() %} + Create order + {% endif %} +
+
{% endblock %} diff --git a/app/templates/maps.html b/app/templates/maps.html index 508a2e2..0b27b3f 100644 --- a/app/templates/maps.html +++ b/app/templates/maps.html @@ -20,23 +20,20 @@ {% endblock %} diff --git a/app/templates/order.html b/app/templates/order.html index cc3bba6..40732b9 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -7,190 +7,200 @@ {% block container %}
-
-

Order {{ order.id }} -
- {% if order.can_close(current_user.id) -%} -
- -
- {% endif %}{% if courier_or_admin %} - Edit - {%- endif %} -

- courier: {{ order.courier.username }} - {% if order.courier == None and not current_user.is_anonymous() %} -
- -
- {% endif %} -
- location: {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %}
- {% if order.location.telephone != None %} - telephone: {{ order.location.telephone }}
- {% endif %} - start: {{ order.starttime.strftime("%d/%m/%Y %H:%M") }}
- {% if order.stoptime %} - closing time: {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) - {% else %}open{% endif %}
- total price: {{ total_price|euro }} {% if courier_or_admin %}- remaining debts: {{ debts|euro }}{% endif %} -
- {% if form -%} -
-

Order:

-
- - Choose for me - - {{ form.csrf_token }} -
- {{ form.dish_id.label(class='control-label') }}
- {{ form.dish_id(class='form-control select') }} - {{ util.render_form_field_errors(form.dish_id) }} -
+
+

Order {{ order.id }} +
+ {% if order.can_close(current_user.id) -%} + + + + {% endif %}{% if courier_or_admin %} + Edit + {%- endif %} +

+ courier: {{ order.courier.username }} + {% if order.courier == None and not current_user.is_anonymous() %} +
+ +
+ {% endif %} +
+ location: {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %}
+ {% if order.location.telephone != None %} + telephone: {{ order.location.telephone }}
+ {% endif %} + start: {{ order.starttime.strftime("%d/%m/%Y %H:%M") }}
+ {% if order.stoptime %} + closing time: {{ order.stoptime.strftime("%H:%M") }} ({{ order.stoptime|countdown }}) + {% else %}open{% endif %}
+ total price: {{ total_price|euro }} {% if courier_or_admin %}- remaining debts: {{ debts|euro }}{% endif %} +
+ {% if form -%} +
+

Order:

+
+ + Choose for me + + {{ form.csrf_token }} +
+ {{ form.dish_id.label(class='control-label') }}
+ {{ form.dish_id(class='form-control select') }} + {{ util.render_form_field_errors(form.dish_id) }} +
- - {% if dish and dish.choices %} - {% for (choice_type, choice) in dish.choices %} -
-
- -
- {% endfor %} - {% endif %} + {% if dish and dish.choices %} + + {% for (choice_type, choice) in dish.choices %} +
+
+ +
+ {% endfor %} + {% endif %} -
- {{ form.comment.label(class='control-label') }}
- {{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} - {{ util.render_form_field_errors(form.comment) }} -
+
+ {{ form.comment.label(class='control-label') }}
+ {{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} + {{ util.render_form_field_errors(form.comment) }} +
- {% if current_user.is_anonymous() %} -
- {{ form.user_name.label(class='control-label') }} - {{ form.user_name(class='form-control', placeholder='Fill in your name...') }} - {{ util.render_form_field_errors(form.user_name) }} -
- {% endif %} -
- {{ form.submit_button(class='btn btn-primary') }} - {% if not dish %} -
If the chosen dish has options, they will be shown when you press submit, before adding the item to the order.
- {% endif %} -
-
-
- {%- endif %} + {% if current_user.is_anonymous() %} +
+ {{ form.user_name.label(class='control-label') }} + {{ form.user_name(class='form-control', placeholder='Fill in your name...') }} + {{ util.render_form_field_errors(form.user_name) }} +
+ {% endif %} +
+ {{ form.submit_button(class='btn btn-primary') }} + {% if not dish %} +
If the chosen dish has options, they will be shown when you press submit, before adding the item to the order.
+ {% endif %} +
+ +
+ {%- endif %}
-
-

Items

- - - {% if courier_or_admin %}{% endif %} - - - {% for item in order.items -%} - - - - - {% if courier_or_admin %} - {% endif %} - - - {%- endfor %} - -
NameItemPricePaid?Delete
{{ item.get_name() }}{{ item.dish_name }}{{ "*" if item.comment }}{{ item.price|euro }}{% if not item.paid %} -
- -
- {% else %} - {% endif %}
{% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} -
- -
- {%- endif %}
-
-
-

Ordered dishes: {{ order.items.count() }}

- - {% for key, value in order.group_by_dish().items() -%} -
- {{ key }}: {{ value["count"] }} - {% if value["comments"]|any -%} -
    - {% for comment in value["comments"] -%} -
  • {% if comment %}{{ comment }} - {% else %}No comment - {% endif %}
  • - {% endfor %} -
- {%- endif %} -
- {%- endfor %} -
+
+

Items

+ + + {% if courier_or_admin %}{% endif %} + + + {% for item in order.items -%} + + + + + {% if courier_or_admin %} + + {% endif %} + + + {%- endfor %} + +
NameItemPricePaid?Delete
{{ item.get_name() }}{{ item.dish_name }}{{ "*" if item.comment }}{{ item.price|euro }} + {% if not item.paid %} +
+ +
+ {% else %} + {% endif %} +
+ {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} +
+ +
+ {%- endif %}
+
+
+

Ordered dishes: {{ order.items.count() }}

+ + {% for key, value in order.group_by_dish().items() -%} +
+ {{ key }}: {{ value["count"] }} + {% if value["comments"]|any -%} +
    + {% for comment in value["comments"] -%} +
  • {% if comment %}{{ comment }} + {% else %}No comment + {% endif %}
  • + {% endfor %} +
+ {%- endif %} +
+ {%- endfor %} +
-
-

Debts

- - - {% if courier_or_admin %}{% endif %} - - - {% for key, value in order_items.items() -%} - - - - - {% if courier_or_admin %}{% endif %} - - {%- endfor %} - -
NameTotalTo payPaid?
{{ key }}{{ value["total"]|euro }}{{ value["to_pay"]|euro }}{% if not value["to_pay"] == 0 %} -
- -
- {% else %} {% endif %}
-
+
+

Debts

+ + + {% if courier_or_admin %}{% endif %} + + + {% for key, value in order_items.items() -%} + + + + + {% if courier_or_admin %} + + {% endif %} + + {%- endfor %} + +
NameTotalTo payPaid?
{{ key }}{{ value["total"]|euro }}{{ value["to_pay"]|euro }} + {% if not value["to_pay"] == 0 %} +
+ +
+ {% else %} + + {% endif %} +
+
{% endblock %} {% block styles %} - {{ super() }} - - - + {{ super() }} + + + {% endblock %} {% block scripts %} - {{ super() }} - - + {{ super() }} + + {% endblock %} diff --git a/app/templates/order_edit.html b/app/templates/order_edit.html index 2f28781..a47cd1d 100644 --- a/app/templates/order_edit.html +++ b/app/templates/order_edit.html @@ -5,76 +5,75 @@ {% import "utils.html" as util -%} {% block container %} -
- {% if not current_user.is_anonymous() %} -
-

Edit order:

-
-
-
- {{ form.csrf_token }} -
- {{ form.courier_id.label(class='control-label') }}
- {{ form.courier_id(class='form-control select') }} - {{ util.render_form_field_errors(form.courier_id) }} -
-
- {{ form.location_id.label(class='control-label') }} - {{ form.location_id(class='form-control select') }} - {{ util.render_form_field_errors(form.location_id) }} -
- {% if current_user.is_admin() %} -
- {{ form.starttime.label(class='control-label') }} -
- {{ form.starttime(class='form-control datetimepicker') }} - - - -
- {{ util.render_form_field_errors(form.starttime) }} -
- {% endif %} -
- {{ form.stoptime.label(class='control-label') }} -
- {{ form.stoptime(class='form-control datetimepicker') }} - - - -
- {{ util.render_form_field_errors(form.stoptime) }} -
-
- {{ form.submit_button(class='btn btn-primary') }} -
-
-
-
-
- {% endif %} -
- +
+ {% if not current_user.is_anonymous() %} +
+

Edit order:

+
+
+
+ {{ form.csrf_token }} +
+ {{ form.courier_id.label(class='control-label') }}
+ {{ form.courier_id(class='form-control select') }} + {{ util.render_form_field_errors(form.courier_id) }} +
+
+ {{ form.location_id.label(class='control-label') }} + {{ form.location_id(class='form-control select') }} + {{ util.render_form_field_errors(form.location_id) }} +
+ {% if current_user.is_admin() %} +
+ {{ form.starttime.label(class='control-label') }} +
+ {{ form.starttime(class='form-control datetimepicker') }} + + + +
+ {{ util.render_form_field_errors(form.starttime) }} +
+ {% endif %} +
+ {{ form.stoptime.label(class='control-label') }} +
+ {{ form.stoptime(class='form-control datetimepicker') }} + + + +
+ {{ util.render_form_field_errors(form.stoptime) }} +
+
+ {{ form.submit_button(class='btn btn-primary') }} +
+
+
+
+
+ {% endif %} +
{% endblock %} {% block styles -%} - {{ super() }} + {{ super() }} - - - + + + {%- endblock %} {% block scripts -%} - {{ super() }} - - - - + {{ super() }} + + + + {%- endblock %} diff --git a/app/templates/order_items.html b/app/templates/order_items.html index fb479ee..a92b632 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -6,47 +6,47 @@ Haldis - Order {{ order.id }} {% endblock %} {% block styles %} - {{ super() }} - - - + {{ super() }} + + + {% endblock %} {% block scripts %} - {{ super() }} - - + {{ super() }} + + {% endblock %} {% block content -%} - {{ utils.flashed_messages(container=True) }} + {{ utils.flashed_messages(container=True) }} -
-

Haldis order {{ order.id }}

+
+

Haldis order {{ order.id }}

- {% if not order.is_closed() %} -
- {{ order.stoptime|countdown }}
- Refresh page when closed! -
- {% endif %} + {% if not order.is_closed() %} +
+ {{ order.stoptime|countdown }}
+ Refresh page when closed! +
+ {% endif %} - {% for key, value in order.group_by_dish().items() -%} -
-

{{ value["count"] }} × {{ key }}

- {% if value["comments"]|any -%} -
    - {% for comment in value["comments"] -%} -
  • {% if comment %}{{ comment }} - {% else %}No comment - {% endif %}
  • - {% endfor %} -
- {%- endif %} -

-
- {%- endfor %} -
Total {{ order.items.count() }} items — {{ total_price|euro }}
-
+ {% for key, value in order.group_by_dish().items() -%} +
+

{{ value["count"] }} × {{ key }}

+ {% if value["comments"]|any -%} +
    + {% for comment in value["comments"] -%} +
  • {% if comment %}{{ comment }} + {% else %}No comment + {% endif %}
  • + {% endfor %} +
+ {%- endif %} +

+
+ {%- endfor %} +
Total {{ order.items.count() }} items — {{ total_price|euro }}
+
{%- endblock %} diff --git a/app/templates/orders.html b/app/templates/orders.html index 1c86c9e..e7fb9a1 100644 --- a/app/templates/orders.html +++ b/app/templates/orders.html @@ -5,90 +5,89 @@ {% import "utils.html" as util -%} {% block container %} -
-
- {% if orders|count > 0 -%} -

Open orders:

- {% for order in orders %} - {{ util.render_order(order) }} - {% endfor %} - {% else %} -

No orders available.

- {% if not current_user.is_anonymous() %} - To create an order, fill in the form on the right. - {% else %} - Login to create an order, or ask someone else. - {% endif %} - {%- endif %} -
- {% if not current_user.is_anonymous() %} -
-

Create new order:

-
-
-
- {{ form.csrf_token }} -
- {{ form.courier_id.label(class='control-label') }}
- {{ form.courier_id(class='form-control select') }} - {{ util.render_form_field_errors(form.courier_id) }} -
-
- {{ form.location_id.label(class='control-label') }} - {{ form.location_id(class='form-control select') }} - {{ util.render_form_field_errors(form.location_id) }} -
- {% if current_user.is_admin() %} -
- {{ form.starttime.label(class='control-label') }} -
- {{ form.starttime(class='form-control datetimepicker') }} - - - -
- {{ util.render_form_field_errors(form.starttime) }} -
- {% endif %} -
- {{ form.stoptime.label(class='control-label') }} -
- {{ form.stoptime(class='form-control datetimepicker') }} - - - -
- {{ util.render_form_field_errors(form.stoptime) }} -
-
- {{ form.submit_button(class='btn btn-primary') }} -
-
-
-
-
- {% endif %} -
- +
+
+ {% if orders|count > 0 -%} +

Open orders:

+ {% for order in orders %} + {{ util.render_order(order) }} + {% endfor %} + {% else %} +

No orders available.

+ {% if not current_user.is_anonymous() %} + To create an order, fill in the form on the right. + {% else %} + Login to create an order, or ask someone else. + {% endif %} + {%- endif %} +
+ {% if not current_user.is_anonymous() %} +
+

Create new order:

+
+
+
+ {{ form.csrf_token }} +
+ {{ form.courier_id.label(class='control-label') }}
+ {{ form.courier_id(class='form-control select') }} + {{ util.render_form_field_errors(form.courier_id) }} +
+
+ {{ form.location_id.label(class='control-label') }} + {{ form.location_id(class='form-control select') }} + {{ util.render_form_field_errors(form.location_id) }} +
+ {% if current_user.is_admin() %} +
+ {{ form.starttime.label(class='control-label') }} +
+ {{ form.starttime(class='form-control datetimepicker') }} + + + +
+ {{ util.render_form_field_errors(form.starttime) }} +
+ {% endif %} +
+ {{ form.stoptime.label(class='control-label') }} +
+ {{ form.stoptime(class='form-control datetimepicker') }} + + + +
+ {{ util.render_form_field_errors(form.stoptime) }} +
+
+ {{ form.submit_button(class='btn btn-primary') }} +
+
+
+
+
+ {% endif %} +
{% endblock %} {% block styles -%} - {{ super() }} - - - + {{ super() }} + + + {%- endblock %} {% block scripts -%} - {{ super() }} - - - - + {{ super() }} + + + + {%- endblock %} diff --git a/app/templates/profile.html b/app/templates/profile.html index 964905b..c9b1715 100644 --- a/app/templates/profile.html +++ b/app/templates/profile.html @@ -2,17 +2,17 @@ {% set active_page = "profile" -%} {% block container %} -

{{ current_user.username }}

-

Themes

-

enable custom themes

-

enable high performance

-

- - -

+

{{ current_user.username }}

+

Themes

+

enable custom themes

+

enable high performance

+

+ + +

{% endblock %} diff --git a/app/templates/stats.html b/app/templates/stats.html index e8111c6..80632ac 100644 --- a/app/templates/stats.html +++ b/app/templates/stats.html @@ -1,14 +1,14 @@ {% extends "layout.html" -%} {% set active_page = "stats" -%} {% block container %} -

Stats bruh

-
-
- Over - {{ data.amount.orders }} orders, - {{ data.amount.users }} users have ordered - {{ data.amount.orderitems }} items in - {{ data.amount.locations }} locations. -
-
-{% endblock %} \ No newline at end of file +

Stats bruh

+
+
+ Over + {{ data.amount.orders }} orders, + {{ data.amount.users }} users have ordered + {{ data.amount.orderitems }} items in + {{ data.amount.locations }} locations. +
+
+{% endblock %} diff --git a/app/templates/utils.html b/app/templates/utils.html index 7c62e4b..d835c04 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,25 +1,25 @@ {% macro render_order(order) -%}
-
-
{{ order.location_name }}
- {{ order.items.count() }} orders

-

- {% if order.stoptime %} - Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} - {% else %}open{% endif %}
-

-
- Expand -
+
+
{{ order.location_name }}
+ {{ order.items.count() }} orders

+

+ {% if order.stoptime %} + Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} + {% else %}open{% endif %}
+

+
+ Expand +
{%- endmacro %} {% macro render_form_field_errors(field) %} {%- if field.errors %} - {%- for error in field.errors %} -

{{error}}

- {%- endfor %} + {%- for error in field.errors %} +

{{error}}

+ {%- endfor %} {%- elif field.description -%} -

{{field.description|safe}}

+

{{field.description|safe}}

{%- endif %} {% endmacro %} diff --git a/app/views/themes.yml b/app/views/themes.yml index 3cc45fb..824b689 100644 --- a/app/views/themes.yml +++ b/app/views/themes.yml @@ -1,22 +1,22 @@ # Seasonal themes for Haldis - lightmode: - file: lightmode.css - type: default + file: lightmode.css + type: default - darkmode: - file: darkmode.css - type: default + file: darkmode.css + type: default - halloween: - file: halloween.css - type: static-date - start: 21/10 - end: 10/11 + file: halloween.css + type: static-date + start: 21/10 + end: 10/11 - sinterklaas: - file: sinterklaas.css - type: static-date - start: 28/11 - end: 5/12 + file: sinterklaas.css + type: static-date + start: 28/11 + end: 5/12 - kerstmis: - file: kerstmis.css - type: static-date - start: 6/12 - end: 06/01 \ No newline at end of file + file: kerstmis.css + type: static-date + start: 6/12 + end: 06/01 diff --git a/etc/vscode/language-configuration.json b/etc/vscode/language-configuration.json index f3e7fd6..6dec264 100644 --- a/etc/vscode/language-configuration.json +++ b/etc/vscode/language-configuration.json @@ -1,30 +1,30 @@ { - "comments": { - // symbol used for single line comment. Remove this entry if your language does not support line comments - "lineComment": "//", - // symbols used for start and end a block comment. Remove this entry if your language does not support block comments - "blockComment": [ "=============================================", "=============================================" ] - }, - // symbols used as brackets - "brackets": [ - ["{", "}"], - ["[", "]"], - ["(", ")"] - ], - // symbols that are auto closed when typing - "autoClosingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ], - // symbols that can be used to surround a selection - "surroundingPairs": [ - ["{", "}"], - ["[", "]"], - ["(", ")"], - ["\"", "\""], - ["'", "'"] - ] -} \ No newline at end of file + "comments": { + // symbol used for single line comment. Remove this entry if your language does not support line comments + "lineComment": "//", + // symbols used for start and end a block comment. Remove this entry if your language does not support block comments + "blockComment": [ "=============================================", "=============================================" ] + }, + // symbols used as brackets + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + // symbols that are auto closed when typing + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ], + // symbols that can be used to surround a selection + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["\"", "\""], + ["'", "'"] + ] +} diff --git a/etc/vscode/package.json b/etc/vscode/package.json index 4708b30..7860b42 100644 --- a/etc/vscode/package.json +++ b/etc/vscode/package.json @@ -1,31 +1,31 @@ { - "name": "hlds", - "publisher": "Silvius", - "displayName": "Syntax highlighting for haldis (hlds) files.", - "description": "hlds", - "repository": "https://git.zeus.gent/midgard/haldis", - "version": "0.0.2", - "engines": { - "vscode": "^1.30.0" - }, - "categories": [ - "Programming Languages" - ], - "contributes": { - "languages": [{ - "id": "hlds", - "aliases": ["HLDS", "hlds"], - "extensions": [".hlds"], - "configuration": "./language-configuration.json" - }], - "grammars": [{ - "language": "hlds", - "scopeName": "source.hlds", - "path": "./syntaxes/hlds.tmLanguage.json" - }, { - "path": "./syntaxes/injections.json", - "scopeName": "comment.injection", - "injectTo": ["source.hlds"] - }] - } + "name": "hlds", + "publisher": "Silvius", + "displayName": "Syntax highlighting for haldis (hlds) files.", + "description": "hlds", + "repository": "https://git.zeus.gent/midgard/haldis", + "version": "0.0.2", + "engines": { + "vscode": "^1.30.0" + }, + "categories": [ + "Programming Languages" + ], + "contributes": { + "languages": [{ + "id": "hlds", + "aliases": ["HLDS", "hlds"], + "extensions": [".hlds"], + "configuration": "./language-configuration.json" + }], + "grammars": [{ + "language": "hlds", + "scopeName": "source.hlds", + "path": "./syntaxes/hlds.tmLanguage.json" + }, { + "path": "./syntaxes/injections.json", + "scopeName": "comment.injection", + "injectTo": ["source.hlds"] + }] + } } diff --git a/etc/vscode/syntaxes/injections.json b/etc/vscode/syntaxes/injections.json index 6557b5d..f3960e6 100644 --- a/etc/vscode/syntaxes/injections.json +++ b/etc/vscode/syntaxes/injections.json @@ -1,36 +1,36 @@ { - "scopeName": "comment.injection", - "injectionSelector": "L:embedded.meta.tag", - "patterns": [ - { - "include": "#comment" - }, - { - "include": "#header" - }, - { - "include": "#links" - }, - { - "include": "#brackets" - } - ], - "repository": { - "comment": { - "match": "#.*$", - "name": "comment" - }, - "header": { - "match": "^[a-zA-Z0-9_].*$", - "name": "keyword.todo" - }, - "links": { - "match": "^\\t[a-zA-Z0-9-_]*", - "name": "keyword.todo" - }, - "brackets": { - "match": "=", - "name": "variable.other" - } - } + "scopeName": "comment.injection", + "injectionSelector": "L:embedded.meta.tag", + "patterns": [ + { + "include": "#comment" + }, + { + "include": "#header" + }, + { + "include": "#links" + }, + { + "include": "#brackets" + } + ], + "repository": { + "comment": { + "match": "#.*$", + "name": "comment" + }, + "header": { + "match": "^[a-zA-Z0-9_].*$", + "name": "keyword.todo" + }, + "links": { + "match": "^\\t[a-zA-Z0-9-_]*", + "name": "keyword.todo" + }, + "brackets": { + "match": "=", + "name": "variable.other" + } + } } diff --git a/first-setup.sh b/first-setup.sh index 633a4b1..b9f9585 100755 --- a/first-setup.sh +++ b/first-setup.sh @@ -9,8 +9,8 @@ B="\n${bold}" E="${normal}" if [ ! -d "venv" ]; then - echo -e "${B} No venv found, creating a new one ${E}" - python3 -m venv venv + echo -e "${B} No venv found, creating a new one ${E}" + python3 -m venv venv fi source venv/bin/activate @@ -29,4 +29,4 @@ cd .. echo -e "${B} Seeding database ${E}" ./populate-db.sh -echo -e "${B} Activate your venv using 'source venv/bin/activate'.\nThen run the server with 'python app/app.py runserver' ${E}" \ No newline at end of file +echo -e "${B} Activate your venv using 'source venv/bin/activate'.\nThen run the server with 'python app/app.py runserver' ${E}" -- 2.43.4 From 04a1f0acb1d20c06c8f8e443b20ac920007cbf70 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 17:38:25 +0100 Subject: [PATCH 032/197] Rename from .min.css to .css This file is not minified, so the .min.css is wrong. Also remove the executable flag from some non-executable files. --- ...trap-datetimepicker.min.css => bootstrap-datetimepicker.css} | 0 app/static/js/bootstrap-datetimepicker.min.js | 0 app/templates/order_edit.html | 2 +- app/templates/orders.html | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename app/static/css/{bootstrap-datetimepicker.min.css => bootstrap-datetimepicker.css} (100%) mode change 100755 => 100644 mode change 100755 => 100644 app/static/js/bootstrap-datetimepicker.min.js diff --git a/app/static/css/bootstrap-datetimepicker.min.css b/app/static/css/bootstrap-datetimepicker.css old mode 100755 new mode 100644 similarity index 100% rename from app/static/css/bootstrap-datetimepicker.min.css rename to app/static/css/bootstrap-datetimepicker.css diff --git a/app/static/js/bootstrap-datetimepicker.min.js b/app/static/js/bootstrap-datetimepicker.min.js old mode 100755 new mode 100644 diff --git a/app/templates/order_edit.html b/app/templates/order_edit.html index a47cd1d..8ba1cc4 100644 --- a/app/templates/order_edit.html +++ b/app/templates/order_edit.html @@ -60,7 +60,7 @@ {{ super() }} - + {%- endblock %} {% block scripts -%} diff --git a/app/templates/orders.html b/app/templates/orders.html index e7fb9a1..5531654 100644 --- a/app/templates/orders.html +++ b/app/templates/orders.html @@ -74,7 +74,7 @@ {% block styles -%} {{ super() }} - + {%- endblock %} {% block scripts -%} -- 2.43.4 From 13097b8156ed29be69ed2f14e28fb97214756c89 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 17:39:28 +0100 Subject: [PATCH 033/197] Remove GitHub buttons script include It has no purpose and is bad for privacy. --- app/templates/order_items.html | 1 - 1 file changed, 1 deletion(-) diff --git a/app/templates/order_items.html b/app/templates/order_items.html index a92b632..58a81c6 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -14,7 +14,6 @@ Haldis - Order {{ order.id }} {% block scripts %} {{ super() }} - {% endblock %} -- 2.43.4 From e013127ed78b7f13d4eebe902fd9219f056da3b4 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 17:50:40 +0100 Subject: [PATCH 034/197] Add contact information to locations --- data/fitchen.hlds | 5 ++++- data/fritoloog.hlds | 3 ++- data/ocean_garden.hlds | 6 ++++-- data/simpizza.hlds | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/data/fitchen.hlds b/data/fitchen.hlds index 502ffcb..f7f0dad 100644 --- a/data/fitchen.hlds +++ b/data/fitchen.hlds @@ -1,6 +1,9 @@ ============================================= fitchen: Fitchen - osm https://www.openstreetmap.org/node/3394542496 + osm https://www.openstreetmap.org/node/3394542496 + website https://www.fitchen.be/ + address Vlaanderenstraat 129, 9000 Gent + phone +32 9 310 44 62 # Menu: https://www.fitchen.be/wp-content/uploads/2019/12/FITCHEN_gids_02122019_3web.pdf ============================================= diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds index 8abfbf9..b3794ee 100644 --- a/data/fritoloog.hlds +++ b/data/fritoloog.hlds @@ -2,8 +2,9 @@ fritoloog: Fritoloog osm https://www.openstreetmap.org/node/5813542646 address Voskenslaan 413, 9000 Gent + phone +32 495 22 19 75 website https://defritoloog.be - # Op bovenstaande website kan men ook online orderen + # Op bovenstaande website kan men ook online bestellen ============================ dish fries: Frietjes :: {has_meat} diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds index 00510ae..7f57b39 100644 --- a/data/ocean_garden.hlds +++ b/data/ocean_garden.hlds @@ -1,7 +1,9 @@ ============================================= ocean_garden: Ocean Garden - # Openingsuren, website, telefoonnummer, adres enz. worden uit OpenStreetMap gehaald - osm https://www.openstreetmap.org/node/2275105003 + osm https://www.openstreetmap.org/node/2275105003 + address Zwijnaardsesteenweg 399, 9000 Gent + phone +32 9 222 72 74 + website http://oceangarden.byethost3.com/ # Studentenmenu wordt beschreven op # http://oceangarden.byethost3.com/studentenmenus.html?i=1 diff --git a/data/simpizza.hlds b/data/simpizza.hlds index 11872fb..0e87a4c 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -2,8 +2,9 @@ simpizza: Simpizza osm https://www.openstreetmap.org/node/5803560353 address De Pintelaan 252, 9000 Gent + phone +32 9 321 02 00 website https://www.simpizza.be/ - # Op bovenstaande website kan men ook online orderen + # Op bovenstaande website kan men ook online bestellen ============================ dish garlic_bread: Lookbroodjes natuur € 2.2 -- 2.43.4 From 21f4903bfda138dc6a7fa53d4ba56b5ba6db040b Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 19:34:31 +0100 Subject: [PATCH 035/197] Complete Simpizza menu --- data/simpizza.hlds | 289 +++++++++++++++++++++++++++++++++------------ 1 file changed, 213 insertions(+), 76 deletions(-) diff --git a/data/simpizza.hlds b/data/simpizza.hlds index 0e87a4c..af12f1a 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -7,120 +7,257 @@ simpizza: Simpizza # Op bovenstaande website kan men ook online bestellen ============================ -dish garlic_bread: Lookbroodjes natuur € 2.2 -dish garlic_bread_cheese: Lookbroodjes kaas € 2.5 -dish garlic_bread_cheese_ham: Lookbroodjes kaas en ham :: {has_meat} € 3 -dish garlic_bread_cheese_tomato: Lookbroodjes kaas en tomaat € 3 -dish garlic_bread_cheese_salami: Lookbroodjes kaas en salami :: {has_meat} € 3 - -dish baguette_oven: Baguette in de oven € 3 -dish chicken_fingers: Kippenvingers :: {has_meat} € 3 -dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 8.5 - size: Grootte small: Small -- 27 cm € 9.95 medium: Medium -- 30 cm € 12.95 large: Large -- 37 cm € 15.95 -garlic_sauce: Looksaus - no_garlic_sauce: Geen extra looksaus :: {no_text} - yes_garlic_sauce: Met looksaus (prijs onzeker) € 0.75 +base: Bodem + italian: Italian classic :: {no_text} + cheesy: Cheesy crust € 2 -dish margherita: Pizza margherita (veggie) +sauce: Extra potje saus + garlic_sauce: Looksaus € 0.75 + bbq: Barbecuesaus € 0.35 + sweet_sour: Zoetzure saus € 0.35 + ketchup: Ketchup € 0.75 + mayo: Mayonaise € 0.75 + +sauce_no_garlic: Extra potje saus (looksaus al inbegrepen) + bbq: Barbecuesaus € 0.35 + sweet_sour: Zoetzure saus € 0.35 + ketchup: Ketchup € 0.75 + mayo: Mayonaise € 0.75 + +dish margherita: Pizza margherita (veggie) -- Tomatensaus, kaas, mozzarella single_choice size - single_choice garlic_sauce -dish bolognese_de_luxe: Pizza bolognese de luxe :: {has_meat} + single_choice base + multi_choice sauce +dish bolognese_de_luxe: Pizza bolognese de luxe -- Bolognesesaus, look, ui, extra gehakt :: {has_meat} single_choice size - single_choice garlic_sauce -dish hawaii: Pizza Hawaï :: {has_meat} + single_choice base + multi_choice sauce +dish hawaii: Pizza Hawaï -- Ham, kip, maïs, ananas :: {has_meat} single_choice size - single_choice garlic_sauce -dish popeye: Pizza Popeye (veggie) + single_choice base + multi_choice sauce +dish popeye: Pizza Popeye (veggie) -- Extra spinazie, ei, room, extra kaas single_choice size - single_choice garlic_sauce -dish pepperoni: Pizza pepperoni :: {has_meat} + single_choice base + multi_choice sauce +dish pepperoni: Pizza pepperoni -- Dubbele portie pepperoni, paprika, jalapeños :: {has_meat} single_choice size - single_choice garlic_sauce -dish seafood: Pizza seafood :: {has_meat} + single_choice base + multi_choice sauce +dish seafood: Pizza seafood -- Tonijn, calamares, mosselen, garnalen :: {has_fish} single_choice size - single_choice garlic_sauce -dish hot_pizza: Pizza hot pizzaaah!!! :: {has_meat} + single_choice base + multi_choice sauce +dish mega_fish: Pizza mega fish -- Ansjovis, tonijn, champignons, ui :: {has_fish} single_choice size - single_choice garlic_sauce -dish salmon_delight: Pizza salmon delight :: {has_meat} + single_choice base + multi_choice sauce +dish hot_pizza: Pizza hot pizzaaah!!! -- Gehakt, jalapeños, ui, pepperoni :: {has_meat} single_choice size - single_choice garlic_sauce -dish full_option: Pizza full option :: {has_meat} + single_choice base + multi_choice sauce +dish salmon_delight: Pizza salmon delight -- Roomsaus, ui, gerookte zalm, kappertjes :: {has_meat} single_choice size - single_choice garlic_sauce -dish pitza_kebab: Pitza kebab -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce +dish full_option: Pizza full option -- Salami, paprika, ui, olijven, kip, ananas, maïs, gehakt, extra kaas :: {has_meat} single_choice size -dish multi_cheese: Pizza multi cheese (veggie) + single_choice base + multi_choice sauce +dish pitza_kebab: Pitza kebab -- Look, ui, pitavlees, potje looksaus :: {has_meat} single_choice size - single_choice garlic_sauce -dish 4_seasons: Pizza 4 seasons :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish multi_cheese: Pizza multi cheese (veggie) -- Gorgonzola, feta, belpaese, extra kaas single_choice size - single_choice garlic_sauce -dish mega_fish: Pizza mega fish :: {has_meat} + single_choice base + multi_choice sauce +dish creamy_multi_cheese: Pizza creamy multi cheese (veggie) -- Roomsaus, gorgonzola, feta, mozzarella, extra kaas single_choice size - single_choice garlic_sauce -dish creamy_multi_cheese: Pizza creamy multi cheese (veggie) + single_choice base + multi_choice sauce_no_garlic +dish 4_seasons: Pizza 4 seasons -- Ham, salami, champignons, paprika :: {has_meat} single_choice size -dish green_fiesta: Pizza green fiësta -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce +dish green_fiesta: Pizza green fiësta -- Roomsaus, spinazie, look, döner kebab, potje looksaus :: {has_meat} single_choice size -dish veggie: Pizza veggie + single_choice base + multi_choice sauce_no_garlic +dish veggie: Pizza veggie -- Champignons, paprika, ui, maïs, tomaat, olijven single_choice size - single_choice garlic_sauce -dish meat_lovers: Pizza meat lovers :: {has_meat} + single_choice base + multi_choice sauce +dish meat_lovers: Pizza meat lovers -- Ham, salami, pepperoni, extra gehakt :: {has_meat} single_choice size - single_choice garlic_sauce -dish meat_lovers_deluxe: Pizza meat lovers deluxe -- Heeft al swirl van looksaus :: {has_meat} € 2 + single_choice base + multi_choice sauce +dish meat_lovers_deluxe: Pizza meat lovers deluxe -- Ham, salami, pepperoni, bacon, meatballs, merguez, swirl van looksaus :: {has_meat} € 2 single_choice size -dish scampi_mampi: Pizza scampi mampi :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish scampi_mampi: Pizza scampi mampi -- Ui, look, scampi, verse tomaat :: {has_meat} single_choice size - single_choice garlic_sauce -dish tabasco: Pizza tabasco :: {has_meat} + single_choice base + multi_choice sauce +dish tabasco: Pizza tabasco -- Tabascopizzasaus, ui, paprika, champignons, pepperoni :: {has_meat} single_choice size - single_choice garlic_sauce -dish funky_chicken: Pizza funky chicken :: {has_meat} + single_choice base + multi_choice sauce +dish funky_chicken: Pizza funky chicken -- Ui, ananas, paprika, kip :: {has_meat} single_choice size - single_choice garlic_sauce -dish chicken_time: Pizza chicken time :: {has_meat} + single_choice base + multi_choice sauce +dish chicken_time: Pizza chicken time -- Kip, paprika, olijven, verse tomaten :: {has_meat} single_choice size - single_choice garlic_sauce -dish creamy_chicken: Pizza creamy chicken -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce +dish creamy_chicken: Pizza creamy chicken -- Roomsaus, kip, ui, look, potje looksaus :: {has_meat} single_choice size -dish spicy_chicken: Pizza spicy chicken -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish spicy_chicken: Pizza spicy chicken -- Rode ui, jalapeños, kip, paprika, mozzarella, potje looksaus :: {has_meat} single_choice size -dish meatballs: Pizza meatballs :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish meatballs: Pizza meatballs -- Gekruide gehaktballetjes, ui, paprika, verse tomaat :: {has_meat} single_choice size - single_choice garlic_sauce -dish tuna: Pizza tuna :: {has_meat} + single_choice base + multi_choice sauce +dish tuna: Pizza tuna -- Ui, tonijn, olijven, extra kaas :: {has_meat} single_choice size - single_choice garlic_sauce -dish anchovy: Pizza anchovy :: {has_meat} + single_choice base + multi_choice sauce +dish anchovy: Pizza anchovy -- Ui, ansjovis, paprika, olijven :: {has_meat} single_choice size - single_choice garlic_sauce -dish calzone: Pizza calzone :: {has_meat} + single_choice base + multi_choice sauce +dish calzone: Pizza calzone -- Dubbelgevouwen. Ham, salami, champignons, paprika, bolognesesaus :: {has_meat} single_choice size - single_choice garlic_sauce -dish hot_bolognese: Pizza hot bolognese :: {has_meat} + single_choice base + multi_choice sauce +dish curry: Pizza curry -- Currysaus, champignons, ui, ananas, paprika, kip, mozzarella, potje looksaus :: {has_meat} single_choice size - single_choice garlic_sauce -dish hot_and_cheesy: Pizza hot & cheesy :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish bbq_chicken: Pizza chicken barbecue -- Barbecuesaus, gegrilde kip, ui, paprika :: {has_meat} single_choice size - single_choice garlic_sauce -dish curry: Pizza curry -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce +dish bbq_meatballs: Pizza barbecue meatballs -- Barbecuesaus, gekruide gehaktballetjes, ui, paprika, verse tomaat :: {has_meat} single_choice size -dish bbq_chicken: Pizza chicken barbecue :: {has_meat} + single_choice base + multi_choice sauce +dish bbq_bacon: Pizza barbecue bacon -- Barbecuesaus, bacon, ui, kip, jalapeños, potje looksaus :: {has_meat} single_choice size - single_choice garlic_sauce -dish bbq_meatballs: Pizza barbecue meatballs :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish bbq_special: Pizza barbecue special -- Barbecuesaus, pepperoni, kip, meatballs, ui, swirl van looksaus :: {has_meat} single_choice size - single_choice garlic_sauce -dish bbq_bacon: Pizza barbecue bacon -- Heeft al potje looksaus :: {has_meat} + single_choice base + multi_choice sauce_no_garlic +dish bbq_merguez: Pizza merguez -- Barbecuesaus, merguez, ui, paprika, potje looksaus :: {has_meat} single_choice size -dish bbq_special: Pizza barbecue special -- Heeft al potje looksaus :: {has_meat} - single_choice size -dish bbq_merguez: Pizza merguez -- Heeft al swirl van looksaus :: {has_meat} + single_choice base + multi_choice sauce_no_garlic + +dish diy: Pizza do it yourself -- Vier ingrediënten gratis, daarna €1 per ingrediënt op small, €1.25 op medium, €1.5 op large single_choice size + single_choice base + multi_choice meat: Vlees + ham: Ham :: {has_meat} + salami: Salami :: {has_meat} + hot_salami: Pikante salami :: {has_meat} + minced_meat: Gehakt :: {has_meat} + chicken: Kip :: {has_meat} + kebab: Kebabvlees :: {has_meat} + merguez: Merguez :: {has_meat} + bacon: Bacon :: {has_meat} + + multi_choice fish: Vis + tuna: Tonijn :: {has_fish} + mussels: Mosselen :: {has_fish} + anchovy: Ansjovis :: {has_fish} + calamares: Calamares :: {has_fish} + shrimp: Garnalen :: {has_fish} + + multi_choice vegetables: Groenten + mushroom: Champignons + onion: Ui + garlic: Look + olives: Olijven + bell_pepper: Paprika + maize: Maïs + capers: Kappertjes + hot_peppers: Pikante pepers + pineapple: Ananas + tomato: Tomaat + + multi_choice sauces: Sauzen + bolognese: Bolognesesaus :: {has_meat} + cream: Roomsaus + tomato: Tomatensaus + tabasco: Tabascopizzasaus + bbq: Barbecuesaus + garlic: Looksaus + + multi_choice dairy: Zuivel + egg: Ei + gorgonzola: Gorgonzola + bel_paese: Bel paese + feta: Feta + extra_cheese: Extra kaas + +dish garlic_bread: Lookbroodjes natuur € 2.2 +dish garlic_bread_cheese: Lookbroodjes kaas € 2.5 +dish garlic_bread_cheese_ham: Lookbroodjes kaas en ham :: {has_meat} € 3 +dish garlic_bread_cheese_tomato: Lookbroodjes kaas en tomaat € 3 + +dish baguette_pesto: Lookbaguette pesto -- Pesto, tomatensaus, verse tomaat, mozzarella € 4.75 +dish baguette_bolognese: Lookbaguette bolognese -- Bolognesesaus, salami, mozzarella € 4.75 +dish baguette_chicken_kebab: Lookbaguette chicken kebab -- Tomatensaus, ui, kip, kebabvlees, mozzarella € 4.75 +dish baguette_tuna: Lookbaguette tuna -- Tomatensaus, ui, tonijn, olijven, mozzarella € 4.75 +dish baguette_hot: Lookbaguette hot -- Tabascotomatensaus, ui, pepperoni, jalapeños, mozzarella € 4.75 + +dish hot_and_cheesy: Hot & cheesy -- 5 stuks, inclusief potje dipsaus € 3.5 +dish usa_potatoes: USA potatoes -- 1 portie, inclusief potje dipsaus € 3.5 + +dish 8_chicken_wings: 8 chicken wings -- Met potje dipsaus :: {has_meat} € 6 +dish 16_chicken_wings: 16 chicken wings -- Met potje dipsaus :: {has_meat} € 10 +dish 8_chicken_nuggets: 8 chicken nuggets -- Met potje dipsaus :: {has_meat} € 7 +dish 16_chicken_nuggets: 16 chicken nuggets -- Met potje dipsaus :: {has_meat} € 12 + +dish salad_mix: Salade mix -- IJsbergsla, kerstomaatjes, maïs, olijven, potje bieslook € 4.75 +dish salad_mix_mozzarella: Salade mix mozzarella € 6.5 +dish salad_mix_feta: Salade mix feta € 6.5 +dish salad_mix_tuna: Salade mix tuna € 6.5 + +pasta: Pasta + spaghetti: Spaghetti + penne: Penne + +dish pasta_bolognaise: Pasta bolognaise :: {has_meat} € 8.5 + single_choice pasta +dish pasta_cheese: Pasta kaassaus (veggie) € 8.5 + single_choice pasta +dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 9.5 + single_choice pasta +dish pasta_milano: Pasta milano -- Kip, champignons, ui, room, look, curry :: {has_meat} € 9.95 + single_choice pasta +dish pasta_scampi: Pasta scampi -- Scampi, champignons, ui, room, look, curry :: {has_fish} € 9.95 + single_choice pasta +dish pasta_multi_cheese: Pasta multi cheese (veggie) € 9.95 + single_choice pasta +dish pasta_pesto_chicken: Pasta pesto chicken -- Pestoroomsaus en kip € 9.95 + single_choice pasta +dish pasta_veggie: Pasta veggie -- Tomatenroomsaus, champignons, ui, paprika, tomaat € 9.95 + single_choice pasta + +dish tiramisu: Tiramisu € 3 +dish tiramisu_speculoos: Tiramisu speculoos € 3 +dish tiramisu_oreo: Tiramisu oreo € 3 -- 2.43.4 From 076fb9880eb1ea99c5a7e454b872a28922df49aa Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 19:51:58 +0100 Subject: [PATCH 036/197] Add 50/50 --- data/simpizza.hlds | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/simpizza.hlds b/data/simpizza.hlds index af12f1a..bf7d3b2 100644 --- a/data/simpizza.hlds +++ b/data/simpizza.hlds @@ -166,6 +166,11 @@ dish bbq_merguez: Pizza merguez -- Barbecuesaus, single_choice base multi_choice sauce_no_garlic +dish 50_50: Pizza fifty/fifty (helften in commentaar) -- Twee pizzahelften naar keuze € 2 + single_choice size + single_choice base + multi_choice sauce + dish diy: Pizza do it yourself -- Vier ingrediënten gratis, daarna €1 per ingrediënt op small, €1.25 op medium, €1.5 op large single_choice size single_choice base -- 2.43.4 From f2112ec26d492b4b79b7c567d98f90b27c685bf2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 20:04:14 +0100 Subject: [PATCH 037/197] Restore form field location Ugh, how did that happen --- app/templates/order.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/order.html b/app/templates/order.html index 40732b9..e456ae3 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -53,8 +53,8 @@ {{ util.render_form_field_errors(form.dish_id) }} + {% if dish and dish.choices %} - {% for (choice_type, choice) in dish.choices %}

-- 2.43.4 From 45a110db2313ab3c0138517ed6e541d284329bcc Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Feb 2020 21:56:04 +0100 Subject: [PATCH 038/197] Add price range on location view --- app/app.py | 12 ++++-------- app/forms.py | 11 ++--------- app/templates/location.html | 2 +- app/utils.py | 5 +++++ 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/app/app.py b/app/app.py index 51888a3..6595a52 100755 --- a/app/app.py +++ b/app/app.py @@ -18,7 +18,7 @@ from flask_script import Manager, Server from login import init_login from models import db from models.anonymous_user import AnonymouseUser -from utils import euro_string +from utils import euro_string, price_range_string from zeus import init_oauth @@ -159,15 +159,11 @@ def add_template_filters(app: Flask) -> None: return time @app.template_filter("year") - def current_year(value: typing.Any) -> str: # pylint: disable=W0613 - "A function which returns the current year" + def current_year(_value: typing.Any) -> str: return str(datetime.now().year) - @app.template_filter("euro") - def euro(value: int) -> str: - "A function which converts a value to its euro_string" - return euro_string(value) - + app.template_filter("euro")(euro_string) + app.template_filter("price_range")(price_range_string) app.template_filter("any")(any) diff --git a/app/forms.py b/app/forms.py index 115a80a..cf92c6b 100644 --- a/app/forms.py +++ b/app/forms.py @@ -9,7 +9,7 @@ from flask_wtf import FlaskForm as Form from wtforms import (DateTimeField, SelectField, SelectMultipleField, StringField, SubmitField, FieldList, validators) -from utils import euro_string +from utils import euro_string, price_range_string from hlds.definitions import location_definitions from hlds.models import Location, Dish, Choice from models import User @@ -53,16 +53,9 @@ class OrderItemForm(Form): comment = StringField("Comment") submit_button = SubmitField("Submit") - @staticmethod - def format_price_range(price_range): - if price_range[0] == price_range[1]: - return euro_string(price_range[0]) - else: - return "from {}".format(euro_string(price_range[0])) - def populate(self, location: Location) -> None: self.dish_id.choices = [ - (dish.id, (dish.name + ": " + self.format_price_range(dish.price_range()))) + (dish.id, (dish.name + ": " + price_range_string(dish.price_range()))) for dish in location.dishes ] if not self.is_submitted() and self.comment.data is None: diff --git a/app/templates/location.html b/app/templates/location.html index 2cfa19b..34f7453 100644 --- a/app/templates/location.html +++ b/app/templates/location.html @@ -33,7 +33,7 @@
{{ dish.name or dish.id }} {{ dish.description or "" }}{{ dish.price|euro }} + {{ dish.price_range()|price_range(true) }}
{{ dish.name or dish.id }}{{ dish.description or "" }} + {{ dish.description or "" }} + {% if dish.choices %} +
+ Choices: + {% set comma = joiner(",") %} + {% for choice in dish.choices %}{{ comma() }} + {{ choice[1].name }}{% endfor %} +
+ {% endif %} +
{{ dish.price_range()|price_range(true) }}
- - {% if courier_or_admin %}{% endif %} - - - {% for item in order.items -%} - - - - - {% if courier_or_admin %} - - {% endif %} - + {%- endif %} + {{ item.price|euro }} {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %} + + {% endfor %} + + {% else %} +
(None)
+ {% endif %} + + + +
+
+

Ordered dishes

+ {% for dish_name, dish_order_items in order.group_by_dish() -%} + {% set has_comments = dish_order_items | map(attribute="comment") | any -%} +
+

+ {{ dish_order_items | length }} × + {{ dish_name }} +

+ + {% if has_comments -%} +
    + {% for item in dish_order_items -%} +
  • {% if item["comment"] %}{{ item["comment"] }} + {% else %}No comment + {% endif %} for {{ item.for_name }}
  • + {% endfor %} +
+ {% else %} + for {{ dish_order_items | map(attribute="for_name") | join(", ") }} + {%- endif %} + +

+
+ {%- endfor %} + +
+

Ordering at {{ order.location_name }}

+
+ {% if order.location.telephone %} +
Telephone
+
{{ order.location.telephone }}
+ {% endif %} + + {% if order.location.website %} +
Website
+
{{ order.location.website }}
+ {% endif %} + + {% if order.location.address or order.location.osm %} +
Location
+
+ {% if order.location.osm %} + {{ order.location.address or "View on OSM" }} + {% else %} + {{ order.location.address }} + {% endif %} +
+ {% endif %} +
+ TODO Only show options that allow you to order +
+
+ +
+
+

Items per person

+
NameItemPricePaid?Delete
{{ item.get_name() }}{{ item.dish_name }}{{ "*" if item.comment }}{{ item.price|euro }} - {% if not item.paid %} -
- -
- {% else %} - {% endif %} -
+
+

Add from history

+
    +
  • Todo
  • +
+
{% endif %}
+

My items

+ {% if my_items %} +
    + {% for item in my_items %} +
  • {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%}
    - +
    - {%- endif %}
+ + + + + {% for user_name, order_items in order.group_by_user() -%} + + + + + {%- endfor %}
TotalNameItems
+ {% set paid = order_items | map(attribute="paid") | all %} + + + {{ order_items | map(attribute="price") | sum | euro }} + + {% if paid %}paid{% endif %} + {{ user_name }} +
    + {% for item in order_items %} +
  • +
    + {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} +
    + +
    + {% else %} + + {%- endif %} +
    + +
    {{ item.price|euro }}
    +
    {{ item.dish_name }}{{ "; " + item.comment if item.comment }}
    +
  • + {% endfor %} +
  • + +
  • +
+
+ +
-
-

Ordered dishes: {{ order.items.count() }}

- - {% for key, value in order.group_by_dish().items() -%} -
- {{ key }}: {{ value["count"] }} - {% if value["comments"]|any -%} -
    - {% for comment in value["comments"] -%} -
  • {% if comment %}{{ comment }} - {% else %}No comment - {% endif %}
  • - {% endfor %} -
- {%- endif %} -
- {%- endfor %} -
- -
-
-

Debts

- - - {% if courier_or_admin %}{% endif %} - - - {% for key, value in order_items.items() -%} - - - - - {% if courier_or_admin %} - - {% endif %} - - {%- endfor %} - -
NameTotalTo payPaid?
{{ key }}{{ value["total"]|euro }}{{ value["to_pay"]|euro }} - {% if not value["to_pay"] == 0 %} -
- -
- {% else %} - - {% endif %} -
-
-
+ {% endblock %} {% block styles %} @@ -188,6 +296,122 @@ + + {% endblock %} {% block scripts %} {{ super() }} diff --git a/app/templates/order_items.html b/app/templates/order_items.html index 5dcb488..6d73795 100644 --- a/app/templates/order_items.html +++ b/app/templates/order_items.html @@ -33,13 +33,13 @@ Haldis - Order {{ order.id }} {% endif %} - {% for key, value in order.group_by_dish(True).items() -%} + {% for dish_name, dish_order_items in order.group_by_dish() -%}
-

{{ value["count"] }} × {{ key }}

- {% if value["comments"]|any -%} +

{{ dish_order_items | length }} × {{ dish_name }}

+ {% if dish_order_items | map(attribute="comment") | any -%}
    - {% for comment in value["comments"] -%} -
  • {% if comment %}{{ comment }} + {% for item in dish_order_items -%} +
  • {% if item["comment"] %}{{ item["comment"] }} {% else %}No comment {% endif %}
  • {% endfor %} diff --git a/app/templates/utils.html b/app/templates/utils.html index 6a34e0f..15d85eb 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,5 +1,5 @@ {% macro render_order(order) -%} -
    +
    {{ order.location_name }}
    {{ order.items.count() }} orders

    diff --git a/app/utils.py b/app/utils.py index e2b7417..60a382f 100644 --- a/app/utils.py +++ b/app/utils.py @@ -7,7 +7,11 @@ def euro_string(value: int) -> str: """ Convert cents to string formatted euro """ - return "€ {}.{:02}".format(*divmod(value, 100)) + euro, cents = divmod(value, 100) + if cents: + return "€ {}.{:02}".format(euro, cents) + else: + return "€ {}".format(euro) def price_range_string(price_range, include_upper=False): diff --git a/app/views/order.py b/app/views/order.py index 0187722..6528038 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -234,21 +234,6 @@ def order_item_create(order_id: int) -> typing.Any: return redirect(url_for("order_bp.order_from_id", order_id=order_id)) -@order_bp.route("///paid", methods=["POST"]) -@login_required -# pylint: disable=R1710 -def item_paid(order_id: int, item_id: int) -> typing.Optional[Response]: - "Indicate payment status for an item in an order" - item = OrderItem.query.filter(OrderItem.id == item_id).first() - user_id = current_user.id - if item.order.courier_id == user_id or current_user.admin: - item.paid = True - db.session.commit() - flash("Paid %s by %s" % (item.dish_name, item.get_name()), "success") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) - abort(404) - - @order_bp.route("///user_paid", methods=["POST"]) @login_required # pylint: disable=R1710 @@ -269,7 +254,7 @@ def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]: for item in items: item.paid = True db.session.commit() - flash("Paid %d items for %s" % (len(items), item.get_name()), "success") + flash("Paid %d items for %s" % (len(items), item.for_name), "success") return redirect(url_for("order_bp.order_from_id", order_id=order_id)) abort(404) -- 2.43.4 From 63ce1c55519f94f1b176cfe58c6a0a3d599eedd5 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 15 Aug 2020 17:46:51 +0200 Subject: [PATCH 077/197] Show options for choices on location page --- app/static/css/main.css | 12 ++++++++++++ app/templates/location.html | 24 +++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index 2fd83df..2689bd4 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -290,3 +290,15 @@ h1, h2, h3, h4, h5, h6{ #dish_choices.loading { opacity: 0.2; } + +.dish-choices summary { + font-style: italic; + cursor: pointer; +} +.dish-choices summary:before { + font-style: normal; + content: "⯈"; +} +.dish-choices[open] summary:before { + content: "⯆"; +} diff --git a/app/templates/location.html b/app/templates/location.html index 5080a30..f41c032 100644 --- a/app/templates/location.html +++ b/app/templates/location.html @@ -35,12 +35,30 @@
{{ dish.description or "" }} {% if dish.choices %} -
- Choices: +
+ {% set comma = joiner(",") %} {% for choice in dish.choices %}{{ comma() }} {{ choice[1].name }}{% endfor %} -
+ +
    + {% for type, choice in dish.choices %} +
  • {{ choice.name }}{{ + choice.description if choice.description + }}{{ + " (choose one)" if type == "single_choice" + }} +
      + {% for option in choice.options %} +
    • {{ option.name }}{% if option.description %}: + {{ option.description}}{% endif %}{% if option.price %}: + {{ option.price | euro }}{% endif %}
    • + {% endfor %} +
    +
  • + {% endfor %} +
+ {% endif %}
{{ dish.price_range()|price_range(true) }} -- 2.43.4 From f49952b4f2dda7cb43b7c4296953bcd1d98834ac Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 15 Aug 2020 17:58:02 +0200 Subject: [PATCH 078/197] Correct incorrect comment --- app/hlds/parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index 55c9fb5..08c87eb 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -33,7 +33,7 @@ class HldsSemanticActions: if not isinstance(choice[1], Choice): dish.choices[i] = (dish.choices[i][0], deepcopy(choices[choice[1]])) - # Move the base price to the first single_choice if the dish has a fixed price + # Move the base price to the first single_choice if the dish doesn't have a fixed price first_single_choice = first( c[1] for c in dish.choices if c[0] == "single_choice" ) -- 2.43.4 From 48d67cbd899f6c756860f4a25b324bd84d575a70 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 17 Aug 2020 10:43:11 +0200 Subject: [PATCH 079/197] Remove weird d from colours, add separate bg --- app/static/css/darkmode.css | 110 ------------------ app/static/css/main.css | 100 ++++++++-------- app/static/css/themes/christmas_heavy.css | 47 +++----- app/static/css/themes/christmas_heavy.css.map | 14 +-- app/static/css/themes/christmas_heavy.scss | 23 ++-- .../css/themes/christmas_lightweight.css | 36 +++--- .../css/themes/christmas_lightweight.css.map | 14 +-- .../css/themes/christmas_lightweight.scss | 23 ++-- app/static/css/themes/halloween.css | 19 +-- app/static/css/themes/plain_darkmode.css | 19 +-- app/static/css/themes/plain_lightmode.css | 19 +-- app/static/css/themes/sinterklaas.css | 16 +-- app/templates/order.html | 10 +- 13 files changed, 165 insertions(+), 285 deletions(-) delete mode 100644 app/static/css/darkmode.css diff --git a/app/static/css/darkmode.css b/app/static/css/darkmode.css deleted file mode 100644 index 41481be..0000000 --- a/app/static/css/darkmode.css +++ /dev/null @@ -1,110 +0,0 @@ -:root { - /*Darkmode colors*/ - --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; -} -.table-hover tbody tr:hover{ - background-color: var(--dGray3); -} -body{ - background-color: var(--dGray5); - color: var(--dGray1); -} -a { - color: var(--dBlue); -} -.btn-primary { - color: var(--dGray6); - background-color: var(--dBlue); -} - -.navbar { - background-color: var(--dGray6); -} -.navbar-default .navbar-nav .active a{ - background-color: var(--dGray4); - color: var(--dGray1); -} -.navbar-default .navbar-nav .active a:hover{ - background-color: var(--dGray3); - color: var(--dGray0); -} -.navbar-default .navbar-nav li a,.navbar-default .navbar-brand{ - color: var(--dGray1); -} -.navbar-default .navbar-nav li a:hover,.navbar-default .navbar-brand:hover{ - color: var(--dGray0); -} -hr{ - border-top: 1px solid var(--dGray2); -} - -h1, h2, h3, h4, h5, h6{ - color: var(--dGray1); -} - -.jumbotron, .darker { - background-color: var(--dGray4); -} -.table tbody tr td { - border-top: 1px solid var(--dGray3); -} -.table thead tr th { - border-bottom: 2px solid var(--dGray2); -} -.navbar-toggle .icon-bar { - background-color: var(--dGray0); - opacity: 0.5; -} -.select2-container--default .select2-selection--single{ - background-color: var(--dGray3); - color: var(--dGray0); -} -.select2-container--default .select2-selection--single .select2-selection__rendered{ - color: var(--dGray0); -} -.select2-results__option{ - background-color: var(--dGray5); - color: var(--dGray0); -} -.select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: var(--dGray4); - color: var(--dGray0); -} -.bootstrap-datetimepicker-widget table thead tr:first-child th:hover, -.bootstrap-datetimepicker-widget table td.day:hover, -.bootstrap-datetimepicker-widget table td.hour:hover, -.bootstrap-datetimepicker-widget table td.minute:hover, -.bootstrap-datetimepicker-widget table td span:hover, -.bootstrap-datetimepicker-widget table td.second:hover { - background: var(--dGray4); -} - -.select2-container--default .select2-results__option[aria-selected=true]{ - background-color: var(--dBlue); - color: var(--dGray0); -} -.select2-search{ - background-color: var(--dGray2); -} -.select2-search input{ - background-color: var(--dGray0); -} -.dropdown-menu{ - background-color: var(--dGray5); -} -.form-control{ - color: var(--dGray0); -} -.form-control::placeholder{ - color: var(--dGray2); -} -.enter_darkmode>a { - text-align: center; -} diff --git a/app/static/css/main.css b/app/static/css/main.css index 2689bd4..149f0f8 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -1,15 +1,19 @@ :root { /* Darkmode colors */ - --dGray0: #D0D0D8; - --dGray1: #8E8E93; - --dGray2: #636366; - --dGray3: #48484A; - --dGray4: #3A3A3C; - --dGray5: #2C2C2E; - --dGray6: #1C1C1E; - --dBlue: #0A84FF; - --FontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; - --FontSize: 13px; + --gray0: #d0d0d8; + --gray1: #8e8e93; + --gray2: #636366; + --gray3: #48484a; + --gray4: #3a3a3c; + --gray5: #2c2c2e; + --gray6: #1c1c1e; + --accent: #0a84ff; + + --bg: #2c2c2e; + --navbarBg: #1c1c1e; + + --fontFamily: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif; + --fontSize: 13px; } html { @@ -18,11 +22,11 @@ html { body { padding-top: 70px; - background-color: var(--dGray5); - color: var(--dGray1); + background-color: var(--bg); + color: var(--gray1); height: 100%; - font-family: var(--FontFamily); - font-size: var(--FontSize); + font-family: var(--fontFamily); + font-size: var(--fontSize); } .background { @@ -71,7 +75,7 @@ body { font-size: 200%; margin: 0 ; padding: 0.4em 0 0.2em; - border-bottom: 1px dashed var(--dGray1); + border-bottom: 1px dashed var(--gray1); text-align: center; } .showcase h2 { @@ -108,7 +112,7 @@ body { } .showcase .total { - border-top: 1px dashed var(--dGray1); + border-top: 1px dashed var(--gray1); text-align: center; padding: 0.5em 0; margin-top: 1.3em; @@ -166,50 +170,50 @@ a.divLink { } .table-hover tbody tr:hover{ - background-color: var(--dGray3); + background-color: var(--gray4); } a { - color: var(--dBlue); + color: var(--accent); } .btn-primary { - color: var(--dGray6); - background-color: var(--dBlue); + color: var(--gray6); + background-color: var(--accent); } .navbar { - background-color: var(--dGray6); + background-color: var(--navbarBg); } .navbar-default .navbar-nav .active a { - background-color: var(--dGray5); - color: var(--dGray1); + background-color: var(--gray5); + color: var(--gray1); } .navbar-default .navbar-nav .active a:hover, .navbar-default .navbar-nav .active a:focus, .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { - background-color: var(--dGray4); - color: var(--dGray0); + background-color: var(--gray4); + color: var(--gray0); } .navbar-default .navbar-nav li a, .navbar-default .navbar-brand { - color: var(--dGray1); + color: var(--gray1); } .navbar-default .navbar-nav li a:hover, .navbar-default .navbar-nav li a:focus, .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { - color: var(--dGray0); + color: var(--gray0); } hr{ - border-top: 1px solid var(--dGray2); + border-top: 1px solid var(--gray2); } h1, h2, h3, h4, h5, h6{ - color: var(--dGray1); + color: var(--gray1); } .jumbotron, .darker, .order_row { - background: var(--dGray4); + background: var(--gray5); } .darker { @@ -219,29 +223,29 @@ h1, h2, h3, h4, h5, h6{ } .table tbody tr td { - border-top: 1px solid var(--dGray3); + border-top: 1px solid var(--gray3); } .table thead tr th { - border-bottom: 2px solid var(--dGray2); + border-bottom: 2px solid var(--gray2); } .navbar-toggle .icon-bar { - background-color: var(--dGray0); + background-color: var(--gray0); opacity: 0.5; } .select2-container--default .select2-selection--single{ - background-color: var(--dGray3); - color: var(--dGray0); + background-color: var(--gray3); + color: var(--gray0); } .select2-container--default .select2-selection--single .select2-selection__rendered{ - color: var(--dGray0); + color: var(--gray0); } .select2-results__option{ - background-color: var(--dGray5); - color: var(--dGray0); + background-color: var(--gray5); + color: var(--gray0); } .select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: var(--dGray4); - color: var(--dGray0); + background-color: var(--gray4); + color: var(--gray0); } .bootstrap-datetimepicker-widget table thead tr:first-child th:hover, .bootstrap-datetimepicker-widget table td.day:hover, @@ -249,15 +253,15 @@ h1, h2, h3, h4, h5, h6{ .bootstrap-datetimepicker-widget table td.minute:hover, .bootstrap-datetimepicker-widget table td span:hover, .bootstrap-datetimepicker-widget table td.second:hover { - background: var(--dGray4); + background: var(--gray4); } .select2-container--default .select2-results__option[aria-selected=true]{ - background-color: var(--dBlue); - color: var(--dGray0); + background-color: var(--accent); + color: var(--gray0); } .select2-search{ - background-color: var(--dGray2); + background-color: var(--gray2); } .select2-selection--multiple .select2-search{ background-color: transparent; @@ -271,16 +275,16 @@ h1, h2, h3, h4, h5, h6{ box-sizing: content-box; } .select2-search input{ - background-color: var(--dGray0); + background-color: var(--gray0); } .dropdown-menu{ - background-color: var(--dGray5); + background-color: var(--gray5); } .form-control{ - color: var(--dGray0); + color: var(--gray0); } .form-control::placeholder{ - color: var(--dGray2); + color: var(--gray2); } #dish_choices { diff --git a/app/static/css/themes/christmas_heavy.css b/app/static/css/themes/christmas_heavy.css index fec71d9..2bb8c0d 100644 --- a/app/static/css/themes/christmas_heavy.css +++ b/app/static/css/themes/christmas_heavy.css @@ -10,40 +10,37 @@ Enige discretie is aangeraden. */ :root { - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } + --gray0: #F28705; + --gray1: white; + --gray2: #590212; + --gray3: #590212; + --gray4: #274001; + --gray5: #274001; + --gray6: #F2778D; + --accent: #F2778D; + --bg: #2F0000; + --navbarBg: #F2778D; + --fontFamily: Radikal, Optima, Segoe, Segoe UI, Candara, Calibri, Arial, sans-serif; } body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } + height: 100%; } @font-face { font-family: Radikal; src: url("static/fonts/radikal_regular.ttf"); font-weight: normal; } - @font-face { font-family: Radikal; src: url("static/fonts/radikal_light.ttf"); font-weight: 200; } - @font-face { font-family: Radikal; src: url("static/fonts/radikal_medium.ttf"); font-weight: medium; } - @font-face { font-family: Radikal; src: url("static/fonts/radikal_bold.ttf"); font-weight: bold; } - .btn { border-radius: 5rem; color: white; @@ -82,15 +79,12 @@ body { @media (min-width: 768px) { .container { width: 100%; } } - @media (min-width: 992px) { .main .container, .main .orders { width: 970px; } } - @media (min-width: 1200px) { .main .container, .main .orders { width: 1170px; } } - .main { padding-top: 2.5rem; } @@ -437,7 +431,7 @@ footer > hr { width: 1rem; height: 1rem; filter: blur(1.5px); - box-shadow: 95.5vw 70.4vh 0 -0.48rem#fff,87.9vw 28.3vh 0 -0.3rem#fff,48.4vw 63.8vh 0 -0.16rem#fff,55.2vw 23.5vh 0 -0.28rem#fff,43.2vw 62.6vh 0 -0.32rem#fff,5vw 16.6vh 0 -0.42rem#fff,34.4vw 88.5vh 0 -0.08rem#fff,63.3vw 27.4vh 0 -0.26rem#fff,58.1vw 21.3vh 0 -0.21rem#fff,58.2vw 56.7vh 0 -0.29rem#fff,81.1vw 47.1vh 0 -0.27rem#fff,89.6vw 19.1vh 0 -0.23rem#fff,76vw 67.1vh 0 -0.16rem#fff,50.8vw 26.8vh 0 -0.43rem#fff,59.1vw 73.6vh 0 -0.11rem#fff,48.2vw 55.3vh 0 -0.09rem#fff,28.1vw 65.2vh 0 -0.13rem#fff,48.3vw 77.8vh 0 -0.31rem#fff,21vw 86.9vh 0 -0.03rem#fff,8.5vw 46.7vh 0 -0.37rem#fff,65.2vw 10.1vh 0 -0.04rem#fff,16.3vw 76.3vh 0 -0.33rem#fff,36.8vw 80.3vh 0 -0.05rem#fff,64.1vw 25.3vh 0 -0.15rem#fff,69vw 4.4vh 0 -0.37rem#fff,20.6vw 59.8vh 0 -0.05rem#fff,92.5vw 58.8vh 0 -0.3rem#fff,89.3vw 76.2vh 0 -0.24rem#fff,16.4vw 77.7vh 0 -0.32rem#fff,93.4vw 49.7vh 0 -0.25rem#fff,75.7vw 50.5vh 0 -0.36rem#fff,53.8vw 45.1vh 0 -0.2rem#fff,25.2vw 42.9vh 0 -0.41rem#fff,21.7vw 63.5vh 0 -0.36rem#fff,76.8vw 29vh 0 -0.11rem#fff,27.4vw 56.2vh 0 -0.25rem#fff,10.7vw 87.3vh 0 -0.37rem#fff,71.9vw 5.2vh 0 -0.09rem#fff,64.9vw 31.5vh 0 -0.13rem#fff,24vw 21.4vh 0 -0.33rem#fff,54.9vw 18vh 0 -0.48rem#fff,4.4vw 37.8vh 0 -0.23rem#fff,58.3vw 93.1vh 0 -0.41rem#fff,56.1vw 58.2vh 0 -0.42rem#fff,17.1vw 17.4vh 0 -0.3rem#fff,69.6vw 50.9vh 0 -0.04rem#fff,81.1vw 8.8vh 0 -0.12rem#fff,69.9vw 6.2vh 0 -0.31rem#fff,86vw 17.9vh 0 -0.16rem#fff,27.7vw 14.1vh 0 -0.37rem#fff,46.9vw 10.9vh 0 -0.07rem#fff,58.3vw 93.4vh 0 -0.14rem#fff,98.9vw 1.1vh 0 -0.17rem#fff,82.5vw 36.2vh 0 -0.41rem#fff,28vw 0.5vh 0 -0.06rem#fff,0.4vw 21.8vh 0 -0.5rem#fff,70.4vw 47.8vh 0 -0.31rem#fff,16vw 42.2vh 0 -0.11rem#fff,42.1vw 14.1vh 0 -0.23rem#fff,49.3vw 67.7vh 0 -0.43rem#fff,46.2vw 69vh 0 -0.13rem#fff,23.2vw 88vh 0 -0.45rem#fff,93.2vw 88.3vh 0 -0.5rem#fff,17.3vw 22vh 0 -0.14rem#fff,57.6vw 6.5vh 0 -0.44rem#fff,26.5vw 88.2vh 0 -0.14rem#fff,85.4vw 14.8vh 0 -0.32rem#fff,33.1vw 44.2vh 0 -0.15rem#fff,1.3vw 6.4vh 0 -0.12rem#fff,1.8vw 58.5vh 0 -0.21rem#fff,85.5vw 74.1vh 0 -0.43rem#fff,82.9vw 4.4vh 0 -0.35rem#fff,94.6vw 55.2vh 0 -0.1rem#fff,7.1vw 5.1vh 0 -0.29rem#fff,47.1vw 95.8vh 0 -0.13rem#fff,69.3vw 35.3vh 0 -0.1rem#fff,8.3vw 83vh 0 -0.02rem#fff,90.8vw 47vh 0 -0.21rem#fff,85.2vw 35.3vh 0 -0.06rem#fff,80.1vw 13.6vh 0 -0.07rem#fff,52vw 37vh 0 -0.11rem#fff,75.7vw 26.3vh 0 -0.16rem#fff,51.3vw 7.7vh 0 -0.46rem#fff,35.2vw 18.6vh 0 -0.09rem#fff,69.4vw 21.3vh 0 -0.05rem#fff,16.1vw 66.8vh 0 -0.14rem#fff,80.3vw 4vh 0 -0.25rem#fff,31.1vw 78.7vh 0 -0.08rem#fff,26.9vw 45.3vh 0 -0.01rem#fff,38.3vw 11.4vh 0 -0.47rem#fff,46.7vw 10.2vh 0 -0.44rem#fff,15.5vw 2.9vh 0 -0.35rem#fff,97.8vw 19.8vh 0 -0.24rem#fff,60.8vw 94.7vh 0 -0.12rem#fff,46.1vw 66vh 0 -0.45rem#fff,59.6vw 65vh 0 -0.33rem#fff,30.5vw 44.4vh 0 -0.18rem#fff,78.2vw 55.6vh 0 -0.07rem#fff,69.5vw 61.9vh 0 -0.11rem#fff,53.4vw 38.3vh 0 -0.11rem#fff; + box-shadow: 38.1vw 38.9vh 0 -0.23rem#fff,63.6vw 92.5vh 0 -0.37rem#fff,26.2vw 19vh 0 -0.13rem#fff,43.8vw 53.8vh 0 -0.32rem#fff,18.9vw 78.9vh 0 -0.48rem#fff,78vw 88.3vh 0 -0.45rem#fff,76.2vw 40.9vh 0 -0.35rem#fff,31vw 100vh 0 -0.35rem#fff,30.9vw 40.6vh 0 -0.38rem#fff,78.3vw 68.7vh 0 -0.38rem#fff,90.8vw 12.9vh 0 -0.25rem#fff,80.4vw 98.6vh 0 -0.33rem#fff,8.8vw 75.2vh 0 -0.36rem#fff,45.3vw 50.7vh 0 -0.36rem#fff,79.6vw 2.2vh 0 -0.39rem#fff,4vw 57.4vh 0 -0.24rem#fff,68.4vw 42.8vh 0 -0.38rem#fff,62.4vw 0.5vh 0 -0.04rem#fff,99.8vw 32.8vh 0 -0.41rem#fff,71.4vw 5.4vh 0 -0.15rem#fff,62.8vw 79.2vh 0 -0.18rem#fff,82.1vw 85.2vh 0 -0.18rem#fff,45.1vw 19.1vh 0 -0.4rem#fff,35.2vw 39.2vh 0 -0.03rem#fff,95.6vw 85.1vh 0 -0.06rem#fff,77.3vw 53.1vh 0 -0.36rem#fff,3.2vw 18.3vh 0 -0.43rem#fff,55vw 88.9vh 0 -0.27rem#fff,73.7vw 1.7vh 0 -0.28rem#fff,16.7vw 45vh 0 -0.37rem#fff,78.8vw 65.8vh 0 -0.19rem#fff,10.9vw 64.9vh 0 -0.4rem#fff,42.6vw 84.1vh 0 -0.44rem#fff,4.6vw 77.8vh 0 -0.39rem#fff,40.6vw 37.6vh 0 -0.19rem#fff,82.6vw 51.2vh 0 -0.4rem#fff,15.9vw 87.9vh 0 -0.06rem#fff,7.3vw 98.7vh 0 -0.23rem#fff,91.6vw 20vh 0 -0.48rem#fff,73.6vw 26.2vh 0 -0.32rem#fff,36.3vw 24.8vh 0 -0.39rem#fff,95.3vw 55.1vh 0 -0.12rem#fff,33.1vw 34.4vh 0 -0.09rem#fff,2.7vw 86.9vh 0 -0.25rem#fff,99.8vw 99.6vh 0 -0.06rem#fff,59.3vw 88.2vh 0 -0.48rem#fff,46.5vw 84.2vh 0 -0.4rem#fff,0.9vw 40.4vh 0 -0.04rem#fff,35.8vw 16.7vh 0 -0.41rem#fff,42.7vw 19.1vh 0 -0.25rem#fff,62.9vw 89.8vh 0 -0.43rem#fff,61.6vw 100vh 0 -0.27rem#fff,61.5vw 76.9vh 0 -0.25rem#fff,33.6vw 33.1vh 0 -0.03rem#fff,59.5vw 15.7vh 0 -0.03rem#fff,13.1vw 17.1vh 0 -0.41rem#fff,39.4vw 27.9vh 0 -0.13rem#fff,70.6vw 15.5vh 0 -0.41rem#fff,29vw 27.7vh 0 -0.46rem#fff,88.2vw 64.1vh 0 -0.33rem#fff,93.3vw 42.2vh 0 -0.38rem#fff,52.4vw 55vh 0 -0.01rem#fff,48.2vw 21.7vh 0 -0.4rem#fff,16.2vw 48.9vh 0 -0.36rem#fff,36.3vw 24.2vh 0 -0.24rem#fff,28.9vw 39.6vh 0 -0.32rem#fff,50.2vw 5.1vh 0 -0.11rem#fff,67.5vw 54.6vh 0 -0.12rem#fff,44.1vw 24.5vh 0 -0.23rem#fff,91.4vw 27.6vh 0 -0.1rem#fff,93.2vw 42.3vh 0 -0.46rem#fff,59.6vw 42.4vh 0 -0.29rem#fff,88vw 39.1vh 0 -0.03rem#fff,74vw 5.6vh 0 -0.31rem#fff,49.7vw 0.1vh 0 -0.36rem#fff,93.1vw 47.2vh 0 -0.21rem#fff,54.8vw 59.2vh 0 -0.38rem#fff,27.1vw 71.9vh 0 -0.3rem#fff,20.8vw 10.8vh 0 -0.46rem#fff,20.2vw 10vh 0 -0.45rem#fff,48.9vw 79.3vh 0 -0.36rem#fff,73.3vw 21.8vh 0 -0.2rem#fff,68.4vw 21.6vh 0 -0.06rem#fff,90.1vw 87.1vh 0 -0.24rem#fff,41.6vw 99.4vh 0 -0.03rem#fff,51.4vw 58.8vh 0 -0.43rem#fff,45.7vw 3.5vh 0 -0.14rem#fff,64.7vw 99.3vh 0 -0.31rem#fff,4vw 48.3vh 0 -0.42rem#fff,86.8vw 87.5vh 0 -0.19rem#fff,81.2vw 56.6vh 0 -0.48rem#fff,95.2vw 83.9vh 0 -0.05rem#fff,30.6vw 15.7vh 0 -0.1rem#fff,32.8vw 24.3vh 0 -0.39rem#fff,83.3vw 7.8vh 0 -0.34rem#fff,41.3vw 13.3vh 0 -0.23rem#fff,63.4vw 16.5vh 0 -0.08rem#fff,57.6vw 98.5vh 0 -0.22rem#fff,78.4vw 63.8vh 0 -0.08rem#fff,49vw 29.5vh 0 -0.01rem#fff; animation-duration: 18s; } .layer1.a { @@ -447,7 +441,7 @@ footer > hr { width: 0.8rem; height: 0.8rem; filter: blur(3px); - box-shadow: 89.1vw 69.4vh 0 -0.15rem#fff,19.2vw 77.1vh 0 -0.35rem#fff,52.3vw 3.8vh 0 -0.04rem#fff,69.5vw 14.1vh 0 -0.25rem#fff,75.5vw 74.6vh 0 -0.44rem#fff,13.6vw 48vh 0 -0.36rem#fff,62.5vw 17.4vh 0 -0.2rem#fff,53.5vw 44.1vh 0 -0.41rem#fff,58.2vw 63vh 0 -0.28rem#fff,64.3vw 54.3vh 0 -0.42rem#fff,38.3vw 92.4vh 0 -0.36rem#fff,89.4vw 6.5vh 0 -0.06rem#fff,92.9vw 11.4vh 0 -0.06rem#fff,8.4vw 33.7vh 0 -0.25rem#fff,84.1vw 44.5vh 0 -0.02rem#fff,58.2vw 87.2vh 0 -0.43rem#fff,64.8vw 34.8vh 0 -0.33rem#fff,46.1vw 31.1vh 0 -0.4rem#fff,11.3vw 61.1vh 0 -0.33rem#fff,50.9vw 4.5vh 0 -0.3rem#fff,43.6vw 97.2vh 0 -0.43rem#fff,24.7vw 62.9vh 0 -0.12rem#fff,5.2vw 40.3vh 0 -0.45rem#fff,48.2vw 21.6vh 0 -0.45rem#fff,28.4vw 48.3vh 0 -0.18rem#fff,35vw 16.7vh 0 -0.09rem#fff,29.5vw 65.1vh 0 -0.11rem#fff,65.7vw 59.2vh 0 -0.15rem#fff,28vw 80.1vh 0 -0.4rem#fff,20.4vw 33.1vh 0 -0.1rem#fff,11.1vw 70.2vh 0 -0.4rem#fff,37.4vw 92.5vh 0 -0.49rem#fff,38.5vw 90.5vh 0 -0.12rem#fff,97.3vw 34.4vh 0 -0.07rem#fff,14.7vw 10.4vh 0 -0.23rem#fff,98.2vw 54.5vh 0 -0.3rem#fff,23.4vw 44vh 0 -0.17rem#fff,4.8vw 21.2vh 0 -0.26rem#fff,27vw 63.3vh 0 -0.27rem#fff,93.4vw 67.2vh 0 -0.16rem#fff,86.2vw 82vh 0 -0.02rem#fff,61.4vw 50vh 0 -0.41rem#fff,43.9vw 68.4vh 0 -0.49rem#fff,46.6vw 6.3vh 0 -0.18rem#fff,69.8vw 94.2vh 0 -0.03rem#fff,17.1vw 31.7vh 0 -0.39rem#fff,88vw 76.3vh 0 -0.13rem#fff,90.8vw 27.8vh 0 -0.5rem#fff,16.5vw 86vh 0 -0.24rem#fff,48.4vw 50vh 0 -0.12rem#fff,0.2vw 9.7vh 0 -0.29rem#fff,70.6vw 13.2vh 0 -0.34rem#fff,75.4vw 46.7vh 0 -0.02rem#fff,41.9vw 63.2vh 0 -0.09rem#fff,81.2vw 32.4vh 0 -0.44rem#fff,62.1vw 38.9vh 0 -0.29rem#fff,83.8vw 8.6vh 0 -0.46rem#fff,60.4vw 96.9vh 0 -0.37rem#fff,80.7vw 83.8vh 0 -0.14rem#fff,91.1vw 35.7vh 0 -0.45rem#fff,19.8vw 9.6vh 0 -0.11rem#fff,56.3vw 28.3vh 0 -0.11rem#fff,49.7vw 27.6vh 0 -0.21rem#fff,92.2vw 61.1vh 0 -0.37rem#fff,10.7vw 18.8vh 0 -0.04rem#fff,44.4vw 77.2vh 0 -0.41rem#fff,42.3vw 53.9vh 0 -0.32rem#fff,16vw 19.5vh 0 -0.02rem#fff,40.8vw 60.8vh 0 -0.23rem#fff,6.5vw 77.1vh 0 -0.41rem#fff,78.2vw 98.6vh 0 -0.5rem#fff,70.3vw 88vh 0 -0.34rem#fff,21.4vw 45.7vh 0 -0.2rem#fff,79.3vw 27.8vh 0 -0.16rem#fff,20.5vw 91.9vh 0 -0.1rem#fff,44vw 20.7vh 0 -0.05rem#fff,20.2vw 58.5vh 0 -0.18rem#fff,0.4vw 57.7vh 0 -0.44rem#fff,29.8vw 96.4vh 0 -0.41rem#fff,66vw 94.4vh 0 -0.01rem#fff,25.4vw 74.6vh 0 -0.37rem#fff,89.7vw 38.4vh 0 -0.04rem#fff,32vw 64vh 0 -0.4rem#fff,79.9vw 73.7vh 0 -0.45rem#fff,92.8vw 72.3vh 0 -0.46rem#fff,50.5vw 54.5vh 0 -0.47rem#fff,77.8vw 38.2vh 0 -0.29rem#fff,73.9vw 61.4vh 0 -0.17rem#fff,88.1vw 91.1vh 0 -0.37rem#fff,20.4vw 32.5vh 0 -0.39rem#fff,68.5vw 97.8vh 0 -0.42rem#fff,62.7vw 53.2vh 0 -0.11rem#fff,65.4vw 70.8vh 0 -0.14rem#fff,31.3vw 5.3vh 0 -0.12rem#fff,39.2vw 78vh 0 -0.48rem#fff,50vw 44.2vh 0 -0.01rem#fff,16.9vw 20.6vh 0 -0.05rem#fff,61.3vw 5.1vh 0 -0.48rem#fff,18.6vw 65.8vh 0 -0.35rem#fff,88.4vw 67.2vh 0 -0.5rem#fff; + box-shadow: 79.8vw 46.8vh 0 -0.07rem#fff,11.3vw 43.8vh 0 -0.4rem#fff,69.3vw 2.8vh 0 -0.27rem#fff,48.8vw 5.8vh 0 -0.13rem#fff,61.1vw 28vh 0 -0.02rem#fff,74.7vw 11.5vh 0 -0.24rem#fff,57.8vw 84.7vh 0 -0.34rem#fff,79.9vw 69.7vh 0 -0.33rem#fff,12vw 68.1vh 0 -0.49rem#fff,47.9vw 86.4vh 0 -0.23rem#fff,82.5vw 46.9vh 0 -0.24rem#fff,21.6vw 20.8vh 0 -0.14rem#fff,9.7vw 80.1vh 0 -0.29rem#fff,6.1vw 47.4vh 0 -0.17rem#fff,59.1vw 97.7vh 0 -0.19rem#fff,11.7vw 40.7vh 0 -0.46rem#fff,92.2vw 58.5vh 0 -0.2rem#fff,71.6vw 91.9vh 0 -0.01rem#fff,9.5vw 12.5vh 0 -0.33rem#fff,73.1vw 91.5vh 0 -0.13rem#fff,53.5vw 55.7vh 0 -0.01rem#fff,7.5vw 95.5vh 0 -0.48rem#fff,11.2vw 13.7vh 0 -0.08rem#fff,3.4vw 81.1vh 0 -0.5rem#fff,40.9vw 43vh 0 -0.4rem#fff,78.3vw 33.4vh 0 -0.35rem#fff,92.7vw 70.1vh 0 -0.36rem#fff,90.1vw 17.5vh 0 -0.18rem#fff,6.6vw 15.7vh 0 -0.41rem#fff,13.8vw 74.1vh 0 -0.38rem#fff,40vw 11.6vh 0 -0.35rem#fff,90.4vw 70.9vh 0 -0.48rem#fff,82.7vw 73.9vh 0 -0.23rem#fff,91.4vw 44.3vh 0 -0.21rem#fff,85.9vw 95.5vh 0 -0.01rem#fff,96.5vw 63.6vh 0 -0.39rem#fff,23.6vw 10.6vh 0 -0.04rem#fff,0.4vw 0.7vh 0 -0.24rem#fff,51.1vw 61.4vh 0 -0.12rem#fff,2.4vw 52.3vh 0 -0.06rem#fff,99.9vw 25.8vh 0 -0.22rem#fff,20.4vw 18.4vh 0 -0.05rem#fff,28vw 64.9vh 0 -0.1rem#fff,95.2vw 34.5vh 0 -0.05rem#fff,43.9vw 96.6vh 0 -0.23rem#fff,10.3vw 27.4vh 0 -0.11rem#fff,2.6vw 91.2vh 0 -0.41rem#fff,85.3vw 12.9vh 0 -0.2rem#fff,50.4vw 32.7vh 0 -0.38rem#fff,12.1vw 76.7vh 0 -0.4rem#fff,24.1vw 83.3vh 0 -0.32rem#fff,80.2vw 30.9vh 0 -0.24rem#fff,30.8vw 34.7vh 0 -0.48rem#fff,94.6vw 65vh 0 -0.08rem#fff,1.3vw 55.1vh 0 -0.36rem#fff,74.8vw 69.7vh 0 -0.04rem#fff,79.4vw 78.9vh 0 -0.19rem#fff,16.7vw 35.6vh 0 -0.19rem#fff,36vw 13.4vh 0 -0.36rem#fff,77.5vw 44.7vh 0 -0.42rem#fff,88.9vw 90.4vh 0 -0.33rem#fff,83vw 74.8vh 0 -0.3rem#fff,67.2vw 98.4vh 0 -0.14rem#fff,10vw 10.9vh 0 -0.27rem#fff,97.3vw 64.2vh 0 -0.03rem#fff,57.8vw 30.6vh 0 -0.37rem#fff,55.2vw 33.3vh 0 -0.39rem#fff,83.8vw 43.2vh 0 -0.28rem#fff,99.4vw 93.6vh 0 -0.45rem#fff,63.2vw 31.2vh 0 -0.16rem#fff,32.5vw 96.4vh 0 -0.49rem#fff,8.9vw 70.8vh 0 -0.27rem#fff,27vw 2.3vh 0 -0.46rem#fff,26.6vw 52.4vh 0 -0.31rem#fff,39.9vw 24.2vh 0 -0.04rem#fff,32.8vw 86.7vh 0 -0.42rem#fff,85.3vw 11.8vh 0 -0.14rem#fff,69vw 85.4vh 0 -0.19rem#fff,84.5vw 54.2vh 0 -0.09rem#fff,22vw 38.9vh 0 -0.34rem#fff,42.8vw 5.4vh 0 -0.35rem#fff,61.2vw 68.5vh 0 -0.26rem#fff,20.8vw 50.7vh 0 -0.01rem#fff,41.6vw 69.5vh 0 -0.15rem#fff,37.8vw 46.8vh 0 -0.05rem#fff,23vw 9.5vh 0 -0.01rem#fff,1.3vw 84.1vh 0 -0.07rem#fff,59.5vw 95.9vh 0 -0.36rem#fff,1.6vw 49.5vh 0 -0.23rem#fff,40.4vw 67.3vh 0 -0.33rem#fff,84vw 12.2vh 0 -0.27rem#fff,53.5vw 55.2vh 0 -0.39rem#fff,98.1vw 39.7vh 0 -0.33rem#fff,68.5vw 53.8vh 0 -0.33rem#fff,6.8vw 4.4vh 0 -0.45rem#fff,35.9vw 51.8vh 0 -0.11rem#fff,42.1vw 77.1vh 0 -0.21rem#fff,9.8vw 37.4vh 0 -0.01rem#fff,99.2vw 13.4vh 0 -0.26rem#fff,88.2vw 21vh 0 -0.33rem#fff; animation-duration: 24s; } .layer2.a { @@ -457,7 +451,7 @@ footer > hr { width: 0.6rem; height: 0.6rem; filter: blur(6px); - box-shadow: 12.2vw 53.5vh 0 -0.46rem#fff,38.8vw 53vh 0 -0.18rem#fff,48vw 42vh 0 -0.4rem#fff,89.7vw 31vh 0 -0.36rem#fff,67vw 60.1vh 0 -0.3rem#fff,69vw 14.5vh 0 -0.49rem#fff,6.7vw 91.1vh 0 -0.18rem#fff,13.2vw 34.7vh 0 -0.48rem#fff,70.4vw 67.8vh 0 -0.36rem#fff,85.1vw 82.5vh 0 -0.05rem#fff,16.8vw 7.6vh 0 -0.19rem#fff,6.2vw 34.2vh 0 -0.16rem#fff,8.9vw 68.8vh 0 -0.32rem#fff,58.5vw 28.3vh 0 -0.3rem#fff,41.7vw 74.1vh 0 -0.34rem#fff,10.3vw 79.8vh 0 -0.26rem#fff,8.3vw 24.6vh 0 -0.05rem#fff,33.1vw 85.4vh 0 -0.41rem#fff,20.3vw 16.9vh 0 -0.02rem#fff,21.1vw 50.7vh 0 -0.36rem#fff,14.9vw 17vh 0 -0.05rem#fff,45.8vw 17vh 0 -0.21rem#fff,25.6vw 0.8vh 0 -0.31rem#fff,35.4vw 53.4vh 0 -0.22rem#fff,19.2vw 79.1vh 0 -0.35rem#fff,74.5vw 60.8vh 0 -0.25rem#fff,88.9vw 89.9vh 0 -0.48rem#fff,48.7vw 7.2vh 0 -0.13rem#fff,88.1vw 84.1vh 0 -0.12rem#fff,63.2vw 82.3vh 0 -0.06rem#fff,99.9vw 46.2vh 0 -0.47rem#fff,92vw 59.8vh 0 -0.12rem#fff,1.6vw 8.8vh 0 -0.23rem#fff,79.8vw 2vh 0 -0.5rem#fff,58.2vw 22.4vh 0 -0.34rem#fff,47.6vw 7.3vh 0 -0.06rem#fff,28.1vw 71vh 0 -0.18rem#fff,14.2vw 77.1vh 0 -0.43rem#fff,95.5vw 68.6vh 0 -0.43rem#fff,6.7vw 8.1vh 0 -0.1rem#fff,60.2vw 36.7vh 0 -0.31rem#fff,25.8vw 27vh 0 -0.42rem#fff,1vw 60vh 0 -0.42rem#fff,64.2vw 19.1vh 0 -0.23rem#fff,80.9vw 88.8vh 0 -0.03rem#fff,3.6vw 60.1vh 0 -0.08rem#fff,30.1vw 10.9vh 0 -0.44rem#fff,38.5vw 26.3vh 0 -0.45rem#fff,44.3vw 38.8vh 0 -0.1rem#fff,16.2vw 45.5vh 0 -0.14rem#fff,90.6vw 6.6vh 0 -0.23rem#fff,15.8vw 52.6vh 0 -0.45rem#fff,30.2vw 2.7vh 0 -0.4rem#fff,3.8vw 40.1vh 0 -0.48rem#fff,10.7vw 82.2vh 0 -0.4rem#fff,90.5vw 73.3vh 0 -0.16rem#fff,72.9vw 48.3vh 0 -0.14rem#fff,17.7vw 25.7vh 0 -0.07rem#fff,84.6vw 82.3vh 0 -0.3rem#fff,69.9vw 71.5vh 0 -0.05rem#fff,34.6vw 45.9vh 0 -0.1rem#fff,81.3vw 12.5vh 0 -0.1rem#fff,58.3vw 11.4vh 0 -0.48rem#fff,17.7vw 7vh 0 -0.18rem#fff,67.5vw 27.8vh 0 -0.4rem#fff,92.1vw 63.6vh 0 -0.42rem#fff,92vw 97.7vh 0 -0.3rem#fff,7.3vw 28.6vh 0 -0.22rem#fff,93.4vw 39.8vh 0 -0.04rem#fff,27.4vw 56.7vh 0 -0.08rem#fff,2.5vw 39.9vh 0 -0.47rem#fff,61.1vw 38.3vh 0 -0.29rem#fff,42.4vw 41.2vh 0 -0.14rem#fff,85.8vw 26vh 0 -0.44rem#fff,95.9vw 70vh 0 -0.19rem#fff,77.4vw 52.9vh 0 -0.15rem#fff,54.9vw 1.2vh 0 -0.4rem#fff,47.1vw 44.2vh 0 -0.2rem#fff,60vw 66.7vh 0 -0.41rem#fff,88.2vw 72vh 0 -0.05rem#fff,77.2vw 74.3vh 0 -0.31rem#fff,77.7vw 63.2vh 0 -0.1rem#fff,15.9vw 61.7vh 0 -0.19rem#fff,13.9vw 23.5vh 0 -0.4rem#fff,81.2vw 18.9vh 0 -0.17rem#fff,20.1vw 44.6vh 0 -0.47rem#fff,59vw 4vh 0 -0.44rem#fff,6vw 40vh 0 -0.34rem#fff,12.2vw 77vh 0 -0.26rem#fff,9.5vw 20.3vh 0 -0.01rem#fff,52.6vw 58.7vh 0 -0.17rem#fff,89.5vw 32.6vh 0 -0.03rem#fff,0.2vw 83.9vh 0 -0.3rem#fff,42.3vw 73.3vh 0 -0.03rem#fff,0.5vw 15.7vh 0 -0.17rem#fff,58.1vw 98.2vh 0 -0.01rem#fff,95.7vw 4.3vh 0 -0.01rem#fff,82.7vw 57.7vh 0 -0.18rem#fff,99.6vw 2.6vh 0 -0.12rem#fff,44.5vw 68.3vh 0 -0.02rem#fff; + box-shadow: 64.8vw 75.7vh 0 -0.14rem#fff,58.4vw 85.5vh 0 -0.16rem#fff,98.2vw 40.9vh 0 -0.03rem#fff,50.5vw 40.3vh 0 -0.42rem#fff,28.8vw 85.1vh 0 -0.3rem#fff,86.8vw 47.7vh 0 -0.47rem#fff,87vw 17.9vh 0 -0.06rem#fff,31.7vw 16.2vh 0 -0.16rem#fff,90.8vw 9.8vh 0 -0.49rem#fff,98.4vw 66.5vh 0 -0.43rem#fff,33.1vw 92vh 0 -0.46rem#fff,44.7vw 23vh 0 -0.21rem#fff,82.8vw 10.7vh 0 -0.1rem#fff,14.2vw 75.9vh 0 -0.33rem#fff,7.7vw 13vh 0 -0.29rem#fff,39.8vw 98.5vh 0 -0.27rem#fff,24.1vw 80.8vh 0 -0.13rem#fff,30.6vw 21.2vh 0 -0.36rem#fff,69.1vw 92.1vh 0 -0.17rem#fff,20.6vw 58.8vh 0 -0.28rem#fff,1vw 86.4vh 0 -0.27rem#fff,32.7vw 56.3vh 0 -0.43rem#fff,83.3vw 12.9vh 0 -0.07rem#fff,19.4vw 82.1vh 0 -0.46rem#fff,59.9vw 27.9vh 0 -0.22rem#fff,45.9vw 40vh 0 -0.11rem#fff,51.5vw 21.6vh 0 -0.03rem#fff,70.8vw 15.1vh 0 -0.1rem#fff,50.7vw 44.1vh 0 -0.18rem#fff,31.3vw 0.6vh 0 -0.19rem#fff,65.4vw 13.1vh 0 -0.19rem#fff,10.6vw 64.5vh 0 -0.15rem#fff,95.5vw 75.9vh 0 -0.12rem#fff,66.4vw 94vh 0 -0.19rem#fff,33.2vw 46.2vh 0 -0.12rem#fff,33.9vw 1.5vh 0 -0.13rem#fff,43.1vw 89vh 0 -0.1rem#fff,30.4vw 39.9vh 0 -0.45rem#fff,9.3vw 93.2vh 0 -0.35rem#fff,62.6vw 99.4vh 0 -0.09rem#fff,6.5vw 68.9vh 0 -0.14rem#fff,53.8vw 8.3vh 0 -0.46rem#fff,5.4vw 96.1vh 0 -0.18rem#fff,2.8vw 60.2vh 0 -0.05rem#fff,79.9vw 46.9vh 0 -0.48rem#fff,20.9vw 40.4vh 0 -0.24rem#fff,82.2vw 44.5vh 0 -0.37rem#fff,2.9vw 94.1vh 0 -0.31rem#fff,87.7vw 28.5vh 0 -0.44rem#fff,7.7vw 46.6vh 0 -0.25rem#fff,78.5vw 59.4vh 0 -0.48rem#fff,4.5vw 72.6vh 0 -0.21rem#fff,83.8vw 73.9vh 0 -0.25rem#fff,99.8vw 8.1vh 0 -0.42rem#fff,86.6vw 31.8vh 0 -0.21rem#fff,38.8vw 77.2vh 0 -0.13rem#fff,4.6vw 16.4vh 0 -0.17rem#fff,61.3vw 85.8vh 0 -0.06rem#fff,20.3vw 97vh 0 -0.21rem#fff,26.7vw 94.3vh 0 -0.06rem#fff,10.3vw 32.7vh 0 -0.37rem#fff,66.1vw 7.3vh 0 -0.24rem#fff,23.7vw 17.2vh 0 -0.48rem#fff,79.9vw 55.4vh 0 -0.03rem#fff,76.9vw 92.2vh 0 -0.43rem#fff,14.7vw 7.2vh 0 -0.35rem#fff,27.5vw 67.1vh 0 -0.23rem#fff,50vw 7.8vh 0 -0.4rem#fff,25.3vw 79.1vh 0 -0.34rem#fff,3vw 26.3vh 0 -0.26rem#fff,81.4vw 75vh 0 -0.38rem#fff,76.9vw 11.4vh 0 -0.18rem#fff,63.1vw 29.7vh 0 -0.16rem#fff,91.5vw 28.9vh 0 -0.47rem#fff,4.4vw 33.7vh 0 -0.35rem#fff,63.5vw 73.1vh 0 -0.1rem#fff,6.6vw 83.1vh 0 -0.45rem#fff,16.4vw 89.5vh 0 -0.01rem#fff,20.2vw 70.9vh 0 -0.18rem#fff,87.6vw 62vh 0 -0.2rem#fff,94vw 56.4vh 0 -0.03rem#fff,56.8vw 71vh 0 -0.26rem#fff,34.2vw 78.5vh 0 -0.4rem#fff,81.6vw 3.9vh 0 -0.21rem#fff,84.6vw 0.4vh 0 -0.5rem#fff,25vw 38.4vh 0 -0.23rem#fff,49.5vw 22.8vh 0 -0.08rem#fff,90.4vw 71.3vh 0 -0.21rem#fff,24.6vw 52.3vh 0 -0.16rem#fff,35.7vw 50.5vh 0 -0.3rem#fff,68.4vw 67.7vh 0 -0.34rem#fff,67.1vw 33.6vh 0 -0.47rem#fff,90.8vw 98.7vh 0 -0.24rem#fff,15.6vw 86.9vh 0 -0.34rem#fff,48.6vw 65vh 0 -0.37rem#fff,38.8vw 2.6vh 0 -0.36rem#fff,55.5vw 16.2vh 0 -0.07rem#fff,58.4vw 29.6vh 0 -0.29rem#fff,35.8vw 1.1vh 0 -0.42rem#fff,61.1vw 69.5vh 0 -0.38rem#fff; animation-duration: 30s; } .layer3.a { @@ -466,7 +460,6 @@ footer > hr { @keyframes fall { 100% { transform: translateY(200vh); } } - @keyframes gradientBG { 0% { transform: translate(-10%, -10%); } @@ -474,7 +467,6 @@ footer > hr { transform: translate(-60%, -60%); } 100% { transform: translate(-10%, -10%); } } - @keyframes sled { 0% { transform: translate(-50rem, 40vh) rotate(0deg); } @@ -486,7 +478,6 @@ footer > hr { transform: translate(150vw, 40vh) rotate(40deg); } 100% { transform: translate(150vw, 40vh) rotate(40deg); } } - @keyframes train { 0% { transform: translateX(-80rem); } @@ -496,7 +487,6 @@ footer > hr { transform: translateX(100vw); } 100% { transform: translateX(100vw); } } - @keyframes follow_train { 0% { transform: translateX(-80rem) scaleX(20) scaleY(8); } @@ -506,15 +496,12 @@ footer > hr { transform: translateX(100vw) scaleX(20) scaleY(8); } 100% { transform: translateX(100vw) scaleX(20) scaleY(8); } } - @keyframes turn { 100% { transform: rotate(360deg); } } - @keyframes whobble { 100% { transform: translateY(0.5vh); } } - @keyframes snowman { 0% { transform: rotate(0); } @@ -528,7 +515,6 @@ footer > hr { transform: rotate(0); } 100% { transform: rotate(0); } } - @keyframes snowman_head { 0% { transform: rotate(-3deg); } @@ -536,7 +522,6 @@ footer > hr { transform: rotate(3deg); } 100% { transform: rotate(-3deg); } } - @keyframes merry_christmas { 0% { opacity: 0.8; } @@ -545,4 +530,4 @@ footer > hr { 100% { opacity: 0.8; } } -/*# sourceMappingURL=christmas_heavy.css.map */ \ No newline at end of file +/*# sourceMappingURL=christmas_heavy.css.map */ diff --git a/app/static/css/themes/christmas_heavy.css.map b/app/static/css/themes/christmas_heavy.css.map index 6b24b60..256ef85 100644 --- a/app/static/css/themes/christmas_heavy.css.map +++ b/app/static/css/themes/christmas_heavy.css.map @@ -1,9 +1,7 @@ { - "version": 3, - "file": "christmas_heavy.css", - "sources": [ - "christmas_heavy.scss" - ], - "names": [], - "mappings": "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" -} \ No newline at end of file +"version": 3, +"mappings": "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", +"sources": ["christmas_heavy.scss"], +"names": [], +"file": "christmas_heavy.css" +} diff --git a/app/static/css/themes/christmas_heavy.scss b/app/static/css/themes/christmas_heavy.scss index f21dcf7..4adfadf 100644 --- a/app/static/css/themes/christmas_heavy.scss +++ b/app/static/css/themes/christmas_heavy.scss @@ -10,19 +10,22 @@ Enige discretie is aangeraden. */ :root { - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; + --gray0: #F28705; + --gray1: white; + --gray2: #590212; + --gray3: #590212; + --gray4: #274001; + --gray5: #274001; + --gray6: #F2778D; + --accent: #F2778D; + + --bg: #2F0000; + --navbarBg: #F2778D; + + --fontFamily: Radikal, Optima, Segoe, Segoe UI, Candara, Calibri, Arial, sans-serif; } body{ height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } @font-face { font-family: Radikal; diff --git a/app/static/css/themes/christmas_lightweight.css b/app/static/css/themes/christmas_lightweight.css index e96e389..2050e53 100644 --- a/app/static/css/themes/christmas_lightweight.css +++ b/app/static/css/themes/christmas_lightweight.css @@ -10,35 +10,33 @@ Enige discretie is aangeraden. */ :root { - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; } + --gray0: #F28705; + --gray1: white; + --gray2: #590212; + --gray3: #590212; + --gray4: #274001; + --gray5: #274001; + --gray6: #F2778D; + --accent: #F2778D; + --bg: #2F0000; + --navbarBg: #F2778D; + --fontFamily: Radikal, Optima, Segoe, Segoe UI, Candara, Calibri, Arial, sans-serif; } body { - height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } + height: 100%; } @font-face { font-family: Radikal; src: url("static/fonts/radikal_regular.ttf"); font-weight: normal; } - @font-face { font-family: Radikal; src: url("static/fonts/radikal_light.ttf"); font-weight: 200; } - @font-face { font-family: Radikal; src: url("static/fonts/radikal_bold.ttf"); font-weight: bold; } - .btn { border-radius: 5rem; color: white; @@ -77,15 +75,12 @@ body { @media (min-width: 768px) { .container { width: 100%; } } - @media (min-width: 992px) { .main .container, .main .orders { width: 970px; } } - @media (min-width: 1200px) { .main .container, .main .orders { width: 1170px; } } - .main { padding-top: 2.5rem; } @@ -407,7 +402,6 @@ footer > hr { transform: translate(150vw, 40vh) rotate(40deg); } 100% { transform: translate(150vw, 40vh) rotate(40deg); } } - @keyframes train { 0% { transform: translateX(-80rem); } @@ -417,15 +411,12 @@ footer > hr { transform: translateX(100vw); } 100% { transform: translateX(100vw); } } - @keyframes turn { 100% { transform: rotate(360deg); } } - @keyframes whobble { 100% { transform: translateY(0.5vh); } } - @keyframes snowman { 0% { transform: rotate(0); } @@ -439,7 +430,6 @@ footer > hr { transform: rotate(0); } 100% { transform: rotate(0); } } - @keyframes snowman_head { 0% { transform: rotate(-3deg); } @@ -448,4 +438,4 @@ footer > hr { 100% { transform: rotate(-3deg); } } -/*# sourceMappingURL=christmas_lightweight.css.map */ \ No newline at end of file +/*# sourceMappingURL=christmas_lightweight.css.map */ diff --git a/app/static/css/themes/christmas_lightweight.css.map b/app/static/css/themes/christmas_lightweight.css.map index 5e25b2d..285e888 100644 --- a/app/static/css/themes/christmas_lightweight.css.map +++ b/app/static/css/themes/christmas_lightweight.css.map @@ -1,9 +1,7 @@ { - "version": 3, - "file": "christmas_lightweight.css", - "sources": [ - "christmas_lightweight.scss" - ], - "names": [], - "mappings": "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" -} \ No newline at end of file +"version": 3, +"mappings": "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", +"sources": ["christmas_lightweight.scss"], +"names": [], +"file": "christmas_lightweight.css" +} diff --git a/app/static/css/themes/christmas_lightweight.scss b/app/static/css/themes/christmas_lightweight.scss index 73bd16d..0e3628f 100644 --- a/app/static/css/themes/christmas_lightweight.scss +++ b/app/static/css/themes/christmas_lightweight.scss @@ -10,19 +10,22 @@ Enige discretie is aangeraden. */ :root { - --dGray0:#F28705; - --dGray1:white; - --dGray2:#590212; - --dGray3:#590212; - --dGray4:#274001; - --dGray5:#274001; - --dGray6:#F2778D; - --dBlue:#F2778D; + --gray0: #F28705; + --gray1: white; + --gray2: #590212; + --gray3: #590212; + --gray4: #274001; + --gray5: #274001; + --gray6: #F2778D; + --accent: #F2778D; + + --bg: #2F0000; + --navbarBg: #F2778D; + + --fontFamily: Radikal, Optima, Segoe, Segoe UI, Candara, Calibri, Arial, sans-serif; } body{ height: 100%; - font-family: Radikal,Optima,Segoe,Segoe UI,Candara,Calibri,Arial,sans-serif; - background-color: #2F0000; } @font-face { font-family: Radikal; diff --git a/app/static/css/themes/halloween.css b/app/static/css/themes/halloween.css index 8d07136..f042cdc 100644 --- a/app/static/css/themes/halloween.css +++ b/app/static/css/themes/halloween.css @@ -1,12 +1,15 @@ :root { - --dGray0:#FFEB65; - --dGray1:#F28705; - --dGray2:#F25C05; - --dGray3:#F27405; - --dGray4:#8C3D0F; - --dGray5:#260101; - --dGray6:#260101; - --dBlue:#D91604; + --gray0: #ffeb65; + --gray1: #f28705; + --gray2: #f25c05; + --gray3: #f27405; + --gray4: #8c3d0f; + --gray5: #260101; + --gray6: #260101; + --accent: #d91604; + + --bg: #260101; + --navbarBg: #260101; } .table-hover tbody tr:hover{ diff --git a/app/static/css/themes/plain_darkmode.css b/app/static/css/themes/plain_darkmode.css index 3b5d50f..8617f86 100644 --- a/app/static/css/themes/plain_darkmode.css +++ b/app/static/css/themes/plain_darkmode.css @@ -1,10 +1,13 @@ :root { - --dGray0:#D0D0D8; - --dGray1:#8E8E93; - --dGray2:#636366; - --dGray3:#48484A; - --dGray4:#3A3A3C; - --dGray5:#2C2C2E; - --dGray6:#1C1C1E; - --dBlue:#0A84FF; + --gray0: #d0d0d8; + --gray1: #8e8e93; + --gray2: #636366; + --gray3: #48484a; + --gray4: #3a3a3c; + --gray5: #2c2c2e; + --gray6: #1c1c1e; + --accent: #0a84ff; + + --bg: #222224; + --navbarBg: #1c1c1e; } diff --git a/app/static/css/themes/plain_lightmode.css b/app/static/css/themes/plain_lightmode.css index cb6baf7..1dcacf8 100644 --- a/app/static/css/themes/plain_lightmode.css +++ b/app/static/css/themes/plain_lightmode.css @@ -1,10 +1,13 @@ :root { - --dGray0:#212121; - --dGray1:#444444; - --dGray2:#666666; - --dGray3:#cccccc; - --dGray4:#f1f1f1; - --dGray5:#f8f8f8; - --dGray6:#ffffff; - --dBlue:#0A84FF; + --gray0: #212121; + --gray1: #444444; + --gray2: #666666; + --gray3: #cccccc; + --gray4: #f1f1f1; + --gray5: #f8f8f8; + --gray6: #ffffff; + --accent: #0a84ff; + + --bg: #ffffff; + --navbarBg: #f8f8f8; } diff --git a/app/static/css/themes/sinterklaas.css b/app/static/css/themes/sinterklaas.css index 56c32a7..5882825 100644 --- a/app/static/css/themes/sinterklaas.css +++ b/app/static/css/themes/sinterklaas.css @@ -1,12 +1,12 @@ :root { - --dGray0:#F2EB80; - --dGray1:#F2EF05; - --dGray2:#F2EF05; - --dGray3:#177EBF; - --dGray4:#0C6AA6; - --dGray5:#F20505; - --dGray6:#F50B00; - --dBlue:#35F546; + --gray0: #f2eb80; + --gray1: #f2ef05; + --gray2: #f2ef05; + --gray3: #177ebf; + --gray4: #0c6aa6; + --gray5: #f20505; + --gray6: #f50b00; + --accent: #35f546; } .background{ diff --git a/app/templates/order.html b/app/templates/order.html index 2cbfc65..108373a 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -260,7 +260,7 @@ {% else %} - + {%- endif %} @@ -299,7 +299,7 @@ {% endblock %} {% block scripts %} -- 2.43.4 From d1fcea7391771e75dbba8b40154aa47e7ec35ad2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 18 Sep 2020 19:54:00 +0200 Subject: [PATCH 086/197] Migrate menus to separate repo --- .gitignore | 3 + data/README.md | 110 ------- data/fitchen.hlds | 80 ------ data/fritoloog.hlds | 111 -------- data/ocean_garden.hlds | 71 ----- data/ocean_garden_future_syntax.hlds-disabled | 88 ------ data/prima_donna.hlds | 41 --- data/s5.hlds | 190 ------------- data/s5_generate.py | 98 ------- data/simpizza.hlds | 268 ------------------ 10 files changed, 3 insertions(+), 1057 deletions(-) delete mode 100644 data/README.md delete mode 100644 data/fitchen.hlds delete mode 100644 data/fritoloog.hlds delete mode 100644 data/ocean_garden.hlds delete mode 100644 data/ocean_garden_future_syntax.hlds-disabled delete mode 100644 data/prima_donna.hlds delete mode 100644 data/s5.hlds delete mode 100755 data/s5_generate.py delete mode 100644 data/simpizza.hlds diff --git a/.gitignore b/.gitignore index e3056d3..e35c022 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +menus/ + + # Byte-compiled / optimized / DLL files __pycache__/ *.pyc diff --git a/data/README.md b/data/README.md deleted file mode 100644 index 51aee8c..0000000 --- a/data/README.md +++ /dev/null @@ -1,110 +0,0 @@ -# HLDS data format - -HLDS is the Haldis Language for Describing Servings. It defines the menu you see when ordering in -Haldis. - -There is syntax highlighting support for editors in `etc/` in the Haldis repository. - -## Indentation -Indentation requires hard **tabs**. Spaces will not work. - -## Identifiers -You must choose an identifier for each location, dish, choice, option and tag. Identifiers may -consist of numbers, hyphens, underscores and lowercase letters of the alphabet (a through z). - -* Allowed: `0-my_identifier` -* Disallowed: ~~`0 My Identifié`~~ - -## Locations - -A HLDS file consists of one or more locations. Each location starts with a header, which is enclosed -in "fences" of at least three equal signs. The first line of the header contains the ID and name of -the location. Further lines contain the metadata of the location, such as the phone number and -OpenStreetMap element. In the future, the phone number and such will be fetched from OpenStreetMap. - -```hlds -========================== -ocean_garden: Ocean Garden - osm https://www.openstreetmap.org/node/2275105003 - phone +32 9 222 72 74 - address Zwijnaardsesteenweg 399, 9000 Gent - website http://oceangarden.byethost3.com/ - # Comments are allowed too! -========================== -``` - -## Dishes - -A location consists of dishes. Spaces can be used to align the elements of your dish (but that's -not required). - -```hlds -dish cheeseburger: Cheeseburger € 2.9 -dish assortment: Twijfelaar € 3 -``` - -## Inline choices -Dishes can contain choices. There are two types: -* `single_choice` is a required choice where the user must choose one option. -* `multi_choice` is an optional choice where the user can choose zero or more options. - -```hlds -dish fries: Frietjes - single_choice size: Formaat - extra_small: Extra small € 1.8 - small: Small € 2 - medium: Medium € 2.5 - large: Large € 3.3 - multi_choice sauce: Saus - ketchup: Ketchup € 1.4 - mayo: Mayonaise € 1.4 - bicky: Bickysaus € 1.4 - stew: Stoofvleessaus € 1.9 -``` - -## Common choices -Choices that are used more than once, can be declared once and referenced in multiple dishes. - -```hlds -bami_nasi: Bami of nasi - bami: Bami - nasi: Nasi - -dish wok3: Studentenwok 3 kip bami/nasi zonder saus € 6 - single_choice bami_nasi - -dish wok5: Studentenwok 5 babi pangang € 6 - single_choice bami_nasi -``` - -## Descriptions -You can add descriptions to dishes, choices and options. Separate name and description with ` -- `. - -```hlds -dish dishid: Name -- This is a description € 3 -``` - -## Tags - -**Note:** Only the `{no_text}` tag is supported at this moment. You can ignore other tags for now. - -You can add tags after ` :: `. Tags are `{identifier}`. You can use tags to attach more information -about a dish or option in a structured way. For example: `{has_meat}` signals to vegetarians that -they should avoid this. - -The order is always id, name, description, tags, price (not all have to be present of course). - -```hlds -dish dishid: Name -- This is a description :: {has_meat} € 3 -``` - -The `{no_text}` tag signals that an option is not to be shown in a dish's description. This is -useful for choices that have a default that needs not be read when ordering. - -```hlds -veggie: Vegetarische opties - meat: Niet vegetarisch :: {has_meat} {no_text} - tofu: Vegetarisch met tofu - falafel: Vegetarisch met falafel - vegan: Veganistisch -``` diff --git a/data/fitchen.hlds b/data/fitchen.hlds deleted file mode 100644 index a17cc0a..0000000 --- a/data/fitchen.hlds +++ /dev/null @@ -1,80 +0,0 @@ -============================================= -fitchen: Fitchen - osm https://www.openstreetmap.org/node/3394542496 - website https://www.fitchen.be/ - address Vlaanderenstraat 129, 9000 Gent - phone +32 9 310 44 62 - # Menu: https://www.fitchen.be/wp-content/uploads/2020/06/Fitchen-Menu-Zomer-2020.pdf -============================================= - -size: Grootte - small: Small -- ±400 kcal € 7.99 - medium: Medium -- ±600 kcal € 9.99 - large: Large -- ±800 kcal € 11.99 - -bowl_wrap: Bowl of wrap - bowl: Bowl -- Wegwerpschaal - wrap: Volkorenwrap - -# Veggie/vegan -dish sunset_beach: Sunset beach -- Tofu, bruine rijst, slamix, Fitchens currydressing - single_choice bowl_wrap - single_choice size - -dish hot_tempeh: Hot tempeh -- Gekruide tempeh, quinoa, slamix, Fitchens spicy dressing - single_choice bowl_wrap - single_choice size - -dish vegan_avocado_spring: Vegan avocado spring -- Gekruide tempeh, quinoa, avocado, rode ui, komkommer, kerstomaten, babyspinazie, lijnzaad, vegan spicy dressing - single_choice bowl_wrap - single_choice size - -dish vegan_healthy_wave: Vegan healthy wave -- Tofu, quinoa, mango, edamamebonen, avocado, zwarte bonen, kerstomaten, ijsbergsla, vegan notendressing, pindakruimels - single_choice bowl_wrap - single_choice size - - -# Kip -dish avocado_chick: Avocado chick -- Kip, zoete aardappel, ijsbergsla, paprika, avocado, parmezaan, maïs, Fitchens mosterddressing - single_choice bowl_wrap - single_choice size - -dish spicy_chicken: Spicy chicken -- Kip, quinoa, slamix, Fitchens spicy dressing - single_choice bowl_wrap - single_choice size - -dish indian_summer: Indian summer -- Kip, bruine rijst, slamix, Fitchens currydressing - single_choice bowl_wrap - single_choice size - -dish olive_garden: Olive garden -- Kip, volkorenpasta, babyspinazie, kerstomaten, parmezaan, zwarte olijven, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - -dish healthy_wave: Vegan healthy wave -- Kip, quinoa, mango, edamamebonen, avocado, zwarte bonen, kerstomaten, ijsbergsla, vegan notendressing, pindakruimels - single_choice bowl_wrap - single_choice size - - -# Rund -dish spicy_mexican: Spicy Mexican -- Mager rundvlees, quinoa, ijsbergsla, avocado, parmezaan, maïs, paprika, Fitchens spicy dressing - single_choice bowl_wrap - single_choice size - -dish beefcake: Beefcake -- Mager rundvlees, zoete aardappel, slamix, Fitchens mosterddressing - single_choice bowl_wrap - single_choice size - -dish iron_man: Iron man -- Mager rundvlees, volkorenpasta, kerstomaten, parmezaan, zwarte olijven, babyspinazie, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - - -# Vis -dish captain: Captain -- Gerookte zalm, volkorenpasta, witte ui, babyspinazie, kerstomaten, Fitchens basilicum-pestodressing - single_choice bowl_wrap - single_choice size - -dish slim_fish: Slim fish -- Gerookte zalm, bruine rijst, babyspinazie, radijs, edamamebonen, komkommer, maïs, avocado, sesamzaad, Fitchens spicy dressing - single_choice bowl_wrap - single_choice size diff --git a/data/fritoloog.hlds b/data/fritoloog.hlds deleted file mode 100644 index b3794ee..0000000 --- a/data/fritoloog.hlds +++ /dev/null @@ -1,111 +0,0 @@ -============================ -fritoloog: Fritoloog - osm https://www.openstreetmap.org/node/5813542646 - address Voskenslaan 413, 9000 Gent - phone +32 495 22 19 75 - website https://defritoloog.be - # Op bovenstaande website kan men ook online bestellen -============================ - -dish fries: Frietjes :: {has_meat} - # Gebakken in rundsvet dus {has_meat} - - single_choice size: Formaat - extra_small: Extra small € 1.8 - small: Small € 2 - medium: Medium € 2.5 - large: Large € 3.3 - - multi_choice sauce € 1.4 - -dish standalone_sauce: Saus in potje € 0.8 - single_choice sauce - -sauce: Saus - ketchup: Ketchup - mayo: Mayonaise - bicky: Bickysaus - stew: Stoofvleessaus :: {has_meat} € 0.5 - other: Andere (in commentaar) - -extra_cheese: Extra kaas - no_extra_cheese: Geen extra kaas :: {no_text} - yes_extra_cheese: Extra kaas € 0.2 - -dish chicken_fingers: Kippenvingers :: {has_meat} € 3 -dish nuggiz: Nuggiz :: {has_meat} € 3 -dish mammoth_sausage: Mammoetworst :: {has_meat} € 2.1 -dish taco: Taco :: {has_meat} € 2.5 -dish ragoezi: Ragoezi :: {has_meat} € 2 -dish gypsy_stick: Zigeunerstick :: {has_meat} € 2 -dish frikandel: Frikandel :: {has_meat} € 1.5 -dish frikandel_special: Frikandel special :: {has_meat} € 2.2 -dish frikandel_xxl: XXL Frikandel :: {has_meat} € 3 -dish viandel: Viandel :: {has_meat} € 1.8 -dish viandel_spicy: Spicy-viandel :: {has_meat} € 1.8 -dish chicken_corn: Kipcorn :: {has_meat} € 1.8 -dish sito: Sito :: {has_meat} € 2.7 -dish horse_garlic_sausage: Paardenlookworst :: {has_meat} € 2.4 -dish garlic_sausage: Lookworst :: {has_meat} € 2.4 -dish bitterbal: Bitterbal :: {has_meat} € 1.5 -dish boulet: Boulet :: {has_meat} € 1.8 -dish chicken_spring_roll: Kippenloempia :: {has_meat} € 3 -dish meat_croquette: Vleeskroket :: {has_meat} € 1.8 -dish chicken_drumsticks: Kippenboutjes :: {has_meat} € 3.2 -dish fire_breather: Vuurvreter :: {has_meat} € 2 -dish mexicano: Mexicano :: {has_meat} € 2.4 -dish ardeens_satay: Ardeense saté :: {has_meat} € 2.5 -dish satay: Saté :: {has_meat} € 2.7 -dish grisley: Grisley :: {has_meat} € 2.7 -dish flemish_stew: Stoofvlees :: {has_meat} € 4.5 -dish meatballs_tomato_sauce: Balletjes in tomatensaus :: {has_meat} € 4.5 -dish assortment: Twijfelaar :: {has_meat} € 3 - -# Burgers -dish hamburger: Hamburger :: {has_meat} € 2.6 - single_choice extra_cheese -dish samuraiburger: Samuraiburger :: {has_meat} € 2.6 - single_choice extra_cheese -dish joppieburger: Joppieburger :: {has_meat} € 2.6 - single_choice extra_cheese -dish cheeseburger: Cheeseburger :: {has_meat} € 2.9 - single_choice extra_cheese -dish chicken_burger: Chickenburger :: {has_meat} € 3.2 - single_choice extra_cheese -dish bicky_burger: Bickyburger :: {has_meat} € 2.9 - single_choice extra_cheese -dish bicky_rib: Bicky Rib :: {has_meat} € 3.5 - single_choice extra_cheese -dish bicky_royal: Bicky Royal :: {has_meat} € 4.3 - single_choice extra_cheese -dish bicky_chicken: Bicky Chicken :: {has_meat} € 3.2 - single_choice extra_cheese -dish bicky_wrap: Bicky Wrap :: {has_meat} € 3 - single_choice extra_cheese - -dish grill_burger: Burger op de grill :: {has_meat} € 5.5 - single_choice soort: Soort burger # FIXME maybe change this desciption - keizer_karel: Keizer Karel - walter_de_buck: Walter De Buck - john_massis: John Massis € 0.5 - pierke_pierlala: Pierke Pierlala € 0.5 - van_eyck: Van Eyck € 0.5 - - -dish fish_burger: Fishburger :: {has_fish} € 3 -dish cod_stick: Kabeljauwstick :: {has_fish} € 2.5 -dish shrimp_croquette: Garnaalkroket :: {has_fish} € 2 - -dish chili_cheese: Chili cheese (veggie) :: € 2.7 -dish mozarella_sticks: Mozarellasticks (veggie) :: € 3 -dish cheese_croquette: Kaaskroket (veggie) :: € 1.5 -dish veggi_burger: Veggieburger :: € 3.2 -dish cheese_souflesse: Kaassouflesse (veggie) :: € 1.5 - # https://www.vangeloven.com/merk/souflesse -dish bonita: Bonita (veggie) :: € 2 - # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentesnack-vries-bonita/ -dish sajoera: Sajoera (veggie) :: € 2 - # https://www.devriesvanoers.nl/assortiment/specialiteiten/vegetarisch-groentekroket-vries-sajoera/ -dish veg_cheese_disc: Groenten-kaasschijf (veggie) :: € 2.4 -dish mini_spring_rolls: Mini-loempia's (veggie) :: € 3 -dish bami: Bami (veggie) :: € 2 diff --git a/data/ocean_garden.hlds b/data/ocean_garden.hlds deleted file mode 100644 index 12f571f..0000000 --- a/data/ocean_garden.hlds +++ /dev/null @@ -1,71 +0,0 @@ -============================================= -ocean_garden: Ocean Garden - osm https://www.openstreetmap.org/node/2275105003 - address Zwijnaardsesteenweg 399, 9000 Gent - phone +32 9 222 72 74 - website http://oceangarden.byethost3.com/ - - # Studentenmenu wordt beschreven op - # http://oceangarden.byethost3.com/studentenmenus.html?i=1 - # http://oceangarden.byethost3.com/joomla/index.php/studentenmenu - # Rest van menu wordt beschreven op - # http://oceangarden.byethost3.com/joomla/index.php/menu -============================================= - -bami_nasi: Bami of nasi - bami: Bami -- Tarwenoedels - nasi: Nasi -- Rijst - -bami_mihoen: Bami of mihoen - bami: Bami -- Tarwenoedels - mihoen: Mihoen -- Dunne, Chinese noedels, gemaakt van rijstbloem - -sauce: Saus - bali: Bali -- Indonesische saus - yusiang: Yu-siang -- Chinese saus met chili, pijpajuin, gember en look - gonboa: Gon-boa -- Pikante kruidensaus uit het westen van China - curry: Curry - sweetsour: Zoetzuur - oyster: Oester :: {has_fish} - pepper: Pepersaus - mushroom: Champignon -- Saus met champignon, wortel en wat andere groentjes - malaysian: A la Maleisië -- Licht pikante saus - - -# Student woks -dish wok5: Babi pangang -- Geroosterd varkensvlees :: {has_meat} € 6 - single_choice bami_nasi - -dish wok1_chicken: Kip met saus :: {has_meat} € 6 - single_choice bami_nasi - single_choice sauce -dish wok1_pork: Varken met saus :: {has_meat} € 6 - single_choice bami_nasi - single_choice sauce - -dish wok1_breaded_chicken: Kippenballetjes zoetzuur :: {has_meat} € 6 - single_choice bami_nasi -dish wok1_breaded_pork: Varkensballetjes zoetzuur :: {has_meat} € 6 - single_choice bami_nasi - -dish wok2_chicken: Wok 2: kip zonder saus :: {has_meat} € 6 - single_choice bami_mihoen -dish wok2_pork: Wok 2: varken zonder saus :: {has_meat} € 6 - single_choice bami_mihoen - -dish wok3_chicken: Wok 3: kip met rijst zonder saus :: {has_meat} € 6 -dish wok3_pork: Wok 3: varken met rijst zonder saus :: {has_meat} € 6 - -dish wok4: Vegetarisch met saus € 6 - single_choice bami_nasi - single_choice sauce - -# Vegetarian dishes -dish chop_choy: 76. Chop Choy (veggie) -- Sojascheuten, met gebakken rijst € 9 -dish tjap_tjoy: 77. Tjap Tjoy (veggie) -- Diverse groenten met gebakken rijst, veggie € 9 -dish mihoen_veggies: 78. Mihoen met diverse groenten (veggie) -- Rijstnoedels € 10 -dish chau_ming_veggies: 79. Chau ming met diverse groenten (veggie) -- Eiernoedels € 10 -dish tau_foe_ma_po: 80. Tau Foe met ma-po-saus (veggie) -- Met gebakken rijst € 11.5 -dish tau_foe_mushrooms: 81. Tau Foe met Chinese champignons (veggie) -- Met gebakken rijst € 11.5 - -dish chopsticks: Stokjes diff --git a/data/ocean_garden_future_syntax.hlds-disabled b/data/ocean_garden_future_syntax.hlds-disabled deleted file mode 100644 index 102d93f..0000000 --- a/data/ocean_garden_future_syntax.hlds-disabled +++ /dev/null @@ -1,88 +0,0 @@ -# Syntaxprimer: -# • Bestanden kunnen geconcateneerd worden, de syntax “== label: Naam” opent een nieuwe locatie. -# • Alle labels binnen een locatie moeten uniek zijn. -# • “single_choice” is een keyword dat betekent: optiegroep met verplicht 1 keuze. “multi_choice” -# betekent: keuzegroep met 0..∞ keuzes. -# • Dubbelepunt leidt de naam in, dubbele hyphen de beschrijving. Bij basisgerechten en opties kan -# ook een prijs gegeven worden. Alles kan ook tags krijgen, ik dacht aan allergiën of diëten: -# {has_meat} en {has_fish} markeren dingen als niet-vegetarisch. Volgorde is altijd -# “label: Naam -- Beschrijving :: {tag1} {tag2} €prijs”. -# • *label (mix-in) voegt alle entries in in het huidige blok. Bruikbaar in basisgerechten en in -# opties. -# • Attributen propageren van optiegroep naar de opties erin. Daarmee bedoel ik dat de {has_meat} -# op “meat” op de “pork” zal plakken, zodat “wok1_4” {has_meat} krijgt als je “pork” bij kiest. - -============================================= -og: Ocean Garden - # Openingsuren, website, telefoonnummer, adres enz. worden uit OpenStreetMap gehaald - osm https://www.openstreetmap.org/node/2275105003 -============================================= - -carbs: Koolhydraten - bami: Bami -- Tarwenoedels - nasi: Nasi -- Rijst - mihoen: Mihoen -- Dunne, Chinese noedels, gemaakt van rijstbloem - - # De balletjes worden enkel getoond bij gerechten waar je "sweetsour" kán kiezen, en worden enkel - # geactiveerd als "sweetsour" ook effectief gekozen is – idealiter staat bij een niet-actieve - # keuze ook de reden erbij - balls: Gepaneerde balletjes € 3 - requires sweetsour - -bami_nasi: Bami of nasi - *bami_nasi - only bami, nasi - -sauce: Saus - bali: Bali -- Indonesische saus - yusiang: Yu-siang -- Chinese saus met chili, pijpajuin, gember en look - gonboa: Gon-boa -- Pikante kruidensaus uit het westen van China - curry: Curry - sweetsour: Zoetzuur - oyster: Oester :: {has_fish} - pepper: Pepersaus - mushroom: Champignon - malaysian: A la Maleisië -- Licht pikante saus - -meat: Vlees :: {has_meat} - chicken: Kip - pork: Varken - duck: Eend - -maybe_meat: Vlees - *meat - no_meat: Geen vlees - - -# Studentenwok 1 en 4 zijn eigenlijk hetzelfde -dish wok1_4: Studentenwok met saus € 6 - single_choice carbs - except mihoen - single_choice maybe_meat - except duck - -dish wok2: Studentenwok kip/varken bami/mihoen zonder saus € 6 - single_choice carbs - except nasi - single_choice meat - only chicken, pork - -dish wok3: Studentenwok kip bami/nasi zonder saus € 6 - single_choice bami_nasi - single_choice meat - only chicken - -dish wok5: Studentenwok Babi Pangang -- Geroosterd varkensvlees :: {has_meat} € 6 - single_choice bami_nasi - single_choice sauce - -dish veggie: VEGETARISCH-PURISTISCH demo-entry waarbij je ENKEL VEGGIE kan kiezen = LETTERLIJIK HET BESTE € 6 - single_choice carbs - single_choice sauce - except {has_fish} - except {has_meat} - - -preset bbp: Bami Babi Pangang - wok5 - bami diff --git a/data/prima_donna.hlds b/data/prima_donna.hlds deleted file mode 100644 index 9b9eb00..0000000 --- a/data/prima_donna.hlds +++ /dev/null @@ -1,41 +0,0 @@ -======================== -prima_donna: Prima Donna - address Overpoortstraat 46, 9000 Gent - website https://primadonnagent.be - phone +32 475 40 13 00 -======================== - -dish basic_pizza: Basispizza :: € 4.5 -dish margarita: Pizza margharita :: € 4.5 -dish pepperoni: Pizza pepperoni :: € 5.75 -dish parma: Pizza Parma :: € 5.75 -dish fungi: Pizza funghi :: € 5.5 -dish mamma_mia: Pizza mamma mia :: € 5.5 -dish napoletana: Pizza Napoletana :: € 5.75 -dish exotic: Pizza exotic :: € 5.75 -dish siciliana: Pizza Siciliana :: € 5.75 -dish michelangelo: Pizza Michelangelo :: € 5.75 -dish roma: Pizza Roma :: € 5.75 -dish torno: Pizza torno :: € 5.75 -dish bolognese: Pizza bolognese :: € 6 -dish hawaii: Pizza hawaï :: € 7 -dish cipolla: Pizza cipolla :: € 7 -dish dolce_vita: Pizza dolce vita :: € 7 -dish valentino: Pizza valentino :: € 7 -dish vegateriana: Pizza vegateriana :: € 7.7 -dish la_donna: Pizza la donna :: € 7.7 -dish tropical: Pizza tropical :: € 7.7 -dish quattro_stagioni: Pizza quattro stagioni :: € 7.7 -dish romana: Pizza Romana :: € 7.7 -dish diabolo: Pizza diabolo :: € 7.7 -dish turkish: Pizza Turkish :: € 7.7 -dish cesar: Pizza Cesar :: € 7.7 -dish calzone: Pizza calzone :: € 8 -dish calzone_vegetariana: Pizza calzone Vegetariana :: € 8 -dish quattro_formaggi: Pizza quattro formaggi :: € 8 -dish frutti_di_mare: Pizza frutti di mare :: € 8 -dish gerookte_ham_en_rucola: Pizza gerookte ham en rucola :: € 8 -dish van_de_chef: Pizza van de chef :: € 9 -dish milano: Pizza Milano :: € 9 -dish soronto: Pizza soronto :: € 9.7 -dish prima_donna: Pizza Prima Donna :: € 9.7 diff --git a/data/s5.hlds b/data/s5.hlds deleted file mode 100644 index eda521c..0000000 --- a/data/s5.hlds +++ /dev/null @@ -1,190 +0,0 @@ -============================ -s5: S5 - osm https://www.openstreetmap.org/node/3752879366 - address Krijgslaan 281, 9000 Gent - website https://www.ugent.be/student/nl/meer-dan-studeren/resto/restos/restocampussterre.htm -============================ - -dish sandwich_kaas: Broodje Kaas -- Kaas, ei, komkommer, sla, tomaat en mayonaise - single_choice sandwich: Broodje - small_white: Klein wit € 1.40 - small_brown: Klein bruin € 1.40 - large_white: Groot wit € 2.10 - large_brown: Groot bruin € 2.10 - quattro: Quattro € 2.10 - -dish sandwich_kruidenkaas: Broodje Kruidenkaas -- Kruidenkaas, ei, komkommer, sla en tomaat - single_choice sandwich: Broodje - small_white: Klein wit € 1.40 - small_brown: Klein bruin € 1.40 - large_white: Groot wit € 2.10 - large_brown: Groot bruin € 2.10 - quattro: Quattro € 2.10 - -dish sandwich_kipcurry: Broodje Kip curry -- Kip curry, ei, komkommer, sla en tomaat - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.20 - large_brown: Groot bruin € 2.20 - quattro: Quattro € 2.20 - -dish sandwich_kipcurryhawa: Broodje Kip curry Hawaï -- Kip curry, ananas, ei, komkommer, sla en tomaat - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.20 - large_brown: Groot bruin € 2.20 - quattro: Quattro € 2.20 - -dish sandwich_vissalade: Broodje Vissalade -- Duurzame vissalade, tomaat, sla, komkommer en ei - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.30 - large_brown: Groot bruin € 2.30 - quattro: Quattro € 2.30 - -dish sandwich_ham: Broodje Ham -- Ham, ei, komkommer, sla, tomaat en mayonaise - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.30 - large_brown: Groot bruin € 2.30 - quattro: Quattro € 2.30 - -dish sandwich_prepare: Broodje Preparé -- Preparé, ei, komkommer, sla en tomaat - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.30 - large_brown: Groot bruin € 2.30 - quattro: Quattro € 2.30 - -dish sandwich_springbreak: Broodje Spring break -- Erwten-munt spread, komkommer, radijs, sla, croutons, cocktailsaus - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.40 - large_brown: Groot bruin € 2.40 - quattro: Quattro € 2.40 - -dish sandwich_argenteuil: Broodje Argenteuil -- Ham, asperge, ei, komkommer, sla, tomaat en mayonaise - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.40 - large_brown: Groot bruin € 2.40 - quattro: Quattro € 2.40 - -dish sandwich_brie: Broodje Brie -- Brie, honing, pijnboompitten, sla - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.50 - large_brown: Groot bruin € 2.50 - quattro: Quattro € 2.50 - -dish sandwich_caesar: Broodje Caesar -- Kippenreepjes, Gran Moravia kaasschilfers, croutons, sla en caesardressing - single_choice sandwich: Broodje - small_white: Klein wit € 1.50 - small_brown: Klein bruin € 1.50 - large_white: Groot wit € 2.50 - large_brown: Groot bruin € 2.50 - quattro: Quattro € 2.50 - -dish sandwich_martino: Broodje Martino -- Preparé, augurk, tomaat, mosterd en tabasco - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.40 - large_brown: Groot bruin € 2.40 - quattro: Quattro € 2.40 - -dish sandwich_maison: Broodje Maison -- Ham, kaas, augurk, ei, sla, tomaat, cocktailsaus en mayonaise - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.40 - large_brown: Groot bruin € 2.40 - quattro: Quattro € 2.40 - -dish sandwich_tropical: Broodje Tropical -- Ham, kaas, ananas, ei, sla, cocktailsaus - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.40 - large_brown: Groot bruin € 2.40 - quattro: Quattro € 2.40 - -dish sandwich_groentespread: Broodje Groentespread -- Weekelijks wisselende groentespread - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.60 - large_brown: Groot bruin € 2.60 - quattro: Quattro € 2.60 - -dish sandwich_gerooktezalmmetkruidenkaas: Broodje Gerookte zalm met kruidenkaas -- Gerookte zalm, kruidenkaas en ui - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.60 - large_brown: Groot bruin € 2.60 - quattro: Quattro € 2.60 - -dish sandwich_toscane: Broodje Toscane -- Mozzarella, prosciutto ham, sla en tomatensalsa - single_choice sandwich: Broodje - small_white: Klein wit € 1.60 - small_brown: Klein bruin € 1.60 - large_white: Groot wit € 2.70 - large_brown: Groot bruin € 2.70 - quattro: Quattro € 2.70 - -dish sandwich_geitenkaas: Broodje Geitenkaas -- Geitenkaas, appel, honing en sla - single_choice sandwich: Broodje - small_white: Klein wit € 1.70 - small_brown: Klein bruin € 1.70 - large_white: Groot wit € 2.60 - large_brown: Groot bruin € 2.60 - quattro: Quattro € 2.60 - -dish sandwich_tomaatmozzarella: Broodje Tomaat-mozzarella -- Mozzarella, tomaat, basilicumpesto en sla - single_choice sandwich: Broodje - small_white: Klein wit € 1.70 - small_brown: Klein bruin € 1.70 - large_white: Groot wit € 2.60 - large_brown: Groot bruin € 2.60 - quattro: Quattro € 2.60 - -dish sandwich_hoevebroodje: Broodje Hoevebroodje -- Geitenkaas, appel, honing, gebakken spek en sla - single_choice sandwich: Broodje - small_white: Klein wit € 1.70 - small_brown: Klein bruin € 1.70 - large_white: Groot wit € 2.60 - large_brown: Groot bruin € 2.60 - quattro: Quattro € 2.60 - -dish yoghurt: Natuuryoghurt € 0.4 -dish yofu: Plantaardige yofu € 1 -dish yoghurt_muesli: Yoghurt met muesli € 1 -dish greek_fruit_yoghurt: Griekse vruchtenyoghurt € 1.4 -dish chocolate_mousse: Chocomousse € 1.4 -dish speculoos_mousse: Speculaasmousse € 1.4 -dish soy_dessert: Soja dessert € 0.7 -dish tiramisu: Tiramisu € 1.4 -dish muffin: Muffin € 1 -dish donut: Donut € 1 -dish ice_variation: IJsvariatie € 2.3 -dish fruit: Fruit € 0.5 -dish nuts_fruit: Nuts & fruit € 1.5 - -dish chocolate_milk: Koude chocolademelk € 0.8 -dish juice: Fruitsap 20 cl Fair Trade € 0.8 -dish water: Bruisend water 50 cl € 0.8 -dish perfumed_water: Gearomatiseerd water 50 cl € 1 -dish bionade: Bionade € 1.5 -dish finley: Finley € 1 -dish iced_coffee: IJskoffie € 2 -dish iced_tea: IJsthee € 2 -dish smoothie: Smoothie € 2 diff --git a/data/s5_generate.py b/data/s5_generate.py deleted file mode 100755 index 60e3725..0000000 --- a/data/s5_generate.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 - -print( - """============================ -s5: S5 - osm https://www.openstreetmap.org/node/3752879366 - address Krijgslaan 281, 9000 Gent - website https://www.ugent.be/student/nl/meer-dan-studeren/resto/restos/restocampussterre.htm -============================""" -) - -# Paste menu from https://www.ugent.be/student/nl/meer-dan-studeren/resto/broodjes/overzicht.htm -# here -MENU = [ - l.split("\t") - for l in """ -Spring break Erwten-munt spread, komkommer, radijs, sla, croutons, cocktailsaus € 1,50 € 2,40 -Groentespread Weekelijks wisselende groentespread € 1,60 € 2,60 -Brie Brie, honing, pijnboompitten, sla € 1,50 € 2,50 -Geitenkaas Geitenkaas, appel, honing en sla € 1,70 € 2,60 -Kaas Kaas, ei, komkommer, sla, tomaat en mayonaise € 1,40 € 2,10 -Kruidenkaas Kruidenkaas, ei, komkommer, sla en tomaat € 1,40 € 2,10 -Tomaat-mozzarella Mozzarella, tomaat, basilicumpesto en sla € 1,70 € 2,60 -Kip curry Kip curry, ei, komkommer, sla en tomaat € 1,50 € 2,20 -Kip curry Hawaï Kip curry, ananas, ei, komkommer, sla en tomaat € 1,50 € 2,20 -Caesar Kippenreepjes, Gran Moravia kaasschilfers, croutons, sla en caesardressing € 1,50 € 2,50 -Gerookte zalm met kruidenkaas Gerookte zalm, kruidenkaas en ui € 1,60 € 2,60 -Vissalade Duurzame vissalade, tomaat, sla, komkommer en ei € 1,50 € 2,30 -Ham Ham, ei, komkommer, sla, tomaat en mayonaise € 1,50 € 2,30 -Preparé Preparé, ei, komkommer, sla en tomaat € 1,50 € 2,30 -Martino Preparé, augurk, tomaat, mosterd en tabasco € 1,60 € 2,40 -Hoevebroodje Geitenkaas, appel, honing, gebakken spek en sla € 1,70 € 2,60 -Maison Ham, kaas, augurk, ei, sla, tomaat, cocktailsaus en mayonaise € 1,60 € 2,40 -Tropical Ham, kaas, ananas, ei, sla, cocktailsaus € 1,60 € 2,40 -Toscane Mozzarella, prosciutto ham, sla en tomatensalsa € 1,60 € 2,70 -Argenteuil Ham, asperge, ei, komkommer, sla, tomaat en mayonaise € 1,50 € 2,40 -""".strip().split( - "\n" - ) -] -# Sort by price. This fails if price is not always exactly "€ x,xx" but whatever -MENU.sort(key=lambda dish: dish[2] + dish[3]) - -SANDWICHES = [ - [("small_white", "Klein wit "), ("small_brown", "Klein bruin"),], # First price - [ # Second price - ("large_white", "Groot wit "), - ("large_brown", "Groot bruin"), - ("quattro", " Quattro "), - ], -] - - -def name_to_id(name): - return "".join( - filter(lambda c: ord("a") <= ord(c) <= ord("z"), name.lower().replace("é", "e")) - ) - - -for dish in MENU: - print() - name, description = dish[0], dish[1] - prices = [p.replace(",", ".") for p in dish[2:]] - - print( - "dish sandwich_{}: Broodje {} -- {}".format(name_to_id(name), name, description) - ) - print("\tsingle_choice sandwich: Broodje") - for sandwiches, price in zip(SANDWICHES, prices): - for sw_id, sw_name in sandwiches: - print("\t\t{}: {} {}".format(sw_id, sw_name, price)) - -print( - """ -dish yoghurt: Natuuryoghurt € 0.4 -dish yofu: Plantaardige yofu € 1 -dish yoghurt_muesli: Yoghurt met muesli € 1 -dish greek_fruit_yoghurt: Griekse vruchtenyoghurt € 1.4 -dish chocolate_mousse: Chocomousse € 1.4 -dish speculoos_mousse: Speculaasmousse € 1.4 -dish soy_dessert: Soja dessert € 0.7 -dish tiramisu: Tiramisu € 1.4 -dish muffin: Muffin € 1 -dish donut: Donut € 1 -dish ice_variation: IJsvariatie € 2.3 -dish fruit: Fruit € 0.5 -dish nuts_fruit: Nuts & fruit € 1.5 - -dish chocolate_milk: Koude chocolademelk € 0.8 -dish juice: Fruitsap 20 cl Fair Trade € 0.8 -dish water: Bruisend water 50 cl € 0.8 -dish perfumed_water: Gearomatiseerd water 50 cl € 1 -dish bionade: Bionade € 1.5 -dish finley: Finley € 1 -dish iced_coffee: IJskoffie € 2 -dish iced_tea: IJsthee € 2 -dish smoothie: Smoothie € 2""" -) diff --git a/data/simpizza.hlds b/data/simpizza.hlds deleted file mode 100644 index 42a744c..0000000 --- a/data/simpizza.hlds +++ /dev/null @@ -1,268 +0,0 @@ -============================ -simpizza: Simpizza - osm https://www.openstreetmap.org/node/5803560353 - address De Pintelaan 252, 9000 Gent - phone +32 9 321 02 00 - website https://www.simpizza.be/ - # Op bovenstaande website kan men ook online bestellen -============================ - -size: Grootte - small: Small -- 27 cm € 9.95 - medium: Medium -- 30 cm € 12.95 - large: Large -- 37 cm € 15.95 - -base: Bodem - italian: Italian classic :: {no_text} - cheesy: Cheesy crust € 2 - -sauce: Extra potje saus - garlic_sauce: Looksaus € 0.75 - bbq: Barbecuesaus € 0.35 - sweet_sour: Zoetzure saus € 0.35 - ketchup: Ketchup € 0.75 - mayo: Mayonaise € 0.75 - -sauce_no_garlic: Extra potje saus (looksaus al inbegrepen) - bbq: Barbecuesaus € 0.35 - sweet_sour: Zoetzure saus € 0.35 - ketchup: Ketchup € 0.75 - mayo: Mayonaise € 0.75 - -dish margherita: Pizza margherita (veggie) -- Tomatensaus, kaas, mozzarella - single_choice size - single_choice base - multi_choice sauce -dish bolognese_de_luxe: Pizza bolognese de luxe -- Bolognesesaus, look, ui, extra gehakt :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish hawaii: Pizza Hawaï -- Ham, kip, maïs, ananas :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish popeye: Pizza Popeye (veggie) -- Extra spinazie, ei, room, extra kaas - single_choice size - single_choice base - multi_choice sauce -dish pepperoni: Pizza pepperoni -- Dubbele portie pepperoni, paprika, jalapeños :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish seafood: Pizza seafood -- Tonijn, calamares, mosselen, garnalen :: {has_fish} - single_choice size - single_choice base - multi_choice sauce -dish mega_fish: Pizza mega fish -- Ansjovis, tonijn, champignons, ui :: {has_fish} - single_choice size - single_choice base - multi_choice sauce -dish hot_pizza: Pizza hot pizzaaah!!! -- Gehakt, jalapeños, ui, pepperoni :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish salmon_delight: Pizza salmon delight -- Roomsaus, ui, gerookte zalm, kappertjes :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish full_option: Pizza full option -- Salami, paprika, ui, olijven, kip, ananas, maïs, gehakt, extra kaas :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish pitza_kebab: Pitza kebab -- Look, ui, pitavlees, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish multi_cheese: Pizza multi cheese (veggie) -- Gorgonzola, feta, belpaese, extra kaas - single_choice size - single_choice base - multi_choice sauce -dish creamy_multi_cheese: Pizza creamy multi cheese (veggie) -- Roomsaus, gorgonzola, feta, mozzarella, extra kaas - single_choice size - single_choice base - multi_choice sauce -dish 4_seasons: Pizza 4 seasons -- Ham, salami, champignons, paprika :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish green_fiesta: Pizza green fiësta -- Roomsaus, spinazie, look, döner kebab, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish veggie: Pizza veggie -- Champignons, paprika, ui, maïs, tomaat, olijven - single_choice size - single_choice base - multi_choice sauce -dish meat_lovers: Pizza meat lovers -- Ham, salami, pepperoni, extra gehakt :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish meat_lovers_deluxe: Pizza meat lovers deluxe -- Ham, salami, pepperoni, bacon, meatballs, merguez, swirl van looksaus :: {has_meat} € 2 - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish scampi_mampi: Pizza scampi mampi -- Ui, look, scampi, verse tomaat :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish tabasco: Pizza tabasco -- Tabascopizzasaus, ui, paprika, champignons, pepperoni :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish funky_chicken: Pizza funky chicken -- Ui, ananas, paprika, kip :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish chicken_time: Pizza chicken time -- Kip, paprika, olijven, verse tomaten :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish creamy_chicken: Pizza creamy chicken -- Roomsaus, kip, ui, look, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish spicy_chicken: Pizza spicy chicken -- Rode ui, jalapeños, kip, paprika, mozzarella, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish meatballs: Pizza meatballs -- Gekruide gehaktballetjes, ui, paprika, verse tomaat :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish tuna: Pizza tuna -- Ui, tonijn, olijven, extra kaas :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish anchovy: Pizza anchovy -- Ui, ansjovis, paprika, olijven :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish calzone: Pizza calzone -- Dubbelgevouwen. Ham, salami, champignons, paprika, bolognesesaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish curry: Pizza curry -- Currysaus, champignons, ui, ananas, paprika, kip, mozzarella, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish bbq_chicken: Pizza chicken barbecue -- Barbecuesaus, gegrilde kip, ui, paprika :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish bbq_meatballs: Pizza barbecue meatballs -- Barbecuesaus, gekruide gehaktballetjes, ui, paprika, verse tomaat :: {has_meat} - single_choice size - single_choice base - multi_choice sauce -dish bbq_bacon: Pizza barbecue bacon -- Barbecuesaus, bacon, ui, kip, jalapeños, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish bbq_special: Pizza barbecue special -- Barbecuesaus, pepperoni, kip, meatballs, ui, swirl van looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic -dish bbq_merguez: Pizza merguez -- Barbecuesaus, merguez, ui, paprika, potje looksaus :: {has_meat} - single_choice size - single_choice base - multi_choice sauce_no_garlic - -dish 50_50: Pizza fifty/fifty (helften in commentaar) -- Twee pizzahelften naar keuze € 2 - single_choice size - single_choice base - multi_choice sauce - -dish diy: Pizza do it yourself -- Vier ingrediënten gratis, daarna €1 per ingrediënt op small, €1.25 op medium, €1.5 op large - single_choice size - single_choice base - multi_choice meat: Vlees - ham: Ham :: {has_meat} - salami: Salami :: {has_meat} - hot_salami: Pikante salami :: {has_meat} - minced_meat: Gehakt :: {has_meat} - chicken: Kip :: {has_meat} - kebab: Kebabvlees :: {has_meat} - merguez: Merguez :: {has_meat} - bacon: Bacon :: {has_meat} - - multi_choice fish: Vis - tuna: Tonijn :: {has_fish} - mussels: Mosselen :: {has_fish} - anchovy: Ansjovis :: {has_fish} - calamares: Calamares :: {has_fish} - shrimp: Garnalen :: {has_fish} - - multi_choice vegetables: Groenten - mushroom: Champignons - onion: Ui - garlic: Look - olives: Olijven - bell_pepper: Paprika - maize: Maïs - capers: Kappertjes - hot_peppers: Pikante pepers - pineapple: Ananas - tomato: Tomaat - - multi_choice sauces: Sauzen - bolognese: Bolognesesaus :: {has_meat} - cream: Roomsaus - tomato: Tomatensaus - tabasco: Tabascopizzasaus - bbq: Barbecuesaus - garlic: Looksaus - - multi_choice dairy: Zuivel - egg: Ei - gorgonzola: Gorgonzola - bel_paese: Bel paese - feta: Feta - extra_cheese: Extra kaas - -dish garlic_bread: Lookbroodjes natuur € 2.2 -dish garlic_bread_cheese: Lookbroodjes kaas € 2.5 -dish garlic_bread_cheese_ham: Lookbroodjes kaas en ham :: {has_meat} € 3 -dish garlic_bread_cheese_tomato: Lookbroodjes kaas en tomaat € 3 - -dish baguette_pesto: Lookbaguette pesto -- Pesto, tomatensaus, verse tomaat, mozzarella € 4.75 -dish baguette_bolognese: Lookbaguette bolognese -- Bolognesesaus, salami, mozzarella € 4.75 -dish baguette_chicken_kebab: Lookbaguette chicken kebab -- Tomatensaus, ui, kip, kebabvlees, mozzarella € 4.75 -dish baguette_tuna: Lookbaguette tuna -- Tomatensaus, ui, tonijn, olijven, mozzarella € 4.75 -dish baguette_hot: Lookbaguette hot -- Tabascotomatensaus, ui, pepperoni, jalapeños, mozzarella € 4.75 - -dish hot_and_cheesy: Hot & cheesy -- 5 stuks, inclusief potje dipsaus € 3.5 -dish usa_potatoes: USA potatoes -- 1 portie, inclusief potje dipsaus € 3.5 - -dish 8_chicken_wings: 8 chicken wings -- Met potje dipsaus :: {has_meat} € 6 -dish 16_chicken_wings: 16 chicken wings -- Met potje dipsaus :: {has_meat} € 10 -dish 8_chicken_nuggets: 8 chicken nuggets -- Met potje dipsaus :: {has_meat} € 7 -dish 16_chicken_nuggets: 16 chicken nuggets -- Met potje dipsaus :: {has_meat} € 12 - -dish salad_mix: Salade mix -- IJsbergsla, kerstomaatjes, maïs, olijven, potje bieslook € 4.75 -dish salad_mix_mozzarella: Salade mix mozzarella € 6.5 -dish salad_mix_feta: Salade mix feta € 6.5 -dish salad_mix_tuna: Salade mix tuna € 6.5 - -pasta: Pasta - spaghetti: Spaghetti - penne: Penne - -dish pasta_bolognaise: Pasta bolognaise :: {has_meat} € 8.5 - single_choice pasta -dish pasta_cheese: Pasta kaassaus (veggie) € 8.5 - single_choice pasta -dish pasta_ham_and_cheese: Pasta ham-en-kaussaus :: {has_meat} € 9.5 - single_choice pasta -dish pasta_milano: Pasta milano -- Kip, champignons, ui, room, look, curry :: {has_meat} € 9.95 - single_choice pasta -dish pasta_scampi: Pasta scampi -- Scampi, champignons, ui, room, look, curry :: {has_fish} € 9.95 - single_choice pasta -dish pasta_multi_cheese: Pasta multi cheese (veggie) € 9.95 - single_choice pasta -dish pasta_pesto_chicken: Pasta pesto chicken -- Pestoroomsaus en kip € 9.95 - single_choice pasta -dish pasta_veggie: Pasta veggie -- Tomatenroomsaus, champignons, ui, paprika, tomaat € 9.95 - single_choice pasta - -dish tiramisu: Tiramisu € 3 -dish tiramisu_speculoos: Tiramisu speculoos € 3 -dish tiramisu_oreo: Tiramisu oreo € 3 -- 2.43.4 From a841be3c48c22ef95946e2476e7ce91f6c05c9a7 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 25 Sep 2020 19:48:25 +0200 Subject: [PATCH 087/197] Complete menu migration to separate repo --- app/hlds/definitions.py | 2 +- data/hawaiian_poke_bowl.hlds | 95 ------------------------------------ 2 files changed, 1 insertion(+), 96 deletions(-) delete mode 100644 data/hawaiian_poke_bowl.hlds diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 385e16d..0da89aa 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -12,7 +12,7 @@ __all__ = ["location_definitions", "location_definition_version"] # pylint: disable=invalid-name # TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674 -DATA_DIR = path.join(path.dirname(__file__), "..", "..", "data") +DATA_DIR = path.join(path.dirname(__file__), "..", "..", "menus") location_definitions: List[Location] = parse_all_directory(DATA_DIR) location_definitions.sort(key=lambda l: l.name) diff --git a/data/hawaiian_poke_bowl.hlds b/data/hawaiian_poke_bowl.hlds deleted file mode 100644 index 91ef8f2..0000000 --- a/data/hawaiian_poke_bowl.hlds +++ /dev/null @@ -1,95 +0,0 @@ -============================================= -hawaiian_poke_bowl: Hawaiian Poké Bowl - website https://hawaiianpokebowl.be/ -============================================= - -dish own_bowl: Own bowl - single_choice size: Grootte - medium: Medium € 9.90 - large: Large € 12.90 - - single_choice base: Basis - sushi_rice: Sushirijst - brown_rice: Bruine rijst - quinoa: Quinoa € 1 - salad: Salad - mix: Mix - nachos: Nacho's - - multi_choice mixins: Mix-ins (max. 5) - guacamole: Guacamole - cucumber: Komkommer - seaweed: Zeewiersalade - avocado: Avocado - carrots: Worteltjes - mango: Mango - red_onion: Rode ui - corn: Maïs - edamame: Edamamebonen - beetroot: Rode biet - jalapenos: Jalapeños - feta: Fetakaas - cherry_tomatoes: Kerstomaatjes - pickled_cucumber: Augurkjes - hummus: Hummus - - single_choice protein: Eiwit - farm_chicken: Hoevekip :: {has_meat} - highland_steak: Hoogvlaktebiefstuk :: {has_meat} - japanese_tofu: Japanse tofu - nordic_salmon: Noordse zalm :: {has_fish} € 1 - ahi_tuna: Ahitonijn :: {has_fish} € 2 - marinated_nordic_salmon: Gemarineerde Noordse zalm :: {has_fish} € 1 - spicy_ahi_tuna: Pikante Ahitonijn :: {has_fish} € 2 - - single_choice dressing: Sausje - sriracha_mayo: Sriracha-mayonaise - wasabi_mayo: Wasabi-mayonaise - chili_mayo: Chili-mayonaise - teriyaki: Teriyaki - sweet_chili: Zoete chili - sriracha_hot: Pikante sriracha - sesam: Sesam :: {vegan} - avocado_garlic: Avocado-look :: {vegan} € 0.5 - tzatziki: Tzatziki € 0.5 - - multi_choice toppings: Toppings (max. 3) - crispy_onions: Krokante uitjes - spring_onions: Lente-ui - furikake: Furikake - sesam_soy: Sesamsoja - sesam_mix: Sesammengeling - sesam_wasabi: Sesamwasabi - masago: Masago - sesam_bbq: Gegrilde sesamzaadjes - crushed_wasabi: Geplette wasabi - walnuts: Walnoten - shrimp_chips: Kroepoek - pickled_ginger: Gari (gemarineerde gember) - chili_flakes: Chilivlokjes - nachos: Nacho's - -dish salmon_style: Salmon style -- Noordse zalm, avocado, zeewiersalade, edamamebonen, komkommer, maïs, wasabi-mayonaise, sesam-mix, masago en nacho's :: {has_fish} - single_choice size: Grootte - medium: Medium € 10.90 - large: Large € 13.90 - -dish sweet_chicken: Sweet chicken -- Hoevekip, guacamole, maïs, kerstomaten, mango, Fetakaas, teriyaki, krokante uitjes, kroepoek :: {has_meat} {has_fish} - single_choice size: Grootte - medium: Medium € 9.90 - large: Large € 12.90 - -dish mighty_steak: Mighty steak -- Hoogvlaktebiefstuk, guacamole, kerstomaatjes, maïs, komkommer, rode uitjes, sriracha-mayonaise, lente-uitjes, chilivlokjes :: {has_meat} - single_choice size: Grootte - medium: Medium € 9.90 - large: Large € 12.90 - -dish lets_tofu: Let's tofu -- Japanse tofu, avocado, zeewiersalade, komkommer, worteltjes, edamamebonen, sesamsaus, sesamsoja :: {vegan} - single_choice size: Grootte - medium: Medium € 9.90 - large: Large € 12.90 - -dish vegan_avocado: Vegan avocado -- Dubbele avocado, worteltjes, maïs, rode biet, komkommer, edamamebonen, avocado-looksaus, lente-uitjes en walnoten - single_choice size: Grootte - medium: Medium € 9.90 - large: Large € 12.90 -- 2.43.4 From 7856302028ec4ea62b38f494840380eb717a8114 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 25 Sep 2020 21:12:41 +0200 Subject: [PATCH 088/197] Improve order menu design --- app/templates/order.html | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/templates/order.html b/app/templates/order.html index c43ebe4..c5866b4 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -105,7 +105,13 @@ {% endif %}
- {{ dish.name }} {{ dish.tags | join(", ") }}{{ dish.description }}{{ dish.price_range() | price_range }} + + {{ dish.name }} + {% if dish.tags %} {{ dish.tags | join(", ") }}{% endif %} + {% if dish.description %}{{ dish.description }}{% endif %} + + {{ dish.price_range() | price_range }} + {% for (choice_type, choice) in dish.choices %}

@@ -377,6 +383,10 @@ dl { display: flex; align-items: flex-end; } +.spacecake .tags { + padding-left: 0.5em; + color: var(--gray2); +} .spacecake .spacer { content: ' '; flex-grow: 1; -- 2.43.4 From 0ab0824913d269516172ca681e1b9ce9d51e9119 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 26 Sep 2020 00:30:40 +0200 Subject: [PATCH 089/197] Remove disused labels --- app/forms.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/forms.py b/app/forms.py index 92be9c5..1317c21 100644 --- a/app/forms.py +++ b/app/forms.py @@ -59,10 +59,7 @@ class OrderItemForm(Form): submit_button = SubmitField("Submit") def populate(self, location: Location) -> None: - self.dish_id.choices = [ - (dish.id, (dish.name + ": " + price_range_string(dish.price_range()))) - for dish in location.dishes - ] + self.dish_id.choices = [(dish.id, dish.name) for dish in location.dishes] if not self.is_submitted() and self.comment.data is None: self.comment.data = request.args.get("comment") -- 2.43.4 From 9641435b64a50e54298a8dc173993b2c2d05455a Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 26 Sep 2020 00:39:50 +0200 Subject: [PATCH 090/197] Add norobot tag on order pages --- app/templates/order.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/templates/order.html b/app/templates/order.html index c5866b4..cbdde26 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -9,6 +9,11 @@ {% import "utils.html" as util %} +{% block metas %} + {{ super() }} + +{% endblock %} + {% block container %}

Order {{ order.id }}

-- 2.43.4 From 6a052fae73bce331ed2bd24463fae803a77ae870 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 26 Sep 2020 01:10:37 +0200 Subject: [PATCH 091/197] Take price of choice references into account --- app/hlds/parser.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/app/hlds/parser.py b/app/hlds/parser.py index 55c9fb5..fba4364 100644 --- a/app/hlds/parser.py +++ b/app/hlds/parser.py @@ -21,6 +21,12 @@ def filter_instance(cls, iterable): return [item for item in iterable if isinstance(item, cls)] +class ChoiceReference: + def __init__(self, identifier, price): + self.identifier = identifier + self.price = price + + # pylint: disable=no-self-use class HldsSemanticActions: def location(self, ast) -> Location: @@ -31,7 +37,16 @@ class HldsSemanticActions: for dish in dishes: for i, choice in enumerate(dish.choices): if not isinstance(choice[1], Choice): - dish.choices[i] = (dish.choices[i][0], deepcopy(choices[choice[1]])) + choiceId, choiceRef = choice + assert isinstance(choiceRef, ChoiceReference) + # We must replace the ChoiceReference with the Choice it refers to. A deep copy + # allows us to modify the individual Options of the Choice. + choiceObject = deepcopy(choices[choiceRef.identifier]) + + for option in choiceObject.options: + option.price += choiceRef.price + + dish.choices[i] = (choiceId, choiceObject) # Move the base price to the first single_choice if the dish has a fixed price first_single_choice = first( @@ -68,7 +83,7 @@ class HldsSemanticActions: def choice_block(self, ast) -> Choice: if ast["price"] or ast["tags"]: raise SemanticError( - "Choice blocks cannot have price or tags, put them on each of its options instead" + "Choice block definitions cannot have price or tags, put them on each of its options instead" ) return Choice( @@ -79,11 +94,14 @@ class HldsSemanticActions: ) def indent_choice_block(self, ast) -> Tuple[str, Union[Choice, AST]]: - return ( - (ast["type"], self.choice_block(ast)) - if ast["kind"] == "declaration" - else (ast["type"], ast["id"]) - ) + if ast["kind"] == "declaration": + return (ast["type"], self.choice_block(ast)) + else: + if ast["type"] == "single_choice" and ast["price"]: + raise SemanticError( + "Single_choice choices can't have a price, because it would always be triggered" + ) + return (ast["type"], ChoiceReference(ast["id"], ast["price"] or 0)) def indent_choice_entry(self, ast) -> Option: return Option( -- 2.43.4 From 837dc682bca408d7457676e830cb9816ac7cc7b6 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 12 Oct 2020 22:40:27 +0200 Subject: [PATCH 092/197] Tweak UI a bit after demo --- app/templates/order.html | 206 ++++++++++++++++++++------------------- 1 file changed, 104 insertions(+), 102 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index cbdde26..c0a9f80 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -29,6 +29,109 @@
+
+

My items

+ {% if my_items %} +
    + {% for item in my_items %} +
  • + {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} +
    + +
    + {%- endif %} + {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %} {{ item.price | euro }} +
  • + {% endfor %} +
+ {% else %} +
(None)
+ {% endif %} +
+ + + {% if form %} + + + +
+

Add item to order

+ + {% for dish in order.location.dishes %} +
+ {{ form.csrf_token }} + + + {% if form.dish_id.errors %} +
+ {{ util.render_form_field_errors(form.dish_id) }} +
+ {% endif %} + +
+ + {{ dish.name }} + + + {{ dish.price_range() | price_range }} + + {% if dish.description %}
{{ dish.description }}
{% endif %} + {% for (choice_type, choice) in dish.choices %} +
+
+ +
+ {% endfor %} + +
+ {{ form.comment.label }}
+ {{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} + {{ util.render_form_field_errors(form.comment) }} +
+ + {% if current_user.is_anonymous() %} +
+ {{ form.user_name.label(class='control-label') }} + {{ form.user_name(class='form-control', placeholder='Fill in your name...') }} + {{ util.render_form_field_errors(form.user_name) }} +
+ {% endif %} +
+ {{ form.submit_button(class='btn btn-primary') }} +
+
+
+ {% endfor %} +
+ + {% endif %} + + {% if form %} +
+ +
+ {% endif %} + +

Order information

@@ -83,107 +186,6 @@
- - {% if form %} - - - -
-

Add item to order

- - {% for dish in order.location.dishes %} -
- {{ form.csrf_token }} - - - {% if form.dish_id.errors %} -
- {{ util.render_form_field_errors(form.dish_id) }} -
- {% endif %} - -
- - {{ dish.name }} - {% if dish.tags %} {{ dish.tags | join(", ") }}{% endif %} - {% if dish.description %}{{ dish.description }}{% endif %} - - {{ dish.price_range() | price_range }} - - {% for (choice_type, choice) in dish.choices %} -
-
- -
- {% endfor %} - -
- {{ form.comment.label }}
- {{ form.comment(class='form-control', placeholder='Fill in comment, when applicable') }} - {{ util.render_form_field_errors(form.comment) }} -
- - {% if current_user.is_anonymous() %} -
- {{ form.user_name.label(class='control-label') }} - {{ form.user_name(class='form-control', placeholder='Fill in your name...') }} - {{ util.render_form_field_errors(form.user_name) }} -
- {% endif %} -
- {{ form.submit_button(class='btn btn-primary') }} -
-
-
- {% endfor %} -
- - {% endif %} - - {% if form %} -
- -
- {% endif %} - - -
-

My items

- {% if my_items %} -
    - {% for item in my_items %} -
  • - {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} -
    - -
    - {%- endif %} - {{ item.dish_name }}{% if item.comment %}; {{ item.comment }}{% endif %} {{ item.price | euro }} -
  • - {% endfor %} -
- {% else %} -
(None)
- {% endif %} -
-

Ordering at {{ order.location_name }}

@@ -289,7 +291,7 @@ {% endfor %}
  • - +
  • @@ -276,12 +277,20 @@ @@ -331,8 +328,6 @@ On selected: - - {% if order.is_closed() %}      -- 2.43.4 From 5a9d9c1d31cf149b6d3acc9d109c172103c644b6 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 22 Apr 2022 01:25:01 +0200 Subject: [PATCH 137/197] Update prices per person on key up After user feedback --- app/templates/order_prices.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/templates/order_prices.html b/app/templates/order_prices.html index bbb9ca5..d5eec77 100644 --- a/app/templates/order_prices.html +++ b/app/templates/order_prices.html @@ -119,12 +119,14 @@ $(".noscript").css("display", "none"); $(".script").css("display", "unset"); - $("#per_dish input").on("change", e => { + function updatePerPersonPrices(e) { console.log(e.target); for (let item_id of e.target.dataset.forItems.split(",")) { $("#item_" + item_id).val(e.target.value); } - }); + }; + $("#per_dish input").on("change", updatePerPersonPrices); + $("#per_dish input").on("keyup", updatePerPersonPrices); }); {% endblock %} -- 2.43.4 From 2271b0427cf8f75c46a117917d3073c645f728d7 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Mon, 2 May 2022 14:16:20 +0200 Subject: [PATCH 138/197] Hotfix for create_database script --- app/create_database.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/create_database.py b/app/create_database.py index df07727..58ed446 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -2,7 +2,9 @@ import add_admins -from app import app_manager, db +from app import create_app, db + +app_manager = create_app() entry_sets = { "admins": add_admins.add, -- 2.43.4 From 9c00fcc0cfaecc55e4bf3ad8d968591e0b0a3a51 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Mon, 2 May 2022 18:18:32 +0200 Subject: [PATCH 139/197] Fix for wsgi startup script --- app/passenger_wsgi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index 9d3ebd1..79a8a72 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -18,8 +18,9 @@ sys.path.append(os.getcwd()) # Phusion Passenger expects this file to be called `passenger_wsgi.py` # and the WSGI object to be called `application` -from app import app as application +from app import create_app # For running on the server with passenger etc if __name__ == "__main__": + application = create_app() application.run() -- 2.43.4 From fec9d660c3261dc8342f5e9b63c47bce5451e175 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Mon, 2 May 2022 18:21:27 +0200 Subject: [PATCH 140/197] Fix wsgi startup script for real --- app/passenger_wsgi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index 79a8a72..35d8c99 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -20,7 +20,8 @@ sys.path.append(os.getcwd()) # and the WSGI object to be called `application` from app import create_app +application = create_app() + # For running on the server with passenger etc if __name__ == "__main__": - application = create_app() application.run() -- 2.43.4 From dfbf1de5a105b68a72694686ef7f32bea5282854 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Mon, 2 May 2022 18:25:54 +0200 Subject: [PATCH 141/197] wsgi is particular about the app object --- app/app.py | 4 ++-- app/create_database.py | 2 +- app/passenger_wsgi.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/app.py b/app/app.py index 8a7cc64..3553d2a 100755 --- a/app/app.py +++ b/app/app.py @@ -165,10 +165,10 @@ def create_app(): add_routes(app) add_template_filters(app) - return app_manager + return app, app_manager # For usage when you directly call the script with python if __name__ == "__main__": - app_mgr = create_app() + app, app_mgr = create_app() app_mgr.run() diff --git a/app/create_database.py b/app/create_database.py index 58ed446..58250ea 100644 --- a/app/create_database.py +++ b/app/create_database.py @@ -4,7 +4,7 @@ import add_admins from app import create_app, db -app_manager = create_app() +app, app_manager = create_app() entry_sets = { "admins": add_admins.add, diff --git a/app/passenger_wsgi.py b/app/passenger_wsgi.py index 35d8c99..ea68999 100644 --- a/app/passenger_wsgi.py +++ b/app/passenger_wsgi.py @@ -20,7 +20,7 @@ sys.path.append(os.getcwd()) # and the WSGI object to be called `application` from app import create_app -application = create_app() +application, appmgr = create_app() # For running on the server with passenger etc if __name__ == "__main__": -- 2.43.4 From 85d889217609d512b80bbfe537b2989d1963d2d2 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 2 May 2022 21:56:38 +0200 Subject: [PATCH 142/197] Hide buttons for which user has no permission --- app/models/order.py | 14 ++++++++++++++ app/templates/order.html | 8 +++++--- app/views/order.py | 10 ++-------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index b738c45..31f5620 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -114,3 +114,17 @@ class Order(db.Model): if self.courier_id == user_id or (user and user.is_admin()): return True return False + + def can_modify_prices(self, user_id: int) -> bool: + if not self.is_closed(): + return False + if user_id is None: + return False + if self.courier_id == user_id: + return True + user = User.query.filter_by(id=user_id).first() + return user and user.is_admin() + + def can_modify_payment(self, user_id: int) -> bool: + user = User.query.filter_by(id=user_id).first() + return user and (user.is_admin() or user == self.order.courier) diff --git a/app/templates/order.html b/app/templates/order.html index 7285ce8..313e164 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -290,9 +290,9 @@ {{ order_items | map(attribute="price") | sum | euro }} - {% if paid %}{% endif %} + {% if paid %}{% endif %} - +
    TotalNameItems
    {% set paid = order_items | map(attribute="paid") | all %} - + {% set can_modify_payment = True %} + {% for order_item in order_items %} + {% if not order_item.can_modify_payment(order.id, current_user.id) %} + {% set can_modify_payment = False %} + {% endif %} + {% endfor %} + - {{ order_items | map(attribute="price") | sum | euro }} + + {{ order_items | map(attribute="price") | sum | euro }} + - {% if paid %}paid{% endif %} + {% if paid %}{% endif %} {{ user_name }} @@ -315,10 +324,12 @@ + {% endblock %} diff --git a/app/views/order.py b/app/views/order.py index 49ca679..ad2ccad 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -225,29 +225,47 @@ def order_item_create(order_id: int) -> typing.Any: return redirect(url_for("order_bp.order_from_id", order_id=order_id)) -@order_bp.route("///user_paid", methods=["POST"]) +@order_bp.route("//users_paid", methods=["POST"]) @login_required # pylint: disable=R1710 -def items_user_paid(order_id: int, user_name: str) -> typing.Optional[Response]: - "Indicate payment status for a user in an order" - user = User.query.filter(User.username == user_name).first() - items: typing.List[OrderItem] = [] - if user: - items = OrderItem.query.filter( - (OrderItem.user_id == user.id) & (OrderItem.order_id == order_id) - ).all() +def items_user_paid(order_id: int) -> typing.Optional[Response]: + user_names = request.form.getlist("user_names") + if request.form.get("action") == "mark_paid": + return set_items_paid(order_id, user_names, True) + elif request.form.get("action") == "mark_unpaid": + return set_items_paid(order_id, user_names, False) else: - items = OrderItem.query.filter( - (OrderItem.user_name == user_name) & (OrderItem.order_id == order_id) - ).all() - current_order = Order.query.filter(Order.id == order_id).first() - if current_order.courier_id == current_user.id or current_user.admin: + abort(404) + +def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool): + total_paid_items = 0 + total_failed_items = 0 + for user_name in user_names: + user = User.query.filter(User.username == user_name).first() + items: typing.List[OrderItem] = [] + if user: + items = OrderItem.query.filter( + (OrderItem.user_id == user.id) & (OrderItem.order_id == order_id) + ).all() + else: + items = OrderItem.query.filter( + (OrderItem.user_name == user_name) & (OrderItem.order_id == order_id) + ).all() + for item in items: - item.paid = True - db.session.commit() - flash("Paid %d items for %s" % (len(items), item.for_name), "success") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) - abort(404) + if item.can_modify_payment(order_id, current_user.id): + if item.paid != paid: + item.paid = paid + total_paid_items += 1 + else: + total_failed_items += 1 + + db.session.commit() + if total_failed_items == 0: + flash("Marked %d items as paid" % (total_paid_items,), "success") + else: + flash("Failed to mark %d items as paid (succeeded in marking %d items as paid)" % (total_failed_items, total_paid_items), "error") + return redirect(url_for("order_bp.order_from_id", order_id=order_id)) @order_bp.route("///delete", methods=["POST"]) -- 2.43.4 From 09e2d704cdfdc6c95411c17054d183750d0adef7 Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 22 Apr 2022 01:15:54 +0200 Subject: [PATCH 135/197] Add price editor --- ...013fe95bea_create_price_modified_column.py | 21 +++ app/models/orderitem.py | 1 + app/templates/order.html | 15 +- app/templates/order_prices.html | 130 ++++++++++++++++++ app/utils.py | 17 ++- app/views/order.py | 51 ++++++- 6 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 app/migrations/versions/55013fe95bea_create_price_modified_column.py create mode 100644 app/templates/order_prices.html diff --git a/app/migrations/versions/55013fe95bea_create_price_modified_column.py b/app/migrations/versions/55013fe95bea_create_price_modified_column.py new file mode 100644 index 0000000..d4010c1 --- /dev/null +++ b/app/migrations/versions/55013fe95bea_create_price_modified_column.py @@ -0,0 +1,21 @@ +"""Create price_modified column + +Revision ID: 55013fe95bea +Revises: 9159a6fed021 +Create Date: 2022-04-22 01:00:03.729596 + +""" + +# revision identifiers, used by Alembic. +revision = '55013fe95bea' +down_revision = '9159a6fed021' + +from alembic import op +import sqlalchemy as sa + +def upgrade(): + op.add_column('order_item', sa.Column('price_modified', sa.DateTime(), nullable=True)) + + +def downgrade(): + op.drop_column('order_item', 'price_modified') diff --git a/app/models/orderitem.py b/app/models/orderitem.py index 6e85e6c..623d751 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -18,6 +18,7 @@ class OrderItem(db.Model): dish_id = db.Column(db.String(64), nullable=True) dish_name = db.Column(db.String(120), nullable=True) price = db.Column(db.Integer, nullable=True) + price_modified = db.Column(db.DateTime, nullable=True) paid = db.Column(db.Boolean, default=False, nullable=True) comment = db.Column(db.Text(), nullable=True) hlds_data_version = db.Column(db.String(40), nullable=True) diff --git a/app/templates/order.html b/app/templates/order.html index 60e1cf5..02fdccd 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -307,7 +307,12 @@ {%- endif %} -
    {{ item.price|euro }}
    +
    + {{ item.price|euro }} + {% if item.price_modified %} + + {% endif %} +
    {{ item.dish_name }}{{ "; " + item.comment if item.comment }}
    {% endfor %} @@ -328,6 +333,14 @@ + + {% if order.is_closed() %} +      + + Edit prices + + {% endif %} + diff --git a/app/templates/order_prices.html b/app/templates/order_prices.html new file mode 100644 index 0000000..bbb9ca5 --- /dev/null +++ b/app/templates/order_prices.html @@ -0,0 +1,130 @@ +{% extends "layout.html" %} +{% set active_page = "orders" -%} + +{% import "utils.html" as util %} + +{% block metas %} + {{ super() }} + +{% endblock %} + +{% block container %} +
    +

    Edit prices

    +
    Only applied to order {{ order.id }}. To permanently change prices for {{ order.location_name }}, edit the HLDS location definition.
    +
    + +
    +
    +

    Per dish

    +
    This functionality requires JavaScript.
    +
    + + + + + + + {% for dish_name, dish_quantity, dish_comment_groups in order.group_by_dish() -%} + {% set has_comments = dish_comment_groups | length > 1 or (dish_comment_groups | map("first") | any) -%} + {% for comment, items in dish_comment_groups -%} + + + {% if loop.first %} + + {% endif %} + + + + + + + {% endfor %} + {%- endfor %} + +
    DishPrice
    + {{ dish_quantity }} × + {{ dish_name }} + + {{ items | length }} × + {% if comment %}{{ comment }} + {% else %}No comment + {% endif %} + + {% set price = items[0].price | euro("") %} + {% set item_ids = items | map(attribute="id") %} + € +
    +
    +
    + +
    +

    Per person

    + + + + + + {% for user_name, order_items in order.group_by_user() -%} + + + + + + {%- endfor %} + +
    NameItems
    {{ user_name }} +
      + {% for item in order_items %} +
    • + € + {{ item.dish_name }}{{ "; " + item.comment if item.comment }} +
    • + {% endfor %} +
    +
    +
    + +
    + Cancel + +
    +
    + +{% endblock %} + +{% block styles %} + {{ super() }} + +{% endblock %} + +{% block scripts %} + {{ super() }} + +{% endblock %} diff --git a/app/utils.py b/app/utils.py index 91c9793..80556f2 100644 --- a/app/utils.py +++ b/app/utils.py @@ -1,16 +1,25 @@ "Script which contains several utils for Haldis" -from typing import Iterable +import re +from typing import Iterable, Optional -def euro_string(value: int) -> str: +def euro_string(value: int, unit="€ ") -> str: """ Convert cents to string formatted euro """ euro, cents = divmod(value, 100) if cents: - return f"€ {euro}.{cents:02}" - return f"€ {euro}" + return f"{unit}{euro}.{cents:02}" + return f"{unit}{euro}" + + +def parse_euro_string(value: str) -> Optional[int]: + m = re.fullmatch("(?:€ ?)?([0-9]+)(?:[.,]([0-9]+))?", value) + if not m: + return None + cents_02 = "{:0<2.2}".format(m.group(2)) if m.group(2) else "00" + return int(m.group(1)) * 100 + int(cents_02) def price_range_string(price_range, include_upper=False): diff --git a/app/views/order.py b/app/views/order.py index ad2ccad..cd3847a 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -1,5 +1,6 @@ "Script to generate the order related views of Haldis" import random +import re import typing from datetime import datetime @@ -11,7 +12,7 @@ from forms import AnonOrderItemForm, OrderForm, OrderItemForm from hlds.definitions import location_definition_version, location_definitions from models import Order, OrderItem, User, db from notification import post_order_to_webhook -from utils import ignore_none +from utils import ignore_none, parse_euro_string from werkzeug.wrappers import Response order_bp = Blueprint("order_bp", "order") @@ -323,6 +324,54 @@ def close_order(order_id: int) -> typing.Optional[Response]: return None +@order_bp.route("//prices", methods=["GET", "POST"]) +@login_required +def prices(order_id: int) -> typing.Optional[Response]: + order = Order.query.filter(Order.id == order_id).first() + if order is None: + abort(404) + if ( + current_user.is_anonymous() or + not (current_user.is_admin() or current_user.id == order.courier_id) + ): + flash("Only the courier can edit prices.", "error") + return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + if not order.is_closed(): + flash("Cannot modify prices until the order is closed.", "error") + return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + + if request.method == "GET": + return render_template( + "order_prices.html", + order=order, + ) + else: + new_prices = {} + + for key, value in request.form.items(): + m = re.fullmatch("item_([0-9]+)", key) + if not m: + continue + item_id = int(m.group(1)) + + price = parse_euro_string(value) + if not price: + flash(f"Could not recognize '{value}' as a price") + continue + + new_prices[item_id] = price + + for item in order.items: + new_price = new_prices.get(item.id) + if new_price is not None and new_price != item.price: + item.price = new_price + item.price_modified = datetime.now() + db.session.commit() + + return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + + + def select_user(items) -> typing.Optional[User]: "Select a random user from those who are signed up for the order" user = None -- 2.43.4 From ced04acb2e2ec63fea5e0af5ccc66e682a10430a Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 22 Apr 2022 01:17:32 +0200 Subject: [PATCH 136/197] Remove TODO buttons --- app/templates/order.html | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 02fdccd..7285ce8 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -316,9 +316,6 @@
    {{ item.dish_name }}{{ "; " + item.comment if item.comment }}
    {% endfor %} -
  • - -
  • {{ user_name }}{{ user_name }}
      {% for item in order_items %} @@ -325,11 +325,13 @@
    {% set paid = order_items | map(attribute="paid") | all %} - {% set can_modify_payment = True %} - {% for order_item in order_items %} - {% if not order_item.can_modify_payment(order.id, current_user.id) %} - {% set can_modify_payment = False %} - {% endif %} - {% endfor %} + {{ "disabled" if not order.can_modify_payment(current_user.id) }}> {{ order_items | map(attribute="price") | sum | euro }} -- 2.43.4 From 03f1e56161a8de68d14df48afccfa8bf8ab0d9c6 Mon Sep 17 00:00:00 2001 From: Midgard Date: Mon, 2 May 2022 22:25:06 +0200 Subject: [PATCH 145/197] Fix bug with form inside form --- app/templates/order.html | 8 +++----- app/views/order.py | 7 +++++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index a9a6dcd..39d43c7 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -267,7 +267,7 @@

    Items per person

    -
    + @@ -293,11 +293,9 @@
  • {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} - - - + {% else %} - + {%- endif %}
    diff --git a/app/views/order.py b/app/views/order.py index 4d3415c..d05944a 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -226,10 +226,12 @@ def order_item_create(order_id: int) -> typing.Any: return redirect(url_for("order_bp.order_from_id", order_id=order_id)) -@order_bp.route("//users_paid", methods=["POST"]) +@order_bp.route("//modify_items", methods=["POST"]) @login_required # pylint: disable=R1710 -def items_user_paid(order_id: int) -> typing.Optional[Response]: +def modify_items(order_id: int) -> typing.Optional[Response]: + if "delete_item" in request.form: + return delete_item(order_id, int(request.form["delete_item"])) user_names = request.form.getlist("user_names") if request.form.get("action") == "mark_paid": return set_items_paid(order_id, user_names, True) @@ -237,6 +239,7 @@ def items_user_paid(order_id: int) -> typing.Optional[Response]: return set_items_paid(order_id, user_names, False) else: abort(404) + return None def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool): total_paid_items = 0 -- 2.43.4 From 7b16a3b6c518740452207bda2049a267d146d057 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 11 May 2022 02:35:38 +0200 Subject: [PATCH 146/197] Don't crash when item.price is None --- app/views/order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/order.py b/app/views/order.py index d05944a..2e91fb8 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -62,8 +62,8 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: form.populate(order.location) if order.is_closed(): form = None - total_price = sum(o.price for o in order.items) - debts = sum(o.price for o in order.items if not o.paid) + total_price = sum(o.price or 0 for o in order.items) + debts = sum(o.price or 0 for o in order.items if not o.paid) dish = order.location.dish_by_id(dish_id) if order.location else None @@ -86,7 +86,7 @@ def items_shop_view(order_id: int) -> str: if current_user.is_anonymous() and not order.public: flash("Please login to see this order.", "info") abort(401) - total_price = sum(o.price for o in order.items) + total_price = sum(o.price or 0 for o in order.items) return render_template("order_items.html", order=order, total_price=total_price) -- 2.43.4 From b5202a9de6d3525c4334195c7ae8da4c973394f0 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 11 May 2022 02:43:08 +0200 Subject: [PATCH 147/197] Don't crash when rendering None price --- app/app.py | 3 ++- app/templates/order.html | 2 +- app/utils.py | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/app.py b/app/app.py index 3553d2a..c2d9e05 100755 --- a/app/app.py +++ b/app/app.py @@ -19,7 +19,7 @@ from login import init_login from markupsafe import Markup from models import db from models.anonymous_user import AnonymouseUser -from utils import euro_string, price_range_string +from utils import euro_string, price_range_string, ignore_none from zeus import init_oauth @@ -151,6 +151,7 @@ def add_template_filters(app: Flask) -> None: app.template_filter("price_range")(price_range_string) app.template_filter("any")(any) app.template_filter("all")(all) + app.template_filter("ignore_none")(ignore_none) def create_app(): diff --git a/app/templates/order.html b/app/templates/order.html index 39d43c7..ffb267b 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -281,7 +281,7 @@ {{ "disabled" if not order.can_modify_payment(current_user.id) }}> - {{ order_items | map(attribute="price") | sum | euro }} + {{ order_items | map(attribute="price") | ignore_none | sum | euro }} {% if paid %}{% endif %} diff --git a/app/utils.py b/app/utils.py index 80556f2..9ef9037 100644 --- a/app/utils.py +++ b/app/utils.py @@ -4,10 +4,12 @@ import re from typing import Iterable, Optional -def euro_string(value: int, unit="€ ") -> str: +def euro_string(value: Optional[int], unit="€ ") -> str: """ Convert cents to string formatted euro """ + if value is None: + return "✗" euro, cents = divmod(value, 100) if cents: return f"{unit}{euro}.{cents:02}" -- 2.43.4 From 749012140bc61532011320b8c759fe0907f503f6 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Wed, 11 May 2022 18:33:34 +0200 Subject: [PATCH 148/197] Make deadline minutes integer instead of rounded float --- app/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/notification.py b/app/notification.py index fa97045..02a994e 100644 --- a/app/notification.py +++ b/app/notification.py @@ -64,5 +64,5 @@ def remaining_minutes(value) -> str: delta = value - datetime.now() if delta.total_seconds() < 0: return "0" - minutes = delta.total_seconds() // 60 + minutes = int(delta.total_seconds() // 60) return f"{minutes:02}" -- 2.43.4 From 0e0771bae1caa1b2d352c6ec2b4e38ad8de04b32 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Fri, 20 May 2022 18:17:34 +0200 Subject: [PATCH 149/197] use a more common unicode arrow that can be found in more fonts --- app/static/css/main.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/static/css/main.css b/app/static/css/main.css index e8418ce..e1eceb4 100644 --- a/app/static/css/main.css +++ b/app/static/css/main.css @@ -243,9 +243,9 @@ details summary { } details summary:before { font-style: normal; - content: "⯈"; + content: "▸"; padding-right: 0.4em; } details[open] summary:before { - content: "⯆"; + content: "▾"; } -- 2.43.4 From 7702fdecbeca57dc622d6a83ee8827380a79ddf4 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Wed, 20 Apr 2022 02:05:10 +0200 Subject: [PATCH 150/197] change url usage to unique 7char slugs --- app/models/order.py | 22 +++++-- app/models/orderitem.py | 4 +- app/notification.py | 14 ++-- app/templates/order.html | 16 +++-- app/templates/order_edit.html | 2 +- app/templates/utils.html | 2 +- app/views/order.py | 121 +++++++++++++++++----------------- 7 files changed, 96 insertions(+), 85 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 255704a..6e5391c 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -1,7 +1,9 @@ -"Script for everything Order related in the database" +"""Script for everything Order related in the database""" import typing from collections import defaultdict from datetime import datetime +import secrets +import string from hlds.definitions import location_definitions from utils import first @@ -10,8 +12,13 @@ from .database import db from .user import User +def generate_slug(): + alphabet = string.ascii_letters + string.digits + return ''.join(secrets.choice(alphabet) for i in range(7)) + + class Order(db.Model): - "Class used for configuring the Order model in the database" + """Class used for configuring the Order model in the database""" id = db.Column(db.Integer, primary_key=True) courier_id = db.Column(db.Integer, nullable=True) location_id = db.Column(db.String(64)) @@ -19,6 +26,7 @@ class Order(db.Model): starttime = db.Column(db.DateTime) stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) + slug = db.Column(db.String(7), default=generate_slug, unique=True) items = db.relationship("OrderItem", backref="order", lazy="dynamic") @@ -47,7 +55,7 @@ class Order(db.Model): self.location_name = self.location.name def for_user(self, anon=None, user=None) -> typing.List: - "Get the items for a certain user" + """Get the items for a certain user""" return list( filter( (lambda i: i.user == user) @@ -58,7 +66,7 @@ class Order(db.Model): ) def group_by_user(self) -> typing.List[typing.Tuple[str, typing.List]]: - "Group items of an Order by user" + """Group items of an Order by user""" group: typing.Dict[str, typing.List] = {} # pylint: disable=E1133 @@ -78,7 +86,7 @@ class Order(db.Model): ) -> typing.List[ typing.Tuple[str, int, typing.List[typing.Tuple[str, typing.List]]] ]: - "Group items of an Order by dish" + """Group items of an Order by dish""" group: typing.Dict[str, typing.Dict[str, typing.List]] = defaultdict( lambda: defaultdict(list) ) @@ -101,11 +109,11 @@ class Order(db.Model): ) def is_closed(self) -> bool: - "Return whether or not the order is closed" + """Return whether the order is closed""" return self.stoptime and datetime.now() > self.stoptime def can_close(self, user_id: int) -> bool: - "Check if a user can close the Order" + """Check if a user can close the Order""" if self.stoptime and self.stoptime < datetime.now(): return False user = None diff --git a/app/models/orderitem.py b/app/models/orderitem.py index 623d751..fa74bba 100644 --- a/app/models/orderitem.py +++ b/app/models/orderitem.py @@ -10,7 +10,7 @@ from .user import User class OrderItem(db.Model): - "Class used for configuring the OrderItem model in the database" + """Class used for configuring the OrderItem model in the database""" id = db.Column(db.Integer, primary_key=True) order_id = db.Column(db.Integer, db.ForeignKey("order.id"), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey("user.id")) @@ -61,7 +61,7 @@ class OrderItem(db.Model): # pylint: disable=W0613 def can_delete(self, order_id: int, user_id: int, name: str) -> bool: - "Check if a user can delete an item" + """Check if a user can delete an item""" if int(self.order_id) != int(order_id): return False if self.order.is_closed(): diff --git a/app/notification.py b/app/notification.py index fa97045..14ee065 100644 --- a/app/notification.py +++ b/app/notification.py @@ -11,14 +11,14 @@ from models.order import Order def webhook_text(order: Order) -> typing.Optional[str]: - "Function that makes the text for the notification" + """Function that makes the text for the notification""" if order.location_id == "test": return None if order.courier is not None: # pylint: disable=C0301, C0209 return " {3} is going to {1}, order <{0}|here>! Deadline in {2} minutes!".format( - url_for("order_bp.order_from_id", order_id=order.id, _external=True), + url_for("order_bp.order_from_slug", order_slug=order.slug, _external=True), order.location_name, remaining_minutes(order.stoptime), order.courier.username.title(), @@ -28,12 +28,12 @@ def webhook_text(order: Order) -> typing.Optional[str]: return " New order for {}. Deadline in {} minutes. <{}|Open here.>".format( order.location_name, remaining_minutes(order.stoptime), - url_for("order_bp.order_from_id", order_id=order.id, _external=True), + url_for("order_bp.order_from_slug", order_slug=order.slug, _external=True), ) def post_order_to_webhook(order: Order) -> None: - "Function that sends the notification for the order" + """Function that sends the notification for the order""" message = webhook_text(order) if message: webhookthread = WebhookSenderThread(message, app.config["SLACK_WEBHOOK"]) @@ -41,7 +41,7 @@ def post_order_to_webhook(order: Order) -> None: class WebhookSenderThread(Thread): - "Extension of the Thread class, which sends a webhook for the notification" + """Extension of the Thread class, which sends a webhook for the notification""" def __init__(self, message: str, url: str) -> None: super().__init__() @@ -52,7 +52,7 @@ class WebhookSenderThread(Thread): self.slack_webhook() def slack_webhook(self) -> None: - "The webhook for the specified chat platform" + """The webhook for the specified chat platform""" if self.url: requests.post(self.url, json={"text": self.message}) else: @@ -60,7 +60,7 @@ class WebhookSenderThread(Thread): def remaining_minutes(value) -> str: - "Return the remaining minutes until the deadline of and order" + """Return the remaining minutes until the deadline of and order""" delta = value - datetime.now() if delta.total_seconds() < 0: return "0" diff --git a/app/templates/order.html b/app/templates/order.html index ffb267b..cd218ff 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -36,7 +36,7 @@ {% for item in my_items %}
  • {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} -
    + {%- endif %} @@ -65,7 +65,7 @@

    Add item to order

    {% for dish in order.location.dishes %} -
    + {{ form.csrf_token }} @@ -167,7 +167,7 @@
    {% if order.courier == None %} {% if not current_user.is_anonymous() %} - + {% else %}No-one yet{% endif %} @@ -180,12 +180,12 @@
    {% if order.can_close(current_user.id) -%} -
    + {% endif %} {% if courier_or_admin %} - Edit + Edit {%- endif %}
    @@ -258,7 +258,7 @@ @@ -293,7 +293,9 @@
  • {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} - +
    + + {% else %} {%- endif %} diff --git a/app/templates/order_edit.html b/app/templates/order_edit.html index 2667a9c..db6d709 100644 --- a/app/templates/order_edit.html +++ b/app/templates/order_edit.html @@ -11,7 +11,7 @@

    Edit order

    -
    + {{ form.csrf_token }}
    {{ form.courier_id.label(class='control-label') }}
    diff --git a/app/templates/utils.html b/app/templates/utils.html index 15d85eb..0af7b82 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -9,7 +9,7 @@ {% else %}open{% endif %}
    {%- endmacro %} diff --git a/app/views/order.py b/app/views/order.py index 2e91fb8..8023ecf 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -1,4 +1,4 @@ -"Script to generate the order related views of Haldis" +"""Script to generate the order related views of Haldis""" import random import re import typing @@ -20,7 +20,7 @@ order_bp = Blueprint("order_bp", "order") @order_bp.route("/") def orders(form: OrderForm = None) -> str: - "Generate general order view" + """Generate general order view""" if form is None and not current_user.is_anonymous(): form = OrderForm() location_id = request.args.get("location_id") @@ -33,7 +33,7 @@ def orders(form: OrderForm = None) -> str: @order_bp.route("/create", methods=["POST"]) @login_required def order_create() -> typing.Union[str, Response]: - "Generate order create view" + """Generate order create view""" orderForm = OrderForm() orderForm.populate() if orderForm.validate_on_submit(): @@ -43,14 +43,14 @@ def order_create() -> typing.Union[str, Response]: db.session.add(order) db.session.commit() post_order_to_webhook(order) - return redirect(url_for("order_bp.order_from_id", order_id=order.id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order.slug)) return orders(form=orderForm) -@order_bp.route("/") -def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: - "Generate order view from id" - order = Order.query.filter(Order.id == order_id).first() +@order_bp.route("/") +def order_from_slug(order_slug: str, form: OrderForm = None, dish_id=None) -> str: + """Generate order view from id""" + order = Order.query.filter(Order.slug == order_slug).first() if order is None: abort(404) if current_user.is_anonymous() and not order.public: @@ -77,10 +77,10 @@ def order_from_id(order_id: int, form: OrderForm = None, dish_id=None) -> str: ) -@order_bp.route("//items") -def items_shop_view(order_id: int) -> str: - "Generate order items view from id" - order = Order.query.filter(Order.id == order_id).first() +@order_bp.route("//items") +def items_shop_view(order_slug: int) -> str: + """Generate order items view from id""" + order = Order.query.filter(Order.slug == order_slug).first() if order is None: abort(404) if current_user.is_anonymous() and not order.public: @@ -90,31 +90,31 @@ def items_shop_view(order_id: int) -> str: return render_template("order_items.html", order=order, total_price=total_price) -@order_bp.route("//edit", methods=["GET", "POST"]) +@order_bp.route("//edit", methods=["GET", "POST"]) @login_required -def order_edit(order_id: int) -> typing.Union[str, Response]: - "Generate order edit view from id" - order = Order.query.filter(Order.id == order_id).first() +def order_edit(order_slug: str) -> typing.Union[str, Response]: + """Generate order edit view from id""" + order = Order.query.filter(Order.slug == order_slug).first() if current_user.id is not order.courier_id and not current_user.is_admin(): abort(401) if order is None: abort(404) - orderForm = OrderForm(obj=order) - orderForm.populate() - if orderForm.validate_on_submit(): - orderForm.populate_obj(order) + order_form = OrderForm(obj=order) + order_form.populate() + if order_form.validate_on_submit(): + order_form.populate_obj(order) order.update_from_hlds() db.session.commit() - return redirect(url_for("order_bp.order_from_id", order_id=order.id)) - return render_template("order_edit.html", form=orderForm, order_id=order_id) + return redirect(url_for("order_bp.order_from_slug", order_slug=order.slug)) + return render_template("order_edit.html", form=order_form, order_slug=order.slug) -@order_bp.route("//create", methods=["GET", "POST"]) -def order_item_create(order_id: int) -> typing.Any: +@order_bp.route("//create", methods=["GET", "POST"]) +def order_item_create(order_slug: str) -> typing.Any: # type is 'typing.Union[str, Response]', but this errors due to # https://github.com/python/mypy/issues/7187 - "Add item to order from id" - current_order = Order.query.filter(Order.id == order_id).first() + """Add item to order from slug""" + current_order = Order.query.filter(Order.slug == order_slug).first() if current_order is None: abort(404) if current_order.is_closed(): @@ -123,7 +123,7 @@ def order_item_create(order_id: int) -> typing.Any: flash("Please login to see this order.", "info") abort(401) location = current_order.location - # If location doesn't exist any more, adding items is nonsensical + # If location doesn't exist anymore, adding items is nonsensical if not location: abort(404) form = AnonOrderItemForm() if current_user.is_anonymous() else OrderItemForm() @@ -171,7 +171,7 @@ def order_item_create(order_id: int) -> typing.Any: return redirect( url_for( "order_bp.order_item_create", - order_id=order_id, + order_slug=current_order.slug, dish=form.dish_id.data, user_name=user_name, comment=comment, @@ -180,14 +180,13 @@ def order_item_create(order_id: int) -> typing.Any: # If the form was not submitted (GET request) or the form had errors: show form again if not form.validate_on_submit(): - return order_from_id(order_id, form=form, dish_id=dish_id) + return order_from_slug(current_order.slug, form=form, dish_id=dish_id) # Form was submitted and is valid - item = OrderItem() form.populate_obj(item) item.hlds_data_version = location_definition_version - item.order_id = order_id + item.order_id = current_order.id if not current_user.is_anonymous(): item.user_id = current_user.id else: @@ -222,16 +221,16 @@ def order_item_create(order_id: int) -> typing.Any: db.session.add(item) db.session.commit() - flash("Ordered %s" % (item.dish_name), "success") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + flash("Ordered %s" % item.dish_name, "success") + return redirect(url_for("order_bp.order_from_slug", order_slug=order_slug)) -@order_bp.route("//modify_items", methods=["POST"]) +@order_bp.route("//modify_items", methods=["POST"]) @login_required # pylint: disable=R1710 -def modify_items(order_id: int) -> typing.Optional[Response]: +def modify_items(order_slug: str) -> typing.Optional[Response]: if "delete_item" in request.form: - return delete_item(order_id, int(request.form["delete_item"])) + return delete_item(order_slug, int(request.form["delete_item"])) user_names = request.form.getlist("user_names") if request.form.get("action") == "mark_paid": return set_items_paid(order_id, user_names, True) @@ -241,7 +240,8 @@ def modify_items(order_id: int) -> typing.Optional[Response]: abort(404) return None -def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool): +def set_items_paid(order_slug: str, user_names: typing.Iterable[str], paid: bool): + order = Order.query.filter(Order.slug == order_slug).first() total_paid_items = 0 total_failed_items = 0 for user_name in user_names: @@ -249,15 +249,15 @@ def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool): items: typing.List[OrderItem] = [] if user: items = OrderItem.query.filter( - (OrderItem.user_id == user.id) & (OrderItem.order_id == order_id) + (OrderItem.user_id == user.id) & (OrderItem.order_id == order.id) ).all() else: items = OrderItem.query.filter( - (OrderItem.user_name == user_name) & (OrderItem.order_id == order_id) + (OrderItem.user_name == user_name) & (OrderItem.order_id == order.id) ).all() for item in items: - if item.can_modify_payment(order_id, current_user.id): + if item.can_modify_payment(order.id, current_user.id): if item.paid != paid: item.paid = paid total_paid_items += 1 @@ -269,33 +269,34 @@ def set_items_paid(order_id: int, user_names: typing.Iterable[str], paid: bool): flash("Marked %d items as paid" % (total_paid_items,), "success") else: flash("Failed to mark %d items as paid (succeeded in marking %d items as paid)" % (total_failed_items, total_paid_items), "error") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order_slug)) -@order_bp.route("///delete", methods=["POST"]) +@order_bp.route("///delete", methods=["POST"]) # pylint: disable=R1710 -def delete_item(order_id: int, item_id: int) -> typing.Any: +def delete_item(order_slug: str, item_id: int) -> typing.Any: # type is 'typing.Optional[Response]', but this errors due to # https://github.com/python/mypy/issues/7187 - "Delete an item from an order" - item = OrderItem.query.filter(OrderItem.id == item_id).first() + """Delete an item from an order""" + item: OrderItem = OrderItem.query.filter(OrderItem.id == item_id).first() + order: Order = Order.query.filter(Order.slug == order_slug).first() user_id = None if not current_user.is_anonymous(): user_id = current_user.id - if item.can_delete(order_id, user_id, session.get("anon_name", "")): + if item.can_delete(order.id, user_id, session.get("anon_name", "")): dish_name = item.dish_name db.session.delete(item) db.session.commit() - flash("Deleted %s" % (dish_name), "success") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + flash("Deleted %s" % dish_name, "success") + return redirect(url_for("order_bp.order_from_slug", order_slug=order_slug)) abort(404) -@order_bp.route("//volunteer", methods=["POST"]) +@order_bp.route("//volunteer", methods=["POST"]) @login_required -def volunteer(order_id: int) -> Response: - "Add a volunteer to an order" - order = Order.query.filter(Order.id == order_id).first() +def volunteer(order_slug: str) -> Response: + """Add a volunteer to an order""" + order = Order.query.filter(Order.slug == order_slug).first() if order is None: abort(404) if order.courier_id is None or order.courier_id == 0: @@ -304,14 +305,14 @@ def volunteer(order_id: int) -> Response: flash("Thank you for volunteering!") else: flash("Volunteering not possible!") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order.slug)) -@order_bp.route("//close", methods=["POST"]) +@order_bp.route("//close", methods=["POST"]) @login_required -def close_order(order_id: int) -> typing.Optional[Response]: - "Close an order" - order = Order.query.filter(Order.id == order_id).first() +def close_order(order_slug: str) -> typing.Optional[Response]: + """Close an order""" + order = Order.query.filter(Order.slug == order_slug).first() if order is None: abort(404) if ( @@ -323,7 +324,7 @@ def close_order(order_id: int) -> typing.Optional[Response]: if courier is not None: order.courier_id = courier.id db.session.commit() - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order_slug)) return None @@ -370,7 +371,7 @@ def prices(order_id: int) -> typing.Optional[Response]: def select_user(items) -> typing.Optional[User]: - "Select a random user from those who are signed up for the order" + """Select a random user from those who are signed up for the order""" user = None # remove non users items = [i for i in items if i.user_id] @@ -389,7 +390,7 @@ def select_user(items) -> typing.Optional[User]: def get_orders(expression=None) -> typing.List[Order]: - "Give the list of all currently open and public Orders" + """Give the list of all currently open and public Orders""" order_list: typing.List[OrderForm] = [] if expression is None: expression = (datetime.now() > Order.starttime) & ( -- 2.43.4 From 98214f8b84f5262c67e7c06c6e7fcc7c32755f7d Mon Sep 17 00:00:00 2001 From: mcbloch Date: Wed, 20 Apr 2022 02:35:44 +0200 Subject: [PATCH 151/197] Add share slug and qr code to order page --- app/static/js/jquery.min.js | 2 ++ app/static/js/qrcode.min.js | 1 + app/templates/order.html | 37 +++++++++++++++++++++++++++++-------- 3 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 app/static/js/jquery.min.js create mode 100644 app/static/js/qrcode.min.js diff --git a/app/static/js/jquery.min.js b/app/static/js/jquery.min.js new file mode 100644 index 0000000..2740cc4 --- /dev/null +++ b/app/static/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
  • TotalNameItems
    a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
    t
    ",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
    ",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
    ",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

    ",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/
    ","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
    ","
    "]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
    ").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.ajQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/app/static/js/qrcode.min.js b/app/static/js/qrcode.min.js new file mode 100644 index 0000000..993e88f --- /dev/null +++ b/app/static/js/qrcode.min.js @@ -0,0 +1 @@ +var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=['
    '],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
    "),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/app/templates/order.html b/app/templates/order.html index cd218ff..a1015fd 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -12,18 +12,39 @@ {% block metas %} {{ super() }} + + + {% endblock %} {% block container %} -
    -

    Order {{ order.id }}

    +
    +
    +
    + +
    +
    +

    Order {{ order.id }}

    -
    - {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %} +
    + {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
    +
    + Unique order link: {{ url_for("order_bp.order_from_slug", order_slug=order.slug, _external=True) }} +
    -- 2.43.4 From a33c76f84bfcd1c82ef824c7d60b5b8ae69402ff Mon Sep 17 00:00:00 2001 From: mcbloch Date: Fri, 20 May 2022 19:14:10 +0200 Subject: [PATCH 152/197] fix modify link --- app/templates/order.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/order.html b/app/templates/order.html index a1015fd..45a222f 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -288,7 +288,7 @@

    Items per person

    - + -- 2.43.4 From ab47c0a882a941f48390201218761f3631ff0c13 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 19:32:59 +0200 Subject: [PATCH 153/197] Change HALDIS_ADMIN_USERS configuration key to the one actually used --- README.md | 2 +- app/config.example.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d5876d6..2ed7864 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Afterwards upgrade the database to the latest version using cd app python3 app.py db upgrade -You can now still seed the database by running, note that you might want to put your name in the `HALDIS_ADMIN_USERS` in `app/config.py` +You can now still seed the database by running, note that you might want to put your name in the `HALDIS_ADMINS` in `app/config.py` ./populate-db.sh diff --git a/app/config.example.py b/app/config.example.py index daac1ab..2d02245 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -8,7 +8,7 @@ class Configuration: SQLALCHEMY_DATABASE_URI = "sqlite:///haldis.db" SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = True - HALDIS_ADMIN_USERS = [] + HALDIS_ADMINS = [] SECRET_KEY = "" SLACK_WEBHOOK = None LOGFILE = "haldis.log" -- 2.43.4 From 8a2b9247e111f95a80f290ed40fdc2d7f3556cd0 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Fri, 20 May 2022 19:04:32 +0200 Subject: [PATCH 154/197] initial work, model works, layout doenst --- app/add_admins.py | 2 +- app/models/user.py | 16 ++++++++++++++-- app/templates/layout.html | 6 ++++++ app/zeus.py | 2 +- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/app/add_admins.py b/app/add_admins.py index b3f8112..e9e2fba 100644 --- a/app/add_admins.py +++ b/app/add_admins.py @@ -10,5 +10,5 @@ def add() -> None: """Add users as admin.""" for username in Configuration.HALDIS_ADMINS: user = User() - user.configure(username, True, 0) + user.configure(username, True, 0, associations=["zeus"]) db.session.add(user) diff --git a/app/models/user.py b/app/models/user.py index 8e78b2f..13634bb 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,4 +1,6 @@ "Script for everything User related in the database" +from typing import List + from models import db @@ -8,6 +10,10 @@ class User(db.Model): username = db.Column(db.String(80), unique=True, nullable=False) admin = db.Column(db.Boolean) bias = db.Column(db.Integer) + # Assocation logic + associations = db.Column(db.String(120)) + + # Relations runs = db.relation( "Order", backref="courier", @@ -16,11 +22,17 @@ class User(db.Model): ) orderItems = db.relationship("OrderItem", backref="user", lazy="dynamic") - def configure(self, username: str, admin: bool, bias: int) -> None: - "Configure the User" + def association_list(self) -> List[str]: + return self.associations.split(",") + + def configure(self, username: str, admin: bool, bias: int, associations: List[str] = None) -> None: + """Configure the User""" + if associations is None: + associations = [] self.username = username self.admin = admin self.bias = bias + self.associations = ",".join(associations) # pylint: disable=C0111, R0201 def is_authenticated(self) -> bool: diff --git a/app/templates/layout.html b/app/templates/layout.html index 72b85b7..3ba9722 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -14,6 +14,12 @@ {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} +{% if not current_user.is_anonymous() -%} + {% for association in current_user.association_list() %} + {% set navbar = navbar + [('general_bp.home', association)] -%} + {% endfor -%} +{% endif -%} + {% set active_page = active_page|default('index') -%} {% block title %} diff --git a/app/zeus.py b/app/zeus.py index ebc16ab..09a4b04 100644 --- a/app/zeus.py +++ b/app/zeus.py @@ -77,7 +77,7 @@ def login_and_redirect_user(user) -> Response: def create_user(username) -> User: "Create a temporary user if it is needed" user = User() - user.configure(username, False, 1) + user.configure(username, False, 1, associations=["zeus"]) db.session.add(user) db.session.commit() return user -- 2.43.4 From c43efa4b10cc2bb5c040d20451292e4ac3c9980a Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 21:34:18 +0200 Subject: [PATCH 155/197] Migration --- .../5c8378aa4dff_add_user_associations.py | 28 +++++++++++++++++++ app/models/order.py | 1 + 2 files changed, 29 insertions(+) create mode 100644 app/migrations/versions/5c8378aa4dff_add_user_associations.py diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/5c8378aa4dff_add_user_associations.py new file mode 100644 index 0000000..4cc135d --- /dev/null +++ b/app/migrations/versions/5c8378aa4dff_add_user_associations.py @@ -0,0 +1,28 @@ +"""Add user associations + +Revision ID: 5c8378aa4dff +Revises: 55013fe95bea +Create Date: 2022-05-20 21:32:47.786340 + +""" + +# revision identifiers, used by Alembic. +revision = '5c8378aa4dff' +down_revision = '55013fe95bea' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('order', sa.Column('association', sa.String(length=120), nullable=True)) + op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'associations') + op.drop_column('order', 'association') + # ### end Alembic commands ### diff --git a/app/models/order.py b/app/models/order.py index 6e5391c..7729d42 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,6 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) + association = db.Column(db.String(120)) items = db.relationship("OrderItem", backref="order", lazy="dynamic") -- 2.43.4 From bbb38aa825ff143f3216d5df5b3053e9dd358483 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 21:59:51 +0200 Subject: [PATCH 156/197] Make sure to stamp database at latest revision after setup --- populate-db.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/populate-db.sh b/populate-db.sh index a9e9fad..417dc37 100755 --- a/populate-db.sh +++ b/populate-db.sh @@ -4,3 +4,6 @@ set -euo pipefail cd "$(dirname "$0")/app" env python create_database.py setup_database +latest_revision=$(env python app.py db heads | sed "s/ (head)$//") +echo Stamping db at $latest_revision +env python app.py db stamp $latest_revision -- 2.43.4 From 1c0d78f2eec787a5c70fa14f21644c31fb932fb3 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 22:46:56 +0200 Subject: [PATCH 157/197] Make sure only users with at least one association can create an order --- app/forms.py | 2 ++ .../versions/5c8378aa4dff_add_user_associations.py | 4 ++-- app/models/anonymous_user.py | 4 ++++ app/models/order.py | 2 +- app/models/user.py | 2 +- app/templates/orders.html | 5 +++++ app/views/order.py | 5 ++++- 7 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/forms.py b/app/forms.py index e259563..f847e96 100644 --- a/app/forms.py +++ b/app/forms.py @@ -24,6 +24,7 @@ class OrderForm(Form): "Starttime", default=datetime.now, format="%d-%m-%Y %H:%M" ) stoptime = DateTimeField("Stoptime", format="%d-%m-%Y %H:%M") + association = SelectField("Association", coerce=str, validators=[validators.required()]) submit_button = SubmitField("Submit") def populate(self) -> None: @@ -38,6 +39,7 @@ class OrderForm(Form): (current_user.id, current_user.username), ] self.location_id.choices = [(l.id, l.name) for l in location_definitions] + self.association.choices = current_user.association_list() if self.stoptime.data is None: self.stoptime.data = datetime.now() + timedelta(hours=1) diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/5c8378aa4dff_add_user_associations.py index 4cc135d..24f52c7 100644 --- a/app/migrations/versions/5c8378aa4dff_add_user_associations.py +++ b/app/migrations/versions/5c8378aa4dff_add_user_associations.py @@ -16,8 +16,8 @@ import sqlalchemy as sa def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('order', sa.Column('association', sa.String(length=120), nullable=True)) - op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=True)) + op.add_column('order', sa.Column('association', sa.String(length=120), nullable=False, default="")) + op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=False, default="")) # ### end Alembic commands ### diff --git a/app/models/anonymous_user.py b/app/models/anonymous_user.py index 2ae10f2..8e2532a 100644 --- a/app/models/anonymous_user.py +++ b/app/models/anonymous_user.py @@ -1,10 +1,14 @@ "AnonymouseUser for people who are not logged in the normal way" +from typing import List # pylint: disable=R0201,C0111 class AnonymouseUser: id = None + def association_list(self) -> List[str]: + return [] + def is_active(self) -> bool: return False diff --git a/app/models/order.py b/app/models/order.py index 7729d42..37407dd 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,7 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) - association = db.Column(db.String(120)) + association = db.Column(db.String(120), nullable=False) items = db.relationship("OrderItem", backref="order", lazy="dynamic") diff --git a/app/models/user.py b/app/models/user.py index 13634bb..964ba42 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -11,7 +11,7 @@ class User(db.Model): admin = db.Column(db.Boolean) bias = db.Column(db.Integer) # Assocation logic - associations = db.Column(db.String(120)) + associations = db.Column(db.String(120), nullable=False) # Relations runs = db.relation( diff --git a/app/templates/orders.html b/app/templates/orders.html index e472461..35fa189 100644 --- a/app/templates/orders.html +++ b/app/templates/orders.html @@ -38,6 +38,11 @@ {{ form.location_id(class='form-control select') }} {{ util.render_form_field_errors(form.location_id) }} +
    + {{ form.association.label(class='control-label') }} + {{ form.association(class='form-control select') }} + {{ util.render_form_field_errors(form.association) }} +
    {% if current_user.is_admin() %}
    {{ form.starttime.label(class='control-label') }} diff --git a/app/views/order.py b/app/views/order.py index 8023ecf..e779c5a 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -21,7 +21,7 @@ order_bp = Blueprint("order_bp", "order") @order_bp.route("/") def orders(form: OrderForm = None) -> str: """Generate general order view""" - if form is None and not current_user.is_anonymous(): + if form is None and current_user.association_list(): form = OrderForm() location_id = request.args.get("location_id") form.location_id.default = location_id @@ -34,6 +34,9 @@ def orders(form: OrderForm = None) -> str: @login_required def order_create() -> typing.Union[str, Response]: """Generate order create view""" + if not current_user.association_list(): + flash("Not allowed to create an order.", "info") + abort(401) orderForm = OrderForm() orderForm.populate() if orderForm.validate_on_submit(): -- 2.43.4 From a077a8038a1908a57e685a7384264821c5a1cea4 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:15:45 +0200 Subject: [PATCH 158/197] Only list orders to users of its association --- app/views/general.py | 8 +++++--- app/views/order.py | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/views/general.py b/app/views/general.py index 42753b6..9946fe6 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -9,7 +9,7 @@ from flask import Blueprint, Flask, abort from flask import current_app as app from flask import (jsonify, make_response, render_template, request, send_from_directory, url_for) -from flask_login import login_required +from flask_login import current_user, login_required from hlds.definitions import location_definitions from hlds.models import Location from models import Order @@ -31,10 +31,12 @@ def home() -> str: "Generate the home view" prev_day = datetime.now() - timedelta(days=1) recently_closed = get_orders( - (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) + (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) & Order.association.in_(current_user.association_list()) ) return render_template( - "home.html", orders=get_orders(), recently_closed=recently_closed + "home.html", orders=get_orders( + ((datetime.now() > Order.starttime) & (Order.stoptime > datetime.now()) | (Order.stoptime == None)) & Order.association.in_(current_user.association_list()) + ), recently_closed=recently_closed ) diff --git a/app/views/order.py b/app/views/order.py index e779c5a..dea851c 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -27,7 +27,7 @@ def orders(form: OrderForm = None) -> str: form.location_id.default = location_id form.process() form.populate() - return render_template("orders.html", orders=get_orders(), form=form) + return render_template("orders.html", orders=get_orders(expression=Order.association.in_(current_user.association_list())), form=form) @order_bp.route("/create", methods=["POST"]) -- 2.43.4 From d6d9d61f27bb1e6a491ccc7a559c2ca617a39be0 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:21:11 +0200 Subject: [PATCH 159/197] Remove some unused code --- app/templates/layout.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/templates/layout.html b/app/templates/layout.html index 3ba9722..72b85b7 100644 --- a/app/templates/layout.html +++ b/app/templates/layout.html @@ -14,12 +14,6 @@ {% set navbar = navbar + [('admin.index', 'Admin')] -%} {% endif -%} -{% if not current_user.is_anonymous() -%} - {% for association in current_user.association_list() %} - {% set navbar = navbar + [('general_bp.home', association)] -%} - {% endfor -%} -{% endif -%} - {% set active_page = active_page|default('index') -%} {% block title %} -- 2.43.4 From da1a708e28b7fb5329a88512fd7966a5a86ea52b Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 20 May 2022 23:29:05 +0200 Subject: [PATCH 160/197] List order association in admin view --- app/admin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/admin.py b/app/admin.py index 24b7d99..1845dee 100644 --- a/app/admin.py +++ b/app/admin.py @@ -28,11 +28,12 @@ class OrderAdminModel(ModelBaseView): "Class for the model of a OrderAdmin" # pylint: disable=too-few-public-methods column_default_sort = ("starttime", True) - column_list = ["starttime", "stoptime", "location_name", "location_id", "courier"] + column_list = ["starttime", "stoptime", "location_name", "location_id", "courier", "association"] column_labels = { "starttime": "Start Time", "stoptime": "Closing Time", "location_id": "HLDS Location ID", + "association": "Association", } form_excluded_columns = ["items", "courier_id"] can_delete = False -- 2.43.4 From 4d9d43b0f010015cf68d7285c7ffa55d20ada1fb Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Tue, 24 May 2022 21:26:51 +0200 Subject: [PATCH 161/197] Don't limit length (and fix migration) --- ...ations.py => f6a6004bf4b9_add_user_associations.py} | 10 +++++----- app/models/order.py | 2 +- app/models/user.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename app/migrations/versions/{5c8378aa4dff_add_user_associations.py => f6a6004bf4b9_add_user_associations.py} (70%) diff --git a/app/migrations/versions/5c8378aa4dff_add_user_associations.py b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py similarity index 70% rename from app/migrations/versions/5c8378aa4dff_add_user_associations.py rename to app/migrations/versions/f6a6004bf4b9_add_user_associations.py index 24f52c7..e084687 100644 --- a/app/migrations/versions/5c8378aa4dff_add_user_associations.py +++ b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py @@ -1,13 +1,13 @@ """Add user associations -Revision ID: 5c8378aa4dff +Revision ID: f6a6004bf4b9 Revises: 55013fe95bea -Create Date: 2022-05-20 21:32:47.786340 +Create Date: 2022-05-24 21:23:27.770365 """ # revision identifiers, used by Alembic. -revision = '5c8378aa4dff' +revision = 'f6a6004bf4b9' down_revision = '55013fe95bea' from alembic import op @@ -16,8 +16,8 @@ import sqlalchemy as sa def upgrade(): # ### commands auto generated by Alembic - please adjust! ### - op.add_column('order', sa.Column('association', sa.String(length=120), nullable=False, default="")) - op.add_column('user', sa.Column('associations', sa.String(length=120), nullable=False, default="")) + op.add_column('order', sa.Column('association', sa.String(length=120), server_default='', nullable=False)) + op.add_column('user', sa.Column('associations', sa.String(), server_default='', nullable=False)) # ### end Alembic commands ### diff --git a/app/models/order.py b/app/models/order.py index 37407dd..c7b458e 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -27,7 +27,7 @@ class Order(db.Model): stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) slug = db.Column(db.String(7), default=generate_slug, unique=True) - association = db.Column(db.String(120), nullable=False) + association = db.Column(db.String(120), nullable=False, server_default="") items = db.relationship("OrderItem", backref="order", lazy="dynamic") diff --git a/app/models/user.py b/app/models/user.py index 964ba42..a45faeb 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -11,7 +11,7 @@ class User(db.Model): admin = db.Column(db.Boolean) bias = db.Column(db.Integer) # Assocation logic - associations = db.Column(db.String(120), nullable=False) + associations = db.Column(db.String(), nullable=False, server_default="") # Relations runs = db.relation( -- 2.43.4 From c04d9bbd447509f451b8c8a475bc3aea6e39b925 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Wed, 25 May 2022 10:07:30 +0200 Subject: [PATCH 162/197] Fix typing of associations in user model --- app/models/user.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/user.py b/app/models/user.py index a45faeb..6f6a372 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -1,5 +1,5 @@ "Script for everything User related in the database" -from typing import List +from typing import List, Optional from models import db @@ -25,7 +25,7 @@ class User(db.Model): def association_list(self) -> List[str]: return self.associations.split(",") - def configure(self, username: str, admin: bool, bias: int, associations: List[str] = None) -> None: + def configure(self, username: str, admin: bool, bias: int, associations: Optional[List[str]] = None) -> None: """Configure the User""" if associations is None: associations = [] -- 2.43.4 From 44feb1a4ff7c62998c3f38fb98f2097dc32ea0aa Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 20 May 2022 19:41:42 +0200 Subject: [PATCH 163/197] Change forgotten order_id to order_slug in a few places --- app/admin.py | 1 + app/database/muhscheme.txt | 1 + app/templates/order.html | 2 +- app/templates/order_prices.html | 6 +++--- app/views/order.py | 14 +++++++------- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/admin.py b/app/admin.py index 24b7d99..0d0c172 100644 --- a/app/admin.py +++ b/app/admin.py @@ -44,6 +44,7 @@ class OrderItemAdminModel(ModelBaseView): column_default_sort = ("order_id", True) column_list = [ "order_id", + "slug", "order.location_name", "user_name", "user", diff --git a/app/database/muhscheme.txt b/app/database/muhscheme.txt index 173ff3c..9ac0206 100644 --- a/app/database/muhscheme.txt +++ b/app/database/muhscheme.txt @@ -9,6 +9,7 @@ user order id + slug secret used in URL courier_id location_id HLDS identifier location_name this allows historical orders to keep the same location name diff --git a/app/templates/order.html b/app/templates/order.html index 45a222f..0ad5611 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -348,7 +348,7 @@ {% if order.can_modify_prices(current_user.id) %}      - + Edit prices {% endif %} diff --git a/app/templates/order_prices.html b/app/templates/order_prices.html index d5eec77..49ac068 100644 --- a/app/templates/order_prices.html +++ b/app/templates/order_prices.html @@ -11,10 +11,10 @@ {% block container %}

    Edit prices

    -
    Only applied to order {{ order.id }}. To permanently change prices for {{ order.location_name }}, edit the HLDS location definition.
    +
    Only applied to order {{ order.id }}. To permanently change prices for {{ order.location_name }}, edit the HLDS location definition.
    - +

    Per dish

    This functionality requires JavaScript.
    @@ -86,7 +86,7 @@
    - Cancel + Cancel
    diff --git a/app/views/order.py b/app/views/order.py index 8023ecf..ddce63d 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -233,9 +233,9 @@ def modify_items(order_slug: str) -> typing.Optional[Response]: return delete_item(order_slug, int(request.form["delete_item"])) user_names = request.form.getlist("user_names") if request.form.get("action") == "mark_paid": - return set_items_paid(order_id, user_names, True) + return set_items_paid(order_slug, user_names, True) elif request.form.get("action") == "mark_unpaid": - return set_items_paid(order_id, user_names, False) + return set_items_paid(order_slug, user_names, False) else: abort(404) return None @@ -328,15 +328,15 @@ def close_order(order_slug: str) -> typing.Optional[Response]: return None -@order_bp.route("//prices", methods=["GET", "POST"]) +@order_bp.route("//prices", methods=["GET", "POST"]) @login_required -def prices(order_id: int) -> typing.Optional[Response]: - order = Order.query.filter(Order.id == order_id).first() +def prices(order_slug: str) -> typing.Optional[Response]: + order = Order.query.filter(Order.slug == order_slug).first() if order is None: abort(404) if not order.can_modify_prices(current_user.id): flash("You cannot modify the prices at this time.", "error") - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order.slug)) if request.method == "GET": return render_template( @@ -366,7 +366,7 @@ def prices(order_id: int) -> typing.Optional[Response]: item.price_modified = datetime.now() db.session.commit() - return redirect(url_for("order_bp.order_from_id", order_id=order_id)) + return redirect(url_for("order_bp.order_from_slug", order_slug=order.slug)) -- 2.43.4 From 453cacebd959a26a4af2da4fcf470c53bbc9a8cd Mon Sep 17 00:00:00 2001 From: Midgard Date: Fri, 20 May 2022 20:01:34 +0200 Subject: [PATCH 164/197] Add migration to add slug DB field to order --- .../versions/29ccbe077c57_add_slug.py | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/migrations/versions/29ccbe077c57_add_slug.py diff --git a/app/migrations/versions/29ccbe077c57_add_slug.py b/app/migrations/versions/29ccbe077c57_add_slug.py new file mode 100644 index 0000000..6e527e9 --- /dev/null +++ b/app/migrations/versions/29ccbe077c57_add_slug.py @@ -0,0 +1,23 @@ +"""add slug + +Revision ID: 29ccbe077c57 +Revises: 55013fe95bea +Create Date: 2022-05-20 19:46:11.924218 + +""" + +# revision identifiers, used by Alembic. +revision = '29ccbe077c57' +down_revision = '55013fe95bea' + +from alembic import op +import sqlalchemy as sa + +def upgrade(): + op.add_column('order', sa.Column('slug', sa.String(length=7), nullable=True)) + op.create_unique_constraint(None, 'order', ['slug']) + + +def downgrade(): + op.drop_constraint(None, 'order', type_='unique') + op.drop_column('order', 'slug') -- 2.43.4 From bb49fb2795eff59ca21834c38ce8cd1b87a4a206 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Mon, 30 May 2022 18:44:18 +0200 Subject: [PATCH 165/197] Add merge migration --- app/migrations/versions/9eac0f3d7b1e_.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 app/migrations/versions/9eac0f3d7b1e_.py diff --git a/app/migrations/versions/9eac0f3d7b1e_.py b/app/migrations/versions/9eac0f3d7b1e_.py new file mode 100644 index 0000000..b18b48c --- /dev/null +++ b/app/migrations/versions/9eac0f3d7b1e_.py @@ -0,0 +1,22 @@ +"""empty message + +Revision ID: 9eac0f3d7b1e +Revises: ('f6a6004bf4b9', '29ccbe077c57') +Create Date: 2022-05-30 18:35:43.918797 + +""" + +# revision identifiers, used by Alembic. +revision = '9eac0f3d7b1e' +down_revision = ('f6a6004bf4b9', '29ccbe077c57') + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + pass + + +def downgrade(): + pass -- 2.43.4 From 8f3750060b225aea58ef808974f4a55632519000 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Mon, 30 May 2022 18:50:46 +0200 Subject: [PATCH 166/197] VARCHAR requires a length in mysql --- app/migrations/versions/f6a6004bf4b9_add_user_associations.py | 2 +- app/models/user.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/migrations/versions/f6a6004bf4b9_add_user_associations.py b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py index e084687..44c0c9c 100644 --- a/app/migrations/versions/f6a6004bf4b9_add_user_associations.py +++ b/app/migrations/versions/f6a6004bf4b9_add_user_associations.py @@ -17,7 +17,7 @@ import sqlalchemy as sa def upgrade(): # ### commands auto generated by Alembic - please adjust! ### op.add_column('order', sa.Column('association', sa.String(length=120), server_default='', nullable=False)) - op.add_column('user', sa.Column('associations', sa.String(), server_default='', nullable=False)) + op.add_column('user', sa.Column('associations', sa.String(length=255), server_default='', nullable=False)) # ### end Alembic commands ### diff --git a/app/models/user.py b/app/models/user.py index 6f6a372..974fb81 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -11,7 +11,7 @@ class User(db.Model): admin = db.Column(db.Boolean) bias = db.Column(db.Integer) # Assocation logic - associations = db.Column(db.String(), nullable=False, server_default="") + associations = db.Column(db.String(255), nullable=False, server_default="") # Relations runs = db.relation( -- 2.43.4 From 4a353ec17ed4a3fa96b6be2aee488e876a3bdff9 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 25 May 2022 13:54:42 +0200 Subject: [PATCH 167/197] Create a slug for old orders in the migration --- .../versions/29ccbe077c57_add_slug.py | 28 +++++++++++++++++-- app/models/order.py | 10 ++----- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/app/migrations/versions/29ccbe077c57_add_slug.py b/app/migrations/versions/29ccbe077c57_add_slug.py index 6e527e9..4827845 100644 --- a/app/migrations/versions/29ccbe077c57_add_slug.py +++ b/app/migrations/versions/29ccbe077c57_add_slug.py @@ -12,12 +12,34 @@ down_revision = '55013fe95bea' from alembic import op import sqlalchemy as sa +from sqlalchemy.sql import text def upgrade(): - op.add_column('order', sa.Column('slug', sa.String(length=7), nullable=True)) - op.create_unique_constraint(None, 'order', ['slug']) + op.add_column('order', sa.Column( + 'slug', + sa.String(length=7), + nullable=False, + # Default: random alphanumerical string + server_default=text('SUBSTRING(MD5(RAND()) FROM 1 FOR 7)') + )) + op.create_unique_constraint('order_slug_unique', 'order', ['slug']) + + # Trigger to handle duplicates: generate new slug if slug already exists + op.execute(text( + """ + CREATE TRIGGER order_before_insert + BEFORE UPDATE ON `order` + FOR EACH ROW + BEGIN + WHILE (NEW.slug IS NULL OR (SELECT id FROM `order` WHERE slug = NEW.slug) IS NOT NULL) DO + SET NEW.slug = SUBSTRING(MD5(RAND()) FROM 1 FOR 7); + END WHILE; + END + """ + )) def downgrade(): - op.drop_constraint(None, 'order', type_='unique') + op.execute(text("DROP TRIGGER order_before_insert")) + op.drop_constraint('order_slug_unique', 'order', type_='unique') op.drop_column('order', 'slug') diff --git a/app/models/order.py b/app/models/order.py index c7b458e..6e1ff0b 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -2,7 +2,6 @@ import typing from collections import defaultdict from datetime import datetime -import secrets import string from hlds.definitions import location_definitions @@ -12,11 +11,6 @@ from .database import db from .user import User -def generate_slug(): - alphabet = string.ascii_letters + string.digits - return ''.join(secrets.choice(alphabet) for i in range(7)) - - class Order(db.Model): """Class used for configuring the Order model in the database""" id = db.Column(db.Integer, primary_key=True) @@ -26,7 +20,9 @@ class Order(db.Model): starttime = db.Column(db.DateTime) stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) - slug = db.Column(db.String(7), default=generate_slug, unique=True) + # The default value for `slug`, a random 7-character alphanumerical string, + # is created on the database side. See migrations/versions/29ccbe077c57_add_slug.py + slug = db.Column(db.String(7), unique=True) association = db.Column(db.String(120), nullable=False, server_default="") items = db.relationship("OrderItem", backref="order", lazy="dynamic") -- 2.43.4 From 01b5c72e7b76efc860388c8a8d061e20044aaaa1 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Mon, 30 May 2022 19:48:23 +0200 Subject: [PATCH 168/197] Generate slug in app --- app/migrations/versions/29ccbe077c57_add_slug.py | 15 --------------- app/models/order.py | 11 ++++++++--- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/app/migrations/versions/29ccbe077c57_add_slug.py b/app/migrations/versions/29ccbe077c57_add_slug.py index 4827845..31166ef 100644 --- a/app/migrations/versions/29ccbe077c57_add_slug.py +++ b/app/migrations/versions/29ccbe077c57_add_slug.py @@ -24,22 +24,7 @@ def upgrade(): )) op.create_unique_constraint('order_slug_unique', 'order', ['slug']) - # Trigger to handle duplicates: generate new slug if slug already exists - op.execute(text( - """ - CREATE TRIGGER order_before_insert - BEFORE UPDATE ON `order` - FOR EACH ROW - BEGIN - WHILE (NEW.slug IS NULL OR (SELECT id FROM `order` WHERE slug = NEW.slug) IS NOT NULL) DO - SET NEW.slug = SUBSTRING(MD5(RAND()) FROM 1 FOR 7); - END WHILE; - END - """ - )) - def downgrade(): - op.execute(text("DROP TRIGGER order_before_insert")) op.drop_constraint('order_slug_unique', 'order', type_='unique') op.drop_column('order', 'slug') diff --git a/app/models/order.py b/app/models/order.py index 6e1ff0b..1405563 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -2,6 +2,7 @@ import typing from collections import defaultdict from datetime import datetime +import secrets import string from hlds.definitions import location_definitions @@ -10,6 +11,12 @@ from utils import first from .database import db from .user import User +def generate_slug(): + alphabet = string.ascii_letters + string.digits + secret = ''.join(secrets.choice(alphabet) for i in range(7)) + while Order.query.filter(Order.slug == secret).first() is not None: + secret = ''.join(secrets.choice(alphabet) for i in range(7)) + return secret class Order(db.Model): """Class used for configuring the Order model in the database""" @@ -20,9 +27,7 @@ class Order(db.Model): starttime = db.Column(db.DateTime) stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) - # The default value for `slug`, a random 7-character alphanumerical string, - # is created on the database side. See migrations/versions/29ccbe077c57_add_slug.py - slug = db.Column(db.String(7), unique=True) + slug = db.Column(db.String(7), default=generate_slug, unique=True) association = db.Column(db.String(120), nullable=False, server_default="") items = db.relationship("OrderItem", backref="order", lazy="dynamic") -- 2.43.4 From 5306561ddd5d92ada7babc40a25327fe6921d830 Mon Sep 17 00:00:00 2001 From: Midgard Date: Wed, 25 May 2022 15:11:06 +0200 Subject: [PATCH 169/197] Correct word on home page --- app/templates/utils.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/utils.html b/app/templates/utils.html index 0af7b82..6ef2cf7 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -2,7 +2,7 @@
    {{ order.location_name }}
    - {{ order.items.count() }} orders

    + {{ order.items.count() }} items ordered

    {% if order.stoptime %} Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} -- 2.43.4 From 426357f00d3fe69b290c5004c27809bcebcd249c Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Mon, 30 May 2022 20:23:14 +0200 Subject: [PATCH 170/197] Move filtering by association to `get_orders` Fixes duplication and restores old `/orders` behaviour --- app/views/general.py | 4 ++-- app/views/order.py | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/views/general.py b/app/views/general.py index 9946fe6..8fd5b4f 100644 --- a/app/views/general.py +++ b/app/views/general.py @@ -31,11 +31,11 @@ def home() -> str: "Generate the home view" prev_day = datetime.now() - timedelta(days=1) recently_closed = get_orders( - (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) & Order.association.in_(current_user.association_list()) + (Order.stoptime > prev_day) & (Order.stoptime < datetime.now()) ) return render_template( "home.html", orders=get_orders( - ((datetime.now() > Order.starttime) & (Order.stoptime > datetime.now()) | (Order.stoptime == None)) & Order.association.in_(current_user.association_list()) + ((datetime.now() > Order.starttime) & (Order.stoptime > datetime.now()) | (Order.stoptime == None)) ), recently_closed=recently_closed ) diff --git a/app/views/order.py b/app/views/order.py index 80d930a..840fefd 100644 --- a/app/views/order.py +++ b/app/views/order.py @@ -27,7 +27,7 @@ def orders(form: OrderForm = None) -> str: form.location_id.default = location_id form.process() form.populate() - return render_template("orders.html", orders=get_orders(expression=Order.association.in_(current_user.association_list())), form=form) + return render_template("orders.html", orders=get_orders(), form=form) @order_bp.route("/create", methods=["POST"]) @@ -396,16 +396,17 @@ def get_orders(expression=None) -> typing.List[Order]: """Give the list of all currently open and public Orders""" order_list: typing.List[OrderForm] = [] if expression is None: - expression = (datetime.now() > Order.starttime) & ( - Order.stoptime - > datetime.now() - # pylint: disable=C0121 - ) | (Order.stoptime == None) + expression = ((datetime.now() > Order.starttime) & ( + Order.stoptime + > datetime.now() + # pylint: disable=C0121 + ) | (Order.stoptime == None) + ) & (Order.association.in_(current_user.association_list())) if not current_user.is_anonymous(): order_list = Order.query.filter(expression).all() else: order_list = Order.query.filter( # pylint: disable=C0121 - expression & (Order.public == True) + expression & (Order.public == True) & (Order.association.in_(current_user.association_list())) ).all() return order_list -- 2.43.4 From 978b432d7e0a62872103535ca8928d94594f090c Mon Sep 17 00:00:00 2001 From: mcbloch Date: Wed, 1 Jun 2022 17:18:47 +0200 Subject: [PATCH 171/197] use base58 for slugs to remove doubt --- app/models/order.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 1405563..3d9f84a 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -11,9 +11,11 @@ from utils import first from .database import db from .user import User +BASE58_ALPHABET = \ + b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' + def generate_slug(): - alphabet = string.ascii_letters + string.digits - secret = ''.join(secrets.choice(alphabet) for i in range(7)) + secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) while Order.query.filter(Order.slug == secret).first() is not None: secret = ''.join(secrets.choice(alphabet) for i in range(7)) return secret -- 2.43.4 From 2bdd07c9afb3df50303b56232a753139d985a53a Mon Sep 17 00:00:00 2001 From: Maxime <12089026+mcbloch@users.noreply.github.com> Date: Wed, 1 Jun 2022 17:24:27 +0200 Subject: [PATCH 172/197] Update app/models/order.py Co-authored-by: Charlotte Van Petegem --- app/models/order.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/order.py b/app/models/order.py index 3d9f84a..a56c121 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -17,7 +17,7 @@ BASE58_ALPHABET = \ def generate_slug(): secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) while Order.query.filter(Order.slug == secret).first() is not None: - secret = ''.join(secrets.choice(alphabet) for i in range(7)) + secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) return secret class Order(db.Model): -- 2.43.4 From 5d204a40125991ef10650b0673faf43ecdb4e430 Mon Sep 17 00:00:00 2001 From: mcbloch Date: Wed, 1 Jun 2022 17:36:52 +0200 Subject: [PATCH 173/197] use a string, not bytes --- app/models/order.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index a56c121..8c09cbd 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -11,8 +11,7 @@ from utils import first from .database import db from .user import User -BASE58_ALPHABET = \ - b'123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' def generate_slug(): secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) -- 2.43.4 From 066101623660f16af6939cf1fef607a4a9a32a3e Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 3 Jun 2022 19:05:33 +0200 Subject: [PATCH 174/197] Make slug eight characters --- app/migrations/versions/29ccbe077c57_add_slug.py | 2 +- app/models/order.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/migrations/versions/29ccbe077c57_add_slug.py b/app/migrations/versions/29ccbe077c57_add_slug.py index 31166ef..a4cf41c 100644 --- a/app/migrations/versions/29ccbe077c57_add_slug.py +++ b/app/migrations/versions/29ccbe077c57_add_slug.py @@ -17,7 +17,7 @@ from sqlalchemy.sql import text def upgrade(): op.add_column('order', sa.Column( 'slug', - sa.String(length=7), + sa.String(length=8), nullable=False, # Default: random alphanumerical string server_default=text('SUBSTRING(MD5(RAND()) FROM 1 FOR 7)') diff --git a/app/models/order.py b/app/models/order.py index 8c09cbd..7ae5de9 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -11,12 +11,12 @@ from utils import first from .database import db from .user import User -BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' +BASE34_ALPHABET = '123456789abcdefghijkmnopqrstuvwxyz' def generate_slug(): - secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) + secret = ''.join(secrets.choice(BASE34_ALPHABET) for i in range(8)) while Order.query.filter(Order.slug == secret).first() is not None: - secret = ''.join(secrets.choice(BASE58_ALPHABET) for i in range(7)) + secret = ''.join(secrets.choice(BASE34_ALPHABET) for i in range(8)) return secret class Order(db.Model): @@ -28,7 +28,7 @@ class Order(db.Model): starttime = db.Column(db.DateTime) stoptime = db.Column(db.DateTime) public = db.Column(db.Boolean, default=True) - slug = db.Column(db.String(7), default=generate_slug, unique=True) + slug = db.Column(db.String(8), default=generate_slug, unique=True) association = db.Column(db.String(120), nullable=False, server_default="") items = db.relationship("OrderItem", backref="order", lazy="dynamic") -- 2.43.4 From 3bc2ad83eacbf18e018d6124a41d03bda33236cf Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 3 Jun 2022 19:12:00 +0200 Subject: [PATCH 175/197] Remove some more letters from the alphabet --- app/models/order.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/order.py b/app/models/order.py index 7ae5de9..b5cc016 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -11,12 +11,12 @@ from utils import first from .database import db from .user import User -BASE34_ALPHABET = '123456789abcdefghijkmnopqrstuvwxyz' +BASE31_ALPHABET = '23456789abcdefghjkmnpqrstuvwxyz' def generate_slug(): - secret = ''.join(secrets.choice(BASE34_ALPHABET) for i in range(8)) + secret = ''.join(secrets.choice(BASE31_ALPHABET) for i in range(8)) while Order.query.filter(Order.slug == secret).first() is not None: - secret = ''.join(secrets.choice(BASE34_ALPHABET) for i in range(8)) + secret = ''.join(secrets.choice(BASE31_ALPHABET) for i in range(8)) return secret class Order(db.Model): -- 2.43.4 From 754eae4a50d7d6e108786110528389b15aa977a0 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Fri, 3 Jun 2022 19:27:11 +0200 Subject: [PATCH 176/197] Don't title username --- app/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/notification.py b/app/notification.py index 14ee065..33dd42e 100644 --- a/app/notification.py +++ b/app/notification.py @@ -21,7 +21,7 @@ def webhook_text(order: Order) -> typing.Optional[str]: url_for("order_bp.order_from_slug", order_slug=order.slug, _external=True), order.location_name, remaining_minutes(order.stoptime), - order.courier.username.title(), + order.courier.username, ) # pylint: disable=C0209 -- 2.43.4 From 687d389fa2d1f0e9a5e6d13f64943921d990ea86 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Fri, 10 Jun 2022 18:28:31 +0200 Subject: [PATCH 177/197] Fix not being able to delete an item from the list at the bottom of an order --- app/templates/order.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 0ad5611..fdc4948 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -314,9 +314,7 @@

  • {% if item.can_delete(order.id, current_user.id, session.get('anon_name', '')) -%} -
    - - + {% else %} {%- endif %} -- 2.43.4 From e302da0335e3bbe73636ff2bcf95c576e12fad37 Mon Sep 17 00:00:00 2001 From: AlexVDP8 Date: Thu, 27 Oct 2022 19:15:29 +0200 Subject: [PATCH 178/197] .tool-versions toegevoegd Co-authored-by: Francis --- .tool-versions | 1 + 1 file changed, 1 insertion(+) create mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..6826aa8 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +python 3.9.2 -- 2.43.4 From 4e8799eca5a0e8f9d332a86e26b59d1fe77e8d72 Mon Sep 17 00:00:00 2001 From: Happilands <49983499+Happilands@users.noreply.github.com> Date: Thu, 27 Oct 2022 19:29:50 +0200 Subject: [PATCH 179/197] Add robots.txt file From https://www.pythonanywhere.com/forums/topic/2899/ --- app/app.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/app.py b/app/app.py index c2d9e05..f42104e 100755 --- a/app/app.py +++ b/app/app.py @@ -8,7 +8,7 @@ from datetime import datetime from logging.handlers import TimedRotatingFileHandler from admin import init_admin -from flask import Flask, render_template +from flask import Flask, render_template, Response from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager @@ -158,6 +158,12 @@ def create_app(): """Initializer for the Flask app object""" app = Flask(__name__) + @app.route('/robots.txt') + def noindex(): + r = Response(response="User-Agent: *\nDisallow: /\n", status=200, mimetype="text/plain") + r.headers["Content-Type"] = "text/plain; charset=utf-8" + return r + # Load the config file app.config.from_object("config.Configuration") -- 2.43.4 From c0f44ab0375c329e05433013f6ba6f31724443e2 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Thu, 27 Oct 2022 19:38:46 +0200 Subject: [PATCH 180/197] Add glitchtip --- app/app.py | 8 ++++++++ app/config.example.py | 1 + requirements.in | 1 + requirements.txt | 47 ++++++++++++++++++++++++++----------------- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/app/app.py b/app/app.py index c2d9e05..852bc39 100755 --- a/app/app.py +++ b/app/app.py @@ -3,11 +3,13 @@ """Main Haldis script""" import logging +import sentry_sdk import typing from datetime import datetime from logging.handlers import TimedRotatingFileHandler from admin import init_admin +from config import Configuration from flask import Flask, render_template from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension @@ -19,6 +21,7 @@ from login import init_login from markupsafe import Markup from models import db from models.anonymous_user import AnonymouseUser +from sentry_sdk.integrations.flask import FlaskIntegration from utils import euro_string, price_range_string, ignore_none from zeus import init_oauth @@ -171,5 +174,10 @@ def create_app(): # For usage when you directly call the script with python if __name__ == "__main__": + sentry_sdk.init( + dsn=Configuration.SENTRY_DSN, + integrations=[FlaskIntegration()] + ) + app, app_mgr = create_app() app_mgr.run() diff --git a/app/config.example.py b/app/config.example.py index 2d02245..43cc22d 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -12,5 +12,6 @@ class Configuration: SECRET_KEY = "" SLACK_WEBHOOK = None LOGFILE = "haldis.log" + SENTRY_DSN = "" ZEUS_KEY = "tomtest" ZEUS_SECRET = "blargh" diff --git a/requirements.in b/requirements.in index 36c6ea3..8fbcf3f 100644 --- a/requirements.in +++ b/requirements.in @@ -12,3 +12,4 @@ black pymysql pyyaml tatsu<5.6 # >=5.6 needs Python >=3.8 +sentry-sdk[flask] diff --git a/requirements.txt b/requirements.txt index bbca76b..b2ca927 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.9 # To update, run: # # pip-compile @@ -11,11 +11,15 @@ appdirs==1.4.4 black==21.6b0 # via -r requirements.in blinker==1.4 - # via flask-debugtoolbar + # via + # flask-debugtoolbar + # sentry-sdk cachelib==0.1.1 # via flask-oauthlib certifi==2021.5.30 - # via requests + # via + # requests + # sentry-sdk chardet==4.0.0 # via requests click==7.1.2 @@ -24,6 +28,19 @@ click==7.1.2 # flask dominate==2.6.0 # via flask-bootstrap +flask==1.1.4 + # via + # -r requirements.in + # flask-admin + # flask-bootstrap + # flask-debugtoolbar + # flask-login + # flask-migrate + # flask-oauthlib + # flask-script + # flask-sqlalchemy + # flask-wtf + # sentry-sdk flask-admin==1.5.8 # via -r requirements.in flask-bootstrap==3.3.7.1 @@ -44,18 +61,6 @@ flask-sqlalchemy==2.5.1 # flask-migrate flask-wtf==0.15.1 # via -r requirements.in -flask==1.1.4 - # via - # -r requirements.in - # flask-admin - # flask-bootstrap - # flask-debugtoolbar - # flask-login - # flask-migrate - # flask-oauthlib - # flask-script - # flask-sqlalchemy - # flask-wtf greenlet==1.1.0 # via sqlalchemy idna==2.10 @@ -92,10 +97,12 @@ pyyaml==5.4.1 # via -r requirements.in regex==2021.4.4 # via black -requests-oauthlib==1.1.0 - # via flask-oauthlib requests==2.25.1 # via requests-oauthlib +requests-oauthlib==1.1.0 + # via flask-oauthlib +sentry-sdk[flask]==1.10.1 + # via -r requirements.in six==1.16.0 # via python-dateutil sqlalchemy==1.4.18 @@ -106,8 +113,10 @@ tatsu==4.4.0 # via -r requirements.in toml==0.10.2 # via black -urllib3==1.26.5 - # via requests +urllib3==1.26.12 + # via + # requests + # sentry-sdk visitor==0.1.3 # via flask-bootstrap werkzeug==1.0.1 -- 2.43.4 From 29afc8db7a3d6b50f33bb1252315f1b090f0ea47 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Thu, 27 Oct 2022 19:47:12 +0200 Subject: [PATCH 181/197] Make sure local dev still works with sentry --- app/app.py | 9 +++++---- app/config.example.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/app.py b/app/app.py index 852bc39..6ff1b25 100755 --- a/app/app.py +++ b/app/app.py @@ -174,10 +174,11 @@ def create_app(): # For usage when you directly call the script with python if __name__ == "__main__": - sentry_sdk.init( - dsn=Configuration.SENTRY_DSN, - integrations=[FlaskIntegration()] - ) + if Configuration.SENTRY_DSN: + sentry_sdk.init( + dsn=Configuration.SENTRY_DSN, + integrations=[FlaskIntegration()] + ) app, app_mgr = create_app() app_mgr.run() diff --git a/app/config.example.py b/app/config.example.py index 43cc22d..9606e09 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -12,6 +12,6 @@ class Configuration: SECRET_KEY = "" SLACK_WEBHOOK = None LOGFILE = "haldis.log" - SENTRY_DSN = "" + SENTRY_DSN = None ZEUS_KEY = "tomtest" ZEUS_SECRET = "blargh" -- 2.43.4 From bf8eb941174f46348ea6a47f4f9f493d26ea7692 Mon Sep 17 00:00:00 2001 From: Jasper Janin Date: Thu, 27 Oct 2022 20:24:35 +0200 Subject: [PATCH 182/197] Add user group reference to orders --- app/templates/order.html | 108 +++++++++++++++++++++------------------ app/templates/utils.html | 9 ++-- 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index fdc4948..2077f00 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -155,60 +155,66 @@

    Order information

    -
    -
    -
    Order opens
    -
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    +
    +
    +
    +
    Order opens
    +
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    -
    Order closes
    -
    - {% if order.stoptime %} - {% set stoptimefmt = ( - "%H:%M" if order.stoptime.date() == order.starttime.date() - else "%Y-%m-%d, %H:%M" - ) %} - {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) - {% else %} - Never - {% endif %} -
    +
    Order closes
    +
    + {% if order.stoptime %} + {% set stoptimefmt = ( + "%H:%M" if order.stoptime.date() == order.starttime.date() + else "%Y-%m-%d, %H:%M" + ) %} + {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) + {% else %} + Never + {% endif %} +
    +
    + +
    +
    Location
    +
    + {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
    + +
    Courier
    +
    + {% if order.courier == None %} + {% if not current_user.is_anonymous() %} +
    + + + {% else %}No-one yet{% endif %} + {% else %} + {{ order.courier.username }} + {% endif %} +
    +
    + +
    + +
    +
    - -
    -
    Location
    -
    - {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %} -
    - -
    Courier
    -
    - {% if order.courier == None %} - {% if not current_user.is_anonymous() %} -
    - - - {% else %}No-one yet{% endif %} - {% else %} - {{ order.courier.username }} - {% endif %} -
    -
    -
    - -
    - {% if order.can_close(current_user.id) -%} -
    - - - {% endif %} - {% if courier_or_admin %} - Edit - {%- endif %}
    + + {% if order.can_close(current_user.id) -%} +
    + + + {% endif %} + {% if courier_or_admin %} + Edit + {%- endif %} +
    diff --git a/app/templates/utils.html b/app/templates/utils.html index 6ef2cf7..ed7e2f3 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,14 +1,17 @@ {% macro render_order(order) -%}
    -
    +
    {{ order.location_name }}
    - {{ order.items.count() }} items ordered

    + {{ order.items.count() }} items ordered for {{ order.association }}

    {% if order.stoptime %} Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} {% else %}open{% endif %}

    -
    +
    + +
    +
    -- 2.43.4 From 202d5d3e7a6d43116ad70bdc778d306637aba6b4 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Thu, 27 Oct 2022 21:23:13 +0200 Subject: [PATCH 183/197] Revert "Merge branch 'master' of github.com:ZeusWPI/Haldis" This reverts commit 28fa1b75921c045754ed1c860996e1e9d511f8d2, reversing changes made to b14671413c5734c66503aae32f1f51f2dd4059ec. --- app/templates/order.html | 108 ++++++++++++++++++--------------------- app/templates/utils.html | 9 ++-- 2 files changed, 54 insertions(+), 63 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index 2077f00..fdc4948 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -155,66 +155,60 @@

    Order information

    -
    -
    -
    -
    Order opens
    -
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    +
    +
    +
    Order opens
    +
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    -
    Order closes
    -
    - {% if order.stoptime %} - {% set stoptimefmt = ( - "%H:%M" if order.stoptime.date() == order.starttime.date() - else "%Y-%m-%d, %H:%M" - ) %} - {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) - {% else %} - Never - {% endif %} -
    -
    - -
    -
    Location
    -
    - {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %} -
    - -
    Courier
    -
    - {% if order.courier == None %} - {% if not current_user.is_anonymous() %} -
    - - - {% else %}No-one yet{% endif %} - {% else %} - {{ order.courier.username }} - {% endif %} -
    -
    - -
    - -
    - +
    Order closes
    +
    + {% if order.stoptime %} + {% set stoptimefmt = ( + "%H:%M" if order.stoptime.date() == order.starttime.date() + else "%Y-%m-%d, %H:%M" + ) %} + {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) + {% else %} + Never + {% endif %} +
    + +
    +
    Location
    +
    + {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
    + +
    Courier
    +
    + {% if order.courier == None %} + {% if not current_user.is_anonymous() %} +
    + + + {% else %}No-one yet{% endif %} + {% else %} + {{ order.courier.username }} + {% endif %} +
    +
    +
    + +
    + {% if order.can_close(current_user.id) -%} +
    + + + {% endif %} + {% if courier_or_admin %} + Edit + {%- endif %}
    - - {% if order.can_close(current_user.id) -%} -
    - - - {% endif %} - {% if courier_or_admin %} - Edit - {%- endif %} -
    diff --git a/app/templates/utils.html b/app/templates/utils.html index ed7e2f3..6ef2cf7 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,17 +1,14 @@ {% macro render_order(order) -%}
    -
    +
    {{ order.location_name }}
    - {{ order.items.count() }} items ordered for {{ order.association }}

    + {{ order.items.count() }} items ordered

    {% if order.stoptime %} Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} {% else %}open{% endif %}

    -
    - -
    -
    +
    -- 2.43.4 From 7b12c266b34965133e6232f273cc35a93b02017e Mon Sep 17 00:00:00 2001 From: Jasper Janin Date: Thu, 27 Oct 2022 21:32:22 +0200 Subject: [PATCH 184/197] Add user group reference to orders --- app/templates/order.html | 108 +++++++++++++++++++++------------------ app/templates/utils.html | 9 ++-- 2 files changed, 63 insertions(+), 54 deletions(-) diff --git a/app/templates/order.html b/app/templates/order.html index fdc4948..2077f00 100644 --- a/app/templates/order.html +++ b/app/templates/order.html @@ -155,60 +155,66 @@

    Order information

    -
    -
    -
    Order opens
    -
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    +
    +
    +
    +
    Order opens
    +
    {{ order.starttime.strftime("%Y-%m-%d, %H:%M") }}
    -
    Order closes
    -
    - {% if order.stoptime %} - {% set stoptimefmt = ( - "%H:%M" if order.stoptime.date() == order.starttime.date() - else "%Y-%m-%d, %H:%M" - ) %} - {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) - {% else %} - Never - {% endif %} -
    +
    Order closes
    +
    + {% if order.stoptime %} + {% set stoptimefmt = ( + "%H:%M" if order.stoptime.date() == order.starttime.date() + else "%Y-%m-%d, %H:%M" + ) %} + {{ order.stoptime.strftime(stoptimefmt) }} ({{ order.stoptime|countdown }}) + {% else %} + Never + {% endif %} +
    +
    + +
    +
    Location
    +
    + {% if order.location %} + {{ order.location_name }} + {% else %} + {{ order.location_name }} + {% endif %} +
    + +
    Courier
    +
    + {% if order.courier == None %} + {% if not current_user.is_anonymous() %} +
    + + + {% else %}No-one yet{% endif %} + {% else %} + {{ order.courier.username }} + {% endif %} +
    +
    + +
    + +
    +
    - -
    -
    Location
    -
    - {% if order.location %} - {{ order.location_name }} - {% else %} - {{ order.location_name }} - {% endif %} -
    - -
    Courier
    -
    - {% if order.courier == None %} - {% if not current_user.is_anonymous() %} -
    - - - {% else %}No-one yet{% endif %} - {% else %} - {{ order.courier.username }} - {% endif %} -
    -
    -
    - -
    - {% if order.can_close(current_user.id) -%} -
    - - - {% endif %} - {% if courier_or_admin %} - Edit - {%- endif %}
    + + {% if order.can_close(current_user.id) -%} +
    + + + {% endif %} + {% if courier_or_admin %} + Edit + {%- endif %} +
    diff --git a/app/templates/utils.html b/app/templates/utils.html index 6ef2cf7..ed7e2f3 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,14 +1,17 @@ {% macro render_order(order) -%}
    -
    +
    {{ order.location_name }}
    - {{ order.items.count() }} items ordered

    + {{ order.items.count() }} items ordered for {{ order.association }}

    {% if order.stoptime %} Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} {% else %}open{% endif %}

    -
    +
    + +
    +
    -- 2.43.4 From a29ade4773c38855b2a51fbb4c761275e9d93a6c Mon Sep 17 00:00:00 2001 From: Jasper Janin Date: Thu, 27 Oct 2022 22:12:03 +0200 Subject: [PATCH 185/197] Remove redundant class attributes --- app/templates/utils.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/templates/utils.html b/app/templates/utils.html index ed7e2f3..781eac2 100644 --- a/app/templates/utils.html +++ b/app/templates/utils.html @@ -1,6 +1,6 @@ {% macro render_order(order) -%}
    -
    +
    {{ order.location_name }}
    {{ order.items.count() }} items ordered for {{ order.association }}

    @@ -8,10 +8,10 @@ Closes {{ order.stoptime.strftime("%H:%M") }}{{ order.stoptime|countdown }} {% else %}open{% endif %}

    -
    +
    -
    +
    -- 2.43.4 From 1bc6a5931e1e7813a5c0eb2177592e51cbea32d1 Mon Sep 17 00:00:00 2001 From: Charlotte Van Petegem Date: Tue, 24 Jan 2023 19:06:10 +0100 Subject: [PATCH 186/197] Order current user to the top for admins --- app/forms.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/forms.py b/app/forms.py index f847e96..4c21d4f 100644 --- a/app/forms.py +++ b/app/forms.py @@ -30,8 +30,11 @@ class OrderForm(Form): def populate(self) -> None: "Fill in the options for courier for an Order" if current_user.is_admin(): - self.courier_id.choices = [(0, None)] + [ - (u.id, u.username) for u in User.query.order_by("username") + self.courier_id.choices = [ + (0, None), + (current_user.id, current_user.username), + ] + [ + (u.id, u.username) for u in User.query.order_by("username") if u.id != current_user.id ] else: self.courier_id.choices = [ -- 2.43.4 From 6bb11e49a3d5b200769e804e5e74597bd375850f Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 21:18:44 +0200 Subject: [PATCH 187/197] Add support for when cwd is outside the project E.g. Pycharm runs `/.../haldis/venv/bin/python /.../haldis/app/app.py` when no working directory is set. --- app/hlds/definitions.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 961d14b..7f6e0c1 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -1,7 +1,6 @@ # Import this class to load the standard HLDS definitions - import subprocess -from os import path +from pathlib import Path from typing import List from .models import Location @@ -12,10 +11,11 @@ __all__ = ["location_definitions", "location_definition_version"] # pylint: disable=invalid-name # TODO Use proper way to get resources, see https://stackoverflow.com/a/10935674 -DATA_DIR = path.join(path.dirname(__file__), "..", "..", "menus") +ROOT_DIR = Path(__file__).parent.parent.parent +DATA_DIR = ROOT_DIR / "menus" -location_definitions: List[Location] = parse_all_directory(DATA_DIR) +location_definitions: List[Location] = parse_all_directory(str(DATA_DIR)) location_definitions.sort(key=lambda l: l.name) -proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, check=True) +proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=str(ROOT_DIR), check=True) location_definition_version = proc.stdout.decode().strip() -- 2.43.4 From 1ffcdc3ec1aa744d72f6a7f5da3447b668a75db1 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 22:03:40 +0200 Subject: [PATCH 188/197] Do not store UGent username since it is not exposed through Graph API --- app/app.py | 6 +++--- app/auth/microsoft.py | 11 +---------- app/models/user.py | 3 +-- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/app/app.py b/app/app.py index 1d38f73..262604f 100755 --- a/app/app.py +++ b/app/app.py @@ -8,22 +8,22 @@ import typing from datetime import datetime from logging.handlers import TimedRotatingFileHandler -from admin import init_admin from flask import Flask, render_template from flask_bootstrap import Bootstrap, StaticCDN from flask_debugtoolbar import DebugToolbarExtension from flask_login import LoginManager from flask_migrate import Migrate, MigrateCommand from flask_script import Manager, Server -from auth.login import init_login from markupsafe import Markup +from admin import init_admin +from auth.login import init_login +from auth.zeus import init_oauth from config import Configuration from models import db from models.anonymous_user import AnonymouseUser from sentry_sdk.integrations.flask import FlaskIntegration from utils import euro_string, price_range_string, ignore_none -from auth.zeus import init_oauth def register_plugins(app: Flask) -> Manager: diff --git a/app/auth/microsoft.py b/app/auth/microsoft.py index 35e542a..f10beb8 100644 --- a/app/auth/microsoft.py +++ b/app/auth/microsoft.py @@ -36,25 +36,16 @@ def authorized() -> typing.Any: oauth_code = request.args['code'] resp = client.exchange_code(url_for("auth_microsoft_bp.authorized", _external=True), oauth_code) - - # access_token = resp.data['access_token'] - # id_token = resp.data['id_token'] - # expires_in = resp.data['expires_in'] - client.set_token(resp.data) resp = client.users.get_me() - # print(resp.data) - username = resp.data['userPrincipalName'] microsoft_uuid = resp.data['id'] user = User.query.filter_by(username=username).first() - if username and user: return login_and_redirect_user(user) elif username: - # TODO Save 'ugent_username' or something similar user = create_user(username, microsoft_uuid) return login_and_redirect_user(user) @@ -71,7 +62,7 @@ def login_and_redirect_user(user) -> Response: def create_user(username, microsoft_uuid) -> User: """Create a temporary user if it is needed""" user = User() - user.configure(username, False, 1, microsoft_uuid) + user.configure(username, False, 1, microsoft_uuid=microsoft_uuid) db.session.add(user) db.session.commit() return user diff --git a/app/models/user.py b/app/models/user.py index a8cef69..5110cf7 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -12,7 +12,6 @@ class User(db.Model): bias = db.Column(db.Integer) # Microsoft OAUTH info microsoft_uuid = db.Column(db.String(120), unique=True) - ugent_username = db.Column(db.String(80), unique=True) # Association logic associations = db.Column(db.String(255), nullable=False, server_default="") @@ -28,7 +27,7 @@ class User(db.Model): def association_list(self) -> List[str]: return self.associations.split(",") - def configure(self, username: str, admin: bool, bias: int, microsoft_uuid: str = None, associations: Optional[List[str]] = None) -> None: + def configure(self, username: str, admin: bool, bias: int, *, microsoft_uuid: str = None, associations: Optional[List[str]] = None) -> None: """Configure the User""" if associations is None: associations = [] -- 2.43.4 From ba29ecbc73474d36d4659bee946cdcaaf471c0ca Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 22:38:30 +0200 Subject: [PATCH 189/197] Check for user with matching Microsoft UUID first --- app/auth/microsoft.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/app/auth/microsoft.py b/app/auth/microsoft.py index f10beb8..dced8a0 100644 --- a/app/auth/microsoft.py +++ b/app/auth/microsoft.py @@ -39,18 +39,27 @@ def authorized() -> typing.Any: client.set_token(resp.data) resp = client.users.get_me() - username = resp.data['userPrincipalName'] microsoft_uuid = resp.data['id'] + username = resp.data['userPrincipalName'] + # Fail if fields are not populated + if not microsoft_uuid or not username: + flash("You're not allowed to enter, please contact a system administrator") + return redirect(url_for("general_bp.home")) + + # Find existing user by Microsoft UUID (userPrincipalName can change) + user = User.query.filter_by(microsoft_uuid=microsoft_uuid).first() + if user: + return login_and_redirect_user(user) + + # Find existing user by username (pre-existing account) user = User.query.filter_by(username=username).first() - if username and user: - return login_and_redirect_user(user) - elif username: - user = create_user(username, microsoft_uuid) + if user: return login_and_redirect_user(user) - flash("You're not allowed to enter, please contact a system administrator") - return redirect(url_for("general_bp.home")) + # No user found, create a new one + user = create_user(username, microsoft_uuid=microsoft_uuid) + return login_and_redirect_user(user) def login_and_redirect_user(user) -> Response: @@ -59,7 +68,7 @@ def login_and_redirect_user(user) -> Response: return redirect(url_for("general_bp.home")) -def create_user(username, microsoft_uuid) -> User: +def create_user(username, *, microsoft_uuid) -> User: """Create a temporary user if it is needed""" user = User() user.configure(username, False, 1, microsoft_uuid=microsoft_uuid) -- 2.43.4 From 2d6aea10fb5fcf198123e2e8f9442c3cbabffc40 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 23:17:51 +0200 Subject: [PATCH 190/197] Change Microsoft account type to ugentbe.onmicrosoft.com --- app/auth/microsoft.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/auth/microsoft.py b/app/auth/microsoft.py index dced8a0..059f4eb 100644 --- a/app/auth/microsoft.py +++ b/app/auth/microsoft.py @@ -11,7 +11,7 @@ auth_microsoft_bp = Blueprint("auth_microsoft_bp", __name__) client = Client(Configuration.MICROSOFT_AUTH_ID, Configuration.MICROSOFT_AUTH_SECRET, - account_type='common') # by default common, thus account_type is optional parameter. + account_type="ugentbe.onmicrosoft.com") def microsoft_login(): -- 2.43.4 From 8b1b3f482a980ed989b707c303cf46c557309dfc Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 02:07:43 +0200 Subject: [PATCH 191/197] Add migration for Microsoft Auth --- app/migrations/versions/89b2c980b663_.py | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 app/migrations/versions/89b2c980b663_.py diff --git a/app/migrations/versions/89b2c980b663_.py b/app/migrations/versions/89b2c980b663_.py new file mode 100644 index 0000000..d859e69 --- /dev/null +++ b/app/migrations/versions/89b2c980b663_.py @@ -0,0 +1,26 @@ +"""empty message + +Revision ID: 89b2c980b663 +Revises: 9eac0f3d7b1e +Create Date: 2023-04-20 02:01:54.558602 + +""" + +# revision identifiers, used by Alembic. +revision = '89b2c980b663' +down_revision = '9eac0f3d7b1e' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('user', sa.Column('microsoft_uuid', sa.VARCHAR(length=120), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('user', 'microsoft_uuid') + # ### end Alembic commands ### -- 2.43.4 From 0aea3f6d3447320b4ae92e7fe7cfbd20caa3ec91 Mon Sep 17 00:00:00 2001 From: redfast00 Date: Tue, 13 Jun 2023 21:39:19 +0200 Subject: [PATCH 192/197] Remove double space requirement --- app/hlds/hlds.tatsu | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/hlds/hlds.tatsu b/app/hlds/hlds.tatsu index 08c859c..35612b8 100644 --- a/app/hlds/hlds.tatsu +++ b/app/hlds/hlds.tatsu @@ -29,9 +29,9 @@ location = >location_header items:{ block } ; attributes = - name:/[^\n#]*?(?= +-- | | *\n| *#)/ + name:/[^\n#]*?(?= +-- | | €| *\n| *#)/ [ s '--' ~ s description:/[^\n#]*?(?= | *\n| *#)/ ] - [ / {2,}/ ~ + [ / +/ ~ [ {[ s ] ('{' tags+:identifier '}')} / +|$/ ] [ price:price ] ] -- 2.43.4 From 7fad75fc088eeb53b24227ee56f74d1274cad6df Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Wed, 19 Apr 2023 23:48:59 +0200 Subject: [PATCH 193/197] Dockerize the application --- Dockerfile | 22 +++++++++++++ app/config.example.py | 7 ++++- app/hlds/definitions.py | 7 +++-- app/migrations/versions/150252c1cdb1_.py | 4 +-- .../9159a6fed021_initial_haldis_support.py | 5 ++- app/wsgi.py | 16 ++++++++++ docker-compose.override.yml | 17 ++++++++++ docker-compose.yml | 31 +++++++++++++++++++ 8 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 Dockerfile create mode 100644 app/wsgi.py create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..949823d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1 +FROM python:3.9.2-slim AS development + +WORKDIR /src + +RUN pip install pymysql + +COPY requirements.txt . +RUN pip install -r requirements.txt + +COPY . . + +WORKDIR /src/app +CMD python app.py db upgrade && \ + python app.py runserver -h 0.0.0.0 -p 8000 + +FROM development AS production + +RUN pip install waitress + +CMD python app.py db upgrade && \ + python wsgi.py diff --git a/app/config.example.py b/app/config.example.py index 1b016a8..ae60a55 100644 --- a/app/config.example.py +++ b/app/config.example.py @@ -1,11 +1,16 @@ """An example for a Haldis config""" -# config +# import os class Configuration: "Haldis configuration object" # pylint: disable=too-few-public-methods SQLALCHEMY_DATABASE_URI = "sqlite:///haldis.db" + # MARIADB_HOST = os.environ.get("MARIADB_HOST") + # MARIADB_DB = os.environ.get("MARIADB_DATABASE") + # MARIADB_USER = os.environ.get("MARIADB_USER") + # MARIADB_PASS = os.environ.get("MARIADB_PASSWORD") + # SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{MARIADB_USER}:{MARIADB_PASS}@{MARIADB_HOST}/{MARIADB_DB}" SQLALCHEMY_TRACK_MODIFICATIONS = False DEBUG = True HALDIS_ADMINS = [] diff --git a/app/hlds/definitions.py b/app/hlds/definitions.py index 7f6e0c1..1e540e7 100644 --- a/app/hlds/definitions.py +++ b/app/hlds/definitions.py @@ -17,5 +17,8 @@ DATA_DIR = ROOT_DIR / "menus" location_definitions: List[Location] = parse_all_directory(str(DATA_DIR)) location_definitions.sort(key=lambda l: l.name) -proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=str(ROOT_DIR), check=True) -location_definition_version = proc.stdout.decode().strip() +try: + proc = subprocess.run(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE, cwd=str(ROOT_DIR), check=True) + location_definition_version = proc.stdout.decode().strip() +except FileNotFoundError: + location_definition_version = "" diff --git a/app/migrations/versions/150252c1cdb1_.py b/app/migrations/versions/150252c1cdb1_.py index 927c101..77c7961 100644 --- a/app/migrations/versions/150252c1cdb1_.py +++ b/app/migrations/versions/150252c1cdb1_.py @@ -43,7 +43,7 @@ def upgrade(): sa.Column("starttime", sa.DateTime(), nullable=True), sa.Column("stoptime", sa.DateTime(), nullable=True), sa.Column("public", sa.Boolean(), nullable=True), - sa.ForeignKeyConstraint(["location_id"], ["location.id"]), + sa.ForeignKeyConstraint(["location_id"], ["location.id"], name="order_ibfk_1"), sa.PrimaryKeyConstraint("id"), ) op.create_table( @@ -65,7 +65,7 @@ def upgrade(): sa.Column("extra", sa.String(length=254), nullable=True), sa.Column("name", sa.String(length=120), nullable=True), sa.ForeignKeyConstraint(["order_id"], ["order.id"]), - sa.ForeignKeyConstraint(["product_id"], ["product.id"]), + sa.ForeignKeyConstraint(["product_id"], ["product.id"], name="order_item_ibfk_3"), sa.ForeignKeyConstraint(["user_id"], ["user.id"]), sa.PrimaryKeyConstraint("id"), ) diff --git a/app/migrations/versions/9159a6fed021_initial_haldis_support.py b/app/migrations/versions/9159a6fed021_initial_haldis_support.py index 710feb2..70ce1d7 100644 --- a/app/migrations/versions/9159a6fed021_initial_haldis_support.py +++ b/app/migrations/versions/9159a6fed021_initial_haldis_support.py @@ -112,14 +112,12 @@ def upgrade(): ) ) # Historical product data migrated, drop obsolete column and table - op.execute(text("ALTER TABLE order_item DROP FOREIGN KEY order_item_ibfk_3")) + op.drop_constraint("order_item_ibfk_3", "order_item", type_="foreignkey") op.drop_column("order_item", "product_id") op.drop_table("product") # ---------------------------------------------------------------------------------------------- # Migrate historical location data to orders - - op.execute(text("ALTER TABLE `order` DROP FOREIGN KEY order_ibfk_2")) op.alter_column( "order", "location_id", @@ -157,6 +155,7 @@ def upgrade(): for query in chain(new_location_id, [location_name_from_location]): op.execute(query) # Historical location data migrated, drop obsolete column and table + op.drop_constraint("order_ibfk_1", "order", type_="foreignkey") op.drop_column("order", "legacy_location_id") op.drop_table("location") diff --git a/app/wsgi.py b/app/wsgi.py new file mode 100644 index 0000000..d23f6f5 --- /dev/null +++ b/app/wsgi.py @@ -0,0 +1,16 @@ +import sentry_sdk +from sentry_sdk.integrations.flask import FlaskIntegration +from waitress import serve + +from app import create_app +from config import Configuration + +if __name__ == "__main__": + if Configuration.SENTRY_DSN: + sentry_sdk.init( + dsn=Configuration.SENTRY_DSN, + integrations=[FlaskIntegration()] + ) + + app, app_mgr = create_app() + serve(app_mgr, host="0.0.0.0", port=8000) diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..536e11b --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,17 @@ +version: "3.4" + +services: + app: + build: + target: "development" + environment: + - MARIADB_DATABASE=haldis + - MARIADB_USER=haldis + - MARIADB_PASSWORD=haldis + volumes: ["$PWD:/src"] + database: + environment: + - MARIADB_DATABASE=haldis + - MARIADB_ROOT_PASSWORD=mariadb + - MARIADB_USER=haldis + - MARIADB_PASSWORD=haldis \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..297cffd --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +version: "3.4" + +services: + app: + build: + context: . + target: production + restart: on-failure + depends_on: [database] + ports: ["8000:8000"] + environment: + - MARIADB_HOST=database + - MARIADB_DATABASE + - MARIADB_USER + - MARIADB_PASSWORD + networks: [haldis] + database: + image: mariadb:10.8 + hostname: database + restart: on-failure + environment: + - MARIADB_DATABASE + - MARIADB_ROOT_PASSWORD + - MARIADB_USER + - MARIADB_PASSWORD + networks: [haldis] + volumes: [haldis_data:/var/lib/mysql] +networks: + haldis: +volumes: + haldis_data: \ No newline at end of file -- 2.43.4 From a29d3a33be1959597fc3be666e0b894335f77e03 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 02:33:36 +0200 Subject: [PATCH 194/197] Use correct app when running with waitress --- Dockerfile | 2 +- app/{wsgi.py => waitress_wsgi.py} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename app/{wsgi.py => waitress_wsgi.py} (89%) diff --git a/Dockerfile b/Dockerfile index 949823d..c8381ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,4 +19,4 @@ FROM development AS production RUN pip install waitress CMD python app.py db upgrade && \ - python wsgi.py + python waitress_wsgi.py diff --git a/app/wsgi.py b/app/waitress_wsgi.py similarity index 89% rename from app/wsgi.py rename to app/waitress_wsgi.py index d23f6f5..579aa92 100644 --- a/app/wsgi.py +++ b/app/waitress_wsgi.py @@ -13,4 +13,4 @@ if __name__ == "__main__": ) app, app_mgr = create_app() - serve(app_mgr, host="0.0.0.0", port=8000) + serve(app, host="0.0.0.0", port=8000) -- 2.43.4 From 7b78e7d8fff862534ac694dcc0650d0e9f9a1919 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 19:50:23 +0200 Subject: [PATCH 195/197] Add .dockerignore --- .dockerignore | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d10c610 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,11 @@ +# Ignore everything +* + +# Include source, config and scripts +!app +!etc +!menus +!*.md +!*.sh +!*.txt +!LICENSE -- 2.43.4 From 45b49136578b2afde04f9527e4cbd7b36f109526 Mon Sep 17 00:00:00 2001 From: Maxim De Clercq Date: Thu, 20 Apr 2023 20:12:21 +0200 Subject: [PATCH 196/197] Add menus provided by Zeus WPI by default --- .dockerignore | 1 - Dockerfile | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.dockerignore b/.dockerignore index d10c610..9e692b1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,7 +4,6 @@ # Include source, config and scripts !app !etc -!menus !*.md !*.sh !*.txt diff --git a/Dockerfile b/Dockerfile index c8381ec..5c2add3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,10 @@ WORKDIR /src RUN pip install pymysql +ADD https://git.zeus.gent/haldis/menus/-/archive/master/menus-master.tar /tmp +RUN mkdir menus && \ + tar --directory=menus --extract --strip-components=1 --file=/tmp/menus-master.tar + COPY requirements.txt . RUN pip install -r requirements.txt -- 2.43.4 From 3cde7764c4fd10483ffb58af6c80b053aef08a87 Mon Sep 17 00:00:00 2001 From: Midgard Date: Sat, 29 Jun 2024 11:56:12 +0200 Subject: [PATCH 197/197] Update syntax for lifted double space requirement --- etc/vim/syntax.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/vim/syntax.vim b/etc/vim/syntax.vim index 5b783cd..d432f41 100644 --- a/etc/vim/syntax.vim +++ b/etc/vim/syntax.vim @@ -25,7 +25,7 @@ syn keyword hldsChoiceType single_choice multi_choice nextgroup=hldsBlockIdAf syn match hldsBlockId "^[a-z0-9_-]\+: " syn match hldsBlockIdAftrKywrd "[a-z0-9_-]\+: " contained -syn match _doubleSpace " \+" nextgroup=hldsTag,hldsPrice +syn match _space " \+" nextgroup=hldsTag,hldsPrice syn match hldsTag "{[a-z0-9_-]\+}\( \|$\)" contained nextgroup=hldsTag,hldsPrice syn match hldsPrice "€ *[0-9]\+\(\.[0-9]\+\|\)\( \|$\)" contained -- 2.43.4
  • TotalNameItems