From f574cc297bd3ea5c73abd84d2c188dbfbab1d61c Mon Sep 17 00:00:00 2001 From: "admin.suherdy" Date: Tue, 2 Dec 2025 23:14:27 +0700 Subject: [PATCH] first commit --- .gitignore | 152 +++++++++ README.md | 322 ++++++++++++++++++ __init__.py | 1 + __manifest__.py | 30 ++ ai_face_recognition_server/app.py | 170 +++++++++ .../faces/19_Suherdy_Yacob_58_0.jpg | Bin 0 -> 51160 bytes .../faces/19_Suherdy_Yacob_58_1.jpg | Bin 0 -> 37055 bytes .../faces/19_Suherdy_Yacob_58_2.jpg | Bin 0 -> 36114 bytes ai_face_recognition_server/requirements.txt | 5 + models/__init__.py | 4 + models/pos_config.py | 10 + models/res_config_settings.py | 12 + models/res_partner.py | 74 ++++ static/src/css/face_recognition.css | 255 ++++++++++++++ static/src/js/face_recognition_sidebar.js | 184 ++++++++++ static/src/js/models.js | 20 ++ static/src/js/partner_details_edit.js | 107 ++++++ static/src/xml/face_recognition_screens.xml | 104 ++++++ static/src/xml/partner_details_edit.xml | 79 +++++ views/pos_config_views.xml | 15 + views/res_config_settings_views.xml | 15 + views/res_partner_views.xml | 21 ++ 22 files changed, 1580 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 __init__.py create mode 100644 __manifest__.py create mode 100644 ai_face_recognition_server/app.py create mode 100644 ai_face_recognition_server/faces/19_Suherdy_Yacob_58_0.jpg create mode 100644 ai_face_recognition_server/faces/19_Suherdy_Yacob_58_1.jpg create mode 100644 ai_face_recognition_server/faces/19_Suherdy_Yacob_58_2.jpg create mode 100644 ai_face_recognition_server/requirements.txt create mode 100644 models/__init__.py create mode 100644 models/pos_config.py create mode 100644 models/res_config_settings.py create mode 100644 models/res_partner.py create mode 100644 static/src/css/face_recognition.css create mode 100644 static/src/js/face_recognition_sidebar.js create mode 100644 static/src/js/models.js create mode 100644 static/src/js/partner_details_edit.js create mode 100644 static/src/xml/face_recognition_screens.xml create mode 100644 static/src/xml/partner_details_edit.xml create mode 100644 views/pos_config_views.xml create mode 100644 views/res_config_settings_views.xml create mode 100644 views/res_partner_views.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ffe44b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,152 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Node modules (if using any JS tools) +node_modules/ + +# Temporary files +*.tmp +*.temp diff --git a/README.md b/README.md new file mode 100644 index 0000000..7ec5bc2 --- /dev/null +++ b/README.md @@ -0,0 +1,322 @@ +# POS Face Recognition + +## Overview + +This Odoo module extends the Point of Sale (POS) system with AI-powered face recognition capabilities. It enables automatic customer identification through facial recognition, providing staff with instant access to customer information, purchase history, and personalized recommendations. + +## Features + +### 🎯 Core Functionality + +- **Real-time Face Recognition**: Automatically identifies customers using webcam in the POS interface +- **Customer Training**: Capture and store up to 3 face images per customer for accurate recognition +- **Automatic Sync**: Face images are automatically synchronized with the AI server +- **Confidence Scoring**: Displays match probability for each recognized customer + +### 📊 Customer Insights + +When a customer is recognized, the sidebar displays: + +- **Customer Information**: Name and contact details +- **Last 2 Orders**: Complete order history including: + - Order number and date + - Total amount + - Order status (with color-coded badges) + - Complete product list with quantities and prices +- **Top 3 Products**: Most frequently purchased items by the customer + +### 🎨 User Interface + +- **Sidebar Integration**: Non-intrusive sidebar in the POS product screen +- **Live Camera Feed**: Real-time video preview for face recognition +- **Match List**: Shows all potential customer matches with confidence scores +- **Detailed Order Cards**: Beautifully styled order history with hover effects +- **Responsive Design**: Optimized for POS touchscreen interfaces + +## Requirements + +### Odoo Dependencies + +- `point_of_sale` +- `contacts` + +### External Dependencies + +- **AI Face Recognition Server**: A separate Python Flask server that handles face recognition + - Repository: `ai_face_recognition_server` (included in workspace) + - Required Python packages: `flask`, `face_recognition`, `numpy`, `opencv-python` + +### Hardware Requirements + +- Webcam or camera device +- Sufficient lighting for face recognition + +## Installation + +### 1. Install the Odoo Module + +```bash +# Copy the module to your Odoo addons directory +cp -r pos_face_recognition /path/to/odoo/addons/ + +# Update the addons list in Odoo +# Navigate to Apps > Update Apps List + +# Search for "POS Face Recognition" and install +``` + +### 2. Setup the AI Face Recognition Server + +```bash +# Navigate to the AI server directory +cd ai_face_recognition_server + +# Install Python dependencies +pip install -r requirements.txt + +# Start the server +python app.py +``` + +The server will run on `http://localhost:5000` by default. + +### 3. Configure the Module + +1. Go to **Point of Sale > Configuration > Point of Sale** +2. Select your POS configuration +3. In the **Face Recognition** section, set the **Face Recognition Server URL**: + ``` + http://localhost:5000 + ``` +4. Save the configuration + +## Usage + +### Training Customer Faces + +1. Navigate to **Contacts** +2. Open a customer record +3. In the **Face Recognition** tab, you'll find three image fields: + - **Face Image 1** + - **Face Image 2** + - **Face Image 3** +4. Upload clear, front-facing photos of the customer +5. Save the record - images are automatically synced to the AI server + +**Best Practices for Training Images:** +- Use well-lit, clear photos +- Capture different angles and expressions +- Ensure the face is clearly visible +- Avoid sunglasses or face coverings +- Use recent photos + +### Using Face Recognition in POS + +1. Open the POS session +2. The face recognition sidebar appears on the right side +3. The camera automatically starts and begins scanning for faces +4. When a customer is recognized: + - Their name appears in the match list with a confidence score + - Click on the match to select the customer + - View their order history and top products + - The customer is automatically set for the current order + +### Understanding the Display + +**Match List:** +- Shows all potential matches with confidence percentage +- Higher percentage = more confident match +- Click any match to select that customer + +**Order History:** +- Displays the last 2 orders with complete details +- Color-coded status badges: + - 🟢 Green: Paid/Done + - 🔵 Blue: Invoiced +- Shows all products ordered with quantities and prices + +**Top Products:** +- Highlights the 3 most frequently purchased items +- Helps staff make personalized recommendations + +## Configuration + +### POS Configuration + +**Settings > Point of Sale > Configuration > Point of Sale** + +- `pos_face_rec_server_url`: URL of the AI Face Recognition Server + +### Partner Configuration + +**Contacts > Customer** + +- `image_face_1`: First training image +- `image_face_2`: Second training image +- `image_face_3`: Third training image + +## Technical Details + +### Module Structure + +``` +pos_face_recognition/ +├── __init__.py +├── __manifest__.py +├── README.md +├── models/ +│ ├── __init__.py +│ ├── pos_config.py # POS configuration extension +│ ├── res_partner.py # Customer model with face images +│ └── res_config_settings.py # Settings configuration +├── views/ +│ ├── pos_config_views.xml +│ ├── res_partner_views.xml +│ └── res_config_settings_views.xml +└── static/ + └── src/ + ├── css/ + │ └── face_recognition.css + ├── js/ + │ ├── face_recognition_sidebar.js + │ ├── models.js + │ └── partner_details_edit.js + └── xml/ + ├── face_recognition_screens.xml + └── partner_details_edit.xml +``` + +### API Endpoints + +The module communicates with the AI server using these endpoints: + +**POST /train** +- Trains the AI model with customer face images +- Payload: `{ partner_id, name, images: [base64_image1, base64_image2, base64_image3] }` + +**POST /recognize** +- Recognizes faces in the provided image +- Payload: `{ image: base64_image }` +- Response: `{ matches: [{ id, name, probability }] }` + +### Data Flow + +1. **Training Phase:** + - Customer face images uploaded in Odoo + - Images automatically synced to AI server via `/train` endpoint + - AI server trains face recognition model + +2. **Recognition Phase:** + - POS camera captures frames every 5 seconds + - Frame sent to AI server via `/recognize` endpoint + - Server returns matching customers with confidence scores + - POS displays matches and fetches order history + +### Database Schema + +**res.partner (extended)** +```python +image_face_1 = fields.Binary("Face Image 1", attachment=True) +image_face_2 = fields.Binary("Face Image 2", attachment=True) +image_face_3 = fields.Binary("Face Image 3", attachment=True) +``` + +**pos.config (extended)** +```python +pos_face_rec_server_url = fields.Char("Face Recognition Server URL") +``` + +## Troubleshooting + +### Camera Not Working + +- **Check browser permissions**: Ensure the browser has camera access +- **HTTPS requirement**: Some browsers require HTTPS for camera access +- **Check console**: Open browser developer tools for error messages + +### No Matches Found + +- **Verify server connection**: Check if the AI server is running +- **Check server URL**: Ensure the URL in POS config is correct +- **Training data**: Verify customer has face images uploaded +- **Lighting**: Ensure adequate lighting for face detection + +### Images Not Syncing + +- **Check server URL**: Verify the Face Recognition Server URL is configured +- **Server logs**: Check AI server logs for errors +- **Network connectivity**: Ensure Odoo can reach the AI server +- **Image format**: Ensure images are in supported formats (JPEG, PNG) + +### Performance Issues + +- **Recognition interval**: Default is 5 seconds, can be adjusted in code +- **Image quality**: Lower resolution images process faster +- **Server resources**: Ensure AI server has adequate CPU/RAM + +## Development + +### Extending the Module + +**Add more customer insights:** +```python +# In res_partner.py +def get_customer_stats(self): + self.ensure_one() + # Add custom logic + return {...} +``` + +**Customize recognition interval:** +```javascript +// In face_recognition_sidebar.js +this.recognitionInterval = setInterval(() => { + this.captureAndSendFrame(); +}, 3000); // Change from 5000 to 3000 for 3 seconds +``` + +**Add more order history:** +```javascript +// In face_recognition_sidebar.js +const orders = await this.orm.searchRead("pos.order", + [['partner_id', '=', partnerId]], + ['name', 'date_order', 'amount_total', 'state', 'lines'], + { limit: 5, order: "date_order desc" } // Change from 2 to 5 +); +``` + +## Security & Privacy + +- Face images are stored securely in Odoo's attachment system +- Communication with AI server should use HTTPS in production +- Comply with local privacy laws (GDPR, CCPA, etc.) +- Obtain customer consent before capturing face images +- Implement data retention policies +- Provide customers with opt-out options + +## License + +LGPL-3 + +## Support + +For issues, questions, or contributions: +- Check the troubleshooting section +- Review server logs for detailed error messages +- Ensure all dependencies are properly installed + +## Changelog + +### Version 17.0.1.0.0 +- Initial release +- Real-time face recognition in POS +- Customer training with 3 images +- Last 2 orders display with detailed information +- Top 3 products recommendation +- Automatic image synchronization +- Confidence scoring for matches +- Responsive sidebar UI with enhanced styling + +## Credits + +Developed for Odoo 17.0 diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..64fbcfc --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,30 @@ +{ + 'name': 'POS Face Recognition', + 'version': '17.0.1.0.0', + 'category': 'Point of Sale', + 'summary': 'Face Recognition for POS', + 'description': """ + This module extends the Point of Sale to include Face Recognition capabilities. + - Capture customer images for training. + - Recognize customers in POS using AI. + """, + 'depends': ['point_of_sale', 'contacts'], + 'data': [ + 'views/res_partner_views.xml', + 'views/pos_config_views.xml', + 'views/res_config_settings_views.xml', + ], + 'assets': { + 'point_of_sale.assets_prod': [ + 'pos_face_recognition/static/src/xml/face_recognition_screens.xml', + 'pos_face_recognition/static/src/xml/partner_details_edit.xml', + 'pos_face_recognition/static/src/js/models.js', + 'pos_face_recognition/static/src/js/face_recognition_sidebar.js', + 'pos_face_recognition/static/src/js/partner_details_edit.js', + 'pos_face_recognition/static/src/css/face_recognition.css', + ], + }, + 'installable': True, + 'application': False, + 'license': 'LGPL-3', +} diff --git a/ai_face_recognition_server/app.py b/ai_face_recognition_server/app.py new file mode 100644 index 0000000..4a8c3c6 --- /dev/null +++ b/ai_face_recognition_server/app.py @@ -0,0 +1,170 @@ +from flask import Flask, request, jsonify +from flask_cors import CORS +import face_recognition +import numpy as np +import base64 +import cv2 +import os + +app = Flask(__name__) +CORS(app) # Enable CORS for all routes + +# In-memory storage for known face encodings and names +known_face_encodings = [] +known_face_names = [] +known_face_ids = [] + +def load_known_faces(): + """ + Load known faces from a directory or database. + For this MVP, we'll assume images are stored in a 'faces' directory + with filenames like 'partner_id_name.jpg'. + In a real production scenario, you'd fetch these from Odoo or a shared storage. + """ + global known_face_encodings, known_face_names, known_face_ids + + faces_dir = "faces" + if not os.path.exists(faces_dir): + os.makedirs(faces_dir) + print(f"Created {faces_dir} directory. Please add images there.") + return + + for filename in os.listdir(faces_dir): + if filename.endswith((".jpg", ".png", ".jpeg")): + try: + # Filename format: ID_Name.jpg + name_part = os.path.splitext(filename)[0] + parts = name_part.split('_', 1) + if len(parts) == 2: + p_id = int(parts[0]) + name = parts[1] + else: + p_id = 0 + name = name_part + + image_path = os.path.join(faces_dir, filename) + image = face_recognition.load_image_file(image_path) + encodings = face_recognition.face_encodings(image) + + if encodings: + known_face_encodings.append(encodings[0]) + known_face_names.append(name) + known_face_ids.append(p_id) + print(f"Loaded face for: {name} (ID: {p_id})") + except Exception as e: + print(f"Error loading {filename}: {e}") + +@app.route('/recognize', methods=['POST']) +def recognize_face(): + data = request.json + if 'image' not in data: + return jsonify({'error': 'No image provided'}), 400 + + try: + # Decode base64 image + image_data = base64.b64decode(data['image']) + nparr = np.frombuffer(image_data, np.uint8) + frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR) + + if frame is None: + return jsonify({'error': 'Invalid image data'}), 400 + + # Convert BGR (OpenCV) to RGB (face_recognition) + rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + + # Ensure the image is in the correct format + rgb_frame = np.ascontiguousarray(rgb_frame, dtype=np.uint8) + + # Find all faces in the current frame + face_locations = face_recognition.face_locations(rgb_frame) + face_encodings = face_recognition.face_encodings(rgb_frame, face_locations) + + matches_list = [] + + for face_encoding in face_encodings: + # See if the face is a match for the known face(s) + matches = face_recognition.compare_faces(known_face_encodings, face_encoding) + name = "Unknown" + p_id = 0 + probability = 0.0 + + # Or instead, use the known face with the smallest distance to the new face + face_distances = face_recognition.face_distance(known_face_encodings, face_encoding) + if len(face_distances) > 0: + best_match_index = np.argmin(face_distances) + if matches[best_match_index]: + name = known_face_names[best_match_index] + p_id = known_face_ids[best_match_index] + # Simple probability estimation based on distance (lower distance = higher prob) + # Distance 0.0 -> 100%, Distance 0.6 -> ~0% (threshold) + distance = face_distances[best_match_index] + probability = max(0, 1.0 - distance) + + matches_list.append({ + 'id': p_id, + 'name': name, + 'probability': probability + }) + + # Sort by probability + matches_list.sort(key=lambda x: x['probability'], reverse=True) + + return jsonify({'matches': matches_list}) + + except Exception as e: + print(f"Error processing image: {e}") + return jsonify({'error': str(e)}), 500 + +@app.route('/train', methods=['POST']) +def train_face(): + data = request.json + if 'partner_id' not in data or 'images' not in data: + return jsonify({'error': 'Missing partner_id or images'}), 400 + + partner_id = data['partner_id'] + name = data.get('name', 'Unknown') + images = data['images'] # List of base64 strings + + faces_dir = "faces" + if not os.path.exists(faces_dir): + os.makedirs(faces_dir) + + processed_count = 0 + + # Clear existing images for this partner to avoid duplicates/stale data? + # For simplicity, we might just overwrite or append. Let's append with index. + # Or better, delete old ones first if we want to keep it clean. + # Let's just save new ones for now. + + for idx, img_data in enumerate(images): + if not img_data: + continue + + try: + # Decode base64 + image_bytes = base64.b64decode(img_data) + filename = f"{partner_id}_{name.replace(' ', '_')}_{idx}.jpg" + filepath = os.path.join(faces_dir, filename) + + with open(filepath, "wb") as f: + f.write(image_bytes) + + # Update in-memory knowledge + image = face_recognition.load_image_file(filepath) + encodings = face_recognition.face_encodings(image) + + if encodings: + known_face_encodings.append(encodings[0]) + known_face_names.append(name) + known_face_ids.append(partner_id) + processed_count += 1 + print(f"Trained face for: {name} (ID: {partner_id}) - Image {idx}") + + except Exception as e: + print(f"Error saving/training image {idx} for {name}: {e}") + + return jsonify({'message': f'Processed {processed_count} images for {name}'}) + +if __name__ == '__main__': + load_known_faces() + app.run(host='0.0.0.0', port=5000) diff --git a/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_0.jpg b/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..34e6a3579af656b6018bfd7329a1c9a8f43ad0fb GIT binary patch literal 51160 zcmbTdXH-*N*adh)sG&oUj`XTXARrLX5ClT#p$dpJfzTv?fbgoJ1T_@tLMReQ=pZO1 zfGE8wNEa!-2uKsKP*iM__xonetTn%8=49n2E4So6_niAY`|Q2%-}%2Q03XKG+!O$T z006{z0e=?(V*t$bU;A$fW;AA2=KmTyD=P~t2Rj79!Op<};o{|jaPn|+aB%Z;^YHTV z@$*5r1Ox^61R3A?{yPZhzdgas?2H}xI5{{Ozy5!0f4c#GcF+nF0Sw{?nD{|pe$d~3 z;56erSwR2Ofd8|Bn83^|tZeKY5KhJhEqnkImN2Yx3+h_d_6ckI{x`cap}Wr`oz)!X&`-drirKql#^yJlnLY} z!;h%TBR*AuCpj{@HSK3G$w_Qva~Gy+U~kF0d1I=NPFT%~;w#3T4-?k?R(32oAhPFB zd_Qm{Hp2SY$;(T)3l*ipqm&A93$}fioaGd)5I}ks4Q)?v?(vF@Ww-GLOcu13P)9P`+>A5A`$^4OzH6lI2D)uk&v>G&zalCq`O z1C0573e{fFiR)w%&&IZpCc>%4*ANQKm}s#;256Db;pL%JtP@{CoWs0G7oFN|nThhI=kz0h z2+LaO$}orz*UDGrjV5kDuk4$Elb~$wl!)M%8es+Rl+R(kzDO_i%a=9`yj&)bQ3qwe zK38@^zSqZk%Hj)OG5>^@cr=88F`s>b#6=n$dmJUM3hi#6@|+$bp~?lrj+@ z>L3$>GNxNMvXlz{VkE6UiKi^%DEmUF(D%p$0;uFjL7FB^V7h_T_)0G)GP8j~gGXe~y3Yt} z>jPy+;gK-5E^!VP`6Ll-b6}@12W+@~J`BwZ?>5eSm(ePyNT7qrOuZ{49Fc&Z%bz2l z2S8!WWM<-p8Lj}`vQP$PPo3f`?5Zg#qeJrGXR-TSsDRik1wc}l z%9H@Jf-?z{t(KT7J)shIc#3L+bam(oLN=j6Mvpp?pOc@E2C%vEO{{8Jao46*pi5V? z#h764@?9`i?8=@(($Fb7%PBw-w-kVlFe`(IU=ClM@WRXDx3rVkox7n*2vSk|p1?K{zJ zHzp6V^o+%N`vf$}Zpz!?->qhod_sG{B{Sb9oS6)(b?46u$CJUNr1Qt8ElAn-JELrhhuTt;(bW;J_O1tuuh1Y7}~ zPz_+|kQO^16i+jgWRdMqqpw3Ly|9|JVjX7}CrvLH5a#1iAuxK9afAt;;TrmMqpkGH zln+WO2gZSAN*sfO_U3XP8BsXKG(0afKlWm~Sd2*THr(RdCDjrN*y=5!#rRUOoGfUf zE6o>v_LQ zY}{8j0n?{R%pzlI?6!#Mz%}GdVIxe10@@%zd5+8hezM3EJ+WS%-KnC7AVQJhvs?KCvDxV?G9S7kyTiTJ?cyqLM(V)1E5Z=*q@?c%2&0N9(>N4dq4`UN}&A zYa7yQ-?CGnJ;%o=A$%;hJi`^FCDV%j*`#W|(p7R4Fihcc-zZs0 zo}o$)U1;6~Vcr08PzA3R&r%~x7GNXG2?(qJ(1u$fz@s$lVgP?wF}j2kp(-+xDx4kv zI`I0H%4L_Sppm6*1q?n4I^7o4Px52-pL@Pr^cNxTNZd6IzHZcpR|%Ca>sIN8 zPBqyWsRW~IZSbWRF;3!qag*N0q7*d(y}Pv5g^{;AIXa0Q;3TNrgCqma&f z6(dHMd0Q#ThCh{&AxQG<^x-@4Dtj>CdwxFaG;GlAYBAyNy1}MN-1VlkWBCfk*%0ed*905duaqT z-j^j(b)kD+nPtDN1SN<|F zpU@C0i3Q&*0A<8J6dNVgD@Z=iy05BJ(vb&^hAYQJJ?VCO~MWY$PLH z?jj%;a+F4;m1JwymMl-OoXNUl(v7yW{pW)1x0v`z#(}+im0ldFc8x63Ofcj^qdi~e zt?l^`7o#~U-wu98#9vz_)o460uZ+&0e&}*W8p`A>VXeZQrUd8cB(dTs5ZFR-a`KD| zDv{)avX!p()IF>*fl<8+o#bI?HjwrBnv)>2*co;d3@z5kNO8FYWlv~!BZSSsaX!G+ zYM#=}2L*VPJ()Lhlb3swq$`#Q*ocMrCE$}Kj%P@;hE+!NlX-2HvSrk0cW_*Bm2^Fp-ny8D!= zT)L{!i9LO{&i&8JclmbHi_if1I-B2Fn1*+-86Q1bB z*?P>HRWN+JGgf(wJ4!IOfcaRVT+iM6X%{i_+LBwNxD9-!L0BtvkCWo5f1`3nJ>tOB zZj?OX8w1@{V`X&ABC<|VZvf<3irSPqG?@pu9Hmbs?>en&D>8~au!SpSf|+kIWtYtG ztb$1(#D7>_p< zJlqxvvOC-Ik)m~@?QpTn>iYho)Oj5%?F@O-lz++MLWSoe>lKjh)vTE~@#6)Tj1{pG zkAdKTp0YfI9$Q6B8PqS+Le7nDHD`)B%0(ha}I2wDih}sfZwNSB~aWuuqP? zCsI~sI#lJQp%;@;+@l4OJ8SE16T=--y(*s1e7XYi>mxGe&O}`}vgGx${xj91QnTh0;SpoHbW1~Rq1B!KkE~BZ3N(hcYU#v zgA-_e66qY_1@+2S0WC~lV`o+4J_8FSI*ZRw z@qtOD);&l<+=ND{kud|fRySF(Bc|!Zag_?hyazXk{%>!J0MvykuN&I!j&}?JtPNFw z8pJ9Yw4+yp`5=2K!R)=$qqD?tR0(D!-HK;UaNx#^%xcnImEbr@IVq%<2 zYN8!W*H|xoxvZBkk#>exUHCLnJ?LI%`8H}NLO$hZ^KUD4zaVJAtZP6)kHd=n1}e&Q zHjh;5Kl*yjq9|`aa1rOLai-90sya=6OsFZzXB|A%lsj2IE5NPIqf?KW$@y_Z@Taz1 z@E)^Nk^P4#dS2OuM`FJ|m>5TKavXc|auRU!57oE}t)1NY*gvMvMui9*sp*uY(ga0+ ztAw}0NzSe!^Wmj`gz!#cY2*I3lW%=8Mf@edSdhOqx!%y-b2AH16*EY^F`#{eUKeif zax)?X5a_NTtxE3kGnAF~~XthHdJLo}GQOd6PkMyL~vgIF)>yumrZZ73~~&N;<14j(q-nMGV`H&16X;F zVwJtdg+@M`Kr43?meEP26-lKTrC@`Ne4g<@0@5%r#EYWB?hb)8CNdvVWsr>eWXLQT zm_+!3)L?X^G!@)|Rr6whEnBiOJ76#Y4hs+>4ncVqIE-XVV(q-TE|sF{!AP^%GdfA9 zUEKoF&!UB#pRY*x>(NRlq+;#pFc`@jf>ah+pK2Kj0_jyY!Y+!P#Y0%&gqZE&F%X?= zQ?WrGGB96McDO!kp1f|Ex@#Is&S;w0a&@tl^6lQ?aLt?ed0C&_~bO5;GR`w#3nS6&Acz~WV*`a?#XNCM8a%1982$uY%bKZq!!dAWU*f) zUb!DodB#l~Ow%;2yLRGu$+~xUF(C%potcUG$v|#YO(qTeWx~YLAq}sMpBEW}-A8hd zp*cH}2D^VNd-HKkNfMP>z`+;}$#^3tam!5P5L{;7^2GLEFV2qQZcGv=UCS~G!mN8( zS^?*pkZ%wjfU!t}J|Q6*hzae|a&qRqS(LZu#3|wHT_7)IJ}G6;TWGWDd$f0Gjp7Qo zcGWZ!-Z+}I{})aG8VWM)h61J8@8XwGFrBxs2VNsch+n3vUHbZCuX&=1u zH9Ry~uBqOKX8A2QkiyKp(qW@UY*WptXRDp#gwO8H z_V{14bhgCRx{Dbd>lqE}x#sP1q^YhDe=h$H5?>}Ol)hEdu zcrD>DU(4T`56%!is7VdhjBLCl>K>P%Kb70FgKkY}i<-Ct2^gW0&dPhWrUgdzofldzxm>RWJSW~CpCMw%?#CIUQ%+4M^EJ~I{P%3Rp>U5LTDf-6z0|SH7SGpIbcamp4zGV(wB4x(7hRK?=2Z{Kyt`O z+mbKIn<|pzU5J7p8M8^`zOqP-Q4o9VMmC?e;$WZNDuJG(gojw0VVvoo@GAG%;6P;y ztVxAkIg~+OBr}*j2;b)jqcfHp@hkuXj{VQfQ^PwFu05jzLGeZ~n8M$vc*dO6n;b1k zWF<#2E69NKDBO)whjoDd6f;7$rjNcvj+R$-0|r$>LDt>6JTTW_&4BpZyk1u9c2Ydi zr$^&mT0*jP*2vMEVsk6cX9m$9KV9y+d|tmxU^t_JWE#8LR49fJ7r#}-`i{-my)}3e zQ8;(plWE=a2ooFJO}4OlnefbU8JtWr<}=UIu}p|9nN{`6G#5W^{DE&6FTDXZzruZK zs_j08t4%4rMeUNYl~`13KldnyHkIElTH9y(CD*Vs0hS&yaNTOF_|}-S+(oYycF;Ks)`om@7^Yz$so6Tgcw+e^A85z3^jI!-Qeci?G7J$ z?5by%V#d9CmDgMrK3YiD??ZPnqmN#W-P503ZCJ?}ysuqHPG4vGO zRwhhYwL8|n5e6FIn9opxpAQqlU2UAmm4!+;a&wTqxi$!rsF@}Xxh`&(y!o6YD1Z%S zj6Sg_$+?m>#w@w)SkMVHW8d{3`6v+2qR5moYQd=|@qapXX%*G^jdUos4%^+v6{4gbVY)y%quB!10Ij{uSKKWch}d(; zO|jl3yMR*mH>Gmmm-9xAb0iKf?=!z-my^e4H8wbBVp_S;gQNg9M_@t=o6EqEWaBMq z-BLa(m#t1BgPX6U=^ToSWA8&5JRX9bN11sS>VjkqkW65t7nK2Ul%O61zkrayN0Vft z925-hUL}?u3o0fP!z65FqT}q1Lsxll?Cb+FEnaV-Lt%pfAofkgY)%f_5h%G?rw5mC zDkTS=YHQ&HVLrE98pnZ5$Y)UmSaB{mcQ)6vp2i)sXN`7*P>rR&tAsOWd_f7Y!Y$qn`>BI31B9ZsEgSG0mG zUG`+L^_C&`C3||#z6<11jNkEUhm1N=QE{R{Z&+fZIXL>J=fyjD$wyIPQ$L?(0$q{XQ-w3r9sk->VXO~-z z(?{yWMnfLVvow z&{_F)aG^CrY0$Y;mN^!99G}}tqUSe_08i-uiWZVZhj1Z0PpSojz%WSVN#>SoNWrykxdc|Vyl|D;Vw1GO=36~dM-XRDmuJR` z{5O^AU9*|pTH1z}rB|@+6$AGsuY7IqJ}S=*z0zPKRI0A~(JElqu_4gyZI!M&_>*Hf za;<{a-0b)Il{Et5-ll+SQhR$Jtv>eRy53*FV7kdp*6qrZ;D86N__P$9<|>Mx)nO%K zs+#h3$wzG;1RB{=&8Cw-s2lq$g48n8^=jI4>yG4&KhOnL7M8fXo;S~vm9p61GNGbj zqVgm`QJFPYdnuazc^~I!&&xXQyRItsX>Kabd{)_>Xb8&xCcCes>kaxH z@C3D-*_`zXGW=ccd4yvebS-4``b_GkP)@osZ~-fL zef#)q>J$kOHKSQ|vq1?SUDai6e0U>iYaDkcVIw~w1A-i2fioyv z8D&0OKz{;$&U%K|Q?83C0K@!0FiKjt+Os&JxF7lrgdUQm))OM;3I%5LCrcTFZPIhz z9TFv(WDrU7GGwV~G9o)SHptm>@yfwrkpfgBlc^=9WTr$bwKSLwrmZn~hEN(^=|zbk z@xgfO757guh#ngnIM~u2vkK*P#Q{elUDfxdrq9rx6(d7ROQ_h;(f*RVWvING%oYE+#geJ9b67MfA}kIDvWv9Zz}UN zL~H-zAgz{cYRprZnZ=TDJ4#Z31YCAFYLPe{V;dH$sopyw_#YXFYtx z(<3Hkzb=c0yHwZV6euCJ2fTryirBPqHis#7*~0M{QhMph%)$^NtpMdBpJg~UBB}Z# zR853DPF9yudimpS3)VYM;sS-H>6_av`Q-{sXt=IYW8=KiLUUK|nl>MSLs(*RjBv+`VSGOmr*z&FQFJRH0p?***Y;#XtlJ=2yDD>EHAUUSr(I2aYCf_K>lgvsh zCLpocCbu*>s3G(0U8$T!PVQvC!xlJIx6aDO;IMNR}}gP@qrb^s|wG8;Cq8LDhwY!<~82 zsw`L$W=~JZhcGDHQYFKhLVA+q7Mg{Pp+$Q%yZA6*SFkXIS%oQq48=R;-j~Y!^jh04 zZSc@|Zn+?#dORSoe`%*#+(!%u=e?~e-z=d2@tSnCu1JGQXXpi|;_-yRgV8Ic_9VEu zpv~ifP)Ta=_PLlvM}+*%dgwVu!(-@e#>p7hu#T9Yd!g+26E(&8?cD>mdcnBkviBg&EeK$ z&uT|Wk6_2-(V`ypo|)dc9z87ZD@fR%(y`IB;36LlqwZ=@KjXjEp63p>FP=?%8N^Oa z5r0D68X0GViTL^T z1KXZUfw-()tutPeHu4d#X{`60r$z0@oyGKQg~A~zJmGDE6Y@=xD9gJtHKSr&Q>mpE9`abKUE{!?PDK1 zBqI8!!o)>^!!fV3lBw6C!rEf-38tfKl7`&;xx-7ZVM8z&+^2%waGTOxF!pi5Ab>D< z_Yr0iGZ?By84MJQY?3I;FvPnqXW7ME3mDa{v0iVrCz*%P7PDAy)}RaB+YHBTx%}TH zPcheFvrx}w%*D!RFWC^usvbm>rG!i`Bnu#;SDlSy-fWRs!gxzgB@Ip#Rs{<-<|O^6 zihGtKVee?EDpcuTxc>xA&bD{iMxJs^Nv8zziP8|uU{nNJoX*p{&+hcULZ^xdl?#Kr z$1w(L!*7yW8xZ$xCwghMfGx-&pEUxRToNF!3`j`fT;d?sxI{jwo0YF*Yz&oS3HfW< zI+6*DoGu_Ozv48)H1kyG`RvQ^*x#zH0%sN)-WnYl*7%-q6kjO-Ii#xzt0idfsassQ zsJa>WVd-f^^;nR|*VDND*lDy?f&H>o6z}+033cw*V=pCdM2MzE7OKJA;ESWka@NAN zgVGVMn-H7#Q?03ISZWc7s)Ve{(Ad@1)L@Hf9ZC}2E-S(crn#;ocp)(ZZDcc~=M9rZh-K>Amiwygs+c=U@YH}> zI zrGlqq5;`(u zJ=>8x+~)IWrtYmshl-rl9Ly7zi0Kg><=9M7s*A5(7}qL+ zPr^YPPhr3YrYsm{Ku1BR0d3pOJ^&8vF;Ig*1g990ZS8t}^&a|X>N$8)~v5|&!U z%G=_txH-((VdU$!keoWk9`@o+5EPdm8EhH@X2=d}LQlQCS#(E3aKyOz{@=eYYL z90pw)RYUbcS$s6D^4EtrC!ByZ#LcDB-baBsc3$4?#RTc1!?D1O_DJo>J%fIom;CD+ zCB1=zdzIM%FEqW}vS6-*Bkp4j#QYD<{(k`{NJ#-edQ%`+Grurhw`+WkTwpwF7TcNI z-gb&uW@&89j-o4ZXCEC_Z_ET12ETdw`BrDfOSrENWHWoNvs$53GpluQ>_vS2wcg4* ztBb$&#gzQ^IUWW-lMYcA4o)T7j8;!R{a2)_H8CPee_4O*?7q)gIW)!GNx70u;=y0w z3IbP^^LD2rScBHpeBnA7!or;u1OB(ty5wkldwI#OFnH%|$SPlwT<)5-)dgDIEwtY> zCH!)JtE!UD++A$-808^8ICI!Z8Fj8yvET=SXk&kJxV9720ZM) z)t;nF+L&Haf4lkZ@hzOD12BcU4&wzjH{9z$oVcC^go;8O zj~eBo4KJ%Vb47oh%miMD$eTHGYp1GDX|Pr3R=@Ce3-VFi`LZ1GEc;{8%&5wa4eY_q zn^B1${5Gpa>!?}k3W%V^dkS22eP8O_t+4I00Uk2Okr_(^Uo#0mJ5J-@J;jwfavq&; zkV!uh?emq$P`*@E)WQJCrqZ4#Vznf5iHgoZZ&Ouzt-T*kVu8i4k0)>@f6u#kDo1aR zf%g3>*5+|Tm}J|#l2rheVPjz>#FHwL6wv<>ik|6s0@6k6rL1*`XJn&cW}e zf4mhs(Wtv{4KlRFqvgzvNinmyR{aiH^3SwzRbV z`<>w})j-Eop?M4LUzHL5`b+HVzHEk&M|17lYeJ@Y%tN)Ns@8Y^#27cK{E=edwCyyv zKr@-??Kdh=zQL~vqa^x}C707qvuo2`wa_8s%D|D{=J{d7T|-0VY^)AZ{ln4hZazGq zI|I4SSGk2B^R8Z+HC^D>P2b$yicOWu6|~!ld>n05b}*V$weH_WvxHtRT`n2;Xp)8e z3+P}7_%}=~4^^GKb5k;x7tFgi6S3r25zLs-^~dE|!qL}^5+4=Tq#pbQ<{FZ+ zoiwwzZtiU~Wb~c+AY?f{By-byNbkboQhTJSHTP5E7n7=tf~*CdgVRywa==%c_KTRX z+L8J(%Bj3c-srNOwgd577p63L6?zA2zdsFEy>{iiKfPuE-S_OXRBM&1xu?7oQt1KZ z6KYl2gPUKtu=t4hMaib7*QsBX+Q|yLYAJCHlc4U>aBD(VYE;AOCe~y>_ zoxG7JP55Cr5V6p=dFJ1$e9_kT_o~JG6;_!pyp##}rXg_)SFRH_ZXRy*JIGhf-I)V! zCco~e{EgK%(pOho(>SGF^rNjU7W7ugJQvR~hR)An_bA>{^HP=v#<<<1xHeMm!N>rN zc?@9Lchq!9g1XhgY+&*=r7%NfR-FVB zhSyTEztjlHq6RQ36l@8JU&vSTnl<)bS<^-*1HP*b8WB;bt_K01g%h4#eE%2V==s9i ze<~&RNd(s!%2yi+m6eQ$H`5ob4Fc^RJ-weq{a~NBal7q{l1o>9GYX-bj)w;5N+rEf z(3g67$+AkfbIFEhN5AV=QepdLVV30mg6)C8Y12k)x8jY5{$WNTLmLtYbF_yd2y)b1 zbm&^FWDUM(8hh=lR_#ps!m@OeH_=a+hTAmj8G_&9w-+)2@XL#y(;@QOvt*;7Ob0iU$&;i`*3Ox^5ddz_r8 zMK0C*%I(+Qv#(Cr?tiLV54{8%e&=#wJ;Ub1m7J!I1$2+MA~nYn4ZlMY6HI;r+nJ>N z%vvb^aZ=>-MX^g%U+}@R7g|jR3%lEgcS!orQ&BOmdt8aBH`&Ho)l{oL4aS^K^FPuL zpDR>YSdc1y|5_?WygzJk!G;w4>eEm*f?Z);PuxxPm#Y8WV(l8eq8s|=p6vutIT3k2 z@hUx`l&ZPDR7C!_3)1b=BhCs@|14`>9Bk0$xrg1@Is33b#VJEA)b_={cXIv!PCJ3B z8-IG_OwZlRdm`;PLt+sL8a0nnPYQU2C!a8ott}!t^*-A{M)8 zH%l67j7d0NU3~v7xp~;ni~k->^kWkDP^c@uHto-1<-J3xgqGALcXFP22rJFf;2368Dy@eaT^cRO9`kCuZV-1e zS3SRQ;zE97-q_(6mlCrsSK%OVN9;viM;x1WO876i&(8PDeQs6O*+18kRbILyIQ)xS z#b-10FYty^XkN5m{n>5kwqUa9_nTiVY+KWy%{mWn<_X;F{q+`dk>_aAM$)$9=592c)1#6O;sm(g+vi$1j`ftfdxbs4Bo#=%- zw+n{WhJ^}KA5+x3R1p6j=o@mbK8~-eG(YzYPg|@})HySd;*0-gwAz|3_H6Fo%+yM2 zH?6wX@1H&w+uj)nXp_Igtdk8>n)s*mc1u#@4X=)0sj9l=Mt>0Bm4;89Tu6Jo^9GwW zB5_K_{Flp@>8U3rr>xJnkCNNDH~Vewk)NT-X1)Eb*k>a*s}jsaKRC14h^#vd@svKs z>(?BcDO7v>x;`tfN9qKVDEkK7)S#(dc|iH=3F7J#+loiMH%vRF z{{lp-FL^SJ-^pXV-#o(ZTxk)oTb99;7q%DQ{QPOnQt73X{Ita#{Hp0`t9Kq3T_uEC zRl<*8+PsiozSD2>aB#OFBYLk+vfMn;_Ktr3dw-=eMfb<=^VS;0?sL}Mnytd34BT$ZJ+HNg z1qarl*QOHkC$x}R^h(JpZszLHRS2L`%6Pg2<*6bE9SuhQx5{%WmPlM2JH^Ri+?Xgr zZ2`^JEIC63Dy3(G&yKt=+T{MXE1ynR|!t7a~i;T0oT|rVg^br6WMg-gybYK zABZ};Ad4`DYh}V}K13E(+^vD5%sW=ZLv(9g!6x7N^5cQIqUHNtcZu)*xC9G+U5}fk z=0Bc4{P*76L$PbgY1hQByTvTWoZc;cz3r~8Fs4=}srY-t@0Y;@FUi0nrRt@(uYksJ;Yd}wjzHQJoe;GkR?2w{eujl+jbBAd^vB0M# z&!IWaFs)^et61Zp1?PXs-|_WsonrCSaFdu*ryZ;R9@Y9jr&H)XdZ7C$yG{4#;#6~` zsr{_TI7a`emfiQ_i1$q#c?%kf<3fqyY}ku1kA~Cg#a6C=o*z6~9N4n(`H772Hg(8b zUh~wrycn2e*zpE6syg%C>Cw3ZVZ%fH`qQgz#D7q*ik&aC(MS1h{I${Ut-RJ+q>gq& zSG$e24}Y%dg@=ar)!y87@=J>!7ex0o^zTt$lvj4>6&>h>wLdoV=#8_ zT!Q%^4;$v&#+Kcb+pi&OqHFr_r{>3RbuQ+%NS-!95D;$I_KdZq8h-M@M?Z(sAKou6 zentGLR}cufdhGEuZ8G@6>3NKg{G+EItqvq2uVu0w2u)jv-YpU@d9V>NnnaBu=E={@H7N8%3O_l2Q8 z!QtZxi}NRz$p#=uQM<&Kp@W9m7TDW+VI={Iq(t9l{7k$ zoe^Uo@tfQ0NO`GJNb)7->7`2+p>FuKomdFIr>~kSIlLKki@2V;ug5(Uc>lfU+i4-G z3WLv!&q7hx9>~f22%Y09vn(srI0p|p@2E*JN)?tUx@8q2Vwk03*0kX|P&n9*XAtnY z@BPf%?|7INk>>Q;^VaF9=0vv7kHze7@!(J!SMR~Qq}04FP~QKv=r$XF=VEsHv$UpK z=GbsrI^^ri?r8g!C5E`9L`WJZ{L#~Hmbvw6hT5jGBgHXWzxx+xfxB(Bq;TzNGS2t# z+WI$1!yre~pSDYnq9>9>Wz%D)Eb9mAJ*YBlv39IyFUw7K zo}ziSyfkm-u4F!$Si@I(>#Yor#(#H!Yj!eKa>1}zZ-*yIN~}qW{Yu(Sf)F=$6~G>; zD=~Z4Ec_3VI?@n$9BZk>eM5EV5zL;H!f3$j_&L{tb4faK<@BZ5x-p~7+ zm9BE}=1`N6ddfwnNQzWtRbcojP??1-6hE?Lv&FXNct3$``Z*!)5o$4CU>eALZRwxt zEHI5K3aNfrm!f%TO4+XM!;gExzY%lQ1=a9~ljO25i@Nq*4z@nZ2L>IusXW@baPC|I{4?OLf`wH@Lv7c=PzF!shW6+p%2d%xipW*dt;u@oM?XzikP)z?hk$+~`xySJUrKM3D#R90uV<(jR8hFLZrubvGo{ z*Q7rfyHoJ5N|lz9$CtrePPok-Fb}K)sd4AxV3*~2j@3;mhx%`KzMAMps1;rN3-nvD z-jqk*2y*ZZlee`HlI%9*_&7b+_3J!%72Emy;t!cPVVifiEDQdq$0&|EN6iHjQdB?C z=0Du^rjN%t*L@f0x+T2*7Z{PqFTzrUUcWinig3QuVoLN6vo0)KTINAzCBTP#5-bFN zICm01w}=1v>h$Bz@uuvcUG_KHcOl>34eM!qm%m?(0DY^VcfW1~=CVGQ6y-g+6a5#6 zl;pZ5f@uBo{>$xI^0mdGQ`PTP)_UK+duKa;!ekQe@R_VJYxDUpu%DbgXqRhYw7nJL z_RIgX_NtkIShL2n%A4sMI(|0pdm^t}gVNiQXH{;zSZ17R$#XG>Cdgz~`@}$%Yar%{ zt2>9l4X%1o-Gx5AqdzU5+vhCKG@L7TJMp+qcL?Me?)}2dj~)}31&Pk%54e8cQT=sC zBkTC#ow-3+p_%yE1Yra}@>poSEh4Cl7aDW>Lu9pgudweAF|GF4)P!3x+ByFR0BJ#% zzE-12HhlB0tdQQz1B@8o0FL7|(@t@3Q#!n@*y{cd>JvfYc=VZOklJbp>hb60SpwuZ z9=HU4HQ!25ZL~N?R z!O0|Ju_GU)5rv)1|E1 zza4>YKb>$&no`l6^q()fdN0BY2=wm?!*wKhlI(e?`0AyPB>MCf%ZRTS&y^mGBc;y# zUKCKpvN`Kn^DW9|2D7O>z}gwGgyV|JSC**Fz~|?lX)pjM>s20Yiiu}T(k?EGGA2mp zs2|R^j2dRjRz;>aI#Nk0#&Q(kGW&X0(`2|wSFEG`Y{|bi=bUQRI^V?|WZr2O7SMdl z3>IkTfJxly06cNIy*=yuCx)_|Hc5d_s_%ENcjo(^Mn4Twoh4JJ{4weJAM8c(2Ud|1 z>%^Kxpd&2kvba(8A#+$__~$RAn^c?m*!k&KlvUQ}UuFLQ1n}0LWH%oY?3NOFF=?(z z^#d|uys7w;go5{Q&i?@7U*yQAT21P|ANU8j=^wL(z2UD94-R-w#5NGDR_hFM$s3j= z6V47mJd>Q7_`Giv)5g_xYg2!E?QWih&k;3KoBG(`wf_Lw3*$BJ=ZoSMi-rIje<_tn z_i))gx{OzTAB!@j4oZ|?{shlk51Xh<-i`i$@D7R}f!`G)(V$IU=FTgdGqI+(hwUb0 z;~7);dY*7jE6c=Va(eYSp&k6>Z!FH5)vJB~0OWCAE7N>mr0Z@qyBmnD?ePm-OA|Vg zo*76?1%7iqTY=2%l`lo%$JWE+w2jx z0RXN!_chf?a_DO~CaiJyHgVqgq8T){ODS~=sFryaE#fgVtTIWC26E_Y^*#iQt717M zu99!=jNj;d{$|}56&>IF1L@BWe$PGz(PVkv>r=a(vKgM^3O#T-{$$tLVmOBtQ%Izj z-h8vqD#_cM^8WxLZA0L1!^yWa`b4s+U|kyFwzfNvI+~hU-Yz>yeaP0PYgd-v<^D#0 z{3vgPS0Q7Mz}9N4_$8iA#18)edb*Z>kEgv)!GDqGRL$#Ol|Re;jzi+-z<-67R#uOv z{5{haSphE~jkjS)9YOc6Un1f>ceInKQvU!Y{zrwF=6Kq1PMq!cd3hdLq<+sjCyMW+ z()=^v{X6XnzF=E|=t^g($sqk}>#;mrEEP3Yw6yeJ{E5Sc%yU}LS^og(CzpJ0_*rA{ z+f$1{)U=BoKJ@u)%>=}#R}6EL#zw=(`(KTHHw|b10NWAvuy%TkvvL4FY8|k;%;9`7%yoRXa4{O9%r>q zP^(LxJFmp;wPuRvbkHsmPo01{>+fI3*uHf)%yhiqD?Rha=^`9O)-c@g3c(449ZJdz^Lrdec*8bCP=(ei_Fc zzBAL}jW<8|ipnh&DJ1%l;$vsGPYKx z`$=7$acQGM?&R$_C#5pCGk&@9d4E3 z+fxqo8=E{ZYz%!XNJ-x0%3aMl{2OaLU%$5wMi{mT!uRBL;=Y?9#JJ+3*PrCf@7U7# zP4KfqwbCJIbc>gfGr=K`Dctob(m_DVS#UCrw%Z0G9o%dAW`1#YO)B zTOU%y)H{#D7$=JX*!5?Nl_ z-JO=~cY%_mV2YW-OIABBrL%?Muxl&a&P_c?F6E6PWZDQ}gIYm0&T6tei{meg?R-1o zOQ2X7=8jJ{IpQ@OfIF5XApZb*z1%IJ{jB;NSX?@J&5(vP~&TC*1Lz@`Dac_hDc&3sg( z@2Tk0Z7oYgtEdh6)VJL3r?tvAP&2s*#PCiFeuAk*8n%p!9|_+0!%=-7MYJ>DOBs|a z5Ep31;&a!ncH!uA9F^-TYV7e1FI2nH{x4a0Us__GWyQvsAUVR#ljS<`+Eh#*YW-h? z;^<47JO2RtM}?bIjx!G7Z9m|zL-aSnmvC$T7t*z6O|N-wlFB=)9;5TkZH`i-UQq3^ z@N&YaRB3-&8`mBkvbl@PP4SjsS(U%XwRx)*C_A0L#VFW>_*xinVk+Vlf&9Zt!5*?($ZNW1fv&qBO{)T{&8JcY)wjX=8V5D@-v%?ymBE;?=9Fx>2;1YU&Uy0?uHt=?Z;!R6tucgO( zbX8d{CPH?uO5<_JQ`fe6HT79$I(SujZr{^A8Z@UE`=d2+;V*|C8MV?aAIxMYAvuy~ zJeE1{&QGTU(zc-S8I5;2{)cWC2YFsd`DfyHi?u%$>bGg;yf!Z*Kq6T;BSxp>Bhxq; z^{>-1j2tkumGyt{=haioV&SgO{tua7;p}f^aea2IOlM>y520-T058tIE5$5IjtVQi z{{ROArO@^*r1bv3%=GO)S5XO#$Y6f&(!Y>#pA&4>H5yhrT@u#S6>eiJvM?dCbDaMG zO7kjKva&IAyESfNg{|Cqn06m1&N6)~hIJg4f=wSU{B^K8e~n~hTnmdhU+6$8f0cDm zjHHX2i&u$5;AAq(<9TI@7M0<#a)YpDbs7A#`B!8xin6urbL?@RDY&-0@dl@JZbGb= zvy~&E9%EqFOz2LZyCXFjM9WDU2;U2kdCg+<(6y%K4dlLK^r)IHI+e)HLsu+sBBx*% zbr%56J5#s;Ip9?8R^kzg9)fDYO2P_A0~xAF1s&>Iu+W380EH(s(*`9m0T`okwPA6N zYC_f$feJ=D(1&3F%{B>K0mUtWI{`VNyMqdMOh5)`wZ@ggi`+m4X%4_T)945Z%^+^# z?W!Gx>DH++Fs2}&dk9Zzn}ZWLrF#e{+yw(P4GBPiccpQP4ry*Q#U~V48?aRjP(?Hc z(LV@pG@EaQ6Gak4Z)Llc$$0QGW_p%r@ick94jxl#SUxuoq zOiPJWyIdA_3@}3mDo3{pwfp8Fw@o91A4#XD^|9;r69WqEJPOsr>0VHFzgm z*Zw4GekAae7J?CR9n@^n?T}7~c`7h-^JnW{XOm|1@J)M9>whE3gcNR%vAzv!w)&@r z{G@;)hD(_Fb|-P=eXYr_KuS zz~EPgsY-j8Qm)&v96GAp7KF#Om#$3?k15#=SsbCI1$ONxzB#QUc(bWNGamazS$<=N z0F#6N0M@SBScevE2q^4u9wqQ(cV&!GM++&+kj?Y@Vp^fg&q0>c%bf|k-N!xglX7+4h$#C*uc zepK1q4C9LZ69bs3CH;5uJ^D3bq3>)%;eQO?*=XhGvzi|{gulE(rMD>TdJ&9$L9faD zRLtP{X+__E{j{DWbe7xXd29IXrcc4j1m47=T4EE zi|B04dXE|1%K^a6VxZe6+23=+K04UTs9xA=Hn0*Rw|Hg8d^Sh(uDVcBFsPrxQurNa zEEmMyAZ6PvoubDcdypN-{RMVPP6;$iT&q*ab$vEyu36&*t9;yh^Gn(}vslzkS(azh znS3gBJ;QjHV;~(DILZAhIn+^U1AUG*T<+)ArMsF$j*(zSX*F;gj&Vo@;LzC6gRLZl zD^Vf0aXK0<8v!|>8@RZ~HCqTX?Nap}z>jK>XaLOsgd9*HCpAcI+){JefVh+hT;$L_ z#H7%G3PVD*0KkEYH_&YeGuocQKt?G8RseBM;c%h0A#ue?Rt>z?fnjM3L&a6Zz!OU1 zLR1JbiU0>%sDQZ?NN7RDNQLW74{!p62>>+5acCG&v=xs30O4KilHN-4IJy`n9yWJjVPySh{gHy@jC z(zMteCoPVy_rW)sg|c61mgyzLOa8BZ0}t-!pgxqYklb7~MV$j)v6aP@%ui`?2nj8; zibF@xcjl&4Bf2xEQO((%Xwu`jRg&5Fh8uwZ5szbB^NqJU)LClICWL3NYQkEHXl~fY zxp)~Q{xuPcPeR;nsnKcBmUUe11QEw?{YrS$#>=QA_&!&pFdI&Emq$Kbz-;?T8A zy(aEQ*)Pij1H#7SxFmWB0}S@v=xg*msk~+tN34I%pCg`S%i~X9_-`}ZEcLi2a}2o; zo&nAP{{R}^rXEq%A3sWigZGY#$|z-QrU?U*JN+xpsN8owS~h!^Wr{f0d#-cP=CD$` zI^zqJW|>zYo;?k32wy{{G?O{KPIYz$LNOU3c=i7P^;e@tHrU!Qac7tKz{bJGeV!7lNcHK_=U(wZX(lUG z^P*NV5@Z9MobW*Hk@;8SJ|SYcu@?Teh^jSvByt+=oSWS?k=F!u`q$)hpHyodQO{Y) zb7L^i1RtoWQn=hSI!N!l_ycaqKhBhqn}bK5{79VKSVs)F4;{uA*pPYrfu%`ZoS2Gk z*NG2=tPsy5U-kUAbg{(_X?ni^>{hq^+N6=mkJX{`;Dxm+B5DO|KJb5xzi z#*Vcj6!xa|8&(#PK}ZJCasq$~007McO5u+6Em%T>iUxp;cc3gKG$5kj1Y(%lunx3r z2q_^3DqFDZ2Z~|}U=&;c=e;JZH*lr6hh$SK;CbSZc?DWy3Ty)zq#*?YLBOdV!V{Wk zO@$!^02BbDr8H6&r>Mlht4`vuy(wHa0CPiE1nzZz4fRO$j}t+4C2%X{TSLpRJs3l! zP2*&GzLjmV+Z*{f%7KB!XUojAGOJGOK{aoOS|5tyifuv(Qsy@5T*pH42RGrj@K&v-p9eJEf+( z1;&$govfEO?wLNhDhFDMm^nvc9G%YhM}|A4Sv2|MxI@NcaM`XNM+asuZfy>Z+9={X z^6CK?562_F<5L=Ku_dXl*ATv+Hp_?F=)(#AdRNwP>{`UH>!UNAd6~K4%~o4oD$OO8 zRm@2v#zuDhqmOaYzjCihNpl`vFIgQurn%=wkKLCZg9DzG=gx|`#U!4C?sYt<`SykC zsyd$4F`;H>WMo`kOE599+`#8K$v;}{g*1%i6NC7lccD?aA7KD^c<)MFfSTg(4aI zqOKJ>8mUE^nsaW*!Q-gxDw|JoTehaeN+eK)6an?g`tw%W=v-v%IpS#7k^VwW>2IOyC0D{<+0^iQN$=&9UgL z@!7KK_O{IIBQd@>VH@M-_u4>gdm8rgJafWg5^qQTPssA~3^%uizt+dIcvoDD#9BSJ zv1KYVmDxB_2w7K#AD<)G*WTi(`#CthkC>^3OI5Mg>H6cw3Wgx(p%vxT!>JP(D6I`~ zsLe3l<`6pLj%$U{QD;>NH0;XP7ZXglCkLqJwuDmD>R;V4uVI_-ysp{f?|(|}q}M~f zo~u)i@dlcz@?1(m!hl|tu#M0C=6XnD4`r3bl;AqqEvwEb)8F!ijoJ7~9i z6<0z_YdGOpqyiNRHgq6=pRIlo#@LT(ifaD=)uL2lr1UwT5ol3KwpgRv<$^Y-;Pcd; z=ZgIP6_j*0rw0>{ztI)RDwtq94z+GwQF4h!8(FQ(DBXj>z@+7K3Ebm8A=%tqStL*q z<{6ZrJaRzuI%gj-A5)X~*HO zBei8A#oWboAmG+b8zwg(QF{zQ#Yh1(4ZDglO;{7KZlQ(5rC|r*O@LCk02!cYT=9wk zN=*ndXt?eNnl}&*DF73i2Hn7W)3|`+wHL714zz&^Mkod)0u&Ew8nDs^rr6j4nw`Xi zrXZm!fa;>cfC?@FKnb5-l$eC1NKgWUill~x$fVHjHjyHZb49K+C>WwT4J!pU#uR|F zVQ}`hG0wm8&DF=?LH?9QU572tvTU_kFZ?SWrwAoA8(%sy21@TwUt?O+KbjNqsxzWaKAHpd(_jCaVk?wW3SU7hyZ|w;2h)H zhvZ{X^E;!VOGK0_70x!(=@)Y+ z9>+6z`#<ptnB1fC${Ew0DWtZ z5n7fNUbL<9Z}Kjl7Nqnt;qWhsJYlZE;~$Aj9B*!Mrf9b89t$uJ-jM$Q8*wb9k%hYC&YoaHMCk z$A6^`S{CWpmgc~ij{M`P9e+x3VoBKN^?Oe;5=yHf9)ukIe=6P*F`YY{@Y5j@kCZV} zyQXWt6*6`k-? z6w4>d(tviH9&%UZJwYlt=D$Tyiu1 z74($-$nzbvlP}x{p4_ZtL_onIb6?MVTPE?6`F>FyIJGTKdiv5M5mr{(a(P~r@e`=t zi0g9D<*&5;@3leWkSnH)q}7=>xtTtchBlI2s1y^HI0F^g6m!&?O6Qq)vg+PT==9qK zTbs8y0XfEceLYF+D|&6MQO6H`-4!l$>2&x&oDVY}FbqnQ>NDE3_R%zINosWe01T$v zr)w5|SjEJV;fVXWQVu@2AC)&KRMC+bHqRFL*KwxlULjo?%XpI3Et4w&jO3jDL~-?} zNnBM^zNd}qH$mKyRV@t6*(CEiip{&4B*<$rfF9Ib0E|)_RuuH1jj?gsfDq6ON=%VS z$fP@oR3M-NfC`WmXc`iM02!exjVplbPQZs`Qe(K<2^1VqG#h9gg(nmPb{o{tg}6|) zdI%`xumKpSxZ1Glwu%gjkz6=6A-II%i-QBwnn1)D?@q!%0qcr31P49nPT<2CphAJ` zQc^GZCI(BoM{Q_}R6d80zOz#&O3$*d~AUxeA#gGXs+Y2~2CGqh)( zm7EtYr#ooZvUkd14$^SkbfFt2tz>j|a+E-&Rd6`<%~O+;)Wx*R(6~7BIO|6+ElDJn zG5|b=>T%90WXY6F_C)1yN}pb&d-knq)|7O)QKw=(fFX^BLk0u?Jq*mp~<$=>>+kJWlLmSenX$e zwW*uelGXlScE6k~it6BTZ#=~`ZAhU`~nUe~NUB085 z#!+@I4Yqk_i2PS?1Ed!>aU_JDqjq!Z4{z(mXHF$b^LiYfuc}#GTSz?R+;g>+xd$Dq zx|)4VtnN|Ltt7mcNL^TkY*c0y$v%R=kr0#%Q3*wpE0fyiH&Nv)$XqTL5Gh z+BpR9cJ$71U!q~Nyt_1Oo%=a?UH<^>zDJEL7b~|<>&!@gID8@086mmWWYKP4gB{E- z8t2y}abEo_1|p)pD@s3i=1;SG#OUB$}HDq!(2-kUe& zl2>M=+OCi{CBDC>$fRcib;%!z#b*i?AH@gv4wT%b%8|?KI=+)-2{UUtdk4l@C);#CLn(mI55D0a9Da%N?Sf>t0%sImK<0l@~?o**DQg_iFl^r)D z)I4RNTSXkVUMaGQJ*8P%QW=l?y}ug%cF(EGwk7ia09qqh&JxiazP0gx!WvwQVw2r! zQnwymnycf}q37veG_vVl?@#O0&AVvKs61ukt#obh*TaoZo&@t-KEmHt+7x|F9>z4C znBrH9;m^fy5KoU2>NdJ9qcC9{E#^4KIKVj1xhL_h;OV^)%~KEUG`TjP@bg6QdQ7%= zbI*BvGc4DRuOna#;DyK^{c6^#k1CCaDk>4s<-AX8h+73qbO2YM$$d=SJCl4rx4MQI z)R?wN=_WFA2n1m9k4os~OG8N0a92KM_@%EMZ^nAH`>xh&sbeGk#@atcs%gdUa#f7g zOGw}@h-V}olp<2GTA5>TeJX4Mfr@DW6WWG0?f~b5O5lYj6o%b~=QI)&00W9i4Kdiw zF^!;*paPYE0mUJwV5Y2jqWMRTUc&;ibS)LP7#D~-<3&IU$kdJV*loeKlW`cyWCq0pWfM1%$Ti*dy} zs}GRa)2&x=iJ;`J4o5#qrtYp|JrS=H!(;=xkco^BO4^)yvz?wn@t?=CTdA?r7Dg-b zGiMuFvy6`8fu5as%_})RQs}G5@L6uJuP#ip%Os3WOED)T_2Z{=R~i;N91>&IFK3)Y zWH-*@>J8gBPEom=2%!M#RNB;E(H4fj|^T@?NR@N3t@@n&U* zR*g@>Km3VOqt5j*;Qg9@2u1S6;o0HbcONTIxLhCm?!7n1xvcHYQ}B=f03u`cSj3j& z_HFn@I9U#ls7zE~7u9YKfAQ+(mmB7ZSx@kf{{SL5(okgf{{XXZ!5GMp_&m!dIWphe zF$ezpu37O`V^%IQo}Q8a0OU)I99_*wz65+8x5SWm6HazqW6uU`WBvU8wc^hgQmeaW ziM^3}-@@J;(i?7xpy`%KPV8G+BwXVe;CfWbwfAQBxfSxn`A2gj07w`(u3Gn&p!*#C z+)49|m>>`V80NU*?DPb1y6wC9jIu^HmMRp1)BgakT@sd>kDXZZe;3;TUOQ$4ASh08 zhUt!dD=ABq&C2TRW{WfE{v5u)FORcDEbX5AP>=!qKU#6A8k-$d<#l7??Nad1b0p{Q zNae{VsXgnh!aWZ*uClS3&Pc(iv6Y4siW?Z*=8y#>z){aycN#!NAZSVi6acG0(1RUw zOc12zkTEC_qaCTDkf+jy3~3mt+)Y?qW0OcMAvvHJP#~dzQ(zP%0Y!i*INSv%B8yme z7Xp)49e@l|1gtci(zuxFWeJRS>q1v2VQP}GKu#zVb_~;Q;c*tG!a~w0F^YFW6999H zq{Cr&G`9`Hq+vy_AUsiU6FKcd6~|VKu-=-VK>o>=ao^wgg4M^~OI~x1@@M&1OQB7} zo?D_Eq?OU_{uqQ$G_Sv6AR}WoNI4t~)hWR(4HTQzoy~^tC6XcobqduEv?JvPh!{s9yQyN3V<=3b6dtqD;m?Y(B87MX$Bk(r;HxP zstqy9b~LT5(k2WP<2{cYdez0sRV$-wPHW9ObZTyxnMdI>siWb zW{IV^M+>LOP@bl;QM=TZ(WPr_QG)In;N%*7wjr}-6)})cPYuVg5`K@?BjCJDQ)^S0>!a~T8AjVp&k5{5hic^Itpiyf`8 z=6ctM^#!}%EJtp@skMUw0VLxY_3vE}acaakDJ@KGM@qVZcbMB@0B7IQw2hmyAybTZ zI**4wF}TomI3tu|GFCH_jyMa~jxqRT*3p4AX)9eL>U&%0^$S=f^L)Y(D=-)ZhXnq0 zg-E!wl`9Row`oQO6few4>si@a=Ttix^F)pElaETt>Q}?DR!Bkv$;B@st)Q_;0015b z6gi5>ddL;{$tTcts!ePzLUSkpFkBPZ3eqIC+^KQ|jgi+Fp~d$pJuGEhBuG!5IvjCW z)J+Md*@JeEk-KYw+;rC$OovR$!ybcz=xi=hP$$Hzbk` zpq%8MPi&5JTe!oQQ)uhC&-`1~WYB&V-UpSu>#-ezA3)u3f87|Y{f55bx@s}HJ~p}_ zxEam`RoTZmDHV%zPngAsI?@^xj8L7yi9m(xL0gMJ!~;2?n+ZULS_XumK|lp7fS_iW z(1Wc2g=#hi8P6D_Vcy_IDo~h|Aq7>C1xNuosvCC-O^7IL0*1g{)RRNFXD1XkJKQiS zZWcn5imZ70M2PJ43otqJ;mEVSX0ueA+Z4OQY3|T9c>y4Agj!lNr?D}Rk)ZjM09lV;dP+AnTAEhS zi;2}_lVXF(BdGMN_AV;su!~1kX9+RyNWv-f#}t#W*Su>(ZEnamwgB&rPd)0nv?k6Z zhTNd}Msvn#b2K>0`<5ZKBxX(7J+acGb53H|)5Cxf6cfoNn$*rs+>$LZQOl0Fs<1g- zSd}7Sl^(rlL}<4-ABgd|+)&2MN~g@k4nfEsr?qOGmV#@UoUev_CUqAK_UORioRD^m z`|(&htsNKTS{|XN_)-`mhY`jEV3MPzS!NR!m! zb?Xhz@hJ<3%VctEDcan~+A_Ma%iY-|ZI#C0c|B{ErRA_Vxg#8SM%L;dEg)9dFb>Xw zoM6(_q?$4{{{R6*Egh0MND2!Nl&HsiV~VP8mP1lkvF3V*hNaUl))oVMk+V3)3BWlW zE4DR}a@6yMdL6j9a$XRYIjkzq??aAi??bz5aLNG#8RnCGrCF^? zS9Wot6M&@jIjm={!&AA3bh50QK_z|bmCjAsBSgjm2j3(4R;V>(w&M@G8Btm*q*k#- zoy&rAj8?IqLp}E@w6VJqpz+qRX}75@SjN=Yw7>v%s^bH>^{Kyc$D65_JZe`gKp)Dc zPeU2W^*IelbWDnQeqSwQW_G3 zAg8zmAPQI10~}_kb_zBSQK$;EhJcW02E?F4s_syS1GNsq*g@8kdWch=^w7~gHs(DC(NsUmDKK3!s z^{k~y-t5ZvX0DUvO)r%l!Db9|yOYK`{$jPVin-Gmt<759K=Vlo$@ zBD9v94*C{EAH5h~yUk*i_cENUP9tZ@JXVP$RAjAYNYKWh5rOnHpSp*8j98X2xF&eb zMcX5pbUf$A+GD!!c~Q2oWe1kVdEoV~igh`aha0_(UkBMlA;#rVfx`9U`d2j8w>o5> zD11fnw7v%L-QKBfX16k^Q4+B`a@pkLup*r(s*cAjuXE>nzuF(-ZJpCzNhY5?sBD;C z*>(l?BavO}2^(q&xU^j zDC855nVYZp4Dnj2y^+r*`krLEbQ-saE@G9Cm;$Vhyr|DZ@0yt@N!*y(Jr9z8IqEBU z@dH$jC(IT^T0%V)f38VCjX2@`jCrlO(^d*8G$UX8Uk}eb_VVPtpJ51 z6ax~01pp~I?M~ykl!O%^C>fw=Lypt~uxAtqC_n=p>D*{2VhSt(I?}Mvq5hNGgE7cD~fZDlnsCxszO3iZo&X@Qih#?d(m+L$7*9^so0?jrb}XDjL;SrlSS?p z5OGPd3%Zc*B?1a)2T)j2k^rQ@Gn!inDeN%LC|Zarmtm4XGawl2#c3G1XfNx|{XZqJQO1#d< z8qT4IO^8%zExcQH#HH4z(UnaVp9hJNh%DYAj zU^8^jy;M`#7jA~sHv425$x+Y~#cLK)(^hFk4l+pVT^dPPR=c@8cKh2ToDXVhnn2Rr zo5~7K2X6FA(Lk1^c@c>u;9|L?`HHoOt}asE5?#Wbqyy@GDpi)}I^5#CLwK^JnT)XD zo-%RU6ePMG5Q`JSnxrKh6XlSr!E6=loc7O3Qe3Rkr!qsle42gki6nQ^L}QUmXDlC~q(lrcUD> zIQnCnpF#n(C&obuSAc~%FR+1Du=g*eAQc#tty zO{(FzE^%GdXUOyllD?;Z;BOAt>DCclv$U5` zpWV1PRU-r(V>!=S(s!QcDtykz*#7_yE_EwU3EA1}1={8))mXMUILYL3)b{nSHl&hf z$_*J_GxABD|Exo!gnnKD+E1p0D7(e&TX{24*jb@KZ zN48jk?D@w-RGs8=C|^>niRSr?vF-l=dy;;Yt5I>XG>WlCdm;!fHs|?PNfuI&G+=}S zuQ{gEdy4khtvbe3wlnLF^si=J?otwj&JYy`7$YO;O|bk17L~Vx19z!P#-Z9l>O8rQs4bs~$2u zx5V13>bkYv`$^^-nciL5>$v8v&Q|4-mosluA9hVcDKIpEZ3KZBplw(v5KsX?1ppKP zPys*%NCget0-FG&01hd=MxBRIVus?8HUYurfY@FIAlOWCnyUqc2NfWMrXV8}Uc+j_ z;9`s1b`QHiY$XJRCawaWdR2|;8-3_OVF<+l#Q+*<0#_2Dh$-v=Nq|zg22BgVMao#V2zJ$g`!}c{A^n9m+T-sqfp;rB&#Tg(qXM z({1J|uBYW?{C^r=(V~=_IvXos3YiB0@t*apX1W?Z5xZ>wc1)-M9B2B~D|H#I9kM$F zQP!?9wuE0@M>VQMHi9#ro`$q?Wv6k40PRV(qo8Vx`?*XZpBV%2tR9a*l6E;=TUe6e zkz)tTT!IP5<5|fq*-?tz=JhM5XH0fdGoJM0INHe7S!i;atNoc7p(SJ_vN&vQJ^ug` zR<(K>Mcky5>X(+gO~n3Mos3zD+aG^l}U@!HqT9=8G8%*!~Gi&8rlzjCK^A6bU>rOIq-0bB`Q*!1Tc&(aUxgmJR zb6PC{obvMUI6aL&1NbBR8(e|)8_%`c!7wQiU%q(3VbA4T%Bzylj!53<`d-&t zu}fX=I*}B6y)nm3R~+SLQdivNb{lw-&72P~;SK@D4P_+Ku=dcSG|3X>zL*t@ z(80Y-JxSIZca&v`AOZC?Jl)LaE7<3!1qg9~Gn&Ecv6I(h%Kj!@$*1VIC~hQ@Ilp!z zXX<^vgP+2>XwJ`4sXkY!@!!ThPV!s3YdLP&;fV~17(Xax&Q3jkQP#Hl-P?*WsZ!5F z$()kJnyzkQ6S*Bg#Rt}!u>#CZ3>q#w3I=I{5`hLYKm`C4ZUT@oQq_uRN(li# z0LOX;fOVh{yJ?}=57vgkfEl3)2}uZ0GebydN(2;u2U;vND^jpA0mV=!VMje^1*nt= zC;+Mf#NvXRu+z;VLYM&SQq_isXV!t-Z9CkM12l$}!jOj!l#{VYDef@FDA5Qhj47}W zYNR4a#v86HXlN*_v+U1MlCyK`bRk;=>rubJn?~JM3RKMsqsl8216$qUEKzI3afJ=xm$A~+C_Gqn1bg#@-fn?H0`-As$E9IU@vga2nuld zfe2Nr<{ZGAZ zPIl3b6**nmm*(ngh;Cq*GBy~nJ$}72SuI_8rHGGuCf3N05g%C{c8z3s|{3% z*=ZV1B-rkjzt(J!`HSn5`K)#&Q`Oka;9^tx`zcO2SJT zzU{*Wy45FrfxQgbEsU>#Gq*g|IXh}xWo;P@k%dsLgNnjR#kOQ$TS`7?#~s1yDqBd7 zWQ<#+jx}i*e86Dlxn)swGoAKEHlhS}?8SgB8QZ%cfBLgoxhWj7RyoVYSA%*;59yvN zCizh}XNY`WndOo@XhBzqI}_OFl1Jz(d_6>#rgM|%d{^-b_3pe&s4-#!%3}%HLh+B% zsuGJ#_$c7`Yh6Xbyn1 z0u<6?V`&l;08qePv?8o6HZc!9DI#8=4k@reMNO;?2}a@y7zz$3Lqby!QEfmd0M030 z^Z=#-Kmj?b8)2N(w{ZnKfKkkV2NaXI0Xd*;+y`18a6;!Ds11Z2YJEWtr(%Mb1t0^( zF$fN51S#UI2O;MbX^n4l?Ee6O!DaByhj9yuB~(CPxc%7qe=Lenob^o+Cb}O?=_s

