diff --git a/DEPRECATED - routes.py b/DEPRECATED - routes.py new file mode 100644 index 00000000..4a2b23f6 --- /dev/null +++ b/DEPRECATED - routes.py @@ -0,0 +1,54 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Controller - Webpage routing + +Description: +Defines the routes and view functions for each page. +Manages the interaction between the frontend and backend. +""" + +from flask import render_template, url_for, Blueprint +from app import app +from app.forms import Form_Contact +# from forms import MyForm +# from app import MyForm +from models.model_view_contact import Model_View_Contact + +@app.route('/', methods=['GET']) +def home(): + return render_template('_home.html', title='Home') + +@app.route('/store', methods=['GET']) +def store_home(): + return render_template('_store_home.html', title='Store Home') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = Form_Contact() + if form.validate_on_submit(): + # Handle form submission + email = form.sender_email.data + CC = form.sender_CC.data + name = form.sender_name.data + msg = form.sender_message.data + # return render_template('contact.html', form=form) + # return render_template('_contact.html', title='Contact Us') + return render_template('contact.html', model=Model_View_Contact(form)) + +""" +@app.route('/about') +def about(): + return render_template('about.html') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = MyForm() + if form.validate_on_submit(): + # Handle form submission + pass + return render_template('contact.html', form=form) +""" \ No newline at end of file diff --git a/DEPRECATED_app.py b/DEPRECATED_app.py index fc0b6d82..d7eac935 100644 --- a/DEPRECATED_app.py +++ b/DEPRECATED_app.py @@ -252,12 +252,12 @@ def basket_add(): print(f'editing basket:') model.basket_item_edit(permutation_id, quantity, True) # new_basket = except: - return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) # 'items': [b_i.to_json() for b_i in model.basket]}}) - return jsonify({'status': 'failure', 'Message': 'Invalid quantities'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Invalid quantities'}) @@ -285,12 +285,12 @@ def basket_edit(): permutation_id, quantity = model.import_JSON_basket_item(data, form) model.basket_item_edit(permutation_id, quantity, False) # new_basket = except: - return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) - return jsonify({'status': 'failure', 'Message': 'Invalid quantities'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Invalid quantities'}) @app.route('/store/basket_delete', methods=['POST']) def basket_delete(): @@ -307,7 +307,7 @@ def basket_delete(): permutation_id, quantity = model.import_JSON_basket_item(data) model.basket_item_edit(permutation_id, 0, False) # new_basket = except: - return jsonify({'status': 'failure', 'Message': 'Bad data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad data received by controller'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') @@ -320,7 +320,7 @@ def basket_delete(): item_deleted = True break if not item_deleted: - return jsonify({'status': 'failure', 'Message': 'Basket item removal failure: product not found in basket.'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Basket item removal failure: product not found in basket.'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') @@ -345,7 +345,7 @@ def store_basket(): print('importing basket') model.import_JSON_basket(data) except: - return jsonify({'status': 'failure', 'Message': 'Bad basket data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad basket data received by controller'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) html_block = render_template('_page_store_billing.html', model = model) # print(f'html_block:\n{html_block}') @@ -390,7 +390,7 @@ def basket_info(): data_info[model.key_info_identical] = form.identical print(f'identical: {data_info[model.key_info_identical]}') except: - return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad form data received by controller'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) # html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') @@ -398,7 +398,7 @@ def basket_info(): data[model.key_info_type] = model.key_info_billing if (info_type == model.key_info_billing) else model.key_info_delivery data[info_type] = data_info return jsonify(Success = True, data = data) - return jsonify({'status': 'failure', 'Message': f'Invalid address information\n{form.errors}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': f'Invalid address information\n{form.errors}'}) @app.route('/store/product?permutationId=regionId=&¤cyId=&isIncludedVAT=', methods=['GET']) # & @@ -507,7 +507,7 @@ def create_checkout_session(): code_currency = 'GBP' # data[model.key_code_currency] print(f'currency code: {code_currency}') except: - return jsonify({'status': 'failure', 'Message': 'Bad form data received by controller'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, 'Message': 'Bad form data received by controller'}) items = [] for item in model.basket.items: permutation = item.product.get_permutation_selected() diff --git a/README b/README index ccdef51f..1e486389 100644 --- a/README +++ b/README @@ -7,4 +7,4 @@ host for machine: python -m flask run host for local network: -python -m flask run --host=0.0.0.0 \ No newline at end of file +python -m flask run --host=0.0.0.0 diff --git a/__pycache__/app.cpython-312.pyc b/__pycache__/app.cpython-312.pyc index 932cbac8..b2d92a9d 100644 Binary files a/__pycache__/app.cpython-312.pyc and b/__pycache__/app.cpython-312.pyc differ diff --git a/app.py b/app.py index 08bc98d5..e63b6477 100644 --- a/app.py +++ b/app.py @@ -39,6 +39,8 @@ import lib.argument_validation as av """ from routing.core import routes_core from routing.legal import routes_legal +from routing.store.store import routes_store +from routing.store.product import routes_store_product from routing.store.product_category import routes_store_product_category from routing.store.product_permutation import routes_store_product_permutation from routing.store.stock_item import routes_store_stock_item @@ -100,7 +102,8 @@ with app.app_context(): app.register_blueprint(routes_core) app.register_blueprint(routes_legal) -# app.register_blueprint(routes_store_product) +app.register_blueprint(routes_store) +app.register_blueprint(routes_store_product) app.register_blueprint(routes_store_product_category) app.register_blueprint(routes_store_product_permutation) app.register_blueprint(routes_store_stock_item) diff --git a/business_objects/__pycache__/base.cpython-312.pyc b/business_objects/__pycache__/base.cpython-312.pyc new file mode 100644 index 00000000..c7ef2d0f Binary files /dev/null and b/business_objects/__pycache__/base.cpython-312.pyc differ diff --git a/business_objects/__pycache__/db_base.cpython-312.pyc b/business_objects/__pycache__/db_base.cpython-312.pyc new file mode 100644 index 00000000..75c2841e Binary files /dev/null and b/business_objects/__pycache__/db_base.cpython-312.pyc differ diff --git a/business_objects/__pycache__/user.cpython-312.pyc b/business_objects/__pycache__/user.cpython-312.pyc index 64002d4d..85d51bf6 100644 Binary files a/business_objects/__pycache__/user.cpython-312.pyc and b/business_objects/__pycache__/user.cpython-312.pyc differ diff --git a/business_objects/db_base.py b/business_objects/db_base.py new file mode 100644 index 00000000..be09dc7b --- /dev/null +++ b/business_objects/db_base.py @@ -0,0 +1,73 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Database Base Business Objects + +Description: +Abstract business object for database objects +""" + +# internal +# from helpers.DEPRECATED.helper_abc import Interface_ABC +from extensions import db +import lib.argument_validation as av +# external +from typing import ClassVar +from abc import abstractmethod, ABCMeta +from pydantic import BaseModel +from sqlalchemy.ext.declarative import DeclarativeMeta +# from flask_sqlalchemy import SQLAlchemy + + +class Get_Many_Parameters_Base(BaseModel, metaclass=ABCMeta): + def __init__(self, **kwargs): + super().__init__(**kwargs) + @classmethod + @abstractmethod + def get_default(cls): + pass + @abstractmethod + def to_json(self): + pass + @classmethod + @abstractmethod + def from_json(cls, json): + pass + """ + @classmethod + @abstractmethod + def from_form(cls, form): + pass + """ + + +# db = SQLAlchemy() +# Base = declarative_base() +class SQLAlchemy_ABCMeta(db.Model.__class__, ABCMeta): + pass + +class SQLAlchemy_ABC(db.Model, metaclass=SQLAlchemy_ABCMeta): + __abstract__ = True + # id = db.Column(db.Integer, primary_key=True) + def __init__(self): + pass + def __repr__(self): + pass + def to_json(self): + pass + @classmethod + def from_json(cls, json): + pass + def to_json_option(self): + pass + def to_temporary_record(self): + pass + def to_object_with_missing_attributes(self, excluded_attributes): + return { + column.name: getattr(self, column.name) + for column in self.__table__.columns + if column.name not in excluded_attributes + } \ No newline at end of file diff --git a/business_objects/store/__pycache__/access_level.cpython-312.pyc b/business_objects/store/__pycache__/access_level.cpython-312.pyc new file mode 100644 index 00000000..a5cfe08f Binary files /dev/null and b/business_objects/store/__pycache__/access_level.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/basket.cpython-312.pyc b/business_objects/store/__pycache__/basket.cpython-312.pyc index 8e434db6..053352a6 100644 Binary files a/business_objects/store/__pycache__/basket.cpython-312.pyc and b/business_objects/store/__pycache__/basket.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/currency.cpython-312.pyc b/business_objects/store/__pycache__/currency.cpython-312.pyc index d1751f92..b9e8f026 100644 Binary files a/business_objects/store/__pycache__/currency.cpython-312.pyc and b/business_objects/store/__pycache__/currency.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/delivery_option.cpython-312.pyc b/business_objects/store/__pycache__/delivery_option.cpython-312.pyc index d5d868c1..c5117e83 100644 Binary files a/business_objects/store/__pycache__/delivery_option.cpython-312.pyc and b/business_objects/store/__pycache__/delivery_option.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/delivery_region.cpython-312.pyc b/business_objects/store/__pycache__/delivery_region.cpython-312.pyc index 7424ffc4..8b3529c7 100644 Binary files a/business_objects/store/__pycache__/delivery_region.cpython-312.pyc and b/business_objects/store/__pycache__/delivery_region.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/discount.cpython-312.pyc b/business_objects/store/__pycache__/discount.cpython-312.pyc index 8c972ffc..aeb74573 100644 Binary files a/business_objects/store/__pycache__/discount.cpython-312.pyc and b/business_objects/store/__pycache__/discount.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/image.cpython-312.pyc b/business_objects/store/__pycache__/image.cpython-312.pyc index cd02d233..28d28bca 100644 Binary files a/business_objects/store/__pycache__/image.cpython-312.pyc and b/business_objects/store/__pycache__/image.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product.cpython-312.pyc b/business_objects/store/__pycache__/product.cpython-312.pyc index aca21f39..ed4981c7 100644 Binary files a/business_objects/store/__pycache__/product.cpython-312.pyc and b/business_objects/store/__pycache__/product.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product_category.cpython-312.pyc b/business_objects/store/__pycache__/product_category.cpython-312.pyc index be00f8a1..7e2f12e9 100644 Binary files a/business_objects/store/__pycache__/product_category.cpython-312.pyc and b/business_objects/store/__pycache__/product_category.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product_permutation.cpython-312.pyc b/business_objects/store/__pycache__/product_permutation.cpython-312.pyc index a5f47324..3642ef73 100644 Binary files a/business_objects/store/__pycache__/product_permutation.cpython-312.pyc and b/business_objects/store/__pycache__/product_permutation.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product_price.cpython-312.pyc b/business_objects/store/__pycache__/product_price.cpython-312.pyc index 6a00f095..5554e929 100644 Binary files a/business_objects/store/__pycache__/product_price.cpython-312.pyc and b/business_objects/store/__pycache__/product_price.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product_variation.cpython-312.pyc b/business_objects/store/__pycache__/product_variation.cpython-312.pyc index ecc8f3c6..29babe0d 100644 Binary files a/business_objects/store/__pycache__/product_variation.cpython-312.pyc and b/business_objects/store/__pycache__/product_variation.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/product_variation_tree.cpython-312.pyc b/business_objects/store/__pycache__/product_variation_tree.cpython-312.pyc index c5a3d399..05f65774 100644 Binary files a/business_objects/store/__pycache__/product_variation_tree.cpython-312.pyc and b/business_objects/store/__pycache__/product_variation_tree.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/stock_item.cpython-312.pyc b/business_objects/store/__pycache__/stock_item.cpython-312.pyc index 202b1247..c5e06616 100644 Binary files a/business_objects/store/__pycache__/stock_item.cpython-312.pyc and b/business_objects/store/__pycache__/stock_item.cpython-312.pyc differ diff --git a/business_objects/store/__pycache__/store_base.cpython-312.pyc b/business_objects/store/__pycache__/store_base.cpython-312.pyc index 5b53c735..01a1a0c6 100644 Binary files a/business_objects/store/__pycache__/store_base.cpython-312.pyc and b/business_objects/store/__pycache__/store_base.cpython-312.pyc differ diff --git a/business_objects/store/access_level.py b/business_objects/store/access_level.py index e69de29b..108097e4 100644 --- a/business_objects/store/access_level.py +++ b/business_objects/store/access_level.py @@ -0,0 +1,95 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Business Objects +Feature: Product Category Business Object + +Description: +Business object for product +""" + +# internal +import lib.argument_validation as av +from business_objects.store.store_base import Store_Base +from extensions import db +# external +from pydantic import BaseModel +from typing import ClassVar + + +class Access_Level(db.Model, Store_Base): + __tablename__ = 'Shop_Access_Level_Temp' + id_access_level = db.Column(db.Integer, primary_key=True) + code = db.Column(db.String(50)) + name = db.Column(db.String(255)) + description = db.Column(db.String(4000)) + priority = db.Column(db.Integer) + display_order = db.Column(db.Integer) + active = db.Column(db.Boolean) + created_on = db.Column(db.DateTime) + created_by = db.Column(db.Integer) + def __init__(self): + super().__init__() + Store_Base.__init__(self) + def from_DB_access_level(query_row): + access_level = Access_Level() + access_level.id_access_level = query_row[0] + access_level.code = query_row[1] + access_level.name = query_row[2] + access_level.priority = query_row[3] + access_level.display_order = query_row[4] + access_level.active = query_row[5] + return access_level + def __repr__(self): + return f''' + id: {self.id_access_level[0] if isinstance(self.id_access_level, tuple) else self.id_access_level} + code: {self.code[0] if isinstance(self.code, tuple) else self.code} + name: {self.name[0] if isinstance(self.name, tuple) else self.name} + description: {self.description[0] if isinstance(self.description, tuple) else self.description} + priority: {self.priority[0] if isinstance(self.priority, tuple) else self.priority} + display_order: {self.display_order} + active: {self.active} + ''' + def to_json(self): + return { + self.ATTR_ID_ACCESS_LEVEL: self.id_access_level[0] if isinstance(self.id_access_level, tuple) else self.id_access_level, + self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code, + self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name, + self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description, + self.FLAG_PRIORITY: self.priority[0] if isinstance(self.priority, tuple) else self.priority, + self.FLAG_DISPLAY_ORDER: self.display_order, + self.FLAG_ACTIVE: self.active + } + def to_json_option(self): + return { + 'value': self.id_access_level, + 'text': self.name + } + @classmethod + def from_json(cls, json): + print(f'Access Level.from_json: {json}') + access_level = cls() + access_level.id_access_level = json[cls.ATTR_ID_ACCESS_LEVEL], + access_level.code = json[cls.FLAG_CODE], + access_level.name = json[cls.FLAG_NAME], + access_level.priority = json[cls.FLAG_PRIORITY], + access_level.description = json[cls.FLAG_DESCRIPTION], + access_level.display_order = json[cls.FLAG_DISPLAY_ORDER] + access_level.active = json[cls.FLAG_ACTIVE] + return access_level + +class Filters_Access_Level(BaseModel): + get_inactive_access_level: bool + def __init__(self, get_inactive_access_level = False): + super().__init__(get_inactive_access_level = get_inactive_access_level) + def to_json(self): + return { + 'a_get_inactive_access_level': self.get_inactive_access_level + } + @classmethod + def from_json(cls, json): + filters = cls() + filters.get_inactive_access_level = json['a_get_inactive_access_level'] + return filters \ No newline at end of file diff --git a/business_objects/store/basket.py b/business_objects/store/basket.py index 08bc9c85..ef7bff0d 100644 --- a/business_objects/store/basket.py +++ b/business_objects/store/basket.py @@ -61,8 +61,8 @@ class Basket_Item(): basket_item.is_included_VAT = is_included_VAT return basket_item - def add_discount(self, discount): - av.val_instance(discount, 'discount', 'Basket_Item.add_discount', Discount, v_arg_type='class attribute') + def add_product_price_discount(self, discount): + av.val_instance(discount, 'discount', 'Basket_Item.add_product_price_discount', Discount, v_arg_type='class attribute') self.discounts.append(discount) def set_delivery_option(self, delivery_option): diff --git a/business_objects/store/currency.py b/business_objects/store/currency.py index 5852a190..498e1a51 100644 --- a/business_objects/store/currency.py +++ b/business_objects/store/currency.py @@ -66,8 +66,8 @@ class Currency(db.Model): currency.display_order = query_row[5] return currency """ - def from_DB_product(query_row): - _m = 'Currency.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + _m = 'Currency.from_DB_get_many_product_catalogue' v_arg_type = 'class attribute' currency = Currency() currency.id_permutation = query_row[0] diff --git a/business_objects/store/delivery_option.py b/business_objects/store/delivery_option.py index 02931a0b..36e4c0b6 100644 --- a/business_objects/store/delivery_option.py +++ b/business_objects/store/delivery_option.py @@ -63,7 +63,7 @@ class Delivery_Option(db.Model): display_order = db.Column(db.Integer) def __init__(self): self.delivery_regions = [] - def from_DB_product(query_row): + def from_DB_get_many_product_catalogue(query_row): option = Delivery_Option() option.id_option = query_row[0] option.id_product = query_row[1] diff --git a/business_objects/store/delivery_region.py b/business_objects/store/delivery_region.py index 8d84ea38..5f7ceca8 100644 --- a/business_objects/store/delivery_region.py +++ b/business_objects/store/delivery_region.py @@ -59,7 +59,7 @@ class Delivery_Region(db.Model): self.code = code self.display_order = display_order """ - def from_DB_product(query_row): + def from_DB_get_many_product_catalogue(query_row): region = Delivery_Region() region.id_region = query_row[0] region.name = query_row[1] diff --git a/business_objects/store/discount.py b/business_objects/store/discount.py index be60d5e5..f5e5c75a 100644 --- a/business_objects/store/discount.py +++ b/business_objects/store/discount.py @@ -37,7 +37,7 @@ class Discount(db.Model): def __init__(self): self.delivery_regions = [] - def from_DB_product(query_row): + def from_DB_get_many_product_catalogue(query_row): discount = Discount() discount.id_discount = query_row[0] discount.id_category = query_row[1] diff --git a/business_objects/store/image.py b/business_objects/store/image.py index c9028c13..bbd886e5 100644 --- a/business_objects/store/image.py +++ b/business_objects/store/image.py @@ -73,8 +73,8 @@ class Image(db.Model): self.display_order = display_order super().__init__() """ - def from_DB_product(query_row): - _m = 'Image.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + _m = 'Image.from_DB_get_many_product_catalogue' # print(f'image: {query_row}') image = Image() image.id_image = query_row[0] diff --git a/business_objects/store/product.py b/business_objects/store/product.py index 9447c356..dce91325 100644 --- a/business_objects/store/product.py +++ b/business_objects/store/product.py @@ -14,6 +14,7 @@ Business object for product import lib.argument_validation as av from lib import data_types from forms.forms import Form_Basket_Add, Form_Basket_Edit, Form_Filters_Permutation +from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base from business_objects.store.delivery_option import Delivery_Option from business_objects.store.discount import Discount from business_objects.store.image import Image @@ -24,6 +25,7 @@ from business_objects.store.stock_item import Stock_Item from business_objects.store.product_variation import Product_Variation from business_objects.store.product_variation_tree import Product_Variation_Tree from extensions import db +from forms.store.product import Form_Filters_Product # external from dataclasses import dataclass from typing import ClassVar, List @@ -49,7 +51,7 @@ class Enum_Status_Stock(Enum): return data_types.get_enum_member_by_text(Enum_Status_Stock, text.upper()) """ -class Product(db.Model, Store_Base): +class Product(SQLAlchemy_ABC, Store_Base): FLAG_NAME: ClassVar[str] = 'name-product' FLAG_DISPLAY_ORDER: ClassVar[str] = 'display-order-product' FLAG_CAN_VIEW: ClassVar[str] = 'can-view-product' @@ -83,9 +85,10 @@ class Product(db.Model, Store_Base): Store_Base.__init__(self) self.form_basket_add = Form_Basket_Add() self.form_basket_edit = Form_Basket_Edit() + self.name_access_level_required = None - def from_DB_product(query_row): - _m = 'Product.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + _m = 'Product.from_DB_get_many_product_catalogue' v_arg_type = 'class attribute' product = Product() product.id_product = query_row[0] @@ -93,11 +96,12 @@ class Product(db.Model, Store_Base): product.name = query_row[2] product.has_variations = av.input_bool(query_row[3], "has_variations", _m, v_arg_type=v_arg_type) product.id_access_level_required = query_row[4] - product.active = av.input_bool(query_row[5], "active", _m, v_arg_type=v_arg_type) - product.display_order = query_row[6] - product.can_view = av.input_bool(query_row[7], "can_view", _m, v_arg_type=v_arg_type) - product.can_edit = av.input_bool(query_row[8], "can_edit", _m, v_arg_type=v_arg_type) - product.can_admin = av.input_bool(query_row[9], "can_admin", _m, v_arg_type=v_arg_type) + product.name_access_level_required = query_row[5] + product.active = av.input_bool(query_row[6], "active", _m, v_arg_type=v_arg_type) + product.display_order = query_row[7] + product.can_view = av.input_bool(query_row[8], "can_view", _m, v_arg_type=v_arg_type) + product.can_edit = av.input_bool(query_row[9], "can_edit", _m, v_arg_type=v_arg_type) + product.can_admin = av.input_bool(query_row[10], "can_admin", _m, v_arg_type=v_arg_type) return product """ def from_permutation(permutation, has_variations = False): @@ -117,8 +121,8 @@ class Product(db.Model, Store_Base): # product.get_variation_trees() return product """ - def add_permutation(self, permutation): - _m = 'Product.add_permutation' + def add_product_permutation(self, permutation): + _m = 'Product.add_product_permutation' av.val_instance(permutation, 'permutation', _m, Product_Permutation) try: self.permutation_index[permutation.id_permutation] @@ -159,7 +163,8 @@ class Product(db.Model, Store_Base): def get_variation_trees(self): self.variation_trees = [] for index_permutation in range(len(self.permutations)): - variation_tree = Product_Variation_Tree.from_product_permutation(self.permutations[index_permutation]) + permutation = self.permutations[index_permutation] + variation_tree = permutation.variation_tree # Product_Variation_Tree.from_product_permutation(permutation) found_variation_tree_match = False for index_tree in range(len(self.variation_trees)): if self.variation_trees[index_tree].is_equal(variation_tree): @@ -245,27 +250,27 @@ class Product(db.Model, Store_Base): return index_permutation raise ValueError(f"{av.error_msg_str(id_permutation, 'id_permutation', 'Product.get_index_permutation_from_id', int)}\nPermutation ID not found.") """ - def add_variation(self, variation): - av.val_instance(variation, 'variation', 'Product.add_variation', Product_Variation) + def add_product_variation(self, variation): + av.val_instance(variation, 'variation', 'Product.add_product_variation', Product_Variation) # print(f'variation: {variation}') index_permutation = self.permutation_index[variation.id_permutation] # self.get_index_permutation_from_id(variation.id_permutation) - self.permutations[index_permutation].add_variation(variation) - def add_price(self, price): - av.val_instance(price, 'price', 'Product.add_price', Product_Price) + self.permutations[index_permutation].add_product_variation(variation) + def add_product_price(self, price): + av.val_instance(price, 'price', 'Product.add_product_price', Product_Price) index_permutation = self.permutation_index[price.id_permutation] # self.get_index_permutation_from_id(price.id_permutation) - self.permutations[index_permutation].add_price(price) - def add_image(self, image): - av.val_instance(image, 'image', 'Product.add_image', Image) + self.permutations[index_permutation].add_product_price(price) + def add_product_image(self, image): + av.val_instance(image, 'image', 'Product.add_product_image', Image) index_permutation = self.permutation_index[image.id_permutation] # self.get_index_permutation_from_id(image.id_permutation) - self.permutations[index_permutation].add_image(image) + self.permutations[index_permutation].add_product_image(image) def add_delivery_option(self, delivery_option): av.val_instance(delivery_option, 'delivery_option', 'Product.add_delivery_option', Delivery_Option) index_permutation = self.permutation_index[delivery_option.id_permutation] # self.get_index_permutation_from_id(delivery_option.id_permutation) self.permutations[index_permutation].add_delivery_option(delivery_option) - def add_discount(self, discount): - av.val_instance(discount, 'discount', 'Product.add_discount', Discount) + def add_product_price_discount(self, discount): + av.val_instance(discount, 'discount', 'Product.add_product_price_discount', Discount) index_permutation = self.permutation_index[discount.id_permutation] # self.get_index_permutation_from_id(discount.id_permutation) - self.permutations[index_permutation].add_discount(discount) + self.permutations[index_permutation].add_product_price_discount(discount) def add_stock_item(self, stock_item): av.val_instance(stock_item, 'stock_item', 'Product.add_stock_item', Stock_Item) index_permutation = self.permutation_index[stock_item.id_permutation] @@ -279,7 +284,7 @@ class Product(db.Model, Store_Base): if permutation.is_available(): return True return False - def to_list_rows_permutation(self): + def to_permutation_row_list(self): list_rows = [] for permutation in self.permutations: list_rows.append(permutation.to_row_permutation()) @@ -317,6 +322,35 @@ class Product(db.Model, Store_Base): self.ATTR_ID_PRODUCT_PERMUTATION: [permutation.to_json() for permutation in self.permutations], self.FLAG_VARIATION_TREES: [tree.to_json() for tree in self.variation_trees] } + def to_json_option(self): + return { + 'value': self.id_product, + 'text': self.name + } + def get_variation_types_unique(self): + list_types = [] + for tree in self.variation_trees: + for type in tree.get_types_unique(): + if type not in list_types: + list_types.append(type) + return list_types + """ + def get_json_str_types_variation_trees(self): + json_str = '' + for tree in self.variation_trees: + if json_str != '': + json_str += '\n' + json_str += tree.get_json_str_types() + return json_str + def get_text_input_variation_types(self): + text_input = '' + for tree in self.variation_trees: + if text_input != '': + text_input += '\n' + text_input += tree.get_text_input_types() + return text_input + """ + @dataclass class Filters_Product(): @@ -386,7 +420,44 @@ class Filters_Product(): } @staticmethod - def from_form(form): + def from_form_filters_product(form): + # if not (form is Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}') + av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Product) + has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '') + is_not_empty = av.input_bool(form.is_not_empty.data, "is_not_empty", "Filters_Product.from_form_filters_product") + active = av.input_bool(form.active.data, "active", "Filters_Product.from_form_filters_product") + return Filters_Product( + get_all_product_category = not has_filter_category, + get_inactive_product_category = not active, + # get_first_product_category_only = False, + ids_product_category = form.id_category.data, + get_all_product = True, + get_inactive_product = not active, + # get_first_product_only = False, + ids_product = '', + get_all_permutation = True, + get_inactive_permutation = not active, + # get_first_permutation_only = False, + ids_permutation = '', + get_all_image = False, + get_inactive_image = False, + # get_first_image_only = False, + ids_image = '', + # get_all_region = False, + # get_inactive_region = False, + # get_first_region_only = False, + # ids_region = '', + # get_all_currency = False, + # get_inactive_currency = False, + # get_first_currency_only = False, + # ids_currency = '', + # get_all_discount = False, + # get_inactive_discount = False, + # ids_discount = '', + get_products_quantity_stock_below_min = False + ) + @staticmethod + def from_form_filters_product_permutation(form): # if not (form is Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}') av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Permutation) has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '') @@ -494,7 +565,7 @@ class Filters_Product(): def from_filters_product_category(cls, filters_category): return cls( get_all_product_category = True, - get_inactive_product_category = filters_category.active_only, + get_inactive_product_category = filters_category.active, ids_product_category = '', get_all_product = True, get_inactive_product = False, @@ -506,4 +577,234 @@ class Filters_Product(): get_inactive_image = False, ids_image = '', get_products_quantity_stock_below_min = False + ) + + +class Filters_Product(Get_Many_Parameters_Base): + # id_user: str + get_all_product_category: bool + get_inactive_product_category: bool + # get_first_product_category_only: bool + ids_product_category: str + get_all_product: bool + get_inactive_product: bool + # get_first_product_only: bool + ids_product: str + get_all_permutation: bool + get_inactive_permutation: bool + # get_first_permutation_only: bool + ids_permutation: str + get_all_image: bool + get_inactive_image: bool + # get_first_image_only: bool + ids_image: str + """ + get_all_region: bool + get_inactive_region: bool + get_first_region_only: bool + ids_region: str + get_all_currency: bool + get_inactive_currency: bool + get_first_currency_only: bool + ids_currency: str + get_all_discount: bool + get_inactive_discount: bool + ids_discount: str + """ + get_products_quantity_stock_below_min: bool + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def to_json(self): + return { + 'a_id_user': None, + 'a_get_all_product_category': self.get_all_product_category, + 'a_get_inactive_product_category': self.get_inactive_product_category, + # 'a_get_first_product_category_only': self.get_first_product_category_only, + 'a_ids_product_category': self.ids_product_category, + 'a_get_all_product': self.get_all_product, + 'a_get_inactive_product': self.get_inactive_product, + # 'a_get_first_product_only': self.get_first_product_only, + 'a_ids_product': self.ids_product, + 'a_get_all_permutation': self.get_all_permutation, + 'a_get_inactive_permutation': self.get_inactive_permutation, + # 'a_get_first_permutation_only': self.get_first_permutation_only, + 'a_ids_permutation': self.ids_permutation, + 'a_get_all_image': self.get_all_image, + 'a_get_inactive_image': self.get_inactive_image, + # 'a_get_first_image_only': self.get_first_image_only, + 'a_ids_image': self.ids_image, + # 'a_get_all_delivery_region': self.get_all_region, + # 'a_get_inactive_delivery_region': self.get_inactive_region, + # 'a_get_first_delivery_region_only': self.get_first_region_only, + # 'a_ids_delivery_region': self.ids_region, + # 'a_get_all_currency': self.get_all_currency, + # 'a_get_inactive_currency': self.get_inactive_currency, + # 'a_get_first_currency_only': self.get_first_currency_only, + # 'a_ids_currency': self.ids_currency, + # 'a_get_all_discount': self.get_all_discount, + # 'a_get_inactive_discount': self.get_inactive_discount, + # 'a_ids_discount': self.ids_discount, + 'a_get_products_quantity_stock_below_min': self.get_products_quantity_stock_below_min + } + + @staticmethod + def from_form_filters_product(form): + # if not (form is Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}') + av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Product) + has_filter_category = not (form.id_category.data == '0' or form.id_category.data == '') + is_not_empty = av.input_bool(form.is_not_empty.data, "is_not_empty", "Filters_Product.from_form_filters_product") + active = av.input_bool(form.active.data, "active", "Filters_Product.from_form_filters_product") + return Filters_Product( + get_all_product_category = not has_filter_category, + get_inactive_product_category = not active, + # get_first_product_category_only = False, + ids_product_category = form.id_category.data, + get_all_product = True, + get_inactive_product = not active, + # get_first_product_only = False, + ids_product = '', + get_all_permutation = True, + get_inactive_permutation = not active, + # get_first_permutation_only = False, + ids_permutation = '', + get_all_image = False, + get_inactive_image = False, + # get_first_image_only = False, + ids_image = '', + # get_all_region = False, + # get_inactive_region = False, + # get_first_region_only = False, + # ids_region = '', + # get_all_currency = False, + # get_inactive_currency = False, + # get_first_currency_only = False, + # ids_currency = '', + # get_all_discount = False, + # get_inactive_discount = False, + # ids_discount = '', + get_products_quantity_stock_below_min = False + ) + @staticmethod + def from_form_filters_product_permutation(form): + # if not (form is Form_Filters_Permutation): raise ValueError(f'Invalid form type: {type(form)}') + av.val_instance(form, 'form', 'Filters_Product.from_form', Form_Filters_Permutation) + has_category_filter = not (form.id_category.data == '0' or form.id_category.data == '') + has_product_filter = not (form.id_product.data == '0' or form.id_product.data == '') + get_permutations_stock_below_min = av.input_bool(form.is_out_of_stock.data, "is_out_of_stock", "Filters_Product.from_form") + print(f'form question: {type(form.is_out_of_stock)}\nbool interpretted: {get_permutations_stock_below_min}\type form: {type(form)}') + return Filters_Product( + get_all_product_category = not has_category_filter, + get_inactive_product_category = False, + # get_first_product_category_only = False, + ids_product_category = form.id_category.data, + get_all_product = not has_product_filter, + get_inactive_product = False, + # get_first_product_only = False, + ids_product = form.id_product.data, + get_all_permutation = not get_permutations_stock_below_min, + get_inactive_permutation = False, + # get_first_permutation_only = False, + ids_permutation = '', + get_all_image = False, + get_inactive_image = False, + # get_first_image_only = False, + ids_image = '', + # get_all_region = False, + # get_inactive_region = False, + # get_first_region_only = False, + # ids_region = '', + # get_all_currency = False, + # get_inactive_currency = False, + # get_first_currency_only = False, + # ids_currency = '', + # get_all_discount = False, + # get_inactive_discount = False, + # ids_discount = '', + get_products_quantity_stock_below_min = get_permutations_stock_below_min + ) + + @staticmethod + def get_default(): + return Filters_Product( + get_all_product_category = True, + get_inactive_product_category = False, + # get_first_product_category_only = False, + ids_product_category = '', + get_all_product = True, + get_inactive_product = False, + # get_first_product_only = False, + ids_product = '', + get_all_permutation = True, + get_inactive_permutation = False, + # get_first_permutation_only = False, + ids_permutation = '', + get_all_image = True, + get_inactive_image = False, + # get_first_image_only = False, + ids_image = '', + # get_all_region = True, + # et_inactive_region = False, + # get_first_region_only = False, + # ids_region = '', + # get_all_currency = True, + # get_inactive_currency = False, + # get_first_currency_only = False, + # ids_currency = '', + # get_all_discount = True, + # get_inactive_discount = False, + # ids_discount = '', + get_products_quantity_stock_below_min = True + ) + + @classmethod + def from_json(cls, json): + return cls( + get_all_product_category = json.get('a_get_all_product_category', False), + get_inactive_product_category = json.get('a_get_inactive_product_category', False), + # get_first_product_category_only = json.get('a_get_first_product_category_only', False), + ids_product_category = json.get('a_ids_product_category', ''), + get_all_product = json.get('a_get_all_product', False), + get_inactive_product = json.get('a_get_inactive_product', False), + # get_first_product_only = json.get('a_get_first_product_only', False), + ids_product = json.get('a_ids_product', ''), + get_all_permutation = json.get('a_get_all_permutation', False), + get_inactive_permutation = json.get('a_get_inactive_permutation', False), + # get_first_permutation_only = json.get('a_get_first_permutation_only', False), + ids_permutation = json.get('a_ids_permutation', ''), + get_all_image = json.get('a_get_all_image', False), + get_inactive_image = json.get('a_get_inactive_image', False), + # get_first_image_only = json.get('a_get_first_image_only', False), + ids_image = json.get('a_ids_image', ''), + # get_all_region = json.get('a_get_all_region', False), + # get_inactive_region = json.get('a_get_inactive_region', False), + # get_first_region_only = json.get('a_get_first_region_only', False), + # ids_region = json.get('a_ids_region', ''), + # get_all_currency = json.get('a_get_all_currency', False), + # get_inactive_currency = json.get('a_get_inactive_currency', False), + # get_first_currency_only = json.get('a_get_first_currency_only', False), + # ids_currency = json.get('a_ids_currency', ''), + # get_all_discount = json.get('a_get_all_discount', False), + # get_inactive_discount = json.get('a_get_inactive_discount', False), + # ids_discount = json.get('a_ids_discount', ''), + get_products_quantity_stock_below_min = json.get('a_get_products_quantity_stock_below_min', False) + ) + + @classmethod + def from_filters_product_category(cls, filters_category): + return cls( + get_all_product_category = True, + get_inactive_product_category = filters_category.active.data, + ids_product_category = '', + get_all_product = True, + get_inactive_product = False, + ids_product = '', + get_all_permutation = True, + get_inactive_permutation = False, + ids_permutation = '', + get_all_image = False, + get_inactive_image = False, + ids_image = '', + get_products_quantity_stock_below_min = False ) \ No newline at end of file diff --git a/business_objects/store/product_category.py b/business_objects/store/product_category.py index 53e0018f..6f28cf8b 100644 --- a/business_objects/store/product_category.py +++ b/business_objects/store/product_category.py @@ -12,6 +12,7 @@ Business object for product category # internal import lib.argument_validation as av +from business_objects.db_base import SQLAlchemy_ABC, Get_Many_Parameters_Base from business_objects.store.product import Product, Product_Permutation, Product_Price from business_objects.store.product_variation import Product_Variation from business_objects.store.image import Image @@ -24,36 +25,16 @@ from extensions import db from pydantic import BaseModel from typing import ClassVar -""" -class Enum_Product_Category(Enum): - ASSISTIVE_DEVICES = 0 - HOME_DECOR = 1 - MISCELLANEOUS = 99 - def text(self): - return Enum_Product_Category.Enum_Product_Category_Text(self) - - def Enum_Product_Category_Text(category): - av.val_instance(category, 'category', 'Product_Category_Enum_Text', Enum_Product_Category) - if category == Enum_Product_Category.ASSISTIVE_DEVICES: - return 'Assistive devices' - elif category == Enum_Product_Category.HOME_DECOR: - return 'Home decor' - else: - return 'Other' - - def get_member_by_text(text): - av.val_str(text, 'text', 'Enum_Product_Category.get_member_by_text') - return data_types.get_enum_member_by_text(Enum_Product_Category, text.upper()) -""" - -class Product_Category(db.Model, Store_Base): +class Product_Category(SQLAlchemy_ABC, Store_Base): + FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'id_access_level_required' __tablename__ = 'Shop_Product_Category_Temp' id_category = db.Column(db.Integer, primary_key=True) code = db.Column(db.String(50)) name = db.Column(db.String(255)) description = db.Column(db.String(4000)) id_access_level_required = db.Column(db.Integer) + name_access_level_required = db.Column(db.String(255)) display_order = db.Column(db.Integer) active = db.Column(db.Boolean) can_view = db.Column(db.Boolean) @@ -61,39 +42,25 @@ class Product_Category(db.Model, Store_Base): can_admin = db.Column(db.Boolean) created_on = db.Column(db.DateTime) created_by = db.Column(db.Integer) - """ - def __new__(cls, id, name, description, display_order): - _m = 'Category.__new__' - v_arg_type = 'class attribute' - av.val_int(id, 'id', _m, 0, v_arg_type=v_arg_type) - av.val_str(name, 'name', _m, max_len=256, v_arg_type=v_arg_type) - av.val_str(description, 'description', _m, max_len=4001, v_arg_type=v_arg_type) - av.val_int(display_order, 'display_order', _m, v_arg_type=v_arg_type) - return super(Category, cls).__new__(cls) - """ - def __init__(self): # , id, name, description, display_order): - """ - self.id_category = id - self.name = name - self.description = description - self.display_order = display_order - """ + def __init__(self): self.products = [] self.product_index = {} super().__init__() Store_Base.__init__(self) - def from_DB_product(query_row): + self.name_access_level_required = None + def from_DB_get_many_product_catalogue(query_row): category = Product_Category() category.id_category = query_row[0] category.code = query_row[1] category.name = query_row[2] category.description = query_row[3] category.id_access_level_required = query_row[4] - category.display_order = query_row[5] - category.active = query_row[6] - category.can_view = query_row[7] - category.can_edit = query_row[8] - category.can_admin = query_row[9] + category.name_access_level_required = query_row[5] + category.display_order = query_row[6] + category.active = query_row[7] + category.can_view = query_row[8] + category.can_edit = query_row[9] + category.can_admin = query_row[10] return category """ def key_product_index_from_ids_product_permutation(id_product, id_permutation): @@ -128,39 +95,39 @@ class Product_Category(db.Model, Store_Base): except KeyError: self.product_index[product.id_product] = len(self.products) self.products.append(product) - def add_permutation(self, permutation): - _m = 'Category.add_permutation' + def add_product_permutation(self, permutation): + _m = 'Category.add_product_permutation' av.val_instance(permutation, 'permutation', _m, Product_Permutation) # self.product_index.append(len(self.products)) # self.product_index[Category.key_product_index_from_ids_product_permutation(product.id_product, product.id_permutation)] = len(self.products) index_product = self.get_index_product_from_id(permutation.id_product) # index_product = self.product_index[permutation.id_product] - self.products[index_product].add_permutation(permutation) - def add_variation(self, variation): - av.val_instance(variation, 'variation', 'Category.add_variation', Product_Variation) + self.products[index_product].add_product_permutation(permutation) + def add_product_variation(self, variation): + av.val_instance(variation, 'variation', 'Category.add_product_variation', Product_Variation) index_product = self.get_index_product_from_id(variation.id_product) - self.products[index_product].add_variation(variation) - def add_price(self, price): - av.val_instance(price, 'price', 'Category.add_price', Product_Price) + self.products[index_product].add_product_variation(variation) + def add_product_price(self, price): + av.val_instance(price, 'price', 'Category.add_product_price', Product_Price) index_product = self.get_index_product_from_id(price.id_product) - self.products[index_product].add_price(price) - def add_image(self, image): - av.val_instance(image, 'image', 'Category.add_image', Image) + self.products[index_product].add_product_price(price) + def add_product_image(self, image): + av.val_instance(image, 'image', 'Category.add_product_image', Image) index_product = self.get_index_product_from_id(image.id_product) - self.products[index_product].add_image(image) + self.products[index_product].add_product_image(image) def add_delivery_option(self, delivery_option): av.val_instance(delivery_option, 'delivery_option', 'Category.add_delivery_option', Delivery_Option) index_product = self.get_index_product_from_id(delivery_option.id_product) self.products[index_product].add_delivery_option(delivery_option) - def add_discount(self, discount): - av.val_instance(discount, 'discount', 'Category.add_discount', Discount) + def add_product_price_discount(self, discount): + av.val_instance(discount, 'discount', 'Category.add_product_price_discount', Discount) index_product = self.get_index_product_from_id(discount.id_product) - self.products[index_product].add_discount(discount) + self.products[index_product].add_product_price_discount(discount) def add_stock_item(self, stock_item): av.val_instance(stock_item, 'stock_item', 'Category.add_stock_item', Stock_Item) index_product = self.get_index_product_from_id(stock_item.id_product) self.products[index_product].add_stock_item(stock_item) - def get_all_variation_trees(self): + def get_all_product_variation_trees(self): for product in self.products: if product.has_variations: print(f'product with id:{product.id_product} has variations') @@ -181,14 +148,17 @@ class Product_Category(db.Model, Store_Base): code: {self.code[0] if isinstance(self.code, tuple) else self.code} name: {self.name[0] if isinstance(self.name, tuple) else self.name} description: {self.description[0] if isinstance(self.description, tuple) else self.description} + access_level: {self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required} display_order: {self.display_order} active: {self.active} products: {self.products} ''' + """ def get_permutation_first(self): if not (len(self.products) == 0): print(f'getting first permutation from product') return None if len(self.products) == 0 else self.products[0].get_permutation_selected() + """ def is_available(self): if len(self.products) == 0: return False @@ -196,22 +166,25 @@ class Product_Category(db.Model, Store_Base): if product.is_available(): return True return False - def to_list_rows_permutation(self): + def to_permutation_row_list(self): list_rows = [] for product in self.products: - list_rows += product.to_list_rows_permutation() + list_rows += product.to_permutation_row_list() return list_rows - def to_list_products(self): + def to_product_option_list(self): list_products = [] for product in self.products: list_products.append({'value': product.id_product, 'text': product.name}) return list_products def to_json(self): return { + self.FLAG_KEY_PRIMARY: self.ATTR_ID_PRODUCT_CATEGORY, self.ATTR_ID_PRODUCT_CATEGORY: self.id_category[0] if isinstance(self.id_category, tuple) else self.id_category, self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code, self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name, self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description, + self.ATTR_ID_ACCESS_LEVEL: self.id_access_level_required[0] if isinstance(self.id_access_level_required, tuple) else self.id_access_level_required, + self.FLAG_ACCESS_LEVEL_REQUIRED: self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required, self.FLAG_DISPLAY_ORDER: self.display_order, self.FLAG_ACTIVE: self.active, self.FLAG_CAN_VIEW: self.can_view, @@ -222,31 +195,42 @@ class Product_Category(db.Model, Store_Base): def from_json(cls, json): print(f' Category.from_json: {json}') category = cls() - category.id_category = json.get(cls.ATTR_ID_PRODUCT_CATEGORY), + category.id_category = json[cls.ATTR_ID_PRODUCT_CATEGORY], category.code = json[cls.FLAG_CODE], category.name = json[cls.FLAG_NAME], category.description = json[cls.FLAG_DESCRIPTION], + category.id_access_level_required = json[cls.ATTR_ID_ACCESS_LEVEL], + category.name_access_level_required = json.get(cls.FLAG_ACCESS_LEVEL_REQUIRED, ''), category.display_order = json[cls.FLAG_DISPLAY_ORDER] category.active = json[cls.FLAG_ACTIVE] category.can_view = json.get(cls.FLAG_CAN_VIEW, False) category.can_edit = json.get(cls.FLAG_CAN_EDIT, False) category.can_admin = json.get(cls.FLAG_CAN_ADMIN, False) return category + """ def to_json_str(self): return { self.ATTR_ID_PRODUCT_CATEGORY: self.id_category[0] if isinstance(self.id_category, tuple) else self.id_category, self.FLAG_CODE: self.code[0] if isinstance(self.code, tuple) else self.code, self.FLAG_NAME: self.name[0] if isinstance(self.name, tuple) else self.name, self.FLAG_DESCRIPTION: self.description[0] if isinstance(self.description, tuple) else self.description, + self.ATTR_ID_ACCESS_LEVEL: self.id_access_level_required[0] if isinstance(self.id_access_level_required, tuple) else self.id_access_level_required, + self.FLAG_ACCESS_LEVEL_REQUIRED: self.name_access_level_required[0] if isinstance(self.name_access_level_required, tuple) else self.name_access_level_required, self.FLAG_DISPLAY_ORDER: self.display_order, self.FLAG_ACTIVE: self.output_bool(self.active), self.FLAG_CAN_VIEW: self.output_bool(self.can_view), self.FLAG_CAN_EDIT: self.output_bool(self.can_edit), self.FLAG_CAN_ADMIN: self.output_bool(self.can_admin) } + """ @staticmethod def output_bool(value): return av.input_bool(value, 'Product_Category bool attribute', 'Product_Category.output_bool') + def to_json_option(self): + return { + 'value': self.id_category, + 'text': self.name + } """ class Filters_Product_Category(BaseModel, Store_Base): ids_product_category: str @@ -284,42 +268,45 @@ class Filters_Product_Category(BaseModel, Store_Base): filters = cls() filters.ids_product_category = json['a_ids_product_category'], filters.ids_product = json['a_ids_product'] -""" -class Filters_Product_Category(BaseModel, Store_Base): - is_not_empty_only: bool - active_only: bool - def __init__(self, is_not_empty_only, active_only): - super().__init__(is_not_empty_only=is_not_empty_only, active_only=active_only) + + +class Filters_Product_Category(Get_Many_Parameters_Base): + FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is_not_empty' + is_not_empty: bool + active: bool + def __init__(self, is_not_empty, active): + super().__init__(is_not_empty=is_not_empty, active=active) @classmethod def get_default(cls): return cls( - is_not_empty_only = False, - active_only = True + is_not_empty = False, + active = True ) def to_json(self): return { - 'is_not_empty_only': self.is_not_empty_only, - 'active_only': self.active_only + self.FLAG_IS_NOT_EMPTY: self.is_not_empty, + self.FLAG_ACTIVE: self.active } @classmethod def from_json(cls, json): return cls( - is_not_empty_only = json['is_not_empty_only'], - active_only = json['active_only'] + is_not_empty = json['is_not_empty'], + active = json['active'] ) @classmethod def from_form(cls, form): return cls( - is_not_empty_only = av.input_bool(form.is_not_empty.data, 'is_not_empty', 'Filters_Product_Category.from_form'), - active_only = av.input_bool(form.active.data, 'active', 'Filters_Product_Category.from_form') + is_not_empty = av.input_bool(form.is_not_empty.data, 'is_not_empty', 'Filters_Product_Category.from_form'), + active = av.input_bool(form.active.data, 'active', 'Filters_Product_Category.from_form') ) +""" -class Container_Product_Category(Store_Base): +class Product_Category_Container(Store_Base): categories: list def __init__(self): self.categories = [] - def add_category(self, category): - av.val_instance(category, 'category', 'Container_Product_Categories.add_category', Product_Category) + def add_product_category(self, category): + av.val_instance(category, 'category', 'Container_Product_Categories.add_product_category', Product_Category) self.categories.append(category) def get_index_category_from_id(self, id_category): for index_category in range(len(self.categories)): @@ -340,73 +327,89 @@ class Container_Product_Category(Store_Base): av.val_instance(product, 'product', 'Container_Product_Categories.add_product', Product) index_category = self.get_index_category_from_id(product.id_category) self.categories[index_category].add_product(product) - def add_permutation(self, permutation): - av.val_instance(permutation, 'permutation', 'Container_Product_Categories.add_permutation', Product_Permutation) + def add_product_permutation(self, permutation): + av.val_instance(permutation, 'permutation', 'Container_Product_Categories.add_product_permutation', Product_Permutation) index_category = self.get_index_category_from_id(permutation.id_category) - self.categories[index_category].add_permutation(permutation) - def add_variation(self, variation): - av.val_instance(variation, 'variation', 'Container_Product_Categories.add_variation', Product_Variation) + self.categories[index_category].add_product_permutation(permutation) + def add_product_variation(self, variation): + av.val_instance(variation, 'variation', 'Container_Product_Categories.add_product_variation', Product_Variation) index_category = self.get_index_category_from_id(variation.id_category) - self.categories[index_category].add_variation(variation) - def add_price(self, price): - av.val_instance(price, 'price', 'Container_Product_Categories.add_price', Product_Price) + self.categories[index_category].add_product_variation(variation) + def add_product_price(self, price): + av.val_instance(price, 'price', 'Container_Product_Categories.add_product_price', Product_Price) index_category = self.get_index_category_from_id(price.id_category) - self.categories[index_category].add_price(price) - def add_image(self, image): - av.val_instance(image, 'image', 'Container_Product_Categories.add_image', Image) + self.categories[index_category].add_product_price(price) + def add_product_image(self, image): + av.val_instance(image, 'image', 'Container_Product_Categories.add_product_image', Image) index_category = self.get_index_category_from_id(image.id_category) - self.categories[index_category].add_image(image) + self.categories[index_category].add_product_image(image) def add_delivery_option(self, delivery_option): av.val_instance(delivery_option, 'delivery_option', 'Container_Product_Categories.add_delivery_option', Delivery_Option) index_category = self.get_index_category_from_id(delivery_option.id_category) self.categories[index_category].add_delivery_option(delivery_option) - def add_discount(self, discount): - av.val_instance(discount, 'discount', 'Container_Product_Categories.add_discount', Discount) + def add_product_price_discount(self, discount): + av.val_instance(discount, 'discount', 'Container_Product_Categories.add_product_price_discount', Discount) index_category = self.get_index_category_from_id(discount.id_category) - self.categories[index_category].add_discount(discount) + self.categories[index_category].add_product_price_discount(discount) def add_stock_item(self, stock_item): av.val_instance(stock_item, 'stock_item', 'Container_Product_Categories.add_stock_item', Stock_Item) index_category = self.get_index_category_from_id(stock_item.id_category) self.categories[index_category].add_stock_item(stock_item) - def get_all_variation_trees(self): + def get_all_product_variation_trees(self): for category in self.categories: - category.get_all_variation_trees() + category.get_all_product_variation_trees() def __repr__(self): return f'categories: {self.categories}' + """ def get_permutation_first(self): print(f'getting first permutation from category list') if not (len(self.categories) == 0): print(f'getting first permutation from category') return None if len(self.categories) == 0 else self.categories[0].get_permutation_first() - def get_count_categories(self): + """ + def get_category_count(self): return len(self.categories) - def to_list_rows_permutation(self): + def to_permutation_row_list(self): list_rows = [] for category in self.categories: - list_rows += category.to_list_rows_permutation() + list_rows += category.to_permutation_row_list() return list_rows - def to_list_category_options(self): + def to_category_option_list(self): list_categories = [] for category in self.categories: list_categories.append({'value': category.id_category, 'text': category.name}) return list_categories - def to_list_products(self): + def to_product_option_list(self): list_products = [] for category in self.categories: - # list_products.append(category.to_list_products()) + # list_products.append(category.to_product_option_list()) for product in category.products: list_products.append({'value': product.id_product, 'text': product.name, Product.ATTR_ID_PRODUCT_CATEGORY: product.id_category}) return list_products - def to_dict_lists_products(self): + def get_product_option_lists_by_category(self): dict_lists_products = {} for category in self.categories: - dict_lists_products[category.id_category] = category.to_list_products() + dict_lists_products[category.id_category] = category.to_product_option_list() return dict_lists_products def to_json(self): return { - 'categories': [category.to_json() for category in self.categories] + f'{self.FLAG_ROWS}': [category.to_json() for category in self.categories] } + """ def to_json_str(self): return { - 'categories': [category.to_json_str() for category in self.categories] - } \ No newline at end of file + f'{self.FLAG_ROWS}': [category.to_json_str() for category in self.categories] + } + """ + @classmethod + def from_json(cls, json): + return None + def to_json_option(self): + return None + def to_temporary_record(self): + excluded_attributes = { + column.name: getattr(self, column.name) + for column in self.__table__.columns + if column.name not in ['created_on', 'created_by'] + } + return self.to_object_with_missing_attributes(excluded_attributes) \ No newline at end of file diff --git a/business_objects/store/product_permutation.py b/business_objects/store/product_permutation.py index be0a4f44..8354a4c4 100644 --- a/business_objects/store/product_permutation.py +++ b/business_objects/store/product_permutation.py @@ -21,6 +21,7 @@ from business_objects.store.product_price import Product_Price from business_objects.store.stock_item import Stock_Item from business_objects.store.store_base import Store_Base from business_objects.store.product_variation import Product_Variation +from business_objects.store.product_variation_tree import Product_Variation_Tree from extensions import db # external from datetime import datetime, timedelta @@ -64,6 +65,7 @@ class Product_Permutation(db.Model, Store_Base): # form_basket_edit: Form_Basket_Edit # is_unavailable_in_currency_or_region: bool # is_available: bool + # variation_tree def __init__(self): self.variations = [] @@ -84,9 +86,10 @@ class Product_Permutation(db.Model, Store_Base): self.form_basket_edit = Form_Basket_Edit() self.is_unavailable_in_currency_or_region = False # self.is_available = False + self.variation_tree = None - def from_DB_product(query_row): - _m = 'Product_Permutation.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + _m = 'Product_Permutation.from_DB_get_many_product_catalogue' v_arg_type = 'class attribute' print(f'query_row: {query_row}') permutation = Product_Permutation() @@ -155,7 +158,7 @@ class Product_Permutation(db.Model, Store_Base): if permutation.has_variations: for jsonProductVariation in json[cls.ATTR_ID_PRODUCT_VARIATION]: variation = Product_Variation.from_json(jsonProductVariation) - permutation.add_variation(variation) + permutation.add_product_variation(variation) permutation.quantity_stock = json[cls.FLAG_QUANTITY_STOCK] permutation.quantity_min = json[cls.FLAG_QUANTITY_MIN] permutation.quantity_max = json[cls.FLAG_QUANTITY_MAX] @@ -185,6 +188,13 @@ class Product_Permutation(db.Model, Store_Base): 'delivery_options': {self.delivery_options}, 'prices': {self.prices} } + def to_json_option(self): + return { + 'value': self.id_permutation, + 'text': self.get_name_variations() + } + def get_name_variations(self): + return self.variation_tree.get_name_variations() def is_available(self): return len(self.prices) > 0 def get_price(self): @@ -270,8 +280,9 @@ class Product_Permutation(db.Model, Store_Base): price_GBP_min: {self.price_GBP_min} """ - def add_variation(self, variation): - _m = 'Product_Permutation.add_variation' + def add_product_variation(self, variation): + _m = 'Product_Permutation.add_product_variation' + """ av.val_instance(variation, 'variation', _m, Product_Variation) try: self.variation_index[variation.id_variation] @@ -279,8 +290,13 @@ class Product_Permutation(db.Model, Store_Base): except KeyError: self.variation_index[variation.id_variation] = len(self.variations) self.variations.append(variation) - def add_price(self, price): - _m = 'Product_Permutation.add_price' + """ + if self.variation_tree is None: + self.variation_tree = Product_Variation_Tree.from_product_variation(variation) + else: + self.variation_tree.add_product_variation(variation) + def add_product_price(self, price): + _m = 'Product_Permutation.add_product_price' av.val_instance(price, 'price', _m, Product_Price) try: self.price_index[price.display_order] @@ -288,8 +304,8 @@ class Product_Permutation(db.Model, Store_Base): except KeyError: self.price_index[price.display_order] = len(self.prices) self.prices.append(price) - def add_image(self, image): - _m = 'Product_Permutation.add_image' + def add_product_image(self, image): + _m = 'Product_Permutation.add_product_image' av.val_instance(image, 'image', _m, Image) try: self.image_index[image.id_image] @@ -306,8 +322,8 @@ class Product_Permutation(db.Model, Store_Base): except KeyError: self.delivery_option_index[delivery_option.id_option] = len(self.delivery_options) self.delivery_options.append(delivery_option) - def add_discount(self, discount): - _m = 'Product_Permutation.add_discount' + def add_product_price_discount(self, discount): + _m = 'Product_Permutation.add_product_price_discount' av.val_instance(discount, 'discount', _m, Discount) try: self.discount_index[discount.display_order] @@ -352,8 +368,8 @@ class Permutation_Product_Variation_Link(db.Model): id_category = db.Column(db.Integer) id_variation = db.Column(db.Integer) - def from_DB_product(query_row): - _m = 'Permutation_Product_Variation_Link.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + _m = 'Permutation_Product_Variation_Link.from_DB_get_many_product_catalogue' v_arg_type = 'class attribute' link = Permutation_Product_Variation_Link() link.id_permutation = query_row[0] diff --git a/business_objects/store/product_price.py b/business_objects/store/product_price.py index 71139b68..71adab43 100644 --- a/business_objects/store/product_price.py +++ b/business_objects/store/product_price.py @@ -42,8 +42,8 @@ class Product_Price(db.Model, Store_Base): super().__init__() Store_Base.__init__(self) - def from_DB_product(query_row): - # _m = 'Product_Price.from_DB_product' + def from_DB_get_many_product_catalogue(query_row): + # _m = 'Product_Price.from_DB_get_many_product_catalogue' price = Product_Price() price.id_price = query_row[0] price.id_permutation = query_row[1] @@ -90,6 +90,11 @@ class Product_Price(db.Model, Store_Base): self.FLAG_VALUE_LOCAL_VAT_EXCL: {self.value_local_VAT_excl}, self.FLAG_DISPLAY_ORDER: {self.display_order} } + def to_json_option(self): + return { + 'value': self.id_price, + 'text': f'{self.symbol_currency} {self.value_local_VAT_incl}' + } @classmethod def from_json(cls, json): diff --git a/business_objects/store/product_variation.py b/business_objects/store/product_variation.py index c9bd00ee..e6782677 100644 --- a/business_objects/store/product_variation.py +++ b/business_objects/store/product_variation.py @@ -56,7 +56,7 @@ class Product_Variation(db.Model, Store_Base): super().__init__() Store_Base.__init__(self) - def from_DB_product(query_row): + def from_DB_get_many_product_catalogue(query_row): variation = Product_Variation.from_DB_variation(query_row) variation.id_product = query_row[11] variation.id_permutation = query_row[12] @@ -122,6 +122,11 @@ class Product_Variation(db.Model, Store_Base): self.KEY_ACTIVE_VARIATION_TYPE: self.active_variation_type, self.KEY_ACTIVE_VARIATION: self.active_variation, } + def to_json_option(self): + return { + 'value': self.id_variation, + 'text': self.name_variation + } def to_json_variation_type(self): return { @@ -159,7 +164,7 @@ class Product_Variation_Filters(): @staticmethod def from_form(form): av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_Product_Variation) - get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form") + get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form") id_user = form.id_user.data return User_Filters( get_all_user = (id_user is None), @@ -197,8 +202,8 @@ class Product_Variation_Filters(): class Product_Variation_List(BaseModel): variations: list = [] - def add_variation(self, variation): - av.val_instance(variation, 'variation', 'Product_Variation_List.add_variation', Product_Variation) + def add_product_variation(self, variation): + av.val_instance(variation, 'variation', 'Product_Variation_List.add_product_variation', Product_Variation) self.variations.append(variation) def __repr__(self): diff --git a/business_objects/store/product_variation_tree.py b/business_objects/store/product_variation_tree.py index 0f24066e..51910d6f 100644 --- a/business_objects/store/product_variation_tree.py +++ b/business_objects/store/product_variation_tree.py @@ -38,24 +38,19 @@ class Product_Variation_Tree_Node(): class Product_Variation_Tree(): node_root: Product_Variation_Tree_Node - def from_node_root(node_root): - tree = Product_Variation_Tree() + @classmethod + def from_node_root(cls, node_root): + tree = cls() tree.node_root = node_root return tree - def get_variation_type_list(self): - variation_types = [] - node = self.node_root - at_leaf_node = node.is_leaf() - while not at_leaf_node: - variation_types.append(node.variation.name_variation_type) - at_leaf_node = node.is_leaf() - if not at_leaf_node: - node = node.nodes_child[0] - return variation_types + @classmethod + def from_variation_root(cls, variation_root): + node_root = Product_Variation_Tree_Node.from_variation_and_node_parent(variation_root, None) + return cls.from_node_root(node_root) def is_equal(self, tree): - my_type_list = self.get_variation_type_list() + my_type_list = self.get_product_variations() sz_me = len(my_type_list) - other_type_list = tree.get_variation_type_list() + other_type_list = tree.get_product_variations() sz_other = len(other_type_list) is_equal = (sz_me == sz_other) if is_equal: @@ -71,3 +66,44 @@ class Product_Variation_Tree(): for depth in range(depth_max - 1): node = Product_Variation_Tree_Node.from_variation_and_node_parent(product_permutation.variations[depth + 1], node) return Product_Variation_Tree.from_node_root(node_root) + def from_product_variation(product_variation): + node_root = Product_Variation_Tree_Node.from_variation_and_node_parent(product_variation, None) + return Product_Variation_Tree.from_node_root(node_root) + def get_name_variations(self): + node = self.node_root + name = node.variation.name_variation_type + at_leaf_node = node.is_leaf() + while not at_leaf_node: + node = node.nodes_child[0] + name += f', {node.variation.name_variation_type}' + at_leaf_node = node.is_leaf() + return name + def get_node_leaf(self): + node = self.node_root + at_leaf_node = node.is_leaf() + while not at_leaf_node: + node = node.nodes_child[0] + at_leaf_node = node.is_leaf() + return node + def add_product_variation(self, variation): + node_leaf = self.get_node_leaf() + node_new = Product_Variation_Tree_Node.from_variation_and_node_parent(variation, node_leaf) + node_leaf.add_child(node_new) + def get_product_variation_types(self): + types = [] + node = self.node_root + at_leaf_node = node.is_leaf() + while not at_leaf_node: + types.append(node.variation.name_variation_type) + node = node.nodes_child[0] + at_leaf_node = node.is_leaf() + return types + def get_product_variations(self): + variations = [] + node = self.node_root + at_leaf_node = node.is_leaf() + while not at_leaf_node: + variations.append(node.variation) + node = node.nodes_child[0] + at_leaf_node = node.is_leaf() + return variations \ No newline at end of file diff --git a/business_objects/store/stock_item.py b/business_objects/store/stock_item.py index f0496349..65b5e41a 100644 --- a/business_objects/store/stock_item.py +++ b/business_objects/store/stock_item.py @@ -173,6 +173,19 @@ class Stock_Item(db.Model, Store_Base): permutations: {self.permutations} variation trees: {self.variation_trees} ''' + def to_json(self): + return { + self.ATTR_ID_PRODUCT: {self.id_product}, + self.ATTR_ID_PRODUCT_CATEGORY: {self.id_category}, + self.FLAG_NAME: {self.name}, + self.FLAG_DISPLAY_ORDER: {self.display_order}, + self.FLAG_CAN_VIEW: {self.can_view}, + self.FLAG_CAN_EDIT: {self.can_edit}, + self.FLAG_CAN_ADMIN: {self.can_admin}, + self.FLAG_HAS_VARIATIONS: {self.has_variations}, + self.FLAG_PERMUTATIONS: {self.permutations}, + self.FLAG_VARIATION_TREES: {self.variation_trees}, + } def has_permutations(self): return len(self.permutations) > 0 def is_available(self): @@ -183,12 +196,17 @@ class Stock_Item(db.Model, Store_Base): return True return False """ - def to_list_rows_permutation(self): + def to_permutation_row_list(self): list_rows = [] for permutation in self.permutations: list_rows.append(permutation.to_row_permutation()) return list_rows """ + def to_json_option(self): + return { + 'value': self.id_stock_item, + 'text': self.id_stock_item + } @dataclass class Stock_Item_Filters(): diff --git a/business_objects/store/store_base.py b/business_objects/store/store_base.py index b51118fc..67a40d03 100644 --- a/business_objects/store/store_base.py +++ b/business_objects/store/store_base.py @@ -11,10 +11,52 @@ Abstract business object for store objects """ # internal +# from helpers.DEPRECATED.helper_abc import Interface_ABC +from extensions import db +import lib.argument_validation as av # external from typing import ClassVar +""" +class I_Store_Base(): + @abstractmethod + def __repr__(self): + pass + @classmethod + @abstractmethod + def from_json(cls, json): + pass + @abstractmethod + def to_json(self): + pass + @abstractmethod + def to_json_option(self): + pass + @abstractmethod + def test_69 (self): + pass + "" + def __init_subclass__(cls, **kwargs): + super().__init_subclass__(**kwargs) + for name, value in vars(Store_Base).items(): + if getattr(value, "__isabstractmethod__", False): + if name not in cls.__dict__: + raise TypeError(f"Can't instantiate class {cls.__name__} " + f"without implementation of abstract method {name}") + subclass_value = cls.__dict__[name] + if (isinstance(value, (staticmethod, classmethod)) and + not isinstance(subclass_value, type(value))): + raise TypeError(f"Abstract {type(value).__name__} {name} in {cls.__name__} " + f"must be implemented as a {type(value).__name__}") + def __new__(cls, *args, **kwargs): + if cls is Store_Base: + raise TypeError("Can't instantiate abstract class Store_Base directly") + return super().__new__(cls) + "" +""" + class Store_Base(): + ATTR_ID_ACCESS_LEVEL: ClassVar[str] = 'id_access_level' ATTR_ID_CURRENCY: ClassVar[str] = 'id_currency' # ATTR_ID_CURRENCY_COST: ClassVar[str] = 'id_currency_cost' ATTR_ID_DELIVERY_REGION: ClassVar[str] = 'id_delivery_region' @@ -28,6 +70,7 @@ class Store_Base(): ATTR_ID_PRODUCT_VARIATION: ClassVar[str] = 'id_variation' ATTR_ID_PRODUCT_VARIATION_TYPE: ClassVar[str] = 'id_variation_type' ATTR_ID_STOCK_ITEM: ClassVar[str] = 'id_stock_item' + FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = 'access_level_required' FLAG_ACTIVE: ClassVar[str] = 'active' FLAG_CAN_ADMIN: ClassVar[str] = 'can_admin' FLAG_CAN_EDIT: ClassVar[str] = 'can_edit' @@ -35,31 +78,17 @@ class Store_Base(): FLAG_CODE: ClassVar[str] = 'code' FLAG_DESCRIPTION: ClassVar[str] = 'description' FLAG_DISPLAY_ORDER: ClassVar[str] = 'display_order' + FLAG_HAS_VARIATIONS: ClassVar[str] = 'has_variations' + FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is_not_empty' + FLAG_KEY_PRIMARY: ClassVar[str] = 'key_primary' FLAG_NAME: ClassVar[str] = 'name' - - def __init_subclass__(cls, **kwargs): - super().__init_subclass__(**kwargs) - for name, value in vars(Store_Base).items(): - if getattr(value, "__isabstractmethod__", False): - if name not in cls.__dict__: - raise TypeError(f"Can't instantiate class {cls.__name__} " - f"without implementation of abstract method {name}") - subclass_value = cls.__dict__[name] - if (isinstance(value, (staticmethod, classmethod)) and - not isinstance(subclass_value, type(value))): - raise TypeError(f"Abstract {type(value).__name__} {name} in {cls.__name__} " - f"must be implemented as a {type(value).__name__}") - - def __new__(cls, *args, **kwargs): - if cls is Store_Base: - raise TypeError("Can't instantiate abstract class Store_Base directly") - return super().__new__(cls) - - def __repr__(self): - pass + FLAG_PERMUTATIONS: ClassVar[str] = 'permutations' + FLAG_PRIORITY: ClassVar[str] = 'priority' + FLAG_ROWS: ClassVar[str] = 'rows' + FLAG_VARIATION_TREES: ClassVar[str] = 'variation_trees' @classmethod - def from_json(cls, json): - pass - def to_json(self): - pass - + def output_bool(cls, value): + return av.input_bool(value, f'{cls.__name__} bool attribute', f'{cls.__name__}.output_bool') + @staticmethod + def convert_list_objects_to_list_options(objects): + return [object.to_json_option() for object in objects] diff --git a/business_objects/store/stripe.py b/business_objects/store/stripe.py index 96eac17e..4dc17f7b 100644 --- a/business_objects/store/stripe.py +++ b/business_objects/store/stripe.py @@ -153,7 +153,7 @@ class Stripe_Product(db.Model): delivery_options: {self.delivery_options} ''' - def add_discount(self, discount): + def add_product_price_discount(self, discount): _m = 'Category.add_product' av.val_instance(discount, 'discount', _m, Discount) # self.product_index.append(len(self.products)) diff --git a/business_objects/user.py b/business_objects/user.py index dfdf5b4d..a55331ca 100644 --- a/business_objects/user.py +++ b/business_objects/user.py @@ -160,7 +160,7 @@ class User_Filters(): @staticmethod def from_form(form): av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_User) - get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form") + get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form") id_user = form.id_user.data return User_Filters( get_all_user = (id_user is None), @@ -212,7 +212,7 @@ class User_Filters(): @staticmethod def from_form(form): av.val_instance(form, 'form', 'User_Filters.from_form', Form_Filters_User) - get_inactive = av.input_bool(form.active_only.data, "active_only", "User_Filters.from_form") + get_inactive = av.input_bool(form.active.data, "active", "User_Filters.from_form") return User_Filters( ids_user = form.id_user.data, get_inactive_users = get_inactive, diff --git a/datastores/__pycache__/datastore_base.cpython-312.pyc b/datastores/__pycache__/datastore_base.cpython-312.pyc index ef2af9b1..60f70209 100644 Binary files a/datastores/__pycache__/datastore_base.cpython-312.pyc and b/datastores/__pycache__/datastore_base.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_store_base.cpython-312.pyc b/datastores/__pycache__/datastore_store_base.cpython-312.pyc index e6b24b8d..d4134262 100644 Binary files a/datastores/__pycache__/datastore_store_base.cpython-312.pyc and b/datastores/__pycache__/datastore_store_base.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_store_basket.cpython-312.pyc b/datastores/__pycache__/datastore_store_basket.cpython-312.pyc index 6a6a9abe..850a0869 100644 Binary files a/datastores/__pycache__/datastore_store_basket.cpython-312.pyc and b/datastores/__pycache__/datastore_store_basket.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc b/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc index 411ea097..8403f80c 100644 Binary files a/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc and b/datastores/__pycache__/datastore_store_product_category.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc b/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc index d27577e9..09b2f8a4 100644 Binary files a/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc and b/datastores/__pycache__/datastore_store_product_permutation.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc b/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc index d6514b5f..6a415a29 100644 Binary files a/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc and b/datastores/__pycache__/datastore_store_stock_item.cpython-312.pyc differ diff --git a/datastores/__pycache__/datastore_user.cpython-312.pyc b/datastores/__pycache__/datastore_user.cpython-312.pyc index 566505f6..4835f896 100644 Binary files a/datastores/__pycache__/datastore_user.cpython-312.pyc and b/datastores/__pycache__/datastore_user.cpython-312.pyc differ diff --git a/datastores/datastore_base.py b/datastores/datastore_base.py index cb41c322..c316a45c 100644 --- a/datastores/datastore_base.py +++ b/datastores/datastore_base.py @@ -13,8 +13,9 @@ Datastore for Store # internal # from routes import bp_home import lib.argument_validation as av +from business_objects.store.access_level import Access_Level, Filters_Access_Level from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -26,7 +27,7 @@ from business_objects.sql_error import SQL_Error from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external @@ -164,17 +165,52 @@ class DataStore_Base(BaseModel): def get_user_auth0(): return User.from_json_auth0(session.get(current_app.config['ID_TOKEN_USER'])) @staticmethod - def upload_bulk(objects, objectType, batch_size): + def upload_bulk(permanent_table_name, records, batch_size): _m = 'DataStore_Base.upload_bulk' print(f'{_m}\nstarting...') try: - for i in range(0, len(objects), batch_size): - batch = objects[i:i+batch_size] + for i in range(0, len(records), batch_size): + batch = records[i:i+batch_size] data = [object.to_json() for object in batch] print(f'batch: {batch}\ndata: {data}') - db.session.bulk_insert_mappings(objectType, data) + db.session.bulk_insert_mappings(permanent_table_name, data) db.session.commit() except Exception as e: print(f'{_m}\n{e}') db.session.rollback() - raise e \ No newline at end of file + raise e + @classmethod + def get_many_access_level(cls, filters): + _m = 'DataStore_Store_Base.get_many_access_level' + av.val_instance(filters, 'filters', _m, Filters_Access_Level) + argument_dict = filters.to_json() + # user = cls.get_user_session() + # argument_dict['a_id_user'] = 1 # 'auth0|6582b95c895d09a70ba10fef' # id_user + print(f'argument_dict: {argument_dict}') + print('executing p_shop_get_many_access_level') + result = cls.db_procedure_execute('p_shop_get_many_access_level', argument_dict) + cursor = result.cursor + print('data received') + + # access_levels + result_set_1 = cursor.fetchall() + print(f'raw access levels: {result_set_1}') + access_levels = [] + for row in result_set_1: + new_access_level = Access_Level.from_DB_access_level(row) + access_levels.append(new_access_level) + + # Errors + cursor.nextset() + result_set_e = cursor.fetchall() + print(f'raw errors: {result_set_e}') + errors = [] + if len(result_set_e) > 0: + errors = [SQL_Error.from_DB_record(row) for row in result_set_e] # (row[0], row[1]) + for error in errors: + print(f"Error [{error.code}]: {error.msg}") + + DataStore_Base.db_cursor_clear(cursor) + cursor.close() + + return access_levels, errors \ No newline at end of file diff --git a/datastores/datastore_store_base.py b/datastores/datastore_store_base.py index ba31acf1..352856cf 100644 --- a/datastores/datastore_store_base.py +++ b/datastores/datastore_store_base.py @@ -13,8 +13,9 @@ Datastore for Store # internal # from routes import bp_home import lib.argument_validation as av +# from business_objects.store.access_level import Access_Level, Filters_Access_Level from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +28,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_base import DataStore_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external @@ -69,7 +70,7 @@ class DataStore_Store_Base(DataStore_Base): print('data received') - category_list = Container_Product_Category() + category_list = Product_Category_Container() # Categories result_set_1 = cursor.fetchall() print(f'raw categories: {result_set_1}') @@ -77,10 +78,10 @@ class DataStore_Store_Base(DataStore_Base): # categories = [] # category_index = {} for row in result_set_1: - new_category = Product_Category.from_DB_product(row) # Product_Category(row[0], row[1], row[2], row[3]) + new_category = Product_Category.from_DB_get_many_product_catalogue(row) # Product_Category(row[0], row[1], row[2], row[3]) # category_index[new_category.id_category] = len(categories) # categories.append(new_category) - category_list.add_category(new_category) + category_list.add_product_category(new_category) # print(f'categories: {[c.id_category for c in categories]}') # Products @@ -90,7 +91,7 @@ class DataStore_Store_Base(DataStore_Base): # products = [] # [Product(**row) for row in result_set_2] # product_index = {} for row in result_set_2: - new_product = Product.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) + new_product = Product.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) index_category = category_list.get_index_category_from_id(new_product.id_category) category = category_list.categories[index_category] category_list.add_product(new_product) @@ -104,10 +105,10 @@ class DataStore_Store_Base(DataStore_Base): permutations = [] # [Product(**row) for row in result_set_2] # permutation_index = {} for row in result_set_3: - new_permutation = Product_Permutation.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) + new_permutation = Product_Permutation.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9], row[10], row[11], row[12], row[13], row[14], row[15], row[16], row[17], row[18], row[19]) index_category = category_list.get_index_category_from_id(new_permutation.id_category) category = category_list.categories[index_category] - category_list.add_permutation(new_permutation) + category_list.add_product_permutation(new_permutation) print(f'category_list: {category_list}') # Product_Variations @@ -117,13 +118,13 @@ class DataStore_Store_Base(DataStore_Base): # variations = [Product_Variation(**row) for row in result_set_4] variations = [] for row in result_set_4: - new_variation = Product_Variation.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) + new_variation = Product_Variation.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]) variations.append(new_variation) # products[product_index[new_variation.id_product]].variations.append(new_variation) # index_category = category_index[new_variation.id_category] # index_product = categories[index_category].index_product_from_ids_product_permutation(new_variation.id_product, new_variation.id_permutation) # categories[index_category].products[index_product].variations.append(new_variation) - category_list.add_variation(new_variation) + category_list.add_product_variation(new_variation) # print(f'variations: {variations}') # print(f'products: {[p.id_product for p in products]}') @@ -134,7 +135,7 @@ class DataStore_Store_Base(DataStore_Base): # images = [Image(**row) for row in result_set_5] images = [] for row in result_set_5: - new_image = Image.from_DB_product(row) # (row[0], row[1], row[2], row[3], row[4]) + new_image = Image.from_DB_get_many_product_catalogue(row) # (row[0], row[1], row[2], row[3], row[4]) images.append(new_image) # products[product_index[new_image.id_product]].images.append(new_image) """ @@ -142,7 +143,7 @@ class DataStore_Store_Base(DataStore_Base): index_product = categories[index_category].index_product_from_ids_product_permutation(new_image.id_product, new_image.id_permutation) categories[index_category].products[index_product].images.append(new_image) """ - category_list.add_image(new_image) + category_list.add_product_image(new_image) # print(f'images: {images}') # print(f'products: {[p.id_product for p in products]}') @@ -156,7 +157,7 @@ class DataStore_Store_Base(DataStore_Base): for error in errors: print(f"Error [{error.code}]: {error.msg}") - category_list.get_all_variation_trees() + category_list.get_all_product_variation_trees() """ for category in category_list.categories: print(f'category: {category.name}') @@ -283,7 +284,7 @@ class DataStore_Store_Base(DataStore_Base): variations = Product_Variation_List() for row in result_set: new_variation = Product_Variation.from_DB_variation(row) - variations.add_variation(new_variation) + variations.add_product_variation(new_variation) errors = [] cursor.nextset() @@ -298,4 +299,5 @@ class DataStore_Store_Base(DataStore_Base): cursor.close() - return variations, errors \ No newline at end of file + return variations, errors + \ No newline at end of file diff --git a/datastores/datastore_store_basket.py b/datastores/datastore_store_basket.py index 4147a85c..b4b31a3b 100644 --- a/datastores/datastore_store_basket.py +++ b/datastores/datastore_store_basket.py @@ -14,7 +14,7 @@ Datastore for Store Baskets # from routes import bp_home import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_store_base import DataStore_Store_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external diff --git a/datastores/datastore_store_product.py b/datastores/datastore_store_product.py new file mode 100644 index 00000000..86b18e1e --- /dev/null +++ b/datastores/datastore_store_product.py @@ -0,0 +1,129 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: DataStores +Feature: Store Product DataStore + +Description: +Datastore for Store Products +""" + +# internal +import lib.argument_validation as av +from business_objects.store.basket import Basket, Basket_Item +from business_objects.store.product_category import Product_Category_Container, Product_Category +from business_objects.store.currency import Currency +from business_objects.store.image import Image +from business_objects.store.delivery_option import Delivery_Option +from business_objects.store.delivery_region import Delivery_Region +from business_objects.store.discount import Discount +from business_objects.store.order import Order +from business_objects.store.product import Product, Product_Permutation, Product_Price, Filters_Product +from business_objects.sql_error import SQL_Error +from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters +from business_objects.user import User, User_Filters, User_Permission_Evaluation +from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List +# from datastores.datastore_base import Table_Shop_Product_Category, Table_Shop_Product_Category_Temp +from datastores.datastore_store_base import DataStore_Store_Base +from helpers.helper_db_mysql import Helper_DB_MySQL +# from models.model_view_store_checkout import Model_View_Store_Checkout # circular! +from extensions import db +# external +# from abc import ABC, abstractmethod, abstractproperty +from flask_sqlalchemy import SQLAlchemy +from sqlalchemy import text +import stripe +import os +from flask import Flask, session, current_app +from pydantic import BaseModel, ConfigDict +from typing import ClassVar +from datetime import datetime + +# db = SQLAlchemy() + +""" +class Table_Shop_Product_Category(db.Model): + __tablename__ = 'Shop_Product_Category' + id_category: int = db.Column(db.Integer, primary_key=True) + code: str = db.Column(db.String(50)) + name: str = db.Column(db.String(255)) + description: str = db.Column(db.String(4000)) + active: bool = db.Column(db.Boolean) + display_order: int = db.Column(db.Integer) + created_on: datetime = db.Column(db.DateTime) + created_by: int = db.Column(db.Integer) + id_change_set: int = db.Column(db.Integer) +""" +class Row_Shop_Product_Temp(db.Model): + __tablename__ = 'Shop_Product_Temp' + __table_args__ = { 'extend_existing': True } + id_product: int = db.Column(db.Integer, primary_key=True) + id_category: int = db.Column(db.Integer) + name: str = db.Column(db.String(50)) + has_variations: str = db.Column(db.String(255)) + id_access_level_required: int = db.Column(db.Integer) + active: bool = db.Column(db.Boolean) + display_order: int = db.Column(db.Integer) + guid: str = db.Column(db.BINARY(36)) + + @classmethod + def from_product(cls, product): + row = cls() + row.id_product = product.id_product[0] if isinstance(product.id_product, tuple) else product.id_product + row.id_category = product.id_category[0] if isinstance(product.id_category, tuple) else product.id_category + row.name = product.name[0] if isinstance(product.name, tuple) else product.name + row.id_access_level_required = product.id_access_level_required[0] if isinstance(product.id_access_level_required, tuple) else product.id_access_level_required + row.active = product.active + row.display_order = product.display_order + return row + def to_json(self): + return { + 'id_category': self.id_category, + 'name': self.name, + 'id_access_level_required': self.id_access_level_required, + 'active': self.active, + 'display_order': self.display_order, + 'guid': self.guid, + } + + +class DataStore_Store_Product(DataStore_Store_Base): + def __init__(self): + super().__init__() + @classmethod + def save_categories(cls, comment, categories): + _m = 'DataStore_Store_Product_Category.save_categories' + print(f'{_m}\nstarting...') + print(f'comment: {comment}\ncategories: {categories}') + # av.val_str(comment, 'comment', _m) + # av.val_list_instances(categories, 'categories', _m, Product_Category, 1) + + guid = Helper_DB_MySQL.create_guid() + user = cls.get_user_session() + rows = [] + id_category_new = 0 + for category in categories: + row = Row_Shop_Product_Temp.from_product(category) + if row.id_category == '': + id_category_new -= 1 + row.id_category = id_category_new + else: + print(f'row.id_category: {row.id_category}') + row.guid = guid + rows.append(row) + + print(f'rows: {rows}') + + DataStore_Store_Base.upload_bulk(rows, Row_Shop_Product_Temp, 1000) + + argument_dict_list = { + 'a_id_user': user.id_user, + 'a_guid': guid, + 'a_comment': comment, + } + save_result = cls.db_procedure_execute('p_shop_save_product', argument_dict_list) + save_result.close() + print('save procedure executed') + diff --git a/datastores/datastore_store_product_category.py b/datastores/datastore_store_product_category.py index fe65a4e9..2c057cb0 100644 --- a/datastores/datastore_store_product_category.py +++ b/datastores/datastore_store_product_category.py @@ -13,7 +13,7 @@ Datastore for Store Product Categories # internal import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -63,11 +63,12 @@ class Row_Shop_Product_Category_Temp(db.Model): code: str = db.Column(db.String(50)) name: str = db.Column(db.String(255)) description: str = db.Column(db.String(4000)) + id_access_level_required: int = db.Column(db.Integer) active: bool = db.Column(db.Boolean) display_order: int = db.Column(db.Integer) guid: str = db.Column(db.BINARY(36)) - created_on: datetime = db.Column(db.DateTime) - created_by: int = db.Column(db.Integer) + # created_on: datetime = db.Column(db.DateTime) + # created_by: int = db.Column(db.Integer) @classmethod def from_product_category(cls, product_category): @@ -76,6 +77,7 @@ class Row_Shop_Product_Category_Temp(db.Model): row.code = product_category.code[0] if isinstance(product_category.code, tuple) else product_category.code row.name = product_category.name[0] if isinstance(product_category.name, tuple) else product_category.name row.description = product_category.description[0] if isinstance(product_category.description, tuple) else product_category.description + row.id_access_level_required = product_category.id_access_level_required[0] if isinstance(product_category.id_access_level_required, tuple) else product_category.id_access_level_required row.active = product_category.active row.display_order = product_category.display_order """ @@ -90,12 +92,15 @@ class Row_Shop_Product_Category_Temp(db.Model): 'code': self.code, 'name': self.name, 'description': self.description, + 'id_access_level_required': self.id_access_level_required, 'active': self.active, 'display_order': self.display_order, 'guid': self.guid, - 'created_on': self.created_on, - 'created_by': self.created_by } + """ + 'created_on': self.created_on, + 'created_by': self.created_by + """ class DataStore_Store_Product_Category(DataStore_Store_Base): @@ -115,7 +120,8 @@ class DataStore_Store_Product_Category(DataStore_Store_Base): rows = [] id_category_new = 0 for category in categories: - row = Row_Shop_Product_Category_Temp.from_product_category(category) + # row = Row_Shop_Product_Category_Temp.from_product_category(category) + row = category.to_temporary_record() # id_tmp = if row.id_category == '': id_category_new -= 1 @@ -123,8 +129,8 @@ class DataStore_Store_Product_Category(DataStore_Store_Base): else: print(f'row.id_category: {row.id_category}') row.guid = guid - row.created_on = now - row.created_by = user.id_user + # row.created_on = now + # row.created_by = user.id_user rows.append(row) print(f'rows: {rows}') @@ -141,7 +147,7 @@ class DataStore_Store_Product_Category(DataStore_Store_Base): cursor.close() print('cursor closed') """ - DataStore_Store_Base.upload_bulk(rows, Row_Shop_Product_Category_Temp, 1000) + DataStore_Store_Base.upload_bulk(rows, Product_Category.__tablename__, 1000) argument_dict_list = { 'a_id_user': user.id_user, diff --git a/datastores/datastore_store_product_permutation.py b/datastores/datastore_store_product_permutation.py index d1e0186b..65b32361 100644 --- a/datastores/datastore_store_product_permutation.py +++ b/datastores/datastore_store_product_permutation.py @@ -13,7 +13,7 @@ Datastore for Store Product Permutations # internal import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -26,7 +26,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_store_base import DataStore_Store_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external diff --git a/datastores/datastore_store_product_variation.py b/datastores/datastore_store_product_variation.py index 84a68a78..6575a7e7 100644 --- a/datastores/datastore_store_product_variation.py +++ b/datastores/datastore_store_product_variation.py @@ -14,7 +14,7 @@ Datastore for Store Product Variations # from routes import bp_home import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_store_base import DataStore_Store_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external @@ -83,7 +83,7 @@ class DataStore_Store_Product_Variation(DataStore_Store_Base): variations = Product_Variation_List() for row in result_set: new_variation = Product_Variation.from_DB_variation(row) - variations.add_variation(new_variation) + variations.add_product_variation(new_variation) errors = [] cursor.nextset() diff --git a/datastores/datastore_store_stock_item.py b/datastores/datastore_store_stock_item.py index da5798a0..53318b99 100644 --- a/datastores/datastore_store_stock_item.py +++ b/datastores/datastore_store_stock_item.py @@ -14,7 +14,7 @@ Datastore for Store Stock Items # from routes import bp_home import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_store_base import DataStore_Store_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external @@ -73,7 +73,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): def input_many_stock_item(cursor): _m = 'DataStore_Store_Stock_Item.input_many_stock_item' - category_list = Container_Product_Category() + category_list = Product_Category_Container() # Categories result_set_1 = cursor.fetchall() print(f'raw categories: {result_set_1}') @@ -95,12 +95,12 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): except KeyError: permutation = Product_Permutation.from_DB_stock_item(row) permutation.add_stock_item(new_stock_item) - product.add_permutation(permutation) + product.add_product_permutation(permutation) except KeyError: product = Product.from_DB_stock_item(row) permutation = Product_Permutation.from_DB_stock_item(row) permutation.add_stock_item(new_stock_item) - product.add_permutation(permutation) + product.add_product_permutation(permutation) category_list.add_product(product) """ except KeyError: @@ -109,10 +109,10 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): product = Product.from_DB_stock_item(row) permutation = Product_Permutation.from_DB_stock_item(row) permutation.add_stock_item(new_stock_item) - product.add_permutation(permutation) + product.add_product_permutation(permutation) new_category.add_product(product) """ - category_list.add_category(new_category) + category_list.add_product_category(new_category) try: index_product = category.get_index_product_from_id(new_stock_item.id_product) product = category.products[index_product] @@ -125,7 +125,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): permutation.add_stock_item(new_stock_item) except KeyError: new_permutation = Product_Permutation.from_DB_stock_item(row) - product.add_permutation(new_permutation) + product.add_product_permutation(new_permutation) category_list.add_stock_item(new_stock_item) # Product_Variations @@ -133,9 +133,9 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): result_set_3 = cursor.fetchall() variations = [] for row in result_set_3: - new_variation = Product_Variation.from_DB_product(row) + new_variation = Product_Variation.from_DB_get_many_product_catalogue(row) variations.append(new_variation) - category_list.add_variation(new_variation) + category_list.add_product_variation(new_variation) # Errors cursor.nextset() @@ -147,7 +147,7 @@ class DataStore_Store_Stock_Item(DataStore_Store_Base): for error in errors: print(f"Error [{error.code}]: {error.msg}") - category_list.get_all_variation_trees() + category_list.get_all_product_variation_trees() """ for category in category_list.categories: print(f'category: {category.name}') diff --git a/datastores/datastore_store_stripe.py b/datastores/datastore_store_stripe.py index 8784af40..6cc1942c 100644 --- a/datastores/datastore_store_stripe.py +++ b/datastores/datastore_store_stripe.py @@ -14,7 +14,7 @@ Datastore for Store Stripe service # from routes import bp_home import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_store_base import DataStore_Store_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external diff --git a/datastores/datastore_user.py b/datastores/datastore_user.py index cad8e648..39fe4c0f 100644 --- a/datastores/datastore_user.py +++ b/datastores/datastore_user.py @@ -14,7 +14,7 @@ Datastore for Users # from routes import bp_home import lib.argument_validation as av from business_objects.store.basket import Basket, Basket_Item -from business_objects.store.product_category import Container_Product_Category, Product_Category +from business_objects.store.product_category import Product_Category_Container, Product_Category from business_objects.store.currency import Currency from business_objects.store.image import Image from business_objects.store.delivery_option import Delivery_Option @@ -27,7 +27,7 @@ from business_objects.store.stock_item import Stock_Item, Stock_Item_Filters from business_objects.user import User, User_Filters, User_Permission_Evaluation from business_objects.store.product_variation import Product_Variation, Product_Variation_Filters, Product_Variation_List from datastores.datastore_base import DataStore_Base -from helpers.helper_db_mysql import Helper_DB_MySQL +# from helpers.helper_db_mysql import Helper_DB_MySQL # from models.model_view_store_checkout import Model_View_Store_Checkout # circular! from extensions import db # external diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/INSTALLER b/env_web/Lib/site-packages/pip-23.0.1.dist-info/INSTALLER new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/LICENSE.txt b/env_web/Lib/site-packages/pip-23.0.1.dist-info/LICENSE.txt new file mode 100644 index 00000000..8e7b65ea --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-present The pip developers (see AUTHORS.txt file) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/METADATA b/env_web/Lib/site-packages/pip-23.0.1.dist-info/METADATA new file mode 100644 index 00000000..984f9ad3 --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/METADATA @@ -0,0 +1,88 @@ +Metadata-Version: 2.1 +Name: pip +Version: 23.0.1 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: distutils-sig@python.org +License: MIT +Project-URL: Documentation, https://pip.pypa.io +Project-URL: Source, https://github.com/pypa/pip +Project-URL: Changelog, https://pip.pypa.io/en/stable/news/ +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=3.7 +License-File: LICENSE.txt + +pip - The Python Package Installer +================================== + +.. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + +.. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + +pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. + +Please take a look at our documentation for how to install and use pip: + +* `Installation`_ +* `Usage`_ + +We release updates regularly, with a new version every 3 months. Find more details in our documentation: + +* `Release notes`_ +* `Release process`_ + +In pip 20.3, we've `made a big improvement to the heart of pip`_; `learn more`_. We want your input, so `sign up for our user experience research studies`_ to help us do it right. + +**Note**: pip 21.0, in January 2021, removed Python 2 support, per pip's `Python 2 support policy`_. Please migrate to Python 3. + +If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms: + +* `Issue tracking`_ +* `Discourse channel`_ +* `User IRC`_ + +If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: + +* `GitHub page`_ +* `Development documentation`_ +* `Development IRC`_ + +Code of Conduct +--------------- + +Everyone interacting in the pip project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. + +.. _package installer: https://packaging.python.org/guides/tool-recommendations/ +.. _Python Package Index: https://pypi.org +.. _Installation: https://pip.pypa.io/en/stable/installation/ +.. _Usage: https://pip.pypa.io/en/stable/ +.. _Release notes: https://pip.pypa.io/en/stable/news.html +.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ +.. _GitHub page: https://github.com/pypa/pip +.. _Development documentation: https://pip.pypa.io/en/latest/development +.. _made a big improvement to the heart of pip: https://pyfound.blogspot.com/2020/11/pip-20-3-new-resolver.html +.. _learn more: https://pip.pypa.io/en/latest/user_guide/#changes-to-the-pip-dependency-resolver-in-20-3-2020 +.. _sign up for our user experience research studies: https://pyfound.blogspot.com/2020/03/new-pip-resolver-to-roll-out-this-year.html +.. _Python 2 support policy: https://pip.pypa.io/en/latest/development/release-process/#python-2-support +.. _Issue tracking: https://github.com/pypa/pip/issues +.. _Discourse channel: https://discuss.python.org/c/packaging +.. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa +.. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev +.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/RECORD b/env_web/Lib/site-packages/pip-23.0.1.dist-info/RECORD new file mode 100644 index 00000000..af445f64 --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/RECORD @@ -0,0 +1,1002 @@ +../../Scripts/pip.exe,sha256=QOekK_X69rprtL03MiCaIDDAHDnWj-uxU2pvwy9BF9Q,98226 +../../Scripts/pip3.8.exe,sha256=QOekK_X69rprtL03MiCaIDDAHDnWj-uxU2pvwy9BF9Q,98226 +../../Scripts/pip3.exe,sha256=QOekK_X69rprtL03MiCaIDDAHDnWj-uxU2pvwy9BF9Q,98226 +pip-23.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-23.0.1.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093 +pip-23.0.1.dist-info/METADATA,sha256=POh89utz-H1e0K-xDY9CL9gs-x0MjH-AWxbhJG3aaVE,4072 +pip-23.0.1.dist-info/RECORD,, +pip-23.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip-23.0.1.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92 +pip-23.0.1.dist-info/entry_points.txt,sha256=w694mjHYSfmSoUVVSaHoQ9UkOBBdtKKIJbyDRLdKju8,124 +pip-23.0.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip/__init__.py,sha256=5yroedzc2dKKbcynDrHX8vBoLxqU27KmFvvHmdqQN9w,357 +pip/__main__.py,sha256=mXwWDftNLMKfwVqKFWGE_uuBZvGSIiUELhLkeysIuZc,1198 +pip/__pip-runner__.py,sha256=EnrfKmKMzWAdqg_JicLCOP9Y95Ux7zHh4ObvqLtQcjo,1444 +pip/__pycache__/__init__.cpython-38.pyc,, +pip/__pycache__/__main__.cpython-38.pyc,, +pip/__pycache__/__pip-runner__.cpython-38.pyc,, +pip/_internal/__init__.py,sha256=nnFCuxrPMgALrIDxSoy-H6Zj4W4UY60D-uL1aJyq0pc,573 +pip/_internal/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/__pycache__/build_env.cpython-38.pyc,, +pip/_internal/__pycache__/cache.cpython-38.pyc,, +pip/_internal/__pycache__/configuration.cpython-38.pyc,, +pip/_internal/__pycache__/exceptions.cpython-38.pyc,, +pip/_internal/__pycache__/main.cpython-38.pyc,, +pip/_internal/__pycache__/pyproject.cpython-38.pyc,, +pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc,, +pip/_internal/__pycache__/wheel_builder.cpython-38.pyc,, +pip/_internal/build_env.py,sha256=1ESpqw0iupS_K7phZK5zshVE5Czy9BtGLFU4W6Enva8,10243 +pip/_internal/cache.py,sha256=C3n78VnBga9rjPXZqht_4A4d-T25poC7K0qBM7FHDhU,10734 +pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 +pip/_internal/cli/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc,, +pip/_internal/cli/__pycache__/base_command.cpython-38.pyc,, +pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc,, +pip/_internal/cli/__pycache__/command_context.cpython-38.pyc,, +pip/_internal/cli/__pycache__/main.cpython-38.pyc,, +pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc,, +pip/_internal/cli/__pycache__/parser.cpython-38.pyc,, +pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc,, +pip/_internal/cli/__pycache__/req_command.cpython-38.pyc,, +pip/_internal/cli/__pycache__/spinners.cpython-38.pyc,, +pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc,, +pip/_internal/cli/autocompletion.py,sha256=wY2JPZY2Eji1vhR7bVo-yCBPJ9LCy6P80iOAhZD1Vi8,6676 +pip/_internal/cli/base_command.py,sha256=t1D5x40Hfn9HnPnMt-iSxvqL14nht2olBCacW74pc-k,7842 +pip/_internal/cli/cmdoptions.py,sha256=0OHXkgnppCtC4QyF28ZL8FBosVUXG5pWj2uzO1CgWhM,29497 +pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774 +pip/_internal/cli/main.py,sha256=ioJ8IVlb2K1qLOxR-tXkee9lURhYV89CDM71MKag7YY,2472 +pip/_internal/cli/main_parser.py,sha256=laDpsuBDl6kyfywp9eMMA9s84jfH2TJJn-vmL0GG90w,4338 +pip/_internal/cli/parser.py,sha256=tWP-K1uSxnJyXu3WE0kkH3niAYRBeuUaxeydhzOdhL4,10817 +pip/_internal/cli/progress_bars.py,sha256=So4mPoSjXkXiSHiTzzquH3VVyVD_njXlHJSExYPXAow,1968 +pip/_internal/cli/req_command.py,sha256=ypTutLv4j_efxC2f6C6aCQufxre-zaJdi5m_tWlLeBk,18172 +pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118 +pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116 +pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882 +pip/_internal/commands/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/commands/__pycache__/cache.cpython-38.pyc,, +pip/_internal/commands/__pycache__/check.cpython-38.pyc,, +pip/_internal/commands/__pycache__/completion.cpython-38.pyc,, +pip/_internal/commands/__pycache__/configuration.cpython-38.pyc,, +pip/_internal/commands/__pycache__/debug.cpython-38.pyc,, +pip/_internal/commands/__pycache__/download.cpython-38.pyc,, +pip/_internal/commands/__pycache__/freeze.cpython-38.pyc,, +pip/_internal/commands/__pycache__/hash.cpython-38.pyc,, +pip/_internal/commands/__pycache__/help.cpython-38.pyc,, +pip/_internal/commands/__pycache__/index.cpython-38.pyc,, +pip/_internal/commands/__pycache__/inspect.cpython-38.pyc,, +pip/_internal/commands/__pycache__/install.cpython-38.pyc,, +pip/_internal/commands/__pycache__/list.cpython-38.pyc,, +pip/_internal/commands/__pycache__/search.cpython-38.pyc,, +pip/_internal/commands/__pycache__/show.cpython-38.pyc,, +pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc,, +pip/_internal/commands/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/commands/cache.py,sha256=muaT0mbL-ZUpn6AaushVAipzTiMwE4nV2BLbJBwt_KQ,7582 +pip/_internal/commands/check.py,sha256=0gjXR7j36xJT5cs2heYU_dfOfpnFfzX8OoPNNoKhqdM,1685 +pip/_internal/commands/completion.py,sha256=H0TJvGrdsoleuIyQKzJbicLFppYx2OZA0BLNpQDeFjI,4129 +pip/_internal/commands/configuration.py,sha256=NB5uf8HIX8-li95YLoZO09nALIWlLCHDF5aifSKcBn8,9815 +pip/_internal/commands/debug.py,sha256=AesEID-4gPFDWTwPiPaGZuD4twdT-imaGuMR5ZfSn8s,6591 +pip/_internal/commands/download.py,sha256=LwKEyYMG2L67nQRyGo8hQdNEeMU2bmGWqJfcB8JDXas,5289 +pip/_internal/commands/freeze.py,sha256=gCjoD6foBZPBAAYx5t8zZLkJhsF_ZRtnb3dPuD7beO8,2951 +pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703 +pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132 +pip/_internal/commands/index.py,sha256=cGQVSA5dAs7caQ9sz4kllYvaI4ZpGiq1WhCgaImXNSA,4793 +pip/_internal/commands/inspect.py,sha256=2wSPt9yfr3r6g-s2S5L6PvRtaHNVyb4TuodMStJ39cw,3188 +pip/_internal/commands/install.py,sha256=3vT9tnHOV-p6dPMaKDqzivqmcq_kPAI-jVkxOEwN5C4,32389 +pip/_internal/commands/list.py,sha256=Fk1TSxB33NlRS4qlLQ0xwnytnF9-zkQJbKQYv2xc4Q4,12343 +pip/_internal/commands/search.py,sha256=sbBZiARRc050QquOKcCvOr2K3XLsoYebLKZGRi__iUI,5697 +pip/_internal/commands/show.py,sha256=t5jia4zcYJRJZy4U_Von7zMl03hJmmcofj6oDNTnj7Y,6419 +pip/_internal/commands/uninstall.py,sha256=OIqO9tqadY8kM4HwhFf1Q62fUIp7v8KDrTRo8yWMz7Y,3886 +pip/_internal/commands/wheel.py,sha256=mbFJd4dmUfrVFJkQbK8n2zHyRcD3AI91f7EUo9l3KYg,7396 +pip/_internal/configuration.py,sha256=uBKTus43pDIO6IzT2mLWQeROmHhtnoabhniKNjPYvD0,13529 +pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858 +pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/distributions/__pycache__/base.cpython-38.pyc,, +pip/_internal/distributions/__pycache__/installed.cpython-38.pyc,, +pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc,, +pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/distributions/base.py,sha256=jrF1Vi7eGyqFqMHrieh1PIOrGU7KeCxhYPZnbvtmvGY,1221 +pip/_internal/distributions/installed.py,sha256=NI2OgsgH9iBq9l5vB-56vOg5YsybOy-AU4VE5CSCO2I,729 +pip/_internal/distributions/sdist.py,sha256=SQBdkatXSigKGG_SaD0U0p1Jwdfrg26UCNcHgkXZfdA,6494 +pip/_internal/distributions/wheel.py,sha256=m-J4XO-gvFerlYsFzzSXYDvrx8tLZlJFTCgDxctn8ig,1164 +pip/_internal/exceptions.py,sha256=cU4dz7x-1uFGrf2A1_Np9tKcy599bRJKRJkikgARxW4,24244 +pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30 +pip/_internal/index/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/index/__pycache__/collector.cpython-38.pyc,, +pip/_internal/index/__pycache__/package_finder.cpython-38.pyc,, +pip/_internal/index/__pycache__/sources.cpython-38.pyc,, +pip/_internal/index/collector.py,sha256=3OmYZ3tCoRPGOrELSgQWG-03M-bQHa2-VCA3R_nJAaU,16504 +pip/_internal/index/package_finder.py,sha256=rrUw4vj7QE_eMt022jw--wQiKznMaUgVBkJ1UCrVUxo,37873 +pip/_internal/index/sources.py,sha256=SVyPitv08-Qalh2_Bk5diAJ9GAA_d-a93koouQodAG0,6557 +pip/_internal/locations/__init__.py,sha256=Dh8LJWG8LRlDK4JIj9sfRF96TREzE--N_AIlx7Tqoe4,15365 +pip/_internal/locations/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/locations/__pycache__/_distutils.cpython-38.pyc,, +pip/_internal/locations/__pycache__/_sysconfig.cpython-38.pyc,, +pip/_internal/locations/__pycache__/base.cpython-38.pyc,, +pip/_internal/locations/_distutils.py,sha256=cmi6h63xYNXhQe7KEWEMaANjHFy5yQOPt_1_RCWyXMY,6100 +pip/_internal/locations/_sysconfig.py,sha256=jyNVtUfMIf0mtyY-Xp1m9yQ8iwECozSVVFmjkN9a2yw,7680 +pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556 +pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340 +pip/_internal/metadata/__init__.py,sha256=84j1dPJaIoz5Q2ZTPi0uB1iaDAHiUNfKtYSGQCfFKpo,4280 +pip/_internal/metadata/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/metadata/__pycache__/_json.cpython-38.pyc,, +pip/_internal/metadata/__pycache__/base.cpython-38.pyc,, +pip/_internal/metadata/__pycache__/pkg_resources.cpython-38.pyc,, +pip/_internal/metadata/_json.py,sha256=BTkWfFDrWFwuSodImjtbAh8wCL3isecbnjTb5E6UUDI,2595 +pip/_internal/metadata/base.py,sha256=vIwIo1BtoqegehWMAXhNrpLGYBq245rcaCNkBMPnTU8,25277 +pip/_internal/metadata/importlib/__init__.py,sha256=9ZVO8BoE7NEZPmoHp5Ap_NJo0HgNIezXXg-TFTtt3Z4,107 +pip/_internal/metadata/importlib/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/metadata/importlib/__pycache__/_compat.cpython-38.pyc,, +pip/_internal/metadata/importlib/__pycache__/_dists.cpython-38.pyc,, +pip/_internal/metadata/importlib/__pycache__/_envs.cpython-38.pyc,, +pip/_internal/metadata/importlib/_compat.py,sha256=GAe_prIfCE4iUylrnr_2dJRlkkBVRUbOidEoID7LPoE,1882 +pip/_internal/metadata/importlib/_dists.py,sha256=BUV8y6D0PePZrEN3vfJL-m1FDqZ6YPRgAiBeBinHhNg,8181 +pip/_internal/metadata/importlib/_envs.py,sha256=7BxanCh3T7arusys__O2ZHJdnmDhQXFmfU7x1-jB5xI,7457 +pip/_internal/metadata/pkg_resources.py,sha256=WjwiNdRsvxqxL4MA5Tb5a_q3Q3sUhdpbZF8wGLtPMI0,9773 +pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 +pip/_internal/models/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/models/__pycache__/candidate.cpython-38.pyc,, +pip/_internal/models/__pycache__/direct_url.cpython-38.pyc,, +pip/_internal/models/__pycache__/format_control.cpython-38.pyc,, +pip/_internal/models/__pycache__/index.cpython-38.pyc,, +pip/_internal/models/__pycache__/installation_report.cpython-38.pyc,, +pip/_internal/models/__pycache__/link.cpython-38.pyc,, +pip/_internal/models/__pycache__/scheme.cpython-38.pyc,, +pip/_internal/models/__pycache__/search_scope.cpython-38.pyc,, +pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc,, +pip/_internal/models/__pycache__/target_python.cpython-38.pyc,, +pip/_internal/models/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/models/candidate.py,sha256=6pcABsaR7CfIHlbJbr2_kMkVJFL_yrYjTx6SVWUnCPQ,990 +pip/_internal/models/direct_url.py,sha256=f3WiKUwWPdBkT1xm7DlolS32ZAMYh3jbkkVH-BUON5A,6626 +pip/_internal/models/format_control.py,sha256=DJpMYjxeYKKQdwNcML2_F0vtAh-qnKTYe-CpTxQe-4g,2520 +pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030 +pip/_internal/models/installation_report.py,sha256=Hymmzv9-e3WhtewYm2NIOeMyAB6lXp736mpYqb9scZ0,2617 +pip/_internal/models/link.py,sha256=nfybVSpXgVHeU0MkC8hMkN2IgMup8Pdaudg74_sQEC8,18602 +pip/_internal/models/scheme.py,sha256=3EFQp_ICu_shH1-TBqhl0QAusKCPDFOlgHFeN4XowWs,738 +pip/_internal/models/search_scope.py,sha256=iGPQQ6a4Lau8oGQ_FWj8aRLik8A21o03SMO5KnSt-Cg,4644 +pip/_internal/models/selection_prefs.py,sha256=KZdi66gsR-_RUXUr9uejssk3rmTHrQVJWeNA2sV-VSY,1907 +pip/_internal/models/target_python.py,sha256=qKpZox7J8NAaPmDs5C_aniwfPDxzvpkrCKqfwndG87k,3858 +pip/_internal/models/wheel.py,sha256=YqazoIZyma_Q1ejFa1C7NHKQRRWlvWkdK96VRKmDBeI,3600 +pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50 +pip/_internal/network/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/network/__pycache__/auth.cpython-38.pyc,, +pip/_internal/network/__pycache__/cache.cpython-38.pyc,, +pip/_internal/network/__pycache__/download.cpython-38.pyc,, +pip/_internal/network/__pycache__/lazy_wheel.cpython-38.pyc,, +pip/_internal/network/__pycache__/session.cpython-38.pyc,, +pip/_internal/network/__pycache__/utils.cpython-38.pyc,, +pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc,, +pip/_internal/network/auth.py,sha256=MQVP0k4hUXk8ReYEfsGQ5t7_TS7cNHQuaHJuBlJLHxU,16507 +pip/_internal/network/cache.py,sha256=hgXftU-eau4MWxHSLquTMzepYq5BPC2zhCkhN3glBy8,2145 +pip/_internal/network/download.py,sha256=HvDDq9bVqaN3jcS3DyVJHP7uTqFzbShdkf7NFSoHfkw,6096 +pip/_internal/network/lazy_wheel.py,sha256=PbPyuleNhtEq6b2S7rufoGXZWMD15FAGL4XeiAQ8FxA,7638 +pip/_internal/network/session.py,sha256=BpDOJ7_Xw5VkgPYWsePzcaqOfcyRZcB2AW7W0HGBST0,18443 +pip/_internal/network/utils.py,sha256=6A5SrUJEEUHxbGtbscwU2NpCyz-3ztiDlGWHpRRhsJ8,4073 +pip/_internal/network/xmlrpc.py,sha256=AzQgG4GgS152_cqmGr_Oz2MIXsCal-xfsis7fA7nmU0,1791 +pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/operations/__pycache__/check.cpython-38.pyc,, +pip/_internal/operations/__pycache__/freeze.cpython-38.pyc,, +pip/_internal/operations/__pycache__/prepare.cpython-38.pyc,, +pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/build_tracker.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/metadata_editable.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/wheel_editable.cpython-38.pyc,, +pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc,, +pip/_internal/operations/build/build_tracker.py,sha256=vf81EwomN3xe9G8qRJED0VGqNikmRQRQoobNsxi5Xrs,4133 +pip/_internal/operations/build/metadata.py,sha256=9S0CUD8U3QqZeXp-Zyt8HxwU90lE4QrnYDgrqZDzBnc,1422 +pip/_internal/operations/build/metadata_editable.py,sha256=VLL7LvntKE8qxdhUdEJhcotFzUsOSI8NNS043xULKew,1474 +pip/_internal/operations/build/metadata_legacy.py,sha256=o-eU21As175hDC7dluM1fJJ_FqokTIShyWpjKaIpHZw,2198 +pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075 +pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417 +pip/_internal/operations/build/wheel_legacy.py,sha256=C9j6rukgQI1n_JeQLoZGuDdfUwzCXShyIdPTp6edbMQ,3064 +pip/_internal/operations/check.py,sha256=WsN7z0_QSgJjw0JsWWcqOHj4wWTaFv0J7mxgUByDCOg,5122 +pip/_internal/operations/freeze.py,sha256=mwTZ2uML8aQgo3k8MR79a7SZmmmvdAJqdyaknKbavmg,9784 +pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51 +pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc,, +pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc,, +pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/operations/install/editable_legacy.py,sha256=ee4kfJHNuzTdKItbfAsNOSEwq_vD7DRPGkBdK48yBhU,1354 +pip/_internal/operations/install/legacy.py,sha256=cHdcHebyzf8w7OaOLwcsTNSMSSV8WBoAPFLay_9CjE8,4105 +pip/_internal/operations/install/wheel.py,sha256=CxzEg2wTPX4SxNTPIx0ozTqF1X7LhpCyP3iM2FjcKUE,27407 +pip/_internal/operations/prepare.py,sha256=BeYXrLFpRoV5XBnRXQHxRA2plyC36kK9Pms5D9wjCo4,25091 +pip/_internal/pyproject.py,sha256=QqSZR5AGwtf3HTa8NdbDq2yj9T2r9S2h9gnU4aX2Kvg,6987 +pip/_internal/req/__init__.py,sha256=rUQ9d_Sh3E5kNYqX9pkN0D06YL-LrtcbJQ-LiIonq08,2807 +pip/_internal/req/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/req/__pycache__/constructors.cpython-38.pyc,, +pip/_internal/req/__pycache__/req_file.cpython-38.pyc,, +pip/_internal/req/__pycache__/req_install.cpython-38.pyc,, +pip/_internal/req/__pycache__/req_set.cpython-38.pyc,, +pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc,, +pip/_internal/req/constructors.py,sha256=ypjtq1mOQ3d2mFkFPMf_6Mr8SLKeHQk3tUKHA1ddG0U,16611 +pip/_internal/req/req_file.py,sha256=N6lPO3c0to_G73YyGAnk7VUYmed5jV4Qxgmt1xtlXVg,17646 +pip/_internal/req/req_install.py,sha256=X4WNQlTtvkeATwWdSiJcNLihwbYI_EnGDgE99p-Aa00,35763 +pip/_internal/req/req_set.py,sha256=j3esG0s6SzoVReX9rWn4rpYNtyET_fwxbwJPRimvRxo,2858 +pip/_internal/req/req_uninstall.py,sha256=ZFQfgSNz6H1BMsgl87nQNr2iaQCcbFcmXpW8rKVQcic,24045 +pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/resolution/__pycache__/base.cpython-38.pyc,, +pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583 +pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc,, +pip/_internal/resolution/legacy/resolver.py,sha256=9em8D5TcSsEN4xZM1WreaRShOnyM4LlvhMSHpUPsocE,24129 +pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc,, +pip/_internal/resolution/resolvelib/base.py,sha256=u1O4fkvCO4mhmu5i32xrDv9AX5NgUci_eYVyBDQhTIM,5220 +pip/_internal/resolution/resolvelib/candidates.py,sha256=6kQZeMzwibnL4lO6bW0hUQQjNEvXfADdFphRRkRvOtc,18963 +pip/_internal/resolution/resolvelib/factory.py,sha256=OnjkLIgyk5Tol7uOOqapA1D4qiRHWmPU18DF1yN5N8o,27878 +pip/_internal/resolution/resolvelib/found_candidates.py,sha256=hvL3Hoa9VaYo-qEOZkBi2Iqw251UDxPz-uMHVaWmLpE,5705 +pip/_internal/resolution/resolvelib/provider.py,sha256=Vd4jW_NnyifB-HMkPYtZIO70M3_RM0MbL5YV6XyBM-w,9914 +pip/_internal/resolution/resolvelib/reporter.py,sha256=3ZVVYrs5PqvLFJkGLcuXoMK5mTInFzl31xjUpDBpZZk,2526 +pip/_internal/resolution/resolvelib/requirements.py,sha256=B1ndvKPSuyyyTEXt9sKhbwminViSWnBrJa7qO2ln4Z0,5455 +pip/_internal/resolution/resolvelib/resolver.py,sha256=nYZ9bTFXj5c1ILKnkSgU7tUCTYyo5V5J-J0sKoA7Wzg,11533 +pip/_internal/self_outdated_check.py,sha256=pnqBuKKZQ8OxKP0MaUUiDHl3AtyoMJHHG4rMQ7YcYXY,8167 +pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/utils/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/utils/__pycache__/_log.cpython-38.pyc,, +pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc,, +pip/_internal/utils/__pycache__/compat.cpython-38.pyc,, +pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc,, +pip/_internal/utils/__pycache__/datetime.cpython-38.pyc,, +pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc,, +pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc,, +pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc,, +pip/_internal/utils/__pycache__/egg_link.cpython-38.pyc,, +pip/_internal/utils/__pycache__/encoding.cpython-38.pyc,, +pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc,, +pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc,, +pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc,, +pip/_internal/utils/__pycache__/glibc.cpython-38.pyc,, +pip/_internal/utils/__pycache__/hashes.cpython-38.pyc,, +pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc,, +pip/_internal/utils/__pycache__/logging.cpython-38.pyc,, +pip/_internal/utils/__pycache__/misc.cpython-38.pyc,, +pip/_internal/utils/__pycache__/models.cpython-38.pyc,, +pip/_internal/utils/__pycache__/packaging.cpython-38.pyc,, +pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc,, +pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc,, +pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc,, +pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc,, +pip/_internal/utils/__pycache__/urls.cpython-38.pyc,, +pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc,, +pip/_internal/utils/__pycache__/wheel.cpython-38.pyc,, +pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015 +pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665 +pip/_internal/utils/compat.py,sha256=ACyBfLgj3_XG-iA5omEDrXqDM0cQKzi8h8HRBInzG6Q,1884 +pip/_internal/utils/compatibility_tags.py,sha256=ydin8QG8BHqYRsPY4OL6cmb44CbqXl1T0xxS97VhHkk,5377 +pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242 +pip/_internal/utils/deprecation.py,sha256=OLc7GzDwPob9y8jscDYCKUNBV-9CWwqFplBOJPLOpBM,5764 +pip/_internal/utils/direct_url_helpers.py,sha256=6F1tc2rcKaCZmgfVwsE6ObIe_Pux23mUVYA-2D9wCFc,3206 +pip/_internal/utils/distutils_args.py,sha256=bYUt4wfFJRaeGO4VHia6FNaA8HlYXMcKuEq1zYijY5g,1115 +pip/_internal/utils/egg_link.py,sha256=ZryCchR_yQSCsdsMkCpxQjjLbQxObA5GDtLG0RR5mGc,2118 +pip/_internal/utils/encoding.py,sha256=qqsXDtiwMIjXMEiIVSaOjwH5YmirCaK-dIzb6-XJsL0,1169 +pip/_internal/utils/entrypoints.py,sha256=YlhLTRl2oHBAuqhc-zmL7USS67TPWVHImjeAQHreZTQ,3064 +pip/_internal/utils/filesystem.py,sha256=RhMIXUaNVMGjc3rhsDahWQ4MavvEQDdqXqgq-F6fpw8,5122 +pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716 +pip/_internal/utils/glibc.py,sha256=tDfwVYnJCOC0BNVpItpy8CGLP9BjkxFHdl0mTS0J7fc,3110 +pip/_internal/utils/hashes.py,sha256=1WhkVNIHNfuYLafBHThIjVKGplxFJXSlQtuG2mXNlJI,4831 +pip/_internal/utils/inject_securetransport.py,sha256=o-QRVMGiENrTJxw3fAhA7uxpdEdw6M41TjHYtSVRrcg,795 +pip/_internal/utils/logging.py,sha256=U2q0i1n8hPS2gQh8qcocAg5dovGAa_bR24akmXMzrk4,11632 +pip/_internal/utils/misc.py,sha256=XLtMDOmy8mWiNLuPIhxPdO1bWIleLdN6JnWDZsXfTgE,22253 +pip/_internal/utils/models.py,sha256=5GoYU586SrxURMvDn_jBMJInitviJg4O5-iOU-6I0WY,1193 +pip/_internal/utils/packaging.py,sha256=5Wm6_x7lKrlqVjPI5MBN_RurcRHwVYoQ7Ksrs84de7s,2108 +pip/_internal/utils/setuptools_build.py,sha256=4i3CuS34yNrkePnZ73rR47pyDzpZBo-SX9V5PNDSSHY,5662 +pip/_internal/utils/subprocess.py,sha256=0EMhgfPGFk8FZn6Qq7Hp9PN6YHuQNWiVby4DXcTCON4,9200 +pip/_internal/utils/temp_dir.py,sha256=aCX489gRa4Nu0dMKRFyGhV6maJr60uEynu5uCbKR4Qg,7702 +pip/_internal/utils/unpacking.py,sha256=SBb2iV1crb89MDRTEKY86R4A_UOWApTQn9VQVcMDOlE,8821 +pip/_internal/utils/urls.py,sha256=AhaesUGl-9it6uvG6fsFPOr9ynFpGaTMk4t5XTX7Z_Q,1759 +pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456 +pip/_internal/utils/wheel.py,sha256=lXOgZyTlOm5HmK8tw5iw0A3_5A6wRzsXHOaQkIvvloU,4549 +pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596 +pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc,, +pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc,, +pip/_internal/vcs/__pycache__/git.cpython-38.pyc,, +pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc,, +pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc,, +pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc,, +pip/_internal/vcs/bazaar.py,sha256=j0oin0fpGRHcCFCxEcpPCQoFEvA-DMLULKdGP8Nv76o,3519 +pip/_internal/vcs/git.py,sha256=mjhwudCx9WlLNkxZ6_kOKmueF0rLoU2i1xeASKF6yiQ,18116 +pip/_internal/vcs/mercurial.py,sha256=Bzbd518Jsx-EJI0IhIobiQqiRsUv5TWYnrmRIFWE0Gw,5238 +pip/_internal/vcs/subversion.py,sha256=vhZs8L-TNggXqM1bbhl-FpbxE3TrIB6Tgnx8fh3S2HE,11729 +pip/_internal/vcs/versioncontrol.py,sha256=KUOc-hN51em9jrqxKwUR3JnkgSE-xSOqMiiJcSaL6B8,22811 +pip/_internal/wheel_builder.py,sha256=8cObBCu4mIsMJqZM7xXI9DO3vldiAnRNa1Gt6izPPTs,13079 +pip/_vendor/__init__.py,sha256=fNxOSVD0auElsD8fN9tuq5psfgMQ-RFBtD4X5gjlRkg,4966 +pip/_vendor/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/__pycache__/six.cpython-38.pyc,, +pip/_vendor/__pycache__/typing_extensions.cpython-38.pyc,, +pip/_vendor/cachecontrol/__init__.py,sha256=hrxlv3q7upsfyMw8k3gQ9vagBax1pYHSGGqYlZ0Zk0M,465 +pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc,, +pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc,, +pip/_vendor/cachecontrol/_cmd.py,sha256=lxUXqfNTVx84zf6tcWbkLZHA6WVBRtJRpfeA9ZqhaAY,1379 +pip/_vendor/cachecontrol/adapter.py,sha256=ew9OYEQHEOjvGl06ZsuX8W3DAvHWsQKHwWAxISyGug8,5033 +pip/_vendor/cachecontrol/cache.py,sha256=Tty45fOjH40fColTGkqKQvQQmbYsMpk-nCyfLcv2vG4,1535 +pip/_vendor/cachecontrol/caches/__init__.py,sha256=h-1cUmOz6mhLsjTjOrJ8iPejpGdLCyG4lzTftfGZvLg,242 +pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc,, +pip/_vendor/cachecontrol/caches/file_cache.py,sha256=GpexcE29LoY4MaZwPUTcUBZaDdcsjqyLxZFznk8Hbr4,5271 +pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=mp-QWonP40I3xJGK3XVO-Gs9a3UjzlqqEmp9iLJH9F4,1033 +pip/_vendor/cachecontrol/compat.py,sha256=LNx7vqBndYdHU8YuJt53ab_8rzMGTXVrvMb7CZJkxG0,778 +pip/_vendor/cachecontrol/controller.py,sha256=bAYrt7x_VH4toNpI066LQxbHpYGpY1MxxmZAhspplvw,16416 +pip/_vendor/cachecontrol/filewrapper.py,sha256=X4BAQOO26GNOR7nH_fhTzAfeuct2rBQcx_15MyFBpcs,3946 +pip/_vendor/cachecontrol/heuristics.py,sha256=8kAyuZLSCyEIgQr6vbUwfhpqg9ows4mM0IV6DWazevI,4154 +pip/_vendor/cachecontrol/serialize.py,sha256=_U1NU_C-SDgFzkbAxAsPDgMTHeTWZZaHCQnZN_jh0U8,7105 +pip/_vendor/cachecontrol/wrapper.py,sha256=X3-KMZ20Ho3VtqyVaXclpeQpFzokR5NE8tZSfvKVaB8,774 +pip/_vendor/certifi/__init__.py,sha256=bK_nm9bLJzNvWZc2oZdiTwg2KWD4HSPBWGaM0zUDvMw,94 +pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255 +pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc,, +pip/_vendor/certifi/__pycache__/core.cpython-38.pyc,, +pip/_vendor/certifi/cacert.pem,sha256=LBHDzgj_xA05AxnHK8ENT5COnGNElNZe0svFUHMf1SQ,275233 +pip/_vendor/certifi/core.py,sha256=ZwiOsv-sD_ouU1ft8wy_xZ3LQ7UbcVzyqj2XNyrsZis,4279 +pip/_vendor/chardet/__init__.py,sha256=57R-HSxj0PWmILMN0GFmUNqEMfrEVSamXyjD-W6_fbs,4797 +pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/johabfreq.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/johabprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/macromanprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/resultdict.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/utf1632prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc,, +pip/_vendor/chardet/__pycache__/version.cpython-38.pyc,, +pip/_vendor/chardet/big5freq.py,sha256=ltcfP-3PjlNHCoo5e4a7C4z-2DhBTXRfY6jbMbB7P30,31274 +pip/_vendor/chardet/big5prober.py,sha256=lPMfwCX6v2AaPgvFh_cSWZcgLDbWiFCHLZ_p9RQ9uxE,1763 +pip/_vendor/chardet/chardistribution.py,sha256=13B8XUG4oXDuLdXvfbIWwLFeR-ZU21AqTS1zcdON8bU,10032 +pip/_vendor/chardet/charsetgroupprober.py,sha256=UKK3SaIZB2PCdKSIS0gnvMtLR9JJX62M-fZJu3OlWyg,3915 +pip/_vendor/chardet/charsetprober.py,sha256=L3t8_wIOov8em-vZWOcbkdsrwe43N6_gqNh5pH7WPd4,5420 +pip/_vendor/chardet/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc,, +pip/_vendor/chardet/cli/chardetect.py,sha256=zibMVg5RpKb-ME9_7EYG4ZM2Sf07NHcQzZ12U-rYJho,3242 +pip/_vendor/chardet/codingstatemachine.py,sha256=K7k69sw3jY5DmTXoSJQVsUtFIQKYPQVOSJJhBuGv_yE,3732 +pip/_vendor/chardet/codingstatemachinedict.py,sha256=0GY3Hi2qIZvDrOOJ3AtqppM1RsYxr_66ER4EHjuMiMc,542 +pip/_vendor/chardet/cp949prober.py,sha256=0jKRV7fECuWI16rNnks0ZECKA1iZYCIEaP8A1ZvjUSI,1860 +pip/_vendor/chardet/enums.py,sha256=TzECiZoCKNMqgwU76cPCeKWFBqaWvAdLMev5_bCkhY8,1683 +pip/_vendor/chardet/escprober.py,sha256=Kho48X65xE0scFylIdeJjM2bcbvRvv0h0WUbMWrJD3A,4006 +pip/_vendor/chardet/escsm.py,sha256=AqyXpA2FQFD7k-buBty_7itGEYkhmVa8X09NLRul3QM,12176 +pip/_vendor/chardet/eucjpprober.py,sha256=5KYaM9fsxkRYzw1b5k0fL-j_-ezIw-ij9r97a9MHxLY,3934 +pip/_vendor/chardet/euckrfreq.py,sha256=3mHuRvXfsq_QcQysDQFb8qSudvTiol71C6Ic2w57tKM,13566 +pip/_vendor/chardet/euckrprober.py,sha256=hiFT6wM174GIwRvqDsIcuOc-dDsq2uPKMKbyV8-1Xnc,1753 +pip/_vendor/chardet/euctwfreq.py,sha256=2alILE1Lh5eqiFJZjzRkMQXolNJRHY5oBQd-vmZYFFM,36913 +pip/_vendor/chardet/euctwprober.py,sha256=NxbpNdBtU0VFI0bKfGfDkpP7S2_8_6FlO87dVH0ogws,1753 +pip/_vendor/chardet/gb2312freq.py,sha256=49OrdXzD-HXqwavkqjo8Z7gvs58hONNzDhAyMENNkvY,20735 +pip/_vendor/chardet/gb2312prober.py,sha256=KPEBueaSLSvBpFeINMu0D6TgHcR90e5PaQawifzF4o0,1759 +pip/_vendor/chardet/hebrewprober.py,sha256=96T_Lj_OmW-fK7JrSHojYjyG3fsGgbzkoTNleZ3kfYE,14537 +pip/_vendor/chardet/jisfreq.py,sha256=mm8tfrwqhpOd3wzZKS4NJqkYBQVcDfTM2JiQ5aW932E,25796 +pip/_vendor/chardet/johabfreq.py,sha256=dBpOYG34GRX6SL8k_LbS9rxZPMjLjoMlgZ03Pz5Hmqc,42498 +pip/_vendor/chardet/johabprober.py,sha256=O1Qw9nVzRnun7vZp4UZM7wvJSv9W941mEU9uDMnY3DU,1752 +pip/_vendor/chardet/jpcntx.py,sha256=uhHrYWkLxE_rF5OkHKInm0HUsrjgKHHVQvtt3UcvotA,27055 +pip/_vendor/chardet/langbulgarianmodel.py,sha256=vmbvYFP8SZkSxoBvLkFqKiH1sjma5ihk3PTpdy71Rr4,104562 +pip/_vendor/chardet/langgreekmodel.py,sha256=JfB7bupjjJH2w3X_mYnQr9cJA_7EuITC2cRW13fUjeI,98484 +pip/_vendor/chardet/langhebrewmodel.py,sha256=3HXHaLQPNAGcXnJjkIJfozNZLTvTJmf4W5Awi6zRRKc,98196 +pip/_vendor/chardet/langhungarianmodel.py,sha256=WxbeQIxkv8YtApiNqxQcvj-tMycsoI4Xy-fwkDHpP_Y,101363 +pip/_vendor/chardet/langrussianmodel.py,sha256=s395bTZ87ESTrZCOdgXbEjZ9P1iGPwCl_8xSsac_DLY,128035 +pip/_vendor/chardet/langthaimodel.py,sha256=7bJlQitRpTnVGABmbSznHnJwOHDy3InkTvtFUx13WQI,102774 +pip/_vendor/chardet/langturkishmodel.py,sha256=XY0eGdTIy4eQ9Xg1LVPZacb-UBhHBR-cq0IpPVHowKc,95372 +pip/_vendor/chardet/latin1prober.py,sha256=p15EEmFbmQUwbKLC7lOJVGHEZwcG45ubEZYTGu01J5g,5380 +pip/_vendor/chardet/macromanprober.py,sha256=9anfzmY6TBfUPDyBDOdY07kqmTHpZ1tK0jL-p1JWcOY,6077 +pip/_vendor/chardet/mbcharsetprober.py,sha256=Wr04WNI4F3X_VxEverNG-H25g7u-MDDKlNt-JGj-_uU,3715 +pip/_vendor/chardet/mbcsgroupprober.py,sha256=iRpaNBjV0DNwYPu_z6TiHgRpwYahiM7ztI_4kZ4Uz9A,2131 +pip/_vendor/chardet/mbcssm.py,sha256=hUtPvDYgWDaA2dWdgLsshbwRfm3Q5YRlRogdmeRUNQw,30391 +pip/_vendor/chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/chardet/metadata/__pycache__/languages.cpython-38.pyc,, +pip/_vendor/chardet/metadata/languages.py,sha256=FhvBIdZFxRQ-dTwkb_0madRKgVBCaUMQz9I5xqjE5iQ,13560 +pip/_vendor/chardet/resultdict.py,sha256=ez4FRvN5KaSosJeJ2WzUyKdDdg35HDy_SSLPXKCdt5M,402 +pip/_vendor/chardet/sbcharsetprober.py,sha256=-nd3F90i7GpXLjehLVHqVBE0KlWzGvQUPETLBNn4o6U,6400 +pip/_vendor/chardet/sbcsgroupprober.py,sha256=gcgI0fOfgw_3YTClpbra_MNxwyEyJ3eUXraoLHYb59E,4137 +pip/_vendor/chardet/sjisprober.py,sha256=aqQufMzRw46ZpFlzmYaYeT2-nzmKb-hmcrApppJ862k,4007 +pip/_vendor/chardet/universaldetector.py,sha256=xYBrg4x0dd9WnT8qclfADVD9ondrUNkqPmvte1pa520,14848 +pip/_vendor/chardet/utf1632prober.py,sha256=pw1epGdMj1hDGiCu1AHqqzOEfjX8MVdiW7O1BlT8-eQ,8505 +pip/_vendor/chardet/utf8prober.py,sha256=8m08Ub5490H4jQ6LYXvFysGtgKoKsHUd2zH_i8_TnVw,2812 +pip/_vendor/chardet/version.py,sha256=lGtJcxGM44Qz4Cbk4rbbmrKxnNr1-97U25TameLehZw,244 +pip/_vendor/colorama/__init__.py,sha256=wePQA4U20tKgYARySLEC047ucNX-g8pRLpYBuiHlLb8,266 +pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc,, +pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc,, +pip/_vendor/colorama/ansi.py,sha256=Top4EeEuaQdBWdteKMEcGOTeKeF19Q-Wo_6_Cj5kOzQ,2522 +pip/_vendor/colorama/ansitowin32.py,sha256=vPNYa3OZbxjbuFyaVo0Tmhmy1FZ1lKMWCnT7odXpItk,11128 +pip/_vendor/colorama/initialise.py,sha256=-hIny86ClXo39ixh5iSCfUIa2f_h_bgKRDW7gqs-KLU,3325 +pip/_vendor/colorama/tests/__init__.py,sha256=MkgPAEzGQd-Rq0w0PZXSX2LadRWhUECcisJY8lSrm4Q,75 +pip/_vendor/colorama/tests/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/utils.cpython-38.pyc,, +pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-38.pyc,, +pip/_vendor/colorama/tests/ansi_test.py,sha256=FeViDrUINIZcr505PAxvU4AjXz1asEiALs9GXMhwRaE,2839 +pip/_vendor/colorama/tests/ansitowin32_test.py,sha256=RN7AIhMJ5EqDsYaCjVo-o4u8JzDD4ukJbmevWKS70rY,10678 +pip/_vendor/colorama/tests/initialise_test.py,sha256=BbPy-XfyHwJ6zKozuQOvNvQZzsx9vdb_0bYXn7hsBTc,6741 +pip/_vendor/colorama/tests/isatty_test.py,sha256=Pg26LRpv0yQDB5Ac-sxgVXG7hsA1NYvapFgApZfYzZg,1866 +pip/_vendor/colorama/tests/utils.py,sha256=1IIRylG39z5-dzq09R_ngufxyPZxgldNbrxKxUGwGKE,1079 +pip/_vendor/colorama/tests/winterm_test.py,sha256=qoWFPEjym5gm2RuMwpf3pOis3a5r_PJZFCzK254JL8A,3709 +pip/_vendor/colorama/win32.py,sha256=YQOKwMTwtGBbsY4dL5HYTvwTeP9wIQra5MvPNddpxZs,6181 +pip/_vendor/colorama/winterm.py,sha256=XCQFDHjPi6AHYNdZwy0tA02H-Jh48Jp-HvCjeLeLp3U,7134 +pip/_vendor/distlib/__init__.py,sha256=acgfseOC55dNrVAzaBKpUiH3Z6V7Q1CaxsiQ3K7pC-E,581 +pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/database.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/index.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/util.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/version.cpython-38.pyc,, +pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc,, +pip/_vendor/distlib/compat.py,sha256=tfoMrj6tujk7G4UC2owL6ArgDuCKabgBxuJRGZSmpko,41259 +pip/_vendor/distlib/database.py,sha256=o_mw0fAr93NDAHHHfqG54Y1Hi9Rkfrp2BX15XWZYK50,51697 +pip/_vendor/distlib/index.py,sha256=HFiDG7LMoaBs829WuotrfIwcErOOExUOR_AeBtw_TCU,20834 +pip/_vendor/distlib/locators.py,sha256=wNzG-zERzS_XGls-nBPVVyLRHa2skUlkn0-5n0trMWA,51991 +pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 +pip/_vendor/distlib/markers.py,sha256=TpHHHLgkzyT7YHbwj-2i6weRaq-Ivy2-MUnrDkjau-U,5058 +pip/_vendor/distlib/metadata.py,sha256=g_DIiu8nBXRzA-mWPRpatHGbmFZqaFoss7z9TG7QSUU,39801 +pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820 +pip/_vendor/distlib/scripts.py,sha256=BmkTKmiTk4m2cj-iueliatwz3ut_9SsABBW51vnQnZU,18102 +pip/_vendor/distlib/t32.exe,sha256=a0GV5kCoWsMutvliiCKmIgV98eRZ33wXoS-XrqvJQVs,97792 +pip/_vendor/distlib/t64-arm.exe,sha256=68TAa32V504xVBnufojh0PcenpR3U4wAqTqf-MZqbPw,182784 +pip/_vendor/distlib/t64.exe,sha256=gaYY8hy4fbkHYTTnA4i26ct8IQZzkBG2pRdy0iyuBrc,108032 +pip/_vendor/distlib/util.py,sha256=31dPXn3Rfat0xZLeVoFpuniyhe6vsbl9_QN-qd9Lhlk,66262 +pip/_vendor/distlib/version.py,sha256=WG__LyAa2GwmA6qSoEJtvJE8REA1LZpbSizy8WvhJLk,23513 +pip/_vendor/distlib/w32.exe,sha256=R4csx3-OGM9kL4aPIzQKRo5TfmRSHZo6QWyLhDhNBks,91648 +pip/_vendor/distlib/w64-arm.exe,sha256=xdyYhKj0WDcVUOCb05blQYvzdYIKMbmJn2SZvzkcey4,168448 +pip/_vendor/distlib/w64.exe,sha256=ejGf-rojoBfXseGLpya6bFTFPWRG21X5KvU8J5iU-K0,101888 +pip/_vendor/distlib/wheel.py,sha256=Rgqs658VsJ3R2845qwnZD8XQryV2CzWw2mghwLvxxsI,43898 +pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981 +pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64 +pip/_vendor/distro/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/distro/__pycache__/__main__.cpython-38.pyc,, +pip/_vendor/distro/__pycache__/distro.cpython-38.pyc,, +pip/_vendor/distro/distro.py,sha256=UZO1LjIhtFCMdlbiz39gj3raV-Amf3SBwzGzfApiMHw,49330 +pip/_vendor/idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849 +pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/codec.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/compat.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/core.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc,, +pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc,, +pip/_vendor/idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374 +pip/_vendor/idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321 +pip/_vendor/idna/core.py,sha256=1JxchwKzkxBSn7R_oCE12oBu3eVux0VzdxolmIad24M,12950 +pip/_vendor/idna/idnadata.py,sha256=xUjqKqiJV8Ho_XzBpAtv5JFoVPSupK-SUXvtjygUHqw,44375 +pip/_vendor/idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881 +pip/_vendor/idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21 +pip/_vendor/idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539 +pip/_vendor/msgpack/__init__.py,sha256=NryGaKLDk_Egd58ZxXpnuI7OWO27AXz7S6CBFRM3sAY,1132 +pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc,, +pip/_vendor/msgpack/__pycache__/ext.cpython-38.pyc,, +pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc,, +pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081 +pip/_vendor/msgpack/ext.py,sha256=TuldJPkYu8Wo_Xh0tFGL2l06-gY88NSR8tOje9fo2Wg,6080 +pip/_vendor/msgpack/fallback.py,sha256=OORDn86-fHBPlu-rPlMdM10KzkH6S_Rx9CHN1b7o4cg,34557 +pip/_vendor/packaging/__about__.py,sha256=ugASIO2w1oUyH8_COqQ2X_s0rDhjbhQC3yJocD03h2c,661 +pip/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497 +pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/_manylinux.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/_musllinux.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/tags.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc,, +pip/_vendor/packaging/__pycache__/version.cpython-38.pyc,, +pip/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488 +pip/_vendor/packaging/_musllinux.py,sha256=_KGgY_qc7vhMGpoqss25n2hiLCNKRtvz9mCrS7gkqyc,4378 +pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431 +pip/_vendor/packaging/markers.py,sha256=AJBOcY8Oq0kYc570KuuPTkvuqjAlhufaE2c9sCUbm64,8487 +pip/_vendor/packaging/requirements.py,sha256=NtDlPBtojpn1IUC85iMjPNsUmufjpSlwnNA-Xb4m5NA,4676 +pip/_vendor/packaging/specifiers.py,sha256=LRQ0kFsHrl5qfcFNEEJrIFYsnIHQUJXY9fIsakTrrqE,30110 +pip/_vendor/packaging/tags.py,sha256=lmsnGNiJ8C4D_Pf9PbM0qgbZvD9kmB9lpZBQUZa3R_Y,15699 +pip/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200 +pip/_vendor/packaging/version.py,sha256=_fLRNrFrxYcHVfyo8vk9j8s6JM8N_xsSxVFr6RJyco8,14665 +pip/_vendor/pkg_resources/__init__.py,sha256=NnpQ3g6BCHzpMgOR_OLBmYtniY4oOzdKpwqghfq_6ug,108287 +pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc,, +pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 +pip/_vendor/platformdirs/__init__.py,sha256=9iY4Z8iJDZB0djln6zHHwrPVWpB54TCygcnh--MujU0,12936 +pip/_vendor/platformdirs/__main__.py,sha256=ZmsnTxEOxtTvwa-Y_Vfab_JN3X4XCVeN8X0yyy9-qnc,1176 +pip/_vendor/platformdirs/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/__main__.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/android.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/api.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/macos.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/unix.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/version.cpython-38.pyc,, +pip/_vendor/platformdirs/__pycache__/windows.cpython-38.pyc,, +pip/_vendor/platformdirs/android.py,sha256=GKizhyS7ESRiU67u8UnBJLm46goau9937EchXWbPBlk,4068 +pip/_vendor/platformdirs/api.py,sha256=MXKHXOL3eh_-trSok-JUTjAR_zjmmKF3rjREVABjP8s,4910 +pip/_vendor/platformdirs/macos.py,sha256=-3UXQewbT0yMhMdkzRXfXGAntmLIH7Qt4a9Hlf8I5_Y,2655 +pip/_vendor/platformdirs/unix.py,sha256=P-WQjSSieE38DXjMDa1t4XHnKJQ5idEaKT0PyXwm8KQ,6911 +pip/_vendor/platformdirs/version.py,sha256=qaN-fw_htIgKUVXoAuAEVgKxQu3tZ9qE2eiKkWIS7LA,160 +pip/_vendor/platformdirs/windows.py,sha256=LOrXLgI0CjQldDo2zhOZYGYZ6g4e_cJOCB_pF9aMRWQ,6596 +pip/_vendor/pygments/__init__.py,sha256=5oLcMLXD0cTG8YcHBPITtK1fS0JBASILEvEnWkTezgE,2999 +pip/_vendor/pygments/__main__.py,sha256=p0_rz3JZmNZMNZBOqDojaEx1cr9wmA9FQZX_TYl74lQ,353 +pip/_vendor/pygments/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/__main__.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/cmdline.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/console.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/filter.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/formatter.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/lexer.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/modeline.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/plugin.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/regexopt.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/scanner.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/sphinxext.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/style.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/token.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/unistring.cpython-38.pyc,, +pip/_vendor/pygments/__pycache__/util.cpython-38.pyc,, +pip/_vendor/pygments/cmdline.py,sha256=rc0fah4eknRqFgn1wKNEwkq0yWnSqYOGaA4PaIeOxVY,23685 +pip/_vendor/pygments/console.py,sha256=hQfqCFuOlGk7DW2lPQYepsw-wkOH1iNt9ylNA1eRymM,1697 +pip/_vendor/pygments/filter.py,sha256=NglMmMPTRRv-zuRSE_QbWid7JXd2J4AvwjCW2yWALXU,1938 +pip/_vendor/pygments/filters/__init__.py,sha256=b5YuXB9rampSy2-cMtKxGQoMDfrG4_DcvVwZrzTlB6w,40386 +pip/_vendor/pygments/filters/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pygments/formatter.py,sha256=6-TS2Y8pUMeWIUolWwr1O8ruC-U6HydWDwOdbAiJgJQ,2917 +pip/_vendor/pygments/formatters/__init__.py,sha256=YTqGeHS17fNXCLMZpf7oCxBCKLB9YLsZ8IAsjGhawyg,4810 +pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/groff.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/html.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/img.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/irc.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/latex.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/other.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/svg.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-38.pyc,, +pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-38.pyc,, +pip/_vendor/pygments/formatters/_mapping.py,sha256=fCZgvsM6UEuZUG7J6lr47eVss5owKd_JyaNbDfxeqmQ,4104 +pip/_vendor/pygments/formatters/bbcode.py,sha256=JrL4ITjN-KzPcuQpPMBf1pm33eW2sDUNr8WzSoAJsJA,3314 +pip/_vendor/pygments/formatters/groff.py,sha256=xrOFoLbafSA9uHsSLRogy79_Zc4GWJ8tMK2hCdTJRsw,5086 +pip/_vendor/pygments/formatters/html.py,sha256=QNt9prPgxmbKx2M-nfDwoR1bIg06-sNouQuWnE434Wc,35441 +pip/_vendor/pygments/formatters/img.py,sha256=h75Y7IRZLZxDEIwyoOsdRLTwm7kLVPbODKkgEiJ0iKI,21938 +pip/_vendor/pygments/formatters/irc.py,sha256=iwk5tDJOxbCV64SCmOFyvk__x6RD60ay0nUn7ko9n7U,5871 +pip/_vendor/pygments/formatters/latex.py,sha256=thPbytJCIs2AUXsO3NZwqKtXJ-upOlcXP4CXsx94G4w,19351 +pip/_vendor/pygments/formatters/other.py,sha256=PczqK1Rms43lz6iucOLPeBMxIncPKOGBt-195w1ynII,5073 +pip/_vendor/pygments/formatters/pangomarkup.py,sha256=ZZzMsKJKXrsDniFeMTkIpe7aQ4VZYRHu0idWmSiUJ2U,2212 +pip/_vendor/pygments/formatters/rtf.py,sha256=abrKlWjipBkQvhIICxtjYTUNv6WME0iJJObFvqVuudE,5014 +pip/_vendor/pygments/formatters/svg.py,sha256=6MM9YyO8NhU42RTQfTWBiagWMnsf9iG5gwhqSriHORE,7335 +pip/_vendor/pygments/formatters/terminal.py,sha256=NpEGvwkC6LgMLQTjVzGrJXji3XcET1sb5JCunSCzoRo,4674 +pip/_vendor/pygments/formatters/terminal256.py,sha256=4v4OVizvsxtwWBpIy_Po30zeOzE5oJg_mOc1-rCjMDk,11753 +pip/_vendor/pygments/lexer.py,sha256=ZPB_TGn_qzrXodRFwEdPzzJk6LZBo9BlfSy3lacc6zg,32005 +pip/_vendor/pygments/lexers/__init__.py,sha256=8d80-XfL5UKDCC1wRD1a_ZBZDkZ2HOe7Zul8SsnNYFE,11174 +pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-38.pyc,, +pip/_vendor/pygments/lexers/__pycache__/python.cpython-38.pyc,, +pip/_vendor/pygments/lexers/_mapping.py,sha256=zEiCV5FPiBioMJQJjw9kk7IJ5Y9GwknS4VJPYlcNchs,70232 +pip/_vendor/pygments/lexers/python.py,sha256=gZROs9iNSOA18YyVghP1cUCD0OwYZ04a6PCwgSOCeSA,53376 +pip/_vendor/pygments/modeline.py,sha256=gIbMSYrjSWPk0oATz7W9vMBYkUyTK2OcdVyKjioDRvA,986 +pip/_vendor/pygments/plugin.py,sha256=5rPxEoB_89qQMpOs0nI4KyLOzAHNlbQiwEMOKxqNmv8,2591 +pip/_vendor/pygments/regexopt.py,sha256=c6xcXGpGgvCET_3VWawJJqAnOp0QttFpQEdOPNY2Py0,3072 +pip/_vendor/pygments/scanner.py,sha256=F2T2G6cpkj-yZtzGQr-sOBw5w5-96UrJWveZN6va2aM,3092 +pip/_vendor/pygments/sphinxext.py,sha256=F8L0211sPnXaiWutN0lkSUajWBwlgDMIEFFAbMWOvZY,4630 +pip/_vendor/pygments/style.py,sha256=RRnussX1YiK9Z7HipIvKorImxu3-HnkdpPCO4u925T0,6257 +pip/_vendor/pygments/styles/__init__.py,sha256=iZDZ7PBKb55SpGlE1--cx9cbmWx5lVTH4bXO87t2Vok,3419 +pip/_vendor/pygments/styles/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pygments/token.py,sha256=vA2yNHGJBHfq4jNQSah7C9DmIOp34MmYHPA8P-cYAHI,6184 +pip/_vendor/pygments/unistring.py,sha256=gP3gK-6C4oAFjjo9HvoahsqzuV4Qz0jl0E0OxfDerHI,63187 +pip/_vendor/pygments/util.py,sha256=KgwpWWC3By5AiNwxGTI7oI9aXupH2TyZWukafBJe0Mg,9110 +pip/_vendor/pyparsing/__init__.py,sha256=ZPdI7pPo4IYXcABw-51AcqOzsxVvDtqnQbyn_qYWZvo,9171 +pip/_vendor/pyparsing/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/actions.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/common.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/core.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/exceptions.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/helpers.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/results.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/testing.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/unicode.cpython-38.pyc,, +pip/_vendor/pyparsing/__pycache__/util.cpython-38.pyc,, +pip/_vendor/pyparsing/actions.py,sha256=wU9i32e0y1ymxKE3OUwSHO-SFIrt1h_wv6Ws0GQjpNU,6426 +pip/_vendor/pyparsing/common.py,sha256=lFL97ooIeR75CmW5hjURZqwDCTgruqltcTCZ-ulLO2Q,12936 +pip/_vendor/pyparsing/core.py,sha256=AzTm1KFT1FIhiw2zvXZJmrpQoAwB0wOmeDCiR6SYytw,213344 +pip/_vendor/pyparsing/diagram/__init__.py,sha256=KW0PV_TvWKnL7jysz0pQbZ24nzWWu2ZfNaeyUIIywIg,23685 +pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pyparsing/exceptions.py,sha256=3LbSafD32NYb1Tzt85GHNkhEAU1eZkTtNSk24cPMemo,9023 +pip/_vendor/pyparsing/helpers.py,sha256=QpUOjW0-psvueMwWb9bQpU2noqKCv98_wnw1VSzSdVo,39129 +pip/_vendor/pyparsing/results.py,sha256=HgNvWVXBdQP-Q6PtJfoCEeOJk2nwEvG-2KVKC5sGA30,25341 +pip/_vendor/pyparsing/testing.py,sha256=7tu4Abp4uSeJV0N_yEPRmmNUhpd18ZQP3CrX41DM814,13402 +pip/_vendor/pyparsing/unicode.py,sha256=fwuhMj30SQ165Cv7HJpu-rSxGbRm93kN9L4Ei7VGc1Y,10787 +pip/_vendor/pyparsing/util.py,sha256=kq772O5YSeXOSdP-M31EWpbH_ayj7BMHImBYo9xPD5M,6805 +pip/_vendor/pyproject_hooks/__init__.py,sha256=kCehmy0UaBa9oVMD7ZIZrnswfnP3LXZ5lvnNJAL5JBM,491 +pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-38.pyc,, +pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-38.pyc,, +pip/_vendor/pyproject_hooks/_compat.py,sha256=by6evrYnqkisiM-MQcvOKs5bgDMzlOSgZqRHNqf04zE,138 +pip/_vendor/pyproject_hooks/_impl.py,sha256=61GJxzQip0IInhuO69ZI5GbNQ82XEDUB_1Gg5_KtUoc,11920 +pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=9gQATptbFkelkIy0OfWFEACzqxXJMQDWCH9rBOAZVwQ,546 +pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-38.pyc,, +pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=m2b34c917IW5o-Q_6TYIHlsK9lSUlNiyrITTUH_zwew,10927 +pip/_vendor/requests/__init__.py,sha256=64HgJ8cke-XyNrj1ErwNq0F9SqyAThUTh5lV6m7-YkI,5178 +pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/api.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/auth.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/certs.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/compat.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/help.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/models.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/packages.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/structures.cpython-38.pyc,, +pip/_vendor/requests/__pycache__/utils.cpython-38.pyc,, +pip/_vendor/requests/__version__.py,sha256=h48zn-oFukaXrYHocdadp_hIszWyd_PGrS8Eiii6aoc,435 +pip/_vendor/requests/_internal_utils.py,sha256=aSPlF4uDhtfKxEayZJJ7KkAxtormeTfpwKSBSwtmAUw,1397 +pip/_vendor/requests/adapters.py,sha256=GFEz5koZaMZD86v0SHXKVB5SE9MgslEjkCQzldkNwVM,21443 +pip/_vendor/requests/api.py,sha256=dyvkDd5itC9z2g0wHl_YfD1yf6YwpGWLO7__8e21nks,6377 +pip/_vendor/requests/auth.py,sha256=h-HLlVx9j8rKV5hfSAycP2ApOSglTz77R0tz7qCbbEE,10187 +pip/_vendor/requests/certs.py,sha256=PVPooB0jP5hkZEULSCwC074532UFbR2Ptgu0I5zwmCs,575 +pip/_vendor/requests/compat.py,sha256=IhK9quyX0RRuWTNcg6d2JGSAOUbM6mym2p_2XjLTwf4,1286 +pip/_vendor/requests/cookies.py,sha256=kD3kNEcCj-mxbtf5fJsSaT86eGoEYpD3X0CSgpzl7BM,18560 +pip/_vendor/requests/exceptions.py,sha256=FA-_kVwBZ2jhXauRctN_ewHVK25b-fj0Azyz1THQ0Kk,3823 +pip/_vendor/requests/help.py,sha256=FnAAklv8MGm_qb2UilDQgS6l0cUttiCFKUjx0zn2XNA,3879 +pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733 +pip/_vendor/requests/models.py,sha256=dDZ-iThotky-Noq9yy97cUEJhr3wnY6mv-xR_ePg_lk,35288 +pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 +pip/_vendor/requests/sessions.py,sha256=KUqJcRRLovNefUs7ScOXSUVCcfSayTFWtbiJ7gOSlTI,30180 +pip/_vendor/requests/status_codes.py,sha256=FvHmT5uH-_uimtRz5hH9VCbt7VV-Nei2J9upbej6j8g,4235 +pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912 +pip/_vendor/requests/utils.py,sha256=0gzSOcx9Ya4liAbHnHuwt4jM78lzCZZoDFgkmsInNUg,33240 +pip/_vendor/resolvelib/__init__.py,sha256=UL-B2BDI0_TRIqkfGwLHKLxY-LjBlomz7941wDqzB1I,537 +pip/_vendor/resolvelib/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/resolvelib/__pycache__/providers.cpython-38.pyc,, +pip/_vendor/resolvelib/__pycache__/reporters.cpython-38.pyc,, +pip/_vendor/resolvelib/__pycache__/resolvers.cpython-38.pyc,, +pip/_vendor/resolvelib/__pycache__/structs.cpython-38.pyc,, +pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-38.pyc,, +pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156 +pip/_vendor/resolvelib/providers.py,sha256=roVmFBItQJ0TkhNua65h8LdNny7rmeqVEXZu90QiP4o,5872 +pip/_vendor/resolvelib/reporters.py,sha256=fW91NKf-lK8XN7i6Yd_rczL5QeOT3sc6AKhpaTEnP3E,1583 +pip/_vendor/resolvelib/resolvers.py,sha256=2wYzVGBGerbmcIpH8cFmgSKgLSETz8jmwBMGjCBMHG4,17592 +pip/_vendor/resolvelib/structs.py,sha256=IVIYof6sA_N4ZEiE1C1UhzTX495brCNnyCdgq6CYq28,4794 +pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090 +pip/_vendor/rich/__main__.py,sha256=TT8sb9PTnsnKhhrGuHkLN0jdN0dtKhtPkEr9CidDbPM,8478 +pip/_vendor/rich/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/__main__.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_cell_widths.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_emoji_codes.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_emoji_replace.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_export_format.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_extension.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_inspect.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_log_render.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_loop.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_null_file.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_palettes.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_pick.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_ratio.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_spinners.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_stack.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_timer.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_win32_console.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_windows.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_windows_renderer.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/_wrap.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/abc.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/align.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/ansi.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/bar.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/box.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/cells.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/color.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/color_triplet.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/columns.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/console.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/constrain.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/containers.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/control.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/default_styles.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/diagnose.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/emoji.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/errors.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/file_proxy.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/filesize.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/highlighter.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/json.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/jupyter.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/layout.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/live.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/live_render.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/logging.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/markup.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/measure.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/padding.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/pager.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/palette.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/panel.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/pretty.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/progress.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/progress_bar.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/prompt.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/protocol.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/region.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/repr.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/rule.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/scope.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/screen.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/segment.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/spinner.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/status.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/style.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/styled.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/syntax.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/table.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/terminal_theme.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/text.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/theme.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/themes.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/traceback.cpython-38.pyc,, +pip/_vendor/rich/__pycache__/tree.cpython-38.pyc,, +pip/_vendor/rich/_cell_widths.py,sha256=2n4EiJi3X9sqIq0O16kUZ_zy6UYMd3xFfChlKfnW1Hc,10096 +pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235 +pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064 +pip/_vendor/rich/_export_format.py,sha256=nHArqOljIlYn6NruhWsAsh-fHo7oJC3y9BDJyAa-QYQ,2114 +pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265 +pip/_vendor/rich/_inspect.py,sha256=oZJGw31e64dwXSCmrDnvZbwVb1ZKhWfU8wI3VWohjJk,9695 +pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225 +pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236 +pip/_vendor/rich/_null_file.py,sha256=cTaTCU_xuDXGGa9iqK-kZ0uddZCSvM-RgM2aGMuMiHs,1643 +pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063 +pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423 +pip/_vendor/rich/_ratio.py,sha256=2lLSliL025Y-YMfdfGbutkQDevhcyDqc-DtUYW9mU70,5472 +pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919 +pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351 +pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417 +pip/_vendor/rich/_win32_console.py,sha256=P0vxI2fcndym1UU1S37XAzQzQnkyY7YqAKmxm24_gug,22820 +pip/_vendor/rich/_windows.py,sha256=dvNl9TmfPzNVxiKk5WDFihErZ5796g2UC9-KGGyfXmk,1926 +pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783 +pip/_vendor/rich/_wrap.py,sha256=xfV_9t0Sg6rzimmrDru8fCVmUlalYAcHLDfrJZnbbwQ,1840 +pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890 +pip/_vendor/rich/align.py,sha256=FV6_GS-8uhIyViMng3hkIWSFaTgMohK1Oqyjl8I8mGE,10368 +pip/_vendor/rich/ansi.py,sha256=THex7-qjc82-ZRtmDPAYlVEObYOEE_ARB1692Fk-JHs,6819 +pip/_vendor/rich/bar.py,sha256=a7UD303BccRCrEhGjfMElpv5RFYIinaAhAuqYqhUvmw,3264 +pip/_vendor/rich/box.py,sha256=FJ6nI3jD7h2XNFU138bJUt2HYmWOlRbltoCEuIAZhew,9842 +pip/_vendor/rich/cells.py,sha256=zMjFI15wCpgjLR14lHdfFMVC6qMDi5OsKIB0PYZBBMk,4503 +pip/_vendor/rich/color.py,sha256=GTITgffj47On3YK1v_I5T2CPZJGSnyWipPID_YkYXqw,18015 +pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054 +pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131 +pip/_vendor/rich/console.py,sha256=w3tJfrILZpS359wrNqaldGmyk3PEhEmV8Pg2g2GjXWI,97992 +pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288 +pip/_vendor/rich/containers.py,sha256=aKgm5UDHn5Nmui6IJaKdsZhbHClh_X7D-_Wg8Ehrr7s,5497 +pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630 +pip/_vendor/rich/default_styles.py,sha256=WqVh-RPNEsx0Wxf3fhS_fCn-wVqgJ6Qfo-Zg7CoCsLE,7954 +pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972 +pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501 +pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642 +pip/_vendor/rich/file_proxy.py,sha256=4gCbGRXg0rW35Plaf0UVvj3dfENHuzc_n8I_dBqxI7o,1616 +pip/_vendor/rich/filesize.py,sha256=9fTLAPCAwHmBXdRv7KZU194jSgNrRb6Wx7RIoBgqeKY,2508 +pip/_vendor/rich/highlighter.py,sha256=3WW6PACGlq0e3YDjfqiMBQ0dYZwu7pcoFYUgJy01nb0,9585 +pip/_vendor/rich/json.py,sha256=TmeFm96Utaov-Ff5miavBPNo51HRooM8S78HEwrYEjA,5053 +pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252 +pip/_vendor/rich/layout.py,sha256=RFYL6HdCFsHf9WRpcvi3w-fpj-8O5dMZ8W96VdKNdbI,14007 +pip/_vendor/rich/live.py,sha256=emVaLUua-FKSYqZXmtJJjBIstO99CqMOuA6vMAKVkO0,14172 +pip/_vendor/rich/live_render.py,sha256=zElm3PrfSIvjOce28zETHMIUf9pFYSUA5o0AflgUP64,3667 +pip/_vendor/rich/logging.py,sha256=uB-cB-3Q4bmXDLLpbOWkmFviw-Fde39zyMV6tKJ2WHQ,11903 +pip/_vendor/rich/markup.py,sha256=xzF4uAafiEeEYDJYt_vUnJOGoTU8RrH-PH7WcWYXjCg,8198 +pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305 +pip/_vendor/rich/padding.py,sha256=kTFGsdGe0os7tXLnHKpwTI90CXEvrceeZGCshmJy5zw,4970 +pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828 +pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396 +pip/_vendor/rich/panel.py,sha256=wGMe40J8KCGgQoM0LyjRErmGIkv2bsYA71RCXThD0xE,10574 +pip/_vendor/rich/pretty.py,sha256=dAbLqSF3jJnyfBLJ7QjQ3B2J-WGyBnAdGXeuBVIyMyA,37414 +pip/_vendor/rich/progress.py,sha256=eg-OURdfZW3n3bib1-zP3SZl6cIm2VZup1pr_96CyLk,59836 +pip/_vendor/rich/progress_bar.py,sha256=cEoBfkc3lLwqba4XKsUpy4vSQKDh2QQ5J2J94-ACFoo,8165 +pip/_vendor/rich/prompt.py,sha256=x0mW-pIPodJM4ry6grgmmLrl8VZp99kqcmdnBe70YYA,11303 +pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391 +pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166 +pip/_vendor/rich/repr.py,sha256=eJObQe6_c5pUjRM85sZ2rrW47_iF9HT3Z8DrgVjvOl8,4436 +pip/_vendor/rich/rule.py,sha256=V6AWI0wCb6DB0rvN967FRMlQrdlG7HoZdfEAHyeG8CM,4773 +pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843 +pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591 +pip/_vendor/rich/segment.py,sha256=6XdX0MfL18tUCaUWDWncIqx0wpq3GiaqzhYP779JvRA,24224 +pip/_vendor/rich/spinner.py,sha256=7b8MCleS4fa46HX0AzF98zfu6ZM6fAL0UgYzPOoakF4,4374 +pip/_vendor/rich/status.py,sha256=gJsIXIZeSo3urOyxRUjs6VrhX5CZrA0NxIQ-dxhCnwo,4425 +pip/_vendor/rich/style.py,sha256=odBbAlrgdEbAj7pmtPbQtWJNS8upyNhhy--Ks6KwAKk,26332 +pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258 +pip/_vendor/rich/syntax.py,sha256=W1xtdBA1-EVP-weYofKXusUlV5zghCOv1nWMHHfNmiY,34995 +pip/_vendor/rich/table.py,sha256=-WzesL-VJKsaiDU3uyczpJMHy6VCaSewBYJwx8RudI8,39684 +pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370 +pip/_vendor/rich/text.py,sha256=andXaxWW_wBveMiZZpd5viQwucWo7SPopcM3ZCQeO0c,45686 +pip/_vendor/rich/theme.py,sha256=GKNtQhDBZKAzDaY0vQVQQFzbc0uWfFe6CJXA-syT7zQ,3627 +pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102 +pip/_vendor/rich/traceback.py,sha256=6LkGguCEAxKv8v8xmKfMeYPPJ1UXUEHDv4726To6FiQ,26070 +pip/_vendor/rich/tree.py,sha256=BMbUYNjS9uodNPfvtY_odmU09GA5QzcMbQ5cJZhllQI,9169 +pip/_vendor/six.py,sha256=TOOfQi7nFGfMrIvtdr6wX4wyHH8M7aknmuLfo2cBBrM,34549 +pip/_vendor/tenacity/__init__.py,sha256=rjcWJVq5PcNJNC42rt-TAGGskM-RUEkZbDKu1ra7IPo,18364 +pip/_vendor/tenacity/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/_asyncio.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/_utils.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/after.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/before.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/before_sleep.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/nap.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/retry.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/stop.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-38.pyc,, +pip/_vendor/tenacity/__pycache__/wait.cpython-38.pyc,, +pip/_vendor/tenacity/_asyncio.py,sha256=HEb0BVJEeBJE9P-m9XBxh1KcaF96BwoeqkJCL5sbVcQ,3314 +pip/_vendor/tenacity/_utils.py,sha256=-y68scDcyoqvTJuJJ0GTfjdSCljEYlbCYvgk7nM4NdM,1944 +pip/_vendor/tenacity/after.py,sha256=dlmyxxFy2uqpLXDr838DiEd7jgv2AGthsWHGYcGYsaI,1496 +pip/_vendor/tenacity/before.py,sha256=7XtvRmO0dRWUp8SVn24OvIiGFj8-4OP5muQRUiWgLh0,1376 +pip/_vendor/tenacity/before_sleep.py,sha256=ThyDvqKU5yle_IvYQz_b6Tp6UjUS0PhVp6zgqYl9U6Y,1908 +pip/_vendor/tenacity/nap.py,sha256=fRWvnz1aIzbIq9Ap3gAkAZgDH6oo5zxMrU6ZOVByq0I,1383 +pip/_vendor/tenacity/retry.py,sha256=Cy504Ss3UrRV7lnYgvymF66WD1wJ2dbM869kDcjuDes,7550 +pip/_vendor/tenacity/stop.py,sha256=sKHmHaoSaW6sKu3dTxUVKr1-stVkY7lw4Y9yjZU30zQ,2790 +pip/_vendor/tenacity/tornadoweb.py,sha256=E8lWO2nwe6dJgoB-N2HhQprYLDLB_UdSgFnv-EN6wKE,2145 +pip/_vendor/tenacity/wait.py,sha256=tdLTESRm5E237VHG0SxCDXRa0DHKPKVq285kslHVURc,8011 +pip/_vendor/tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396 +pip/_vendor/tomli/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/tomli/__pycache__/_parser.cpython-38.pyc,, +pip/_vendor/tomli/__pycache__/_re.cpython-38.pyc,, +pip/_vendor/tomli/__pycache__/_types.cpython-38.pyc,, +pip/_vendor/tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633 +pip/_vendor/tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943 +pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254 +pip/_vendor/typing_extensions.py,sha256=VKZ_nHsuzDbKOVUY2CTdavwBgfZ2EXRyluZHRzUYAbg,80114 +pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333 +pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/_version.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc,, +pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc,, +pip/_vendor/urllib3/_collections.py,sha256=Rp1mVyBgc_UlAcp6M3at1skJBXR5J43NawRTvW2g_XY,10811 +pip/_vendor/urllib3/_version.py,sha256=JWE--BUVy7--9FsXILONIpQ43irftKGjT9j2H_fdF2M,64 +pip/_vendor/urllib3/connection.py,sha256=8976wL6sGeVMW0JnXvx5mD00yXu87uQjxtB9_VL8dx8,20070 +pip/_vendor/urllib3/connectionpool.py,sha256=vS4UaHLoR9_5aGLXSQ776y_jTxgqqjx0YsjkYksWGOo,39095 +pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957 +pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632 +pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922 +pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036 +pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528 +pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081 +pip/_vendor/urllib3/contrib/securetransport.py,sha256=yhZdmVjY6PI6EeFbp7qYOp6-vp1Rkv2NMuOGaEj7pmc,34448 +pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097 +pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217 +pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579 +pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440 +pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc,, +pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417 +pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665 +pip/_vendor/urllib3/poolmanager.py,sha256=0KOOJECoeLYVjUHvv-0h4Oq3FFQQ2yb-Fnjkbj8gJO0,19786 +pip/_vendor/urllib3/request.py,sha256=ZFSIqX0C6WizixecChZ3_okyu7BEv0lZu1VT0s6h4SM,5985 +pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641 +pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155 +pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/proxy.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc,, +pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc,, +pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901 +pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605 +pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498 +pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997 +pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510 +pip/_vendor/urllib3/util/retry.py,sha256=4laWh0HpwGijLiBmdBIYtbhYekQnNzzhx2W9uys0RHA,22003 +pip/_vendor/urllib3/util/ssl_.py,sha256=X4-AqW91aYPhPx6-xbf66yHFQKbqqfC_5Zt4WkLX1Hc,17177 +pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758 +pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895 +pip/_vendor/urllib3/util/timeout.py,sha256=QSbBUNOB9yh6AnDn61SrLQ0hg5oz0I9-uXEG91AJuIg,10003 +pip/_vendor/urllib3/util/url.py,sha256=HLCLEKt8D-QMioTNbneZSzGTGyUkns4w_lSJP1UzE2E,14298 +pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403 +pip/_vendor/vendor.txt,sha256=3i3Zr7_kRDD9UEva0I8YOMroCZ8xuZ9OWd_Q4jmazqE,476 +pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 +pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc,, +pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc,, +pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc,, +pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc,, +pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc,, +pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979 +pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305 +pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563 +pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307 +pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286 diff --git a/static/css/pages/page_store_home.css b/env_web/Lib/site-packages/pip-23.0.1.dist-info/REQUESTED similarity index 100% rename from static/css/pages/page_store_home.css rename to env_web/Lib/site-packages/pip-23.0.1.dist-info/REQUESTED diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/WHEEL b/env_web/Lib/site-packages/pip-23.0.1.dist-info/WHEEL new file mode 100644 index 00000000..57e3d840 --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.38.4) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/entry_points.txt b/env_web/Lib/site-packages/pip-23.0.1.dist-info/entry_points.txt new file mode 100644 index 00000000..ab909c9b --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/entry_points.txt @@ -0,0 +1,4 @@ +[console_scripts] +pip = pip._internal.cli.main:main +pip3 = pip._internal.cli.main:main +pip3.9 = pip._internal.cli.main:main diff --git a/env_web/Lib/site-packages/pip-23.0.1.dist-info/top_level.txt b/env_web/Lib/site-packages/pip-23.0.1.dist-info/top_level.txt new file mode 100644 index 00000000..a1b589e3 --- /dev/null +++ b/env_web/Lib/site-packages/pip-23.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/env_web/Lib/site-packages/pip/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e41547ee Binary files /dev/null and b/env_web/Lib/site-packages/pip/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..d2073e10 Binary files /dev/null and b/env_web/Lib/site-packages/pip/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/__pycache__/__pip-runner__.cpython-38.pyc b/env_web/Lib/site-packages/pip/__pycache__/__pip-runner__.cpython-38.pyc new file mode 100644 index 00000000..e9fc39c5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/__pycache__/__pip-runner__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ef88a9b4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc new file mode 100644 index 00000000..56ea6525 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc new file mode 100644 index 00000000..df1e9cc8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc new file mode 100644 index 00000000..160d7044 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc new file mode 100644 index 00000000..42795841 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc new file mode 100644 index 00000000..176ec0ad Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc new file mode 100644 index 00000000..fac5a89c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc new file mode 100644 index 00000000..ae2a3bd1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc new file mode 100644 index 00000000..33629e26 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..b05e862f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc new file mode 100644 index 00000000..6e3d0c29 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc new file mode 100644 index 00000000..4bd2596c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc new file mode 100644 index 00000000..3cd72e9d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc new file mode 100644 index 00000000..36065b59 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc new file mode 100644 index 00000000..98040c3f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc new file mode 100644 index 00000000..2bf7e9c2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc new file mode 100644 index 00000000..dcd0c1c2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc new file mode 100644 index 00000000..1e639fcd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc new file mode 100644 index 00000000..bec4aad8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc new file mode 100644 index 00000000..c653e36b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc new file mode 100644 index 00000000..41a45ee2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..9ca047eb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc new file mode 100644 index 00000000..50ba7542 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc new file mode 100644 index 00000000..8fa23510 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc new file mode 100644 index 00000000..93ea58ad Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc new file mode 100644 index 00000000..e31e1fc8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc new file mode 100644 index 00000000..1d7243a4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc new file mode 100644 index 00000000..4a0711f9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc new file mode 100644 index 00000000..5f279b7a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc new file mode 100644 index 00000000..1c074626 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc new file mode 100644 index 00000000..42692007 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-38.pyc new file mode 100644 index 00000000..e8f923da Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/index.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-38.pyc new file mode 100644 index 00000000..a4d0679b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc new file mode 100644 index 00000000..d7c56174 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc new file mode 100644 index 00000000..293c502d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc new file mode 100644 index 00000000..19509cf2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc new file mode 100644 index 00000000..dac7b759 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc new file mode 100644 index 00000000..8de5ecec Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..11f30c7d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7c99f376 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc new file mode 100644 index 00000000..7873447c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc new file mode 100644 index 00000000..02222193 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc new file mode 100644 index 00000000..15aa4db8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..bd1bfd6f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..c7e85420 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc new file mode 100644 index 00000000..8ea5a826 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc new file mode 100644 index 00000000..9a945667 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-38.pyc new file mode 100644 index 00000000..447f608d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/index/__pycache__/sources.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..11c294e7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-38.pyc new file mode 100644 index 00000000..87b4abee Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-38.pyc new file mode 100644 index 00000000..07fa49ac Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-38.pyc new file mode 100644 index 00000000..0d484521 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/locations/__pycache__/base.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..20a91a71 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-38.pyc new file mode 100644 index 00000000..2a7b4f27 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-38.pyc new file mode 100644 index 00000000..527d94a2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/base.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-38.pyc new file mode 100644 index 00000000..56da5e50 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..f4e8afcf Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-38.pyc new file mode 100644 index 00000000..a963fd3a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-38.pyc new file mode 100644 index 00000000..3f37e24d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-38.pyc new file mode 100644 index 00000000..9dcb1ba3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..c2663300 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc new file mode 100644 index 00000000..3d1c8a96 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-38.pyc new file mode 100644 index 00000000..2eea6e54 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc new file mode 100644 index 00000000..ea461698 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc new file mode 100644 index 00000000..9b4d1585 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-38.pyc new file mode 100644 index 00000000..467db71e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc new file mode 100644 index 00000000..d9a8ef17 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc new file mode 100644 index 00000000..dd6252ba Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc new file mode 100644 index 00000000..4eeb2cc5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc new file mode 100644 index 00000000..e5705bdb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc new file mode 100644 index 00000000..62e778d0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..396c78e1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..eff1e9b6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc new file mode 100644 index 00000000..1f281239 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc new file mode 100644 index 00000000..f1f10804 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc new file mode 100644 index 00000000..78b0de16 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-38.pyc new file mode 100644 index 00000000..93690167 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc new file mode 100644 index 00000000..a257f5ff Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..e60a534b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc new file mode 100644 index 00000000..8c26c337 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..68d9da3d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc new file mode 100644 index 00000000..3a74361e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc new file mode 100644 index 00000000..e6eb7c1e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc new file mode 100644 index 00000000..db58717d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..609825b4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-38.pyc new file mode 100644 index 00000000..233ae238 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc new file mode 100644 index 00000000..afe02745 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-38.pyc new file mode 100644 index 00000000..a0d3a1ae Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc new file mode 100644 index 00000000..de65df10 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..5296a6da Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-38.pyc new file mode 100644 index 00000000..4ac31b82 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc new file mode 100644 index 00000000..f4e76160 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e4f3a462 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc new file mode 100644 index 00000000..f3da62fe Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc new file mode 100644 index 00000000..8ccd01b1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..1833337b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/operations/install/legacy.py b/env_web/Lib/site-packages/pip/_internal/operations/install/legacy.py new file mode 100644 index 00000000..290967dd --- /dev/null +++ b/env_web/Lib/site-packages/pip/_internal/operations/install/legacy.py @@ -0,0 +1,120 @@ +"""Legacy installation process, i.e. `setup.py install`. +""" + +import logging +import os +from typing import List, Optional, Sequence + +from pip._internal.build_env import BuildEnvironment +from pip._internal.exceptions import InstallationError, LegacyInstallFailure +from pip._internal.locations.base import change_root +from pip._internal.models.scheme import Scheme +from pip._internal.utils.misc import ensure_dir +from pip._internal.utils.setuptools_build import make_setuptools_install_args +from pip._internal.utils.subprocess import runner_with_spinner_message +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +def write_installed_files_from_setuptools_record( + record_lines: List[str], + root: Optional[str], + req_description: str, +) -> None: + def prepend_root(path: str) -> str: + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + for line in record_lines: + directory = os.path.dirname(line) + if directory.endswith(".egg-info"): + egg_info_dir = prepend_root(directory) + break + else: + message = ( + "{} did not indicate that it installed an " + ".egg-info directory. Only setup.py projects " + "generating .egg-info directories are supported." + ).format(req_description) + raise InstallationError(message) + + new_lines = [] + for line in record_lines: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append(os.path.relpath(prepend_root(filename), egg_info_dir)) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, "installed-files.txt") + with open(inst_files_path, "w") as f: + f.write("\n".join(new_lines) + "\n") + + +def install( + install_options: List[str], + global_options: Sequence[str], + root: Optional[str], + home: Optional[str], + prefix: Optional[str], + use_user_site: bool, + pycompile: bool, + scheme: Scheme, + setup_py_path: str, + isolated: bool, + req_name: str, + build_env: BuildEnvironment, + unpacked_source_directory: str, + req_description: str, +) -> bool: + + header_dir = scheme.headers + + with TempDirectory(kind="record") as temp_dir: + try: + record_filename = os.path.join(temp_dir.path, "install-record.txt") + install_args = make_setuptools_install_args( + setup_py_path, + global_options=global_options, + install_options=install_options, + record_filename=record_filename, + root=root, + prefix=prefix, + header_dir=header_dir, + home=home, + use_user_site=use_user_site, + no_user_config=isolated, + pycompile=pycompile, + ) + + runner = runner_with_spinner_message( + f"Running setup.py install for {req_name}" + ) + with build_env: + runner( + cmd=install_args, + cwd=unpacked_source_directory, + ) + + if not os.path.exists(record_filename): + logger.debug("Record file %s not found", record_filename) + # Signal to the caller that we didn't install the new package + return False + + except Exception as e: + # Signal to the caller that we didn't install the new package + raise LegacyInstallFailure(package_details=req_name) from e + + # At this point, we have successfully installed the requirement. + + # We intentionally do not use any encoding to read the file because + # setuptools writes the file using distutils.file_util.write_file, + # which does not specify an encoding. + with open(record_filename) as f: + record_lines = f.read().splitlines() + + write_installed_files_from_setuptools_record(record_lines, root, req_description) + return True diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bb11a1da Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc new file mode 100644 index 00000000..2070897a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc new file mode 100644 index 00000000..2d2291e6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc new file mode 100644 index 00000000..bfd2c25b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc new file mode 100644 index 00000000..98106de1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc new file mode 100644 index 00000000..3a21bef6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..06bb4c3d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-38.pyc new file mode 100644 index 00000000..c2c83679 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/__pycache__/base.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..92b38a85 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc new file mode 100644 index 00000000..48e0a2c5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e6782e17 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc new file mode 100644 index 00000000..49c7bddc Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc new file mode 100644 index 00000000..55eeed99 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc new file mode 100644 index 00000000..a2d6a791 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-38.pyc new file mode 100644 index 00000000..0d8c0527 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc new file mode 100644 index 00000000..de1adaea Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-38.pyc new file mode 100644 index 00000000..8fd12b96 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc new file mode 100644 index 00000000..bd295f51 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc new file mode 100644 index 00000000..c4a465e9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7231f482 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-38.pyc new file mode 100644 index 00000000..875682a0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/_log.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc new file mode 100644 index 00000000..2faac3cb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc new file mode 100644 index 00000000..465b8fd4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc new file mode 100644 index 00000000..2f377c86 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-38.pyc new file mode 100644 index 00000000..abad6500 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc new file mode 100644 index 00000000..a9048eec Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc new file mode 100644 index 00000000..24ac8bc4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc new file mode 100644 index 00000000..a2258ade Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-38.pyc new file mode 100644 index 00000000..741484e6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc new file mode 100644 index 00000000..1c307785 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc new file mode 100644 index 00000000..1e5443ba Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc new file mode 100644 index 00000000..1fca9daf Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc new file mode 100644 index 00000000..797167fe Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc new file mode 100644 index 00000000..ef8f769e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc new file mode 100644 index 00000000..d3d30a37 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc new file mode 100644 index 00000000..2d7bfb33 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc new file mode 100644 index 00000000..aeb82c5c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc new file mode 100644 index 00000000..015c0923 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc new file mode 100644 index 00000000..a9fa60dc Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc new file mode 100644 index 00000000..7472b745 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc new file mode 100644 index 00000000..7f8d13b9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc new file mode 100644 index 00000000..a03c3a84 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc new file mode 100644 index 00000000..28f69911 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc new file mode 100644 index 00000000..31254595 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc new file mode 100644 index 00000000..686e7694 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc new file mode 100644 index 00000000..1c51d7d5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..6b02e151 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/utils/distutils_args.py b/env_web/Lib/site-packages/pip/_internal/utils/distutils_args.py new file mode 100644 index 00000000..2fd18620 --- /dev/null +++ b/env_web/Lib/site-packages/pip/_internal/utils/distutils_args.py @@ -0,0 +1,43 @@ +from getopt import GetoptError, getopt +from typing import Dict, List + +_options = [ + "exec-prefix=", + "home=", + "install-base=", + "install-data=", + "install-headers=", + "install-lib=", + "install-platlib=", + "install-purelib=", + "install-scripts=", + "prefix=", + "root=", + "user", +] + + +def parse_distutils_args(args: List[str]) -> Dict[str, str]: + """Parse provided arguments, returning an object that has the matched arguments. + + Any unknown arguments are ignored. + """ + result = {} + for arg in args: + try: + parsed_opt, _ = getopt(args=[arg], shortopts="", longopts=_options) + except GetoptError: + # We don't care about any other options, which here may be + # considered unrecognized since our option list is not + # exhaustive. + continue + + if not parsed_opt: + continue + + option = parsed_opt[0] + name_from_parsed = option[0][2:].replace("-", "_") + value_from_parsed = option[1] or "true" + result[name_from_parsed] = value_from_parsed + + return result diff --git a/env_web/Lib/site-packages/pip/_internal/utils/inject_securetransport.py b/env_web/Lib/site-packages/pip/_internal/utils/inject_securetransport.py new file mode 100644 index 00000000..276aa79b --- /dev/null +++ b/env_web/Lib/site-packages/pip/_internal/utils/inject_securetransport.py @@ -0,0 +1,35 @@ +"""A helper module that injects SecureTransport, on import. + +The import should be done as early as possible, to ensure all requests and +sessions (or whatever) are created after injecting SecureTransport. + +Note that we only do the injection on macOS, when the linked OpenSSL is too +old to handle TLSv1.2. +""" + +import sys + + +def inject_securetransport() -> None: + # Only relevant on macOS + if sys.platform != "darwin": + return + + try: + import ssl + except ImportError: + return + + # Checks for OpenSSL 1.0.1 + if ssl.OPENSSL_VERSION_NUMBER >= 0x1000100F: + return + + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + return + + securetransport.inject_into_urllib3() + + +inject_securetransport() diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..b4a83d8b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc new file mode 100644 index 00000000..43e63f2d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc new file mode 100644 index 00000000..50bd403d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc new file mode 100644 index 00000000..094dcc3c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc new file mode 100644 index 00000000..8a967236 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc new file mode 100644 index 00000000..3e168640 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7b6a4a09 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-38.pyc new file mode 100644 index 00000000..d87ad8b7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/__pycache__/six.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-38.pyc new file mode 100644 index 00000000..5f6a3690 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..273e353f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc new file mode 100644 index 00000000..2b56ce0b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc new file mode 100644 index 00000000..c79d5a81 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc new file mode 100644 index 00000000..14b9fa5d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc new file mode 100644 index 00000000..4aa31e1e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc new file mode 100644 index 00000000..60fa4e1c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc new file mode 100644 index 00000000..fd27b728 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc new file mode 100644 index 00000000..cf08fa87 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc new file mode 100644 index 00000000..187308fa Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc new file mode 100644 index 00000000..069e548b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d7c3f046 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc new file mode 100644 index 00000000..4e83d8ff Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc new file mode 100644 index 00000000..4a73bb22 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/cachecontrol/compat.py b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 00000000..ccec9379 --- /dev/null +++ b/env_web/Lib/site-packages/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: 2015 Eric Larson +# +# SPDX-License-Identifier: Apache-2.0 + +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..17653a0d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..3a706c40 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-38.pyc new file mode 100644 index 00000000..9b8def68 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e82cb6fd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc new file mode 100644 index 00000000..8f03d5e2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc new file mode 100644 index 00000000..339403de Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc new file mode 100644 index 00000000..58d6256c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc new file mode 100644 index 00000000..9e5d43e0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc new file mode 100644 index 00000000..eca8fed3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc new file mode 100644 index 00000000..6d8f2654 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-38.pyc new file mode 100644 index 00000000..8e330205 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc new file mode 100644 index 00000000..975db4c4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc new file mode 100644 index 00000000..2d178a3b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc new file mode 100644 index 00000000..4dd81848 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc new file mode 100644 index 00000000..354b3dfe Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc new file mode 100644 index 00000000..60bac9d0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc new file mode 100644 index 00000000..535faf75 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc new file mode 100644 index 00000000..67e6961e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc new file mode 100644 index 00000000..cb443384 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc new file mode 100644 index 00000000..3d5427d4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc new file mode 100644 index 00000000..5477f625 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc new file mode 100644 index 00000000..65ee169a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc new file mode 100644 index 00000000..c1e68641 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc new file mode 100644 index 00000000..39235c8c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-38.pyc new file mode 100644 index 00000000..e61bd410 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabfreq.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-38.pyc new file mode 100644 index 00000000..4aa9cc48 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/johabprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc new file mode 100644 index 00000000..194bd747 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc new file mode 100644 index 00000000..321f49cd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc new file mode 100644 index 00000000..daf86276 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc new file mode 100644 index 00000000..999e0e9f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc new file mode 100644 index 00000000..c2e99d8c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-38.pyc new file mode 100644 index 00000000..f044db38 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc new file mode 100644 index 00000000..a3724201 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc new file mode 100644 index 00000000..8bb98401 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc new file mode 100644 index 00000000..10a1699e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-38.pyc new file mode 100644 index 00000000..a8b9e0b4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/macromanprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc new file mode 100644 index 00000000..462b3355 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc new file mode 100644 index 00000000..4ae90a13 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc new file mode 100644 index 00000000..9d5184eb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-38.pyc new file mode 100644 index 00000000..57d9e83a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/resultdict.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc new file mode 100644 index 00000000..47405286 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc new file mode 100644 index 00000000..8c752687 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc new file mode 100644 index 00000000..4f4d586b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc new file mode 100644 index 00000000..4570cfb7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-38.pyc new file mode 100644 index 00000000..1297443d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf1632prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc new file mode 100644 index 00000000..6104e3e0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-38.pyc new file mode 100644 index 00000000..29688c67 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7c6087d0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc new file mode 100644 index 00000000..438dabc8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..4c1b2488 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-38.pyc new file mode 100644 index 00000000..21b9e3c8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0ad58ce4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc new file mode 100644 index 00000000..a0c7cb1f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc new file mode 100644 index 00000000..75747e4c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc new file mode 100644 index 00000000..ec84863a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc new file mode 100644 index 00000000..edcb6c69 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc new file mode 100644 index 00000000..c7a1785f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..cfe90d2d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-38.pyc new file mode 100644 index 00000000..d3139317 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-38.pyc new file mode 100644 index 00000000..b5c69adb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-38.pyc new file mode 100644 index 00000000..41ad5324 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-38.pyc new file mode 100644 index 00000000..3914c456 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..afad0de6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-38.pyc new file mode 100644 index 00000000..1d3a9fc8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..89bacb9e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc new file mode 100644 index 00000000..9f6f1504 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-38.pyc new file mode 100644 index 00000000..fc000791 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-38.pyc new file mode 100644 index 00000000..807d45ff Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc new file mode 100644 index 00000000..0dfad29a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc new file mode 100644 index 00000000..aef68e1b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc new file mode 100644 index 00000000..d7f52460 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc new file mode 100644 index 00000000..9e166e30 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc new file mode 100644 index 00000000..b2c370de Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc new file mode 100644 index 00000000..de8876e4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-38.pyc new file mode 100644 index 00000000..44c13852 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-38.pyc new file mode 100644 index 00000000..3dc8b200 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc new file mode 100644 index 00000000..d70e97e4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d7aec6c1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..5087ce1e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-38.pyc new file mode 100644 index 00000000..2dc1f63d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..16b7c50d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-38.pyc new file mode 100644 index 00000000..b8c5b721 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-38.pyc new file mode 100644 index 00000000..fb7a35f5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-38.pyc new file mode 100644 index 00000000..a8b353e3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/core.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc new file mode 100644 index 00000000..09ba7e6a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc new file mode 100644 index 00000000..9ad1a389 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc new file mode 100644 index 00000000..1626189d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc new file mode 100644 index 00000000..703759c3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0e5610fd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc new file mode 100644 index 00000000..b93b8c19 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-38.pyc new file mode 100644 index 00000000..5bddd1ed Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc new file mode 100644 index 00000000..71d15009 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc new file mode 100644 index 00000000..4e951922 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..20357fa5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-38.pyc new file mode 100644 index 00000000..2d68c5c6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-38.pyc new file mode 100644 index 00000000..0db56fa8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc new file mode 100644 index 00000000..b3c1d015 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc new file mode 100644 index 00000000..9df94e61 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc new file mode 100644 index 00000000..4b813db4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc new file mode 100644 index 00000000..5ec2334d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-38.pyc new file mode 100644 index 00000000..fe89ce1e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..7e0b1528 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-38.pyc new file mode 100644 index 00000000..9ba2fedd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..2d1b5cb5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc new file mode 100644 index 00000000..89ce6553 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py new file mode 100644 index 00000000..a2d3007c --- /dev/null +++ b/env_web/Lib/site-packages/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +import os +import errno +import sys + +from pip._vendor import six + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + six.PY2 or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..225ba369 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..dd6d6d86 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-38.pyc new file mode 100644 index 00000000..91163907 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-38.pyc new file mode 100644 index 00000000..4828ac7e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-38.pyc new file mode 100644 index 00000000..8b613498 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-38.pyc new file mode 100644 index 00000000..a0b7931b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-38.pyc new file mode 100644 index 00000000..6c3a7d2e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-38.pyc new file mode 100644 index 00000000..96c47931 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..1592ccec Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..985f8df4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-38.pyc new file mode 100644 index 00000000..5c0601d4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-38.pyc new file mode 100644 index 00000000..25e7a66b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-38.pyc new file mode 100644 index 00000000..a190636f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-38.pyc new file mode 100644 index 00000000..0f344eb1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-38.pyc new file mode 100644 index 00000000..4d3f24b7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-38.pyc new file mode 100644 index 00000000..7505cb4c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-38.pyc new file mode 100644 index 00000000..9c4c799f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-38.pyc new file mode 100644 index 00000000..b73d8556 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-38.pyc new file mode 100644 index 00000000..e541ccdf Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-38.pyc new file mode 100644 index 00000000..4f89eef5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-38.pyc new file mode 100644 index 00000000..30d37bee Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-38.pyc new file mode 100644 index 00000000..100941b3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-38.pyc new file mode 100644 index 00000000..db25d7eb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-38.pyc new file mode 100644 index 00000000..da888c54 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e8ad27a8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ea994df0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-38.pyc new file mode 100644 index 00000000..ffe8abf5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-38.pyc new file mode 100644 index 00000000..d5ae49a6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-38.pyc new file mode 100644 index 00000000..8b6aba10 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-38.pyc new file mode 100644 index 00000000..1ac22597 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-38.pyc new file mode 100644 index 00000000..5ad71e7d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-38.pyc new file mode 100644 index 00000000..b107eb76 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-38.pyc new file mode 100644 index 00000000..bdc2e13e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-38.pyc new file mode 100644 index 00000000..d5ea82ca Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-38.pyc new file mode 100644 index 00000000..e4159d18 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-38.pyc new file mode 100644 index 00000000..809fe25f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-38.pyc new file mode 100644 index 00000000..ec911513 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-38.pyc new file mode 100644 index 00000000..363eb825 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-38.pyc new file mode 100644 index 00000000..25ee2e89 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d8876c74 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-38.pyc new file mode 100644 index 00000000..2771fc80 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-38.pyc new file mode 100644 index 00000000..93204be5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..03ec896d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d1cdd137 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-38.pyc new file mode 100644 index 00000000..9ffca471 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-38.pyc new file mode 100644 index 00000000..6696f669 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-38.pyc new file mode 100644 index 00000000..8f292adb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-38.pyc new file mode 100644 index 00000000..47c9dd04 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-38.pyc new file mode 100644 index 00000000..a991779d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-38.pyc new file mode 100644 index 00000000..44206323 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-38.pyc new file mode 100644 index 00000000..33a51a56 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-38.pyc new file mode 100644 index 00000000..1df192ad Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-38.pyc new file mode 100644 index 00000000..bbc30cbe Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0e87b789 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bfe493fa Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-38.pyc new file mode 100644 index 00000000..bd7b9d3d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-38.pyc new file mode 100644 index 00000000..a10bbbef Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..523e00a6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-38.pyc new file mode 100644 index 00000000..89117569 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..50e00a08 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc new file mode 100644 index 00000000..6e6ab717 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc new file mode 100644 index 00000000..9539bbd4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc new file mode 100644 index 00000000..41d32a7e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-38.pyc new file mode 100644 index 00000000..9cb8c8b2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/api.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-38.pyc new file mode 100644 index 00000000..38edf7bd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-38.pyc new file mode 100644 index 00000000..e1a63786 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-38.pyc new file mode 100644 index 00000000..6fc78b70 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc new file mode 100644 index 00000000..29f5b413 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc new file mode 100644 index 00000000..476cef2e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/help.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/help.cpython-38.pyc new file mode 100644 index 00000000..c420f4a6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/help.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc new file mode 100644 index 00000000..d4dab36c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-38.pyc new file mode 100644 index 00000000..68b6390d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/models.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-38.pyc new file mode 100644 index 00000000..2ebbb4ab Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc new file mode 100644 index 00000000..9296aa0e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc new file mode 100644 index 00000000..35014164 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-38.pyc new file mode 100644 index 00000000..684f491f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..1c962b7f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..f3f3176c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-38.pyc new file mode 100644 index 00000000..197463b5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-38.pyc new file mode 100644 index 00000000..43de8760 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-38.pyc new file mode 100644 index 00000000..49d6c6eb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-38.pyc new file mode 100644 index 00000000..f1984d78 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0428da81 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-38.pyc new file mode 100644 index 00000000..a1f58fac Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7f15a7e8 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-38.pyc new file mode 100644 index 00000000..e64f2cef Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-38.pyc new file mode 100644 index 00000000..c83c338a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-38.pyc new file mode 100644 index 00000000..22d22394 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-38.pyc new file mode 100644 index 00000000..3a22a12a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-38.pyc new file mode 100644 index 00000000..edb9695a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-38.pyc new file mode 100644 index 00000000..e7fd07c7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-38.pyc new file mode 100644 index 00000000..1869350f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-38.pyc new file mode 100644 index 00000000..d566dd7c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-38.pyc new file mode 100644 index 00000000..b4b8091c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-38.pyc new file mode 100644 index 00000000..b1d19b50 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-38.pyc new file mode 100644 index 00000000..be1b985b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-38.pyc new file mode 100644 index 00000000..e760b5d1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-38.pyc new file mode 100644 index 00000000..842e25c3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-38.pyc new file mode 100644 index 00000000..23b8ab82 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-38.pyc new file mode 100644 index 00000000..cd994454 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-38.pyc new file mode 100644 index 00000000..7e837e4d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-38.pyc new file mode 100644 index 00000000..2f303ae0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-38.pyc new file mode 100644 index 00000000..084ec8df Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-38.pyc new file mode 100644 index 00000000..1a0721a0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-38.pyc new file mode 100644 index 00000000..7fb98dea Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-38.pyc new file mode 100644 index 00000000..d1867696 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-38.pyc new file mode 100644 index 00000000..2424e784 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/align.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-38.pyc new file mode 100644 index 00000000..87a9f264 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-38.pyc new file mode 100644 index 00000000..be447362 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-38.pyc new file mode 100644 index 00000000..cdd6fed2 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/box.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-38.pyc new file mode 100644 index 00000000..97d34ec4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-38.pyc new file mode 100644 index 00000000..750ca157 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-38.pyc new file mode 100644 index 00000000..554038aa Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-38.pyc new file mode 100644 index 00000000..8a67f4af Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-38.pyc new file mode 100644 index 00000000..68b36161 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/console.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-38.pyc new file mode 100644 index 00000000..bfe1d4cb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-38.pyc new file mode 100644 index 00000000..b3370605 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-38.pyc new file mode 100644 index 00000000..f1120e36 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/control.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-38.pyc new file mode 100644 index 00000000..87b78e5d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-38.pyc new file mode 100644 index 00000000..7715ecb1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-38.pyc new file mode 100644 index 00000000..70426c0b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-38.pyc new file mode 100644 index 00000000..b04d68d3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-38.pyc new file mode 100644 index 00000000..d102f8b6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-38.pyc new file mode 100644 index 00000000..cf5f307f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-38.pyc new file mode 100644 index 00000000..ffd521c9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/json.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/json.cpython-38.pyc new file mode 100644 index 00000000..3f269a0f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/json.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-38.pyc new file mode 100644 index 00000000..7bfc3950 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-38.pyc new file mode 100644 index 00000000..fe7e0fb9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-38.pyc new file mode 100644 index 00000000..2b7ed094 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-38.pyc new file mode 100644 index 00000000..83bafffc Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-38.pyc new file mode 100644 index 00000000..23cf2cc4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-38.pyc new file mode 100644 index 00000000..6c28a7ea Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-38.pyc new file mode 100644 index 00000000..381edcfb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-38.pyc new file mode 100644 index 00000000..d6828f46 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-38.pyc new file mode 100644 index 00000000..2632b296 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-38.pyc new file mode 100644 index 00000000..4e81a83b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-38.pyc new file mode 100644 index 00000000..4527bdf0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-38.pyc new file mode 100644 index 00000000..2b5083e3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-38.pyc new file mode 100644 index 00000000..38e8e258 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-38.pyc new file mode 100644 index 00000000..db414ae6 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-38.pyc new file mode 100644 index 00000000..f58470f1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-38.pyc new file mode 100644 index 00000000..6567164a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-38.pyc new file mode 100644 index 00000000..61d9f162 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/region.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-38.pyc new file mode 100644 index 00000000..ba77d817 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-38.pyc new file mode 100644 index 00000000..096a4bd7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-38.pyc new file mode 100644 index 00000000..8ffa208a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-38.pyc new file mode 100644 index 00000000..5c29d26c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-38.pyc new file mode 100644 index 00000000..e4b77b6c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-38.pyc new file mode 100644 index 00000000..1d2cbffb Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/status.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/status.cpython-38.pyc new file mode 100644 index 00000000..427e78a1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/status.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-38.pyc new file mode 100644 index 00000000..ba1b6522 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/style.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-38.pyc new file mode 100644 index 00000000..c4da3f44 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-38.pyc new file mode 100644 index 00000000..1377bf7e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-38.pyc new file mode 100644 index 00000000..1cdf5150 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/table.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-38.pyc new file mode 100644 index 00000000..8e82755a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-38.pyc new file mode 100644 index 00000000..1cc43c45 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/text.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-38.pyc new file mode 100644 index 00000000..80403895 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-38.pyc new file mode 100644 index 00000000..e2487fda Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-38.pyc new file mode 100644 index 00000000..c638f372 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-38.pyc new file mode 100644 index 00000000..1018ae96 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bd1097bd Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-38.pyc new file mode 100644 index 00000000..fee65603 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-38.pyc new file mode 100644 index 00000000..056b1f91 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-38.pyc new file mode 100644 index 00000000..7ac3b5d9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-38.pyc new file mode 100644 index 00000000..6c6efd4e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-38.pyc new file mode 100644 index 00000000..c95d6b46 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-38.pyc new file mode 100644 index 00000000..7891d217 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-38.pyc new file mode 100644 index 00000000..908a336f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-38.pyc new file mode 100644 index 00000000..8cc04f91 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-38.pyc new file mode 100644 index 00000000..bbf691c4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-38.pyc new file mode 100644 index 00000000..b5a7fa69 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..5410511c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-38.pyc new file mode 100644 index 00000000..ee3a3cff Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-38.pyc new file mode 100644 index 00000000..a89b51ea Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-38.pyc new file mode 100644 index 00000000..1c8a60ee Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..a0c5e035 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc new file mode 100644 index 00000000..4e2e4a48 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-38.pyc new file mode 100644 index 00000000..ccd659c5 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc new file mode 100644 index 00000000..1ed299b4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc new file mode 100644 index 00000000..61e359ad Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc new file mode 100644 index 00000000..6323c7c4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc new file mode 100644 index 00000000..d5bd9659 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc new file mode 100644 index 00000000..f5defda0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc new file mode 100644 index 00000000..bf770e8c Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc new file mode 100644 index 00000000..29fbd96b Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc new file mode 100644 index 00000000..e0503c32 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..14d3d301 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc new file mode 100644 index 00000000..a3ed6e5a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc new file mode 100644 index 00000000..a5beb18a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc new file mode 100644 index 00000000..3d52d4e1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc new file mode 100644 index 00000000..b1d28168 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc new file mode 100644 index 00000000..eff9120e Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc new file mode 100644 index 00000000..0ce90797 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7ff27668 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc new file mode 100644 index 00000000..c66c301f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc new file mode 100644 index 00000000..0bb1b6f9 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..a3221fae Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc new file mode 100644 index 00000000..aaa7af14 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..592f094d Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc new file mode 100644 index 00000000..f93e7ad0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..b03a5781 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc new file mode 100644 index 00000000..42655334 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-38.pyc new file mode 100644 index 00000000..04915183 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc new file mode 100644 index 00000000..8d65e9c7 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc new file mode 100644 index 00000000..a6ecc1cc Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc new file mode 100644 index 00000000..0c0e86ff Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc new file mode 100644 index 00000000..655455c3 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc new file mode 100644 index 00000000..9d1a9c29 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-38.pyc new file mode 100644 index 00000000..8017e4c1 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-38.pyc new file mode 100644 index 00000000..84dd9380 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc new file mode 100644 index 00000000..0a82572f Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc new file mode 100644 index 00000000..b455504a Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc new file mode 100644 index 00000000..2f4ad049 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..95878178 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc new file mode 100644 index 00000000..cce5b9d4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc new file mode 100644 index 00000000..47ee83d4 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc new file mode 100644 index 00000000..3a846632 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc differ diff --git a/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc new file mode 100644 index 00000000..46a05ae0 Binary files /dev/null and b/env_web/Lib/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc differ diff --git a/env_web/Scripts/pip3.8.exe b/env_web/Scripts/pip3.8.exe new file mode 100644 index 00000000..0a026553 Binary files /dev/null and b/env_web/Scripts/pip3.8.exe differ diff --git a/forms/__pycache__/base.cpython-312.pyc b/forms/__pycache__/base.cpython-312.pyc new file mode 100644 index 00000000..af6d106b Binary files /dev/null and b/forms/__pycache__/base.cpython-312.pyc differ diff --git a/forms/__pycache__/forms.cpython-312.pyc b/forms/__pycache__/forms.cpython-312.pyc index 445181d8..b45e6575 100644 Binary files a/forms/__pycache__/forms.cpython-312.pyc and b/forms/__pycache__/forms.cpython-312.pyc differ diff --git a/forms/base.py b/forms/base.py new file mode 100644 index 00000000..823a370b --- /dev/null +++ b/forms/base.py @@ -0,0 +1,46 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Form Base and Meta Classes - data input + +Description: +Defines Flask-WTF base forms for handling user input. +""" + +# internal +# external +from flask_wtf import FlaskForm +from abc import ABCMeta, abstractmethod + + +class Form_Base_Meta(type(FlaskForm), ABCMeta): + pass + + +class Form_Base(FlaskForm, metaclass=Form_Base_Meta): + @classmethod + @abstractmethod + def from_filters(cls, filters): + pass + @abstractmethod + def __repr__(self): + pass + @classmethod + @abstractmethod + def from_json(cls, json): + pass + """ + @abstractmethod + def test_69(self): + pass + + def get_Filters_Product_Category(data_request): + data_form = data_request[Model_View_Store_Product_Category.KEY_FORM] + form_filters = Filters_Product_Category(**data_form) + form_filters.is_not_empty.data = av.input_bool(data_form['is_not_empty'], 'is_not_empty', 'filter_category') + form_filters.active.data = av.input_bool(data_form['active'], 'active', 'filter_category') + return form_filters + """ \ No newline at end of file diff --git a/forms/forms.py b/forms/forms.py index a9f690ee..34b8b0af 100644 --- a/forms/forms.py +++ b/forms/forms.py @@ -14,11 +14,14 @@ Defines Flask-WTF forms for handling user input. # internal # from business_objects.store.product_category import Filters_Product_Category # circular # from models.model_view_store import Model_View_Store # circular +from forms.base import Form_Base # external from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, SubmitField, BooleanField, IntegerField, SelectField, FloatField from wtforms.validators import InputRequired, NumberRange, Regexp, DataRequired, Optional from flask_wtf.recaptcha import RecaptchaField +from abc import ABCMeta, abstractmethod + class Form_Contact(FlaskForm): @@ -141,5 +144,5 @@ class Form_Filters_Stock_Item(FlaskForm): class Form_Filters_User(FlaskForm): - active_only = BooleanField('Active only?') + active = BooleanField('Active only?') id_user = SelectField('User ID', validators=[Optional()], choices=[]) \ No newline at end of file diff --git a/forms/store/__pycache__/product.cpython-312.pyc b/forms/store/__pycache__/product.cpython-312.pyc new file mode 100644 index 00000000..b68ce617 Binary files /dev/null and b/forms/store/__pycache__/product.cpython-312.pyc differ diff --git a/forms/store/__pycache__/product_category.cpython-312.pyc b/forms/store/__pycache__/product_category.cpython-312.pyc index 4555ea30..6c5b475b 100644 Binary files a/forms/store/__pycache__/product_category.cpython-312.pyc and b/forms/store/__pycache__/product_category.cpython-312.pyc differ diff --git a/forms/store/product.py b/forms/store/product.py new file mode 100644 index 00000000..41c0fb9d --- /dev/null +++ b/forms/store/product.py @@ -0,0 +1,36 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Forms - Product Filter data input + +Description: +Defines Flask-WTF forms for handling user input. +""" + +# IMPORTS +# internal +# from business_objects.store.product_category import Filters_Product_Category +# from models.model_view_store import Model_View_Store # circular +# external +from flask_wtf import FlaskForm +from wtforms import StringField, TextAreaField, SubmitField, BooleanField, IntegerField, SelectField, FloatField +from wtforms.validators import InputRequired, NumberRange, Regexp, DataRequired, Optional +from flask_wtf.recaptcha import RecaptchaField + + +class Form_Filters_Product(FlaskForm): + id_category = SelectField('Category', validators=[Optional()], choices=[]) + is_not_empty = BooleanField('Not empty only?') + active = BooleanField("Active only?") + @classmethod + def from_filters_product(cls, filters_product): + form = Form_Filters_Product() + form.id_category = filters_product.id_category + form.is_not_empty.data = filters_product.is_not_empty + form.active.data = filters_product.active + return form + def __repr__(self): + return f'Form_Filters_Product(id_category={self.id_category}, is_not_empty={self.is_not_empty.data}, active={self.active.data})' \ No newline at end of file diff --git a/forms/store/product_category.py b/forms/store/product_category.py index 8142194b..79b96a9f 100644 --- a/forms/store/product_category.py +++ b/forms/store/product_category.py @@ -4,31 +4,41 @@ Author: Edward Middleton-Smith Precision And Research Technology Systems Limited Technology: Backend -Feature: Forms - User data input +Feature: Forms - Product Category Filters data input Description: -Defines Flask-WTF forms for handling user input. +Defines Flask-WTF forms for handling product category filter input. """ -# IMPORTS # internal +from business_objects.store.store_base import Store_Base # from business_objects.store.product_category import Filters_Product_Category # from models.model_view_store import Model_View_Store # circular +# from helpers.DEPRECATED.helper_abc import Interface_ABC +from forms.base import Form_Base +import lib.argument_validation as av # external from flask_wtf import FlaskForm from wtforms import StringField, TextAreaField, SubmitField, BooleanField, IntegerField, SelectField, FloatField from wtforms.validators import InputRequired, NumberRange, Regexp, DataRequired, Optional from flask_wtf.recaptcha import RecaptchaField +from abc import ABCMeta, abstractmethod -class Form_Filters_Product_Category(FlaskForm): +class Filters_Product_Category(Form_Base): is_not_empty = BooleanField('Not empty only?') active = BooleanField("Active only?") @classmethod - def from_filters_product_category(cls, filters_product_category): - form = Form_Filters_Product_Category() - form.is_not_empty.data = filters_product_category.is_not_empty_only - form.active.data = filters_product_category.active_only + def from_filters(cls, filters): + form = Filters_Product_Category() + form.is_not_empty.data = filters.is_not_empty + form.active.data = filters.active return form def __repr__(self): - return f'Form_Filters_Product_Category(is_not_empty={self.is_not_empty.data}, active={self.active.data})' \ No newline at end of file + return f'Filters_Product_Category(is_not_empty={self.is_not_empty.data}, active={self.active.data})' + @classmethod + def from_json(cls, json): + form = Filters_Product_Category() # is_not_empty=json['is_not_empty'], active=json['active']) + form.is_not_empty.data = av.input_bool(json[Store_Base.FLAG_IS_NOT_EMPTY], 'is_not_empty', 'Filters_Product_Category') + form.active.data = av.input_bool(json[Store_Base.FLAG_ACTIVE], 'active', 'Filters_Product_Category') + return form \ No newline at end of file diff --git a/helpers/DEPRECATED/__pycache__/helper_abc.cpython-312.pyc b/helpers/DEPRECATED/__pycache__/helper_abc.cpython-312.pyc new file mode 100644 index 00000000..51b38b36 Binary files /dev/null and b/helpers/DEPRECATED/__pycache__/helper_abc.cpython-312.pyc differ diff --git a/helpers/DEPRECATED/helper_abc.py b/helpers/DEPRECATED/helper_abc.py new file mode 100644 index 00000000..4d2dd89e --- /dev/null +++ b/helpers/DEPRECATED/helper_abc.py @@ -0,0 +1,38 @@ +from abc import abstractmethod +from functools import wraps +import inspect + +def Interface_ABC(cls): + abstract_methods = {} + for name, value in vars(cls).items(): + if getattr(value, '__isabstractmethod__', False): + if isinstance(value, classmethod): + abstract_methods[name] = 'classmethod' + elif isinstance(value, staticmethod): + abstract_methods[name] = 'staticmethod' + else: + abstract_methods[name] = 'method' + + def decorator(subclass): + for method, method_type in abstract_methods.items(): + if not hasattr(subclass, method): + raise NotImplementedError( + f"'{subclass.__name__}' must implement abstract {method_type} '{method}' from interface '{cls.__name__}'" + ) + + subclass_value = getattr(subclass, method) + + if method_type == 'classmethod' and not isinstance(subclass_value, classmethod): + raise TypeError(f"'{method}' must be a classmethod in '{subclass.__name__}'") + elif method_type == 'staticmethod' and not isinstance(subclass_value, staticmethod): + raise TypeError(f"'{method}' must be a staticmethod in '{subclass.__name__}'") + elif method_type == 'method' and (isinstance(subclass_value, (classmethod, staticmethod)) or inspect.isfunction(subclass_value)): + # For normal methods, we accept either functions or methods, as unbound methods are functions in Python 3 + pass + else: + raise TypeError(f"'{method}' has incorrect type in '{subclass.__name__}'") + + return subclass + + return decorator + diff --git a/helpers/helper_db_postgresql.py b/helpers/DEPRECATED/helper_db_postgresql.py similarity index 100% rename from helpers/helper_db_postgresql.py rename to helpers/DEPRECATED/helper_db_postgresql.py diff --git a/helpers/__pycache__/helper_abc.cpython-312.pyc b/helpers/__pycache__/helper_abc.cpython-312.pyc new file mode 100644 index 00000000..5b086707 Binary files /dev/null and b/helpers/__pycache__/helper_abc.cpython-312.pyc differ diff --git a/helpers/__pycache__/helper_app.cpython-312.pyc b/helpers/__pycache__/helper_app.cpython-312.pyc index 01ea7a07..5ae92951 100644 Binary files a/helpers/__pycache__/helper_app.cpython-312.pyc and b/helpers/__pycache__/helper_app.cpython-312.pyc differ diff --git a/helpers/helper_app.py b/helpers/helper_app.py index 1a5b2b66..db5a461b 100644 --- a/helpers/helper_app.py +++ b/helpers/helper_app.py @@ -19,13 +19,17 @@ class Helper_App(BaseModel): @staticmethod def get_request_data(request): + print(f'request={request}') + data = {} try: - return request.json + data = request.json except: try: - return request.data + data = request.data except: try: - return request.form + data = request.form except: - return {} \ No newline at end of file + pass + print(f'data={data}') + return data \ No newline at end of file diff --git a/lib/__pycache__/argument_validation.cpython-312.pyc b/lib/__pycache__/argument_validation.cpython-312.pyc index 389a27cb..48ef064e 100644 Binary files a/lib/__pycache__/argument_validation.cpython-312.pyc and b/lib/__pycache__/argument_validation.cpython-312.pyc differ diff --git a/lib/argument_validation.py b/lib/argument_validation.py index 579f2c4f..aa25e46c 100644 --- a/lib/argument_validation.py +++ b/lib/argument_validation.py @@ -1313,4 +1313,6 @@ def val_DataFrame(v_input, v_name, method, v_types=[], min_col=-1, max_col=-1, c - +if __name__ == '__main__': + print(input_bool('true', 'input_bool', 'test')) + print(input_bool(None, 'input_bool', 'test')) \ No newline at end of file diff --git a/models/__pycache__/model_view_base.cpython-312.pyc b/models/__pycache__/model_view_base.cpython-312.pyc index fb1ae579..f110801e 100644 Binary files a/models/__pycache__/model_view_base.cpython-312.pyc and b/models/__pycache__/model_view_base.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store.cpython-312.pyc b/models/__pycache__/model_view_store.cpython-312.pyc index dfa94027..b611bf85 100644 Binary files a/models/__pycache__/model_view_store.cpython-312.pyc and b/models/__pycache__/model_view_store.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store_home.cpython-312.pyc b/models/__pycache__/model_view_store_home.cpython-312.pyc new file mode 100644 index 00000000..2c1ddccc Binary files /dev/null and b/models/__pycache__/model_view_store_home.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store_product.cpython-312.pyc b/models/__pycache__/model_view_store_product.cpython-312.pyc new file mode 100644 index 00000000..b84d824d Binary files /dev/null and b/models/__pycache__/model_view_store_product.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store_product_category.cpython-312.pyc b/models/__pycache__/model_view_store_product_category.cpython-312.pyc index 31913525..ef762ed1 100644 Binary files a/models/__pycache__/model_view_store_product_category.cpython-312.pyc and b/models/__pycache__/model_view_store_product_category.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store_product_permutation.cpython-312.pyc b/models/__pycache__/model_view_store_product_permutation.cpython-312.pyc index 3b342acf..949949a5 100644 Binary files a/models/__pycache__/model_view_store_product_permutation.cpython-312.pyc and b/models/__pycache__/model_view_store_product_permutation.cpython-312.pyc differ diff --git a/models/__pycache__/model_view_store_stock_items.cpython-312.pyc b/models/__pycache__/model_view_store_stock_items.cpython-312.pyc index 62ebfc65..6e333982 100644 Binary files a/models/__pycache__/model_view_store_stock_items.cpython-312.pyc and b/models/__pycache__/model_view_store_stock_items.cpython-312.pyc differ diff --git a/models/model_view_base.py b/models/model_view_base.py index a872beb7..759f0fbd 100644 --- a/models/model_view_base.py +++ b/models/model_view_base.py @@ -19,8 +19,11 @@ Base data model for views # from routes import bp_home import lib.argument_validation as av from forms.forms import Form_Is_Included_VAT, Form_Delivery_Region, Form_Currency +from datastores.datastore_base import DataStore_Base from datastores.datastore_user import DataStore_User from business_objects.store.store_base import Store_Base +from business_objects.store.product_category import Product_Category +from business_objects.store.access_level import Filters_Access_Level from business_objects.user import User, User_Filters # external from abc import ABC, abstractmethod @@ -33,10 +36,13 @@ from typing import ClassVar class Model_View_Base(BaseModel, ABC): # Global constants # ATTR_FOR: ClassVar[str] = 'for' + ATTR_ID_ACCESS_LEVEL: ClassVar[str] = Store_Base.ATTR_ID_ACCESS_LEVEL ATTR_TEXT_COLLAPSED: ClassVar[str] = 'textCollapsed' ATTR_TEXT_EXPANDED: ClassVar[str] = 'textExpanded' ATTR_VALUE_CURRENT: ClassVar[str] = 'current-value' ATTR_VALUE_PREVIOUS: ClassVar[str] = 'previous-value' + FLAG_ACCESS_LEVEL: ClassVar[str] = 'access_level' + FLAG_ACCESS_LEVEL_REQUIRED: ClassVar[str] = Product_Category.FLAG_ACCESS_LEVEL_REQUIRED FLAG_ACTIVE: ClassVar[str] = Store_Base.FLAG_ACTIVE FLAG_ADD: ClassVar[str] = 'add' FLAG_CANCEL: ClassVar[str] = 'button-cancel' @@ -58,10 +64,14 @@ class Model_View_Base(BaseModel, ABC): FLAG_DISPLAY_ORDER: ClassVar[str] = Store_Base.FLAG_DISPLAY_ORDER FLAG_ERROR: ClassVar[str] = 'error' FLAG_EXPANDED: ClassVar[str] = 'expanded' + FLAG_FAILURE: ClassVar[str] = 'failure' FLAG_FILTER: ClassVar[str] = 'filter' + FLAG_FORM_FILTERS: ClassVar[str] = 'form-filters' FLAG_HAMBURGER: ClassVar[str] = 'hamburger' FLAG_IMAGE_LOGO: ClassVar[str] = 'image-logo' FLAG_INITIALISED: ClassVar[str] = 'initialised' + FLAG_KEY_PRIMARY: ClassVar[str] = Store_Base.FLAG_KEY_PRIMARY + FLAG_MESSAGE: ClassVar[str] = 'Message' FLAG_MODAL: ClassVar[str] = 'modal' FLAG_NAME: ClassVar[str] = Store_Base.FLAG_NAME FLAG_NAV_ADMIN_HOME: ClassVar[str] = 'navAdminHome' @@ -86,11 +96,14 @@ class Model_View_Base(BaseModel, ABC): FLAG_PAGE_BODY: ClassVar[str] = 'page-body' FLAG_ROW: ClassVar[str] = 'row' FLAG_ROW_NEW: ClassVar[str] = 'row-new' + FLAG_ROWS: ClassVar[str] = Store_Base.FLAG_ROWS FLAG_SAVE: ClassVar[str] = 'save' FLAG_SCROLLABLE: ClassVar[str] = 'scrollable' FLAG_SLIDER: ClassVar[str] = 'slider' + FLAG_STATUS: ClassVar[str] = 'status' FLAG_SUBMIT: ClassVar[str] = 'submit' FLAG_SUBMITTED: ClassVar[str] = 'submitted' + FLAG_SUCCESS: ClassVar[str] = 'success' # flagIsDatePicker: ClassVar[str] = 'is-date-picker' HASH_APPLY_FILTERS_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_filter' HASH_CALLBACK_LOGIN: ClassVar[str] = '/callback-login' @@ -118,6 +131,7 @@ class Model_View_Base(BaseModel, ABC): HASH_PAGE_USER_ADMIN: ClassVar[str] = '/user/admin' HASH_PAGE_USER_LOGIN: ClassVar[str] = '/login' HASH_PAGE_USER_LOGOUT: ClassVar[str] = '/logout' + HASH_SCRIPTS_SECTION_STORE: ClassVar[str] = '/scripts_store' ID_BUTTON_ADD: ClassVar[str] = 'buttonAdd' ID_BUTTON_APPLY_FILTERS: ClassVar[str] = 'buttonApplyFilters' ID_BUTTON_CANCEL: ClassVar[str] = 'buttonCancel' @@ -127,6 +141,7 @@ class Model_View_Base(BaseModel, ABC): ID_FORM_CONTACT: ClassVar[str] = 'formContact' ID_FORM_CURRENCY: ClassVar[str] = 'formCurrency' ID_FORM_DELIVERY_REGION: ClassVar[str] = 'formDeliveryRegion' + ID_FORM_FILTERS: ClassVar[str] = 'formFilters' ID_FORM_IS_INCLUDED_VAT: ClassVar[str] = 'formIsIncludedVAT' ID_LABEL_ERROR: ClassVar[str] = 'labelError' ID_MODAL_SERVICES: ClassVar[str] = 'modalServices' @@ -158,6 +173,7 @@ class Model_View_Base(BaseModel, ABC): ID_TEXTAREA_CONFIRM: ClassVar[str] = 'textareaConfirm' KEY_CALLBACK: ClassVar[str] = 'callback' # KEY_CSRF_TOKEN: ClassVar[str] = 'X-CSRFToken' + KEY_DATA: ClassVar[str] = 'data' KEY_FORM: ClassVar[str] = 'form' KEY_FORM_FILTERS: ClassVar[str] = KEY_FORM + 'Filters' KEY_USER: ClassVar[str] = User.KEY_USER @@ -184,6 +200,7 @@ class Model_View_Base(BaseModel, ABC): session: None = None is_page_store: bool = None is_user_logged_in: bool = None + access_levels: list = None model_config = ConfigDict(arbitrary_types_allowed=True) @@ -272,4 +289,21 @@ class Model_View_Base(BaseModel, ABC): return False """ - # def get_csrf_token(self): + def get_many_access_level(self, filters): + _m = 'Model_View_Store.get_many_access_level' + av.val_instance(filters, 'filters', _m, Filters_Access_Level) + + access_levels, errors = DataStore_Base.get_many_access_level(filters) + + return access_levels + @staticmethod + def convert_list_objects_to_list_options(list_objects): + return Store_Base.convert_list_objects_to_list_options(list_objects) + @staticmethod + def join_with_linebreaks(strs): + str_multiline = '' + for str in strs: + if str_multiline != '': + str_multiline += '\n' + str_multiline += str + return str_multiline \ No newline at end of file diff --git a/models/model_view_store.py b/models/model_view_store.py index 13b1dd1a..9b19b447 100644 --- a/models/model_view_store.py +++ b/models/model_view_store.py @@ -18,7 +18,9 @@ Parent data model for store views # internal # from context import models from models.model_view_base import Model_View_Base +from business_objects.store.store_base import Store_Base from business_objects.store.product import Product, Filters_Product, Product_Permutation # Product_Image_Filters, +# from business_objects.store.product_category import Filters_Product_Category from business_objects.store.image import Resolution_Level_Enum import lib.argument_validation as av from datastores.datastore_store_base import DataStore_Store_Base @@ -33,6 +35,7 @@ from flask import send_file, jsonify from flask_sqlalchemy import SQLAlchemy import locale from typing import ClassVar +from abc import abstractmethod # VARIABLE INSTANTIATION @@ -56,6 +59,7 @@ class Model_View_Store(Model_View_Base): FLAG_DATE_PURCHASED: ClassVar[str] = 'date-purchased' FLAG_DATE_RECEIVED: ClassVar[str] = 'date-received' FLAG_DATE_UNSEALED: ClassVar[str] = 'date-unsealed' + FLAG_IS_NOT_EMPTY: ClassVar[str] = Store_Base.FLAG_IS_NOT_EMPTY FLAG_IS_OUT_OF_STOCK: ClassVar[str] = 'is-out-of-stock' FLAG_LOCATION_STORAGE: ClassVar[str] = 'storage-location' FLAG_PRODUCT: ClassVar[str] = 'product' @@ -64,6 +68,7 @@ class Model_View_Store(Model_View_Base): FLAG_QUANTITY_MIN: ClassVar[str] = Product_Permutation.FLAG_QUANTITY_MIN # 'quantity-min' FLAG_QUANTITY_STOCK: ClassVar[str] = Product_Permutation.FLAG_QUANTITY_STOCK # 'quantity-stock' FLAG_PLANT_STORAGE: ClassVar[str] = 'plant-storage' + FLAG_PRODUCT_CATEGORY: ClassVar[str] = 'category' FLAG_REGION_STORAGE: ClassVar[str] = 'region-storage' FLAG_VARIATIONS: ClassVar[str] = 'variations' HASH_PAGE_STORE_BASKET : ClassVar[str] = '/store/basket' @@ -71,7 +76,9 @@ class Model_View_Store(Model_View_Base): HASH_STORE_BASKET_DELETE : ClassVar[str] = '/store/basket_delete' HASH_STORE_BASKET_EDIT : ClassVar[str] = '/store/basket_edit' HASH_STORE_BASKET_LOAD : ClassVar[str] = '/store/basket_load' + HASH_GET_STORE_PRODUCT: ClassVar[str] = '/store/product_get' HASH_GET_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/category_get' + HASH_SAVE_STORE_PRODUCT: ClassVar[str] = '/store/product_save' HASH_GET_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_get' HASH_SAVE_STORE_PRODUCT_CATEGORY: ClassVar[str] = '/store/category_save' HASH_SAVE_STORE_PRODUCT_PERMUTATION: ClassVar[str] = '/store/permutation_save' @@ -103,7 +110,6 @@ class Model_View_Store(Model_View_Base): KEY_NAME_VARIATION : ClassVar[str] = Product_Variation.KEY_NAME_VARIATION KEY_NAME_VARIATION_TYPE : ClassVar[str] = Product_Variation.KEY_NAME_VARIATION_TYPE KEY_PRICE : ClassVar[str] = 'price' - KEY_PRODUCT_CATEGORY: ClassVar[str] = 'category' KEY_QUANTITY : ClassVar[str] = 'quantity' KEY_VALUE_DEFAULT : ClassVar[str] = 'default' TYPE_FORM_BASKET_ADD : ClassVar[str] = 'Form_Basket_Add' @@ -133,6 +139,9 @@ class Model_View_Store(Model_View_Base): # cls.FLAG_BUTTON_BASKET_ADD = cls.FLAG_BUTTON_SUBMIT + '.buttonAdd2Basket' return super().__new__(cls, db, info_user, app) # Model_View_Store, cls """ + @property + def title(self): + raise NotImplementedError('title must be implemented in child class') def __init__(self, hash_page_current, **kwargs): # , id_currency, id_region_delivery, is_included_VAT): # Constructor diff --git a/models/model_view_store_home.py b/models/model_view_store_home.py index 63e665c7..a5bb1b7a 100644 --- a/models/model_view_store_home.py +++ b/models/model_view_store_home.py @@ -21,26 +21,26 @@ from models.model_view_store import Model_View_Store from business_objects.store.product import Product from forms.forms import Form_Basket_Add, Form_Basket_Edit # Form_Product # external - +from typing import ClassVar # VARIABLE INSTANTIATION # CLASSES class Model_View_Store_Home(Model_View_Store): + # Global constants + MAX_PRODUCTS_PER_CATEGORY: ClassVar[int] = -1 # Attributes product_categories: list # (str) forms_product: dict forms_basket: dict - # Global constants # category_products: dict { category_enum_id: List[Product] } # Attributes @property def title(self): return 'Store Home' - max_products_per_category = -1 - def __init__(self, id_currency, id_region_delivery, is_included_VAT, hash_page_current=Model_View_Store.HASH_PAGE_STORE_): + def __init__(self, id_currency, id_region_delivery, is_included_VAT, hash_page_current=Model_View_Store.HASH_PAGE_STORE_HOME): # Constructor super().__init__(id_currency, id_region_delivery, is_included_VAT) # self.categories = Model_View_Store_Home.get_many_product(self.db, get_all_category = True, get_all_product = True) diff --git a/models/model_view_store_product.py b/models/model_view_store_product.py index af202c0a..14dce9f7 100644 --- a/models/model_view_store_product.py +++ b/models/model_view_store_product.py @@ -37,7 +37,7 @@ class Model_View_Store_Product(Model_View_Store): def title(self): return 'Store Product' - def __init__(self, id_permutation, id_currency, id_region_delivery, is_included_VAT, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCT): + def __init__(self, id_permutation, id_currency, id_region_delivery, is_included_VAT, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCTS): # Constructor _m = 'Model_View_Store_Product.__init__' print(f'{_m}\nstarting...') @@ -57,8 +57,10 @@ class Model_View_Store_Product(Model_View_Store): print('connection to db successful') # self.categories = categories # self.category_index = category_index - if (category_list.get_count_categories() > 0): + """ + if (category_list.get_category_count() > 0): self.product = category_list.get_permutation_first() else: self.product = None print('selected permutation selected') + """ diff --git a/models/model_view_store_product_category.py b/models/model_view_store_product_category.py index ba186822..34645d5d 100644 --- a/models/model_view_store_product_category.py +++ b/models/model_view_store_product_category.py @@ -14,9 +14,10 @@ Data model for store permutations view from models.model_view_store import Model_View_Store # from datastores.datastore_store_base import DataStore_Store_Base from datastores.datastore_store_product_category import DataStore_Store_Product_Category -from business_objects.store.product_category import Container_Product_Category, Filters_Product_Category +from business_objects.store.access_level import Filters_Access_Level +from business_objects.store.product_category import Product_Category_Container # , Filters_Product_Category from forms.forms import Form_Filters_Permutation -from forms.store.product_category import Form_Filters_Product_Category +from forms.store.product_category import Filters_Product_Category # from routes import bp_home from business_objects.store.product import Product, Filters_Product, Product_Permutation from business_objects.store.product_variation import Product_Variation_List @@ -27,26 +28,25 @@ from pydantic import BaseModel from typing import ClassVar class Model_View_Store_Product_Category(Model_View_Store): - FLAG_IS_NOT_EMPTY: ClassVar[str] = 'is-not-empty' - ID_FORM_FILTERS_PRODUCT_CATEGORY: ClassVar[str] = 'Form_Filters_Product_Category' - KEY_CATEGORIES: ClassVar[str] = 'categories' + # KEY_CATEGORIES: ClassVar[str] = 'categories' - category_list: Container_Product_Category = None # (str) - filters_category: Filters_Product_Category - form_filters: Form_Filters_Product_Category = None + category_list: Product_Category_Container = None # (str) + # filters_category: Filters_Product_Category + form_filters: Filters_Product_Category = None @property def title(self): return 'Product Category' - def __init__(self, filters_category, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCT_CATEGORIES): + def __init__(self, form_filters, hash_page_current=Model_View_Store.HASH_PAGE_STORE_PRODUCT_CATEGORIES): _m = 'Model_View_Store_Product_Category.__init__' print(f'{_m}\nstarting...') - super().__init__(hash_page_current=hash_page_current, filters_category=filters_category) + super().__init__(hash_page_current=hash_page_current, form_filters=form_filters) # filters_category=filters_category) # BaseModel.__init__(self, app=app, filters_product=filters_product, **kwargs) + self.access_levels = self.get_many_access_level(Filters_Access_Level()) datastore_store = DataStore_Store_Product_Category() - self.form_filters = Form_Filters_Product_Category.from_filters_product_category(filters_category) - filters_product = Filters_Product.from_filters_product_category(filters_category) + # self.form_filters = Filters_Product_Category.from_filters(filters_category) + filters_product = Filters_Product.from_filters_product_category(self.form_filters) self.category_list, errors = datastore_store.get_many_product(filters_product) @classmethod diff --git a/models/model_view_store_product_permutation.py b/models/model_view_store_product_permutation.py index 5ed5da0d..011b3244 100644 --- a/models/model_view_store_product_permutation.py +++ b/models/model_view_store_product_permutation.py @@ -13,7 +13,7 @@ Data model for store permutations view # internal from models.model_view_store import Model_View_Store from datastores.datastore_store_product_permutation import DataStore_Store_Product_Permutation -from business_objects.store.product_category import Container_Product_Category +from business_objects.store.product_category import Product_Category_Container from forms.forms import Form_Filters_Permutation # from routes import bp_home from business_objects.store.product import Product, Filters_Product, Product_Permutation @@ -30,10 +30,10 @@ class Model_View_Store_Product_Permutation(Model_View_Store): ID_FILTER_IS_OUT_OF_STOCK: ClassVar[str] = 'is_out_of_stock' ID_FILTER_QUANTITY_MIN: ClassVar[str] = 'quantity_min' ID_FILTER_QUANTITY_MAX: ClassVar[str] = 'quantity_max' - ID_Form_Filters_Permutation: ClassVar[str] = 'Form_Filters_Permutation' + # ID_Form_Filters_Permutation: ClassVar[str] = 'Form_Filters_Permutation' KEY_PERMUTATIONS: ClassVar[str] = 'permutations' - category_list: Container_Product_Category = None # (str) + category_list: Product_Category_Container = None # (str) filters_product: Filters_Product form_filters: Form_Filters_Permutation = None permutation_blank: Product_Permutation = None @@ -67,7 +67,7 @@ class Model_View_Store_Product_Permutation(Model_View_Store): print(f'category_list_filters: {category_list_filters.categories}') self.form_filters.id_category.choices = [('0', 'All')] + [(str(category.id_category), category.name) for category in category_list_filters.categories] print(f'category options: {self.form_filters.id_category.choices}') - product_list = category_list_filters.to_list_products() + product_list = category_list_filters.to_product_option_list() print(f'product_list: {product_list}') self.form_filters.id_product.choices = [('0', 'All')] + [(str(product['value']), product['text']) for product in product_list] self.permutation_blank = Product_Permutation() diff --git a/models/model_view_store_stock_items.py b/models/model_view_store_stock_items.py index 40220be3..c4f42d60 100644 --- a/models/model_view_store_stock_items.py +++ b/models/model_view_store_stock_items.py @@ -13,7 +13,7 @@ Data model for store stock items view # internal from models.model_view_store import Model_View_Store from datastores.datastore_store_stock_item import DataStore_Store_Stock_Item -from business_objects.store.product_category import Container_Product_Category +from business_objects.store.product_category import Product_Category_Container from forms.forms import Form_Filters_Stock_Item # from routes import bp_home from business_objects.store.product import Product, Filters_Product, Product_Permutation @@ -33,7 +33,7 @@ class Model_View_Store_Stock_Items(Model_View_Store): ID_Form_Filters_Permutation: ClassVar[str] = 'Form_Filters_Permutation' KEY_PERMUTATIONS: ClassVar[str] = 'permutations' - category_list: Container_Product_Category = None # (str) + category_list: Product_Category_Container = None # (str) filters_stock_item: Stock_Item_Filters form_filters: Form_Filters_Stock_Item = None permutation_blank: Product_Permutation = None @@ -70,7 +70,7 @@ class Model_View_Store_Stock_Items(Model_View_Store): print(f'category_list_filters: {category_list_filters.categories}') self.form_filters.id_category.choices = [('0', 'All')] + [(str(category.id_category), category.name) for category in category_list_filters.categories] print(f'category options: {self.form_filters.id_category.choices}') - product_list = category_list_filters.to_list_products() + product_list = category_list_filters.to_product_option_list() print(f'product_list: {product_list}') self.form_filters.id_product.choices = [('0', 'All')] + [(str(product['value']), product['text']) for product in product_list] self.permutation_blank = Product_Permutation() diff --git a/pay_stripe.py b/pay_stripe.py index bda7620a..821e3bde 100644 --- a/pay_stripe.py +++ b/pay_stripe.py @@ -169,7 +169,7 @@ def webhook_received(): if event_type == 'checkout.session.completed': print('🔔 Payment succeeded!') - return jsonify({'status': 'success'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS}) if __name__ == '__main__': diff --git a/payments/pay_stripe.py b/payments/pay_stripe.py index 944bfecd..2a020f7f 100644 --- a/payments/pay_stripe.py +++ b/payments/pay_stripe.py @@ -157,7 +157,7 @@ def webhook_received(): if event_type == 'checkout.session.completed': print('🔔 Payment succeeded!') - return jsonify({'status': 'success'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS}) if __name__ == '__main__': diff --git a/routes.py b/routes.py new file mode 100644 index 00000000..d93a97ad --- /dev/null +++ b/routes.py @@ -0,0 +1,54 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: Backend +Feature: Controller - Webpage routing + +Description: +Defines the routes and view functions for each page. +Manages the interaction between the frontend and backend. +""" + +from flask import render_template, url_for, Blueprint +from app import app +from app.forms import Form_Contact +# from forms import MyForm +# from app import MyForm +from model_view_contact import Model_View_Contact + +""" +@app.route('/', methods=['GET']) +def home(): + return render_template('_home.html', title='Home') + +@app.route('/store', methods=['GET']) +def store_home(): + return render_template('_store_home.html', title='Store Home') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = Form_Contact() + if form.validate_on_submit(): + # Handle form submission + email = form.sender_email.data + CC = form.sender_CC.data + name = form.sender_name.data + msg = form.sender_message.data + # return render_template('contact.html', form=form) + # return render_template('_contact.html', title='Contact Us') + return render_template('contact.html', model=Model_View_Contact(form)) + +@app.route('/about') +def about(): + return render_template('about.html') + +@app.route('/contact', methods=['GET', 'POST']) +def contact(): + form = MyForm() + if form.validate_on_submit(): + # Handle form submission + pass + return render_template('contact.html', form=form) +""" \ No newline at end of file diff --git a/routing/__pycache__/core.cpython-312.pyc b/routing/__pycache__/core.cpython-312.pyc index 9d70ad0b..d4671612 100644 Binary files a/routing/__pycache__/core.cpython-312.pyc and b/routing/__pycache__/core.cpython-312.pyc differ diff --git a/routing/__pycache__/legal.cpython-312.pyc b/routing/__pycache__/legal.cpython-312.pyc index 8ce97d5d..94783a90 100644 Binary files a/routing/__pycache__/legal.cpython-312.pyc and b/routing/__pycache__/legal.cpython-312.pyc differ diff --git a/routing/__pycache__/user.cpython-312.pyc b/routing/__pycache__/user.cpython-312.pyc index 391a7ff7..9710f824 100644 Binary files a/routing/__pycache__/user.cpython-312.pyc and b/routing/__pycache__/user.cpython-312.pyc differ diff --git a/routing/core.py b/routing/core.py index e6ab2f7c..d8a15b78 100644 --- a/routing/core.py +++ b/routing/core.py @@ -36,7 +36,7 @@ def home(): try: model = Model_View_Home() print('nips') - html_body = render_template('_page_home.html', model = model) + html_body = render_template('pages/core/_home.html', model = model) except Exception as e: return jsonify(error=str(e)), 403 return html_body @@ -46,7 +46,7 @@ def contact(): try: form = Form_Contact() model = Model_View_Contact(form) - html_body = render_template('_page_contact.html', model = model) + html_body = render_template('pages/core/_contact.html', model = model) except Exception as e: return jsonify(error=str(e)), 403 return html_body @@ -67,7 +67,7 @@ def contact_post(): mail.send(mailItem) return "Submitted." return "Invalid. Failed to submit." - # html_body = render_template('_page_contact.html', model = model) + # html_body = render_template('pages/core/_contact.html', model = model) except Exception as e: return jsonify(error=str(e)), 403 @@ -75,7 +75,7 @@ def contact_post(): def services(): try: model = Model_View_Services() - html_body = render_template('_page_services.html', model = model) + html_body = render_template('pages/core/_services.html', model = model) except Exception as e: return jsonify(error=str(e)), 403 return html_body @@ -84,7 +84,7 @@ def services(): def admin_home(): try: model = Model_View_Admin_Home() - html_body = render_template('_page_admin_home.html', model = model) + html_body = render_template('pages/core/_admin_home.html', model = model) except Exception as e: return jsonify(error=str(e)), 403 return html_body diff --git a/routing/legal.py b/routing/legal.py index 01802207..78557d9c 100644 --- a/routing/legal.py +++ b/routing/legal.py @@ -30,7 +30,7 @@ routes_legal = Blueprint('routes_legal', __name__) def license(): try: model = Model_View_Home() - html_body = render_template('_page_license.html', model = model) + html_body = render_template('pages/legal/_license.html', model = model) except Exception as e: return str(e) return html_body @@ -38,7 +38,7 @@ def license(): def accessibility_statement(): try: model = Model_View_Home() - html_body = render_template('_page_accessibility_statement.html', model = model) + html_body = render_template('pages/legal/_accessibility_statement.html', model = model) except Exception as e: return str(e) return html_body @@ -46,7 +46,7 @@ def accessibility_statement(): def accessibility_report(): try: model = Model_View_Home() - html_body = render_template('_page_accessibility_report.html', model = model) + html_body = render_template('pages/legal/_accessibility_report.html', model = model) except Exception as e: return str(e) return html_body @@ -54,7 +54,7 @@ def accessibility_report(): def retention_schedule(): try: model = Model_View_Home() - html_body = render_template('_page_retention_schedule.html', model = model) + html_body = render_template('pages/legal/_retention_schedule.html', model = model) except Exception as e: return str(e) return html_body @@ -62,7 +62,7 @@ def retention_schedule(): def privacy_notice(): try: model = Model_View_Home() - html_body = render_template('_page_privacy_notice.html', model = model) + html_body = render_template('pages/legal/_privacy_notice.html', model = model) except Exception as e: return str(e) return html_body diff --git a/routing/store/__pycache__/product.cpython-312.pyc b/routing/store/__pycache__/product.cpython-312.pyc new file mode 100644 index 00000000..d82b6c1a Binary files /dev/null and b/routing/store/__pycache__/product.cpython-312.pyc differ diff --git a/routing/store/__pycache__/product_category.cpython-312.pyc b/routing/store/__pycache__/product_category.cpython-312.pyc index 8fbf94e8..4d83af2c 100644 Binary files a/routing/store/__pycache__/product_category.cpython-312.pyc and b/routing/store/__pycache__/product_category.cpython-312.pyc differ diff --git a/routing/store/__pycache__/product_permutation.cpython-312.pyc b/routing/store/__pycache__/product_permutation.cpython-312.pyc index 78881aff..be337c63 100644 Binary files a/routing/store/__pycache__/product_permutation.cpython-312.pyc and b/routing/store/__pycache__/product_permutation.cpython-312.pyc differ diff --git a/routing/store/__pycache__/stock_item.cpython-312.pyc b/routing/store/__pycache__/stock_item.cpython-312.pyc index c924126d..5f520ad9 100644 Binary files a/routing/store/__pycache__/stock_item.cpython-312.pyc and b/routing/store/__pycache__/stock_item.cpython-312.pyc differ diff --git a/routing/store/__pycache__/store.cpython-312.pyc b/routing/store/__pycache__/store.cpython-312.pyc new file mode 100644 index 00000000..edf2d772 Binary files /dev/null and b/routing/store/__pycache__/store.cpython-312.pyc differ diff --git a/routing/store/__pycache__/supplier.cpython-312.pyc b/routing/store/__pycache__/supplier.cpython-312.pyc index 0fc6ca9b..c4075ecc 100644 Binary files a/routing/store/__pycache__/supplier.cpython-312.pyc and b/routing/store/__pycache__/supplier.cpython-312.pyc differ diff --git a/routing/store/product.py b/routing/store/product.py new file mode 100644 index 00000000..d754ad4b --- /dev/null +++ b/routing/store/product.py @@ -0,0 +1,99 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App Routing +Feature: Store Product Routes + +Description: +Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles. +""" + +# internal +from business_objects.store.product import Product, Filters_Product +from forms.store.product import Form_Filters_Product +from models.model_view_store_product import Model_View_Store_Product +from helpers.helper_app import Helper_App +import lib.argument_validation as av +# external +from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app +from extensions import db, oauth +from urllib.parse import quote_plus, urlencode +from authlib.integrations.flask_client import OAuth +from authlib.integrations.base_client import OAuthError +from urllib.parse import quote, urlparse, parse_qs + + +routes_store_product = Blueprint('routes_store_product', __name__) + + +@routes_store_product.route(Model_View_Store_Product.HASH_PAGE_STORE_PRODUCTS, methods=['GET']) +def products(): + print('products') + print(f'request.args={request.args}') + filters = Filters_Product.get_default() + have_changed_filters = False + arg_filter_is_not_empty = request.args.get(Model_View_Store_Product.FLAG_IS_NOT_EMPTY, None) + have_changed_filters = have_changed_filters or arg_filter_is_not_empty is None + print(f'arg_filter_is_not_empty={arg_filter_is_not_empty}') + filters.is_not_empty = filters.is_not_empty if arg_filter_is_not_empty is None else av.input_bool(arg_filter_is_not_empty, 'is_not_empty', 'filter') + arg_filter_active = request.args.get(Model_View_Store_Product.FLAG_ACTIVE, None) + have_changed_filters = have_changed_filters or arg_filter_active is None + print(f'arg_filter_active={arg_filter_active}') + filters.active = filters.active if arg_filter_active is None else av.input_bool(arg_filter_active, 'active', 'filter') + if have_changed_filters: + print('redirecting') + return redirect(url_for('routes_store_product.products', **filters.to_json())) + model = Model_View_Store_Product(filters) + return render_template('pages/store/_products.html', model = model) + +@routes_store_product.route(Model_View_Store_Product.HASH_GET_STORE_PRODUCT, methods=['POST']) +def filter(): + data = Helper_App.get_request_data(request) + # form_filters = None + try: + form_filters = get_Form_Filters_Product(data) + if not form_filters.validate_on_submit(): + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'}) + # ToDo: manually validate category, product + filters_form = Filters_Product.from_form_filters_product(form_filters) + model = Model_View_Store_Product(filters = filters_form) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model.category_list.to_json()}) + except Exception as e: + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) + +def get_Form_Filters_Product(data_request): + data_form = data_request[Model_View_Store_Product.KEY_FORM] + form_filters = Form_Filters_Product(**data_form) + form_filters.is_not_empty.data = av.input_bool(data_form['is_not_empty'], 'is_not_empty', 'filter') + form_filters.active.data = av.input_bool(data_form['active'], 'active', 'filter') + return form_filters + +@routes_store_product.route(Model_View_Store_Product.HASH_SAVE_STORE_PRODUCT, methods=['POST']) +def save(): + data = Helper_App.get_request_data(request) + # form_filters = None + print(f'data={data}') + try: + form_filters = get_Form_Filters_Product(data) + if not form_filters.validate_on_submit(): + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'}) + filters_form = Filters_Product.from_form(form_filters) + + categories = data[Model_View_Store_Product.FLAG_PRODUCT] + if len(categories) == 0: + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'No categories.'}) + objsCategory = [] + for category in categories: + objsCategory.append(Product.from_json(category)) + # model_save = Model_View_Store_Product() # filters_product=filters_form) + print(f'objsCategory={objsCategory}') + Model_View_Store_Product.save_categories(data.get('comment', 'No comment'), objsCategory) + + model_return = Model_View_Store_Product(filters=filters_form) + print('nips') + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model_return.category_list.to_json()}) + except Exception as e: + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) + \ No newline at end of file diff --git a/routing/store/product_category.py b/routing/store/product_category.py index 88c8ad91..0c3d5618 100644 --- a/routing/store/product_category.py +++ b/routing/store/product_category.py @@ -11,8 +11,8 @@ Initializes the Flask application, sets the configuration based on the environme """ # internal -from business_objects.store.product_category import Product_Category, Filters_Product_Category -from forms.store.product_category import Form_Filters_Product_Category +from business_objects.store.product_category import Product_Category #, Filters_Product_Category +from forms.store.product_category import Filters_Product_Category from models.model_view_store_product_category import Model_View_Store_Product_Category from helpers.helper_app import Helper_App import lib.argument_validation as av @@ -30,46 +30,74 @@ routes_store_product_category = Blueprint('routes_store_product_category', __nam @routes_store_product_category.route(Model_View_Store_Product_Category.HASH_PAGE_STORE_PRODUCT_CATEGORIES, methods=['GET']) def categories(): + print('categories') + # data = Helper_App.get_request_data(request) + try: + form_filters = Filters_Product_Category.from_json(request.args) + except Exception as e: + print(f'Error: {e}') + form_filters = Filters_Product_Category() + print(f'form_filters={form_filters}') + """ filters = Filters_Product_Category.get_default() - model = Model_View_Store_Product_Category(filters) - return render_template('_page_store_product_categories.html', model = model) + have_changed_filters = False + arg_filter_is_not_empty = request.args.get(Model_View_Store_Product_Category.FLAG_IS_NOT_EMPTY, None) + have_changed_filters = have_changed_filters or arg_filter_is_not_empty is None + print(f'arg_filter_is_not_empty={arg_filter_is_not_empty}') + filters.is_not_empty = filters.is_not_empty if arg_filter_is_not_empty is None else av.input_bool(arg_filter_is_not_empty, 'is_not_empty', 'filter_category') + arg_filter_active = request.args.get(Model_View_Store_Product_Category.FLAG_ACTIVE, None) + have_changed_filters = have_changed_filters or arg_filter_active is None + print(f'arg_filter_active={arg_filter_active}') + filters.active = filters.active if arg_filter_active is None else av.input_bool(arg_filter_active, 'active', 'filter_category') + if have_changed_filters: + print('redirecting') + return redirect(url_for('routes_store_product_category.categories', **filters.to_json())) + """ + model = Model_View_Store_Product_Category(form_filters) + return render_template('pages/store/_product_categories.html', model = model) @routes_store_product_category.route(Model_View_Store_Product_Category.HASH_GET_STORE_PRODUCT_CATEGORY, methods=['POST']) def filter_category(): data = Helper_App.get_request_data(request) # form_filters = None try: - form_filters = get_Form_Filters_Product_Category(data) + form_filters = Filters_Product_Category.from_json(data) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Form invalid.\n{form_filters.errors}'}) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}' + }) # ToDo: manually validate category, product - filters_form = Filters_Product_Category.from_form(form_filters) - model = Model_View_Store_Product_Category(filters_category = filters_form) - return jsonify({'status': 'success', 'Success': True, 'data': model.category_list.to_json_str()}) + # filters_form = Filters_Product_Category.from_form(form_filters) + model = Model_View_Store_Product_Category(form_filters = form_filters) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.KEY_DATA: model.category_list.to_json() + }) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) - -def get_Form_Filters_Product_Category(data_request): - data_form = data_request[Model_View_Store_Product_Category.KEY_FORM] - form_filters = Form_Filters_Product_Category(**data_form) - form_filters.is_not_empty.data = av.input_bool(data_form['is_not_empty'], 'is_not_empty', 'filter_category') - form_filters.active.data = av.input_bool(data_form['active'], 'active', 'filter_category') - return form_filters + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.FLAG_MESSAGE: f'Bad data received by controller.\n{e}' + }) @routes_store_product_category.route(Model_View_Store_Product_Category.HASH_SAVE_STORE_PRODUCT_CATEGORY, methods=['POST']) def save_category(): data = Helper_App.get_request_data(request) - # form_filters = None - print(f'data={data}') try: - form_filters = get_Form_Filters_Product_Category(data) + form_filters = Filters_Product_Category.from_json(data[Model_View_Store_Product_Category.FLAG_FORM_FILTERS]) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Filters form invalid.\n{form_filters.errors}'}) - filters_form = Filters_Product_Category.from_form(form_filters) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}' + }) + # filters_form = Filters_Product_Category.from_form(form_filters) categories = data[Model_View_Store_Product_Category.FLAG_PRODUCT_CATEGORY] if len(categories) == 0: - return jsonify({'status': 'failure', 'Message': f'No categories.'}) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.FLAG_MESSAGE: f'No categories.' + }) objsCategory = [] for category in categories: objsCategory.append(Product_Category.from_json(category)) @@ -77,9 +105,15 @@ def save_category(): print(f'objsCategory={objsCategory}') Model_View_Store_Product_Category.save_categories(data.get('comment', 'No comment'), objsCategory) - model_return = Model_View_Store_Product_Category(filters_category=filters_form) + model_return = Model_View_Store_Product_Category(form_filters=form_filters) print('nips') - return jsonify({'status': 'success', 'Success': True, 'data': model_return.category_list.to_json_str()}) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.KEY_DATA: model_return.category_list.to_json() + }) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({ + Model_View_Store_Product_Category.FLAG_STATUS: Model_View_Store_Product_Category.FLAG_SUCCESS, + Model_View_Store_Product_Category.FLAG_MESSAGE: f'Bad data received by controller.\n{e}' + }) \ No newline at end of file diff --git a/routing/store/product_permutation.py b/routing/store/product_permutation.py index ba330a3b..55b45281 100644 --- a/routing/store/product_permutation.py +++ b/routing/store/product_permutation.py @@ -39,7 +39,7 @@ routes_store_product_permutation = Blueprint('routes_store_product_permutation', def permutation(): filters = Filters_Product.get_default() model = Model_View_Store_Product_Permutation(filters_product=filters) - return render_template('_page_store_product_permutations.html', model = model) + return render_template('pages/store/_product_permutations.html', model = model) @routes_store_product_permutation.route('/store/permutation_filter', methods=['POST']) def permutation_filter(): @@ -48,13 +48,13 @@ def permutation_filter(): try: form_filters = get_Form_Filters_Permutation(data) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Form invalid.\n{form_filters.errors}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'}) # ToDo: manually validate category, product filters_form = Filters_Product.from_form(form_filters) model = Model_View_Store_Product_Permutation(filters_product=filters_form) - return jsonify({'status': 'success', 'Success': True, 'data': model.category_list.to_list_rows_permutation()}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model.category_list.to_permutation_row_list()}) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) def get_Form_Filters_Permutation(data_request): data_form = data_request[Model_View_Store_Product_Permutation.KEY_FORM] @@ -69,11 +69,11 @@ def permutation_save(): try: form_filters = get_Form_Filters_Permutation(data) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Filters form invalid.\n{form_filters.errors}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'}) permutations = data[Model_View_Store_Product_Permutation.KEY_PERMUTATIONS] if len(permutations) == 0: - return jsonify({'status': 'failure', 'Message': f'No permutations.'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'No permutations.'}) objsPermutation = [] for permutation in permutations: objsPermutation.append(Product_Permutation.from_json(permutation)) @@ -84,7 +84,7 @@ def permutation_save(): model_save.save_permutations(data.comment, objsPermutation) model_return = Model_View_Store_Product_Permutation(filters_product=filters_form) - return jsonify({'status': 'success', 'Success': True, 'data': model_return.category_list.to_list_rows_permutation()}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model_return.category_list.to_permutation_row_list()}) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) \ No newline at end of file diff --git a/routing/store/stock_item.py b/routing/store/stock_item.py index 368f4c1c..4941b161 100644 --- a/routing/store/stock_item.py +++ b/routing/store/stock_item.py @@ -38,7 +38,7 @@ routes_store_stock_item = Blueprint('routes_store_stock_item', __name__) def stock(): filters = Stock_Item_Filters.get_default() model = Model_View_Store_Stock_Items(filters_stock_item=filters) - return render_template('_page_store_stock_items.html', model = model) + return render_template('pages/store/_stock_items.html', model = model) @routes_store_stock_item.route('/store/stock_item_filter', methods=['POST']) def stock_filter(): @@ -47,13 +47,13 @@ def stock_filter(): try: form_filters = get_form_filters_stock_items(data) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Form invalid.\n{form_filters.errors}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Form invalid.\n{form_filters.errors}'}) # ToDo: manually validate category, product filters_form = Stock_Item_Filters.from_form(form_filters) model = Model_View_Store_Stock_Items(filters_stock_item=filters_form) - return jsonify({'status': 'success', 'Success': True, 'data': model.category_list.to_list_rows_permutation()}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model.category_list.to_permutation_row_list()}) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) def get_form_filters_stock_items(data_request): data_form = data_request[Model_View_Store_Stock_Items.KEY_FORM] @@ -69,12 +69,12 @@ def stock_save(): try: form_filters = get_form_filters_stock_items(data) if not form_filters.validate_on_submit(): - return jsonify({'status': 'failure', 'Message': f'Filters form invalid.\n{form_filters.errors}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Filters form invalid.\n{form_filters.errors}'}) stock_items = data[Model_View_Store_Stock.KEY_PERMUTATIONS] print(f'stock_items: {stock_items}') if len(stock_items) == 0: - return jsonify({'status': 'failure', 'Message': f'No stock items.'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'No stock items.'}) objsStockItem = [] for stock_item in stock_items: objsStockItem.append(Product_Permutation.from_json(stock_item)) @@ -86,7 +86,7 @@ def stock_save(): model_save.save_stock_items(data.comment, objsPermutation) model_return = Model_View_Store_Stock(filters_product=filters_form) - return jsonify({'status': 'success', 'Success': True, 'data': model_return.category_list.to_list_rows_permutation()}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, 'Success': True, Model_View_Base.KEY_DATA: model_return.category_list.to_permutation_row_list()}) except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) """ diff --git a/routing/store/store.py b/routing/store/store.py new file mode 100644 index 00000000..f97b4a32 --- /dev/null +++ b/routing/store/store.py @@ -0,0 +1,30 @@ +""" +Project: PARTS Website +Author: Edward Middleton-Smith + Precision And Research Technology Systems Limited + +Technology: App Routing +Feature: Store Routes + +Description: +Initializes the Flask application, sets the configuration based on the environment, and defines two routes (/ and /about) that render templates with the specified titles. +""" + +# IMPORTS +# internal +from models.model_view_store import Model_View_Store +# external +from flask import Flask, render_template, jsonify, request, render_template_string, send_from_directory, redirect, url_for, session, Blueprint, current_app +from extensions import db, oauth +from urllib.parse import quote_plus, urlencode +from authlib.integrations.flask_client import OAuth +from authlib.integrations.base_client import OAuthError +from urllib.parse import quote, urlparse, parse_qs + +routes_store = Blueprint('routes_store', __name__) + +@routes_store.route(Model_View_Store.HASH_SCRIPTS_SECTION_STORE, methods=['GET']) +def scripts_section_store(): + hash_page_current = request.args.get('hash_page_current', default = Model_View_Store.HASH_SCRIPTS_SECTION_STORE, type = str) + model = Model_View_Store(hash_page_current=hash_page_current) + return render_template('js/sections/store.js', model = model) \ No newline at end of file diff --git a/routing/store/supplier.py b/routing/store/supplier.py index 2d520c64..4c4e9500 100644 --- a/routing/store/supplier.py +++ b/routing/store/supplier.py @@ -59,10 +59,10 @@ def supplier(): permutation_id, quantity = model.import_JSON_basket_item(data, form) model.basket_item_edit(permutation_id, quantity, False) # new_basket = except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Bad data received by controller.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Bad data received by controller.\n{e}'}) # return jsonify(Success = True, data = { html_block: render_template(), Model_View_Store.key_basket: new_basket }) # html_block = render_template('_block_store_basket.html', model = model) # print(f'html_block:\n{html_block}') # return jsonify(Success = True, data = { 'html_block': html_block, 'basket': {'items': model.basket.to_json_list()}}) - return render_template('_page_supplier.html', model = model) - return jsonify({'status': 'failure', 'Message': f'Invalid supplier details.\n{form.errors}'}) + return render_template('pages/store/_supplier.html', model = model) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Invalid supplier details.\n{form.errors}'}) diff --git a/routing/user.py b/routing/user.py index 2cb83803..72a24b60 100644 --- a/routing/user.py +++ b/routing/user.py @@ -63,7 +63,7 @@ def login(): Query Parameters: {query_params} """) - return jsonify({'Success': True, 'status': 'success', f'{Model_View_Base.KEY_CALLBACK}': headers}) + return jsonify({'Success': True, Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS, f'{Model_View_Base.KEY_CALLBACK}': headers}) @routes_user.route("/login_callback") # / def login_callback(): @@ -117,7 +117,7 @@ def login_callback(): print(f'user session: {session[Model_View_Base.KEY_USER]}') return redirect(f'{current_app.config['URL_HOST']}{hash_callback}') except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Controller error.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Controller error.\n{e}'}) @routes_user.route("/logout") def logout(): @@ -156,14 +156,14 @@ def logout_callback(): print(f'user session: {session[Model_View_Base.KEY_USER]}') return redirect(f'{current_app.URL_HOST}{hash_callback}') except Exception as e: - return jsonify({'status': 'failure', 'Message': f'Controller error.\n{e}'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.STATUS_FAILURE, Model_View_Base.FLAG_MESSAGE: f'Controller error.\n{e}'}) @routes_user.route("/user") def user(): try: model = Model_View_User(current_app, db) - html_body = render_template('_page_user.html', model = model) + html_body = render_template('pages/user/_user.html', model = model) except Exception as e: return str(e) return html_body diff --git a/static/MySQL/1202_tbl_Shop_Product_Category_Temp.sql b/static/MySQL/1202_tbl_Shop_Product_Category_Temp.sql index f033892d..e8667b07 100644 --- a/static/MySQL/1202_tbl_Shop_Product_Category_Temp.sql +++ b/static/MySQL/1202_tbl_Shop_Product_Category_Temp.sql @@ -14,6 +14,4 @@ CREATE TABLE IF NOT EXISTS Shop_Product_Category_Temp ( , display_order INT NOT NULL , id_access_level_required INT NOT NULL DEFAULT 1 , guid BINARY(36) NOT NULL - , created_on TIMESTAMP NOT NULL - , created_by INT NOT NULL ); diff --git a/static/MySQL/7003_p_shop_get_many_access_level.sql b/static/MySQL/7003_p_shop_get_many_access_level.sql index 1dd4279c..9cd0b285 100644 --- a/static/MySQL/7003_p_shop_get_many_access_level.sql +++ b/static/MySQL/7003_p_shop_get_many_access_level.sql @@ -16,23 +16,22 @@ DROP PROCEDURE IF EXISTS p_shop_get_many_access_level; DELIMITER // CREATE PROCEDURE p_shop_get_many_access_level ( - IN a_get_inactive_access_level BIT + IN a_id_user INT, + IN a_get_inactive_access_level BIT ) BEGIN - IF a_get_inactive_access_level IS NULL THEN - SET a_get_inactive_access_level = 0; - END IF; + SET a_get_inactive_access_level = IFNULL(a_get_inactive_access_level, 0); SELECT AL.id_access_level, - AL.code, - AL.name, - AL.active, - AL.priority, - AL.display_order + AL.code, + AL.name, + AL.active, + AL.priority, + AL.display_order FROM Shop_Access_Level AL WHERE - a_get_inactive_access_level = 1 + a_get_inactive_access_level = 1 OR AL.active = 1 ORDER BY AL.display_order ; diff --git a/static/MySQL/7200_p_shop_save_product_category.sql b/static/MySQL/7200_p_shop_save_product_category.sql index 422e310f..84cecf5b 100644 --- a/static/MySQL/7200_p_shop_save_product_category.sql +++ b/static/MySQL/7200_p_shop_save_product_category.sql @@ -111,7 +111,7 @@ BEGIN , IFNULL(PC_T.code, PC.code) AS code , IFNULL(PC_T.name, PC.code) AS name , IFNULL(PC_T.description, PC.description) AS description - , PC_T.id_access_level_required AS id_access_level_required + , IFNULL(PC_T.id_access_level_required, PC.id_access_level_required) AS id_access_level_required , IFNULL(PC_T.active, PC.active) AS active , IFNULL(PC_T.display_order, PC.display_order) AS display_order , IFNULL(PC_T.name, IFNULL(PC.name, IFNULL(PC_T.code, IFNULL(PC.code, IFNULL(PC_T.id_category, '(No Product Category)'))))) AS name_error diff --git a/static/MySQL/7204_p_shop_get_many_product.sql b/static/MySQL/7204_p_shop_get_many_product.sql index 725251ab..6b20ac92 100644 --- a/static/MySQL/7204_p_shop_get_many_product.sql +++ b/static/MySQL/7204_p_shop_get_many_product.sql @@ -325,14 +325,16 @@ BEGIN , PC.name , PC.description , PC.id_access_level_required + , AL.name AS name_access_level_required , PC.display_order , PC.active , MIN(t_P.can_view) AS can_view , MIN(t_P.can_edit) AS can_edit , MIN(t_P.can_admin) AS can_admin FROM tmp_Category t_C - INNER JOIN Shop_product_category PC ON t_C.id_category = PC.id_category + INNER JOIN Shop_Product_Category PC ON t_C.id_category = PC.id_category LEFT JOIN tmp_Product t_P ON t_C.id_category = t_P.id_product + INNER JOIN Shop_Access_Level AL ON PC.id_access_level_required = AL.id_access_level GROUP BY t_C.id_category -- , t_P.id_product ORDER BY PC.display_order ; @@ -344,6 +346,7 @@ BEGIN P.name, P.has_variations, P.id_access_level_required, + AL.name AS name_access_level_required, P.active, P.display_order, t_P.can_view, @@ -352,6 +355,7 @@ BEGIN FROM tmp_Product t_P INNER JOIN Shop_Product P ON t_P.id_product = P.id_product INNER JOIN tmp_Category t_C ON t_P.id_category = t_C.id_category + INNER JOIN Shop_Access_Level AL ON P.id_access_level_required = AL.id_access_level GROUP BY t_P.id_category, t_C.display_order, t_P.id_product, t_P.can_view, t_P.can_edit, t_P.can_admin ORDER BY t_C.display_order, P.display_order ; diff --git a/static/css/pages/page_home.css b/static/css/home.css similarity index 100% rename from static/css/pages/page_home.css rename to static/css/home.css diff --git a/static/css/pages/page_admin_home.css b/static/css/pages/core/admin_home.css similarity index 100% rename from static/css/pages/page_admin_home.css rename to static/css/pages/core/admin_home.css diff --git a/static/css/pages/page_contact.css b/static/css/pages/core/contact.css similarity index 100% rename from static/css/pages/page_contact.css rename to static/css/pages/core/contact.css diff --git a/static/css/pages/core/home.css b/static/css/pages/core/home.css new file mode 100644 index 00000000..73a09151 --- /dev/null +++ b/static/css/pages/core/home.css @@ -0,0 +1,25 @@ + +.page-body > * { + height: 100%; +} +#pageBody > * :first-child{ + margin-top: 25vh; +} +#pageBody > * :last-child { + margin-bottom: 35vh; +} + +.img-demo { + max-width: 50%; + min-width: 500px; +} + +.img-featured { + width: 100%; +} + +/* +img { + background-image: url("/static/images/Tag_Molly1.png"); +} +*/ \ No newline at end of file diff --git a/static/css/pages/page_services.css b/static/css/pages/core/services.css similarity index 100% rename from static/css/pages/page_services.css rename to static/css/pages/core/services.css diff --git a/static/css/pages/page_license.css b/static/css/pages/legal/license.css similarity index 100% rename from static/css/pages/page_license.css rename to static/css/pages/legal/license.css diff --git a/static/css/pages/store/home.css b/static/css/pages/store/home.css new file mode 100644 index 00000000..e69de29b diff --git a/static/css/pages/page_store_product_categories.css b/static/css/pages/store/product_categories.css similarity index 89% rename from static/css/pages/page_store_product_categories.css rename to static/css/pages/store/product_categories.css index 0cc03cd9..5872ca5b 100644 --- a/static/css/pages/page_store_product_categories.css +++ b/static/css/pages/store/product_categories.css @@ -1,7 +1,7 @@ td.display-order, th.display-order { - width: 10% !important; + width: 8% !important; } td.code, th.code { width: 15% !important; @@ -10,10 +10,13 @@ td.name, th.name { width: 25% !important; } td.description, th.description { - width: 40% !important; + width: 35% !important; +} +td.access_level, th.access_level { + width: 10% !important; } td.active, th.active { - width: 10% !important; + width: 7% !important; } /* diff --git a/static/css/pages/page_store_product_permutations.css b/static/css/pages/store/product_permutations.css similarity index 100% rename from static/css/pages/page_store_product_permutations.css rename to static/css/pages/store/product_permutations.css diff --git a/static/css/pages/page_store_stock_items.css b/static/css/pages/store/stock_items.css similarity index 100% rename from static/css/pages/page_store_stock_items.css rename to static/css/pages/store/stock_items.css diff --git a/static/css/sections/core.css b/static/css/sections/core.css new file mode 100644 index 00000000..e69de29b diff --git a/static/css/store_shared.css b/static/css/store_shared.css new file mode 100644 index 00000000..11a7d43d --- /dev/null +++ b/static/css/store_shared.css @@ -0,0 +1,52 @@ +.img-product { + max-width: 20vh; + max-height: 20vh; + border-radius: 3vh; + justify-self: left; +} + +.img-thumbnail { + max-width: 10vh; + max-height: 10vh; + border-radius: 3vh; + justify-self: left; +} + +.buttonAdd2Basket { + background-color: var(--c_blue_pastel); + color: var(--c_blue_dark); + border-color: var(--c_blue_dark); +} + +#buttonCheckout, .buttonBuyNow { + background-color: var(--c_purple_pastel); + color: var(--c_purple_dark); + border-color: var(--c_purple_dark); +} + +.button-increment, .button-decrement { + border: 2px solid darkgrey; + background-color: lightgray; + margin: 1vh 1vh; + width: 2.5vh; + height: 2.5vh; + border-radius: 1.25vh; + font-size: 2vh; +} + +.container-input > input { + padding: 0vh 1vh; + border-radius: 0.5vh; + max-width: 7vh; +} + +#basket { + max-width: 100%; +} + + + +/* Right column */ +.rightcolumn { + min-width: fit-content; +} \ No newline at end of file diff --git a/static/css/stylesheet.css b/static/css/stylesheet.css new file mode 100644 index 00000000..5818ec66 --- /dev/null +++ b/static/css/stylesheet.css @@ -0,0 +1,86 @@ +* { + box-sizing: border-box; +} + +body { + padding: 10px; + display: block; + background-color: grey; +} + +.banner { + background-color: black; + color: white; + width: 100%; + position: fixed; + padding-top: 5vh; + padding-bottom: 10vh; +} + +.banner.top { + background-color: black; + color: white; +} + +.banner.bottom { + background-color: black; + color: white; + bottom: 0; +} + +.row:after { + content: ""; + display: table; + clear: both; +} + +.column { + float: left; + padding: 5vw; +} + +.column.side { + width: 25%; +} + +.column.middle { + width: 50%; +} + +.midbod { + background-color: white; + color: black; +} + +.panel { + float: left; +} + +img { + height: 100px; + width: 100px; +} + +.panel.labelcontainer { + background-color: black; + color: white; + text-align: center; +} + +.label { + font-family: Arial, Helvetica, sans-serif; + text-decoration: none; +} + +.label.bodytext { + background-color: black; + color: white; + text-decoration: none; + font-style: normal; + font-size: 12; +} + +.label.title { + font-style: bold; + font-size: 18; +} \ No newline at end of file diff --git a/static/css/themes/dark.css b/static/css/themes/dark.css index 016ced9b..5c30a951 100644 --- a/static/css/themes/dark.css +++ b/static/css/themes/dark.css @@ -27,10 +27,10 @@ --nav-hover-text: #bb86fc; /* Buttons */ - --btn-primary-bg: #bb86fc; - --btn-primary-text: #121212; - --btn-secondary-bg: #03dac6; - --btn-secondary-text: #121212; + --Button-primary-bg: #bb86fc; + --Button-primary-text: #121212; + --Button-secondary-bg: #03dac6; + --Button-secondary-text: #121212; /* Forms */ --input-bg: #2c2c2c; diff --git a/static/css/themes/light.css b/static/css/themes/light.css index 48fe8c55..e46bc225 100644 --- a/static/css/themes/light.css +++ b/static/css/themes/light.css @@ -27,10 +27,10 @@ --nav-hover-text: #007bff; /* Buttons */ - --btn-primary-bg: #007bff; - --btn-primary-text: #ffffff; - --btn-secondary-bg: #6c757d; - --btn-secondary-text: #ffffff; + --Button-primary-bg: #007bff; + --Button-primary-text: #ffffff; + --Button-secondary-bg: #6c757d; + --Button-secondary-text: #ffffff; /* Forms */ --input-bg: #ffffff; diff --git a/static/docs/naming conventions.txt b/static/docs/naming conventions.txt new file mode 100644 index 00000000..8bb6f7bb --- /dev/null +++ b/static/docs/naming conventions.txt @@ -0,0 +1,119 @@ +Precision and Research Technology Systems Limited +Naming Conventions + + +Language: CSS +File naming convention: + kebab-case + lowercase + + +Language: HTML +File naming convention: + prefix with underscore for templates + snake_case + lowercase + + +Language: JavaScript +Variable naming convention: + prefix with underscore for private variables + camelCase for mutable variables + uppercase with underscore spacing for constants + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Function naming convention: + camelCase + verb is first word + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Class naming convention: + PascalCase (UpperCamelCase) + singular noun or noun phrase +File naming convention: + kebab-case + lowercase + suffix with type for type hinting +Folder naming convention: + kebab-case + lowercase + + +Language: MySQL +Database naming convention: + snake_case + lowercase +Variable naming convention: + lowercase and prefix with 'v_' for mutable variables + uppercase and prefix with 'C_' for constants + snake_case + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Function, Store Procedure, Trigger, and View naming convention: + prefix with 'fn_' for functions + prefix with 'vw_' for views + prefix with 'p_' for stored procedures + prefix with 'tri_' for triggers + suffix with action then event timing for triggers + lowercase + snake_case + verb is first word + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Table naming convention: + prefix with project + prefix with 'tmp' for temporary tables + singular noun or noun phrase + Upper_Snake_Case +Column naming convention: + prefix with project + prefix with 'idx_' for indices + singular noun or noun phrase + snake_case + lowercase +Constraint naming convention: + prefix with 'pk_' for primary keys + prefix with 'fk_' for foreign keys + prefix with 'chk_' for check + singular noun or noun phrase + snake_case + lowercase +File naming convention: + snake_case + lowercase + suffix with type for type hinting +Folder naming convention: + kebab-case + lowercase + + +Language: Python +Variable naming convention: + prefix with underscore for private variables + prefix with double underscore for private variables that are not inherited + lowercase for mutable variables + uppercase for constants + snake_case + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Function naming convention: + lowercase + snake_case + verb is first word + top-down heirarchy of objects flows left to right + suffix with type for type hinting +Class naming convention: + suffix with 'Base' for base classes + prefix with 'Abstract' for abstract classes + prefix with 'Abstract' for abstract classes + PascalCase (UpperCamelCase) + singular noun or noun phrase +File naming convention: + snake_case + lowercase + suffix with type for type hinting +Folder naming convention: + snake_case + lowercase + + diff --git a/static/docs/server.py b/static/docs/server.py index 13733752..8b30117e 100644 --- a/static/docs/server.py +++ b/static/docs/server.py @@ -118,7 +118,7 @@ def webhook_received(): if event_type == 'checkout.session.completed': print('🔔 Payment succeeded!') - return jsonify({'status': 'success'}) + return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS}) if __name__ == '__main__': app.run(port=4242, debug=True) \ No newline at end of file diff --git a/static/js/accessibility_statement.js b/static/js/accessibility_statement.js new file mode 100644 index 00000000..1a4f23ab --- /dev/null +++ b/static/js/accessibility_statement.js @@ -0,0 +1,5 @@ +var _loading = true; + +function hookupPageAccessibilityStatement() { + _loading = false; +} diff --git a/static/js/api.js b/static/js/api.js index ffe3012a..59f9ebd7 100644 --- a/static/js/api.js +++ b/static/js/api.js @@ -8,8 +8,8 @@ export default class API { return document.querySelector(idCSRFToken).getAttribute('content'); } - static async request(hashEndpoint, method = 'GET', data = null) { - const url = API.getUrlFromHash(hashEndpoint); + static async request(hashEndpoint, method = 'GET', data = null, params = null) { + const url = API.getUrlFromHash(hashEndpoint, params); const options = { method, headers: { @@ -36,11 +36,25 @@ export default class API { } } - static getUrlFromHash(hash) { + static getUrlFromHash(hash, params = null) { if (hash == null) hash = hashPageHome; console.log("getUrlFromHash:"); - console.log("base url: " + _pathHost + "\nhash: " + hash); - return _pathHost + hash; + console.log("base url: " + _pathHost + "\nhash: " + hash + '\nparams: ' + params); + let url = _pathHost + hash; + if (params) { + url += '?' + new URLSearchParams(params).toString(); + } + console.log("url: " + url); + return url; + } + + static goToUrl(url) { + window.location.href = url; + } + + static goToHash(hash, params = null) { + const url = API.getUrlFromHash(hash, params); + API.goToUrl(url); } @@ -63,14 +77,18 @@ export default class API { static async getCategories() { return await API.request(hashGetStoreProductCategory); } - static async getCategoriesByFilters(formFilters) { + static async getCategoriesByFilters(filtersJson) { + /* let dataRequest = {}; - dataRequest[keyForm] = DOM.convertForm2JSON(formFilters); + dataRequest[keyForm] = filtersJson; return await API.request(hashGetStoreProductCategory, 'POST', dataRequest); + */ + // return await API.request(hashPageStoreProductCategories, 'GET', filtersJson); + API.goToHash(hashPageStoreProductCategories, filtersJson); } static async saveCategories(categories, formFilters, comment) { let dataRequest = {}; - dataRequest[keyForm] = DOM.convertForm2JSON(formFilters); + dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters); dataRequest[flagCategory] = categories; dataRequest[flagComment] = comment; return await API.request(hashSaveStoreProductCategory, 'POST', dataRequest); diff --git a/static/js/app.js b/static/js/app.js index a1de1fd3..93058223 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -38,8 +38,11 @@ class App { initPageCurrent() { console.log("initPageCurrent"); + /* _pageCurrent = Router.getPageCurrent(); _pageCurrent.initialize(); + */ + this.router.loadPageCurrent(); } } diff --git a/static/js/dom.js b/static/js/dom.js index 8ee9e90f..e7868ee7 100644 --- a/static/js/dom.js +++ b/static/js/dom.js @@ -44,17 +44,22 @@ export default class DOM { pageBody.innerHTML = contentNew; } static getHashPageCurrent() { - return document.body.dataset.page; + const hashPageCurrent = document.body.dataset.page; + console.log("hashPageCurrent: " + hashPageCurrent); + return hashPageCurrent; } static isElementDirty(element) { element.setAttribute(attrValueCurrent, DOM.getElementValueCurrent(element)); let isDirty = element.getAttribute(attrValuePrevious) != element.getAttribute(attrValueCurrent); + DOM.handleDirtyElement(element, isDirty); + return isDirty; + } + static handleDirtyElement(element, isDirty) { if (isDirty) { element.classList.add(flagDirty); } else { element.classList.remove(flagDirty); } - return isDirty; } static getElementValueCurrent(element) { let returnVal = ''; @@ -99,5 +104,7 @@ export default class DOM { } } */ - + /* non-static method on page object to use + static handleChangeElement(element) {} + */ } diff --git a/static/js/lib/main.js b/static/js/lib/main.js new file mode 100644 index 00000000..d4970fa0 --- /dev/null +++ b/static/js/lib/main.js @@ -0,0 +1,65 @@ +// main.js + +import { initializeAPI } from './shared/api.js'; +import { setupEventListeners } from './shared/events.js'; +import { initializeComponents } from './components/componentInitializer.js'; +import { router } from './shared/router.js'; +import { CONFIG } from './config/config.js'; + +// DOM ready function +function domReady(fn) { + if (document.readyState !== 'loading') { + fn(); + } else { + document.addEventListener('DOMContentLoaded', fn); + } +} + +// Main initialization function +function initializeApp() { + console.log('Initializing application...'); + + // Initialize API with base URL + initializeAPI(CONFIG.API_BASE_URL); + + // Setup global event listeners + setupEventListeners(); + + // Initialize reusable components + initializeComponents(); + + // Initialize router + router.init(); + + // Page-specific initialization + const currentPage = document.body.dataset.page; + switch (currentPage) { + case 'home': + import('./pages/home.js').then(module => module.initHomePage()); + break; + case 'about': + import('./pages/about.js').then(module => module.initAboutPage()); + break; + case 'contact': + import('./pages/contact.js').then(module => module.initContactPage()); + break; + default: + console.log('No specific initialization for this page'); + } + + console.log('Application initialized'); +} + +// Run the initialization when the DOM is ready +domReady(initializeApp); + +// Expose a global app object if needed +window.app = { + // Add methods or properties that need to be globally accessible + reloadPage: () => { + window.location.reload(); + }, + navigateTo: (url) => { + router.navigateTo(url); + } +}; \ No newline at end of file diff --git a/static/js/lib/validation.js b/static/js/lib/validation.js index 0bffd2df..88940d99 100644 --- a/static/js/lib/validation.js +++ b/static/js/lib/validation.js @@ -126,6 +126,22 @@ function arrayContainsItem(array, itemValue) { function dictHasKey(d, k) { return (k in d); } +function areEqualDicts(dict1, dict2) { + const keys1 = Object.keys(dict1); + const keys2 = Object.keys(dict2); + + if (keys1.length !== keys2.length) { + return false; + } + + for (let key of keys1) { + if (dict1[key] !== dict2[key]) { + return false; + } + } + + return true; + } function imageExists(url, callback) { diff --git a/static/js/pages/page_base.js b/static/js/pages/base.js similarity index 95% rename from static/js/pages/page_base.js rename to static/js/pages/base.js index df5114c7..10500456 100644 --- a/static/js/pages/page_base.js +++ b/static/js/pages/base.js @@ -1,11 +1,12 @@ import API from "../api.js"; +import DOM from "../dom.js"; import { router } from "../router.js"; -export class PageBase { +export class BasePage { constructor() { this.title = titlePageCurrent; // this.hash = hashPageCurrent; - if (this.constructor === PageBase) { + if (this.constructor === BasePage) { throw new Error("Cannot instantiate abstract class"); } @@ -15,7 +16,7 @@ export class PageBase { } initialize() { - throw new Error("Method 'init()' must be implemented."); + throw new Error("Method 'initialize()' must be implemented."); } sharedInitialize() { @@ -237,10 +238,16 @@ export class PageBase { leave() { console.log('Leaving ' + this.title + ' page'); _pageCurrent = null; - if (this.constructor === PageBase) { + if (this.constructor === BasePage) { throw new Error("Must implement leave() method."); } } + setLocalStoragePage(dataPage) { + setLocalStorage(this.constructor.hash, dataPage); + } + getLocalStoragePage() { + return getLocalStorage(this.constructor.hash); + } toggleShowButtonsSaveCancel(show, buttonSave = null, buttonCancel = null) { if (buttonSave == null) buttonSave = document.querySelector('form.' + flagFilter + ' button.' + flagSave); @@ -254,14 +261,6 @@ export class PageBase { } } - refreshDisplayOrders() { - let rows = document.querySelectorAll(idTableMain + 'tbody tr.' + flagRow); - rows.forEach((row, indexRow) => { - sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); - sliderDisplayOrder.setAttribute(attrValueCurrent, indexRow); - }); - } - static isDirtyFilter(filter) { let isDirty = DOM.isElementDirty(filter); if (isDirty) document.querySelectorAll(idTableMain + ' tbody tr').remove(); diff --git a/static/js/pages/base_table.js b/static/js/pages/base_table.js new file mode 100644 index 00000000..c95a149c --- /dev/null +++ b/static/js/pages/base_table.js @@ -0,0 +1,483 @@ + + +import { BasePage } from "./base.js"; +import API from "../api.js"; +import DOM from "../dom.js"; + +export class TableBasePage extends BasePage { + // callFilterTableContent + // callSaveTableContent + + constructor() { + super(); + /* + if (!this.constructor.callFilterTableContent) { + throw new Error(`Class ${this.constructor.name} must have a static callFilterTableContent method attribute that takes a single argument - the filters as json.`); + } + if (!this.constructor.callSaveTableContent) { + throw new Error(`Class ${this.constructor.name} must have a static callSaveTableContent method attribute that takes 3 arguments - a list of records, the filters as json, and a comment for saving.`); + } + this.initialize(); + // this.hookupFilters(); + this.loadRowTable(null); + this.getJsonRow(null); + // this.hookupTableMain(); + this.isDirtyRow(null); + this.getTableRecords(); + this.leave(); + */ + // this.cursorXInitial = null; + this.cursorYInitial = null; + this.rowInitial = null; + this.placeholder = null; + this.dragSrcEl = null; + this.dragSrcRow = null; + + } + + initialize(isPopState = false) { + if (this.constructor === TableBasePage) { + throw new Error("Must implement initialize() method."); + } + if (!isPopState) { + this.sharedInitialize(); + this.hookupFilters(); + this.hookupButtonsAddSaveCancel(); + this.hookupTableMain(); + hookupOverlayConfirm(() => { + this.leave(); + this.saveRecordsTableDirty(); + }); + } else { + let dataPage = this.getLocalStoragePage(); + let filters = dataPage[flagFormFilters]; + let formFilters = this.getFormFilters(); + let filtersDefault = DOM.convertForm2JSON(formFilters); + if (!areEqualDicts(filters, filtersDefault)) { + + } + } + } + hookupFilters() { + if (this.constructor === TableBasePage) { + throw new Error("Subclass of TableBasePage must implement method hookupFilters()."); + } + this.hookupButtonApplyFilters(); + } + hookupFilterActive() { + initialiseEventHandler(idFormFilters + '.' + flagActive, flagInitialised, (filter) => { + filter.addEventListener("change", (event) => { + TableBasePage.isDirtyFilter(filter); + }); + }); + } + static isDirtyFilter(filter) { + let isDirty = DOM.isElementDirty(filter); + if (isDirty) { + let tbody = document.querySelector(idTableMain + ' tbody'); + tbody.querySelectorAll('tr').remove(); + tbody.appendChild(document.createElement('
Press "Apply Filters" to refresh the table.
')); + } + return isDirty; + } + hookupButtonApplyFilters() { + initialiseEventHandler(idButtonApplyFilters, flagInitialised, (button) => { + button.addEventListener("click", (event) => { + event.stopPropagation(); + this.getAndLoadFilteredTableContent(); + }); + }); + } + getAndLoadFilteredTableContent() { + let formFilters = this.getFormFilters(); + let filtersJson = DOM.convertForm2JSON(formFilters); + this.callFilterTableContent(filtersJson) + /* + .then(data => { + console.log('Table data received:', data); + this.callbackLoadTableContent(data); + }) + */ + .catch(error => console.error('Error:', error)); + } + getFormFilters() { + return document.querySelector(idFormFilters); + } + callbackLoadTableContent(response) { + let table = this.getTableMain(); + let bodyTable = table.querySelector('tbody'); + bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); }); + let rowsJson = response.data[flagRows]; + if (!isEmpty(rowsJson) && rowsJson.every(row => row.hasOwnProperty('display_order'))) { + rowsJson = rowsJson.sort((a, b) => a.display_order - b.display_order); + } + rowsJson.forEach(this.loadRowTable.bind(this)); + this.hookupTableMain(); + } + getTableMain() { + return document.querySelector(idTableMain); + } + loadRowTable(rowJson) { + throw new Error("Subclass of TableBasePage must implement method loadRowTable()."); + } + hookupButtonsAddSaveCancel() { + this.hookupButtonSave(); + this.hookupButtonCancel(); + this.hookupButtonAddRowTable(); + } + saveRecordsTableDirty() { + let records = this.getTableRecords(true); + if (records.length == 0) { + showOverlayError('No records to save'); + return; + } + let formElement = this.getFormFilters(); + let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm)); + this.callSaveTableContent(records, formElement, comment) + .then(data => { + if (data[flagStatus] == flagSuccess) { + console.log('Data received:', data); + this.callbackLoadTableContent(data); + console.log('Records saved!'); + } + else { + showOverlayError(data[flagMessage]); + } + }) + .catch(error => console.error('Error:', error)); + } + getTableRecords(dirtyOnly = false) { + let table = this.getTableMain(); + let records = []; + let record; + table.querySelectorAll('tbody tr').forEach((row) => { + if (dirtyOnly && !row.classList.contains(flagDirty)) return; + record = this.getJsonRow(row); + records.push(record); + }); + return records; + } + getJsonRow(row) { + throw new Error("Subclass of TableBasePage must implement method getJsonRow()."); + } + hookupButtonCancel() { + initialiseEventHandler(idFormFilters + ' button.' + flagCancel, flagInitialised, function(button) { + button.addEventListener("click", function(event) { + event.stopPropagation(); + getAndLoadFilteredTableContent(); + }); + button.classList.add(flagCollapsed); + }); + } + hookupButtonAddRowTable() { + initialiseEventHandler(idFormFilters + ' button.' + flagAdd, flagInitialised, (button) => { + button.addEventListener("click", (event) => { + event.stopPropagation(); + let tbody = document.querySelector(idTableMain + ' tbody'); + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagInitialised); + row.querySelectorAll('.' + flagInitialised).forEach(function(element) { + element.classList.remove(flagInitialised); + }); + let newDisplayOrder = parseInt(tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider).getAttribute(attrValueCurrent)) + 1; + tbody.appendChild(row); + let slider = tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + if (slider) { + slider.setAttribute(attrValueCurrent, newDisplayOrder); + slider.setAttribute(attrValuePrevious, newDisplayOrder); + } + this.hookupTableMain(); + }); + }); + } + hookupTableMain() { + if (this.constructor === TableBasePage) { + throw new Error("Must implement hookupTableMain() method."); + } + if (_rowBlank == null) { + this.cacheRowBlank(); + } + } + cacheRowBlank() { + let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew; + let rowBlankTemp = document.querySelector(selectorRowNew); + console.log("row blank temp: ", rowBlankTemp); + _rowBlank = rowBlankTemp.cloneNode(true); + document.querySelectorAll(selectorRowNew).forEach(function(row) { + row.remove(); + }); + } + hookupSlidersDisplayOrderTable() { + let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder + ' input.' + flagSlider + '.' + flagDisplayOrder; + initialiseEventHandler(selectorDisplayOrder, flagInitialised, (sliderDisplayOrder) => { + /* + sliderDisplayOrder.setAttribute('draggable', true); + sliderDisplayOrder.addEventListener('dragstart', this.handleDragSliderStart.bind(this), false); + sliderDisplayOrder.addEventListener('dragenter', this.handleDragSliderEnter.bind(this), false); + sliderDisplayOrder.addEventListener('dragover', this.handleDragSliderOver.bind(this), false); + sliderDisplayOrder.addEventListener('dragleave', this.handleDragSliderLeave.bind(this), false); + sliderDisplayOrder.addEventListener('drop', this.handleDropSlider.bind(this), false); + sliderDisplayOrder.addEventListener('dragend', this.handleDragSliderEnd.bind(this), false); + */ + sliderDisplayOrder.addEventListener('change', (event) => { + console.log("slider change event"); + this.handleChangeElementCellTable(sliderDisplayOrder); + }); + }); + } + /* ToDo: Fix this slider drag and drop functionality + handleDragSliderStart(event) { + this.dragSrcEl = event.target; + event.dataTransfer.effectAllowed = flagMove; + /* + console.log("setting outer html: ", this.dragSrcEl.outerHTML); + event.dataTransfer.setData('text/html', this.dragSrcEl.outerHTML); + * + this.dragSrcRow = DOM.getRowFromElement(this.dragSrcEl); + this.dragSrcEl.classList.add(flagDragging); + } + handleDragSliderOver(event) { + if (event.preventDefault) { + event.preventDefault(); + } + event.dataTransfer.dropEffect = flagMove; + return false; + } + handleDragSliderEnter(event) { + event.target.closest('tr').classList.add(flagDragOver); + } + handleDragSliderLeave(event) { + event.target.closest('tr').classList.remove(flagDragOver); + } + handleDropSlider(event) { + event.stopPropagation(); + let targetRow = DOM.getRowFromElement(event.target); + if (this.dragSourceRow != targetRow) { + targetRow.classList.remove(flagDragOver); + this.dragSrcEl.classList.remove(flagDragging); + let sourceRowClone = this.dragSrcRow.cloneNode(true); + let targetRowClone = targetRow.cloneNode(true); + console.log("sourceRowClone: ", sourceRowClone); + console.log("targetRowClone: ", targetRowClone); + let tbody = targetRow.closest('tbody'); + tbody.replaceChild(sourceRowClone, targetRow); + tbody.replaceChild(targetRowClone, this.dragSrcRow); + this.refreshDisplayOrders(); + } + return false; + } + handleDragSliderEnd(event) { + let table = this.getTableMain(); + let rows = table.querySelectorAll('tr'); + rows.forEach(row => { + row.classList.remove(flagDragOver); + row.classList.remove(flagDragging); + }); + } + refreshDisplayOrders() { + console.log("updating display order values"); + let rows = document.querySelectorAll(idTableMain + 'tbody tr.' + flagRow); + rows.forEach((row, indexRow) => { + sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + sliderDisplayOrder.setAttribute(attrValueCurrent, indexRow); + }); + } + */ + hookupTextareasCodeTable() { + let selectorCode = idTableMain + ' tbody tr td.' + flagCode + ' textarea'; + initialiseEventHandler(selectorCode, flagInitialised, (textareaCode) => { + textareaCode.addEventListener("change", (event) => { + console.log("textarea change event"); + this.handleChangeElementCellTable(textareaCode); + }); + }); + } + handleChangeElementCellTable(element) { + let row = DOM.getRowFromElement(element); + let td = DOM.getCellFromElement(element); + console.log("td: ", td); + let wasDirtyRow = this.isDirtyRow(row); + let wasDirtyElement = element.classList.contains(flagDirty); + let isDirtyElement = DOM.isElementDirty(element); + console.log("isDirtyElement: ", isDirtyElement); + console.log("wasDirtyElement: ", wasDirtyElement); + if (isDirtyElement != wasDirtyElement) { + DOM.handleDirtyElement(td, isDirtyElement); + let isNowDirtyRow = this.isDirtyRow(row); + console.log("isNowDirtyRow: ", isNowDirtyRow); + console.log("wasDirtyRow: ", wasDirtyRow); + if (isNowDirtyRow != wasDirtyRow) { + DOM.handleDirtyElement(row, isNowDirtyRow); + let rows = this.getTableRecords(true); + let existsDirtyRecord = rows.length > 0; + console.log("dirty records:", rows); + console.log("existsDirtyRecord:", existsDirtyRecord); + this.toggleShowButtonsSaveCancel(existsDirtyRecord); + } + } + } + isDirtyRow(row) { + throw new Error("Subclass of TableBasePage must implement method isDirtyRow()."); + } + toggleShowButtonsSaveCancel(show, buttonSave = null, buttonCancel = null) { + if (buttonSave == null) buttonSave = document.querySelector(idFormFilters + ' button.' + flagSave); + if (buttonCancel == null) buttonCancel = document.querySelector(idFormFilters + ' button.' + flagCancel); + if (show) { + buttonCancel.classList.remove(flagCollapsed); + buttonSave.classList.remove(flagCollapsed); + } else { + buttonCancel.classList.add(flagCollapsed); + buttonSave.classList.add(flagCollapsed); + } + } + handleChangeSelectCellTable(element) { + let row = DOM.getRowFromElement(element); + let td = DOM.getCellFromElement(element); + console.log("td: ", td); + let wasDirtyRow = this.isDirtyRow(row); + let wasDirtyElement = element.classList.contains(flagDirty); + let isDirtyElement = DOM.isElementDirty(element); + console.log("isDirtyElement: ", isDirtyElement); + console.log("wasDirtyElement: ", wasDirtyElement); + if (isDirtyElement != wasDirtyElement) { + DOM.handleDirtyElement(td, isDirtyElement); + let optionSelected = element.options[element.selectedIndex]; + td.setAttribute(attrIdAccessLevel, optionSelected.value); + td.setAttribute(flagAccessLevelRequired, optionSelected.textcontent); + let isNowDirtyRow = this.isDirtyRow(row); + console.log("isNowDirtyRow: ", isNowDirtyRow); + console.log("wasDirtyRow: ", wasDirtyRow); + if (isNowDirtyRow != wasDirtyRow) { + DOM.handleDirtyElement(row, isNowDirtyRow); + let rows = this.getTableRecords(true); + let existsDirtyRecord = rows.length > 0; + console.log("dirty records:", rows); + console.log("existsDirtyRecord:", existsDirtyRecord); + this.toggleShowButtonsSaveCancel(existsDirtyRecord); + } + } + } + hookupTextareasNameTable() { + let selectorName = idTableMain + ' tbody tr td.' + flagName + ' textarea'; + initialiseEventHandler(selectorName, flagInitialised, (textareaName) => { + textareaName.addEventListener("change", (event) => { + console.log("textarea change event"); + this.handleChangeElementCellTable(textareaName); + }); + }); + } + hookupTextareasDescriptionTable() { + let selectorDescription = idTableMain + ' tbody tr td.' + flagDescription + ' textarea'; + initialiseEventHandler(selectorDescription, flagInitialised, (textareaDescription) => { + textareaDescription.addEventListener("change", (event) => { + console.log("textarea change event"); + this.handleChangeElementCellTable(textareaDescription); + }); + }); + } + hookupInputsActiveTable() { + let selectorActive = idTableMain + ' tbody tr td.' + flagActive + ' input[type="checkbox"]'; + initialiseEventHandler(selectorActive, flagInitialised, (inputActive) => { + inputActive.addEventListener("change", (event) => { + console.log("input change event"); + this.handleChangeElementCellTable(inputActive); + }); + }); + } + hookupTdsAccessLevel() { + initialiseEventHandler(idTableMain + ' tbody td.' + flagAccessLevel, flagInitialised, (tdAccessLevel) => { + tdAccessLevel.addEventListener("click", (event) => { this.handleClickTdAccessLevel(event); } ); + }); + } + handleClickTdAccessLevel(event) { + console.log("tdAccessLevel clicked"); + event.stopPropagation(); + let tdAccessLevel = DOM.getCellFromElement(event.target); + console.log("tdAccessLevel: ", tdAccessLevel); + let row = DOM.getRowFromElement(tdAccessLevel); + let idAccessLevelSelected = tdAccessLevel.querySelector('div.' + flagAccessLevel).getAttribute(attrIdAccessLevel); + let ddlAccessLevel = document.createElement('select'); + ddlAccessLevel.classList.add(flagAccessLevel); + ddlAccessLevel.setAttribute(attrValueCurrent, idAccessLevelSelected); + ddlAccessLevel.setAttribute(attrValuePrevious, idAccessLevelSelected); + optionsAccessLevel.forEach((accessLevel) => { + let option = document.createElement('option'); + option.value = accessLevel.value; + option.textContent = accessLevel.text; + if (accessLevel.value == idAccessLevelSelected) option.selected = true; + ddlAccessLevel.appendChild(option); + }); + let tdAccessLevelNew = tdAccessLevel.cloneNode(true); + tdAccessLevelNew.innerHTML = ''; + tdAccessLevelNew.appendChild(ddlAccessLevel); + row.replaceChild(tdAccessLevelNew, tdAccessLevel); + this.hookupDdlsAccessLevelTable(); + } + hookupDdlsAccessLevelTable() { + initialiseEventHandler(idTableMain + ' tbody select.' + flagAccessLevel, flagInitialised, (ddlAccessLevel) => { + ddlAccessLevel.addEventListener("change", (event) => { + event.stopPropagation(); + this.handleChangeDdlAccessLevelTable(ddlAccessLevel); + }); + }); + } + handleChangeDdlAccessLevelTable(ddlAccessLevel) { + let row = DOM.getRowFromElement(ddlAccessLevel); + let td = DOM.getCellFromElement(ddlAccessLevel); + console.log("td: ", td); + let wasDirtyRow = this.isDirtyRow(row); + let wasDirtyElement = ddlAccessLevel.classList.contains(flagDirty); + let isDirtyElement = DOM.isElementDirty(ddlAccessLevel); + console.log("isDirtyElement: ", isDirtyElement); + console.log("wasDirtyElement: ", wasDirtyElement); + if (isDirtyElement != wasDirtyElement) { + DOM.handleDirtyElement(td, isDirtyElement); + let optionSelected = ddlAccessLevel.options[ddlAccessLevel.selectedIndex]; + td.setAttribute(attrIdAccessLevel, optionSelected.value); + td.setAttribute(flagAccessLevelRequired, optionSelected.textcontent); + let isNowDirtyRow = this.isDirtyRow(row); + console.log("isNowDirtyRow: ", isNowDirtyRow); + console.log("wasDirtyRow: ", wasDirtyRow); + if (isNowDirtyRow != wasDirtyRow) { + DOM.handleDirtyElement(row, isNowDirtyRow); + let rows = this.getTableRecords(true); + let existsDirtyRecord = rows.length > 0; + console.log("dirty records:", rows); + console.log("existsDirtyRecord:", existsDirtyRecord); + this.toggleShowButtonsSaveCancel(existsDirtyRecord); + } + } + } + leave() { + if (this.constructor === TableBasePage) { + throw new Error("Must implement leave() method."); + } + super.leave(); + let formFilters = this.getFormFilters(); + let dataPage = {}; + dataPage[flagFormFilters] = DOM.convertForm2JSON(formFilters); + this.setLocalStoragePage(dataPage); + _rowBlank = null; + } +} + + +/* Example of a subclass of TableBasePage +import { TableBasePage } from "./page_table_base.js"; +import API from "../api.js"; +import DOM from "../dom.js"; + +export class PageStoreProductCategories extends TableBasePage { + static hash = hashPageStoreProductCategories; + callFilterTableContent = API.getCategoriesByFilters; + + constructor() {} + initialize() {} + hookupFilters() {} + loadRowTable(rowJson) {} + getJsonRow(row) {} + hookupTableMain() {} + isDirtyRow(row) {} + leave() {} +} +*/ \ No newline at end of file diff --git a/static/js/pages/page_admin_home.js b/static/js/pages/core/admin_home.js similarity index 91% rename from static/js/pages/page_admin_home.js rename to static/js/pages/core/admin_home.js index c6c2fc6c..18296419 100644 --- a/static/js/pages/page_admin_home.js +++ b/static/js/pages/core/admin_home.js @@ -1,8 +1,8 @@ -import { PageBase } from "./page_base.js"; -import { router } from "../router.js"; +import { BasePage } from "../base.js"; +// import { router } from "../../router.js"; -export class PageAdminHome extends PageBase { +export class PageAdminHome extends BasePage { static hash = hashPageAdminHome; constructor() { diff --git a/static/js/pages/page_contact.js b/static/js/pages/core/contact.js similarity index 62% rename from static/js/pages/page_contact.js rename to static/js/pages/core/contact.js index eb9fc048..f2e74269 100644 --- a/static/js/pages/page_contact.js +++ b/static/js/pages/core/contact.js @@ -1,7 +1,7 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageContact extends PageBase { +export class PageContact extends BasePage { static hash = hashPageContact; constructor() { diff --git a/static/js/pages/page_home.js b/static/js/pages/core/home.js similarity index 72% rename from static/js/pages/page_home.js rename to static/js/pages/core/home.js index 28936f1d..fb0f98a6 100644 --- a/static/js/pages/page_home.js +++ b/static/js/pages/core/home.js @@ -1,7 +1,7 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageHome extends PageBase { +export class PageHome extends BasePage { static hash = hashPageHome; constructor() { diff --git a/static/js/pages/page_services.js b/static/js/pages/core/services.js similarity index 68% rename from static/js/pages/page_services.js rename to static/js/pages/core/services.js index 655b26ab..61741b59 100644 --- a/static/js/pages/page_services.js +++ b/static/js/pages/core/services.js @@ -1,7 +1,7 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageServices extends PageBase { +export class PageServices extends BasePage { static hash = hashPageServices; constructor() { diff --git a/static/js/pages/page_accessibility_statement.js b/static/js/pages/legal/accessibility_statement.js similarity index 66% rename from static/js/pages/page_accessibility_statement.js rename to static/js/pages/legal/accessibility_statement.js index 0a17851f..657f85c2 100644 --- a/static/js/pages/page_accessibility_statement.js +++ b/static/js/pages/legal/accessibility_statement.js @@ -1,6 +1,6 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageAccessibilityStatement extends PageBase { +export class PageAccessibilityStatement extends BasePage { static hash = hashPageAccessibilityStatement; constructor() { diff --git a/static/js/pages/page_license.js b/static/js/pages/legal/license.js similarity index 68% rename from static/js/pages/page_license.js rename to static/js/pages/legal/license.js index 19938631..b9f725d9 100644 --- a/static/js/pages/page_license.js +++ b/static/js/pages/legal/license.js @@ -1,7 +1,7 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageLicense extends PageBase { +export class PageLicense extends BasePage { static hash = hashPageLicense; constructor() { diff --git a/static/js/pages/page_store_home.js b/static/js/pages/page_store_home.js deleted file mode 100644 index b400c909..00000000 --- a/static/js/pages/page_store_home.js +++ /dev/null @@ -1,174 +0,0 @@ - -import { PageBase } from "./page_base.js"; - -export class PageStoreHome extends PageBase { - static hash = hashPageStoreHome; - - constructor() { - super(); - } - - initialize() { - this.sharedInitialize(); - this.hookupFiltersStore(); - this.hookupStoreHome(); - } - - - hookupFiltersStore() { - hookupFilterCurrency(); - hookupFilterDeliveryRegion(); - hookupFilterIsIncludedVAT(); - } - - hookupFilterCurrency() { - /* - let elForm = document.querySelectorAll(idFormCurrency); - let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]); - initialiseEventHandler(elSelector, flagInitialised, function(){ - elForm = document.querySelectorAll(idFormCurrency); - elSelector.addEventListener("change", function(event) { - ajaxData = {}; - ajaxData[keyForm] = convertForm2JSON(elForm); - console.log('sending data to currency selector controller: '); console.log(ajaxData); - ajaxJSONData('select currency', mapHashToController(hashStoreSelectCurrency), ajaxData, function() { window.location.reload() }, false); - - let optionSelected = elSelector.options[elSelector.selectedIndex] - let textSelected = optionSelected.attr(attrDataShort) - - }); - }); - console.log("form currency initialised") - */ - - let dropdownCurrency = document.querySelectorAll(idCurrency)[0]; - // dropdownCurrency.options.map(function(option) { - let option, indexHyphen, textOption; - for (let indexOption = 0; indexOption < dropdownCurrency.options.length; indexOption++) { - option = document.querySelectorAll(dropdownCurrency.options[indexOption]); - textOption = option.text(); - indexHyphen = textOption.indexOf('-'); - option.attr(attrTextExpanded, textOption); - option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1)); - option.classList.add(flagCollapsed); - } - handleSelectCollapse(dropdownCurrency); - initialiseEventHandler(dropdownCurrency, flagInitialised, function() { - dropdownCurrency = document.querySelectorAll(dropdownCurrency); - dropdownCurrency.addEventListener("focus", function() { - handleSelectExpand(dropdownCurrency); - }); - dropdownCurrency.addEventListener("blur", function() { - handleSelectCollapse(dropdownCurrency); - }); - dropdownCurrency.addEventListener("change", function() { - let selectedCurrency = dropdownCurrency.val(); - console.log("selected currency: ", selectedCurrency); - let basket = getLocalStorage(keyBasket); - basket[keyIdCurrency] = selectedCurrency; - // setLocalStorage(keyIdCurrency, selectedCurrency); - setLocalStorage(keyBasket, basket); - let ajaxData = {}; - ajaxData[keyBasket] = basket; - ajaxJSONData('update currency', mapHashToController(hashPageCurrent), ajaxData, loadPageBody, false); - }); - }); - } - - hookupFilterDeliveryRegion() { - /* - let elForm = document.querySelectorAll(idFormDeliveryRegion); - let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]); - initialiseEventHandler(elSelector, flagInitialised, function(){ - elForm = document.querySelectorAll(idFormDeliveryRegion); - elSelector.addEventListener("change", function(event) { - ajaxData = {}; - ajaxData[keyForm] = convertForm2JSON(elForm); - console.log('sending data to delivery region selector controller: '); console.log(ajaxData); - ajaxJSONData('select delivery region', mapHashToController(hashStoreSelectDeliveryRegion), ajaxData, function() { window.location.reload() }, false); - }); - console.log("form delivery region initialised") - }); - */ - - let dropdownRegion = document.querySelectorAll(idRegionDelivery)[0]; - - let option, indexHyphen, textOption; - for (let indexOption = 0; indexOption < dropdownRegion.options.length; indexOption++) { - option = document.querySelectorAll(dropdownRegion.options[indexOption]); - textOption = option.text(); - indexHyphen = textOption.indexOf('-'); - option.attr(attrTextExpanded, textOption); - option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1)); - option.classList.add(flagCollapsed); - } - - handleSelectCollapse(dropdownRegion); - - initialiseEventHandler(dropdownRegion, flagInitialised, function() { - dropdownRegion = document.querySelectorAll(dropdownRegion); - dropdownRegion.addEventListener("focus", function() { - console.log("dropdown region focused"); - handleSelectExpand(dropdownRegion); - }); - dropdownRegion.addEventListener("blur", function() { - console.log("dropdown region blurred"); - handleSelectCollapse(dropdownRegion); - }); - dropdownRegion.addEventListener("change", function() { - handleSelectCollapse(dropdownRegion); - let selectedRegion = dropdownRegion.val(); - console.log("selected region: ", selectedRegion); - let basket = getLocalStorage(keyBasket); - basket[keyIdRegionDelivery] = selectedRegion; - // setLocalStorage(keyIdRegionDelivery, selectedRegion); - setLocalStorage(keyBasket, basket); - let ajaxData = {}; - ajaxData[keyIdRegionDelivery] = selectedRegion; - ajaxJSONData('update region', mapHashToController(hashStoreSetRegion), ajaxData, null, false); - }); - }); - } - - hookupFilterIsIncludedVAT() { - let elForm = document.querySelectorAll(idFormIsIncludedVAT); - let elSelector = document.querySelectorAll(elForm.querySelector('input[type="checkbox"]')[0]); - initialiseEventHandler(elSelector, flagInitialised, function(){ - elForm = document.querySelectorAll(idFormIsIncludedVAT); - elSelector.addEventListener("change", function(event) { - ajaxData = {}; - ajaxData[keyForm] = convertForm2JSON(elForm); - console.log('sending data to include VAT controller: '); console.log(ajaxData); - ajaxJSONData('set include VAT', mapHashToController(hashStoreSetIsIncludedVAT), ajaxData, function() { window.location.reload() }, false); - }); - console.log("form is included VAT initialised") - }); - } - - hookupStoreCardsProduct() { - - let d; // , lsShared; - let selectorCardProduct = '.card.subcard'; - initialiseEventHandler(selectorCardProduct, flagInitialised, function(cardProduct) { - console.log("initialising product card: ", cardProduct); - cardProduct.addEventListener("click", function(event) { - // d = { keyIdProduct: product.attr(attrIdProduct) } - var elemClicked = event.target; - if (elemClicked.id != 'submit') { // disable for submit buttons - console.log("product click: " + cardProduct.attr(attrIdProduct)); - console.log("permutation click: " + cardProduct.attr(attrIdPermutation)); - var d = {} - d[keyIdProduct] = cardProduct.attr(attrIdProduct) - d[keyIdPermutation] = cardProduct.attr(attrIdPermutation) - // send quantity requested - goToPage(hashPageStoreProduct, d); - } - }); - console.log("click method added for product ID: " + cardProduct.attr(attrIdProduct) + ', permutation ID: ', cardProduct.attr(attrIdPermutation)); - }); - } - - leave() { - super.leave(); - } -} diff --git a/static/js/pages/page_store_product_categories.js b/static/js/pages/page_store_product_categories.js deleted file mode 100644 index 68f1305e..00000000 --- a/static/js/pages/page_store_product_categories.js +++ /dev/null @@ -1,344 +0,0 @@ -var _rowBlank = null; - -import { PageBase } from "./page_base.js"; -import API from "../api.js"; -import DOM from "../dom.js"; - -export class PageStoreProductCategories extends PageBase { - static hash = hashPageStoreProductCategories; - - constructor() { - super(); - } - - initialize() { - this.sharedInitialize(); - this.hookupFilters(); - this.hookupButtonsAddSaveCancel(); - this.hookupTableMain(); - hookupOverlayConfirm(() => { - this.leave(); - this.saveCategories(); - }); - } - - hookupFilters() { - this.hookupFilterIsNotEmpty(); - this.hookupFilterActive(); - this.hookupButtonApplyFilters(); - } - - hookupFilterIsNotEmpty() { - initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => { - filter.addEventListener("change", (event) => { - PageStoreProductCategories.isDirtyFilter(filter); - }); - }); - } - - hookupFilterActive() { - initialiseEventHandler('.' + flagActive, flagInitialised, (filter) => { - filter.addEventListener("change", (event) => { - PageStoreProductCategories.isDirtyFilter(filter); - }); - }); - } - - hookupButtonApplyFilters() { - initialiseEventHandler(idButtonApplyFilters, flagInitialised, (button) => { - button.addEventListener("click", (event) => { - event.stopPropagation(); - this.loadCategories(); - }); - }); - } - - loadCategories() { - - let elForm = document.querySelector(idFormFiltersProductCategory); - API.getCategoriesByFilters(elForm) - .then(data => { - console.log('Data received:', data); - this.callbackLoadCategories(data); - }) - .catch(error => console.error('Error:', error)); - } - - callbackLoadCategories(response) { - - console.log('ajax:'); console.log(response); - - let table = document.querySelector(idTableMain); - let row, sliderDisplayOrder, textareaCode, textareaName, textareaDescription, inputActive; - - // table.querySelector('tr').remove(); // :not(.' + flagRowNew + ') - let bodyTable = table.querySelector('tbody'); - bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); }); - - let categories = response.data.categories.sort((a, b) => a.display_order - b.display_order); - - categories.forEach((category) => { - row = _rowBlank.cloneNode(true); - row.classList.remove(flagRowNew); - row.classList.remove(flagInitialised); - row.querySelectorAll('.' + flagInitialised).forEach(function(element) { - element.classList.remove(flagInitialised); - }); - console.log("applying data row: ", category); - sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); - textareaCode = row.querySelector('td.' + flagCode + ' textarea'); - textareaName = row.querySelector('td.' + flagName + ' textarea'); - textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); - inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); - sliderDisplayOrder.setAttribute(attrValueCurrent, category[flagDisplayOrder]); - DOM.setElementValuePrevious(sliderDisplayOrder, category[flagDisplayOrder]); - DOM.setElementValueCurrent(textareaCode, category[flagCode]); - DOM.setElementValuePrevious(textareaCode, category[flagCode]); - DOM.setElementValueCurrent(textareaName, category[flagName]); - DOM.setElementValuePrevious(textareaName, category[flagName]); - DOM.setElementValueCurrent(textareaDescription, category[flagDescription]); - DOM.setElementValuePrevious(textareaDescription, category[flagDescription]); - DOM.setElementValueCurrent(inputActive, category[flagActive]); - DOM.setElementValuePrevious(inputActive, category[flagActive]); - row.setAttribute(attrIdCategory, category[attrIdCategory]); - bodyTable.appendChild(row); - }); - - this.hookupTableMain(); - } - - hookupButtonsAddSaveCancel() { - this.hookupButtonSave(); - - initialiseEventHandler('form.' + flagFilter + ' button.' + flagCancel, flagInitialised, function(button) { - button.addEventListener("click", function(event) { - event.stopPropagation(); - loadCategories(); - }); - button.classList.add(flagCollapsed); - }); - - initialiseEventHandler('form.' + flagFilter + ' button.' + flagAdd, flagInitialised, (button) => { - button.addEventListener("click", (event) => { - event.stopPropagation(); - let tbody = document.querySelector(idTableMain + ' tbody'); - let row = _rowBlank.cloneNode(true); - row.classList.remove(flagInitialised); - row.querySelectorAll('.' + flagInitialised).forEach(function(element) { - element.classList.remove(flagInitialised); - }); - let newDisplayOrder = parseInt(tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider).getAttribute(attrValueCurrent)) + 1; - tbody.appendChild(row); - let slider = tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); - slider.setAttribute(attrValueCurrent, newDisplayOrder); - slider.setAttribute(attrValuePrevious, newDisplayOrder); - this.hookupTableMain(); - }); - }); - } - - saveCategories() { - - let categories = this.getCategories(true); - - if (categories.length == 0) { - showOverlayError('No categories to save'); - return; - } - - let elForm = document.querySelector(idFormFiltersProductCategory); - let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm)); // idOverlayConfirm + ' ' + textarea - API.saveCategories(categories, elForm, comment) - .then(data => { - console.log('Data received:', data); - this.callbackLoadCategories(data); - console.log('Categories saved?'); - }) - .catch(error => console.error('Error:', error)); - } - - getCategories(dirtyOnly) { - let table = document.querySelector(idTableMain); - let categories = []; - let category, sliderDisplayOrder, textareaCode, textareaName, textareaDescription, inputActive; - table.querySelectorAll('tbody tr').forEach(function(row) { - if (dirtyOnly && !row.classList.contains(flagDirty)) return; - - sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); - textareaCode = row.querySelector('td.' + flagCode + ' textarea'); - textareaName = row.querySelector('td.' + flagName + ' textarea'); - textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); - inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); - - category = {}; - category[attrIdCategory] = row.getAttribute(attrIdCategory); - category[flagCode] = DOM.getElementValueCurrent(textareaCode); - category[flagName] = DOM.getElementValueCurrent(textareaName); - category[flagDescription] = DOM.getElementValueCurrent(textareaDescription); - category[flagActive] = DOM.getElementValueCurrent(inputActive); - category[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent); - categories.push(category); - }); - return categories; - } - - hookupTableMain() { - this.hookupSlidersDisplayOrder(); - this.hookupTextareasCode(); - this.hookupTextareasName(); - this.hookupTextareasDescription(); - this.hookupInputsActive(); - if (_rowBlank == null) { - this.cacheRowBlank(); - } - } - hookupSlidersDisplayOrder() { - let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder; - initialiseEventHandler(selectorDisplayOrder, flagInitialised, (sliderDisplayOrder) => { - sliderDisplayOrder.addEventListener('mousedown', (event) => { - this.handleSliderMouseDown(event); - }); - }); - } - hookupTextareasCode() { - let selectorCode = idTableMain + ' tbody tr td.' + flagCode + ' textarea'; - initialiseEventHandler(selectorCode, flagInitialised, (textareaCode) => { - textareaCode.addEventListener("change", (event) => { - console.log("textarea change event"); - this.handleChangeInputCategories(textareaCode); - }); - }); - } - hookupTextareasName() { - let selectorName = idTableMain + ' tbody tr td.' + flagName + ' textarea'; - initialiseEventHandler(selectorName, flagInitialised, (textareaName) => { - textareaName.addEventListener("change", (event) => { - console.log("textarea change event"); - this.handleChangeInputCategories(textareaName); - }); - }); - } - hookupTextareasDescription() { - let selectorDescription = idTableMain + ' tbody tr td.' + flagDescription + ' textarea'; - initialiseEventHandler(selectorDescription, flagInitialised, (textareaDescription) => { - textareaDescription.addEventListener("change", (event) => { - console.log("textarea change event"); - this.handleChangeInputCategories(textareaDescription); - }); - }); - } - hookupInputsActive() { - let selectorActive = idTableMain + ' tbody tr td.' + flagActive + ' input[type="checkbox"]'; - initialiseEventHandler(selectorActive, flagInitialised, (inputActive) => { - inputActive.addEventListener("change", (event) => { - console.log("input change event"); - this.handleChangeInputCategories(inputActive); - }); - }); - } - handleSliderMouseDown(event) { - event.stopPropagation(); - console.log("start drag slider"); - let slider = event.target; - let initialY = event.clientY; - let initialRow = DOM.getRowFromElement(slider); - let placeholder = document.createElement('tr'); - placeholder.className = 'placeholder'; - placeholder.style.height = `${initialRow.offsetHeight}px`; - initialRow.parentNode.insertBefore(placeholder, initialRow.nextSibling); - initialRow.style.position = 'absolute'; - initialRow.style.zIndex = '1000'; - initialRow.style.width = `${initialRow.offsetWidth}px`; - - function onMouseMove(event) { - let newY = event.clientY; - let deltaY = newY - initialY; - initialRow.style.transform = `translateY(${deltaY}px)`; - - let rows = Array.from(initialRow.parentNode.children); - let currentIndex = rows.indexOf(initialRow); - let placeholderIndex = rows.indexOf(placeholder); - - if (deltaY > 0 && currentIndex < rows.length - 1) { - let nextRow = rows[currentIndex + 1]; - if (newY > nextRow.getBoundingClientRect().top) { - initialRow.parentNode.insertBefore(placeholder, nextRow.nextSibling); - } - } else if (deltaY < 0 && currentIndex > 0) { - let prevRow = rows[currentIndex - 1]; - if (newY < prevRow.getBoundingClientRect().bottom) { - initialRow.parentNode.insertBefore(placeholder, prevRow); - } - } - } - - function onMouseUp() { - initialRow.style.position = ''; - initialRow.style.zIndex = ''; - initialRow.style.transform = ''; - placeholder.parentNode.insertBefore(initialRow, placeholder); - placeholder.remove(); - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - } - - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - } - cacheRowBlank() { - let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew; - let rowBlankTemp = document.querySelector(selectorRowNew); - console.log("row blank temp: ", rowBlankTemp); - _rowBlank = rowBlankTemp.cloneNode(true); - document.querySelectorAll(selectorRowNew).forEach(function(row) { - row.remove(); - }); - } - - handleChangeInputCategories(element) { - console.log("handleChangeInputCategories"); - console.log("element value:", DOM.getElementValueCurrent(element)); - let row = DOM.getRowFromElement(element); - let wasDirtyRow = this.isRowDirty(row); - let wasDirty = element.classList.contains(flagDirty); - let isDirty = DOM.isElementDirty(element); - if (isDirty != wasDirty) { - let isDirtyRow = this.isRowDirty(row); - if (isDirtyRow != wasDirtyRow) { - let categoriesDirty = this.getCategories(true); - let existsDirtyCategory = categoriesDirty.length > 0; - console.log("categoriesDirty:", categoriesDirty); - console.log("existsDirtyCategory:", existsDirtyCategory); - this.toggleShowButtonsSaveCancel(existsDirtyCategory); - } - } - } - - isRowDirty(row) { - let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder); - let inputCode = row.querySelector('td.' + flagCode + ' textarea'); - let inputName = row.querySelector('td.' + flagName + ' textarea'); - let inputDescription = row.querySelector('td.' + flagDescription + ' textarea'); - let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); - let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) || - inputDescription.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty); - if (isDirty) { - row.classList.add(flagDirty); - } else { - row.classList.remove(flagDirty); - } - return isDirty; - } - - leave() { - super.leave(); - } - - getFiltersDefaults() { - return { - [flagIsNotEmpty]: true, - [flagActive]: true - }; - } -} - diff --git a/static/js/pages/page_store_base.js b/static/js/pages/store/base.js similarity index 57% rename from static/js/pages/page_store_base.js rename to static/js/pages/store/base.js index e4421a20..091c139f 100644 --- a/static/js/pages/page_store_base.js +++ b/static/js/pages/store/base.js @@ -1,37 +1,146 @@ -import { PageBase } from "./page_base.js"; +// import { BasePage } from "../base.js"; +import { DOM } from "../../dom.js"; +import { isEmpty } from "../../lib/utils.js"; -export class PageStoreHome extends PageBase { +export class StoreMixinPage { // extends BasePage { constructor() { super(); } - sharedInitialize() { - super.sharedInitialize(); + initialize(thisPage) { + console.log('hookup store start for ', DOM.getHashPageCurrent()); this.hookupFiltersStore(); - this.hookupStoreHome(); + this.hookupLocalStorageStore(); + this.hookupBasket(); + this.hookupButtonsAdd2Basket(); } - - - hookupStore() { - console.log('hookup store start'); - console.log(_pathHost); - hookupLocalStorageStore(); - hookupBasket(); - hookupBtnsAdd2Basket(); + hookupFiltersStore() { + hookupFilterCurrency(); + hookupFilterDeliveryRegion(); + hookupFilterIsIncludedVAT(); } + hookupFilterCurrency() { + /* + let elForm = document.querySelectorAll(idFormCurrency); + let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = document.querySelectorAll(idFormCurrency); + elSelector.addEventListener("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to currency selector controller: '); console.log(ajaxData); + ajaxJSONData('select currency', mapHashToController(hashStoreSelectCurrency), ajaxData, function() { window.location.reload() }, false); - hookupBasket() { + let optionSelected = elSelector.options[elSelector.selectedIndex] + let textSelected = optionSelected.attr(attrDataShort) + + }); + }); + console.log("form currency initialised") + */ + + let dropdownCurrency = document.querySelectorAll(idCurrency)[0]; + // dropdownCurrency.options.map(function(option) { + let option, indexHyphen, textOption; + for (let indexOption = 0; indexOption < dropdownCurrency.options.length; indexOption++) { + option = document.querySelectorAll(dropdownCurrency.options[indexOption]); + textOption = option.text(); + indexHyphen = textOption.indexOf('-'); + option.attr(attrTextExpanded, textOption); + option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1)); + option.classList.add(flagCollapsed); + } + handleSelectCollapse(dropdownCurrency); + initialiseEventHandler(dropdownCurrency, flagInitialised, function() { + dropdownCurrency = document.querySelectorAll(dropdownCurrency); + dropdownCurrency.addEventListener("focus", function() { + handleSelectExpand(dropdownCurrency); + }); + dropdownCurrency.addEventListener("blur", function() { + handleSelectCollapse(dropdownCurrency); + }); + dropdownCurrency.addEventListener("change", function() { + let selectedCurrency = dropdownCurrency.val(); + console.log("selected currency: ", selectedCurrency); + let basket = getLocalStorage(keyBasket); + basket[keyIdCurrency] = selectedCurrency; + // setLocalStorage(keyIdCurrency, selectedCurrency); + setLocalStorage(keyBasket, basket); + let ajaxData = {}; + ajaxData[keyBasket] = basket; + ajaxJSONData('update currency', mapHashToController(hashPageCurrent), ajaxData, loadPageBody, false); + }); + }); + } + hookupFilterDeliveryRegion() { + /* + let elForm = document.querySelectorAll(idFormDeliveryRegion); + let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = document.querySelectorAll(idFormDeliveryRegion); + elSelector.addEventListener("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to delivery region selector controller: '); console.log(ajaxData); + ajaxJSONData('select delivery region', mapHashToController(hashStoreSelectDeliveryRegion), ajaxData, function() { window.location.reload() }, false); + }); + console.log("form delivery region initialised") + }); + */ + + let dropdownRegion = document.querySelectorAll(idRegionDelivery)[0]; - // const containerBasket = document.querySelectorAll(idContainerBasket); - toggleShowBtnCheckout(); // containerBasket - hookupBtnCheckout(); - hookupBtnsPlusMinus(); - hookupBasketAddInputs(); - hookupBasketEditInputs(); - hookupBtnsDelete(); - } + let option, indexHyphen, textOption; + for (let indexOption = 0; indexOption < dropdownRegion.options.length; indexOption++) { + option = document.querySelectorAll(dropdownRegion.options[indexOption]); + textOption = option.text(); + indexHyphen = textOption.indexOf('-'); + option.attr(attrTextExpanded, textOption); + option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1)); + option.classList.add(flagCollapsed); + } + handleSelectCollapse(dropdownRegion); + + initialiseEventHandler(dropdownRegion, flagInitialised, function() { + dropdownRegion = document.querySelectorAll(dropdownRegion); + dropdownRegion.addEventListener("focus", function() { + console.log("dropdown region focused"); + handleSelectExpand(dropdownRegion); + }); + dropdownRegion.addEventListener("blur", function() { + console.log("dropdown region blurred"); + handleSelectCollapse(dropdownRegion); + }); + dropdownRegion.addEventListener("change", function() { + handleSelectCollapse(dropdownRegion); + let selectedRegion = dropdownRegion.val(); + console.log("selected region: ", selectedRegion); + let basket = getLocalStorage(keyBasket); + basket[keyIdRegionDelivery] = selectedRegion; + // setLocalStorage(keyIdRegionDelivery, selectedRegion); + setLocalStorage(keyBasket, basket); + let ajaxData = {}; + ajaxData[keyIdRegionDelivery] = selectedRegion; + ajaxJSONData('update region', mapHashToController(hashStoreSetRegion), ajaxData, null, false); + }); + }); + } + hookupFilterIsIncludedVAT() { + let elForm = document.querySelectorAll(idFormIsIncludedVAT); + let elSelector = document.querySelectorAll(elForm.querySelector('input[type="checkbox"]')[0]); + initialiseEventHandler(elSelector, flagInitialised, function(){ + elForm = document.querySelectorAll(idFormIsIncludedVAT); + elSelector.addEventListener("change", function(event) { + ajaxData = {}; + ajaxData[keyForm] = convertForm2JSON(elForm); + console.log('sending data to include VAT controller: '); console.log(ajaxData); + ajaxJSONData('set include VAT', mapHashToController(hashStoreSetIsIncludedVAT), ajaxData, function() { window.location.reload() }, false); + }); + console.log("form is included VAT initialised") + }); + } hookupLocalStorageStore() { // setupPageLocalStorage(hashPageCurrent); @@ -72,37 +181,21 @@ export class PageStoreHome extends PageBase { console.log('ajax:' + ajaxData); ajaxJSONData(keyBasket, mapHashToController(hashStoreBasketLoad), ajaxData, loadBasket, false); } - - /* - setupPageLocalStorageNextStore(pageHashNext) { - let lsOld = getPageLocalStorage(hashPageCurrent); - hashPageCurrent = pageHashNext; - clearPageLocalStorage(hashPageCurrent); - setupPageLocalStorage(hashPageCurrent); - let lsNew = getPageLocalStorage(hashPageCurrent); - lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; - setPageLocalStorage(hashPageCurrent, lsNew); - } - - goToPageStore(pageHash, parameters_dict) { + hookupBasket() { - let lsOld = getPageLocalStorage(pageHashCurrent); - pageHashCurrent = pageHash; - clearPageLocalStorage(pageHashCurrent); - setupPageLocalStorage(pageHashCurrent); - let lsNew = getPageLocalStorage(pageHashCurrent); - lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; - setPageLocalStorage(pageHashCurrent, lsNew); - - goToPage(pageHash, parameters_dict); + // const containerBasket = document.querySelectorAll(idContainerBasket); + this.toggleShowButtonCheckout(); // containerBasket + this.hookupButtonCheckout(); + this.hookupBasketItemPlusAndMinusButtons(); + this.hookupBasketAddInputs(); + this.hookupBasketEditInputs(); + this.hookupDeleteBasketItemButtons(); } - */ - - toggleShowBtnCheckout() { // containerBasket + toggleShowButtonCheckout() { // containerBasket console.log("toggling checkout button"); - const btnCheckout = document.querySelectorAll(idBtnCheckout); + const btnCheckout = document.querySelectorAll(idButtonCheckout); const labelBasketEmpty = document.querySelectorAll(idLabelBasketEmpty); // let lsPage = getPageLocalStorage(hashPageCurrent); @@ -118,6 +211,164 @@ export class PageStoreHome extends PageBase { labelBasketEmpty.style.display = "none"; } } + hookupButtonCheckout() { + + console.log("hooking up checkout button"); + + const btnCheckout = document.querySelectorAll(idButtonCheckout); + // let lsPage = getPageLocalStorage(hashPageCurrent); + initialiseEventHandler(btnCheckout, flagInitialised, function() { + btnCheckout.addEventListener("click", function() { + /* + //setupPageLocalStorageNext(hashPageStoreBasket); + let basket = getLocalStorage(keyBasket); + // goToPage(hashPageStoreBasket); + let ajaxData = {}; + ajaxData[keyBasket] = basket; + + ajaxJSONData('checkout', mapHashToController(hashPageStoreBasket), ajaxData, null, false); + */ + goToPage(hashPageStoreBasket); + }); + }); + } + hookupBasketItemPlusAndMinusButtons() { + const minVal = 1; + // Basket Add + // Increment + document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elButton = this; + initialiseEventHandler(elButton, flagInitialised, function(){ + elButton.addEventListener("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elButton)).querySelector('input[type="number"]'); + // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elButton.attr(attrFormType) + '][' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + ']'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal += 1; + elInput.val(newVal); + }); + }); + }); + // Decrement + document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elButton = this; + initialiseEventHandler(elButton, flagInitialised, function(){ + elButton.addEventListener("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + // let product = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elButton.attr(attrIdProduct) + ']'); + let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elButton)).querySelector('input[type="number"]'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal = Math.max(minVal, newVal - 1); + elInput.val(newVal); + }); + }); + }); + + // Basket Edit + // Increment + document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elButton = this; + initialiseEventHandler(elButton, flagInitialised, function(){ + elButton.addEventListener("click", function(event) { + event.stopPropagation(); + // basketItem = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elButton.attr(attrIdProduct) + ']'); + let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elButton)).querySelector('input[type="number"]'); + // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elButton.attr(attrFormType) + '][' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + ']'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal += 1; + elInput.val(newVal); + elInput.trigger("change"); + }); + }); + }); + // Decrement + document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elButton = this; + initialiseEventHandler(elButton, flagInitialised, function(){ + elButton.addEventListener("click", function(event) { + event.stopPropagation(); + let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elButton)).querySelector('input[type="number"]'); + let newVal = parseInt(getElementCurrentValue(elInput)); + if (isNaN(newVal)) newVal = minVal; + newVal = Math.max(minVal, newVal - 1); + elInput.val(newVal); + elInput.trigger("change"); + }); + }); + }); + } + hookupBasketAddInputs() { + + document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { + let elForm = this; + let elInput = elForm.querySelector('input[type="number"]'); + initialiseEventHandler(elInput, flagInitialised, function(){ + elInput.addEventListener("change", function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + elInput.addEventListener("click", function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + }); + }); + } + hookupBasketEditInputs() { + + // let elButton, elInput, newVal, product; + const minVal = 1; + // Basket Edit + // Increment + document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elForm = this; + let elInput = elForm.querySelector('input[type="number"]'); + initialiseEventHandler(elInput, flagInitialised, function(){ + elInput.addEventListener("change", function(event) { + event.preventDefault(); + event.stopPropagation(); + // let lsPage = getPageLocalStorageCurrent(); + d = {}; + d[keyBasket]= getLocalStorage(keyBasket); // lsPage[keyBasket]; // JSON.parse(lsPage[keyBasket]); + d[keyIdProduct] = elForm.attr(attrIdProduct); // lsPage[keyIdProduct]; + d[keyIdPermutation] = elForm.attr(attrIdPermutation); + // d[keyQuantity] = lsPage[keyQuantity]; + d[keyForm] = convertForm2JSON(elForm); + d[keyForm][keyQuantity] = elInput.val(); + console.log('sending data to basket edit controller: '); console.log(d); + ajaxJSONData('basket update', mapHashToController(hashStoreBasketEdit), d, loadBasket, false); + }); + }); + }); + } + hookupDeleteBasketItemButtons() { + + console.log('hooking up basket item delete buttons'); + // let elForm, elDelete; + // const minVal = 1; + // Basket Add + // Increment + document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { + let elForm = this; + let elDelete = elForm.querySelector('a.' + flagBasketItemDelete); + initialiseEventHandler(elDelete, flagInitialised, function(){ + elDelete.addEventListener("click", function(event) { + event.stopPropagation(); + ajaxData = {}; + ajaxData[keyBasket]= getLocalStorage(keyBasket); + ajaxData[keyIdProduct] = elForm.attr(attrIdProduct); + ajaxData[keyIdPermutation] = elForm.attr(attrIdPermutation); + console.log('sending data to basket delete controller: '); console.log(ajaxData); + ajaxJSONData('basket update', mapHashToController(hashStoreBasketDelete), ajaxData, loadBasket, false); + }); + }); + }); + } /* getBasket() { @@ -128,10 +379,10 @@ export class PageStoreHome extends PageBase { } */ - hookupBtnsAdd2Basket() { + hookupButtonsAdd2Basket() { // let product, btn, lsPage; - // [' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + '] + // [' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + '] document.querySelectorAll('form[' + attrFormType + '="' + typeFormBasketAdd +'"]').each(function() { var form = this; @@ -159,28 +410,6 @@ export class PageStoreHome extends PageBase { }); } - hookupBtnCheckout() { - - console.log("hooking up checkout button"); - - const btnCheckout = document.querySelectorAll(idBtnCheckout); - // let lsPage = getPageLocalStorage(hashPageCurrent); - initialiseEventHandler(btnCheckout, flagInitialised, function() { - btnCheckout.addEventListener("click", function() { - /* - //setupPageLocalStorageNext(hashPageStoreBasket); - let basket = getLocalStorage(keyBasket); - // goToPage(hashPageStoreBasket); - let ajaxData = {}; - ajaxData[keyBasket] = basket; - - ajaxJSONData('checkout', mapHashToController(hashPageStoreBasket), ajaxData, null, false); - */ - goToPage(hashPageStoreBasket); - }); - }); - } - loadBasket(response) { let basketContainer = document.querySelectorAll(idBasketContainer); @@ -223,148 +452,7 @@ export class PageStoreHome extends PageBase { return 'form[' + attrFormType + '="' + typeForm + '"][' + attrIdProduct + '=' + elementInForm.attr(attrIdProduct) + ']' + selectorIdPermutation; } - hookupBtnsPlusMinus() { - - // let elBtn, elInput, newVal, product; - const minVal = 1; - // Basket Add - // Increment - document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { - let elBtn = this; - initialiseEventHandler(elBtn, flagInitialised, function(){ - elBtn.addEventListener("click", function(event) { - event.preventDefault(); - event.stopPropagation(); - let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elBtn)).querySelector('input[type="number"]'); - // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']'); - let newVal = parseInt(getElementCurrentValue(elInput)); - if (isNaN(newVal)) newVal = minVal; - newVal += 1; - elInput.val(newVal); - }); - }); - }); - // Decrement - document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { - let elBtn = this; - initialiseEventHandler(elBtn, flagInitialised, function(){ - elBtn.addEventListener("click", function(event) { - event.preventDefault(); - event.stopPropagation(); - // let product = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']'); - let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elBtn)).querySelector('input[type="number"]'); - let newVal = parseInt(getElementCurrentValue(elInput)); - if (isNaN(newVal)) newVal = minVal; - newVal = Math.max(minVal, newVal - 1); - elInput.val(newVal); - }); - }); - }); - // Basket Edit - // Increment - document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { - let elBtn = this; - initialiseEventHandler(elBtn, flagInitialised, function(){ - elBtn.addEventListener("click", function(event) { - event.stopPropagation(); - // basketItem = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']'); - let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elBtn)).querySelector('input[type="number"]'); - // console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']'); - let newVal = parseInt(getElementCurrentValue(elInput)); - if (isNaN(newVal)) newVal = minVal; - newVal += 1; - elInput.val(newVal); - elInput.trigger("change"); - }); - }); - }); - // Decrement - document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { - let elBtn = this; - initialiseEventHandler(elBtn, flagInitialised, function(){ - elBtn.addEventListener("click", function(event) { - event.stopPropagation(); - let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elBtn)).querySelector('input[type="number"]'); - let newVal = parseInt(getElementCurrentValue(elInput)); - if (isNaN(newVal)) newVal = minVal; - newVal = Math.max(minVal, newVal - 1); - elInput.val(newVal); - elInput.trigger("change"); - }); - }); - }); - } - - hookupBasketAddInputs() { - - document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() { - let elForm = this; - let elInput = elForm.querySelector('input[type="number"]'); - initialiseEventHandler(elInput, flagInitialised, function(){ - elInput.addEventListener("change", function(event) { - event.preventDefault(); - event.stopPropagation(); - }); - elInput.addEventListener("click", function(event) { - event.preventDefault(); - event.stopPropagation(); - }); - }); - }); - } - - hookupBasketEditInputs() { - - // let elBtn, elInput, newVal, product; - const minVal = 1; - // Basket Edit - // Increment - document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { - let elForm = this; - let elInput = elForm.querySelector('input[type="number"]'); - initialiseEventHandler(elInput, flagInitialised, function(){ - elInput.addEventListener("change", function(event) { - event.preventDefault(); - event.stopPropagation(); - // let lsPage = getPageLocalStorageCurrent(); - d = {}; - d[keyBasket]= getLocalStorage(keyBasket); // lsPage[keyBasket]; // JSON.parse(lsPage[keyBasket]); - d[keyIdProduct] = elForm.attr(attrIdProduct); // lsPage[keyIdProduct]; - d[keyIdPermutation] = elForm.attr(attrIdPermutation); - // d[keyQuantity] = lsPage[keyQuantity]; - d[keyForm] = convertForm2JSON(elForm); - d[keyForm][keyQuantity] = elInput.val(); - console.log('sending data to basket edit controller: '); console.log(d); - ajaxJSONData('basket update', mapHashToController(hashStoreBasketEdit), d, loadBasket, false); - }); - }); - }); - } - - hookupBtnsDelete() { - - console.log('hooking up basket item delete buttons'); - // let elForm, elDelete; - // const minVal = 1; - // Basket Add - // Increment - document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() { - let elForm = this; - let elDelete = elForm.querySelector('a.' + flagBasketItemDelete); - initialiseEventHandler(elDelete, flagInitialised, function(){ - elDelete.addEventListener("click", function(event) { - event.stopPropagation(); - ajaxData = {}; - ajaxData[keyBasket]= getLocalStorage(keyBasket); - ajaxData[keyIdProduct] = elForm.attr(attrIdProduct); - ajaxData[keyIdPermutation] = elForm.attr(attrIdPermutation); - console.log('sending data to basket delete controller: '); console.log(ajaxData); - ajaxJSONData('basket update', mapHashToController(hashStoreBasketDelete), ajaxData, loadBasket, false); - }); - }); - }); - } getCurrencySelected() { let elementSelectorCurrency = document.querySelectorAll(idSelectorCurrency); @@ -379,4 +467,52 @@ export class PageStoreHome extends PageBase { jsonData[keyIsIncludedVAT] = getLocalStorage(keyIsIncludedVAT); return jsonData; } + + hookupStoreCardsProduct() { + + let d; // , lsShared; + let selectorCardProduct = '.card.subcard'; + initialiseEventHandler(selectorCardProduct, flagInitialised, function(cardProduct) { + console.log("initialising product card: ", cardProduct); + cardProduct.addEventListener("click", function(event) { + // d = { keyIdProduct: product.attr(attrIdProduct) } + var elemClicked = event.target; + if (elemClicked.id != 'submit') { // disable for submit buttons + console.log("product click: " + cardProduct.attr(attrIdProduct)); + console.log("permutation click: " + cardProduct.attr(attrIdPermutation)); + var d = {} + d[keyIdProduct] = cardProduct.attr(attrIdProduct) + d[keyIdPermutation] = cardProduct.attr(attrIdPermutation) + // send quantity requested + goToPage(hashPageStoreProduct, d); + } + }); + console.log("click method added for product ID: " + cardProduct.attr(attrIdProduct) + ', permutation ID: ', cardProduct.attr(attrIdPermutation)); + }); + } + + leave() { + let lsOld = getPageLocalStorage(hashPageCurrent); + hashPageCurrent = pageHashNext; + clearPageLocalStorage(hashPageCurrent); + setupPageLocalStorage(hashPageCurrent); + let lsNew = getPageLocalStorage(hashPageCurrent); + lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; + setPageLocalStorage(hashPageCurrent, lsNew); + } + + /* + loadFiltersFromLocalStorage(pageHash, parameters_dict) { + + let lsOld = getPageLocalStorage(pageHashCurrent); + pageHashCurrent = pageHash; + clearPageLocalStorage(pageHashCurrent); + setupPageLocalStorage(pageHashCurrent); + let lsNew = getPageLocalStorage(pageHashCurrent); + lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []}; + setPageLocalStorage(pageHashCurrent, lsNew); + + goToPage(pageHash, parameters_dict); + } + */ } \ No newline at end of file diff --git a/static/js/pages/page_store_basket.js b/static/js/pages/store/basket.js similarity index 92% rename from static/js/pages/page_store_basket.js rename to static/js/pages/store/basket.js index 3a84fb37..94482982 100644 --- a/static/js/pages/page_store_basket.js +++ b/static/js/pages/store/basket.js @@ -1,6 +1,6 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageStoreBasket extends PageBase { +export class PageStoreBasket extends BasePage { static hash = hashPageStoreBasket; constructor() { @@ -11,7 +11,7 @@ export class PageStoreBasket extends PageBase { this.sharedInitialize(); this.hookupStoreCardsInfo(); this.hookupOverlaysStoreBasketInfo(); - this.hookupBtnCheckoutSession(); + this.hookupButtonCheckoutSession(); } @@ -134,10 +134,10 @@ export class PageStoreBasket extends PageBase { return ajaxData; } - hookupBtnCheckoutSession() { - let btnCheckout = document.querySelectorAll(idBtnCheckout); + hookupButtonCheckoutSession() { + let btnCheckout = document.querySelectorAll(idButtonCheckout); btnCheckout.classList.remove(flagInitialised); - initialiseEventHandler(idBtnCheckout, flagInitialised, function() { + initialiseEventHandler(idButtonCheckout, flagInitialised, function() { btnCheckout.removeEventListener("click"); btnCheckout.addEventListener("click", function(event) { @@ -165,12 +165,12 @@ export class PageStoreBasket extends PageBase { window.location.href = response.data[keyUrlCheckout] } - hookupBtnFormBillingCopy() { + hookupButtonFormBillingCopy() { - // let elBtn = document.querySelectorAll(idBtnFormBillingCopy); + // let elButton = document.querySelectorAll(idButtonFormBillingCopy); - initialiseEventHandler(idBtnFormBillingCopy, flagInitialised, function() { - document.querySelectorAll(idBtnFormBillingCopy).addEventListener("click", function (event) { + initialiseEventHandler(idButtonFormBillingCopy, flagInitialised, function() { + document.querySelectorAll(idButtonFormBillingCopy).addEventListener("click", function (event) { let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty]; diff --git a/static/js/pages/store/home.js b/static/js/pages/store/home.js new file mode 100644 index 00000000..160e8518 --- /dev/null +++ b/static/js/pages/store/home.js @@ -0,0 +1,20 @@ + +import { BasePage } from "../base.js"; + +export class PageStoreHome extends BasePage { + static hash = hashPageStoreHome; + + constructor() { + super(); + } + + initialize() { + this.sharedInitialize(); + this.hookupFiltersStore(); + this.hookupStoreHome(); + } + + leave() { + super.leave(); + } +} diff --git a/static/js/pages/store/product_categories.js b/static/js/pages/store/product_categories.js new file mode 100644 index 00000000..00b11df5 --- /dev/null +++ b/static/js/pages/store/product_categories.js @@ -0,0 +1,129 @@ + +import { TableBasePage } from "../base_table.js"; +import API from "../../api.js"; +import DOM from "../../dom.js"; + +export class PageStoreProductCategories extends TableBasePage { + static hash = hashPageStoreProductCategories; + callFilterTableContent = API.getCategoriesByFilters; + callSaveTableContent = API.saveCategories; + + constructor() { + super(); + } + + initialize() { + super.initialize(); + } + + hookupFilters() { + super.hookupFilters(); + this.hookupFilterIsNotEmpty(); + this.hookupFilterActive(); + } + hookupFilterIsNotEmpty() { + initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => { + filter.addEventListener("change", (event) => { + PageStoreProductCategories.isDirtyFilter(filter); + }); + }); + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagRowNew); + row.classList.remove(flagInitialised); + row.querySelectorAll('.' + flagInitialised).forEach(function(element) { + element.classList.remove(flagInitialised); + }); + console.log("applying data row: ", rowJson); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + sliderDisplayOrder.setAttribute(attrValueCurrent, rowJson[flagDisplayOrder]); + DOM.setElementValuePrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]); + DOM.setElementValueCurrent(textareaCode, rowJson[flagCode]); + DOM.setElementValuePrevious(textareaCode, rowJson[flagCode]); + DOM.setElementValueCurrent(textareaName, rowJson[flagName]); + DOM.setElementValuePrevious(textareaName, rowJson[flagName]); + DOM.setElementValueCurrent(textareaDescription, rowJson[flagDescription]); + DOM.setElementValuePrevious(textareaDescription, rowJson[flagDescription]); + tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]); + divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValueCurrent(divAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValuePrevious(divAccessLevel, rowJson[attrIdAccessLevel]); + divAccessLevel.textContent = rowJson[flagAccessLevelRequired]; + DOM.setElementValueCurrent(inputActive, rowJson[flagActive]); + DOM.setElementValuePrevious(inputActive, rowJson[flagActive]); + row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]); + + let table = this.getTableMain(); + let bodyTable = table.querySelector('tbody'); + bodyTable.appendChild(row); + } + getJsonRow(row) { + if (row == null) return; + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + let jsonCategory = {}; + jsonCategory[attrIdCategory] = row.getAttribute(attrIdCategory); + jsonCategory[flagCode] = DOM.getElementValueCurrent(textareaCode); + jsonCategory[flagName] = DOM.getElementValueCurrent(textareaName); + jsonCategory[flagDescription] = DOM.getElementValueCurrent(textareaDescription); + jsonCategory[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired); + jsonCategory[attrIdAccessLevel] = tdAccessLevel.getAttribute(attrIdAccessLevel); + jsonCategory[flagActive] = DOM.getElementValueCurrent(inputActive); + jsonCategory[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent); + return jsonCategory; + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSlidersDisplayOrderTable(); + this.hookupTextareasCodeTable(); + this.hookupTextareasNameTable(); + this.hookupTextareasDescriptionTable(); + this.hookupTdsAccessLevel(); + this.hookupInputsActiveTable(); + } + + isDirtyRow(row) { + if (row == null) return false; + console.log("Product Category isDirtyRow"); + console.log("row: ", row); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder); + let inputCode = row.querySelector('td.' + flagCode + ' textarea'); + let inputName = row.querySelector('td.' + flagName + ' textarea'); + let inputDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) || + inputDescription.classList.contains(flagDirty) || tdAccessLevel.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty); + DOM.handleDirtyElement(row, isDirty); + return isDirty; + } + + leave() { + super.leave(); + } + + getFiltersDefaults() { + filters = {}; + filters.flagIsNotEmpty = true; + filters.flagActive = true; + return filters; + } +} + diff --git a/static/js/pages/page_store_product_permutations.js b/static/js/pages/store/product_permutations.js similarity index 99% rename from static/js/pages/page_store_product_permutations.js rename to static/js/pages/store/product_permutations.js index 88ef616a..ef4ceabd 100644 --- a/static/js/pages/page_store_product_permutations.js +++ b/static/js/pages/store/product_permutations.js @@ -1,8 +1,7 @@ -var _rowBlank = null; -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageStoreProductPermutations extends PageBase { +export class PageStoreProductPermutations extends BasePage { static hash = hashPageStoreProductPermutations; constructor() { diff --git a/static/js/pages/page_store_stock_items.js b/static/js/pages/store/stock_items.js similarity index 72% rename from static/js/pages/page_store_stock_items.js rename to static/js/pages/store/stock_items.js index f3604191..29cc19b0 100644 --- a/static/js/pages/page_store_stock_items.js +++ b/static/js/pages/store/stock_items.js @@ -1,9 +1,9 @@ -var _rowBlank = null; -import { PageBase } from "./page_base.js"; -export class PageStoreStockItems extends PageBase { +import { BasePage } from "../base.js"; + +export class PageStoreStockItems extends BasePage { static hash = hashPageStoreStockItems; constructor() { @@ -12,8 +12,8 @@ export class PageStoreStockItems extends PageBase { initialize() { this.sharedInitialize(); - hookupFilters(); - hookupButtonsSaveCancel(); + this.hookupFilters(); + this.hookupButtonsSaveCancel(); hookupTableMain(); hookupOverlayConfirm(savePermutations); } @@ -213,7 +213,7 @@ export class PageStoreStockItems extends PageBase { let table = document.querySelectorAll(idTableMain); let rowBlankTemp = table.querySelector('tr.' + flagRowNew); console.log("row blank temp: ", rowBlankTemp); - _rowBlank = rowBlankTemp[0].cloneNode(true); + _rowBlank = rowBlankTemp.cloneNode(true); table.querySelector('tr.' + flagRowNew).remove(); /* @@ -370,8 +370,138 @@ export class PageStoreStockItems extends PageBase { }); return variations.join(','); } +} + + +import { TableBasePage } from "../base_table.js"; +import API from "../../api.js"; +import DOM from "../../dom.js"; + +export class PageStoreProductCategories extends TableBasePage { + static hash = hashPageStoreProductCategories; + callFilterTableContent = API.getCategoriesByFilters; + + constructor() { + super(); + } + + initialize() { + super.initialize(); + } + + hookupFilters() { + super.hookupFilters(); + this.hookupFilterIsNotEmpty(); + this.hookupFilterActive(); + } + hookupFilterIsNotEmpty() { + initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => { + filter.addEventListener("change", (event) => { + PageStoreProductCategories.isDirtyFilter(filter); + }); + }); + } + + loadRowTable(rowJson) { + if (rowJson == null) return; + let row = _rowBlank.cloneNode(true); + row.classList.remove(flagRowNew); + row.classList.remove(flagInitialised); + row.querySelectorAll('.' + flagInitialised).forEach(function(element) { + element.classList.remove(flagInitialised); + }); + console.log("applying data row: ", rowJson); + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + sliderDisplayOrder.setAttribute(attrValueCurrent, rowJson[flagDisplayOrder]); + DOM.setElementValuePrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]); + DOM.setElementValueCurrent(textareaCode, rowJson[flagCode]); + DOM.setElementValuePrevious(textareaCode, rowJson[flagCode]); + DOM.setElementValueCurrent(textareaName, rowJson[flagName]); + DOM.setElementValuePrevious(textareaName, rowJson[flagName]); + DOM.setElementValueCurrent(textareaDescription, rowJson[flagDescription]); + DOM.setElementValuePrevious(textareaDescription, rowJson[flagDescription]); + tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]); + divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValueCurrent(divAccessLevel, rowJson[attrIdAccessLevel]); + DOM.setElementValuePrevious(divAccessLevel, rowJson[attrIdAccessLevel]); + divAccessLevel.textContent = rowJson[flagAccessLevelRequired]; + DOM.setElementValueCurrent(inputActive, rowJson[flagActive]); + DOM.setElementValuePrevious(inputActive, rowJson[flagActive]); + row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]); + + let table = this.getTableMain(); + let bodyTable = table.querySelector('tbody'); + bodyTable.appendChild(row); + } + getJsonRow(row) { + if (row == null) return; + let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider); + let textareaCode = row.querySelector('td.' + flagCode + ' textarea'); + let textareaName = row.querySelector('td.' + flagName + ' textarea'); + let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea'); + let tdAccessLevel = row.querySelector('td.' + flagAccessLevel); + let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]'); + + let jsonCategory = {}; + jsonCategory[attrIdCategory] = row.getAttribute(attrIdCategory); + jsonCategory[flagCode] = DOM.getElementValueCurrent(textareaCode); + jsonCategory[flagName] = DOM.getElementValueCurrent(textareaName); + jsonCategory[flagDescription] = DOM.getElementValueCurrent(textareaDescription); + jsonCategory[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired); + jsonCategory[attrIdAccessLevel] = tdAccessLevel.getAttribute(attrIdAccessLevel); + jsonCategory[flagActive] = DOM.getElementValueCurrent(inputActive); + jsonCategory[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent); + return jsonCategory; + } + + hookupTableMain() { + super.hookupTableMain(); + this.hookupSlidersDisplayOrderTable(); + this.hookupTextareasCodeTable(); + this.hookupTextareasNameTable(); + this.hookupTextareasDescriptionTable(); + this.hookupTdsAccessLevel(); + this.hookupInputsActiveTable(); + } + + isRowDirty(row) { + if (row == null) return; + let ddlCategory = row.querySelector('td.' + flagCategory + ' select'); + let ddlProduct = row.querySelector('td.' + flagProduct + ' select'); + let variations = row.querySelector('td.' + flagVariations + ' textarea'); + let quantityStock = row.querySelector('td.' + flagQuantityStock + ' input'); + let quantityMin = row.querySelector('td.' + flagQuantityMin + ' input'); + let quantityMax = row.querySelector('td.' + flagQuantityMax + ' input'); + + // return isElementDirty(ddlCategory) || isElementDirty(ddlProduct) || isElementDirty(variations) || isElementDirty(quantityStock) || isElementDirty(quantityMin) || isElementDirty(quantityMax); + let isDirty = ddlCategory.classList.contains(flagDirty) || ddlProduct.classList.contains(flagDirty) || variations.classList.contains(flagDirty) || + quantityStock.classList.contains(flagDirty) || quantityMin.classList.contains(flagDirty) || quantityMax.classList.contains(flagDirty); + if (isDirty) { + row.classList.add(flagDirty); + } else { + row.classList.remove(flagDirty); + } + return isDirty; + } + leave() { super.leave(); } -} \ No newline at end of file + + getFiltersDefaults() { + filters = {}; + filters.flagIsNotEmpty = true; + filters.flagActive = true; + return filters; + } +} + diff --git a/static/js/pages/page_user.js b/static/js/pages/user/user.js similarity index 72% rename from static/js/pages/page_user.js rename to static/js/pages/user/user.js index aec6a7cc..2e6c451a 100644 --- a/static/js/pages/page_user.js +++ b/static/js/pages/user/user.js @@ -1,7 +1,7 @@ -import { PageBase } from "./page_base.js"; +import { BasePage } from "../base.js"; -export class PageUser extends PageBase { +export class PageUser extends BasePage { static hash = hashPageUser; constructor() { diff --git a/static/js/router.js b/static/js/router.js index 14f4f9fd..d290cb20 100644 --- a/static/js/router.js +++ b/static/js/router.js @@ -1,36 +1,117 @@ -import { PageAdminHome } from './pages/page_admin_home.js'; -import { PageHome } from './pages/page_home.js'; -import { PageContact } from './pages/page_contact.js'; -import { PageAccessibilityStatement } from './pages/page_accessibility_statement.js'; -import { PageLicense } from './pages/page_license.js'; -import { PageServices } from './pages/page_services.js'; -import { PageStoreBasket } from './pages/page_store_basket.js'; -import { PageStoreHome } from './pages/page_store_home.js'; -import { PageStoreProductCategories } from './pages/page_store_product_categories.js'; -import { PageStoreProductPermutations } from './pages/page_store_product_permutations.js'; -// import { PageStoreProductPrices } from './pages/page_store_product_prices.js'; -// import { PageStoreProducts } from './pages/page_store_products.js'; -// import { PageStoreProductVariations } from './pages/page_store_product_variations.js'; -import { PageStoreStockItems } from './pages/page_store_stock_items.js'; +/* +import { PageAdminHome } from './pages/core/admin_home.js'; +import { PageHome } from './pages/core/home.js'; +import { PageContact } from './pages/core/contact.js'; +import { PageAccessibilityStatement } from './pages/legal/accessibility_statement.js'; +import { PageLicense } from './pages/legal/license.js'; +import { PageServices } from './pages/core/services.js'; +import { PageStoreBasket } from './pages/store/basket.js'; +import { PageStoreHome } from './pages/store/home.js'; +import { PageStoreProductCategories } from './pages/store/product_categories.js'; +import { PageStoreProductPermutations } from './pages/store/product_permutations.js'; +// import { PageStoreProductPrices } from './pages/store/product_prices.js'; +// import { PageStoreProducts } from './pages/store/products.js'; +// import { PageStoreProductVariations } from './pages/store/product_variations.js'; +import { PageStoreStockItems } from './pages/store/stock_items.js'; +*/ import API from './api.js'; import DOM from './dom.js'; export default class Router { constructor() { + // Pages + this.pages = {}; + // Core + this.pages[hashPageHome] = { name: 'PageHome', pathModule: './pages/core/home.js' }; + this.pages[hashPageContact] = { name: 'PageContact', pathModule: './pages/core/contact.js' }; + this.pages[hashPageServices] = { name: 'PageServices', pathModule: './pages/core/services.js' }; + this.pages[hashPageAdminHome] = { name: 'PageAdminHome', pathModule: './pages/core/admin_home.js' }; + // Legal + this.pages[hashPageAccessibilityStatement] = { name: 'PageAccessibilityStatement', pathModule: './pages/legal/accessibility_statement.js' }; + this.pages[hashPageLicense] = { name: 'PageLicense', pathModule: './pages/legal/license.js' }; + // Store + this.pages[hashPageStoreProductCategories] = { name: 'PageStoreProductCategories', pathModule: './pages/store/product_categories.js' }; + this.pages[hashPageStoreProductPermutations] = { name: 'PageStoreProductPermutations', pathModule: './pages/store/product_permutations.js' }; + // this.pages[hashPageStoreProductPrices] = { name: 'PageStoreProductPrices', pathModule: './pages/store/product_prices.js' }; + this.pages[hashPageStoreProducts] = { name: 'PageStoreProducts', pathModule: './pages/store/products.js' }; + // this.pages[hashPageStoreProductVariations] = { name: 'PageStoreProductVariations', pathModule: './pages/store/product_variations.js' }; + // User + // this.pages[hashPageUserLogin] = { name: 'PageUserLogin', pathModule: './pages/user/login.js' }; + // this.pages[hashPageUserLogout] = { name: 'PageUserLogout', pathModule: './pages/user/logout.js' }; + // this.pages[hashPageUserAccount] = { name: 'PageUserAccount', pathModule: './pages/user/account.js' }; + + // Routes this.routes = {}; + // Core + this.routes[hashPageHome] = (isPopState = false) => this.navigateToHash(hashPageHome, isPopState); + this.routes[hashPageContact] = (isPopState = false) => this.navigateToHash(hashPageContact, isPopState); + this.routes[hashPageServices] = (isPopState = false) => this.navigateToHash(hashPageServices, isPopState); + this.routes[hashPageAdminHome] = (isPopState = false) => this.navigateToHash(hashPageAdminHome, isPopState); + // Legal + this.routes[hashPageAccessibilityStatement] = (isPopState = false) => this.navigateToHash(hashPageAccessibilityStatement, isPopState); + this.routes[hashPageLicense] = (isPopState = false) => this.navigateToHash(hashPageLicense, isPopState); + // Store + this.routes[hashPageStoreProductCategories] = (isPopState = false) => this.navigateToHash(hashPageStoreProductCategories, isPopState); + this.routes[hashPageStoreProductPermutations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPermutations, isPopState); + // this.routes[hashPageStoreProductPrices] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPrices, isPopState); + this.routes[hashPageStoreProducts] = (isPopState = false) => this.navigateToHash(hashPageStoreProducts, isPopState); + // this.routes[hashPageStoreProductVariations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductVariations, isPopState); + // User + // this.routes[hashPageUserLogin] = (isPopState = false) => this.navigateToHash(hashPageUserLogin, isPopState); + // this.routes[hashPageUserLogout] = (isPopState = false) => this.navigateToHash(hashPageUserLogout, isPopState); + // this.routes[hashPageUserAccount] = (isPopState = false) => this.navigateToHash(hashPageUserAccount, isPopState); this.initialize(); } - + async loadPage(hashPage, isPopState = false) { + const PageClass = await this.getClassPageFromHash(hashPage); + this.currentPage = new PageClass(); + this.currentPage.initialize(isPopState); + } + async getClassPageFromHash(hashPage) { + let pageJson = this.pages[hashPage]; + const module = await import(pageJson.pathModule); + return module[pageJson.name]; + } initialize() { + /* let pages = Router.getPages(); for (const key of Object.keys(pages)) { let page = pages[key]; this.addRoute(page.hash, page.initialize); } + */ window.addEventListener('popstate', this.handlePopState.bind(this)); // page accessed by history navigation } + handlePopState(event) { + this.loadPageCurrent(); + } + loadPageCurrent() { + const hashPageCurrent = DOM.getHashPageCurrent(); + this.loadPage(hashPageCurrent); + } + navigateToHash(hash, data = null, params = null, isPopState = false) { + this.beforeLeave(); + /* + if (this.routes[hash]) { + console.log("navigating to hash: " + hash); + this.routes[hash](isPopState); + } else { + console.error(`Hash ${hash} not found`); + } + */ + let url = API.getUrlFromHash(hash, params); + // if (!isPopState) + history.pushState(data, '', url); + API.goToUrl(url, data); + } + async beforeLeave() { + const ClassPageCurrent = await this.getClassPageFromHash(DOM.getHashPageCurrent()); + const pageCurrent = new ClassPageCurrent(); + pageCurrent.leave(); + } + /* static getPages() { let pages = {}; pages[hashPageAccessibilityStatement] = PageAccessibilityStatement; @@ -56,15 +137,19 @@ export default class Router { } handlePopState(event) { + /* let url = window.location.pathname; url = url.split('?')[0]; let hash = url.replace(_pathHost, ''); console.log("handlePopState: " + hash); this.handleRouteHash(hash); + * + let pageCurrent = Router.getPageCurrent(); + pageCurrent.initialize(true); } navigateToHash(hash, data = null) { - const url = Router.getUrlFromHash(hash); + const url = API.getUrlFromHash(hash); this.navigateToUrl(url, data); } @@ -109,11 +194,8 @@ export default class Router { } return url; } + */ - static #goToUrl(url) { - window.location.href = url; - } - /* handleRouteUrl(url) { const path = url.split('?')[0]; // Remove query parameters diff --git a/static/js/sections/core.js b/static/js/sections/core.js new file mode 100644 index 00000000..e69de29b diff --git a/static/js/sections/store.js b/static/js/sections/store.js new file mode 100644 index 00000000..e69de29b diff --git a/stderr.log b/stderr.log index 7287656e..13cd0a4d 100644 --- a/stderr.log +++ b/stderr.log @@ -5150,7 +5150,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5203,7 +5203,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5248,7 +5248,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5309,7 +5309,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5354,7 +5354,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5399,7 +5399,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5460,7 +5460,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_contact.html", line 1, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5520,7 +5520,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5573,7 +5573,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5618,7 +5618,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5663,7 +5663,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5708,7 +5708,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5753,7 +5753,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_home.html", line 3, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 90, in top-level template code Contact @@ -5886,7 +5886,7 @@ Traceback (most recent call last): File "/home/partsltd/virtualenv/public_html/parts_website/3.11/lib/python3.11/site-packages/jinja2/environment.py", line 936, in handle_exception raise rewrite_traceback_stack(source=source) File "/home/partsltd/public_html/parts_website/templates/_page_contact.html", line 1, in top-level template code - {% extends 'layout.html' %} + {% extends 'layouts/layout.html' %} ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/partsltd/public_html/parts_website/templates/layout.html", line 138, in top-level template code {% block page_body %}{% endblock %} diff --git a/templates/DEPRECATED/DEPRECATED_block_store_product.html b/templates/DEPRECATED/DEPRECATED_block_store_product.html index 44765124..8b58a82f 100644 --- a/templates/DEPRECATED/DEPRECATED_block_store_product.html +++ b/templates/DEPRECATED/DEPRECATED_block_store_product.html @@ -14,7 +14,7 @@

{{ product.name }}

{{ permutation.output_price(model.is_included_VAT) }}

{% set tmp_quantity = 1 %} - {% include '_block_input_number_plus_minus.html' %} + {% include 'components/common/inputs/_input_number_plus_minus.html' %} {{ form.submit() }}

Get it: {{ permutation.output_delivery_date() }}

diff --git a/templates/DEPRECATED/DEPRECATED_block_store_product_price.html b/templates/DEPRECATED/DEPRECATED_block_store_product_price.html index 625e1ddc..aaa58302 100644 --- a/templates/DEPRECATED/DEPRECATED_block_store_product_price.html +++ b/templates/DEPRECATED/DEPRECATED_block_store_product_price.html @@ -6,7 +6,7 @@
{{ form.hidden_tag() }} {% set tmp_quantity = 1 %} - {% include '_block_input_number_plus_minus.html' %} + {% include 'components/common/inputs/_input_number_plus_minus.html' %} {{ form.submit() }}
-{% elif block_id == 'checkout' %} - - -{% elif block_id == 'Textarea_Product_Permutation_Variations' %} - -{% elif block_id == 'Textarea_Product_Permutation_Variations_Blank' %} - -{% endif %} \ No newline at end of file diff --git a/templates/_blocks_button_save_cancel.html b/templates/components/common/buttons/_buttons_save_cancel.html similarity index 100% rename from templates/_blocks_button_save_cancel.html rename to templates/components/common/buttons/_buttons_save_cancel.html diff --git a/templates/components/common/buttons/_slider_display_order.html b/templates/components/common/buttons/_slider_display_order.html new file mode 100644 index 00000000..a1d10ce7 --- /dev/null +++ b/templates/components/common/buttons/_slider_display_order.html @@ -0,0 +1,8 @@ +{% if display_order is defined %} + + +{% else %} +
+{% endif %} \ No newline at end of file diff --git a/templates/_block_input_number_plus_minus.html b/templates/components/common/inputs/_input_number_plus_minus.html similarity index 100% rename from templates/_block_input_number_plus_minus.html rename to templates/components/common/inputs/_input_number_plus_minus.html diff --git a/templates/components/common/inputs/_textarea_product_permutation_variations.html b/templates/components/common/inputs/_textarea_product_permutation_variations.html new file mode 100644 index 00000000..54e74042 --- /dev/null +++ b/templates/components/common/inputs/_textarea_product_permutation_variations.html @@ -0,0 +1,18 @@ + +{% if variation_tree is not defined %} + {% set is_blank_row = True %} +{% endif %} +{% if is_blank_row is not defined %} + {% set is_blank_row = True %} +{% endif %} + +{% if not is_blank_row %} + {% set json_str_variations = permutation.variation_tree.to_json_str() %} + +{% else %} + +{% endif %} \ No newline at end of file diff --git a/templates/components/common/inputs/_textarea_product_variation_types.html b/templates/components/common/inputs/_textarea_product_variation_types.html new file mode 100644 index 00000000..d3cd1126 --- /dev/null +++ b/templates/components/common/inputs/_textarea_product_variation_types.html @@ -0,0 +1,20 @@ + +{% if variation_tree is not defined %} + {% set is_blank_row = True %} +{% endif %} +{% if is_blank_row is not defined %} + {% set is_blank_row = True %} +{% endif %} + +{% if not is_blank_row %} + {# % set json_str_variation_types = product.get_json_str_types_variation_trees() % #} + {% set names_variation_type = product.get_variation_types_unique() %} + {% set json_str_variation_types = jsonify(names_variation_type) %} + +{% else %} + +{% endif %} \ No newline at end of file diff --git a/templates/_block_overlay_address.html b/templates/components/common/temporary/_overlay_address.html similarity index 76% rename from templates/_block_overlay_address.html rename to templates/components/common/temporary/_overlay_address.html index 994d9775..e35992d9 100644 --- a/templates/_block_overlay_address.html +++ b/templates/components/common/temporary/_overlay_address.html @@ -6,5 +6,5 @@ string overlay_title --> {% block overlay_body %} - {% include '_block_store_address.html' %} + {% include 'components/store/_address.html' %} {% endblock %} \ No newline at end of file diff --git a/templates/_block_overlay_confirm.html b/templates/components/common/temporary/_overlay_confirm.html similarity index 93% rename from templates/_block_overlay_confirm.html rename to templates/components/common/temporary/_overlay_confirm.html index 8f8d6cb6..5da1ef30 100644 --- a/templates/_block_overlay_confirm.html +++ b/templates/components/common/temporary/_overlay_confirm.html @@ -7,9 +7,9 @@
{% set block_id = 'button_cancel' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %} {% set block_id = 'button_confirm' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
diff --git a/templates/_block_overlay_error.html b/templates/components/common/temporary/_overlay_error.html similarity index 94% rename from templates/_block_overlay_error.html rename to templates/components/common/temporary/_overlay_error.html index 92a7d78d..b7b1c745 100644 --- a/templates/_block_overlay_error.html +++ b/templates/components/common/temporary/_overlay_error.html @@ -5,7 +5,7 @@
{% set block_id = 'button_cancel' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
diff --git a/templates/_template_overlay.html b/templates/components/common/temporary/template_overlay.html similarity index 100% rename from templates/_template_overlay.html rename to templates/components/common/temporary/template_overlay.html diff --git a/templates/_block_store_home_body.html b/templates/components/store/_body_home.html similarity index 62% rename from templates/_block_store_home_body.html rename to templates/components/store/_body_home.html index a8380b73..ab55aa8b 100644 --- a/templates/_block_store_home_body.html +++ b/templates/components/store/_body_home.html @@ -1,28 +1,30 @@ {% set block_id = 'styles' %} -{% include '_shared_store.html' %} +{% include 'layouts/_shared_store.html' %} - + +
{% for cat in model.category_list.categories %} {% if cat.is_available() %} - {% include '_block_store_product_category.html' %} + {% include 'components/store/_product_category.html' %} {% endif %} {% endfor %}
- {% include '_block_store_basket.html' %} + {% include 'components/store/_basket.html' %}
{% set block_id = 'scripts' %} -{% include '_shared_store.html' %} +{% include 'layouts/_shared_store.html' %} - + + +{% endif %} \ No newline at end of file diff --git a/templates/layout.html b/templates/layouts/layout.html similarity index 95% rename from templates/layout.html rename to templates/layouts/layout.html index 1765096c..f9055682 100644 --- a/templates/layout.html +++ b/templates/layouts/layout.html @@ -47,11 +47,14 @@ @@ -298,7 +315,7 @@ - + diff --git a/templates/_page_admin_home.html b/templates/pages/core/_admin_home.html similarity index 86% rename from templates/_page_admin_home.html rename to templates/pages/core/_admin_home.html index 4c624cc0..23a11405 100644 --- a/templates/_page_admin_home.html +++ b/templates/pages/core/_admin_home.html @@ -1,10 +1,11 @@ -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block title %}{{ model.title }}{% endblock %} {% block page_body %} - + +
@@ -37,8 +38,9 @@
- - + + + - + + @@ -80,13 +81,14 @@

{{ model.app.MAIL_CONTACT_PUBLIC }}

- LinkedIn - GitHub + LinkedIn + GitHub
- + + + + -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block title %}{{ model.title }}{% endblock %} {% block page_body %} - + +
@@ -101,7 +102,8 @@
- + + - + +
@@ -48,7 +49,7 @@ If you need information on this website in a different format like accessible PDF, large print, easy read, audio recording or braille:

{% set block_id = 'button_get_in_touch' %} - {% include '_shared.html' %} + {% include 'layouts/_shared.html' %}

We’ll consider your request and get back to you in 7 days. @@ -202,5 +203,6 @@

- + + {% endblock %} \ No newline at end of file diff --git a/templates/_page_license.html b/templates/pages/legal/_license.html similarity index 86% rename from templates/_page_license.html rename to templates/pages/legal/_license.html index dfe1a805..b8efc112 100644 --- a/templates/_page_license.html +++ b/templates/pages/legal/_license.html @@ -1,35 +1,37 @@ -{% extends 'layout.html' %} - -{% block title %}{{ model.title }}{% endblock %} - -{% block page_body %} - - - - -
-

Copyright © 2024 Precision And Research Technology Systems Limited -

-

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -

- -

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -

- -

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -

-
- - - - - +{% extends 'layouts/layout.html' %} + +{% block title %}{{ model.title }}{% endblock %} + +{% block page_body %} + + + + + +
+

Copyright © 2024 Precision And Research Technology Systems Limited +

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +

+ +

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +

+ +

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +

+
+ + + + + + {% endblock %} \ No newline at end of file diff --git a/templates/_page_privacy_notice.html b/templates/pages/legal/_privacy_notice.html similarity index 94% rename from templates/_page_privacy_notice.html rename to templates/pages/legal/_privacy_notice.html index 860a0e47..686b5ebe 100644 --- a/templates/_page_privacy_notice.html +++ b/templates/pages/legal/_privacy_notice.html @@ -1,10 +1,11 @@ -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block title %}{{ model.title }}{% endblock %} {% block page_body %} - + +
@@ -80,7 +81,8 @@
- + + - + +
@@ -1946,7 +1947,8 @@
- + + - {% set block_id = 'styles' %} - {% include '_shared_store.html' %} - + +
@@ -25,7 +24,7 @@
- {% include '_block_store_basket.html' %} + {% include 'components/store/_basket.html' %}
- {% set block_id = 'scripts' %} - {% include '_shared_store.html' %} - + + {% set block_id = 'checkout' %} - {% include '_shared_store.html' %} + {% include 'layouts/_shared_store.html' %} - {% set block_id = 'styles' %} - {% include '_shared_store.html' %} + +
@@ -26,11 +26,10 @@
- {% set block_id = 'scripts' %} - {% include '_shared_store.html' %} - + + {% set block_id = 'checkout' %} - {% include '_shared_store.html' %} + {% include 'layouts/_shared_store.html' %} +
{{ model.form_filters.hidden_tag() }}
@@ -28,7 +27,7 @@
{% set block_id = 'button_apply_filters' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
+ + + + {% endblock %} \ No newline at end of file diff --git a/templates/_page_store_product_permutations.html b/templates/pages/store/_product_permutations.html similarity index 82% rename from templates/_page_store_product_permutations.html rename to templates/pages/store/_product_permutations.html index 6251047f..a829773a 100644 --- a/templates/_page_store_product_permutations.html +++ b/templates/pages/store/_product_permutations.html @@ -1,17 +1,16 @@ -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block page_body %} - {% set block_id = 'styles' %} - {% include '_shared_store.html' %} - + + - + {{ model.form_filters.hidden_tag() }}
@@ -66,19 +65,19 @@
{% set block_id = 'button_add' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
{% set block_id = 'button_save' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
{% set block_id = 'button_cancel' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
- + + + + + +{% endblock %} \ No newline at end of file diff --git a/templates/_page_store_stock_items.html b/templates/pages/store/_stock_items.html similarity index 85% rename from templates/_page_store_stock_items.html rename to templates/pages/store/_stock_items.html index 0fd3dc9b..a2adbd53 100644 --- a/templates/_page_store_stock_items.html +++ b/templates/pages/store/_stock_items.html @@ -1,10 +1,9 @@ -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block page_body %} - {% set block_id = 'styles' %} - {% include '_shared_store.html' %} - + + @@ -58,11 +57,11 @@
{% set block_id = 'button_save' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %} {% set block_id = 'button_cancel' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %} {% set block_id = 'button_add' %} - {% include '_blocks_button_save_cancel.html' %} + {% include 'components/common/buttons/_buttons_save_cancel.html' %}
@@ -98,24 +97,23 @@ {% for permutation in product.permutations %} {% for stock_item in permutation.stock_items %} {% set is_blank_row = False %} - {% include '_block_store_stock_item.html' %} + {% include 'components/store/_stock_item.html' %} {% endfor %} {% endfor %} {% endfor %} {% endfor %} {% set is_blank_row = True %} - {% include '_block_store_stock_item.html' %} + {% include 'components/store/_stock_item.html' %} - {% include '_block_overlay_confirm.html' %} - {% include '_block_overlay_error.html' %} + {% include 'components/common/temporary/_overlay_confirm.html' %} + {% include 'components/common/temporary/_overlay_error.html' %} - {% set block_id = 'scripts' %} - {% include '_shared_store.html' %} - + + + + -{% extends 'layout.html' %} +{% extends 'layouts/layout.html' %} {% block page_body %} - + +
{% set firstname = 'new user' if user.firstname is none else user.firstname %}

Welcome, {{ firstname }}

{% set block_id = 'button_get_in_touch' %} - {% include '_shared.html' %} + {% include 'layouts/_shared.html' %}
- + +