From 4e7f434e9004d4336385e991dd1d16d6556e173b Mon Sep 17 00:00:00 2001 From: Yasir Karam Date: Mon, 2 Sep 2024 03:58:52 +0300 Subject: [PATCH 001/127] Refactored Birthday-Manager.py --- Automating Emails/Birthday-Manager.py | 152 +++++++++++++++++--------- 1 file changed, 102 insertions(+), 50 deletions(-) diff --git a/Automating Emails/Birthday-Manager.py b/Automating Emails/Birthday-Manager.py index 899ecf3c..40e8df30 100644 --- a/Automating Emails/Birthday-Manager.py +++ b/Automating Emails/Birthday-Manager.py @@ -1,56 +1,108 @@ +import ssl +import smtplib import csv -import smtplib, ssl +from abc import ABC, abstractmethod + + +class EmailSender(ABC): + @abstractmethod + def send_email(self, recipient, message): + pass + + +class GmailEmailSender(EmailSender): + def __init__(self, sender_address, sender_password): + self.sender_address = sender_address + self.sender_password = sender_password + + def send_email(self, recipient, message): + context = ssl.create_default_context() + with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server: + server.login(self.sender_address, self.sender_password) + server.sendmail(self.sender_address, recipient, message) + + +class BirthdayMessage: + @staticmethod + def create_message(fname): + return f"""Hi {fname}, -message = """Hi {fname}, I wish you a very Happy Birthday. + I hope you had a great day.""" -sender_address = "you@example.com" -sender_password = "examplePassword" - -context = ssl.create_default_context() -with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server: - server.login(sender_address, sender_password) - - with open(r"birthday.csv") as birthdays: - reader = csv.reader(birthdays) - next(reader) - for fname, lname, email, dob in reader: - server.sendmail( - sender_address, - email, - message.format(fname=fname), - ) - -choice = input( - """Do you wish to add or remove names from the csv file? - if you would like to add names type add - otherwise if you would like to remove names type remove - When you are finished, type exit - """ -) - -if choice == "add": - new_data = input("Enter data as first name,lastname,email,date of birth: ") - new_data = new_data.split(",") - with open(r"birthday.csv", "r ") as file: - writer_object = csv.writer(file) - next(file) - writer_object.writerow(new_data) -elif choice == "remove": - lines = [] - removal = input("Enter the first name of the person to be removed: ") - with open(r"birthday.csv", "r") as file: - reader = csv.reader(file) - - for row in reader: - lines.append(row) - - for fields in row: - if fields == removal: - lines.remove(row) - - with open(r"birthday.csv", "w", newline="") as file: - writer = csv.writer(file) - writer.writerows(lines) +class BirthdayListManager: + def __init__(self, filename): + self.filename = filename + + def load_birthdays(self): + with open(self.filename) as file: + reader = csv.reader(file) + next(reader) # Skip header + return list(reader) + + def add_birthday(self, new_data): + with open(self.filename, "a", newline="") as file: + writer = csv.writer(file) + writer.writerow(new_data) + + def remove_birthday(self, first_name): + updated_lines = [] + with open(self.filename, "r") as file: + reader = csv.reader(file) + for row in reader: + if row and row[0] != first_name: + updated_lines.append(row) + + with open(self.filename, "w", newline="") as file: + writer = csv.writer(file) + writer.writerows(updated_lines) + + +class BirthdayNotifier: + def __init__(self, email_sender, birthday_list_manager): + self.email_sender = email_sender + self.birthday_list_manager = birthday_list_manager + + def notify_birthdays(self): + birthdays = self.birthday_list_manager.load_birthdays() + for fname, lname, email, dob in birthdays: + message = BirthdayMessage.create_message(fname) + self.email_sender.send_email(email, message) + + +def main(): + sender_address = "you@example.com" + sender_password = "examplePassword" + birthday_file = "birthday.csv" + + email_sender = GmailEmailSender(sender_address, sender_password) + birthday_list_manager = BirthdayListManager(birthday_file) + notifier = BirthdayNotifier(email_sender, birthday_list_manager) + + notifier.notify_birthdays() + + while True: + choice = input( + """Do you wish to add or remove names from the csv file? + If you would like to add names type 'add' + Otherwise if you would like to remove names type 'remove' + When you are finished, type 'exit': """ + ).strip().lower() + + if choice == "exit": + break + elif choice == "add": + new_data = input("Enter data as first name,lastname,email,date of birth: ") + new_data = new_data.split(",") + birthday_list_manager.add_birthday(new_data) + elif choice == "remove": + removal = input("Enter the first name of the person to be removed: ") + birthday_list_manager.remove_birthday(removal) + else: + print("Invalid choice. Please try again.") + + +if __name__ == "__main__": + main() From 5c4546867a27b8632e55f59620f27bd66b2fb2cc Mon Sep 17 00:00:00 2001 From: shailesh-vaidya Date: Thu, 12 Sep 2024 01:29:54 +0530 Subject: [PATCH 002/127] Added support to download audio output only Signed-off-by: shailesh-vaidya --- Youtube Downloader/youtubeDownloader.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Youtube Downloader/youtubeDownloader.py b/Youtube Downloader/youtubeDownloader.py index 31c667ab..fa188d0f 100644 --- a/Youtube Downloader/youtubeDownloader.py +++ b/Youtube Downloader/youtubeDownloader.py @@ -5,10 +5,10 @@ def my_hook(d): print(f"Done downloading, now post-processing ... File saved as: {d['filename']}") ydl_opts = { - 'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', 'ffmpeg_location': r'Youtube Downloader\bin', 'progress_hooks': [my_hook], 'outtmpl': '%(title)s.%(ext)s', + 'restrictfilenames': 'True', } @@ -25,9 +25,14 @@ def downloader(): else: URLS.append(input('Enter Video URL: ')) + question = input("Do you want audio output only (Y/n): ").lower() + if question == 'y': + ydl_opts['format'] = 'bestaudio[ext=m4a]/best,' + else: + ydl_opts['format'] = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best,' + with yt_dlp.YoutubeDL(ydl_opts) as ydl: ydl.download(URLS) - - + if __name__ == "__main__": downloader() \ No newline at end of file From 733d44a099c29e9fbb9b9ab7af140d91386c8cb2 Mon Sep 17 00:00:00 2001 From: Carlonii Date: Tue, 1 Oct 2024 13:57:24 -0300 Subject: [PATCH 003/127] Add a option to transform pdfs into text --- PDF to text/Atividade 28 Fev.pdf | Bin 0 -> 28649 bytes PDF to text/README.md | 28 +++++++++++ PDF to text/script.py | 77 +++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 PDF to text/Atividade 28 Fev.pdf create mode 100644 PDF to text/README.md create mode 100644 PDF to text/script.py diff --git a/PDF to text/Atividade 28 Fev.pdf b/PDF to text/Atividade 28 Fev.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8109af3ddd9bc1e562a88fc9d960065e30354d17 GIT binary patch literal 28649 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 literal 0 HcmV?d00001 diff --git a/PDF to text/README.md b/PDF to text/README.md new file mode 100644 index 00000000..16e8206a --- /dev/null +++ b/PDF to text/README.md @@ -0,0 +1,28 @@ +# PDF to Text Converter + +Este projeto é uma ferramenta em Python para converter arquivos PDF em texto limpo e legível. Ele foi projetado para extrair texto de PDFs locais e remotos, realizar o pós-processamento do texto extraído para melhorar a legibilidade e salvar o conteúdo formatado em arquivos `.txt`. O projeto também inclui funcionalidades de download de PDFs a partir de URLs e limpeza de texto para evitar problemas com quebras de linha e espaçamento desorganizado. + +--- + +## Funcionalidades +1. **Extração de Texto de PDFs Locais e Remotos**: + - Suporte para arquivos PDF armazenados localmente e para PDFs disponibilizados via URL. +2. **Limpeza e Formatação do Texto**: + - Remoção de quebras de linha indesejadas e espaçamento excessivo. + - Manutenção de parágrafos e estrutura original. +3. **Salvamento do Texto em Arquivos `.txt`**: + - O texto extraído pode ser salvo em um arquivo `.txt` com o mesmo nome do PDF original. +4. **Criação Automática de Pastas de Saída**: + - Organiza os textos gerados em uma pasta de saída (`output_texts`) para fácil navegação e uso futuro. + +## Requisitos + +Certifique-se de ter as seguintes bibliotecas instaladas: + +- `requests` +- `PyPDF2` + +Se ainda não as tiver, instale usando: + +```bash +pip install requests PyPDF2 diff --git a/PDF to text/script.py b/PDF to text/script.py new file mode 100644 index 00000000..9d55aa8e --- /dev/null +++ b/PDF to text/script.py @@ -0,0 +1,77 @@ +import os +import re +import requests +import PyPDF2 + +def download_pdf(url, local_filename): + """Download PDF from a URL to a local file.""" + response = requests.get(url) + with open(local_filename, 'wb') as f: + f.write(response.content) + +def extract_text_from_pdf(pdf_path): + """Extract text from a single PDF file.""" + try: + with open(pdf_path, 'rb') as file: + reader = PyPDF2.PdfReader(file) + text = "" + for page in reader.pages: + text += page.extract_text() or "" + # Apply text cleaning after extraction + return clean_extracted_text(text) + except Exception as e: + print(f"Failed to read {pdf_path}: {e}") + return None + +def clean_extracted_text(text): + """Clean and format the extracted text.""" + # Remove line breaks in the middle of sentences + cleaned_text = re.sub(r'(? Date: Tue, 1 Oct 2024 14:00:47 -0300 Subject: [PATCH 004/127] changes to readme --- PDF to text/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/PDF to text/README.md b/PDF to text/README.md index 16e8206a..3e84bb24 100644 --- a/PDF to text/README.md +++ b/PDF to text/README.md @@ -1,28 +1,28 @@ # PDF to Text Converter -Este projeto é uma ferramenta em Python para converter arquivos PDF em texto limpo e legível. Ele foi projetado para extrair texto de PDFs locais e remotos, realizar o pós-processamento do texto extraído para melhorar a legibilidade e salvar o conteúdo formatado em arquivos `.txt`. O projeto também inclui funcionalidades de download de PDFs a partir de URLs e limpeza de texto para evitar problemas com quebras de linha e espaçamento desorganizado. +This project is a Python tool designed to convert PDF files into clean and readable text. It is built to extract text from both local and remote PDFs, perform post-processing to improve readability, and save the formatted content into `.txt` files. The project also includes features for downloading PDFs from URLs and cleaning up the extracted text to prevent issues with line breaks and disorganized spacing. --- -## Funcionalidades -1. **Extração de Texto de PDFs Locais e Remotos**: - - Suporte para arquivos PDF armazenados localmente e para PDFs disponibilizados via URL. -2. **Limpeza e Formatação do Texto**: - - Remoção de quebras de linha indesejadas e espaçamento excessivo. - - Manutenção de parágrafos e estrutura original. -3. **Salvamento do Texto em Arquivos `.txt`**: - - O texto extraído pode ser salvo em um arquivo `.txt` com o mesmo nome do PDF original. -4. **Criação Automática de Pastas de Saída**: - - Organiza os textos gerados em uma pasta de saída (`output_texts`) para fácil navegação e uso futuro. +## Features +1. **Text Extraction from Local and Remote PDFs**: + - Supports PDF files stored locally and PDFs available via URL. +2. **Text Cleaning and Formatting**: + - Removes unwanted line breaks and excessive spacing. + - Preserves paragraphs and maintains the original structure. +3. **Saving Extracted Text as `.txt` Files**: + - The extracted text can be saved as a `.txt` file with the same name as the original PDF. +4. **Automatic Output Folder Creation**: + - Organizes generated text files into an `output_texts` folder for easy navigation and future use. -## Requisitos +## Requirements -Certifique-se de ter as seguintes bibliotecas instaladas: +Make sure to have the following libraries installed: - `requests` - `PyPDF2` -Se ainda não as tiver, instale usando: +If you do not have them yet, install them using: ```bash pip install requests PyPDF2 From a93f0b4e49a2352bab15d4551ebfaa06003f3481 Mon Sep 17 00:00:00 2001 From: shashank-amireddy Date: Wed, 2 Oct 2024 15:05:36 +0530 Subject: [PATCH 005/127] QR Code Customization Feature Added --- README.md | 2 +- qr_with_logo/README.md | 20 +++++++++++++ qr_with_logo/github-logo.png | Bin 0 -> 173518 bytes qr_with_logo/qr.py | 53 ++++++++++++++++++++++++++++++++++ qr_with_logo/qr_with_logo.png | Bin 0 -> 14818 bytes 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 qr_with_logo/README.md create mode 100644 qr_with_logo/github-logo.png create mode 100644 qr_with_logo/qr.py create mode 100644 qr_with_logo/qr_with_logo.png diff --git a/README.md b/README.md index 3889ae25..a924eec8 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ More information on contributing and the general code of conduct for discussion | Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | the pigeonhole sort algorithm to sort your arrays efficiently! | Youtube Playlist Info Scraper | [Youtube Playlist Info Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Playlist%20Info%20Scraper) | This python module retrieve information about a YouTube playlist in json format using playlist link. - +| QR Code with logo | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/qr_with_logo) | QR Code Customization Feature ## Gitpod Use the cloud-free development environment where you can directly start coding. diff --git a/qr_with_logo/README.md b/qr_with_logo/README.md new file mode 100644 index 00000000..aa90998e --- /dev/null +++ b/qr_with_logo/README.md @@ -0,0 +1,20 @@ +# QR Code Generator with Logo + +## Description +This Python script generates a QR code with a specified URL and overlays a logo onto it. It utilizes the `qrcode` library to generate the QR code and the `PIL` library for image processing to overlay the logo. + +## Prerequisites +- `qrcode` library: You can install it via pip with the command `pip install qrcode`. +- `PIL` library: You can install it via pip with the command `pip install pillow`. + +## How to Run the Script +1. Ensure you have installed the required libraries mentioned above. +2. Replace the `logo_path` and `url` variables with your desired logo path and target URL, respectively. +3. Run the script. +4. The script will generate a QR code image named `qr_with_logo.png` in the current directory. + +## Sample Use +![QR Code with Logo](qr_with_logo.png) + +## Author +Shashank Reddy (GitHub: shashank-amireddy) diff --git a/qr_with_logo/github-logo.png b/qr_with_logo/github-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..f629d90a95f8462271327d23ca2a729c0a36aecf GIT binary patch literal 173518 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�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�>#l)w@j&VK53qON_bchVP0Y9zBZre={<6)YzDTm6#U?rkatK z+xQ(wpbM&IwNBeKkxzZW+#F>i?T^6uG`+2%bg~Pb5R(&urQ!=*;OHD0%A_u=m-ZIl znMdDF6+UAMPxNX#PBi$l@rA>YX+`H*$q-Z#IcVzX_M<+MwyEFO`4e()Cb?>TJz5Yn zdHNJ>oQXaJEgd0ea*p9IwZ%7%=EMQ!ZRhdsV(8(@k~L1I46s08fv~DSoomo7zI|qk zfefadcwr|SeY&xq)=(q043q*#Q4Z8e7@O~tn289S&v+Fv@XtLd=!P4y-GCTnx%zqIC z5fp12YNR+x>AC;i|JuB=0^qT{K8NWnzl(1!o@AQXaLa8usfCz@eeq=dJooF8h@7Nk zn)va&m{rL}bECNb1t3gYP(q1=suQ~|41M{Z7KHN>!GL?|(j}nT|A(xrj;d<=x|b_R zN~xrTqN22t(ux8~mmnP?(%pFtPy_>MC8Uuw=(>u6h_rO0bW8WQ4!-xie!qVlj5o&P zu+Q0h?X~8bb1rSts`Zn<@BLj8@bA}+V1$W5efs_i4uES<%dUgUk$j&x; zZMWxGC4uzyTalGpo6f=^^&v!b+=%ih@!A#o~UyagtyRWWs14ZY)Nc0!^$&YlM2DM1Ms9R$5<~QN-4*Sy>?TkX!hlr{B%TYKoAoMp zzdr+t>QFegpmQ)ofj6NVjXkRh44D6pMnC`+8a9x+Y0~RRKa0zTmre}1VVK!ssE?(_}q}b6sb#r0I9Sc`yHNMBe02A7f;=lF`pvu)D z@Xd8M`#T?hPbPxg=elw0Pv4d9aicSml9F(AnJMvlTUl}-Kd-jEK|z>u;K~7x=FZM^ zCE;!z`|?dE=`B_0h`glzk02Bpgc5tAa0Pb@5$Pd&lb>JXQRVIl8-8jsJp5g@e-lTJ z>`7ZaFRv=FHCmjD1}JO>p4Zgkm%A0XduT}G<~n|_m-}!<3cHx z2Sl1DSR9SgGBoX7y?>f~X!RRH9^P)2ajjSCEQ!0bLB*$R3`Eq)kata5qJt>DxgM&& zp#5#y1t`C1p0tBdZrq=$@iJ7M#QGkKsil*Vy%Awy$KJ;aI4NV_W-Gww4$iWfv>E@Z zepUyOk8Rd}{~_SsIQqfrDpX_+^4KB?soCXs;qi^!0mn|HlHtB8I@TfR$o|G91zEYN zsHBJTw2iVZIOkorvLc~F?%MWB0&GK}KtFan_eoz%%PW2rDW!K!Qce4pY%KNwg?P$y z6)^*#LZw|{=f(Zyz-pH^@~`5kuSaO73;U>{^a8$J<%(OJ)Rrm8L=Nr;jQkY6Y|y}Y zM!J-nX`MYHfWe_yB(9_Y{ZoW(VW|4a6g12^?h*v>Cu;u18DYbRM%nw_&FSfiB17R5 zyvL~=%CP-wyGrQ^p5*R)e9QNZ72F|Sj8a_dc(xxeY;A3UUT_|?lDxTY#vb^JM?7G_ ziA&%2!x7Iu2*daDy9s*sKc9RLAMk=u;Q{$Q4_k~sfe0xc{v8hN7VX7Ra%mXsH;5j( zS|@r2)qa*9m_HrY`<;HQh>qP}6~;?T6GuNL-QFn~cm34juYOB5@JGQ}5Iy3Y?0Z@J zbvScXgrVPXw?n8rK&R`xICs70-p6mWfji;QsN8*NW6i=(=-@sD{*C?qP2x-*LoEG= zJ}eW_omu#5oi`nDms|~seaz&;zrr@rIy<7NiF50@*d)FY{qG7E#-s*12DX?Iv$+PU zh&akM8o0JRk%M=%_pRT&rqUF?3aCSGEV1}setvrAID|&PtsfJWLo(arJih~z7e?hJ zf^kD1w5Ew%)|MwI4zo`@3z`!?&O=Y-P=S?W@y|A3S5$Wsnm3AGH_f-%(#pzsKf-;r zELtR>mtR;=FlXm$ACK7l&)=62o*#z6z3%U;hn&d8-Q60bZY>f^a}J3Nr=U1#MjQF> zg!+~BD}x}4+=X+BP%A_C5?zJm9r+AnezVoi$&{o8t^_BzFQ>QZAGYc z%~lWor7|&B88b*`7JMO@k^N0OIimB{B~z$(%6%IxxX?pIkF$yJw`nJ4W?B=TNa%JN zN_6g>cnJ@`cz7Xqf zgo&<6fnGSk`9Eg|@W>ih&4iEgXFr+nHvd5{s8??g!){ZzRm!P}%*!hmr$Nb9GIROb z9*wxp6J|4TQD}jrLs(#9npd)Yb6SfbI{ph$u^x=fRQ_x}y-51KpZ7o-F4e;o4N`N& z(4y41L$R}=5es*%>R@w5Qkc^~72o1WPJ<2iYCrmRNeYRXg@fY)Xm!K1a;^X60&s7R zkw!dW9N$lQ6yc-@jfR}P?q?VubKogd=6@nA<$?^jZuri=*aN?%QWgtmkf!15C8ic= zm6+B1+P#uL95<~!s)zD886l$m{MrX<2$sJ=P5nyam^MPZbO;Gs;o*@vP<^IfQz!iE zmlJs-Y-j_=?$4s5KMy1AF)C^4soV3aw+vtXTG~J*zsd`;8bo6`GnG&P#Fg$FZSdaprSmb4rHV+PwBF zB%@w_YenL*t~y_94f z<@6=@!vuq#Ql&krE1C0S_bciQ5byRgJOPQb%u!4wVDu!InQhb0wY7-6=ZKcb-^D(k z90C;O@p@bpv#H8KFu{O&0#j;rNH4b;jPZ;YJ}+^jVy()rDJckgkR-7IgZAx;kgB~( z9yBleA7Ovuyad)E4oqO6tnX%vchAiqq5Dvr@mo|ApTNe{RW1}+r5{+NTUlmnIjJXo z(4b_(TO+ZlY`53a)6RnlSpOf~FTR#oS$R>RN-v|em0G)@A)hFk3qg<1nUN?me`xQ9 zztCsH+RD1Uy(6QzOXO}kt0;QzXqQPRv2LMD%*e?4V7|8zfg;Z93@F1dj(by5>7 zMQfxhb#7b4tEr!8T6EY@z%1er*&OZz%f(vi+ZQzUXw-}2Z1V8SuHL_YpGx3anXCzX z$CcezX|i{buW;wGdl~k|_{((fxvdufneMlYe*ay3`gnR_f_--{ki(fI;)P@rPP&q< z(#mg*&O#RY9C0SpSaUj{0)m~IgUIV?);)BNlDfPL<>YaxE$w1RYa3-9n zal+8p!9i86rR7(yKJ$LB=Gn=oPs1{2X1HijfrgsMKO#mp$fpobVq=}`=$-%WIoPv#Qmr!hT0u=tKk=iBKQ^clrA-f}GUF)pasohP)+5*l6Ct{43y@tOQ9TVOlyO zr=N0XFiGRlpzuB&a+&-M8ebhD?!y$ONun{7IM>-eYwV+Dz>A&0$@|A?{tadT^dZbH zx36`jKa;xg=C2%pELAyxAiz2DRR+AyBU9un*_k<7Msit6Ny*1v%hSU~Nt3oW%2RK3 z4o_(EUA{A^%!~U{i9)6I^vZb3ets-aKtZ_y_DWi%8SnAI=(m&qZ+Vfh>zU+$JF}DYtW9IVsC$6xHO5QNj zLD6|%fS}+#nF0fs3xqp4k01Z=&o2Xim+-ha?)s7IhI4+W_$2;aExgxfyv==m+35*h z`u<&Jravj_?-5;oiefPo*fNFlyuJxIb7tx=A;KIHCupH^D3VsYks5fA@F)}0EQ0*t zY;w#4+S@iZ-?!$=Gjj_2&W~7_OXHuo$|`#NiWy0cGJb>kf0sH`7U8I178mxMn$2J5^kvpN_z>zfvBId3ilpmmmgdPfE$GEC zkM4H1w@(IXaYn>7j5;sY2ecfb71>m&odmt&nRCyoP>guMnpJauqO;ISkbL;iuv`c*k{Z@f|_lC7qiru zkRvu%`oh9<;m$un14BfWf9eL+c~Ub-sh%S;^{L6Z>l!;0%8{wCSMha>9gI~MGwC_L zSm03_Pf17Q!8KJLMslDXQ;Ip9k(JlER!@_a;h;Das|slzn#18oLy^_$l_-u-3s3y- zF(ZFM3S%93L$oB_S&55X0~j>7Xi)X1wD2?V%nzIa_vDNwsf~1@9*4WXLkqt8P{rC_ zro`&Y>=~~3Q7U;0E8G@=^lgGtMAab)st)%i(tj5M%t}r5MaI$5vBwkQbIzzr1bp7b8I@N}Q#C@2`puKw?Oh zzrU|iY>$XCn!0(z3Ib37!S&qb31LS2#w{8=H*$SX>o-smy-_U`I;4M?gYepZmQk^t zK&t(#Q07b4ZqBp+D(! z&s0$_2YV0&&*SerT#t*E3&83-;Ti)A4Tk942}~L=?)H{7V);ypsN!lrz{fR2t1Z?s zXsEK*zx~KbXZa_TAU_4+>+0$*7j4b8T=eg2dKDag5rr`(^4a}N+ha1`9}ySF6ymn* zU^v9TU$^+&>+|dj(6+I&Yx(g+Jfnhro_^o82ZJTPIZn$dDX9#UUySu7bDV$$h0r~8 zWf|S}kM^j7*}~p?d;~dE(#9$1dH;o1rSH#R5?apHDrw2e$~rK%HPGYL`weh# zaQmyjC3i|Yp#^SmuxaXfN>tP1oSgW2TjBmbMuV8ixK55bhlBIg{%whyxxbZn zMcldV=OSQ9_fa{()~m~a8jX8b2i)B!&pOpNtV}61iRnbB!z##d`xqZ?%Td%4%mn=l zu>b%;_xlF^hg<#o1}1umwMg*I1)MT*W@ZK}`06j(5G&;gVENlIxiqu5cG?!*JA-En zgl;1YqkW~;JKj=FOUu3jtWmXUyagaFpHq(t_qHyp9(+~gj|)giaR4)Yo3ri){E2AH zW}xiRh!71!LqlL}{pGkvNt7+^?H$x8u|?Jp>#1zasKx{@nYMVWl+mU8C}J-*;$cg2 z&=4DDx5$mkeVh93z~EzY<^7!HOEpEClCb`?i{%vT=%@d%_j&70eQ9rcffL)G4+HT8 z4yNmxLD5w6Sq*gG!(V{vzQ^9DHG2KRuEgN%**fK@G($>!u1PBZ3V%`e7V?r^lF}97 zLabuoTxM>~SM&~l4VQuAO#1Ukh?c&7c2ZK(o&H!q+{lkuMlmqHSl)Z%K8R7%^4zPH z60UF$zADf9(BK1)DW01Co3h}FHN(!z)wx{PS%WC8H%S@!NnPHwq*kYIUOITZV(r_G zgz(&)io2S6THmkuz4##SrnM#CxEs&El{hy}la5>e`pI3b8}wnnm6D#Y!Y(1YbuKk6 z<({8|ELmBA37t0G{T~XA!b(4S^0kw}U|I+q$eT-(nNQZVqlg=B3e(c_o1I{a*@orV{t>E!g5w#U`r zNuY_L@e!Jcmv#&_+_}?@2M(F8e@$osCj`rWzOrxonC{v7*lE=sb4?cFVzHKhrx zaODt^eCzTQ_FZh(zNRSeVC;2*G3_xw$s+~w^XA(J$j6D7S60rlu^CADlyxC;5J*FQ zpWMwD0P}7gJpa$H9^$}Tt#@g6X$5eV>;~4$!|~&~DWcbwsf=QTIJt?|Q|!L(=YLd> zM$VrjFarD3Gyj=Xr3-I0{D};h7fBq(IZ1?fcXZWepIDJYOB?%zV8C_u^c~^9(l@b`3fgDf6o@GJN zCYeRY@zOR|IF0W9;nRu&ch4F1oIZRp@Z>^U@X@JxE5=p{efT1)N9d}?M5pGauG`pT zOYEzHaV}uGBxwVK3dxNHCfoeoO_}oN^$@qnks4FiEcDHs9%|vsIVD*|hcGqG_qVQA zQ7v~5AG#9wiZollMBTQ*6?Vn3&4xY<3SCIuWf|4KvH{JObINw*b^k5PN!OizA;N?yfalz^FYw-TIjjd)Z`zV@144m9n3Td zAay#ruq9xnX{hOpbZ2CF9D3+2tXIvRaGpA4{`2lRH17Uor8LJF^JPE^;wsQ7cY$~m z?s*Y(zeNAF`fqK~=gb0~#n!r{6M2=*LSR(%O@5&_)dxKv@R4D9N=1FQMlCqFx#?^A z`=HP}~jW*T2nbXtLD~*hKmJos$h4A~?hR~S%c|5K0Ti?`` z-3m!dUlHJ@EeoZHTUwe*LK-{Ei=DC~%-zAg)Aod$?upnZqms7yEolr9wT*1#FC{sh zjIi^M_BzqhH!5z9iM*#$skMVL=$%Sa3(KvU2}{CQIqV@cW>m`ZW9;s6?SXkkIrK)?I8QqVD%fOMwY%y>mapV%$PdSkJ=al$>gC(Nb=IAd_hfH-|gyp zFdy9UmlchnDc%Yfc`9hEAN&u;#0sxXpulwW+KPL@eXrX!aN7|P_jxSkl#aZ%1~mmU zB(%hDuw{5v_AmT-QROEsqbO;Oi;0MUH8~Nmb8E7(*FIEQ@ESM-6cg}N{j%!!nI43O z6V04@NEHKKJlilgPV*PLfCw`|^OPJgD7<~K_%I%R5{JWwE40&d-t*c>mEo-F(}m_G z+^#erq(MQTX5mjg5F~L#SXL=9D@&nQR zLEK)U5UBj%Cd%r*EK*ra=T*fU8Wpn&95@dE^<^#WcviF5bD@@u^74$aL|msvNS~>Z zwic83^0U(6Qft}sWNT0b9U)llvGA{0n)3$lt`Jj_YZQ9e@BL6cJ%o6LR~6iOEXqC)8po%0y&#oPFDosC)IpY*Yi zedS9Xt>+L&w1#$6XE<(XNL2U+KMHkKP*{do_~%i~`-Lzez!9ORm6mnJ-#-fQ#_#Ah z4g>kuQCiyZ_%!kF4^3jnwY9bM_m*g+e<(bO$}E%kUS+K-sH6eJ|0zp*HzgH;J8(eV zdaYS}*Fj;R_>=^4U;P}q47+ket@U}|bNtI> zKt(w5-@)2n)Z@bw^YhyN`9^{mj#_he@IT)6$16PJwqEu@V3k5MLTV$AA9ea0Ur4m} zv4Jp)A9`6+4Tm@{JnMZok796tfi3ssoeYp6*9ID2uWmB5U;kWp3jzBsSN0|M#~OTV z4)nL404(`|(zP}Qv)a<4i&5^kVn4)1YI7TiHXkqoy;ObFKBUI5+tw!(Ap4+^P8$G-EMspM-vCU6M#QDBCn5z za5uwXz;lin(u&P}KHYDFRSwdif`dD_CWY@v2Ca^4bb(~eYkK8=kIy?LiQivdzVVBi z+jW|)nG*9$lLv6Z9R)Gs>rz*1VGSl~tE!#vg8})j+#4oT>bXe@O7N1ba}=(Jt!u)s zYwhSP<`D!W&G@lZevsKId);1>c3MJc%Vf5s*DiPJ(Jjh_x7eRKMQyFus$j-L#W(5s zKidlyB#rP=wX}CLTEs8RV7uAQqoqj8cWW4XT%Y)Yv-zQiG6W-`yE9OKrtKZm(pS~* z;eE&!$0YI!WXz?*u~{x3iEA(HE3%EX(Ci6bY0L@ya%az;{eS80V=AJ9ci%E=&e#lJ z(5O{pxJadQA1lS2ko-eM^vaExm~{~iR=R~P)0~MaeN@J?Pl0XZFPou@1Tf~q(vi0c z$B@<;Yd!}C_*t6iagK%OH!jvQLbdy62OK+zxH7yItY02@@#w_Mp6$_EeX3lg3;2EP z2y`?RoRteopwg|_C0V%wh^IrSAR{hRxG#Imv`4bPyK6V}^`zzs(&wtimE8qpg^4_L zhNkT+TW;yuC6|}$Q*br|7wyk>7EwZIk3q~}N>wqLr~F9S5clU+rmoQ) zgN?B#GrNj4s+{xZMuk_hSz22N{ha-du+U8(HLSEQHF+`KnWJ)uk=A!AtqEb~u3m4_ z&8ZhnVcK8T8u7w%>eg8JV^|~R6)|E>2+_Xn6(Nhrd&UwtYBr}FfD~srZ2c%aJp3kr zJoN8>-xNmNC@2#e1rNdW$K%D#Li?7Myk9!USt{&bDB=S`@{BaQU@p+g(iY09zAuDk z_&6^Ta!@oHV#nslbBcmFQER#1&0u}#UNkkkD^zMQ(hgW2XGWWUJO!3ZxW|($T;ja~!9VaT55d0r$?I??y=%7O=8$*;l5b zv^O@$g@qOvr#tu^`W7+;g#~AM?1qlrFeE?BcT-YzHczA`cqhU4)UVno1B>V}Px9&e z#bJtV--9DK+XveN3DHEw@+7#2{{ob%s=im@N#)y)6N-AIC<)t!;D@9B z;pB0bOxYHs&YkpS6Mwb^@>3!0ZF_rAeKNnQ8gR&&eMb%6PJTwLLg$ps zY99~lUmCAe+dZNTT{PF{5?_X}eVtaJ8wij|pNJ+{MU0fq7R%AWLtpKd3 z?BX&TLrdHqt1yXxkf7x%8->-p#F~Sd_wu~}aI1}dA!rrq$iVOQ-onexAUTbkLUV(8 zryVVA;y9_O;nnTh;FaSrT^gSG#P5Rm7Ub(RPPLwq7o+0NVug9iMG;TK*Ch6w4zV zOW@d8z1AB}%Dqj1XHUZAwWBm!*vS&{JZ@GAMeD+JSU}jQFni=VZ1SH`;Ya9q0tX3p zJm21jq{qN}B|>!L(+`PmDJ3@e*cRiB?Iv=^lC!h9iVEe8{@My?#3{_SaPoBQ-pCTq zL?8|2LLs*L$+kgyykjKTyj2_;9-3>=dFSDIMA#sdC8hCu(#*$yUF1pZk@+7`9KKzI9PLS{ZtU#8^AR=aK*u6 zylznz*-UHjuTj#JmTqo?|ASJ3q>_rHQ1A1dHUYF9%@_KDKC1lCc)7<_2(>}XE`jk%+x}^u(kUx zYB`UYo%;;W%2f`>+h*~P`@zr-5t1wq^v1g-dgAw;$scF2nCxGZ1jRrSV{bA$?h$q< zmgb{7CW0z1diQxaj*y^lso+c{R z80wvmy#2g^ol{si${E#n;j;^lY9}C>0F*#3>n4QLkyX2&TYM=2(DtK|S8Px<95^F+ z*I|nBWAk&&wZYviebg5gBd;uzDS`CWv6VhfYb(t)jRM#<<;oXfezh{IAiw<(BPzSH z%+AUZ*Ojc66!C9tH1qESbiu`kS0DgVv(2r|i0Js#H)b^+aUb98ya=?@Gn^FjjUYu4 z{HW)7YH9eRYfhZG9EcJuReOa(eZ~i#C^So==MHx*Qj|^9=h1MUdj_i!E_1=*ssuO_ zWHS*%Qs3T}uYUFz-BjPhlNZo?)C(IN?*~$p1UPsp4yTjQ)!fH?{blWMhL^ZZ6yxs zks{(SfLHuM-ZJYt`(~{Yh(ofUGtq&M$uu{a4M)+~;ze_RqS!I?{(Ix*&MDpeTJJJd z$Nuk=fXkGW+2*cpXZLv8EBW|eyDV2)&LVxa+uOe1eQmbU_6|@N7FfV7%uh2tVS~Mp z&V9lAL=B&t;q@E4Osp_P;xyoM^v-tT4mGWG0RGDe}J4E<8=c6ynvDVPzW(<}KyqK8tZ zQWdInVP#!!->SW-xD~4LV##X`IkPWHnppguH}gx0gqN@`0^KzmaG^`pleZ20r7?t=Z(V`SlmS z!LPvMs+w;jvx7p+%*=uug^K`8;TT#wx_7>og9dd?@@WXSEoCH;%#r*`ucF^o@u5X! z9%#{~6Q!6xQTNhika`ez-sC5ac`x=eIy6)%cByNypf{J_pzl=9@gZ(Zaf(1FJ%1n} z1(Vq9SP-87=bwW{C^{oixwKVhn(>R>QH705>7ZvUguROd-v98 z!ED7YEQCLzoS%TP(MOq-M_Nuki7vlSB&>Y#+7AyM>oH!&O(_lF98Q;SQrT zcD;5AM0dNAEA~T>I(9yJvTYDsbhp zj;?PF?!9`hEG7d^TUiy6q%$1GFPRpi2A8);K~cU{$2Zd=k;ZPIcRnOCFirudXlDD?1oZY1di8%<^1Wag0!7Q|QNKa& zsw$MKu4vhMHpXmLZ;5mRs;rDSYEWdMh{iIe4ivIc>?$*Bw!7iP| zvNAnJrPz%7q=s)DuO)#pT$Mnm-zoTY)&Urm!7`PjZ+{q%U-?SCZ>4!v8OnIa?4qNk zYM9CMzE5;_;Ia&NrF78N`$0K3q7D~XSO7g4$8m0jM zV2yzuk5ZJ8X8~LowsFrLZ~_qP5D%gaGQVX$6=YxOq;2MMH=vflk892HZm1Abmu*0l z8NmQCT;;p&n-Ii*(njr6KlOZSrnlm;0JUv{-_MJ)730jzQHj3zeVnQ{Ze)T|K;F}{ zB>P*Ld+a0->i;`Xy~OVeil%=)S8i^PGO{YO!3W5An6zBn9|K*Id{AQrNfEirYGK0{ zyPW(tKHSv<2&$}u@7q#xZ1hMq4Kms!fmhsU{H5<$e(jJfK4pFtB<#9Vb8~7w`Y(5? z!~SvsKE`WoyVnK@m;0c8ijq)w*WykyfH~X#h^>-Al)hi;`7TTB8++0=fm}U9Ex!+m z0I}6Xy<}}Gu7A_-CGKHiF^+B9TN|uD;ytzgm!H%7qK_WMyMx-Qp=`}(v0Yp<)@(Y-wq#$IOW8O9;12gXJLNKrrSX!lF{6ZarDG9<5=P-DT)1$o+`NhY1o&J3SJli>=QE4+ znU6JYZdFqhXPqmB){at~q|6}qh9RVPw?#CuPu((Cx5nT}#x`o*UT*?7LS?*Hd}aVl z2Ut$9GjF+^07X=6z

J8|<2bLqlD?vz7r7{PPesnxStW&ZwY9sfd!X8QUj5f3Eqp zafvRpTEeBuGP^42^>*(?Zd3?8|2aXP%nI(lS9DV1=#F?F$i2R|b!10(MK2sN0c~CW zeQfpt@|Gmw0aYjUFz#O0e1!_vTy~R8Yd@CfuMM^2Q_|^WIiX#2yYZ6Z`IU^5a z;Y!LidT^Uk^0KVwE^1b2l45M2L)g)LL|iw1RS5OiC;*6a-^3*_lZ`HF6VjQmANgJGY@S8%K7@2aY*#ip9r$w9n6V4SgOZp{wcrR;S+nn z9in?ThQ4OywTB81zJ}n$r)|2<%&y`_5R;qy&tP>xtxufhbNtaz@V4+ez@1cCS6?-g(4{@j%KgrY8|?sGa)o*0k7B6(8wBSjFgW^AqQAm&3Metd+LXZq=ve>=@AW8FAsED z%Ak0dg@=q2?xk^@nyza%J=ZWNR1hH8`B2I?=gFY$C4a5yIy7%gyGH7-FP#tPOS5d$ zG1OX|dio!FSo!M6h^{xW4k@ah!>>8|joHlpOan?MO!pIsSBI4)U5EIL|Hh}KGw`!# z{W}aSY@yiakkTg6qOSqe=L~>IMQ7|oF9EDAdX4xDBMC-_KkfbNsoG$8pE|U(N1|4* z1|PaYRP&%*8ia&~FSoLxf5fmcq6q?-2c-FjR6o_>>MH`K39=~&?JE}#GC6;z%AJom zNVSlJ^`7@nWZKPt1g+Kbu1YEtH)!14#U(xhRBL1asERIM7RE#i=03pwKJ6DW!F^Vr^LmmVi!Uu!E z<8iKyo?pLx$-l^Of(+U+PoP56t#X~8-@iN>g;U~!w4z@m@jy13>ATjiw>IGE{rw#! zT(BQ`7h3B{-w$F4VNQoa;D`8M!?fwR4Z*p6m+tVK)6@6I84Rr*LZrtZWHb}B|4*QiUHsHG9s790k!yVWka>p zO{rDJJ!}RnY5znej4CPggJG`VDe86yuZ1QS}3vEsuk&}g|)LQy6_ z@ZXgP$p)x~j1qc!d)s?-rsrfQ$?=|$-W(0pa&iiW(H!DD!$YfwmcB`wf99@6?!#`S zz;jI>X1zsA3v`V%^s-_{{UF+T_uLtyS_sB&vG`<6^55cMXMX{4bLrkd*+)K68E`sc!q2`^nO!a@;I({4QYOFp9+~i6%Q@zZ*B*|rri~x9d1ldX z1`ibptz9vKvF&QS6${yg2||LK`*WqJsLpWlXaH3eplmkvCntX29@|d>&OZEc+XI+} zkg6ZeXFg+d+vfXp-nY)5b$X(O6nCH^ohL0{n%jy!=d2CfV(C$1ytWA=cTe-tFcWT+ zd@ukXv(65C@lOVTPNl$GDQ^+y7(335lE!kPY4u&+%$1J&fu71M)qE4D@<47}9Sf2g zx^tVEUY101=HR2A{{lPfK9EDY=kxIV`SUY0q2e->MC-neVVgl^s6^=HvYd)I^y+j} zk33?W&2KT6-Ay57oUC~nj;903dRC-mj;pY$on5Y}X;(Gx%MM)Q7w}buE~{(n!`jJM zPF{Be_d`KJpWjI3Gq*t-{_Tb64m!PGEtCD9pQ{LI3{Of5LW zr31uz_pXn)$liM#!cPEgZ%suIg`U#wbhDbyi zA)|w^)+$$T67eQRV0BlVjTTBcBV#W)_*Rpp9_Yl{V5oX zKcQ!5nM8jk9#}5Yvu9Y;A%ke-+ST)r%z4sa>+ISP5>YpcxesgQ_S8(v_!Lr+` z2}F?U6kZ$YA8HoXM|cBvMLF@FzZ`?y5HmcwT&x$^z?N=`g1r)%JJB3&s)I*Cq+>yZ z2%W$|ueHZIXB6|;k_ykBbjH2;xbFK2gp1_K__4dch+w;NxxIj|iy%Pdq-|;Ghjn*v z5*?%AcdK}L>x*LE`%_i!DGlY8&9|4(?%trEoIG~$n2`Cw|1N@qyx1F5cZ){8et|q; z?TmjYh(zB#VbhDYf{yJ`%-aHCRXuOU@q@Bgq;6i30zmLZj@^4mE1(4C<4QCmdSOrcW!5*Tvww9}?#y|^w-3xYcmS8>9I%8BG=z2_M<+yTondFM^*r0RwZWn?5Y#xut4Ly~ZnULlbNTsMqKc(Nit!c>Ii~mID zyw?G`)}nU5!Ogo@`6dVg?u@)mKjob8f$Xc`D#AwTv|y>qTj?;UjmNtRXtl}F;$2>0 z!1wG_!O=u#8m8O)yL+(qqzeS+2AJHaVg9q4tXJUIDx+C)YPVn|8aTojY|$Wh%jp*? z*9{E^h-8O5CP?X;@V7^|$WPZ&0{WJ>UX^!5Up)F^NliRrhf_Km$>{oXIH;SSH4{E* zHrlts_v;tNWSBe(t}gcrX#O$_3#cH-PT$i5%4eHVUgsM*7R&kk6ri&_CEoU3H4~lu z-Ud!~^l#76pW#4jAKb1~IH=*-jNJGN6nu&jlE0q{^2Z+kDqq*m*`j}*I)i49b1G#{ zSV{pVakU}BB8Fi0&p*aS2$Ha}viiF6R>|+Pb&1E=muKPAa}{tjKlRg$-}oo6^ay$K zmL<+b2j4XW8$qt_<`BV3hHr`bW-55oLEe5BD<$_PeE$hP2EdM%{c)`WAyh#+RBia= z--qo#)>s7*AjfT`OHC$`HomctR^LBiNI2%sGOXDMFlh7FR!E|KyU zVsH<-d?N)s2MgS_IW)cbNaZ_$}=GyHz)G^0C6>zR>^zS>nb?=`-KK{;){%QSo14aH6B6w zm(XVxa8PE2KFh*m>4>Up*15uJ$+C{9{A7#%-_$2#Z@MXTfa^gl-d(1b(=+?iqP^$J z4G39^t9CvZ|7ds68+Ol^F0 z@(*S4D>sgzj-6ZLJL(0!BPNlqH$kN+hi55S2gO7>yH&8FMC<<$pbGW{R??sFX(~(Q zz32E9x^LV#A98%>%mW?Szn?fkASx=l5=1XHvFI<(u=#-=MvB>RJB*x7w`_c_;*84A zv9MGf-aWRkmCO7+LZ-h-%HO9uKG3p}X=X^@LJIkG=aOsTnv;6_`_A@^NEz)E#x8W?cJ<*e>cGkTDLZEI?5AC_a{Uuc)AB%oCD z3dVV@tr_&W82xbtRJL&W3m#Yc!9je^4#ryMq{e7bidHj z7ab?X!U~zMQRNmyA-db#@@;B_R~!fJr=EMs~6HQ*8=;p`Z3hZlioI#r^mCjAPS~mY-&odgfVpn{vq8 z493Pz+a!)f(wti04#-%?9sY}PAl6aY6BZJhswf(y6G24-V&S2Zm{XwCoxCInH5z@* zQz`OQ=IBr{q12qHE#LV=r$(My_i!IH9AH}A2Ba9NC? z_dI+aKbCrCk9YZ4{2iQ#b`SX5oBqjH8K(qScPZWpRI@=8C&(*L^1a2BF*9Sc6?n2c z5#LLcy3N|U%9io_=e^R~Ur13MzR>SdIGH06eo5b&7ZI4pdHs5LAP8>>X%cf`T!s4N zS6o+Mi{k&q3esmqED>vJPW!G8=*4~-*yD*-)0H;%K+_ufWX_du8A8@aZjYLK3!Z-` zhj@+LGfV=DP^y}n_sC|YzMJaXvmpBNoT9l>uO9{eJ?uxW!s=e5d7F$9Zx9|6cc765 zF^}dugj)Qk#+F5}hF6vvMQ!g?B+mW%KnDodG0yz{RWYl&HL3jBJTr?0qYp|A#F`uA zbXJT|XVV$EVHB5QU(x*V+9J~NMhOWQWmJ?jO1_c@`lcFfmrs^$fy<;i+-Xp=$o4_<|q6Z zqz!a5NqoEA^J?{6HbKD0k=B^BPff4%k2GnWH@V|`=NY`xBo2_& zuvqqxivij85qwtH(`RrJW$YJxfD}M)z1Fd_)_378rWl4$9^;0{FLk^1wB8wB-X`d$ z8=g-wc)e4(AyYut0h}SnMF!tsJ<0E;R3-7|pD*$Y7rmcItJ2Ridm`!7yygH3{9>bh zbPYxnseuS$>qV*z&TG~`gShX&NP!%(brAZDeI&O8Ebkzv!&?8^R3GVHc1TFbhk=i- zLPsBH7*!6=?^$Ln1{R=8#=>c&-f0eHS* zpWmLhWZ~|KooDRuvt!dioq53?Q+8pnv5ZMa1z$c5rZHDMk{$;>+cnHx@(cP)dnKxw znP-V`;&?y+82ovAw*!N=CU*3^sp+xsml+U?$uVjhR}N6DeO?SO67gUYNn11pe%Y1- z3As03qJvNOXqu(r`Ikw3W)yhSnE{}p%^}j{Ued<16JJq5W;ln_IU`$R~-O#t|hRtp3XMV2M&EanOPUh0dM^l=2^x-$1ASp z8>!V-`DbF9Sd0qOO=6v4fTH&d8zMOfnyb=&x4M(;dkNV)Hpd+{BDAM#^z1aCgIjf` z%T$&K{+xfK0)R6*D!b|FsaYen_OFohybKB4RP+yJWW+B6IW6BIv%JxW(I$%Y&|zLw zI70e4=v_-D*Dt$P`{{ka(eRF)3hRZdr}$Ms~dA-E~rSP!d0afLr))UvZt!oaL5GbfUc)XTUewE#R{n9Rh(y` zgY9c9ZQS50q^Y2nHPYSFIXV9z0qtkB>+phZ5{-Qn=Eh{_IQOVBpg?NqYb=9np#Y-d z+r%JK)e8^f#DQ)eMhwnlz+q#0S_8VkkzBj_ke)w9(&VZ6X>C)lNC18s3M(7^rOJVI z=Ei8p2w2LQV@7Tq0msT-I#O%v)aj5EHA;S2)l@WMC;FOO~ooE zrT|{YkLQC9;ylpddBBRX5j29yrDiDmz1ocWzcW<8bXy|)v8rFet8uQ0&|j0|BPr^+ zh~*2Z&*H4-WweWgnW#T$BWCUB#z?EV8+}(P^ZnFBhKtQyX4|!U*eK6ZI=l=xYk7I^ zLV<5BP(9y|Rjj{-aT6X+*wuGer2m|KUSz`X7a&cHrJDzz>)UaE7&R7QNJW>4-2mKR zt#2&=$^|*mBWrRuumYhHk=hYWjCLVZJ2&Zs?Pj-)6^)FGKbJHyqdRy>f7H@WC$9|@ z{+@w8i+^WlhrvL^@SJQ2HFX!yH@Cx=S^qp&g+zyCy9k=Gb7JS*AhWWWWUva^4C zh4~VY$t4Jweb&|D+-kaEQ0BO_v9~f66kPw}IpU{{nYPR3N~b5{gbkMv4mh;x4YP&g2`JRmzPfwwdnP-WU7KlQ`|uh}_Tj>Y*LIb9p1h1ps?fE|tPZs}1 z4iw=Q`ST$jc&zrb1#O4RHg#q9->7li0ab17y!gjs6G6xEK;mTxu)k)%gaqUs?|rZD zzrlYZ8$1Z+5(o+lThF~yu}o)jchIn2h70{T^#hg0<_tB@nLU;hO}EM0;*LbAt?jJk zu+_m3W>l63gq*0b(~nOQt;zmI!5e+Ax23Cu{{DhF1p9@~uA>o%Q8pmt~-26q57j_#lAsz zbVvaW9d7RG9_O`wrd~osqgjpyi^XTz29nStsMdSXQq5x=Et*^U)qPN&^!_b8301LAVN`BO{|3npK`eKY1ve2}T}hroxm zMoZc6v}NWL4P4`G^sTX;Z39m>GWEptBDu5lB|yFv82rwX5|hLGh}iCkPN~bMgp#0} zc-T7}Ts*cysbqS|RCWcxR|@r-dgy;UDn=}CRhI`j>Rgxu6q1UhhBq>f6rx8C;oOb@ z;KAqoW~|z-C3))f$-vZuccG86L=c~_mP9W4lL&z13sv+_+<(_sx6aUADnvn>ZRTjq zScvL9(~t>bogiW+uLVr$${1rZ?VYbc>^%bqfO(qFO0ZNA=-Hp^Dq0%8C-6|c@_08h--tYIuyfg2alh1h$jT6>l zZX!E?f&G(LL6T#hH}3T*9LyAeB>6(fmwO;z#f_Kpxbv6q{MQ_8rv8N`S1724=JL<* zP?&{){A2BJd==_&HVPX>5S8Pg#yc0nU8t3XFylEBU)|i7*Hk3Mt%sOELsJv}T?GPT zqB!(fO(#;Ha+dB1u#3ULx(`?$!q|kZdOU^!692HaHgmG0YM-L^+U$WD+4K9XCn073 zfEY4y+i3>KO9Sfw=vL3Y_09*5E6PH+@xWxc!IT-?3zvISbH0K8RJzBLYyU_42NEp+ zdXHu-2W_^`moQ|dHAoXlN}~~~?vam1xxf9?et(!eDOPdqlqIa&tl*4Nh&U+ZBFG*L z!^9_W?;dMAzC2F!sFq(Z!G|Fx7%hLn&0fQ~SM3dgfXFJt2UK<>u{7il) zCPm@qf6FUcppHEQO-zzwB-TiJe@31^egT0hGg@8lMuk7|{@NY8G4q>PBIi z*YJN`YJ$eF$4--}KRU%8yIc6JX{_HpqPR zN%jAig@nLbDZy~#yXNM_Z~V`eT*GJOKn^JZ(VOcJ2B)I+l}&1WiJ8tvm%14*(_ATn zbr|aK6+7XOx3KOU%@rxw$ZKpcVd(fcQnSj==)vQgT7dA1L7?>4Vv$~5KJe)$W(F@<*c{CNAlUmH zaA2Thmpy-o|8C*O>;Ln=KJi%w&^Ln)6chEdLV)n5p0-BwTNRUyJz8C_eEfiuc(%?) zKM4OY;3(6H6HWlJ)l^-U%Y=V5d`XQ?UzfOOdHLxqM(ThJm?`^ZJ%Tw_J`-G1FnqM0fg->e#7q_*t*wjOJ{Gd=Yw!2$1dSseBC!Q44uUaO%N@K zz#aj0k;5C@3fJ@>V-}V$G5ytb+sPXPDPF9itV4>nUH*3aa{lU9GEwGL3TiB zm7%HGG^k2L=KSzQOphh_OtOf zmS;T=*H7emg$z`ijs^!B(dhPf?4?ddRh=V77NGOsT2!fjH+^b{jPbDOUf+^lQ>wyL zpy4!VKK~H(=CN&V>oxO5tRxfT$6e7u1E9Ty=@J(L9mQJ{br%l+44)X`$=hAeR+uJl8BGT%9|AWh3(Ib;A-U;rN0pO{OX;KN-X|7InvVV9 z_$8MR-=D%~$KnFT8Qw-Y9Adsidr`N%WmbjXWoO%YREsIrURwfMr3khJ+NaCg^#O7m zpx>MyzHa(&yCjAmKnz{Ihv@eCajp{7G%FJaJ`A=Z;P_zABQ335cJ*p2(^L9~?ETDJ zv8u18e-e1S6BdBL88Dp!Ff5I8F+{)_15V1lorWKx4_7>23TXiTU_i**Ky5K{j>GsV z6IGmImh@j|#GycN5c6^URQ1G`y5BSxC}pt)zx^T94=`~0o}T*=9dmXQxD5c9RZXm% zlQ7+M=EG zucB3lk($>%*Jy-v`oS2$5Cn^tQ|A1_JO%YiWFYHz&F(7K~t5ZIXIJSKailq9ahRQrya5U+*}%OhZf<(m!x-1vHvS*mxdw$ z(!J1Sw0U>gas2+E;-55$gn{Mud`Z<&+(R(Qr*&qaH?_lpOZ@dh^y1FW&W39x`G}@5 z2)&AQB6GsnCBS}xHBtYO>i$Mh=3?>-RW=>S5SeEbHL8P&Gi6dz(g1kzMM$VP-HqGx6>pK*gV1&UsZ!A65F=DSDcV!I zX14e|&qIqGu+`Ct7i*;l9;W>n3z5P$Tk_lSy+AeH;j#72n@@DCU;khGUGNMgx+B-o zu|TltCoI*g_xt_J10pqaX;s&q(JDDSJbV%LnPq@d7{2g)rE^EMHJ+^yfRAo*N`Ddl zRPLo+i=gouhP7B~p_w6_4f807sOKJn7{`jluy*VEdRZSoV4dGpRip8z{m*x2DTj^B z3_N_eemRb(ALBr=S^~^aMFH1XJ(@1nq7YP?c)}h&p1RtXU1tOEepRm5$w#mt4~$K3 zY?l+M@GFNpVzWy)ySrCxG@OZ{y<5`4J78qu)+^K*v0NdTLt_F4#WCDl{O~Nt;BSzL zvW1O=UyP((m^d{hnkQbo>-zW}v|2`FqXGcSaz(GCCP?87MBP~L$NPXWrL*{c6;ywV3Xe0n7mIfhy-Wn6$ONmSSu(rm~-q9A42WwR_ zob7`)Z?3qGz)vokb|df9h`}4ld%0+&AHl!`Vc%b&_El$ zz*T79ij2N8gCY7aO{;_o>UgUeK;u=OsThL>+|J%k&%6HRKxJcKQt=;x-kl2;Tl?J^ zY8c>RuHIpaR1$ zyHu78ECB8<@fO5OjmPX?-=UbYRPK~G=|;fLxilaSd*XPKbrrnWG!&?ly{EQFDp_1y z1P zVew6}ty3Bypt_F6>M?BC(a4{|Mhxia0qgJ|CXb^JT&MHsI?rmebh4A2QM_JP+^ZD+ z)`%~$g0ug=RZzZ<16nB-MDDJLS0v7tDe=1vmF#!xW z&x;mMEle7h0^J;CxG3rW+TcN%MOL=a!Nq0hb?k*g{YJU_pE}E=kg!y<;nk~QU_iv= zOrf|`A<<#L0^5MYA{C_LtsI+9_^o$54j~4p@tF63e>Oefv}we|D|L&?20hGSmKxTh z-jh`O>y3k>quyPzNJxX^e1|jun#K(hY=K)? zm^Zxqx`x(!{P``&G~Hj{8jx2~fk}RPj*iJp4Htrpr89vq1vO>CE6G5m_ckKHEUi+I z$dnyxR5cNMte7!K{j#r<9n`0^^m8SK&^ZhO%t8zAS30lsjuyzMA1e@mXB7YGsK+zKjIM*XXt9{1z;uZ3H;5vUiEonPVn;~+I>L&3rTTy7M!@KU6!>9 zB;7J_V#xDk`v?J`nqz96W1Xy|_Zr?<#uMX@H@@4WaTkOxtV-x8ED+FGzqgr9hFs@! z1S^{TM|DCX238DO_3FD~C!as%HNolRL4(%Ehc3aYg7r6RrUKs%4vw9F7T6?GICcd5 zBN|!9&(_d7Ayr*xmwlMQ;}aj6(!F8QG@$;lVvEZ9Qg*yBf#I$?S}dyaKf(tB%frQm z{r^;{H`y!$PNskg1lZ2qWw|0yX(squ3r9Z}T;FniPfS<@S<_%KL)Cp1n zVZd$X`;e8zEhgrO zZ>YA%Dd5SdE|6RuEsbt^9?Xso7#HD*9X&6dUK!7kmp0)`dUn$U>>Yic# z%>8MvpvLN-9v`x^%W;J<#RdPX&>tG1Elx#+>Vsbod^d}3@$z#cvB8Uuc#f<()3kAq zB%5DA!yv3kgu6vRGfYj0)#41pwRzCccFT74fPQ)O&${TCxS+(q_K0k$q)h1$|0R44@+jrdeC@yi zGy1r7>fUM)f*v0i%!;4lJ{|fI5ZC}tpAIV(h029TVBtTjN1_q&D?iu1Nja8$IGFJ@ zyXwUAtGxy)%Wg>@94Swl6x;vM| zD1ZK1*VEU}4m@1uOXlJL)U4immyua|Z@r~ua~qhzotCt>B2+oR*4MjoG>+&WWAlvFc(>-s-6!;+1US{HtRoEo2i z;C0VfTa1=?tM|a=e868hX@y-vjS{}BxoA-GX&8!F{*B{tOc2fC9WN00TU%R~{ugK= z5Wu$vHe)p2z%;+2PlAvXEdo?9`*imvP`@GlkX?QjE5OB}$O}0)vGu3C`Y!58qhEE1P^r3IION`I~rve^MDB_urZhC zxBqSBR#ZbBbNPV@Dgf@c*Cx+2ASiO=&1QW_0lL|S@hK?cbA@Ph{Y@twN|s>uxCw(# zKzC#J{j6xvhtqQSO5`408-u6*Uo3#Q^7{u4VW5D$l=pwOv7g#f5$pyG`n@5NOB*z% z#~iei2N=L9J`3rvYT4rcD|1F@Pan)$xpPNj@Y9jdgR{L64}A>Ktqe6F@IU@#KW;Zp z)cMuwgxNs7(khJ>z*GS9-K~dE%jo&*qtV)16Zb{cd$w@V?3-inW4{rOnvti$qR(|b^pOSyHKX01kt9clfdYcKw2pl`&vcO;*4gX9 zuQepiG(l4lO2M&VlAT1i+gJW5=v0u75iE^zs0MA!SMoUMqIE=mqv<@KUxlCPHj4g! zDuRY-WnxkM!!>3B7}j6!P+$J-(b)Q4KWaR9osAxxyX==?Wwl9$%b~i?)E0Y zINLt&MtgWQ((;1(?So3==Q}XOSM^tJc9lsv&iAnjA0pASB{obVE5CNohkLpzq5t(0 z%htM=YUNOG{UZri8mIqaqS8p@UQNEoSjk?|9)X~QCbflYn%TRTXm{u^9tDO{6(!cM z0}bOutE4MmZEJUv*K(R+%OHhvkTqP`Pw;s8H_Gv3;+y-p`_<6%OP zHWEg$Rf=0QO5wZMlN5G)x1SF7eAX|f)>LZdxGhi`>* zzXZR_VR0j%Z!y`d9a#8f;L!7wgk`dNFm~Dfd zAgRD_)<9zB{Baspc!(rQg!sF&Xi!lA#p{S+Awe842I^`o0WDEI%DW`bVjDat4%>1Dez z9dM!!Z?b>kM`y=(c^LezI-@3~?xW6_ILR`Ty@W#h{eOD;;$RCmcJb90x z9RJR@xN8%QFzZBH{ShCDN4*#_rEQJ1PSN1NlTZ&EPpr4oNVmkC(NSMe*?Ow2^Lkr7`WxOxEHfJjwJPIW{UYAe)6<4Y>H6I)gi40) zLd~~tLuqRZj~<@*LlBrW_8QZW+3_x{u8U&EU=XP`?2b@O25riY<0ZYk3tsGDB+8Fj ztrcJd33Xg?YcS{Q6>MPFG8nwRP@`Whz82yFWo@1te$aHQyHHcq7uNPV;OG&<} zc$C==5pOug30z8CFsjVvbAO{f^S$xFTlepS<#%onj&c537(85U9OA(Pp0MsVzEM6V_Sr*}s zEA76_ACtqVRAgK=IVx=O4uZu!%O1?y%G8!a(2VdlOep7k(I(LAuZ!oY`tRWj;zop@ zdxm4EJhLk_-oEZIny*fWuZ5b08Jptxi4H%>7MRFzi07R=SGM1rAv1E=nb`h@(WIeD zi2-tA({N(m_PBe#EHW zsd`eXPK+mdT4Z5=MGhH^*-3O99T9=D-~I8<{YMOTXIdT*5?_j3Qpd3L^bjNx@<*>2 z`O5BkuV7w>I*&{GW9*15FH+&=W|_iF|b z@Ht$-^+!g_p>vOMNJt3H_>J(d>19R&!^5xMc49;B%0U)!hM%-bm{OC3Uz5aV_#)>% zxYscTL;r0&zRd1qWWw>jbSDc!ON+z+Bezlm9(k!l!N(8r;(Ctz`uaXci<`#YN*B_S zbKJg#zGp(P%$Itkl$3ZuK|zgKZ88+lUkb_BJ+h32b+1E6Tr^e$6^t{f7&_)YA`ek- zQd6V9i`ZubHOm!?f1yI}CRcZMHnSB?mFmVX%b3Z^iVKJ9KFIoSW&B)=45yLiL$$q@ z`ppcBnduecBvP~v$VH+)yDwXHkGXY1AQs1DFIWz~lx7#{s_N&{K}fjWmhTw}NJO>D z!oUcX`;)n(O%~1LvV`T7Xhp?K1$G*=H5n_ZiI%uHIvV2X!=5;0``PbXBigb$!w8jbBi;fQc2{((9YlqwLvh)O z7b^{;u6`kaxaW;2=e@}|>8t9sj@fq`ZOwEMv-k6{)J>{y4D;&MhB{$Qiaz?~pFI31 zHpyCVYAB*MB<}phqR_XHHbYbDFI`=&3h$NXm#EX-8?RPh$_zVzOJRe%`)nszwgkyh^g(dge8` zKW2}c_mTCNEmFhEL)DP*a2}jdx9dogXWwc5J^&ph$;4TN(S>I{#xpyS<-XKsZv>3* zi_(XwgZGkg3e(FUReJFi+-2m>OdDSnixveL_pR*gY^r=7!(l=QZiYZ6#~2y=REg$R+r7aEkV`j=Z)> zU_JvR_th&h+WEMO;jngZQ*sg!nch_C*usitR*nSbEz_aJDe&lTuryMoqEEu3Q6Kl{ z<7AoDC#i0CE!|r~`vU087pE}Ww;s5bYf>X<7bHsfaJ*9Rb815fde?!N8tIaewILk3 z1^V&f7b`i1LHFiyZ7>)WD|4|nx=>1}1j z3VbYh(+@#4zYDYXcZFTh!ulMUa3<7rfQ5~HSJ56;&M}jom?mZt{UFa1!oteRnyrX0 zlcOZsq3Z)JThnpE_`T3kWx8SHqcp7oR@KVL%A&F9kc%;@u;&ZMOjhIC@`o@|CGntL z2lTdBT({*e#3x;4< zd*R1$LXraxBu=}mEz9=B2a{pk&k4LjmNn9@s{&KP2MdYuE+JlMmDrz$`Z}Xw-KJnu zx-zjzf_8{6EOJYTV~RUt9Wz1pdGzNg0=BR9Cl_pjBPK&`?=RhP`l9I<{rz+e^hLLHYyb7qTN+u zEmyyhj;nF!8aDiAPR~7>OILyzcX4Ss(|Fyxt*y=VLk*69z*H9eC|J!g$)Tp)U=ISR zf$r>0jJluwSX`b5Eqv|l#IgIPSDeuI7)gYQ9yu-}>d6pzwr3C$7RKv$>k$hAC)5`I zADL&wjR0%6x4TkM0KfecpHL&xN?~L42AETX{sTWO^FR-_?1nueHt)j{KP$b#q@zS+&pR|kp9pGd-?;h~|kV*?6Fk*QD}aQ<7NDC)>JmZu>(uKV4R zV0l*-6!k63^uPCw8#dq4Z1`P(=wR>Q?bgpR<*n|JD-Bufj&s^!Z~4avfzv@5JSOF# zeb>0NHK^)t>GL)ot3-jR!3wq-?-OGII0PORB{>~t6_iFv!c5bbE+4z8AMmt5%Hy|_ zy;CZB12LFX0>)32(-V+|yGFRA7*HtGlr-c0@wH342fmPmB^bCRbOe3R#1L#??#uM* z_y<*fVtg5pPbq4{YJaQ^8c~{o0qxU`?9axkwWDvG6APBV>B>X20ABK18;^Yf?aMMf z4b+@#hI>xTq3^GEo!3#9?mdm+?9&HB+k<>1tia8`U1~^*3Wi`bGbTv=bLZZ}I`!o_ zIk{aaxGOF`$IwPorw5I^4=8uLluFXt^X%fW3NPj-Pkjzc%pH8)m|_q-E2a((F-h(^ zXAmSRQY42Td$GwO?4A=PHHoTHJ1|rb7fCw!J7)T z*GXo`{vLj<=IlJqg>}aTVCmgD713&=1tvYVsLj1}UkAkt~Sk0>#^1hy~*7r6{pLYA?iWc}2>Cn6DBZw#p?%0lk z^eI%}Ts}z#5-?9mOpeYWkU6OphB?$X(c zQ16YSw_6imXGqA%o@ZnrdPV2_z&*ZH@WGGpfUwU?Cyf-$HZ5FeaQXx?c2?&oa|>%NHC3~h7rq+CY|++s1j?~JcgaV zzL?y_JwfNjD&=AX!TvdWy3`#mwOVrx-*QH76sPJ`O-~pj4?yG_S)i^=a+yVl6 zOs5m;o^9ll+Y*|n<4Eq+qe+{WQu9!JQ zZ_d|>il80I4FL?*Dr6@OAD5PvRs>fx{rt(EBd;fWNjBP)1b5*x$Opp6uV`w&NqwGp zrKN@I@Z@9{RUGi`9+{N#h(bF#tG(u@KTXfsQ0GH5_G+M z8W9_*=avP(be24^$}7sZS5{vO+br|Pz3IdyB2u!nWWj+|n%q?au@G8FbK{VPp#n^& zkU_gYF6clH5!_6`AmNQ$G~tPe=e;`lN-y2z#jaSvhv)it zhejX>>z&76XtF6yJB$K@Pfz_P-4D#X?N{Q^o)OQM5bV(do;4zzwHTN!k2^4NJG(ox z%p}O4Ke@l`geJ3pYSsGi+%C|rVwu7<67Y9ue9q!=nO{qE$0a1x#)h4qdgrE_xPHg| z=hQyHf;KiSKnx`hue%6T^R{M?Cn%^iM?2{K)u={=Fstw7E+lkx`Rj@_XYvHM6RcEg z;G_7l+1Ly>{hzI~?^yswwRXE;Q&V`VnCRaL_| z*J+%@=z-Jm{*;vX^o&E^)^0ac{xIN8#o@~<3O@Tn7KbMOq_0$MBjUNW2efmw-%E9S zkZB2VVtxJUq1|jQE9x``;rXf(wr4kgOljEUk7b^AD7C-#{oq6rdZTk6;s1{X=FVUa zCYU&tu<{yvsda^Ef!PnPu)$oIj+uyu-f}!%MA7iO{9(n%x}wb%d4*yd_{wioU3z5# z)kORf9UUMD3ZCAS6e84G@slz}4-jyd*45P|9IkZH>}A+t_kRn{+2sbUx!Y4oRfZML zjDhF2(nJgr8Qs&wxVQ*pbMsDDZ?N?{&PXWV44ix zcvWp7Nvwwx)k+h5#VEa0>C9WZc2cAEzDlHHRes{r2|H9xrz?Dz*w}7GCC`D>+hd;I+on@jQ8A=|lcQtK z99q!hpz_$|b=t!sYt1h*^s05nvEo-W-vqlYeN3Q!a0e0fA}lm?9&O~FC%1gGm{klT zbYJdmZ8#!$;Vet^ng{pBjT@a}oby)ALe;$5*w}Yewbveh0@|t~w~g+J2IKfb*lLOL zTS4);=Oaavu`N_Qv$vpS9wRs)who&1vyd$0<>1ggI{2&yHRp%bUy45zzm`SIGq+?6 zzruIVf#$lkgiG!@G@&gBRE~yty_s2|=Vv zsXSCY%Sx{b={D@T!eW$g%S-B3p|`ufJw>|E8`u z9zG;{3hSM>rl6$CEX^fp$!2-HIl>s=d!X1X*Z7U*n$0^z9hT?X*fXzbKV}Pl^ZdeU z9%<1rY7EyUq9p3e7XX|)Zr5$6i%;*^em7L%Ffqx}rAk$cXJG4~Rn)9Wun?6%%NcNm zd3oLCX}YR2GyD0~_tC z2Y4;48&)i^H16HA1pJXU2gOsJP)Y0R<`JfAZyqvp=$A)egh!@mm`>G^Z#1oHfV3aU z43wh367}wu>el!okA(N^i)#|p6dc$;y!DaUk)5-b0SICjW?da*Wkt$BB<(Pq|LkP5 znRuZi=EiN;(q(s>OG8r03lyV^S-> zuV^B=bLIT@8HmF zAx_9e;|e}Leth%h#|6)ZtDCwJqD_&^v92d{NB{9L4v+a8yu!@c5Mew(jLjV@AGH(Bs>FbQghvj zL!I5!+b*X5kmXK@tX@(b+HPhbuV8jE9Y>0MXj8b@iok_`bZ1e5(?7x9TlIUVS`ET4 z@GWPugspD(L)URQ$TQUE-4c5*2E`lfhdZvQRkiD-d5cOzv>JUEwlexZ?Lwlideq7c ze;c@N?OEBJ&U{UiVMtqF?StCvYfbsjTR6(BQc~kv#8~Ze#q+A>flZ7Cl@Fq8X8bWg zq`aIQ3QM8}#_Nh*UurB?x=_eijsyqCVJt?IBu&QA&b2?b9(2ih|Fqcm>7V09xZW1t zpb>@~%mfjSyIKT^^Hk8HpE!*=_im%u6E&{ZHP=}m?cqHw(|h9WDRKcUnjSCX*;#ss zAQ6-E-734#2U?Oli=1@iB+MZd6%|)qdij6<8rHEH5Si@4o4k5oxXGjuJ2Nx$ZT&al zi?hC9r2pfUF{n;XL-2A>(np~nT4Z+6e0}T_0Ury?g#-E7_eSnp!{xR}{tGv6VFPUM zW~#N9mp9&DNK0(!;?u|rEF?#!S4kSpqZvz3i5PAoenEQqA`qdNVAtW{%(UTOzTmcM zJ}M+h$rgMgUuHD4F`^5S@CCm<-*8*bVnY6o*59T*XeNj_6C@`iD-BrXy8BBlL*a*` zm5Qp!+P?gSzQ$D&mgy7gTZmC$Bi<9wDDTk?d+ZZgN-0qpR{3715;P65?b1hSYawSX zU++{P?XhW&%vvTJ`B0=*o4ys|_@*Qz#AlI_k@4~A^O-@nU2&c3i*TGbXNadhda{yV zx-s_+GXme+ed+9779k=W-P+0Qsu?SMz$X}#Dpk_|8-iqs7P(>q<;Z>gR=bXkg()OW zK0S1Ev_z@C+MsrjVpA^>k?fi3%C>+RBzdlC)=3n=$Ip*?+8S=tNl&h)e=AG@I*L_& zR?e6%WEvtwCDfibloJ;Z&7Q%*0PYlS!|Ep|baV;9^5H{fy>qp8rZm>EG7e9jr zoLJ8y11EO|-iBJupuaQ8y|unF{Bz=h$k}a8NrzI*W74iFL663uPGRsAf^f3#Tz$na zue}lFlbMa#CYP{2Ufq)K(lnww3E!W=a$cQcP7XR&@frI(3Qk=p+WJjG5CW3jv@L}_ z(`wdtm^P4u7%#IqT-&{MXg$CN+)P6wTFYx#?83qbNyUUe(Mbl93bRcisH`g1`=^lp z$LlU5aE#-<7DkL?_LgoRN8?;p8+6hVSYe{nl9qvQqDvzW8=y)zl8*OTJ%z--nnd=(@2!cTfejEoS-OqkM^&j(Rlx7 zEl`x*bbRKwKJD>6d?4-V~tUzy)XWxlh5>bX+df3SRBj zbL3&d)?WG2;c{}kVc8?f-ZXjQ*D8fX!mPr`0*r>cnCV`hpz!p!NGP~tK_E|Y-pL+?z2&-@Qi0i?eNIbiSX%Mj^ZIt6kOO5#QyH z-aAx|8niq&0xeeCEl)4_S@v)Cb#{KrlT5%r`HKbUCXa}~z4BTElTO?*bjZGs_atCf z?<%xR-~|n4u2}_FlW93gH2w8_LyU$b7#)=a(9r1YLi|i%xW}sa&9ErTq0pxx?JJPp zh5=VM+RHdU9zSk<$wI8l!l}o5{kp-zn_{#6B0up2@|9fCM`3?LzBDq4qX`v`EKx1H z3-_+Onmi{>X0(I3AmYPmifyaHeS8)20yGt^$DQ>-`)|n=$Lpqh{a9L>YnfA!Trg5z zN|pAKQ;PPX(AIuA+54W%gR-J84r2+QU~5f>e5>v7Gw%StOD1w3OYGtF6BqqLRJn`( z{Fj&SL8~n8O_myh!9cgf%b<`M?{u?T?iTkWs!ZEms-W&2m#L5Ov1~Rqmp*0&RWOdS zd{iH`;7ySDHoj@iutEI-$`xHtpk>l-{O)uHFOq12RlH_9; z*=zU~sO~Rd1!wt2zes+YBU8Fi@Cc@1f3;1_NIhAsqntBRt5Iq1vMic`5$s>T@W~Rj z6MyKr=difE$jyiGmnZogTfUemjFN7R&=N_#7{AC$!>$KT`l zKHmIPXUFu?{yqAMD|u%5AF-7itAjwAjfDk~tRlS9h5zLR)jeY!9JBqKgr*tEP^7o} zBXL^8Jg9q^As%!)Q$}2zSV-;y-Vx)IOD3>IbsfLZyq>D@7>>}@rFh$2r^QmnZ?-1S zhuz85czg|{XS+j3y!o(xvs?DnEF@DFl+J~3ZclkRx_+|Lsb*Y2A_E<|)xZtI*HuFJ zdy-8=Jr6RRPQ4qYv7#1=R86DY3RcSs;7;~f&+{8Q4xz?Hd}?*h)(0V!$k!~8u{ zXS|ZnUw(%x#B=ejS0yc_IB@D1E+ zSghQ_T8WLVBACC81D1hw(inj((Ydu}b3)zsEI0N^@7BHA^N)_MyV2roEH6YPqEDHu zHqeL7%cfPO!~la~kbaqAq_i3uugU`fdfLd7Cf$aQbdU&5HJ=-AmVWHrWmw*BhRs9m zJw1u+dcB!3aNsPlF_?6s&cPKwdf6l-43&+JxG1-=M(13)?fD9gs$hF7Zff7e<1I^! zNnR}7Ei}216+7L+5OW@jD4Gb=?j_Q~#(HwjKr%aGo*b2J+&F`5*@aV)hAXqo9 zd=TE>uVqUmXi7n8quG&g#~GhS5#fJjvhvpzr||~bi>XSZqnUXU zUt2Af+oyPUtNF+aFeSJxUx;H30YjoIz#_LB@s+rple4oh(3UvJp0v$VE>-$5B1eO9 zAkPM;(rLhS*hg66kJlQ5l&q5jiTkB`sKqhmi#u9E?5(fz-@-kvLs*`Z*=v|XGwRLp z+hooSGIZa(jE@g3dE+0P?9vb{BSmJo_5CKCQI728OHy-LMdiNNi098!zI64qW=P{$ zcZ6@Q{+#-x%MC(QqmJ=C`m(u`%`%TwvC~RhzUQjX<6AmW87!FC5%Dl^{#({6W0at< zX9``iYEJlGBJ{b$Zk9=XW08A0;xVc8pvZE}*4;mWa*}X8_(!xr=!M zIIY+nBey=h8%#F(3axw(^;LJ#-60>?EtL|!nTOj=yEK48dG$=Fj?$j zM{KfCA(g}<4m~4ImVHR$me(vZ9~NAr{Wn@}bnnc@CZ5e(1-V^)-rgFRqw~EyM}1Yl zv+x`gjxuyU$K;w9Iea*tRlih-h~Ve=qW34^Kg!Fk=GQKs4?bA&HF~w#t)@9NTwyy! z2#N60O_4m}K++}odR-lRL=cfEZ%v6>(c|l{(+Phx^O>NERoH3qzW@GrYFuLC1r}uT z9j@~p3XqBy<-p{76BJ6-lU$c)E2aQSQ+R6=&CJcGQMyd~76aMWjcXi2s|_lHB{PYB zp}z-osT?UfH-t?@7X=bxfoTUSSPdh;c#?F1m2M~^eSJbyh1J_&=jzWQLn${+On$WxMYZ&)OrR z3!;hEOB7E$*ZbcYiHN!kz=sRm=$U1knG@*IZc7nfrNaahEv;CB8dp(huQwmpR(6jA ztwEW|x1cIP9LW6Y$V0)m$Lsp?^6Z6$$b=7VM@_R)ZvMTPh2o7G= zL{~S9!9mJnha-wc?pse$g(SY#>?4@9{whf0mInL~T$`*TuwFtC4e+aWBK5iEa(XijXMSKz&AAa1EBz|kCL*2EVvM7%BoN#5-zyv=k z{L=H~1_QGkM<1fGLp&81?LXYXfKHa9`06hbo=&mT*S>*rA~z_S`!FI`_wPZlU@~4QsveKDB;o@D(oAki599DubkW3Q=IHCEiq{B*;DlnInGz zmaY#VMMk{8@jX1%Z=dD*@RRikulaAkhHy#j30y5vqny?k;1yY5wuPj;dUbcn@^M*! zX4y_@v*FRjz`(%$;dhcr*ImN&dy;sF&rHNzh@KIvAIkknN)h5eZa9`=kbFeZ($Yc~ zmBwm-ux#vcsLO6~j#P z-S=rY>-7U(m%)Dja+fS@p1?OSP|mr2kBUD*d_p!F4NpL=qidpL^)5pD>r=5)eg{^Y z=VucBi?}f+nkadcg`^G(%A$~FtNH#gQvUSx@d;_)dWX{s06eNh9ySEb-Dn=G{&9eF z+Bq{H^&0X`Q$^`@NAy6J3i(o0=CXP+OG^sk?xi9HDMQS_@p8)1nQw%k=9qF;lALeO zMv8YZJ}BV6myliD%-E6mIuf$=ER$)buKCBJtAuOMuz}UDcYPiyoI1(kLC~;RUtH2T zYHVn&X0_im`FvNyl(TXqRnPX>@%8>aA=(qyOcF5FGdLq_ug?WxF{@J|sb2Sx@f{wgNOA&$Piz(@h2MP8{uN(78Y_f8J}7 zSnRzORzT5Hlw^@G3^4A`%hlN}{?Sa$cwdldO{UYX?&53H6@bKJ??T^eyzmW6V|L!^ z4_Oe4<{?G(OWJMBwd~lR=|Pl#()9zDX!1 zPV2pE+i)s9gI6uuvq4yG7#E<90`&GfP;v4x)UL4eX#3orY2HZjt-yeIPv-_Yrl0DbFQA!0A%^gdc#tzSjI|tp%+OaH(3F11hwY@Pet8%nD=}RVc znx9iDE&z7#zClKADamHTf!wtJs{E;B!PK>Dk1+5fph%D|D>U7wBqQ&^rm*b%^GMJG z+z84_G^!?^S1*pT-2a!cWf8d1Dt)vofe@DIl*e!3zsO~&U)DjbnHQTH{j8Uxh`(Bq z1i!UNjTkjgFNDJq)NV``e`f4>jcD$rMtSMJ)H;^6{R2K-|LY z>^&fzIB}Xfl{MJY!;BsMC#wxvI_0v>9P0fS zej{VF%Mu)v^PPWx-6ljD`q&J(WEd)%8yA7#N^mmb#qtlqSK=@jFg-pcRrKCEm zuzkcqxtlil*=sI^!qVpv5n6$1JHP?IuY-WYBH|&|h@h_J=+2pc%Qjka!4tj*t=T>D zZkrc7ZVyg)jneK*r|rj8zpnNF9R`ZDv6}f;PE?fz`&#%a`C0U#An$*p5SIH@4`M86 z`@!0xVNn$x;L5>*(b6KrQhPUodP-LeSF6b3`r1^Lx+HEK$bBGYU?q*`*ygDcDn5sO zyL!LP9PRAk!R717wjb{vnw&?DjhA)YPBHrDXiQ1adfB+rIUHP1uN&IZHFr24okc}e zz8`;9`{*T|H3ZS$c7-E|Q}w5jB-iu@N@)F54AWG-)p?4MFT_NG4o|>&sswG=<%`1HE5FV|o!R0rQ zFJ>*BW~y&V{s{jkZv(*+6zE^5mK!Vg;IqG=pH*l3dMLF}`{6D0Zm1Qg$gO5gavgoO zpwG-z>eZGcm_79|jA2kTb$ZCILnCznJYCDJGldt)>BQTiZ$*swE)>F>r&>)@Fy7ZL?Y5a6CSEHX5@8KY4Keh-WymKwN#!#9j4pNY z`3kJvsBY9GG%C=W-!4!F$I2?RlS(Ww@D$5DQ9SHXLdH}~4CA=X(oPBQ5GFd9)a4a+ z+&7gGwc}@FVIgXHoq zC!rM=9tPio)P9!sI6Sx?rE8T!33-=MhW9mAm5ht_L#?uc+qgZU{|Y$zHO`reV6s95h)Y>gHo8dfk`tgzXHLBhn; zixD(z$kL$*6(@+e0jX~dmU7!3t2?`Lcyd%hEBU6kz$G{oLHdEHkBWwNobX>ru zj{R-$XOW^eUzeJ0EKt)qVj)ah^Ko6%2E2P{0wpoqoR;W|o0%fzF0vR5cFEX5{>bdT zk~|vf#{2%r+Jq&ISgWivvZbn_!GBWZr$)oY#sp=3q5+6X^2yM!3n>eCj3-akJ5k)g zrXsImwjrBZ=Mb;CqPG`1JUVVC{gwGnR#*1}ld^ylqTX|%@OVK%9->0K3P!1dNYl=j zA(_~a5amM2BX&HRyF~Qn@2sHP89S48yAqW_S5~-2hF!VfQ&TXVnR8-u|D)@+iWV}5 zI|o13YM#?jzl~!N7pE?1`VC|9@qT>Ed8rCK#~sXTK|P9*BkQaRN~O;xkhxj>@TV|y za$w1hj*fm#)n8fePMNC;{Qd{hpoJ)c`5kO1OvD&u-hta+6jUi~M5$ui*%=EcOnuKD zpST7Jgr?Sa{J!jHItalR+|3aDZcQKE?ft9nWv)h-VVU7Y7_A);(T2qrG~MzBDC<2e z1B|%lHjNzex;h`j@ z5f#;Ns^0JfK&0|eAvx*o0KKoQs3?IW6JU(zsR7-?jU)VdaXJ(i>IR z*9_Tv7iI6gZyAxDP4*rMWn^AtD`Y1lE2FYk#I-kBA>!I0TlV<9E}!r3U;o^<*Er`n z&w0-ClKzL$sr27>nUehR9`_J)KPaq_Nanr3Q;Ng3F&L%zBRhIE@FNZ#63jIC!5K5o zyegQM+pN56?PTBZIN-vu%E>o$c*L%WoQTK{UFz&S8b}*-3EG#EVJTgtArQ;BFY12u ze`m}8?TPN-0>Ett?Mo>|z#Fy{b*%H;aU`xmV?Lg)fPsQ4RXo&#oNXb7;BkcHsh?lExWN60`7*0d3J}qd zv_62lA4l$s06&YJrNzbFgV$YsZrHpaur{*)s2E5Ri;r)S3;Z5A*u<6%@{e55r^ZVf z#TcrB@;}r(*Nqm<>;`mGK3X^Q%v#v14-FL%x)V&&mp?mwo=g zKNDM%U2azXy7>P^Txi@(3{#3U^id_> z)-G$()RolL5Y;xm@}5&xe85;)I3aW$htKlkP3;CQH{#P>Ow8LK;) z{hJE%@=ja1ea{n{LoUL>b1&WU@G@^#BI5>;!>!W}lY8cXih$k2Xb+gZ<*^~RcN7wN zcB%g`u2vI~3SIDe1*%R!9*1G>+tQK-8QxG+TbPa=tT|OWikh0)TQ6*aqYy?wVV)4r zEe45;8)1BR9vVM~q1a>M_mS8*Q8n`z_eeze@$m1&)ztD>i=Th%0jIOdgs@TVNTWUR zl>FvZPo2e`x>|r+2HKq2IndgFTj5uib<`g}-uW=Dqa|gkffj-nu@3<@p}YS^I_lOs zH*SAzx#p!bVb7t@RnwyMP19dTM7Rd1|1@^vO^W6ES4*#9;+**Mie00P5Q38^_M-Oz z%*B35G+4`>(lxnFX^TLX}G`rNoI!z$t0_v_+J0Ji?c%D-ohiY|%TH0Saez1wt?-{tl_?10oO3bq}9UcP&_jhaW{6*gk0S8akd{6%uf^&KUc)4J>+IgmHFD6^cdI4*4kR^AYOgB z5(z}e|FtoH)Kr6+I&{gr2M=MuYndobJ06IC6={Ck36mf8NYP~*h^6)>^Kg1wAk{%fn>^=Db?!^;J zQ}G&@QJ|kJ-5X0U4u42P4hDX=(*s>RB1K>442=<n3GWquR{ z*pSPIj47!VG!=dcLmaJdzjFYED5P>KX4CjYu%%>2V&n7Z_{2P-r47J<`Tl8@v6`wX zGI4Qn?~Q>Ts#Ao&gfBK9J?^m{GC9+~{Nz(sVvtf3Dz$n)gq<^>nx;VV@usA-srP?V zoZxF8VbBOa4;B10StywMyBFc)QZlEW?A@@Cm+!*&c+@E!Jz9_iymX;v~HpAo9oQPm^TK?UIQq zj8F>Dn0TbzmlTR|&{JmA#5K`@RUd&4xzhXtLM9K)#UkzqK0iu!mVk|kd51Z}4n})9 zfP^9Bx)ZwOWdpS7b3Cyg5(&K}H@VT1HQbrS|9h*r0nn>B3)LDA9u zX`+oJ^=qKL107>M34G4o7ml|R+_Ye%&;_DB$*pgcsFv`M4k@`+9NCX1xWT|Gm;1uZ zn(8KN8~!y~f=xhqo6b23nl2cZ&+1urckSw4^|e;}rQFoWK<>lTO33%@R2=8xN0O&3$Fb zM#gHOFzo))m<$ah{WEeQa^Coi_Mx0y{mc&IEMqU)48U5Vt5yt%fk0WZ!q>1(iAc8j zfP$pBMQ(86N}#Kn|<(tU&1RI3*N}$$l}eLHyd*JI(PuEMi8Z z7D(I_uXy1twt8=!g8)gv$pZ9XA&f`XW5W$uMczi{o&B-9lgF&Y)YL6#iW*kYhaP2= z#iFT`;pG_Z?bQ4@asH>GU!i<@YiZmlFg%X;)MN9FnClJ`;5&5~OE%EVs2lr z@ap3VCTMN}J!DW-F1An>9_h|^#5rb`MSJ&fugveK0mnx^;LSTGPENcHz0!wW1e^Y5 ze2PFojmLHDd?!p+j7Cdq=FDt4-_o1x$9IT6+MlL&Ra8EPuV9e8qd{mP;gO^^Li&;^ z&}6>0WEbkKC$tjHY3Ps?c2_^YCxTOEzjF7F&_)}SVEy*J0|UCYg3^0C_P;a{HrJVW zc;Q|znmlSrRLJmf@wC1?#wXZZjWtS{b9ROuLI2ST%jtQF*j;TjjewtBr_|I#TUxgI zn>y@0UvD?Y$j5vWHBImu1>8txQ>Dm>iRWkTYfmIy`no@foRMN?epcEt@>TO29fS>A z9|QwI2zs9zJMVBLe01$~ZZ@RZCXZQX^sLiOR;;@5-t^Nc;;y%b#3UsBgv^2Ly`c|k zrKDtBxH4a@D_1ARxM_mhLzyfz7Y^EvmvmYt9#lk_G3-n-f|QaOV!j-ssgVBn*U&)c z4pWoHPxZp+vLAdv;$3+6KGwW&(9kozK6=v)wOo2PNH$$)^i2*fr%Tx*$pBQ(JD^MQ z2j(E3V++<;I1A=g(8>qYzIP5J5!KP{ZYL2<<1DQ#FZ^hdE+l1K?R!%G9Jf#p8O15t z<}-r}B+$R8sKF$rITzY)nm8*fHe=%v0sYWCRdB+d(MAn4oN}xD?216HMkV> z=a=aSW1oLohg$?V$j`5vf3|@cBDdVmvJ+xhtA1`nBz7pphjfA&p!F|}TYw-;0b|F9Ro$k8bWA8($*ZWfN=A@jes)JUp zR-v3C&x2ABX&+%yu1{j|nJ zTab+vq|K`F(R9(a7e5pjJqW+fdr#GF+G@G1mK*l3d@cNTab$FmCL#q|s_uvWT=f+x zF)^^u2=PZ%lXZEZmp2v?>#LfR~JS+K zRW{3FCGKozpD+)KikNA9N+(@MSzc`=oO!!VKN@x=iDfbH-UEztEn_D)lXb9P4lFNO z_7!XoHyUbRM*zgeO~rz~rAZ*XNJ(3|UnvJFV<>cCzrsM=cT2|>b88|02KEL;;Te4C z8ZI+b0b(u=Ns%2JE;Ped`n0v=p*Km@PE+oXY?1)b)y#m8Rgl!~QQXFxq$j9y9Hs-Y zc*K}k(vWy2W2$tsYlVdf-HF-P=-7lzEG&6BwR=9Bcz>%5xxZ9r zg?R}gA+URmizErya-AO@&-5A#ab?rte8>pVSn-dUm3}@7IA0SrV4Hu2IWg-hcvt+z z{Bs*(LXvh*=*8(lXFoM#aglRODAW{%6driL6mDU5C^!Jy+_h4EL^qjF|E8ly* z`V7pL_r1S3zu1|MeEG%}Q8v!D(`~iL?>i_3B;qfkW1Gp8=r~e=H$exUtiq9t$+&?G z;OAp+HD1lXRP{bJw1LN6w^xjah?;AMz?k*SXKftZrJxw2Lh5TBY_>2O!+A+{RK4)5 zKM;YX85;{JS%DF4>yL{A>~hxKjJkWCvjtjc%P{1*AO80%8P!)-If|9$la6HeV~ynM zSrP-!WG+97St8YvgI@MMcpVy6RPGlO350+4v&HlQk|(sm!N)`c%n0X1aD^gZ>goiu z-kanxRQ&zSo0VEO+5Ib`d)SIe5Au2!X(rcn%UVfJ;7d^@ep+L+@(Tz869I139mwsc z_QAD|nlL)o7fX}dwurcKwlceInWs~`j`9k-M7hmBAK^EO(-8;(=`Zbs z|EJD9{`lKY<9lPf(glOoqlAeAc0*unmH zjdV^N4v5K-z>-4DcI zi7CrBF3`?*hx)bZh}X()fhZ01h6^acuN8D5`i;S?)Mm&L-=D!Cn&`~=V#93ZeG#!& z>nyd<)9|~IV{`Yy5z zn{T&Tzwx*5*^LmH9@kIGj)5UyiC% zRUe{?gP`bv9nagi5z7Pl_wI?MIfMee0hXY7w<8(RbU>B!i+gwPwh|K|j>gTLbaa;F zo1__KpI`F67g|}D6>bWrPS}8A6EHkU7S;b^l!P79FxZ3g;9x{quGk2KjJr=_f3H-z zK1@Fn;7^UB*4=E6l>=~a7nZ1`$7^QlmG(kv4urN4Ph85H&AQPblsmmH%N!6`~GPhcY*AZUQv1n~f zr@GZM?fl*6o&S9#EAK5i^Y!q5lt=(aO2X8z&7ZA$<7%-EYCgFwS= zsjn1R$@Fe_8S&cMEUf;$>Mgw3WB@A_6kh_Fffo+n2M_bbC1t!Zt8rd%wtn+d^NWS3 z{V%B9(1&F`*p(*Ju4W4`UeWENFlb&eu1=0~)5;!!_WVm{;+2h^zS1#@69r%4NYp(r z(Ds_ObH1mmtLP40=S{sqLw4OPF#*kzoZR`LkU(LB2cob0r>2xe zfDseu{5kod-DeI;DsdltnG3%=t*xzfW4nxwx}I!1jZ=cdrO%%y=_kx<0Xna=@lfKv zhCeOw{QPo5kUlDPY8JtdWBgA0sXtr@qsME-bG&(Hah+1(Mqm_iL9{?s0Tjp0geBEV znQv8Eag4v&eEZbE|L}|s;%b$&*w2oQR{xPU-CCQ5m;n@@e;Q9Q6 zfIX|K&xNp*m~+IDq+RTFzQ{HVG7CH-XTSZPeRTnIXGV13=WsP5Urxlyk$K`5^0y5L zN3M&$zyV1>KI}aH`jbe?BrU}|#{q@;vav_LR& ze-g7=KmMytCVhNF^-GHbKM%NH^^R_lJt23j-lnJ9ya3x4o)O6_(VVID$lM&Rm}8sj zNXf>=1rVMGF&WisfEla9HxiE9nc$#Y5-!nin>CrPR~=*3HUIP#7ysK4+GnGG+z-V@ zdvqVqYJjen67u|H-=Jbg`{m{@1qH4D%2v%>_^~==N*pkMfq}hlD5Y^)N=miHuc5E) z-+yd|we}hv!oc9+J zmxljZn`N?uhzE6t`lgZ3_5C*gT~6J>A+B`GZVgF=i0vt3*o%s-1&1jceKT4~;#Z-St4r-_gHS(gz}Q41$t z>uix4IdS)9;?rDCW>_;e>a+2JW`ecZj%o=5p_z6db(8AjFlPXgSFveCPq_+zQ&+ zqrN2@D(bNrWYTc7gBSZ?W2lNf+balI^!29;l7b?5#J9NrhGplt14_IueqT`Hg@?Nd zJKsA$aF6Cv{w^@8U7t9IjtNAk*qVLsV?b4g=^BFFU_Q!00Whedx(iRhRK+bY`l18o z`qfmRAlqJ>i8ad-DtuF&PkaEFsDmvJ&J}+t6%`xX&sbzQu|;nqc3gS9M9eqS1TbTm z%)P{Z)OtPl6WWw!&g-MQ=BfbHZ#ep^aHc-N#KG~-&O#TV7M}7IxDJZ0^YQBDwS&`> ze5b~xci>6UdB*kUfa}Bt1C~#&$B-i_-B(3IaHLqHfRf~QiEQc*>acD-E}k}J5W z$dbtI$36oHDl<^I#er9taQ45dRYLiZhrdNxLijR+< z-Aw(Ciitb#;K!<53|rP9b^y8Ilu=31xZ%kP|SW8RI zk2ng$FWI7cW-Yqu%@|1ajhdUs$9c9D&FyN)@8(~A@;p{iiBCxh2Qrk7N(~K7r_>k~ zt813|YeEFD+q5w=Y2x8!!a{3DkI>^bwp^587E) zPN9k44Jwea&sylRmt_Rw#d@5p8I3W}ElPvaas9fp**g)DZ#@GSol!%p@Fcr_NlS+sB6a!~$I0xOqbMQGY);gILBLww;jLVexul&dOYq=x3>EWak^2 z6BYu`$7pUlQ&rT00Ff%ya z3Ifw?t(#s14*`D*3^aw_haR<2gg}799m-#A{?q=CFHV%(*ewjVd0l_2nUn`!p;n*?%L~Q?^lZ=ku7Z> z6tp5w$;rvt!_hS|1a7s3%V*m!Y}5}5_8|5R(|H5Mu25(vxHMOlmFs5QKeh>TnbX@5+nMW@O}u+AW{6wr9F zvh=tLVa%rK7F20B^wBfpn-rvO;bkK#L>9tRakTH<$HG3^8neg3N7=@KQ7_IP#U|Kv zwVBAg>R#yj9~tUn*~2Y#sVK)y^y9!9YbWT(gxkv9VLagF@OJ23wrnVeWy9UVi0^kJ zzJr4q^<6*iu0AFi``zr3lI$E?Ig*Na(-AMxhJF7^ob~E5|4-*H7#SLUde1Hgi7NI7 zKL~#NJozs%>d8BQ4lW3bMI_zS;9ZE{f#j`2_p~R!a0_!PNURj+BG0y{nN!NB!do$U zn*IV?fJO|x65aVU7FNHt?5*{6nyTk>6nL^(;Z;>*OBk(&!pu8Ut7gar72ZcaKHqHJ zZF9hxsKJDy5&Itg4J!>JJa;&IjG|ZJKQR~rUP@&Ktcbf@(yRcA6KgVRIjv$u=6B!tMdvqTV?tE; zSosCo?E&Tk7M z%)-+om->9x{FuiYwOX%&yBa!@_{@?M0fjkBx6us5FP@X#9V9Fvr7cm1ed}S9zEy2K@AquS=^6LC_wRcdD{>A}YB1grY^qm(vOKLia(jH_qV=|Wi|p70VXm$) zTA+5knn;NW?lL=CY*z@6iGI>l{(S&@UyT}#}BInfq=rtEms9(xZdpZ1T;mV{5 zx>6VY6kR!<4s6@IMTQT;l{S3|?Qj6v)9^cl90%Z$NPB%co|5L@6L zUj+O)@TrT&ZT;J`a)Xswf+*_0Xc=pxlh!uqj8t@R>ph_Sqxa4K?0uaYBIrsNoN*R2 zChDod2@K>fmhhIf1TLoE=AVndDuSll&ivTXJG$GS^g|GwrOlDUUa<;BMl@MGZ-;{) zi*f}&N6*W*_;t38tYY}oZf{MHs{l-2c-lkdcoe{$qX6j%T(2<9yewa@tzVdd&+@~_ zZ`{#5@bGEfZp&l{#@dY*`KHMYsUw`W?oN1o^fK==z$=3gISuo5^#MA95`yM;MB~uP;(|&k?7NS{kBwJ9 zlh!HECvTl9pc^IEKb3s@JCS?g9ym&k)@@Xxf~?zjw8$9obMexPbr2i>?lMJ9mS0dB z^xG!c_EeGF<9l|BA4BJ%y@SomP)BC`kNG*eko_cNbS{vRHRGkFGbwhKtbj6QbbS)Hvhlxwfuk1_aklua~vc)K8@YZX_WmD)5FE~7P(3aM6bhD zqH!6bEO9*F1VQj1{IHmSh)k?UKi@vYu_wMTpnK2*9U1Ky9~b^J`<+%MYrp)Rw#8oo zV*Al1W-z(m?N7N_#t`U7i#*>yU93(qmH&SFZ-I|ATqhT?_IXQd&w8AU4^`+I{Om}| z+e{W5Zy|W+n5v1XWo3J;Gw2Nm%hf`NhG0LZ5%%XK<AF+;^W{D~~Lj{TaD9}%)HQ?Dt~ z-m)mPIE>%@!PATfX6^cFAq$P!P2avD@3erA?n<=FTByNtJJkENljVPj$&hux^7D%^ zVfr}D`F=N{;$vflPT*PH{up*@SZg?Xf3nfy+2^n&vFrO8Cm&Q%Ay6g$Rq!(f-khu2 zf<(9TdeWBV1iL`Aa^-v(gef6UFfL4!{A6NYgR#2>L zMhIuv8>BJhmO($V1}4K;TvF`nm$JC~i*qQ~WV+^7YMOTU6Brr)N&PDS$<(SF5)oj) zr3Z{VPsWM0wt0R2LoDIT-^H6zkx)Yd-Zw*Fi7my%QYW?$DV(YCwgvsx(j8& z@PK@Uue^y=4K!A^XfWH7^=`L8cto@f1x1^3Fe08%QUCTCVP^Wd4#{0)q9cj@=tt7S zZCOYHyMmfSj|k=3P-)kqg02U-Pu3KkhMG6s=C5)hrfJM*H}mx7>EKl}Kg`hrjqnz8 z9ENqCi@~-!EBpcAB!kw0tAx3q(csx)W?VE$MkKX^mbe zgGW$rkxblMii-u8W6vrVny4*&~J?VW8x1zzb z7f5v8^Bgz}k}{M)QUy04JIoKm01`K3ME8b8a9Ug$L$QxfC@c{JEp`GA4I1@Sw$-ux z{vD`#5k=6?%{{lB9}n{KcDUj4rEBw|P^p$mX?5v*$;|gcXc>~rtP=Qxl-NPMDO??b z+L>L!q0#32#=+QUG;b7THW{&<2!LZyp^Euj(}lt1_}vea|1do6bvj>1MtLSCthj_} zEaB>EspsmGl7zA@n3?9OG;cVC%#e%o~q;j z2~>ZVGhY>t>wLDxijrY^UtKutcuTi@SIBo5 z%@Rj-S~VLHh!#qV6VbU=$LhWP`~`hMky{Z6^<&2mHa0fn<<#-H?Tl13*Qnt(#H++}!5-#gq`Od6|H11N>_q&Wz zxc@|{KH-F!EQ!}|H`@OD+IztZ{Z|}2qeIQe??t0KEn^Oo)i1nu3YuRQguNWi@;%#M zKvnZZO)v!oOz^Ok>5SVn_q>FchXsPA9i1fY~y>S?|vs`(^IFD>`PaRl6 zss%Fq>2m_8KO1%c9jWowHw^%$kSl9{uorP|LJ?ok6EEst9)Ibi_M-@s@5PwhBK`7` zvO!(zVYX3BJSK#?)JL(evFRb~DbpemwNWr;Ui#}dG{WsQU(!jX1V3pfz%CTkEJTdG zl@j_X#a`ACWVOVr-!`AglCn)%|oZiBssnrO(7PuD&tY$ERC#ib)A@@Sp1 znZ~1dBAU-tPg>~+>7&`$ z6f=Kx&jz(;MMZbBn4e?Pv17elON=dfgx|GeaWzjW;$|=}?RzvoTEEZdHTcx8{v|au zAaF-HaIMVQWt$Y+6?Ks`k)mj8n?F~m2g)5bIo@BVMEFAtm+y-_VC4C%W#}DHH{Q__ z?8m@q+~)B#NrS%xqlEiv zB$N?Rwz$XW2FJ^m{a2QER{AgSUA(AO?`yj{F|Lu@u7%(q9q11S3xa`bSPgV!&TYgP za^_WUL(7bQ-I)uT!<5Oo!sMazp(v|;YL#c}B%X}H80Hv@(HnOKvj zF;Bmeg+H<;Cks(7hEHsSc5QTM7>j%a(k$gSp$VMY=164p&OnrInL&TADl9~ckq7HI zcp78;r_YbOqd^bQhq|&KtjNj8uqDL4L{#Byd?{{(X?* za{NN}>IdBvs`CT;jF~4o>$x?9+5Ac1r`!uE6xt<=C`W;&xQPPv10T5^HNyZcBq5Zr zF4`paiTo_;Ncj4{Rb1`%bU{aG-yyFs-6haIMX+RG$E|g@uiP$Kl&0^}|A-Ks`zk*d zfF75bIru4qysqg{%`IFCbZG_{k?U!Zw5x4t=AT!cYhr8dUvc|6MD9GFsvrl=74D`J zTg)cIa%l7AH^JjO_d2W}Mh#Q>ZG@I`c6Gkbz5YBsizX4+yi#FTy<57`69zFmHSg0xo z4VxonE{lyk?gRW;sAfK~^?R~;^vzh6PIZ2#A1Y52Dk2Amt#(h-pTC$39RF;OPf8s6 zaqC@h8b4jUT!%7 zn{{gLB|8sKOHEc_XU#KNi)jtn`EbU7_Mh8<@~=+rP{k-x-BzS}6Nc22@%tt#GeP2x_U{!{ znGwZ5vpumVWO1`(aZPq(<0r_Hk`M?Q_1hKK8t2Glaq(`4G}3eFS{o6d5POYvn_>W^~!yL){f61A7(;-$}bY9YH{LAZ^qEk`9Xv56iz>Js?RccfUZ zRVWjXik z+{bxdSVu-KkZ!$eb&L0~Ew#o0U#@i3rd`qo(JDpCv zB^;vnNzKsKRsyf~v3B{8#{wmmFN-vpe(z9rKnSiXBifFx0fvx}BCN>6lSKJzFd2o*8!= zd>=d4^m`TZFdh6TBPK?K{&^spIhgbZR;R(lCXJu|I>Z9*Wr<5u%P^AP>vxcw)pqiW)R=4EXIl&c z2C)de&Ha#*_o_2TW`cN(jyb_%6DB&|0fhro>N2SKYscLh)jnKd!;0}Ty>-34vzSuM zodH&9JFs)H@~?O(ecO$EIF4G)(O~sX*nkd`f-rphh!l=_^aoAr^?`*W ztT`a{@N#-LHQ1_H6ZzoXBuw9h-kN9|f&D&6J+)xP+3_q_F@Y}mr97pCn65EEj^{ph$w%>9F`-0PReSj}v% zIxq>sY!t-Qc#n|QeP!~RWoI)=S8U_MrBbO`mh9h9mQKb0{e$wHn%deSXct2*zR#Pf zH#Pr)jxg9@EgaPgSFEq}9_SzqKPa7e#81*ttb?@kDld8S_{FHa5eQCxY4nD#^SVT-U2Dct|Ns05kQILUqL4Lf zx6oF!-NPplh8h%v(LzI~@rF-cCjjsk_s()maim{B3QenS(&PyrXQR3^H!Fx6OI0+) zoeMYh9`oNp7Y>RYZz;a?ezxN^Uj}6Eg2!83N7SP$TB0*CpexCQbG~s$?$Z{}}=i<;#jJJ%p-Pyi?)dMQivK2SQScqYfq@ znDHuyK^7h9Q*176l@|Px&DBHgwuI*&__7&y)bbBHm3-)1E>=Ge55GOR{EfaU)aHSO zbSH^p&=aqpR!%+ZaTX8lFu2}SMRO!3rPb8lGGImha8w0L81!<`T4F`=^S=g{`IMLc z#qe%3@Khl&grynQTgg92B{F<|_@olXLE91dObhbl`RzKEESmcI;d0B%sWShh@ujwBsNVEijB)&s zD!B)}gv2OrT^0Tmwl)3lM2X{ge>bgqK0%<;{FEu&l?okoVFqwM8`R_a4^l&X9XVpK zLTvYJb1ZOh3^sV&GsqMPMUu)vJQ6Vd;41gRdigMniHo3?aoR}^b_&0D@vFjt-pJb4 zk=enPIvz1PBo&Sd5jstnMDdK0sHP_BsuI12PprzBy71`vUFh1=Pu>W1awy_zZVft( zGRTq!LnBpIEa=E9$jAeyfpp=n zp933~e0Re&D`DD?2;?J_=8YkarnW2pJz1nwj5_eP1?U_4rAm%;A3lH&fhS|AuLnrr zKE(tXYvxc_1&>h=c-U?&w9>Y%w{})gfB^Bck2Jvb_TJtImy8=Nd}aQ~marNRBTp^} zuqCGspDYKv7>lG$RwzReeWgur8@k@g0je{QEv7Zz1eJGCkPhstLwYYT<6mre z1!U-G&2x-WWZwOMB;Drf%K53{<=UUZFqlHN2kXB~=YpO`L1JR+r*5?W{dP872U2L( z%uw^}x9WAqfrKhjO*={lp zY#KTe!fu;DJ&hMICW29ka;GM;3mPw($kv|=P^zA`SQ069`>D6Jb9cwhuzUl$Y>Vi= z0!R>&WJ>#XX6EM(o@|kjbOAX!+8WG!?MK$YhCVZAi2}aj5|JaB*k#@p8~YSm<<#fS zgVY=ETCmQ_WFS)9ue_zutR$Jbcaswq?zkcmXjN-JsB@^0ADed}dPAvq4=jznEar#S zl_S&Wh`|b4k4W81TsIL2|lbiw~Z83wNLsADOFY)FeKmIBpz@tS$b$CjI9^~Xn2uuEbzuGz{ zPA@2NT?6P?<+%%*FJ0XSxwW^H@KMb^Eks%;^ZsbGCX55Bqp!bs%#*RZ+>QI2k?quTbTFqr{~Oe?u9L|7CV*u(ffihv(!Q-j+I+5X4UQ*xZpk&g&rVPS)Yb>pgMqeh$# zfSFcSQ8kn;mgTR9qt*WZjv(gnz;dRKhXrTVyu0ZWS+bNlP4H9=$udY}Fx=OE z9HY3*2lS(G#>den^kb>CFHS4L|4CDSmu{*a9b%EGIAZgj7#Hx#fO%W^#3?DbI}UA6^Fx zeiHj>K!E=JO)F(>LgYQotN59NUQueo?qM*MceWiZZv~#eBY%^%NLezDQ!#SMv&a1;0+(@+c@ih+lIeprmBe)L(s6oB;|i zk{9+MlUqSoKS&al=#>TyI4-XWzxm>SyoSr$5RK=8)6D40rUfqMy{|^E`9)o3W-~2! z&mm~scjE7kFg-U*YAK1jdM(x^zDM7#5STGAOFIyUpqxrD05$|s#_dbYjfiqNNhNx zf)N)5-cia}Yp~#>n?MAM!OVlgE>8cIJ=<8JitR^H;JEg3*<+iEpB6PAo3G!&iO7lg^~(sfC8?%sTyQ^Pr`szd z)1T|-Ja0x*N;rHkL{*h2@d8zuqfQdjW3(a&pkCfG);h-zab@dnX zzOtInpT9CvPJb1~wlld%%D3C|$wEUdG;@9lkz z&nSaGBz<9xBRwgv0=*cbjR76t7Td*9RwE;?l^cNvS%f0e6)jsPV5YTJHP_7=sGDHM z*L3a~qYs9|2)cpK_nLQhHN>|fg2i$^7w&9ENK__pfX0Akhk#8LSO1}NHhs{-J9@Fpc9$P(2U27Pl6`}!|6LYh5P{)g zz((|JV1t<~|{4ssF<& z3D6cOEF|psQj!89^a_p70k>TqHr8JG1*i}obn&pZnynI2K#moH;xI7qy(sHvZxwOV z78!xf)#ZKe-D6|Dsz%PVC%>~ZDK!0SaTjv8%x2L@$Z1x!l0fym6e?&p(5b6$2D&&X zkq62D5HP50$N^pf+NaiJwGFl#RCvV%0<+xNTUPTqP~5mA=__|b@4j}h>A*}0p9#9H z%MD;daf)c;(tC*vHGGfOSokDUW2W;L1vD)(Eo0+opMM+kT?4ch3;##eS4TzJb#KoM zGca_6^hlS4gp@K!BOoOWQqs~$3Nr%IEeMhpQi6ael0!*IgM=as(xMWIH2lu!^R91w zf4J7Ocv#%`IrlkxU;EnE-rE>y*-UXNxf;e5j2ymv#%=WD4ySIn2!X~Y+#zhFC`8(Q z0%>Id!7~z^4xS64zxk2b>Wvrnqk9Z$OO{hS%K#pI5=dP0MeLzRkl@Q1jT6}M(Bo4X zDv{2C@3SA&kj9-LIFCiV-dXPykvEV zE!+Pt(6Kr?l&DyH@%_HnqUE>0@B%lFv<}{WZhpL+fp-xu(AVT4i{?e4o10%Z_*iNs z&uGzu+w1C(+j;Gxl;Wly?bo=i(3*Nv1Plu)FE1ZG8YtY~tX#JQ-Nw#P62EIjB+e4m zU(HmC!nTC}$tA%8uY*6ab&s%mP#5Lc^Cgz~W(4D%)*FK#cqyRJ4y)(g2(#GH7(E#j z*kfWQ`B?_GdbdpX@|T~fitQWj&e-O`BHFkJnE}aT9i>YLLbtgkHX<1s?0TQ?`;it| zF7W+x-aznDL@>kS{K+*TMDq}QJ;C$?I!(M~M_413B^D%e3M<}U<6+0%mC-mK1V+?` z$Q4YRo)8RFWHL{`1aNd(G~2#v1vA>2urZQ`gak6(M_Y1)C{mAAVm*>+?enHJXg^LR zTai^=wR81`EW5+K28|MoNRh-IqSG=v&7>O+EcQ8YMA zGCW|R&e;mbYEpjr!=&6^q-`(Wgt=}BVxE%!{B>Xe#7Y+9FC5Tk{;%(zmpE!e{#F8R zXSP8oI5^9;`UTDZuo^2NKp)JL?Jn7^kP-XWnTDNd-|GWYe&~A(kaE}3);>>;xXMI> zUHyBYg4jj^ zel1&Uu^rcp{%iZe$}q!bu`7e-5d3q3GeFZ#A8hC^1^pmi&%a#Pr^Y}Q&GYJ`&G&v1 z)aA^6ae!69O|@k>6UO)6`2%|ut;>Ma#4T>4L)q*;zWp%rMla8&vGye~T#QQ==D#u! zGw2nI^@h3Hb^jeWN%(e~K#Ibg=OW!xQeUCMHPYbX%@=m0@T-aVV z?>w^E=EXWW_wmv&NP@MJwXub{s$=F2U)PQqF6Dwkg;#?!3Qy}gqnH^<&>9&7 zdrTgnaLW5#@Ip+t!@}U%$jtQ4E8Nqc4$PaNNNwK?fc9W)G;dmZR+BDG^th_~fCeC& z73tLhRON1oP7!W5?Hf)d*+G(Aw72C|IMHW7?pO@Vj@`JFm_DkHFjLp0s36OMn0@-s?KY zK7ZSigyW{;#3A4I!(*4BN6EBPDbd{yl$?IuW;P-5f6W2N;qssuAs3}M%-cd^?qoQZ z5NyXON@A-cu_j>MZ`#vz?szqewiP2bGShPRXk|;WHg*#Dy^&7|n(5xo*}t3(aSsIV z+nG_4!Jl!X17#FAgV?hp>$Rd_x(DX44OvgMHh&Us{GNZ?2S@wuw!e*?Kwm^&a3d0! zGRweQ*pnwUZaeE9`4EG7YrmD)E_f=x45Cq+HM0B~YP&%-pezjyWQIKZ9()?;YIZg5 zB?trRAPY}u^6FR+_h48wgrEdCdCf_nk;)D5;;^PWKRec4{&fGm+;s3wr21cuw-}=V z2eu+{fXV#rAzQN3fHcAHu`@MnVl}tEKUhtFY0E&1jN^KjNFJ*;l5Qg{T>KM; z(O{M-bX#3olKvGR>LyZLvYj96SaBV*z zbp_GciG6x$`CsN14V5Q94uhgYGZMMXmYX989BrH~zWd?L?zNi5G{8>{E2Y!Aw@isW z#cx`hn7lULpczmOfS#%`HZoeB^5c8^n~?Y95>X6DGXjb-F~JXg_U`Vap5yWgdNUP= z0~4*f_67I>6S{2;Nv@P9bg>7Q_%_)VCFFLMVqFQCy?f=+iDVVKFD39$=aMxp7)$JF zA=DNeg0!KVed^y{j7ES16|nGBPm!nRApiBe`Rm13ZGYh3zJ0r=j@eGVlJwc@opu;x zK#muiRblG5rT!4NxQla;{e`Yfo0$F=%Lx{X67b?jZgLN^yDuwoEQH1rSR_1K%qry< zu?-}#n>BnS9;8#v&h_IC@@#gH?A4liG4Ju1IMPm%VlR8PxaZq*$2Qc`O=_Hz4i-R)eA((~*E*)30nE(0DR&tDOjSYJez^wy zaLj(kqqxa~ZkBK+@p9L`_AKh*c>xSN~NLfqTlUgBFG?y%}il_s-^X*BK({?@;Gq%d!3G^Sitz56p0$ zvcFa$uTI>M*S08t+T3|(-E(FfW_M?QwaxJ@K`pm8UF70-I=(85--O!eVT1VmkzVt33G(MGazRxi71oJyP z>~veeVee{9hJNk}HSE{VK{F zz7>o@DpcOAgIQd-D3g9EGfBU=xtZO}<}%$cX3^*`&Z;_OdmoeZAGG`j*5m274#Rst z40b0}x9QA2%LmP>iqZLq6yI#YoHE0gXUwr#d4&+8`?~E2T0tk-ncEGmV z;i*4^A-AA)8NufX)5%#wT;mzR@Nh7Qj6f3A;)Gu8c2IwQgYZ7x2v8uHku`XBW1>yV z6SjLTLR(FQ=#~Z_18VN5AVD&ognorIAi(CaS8iY2pFMx>#vjDb+Jbxb zf?riZ(ERYjpl3E2G?WSU#N~fB6Wf5)B5_=)_jBm3<@04JiXw0-TF-DSE`QorHs9cY zx@aYmd*S0Hvt+^jRB;jEPbIArIfk|1h-zgwC#(i8$;GO4DGKYSmvvhJs|hB_K2Zt1 z>uLR#tgNiew=li4LJwaAt}&5y84+|%?tYa|VYxH!#N%kZcu5i5 zjB?iSQk70(${H16*!1mms_qC@#GQ#qxW5B2g`_4wjSD(NCeIyg;;II6X{qCib;T**3dS-MVgru@DT3x9AdV6Bd4?Qm4*7-8g=p}+^@~4eyvPysb2eW4x^mRiTrhcP zf!Mw&gqnPEU;V!Zi>NY~5wtjPV{-pK0`shjNB}Sm-1H6mV5B;9)HPs5j;MX%*k24ni0{gK}V(r01dRJp_C2ukJqN;SN#J8Yp#?Hc0IjW@oQV@5 zp_k|3aqlzlQj<6D&5;DJje^d~9+yN-$&HdUuC#O}{tFU2=x7caJRo$Nxb;IuL)MVQKO} zEKg&Mt*GVz#Nr9_9mTgN@j{h%NUVS=D)6J%;ee7MaL~LumW#inhldnxNeqQyTaU)~ z>uGKu8quOZQI+1_Fg4%(vEv%+7)f@lU0mKsEZ)3N2l^>9exIomZ@8S+_n_k~EV$sm z=YB;2$oZ-McGRtFOx^YYf5lp;H?XNMKJ+Db<$&<3porSxTE)lFE=Y7$8xynVh%n@r zem=zeJ^zs9FR5G3t2R7WmkOO9wb4Bxku!q3j+Zl2{LJd>4f?z;B^S%zqE0c1$ zRJdu;naGubf3+Mh4`u-F6o++CK8i)5Ct#Xyi2B{rV|G1S7us=#iGG+!`kcL)@Mh&e zVIZ1k4vk9hhS-Yza~{}pAR$0Qq(%kYW|xiK((a{&&h_ve<)0&u9-+hgY^;NymKZtL zYBPf4RCfF+fA*iwP`1uxvW9`MzR@S@Te=tqV;#}hRda@YD=bepM&5r_rTSq4lpjF3 zwEzVq?96ic7QsXjuIvqPk^|O8IB#A!{QSG3CS-aQXO@ZW(xMomB-PUu0XuK*HpARGz=|LMon@OwvOd*)c&t`1DY zk+06|aHtqf?1<;%L(Geadfl(^0l&)7iqWA|mQvjFqwOHkNiOpJa1D6N(wAV+uwISV zE}8j-$_srSF|TO{AJuPctv3$?;h)lR!)*Y9F`eEdYrCPX9L32WAY*$xZOWKN1ug(v z2?C$_&Df8iD!4dy#%U}L{udSdcmjwzvfV(n@3(O5c**%MJ5I{*KU33uP=xlspv#AD zegZg=awfl9DLdezqir`Hm$_c_&!<lbkz zDW_<==x=?SlwAlWt#!TU@S})9b;RY{PzkFUGLsuO7Au~A*jgTY-ag+pe|VWfV{zdg zW)vCKj+25rHH2zjnIWQxq|1FFAK zX&yGcN7C8$B@}-#iyy(YMD#4a3T|KR19EJFFW=|F{t`cT@A-%9PUmF+(AjI~Y1Bmp zMSKhBn`q_f5FPa3MktBDNvT0QJA1^I?o~t6Xcr&L=W8ISn4#{5Z4s8Qkbs=7G9)dz z5Cq1)SCU0Em^XT|m{!>mrS=d#ZAU&Gr4dDHAz&@~J(mz)o6|IlmiCSosORu|XLsu6 zQxzgP#x`C&4a_rj&72~8X|?*;I6`x2b(LqFcJ8JX=uLvoO!AbzJ;po4;u}o3Tm7_K z!7XcDFpM8lQo0d(8Ade3mE_%O0~PT;tq6ZkUuc_)pDHr3Jgie(kn+Dub_~*w5b>C2 z=%hWXMc0ZdVNZw zWRqQBHUr)6bYGpbdyoJlR^5_W;&CAZmz`C45^?^nGAP$TYF*loYJ2wL;4D1zW@GMr zNg&&6ufTo&NVfI+ksGG2x#K(Low3LB)SL>@?+2}bC8|Bg26i9JawCI`<(VY5=Ddgr z$mKx@q8$GNH>RD!9QzgHeR4+kOQfODwVRgTzuI5Yv69Q`{-8)AY-RAgBs2X7`vpkm z16Jk5>>^w`H)h7O&xgjEbdr~_3MqF#W3Epi&DHDNN6OxC4%mnv8SqI?dM>8%mk_j5& zf7{-D74jh)|3+Eq#kKTnf}e}k@jq)FrZQ_O)39zD0H_a&)*sUYtT-PNC$h{X#AA|x z3Gg@gWU4*_4Jy7#4qr%Q+3IiEj#od3u=bjn^)idRyv8i;n11u&$RhdS~-0W}_a}IOvcvbmW zalI(ggNGyGW2vvIlamulQG`5~h3d6u2>5=91G-MyXG5db{rtQif-gBhQF9&aML=Kw z1SI#?#-7tNMO-n9UyyPJ#L)t5jOF?l{U7o7Zd$*xyZ{)Zt=$JU`>;8G=6Cn|#Kef7 zX+uN8g(rD0XP#D|uSfBO^$0@*3}Rt5bil!+y*V+Li=@*3{z=AE)t{ZL*A}Qe9}oO^ zU-hM_#(&D|`&`aYzefOKn$i`@?iUP%b2Ec|xfGGWHrv~L{>B7RzWHwo) z<1;pytBdc!4^()bl|1jCJB=i&6s$%^Ia9SliyN{WaR7@cA)b-Q=*zW|x9)rDE4^5l z{>xQy1HE;3{1<&7&SYRB_dfka7yk|y8swXpiG3a@$(2iFgo0sxl>0R$5KRWC0PH~a zgbC3c*N$JIa(mMjA8YxsrKCD^xq)hMc&{EJq;LoP`b1V!%-M-r_sg zV~9=4pS^}K%mHw=%ksah*-6kG4iQD%9U7cM@aG_n@Jx#B+a>oQ7^Iq(@Qg^pg$8sk zslRfr9y8%5q_l)N8bC-POvNc0+wDNL34Iu?)~o$M3`O?!)-ClIF5%16@2kat|DC8W zEbn`t{v#ZYJ1N(Wi|^GSJQmb6#t04Db=^?%yDCfGi54vO1HWt1iqi%CEaJ2XC`0)j z+e-Mcq1wsJUo$TUQ}5!w=Pit7p2f@U3Fq%mn=-;uL4-(M%1zJzSeWo9>hr(p zyiYGsB&QKGGBX{}pdzHOfQX~P<-6;wvR5VhRR;2=wqn?vGG(ef9=rkzX(%1>8x-b;*$=lO$S6rwuw$+P+kt~(5I;zv( zUdjgkO{r(C^t@&u@Jt=d20s?wx~6}YDW;z+zkGe=Av@NNwz!s#rz?|zQCN$HD5Og-hX@3qIt0$WCG<~M<$Cy}X8cA^ju6TP zYi4_wpQys>FI(2bk_D?39Rq4eApF{5k` z3keA+VJ#BmAe-g0&-CN|%c?yB3HIBw=jJ0$7+Gaqi_4C4MZt=dp+(hH*{=hbAYU~H z(gDMR0NNrO^6MyAw% zJ%+_q1^BEBm9+_e1O5FQcxFJ(nlL`^HgV!bB{=w0dpYWmWs6%xPrlr7V&G5(8LJ1v z;0PL-rTBs^-eyRPSos!a>aBZ({}QaR1Dr}+TyjB%P#TcP@y6}Tz4rvUx-(N7bQAn`>5Ty3VB=c6OUDX3!iwn1$^3_q(zH=ulLA z?8rO2Xw4-P!wV*bnl2rx>B&nn|HrwR-nyUSxmo}zOpueOg;bx$9lRa^At=yNPE3YM z_`fGvn|fQ#H0GQ_V8-Ae8Zr953*I(UJQj!;9tZ&uZ=(OudScmT>+=ElIT?gtS^&1c zTsUBJlwNW6`72A&k@W!W)OcvAC0;D3X2b1+}nC zy4gU=MJU0%W?b0)%Kl8-^j!W!;Ex+Hg2Z;OCsga4^%x6DJO3*16tN&O_`MNCbtQOp zaGJ6|9mJo5$OnxdMi!H#3=M6m>ShM=&K_AD@bU?NWdwr2L*Bt5HzArVz@8ay*Z9{W z*yTgW&nMi?;2>EwdrJ^hs;l#PwVf~}MeeHv{_W8Xsz2i-a>fa375leV5LXXzj8FsZ z*Zqt1b`xMj#^ADEv(c?5!>TA$ho`IxO>mfqTjJxGc!Yg=Qz_;%%+>zojYm9fs^tOp z^%=P+(u&6)q%DLX>I)*MVx0L)}2aCUN= zv!`I0Q;X6>g!h;b+*+RvX*gEyw6DoY&&UAZ*4^4EWZA^r1-)k@Hsuu()9orq(+HOO z*sA8aF5;rUWgvYwPB`~|&npvN{N9nFjZHE^ocsGj%(05Gy2l3-!89Z^NxV zQ#wx>wBCTF_Sr&*xTLTHm9vshP`Yt581^{W848ua4eA3yZBKg!qUh<}qdTt&$v_`n zXw*!K^WY8TAp0Pl{PueW!iMatFwvW2M?_H$x6nxX{&Nv6a}-E7O{JeZRJ zL}iR~5JFkDt3Ck{Uy!FSfgn=O8`#)HC5o{oP1%NGP5+`T)8eY3*zvI4_C00KsE_Vg zke+5h(4kPx-^Iil&O_;a$;f!sfN6}D@Xt^qldCN#g02s`~d3`Uf}AQSAcyQSU=9Rr9L$~NhDZxYF+@G@vc|I^;{ zfr+NhNs&vB38h)!vmwaV2Jc9(GNH+=<$>8H>$+Cl*vP6X-ij1&li;&8_OS*Y|1oU- z_Dn(@kY-2Pa11z0!Le_v85$qxkcU+mZWWoDm;@NOVWn)zj`JXGQ9FkQ&(Y2wvJV{4 zZ`sk8Z}9g%a}pq^!$Ge4_s_fhR}SJ_;C)_L&}G|+pnITT!V>7!S~_r!A5w87Fc(E? znEq|(jCu#FQ$B^8C7&bBoPitbka?d91j)aaK02?$EZ0IP6MFqX+W+Hyu;NeVE_%-E zy+a%jctAe2`dC4>Q73Lzk<+G}F% zaPe{$3qB&||}A^Mv}m%*T`m4;U=E-`h<9EU_Ub_TbHf6=sBq0C?$d*$+rh z3~}j;%~agBkI4{pd_dD`U}Z&K*PYb;OIh{k&ks5onN{F)oCvsQfH`gf(CMUvoYmR8 zV&rK`V`*YAC!r^nUV!m3_VC_(2IxTmDM~{Eb3Yqm2fjC7Qjg=&x{6gJ11`tJ^oITHbd&G=Wk))B8A27llVI_s znbGDDDHe_QX#|VFs|gBYSUanl*}(`hCqEdzl3<4sv$t-^JvHMZOp#_vL?{%9txHNm zejt%FbHW$I8Y~rAq>NvJ%Ub*~Yszkp#bQVt4t4R62rS80gRcAF`}>8hCHBLc_x|K* zCq)|rSKde9{bxjQ2Vj}+NCA$ZHM5C-QIwB*J8}+GlcYhg&#yhS-%7hyJiZPx48hah zumSn*P1ut-#4Wxme;|OpK+q}2+;C1&0nO?v1KRAY$xub$&OAeJ`QX2~11g;O+C$Ok zZcqKC-}yk~ofZ#{+(irIeZXV(Y7nY_%&6PQuIq(fm6enPZO2iPu+0`_#;0D52-yls zAt8;qxj3C3vJ@7{?&2Oy)n-p7^+J?2Dbks5LogSmP5zjiY z9`2y8NDCBH%Fv`FC8_BTzXLnU0^So9rEZ4==eQEkNH`gu`-^??sUL*Jhyml-WrlyB z=iRBe*+Si9qwsy|+CO^w*j;EvQqk&5<#0%NQ%D(k|d+B zu>~9e_2E~zN?ML&hc3U3e4>gE2VaX0+!ihFD=&Z%bP@tiwW{flyKeBYq{aK5VnD)8 zljnaq3$L`UCo|2XBY(c#7;4dtmXN8` z_tXVMFaS(t5L_qL5d(@*iY1^eefL)e^F&15?}G*u2B-*dHSIv**jCrR=Hew%O~MPD zH~1#jnd?%J3??sk^mj(ws^PDpz6wWeeolgQeYloL{-XOzP>L2bguM6YdP(z-a|Im; z_L-0%$k%bQ>ro3Lpyr9){BY!R(_ZfW(o+_)!F%@L_$&}O=@h2V|Ck`oxQ5e4kL@nU zRM+!1D_YP&G9W`lKD3slP$&R(g99h0GGTnYioOf_LB8!vPMYlpLTQ9j#f-;8^0#MP)M{3GBHe*gjz5ch5GAg<)KLGHMcAv0K zTxKcd5>U-MbD)o>nZ3P~br#_}R!_0b(ybMSy~m%1?HeWNWM{kmf7-V;1V(4pZ=5oC z={%sqZ}Y06Pmi($RQZ_vIhA~9E+6G5|4{F4KRMl1`hJP2lAVVeYF`L)=go1AweB~-;Dm`b z#n__>CI>DIblaaVTv~Wc^7EP{MSc!|YcFw+>OFja;u2AJ-$)XAv;@=?V4i{?80uTU zR&luw7y^YQF;6XM7Qq&c#oV%7Aa`0?aVCwhCxy7|x6DMrYG~7j5QNYQBnn?SjfR6V z%4v!LLvSyifh2j_Z$3K+*xCUQF{I7hlVB%P6C%us1%nHI#tgcv>wpCJQR-Ocm#1_- z@uAxTwH+N9r5f5-UDh>T{*It)6QsEY&Xq%1Uk!u!h?3%FFh`d-biyqBqAt1yh<#AO zVi?;Ootje0U7*0eWZIh0YGkVkljab^!xP2(H{r6CM>tu({#f~*wd{>V6A(HstF!w3 z_f%!VvEujxx)Xo|n;qop=FLQMSzbwEeLbiJP)egJmhB|`XnK45FJGgHR`-jGk#se~ zr>?@1np`M;F1~|&YB`tl&K*v%Vj}G^X(DqV@t1fRB}8#eKbs4bSJlY-0Ni_mYrT6k zvYHR|VPpdOjR=syBhx?019_9X{W@gK^x&2DZGb_trDWJ=!zQt>8mM#yd^JGLz{cis zflYexXAL{NdY1xv{HEZ$%)&84oC&Hs`#xyz_bYH;3pxYH7lQ({`Ypbnt-q*d!-l_< ze@G@ZM3aL_ht|=cQ4gJh3Q1=C(TRus;Bw(pL3~Cn_Y}pup1ys-G*{@Hw$5w0RpTTK zk3bNE+QO}F_yGEb2uo(O33>2AOE?9RR8& zr|P)$%phvDZC`Ff!jiMm|GfCH@{#m?n-KL{)vw3k_~yVSLn+g3 z+pZ|1V%Oh;URjt>Aoj#H)I61R{$21*FC*6w9rKrdU%nYhls8Bm)n42|k(==q4!6&5 zD#ep_cMoEO(oobNrJoiNyzlUq$q=d*Agg2m$GLSb0K8IVjJ4 zAD900Uf9XCwua@@@`qOPeWbyIHcO5A@=z%wfIl!r=*-0-3r0bFub+M_<}n#X!TAaU zv;uSSn>S4FA25Vp^iXIFQnrY(xX1?@&Y)VfiA9~I0>UlzZOA`>elyrO!cG(IC3hCQ zooC%XN61Kb-NZjipK|<^lndA&pfim>i_XWw9wXy&7Q}pQ=yZ(VJjP4{w>fgih&%42 z1C5%LNk+u~dObOU!6IO%8#fmIeD-SJ*W^qX*CiB(#KoXHOL8T0jX(^G;O_w>6Bstb z2>D-wmh#?MZ3FaeSlFMRoiiuHF&}OqD?XC7*jB$`$W8S_tTZLsoMf?G;dy~}AUN#G zOD@I@AX8MLK9R=+U3z`g z7wue9u>a4|A)q%*1pdlw#KxduO4m>Dtt$~LcV)TEtYx?xhTC2*Q_tHa)l2jwUd3Cr zZ>}3#T3XU~pZl%@)gzQylr1~g*3h_q3y_tZ078$Y9tS0Wtjv+@Gjv*^!Y+psdj$D( z&ADtxfcqsGT(fg23-pJnM)2>usnZO+^h=nqOc!?Yp#=>z=qgJ;2hM(G zxn{mJ@dmz;HAU}EpcSk>ewG6Tt_46KZWrhti|*B^%#t-MeoE1zbZF{M^b$w}c6akr3-b>q(uK z-`pEE>w#fDF=Zcs5AnAef;3e*flb4P`QK4j6ZiRS6SP=AHHXhu9yRuhZa~J};Ery+ z)m_Et%TgF+geD?Tj&|v}4&jK4wU&Qq;a~1`s=GxPqOZW(FJQy3n3$S4OaxBhb6@cH z3CL+&g;J6&y>=(R{xTK;p{%-W3}D?UfpgRiJ(f&jmB|3b)@VAytfAPtqoUNJNHNUE z{tJ;Aui*JR)37Ik#6w~tGhzjuy?}>CU4_oQN}~BW{e{O|8g*U2_@Z1XBm6Wh_APt|$F=3yzw|=ld%sA^m-q|7pyZIfcK=KZy3|RW z`z^`wFp40uGAPGA-ti;!@2YAEZ7?#nn`JO~hWj{`(h)1=((YB)?katiCfGwOoxE(P zSRMK>oAF&qg_2&0CN>(m)f9d;M?T&Ze$me_mi)<9w&~8T!hX86H}D;861bVE!&WhN zA8%t@-fyX*Q4xThD9mS_gNHmr$Y_S>Ed=-zdne6i{O>kfRz=Ml(umPISuE^O zcr!0v8sgQq%+C?BL?a%fSBVVPz#mwMyY`MaPJEgyKW1n@zQb`e47-_Nr%yQOgmnH(A>q5VsGK<)(SH?ecSkZ(+q!bGB%na;m?3{()>cBThK$v%0E@BdTjZ?_2|qZ&KH!k{`JJn3ft=$SfDurS(P9zBY9C z+w**O@bGYzlOkOAZvCjpaS=ZYcNz;cqJKC^v5r`)xIy%*G$daG!UeY$Nt;GBywn5q zW6Akgj`BYG_f4{!i{?oTi9F z8z5E&%Eqo7ah2Y`KTN-IQuo`=pc;OC`L6oi+rJ&ItLwf(2J2#oF+F4&4RZ{F!Y|n! zlQ@95*;bpyAvGb=5To(|JQ9WH1FS;Z zSV89djgctoKStAC2^bFqzixh|zh;Ul7%j|p()dOP{znz+F*tp{v3#@?g+aR`Tp`aU zACA(RpEodKdN--Fdi5TduA2WAYH4Lv?>Td^AYhENaoaN6J|Ju`ZkP>bb$d_o__QUi61pI z_b-U=sNj-e(vVqmMu(l3XkUwN$_)7rZ%H$9s^R&R_wpV+n(!`&2n}DMpk!|-tlr^a zfsb8y^@B>WJk*Pl5);rV#RWq)nA)w6J#X9?(pFf*o!GGPV9(?4U}IedCSDm|KN_C& zKfk=ZTsvC*nOq}$o^+aR!=qyOJ`s3X9&o5G4-MSIkzv2?^y<|r5YfS#QTS%ck+HES zE7{J;3f|FT?3c&L?df@7RSeT!Jq0&p1RhPtrBcI?C=6yv8uByuq6G=N#5pQB%^JwE z%{`8yx_mVk3ZhPlwtucIuMFXk0&6pEr~(dff3`c1BXT#AIij6Luy zG$=OqhUhkhCH$H9zNtimE+&T!4~ME~vIpvZRpD@HIRoLLSpMK+q?0~Q>utCD(^>L9 zYtkI~VzAjT%iyu0X0*0N_ifXai2=>4aAbf!iZfLpqR;0M)UmqpssOcOjlX~&0}ROv zzcU+Rc5*a6BMoWb1kc58!m~wf%ELBu%iE8BMv=mh0Y>;PWBu{pVVh>v9UWc63`)E6 z+HzDM8ZhY`Too_xOjdl2g23FEilJ%FJ|(L7SXlQh#zj7VGGSz}I?jSla9b8vd+U>1 z&-{is^_QaHZ*gFEE3NU=O+Twrl~1FIas6d-Fen_x4bIljwmq*OO;fhez8q=VwN@OP zckA;gDmHGHU*GQ?hZi1hUg2|bR>RHN-n1GdN@J;UF@p25LaY%;Cvyxx`aU`C_ZPag zwYZ9R?<^K7(*W1Z&*3+M{lXfXNrTM5iA8==s;W)tl=f4Rq5 z|4SBaWo6~yjk*1HPDhF>6n)ohoh^WAM-%iJxbx+%c+1`?N&nz2YKRy;_^3EqA65vp zvQPD&S;rtW4I1wPp9?+W;P9JHKlB^rUS3@lVy9Y+#=L-=|LHMa<~HXdAAxN7`f3ka z!8|FxzYL}Q5sAoefr9(`b<%x+@nOv+2r~(+4fX1%@M!Hv(A*6$Bv%8RTnH?l7)Li4 zz83ML^{8kIeAOak{$+<}KXc?PKu7rgTQ4K4sHw@!*C+3PT3hF&C`hB-Du7Tz=Cd9| zH;WorbH39ybqSUyaiA{2MeY&1PE1;zm`ZUrnpM1Pw3LwSWyRj4nReVf`MqN0Jr2Q> zsX(CcR(dUIh_h1hm!Qv-V6pr9xC4uYku7K?3yM`Vs9bajQA*a2_U@MDEwI~}K0n_^IYOK2@jdI|FW^?cX*QHG zPP=SjLwD<^+#t`gb4S4kd;t?XP50Q&;0p~{>HKv2p|a5>I8EA;(r)BYwDz};70lO9 z{MCcaadYN3t?s^wrAGz8!v)YpxF9~h^UBBv57evb$KFNs#<1TL*y?->jc8h4IsDMM z=dt_Il$sOH!m~w>y}PHZCEj-UXvZ8D=K;(LjTTal64T>6G*Z>{JqZcJG6gRVz71GQ z{VP8LzT6%D-DP|xU%6Yvee1qnET-PsQ`P3r$j*j^MU;f5>n|ER9+=JC%{`{L0G8T5d(fBe6r|)`mCP zS{i=E`t!n&&x|p|XodP*a;z7U;h}myF=iZzkHWb8^*5H56JukQQuJE-H+h+q+nV7sUKGagpMb#z2DEFIq;3JYbBK0}9vHL>OakMpBG z@a%Qd>*Z`K_!#zCl#tIpt>*g7s*6w&ALd>NG))GEJWeGn`%kXG@1`GbHA%2&q>_?j ziT;(qhOd+SoJf4x8T!GODQ#8{&F*jIJqHTf8LD7Vh%_YJK+OnwAMG2`om;!|-p=V- zb_A18Hp1P_?PKk&`EU3rs*%gao4@@Vm+k|vbY7FAqV42|{PJoY3FILHI2}9^sKm`9 zBUgleygGS$RXx4I{-M6f{XB17X`+1;-UYfEc=n?3 zG!M+YJjv&OcOICG0w!Rc>I&~#e!ktL_hNVf4R7X`u>b0md@fMstIJ&TtaZ%Q^VQGM z&B)_wOwEglDU*39B@7v?3U2YGZ)y*al{A9F)pGC6r5Nep$A8`I_QJl}BwU!+O|*GB_i5w1Men1NI6R1WRPPFi9R6sqxvfPKF=3uWtvOAz$HP zbyZ=-z0JbIJ(~=W4}p4ouc4Ir7=*YOlA(cn3ieycQm%vQ4cahd$-r?J{fe=7?mBFU zzkP6U(0y}lBlHrf=vdA>-kE5t?q^$bsvNbalo=%gAKr1NfI@Bkw9IwoOQ(N z!Ij<>*<(%DO5-y}tmR2JJN+!M;^M~ZSlz=agbI8#|*oEWjE=5!A0wN(IeA?kPx!i&eq;UUYazgmy%Iz?&X}S z!0t2);F480KPJTy(3^>ZotfhRPlix50@{WYo#$;(|B!uQd@k(AW4EB|hPGmPC5O*j zRfZg=%Q|dzw#^Z^_c;b|rv@8oWngEwVGq>bNM-!u$63BY;RT>BnRYG~ zD39lfV&|Uw4=Hql&AtXf=yOD5a|W-SXN5p3FAMQtaKq%lYMPyHs^5OI&QEh5Z-Hg= zYE);w8LIA3Rs^DggI&+_q{k28Oy+Jrs<(eL#sSmU1io;yl_IyMT?~2~1I-iUJgj&| zW=^w}iKBi9riO@*zb?zHpK;DR6jJviO~b9b6g~~x1cMLJ7ushzn!a0TM!utiun_Ab?823 z{AbI}7*XibFP%(I0G>>N{cb+!KU=@lHd9*n!iOEk!o0td=PeDIIQ<6QfQ+j*We;SI ztsiYS(tzCL6=e6|>93U=>X}zA5^-bDpAZdU8F&2n)lh*j4^3{5n9s}7&^On=h$bbW zSKyxtZUJ@6gUq~&JnsgLSPnm}m3#Ki@J2zOp*X`wp?lJdOtmCv=5;v`nS~2)Ek8{B zJ-H$7_LTC{Z@2r;mM=kF-W6RFZ!@x3c(vo_PcY+e8Tv?|n)u~Eul^KqC5vIexjQ}& z{3TZ)FFD*4ILrr2pDSl`GfpYUVG#@j%jV%>?CAJZ_LEQA&qn_Y*=f7G$|XAbSLn}4 z?u37l-xUL|;N3K=b4>yGBR%K~=+;nPwL8uH;unUc*8!x>JKsDMR-!W}Mz-DoPr^tQ z+iiTdKIT#=O|ImqU`Z9%?V#sY_;8&Djfw$>!6@#-2-3-@xIucSI4M|3AyeJ%=L0gi z53qXh?{1Us(f5|vpM?q*hyx{y0;2%p&2(JpFY$@4K4VwNZ>{u9S~TuD>}JHl^SQ8% zz?W^OXyxbXVpr(Q8w1Kx6t|r&pA6Iqf4@;Wo6qibd{o-{Y=<6N5&Lc9N$l5q5ZEa_ zxC3pEGH78U@PrRM^tS@Jd6D}T#hn&RrSB|E$KJUVm62vgL zLrKa3g=dHWcsm!lN=a$$-LgbA;ELo`!S_opN;}Wi$LF2C6Wz;%8{YS+$BaHZe6*%r zm6DDJu>UhybfaERJTSAx&qV!_vowNvET5o@CxDl^UJKsaM<9*U^9~1d7Mrs4EfM=1!#@vi3OPvd|+A!5nVv=7tw7~bhC>-s3 zK{aJIAN~~ZvbSP8BlI86(xjzVC4bZyjsmFs7)0i{wt7A(@bwuUnx$mdo2lNz%p>wO z&=qx}298f7+B*L{3Jup^mHeL;U{#IrWnIerIKOf#(%Nr^vGHJX8$hv#n%w-l!0e*x zVfsY)#l3mMThF-b=_M6l1vH>eQLcu8uNI7QpIRNtYBbmE2%pVy863KJj+rn}Ecsg4P& z+(GT(k%U8EUtd;JrhV(=Xk&$~dP*$vSk(v8J0SxzOMa&@WgQt6S_e<_0M)KYRGI}? zIrF!=$jE24W2d>4(KAE>5+0M}3b*!I-1m>k85x!YypGvAf28AVknOs`W%YlG?>By1 zjmo`Z!9$}9ZC$u$5mZanfK#}Yl^5&8mED!%0c~Tt_aI`{4K8;?B@d7!2tISFdGlX-^gFYQ2IV_NbV{BB1bld?1)N-{rR=oWmO?4<1on7R`NW zuY%GdeEbU+F1UMoPPCJ76o2-9XA#pv7Nv%+VxepJbI7(VN;J_Fv`L|kdrb)Ho8U~M z)}`jC#aFRXI~8K6>J3MOAWF)Q)Tv^4s##&YAyp)Q?oS5}_On@%(toPo1p^EZ_uRH@^|vzr!?u$EciGS z5JG$O^7UGz){6G$$zUy2RaG8VBno^4R!DoLq6NzH%AjSB|_wZ)fm1bxf@$C{oDTpIQ&0iV(Dpwx=bTawpYD3qW zB$h?W`CC$*rmMx`MZltnC@Oxhp+GW&&hj};-#jW(^xkVFVS)Q6KzPaGEL0$r+A0BzEvXe3rArcA%2VdHZF=VdJjEMScKd0zNMAp;{*--fJr;+c{XmteU}TAmEE zpUQ82$ab4j{+aIze~_K!tRT9w*MR#$&+k5Qzzm49V2&ux)~qgZ8kIJ(jE86U5ahqr z?=muVtuYSEu-lVDR68=GnX>}=g->XCG{+%p zq};3A7)&*MMclkNrf7Iv`0ml6uy}@cDz5guMnTw|;FrL?07eET!Ak;W78bMn*Hf?5 z{a;((9Z&W9{?F+sBV{I(l)d*Br;?SGy(xQS%L?Z-lp<2dCQ5cz331*fk-bww2~kAZ z^LM?@(fE8Hzy9b^=bYF5y6@|{?rS`+=lyzB8QNy$ociXLz3t_4>FPBS6f@l@Y5Ly( zB!o~NOkYjR<#=1(?cprliu`cv^d&wfbx9PIbG^NVSN6TP2^hLqKuPt}KuLst<&5pm zdo_MbH||Wg&|$Xt1qZ5J*?ATnwgQt zvtNL1eyQ_Z+c}$FqtMHMLb1;oAT~e`|G0&E`0!!DQ-O6-y9J*6G#HEz3n?W0k)bFZ z#Vym1ULR$d54;-f{+fgDt;wB=DsLZGHQ{+7yBC6)2*luoR!_Z>;TIbjg3R2fZC^Gt zM{fGbfA)qAB%p9e=WW&A%h*J+!oKozm4}T@OrABg1kor!F{=Zfc-ozrnREoQAS0d9 zvNvnoN9j&vUPnO~j#S0SrWR4DX5^N)9~^!~D|eh6)${0MfkB7tnNYLoW8~x9YJebK z#c!-qRV=i0fTw#GnJvfJgreux>V6GjY67%YsGUvD9LQxxVgLQ)*?K;o!D$&W ze+AD7`1q~OSaLbg*dNq*E*=WoFPvuDb4L1{cg;yt0tH_WWWXbYQmMbHrfPHG2grV$ z@PVgW#_GtAOG?*##~sZD+p9-UbYzrxCI}i@Tc_94aip+OA;on2VJY)lOhRXIzGKP? zDXiPajU7mAC=OB=ltk(*80m0A)xk$Uw|XJz-g7Zg6pj%vqIU-3%NoaBB9zaPRN(2dNN zT6#F{fUsplba*iZI?Q@hpm|?jNl_RjJ0vHW<&bd63%vFw_!@gWHu{3%7fDj-%MgOX z1m}8G@m!NJ{ZG#Eyu6C}{HU>%XKywsz7i>{F7beEnb(=+7kVAwCS?lzndd~OyYXh? zwV|FKo_?FOo=tt5iA+g6YbEyG(DNgI_5@1e zZA#f_?9-u*^4k7d2P{Hmd zNrdRO0R4}`pBJ0chq6z|GLs&mDs)CmO1V__8TUP8vdOf&%`!a}r7@F;W()f6eb~FV z)I5GS2@|q4V`)}C-&%Eb+tB1z*~RXh*kE%c)R4*2F9|ySAOp~^vkA%SMQ!}hSsM#~ z&4Kn$&Pe%P52CJO0hzx+aXn<@C=#;^QKZ?$K5B;>kH$*Fvy<`?%hm95PTx``beFvw zbCwK%-4dvO{Ya1`B!Se(5DHLGbPjJ&vyswyC9E-vtzGKtYcn{Zq`R@_@j}jfZBo0L z$EH?`RUYZ>E`-V(*2;te*!y(mV@01ErNN?nSH#FsN(WYcumRQ1$zkftUEN-Q4Fv51 z*GerMo(-?MG(Mm5Zu+F=+Gk{jdTdcS!3mLs2$n7|(I-pKSX=q6GOqn>IX$$pUuUqn z;ySATYiC6A*Hgz2MfA}A30<*@xVWGG&z?$$)#u#&68%=4e8qshi~Q?XJzs6B;8JFc}X5Mp_hx< zBy>hDtrr1?GdLt;aLv}bgu;-OUS82yV$#2aOs5viUx##7ysBJSua!T?&u(tiz2Zx>&+&FYZi_~sw zINc%UK9rH<+$3fkSPVY^=s73j#h~Bu`r#b~d&#|&;1p{STn-2vz1{Eg$8IZWnplRF z8c((Oh@~<4E#IN%*69w)7BS3F3LQGk+l2sCE_9|uRQ=TifX>b3$*NcAZE;xoT?x=-RuvvZI}@wd`%3tS%~2bbaH0Uf_!J;a3@l6R7* zU*oqsh6U*F!Oy0!M%QG{eu+=jn9N(K!-o$;`NG1=TDj_&;=0iEt76$Y#Lt^yU%)MV z*PDz?p7cQZ(%s@mKnWzI&Ck6RH`DW2YJVts1?pvbSZmo8KQ|5-Id1hl==s|gtFW;Q z=&|@|jIz2(R%CInIVZM%wuLL9iv;B)_H`E2;>U5_-EXNCqSAz2%4ehTX5?rK=n)lE z7HMloM^D?lx5-vZEy#{wqjhK4?^yrw$5v+kwClLNQ;2BrNmXz;aUyeVG9%L)XE`K& zuKw!gJyJqmyFR?m64F)~{H2S>@Lhr4bGi2DZNZYOx~b$<8lxWt-EJ2a6s*0|K0!+b z$@FjZpS(&x6W;6gEU#@?XiCpyx4IsAAO=4uT2)k}9j&cx{?OAVTK3xSz_ zku)YhOdfzYcW}5?OD7IVCBz9vXIGE@x{#T?yZ{}oDaF0%hj40aA(n|&Vev|v-z69i zF!1ucS=AY94EOP4=E9=(PdKGy!x?CE)O`g2r!dJ#W0W~{iiW%zqY*Uj(Et9{m08Rd z`GSgV5J#p}TbnlJwW!;2YrIy$U1Z39(2W=$Vt_ZRmYHte+~eFPH4rPdu@ZmMH3CGl zpF%cdcwx5B!dGdt^VHcrBE2p>KYAV}+B{sPVtUN3Y%@4GNO{fKanBD;_Az^kgLc9( zeTG(Xh4TmZK$dEnL{g6{*1EBM1Y|4>38z@Y+o6;N95W3LOCcLg;*^1%m^c7c#@EbU zO9QLf?LGL#eyaOd*L%|Be$gKGAEGdKh&LKKB1nr!#)ZzS?hTUq^?TOq-*}eYoiqI0 zB>|9Q&`o`z;y7V=^VTZ2aMJNsqa-6U1TRw^esNWF201c`=+)$b( zX-TkoYg6E9)b&=YIO*v@_0(t*)NOo>^xom~zE+|?6=$BmnH{ZC8SVY#Gz~3U&h*qT z5XT{Dv%ztlN%%Ui<~SXr@B@8|3azyDh2Bc4(QIVEOn&uY`j=Q*(0WpEvVC5|dlSWk4nrLSH|>g9O!o`uc)5qh%miKOVB|U*6x(hnI8O66dI3!DwO8(9lro$|P>j-hM77tH(D<$Cci8v*sb2 zAf(x{k#wavB??v&_V%Vcm?E!`sAvFg=Y0r!mYAwFNU!}M!HM{mrD*V5f4HmBL zjdg`TIu>yleX`=mCDCPjto1dZ>_S)bV|Ha0oIeC5H6JYkySJK380lMUa@*>mQG#=u zKQS%P-+AqrGQDwU(xv3Z68RJLU<2i`R9YWtJwZWU^&btbP>Lcu%>^DwOVSoR>jG>8 zX|@~h){hFCRjUk)1m1!-LSAe(2Y*&tSHIk%xqFu0xvY_GK+j+kyMB`67@CGWnS>gf zX_R`2)~j>}piMsJLdA4l!HF|nXfuzy)M zUS@2!`RE1un@3nv6qc`G1Y#9|AfO6$xtrz*z&Ym9Fvi|N_W6Yo#{jX*qxDLE>h9*Y z?h%x^@37yfZCcQp%X{}8Z3BsOShY0Kb8)Jv;aO`7vu!_>N$d8h156iYg%2`l3!<_O z3oTk(nxQhGBl|qRPdi!BXuvWcyY9ZS4H+5CN5wkg>bQA*j zI;2nW8JztQ3WoU8st2c7ObLirOX40^BRhla{sK!A5JRmF+r{&)Jk*_E9q!;Fsgu&A z;#Udq{6-o6*@$qD2G5}aZ@c2ld=zj32|U%C+dZ!&wvtVU-vqrMSs`7v~rJ$!akkMahL zNLUSg3@p#je-N3wdH9S|QigD7A?GZEUu4vkT_T;fIb(K}T}~(wQn0KleQb%pNy4>E zNYg@aadC?`$FgqoHGb873?;=hS?V}0^%*MJ!o2t0yT?K@BU(=BN|t+$_+h4bmb>;! zvkfG_b^zv&k55_XJ?6YXHLOD5a313wc~tvy%&!;aBXuF)iWPWp-DJ4xAhC~rEk(&b z10Qb&G{h%nWH?V;Kba*Q^%4nlhe_QQ-FegfEd`g%LIc_-4}qT84}+e%vsw?q_jZt# zHC1hISO;3i>^V;Y`A7x!moc{71Y3SJ+E?OJ)6wfL4RTI-&T0Pg$5r+AD{eIyEF{(| zL6ZoTzO{e)G-en^alkcLlblJM9%piLxg{k1dfC4;LgidJX*WqoKQUI#&&yHpfoSNUUHMr+R9>wFvu#vD{XH*nEkv6Ouar zwZ)$6KVFQtYy>CwI{8j~?YH>RS+PEA6cS>&x*8N&xmi=&s;j%}(4 zFuCt8gNmXAa+NvFhd1a+(R5I5$Fp8M2n~>@*U&(#5gDyz?0nz<2ufCF`tGeO%UwyY zbbB0AE+lW+#wpo#Bx;$J`9=0ygxm4i-)m{C*C?TZRt9#P3`h%u&srn{=Z34-btcu6 zly2jrm?iw%7Gs2stj0}Wn zKlhutf(u3l7P&w@ z^LUG1(_{|^cb$iOKa7C^r4Dz?0xYhV6}%W7+%MXl!a|cv$Q@3ASyjMi66Z3 zsI*i=_xSt`1X0J`ak+4z5Be5u2Mv zf`sWpOKggxfXrudG>um&5u#0yA-(LM+x1%NXoW46tnP)U6&2jl`>gGvr6d=cUP*nw zI@VVo9$9j3t9GC+c)V|bK1KAW{iBjI+CGpgtCCKxH@FBZ|7ys7fA0EBx2*44ZZbqk z?PQ-^wvY`z1f&uXk(sYhKC_Wif1vdSUKc%lyCroc=t7@D6XM9M5x}tTEv*a$OsFdr z#m^e^yaY!yOXHP5?&|5OD@glAa+ma0TO-TG?s@sygHDm`+Z!ug!~Mk{mxe4n>om=HhapZzMfX>%)a-(IsUe%P*EC&;4XLzA}2s)$ND6;QZLohSMn< zn|Qfh%?p=wv-hHB+WDfn`vz2WeVn{h0Ky{ov&Jje;{ueNkS&rydGDU8&J$JoQ2&6g z+{$A`wiJRk#~y39wQHv)9GH3fO*rxyYU%y2j=U@CuYS~JY^)n>1_9w^(Zq%i$SgeD z1}567sw6lpbTvtw>_)q?J9p zL8H>&pP#o$x3HrX$zCz+$H7BK^k8N`79@JqP07#HkJL>iRi%_~%y@RVzWvy<*xS>= zD? zi6c4N>Z6pe8+SM=2dw#qEGA6yMc2#alEX$et9_@fV3{TK>o339D~vE5O}H^OeHy=s z5;5=b_Bo~9mOHyYo*eK7+$=>W$=7sNr=wWxo8N?^AVK$+r`bDEBQm>E+peUfq*TuI zTks@M$WPzkV0cUUuyq27Rva-(kKSYin@0nep#IJ)`fa{nj)c0A2h!Bj1?A7Q?6UjK zLxj@2zL&oD9C;z-d}T32{JUmH+UB5B^?LeLvh-${ka?~1>wwd;hbA6vYc9%?kOq*O zx;0Ao8bx1JlT?9b!arCl+LBw((E52v>C#1wSu5Ki2gj>duomc4R>k(X{QzrLR%+LO zIHz!7Atk!P+Cc?6)aE5+`r}rXs0S~KtbT+qWDSRJp9-DpQbSzoLL;juzd~wJZS7El ze481d*-hRpr!f%bvG@}54KF#l$(jdGOhjfXCui4sifg81Sod|SvQo#1eRN|R=x^(( zS6)>)61EYkw7Ois*nOrXUszhiyGL1uM{Q_fvRei3i=ytoZ@>bCj9->t&{2p}0rm?< zrc)N+!CHYQ7dgv}t3D115ALc>A-lstr$_M_`YoQGWwDQJ%YY$K;VG8`K0mVJWNbtcR$?+Lq2!NN?+yZg^{N9tTXT>C%2 zzEx>IWn!MZQf&HQt%KF@h@1K)8Nuy3a)H#eqVHb!cbD!jrq?IW$0iN3Jatm(nx0I zD7_ET*Qh=QC5?djp<5)VIyzqAk|EXpVQv>H8!lCGP$0fFu(iqaxx}fW8=6@;M37bs7Af4kok;I0BpPLR-R?S z<;%|d?+uY4$nYe*S$h5xK$$jyV!`JLu!#`#F$W(+T_*ua`M%zd#5rHBuxz2ymtZ9Np2e&v7gO_F4kj-RF7EtzacOjz5AW&Y#l)f6zCm z@X>UfeN0Ore1^3_n6D4xzQE??qvsXA^<8kvQG@lNJKb(%N&m>|>rK2`oN!)WFUihx z0dz`AqU$>2?;;TQKjk7Ovj+9(v7k@+orr({lJ-;oXO!pIawiMWRaAOR135B*ZP3+9 zeWU#i5_sboFMrH;r^4BL6~T1Z9eDq}Js4g*m0+3b8<}2}BUY65Zj{jBLMk?0Ko#6;uK~dci0#b)71|HGZYGxKwwE{YP@@>Dc(^^&IXU$$*!t4?m7V@;dYx@GeiLwVy&jJce-CyUMChbm#LW zUp|Kb%YUxNWs(ct=^9*=>Z-XCCmMv56nVfojpa9MJWYbbQ!M;Ye!}bV-ZQrADDF)9 z)&ITLp4{{}L)oYD$+nb_u~DB6A{1BhYNW8YA^igQf(8?j);Cs5{Y0~Sj}r!6Env$v zUo>KM{2#@szrgFeeIG>Fc@M+*9g*2x=D-(WM|+dCh&aaw66xNswD^5z#wxUsd<@iD zkNzBYa!WJPogj!U6TJHV`++N#>1&hI$N+I7uvbIup|$G#>${SaHIQHbVZf8% zY^e&LPh?ulkrfT7FMY8+6MGy*N@F`VPQsAHup|7;Gbm$v^AsO7LCclqXIAnta0&pX zTMh0Z^MhY1vSdFSXvmz`mXW3Fje{qN*+(S>4T5XDser)~EE*$r|mMBh1g#o0lyol>|5 z-Azl4&Z#*wH5a+n{;~1V)1>{)zs~nn)BbAdceOudwJ`3H+QLT|T>~*VPW1@Hu7mmE z+ynEud(P;&0AF1(Ie;?%PF$SJwn(xJK#L2HP`1_tp>I=GedfMPf3;_O67hCutIVng z=Z}9l*T~}H)hX2UKbO~X+2*KSNH}a}W3`#|>==(ZjDW946@!CFOl(C|I7`8hs2cIs zxiH7SS_TDa(7!r&p0U^(Z4DmP*AU+=-)Foqj8McwK1thpr4 z^S>sSMcS%3(x8!qM+Q&=kvSV);bM!kcPN7z<%a9O8g}yu( za?X8rX#Wr$9nh&@2tOn}bn9~2>Wn=+{8e${kPX$8Z=@w#L;cN@++eqPeo`0#*W z{lB*tjyA9_qV*xQZ$UbhRwL(4WJ>s5iU@573kTwEwg^O+xe1Hu*JrZC0xa-HP^2{X zMeIb15UL&4QiB$86{9?;T2ee0B3!g7!n9()cQ-t;QeFhVH|L*_jTIq_>XMr8f7HSP ze?pVkH3)mX&=9*DuNeuI2e`p{Onvv;6J}*hEnjK2oz6u3y)XHSC4M?%syxk=!nlFgu7jd@C=EHph_hZ z^2y>msWK>IZw>XUgv^g}M@=d;XP@$4eM`_Ckff)ajf z8m$j8eoybYHx1|ejywvJb|id39tYuy-6#dluYt#&E4c+MNA zK~0Jt5)y5RXq7^?v~R$D6{uOjL->=1eO`uhCP-ACi$$`Gx<+mm(hotr?kACqYiIiG zW~dU=Y&TZd2Ql1km_}l{J34^uu26z}bF2^!#^X|!qb|QHblVXi1Q{RsE5~Lu?T5#P z^8Ky6B!WX=Z$e5u%TOPL>>>^))L5AL?>eL1?|ss{&-Uk*NQ?avXZE*gB)XsXY9uC1 zwhnNuF?Yi@=>admOlQ&-Kmx#v;Dm4pFD zha?f6?hV3mLwMgj&C~80-=1^xqKIoEEE#x1s=l07Ha7HW?*YNk;y!Nfof5vEZi2Yh1WcC z-QMG7pYccLC%qa>$P(cU&c^g~*GpPyxF?N0QlgwKlRwq%2pr{rKX=7dP}B-!r~FUS zg<+=vwZvhYXb1~Rf+l9nA=d;M)YE1ybnEnCQntZmouV5Igu5uC>Q=Tw+gLsh>CuOF zD*GQLf(-1CtCQ=;)IIYW+);nb&yW`L^kmi!cQ4J(@!@yAnE{8k+_20h>yrhq; zxbnZZx8$>J9f__CXmHJrsS;PZyp#P>!@aw)tqg>F&q8$??d}Ak3lCDDvt$B4DUFlY z2yjff-Hf1DITwt%iPDEtjvKwRSB}L2iw>4Efi%A&Oqp|OpBPL$uyrKL2^>QrN`z%l z!48t{RdI#5|DWcz;M8x)P@{QBs@aw?JaXZ;-fd0_1;=?{y?=HI(Mgl1O6)T z1sRAxQ-6T*o?k2Y;Ps(Y)n|#~;QfXyW=h1I2!5;_@9rkm=Vz~*SF-JQCxe~~4h19M zbn}7!(%!cc;0GFB+=H$7^{Y|G`&njKA2(F|jXaY$+XWCw1`k}h~ z$au@BgW}T6PD%CmI1@o_8-}Ab+E-!{DyZat>k)%Tr^}QDl;?Tk^L45TpE5&NE%s~} zH^F?#^NExTkK1vrE^%d7rjbrG!33b+F5Nu*DE37zg8qeO2vGzZvip1P3SqeV1WrIX zppLIv+}w?Axv3#bxZ*#+^kNQi6=cO-+-JRH|J#U_7+0<%1P7HL^DbdIJCF?z*l*wi zEi}?mVW&Y8Yq$B>9&*{Z7pTj6-af>j3(BJ6)RxIwsX)lCE5ZtNJLYo*l&EMbN%Rqr zou3VQeXcQ?gLCH7wmZQF5e+B`&s9h*4M!wT?@>(O^J&L(DS+py6X2sD*u#oOW)7!* z-V?c(<_aqM4>No?n0{-&0uwJbp;Y-H#IDpiK3C!>QWC?UmmtfDZA*3Bmf3@h!l6JJb^v4##fwOUQIne8mUuwsYz_jaVM*I8UXMtmd$6sgG&wu*ziC6UcX zf+{AGqPw%=o9ZgdX{+H@RRzhRy9wy<9FCVmazZ}{bCDsx~Xno4?K8fEKXE^cb-3{oe5O?h{J+~ZYZjU4BG9_zm6|GI2zvpol z=D|Gf&YztIDX_dEm3C}{28#zT0^1pr`hRIe$?Vw?WyEBMsVa#TvpgO^UiUMzK1!FllYE` z)vsZ0#V0YxZJsHVUQ_4iwk6;=Fx|NbNDMrCBZ1n5n1cFq47{zw!`EViL|{x3wWPax z^-sd7aX?fe`g3?&%f7b4{Cro9pQC#T`8BAO4N2tSi4)>PZRQ;?Eh;P14XZf}M@&p- z?oO{B{EdiJ^FfZEQ!jn3je~$lP4K4vP7#%m4t&qcID}pRV>Z+A3JF9*Mm)k;6Cv<2EpLzfWe_+N=`;tww zYzulEL#PBtg-8V=Z78iQ%8i?qJlwyQHXb_O{!^*Ah#p5&->55TSii4-5IHfsCiNtj zWhIxXbUniSO_0_vN9F;y=8i$~iCXn5-pR;*GuSi`zj$<~N1%wHqXzI;4dSnA;Tbr_ zrPqy|MVi?-U8p@(wC@q^%3fvkOmnN~O=aeSqA+<5T2a28UA1D2-Hr7;bLKqpcU7k{ zA4`_KuwSBNu8E1?{hWjU0YU2+c3+h08mC9wSX^isWFI~g$KX)zj&rC11F1K;zd`)3 z*Bt^panx>Ev^yQn`JQ#YN|YNWpUk?V+rZl`ed|H-^j$;U#+4nT$6_H3z=f22S}Z)FwJwg|l9u5FF`57#?Aom4SQPpw%VTz=<|6-JM7Ws=;?X4o zRicL^!Ld;m8a$odeY9tu$E__Rsv>0n^)Wx zQ+nbfPhc>t1^ASzO7R9_u)@TlQ$<2ja!Q9pwOm}rBMxV+6qh-gXw;~`^*&|UfXIM- z)Bi$gkKc8`GaHI5zOl92v@ zx@pe3?Z$6ZshUsEkY#ZA;0$Nc3jOSa9?^%43gM(Rwl_LPwnfYfm{_MDh=d4Sdhn;h zuLdMDGsGj6C~Bme`Hs)h()?LA#kDZcqL1^+ElL~Kbjqwjb;X>Bq&d;w!xOHoCyGsE zNV9F5gj!80o4v^pAk+Y0$Cr8WBF|40%FFH4UifWz8HOaU)6}!JdYMMqXzWPnG7l9$ zL7uwgvMCF7oKxF{mD~JH6q`0iMn<=Ij`8e7H4xOFv*JV(9(BN_z2q7%JzQ9+U|MiE zs%t4OI7p7;yc)g()jl@7;WIW#xvlFlVqTCK-F2q%e&Ts4E|K}G;hEEL40C4}Xpn}f z&T=wb-w7ok`|)oc7aX45^-m_fsG#vJldy4P58yhue%*|+mKHB*aGj`4PcTa&+6NfP zToo8n3{&jfjv;}cIK6B4-g{CXnv*X?R}|$$i!)J6AOfhPTWQiPd22e^Awcar*}i0S z5jhS;oJx)cq!G!PNrb1vfaEqr^z`-1lFNLamWqF9x_=?6(!wGyW?O>i6bLJG9bD0S zmS5F{p>0idk8bx5oG*R%c{Zjg>G$4)9yXxhqvk}{1>@=S>M7ddxgT*<7!5fKa9rSW z8Dr3S(}`>^CbZI%Zq}m(GWQt6k0WMfO`d#kXEAWR6p)0u^L;m%cU+UAz>`Ki?uBp4 zhj6#T%_6Dy-EY6!=7gnd-$2S}oDJ=hZYI?wF1y79sfo6P+PM^)_Vi6^=f4x1Li%`Y zlfvzv@4db_e`p^e?S*-kP$CV@$FKa{X(?T(+-4Huq@AvuD>1%XMN3|RpNtz8Ypi9A z`8Fe%vba#Ry?oNIfa+k#vQ9b zHcKM8r252Ry9FJ~V70838tT42f8oezAVGkX2!GYV69MoK5$i^)VxQeY8Mx9d7GccH z2IUV^db&mr8hY16Mh&WzeOs44M+YJG8K5tHA(TnW(Um_O@-|<*e{T*1L#5wygX7WQ zP)C2FXbDg>GQl}Flv}afW0Q*~S{fVQMLV2gJ#*2HW3y2+G!_Zb)yHgeN{SY;?3H38 z!)=RJGmFHQuUw;2UVSPs<|VkZKu}x=_}8l311i6RGC8MqW`*C!n@h2q(WMtTG+3LR zPnpSWw|9hV7&x+{6$M7!WtU2GVp5g+@5hwMFThjvjm~yBs*L`fsU0ll`64sE$y8nh}q z`M8O#PehrQ!2zBoVT_&;ZZ=$jF00a)l@Ug+?4J{hd+9v zT{30VsPS#3Qqnib9BR(5ZOG)_#CXb|@<{&yburPcZ`1>Kt!{>LhF({1q zW8YmhJ_vBvHu86cGJ1Sw<8$$$qwcJl5A(*x2^Tjj$)XNfb%vkdBMY;wtMf0^v9 zFuv9t$7##ecGu9!VcOov>Eyh*ozZ~DDXFIqGcRs!>`&lw5hnC~ckW{Q5Vdi>QvcXK zobN6? zw^vRSt1Oe|zBcW^Sl-yk&|e$j-1~gB<9D)&+-CqXQ!i~k@;}}clPQ4O~?2ZaRE8G{Uzlpw(W&4S1Y+`6Xk7(HYcasO_`@D|%b$cu@`MI~< zK9W4KVlR3yOg4%05RP1h9YuQsgFZGlL8ea<`0LDl^f8)0pKft`d3kl#6fF8mjNiSr zCLO9WqF-O-VRym8{mN6k1%{O?-%~#m<&-Hgm(S)u84fL_UcPEg5w`- zMeo-(Ye`J~xebi1c#542>%=~O@1GB2xSrJ4*IT;<^rT;C|3cm6u2-8iy{Ku%WSwX# zQP>q>`nvF?T_H(Y4A+wDpc1wiKX5~!mC=i@s^Yn1HE%B!la-#7c==ho=$wf|+}W>Q zz3M7xTTFnFFn2mF1RcMV_qSm?Jej3n$0gXHP-^I>>{rt~V&|0-;{M_4~HRqbh1w|i{I zZ`XPF=Y{y$$BV|U9)^z39QvOp`F+z45Pz;DFYo$c{tKd#-!sIZtu;n@!aHSOx%ki; QlfWO1(>f}}Cv7kPKV~Sh=l}o! literal 0 HcmV?d00001 diff --git a/qr_with_logo/qr.py b/qr_with_logo/qr.py new file mode 100644 index 00000000..554df287 --- /dev/null +++ b/qr_with_logo/qr.py @@ -0,0 +1,53 @@ +import qrcode +from PIL import Image + + +#import requests + +# Load the logo image +# Logo_link = 'https://cdn.pixabay.com/photo/2022/01/30/13/33/github-6980894_1280.png' +# logo_response = requests.get(Logo_link, stream=True) +# logo_response.raise_for_status() # Raise an exception for HTTP errors +# logo_img = Image.open(logo_response.raw) + +''' +if you want to take an image which is already hosted on web comment lines 18,19 and use the above method +''' + +# Path to the logo image file on user's machine +logo_path = "github-logo.png" +logo_img = Image.open(logo_path) + +url = 'https://github.com/shashank-amireddy' + +# Ensure the logo has an alpha channel (transparency) +logo_img = logo_img.convert("RGBA") + +# Resize the logo to fit within the QR code +basewidth = 100 +wpercent = basewidth / float(logo_img.size[0]) +hsize = int(float(logo_img.size[1]) * float(wpercent)) +logo_img = logo_img.resize((basewidth, hsize), Image.LANCZOS) + +# Generate QR code +QRcode = qrcode.QRCode( + error_correction=qrcode.constants.ERROR_CORRECT_H +) +QRcode.add_data(url) +QRcode.make() + +# Create QR code image with a mode that supports color +QRimg = QRcode.make_image(fill_color="black", back_color="white").convert("RGBA") + +# Calculate position to paste the logo +logo_position = ( + (QRimg.size[0] - logo_img.size[0]) // 2, + (QRimg.size[1] - logo_img.size[1]) // 2 +) + +# Paste the logo onto the QR code +QRimg.paste(logo_img, logo_position, logo_img) + +# Save the final QR code image +QRimg.save('qr_with_logo.png') +print('QR code generated!') diff --git a/qr_with_logo/qr_with_logo.png b/qr_with_logo/qr_with_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..523858d0bd44b414217b079ded885770ed8f19e8 GIT binary patch literal 14818 zcmdtJbySqm`!703_W%;oh@fu+}WrdS~9fpS_>h&*!tBCstQmm6(8*00aUNKT}iI2Z1np z?ml=pz>^@F{-+?2MA3X(^Palwk{*%&pWI zz9y7<^2%gY0T%KJ%+%GB=e%)o%rRW|#PH%`o}i96@uk>bM!y#7e9MIA_B(cx* z`*#jJ{p6+OuiwG>`|CnX9)hzL-YqTpvfe|NnfwSEFd3PN`dT1nOiavCtb&@dvXLE_ zoGkS>4NO`2r3elS@O9$<29N&+LAua*EJyA5g)bBOxAu>IhkTvucwN9}W&@qIO|4!Q zwn7%T?n4^i+(-J}Xo*kss)E}RY0qTE|cEa#&t=1G5Vx>Y*ed=6nvYO84v%J#fH^zTZc&2@vdF^vS zj<*A>Hq|Kx+;Q+F5-pN{m8x<{dFs6B1!v_-#gSHRy;Wlz{QVcovtdZBb@KmDRs5G- zG!o9V@3ACfwd%2qWwpwbiL;0P35hIwaaR1IM)iN)+6ja0bIgsueQ>X>EK;j|{<44a zIP%7C@v@x1_8&*HP2Eei!6wRV!`P@h_r& zsjAbg;(E4XTE)c=Yd=z&YT}!G@rU(G4V2gOXCr}x4e}p!t(BdUg;N8ls8JE!xLPUr zbc)MI*Ji*NUSQ4y1w1Lp<{xyl285rp$2*y-J-k+#dOeoiMK3rVferZCV0(F8XRFuz zFU$XrrtJD+f4s3sW!s^&i-X(hb#QJ@HFjP~LRMU$uD$=T{7NUz!IhS=ryZOIz?N!N zt-3(t;YV5>oNX^FUU0VEAG~DSL2CTZ)K%%kJ_ue7!}!1g>;5#HrmyZg+u}MCl?d4} z@3iS%KoCR3XQoZL-kCW(CtNgorurO@nSkX6`C#_}b5-U8e#Exac{pL9W4$I*wv6Lj z$)KUUBZ)7LS~(J)2qL6M9+??44A&0pny;aansgKc{88;AF6H3osv5$;R?V^CKSa#; zt;ZG}6S}7xwnabtEk-s{4tH*R4hZ%>Zge#(?Xy*)#B1besCJlwCbN9Y7p6OFuB#gh zdm!ZCW>xR5fD%ycG+^)?*W)=}`}tnz4Kxy$2KT`|ft@crfP12jBZJS_9TOc8%y|pP z_7!UHBu;kUr09gwh9toQ?b$}hGVNC>->WiwX}16Qt|3}u6U5JtxFu7h;eg|S>=H&y zF++5BU6qJItZ>*t;JXo14Z8%eV#%3~yi4Te@p>iHrthe6YC&Gbsf@R ze!R!H5jFe*c#kiF{&1!_kOa5VmryLkfV}8^15KW;wj2$Vucf7J1hG6y80ANFdBbr* zrb@JSutPpG?QC$*MIiw(D8JM~j^<`k`_YmM4hl7Ghk4_fdGry^_?AQ&XK}?EOvR3~ zhy@%JPse@~LbB)~1#&pq1YK&+ye#Yuy#rr8{XJujEPHl(MU-GP=HW>jgrdMIHp-7m zNjm5@D0g)Fu-}00m|J`KP*&`8UEPJ}DdSj}LiU3Qese`8Sl^o^Vic~pmEvDsf>67J z?ky3QiP<;XuC3?;Brdg!t9hk}xoW_)ymRHb#Ia;^-sUYRRBiuwBbfAT^wtW~E~VpJ zOQ%nozB9)M8Mp-pTgm-7+#yNNOGm!e`d8i8m!25Vd&AlNqPP!|*MIa_+C14=pEb7w zYwJ#tcGVEtv^td_4(O4uZm&e<%>&mhe3>dTI7dx;z2T)99%mEBgo--qw`ul*n=Cn+ z4^uT2{Ru+Dz~o7+EO1y#ND^&jVMCNYE#e|~L7YTg{b7vq!ZisN@##}}NK4B{ zn=m?$-1-T3`m%b_HxLXOuX^cWC2lIEhpD04D!RtT@tZt6euHKt-DV^?v2Wi}35$pn zHh#oeU9|^<0ENCB>s?r24hRUWaWTdAJDC6}8T$r>`GgS0~t9 zC1+#Ek?Em&eW+ZRIhK?`PJBw-+Humy_Zj^Sd!4CZT6>r{e}#GJFz-%bG%$+$XPEpu zietQ+wen)*{$Cn9$|^p$EveZN(Q`<{h0Z~d2Z65n>xEEj(7^G?$VezF70Idnfmzbtp4;>1&p&+r`~%7WjYZ&f zvl&z_8a;o0X4!P|ZgS{yN;O%-HCOgUmb$;RBZ8TT8t|FO8xT>ebW{Aj1w59ehEpvr z&I*^e7t0V+3|mcV-VF>A5)xZ}s@^=4F9)f~L3m84@6iI#xxXj#59~hFpW)I*YrT~K zqtCjm@-ey&C#gT)2JcRLzc_0}x$g&`+w~&EbS;gdj*gDn&%g#*ehe&FLsIKIj&98% zn*wZXY@-n(sZsyEjSbqh`hm=m9y42|nzI(BrXjF-!ut;b!>YDzpD?OIt(d5|UxaG# zb>KNdcZxq%mSKRLT&)wdbuuKf!|{a_)zmg2&N@1zXx~5k?lZ$7Nt4FaD)xqy>cx6~ z`C@B_A^WSY*ovOI9^s3z~b4Mt=JI3AB*BsHJkTs|AizaCEb_2Fcy7Rv#|sLb@9# zjK+WehTpmgPiE#%xSM^{c4@t7EI47Tby^G>Hpt(Wlps`M9L^EI>y1wZYpnSSx+*9%z5q9#?R*u=G(lOcC3TR zG}FLIwx0 zj1Qzr#}Jb&gU0Ic`6*WGvui3WJYG7%k@VUV>5(xp4fr}DBxHuCB8&cfkJXbh%Eq-c zf^Da}kNL-Er*Qt2Rz zyZzUf0aZRWtW^R#isV|Q$OQJkb`bR)a(LV<=89w;^4x;M#|wG*yH# zh!iMsO%FWP?=etMCQ?8uSXnVS{K!s{``bwbk+CI{9v-|8#vb;z z@XL>GVywl3Ht$>h$QHm14i0ulnx9c7P2?LJ8P$IJ*x?}o!UgBVzayu_z+s_egJ-<4 zKw9|h2M?q7>*je<$Nch3RZDW0#c62hzm2as{B7EC`;jj~m|q$vh=mzK!}%lMn`Y0- zN9?1vE23+`I!Zuy)A{{LdAUnghVgS5LK;PWk^)S`aE6py9RZMJc@ z{@3uQWa2)Jh6&a^dKS2{V2-jdZ66c#w)MG=Znrm~r~VH=Y*fpe-<)}uVad#l$*knD z3He%E)U09wpW0n#+=exV)NXjUrRJyy*Tt;FRm3HxSWAlR5(E_S4p*x~+CBM2pQm0~ zTv2erpq_t~ABIV}wc1aujh(A7-4$YJ{FZcoh=PF`*q==6vTu<6mi3%fF3Sr!bo0X0gQC{f7WZZ1$>kCX zo$t013i-)qHFm5Hf8mvky$E_@%a+9HAQ!e3?@%oT3TDR#V>_NXJ(9Zw^-nv2Vbk= zhlXaw&v%lS8i9xb!NX}U3F}t)Z1ROFlaex9)RnfpqGAkMoDrTv{w8fEz>D$$2+*Fg zSuT`yzL!MizLr*EPCx)FmaF@wqg-_BzDX4DH@Z4i55A}FKfCK{mS|MY+fe_q)2bx? z&PUsXB_-n6@xJt>J*A*Hk~c=stiN-~lD)~DpYy!lz!%h4Cn6>;gu}6QWUu&vxz7XR zORTwfrRHxKt6CRTG+o_Pw6uulTAWzs0;kKwZ%)o_)eX{bmrOoO5l!1eb}6KNpeU)J z!XUu<(MR8lFMcVJF0UF}J_W*>q@<)f0;P?tYu$%U1Qa~&P88rrd}wN-ew=qS>;y!e zSFbi>4i!7)o809>&=NY(_4$tApvERw0#vNDnKY@E=6Aa&1@X~Id$7aXXo^%E<_XBu z#Tv(c@VsVagIxkyFA|4=WAxWd{QS+n#U}PKN-7JL#UP?BdD{M>-GOIdU?4^95x=l7 zmJY{{Y*_{-^a9FbldS+@6U|6qt)qr5)A&JEG{5h%n2GL0JUZHReQ)-nj}MwCwckQV zC;A!&z6XcH?~?EgdiEj>3nek8{PplTWV)~+Ney2{8p~p`Z?B5i+#UVZ zB>IDP;#b$8W#ZRU7dSC%992m!9;$X|r zzu4TB>&1Uu5Cxx{51p701oqDu`Hyp_zFCS*Do(SGgJ5(V{+?GX(Tqh6 zsl7<-n?s(+qoX&{sFh+TH#hC*fetJi|M~sf(0JKkj;*aNM8+e+dt5o1MXjZ{(Ze|r z@JY)=Qs@EZ#?IeFAgMse8C@wf0Xb`Z)4s9}gbzsF()u4|jDfCQJuIjJy?m-FSF|%= zCCQP%^dyy|zl)qyyyl@fLJrn_aqEYP@X1BUFpsLCJ)63QhLH9&@D>9D!^M)J@lw=w zmV*e(6Fl_UnGd~h4+o8AB_BQduf94Dd?Z==dgLttDR-NUUvSHS^P}0>R|L|()=BHx zkm2yx)wO&ybP>`}_cPu9It`p&KKpw;#s<)+{BdtHFYVU0K;Q&7pj(pm_I4-d*D!s~Wf`1^-8b~OxuOu9(9dr4^e3XF+VA7| zg3xcwJ$IW%#>d5%M6N9hJ)i-oVbj}v-%cS77ooGHPG#(`KE<{S+O+rb@+m5> zBTr0B{8U}7WN64XFi_-f;rmS#D~#@hpm_8NCl?n0OQI17mGOyjYbPf>zV>Uuj0wP! z!`A&#*KZlHY>bV4TNvs9=p=wc4c$u54!ofMW?M^^Y&al}pgBg$$zCK`wEFCN(Qm?T z%E?F3{CH(umm>UwoaIJRZqMM$cp|pp3CkYoCUv`c^Zb48CH* zvlu!-OG!z&sm_zXuE3FbC6=BKmoPm*$;2-iUezWoe<&)tC+M9cCUq}A>&FqqAQ_08 zF3*jOmc}$>6VYK|WbKZ23GVcTICh5vsF2$(=dS8a$tr3Vf(O6}BEAe7v8Ocrl`u*Z z^6WWYSYaUxeZY4X@%=W>YfJr!_HG%OhNHMQa#%=#j}#)CHO9GY&5<>SHcZ{0NEx!1|Vxu;e6-U6f9m z2R-i1&CSI@v}{bv^z_NgltbqnQIV_}X$gH9WZBQ3ApW(a6I95jPR(M#mzgdPa7X9o z<%*26o$bE(>`s5JZa+)@t%z4xxBrnmk|ZL9APbBG8sOxVx(=oDkJaXg92ii~^BqF! zLuEU_MCg#YHh*^uY6p6oG>9UepSsOl+gA`m&V_I4+;dohE;BRJju$DJq^pQ`y*W(k z3qs4g@;2r^VFJ#W=;Z31?Z=bh1CLOs{?m|^EAL~rnVaw9IHnw`9Ps(WA>W~c$KB1F z%O>iv=r9cW;Bl#1_r-7z?X*9~^avVy@0HYSp+HevrNeM1gD$>YBLj;>10C5{il`3v z?jU;46TJ;48k$3T^r~KjDibs)YQj`X@OX6;AoCu-xz<{FY`-S6Dd>A$9&)%KAVbCfR8h(B#bFfU z$#QcZ`pI1Yuj~Vl6*^ohz)xL0_62toHsPAx*^UXW*DLqCvY`5c(0e*@dHx9g{CL)@W(KlZbYm^!G9J7Hz@$-AB@^m8K2O<(>5) zR^E8TvIn>9+J={Z!yz8Qa|l2L+#W~d>RMUhR);F`FZeUk($c!$VnV<5LN8rfvcwtH zIq+C&F0zZsl95756jgU4t(W~^bBiGW0aj$>;^H#%c4FdH*xlJ6#H$tL^GAy=az`|_#JMtqR;!OvTwY538zGBxl9Z&P3> zGi|XvCvspTtSjeh3T4QWv*2#96m2Q^eIO^Pb?UwcS|(IX=hSKp^rZ&8l1b0d&`>u^ zS@l;LrvO(zl#I(rT5gZ=&4>>nHLtw4_h}3gAh^IikCqPWPU%GJ*MpX0+3^9fCtAF> zaTn*;`D6%{@xp+t67ZmG0lR=J-#-NG8PbR222QT7O2Vf4HSOK<{1InixVKo$73vq0#qBUE!1x_>%pTwGFe5Eu~({n}Jgf|c9!`e`6)=w!c+vVM_8$noP_ z-JMr%b_t;Z|B*_3SK{T7_wvkZdy5l)a1na9mN`JO9*G|_J z_CEU^EuGL@=4cm`kG(Nc`LdU}B%F<2FJHZyOye;u1)v(vZXL|$Gj80~9#I@flPbb) zb9ellT!H*ecn^u~`oh3~m}O-{l#Cw%1vczHuwie(F%DPl8TVFKaYHN_Eo<7Q2%M69 z85Z4FS62fon_8OA!#{z6BP6sx!S1gj9$=4$au%G|>JQo64bmMDoH5s3rU6~a z$<2GR0aH2ighh&7%q2x$%+$gW20$zgiHR98BIya<+ihp&!~($M z3zeMiaT?339eS9FuTJu<*m7Ij18&9wnQeYQ%Q^t|=cs*v+tUJA9%147*r|6fpOL0m zRc=Ba?-m$A_ihB!ijMY5mzf5aNemfB_c7?q%v?a%>YpA&b?3WpJ=lcT;h4*x8!4u~ zdKx2YjWKT9vqx0OSM^4JoD6tJM$}X@alMTrp;+Xo7F!yg7E}A_jqlbyKD{C~n` z#my%U1OQzV6O$3&e7p-+>w_vgYD}720kV1x}!?T@6tE#7pYht;`++9v?Z-goUE*vb`X^Nc;+$;qiJ zjcp&t-P-jY$gI&VV!N4D`=cTrCX4&`A2~N)XKai54W|m+>)vH)CTvzcu+t@vwcc(t zA|fLBh$KQPabQn+xUW4ZWu>Cy++g;)J6JLO&gB^5AN(p!My<7VuPy>u?DcFTF&kUX zcJ)xc_lrf}_x+}kDE!CUZ0WHdzL{Q$lQ;x7Htm0V%VRdyNtew0WJm^O=j7}R0ATI| z?^B$DtCdJJH1P{hc;|ebJ>m3>ZxV-cRl{3;9M5&eA##`JHFpuC?PZzj$F6*}bES^l+aYb1|?hz&(;i-&VaiY?EVsMszD?0|Se{ zygJ$aRjLE&?~kHbRagwFi$(CeJxrZi#9ho6!7!!EP|>)fZx=X3_AJ3Qjxx5v!7^x6 zXGe5lq2JYcWS6(a&h+oFiq132w&U-<@*LR62e-&s5BeuMHkZf4#lohNMZP?20D6t5 z;+bA-(O&e5DH8u2;UxtKuXX`r@Z6=?AlPory_F zBzP=}vqD4!Ns#$k%z};$#h}Z0V+9Ux`5F59KU)nhHEuUJzz7abs$qTc$+rF?oKA~3 z$`tl2vckejF7U8a-%)RR+~AuVzm-uWi2el_XSg_{XSLvl2)#THQ3fVL=cwI>)`1``8Qu!ifp=n%3T9L4jw zdD5$@BlU9TnhtjiMCJYroE@j`>U7BMf0bkcQpNbEqgX6|R7-GhhsAFS=n@6WG`s`V zIKatBk9ElY+^OF~+Xne$1=^uWAoS)L&5rC@CSoTZnS7YL*+b$b8rO|I2a7;3*y zZ(mwahFyG=A`^Vicg|aE=}>$ndp#{l0H-z#tpW-a=<_ssv>j7pHTM0iH*b3u57qQO zrPEac(%HUS{Y+vvcz?d;F4S=hkPd=VyC=&wz*J?EcnI& zpzn840W_fBhK3hiCXP#H^Vc}<-q99jFbXUSUidIb>$sTFF$V77OQXLT_?hY7Ao;q>O7jx@JxPa~EpXLcZb>Ml zre_ZKmUVhYM!@vQXPvmfO>08xpW#EfnxL1ogA_79mLlD+HSd^Jvs;R*2m@WImFf@%P=(TTZzd)KgC6LN#I zGc}r|${0)pIG%gnVdW}eK5E=R8*%dXRko0$=-O~@w1lTaaYvO~!HfWz0$uQW>wIq_ zz)1l)#G-#7dsIu+Nj;UD@%m8dRbcBpCLSsO14mMTY{vzNV&H})HIW%+3;)NU-XW)}S!fvgfR!{ox+LJY)3mX>PkEh*{3_GAzRaQy(BH1fJ$Dw^z@uRe_D(f9;9HVmlp^)HZXLIjW zN>;R%3$ZKF%c#jbyh>si2w=cG{sw9*Ladm~eRT?5Szs8T%C@kx#>xowG7cJ_^W;&0 zK#u?jbb8j3aCR72{nhXBapBd^UxtEA@L1?oOC0-X?7)dCwUrH&a#x2uWwF?HS^7`l z2Zf|9| z3&3(|4*0m~cJDesXCpRCt3k{b#vg|l5LkpexHTs&kkSw_(d>t*c)(7?K5oM;K<&VR z3($KB3Q9^c9jNx(Zw5MY5o(Xp_A>3sHTCv4cl)f+S9k!Kv8c7M)}hV;umiT2aqG2i zvsWi$Nf9hlrSQqwP&7Jh94klWHs9I6|8CZUv{;jaN!KHKMeJl;0ZMF^YcrOhL#wJh zPPnEs@q+|MjF1oGzb6*DXcdkxc+TBQ zO^V)R0VYUrVq$?E21W>8_CdeC;XD)IReSCPDDHl^SsI!SC`LX*PQZ5!Uf3ZJRTP)Mi0U6e*nS=aV zH~n@lQ1{MEq?L{MJ_itIE*I-G9VQIQ_%JsK5T~knca+i+}kAP zSJ~aI(6-%7QR6vT<;AD#l9->*SYKbiFnfE#+jbiB)ag^T>cgC_iOQLSEf=oCt%~ZR z(k5!)@R5*^1+LeOjm2cIQb`w+X51cp!Fu^HYS{1Q06El`t|OE9?plTfej5gqi!TN%G}8w%lry3mfW=fo^5oC*HP3re#rcRkOq6Vp2CYsxHy8K>+s{6lPkIrL04MfOo4#`=1dg= z;oEE954qm23p5auKdHX2@{kw6^m-;HIlnZr^$CcG`^ILnxI+BJsVCWa z&U|Z~u)KPu5paOLP!;%gQSNpfY4Uh1pUyf&V$ZL5Gin~1F%BnUg+kZ z+0hS~VkuX%F*Kv5#UEQ}je|F>4yTrNlJI*!Od9Ixg<0J!`EZ-ogQa|S4q8>JaxH~E zHH42z22T>OVCB(|U()kTQkRE=gO>VBJyxkZ6W(oYX)XgrF+f-1GFvXd z{JRHC5FsvR4xJs0rWf@5IAOYOXP&ZQz5FrW!E6_DH zm2}{ErmJ(ZlN@}Jb9{p`^`hQQB zb4RB}YKBqF4!s`qUcToGpM|uMkdV`3OajGQQA709+Om#x>>aDW6swE?d(oFAgdI0F zwR``*8QhaKSKn0Qu&3dT7sL|+if)MbJaq*q4mx)-y>^`;K+xP(RKqQ19|lq;Q~i7J z`$L@v1{ZzRA@BFdNIJVKJNHIPsE6t7z_H4}n%|LhGt+oNUyaMtTLY1R81q(}{w`e` zYF|)%Bm?1N*?3Z!DAeFTa5e+^`jv$|HX|m3eg{kM34qwAo`KXkAkN64-FEd&OBNU= zRKf4v*feQ_(|xOpEWYI}2zR7@$gs;wb0Lj~*wv!%?b)pbV|~B}+@rkw^~>!?7(v@t zbncgw#)Sa?lB)K|K*!Lf^8LU-`CP&6PH8(p4e1!Fb0iV!*Dhmdi@JmS`ju@h*Q*-E z8UzGbVBbFR6FCG=O#WW{$TXjD4&5kz(HVkiK6wfW%&>W;tot(1OAY%^>Y%u$)yJPp zkceGx3+h}^S46aI015iI6B^nw{m#oKbd;1#@w?NjS35~F(4)1YNWyjh{B@5qtUt{A z5%VYm?#c3A*+#N6RQGBqVV4FGaeMoh_FZ_?+FNY>7(u&)aHb5X`_0ORVsk{Sgf<1a55OB0;J6!%3keA zcHd`%xz`KS7R>t$Zu#<929*FpNChEAo?Ozp5TIVXs7>fLahIhDlToaTCG3hP?MvGE zJKCcCYIfO*{kPp1OLGoHnh|Mebwwb1G3t2$K#&r?K%8xybM{~nf#~)0;P-jqAX0>& zab*C*dfqL*c}Slj4GoRFmex;8McqI}Jk?jTzrGfG&!#QUwaL=(0$eNSyY; z=ztzMt$bXn%MDRV$PF{dY-Za1r&wp?uOUA~G~q9)aac^gH-p-M>Nes{?paP;3(__m!LmxaPB;ok$?}31GX)X|fs(tf&`w1UcuKTPW z3l@1S767lJ9y4AF0XKEmiN*v_6w0$1m2dC2vDj%nS!MC5yj)S3c6R0kGpHDrk_5hY z(=IdYwLj;bAiz#r|8xquP}e8W^P?w(aR4ZTdW4U{aC!y4*Sl9?Y-w`(TFc_sjQM2Q z#Pl&}lexFy=Yk+mccE+rm80jVwMGZ!`Sk?q8W<$1G6mA}bzBp04h(u41(~VG0;vGE zIX{!*dw(1N6ZrwB#X)i=SE?Gjo}o!>+PLZW_WE{=`m`}`8J*KJuiXIGn$G>^QP(bJ z?jMssji!c`E_;~s9szYgJS2+DB7bqZJXll3T()yt1_rp2gb`g%s|qhkl)I|0Y!eiK zO1sxicnF$|%(q3-(JVA6`VXn%ZTP7oLgin*x(_gno2%fQX>&XqdX9`S1f?RgsQ7{Y z`JRQhrJz5}wdDu;4hT_CPtfe^$Q$VlKBAsyB23`;Cnt562oc}^(!!oqXjXxnZKVe+|$+dK@`_WC% zeX{MxD9v|#L=2SHS!_PAg9*3;>E=>Tvem)K-J6_P5p#Tx`@rxTRqZJ;#7H`DMr@7pnthKbNo%km4yCmovV91ZtJ^2e&?UH-?)OM_j(B0qWd9kTyh zQ2b!<+ErKGE{y5S2mcbEOU4Hel$y5DGElyCHWpXj^fk#Ky&7xW=d(~E zhP8EllpNu6JeCEH-$KG8=cZ6Ah$mqGxmPm+c3~7Dhbc_we+DMkSIXNdYjg3UIGL+W|S!@#IO#1#)49hy%y@AUVzFjzW z>XLU={a)?cB+=P<0}|(IopV)7Lq?^Wv@`GAv^V6hW4wZR?fRh6f9ewSY~)yA?G^-& z@Gx2Lk%82U;9P?PT$0I>4jzL*RU>KE7)H%{(tUIZWf=xDUSBYF3AhK3Mbr73&!T1g zw)8`DQ|JUi|4Z9oY0)VvI(jFyZ_!CKXTrEVAWR#%y)Sow{MeprMF2R-Kh+d~d**nt zsbCnGc$ww8%eOr=pDkM5dgG`qoy-oeE;(jWF{|8y`~~o+(RzBv(@60cIWggc}(8XInqnoB-ufz=N~+EuYVfCHVo)qH^R7 z41DIpF~UrAVHcxFQ+yg@k`3tC8vqG(q8+uKH&Mh9bYg9buU%X!r@nq^Z>gwga<;DN zd`On8Dzhp#T6H~9Y(2@aSw2~lUOrc=qN*8sRb3;ILg{{v>XB}PW3*TMfkHlk2n^$UJA;$}RtA- zjazNBu&Jg==lPc=kN>k#=B%cYToq`HnL1~+qEtUJ3}c@JnsP1!pkII~v+DZ(wLD*= zii`ce#%gMiAwj><)Qp7H4E341$YsE6jd3{efJS{pHrdl_R?~jq!leYt;e+UBMnKi}<{ioa0Mu*=TcL`Bw zhj^L)rCz81G}xGKa1FlX+Q}rW%iLCH>C?Ytv7&rl*GHg+1-tdUe>R|T+4GM&e92`+ zNpWQ80rY`b05ebu^q@mlTFCVphqJ2V)Gq@%%m+_VWM|95lT-iDQe|Rn5+yk3y_!&C z{PDYYWMa)eWQvQ9Qlqal$j}Wxa5cBa?jN=pF(8;>+^4Vi$n3Iwf#Pg{^|HL4{Op`{ zCo}QL@Y&;km6UyllH`cZYWHp^t4!55JXV=zJ?Iu2Xvb?xjmWHj>bJS;iF#v!0b>US zH#zcdyRU(rVq2Dy?qX9duaxsIk%A%$P8bvO-FAoUf5X Date: Wed, 2 Oct 2024 16:08:54 +0530 Subject: [PATCH 006/127] Updated Code and Readme --- {qr_with_logo => QR with Logo}/README.md | 2 +- {qr_with_logo => QR with Logo}/github-logo.png | Bin {qr_with_logo => QR with Logo}/qr.py | 0 {qr_with_logo => QR with Logo}/qr_with_logo.png | Bin README.md | 2 +- 5 files changed, 2 insertions(+), 2 deletions(-) rename {qr_with_logo => QR with Logo}/README.md (93%) rename {qr_with_logo => QR with Logo}/github-logo.png (100%) rename {qr_with_logo => QR with Logo}/qr.py (100%) rename {qr_with_logo => QR with Logo}/qr_with_logo.png (100%) diff --git a/qr_with_logo/README.md b/QR with Logo/README.md similarity index 93% rename from qr_with_logo/README.md rename to QR with Logo/README.md index aa90998e..d0e7aced 100644 --- a/qr_with_logo/README.md +++ b/QR with Logo/README.md @@ -17,4 +17,4 @@ This Python script generates a QR code with a specified URL and overlays a logo ![QR Code with Logo](qr_with_logo.png) ## Author -Shashank Reddy (GitHub: shashank-amireddy) +[Shashank Reddy](https://github.com/shashank-amireddy) diff --git a/qr_with_logo/github-logo.png b/QR with Logo/github-logo.png similarity index 100% rename from qr_with_logo/github-logo.png rename to QR with Logo/github-logo.png diff --git a/qr_with_logo/qr.py b/QR with Logo/qr.py similarity index 100% rename from qr_with_logo/qr.py rename to QR with Logo/qr.py diff --git a/qr_with_logo/qr_with_logo.png b/QR with Logo/qr_with_logo.png similarity index 100% rename from qr_with_logo/qr_with_logo.png rename to QR with Logo/qr_with_logo.png diff --git a/README.md b/README.md index a924eec8..848a0d73 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ More information on contributing and the general code of conduct for discussion | Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | the pigeonhole sort algorithm to sort your arrays efficiently! | Youtube Playlist Info Scraper | [Youtube Playlist Info Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Playlist%20Info%20Scraper) | This python module retrieve information about a YouTube playlist in json format using playlist link. -| QR Code with logo | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/qr_with_logo) | QR Code Customization Feature +| QR Code with logo | [QR code generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature ## Gitpod Use the cloud-free development environment where you can directly start coding. From f2565cbfa0564781b400c9edcef3338ef490c0dc Mon Sep 17 00:00:00 2001 From: Carlonii Date: Wed, 2 Oct 2024 08:10:37 -0300 Subject: [PATCH 007/127] Updated the list in the main readme.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3889ae25..9d5dc640 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ More information on contributing and the general code of conduct for discussion | Password Generator | [Password Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Password%20Generator) | Generates a random password. | | Password Manager | [Password Manager](https://github.com/nem5345/Python-Scripts/tree/master/Password%20Manager) | Generate and interact with a password manager. | | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | +| PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. From 43064a606b6e816438affa82a5842f4867e59615 Mon Sep 17 00:00:00 2001 From: shashank-amireddy Date: Wed, 2 Oct 2024 19:37:19 +0530 Subject: [PATCH 008/127] Placed feature according to alphabetical order in readme --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 848a0d73..70b080d2 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ More information on contributing and the general code of conduct for discussion | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. | QR Code Generator | [QR Code Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20Code%20Generator) | This is generate a QR code from the provided link | +| QR Code with logo | [QR code with Logo](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature | Random Color Generator | [Random Color Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Random%20Color%20Generator) | A random color generator that will show you the color and values! | | Remove Background | [Remove Background](https://github.com/DhanushNehru/Python-Scripts/tree/master/Remove%20Background) | Removes the background of images. | | Rock Paper Scissor 1 | [Rock Paper Scissor 1](https://github.com/DhanushNehru/Python-Scripts/tree/master/Rock%20Paper%20Scissor%201) | A game of Rock Paper Scissors. @@ -125,7 +126,7 @@ More information on contributing and the general code of conduct for discussion | Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | the pigeonhole sort algorithm to sort your arrays efficiently! | Youtube Playlist Info Scraper | [Youtube Playlist Info Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Playlist%20Info%20Scraper) | This python module retrieve information about a YouTube playlist in json format using playlist link. -| QR Code with logo | [QR code generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature + ## Gitpod Use the cloud-free development environment where you can directly start coding. From c36b7f7ca80ab85e0e2d0ec582a737c30d7e318e Mon Sep 17 00:00:00 2001 From: Prem-Kumar-Dev Date: Thu, 3 Oct 2024 00:39:02 +0530 Subject: [PATCH 009/127] Added PDF Merger python app as permitted in PR #277.Kindly add hacktoberfest2024-accepted label. --- PDF Merger/README.md | 73 +++++++++++++++++++++++++++++++ PDF Merger/pdf_merger.py | 4 ++ PDF Merger/pdf_merger/__init__.py | 0 PDF Merger/pdf_merger/cli.py | 51 +++++++++++++++++++++ PDF Merger/pdf_merger/merger.py | 31 +++++++++++++ PDF Merger/requirements.txt | 1 + 6 files changed, 160 insertions(+) create mode 100644 PDF Merger/README.md create mode 100644 PDF Merger/pdf_merger.py create mode 100644 PDF Merger/pdf_merger/__init__.py create mode 100644 PDF Merger/pdf_merger/cli.py create mode 100644 PDF Merger/pdf_merger/merger.py create mode 100644 PDF Merger/requirements.txt diff --git a/PDF Merger/README.md b/PDF Merger/README.md new file mode 100644 index 00000000..de2b0a58 --- /dev/null +++ b/PDF Merger/README.md @@ -0,0 +1,73 @@ +Here is the `README.md` text specifically for the `pdf_merger` folder: + +```markdown +# PDF Merger + +## Overview + +The **PDF Merger** is a Python script that allows you to merge multiple PDF files into a single file. It uses the `PyPDF2` library to handle PDF manipulation and provides an easy-to-use command-line interface to input the desired PDF files and specify the output location. + +## How to Use + +1. Clone the repository or download the script. + ```bash + git clone https://github.com/yourusername/python-scripts-repo + ``` + +2. Navigate to the `pdf_merger` folder. + ```bash + cd pdf_merger + ``` + +3. Install the required dependencies: + ```bash + pip install -r requirements.txt + ``` + +4. Run the script: + ```bash + python pdf_merger.py + ``` + +5. The script will prompt you to enter the path to each PDF file you want to merge. After entering all PDF files, type `done` to proceed. + +6. Specify the output directory and output filename for the merged PDF. The merged file will be saved at the location you specify. + +## Example + +```bash +Enter the path of a PDF file to merge (or type 'done' to finish): /path/to/file1.pdf +Enter the path of a PDF file to merge (or type 'done' to finish): /path/to/file2.pdf +Enter the path of a PDF file to merge (or type 'done' to finish): done +Enter the output directory (leave empty for current directory): /path/to/output/ +Enter the output filename (e.g., merged.pdf): merged.pdf +``` + +The merged PDF will be saved as `/path/to/output/merged.pdf`. + +## Prerequisites + +- Python 3.x +- `PyPDF2` library + +Install the prerequisites by running: +```bash +pip install PyPDF2 +``` + +## Additional Features + +- **Custom PDF order**: The script allows you to specify the order of the PDF files to merge. +- **Error Handling**: Handles invalid file inputs and provides meaningful error messages. +- **Output location**: You can specify the directory and filename for the merged PDF output. + +## Contribution + +Feel free to contribute by creating an issue and submitting a pull request. Ensure to update this README with any additional features or changes. + +## License + +This project is licensed under the MIT License. See the `LICENSE` file for more information. +``` + +You can copy and paste this directly into the `README.md` file for the `pdf_merger` folder. Let me know if you need further changes! \ No newline at end of file diff --git a/PDF Merger/pdf_merger.py b/PDF Merger/pdf_merger.py new file mode 100644 index 00000000..d71205d2 --- /dev/null +++ b/PDF Merger/pdf_merger.py @@ -0,0 +1,4 @@ +from pdf_merger.cli import main + +if __name__ == '__main__': + main() diff --git a/PDF Merger/pdf_merger/__init__.py b/PDF Merger/pdf_merger/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/PDF Merger/pdf_merger/cli.py b/PDF Merger/pdf_merger/cli.py new file mode 100644 index 00000000..6ea13abf --- /dev/null +++ b/PDF Merger/pdf_merger/cli.py @@ -0,0 +1,51 @@ +from pdf_merger.merger import PDFMerger +import os + +def get_pdf_order(pdf_list): + """Prompt the user to specify the order of PDFs to merge.""" + print("\nCurrent PDF files:") + for idx, pdf in enumerate(pdf_list): + print(f"{idx + 1}: {pdf}") + + order_input = input("Enter the numbers of the PDFs in the desired order (comma-separated, e.g., 1,3,2): ") + + try: + order = [int(num) - 1 for num in order_input.split(',')] + ordered_pdfs = [pdf_list[i] for i in order if i < len(pdf_list)] + return ordered_pdfs + except ValueError: + print("Error: Invalid input. Please enter numbers only.") + return [] + +def main(): + print("Welcome to the PDF Merger!") + + merger = PDFMerger() + + while True: + pdf_file = input("Enter the path of a PDF file to merge (or type 'done' to finish): ") + if pdf_file.lower() == 'done': + break + merger.add_pdf(pdf_file) + + if not merger.pdf_list: + print("No valid PDF files to merge. Exiting...") + return + + output_path = input("Enter the output directory (leave empty for current directory): ") + output_filename = input("Enter the output filename (e.g., merged.pdf): ") + + if not output_filename.endswith('.pdf'): + output_filename += '.pdf' + + if output_path: + output_filename = os.path.join(output_path, output_filename) + + ordered_pdfs = get_pdf_order(merger.pdf_list) + + if not ordered_pdfs: + print("No valid order provided. Exiting...") + return + + merger.pdf_list = ordered_pdfs + merger.merge_pdfs(output_filename) diff --git a/PDF Merger/pdf_merger/merger.py b/PDF Merger/pdf_merger/merger.py new file mode 100644 index 00000000..4e3164b8 --- /dev/null +++ b/PDF Merger/pdf_merger/merger.py @@ -0,0 +1,31 @@ +import PyPDF2 +import os + +class PDFMerger: + def __init__(self): + self.pdf_list = [] + + def add_pdf(self, pdf_file): + """Add a PDF file to the list if it's valid.""" + if os.path.isfile(pdf_file) and pdf_file.endswith('.pdf'): + self.pdf_list.append(pdf_file) + print(f'Added: {pdf_file}') + else: + print(f'Error: Invalid file - {pdf_file}') + + def merge_pdfs(self, output_filename): + """Merge all added PDFs into a single output file.""" + pdf_writer = PyPDF2.PdfWriter() + + try: + for pdf in self.pdf_list: + pdf_reader = PyPDF2.PdfReader(pdf) + for page in range(len(pdf_reader.pages)): + pdf_writer.add_page(pdf_reader.pages[page]) + + with open(output_filename, 'wb') as output_pdf: + pdf_writer.write(output_pdf) + + print(f'Merged {len(self.pdf_list)} PDFs into "{output_filename}".') + except Exception as e: + print(f'Error during merging: {e}') diff --git a/PDF Merger/requirements.txt b/PDF Merger/requirements.txt new file mode 100644 index 00000000..e9a5c8ea --- /dev/null +++ b/PDF Merger/requirements.txt @@ -0,0 +1 @@ +PyPDF2 From effd66f8f6706d658bebad34f349baaa016a6fd0 Mon Sep 17 00:00:00 2001 From: Charul00 Date: Thu, 3 Oct 2024 11:46:02 +0530 Subject: [PATCH 010/127] Web Scraper Script Added --- Web Scraper/README.md | 8 ++++++++ Web Scraper/Web_Scraper.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 Web Scraper/README.md create mode 100644 Web Scraper/Web_Scraper.py diff --git a/Web Scraper/README.md b/Web Scraper/README.md new file mode 100644 index 00000000..5c796460 --- /dev/null +++ b/Web Scraper/README.md @@ -0,0 +1,8 @@ +In this script, we use the `requests` library to send a GET request to the Python.org blogs page. We then use the `BeautifulSoup` library to parse the HTML content of the page. + +We find all the blog titles on the page by searching for `h2` elements with the class `blog-title`. We then print each title found and save them to a file named `blog_titles.txt`. + +To run this script, first install the required libraries: + +```bash +pip install requests beautifulsoup4 diff --git a/Web Scraper/Web_Scraper.py b/Web Scraper/Web_Scraper.py new file mode 100644 index 00000000..f1f0d62b --- /dev/null +++ b/Web Scraper/Web_Scraper.py @@ -0,0 +1,30 @@ +import requests +from bs4 import BeautifulSoup + +# URL to scrape data from +URL = "https://www.python.org/blogs/" + +# Send a GET request to the URL +response = requests.get(URL) + +# Parse the webpage content using BeautifulSoup +soup = BeautifulSoup(response.content, "html.parser") + +# Find all the blog titles on the page +titles = soup.find_all('h2', class_='blog-title') + +# Print each title found +print("Python.org Blog Titles:\n") +for i, title in enumerate(titles, start=1): + print(f"{i}. {title.get_text(strip=True)}") + +# Save the titles to a file +with open("blog_titles.txt", "w") as file: + for title in titles: + file.write(title.get_text(strip=True) + "\n") + +print("\nBlog titles saved to 'blog_titles.txt'.") + + + + \ No newline at end of file From 83be91a259357e7c77e0440a92c8e8964ffc88a0 Mon Sep 17 00:00:00 2001 From: Prem_Kumar <43103958+Prem-Kumar-Dev@users.noreply.github.com> Date: Thu, 3 Oct 2024 20:03:28 +0530 Subject: [PATCH 011/127] Update README.md kindly specify any other changes if required --- PDF Merger/README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PDF Merger/README.md b/PDF Merger/README.md index de2b0a58..75003631 100644 --- a/PDF Merger/README.md +++ b/PDF Merger/README.md @@ -1,6 +1,12 @@ Here is the `README.md` text specifically for the `pdf_merger` folder: ```markdown + +## List of Scripts + +1. [PDF Merger](./pdf_merger/README.md) - A Python script that merges multiple PDF files into one. Useful for combining documents easily. + + # PDF Merger ## Overview @@ -70,4 +76,4 @@ Feel free to contribute by creating an issue and submitting a pull request. Ensu This project is licensed under the MIT License. See the `LICENSE` file for more information. ``` -You can copy and paste this directly into the `README.md` file for the `pdf_merger` folder. Let me know if you need further changes! \ No newline at end of file +You can copy and paste this directly into the `README.md` file for the `pdf_merger` folder. Let me know if you need further changes! From d9ecdb12482b3cabf8ef3be5038cd143161b113a Mon Sep 17 00:00:00 2001 From: Charul00 Date: Thu, 3 Oct 2024 20:10:15 +0530 Subject: [PATCH 012/127] Update README.md to add Web Scraper script --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b5090ad9..70b49df9 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,8 @@ More information on contributing and the general code of conduct for discussion | Weather GUI | [Weather GUI](https://github.com/DhanushNehru/Python-Scripts/tree/master/Weather%20GUI) | Displays information on the weather. | | Website Blocker | [Website Blocker](https://github.com/DhanushNehru/Python-Scripts/tree/master/Website%20Blocker) | Downloads the website and loads it on your homepage in your local IP. | | Website Cloner | [Website Cloner](https://github.com/DhanushNehru/Python-Scripts/tree/master/Website%20Cloner) | Clones any website and opens the site in your local IP. | +| Web Scraper | [Web Scraper](https://github.com/Charul00/Python-Scripts/tree/main/Web%20Scraper) | A Python script that scrapes blog titles from Python.org and saves them to a file. | + | Weight Converter | [Weight Converter](https://github.com/WatashiwaSid/Python-Scripts/tree/master/Weight%20Converter) | Simple GUI script to convert weight in different measurement units. | | Wikipedia Data Extractor | [Wikipedia Data Extractor](https://github.com/DhanushNehru/Python-Scripts/tree/master/Wikipedia%20Data%20Extractor) | A simple Wikipedia data extractor script to get output in your IDE. | | Word to PDF | [Word to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Word%20to%20PDF%20converter) | A Python script to convert an MS Word file to a PDF file. | From 60706e6f12adcc6304142b9d351455863a5ee2e5 Mon Sep 17 00:00:00 2001 From: Prem-Kumar-Dev Date: Thu, 3 Oct 2024 21:10:35 +0530 Subject: [PATCH 013/127] Updated main README file as permitted in PR #277.Kindly add hacktoberfest2024-accepted label --- PDF Merger/pdf_merger/merger.py | 4 ++-- README.md | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/PDF Merger/pdf_merger/merger.py b/PDF Merger/pdf_merger/merger.py index 4e3164b8..3cdec3ea 100644 --- a/PDF Merger/pdf_merger/merger.py +++ b/PDF Merger/pdf_merger/merger.py @@ -6,7 +6,7 @@ def __init__(self): self.pdf_list = [] def add_pdf(self, pdf_file): - """Add a PDF file to the list if it's valid.""" + if os.path.isfile(pdf_file) and pdf_file.endswith('.pdf'): self.pdf_list.append(pdf_file) print(f'Added: {pdf_file}') @@ -14,7 +14,7 @@ def add_pdf(self, pdf_file): print(f'Error: Invalid file - {pdf_file}') def merge_pdfs(self, output_filename): - """Merge all added PDFs into a single output file.""" + pdf_writer = PyPDF2.PdfWriter() try: diff --git a/README.md b/README.md index b5090ad9..ef09198f 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,8 @@ More information on contributing and the general code of conduct for discussion | OTP Verification | [OTP Verification](https://github.com/DhanushNehru/Python-Scripts/tree/master/OTP%20%20Verify) | An OTP Verification Checker. | | Password Generator | [Password Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Password%20Generator) | Generates a random password. | | Password Manager | [Password Manager](https://github.com/nem5345/Python-Scripts/tree/master/Password%20Manager) | Generate and interact with a password manager. | +| PDF Merger | [PDF Merger](https://github.com/DhanushNehru/Python-Scripts/tree/master/ +PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. From f47aec07a4e5fb31247880b404c7c11091c83386 Mon Sep 17 00:00:00 2001 From: Prem_Kumar <43103958+Prem-Kumar-Dev@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:13:52 +0530 Subject: [PATCH 014/127] Updated main README file as permitted in PR #277.Kindly add hacktoberfest2024-accepted label --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef09198f..6b5335c4 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ More information on contributing and the general code of conduct for discussion | Password Generator | [Password Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Password%20Generator) | Generates a random password. | | Password Manager | [Password Manager](https://github.com/nem5345/Python-Scripts/tree/master/Password%20Manager) | Generate and interact with a password manager. | | PDF Merger | [PDF Merger](https://github.com/DhanushNehru/Python-Scripts/tree/master/ -PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| +PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. From 3770cc7f90d468ead2b1dd18ebb146a7bb6fcdf2 Mon Sep 17 00:00:00 2001 From: Prem_Kumar <43103958+Prem-Kumar-Dev@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:21:48 +0530 Subject: [PATCH 015/127] Update and rename README.md to Updated README.md PR #277 --- README.md => Updated README.md PR #277 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename README.md => Updated README.md PR #277 (99%) diff --git a/README.md b/Updated README.md PR #277 similarity index 99% rename from README.md rename to Updated README.md PR #277 index 6b5335c4..b22404fd 100644 --- a/README.md +++ b/Updated README.md PR #277 @@ -87,8 +87,7 @@ More information on contributing and the general code of conduct for discussion | OTP Verification | [OTP Verification](https://github.com/DhanushNehru/Python-Scripts/tree/master/OTP%20%20Verify) | An OTP Verification Checker. | | Password Generator | [Password Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Password%20Generator) | Generates a random password. | | Password Manager | [Password Manager](https://github.com/nem5345/Python-Scripts/tree/master/Password%20Manager) | Generate and interact with a password manager. | -| PDF Merger | [PDF Merger](https://github.com/DhanushNehru/Python-Scripts/tree/master/ -PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| +| PDF Merger | [PDF Merger](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. From 990fed63a7c84cd731a240fecf400cfe573fbc4d Mon Sep 17 00:00:00 2001 From: Prem_Kumar <43103958+Prem-Kumar-Dev@users.noreply.github.com> Date: Thu, 3 Oct 2024 21:27:43 +0530 Subject: [PATCH 016/127] Final review --- Updated README.md PR #277 => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Updated README.md PR #277 => README.md (100%) diff --git a/Updated README.md PR #277 b/README.md similarity index 100% rename from Updated README.md PR #277 rename to README.md From fa430a3795fc7c68272712abc635d536986eccc1 Mon Sep 17 00:00:00 2001 From: Deepikakolli4 Date: Fri, 4 Oct 2024 21:30:27 +0530 Subject: [PATCH 017/127] Updated readme.md file Signed-off-by: Deepikakolli4 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b5090ad9..c711c49d 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,8 @@ More information on contributing and the general code of conduct for discussion | Image Text to PDF | [Image Text to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Text%20to%20PDF) | Adds an image and text to a PDF. | Image Watermarker | [Image Watermarker](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Watermarker) | Adds a watermark to an image. | Image to ASCII | [Image to ASCII](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20to%20ASCII) | Converts an image into ASCII art. | -| Image to Gif | [Image to Gif](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20to%20GIF) | Generate gif from images. | +| Image to Gif | [Image to Gif](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20to%20GIF) | Generate gif from images. +|Interactive Dictionary | [Interactive Dictionary](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20InteractiveDictionary) |finding out meanings of words| | IP Geolocator | [IP Geolocator](https://github.com/DhanushNehru/Python-Scripts/tree/master/IP%20Geolocator) | Uses an IP address to geolocate a location on Earth. | | Jokes Generator | [Jokes generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Jokes%20Generator) | Generates jokes. | | JSON to CSV 1 | [JSON to CSV 1](https://github.com/DhanushNehru/Python-Scripts/tree/master/JSON%20to%20CSV) | Converts JSON to CSV files. | From 2c1eeebc7ffbe4117e077aeea9960399b5b0ccff Mon Sep 17 00:00:00 2001 From: Hasan <57855533+hasan-py@users.noreply.github.com> Date: Sat, 5 Oct 2024 00:15:03 +0600 Subject: [PATCH 018/127] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2a2a3ace..db6be295 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,8 @@ More information on contributing and the general code of conduct for discussion | Weather GUI | [Weather GUI](https://github.com/DhanushNehru/Python-Scripts/tree/master/Weather%20GUI) | Displays information on the weather. | | Website Blocker | [Website Blocker](https://github.com/DhanushNehru/Python-Scripts/tree/master/Website%20Blocker) | Downloads the website and loads it on your homepage in your local IP. | | Website Cloner | [Website Cloner](https://github.com/DhanushNehru/Python-Scripts/tree/master/Website%20Cloner) | Clones any website and opens the site in your local IP. | -| Web Scraper | [Web Scraper](https://github.com/Charul00/Python-Scripts/tree/main/Web%20Scraper) | A Python script that scrapes blog titles from Python.org and saves them to a file. | - -| Weight Converter | [Weight Converter](https://github.com/WatashiwaSid/Python-Scripts/tree/master/Weight%20Converter) | Simple GUI script to convert weight in different measurement units. | +| Web Scraper | [Web Scraper](https://github.com/Charul00/Python-Scripts/tree/main/Web%20Scraper) | A Python script that scrapes blog titles from Python.org and saves them to a file. | +Weight Converter | [Weight Converter](https://github.com/WatashiwaSid/Python-Scripts/tree/master/Weight%20Converter) | Simple GUI script to convert weight in different measurement units. | | Wikipedia Data Extractor | [Wikipedia Data Extractor](https://github.com/DhanushNehru/Python-Scripts/tree/master/Wikipedia%20Data%20Extractor) | A simple Wikipedia data extractor script to get output in your IDE. | | Word to PDF | [Word to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Word%20to%20PDF%20converter) | A Python script to convert an MS Word file to a PDF file. | | Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! From 6211d6b59fd1ac90a524fe7c782f1e05e4ca3e65 Mon Sep 17 00:00:00 2001 From: Hasan <57855533+hasan-py@users.noreply.github.com> Date: Sat, 5 Oct 2024 00:20:07 +0600 Subject: [PATCH 019/127] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index db6be295..f2c226b0 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,7 @@ More information on contributing and the general code of conduct for discussion | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. +| Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | The pigeonhole sort algorithm to sort your arrays efficiently! | PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. | QR Code Generator | [QR Code Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20Code%20Generator) | This is generate a QR code from the provided link | | QR Code with logo | [QR code with Logo](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature @@ -127,7 +128,6 @@ Weight Converter | [Weight Converter](https://github.com/Wa | Wikipedia Data Extractor | [Wikipedia Data Extractor](https://github.com/DhanushNehru/Python-Scripts/tree/master/Wikipedia%20Data%20Extractor) | A simple Wikipedia data extractor script to get output in your IDE. | | Word to PDF | [Word to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Word%20to%20PDF%20converter) | A Python script to convert an MS Word file to a PDF file. | | Youtube Downloader | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Downloader) | Downloads any video from [YouTube](https://youtube.com) in video or audio format! -| Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | the pigeonhole sort algorithm to sort your arrays efficiently! | Youtube Playlist Info Scraper | [Youtube Playlist Info Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/master/Youtube%20Playlist%20Info%20Scraper) | This python module retrieve information about a YouTube playlist in json format using playlist link. ## Gitpod From cfbf90b5c52992d15dc2ff4a8254938fafb50525 Mon Sep 17 00:00:00 2001 From: Abhijit Motekar <109235675+AbhijitMotekar99@users.noreply.github.com> Date: Sat, 5 Oct 2024 08:59:09 +0530 Subject: [PATCH 020/127] Implemented PDF Merger and Splitter python script : Issue no #283 (#291) * Create PDF Merger and Splitter.py * Update README.md * Create readme.md --- .../PDF Merger and Splitter.py | 23 ++++++++++++ PDF Merger and Splitter/readme.md | 35 +++++++++++++++++++ README.md | 1 + 3 files changed, 59 insertions(+) create mode 100644 PDF Merger and Splitter/PDF Merger and Splitter.py create mode 100644 PDF Merger and Splitter/readme.md diff --git a/PDF Merger and Splitter/PDF Merger and Splitter.py b/PDF Merger and Splitter/PDF Merger and Splitter.py new file mode 100644 index 00000000..09e37467 --- /dev/null +++ b/PDF Merger and Splitter/PDF Merger and Splitter.py @@ -0,0 +1,23 @@ +from PyPDF2 import PdfReader, PdfWriter + +def merge_pdfs(pdfs, output): + pdf_writer = PdfWriter() + for pdf in pdfs: + reader = PdfReader(pdf) + for page in range(len(reader.pages)): + pdf_writer.add_page(reader.pages[page]) + + with open(output, 'wb') as out: + pdf_writer.write(out) + +def split_pdf(pdf): + reader = PdfReader(pdf) + for page_num, page in enumerate(reader.pages): + writer = PdfWriter() + writer.add_page(page) + output_filename = f'{pdf.split(".")[0]}_page_{page_num+1}.pdf' + with open(output_filename, 'wb') as out: + writer.write(out) + +merge_pdfs(['file1.pdf', 'file2.pdf'], 'merged.pdf') +split_pdf('merged.pdf') diff --git a/PDF Merger and Splitter/readme.md b/PDF Merger and Splitter/readme.md new file mode 100644 index 00000000..a0aa8fcf --- /dev/null +++ b/PDF Merger and Splitter/readme.md @@ -0,0 +1,35 @@ +# PDF Merger and Splitter + +This Python script allows you to merge multiple PDF files into a single PDF and split a PDF file into individual pages. It utilizes the `PyPDF2` library for handling PDF files. + +## Features + +- **Merge PDFs**: Combine multiple PDF files into one. +- **Split PDF**: Divide a single PDF file into separate pages, saving each page as a new PDF file. + +## Requirements + +Make sure you have Python installed on your machine. This script also requires the `PyPDF2` library. You can install it using pip: + +```bash +pip install PyPDF2 +``` + +# Usage +## Merging PDFs +- Place the PDF files you want to merge in the same directory as the script. +- Modify the merge_pdfs function call in the script to include the names of the PDF files you want to merge. For example: + ```bash + merge_pdfs(['file1.pdf', 'file2.pdf'], 'merged.pdf') + ``` +- Run the script: + ```bash + python pdf_merger_splitter.py + ``` +## Splitting PDFs +- After merging, the script automatically splits the merged PDF file (merged.pdf) into separate pages. Each page will be saved as a new PDF file named merged_page_X.pdf, where X is the page number. +- You can also split any PDF file by calling the split_pdf function in the script: + ```bash + split_pdf('your_pdf_file.pdf') + ``` +- Run the script to create separate PDF files for each page. diff --git a/README.md b/README.md index f2c226b0..80cdf214 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,7 @@ More information on contributing and the general code of conduct for discussion | PDF Merger | [PDF Merger](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20Merger) |Merges multiple PDF files into a single PDF, with options for output location and custom order.| | PDF to Audio | [PDF to Audio](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20Audio) | Converts PDF to audio. | | PDF to Text | [PDF to text](https://github.com/DhanushNehru/Python-Scripts/tree/master/PDF%20to%20text) | Converts PDF to text. | +| PDF merger and splitter | [PDF Merger and Splitter](https://github.com/AbhijitMotekar99/Python-Scripts/blob/master/PDF%20Merger%20and%20Splitter/PDF%20Merger%20and%20Splitter.py) | Create a tool that can merge multiple PDF files into one or split a single PDF into separate pages. | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | The pigeonhole sort algorithm to sort your arrays efficiently! From fc968ff8086ac53458fc7527bfe4f64492440a9e Mon Sep 17 00:00:00 2001 From: Abhijit Motekar <109235675+AbhijitMotekar99@users.noreply.github.com> Date: Sat, 5 Oct 2024 19:52:44 +0530 Subject: [PATCH 021/127] Implemented Python GUI Notepad Script : Issue no #284 (#297) * Create PDF Merger and Splitter.py * Update README.md * Create readme.md * Create Python GUI Notepad.py * Create Readme.md * Update README.md --- Python GUI Notepad/Python GUI Notepad.py | 29 ++++++++++++++++++++ Python GUI Notepad/Readme.md | 34 ++++++++++++++++++++++++ README.md | 3 ++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Python GUI Notepad/Python GUI Notepad.py create mode 100644 Python GUI Notepad/Readme.md diff --git a/Python GUI Notepad/Python GUI Notepad.py b/Python GUI Notepad/Python GUI Notepad.py new file mode 100644 index 00000000..6aa14693 --- /dev/null +++ b/Python GUI Notepad/Python GUI Notepad.py @@ -0,0 +1,29 @@ +import tkinter as tk +from tkinter import filedialog + +def save_file(): + file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Text Files", "*.txt")]) + if file: + with open(file, 'w') as f: + f.write(text_area.get(1.0, tk.END)) + +def open_file(): + file = filedialog.askopenfilename(filetypes=[("Text Files", "*.txt")]) + if file: + with open(file, 'r') as f: + text_area.delete(1.0, tk.END) + text_area.insert(tk.END, f.read()) + +root = tk.Tk() +root.title("Notepad") +text_area = tk.Text(root, wrap='word') +text_area.pack(expand='yes', fill='both') + +menu = tk.Menu(root) +root.config(menu=menu) +file_menu = tk.Menu(menu, tearoff=0) +menu.add_cascade(label="File", menu=file_menu) +file_menu.add_command(label="Open", command=open_file) +file_menu.add_command(label="Save As", command=save_file) + +root.mainloop() diff --git a/Python GUI Notepad/Readme.md b/Python GUI Notepad/Readme.md new file mode 100644 index 00000000..ceccdd5a --- /dev/null +++ b/Python GUI Notepad/Readme.md @@ -0,0 +1,34 @@ +# Python GUI Notepad + +This Python script provides a simple graphical user interface (GUI) Notepad application that allows users to open and save text files. It is built using the `tkinter` library, which comes with Python. + +## Features + +- **Open Files**: Open and edit existing `.txt` files. +- **Save Files**: Save the current text as a new `.txt` file. + +## Requirements + +Make sure you have Python installed on your machine. This script uses the built-in `tkinter` library, so no additional installations are necessary. + +## Usage + +### Opening Files + +- Run the script by executing the following command: + ```bash + python gui_notepad.py + ``` +- Click on the "File" menu and select "Open" to browse and open a .txt file. +- The contents of the selected file will be loaded into the text editor for editing. + +### Saving Files +- After making edits, click on the "File" menu and select "Save As" to save your work as a new .txt file. +- The file will be saved with the provided name in the location of your choice. + +### Example +1) Open an existing text file: + - Click on "File" -> "Open" and select the .txt file you want to edit. +2) Edit the contents in the text area. +3) Save the edited text: + - Click on "File" -> "Save As" to save the changes to a new or existing file. diff --git a/README.md b/README.md index 30e73edd..ee4ca162 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,8 @@ More information on contributing and the general code of conduct for discussion | Planet Simulation | [Planet Simulation](https://github.com/DhanushNehru/Python-Scripts/tree/master/Planet%20Simulation) | A simulation of several planets rotating around the sun. | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | The pigeonhole sort algorithm to sort your arrays efficiently! -| PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. +| PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. +| Python GUI Notepad | [Python GUI Notepad](https://github.com/DhanushNehru/Python-Scripts/blob/master/PDF%20Merger%20and%20Splitter/PDF%20Merger%20and%20Splitter.py) | A Python-based GUI Notepad with essential features like saving, opening, editing text files, basic formatting, and a simple user interface for quick note-taking. | QR Code Generator | [QR Code Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20Code%20Generator) | This is generate a QR code from the provided link | | QR Code with logo | [QR code with Logo](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature | Random Color Generator | [Random Color Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Random%20Color%20Generator) | A random color generator that will show you the color and values! | From c20547e13f422bed3f950276cffe63f2b47f17af Mon Sep 17 00:00:00 2001 From: Andrey Ivanov <97749666+ivnvxd@users.noreply.github.com> Date: Sat, 5 Oct 2024 15:31:09 +0100 Subject: [PATCH 022/127] Subnetting calculator (#296) --- README.md | 1 + Subnetting Calculator/README.md | 40 ++++++++++++++++ .../subnetting_calculator.py | 46 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 Subnetting Calculator/README.md create mode 100644 Subnetting Calculator/subnetting_calculator.py diff --git a/README.md b/README.md index ee4ca162..d15f4e8b 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ More information on contributing and the general code of conduct for discussion | Snake Water Gun | [Snake Water Gun](https://github.com/DhanushNehru/Python-Scripts/tree/master/Snake%20Water%20Gun) | A game similar to Rock Paper Scissors. | | Sorting | [Sorting](https://github.com/DhanushNehru/Python-Scripts/tree/master/Sorting) | Algorithm for bubble sorting. | | Star Pattern | [Star Pattern](https://github.com/DhanushNehru/Python-Scripts/tree/master/Star%20Pattern) | Creates a star pattern pyramid. | +| Subnetting Calculator | [Subnetting Calculator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Subnetting%20Calculator) | Calculates network information based on a given IP address and subnet mask. | | Take a break | [Take a break](https://github.com/DhanushNehru/Python-Scripts/tree/master/Take%20A%20Break) | Python code to take a break while working long hours. | | Text Recognition | [Text Recognition](https://github.com/DhanushNehru/Python-Scripts/tree/Text-Recognition/Text%20Recognition) | A Image Text Recognition ML Model to extract text from Images | | Text to Image | [Text to Image](https://github.com/DhanushNehru/Python-Scripts/tree/master/Text%20to%20Image) | A Python script that will take your text and convert it to a JPEG. | diff --git a/Subnetting Calculator/README.md b/Subnetting Calculator/README.md new file mode 100644 index 00000000..2fd34271 --- /dev/null +++ b/Subnetting Calculator/README.md @@ -0,0 +1,40 @@ +# Subnetting Calculator + +This Python script calculates network information based on a given IP address and subnet mask. + +## Features + +- Calculates network address and broadcast address +- Provides the range of IP addresses for the network +- Shows the usable host IP range +- Calculates the total number of hosts and usable hosts + +## Usage + +1. Ensure you have Python 3.x installed on your system. +2. Run the script: + ``` + python subnetting_calculator.py + ``` +3. Enter the IP address and subnet mask when prompted. + +## Example + +``` +Enter IP address: 192.168.1.1 +Enter subnet mask: 255.255.255.0 + +Network Information: +IP Address: 192.168.1.1 +Subnet Mask: 255.255.255.0 +Network Address: 192.168.1.0 +Broadcast Address: 192.168.1.255 +Range of IP addresses: 192.168.1.0 - 192.168.1.255 +Usable Host IP Range: 192.168.1.1 - 192.168.1.254 +Total Hosts: 256 +Usable Hosts: 254 +``` + +## Requirements + +This script uses the `ipaddress` module, which is part of the Python standard library. No additional installations are required. diff --git a/Subnetting Calculator/subnetting_calculator.py b/Subnetting Calculator/subnetting_calculator.py new file mode 100644 index 00000000..c9638fbf --- /dev/null +++ b/Subnetting Calculator/subnetting_calculator.py @@ -0,0 +1,46 @@ +import ipaddress + + +def calculate_network_info(ip_address, subnet_mask): + network = ipaddress.IPv4Network(f"{ip_address}/{subnet_mask}", strict=False) + + network_address = network.network_address + broadcast_address = network.broadcast_address + total_hosts = network.num_addresses + usable_hosts = max(total_hosts - 2, 0) + first_usable_host = network_address + 1 if usable_hosts > 0 else None + last_usable_host = broadcast_address - 1 if usable_hosts > 0 else None + + results = { + "IP Address": ip_address, + "Subnet Mask": subnet_mask, + "Network Address": str(network_address), + "Broadcast Address": str(broadcast_address), + "Range of IP addresses": f"{network_address} - {broadcast_address}", + "Usable Host IP Range": ( + f"{first_usable_host} - {last_usable_host}" if usable_hosts > 0 else "N/A" + ), + "Total Hosts": total_hosts, + "Usable Hosts": usable_hosts, + } + + return results + + +def main(): + try: + ip_address = input("Enter IP address: ") + subnet_mask = input("Enter subnet mask: ") + + info = calculate_network_info(ip_address, subnet_mask) + + print("\nNetwork Information:") + for key, value in info.items(): + print(f"{key}: {value}") + + except ValueError as e: + print(f"Error: {e}") + + +if __name__ == "__main__": + main() From 87a3a025a6cbf9aab1e5f5156702ed8110a16bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Sat, 5 Oct 2024 21:26:48 +0530 Subject: [PATCH 023/127] Support Custom Folder Configuration added --- Arrange It/arrangeit.py | 53 +++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/Arrange It/arrangeit.py b/Arrange It/arrangeit.py index 682f398b..1f9beb28 100644 --- a/Arrange It/arrangeit.py +++ b/Arrange It/arrangeit.py @@ -1,22 +1,18 @@ from shutil import move -from os import path import os - - -directory = { - 'Programming Files': set(['ipynb', 'py', 'java', 'cs', 'js', 'vsix', 'jar', 'cc', 'ccc', 'html', 'xml', 'kt']), - 'Music': set(['mp3', 'wav', 'wma', 'mpa', 'ram', 'ra', 'aac', 'aif', 'm4a', 'tsa']), - 'Videos': set(['mp4', 'webm', 'mkv', 'MPG', 'MP2', 'MPEG', 'MPE', 'MPV', 'OGG', 'M4P', 'M4V', 'WMV', 'MOV', 'QT', 'FLV', 'SWF', 'AVCHD', 'avi', 'mpg', 'mpe', 'mpeg', 'asf', 'wmv', 'mov', 'qt', 'rm']), - 'Pictures': set(['jpeg', 'jpg', 'png', 'gif', 'tiff', 'raw', 'webp', 'jfif', 'ico', 'psd', 'svg', 'ai']), - 'Applications': set(['exe', 'msi', 'deb', 'rpm']), - 'Compressed': set(['zip', 'rar', 'arj', 'gz', 'sit', 'sitx', 'sea', 'ace', 'bz2', '7z']), - 'Documents': set(['txt', 'pdf', 'doc', 'xlsx', 'pdf', 'ppt', 'pps', 'docx', 'pptx']), - 'Other': set([]) -} - - -def create_folders(): - +import json + +# Load folder-extension mappings from config.json +def load_config(file='config.json'): + try: + with open(file, 'r') as f: + return json.load(f) + except FileNotFoundError: + print(f"Configuration file {file} not found! Using default settings.") + return {} + +# Create folders based on config.json +def create_folders(directory): for dir_ in directory: try: os.mkdir(dir_) @@ -24,24 +20,23 @@ def create_folders(): except OSError: print(f'{dir_:20} Already Exists') - -def get_folder(ext): - - for f, ex in directory.items(): - if ext in ex: - return f +# Determine which folder a file belongs to +def get_folder(ext, directory): + for folder, extensions in directory.items(): + if ext in extensions: + return folder return 'Other' - -def start(): +# Start moving files based on their extensions +def start(directory): for filename in os.listdir(): if filename != __file__ and filename[0] != '.' and '.' in filename: ext = os.path.basename(filename).split('.')[-1] - folder = get_folder(ext) + folder = get_folder(ext, directory) if not os.path.isfile(os.path.join(folder, filename)): move(filename, folder) - if __name__ == '__main__': - create_folders() - start() + config = load_config() # Load configuration + create_folders(config) # Create necessary folders + start(config) # Start organizing files From 896c1b681995cdff99b4b71304233350a5ff1852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Sat, 5 Oct 2024 21:33:54 +0530 Subject: [PATCH 024/127] Added a config.json that holds the mappings --- .gitignore | 1 - Arrange It/config.json | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 Arrange It/config.json diff --git a/.gitignore b/.gitignore index e2825f9f..5109c9bf 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ node_modules/ creds.js # Private Files -*.json *.csv *.csv.gz *.tsv diff --git a/Arrange It/config.json b/Arrange It/config.json new file mode 100644 index 00000000..d573f41d --- /dev/null +++ b/Arrange It/config.json @@ -0,0 +1,11 @@ +{ + "Programming Files": ["ipynb", "py", "java", "cs", "js", "vsix", "jar", "cc", "ccc", "html", "xml", "kt"], + "Music": ["mp3", "wav", "wma", "mpa", "ram", "ra", "aac", "aif", "m4a", "tsa"], + "Videos": ["mp4", "webm", "mkv", "MPG", "MP2", "MPEG", "MPE", "MPV", "OGG", "M4P", "M4V", "WMV", "MOV", "QT", "FLV", "SWF", "AVCHD", "avi", "mpg", "mpe", "mpeg", "asf", "wmv", "mov", "qt", "rm"], + "Pictures": ["jpeg", "jpg", "png", "gif", "tiff", "raw", "webp", "jfif", "ico", "psd", "svg", "ai"], + "Applications": ["exe", "msi", "deb", "rpm"], + "Compressed": ["zip", "rar", "arj", "gz", "sit", "sitx", "sea", "ace", "bz2", "7z"], + "Documents": ["txt", "pdf", "doc", "xlsx", "ppt", "pps", "docx", "pptx"], + "Other": [] + } + \ No newline at end of file From 6db72388f1b3d5b26d2c0a53489e6c2043e032c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Sat, 5 Oct 2024 22:56:22 +0530 Subject: [PATCH 025/127] Updated README.md --- Arrange It/README.md | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/Arrange It/README.md b/Arrange It/README.md index fb4553fb..c3515c04 100644 --- a/Arrange It/README.md +++ b/Arrange It/README.md @@ -1,18 +1,41 @@ # Arrange It -With the help of this script, files can be moved automatically to the folder that corresponds to their extension (for example, ".jpg" or ".png" ==> "/Pictures," and ".mp4" ==> "/Videos"). +With the help of this script, files can be moved automatically to the folder that corresponds to their extension (for example, .jpg or .png files go to the /Pictures folder, and .mp4 files go to /Videos). -## How To Run +## New Feature: Custom Folder Configuration -- Put in Download Folder Or Wherever You want to automatically move the file and Just run +-Now, you can customize how files are arranged by defining your own folder structure and file extensions using a config.json file. This allows for more flexibility without needing to modify the Python code itself. +python arrangeit.py + +# How To Use the config.json File + +1. The config.json file contains the mappings of file extensions to folder names. +2. You can modify, add, or remove folder categories and file extensions as per your needs. + +Example config.json: + +{ + "Programming Files": ["ipynb", "py", "java", "cs", "js"], + "Music": ["mp3", "wav", "aac"], + "Videos": ["mp4", "mkv", "avi"], + "Pictures": ["jpeg", "png", "gif"], + "Documents": ["pdf", "docx", "xlsx"] +} -For CLI +# How To Run + +Put the script and the config.json file in the folder where you want to automatically move the files. + +Run the following command from the terminal: -```bash python arrangeit.py - -``` - - \ No newline at end of file +The script will create folders and move files based on the folder-extension mappings in the config.json file. + + +# Benefits + +Customizable: Easily modify the config.json file to tailor the organization to your preferences. +User-Friendly: No need to modify Python code—just update the config.json file. +Scalable: Works with different folder structures for different use cases. \ No newline at end of file From 215c7cebfbae0ddadc466cce2a82e6d6099e6c58 Mon Sep 17 00:00:00 2001 From: Venkat Prashanth Mattaparthi <130282618+m-vp@users.noreply.github.com> Date: Mon, 7 Oct 2024 10:00:19 +0530 Subject: [PATCH 026/127] Autocomplete Notes App with GUI (#304) * Added Automatic Notes App * Added Readme file --- Autocomplete Notes App/README.md | 32 + Autocomplete Notes App/app.py | 95 + Autocomplete Notes App/wordlist.py | 9993 ++++++++++++++++++++++++++++ README.md | 1 + 4 files changed, 10121 insertions(+) create mode 100644 Autocomplete Notes App/README.md create mode 100644 Autocomplete Notes App/app.py create mode 100644 Autocomplete Notes App/wordlist.py diff --git a/Autocomplete Notes App/README.md b/Autocomplete Notes App/README.md new file mode 100644 index 00000000..ed1e94bc --- /dev/null +++ b/Autocomplete Notes App/README.md @@ -0,0 +1,32 @@ +# Autocomplete Notes App + +## Overview + +The Autocomplete Notes App is a simple graphical user interface (GUI) application that allows users to take notes efficiently. It features an autocomplete functionality, where suggestions for completing words are displayed as the user types. This app is built using Python and the Tkinter library for the GUI, with the addition of word suggestions from a predefined word list. + +## Features + +- **Text Input**: A large text area for users to enter notes. +- **Autocomplete**: As users type, a suggestion box displays the full word based on the entered text. +- **Tab Functionality**: Users can press the Tab key to automatically fill in the suggested word into the text area. +- **Save Notes**: Users can choose a filename to save their notes to a `.txt` file. +- **Dynamic Sizing**: The app window resizes based on user actions. + +## Requirements + +- Python 3.x +- Tkinter (usually comes pre-installed with Python) +- A `wordlist.txt` file containing words for autocomplete suggestions. + +## Installation + +1. Clone the repository or download the source code files. +2. Ensure you have Python 3.x installed on your machine. +3. Make sure `wordlist.txt` is in the same directory as the application code. This file should contain words, each on a new line. + +## Usage + +1. Open a terminal or command prompt and navigate to the directory containing the application code. +2. Run the application using the command: + ```bash + python app.py diff --git a/Autocomplete Notes App/app.py b/Autocomplete Notes App/app.py new file mode 100644 index 00000000..90c2ff03 --- /dev/null +++ b/Autocomplete Notes App/app.py @@ -0,0 +1,95 @@ +import tkinter as tk +from tkinter import filedialog, messagebox + +class AutocompleteApp: + def __init__(self, root): + self.root = root + self.root.title("Autocomplete Notes App") + + # Load words from wordlist.txt + self.autocomplete_list = self.load_wordlist("wordlist.txt") + + self.create_widgets() + + def load_wordlist(self, filename): + """Load words from a specified file.""" + try: + with open(filename, 'r') as file: + words = [line.strip() for line in file.readlines() if line.strip()] + return words + except FileNotFoundError: + messagebox.showerror("Error", f"File '{filename}' not found.") + return [] + + def create_widgets(self): + self.large_entry = tk.Text(self.root, wrap=tk.WORD) + self.large_entry.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") + + self.suggestion_entry = tk.Entry(self.root, width=60, state='readonly') + self.suggestion_entry.grid(row=1, column=0, padx=10, pady=5, sticky="ew") + + self.save_button = tk.Button(self.root, text="Save Notes", command=self.save_notes) + self.save_button.grid(row=2, column=0, padx=10, pady=5, sticky="ew") + + self.root.grid_rowconfigure(0, weight=1) + self.root.grid_columnconfigure(0, weight=1) + + self.large_entry.bind("", self.update_suggestion) + self.large_entry.bind("", self.insert_complete_word) + + def update_suggestion(self, event): + """Update the suggestion based on the current input.""" + current_input = self.get_last_word() + suggestion = "" + + if current_input: + matches = [word for word in self.autocomplete_list if word.startswith(current_input)] + if matches: + suggestion = matches[0] + + self.suggestion_entry.config(state='normal') + self.suggestion_entry.delete(0, tk.END) + self.suggestion_entry.insert(0, suggestion) + self.suggestion_entry.config(state='readonly') + + def get_last_word(self): + """Get the last word from the current line of the large entry.""" + cursor_index = self.large_entry.index(tk.INSERT) + line_number = cursor_index.split('.')[0] + line_text = self.large_entry.get(f"{line_number}.0", f"{line_number}.end").strip() # Get the current line text + words = line_text.split() + return words[-1] if words else "" + + def insert_complete_word(self, event): + """Insert the complete word into the large entry when Tab is pressed.""" + complete_word = self.suggestion_entry.get() + if complete_word: + cursor_index = self.large_entry.index(tk.INSERT) + line_number = cursor_index.split('.')[0] + line_text = self.large_entry.get(f"{line_number}.0", f"{line_number}.end").strip() + words = line_text.split() + if words: + words[-1] = complete_word + self.large_entry.delete(f"{line_number}.0", f"{line_number}.end") + self.large_entry.insert(f"{line_number}.0", ' '.join(words)) + + return "break" + + def save_notes(self): + """Save the notes to a file.""" + notes = self.large_entry.get("1.0", tk.END).strip() + if notes: + file_path = filedialog.asksaveasfilename(defaultextension=".txt", + filetypes=[("Text files", "*.txt"), + ("All files", "*.*")]) + if file_path: + with open(file_path, 'w') as file: + file.write(notes) + messagebox.showinfo("Success", "Notes saved successfully!") + else: + messagebox.showwarning("Warning", "No notes to save!") + +if __name__ == "__main__": + root = tk.Tk() + app = AutocompleteApp(root) + root.mainloop() diff --git a/Autocomplete Notes App/wordlist.py b/Autocomplete Notes App/wordlist.py new file mode 100644 index 00000000..a0804248 --- /dev/null +++ b/Autocomplete Notes App/wordlist.py @@ -0,0 +1,9993 @@ +abandoned +abilities +ability +able +aboriginal +abortion +about +above +abraham +abroad +abs +absence +absent +absolute +absolutely +absorption +abstract +abstracts +abu +abuse +ac +academic +academics +academy +acc +accent +accept +acceptable +acceptance +accepted +accepting +accepts +access +accessed +accessibility +accessible +accessing +accessories +accessory +accident +accidents +accommodate +accommodation +accommodations +accompanied +accompanying +accomplish +accomplished +accordance +according +accordingly +account +accountability +accounting +accounts +accreditation +accredited +accuracy +accurate +accurately +accused +acdbentity +ace +acer +achieve +achieved +achievement +achievements +achieving +acid +acids +acknowledge +acknowledged +acm +acne +acoustic +acquire +acquired +acquisition +acquisitions +acre +acres +acrobat +across +acrylic +act +acting +action +actions +activated +activation +active +actively +activists +activities +activity +actor +actors +actress +acts +actual +actually +acute +ad +ada +adam +adams +adaptation +adapted +adapter +adapters +adaptive +adaptor +add +added +addiction +adding +addition +additional +additionally +additions +address +addressed +addresses +addressing +adds +adelaide +adequate +adidas +adipex +adjacent +adjust +adjustable +adjusted +adjustment +adjustments +admin +administered +administration +administrative +administrator +administrators +admission +admissions +admit +admitted +adobe +adolescent +adopt +adopted +adoption +adrian +ads +adsl +adult +adults +advance +advanced +advancement +advances +advantage +advantages +adventure +adventures +adverse +advert +advertise +advertisement +advertisements +advertiser +advertisers +advertising +advice +advise +advised +advisor +advisors +advisory +advocacy +advocate +adware +ae +aerial +aerospace +af +affair +affairs +affect +affected +affecting +affects +affiliate +affiliated +affiliates +affiliation +afford +affordable +afghanistan +afraid +africa +african +after +afternoon +afterwards +ag +again +against +age +aged +agencies +agency +agenda +agent +agents +ages +aggregate +aggressive +aging +ago +agree +agreed +agreement +agreements +agrees +agricultural +agriculture +ah +ahead +ai +aid +aids +aim +aimed +aims +air +aircraft +airfare +airline +airlines +airplane +airport +airports +aj +ak +aka +al +ala +alabama +alan +alarm +alaska +albania +albany +albert +alberta +album +albums +albuquerque +alcohol +alert +alerts +alex +alexander +alexandria +alfred +algebra +algeria +algorithm +algorithms +ali +alias +alice +alien +align +alignment +alike +alive +all +allah +allan +alleged +allen +allergy +alliance +allied +allocated +allocation +allow +allowance +allowed +allowing +allows +alloy +almost +alone +along +alot +alpha +alphabetical +alpine +already +also +alt +alter +altered +alternate +alternative +alternatively +alternatives +although +alto +aluminium +aluminum +alumni +always +am +amanda +amateur +amazing +amazon +amazoncom +amazoncouk +ambassador +amber +ambien +ambient +amd +amend +amended +amendment +amendments +amenities +america +american +americans +americas +amino +among +amongst +amount +amounts +amp +ampland +amplifier +amsterdam +amy +an +ana +anaheim +anal +analog +analyses +analysis +analyst +analysts +analytical +analyze +analyzed +anatomy +anchor +ancient +and +andale +anderson +andorra +andrea +andreas +andrew +andrews +andy +angel +angela +angeles +angels +anger +angle +angola +angry +animal +animals +animated +animation +anime +ann +anna +anne +annex +annie +anniversary +annotated +annotation +announce +announced +announcement +announcements +announces +annoying +annual +annually +anonymous +another +answer +answered +answering +answers +ant +antarctica +antenna +anthony +anthropology +anti +antibodies +antibody +anticipated +antigua +antique +antiques +antivirus +antonio +anxiety +any +anybody +anymore +anyone +anything +anytime +anyway +anywhere +aol +ap +apache +apart +apartment +apartments +api +apnic +apollo +app +apparatus +apparel +apparent +apparently +appeal +appeals +appear +appearance +appeared +appearing +appears +appendix +apple +appliance +appliances +applicable +applicant +applicants +application +applications +applied +applies +apply +applying +appointed +appointment +appointments +appraisal +appreciate +appreciated +appreciation +approach +approaches +appropriate +appropriations +approval +approve +approved +approx +approximate +approximately +apps +apr +april +apt +aqua +aquarium +aquatic +ar +arab +arabia +arabic +arbitrary +arbitration +arc +arcade +arch +architect +architects +architectural +architecture +archive +archived +archives +arctic +are +area +areas +arena +arg +argentina +argue +argued +argument +arguments +arise +arising +arizona +arkansas +arlington +arm +armed +armenia +armor +arms +armstrong +army +arnold +around +arrange +arranged +arrangement +arrangements +array +arrest +arrested +arrival +arrivals +arrive +arrived +arrives +arrow +art +arthritis +arthur +article +articles +artificial +artist +artistic +artists +arts +artwork +aruba +as +asbestos +ascii +ash +ashley +asia +asian +aside +asin +ask +asked +asking +asks +asn +asp +aspect +aspects +aspnet +ass +assault +assembled +assembly +assess +assessed +assessing +assessment +assessments +asset +assets +assign +assigned +assignment +assignments +assist +assistance +assistant +assisted +assists +associate +associated +associates +association +associations +assume +assumed +assumes +assuming +assumption +assumptions +assurance +assure +assured +asthma +astrology +astronomy +asus +at +ata +ate +athens +athletes +athletic +athletics +ati +atlanta +atlantic +atlas +atm +atmosphere +atmospheric +atom +atomic +attach +attached +attachment +attachments +attack +attacked +attacks +attempt +attempted +attempting +attempts +attend +attendance +attended +attending +attention +attitude +attitudes +attorney +attorneys +attract +attraction +attractions +attractive +attribute +attributes +au +auburn +auckland +auction +auctions +aud +audi +audience +audio +audit +auditor +aug +august +aurora +aus +austin +australia +australian +austria +authentic +authentication +author +authorities +authority +authorization +authorized +authors +auto +automated +automatic +automatically +automation +automobile +automobiles +automotive +autos +autumn +av +availability +available +avatar +ave +avenue +average +avg +avi +aviation +avoid +avoiding +avon +aw +award +awarded +awards +aware +awareness +away +awesome +awful +axis +aye +az +azerbaijan +b +ba +babe +babes +babies +baby +bachelor +back +backed +background +backgrounds +backing +backup +bacon +bacteria +bacterial +bad +badge +badly +bag +baghdad +bags +bahamas +bahrain +bailey +baker +baking +balance +balanced +bald +bali +ball +ballet +balloon +ballot +balls +baltimore +ban +banana +band +bands +bandwidth +bang +bangbus +bangkok +bangladesh +bank +banking +bankruptcy +banks +banned +banner +banners +baptist +bar +barbados +barbara +barbie +barcelona +bare +barely +bargain +bargains +barn +barnes +barrel +barrier +barriers +barry +bars +base +baseball +based +baseline +basement +basename +bases +basic +basically +basics +basin +basis +basket +basketball +baskets +bass +bat +batch +bath +bathroom +bathrooms +baths +batman +batteries +battery +battle +battlefield +bay +bb +bbc +bbs +bbw +bc +bd +bdsm +be +beach +beaches +beads +beam +bean +beans +bear +bearing +bears +beast +beastality +beastiality +beat +beatles +beats +beautiful +beautifully +beauty +beaver +became +because +become +becomes +becoming +bed +bedding +bedford +bedroom +bedrooms +beds +bee +beef +been +beer +before +began +begin +beginner +beginners +beginning +begins +begun +behalf +behavior +behavioral +behaviour +behind +beijing +being +beings +belarus +belfast +belgium +belief +beliefs +believe +believed +believes +belize +belkin +bell +belle +belly +belong +belongs +below +belt +belts +ben +bench +benchmark +bend +beneath +beneficial +benefit +benefits +benjamin +bennett +benz +berkeley +berlin +bermuda +bernard +berry +beside +besides +best +bestiality +bestsellers +bet +beta +beth +better +betting +betty +between +beverage +beverages +beverly +beyond +bg +bhutan +bi +bias +bible +biblical +bibliographic +bibliography +bicycle +bid +bidder +bidding +bids +big +bigger +biggest +bike +bikes +bikini +bill +billing +billion +bills +billy +bin +binary +bind +binding +bingo +bio +biodiversity +biographies +biography +biol +biological +biology +bios +biotechnology +bird +birds +birmingham +birth +birthday +bishop +bit +bitch +bite +bits +biz +bizarre +bizrate +bk +bl +black +blackberry +blackjack +blacks +blade +blades +blah +blair +blake +blame +blank +blanket +blast +bleeding +blend +bless +blessed +blind +blink +block +blocked +blocking +blocks +blog +blogger +bloggers +blogging +blogs +blond +blonde +blood +bloody +bloom +bloomberg +blow +blowing +blowjob +blowjobs +blue +blues +bluetooth +blvd +bm +bmw +bo +board +boards +boat +boating +boats +bob +bobby +boc +bodies +body +bold +bolivia +bolt +bomb +bon +bond +bondage +bonds +bone +bones +bonus +boob +boobs +book +booking +bookings +bookmark +bookmarks +books +bookstore +bool +boolean +boom +boost +boot +booth +boots +booty +border +borders +bored +boring +born +borough +bosnia +boss +boston +both +bother +botswana +bottle +bottles +bottom +bought +boulder +boulevard +bound +boundaries +boundary +bouquet +boutique +bow +bowl +bowling +box +boxed +boxes +boxing +boy +boys +bp +br +bra +bracelet +bracelets +bracket +brad +bradford +bradley +brain +brake +brakes +branch +branches +brand +brandon +brands +bras +brass +brave +brazil +brazilian +breach +bread +break +breakdown +breakfast +breaking +breaks +breast +breasts +breath +breathing +breed +breeding +breeds +brian +brick +bridal +bride +bridge +bridges +brief +briefing +briefly +briefs +bright +brighton +brilliant +bring +bringing +brings +brisbane +bristol +britain +britannica +british +britney +broad +broadband +broadcast +broadcasting +broader +broadway +brochure +brochures +broke +broken +broker +brokers +bronze +brook +brooklyn +brooks +bros +brother +brothers +brought +brown +browse +browser +browsers +browsing +bruce +brunei +brunette +brunswick +brush +brussels +brutal +bryan +bryant +bs +bt +bubble +buck +bucks +budapest +buddy +budget +budgets +buf +buffalo +buffer +bufing +bug +bugs +build +builder +builders +building +buildings +builds +built +bukkake +bulgaria +bulgarian +bulk +bull +bullet +bulletin +bumper +bunch +bundle +bunny +burden +bureau +buried +burke +burlington +burn +burner +burning +burns +burst +burton +bus +buses +bush +business +businesses +busty +busy +but +butler +butt +butter +butterfly +button +buttons +butts +buy +buyer +buyers +buying +buys +buzz +bw +by +bye +byte +bytes +c +ca +cab +cabin +cabinet +cabinets +cable +cables +cache +cached +cad +cadillac +cafe +cage +cake +cakes +cal +calcium +calculate +calculated +calculation +calculations +calculator +calculators +calendar +calendars +calgary +calibration +calif +california +call +called +calling +calls +calm +calvin +cam +cambodia +cambridge +camcorder +camcorders +came +camel +camera +cameras +cameron +cameroon +camp +campaign +campaigns +campbell +camping +camps +campus +cams +can +canada +canadian +canal +canberra +cancel +cancellation +cancelled +cancer +candidate +candidates +candle +candles +candy +cannon +canon +cant +canvas +canyon +cap +capabilities +capability +capable +capacity +cape +capital +capitol +caps +captain +capture +captured +car +carb +carbon +card +cardiac +cardiff +cardiovascular +cards +care +career +careers +careful +carefully +carey +cargo +caribbean +caring +carl +carlo +carlos +carmen +carnival +carol +carolina +caroline +carpet +carried +carrier +carriers +carries +carroll +carry +carrying +cars +cart +carter +cartoon +cartoons +cartridge +cartridges +cas +casa +case +cases +casey +cash +cashiers +casino +casinos +casio +cassette +cast +casting +castle +casual +cat +catalog +catalogs +catalogue +catalyst +catch +categories +category +catering +cathedral +catherine +catholic +cats +cattle +caught +cause +caused +causes +causing +caution +cave +cayman +cb +cbs +cc +ccd +cd +cdna +cds +cdt +ce +cedar +ceiling +celebrate +celebration +celebrities +celebrity +celebs +cell +cells +cellular +celtic +cement +cemetery +census +cent +center +centered +centers +central +centre +centres +cents +centuries +century +ceo +ceramic +ceremony +certain +certainly +certificate +certificates +certification +certified +cest +cet +cf +cfr +cg +cgi +ch +chad +chain +chains +chair +chairman +chairs +challenge +challenged +challenges +challenging +chamber +chambers +champagne +champion +champions +championship +championships +chan +chance +chancellor +chances +change +changed +changelog +changes +changing +channel +channels +chaos +chapel +chapter +chapters +char +character +characteristic +characteristics +characterization +characterized +characters +charge +charged +charger +chargers +charges +charging +charitable +charity +charles +charleston +charlie +charlotte +charm +charming +charms +chart +charter +charts +chase +chassis +chat +cheap +cheaper +cheapest +cheat +cheats +check +checked +checking +checklist +checkout +checks +cheers +cheese +chef +chelsea +chem +chemical +chemicals +chemistry +chen +cheque +cherry +chess +chest +chester +chevrolet +chevy +chi +chicago +chick +chicken +chicks +chief +child +childhood +children +childrens +chile +china +chinese +chip +chips +cho +chocolate +choice +choices +choir +cholesterol +choose +choosing +chorus +chose +chosen +chris +christ +christian +christianity +christians +christina +christine +christmas +christopher +chrome +chronic +chronicle +chronicles +chrysler +chubby +chuck +church +churches +ci +cia +cialis +ciao +cigarette +cigarettes +cincinnati +cindy +cinema +cingular +cio +cir +circle +circles +circuit +circuits +circular +circulation +circumstances +circus +cisco +citation +citations +cite +cited +cities +citizen +citizens +citizenship +city +citysearch +civic +civil +civilian +civilization +cj +cl +claim +claimed +claims +claire +clan +clara +clarity +clark +clarke +class +classes +classic +classical +classics +classification +classified +classifieds +classroom +clause +clay +clean +cleaner +cleaners +cleaning +cleanup +clear +clearance +cleared +clearing +clearly +clerk +cleveland +click +clicking +clicks +client +clients +cliff +climate +climb +climbing +clinic +clinical +clinics +clinton +clip +clips +clock +clocks +clone +close +closed +closely +closer +closes +closest +closing +closure +cloth +clothes +clothing +cloud +clouds +cloudy +club +clubs +cluster +clusters +cm +cms +cn +cnet +cnetcom +cnn +co +coach +coaches +coaching +coal +coalition +coast +coastal +coat +coated +coating +cock +cocks +cod +code +codes +coding +coffee +cognitive +cohen +coin +coins +col +cold +cole +coleman +colin +collaboration +collaborative +collapse +collar +colleague +colleagues +collect +collectables +collected +collectible +collectibles +collecting +collection +collections +collective +collector +collectors +college +colleges +collins +cologne +colombia +colon +colonial +colony +color +colorado +colored +colors +colour +colours +columbia +columbus +column +columnists +columns +com +combat +combination +combinations +combine +combined +combines +combining +combo +come +comedy +comes +comfort +comfortable +comic +comics +coming +comm +command +commander +commands +comment +commentary +commented +comments +commerce +commercial +commission +commissioner +commissioners +commissions +commit +commitment +commitments +committed +committee +committees +commodities +commodity +common +commonly +commons +commonwealth +communicate +communication +communications +communist +communities +community +comp +compact +companies +companion +company +compaq +comparable +comparative +compare +compared +comparing +comparison +comparisons +compatibility +compatible +compensation +compete +competent +competing +competition +competitions +competitive +competitors +compilation +compile +compiled +compiler +complaint +complaints +complement +complete +completed +completely +completing +completion +complex +complexity +compliance +compliant +complicated +complications +complimentary +comply +component +components +composed +composer +composite +composition +compound +compounds +comprehensive +compressed +compression +compromise +computation +computational +compute +computed +computer +computers +computing +con +concentrate +concentration +concentrations +concept +concepts +conceptual +concern +concerned +concerning +concerns +concert +concerts +conclude +concluded +conclusion +conclusions +concord +concrete +condition +conditional +conditioning +conditions +condo +condos +conduct +conducted +conducting +conf +conference +conferences +conferencing +confidence +confident +confidential +confidentiality +config +configuration +configure +configured +configuring +confirm +confirmation +confirmed +conflict +conflicts +confused +confusion +congo +congratulations +congress +congressional +conjunction +connect +connected +connecticut +connecting +connection +connections +connectivity +connector +connectors +cons +conscious +consciousness +consecutive +consensus +consent +consequence +consequences +consequently +conservation +conservative +consider +considerable +consideration +considerations +considered +considering +considers +consist +consistency +consistent +consistently +consisting +consists +console +consoles +consolidated +consolidation +consortium +conspiracy +const +constant +constantly +constitute +constitutes +constitution +constitutional +constraint +constraints +construct +constructed +construction +consult +consultancy +consultant +consultants +consultation +consulting +consumer +consumers +consumption +contact +contacted +contacting +contacts +contain +contained +container +containers +containing +contains +contamination +contemporary +content +contents +contest +contests +context +continent +continental +continually +continue +continued +continues +continuing +continuity +continuous +continuously +contract +contracting +contractor +contractors +contracts +contrary +contrast +contribute +contributed +contributing +contribution +contributions +contributor +contributors +control +controlled +controller +controllers +controlling +controls +controversial +controversy +convenience +convenient +convention +conventional +conventions +convergence +conversation +conversations +conversion +convert +converted +converter +convertible +convicted +conviction +convinced +cook +cookbook +cooked +cookie +cookies +cooking +cool +cooler +cooling +cooper +cooperation +cooperative +coordinate +coordinated +coordinates +coordination +coordinator +cop +cope +copied +copies +copper +copy +copying +copyright +copyrighted +copyrights +coral +cord +cordless +core +cork +corn +cornell +corner +corners +cornwall +corp +corporate +corporation +corporations +corps +corpus +correct +corrected +correction +corrections +correctly +correlation +correspondence +corresponding +corruption +cos +cosmetic +cosmetics +cost +costa +costs +costume +costumes +cottage +cottages +cotton +could +council +councils +counsel +counseling +count +counted +counter +counters +counties +counting +countries +country +counts +county +couple +coupled +couples +coupon +coupons +courage +courier +course +courses +court +courtesy +courts +cove +cover +coverage +covered +covering +covers +cow +cowboy +cox +cp +cpu +cr +crack +cradle +craft +crafts +craig +crap +craps +crash +crawford +crazy +cream +create +created +creates +creating +creation +creations +creative +creativity +creator +creature +creatures +credit +credits +creek +crest +crew +cricket +crime +crimes +criminal +crisis +criteria +criterion +critical +criticism +critics +crm +croatia +crop +crops +cross +crossing +crossword +crowd +crown +crucial +crude +cruise +cruises +cruz +cry +crystal +cs +css +cst +ct +cu +cuba +cube +cubic +cuisine +cult +cultural +culture +cultures +cum +cumshot +cumshots +cumulative +cunt +cup +cups +cure +curious +currencies +currency +current +currently +curriculum +cursor +curtis +curve +curves +custody +custom +customer +customers +customise +customize +customized +customs +cut +cute +cuts +cutting +cv +cvs +cw +cyber +cycle +cycles +cycling +cylinder +cyprus +cz +czech +d +da +dad +daddy +daily +dairy +daisy +dakota +dale +dallas +dam +damage +damaged +damages +dame +damn +dan +dana +dance +dancing +danger +dangerous +daniel +danish +danny +dans +dare +dark +darkness +darwin +das +dash +dat +data +database +databases +date +dated +dates +dating +daughter +daughters +dave +david +davidson +davis +dawn +day +days +dayton +db +dc +dd +ddr +de +dead +deadline +deadly +deaf +deal +dealer +dealers +dealing +deals +dealt +dealtime +dean +dear +death +deaths +debate +debian +deborah +debt +debug +debut +dec +decade +decades +december +decent +decide +decided +decimal +decision +decisions +deck +declaration +declare +declared +decline +declined +decor +decorating +decorative +decrease +decreased +dedicated +dee +deemed +deep +deeper +deeply +deer +def +default +defeat +defects +defence +defend +defendant +defense +defensive +deferred +deficit +define +defined +defines +defining +definitely +definition +definitions +degree +degrees +del +delaware +delay +delayed +delays +delegation +delete +deleted +delhi +delicious +delight +deliver +delivered +delivering +delivers +delivery +dell +delta +deluxe +dem +demand +demanding +demands +demo +democracy +democrat +democratic +democrats +demographic +demonstrate +demonstrated +demonstrates +demonstration +den +denial +denied +denmark +dennis +dense +density +dental +dentists +denver +deny +department +departmental +departments +departure +depend +dependence +dependent +depending +depends +deployment +deposit +deposits +depot +depression +dept +depth +deputy +der +derby +derek +derived +des +descending +describe +described +describes +describing +description +descriptions +desert +deserve +design +designated +designation +designed +designer +designers +designing +designs +desirable +desire +desired +desk +desktop +desktops +desperate +despite +destination +destinations +destiny +destroy +destroyed +destruction +detail +detailed +details +detect +detected +detection +detective +detector +determination +determine +determined +determines +determining +detroit +deutsch +deutsche +deutschland +dev +devel +develop +developed +developer +developers +developing +development +developmental +developments +develops +deviant +deviation +device +devices +devil +devon +devoted +df +dg +dh +di +diabetes +diagnosis +diagnostic +diagram +dial +dialog +dialogue +diameter +diamond +diamonds +diana +diane +diary +dice +dick +dicke +dicks +dictionaries +dictionary +did +die +died +diego +dies +diesel +diet +dietary +diff +differ +difference +differences +different +differential +differently +difficult +difficulties +difficulty +diffs +dig +digest +digit +digital +dildo +dildos +dim +dimension +dimensional +dimensions +dining +dinner +dip +diploma +dir +direct +directed +direction +directions +directive +directly +director +directories +directors +directory +dirt +dirty +dis +disabilities +disability +disable +disabled +disagree +disappointed +disaster +disc +discharge +disciplinary +discipline +disciplines +disclaimer +disclaimers +disclose +disclosure +disco +discount +discounted +discounts +discover +discovered +discovery +discrete +discretion +discrimination +discs +discuss +discussed +discusses +discussing +discussion +discussions +disease +diseases +dish +dishes +disk +disks +disney +disorder +disorders +dispatch +dispatched +display +displayed +displaying +displays +disposal +disposition +dispute +disputes +dist +distance +distances +distant +distinct +distinction +distinguished +distribute +distributed +distribution +distributions +distributor +distributors +district +districts +disturbed +div +dive +diverse +diversity +divide +divided +dividend +divine +diving +division +divisions +divorce +divx +diy +dj +dk +dl +dm +dna +dns +do +doc +dock +docs +doctor +doctors +doctrine +document +documentary +documentation +documentcreatetextnode +documented +documents +dod +dodge +doe +does +dog +dogs +doing +doll +dollar +dollars +dolls +dom +domain +domains +dome +domestic +dominant +dominican +don +donald +donate +donated +donation +donations +done +donna +donor +donors +dont +doom +door +doors +dos +dosage +dose +dot +double +doubt +doug +douglas +dover +dow +down +download +downloadable +downloadcom +downloaded +downloading +downloads +downtown +dozen +dozens +dp +dpi +dr +draft +drag +dragon +drain +drainage +drama +dramatic +dramatically +draw +drawing +drawings +drawn +draws +dream +dreams +dress +dressed +dresses +dressing +drew +dried +drill +drilling +drink +drinking +drinks +drive +driven +driver +drivers +drives +driving +drop +dropped +drops +drove +drug +drugs +drum +drums +drunk +dry +dryer +ds +dsc +dsl +dt +dts +du +dual +dubai +dublin +duck +dude +due +dui +duke +dumb +dump +duncan +duo +duplicate +durable +duration +durham +during +dust +dutch +duties +duty +dv +dvd +dvds +dx +dying +dylan +dynamic +dynamics +e +ea +each +eagle +eagles +ear +earl +earlier +earliest +early +earn +earned +earning +earnings +earrings +ears +earth +earthquake +ease +easier +easily +east +easter +eastern +easy +eat +eating +eau +ebay +ebony +ebook +ebooks +ec +echo +eclipse +eco +ecological +ecology +ecommerce +economic +economics +economies +economy +ecuador +ed +eddie +eden +edgar +edge +edges +edinburgh +edit +edited +editing +edition +editions +editor +editorial +editorials +editors +edmonton +eds +edt +educated +education +educational +educators +edward +edwards +ee +ef +effect +effective +effectively +effectiveness +effects +efficiency +efficient +efficiently +effort +efforts +eg +egg +eggs +egypt +egyptian +eh +eight +either +ejaculation +el +elder +elderly +elect +elected +election +elections +electoral +electric +electrical +electricity +electro +electron +electronic +electronics +elegant +element +elementary +elements +elephant +elevation +eleven +eligibility +eligible +eliminate +elimination +elite +elizabeth +ellen +elliott +ellis +else +elsewhere +elvis +em +emacs +email +emails +embassy +embedded +emerald +emergency +emerging +emily +eminem +emirates +emission +emissions +emma +emotional +emotions +emperor +emphasis +empire +empirical +employ +employed +employee +employees +employer +employers +employment +empty +en +enable +enabled +enables +enabling +enb +enclosed +enclosure +encoding +encounter +encountered +encourage +encouraged +encourages +encouraging +encryption +encyclopedia +end +endangered +ended +endif +ending +endless +endorsed +endorsement +ends +enemies +enemy +energy +enforcement +eng +engage +engaged +engagement +engaging +engine +engineer +engineering +engineers +engines +england +english +enhance +enhanced +enhancement +enhancements +enhancing +enjoy +enjoyed +enjoying +enlarge +enlargement +enormous +enough +enquiries +enquiry +enrolled +enrollment +ensemble +ensure +ensures +ensuring +ent +enter +entered +entering +enterprise +enterprises +enters +entertaining +entertainment +entire +entirely +entities +entitled +entity +entrance +entrepreneur +entrepreneurs +entries +entry +envelope +environment +environmental +environments +enzyme +eos +ep +epa +epic +epinions +epinionscom +episode +episodes +epson +eq +equal +equality +equally +equation +equations +equilibrium +equipment +equipped +equity +equivalent +er +era +eric +ericsson +erik +erotic +erotica +erp +error +errors +es +escape +escort +escorts +especially +espn +essay +essays +essence +essential +essentially +essentials +essex +est +establish +established +establishing +establishment +estate +estates +estimate +estimated +estimates +estimation +estonia +et +etc +eternal +ethernet +ethical +ethics +ethiopia +ethnic +eu +eugene +eur +euro +europe +european +euros +ev +eva +eval +evaluate +evaluated +evaluating +evaluation +evaluations +evanescence +evans +eve +even +evening +event +events +eventually +ever +every +everybody +everyday +everyone +everything +everywhere +evidence +evident +evil +evolution +ex +exact +exactly +exam +examination +examinations +examine +examined +examines +examining +example +examples +exams +exceed +excel +excellence +excellent +except +exception +exceptional +exceptions +excerpt +excess +excessive +exchange +exchanges +excited +excitement +exciting +exclude +excluded +excluding +exclusion +exclusive +exclusively +excuse +exec +execute +executed +execution +executive +executives +exempt +exemption +exercise +exercises +exhaust +exhibit +exhibition +exhibitions +exhibits +exist +existed +existence +existing +exists +exit +exotic +exp +expand +expanded +expanding +expansion +expansys +expect +expectations +expected +expects +expedia +expenditure +expenditures +expense +expenses +expensive +experience +experienced +experiences +experiencing +experiment +experimental +experiments +expert +expertise +experts +expiration +expired +expires +explain +explained +explaining +explains +explanation +explicit +explicitly +exploration +explore +explorer +exploring +explosion +expo +export +exports +exposed +exposure +express +expressed +expression +expressions +ext +extend +extended +extending +extends +extension +extensions +extensive +extent +exterior +external +extra +extract +extraction +extraordinary +extras +extreme +extremely +eye +eyed +eyes +ez +f +fa +fabric +fabrics +fabulous +face +faced +faces +facial +facilitate +facilities +facility +facing +fact +factor +factors +factory +facts +faculty +fail +failed +failing +fails +failure +failures +fair +fairfield +fairly +fairy +faith +fake +fall +fallen +falling +falls +false +fame +familiar +families +family +famous +fan +fancy +fans +fantastic +fantasy +faq +faqs +far +fare +fares +farm +farmer +farmers +farming +farms +fascinating +fashion +fast +faster +fastest +fat +fatal +fate +father +fathers +fatty +fault +favor +favorite +favorites +favors +favour +favourite +favourites +fax +fbi +fc +fcc +fd +fda +fe +fear +fears +feat +feature +featured +features +featuring +feb +february +fed +federal +federation +fee +feed +feedback +feeding +feeds +feel +feeling +feelings +feels +fees +feet +fell +fellow +fellowship +felt +female +females +fence +feof +ferrari +ferry +festival +festivals +fetish +fever +few +fewer +ff +fg +fi +fiber +fibre +fiction +field +fields +fifteen +fifth +fifty +fig +fight +fighter +fighters +fighting +figure +figured +figures +fiji +file +filed +filename +files +filing +fill +filled +filling +film +filme +films +filter +filtering +filters +fin +final +finally +finals +finance +finances +financial +financing +find +findarticles +finder +finding +findings +findlaw +finds +fine +finest +finger +fingering +fingers +finish +finished +finishing +finite +finland +finnish +fioricet +fire +fired +firefox +fireplace +fires +firewall +firewire +firm +firms +firmware +first +fiscal +fish +fisher +fisheries +fishing +fist +fisting +fit +fitness +fits +fitted +fitting +five +fix +fixed +fixes +fixtures +fl +fla +flag +flags +flame +flash +flashers +flashing +flat +flavor +fleece +fleet +flesh +flex +flexibility +flexible +flickr +flight +flights +flip +float +floating +flood +floor +flooring +floors +floppy +floral +florence +florida +florist +florists +flour +flow +flower +flowers +flows +floyd +flu +fluid +flush +flux +fly +flyer +flying +fm +fo +foam +focal +focus +focused +focuses +focusing +fog +fold +folder +folders +folding +folk +folks +follow +followed +following +follows +font +fonts +foo +food +foods +fool +foot +footage +football +footwear +for +forbes +forbidden +force +forced +forces +ford +forecast +forecasts +foreign +forest +forestry +forests +forever +forge +forget +forgot +forgotten +fork +form +formal +format +formation +formats +formatting +formed +former +formerly +forming +forms +formula +fort +forth +fortune +forty +forum +forums +forward +forwarding +fossil +foster +foto +fotos +fought +foul +found +foundation +foundations +founded +founder +fountain +four +fourth +fox +fp +fr +fraction +fragrance +fragrances +frame +framed +frames +framework +framing +france +franchise +francis +francisco +frank +frankfurt +franklin +fraser +fraud +fred +frederick +free +freebsd +freedom +freelance +freely +freeware +freeze +freight +french +frequencies +frequency +frequent +frequently +fresh +fri +friday +fridge +friend +friendly +friends +friendship +frog +from +front +frontier +frontpage +frost +frozen +fruit +fruits +fs +ft +ftp +fu +fuck +fucked +fucking +fuel +fuji +fujitsu +full +fully +fun +function +functional +functionality +functioning +functions +fund +fundamental +fundamentals +funded +funding +fundraising +funds +funeral +funk +funky +funny +fur +furnished +furnishings +furniture +further +furthermore +fusion +future +futures +fuzzy +fw +fwd +fx +fy +g +ga +gabriel +gadgets +gage +gain +gained +gains +galaxy +gale +galleries +gallery +gambling +game +gamecube +games +gamespot +gaming +gamma +gang +gangbang +gap +gaps +garage +garbage +garcia +garden +gardening +gardens +garlic +garmin +gary +gas +gasoline +gate +gates +gateway +gather +gathered +gathering +gauge +gave +gay +gays +gazette +gb +gba +gbp +gc +gcc +gd +gdp +ge +gear +geek +gel +gem +gen +gender +gene +genealogy +general +generally +generate +generated +generates +generating +generation +generations +generator +generators +generic +generous +genes +genesis +genetic +genetics +geneva +genius +genome +genre +genres +gentle +gentleman +gently +genuine +geo +geographic +geographical +geography +geological +geology +geometry +george +georgia +gerald +german +germany +get +gets +getting +gg +ghana +ghost +ghz +gi +giant +giants +gibraltar +gibson +gif +gift +gifts +gig +gilbert +girl +girlfriend +girls +gis +give +given +gives +giving +gl +glad +glance +glasgow +glass +glasses +glen +glenn +global +globe +glory +glossary +gloves +glow +glucose +gm +gmbh +gmc +gmt +gnome +gnu +go +goal +goals +goat +god +gods +goes +going +gold +golden +golf +gone +gonna +good +goods +google +gordon +gore +gorgeous +gospel +gossip +got +gothic +goto +gotta +gotten +gourmet +gov +governance +governing +government +governmental +governments +governor +govt +gp +gpl +gps +gr +grab +grace +grad +grade +grades +gradually +graduate +graduated +graduates +graduation +graham +grain +grammar +grams +grand +grande +granny +grant +granted +grants +graph +graphic +graphical +graphics +graphs +gras +grass +grateful +gratis +gratuit +grave +gravity +gray +great +greater +greatest +greatly +greece +greek +green +greene +greenhouse +greensboro +greeting +greetings +greg +gregory +grenada +grew +grey +grid +griffin +grill +grip +grocery +groove +gross +ground +grounds +groundwater +group +groups +grove +grow +growing +grown +grows +growth +gs +gsm +gst +gt +gtk +guam +guarantee +guaranteed +guarantees +guard +guardian +guards +guatemala +guess +guest +guestbook +guests +gui +guidance +guide +guided +guidelines +guides +guild +guilty +guinea +guitar +guitars +gulf +gun +guns +guru +guy +guyana +guys +gym +gzip +h +ha +habitat +habits +hack +hacker +had +hair +hairy +haiti +half +halfcom +halifax +hall +halloween +halo +ham +hamburg +hamilton +hammer +hampshire +hampton +hand +handbags +handbook +handed +handheld +handhelds +handjob +handjobs +handle +handled +handles +handling +handmade +hands +handy +hang +hanging +hans +hansen +happen +happened +happening +happens +happiness +happy +harassment +harbor +harbour +hard +hardcore +hardcover +harder +hardly +hardware +hardwood +harley +harm +harmful +harmony +harold +harper +harris +harrison +harry +hart +hartford +harvard +harvest +harvey +has +hash +hat +hate +hats +have +haven +having +hawaii +hawaiian +hawk +hay +hayes +hazard +hazardous +hazards +hb +hc +hd +hdtv +he +head +headed +header +headers +heading +headline +headlines +headphones +headquarters +heads +headset +healing +health +healthcare +healthy +hear +heard +hearing +hearings +heart +hearts +heat +heated +heater +heath +heather +heating +heaven +heavily +heavy +hebrew +heel +height +heights +held +helen +helena +helicopter +hell +hello +helmet +help +helped +helpful +helping +helps +hence +henderson +henry +hentai +hepatitis +her +herald +herb +herbal +herbs +here +hereby +herein +heritage +hero +heroes +herself +hewlett +hey +hh +hi +hidden +hide +hierarchy +high +higher +highest +highland +highlight +highlighted +highlights +highly +highs +highway +highways +hiking +hill +hills +hilton +him +himself +hindu +hint +hints +hip +hire +hired +hiring +his +hispanic +hist +historic +historical +history +hit +hitachi +hits +hitting +hiv +hk +hl +ho +hobbies +hobby +hockey +hold +holdem +holder +holders +holding +holdings +holds +hole +holes +holiday +holidays +holland +hollow +holly +hollywood +holmes +holocaust +holy +home +homeland +homeless +homepage +homes +hometown +homework +hon +honda +honduras +honest +honey +hong +honolulu +honor +honors +hood +hook +hop +hope +hoped +hopefully +hopes +hoping +hopkins +horizon +horizontal +hormone +horn +horny +horrible +horror +horse +horses +hose +hospital +hospitality +hospitals +host +hosted +hostel +hostels +hosting +hosts +hot +hotel +hotels +hotelscom +hotmail +hottest +hour +hourly +hours +house +household +households +houses +housewares +housewives +housing +houston +how +howard +however +howto +hp +hq +hr +href +hrs +hs +ht +html +http +hu +hub +hudson +huge +hugh +hughes +hugo +hull +human +humanitarian +humanities +humanity +humans +humidity +humor +hundred +hundreds +hung +hungarian +hungary +hunger +hungry +hunt +hunter +hunting +huntington +hurricane +hurt +husband +hwy +hybrid +hydraulic +hydrocodone +hydrogen +hygiene +hypothesis +hypothetical +hyundai +hz +i +ia +ian +ibm +ic +ice +iceland +icon +icons +icq +ict +id +idaho +ide +idea +ideal +ideas +identical +identification +identified +identifier +identifies +identify +identifying +identity +idle +idol +ids +ie +ieee +if +ignore +ignored +ii +iii +il +ill +illegal +illinois +illness +illustrated +illustration +illustrations +im +ima +image +images +imagination +imagine +imaging +img +immediate +immediately +immigrants +immigration +immune +immunology +impact +impacts +impaired +imperial +implement +implementation +implemented +implementing +implications +implied +implies +import +importance +important +importantly +imported +imports +impose +imposed +impossible +impressed +impression +impressive +improve +improved +improvement +improvements +improving +in +inappropriate +inbox +inc +incentive +incentives +incest +inch +inches +incidence +incident +incidents +incl +include +included +includes +including +inclusion +inclusive +income +incoming +incomplete +incorporate +incorporated +incorrect +increase +increased +increases +increasing +increasingly +incredible +incurred +ind +indeed +independence +independent +independently +index +indexed +indexes +india +indian +indiana +indianapolis +indians +indicate +indicated +indicates +indicating +indication +indicator +indicators +indices +indie +indigenous +indirect +individual +individually +individuals +indonesia +indonesian +indoor +induced +induction +industrial +industries +industry +inexpensive +inf +infant +infants +infected +infection +infections +infectious +infinite +inflation +influence +influenced +influences +info +inform +informal +information +informational +informative +informed +infrared +infrastructure +ing +ingredients +inherited +initial +initially +initiated +initiative +initiatives +injection +injured +injuries +injury +ink +inkjet +inline +inn +inner +innocent +innovation +innovations +innovative +inns +input +inputs +inquire +inquiries +inquiry +ins +insects +insert +inserted +insertion +inside +insider +insight +insights +inspection +inspections +inspector +inspiration +inspired +install +installation +installations +installed +installing +instance +instances +instant +instantly +instead +institute +institutes +institution +institutional +institutions +instruction +instructional +instructions +instructor +instructors +instrument +instrumental +instrumentation +instruments +insulin +insurance +insured +int +intake +integer +integral +integrate +integrated +integrating +integration +integrity +intel +intellectual +intelligence +intelligent +intend +intended +intense +intensity +intensive +intent +intention +inter +interact +interaction +interactions +interactive +interest +interested +interesting +interests +interface +interfaces +interference +interim +interior +intermediate +internal +international +internationally +internet +internship +interpretation +interpreted +interracial +intersection +interstate +interval +intervals +intervention +interventions +interview +interviews +intimate +intl +into +intranet +intro +introduce +introduced +introduces +introducing +introduction +introductory +invalid +invasion +invention +inventory +invest +investigate +investigated +investigation +investigations +investigator +investigators +investing +investment +investments +investor +investors +invisible +invision +invitation +invitations +invite +invited +invoice +involve +involved +involvement +involves +involving +io +ion +iowa +ip +ipaq +ipod +ips +ir +ira +iran +iraq +iraqi +irc +ireland +irish +iron +irrigation +irs +is +isa +isaac +isbn +islam +islamic +island +islands +isle +iso +isolated +isolation +isp +israel +israeli +issn +issue +issued +issues +ist +istanbul +it +italia +italian +italiano +italic +italy +item +items +its +itsa +itself +itunes +iv +ivory +ix +j +ja +jack +jacket +jackets +jackie +jackson +jacksonville +jacob +jade +jaguar +jail +jake +jam +jamaica +james +jamie +jan +jane +janet +january +japan +japanese +jar +jason +java +javascript +jay +jazz +jc +jd +je +jean +jeans +jeep +jeff +jefferson +jeffrey +jelsoft +jennifer +jenny +jeremy +jerry +jersey +jerusalem +jesse +jessica +jesus +jet +jets +jewel +jewellery +jewelry +jewish +jews +jill +jim +jimmy +jj +jm +jo +joan +job +jobs +joe +joel +john +johnny +johns +johnson +johnston +join +joined +joining +joins +joint +joke +jokes +jon +jonathan +jones +jordan +jose +joseph +josh +joshua +journal +journalism +journalist +journalists +journals +journey +joy +joyce +jp +jpeg +jpg +jr +js +juan +judge +judges +judgment +judicial +judy +juice +jul +julia +julian +julie +july +jump +jumping +jun +junction +june +jungle +junior +junk +jurisdiction +jury +just +justice +justify +justin +juvenile +jvc +k +ka +kai +kansas +karaoke +karen +karl +karma +kate +kathy +katie +katrina +kay +kazakhstan +kb +kde +keen +keep +keeping +keeps +keith +kelkoo +kelly +ken +kennedy +kenneth +kenny +keno +kent +kentucky +kenya +kept +kernel +kerry +kevin +key +keyboard +keyboards +keys +keyword +keywords +kg +kick +kid +kidney +kids +kijiji +kill +killed +killer +killing +kills +kilometers +kim +kinase +kind +kinda +kinds +king +kingdom +kings +kingston +kirk +kiss +kissing +kit +kitchen +kits +kitty +klein +km +knee +knew +knife +knight +knights +knit +knitting +knives +knock +know +knowing +knowledge +knowledgestorm +known +knows +ko +kodak +kong +korea +korean +kruger +ks +kurt +kuwait +kw +ky +kyle +l +la +lab +label +labeled +labels +labor +laboratories +laboratory +labour +labs +lace +lack +ladder +laden +ladies +lady +lafayette +laid +lake +lakes +lamb +lambda +lamp +lamps +lan +lancaster +lance +land +landing +lands +landscape +landscapes +lane +lanes +lang +language +languages +lanka +lap +laptop +laptops +large +largely +larger +largest +larry +las +laser +last +lasting +lat +late +lately +later +latest +latex +latin +latina +latinas +latino +latitude +latter +latvia +lauderdale +laugh +laughing +launch +launched +launches +laundry +laura +lauren +law +lawn +lawrence +laws +lawsuit +lawyer +lawyers +lay +layer +layers +layout +lazy +lb +lbs +lc +lcd +ld +le +lead +leader +leaders +leadership +leading +leads +leaf +league +lean +learn +learned +learners +learning +lease +leasing +least +leather +leave +leaves +leaving +lebanon +lecture +lectures +led +lee +leeds +left +leg +legacy +legal +legally +legend +legendary +legends +legislation +legislative +legislature +legitimate +legs +leisure +lemon +len +lender +lenders +lending +length +lens +lenses +leo +leon +leonard +leone +les +lesbian +lesbians +leslie +less +lesser +lesson +lessons +let +lets +letter +letters +letting +leu +level +levels +levitra +levy +lewis +lexington +lexmark +lexus +lf +lg +li +liabilities +liability +liable +lib +liberal +liberia +liberty +librarian +libraries +library +libs +licence +license +licensed +licenses +licensing +licking +lid +lie +liechtenstein +lies +life +lifestyle +lifetime +lift +light +lighter +lighting +lightning +lights +lightweight +like +liked +likelihood +likely +likes +likewise +lil +lime +limit +limitation +limitations +limited +limiting +limits +limousines +lincoln +linda +lindsay +line +linear +lined +lines +lingerie +link +linked +linking +links +linux +lion +lions +lip +lips +liquid +lisa +list +listed +listen +listening +listing +listings +listprice +lists +lit +lite +literacy +literally +literary +literature +lithuania +litigation +little +live +livecam +lived +liver +liverpool +lives +livesex +livestock +living +liz +ll +llc +lloyd +llp +lm +ln +lo +load +loaded +loading +loads +loan +loans +lobby +loc +local +locale +locally +locate +located +location +locations +locator +lock +locked +locking +locks +lodge +lodging +log +logan +logged +logging +logic +logical +login +logistics +logitech +logo +logos +logs +lol +lolita +london +lone +lonely +long +longer +longest +longitude +look +looked +looking +looks +looksmart +lookup +loop +loops +loose +lopez +lord +los +lose +losing +loss +losses +lost +lot +lots +lottery +lotus +lou +loud +louis +louise +louisiana +louisville +lounge +love +loved +lovely +lover +lovers +loves +loving +low +lower +lowest +lows +lp +ls +lt +ltd +lu +lucas +lucia +luck +lucky +lucy +luggage +luis +luke +lunch +lung +luther +luxembourg +luxury +lycos +lying +lynn +lyric +lyrics +m +ma +mac +macedonia +machine +machinery +machines +macintosh +macro +macromedia +mad +madagascar +made +madison +madness +madonna +madrid +mae +mag +magazine +magazines +magic +magical +magnet +magnetic +magnificent +magnitude +mai +maiden +mail +mailed +mailing +mailman +mails +mailto +main +maine +mainland +mainly +mainstream +maintain +maintained +maintaining +maintains +maintenance +major +majority +make +maker +makers +makes +makeup +making +malawi +malaysia +maldives +male +males +mali +mall +malpractice +malta +mambo +man +manage +managed +management +manager +managers +managing +manchester +mandate +mandatory +manga +manhattan +manitoba +manner +manor +manual +manually +manuals +manufacture +manufactured +manufacturer +manufacturers +manufacturing +many +map +maple +mapping +maps +mar +marathon +marble +marc +march +marco +marcus +mardi +margaret +margin +maria +mariah +marie +marijuana +marilyn +marina +marine +mario +marion +maritime +mark +marked +marker +markers +market +marketing +marketplace +markets +marking +marks +marriage +married +marriott +mars +marshall +mart +martha +martial +martin +marvel +mary +maryland +mas +mask +mason +mass +massachusetts +massage +massive +master +mastercard +masters +masturbating +masturbation +mat +match +matched +matches +matching +mate +material +materials +maternity +math +mathematical +mathematics +mating +matrix +mats +matt +matter +matters +matthew +mattress +mature +maui +mauritius +max +maximize +maximum +may +maybe +mayor +mazda +mb +mba +mc +mcdonald +md +me +meal +meals +mean +meaning +meaningful +means +meant +meanwhile +measure +measured +measurement +measurements +measures +measuring +meat +mechanical +mechanics +mechanism +mechanisms +med +medal +media +median +medicaid +medical +medicare +medication +medications +medicine +medicines +medieval +meditation +mediterranean +medium +medline +meet +meeting +meetings +meets +meetup +mega +mel +melbourne +melissa +mem +member +members +membership +membrane +memo +memorabilia +memorial +memories +memory +memphis +men +mens +ment +mental +mention +mentioned +mentor +menu +menus +mercedes +merchandise +merchant +merchants +mercury +mercy +mere +merely +merge +merger +merit +merry +mesa +mesh +mess +message +messages +messaging +messenger +met +meta +metabolism +metadata +metal +metallic +metallica +metals +meter +meters +method +methodology +methods +metres +metric +metro +metropolitan +mexican +mexico +meyer +mf +mfg +mg +mh +mhz +mi +mia +miami +mic +mice +michael +michel +michelle +michigan +micro +microphone +microsoft +microwave +mid +middle +midi +midlands +midnight +midwest +might +mighty +migration +mike +mil +milan +mild +mile +mileage +miles +milf +milfhunter +milfs +military +milk +mill +millennium +miller +million +millions +mills +milton +milwaukee +mime +min +mind +minds +mine +mineral +minerals +mines +mini +miniature +minimal +minimize +minimum +mining +minister +ministers +ministries +ministry +minneapolis +minnesota +minolta +minor +minority +mins +mint +minus +minute +minutes +miracle +mirror +mirrors +misc +miscellaneous +miss +missed +missile +missing +mission +missions +mississippi +missouri +mistake +mistakes +mistress +mit +mitchell +mitsubishi +mix +mixed +mixer +mixing +mixture +mj +ml +mlb +mls +mm +mn +mo +mobile +mobiles +mobility +mod +mode +model +modeling +modelling +models +modem +modems +moderate +moderator +moderators +modern +modes +modification +modifications +modified +modify +mods +modular +module +modules +moisture +mold +moldova +molecular +molecules +mom +moment +moments +momentum +moms +mon +monaco +monday +monetary +money +mongolia +monica +monitor +monitored +monitoring +monitors +monkey +mono +monroe +monster +montana +monte +montgomery +month +monthly +months +montreal +mood +moon +moore +moral +more +moreover +morgan +morning +morocco +morris +morrison +mortality +mortgage +mortgages +moscow +moses +moss +most +mostly +motel +motels +mother +motherboard +mothers +motion +motivated +motivation +motor +motorcycle +motorcycles +motorola +motors +mount +mountain +mountains +mounted +mounting +mounts +mouse +mouth +move +moved +movement +movements +movers +moves +movie +movies +moving +mozambique +mozilla +mp +mpeg +mpegs +mpg +mph +mr +mrna +mrs +ms +msg +msgid +msgstr +msie +msn +mt +mtv +mu +much +mud +mug +multi +multimedia +multiple +mumbai +munich +municipal +municipality +murder +murphy +murray +muscle +muscles +museum +museums +music +musical +musician +musicians +muslim +muslims +must +mustang +mutual +muze +mv +mw +mx +my +myanmar +myers +myrtle +myself +mysimon +myspace +mysql +mysterious +mystery +myth +n +na +nail +nails +naked +nam +name +named +namely +names +namespace +namibia +nancy +nano +naples +narrative +narrow +nasa +nascar +nasdaq +nashville +nasty +nat +nathan +nation +national +nationally +nations +nationwide +native +nato +natural +naturally +naturals +nature +naughty +nav +naval +navigate +navigation +navigator +navy +nb +nba +nbc +nc +ncaa +nd +ne +near +nearby +nearest +nearly +nebraska +nec +necessarily +necessary +necessity +neck +necklace +need +needed +needle +needs +negative +negotiation +negotiations +neighbor +neighborhood +neighbors +neil +neither +nelson +neo +neon +nepal +nerve +nervous +nest +nested +net +netherlands +netscape +network +networking +networks +neural +neutral +nevada +never +nevertheless +new +newark +newbie +newcastle +newer +newest +newfoundland +newly +newport +news +newscom +newsletter +newsletters +newspaper +newspapers +newton +next +nextel +nfl +ng +nh +nhl +nhs +ni +niagara +nicaragua +nice +nicholas +nick +nickel +nickname +nicole +niger +nigeria +night +nightlife +nightmare +nights +nike +nikon +nil +nine +nintendo +nipple +nipples +nirvana +nissan +nitrogen +nj +nl +nm +nn +no +noble +nobody +node +nodes +noise +nokia +nominated +nomination +nominations +non +none +nonprofit +noon +nor +norfolk +norm +normal +normally +norman +north +northeast +northern +northwest +norton +norway +norwegian +nos +nose +not +note +notebook +notebooks +noted +notes +nothing +notice +noticed +notices +notification +notifications +notified +notify +notion +notre +nottingham +nov +nova +novel +novels +novelty +november +now +nowhere +np +nr +ns +nsw +nt +ntsc +nu +nuclear +nude +nudist +nudity +nuke +null +number +numbers +numeric +numerical +numerous +nurse +nursery +nurses +nursing +nut +nutrition +nutritional +nuts +nutten +nv +nvidia +nw +ny +nyc +nylon +nz +o +oak +oakland +oaks +oasis +ob +obesity +obituaries +obj +object +objective +objectives +objects +obligation +obligations +observation +observations +observe +observed +observer +obtain +obtained +obtaining +obvious +obviously +oc +occasion +occasional +occasionally +occasions +occupation +occupational +occupations +occupied +occur +occurred +occurrence +occurring +occurs +ocean +oclc +oct +october +odd +odds +oe +oecd +oem +of +off +offense +offensive +offer +offered +offering +offerings +offers +office +officer +officers +offices +official +officially +officials +offline +offset +offshore +often +og +oh +ohio +oil +oils +ok +okay +oklahoma +ol +old +older +oldest +olive +oliver +olympic +olympics +olympus +om +omaha +oman +omega +omissions +on +once +one +ones +ongoing +onion +online +only +ons +ontario +onto +oo +ooo +oops +op +open +opened +opening +openings +opens +opera +operate +operated +operates +operating +operation +operational +operations +operator +operators +opinion +opinions +opponent +opponents +opportunities +opportunity +opposed +opposite +opposition +opt +optical +optics +optimal +optimization +optimize +optimum +option +optional +options +or +oracle +oral +orange +orbit +orchestra +order +ordered +ordering +orders +ordinance +ordinary +oregon +org +organ +organic +organisation +organisations +organised +organisms +organization +organizational +organizations +organize +organized +organizer +organizing +orgasm +orgy +oriental +orientation +oriented +origin +original +originally +origins +orlando +orleans +os +oscar +ot +other +others +otherwise +ottawa +ou +ought +our +ours +ourselves +out +outcome +outcomes +outdoor +outdoors +outer +outlet +outline +outlined +outlook +output +outputs +outreach +outside +outsourcing +outstanding +oval +oven +over +overall +overcome +overhead +overnight +overseas +overview +owen +own +owned +owner +owners +ownership +owns +oxford +oxide +oxygen +oz +ozone +p +pa +pac +pace +pacific +pack +package +packages +packaging +packard +packed +packet +packets +packing +packs +pad +pads +page +pages +paid +pain +painful +paint +paintball +painted +painting +paintings +pair +pairs +pakistan +pal +palace +pale +palestine +palestinian +palm +palmer +pam +pamela +pan +panama +panasonic +panel +panels +panic +panties +pants +pantyhose +paper +paperback +paperbacks +papers +papua +par +para +parade +paradise +paragraph +paragraphs +paraguay +parallel +parameter +parameters +parcel +parent +parental +parenting +parents +paris +parish +park +parker +parking +parks +parliament +parliamentary +part +partial +partially +participant +participants +participate +participated +participating +participation +particle +particles +particular +particularly +parties +partition +partly +partner +partners +partnership +partnerships +parts +party +pas +paso +pass +passage +passed +passenger +passengers +passes +passing +passion +passive +passport +password +passwords +past +pasta +paste +pastor +pat +patch +patches +patent +patents +path +pathology +paths +patient +patients +patio +patricia +patrick +patrol +pattern +patterns +paul +pavilion +paxil +pay +payable +payday +paying +payment +payments +paypal +payroll +pays +pb +pc +pci +pcs +pct +pd +pda +pdas +pdf +pdt +pe +peace +peaceful +peak +pearl +peas +pediatric +pee +peeing +peer +peers +pen +penalties +penalty +pencil +pendant +pending +penetration +penguin +peninsula +penis +penn +pennsylvania +penny +pens +pension +pensions +pentium +people +peoples +pepper +per +perceived +percent +percentage +perception +perfect +perfectly +perform +performance +performances +performed +performer +performing +performs +perfume +perhaps +period +periodic +periodically +periods +peripheral +peripherals +perl +permalink +permanent +permission +permissions +permit +permits +permitted +perry +persian +persistent +person +personal +personality +personalized +personally +personals +personnel +persons +perspective +perspectives +perth +peru +pest +pet +pete +peter +petersburg +peterson +petite +petition +petroleum +pets +pf +pg +pgp +ph +phantom +pharmaceutical +pharmaceuticals +pharmacies +pharmacology +pharmacy +phase +phases +phd +phenomenon +phentermine +phi +phil +philadelphia +philip +philippines +philips +phillips +philosophy +phoenix +phone +phones +photo +photograph +photographer +photographers +photographic +photographs +photography +photos +photoshop +php +phpbb +phrase +phrases +phys +physical +physically +physician +physicians +physics +physiology +pi +piano +pic +pichunter +pick +picked +picking +picks +pickup +picnic +pics +picture +pictures +pie +piece +pieces +pierce +pierre +pig +pike +pill +pillow +pills +pilot +pin +pine +ping +pink +pins +pioneer +pipe +pipeline +pipes +pirates +piss +pissing +pit +pitch +pittsburgh +pix +pixel +pixels +pizza +pj +pk +pl +place +placed +placement +places +placing +plain +plains +plaintiff +plan +plane +planes +planet +planets +planned +planner +planners +planning +plans +plant +plants +plasma +plastic +plastics +plate +plates +platform +platforms +platinum +play +playback +playboy +played +player +players +playing +playlist +plays +playstation +plaza +plc +pleasant +please +pleased +pleasure +pledge +plenty +plot +plots +plug +plugin +plugins +plumbing +plus +plymouth +pm +pmc +pmid +pn +po +pocket +pockets +pod +podcast +podcasts +poem +poems +poet +poetry +point +pointed +pointer +pointing +points +pokemon +poker +poland +polar +pole +police +policies +policy +polish +polished +political +politicians +politics +poll +polls +pollution +polo +poly +polyester +polymer +polyphonic +pond +pontiac +pool +pools +poor +pop +pope +popular +popularity +population +populations +por +porcelain +pork +porn +porno +porsche +port +portable +portal +porter +portfolio +portion +portions +portland +portrait +portraits +ports +portsmouth +portugal +portuguese +pos +pose +posing +position +positioning +positions +positive +possess +possession +possibilities +possibility +possible +possibly +post +postage +postal +postcard +postcards +posted +poster +posters +posting +postings +postposted +posts +pot +potato +potatoes +potential +potentially +potter +pottery +poultry +pound +pounds +pour +poverty +powder +powell +power +powered +powerful +powerpoint +powers +powerseller +pp +ppc +ppm +pr +practical +practice +practices +practitioner +practitioners +prague +prairie +praise +pray +prayer +prayers +pre +preceding +precious +precipitation +precise +precisely +precision +predict +predicted +prediction +predictions +prefer +preference +preferences +preferred +prefers +prefix +pregnancy +pregnant +preliminary +premier +premiere +premises +premium +prep +prepaid +preparation +prepare +prepared +preparing +prerequisite +prescribed +prescription +presence +present +presentation +presentations +presented +presenting +presently +presents +preservation +preserve +president +presidential +press +pressed +pressing +pressure +preston +pretty +prev +prevent +preventing +prevention +preview +previews +previous +previously +price +priced +prices +pricing +pride +priest +primarily +primary +prime +prince +princess +princeton +principal +principle +principles +print +printable +printed +printer +printers +printing +prints +prior +priorities +priority +prison +prisoner +prisoners +privacy +private +privilege +privileges +prix +prize +prizes +pro +probability +probably +probe +problem +problems +proc +procedure +procedures +proceed +proceeding +proceedings +proceeds +process +processed +processes +processing +processor +processors +procurement +produce +produced +producer +producers +produces +producing +product +production +productions +productive +productivity +products +prof +profession +professional +professionals +professor +profile +profiles +profit +profits +program +programme +programmer +programmers +programmes +programming +programs +progress +progressive +prohibited +project +projected +projection +projector +projectors +projects +prominent +promise +promised +promises +promising +promo +promote +promoted +promotes +promoting +promotion +promotional +promotions +prompt +promptly +proof +propecia +proper +properly +properties +property +prophet +proportion +proposal +proposals +propose +proposed +proposition +proprietary +pros +prospect +prospective +prospects +prostate +prostores +prot +protect +protected +protecting +protection +protective +protein +proteins +protest +protocol +protocols +prototype +proud +proudly +prove +proved +proven +provide +provided +providence +provider +providers +provides +providing +province +provinces +provincial +provision +provisions +proxy +prozac +ps +psi +psp +pst +psychiatry +psychological +psychology +pt +pts +pty +pub +public +publication +publications +publicity +publicly +publish +published +publisher +publishers +publishing +pubmed +pubs +puerto +pull +pulled +pulling +pulse +pump +pumps +punch +punishment +punk +pupils +puppy +purchase +purchased +purchases +purchasing +pure +purple +purpose +purposes +purse +pursuant +pursue +pursuit +push +pushed +pushing +pussy +put +puts +putting +puzzle +puzzles +pvc +python +q +qatar +qc +qld +qt +qty +quad +qualification +qualifications +qualified +qualify +qualifying +qualities +quality +quantitative +quantities +quantity +quantum +quarter +quarterly +quarters +que +quebec +queen +queens +queensland +queries +query +quest +question +questionnaire +questions +queue +qui +quick +quickly +quiet +quilt +quit +quite +quiz +quizzes +quotations +quote +quoted +quotes +r +ra +rabbit +race +races +rachel +racial +racing +rack +racks +radar +radiation +radical +radio +radios +radius +rage +raid +rail +railroad +railway +rain +rainbow +raise +raised +raises +raising +raleigh +rally +ralph +ram +ran +ranch +rand +random +randy +range +rangers +ranges +ranging +rank +ranked +ranking +rankings +ranks +rap +rape +rapid +rapidly +rapids +rare +rarely +rat +rate +rated +rates +rather +rating +ratings +ratio +rational +ratios +rats +raw +ray +raymond +rays +rb +rc +rca +rd +re +reach +reached +reaches +reaching +reaction +reactions +read +reader +readers +readily +reading +readings +reads +ready +real +realistic +reality +realize +realized +really +realm +realtor +realtors +realty +rear +reason +reasonable +reasonably +reasoning +reasons +rebate +rebates +rebecca +rebel +rebound +rec +recall +receipt +receive +received +receiver +receivers +receives +receiving +recent +recently +reception +receptor +receptors +recipe +recipes +recipient +recipients +recognised +recognition +recognize +recognized +recommend +recommendation +recommendations +recommended +recommends +reconstruction +record +recorded +recorder +recorders +recording +recordings +records +recover +recovered +recovery +recreation +recreational +recruiting +recruitment +recycling +red +redeem +redhead +reduce +reduced +reduces +reducing +reduction +reductions +reed +reef +reel +ref +refer +reference +referenced +references +referral +referrals +referred +referring +refers +refinance +refine +refined +reflect +reflected +reflection +reflections +reflects +reform +reforms +refresh +refrigerator +refugees +refund +refurbished +refuse +refused +reg +regard +regarded +regarding +regardless +regards +reggae +regime +region +regional +regions +register +registered +registrar +registration +registry +regression +regular +regularly +regulated +regulation +regulations +regulatory +rehab +rehabilitation +reid +reject +rejected +rel +relate +related +relates +relating +relation +relations +relationship +relationships +relative +relatively +relatives +relax +relaxation +relay +release +released +releases +relevance +relevant +reliability +reliable +reliance +relief +religion +religions +religious +reload +relocation +rely +relying +remain +remainder +remained +remaining +remains +remark +remarkable +remarks +remedies +remedy +remember +remembered +remind +reminder +remix +remote +removable +removal +remove +removed +removing +renaissance +render +rendered +rendering +renew +renewable +renewal +reno +rent +rental +rentals +rentcom +rep +repair +repairs +repeat +repeated +replace +replaced +replacement +replacing +replica +replication +replied +replies +reply +report +reported +reporter +reporters +reporting +reports +repository +represent +representation +representations +representative +representatives +represented +representing +represents +reprint +reprints +reproduce +reproduced +reproduction +reproductive +republic +republican +republicans +reputation +request +requested +requesting +requests +require +required +requirement +requirements +requires +requiring +res +rescue +research +researcher +researchers +reseller +reservation +reservations +reserve +reserved +reserves +reservoir +reset +residence +resident +residential +residents +resist +resistance +resistant +resolution +resolutions +resolve +resolved +resort +resorts +resource +resources +respect +respected +respective +respectively +respiratory +respond +responded +respondent +respondents +responding +response +responses +responsibilities +responsibility +responsible +rest +restaurant +restaurants +restoration +restore +restored +restrict +restricted +restriction +restrictions +restructuring +result +resulted +resulting +results +resume +resumes +retail +retailer +retailers +retain +retained +retention +retired +retirement +retreat +retrieval +retrieve +retrieved +retro +return +returned +returning +returns +reunion +reuters +rev +reveal +revealed +reveals +revelation +revenge +revenue +revenues +reverse +review +reviewed +reviewer +reviewing +reviews +revised +revision +revisions +revolution +revolutionary +reward +rewards +reynolds +rf +rfc +rg +rh +rhode +rhythm +ri +ribbon +rica +rice +rich +richard +richards +richardson +richmond +rick +rico +rid +ride +rider +riders +rides +ridge +riding +right +rights +rim +ring +rings +ringtone +ringtones +rio +rip +ripe +rise +rising +risk +risks +river +rivers +riverside +rj +rl +rm +rn +rna +ro +road +roads +rob +robert +roberts +robertson +robin +robinson +robot +robots +robust +rochester +rock +rocket +rocks +rocky +rod +roger +rogers +roland +role +roles +roll +rolled +roller +rolling +rolls +rom +roman +romance +romania +romantic +rome +ron +ronald +roof +room +roommate +roommates +rooms +root +roots +rope +rosa +rose +roses +ross +roster +rotary +rotation +rouge +rough +roughly +roulette +round +rounds +route +router +routers +routes +routine +routines +routing +rover +row +rows +roy +royal +royalty +rp +rpg +rpm +rr +rrp +rs +rss +rt +ru +rubber +ruby +rug +rugby +rugs +rule +ruled +rules +ruling +run +runner +running +runs +runtime +rural +rush +russell +russia +russian +ruth +rv +rw +rwanda +rx +ryan +s +sa +sacramento +sacred +sacrifice +sad +saddam +safari +safe +safely +safer +safety +sage +sagem +said +sail +sailing +saint +saints +sake +salad +salaries +salary +sale +salem +sales +sally +salmon +salon +salt +salvador +salvation +sam +samba +same +samoa +sample +samples +sampling +samsung +samuel +san +sand +sandra +sandwich +sandy +sans +santa +sanyo +sao +sap +sapphire +sara +sarah +sas +saskatchewan +sat +satellite +satin +satisfaction +satisfactory +satisfied +satisfy +saturday +saturn +sauce +saudi +savage +savannah +save +saved +saver +saves +saving +savings +saw +say +saying +says +sb +sbjct +sc +scale +scales +scan +scanned +scanner +scanners +scanning +scary +scenario +scenarios +scene +scenes +scenic +schedule +scheduled +schedules +scheduling +schema +scheme +schemes +scholar +scholars +scholarship +scholarships +school +schools +sci +science +sciences +scientific +scientist +scientists +scoop +scope +score +scored +scores +scoring +scotia +scotland +scott +scottish +scout +scratch +screen +screening +screens +screensaver +screensavers +screenshot +screenshots +screw +script +scripting +scripts +scroll +scsi +scuba +sculpture +sd +se +sea +seafood +seal +sealed +sean +search +searchcom +searched +searches +searching +seas +season +seasonal +seasons +seat +seating +seats +seattle +sec +second +secondary +seconds +secret +secretariat +secretary +secrets +section +sections +sector +sectors +secure +secured +securely +securities +security +see +seed +seeds +seeing +seek +seeker +seekers +seeking +seeks +seem +seemed +seems +seen +sees +sega +segment +segments +select +selected +selecting +selection +selections +selective +self +sell +seller +sellers +selling +sells +semester +semi +semiconductor +seminar +seminars +sen +senate +senator +senators +send +sender +sending +sends +senegal +senior +seniors +sense +sensitive +sensitivity +sensor +sensors +sent +sentence +sentences +seo +sep +separate +separated +separately +separation +sept +september +seq +sequence +sequences +ser +serbia +serial +series +serious +seriously +serum +serve +served +server +servers +serves +service +services +serving +session +sessions +set +sets +setting +settings +settle +settled +settlement +setup +seven +seventh +several +severe +sewing +sex +sexcam +sexo +sexual +sexuality +sexually +sexy +sf +sg +sh +shade +shades +shadow +shadows +shaft +shake +shakespeare +shakira +shall +shame +shanghai +shannon +shape +shaped +shapes +share +shared +shareholders +shares +shareware +sharing +shark +sharon +sharp +shaved +shaw +she +shed +sheep +sheer +sheet +sheets +sheffield +shelf +shell +shelter +shemale +shemales +shepherd +sheriff +sherman +shield +shift +shine +ship +shipment +shipments +shipped +shipping +ships +shirt +shirts +shit +shock +shoe +shoes +shoot +shooting +shop +shopper +shoppercom +shoppers +shopping +shoppingcom +shops +shopzilla +shore +short +shortcuts +shorter +shortly +shorts +shot +shots +should +shoulder +show +showcase +showed +shower +showers +showing +shown +shows +showtimes +shut +shuttle +si +sic +sick +side +sides +sie +siemens +sierra +sig +sight +sigma +sign +signal +signals +signature +signatures +signed +significance +significant +significantly +signing +signs +signup +silence +silent +silicon +silk +silly +silver +sim +similar +similarly +simon +simple +simplified +simply +simpson +simpsons +sims +simulation +simulations +simultaneously +sin +since +sing +singapore +singer +singh +singing +single +singles +sink +sip +sir +sister +sisters +sit +site +sitemap +sites +sitting +situated +situation +situations +six +sixth +size +sized +sizes +sk +skating +ski +skiing +skill +skilled +skills +skin +skins +skip +skirt +skirts +sku +sky +skype +sl +slave +sleep +sleeping +sleeps +sleeve +slide +slides +slideshow +slight +slightly +slim +slip +slope +slot +slots +slovak +slovakia +slovenia +slow +slowly +slut +sluts +sm +small +smaller +smart +smell +smile +smilies +smith +smithsonian +smoke +smoking +smooth +sms +smtp +sn +snake +snap +snapshot +snow +snowboard +so +soa +soap +soc +soccer +social +societies +society +sociology +socket +socks +sodium +sofa +soft +softball +software +soil +sol +solar +solaris +sold +soldier +soldiers +sole +solely +solid +solo +solomon +solution +solutions +solve +solved +solving +soma +somalia +some +somebody +somehow +someone +somerset +something +sometimes +somewhat +somewhere +son +song +songs +sonic +sons +sony +soon +soonest +sophisticated +sorry +sort +sorted +sorts +sought +soul +souls +sound +sounds +soundtrack +soup +source +sources +south +southampton +southeast +southern +southwest +soviet +sox +sp +spa +space +spaces +spain +spam +span +spanish +spank +spanking +sparc +spare +spas +spatial +speak +speaker +speakers +speaking +speaks +spears +spec +special +specialist +specialists +specialized +specializing +specially +specials +specialties +specialty +species +specific +specifically +specification +specifications +specifics +specified +specifies +specify +specs +spectacular +spectrum +speech +speeches +speed +speeds +spell +spelling +spencer +spend +spending +spent +sperm +sphere +spice +spider +spies +spin +spine +spirit +spirits +spiritual +spirituality +split +spoke +spoken +spokesman +sponsor +sponsored +sponsors +sponsorship +sport +sporting +sports +spot +spotlight +spots +spouse +spray +spread +spreading +spring +springer +springfield +springs +sprint +spy +spyware +sq +sql +squad +square +squirt +squirting +sr +src +sri +ss +ssl +st +stability +stable +stack +stadium +staff +staffing +stage +stages +stainless +stakeholders +stamp +stamps +stan +stand +standard +standards +standing +standings +stands +stanford +stanley +star +starring +stars +starsmerchant +start +started +starter +starting +starts +startup +stat +state +stated +statement +statements +states +statewide +static +stating +station +stationery +stations +statistical +statistics +stats +status +statute +statutes +statutory +stay +stayed +staying +stays +std +ste +steady +steal +steam +steel +steering +stem +step +stephanie +stephen +steps +stereo +sterling +steve +steven +stevens +stewart +stick +sticker +stickers +sticks +sticky +still +stock +stockholm +stockings +stocks +stolen +stomach +stone +stones +stood +stop +stopped +stopping +stops +storage +store +stored +stores +stories +storm +story +str +straight +strain +strand +strange +stranger +strap +strategic +strategies +strategy +stream +streaming +streams +street +streets +strength +strengthen +strengthening +strengths +stress +stretch +strict +strictly +strike +strikes +striking +string +strings +strip +stripes +strips +stroke +strong +stronger +strongly +struck +struct +structural +structure +structured +structures +struggle +stuart +stuck +stud +student +students +studied +studies +studio +studios +study +studying +stuff +stuffed +stunning +stupid +style +styles +stylish +stylus +su +sub +subaru +subcommittee +subdivision +subject +subjects +sublime +sublimedirectory +submission +submissions +submit +submitted +submitting +subscribe +subscriber +subscribers +subscription +subscriptions +subsection +subsequent +subsequently +subsidiaries +subsidiary +substance +substances +substantial +substantially +substitute +subtle +suburban +succeed +success +successful +successfully +such +suck +sucking +sucks +sudan +sudden +suddenly +sue +suffer +suffered +suffering +sufficient +sufficiently +sugar +suggest +suggested +suggesting +suggestion +suggestions +suggests +suicide +suit +suitable +suite +suited +suites +suits +sullivan +sum +summaries +summary +summer +summit +sun +sunday +sunglasses +sunny +sunrise +sunset +sunshine +super +superb +superintendent +superior +supervision +supervisor +supervisors +supplement +supplemental +supplements +supplied +supplier +suppliers +supplies +supply +support +supported +supporters +supporting +supports +suppose +supposed +supreme +sur +sure +surely +surf +surface +surfaces +surfing +surge +surgeon +surgeons +surgery +surgical +surname +surplus +surprise +surprised +surprising +surrey +surround +surrounded +surrounding +surveillance +survey +surveys +survival +survive +survivor +survivors +susan +suse +suspect +suspected +suspended +suspension +sussex +sustainability +sustainable +sustained +suzuki +sv +sw +swap +sweden +swedish +sweet +swift +swim +swimming +swing +swingers +swiss +switch +switched +switches +switching +switzerland +sword +sydney +symantec +symbol +symbols +sympathy +symphony +symposium +symptoms +sync +syndicate +syndication +syndrome +synopsis +syntax +synthesis +synthetic +syracuse +syria +sys +system +systematic +systems +t +ta +tab +table +tables +tablet +tablets +tabs +tackle +tactics +tag +tagged +tags +tahoe +tail +taiwan +take +taken +takes +taking +tale +talent +talented +tales +talk +talked +talking +talks +tall +tamil +tampa +tan +tank +tanks +tanzania +tap +tape +tapes +tar +target +targeted +targets +tariff +task +tasks +taste +tattoo +taught +tax +taxation +taxes +taxi +taylor +tb +tba +tc +tcp +td +te +tea +teach +teacher +teachers +teaches +teaching +team +teams +tear +tears +tech +technical +technician +technique +techniques +techno +technological +technologies +technology +techrepublic +ted +teddy +tee +teen +teenage +teens +teeth +tel +telecharger +telecom +telecommunications +telephone +telephony +telescope +television +televisions +tell +telling +tells +temp +temperature +temperatures +template +templates +temple +temporal +temporarily +temporary +ten +tenant +tend +tender +tennessee +tennis +tension +tent +term +terminal +terminals +termination +terminology +terms +terrace +terrain +terrible +territories +territory +terror +terrorism +terrorist +terrorists +terry +test +testament +tested +testimonials +testimony +testing +tests +tex +texas +text +textbook +textbooks +textile +textiles +texts +texture +tf +tft +tgp +th +thai +thailand +than +thank +thanks +thanksgiving +that +thats +the +theater +theaters +theatre +thee +theft +thehun +their +them +theme +themes +themselves +then +theology +theorem +theoretical +theories +theory +therapeutic +therapist +therapy +there +thereafter +thereby +therefore +thereof +thermal +thesaurus +these +thesis +they +thick +thickness +thin +thing +things +think +thinking +thinkpad +thinks +third +thirty +this +thomas +thompson +thomson +thong +thongs +thorough +thoroughly +those +thou +though +thought +thoughts +thousand +thousands +thread +threaded +threads +threat +threatened +threatening +threats +three +threesome +threshold +thriller +throat +through +throughout +throw +throwing +thrown +throws +thru +thu +thumb +thumbnail +thumbnails +thumbs +thumbzilla +thunder +thursday +thus +thy +ti +ticket +tickets +tide +tie +tied +tier +ties +tiffany +tiger +tigers +tight +til +tile +tiles +till +tim +timber +time +timeline +timely +timer +times +timing +timothy +tin +tiny +tion +tions +tip +tips +tire +tired +tires +tissue +tit +titanium +titans +title +titled +titles +tits +titten +tm +tmp +tn +to +tobacco +tobago +today +todd +toddler +toe +together +toilet +token +tokyo +told +tolerance +toll +tom +tomato +tomatoes +tommy +tomorrow +ton +tone +toner +tones +tongue +tonight +tons +tony +too +took +tool +toolbar +toolbox +toolkit +tools +tooth +top +topic +topics +topless +tops +toronto +torture +toshiba +total +totally +totals +touch +touched +tough +tour +touring +tourism +tourist +tournament +tournaments +tours +toward +towards +tower +towers +town +towns +township +toxic +toy +toyota +toys +tp +tr +trace +track +trackback +trackbacks +tracked +tracker +tracking +tracks +tract +tractor +tracy +trade +trademark +trademarks +trader +trades +trading +tradition +traditional +traditions +traffic +tragedy +trail +trailer +trailers +trails +train +trained +trainer +trainers +training +trains +tramadol +trance +tranny +trans +transaction +transactions +transcript +transcription +transcripts +transexual +transexuales +transfer +transferred +transfers +transform +transformation +transit +transition +translate +translated +translation +translations +translator +transmission +transmit +transmitted +transparency +transparent +transport +transportation +transsexual +trap +trash +trauma +travel +traveler +travelers +traveling +traveller +travelling +travels +travesti +travis +tray +treasure +treasurer +treasures +treasury +treat +treated +treating +treatment +treatments +treaty +tree +trees +trek +trembl +tremendous +trend +trends +treo +tri +trial +trials +triangle +tribal +tribe +tribes +tribunal +tribune +tribute +trick +tricks +tried +tries +trigger +trim +trinidad +trinity +trio +trip +tripadvisor +triple +trips +triumph +trivia +troops +tropical +trouble +troubleshooting +trout +troy +truck +trucks +true +truly +trunk +trust +trusted +trustee +trustees +trusts +truth +try +trying +ts +tsunami +tt +tu +tub +tube +tubes +tucson +tue +tuesday +tuition +tulsa +tumor +tune +tuner +tunes +tuning +tunisia +tunnel +turbo +turkey +turkish +turn +turned +turner +turning +turns +turtle +tutorial +tutorials +tv +tvcom +tvs +twelve +twenty +twice +twiki +twin +twinks +twins +twist +twisted +two +tx +ty +tyler +type +types +typical +typically +typing +u +uc +uganda +ugly +uh +ui +uk +ukraine +ul +ultimate +ultimately +ultra +ultram +um +un +una +unable +unauthorized +unavailable +uncertainty +uncle +und +undefined +under +undergraduate +underground +underlying +understand +understanding +understood +undertake +undertaken +underwear +undo +une +unemployment +unexpected +unfortunately +uni +unified +uniform +union +unions +uniprotkb +unique +unit +united +units +unity +univ +universal +universe +universities +university +unix +unknown +unless +unlike +unlikely +unlimited +unlock +unnecessary +unsigned +unsubscribe +until +untitled +unto +unusual +unwrap +up +upc +upcoming +update +updated +updates +updating +upgrade +upgrades +upgrading +upload +uploaded +upon +upper +ups +upset +upskirt +upskirts +ur +urban +urge +urgent +uri +url +urls +uruguay +urw +us +usa +usage +usb +usc +usd +usda +use +used +useful +user +username +users +uses +usgs +using +usps +usr +usual +usually +ut +utah +utc +utilities +utility +utilization +utilize +utils +uv +uw +uzbekistan +v +va +vacancies +vacation +vacations +vaccine +vacuum +vagina +val +valentine +valid +validation +validity +valium +valley +valuable +valuation +value +valued +values +valve +valves +vampire +van +vancouver +vanilla +var +variable +variables +variance +variation +variations +varied +varies +variety +various +vary +varying +vast +vat +vatican +vault +vb +vbulletin +vc +vcr +ve +vector +vegas +vegetable +vegetables +vegetarian +vegetation +vehicle +vehicles +velocity +velvet +vendor +vendors +venezuela +venice +venture +ventures +venue +venues +ver +verbal +verde +verification +verified +verify +verizon +vermont +vernon +verse +version +versions +versus +vertex +vertical +very +verzeichnis +vessel +vessels +veteran +veterans +veterinary +vg +vhs +vi +via +viagra +vibrator +vibrators +vic +vice +victim +victims +victor +victoria +victorian +victory +vid +video +videos +vids +vienna +vietnam +vietnamese +view +viewed +viewer +viewers +viewing +viewpicture +views +vii +viii +viking +villa +village +villages +villas +vincent +vintage +vinyl +violation +violations +violence +violent +violin +vip +viral +virgin +virginia +virtual +virtually +virtue +virus +viruses +visa +visibility +visible +vision +visit +visited +visiting +visitor +visitors +visits +vista +visual +vital +vitamin +vitamins +vocabulary +vocal +vocals +vocational +voice +voices +void +voip +vol +volkswagen +volleyball +volt +voltage +volume +volumes +voluntary +volunteer +volunteers +volvo +von +vote +voted +voters +votes +voting +voyeur +voyeurweb +voyuer +vp +vpn +vs +vsnet +vt +vulnerability +vulnerable +w +wa +wage +wages +wagner +wagon +wait +waiting +waiver +wake +wal +wales +walk +walked +walker +walking +walks +wall +wallace +wallet +wallpaper +wallpapers +walls +walnut +walt +walter +wan +wang +wanna +want +wanted +wanting +wants +war +warcraft +ward +ware +warehouse +warm +warming +warned +warner +warning +warnings +warrant +warranties +warranty +warren +warrior +warriors +wars +was +wash +washer +washing +washington +waste +watch +watched +watches +watching +water +waterproof +waters +watershed +watson +watt +watts +wav +wave +waves +wax +way +wayne +ways +wb +wc +we +weak +wealth +weapon +weapons +wear +wearing +weather +web +webcam +webcams +webcast +weblog +weblogs +webmaster +webmasters +webpage +webshots +website +websites +webster +wed +wedding +weddings +wednesday +weed +week +weekend +weekends +weekly +weeks +weight +weighted +weights +weird +welcome +welding +welfare +well +wellington +wellness +wells +welsh +wendy +went +were +wesley +west +western +westminster +wet +whale +what +whatever +whats +wheat +wheel +wheels +when +whenever +where +whereas +wherever +whether +which +while +whilst +white +who +whole +wholesale +whom +whore +whose +why +wi +wichita +wicked +wide +widely +wider +widescreen +widespread +width +wife +wifi +wiki +wikipedia +wild +wilderness +wildlife +wiley +will +william +williams +willing +willow +wilson +win +wind +window +windows +winds +windsor +wine +wines +wing +wings +winner +winners +winning +wins +winston +winter +wire +wired +wireless +wires +wiring +wisconsin +wisdom +wise +wish +wishes +wishlist +wit +witch +with +withdrawal +within +without +witness +witnesses +wives +wizard +wm +wma +wn +wolf +woman +women +womens +won +wonder +wonderful +wondering +wood +wooden +woods +wool +worcester +word +wordpress +words +work +worked +worker +workers +workflow +workforce +working +workout +workplace +works +workshop +workshops +workstation +world +worldcat +worlds +worldsex +worldwide +worm +worn +worried +worry +worse +worship +worst +worth +worthy +would +wound +wow +wp +wr +wrap +wrapped +wrapping +wrestling +wright +wrist +write +writer +writers +writes +writing +writings +written +wrong +wrote +ws +wt +wto +wu +wv +ww +www +wx +wy +wyoming +x +xanax +xbox +xerox +xhtml +xi +xl +xml +xnxx +xp +xx +xxx +y +ya +yacht +yahoo +yale +yamaha +yang +yard +yards +yarn +ye +yea +yeah +year +yearly +years +yeast +yellow +yemen +yen +yes +yesterday +yet +yield +yields +yn +yo +yoga +york +yorkshire +you +young +younger +your +yours +yourself +youth +yr +yrs +yu +yugoslavia +yukon +z +za +zambia +zdnet +zealand +zen +zero +zimbabwe +zinc +zip +zoloft +zone +zones +zoning +zoo +zoom +zoophilia +zope +zshops +zu +zum +zus \ No newline at end of file diff --git a/README.md b/README.md index d15f4e8b..b5ac43db 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ More information on contributing and the general code of conduct for discussion | Arrange It | [Arrange It](https://github.com/DhanushNehru/Python-Scripts/tree/master/Arrange%20It) | A Python script that can automatically move files into corresponding folders based on their extensions. | | Auto WiFi Check | [Auto WiFi Check](https://github.com/DhanushNehru/Python-Scripts/tree/master/Auto%20WiFi%20Check) | A Python script to monitor if the WiFi connection is active or not | AutoCert | [AutoCert](https://github.com/DhanushNehru/Python-Scripts/tree/master/AutoCert) | A Python script to auto-generate e-certificates in bulk. | +| Autocomplete Notes App | [AutoCert](https://github.com/DhanushNehru/Python-Scripts/tree/master/Autocomplete%20Notes%20App) | A Python script to auto-generate e-certificates in bulk. | | Automated Emails | [Automated Emails](https://github.com/DhanushNehru/Python-Scripts/tree/master/Automate%20Emails%20Daily) | A Python script to send out personalized emails by reading a CSV file. | | Black Hat Python | [Black Hat Python](https://github.com/DhanushNehru/Python-Scripts/tree/master/Black%20Hat%20Python) | Source code from the book Black Hat Python | | Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. | From db40916edfc02183d83030ba6cd3c9ca4cd23775 Mon Sep 17 00:00:00 2001 From: Maximiliano Date: Mon, 7 Oct 2024 05:46:34 -0600 Subject: [PATCH 027/127] Added Pomodoro Timer (#302) * Added Pomodoro Timer * Update README.md * Update README.md --- Pomodoro Timer/Pomodoro Timer MacOS Linux.py | 24 ++++++++++++++ Pomodoro Timer/Pomodoro Timer Windows.py | 24 ++++++++++++++ Pomodoro Timer/README.md | 33 ++++++++++++++++++++ README.md | 1 + 4 files changed, 82 insertions(+) create mode 100644 Pomodoro Timer/Pomodoro Timer MacOS Linux.py create mode 100644 Pomodoro Timer/Pomodoro Timer Windows.py create mode 100644 Pomodoro Timer/README.md diff --git a/Pomodoro Timer/Pomodoro Timer MacOS Linux.py b/Pomodoro Timer/Pomodoro Timer MacOS Linux.py new file mode 100644 index 00000000..43fca53d --- /dev/null +++ b/Pomodoro Timer/Pomodoro Timer MacOS Linux.py @@ -0,0 +1,24 @@ +# Pomodoro Timer for macOS/Linux +import time +import os + +def pomodoro_timer_unix(work_duration=25, break_duration=5, cycles=4): + for cycle in range(cycles): + print(f"Cycle {cycle + 1}/{cycles}: Start working for {work_duration} minutes.") + time.sleep(work_duration * 60) + os.system('echo -e "\a"') # Make a beep sound on macOS/Linux + print("Time's up! Take a break.") + + print(f"Break time! Relax for {break_duration} minutes.") + time.sleep(break_duration * 60) + os.system('echo -e "\a"') # Make a beep sound on macOS/Linux + print("Break is over! Back to work.") + + print("All cycles completed! Great job!") + +if __name__ == "__main__": + work_duration = int(input("Enter work duration in minutes (default is 25): ") or 25) + break_duration = int(input("Enter break duration in minutes (default is 5): ") or 5) + cycles = int(input("Enter number of cycles (default is 4): ") or 4) + + pomodoro_timer_unix(work_duration, break_duration, cycles) diff --git a/Pomodoro Timer/Pomodoro Timer Windows.py b/Pomodoro Timer/Pomodoro Timer Windows.py new file mode 100644 index 00000000..8687c954 --- /dev/null +++ b/Pomodoro Timer/Pomodoro Timer Windows.py @@ -0,0 +1,24 @@ +# Pomodoro Timer for Windows +import time +import winsound + +def pomodoro_timer_windows(work_duration=25, break_duration=5, cycles=4): + for cycle in range(cycles): + print(f"Cycle {cycle + 1}/{cycles}: Start working for {work_duration} minutes.") + time.sleep(work_duration * 60) + winsound.Beep(1000, 1000) # Sound an alert to indicate work period end + print("Time's up! Take a break.") + + print(f"Break time! Relax for {break_duration} minutes.") + time.sleep(break_duration * 60) + winsound.Beep(1000, 1000) # Sound an alert to indicate break period end + print("Break is over! Back to work.") + + print("All cycles completed! Great job!") + +if __name__ == "__main__": + work_duration = int(input("Enter work duration in minutes (default is 25): ") or 25) + break_duration = int(input("Enter break duration in minutes (default is 5): ") or 5) + cycles = int(input("Enter number of cycles (default is 4): ") or 4) + + pomodoro_timer_windows(work_duration, break_duration, cycles) diff --git a/Pomodoro Timer/README.md b/Pomodoro Timer/README.md new file mode 100644 index 00000000..b1620918 --- /dev/null +++ b/Pomodoro Timer/README.md @@ -0,0 +1,33 @@ +# Pomodoro Timer +## 📋 Overview +The Pomodoro Timer is a productivity tool designed to help you manage your time efficiently using the Pomodoro Technique. It splits your work into intervals—typically 25 minutes of focused work followed by a 5-minute break. This cycle helps to boost focus and prevent burnout by encouraging regular breaks. The script is cross-platform, supporting both Windows and macOS/Linux. + +## ✨ Features +- **Customizable Work and Break Durations:** Set your preferred time for work and break sessions. +- **Support for Multiple Cycles:** Run multiple Pomodoro sessions in a row. +- **Platform-Specific Alerts:** +- **Windows:** Uses sound alerts (winsound) to notify users when a session is complete. +- **macOS/Linux:** Uses terminal beep commands for notifications. + +## Running the script +1. **Clone the Repository or Download the Script:** +- clone the repository: +``` +git clone https://github.com/max-lopzzz/Python-Scripts/tree/master/Pomodoro%20Timer +``` +- Or download the script directly from the repository page. +2. **Navigate to the Script Location:** Open your terminal (Command Prompt on Windows, Terminal on macOS/Linux) and navigate to the folder containing the script: +``` +cd path/to/your/script +``` +3. **Run the Script:** Execute the script using Python: +``` +python pomodoro_timer.py +``` +or, if `python` points to Python 2.x on your system: +``` +python3 pomodoro_timer.py +``` +### Customizing Durations +- Once the script runs, it may prompt you to enter custom durations for both work and break intervals. +- Simply follow the prompts to customize your session lengths. diff --git a/README.md b/README.md index b5ac43db..97710f02 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ More information on contributing and the general code of conduct for discussion | Playlist Exchange | [Playlist Exchange](https://github.com/DhanushNehru/Python-Scripts/tree/master/Playlist%20Exchange) | A Python script to exchange songs and playlists between Spotify and Python. | Pigeonhole Sort | [Algorithm](https://github.com/DhanushNehru/Python-Scripts/tree/master/PigeonHole) | The pigeonhole sort algorithm to sort your arrays efficiently! | PNG TO JPG CONVERTOR | [PNG-To-JPG](https://github.com/DhanushNehru/Python-Scripts/tree/master/PNG%20To%20JPG) | A PNG TO JPG IMAGE CONVERTOR. +| Pomodoro Timer | [Pomodoro Timer](https://github.com/DhanushNehru/Python-Scripts/tree/master/Pomodoro%20Timer) | A Pomodoro timer | Python GUI Notepad | [Python GUI Notepad](https://github.com/DhanushNehru/Python-Scripts/blob/master/PDF%20Merger%20and%20Splitter/PDF%20Merger%20and%20Splitter.py) | A Python-based GUI Notepad with essential features like saving, opening, editing text files, basic formatting, and a simple user interface for quick note-taking. | QR Code Generator | [QR Code Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20Code%20Generator) | This is generate a QR code from the provided link | | QR Code with logo | [QR code with Logo](https://github.com/DhanushNehru/Python-Scripts/tree/master/QR%20with%20Logo) | QR Code Customization Feature From c77b6ac9bb8565b7f676f8399014db66ab1959d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Tue, 8 Oct 2024 19:37:15 +0530 Subject: [PATCH 028/127] Added a feature and READme.md guide --- Automate Emails Daily/README.md | 151 ++++++++++++++++++++++++++++++++ Automate Emails Daily/main.py | 50 ++++++++--- 2 files changed, 191 insertions(+), 10 deletions(-) create mode 100644 Automate Emails Daily/README.md diff --git a/Automate Emails Daily/README.md b/Automate Emails Daily/README.md new file mode 100644 index 00000000..b4b02f72 --- /dev/null +++ b/Automate Emails Daily/README.md @@ -0,0 +1,151 @@ +# Guidebook: Email Automation Script with Advanced Features + +# Overview + +This Python script automates the process of sending emails to multiple recipients with enhanced features such as support for attachments and HTML-formatted emails. The script uses Python's built-in libraries (smtplib, ssl, and email) to send emails securely through Gmail's SMTP server. It also allows the user to customize the email's content, subject, recipients, and more via environment variables or in-script configuration. + +# Features Added + +1. Support for Attachments: You can now attach files to the email, making it more versatile for different use cases like sending reports, documents, or images. +2. HTML Email Support: You can send emails in HTML format, giving you more flexibility with rich text formatting, embedded links, and other styling options. + +# Prerequisites + +1. Python 3.x +2. A Gmail account (with less secure apps access enabled or an app-specific password if using 2FA) +3. Required libraries: smtplib, ssl, os, email (all built-in Python libraries) + +# Environment Setup +To ensure security, it's recommended to store sensitive information like email credentials in environment variables. For this guide, we will store the Gmail password as an environment variable: + +export EMAIL_PASSWORD='your_gmail_password' + +# Code Breakdown +1. Import Required Modules + +import smtplib +import ssl +import os +from email.message import EmailMessage +from email.utils import formataddr +------------------------------------------------------------------------------------- +smtplib: Used to create the connection to the Gmail SMTP server. +ssl: Provides a layer of security for the email communication. +os: Used to access environment variables (like the email password). +email.message: Allows crafting email messages, including text, HTML, and attachments. + +**send_email Function** + +This is the main function that sends the email. + +Function Parameters: +sender_email (str): The email address sending the email. +sender_name (str): The sender's name that will appear in the email. +password (str): The sender's email password, pulled from environment variables. +receiver_emails (list): A list of email addresses to send the email to. +email_body (str): The body of the email, which can be in plain text or HTML. +email_subject (str): The subject line of the email. Default is "No subject." + +**Example Function** + +send_email( + sender_email="youremail@gmail.com", + sender_name="Your Name", + password=os.environ.get("EMAIL_PASSWORD"), + receiver_emails=["recipient1@gmail.com", "recipient2@gmail.com"], + email_body="Hello, this is a test email!", + email_subject="Test Email" +) + +------------------------------------------------------------------------------------- + +**Setting Up Email Headers** +The email headers include the subject, sender, recipient, and format: + +msg["Subject"] = email_subject +msg["From"] = formataddr((f"{sender_name}", f"{sender_email}")) +msg["BCC"] = sender_email +msg.set_content(email_body) # This can also be an HTML body + +------------------------------------------------------------------------------------- + +**SMTP Server Connection** +Here we establish a connection to Gmail's SMTP server and use TLS (Transport Layer Security) to ensure a secure connection. + +smtp_port = 587 +smtp_server = "smtp.gmail.com" +ssl_context = ssl.create_default_context() + +------------------------------------------------------------------------------------- + +**Login and Sending the Email** +After logging in, the script loops through each recipient in the receiver_emails list and sends the email. + +my_server = smtplib.SMTP(smtp_server, smtp_port) +my_server.starttls(context=ssl_context) +my_server.login(sender_email, password) + +------------------------------------------------------------------------------------- + +**Adding Attachments** +If you want to send attachments, use the following modification: + +if attachments: + for file in attachments: + with open(file, "rb") as f: + file_data = f.read() + file_name = os.path.basename(file) + msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name) + +------------------------------------------------------------------------------------- + +**Sending HTML Emails** +To send HTML emails, modify the email body to contain HTML: + +msg.add_alternative("""\ + + +

Hello,
+ This is an HTML email!

+ + + """, subtype='html') + + ------------------------------------------------------------------------------------- + +**Error Handling** +The script includes basic error handling to notify you if the connection or email-sending process fails: + +except Exception as e: + print(f"ERROR: {e}") + +-------------------------------------------------------------------------------------- + +**Full Example with Attachment and HTML Support** + +send_email( + sender_email="youremail@gmail.com", + sender_name="Your Name", + password=os.environ.get("EMAIL_PASSWORD"), + receiver_emails=["recipient1@gmail.com", "recipient2@gmail.com"], + email_body="

This is a Test Email with HTML

", + email_subject="Test Email with HTML and Attachment", + attachments=["path/to/attachment1", "path/to/attachment2"] +) + + +-------------------------------------------------------------------------------------- + +# How to run the script + +Ensure the required environment variable (EMAIL_PASSWORD) is set. +Customize the sender email, receiver emails, email body, and subject in the script. +Run the script from the command line: + +python email_automation.py or main.py + +You can also schedule the script to run daily using cron jobs or Task Scheduler (Windows). + + +# Thank You for reading this tutorial. I hope you found it helpful. If you have any questions or need further + diff --git a/Automate Emails Daily/main.py b/Automate Emails Daily/main.py index 38698858..490e48ee 100644 --- a/Automate Emails Daily/main.py +++ b/Automate Emails Daily/main.py @@ -3,20 +3,46 @@ import os from email.message import EmailMessage from email.utils import formataddr +from mimetypes import guess_type def send_email(sender_email: str, sender_name: str, password:str, - receiver_emails: str , + receiver_emails: list, email_body: str, - email_subject: str="No subject",)-> None: + email_subject: str = "No subject", + is_html: bool = False, + attachments: list = None) -> None: msg = EmailMessage() msg["Subject"] = email_subject msg["From"] = formataddr((f"{sender_name}", f"{sender_email}")) - msg["BCC"] = sender_email - msg.set_content(email_body) + msg["BCC"] = sender_email # Can add CC or BCC here if needed + # Support both plain text and HTML emails + if is_html: + msg.add_alternative(email_body, subtype='html') + else: + msg.set_content(email_body) + + # Add attachments if provided + if attachments: + for file_path in attachments: + try: + with open(file_path, 'rb') as file: + file_data = file.read() + file_name = os.path.basename(file_path) + mime_type, _ = guess_type(file_path) + if mime_type: + mime_main, mime_subtype = mime_type.split('/') + else: + mime_main, mime_subtype = 'application', 'octet-stream' + + msg.add_attachment(file_data, maintype=mime_main, subtype=mime_subtype, filename=file_name) + print(f"Attached file: {file_name}") + except Exception as e: + print(f"Failed to attach {file_path}: {e}") + smtp_port = 587 smtp_server = "smtp.gmail.com" @@ -48,14 +74,18 @@ def send_email(sender_email: str, finally: my_server.quit() -# change these variables to suite your requirements +# Example usage sender_email = "your-email@gmail.com" sender_name = "your name" password = os.environ.get("EMAIL_PASSWORD") -email_subject = "good morning" -email_body = "good morning, hope you have a wonderful day" - -receiver_emails = ["receiver1-email@gmail.com", "receiver2-email@gmail.com", "receiver3-email@gmail.com"] +email_subject = "Good morning" +email_body = """ +

Good Morning!

+

Hope you have a wonderful day.

+""" +receiver_emails = ["receiver1-email@gmail.com", "receiver2-email@gmail.com"] +attachments = ["path/to/attachment1.pdf", "path/to/attachment2.jpg"] -send_email(sender_email, sender_name, password, receiver_emails, email_body,email_subject) \ No newline at end of file +# Sending the email as HTML with attachments +send_email(sender_email, sender_name, password, receiver_emails, email_body, email_subject, is_html=True, attachments=attachments) From 5483f87a23a6d9bd8e39fad6e306a74ac8e61921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Thu, 10 Oct 2024 00:56:06 +0530 Subject: [PATCH 029/127] feat: Add CSV delimiter selection and cell styling to CSV to Excel script --- CSV to Excel/csv_excel.py | 81 +++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/CSV to Excel/csv_excel.py b/CSV to Excel/csv_excel.py index 19fa8e11..4fca88ed 100644 --- a/CSV to Excel/csv_excel.py +++ b/CSV to Excel/csv_excel.py @@ -1,37 +1,62 @@ import openpyxl import os +from openpyxl.styles import Font, PatternFill # Get the CSV and Excel file names from the user -csv_name = input("Name of the input CSV file with extension: ") -sep = input("Separator of the CSV file: ") -excel_name = input("Name of the output excel file with extension: ") -sheet_name = input("Name of the output excel sheet: ") +csv_files = input("Enter the CSV files separated by commas (e.g., file1.csv, file2.csv): ").split(',') +sep = input("Separator of the CSV files (default is ','): ") or ',' # Default to comma separator if not provided +excel_name = input("Name of the output Excel file with extension: ") -# Load the CSV file +# Load or create Excel workbook if os.path.exists(excel_name): workbook = openpyxl.load_workbook(excel_name) - sheet = workbook[sheet_name] if sheet_name in workbook.sheetnames else workbook.create_sheet(sheet_name) else: workbook = openpyxl.Workbook() - sheet = workbook.active - sheet.title = sheet_name - -# Write the CSV data to the Excel sheet -try: - with open(csv_name, "r", encoding="utf-8") as file: - excel_row = 1 - for line in file: - data = line.strip().split(sep) - excel_column = 1 - for value in data: - sheet.cell(row=excel_row, column=excel_column, value=value) - excel_column += 1 - excel_row += 1 - - # Save the Excel file - workbook.save(excel_name) - -except FileNotFoundError: - print("Error: The CSV file was not found.") -except Exception as e: - print(f"An error occurred: {e}") \ No newline at end of file + +# Loop over multiple CSV files to write them into different sheets +for csv_name in csv_files: + csv_name = csv_name.strip() # Trim any whitespace + sheet_name = os.path.splitext(os.path.basename(csv_name))[0] # Sheet name based on the CSV filename + + # Create a new sheet for each CSV file + if sheet_name in workbook.sheetnames: + sheet = workbook[sheet_name] + else: + sheet = workbook.create_sheet(sheet_name) + + # Write CSV data to the Excel sheet + try: + with open(csv_name, "r", encoding="utf-8") as file: + excel_row = 1 + header_detected = False # Flag to check if header formatting should be applied + + for line in file: + data = line.strip().split(sep) + excel_column = 1 + + # Apply header formatting for the first row (headers) + if not header_detected: + for value in data: + cell = sheet.cell(row=excel_row, column=excel_column, value=value) + # Apply bold font and background color for the header row + cell.font = Font(bold=True) + cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") + excel_column += 1 + header_detected = True # Mark the first row as header + else: + for value in data: + sheet.cell(row=excel_row, column=excel_column, value=value) + excel_column += 1 + + excel_row += 1 + + except FileNotFoundError: + print(f"Error: The CSV file '{csv_name}' was not found.") + except Exception as e: + print(f"An error occurred while processing {csv_name}: {e}") + +# Save the Excel file with all sheets +workbook.save(excel_name) + +print(f"All CSV files have been processed and saved to {excel_name}.") + From af1e7290220a6e39aaefb88d38c10b576e5c0504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Thu, 10 Oct 2024 00:59:59 +0530 Subject: [PATCH 030/127] Explaination od Modifications --- CSV to Excel/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 CSV to Excel/README.md diff --git a/CSV to Excel/README.md b/CSV to Excel/README.md new file mode 100644 index 00000000..8774d1c9 --- /dev/null +++ b/CSV to Excel/README.md @@ -0,0 +1,23 @@ +# Explanation of Modifications + +**Support for Multiple CSV Files:** + +Modification: We now accept multiple CSV files, split by commas, in the csv_files list. + +Sheet Name: For each CSV file, a new sheet is created, named after the CSV file (without the extension). + +Loop: We loop over each CSV file in csv_files and process it individually. + +**Automatic CSV Header Detection and Formatting:** + +Modification: The first row of each CSV file is detected as the header. + +Formatting: The header row is formatted with bold text (Font(bold=True)) and a yellow background (PatternFill). + +Flag: A header_detected flag ensures that formatting is only applied to the first row + +**Handling Empty or Invalid Files:** + +Error handling remains in place for file not found and general exceptions. + +#Thank You \ No newline at end of file From 928efee938b621f1510c2f1a73ad8314af7f8d63 Mon Sep 17 00:00:00 2001 From: "A.S Chaudhary" Date: Thu, 10 Oct 2024 10:53:08 +0530 Subject: [PATCH 031/127] Enhancement: Added Support for Attachments and HTML Emails to Automate Email Script (#310) * Added a feature and READme.md guide * feat: Add CSV delimiter selection and cell styling to CSV to Excel script * Explaination od Modifications --- Automate Emails Daily/README.md | 151 ++++++++++++++++++++++++++++++++ Automate Emails Daily/main.py | 50 ++++++++--- CSV to Excel/README.md | 23 +++++ CSV to Excel/csv_excel.py | 81 +++++++++++------ 4 files changed, 267 insertions(+), 38 deletions(-) create mode 100644 Automate Emails Daily/README.md create mode 100644 CSV to Excel/README.md diff --git a/Automate Emails Daily/README.md b/Automate Emails Daily/README.md new file mode 100644 index 00000000..b4b02f72 --- /dev/null +++ b/Automate Emails Daily/README.md @@ -0,0 +1,151 @@ +# Guidebook: Email Automation Script with Advanced Features + +# Overview + +This Python script automates the process of sending emails to multiple recipients with enhanced features such as support for attachments and HTML-formatted emails. The script uses Python's built-in libraries (smtplib, ssl, and email) to send emails securely through Gmail's SMTP server. It also allows the user to customize the email's content, subject, recipients, and more via environment variables or in-script configuration. + +# Features Added + +1. Support for Attachments: You can now attach files to the email, making it more versatile for different use cases like sending reports, documents, or images. +2. HTML Email Support: You can send emails in HTML format, giving you more flexibility with rich text formatting, embedded links, and other styling options. + +# Prerequisites + +1. Python 3.x +2. A Gmail account (with less secure apps access enabled or an app-specific password if using 2FA) +3. Required libraries: smtplib, ssl, os, email (all built-in Python libraries) + +# Environment Setup +To ensure security, it's recommended to store sensitive information like email credentials in environment variables. For this guide, we will store the Gmail password as an environment variable: + +export EMAIL_PASSWORD='your_gmail_password' + +# Code Breakdown +1. Import Required Modules + +import smtplib +import ssl +import os +from email.message import EmailMessage +from email.utils import formataddr +------------------------------------------------------------------------------------- +smtplib: Used to create the connection to the Gmail SMTP server. +ssl: Provides a layer of security for the email communication. +os: Used to access environment variables (like the email password). +email.message: Allows crafting email messages, including text, HTML, and attachments. + +**send_email Function** + +This is the main function that sends the email. + +Function Parameters: +sender_email (str): The email address sending the email. +sender_name (str): The sender's name that will appear in the email. +password (str): The sender's email password, pulled from environment variables. +receiver_emails (list): A list of email addresses to send the email to. +email_body (str): The body of the email, which can be in plain text or HTML. +email_subject (str): The subject line of the email. Default is "No subject." + +**Example Function** + +send_email( + sender_email="youremail@gmail.com", + sender_name="Your Name", + password=os.environ.get("EMAIL_PASSWORD"), + receiver_emails=["recipient1@gmail.com", "recipient2@gmail.com"], + email_body="Hello, this is a test email!", + email_subject="Test Email" +) + +------------------------------------------------------------------------------------- + +**Setting Up Email Headers** +The email headers include the subject, sender, recipient, and format: + +msg["Subject"] = email_subject +msg["From"] = formataddr((f"{sender_name}", f"{sender_email}")) +msg["BCC"] = sender_email +msg.set_content(email_body) # This can also be an HTML body + +------------------------------------------------------------------------------------- + +**SMTP Server Connection** +Here we establish a connection to Gmail's SMTP server and use TLS (Transport Layer Security) to ensure a secure connection. + +smtp_port = 587 +smtp_server = "smtp.gmail.com" +ssl_context = ssl.create_default_context() + +------------------------------------------------------------------------------------- + +**Login and Sending the Email** +After logging in, the script loops through each recipient in the receiver_emails list and sends the email. + +my_server = smtplib.SMTP(smtp_server, smtp_port) +my_server.starttls(context=ssl_context) +my_server.login(sender_email, password) + +------------------------------------------------------------------------------------- + +**Adding Attachments** +If you want to send attachments, use the following modification: + +if attachments: + for file in attachments: + with open(file, "rb") as f: + file_data = f.read() + file_name = os.path.basename(file) + msg.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name) + +------------------------------------------------------------------------------------- + +**Sending HTML Emails** +To send HTML emails, modify the email body to contain HTML: + +msg.add_alternative("""\ + + +

Hello,
+ This is an HTML email!

+ + + """, subtype='html') + + ------------------------------------------------------------------------------------- + +**Error Handling** +The script includes basic error handling to notify you if the connection or email-sending process fails: + +except Exception as e: + print(f"ERROR: {e}") + +-------------------------------------------------------------------------------------- + +**Full Example with Attachment and HTML Support** + +send_email( + sender_email="youremail@gmail.com", + sender_name="Your Name", + password=os.environ.get("EMAIL_PASSWORD"), + receiver_emails=["recipient1@gmail.com", "recipient2@gmail.com"], + email_body="

This is a Test Email with HTML

", + email_subject="Test Email with HTML and Attachment", + attachments=["path/to/attachment1", "path/to/attachment2"] +) + + +-------------------------------------------------------------------------------------- + +# How to run the script + +Ensure the required environment variable (EMAIL_PASSWORD) is set. +Customize the sender email, receiver emails, email body, and subject in the script. +Run the script from the command line: + +python email_automation.py or main.py + +You can also schedule the script to run daily using cron jobs or Task Scheduler (Windows). + + +# Thank You for reading this tutorial. I hope you found it helpful. If you have any questions or need further + diff --git a/Automate Emails Daily/main.py b/Automate Emails Daily/main.py index 38698858..490e48ee 100644 --- a/Automate Emails Daily/main.py +++ b/Automate Emails Daily/main.py @@ -3,20 +3,46 @@ import os from email.message import EmailMessage from email.utils import formataddr +from mimetypes import guess_type def send_email(sender_email: str, sender_name: str, password:str, - receiver_emails: str , + receiver_emails: list, email_body: str, - email_subject: str="No subject",)-> None: + email_subject: str = "No subject", + is_html: bool = False, + attachments: list = None) -> None: msg = EmailMessage() msg["Subject"] = email_subject msg["From"] = formataddr((f"{sender_name}", f"{sender_email}")) - msg["BCC"] = sender_email - msg.set_content(email_body) + msg["BCC"] = sender_email # Can add CC or BCC here if needed + # Support both plain text and HTML emails + if is_html: + msg.add_alternative(email_body, subtype='html') + else: + msg.set_content(email_body) + + # Add attachments if provided + if attachments: + for file_path in attachments: + try: + with open(file_path, 'rb') as file: + file_data = file.read() + file_name = os.path.basename(file_path) + mime_type, _ = guess_type(file_path) + if mime_type: + mime_main, mime_subtype = mime_type.split('/') + else: + mime_main, mime_subtype = 'application', 'octet-stream' + + msg.add_attachment(file_data, maintype=mime_main, subtype=mime_subtype, filename=file_name) + print(f"Attached file: {file_name}") + except Exception as e: + print(f"Failed to attach {file_path}: {e}") + smtp_port = 587 smtp_server = "smtp.gmail.com" @@ -48,14 +74,18 @@ def send_email(sender_email: str, finally: my_server.quit() -# change these variables to suite your requirements +# Example usage sender_email = "your-email@gmail.com" sender_name = "your name" password = os.environ.get("EMAIL_PASSWORD") -email_subject = "good morning" -email_body = "good morning, hope you have a wonderful day" - -receiver_emails = ["receiver1-email@gmail.com", "receiver2-email@gmail.com", "receiver3-email@gmail.com"] +email_subject = "Good morning" +email_body = """ +

Good Morning!

+

Hope you have a wonderful day.

+""" +receiver_emails = ["receiver1-email@gmail.com", "receiver2-email@gmail.com"] +attachments = ["path/to/attachment1.pdf", "path/to/attachment2.jpg"] -send_email(sender_email, sender_name, password, receiver_emails, email_body,email_subject) \ No newline at end of file +# Sending the email as HTML with attachments +send_email(sender_email, sender_name, password, receiver_emails, email_body, email_subject, is_html=True, attachments=attachments) diff --git a/CSV to Excel/README.md b/CSV to Excel/README.md new file mode 100644 index 00000000..8774d1c9 --- /dev/null +++ b/CSV to Excel/README.md @@ -0,0 +1,23 @@ +# Explanation of Modifications + +**Support for Multiple CSV Files:** + +Modification: We now accept multiple CSV files, split by commas, in the csv_files list. + +Sheet Name: For each CSV file, a new sheet is created, named after the CSV file (without the extension). + +Loop: We loop over each CSV file in csv_files and process it individually. + +**Automatic CSV Header Detection and Formatting:** + +Modification: The first row of each CSV file is detected as the header. + +Formatting: The header row is formatted with bold text (Font(bold=True)) and a yellow background (PatternFill). + +Flag: A header_detected flag ensures that formatting is only applied to the first row + +**Handling Empty or Invalid Files:** + +Error handling remains in place for file not found and general exceptions. + +#Thank You \ No newline at end of file diff --git a/CSV to Excel/csv_excel.py b/CSV to Excel/csv_excel.py index 19fa8e11..4fca88ed 100644 --- a/CSV to Excel/csv_excel.py +++ b/CSV to Excel/csv_excel.py @@ -1,37 +1,62 @@ import openpyxl import os +from openpyxl.styles import Font, PatternFill # Get the CSV and Excel file names from the user -csv_name = input("Name of the input CSV file with extension: ") -sep = input("Separator of the CSV file: ") -excel_name = input("Name of the output excel file with extension: ") -sheet_name = input("Name of the output excel sheet: ") +csv_files = input("Enter the CSV files separated by commas (e.g., file1.csv, file2.csv): ").split(',') +sep = input("Separator of the CSV files (default is ','): ") or ',' # Default to comma separator if not provided +excel_name = input("Name of the output Excel file with extension: ") -# Load the CSV file +# Load or create Excel workbook if os.path.exists(excel_name): workbook = openpyxl.load_workbook(excel_name) - sheet = workbook[sheet_name] if sheet_name in workbook.sheetnames else workbook.create_sheet(sheet_name) else: workbook = openpyxl.Workbook() - sheet = workbook.active - sheet.title = sheet_name - -# Write the CSV data to the Excel sheet -try: - with open(csv_name, "r", encoding="utf-8") as file: - excel_row = 1 - for line in file: - data = line.strip().split(sep) - excel_column = 1 - for value in data: - sheet.cell(row=excel_row, column=excel_column, value=value) - excel_column += 1 - excel_row += 1 - - # Save the Excel file - workbook.save(excel_name) - -except FileNotFoundError: - print("Error: The CSV file was not found.") -except Exception as e: - print(f"An error occurred: {e}") \ No newline at end of file + +# Loop over multiple CSV files to write them into different sheets +for csv_name in csv_files: + csv_name = csv_name.strip() # Trim any whitespace + sheet_name = os.path.splitext(os.path.basename(csv_name))[0] # Sheet name based on the CSV filename + + # Create a new sheet for each CSV file + if sheet_name in workbook.sheetnames: + sheet = workbook[sheet_name] + else: + sheet = workbook.create_sheet(sheet_name) + + # Write CSV data to the Excel sheet + try: + with open(csv_name, "r", encoding="utf-8") as file: + excel_row = 1 + header_detected = False # Flag to check if header formatting should be applied + + for line in file: + data = line.strip().split(sep) + excel_column = 1 + + # Apply header formatting for the first row (headers) + if not header_detected: + for value in data: + cell = sheet.cell(row=excel_row, column=excel_column, value=value) + # Apply bold font and background color for the header row + cell.font = Font(bold=True) + cell.fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") + excel_column += 1 + header_detected = True # Mark the first row as header + else: + for value in data: + sheet.cell(row=excel_row, column=excel_column, value=value) + excel_column += 1 + + excel_row += 1 + + except FileNotFoundError: + print(f"Error: The CSV file '{csv_name}' was not found.") + except Exception as e: + print(f"An error occurred while processing {csv_name}: {e}") + +# Save the Excel file with all sheets +workbook.save(excel_name) + +print(f"All CSV files have been processed and saved to {excel_name}.") + From 2e95942a69fd4b437c5aa8fdea7c53605e9328d4 Mon Sep 17 00:00:00 2001 From: Brahmajit Mohapatra <57172489+BrahmajitMohapatra@users.noreply.github.com> Date: Thu, 10 Oct 2024 21:41:29 +0530 Subject: [PATCH 032/127] Update currency_calculator.py (#318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Key Points: • Input Handling: The program takes the base currency and the currency to exchange into from the user. If the input is blank, the loop exits. • Cache: The program uses a cache to store exchange rates for USD and EUR. If the rate is already in the cache, it retrieves it; otherwise, it fetches the rate from the API. • Exchange Rate API: The rates are fetched from floatrates.com in JSON format. • Currency Conversion: The amount is exchanged based on the cached or newly fetched rate, and the result is displayed. --- Currency Script/currency_calculator.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/Currency Script/currency_calculator.py b/Currency Script/currency_calculator.py index 05f294fb..e0ae9585 100644 --- a/Currency Script/currency_calculator.py +++ b/Currency Script/currency_calculator.py @@ -1,37 +1,55 @@ +# Importing necessary modules for currency formatting and HTTP requests from locale import currency import requests import json -currency = input().lower() +# Get the base currency input from the user and convert it to lowercase +currency = input("Enter the base currency (e.g., USD, EUR): ").lower() + +# Initialize an empty cache to store exchange rates cache = {} +# Infinite loop to process exchange requests until the user exits while True: - currency_exch = input().lower() + # Get the target currency input from the user and convert it to lowercase + currency_exch = input("Enter the currency to exchange to (leave blank to exit): ").lower() + # If the input is blank, break out of the loop (exit condition) if currency_exch == '': break - amount_to_exch = int(input()) + # Get the amount to exchange from the user + amount_to_exch = int(input("Enter the amount to exchange: ")) + # URL for getting exchange rates from floatrates.com URL = f'http://www.floatrates.com/daily/{currency}.json' + # Fetch the exchange rates in JSON format exch = json.loads(requests.get(URL).text) + # Update cache for USD and EUR based on the base currency if currency == 'usd': + # If base currency is USD, cache EUR rate cache.update(eur=exch['eur']['rate']) elif currency == 'eur': + # If base currency is EUR, cache USD rate cache.update(usd=exch['usd']['rate']) else: + # For other base currencies, cache both USD and EUR rates cache.update(usd=exch['usd']['rate'], eur=exch['eur']['rate']) print("Checking the cache...") + + # Check if the target currency's rate is in the cache if currency_exch in cache: + # If the rate is in the cache, calculate the exchanged amount rate = round(amount_to_exch * cache[currency_exch], 2) print("Oh! It is in the cache!") print(f"You received {rate} {currency_exch.upper()}.") else: - #print("Sorry, but it is not in the cache!") + # If the rate is not in the cache, fetch it from the exchange rates and store it in cache + print("Sorry, but it is not in the cache!") cache[currency_exch] = exch[currency_exch]['rate'] rate = round(amount_to_exch * cache[currency_exch], 2) print(f"You received {rate} {currency_exch.upper()}.") From 101639908efc290c6b17520e3f26d297476c88d6 Mon Sep 17 00:00:00 2001 From: "A.S Chaudhary" Date: Thu, 10 Oct 2024 21:42:52 +0530 Subject: [PATCH 033/127] feat: Add CSV delimiter selection and cell styling to CSV to Excel script (#312) * Added a feature and READme.md guide * feat: Add CSV delimiter selection and cell styling to CSV to Excel script * Explaination od Modifications From 35f07713a4abedcf727d6db75b188e900b796476 Mon Sep 17 00:00:00 2001 From: Papireddy E <97383201+papireddy903@users.noreply.github.com> Date: Fri, 11 Oct 2024 12:15:35 +0530 Subject: [PATCH 034/127] Screenshot to Text (#320) --- Screenshot to Text/README.md | 30 +++++++++++++++ Screenshot to Text/main.py | 74 ++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 Screenshot to Text/README.md create mode 100644 Screenshot to Text/main.py diff --git a/Screenshot to Text/README.md b/Screenshot to Text/README.md new file mode 100644 index 00000000..692b8f64 --- /dev/null +++ b/Screenshot to Text/README.md @@ -0,0 +1,30 @@ +# OCR Text Extractor + +## Overview +**OCR Text Extractor** is a Python application that allows users to extract text from images using Optical Character Recognition (OCR) via the Tesseract engine. The application provides a simple and user-friendly graphical interface for uploading images, capturing full-screen screenshots, or pasting images from the clipboard to extract text. + +## Features +- **Select Image File**: Choose an image from your computer to extract text from. Supported formats include `.png`, `.jpg`, `.jpeg`, and `.bmp`. +- **Paste Image from Clipboard**: Take a partial screenshot (e.g., using Windows + Shift + S) and extract text from the image saved in the clipboard. +- **Capture Full Screen Screenshot**: Capture a screenshot of your entire screen and extract text from it. + +## Requirements +To run this application, you need to have the following installed: + +- Python 3.x +- The following Python packages: + - `pytesseract` (Download Tesseract OCR from https://github.com/UB-Mannheim/tesseract/wiki and Add to Environment Path) + - `Pillow` (Python Imaging Library, a fork of PIL) + - `Tkinter` (comes pre-installed with Python on most systems) + +### Installation of Required Packages +You can install the required packages using pip: + +```bash +pip install pytesseract Pillow +``` + +### How to Run +```bash +python main.py +``` diff --git a/Screenshot to Text/main.py b/Screenshot to Text/main.py new file mode 100644 index 00000000..450e24b3 --- /dev/null +++ b/Screenshot to Text/main.py @@ -0,0 +1,74 @@ +import pytesseract +from PIL import Image, ImageGrab +import tkinter as tk +from tkinter import filedialog, messagebox, Text, Scrollbar + +def extract_text_from_image(img): #Extracts Text from Image using Pytesseract + try: + text = pytesseract.image_to_string(img) + return text + except Exception as e: + print(e) + return None + +def select_image_file(): # Upload a Image file + img_path = filedialog.askopenfilename(title="Select Screenshot", filetypes=[("Image Files", "*.png *.jpg *.jpeg *.bmp")]) + if img_path: + img = Image.open(img_path) + display_extracted_text(img) + +def paste_image_from_clipboard(): # Take partial screenshot (Windows + shift + S) it will be saved in clipboard. + try: + img = ImageGrab.grabclipboard() + if isinstance(img, Image.Image): + display_extracted_text(img) + else: + messagebox.showwarning("Error", "No image found in the clipboard.") + except Exception as e: + messagebox.showerror("Error", f"Error accessing clipboard: {e}") + +def capture_screenshot(): # Takes entire screen screenshot + try: + img = ImageGrab.grab() + display_extracted_text(img) + except Exception as e: + messagebox.showerror("Error", f"Error capturing screenshot: {e}") + +def display_extracted_text(img): # Displaying extracted text from pytesseract + text = extract_text_from_image(img) + if text: + text_display.delete(1.0, tk.END) + text_display.insert(tk.END, text) + else: + messagebox.showwarning("Error", "No text could be extracted or an error occurred.") + +def main(): + global text_display + + root = tk.Tk() + root.title("Text Extractor with Python") + + text_frame = tk.Frame(root) + text_frame.pack(pady=10) + + scrollbar = Scrollbar(text_frame) + scrollbar.pack(side=tk.RIGHT, fill=tk.Y) + + text_display = Text(text_frame, wrap=tk.WORD, yscrollcommand=scrollbar.set, height=15, width=60) + text_display.pack() + + scrollbar.config(command=text_display.yview) + + btn_select_file = tk.Button(root, text="Select Image File", command=select_image_file, width=30) + btn_select_file.pack(pady=10) + + btn_paste_clipboard = tk.Button(root, text="Paste Image from Clipboard", command=paste_image_from_clipboard, width=30) + btn_paste_clipboard.pack(pady=10) + + btn_capture_screenshot = tk.Button(root, text="Capture Full Screen Screenshot", command=capture_screenshot, width=30) + btn_capture_screenshot.pack(pady=10) + + root.mainloop() + +if __name__ == "__main__": + main() From 25f422bb1d8fff6e560ab46e496a5de235226e9e Mon Sep 17 00:00:00 2001 From: rusty-bytes7 <147008821+rusty-bytes7@users.noreply.github.com> Date: Fri, 11 Oct 2024 02:46:35 -0400 Subject: [PATCH 035/127] Create caesarcipher.py (#306) * Create caesarcipher.py This is a simple example of a Caesar Cipher for Hacktoberfest- this is my first-ever pull request! :) * Updated README to include program in list --- README.md | 3 ++- caesarcipher.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 caesarcipher.py diff --git a/README.md b/README.md index 97710f02..e989ee40 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,8 @@ More information on contributing and the general code of conduct for discussion | Autocomplete Notes App | [AutoCert](https://github.com/DhanushNehru/Python-Scripts/tree/master/Autocomplete%20Notes%20App) | A Python script to auto-generate e-certificates in bulk. | | Automated Emails | [Automated Emails](https://github.com/DhanushNehru/Python-Scripts/tree/master/Automate%20Emails%20Daily) | A Python script to send out personalized emails by reading a CSV file. | | Black Hat Python | [Black Hat Python](https://github.com/DhanushNehru/Python-Scripts/tree/master/Black%20Hat%20Python) | Source code from the book Black Hat Python | -| Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. | +| Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. +|Caesar Cipher | [Caesar Cipher](https://github.com/rusty-bytes7/Python-Scripts/blob/e94c8b52d313dc0d66b9ed0b55032c4470f72475/caesarcipher.py) | A Python script to encrypt messages using the Caesar cipher. | | Chessboard | [Chessboard](https://github.com/DhanushNehru/Python-Scripts/tree/master/Chess%20Board) | Creates a chessboard using matplotlib. | | Compound Interest Calculator | [Compound Interest Calculator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Calculate%20Compound%20Interest) | A Python script to calculate compound interest. | | Countdown Timer | [Countdown Timer](https://github.com/DhanushNehru/Python-Scripts/tree/master/Countdown%20Timer) | Displays a message when the Input time elapses. | diff --git a/caesarcipher.py b/caesarcipher.py new file mode 100644 index 00000000..d4466f4f --- /dev/null +++ b/caesarcipher.py @@ -0,0 +1,21 @@ +#this program is a simple caesar cipher, which encrypts +#a message by shifting each letter three to the right in the alphabet +#this will ignore all characters that are not letters + +def caesar_encrypt(plaintext): + #each letter in plaintext + finalstring= "" + for letter in plaintext.lower(): + #get the number value of the letter + cipher = (ord(letter)+3) + #wraparound + #checks letter to see if it's out of range + if cipher > 122: + cipher -= 26 + finalstring += chr(cipher) + #skips any other characters + elif (ord(letter)) in range (97,123): + finalstring +=chr(cipher) + else: + continue + return(finalstring) \ No newline at end of file From 1cd54ecb2060c48ae36a8afe09866e17a1d9f161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Fri, 11 Oct 2024 13:27:18 +0530 Subject: [PATCH 036/127] Add Custom Emoji Support and Emotion Detection History --- Face Reaction/app.py | 99 ++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/Face Reaction/app.py b/Face Reaction/app.py index 27357872..166252b1 100644 --- a/Face Reaction/app.py +++ b/Face Reaction/app.py @@ -1,43 +1,72 @@ import cv2 import numpy as np from fer import FER +import os +import json -scr = cv2.VideoCapture(0) #30fps +# Load custom emojis from a config file (custom_emojis.json) +def load_custom_emojis(config_file='custom_emojis.json'): + if os.path.exists(config_file): + with open(config_file, 'r') as file: + return json.load(file) + return {} + +# Save the emotion detection history +def save_emotion_history(history, filename='emotion_history.txt'): + with open(filename, 'a') as file: + for emotion in history: + file.write(f"{emotion}\n") + +# Initialize the webcam +scr = cv2.VideoCapture(0) # 30fps scr.set(3, 640) scr.set(4, 480) -#init FRE (Facial expression recognition from images) +# Initialize FER (Facial Expression Recognition) detector = FER(mtcnn=True) -while True: +# Load custom emojis +custom_emojis = load_custom_emojis() - ret,frame = scr.read() - # frame = cv2.flip(frame,1) +# Initialize emotion detection history +emotion_history = [] - #return emotion name and % of true detection +while True: + ret, frame = scr.read() + + # Return emotion name and % of true detection emotion, score = detector.top_emotion(frame) - print(emotion,score) - if emotion == 'angry': - emoj = cv2.imread('https://i.ibb.co/QN0gqNH/angry.png') - elif emotion == 'disgust': - emoj = cv2.imread('https://i.ibb.co/tJDxrhD/disgust.png') - elif emotion == 'fear': - emoj = cv2.imread('https://i.ibb.co/yBczSFB/fear.png') - elif emotion == 'happy': - emoj = cv2.imread('https://i.ibb.co/g6DW0Cf/happy.png') - elif emotion == 'sad': - emoj = cv2.imread('https://i.ibb.co/NyF0sDq/sad.png') - elif emotion == 'surprise': - emoj = cv2.imread('https://i.ibb.co/D4rDyfM/surprise.png') - elif emotion == 'neutral': - emoj = cv2.imread('https://i.ibb.co/KX7VSjh/neutral.png') - else: - emoj = cv2.imread('https://i.ibb.co/LdnS9nL/none.png') + # Append detected emotion to the history + emotion_history.append(emotion) + # Optionally save the history to a file (uncomment to enable) + # save_emotion_history(emotion_history) + print(emotion, score) - #Adding Image on Screen - + # Use custom emoji if available, otherwise fall back to default + if emotion in custom_emojis: + emoj = cv2.imread(custom_emojis[emotion]) + else: + # Default emojis if no custom emojis are set + if emotion == 'angry': + emoj = cv2.imread('https://i.ibb.co/QN0gqNH/angry.png') + elif emotion == 'disgust': + emoj = cv2.imread('https://i.ibb.co/tJDxrhD/disgust.png') + elif emotion == 'fear': + emoj = cv2.imread('https://i.ibb.co/yBczSFB/fear.png') + elif emotion == 'happy': + emoj = cv2.imread('https://i.ibb.co/g6DW0Cf/happy.png') + elif emotion == 'sad': + emoj = cv2.imread('https://i.ibb.co/NyF0sDq/sad.png') + elif emotion == 'surprise': + emoj = cv2.imread('https://i.ibb.co/D4rDyfM/surprise.png') + elif emotion == 'neutral': + emoj = cv2.imread('https://i.ibb.co/KX7VSjh/neutral.png') + else: + emoj = cv2.imread('https://i.ibb.co/LdnS9nL/none.png') + + # Adding Image on Screen # Read emoj and resize size = 150 emoj = cv2.resize(emoj, (size, size)) @@ -47,27 +76,25 @@ ret, mask = cv2.threshold(img2gray, 1, 255, cv2.THRESH_BINARY) roi = frame[-size-20:-20, -size-20:-20] - # roi = frame[-size-310:-310, -size-470:-470] # Set an index of where the mask is roi[np.where(mask)] = 0 roi += emoj - - #add text + # Add text font = cv2.FONT_HERSHEY_SIMPLEX org = (40, 210) fontScale = 1 color = (255, 0, 0) thickness = 2 - cv2.putText(frame,emotion, org, font, fontScale, color, thickness, cv2.LINE_AA) - - #show screen - cv2.imshow('frame',frame) - - #stop + cv2.putText(frame, emotion, org, font, fontScale, color, thickness, cv2.LINE_AA) + + # Show screen + cv2.imshow('frame', frame) + + # Stop if cv2.waitKey(1) & 0xff == ord('q'): break +# Release resources scr.release() - -cv2.destroyAllWindows() \ No newline at end of file +cv2.destroyAllWindows() From bc1320ccce2726f7192f96f24a2fc3421f3fcb5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96Stonebanks-js?= Date: Fri, 11 Oct 2024 13:41:53 +0530 Subject: [PATCH 037/127] Added a Documentation --- Face Reaction/README.md | 79 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 Face Reaction/README.md diff --git a/Face Reaction/README.md b/Face Reaction/README.md new file mode 100644 index 00000000..36b74c4e --- /dev/null +++ b/Face Reaction/README.md @@ -0,0 +1,79 @@ + +# Face Reaction with Custom Emojis and Emotion History + +This project uses OpenCV and FER (Facial Expression Recognition) to capture live video from the webcam, detect facial expressions in real time, and display corresponding emoji images for each detected emotion. Additionally, this enhanced version features custom emoji support and emotion detection history tracking, which provides a list of recently detected emotions. + + + + +## Acknowledgements + + We would like to express our sincere gratitude to the following: + +OpenCV for providing powerful tools for computer vision, enabling us to process real-time video feeds with ease. + +FER (Facial Expression Recognition) for simplifying the process of emotion detection with advanced facial expression recognition algorithms. + +The open-source community for providing constant support, knowledge, and resources that have helped improve and evolve this project. + +Contributors to this repository for their efforts in enhancing the functionality and maintaining the quality of the code. + +Special thanks to all the libraries, frameworks, and developers whose work has made this project possible! + + +## Features Added to Project + +Real-Time Emotion Detection: + +The system detects emotions such as angry, happy, sad, surprise, and more in real time using the FER library. +Custom Emojis: + +Users can provide their own custom emoji images to represent emotions. +Emotion Detection History: + +The program keeps track of the last 10 detected emotions and displays them on the screen, allowing users to see the emotion flow during the session. +Smooth Emoji Overlay: + +The corresponding emoji for the detected emotion is displayed on the video feed in a designated corner of the screen. +## Prerequisites + +Ensure that you have the following installed before running the script: + +Python 3.x +OpenCV +Numpy +FER (Facial Expression Recognition) + +You can install the required libraries by running: +pip install opencv-python numpy fer + + +## How to Run + +Clone the Repository : + +git clone https://github.com/your-repo/face-reaction.git + +Run the Python script: + +python face_reaction.py + + +## Custom Emoji Support + +To add your custom emoji, replace the URLs or paths in the script with the path to your custom emoji image files. The supported emotions include angry, happy, sad, disgust, fear, surprise, and neutral. + + +## Code Explanation + +Emotion Detection: The FER library is used to detect the dominant emotion in the video frame, with the highest probability score. + +Custom Emoji Overlay: Based on the detected emotion, the corresponding emoji image is resized and overlaid on the video feed. + +Emotion History: The recent emotions are displayed at the top-left corner of the video frame, showing the last 10 detected emotions during the session. + + +## Future Improvements + +Support for additional facial expressions. +Integration with cloud services for storing emotion history. \ No newline at end of file From 4fe6365ef5b9212291350a1ea578e7995864d1a0 Mon Sep 17 00:00:00 2001 From: Dhanush Date: Fri, 11 Oct 2024 18:37:33 +0530 Subject: [PATCH 038/127] Revert "Create caesarcipher.py (#306)" This reverts commit 25f422bb1d8fff6e560ab46e496a5de235226e9e. --- README.md | 3 +-- caesarcipher.py | 21 --------------------- 2 files changed, 1 insertion(+), 23 deletions(-) delete mode 100644 caesarcipher.py diff --git a/README.md b/README.md index e989ee40..97710f02 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,7 @@ More information on contributing and the general code of conduct for discussion | Autocomplete Notes App | [AutoCert](https://github.com/DhanushNehru/Python-Scripts/tree/master/Autocomplete%20Notes%20App) | A Python script to auto-generate e-certificates in bulk. | | Automated Emails | [Automated Emails](https://github.com/DhanushNehru/Python-Scripts/tree/master/Automate%20Emails%20Daily) | A Python script to send out personalized emails by reading a CSV file. | | Black Hat Python | [Black Hat Python](https://github.com/DhanushNehru/Python-Scripts/tree/master/Black%20Hat%20Python) | Source code from the book Black Hat Python | -| Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. -|Caesar Cipher | [Caesar Cipher](https://github.com/rusty-bytes7/Python-Scripts/blob/e94c8b52d313dc0d66b9ed0b55032c4470f72475/caesarcipher.py) | A Python script to encrypt messages using the Caesar cipher. | +| Blackjack | [Blackjack](https://github.com/DhanushNehru/Python-Scripts/tree/master/Blackjack) | A game of Blackjack - let's get a 21. | | Chessboard | [Chessboard](https://github.com/DhanushNehru/Python-Scripts/tree/master/Chess%20Board) | Creates a chessboard using matplotlib. | | Compound Interest Calculator | [Compound Interest Calculator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Calculate%20Compound%20Interest) | A Python script to calculate compound interest. | | Countdown Timer | [Countdown Timer](https://github.com/DhanushNehru/Python-Scripts/tree/master/Countdown%20Timer) | Displays a message when the Input time elapses. | diff --git a/caesarcipher.py b/caesarcipher.py deleted file mode 100644 index d4466f4f..00000000 --- a/caesarcipher.py +++ /dev/null @@ -1,21 +0,0 @@ -#this program is a simple caesar cipher, which encrypts -#a message by shifting each letter three to the right in the alphabet -#this will ignore all characters that are not letters - -def caesar_encrypt(plaintext): - #each letter in plaintext - finalstring= "" - for letter in plaintext.lower(): - #get the number value of the letter - cipher = (ord(letter)+3) - #wraparound - #checks letter to see if it's out of range - if cipher > 122: - cipher -= 26 - finalstring += chr(cipher) - #skips any other characters - elif (ord(letter)) in range (97,123): - finalstring +=chr(cipher) - else: - continue - return(finalstring) \ No newline at end of file From c1b9d2e1685ed43e9a904868300f845385052c00 Mon Sep 17 00:00:00 2001 From: Dhanush Date: Fri, 11 Oct 2024 13:11:33 +0000 Subject: [PATCH 039/127] File Updates --- Contributions.md => CONTRIBUTIONS.md | 4 --- Rock Paper Scissors - New Version | 50 ---------------------------- 2 files changed, 54 deletions(-) rename Contributions.md => CONTRIBUTIONS.md (95%) delete mode 100644 Rock Paper Scissors - New Version diff --git a/Contributions.md b/CONTRIBUTIONS.md similarity index 95% rename from Contributions.md rename to CONTRIBUTIONS.md index c12a00f8..6cbcddf1 100644 --- a/Contributions.md +++ b/CONTRIBUTIONS.md @@ -88,7 +88,3 @@ members of the project's leadership. This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available [here.][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ -[first]: https://dev.to/diballesteros/step-by-step-guide-for-the-first-time-open-source-contribution-48bo diff --git a/Rock Paper Scissors - New Version b/Rock Paper Scissors - New Version deleted file mode 100644 index b7b3f030..00000000 --- a/Rock Paper Scissors - New Version +++ /dev/null @@ -1,50 +0,0 @@ -import random - -def get_user_choice(): - choices = ["rock", "paper", "scissors", "lizard", "spock"] - user_choice = input("Enter your choice (rock, paper, scissors, lizard, spock): ").lower() - while user_choice not in choices: - user_choice = input("Invalid choice. Please enter rock, paper, scissors, lizard, or spock: ").lower() - return user_choice - -def get_computer_choice(): - choices = ["rock", "paper", "scissors", "lizard", "spock"] - return random.choice(choices) - -def determine_winner(user_choice, computer_choice): - win_conditions = { - "scissors": ["paper", "lizard"], - "paper": ["rock", "spock"], - "rock": ["lizard", "scissors"], - "lizard": ["spock", "paper"], - "spock": ["scissors", "rock"] - } - - if user_choice == computer_choice: - return "tie" - elif computer_choice in win_conditions[user_choice]: - return "user" - else: - return "computer" - -def play_game(): - print("Welcome to Rock, Paper, Scissors, Lizard, Spock!") - - user_choice = get_user_choice() - computer_choice = get_computer_choice() - - print(f"You chose: {user_choice}") - print(f"Computer chose: {computer_choice}") - - winner = determine_winner(user_choice, computer_choice) - - if winner == "tie": - print("It's a tie! Let's play again.") - play_game() - elif winner == "user": - print("You win!") - else: - print("Computer wins!") - -if __name__ == "__main__": - play_game() From 65c5a3a9d2b37560faab71fbfd87747a9a3dd9bb Mon Sep 17 00:00:00 2001 From: Dhanush Date: Fri, 11 Oct 2024 19:21:51 +0530 Subject: [PATCH 040/127] Update README.md --- README.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 97710f02..19297b4c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,16 @@ # Table of Contents -- [Table of Contents](#table-of-contents) -- [Python Scripts](#python-scripts) - - [Contributing](#contributing) - - [Adding a New Script](#adding-a-new-script) - - [List of Scripts in Repo](#list-of-scripts-in-repo) - - [Wall of Contributors](#wall-of-contributors) +- [Contributing](#contributing) + - [Adding a New Script](#adding-a-new-script) +- [List of Scripts in Repo](#list-of-scripts-in-repo) +- [Gitpod](#gitpod) +- [Wall of Contributors](#wall-of-contributors) + +
+ +[![Join Our Discord](https://img.shields.io/badge/Discord-Join%20Server-blue?logo=discord&style=for-the-badge)](https://discord.com/invite/Yn9g6KuWyA) +[![Subscribe on YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?logo=youtube&style=for-the-badge)](https://www.youtube.com/@dhanushnehru?sub_confirmation=1) +[![Subscribe to Newsletter](https://img.shields.io/badge/Newsletter-Subscribe-orange?style=for-the-badge)](https://dhanushn.substack.com/) # Python Scripts @@ -17,7 +22,7 @@ We encourage contributions from the community to make this repository even more _**Note: Please follow the maintainer of the repository for quick approval of the PR's via [Twitter](https://twitter.com/Dhanush_Nehru), [Instagram](https://www.instagram.com/dhanush_nehru/), [Youtube](https://www.youtube.com/@dhanushnehru?sub_confirmation=1), [Github](https://github.com/DhanushNehru)**_ -### Adding a New Script 👇 +### Adding a New Script **1. Create an issue:** Start by creating an issue in this repository. Describe the new script you'd like to contribute, its purpose, and any specific features it will provide. @@ -149,11 +154,8 @@ You can use Gitpod in the cloud [![Gitpod Ready-to-Code](https://img.shields.io
+
+ If you liked this repository, support it by starring ⭐ Thank You for being here :) - -### Connect 👉 [**Twitter**](https://twitter.com/Dhanush_Nehru) **/** [**Instagram**](https://www.instagram.com/dhanush_nehru/) **/** [**Github**](https://github.com/DhanushNehru/) **/** [**Youtube**](https://www.youtube.com/@dhanushnehru?sub_confirmation=1) **/** [**Newsletter**](https://dhanushn.substack.com/) **/** [**Discord**](https://discord.com/invite/Yn9g6KuWyA) - - - From 734eabe33d644895034c486e594ef8910a7effcd Mon Sep 17 00:00:00 2001 From: debojit11 <126899332+debojit11@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:11:17 +0530 Subject: [PATCH 041/127] PR for File_search script (#316) * Create file_search.py * Create readme.md * Update file_search.py * Update readme.md * Update readme.md * Update README.md * improved the heading in readme.md * placed the name , link and description in correct row --- File_Search/file_search.py | 23 +++++++++++++++++++++++ File_Search/readme.md | 31 +++++++++++++++++++++++++++++++ README.md | 1 + 3 files changed, 55 insertions(+) create mode 100644 File_Search/file_search.py create mode 100644 File_Search/readme.md diff --git a/File_Search/file_search.py b/File_Search/file_search.py new file mode 100644 index 00000000..e0b8321f --- /dev/null +++ b/File_Search/file_search.py @@ -0,0 +1,23 @@ +import pathlib +all_files_path = pathlib.Path('Place the folder path here under quotes') +file_paths = [] + +for file in all_files_path.rglob('*'): + if file.is_file(): + file_paths.append(str(file)) + +formatted_output = '[\n' + ',\n'.join(f' "{path}"' for path in file_paths) + '\n]' +print(formatted_output) + + +file_extensions = [] + +for file in all_files_path.rglob('*'): + if file.is_file(): + ext = file.suffix.lower() + if ext and ext not in file_extensions: + file_extensions.append(ext) + + +formattedd_output = '[\n' + ',\n'.join(f' "{ext}"' for ext in file_extensions) + '\n]' +print(formattedd_output) diff --git a/File_Search/readme.md b/File_Search/readme.md new file mode 100644 index 00000000..597c155e --- /dev/null +++ b/File_Search/readme.md @@ -0,0 +1,31 @@ +Automated File Explorer: +This Python script searches a specified folder for all files, regardless of file type, within its directory and subdirectories. It outputs the paths of all files found and also lists all unique file extensions present in the folder. The script uses Python's pathlib module, which is cross-platform and simplifies working with file paths. + +Features: +File Path Finder: The script scans a folder and lists the file paths of all files it finds within the specified directory and its subdirectories. +Unique File Extension Lister: The script identifies all unique file extensions present in the folder, displaying them in lowercase format. + +Requirements: Python 3.x + +Set the Folder Path: + +Replace 'Place the folder path here under quotes' in the script with the path to the folder you want to scan: +all_files_path = pathlib.Path('path/to/your/folder') + +Run the Script: + +Save the script as file_finder.py (or another name of your choice). +Open your terminal or command prompt. +Navigate to the folder containing the script and run it with: +python file_finder.py + +Output: +The script will output two lists: +The first list contains the paths of all files found within the specified folder and its subdirectories. +The second list contains all unique file extensions in the folder, displayed in lowercase. + + +Example output: + +[ "path/to/folder/document.txt", "path/to/folder/image.jpg", "path/to/folder/subfolder/script.py"] +[ ".txt", ".jpg", ".py"] diff --git a/README.md b/README.md index 19297b4c..94f42464 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,7 @@ More information on contributing and the general code of conduct for discussion | Face Reaction | [Face Reaction](https://github.com/DhanushNehru/Python-Scripts/tree/master/Face%20Reaction) | A script which attempts to detect facial expressions. | | Fake Profiles | [Fake Profiles](https://github.com/DhanushNehru/Python-Scripts/tree/master/Fake%20Profile) | Creates fake profiles. | | File Encryption Decryption | [File Encryption Decryption](https://github.com/DhanushNehru/Python-Scripts/tree/master/File%20Encryption%20Decryption) | Encrypts and Decrypts files using AES Algorithms for Security purposes. | +| File Search | [File_search](https://github.com/debojit11/Python-Scripts/tree/master/File_Search) | A python script that searches a specified folder for all files, regardless of file type, within its directory and subdirectories. | Font Art | [Font Art](https://github.com/DhanushNehru/Python-Scripts/tree/master/Font%20Art) | Displays a font art using Python. | | Freelance Helper Program | [freelance-helper](https://github.com/DhanushNehru/Python-Scripts/tree/master/freelance-help-program) | Takes an Excel file with working hours and calculates the payment. | | Get Hexcodes From Websites | [Get Hexcodes From Websites](https://github.com/DhanushNehru/Python-Scripts/tree/master/Get%20Hexcodes%20From%20Websites) | Generates a Python list containing Hexcodes from a website. | From 0294be5c260d449c8ea0b73933f6f4ad03a2e6a2 Mon Sep 17 00:00:00 2001 From: Vignesh Skanda Date: Sun, 13 Oct 2024 10:14:44 +0530 Subject: [PATCH 042/127] Update README.md (#325) --- Arrange It/README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Arrange It/README.md b/Arrange It/README.md index c3515c04..78013930 100644 --- a/Arrange It/README.md +++ b/Arrange It/README.md @@ -5,7 +5,7 @@ With the help of this script, files can be moved automatically to the folder tha ## New Feature: Custom Folder Configuration -Now, you can customize how files are arranged by defining your own folder structure and file extensions using a config.json file. This allows for more flexibility without needing to modify the Python code itself. -python arrangeit.py +`python arrangeit.py` # How To Use the config.json File @@ -14,6 +14,7 @@ python arrangeit.py Example config.json: +```bash { "Programming Files": ["ipynb", "py", "java", "cs", "js"], "Music": ["mp3", "wav", "aac"], @@ -21,6 +22,7 @@ Example config.json: "Pictures": ["jpeg", "png", "gif"], "Documents": ["pdf", "docx", "xlsx"] } +``` # How To Run @@ -28,14 +30,17 @@ Put the script and the config.json file in the folder where you want to automati Run the following command from the terminal: +```bash python arrangeit.py - +``` The script will create folders and move files based on the folder-extension mappings in the config.json file. # Benefits -Customizable: Easily modify the config.json file to tailor the organization to your preferences. -User-Friendly: No need to modify Python code—just update the config.json file. -Scalable: Works with different folder structures for different use cases. \ No newline at end of file +**Customizable:** Easily modify the config.json file to tailor the organization to your preferences. + +**User-Friendly:** No need to modify Python code—just update the config.json file. + +**Scalable:** Works with different folder structures for different use cases. From 0073d35b7d6559591851c4e6d94ed9be5385e29b Mon Sep 17 00:00:00 2001 From: Vignesh Skanda Date: Sun, 13 Oct 2024 10:15:25 +0530 Subject: [PATCH 043/127] Create requirements.txt (#326) --- Auto WiFi Check/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 Auto WiFi Check/requirements.txt diff --git a/Auto WiFi Check/requirements.txt b/Auto WiFi Check/requirements.txt new file mode 100644 index 00000000..7a7d08a2 --- /dev/null +++ b/Auto WiFi Check/requirements.txt @@ -0,0 +1 @@ +schedule==1.1.0 From 66161ee21d01f5e7b735875301e59865a97f5f84 Mon Sep 17 00:00:00 2001 From: bibliofilo <42589480+bibliofilo@users.noreply.github.com> Date: Sat, 12 Oct 2024 22:47:48 -0600 Subject: [PATCH 044/127] Add longitude and latitude to conical converter (#329) * Create lonlat_converter_lambert.py * Create readme.md * Rename Longitude Latitude conical converter/Python/lonlat_converter_lambert.py to Longitude Latitude conical converter/lonlat_converter_lambert.py * Rename Longitude Latitude conical converter/Python/readme.md to Longitude Latitude conical converter/readme.md * Update README.md --- .../lonlat_converter_lambert.py | 35 +++++++++++++++++++ .../readme.md | 21 +++++++++++ README.md | 1 + 3 files changed, 57 insertions(+) create mode 100644 Longitude Latitude conical converter/lonlat_converter_lambert.py create mode 100644 Longitude Latitude conical converter/readme.md diff --git a/Longitude Latitude conical converter/lonlat_converter_lambert.py b/Longitude Latitude conical converter/lonlat_converter_lambert.py new file mode 100644 index 00000000..fb8371eb --- /dev/null +++ b/Longitude Latitude conical converter/lonlat_converter_lambert.py @@ -0,0 +1,35 @@ +from pyproj import Proj +from shapely.geometry import Point +from shapely.geometry.polygon import Polygon + +# Definition of lambert conical projection. +lambert = {'proj': 'lcc', # Lambert Conformal Conic 2SP (epsg:9802) + 'ellps': 'GRS80', #'epsg:7019', #'epsg:9802', # 'epsg:6651', + 'lon_0': -102.00000000, + 'lat_0': 12.00000000, # 12° 00’ 0.0’’ N + 'lat_1': 17.50000000, # 17° 30’ 0.00’’ N + 'lat_2': 29.50000000, # 29° 30’ 0.00’’ N + 'x_0': 2500000, + 'y_0': 0} + +prj = Proj(lambert) + +# Coordinates for the city of Monterrey, Nuevo León, México + +city = {'c_name': 'Monterrey', 'lon': -100.316116, 'lat': 25.686613} + +x, y = prj(city['lon'], city['lat']) + +print(' X Y') +print(city['c_name'], ': lon:', city['lon'], ' , lat:', city['lat']) +print('Lambert function:', x, ',', y) +print(' Should return: 2668223.843 , 1516271.922') + +# Should return: + +""" + X Y +Monterrey : lon: -100.316116 , lat: 25.686613 +Lambert function: 2668223.842598227 , 1516271.9216458194 + Should return: 2668223.843 , 1516271.922 +""" diff --git a/Longitude Latitude conical converter/readme.md b/Longitude Latitude conical converter/readme.md new file mode 100644 index 00000000..a22092a3 --- /dev/null +++ b/Longitude Latitude conical converter/readme.md @@ -0,0 +1,21 @@ +## Longitude and Latitude to Conical Converter + +This script converts longitude and latitude to [Lambert conformal conic projection](https://en.wikipedia.org/wiki/Lambert_conformal_conic_projection). +The example used is for Mexico, under International Terrestrial Reference Frame 2008, which uses Lambert Conformal Conic projection 2SP (epsg:9802). + +This script is useful to combine census and geographic data, with traditional Longitude and Latitude from the more international frame of reference. + +For more reference, see [National Geography institute explanatory PDF](https://www.inegi.org.mx/contenidos/temas/MapaDigital/Doc/asignar_sistema_coordenadas.pdf) +and [Pyproj, Lambert projections](https://proj.org/operations/projections/lcc.html). + +## Prerequisites +- Python 3.x installed on your machine. + +## Dependencies +The script requires the following Python libraries: +`pyproj` +`shapely` + +You can install the required library using pip: +`pip install pyproj` +`pip install shapely` diff --git a/README.md b/README.md index 94f42464..26666984 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ More information on contributing and the general code of conduct for discussion | Keylogger | [Keylogger](https://github.com/DhanushNehru/Python-Scripts/tree/master/Keylogger) | Keylogger that can track your keystrokes, clipboard text, take screenshots at regular intervals, and records audio. | | Keyword - Retweeting | [Keyword - Retweeting](https://github.com/DhanushNehru/Python-Scripts/tree/master/Keyword%20Retweet%20Twitter%20Bot) | Find the latest tweets containing given keywords and then retweet them. | | LinkedIn Bot | [LinkedIn Bot](https://github.com/DhanushNehru/Python-Scripts/tree/master/LinkedIn%20Bot) | Automates the process of searching for public profiles on LinkedIn and exporting the data to an Excel sheet. | +| Longitude & Latitude to conical coverter | [Longitude Latitude conical converter](master/Longitude%20Latitude%20conical%20converter) | Converts Longitude and Latitude to Lambert conformal conic projection. | | Mail Sender | [Mail Sender](https://github.com/DhanushNehru/Python-Scripts/tree/master/Mail%20Sender) | Sends an email. | | Merge Two Images | [Merge Two Images](https://github.com/DhanushNehru/Python-Scripts/tree/master/Merge%20Two%20Images) | Merges two images horizontally or vertically. | | Mouse mover | [Mouse mover](https://github.com/DhanushNehru/Python-Scripts/tree/master/Mouse%20Mover) | Moves your mouse every 15 seconds. | From 4d28b625bcc848a1377c904b429eea754514151f Mon Sep 17 00:00:00 2001 From: "A.S Chaudhary" Date: Sun, 13 Oct 2024 10:18:52 +0530 Subject: [PATCH 045/127] feat: Add file type filtering and report generation features to duplicate finder (#327) --- Duplicate Finder/Readme.md | 15 ++++++++++++++- Duplicate Finder/duplicate-finder.py | 25 +++++++++++++++++++++---- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Duplicate Finder/Readme.md b/Duplicate Finder/Readme.md index 14055ffb..aae927f7 100644 --- a/Duplicate Finder/Readme.md +++ b/Duplicate Finder/Readme.md @@ -33,4 +33,17 @@ Always backup your data before using scripts that modify files. The author is no - \ No newline at end of file + + + +# KEY MODIFICATIONS + +File Type Filtering: + +Added an input prompt to specify file extensions for filtering. +Modified the find_duplicates function to only consider files with the specified extensions. + +Generate Report: + +Added a new generate_report function that creates a JSON report of duplicate files. +Added the option for the user to choose to generate a report instead of deleting or moving files. \ No newline at end of file diff --git a/Duplicate Finder/duplicate-finder.py b/Duplicate Finder/duplicate-finder.py index 47d7bb7e..f36fa390 100644 --- a/Duplicate Finder/duplicate-finder.py +++ b/Duplicate Finder/duplicate-finder.py @@ -1,5 +1,6 @@ import os import hashlib +import json # Import for generating reports def get_file_hash(filepath): """Return the MD5 hash of a file.""" @@ -9,13 +10,16 @@ def get_file_hash(filepath): hasher.update(buf) return hasher.hexdigest() -def find_duplicates(directory, min_size=0): - """Find duplicate files in a directory.""" +def find_duplicates(directory, min_size=0, file_extensions=None): + """Find duplicate files in a directory, with optional file type filtering.""" hashes = {} duplicates = {} for dirpath, dirnames, filenames in os.walk(directory): for filename in filenames: + if file_extensions and not filename.lower().endswith(tuple(file_extensions)): + continue # Skip files that don't match the extensions + filepath = os.path.join(dirpath, filename) if os.path.getsize(filepath) >= min_size: file_hash = get_file_hash(filepath) @@ -29,11 +33,20 @@ def find_duplicates(directory, min_size=0): return {k: v for k, v in duplicates.items() if len(v) > 1} +def generate_report(duplicates, report_path): + """Generate a report of duplicate files in JSON format.""" + with open(report_path, 'w') as report_file: + json.dump(duplicates, report_file, indent=4) + print(f"Report generated: {report_path}") + def main(): directory = input("Enter the directory to scan for duplicates: ") min_size = int(input("Enter the minimum file size to consider (in bytes, default is 0): ") or "0") - duplicates = find_duplicates(directory, min_size) + file_type_input = input("Enter the file extensions to check (comma-separated, e.g. .jpg,.png), or press Enter to check all: ") + file_extensions = [ext.strip().lower() for ext in file_type_input.split(",")] if file_type_input else None + + duplicates = find_duplicates(directory, min_size, file_extensions) if not duplicates: print("No duplicates found.") @@ -45,7 +58,7 @@ def main(): print(path) print("------") - action = input("\nChoose an action: (D)elete, (M)ove, (N)o action: ").lower() + action = input("\nChoose an action: (D)elete, (M)ove, (R)eport, (N)o action: ").lower() if action == "d": for _, paths in duplicates.items(): @@ -64,6 +77,10 @@ def main(): os.rename(path, target_path) print(f"Moved {path} to {target_path}") + elif action == "r": + report_path = input("Enter the path to save the report (e.g., duplicates_report.json): ") + generate_report(duplicates, report_path) + else: print("No action taken.") From 2f37ad2e9cc9ed1e218f56e481443e272aded31c Mon Sep 17 00:00:00 2001 From: Rohit Sharma <138422780+Rohit-Sharma-RS@users.noreply.github.com> Date: Sun, 13 Oct 2024 20:44:45 +0530 Subject: [PATCH 046/127] Added a python script that uploads an image to imgur via keyboard shortcut. (#314) * Added a python script that uploads an image to imgur and also handles exceptions gracefully * Made requested changes * Created morse code encoder and decoder * seperate 2 PRs * minor improvements * added Morse code encoder decoder under issue #313 --- Image Uploader/.gitignore | 1 + Image Uploader/README.md | 23 ++++++++++++++++++++ Image Uploader/main.py | 45 ++++++++++++++++++++++++++++++++++++++ Morse Code/README.md | 24 ++++++++++++++++++++ Morse Code/main.py | 46 +++++++++++++++++++++++++++++++++++++++ README.md | 4 +++- 6 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 Image Uploader/.gitignore create mode 100644 Image Uploader/README.md create mode 100644 Image Uploader/main.py create mode 100644 Morse Code/README.md create mode 100644 Morse Code/main.py diff --git a/Image Uploader/.gitignore b/Image Uploader/.gitignore new file mode 100644 index 00000000..30fe0fbc --- /dev/null +++ b/Image Uploader/.gitignore @@ -0,0 +1 @@ +secret.env \ No newline at end of file diff --git a/Image Uploader/README.md b/Image Uploader/README.md new file mode 100644 index 00000000..61efce3d --- /dev/null +++ b/Image Uploader/README.md @@ -0,0 +1,23 @@ +# Image Upload Script + +## Overview + +This Python script allows users to upload images from their clipboard directly to Imgur by pressing a keyboard shortcut. It utilizes the Imgur API for image uploads and the `python-dotenv` package to manage environment variables securely. + +## Features + +- **Clipboard Image Capture**: Captures images from the clipboard. +- **Imgur API Integration**: Uploads images to Imgur using a simple API call. +- **Keyboard Shortcut**: Allows users to trigger the upload with a predefined keyboard shortcut (`Ctrl + Alt + S`). +- **Environment Variable Management**: Utilizes a `secret.env` file for managing sensitive data, such as the Imgur Client ID and add it under the name `IMGUR_CLIENT_ID`. + + +**Note**: You can add an image in your clipboard using `Win + Shift + S` +Also press Esc to end the program + +## Example Screenshot + +Here’s how the application looks when running: + +![Screenshot of the app](https://i.imgur.com/e35Pvyh.png) +![Screenshot of the app](https://i.imgur.com/ZfyHcsx.png) \ No newline at end of file diff --git a/Image Uploader/main.py b/Image Uploader/main.py new file mode 100644 index 00000000..edad516f --- /dev/null +++ b/Image Uploader/main.py @@ -0,0 +1,45 @@ +import os +import requests +import keyboard +from PIL import ImageGrab +import io +import base64 +from dotenv import load_dotenv + + +load_dotenv("secret.env") +# Set your Imgur API client ID here +CLIENT_ID = os.getenv("IMGUR_CLIENT_ID") + +def upload_to_imgur(image_data): + headers = {"Authorization": f"Client-ID {CLIENT_ID}"} + response = requests.post("https://api.imgur.com/3/image", headers=headers, data={"image": image_data}) + return response.json() + +def upload_image(): + try: + image = ImageGrab.grabclipboard() + if image is None: + print("No image found in the clipboard.") + return + + + with io.BytesIO() as output: + image.save(output, format='PNG') + image_data = base64.b64encode(output.getvalue()).decode() # converted to base64 + + # Upload the image to Imgur + response = upload_to_imgur(image_data) + + if response.get("success"): + print("Image uploaded successfully:", response["data"]["link"]) + else: + print("Failed to upload image:", response) + except Exception as e: + print(f"An error occurred: {e}") + + +keyboard.add_hotkey('ctrl+alt+s', upload_image) + +print("Listening for the shortcut... (Press ESC to stop)") +keyboard.wait('esc') diff --git a/Morse Code/README.md b/Morse Code/README.md new file mode 100644 index 00000000..bcb53263 --- /dev/null +++ b/Morse Code/README.md @@ -0,0 +1,24 @@ +# Morse Code Encoder/Decoder + +## Overview + +This project provides a simple Python program to encode text into Morse code and decode Morse code back into text. It includes exception handling for invalid characters and offers default values when no input is provided. + +## Features + +- **Encoding**: Convert plain text into Morse code. +- **Decoding**: Convert Morse code back into plain text. +- **Exception Handling**: Handles invalid characters gracefully. +- **Default Values**: If no input is provided, it uses default values ('SOS' for encoding and '... --- ...' for decoding). + +## Installation + +1. Ensure you have Python installed on your machine. +2. Download the `morse_code.py` file. + +## Usage + +Run the script directly from the command line: + +```bash +python morse_code.py diff --git a/Morse Code/main.py b/Morse Code/main.py new file mode 100644 index 00000000..fdcad69d --- /dev/null +++ b/Morse Code/main.py @@ -0,0 +1,46 @@ +class MorseCode: + # Morse code dictionary + morse_dict = { + 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.', + 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---', + 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---', + 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-', + 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', + 'Z': '--..', '1': '.----', '2': '..---', '3': '...--', + '4': '....-', '5': '.....', '6': '-....', '7': '--...', + '8': '---..', '9': '----.', '0': '-----', ' ': '/' + } + + @classmethod + def encode(cls, text=""): + """Encodes a given text into Morse code.""" + if not text: + text = "SOS" # Default value if no input is provided + try: + return ' '.join(cls.morse_dict[char.upper()] for char in text) + except KeyError as e: + print(f"Error: Character '{e.args[0]}' cannot be encoded in Morse code.") + return None + + @classmethod + def decode(cls, morse_code=""): + """Decodes a given Morse code into plain text.""" + if not morse_code: + morse_code = "... --- ..." # Default value if no input is provided + try: + reverse_dict = {v: k for k, v in cls.morse_dict.items()} + return ''.join(reverse_dict[code] for code in morse_code.split()) + except KeyError as e: + print(f"Error: Morse code '{e.args[0]}' cannot be decoded.") + return None + + +if __name__ == "__main__": + # Example usage + text = input("Enter text to encode (leave blank for default 'SOS'): ") + morse_code = MorseCode.encode(text) + print(f"Morse Code: {morse_code}") + + morse_input = input("Enter Morse code to decode (leave blank for default '... --- ...'): ") + decoded_text = MorseCode.decode(morse_input) + print(f"Decoded Text: {decoded_text}") diff --git a/README.md b/README.md index 26666984..f7b96ec4 100644 --- a/README.md +++ b/README.md @@ -74,7 +74,8 @@ More information on contributing and the general code of conduct for discussion | Image Compress | [Image Compress](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Compress) | Takes an image and compresses it. | | Image Manipulation without libraries | [Image Manipulation without libraries](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Manipulation%20without%20libraries) | Manipulates images without using any external libraries. | | Image Text | [Image Text](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Text) | Extracts text from the image. | -| Image Text to PDF | [Image Text to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Text%20to%20PDF) | Adds an image and text to a PDF. +| Image Text to PDF | [Image Text to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Text%20to%20PDF) | Adds an image and text to a PDF. +| Image Uploader | [Image Uploader](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Uploader) | Uploads images to Imgur using a keyboard shortcut. | | Image Watermarker | [Image Watermarker](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20Watermarker) | Adds a watermark to an image. | Image to ASCII | [Image to ASCII](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20to%20ASCII) | Converts an image into ASCII art. | | Image to Gif | [Image to Gif](https://github.com/DhanushNehru/Python-Scripts/tree/master/Image%20to%20GIF) | Generate gif from images. @@ -92,6 +93,7 @@ More information on contributing and the general code of conduct for discussion | Mail Sender | [Mail Sender](https://github.com/DhanushNehru/Python-Scripts/tree/master/Mail%20Sender) | Sends an email. | | Merge Two Images | [Merge Two Images](https://github.com/DhanushNehru/Python-Scripts/tree/master/Merge%20Two%20Images) | Merges two images horizontally or vertically. | | Mouse mover | [Mouse mover](https://github.com/DhanushNehru/Python-Scripts/tree/master/Mouse%20Mover) | Moves your mouse every 15 seconds. | +| Morse Code | [Mose Code](https://github.com/DhanushNehru/Python-Scripts/tree/master/Morse%20Code) | Encodes and decodes Morse code. | | No Screensaver | [No Screensaver](https://github.com/DhanushNehru/Python-Scripts/tree/master/No%20Screensaver) | Prevents screensaver from turning on. | | OTP Verification | [OTP Verification](https://github.com/DhanushNehru/Python-Scripts/tree/master/OTP%20%20Verify) | An OTP Verification Checker. | | Password Generator | [Password Generator](https://github.com/DhanushNehru/Python-Scripts/tree/master/Password%20Generator) | Generates a random password. | From a3b538a471bf1b78d17218c91f938794fd1ebd56 Mon Sep 17 00:00:00 2001 From: Vignesh Skanda Date: Wed, 16 Oct 2024 11:43:44 +0530 Subject: [PATCH 047/127] Update README.md (#332) --- Black Hat Python/README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Black Hat Python/README.md b/Black Hat Python/README.md index 037a1d45..cfb0ebf5 100644 --- a/Black Hat Python/README.md +++ b/Black Hat Python/README.md @@ -4,9 +4,14 @@ Source code for the book "Black Hat Python" by Justin Seitz. ## Usage Simply choose a directory (DIR) in which to clone the project using -`git clone`, create a new virtual environment or `venv` for it (recommended + +```bash +git clone https://github.com/DhanushNehru/Python-Scripts/Black Hat Python.git +``` + +create a new virtual environment or `venv` for it (recommended ) and install the requirements using `pip install`. - \ No newline at end of file + From bd5d657dd56cbf6197d671add88efe6e81d7435c Mon Sep 17 00:00:00 2001 From: Vignesh Skanda Date: Wed, 16 Oct 2024 11:45:47 +0530 Subject: [PATCH 048/127] Update BlackjackGame.py (#334) --- Blackjack/BlackjackGame.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/Blackjack/BlackjackGame.py b/Blackjack/BlackjackGame.py index 11032a30..92ad5e92 100644 --- a/Blackjack/BlackjackGame.py +++ b/Blackjack/BlackjackGame.py @@ -58,6 +58,7 @@ def getScore(self): self.score = 0 for card in self.cards: self.score += self.scoreDictionary[card] + self.adjustAceValue() return self.score def adjustAceValue(self): @@ -145,25 +146,17 @@ def playRound3(self): print("My Money: " + str(player.money)) def removeLossers(self): - i = 0 - for player in self.playerlist: - if player.money <= 0: - self.playerlist.pop(i) - i += 1 + self.playerlist = [player for player in self.playerlist if player.money > 0] def refreshPlayerCard(self): for player in self.playerlist: player.cards = [] - dealer.cards = [] + self.dealer.cards = [] def genDeck(self): - cardType = ['2','3','4','5','6','7','8','9','10','J','Q','K','A'] - self.cardDeck = [] - for card in cardType: - self.cardDeck.append(card) - self.cardDeck.append(card) - self.cardDeck.append(card) - self.cardDeck.append(card) + cardType = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'] + self.cardDeck = [card for card in cardType for _ in range(4)] + random.shuffle(self.cardDeck) # Set betting limits min_bet = 5 @@ -192,4 +185,4 @@ def genDeck(self): game1.drawCardsRound2() game1.playRound3() game1.removeLossers() - gameRound += 1 \ No newline at end of file + gameRound += 1 From 0671816f94847a3c8bb56be3da917f97b6a8e4b3 Mon Sep 17 00:00:00 2001 From: Vanshaj Raghuvanshi Date: Thu, 17 Oct 2024 21:46:44 +0530 Subject: [PATCH 049/127] added ddos script (#330) * Add files via upload * Create README.md * Update README.md --- README.md | 1 + Simple DDOS/README.md | 69 +++++++++++++++++++++++++++++++++++++++++++ Simple DDOS/ddos.py | 27 +++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 Simple DDOS/README.md create mode 100644 Simple DDOS/ddos.py diff --git a/README.md b/README.md index f7b96ec4..eb760638 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,7 @@ More information on contributing and the general code of conduct for discussion | Rock Paper Scissor 2 | [Rock Paper Scissor 2](https://github.com/DhanushNehru/Python-Scripts/tree/master/Rock%20Paper%20Scissor%202) | A new version game of Rock Paper Scissors. | Run Then Notify | [Run Then Notify](https://github.com/DhanushNehru/Python-Scripts/tree/master/Run%20Then%20Notify) | Runs a slow command and emails you when it completes execution. | | Selfie with Python | [Selfie with Python](https://github.com/DhanushNehru/Python-Scripts/tree/master/Selfie%20with%20Python) | Take your selfie with python . | +| Simple DDOS | [Simple DDOS](https://github.com/VanshajR/Python-Scripts/tree/master/Simple%20DDOS) | The code allows you to send multiple HTTP requests concurrently for a specified duration. | | Simple TCP Chat Server | [Simple TCP Chat Server](https://github.com/DhanushNehru/Python-Scripts/tree/master/TCP%20Chat%20Server) | Creates a local server on your LAN for receiving and sending messages! | | Snake Water Gun | [Snake Water Gun](https://github.com/DhanushNehru/Python-Scripts/tree/master/Snake%20Water%20Gun) | A game similar to Rock Paper Scissors. | | Sorting | [Sorting](https://github.com/DhanushNehru/Python-Scripts/tree/master/Sorting) | Algorithm for bubble sorting. | diff --git a/Simple DDOS/README.md b/Simple DDOS/README.md new file mode 100644 index 00000000..9d9d2904 --- /dev/null +++ b/Simple DDOS/README.md @@ -0,0 +1,69 @@ +# Multithreaded HTTP Requests with Python + +This script performs multithreaded HTTP requests using Python's `requests` library and `ThreadPoolExecutor`. The code allows you to send multiple HTTP requests concurrently for a specified duration. + +## Features +- Sends concurrent HTTP requests to a specified URL. +- Supports multiple request methods (GET, POST, etc.). +- Allows customizing headers, cookies, data, and URL parameters. +- The number of threads and the duration of the requests can be controlled. +- Uses ThreadPoolExecutor to handle multithreading efficiently. + +## Requirements +- Python 3.x +- `requests` library + +To install the `requests` library, run: +```bash +pip install requests +``` + +## Usage + +### Function: `make_request` +This function sends a single HTTP request to a given URL with the specified parameters. +- **Arguments**: + - `url` (str): The URL to send the request to. + - `method` (str): The HTTP method to use (default: GET). + - `headers` (dict): Optional HTTP headers to include. + - `cookies` (dict): Optional cookies to include. + - `data` (dict): Optional data for POST requests. + - `params` (dict): Optional URL parameters. + +- **Example**: +make_request("https://example.com", method='POST', data={"key": "value"}) + +### Function: `start_requests` +This function sends multiple HTTP requests concurrently for a specified duration. +- **Arguments**: + - `url` (str): The URL to send the requests to. + - `method` (str): The HTTP method to use (default: GET). + - `headers` (dict): Optional HTTP headers to include. + - `cookies` (dict): Optional cookies to include. + - `data` (dict): Optional data for POST requests. + - `params` (dict): Optional URL parameters. + - `num_threads` (int): The number of threads to use (default: 5). + - `duration` (int): The duration in seconds to send requests (default: 10 seconds). + +- **Example**: +url = "https://example.com/api" +start_requests(url, method='GET', num_threads=5, duration=15) + +## How It Works +1. The `start_requests` function uses `ThreadPoolExecutor` to manage the specified number of threads. +2. Each thread sends an HTTP request to the given URL. +3. The process continues until the specified duration ends. +4. The `make_request` function handles sending the requests and printing the response status codes. + +## Example Usage +url = "https://example.com/api" +start_requests(url, num_threads=5, duration=15) # Sends requests for 15 seconds using 5 threads. + +## Customization +- You can modify the method, headers, cookies, data, or params in the function calls to fit your use case. +- For POST requests, pass data through the `data` argument. + +start_requests("https://example.com/post", method='POST', data={'key': 'value'}, num_threads=10, duration=20) + +## License +This project is licensed under the MIT License. diff --git a/Simple DDOS/ddos.py b/Simple DDOS/ddos.py new file mode 100644 index 00000000..9abf8f64 --- /dev/null +++ b/Simple DDOS/ddos.py @@ -0,0 +1,27 @@ +import requests +from concurrent.futures import ThreadPoolExecutor +import time + +def make_request(url, method='GET', headers=None, cookies=None, data=None, params=None): + try: + + response = requests.request(method, url, headers=headers, cookies=cookies, data=data, params=params) + print(f"Response code: {response.status_code}") + except requests.exceptions.RequestException as e: + print(f"Error occurred: {e}") + +def start_requests(url, method='GET', headers=None, cookies=None, data=None, params=None, num_threads=5, duration=10): + executor = ThreadPoolExecutor(max_workers=num_threads) + end_time = time.time() + duration # Time to stop the requests + + while time.time() < end_time: + for _ in range(num_threads): + executor.submit(make_request, url, method, headers, cookies, data, params) + + executor.shutdown(wait=True) + print("Requests completed.") + +# Usage example +url = "Sample URL" +start_requests(url, num_threads=5, duration=15) #time in seconds +#change methods as required \ No newline at end of file From 88ee0adeb40a8c69e95389d51083fecd327c6003 Mon Sep 17 00:00:00 2001 From: Maximiliano Date: Fri, 18 Oct 2024 11:30:34 -0600 Subject: [PATCH 050/127] Organize Files, Rename Files, and Search Text Files (#342) * Added Pomodoro Timer * Update README.md * Update README.md * Added FileOrganizer,FileRenamer and FileTextSearch --- FileOrganizer/FileOrganizer.py | 26 +++++++++++++++ FileOrganizer/README.md | 22 +++++++++++++ FileRenamer/File_Renamer.py | 31 ++++++++++++++++++ FileRenamer/README.md | 27 ++++++++++++++++ FileTextSearch/FileTextSearch.py | 55 ++++++++++++++++++++++++++++++++ FileTextSearch/README.md | 26 +++++++++++++++ README.md | 3 ++ 7 files changed, 190 insertions(+) create mode 100644 FileOrganizer/FileOrganizer.py create mode 100644 FileOrganizer/README.md create mode 100644 FileRenamer/File_Renamer.py create mode 100644 FileRenamer/README.md create mode 100644 FileTextSearch/FileTextSearch.py create mode 100644 FileTextSearch/README.md diff --git a/FileOrganizer/FileOrganizer.py b/FileOrganizer/FileOrganizer.py new file mode 100644 index 00000000..834db468 --- /dev/null +++ b/FileOrganizer/FileOrganizer.py @@ -0,0 +1,26 @@ +import os +import shutil + +# Prompt the user for the directory path to organize files +path = input("Enter path: ") + +# List all files in the specified directory +files = os.listdir(path) + +# Iterate through each file in the directory +for file in files: + # Split the filename and extension + filename, extension = os.path.splitext(file) + + # Remove the leading dot from the extension for folder naming + extension = extension[1:] + + # Check if a directory for the file extension already exists + if os.path.exists(path + '/' + extension): + # Move the file to the corresponding extension folder + shutil.move(path + '/' + file, path + '/' + extension + '/' + file) + else: + # If the directory does not exist, create it + os.makedirs(path + '/' + extension) + # Move the file to the newly created extension folder + shutil.move(path + '/' + file, path + '/' + extension + '/' + file) diff --git a/FileOrganizer/README.md b/FileOrganizer/README.md new file mode 100644 index 00000000..5606765c --- /dev/null +++ b/FileOrganizer/README.md @@ -0,0 +1,22 @@ +# File Organizer Script +## Description +The `FileOrganizer.py` script is a simple utility for organizing files in a specified directory. It automatically sorts files into subdirectories based on their file extensions, making it easier to manage and locate files. +## Features +- *Automatic Organization:* Files are moved into subfolders named after their extensions (e.g., all `.jpg` files go into a folder named `jpg`). +- *Dynamic Folder Creation:* If a folder for a specific file type doesn't exist, it will be created automatically. +## Usage +1. Ensure you have Python installed on your machine. +2. Download the FileOrganizer.py script. +3. Open a terminal or command prompt and navigate to the directory where the script is located. +4. Run the script using the following command: +python FileOrganizer.py +5. When prompted, enter the path of the directory you want to organize. +Enter path: /path/to/your/directory +6. The script will process the files in the specified directory and create folders for each file type, moving the corresponding files into their respective folders. +## Requirements +- Python 3.x +- Basic understanding of file paths in your operating system. +## License +This script is open-source and free to use. Feel free to modify and distribute as needed. +## Contributing +If you'd like to contribute to this project, please open an issue or submit a pull request with your proposed changes or enhancements. \ No newline at end of file diff --git a/FileRenamer/File_Renamer.py b/FileRenamer/File_Renamer.py new file mode 100644 index 00000000..4576396a --- /dev/null +++ b/FileRenamer/File_Renamer.py @@ -0,0 +1,31 @@ +import os +import re + +# Prompt the user for the directory path where files need to be renamed +directory = input("Enter path: ") + +# Provide instructions on how to use regex for searching specific files +print("To look for specific files, enter what you know, using .* for any characters you don't know.") +print("For example: IMG.* will filter files that start with IMG") + +# Get the regex pattern to match files and the new base name for renaming +pattern = input("Enter pattern: ") +new_name = input("Enter the new name: ") + +def rename_files(directory, pattern, new_name): + # List all files in the specified directory + files = os.listdir(directory) + counter = 0 # Initialize a counter for unique naming + + # Iterate over each file in the directory + for file in files: + # Check if the file matches the given pattern + if re.match(pattern, file): + # Get the file extension + filetype = file.split('.')[-1] + # Rename the file with the new base name and counter + os.rename(directory + '/' + file, directory + '/' + new_name + str(counter) + '.' + filetype) + counter += 1 # Increment the counter for the next file + +# Call the function to rename files +rename_files(directory, pattern, new_name) diff --git a/FileRenamer/README.md b/FileRenamer/README.md new file mode 100644 index 00000000..72e7b43e --- /dev/null +++ b/FileRenamer/README.md @@ -0,0 +1,27 @@ +# File Renamer Script +## Description +The `FileRenamer.py` script is a utility designed to rename multiple files in a specified directory based on a given regex pattern. This script helps users quickly standardize file names, making file management easier. +## Features +- *Batch Renaming:* Rename multiple files that match a specified regex pattern. +- *Custom Naming:* Users can provide a new base name for the renamed files, with a counter appended to ensure unique names. +## Usage +1. Ensure you have Python installed on your machine. +2. Download the `FileRenamer.py` script. +3. Open a terminal or command prompt and navigate to the directory where the script is located. +4. Run the script using the following command: +python `FileRenamer.py` +5. When prompted, enter the path of the directory containing the files you want to rename. +Enter path: /path/to/your/directory +6. Enter the regex pattern for the files you want to rename. For example: +Enter pattern: IMG.* +7. Enter the new base name for the renamed files. +Enter the new name: NewImageName +8. The script will rename all matching files in the specified directory according to the new name format. +## Requirements +- Python 3.x +- Basic understanding of file paths in your operating system. +- Familiarity with regex patterns for filtering files. +## License +This script is open-source and free to use. Feel free to modify and distribute as needed. +## Contributing +If you'd like to contribute to this project, please open an issue or submit a pull request with your proposed changes or enhancements. \ No newline at end of file diff --git a/FileTextSearch/FileTextSearch.py b/FileTextSearch/FileTextSearch.py new file mode 100644 index 00000000..443711fe --- /dev/null +++ b/FileTextSearch/FileTextSearch.py @@ -0,0 +1,55 @@ +import os +import uuid + +# Initialize a list to store files containing the keyword +contains = [] + +# Generate a unique identifier for this search session (not currently used) +id_ = uuid.uuid4() + +# List of file extensions to search within +extensions = [".txt", ".docx", ".pdf"] + +def change_direct(): + # Prompt the user to enter the directory path + path = input("Enter path: ") + # Prompt the user to enter the keyword or phrase to search for + keyword = input("Keyword/Phrase: ") + # Start searching the specified folder + search_folder(path, keyword) + +def search_folder(path, keyword): + global contains # Declare the global variable to store found files + # Check if the given path is a directory + if os.path.isdir(path): + # List all files and directories in the specified path + files = os.listdir(path) + # Iterate over each file in the directory + for file in files: + # Construct the full path to the file or directory + full_path = os.path.join(path, file) + + # If the current path is a directory, recursively search inside it + if os.path.isdir(full_path): + search_folder(full_path, keyword) + else: + # Get the file extension and convert it to lowercase + filetype = os.path.splitext(file)[-1].lower() + # Check if the file type is in the allowed extensions + if filetype in extensions: + try: + # Open the file and read its content + with open(full_path, 'r', encoding='utf-8', errors='ignore') as file_: + # Check if the keyword is found in the file content + if keyword in file_.read(): + contains.append(file) # Add the file to the list of found files + print(keyword, "found in", file) # Print the result + except Exception as e: + # Print any errors encountered while reading the file + print(f"Error reading {full_path}: {e}") + else: + # Print an error message if the provided path is not a directory + print(f"{path} is not a directory.") + +# Start the process by calling the change_direct function +change_direct() diff --git a/FileTextSearch/README.md b/FileTextSearch/README.md new file mode 100644 index 00000000..3540b5c5 --- /dev/null +++ b/FileTextSearch/README.md @@ -0,0 +1,26 @@ +# File Text Search Script +## Description +The `FileTextSearch.py` script is a utility designed to search for a specific keyword or phrase within text-based files located in a specified directory. The script searches through files with the following extensions: `.txt`, `.docx`, and `.pdf`. It can recursively search through subdirectories, making it easier to locate documents containing the desired information. +## Features +- Recursive Searching: The script can search within specified subdirectories. +- Keyword Matching: Users can input a keyword or phrase to find within the text files. +- Supported Formats: The script can read `.txt`, `.docx`, and `.pdf` file formats. +## Usage +1. Ensure you have Python installed on your machine. +2. Download the `FileTextSearch.py` script. +3. Open a terminal or command prompt and navigate to the directory where the script is located. +4. Run the script using the following command: +python FileTextSearch.py +5. When prompted, enter the path of the directory you want to search. +Enter path: /path/to/your/directory +6. Enter the keyword or phrase you want to search for in the files. +Keyword/Phrase: your_keyword +7. The script will search through the specified directory and print out the names of any files where the keyword is found. +## Requirements +- Python 3.x +- Basic understanding of file paths in your operating system. +- The script will read text-based files, so ensure the files are not encrypted or password protected. +## License +This script is open-source and free to use. Feel free to modify and distribute as needed. +## Contributing +If you'd like to contribute to this project, please open an issue or submit a pull request with your proposed changes or enhancements. \ No newline at end of file diff --git a/README.md b/README.md index eb760638..813176a7 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,9 @@ More information on contributing and the general code of conduct for discussion | File Encryption Decryption | [File Encryption Decryption](https://github.com/DhanushNehru/Python-Scripts/tree/master/File%20Encryption%20Decryption) | Encrypts and Decrypts files using AES Algorithms for Security purposes. | | File Search | [File_search](https://github.com/debojit11/Python-Scripts/tree/master/File_Search) | A python script that searches a specified folder for all files, regardless of file type, within its directory and subdirectories. | Font Art | [Font Art](https://github.com/DhanushNehru/Python-Scripts/tree/master/Font%20Art) | Displays a font art using Python. | +| File Organizer | [FileOrganizer](https://github.com/DhanushNehru/Python-Scripts/tree/master/FileOrganizer) | Organizes files into different folders according to their file type +| File Renamer | [FileRenamer](https://github.com/DhanushNehru/Python-Scripts/tree/master/FileRenamer) | Bulk renames files with the same start/end +| File Text Search | [FileTextSearch](https://github.com/DhanushNehru/Python-Scripts/tree/master/FileTextSearch) | Searches for a keyword/phrase accross different files | Freelance Helper Program | [freelance-helper](https://github.com/DhanushNehru/Python-Scripts/tree/master/freelance-help-program) | Takes an Excel file with working hours and calculates the payment. | | Get Hexcodes From Websites | [Get Hexcodes From Websites](https://github.com/DhanushNehru/Python-Scripts/tree/master/Get%20Hexcodes%20From%20Websites) | Generates a Python list containing Hexcodes from a website. | | Hand_Volume | [Hand_Volume](https://github.com/DhanushNehru/Python-Scripts/tree/master/Hand%20Volume) | Detects and tracks hand movements to control volume. | From 477f1022231e8c0c10e1dfaddbef76b18130b98d Mon Sep 17 00:00:00 2001 From: Charalampos Deligiannakis <49127082+iHaz32@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:45:03 +0300 Subject: [PATCH 051/127] Add Password Strength Checker script with ML and NN (#349) * Add password strengtch checker source code * Update README.md * Fix README.md * Fix typo in model README.md --- Password Strength Checker/README.md | 27 +++++++ Password Strength Checker/main.py | 8 +++ Password Strength Checker/model/README.md | 15 ++++ .../model/deep_learning_model.h5 | Bin 0 -> 142576 bytes Password Strength Checker/model/model.py | 68 ++++++++++++++++++ Password Strength Checker/model/scaler.pkl | Bin 0 -> 851 bytes .../model/utils/functions.py | 18 +++++ .../model/utils/preprocessing.py | 32 +++++++++ .../model/utils/training.py | 47 ++++++++++++ Password Strength Checker/requirements.txt | 46 ++++++++++++ README.md | 1 + 11 files changed, 262 insertions(+) create mode 100644 Password Strength Checker/README.md create mode 100644 Password Strength Checker/main.py create mode 100644 Password Strength Checker/model/README.md create mode 100644 Password Strength Checker/model/deep_learning_model.h5 create mode 100644 Password Strength Checker/model/model.py create mode 100644 Password Strength Checker/model/scaler.pkl create mode 100644 Password Strength Checker/model/utils/functions.py create mode 100644 Password Strength Checker/model/utils/preprocessing.py create mode 100644 Password Strength Checker/model/utils/training.py create mode 100644 Password Strength Checker/requirements.txt diff --git a/Password Strength Checker/README.md b/Password Strength Checker/README.md new file mode 100644 index 00000000..ea4db086 --- /dev/null +++ b/Password Strength Checker/README.md @@ -0,0 +1,27 @@ +# Password Strength Checker + +## Description +A password strength checker that utilizes machine learning to classify the strength of passwords. This project provides a simple interface for users to input their passwords and receive feedback on their strength based on various criteria. + +## Features +- Classifies password strength into multiple categories. + +## Installation +1. Clone the repository: + ```bash + git clone https://github.com/DhanushNehru/Python-Scripts + cd "Password Strength Checker" + +2. Create and activate a virtual environment: + ```bash + python3 -m venv venv + source venv/bin/activate # On Windows use `venv\Scripts\activate` + +3. Install the required packages: + ```bash + pip install -r requirements.txt + +## Usage +To run the password strength checker: + ```bash + python main.py \ No newline at end of file diff --git a/Password Strength Checker/main.py b/Password Strength Checker/main.py new file mode 100644 index 00000000..2ae79e81 --- /dev/null +++ b/Password Strength Checker/main.py @@ -0,0 +1,8 @@ +from model.model import predict # import model + +def main(): + password_to_test = input("Enter a password to check its strength: ") # get password from terminal + predicted_class = int(predict(password_to_test)) # evaluate password strength + print(f"Password strength classification: {predicted_class} / 2") # output 0 - weak, 1 - moderate, or 2 - strong + +if __name__ == "__main__": main() \ No newline at end of file diff --git a/Password Strength Checker/model/README.md b/Password Strength Checker/model/README.md new file mode 100644 index 00000000..98f3e1d0 --- /dev/null +++ b/Password Strength Checker/model/README.md @@ -0,0 +1,15 @@ +# Password Strength Classification Model + +## Overview +This model is designed to evaluate the strength of passwords using machine learning techniques. It analyzes input passwords and classifies them based on their strength, providing feedback for users to create stronger passwords. + +## Model Architecture +- **Input Layer**: The model accepts passwords as input. +- **Dense Layers**: A series of dense layers with activation functions (e.g., ReLU) process the input features. +- **Output Layer**: The final layer outputs a classification score indicating password strength (e.g., weak - 0, medium - 1, strong - 2). + +## Training +- The model is trained on a labeled dataset of passwords classified by strength. + +## Future improvements +- In feature engineering, columns about the amount of common used passwords (etc. 'password') or common used words should be added and be taken into consideration properly in model training. diff --git a/Password Strength Checker/model/deep_learning_model.h5 b/Password Strength Checker/model/deep_learning_model.h5 new file mode 100644 index 0000000000000000000000000000000000000000..6fd66c9e7f2953a4b42c9c20a95ab689fefe9183 GIT binary patch literal 142576 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�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%0DUb;G)vEg8XI`zV_S>5D)I+n6gCR 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 z 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 literal 0 HcmV?d00001 diff --git a/Password Strength Checker/model/model.py b/Password Strength Checker/model/model.py new file mode 100644 index 00000000..d7255bd1 --- /dev/null +++ b/Password Strength Checker/model/model.py @@ -0,0 +1,68 @@ +# disable debugging messages +def warn(*args, **kwargs): + pass +import warnings +warnings.warn = warn +warnings.filterwarnings("ignore", category=DeprecationWarning) +import os +os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0' +os.environ['TF_CPP_MIN_LOG_LEVEL'] = '1' +from silence_tensorflow import silence_tensorflow +silence_tensorflow("WARNING") + +import pandas as pd +import pickle + +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Dense +from model.utils.functions import calculate_entropy, count_repeats, count_sequential +from model.utils.preprocessing import run_preprocessing +from model.utils.training import run_training + +# run preprocessing and training +# run_preprocessing() # uncomment to run preprocessing +# run_training() # uncomment to train the model + +def prepare_input(password): # function to prepare input features from password + # create a dataframe for a single input + data = { + 'length': [len(password)], # calculate password length + 'lowercase_count': [sum(c.islower() for c in password)], # count lowercase characters + 'uppercase_count': [sum(c.isupper() for c in password)], # count uppercase characters + 'digit_count': [sum(c.isdigit() for c in password)], # count digits + 'special_count': [sum(not c.isalnum() for c in password)], # count special characters + 'entropy': [calculate_entropy(password)], # calculate entropy + 'repetitive_count': [count_repeats(password)], # count repetitive characters + 'sequential_count': [count_sequential(password)] # count sequential characters + } + + with open('model/scaler.pkl', 'rb') as file: # load the fitted scaler from file + scaler = pickle.load(file) + + # convert to dataframe + input_df = pd.DataFrame(data) + + # normalize using the previously fitted scaler + normalized_input = scaler.transform(input_df) + + return pd.DataFrame(normalized_input, columns=input_df.columns) # return normalized input as dataframe + +def predict(password): # function to predict password strength + # load the model + model = Sequential() # create a sequential model + model.add(Dense(128, activation='relu', input_shape=(8,))) # add input layer with 128 neurons + model.add(Dense(64, activation='relu')) # add hidden layer with 64 neurons + model.add(Dense(3, activation='softmax')) # add output layer with softmax activation + + # load trained weights + model.load_weights('model/deep_learning_model.h5') # load weights from the trained model file + + # prepare the input + password_to_test = password # assign password to test + input_features = prepare_input(password_to_test) # prepare input features + + # make the prediction + prediction = model.predict(input_features, verbose=0) # predict using the model + predicted_class = prediction.argmax(axis=-1) # get the predicted class index + + return predicted_class # return the predicted class \ No newline at end of file diff --git a/Password Strength Checker/model/scaler.pkl b/Password Strength Checker/model/scaler.pkl new file mode 100644 index 0000000000000000000000000000000000000000..a7002b2ad1c831d22f765a88473c26532ea87541 GIT binary patch literal 851 zcmaKr+e;Ne9LLYab37;Qc#O<$ROCZOwNT&6NS&yWYbFUF}of?;$S2hFpg|VGbBcH3@2_S1lhz$h&wvbAjUAkXr_dbY#KJf zj!d`*4I~2@O?SQBkRBHEbh0vU9XrbovHX}f7V2bbCJiVgVIlX5?_e?O?n<5dsrMwS ztgPJslec6S6A7#9KF$*l>d0syDx+Dt*^00XZ6wL2V-UXMSk}^=3`J|u$in$@+d{Gi z^@VjhG6;67rBTif5shdqzr~_9YIbcIW}6Vtii$BJ;<<;E|fa^y+j011N^)$D4?-P_{JhkJ_$C(}Ve zYxSL>wl`w`(4}|JvYv{}EjO(N;(w)4%uV*~7^?j?wGs4