|rU%y-gO=4fIJ2N(l25w_}X+`W)7YIPOZ5X3FW%Ll{t_Abi6E z1p12BRc?)zPh_KmcTsKzHlZFs7K za)QT}=e=}BNu2d}I42%~82iB=dBDfWFnZFG zeGO8+hE&N4OY-tarF#|1mV@JoTjh~L_s^{x5$yFdHG6Wq_#`MKWS+R8P4y+|vBN{J z$@cST^8WT8kfM$<*ggHKy_`!|-0d`L>0NyAAw3LZmx(P5Ualr(7(~It1?WtX#83A!k%GwJ2&gE%P z{o&fPlj>-lkw)tA@PXPF*c_qE{jQLh zPXvHlIQkGPraYXsW;I$z#y%svYyDF4@w(hh(jUi~%A9PDXic*b@th9Tsx?9_Sx8)B zfrSGCaY>5eXN*!6#GpaOC?7zg;tF>FqTne#sAFOZdx8#?Em#AtO#!%2A=G-7AwHCe zYyiy(+z=C<)WYIY5K{o9Uz0Hy&*0+qli01<)GwYcmRA_^^V7a9C1*r7%{Qa~e6 zCM71s1Y(uO)qr)O0v99JhVDCqP>`6QVyJ0YC|lfNLw5kDdw}K1J!+G%C3Ea=*|PNy zgEaDk4;T8tI_=z3ch;O|cGqhKUR1O`qR>mW=wY15u$`kI3=%RwE`K_~HrA-)ijtSS zcDiaA08j>d=K`IQ)ai^FMe8SW@dq^wwpisWalH!!(& z6+lBN=iaGIhVC~0=g5S)Phd*mB_3trAwQO zv9BVI=JlMTV&|44878%hQZSV}>@!rc4GYiZmfA8v?_0(?nA?*^dFT8hzh=~C)mqof z5;z>4by$<{+r}p#-6b8;Dcv2TYjjG(MhF`rAc~~aXpqhU14a)Rh|=9HrP7U(VtwEJ z-hcPkjvddQ`@YWeI?sad@FPTyT%M7>RKXoIo zW?d2#;du{LJ3jw%Q&)@ejXor4)MIUWuS=BG`6vKi2lvzly0s;NFmJgg7>#r|?ha{E zY*7#Rs1F1ZhB~R;jb7L9nTNPr-B(_eayiO_Rov`8qh>sqX*U}Ar8LOV-c<_G(NQ!n zdhymY_(>iM5%PQgKMm^9sY!rFNjPYYt-`!3igXTpn|dEz-UFz*tCkrW5!l|rn(lKo zCE1On*jWgt-^fNIQ{1Sckh*#gemXY~jfIHv@^B9^Ov{|%WUW_Km1`@=jeA>UPNDv`*!@JTip8(kO+5@38)MC^opg3-APsO=pcFXuy{iVoh_5Zn6}La zzD&CkDqhmK3-vUvse6#QdXU>5bl#Lu!=?;o*99Q(B#VX_=)%`}dQ9FFD>-&IE$eXe zMxI%;_qNT?vVWua<8o4UMpN595CN~kN{A#Fds1txN;dq0@P;W(ytCe6O=h*zXp-a0 z0lEA=yZ+IhA2e$mCcxEJY^PhS%f$hYm}lWclnmaC`5km!LDfjNH+Sl6UXDT$#`73t z?J*TeP*4Urtau0~-1&{_L^BevL%uA3auzo&o&S*@fC3eWm2yT}4?M^nrObz%I<5iYmx`ljwl~1w!QShtW+~`l_>#clQ8KBh2dO7W*bJw2cNv5r7? z7ElyHMGw`GQ0jksp}6d{hY6Kqr$lx(r@I9vKb!OtRJgurz%+^ICPQ=5lHY*OLAIjh zi)(v{9^8kyxSmA!tg6J@1<9enMj3d*^tFu5Ur1HX)R~qsgrP5RTIzqMwTFmynTsa& zoS_9IAaI=P?8~N&`*KDZwq9Qqu|q=0t>S~KL}FOHq#k4cQ91oWafI0PrZ?EZaeFBN zTlOn1#)`dLF_bZ|Ws{x#k7gs__)bs_+k{f%T0kAG&9#tWMT5XuGhdY2=vvE8WX-V4 z38)w(#-nW%S72i1bCJ})Cy5goqT~3VgaMbdNI%1JaKw|scHV~(>>7{Z`9;n~G zG+%T$6|4}v!adR2d|0%~UHY`8K>uJLG5%olSYA$^uE<(uB$Wv=toADA2DLAwqj6b| z00&e(1HeB^Q#soBVJb2u%Nb6@0`2>=>cSa+CA^>dB>E(C`Y7U!9gBZ|N78)Xg8K;c zb#G){Ve8U(&xwp}WBFruV%QSydW9dCQ04oT#l|)YGm%pm+`1~tIP?C z;p9H{YYF8dm_QjFg3guf1vmdA49{jl#DsyQ0O0VVD8MJzNGtZiDc%+%7_h5!-zbj| z!FC77Juy4n6P6tDdB&9)F!u>u|6Z)8Re>5T4=n;AVC5~{wgE2A{r>?Bt?EMM5%eX9 zmBq?X;ql4zm#qH*W`um6yYa@$B)?$Bg6_G4lnLf6ZOe>ucF|eCfdbzxHO^fXeqeis zhj|+td}tawEXBzx0mS1Y8%(|v3b6>HM}Z|Hl?9ikhaX2m4$jSjl6zOGOgLekFSu^& zQ_xEgJ!Qkw))Yc$U)G3_p4~dbj9wet-`A#C!OwZrDZ2IWzzS$7oPY3!s>VlI_1rmI zQZ)w?9<8pr&{|{k1(aJi+V_b)cwE|q$o$z;zAETlP0%bGnlR8F=}65dFM>7o<5ZkzcCXdMs< z9kp4%<>0!1!JDu9d~-9$Hk334U>oKxQ;z;}a%{bJp*4VjHj^oYmfcQNF>w_wGTa5l z_E6C2t*Kk##GIPmGPy3SmDQL5iKloW8pW7S}Aziz34FtLC!b8T`l8@7h{(Y!rU;;Xz1>n6ur?nt zf-askK(j<(WhdW`20!}^c@Ocgzph7w!oyKSd7eJNxV%U5xO5eB31uQ3vWjnKS;H-n z9R?v1XpqQcWRg);2_gHW)Y5-|_ald#J4Pm;woWh|uB4d7rXInnG<9ZfKcN6*mg|RV z3R>4m*Kr@1k+?2~Q*^yr6mmKIf>=MCElxrIUcT#9a3lrqioAGfc52N=hNFJ0pIe=v zBT2_cSxhg!?#+_{x3I7Pf^Y3VE(?N=YAO}J86TY2q@3r_%eLmc*$Pnm^TSL@vUg|V zPUOh%xJ0B4lQ*78#MRfAq3e=X1JRGeJ`HnAj-YLqZbpXM@%_LIN2-`45#aBF^piUQ z`b9}h7Tkmm-ttcit!MPcE3%Cq8=Kzy^MOgzY^nSP{6*ysTN)w@ zGE&OmO@r(0Z1%;|@Ue)9(ur2TQO)R}vzd>xW<=E7ZA3(j1PqOFyfb>EEn)s5HGwQK zjBzi6w_IqC@N!bA#w*;6}OL zrZd0s=As#H=Ekm z-=J_ZGj0P9&y99>bKi9-y|^x?hlq9rJs>>p8 z0Owg8qxIMa3J49Rvc`{C)@nFjywq5r2o2txESO6-CWpX@vl~H~ z^eOI15s-kHJOMfj$Enzvmt}>UMALvl?BbTy{~~>^{yQbuvlF`_s<+19O>x=sU?8$hAv0opIVn093R($mJHsl*QAi>29eFQu zQeZc6>PZgh35m8djKa{9eg=T%E(`grp^nEly~gqS+uiXa?g)NT~-pq;aOkud|I%|X*7#=x8_LUXOh zHsV;LPW54Dnl)~jKV;aU75=H#42(08Iw<{6;()fLtLL=GAP9|QGw$Sro;F|k<>idf zJc5U&mn-$(IGm3FjCUm=fnCvfI=^hRwt+@lMhW*Dz*5Kq|3Vy=ZxlJkRK~7!dn#QR zomI@o8L<~&g;!^%X&Lit>t$L=N_7Hb1dOV7B|co*G+s^t*nm+ekb~7yYDY%biNts|Bg=Xc-PIuWUHO9&mm9RU?Xai|&R4SE_Ss$h0GE&+J$$PpHzi z<3IOv+;E}8{(Tm(*~iS=4%7$Ug;AynsN?-zyg^ke2T8UXAME$0r0l%N^H-pR{WQtj#~LDhi7X)tM0 z|NJeUer5T+)En#xN|w0I|Ip)XQRXtXHQQ-|)j3S;x#Yvxx&N)Gh!z@s|Dzxwktj{l z)^)i*Z{d|z@7hsQuS`tG>7zWG(q!PEIw1}Rpm-n93QPxUslvRjBs`uzOhyH{;b84; z(?eFUBWu9mIC(DXPoo5Qel2DWsn=?AGZ>}ASeegd^Q};L*tzVwG<x zjAeDLGp;#HlLeeYUKD85!8S65c-!TCZG2B)bSpYaX^FSg!&$rLQZYlH4XS5xZGK{@%vwIEAv^q!olnouP6QqUQ@pyos5@(aHn?DJx(;g zoD{o56+7Ad9`a;(ISqSu>UPR(>*R{i^VsOx3vRTXR;FMR%2`|ONCK{X4dPN+o>t^R zLY!{%mycU?UwvpM)|r4Uv_+?+*N7%q*T}wKgFdnx8%6sNURClI%D89@3X2IIHuIjl z_U@HSB*itzA}4dkI706J%KUGxkl`wgFy9)M3zZ7L^`5te49Uh23nq* z&ocq*S{5|RUjTCWQk++Md_5F~o~$dS*E08g=`*fc)>KQ4$fxm^rM#}N6H%^5bqQk(n0$pMwf?wyWsJ;7_{AMKT#M|MKVC6IJ))`BwxON`DNr++**C7ehcX9=?EuWA(@0%kRhtEUnM>6|URpbQNL29;o zV7~=@`1kcw$2D$M?w1Y4_Qetd8bTWO5zbuw#^R<2(!dS65;}6=ETqZXySBnR`+Nh7 z!4P*jDDE3=0*wTGq<4V6sOXfZ z__Ra_Wzih(#s5gI4*GbwD7CpyB9?>d0`CNE0H->&b5*YCVtp(-Z_ha8>kN&s&V?Z* zOGp_*49jBfu)wUso2wH=ziB_@5lF#kkyV!1?lO2zgXy}$W!!7A58v~W8!l1) zh5`Yneu^PiYqxj(2i?dKiJuv9x|qt#OX8F3ZF_sER{u~2Pc@YQg$_kr`1b9vRe{mk z_c~Eq+v4GpD|JS0mcK6>4W0w#q)KYcE61kkS>FO~ZfZYiQMZ>Q7`X0Hs`ul@6a_j8 z>Ty8rxg5Sc*2eov^>ay{+r1K*8u4<$c=IbcVA?|f#w7Ow3<(C7s}nQJ*S$Bio$^gh}%KX+B#co1=1fzB?dpSN@Cl1 zP_$ua&wul%gvoDf9%`vu$1MYQpfR2O=9ZO- zMoNeJJq^_;l7;<8eXvw3`wG|c`&AWMJyyo2!RBv!_(~hG5Q?gmI3-s*UV9UqusZs0 z08?YaG0&TuhQBpJm~kb0DQx1B(B1|R)#k?0f-6^n&{Kwot-z$p7gts!TE43kt+I1v zVW!qShhx>s27YY9Z(A$fwXj=<-5UK}Dws>#UdKe^-^HS(5g)}FxSA%&g0!X3G->}6K?CTyQu0$@w{fg z=V@&|14}mo8Rk)9zP-dPsAsuKmYCNx=)P4_&QMX2msqu6D7EUs$nXm=^Nj5Axv&M%77GD)1!0k0=LcF)A zW63XLZ#G9Ue@v=mO#11cpxKR&}CvL2ETFq+?iU;DPcQxrcP>6*6*98Am$+o znVawm{F!{ zkhv=+THI>Ka{TLa@saDe%cSXgI@*%`{btQ*cI<67ByJX!_yHY-zeyX|uWaO>VbvqD zF>)5Bxmv)Z=TD|=^sKf1Z5-EJI0)269m3gV%caqRbXzJ|c~&%Ib|7DWkSo8f5wE65 zO73In-k`|c;CcMRq;_jkWa0fl$I^2(@qcfaY9{@Npn+D2-5s1eS9i$6bb^N)q{X@* zb%q4kxhapE)%ZduJg++HV2-DqzwbRzeOD-x%y1VmIvaSfi5W9i4s?K9dD#6*9|v4? zN$pU5a;0+na8=lLx}CLrB9iaPprz@}fWq7~OH7o0+r*EANNo>wtt~BH;Bj3<^+Aoa z_9Kb1?3uI?C0hxmqi;{YAi%^)3V7}rF~LIP%w8P7%=o5j4~5!ty45`RnlMTQ{nOdI z!LVo6Jq8SHwuMx6dmWM~kwP}Z(o?BjVn{7Cn7`4WACUAB0l}(d*n;| zQFpwNNb;zXR=s{~oT(yk_Gwm52NiuO=8>y-iTA!0?~aLhcJVek*-F4RV@UT^w4gMf z#u~?MHJG8y9Ry2R=9>#?A>G3h!2;iC`19YqHdZWXlJcw!31SLz=j3(|Majxo%;ibG z{tlgwn7iom`pxRUJN>v6jwpMFibG8U}3#LV*ZI;GP6d|I4O zE+e>E57hs$bQSJeaVKA$@&Nn?smLF;q^pjZ(#)D|R9Kl;`qgsb`rO`^kL%b@a=P9` zQ?3aGQo3u9O4E1s)_0GWo5pRfJk|diiz|hrk)exSsa=o1ctV~0&fzcxBzTV_Zt?y- z)`i`E8z>-xrwG0@0X8_kzX2KXlvh37;GtykDiDEr=zneQ083F-T{yPAdx&yFnIMnm zVoWrlgl|*!{zB|^%8(du8H0e&6DdrgK*=hLLT!nZ5sDpw?L(>WjoPYb%)MU(QzDja zS^fi|^zGMLb8#9|6e@%A@B#=G?DvXVH4Ehf;%HetF!tyHY9}s6!6c z#xpIm)ZRrauHEo2m?~bzz7{JS*ycxvd3^Q~o@fIE78RHM`-FhhIocdf9Y;V!o}F4m z)_+6kf8L?MQ``+BX|(s>sbnBnOdDy=whvXoaoTNDJSAdMTclQT$%vApn>5?Xkm-;` z@jYnbj)sqA7kCVO;eFIMEbUw=D-b%C+dbdC`!77o0o3BcoffwD&5!N<1O zndyIwVsz!%XOP2*TfW{YlsI<`D1nJtGyWr~jrPVzjHcn%?jXoPx}Lx9XD%IP$tI`B z;~pt<@YBBcIC7&b2W^MR5__OEM4+%?L+T<+%58mg+njRYk(*&%UziWp`jN-!(Cf7Y zC2uy0+NBB&Mvi{suGCd{DsBkmJY|4 z6fN_o_N2GvDeBn4D@5(L=sd_raZ6D|5I#2S7;*oG->*M#A*)lv4VUTHez9(9Gtu6X zP^G|zYexCmLvw=e8}5vO8dH4 z`GyGG)(&ldd%*+zM_IP3jFD5-KPz&?1wYUeKc(l$S-` ziB;`rg705V?XI-u)*k6=E2iDlmp)VSTBy&sh?%A~@b5ql;+P;b{qTonII>F61^5XS z(Q7P=A^7?3r2JzXOIZ^`R-1$uSdt2v0_E18cBfLtc7}wt(As(;&twq*vU6d{e=S+2 zJ7h*@Owm=nm0G002r^3GVmZiDo~O1W2fE_#4&#eZKP0IiB79Q{Bq}U@av3id5GPYr z$^DLDX6soWjKRDef+m=LQb}`6PQF8bQ7~X-JV*>HvmCwy5=mEh@1RVwhd-!2OnUu5 znPU!?YoLkk1ZcaK! zrMjUAGYL8F@Fa(kIwGM|aLd~y+8#RU;r638P7gi;l^nAyOe@ptLKJs`^^-&0tumrg!&*LAHdS9J9`gYM+vZ zpl%hv`RrhYRE6tl$IRf<{!53{_L1d`de%NwPCmIKaMoB!^d+;t*GC8s{dN@;3XkVZ z*BwJ0Yd_5{8Jq9mbf7;H^7oGuDj-(z8~lmcsWY&D!g?z$T()&BFcSG|B}u8)YT+Q` zxkx~r4y(2gE4Gy0W808kqP$uCkS+UxlhrK13K+5F$6%fX+IPM5fHq+9Z{8e-w}{!P zk*X@@WRFVD=M4S7(GY7Z&URlLhgt{K8uLvns7bjJ^33tKYn04&Nw~$CX7Y(1-Gs@Q z2g}>H>(zSx=E=>!v$;4Z1NF(DK^5}NC1Sq71(uS~^MU;J6jJeDy;fS1BVyB!^KtfI z8+3uW-Ehha>%@2y7I;3bf?rQrE8k-v#j#DJ`wf0O0fsaR|8e+t$Wl)h!&bJx=p4J@ zea$4aBwnVnR+H9ve~I?%VTq55)s19PV?!F<&$b`Ls{@1}>S&8s^w^m@C{l3Vct z)IDT>N&PxUq1=0tawrK3J2wQ=v&sUrjS^hxH5gc!LNx@x^Z@F5y~7i8Z#F;{y2h{- zxIMEu_(@~&fLk?$u~WQ+X4D6IkGpZ=vQWmm&hlfx~5n(tvu@%~}>w36J%f24`+#Zfy>FGepzG0A@kk(l4 zX0#2(M7!bDp^<~HnC{+HfZzjMPd&q-oZor@?p6{Y;hw?;Gd?VpgSOK2*I{DjEGxdo zvY5G$qr-VEMI{HG$;>w6S;xg`v!$vbl3~U$5=-O7_5C)Ky0MaJS1o zgGB7r)CS#6_x)0{g}EQhTG~waAeAnhKv$fU1;cgzxoC;h>u1N>jlunr#%!j6DHgVs z2;d%uuOiFnX%RJ5A$!DCy_eE%Bx$iOcT|+_sQxqy`sruj%yLy0nGxe6wjaF5<4L+0 zIR)C@tCBbzn{~8$NSu8QVG*@NGc1am67FPL&1Y9amkS5y)2Ve4!E-CLmzX+_0cR)y z#1kdKNJqp?F0Lnqr{>QUFbnbE-z?zkkNa@6EH*$ z6dy(T_zA2$pfGBVcUnvwu#1$JNR^Jxk|I5j)$Rs>>^?5ZVOXqSF z3D(i6XRp;QN1R5RMei&$et5CB5Oz6fR;Y@ zx1@<>VCcWRsSmGb+CB=p=Z=s3$=b4B|4kxW*lm(KBUgUhEnU3G!f1;LDDGYD_;vt^ zlg*kGekSOLn==FcMK$g+@uQ)~1Y1vCNk0Mqm0Jm|Vk`ScXU}ANq3aQV00tJ7LK1~U zNI$cLLb*$9Sl=*>L&m|kqM~KLfd_j565e;=M+VlMxo%JQXAW59YV*3K+02zjw0b&& zRdc-Bcslw$2kAV&Mpz0?t3NTQPdEYF&8J| z^0~*G72ii*e1tc6`sc<6th)E+GaK5j*9_Y(HTxlAx1NIhv+~yTuc1s`E^Uv8YURG! z&Okd2knz~jfQv_Bp0L>u)wDkzZ+5nvjP!q<*vhsM&KK@$%>u}`B<&|qIr;Z5S=!dL z!G9wUg{Llx1B{>;wmku?3hSQU<3&J#5``H%?b~-gRZb{H7`QceeCh5OW4J8H9`^t{ z=<0GDs^s|FQLdDe1J;3Rch%_45>UX0KlKZF&p?^@o>s()OGl$VX~M+mYJYrG?2q0a zm*<73X92FUld!;Z%}~P!XB-WR@(L@@lTs-2cx=@-F#^D^6*sevL6K!Gr<=2GqE>nF zl!HdWpv zCrTKiO&Uu1S5Rw+g$;~$UIW2&8Dd?dyamcx9ZaJFu;aW+hZye_Z3-J&WbKnz*-}cG zssOt_bMrz+6-|5y9`vyRp8ev$`QUDnp3O-ObHO8vEBba&%LXB}5FLjbZBa&r=2j^e zV9CMP!T(fy3PJDnMKCKG=l8D#@55}Z#iyXXxIf@(IdcPZ?d0sK$p}zG1tESvy4f{2N~;6mVN_ccDm;$-^42EXWqUuc?H< z%dB~tyU)LtTIK$b{it9?c!B>F^kL!gtaA9ukELxfMH8ZzZD!wl&qBMy@U`%yd|&I~ zi^t#6%@ycRU0)MhoPb_^S*iWC*r!S<@=6D>;W!M4Y89pJ(0x$vQyw+@Y5mwvp|sFd z;I|;0@CGIE*PqS;2B%Oa3;Zq9DPel_;`64&x6n)i_2Y9rjhzFtwU3>o9zQ}>SYxVWfP&uqyKm@I)BdPeF-?3*k;b_F;<86n=cp6ehKGZ>5vgW$Et}C}n zw!~MmtB21SNz1hnvY(uR0*q_mLSFDRDLU0X3*|}}q=E$oN2v*#Z zgUGG8f$pfNNBxgqLtd?K;WM?Ie4*y09gVC|B|VdyVEtDZFD|EpzOx>9h=_|I+=IO+0~7ph`OdCAv-|BQNF&8m z_*V->gr|ver_%N4e*o&6H-sBuovUQMJ8yX9HUjfoCcXyYrevMkn^`LablL8BW}96- zA9}_NDUn=y{iW6@I{~^eRI`^#;j9pHYI(lJSN==IGH;NGjQ-R2e_n-KV^_1CO4ic) zALlpkS6bfrEA#C1r%w{}wT-^z_Ixp<5Tqnyr@jw!zk>*0bsa3dlbz{*ez#>Sr>Xurgr?7RYr&$1SHAVIim9;w0`qjy>9hnOpKm) zz=X`4f7q~@EPk0GDA0Jdgi=zmq>=~$6p^u(+7#goh8agkkQYzaIl(l z*+ED@0!g{O% zRjGQ>QD42J^7Uoeen`NQQuVS8>wjR{GK`95xZ1}_eceV03Tlrm=-Q=?lkyra8k1;Wk z&`$2*YR}~&tOq}CErTm9jKGw7>Q1*1!|E@ZW$4(h?eLWh6Xc+i(vLRf`o1TUgJs8Q zq*b_-8yQEVHC?Pe9t@MPZ-F;?9dA~(BA&(nF%ZPl!xq8u^{|_-G-rd>t{oNI7TW)U z1a_^dakj|G!LG*RxFmc9RUp?pnOoMf z(GxSvhhW?OMK!(ILq&3x4*M%uUf*TQ6w*i+5)81`*FShwjczPH>$j{?!>@h z82`QG3#VA~5cSu4)DRLze&&o-)_Qp(P8eTHLfvWdqYUxS-R|EB9EkM|-&bwd6ulfB zO$XO=#y?Y#+mYzm`=++{<4pc|R{yBR$im9y%+Vy6o#$uGutHN}@J6b+S(lgSzMIp# zcjUB!cROg5p1Sw!yhI9hr4g1Wm>~Y_!cCV@^$m-4skz%Ra%f=F-M_40+~EY>A)Ff& zTkBuRVwHp^1?tllfyYQ&NoLrMMOFi0_iuO7<&L2SbCiDEmLiYGVaj*4V{{eX4jp)d zqJagkR(OYMd+`6=7W$>Bfo!f|p!a7ql<)N9X!$(JXdBF@F@0?R(1;5v;Ly8m8;5J7 zvDSu+;x(m}@QOwN-7X5`dLa3%c+igkAs}?-A}`&7sL^?niJCESvu+6Dg|;r$gqLkc z5fa>->RI>>h;(@CmwKVEaf8_x>eqQN#g^_c34-1(;>uh(#=3oTFCk;&Q8O18vTQxJ zIeoYZ5*aS}64csCfA@=Ub2LSU00Q@D@fUfTvT(pFG6(1PqVqm-(WA;q1Vo$I$#|85 zWa%0lNH0#5Av>SP1$~hsNa9e~Ey`?CPEz4uT`ZucU|z9E8hj^lftt7y>{R--ly3-M zVlfJ$@v}^9&gV8=b1)6mrKE!2U}b$%LVY}bxw_{0HJbG2-p4EPkwd`2$)K++Do-irsTZ>jR)M5xrlvt)3)KRnVT>kIF2A z7VgP`D?;^JbsMwU4|z(vjgW^%$KsURuJzITH>Ke-o7EZZmJ@l@ z$Qhu{8~sC6SPvyi#(gU+v(YU;AFeEvy4bdac-)e&_}&JfaE~;#$6a(qEybm~HLV~A z=DY4B{Jm`4{DHb$Sle`RHj>c)kgxGnV_NRbwyqi|Fm-hGssTY{;v9W4!#otaninf6 zb2O_+E}rq_)Lg$6A*8!NkJBnoqGst0O#d9pU4$2mFGDx~l8~6>K)g;&6CCJSLK;K4Lx&mp<2(iqQAC9`u3>Kh zIAKaFjRx*U6P;XCwa?;iqG8-yN zC`3MAsS2|x9vxY)C1hjsjWs0DX!t^TqC3%MuF3F*wvcXUfs6CQGEN;2m+?3Ek?#TG zF&2L&bn8EXM;(5Hp!n$n4<}*2EY`-4ydVO(8D(l*76J$^)o*ibep8p>}ixa~gs8x|Ms~Vw6KA_z8ka{{ytWF5=H-X(nzyw~r zCs#%~{bDuPvU~qRs?(gv=0bT^zsBfU7z0LtdP{$bie@n*sqj|r#J+YpZ6Y=oS5@D> zC^LyO)8UyaN_z7!+YAV`p%gFJ&YuJkmWz@&BWD-d4ZjwV{zl{Nd9mHvvjuw~i-p~p zI?`0C6e;K0#hAhiLU`hYuy`YSW*6;PTHi-0W&sL2gWi_@TeZHwv7#iW1i6GDOM_IS zy0~CqQCj#^O*xAfMG@#@xzULu+~G&jLF3^o?vl7#V;j;rw5)Cql|?}K+h6lMF0EfP zCGTJU5v2BY(t5$kNUkH*uoA1k@jkTY)qusaGF1$_=UEMJ>NICdMVt-k!XC!WUvDjN z6au!fTG^-LQ-oxSC^A`T6OnF33TDb0cAX7*kPGNPVLON`*jFBH3U}y`jb*)X0z4i! zTU@|YHTaFqr`76?n8*DJ)YE&4jRe`$=k;@YqKzb|6_{}*2xnl!U^-fh?F7spqApFk zf7wZshYC|~H~2UxfssG^?&?#k&(hxR5Q7d6|8=u9u4pF*NT{<4Rmi9~$1{+=*vAOU z2GN0<(ZIXnNSTJ@7@yiuJ|joh`c_{rH|ZO;;PQaOLcI-=?zFITE47ubwW*@Uid#0A#&uaf;+AeY;+h!6~ZG>TD%Q3d*ou(BXQM1#)@HF^l?D0!2 z(0CZk|Lzk{b2+t~u+y?pj5;BBWm)^h)dsbn3rMPArZgZH+B?ixL0cUu(r^;X>{Mut zjV;5EL*9bs^WW$vOuVC6O6sa-5=nldcz1qkE?`^8ZEl`*)%d!i&6lUFVy%Zju0o<^ z_Gw4mM+ct~qD$+Bj;BXiz;rzMe@vgXp?N;_In`N{OQ9J>opP5NU`ct-U&)No*?8&V zMkg-Zg}q7hwVm%6@hR+P%$jB0lb*;f82=_vA9<|x0!FlaF!#yFw|V2mYlholpH@kC z{nV~JRs9jGr`C|6lurV93(E}c^BTdsxU13?IxM$>t(mZ-b>R`+CgInfY7dZ^Fs*4U zQeb_07VQwEv_5xco+~!^HmNe&)CU^VxQJcC87(!l%_tGPa0PfKrwS!u`DgT$q>Ffs zxF}viL9O6^jj<=INff=U!cU01swNYiJn;a6Aw*{yV#W#JRWe$9Mq-(jsEN&%|T-V`z}eei0M()$<>L$@ox`RY{T_aA`B>ob6g@#!wBLDXo#?EZfMoI3=tXs1;CD(o*~ zgy@UYphz0&{ESz9g$AUnK_=0lmb^ePdUP^fapioAX~cSSu{q8?!Np}%`_jfZP;~em zinsN1pnFfTy$G8G!yC8|pQXrD)n%n3nd-1rp0CKb_m)Pk75CXpVCmQrV!BQ|0Ak0S z4hf|S%M{L6zYjbjcs_!*^Y*Tqhb}$`+bQ?F$KWy^mmUZf`I=vNYa>UM{PxFisdao~ z{u!|#a~N&rV@%fp63>43VE!PXo6EWjNw+p^KoiIUh1oUX{UhLQI)H#n`h$B%dUiMC z;`14ni)=ZSob2)^Eh5#oLIz0MZ|ro%#?YBt#ELMjpG$CWZFKT%wPU6uBw zo&vtjz2GKFW|;JzVs)n0$lS1|b0mcm!8g-YacF_=p=JH8M{WI)aNwe*mSAZuG{IPe=xY>y@+~V=xBDQ{b-ynVqO2XfVqGoM)$2vP5 zH~P&EMqS92$_jS~h}bD^v=-EwEbe>yV;iB}A~BW%D+<)ql5*enxX^ez0b2W5zVuej@NHoJK^PRLiRSc`dxc=BFZzT;Xe=rSJD zl&Wo^Qt7QL?Aq+1dy!2tXK}?`@U&50gp4rOFy0nlOkNJ<=O*BtqO5=PA(r&1MdRs#B8qUZ zW4;6r87B#rGU7dQK%<%3B1q&EDbVRwVk+pURSTt%4wVG%_9ClV@G2mDRy zjZ+A7zystr_X<%REXRoec$?1!Ch^D6-!sd!-nz89_I8sqqnG+?%E%6eaC2y1m5`8?e8$5Y-2g&x~p zOLiAZyIFni#||~<&G{2`C^4n@Y;8H^*j`SooYL2z>J<0+3?YK78uNw1rM`uZv`O{L z^{jbj^@;`200MI>w3M%?>0^>Pb9cvVjX#^t1$oFo!-aO|3C&v1tJ$sPnd4Wn@v~i+$LHB-=c?rJrqi z4ncdPD%Oax*R6?g=L~U{unDw4J$>e9YsW~|P)Qsnx32A`0I_RbnpU(&q_b|~I<(e! zDzgnXO7+-da(9#}_gE+JL&;-*I9lxOV01$xp13YQJLjU0=gFtTp-Q0{b<@;kc@E+a zKI{z0?b&r_A5uB@>u$-eoa<#zp=B31D}2e)oCWwxV5gj=Rh1$ADaq}LQ5dt>)f&Dn z!S}!6ZYWW!49KgQk-gWVIA1@NAgr4h2)I&SOBcLwcX|i=*)8zR)zc-n&q+sFRq(T- zhI>?i(vp}vP{M(0txIc>jw3e<%?no4K%f9cK z@n`Pr&TuiBvGu946#dJQ3|(6hi`4UfCW5kdqfNC8P>cjL6frGh^KJ5zr^lkZSKmN@ z-K<5F8%mahn=@Zjj!b`?=@%xBz@&@ zHF5Z5Wr!|+yfrXBP@-V5ejqKZ&DtCwD;idvF|mko8@r0~CHDzBqyM-cksoUa>#u_x zz^o-ji>tQaFpb1v>y}dVTgA4t*UPPPo@jdAP{6ltt2`_D8s_ZAN@vN=+loUnn>HCs zR;02qaRvuO_rTShTL2qMP@}yd@Wz+NJvJyT|3#O8`!>@%Jlcw@#PAtyqt?E=6}$Wx zHZdrf_Nm2_=kt9VyuBe~nXvV?X-dUx*a%+h`&`EzaG0d~<-Ke}X4E0~U0p}41j$$j zCkMHLXAT^kZw7pI-gl2g=ToJkWn3IaVDsXjMD$m3cs%hDbQe~d&FK@Y#)LyAezk0W9OQBzVhC} zV~n%7gG)$OqP1a1ce`qSpRBc0r(2zXr?PI1&`q4zh7M%|?7 z>#{OIKQ`K%uZXio2;-eMH!am^Dvj(Zy$ey>LvX|GQLBJ4h8gy%_LkVmqG92k7El4V zP{;Uz+J7<5J*!yGOi_0@JP%&^;{kPddHI{reRv~69Qa&r;g-J*t!{F+y<#1#>Fm{gx&>Ib4u)$FQlKQ+F+`PI~38F57h3$4t=)UGkkC)mVhW#}FVT z*zFwkCbo~dWaQbsrD=<25c5K-y04gBhYShn`Sz@3B_(2&t*P?Q?HA&9)%;OyX%Tmd z!Co@mHn!qNAMTOOdN_Jfj5X?gmkwcCZdc#_3FOZ?5t$GId)EbeX+00QitbbM9ousb zYmLUoOkK;cg80jEkH&=bu{#mn%eUklg%xRNQq<0!n8w>i2_0x^+Mv-DV7K2UOA}LO z%%!nyqiDe=pd3?@xUOeNxs;Kfd8kd5Zltgc&x4L?(MepLkr#qTNW0991-lk}}|RGn}6Eltj|p)s9C4gOwEQN0B6?$fJ$CWL8W`Sf}PT?0&T)MX0h< z?)5!s*iu$2YA6~nESysWGS%8UY-b@s;8JiDjJVhBS459r(yB3N!PB^!)V^GPQk}UK z(;s_7j}ZA$S3$N(rZTY3-bE?Xv6U$EE1Q=$Ma(A@$nJ{-`A6aJPWqfxbTcI_$&;y|;;4-ILCLC3+~J&VK=HBw bNZ`@2$vATAMnI-!(1c=vG!)Q+ivj=HAA-8J literal 0 HcmV?d00001 diff --git a/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_1.jpg b/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2826207f9995a26cbd95d6cb0853980e0bce48d8 GIT binary patch literal 37055 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Ⓢ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 literal 0 HcmV?d00001 diff --git a/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_2.jpg b/ai_face_recognition_server/faces/19_Suherdy_Yacob_58_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a734ba50dac00e74dfa92b1d1525bc9ad9f9f9e5 GIT binary patch literal 36114 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"-~l^JiC;KF0}H%k80O+7zSxMI0m)Y9h?t zF%DC~M?sT)R*7a~TR1aKC5fnP z@eOqSDBJnR@Mp3?0)LV(u+Da7+x^J0WV62 zXQX>pAd-WS?@+)Ld>>{~ARa30~8wH6ePMGTNq>JiCjzge;l_$XQDk_*gxJ>;Kn8wN^DDP zP3ilXJc;-cW?TP31piq3J5R1KGjoEzQ?Bk!BHXpgbm)3=5fl{=P`G0Py_}ZEAJ^6krA~CxuY+pmo!bjf- z3VCUjODHXBz{uRcOGI_bw$Xage3&aHj7n#mUy8u3IJsgj*cQ8RmC5YF1A`>y^?f7} z^TCJU9J<81qBLE&t4dFtyGtzVukd8}8~MTY(XRL6y{=M!(?}@D9tx@@h*r}l%LK8B zEr&Mk5|WggShl7205<}DnUG}w^mnfOx@?yz3rEHwVr0w0H=!}axlY*`P$d~trmGQt zF`qmo)uD3g>iDB=*WX{GvX3-;?+oXv9Y~8%KKvCwpnMW3JWBfDhx$L?7mF<(NmAp@ zcR!7WgxPSoD-x-`uC|&YgZSH&1_n$b)P8wJ1PSf|*gG!&vC69v{1)>@zV>s%@RG46 zXH&?SGvTk1(@x|>YjOxQCM|%767dT_dX_7gi#cFNZ$k9P{z@rQ)QP8ri=cApG)tZ`B`1fjv|^+Efks5QO5jmJ7)L zuBKbTzVG^T^3UR92igKl6DrDf#q!=czFO06p7Q>gZS1ovj$AAGrgJZkWAi7YOaW9C ziYrX+PK@>+l&z%~4h}{ zvLzYHQ;WTnqgCKpJC;him12{m;M85PZQ1TK1*X5vx5rWi&8a+eY<&X&-l)JhCBN$u zIZM3)VAs&p8r~c-U~QeVE1XlEV=*xYJIi7&6KgCoq9)3+9a15Bb4{cl?|!SA#oQ%T z#a@Hf*$KU>c<6Jl802A8pahv+Zm%M{k`vm?fk5`qU>KZ`_3mR4a&Z>*7PxBo++Llf@1O~4C zOy>_o+#&DK@hSz@u_sqjzF6TM$lo_an~(ombT1HwvP|e1#SXaxZN@#NoDCOrtT}|Q z#D>^|$jWRNn8ppUdzd7H;uY%b6C#S{xzJ~eVodtbbQ{YvyEK~a-pXNr)&I!^ z+IQ2wx&vT%AHg)NNkS?RP5*}C2_vQVuROF7e%VW7@Fm+k&h&96Eht-14W}!4EY#B6 zLQW0^)=2~1-&9Lb&ZRNd`AJHaNAo*#>0z@Pl(;hQ*?5<&D+Cr9v15D^FQQI}3m`rj z$8(p4hKO`UL-(_dmsm>&9_;$a$IlOgYEu0+DR2OzJ#8PUw)n9VD=<{<%7b^VNiUzj!Kt}T?uceuiWO@HyjIhP$oxmP*!W?58=A#g+W!=mL}I#wc%{mu1e@`J_=f!$}16eV8!^H%{U?>MOsH{ zt~J;WqpYTr$i`Vg?iA057=J5#uQV^X%7?|6Kg{`dXtnX-9>0DFM8-X_YLvrD`@1sq zGS6X_$#(MpNQ8mB$a<0NMZ9IUX|KoG*|KZUFh6&ryjAn=0I8ctu>lDP z&zFLT@c>#??egz*vqHG+Btpx^(Yc0@Xn6c)9LTbHwQd`MXzWezJ+R79T0S+vC&iTDZ0 zw12DzCLV#fuy||4j zcIC^8n=v@@e@O&2RED_4b;S~Ue1}MEV>ZyK1X5u%UwE$L=BcQiIeV(Q z-tUSd%@7KA`_C@V!J}2Z!|pvzz%jnP_ny(vFk2lagYf7l_epo@a*^f@G{ouwlCAaX z{$9Kt=#{jjp7L+gt%**s{o=e2)$N`yqEFKrI3COO0E*TVgZ}onXzN0koD_th!`Rail^R|jA25ev0Lz&<#x2E3 zIKu6#|%A+7W;n2LY?GM>2)F@VmP2E z8r3q_NT<*2AJ*FPlz^6jPPxch6*K)@1YRwK8k(AVEmfSbc(l_8f>MIkk^HgM#$kPAH36ob8 y9SRic7{x=~3uU!T3l{Wt{k>}tk2r;o{Wp1v^9Gno+*A0U3#b2&4fE*VmH!RIi=8w8 literal 0 HcmV?d00001 diff --git a/ai_face_recognition_server/requirements.txt b/ai_face_recognition_server/requirements.txt new file mode 100644 index 0000000..056574c --- /dev/null +++ b/ai_face_recognition_server/requirements.txt @@ -0,0 +1,5 @@ +flask +flask-cors +face_recognition +numpy +opencv-python diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..d8f24b0 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,4 @@ +from . import res_partner +from . import res_config_settings +from . import pos_config + diff --git a/models/pos_config.py b/models/pos_config.py new file mode 100644 index 0000000..a622ee1 --- /dev/null +++ b/models/pos_config.py @@ -0,0 +1,10 @@ +from odoo import models, fields + + +class PosConfig(models.Model): + _inherit = 'pos.config' + + pos_face_rec_server_url = fields.Char( + string="Face Recognition Server URL", + help="URL of the AI Face Recognition Server (e.g., http://localhost:5000)" + ) diff --git a/models/res_config_settings.py b/models/res_config_settings.py new file mode 100644 index 0000000..2b05327 --- /dev/null +++ b/models/res_config_settings.py @@ -0,0 +1,12 @@ +from odoo import models, fields + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + pos_face_rec_server_url = fields.Char( + string="AI Face Recognition Server URL", + related='pos_config_id.pos_face_rec_server_url', + readonly=False, + help="URL of the AI Face Recognition Server (e.g., http://localhost:5000)" + ) diff --git a/models/res_partner.py b/models/res_partner.py new file mode 100644 index 0000000..34bf2b1 --- /dev/null +++ b/models/res_partner.py @@ -0,0 +1,74 @@ +from odoo import models, fields, api +import requests +import logging + +_logger = logging.getLogger(__name__) + +class ResPartner(models.Model): + _inherit = 'res.partner' + + image_face_1 = fields.Binary("Face Image 1", attachment=True) + image_face_2 = fields.Binary("Face Image 2", attachment=True) + image_face_3 = fields.Binary("Face Image 3", attachment=True) + + def _sync_face_images(self): + # Get the server URL from any POS config that has it configured + pos_config = self.env['pos.config'].search([('pos_face_rec_server_url', '!=', False)], limit=1) + if not pos_config or not pos_config.pos_face_rec_server_url: + _logger.warning("Face Recognition Server URL is not configured in any POS configuration") + return + + server_url = pos_config.pos_face_rec_server_url + + for partner in self: + # Only sync if at least one image is present + if not any([partner.image_face_1, partner.image_face_2, partner.image_face_3]): + continue + + images = [ + partner.image_face_1.decode('utf-8') if isinstance(partner.image_face_1, bytes) else partner.image_face_1, + partner.image_face_2.decode('utf-8') if isinstance(partner.image_face_2, bytes) else partner.image_face_2, + partner.image_face_3.decode('utf-8') if isinstance(partner.image_face_3, bytes) else partner.image_face_3 + ] + + payload = { + 'partner_id': partner.id, + 'name': partner.name, + 'images': images + } + + try: + # Remove trailing slash if present + base_url = server_url.rstrip('/') + requests.post(f"{base_url}/train", json=payload, timeout=5) + except Exception as e: + _logger.error(f"Failed to sync face images for partner {partner.id}: {e}") + + @api.model_create_multi + def create(self, vals_list): + partners = super().create(vals_list) + partners._sync_face_images() + return partners + + def write(self, vals): + res = super().write(vals) + if any(f in vals for f in ['image_face_1', 'image_face_2', 'image_face_3', 'name']): + self._sync_face_images() + return res + + def get_top_products(self): + self.ensure_one() + # Simple implementation: get top 3 products by quantity from past orders + query = """ + SELECT pt.name, sum(pol.qty) as qty + FROM pos_order_line pol + JOIN pos_order po ON pol.order_id = po.id + JOIN product_product pp ON pol.product_id = pp.id + JOIN product_template pt ON pp.product_tmpl_id = pt.id + WHERE po.partner_id = %s + GROUP BY pt.name + ORDER BY qty DESC + LIMIT 3 + """ + self.env.cr.execute(query, (self.id,)) + return [{'name': row[0], 'qty': row[1]} for row in self.env.cr.fetchall()] diff --git a/static/src/css/face_recognition.css b/static/src/css/face_recognition.css new file mode 100644 index 0000000..0ca1998 --- /dev/null +++ b/static/src/css/face_recognition.css @@ -0,0 +1,255 @@ +.face-recognition-sidebar { + position: absolute; + top: 65px; + right: 0; + bottom: 0; + width: 300px; + background: white; + border-left: 1px solid #ccc; + z-index: 100; + display: flex; + flex-direction: column; + box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1); +} + +.sidebar-header { + padding: 10px; + background: #f0f0f0; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #ccc; +} + +.sidebar-content { + flex: 1; + overflow-y: auto; + padding: 10px; +} + +.camera-container video { + background: #000; + border-radius: 4px; +} + +.match-list { + list-style: none; + padding: 0; +} + +.match-item { + padding: 8px; + border-bottom: 1px solid #eee; + cursor: pointer; +} + +.match-item:hover { + background: #f9f9f9; +} + +.match-info { + display: flex; + justify-content: space-between; +} + +.customer-details { + margin-top: 20px; + border-top: 2px solid #eee; + padding-top: 10px; +} + +.close-btn { + background: none; + border: none; + font-size: 1.2em; + cursor: pointer; +} + +.face-recognition-sidebar .control-button { + cursor: pointer; +} + +.face-recognition-sidebar.hidden { + display: none; +} + +/* Add padding to ProductScreen to avoid sidebar overlap */ +.pos .product-screen { + padding-right: 305px; +} +/* Order +Details Styling */ +.last-orders { + margin-top: 15px; +} + +.last-orders h5 { + margin-bottom: 10px; + color: #333; + font-size: 14px; + font-weight: 600; +} + +.orders-list { + display: flex; + flex-direction: column; + gap: 12px; +} + +.order-card { + background: #f8f9fa; + border: 1px solid #e0e0e0; + border-radius: 6px; + padding: 10px; + transition: box-shadow 0.2s; +} + +.order-card:hover { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.order-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 8px; + padding-bottom: 6px; + border-bottom: 1px solid #d0d0d0; +} + +.order-number { + font-weight: 600; + color: #2c3e50; + font-size: 13px; +} + +.order-date { + font-size: 11px; + color: #7f8c8d; +} + +.order-details { + margin-bottom: 8px; +} + +.order-row { + display: flex; + justify-content: space-between; + padding: 3px 0; + font-size: 12px; +} + +.order-row .label { + color: #666; + font-weight: 500; +} + +.order-row .value { + color: #333; + font-weight: 600; +} + +.order-row .value.status { + text-transform: capitalize; + padding: 2px 8px; + border-radius: 3px; + font-size: 11px; +} + +.order-row .value.status.paid { + background: #d4edda; + color: #155724; +} + +.order-row .value.status.done { + background: #d4edda; + color: #155724; +} + +.order-row .value.status.invoiced { + background: #cce5ff; + color: #004085; +} + +.order-products { + margin-top: 8px; + padding-top: 8px; + border-top: 1px dashed #d0d0d0; +} + +.products-label { + font-size: 11px; + color: #666; + font-weight: 600; + margin-bottom: 5px; +} + +.product-list { + list-style: none; + padding: 0; + margin: 0; +} + +.product-item { + display: flex; + align-items: center; + padding: 4px 0; + font-size: 11px; + gap: 6px; +} + +.product-qty { + background: #007bff; + color: white; + padding: 2px 6px; + border-radius: 3px; + font-weight: 600; + min-width: 30px; + text-align: center; +} + +.product-name { + flex: 1; + color: #333; +} + +.product-price { + color: #28a745; + font-weight: 600; +} + +.no-orders { + color: #999; + font-style: italic; + font-size: 12px; + text-align: center; + padding: 20px 0; +} + +/* Top Products Styling */ +.top-products { + margin-top: 15px; + padding-top: 15px; + border-top: 2px solid #e0e0e0; +} + +.top-products h5 { + margin-bottom: 10px; + color: #333; + font-size: 14px; + font-weight: 600; +} + +.top-products ul { + list-style: none; + padding: 0; +} + +.top-products li { + padding: 6px 8px; + background: #fff3cd; + border-left: 3px solid #ffc107; + margin-bottom: 6px; + font-size: 12px; + border-radius: 3px; +} diff --git a/static/src/js/face_recognition_sidebar.js b/static/src/js/face_recognition_sidebar.js new file mode 100644 index 0000000..46061aa --- /dev/null +++ b/static/src/js/face_recognition_sidebar.js @@ -0,0 +1,184 @@ +/** @odoo-module */ + +import { Component, useState, onMounted, onWillUnmount } from "@odoo/owl"; +import { ProductScreen } from "@point_of_sale/app/screens/product_screen/product_screen"; +import { useService } from "@web/core/utils/hooks"; +import { registry } from "@web/core/registry"; + +export class FaceRecognitionSidebar extends Component { + static template = "pos_face_recognition.FaceRecognitionSidebar"; + + setup() { + this.pos = useService("pos"); + this.orm = useService("orm"); + console.log("FaceRecognitionSidebar setup"); + this.state = useState({ + matches: [], + selectedCustomer: null, + lastOrders: [], + topProducts: [], + }); + this.recognitionInterval = null; + this.stream = null; + + onMounted(() => { + this.startCamera(); + }); + + // Cleanup interval and camera when component is destroyed + onWillUnmount(() => { + if (this.recognitionInterval) { + clearInterval(this.recognitionInterval); + } + if (this.stream) { + this.stream.getTracks().forEach(track => track.stop()); + } + }); + } + + async startCamera() { + console.log("startCamera called"); + try { + const video = document.getElementById('face-rec-video'); + console.log("Video element found:", video); + if (video) { + this.stream = await navigator.mediaDevices.getUserMedia({ video: true }); + console.log("Camera stream obtained:", this.stream); + video.srcObject = this.stream; + + // Start real-time recognition loop once camera is ready + this.startRealTimeRecognition(); + } else { + console.error("Video element not found!"); + } + } catch (err) { + console.error("Error accessing camera:", err); + } + } + + startRealTimeRecognition() { + console.log("startRealTimeRecognition called"); + console.log("Server URL:", this.pos.config.pos_face_rec_server_url); + + if (!this.pos.config.pos_face_rec_server_url) { + console.error("Face Recognition Server URL is not configured. Please configure it in POS Settings."); + return; + } + + // Capture frame every 5 seconds + this.recognitionInterval = setInterval(() => { + console.log("Recognition interval tick"); + this.captureAndSendFrame(); + }, 5000); + } + + async captureAndSendFrame() { + const video = document.getElementById('face-rec-video'); + if (!video) { + console.error("Video element not found"); + return; + } + + if (!this.pos.config.pos_face_rec_server_url) { + console.error("Face Recognition Server URL is not configured"); + return; + } + + const canvas = document.createElement('canvas'); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + canvas.getContext('2d').drawImage(video, 0, 0); + // Convert to base64, remove header + const imageData = canvas.toDataURL('image/jpeg').split(',')[1]; + + try { + const response = await fetch(this.pos.config.pos_face_rec_server_url + '/recognize', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ image: imageData }), + }); + + if (response.ok) { + const result = await response.json(); + if (result.matches && result.matches.length > 0) { + // Enrich matches with partner phone numbers + this.state.matches = result.matches.map(match => { + const partner = this.pos.db.get_partner_by_id(match.id); + return { + ...match, + phone: partner ? partner.phone || partner.mobile : null + }; + }); + } + } + } catch (err) { + console.error("Error sending frame to AI server:", err); + } + } + + async selectCustomer(match) { + const partner = this.pos.db.get_partner_by_id(match.id); + if (partner) { + this.state.selectedCustomer = partner; + this.pos.get_order().set_partner(partner); + + // Fetch details + await this.fetchCustomerDetails(partner.id); + } + } + + async fetchCustomerDetails(partnerId) { + // Fetch last 2 orders with detailed information + const orders = await this.orm.searchRead("pos.order", + [['partner_id', '=', partnerId]], + ['name', 'date_order', 'amount_total', 'state', 'lines'], + { limit: 2, order: "date_order desc" } + ); + + // Fetch order lines for each order + for (let order of orders) { + if (order.lines && order.lines.length > 0) { + const lines = await this.orm.searchRead("pos.order.line", + [['id', 'in', order.lines]], + ['product_id', 'qty', 'price_subtotal_incl', 'full_product_name'], + {} + ); + // Add product names to lines + order.lines = lines.map(line => ({ + ...line, + product_name: line.full_product_name || (line.product_id && line.product_id[1]) || 'Unknown Product' + })); + } else { + order.lines = []; + } + } + + this.state.lastOrders = orders; + + // Fetch top 3 products + try { + const topProducts = await this.orm.call("res.partner", "get_top_products", [partnerId]); + console.log("Top products received:", topProducts); + console.log("Type:", typeof topProducts); + console.log("First product:", topProducts && topProducts[0]); + + // Ensure it's an array + if (Array.isArray(topProducts)) { + this.state.topProducts = topProducts; + } else { + console.error("topProducts is not an array:", topProducts); + this.state.topProducts = []; + } + } catch (error) { + console.error("Error fetching top products:", error); + this.state.topProducts = []; + } + } +} + +ProductScreen.components = { + ...ProductScreen.components, + FaceRecognitionSidebar, +}; diff --git a/static/src/js/models.js b/static/src/js/models.js new file mode 100644 index 0000000..f985632 --- /dev/null +++ b/static/src/js/models.js @@ -0,0 +1,20 @@ +/** @odoo-module */ + +import { PosStore } from "@point_of_sale/app/store/pos_store"; +import { patch } from "@web/core/utils/patch"; + +patch(PosStore.prototype, { + async _processData(loadedData) { + await super._processData(...arguments); + // We don't necessarily need to load the full image data for all partners on load + // because it would be heavy. We only need to send it back when saving. + // However, if we want to show existing images in the edit screen, we might need them. + // But standard Odoo doesn't load full images for partners in POS to save bandwidth. + // It usually loads small avatars. + // For now, let's NOT load them by default to avoid performance issues. + // The edit screen will show empty if not modified in current session, + // or we could fetch them on demand (like `partnerImageUrl` does). + // BUT, `saveChanges` in `partner_editor.js` sends `processedChanges`. + // If we want to support editing, we need to handle the fields. + } +}); diff --git a/static/src/js/partner_details_edit.js b/static/src/js/partner_details_edit.js new file mode 100644 index 0000000..e0874e7 --- /dev/null +++ b/static/src/js/partner_details_edit.js @@ -0,0 +1,107 @@ +/** @odoo-module */ + +import { PartnerDetailsEdit } from "@point_of_sale/app/screens/partner_list/partner_editor/partner_editor"; +import { patch } from "@web/core/utils/patch"; +import { getDataURLFromFile } from "@web/core/utils/urls"; +import { ErrorPopup } from "@point_of_sale/app/errors/popups/error_popup"; +import { _t } from "@web/core/l10n/translation"; +import { loadImage } from "@point_of_sale/utils"; +import { useRef, useState, onWillUnmount } from "@odoo/owl"; + +patch(PartnerDetailsEdit.prototype, { + setup() { + super.setup(...arguments); + this.changes.image_face_1 = this.changes.image_face_1 || false; + this.changes.image_face_2 = this.changes.image_face_2 || false; + this.changes.image_face_3 = this.changes.image_face_3 || false; + + this.camera = useState({ + activeField: null, + }); + this.videoRef = useRef("video"); + + onWillUnmount(() => { + this.stopCamera(); + }); + }, + + async startCamera(fieldName) { + if (this.camera.activeField) { + this.stopCamera(); + } + try { + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + this.camera.activeField = fieldName; + this.stream = stream; + // Wait for the video element to be rendered + await Promise.resolve(); + // We might need a small delay or rely on the ref being attached on render + // Since we set state, a render will happen. The ref should be available after render. + // However, in Owl, refs are usually available after patch. + // Let's try setting it in a next tick or just relying on the template to use the ref. + // Actually, we need to set srcObject. + setTimeout(() => { + if (this.videoRef.el) { + this.videoRef.el.srcObject = stream; + } + }, 100); + } catch (err) { + console.error("Camera error", err); + this.popup.add(ErrorPopup, { title: _t("Camera Error"), body: _t("Could not access camera.") }); + } + }, + + stopCamera() { + if (this.stream) { + this.stream.getTracks().forEach(track => track.stop()); + this.stream = null; + } + this.camera.activeField = null; + }, + + capturePhoto() { + if (!this.videoRef.el) return; + const video = this.videoRef.el; + const canvas = document.createElement("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const ctx = canvas.getContext("2d"); + ctx.drawImage(video, 0, 0); + + const dataUrl = canvas.toDataURL('image/jpeg'); + // Remove data:image/jpeg;base64, prefix + this.changes[this.camera.activeField] = dataUrl.split(',')[1]; + this.stopCamera(); + }, + + async uploadFaceImage(event, fieldName) { + const file = event.target.files[0]; + if (!file) return; + + if (!file.type.match(/image.*/)) { + await this.popup.add(ErrorPopup, { + title: _t("Unsupported File Format"), + body: _t("Only web-compatible Image formats such as .png or .jpeg are supported."), + }); + return; + } + + const imageUrl = await getDataURLFromFile(file); + const loadedImage = await loadImage(imageUrl, { + onError: () => { + this.popup.add(ErrorPopup, { + title: _t("Loading Image Error"), + body: _t("Encountered error when loading image. Please try again."), + }); + } + }); + + if (loadedImage) { + // Resize to reasonable size for face recognition (e.g. 800x600 is usually enough) + const resizedImage = await this._resizeImage(loadedImage, 800, 600); + const dataUrl = resizedImage.toDataURL(); + // Remove data:image/png;base64, prefix + this.changes[fieldName] = dataUrl.split(',')[1]; + } + } +}); diff --git a/static/src/xml/face_recognition_screens.xml b/static/src/xml/face_recognition_screens.xml new file mode 100644 index 0000000..f511724 --- /dev/null +++ b/static/src/xml/face_recognition_screens.xml @@ -0,0 +1,104 @@ + + + + +

+ + + +
+ + +
+
+ + + + + + + + diff --git a/static/src/xml/partner_details_edit.xml b/static/src/xml/partner_details_edit.xml new file mode 100644 index 0000000..7bca71d --- /dev/null +++ b/static/src/xml/partner_details_edit.xml @@ -0,0 +1,79 @@ + + + + +
+ +
+ +
+
+
+ +
+ + + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ + + + +
+
+
+
+
+ +
+ +
+
+
+ +
+ + + + +
+
+
+
+
+
+
diff --git a/views/pos_config_views.xml b/views/pos_config_views.xml new file mode 100644 index 0000000..c3ee4ed --- /dev/null +++ b/views/pos_config_views.xml @@ -0,0 +1,15 @@ + + + + pos.config.view.form.inherit.face.recognition + pos.config + + + + + + + + + + diff --git a/views/res_config_settings_views.xml b/views/res_config_settings_views.xml new file mode 100644 index 0000000..8419d30 --- /dev/null +++ b/views/res_config_settings_views.xml @@ -0,0 +1,15 @@ + + + + res.config.settings.view.form.inherit.pos.face.recognition + res.config.settings + + + + + + + + + + diff --git a/views/res_partner_views.xml b/views/res_partner_views.xml new file mode 100644 index 0000000..833f44a --- /dev/null +++ b/views/res_partner_views.xml @@ -0,0 +1,21 @@ + + + + res.partner.form.face.recognition + res.partner + + + + + + + + + + + + + + + +