From 687443ac87e65260d1e0f8314b9e8c07248d67ef Mon Sep 17 00:00:00 2001 From: kyleoconnell-NIH <102973993+kyleoconnell-NIH@users.noreply.github.com> Date: Thu, 9 May 2024 13:15:18 -0400 Subject: [PATCH] Delete tutorials directory --- tutorials/README.md | 91 - .../notebooks/GWAS/GWAS_coat_color.ipynb | 583 ------ .../notebooks/GenAI/Azure_AI_Studio_README.md | 436 ----- .../notebooks/GenAI/Azure_Open_AI_README.md | 395 ---- tutorials/notebooks/GenAI/LICENSE | 21 - .../GenAI/embedding_demos/acs_embeddings.py | 79 - .../GenAI/embedding_demos/aoai_embeddings.py | 102 - ...ample_azureaisearch_openaichat_zeroshot.py | 99 - .../example_langchain_openaichat_zeroshot.py | 93 - .../example_scripts/workshop_embedding.py | 34 - .../GenAI/example_scripts/workshop_search.py | 41 - .../notebooks/GenAI/microsoft-earnings.csv | 63 - ...reAIStudio_index_structured_notebook.ipynb | 857 --------- ...Studio_index_structured_with_console.ipynb | 413 ---- .../notebooks/AzureAIStudio_langchain.ipynb | 357 ---- .../notebooks/AzureAIStudio_sql_chatbot.ipynb | 678 ------- .../notebooks/AzureOpenAI_embeddings.ipynb | 488 ----- .../GenAI/notebooks/Pubmed_RAG_chatbot | 1664 ----------------- tutorials/notebooks/GenAI/requirements.txt | 12 - .../Hurricane_Irene_(2005).pdf | Bin 331598 -> 0 bytes .../search_documents/Koutros_et_al_2023.pdf | Bin 154729 -> 0 bytes .../New_York_State_Route_373.pdf | Bin 364158 -> 0 bytes .../GenAI/search_documents/Rai_et_al_2023.pdf | Bin 2 -> 0 bytes .../search_documents/Silverman_et_al_2023.pdf | Bin 499132 -> 0 bytes .../aoai_workshop_content.pdf | Bin 752509 -> 0 bytes .../search_documents/grant_data_sub1.txt | 1 - .../search_documents/grant_data_sub2.txt | 1 - .../notebooks/SRADownload/SRA-Download.ipynb | 548 ------ .../SpleenLiverSegmentation/README.md | 49 - .../SpleenSeg_Pretrained-4_27.ipynb | 1017 ---------- .../Spleen_best_metric_model_pretrained.pth | Bin 19303897 -> 0 bytes .../pangolin/pangolin_pipeline.ipynb | 361 ---- .../rnaseq-myco-tutorial-main/LICENSE | 21 - .../rnaseq-myco-tutorial-main/README.md | 2 - .../RNAseq_pipeline.ipynb | 493 ----- .../images/count-workflow.png | Bin 51362 -> 0 bytes .../images/rnaseq-workflow.png | Bin 43798 -> 0 bytes .../images/table-cushman.png | Bin 78018 -> 0 bytes 38 files changed, 8999 deletions(-) delete mode 100644 tutorials/README.md delete mode 100644 tutorials/notebooks/GWAS/GWAS_coat_color.ipynb delete mode 100644 tutorials/notebooks/GenAI/Azure_AI_Studio_README.md delete mode 100644 tutorials/notebooks/GenAI/Azure_Open_AI_README.md delete mode 100644 tutorials/notebooks/GenAI/LICENSE delete mode 100644 tutorials/notebooks/GenAI/embedding_demos/acs_embeddings.py delete mode 100644 tutorials/notebooks/GenAI/embedding_demos/aoai_embeddings.py delete mode 100644 tutorials/notebooks/GenAI/example_scripts/example_azureaisearch_openaichat_zeroshot.py delete mode 100644 tutorials/notebooks/GenAI/example_scripts/example_langchain_openaichat_zeroshot.py delete mode 100644 tutorials/notebooks/GenAI/example_scripts/workshop_embedding.py delete mode 100644 tutorials/notebooks/GenAI/example_scripts/workshop_search.py delete mode 100644 tutorials/notebooks/GenAI/microsoft-earnings.csv delete mode 100644 tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_notebook.ipynb delete mode 100644 tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_with_console.ipynb delete mode 100644 tutorials/notebooks/GenAI/notebooks/AzureAIStudio_langchain.ipynb delete mode 100644 tutorials/notebooks/GenAI/notebooks/AzureAIStudio_sql_chatbot.ipynb delete mode 100644 tutorials/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb delete mode 100644 tutorials/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot delete mode 100644 tutorials/notebooks/GenAI/requirements.txt delete mode 100644 tutorials/notebooks/GenAI/search_documents/Hurricane_Irene_(2005).pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/Koutros_et_al_2023.pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/New_York_State_Route_373.pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/Rai_et_al_2023.pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/Silverman_et_al_2023.pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/aoai_workshop_content.pdf delete mode 100644 tutorials/notebooks/GenAI/search_documents/grant_data_sub1.txt delete mode 100644 tutorials/notebooks/GenAI/search_documents/grant_data_sub2.txt delete mode 100644 tutorials/notebooks/SRADownload/SRA-Download.ipynb delete mode 100644 tutorials/notebooks/SpleenLiverSegmentation/README.md delete mode 100644 tutorials/notebooks/SpleenLiverSegmentation/SpleenSeg_Pretrained-4_27.ipynb delete mode 100644 tutorials/notebooks/SpleenLiverSegmentation/monai_data/Spleen_best_metric_model_pretrained.pth delete mode 100644 tutorials/notebooks/pangolin/pangolin_pipeline.ipynb delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/LICENSE delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/README.md delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/RNAseq_pipeline.ipynb delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/images/count-workflow.png delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/images/rnaseq-workflow.png delete mode 100644 tutorials/notebooks/rnaseq-myco-tutorial-main/images/table-cushman.png diff --git a/tutorials/README.md b/tutorials/README.md deleted file mode 100644 index b1d9668..0000000 --- a/tutorials/README.md +++ /dev/null @@ -1,91 +0,0 @@ ->This repository falls under the NIH STRIDES Initiative. STRIDES aims to harness the power of the cloud to accelerate biomedical discoveries. To learn more, visit https://cloud.nih.gov. - -# Microsoft Azure Tutorial Resources - -NIH Cloud Lab’s goal is to make Cloud easy and accessible for you, so that you can spend less time on administrative tasks and focus more on research. - -Use this repository to learn about how to use Azure by exploring the linked resources and walking through the tutorials. If you are a beginner, we suggest you start with the jumpstart section on the [Cloud Lab website](https://cloud.nih.gov/resources/cloudlab/) before returning here. - ---------------------------------- -## Overview of Page Contents - -+ [Artificial Intelligence](#ai) -+ [Clinical Informatics](#ci) -+ [Medical Imaging](#mi) -+ [Genomics on Azure](#bio) -+ [GWAS](#gwas) -+ [BLAST](#blast) -+ [VCF Query](#vcf) -+ [RNAseq](#rna) -+ [scRNAseq](#sc) -+ [Long Read Sequencing Analysis](#long) -+ [Open Data](#open) - -## **Artificial Intelligence** -Machine learning is a subfield of artificial intelligence that focuses on the development of algorithms and models that enable computers to learn from and make predictions or decisions based on data, without being explicitly programmed. Artificial intelligence and machine learning algorithms are being applied to a variety of biomedical research questions, ranging from image classification to genomic variant calling. Azure offers AI services through Azure AI Studio and Azure Machine Learning. - -See our suite of tutorials to learn more about [Gen AI on Azure](/notebooks/GenAI/) that highlight Azure products such as [Azure AI Studio](/notebooks/GenAI/Azure_AI_Studio_README.md), [Azure OpenAI](/notebooks/GenAI/Azure_Open_AI_README.md) and [Azure AI Search](/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot.ipynb) and external tools like [Langchain](/notebooks/GenAI/notebooks/AzureAIStudio_langchain.ipynb). These notebooks walk you through how to deploy, train, and query models, as well as how to implement techniques like [Retrieval-Augmented Generation (RAG)](/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot.ipynb). If you are interested in configuring a model to work with structured data like csv or json files, we've created tutorials that walk you through how to index your csv using the [Azure UI](/docs/create_index_from_csv.md) and query your database using a [notebook within Azure ML](/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_with_console.ipynb). We also have another [tutorial that runs all the necessary steps directly from a notebook](/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_notebook.ipynb). - - ## **Clinical Informatics with FHIR** -Azure Health Data Services is a set of services that enables you to store, process, and analyze medical data in Azure. These services are designed to help organizations quickly connect disparate health data sources and formats, such as structured, imaging, and device data, and normalize it to be persisted in the cloud. At its core, Azure Health Data Services possesses the ability to transform and ingest data into FHIR (Fast Healthcare Interoperability Resources) format. This allows you to transform health data from legacy formats, such as HL7v2 or CDA, or from high-frequency IoT data in device proprietary formats to FHIR. This makes it easier to connect data stored in Azure Health Data Services with services across the Azure ecosystem, like Azure Synapse Analytics, and Azure Machine Learning (Azure ML). - -Azure Health Data Services includes support for multiple health data standards for the exchange of structured data, and the ability to deploy multiple instances of different service types (FHIR, DICOM, and MedTech) that seamlessly work with one another. Services deployed within a workspace also share a compliance boundary and common configuration settings. The product scales automatically to meet the varying demands of your workloads, so you spend less time managing infrastructure and more time generating insights from health data. - -Copying healthcare data stored in Azure FHIR Server to Synapse Analytics allows researchers to leverage a cloud-scale data warehousing and analytics tool to extract insights from their data as well as build scalable research pipelines. -For information on how to perform this export and downstream analytics, please visit [this repository](https://github.com/MicrosoftDocs/azure-docs/blob/main/articles/healthcare-apis/fhir/copy-to-synapse.md). - -You can also see hands-on examples of using [FHIR on Azure](https://github.com/microsoft/genomicsnotebook/tree/main/fhirgenomics), but note that you will need to supply your own VCF files as these are not provided with the tutorial content. - -## **Medical Imaging Analysis** -Medical imaging analysis requires the analysis of large image files and often requires elastic storage and accelerated computing. Microsoft Azure offers cloud-based medical imaging analysis capabilities through its Azure Healthcare APIs and Azure Medical Imaging solutions. Azure's DICOM Service allows for the secure storage, management, and processing of medical images in the cloud, using industry standard DICOM (Digital Imaging and Communications in Medicine) format. The DICOM Service provides features like high availability, disaster recovery, and scalable storage options, making it an ideal solution for pipelines that need to store, manage, and analyze large amounts of medical imaging data. In addition, the server integrates with other Azure services like Azure ML, facilitating the use of advanced machine learning algorithms for image analysis tasks such as object detection, segmentation, and classification. Read about how to deploy the service [here](https://learn.microsoft.com/en-us/azure/healthcare-apis/dicom/deploy-dicom-services-in-azure). - -Microsoft has several medical imaging notebooks that showcase different medical imaging use-cases on Azure Machine Learning. These notebooks demonstrate various data science techniques such as manual model development with PyTorch, automated machine learning, and MLOPS-based examples for automating the machine learning lifecycle in medical use cases, including retraining. -These notebooks are available [here](https://github.com/Azure/medical-imaging). Make sure you select a kernel that includes Pytorch else the install of dependencies can be challenging. Note also that you need to use a GPU VM for most of the notebook cells, but you can create several compute environments and switch between them as needed. Be sure to shut them off when you are finished. - -For Cloud Lab users interested in multi-modal clinical informatics, DICOMcast provides the ability to synchronize data from a DICOM service to a FHIR service, allowing users to integrate clinical and imaging data. DICOMcast expands the use cases for health data by supporting both a streamlined view of longitudinal patient data and the ability to effectively create cohorts for medical studies, analytics, and machine learning. For more information on how to utilize DICOMcast please visit Microsoft’s [documentation](https://learn.microsoft.com/en-us/azure/healthcare-apis/dicom/dicom-cast-overview) or the open-source [GitHub repository](https://github.com/microsoft/dicom-server/blob/main/docs/quickstarts/deploy-dicom-cast.md). - -For users hoping to train deep learning models on imaging data, InnerEye-DeepLearning (IE-DL) is a toolbox that Microsoft developed for easily training deep learning models on 3D medical images. Simple to run both locally and in the cloud with Azure Machine Learning, it allows users to train and run inference on the following: -• Segmentation models -• Classification and regression models -• Any PyTorch Lightning model, via a bring-your-own-model setup -This project exists in a separate [GitHub repository](https://github.com/microsoft/InnerEye-DeepLearning). - -## **Microsoft Genomics** -Microsoft has several genomics-related offerings that will be useful to many Cloud Lab users. For a broad overview, visit the [Microsoft Genomics Community site](https://microsoft.github.io/Genomics-Community/index.html). You can also get an overview of different execution options from [this blog](https://techcommunity.microsoft.com/t5/healthcare-and-life-sciences/genomic-workflow-managers-on-microsoft-azure/ba-p/3747052), and a detailed analysis for Nextflow with AWS Batch at [this blog](https://techcommunity.microsoft.com/t5/healthcare-and-life-sciences/rna-sequencing-analysis-on-azure-using-nextflow-configuration/ba-p/3738854). We highlight a few key services here: -+ [Genomics Notebooks](https://github.com/microsoft/genomicsnotebook): These example notebooks highlight many common use cases in genomics research. The Bioconductor/Rstudio notebook will not work in Cloud Lab. To run Rstudio, look at [Posit Workbench from the Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/rstudio-5237862.rstudioserverprostandard). -+ [Cromwell on Azure](https://github.com/microsoft/CromwellOnAzure): Documentation on how to spin up the resources needed to run Cromwell on Azure. Note that this service will not work within Cloud Lab because you need high-level permissions, but we list it here for demonstration purposes. -+ [Microsoft Genomics](https://learn.microsoft.com/en-us/azure/genomics/quickstart-run-genomics-workflow-portal): Run BWA and GATK using this managed service. Note that it uses Python 2.7 and thus is not compatible with AzureML (which uses Python 3), but you can run it from any other shell environment. -+ [Nextflow on Azure](https://microsoft.github.io/Genomics-Community/mydoc_nextflow.html): Run Nextflow workflows using Azure Batch. -+ [NVIDIA Parabricks for Secondary Genomics Analysis on Azure](https://techcommunity.microsoft.com/t5/healthcare-and-life-sciences/benchmarking-the-nvidia-clara-parabricks-for-secondary-genomics/ba-p/3722434). Follow this guide to run Parabricks on a VM by pulling the Docker container directly from NVIDIA. - -## **Genome Wide Association Studies** -Genome-wide association studies (GWAS) are large-scale investigations that analyze the genomes of many individuals to identify common genetic variants associated with traits, diseases, or other phenotypes. -- This [NIH CFDE written tutorial](https://training.nih-cfde.org/en/latest/Bioinformatic-Analyses/GWAS-in-the-cloud -) walks you through running a simple GWAS on AWS, thus we converted it to Azure in [this notebook](/notebooks/GWAS). Note that the CFDE page has a few other bioinformatics related tutorials like BLAST and Illumina read simulation. -- This blog post [illustrates some of the costs associated](https://techcommunity.microsoft.com/t5/azure-high-performance-computing/azure-to-accelerate-genome-wide-analysis-study/ba-p/2644120) with running GWAS on Azure - -## **NCBI BLAST+** -NCBI BLAST (Basic Local Alignment Search Tool) is a widely used bioinformatics program provided by the National Center for Biotechnology Information (NCBI) that compares nucleotide or protein sequences against a large database to identify similar sequences and infer evolutionary relationships, functional annotations, and structural information. -- [This Microsoft Blog](https://techcommunity.microsoft.com/t5/azure-high-performance-computing/running-ncbi-blast-on-azure-performance-scalability-and-best/ba-p/2410483) explains how to optimize BLAST analyses on Azure VMs. Feel free to install BLAST+ on a VM or an AzureML notebook and run queries there. - -## **Query a VCF file in Azure Synapse** -- You can use SQL to rapidly query a VCF file in Azure Synapse. The requires converting the file from VCF to Parquet format, a common format for databases. Read more about how to do this in Azure on [this Microsoft blog](https://techcommunity.microsoft.com/t5/healthcare-and-life-sciences/genomic-data-in-parquet-format-on-azure/ba-p/3150554). Although the notebooks for this tutorial are bundled with the other genomics notebooks, to get them to work you will need to use Azure Databricks or Synapse Analytics, not AzureML. - -## **RNAseq** -RNA-seq analysis is a high-throughput sequencing method that allows the measurement and characterization of gene expression levels and transcriptome dynamics. Workflows are typically run using workflow managers, and final results can often be visualized in notebooks. -- You can run this [Nextflow on Azure tutorial](https://microsoft.github.io/Genomics-Community/mydoc_nextflow.html) for RNAseq a variety of ways on Azure. Following the instructions outlined above, you could use Virtual Machines, Azure Machine Learning, or Azure Batch. -- For a notebook version of a complete RNAseq pipeline from Fastq to Salmon quantification from the NIGMS Sandbox Program use this [notebook](/notebooks/rnaseq-myco-tutorial-main), which we re-wrote to work on Azure. - -## **Single Cell RNAseq** -Single-cell RNA sequencing (scRNA-seq) is a technique that enables the analysis of gene expression at the individual cell level, providing insights into cellular heterogeneity, identifying rare cell types, and revealing cellular dynamics and functional states within complex biological systems. -- This [NVIDIA blog](https://developer.nvidia.com/blog/accelerating-single-cell-genomic-analysis-using-rapids/) details how to run an accelerated scRNAseq pipeline using RAPIDS. You can find a link to the GitHub that has lots of example notebooks [here](https://github.com/clara-parabricks/rapids-single-cell-examples). For each example use case they show some nice benchmarking data with time and cost for CPU vs. GPU machine types on AWS. You will see that most runs cost less than $1.00 with GPU machines (priced on AWS). If you want a CPU version that users Scanpy you can use this [notebook](https://github.com/clara-parabricks/rapids-single-cell-examples/blob/master/notebooks/hlca_lung_cpu_analysis.ipynb). Pay careful attention to the environment setup as there are a lot of dependencies for these notebooks. Create a conda environment in the terminal, then run the notebook. Consider using [mamba](https://github.com/mamba-org/mamba) to speed up environment creation. We created a [guide](/docs/create_conda_env.md) for conda environment set up as well. - -## **Long Read Sequence Analysis** -Long read DNA sequence analysis involves analyzing sequencing reads typically longer than 10 thousand base pairs (bp) in length, compared with short read sequencing where reads are about 150 bp in length. -Oxford Nanopore has a pretty complete offering of notebook tutorials for handling long read data to do a variety of things including variant calling, RNAseq, Sars-Cov-2 analysis and much more. Access the notebooks [here](https://labs.epi2me.io/nbindex/) and on [GitHub](https://github.com/epi2me-labs). These notebooks expect you are running locally and accessing the epi2me notebook server. To run them in Cloud Lab, skip the first cell that connects to the server and then the rest of the notebook should run correctly, with a few tweaks. Oxford Nanopore also offers a host of [Nextflow workflows](https://labs.epi2me.io/wfindex/) that will allow you to run a variety of long read pipelines. - -## **Open Data** -These publicly available datasets can save you time on data discovery and preparation by being curated and ready to use in your workflows. -+ The [COVID-19 Data Lake](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-covid-19-data-lake) contains COVID-19 related datasets from various sources. It covers testing and patient outcome tracking data, social distancing policy, hospital capacity and mobility. -+ In response to the COVID-19 pandemic, the Allen Institute for AI has partnered with leading research groups to prepare and distribute the [COVID-19 Open Research Dataset (CORD-19)](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-covid-19-open-research?tabs=azure-storage). This dataset is a free resource of over 47,000 scholarly articles, including over 36,000 with full text, about COVID-19 and the coronavirus family of viruses for use by the global research community. This dataset mobilizes researchers to apply recent advances in natural language processing to generate new insights in support of the fight against this infectious disease. -+ [The Genomics Data Lake](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-genomics-data-lake) provides various public datasets that you can access for free and integrate into your genomics analysis workflows and applications. The datasets include genome sequences, variant info, and subject/sample metadata in BAM, FASTA, VCF, CSV file formats: [Illumina Platinum Genomes](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-illumina-platinum-genomes), [Human Reference Genomes](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-human-reference-genomes), [ClinVar Annotations](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-clinvar-annotations), [SnpEff](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-snpeff), [Genome Aggregation Database (gnomAD)](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-gnomad), [1000 Genomes](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-1000-genomes), [OpenCravat](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-open-cravat), [ENCODE](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-encode), [GATK Resource Bundle](https://learn.microsoft.com/en-us/azure/open-datasets/dataset-gatk-resource-bundle). diff --git a/tutorials/notebooks/GWAS/GWAS_coat_color.ipynb b/tutorials/notebooks/GWAS/GWAS_coat_color.ipynb deleted file mode 100644 index fd6bf6d..0000000 --- a/tutorials/notebooks/GWAS/GWAS_coat_color.ipynb +++ /dev/null @@ -1,583 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7a244bb3", - "metadata": {}, - "source": [ - "# Runing Genome Wide Association Studies in the cloud" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Overview\n", - "Genome Wide Association Study analyses are conducted via the command line using mostly BASH commands, and then plotting often done using Python or R. Here, we adapted an [NIH CFDE tutorial](https://training.nih-cfde.org/en/latest/Bioinformatic-Analyses/GWAS-in-the-cloud/background/) and fit it to a notebook. We have greatly simplified the instructions, so if you need or want more details, look at the full tutorial to find out more.\n", - "\n", - "Most of this notebook is bash, but expects that you are using a Python kernel, until step 3, plotting, you will need to switch your kernel to R." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Prerequisites\n", - "We assume you have provisioned a compute environment in Azure ML Studio" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Learning objectives\n", - "+ Learn how to run GWAS analysis and visualize results in Azure AI Studio" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "id": "8fbf6304", - "metadata": {}, - "source": [ - "### Download the data\n", - "Use %%bash to denote a bash block. You can also use '!' to denote a single bash command within a Python notebook" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ec900bd", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "mkdir GWAS\n", - "curl -LO https://de.cyverse.org/dl/d/E0A502CC-F806-4857-9C3A-BAEAA0CCC694/pruned_coatColor_maf_geno.vcf.gz\n", - "curl -LO https://de.cyverse.org/dl/d/3B5C1853-C092-488C-8C2F-CE6E8526E96B/coatColor.pheno" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4d43ae73", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "mv *.gz GWAS\n", - "mv *.pheno GWAS\n", - "ls GWAS" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "28aadbf8", - "metadata": {}, - "source": [ - "### Install packages\n", - "Here we install mamba, which is faster than conda. You could also skip this install and just use conda since that is preinstalled in the kernel." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b3ba3eef", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "curl -L -O https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh\n", - "bash Mambaforge-$(uname)-$(uname -m).sh -b -p $HOME/mambaforge" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ae20d01c", - "metadata": { - "gather": { - "logged": 1686580882939 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#add to your path\n", - "import os\n", - "os.environ[\"PATH\"] += os.pathsep + os.environ[\"HOME\"]+\"/mambaforge/bin\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b219074a", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "! mamba install -y -c bioconda plink vcftools" - ] - }, - { - "cell_type": "markdown", - "id": "013d960d", - "metadata": {}, - "source": [ - "### Make map and ped files from the vcf file to feed into plink" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e91c7a01", - "metadata": { - "gather": { - "logged": 1686579597925 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "cd GWAS" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9b770f7f", - "metadata": { - "gather": { - "logged": 1686579600325 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "ls GWAS" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6570875d", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "! vcftools --gzvcf pruned_coatColor_maf_geno.vcf.gz --plink --out coatColor" - ] - }, - { - "cell_type": "markdown", - "id": "b9a38761", - "metadata": {}, - "source": [ - "### Create a list of minor alleles.\n", - "For more info on these terms, look at step 2 at https://training.nih-cfde.org/en/latest/Bioinformatic-Analyses/GWAS-in-the-cloud/analyze/" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6c868a67", - "metadata": { - "gather": { - "logged": 1686581972147 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#unzip vcf\n", - "! vcftools --gzvcf pruned_coatColor_maf_geno.vcf.gz --recode --out pruned_coatColor_maf_geno" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e11f991", - "metadata": { - "gather": { - "logged": 1686581979545 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#create list of minor alleles\n", - "! cat pruned_coatColor_maf_geno.recode.vcf | awk 'BEGIN{FS=\"\\t\";OFS=\"\\t\";}/#/{next;}{{if($3==\".\")$3=$1\":\"$2;}print $3,$5;}' > minor_alleles" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8cff47e3", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "! head minor_alleles" - ] - }, - { - "cell_type": "markdown", - "id": "56d901c7", - "metadata": {}, - "source": [ - "### Run quality controls" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dafa14a6", - "metadata": { - "gather": { - "logged": 1686582023237 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#calculate missingness per locus\n", - "! plink --file coatColor --make-pheno coatColor.pheno \"yellow\" --missing --out miss_stat --noweb --dog --reference-allele minor_alleles --allow-no-sex --adjust" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5cf5f51b", - "metadata": { - "gather": { - "logged": 1686582030150 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#take a look at lmiss, which is the per locus rates of missingness\n", - "! head miss_stat.lmiss" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "915bb263", - "metadata": { - "gather": { - "logged": 1686582034753 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#peek at imiss which is the individual rates of missingness\n", - "! head miss_stat.imiss" - ] - }, - { - "cell_type": "markdown", - "id": "4c11ca71", - "metadata": {}, - "source": [ - "### Convert to plink binary format" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3b8f2d7f", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "! plink --file coatColor --allow-no-sex --dog --make-bed --noweb --out coatColor.binary" - ] - }, - { - "cell_type": "markdown", - "id": "e36f6cd7", - "metadata": {}, - "source": [ - "### Run a simple association step (the GWAS part!)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f926ef9b", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "! plink --bfile coatColor.binary --make-pheno coatColor.pheno \"yellow\" --assoc --reference-allele minor_alleles --allow-no-sex --adjust --dog --noweb --out coatColor" - ] - }, - { - "cell_type": "markdown", - "id": "b397d484", - "metadata": {}, - "source": [ - "### Identify statistical cutoffs\n", - "This code finds the equivalent of 0.05 and 0.01 p value in the negative-log-transformed p values file. We will use these cutoffs to draw horizontal lines in the Manhattan plot for visualization of haplotypes that cross the 0.05 and 0.01 statistical threshold (i.e. have a statistically significant association with yellow coat color)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b94e1e2a", - "metadata": { - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "%%bash\n", - "unad_cutoff_sug=$(tail -n+2 coatColor.assoc.adjusted | awk '$10>=0.05' | head -n1 | awk '{print $3}')\n", - "unad_cutoff_conf=$(tail -n+2 coatColor.assoc.adjusted | awk '$10>=0.01' | head -n1 | awk '{print $3}')" - ] - }, - { - "cell_type": "markdown", - "id": "1f52e97c", - "metadata": {}, - "source": [ - "### Plotting\n", - "In this tutorial, plotting is done in R. Azure gets a bit funny about running these R commands, so we recommend just runnning the rest of the commands in the Terminal. Run `R` before running the commands. Otherwise you can just download the inputs and run locally in R studio." - ] - }, - { - "cell_type": "markdown", - "id": "effb5acd", - "metadata": {}, - "source": [ - "### Install qqman" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "60feed89", - "metadata": { - "gather": { - "logged": 1686582094642 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "install.packages('qqman', contriburl=contrib.url('http://cran.r-project.org/'))" - ] - }, - { - "cell_type": "markdown", - "id": "d3f1fcd2", - "metadata": {}, - "source": [ - "### Run the plotting function" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a7e8cd2b", - "metadata": { - "gather": { - "logged": 1686584355516 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "#make sure you are still CD in GWAS, when you change kernel it may reset to home\n", - "setwd('GWAS')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7946a3a7", - "metadata": { - "gather": { - "logged": 1686584356532 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "require(qqman)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0d28ef2c", - "metadata": { - "gather": { - "logged": 1686584364339 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "data=read.table(\"coatColor.assoc\", header=TRUE)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e5207be", - "metadata": { - "gather": { - "logged": 1686584368241 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "data=data[!is.na(data$P),]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6330b1e0", - "metadata": { - "gather": { - "logged": 1686584371278 - }, - "vscode": { - "languageId": "r" - } - }, - "outputs": [], - "source": [ - "manhattan(data, p = \"P\", col = c(\"blue4\", \"orange3\"),\n", - " suggestiveline = 12,\n", - " genomewideline = 15,\n", - " chrlabs = c(1:38, \"X\"), annotateTop=TRUE, cex = 1.2)" - ] - }, - { - "cell_type": "markdown", - "id": "26787d84", - "metadata": {}, - "source": [ - "In our graph, haplotypes in four parts of the genome (chromosome 2, 5, 28 and X) are found to be associated with an increased occurrence of the yellow coat color phenotype.\n", - "\n", - "The top associated mutation is a nonsense SNP in the gene MC1R known to control pigment production. The MC1R allele encoding yellow coat color contains a single base change (from C to T) at the 916th nucleotide." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusions\n", - "You learned here how to run and visualize GWAS results using a notebook in Azure ML Studio." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Clean Up\n", - "Make sure you stop your compute instance and if desired, delete the resource group associated with this tutorial." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernel_info": { - "name": "ir" - }, - "kernelspec": { - "display_name": "R", - "language": "R", - "name": "ir" - }, - "language_info": { - "codemirror_mode": "r", - "file_extension": ".r", - "mimetype": "text/x-r-source", - "name": "R", - "pygments_lexer": "r", - "version": "4.2.2" - }, - "microsoft": { - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/notebooks/GenAI/Azure_AI_Studio_README.md b/tutorials/notebooks/GenAI/Azure_AI_Studio_README.md deleted file mode 100644 index 8c5573b..0000000 --- a/tutorials/notebooks/GenAI/Azure_AI_Studio_README.md +++ /dev/null @@ -1,436 +0,0 @@ -# Azure AI Studio Studio -Microsoft Azure migrated the AI front end from Azure OpenAI to Azure AI Studio. - -✨ The following tutorial was modified from this excellent [Microsoft workshop](https://github.com/t-cjackson/AOAI-FED-CIV-Workshop) developed by [Cameron Jackson](https://github.com/t-cjackson). ✨ - -Welcome to this repository, a comprehensive collection of examples that will help you chat with your data using the Azure OpenAI Studio Playground, create highly efficient large language model prompts, and build Azure OpenAI embeddings. - -The purpose of this workshop is to equip participants with the necessary skills to make the most out of the Azure OpenAI Playground, Prompt Engineering, and Azure OpenAI Embeddings in Python. You can view in-depth info on these topics in the [workshop slides](/notebooks/GenAI/search_documents/aoai_workshop_content.pdf). - -You can also learn a lot about the details of using Azure AI at this [site](https://azure.microsoft.com/en-us/products/ai-studio). - -We recommend you 1) go through the steps in this README, 2) complete the general notebook called `notebooks/AzureOpenAI_embeddings.ipynb`, then 3) explore the other notebooks at [this directory](/notebooks/GenAI/notebooks) - -## Overview of Page Contents -+ [Azure AI Playground Prerequisites](#Azure-OpenAI-Playground-Prerequisites) -+ [Chat Playground Navigation](#Chat-Playground-Navigation) -+ [Upload your own data and query over it](#Upload-your-own-data-and-query-over-it) -+ [Prompt Engineering Best Practices](#Prompt-Engineering-Best-Practices) -+ [Azure OpenAI Embeddings](#Azure-OpenAI-Embeddings) -+ [Additional Resources](#Additional-Resources) - -## Azure OpenAI Playground Prerequisites - -Navigate to Azure AI Studio. The easiest way is to search at the top of the page. - - ![search for azure openai](/docs/images/1_azure_ai_studio.png) - -Click new Azure AI. - - ![click to open azure open ai](/docs/images/2_click_new_azureai.png) - -Fill out the necessary information. Create a new Resource Group if needed. Click **Review and Create**. - - ![fill in the info](/docs/images/3_fill_form_azureai.png) - -Once the resource deploys, click **go to resource**. - - ![go to resource](/docs/images/4_go_to_resource.png) - -Now click **Go to Azure AI Studio**. You can also view your access keys at the bottom of the page. - - ![connect to OpenAI UI](/docs/images/5_launch_ai_studio.png) - -Before diving into the UI, stop and watch [this 14 minute overview video](https://www.youtube.com/watch?v=Qes7p5w8Tz8) to learn how to take full advantage of the Studio. We won't cover every option in this tutorial, but feel free to explore! - -When ready, go to **Build** and then click **+ New Project**. - - ![select new project](/docs/images/6_select_new_project.png) - -Fill in the info with the resource name and relevant information. Make sure you put your resource in the same resource group and region as your other Azure AI resources/environments. Then click **Create a Project**. - - ![create new project and resource](/docs/images/7_create_new_project.png) - -When ready, select your project. Now go to **Build** then **Playground**. - -Next, you need to deploy model to power your chat bot. - -## Deploy a model - -On the left navigation panel, click **Deployments**, then click **Create** on the next screen. - - ![Click Models](/docs/images/8_create_model.png) - -Select your model of choice. Here we select gpt-4. - - ![select your model](/docs/images/9_select_model.png) - -Name your deployment and then click **Deploy**. - - ![deploy your model](/docs/images/10_name_and_deploy.png) - -Now under Deployments you should see your model. Feel free to deploy other models here, but be aware that you will pay for those deployed models. - - ![model is deployed](/docs/images/11_model_is_deployed.png) - -Run a quick test to ensure our deployment is acting as expected. Navigate to `Playground`, add an optional system message (we will cover this more later), and then type `Hello World` in the chat box. If you get a response, things are working well! Double check that on the far right it shows the correct deployment. - - ![test model](/docs/images/12_test_hello_world.png) - -Now we will look at [adding and querying over your own data](#Upload-your-own-data-and-query-over-it) and then review [prompt engineering best practices](#prompt-engineering-best-practices) using a general GPT model. - -## Chat Playground Navigation - -If you have not already (A) Navigate to the Chat Playground. Here we will walk through the various options available to you. First, you can specify a `System Message` which tells the model what context with which to respond to inquiries. To modify this, (B) select `System message`, then (B) input a [System Message](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/system-message) in the prompt box, then (D) click **Apply Changes**. - -On the next tab over, you can (A) add your own data, which we dive into in the [next section](#Upload-your-own-data-and-query-over-it). In the middle of the page is where you actually interact with the model (B) through the chat prompts. Always (C) clear the chat after each session. - -On the far right under *Configuration*, you can modify which model you are deploying, which allows you to switch between different model deployments depending on the context. You can also modify the model's parameters on the same tab. - - ![modify deployment](/docs/images/19_deployment.png) - -Finally, you can select the `parameters` tab to modify the model parameters. Review [this presentation](/notebooks/GenAI/search_documents/aoai_workshop_content.pdf) to learn more about the parameters. - - ![modify parameters](/docs/images/20_parameters.png) - -Finally, click on **Prompt Samples** along the top and explore a few of these example prompts. - - ![modify parameters](/docs/images/13_prompt_examples.png) - - -## Upload your own data and query over it - -For an in-depth overview of adding your own data, check out this [Microsoft documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line&pivots=programming-language-studio). We give a quick start version here. - -Now, if you want to add your own data and query it, keep going here. If you want to jump ahead to prompt engineering with LLMs, jump down to [Prompt Engineering Best Practices](#prompt-engineering-best-practices). - -Within this repo there is a directory called `search_documents`. This directory contains a few PDFs that we will upload and query over related to [Immune Response to Mpox in a Woman Living with HIV](https://www.niaid.nih.gov/news-events/immune-response-mpox) and the [DCEG Diesel Exhaust in Minors Study](https://dceg.cancer.gov/news-events/news/2023/dems-ii). - -We are going to upload these PDFs to an Azure Storage Account and then add them to our Azure OpenAI workspace. Note that there are [upload limits](https://learn.microsoft.com/en-us/azure/ai-services/openai/quotas-limits#quotas-and-limits-reference) on the number and size of documents you can query within Azure OpenAI, but sure to read these before getting started. For example, you can only query over a max of 30 documents and/or 1 GB of data. You can only upload the datatypes [listed below] [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/use-your-data#data-formats-and-file-types), and will have the best results with markdown files. - -+ `.txt` -+ `.md` -+ `.html` -+ Microsoft Word files -+ Microsoft PowerPoint files -+ PDF - -Follow [this guide](/docs/create_storage_account.md) to create and upload to a storage account. Use a separate browswer window so that you can easily get back to Azure OpenAI. - -Once you have uploaded your PDFs (or other datatypes if you are trying that), navigate back to the `Playground`, select `Add your data` then click **Add a data source**. - - ![Add data source image](/docs/images/14_add_your_data.png) - -Select `Azure Blob Storage`, and then the correct `Storage Account` and `Container`. If this is your first time indexing documents, for `Select Azure AI Search resource` click **Create a new AI Search resource** which will open a new window. You can add vector search to your AI Search resource, but you will need to first deploy the embedding model for it to be available. - - ![select data source](/docs/images/15_point_to_data.png) - -If needed, create the new Azure AI Search resource. Make sure you delete this when you are finished with Azure AI because it will accrue charges over time. - - ![create cog search](/docs/images/7_cog_search_resource.png) - -Now select your newly made Azure AI Search (formally know as Cognitive Search) resource, and click **Next**. You can select to search with either [Vector](https://learn.microsoft.com/en-us/azure/search/vector-search-overview) or [Hybrid](https://learn.microsoft.com/en-us/azure/search/hybrid-search-overview) search. - - ![choose keyword](/docs/images/16_hybrid_search.png) - -On the last page, click **Save and close**. It will now take a few minutes to index your updated data. Read more [here](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search) about how Azure AI Search is working behind the scenes. - - ![Save and close](/docs/images/17_save_and_close.png) - -Once it is complete, you should see your data source listed. - -Also check that the index is complete by viewing your AI Search resource, and going to `AI Search` on the left. - - ![Cog Search](/docs/images/18_check_ai_search.png) - -Now select your resource, select **indexes**, and then ensure that the number of documents listed is greater then 0. - - ![Cog Search](/docs/images/15_check_index.png) - -Now let's got back to the Playground and run some example queries of our custom data set. Feel free to modify and experiment. After reading the prompt engineering section below, return to this section and see how you can improve these examples. If you get errors after adding your data, try to refresh the page, and if all else fails, send us an email at CloudLab@nih.gov. - -``` -Summarize each of the documents I uploaded in a single paragraph, listing the title, the authors, followed by a five sentence summary for each. Give a new line after each summary. -``` -``` -What were some of the phenotypic presentations of MPOX on patients with HIV? -``` -``` -Are the phenotypic effects of MPOX the same for a patient with HIV and other patients? -``` -``` -Describe the primary findings of the Diesel Exhaust in Miners Study? -``` -``` -Does exposure to Diesel exhaust increase your risk for lung cancer? What about other cancers? Keep your response to one sentence for each of these queries. -``` - - ![search custom data files](/docs/images/16_search_custom_data.png) - -### Bonus, try uploading the grant data in the search_documents and run a few queries -Follow the instructions above for the two files in search_documents called `grant_data_sub1.txt` and `grant_data_sub2.txt`. These data were produced by searching [NIH Reporter](https://reporter.nih.gov/) for NCI-funded projects from fiscal year 2022-2024. The data were downloaded as a csv, converted to txt using Excel, then split in half using a very simple `head -2500 data.txt > grant_data_sub1.txt` and `tail -2499 data.txt > grant_data_sub2.txt`. The reason we split the data is that Azure has an upload limit of 16 MB and the downloaded file was over 30MB. If you are downloading your own data be mindful of these limits and split your files as necessary. - -Once the data is uploaded, try adding a system message like the following: -``` -Pretend to be a Program Officer at the National Institutes of Health in the National Cancer Institute. Your job is to review and summarize funded opportunities. Respond in a professional manner. -``` -Now try some prompts like these: - -``` -What funding years are included in the data I provided? -``` -``` -Based on the Project Abstract, Project Title, and public health relevance please list the Project number of all projects related to women's health research and provide an summary of the women's health relevance for each. -``` -``` -Based on the Project Abstracts, what were the most commonly funded research areas in Fiscal Year 2022? -``` - -## Prompt Engineering Best Practices -First, review [this summary of prompt engineering](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/prompt-engineering) from Microsoft. - -### Write Clear Instructions - -1. Alter the system message to reply with a document that includes a playful comment or joke in each paragraph when responding to inquiries concerning writing assistance. This format should only be used for writing-related questions - -Add the following in the System Message box (SYSTEM:) -``` -You are a comedian English professor at the University of Giggles. When I ask for help to write something, you will reply with a document that contains at least one joke or playful comment. -``` -Add this query to the chat prompt box (QUERY:). -``` -Write a thank you note to my steel bolt vendor for getting a delivery in on time with short notice. This made it possible for my company to deliver an important order. -``` -Add the following to the system message, directing the LLM to only answer questions that involve writing assistance and then rerun the original query. -``` -If the user query does not have "write" in it, respond I do not know truthfully. -``` -2. Modify the system message by adding the prefix "Summary:" which should summarize the paragraph given, delimited with XML tags. Following the summary, the system should translate the paragraph from English to Spanish and add the prefix "Translation:". -To accomplish these tasks, the following steps should be taken: - 1. Identify the paragraph to be summarized, which should be delimited by XML tags. - 2. Generate a summary of the paragraph. - 3. Add the prefix "Summary:" to the beginning of the summary. - 4. Translate the paragraph from English to Spanish. - 5. Add the prefix "Translation:" to the beginning of the translated paragraph. - -SYSTEM: -``` -You will be given a paragraph delimited by XML tags. Use the following step-by-step sequence to respond to user inputs. - - Step 1) The user will provide you with a paragraph delimited by XML tags. Summarize the paragraph in one sentence with a prefix “Summary:” - Step 2) Translate the summary from Step 1 into Spanish, with a prefix “Translation:” -``` -QUERY: -``` - Artificial intelligence (AI) refers to the simulation of human intelligence in machines that are designed to perform tasks that normally require human intelligence, such as learning, problem-solving, and decision-making. AI technology uses algorithms and statistical models to analyze data and make predictions and can be applied to a wide range of fields, including healthcare, finance, and transportation. AI is a rapidly growing field that has the potential to revolutionize many industries by increasing efficiency and productivity. However, as with any technology, there are also concerns about the ethical implications of AI, such as job displacement and privacy concerns. -``` - -Note: When implementing the above example, you might encounter a problem in Step 2 of the prompt where the model translates the entire paragraph instead of the single sentence summary. This issue is likely to arise when using the gpt-35-turbo model, primarily due to its limitations in reasoning capabilities, which impact its translation proficiency. A solution to this minor glitch is the gpt-4 model, which is designed to reason more effectively than the gpt-35-turbo model. - -1. Revise the model to classify the text it is given as either positive, neutral or negative. Once classified, have the LLM recognize the adjective it used to classify the text. Provide an example to the assitant for the LLM to comprehend tasks. - -SYSTEM -``` -Classify the text as either positive, neutral, or negative. Then find the adjective that allows you to classify the text. Follow the example to respond. - - USER: The movie was awesome! - - ASSISTANT: Positive. The adjective here is: awesome. - - USER: The movie was terrible. - - ASSISTANT: Negative. The adjective here is: terrible. - - USER: The movie was ok. - - ASSISTANT: Neutral. The adjective here is: ok. - - QUERY: I can’t wait to go to the beach. -``` - -### Providing Reference Text - -4. Revise the system message to create four bullet points outlining the key principles of the provided text delimited by triple quotes. -To accomplish this, the following steps should be taken: - 1. Identify the text to be analyzed, which should be delimited by triple quotes. - 2. Analyze the text to determine the key principles. - 3. Generate four bullet points that succinctly summarize each principle. - 4. Display the bullet points in the system message. - -SYSTEM: -``` -You will be given text delimited by triple quotes. Create 4 bullet points on the key principles of the text. Answer in the following format: - - Key principle 1 - - Key principle 2 - - Key principle 3 - - Key principle 4 -``` -QUERY: -``` - “”” - Learning a new language is an excellent way to broaden your horizons and improve your cognitive abilities. Firstly, being multilingual can open new opportunities both personally and professionally, such as traveling to new countries, connecting with people from different cultures, and expanding your job prospects. Secondly, it has been shown that learning a new language can improve cognitive function, such as memory, problem-solving, and decision-making skills. Additionally, it can increase empathy and cultural understanding, as well as enhance creativity and communication skills. Finally, it can boost confidence and self-esteem, as mastering a new language is a significant achievement and can provide a sense of accomplishment. Overall, the benefits of learning a new language are numerous and can have a positive impact on many aspects of your life. - “”” -``` -### Split complex tasks into simpler subtasks - -5. Give the system message primary and secondary categories for classifying customer service inquiries. The system should: - - take in customer service queries - - classify the query into primary and secondary categories - - output the response in JSON format with the following keys: primary and secondary - -SYSTEM: -``` -You will be provided with customer services queries. Classify each query into a primary category and a secondary category. Provide your output in JSON format with the keys: primary and secondary - Primary categories: Billing, Technical Support, Account Management, or General Inquiry - Billing secondary categories: - - Unsubscribe or upgrade - - Add a payment method - - Explanation for charge - - Dispute a charge - Technical Support secondary categories: - - Troubleshooting - - Device compatibility - - Software updates - Account Management secondary categories: - - Password reset - - Update personal information - - Close account - - Account security - General Inquiry secondary categories: - - Product information - - Pricing - - Feedback - - Speak to a human -``` -QUERY: -``` -I need to get my internet working again. -``` -(5) Continued: Based on the classification of the customer query from above, provide a set of more specific set of instructions to the system message for troubleshooting in a technical support context. - -SYSTEM: - -``` -You will be provided with customer service inquiries that require troubleshooting in a technical support context. Help the user by: - - Check all router cables are connected properly. If not, reconnect them as needed. - - Ask the customer which router model they are using. - - For MTD-327J model, instruct the customer to hold the red button for 5 seconds and wait 5 minutes before testing the connection. - - For MTD-327S model, advise the customer to unplug and replug the device and wait for 5 minutes before testing the connection. - - If the issue persists, output {"IT support requested"} to connect them to IT support. - - If the customer's questions are unrelated to troubleshooting, ask if they would like to end the chat and classify their request accordingly. - - -``` -QUERY: -``` -I need to get my internet working again. -``` - -### Give GPTs time to "think" - -6. Modify the system message to determine if the student’s solution is correct or not. The model should work out its own solution before comparing it to the student’s solution. Following an in-depth comparison, a decision on whether the answer is correct or not should be made. Add the following example so the model knows how to solve the problem correctly: - -SYSTEM: - - First work out your own solution to the problem. Then compare your solution to the student's solution and evaluate if the student's solution is correct or not. Don't decide if the student's solution is correct until you have done the problem yourself. - - USER: - - Problem Statement: I'm building a solar power installation and I need help working out the financials. - - Land costs $100 / square foot - - I can buy solar panels for $250 / square foot - - I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot - What is the total cost for the first year of operations as a function of the number of square feet. - - ASSISTANT: - - Let x be the size of the installation in square feet. - 1. Land cost: 100x - 2. Solar panel cost: 250x - 3. Maintenance cost: 100,000 + 10x - Total cost: 100x + 250x + 100,000 + 10x = 360x + 100,000 - -QUERY: - - Problem Statement: I'm building a solar power installation and I need help working out the financials. - - Land costs $100 / square foot - - I can buy solar panels for $250 / square foot - - I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot - What is the total cost for the first year of operations as a function of the number of square feet. - Student's Solution: Let x be the size of the installation in square feet. - 1. Land cost: 100x - 2. Solar panel cost: 250x - 3. Maintenance cost: 100,000 + 100x - Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000 - -### Test changes systematically - -7. Modify the system to detect whether the text it was given contains the following pieces of information it has directly. The text should be delimited by triple quotes. Here are the pieces of information to look for: - - Neil Armstrong was the first person to walk on the moon. - - The date Neil Armstrong walked on the moon was July 21, 1969. - -SYSTEM: - - You will be provided with text delimited by triple quotes that is supposed to be the answer to a question. Check if the following pieces of information are directly contained in the answer: - - - Neil Armstrong was the first person to walk on the moon. - - The date Neil Armstrong first walked on the moon was July 21, 1969. - - For each of these points perform the following steps but do not display the step number: - - Step 1 - Restate the point. - Step 2 - Provide a citation from the answer which is closest to this point. - Step 3 - Consider if someone reading the citation who doesn't know the topic could directly infer the point. Explain why or why not before making up your mind. - Step 4 - Write "yes" if the answer to 3 was yes, otherwise write "no". - Finally, provide a count of how many "yes" answers there are. Provide this count as {"count": }. - -QUERY: - - """Neil Armstrong is famous for being the first human to set foot on the Moon. This historic event took place on July 21, 1969, during the Apollo 11 mission.""" - -## Azure OpenAI API and Embeddings - -### Background -Creating embeddings of search documents allows you to use vector search, which is much more powerful than basic keyword search. First, review this page on [how to create embeddings](https://learn.microsoft.com/en-us/azure/search/vector-search-how-to-generate-embeddings), and then review [how vector search works](https://learn.microsoft.com/en-us/azure/search/vector-search-overview). - -### Environment Setup -Navigate to your [Azure Machine Learning Studio environment](https://github.com/STRIDES/NIHCloudLabAzure#launch-a-machine-learning-workspace-jupyter-environment-). If you have not created your environment, [create one now](https://learn.microsoft.com/en-us/azure/machine-learning/tutorial-cloud-workstation?view=azureml-api-2). - -Navigate to `Notebooks`, then clone this Git repo into your environment and navigate to the notebook called [AzureOpenAI_embeddings.ipynb](/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb). - -You will need a variety of parameters to authenticate with the API. You can find these within the Playground by clicking **View Code**. Input these parameters into the notebook cell when asked. - - ![Code View Image](/docs/images/find_endpointv2.png) - -Follow along with the notebook, and when finished, feel free to explore the other notebooks which use more advanced tools like Azure AI Search and LangChain. - -Finally, navigate back here to view the Additional Resources. Make sure to **Stop your Compute** when finished in Azure ML Studio. - -## Additional Resources - -### Azure OpenAI PLayground - -*These resources are for the older Azure OpenAI, but not all the docs have been updated to Azure AI Studio. While the front end has changed, the underlying services largely have not, so these docs should still serve you well.* - -[Azure OpenAI Service models](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) - -[Adding data to Azure OpenAI Playground](https://learn.microsoft.com/en-us/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line&pivots=programming-language-studio) - -[Azure OpenAI Chat API](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions) - - -### Basics of Prompt Egineering - -[Prompting Techniques](https://www.promptingguide.ai/techniques) - -[Prompting Best Practices](https://platform.openai.com/docs/guides/gpt-best-practices) - -### Azure OpenAI Embeddings - -[Getting Started with Embeddings](https://learn.microsoft.com/en-us/azure/ai-services/openai/tutorials/embeddings?tabs=command-line) - -[OpenAI Cookbook GitHub Repository](https://github.com/openai/openai-cookbook) - -## License - -This repository is licensed under the MIT License. See the [LICENSE](https://github.com/t-cjackson/Azure-OpenAI-Workshop/blob/main/LICENSE) file for more information. diff --git a/tutorials/notebooks/GenAI/Azure_Open_AI_README.md b/tutorials/notebooks/GenAI/Azure_Open_AI_README.md deleted file mode 100644 index 6b41e99..0000000 --- a/tutorials/notebooks/GenAI/Azure_Open_AI_README.md +++ /dev/null @@ -1,395 +0,0 @@ -# Azure OpenAI Tutorial -✨ The following tutorial was modified from this excellent [Microsoft workshop](https://github.com/t-cjackson/AOAI-FED-CIV-Workshop) developed by [Cameron Jackson](https://github.com/t-cjackson). ✨ - -Welcome to this repository, a comprehensive collection of examples that will help you chat with your data using the Azure OpenAI Playground, create highly efficient large language model prompts, and build Azure OpenAI embeddings. This repository offers a wide range of examples that can be catered to your use cases, including: - -- Documents for LLM interactions in the Azure OpenAI Playground. -- 7 best practices for implementing prompt egineering in LLM applications. -- 4 Python scripts that demonstrate how to use Azure OpenAI Embeddings to create embedding applications. -- 42 in-depth content slides on the information covered in this workshop. Please find ```aoai_workshop_content.pdf``` in [search_documents](https://github.com/t-cjackson/Azure-OpenAI-Workshop/tree/main/search_documents) folder in this repository. - -The purpose of this workshop is to equip participants with the necessary skills to make the most out of the Azure OpenAI Playground, Prompt Engineering, and Azure OpenAI Embeddings in Python. You can view in-depth info on these topics in the [workshop slides](/notebooks/GenAI/search_documents/aoai_workshop_content.pdf). - -You can also learn a lot about the details of using Azure OpenAI at this [site](https://learn.microsoft.com/en-us/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line&pivots=programming-language-studio). - -We recommend you 1) go through the steps in this README, 2) complete the general notebook called `notebooks/AzureOpenAI_embeddings.ipynb`, then 3) explore the other notebooks at [this directory](/notebooks/GenAI/notebooks) - -## Overview of Page Contents -+ [Azure OpenAI Playground Prerequisites](#Azure-OpenAI-Playground-Prerequisites) -+ [Chat Playground Navigation](#Chat-Playground-Navigation) -+ [Upload your own data and query over it](#Upload-your-own-data-and-query-over-it) -+ [Prompt Engineering Best Practices](#Prompt-Engineering-Best-Practices) -+ [Azure OpenAI Embeddings](#Azure-OpenAI-Embeddings) -+ [Additional Resources](#Additional-Resources) - -## Azure OpenAI Playground Prerequisites - -Navigate to Azure OpenAI. The easiest way is to search at the top of the page. - - ![search for azure openai](/docs/images/1_navigate_openai.png) - -At the time of writing, Azure OpenAI is in Beta and only available to customers via an application form, if you click **Create** that is the message you will see. If you click **Create** and do not get this message, then feel free to create a new OpenAI Service. Otherwise, please email us at CloudLab@nih.gov and ask us to set this part up for you. Once you have an OpenAI Service provisioned, click to open it. - - ![click to open azure open ai](/docs/images/2_select_openai_project.png) - -Now click **Go to Azure OpenAI Studio** or **Explore** to be connected to the Azure OpenAI studio user interface. - - ![connect to OpenAI UI](/docs/images/3_connet_open_ai.png) - -Click **Chat** - - ![click chat image](/docs/images/4_click_chat.png) - -Next, you need to deploy an OpenAI model. - -## Deploy an OpenAI model - -On the left navigation panel, click **Models** - - ![Click Models](/docs/images/10_click_models.png) - -Select the (A) `gpt-35-turbo model`, click (B) **Deploy**. You can learn more about the available models by clicking (C) **Learn more about the different types of base models**, or [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models). - - ![Deploy the model](/docs/images/11_deploy_model.png) - -Name your deployment and then click **Create**. - - ![Name your Deployment](/docs/images/12_name_your_deployment.png) - -Now if you select `Deployments` on the left panel, you should see your deployed model listed. - - ![Check Deployments](/docs/images/13_check_deployments.png) - -Run a quick test to ensure our deployment is acting as expected. Navigate to `Chat`, add an optional system message (we will cover this more later), and then type `Hello World` in the chat box. If you get a response, things are working well! - - ![test model](/docs/images/14_test_your_model.png) - -Now we will look at [adding and querying over your own data](#Upload-your-own-data-and-query-over-it) and then review [prompt engineering best practices](#prompt-engineering-best-practices) using a general GPT model. - -## Chat Playground Navigation - -If you have not already (A) Navigate to the Chat Playground. Here we will walk through the various options available to you. First, you can specify a `System Message` which tells the model what context with which to respond to inquiries. To modify this, (B) select `System message`, then (B) input a [System Message](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/system-message#define-the-models-profile-capabilities-and-limitations-for-your-scenario) in the prompt box, then (D) click **Save**. - -On the next tab over, you can (A) add your own data, which we dive into in the [next section](#Upload-your-own-data-and-query-over-it). In the middle of the page is where you actually interact with the model (B) through the chat prompts. Always (C) clear the chat after each session. - - ![add your own data](/docs/images/18_add_custom_data.png) - -On the far right, you can modify which model you are deploying, which allows you to switch between different model deployments depending on the context. - - ![modify deployment](/docs/images/19_deployment.png) - -Finally, you can select the `parameters` tab to modify the model parameters. Review [this presentation](/notebooks/GenAI/search_documents/aoai_workshop_content.pdf) to learn more about the parameters. - - ![modify parameters](/docs/images/20_parameters.png) - -## Upload your own data and query over it - -For an in-depth overview of adding your own data, check out this [Microsoft documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line&pivots=programming-language-studio). We give a quick start version here. - -Now, if you want to add your own data and query it, keep going here. If you want to jump ahead to prompt engineering with the general GPT model, jump down to [Prompt Engineering Best Practices](#prompt-engineering-best-practices). - -Within this repo there is a directory called `search_documents`. This directory contains a few PDFs that we will upload and query over related to [Immune Response to Mpox in Woman Living with HIV](https://www.niaid.nih.gov/news-events/immune-response-mpox) and the [DCEG Diesel Exhaust in Minors Study](https://dceg.cancer.gov/news-events/news/2023/dems-ii). - -We are going to upload these PDFs to an Azure Storage Account and then add them to our Azure OpenAI workspace. Note that there are [upload limits](https://learn.microsoft.com/en-us/azure/ai-services/openai/quotas-limits#quotas-and-limits-reference) on the number and size of documents you can query within Azure OpenAI, but sure to read these before getting started. For example, you can only query over a max of 30 documents and/or 1 GB of data. You can only upload the datatypes [listed below] [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/use-your-data#data-formats-and-file-types), and will have the best results with markdown files. - -+ `.txt` -+ `.md` -+ `.html` -+ Microsoft Word files -+ Microsoft PowerPoint files -+ PDF - -Follow [this guide](/docs/create_storage_account.md) to create and upload to a storage account. Use a separate browswer window so that you can easily get back to Azure OpenAI. - -Once you have uploaded your PDFs (or other datatypes if you are trying that), navigate back to the `Chat` section of Azure OpenAI and click **Add a data source**. - - ![Add data source image](/docs/images/5_add_data_source.png) - -Select `Azure Blob Storage`, and then the correct `Storage Account` and `Container`. If this is your first time indexing documents, for `Select Azure Cognitive Search resource` click **Create a new Azure Cognitive Search resource** which will open a new window. - - ![select data source](/docs/images/6_point_to_data.png) - -If needed, create the new Azure Cognitive Search resource. Make sure you delete this when you are finished with Azure OpenAI because it will accrue charges over time. - - ![create cog search](/docs/images/7_cog_search_resource.png) - -Now select your newly made Azure Cognitive Search resource, and click **Next**. You can select to search with either [Keyword or Semantic search](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/use-your-data#search-options). Keyword is simple keyword-driven search, semantic search takes the context of the words into account and is normally better. If Semantic search is not allowed in your account, just use **Keyword**. Select **Next**. - - ![choose keyword](/docs/images/choose_keyword.png) - -On the last page, click **Save and close**. It will now take a few minutes to index your updated data. Read more [here](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search) about how Azure Cognitive Search is working behind the scenes. - - ![Save and close](/docs/images/9_review_and_close.png) - -Once it is complete, you should see your data source listed. Note that you can select the box that says `Limit responses to your data content` depending on if you want to limit to your data or query your data plus the general model. - -Also check that the index is complete by viewing your Cognitive Search resource, and going to `Indexes`. Ensure that the number of documents listed > 0. - - ![Cog Search](/docs/images/15_check_index.png) - -Now let's run some example queries of our custom data set. Feel free to modify and experiment. After reading the prompt engineering section below, return to this section and see how you can improve these examples. If you get errors after adding your data, try to refresh the page, and if all else fails, send us an email at CloudLab@nih.gov. - -``` -Summarize each of the documents I uploaded in a single paragraph, listing the title, the authors, followed by a five sentence summary for each. Give a new line after each summary. -``` -``` -What were some of the phenotypic presentations of MPOX on patients with HIV? -``` -``` -Are the phenotypic effects of MPOX the same for a patient with HIV and other patients? -``` -``` -Describe the primary findings of the Diesel Exhaust in Miners Study? -``` -``` -Does exposure to Diesel exhaust increase your risk for lung cancer? What about other cancers? Keep your response to one sentence for each of these queries. -``` - - ![search custom data files](/docs/images/16_search_custom_data.png) - -## Prompt Engineering Best Practices -First, review [this summary of prompt engineering](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/prompt-engineering) from Microsoft. - -### Write Clear Instructions - -1. Alter the system message to reply with a document that includes a playful comment or joke in each paragraph when responding to inquiries concerning writing assistance. This format should only be used for writing-related questions - -Add the following in the System Message box (SYSTEM:) -``` -You are a comedian English professor at the University of Giggles. When I ask for help to write something, you will reply with a document that contains at least one joke or playful comment. -``` -Add this query to the chat prompt box (QUERY:). -``` -Write a thank you note to my steel bolt vendor for getting a delivery in on time with short notice. This made it possible for my company to deliver an important order. -``` -Add the following to the system message, directing the LLM to only answer questions that involve writing assistance and then rerun the original query. -``` -If the user query does not have "write" in it, respond I do not know truthfully. -``` -2. Modify the system message by adding the prefix "Summary:" which should summarize the paragraph given, delimited with XML tags. Following the summary, the system should translate the paragraph from English to Spanish and add the prefix "Translation:". -To accomplish these tasks, the following steps should be taken: - 1. Identify the paragraph to be summarized, which should be delimited by XML tags. - 2. Generate a summary of the paragraph. - 3. Add the prefix "Summary:" to the beginning of the summary. - 4. Translate the paragraph from English to Spanish. - 5. Add the prefix "Translation:" to the beginning of the translated paragraph. - -SYSTEM: -``` -You will be given a paragraph delimited by XML tags. Use the following step-by-step sequence to respond to user inputs. - - Step 1) The user will provide you with a paragraph delimited by XML tags. Summarize the paragraph in one sentence with a prefix “Summary:” - Step 2) Translate the summary from Step 1 into Spanish, with a prefix “Translation:” -``` -QUERY: -``` - Artificial intelligence (AI) refers to the simulation of human intelligence in machines that are designed to perform tasks that normally require human intelligence, such as learning, problem-solving, and decision-making. AI technology uses algorithms and statistical models to analyze data and make predictions and can be applied to a wide range of fields, including healthcare, finance, and transportation. AI is a rapidly growing field that has the potential to revolutionize many industries by increasing efficiency and productivity. However, as with any technology, there are also concerns about the ethical implications of AI, such as job displacement and privacy concerns. -``` - -Note: When implementing the above example, you might encounter a problem in Step 2 of the prompt where the model translates the entire paragraph instead of the single sentence summary. This issue is likely to arise when using the gpt-35-turbo model, primarily due to its limitations in reasoning capabilities, which impact its translation proficiency. A solution to this minor glitch is the gpt-4 model, which is designed to reason more effectively than the gpt-35-turbo model. - -1. Revise the model to classify the text it is given as either positive, neutral or negative. Once classified, have the LLM recognize the adjective it used to classify the text. Provide an example to the assitant for the LLM to comprehend tasks. - -SYSTEM -``` -Classify the text as either positive, neutral, or negative. Then find the adjective that allows you to classify the text. Follow the example to respond. - - USER: The movie was awesome! - - ASSISTANT: Positive. The adjective here is: awesome. - - USER: The movie was terrible. - - ASSISTANT: Negative. The adjective here is: terrible. - - USER: The movie was ok. - - ASSISTANT: Neutral. The adjective here is: ok. - - QUERY: I can’t wait to go to the beach. -``` - -### Providing Reference Text - -4. Revise the system message to create four bullet points outlining the key principles of the provided text delimited by triple quotes. -To accomplish this, the following steps should be taken: - 1. Identify the text to be analyzed, which should be delimited by triple quotes. - 2. Analyze the text to determine the key principles. - 3. Generate four bullet points that succinctly summarize each principle. - 4. Display the bullet points in the system message. - -SYSTEM: -``` -You will be given text delimited by triple quotes. Create 4 bullet points on the key principles of the text. Answer in the following format: - - Key principle 1 - - Key principle 2 - - Key principle 3 - - Key principle 4 -``` -QUERY: -``` - “”” - Learning a new language is an excellent way to broaden your horizons and improve your cognitive abilities. Firstly, being multilingual can open new opportunities both personally and professionally, such as traveling to new countries, connecting with people from different cultures, and expanding your job prospects. Secondly, it has been shown that learning a new language can improve cognitive function, such as memory, problem-solving, and decision-making skills. Additionally, it can increase empathy and cultural understanding, as well as enhance creativity and communication skills. Finally, it can boost confidence and self-esteem, as mastering a new language is a significant achievement and can provide a sense of accomplishment. Overall, the benefits of learning a new language are numerous and can have a positive impact on many aspects of your life. - “”” -``` -### Split complex tasks into simpler subtasks - -5. Give the system message primary and secondary categories for classifying customer service inquiries. The system should: - - take in customer service queries - - classify the query into primary and secondary categories - - output the response in JSON format with the following keys: primary and secondary - -SYSTEM: -``` -You will be provided with customer services queries. Classify each query into a primary category and a secondary category. Provide your output in JSON format with the keys: primary and secondary - Primary categories: Billing, Technical Support, Account Management, or General Inquiry - Billing secondary categories: - - Unsubscribe or upgrade - - Add a payment method - - Explanation for charge - - Dispute a charge - Technical Support secondary categories: - - Troubleshooting - - Device compatibility - - Software updates - Account Management secondary categories: - - Password reset - - Update personal information - - Close account - - Account security - General Inquiry secondary categories: - - Product information - - Pricing - - Feedback - - Speak to a human -``` -QUERY: -``` -I need to get my internet working again. -``` -(5) Continued: Based on the classification of the customer query from above, provide a set of more specific set of instructions to the system message for troubleshooting in a technical support context. - -SYSTEM: - -``` -You will be provided with customer service inquiries that require troubleshooting in a technical support context. Help the user by: - - Check all router cables are connected properly. If not, reconnect them as needed. - - Ask the customer which router model they are using. - - For MTD-327J model, instruct the customer to hold the red button for 5 seconds and wait 5 minutes before testing the connection. - - For MTD-327S model, advise the customer to unplug and replug the device and wait for 5 minutes before testing the connection. - - If the issue persists, output {"IT support requested"} to connect them to IT support. - - If the customer's questions are unrelated to troubleshooting, ask if they would like to end the chat and classify their request accordingly. - - -``` -QUERY: -``` -I need to get my internet working again. -``` - -### Give GPTs time to "think" - -6. Modify the system message to determine if the student’s solution is correct or not. The model should work out its own solution before comparing it to the student’s solution. Following an in-depth comparison, a decision on whether the answer is correct or not should be made. Add the following example so the model knows how to solve the problem correctly: - -SYSTEM: - - First work out your own solution to the problem. Then compare your solution to the student's solution and evaluate if the student's solution is correct or not. Don't decide if the student's solution is correct until you have done the problem yourself. - - USER: - - Problem Statement: I'm building a solar power installation and I need help working out the financials. - - Land costs $100 / square foot - - I can buy solar panels for $250 / square foot - - I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot - What is the total cost for the first year of operations as a function of the number of square feet. - - ASSISTANT: - - Let x be the size of the installation in square feet. - 1. Land cost: 100x - 2. Solar panel cost: 250x - 3. Maintenance cost: 100,000 + 10x - Total cost: 100x + 250x + 100,000 + 10x = 360x + 100,000 - -QUERY: - - Problem Statement: I'm building a solar power installation and I need help working out the financials. - - Land costs $100 / square foot - - I can buy solar panels for $250 / square foot - - I negotiated a contract for maintenance that will cost me a flat $100k per year, and an additional $10 / square foot - What is the total cost for the first year of operations as a function of the number of square feet. - Student's Solution: Let x be the size of the installation in square feet. - 1. Land cost: 100x - 2. Solar panel cost: 250x - 3. Maintenance cost: 100,000 + 100x - Total cost: 100x + 250x + 100,000 + 100x = 450x + 100,000 - -### Test changes systematically - -7. Modify the system to detect whether the text it was given contains the following pieces of information it has directly. The text should be delimited by triple quotes. Here are the pieces of information to look for: - - Neil Armstrong was the first person to walk on the moon. - - The date Neil Armstrong walked on the moon was July 21, 1969. - -SYSTEM: - - You will be provided with text delimited by triple quotes that is supposed to be the answer to a question. Check if the following pieces of information are directly contained in the answer: - - - Neil Armstrong was the first person to walk on the moon. - - The date Neil Armstrong first walked on the moon was July 21, 1969. - - For each of these points perform the following steps but do not display the step number: - - Step 1 - Restate the point. - Step 2 - Provide a citation from the answer which is closest to this point. - Step 3 - Consider if someone reading the citation who doesn't know the topic could directly infer the point. Explain why or why not before making up your mind. - Step 4 - Write "yes" if the answer to 3 was yes, otherwise write "no". - Finally, provide a count of how many "yes" answers there are. Provide this count as {"count": }. - -QUERY: - - """Neil Armstrong is famous for being the first human to set foot on the Moon. This historic event took place on July 21, 1969, during the Apollo 11 mission.""" - -## Azure OpenAI API and Embeddings - -### Background -Creating embeddings of search documents allows you to use vector search, which is much more powerful than the keyword search we used above. First, review this page on [how to create embeddings](https://learn.microsoft.com/en-us/azure/search/vector-search-how-to-generate-embeddings), and then review [how vector search works](https://learn.microsoft.com/en-us/azure/search/vector-search-overview). - -### Environment Setup -Navigate to your [Azure Machine Learning Studio environment](https://github.com/STRIDES/NIHCloudLabAzure#launch-a-machine-learning-workspace-jupyter-environment-). If you have not created your environment, [create one now](https://learn.microsoft.com/en-us/azure/machine-learning/tutorial-cloud-workstation?view=azureml-api-2). - -Navigate to `Notebooks`, then clone this Git repo into your environment and navigate to the notebook called [AzureOpenAI_embeddings.ipynb](/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb). - -You will need a variety of parameters to authenticate with the API. You can find these within the Chat Playground by clicking **View Code**. Input these parameters into the notebook cell when asked. - - ![Code View Image](/docs/images/find_endpointv2.png) - -Follow along with the notebook, and when finished, feel free to explore the other notebooks which use more advanced tools like Azure AI Search and LangChain. - -Finally, navigate back here to view the Additional Resources. Make sure to **Stop your Compute** when finished in Azure ML Studio. - -## Additional Resources - -### Azure OpenAI PLayground - -[Azure OpenAI Service models](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models) - -[Adding data to Azure OpenAI Playground](https://learn.microsoft.com/en-us/azure/ai-services/openai/use-your-data-quickstart?tabs=command-line&pivots=programming-language-studio) - -[Azure OpenAI Chat API](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#chat-completions) - - -### Basics of Prompt Egineering - -[Prompting Techniques](https://www.promptingguide.ai/techniques) - -[Prompting Best Practices](https://platform.openai.com/docs/guides/gpt-best-practices) - -### Azure OpenAI Embeddings - -[Getting Started with Embeddings](https://learn.microsoft.com/en-us/azure/ai-services/openai/tutorials/embeddings?tabs=command-line) - -[OpenAI Cookbook GitHub Repository](https://github.com/openai/openai-cookbook) - -## License - -This repository is licensed under the MIT License. See the [LICENSE](https://github.com/t-cjackson/Azure-OpenAI-Workshop/blob/main/LICENSE) file for more information. diff --git a/tutorials/notebooks/GenAI/LICENSE b/tutorials/notebooks/GenAI/LICENSE deleted file mode 100644 index 48bc6bb..0000000 --- a/tutorials/notebooks/GenAI/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) Microsoft Corporation - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/tutorials/notebooks/GenAI/embedding_demos/acs_embeddings.py b/tutorials/notebooks/GenAI/embedding_demos/acs_embeddings.py deleted file mode 100644 index 8a4a68a..0000000 --- a/tutorials/notebooks/GenAI/embedding_demos/acs_embeddings.py +++ /dev/null @@ -1,79 +0,0 @@ -from langchain.retrievers import AzureCognitiveSearchRetriever -from langchain.embeddings import OpenAIEmbeddings -from langchain.vectorstores import FAISS -from langchain.chains import RetrievalQA -from langchain.chat_models import AzureChatOpenAI -from PIL import Image -import os -import streamlit as st -from dotenv import load_dotenv - -# load in .env variables -load_dotenv() - -def config_keys(): - # set api keys for AOAI and Azure Search - os.environ['OPENAI_API_VERSION'] = os.getenv('AZURE_OPENAI_VERSION') - os.environ['OPENAI_API_KEY'] = os.getenv('AZURE_OPENAI_KEY') - os.environ['OPENAI_API_BASE'] = os.getenv('AZURE_OPENAI_ENDPOINT') - os.environ['OPENAI_EMBEDDING_DEPLOYMENT_NAME'] = os.getenv('AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME') - os.environ['AZURE_COGNITIVE_SEARCH_SERVICE_NAME'] = os.getenv('AZURE_COGNITIVE_SEARCH_SERVICE_NAME') - os.environ['AZURE_COGNITIVE_SEARCH_API_KEY'] = os.getenv('AZURE_COGNITIVE_SEARCH_API_KEY') - os.environ['AZURE_COGNITIVE_SEARCH_INDEX_NAME'] = os.getenv('AZURE_COGNITIVE_SEARCH_INDEX_NAME') - - -def main(): - # Streamlit config - st.title("Demo - Azure OpenAI & Cognitive Search Embeddings") - image = Image.open('image_logo2.png') - st.image(image, caption = '') - st.write('This program is designed to chat over your files in Azure Cognitive Search. \ - Be specific and clear with the questions you ask. \ - Welcome to CHATGPT over your own data !!') - if 'generated' not in st.session_state: - st.session_state.generated = [] - if 'past' not in st.session_state: - st.session_state.past = [] - - # create your LLM and embeddings. Will be conifuring 'azure' in the openai_api_type parameter. - llm = AzureChatOpenAI( - deployment_name = "gpt-35-turbo", - openai_api_type = "azure", - model = "gpt-35-turbo", - temperature=0.7, - max_tokens=200 - ) - - embeddings = OpenAIEmbeddings(chunk_size=1, openai_api_type="azure") - - # ask for the user query - query = st.text_input("Enter a search query: ", key='search_term', placeholder="") - - if query: - st.session_state.past.append(query) - - # set up Azure Cognitive Search to retrieve documents - # top_k = 1: we only want first related doc - retriever = AzureCognitiveSearchRetriever(content_key="content", top_k=1) - - # get the relevant document from Azure Cognitive Search that are only relevant to the query being asked - docs = retriever.get_relevant_documents(query) - - # create embedding from the document retrieved and place in a FAISS vector database - db = FAISS.from_documents(documents=docs, embedding=embeddings) - - # set up the chain that will feed the retrieved document to the LLM - chain = RetrievalQA.from_chain_type(llm=llm, retriever = db.as_retriever(), chain_type="stuff") - - # run the chain on the query asked - response = chain.run(query) - st.session_state.generated.append(response) - - with st.expander('Vector Search'): - for i in range(len(st.session_state.generated)-1, -1, -1): - st.info(st.session_state.past[i]) - st.success(st.session_state.generated[i]) - -if __name__ == '__main__': - config_keys() - main() diff --git a/tutorials/notebooks/GenAI/embedding_demos/aoai_embeddings.py b/tutorials/notebooks/GenAI/embedding_demos/aoai_embeddings.py deleted file mode 100644 index eb694c7..0000000 --- a/tutorials/notebooks/GenAI/embedding_demos/aoai_embeddings.py +++ /dev/null @@ -1,102 +0,0 @@ -import openai -from openai.embeddings_utils import get_embedding, cosine_similarity # must pip install openai[embeddings] -import pandas as pd -import numpy as np -import os -import streamlit as st -import time -from PIL import Image -from dotenv import load_dotenv - -# load in .env variables -load_dotenv() - -# configure azure openai keys -openai.api_type = 'azure' -openai.api_version = os.environ['AZURE_OPENAI_VERSION'] -openai.api_base = os.environ['AZURE_OPENAI_ENDPOINT'] -openai.api_key = os.environ['AZURE_OPENAI_KEY'] - -def embedding_create(): - # acquire the filename to be embed - st.subheader("Vector Creation") - st.write('This program is designed to embed your pre-chunked .csv file. \ - By accomplishing this task, you will be able to chat over all cotent in your .csv via vector searching. \ - Just enter the file and the program will take care of the rest (specify file path if not in this directory). \ - Welcome to CHATGPT over your own data !!') - filename = st.text_input("Enter a file: ", key='filename', value="") - - # start the embeddings process if filename provided - if filename: - - # read the data file to be embed - df = pd.read_csv('C:\\src\\AzureOpenAI_Gov_Workshop\\' + filename) - st.write(df) - - # calculate word embeddings - df['embedding'] = df['text'].apply(lambda x:get_embedding(x, engine='text-embedding-ada-002')) - df.to_csv('C:\\src\\AzureOpenAI_Gov_Workshop\\microsoft-earnings_embeddings.csv') - time.sleep(3) - st.subheader("Post Embedding") - st.success('Embeddings Created Sucessfully!!') - st.write(df) - - -def embeddings_search(): - - # Streamlit configuration - st.subheader("Vector Search") - st.write('This program is designed to chat over your vector stored (embedding) .csv file. \ - This Chat Bot works alongside the "Embeddings Bot" Chat Bot. \ - Be specific with the information you want to obtain over your data. \ - Welcome to CHATGPT over your own data !!') - if 'answer' not in st.session_state: - st.session_state.answer = [] - if 'score' not in st.session_state: - st.session_state.score = [] - if 'past' not in st.session_state: - st.session_state.past = [] - - # read in the embeddings .csv - # convert elements in 'embedding' column back to numpy array - df = pd.read_csv('C:\\src\\AzureOpenAI_Gov_Workshop\\microsoft-earnings_embeddings.csv') - df['embedding'] = df['embedding'].apply(eval).apply(np.array) - - # caluculate user query embedding - search_term = st.text_input("Enter a search query: ", key='search_term', placeholder="") - if search_term: - st.session_state.past.append(search_term) - search_term_vector = get_embedding(search_term, engine='text-embedding-ada-002') - - # find similiarity between query and vectors - df['similarities'] = df['embedding'].apply(lambda x:cosine_similarity(x, search_term_vector)) - df1 = df.sort_values("similarities", ascending=False).head(5) - - # output the response - answer = df1['text'].loc[df1.index[0]] - score = df1['similarities'].loc[df1.index[0]] - st.session_state.answer.append(answer) - st.session_state.score.append(score) - with st.expander('Vector Search'): - for i in range(len(st.session_state.answer)-1, -1, -1): - st.info(st.session_state.past[i]) - st.write(st.session_state.answer[i]) - st.write('Score: ', st.session_state.score[i]) - - -def main(): - # Streamlit config - st.title("Demo-Azure OpenAI Embeddings") - image = Image.open('image_logo2.png') - st.image(image, caption = '') - st.sidebar.title('Chat Bot Type Selection') - chat_style = st.sidebar.selectbox( - 'Choose between Embeddings Bot or Search Bot', ['Embeddings Bot','Search Bot'] - ) - if chat_style == 'Embeddings Bot': - embedding_create() - elif chat_style == 'Search Bot': - embeddings_search() - -if __name__ == '__main__': - main() diff --git a/tutorials/notebooks/GenAI/example_scripts/example_azureaisearch_openaichat_zeroshot.py b/tutorials/notebooks/GenAI/example_scripts/example_azureaisearch_openaichat_zeroshot.py deleted file mode 100644 index 8440bc8..0000000 --- a/tutorials/notebooks/GenAI/example_scripts/example_azureaisearch_openaichat_zeroshot.py +++ /dev/null @@ -1,99 +0,0 @@ -from langchain.chains import ConversationalRetrievalChain -from langchain.prompts import PromptTemplate -from langchain_community.retrievers import AzureCognitiveSearchRetriever -from langchain_openai import AzureChatOpenAI -import sys -import json -import os - - -class bcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - -MAX_HISTORY_LENGTH = 1 - -def build_chain(): - - os.getenv("AZURE_OPENAI_API_KEY") - os.getenv("AZURE_OPENAI_ENDPOINT") - os.getenv("AZURE_COGNITIVE_SEARCH_SERVICE_NAME") - os.getenv("AZURE_COGNITIVE_SEARCH_INDEX_NAME") - os.getenv("AZURE_COGNITIVE_SEARCH_API_KEY") - AZURE_OPENAI_DEPLOYMENT_NAME = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] - - llm = AzureChatOpenAI( - openai_api_version="2023-05-15", - azure_deployment=AZURE_OPENAI_DEPLOYMENT_NAME, - #max_tokens = 3000 -) - - retriever = AzureCognitiveSearchRetriever(content_key="content", top_k=2) - - - prompt_template = """ - Instructions: - I will provide you question and scientific documents you will answer my question with information from documents in English, and you will create a cumulative summary that should be concise and should accurately. - You should not include any personal opinions or interpretations in your summary, but rather focus on objectively presenting the information from the papers. - Your summary should be written in your own words and ensure that your summary is clear, and concise. - - {question} Answer "don't know" if not present in the documents. - {context} - Solution:""" - - - PROMPT = PromptTemplate( - template=prompt_template, input_variables=["context", "question"], - ) - - condense_qa_template = """ - Chat History: - {chat_history} - Here is a new question for you: {question} - Standalone question:""" - standalone_question_prompt = PromptTemplate.from_template(condense_qa_template) - - qa = ConversationalRetrievalChain.from_llm( - llm=llm, - retriever=retriever, - condense_question_prompt=standalone_question_prompt, - return_source_documents=True, - combine_docs_chain_kwargs={"prompt":PROMPT} - ) - return qa - -def run_chain(chain, prompt: str, history=[]): - print(prompt) - return chain({"question": prompt, "chat_history": history}) - -if __name__ == "__main__": - chat_history = [] - qa = build_chain() - print(bcolors.OKBLUE + "Hello! How can I help you?" + bcolors.ENDC) - print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC) - print(">", end=" ", flush=True) - for query in sys.stdin: - if (query.strip().lower().startswith("new search:")): - query = query.strip().lower().replace("new search:","") - chat_history = [] - elif (len(chat_history) == MAX_HISTORY_LENGTH): - chat_history.pop(0) - result = run_chain(qa, query, chat_history) - chat_history.append((query, result["answer"])) - print(bcolors.OKGREEN + result['answer'] + bcolors.ENDC) - if 'source_documents' in result: - print(bcolors.OKGREEN + 'Sources:') - for d in result['source_documents']: - dict_meta=json.loads(d.metadata['metadata']) - print(dict_meta['source']) - print(bcolors.ENDC) - print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC) - print(">", end=" ", flush=True) - print(bcolors.OKBLUE + "Bye" + bcolors.ENDC) diff --git a/tutorials/notebooks/GenAI/example_scripts/example_langchain_openaichat_zeroshot.py b/tutorials/notebooks/GenAI/example_scripts/example_langchain_openaichat_zeroshot.py deleted file mode 100644 index 9d04ccd..0000000 --- a/tutorials/notebooks/GenAI/example_scripts/example_langchain_openaichat_zeroshot.py +++ /dev/null @@ -1,93 +0,0 @@ -from langchain.retrievers import PubMedRetriever -from langchain.chains import ConversationalRetrievalChain -from langchain.prompts import PromptTemplate -import sys -import json -import os - - -class bcolors: - HEADER = '\033[95m' - OKBLUE = '\033[94m' - OKCYAN = '\033[96m' - OKGREEN = '\033[92m' - WARNING = '\033[93m' - FAIL = '\033[91m' - ENDC = '\033[0m' - BOLD = '\033[1m' - UNDERLINE = '\033[4m' - -MAX_HISTORY_LENGTH = 1 - -def build_chain(): - os.getenv("AZURE_OPENAI_API_KEY") - os.getenv("AZURE_OPENAI_ENDPOINT") - AZURE_OPENAI_DEPLOYMENT_NAME = os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"] - - llm = AzureChatOpenAI( - openai_api_version="2023-05-15", - azure_deployment=AZURE_OPENAI_DEPLOYMENT_NAME, - #max_tokens = 3000 -) - - retriever= PubMedRetriever() - - prompt_template = """ - Ignore everything before. - Instructions: - I will provide you with research papers on a specific topic in English, and you will create a cumulative summary. - The summary should be concise and should accurately and objectively communicate the takeaway of the papers related to the topic. - You should not include any personal opinions or interpretations in your summary, but rather focus on objectively presenting the information from the papers. - Your summary should be written in your own words and ensure that your summary is clear, concise, and accurately reflects the content of the original papers. First, provide a concise summary then citations at the end. - {question} Answer "don't know" if not present in the document. - {context} - Solution:""" - - - PROMPT = PromptTemplate( - template=prompt_template, input_variables=["context", "question"], - ) - - condense_qa_template = """ - Chat History: - {chat_history} - Here is a new question for you: {question} - Standalone question:""" - standalone_question_prompt = PromptTemplate.from_template(condense_qa_template) - - qa = ConversationalRetrievalChain.from_llm( - llm=llm, - retriever=retriever, - condense_question_prompt=standalone_question_prompt, - return_source_documents=True, - combine_docs_chain_kwargs={"prompt":PROMPT}, - ) - return qa - -def run_chain(chain, prompt: str, history=[]): - print(prompt) - return chain({"question": prompt, "chat_history": history}) - -if __name__ == "__main__": - chat_history = [] - qa = build_chain() - print(bcolors.OKBLUE + "Hello! How can I help you?" + bcolors.ENDC) - print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC) - print(">", end=" ", flush=True) - for query in sys.stdin: - if (query.strip().lower().startswith("new search:")): - query = query.strip().lower().replace("new search:","") - chat_history = [] - elif (len(chat_history) == MAX_HISTORY_LENGTH): - chat_history.pop(0) - result = run_chain(qa, query, chat_history) - chat_history.append((query, result["answer"])) - print(bcolors.OKGREEN + result['answer'] + bcolors.ENDC) - if 'source_documents' in result: - print(bcolors.OKGREEN + 'Sources:') - for idx, ref in enumerate(result["source_documents"]): - print("PubMed UID: "+ref.metadata["uid"]) - print(bcolors.ENDC) - print(bcolors.OKCYAN + "Ask a question, start a New search: or CTRL-D to exit." + bcolors.ENDC) - print(">", end=" ", flush=True) - print(bcolors.OKBLUE + "Bye" + bcolors.ENDC) diff --git a/tutorials/notebooks/GenAI/example_scripts/workshop_embedding.py b/tutorials/notebooks/GenAI/example_scripts/workshop_embedding.py deleted file mode 100644 index 4212701..0000000 --- a/tutorials/notebooks/GenAI/example_scripts/workshop_embedding.py +++ /dev/null @@ -1,34 +0,0 @@ -import openai -from openai.embeddings_utils import get_embedding, cosine_similarity # must pip install openai[embeddings] -import pandas as pd -import numpy as np -import os -import streamlit as st -from dotenv import load_dotenv -import time - - -# load in variables from .env -load_dotenv() - - -# set keys and configure Azure OpenAI -openai.api_type = 'azure' -openai.api_version = os.environ['AZURE_OPENAI_VERSION'] -openai.api_base = os.environ['AZURE_OPENAI_ENDPOINT'] -openai.api_key = os.environ['AZURE_OPENAI_KEY'] - - -# read the data file to be embed -df = pd.read_csv('microsoft-earnings.csv') -print(df) - - -# calculate word embeddings -df['embedding'] = df['text'].apply(lambda x:get_embedding(x, engine='text-embedding-ada-002')) -df.to_csv('microsoft-earnings_embeddings.csv') -time.sleep(3) -print(df) - - - diff --git a/tutorials/notebooks/GenAI/example_scripts/workshop_search.py b/tutorials/notebooks/GenAI/example_scripts/workshop_search.py deleted file mode 100644 index 4da089e..0000000 --- a/tutorials/notebooks/GenAI/example_scripts/workshop_search.py +++ /dev/null @@ -1,41 +0,0 @@ -import openai -from openai.embeddings_utils import get_embedding, cosine_similarity # must pip install openai[embeddings] -import pandas as pd -import numpy as np -import os -import streamlit as st -from dotenv import load_dotenv - - - -load_dotenv() - - - - -# set keys and configure Azure OpenAI -openai.api_type = 'azure' -openai.api_version = os.environ['AZURE_OPENAI_VERSION'] -openai.api_base = os.environ['AZURE_OPENAI_ENDPOINT'] -openai.api_key = os.environ['AZURE_OPENAI_KEY'] - -# read in the embeddings .csv -# convert elements in 'embedding' column back to numpy array -df = pd.read_csv('microsoft-earnings_embeddings.csv') -df['embedding'] = df['embedding'].apply(eval).apply(np.array) - -# caluculate user query embedding -search_term = input("Enter a search term: ") -if search_term: - search_term_vector = get_embedding(search_term, engine='text-embedding-ada-002') - - # find similiarity between query and vectors - df['similarities'] = df['embedding'].apply(lambda x:cosine_similarity(x, search_term_vector)) - df1 = df.sort_values("similarities", ascending=False).head(5) - - # output the response - print('\n') - print('Answer: ', df1['text'].loc[df1.index[0]]) - print('\n') - print('Similarity Score: ', df1['similarities'].loc[df1.index[0]]) - print('\n') diff --git a/tutorials/notebooks/GenAI/microsoft-earnings.csv b/tutorials/notebooks/GenAI/microsoft-earnings.csv deleted file mode 100644 index c4fcb16..0000000 --- a/tutorials/notebooks/GenAI/microsoft-earnings.csv +++ /dev/null @@ -1,63 +0,0 @@ -text -"Thank you, Brett. To start, I want to outline the principles that are guiding us through these changing economic times. First, we will invest behind categories that will drive the long-term secular trend where digital technology as a percentage of world's GDP will continue to increase.Second, we'll prioritize helping our customers get the most value out of their digital spending, so that they can do more with less. And finally, we will be disciplined in managing our cost structure." -"With that context, this quarter, the Microsoft Cloud again exceeded $25 billion in quarterly revenue, up 24% and 31% in constant currency. And based on current trends continuing, we expect our broader commercial business to grow at around 20% in constant currency this fiscal year, as we manage through the cyclical trends affecting our consumer business. With that, let me highlight our progress starting with Azure. Moving to the cloud is the best way for organizations to do more with less today." -"It helps them align their spend with demand and mitigate risk around increasing energy costs and supply chain constraints. We're also seeing more customers turn to us to build and innovate with infrastructure they already have. With Azure Arc, organizations like Wells Fargo can run Azure services, including containerized applications across on-premises, edge, and multi-cloud environments. We now have more than 8,500 Arc customers, more than double the number a year ago." -"We are the platform of choice for customers' SAP workloads in the cloud, companies like Thabani, Munich Re's, Sodexo, Volvo Cars, all run SAP on Azure. We are the only cloud provider with direct and secure access to Oracle databases running an Oracle Cloud infrastructure, making it possible for companies like FedEx, GE, and Marriott to use capabilities from both companies. And with Azure Confidential Computing, we're enabling companies in highly regulated industries, including RBC, to bring their most sensitive applications to the cloud. Just last week, UBS said it will move more than 50% of its applications to Azure." -"Now to data and AI. With our Microsoft Intelligent Data Platform, we provide a complete data fabric, helping customers cut integration tax associated with bringing together siloed solutions. Customers like Mercedes-Benz are standardizing on our data stack to process and govern massive amounts of data. Cosmos DB is the go-to database powering the world's most demanding workloads at limitless scale." -"Cosmos DB now supports postscript SQL, making Azure the first cloud provider to offer a database service that supports both relational and no SQL workloads. And in AI, we are turning the world's most advanced models into platforms for customers. Earlier this month, we brought the power of DALL-E to Azure OpenAI service, helping customers like Mattel apply the breakthrough image generation model to commercial use cases for the first time. In Azure machine learning, provides industry-leading ML apps, helping organizations like 3M deploy, manage and govern models." -"All of, Azure ML revenue has increased more than 100% for four quarters in a row. Now on to developers. We have the most complete platform for developers to build cloud-native applications. Four years since our acquisition, GitHub is now at $1 billion in annual recurring revenue." -"And GitHub's developer-first ethos has never been stronger. More than 90 million people now use the service to build software for any cloud on any platform up three times. GitHub advanced security is helping organizations improve their security posture by bringing features directly into the developer's workflow. Toyota North America chose the offering this quarter to help its developers build and secure many of its most critical applications." -"Now on to Power Platform. We are helping customers save time and money with our end-to-end suite spanning Low-Code/No-Code tools, robotic process automation, virtual agents, and business intelligence. Power BI is the market leader in business intelligence in the cloud and is growing faster than competition, as companies like Walmart standardize on the tool for reporting and analytics. Power Apps is the market leader in Low-Code/No-Code tools and has nearly 15 million monthly active users, up more than 50% compared to a year ago." -"Power Automate has more than seven million monthly active users and is being used by companies like Brown-Forman, Komatsu, Mass, T-Mobile to digitize manual business processes and save thousands of hours of employee time. And we're going further with new AI-powered capabilities and power automate that turn natural language into advanced workflows. Now on to Dynamics 365. From customer experience and service to finance and supply chain, we continue to take share across all categories we serve." -"For example, Lufthansa Cargo chose us to centralize customer information and related shipments. CBRE is optimizing its field service operations, gaining cost efficiencies. Darden is using our solutions to increase both guest frequency and spend at its restaurants. And Tillamook is scaling its growth and improving supply chain visibility." -"All up more than 400,000 organizations now use our business applications. Now on to Industry Solutions. We are seeing increased adoption of our industry and cross-industry clouds. Bank of Queensland chose our cloud for financial services to deliver new digital experiences for its customers." -"Our cloud for sustainability is off to a fast start as organizations like Telstra use the solution to track their environmental footprint. New updates provide insights on hard-to-measure Scope 3 carbon emissions, and we are seeing record growth in healthcare, driven, in part, by our Nuance DAX ambient intelligence solutions, which automatically documents patient encounters at the point of care. Physicians tell us DAX dramatically improves their productivity, and it's quickly becoming an on-ramp to our broader healthcare offerings. Now on to new systems of work, Microsoft 365, Teams, and Viva uniquely enable employees to thrive in today's digitally connected distributed world of work." -"Microsoft 365 is the cloud-first platform that supports all the ways people work and every type of worker reducing cost and complexity for IT. The new Microsoft 365 app brings together our productivity apps with third-party content, as well as personalized recommendations. Microsoft Teams is the de facto standard for collaboration and has become essential to how hundreds of millions of people meet, call, chat, collaborate and do business. As we emerge from the pandemic, we are retaining users we have gained and are seeing increased engagement, too." -"Users interact with Teams 1,500 times per month on average. In a typical day, the average commercial user spends more time in Teams chat than they do in email, and the number of users who use four or more features within Teams increased over 20% year over year. Teams is becoming a ubiquitous platform for business process. Monthly active enterprise users running third party and custom applications within Teams increased nearly 60% year over year, and over 55% of our enterprise customers who use Teams today also buy Teams Rooms or Teams Phone." -"Teams Phone provides the best-in-class calling. PSTN users have grown by double digits for five quarters in a row. We are bringing Teams Rooms to a growing hardware ecosystem, including Cisco's devices and peripherals, which will now run Teams natively. And we are creating a new category with Microsoft Places to help organizations evolve and manage the space for hybrid and in-person work." -"Just like Outlook calendar orchestrates when people can meet and collaborate, Places will do the same for where. We also announced Teams Premium, addressing enterprise demands for advanced meeting features like additional security options and intelligent meeting recaps. All this innovation is driving growth across Microsoft 365. Leaders in every industry from Fannie Mae and Land O'Lakes to Rabobank continue to turn to our premium E5 offerings for advanced security, compliance, voice, and analytics." -"We've also built a completely new suite for our employee experience platform, Microsoft Viva, which now has more than 20 million monthly active users at companies like Finastra, SES, and Unilever. And we are extending Viva to meet role-specific needs. Viva Sales is helping salespeople at companies like Adobe, Crayon, and PwC reclaim their time by bringing customer interactions across Teams and Outlook directly into their CRM system. Now on to Windows." -"Despite the drop in PC shipments during the quarter, Windows continues to see usage growth. All up, there are nearly 20% more monthly active Windows devices than pre-pandemic. And on average, Windows 10 and Windows 11 users are spending 8.5% more time on their PCs than they were two and a half years ago. And we are seeing larger commercial deployments of Windows 11." -"Accenture, for example, has deployed Windows 11 to more than 450,000 employees' PCs, up from just 25,000, seven months ago, and L'Oreal has deployed the operating system to 85,000 employees. Now to security. Security continues to be a top priority for every organization. We're the only company with integrated end-to-end tools spanning security, compliance, identity and device management, and privacy across all clouds and platforms." -"More than 860,000 organizations across every industry from BP and Fuji Film to ING Bank, iHeartMedia, and Lumen Technologies now use our security solutions, up 33% year over year. They can save up to 60% when they consolidate our security stack, and the number of customers with more than four workloads have increased 50% year over year. More organizations are choosing both our XDR and cloud-native SIM to secure their entire digital estate. The number of E5 customers who also purchased Sentinel increased 44% year over year." -"And as threats become more sophisticated, we are innovating to protect customers. New capabilities in Defender help secure the entire DevOps life cycle and manage security posture across clouds. And Entra now provides comprehensive identity governance for both on-premise and cloud-based user directories. Now on to LinkedIn." -"We once again saw record engagement among our more than 875 million members, with international growth increasing at nearly 2x the pace as in the United States. There are now more than 150 million subscriptions to newsletters on LinkedIn, up 4x year over year. New integrations between Viva and LinkedIn Learning helped companies invest in their existing employees by providing access to courses directly in the flow of work. Members added 365 million skills to their profiles over the last 12 months, up 43% year over year." -"And with our acquisition of EduBrite, they will also soon be able to earn professional certificates from trusted partners directly on the platform. We launched the next-generation sales navigator this quarter, helping sellers increase win rates and deal sizes by better understanding and evaluating customer interest. Finally, LinkedIn Marketing Solution continues to provide leading innovation and ROI in B2B digital advertising. More broadly, with Microsoft Advertising, we offer a trusted platform for any marketeer or advertiser looking to innovate." -"We've expanded our geographies we serve by nearly 4x over the past year. We are seeing record daily usage of Edge, Start, and Bing driven by Windows. Edge is the fastest-growing browser on Windows and continues to gain share as people use built-in coupon price comparison features to save money. We surface more than $2 billion in savings to date." -"And this quarter, we brought our shopping tools to 15 new markets. Users of our Start, personalized content feed are consuming 2x more content compared to a year ago. And we're also expanding our third-party ad inventory. Netflix will launch its first ad-supported subscription plan next month, exclusively powered by our technology and sales." -"And with PromoteIQ we offer an omnichannel media platform for retailers like the auto group looking to generate additional revenue while maintaining ownership of their own data and customer relationships. Now onto gaming. We are adding new gamers to our ecosystem as we execute on our ambition to reach players wherever and whenever they want on any device. We saw usage growth across all platforms driven by the strength of console." -"PC Game Pass subscriptions increased 159% year over year. And with cloud gaming, we're transforming how games are distributed, played and viewed. More than 20 million people have used the service to stream games to date. And we are adding support for new devices like handhelds from Logitech and Razor as well as Meta Quest." -"And as we look toward the holidays, we offer the best value in gaming with Game Pass and Xbox Series S, nearly half of the Series S buyers are new to our ecosystem. In closing, in a world facing increasing headwinds, digital technology is the ultimate tailwind. And we're innovating across the entire tech stack to help every organization, while also focusing intensely on our operational excellence and execution discipline. With that, I'll hand it over to Amy." -"Thank you, Satya, and good afternoon, everyone. Our first quarter revenue was $50.1 billion, up 11% and 16% in constant currency. Earnings per share was $2.35, increased 4% and 11% in constant currency when adjusted for the net tax benefit for the first quarter of fiscal year 2022. Driven by strong execution in a dynamic environment, we delivered a solid start to our fiscal year, in line with our expectations even as we saw many of the macro trends from the end of the fourth quarter continued to weaken through Q1." -"In our consumer business, PC market demand further deteriorated in September, which impacted our Windows OEM and Surface businesses. And reductions in customer advertising spend, which also weakened later in the quarter, impacted search and news advertising and LinkedIn Marketing Solutions. As you heard from Satya, in our commercial business, we saw strong overall demand for our Microsoft cloud offerings with a growth of 31% in constant currency as well as share gains across many businesses. Commercial bookings declined 3% and increased 16% in constant currency on a flat expiry base." -"Excluding the FX impact, growth was driven by strong renewal execution, and we continue to see growth in the number of large long-term Azure and Microsoft 365 contracts across all deal sizes. More than half of the $10 million plus Microsoft 365 bookings came from E5. Commercial remaining performance obligation increased 31% and 34% in constant currency to $180 billion. Roughly 45% will be recognized in revenue in the next 12 months, up 23% year over year." -"The remaining portion, which we recognized beyond the next 12 months, increased 38% year over year, and our annuity mix increased one point year over year to 96%. FX impacted company results in line with expectations. With the stronger US dollar, FX decreased total company revenue by five points, and at the segment level, FX decreased productivity and business processes and intelligent cloud revenue growth by six points and more personal computing revenue growth by three points. Additionally, FX decreased COGS and operating expense growth by three points." -"Microsoft Cloud gross margin percentage increased roughly two points year over year to 73%. Excluding the impact of the change in accounting estimate for useful lives, Microsoft cloud gross margin percentage decreased roughly one point driven by sales mix shift to Azure and lower Azure margin, primarily due to higher energy costs. Company gross margin dollars increased 9% and 16% in constant currency, and gross margin percentage decreased slightly year over year to 69%, excluding the impact of the latest change in accounting estimate, gross margin percentage decreased roughly three points, driven by sales mix shift to cloud, the lower Azure margin noted earlier and Nuance. Operating expense increased 15% and 18% in constant currency, driven by investments in cloud engineering, LinkedIn, Nuance, and commercial sales." -"At a total company level, headcount grew 22% year over year, as we continue to invest in key areas just mentioned, as well as customer deployment. Headcount growth included roughly six points from the Nuance and Xandr acquisitions, which closed last Q3 and Q4, respectively. Operating income increased 6% and 15% in constant currency, and operating margins decreased roughly two points year over year to 43%. Excluding the impact of the change in accounting estimate, operating margins declined roughly four points year over year driven by sales mix shift to cloud, unfavorable FX impact, Nuance, and the lower Azure margin noted earlier." -"Now to our segment results. Revenue from productivity and business processes was $16.5 billion and grew 9% and 15% in constant currency, ahead of expectations, with better-than-expected results in Office commercial and LinkedIn. Office commercial revenue grew 7% and 13% in constant currency. Office 365 commercial revenue increased 11% and 17% in constant currency, slightly better than expected, with the strong renewal execution noted earlier." -"Growth was driven by installed base expansion across all workloads and customer segments, as well as higher ARPU from E5. Demand for security, compliance, and voice value in Microsoft 365 drove strong E5 momentum again this quarter. Paid Office 365 commercial seats grew 14% year over year, driven by our small and medium business and frontline worker offerings, although we saw a continued impact of new deal moderation outside of E5. Office consumer revenue grew 7% and 11% in constant currency, driven by continued momentum in Microsoft 365 subscriptions, which grew 13% to $61.3 million." -"Dynamics revenue grew 15% and 22% in constant currency, driven by Dynamics 365, which grew 24% and 32% in constant currency. LinkedIn revenue increased 17% and 21% in constant currency, ahead of expectations, driven by better-than-expected growth in talent solutions, partially offset by weakness in marketing solutions from the advertising trends noted earlier. Segment gross margin dollars increased 11% and 18% in constant currency, and gross margin percentage increased roughly 1 point year over year. Excluding the impact of the latest change in accounting estimate, gross margin percentage decreased slightly, driven by sales mix shift to cloud offerings." -"Operating expense increased 13% and 16% in constant currency, and operating income increased 10% and 19% in constant currency, including four points due to the latest change in accounting estimate. Next, the Intelligent cloud segment. Revenue was $20.3 billion, increasing 20% and 26% in constant currency, in line with expectations. Overall, server products and cloud services revenue increased 22% and 28% in constant currency." -"Azure and other cloud services revenue grew 35% and 42% in constant currency, about one point lower than expected, driven by the continued moderation in Azure consumption growth, as we help customers optimize current workloads while they prioritize new workloads. In our per-user business, the enterprise mobility and security installed base grew 18% to over 232 million seats, with continued impact from the new deal moderation noted earlier. In our on-premises server business, revenue was flat, and increased 4% in constant currency, slightly ahead of expectations, driven by hybrid demand, including better-than-expected annuity purchasing ahead of the SQL Server 2022 launch. Enterprise services revenue grew 5% and 10% in constant currency, driven by enterprise support services." -"Segment gross margin dollars increased 20% and 26% in constant currency, and gross margin percentage decreased slightly. Excluding the impact of the latest change in accounting estimate, gross margin percentage declined roughly three points, driven by sales mix shift to Azure and higher energy costs impacting Azure margins. Operating expenses increased 25% and 28% in constant currency, including roughly eight points of impact from Nuance. And operating income grew 17% and 25% in constant currency with roughly nine points of favorable impact from the latest change in accounting estimate." -"Now to more personal computing. Revenue decreased slightly year over year to $13.3 billion and grew 3% in constant currency, in line with expectations overall, but with OEM and Surface weakness offset by upside in gaming consoles. Windows OEM revenue decreased 15% year over year. Excluding the impact from the Windows 11 deferral last year, revenue declined 20%, driven by PC market demand deterioration noted earlier." -"Devices revenue grew 2% and 8% in constant currency, in line with expectations, driven by the impact of a large Hollands deal, partially offset by low double-digit declines in consumer Surface sales. Windows commercial products and cloud services revenue grew 8% and 15% in constant currency, in line with expectations, driven by demand for Microsoft 365 E5 noted earlier. Search and news advertising revenue, ex TAC, increased 16% and 21% in constant currency, in line with expectations, benefiting from an increase in search volumes and roughly five points of impact from Xandr even as we saw increased ad market headwinds during September. Edge browser gained share again this quarter." -"And in gaming, revenue grew slightly and was up 4% in constant currency, ahead of expectations, driven by better-than-expected console sales. Xbox hardware revenue grew 13% and 19% in constant currency. Xbox content and services revenue declined 3% and increased 1% in constant currency, driven by declines in first-party content as well as in third-party content where we had lower engagement hours and higher monetization, partially offset by growth in Xbox Game Pass subscriptions. Segment gross margin dollars declined 9% and 4% in constant currency, and gross margin percentage decreased roughly five points year over year driven by sales mix shift to lower margin businesses." -"Operating expenses increased 2% and 5% in constant currency, driven by the Xandr acquisition. And operating income decreased 15% and 9% in constant currency. Now back to total company results. Capital expenditures, including finance leases were $6.6 billion, and cash paid for PP&E was $6.3 billion." -"Our data center investments continue to be based on strong customer demand and usage signals. Cash flow from operations was $23.2 billion, down 5% year over year, driven by strong cloud billings and collections, which were more than offset by a tax payment related to the transfer of intangible property completed in Q1 of FY '22. Free cash flow was $16.9 billion, down 10% year over year. Excluding the impact of this tax payment, cash flow from operations grew 2%, and free cash flow was relatively unchanged [indiscernible] year." -"This quarter, other income and expense was $54 million, driven by interest income, which was mostly offset by interest expense and net losses on foreign currency remeasurement. Our effective tax rate was approximately 19%. And finally, we returned $9.7 billion to shareholders through share repurchases and dividends. Now, moving to our Q2 outlook, which, unless specifically noted otherwise, is on a US dollar basis." -"My commentary, for both the full year and next quarter, does not include any impact from AC division, which we still expect to close by the end of the fiscal year. First, FX. With the stronger US dollar and based on current rates, we now expect FX to decrease total revenue growth by approximately five points and to decrease total COGS and operating expense growth by approximately three points. Within the segments, we anticipate roughly seven points of negative FX impact on revenue growth in productivity and business processes, six points in Intelligent cloud and three points in more personal computing." -"Our outlook has many of the trends we saw at the end of Q1, continue into Q2. In our consumer business, materially weaker PC demand from September will continue, and impact both Windows OEM and Surface device results even as the Windows installed base and usage grows, as you heard from Satya. Additionally, customers focusing our advertising spend will impact LinkedIn and Search and News advertising revenue. In our commercial business, demand for our differentiated hybrid and cloud offerings, together with consistent execution, should drive healthy growth across the Microsoft Cloud." -"In commercial bookings, continued strong execution across core annuity sales motions and commitments to our platform should drive solid growth on a moderately growing expiry base against a strong prior year comparable, which included a significant volume of large long-term Azure contracts. As a reminder, the growing mix of larger long-term Azure contracts which are more unpredictable in their timing, always drives increased quarterly volatility in our bookings growth rate. Microsoft Cloud gross margin percentage should be up roughly one point year over year, driven by the latest accounting estimate change noted earlier. Excluding that impact, Q2 gross margin percentage will decrease roughly two points driven by lower Azure margin, primarily due to higher energy cost, revenue mix shift to Azure and the impact from Nuance." -"In capital expenditures, we expect a sequential increase on a dollar basis with normal quarterly spend variability in the timing of our cloud infrastructure build-out. Next, to segment guidance. In productivity and business processes, we expect revenue to grow between 11% and 13% in constant currency or USD16.6 billion to USD 16.9 billion. In Office Commercial, revenue growth will again be driven by Office 365, with seat growth across customer segments and ARPU growth from E5." -"We expect Office 365 revenue growth to be similar to last quarter on a constant currency basis. In our on-premises business, we expect revenue to decline in the low to mid-30s. In Office Consumer, we expect revenue to decline low to mid-single digits as Microsoft 365 subscription growth will be more than offset by unfavorable FX impact. For LinkedIn, we expect continued strong engagement on the platform, although results will be impacted by a slowdown in advertising spend and hiring, resulting in mid to high single-digit revenue growth or low to mid-teens growth in constant currency." -"And in Dynamics, we expect revenue growth in the low double digits or the low 20s in constant currency, driven by continued share gains in Dynamics 365. For intelligent cloud, we expect revenue to grow between 22% and 24% in constant currency or US$21.25 billion to US$21.55 billion. Revenue will continue to be driven by Azure, which, as a reminder, can have quarterly variability primarily from our per-user business and from in-period recognition depending on the mix of contracts. We expect Azure revenue growth to be sequentially lower by roughly 5 points on a constant currency basis." -"Azure revenue will continue to be driven by strong growth in consumption, with some impact from the Q1 trends noted earlier. And our per user business should continue to benefit from Microsoft 365 suite momentum, though we expect moderation in growth rate given the size of the installed base. In our on-premise server business, we expect revenue to decline low single digits, as demand for our hybrid solutions, including strong annuity purchasing from the SQL Server 2022 launch, will be more than offset by unfavorable FX impact. And in enterprise services, we expect revenue growth to be in the low single digits, driven by enterprise support." -"In More Personal Computing, we expect revenue of US$14.5 billion to US$14.9 billion. In Windows OEM, we expect revenue to decline in the high 30s. Excluding the impact from the Windows 11 revenue deferral last year, revenue would decline mid-30s, reflecting both PC market demand and a strong prior year comparable, particularly in the commercial segment. In devices, revenue should decline approximately 30%, again, roughly in line with the PC market." -"In Windows commercial products and cloud services, customer demand for Microsoft 365 and our advanced security solutions should drive growth in the mid-single digits or low double digits in constant currency. Search and news advertising, ex TAC, should grow in the low to mid-teens, roughly six points faster than overall search and news advertising revenue, driven by growing first-party revenue and the inclusion of Xandr. And in gaming, we expect revenue to decline in the low to mid-teens against a strong prior year comparable. That included several first-party title launches, partially offset by growth in Xbox Game Pass subscribers." -"We expect Xbox content and services revenue to decline in the low to mid-teens. Now back to company guidance. We expect COGS to grow between 6% and 7% in constant currency or to be between US$17.4 billion and US$17.6 billion, and operating expense to grow between 17% and 18% in constant currency, or to be between US$14.3 billion and US$14.4 billion. As we continue to focus our investment in key growth areas, total headcount growth sequentially should be minimal." -"Other income and expense should be roughly $100 million, as interest income is expected to more than offset interest expense. Further FX and equity movements through Q2 are not reflected in this number. And as a reminder, we are required to recognize mark-to-market gains or losses on our equity portfolio, which can increase quarterly volatility. And we expect our Q2 effective tax rate to be between 19% and 20%." -"And finally, as a reminder, for Q2 cash flow, we expect to make a $2.4 billion cash tax payment related to the capitalization of R&D provision enacted in 2017 TCJA and effective as of July 1, 2022. Now some thoughts on the full fiscal year. First, FX. Based on current rates, we now expect a roughly five-point headwind to full-year revenue growth." -"And FX should decrease COGS and operating expense growth by approximately three points. At the total company level, we continue to expect double-digit revenue and operating income growth on a constant currency basis. Revenue will be driven by around 20% constant currency growth in our commercial business, driven by strong demand for our Microsoft cloud offerings. That growth will be partially offset by the increased declines we now see in the PC market." -"With the high margins in our Windows OEM business and the cyclical nature of the PC market, we take a long-term approach to investing in our core strategic growth areas and maintain these investment levels regardless of PC market conditions. Therefore, with our first quarter results and lower expected OEM revenue for the remainder of the year as well as over $800 million of greater-than-expected energy cost, we now expect operating margins in US dollars to be down roughly a point year over year. On a constant currency basis, excluding the incremental impact of the lower Windows OEM revenue and the favorable impact of the latest accounting change, we continue to expect FY 2023 operating margins to be roughly flat year over year. In closing, in this environment, it is more critical than ever to continue to invest in our strategic growth markets such as cloud, security, Teams, Dynamics 365, and LinkedIn where we have opportunities to continue to gain share as we provide problem-solving innovations to our customers." -"And while we continue to help our customers do more with less, we will do the same internally. And you should expect to see our operating expense growth moderate materially through the year. While we focus on growing productivity of the significant headcount investments we've made over the last year. With that, let's go to Q&A." diff --git a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_notebook.ipynb b/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_notebook.ipynb deleted file mode 100644 index 6f56588..0000000 --- a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_notebook.ipynb +++ /dev/null @@ -1,857 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "403555d2-4703-4bec-94ec-9d17ec656d62", - "metadata": {}, - "source": [ - "# Indexing Delimited Files on Azure AI Search" - ] - }, - { - "cell_type": "markdown", - "id": "e421b4fd", - "metadata": {}, - "source": [ - "## Overview\n", - "LLMs work best when querying vector databases (DBs). In a few of our tutorials in this repo, we have created vector DBs from unstructured data like PDF documents. Here, we create a vector DB from structured data, which is technically complex and requires additional steps. Here we will vectorize (embed) a csv file, index our DB using Azure AI Search, and then query our vector DB using a GPT model deployed within Azure AI Studio." - ] - }, - { - "cell_type": "markdown", - "id": "f3fe0439", - "metadata": {}, - "source": [ - "## Prerequisites\n", - "We assume you have access to Azure AI Studio and Azure AI Search Service and have already deployed an LLM." - ] - }, - { - "cell_type": "markdown", - "id": "6c5376ef", - "metadata": {}, - "source": [ - "## Learning objectives\n", - "\n", - "This tutorial will cover the following topics:\n", - "+ Introduce embeddings from structured data\n", - "+ Create Azure AI Search index from command line\n", - "+ Query Azure AI Search index from command line using LLMs\n" - ] - }, - { - "cell_type": "markdown", - "id": "6fd8094c", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "id": "7efcb4f8-f3a1-4ea8-b826-012ceb733f4a", - "metadata": {}, - "source": [ - "### Install packages" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "adb68924-26c9-4e6e-9880-2ea371c8d188", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "pip install -U \"langchain\" \"openai\" \"langchain-openai\" \"langchain-community\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5292c962-637e-4169-ad77-2e62da44596f", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "pip install azure-search-documents --pre --upgrade" - ] - }, - { - "cell_type": "markdown", - "id": "687d3dea-ea4c-4eea-8e5a-cff78c0340de", - "metadata": {}, - "source": [ - "### Import CSV data" - ] - }, - { - "cell_type": "markdown", - "id": "d4687557-c31a-4b6c-a17a-8628e46ad7a3", - "metadata": {}, - "source": [ - "For this tutorial we are using a Kaggle dataset about data scientist salaries from 2023. This dataset can be downloaded from [here](https://www.kaggle.com/datasets/henryshan/2023-data-scientists-salary)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ed34bedc-6339-4991-96b3-e9a2ac62b1a4", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import numpy as np \n", - "# reading the csv file using read_csv\n", - "# storing the data frame in variable called df\n", - "df = pd.read_csv('ds_salaries.csv')\n", - " \n", - "df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "95c03a9b-9719-45e3-9bca-31fd310eb916", - "metadata": {}, - "source": [ - "Add an ID to each row of your data this will be the key in our Index. If you choose to use your own data make sure to clean up any trailing whitespaces or punctuation. Your headers should not have any spaces between the words." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a41c5439-4b14-41a3-aaf4-c6f704c9f232", - "metadata": {}, - "outputs": [], - "source": [ - "df['ID'] = np.arange(df.shape[0]).astype(str)\n", - "\n", - "#making the entire dataset into strings\n", - "df= df.astype(str)\n", - "df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "db997a43-4195-487f-b023-795d361db993", - "metadata": {}, - "source": [ - "#### Optional: Adding embeddings to our data" - ] - }, - { - "cell_type": "markdown", - "id": "84a03ce7-87a4-4e94-acd1-cd01fa3cfa81", - "metadata": {}, - "source": [ - "If you want to add embeddings to your data you can run the code below! Embeddings will help our vector store (Azure AI Search) to retrieve relevant information based on the query or question you have supplied the model. Here we use the embedding **text-embedding-ada-002** to convert our data into numerical values which represents how similar each word is to another in your data. Embedding are usually used for dense data so if you have any columns in your dataset that contains sentences of text its recommended to add embeddings. Although the dataset we are using doesn't have that for this example we will be adding embeddings for the `job_title` column and add them to a new column called and `job_title_vector`.\n", - "\n", - "**If you don't want to add embeddings you can skip this code cell and run the [next one](#csv2json).**" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "87181df6-c8d5-4498-ac6b-faa86631125e", - "metadata": {}, - "outputs": [], - "source": [ - "os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"\"\n", - "os.environ[\"AZURE_OPENAI_KEY\"] = \"\"\n", - "\n", - "#create embeddings functions to apply to a given column\n", - "from openai import AzureOpenAI\n", - " \n", - "client = AzureOpenAI(\n", - " api_key=os.getenv(\"AZURE_OPENAI_KEY\"), \n", - " api_version=\"2023-05-15\",\n", - " azure_endpoint = os.getenv(\"AZURE_OPENAI_ENDPOINT\")\n", - " )\n", - "\n", - "def generate_embeddings(text, model=\"text-embedding-ada-002\"):\n", - " return client.embeddings.create(input = [text], model=model).data[0].embedding\n", - "\n", - "#adding embeddings for job title to get more accurate search results\n", - "df['job_title_vector'] = df['job_title'].apply(lambda x : generate_embeddings (x)) # model should be set to the deployment name you chose when you deployed the text-embedding-ada-002 (Version 2) model" - ] - }, - { - "cell_type": "markdown", - "id": "c0b1da1e-4eda-47c3-a8d4-d04df80b0476", - "metadata": {}, - "source": [ - " Now we will convert our dataframe into JSON format. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fd4c4453-d958-49ad-9b72-34a829ac0437", - "metadata": {}, - "outputs": [], - "source": [ - "df_json = df.to_json(orient=\"records\")" - ] - }, - { - "cell_type": "markdown", - "id": "a532eacf-ff14-44fc-b703-844f83c846bd", - "metadata": {}, - "source": [ - "### Connect to our Azure Open AI Models" - ] - }, - { - "cell_type": "markdown", - "id": "6bfd4382-8809-4bb8-8940-68d81f8fba44", - "metadata": {}, - "source": [ - "Here we are setting the keys and endpoint to our OpenAI models as environmental variables which will help us connect to our LLM model which in this case is **gpt-4**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0377877c-73f4-4508-9a4f-9ddcd14bea96", - "metadata": {}, - "outputs": [], - "source": [ - "os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"\"\n", - "os.environ[\"AZURE_OPENAI_KEY\"] = \"\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b1c91f3a-5a72-463c-b869-a970ae1139df", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from openai import AzureOpenAI\n", - " \n", - "client = AzureOpenAI(\n", - " api_key=os.getenv(\"AZURE_OPENAI_KEY\"), \n", - " api_version=\"2023-05-15\",\n", - " azure_endpoint = os.getenv(\"AZURE_OPENAI_ENDPOINT\")\n", - " )" - ] - }, - { - "cell_type": "markdown", - "id": "daa799c1-f587-4c9b-b1bc-7bc37415ca12", - "metadata": {}, - "source": [ - "### Create Azure AI Search Service" - ] - }, - { - "cell_type": "markdown", - "id": "da8b68e1-2488-41d1-be51-436cb47e5c86", - "metadata": {}, - "source": [ - "Enter in the name you would like for your AI Search service and index along with the name of your resource group and the location you would like your index to be held in." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "711cbd23-73ab-4ce0-b499-0f254549a7c3", - "metadata": {}, - "outputs": [], - "source": [ - "service_name=''\n", - "index_name = ''\n", - "location = 'eastus2'\n", - "resource_group = ''" - ] - }, - { - "cell_type": "markdown", - "id": "53d9a98f-4772-48ea-acef-0f1e947685e4", - "metadata": {}, - "source": [ - "Authenticate to use Azure cli, follow the outputs instructions." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "63ab007c-5c88-4206-aa51-318fc3e82292", - "metadata": {}, - "outputs": [], - "source": [ - "! az login" - ] - }, - { - "cell_type": "markdown", - "id": "19a076aa-d2c1-4709-aec2-9532e6457e48", - "metadata": {}, - "source": [ - "Create your Azure AI Search service." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bf4f5c0e-3fb6-4f79-aaf4-a8f9920af590", - "metadata": {}, - "outputs": [], - "source": [ - "! az search service create --name {service_name} --sku free --location {location} --resource-group {resource_group} --partition-count 1 --replica-count 1" - ] - }, - { - "cell_type": "markdown", - "id": "94fd109a-2729-47b3-9327-811e2ce598b9", - "metadata": {}, - "source": [ - "Save the key to a JSON file and then we will save the value to our **search_key** variable." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd6b4dee-0ea2-434e-b98f-55d22e871f36", - "metadata": {}, - "outputs": [], - "source": [ - "! az search admin-key show --resource-group {resource_group} --service-name {service_name} > keys.json" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b0c98d31-ebad-4e66-adef-abcbe222f317", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "with open('keys.json', mode='r') as f:\n", - " data = json.load(f)\n", - "search_key = data[\"primaryKey\"]" - ] - }, - { - "cell_type": "markdown", - "id": "c4cc7e03-d080-4486-9e0d-30167fec715a", - "metadata": {}, - "source": [ - "### Create Azure AI Index" - ] - }, - { - "cell_type": "markdown", - "id": "dc9f88db-a05a-499a-891b-be32ec44cd97", - "metadata": {}, - "source": [ - "Import the necessary tools to create our index and the fields this will be our **vector store**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "094c737d-d941-4681-ac78-e499f9b96805", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "\n", - "from azure.search.documents import SearchClient\n", - "from azure.core.credentials import AzureKeyCredential\n", - "from azure.search.documents.indexes import SearchIndexClient, SearchIndexerClient\n", - "from azure.search.documents.indexes.models import (\n", - " SimpleField,\n", - " SearchField,\n", - " SearchableField,\n", - " SearchFieldDataType,\n", - " SearchIndexerDataContainer,\n", - " SearchIndexerDataSourceConnection,\n", - " SearchIndex,\n", - " SearchIndexer,\n", - " TextWeights,\n", - " VectorSearch,\n", - " VectorSearchProfile,\n", - " HnswAlgorithmConfiguration,\n", - " ComplexField\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "5e836161-1910-411a-8dfa-7820c0fc9bd0", - "metadata": {}, - "source": [ - "Create your index client to pass on information about our index too." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "80e780b6-a045-4779-876a-2b36e4dc5225", - "metadata": {}, - "outputs": [], - "source": [ - "endpoint = \"https://{}.search.windows.net/\".format(service_name)\n", - "index_client = SearchIndexClient(endpoint, AzureKeyCredential(index_key))" - ] - }, - { - "cell_type": "markdown", - "id": "defec19a-0a82-413d-9a6b-13b9db5873b7", - "metadata": {}, - "source": [ - "Next you will add in the field names to the index which are based on the names of your columns. Notice that the **Key** is our 'ID' column and it is a string also that even columns that hold integers will also be strings because we want to be able to search and retrieve data from our index which can only be done so if our data is in string format.\n", - "\n", - "If you **added embeddings** to your data skip to the next section [Adding Embeddings to Vector Store](#Embeddings-to-Vector-Store)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a949a7ec-6a28-43ed-b16a-0245836a187f", - "metadata": {}, - "outputs": [], - "source": [ - "fields = [\n", - " SimpleField(\n", - " name=\"ID\",\n", - " type=SearchFieldDataType.String,\n", - " key=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"work_year\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"experience_level\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ), \n", - " SearchableField(\n", - " name=\"employment_type\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"job_title\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"salary\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"salary_currency\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"salary_in_usd\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"employee_residence\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"remote_ratio\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"company_location\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"company_size\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " )\n", - "]\n", - " \n", - "#set our index values\n", - "index = SearchIndex(name=index_name, fields=fields)\n", - "#create our index\n", - "index_client.create_index(index)\n" - ] - }, - { - "cell_type": "markdown", - "id": "a7c113a3-3b95-4359-b307-73dda33d5394", - "metadata": {}, - "source": [ - "

Optional: Adding Embeddings to Vector Store

" - ] - }, - { - "cell_type": "markdown", - "id": "361e905c-a945-427f-ac03-741ff6bb54be", - "metadata": {}, - "source": [ - "If you are working with embeddings you need to add a **SearchField** that holds a collection which is your array of numerical values. The name of the column is the same as our dataset **job_title_vector**. We also need to set a **vector profile** which dictates what algorithm we will have our vector store use to find text that are similar to each other (find the nearest neighbors) for this profile we will be using the **Hierarchical Navigable Small World (HNSW) algorithm**, we have named our profile **vector_search**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8107360d-a4f2-4b55-9fe0-8cf8ea3c618a", - "metadata": {}, - "outputs": [], - "source": [ - "fields = [\n", - " fields = [\n", - " SimpleField(\n", - " name=\"ID\",\n", - " type=SearchFieldDataType.String,\n", - " key=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"work_year\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"experience_level\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ), \n", - " SearchableField(\n", - " name=\"employment_type\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"job_title\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchField(\n", - " name=\"job_title_vector\",\n", - " type=SearchFieldDataType.Collection(SearchFieldDataType.Single),\n", - " searchable=True,\n", - " vector_search_dimensions=len(generate_embeddings(\"Text\")),\n", - " vector_search_profile_name=\"my-vector-config\"\n", - " ),\n", - " SearchableField(\n", - " name=\"salary\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"salary_currency\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"salary_in_usd\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"employee_residence\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"remote_ratio\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"company_location\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"company_size\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " )\n", - "]\n", - "\n", - "vector_search = VectorSearch(\n", - " profiles=[VectorSearchProfile(name=\"my-vector-config\", algorithm_configuration_name=\"my-algorithms-config\")],\n", - " algorithms=[HnswAlgorithmConfiguration(name=\"my-algorithms-config\")],\n", - ")\n", - " \n", - "#set our index values\n", - "index = SearchIndex(name=index_name, fields=fields, vector_search=vector_search)\n", - "#create our index\n", - "index_client.create_index(index)\n" - ] - }, - { - "cell_type": "markdown", - "id": "07ed728d-2af3-42d5-843c-e94266ce66d1", - "metadata": {}, - "source": [ - "### Upload Data to our Index" - ] - }, - { - "cell_type": "markdown", - "id": "b65aece2-ad33-4600-b862-a1eedd2cf50a", - "metadata": {}, - "source": [ - "Here we are creating a **search client** that will allow us to upload our data to our index and query our index." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a3273fd-748e-41ee-ad42-6af31db93855", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.search.documents import SearchClient\n", - "search_client = SearchClient(endpoint, index_name, AzureKeyCredential(index_key))" - ] - }, - { - "cell_type": "markdown", - "id": "e2dd96f4-439e-4c74-877e-6da7b10331ff", - "metadata": {}, - "source": [ - "Next we will convert our dataset into a JSON object because even though it is in JSON format its still labeled as a Python object. After that we will upload each row of our data, or in this case, since we are now dealing with JSON, each group as a separate document. This process is essentially **chunking** our data to help our index easily query our data and only retrieve the groups that hold similar text to the our query. This also minimizes hallucinations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d151e32a-ad57-4cf4-9928-8f8933e98959", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "import json\n", - " \n", - "# Convert JSON data to a Python object\n", - "data = json.loads(df_json)\n", - "\n", - "# Iterate through the JSON array\n", - "for item in data:\n", - " result = search_client.upload_documents(documents=[item])\n", - "\n", - "print(\"Upload of new document succeeded: {}\".format(result[0].succeeded))" - ] - }, - { - "cell_type": "markdown", - "id": "fc10ce7e-e9da-443e-9cd1-7cad4faa740b", - "metadata": {}, - "source": [ - "### Interacting with our Model" - ] - }, - { - "cell_type": "markdown", - "id": "b9630cd3-98ab-456f-8e3e-095ce6982143", - "metadata": {}, - "source": [ - "First, we will write our query. You can run any of the ones below or make your own. That query will be passed to our index which will then give us results of documents that held similar text to our query." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7f13c6e1-c719-4fae-a097-f6d7f5081caa", - "metadata": {}, - "outputs": [], - "source": [ - "query = \"Please count how many ML Engineers are there.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4dcf66f5-a0e1-4b9b-9b55-532b9ead433a", - "metadata": {}, - "outputs": [], - "source": [ - "query = \"Please list the unique job titles.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34af7401-4c24-4e5f-888a-990e72e82afc", - "metadata": {}, - "outputs": [], - "source": [ - "query = \"Please count how many employees worked in 2020.\"" - ] - }, - { - "cell_type": "markdown", - "id": "011eedb0-663e-4e4b-9304-f2a810ad5992", - "metadata": {}, - "source": [ - "Here is where we will input our query and then fix the formatting of the results in a way that our model can understand. This will mean first gathering our results in a list, removing any unncessary keys to lessen the token count, converting that list into JSON format so that it is also a string, and then adding quotes around spaces for the model to better decipher our query results." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e34ae18-89f3-40f6-96c6-25b9b1ec5c09", - "metadata": {}, - "outputs": [], - "source": [ - "#gathering our query results\n", - "search_results = list(search_client.search(query))\n", - "\n", - "#removing any removing any unncessary keys to lessen the token count (some of these are provided by the vector store)\n", - "#job_title_vector is for users that included embeddings to their data\n", - "remove_keys = ['job_title_vector', '@search.reranker_score', '@search.highlights', '@search.captions', '@search.score']\n", - "for l in search_results:\n", - " for i in remove_keys:\n", - " l.pop(i, None)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e35dfd1c-06ed-47cf-b6d7-bb6368ff203b", - "metadata": {}, - "outputs": [], - "source": [ - "#converting that list into JSON format\n", - "search_results = json.dumps(search_results)\n", - "#adding quotes around spaces\n", - "context=' '.join('\"{}\"'.format(word) for word in search_results.split(' '))" - ] - }, - { - "cell_type": "markdown", - "id": "e4a6d875-4ce3-4a0d-a803-d65eebb17821", - "metadata": {}, - "source": [ - "We will then pass our context and query to our model via a message." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "69ff5e34-c60f-4e99-a3f3-29950c6e617b", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "response = client.chat.completions.create(\n", - " model=\"gpt-4\",\n", - " messages=[\n", - " {\"role\": \"system\", \"content\": \"You are a helpful assistant who answers only from the given Context and answers the question from the given Query. If you are asked to count then you must count all of the occurances mentioned.\"},\n", - " {\"role\": \"user\", \"content\": \"Context: \"+ context + \"\\n\\n Query: \" + query}\n", - " ],\n", - " #max_tokens=100,\n", - " temperature=1,\n", - " top_p=1,\n", - " n=1\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "2cf1549d-fea7-4a37-b94c-269724c7c519", - "metadata": {}, - "source": [ - "Now we can see our results!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1541aa6e-e09c-4151-9938-c42c063e6dcf", - "metadata": {}, - "outputs": [], - "source": [ - "response.choices[0].message.content" - ] - }, - { - "cell_type": "markdown", - "id": "31c915c9", - "metadata": {}, - "source": [ - "## Conclusion\n", - "Here we created embeddings from structured data and fed these embeddings to our LLM. Key skills you learned were to : \n", - "+ Create embeddings and a vector store using Azure AI Search\n", - "+ Send prompts to the LLM grounded on your structured data" - ] - }, - { - "cell_type": "markdown", - "id": "0459e0ae-5183-4b6a-9eca-41c97b0b8a8c", - "metadata": {}, - "source": [ - "## Clean up" - ] - }, - { - "cell_type": "markdown", - "id": "edb500e2-c8cb-428c-85f7-d4886d89899d", - "metadata": {}, - "source": [ - "**Warning:** Dont forget to delete the resources we just made to avoid accruing additional costs, including shutting down your Azure ML compute, delete your AI search resource, and optionally delete your deployed models in AI Studio" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4d0e5690-1e15-4c97-9422-410c54a92f6f", - "metadata": {}, - "outputs": [], - "source": [ - "#delete search service this will also delete any indexes\n", - "! az search service delete --name {service_name} --resource-group {resource_group} -y" - ] - } - ], - "metadata": { - "kernel_info": { - "name": "python38-azureml" - }, - "kernelspec": { - "display_name": "Python 3.8 - AzureML", - "language": "python", - "name": "python38-azureml" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - }, - "microsoft": { - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_with_console.ipynb b/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_with_console.ipynb deleted file mode 100644 index 5ad4ee9..0000000 --- a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_index_structured_with_console.ipynb +++ /dev/null @@ -1,413 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Indexing Delimited Files on Azure AI Search using Console and Notebook" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Overview\n", - "LLMs work best when querying vector databases (DBs). In a few of our tutorials in this repo, we have created vector DBs from unstructured data like PDF documents. Here, we create a vector DB from structured data, which is technically complex and requires additional steps. Here we will vectorize (embed) a csv file, index our DB using Azure AI Search, and then query our vector DB using a GPT model deployed within Azure AI Studio.\n", - "\n", - "This notebook differs slightly from the tutorial titled `AzureAIStudio_index_structured_notebook.ipynb` in that here we create the index within Azure AI Search directly, rather than in the notebook. We also use NIH grant data here rather than a Kaggle dataset. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Prerequisites\n", - "We assume you have access to both Azure AI Studio and Azure AI Search Service, and have already deployed an LLM." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Learning objectives\n", - "\n", - "This tutorial will cover the following topics:\n", - "+ Introduce embeddings from structured data\n", - "+ Create Azure AI Search index from the console\n", - "+ Query Azure AI Search index from command line using LLMs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Install packages" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Use Python3 (ipykernel) kernel" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1707424158923 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "pip install langchain openai" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Import libraries" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1707412445314 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "import pandas as pd\n", - "from openai import AzureOpenAI\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Connect to an index\n", - "This is the index you created via [these instructions](https://github.com/STRIDES/NIHCloudLabAzure/blob/main/docs/create_index_from_csv.md).\n", - "Look [here](https://learn.microsoft.com/en-us/azure/search/search-create-service-portal#name-the-service) for your endpoint name, and [here](https://learn.microsoft.com/en-us/azure/search/search-security-api-keys?tabs=portal-use%2Cportal-find%2Cportal-query#find-existing-keys) for your index key." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1707412411658 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "endpoint=\"\"\n", - "index_name=\"\"\n", - "index_key=''" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "#connect to vector store \n", - "from azure.search.documents import SearchClient\n", - "from azure.core.credentials import AzureKeyCredential\n", - "\n", - "search_client = SearchClient(endpoint, index_name, AzureKeyCredential(index_key))" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Connect to your model\n", - "First, make sure you have a [model deployed](https://learn.microsoft.com/en-us/azure/ai-studio/how-to/deploy-models-openai), and if not, deploy a model.\n", - "To get your endpoint, key, and version number, just go to the Chat Playground and click **View Code** at the top." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1707412412208 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "#connect to model\n", - "os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"\"\n", - "os.environ[\"AZURE_OPENAI_API_KEY\"] = \"\",\n", - " azure_endpoint = \"\",\n", - " openai_api_key=\"\",\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Run the prompt against the LLM" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1699909895704 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "message = HumanMessage(\n", - " content=\"Translate this sentence from English to French: Why all the hype about Generative AI?\"\n", - ")\n", - "llm([message])" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Use the LLM to summarize a scientific document" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Now let's load in a scientific document to run a query against. Read more about document loaders from langchain [here](https://python.langchain.com/docs/modules/data_connection/document_loaders/pdf). Note that we are both loading, and splitting our document. You can read more about the default document chunking/splitting procedures [here](https://python.langchain.com/docs/modules/data_connection/document_transformers/#get-started-with-text-splitters)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1699909908495 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "loader = WebBaseLoader(\"https://pubmed.ncbi.nlm.nih.gov/37883540/\")\n", - "pages = loader.load_and_split()" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Define that we want to use [stuffing](https://python.langchain.com/docs/modules/chains/document/stuff) to summarize the document." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1699909918382 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "chain = load_summarize_chain(model, chain_type=\"stuff\")\n", - "\n", - "chain.run(pages)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Conclusion\n", - "In this notebook you learned how to feed a PDF document directly to an LLM that you deployed in the Azure console and summarize the document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Clean up\n", - "Make sure to shut down your Azure ML compute and if desired you can delete your deployed model on Azure AI Studio." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernel_info": { - "name": "python310-sdkv2" - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_sql_chatbot.ipynb b/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_sql_chatbot.ipynb deleted file mode 100644 index fb76a70..0000000 --- a/tutorials/notebooks/GenAI/notebooks/AzureAIStudio_sql_chatbot.ipynb +++ /dev/null @@ -1,678 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "66bdb4fe-7ae4-4b3f-8b61-0004d49baa91", - "metadata": {}, - "source": [ - "# Creating a chatbot for structured data using SQL" - ] - }, - { - "cell_type": "markdown", - "id": "4d7509ad", - "metadata": {}, - "source": [ - "## Overview\n", - "**Generative AI (GenAI)** is a groundbreaking technology that generates human-like texts, images, code, and other forms of content. Although this is all true the focus of many GenAI techniques or implementations have been on unstructured data such as PDF's, text docs, image files, websites, etc. where it is required to set a parameter called *top K*. Top K utilizes an algorithm to only retrieve the top scored pieces of content or docs that is relevant to the users ask. This limits the amount of data the model is presented putting a disadvantage for users that may want to gather information from structured data like CSV and JSON files because they typically want all the occurrences relevant data appears. \n", - "\n", - "An example would be if you had a table that lists different types of apples, where they originate, and their colors and you want a list of red apples that originate from the US the model would only give you partial amount of the data you need because it is limited to looking for the top relevant data which may be limited to only finding the top 4 or 20 names of apples (depending on how you have configured your model) instead of listing them all. \n", - "\n", - "The technique that is laid our in this tutorial utilizes **SQL databases** and asks the model to create a query based on the ask of the user. It will then submit that query to the database and present the user with the results. This will not only give us all the information we need but will also decrease the chances of hitting our token limit." - ] - }, - { - "cell_type": "markdown", - "id": "6c69574a-dc53-414c-9606-97c1f871f603", - "metadata": {}, - "source": [ - "## Prerequisites" - ] - }, - { - "cell_type": "markdown", - "id": "7497c624-f592-4061-8dbf-8a9e2baf7fb2", - "metadata": {}, - "source": [ - "We assume you have access to Azure AI Studio, Azure SQL Databases, and have already deployed an LLM. For this tutorial we used **gpt 3.5** and used the **Python 3.10** kernel within our Azure Jupyter notebook." - ] - }, - { - "cell_type": "markdown", - "id": "431e4421-0b41-4a12-9811-0d7a030cf0f9", - "metadata": {}, - "source": [ - "## Learning objectives" - ] - }, - { - "cell_type": "markdown", - "id": "8aee4c83-bb83-442b-a158-61962f43c80a", - "metadata": {}, - "source": [ - "In this tutorial you will learn:\n", - "- Setting up a Azure SQL database\n", - "- Creating a SQl table and query from it\n", - "- Creating a chatbot and utilizing langchains SQL agent to connect the bot to a database" - ] - }, - { - "cell_type": "markdown", - "id": "3d2aa60a-cf87-4083-80fa-e9dc9179dcc8", - "metadata": {}, - "source": [ - "## Table of Contents" - ] - }, - { - "cell_type": "markdown", - "id": "3bad1638-6fcd-4299-b714-48c7cfd865ff", - "metadata": {}, - "source": [ - "- [Summary](#summary)\n", - "- [Install Packages](#packages)\n", - "- [Create Azure SQL Database](#azure_db)\n", - "- [Create Azure SQL Table](#azure_table)\n", - "- [Submitting a Query](#query)\n", - "- [Setting up a Chatbot](#chatbot)\n", - "- [Conclusion](#conclusion)\n", - "- [Cleaning up Resources](#cleanup)" - ] - }, - { - "cell_type": "markdown", - "id": "3d98bdb4", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "id": "79baaa6a-b851-45b5-9002-68af981fb145", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Install packages " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db3117be-a03f-490f-84ed-b322d9df992e", - "metadata": {}, - "outputs": [], - "source": [ - "pip install 'pyodbc' 'fast_to_sql' 'sqlalchemy'\n", - "pip install --upgrade \"langchain-openai\" \"langchain\" \"langchain-community\"" - ] - }, - { - "cell_type": "markdown", - "id": "094bf011-77ca-41ba-a42c-b2b95f890fc7", - "metadata": {}, - "source": [ - "### Create Azure SQL Database " - ] - }, - { - "cell_type": "markdown", - "id": "64e959a6-4515-49cd-bdf8-b0da0544c10a", - "metadata": {}, - "source": [ - "Follow the instructions [here](https://learn.microsoft.com/en-us/azure/azure-sql/database/single-database-create-quickstart?view=azuresql&tabs=azure-portal) to create a single database in Azure SQL Database. Note that for this tutorials database the field name **Use existing data** was set to **None**." - ] - }, - { - "cell_type": "markdown", - "id": "35d70a02-7a15-4c32-b453-3a97752f9755", - "metadata": {}, - "source": [ - "### Create Azure SQL Table " - ] - }, - { - "cell_type": "markdown", - "id": "69ff0cb2-89cb-4c34-a7c0-19cd09b1d3fb", - "metadata": {}, - "source": [ - "Now that we have our SQL database we will connect to it using the python package `pyodbc` which will allow us to commit changes to our database and query tables." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5776725d-df8e-4a74-8b01-eb4f33a74b83", - "metadata": {}, - "outputs": [], - "source": [ - "import pyodbc\n", - "\n", - "server_name = \"\"\n", - "user = \"\"\n", - "password = \"\"\n", - "database = \"\"\n", - "driver= '{ODBC Driver 18 for SQL Server}'\n", - "\n", - "conn = pyodbc.connect('DRIVER='+driver+';PORT=1433;SERVER='+server+'.database.windows.net/;PORT=1443;DATABASE='+database+';UID='+user+';PWD='+ password)" - ] - }, - { - "cell_type": "markdown", - "id": "506c4b63-276e-438a-a1e5-f4b16ff34cfd", - "metadata": {}, - "source": [ - "Now that we are connected to our database we can upload our data as a table, in this example we are using a csv file from Kaggle that can be downloaded from [here](https://www.kaggle.com/datasets/henryshan/2023-data-scientists-salary). \n", - "\n", - "**Tip:** If you are using a json file you can used the command `pd.read_json` to load in the data frame." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6db341b4-62c0-4bb4-a9b6-925b7ebbeccd", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import numpy as np \n", - "# reading the csv file using read_csv and storing the data frame in variable called df\n", - "df = pd.read_csv('ds_salaries.csv')\n", - "\n", - "# view the data\n", - "df.head()" - ] - }, - { - "cell_type": "markdown", - "id": "d071bf99-2f0d-4450-935c-94732a1f27f7", - "metadata": {}, - "source": [ - "**Tip:** If you receive a **timeout error** wait a couple of minutes and then run the above code again." - ] - }, - { - "cell_type": "markdown", - "id": "48f72cf4-b307-47b1-a3e4-7b5809ec7715", - "metadata": {}, - "source": [ - "Our second python package we are using is `fast_to_sql` **(fts)** which will allow us to easily create tables from our data. Usually, you would have to create a SQL query that outlines the columns, datatype, and values of our table but **fts** does all the work for us." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "41c6cba4-f6f0-4210-a116-1a0242804fae", - "metadata": {}, - "outputs": [], - "source": [ - "from fast_to_sql import fast_to_sql as fts\n", - "table_name = \"ds_salaries\"\n", - "create_table = fts(df, table_name , conn, if_exists=\"replace\", temp=\"FALSE\")" - ] - }, - { - "cell_type": "markdown", - "id": "8beb69bb-864c-41e9-b5d2-0ed9625861b8", - "metadata": {}, - "source": [ - "Now we will commit our change to make it permanent." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "298dbb17-b78a-4b72-8ac2-db18581a8cc8", - "metadata": {}, - "outputs": [], - "source": [ - "conn.commit()" - ] - }, - { - "cell_type": "markdown", - "id": "5d68afeb-3166-4729-9dd4-7c67e84f7673", - "metadata": {}, - "source": [ - "### Submiting a query " - ] - }, - { - "cell_type": "markdown", - "id": "217c8b47-ac37-4c28-aa5b-01a7cc997e7a", - "metadata": {}, - "source": [ - "To submit a query to our database we first need to establish our connection with a **cursor** which allows you to process data row by row.\n", - "\n", - "**Tip:** At any time you can close the connection to your database using the command `conn.close()`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5f0f9982-87fa-43c0-9b5a-0c349efad1e6", - "metadata": {}, - "outputs": [], - "source": [ - "cursor = conn.cursor()" - ] - }, - { - "cell_type": "markdown", - "id": "a67e7f2a-c081-47db-a699-e64987f8ed58", - "metadata": {}, - "source": [ - "Now we can finally submit a query to our database! In the query below we ask to count the number of workers that worked in 2023. Then we use the `execute` command to send our query to the database. The result will be an **iterable** which we will need to create a for loop to see our query result. the result you should receive is **1785**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "329f1fa3-a542-4033-926b-58e55085c73b", - "metadata": {}, - "outputs": [], - "source": [ - "query=\"SELECT COUNT(work_year) FROM ds_salaries WHERE work_year = '2023';\"\n", - "\n", - "cursor.execute(query)\n", - "for row in cursor:\n", - " print(f'QUERY RESULT: {str(row)}') " - ] - }, - { - "cell_type": "markdown", - "id": "5666452a-54be-414f-a29d-561f91f6de82", - "metadata": {}, - "source": [ - "Another way to output our query is to make it into a list and we can use the python function `replace` to get rid of the parentheses." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "117d2be0-6e06-4f57-81e7-51ce2548e71a", - "metadata": {}, - "outputs": [], - "source": [ - "query=\"\"\"SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('ds_salaries') \n", - "\"\"\"\n", - "cursor.execute(query)\n", - "\n", - "result = [str(row).replace(\"('\", \"\").replace(\"',)\", \"\") for row in cursor]\n", - "\n", - "print(result)" - ] - }, - { - "cell_type": "markdown", - "id": "9523a38d-16b7-4c34-a8bc-af64ae696853", - "metadata": {}, - "source": [ - "### Setting up a chatbot " - ] - }, - { - "cell_type": "markdown", - "id": "0b2aa0b8-fcc1-440d-b5fe-4762f0ec7f86", - "metadata": {}, - "source": [ - "For our chatbot we will be utilizing langchain to connect our model to our database." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f2225a78-8919-4821-ba29-d14f8445ace0", - "metadata": {}, - "outputs": [], - "source": [ - "#load in the required tools\n", - "from langchain_openai import AzureChatOpenAI\n", - "from sqlalchemy import create_engine\n", - "from langchain.agents import AgentType, create_sql_agent\n", - "from langchain.sql_database import SQLDatabase\n", - "from langchain.agents.agent_toolkits.sql.toolkit import SQLDatabaseToolkit" - ] - }, - { - "cell_type": "markdown", - "id": "4d09ef93-36e5-41e5-89e3-f7b34355b6da", - "metadata": {}, - "source": [ - "Enter in your OpenAI model's endpoint and key. For this tutorial we used gpt 3.5." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ad907b4-37f2-4536-b87d-1132d8dad04e", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"\"\n", - "os.environ[\"AZURE_OPENAI_API_KEY\"] = \"\"" - ] - }, - { - "cell_type": "markdown", - "id": "1e44d275-e7cc-4ad0-acc3-d61f8b97f0aa", - "metadata": {}, - "source": [ - "Set our model to the variable `llm` and enter the model name which was set when the model was deployed, this will connect langchain to our model. We are also setting the **temperature** to **0** because we don't want any randomness or creativity in the models answer only what is in the date." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0b026497-73b5-4d93-8cf4-3e0fd4a5c72c", - "metadata": {}, - "outputs": [], - "source": [ - "model_name=\"\"\n", - "\n", - "llm = AzureChatOpenAI(\n", - " openai_api_version=\"2023-05-15\",\n", - " azure_deployment=model_name,\n", - " temperature = 0\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "51f83b06-e938-459e-8f31-5223326ead34", - "metadata": {}, - "source": [ - "The first step to connecting our model to our database will be to create an engine that will help langchain connect to our SQL database using a package called `sqlalchemy`. The package will take the same info from the connection we name before but the format of driver is a little different where in this package it does not require curly brackets." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f4862c17-e38d-4220-9ccd-c1b295d6e401", - "metadata": {}, - "outputs": [], - "source": [ - "driver= \"ODBC Driver 18 for SQL Server\"" - ] - }, - { - "cell_type": "markdown", - "id": "c59d18f0-2d93-47e0-a743-f48275df47ed", - "metadata": {}, - "source": [ - "The database information will be entered as a connection string and then converted to our database engine using the command `create_engine`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c37e37ca-f6f0-4f5b-a94f-5906a25d6681", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "py_connectionString=f\"mssql+pyodbc://{user}:{password}@{server_name}.database.windows.net/{database}?driver={driver}\"\n", - "db_engine = create_engine(py_connectionString)" - ] - }, - { - "cell_type": "markdown", - "id": "0a696eeb-6a6e-4a32-994d-7460083413c2", - "metadata": {}, - "source": [ - "Now that we have established a connection to the databse we need to use the langchain package `SQLDatabase` to pass that connection to langchain. Notice that we leave the schema as **\"dbo\"** which stands for database owner and will be the default schema for all users, unless some other schema is specified. The dbo schema cannot be dropped." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91adaf0e-1b38-4dee-988d-ceb2f3992b21", - "metadata": {}, - "outputs": [], - "source": [ - "db = SQLDatabase(db_engine, view_support=True, schema=\"dbo\")" - ] - }, - { - "cell_type": "markdown", - "id": "f3dce9b8-b054-4dad-a1c5-c53f6bcc5f04", - "metadata": {}, - "source": [ - "Lets run a test query below to ensure we are connected!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4263a3d5-488e-44ee-8616-79e63758a141", - "metadata": {}, - "outputs": [], - "source": [ - "print(db.dialect)\n", - "db.run(\"SELECT COUNT(*) FROM ds_salaries WHERE work_year = 2023 AND experience_level = 'SE' \")" - ] - }, - { - "cell_type": "markdown", - "id": "46ad4ab1-84ac-43e2-b152-038abadb7184", - "metadata": {}, - "source": [ - "The last step will be to create a SQL agent. The SQL agent will provide our bot with the following instructions:\n", - "1. Taken in the users ask or question and survey the SQL table mentioned in the ask/question\n", - "2. Create a SQL query based on the columns that have relevant information to the ask/question\n", - "3. Submit the query to our database and present the results to the user\n", - "\n", - "There is no need for a prompt because the agent already supplies that.\n", - "\n", - "**Tip**: If you do not want to see the reasoning of the agent and only want to answer set `verbose` to `false` (e.g., `verbose=False`)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10b17ab9-b1b2-4315-97be-06cb39572fcd", - "metadata": {}, - "outputs": [], - "source": [ - "toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n", - "\n", - "agent_executor = create_sql_agent(llm=llm,\n", - "toolkit=toolkit,\n", - "verbose=True,\n", - "agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "faa22b65-e518-4e24-9154-e42bae28940e", - "metadata": {}, - "source": [ - "Now we can ask our bot questions about our data! Notice how in the question below we mention that the table we are looking at is **ds_salaries**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8f968c90-4151-4d4f-b5a9-516ca34a7a58", - "metadata": {}, - "outputs": [], - "source": [ - "question = \"count the number of employees that worked in 2023 and have a experience level of SE in table ds_salaries.\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d80a800-ba4f-431d-bab2-1e4b3e50f8da", - "metadata": {}, - "outputs": [], - "source": [ - "agent_executor.invoke(question)" - ] - }, - { - "cell_type": "markdown", - "id": "032bc4e2-9a10-4e20-b775-3e34dc3683ee", - "metadata": {}, - "source": [ - "## Conclusion " - ] - }, - { - "cell_type": "markdown", - "id": "edac27e0-45dd-450b-bb78-fa341a667575", - "metadata": {}, - "source": [ - "In this notebook you learned how to set up a Azure SQL database and connect your model to the database using langchain tools, creating a chatbot that can read and retrieve data from structured data formats." - ] - }, - { - "cell_type": "markdown", - "id": "116c547b-c569-4843-a6a9-e81c6c0f8252", - "metadata": {}, - "source": [ - "## Clean up " - ] - }, - { - "cell_type": "markdown", - "id": "5a66120b-79a4-4a5a-a78b-125cbb1e8aac", - "metadata": {}, - "source": [ - "Dont forget to turn off or delete any notebooks or compute resources! Below you will find instructions to delete the SQL database. With the first step to close the connection to the database." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0dfaedac-271b-4277-b34b-eac1c4c5fc62", - "metadata": {}, - "outputs": [], - "source": [ - "conn.close()" - ] - }, - { - "cell_type": "markdown", - "id": "d21fcfc6-23e0-40ca-bb25-6f000db03aad", - "metadata": {}, - "source": [ - "We will be using Azure CLI commands which first require use to login. Run the command below and follow the steps outputted." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5fd0edc8-af4d-469f-8eb5-81ffec8d3033", - "metadata": {}, - "outputs": [], - "source": [ - "! az login" - ] - }, - { - "cell_type": "markdown", - "id": "0190471e-7238-4a89-a276-e9ab4ff61f62", - "metadata": {}, - "source": [ - " Next we will delete our database, wait for the command to output **'Finished'**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27ff38bb-3a93-4c0e-90ee-dd34b8a37d9c", - "metadata": {}, - "outputs": [], - "source": [ - "resource_group=\"\"\n", - "!az sql db delete --name {database} --resource-group --server {server_name}" - ] - }, - { - "cell_type": "markdown", - "id": "5ecc188e-c4eb-40a2-8854-03027d99e079", - "metadata": {}, - "source": [ - "For this command you will need your subscriptions ID which can be found running the following command:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34b2beb0-6cd0-4a89-ac0b-1cafcc7f762d", - "metadata": {}, - "outputs": [], - "source": [ - "!az sql server list --resource-group {resource_group}" - ] - }, - { - "cell_type": "markdown", - "id": "e70cea5d-ad6e-49f9-bac7-255f3cf3d147", - "metadata": {}, - "source": [ - "Finally delete your SQL server, wait for the command to output **'Finished'**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2ca10666-81a4-47f2-b168-6fd0a590d4a3", - "metadata": {}, - "outputs": [], - "source": [ - "subscription_id=''\n", - "!az sql server delete --name {server_name} --resource-group {resource_group} --subscription {subscription_id} -y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f91700b-bfe3-452c-b5a0-0b8fed115fd8", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernel_info": { - "name": "python310-sdkv2" - }, - "kernelspec": { - "display_name": "Python 3.10 - SDK v2", - "language": "python", - "name": "python310-sdkv2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.11" - }, - "microsoft": { - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb b/tutorials/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb deleted file mode 100644 index cfc93cd..0000000 --- a/tutorials/notebooks/GenAI/notebooks/AzureOpenAI_embeddings.ipynb +++ /dev/null @@ -1,488 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "# Access Azure OpenAI LLMs from a notebook " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Overview\n", - "Models you deploy to Azure OpenAI can be accessed via API calls. This tutorial gives you the basics of creating local embeddings from custom data and querying over those." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Prerequisites\n", - "We assume you have access to Azure AI Studio and have already deployed an LLM." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Learning objectives\n", - "+ Get familiar with Azure OpenAI APIs\n", - "+ Learn how to create embeddings from custom data\n", - "+ Learn how to query over those embedings\n", - "+ Learn how to access deployed LLMs outside of the Azure console" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Install packages" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "gather": { - "logged": 1696341373678 - } - }, - "outputs": [], - "source": [ - "pip install -r ../requirements.txt" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Run a query on a local csv file by creating local embeddings" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Import required libraries" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696365118786 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "import os\n", - "import openai\n", - "import requests\n", - "import numpy as np\n", - "import pandas as pd\n", - "from openai.embeddings_utils import get_embedding, cosine_similarity" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "You also need to [deploy a new model](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal#deploy-a-model). You need to select and deploy `text-embedding-ada-0021`. If you get an error downstream about your model not being ready, give it up to five minutes for everything to sync. " - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "For simplicity, we just use a microsoft example here, but you could theoretically use any csv file as long as you match the expected format of the downstream code. This example is a recent earning report given by the CEO of Microsoft. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696367383849 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# read the data file to be embedded\n", - "df = pd.read_csv('microsoft-earnings.csv')\n", - "print(df)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696367387035 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# set keys and configure Azure OpenAI\n", - "openai.api_type = \"azure\"\n", - "openai.api_base = \"\"\n", - "openai.api_version = \"2023-07-01-preview\"\n", - "# get the key from the instructions in the README of this repo. \n", - "#You can also just click View Code in the chat playground\n", - "openai.api_key = \"\"\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696367395456 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# calculate word embeddings \n", - "df['embedding'] = df['text'].apply(lambda x:get_embedding(x, engine='text-embedding-ada-002'))\n", - "df.to_csv('microsoft-earnings_embeddings.csv')\n", - "print(df)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Query the embeddings. After each query you put into the little box, you need to rerun this cell to reset the query. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696346882392 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "# read in the embeddings .csv \n", - "# convert elements in 'embedding' column back to numpy array\n", - "df = pd.read_csv('microsoft-earnings_embeddings.csv')\n", - "df['embedding'] = df['embedding'].apply(eval).apply(np.array)\n", - "\n", - "# caluculate user query embedding \n", - "search_term = input(\"Enter a search term: \")\n", - "if search_term:\n", - " search_term_vector = get_embedding(search_term, engine='text-embedding-ada-002')\n", - "\n", - " # find similiarity between query and vectors \n", - " df['similarities'] = df['embedding'].apply(lambda x:cosine_similarity(x, search_term_vector))\n", - " df1 = df.sort_values(\"similarities\", ascending=False).head(5)\n", - "\n", - " # output the response \n", - " print('\\n')\n", - " print('Answer: ', df1['text'].loc[df1.index[0]])\n", - " print('\\n')\n", - " print('Similarity Score: ', df1['similarities'].loc[df1.index[0]]) \n", - " print('\\n')" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "### Query your own data" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "In the README, we show how to add your own data. When you have done this, type in a query, and then similar to what we show for above, if you click **View Code** in the Chat Playground, it will show you all the metadata you need to fill in here." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "openai.api_type = \"azure\"\n", - "openai.api_version = \"2023-08-01-preview\"\n", - "# Azure OpenAI setup\n", - "openai.api_base = \"\" # Add your endpoint here\n", - "deployment_id = \"\" # Add your deployment ID here\n", - "# Azure Cognitive Search setup\n", - "search_endpoint = \"\"; # Add your Azure Cognitive Search endpoint here\n", - "# This is different than the key from above, its the key for the Cog search\n", - "search_key = \"\"; # Add your Azure Cognitive Search admin key here\n", - "search_index_name = \"\"; # Add your Azure Cognitive Search index name here\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "Now run the query, note that the query is defined in the block below, and will output in Json format" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": false, - "gather": { - "logged": 1696353881797 - }, - "jupyter": { - "outputs_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "def setup_byod(deployment_id: str) -> None:\n", - " \"\"\"Sets up the OpenAI Python SDK to use your own data for the chat endpoint.\n", - "\n", - " :param deployment_id: The deployment ID for the model to use with your own data.\n", - "\n", - " To remove this configuration, simply set openai.requestssession to None.\n", - " \"\"\"\n", - "\n", - " class BringYourOwnDataAdapter(requests.adapters.HTTPAdapter):\n", - "\n", - " def send(self, request, **kwargs):\n", - " request.url = f\"{openai.api_base}/openai/deployments/{deployment_id}/extensions/chat/completions?api-version={openai.api_version}\"\n", - " return super().send(request, **kwargs)\n", - "\n", - " session = requests.Session()\n", - "\n", - " # Mount a custom adapter which will use the extensions endpoint for any call using the given `deployment_id`\n", - " session.mount(\n", - " prefix=f\"{openai.api_base}/openai/deployments/{deployment_id}\",\n", - " adapter=BringYourOwnDataAdapter()\n", - " )\n", - "\n", - " openai.requestssession = session\n", - "\n", - "setup_byod(deployment_id)\n", - "\n", - "completion = openai.ChatCompletion.create(\n", - " messages=[{\"role\": \"user\", \"content\": \"What were some of the phenotypic presentations of MPOX on patients with HIV?\"}],\n", - " deployment_id=deployment_id,\n", - " dataSources=[ # camelCase is intentional, as this is the format the API expects\n", - " {\n", - " \"type\": \"AzureCognitiveSearch\",\n", - " \"parameters\": {\n", - " \"endpoint\": search_endpoint,\n", - " \"key\": search_key,\n", - " \"indexName\": search_index_name,\n", - " }\n", - " }\n", - " ]\n", - ")\n", - "print(completion)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "nteract": { - "transient": { - "deleting": false - } - } - }, - "source": [ - "## Conclusion\n", - "In this notebook you learned how to feed a PDF document directly to an LLM that you deployed in the Azure console and summarize the document." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Clean up\n", - "Make sure to shut down your Azure ML compute and if desired you can delete your deployed model on Azure OpenAI." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernel_info": { - "name": "python310-sdkv2" - }, - "kernelspec": { - "display_name": "Python 3.10 - SDK v2", - "language": "python", - "name": "python310-sdkv2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.11" - }, - "microsoft": { - "host": { - "AzureML": { - "notebookHasBeenCompleted": true - } - }, - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorials/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot b/tutorials/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot deleted file mode 100644 index 77f4d28..0000000 --- a/tutorials/notebooks/GenAI/notebooks/Pubmed_RAG_chatbot +++ /dev/null @@ -1,1664 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "2edc6187-82ae-44e2-852f-2ad2712c93aa", - "metadata": {}, - "source": [ - "# Creating a PubMed Chatbot using Azure" - ] - }, - { - "cell_type": "markdown", - "id": "8acf2f72", - "metadata": {}, - "source": [ - "## Overview\n", - "[PubMed](https://pubmed.ncbi.nlm.nih.gov/about/) supports the search and retrieval of biomedical and life sciences literature with the aim of improving health both globally and personally. Here we create a chatbot that is grounded on PubMed data. Most Azure command line tools are already installed and it is recommended to use the **AzureML** kernel in your Jupyter notebook." - ] - }, - { - "cell_type": "markdown", - "id": "58cb56d0", - "metadata": {}, - "source": [ - "## Prerequisites\n", - "We assume you have access to both Azure AI Studio and Azure AI Search, and have already deployed an LLM." - ] - }, - { - "cell_type": "markdown", - "id": "3ecea2ad-7c65-4367-87e1-b021167c3a1d", - "metadata": {}, - "source": [ - "## Learning objectives\n", - "\n", - "This tutorial will cover the following topics:\n", - "+ Introduce Langchain\n", - "+ Explain the differences between zero-shot, one-shot, and few-shot prompting\n", - "+ Practice using different document retrievers" - ] - }, - { - "cell_type": "markdown", - "id": "f645b8cf", - "metadata": {}, - "source": [ - "## Get started" - ] - }, - { - "cell_type": "markdown", - "id": "4d01e74b-b5b4-4be9-b16e-ec55419318ef", - "metadata": {}, - "source": [ - "### Optional: Deploy a model" - ] - }, - { - "cell_type": "markdown", - "id": "9dbd13e7-afc9-416b-94dc-418a93e14587", - "metadata": {}, - "source": [ - "In this tutorial we will be using Azure OpenAI which (if you havent already) you can learn how to deploy [here](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=cli). This tutorial utilizes the model **gpt-35-turbo** version 0301 and the embeddings model **text-embedding-ada-002** version 2." - ] - }, - { - "cell_type": "markdown", - "id": "4f3e3ab1-5f7e-4028-a66f-9619926a2afd", - "metadata": {}, - "source": [ - "### PubMed API vs Azure AI Search" - ] - }, - { - "cell_type": "markdown", - "id": "5a820eea-1538-4f40-86c4-eb14fe09e127", - "metadata": {}, - "source": [ - "Our chatbot will rely on documents to answer our questions to do so we are supplying it a **vector index**. A vector index or index is a data structure that enables fast and accurate search and retrieval of vector embeddings from a large dataset of objects. We will be working with two options for our index: PubMed API vs Azure AI Search." - ] - }, - { - "cell_type": "markdown", - "id": "7314b115-9433-460d-b275-78aa50f0a858", - "metadata": {}, - "source": [ - "**What is the difference?**\n", - "\n", - "The **PubMed API** is provided free by LangChain to connect your model to more than **35 million citations** for biomedical literature from MEDLINE, life science journals, and online books. \n", - "\n", - "**Azure AI Search** (formally known as Azure Cognitive Search) is a vector store from Azure that allows the user more **security and control** on which documents you wish to supply to your model. AI Search is a vector store or database that stores the **embeddings** of your documents and the metadata. It can also act as a retriever by using the LangChain tool **AzureCognitiveSearchRetriever** which will be implementing **Retrieval-augmented generation** (RAG). RAG is a method or technique that **indexes documents** by first loading them in, splitting them into chucks (making it easier for our model to search for relevant splits), embedding the splits, then storing them in a vector store. The next steps in RAG are based on the question you ask your chatbot. If we were to ask it \"What is a cell?\" the vector store will be searched by a retriever to find relevant splits that have to do with our question, thus **retrieving relevant documents**. And finally our chatbot will **generate an answer** that makes sense of what a cell is, and point out which source documents it used to create the answer.\n", - "\n", - "We will be exploring both methods!" - ] - }, - { - "cell_type": "markdown", - "id": "bcf1690d-e93d-4cd3-89c6-8d06b5a071a8", - "metadata": {}, - "source": [ - "### Setting up Azure AI Search" - ] - }, - { - "cell_type": "markdown", - "id": "c6330ddf-7972-4451-9fcb-98cf83f5d118", - "metadata": {}, - "source": [ - "If you choose to use Azure AI Search to supply documents to your model follow the instructions below:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "0c1b23ad-8809-4954-a4df-2ff3b8d9ee58", - "metadata": {}, - "outputs": [], - "source": [ - "!pip install 'langchain' 'langchain-openai' 'langchain-community' 'unstructured' 'tiktoken'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "abddde62-f269-454e-bea6-538bd4267277", - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - } - }, - "outputs": [], - "source": [ - "#Authenticate to use azure cli\n", - "! az login" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d8c1803b-829a-4256-a88c-1f4b57372ba2", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "#uncomment if update is needed\n", - "#! pip install -U \"azure-storage-blob\" \"azure-search-documents\"" - ] - }, - { - "cell_type": "markdown", - "id": "9428d5bc-76e3-4ee1-891b-0bc190c0ae2f", - "metadata": {}, - "source": [ - "### Setting up our storage container" - ] - }, - { - "cell_type": "markdown", - "id": "05b93a90-ff0b-430d-a5f4-4640bfb77b38", - "metadata": {}, - "source": [ - "The first step will be to create a container that we will later use as our data source for our index. Set your storage account name, location, and container name variables." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "43cdc419-25e5-4ba8-b836-a13b2ad77a26", - "metadata": { - "collapsed": false, - "gather": { - "logged": 1701806019922 - }, - "jupyter": { - "outputs_hidden": false, - "source_hidden": false - }, - "nteract": { - "transient": { - "deleting": false - } - }, - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "location = 'eastus2'\n", - "container_name = 'pubmed-chatbot-resources'\n", - "\n", - "#this should be the same as the one you used to set up your workspace\n", - "resource_group = ''\n", - "\n", - "# storage_account_name can be found by going to Azure Machine Learning Workspace > Storage \n", - "#or you can uncomment and run the command below to list the storage accounts names within your resource group\n", - "storage_account_name = ''\n", - "\n", - "#! az storage account list --resource-group {resource_group} --query \"[].{name:name}\" --output tsv" - ] - }, - { - "cell_type": "markdown", - "id": "a568fcc3-24a7-4f5d-9798-9016468a30ee", - "metadata": {}, - "source": [ - "Create your container within your storage account running the command below." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cdf6c373-a0ee-40c6-a5c6-6841c58cc3db", - "metadata": {}, - "outputs": [], - "source": [ - "! az storage container create -n {container_name} --account-name {storage_account_name}" - ] - }, - { - "cell_type": "markdown", - "id": "7adafdba-4c4d-4b96-b9bb-33143a72eafc", - "metadata": {}, - "source": [ - "Run the command below to list the key values of your storage account. The key values will be saved to a json file for protection. We will need one of these keys to create a SAS token that gives us temporary access and permissions to add objects to our container." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6414395e-80b1-4736-b116-70d82675b73b", - "metadata": {}, - "outputs": [], - "source": [ - "!az storage account keys list -g {resource_group} -n {storage_account_name} > keys.json" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "eb2a94da-40de-4b69-8de9-e001b4ea98c7", - "metadata": {}, - "outputs": [], - "source": [ - "import json\n", - "with open('keys.json', mode='r') as f:\n", - " data = json.load(f)\n", - "f.close()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "92cebae7-ddbb-4763-8d50-dd2c9f512696", - "metadata": {}, - "outputs": [], - "source": [ - "key=data[0]['value']" - ] - }, - { - "cell_type": "markdown", - "id": "b3ec2e81-f5c1-43f1-8db0-769069acf9f7", - "metadata": {}, - "source": [ - "Now we can create our SAS token that will last for 2 hours. Here we are giving our token the ability to read, write, list, add, and create objects (blobs) within our container." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4b311d9b-1713-4699-ab62-b228d1decc2d", - "metadata": {}, - "outputs": [], - "source": [ - "# create your SAS token\n", - "from datetime import datetime, timedelta\n", - "from azure.storage.blob import BlobServiceClient, generate_account_sas, ResourceTypes, AccountSasPermissions\n", - "start_time = datetime.utcnow()\n", - "expiry_time = start_time + timedelta(hours=2)\n", - "sas_token = generate_account_sas(\n", - " account_name=storage_account_name,\n", - " container_name=container_name,\n", - " account_key=key,\n", - " resource_types=ResourceTypes(object=True),\n", - " permission=AccountSasPermissions(read=True, write=True, delete=True, list=True, add=True, create=True),\n", - " expiry=expiry_time,\n", - " start=start_time\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "900efd36-371b-4400-9a9f-fffd1bc14cce", - "metadata": {}, - "source": [ - "### Gathering documents for the vector store" - ] - }, - { - "cell_type": "markdown", - "id": "1d1c9de7-4a06-4f85-b9ff-c8c9e51f8c70", - "metadata": {}, - "source": [ - "AWS marketplace has PubMed database named **PubMed Central® (PMC)** that contains free full-text archive of biomedical and life sciences journal article at the U.S. National Institutes of Health's National Library of Medicine (NIH/NLM). We will be subsetting this database to add documents to our AI Search Index. Ensure that you have the correct permissions to allow your environment to connect to containers and AI Search." - ] - }, - { - "cell_type": "markdown", - "id": "b6ad30ba-cee8-47f9-bc1e-ece8961ac66a", - "metadata": {}, - "source": [ - "Here we are downloading the metadata file from the PMC index directory, this will list all of the articles within the PMC bucket and their paths. We will use this to subset the database into our own blob storage. Here we are using curl to connect to the public AWS s3 bucket where the metadata and documents are originally stored." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7b395e34-062d-4f77-afee-3601d471954a", - "metadata": { - "gather": { - "logged": 1701794361537 - } - }, - "outputs": [], - "source": [ - "#download the metadata file\n", - "!curl -O http://pmc-oa-opendata.s3.amazonaws.com/oa_comm/txt/metadata/csv/oa_comm.filelist.csv" - ] - }, - { - "cell_type": "markdown", - "id": "93a8595a-767f-4cad-9273-62d8e2cf60d1", - "metadata": {}, - "source": [ - "We only want the metadata of the first 100 files." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c26b0f29-2b07-43a6-800d-4aa5e957fe52", - "metadata": { - "gather": { - "logged": 1701794425470 - }, - "tags": [] - }, - "outputs": [], - "source": [ - "#import the file as a dataframe\n", - "import pandas as pd\n", - "\n", - "df = pd.read_csv('oa_comm.filelist.csv')\n", - "#first 100 files\n", - "first_100=df[0:100]" - ] - }, - { - "cell_type": "markdown", - "id": "abd1ae93-450e-4c79-83cc-ea46a1b507c1", - "metadata": {}, - "source": [ - "Lets look at our metadata! We can see that the s3 bucket path to the files are under the **Key** column this is what we will use to loop through the PMC bucket and copy the first 100 files to our bucket." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ff77b2aa-ed1b-4d27-8163-fdaa7a304582", - "metadata": { - "gather": { - "logged": 1701794430114 - } - }, - "outputs": [], - "source": [ - "first_100" - ] - }, - { - "cell_type": "markdown", - "id": "84e5f36a-239c-4c15-80ab-f896d45849d3", - "metadata": {}, - "source": [ - "The following commands uses `azcopy`, a tool that allows you to copy objects from AWS s3 buckets. The for loop we created will gather the location of each document with in AWS s3 bucket and save the documents to our container in the form of a text file." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7d63a7e2-dbf1-49ec-bc84-b8c2c8bde62d", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from io import BytesIO\n", - "#gather path to files in bucket\n", - "for i in first_100['Key']:\n", - " doc_name=i.split(r'/')[-1]\n", - " os.system(f'azcopy copy \"https://s3.amazonaws.com/pmc-oa-opendata/{i}\" \"https://{storage_account_name}.blob.core.windows.net/{container_name}/{doc_name}?{sas_token}\"')" - ] - }, - { - "cell_type": "markdown", - "id": "928de2ca-010a-4087-82a7-e548f84f3d95", - "metadata": {}, - "source": [ - "If you run into any errors make sure you have the `Storage Blob Data Contributor` role assigned to your storage account." - ] - }, - { - "cell_type": "markdown", - "id": "e5adf90e-e88b-4631-b860-81c2ea347786", - "metadata": {}, - "source": [ - "The command below sees if our files have any metadata already associated with them. If your data does not have metadata you can add it to your blob following the section **Adding Metadata to Our Data**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3d2831bf-babd-45cf-9641-a34e1b9d7c37", - "metadata": {}, - "outputs": [], - "source": [ - "! az storage blob metadata show --container-name {container_name} --account-name {storage_account_name} --account-key {key} --name 'PMC10000000.txt'" - ] - }, - { - "cell_type": "markdown", - "id": "613cef7d-d0aa-42a8-a46e-7fd1f5c48c3b", - "metadata": {}, - "source": [ - "### Optional: Adding metadata to our dataset" - ] - }, - { - "cell_type": "markdown", - "id": "acd6b7cf-decf-4e1d-8a36-86031cc64faf", - "metadata": {}, - "source": [ - "To add metadata, our keys can't have spaces and need to be strings. Here we are making a new dataframe with wanted columns for our metadata, these columns are from the `first_100` variable we created earlier." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "22b9579b-bde9-4e57-bad6-700c7ee73645", - "metadata": {}, - "outputs": [], - "source": [ - "metadata_table = first_100[['Article Citation', 'AccessionID', 'PMID']].copy()\n", - "#make sure that all keys and values are strings the blob metadata with not beable to parse through our metadata if it is a integer\n", - "metadata_table['PMID'] = metadata_table['PMID'].apply(str)\n", - "metadata_table.rename(columns={'Article Citation': 'Article_Citation'}, inplace=True)" - ] - }, - { - "cell_type": "markdown", - "id": "c02c78e0-18d3-4162-9e58-c790ad85f76f", - "metadata": {}, - "source": [ - "Transform our table into a dictionary to add to our blob metadata." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ae31175-f664-413d-8d2f-ecaef67038dd", - "metadata": {}, - "outputs": [], - "source": [ - "metadata_dict = metadata_table.to_dict('records')" - ] - }, - { - "cell_type": "markdown", - "id": "90dd8101-c635-43a0-9645-1115b32eb037", - "metadata": {}, - "source": [ - "Let's look at our metadata!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5a9de234-c83a-4d94-87b8-3bd51fb0c531", - "metadata": {}, - "outputs": [], - "source": [ - "metadata_dict[0]" - ] - }, - { - "cell_type": "markdown", - "id": "fd877ef2-155f-4fe2-b0c1-8e45293196e2", - "metadata": {}, - "source": [ - "Now that we have our metadata variables set we can connect to our container and the blobs within it by using a **BlobServiceClient**. This client service uses our storage account endpoint and our SAS token. Then we will construct a for loop that loops through the 'first_100' dataframe to gather our document name (which is also the blob name).\n", - "\n", - "Next it will do the following:\n", - "- Gather the metadata (if any exists) of the blob\n", - "- Update the metadata as the new metadata record we created 'metadata_dict'\n", - "- Set the metadata on the blob. Although we have updated the metadata it will not save on your blob unless you set it." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "46767760-8794-4860-9468-6b2d6b72022b", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.storage.blob import BlobServiceClient\n", - "blob_service = BlobServiceClient(account_url=f'https://{storage_account_name}.blob.core.windows.net', credential=sas_token)\n", - "\n", - "for i in range(len(first_100['Key'])):\n", - " document_name = first_100['Key'][i].split(\"/\")[-1] \n", - " blob_client = blob_service.get_blob_client(container=container_name, blob=document_name)\n", - " # gather metadata properties for that blob\n", - " blob_metadata = blob_client.get_blob_properties().metadata\n", - " # Update blob metadata\n", - " more_blob_metadata = metadata_dict[i]\n", - " blob_metadata.update(more_blob_metadata)\n", - "\n", - " # Set metadata on the blob\n", - " blob_client.set_blob_metadata(metadata=blob_metadata)" - ] - }, - { - "cell_type": "markdown", - "id": "2eaf1733-a4f6-4d71-80d2-83089d6dd3f6", - "metadata": {}, - "source": [ - "Lets check the metadata of one of our blobs!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2dc7caf8-f021-4406-93bb-e4834a17cc56", - "metadata": {}, - "outputs": [], - "source": [ - "! az storage blob metadata show --container-name {container_name} --account-name {storage_account_name} --account-key {key} --name 'PMC10000000.txt'" - ] - }, - { - "cell_type": "markdown", - "id": "c1b396c8-baa9-44d6-948c-2326dc514839", - "metadata": {}, - "source": [ - "### Creating an Azure AI Search service" - ] - }, - { - "cell_type": "markdown", - "id": "bb6fa941-bf59-4cae-9aa8-2f2741f3a1b1", - "metadata": {}, - "source": [ - "To create our AI Search index, we will first need to create a search service, and request to create the free SKU to hold all our documents in our vector store. The **free** tier allows you to hold 50MB of data and 3 indexes, and indexers." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "63226024-d03e-4fa0-9557-2f18fec07bd5", - "metadata": {}, - "outputs": [], - "source": [ - "service_name = 'pubmed-search'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ea9458fa-3c0c-4249-a8bd-fd86f9bee8c7", - "metadata": {}, - "outputs": [], - "source": [ - "! az search service create --name {service_name} --sku free --location {location} --resource-group {resource_group} --partition-count 1 --replica-count 1" - ] - }, - { - "cell_type": "markdown", - "id": "4eea51b2-6511-4ae4-ba9d-963a861376cd", - "metadata": {}, - "source": [ - "Below will list the admin keys, select one of them to use for adding objects to our index." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "95382baa-abb9-4ad1-b1db-11cb9a606b7c", - "metadata": {}, - "outputs": [], - "source": [ - "! az search admin-key show --resource-group {resource_group} --service-name {service_name} > keys.json" - ] - }, - { - "cell_type": "markdown", - "id": "ee7c2455-9e61-4568-b2f1-03546c1f9878", - "metadata": {}, - "source": [ - "Save one of the keys." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1dde166b-d342-400a-ba1d-23436e1938ce", - "metadata": {}, - "outputs": [], - "source": [ - "with open('keys.json', mode='r') as f:\n", - " data = json.load(f)\n", - "search_key = data[\"primaryKey\"]" - ] - }, - { - "cell_type": "markdown", - "id": "51fbde69-5a23-45a8-a000-9952824d973a", - "metadata": {}, - "source": [ - "Now we can create our index using a SearchClient which will allow us to also define our fields within our index. Depending on the size of your documents you may need to split your document in chucks so that it fits within the token size of our model." - ] - }, - { - "cell_type": "markdown", - "id": "59c5304e-8e14-485c-b452-e5af2da95e01", - "metadata": {}, - "source": [ - "### Creating an index and loading small documents" - ] - }, - { - "cell_type": "markdown", - "id": "c80ae3c4-ddec-473d-98e9-034e58542968", - "metadata": {}, - "source": [ - "Here we can create an index that connects our blobs in our container using an **Indexer** and a **Data Container**.\n", - "\n", - "**Warning:** This dataset contains large documents, while the below steps are only meant to show you how the process would go with smaller documents" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c0540581-7b16-49af-8c67-a3bbd8a247d2", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.search.documents import SearchClient\n", - "from azure.core.credentials import AzureKeyCredential\n", - "from azure.search.documents.indexes import SearchIndexClient, SearchIndexerClient\n", - "from azure.search.documents.indexes.models import (\n", - " SearchIndexerDataContainer,\n", - " SearchIndexerDataSourceConnection,\n", - " SearchIndex,\n", - " SearchIndexer,\n", - " SearchableField,\n", - " SearchFieldDataType,\n", - " SimpleField,\n", - ")\n", - "\n", - "endpoint = \"https://{}.search.windows.net/\".format(service_name)\n", - "index_client = SearchIndexClient(endpoint, AzureKeyCredential(search_key))\n", - "indexers_client = SearchIndexerClient(endpoint, AzureKeyCredential(search_key))\n", - "connection_string = f\"DefaultEndpointsProtocol=https;AccountName={storage_account_name};AccountKey={key}\"" - ] - }, - { - "cell_type": "markdown", - "id": "0584fad3-a07f-4263-97c3-475d774e87a1", - "metadata": {}, - "source": [ - "Here we are stating our schema or fields before we create our index, these fields are from when we ran the `az storage blob metadata show` command after loading our blobs to our container.\n", - "\n", - "- **SimpleField:** A field that you can retrieve values but not search them this is ideal for keys which is a unique ID for each blob. Here we are setting the Md5 value as our key.\n", - "- **SearchableField:** A field that allows you to retrieve and search values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2bddb00f-fa9e-4677-9d02-484b2eb5b02d", - "metadata": {}, - "outputs": [], - "source": [ - "s_index_name = \"pubmed-index-smalldocs\"\n", - "\n", - "fields = [\n", - " SimpleField(\n", - " name=\"Md5\",\n", - " type=SearchFieldDataType.String,\n", - " key=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"content\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"metadata_storage_path\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"metadata_storage_name\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"Citation\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"Accession_id\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " ),\n", - " SearchableField(\n", - " name=\"Pmid\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True,\n", - " )\n", - "]\n", - "#set our index values\n", - "index = SearchIndex(name=s_index_name, fields=fields)\n", - "#create our index\n", - "index_client.create_index(index)" - ] - }, - { - "cell_type": "markdown", - "id": "2db17d58-1cc3-4a9c-8872-aeca6da86638", - "metadata": {}, - "source": [ - "Now that our index is created we can create our **Data Container** which is the storage container that holds our documents. Once this is created we then create a **Indexer** that will link our data container and our index together, it also has the option to update our index if you were to add new blobs to your storage container." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "6ae3eddb-af30-40cc-95b9-bbba29109af2", - "metadata": {}, - "outputs": [], - "source": [ - "# create a datasource\n", - "container = SearchIndexerDataContainer(name=container_name)\n", - "data_source_connection = SearchIndexerDataSourceConnection(\n", - " name=\"pubmed-datasource\", type=\"azureblob\", connection_string=connection_string, container=container\n", - ")\n", - "data_source = indexers_client.create_data_source_connection(data_source_connection)\n", - "\n", - "# create an indexer\n", - "indexer = SearchIndexer(\n", - " name=\"pubmed-indexer\", data_source_name=\"pubmed-datasource\", target_index_name=s_index_name\n", - ")\n", - "result = indexers_client.create_indexer(indexer)" - ] - }, - { - "cell_type": "markdown", - "id": "39913a9f-5026-4b50-91f9-2acd49d2999f", - "metadata": {}, - "source": [ - "Wait about 5 mins for the index and indexer to sync." - ] - }, - { - "cell_type": "markdown", - "id": "ab4cbeb1-5ba2-4f56-bf8e-7b5875c29538", - "metadata": {}, - "source": [ - "### Creating an index and loading large documents" - ] - }, - { - "cell_type": "markdown", - "id": "67ffaf25-4b54-498a-9b60-4fca4607e9e9", - "metadata": {}, - "source": [ - "For our model to retrieve information from larger documents we need to split the text in our documents into smaller chucks. This will make it easier for our model to sift through our docs to retrieve information without going over the model's token limit. " - ] - }, - { - "cell_type": "markdown", - "id": "0e7acee9-fa89-4d45-b577-5f374103792f", - "metadata": {}, - "source": [ - "If you remember before, we mentioned **RAG**, the process below follows this technique using LangChain. First, we will add metadata to our docs, split our docs into chunks, and embed them. Then much like for smaller documents we will create an index, the fields in our index will be different compared to the small document index. " - ] - }, - { - "cell_type": "markdown", - "id": "f1727147-3cf9-4f9f-a21e-6b33a2f5640d", - "metadata": {}, - "source": [ - "#### Adding metadata to loaded documents" - ] - }, - { - "cell_type": "markdown", - "id": "2fa34e7b-99c7-4a2e-b73b-146636a98285", - "metadata": {}, - "source": [ - "After we have our documents stored in our container we can start to load our files back. This step is necessary though redundant because we will need to embed our docs for our vector store and we need to attach metadata for each document. Although our blobs already have metadata attached to them, LangChain document loader tools only retrieves the path of our files so we need to add them back. In this case we will be using **AzureBlobStorageContainerLoader** to load in the container that holds all of our documents.\n", - "\n", - "If your data is in a directory within your container add the `prefix` variable to the loader definition.\n", - "\n", - "When we load in our documents they will be set as a tuple that is named **Documents**. This tuple will contain two items:\n", - "- **page content:** The text or content within our document\n", - "- **metadata:** The associated metadata which for now will only hold the source (path) to our documents" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a11c98f-463b-48fd-84f7-f2b99f87d992", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "from langchain_community.document_loaders import AzureBlobStorageContainerLoader\n", - "connection_string = f\"DefaultEndpointsProtocol=https;AccountName={storage_account_name};AccountKey={key}\"\n", - "print(f\"Processing documents from {container_name}\")\n", - "\n", - "loader = AzureBlobStorageContainerLoader(\n", - " conn_str=connection_string, container=container_name\n", - ")\n", - "\n", - "documents = loader.load()" - ] - }, - { - "cell_type": "markdown", - "id": "8b6ab068-2919-4d93-8711-15dd7eb19ada", - "metadata": {}, - "source": [ - "Next we use our blob service client to retrieve our metadata from our blobs to add our metadata back to our loaded docs via a for loop. The metadata will consist of the source, title, and the original metadata fields from our blob." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d0a805af-98b1-4367-9aa9-de519e38bdea", - "metadata": {}, - "outputs": [], - "source": [ - "from azure.storage.blob import BlobServiceClient\n", - "\n", - "blob_service = BlobServiceClient(account_url=f'https://{storage_account_name}.blob.core.windows.net', credential=sas_token)\n", - "\n", - "for i in range(len(documents)):\n", - " #set metadata to variable\n", - " doc_md = documents[i].metadata\n", - " #gather document name from metadata to correct source formatting\n", - " document_name = doc_md[\"source\"].split(\"/\")[-1]\n", - " source = f'{container_name}/{document_name}'\n", - " #set the first two fields of our metadata\n", - " documents[i].metadata = {\"source\": source, \"title\": document_name}\n", - " #connect to our blob to gather the metadata\n", - " blob_client = blob_service.get_blob_client(container=container_name, blob=document_name)\n", - " other_metadata = blob_client.get_blob_properties().metadata\n", - " #add the blob metadata to our loaded documents\n", - " documents[i].metadata.update(other_metadata)\n", - "print(f\"# of documents loaded (pre-chunking) = {len(documents)}\")" - ] - }, - { - "cell_type": "markdown", - "id": "4abb10cd-4eb9-4678-aa18-b4f168f1d927", - "metadata": {}, - "source": [ - "Lets look at our metadata!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db06d582-b84d-4b9e-9ff1-1695e37bb50e", - "metadata": {}, - "outputs": [], - "source": [ - "print(documents[0].metadata)" - ] - }, - { - "cell_type": "markdown", - "id": "57e21813-35fa-485a-ac2e-41d38676d87e", - "metadata": {}, - "source": [ - "#### Splitting our documents" - ] - }, - { - "cell_type": "markdown", - "id": "9dfb34dc-4b8d-4c92-9e64-f94926bd8793", - "metadata": {}, - "source": [ - "Splitting our data into chucks will help our vector store parse through our data faster and efficiently.\n", - "\n", - "For this step we will be using langchains **RecursiveCharacterTextSplitter**. This text splitter allows us to set the size of each chunk, if the chunks should have any text overlap (this is to help the model bridge some the chunks to make sense of them), and where best to separate texts. Each chunk will have the same metadata as the original document they came from." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3ae5e1eb-b2df-465c-a37d-3ddbad526602", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.text_splitter import RecursiveCharacterTextSplitter\n", - "\n", - "text_splitter = RecursiveCharacterTextSplitter(\n", - " # Set a small chunk size.\n", - " chunk_size = 2000,\n", - " chunk_overlap = 20,\n", - " length_function = len,\n", - " separators=[\"\\n\\n\", \"\\n\", \".\", \"!\", \"?\", \",\", \" \", \"\"]\n", - ")\n", - "chunk = text_splitter.split_documents(documents)\n", - "\n", - "print(f\"# of documents loaded (pre-chunking) = {len(chunk)}\")" - ] - }, - { - "cell_type": "markdown", - "id": "b70848ce-02ee-4c2c-9824-d231a4d9037a", - "metadata": {}, - "source": [ - "lets look at one of our chunks!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a2ee4576-6d4b-4f70-8cf4-1f52abcb8208", - "metadata": {}, - "outputs": [], - "source": [ - "chunk[0]" - ] - }, - { - "cell_type": "markdown", - "id": "0c8ae84a-3e21-41b0-85d0-7093c563bb90", - "metadata": {}, - "source": [ - "#### Create an Index with a Vector Field" - ] - }, - { - "cell_type": "markdown", - "id": "10628e98-5486-4222-ad36-52ae4ad3a5c0", - "metadata": {}, - "source": [ - "For our index we will be adding in a **content_vector** field which represents each chuck embedded. **Embedding** means that we are converting our text into a **numerical vectors** that will help our model find similar objects like documents that hold similar texts or find similar photos based on the numbers assigned to the object, basically capturing texts meaning and relationship through numbers. Depending on the model you choose you have to find an embedder that is compatible to our model. Since we are using a OpenAI model the compatible embedding model will be **text-embedding-ada-002**." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "11fbd018-4197-4641-bbc3-9feff8c4b4e9", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "from langchain_openai import AzureOpenAIEmbeddings\n", - "from azure.search.documents.indexes.models import SearchIndex\n", - "from azure.search.documents.indexes import SearchIndexClient\n", - "from azure.core.credentials import AzureKeyCredential\n", - "from azure.search.documents.indexes.models import (\n", - " SearchableField,\n", - " SearchField,\n", - " SearchFieldDataType,\n", - " SimpleField,\n", - " TextWeights,\n", - " VectorSearch,\n", - " VectorSearchProfile,\n", - " HnswAlgorithmConfiguration,\n", - " ComplexField\n", - ")\n", - "\n", - "endpoint = \"https://{}.search.windows.net/\".format(service_name)\n", - "index_client = SearchIndexClient(endpoint, AzureKeyCredential(search_key))\n", - "\n", - "#Setup embeddings model\n", - "os.environ[\"AZURE_OPENAI_API_KEY\"] = \"\"\n", - "os.environ[\"AZURE_OPENAI_ENDPOINT\"] = \"\"\n", - "\n", - "embeddings = AzureOpenAIEmbeddings(\n", - " azure_deployment=\"text-embedding-ada-002\",\n", - " chunk_size=10, #processing our chunks in batches of 10\n", - ")\n", - "embedding_function = embeddings.embed_query" - ] - }, - { - "cell_type": "markdown", - "id": "f8643cfd-861c-4d6b-92cf-f21f4e15ccfb", - "metadata": {}, - "source": [ - "Now we can create our fields. You will notice that they are different from the small documents fields. Because we are using LangChain to add our chunks to our index all our metadata will be held in a field called metadata, the page_content will be held in content, and langchan will create ids for each chunk.\n", - "\n", - "Another field you might have noticed is the **content_vector** field this field will hold the content that has been embedded. To create this field we have to set a vector profile which dictates what algorithm we will have our vector store use to find text that are similar to each other (find the nearest neighbors) for this profile we will be using the **Hierarchical Navigable Small World (HNSW) algorithm**.\n", - "\n", - "- **SimpleField:** A field that you can retrieve values but not search them this is ideal for keys which is a unique ID for each blob. Here we are setting the id value as our key.\n", - "- **SearchableField:** A field that allows you to retrieve and search values." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8b542ff8-221a-4e7a-8fca-d5ce09e5976d", - "metadata": {}, - "outputs": [], - "source": [ - "fields = [\n", - " SimpleField(\n", - " name=\"id\",\n", - " type=SearchFieldDataType.String,\n", - " key=True\n", - " ),\n", - " SearchableField(\n", - " name=\"content\",\n", - " type=SearchFieldDataType.String,\n", - " searchable=True\n", - " ),\n", - " SearchField(\n", - " name=\"content_vector\",\n", - " type=SearchFieldDataType.Collection(SearchFieldDataType.Single),\n", - " searchable=True,\n", - " vector_search_dimensions=len(embedding_function(\"Text\")),\n", - " vector_search_profile_name=\"my-vector-config\"\n", - " ),\n", - " SearchableField(name=\"metadata\", type=SearchFieldDataType.String, searchable=True),\n", - "]\n", - "\n", - "vector_search = VectorSearch(\n", - " profiles=[VectorSearchProfile(name=\"my-vector-config\", algorithm_configuration_name=\"my-algorithms-config\")],\n", - " algorithms=[HnswAlgorithmConfiguration(name=\"my-algorithms-config\")],\n", - ")\n", - " \n", - "l_index_name = \"pubmed-index-largedocs\"\n", - "index = SearchIndex(name=l_index_name, fields=fields, vector_search=vector_search)\n", - "index_client.create_index(index)" - ] - }, - { - "cell_type": "markdown", - "id": "9e91998d-376f-4050-8080-50ee3c473ea6", - "metadata": {}, - "source": [ - "Define your vector store for langchain." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1547a74-1727-4c14-8856-842b161fe201", - "metadata": {}, - "outputs": [], - "source": [ - "from langchain.retrievers import AzureCognitiveSearchRetriever\n", - "\n", - "vector_store = AzureSearch(\n", - " azure_search_endpoint=endpoint,\n", - " azure_search_key=search_key,\n", - " index_name=l_index_name,\n", - " embedding_function=embedding_function\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "fe658444-b194-4495-a53c-c39f98498178", - "metadata": {}, - "source": [ - "#### Embedding and Adding Data to Vector Store" - ] - }, - { - "cell_type": "markdown", - "id": "4e3bfb5b-a3a6-4156-bca3-394774a94565", - "metadata": {}, - "source": [ - "For our chunks to be read by our embedding model we need split the tuple within each chunk, remember that the chunks consists of tuple called **Document** that contains **page content** and **metadata**. The code below loops through the chunks and splits the page_content and metadata saving them as separate variable lists." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1ba20bef-5d38-4a99-9374-7642563d8716", - "metadata": {}, - "outputs": [], - "source": [ - "texts = [doc.page_content for doc in chunk]\n", - "metadatas = [doc.metadata for doc in chunk]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "78fcd8d9-1e07-4413-bfbf-53347adf2bcc", - "metadata": {}, - "outputs": [], - "source": [ - "chunk[0]" - ] - }, - { - "cell_type": "markdown", - "id": "62095449-f2bd-4038-ac6a-e1569887680e", - "metadata": {}, - "source": [ - "Finally we can upload our split content and metadata to our vector store! This may take 10 to 20 mins depending on how large your dataset is." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "27eff5e6-ff27-4ea8-9e6a-c0c5c05a245a", - "metadata": { - "scrolled": true, - "tags": [] - }, - "outputs": [], - "source": [ - "vector_store.add_texts(texts=texts, metadatas=metadatas)" - ] - }, - { - "cell_type": "markdown", - "id": "07b3bc6b-8c43-476f-a662-abda830dc2da", - "metadata": { - "tags": [] - }, - "source": [ - "### Creating an inference script " - ] - }, - { - "cell_type": "markdown", - "id": "3ba2291e-109e-4120-ad10-5dbfd341a07b", - "metadata": {}, - "source": [ - "In order for us to fluidly send input and receive outputs from our chatbot we need to create an **inference script** that will format inputs in a way that the chatbot can understand and format outputs in a way we can understand. We will also be supplying instructions to the chatbot through the script.\n", - "\n", - "Our script will utilize **LangChain** tools and packages to enable our model to:\n", - "- **Connect to sources of context** (e.g. providing our model with tasks and examples)\n", - "- **Rely on reason** (e.g. instruct our model how to answer based on provided context)\n", - "\n", - "The following tools must be installed via your terminal `pip install \"langchain\" \"langchain-openai\" \"langchain-community\" \"xmltodict\" \"openai\"` and the general inference script must be run on the terminal via the command `python YOUR_SCRIPT.py`." - ] - }, - { - "cell_type": "markdown", - "id": "ad374085-c4b1-4083-85a5-90cba35846d6", - "metadata": {}, - "source": [ - "The first section below will list all the tools that are required. \n", - "- **PubMedRetriever:** Utilizes the langchain retriever tool to specifically retrieve PubMed documents from the PubMed API.\n", - "- **AzureCognitiveSearchRetriever:** Connects to Azure AI Search to be used as a langchain retriever tool by specifically retrieving embedded documents stored in your vector store.\n", - "- **AzureChatOpenAI:** Connects to your deployed OpenAI model. \n", - "- **ConversationalRetrievalChain:** Allows the user to construct a conversation with the model and retrieves the outputs while sending inputs to the model.\n", - "- **PromptTemplate:** Allows the user to prompt the model to provide instructions, best method for zero and few shot prompting" - ] - }, - { - "cell_type": "markdown", - "id": "6f0ad48d-c6c8-421a-a48b-88e979d15b57", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "from langchain_community.retrievers import PubMedRetriever\n", - "from langchain_community.retrievers import AzureCognitiveSearchRetriever\n", - "from langchain_openai import AzureChatOpenAI\n", - "from langchain.chains import ConversationalRetrievalChain\n", - "from langchain.prompts import PromptTemplate\n", - "import sys\n", - "import json\n", - "import os\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "900f4c31-71cd-4f39-8bfc-de098bdbaafc", - "metadata": {}, - "source": [ - "Second will build a class that will hold the functions we need to send inputs and retrieve outputs from our model. For the beginning of our class we will establish some colors to our text conversation with our chatbot which we will utilize later." - ] - }, - { - "cell_type": "markdown", - "id": "decbb901-f811-4b8e-a956-4c8c7f914ae2", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "class bcolors:\n", - " HEADER = '\\033[95m'\n", - " OKBLUE = '\\033[94m'\n", - " OKCYAN = '\\033[96m'\n", - " OKGREEN = '\\033[92m'\n", - " WARNING = '\\033[93m'\n", - " FAIL = '\\033[91m'\n", - " ENDC = '\\033[0m'\n", - " BOLD = '\\033[1m'\n", - " UNDERLINE = '\\033[4m'\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "ba36d057-5189-4075-a243-18996c6fc932", - "metadata": {}, - "source": [ - "We need to extract environmental variables to connect to our Open AI model. They will be :\n", - "- OpenAI Key\n", - "- OpenAI Endpoint (url)\n", - "- Open AI Deployment Name\n", - "\n", - "If you are using Azure AI Search instead of the PubMed API we need to create a function that will gather the necessary information to connect to our vector store, which will be the:\n", - "- Azure AI Search Service Name\n", - "- Azure AI Search Index Name\n", - "- Azure AI Search API Key" - ] - }, - { - "cell_type": "markdown", - "id": "3f7a244a-7e71-40d3-ae78-8e166dd3c7ee", - "metadata": {}, - "source": [ - "```python\n", - "def build_chain():\n", - " os.getenv(\"AZURE_OPENAI_API_KEY\")\n", - " os.getenv(\"AZURE_OPENAI_ENDPOINT\")\n", - " os.getenv(\"AZURE_COGNITIVE_SEARCH_SERVICE_NAME\")\n", - " os.getenv(\"AZURE_COGNITIVE_SEARCH_INDEX_NAME\")\n", - " os.getenv(\"AZURE_COGNITIVE_SEARCH_API_KEY\")\n", - " AZURE_OPENAI_DEPLOYMENT_NAME = os.environ[\"AZURE_OPENAI_DEPLOYMENT_NAME\"]\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "dab1012f-ed20-47b9-9162-924e03e836d5", - "metadata": {}, - "source": [ - "Now we can define our OpenAI model that has been predeployed. If you want to modify parameters, you can control them via:\n", - "- Temperature: Controls randomness, higher values increase diversity meaning a more unique response make the model to think harder. Must be a number from 0 to 1, 0 being less unique.\n", - "- Max Output Tokens: Limit of tokens outputted by the model.(optional: can assign if you like)" - ] - }, - { - "cell_type": "markdown", - "id": "8cadb1af-2c46-4ab1-92f9-6e0861f83324", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "llm = AzureChatOpenAI(\n", - " openai_api_version=\"2023-05-15\",\n", - " azure_deployment=AZURE_OPENAI_DEPLOYMENT_NAME,\n", - " temperature = 0.5\n", - " #max_tokens = 3000\n", - ")\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "c44b4f91-0c64-459b-a6e9-8a955c0797c7", - "metadata": {}, - "source": [ - "Make sure you use either the PubMed retreiver from LangChain or the Azure AI Search Index, but not both.\n", - "\n", - "If using Azure AI Search we need to specify what we are retrieving for our model to review, in this case it is the **content** part of our scheme we set within our index. We also set **'top_k'** to 2 meaning that our retriever will retrieve 2 documents that are the most similar to our query." - ] - }, - { - "cell_type": "markdown", - "id": "21c61724-23d3-4b49-8c72-cbd208bdb5df", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "retriever= PubMedRetriever()\n", - "\n", - "#only if using Azure AI Search as a retriever\n", - "\n", - "retriever = AzureCognitiveSearchRetriever(content_key=\"content\", top_k=2)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "ec8e464a-0931-444a-aa58-09ee0c4c9884", - "metadata": {}, - "source": [ - "Here we are constructing our **prompt_template**, this is where we can try zero-shot or few-shot prompting. Only add one method per script." - ] - }, - { - "cell_type": "markdown", - "id": "4431051e-0e84-408e-9821-f50a9b88c9c1", - "metadata": {}, - "source": [ - "#### Zero-shot prompting\n", - "\n", - "Zero-shot prompting does not require any additional training, but rather it asks a pre-trained language model to respond directly to a prompt, similar to if you were to ask Chat GPT a quick question without context. The model relies on its general language understanding and the patterns it has learned during its training to produce relevant output. In our script we grounded our model via a **retriever** to make sure it gathers information from our input data (PubMed API or Azure AI Search). \n", - "\n", - "See below that the task is more like instructions notifying our model they will be asked questions which it will answer based on the info of the scientific documents provided from the index provided (this can be the PubMed API or Vector Search index). All of this information is established as a **prompt template** for our model to receive." - ] - }, - { - "cell_type": "markdown", - "id": "c0316dc5-6274-4a5e-92e4-3d266ed6a4df", - "metadata": { - "tags": [] - }, - "source": [ - "```python\n", - "prompt_template = \"\"\"\n", - " Ignore everything before.\n", - " \n", - " Instructions:\n", - " I will provide you with research papers on a specific topic in English, and you will create a cumulative summary. \n", - " The summary should be concise and should accurately and objectively communicate the takeaway of the papers related to the topic. \n", - " You should not include any personal opinions or interpretations in your summary, but rather focus on objectively presenting the information from the papers. \n", - " Your summary should be written in your own words and ensure that your summary is clear, concise, and accurately reflects the content of the original papers.\n", - " \n", - " {question} Answer \"don't know\" if not present in the document. \n", - " {context}\n", - " Solution:\"\"\"\n", - " PROMPT = PromptTemplate(\n", - " template=prompt_template, input_variables=[\"context\", \"question\"],\n", - " )\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "edbe7032-8507-4d07-baab-1b3bf0e92074", - "metadata": {}, - "source": [ - "#### One-shot and Few-shot Prompting" - ] - }, - { - "cell_type": "markdown", - "id": "5614ea04-e1f8-4941-ae16-4359f718f98f", - "metadata": {}, - "source": [ - "One and few-shot prompting are similar to one-shot prompting, in addition to giving our model a task just like before we have also supplied an example of how we want the model to respond. See below for an example. " - ] - }, - { - "cell_type": "markdown", - "id": "5ffb9669-5b77-4d9b-9f4e-a0d3a18b0fae", - "metadata": {}, - "source": [ - "```python\n", - "prompt_template = \"\"\"\n", - " Instructions:\n", - " I will provide you with research papers on a specific topic in English, and you will create a cumulative summary. \n", - " The summary should be concise and should accurately and objectively communicate the takeaway of the papers related to the topic. \n", - " You should not include any personal opinions or interpretations in your summary, but rather focus on objectively presenting the information from the papers. \n", - " Your summary should be written in your own words and ensure that your summary is clear, concise, and accurately reflects the content of the original papers.\n", - " Examples:\n", - " Question: What is a cell?\n", - " Answer: '''\n", - " Cell, in biology, the basic membrane-bound unit that contains the fundamental molecules of life and of which all living things are composed. \n", - " Sources: \n", - " Chow, Christopher , Laskey, Ronald A. , Cooper, John A. , Alberts, Bruce M. , Staehelin, L. Andrew , \n", - " Stein, Wilfred D. , Bernfield, Merton R. , Lodish, Harvey F. , Cuffe, Michael and Slack, Jonathan M.W.. \n", - " \"cell\". Encyclopedia Britannica, 26 Sep. 2023, https://www.britannica.com/science/cell-biology. Accessed 9 November 2023.\n", - " '''\n", - " \n", - " {question} Answer \"don't know\" if not present in the document. \n", - " {context}\n", - " \n", - "\n", - " \n", - " Solution:\"\"\"\n", - " PROMPT = PromptTemplate(\n", - " template=prompt_template, input_variables=[\"context\", \"question\"],\n", - " )\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "82c66d53-97b2-46dc-a466-70a3d3bee4a7", - "metadata": {}, - "source": [ - "The following set of commands control the chat history essentially telling the model to expect another question after it finishes answering the previous one. Follow up questions can contain references to past chat history so the **ConversationalRetrievalChain** combines the chat history and the followup question into a standalone question, then looks up relevant documents from the retriever, and finally passes those documents and the question to a question-answering chain to return a response.\n", - "\n", - "All of these pieces such as our conversational chain, prompt, and chat history are passed through a function called **run_chain** so that our model can return a response. We have also set the length of our chat history to one, meaning that our model can only refer to the pervious conversation as a reference." - ] - }, - { - "cell_type": "markdown", - "id": "fda4d33b-60f2-4462-a8e6-bbce7f8a7b07", - "metadata": {}, - "source": [ - "```python\n", - "condense_qa_template = \"\"\"\n", - " Chat History:\n", - " {chat_history}\n", - " Here is a new question for you: {question}\n", - " Standalone question:\"\"\"\n", - " standalone_question_prompt = PromptTemplate.from_template(condense_qa_template)\n", - " \n", - " qa = ConversationalRetrievalChain.from_llm(\n", - " llm=llm, \n", - " retriever=retriever, \n", - " condense_question_prompt=standalone_question_prompt, \n", - " return_source_documents=True, \n", - " combine_docs_chain_kwargs={\"prompt\":PROMPT},\n", - " )\n", - " return qa\n", - "\n", - "def run_chain(chain, prompt: str, history=[]):\n", - " print(prompt)\n", - " return chain({\"question\": prompt, \"chat_history\": history})\n", - "\n", - "MAX_HISTORY_LENGTH = 1 #increase to refer to more pervious chats\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "b8f1ef8d-66fe-4f84-933b-af2d730bd114", - "metadata": {}, - "source": [ - "The final part of our script utilizes our class and incorporates colors to add a bit of flare to our conversation with our model. The model when first initialized should greet the user asking **\"Hello! How can I help you?\"** then instructs the user to ask a question or exit the session **\"Ask a question, start a New search: or CTRL-D to exit.\"**. With every question submitted to the model it is labeled as a **new search** we then run the run_chain function to get the models response or answer and add the response to the **chat history**. " - ] - }, - { - "cell_type": "markdown", - "id": "1aa6ef65-ced4-445e-875c-7fee3483b81d", - "metadata": {}, - "source": [ - "```python\n", - "if __name__ == \"__main__\":\n", - " chat_history = []\n", - " qa = build_chain()\n", - " print(bcolors.OKBLUE + \"Hello! How can I help you?\" + bcolors.ENDC)\n", - " print(bcolors.OKCYAN + \"Ask a question, start a New search: or CTRL-D to exit.\" + bcolors.ENDC)\n", - " print(\">\", end=\" \", flush=True)\n", - " for query in sys.stdin:\n", - " if (query.strip().lower().startswith(\"new search:\")):\n", - " query = query.strip().lower().replace(\"new search:\",\"\")\n", - " chat_history = []\n", - " elif (len(chat_history) == MAX_HISTORY_LENGTH):\n", - " chat_history.pop(0)\n", - " result = run_chain(qa, query, chat_history)\n", - " chat_history.append((query, result[\"answer\"]))\n", - " print(bcolors.OKGREEN + result['answer'] + bcolors.ENDC) \n", - " if 'source_documents' in result:\n", - " print(bcolors.OKGREEN + 'Sources:')\n", - " for d in result['source_documents']:\n", - " ###Use this for Azure Search AI\n", - " dict_meta=json.loads(d.metadata['metadata'])\n", - " print(dict_meta['source'])\n", - " ###\n", - " #Use this for PubMed retriever:\n", - " #print(\"PubMed UID: \"+d.metadata[\"uid\"])\n", - " print(bcolors.ENDC)\n", - " print(bcolors.OKCYAN + \"Ask a question, start a New search: or CTRL-D to exit.\" + bcolors.ENDC)\n", - " print(\">\", end=\" \", flush=True)\n", - " print(bcolors.OKBLUE + \"Bye\" + bcolors.ENDC)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "id": "1abcbd48-bb84-4310-b8eb-ad87850a8649", - "metadata": {}, - "source": [ - "Running our script in the terminal will require us to export the following global variables before using the command `python NAME_OF_SCRIPT.py`. Example scripts are also ready to use within our 'example_scripts' folder." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ba97df23-6893-438d-8a67-cb7dbf83e407", - "metadata": { - "tags": [] - }, - "outputs": [], - "source": [ - "#retreive info to allow langchain to connect to Azure Search AI\n", - "print(service_name)\n", - "print(l_index_name)\n", - "print(s_index_name)\n", - "print(s_index_name)\n", - "print(search_key)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7eab00a3-54ff-4873-8d25-eaf8bd18a2e6", - "metadata": {}, - "outputs": [], - "source": [ - "#enter the global variables in your terminal\n", - "export AZURE_OPENAI_API_KEY='' \\\n", - "export AZURE_OPENAI_ENDPOINT='' \\\n", - "export AZURE_OPENAI_DEPLOYMENT_NAME='' \\\n", - "export AZURE_COGNITIVE_SEARCH_SERVICE_NAME='' \\\n", - "export AZURE_COGNITIVE_SEARCH_INDEX_NAME='' \\\n", - "export AZURE_COGNITIVE_SEARCH_API_KEY='' " - ] - }, - { - "cell_type": "markdown", - "id": "bbe127e6-c0b1-4e07-ad56-38c30a9bf858", - "metadata": { - "tags": [] - }, - "source": [ - "You should see similar results on the terminal. In this example we ask the chatbot to summarize one of our documents!" - ] - }, - { - "cell_type": "markdown", - "id": "80c8fb4b-e74f-4e8d-892b-0f913eff747d", - "metadata": {}, - "source": [ - "![PubMed Chatbot Results](../../../docs/images/azure_chatbot.png)" - ] - }, - { - "cell_type": "markdown", - "id": "67776cc7", - "metadata": {}, - "source": [ - "## Conclusion\n", - "Here we built a chat bot using LangChain and Azure Open AI. Key skills you learned were to : \n", - "+ Create embeddings and a vector store using Azure AI Search\n", - "+ Use the PubMed API via LangChain\n", - "+ Send prompts to the LLM and capture chat history\n", - "+ Experiment with zero-shot and one/few-shot prompting" - ] - }, - { - "cell_type": "markdown", - "id": "a178c1c6-368a-48c5-8beb-278443b685a2", - "metadata": {}, - "source": [ - "## Clean up" - ] - }, - { - "cell_type": "markdown", - "id": "7ec06a34-dc47-453f-b519-424804fa2748", - "metadata": {}, - "source": [ - "**Warning:** Dont forget to delete the resources we just made to avoid accruing additional costs!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c307bb17-757a-4579-a0d8-698eb1bb3f2e", - "metadata": {}, - "outputs": [], - "source": [ - "#delete search service this will also delete any indexes, datastore, and indexers\n", - "! az search service delete --name {service_name} --resource-group {resource_group} -y" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "280cea0a-a8fc-494e-8ce4-afb65847a222", - "metadata": {}, - "outputs": [], - "source": [ - "#delete container\n", - "! az storage container delete -n {container_name} --account-name {storage_account_name}" - ] - }, - { - "cell_type": "markdown", - "id": "6928d95d-d7ec-43f6-9135-79fcfc9520d9", - "metadata": {}, - "source": [ - "Dont forget to also delete or undeploy your LLM and embeddings model within Azure AI Studio." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7350f02-aaf2-444d-b32a-c414d7d857ee", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "environment": { - "kernel": "python3", - "name": "common-cpu.m113", - "type": "gcloud", - "uri": "gcr.io/deeplearning-platform-release/base-cpu:m113" - }, - "kernel_info": { - "name": "python3" - }, - "kernelspec": { - "display_name": "Python 3.8 - AzureML", - "language": "python", - "name": "python38-azureml" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.5" - }, - "microsoft": { - "ms_spell_check": { - "ms_spell_check_language": "en" - } - }, - "nteract": { - "version": "nteract-front-end@1.0.0" - }, - "toc-autonumbering": false - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/tutorials/notebooks/GenAI/requirements.txt b/tutorials/notebooks/GenAI/requirements.txt deleted file mode 100644 index ebf0d31..0000000 --- a/tutorials/notebooks/GenAI/requirements.txt +++ /dev/null @@ -1,12 +0,0 @@ -python-dotenv -openai -openai[embeddings] -pandas -numpy -streamlit -langchain -langchain-openai -langchain-community -azure-search-documents==11.4.0b6 -tiktoken -faiss-cpu diff --git a/tutorials/notebooks/GenAI/search_documents/Hurricane_Irene_(2005).pdf b/tutorials/notebooks/GenAI/search_documents/Hurricane_Irene_(2005).pdf deleted file mode 100644 index 01e539555e6a1154a6993b1f2778fd7638bedf52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331598 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 diff --git a/tutorials/notebooks/GenAI/search_documents/Koutros_et_al_2023.pdf b/tutorials/notebooks/GenAI/search_documents/Koutros_et_al_2023.pdf deleted file mode 100644 index e15b849fc2a9acb00d9788fcbad6703a35c0850c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154729 zcmeFZWmH^Svo;EZ;O-$LG!DVtA-KCs2n{saxLc6m?(XjH?hxGF9fAdSF4?c_{hsf9 zcb`A^{yL1&gX)^kd{)h;YR%czV~r-07Z#;uq+>xK+uRzPLSO_i04()P5qNm$mF)HG zoUK6g>N3*w%D)X6kR8wfXa}U123Z){83UL(*qQkFZ0&47Kyw5hekUuSz8T04pa(KC zvEU^>ZEhz9m>BR9tFg*3$XE%1j7`K{Y(Ppbvda1{X8N24#Qb~+JWgCr=2qsf#DG66 zJ2PHl0Ru}t5I|i<9w20C0|Ic;G1BTYFfanxIq8^y3@-H4?kgdLriIts+ zr3K(OFHq0Y-j0{}Um+Oi|C`&&-Uj>!vw=Q62n;d@S=iaqGtx2A{|jsNmq09R>HY|v zPT$g;{&nCL$oy~Mt6u+R{STlM(CQV)@K>OW%>O&o-29)a{6jmQS8gt$*L2!}gkN8L zzg4DX;Gkt-S7v1AVq)N8VWMVW z%E!gB)pHUP#~LFrf+7@6qR{u1FoIsOa%zl!;P6y!e({}1e6cwSS(C2wPCV6P9d;rmC~ zN}D)iET8K8{` z(82-)5O)UI{4H7@XlG-hZvy-s{HsQeKpVTioddKm00@KhY=8je*GVQ|hu4Jw|1Ycf z2ibpS=8xR|pK0WI&A6S39T@bVS@|P_0${uU^!}OJ-}@aG7-(U{OYB5z05SyHgYAg< zgiS!UuNsRu83XNY?Oy*|S=!paZo0o?7kYJpXqBu$`mcqn50H7i`+#5*J7<821;EZ2 z1o$s=U%fIWujOw0Dv-T_GeANDKq)LDqx5P}z3$}3uhai~$^PN}&(Qx^`+r^K@9jxO zhD+E|-~RXhDIv^fZ*OA2#jeM~$O&ZAr{w^#>CrM7GBeY%vw%2hIrI$;UXLhN5UU=? zAKSry&i%8d|H&(1VQcq$U-=g=$dLW@tYI~vWoBRn(Xw!`>(O$87#L_dfcor=jD`k= zK#tdv|3^%Jnfp)Pf2`^+2gDzV`G@!Q_<240=>L88@%{S-{r}GRbGiR}jlWaif3^BM zh5j7>U#dFL-B;_M zt@5k&yTyKOS^tk-`*)wsC`2!60=5I$(2Ih9cVZxYO9RlqdTv&B_J6nB;(>Ywxey&>& zJ4A;U8gxBfm_ws=-IT$G78d%ckslr7ob4G^l+3)@!U7~3N}U589rAMn9pmyug^HP^ zBq~H4JxW9wEE1iZ{Ph4vdgfYnF(OX>a*pZ-QfB%uMEuAl1B~pol+2ura-EzcthfUM z3UH%xqtdj6(*m*A!*5Kfsc0qMnjj4n(2Ppci7IU-!)@=9$E`EI%|h2$WX6YY;N8@ zFi;K#rq2O}TvRlV!i}Hn`pF8-{D-0Y@T{g%LFzB=s61Jl7IgA$t{_nTJ#@b=o)k&>Ih_N))I>K=zZR=1-Uu<j|PqyU4 zsT}nlvU2UhYc;D>m^t_JOZVzaOU+IAJ4=WNT!=XyW|gJ4qde}%i^l|J@pOqTvM!w= zvwdM@qhStradD${FojtQu~KoviR}jZo09DV1wlthjS&S&At7tp1a1(JFc5;pSVI3z zO|t%3lmGW3WMX9bOA#u|Gg@>rAT3`Zgi$dKATZ&7Od|I5uM$3?n?lP#>Jtc2c4Ql@eL7h%FpZe}}+Z=Z!wH zE4!TEg9(e-Aqx>62|MP#F3yW#9)u-s8uvhSx2l{vHO&-^j)zyD)S8lem~x2va%*bz zb7Rwz9hZ==mzle{v7Pd}9nL1sVd1 zvcAg(Ut+QwJg_SO)^0A-^8X6#`YM-f${+Hm0TWrs(RDxB;L;j-(B+2M1~cVdXI9U_ zh=9PXYLkbIQC+&!^yOz#&$8N3Q{mMjI*wH}vi0sr--t*19Yu-Od`DL~^*qOym<51G zE%t@8@u9=Q(bZ(EmbJN8ZK@MdciyUAsiyCN)M)-=aR}whCH0ygZkWNpbv&G|$?o zLiMMW5acuQOy+G3Vozy_V<&|=llPN$@h*bE=h{Nu^wT04l<~OU6Y6H41S`YJtGKPNI@Gmb@SKU5d{WAT)pr`OMM=ltakJ@9_e$MqP ztSi-|eEIQ_An}%XZSR5995!i|ddHDfT9)LYGLxdTGE$CHF-L!(M7*V!K#rqGvOWpJ zB&yI{gI{%|^R9M~QW170Obc;b<3VxdxA6`}84yZ7_k54pAX>h8ah)djmrDENTYUFs zi-P{7dUajBhE!@hV%xQeJDwzQ$O3~r>zVb+q<2H7!VAns3Dt++Vj@5x^;YGDGhY0< zCUdezYxr8^jd&LuN}160pA{kL{A-3D9lu>{i9Z97%}c(v>6^t7dJ4QDj?mlF>|7H> z5fSyy8IXI5X;^GQV`uziV*rFEWJE$u`H;RR4%Wki(VBF8>oWq6;#6IBir=RLWr5fy z3Q0X*I`3}y%1f;cHHyABM>}hQE`taz!VawW`=#A@ycuw6v7*)-s+X^WQT&!s z21QrA1HG33v+KQX*3ZO%6xK4wp|Y-as;C%%SlV7RI`N#gvxI1=TFp9%LT-i1w?k{9bBID_kQblc>`UI=addc z1MX0zMD*^6N?I$!nWfP^?;39^;pC(@+ct@nEH>PI!>ElOS z18ir^y))CbXK-`BDtq2;rXeC1z!0z4dMp`J@vC^UALgfQQlUMq0|IZ4u|k48Kr3f| z$zlDJCVutLmG5!ulLM7i){XJDz^h==%LhfD9eG=;)yCo@1NgDP8o{PPCokX{rpmBJ|& zBk{#%g%g!`j@5Grlp7*9Kd;SBf-syuE>W?oSsc_kem*6-R4`T&VMR;uVL5(JcaXd% z6s#vfhc-yI?RPooMU8oFt$gJA&2UA%Fwe@DQ?{O9B zK)~x_#3?o0IO7egn^eU1q0rpf?>9W4-7TIU9`@GP=X!N#Jz z0}S;K2$g+sFpnDv7*b*kQ0Ci@6qO5|oEv~KVVI)2i|aZ+@^i$a>X+``Ni^d~>Wp2V z#!HlTz{_cuw#pkgJLhF3wZ^=6Fqj{wOP!Uu)|3*+CHq2+*o&2?kwR!zXi{aqBN~Zh zPqHI@6$(d^+gMJ-NE}~O7bIedymXQur=V~#rM2EtWxq}{qyD1_LGHBKox3$z`BY0a z%3_*`bXbT?rKa!%-?Y98jn``Ysc7E-=e!YzHb6R`!|lyi){stDacNzc=_w>jWw#nj zqDm*<9;{Vw|9R*@%ON#z!-5kDhHqLNJ=_4Xw4AL7jm<*v(aF8VQQll!OMvjKO1GVH zZFdwbc3Kd7-_eQl`6DT*J$J}e!D-Xev^e-jI?amPh6dVDQghj%+C5e3+0NI5tTN1H z*VQ`v6B5QgpG{|hr;@oy(T53>`A)5hBM}eG4?JBH|bGbr?WkOi(Y-jcdjA6u$_wVi-AD&!V^o9 zXgF4S{wXIWHW^`N!qAcV69N<`J#7aJT22#y_4R6CbgWIb8$l(W4w;*~p85#Mpy?=a zkTCrBq+c^l=L&uKu*exHP#Sa&M+6k`eId2F`JF>MI_=#LGskivW_BlMe66fWtWEv$ z*(ifV549GH1YYlo1>)wjKegJ}9z0Mwqx*)8-KO40CF$VyjZg6~v&qlckaPEU<;}XC zr(iBI3T2Y3x(ub~6`#zAL+KXA&v?HLB=OJqj84DdhZV>W%n z=C7$c82I@fJ=0tsg1mZ#Tz3Bb{7V)?yNfW}Py?yULQk(A-V&!I2lGG~o;m|c$r>~% z9*X-w$UqtmvnKZQlSwh}`CF+Dh;oB3(hQgk(2|9mRFx12>Z32mqz=)PGvnsdn90?F z60*w^9-M3W388blZjCEyd?K|r<-a09$+OtWk_z9|a1pmE8*cBHF4ol~RPX(UeMU6o z^TtBGd!olbY`7^xY%}p$j$e==hz%B@Q#@Z|D)&^97(Kz`NTFmR$&@)0Q3DQ8ZjF5j z`k!q-j?!RpyZg*0*}0nfv5<>HqgLy)9PWn1UMkFYHjY3K&eW_~nqo<92-BqZbXUDm zcs#{b53Ed`AqyU1|KUlG?vD^oA8=z)6l>&*@qV=|)(FQzGJ8r`R)a?(^XROPpEhh` zr7$%WUrg(|U${wPu{6h9cJC@J+P-)$jnqQ<%IJwie&5L>N8dxzc!6a$2`fBN_5PVV zoJF|_%Em5keFGcUNwf{ejI4K2Az0ue?z4;u-PP2Oa|qPoE|1VIwenIZ7f$$N8Y020 z^W4FuQx^7O{oIeNe6naXP@GAUE!U>-Rid-mh>&y!!G?X`7hv~1Lez$Amc%i5z(*dp za3V-l852&Wav#Gfj^N6T9CDKFy*%pz7~!lS<(c-FuPfG?6IGBAuyV(BumIBqCuM_! z!;Ac?zJb`uN6Oo+UF9vM6%6r(yqQ+mFS#g)fd=9C^swZ?^c?ndL)njFiJ!uahC11a zWhxRX1*rPPQrr2-&{Rf9;9AheXn#I5rD**u#7r{uJ&>)M8ZEiWzX8-=$bQeCe~UTF zvOnd#E6wZtV)oU+hm@JO^JH}k%$6(C51s={B~mc`O2T1p zIeD%>7w#(96P5aF6cBi6eM_JAe0!D#$zj3Q(3#rU)0i}~Ze{K!(QS!1tKbJn?)I-) zF3A{wTv!X^H#rg{hjMqf+G(lVy5a2iu>{T3FumD?3hrg9)(v$M;e5`x$l}Irw&_Vg zObONJ522UQ(7j=x+hmXX2B`fZNco+Gt8p719v- zuQu1M-6>B}k-epGenlZ2^ts!MXTVo=E3~HMMEtG8EO)`q0fzqap zcEB^meG*M85e;__YBBul#M`}R`?VR1hN+*ZPiYzKZ_T#eLpORXt0vj9o)CoK3h{P9 zeBBm{q1UQ3U`RbhvU{}@j!R#L4Z#Uj z<~V)_amByJprfJzgxSyQlA_Xj7WQF2q;)-K>s;ayCGp-v51R`PA`-v8uZ$#6bs^Qe z-yqG_yU)Fx$!Ip$;&8PQTig_I7PMPZ4%^`H}jH$VL_n9Yz7gIhbiHb zEczg2LGm^Vr#1zlPr@lu?3*k><_{~!mv}aWFr9hJGZ}(vAmP5p8IlkuW2xLWp5aF9 z69Zac(&x6S?H*>8wDT^)5b7zOZz*!*kyni?$ZN-ye*l3S+LCkvZF$vQ#64oU(^|6=X~*b9Q&XGNbja;GR3AsEN^1cWy(g{j_U9zXNg0 z4ra_S$zh8>!hikzd}Bl40Jt+p6Rf3X)_MC`S4DhyA5{jZ< zy{G&!2X~@$tiWbSG7l(%12kS$++1xt^JL3mF}b9Zi5ZiEc@0I<81y%Hf@ z=y(1JO%y$vs$z`o?0=+lsx3TU$UyCcB(dJ=}2A4sxbuTv$@9Yvd- zDEX!1R5(?&J{MO9T@gKIG4>O&n}^=932OsTMe?(q9#+f^Xo~Kr)rhNmY1N8n;x_XP z+A3H`M~YnOBNT1@+KK%S9;F^8u=wbtJQ5Cuw*eYa6j})-<*lrYU5fgBR%o=P?Z!`| z+XnOsGwVa%gO9d=@+F19iSRk$@80tDfap1T|uPzkb&P*$~ z^p>mUN1*Wlp3$V(i>2O&gXIEDZRLRyFE8D3K8@q%MP$dIgUq#|79dY7M(cgxC{fhM zRJuUw5TW8WGt{w;IYJ#K4ws3MvtPA?gzuGF20kgyVPfCo_l#cD_=~PFe+azwN3e}| zdoNjSg0%K1A^l?QzjfMY>)jIB@@fBco*T?Xlv0qPlxy}YZC`tUSd}S13tPUNh99@8 zCk6i9VLZ0UGr50)kIAF*0M?m8n#7OVbfHL#L9+XmRBx&;{wCFrH5TGEg%Z0-u|=#_2rJ)SE@CEnt;~N)20v&j_ZZYLO0HxT%;X*I4?#JT zsA5mfAE3VJMEXvlmYvOZP4-D5dus*XdPKO|XRBd}WVzmX@c#VQ1tK=fkw2R2S&c2D zY>N1Kji)kB&T@;_2>jFlA1&Yx*jAm6EG=3vmj9W{3!*uL2OO}Ztu~pf`|bKIvg@D= z$rCs)-=T(KmIAOHzjq+fswHA&6$+hS1jrGxFs*e-j5+bvr|O4y2z@jjACHoKZb+W< zMpUSKzT7iJ8LT93*tGUq1`RwQIz(MCYTZe`#05co`}zYd7Q53wl^+s!n(wxb(;_sz z^o5ZSr5xqF+h5&Bg~><~aogpGAmOD=R?~}q%c0AXYS_N3hlmc{XY5Epo4bXFm?nV_ zfX2BBtxF=RAlBMCb*UUlMTZo^$+ab0!?>)rNmq10-oVO2Y9h1IDB5-Xd35P_w@Pjv zi4VtO5;v^!?JebmeEX`BE=hymlNVB|Gs?J{3@I`z-j{7pVSmN70U{^zubRB5Q6NW_ z#JxZIhcvCB};^|GaUye++OI%W1hCYVo`)=Hl_Z--6E?y`W z&h*=#B)dd2@J!>IMk7@on{_%X_bFN_s=P73r&sP|OhVe;y!H7uK%eDgn=|D)$fMR|A|v$6xOUd~ z;$c;kn*8IX5!cB@#esn%^^0q_J!={aV@K|L--iCV!BdWwp5k(@z;FoSFp|u$AKa~b z(I*$DEufRit&cd=-S%W`{3Z=gglqGyfC1V0a}l#rz6^*_3@Y@;;BU=ok*IvMw@LPn z9pA_s<}?YY@A(z8nghMxYxEM4XZlsz$*yVSrq1cV8J55&Ij@`!*~2`dJA1el)c&#i zi04ww)ToWIs$U9RN@1o=5Rpjv8ZT}l=Br0d9RVZ z!`@e)t%=3lhTsiaj*#24Z+Q#DwmRh>+R?%;?aWB&KycMY)>Mru?$a>xrB^L0Z6Dy? zN+W)pQEhQdFhmGLp?D^X_K1}OvRh5#>wbWpS4&U9)yJnNtT`|= zleVvqFvsnSz#TQ{OR2(ZRpurgmH}LKjTTTPCqG~GSKJI2Q{0q)z$?IqdxATD(1ni)!k1}9XmABE5%wcy*{ILA%Vnmh$|P)2gN(&=JOp>9eOf0>pSnm%_Rfmcpm zDZVMgv&7p4T2uNxyAt~mW2OgYHoq%pjo6dI=@z&?{#YSqbt}snHvg88mG>jR&Rhtu zqaur|2zPjuNRYrr1D8eqYI#KhOW5V5f}tDEoaMZElrCNVt>7&se@m*wH>7@tqkDNL z6WTY8jf@T|^(tdUDlsSQDIulUEi!9q2$Ug1vODI2L%g-_TnK3AG?3Zr+olh8U9l*U}mOpIxaXT@{h zWfY8tsXP6$M!oi)e>Deek*c+nIs2}_{9dJXhF-zy)DM^9yIi&^n$R%ZwZgUH^zyfc zsNVhQ?`HS-t9b@59L(M_^m?fD@l<|AD~9=dd7ahLUwVQThcMeUJ~CTjVB^ujxuo1^ z`TKkb*MfMTH?>AUM*ZQ0D#E$b7UNYTow~0?yeCZW1`+C zc;}A(Ji^p*0B+&$YH(~qSDqPg6( znTWVt$CD`2pFv!kEe3^jW^>Ky0`Xic3Lp+dFwTr3<1%? zZ@Y{3;gR!uRzyiYw=fnfP(8LCF0O1H3NB0gKnSVp8e7LMEptywb;a}-$?PK!^}lL!oK~g8G)W`0l?O=p3I!zS~xY$a^C; zh(zP~fhy)b^jikmq%4C$rcZc{N_$is6V%#pDeJ07dFbD17sS!uFe~7D^c^w~GLx~6 zuoocL#Pw|h?4!pbIf@vu9bIb)3$smzD+;q=CnSd=p*C1Pg|_9yRLVZ0WqBbLJD7l9IT2Q<42cWA@mhU@>$`HyXjLhM0_Z+E5v* zKeM)5_opaAu`X(ydKE&aRI9317IYs58uGZAfi`u!6FA{ZS&Tm!>jCSL;LHo?t~DZtSk6<0dUsEFuqXyw$@3 zJL0DVZEN~l^;1ezbqPagh;I`=n+j*SkvkM4yE{y3hTCW#=KLq31`v6+Zwb&{J#pkJHAJZ{JETci{?KKd@6D;Y;{;#6eRtps&h;D$#90x+KxpCg4ZX64o z8PQxwFMSV}CPXELgn8hoQaX{j7|6^<0s}+z%RDM?%!nhz95LExSH?SwHmhR#9ZC`h zshNGa2i#_ev^_^RnQF<8_hMUaR}7QXjeh8?<2NVdqk{9h8xJj$QIFksK0byepuoEdE5jWdqf z2|PJ-J3o&~;EjhS3@U_jePEAWdI6>ZP(m}~B9IDd#SRe7B9#oSl#mvYT}^w}Eb7d< z)|Azqb+$?CA92jWX;-t3)1YCqNDtzM(GmdPRC@)=NeOL)Ij-w3K2`io6Ot5&>M-Hy zM%q=Jnv|s7leyG zO-x$S_l{iOlo3+qet$0Q0}x#ZI6Jo#J`-0qSW-)oA^V(ROYH4F)mk8;ua43!^}Pg% z<_@Yy3(3ekUVl4QhR;X)Z0dV??(rrepf=al;itpT2MlK&mk72R(h%YB`Bi4My_&|P zsL=O{%g+Tm0&T#wY>Nq(P|ot%0)u1enE^@U)*86g!}{-6!5lwqURY7a>ijs)9nD#d z2)tG`@w=0Wp zC&{Fgf&@sY5&(@RUG@V-_Yl3U3L6GUnX+)1G_NsOG4Yx^Ke6623~t^7kJit&?cET; zQX(ZP!-k~1sn{I&nk!Ln6>g_;H;Yy4G7DJ9W7=FAmcS~TExhX>;6O}<^bQnVb*nAc^>nBux z!DEnyqdwoPD>uoEClUVUyWMgUc9!{B z#q|7>(a0Iadkp+G)0P=moa9<`uBg7f)#ZEOb}9_65yjhYrsAo*(teWy<%xb1<8n|9 zGQF}z4d0R_rw;TX9T#dRXY+_@RNo^EtHz-?QBZG>8PRYJ5*k_fV{*66PT|i`!Vw9( zx?5ICmqN2SU+#%@BOF5tw}8$*U~5Ep89H_Q8F?O>A&Y$1dOsi{Q3d7cW|eMX`#xd> zF%t{gJ9x||D$2J-9q|wss`35e4{hyKl!RO^*w`idA825SOWEz}CwxmplSH6PfAB@T zHeY$sekUg3_7vv|t!7K=sMnXp#qy7YxSC)2J}d38#?+lsc&#(nfd6{(>S1cbBUd-I?9F3pLR>SJx{_hy0Sar}CW-2tHr)kM) zuqy|-rEpEaBC+ES$mMC^2;JXOW12@CM> zns_lcB@(g~2;^2M!^HZw-1c!*o85V>(n$_i)6dVt@}Z33EZn8;c-HsCCyun~JRObY zjgCh~jRMZ8+0^n-C!uic_|J8>u}+H;cI@Jj%@j=Oz%K%wSS>FS)!ILcfq7LWf-iiG zLji85FF&X`%58^uB-D@SzkY{TeH(byIqRWTeL~S-@GW*$wwBL8l;*ES<6_lX?&P2 zEs84Z@O%Hn`SF%;41$pQ+eZJ1%F9o;PWGp}a99_{Z4czqvwS{2#+dBh2(!Z3AgFsN z!h8nOF4?!|v4>haAAm)ypLBkP_Y7(#=AhFis(_?NALNc=NyWa#JQGWl?iaUzrAb^P zI1|OPT%9)kd^{#-=b}m8D}z>NcF5C_RmR7$Ac!QOG(Cc>Y>O`6^j#T@ET;mQu&Qa3 zkFDv#Q6A;OsdS7nGMAVjAIT!dMxfID%}}}RqZ`YSV==SdJ$&f0t>k)XRG&B%{wk>( zU2ME9S#IIa7yS||7t&RdzByYm;8eXIUL<)SWfUSsZq?S*lpD}D@Qqy3f!7-{$=Y)- zCV^iL&=7+Sj|`6-t{p!kl*#SEvWYa#C=}J{`dt)e;-{11tJ_jlTzEY4(>ZzcM*+S| z@`>b<6Lj0Yhq^-1M^&E&b~&U1OzxBn+$M!>;Q?t(uxZj(*!fWB9nw(Ry>*OlB~hBa z@7s|?qotaO)FYcMo~JDyVcE5=E%Fc0KuSZQC1I}k-IB61u?amih&wW>I5!eHG3)}j zoK#ZM>NX^z6arX#d+jBYsQU07l7i$@)LmK9MM=SD^sRS9L{GCK)5n6MHu7H!ta`Lc zuFLqP1(Oq$Yxlr z{1d~Mbjsd*a{MgPq5OrMJT@)AUsPN_wD#{Mv{#ZYgvRnyI+)X2UGdC4N{iX;NZ)+F z_!;Jql`jy`O7pq3-6mkD(dY~2lC_>NVj7U?t>Z<2mns-NfB2N+~za&)Y=}OnqM6K&F#cX1j&_ z#Jt}{Vph~cv|rpcj_aPi_l)eBOvCG2iH+aEOU2c}X~#uS}eqBr*#tWv4t0;R;~yC7>1 z@uXpCM^bjZD5DafYO+#QDhC8f4?<%v%YAS}cCNpJR%KIlzr5zo6664XuU=r7W*7y-|a2A}^S&`J8vOmcpkzNoKkD_;QeS zmt2+h_|wnSq=OHSftufhsOi$rBWps(*t(iDLFB$lh-SzJT3$9L1jopd<+D!SS{AFD zS+SY`Kj~7S#s{D7CkoR_y`MvC0>Nyg%;OXFZ@tKll97}5nPqb5Mv*N$# z@e51?NL|ET8_kIa0{pOYcVRsAbTq|I-#xEw?$43Jq9TjZB9b}I}ohopJ^JARp z{JKKc4_!hzR8hR_=*z<~-#=BF@{ zXa2h4w0a;K!pR+Whz+zr z>uV>z#H+P~U#7HC`~nISIzrM5K}0Tk*?|uBkf}&pN&JZJyf5iPWN%S*6uC1Oa5ZAH zb+5^|QP-s)`4k?U7Fa%bHLt~(IMGk;g2R`c5)XUW_s6ge`1Dz z(INEZP-os+|NcSV*1$mRA#Qnar{tL0>`X6x#i2-25~Vd}x@a=j{{3)O*SU)J2m3uk zPh0E)xtpPtoJ@b#=bJ(`c8NPq{|?U?(g%g7 z8MUt}?zelmyc!?Mo*CQk&x%v`e>|QP4L%8X53l9bWmotERR`hJ$Va%ZNJ0|H`gEcM(HhT)8I8j#K8xoc#t69HQRGc%+uyM~mUI+MN5iQLrZ2_@)rXJpmsxoj~ zEYQ{4amk{RwUlpcK$;i*AlIz%B|6dvIw5wOxA+Z~{lbFvH*+e;Tl}62>1TSsc6X}A z%&<(!?e(>E+29#|JrHoTqmz&Qtl8psfkNxQ!z({(Mo?os!6YjXa+L)IqN^T)CwM_o{`Aox-BVM%Ly)%4=cZju@8?tLOTW_uRsqgF9(GSgsgpV7IM#gm!PqsMtJRdJ| z)=_`8-GI-FR#n~#K7wZvA)OkooJo5(9@u~S18CRH?NB(X30b^Cggt0H7N>%{q1jon zBf*L+v8BuDUA2E!i5nPdh!b+GQ5#O@cSeidaDnzkIwWpB((~y znZj^p53WP49N!5ZxYdJeR?#ZJ;4-ZFB8rC@>}5pgCDF`eC2`*)hoO)xW-CHkDg6(+ zwkpad8XwIcxKp9(%XBd%n$|dZNRApvR>c&PYZ2%;_4vpsWQ#yLl+3EEK=+Z7a^Xmr zmQc-Q|6SdS{Q)s;FZxl|F-|KNBN>^lyP)|6Pp&IveWxXMCDt$AMd?tO14|B5S}bRb zbWPDsdd)krD~Tiy4x2YOt$iz=W!?kW1;xzAkzlG^6Nx~ti?k7HGX#l1{&1x%_}p+h zwOtatECy`VG|MZ@7Kj?@Yee;j_w5hw)_~JL2@+zddYy<9JLiLh#U(vZ8@|yGGXIB8VrASVT1D7TIv$WwHAoD z9m0b@EeR8+F{R60%vNTgyUC;xD+$en$hT&ZzwP&Akkl_|)80Ari5Y)S<@oWoh&S0z z1?n*Z0I)-|o9#+?N5YsD*LU*QcNnc{L6}_$NGEBxwf*rRuV9`Endhk(wO1f( z`2q&0Jpazv9IR|^v%0xJph(1Z6*m-e9O4*K5(r<^8F=WAH5{W{O7Ye;DR5N<%KM#F z`iEdKiq484LKK>sm_YGLD&(CRPO#C_2@(~O*yJsx z%CRp2cD=%UIVgQMWcDm^&7WW?t0eo&0+i5egithniJBxPeMAR{5FbZ(Q+Vd41g3(Y zYb$AvqrvwZDdPxWs>22 zr_e{{z8_b#Fxi(BiCqs9IECP zd2Sou|KjcafQo%T%2~Dz@Eex^=C^QOz5h@FO`*N&Z$0na~Ue^=m_y$wecT!GKdegEtRz3!{8cC92-G@i1<;Hpj$iMzB z1%Hh=X&^UP=crmRC)N7Y4lZg=0a;3v=*tDjKOYF z{71~I$ntj&;rh$kc09&d$!qHyxU0vQE6Zrl$|jq>x?$D{*3+chvx3Lo&b1X8+FYMa zAS5{wPd~5On(9Y(C4b%^p5r{c-Nd zAeztmsdR%j>&mJjuF|4P*4*M3gwO~M@~$BdC^dMCHS^{o{-tFPSq}~2w4}Jf(mG{2 z_fZP|-d!q-XgRbMP2zW)Dx5anpKD~_qWCRvyEFu+z-G8+>qxqEN6|(26vPW9A2q<4 zm)_Yo=}NlbZ5e8Zb=arJ*-4w6%s<+aeQ;`_2}T#P#DKP3B`iW2*tYz-1{4WaPzfnw zRP_FJ)u;rk~|~ zFO&H^=aLgjEe<5=hZg=@8wl3@M;CsZR{0_itTFE78y7$% zzV~cg(xvE9+>fYS3lB0He8f*$E_{8o`M%#&%@aEUR8X*GlS$`kF#$zAJpTKl2?(mE z@VjC--{Z1j(?0JfG(8axk?kf*dbxy%^zn<*J~lM^CeSJR?qZK+I7>Y2#s-^Jjip&N zs598es9|B%>2v|0Fh%kBP?GKdvz2<*n4FVTT-q(bJ<wC;KwY#DB}2;&qvo>0L z+HW7v?Zw0d&ZI*5YPi-Ph39k_F^Ipe_va(i3TPraeA>L~oOx1t!OxYo5m*+L9WCnV z>oO|;VMBkGyg7p`9!4IR9QwP5!A<3y_UF+@nsA0&%RYpVSN4}0iF}a~hpq=E$u8`Y z@nGrAUJDeFvNNeKk0O_g0q0A7R!g&6*DY%MD&-0}^HX(w9!atMtA@vfuR)Kk{Ge}G zO&#Q&);Ko~AV#%kVnamt6YnZWI$xns1U*8vp-qKijRj1J&{wMth#JM3nB6sN%ZGKn zlxoB zxPnJ0+i17Wiowswr%xZmn_g}(BJG4+9ySJQ7)gY*H2^T{dVDQ+_=mF!8K!)^x6yU zH8e9Rj;xZ(Kkel{le|TOkDcyvtPMOUl?epT=FOT3P;|Oqz7TC~KlgVnsZ0r zeSJ?($b(lBopwVuyVKWBw55%{`XkYdW-KucjNXxlBB@&LcDt_IwtdJU4fy8yzHhL! zSWpk&jR8zTvk>KucD3Q>wNIFRNk((dXRlK-WDt4;<@O-A>+ACeY;qs|00bF|sgGIt z>vM0Ku{Ei@GLHZq=V&hBIfuw~Pyj%&)2F5R@tBm~5I;JqpOvXb4=(Pc$@X zib9VCVK$vX0tr+B&tL)kY_cz2klm8IOZ_SCRLGYOogX(L1$GD{&kliqIEy_vE3N(3 zt-7@RnOPLrMt+uSfCW3euS=DO48Y#zK7g8Mw*_nQXgwKrDJTvb?JyRE$h_%D9Q?bX zD-XR{-5sa-A>145;GX^51Ejp;fKL#|g)X5HcCLHAi~a%e?h!=3AJb3Kha&c*N~+is zJua3E$S;)}ZADYZP*Qfbe~H5&(BGnE`Y#okQFDk=TmMXA9QpZUdhg z8R|e@pw7Q3BUHvvYnJqF?oY-pt080z43~f5kouc8C&rSdMqRU@4r&*-|ld zxa;|BpsW{8HxTwCHKSAwM&?bAF#??PT{`lK4&bFx>HUT{yjq%rIO)fj3THMG3K`-a z1^dlcL*ApAEGM~CXg65?$~ojnN5)pHq$mHT;r&!m5;$9=g>S*}PkkoA%fwa9uE@(Z z3AZwjQQ=H4M}4v8+YTdcPjmu~CF06_E}j%L7zjt2bFmZP*fL45{>OE9kAF1~T%M3w zO_M2Y=jo&E*c1f~m!nbBD~P^QLSshW1B+X4QAkcpX;9dqBA7aoxlg^cR{or02fW*( za}2T1MgG(sEzkh71Gm%Mz#~3nK!f2**nh5uLD@BPQJZP!yl@?A*cf-YXv{6wSEiEc z0%Q{vZ?J<28daO0Fx3-7D$Qv(Aw8)uKFgZ}bIo%1)-C{J_%c#LI&C=ZH>tKj5N5dq zhVUYE6xNmJGzmKAP>JIZW>{)jWng0DsMNxuiVRkkWwxr&fkBa#1s*e8PK8DA6mL#Y zMsR|N>ZW6po<5eR^AJ-+2d(HbaJ`6UX65%MH4}-Rpb8T@lH};?ApSyH@80hqkr6&Q{VUJ zoSZ**1WH0X7IL(h6gPlbTsto;+y2ZUy*N|LXNO2lA#5pEg!!Q)6~)cFM-#Mo@Z>&N zBd!M?LVSh@E;@Il2q;y##^-rZ1LIGv(y3p%hSC__$dDjP6|Qt0KL%vKk*c>hfmUTh zrB!Td9e)m0qf_Qmh@`=ovy@lgp99HaaqNTpX41HWu*mN_52#E?qjbNowA1BYG^zoi zby4E;OQ@t?KZq@62}}n0H+lbD+EUtvkW-dWqjd)Q56H@Mb7z5N6D3rPiNDkG2q@=f zM2LS6#`Z7l$&%0#E~&M9Qs%lzUCF7>Hv93lz+JK@`rlAO@O!(gfA?p;h+vv-^Rb75Y8nN>nM4%e}yzZB)vazdC*^IzQWhEBW>7SM}e2)IAg{Y#6j5 z(I2TNKNS{(`Y66L7|_SuK%90cwSb`mpy;=@VnaQnb%T5uz=}D;fKrzqyQ%69VPN=R!ACVD3~FAPO-+dRB&`Ig|Td*DdI_R>pzB(Ql$lHPA;Ci7R|3gJlk zYjEP|+$vB(2|>=R=GYzvP1wi+vmgu0U5;V~bVe=%`{IF@OVLFu8Y3+CqA)ZJys~g3 ztKVDDv1e&|J9q5WZjTym;v1e9xkixKjER)Zaw1;zU)2#g77_5_HV6X;GbzB_Dr0st z0+HE0$Gq;sU{XUDKVJK{Z$Dkd2b0#_WY%cmN<a8jr(u5Z>Jx+Ez@{==0tgUv}`vfSA6WCf55`s_h`4jy_;egDNXh{rh{fR z2U7HHcds3Y%nrkW%z?{2HF?65Q5~el2XYTwGD6~Sy&7+~bTL8C7jOY#PR$lgJl%23 znJ~ppD%w6>S#Xi94;sJ!eNpW2)bpp0SDbv)f^}J6GGh$G=N66DcW&FQMT-;Zxs;1k zGbv*ef5XM`YV)Aa~efrNu5g_GGtpPjm&LmqM#$_h~kEw7veBVbwL z-#kM2QM1I;QAS z(9FYV{dV81R=SlrF3enYL_|=8fpN&W$9F=~y-49lh}?J+LlH*MT2aRnM)wV3NMrrq z->&aUp~$=TH1T?D3M&haIT(VjMPY%~1@httTqu0d)dwK5&=vnUrl2V0&QjVo`Pc3l zWoMr^QfnAG&n9LhhN+}jv(sLHfkG4`nA(lyE_9-7fNmxZ((7GLh1+e`AB<0;g9CM~ zWzHaHdeQJCJ&^hO(B0KtenFm~ou9+IHuw+hG zIf)!np{-ws3%}6xpJi@N5)FQTIIW!2$iP_}vo3eyx7+lWZAfR704;$F{s~=_k+W_x+eIB@*Ul=uPRd1}eBNd> zzmGHzanQz!9X`59TgRNKCW~{CppQ*h_0{C#Z~OES=$JUt4v!kOTfb+Q%kHP{7Y8>r zb!svblkeCdYfq`rZ*Qp3M+xU&Q>2UMn%O^D=wtb9*V6yCcKm;Ph4=>)=_${Lrd=mL z?fd;}l9IEpv$G51n{7idfe}d-Lhy3vS{)s!E-f|Y4|Hyg4tD59`JZ2hp0%_JiL_Ek z8-xWbAjYE~n_(ruMVDE41|^DL4m~^X^V4*9yQ17Fv1rc1#XNLdq9{%WGo9O;tn}P&ci-*XPAzTLbe%Tsr!O*K%6lgO z^d#E=Q@z`;cIUhl_;VM8hSBk-j5B2YCM%r+bQavrj@jNAj!m4o0GXxfN zHNw!RUpt^!{I1Pdj3u+NvmQ0T6K*YV<26(*?R=c56vCqj*U8T-;RbzZH!&uX5WTiv%pEaNLM)3w^UHVI$F%d6rG#=p)SI+sk$=>J% zzJ*jnfP4?(V@+5Ns%DoG*I|7z?9wOJ1`e`a_pWlkFX{qg3RE`*+5Vi6GD9|NUhb0G ziv<4l=Ou5^sSS&E`Ew{msGE^h3FJ{o;Y%PxLfE|C)7|T_TQgk?v`ulDd-ue--8`zR8Ys7?SGQH3}*;}%B-0S@8-`tt4{)faLXU8)pC?iq|V1?0#}hO#bW zPqLKqjfFUFQM69i(8vx)XyJL{Aueh*bY28YUBw$igA+x)F)TBw<^&GQXz%GYh!CKM z^wnr(6GMpB7FdwnF;nu{zVGr-aR%?w-S<)jv%c>O_20hzn#lPjG5GJd_q$zum4MH- z?Hly^Q_BH+!*0z*e}@Ix+4B55OMh_lw&CnYk$p7CA8hRSb^dEaYH*YZ*?-C>;jjxAU(@~zN-1%BLUHF`Kcc?wb^-h0zkS;DVcD|F_3yiH(%nA7 z`UN?&+wS;wk3Fga%oHu#uG3%2R(n5>8+`W@=B8P7P3mS@kMKWT+jm#KWu3eH`~5KY z&$Hjx?dVR8EdbU_ZZWUCq78PHEw-IgEbG&5?brBUqMvO~h!2Owv!()!_@@+(U7@*4 z$m{FbVOaq6Q{j(A>@N;fy9FS?jf=8>3KfxA50$;zY4Dhae*p%1Za;B+%U$l;C`Yor z^=vmqJ@Eaq)rGJj7uG73-8(!weYaab#~)w&S*vE<_KosAC`=^w3wPW5zmH{mms#8H z|0O)Fyq3X&E_nNcj`1W+?(5upW$9HzQiQ2gCGBrV0l{l9Vj2J+@4wB!kahZeA_H#5 zdp6na_hR(qJL+!pt{t@CbO#EA!z8i;V-+Cw@}CpSb=WHqB8bMAA&jM9gC>91OlB1r zIA7cJY@do~m=}yGI&!gS2h%+jQ&(Na`H>KtMoUKdlH$Se^`EgKD@+rWS?B1kz~VKQ z9V4?&%XINfR1K<65=@HY>N?XH46ra@MsV0>Oe0@83V< zeB(`GlUY6NuDW|DjzIUj%q`B}Z&W>kJ?emyP^eB?6W6~&iK@}w zxna0nuXXkYzaY7>RTX)Y;zPIKTi2J8c&}WPY@#N)sILoWBqF!wq8?-VD~jxDt70NJ z*wmt5|K)1qZ=^|-4s(AVld`6ELbThT!dVAhpt<{(XI1S&O8%G5^K+SD(nm!lCV1VP zd*X$f2Qkt=L;$)Z1D8U|v~4OXvGTp3nr^)r<^&;+J?yoAo219}p|dhwMTxEikXmiC zFazRGm>5KKU?^uCxu7qIIVW&2$w*%W;6t~G0I$Bx9g+!1kRy&Xere{o6G3_m@_2~M z=))r$d-~lBAQ1f)Sov^ci(v)JULaG(e%t)`qjPLa(_Op z$uc+MMPk)ey)H#a>pFCV8wa<~RJcyfJ=R^`k}aO{`GKT88fJNUxjYSBRVEi1gcBy< z;%RA9=WMMzz0IimNl7!=W`vJha#gnEr5e-TpG1eYwJ!w-qJSzwN$%4Dtz#J>N)Zt^ zTe&2?@L~&{AF;mRcr>rDm{(3@(Je1?USvcaUnN0jvRdi#<)MpxQ8KmQ5j(h`4@=gm zfPv*~wXj$}suaaQlv@`+HEAA0cmB`a z|FN*+&i!J5KiTx%#i?d_t|zL;3gp zX&+tIRQKW}r0Z#K6FGUj7fss>{cq+0e$=M> zV6d<%JdND@O2T{Z!8VqA#!Z?LeRx~fzg;hd&FD$V?IELUFX~qLx~lH-YH~$wZ7q2^ z-*Mse#!C4~cu@90UcHB2_V59rvp5eA2Z!a}-p-uc?k@VZZ(ps6+UGbXo!8ND^Le*= zX{nRGvFW-BO*{KY+R_jo%okGp(}^VZ#bdc9j$!+q2W{~<6brd*zI}=(`Pe% z4L$#P`!|akDDLx?wcRqh{oe_d_KtCMYo61<12XyA#sMkbUK-s=r|n~70{6cU>6M)! zzQ$VY5J2=mOo(mD`>HOxV82g=9*Xidw+Gt_{D1OMK7g*uH{4H6A}w&Em)*U2}II4YGZ?)pprc z(Us~Bv{N#5Y4aPiP zf+?+xDE0f7pWd?-){tpB9_4CC{GATo3i+n{xXLo|I+&5Q`?C2d+iNOikA@)U4ynXs zdxQslW%}Tdr=b%{0DU`GoxW4o#$h;f$G(BFK*cj*IZa zkWmh^QwBXa^U|cFeCf4ucyfuJ6|C4JX0Ag`+%swPPAnKJDiWnHk=MH^+W!K}1LHzj_bs~fM`BRfgdRg1znn75-8eW#M?R4nA-oX#*qDfwxat#{ zjgUZGt(z?P)*aQSGvpu(J^T7h2{fXnV?OFuiNfN?Z9$O?0%ZA-Em6+7B6{*fObG)X zSq0G+0~lk1()r}%*8niI=177BO+L3 zzg-)`@U@WFq1Qp_@9Hoct6&_wTi9|FF0SuM{ivi-fp>L!9Ez7lIgH4_64msl%CGTq z=93i5W0ER*mC?D0rZZO!7A&*Qk4M>tT(uKN9BbV<*;5pqPIt=rgF{(k1YesH_bk0r_Y%y6eo? zu8KT^2+0AlA)lYYuSO)s)ZpY`YJPeq+PhqND;(*vBWx(U#NrY^2euc`bO~QZdYsI+ zlss@vWz2-vq7C17C?CDXMZp~Nq~9GprinP@lgZ3C^H1Nnl=T%&%OIHX^FBFsVKEwv zQyG8mC!~MAXuXqyw#XI*tnrlr2&o)jlb034W8Iwd1S*wFNeK#GV`*`xok>F1seUnduM_!_s3zN``=yxeR2ivUW}sM3ZR%Df zDf8_?KTuDW+aXgTl^WE|6?u79fP$sednwUH&t<^seT8*6?*l!%a;s; z^@cv8L3LL5++LM08HQ^Q+D23lI?n2gh5@Uv0XgbDtPq}Ry9q)iXsa0mKM2g`0D6?u zYolcK>`cKo<>smZna9PKv+~8hQ|W7`q2Ud>onv}qI_Dk5p%vIhDAJ>N;2+aQQGAt` zMP5^+2!Z>@ha~w@q%^U?^2N1OBD&mmHKTRS3?mKM;sUi1u1Kn3{cps>%exZ{Cm@4e4y1&IKZp)&)m;ngEF5W~?@hv0UU=&#nPWKO=MvA97A#-}rf)E*5(F)XHjsB>n z{IbqlL2-5!TO#bF?vM(irmnh`GBXwf`pMjDkcJ_4kj8f(0$JZurcD!ueZI^*bDp?& zEg$ri6P!}u-@jNoCTf)%_IN;h_hOd9e%dzg^&*@3Nf2Se-9L9IR0dW*Zu%>z8Mn_7 z3Ju+OFh0vb8O6=3ymSmDklmG0wHC)a&1Ta-*V>gMx1uu~XXCUP1nsZRS^XwbhnGa5 zX_xxmxFd9Z0+6WAJUcB~hqig1jCU1?piA_>;4AU!svn#ERKJ_0+fX<`sUeHrzQGW`TdB^0oiA#iI4>2@NijDe`ON zx#eNe6X{=C|6H2V>u`bavIGE6Thd3;vGZ4{^-kC_Aa|m5_VVmq4q6;BpCr1~s8?QH z>KeAq#4#-WDvSCpt}8B;HH?^p=Z+sMT?1Ylt5{n~rA;>GQ%>a9j}lanm_p%pEPk4` zQD$>$5JLECHodfJ%v+Pf|om|jduasqYYE^xt?x5}%{TtqOt=X>hWR{eK z1VVG)i}%6@mn2;8GHoW5u4S{gYVYGYFX53Ywt#GxsED|@Sq}Hj2O|%^KIY^;Wh@oX z>zNhjvW9rjGEQX-3*4$jsJO7JG7iRANKB*Gm+0K+v~vlt>=> zq^^W1_q0!{%PLZZNmw$DO)m)us8M+S`Qxb1Iva~6*6RFHe~?g(q?!TmOPU%~bt5Wo z;95@a96EusvDim%pNITB2c;9V$Qg%k^<*WcI-6#|f3x zX2p-aaWcV0_~lMBN+jj4gU(5!Wpts@D8d{!4HG$b_z&^@K_R7wF`DR@rlVkjVAcf}i3YMi z(WC5HBnxUfmvg-EY=hQ+9RW+k-4NnZZ>)D({2HV=uQRdQ>lnNfK6u3oWu3e&E+fCi z*D-LuEh*{#9i7OC-JEN8VsYOgoWh;*KiX3$%v0m{j|f9rl%cPHwU{V_Ci7N>B1n?a z9k!fn^5l)zF1VQoJ#fmnJ_;aAV)jeBhH@n2Eh!AOORA0>(v)}7_Dy>$hG+sclc5t< zM+)ka3l|NK5He+436aXDSVs{_P;Ve71`fOt89~!l!YsnXT>E}LaBndJQ3$;iH#0e(WRG8p%Kfi=y7#j z&R1r@Foa7d1tJ{7sh35vs9)u3uJ`x>-oA*T^ia(#rxGm|?|#irbaP-~I9UBrZ%Lb;*}zj66G9~VgVqyi69 zvlPt|?`6#}QuVFuW>j`~$9Os@ymPM$NY)IR+o^zzs94nvsFy*9bJ(1iTR?z?Yf&0J zrGNBa9u^?d3g*a_ln*$UF=E%RGtoB{x}uv;;`q`7bx4YN(p=DLsO;eU{t?im7i`+e zkcN!YWNhi%YI^ixf!Z0$8&{mLH9JB+rOc@HXq$OhG6#EIE45`P4&J2B;mSY19JDvQLc-RIx{lL zefWV!fdA6yeEo0(RseVJ;0G|U7GR`OiDn{t0vV7*m1*HiiXphB&iQ3V z6A$+T3B`j%wn{uCnf+?fg@`t3`gJ@O^<{!mug@M0noz(jlmAHx&kdNZ`>mVBi^WZC zshSXGFZ$|F7M9vu`ov5aCc7llTsdN!6jwgkf@oxdQDi)Mm#iFlZi;ZuOxmmEFG6_Z zahutPdLkG}9GLW7`Ua&$~p9~0J1+=mKF*m+~}aLPdX%$+Qg71CNe z_m&&;%xO-c=DoP220DSrCsBP9$-G*`z-T zkO2Bw=(5W{l>=U<-ZzG1g=z34%e5dKv|A+13sZsFB^Jh9!rX=7u?$GnMV zfK4;8S7Lx?_!p^*1%`#&Fl~OE@r&|z=IWU}?!egQ<0ju7?DtG~0V^sj|L$%SA?@CK z#gG}eiNY2USSc71gvb2E6%&?7Bp7N}f-zhxIx2i|8h3q)Ywm9BEKM}@L>8k+WiIW8 z_RQw2clSmh12g(sGV!`D{PYd8e(6MXdI5|FK>~b7WU=DFT27ru4>Y3m$p}8R#cn0d z7Of*p5{2ZH;+V#?T^XDv7yVcTT(FEtU;CMTiaxt2r_oggT8w)vd_J8dS{sw9a?Vd} zEZXTA|4|W+WM;Dx$b4g|64wSKGG}%EaPV0vUGUCS+C46M zpOU#$4Oudw)<;L_m!%goJuver`p10Y$>Q6#ppxbzAKP&_+`H?UhLmlKMa1|*+@DzjND!rh%Pijy4}>J)FDvcCKibv+XG=n<-yel|9WbzOUhlux5e6kfNPTMl}ov=~gyY060 z?(^BlSG;Hd3-cBf%zUFCu9tGN@ca~^qU&9_6dSu z!q3pBne$EXynMKs#F67}W!{*tV+D2EMkwSGW!T;gKq5Dw_^U~Noy*CQGsC;JZA+A0 zI7_BCZMY%DuXuG5vA1|h)d%{2_j5+ei=z=dWY zngsr;=M`iXSf`HCmwC!`0|9+r9}`bc#f+2pk*RT;I- zU}BegC854q-A*PDhil%fOQWxvSm2H$I2qnRGTG=&jx3jGZR zc6Jkzef`F{;E6e>pL(snuE^MQ)bMAx156xV1DXX1g2FxkSTCWe`n);US&GoOL$|a% zP>#_EUA89kTtW=iu<_9k&LFli@3_Fgo5+2o)`L#v4o%TAWv6>{F$ZWud2Bs!#RcCG3?lOK#z@-vPY8D4Mng~7ed_puJ-M=ab04K(=qy_SNQn-M`*aCptvWN7b;y(LCv6a(uhFZ@vfwq*jHZ~ zR>zT*CzX3WszA@iJ@=6i4u9OFzg}XYw@6~27Ho&--zcUK)~Mt)CM@2k^$k( z8ep^%o;Bem$?&h33@?9zH&i+#$A=&CQkWx*&X13E`vHGDPx-|RYf zmwwHk_!lb8IAZpq!|J{w`Zx;NhHVWbNP{8g1&0d^TpmN|m&h&!7x-ETI=1x41pbld zZa>I^s(`wxJF-$>)!kUBlc%TCY4$%&RM5tvgp=xUvBQS0E?NEkKF0|OlT8l$uyfX5 zB);my%klfYf4xnoCP3g9h=(XR7&W!l&comp=*csw;kedg0a&oL9AXh!TUlbj9H&jK zzr+9eR57Q2?ly=jJ`Z+tXd4rtRBcn?y=`9<<~D#hYhy;$J{#838u`7NjA9(r+M7=p z&UGECdGFdn$kc7jX%M)mu5BuL?^;Y~IWfY@(nN}~6KPY=deUlz3(t#~g4%F&ym#%y zRj^d9WNZ!E2T0m}d;!4?hFQ-NN04?gv^YX32oA{Sqn zzRsurj67b94h6|774iyroI53niM#mE>)++w=i@iCtyKK*x3hbam2Wec=iBGuF)OV*EH$R1 zG(+)u`|BYcb;yfzK{b*Ls;^%BhRHtv+WokCe?I&t03e-~xC>b!XM%z0YXiVgIh}^$ zEXM%=YMDE1d0}Y{LUekYGB^dLwpZN{8In&`p5%#Td$BxT>|h#n&_R({!fTS72r8bn z3Tnhc1zPGM1dlR_5q_0oxG<1s$;1I-gA?yeb;i%b_v`7|uD`n@m{{TuwM4(Q0xF2S zi%-)>1`yfyAcN(^6Ff<(6b?WJB__EGRwW*|urY;7o3!|PeK@6(lv<4BhrLQ*nY14h zSl}8cXx-U$7MG46#8>?0H?I321e0OT_*^jnbT7YitZn3%O#n#FSuS#FFhU)>=fjgs zZcr3!oe}jdW;rKSZD^*&^10pC`rsIaf2}QVET%XTx|G*g3Y8;NE#ykSIbF~!{bVfA zQq}e}+Fq!KKP0w}<}GA5iPQ6V6F9X-V%YEFeJ!fG!>L$L_AK+yonvEZ(Op@7F`d|_SBwhO4qri+)VcaV-(9Hk{Ftf=ylK_}eB?o1yfX1G{XPbQ3vsNsV zsH7?!Ft58d_Cbwy3Y7?O^BD|4pSj3%H5&h6%|LRbF}yc1d6ofAEG4kjvH%|yz^LG6 z;u8-y9fOa^(uLv~*k5uu&=AsnJ#dX^=85O16CVkHs(>B~!;MYlwQcjoG`ooCa?pVn zn|BI0IAj>fK#AWL#Z?OCRwU9U?hT1+KpWtcw-a|+Yu}ZqF5>}brTE<1^k>rG$E(ZhzDancUc7CORWUVe`eh^ z0K^**SiM zzp2?9?eAd9vWhwOU$@Q?GC0B%QBz?p_qnBApHTBVt`!8@@Rz)EQWAK^CI=xFVQ2>d zQDMb&c*Qm3c2G*E6Y4!UXPBqyu^QLJ00%^H^Ex`xcvmn<5?=}o7-!0I*SeNObAHMZ=r^o^vB34Lsn?pt58 znYAMss_f#SqsFP0-cnTihX(mJOufdS;WDhbG~O{zoQu^f zhPDeMB7LOk5NdgVfcA3rdoBO`dJm6X|LTnLNx|uvgr^r7Rxz;_g=6i(m0eM@sg}WQ z-!Y?B%aCToO=+q6s;0QkskHSaP&WR~W>UQ8I2y#vB&Fnk6-uHaahkBgaG& zt#}HgS&9YMw^I!(+lpcb@oEfZ zDz~A(^t0FxB)O{Houa2ujv=yLt>Up7B16bfPtd_e-Kd?jC&W5!K(EDEK74{O5Ry(F zH$34osvkLw{%=+nvLy+}6E}e&5~>*qju!HfPG+$yhU(e2SHc?bG4T=^bkO=#z=lT} z%IIM4))@9T#(|dvHduulA2-~I)(%T=wHrCq4KUFLZWx}Z`CffD&|r5fm{iPv5~-K^ zcqZ2FD=4^~(l}Wi{bCV2!NHj`KG(jx#=<7h3ECFfax^V+x+y{RKTDc5tJLSESlhfxQmKH{$5B+F!}K zfUWJ(<7D7NMCh)!X}SEo!F&yh)F;qa1 znZauvcETR`*gWQ;eXEH_WZJWiVp?(Op5v^a2{fg<+lhfhAjZ|xqKydGDJVJ^XH6(N z4W>S^>ltEj8L71~oyqR$xuuD>4pLic#DvS$3YiFup|cN*J>M{hIUOdGq(TPjs&V$y zP&IC@YO0+`SOPOsf$=acmk7{jvAR^7S3$S5o9|jiY>uCv%0I|niD22oDJi!y`84Tl()FV>;J?F~U5-C~hPDKP22 z*8Lyt?!nBBhYm`P`6Bci<0Slx0Zg=Y`cH9m%fR^;qpdq!=+c_=i0PQP#~~_y0>&~H z1RvVWK@Dc02UW56n3P53AeiHdl;5<(V5}72&SJ<39hW|!Bsto_d8=PQ5>i?=@3LA~ zRGr0*!J717PM}7iC;M7~7G%F1vYnO!4i!EMF3z-$GIfcp!sJ85Akp4(>d~80n1T!@ z)7DpFm~O~+OZ20L*$FCK+&D5k2=yV7XBf;{--4`|`FSlBa!q)6y`m(*yX%6QMp|~` zd2Z1C2FeEwjB_x6;j9u}v=KY|lTJp8m)4oie7FHw;v+?t01zp&M$|IJ6_uDdAx?|_ zlL6EynrS+Tz@T(CAgNhEb4N8L&M&}rN5XM@*0((S%RylmvShx$kS4=54{&Wv)aGOa z?>LGw1GrcyEOddZi>;Zb(00Q@wuL9i2^pku#La&to&rA(%@uE+o@ zSZ>_+<@>$pH7EX^>20Cosp)5#Mucbp)Sx+$hD_7us%B-MQ~fvw6{eyv`SnMOSu@>? zC~-nOpQ1|E)T2?u7AOcQ{NKFZhvmT1T>=2|KL!IXH6Z|*F+T3KoLSFlXsgoz(d%zO z={017;vWbM2F~TpgO;f+WM@nR@c;L26lU2;ZVZTS3s7fB?j-3HhK3Cc`8ym?iewmE zg%m4H%)00>QngG0fQs4HmSMI6C|J8}8Vh8ZA7rs){-LPB2fTRr=!gpJhyv77e8p_R z7P77fAaxg2=LzTpfuGED$y!PgI&H|B*rCcspVR+cf;?_XwE7qbJ`dWQI0;=1`x{xu zd%0D3x32pY>Sx%-mr&L{dx!ba+v3p4sg5#NSt+*b<*lIZyZIkj7OynS@;$Drv#==3G|F_;*Tx;YRUP<6}Lv^vOUWd?NAV^G?6 z)|?xTS((d*{;bYGq>TYDW ziMoA(1i#>glG$!%z@>d`M1$`I*q^u{_6_thmR46FmY`e}ckh(sHtYp_)!x-%VI}&i z>#_c*vh?0RR5~MmO_y8Q-j~~Ur5bk5I*FVhOy z4>mER8I^d|-Izd%95Q_R{gCLm7r$49cMlAE=p$_Z`|U!jvFYfl{>PrHYr^1s z?fYHZwr$(CZQHhO+qP}nw(b1MDyd|V?WvkmQ?r?QtNZEp@HZM0ZFIX45mt_2nKUtE zvsVCqVbcH_Wk7rC5i1E zZ@bzROT|3wqse@!6eS~KiSvTY0F(``BwU+&QRKKs%oM$U^l5vZp+v;g*ZT$Lc%3>= zBx2LSqYwLjTN(Vj4eM&vT^>@B24(Mg+|w0}G%%l-mXT2!63?v64lFJ_)EH7wAKvKmrM#^6u$_m6bJYJ3@hW z5HU4J_lu?v5DJTK`TuYYa{T|e2HBYZk23CRwJpc3aReXn+-DST36ypb!!zC>ZCqCy zvzi)rs)h_Q4?KJ*!UjS>8h%LyUgJKtGB2=h@nmDNhN|I#nl3p#SvSA0AubqJy5xnTjZf)&C63Mk3)V8eH#4*iYYmqb_sU4Z zH;tXRGEK?s&ztwNjW~GQLi?mFK`w7TFR#=eU+yoHIySh<`iBV-*19TFV1hwGahLyc z)@Hn^RdkI}c3%D)!btiM95ZxQRP<`jCy!~XGDUWxOAg#hO5=W8sN0MxntYkmS?St* zM%vZ~E2erDOqo+UkV!EVSe?2J9dlg#O-*ncU8x(bw9(;OvPcA2X|-&!Ky$3YM&4mN zCQ`RtHsWUpuKtkqv|8U*bWj|ekq|2!xx^9V>=Us;(RO!RcS=KR;89-Ox9K)+H`wT% zRoK`N)W&J6W_XS&F*{8jPG`9k+SsRvNhS?+!Q9Is!1BVk*9Y;=PDET~6(9gjdwkvwkaD0w9=@}^ahbh+ z=Q=3;A3ApsT~V+Hv{l@WyBw7sc%c2d|JIkfpyKMZCWH8EGumcKZR3>y5?Zu8N#s>$ z+m_PhINbysI49C&u5K!$FX}7q$eDOXo{qZMoIzkfPFru!UjDxw5H@z3juk0y;55Lo&fx zy{)ZhyP?5hX11Y3K8U=v8gDlZLKznmkCS%QEN16}ERt{NCJ&>=QfsfSLzD5Djv)Zo zAhG=3VPMhhG8;_{S3t=I)d3y2KFRJti-2RIs>kkvBGBTIHvB9aRm(ELVzTd2Z^Wpt z->9Xla&MDT4kvW&WtW8A&%vw-x1^e<9c&VYh$ifKoBkH%;J#Tqu|z46IftHX^?J|J zyGQO(*;~v|@94R%y0yjQDI(AhdQbd8-o`X;^2}c|@m(|_F0CJ-l8xdWViHDl8)0CU zb+jLs=WOLqnxxgDM1y84T5VJA8t!K;nrsOP;lNhXf`3aH|8^XZ1BoAlL1)TJw91Yb zA`m+;5n8MeZ~-U&t?!L_aL|z1r610!&14zQCgFXg;md7pL3IUxcUe zX^3wmYZf~anv@X>_Z&a@BrG^&epli}T9CtS2&jDE#Iu49A!vlFuwW^){oGzbiB}Rv z?z6{BviqOx*oTv0PfXBeIHsn_ZM!fUKodNA4UtIgTp#E4O!hCZb-2bsbr2MmwQJqd z3SLlFSMb9&wKwe6{r!C?1N#TUqi_Gvmw4oS=={(uyUxB3H|K{lQG!5SXWZ~Ofq*vp z)T+0Kw+X`X0C~1*$0M>2Y|YT^^Ea!>4|}{Z+#2B=tpz2rr}?6weFt>ALS37aJFyg5 zQauJ+Qe0?DH(hurIIO7t0O*K)DzYz57=u#DPHqy>+AaPh-LLY%T-5K>}a7)Lufd6rI6(Od@IQC57gx!5{9aq&Y$ z;`}cBi9#Zn{Cc2=bWDGt{`1d2hU1~Q567KKgcesX^{C%(JwkSTpj)$eS^6xk39{Q% z4&%9H-qqqm7}0&W-B^(`FMc?xHrhDU0q5`i%h@=U-^4v;c7NMwG&3cQ`_Ciu!zDMJ zOM&Q`0*dAS>FaUNWXy@#Wj5AS6}KeHz+OK0b#?HUU>CMoUi;}&Z3G8&3vI^H4L!YZ zl38GW3zw!eqt~tum2EruL)Ch6JC>)$z+u142GnV&(JISRHjQ~`MC}X?t9L}Srt(In zrFM$Fyh=z%QX21&QQ5f4v0;B@d}~MDSxuzFB73?_4Lltv1c$Vl3KeY1Z3-^r9+1WyjZ5xgVeO{BF@272|pxF{K zDaH^ghFWQdkSahL_+UOt-TVHL{y&4x>Xd^evZ5N^w7q(b!~Gi1?pEP z*KCkg2N-9i>oVEU+v@MU0xN3Z z%+qb6^RzmCIiDM;0yJr3uH)3#C9?4bVt@Kx`peM|9Q*P_J-BVdL6q6`I*{DYM55l{ z9)!0nq2CZt&W943SNb1(#G`lk{S~5QRg%Cd)Q1Q!L{H=cC*s!9|C;i6$D8rt(j?-FD4oG{v5ig(FgTI4^~4)t z6AMc=>8%Hp7Zj12`Bq_L(KL}K9O%wna?!LPClrP1=$j!LOsfVkGg+9rlQK_;=G8qz zlDJl&!ii$0(G6LorMdsgpOEXr5p`y*jx8b z2eCdn)ivZly(DPwy^94PLP(7UG?Bp$Pb(a_EFsTB7#}+p&q?nCM3r5-&0#b$yS z{c^FJyK=Ex`b`H#3}2zg!f~-P3lSG0a+h!q9??JEneV4?vj>DZNf8|6E-S}}_=#4# znZj3LdlPyXGQx}j0VU4hiHd~;ott+RDQ6@rT%nZ%%?|$2>(Ox8Vrd`;ZG2F9G65L1 zhj{Wajt|oHgB{`{y%{G>2d194j#^fPC2n4Lj~~08ZBr&z7K%qOHm1kOutc@pK5aXl zYj!@&*|Ie;-f+xx zl_TKuQ6h>}YG)n!Iv8(J3VOr3%A--BVG&;xdXIh-P!HRDMqz-N&SpmMqP}h9j8Va! z0Ko^1W=!gt@Ycs^Fn$hIEH7{#xTk@q<`JmWg+91qh6;<=s3>0O=jO32R zZL0^_hpU#j-1YJ`=EI20$AX=TKbGEz>Kx#ArV`7aPAxI@!s9d)j3MdO*8=bvoc$(r zjWDQWPdHNr?J;HT011p^tsP{I;Nmobcto9KYawof;2H=HXCTt(+OBq;c=m1B&8-N} zV7n9~Kv{$~C5Me*9HuUVboFA>m|85@$9TS7D+Qi(IBjuFD-kk4 z@iZ}}!+~`vaK`_y+b9!Jf-~59(V>RG85wSPTB3$fme;TR^08Gx#8ewgpSs4b!LyN7 z9GPDZi@4H28p}W2UUYo?Cz`{$L}?SitauGT=yURloEXz&UtGvUSwE2RJn1Oo3VGi{ z1b)1a33f;t8F14digk1f814E=69UL!2U)=Xq?A}W5n`Ad2?X=TUJyPwYNG*H-*T{L zHq;BSG6c@EAB=JS5|ADtc8DT3a)Fg2NhLM|Ey1qvMP`hR=kNgSerCAZE$2;1r<(>u?=dGb~sp*T$m_^jPn%Hu+&3z+L;i{ z9T`{`%bAC35h(X6f`+~nH1?7(BwHTsf&!6RS>s$8yj>dnT^Jm~uNpXCv}M-QP8-xc zw}qsoFC#x_oM?)sNQ0}|TJYW3WC|piA=P$qHuMR#fM4HVw_ySkpcyKnYw@3azqd9M z*>GH9Pdf{erDl}@23YjL4kKcZ?h_>jHWxk+Kf=Fr*TJc}0GJDK6#xQ>LZE*sfDrY3 zDxl`{`2OV?l|ao#VJ|KTQ1kzqOryJ`L5<&X6aWnyp~k&4s(}>sXq5q{)A=Mo#b@J` z`GqiP)c`Sv3|hih>PjmCGKuhuaTEc0ZM5&c9$z#mtsPT5GhZI*Mc@{%2=%xkbH6eb zp6`zUfLTk<39sd-qoKJ~(kcE~dS;a2c+K+6tT#=v@;E_ahohFw3^ZEM%%OwZ2h11Q z=m>A%v36ZZipn}4PP#P;{*6H@-_9dA&i0=0Q`hyzy>O)2po%P+E0K1x zAEN<5piyU+TW{ak>+_gLg^QcT9iYHY4^>xp>UMDFCdW)3$~OFOqd>UHgke>+1D-P=%xXrFEBp9u_p#B82fg}_1_m#>Y zja5QeqxJAnOakZ|X2PH^VGz_ls`%u+mqtQB z0&Zrh6TaK!So&o*uc+GN^D;RNvOJ8OEj<_rZ4G1>Rl`Rt{I`IUms*@8%)9X&INba? z=-r!>Q+6X+D0SZ&eMsevTmNDN7P8)<7K=d4lP!t%oP1ULJA+lbNrbuvVCB#!2nZ2q zFe){w*J2}w2nv0Dht<|{lrPW$=R6Q;#1<){jp&zm z&s(r^bNO5Icx!JqTk$6HgMjTW+qLH7zgR+LtM{1^CJ8nlsaFsD*8oTU?&{4@aYVO# zoCof7goRo0Olk#m^ROSwwfaP>YsAx#?oP0Nh{87KkEzxOdTCnLg_h8D%SlK;N41;F zd93VHSUl@0o2r{n0w-q%qZtt7tA}LK3(WD4DP|ZU#QiijK9Nl_2LbH3{uABapO-AZ z9HsWe`GF!DV#mq?Dsbc3hh?KhGfhBgVwd=~&XcAW+YL&(HTFe zrq+j#XpKt)6LwXapJA*D@tpz%e1ev6H_bA#5J}m{eEH-+)4+2D26}mr znAO?%JCCTm$)?^fLMJ`4Qw}@_Jc_C8#_F#~cJEW)T-=MqB<<2$FO)0B`7)*X_Wj0MMyNNZN zBAq2c<_r@vd}fy@jwPf6BQ8iJw%v-92uDM)eKKDnxZ3OJAwH7JtKGRNBBaWM$ys?x z=q?k(<69JA*MwqU)8(!XM6V2%&%@KbuU%LJxnK%_Vsh-%>g;uor=SQvzw#``^R6fAJnvmbTa(h3~$ooUdW63;Mb`Hh8Q}VW#oz;j3e` zP3fA48!}2H0+LNfKZu^(o+`7FJ4u#SL9%wT@LgTj#;VlnLT#VqcazKmwwRJYcv{P9 zuxTyg$_-JCX^RZ05aUghVdfgYQX~)37gJTv-oy`k$2Hh&1b%>uuc?c@cMnCU1t*`9 zT|O*iUVrzjyT%+}_=AFnCz?*2R?@?;AcM2^l&6mezvDUJpLO`gX(}@P1y9MLh)1o^g=y%BJgS{ zU<7qOAy);Q;Rub3Z4>gy-22GPwZ9h z$X8dd?bL5XWkJDx9#y<^7?26>yK{9rhpybizsUQgM#{ z97}@$os@ap_(+n~eyARoaB+!pz4Q?g)oHs%#82F>s^gJGax~PwzV60h3t|bX0)yb$ zWP`9TekgLPPKje~=U9oz+iE;Fu4|9Yaka@@VhS$;B1yKj^waQ|L|4(oLP-cQlo>UK zAbSn!rOvBEWyd(c`m0I`E$O=Sk&S6D{1~e?c+duJn^y6k&y;28i~dDLy5KTD!vS7y z=$fI+^r_e(JRn*8)UmI&9ZMBf2VLm@Jm7woecfR7gGJinJ@|=# zuBr5gCaLhIw#B*QuY4gSh=0x52fp-eA42Lt)4a}GVU-nnW^aN5-i{6MlQZzZuXwjb zLDz&`uqE`i--HD3?~MIEhSu#p>lU=2s zSI=u%ZwL8ds@g6$W1c!KRG8wR>TxSKt(SZ$GVHMN4Q*;`Y)2!RJvCJYmWO0>wY}WQ zT?E`BQ02B4Xq5f6SFM*}7d=@wwm-se0#fF$w`o!F^u<2~-*OvuWJS3AmxBz&nLU0_ zuY_bYiW;lPO7(XW3#rzd{jQ)uR+9$he1zJcY@_8GZw{UZHayBF@~|EbAU6&F)xL%H z<9wZ5&WJQGRo8{e>?r*+Dvwo>c~NiC;>KRasI(&%Pue$|k5MjH+1PWrVNAWE7c9ob zQa5^PHarmjMWK{-*BvL!!8iTKgIHEe1r{(`pK{*7j88GRJ^S65KwDzYO0;fDt8nv!I z%14afZRvW|*#lSVf8Y75T<2!uo!2zS(vuI`bAR-fRtR7{bE4!eUT?E<`)SGX;kkuC zJh+l-GY_QWCEc@(q(&FH*~#-saeI|!pme>5 zo~LK&;JoAJh@gc*IB;esN{Z zTc1MV#0W@41H2}o>3Hy?is7tEZJuCY^YhE8QY=>`T9oW{)i<3#WTx;AZdLImnBCQz z+AUZ!GQ@X8#VfPrU2ahTz1f<`4R1CX-C+I0{|JR3i6ac3TB1yHwLV#VOhKSP0c0$Q zk+Y0{U=ub%J+NpPhHc|j#Sp{~mBqPfdrqc>a+x(%j$ih^qW6LF+?RWo(&htR|60(Q z9Ghqm)cHdmz`s27;){a3TIhd%z=1D_;xr@>g;+KNj}=#X`PuOF#rf+~v<8 z@wv0(qxKCH&D*4c#q~dsaENNYoV|3$7M2mvYa~gJr*EY@Ns&{BaXrhl$$bS+Qq+k| zD?DH2OBNh=IR5S<9KQG0ZpyjrwG`cVfHV-X-BmV1W-N|Vevz5(mTE3wXDO%ddjZ-+ z$0udq$2z%K7*>d~5r0PH;-#d^AF7=K&m&Jx`R?wBwNyxyOVX;iA6~w8{Xx+K0Joy- z{ohh68|(j%)XG55#=`W!wMzx7$vAC|qi_?G{XpRiBtsbS21v+8tjTt_NOr7t);Rf# ziw|QGqXQ&Yf5(6CI`;wMDXR!TzzFc{{z0qAh_V&GR&5U%#ohs_=ZtDau z>zKYD)zK_UqZ}}@an9sS(b=`4WpJyc?b*9D9rley?Irpy@!q0JC7o1AN@|lQg&Oa@ zzR2@Y+ba>TFl)a0bX86n6lhl_b)LAjGf&vCaI3m=RE!ejDDN?h6-3od!T>VCL{VFG zXa=mTx~!+)Me!%>?xK=R@r+zAste?U5zYqgx&pq#OWQw3Rm02 z>wGMu-_SwlahhD4)aqQG+LUReYFKx7^@&GoZh!lNs6belwhaBZZNb~vf=?O?uG*|J zR*%1_4wsY(#S@?Rg~894!O6>Ia6i|B-pw=}kS$V`Cub4|ViP9o&7mJbgB#-@20efS z*L7upEuh?7qkkS-$#5ur6pP#&Ekd58?l{tx&vAx)1JMtV95rF%cYI65- zzlI5HIZeD0{C6~dI8Fbh_7u}zOm<#uCT6TbUZE^}F*N>CCyo}ca)f}wKp6s^kdwP< za<7+7&TNzue%L_Zqh*X#y|&hkm&QB8t#F>`$MW-e*L@Y725Hl~VW`yM#Y1%eV>UXL z8c%lJ#8rU0)Zmd$Dimx90f~vSI!b_6#tnldt?NzO@>Hw&5Z_0fwK(^evdwcZiC^`@ zo7|CyO8_nh$e0w=PlPhCt$>JbzT}WzA=UY)AbmRimoV69lW{^90>Y|epUn>~^XbWy zZ1eDxS{yhjz<$wJL-Mexe{Q|~@+5#2BPP84FGH|xsRh{`xr;OqfM9(Gc+!!U<-FK6Gce@qb zBdW*x(t0zUoYN=TH64+JWvD*VSmjo=Tq}cAkuZjhv%@2K--&-qh06Fq#5QjO5|I3x z`i&H=lqY$n09!Pk+#zHj*c|Zz5o_aisy$|pBftQ2AE62|=%RBz+cOzo$^5znx9}aXZCSJWhcQWcPTUfCJ-{Do2EqXKv^f~4tH%m%NygVQ zY(I4{>qi78iSRw5MlLz)v+>VKamG0p39<*GpaPq@Lp} zi&}@!46&>%(~3pmbh&$NlpkGm|b{ANoAf4p1@Yv zWs^WM5WI?i+cA8NHId!dLGM+?E8Qjz?2RU|J4U5D_z%Kh*@`W4ws%KjHv{IB=e`g$ zYr^*#@kvsL-E@o)mvCZwy|iQ#T{I4Lej&f!Tl>)ljmCu_l~WNZ3g@#2`Pz~nJRQ2j zWAm1+XwzouE0UP8UgcmJ8eK-Hq;~o-^Ebrpk%x|G;+kGg8T*ZIA%pDh6K#K5n*3r<<2}krbv9goGvCM zmVlmJbLHx)E~-h_-wH)ihtvPeWEP1Ol}y)vQhVPD9GA-O+lqEqwd>EG%di+BRL!}F zfl#p?lT~hpDfY4bM^`FP=M|PEZ@|G+!Ehn44g?X~nn1ezB4(tNFoS)QH|H5BVn|E8EZKNl*C|6}oB_8FU zG4X>t{kZs!(TJbMXad2e$1IDBUx$~&IsDC$#ChG73(queS+d)PUu-9*F`{=$O+%3& zVwEM$DZ*W4c_nXT(z+z?{1NI|I|R7e;qF2{tBbH*pSq`95xpBFovS(2PM7reWw~cJ zjjVORo5pdi+p@VrW2-OVWUKY%*N(aI0&vwYr6zl}VTZsNGmq+w`Jps6iX4{6u0?yR zB`6di9|pdgtOoxY&!>Kd)2x5X7=}BfG@Y2Vzv3RNAQYKRUz8-KXr=k;H>3(ZW{+mx z^8UgUm-c}3UfdXjJ9#cMwn4a=C|c=_yXN9T^J;>ABVL`J z@e*f)9ukEImTr>c>|J|c2Gu$zqjW4gZb~b7O{^D@IodLLm>>IX^ehkCC_2se=mDx( zwxw%4YKjdRS%41WV^uqK^-QU*jeC-U2xmapph^JxjCjnKCre&(>izdBULG^mrbiOM zyrtL@(LYk2H5x``>g|HSh0q*c3lvtbnz!&ViV!<|F5gSqIm^GLuq(Q7%>=kS-h?RX z4!X5INBL$1&R6D6D-K1=+ZHn?^)WYl|DWE<;?xt5fC|Dh!`I6L3EgNBa~4Cn%%R&~ z%WH`G((tSDsn;9c+V%h!O04~xz^v$Q=;ghw+G@9MgX1FusR#Ptv<5jzYRA>5P(4u& zM*-aFBE*Eb@>VTsPWeJM6{VrZ5<8S@uSrSj;{RB-XUE$po5868yS)|0ss`jDp`cDg zbo4Z(K-3Bu$NQL*a&?7qioQ@8mR92SBM1UGf-*971&;;!TnT3Ar!}}ckBqr8T$y?Z zwz`gQZ+a9Duj*n13&OX>?fF!pZbPE8YxZvb2~CSIM!96ineVzynXQpm4!^OLv&s~= z9s>!5lc^mD!>%ZZK?t>^Tasg5039W0LJ zam>ZwyjcuoSXH!2{tSJg*-Exp$;;t<%W`wo{d%zD6dxUpB3Aby5J5V~TXSlQHE1<# zDw__}1=V80j1nPU7Fuk!q+h@4wEx*ciV~7w<2ypl!mnk(BaVth%s&q&O$P>H3N~)Y z39VUZGum7ppWMa6N7ToDwyi~yz4Z|<|1oPJF>k2YOR7gio4!N3tpdaKWg(?xvEW$Vx|+Nkz@J3i<{ujq3HbW~#%TI#B)Fbb07V zux7vU6k?l(x`Zf94N^$iPb0}3f@e=HIn3xoh+y^XRjxNXjc)o~+#sl89be7s`c5Q|S^=e9(3n3w! zS&7W@Pl4&hW(*-I@=w&=bC)5A@oF zgj2k2O@r5P--`M!Gvj}m&&uz#%>4|lB~`N_W3)SaoO6_4GN*G`DC6Y0(7+ar--VI1 zXiq6l77d5f5{ZyfaXCb~B|Jh=omseqb9lFS=m@c6CcMBS6f(p}!_<-^;e^qj!X-5p zmC{&CAgwk%2`nL^rJtk^C}6tk$n(pw0PdF4l$eO!0Dq2w5#^v~gKHcOs5Y<3m^Vmr zmA>LZlyX%D4af&SjxB`{x_=s2y1$JdN0)UOyh_6yZK52*%%+e1d1+Sr@nbY59-OM+ zHJ7UsQ5EPAdDs8s+G0utn>AT!8Yye7x0aWJ%-uUwrI#2?6vzrRg`H|YHIG#}ZI^kU zEif(S3jWqfOmK~eKOPapoUDL|K!hhw{XiHxCl zcd%c(b?!4BT2S0%no@3S&mEALq({^Pa!5DKNm^|p4Jlg&>6DWzc#iGn@no9^Orx*2 z^I0l;IOf<`$H-DgK=mgZ2|MEXvX_NSr;?{knPOlBMjrQ~UZPWCNFu38kI46#i*s&| zM4AqqZy6CwUNf=t(_c0e*nk5bo`T@>EzeF1aQUHP3J2$ZOBE1UPoP7AUuEkanS?4W zqV+oVNir-)5|UB1P9{PS^|DbTrW^%Qk>|7-!|q6h1iP4xJ5|92B{uD}2LBxkev47TPM= zEsOQ#j>w-vp1oGUHDPd%s()n7;oH3jpi|hTUfZ>R&~-HE2N8_t^{#a$WR*0h zqWJ6{;*$x6_nZZ1Pq`!_Bf2a~X59a$Es`|7cWE7;LM_1Vgps`Uo^n=_14lg3{fCX& zhcjy8RS>TN%9T;SX#g-Lqals~8WcT(jbc!OPOWU)H+dL4&|u4~ifc@%S=CG$z7*`R zTtJTh&Va&?l81XCn<*a_3;hjONgKSZh@_k#s&BM76arzduP!j6E^jyR!C+}L=^Nu& z3V41<31|d)tcKK)?DW2hTml&MXl#*C$A4vcuDAX;X-5sL)u+|nlH~o`?BSRcx)w8*YXQv)=lw zh$uU{ldE#)#-3CoSk2XTL^dPo1@>!vofW^y$)%jD#hncOC_qJtq(~d^Z)ggHW32bn z@%jAK+vfg=jV$gE6bb28Up?GdentrkaIHd%0ruz@zlcYFK>+Q0P^hcf&piVZmMJKP z`kNbTeF>OXvFoRYhc0M|s7ofC`N;-}i{z3O`a_Qp8x8Z{is;p|auv#Hg23XScq-ws zb4|+0P>D)wjHW9{5Ncn)K?ST#7O)Ya`)s|{EdPx45tu* zKB!rVc8(h3wot4vIt&lmBU9`jbgTY_*63@+3hK-_@!1Tm{h%q{#}L!EFgjiHTT0Wm zek+ExI|D8=PAYq@b+Gd+1)YO5UdVc8{(1G=&E=ikOuS@KD)>67UD4FxrSA(<;}Qh0 z>9$*T^4c__F&`a*f_xi?s5S11y@Xc~4ZQ*OB!RmZrb!9Ka0g)lDGF`WB&`a%rcOhB zLbz9;AOHQveK#_Fr_{wK)~Zo3jb%MP2fkNMAl$qE6+Pis>7H97{Dd$}jXGR#*{*14 zPoxBDp&ey%&QNM>m}dLvlejzk^mLOdg6QyZq9bQUVxkb*xyM&Qk6nx5xG-j3G@~)< zgU8$NSYCxsY=m9!_18l`#-W;`cy6e*Ax4CrWT1YIQa=uv$C|{@BgGKln)74yph+he z^HDF(r55O&tZJFmR;h@(kwre#>MV4-m0MiQKWYgs4nx6@*9z~J4pA0KLxqGX!7TAA z&8+g3;NMy2AsCW$%nSY|-_cE52g>ZiKmB@I!)0RQ;~+oY|5wQ;UTX zv+}ogUY0dTvum=n2!Y%F9+7 zjYj40(PLwA*|FaKvqvV&zjj4(fwG&@VJMbo>$c3!$@0B0xCXal#|T~zAnOJNDga~^ zgVBCLmh0mJ5=t1_i91-8CIp?Uj)Krz_@2HZN=+#)hVRdp1vq87m~vf6N{m}Jh+#52 z1uQzUHXm~Wrp&~4g1qJmI z>Nw1rC`&|*WY9q({;W{p1UT&rdnK*lc)=MLoftM)JBNJ?-h1ZY`2p;1#p1e{7tkBl z*La~PwY$wa)NYZ;wn`*?=5U!V)!;qWz0xzbU!1EgSa+YbS1fpWcK^QKZ{Uqij4#6e z9CZIPITA_0LtlrzmxFbJHb#zszqYIQL%W*-Y_;7$i!_qdQZy1s(p-tXda)5UMHUyg zj-_MajTow$8Vehr3kNVSx)!VfAbMe&)kOz0HrY#LhZ2*BKB}zUNNd8Q^&R(~MjV_} z*SD!lz)09GX@~0Otq_!|L?`TcGvw! z8jo2M1sEBYYHPBQ;Kquc2MHy}7}81jy6|ClWGZ0<2*c0R%USmawqW;=UV?Q$ZR<4f zFX3qskWYr#9f}D6m>{0&eo6zO{zG$3>`dt)ds>&n7I#IKbN+q1>OP(&RnpyFGFb$9 z?+S2_7)Mx4Vvu>O80$!{U1fs^C^CU24yZI6rGB{aB2eNIey66dKgGh_t>Yr$a4jfK zUUt3gdevIGa2BKcZ#;+X%sqi{QR|(!4PABn(^SRvn6#v397WWzK0P+zdfpDc+p)I| z{NjNqYPe#R0iCsI*7v<`hBPshIE_i>OY1dsK#E+v!{f7<5V|8R9=|0fkrD>)(Q1X{ zD6h%lZJu6g!4`uy{uYiEsRXe$fj{!uYWqTxi?ZTomey+aR0y3=W3b&8W=m3yJNOYM zrjQnVTEzZmjdCH_*GknEU7E-BQ19_$_A7m#eb@3;s<+;c%S$HDo8 z?s)5q9`^{p^$sH`46jUpS0p@MF>d}H;o#Pp$4{BPm;i*}hXo9d<96a88X6gd;^sy2 zPdLK;FqJ0{KL4gX8{kcHSr;g0JhpvS?Wo?)Stjx_TIDPP`O`ti8N1$}@TUT@iW{6M z*}H{~4%4dErT`}bb@m4v{oSOzGD$g!w0e~L5_`*wTgBdvc7mndZ7}f2<#n#d0Ah;7 zS=v4wtN41*%QB_8%}H9B&)?ndH-NKjiSO6-CytqMBlsQILUByD%k$Y7irQ?gd~+~b z-l|X#q6ZmZ;j2wdg_Ju)5)mN5{ZasJKG3<$sAx_gD64^^d&UqdzJ}Kq^%yd|miwD1 zZ*e{wYe$B&7jHRB=AJX#d47UDA;)|Rpu(J{A**hU_v|97*COyN-o>W?3da$3@c27g)$Ny&mfDt zscmS6sk$*(3Ybbri(Do3cmsvLuX#rcI6!~?B2uM^VVS8gPX~$WMrNGF_6!ul70kYcdsEwyGm7N>&&J9LOs01 zj)bS*tI4Md&?{THU_S!xdHeZobSbwM@g<5KAolA(OKPiQv-TxJ#eu zT#%uzk$3S{npt!lITtPFJUiFBsx8FLs29dAX3wj*AJQ4HhgdRgKExhIMJkQ#RP8$s z7+xT*{Sf)-L+?+S=y?A@KDx%%6W#s|E~Uv(1CT|RT<&LY$$gtG7cX|em?lO?X$~Nt zL6$M%Q1)g?n=DS6)qKp(TXd*ACw6LGjYERsXrO_FLdEHN^X7Kl0-u=@qwRKbNOi54 zlC|es9Np_4rAM^Crczx^e94gKrN7giv$av$Py6Z!JNJV)sc1VK&LM*hFjlauU_*SQ z*w@d7aw4uSOscF<>#V!02TNuwQTWU;B{ivyiUqG^7|jO6mXWp9I7TXm)ql#Q@QC;* zhB5DCF+vdH(S9aud9&^lR<5eW9z)5Ug^Be@kRwZNW0*Gk?i6vm`ZAoj`g&;Sv|N|@ zBO=_Ma0I}Jubo_@i+RRRL>MvJTOoDiJv?P*Nee}w{xWBStp{#s28`=zR5jWRtzkg>exBq=-#_Yq%?_X4!|lU*;|i?f8qsh*yhNQ501-Nm&3R*TfH75 ze9fF{q@WTPy<0lR&uX&N80prKlEN3NSnZ&K6oi5dy(^z;Hdm0m%54inm-ES9i8x|% zBe{?H#4AlZx|5~MULhwfn8mE-v+ngx$8&ZrZ}Dxp?lw-RXAi&W``s9Zjyqv0&- zmd=2l^f$0JIl#iWA9aR9yi`u*h6Ilguap92F2UpOq-)#Uby z&7|{r%cj~kkesEW2iH^}Yerh+&L<(_GYqixZuXR>=b5*{HVhdqcitk#d;EKscMpVe z76Q;UtoE)pp!E`?VMVl6;T>Oh6lAeLUEh#rXy*F;EWCzuU3i8#`NG622j})>Gryht zW=z~AH9UT^1LV%x2mO!PQ`1^X@G~Q>izFh8Cj=9U6%-cJz{gCYQ^R{9YqrnihYY)T zV<+A)o-Q6c!%s=r?491qJ}qm>1yH0l*i)Eq>K>6>)k-!O@xnDzj8)8A1LS-hy$H}8 zsL+p2TS3Wer!TA0b6zD4Cdk9{$rbZ-_Wdy0iJ;#mZSSv7D7)ZlG!lnts;rLUp5Zp* zzN{K~Yym9#YHR5EVVv^2kwV*%z~R=qrKVlKvpBRZiFFcyxf6C-YGRvCjCE47RChQC zfV@%{vUpgbEyL}4=+AJP_`+qU*uD<9qZjJNL61u)!;zBiou|xUUfkr;^hOv`&@MWQ zLKMAPxGz=T;)6g~G)9*iu`ymu;3)a>n4kd?Uy`=6Yr0OW21DVdVLZmWpgKI9wdCfr z|JMNNWk>06Y@}?!oT^%(#QKJvzquBYEw=C99uMsos$dqDj7=)R&Frbq#!x$M6s@)i z!$byy!j|%ufUEe+1SqoK$0DLvRrRG|8I ziE&yUNr6?xJW}z}@Vwpn4@)023GS_~)BA0=o#TBc<2(J=yl#Sl_vlw`tHZ7oPvukd z#lnzleiN=AmJCnhYXEg*^Vq{X&IapGh1cmpM-6%YlaRIDfA;tShbl)ZgvJ3|OQPG2 z32K{NH$GNXZKGG+GO-P$Ihm9YBOBN`Vk;apga}dMcUUGv^^W|xMv%Kd5*kqv{1H4wCf1Tlemy5Qac)_?r?^{cq!JuL_Y&&l9w{e@nfhi?k zg|@Q~h4%@01IljVtZU;CzoAjYL8v4{v4TxZJrOcR@|GP3CFwC4Yu80)KBE;5cnT4o zF?Sn4kX4O;+erxHJs3DgL-6I;M?Y1P<0rLjW8g3Esq(@`tD}&-bE@t>5zso|7^ZJ` zHatiax(`Hl6X4E7NXaOoMYvK(G4@Z~&+e|{?H`GVM1ZS_r||3#@7eZ85fUwZNzMxV z4-%eBjc}8Sb6wE+2nncpxv3V(X9lc`+#>Ez@q7;yJ!jDWVC)@&bYY^c&9ZIVwr$%! zRd3n0ZQHhOpR(;!w(bAB5gpMt`k(Y92N^lY;flT2de%2m1_mt^`N6I3vnVbZ+jIpA zXUn?l+dms7#**T-IxLFwplhnNA!U)gpuq#?e*&CBMVSIQ*DzYq7U%MQdSwSkEp8kf z>o6U)0F*OkxM9a8T?6KE(DArm)NysJ1Zmkn9{4sa?~MC z(+Jg$luvBbkZ%SPQY}I#kvn@aDJP371~G6q)6MxD9%TpIaEj?3*5)gzHG^&B4!CS? z7(=9!3g<3}>`YQOa!Q0dAdq3L9N8#Y*9pYMDZTbYlA$B*jvlO5mlf(=*MFRzl0IjT z#^v#h%u>GDPmvGz6mtl$FgA*l)uzHEHOm{haWBYwXoRoj_t>{AjrLH2cmNR@;TR!a zK+ojlJO%lCgq&v^ERb`)g!=7HB-0xEPnCOipXs0%c>}udn&X zp)5KKu3&L}Vd7PLPkv~mM|u(;X=IXX9+&{;?P+5Rpgn{+qSz`jPCkXey{$^!L+n5{ z*EKFCU2wL#@Iw2|tYc>{r#abZk_pV}Rd}@wStFO7u4}4{oR|XRY%dX2c(roA{U*P? zSECcXj!=cffGk3j*_XqAU;7zCA97!_CO%8gJ8}Lc!o=9Kgvf~r%7Wwf2P!B&aPB$_ zg3_rE5RNz&Tkb-|C}xB^ZwDT&bdJRmvPx=>q104hA^x=xN9?*CTPn7fan|{kKc)UM zDL#3BQ>#5uCzx6k`}X#^OYcWHjHetTzh?1+@^@bU!h^~JtUJ%R!o3bZ-|&J5sfQ84 z?5>4u_n*pD+>)l5?$2s>zioi=Uux^e3>Gg8K?fpq;RNNcHEsQsF7UD}b%$-FwH|n4 z?A&L5rR?n}@5De5S378m1$6v6hSeS3o-|H(if_S7>=>pzjbs;z8`9N~&~Z*$k8;tx zuYG4AP{Sf&R=l$Kf)wDEc4!(Nc3&YkjYafTqxebNEH&$_M_%-7 z$qkqTKmX%6c?Sh62bQc74AIqYHz59p>@WjH+f$6!T|^791d52QZikBraRAHj_N6bi z`0Icu3gyrJYGI(qb}SMppj@Pg;fO~$a(b`s!I5HZym1f}V5Us6(9OAE`?&qgsN1e{ zOBJy%hn%p!4||76LlI}|mzvPUuAX*qDOg<3V3Fvk>ONP&&Gh8w*p7rkU%chWhe;e_ zLh&97Ht`JU(7)&)40g7&?v;1VrsM1FO@C!otk^K5dwFWsJPJD^Wd1k8E{YB+uRlk( zdXY{G6?L1H0ZU4>9!sLBJCuZ7Sy=;6KJ&5CI;;S@w$PxH{9yL^`EYoOxXuW@wUCja zDH~bh=_=ZNgO(bw$U#3Gu#Q$M^wpA;b$@`KXPzwr-x4zXJcp!H8C+TpJrnO=0|B5z zO+)-hWU%e+NdjTr`jgT~vM|>a_ns|b>p_C@NBe4nGC3`9>rUk*_*`9{cXZSSb$dI5 z4?4k|C1&~dS?Z3Cdju&HPv}R%a!PBY?<%YjpVHCBWuIK;shd0{VLz00?Bq%PbsG;= z-ySl9?E24%z|6rJ;o}xz`*oq9!jp8;P3LgcS=^9sC3b?v4qB;h#lwPTKhNYQ6_^Ws z_{gn(a{`D;JIOl&se>QI`mxszRC#9?(OqWW=~JxZJcwihYKkUhahfA^`ycx(R#SNB1PG0iDXQw_54!*d;Xb^I;CXc+k8`DT>)R)_{I_n-X4UkH6dJhq?D z)nrOqvqc~N&bheAE?ZRWr_12}boQdQyS`D$T!DMqDS!8Ne;An*xw5+SE4sM^3E#$vb4V4cL=orDqlEIshRWTXu33r8=$gXJAm)_&LvVdZihQVhB zM%%5MUTJtF2FY3z&h;#7S#IkS7+ZX_Cdd}Wt-u-|~F zw%U@#$1PDQEob3HG1X2t)x0!J@l@<#uAEh{*9kxH`yrHw+i?5V07JtzBc>F@cJ&qj#_?t8rCBvY5;SklST%`QV9Vo|QKcV^Y+?=Q@2 z9yv62BQ~Qo_1piZl@ZBF_+Dl(R!uoWf6t>^0CEXm6|HusTS`1+vOwvK6i5W@p-Qwu zUdY*AYuS{rnQEh4jhP~kolpom2e0QfBV|lsB5G^}!1l{$gw z^$5K>v_qKv!C?!$lreh7)EVP|@NBcvlDeh8{~4H62{pStJiX+OtJA0ME;xF;6x6#F zvQMh=u(MHWl^M0t%a+JWD}$3wR9Y&jH>q+dR;6q6GBYX=IEzXuhuJN0Y{TyN{s^W2 z0%aCQMz4@bShrNO>pa`oddZ2XsOd~+bpYg>yv!1onBrdG<6h`z{hLt$LsY_8^r&h< zOuJ$YEa+FJLB*L&J7RZeVE)d;BXU|qm^mG6L77Y%5f~343>$jdtye`?nbHx`sS~QI zsg=2v_2)cGIIM%yV>ay@&W<5mx;04t6gMRaK8&2{=Hr*gxeu5ysNzjUI`_$)^`23l z-JwSNwvFq?|HZVU^9nV{cRx|aq%@%_h$UMnWLkxpJEVs0xSq!5vBCzkwBSORVE(`( zK@G;jiDYLF5)NCo)jx@aKkU;u+v03)C}m4DfIiBY$dixfE5%{(acMpf-}CI1ZU)ty z9~zCYx8Pl%5OrS57oz~JR>UceSp z#a#5k7gw(j_QmeFd819~lnm5zZoM=)d*jZz&c}fwBfr~7`}G(Sok9l(r!DTx5Kd2- z1a?mN?Jj$N&fLnbAAhs+yIVS@AK9SCEgfKoNeU|V32o`h>RM;y85K~h?52j<+Ss!? ziKAY>Z~VRqsyL??Oc$i%Nq>;tLuZDY@BOG5&?tXPeGDpw;HU)o9RS_q=#dw3zh5f# zgm8ml;F2lNUH+3jOV3ND)X$_^YZ`r*1-+uKf{I~skt!f*NAyR@8gl~GsL5zm54=rk zBX&P0XkdY|G(Hw2ciFt&(qOyMey@~;{A|O-%$>GWVKXmX-B8{Zn!kUhQPu`{{NW-C z?4o{wP$;r6{bsJyo6tCrLADm%@0Is`Vw-*gX;Nsc1f!(rLNA%$h@K)Y2y7iFqIvW6 z)Ly8&_m0Zy?-NIC^QodWBkz)50AGOFeNPom1uGt3>Jqoe9!FWw5X)cLpK_pcC8c^y z`v(e=wzHCZs^x5bU996kQ&j8ff?Q5He1W!W<<= zQ+!*xFSMG^Lli7t==UGZ`Pw{JMOY_|fRUDj(NMufJ5NP;bPqHCxlb*MKao#z6l^T2 z#}h4|Q<-Ks#0Whg@sE($Cnv6VBnn!vl^<9i>l3Wv0opJlNxLzZcl^Mc@KB)9g*8dg zF)rEee+Y1Byw6*aBh4#1vxTgWz30rm6j@2e- zC8{9N8Nukd1ryNxVo{Lj0TE>VL(IP&%BINMOfw0jq)L{GfZNstR(2Sih@w9f0kr@#lm1cXuX6dvOn@(O2pIb~Rty$0vB3;9;Gy zq|&Hzz$0O_FkO`Z2#2L)?pB;G4Inbbz0^*rdo zGYl5+11nQ&TI&!`PkD9lc@%GHt|a3;VHBy)YGXOr6^=;#Kdz`^3W)u6wHHXapu8q7 z7uD%;80n|-Kd@E#>CHt>cIlj&d|SF9cYAy+T@#{*$H3oAn&4(&R$-%if0pwk=Q>^x zz^pwxLeD&5B#~+e;$S=hiYZ~t4Wc6Pt$~rU=R@17<}XcA>7e;L8)aHSyd?tvZB(r` zcD5n1$M~tHu0+t)AxDcch6oa0a^c}I&xY}Sxw+wvw-)xBJzUh}Cisxvk_-gY-%lm{ z1gVI@#!b5?jRM*2dc-R`t+T;i92#uzg;}nem8;<(C*Pd#in@ezX)g7y6 z!s(-CBQ?gMMIRi}e4+=xFACyFt165HoL`zMl z=4Q&Tio9XH{=e&)hv}BCqFv?`syGx6c{Ynn30$g|Fif55lK}*^T`vhQ=7mh={MI2x zl?iO-XUO3k7MYVuxSp(q;cc9nIUFogussHN(8_$H#iW+6ZkvuWJp@b_ZJ6izREiT`r$%=2hCfkvT8DFb` zE}vQ>;O^aeb1QWd|Bel^R78&m$JWByjJ1LHtJ1xb0dwMdIfBE%%SCO=v8BLQ`n6AH z7}mZQ*8XmPJ!|cyeZxJ8_s5L29}t+GjjjlP>M3(oqUNVCMSS-iQ9U)6QN~pjG!%6P z6~oeATAYzr#`zf{{uMV{31!0${j)Ut2kDyRON@7(^3NZ^42=smhbbafx|VGg|4pgn z%#uH5tV)_})}l-DwCyL$ISTkO#6=M)22{(-Y*o=PCQ6x@fyDctquTTDPbAe-pmU!+ ze5by<`IG~;1A}OnL4syLoejKK>~!qhHj4WA$k+U}@SuP;YC*|4!ctneMxqds^@9|C zmBb*v-lhn`-qcGfqRe-m(lpKk4nm%oTPyfY-pvppwKouhL$CF{{TK(nm(3j94zV5k zKj8H4E7S8tP7lV<*z8L?9FK^@Y%#^2*1zG5M=PMMO?LbkHp$z2W>22=^Z2HGsg|-V zs8Tb~cF)zgbz(niL!vzP61ZJ;K~vo8bppn(_f|#muSD=M!VN|Ed}byD(BQb z(q0B<6Gr=I;^Mkh3!YDrYyjDSYG?R zv2T)tQ-J7wm+&(s3-dnSGmH6Jo*8W2gvpB*pC2&|pETbt;7_#{pNtY;896X`cElQZ zs0B*`D749h5NS!1vK3-URAphF@J81xLJ4z)ft09PP^H=R%78&5$*FgPvjZ?370!}W zRv!4d1*Jg|gpSDd8E!VF(pwk?2^7lUsNAO?AHK!5=p2b4M%&M{5F|4_44zSn%DzDb z)8B6lBcN7`Xy5-^6tgh>ulDQzk0}0s6fiUM{~N0U1_A>H0tN;~kyembkPx922DmA) ziL!~abN|mR`Wqe`hRtW(htGQu_!8nOa`Y=W3J?e|Fc^X;Gxz^`3j_ol{y+C1#0YN@ zZ?Nxh=qX9bY3Vq*p1Gbr0Rf@m1fOu9^f{j32>{ zO0Dm+<{R>6lf{7u(o?p5r#A1Sjm5H`kkL1%QK-L%zjh&vvX2*UVYHBocj163aBQFjU>uu$??DhkSyz{|JTJ z;MtX3jUGcTDZ1KOXQ8r0e$C`rX|_Z@M*X z65iJ|&P9E1?bvMqT4R90+TlNjp_lM5qkN~H2EPD&W+&AaxW6_}uH4UG6Y4%bV@|tP z>M_?fmt7nB3-A;AN}Rt=>cV*D{M^PX|J9dl<#{zz$LwDG`84&}Rs+?xTZ+MR-`HLA zT{~D>iZpWk)wofXnEHrwp22FCzoS=UBL8H%Q zuN1LpX%OZk0kxPwi;gPZm|62xk6a3kiCR7Ez*dNhH(yM&PSekI`M%I9W7SrYLd}%% z{z^4r)1*=ET1Qk7Z?~4r3ZRylXYemSr8o{bBGF<*$zXGjTu4iuAlbGGx*xNu@j}Fx zHOn!C5KHo&?6abzGI%$M5CwOxkb*NxsTkt&Ulw#&jx#~4vb|lNQfx zMnOdh%1Eka`>0`NlfBbQCi*|GaHc1y9sr%Q!z4V>tLahERsp}apA54c-)M6-F}o?& z-Z4>`rp!gB{75rRC5oq$`M3QD;y)v|u1jhmNQ>GL*Ze{Wq|AOk?jxe?iR#BL`-I~% zxT!2j>laSnB)Y>m&Fb9pl>L{h*8wpw$q|O9e@0nC_&id?N9I76)#9q|D|J?erQGlP zsv*oW*`P})+7+9p#5H4_plK{fTGxbqS=Zvwk_3>3mqLPb(K&D1U;v(5g-nLrSeRAp7W(@ zO^4=|S2{bt=QxCjTyGQXx5z!@yvZXZhC-jsQVe}7udtT-vfp<)$hVdZCF-=W;R(B( zo6F{v7OaCDNj973g33;1f^c;*p&N^z4;I{K%{UuMFm?)QOY*&Bp#iPUHxy4YTH(NH zNtio{6V^LaJ?MTZ+siZs({#MSK3L@QaF}fw`L~arz@cyE2VH&vcR|yLxH-_ zO?r36O2cDp3p2Bqveh&;AH-e*D7@XTko7m6bekm%%lUsffKmBRe-qh-CrEagmR&BQ zx+7>9nSP-aF_ArhU3>eRM^n*s{JK;k_Vh3o_lWgSp#O5>D5ApQj{bY-5bL{dkAH`- zl|oKL93;<%>-{M~rX-fN8EOt8hAoC5R6=2NXR9p2j{cY7hMY0~ScVGqcE_KNM{_do zGnk|gCn2~Lp|Uno!uh7!F1!1hA%sd`nEq$17cn{Z_4dowZ8i@{zBIJW45)k>%k>2; zZZ-sgifs-DOSD!buXnv)ik}|~k5(#Cn|1r~5Pkk+WDC~pPO*tDQOS~%e4{`F^DDd3 zXz8&;64>>`z6)3X?CvLna`~Ev4?z7qWDA(%S|Xl(+kC4h_EBz`_az9QJH)mkJwYPK zt4?M*`(V-%7Lw0CvmFiwgss)V8Cv44Q@y#SMOM^U4gd3lzzdhw;JZ3koqIl3mYn>1 z$$xJVGwWA_*EJr5soFu6h8UElI%lBZMnhN*KkWLGH#`}mqXJ3^|IhO~tBAtK7rbE> zDuy4l*MvqGs;9+hqdb}_SDR7yw&P`>;$&GGq+o^JTq{#}zg*w+eeyVpX5l7bCWUiw zV>MqGL!Z)7u++%(JJ~{J(B|owfpFV9n@=*YBq(9=hDM>{T1!N%F*l8fHFbFbk-PI9 zPELW9m^EB&@rEoMvlgV^aG^emN6W?j+IfWU=YSkZS&SR0!GmBt{)wnwC?mGFq|o+Cx~Fr1#D1S&*q2Mgv_f~NHz#alWy_LDAjN{o-)$)SPc_H8l!DKHccQRzjQY%5mV^ss5+ptEftl8qZ_9~wA0~b8|%c{tN0&X@tO-!ve zqN(s}%pL|82-V$Q=tqSw4cF}F!w3mf>ymS;P3P4V*SUe_gJs3yY{AQJ$cm=T+* zNtxi5`QG{?$I~IDPn9!@`PEKVvOeq9pYd;mm!-0Nb?6Ixm|-RI^d1(ccwo|ZZ7<6{ zD6TnB+Jd*Li3T>)VdoV(H#^jZ(#c zod?P7n`(7N8;w(sHkWTMz{|o&Y@m!13($@)mwaafI5)IUi5bb5STm+FZ=AaZvsoT> zKgxjUfEB&g`>m1pL*nR3rVDpNwZs|&EAE%*YOl1vLoJ)7hBnqtG0!$lK7hbX{~(?R z^Ovj;dr#7P`)P-sKCgwbLOGsYXa@kSR0- zeY>x=Tib|$3i^D@Z7v&GkxNh)i#goI!L40rr|IDf&GJ ze;QKIeHxyJAjOF)Uhtiih8X^n<+qQVs(L-u^ag;IVtKyv^DHKV|2QBAdn!QyP`86w z#wAw!&$lTnruhlH8NVMpER*hg%tyhi)V!l*hpUiPqb z{c^zz;Jw>Qe;n4TFN96bylF{nUin~=i!jWMH0in@-=pB((YJf@3vCUv2^%Rxx*GL3 z%F17c5=t@3Pbr%zi6UTHOciG;KP(tdCLRuHLZNFcD2?BHP8M1AkIFt;qAp@VfM0A% z!l2oWfn55#cPKJN)g-2&I$`(Hw@_%!FF`@GAgBfMk7%@XHt zI{fOdqyHOs-Dg)qh{{*F2wGAdq`5eJHQ~OxVfY5xAf!QI#ZCM z$?)D>Sq)`}>@5NwcvJ6z-1UGUdjE@-@tvpK`bqcwczX*0=jL0uxG(e@@CxgkJ!}MQQ4@ zf1RdEb51qBK6 z<^>3e{1ZOOcUb~VuTD4-n8>Z|dOZ=8q*=QplYNen@*ZHM;+qRR29Jb;O;a>qN&0QF zggmSw?>cE;?mh*TlV(u}ipbuzin#s&_h3zSAo{*K@Km_LR7-L!(cRRoZ;9nQJv2sg9xCL7kZ=nnD=*AGh8#Y0>HJ`Y|d+Wk`6Y@}q z9AZ;xaFOmh@z;FRFWR+HFqE@rJy-WtYcg)C+te1n7CVx``AWQ~hBAKk!GCSugSfM- zd$@NPJ@Vq7Lo#qw`(Zl(>wfcGVk+fZ=Z;d$%`_nCo)ra{Ij8FRaP{}~{?iRDO{@Nq z&9Iyfue?g&6c(QO<}vtXuhZU}|0ghAIY-ln zE>#{maYI3^R(Cokz+D?xiP)cNcH9WuV(MuD)NCXBVJ#FMGc~d2yhwlAxBHT>I|MaM1a16<~m;4c*I?4yrQD z)AAAKxFfn0YT{;(jpApxoc(;4EHVz;aNOO7Jyb=&Q61U98FO8Iw;Xa>X}qmEY5fWQ zQk;x7aUGM%O$o`+RcXh5*VslK)gtvP47K@iC7V&Poc&<-euY}Hw$}O=u!;|akc^?8N=Q6wgY3T5 zqA1nDUTlqh<(`iPIo0H(TilyziKw=)5?K;@G*xZ1 z$wBO%@iQpp|~#PoMTS8A|)6Ecdc@5rg60Xe0ug{q)ZW)9bz6S_nmSt9wW(; z1lk5TV0-a*P=LT2{whv8b87}cnwP301Ojt$i9y5zn)U;gfd|LufX&BniJ~y4+Zzh8 zTI$k&hm(i78EV6`-&xx+i9J=_@;evX6z}8Pmv|WJ1G-%S`Med$3|W=LFr+(E*8vbj zB&5t)*gPHU)UHN(@1g>|wwKRcnVgfUnbTrKDpd~p`N=1@Y9IBAX!YP4zfIcg!skRY z+=G~x=2hl==G^7i20Z`fI^8JG0*^~zHz24-02xa{>zlQISbWKd)OKIjOY0H z!tQ!X>}NsFsB_y%BL}Z&vW!Z@hWU7gPI$!zRoFf+pP%KLW1BA!u#0X_twDepm#Y!R zR7SM}XC9*^^Cn4l(_Q}Ft1NZamE*)|`p#b$aZ&0w>*7mnKm7eaqh@h;4GBr=PJIU9 zV{>|4zJ;G9h1)Jx;_#*uyE!1-)pFIvG_hglJs`;_0=;|Tj?>C z&%$7{8BnAm?!Ltm(Uj*fezof~N*!E~r9O&dTv7LlDFgi|Ah;qVRDv9_vinc!lA=8$ zf_MWgd4i~i13~^`0@(hoCr6vJ#<>m>e*~b$!0a|&dO<{qQKx?7Q<=cip)28UN|naP zx}a@Oy%9zZCS-ObhhfONbXj4b_67i^V~J#nNr(&z`}bFGb@`#Baz^RuFBVKR;o@_m zxe}k=9>#0e)fh*p%Km{Hn@hOh{lOAe9+Ew!|F6w^F-X=7vkDZL>Z?Y1io(wFd z#sv(VZeQ_)Bl@bvz|I|J>O@%4sGBj!{D{*eT~Sz0Ji%JYV?1n6OWH6Ov_6#JZxVZtp*^m#sGb;XkQ_xvwr| z_Fn4%qF6eaMd9PlMbCxb>r8{FE=9JtXpJFR-qT=sKN}D4@k{Pua2HF69B!914-M`N zI<_C1e~J8HS1P@b=CLRPvsz$<)!x}O2pHV`7!rF?q6ICeMU*_;uHIZAUU#m7z?E6mriDNmy8Uu>rBjn zJ~hOtn8dpQ3vI@;pgx#C43fuvX=lKtB?(&Q-(o#rfHIG9WbQJ-Y#_@e0_4~zvVxsN z)fV~k+rTZM)L5Y}Y0{XU;E6f*g++z_nj{mT$-Vp$9AE)}(WoOKYt#23@_-oow2)T# zRfYmeR#S6AHE>Gfy((Ac;)q0Cw~?Qi-9)9UV>mZWN}t%Z_uQd(`cp#>_@=@GX;&d7*wC!}I zv(q1G8u6(?4Luq3uSI6H&IvB1@S!k2ej1iaI0ajt-;NlKEzuLL(Pz7A5a(f>W}P_2 z-xA%HNk;Zw4XPC*L(j|!0A>Vt#zw}#Iat(74yUj6l zhO#86kqI&PTI95KsSyRuzncSe%f<8FU2rtO!xC>UUFX~|WEa$1 zr<(`mOE)TIXEx*D09XaxagrNGw=VGSf`xS5hz=*AO=IK)_HW)4Y~F&0Rurc=_G>g{ zvpu}}?=e;|1~~4^Dx|yJpA~P(K?FcDnb%2cUYKsBx>agtUBjD@pK{}ryX`uWm zNg$(ZSc=Dzz^q9oY;M{xx8!)W)gqY?p=S~}`N^g%ibI?q9Et`qQq0~ZTXKEOh(vAy~D6~&`nAIBfZIZjap z*@t2}r>(s@z3Sa?zbPTG3U;~{iQ81@{p#OLLiUXS=*xHDDFbn$d`C+qSkhTVl1opw zOvO27p{o?X7n>d-rsyl#5XB88_Uq4@(Kdtk#licwY4A?~lcgqOJ|nTN)IM0r#J64F zAJ=kp21;Q}O)|t#=3d}~CU+wm^1`(Bq(l>&I$;S~-_ym9gqBxl|J`75k z^c=Xr)Moj;S-75$kkUKcz!(;cf42|li&+Z%FnI- z3e6cAo2khAZ9{og16k4=?Wr9_ZOX}tg}SF?h?9v^+SD~M_pqd+8J1U$3O&}C|JfL^b%h)K<&5EY+)A) zL0WKyzV+O)&E#DZ(L$@D*-BznG3Q|;sw<+|jut9=5m72&K^u9*>0pR%P0#8_#8JX1 zx8r7xBRZr`3*~JX83K?^JY7)%;l1C4Bcpt*6a>p%Rxqj1LWveI==27vB0Dq9>k7>m z%M!i&BS{cN96EQyfs9h-S#kgf8j2~K7hPaqsPt`DEW4>7-})+g%SqWoHqnt@4M;7$ zP}0giqr((eI`FCb_L(}`OG<^TVLQVwJGC7Hi}FrUi5!-l{H~iuns#g7_QBZkS2ksE zJ5@yBE;TuH4~*&vk-B)&08DJ8fRjWj5EkQoC=iy#*H)2$5$6rJmB%L4!Px8#Bh^-= ze>Bk5D^AtUvR*_by7+kW0NnUgSM|KEZTSbf-7;{`il^POaed<5GM414OV`d~D)&uP z=4N8Z<*rJ_d`~K%b^3NIL$F`-UY)c9iKesqX%#UnC4r}h*}rZk?T)B_S@Gk{Fd~ss za8lI@t60heO*kIAoo9Ph(4icHO*BfAQYxpjPhC%4X=N2)aP>o)>@L)6nX1Nlzq45C zrP@0MsC(}03NAQSgMlY&1Klf1pKquO1?D^}1Uz%xrHmOoxt1yCj&c?(Cmxn= z1yYU|dN!8HP@^3M3o>0CNM}k$aV^cL3uIV3Vz<~@(*{s9xVrYo1tpEBfAQ$uj?%Fr z@1|JiV7Y> zrWFAn*LJjZFUAq?w_zW$wfIK^bh z#^rHOlCXK2l3dv2b1dw8m#OJm;R0EN(8FyNJU3kcKN+u1zxj{6DVpOg1(u*C@O4H4 z|HfingAz&AUxkuo>?sH3F8(5f7RFzbvW4QN^CyNaL0}LZR9^|2c)1^<*{`H9^HXu{(XC6&Kg9!4g z5)Sl-JFNf@1Y_^e*D4Isa9%RB4bVR^!MC9rn%8Dj>_oBDl=XX&_51}qDVqeOc$;@; zkd#r_81ci){jUhiJ5G>|nnkwUXrQSt1;CFq>#1XFA?n<`e7t;x%>T%xeJsX3Ww$B~ zaMx}LaRaKOVfW?%O*vdS1vO}HqBQ0AyY=v0y~}c$x|U^~NT6z`_IW8mn!uRz#P~%{ z7`l87@bC^NkO~&R=s9qRRz@v<$8UM-Wuu)2qnm)BlU(l$ahL-4;Zre;=&Si`yZCRQ zMnY(CRvL{^^&gYKx9dB6?jfMz2MQm<_iqj*;}iH9-~IfVTunQh_`CxLpZr-pjk^BV zmOz3f-C)VhK9v5Ml^bKFE!|v*yG0Psh?4?1$J1bR-I^?0T=YjzR(!7PlKyI`LbjaITzAP|iSSW+uv!D1(nBDY zKOl?D`(ysMAGGN6A!i@pRkEIP+K3Dr=5ko=W=Nvepyc3v5%5tc<>F7uZS3Xqgwu?`r*z_Y$SBtob*0QhaM)UFTiS@;4kT6aukV z=W#T7Q)fhhYpnInz{YqyAPk@Yl zcfDz`Uu*&eF>cl)9P=I}=T(#^hO&;lHB3yXRNILiQX+c7W6GT&Q@9eEjfNxRf~A0I zy@bg017_*Y6!q?!O*@11Z513ufCCivOqR_cI)w`4!KNz9ixCsq&tu3-)os>&y=!@* zWL1EZB2bi`l}(-ioKl6dGMbaiaOrR*KwIOBbg+kmdZ2{c4JO#r%s%OuAgVf?)%CX@ zobg~1aj<&n23Dcj#*lqrBvX_!3pLY17s=j)aL-yXpsb_gk{s!HeTOyKCV2MsxW=w< zm=9}n0`q{;{O=FWPfew?Lf2}2_Gdmw(L)V}a;W1YN1|&9JosK9W+-g{kbSM19*2Ey zj6HLnQ<*2#y9~k1*%G&}>1QQs&%hS;_0gFlV<0Y|$PwF%G-%rEgb?tZ2A(>>N^Il_w;S{+H=vj=g=z9r3ZP1_){sbLF}Ro z4DnQ58=MnJ9C>uwh%1E>_AbwvFiv#Ml0{t1>Q70%=0>EOFnTM*`5@JnP_msjp-2j9 zV6n>iuGY5@T{<60Io?iv1zUHtFdZ9ZdLQsx5rO)q_7IHaO!$ICT5`R;)7TJB+8&6p zRL$n}2=`7HS+HYX-O6eAgmLq2kayzlIH&O!cfwH0)o#GIZ}giz5!`*?xt?Sc!}{%% z8_6C2EnricMay!o52PafIf)9FI1#-Yp;;yymn z<3{u{anEbu#P6#meQGY1@M;TP8?FrXfo)8u82YGpwr;HCf-p`7UUOHj`=scJ~|5ZyemIzicxAhhBi5$Zx#9usz$YK9*<()FL0r5#;O>MAV4wsKvNou7A<);UCm~pM!O! zFPtOQP;U2$yv0!Nlq&@*fwmQqX4p_5Jq;QcPzbXd{{yU1!;44Si0=rj8@3fpf#;rXg(V_Rt(L^{m}#0Pce8Vue{tUfal7wIx{XM7||Qf-P)TtZSMU34MK>3Rans zMTij%fgk5a`Zct>O6ivba@JCY)_^wq1&uZ^@e2li&|eOO!$|jScjRy%2GYMaRYqH{ zbY5ZhnsT^%&&cSJSzufbEK8GGPSnqz_<5$j_GKF4@vLr#tYF_&S84Y|sP&MD$QS)- z_xN((xLpE680PlsFhQA@yHO}t+)KO14&#VlhU707(qD6`ZwT7YzMmv!+G~si0Rw@x zR6&B&OQ{E+-T%n^mapmi4gdD>_Y)hHi=ZKJ2SIO}s8DkeiitK~{o2q!#D57~73$Io z;s{~R#Ma<5+jONVuRSOn;vpxNfbxthnB2_OOQeg3;-!an^P9YYt-@AZ-EmENd0znomf?6R7)R4E2SVGAtF9ChYYJw&`oS)k zEm0d~izJCTeg9w<-V;5dgFn-=au>=*aUlfYayN0~>+ zJCZNzw-$4_=fYzgd4$M2FWwRpOST8;C3_%MoE%!0zJN<#+_!Gj7xv1UBp}_9i1=|9 z`~vo|WAcUl!aIE2%0L{G&uzxyw%r_?D&$z#|GLg2a@wx4reD{p6sxx9-j^16x(b|NMQy!~5WKmAKLzHwp8H5^=~C(4JCvalUz!WU z+0DsY^dN}3-(~?JDP^ZIKi)ZIHMxc0%2n?vxAo|P z?JUh505|eWc&)y+%@GIoJ1L-|o+cLn1pF~WnCUYLq!A_c>w-8hqcW{>3MTPr(` z^A|Fa&8%GNrdy58HQwgUjpn9ONV(3IZa_E#15s7NC=b*C!KHDySQQRPoB}J6^|?P?+@%5AZEc9HB2NumQclAw+z{>spaUZ}^_9?Rgo9=x7hqHGI5-kYUblbME+qP}nwr$(CZQHhO zcki}s`|fim=FXWoCnhFt#Cpp0R+UweS(*QrAtD=4xYB6+a_aykuD(FGaYhoAW!7Ke9?Uk+r(R*fA0%2x-IIqz@^alKkNJaG-Vz|_uv8i*@NH!vT&*qwVu8-F@nV-gryVJAB z=bo0$el2dwTv$#aT)xej9673Prc7r;#{-|`cwI;_5NNVCFKg4XC7U2RxVDyLd>oZy z%wP`@!@`Pqb7hoPq1(>)wR>RZVH;}i#k4-4W}BMdFtg`+AG~QZ%7sQ(qPc6|62wAB#=AFaS)XD6 zCR(L1LIy)}SV!y-{FHaMl5MJ}rKUlMY;)s<`7jcvTB|8T8c(yODE$AWQ=9D_84*oS z6FGa5!yno5GZu>u2_fC`H}LQL^^hxoC^U1o21Ff5lYdgq-w1n;N`Hen5bG+1wx*1M z)BCJ(K7hijrJCDn!X1NeDAfa4)R!zO_zpHtOqjC92^xrZ{bxl}zf5>CQffT;eRUI> z7R)bJ8i~tGKyEOr^kJWzZHOo|0Bne!ll*DzaeSOX=Zm0SHdGG8H+H^tCSUj@HV9_o zXMX8S`1m)_NL?g1G%gm+xNGMeyQbE`pgM=v-@*Fw@FDJu-18Tpjc?$eJ2g|FTkJd> z-8}oFjYxhnZIB`m zn{~ocG#z#J_l&KSyG5~%1fm0a>C)MT)p(+ihpDQ|wZk@$gqGEOX7bk!tLqz5!KC~E z)zU$IMoB5ea+Hq`?v(->zFNda;d+!JulY+b_INoT9i0J}66KI$$^LFx2+88+wouh* z*Gcm(1=_9ElT&@qcjwIo5%Rfp_FKS8*|nFW4=sIsyvQaHs)XOA&J5IBiNX$ZTrn3- zRb)1=*G(#23`=yR$7OW^$C~$XfUpn=O?h_I;_I@!GE5l0fm#b$g-t4@wNPP?Z%BLM^}(m(G>gU5T`$X zDo$9khR$Ly3X)-n^OaQC{&irv-1>3LO~D(RTwg-v?MR?q^|;t^+-h!`=v;h1Oa(Yc4sof?(>&@;X|=U_Y?wDHITHm8kSNKGQd? zO@zofbdW*H=i4NS5S`>t%cGkx;QPSO&Pzgg$Xnn^Mch06wZ#n4EoLV?u@S1apetax>WScU;VC{;?zp#OSl4lkUGx+WAf5V`8GIXEZ{-@)_cCPmixiuav4J#of{r;w^v5CD{z}mCu$V#HF6s{=!VGCc6^^Dk#-bM(jyBzh=y1~XXrZJS+?33OUO@xGZX6>Mh2iI`7oCyS zcq+~GofQ*k!b5=_)YrWxmpP~%3At6-fL+oiv<$M4V-T=kyz5umy7;rVJOR770%yKN z$=1P3eDvL)q60(UsgwSmAT5X*u!!;udzN_fPHong`5uEW1ScfKOhZCZc*A4NTj z2%^j@@MjLN&Qv;gWrofLh{%rg8=B6(bnDxb^q2Je$tcISA!91UUK(?@OsQ{AtG~UG z>xQqa>wL|0qU*X2z3IHDzMED*T!GKp#Ig!R!=TX`QW^HqR%y&%&iQMVz4qT_H?Z9Xs~CW)pAN>Ggl zbyz2Zz7DC)_(ywxfd~J|eK3cIDzP*SHn=TIq8Mv5FId`zQ0wM`pz&jG+x)HXsI0M% zbwPhQ9`{PsxvgD?M33oZU$okk?V%`waP2!3UI#z%OijWnigg$w0KwISVFiDpZx1Hp5$Sj3^OtueZmd4dl z$LeV;!3tByj`L;>o`@EgKyOKQ@7T&ZvdpNeHk({8x)z|Jp()-vLJbfO)r~O=_AJZT zI2|~jYE)&-PQ;5vFWfVND(6B^wsB%#mSxlZKtjAMwKD{a2|y$&9hv7OmhX3IXzhNnngP<3)nNYm=y)DlnNg+9gejLD`dyDu^v($1ncxefaO;?&Wz$M}d$*AYpE zKjqrSjB-=<380UWc)SAYRiHaqJ{k_)y1t}B>R_GC=q;uvnx6oW-PgIoV9+5$O!(h; zf(;qTfp2o_ljIlLj{nAtRu~0!94AM!UiMy`H#Dwu4y?}4D$Qz7V@l2yT&0bclxW|F zJ$47!ow)6pZ)D$fUcX%PQy5dToNUwG%Vch;Tz*%WNjt{FgKfN)c9|U+r?*-TLB`_> zM@>u{9}y#BQ8{bmk{u-Nt_-cO5j+Xja=1)eJzF|WzU_Y8IHU9^?Ma|W(Gpf_$VMUl zNaLc6+JRUqG?~odPk}rDHAb_yJ5wz9g)hLyAFKtzpv%9rdknX^G1J{(7PvDup&IU! zbXlHdcEWPxt$nzvwfQn?yv-VvciG!Z35A>};s|dAVP!AWLpv0){cK22-_IF?#6Hf#q|uGG{jZN@*4*03A$;ai{9e3FOb z6dSuOjlDgs#9Q}z2FeY!mHO3k)J||*ert6d*ANV-FH}B%r;$R&bA^+5qVBnA$usyi z-XWYtm}hGdQq3rSQE@xkV@HTT!q};3Pn604gIAe1-FWA!I5(0NGnk(P){N|E;RUIX=% zUU`6ZO2)oD|9d3{#Q>1&sU`of@=->5#{V1nC=)#c+kaAzcK;9csL$*FD;}jdkbR?x z;K?9XCB^n~#XG2=$qc0Vi*im#!I2BU;kVVdz64+)<;X4ZVvtjb0s;if{PA?YwA5zi z{oA?e<*w2IhJ2j8DR*y&VVS00bJUx{xG-7q{dla4g?9I?6+H|6aqD{v zJw+BaS{~d)c>86ru>2it7GY|mw2;Q^P<^TP2>vx+KQftF>Or`nwM+Z>VKAsus4mz9 z6y!$lUjp~J6IUvCGufe+I#4(Wn_-VGtt}l(y0zC7zi|}z_-{kp+z5W3i}}gy<>rk-UGgcBSqgQzdD$bR?j*SREtDIc+@+sXhS`?Q z#rXY1Z!aHZ&HjS#yIG%1p0sg)B(l5fBDO@qlVJG7Q z5B1q%vFba>5=t{e;r;WKz-t!TQ%UQyxum{7Gdoy4a%PjIr?YT@QpGo&SfA+-Z6XwA2KVT}^KZH{0L4S+owKzlzC~?d-JAco9oG^acXk6-YUN38D|wK3 zgNoLw$0t7@iS(H2ai`+t3VyI!I*zZ!*z9 zDK-z{QJ*w&VMD}AgT8|drh~2pQRnv6EPjFJ8PVo}e2-uGEzv;=vM|OLz&DC=C_Wg+ z173JYIrCrXq-@+1BVPE73z$;5A%t z{`hf=MeY^KWL(wP0!0h45sPx=W=>T~ERB4$DsSBZ7o7HoTPnZvs37~f$G&|-02SW3 z2^*>nsz2mRh*as$hUI!sH=!YvqzOoofPCoDzPjN8pc^jxX=JPnf>#q_5< z6S?H%WP6vwKWON%UmEaeEWJz)Tto{t_{=Gx<%gUDp~hLC(w@oBP-`-7`F#`5Ai|g zq2S*Syz6!pA>SOwE#OcBqOCG+1|b~n5c_WAPl8L)#C25IDAw*B7>G|9@I>Uu#RE$j z#(t95OO4hW>f}D^DQMV{3k7=vj#DV5z~ z>VOqR4$=OR(z{@=EA}B;$-(wQD|x7Yj^5g0g;j6DN-^SyRpv0ogXhd9=`@dNGx(2&HA3_Xm&GvkoO$UU(anYL*;KQ8dKH1* zFsuf$JyZs~HP*DOV0+IL%j8|=;F87C0_l-&k5t4qxTV5-bQGW{(K9NhAb<&4ck^W% zl$ONMr-#y(N-n+Mc4)^BN^__YzLyvdIr|QWtYT{xiW!}tzkrN`WP<|KA}oo6B9)%2 z%se9g2`|yycF&H2{8M&SriJ#>>OC5?Y$yHY#l zg6xYdN;~z(!5>uQ4TdogM7Z75>6<>-u!#e~)LdGT1;A0*sxUZ_FP|7BB{OfZJhW0C zSafF25JkAVirin8u~c0ig`1Ldu)Jw0=`bnyi;X(Q514i+4`X?ZDZ20jgP@H*^2@mb zb#q_DTQvFyxF+Ll*p;G3#PDRyvgm5 z=!L|rXX0O5Ke&+hDE0TTs%cykQZcwG|(2o?R$OemeLQKU@5WX*u{K39P_dDFABq!a6By+wqA zLLwKut;uo`@7#DPQSar=pLmamYi}Li!u-WjzjW{9W&2SEY`&a+Z%Jm!kT)H=bHOgV zbqMnyMlU&p_#hS{?75&0CF0oMi=KRXU>d{{mAK%TsLfN=8o?eSIa^im;11~m94sg@ z1>&MJrbFE(c|iw@&ixa2{p^%|+Ne>9)5s~{RGcyACHWd*Pm2}^!xg?9Jv%F)@(Sn; zF@TIMrI8B&uHxV}iml_{jBy7ob~l-eLVEjB@q1F@WtW^~*UNRu#Ujig%k!z0ld-#V z=Emf5__3Lkqa_`1s?EjGcO!+im83iSSQ48ga+uFr3e`9D%qdw1;EqAKNz2W$h#aQE zSBn1{m7(XFNL{FU{XmbW*MS*7^+u~q*evlOcHSfZgaMbHn#}!Khzt%xAzo#BX~YM| z^w2;d6L|Nk^z4>hH2`MYd}tn9QqfU)?}(;ESgt@*)SXQ{WGv=|-zOFSn2Wcpsl!8( z*k-<8m$>c1!Lgv$DW{i9(qe>y72k*0s%UJ`?I-BO+{}BO4@Q(x(11+upQxVAKwjys z-e|Hal^RpnL~0P28Mfq#-5a5Q@-DPozF=&%Xu-MRd=^v<%Pu?bm>>BUHFIpsjf7{J zRuo0*`eswAI|U#@TxA12MYeR$w^{YaOIX<#+zVRvATAA>4^2ROKO5C4OJ(HO ztgaMHFNNz*D7f$WO)R@8my6DWZ0{E;C^);QcZqA7#pxW-33C5#=9U7fdIL3MP zrW9!XDUD+eP~RDM7I{7FNvy`71UTH!WmjLrzn}t?u?0Xn=H<>uA|~7~CAKv{e*a2{ zs=5t3iIpzukNV@u%jb2uA_B_8>?PSwE8PzSJpfRwOZR`14luI(uXI4^{}u|#O#h$J zGRkvuR>%SvV0Y5=_{*Xwlp7iu+eQN975bfI1>x(sSadwfc8VfFhQ-N-6va2)T%TkU zq)eZ)ql=1llm}{OY7gvHUJl$J+IVj~+{F$x8~DN1)~{}^A6c)gdbrm&w$-nm00s} zy4QHPFuU+CHXSFsx2|iyZZ@e{GF;X%E3PT3)tXurIXs6~-+z1{N!XE00iMV?LZV9$ zVg^FU^Mb&gY6Yt|L!En91*pRQbwm$i@<{Lo=p)`SI|rObdTEp9(N$!RR~RdC(8T}H z3-o9sBXFNI5V0GlhG=W3mL7xBm|-Ol=w8@CA8NZ;o?f)GQ;3EzDH=Km%$brH4I2Rg$7%j}sgVY#Sk4BofDlItHHW*{IXt$r1K%|fjVS+Ot28w2kBfYf3Me``8 zcJ^;gG>k9MxByKmy_kv*C65J;ER5OPd-i;*{R4l_8`WO@cYDn7|7VZcnEz7(XlSf& zV5o0woP786`26g&=qgR|2rt1X-YPB0B(uQE2s9z_8*lVQFh{id`56i`wV@YL&3E$f zt4_ZDtt1g1fLfjvkR}i7CJe;^(xIDNxoSnUVU`SuY&cwz<)-cY|m)}Uv z#8V_JK%}8GFy7xUzc$`KFHcaRSU^mqLcl((M3B!cF~GsshR;C9)S@m%z`<9?-qcRa zM5jZ*2U|VPz}7;}#K9mpz(K@EOI?|_>qhf+YL_Y@K1A>i@ zj!9#Hg^q`bj-{m>qfk$P0Kc!C82L;pUo8Q6Y<_VO2!kDLG{66TMw)gKo*XEY)IbLe zAGSPJS>AqnLII$PQWYRGQByfJvoH*Crr+Jx%uwIJ*m&`-=HT=EE$Q(ScA?_RPu5p& z_G08`=-BNA58w3J;Md`yE%$7LkBnzypzl^+`?DE=h05)#4@837yXGljcG5<9gtB3!ZfH5fB6epoa14 z;J@=0_W$KA{|7EC)Bkn_$n)3*)5B~(QgQ395P+P?kVBVA!hFkjxXzJ;ic%6V8tm<| zL7r8@wdV5Wep~Ojrp;~ueC3#K8~G1#3bjvDSp;Lpt_F|~sN=+vd+|`fb0>bfQmzcfsbyYAM33I_cPtn zd2DkFW*9kC=fcwJS`Z(L2A3i*c4`7~KK6}P<~U$KwGp(a>?S}Hl) z{7;xJ>pz(8Ki00JlQTX8J0l~VEdD?K*#CFR+_PtNtm3f88dl^o;#dQ(&tDG->G3C0 zjrvtVHap<lmLW-$5_;_D)m$rv|%+r`=QjXM55{GgsDr;+N)zsE5WL*oE z1Y8@K2HYx|6x<|TX-8!%X2~`wwnL0LO*+#R%kDywYn9&gB(%M@`ssjg>fOhjSod7N zCIJgm+es#6skV@8$^dyaw6VV^M`RzVD!8uiQifS@8~n=zQip~z|3xofoM+3J-DLeh zq(niN)#uSbw%D9T#TVIE(J{47P;H~j9NU+W^d=IM$~mp)r_uP%vZh-J>WV`A@3>j{uN{{Q`Ib+yZ0>6I#UK;b8e3K4|#^ zwlF*xUyMMY?*K@FQk6r_Uyjr5NK=oG=Z|?Ao@X{P)YH|KLF)WUn)rYEEt8wpx*Z40rwQpkQ4xXcLC&t z`@(zT-5h|B^8%9)IQ&3)%E=5PVlk!Ro;wKS(cLPid0#vFCnzEE9P-8Fp_4*4D4>W; zA!Ou{lqP_z-9gQklU;?`RyzjNHw*8d;^YBp!vb5J>_106h+oR2eK5HIMR$a;-X`s` z(G$?b4`yNy?lWA1z2NN9Pw!aJ;*vWnB z2x7-EWXgMYvZfGkM@+JNcLA2cbDzSvPO|u|-Pr7bsoi0b0|;cR>4DYAyt)HPWVx9n z_9yQsAVFB*yJ8x9he-$H4YSJ3e>l)eA~m86G|JC79@Tv)Lt#*N#V7$%T#|{=8^8#_ zvT1q~_rDUQCLFbgbIO78d+#XhQz;rK5_K(EGt8hL3QTfQ_d-RZzG5X~r^FN<1B?|x zU`c}xe3oMqzJ@777^VN9FXv1?#-vmdsAoueHztc!Lz7d)f?c9E%1VIuG5aSH?g40g z!Lc_J97pDHTMQ^J&P#iv#k&+P%l}>^j{%H_IzfBhPhc&Ird$D?kEB4R>&>RKE<7OT zvP3lBdr4)isaIkRksP;ALZKM-lbuSC=*BDgg8$Kwt#D*HO6~)N8*3S5fmykQ1ZB@A z0h#U!&30sVhjNsh3;=eFBxAl7dtfH2p!K+j28nJAmXiDSE5i(9?*CB?{_>H0DI{q|(rq~YA~Yh%}$wf*^sq8pFF+u`0# z0N$ll>wD3oZS9)-dGv$N<$HS`0M+f|PUn+{zd8+($N>E=dOmS(n20Bqr#|V*E6^1l z{?mRIQUK6}kED$J6zyM;5jzoM7^%RHbpVJ=KOf3w^k9^Z&pimzHU{!c{%0qPAw)rX z0cZ$SS_1MiwjV`|L4&ICkuV>x0e8Poy`U#2mM}&(K8{e(PMt2Km<0+0q!}(bxZZ$~ z^qW7{5K2J(!x@;ge!*~`*)Ws7^ei~|qm?oog@9luo#OMKV zT3tqdJP=HZjBamgAs>S7n=HRyl)wVr7%A2vQZlfX$vVUzo;_!+h>{9S;1KGO3Mtxm z5UKbd`ODLk66=*e4yuBYP@lG;+2@71#D5p2PrV;8i#J=LN8Co_5Vt%22t66qko4`f z=&@CYn$?h3Yvz8mBdbpCA39O}X};zmO{rZee53d#t!in6%b~T4-7bZaS{%!uEI2H! zQVGF6RX>!zb_R0uRUM@&Pf3F3;J_@EwGWD@Crg2^BuP&K!TMGu|mj#yI#QkD6_B`><)FR4Igo zxWkWmllCFZF4y;UyKV00>F%km@8>LUE{SO%((dQ!z@rylI@d0>&g~L*Noe?G1u9a% z!*ilp!S!&>Pm87kn^SA_;o3UxrtJ9q#`?1ni0 zcS3*znIQ;Z0~yWquxUSZ?sKeZ%};|`FZaHU?+Ok5H_8p^)7Yc8AL=!2f8?3qNp9AR z4$=3h4sU^m&*05>P&^v3Chl(gy{oJ#Y6Ni9yD2M&?i5~)Ztnb$uR0j5lP)OR-7MK? zDaRm|YCrtH{XWO{$8Q3#SUTuy(Fh~l<&H3vmTCfR;*f0ZhLCXGwrY?99D0J>0!ISh z)Idh6B~fyweE_XQ`kQvMOTBQ5lMm)(;NEA)knE1{9V+#4TRNXS<-gHc|> zQPfAP#h6MJ$OK8E0kOQ}C3@{iNb}uWE#&yq# zxg1=sNk=L}69@urC!UH~1JBvV%bbu?Mr;KQA(hEaY)WRNG&tf|tlQE3`<)AE^9l_Z zU~U}yJA#|B*Lloc=eP+6hv*l0^5}7)wT!1;Fh&P_$f+EmlJ>=-Y_M|h%m6Yp?Ct3V zEpe<dj8`U57vYX4JrQ#mNJB*ZsNk|5wW&9G&W#DCKL#MX+H9jh8wVvu1PO_gJUG% zZM%~JnZe@*how2HaGCZ?k#5^4-n&J+wQqAz!wHsmMKE;OFiLn=H|9mlh#S!zF|0Fe zP;0m`K_PG8mjIQdlvfN$gi2Pu<(w5pFWA0Zr%c!q*4zvJ2;k)l+Ktn15ktN$XsF^NzA zZ(IfHQu~tK83va+X~@JrX-_aayMCwzTN0C}>7cAKPSTnHi0$zzgGYD>6zn5&rOrMm z=?Ddby>P@c*8r5A zV-6q)V)*$D3yj5JE4rKP0ZHLr@R18PDVM=!)B~tp05&1@<$){}bo$;-Rw%iTcb&bx zLPt}+V}ZbIux1idQPOwv0zc4wq!A*9F#uCbP&V_Sp3?)}B<|P<&G?}`{QnVSj z;8-v|?w>pIEVj|Cd+G2w2B0@GEabV!#O!NB8{NRf^xhWcT5oDLLG=MZ?@Ux|(lJC% zaPK6sVp0g#(SA={P`DE$VGPKdOUi=9Bg7aw74tl8vy*AnQ8||dz!LS`B8KP z!dq>Iks9LFZGCNOH|0I@=^JN_^m^qaeMFQU$B5{Ajw7RT^e1B%&KoZw9xXU=#(NMO z1gD5xd(Q{cE}T5vFblJQ#4*9foyI3dGWzZV-1)HTPC>z{_bI8D-O}ibW(`muoDVUjEMIwb4h{F*}^wKB1qsI(u}c^GYP{%b@edm zjjY>f3=n-^VXQhrdHV{MAX;+jeyv zeq~O*G0OJPn3Zdra!JXCtNb_+CsH%_J&7uk+d3NM%iAp>mgES3C_%!I1~iGvEfew= zg=!39Dy?$zD?jLdC$>Ty zTdDC!Wr@A=#6el+sGMCnS=F5-t;mv5Y{fdZ^8Am=1IO!lY4asCuwl(|uY#Wa(3BT$ zI6a}-)1)>4lDb&S+IX9iQ>Sj^^NC3vu}aLXUc|^n+p#4$UW6CXBIc$fY*n>-J-0j) zG5QaNW&7u4`h~yND5uZc9Cyx;vY7PATSnqy$#V4u6-%zJ9d9+EeE>N|?U(Z?@zR`X zRa;ck&vnE$)!7;su{uBxilo3Td?Gmbta)(^~ z?I$gBYbrT>HZsLg_d-ny0|B6|!2l%FWc@y}1;==X1!DK#nWK5P>9Uf31TflJ$Xw?8 zMSMd`gfs&j8#JxjA^^R>8(}IA+LLxue6b;pL(**&M>twy8^Xa8RRUA*%EygH@;`En z46-Tq8G^uO(pPP0!)3@71ni{c$lKFsMA1!NoEUwKvbaTu^|k@G{unI@$-_?!QA{o4 zVolPsL7d`t5Mij>UVo2Q3V)xkZ|C7=nvfh>6iNh`>H|MnLPCXL6ece5WvVPAkOtIv zYt`$;GRiUge!$PeA%%00>yoHw{%AsDwWuG9agEn$#6iII>_k!_1ocBpIINrR+%WcP(Z z={E|k$Q2zP04AB5#7hCfZ92$Urx2Fj z6Eo*!=$|HW2VjVyb~bK7jGBX?abiy-tAR2}M?JY~!lAVdTxbReGckVocvkJ^(Smk= z`*v*FdNFHSIe!OI_PF(|O5%2$xuXZY>>_W7Jyink#`R#Q#V!CF5NvAW%Z^>D{-Q4p z7VPk+6pV+Pn-{}3(~n&lyo0C%a^Y6jVx_wgirFuCQ9Th?O}MwVKM z9<*5Wd+V{~RmF$Rs5RyT0Bd ziE!;5w-wl}(Krgf;k}%ESpv$7GBh(;PD&(2<%ZPWNU(p&;O_jS2KdX>Y$TGoC5>A9EY6sUxfp)&>XJv?7HKWqZ-S zpURcT5KzF2S5{=3k58{oP7WdY9l1o7m_J0-@(;**sl7xj8)1XQBA(DJy_)r0{}G>& zd69FiYSIVp1)nf9U4cq$Oj^9r8Ml~%1W9m=yeGmDMroBUD$q{Q!T@3CfM??3q>;0( zW7;q~syn_L5<{4KQgKsn1{UdI@jZ!{**H=#FljPzj^$=(`W)-yab?(|yx@pwFAU?* zqNc_L9Wyr=Zo}iN#Jt9#wPh=Wy#9l?9>h_o zDJclFmbT+^1V{Bxe?fLTHlp~$$3K*FYmM{-M8&F!?xQzKokre#d)g743q?M+?zs7% zyeRkjYVkSJx5FJzGcns!x|3^I6JjPbbtj2%r4mZ*K_hO&{xlnl3bs!vL^L}$Gjv> z^4p2&A%zMYuii_{hed~H`(N7EwKSZvr{2@#S(d+FV}Gh=Q0IqMR_y3*seapmhtsA` z8CFv4TxzjskW%`P82%cl7rrBcZZYe9S8a^HF%Y2Qt} zZbuh=*SjybAAWSKmsLKU{D(9-oyu5ND<;mruTVf>FOs{o(XYWZFQ{@1#BU`3+CjHT zmD^aafpo_5eA*ok_8+o=wT#R5#fMgy;3?W-dL5Sc*JEwu@{Ry`o8qq3XnXqf4_ZKz zHkGHmnoYgB?ciOcv{=6!t4XqGZ6M*KpH_0M^)Dh^OO$-jv%4AE*1~uz(Et5Hu;sxh zl(Guef)73WODnME3fb8zHQ%BWSbL4+Y?GF6C1P3mclc!Ei~=WV1CtwGNGEP6NtD z^AWIR)Dk}cl{?iB*ANIb4C6rO-&-)z)N{vJ;6|_-Ws?ls6`5-s43g-|pUV|X)zs@# zJ_G;{a^*%4ax4Qa%wWi0K z^d8Odj7dMj{q>m_$));@AF)Md2!yN<`^D@TPy^gAPG*ZXm*;I;&*<6j!ji=qnyL)~ zn1FV%KSL@lr?9FU1uD-4=NRh*PF!k{^mE=`tCrEz^ZUSP3lb3b2^*0DD=-_8rXjCC zfY7a9Jg!zo_+bjUMu!<*mb};5_p3Nr^|;Qvz4AtZ4_%lCKF`N$g1X;wY<6ET&se}5 z)^l}-%#LuUa(_fUx!u%7oIj(SrPGakbEMc**u^)JW7~MF7uR; zW4)!#h!9yzB`MpU$YUriZsg|ZYRbwo*cA;|J&WkBVLc3HvStxu{2rVwCOB%2gQWtW zX>T}A6v3lC>O?(~j=8GtB5wJ-J`oUQd(IcRh2`LgTx!5j&?4Hlh$ZJIA^LoDp#9TkYzvhe=gSjYfyr#(J>g>Zc*t=>8< z=*16guk4ZJ@#k}VZLd>oqsR{W*@c{X+3$@uYZ*gl#2cJ*lB z&a=76&8m{?{oQ(tE=j=bLh>NGVeLS`f-ljxm0hQy<}sbE?xw1^H@R;8*&$*&qWF+A6!j;A09&U9x_sBVCuMYarf_kHqfXEqi(+L$s4Xhr1OTv~M?E zw12Y|hlS&l0)NMg-WPPAT~6!mC^Bi^CP{SlY6xjpIM#LcKn5B+Sh9RuLUed zrvKCo{C{2jXJTUg-$z1P$)l*D-2|L(($gC;zYx#1Zx?k72k(~z;sY)aARuBWD}$tr zg_Gw4W5o=Mvw{d10J20<@w%>o3+tdKrVpz`V?hK6HwP9Hi6-JJj#g8x=HkxA|K(EO zpj7%iRoz{4>wWYon@eGE1Q#Vux^I9!K%bU*ikSSHTu)EL?(A7UVcckEPEsSCc~&_) zP-(!}9T3vUU~g@)mQDo_Cn;H{`)UCOXPKg;5fj zQEfnoL7HfABCX$Rnr;R22$m9+`4E!C>xD*VzD)F)IeR1|b{ zcEG;v5LP5on*u&zbja9WY}u*Z4XC^MHF!=#$OF7BY44Vn4Ixazh4} z{U=*7`-MZtNtI)a%g(v?1O`eiB#uy{LD4~%;f%1oxZ{trg^PXta7>^XzP7_FZkM$ z1RV(6eXniMFx+2rmisznZ?oc*@6>W<{Z`t81@#aodO#zpd4Py`bwIH2kYLL6AW;TE z-gan?&P(kmU0mFjJ{B;2hkZKOpl!=51n=~+qRH&bIt`=HxS!jh;f>5>nO@3$wr!9p*9!AWRmLY&p-M1Gs z*Dc5vkHE-ILY5R`X7Uq5$`}Sz4#B|_4z769H!Z=E66FW>5i}7k;I<_m>&&n1bFO%N zP6C^1s5h8OoJ8&erBQnGZ@yzg12`wk166wv0~Xs#sb#j)RA`e_8scGwQ8{f`tPj_C zU+!y)=nT7lTIR-kT|qj7Lf&!U*P!h^WJ}+fw zaBSC6aPo_=i}di|khHC^O+rtB%+s0(*9p_t-39eUH9f0~YiihNdH<$p33Nl%c;Dt_ z)ow5NPtQj%CSxARqwSz9b*Yr^aZ9oWgPPl0i-C{}Y%Bm9eX^-@zd((~xesZv(Y5}u zv#{aGO>8`>5f9p4gk5#`%IVa2gxw?@8f@LZ`slp5!MWG!*qICeG5<5!=Y764@F+GS z85pW~+ds@kr-SkYf-~850%zf;##PiprV@*WryC!)s=o>NEc5^>+;~S|F(CdzK_glf zAz}uU(5j8whNMrDTT@I%0Ec@QH?bGPmY|i*G^ZuZlAw8yH&Qi5tnSZR5#b50N6$phV$P|3@I z52+T}o;ak0pZwwnx8yc>!f1dsAc4vx3DxYB6x+{@h~{vo=;O0uYhb4`WY*Rk#`|ux zKyWXwpdu;~ifn>uqw<(f9LK8@oJ;8Gh|$Z9ItD!;j5j(&4RqLRWo?IqJ-hY|;+xrb z1@QV+7o5A&Q1+zBjGWRO_(LHh5Bf>dju*L~JaWQp*vQ2r1^b%+H*m%IIUY3Zy2@tJ z;2Z;_-tvKhNObPTbBeyN9 zrQRC-EK9gT!;b1CP}0ov^X8|cNn2h;C|Ofc)j{4!sWBga9shg}V9Q_|LiNza6Rd0%eo9276&~td%iUeg3k0?0AK{ctzyqEf9pzRZm8oeMG__ZAH$)`5yjxQ$| z_dTjG`;RA{56ISlfxf0`Jx_sqR|Q?tP|xN9;D&#q^+M7*>C`?Ld50~AAC@5g;PtJN z$TSXSjAuobnCTGP-iIH(4zy7MqCFFa#}~kINgQaqaRliI$8E9=vIY8k`44%t-NIKc zt;v06PKdbeA1TRHqd91|_)mw{F_U z`_bMw-Gfr-*iGeomYRZrmnqhOQV7j0;MHg7K9jI}8Aoq#%U@!wM)ALdM}UG~+yRFx z1!en}rOcxN_|<<(mQ6GZy&*gmDtVrxc1F;G@Z`#oEmpA2z~4wh<@O@Wsmlc_-J{3` zC|wZ)N!>%5ZlGNCL4XKw1^??Yj%8MDIhsBseq-}tFleC37(oW+&#Nv`WV{snomzQO zjDiaS|1Igc2r8^BWXHedJvYk2z+?F=eeHKmiGP#tMZ^Ao*t_zur-`kPA|eQ`fEO>w zE1-e}(sWG`khbaGbYJ7eYnrBQ+9XYzv`vB+6$Ax0l+6VN1O?nsL9XJ8fCvbpqT+&p zAm9cnC@v`9wB>~tE_$!ubN{@39$wn%%r7%%&YU^t%sJB*@A&h~fkPuNu`t~$UC$Ul zb5Q#q+E?GdzUSJ3{n5ahchlLP%g=T%PIn__cEaMWZtL$|UcGDodyDadH(GYm2@>32(zP{p6?<*O%51#ZouAX=5-=h2ZUmKf2=TC*JIQb-xu|g**L^+55b^L^%iQ^z4TBy|JYqxRoCt-B2BH>UF~x zzy`-v_bxiW>&AI=rdi2NuM~T!uh4Gr?kM?8m#hDB%T1kE`?g$pTDWUUH}T0d_rcoL zQy-YaU(oB9(PwYodWUvW=V!5f(Rja3@#wfWTfXVqenr370r$Br@4i2BsQBT-y)GiZ zUtqs(P`Ss|Uq7XnK|SW=Z;>3-WYQ*8yWuj z>R*35f7@04(7UJ!*rSVo{AcG6TW&T?d-3}v^XHBFVcr!F9k_DCBi9jMKY!NN1>H70 zx$Emb?@!&oMp(LFReaBs!<{Q1|Lx45J3xQ?rR&NA$yW~E{%Gf4?>entnzxr9>%Yi! z-*p{-UAo=SgX1?z^WyL2$&i|Svx{s6Jm+w9hR;eG{Gb<9DPNeEx!PO^v(v`dae2U&n{y`imA%L7(gX@z>k= zmzIxnkOWf)% zM%YgOhVI?Dc%bF79+L-PXI_5=Gxz%+AK3EhjK9D8ey?qBUiVV@o|}iv*Nq=PpSQ?OmU- z!l%s`ck1q8_oO?||M{K2-8km4eQ%$2#tXY2dCfKP_2Mj}r^~b+@BG*UnX}gN-ABwr zTZXN~&0T*B%%ksk^S$YhZ3^liYPW*s-uq$9wvLZ3|EN;z*tyfdpIwX+=R9}ayeHmEKhiyqRUXFQ z*?Dob`pNA#R=%^{5ISc8a>k1LU%PMZhH;~Z`j>wGH1_HlJs-z-G-L|?Wy;`ByKJU! zjSLw)06#ao>`DI_{g4m%i#xvX(_7|_-n+IJrfwg7+uG-BOJ800_~Wzgy=wf`?*=GNDrzGdR23%=>UrrR2)%lmAX^S8Ah@MdWIv_bDY zI^(kB!=tt>EOonQ?>&At`u4S_Uv~b1-ha1kjNaH~ZD#F0b$jru@(;eYspsUi-b-e` z>b`X)bobUyl6Az7#EAA+Z~D;IzRM+(_rTdykKXfVzwzSr_qe`E`jO$`8(_72@HZcI z8!&qVYfqoIE!AiG;%+V1!H3U`e=2bMO1(Q5hg~$`x4)iw!;HxC^($M3+LoVr&dR_O zv-(zq>&{fS+xm6kz{$+6Hb3F{ADdko1AH`8&^htAfLuY?bR;16Dcv((kLMkOrd>TC zH*@IX75#qr=nLciMfc7c{@B*hKfUZf_p9H=L~g!e;+>^$GrJFsUHjl02W~xY{It#! zruW!2bmZG_pX0svde@n~JM?SczF&vcQxDCHjNi8Q)4Mi(oa*rA3p)=zIQGzkAb7Xi z@D3eT&+Ik6W%9sPoy`kZEwoWB!6$E+Fkpf-FZ1xcUHu>G@zDGp1E1|S?b7V-OM6_F zP49YW*Fa?1mp7~*IQH)FY1)n}t{VBu^2u**T=UASufN{E|NK=4Uj#qY^V5SDY~DNO zj?Ay?UwQ4|+#RE@Sa-+mE3O;5`NuKuw)^1a{8@(|C3dt2(d>?`Qfhj8o`}bP>m^OA%8_=Xbxa#wDo9ufI*ZCE-q69)td$NXL^Yg z#nhiu|Hau*qZ>ktq47ROQ#Gm_C{r1#OmQS73>yZaw7@fjj26iVEizOK=m#|dyy~Ma zrt+P&hBm)k`}=Xa27TK+-Yy%z^q+T1yLR7PIUni(PO(4IUA5?$CDWE&ecyA>e3*ay zedYG2KYaS}T|Wm{(=9s&-`x4;r@XdvyYD^gEM)J_%4*Li(tt%fF50!v|Kr#D`fMwF zb@dZB{-g;P=IuFqgl@-k3(U%o|9C0lu?^Jr`eoUL3isiK4^(HxhYtPh8`yO1)a{o) zuyT>@@ITsrxTrE~R{8!|zstJwqi<8$7EZhEn_oI??LAzveKu?kzhwWg87i6G9_&{g zb=!eR-lQA&)9#n&TOn-d^WAR0z4Meer*Eu$cmKK18$KJl;@f9N#&-K|edntuw7+fH z);n^=^F5#V>elO~tY9_IMo<6ebLZ^{El8fKzr1&E%>vu02KSsxAOG@iEmtfK|KOe0b5>neXp;@V*`Qy!_HfySBYEalN(OfFIc_2QBRre5IrIxobOZb^G0~D4jN| zzx@1`3kLo4^qVu@nk=9H^sm}csQ1Ugx6fa`XZOw_OYAr2mbQ$?Z`~Z7KKGd?7GE-y z==5U1G<0G4n)`d*X9t|@!oF_tlj>@;ZwV` z8+Pgz!%0@K;r}BVjmEYPsar!H@A<)Q_iuk^^{XRwcjo^3(LYyy1l? z`H_)*-}cS_+Ii1FZTn7dZ+>cIr}O3=8r$vifwRsL=L|Zu61A!?z7)NA;-{9|xR0L{ z^y3zPi>dBR=^oqr!svabgC7eWS3j*$_gZ~+bkq_Yiu9QN+(*n=Gw#$qKWz1u@fXd& zuNd@KzUSU`v%dHU|9I$(!K?T0T>0Bev-+HU&4o9vDnB`FP@gNtUir%3muL?BRGtfW z_b%iIb$1VDX5T;e#Sy3UnCu`HzLmRti2h#h#&^%^(5J)Kw_omDvTXKv_AI35y`SFF zvPLs({h7KQ;~%^1gUEZ{lJ4{L>{Sl^+_SG-vbaCi>1*5PpIv_X@*86}gl@QT(f#vX zW8$~GJMn?_zU@~I8n|skdHk&TALb^hEa$&|SKmG9k2l`XLhrx)P`81+Yc}p5o&*^S z9d3+TJxQpMH0A=9=KJGq1ZdI9YXgGV|TEaiOyk6QMzu?%k64 z^ygPl-LQrCOylIsml0%5 zlryNVvkzUO-}=|~yPp4az}iKgZF5eoK6MAX`0s~TeDcuKyVtJ!E;6ReCVTO<*fVec z#d%=;0qFC7?LQcG8{?nr8z?`K{Ce~YPtKmT?8++*hc6xT=|rxoGaNkd;a5GcVsF}7 z;5XHblUA9g8Q+_F_Pt*OHhyx;&eKw_j5z1s#Cz^pFO6NleSdC94ef)e%SYS+|&8uQ`WmbU7kvz-X~1YzIf>~E6}aQ^WVR7;-^a|uDnJXKu^a$ zX!q`&0jxjveKuM_Mm_UF|E-QkzI<@`ocD40eDvqVR}I`7n=*R(rsqCy>7(BK<*Qvg z;GTD`prS&o%lVhjKd1eSxxMEuTJm;He6sk;TNl5#P%OR$%{~Xxhjty5JkXpjBYxpQJ<^6=uymM#-&W5%z3 zbm%$d=LVp3s2cO`QpPbo%7(ML$4XWR9=6}PtT3sJM*?zwyyc| zqJCZ8>-p*j(7baw1n>CZ>15^O#e=_ab=c9QxIK!UF>Kv$`SI_I5jqI!G=E6tn zZmakG)Xnld6YwmZvJu@pDITpEq%1_%ge4#ubI;Q(_N2#|KuG@7O6k*VJ}vP zcRBrvL`QP?@ZVm3`M?7s-?EJ=Kh^%0rISCq{Ix6ljJam&eE2ub-+%eC+@bc=Kp z|Lr@sA$wP9R$Z{B|0Bs!Q#&MX|HAUfq<7(63qLtkIE>w$+Vt?|QMW?(bvRJ@wddnY zPSN$dxYMxhZ$6y6=&sLY>7pSU0(*Y(e9=*tke1K<>C9bkZlt%RKYi&=SMh`I-~HwM zjq6j_X4y3ZhW9#ar}~l))4Ifv`@PN;8-<=%R~8LgG(7s^=jcV1CuW~_Da1a}J-_SP zM-Lialg2)9>seDLJrLe|8#8d>?3Ow0DAk3Num9oG+s0gexB8XG4Qoa|(V@8Q7xmB2 zw(L&}XMf)F!*51CA))@|b58rm6X(8l!40={z3-|{(B02Y{lS0fy_j}Qw8xGQJ=>@6 zduWxb)5AYbFR^H5-iC)yTl7aJpZNq3%4x$M7&_!55^rIoO^f* zY_Y$7M$e1;rEk1-^5M>!i9i2SKj7f(5zo%pUtdO7mVbQyWQEV6jdQ6S+Rw_q3l`<7p zd=XM9kfwCsD@Sx5CJmKXo&`#2i^MXVFjN}emjDVNH59zB7ejqp8db!?@V@5y7cC%W zy#@T<3e}$E8#75Tq0Ghh{OB#tv~4K>&UoR{^)}^VMt?)L&zcvNdynUL)6gkG;+Au>>oGG zLNuF&j&=+@cNie)P-~eY#9}#8EHWdSgmW=WMG(vN(iUr2KLj2IomlZ$$B$u9C?QfK z0AY25)qtwn2#gGc^+VN&O06HNRks0Y);s|N*dlaB{!cL4)I1U6h|%&Np|q`g0!}1X zVN)DIGeUzGj!sd7Da?#`d}*DM^;u=;#^mxuS)l5M(eS<@N+?#!B-NJa$G`wl>$5hr zMyJKx2#wy*AW@s5W4-#xW|?A{CBzZ#fX#92X-5kGs2$A$(`^J~ z%0oJ{IT$YB?oifjF=uV&u-W1=n^DLZGz(Eju9|k36vAPuxlpWvna#Rjf$^DDYIEad zF@yT`m(6@>KgoQBIaqHDUO}@3Qt8ZS!Cpvd+>F@~X%w3?P|EBAUuJ_gi#ckuWTSRV zw&1V?lWuD*>#$_AUesLlSZhU30}!>CG1OeE{|lmKUBG5W{HO(s*e$_`O{%3Fl0Z5o zBy;p%&E~Y!NFQoeC&3evj$AZk4;35VHvo@TY}@ERd=DXDpusE{w9Ra;*+R`Bn_VGu z5DS5!*~~;^^iFeqbU{$*=qqS9*IW)j7N^x*0K)^{WnJir^_qY|vlWaM(1mnagGDc> zY6TBK&Do$8lmUtWAPxhQg@r&@?5>bY3dU>>o5n_yNm~@-9XX2>mx6S_(g2K#&Kw5J z6vP^mvsD`tR6>zL$s;GV0jn<>)F@xHE#PD=wG2h`Ft~ES_@%(v`yMnCOdn zEM-{-1#AsK*dI~jiMX91;;@uXFs3-J$?*g$3aPlhn$(8iG?&&<3Er4-!m5ncZ_6bK zC+%WAv`+Triz;hDAC56Rm1OY-U@679H58}!v_k zG@B#BQ8`X0jb5uo8wmR-w=FBBqlH?wF=Tfhw>#)`A#IOpk&<7j$yvSus8$7(oI6|) zu}D-O2r=noJjSOIc9=@QAqHpDMIz3ZQx3S2()_#OHvm;AerT$ngyyf0BcMIs*nnqASzTK4rMB`BgiX+Ds9vhO?c8_ z_ZebQSd|V3YD!X9(eRK&dNDlA#W;OgEmPV0H1bgx4_CDfK%*1EG?Z72*u5;F@+Prt zgs>V!z80}~3PookTO&9v&eddzGr29exx_}oCr(D|+%y2&&QkM>s54`bcvIG5!WpYT z(PlfV(xov;P?aTJwFIbQPF70^E*z6%qT6CE64|6Dp3Fndm4f=*B}(IV5*EJXkLA-! zNmTqbBAl#fRC;r{YH|<>cZm<{S&bkEBN0CZ>F~TGl+*}bfl^svqMVJDn_X%25O9(< zVUO30Xf-FsWX11S*}|TpK?BG2*`(;iqNx;Vj%ieRjB}Rwklw)t3vwV*^$Q5@s<1W# z6>!p8Z8i#_4M3m7t28)jfT9}IBhxjQi!mViFVW({mrWV5n?j^-;=IULTig(O#IG2CvI zdD$cWPS5Od180xb3Jt(y8VT4+m>>q(EQ6Nak_!)`L1!_;un}63>69gmMlhcP(UyWP zqanh@O4gt!7>aZ8Y>_m8!-sMj%ZZhI!Ki5fMuUnJk?63yX7H(#cr_UT64aNgSQ2{o z@k{?Gag6q;x8&zFV$O==fYUw2Qkc@FJk248O37qV>$Wfvs}D!ygk45T-T-2*ppvd= z*EoYFDN*JyLJ=KNIfxoEqz>UVk|wT8%i(xA3LEf}JK`o_TY+oz&|_@nqTlTg_(Ee1 zlBrmnt~f*4Anb8eBVL!{iUrb6MAG_-hHNBLp>+*FjJBugI?+6O(dX9Wybg+j#R9HY zs*!X|Fa>FhshGkQr9@=2P=t#bGT``)fW-kH&~nya5;vx!qcl zh?c_=2j2OUZm%8B#x$Oa6s!vYJ`HX_i2cEzl0NP-a#m{zH#7i4r2@>8ysMDU(_zAF zbfzj+0%r}8DCcz9Y(i1y4c?+k2pX7_1y)(3s7|LC9SpDpHI4#IlIoP95^==%9NX-n ze8R(nnxYm-Gei|r>0{woFdYth^q~@_lO&AJvK$z%q3lg3Fm>Lq*Q+(|qA%;O`ANJa zh8sO33v|kFq-BPPVUpWjB5UEeM{5SdOvS=d(O+@dORS00Ct#~SmI#Mk7B!m1;syt& z3TK?Y9Bstph}M#q5eRMoVp856giXbmo*)BJ3PTKP9aDh=HdK;1Uy;`tgnZhP2Rdk( zb=A_j-<7UlavOjR?u*GnkjScQ*%DhR5M?i+#W1>})5SEFlCMTdeq6)AZb`NXMyyWM z03YW=L=NXkm*4GITvXBJ3+S2xRugAnvl6sr^%x$v;cT!CQR9Gb>^7uqbUS!FZ#2h% z2(r4|fl#>SRh;EerJNNVYTA{o1gxS34m5h0bo!&lAj~KXyh)8IZRJx#7p{{gQmr>_LiAx)N7Pp~bBN-0~qfx{|SJI3% zCRvPHx0Ok2GjJw{IK51w8sQ_FK)%sKhDvyAF##;90;3HWAXG;M9960sXQ_-HMEJQ>l=FoMnI7kkLjU zwOop4p2ZFz3-Qc8ZB6Gd0EOcO>;vKn{hX6)us|H+rbIphC2DUK%qL z%@a9Q-W~D?FarD>7BUl~Yu13xSAs-u5H(S0wY>RHp6gGz9>UA)ZwloW*TVW z4L}o@(dJBALr|803TWq`s?!1{BdLaTG-k}BCbOwV7G2H+pm7@f6RJ9#HfVVyj&Y2~ zgy?*dLs9$PF(%VgI60Lr0kLkUp`c{ad9sQC&qP$4WHUINFErMFD?O43Q2}~aK8vMd zUSnQ{@CZVsWHcXVtkn#Z)aM#K#C;ZP0^^X3C7U!0NjM-U%p9-Edf9N*%LFZ@v?py- z!iKy+xym_RUKJo=SrTHLV613$Y}^{geDPd5p5Wo8fX(~RfZgxJY#9sh@-PLPUuxaU z;}Q)tpcoafV9sC`D;aGnm&=b=7{y^LqaHU^)G#$K4d*yVjR__ArhZ7~5`LY8`~7A{ zo0GHADpJ#GVM3b^+DJYQ5s2LY(IM7dMzj_iT1_gx0Or<|v}#kf5fnbs^rB*cnJ??;qG3smioX8c)aM=U7117l&nNeHb6vnF+Nfm_3P$?xu0)j!3 zZDqI`W7R4*7nNwbl+kjLbR|GzwREbv1t>W?UCkRcHa=QNBF2ashBx+`4G$BrFiFdjXyi~Mk_-a8XyTV*Lr>|C<26&2#`)#Bl9V1O1 z6-ud60gFZ~LCR`HGsP;wDw15LaQf zXw%K&Dp>^^3A{+L zP%IqK#gt-2BCAFv2Ngw)%gE#UN;TqZF1<+B7Y)h&tUaJ7ykJJWV!|ik5xq^oa@wSd zguRwFs!`ntKPvo@Bn#;Z6}*aTO}b24)s)znkntIEIAoM+8RSI4k0t^pb;jsbIg+es z$k=Th69!U0RMWIdeNLrMfUTDfsd%hOLv0drWnc*QY1}|#Na|4=1h^Ea14pKw%^FEn zL8Z%3Fiu6xF$0)+GF`Q{Nz)@0Er+8T>i_RlHShtG{<)VH*n%B5^ zHs>&G@b_Av~H3Ov4KI}0OSlYK-l{r>EAEj}!i*sBC^uMe2YQlucq6*VDxqNr0+ zVkSOm@!0s7OlQ<0Swj>Zg9d3X1I#oI_-I;%Y_Tb^BX}OALg5$>mWN3(>(jg*0Si5A zEZMk}NAHT`ZF^kzrbQJ*fROs8Yjy!r*UaGrrWK4Tq-if#ps*tj0`-CdWYXyXNr(&* za-^l4Dog47;0&P5sSIFW#(_R)gR2o;v4E5kRnF>nXsDdz5z0sb*m_{&#hOlx0PJQ} zMyDQCRaJaN!ctV74WoJRPC=ACns_@&?-^m`YM2xK!4O^STm*I9Xhi z3FKr6Du+}i24ziAI>U+?icM>68a?5J31333FGfp2OK`nKH9ou6B0zI@>YAQU`*m3UVl=;HhS2g?(eBI5amaq zyn};mA&yLDip~nkSj>bTssJbRzY?_pc#N`I4^T0%@P9y5j#N8SoSM_3Morl(C#}_p zKMFRV2B7XZM_CDYYO98*=y7mHl^3Fuic6g_8J#L2P>nc&h9Y`Yz#$K2-HdB1-hw_! zz+S*UdKiYJrUnaUk|y(|jIok1MIlnCMC5WDG@vBFLO?+wb&*&m9w32e23D`L;jshE z7(+4|0gHv=rJBQGCH-0e z-tP(LkWwqfqY0jLv(;h|(zDSFRdXZ^gwu|pO2n4pVZ9_UH1IOpP}rGPM93Ga>hwYd z7Mj8VEtvG)fXk=x6>y#v|KmOQWZQ3J$VZK@Ke-2=Z2N5h{+T@(un|opZJ3DU2{Iqi z+VVD=A2n+qHrTz1P89P*{#AZ9%05-jN^-C7q>oKp#d~ z*yxtXIGOQrd56)J@fUo!H&#-YoDf>~;^DcfO$B6TP@`|Uox$lw#(?Rg6~7=Kb&wq0 zQxS7rDOO>T402S^w~_HR^f+o4rlPcp1j4DSyzIfSvY&LyH6qVVx#u z6i74AvILiGIyk^BtiVJI6|!Yt#%-@;$`K_Ui`zUIR zS@tQZVoXE$N=9o%0-hgCqY`Tf8PfZNTuRpH@_1ZpF;EWD=LZV3^{Dgo$ZYJYS!bn?6N6VC<3XT26~d&npT48rhU@@ ztP(=m97Cf9;Bg20j5<~G+Y?dn*CXa|R2}5>W}P|~vxzBK33;hdMI~eDYDG>;k$}go z3ag_Uq3ZELBnd?ufblq*2mU9!Xn>J$0L36w6Dx3OtrPNjv81eM!zP!is4A;WrU>j0 z7y}N@QLSX0{<6AKKs+X+Sj{^MHJpisn|^GYC1wvt1ha*WM}mT&!BjYe`O2u%NANWU zgDbGZmeqJI3?DS>c}iVTyCh52!Y(lHzy zd>%RUk3ssT8FZouw#E%o5w4b^DL1C3bBvYC2K{-mqVp%IvYI4or5I$%dwje<;9?my zRP{Dp_fWO~>5EDtBRgrMK7*_HoGzGxYHmKGg1mX4X1D_?0?X)8DUDPGC|b=~imH&$ z3u*NvV04QcQbKviMR}`D7lDa0Fo?@jNEGrByDtOeBIDCUAU5xo!16@PUT_fN)deF~ z4I*kVyEQKt5Xuh>JeI?%PE9(WliiTBhFi_nrr#zP^s_i{?C^S*npcwE1Ru>N*`U)G z_fyFXCXn`0RK&|vROVd{rwgO9W?o8Zl}NgnF4C9>RIX(th2RxUvcWc%bRx=VJ#IW` z$3v1iUbLITlnF3yM8;7}lW@AluzYlO1=Qx@{Imv5_-d|N*(R`XfXq_PDl4g}=AnO{ zNfZ>?$um`}V6Qr@6@%m{nYmgts)!_MakyxImMmJLG9g5O0Z19cnK%<=P+QFBGuR0( zV?@+WLdCfQjwWO4dD)UxmkK_0AmUFJ9Jx0A(Rk|I=5iEe*k>_B(is!p*3}Z!S0gDu zVT%`>QW;8@o93+(DJr6XNi`H`ydFz1E`}wiI+IVB%9TJ0OT@ztjnNU2Mc{Ms0D;)> zxs>Io>@@?=32MTfQMIvQNVuAY59EjHE?0^YQOFDqYm5>XBT336d(#Fr5K&brQ*{KK z&T3p+ukwc<8O5N}Bf61U(&)a0QWfGAGmlo}(6QZ&PeWS6<$ReK_suvn-U{Tf_4OQx&WJl zohe5UPN1p)4Ldz?Ob%B)A;s);@)4~PmJ2x900c)lAOxXq!!`cI!a$gT`EiG=f&t+O z${=UrY&2)F+3o2PQ*r_)74R76BL!zZKx%ch*5fJEkZUrw)hO^~(&z{|tX$1)w=n*U zT~|PzRjbvDDv6lrWkjArOR=Oop7U^(464T^wxpJ_1kmJ#qMGq~f@IC=0Eg0z9=0mz zv2s{X!3g>iWs_Ld3mO{*3t4;2 zY0SVv^E}1oVMvNdsWN#bPdgo=$5MfmluPedBZW%Rse#H-y|tio5E^j2BypvTN>vP~EI^FuL5NoakjZ$pA(hrds9eAjC4JFk zDpWUH&2{fEjN43QJfc2=Q4D7kv}CIl5i+PP3l0P51Td8pSOs)F;GJ#&+AVCvsm5H%qY<`ExN1!@{r@zXlJ)h_4Ic&lO?G_amT64-(b zKS@u?yxJCq!|xhbX!>_a)JVX z#G!s{pFiol#w<&*Xg(;^>>gN-h6sU01cS>22dqdTmLkc#OY7BV)2L2gsVHe1E?ZnC zZ_4TuRQY_^?@IzVOvn<7Ig_Yg$Ty=*Lw2;Fw;GRnEP;NLqco&Xo2ptoo*ak=*4b!= zEGfxcfle|O;2!poY7dxH#$wIIbPQn^Yed?U_XnFgc7^u)LnIX?!k#czlAJkKU>vN7 z7mo8qw2F`uto^nhORDB3g$XrBIPZWX+Mvl=sOWWI-;Gs51fK%Vj(AqV4c?H`?eZ0p z8k1G6s%1fpqnENpV-#;Ja3tri)RHb8*r5}yrugD*IN9o7Yo# zvN?>#t01T##MMHwR4ls0tfN9W1B5IyIfvb8D@)}H8f;8TDuv6esE!J_Ppw0W>Ox)S zalFWu>m!fI*5eK^kFeD-34iQe9BCd{CwNEPWk?gaDOo6OWPA7|u+2xe{AYz<=jhTSIY2G#{pmw^OxT{06HPbG$v7?~{vMT=eV!3x+|EC!)@;zN7YU{h1uQ4rOJ`boHo z3q`FfRui!z2Et$1P(IE|E{zgWq=L_Fb-IdVnUA;CWm_qKGB2@U)e}$g4r@o*2=@92AnSX2G#-7LY6u4wTgSqEw8LbS?p$4OLj-(jmUd z*yaM2A=Pp|91oyDE(4CEv#bxZd)Od|`aAKo{fLYZ)j$H+Vw5Uk0|%>N6Sz@?wE7}V zONwC}G9uDcHGwG+A_3Gz0}$pKB>*h1bUCFabUL}dTSKIK>cnymsXn!^1HhZdJ2d{!vjTu1OrcV(;8H&2HU{JdAY~&2xEAL5SS+4Xsd$A-R%DN=6d|yb ztC(~ZW4uEQ*h~tm%b9^`U$jDQ&+jbh2H?rq%Lc*_$z&;;s)ouQy}5)sLTZmwGUXFk z!duiu5Y|oGm`cVS3421$biPPf3P^@*MwzmLoX#g?#>5%p7Re3b!$YQM5Y7imS+rD4 zlo1*xVNF6vc>Hl-EC#5W-^C|<`V>sLj2c0q43dz6V~Q1=Xf=As<{{Lp2dNJrN)}`y z(B-&Lb5$XW}YlUhgK(#6VcWG`SojI0JcU+!Z{hMZ@TPt=wzp7q3)KyPHiZ`;Q48~#5iDk!z z+opOmqj$vd^^X*u*uX-ILI4DH6D-eAZJyqm;1#Ay$CtK#!O$a+lN0y9QKN}`{KJoo z{`Y#^B!IQZ@?}a8K-%F5{gD=J%T64BAXgNNAepjElP*rA%Am1G)RPuRXpXf0{Te4? z`O7o~k|7(dK>}f8uG*HJSied1I{5>%L@^_@N7|fNeqy@-LvRGhIpH#NwgPe%>%DD# z-pRf@v3;VRqsLU5?KFBsV}ikt(Loxu$q4IPhuyZ)i2%v}1fXrD69JC3k8(7~=sPm- z6N-hT{v`03G?lNeD4opi>MLDHEIk@_E5!MDhqb z!3fmR*1uEfkI?+px=5ut@pqw))%aH&Ak0LnaYs{|!L@EL$8QdxwDk+HGg)PV`?s4D z28aX1^}nr`q!^}HJ9)Kc>G54TO0Sc4zjbcHH9{nFj&iZWpDg40c*x^M_a8Fnkv8?! zFf?0#Or4M;P%1-I7_p`K_?E`=8y#+2>DWv(LF$w}hErdIBbvGGM;bLsPHgo5AlS)h z(u8TFX0@`ypH;uW05I&2bdW>DqyT*_aPi1ABGJ@ zsWM%q()MzZ{oPrFS_jysS&^*NwHjn%V zzdXiC3*fc}xec}I1gmTN|FyLvh+yJ}5{;YWMhFC$xw<@VQ+BLV;MvU=km2sHnex@kA4SnGPSYu=E5z2>cM-@sOI zhcE*?gb=vXN2E}StY0L2;Yh-lf{P=~l+G&kH-s~7Y_sf;qo^ji- zmJZ2L!+Q*F+0x;bv9o7iJkojTnvu?H&QoviK6ysv`LWS6{vt>EE|~wqJpQz+`h4{B zV`I-=dC{X>?fv|gueryUj_z3eVdnkYu6*YC?3)k#MDE&f@Yk329sK1V2e0n5Yxg); z|GR#A>b@O2NaN|Y{F(pkzj%9+ST<;s4!7#n{OyRcFEmu-Hr9wkowH4y!P0A?n!S@vTv>de(Q8Y{E%AX%5+_gf4zLsO(fR$ z4g4DF#aB)nx8+rO(3PHv@mtpY?V0bdi^v@g(a38#;!M-@vwK{TvyAQejB8#0TPDB% z^QyljZ<{vjRAtAa>6!EA6DhBBGn zg$qBK`O4zyhue4mqQeWmyNJHG*)x}~d-djM;-$&&PB?V!gu74MKjRurC&TIsrjVPV zU!NQ~u*cq;Y_6wj{Gc@#c)nl$>MC<;%;uqk&K9omeRWrQ`i)b1O`f^`o-fJop4-} z`E28iy{CQq!7d9sUHty9m+u^xyL^HE(3ITI-c9X(+0tX-8DGxqa`E=Dw)JlfxWlq) z+F$P+J7@nZ)6RbWL;slmzkabsePG;~3mwxJy?t5k-7N=}Q!`#@LE0H72PWn3?DqOF zB2c@fSH}Oy+X(~q!J}6We|xLZvhKzo<=!m^4z7CQ`KjuB#|3A(zPWZ|wO#S6FBTN< zdj7AE)1B|=a%gR=+p{y4w!7yQ>+m(_zxC65U#u#xJcrkJS-uZDaO)=zwOk~hPpmUA z7Vm{yY=1Msn=1I2V#{`8&!szO-al#68RIVOFgvg?dPc{m&$L`2KlJiHe|_vwzF75+ zy}I|zM+cmGHn!!V7iS*0ap5Iamu>MCOB0WERLXnq5HmA^8+Lsrd^F_qS+6*e3(iw- zd+Cc^6MU;a+t6?KO$)F3_Wc>BKe6>G@%aS<&K`2{oPC#GoasIC{o!vRuWlcm>-4wI zGunOonWyjIQ=Z{ZJBUXvd*d?4<}uSk^F84oKDR&YH5(88_RfM^roj6@Zdv!+DKqbR zWaJAQC*9X+>b{=o_|(nOX=h4z?>)U!rNeEGg}1+F-rZ^0!oS|s0X=x1&w5HU5WDBa zn>KtfZvQs*pv!`tzwP$kr%w+hUTnE|&ULG|-ShmW{Ttuhc=?4}c20ci-lY$owsvku z*Ch`Hr|Hh_)9%L~w(dQ=e^J4Hr+@LOk54dsw{yF-J$YGm0%UwTXSn~%+SDJvedC9R zPWfWz&0VfqM~{EKILG(SF6iC!yBlxZvEtJ4KQAK>_3ZG@Uh|=w-r7H5 zC$VhB$9Ha7hJ7*N_F>7RGieaU>OP@ieeU}*Nrc3ko%>Jg`>n(RbHokrTpQm5;TV%)O?m4lskq16{cEtY8 z9opaj>rHo!?wefymz8tGolEZT{oqZTdsyF`a5&>p$Vt5(nlo}q=Yc^(mvg&6a`nhJ zwp@puGXI80Z(DuoSsOp8zI^^c&w=Hiz9vk)=9JwZopsy0?{Eih>}V|D>+Txx*5>@( zokpaihp0#B4me`2$xCQN3Z4kOGS)Na~U$`p#%PFr1=8wF2 zm2uNY7cL4~3_mW}QpwIr>@=Oty}x9}rNIZ7bBeVWqMu*Lw}t*^Yo|s z9e!Z$C#5q+os)j~`unzTcxlC9-n}I^x#RHB-+VHB!`e}iZ}*nx-r3`z=d7~^Zz~Jy zdM{eGNap7*U3IQszV({IJ^h~kV%oAj<1X27$H2Qg58a~f(S6(F(|_&$S>&F%L-&q? z_Agsw;xC~4e)sAAX)}Y5tP6ec{_8ucy)O)%fqyf5;pcBwmi%>gcJwMzANwe@Y}$9< zTr)Z;Pu+7r@0ckaT-Uwt?#jOS(mTShUUki<8@HFBdz9-V7xfEuw)gsa_r!1W@y`uw zSKRRI)058FS5gV%p819CbMpm#&%EZv-S8)_SCs9eKMr>|&;9ix?~BMidn)?-F54S< zX7hW&J%dJWJu`^By&wJP&bL>Z$0K9cfBMt+8=l(O^}RlW^1qBd?=LO=<Kmy4rr9H(?X_@nj}CJ#x!HQ*U#>rOw*A^uiFTXb9`NuaGFzK78M}Kwtxm~+=T)oO9o^t2vN-xum^LO5~e#4Zl2Nqs% zane2F-j`=ghsR?7$JsjtXBI}=qH)r(txm_bZQHhO+qP}nwv&!+bZq=d{v>^R?|be& z`&8{yx9YsChqb<1wZ?iHbIvixU`$#_g?p^7uD*WUjrY65qDHK7eziHZJj|A4oFzr2%OUBx4X18H!x4l`r6jNx9`*qhIItZ09 z7C6_)30}mQI9w`Kc!9hn+mKm9!e*8E(JL^MauKu1O!h200+*t~Auqp*6_+S7Hvf3r#}rGu2e09* zjhun;9#l7`y9TlymR^8R#KB`s!n*M@#SedV-GyPpGEpm&c?qPih-=2}@RW%GPGbtW z=yBx>^hhfZO~w77py79}1bP(akYC0PLpT3LHX58t6HKr*NC9#NP22Oh#~R@?Se(vWGBvA&8fbFTH8H~O_l^@*y{Iki z&K)Pqt0`z-{XcuERgOq8(lJXwm%!VTy7r<;ojC@X$~H*|1;{IU!!zJKLZ>n5!@JGr zlL~Zv#Fj-37r3~@4`T&f;#XnN!HRpw(Rw-Ayc#mJ-x0ZS{e-&%36wK2!WbVLire{y8q6>`Fdr+yXTWahD+)T9JE13xs(GoX2CNgc_&S+CQM}Vq z3{)3Y1#M^FaQnja3Hn+2R;g#_FHe!=-g}SX3c}fs-aOWi+}?H_*bCJF^97xL@u0|r z*MB@gI`oWlf)5#-vOsiIa?*4oQv@j+cBaVgf3pvStRHm@XakmO_qkl6x8Q`?9VReT z;QgT$XsyBJA2i3ZYQkc+)qfUHxtB;LLkN zg!5-7`h!S<@v_5eDPXLUA$r_ZPt>AMNFhWe7_qF~5vbgC|#Jl$ds2z84R50%7+wq)YTbLDzp4 z4y=z~0z2O-6+O}HiGL<(a%)`We%u+F9XWL78zwAn-Dw@=F$Imu)gy;(4ei##z6-qL=$O@l85QxW&3BSHB<*_pDX?;n+!U+Yn zHi@FWM57>5!wH;0NQXbUNJ~4re3cCyBnn8%i|4y!`g%vvfsD`;a|Of3@IoIk4XROh zHJ^9fg;HS4GQ0Uuu*@$h{a!Bcz4cP*h0cHltuuOOHBW<}J|W499j$q=R`;Zk#|->g z*B1o+OWaYE))+qngl(C4yOKROI1+*P84X^`zF%kyzD%xq`uOjdr8#O^I~%76<0o>( zk4(KkM_5CVm?!M4>6RrK3+-oTnKBZt%swE+?DujX*MGoyjg+Cd4D@9K#7R#z?#`69 zw%-Z^2~^#tn}6nmKr&0&Kf%F_d3U+MGt0>u5I)87gievF2ZMEWQo<_D=6X!(&UWFQ z-`MAbxdL2qc1JTyT#3ePzkI#W6oA3WNtBW9UKA_~IzuJTE;%VJ)yXoG#~nBu*M&>8 zGa;U^Cmb?=E97sLB6a_2RQ%Ks!wowvyf@3ko}fJ{WV_=VY2vi^BQaT8=amzzK|YJH zIM*PRH^jf{?v7nq*?NkN+Plr~<6TdS?_j|L#bDuUe6}oWqrws=m9>{re_qtby>@W; zJi--iA_lfV+x^rwuFw`iM^(df~4C1Ah2D1=IX zZbo>m_OxU%`kni@W`wM*fiy{%r6W^^$?r>Q&4dyNAC>R{*>AE=zB46uDesOmhJKx{ za`kjl5UnPsdA4Niny_Kdh3>5sHz_U!u{8T1ZNJk5=$t^JmRIh6rS<e0c+dZRthN*xVG;NU@mleg>U`%;9 z*vYi{pzXqfz;~Va=WozsCW`Y5;#w)LO$&zXs5rXL^a1*jDz4<#+;`W_Yygs*?xV>) zc^nlKd%cz5ZmUG)Qk8qvzL$?4x^KQ(I~8%OaK`xh&XE2AaEScA`{2UdV3w{7?q^or>VTh49TzuEvuR&2>&MQS)%f*)(a2xqenQR`%6j-&9E^ z9@xHgP+3299w>h|`bM>6xPtcrrSmT@QwdK5D+jMsky!@8T4Vv0M ziN1PbpWBRfV=?uC(T{lEnBB|0v^iefBoE@<231$INlUQ3;)hK)5yYv)edP!~AS+0j zE%#?_?X}&#T5iAmE)aY*A2q))ID=2g-Ni(|bIEsATj$o6};@9QQg>3ump~ z|C{hk;9r2sznG+p|E6`p@n2$r{$Gds|Nqtn8zS!Kn&I%h1B5e;)ykzhxAlV%3-rK+S@Foal> z>Q79T%XQx%V!0{HQd?>E%Z41Z9;aidb}puxuQ{otXlygwU+RB}YOw_lFh~&`94spo zfT)kg%TM7suQ@rLSn^Zh58)34#5ve6zB|4>l)dA|(Z=}3fUug80pOW)J_9=v`Ge5p zXv*0>D#r;{3#@deu3C%zhTw}jCsNkGsGNsCzR_c#AA|uXCJE<;Qd2|0hsjAwzwar> zp6UxWhZ7dbvxx1hmqj-e+*UnOMD#H2+U8U(%8WW0b`xuv?V7}_2azZq-k|JM1Qr*c zrIx9p0mC+D`*=7`3du;jT~Rinct*^#g&K9Dt9u}y3B=%PCc;&-z3HLoQ2ua73mFXb zd|uL@et@$WOa~Nt3?*LVYreSxTpUjSu-?0L)A5Qwg8k9$Rt_uqRj=q`uhm=8&QS9k8 zoAJ$?$xQp0`|77a%E~d=17`Hzkhoy8^Ix@h(5#>{poHJ%=R${|v1fDzQKus;*uGfu zyp;si{1pkg^jsPFqO}rDr z=z1PK6Oja>J;_Ww96F@_(_;G~!^g@8`%0oX?tOUh{AtjelYAAorrbPv(C@$f^?1Gh{64R4A>dV4V=FM%;xmwQH=c5{ z#{SfTu~!8H^<>mv(TpEbK8dOIyO4N0?i4rS#htT9J7HO6zoZbtCgi83pIcvDcw&v5 z7JKxNLy$MW?9d>pp@^3|W5nF=1FY~XSftI?2prt-x8ztWZV`JoQgHhtL#zXS(9sOY zj10iy%bNg{0XzuegWnE>uFPre$^NBf6H-bCbSV$ZG}2_6YZB?5rLml1TJGOM`@-%C zY}cg)at4yutQK@sX<8cU84@^z`jj~YdI^rXo~I72hh?_&!n(0)a>Ugv>Q@zHfE~30 z6Sf6G>;W;V;{<@A6E4|x`h2?zwuUA5f9sx@u?vQ1JRsTJy)%{3%AcM$$qrc8)d z;qoe_(X;z0l?HNztexIDxH<$B=lemh=!GI%qE9F?b@{g)exM(z?yh3`R*4aY} z-qVGhjXo?4`C*8l50U}6F%||5ew~t6+~e0wXw?~_CkaQ?o`0*(nWrq#2ffq_xbJ} zA_U=UCv+OuD=vRJWLr@)OfER~7^ypf&oa_=L;{{4&YG{3jM@f4O&T`*gE{ts{HlNC zTC~3VK`(xUf;%!kTz*~a5^5tNn3@*SdL{)SjmM7mC<*VkEn_FthJm=l1Ue*GpVIlu z>utV*lsmT1Cx0|fZ3Uv+dRMh<=$>MBy4;YTBhatVrr`Rb^Vm>MmgVir>C2d8cA`G% zc0q#eyUp=<^EDb1>9E#gji)lA5EMcf?sAD+HZ62hxujXCto_$@%6%tO)9#M-MOf2; z7(`;wjto{d9s}2AerligC4gk;pjDw|y+)`gd8j-Gk!Fs46< z;fA$)Jc_=e$1m9XLX7CczUV8HV-%Rl*1n%A`-Yv~}eoACU8V=nUZ)+V|0S8nYy?-9J>u0J1=`tNTInYt= zz^K=n6;erI=%#{$b;`HNI5SRJ`s0c#L6yUVEm&0wJGj@7& zA}24PR@I7G-hyHo=~&-6C)7sPSKK95yb8)&qc^2qI8XX#yQG8)j>ZZ{8!!E&dxPcJ zXgRyJ!nByE$qQhXpms2gOp<{Gm+NIP7B+^4)JzwlA<`42#`UIXF*n0lIgUB(kS-?r4~mOFBjyIh`@Jk-q8VeztP ze77)lSt+v-UBWD#(`z)yfC14W!;c(x^j|pOB$7I_^3A*24R>IxDnCb%xtMnTzyv`b z9+o*o4LmgT{bh4=?cNYj*dZXw&cpdQcI%CR3cw;>&`c-;VTvks>7* z9$4hR{&q^OqO(@6isl;-X64@MWR)zaTaKj6m$-#ZRLPaEEtlf)FFT9MyC;a$EUcJDw+GjqCuFv3>R6IS_g8BM0}nCF$&U%o z=EzFVBo$1R?r&&$wF3Rs6GhEZ)6-q1sOQWiY-S97uw7@}_+E5RckUyCe=bkXnf&Dv*5?AyO%Q=I?B+qnA-38ogkDgXirLn!?wV?-H#giF332!#?pv zb8mM)1@N@z_wL{fDv~EgNk%m*3>f{Av-|;ZCT<_g?#%1%^{!Ch4a0FX(Gs@A%WSab zx4UR+=N^Pbpur;n`xMU%@ zo${It&ne*3)~CFdXaH8h;~sZRbK{3j*taN?Z<$;YJH%;7^8r1=;QzY?>;bKlVCM8Gd%kQKVN!81(J^Pv{(ava)TIdW0eu$^1> zNOJHedA8=-x5+69F}BbclgiE3q}oXK)z3L!43Ejw9k8ds)sMADrevbKS&W-KEdZO) zed)T73#s)6){%cbHioFzsah!Gnt|A9^~DW!XfEGJx>#S*%;znB?}12ltWm`wbaP`U z=8iKf+S)mR4k4(*)5C{-w~f{ga<)onJV(&i=l4Plh zT_Vi6>a-+CU7y|eq-K|FfsbP++0E^zeL%%Ef#r&I#SUDJ&MrWpk39VndfWQDPiPkV zqGMKm=mIV=+V8pPTNDPr(H0FWm;TB42DX@aRQZvbN{JX59`nX;n(&nKMLFHJ@iX{iHkfb)@T*8@kJu6$Aw_-%xAG$876Y)3J+(>aFjfi2t zF4JW(H{f6*c{p`>8uR5RL;V5Q+<(B@d^=dXUqyY1QXYfi*8J5fU$yi!EdWN5XdTz1 zm5KlUR0qT#sMxln*w%@gww418K;w++#P&^LgZ{0}4ZL&AkA+77BtDzj)iw36m4bGi z>&d1UN@JpK>W`ftnZAv|k4b8e7s{VhudbHvSz0+bTsZGRXneoM8A7C1p2YUzHWQAj+_>?YMSCd*>&*w=vC>s>_vbmz&JDPeqWuZB~Kygda z*j3kaR9&{gfB7()rL*hFqQ6l~oK1`{*fUy)QfdcIkVP^t2`yRORuG})5SiER^xPC= z7h__MtE)#2Q0#t3;%fR8~uS#l@zo@#qp{M1cPeI&*4iV;RJG z20Xtc>-R*@jEaEV2AY4;pO95iUoGlrLychD)uyHvam15=8*W^DS)5DwYzW}6VBAC5 z)|2lM<2=5^!%KaYQT4*N`u$aC_$13tfYVy#PLUF`Zj-B9Eo{@?t0e}Mo8QS4K?0D1 zi|`{91@AGK?Y%eOTC}BIrNUp0LDT1U?Aw#mUq85M7QA*|>>m|mS`_N3$CC+zhaal< z=!<{f+~(Y4-MA~-n2m1;;D2EgaSaoO<}{+JPtVs5^PT1<!++(b z1<(JOCnq{Whc%t1R<5(VY2;XJce>~6b&_t;%G;Y>k08o)GnfLuAaXf6D}Uq;bIryde#{4soWvl4F)WU$3b$w+3_segkB8icPmf{ zTm^tcgSveK&;STMgTvb}En@{kZMgNWHD>?Tv~0bTeeygAv%M2T0&y)JjVXbUgaE~$ zE%$js?EvQpu0R;Xgg2}=V+=yHbIs{0b~HmCjg>-+**f9Ydc2|6W>I?Tu;I*pQL~w zTss>z7E(gQ);DPkN9efxsq~t8487gyJLeIS45AtbjoTIsifdU>Jd$UH}xk2d{1%odEMN>9GGml@J}6PL$)5 zZkDMCQwLFoI#=q`S$kleyf7d-?{=X2uu(LA# z*J$!sH7iAQDa`ut`fBl3rEuZ8>^f=&S1`pvAw%9yrG-C=_k)n3{g$}hMLkyXN;te8 zsUm{$;zE}6I^lSr1oy)zO5^vM2?Pml>?=;|aakL2wzKTUa9=F9_O{mvv6Hg^zq?bP z_kLNz;SOO>UP2UHdepEmPN2*)%A%CLaRF&oh3S@H7FGWHQ&#+t;>$cx58isdm4zrr z<%0{uB0*D5CE>vueD#70H;h+nf*vhk$h)(vtLNXPr$vgZmR@VxJ_^z77fZ^9pqsXL zvGmW??ndJ_>6(R0bZV}ebU%>y3Mn>Nr{ZV?+4OR!6jk>a?b^gkXI*}_h-%JkdKHR1 za&huAOAOGv9bZgtuvhH@MnmQe3bn4GHAhGqPtRPTXmm1f1e zU~YSWZnYXL6JBjHjjD2$I56pVbCPwO{E*pH*~j)#C-BYFWz0#3OAkLuxK>HRx^(Mr z$SJ$r+jAoARYCT&zo3=Ye2i*IhID#>cL)s95b|hv#B8$!=B$|dQ=%KpQ3NsQ6AFrl z4-Ao&(D&qsCyl3#=OQmvLzKsab-!AYT25P^TlS06mBAZ{KYc)AK*V3%(~^)(KJ{Qw zUf93thGdgiyv;*)V0KV;gRz-7D^_W@bhg1I;;t~?k0O{?()JE zD!>ARJ2Q5OZhL)EdfZu!AKyg`5zH66OGbkkE0D|D+k76cV}gEme~9{d(XFng_QpxE z-u*;nOu&FNh@s4CFJ{ZKlH6CRu1N2s3p?MsBXP)zO&d2if7{6dc1&&kN{fJh-eYl# zh+VPtaSNa@Dca{L62W$46(A!fyhSfvXnWRUj%_QbP{^XD@m9cbu7<6Nfp`H%$EcPf z^Mh&>Qh;h1ra&no%Liw^Y6OC|yBg8K4!FLf(ub3v*83o?gCTijk95e>{Tf7#WD~*{ zPjsx=!k`ajcl9EKRsVj0)PxZw)jWez7g^6}T{!xNpeOccd`U3)C6UZ?bgIihed)q; zF&%w$yz;R0B}Qef)f$_{FM+io9Xs+X$1xsK7#P(aYpzx;o|3&)Y3IPg-sZdqv%qpH zXFF&(4@7oFMay0uLIWf14uW)~e})gzXT%5twA`f9%Xz6=7LkHfGstf+q-FAK)xQf! zoSz6Y$9N-X>OtR4F5b_P90G%X3nYH7Sl3}Ir00hv^~Z+%^{o$EZFf4JRR6q@*TafoWnn_o?@(=cJ&k2U0psI3kC zCodyk$TaMd0zSH4#u=Bl%s2(4<4+K(x2^m{=A%MW zf_3=D;YLmpa_H#{TCGB2qGuQoYRT5T4Z`Srq_SAX0ubb z$hf9*cL@F>Sllb-bj0(>w8~}hw7~CI@{!J#HiuZ*LIIZ$>vaa zM@gJFD0y+kf`F9NBNm1#fVbY1ceuvR;48M*wRv~&!+FSiUmv1DQZ$KS-ci}gyLwW_mg|mqOxBalnly* zu3_Ovy+ZLI>`~JrNh>hPpJ&VImH(a5)EKArHQo`iCgZz1+WgBk8F}eN38o?_3(5Xl zx+f}2fEy>8y@rZ9nLT_&69RXf>m`N6d zV{MM5@2lYbn?2G2Xs&N{->-f_B$&gpjBR`ZCJ*ZLFKGb%Upq`32m|NVVzi;EPGih&Q?T4>bC1w&1@BgjP%GF?^J zBkEjOX$TJKR|K*V6zEey+jKUX93#@E@25h;27RDImauz-O%3B9UrjQ%G zxH{DuAqJyR6P0azg`;h0kM$ag1C*yWFD-1@<`W6wc15DL0DtxkFVy`ktwsOh4MpWK zcrbWKHq8baZ(+Ukd~y9+mNr%3 z5jU9WVa3cef-3`*ZG%1FF<#EuSUvIw3@S_j|HGRV) z?TAUD6@N-OY~SkA2&0DU4I9FA#e!doDFgonqrnqTrOHd7veQk;C%~%Ev_w;G1mvfs7Z5+LsGheXmL0hQQ9esIDH9SdDUINO~3nn zu6WLP_PO@?7*-?pnkL+s(&KRFvqK2c;eFxx4y&(zSt)_X(v0MrBVe&6dMOG^N;b)t zr!O_5*GSE3A05FzJZ~Ws+YMcR8z$X3TZ>I}SM|+)KinzsmmM}3Ao5~Qtkz^3P^AX< zgsJDx%O5nTy<-`3-y9euAgdg2~BeWOe5Jjn@YH3TNmG~!;FM3N*T?bapDRHv3pmD2p0dGZMUJS|6c=(DL; zFE5Wh-Ci&W^-sh zO#n&amW&>?ceunnhbv~ro|lx8g|nK&_HJ&C`yF(;2i}4?!$F=eP7;rnr}VUvAx5nU zDsmW~!-4+?r=$a1t8B20V(a--`$t+@wmWI~kU}j(PzR>nJ{rDP^8QS1DlSD$mu_w9#u@mk2+C)qgKs{HpNfI0y|x-e4ko(+P%-Gy za$W-~D%NNF@n}&aNum6H`({+1b*UnzRL>WVvru7~5iZ9{a%zaG~P zpH}ck#hAzEN6Nw#0q(ebq(;eOr3w26OY>h2ZYo?_QBp2dJ`2zbc@dsy8t0p!nyBi~ z#Dr3?J|~&jzxmjR2WYL0x#R6!>dTX2I+C69Uoac>Yc{7_?1#LuSJh`fh_PwHyey*y zvATf6@t4i+Z-=6_3ZF76sw>rxvz#NKowI6RML+Ms z_&9$X%#REE?GH`g>Er49z}jO<-RKbBy|l~1$3+@_VQ4L{#a!0}#tWyw8P^B`g?#&? z83Ynp9@Tq=eYLlUVwc;wPyBesXN;H~JOq{HNEYot&V>H4@@)4GWWO5r+p6W1wnPzQ zLl>PQ+C)AVe&$CxfT+e^-sHGD2I`E`lVGPw^Dg6yR}J8bIY$qx2OfjhVZb$C`W#PX zzxdl+H{)Yt=rEeWK)Dg0mxG5W{pm8|o+(~>D!+Jb$x~WAu}t1jSedJ8^(%>mq zO|`DBxGmL+o(#WI95(#f-R-Zm=JoAMa|&Zjj&0Yj;;PEg&5!NBS2H1E(o;r#B56WV zZd%#sP+y3AA~IcoNL~y7kg#f-W`u|1*rfW)I!L>#oDOd~v9m?yTfgE#B~`PsOIwVQ z&p2Z$?6viLYaPCz&wlYD70V0|Xx$k<_Tb)zVvG^XsE)i(MD=W)`)bccCSxihHaK1+ zqo+;sS#p0EMj!FAJPwtTjH;T zTN*Tn)9#^_(TlFM9C--$t9{S*QlgQiaG+^;Nfz?uhTzY!jyMIzx8y`SqbcE~OU+%> zirGn>E0KZ}M;!ACCH7e`kE1FXaFlvF zd5_WIa6)RF1Pbyi=mesg^U4(FC2o_JV-8KoMeTUU55B^|nwa1uV3eUmgoN}BXJ*IK zhT(B@M_j0W z@$Bx!L>VtT(@BNTO(-9sn`c!N6@QjFd4#bF$0Ul3a7ua7ZRq{{{pjkVP#UQ?pgr^w zcXH|9z#R$iR-oeWEymzS3}UWOa7T;;Jq6h3EZY|A_hhdiAHg!4Q9$)K71DID`QHlC zTByJFnmZbv)lZ&u2pNH6yTvJ4(P~`;;$Q4zs?i6{gdO zNM9?`r-Sd%8MGIA%JoYG0)0^K*P#!3g1q%$>o3#QWT+7JlCs6$O6*PTSekkkuFA(w zZuKW+f=Pial5x#D`2E9VOJmzq{fvW6jnU&$NX8 zSPS8QT6XX|r|9~C(e7eYlh+fg@YZWWU@34{j%U^ts+Mq@PepUNAw`l-V^PcTfgcL=m7=)!?0jN#e>! zgQ)V4g}P!8=93)JJA3&H3glnup5>KXz$;*}SK$2{IIt|NMaDynDe(Ffgpo33%8s5^ zlnc)Fpx6RQLi$fmbsDIc>ZlXwTP205-u|r2fw#3i4#RFeK$a_&jk2!b;PxYzGhM5g z;HoQDYG{}rZ!AVU)!|RhIoTF3JwuX>7rU|tnFFEjwZANaj zfiu|7w%FZMBz{Z`5R2ShA{W9+>L_Vq8w))bN(_T`GWasy!`6TKAJ+$>l-JDYJ^Vp=~|%edX+_*9vxMz z8%^lhqZtstTCh1^Rd5e*1O7Q^n}Mf>Ad`LthpPiqI9M0XQZr#)g!QVCmu-^*cY<8z zCK*Vuu^Ev-`u6uw^$nemZT4UckO?0szvumP7Y~(dbZIQ8_nVl5(}~ zKPuEYF~5)h8bPxYd2U=d9VYF>Cw!v&LtCM3=1Km5o)f}jSj@-=iHBKmz5;m0FCXPj zW~px&B=GAQEM)PrQJH-HW|3uxzN;l=OGEju{i*89v9`IAa4Z$D)M5&%sj|87;&ENC z7563@CRo3LMm9_s(IlCPTpa&v<+5*kMkY^0q9RMS8^Dh)eQF(&Yi$gD$K?1?aIx-G zg0QuVxiyP}U@l@(RVg)Xej#VxlGVy}W6$%2qK$qnmDlU{rTjRKov!7sXNkFT`Oq8m zd(j@_Z3CArJw*~hTNbJ=zfcbd zLAd?WKea$q(zR)$%nOG+0=vYX&!gb%K0m#{Suk8Hk&`6HRnXumV(j}jRi{btC{ zj*a85?5PWOPC0v-^rbTk0c<}nsW7F`_eSD?zRZg1TeeMnCfMr=+nIa?LG$0g6X z-uVt8QFETYe*C^&^12xoW_&I; z@LTXSL?dy1B2}7OSu-WOw33@4<_J|LX^)uMCR}V4Z6CDyF$^_!@@$wt-y=CrM-LTR zKog^_Y{at~95LY*`d^{)q)cbb4%G=;FZfUjIPeJ!35Vnq78xS#TV{+&(#UHjznfWF zElelPAWM3c?A$VK$<29ig|3Qn7$xMIkZ}?|{^)W}Qz2ltzG4SEXNHhFf5Ul$g#FDo zDc1AF_3@DPuqSl!@$m4&3k!}-3M5MN@`?AtbMbU{wk~&WU+?Y*kPHw3sNd+a8Z**M z;&J|sW!~5U_!wRZL0XYMe%?6VepW$Bct9K|K+zi&WH#^?Isym_nFqC!nw>q32f%{@ z=6_N_`o6(K|F8K9g=O#5e>Y!Y{lA#6Ftf6={O{^qRh3N)`NW*U8S}0BsOi4fy(`%o z6EUwyN_Se41Mt(IptbOb3CNP95VFF=NHAVIiTBbl5TW<}kVc|7q7ZK4gwYN&OHP?q z1lwh9RyVG5&TV`{DMWpX0>_`{m)rrjT0Q|j0l@8jKH2aFq>w4odVXXgEUcaY71MZ< zpIo##ME!PGuM2e0y+v*Iu^0M1&KRHAn7!ZkFGizv-oJOBV?NqwqywhzABwLsZy6(Gz=5!2iW~vg4>}DyEX5{4fP29Z)1en>rzp zBGk$Rl2bJc5@S5Hkea3{DhdWfO6mVJAWftJ-$NiuTwwHS(mjAAhfQNfF?dZ$?WFzC zP9*zFq_zhZfFF-C0|A>Ph%4xE;P8XEg_O&b8NsW?7D7nN)I;G1EJ_ zjQElogmM_M#f(D6q#?8a&B(^2DFie25d1h{D9ViCC=>P%e)xPO6O2CLaE4zwP9a{A zUcb*Q_}}?sW;|!e{j&Pa_r**(mV$ZB{ibov9Sk#C4Bl>D@Q(tM%QDMA>VwPJ&nr=7 z8|vCKkn6Ox+9sM3enrOyi_>*`^BNV84VFZE;-E9d3|6f z2v)!n=oXOF$=<^Ff$@5RnqW)5H3tJ78@MWS)oK0eCR5W6v#OeoTgG|fiCBZ?CZ0cU zfPin?_!;rt1w9Hd*nb24#D`RJe22phbJ&?7aB|g=XsS8Zen)nq^0;5PTX^Ae6noa^ z{b{c;{8$qmcEma}y;GR#R_oFfYk=(`J>+7dj56bZrLEoHQil0KH(Ls#w2reGuMK(-Mm3o748fIM;_8sdkIBprn z4>VQFkS4uao^|~XgSceO0AZ(d1jnycIsG)dlN@! zFbS0oQwv2hao`ul68acef-X!VgJQwrAe>yXO6@}jl) zeNc0V*k;7x=10~t-YroJc+SnHSLPl#yFwOR$HsBJ>)tI@fwTLw#9Kfge6E1S*yO6`nD zTRN`=24e%nC2K9@E?uzp)y7*FuV0-iscmVV4J3 zngy(tMbL}=mDXTgUEij#MgqvyKDN>PhVebFkWzlUh=4*QvwDL9b8lI?a)Z^akj{q-YlXQKp`*v}?092{j~Dokak z%q3O36y)41dw$Jvx@6)BxM>9MS;5t9o{6DbDrBJ*E^BKWyf`C# zNeFWb z@CPF0o@I`I#AEb+AaPKM5zCDwKTg~U5WLS^vmLD*Xacdxs%d%m~w3k$mF7Iw} zGp9KThzeA5Q^F-E2!8Aaf17_yK1FDRV>TS;dU*hqAvoGd61XMbt2S8D#aqDWYN}RB zj|zrwBr&dBq*s%|hSV70#fKXsAFj6n{cqO=>ygnVm~HrU)@rW?{hqf&WV%;^N6OUC z)U`V+3)j2|pWz@enb2VcAs`Uqg96S*gAtA%g^K))@4IG$y)A)A-QruinhFghzj@|u z22aSvqgHXS8341gHf{qYDIh@a@0U4)MJK5M>QA~I7!jj`_={A5fPZ1?Mu-up$di8F zAA3jmf0}JfkCu3yK$B?DDLbe>InQ=_y2gD^aBONKzJb_}pQ*I6HjNypa&he`mKozz z8kN$g!^;%(ygfj^NW6)=5NH^~#>)tlWJqDC-}JM_bO_|&MeA9rm9-+vd&`Tfe&ihj zbo@H0T7g6g8e~`!KqtW*Aeo2ao`I^WGVT1GBK#}hx$~YjAvq_NN~O~BcoUzlJ*A!f z2+~tatE0blG}q)+qotw-{}1YlVihaZgMuM^@gYtanPt7o`{wDPN`i$WBDVh4RGDqm zY1g=D$v}4=-%j~*b`4caeBi*N>rZpNw6(xL?P-V#1$-|6uin|87$lphUD_cRu`hE7 zZg%bNTQRq?jkz`}%M%9~H2;>L8STtWOhVe`oWe69aU}gR+G+^+RCY4F90S1McLVn! zlc%>r^gykd<468UpB*W9{@v{D{yV{;SG!<8C1ZWgBiaB7mkZhM2psjwGR+fsVC0o`XkDQC$N7qjHUCqIi60 z5U(@WL750q6Cet3!59YEM#cdd93j1-rj0F-n^Ff zRhY?!irPH9aYtkI)Co1IPlI1C^7U zo|ul8o)sOEPZV679i5A}H`%|}?A5F_Mr7LMTUn0VSW-~mTV>6eMwkPI2ZO^l2WiwKJhiy*X6lh(Egg>eZF4i3bPiHVGjBwT~y1NK6O*o4>y;yULC zln+!_o=p(?Cqv3=`}p|a1&76F#>XbdCJ-F~b|Clvy}TOzP4+)DHG@_y8vh;VWB)&L zzW?bQ!^HZ(jAKASAV5JtK|xWa^&Ir zH_{4941f~#KOVsSmvbN>Ab22zAmE^&U^rrkfMNgeQ`a{ebM zX7>Lj3i<~M>_5H| z@9hUnV&rB(odb}wOQ;B&feb*EPXx$QC;%29t&|i}I5(Gl7jL#j+SAZL9%PDSt}?1iL={=2`(`G2*n$Hn+xssUqDLnC8D zQ`6M@=ckvK*EM%pswX5VX32J0X%@Lfc4m;Nsn107&z~c|UKwryGB~er1LQ5=m4|;9 z={Eo^29ZHOO8XL=@?HFe%#_T%#iN47o6Ccff`W?blY)whgq6#LrNpa+9V07*1+9{U zUHt8ZjP=c}o8pC?{q>#9outh5yM_I6HIq#2t(DB3jq`(D#I5NQlS+_t3v#oxm8(Li zZ?d3Q)Rnc9VVAHIm9%oRbYsg$IZ!6&A@4BR3)e>Iscqc2C8AufXGSFQOn3Jjzo$P9~e%WPFhe} zoSPb&n3^)5=YL-a6b!Eu)fb*X0ldQSQPJs?(N;$S52Ym z=rBJmi!7hKe*{GSZAEtb9SwNOh}O*LHrYKAv(d8nj=}!5bD*m zP-q6CkRY>?D;Gx}HccrDdpYqjE40N2g_=zeiAVI|Zb(>8ApCtrD8t1;XkgBd*e|V%Z zop3!)JUb&roERI9B2IBAO~m=j^xeF`##htUa?Rx24M88F7(O#h(ks!}7=Rp9 z6NDMTH^KOA(46?TEG1(Nun{AOFhU;;?g&GmA{=p2Zb(BP1ZYB>U=x9AtbyPm+$G&5 zToKGrCk$IrO^^!^Ftb5mw5Och`+GUm3q?D{;UNv4d~_A4YOG-ah|oPnh+wMn1pxvu z<9aaQhKbdTnmd`YkvWV|CwbD{9(hK&5OuClS{9l+Tu2h2!EI>_@kY|;=K~j^ph!pO zS2njtV%!WX^h$*x_bnQx8M2l}EAy8Q(biBnUp zSL*}0<`+e_>P1Pt2NQZl<4Z*%Q;Ryqb{%XMX{2WV#GaPc(@2;I-Qa5h@^U%Y9QWGa zlP9v6WP~5#&oc1pA$TuWKXkJe`*tI6#!zMBD`nLacvy%ko0=py#|+>nZFT_dHT>w8 z2xM`bVqtCC5lLeNN#(Ixr*m6Vh(=IPm&BZ43wv>k6*N6Rw<;6Dufj~Avd;Wu%E~M~ zTsczvjiXkY5dOF2S|5nM;*6_XP;X{1mj>u-qjPXD~LA1SxGFD(rtA5^O!& znt5#UIAS-;JDKA7zXMOu$WeTAk`*MQBl&pEL1U6w3ckmhs;@$&wfum8%)7WH*q zrntM+-)hP}qu~h`4KQNmbw;9yaLBWqJV^hXCJlZO$#xUf~p74Qsjr_cBz$=OXpS_s?3&yS+Z> zCY?U>gMHHP)niRdFfO9D!z#*rI=A|7@*Gl%&eu3m)SLxXbxj_ct&dp-cD3aP9Oi& zVf(e;@gLtkV)D%F-#eVb|$Ldd)9*HEy3oyiZ) zenfBEaBfzL^;I$EV%5BZV$@I}5 zq8q*!3RJDOMbVHNiOgQ8=SZWVv&6>jn=jyf1^c?@&oYMyJ(CHkDVmEMguQM|+z|!# z!Y&@qJeR#fdC8@kBJ$Iwcx8@UEGO6`>Z^tOj<$S-c`<(7lMijOhq_Xf`G_{!k?Hy` z1Oq_s7tiGXgkS$RWGDyYfAz`|5h{r`GRWWw)|{-4gHU&&xeQc zK;!xB{S!~%=~`D7%2MxR=t~i2cNN@QYqGm&#SEAg({cqPy~0p8%gps~V(Xhvlcxo& zY)(FUlI!<*K|*CATnsE*zB#~nYT|^Cc?VXhd#{N*mG#}rqxgRn z$-#{IW9;K@S5DU!P|FnLnD5ZIG_8vXi|L9wEM&ErpkK}@J1+)VS#lS>lYz;cqbsMp zG;Kh)D@c{P{X~cdw=U-^pIfpkt?PPEm*n=#Gq}7zZeJMbauYHl^{G6rsb!#+a5)?G zIlxF!bc!)qd2WroP}JpF!*<>4p`_>e{OQ)fCU<-Mo8uFI!P*xt&~{x5F14X#wuub@ zh+j{KW50W$Nwui5@a@ewzvOS_b$TAJBw75RXUoCSjXZD}gpKn`72^ej<0=(lp72c! zNlD;>IFxx3m+8A=zdcO{SaP`|czknHtejrCPXoQv=%|~PjTs4{!Psez31O+$25J`s z5Y^AHaPm5q-HZh=VC7nHxAR9OzVL7Oxx6S}4DvcVislukvgmz$Ug(jF^mOlYzyDpU z1Lz{#?EFtv_`e@d|My;}jBM=xy^B;y_EJ!JMIF7}KHec+Zm%G7gZ4V_#%2K%%SS^< z5C>}#J0c8Dxs!0eCguroK?e~;u_>h4*6oL)p@W!?#IhG`>_xr6YSE|0;%@2`xlAzg5xV zuh3F0o}!+(|NLdZi0zIwtYVOfHoU<&i7?#3IEgY2;Aj!`?+!EOwx^K`9|zH33YE-O zNryfOC^7tV&wj7*Wvmkw2kA?Dhr9&!L*|TJ3LOV+2b~A$=P2pQ*sN09(({Nd>jrSB$@bWz=yHH!?+-)!a=CIR>na3{cz8p*7T zH~5Vy%UYI5ipvk_^;MXz<~y7n_hjC5$JDS)_b%LjAzL??y;t6-(NLy48v-PWxAL{zr;aC|c9LjZgBPP8T(X z#BQU$&-;069@G9zI!GyrXd_te;JnKj$=UHG@hMJ-HWk|+hO1dE(uXvxV_|}H-vGx* zyNTsSjNx}A^F4V%;p9gcM@TiVXNVGP>)5#DJ@)L0uoGaSPA3!}eKDSl?HD4zI4tn5 zhFIHq`Y=!e+y5j+qAGXA>H3_pS6`C=q z_|n6i)lDs@myL#CKzP27hp!Rr2iJdPgQ;P z^1EKQK?1`*Nvn?z)h1q!9e!O`$)e**x5BCJxqg5T5hXN{Q@za7o3L9B^>Taq$K;xm_5aN{FU zPx~9ftYMlSDLROQCY4;ayue+@+_>Vbaf4J`Rctk6c|H;=(+FTpCjbpmYh%-ggR4pAghW`T4CmeHYSBd$75yF)`z?Y?!&oS`l4 zX~`m@F?2R4ihdaAv%>uAh3w0$4QW~*)Byg7+9SV0xY2e{V+fuB_OJ1+CY}$Ti;^HIdh=?by=S_Dg%B+|o;to14koG!uSa^UmOzAtfKq z7LJ2wb0A|dKbk}!Lx8N&I;K3^FSvk*&gQm)WW?>s(Y-p_mdVaJKi`{wZXz#~tv_`O zP32Q5V>Gdmk#o&|?R)$`rMx;=w25|gF|smtEY<#^P`#((7kv{Kk|k&+uf>}x{w2LW zt-6YSmhtg{c5_bV@XVJgGhLvn7RE_8c&5;TttFyb7)o12=v0y8AtOwnC-)WpAd)r} zODWXa*AvET#I09-`Sc%-Il$gIs+<2sGyt%nMUeTQ(CvTEQ~n>&jf3s~$FQ0F7sIyt zp9~u#qqO9|Qy7M&|6tf8zyDu`ZRLskezh)-U!%A4!S5B}>IaW@sBdTtBk3?(UqLfD zBUiDoUa5bquTP+#k(8fOm9VX`jfAyTqo0|cv$vd}m!g4$RaCy8kzD*=@7kt8NYTvE zTn#6A0->R#x-7stuXTq@VW9)&;?qJz1qBd98bIBJB zS4t>Lm2y%qW@j7ERjC%7pI4^eA6ctL6K)#paM6ua7%x|vy9H8;qneGWRW-tpbQBG(}X!wXIkhua5g(2*CKid1LcIVK@M4P+@GpNl}w3-cscn0z;q zKa4x-d!&AKjUvVA#7V_bM`A+d6iVJNYQP3rULq{y< z4x{(GeHiUovlA95?-OW1m%%|TRpuaQ6N5#bO(YtYXxEE#NRfEOClB~IT!EO|%G>8Z zR1X@E0gKtol*e;^S@Ij+wehCM(gaQeJ>+!1NHnDnU5IX4f)2dl(V*}+JZGuJdL%>_ zhKDP3;NZ|m2$j53Ypz<*-2PdxohWRzUhCVp&kUd!_tBV|(qv;TWxR33qAC(zV5vfP z@)ZVTz@D>P?SC}$_S48QCrc9&0dmam963f2sic@ljyKsd*J|Z0SW-#-GmXkiD6%mC#~KFmZxn1y zT*wg;)3bch;uG?FSa_aU1UC2fQ8qC5_RHDEl-08F)GDlo$^ zr1ZXbpZYup8h>T94FOq`W@K=(cLw})2BauJhdb0$h^6b3(usl>rk!qr@dO0MS1w6e zUeWp)#fQVW6|JegNIGq|V|y*(099Xztn~1n^cn{AV)lDAkutZpKG1Q> zwUOsDnvvKky429IE6~+mS*AU`4?h2UCxkulSIlf6*sj->PxZE?z#9^hY2u(M`{KA* z5Q}S1%*v)Y#A+Os2=atLG2_DXGGuDiK}0u3{sP&ZI)}aXtzZ_^YJfN4NWI zs3EgTo})V0!aBgk%OWA4R$^S@D2+tFKeM=WUfYq72@%M~ph)M(z;eb}k?VCCF+|m!5JLHdP*8 zqHL|m1(wcvt)rbULqE@gsd&Y-iMSLt`^HImAQ>A0koga9|KfeL1)puAhu?HSTEaJ8 zrwa4io!R6z{w)i57bi0z5f0-i-9hkuCNEJ5zq`>RCmv7VAzg64^>dvDB34ol7pi8t z?y7{0f>B|c87cUL$P4m3p)XN(<(VySKRhlh{FAH>B2M1X1+55L*z!H)=pOqIDJ?!Z zDy~p(QTH?T4|CY^fq=lG(KvVu5g(tKu?QPg5g!g=nbHf%W`{(qVmn-Ydu>l(orghP zc5hhqZi(|dyQkRl$(7X+7M%C|`h2Rs3M~!}89%!P)q%TAs3=&Em&r7J*4#Sn^1H=W z=~Xs|uD7abYTw?R;W^gj>&g~2N1Wb!MGKuW!)i;9Uo`&}&2A^YCSH6AsOSo97g_H< zO(07;Lm+wI-y8mYZ@o&x|A0kLgW9eC0SK5G|7$1tp8=uD_J+o$1k6nA|DG$+|1aan z{|p|cmoT;XWA04A#{NHrU;Kx+B)x{bk)^4zGyQ*N6#vJI|6e}ue}wMZ+5XEFBjEU7 zDH)7R%>Nxts?*;6HcW6vfhpAs;)?}@CQzZAX?3AZvH#6=l*(m``zXUU=2fxlmD;Dg zak5p51y1FUu8*!euZ*{w(_TA%akEK64xW9 zLYPk-bUIa<2h%G|E?Km^YS@BGQAChg&7(#)Y!#qS2d-gBW;!6!tV91)+^$?#?sZrK zd7FpNjJ~m?l2Ry=joEqk9=tbvqyqW;7=?o%VLv*3_9E$Upr61tkigVnVMK%0)Bx~? zVZ_2g)M_n+(a~bY5+GU;q(+LfV@m!F92!E>=*2hwAw#2DNS^AHbb>l#m1-55-DHfl zZNVc#Bgj^2?1(FJBt*}oB+3@UAtFe~R>uw+s|4{GS0=VnpvE~Yc%|;nT|J>+AB%GQ z#2tbOjCe897d}IXhiJW0q_ZG-vyR8f7&=n{C$7gM1tY1MT%S1R>naLD@k4WG?LdU} zoEs3NtS)%?rH@fk5D2knW(6w_{jl+|U!Z-Cgz8En0_t~Sd_jTO0u@W5+AU&C6Ch_& z^|_jE6oF`_9SSr@DhT=1gzWNbCk0`Ou01+*f8Ix}F%=oJEGpX!H~z-N1+z!f5jowH zE;6U3CZeQtTAOLb-#lE`dW)XmW4{cTgSfsyI9sXI0*tIv`loj)Dfz1Fb~`z*W)F!b z-dzJoX6#Pem$y5@x_@ioA=+(7uIl;)k!<4p^}-vRlIu0`Q?muB+ZiH$VIgF=IvJup zWBQU~E^S!*7Z^hPPZ|hje%rHotI?M9XKGhfEY0w*dDACm3$D@R_G_Q_6mI!W=k^Tx zlMmz&dg^)|uenRYHNq>t)JpHzawR+u1Sb6ZaC#!$W&a?X5Ghc3x-SM3UIhVX1MbTB zrYSc_$|)XbOTe>{Pkpc)yT`!>)4DJf3sxPwZX6p_bOmWZO3y^=B8-^b43`=jY<@I?y!0RVoT819_ zBa|D&XKqv~-7kQ(5x#0jh!y#O*&n~ixgexf%R*|NO~j8O zCKG_D8dNC@1IogQy>(^6*^VTCQ#~ckXq^v~Y4=9Np41qL97I!0oXE{Kh-G@ImRY`u znA@a;7GdbxA8*xXu}XJ;^a20_d`@hm{15+GrvFB+{U7EH24?pE zI+l=#$X3^ODjGxeU9HKDRZ`+@2U*QySU9oi(wZz7o!sGF(bs6Wjx69R0j> zqJstEe6UukZS=q4TfOx@eR_99a(`2=BmZ-22W+=3Gn0CtA3)x9JSY;}1i@c$4{V4; zpE{6c2vfB=&R_bt#n!^XsmgR0!mjJRTijV1;)eK%wfoPPL0x-`;A<|c^cV^qS*Odt z=H=;S-t1jC_x^M&OHbV;3(ezmL3(=fr(s)ThobwiLr_(w?5F(;w2K?n7lGQ26Wpur zabX2El7Zr&WxGc24aB^s!)V>$blbV7t>+jugxZbV8=^&51)Cuu*ti%(9Li=?Vc!m& z+6IX~HDO<4yQPIf384rj^1XSZ*=2c3BL1ZxI@aaL3UM?SqRFlaEmy7>|C~UGP}!mJ z%coI8ZU$}Bt5a)zxog5zTf1dv{aJJ`XO_NeeElwK&+a!Df-`2-o&)#;ccx3OZ|-C29b|Wp7%VkUqQ+70Y;Lk8>2HG%Pb zk?1eq;O@I)vT6W=+>xQy>|%!)3}r;Pr+!)IXOkYTY!%?%@V%fGX{k#wHRLx1-;zpi zu?AFR{pZZ+C;3HJW{zaA9x~o!(0P?mc(t`a2tC;_YEVEYbw;#Dj|y4-qdfhY3FFubQKfm+c?E} zR#-F(nYAL{v5P9v^gLYo(fI+R{<@7G>hcFD`^ed$M^5Ux*$6oC6_&gQu;V>UbMXb> zDh!`qpPF_OOYo;(%BYxm2=>nALW{>rytBqmSwa~t6S-{U=y zCp6St06!X{=#uBe2}z&pI5~DCm}U$oH>^J-YYPVmU%UMO%jnEP(<6 z79OAr1_x9>1pxS;upYe|1oC94q1u|fhv@40C7S|6J-r<+UPxcg*175|RW9T6e2B`M z5`YZmSa^tU$IsX;cVHnxbp6>xI|7O&hK#Yf1XDd$T9Ci}AnjjQ4FG)S{1KpX+kj{Q z1fDQsglO^hyi?Va)WwL20s#aDhUGf>g%0@usE#-k5}EH#0Z?BUgY$nsu@jUS=b935 zDtcA>E?fX@BhufDbi4<`@m`78R4@(?E_-5yNDfR?dw05uq(Kmd8*FwXd z0|| z(tDV6H|hA2?_&#JqMcRE__SfqyDJ*)b0 zG3-5F3rQ{&I^x!s$+qnM^OC>}PxfBxwJ!!B*g(DdCNw@1E@Re4f1y~}c4@1VrR?CZ zZG%s6Y};+mA5sw#ov{Pjzdr=r0@hu_W`*4X&n>j5!f?~A%pmH=Jzxq-e#TqFa%(1iXx4N zxfWEtp+p`>X-{bwpEn5w2vr)yJ8SP1f}Zbi=cHcSm)TOO#wU54ymCo61+;`{Nigzm z@^KDP4Dcxl5_0iGh14`M}Az3uixf`fb{2C8bCnD6)w5tvMVoWS4 z5(k@r;q0Nk+?UwrzJ_&H_^f~``t04|Rm@v!-2W}}0#5osPp;Mni)OiAlCtAy?FxB6 z?xLrJq{#G=>e?z~hH76h{Emi>1Y@UWQ<*uVjD@uo7R3?(_XN$UOk}jlD60Amdz2)C zwRfXG2KJJ=W0A1Gz!0`5$7#I`}c1Vs#dcw$-8S_y4NUx)%FX zF!&y3tSk$W>+o%8e9v3X?TU;4A*u_NaNA`>Pi^1yC9z9Mz)A_&M5s5#xbnV{$GgQ( zWqBVmY&(vfPg0o+`p7J|K{ig=6*-CeOnFEFSO+sxq?8JKB!w_acYsG%Wn3o(RmVg1UBU z1fdMGH4LHmE)e0gJGx;u>;mp)l?0wQK56_kZsy)2CQh%GJ#mftJHCmSIot(sZ{I!^ zb>+S?R+5{S&*D~28&cogzCCN$+P!HMwMEhoU||C`<l^?Io1&t(@{rT36wO@9*z%Ddn$5!EPYfM6lWo)k~IlSw{9u5%1zpf8-WE|z#VCUyWd zE5XKs4IDO$lkGr7K$LvTdV)Y${a_2=D|^B4?;2a+(Vxb7;l6`EL}lM#^HvcW2&1k9 zm}BxTfu?WF*bwANXY^N07+wy~$R0os-UVhji~)93V$}*u`O&*J)JGsX*NkiRDDiJy z6*%|-K=1eqRW|K5#1TJ{c*C>_xzu!7(?OH#TAfrW*26pG-0%#L2^t9?Q3NEHw~MR& zqDs}%d0Dm}SJQ$#}OVD+^{!_$4old9L8B{e*j4=!>B0O8F3t39xf-QoW?G~U5Fr@?tO_YaCes?s4*;Mi_3=vupMIv#HQ{kW zY}@S#XP9~R&JNEvgM_DGH=e15yT2M}7GF&r8L2){@4qlMQ~}u(26iOoud_cg#`gH; zoAJHo%dpDfF7hIe{+u4OKFRGsZ!O`#>N>!r0G7l4;ambG^YwD_^M$2pf$&+Tiye%+ zHP{CGLK7z&?op)iX0_*it-&{0#fjV2iv}HZ#Vq-{Jw9`X`G*E z!&J#0Y`Winob*o;5BsP-WNxSQfsfCf4YCpzY*LGfpSg(U|oNTy=DIG;Zx zSOFe~TR0QBVp!Ik(|jM(qa&eWmZUm+I#nbRsP$ks{ctlFg^evXj7LxMd3smU!aC3% zhZ)-6FvMZg?wcO6@oac`L!&`?gV+j;NMAiyMme@>4^-YD=I zp*oCKW+Zmsh@hBJ>2PKB&A0X$%j=OHKuXHnVIv#+e5X=gaMWSv{TN21+_${u{@#pj-8u6`n^Pug13;QiUY@IKK5T|4<` z;TQI9!$3U-NHeim! z(cA0s*8;mRrNkRoqK?;YSAzmvJ=yN({b%v30IfUWPO@)JGY=j))Y9mOTD9pq}k?*J{Sw?wnj)N%1dT(^B;~D0NafSI}*|t0D z83^QOhIXr7cjBipfsk2=O1sh}sDx3RuhvEErdfa3IW!01BTN3pg53kCw}W%R*BUL2 zS7tz<2qMWO^?Oe3;vkof{8iiSpVZbj%2A%FIIi09#$1P!5QO7DTTpJF`)&T{&YP+2 z8fh2cycasiFR(`&HO~ zc#@E!k>Wgs93h^e1W$8to*!8E)Z&012Lu1awe}V~wxP4oRefRe#4+60g_LM>w>naO zL-v4TwT5O8;ggjqEw?*4xx`Kx29bLQY~VP5cnJ2?HISfMnBYbq9IEXKV<Ct^kI6t86@f-90OM*lmiHYq zB=$X!8c?8lNb$h7Zh|7hf1qGGl8VkZeT3Em0X%i~q&Gu5VvQi7OD)Imn5xh17L=H( zb7ZGz3NjBg=dgt``k*VsdB8oz=$UDbKYgn;_V!AEUV+%#&`Ycn{jN*mUL#RMoZMN` z3@?u%k#O}n^6feAN`eaR%`758zkJkeR6veO5qL-Ai8CjY&Xm02_Qr2#%NNV+advY(?>uY)}?Rbr3Wl48i6*`imx zw@KLbF#T9*zB5$913^RSjcR!p?P773sIeTPvp%q_gsQN&)TTepKhc78-SAa&|>Vi6i8v&TRA5IYmKpWu&cQp9tS^qA^e_ugu zFVfSNMh)BqrvV999h~yd1X9{KQY4-=8u_el4ymo1OP&iJg&<&1(3~+#K9TP<75H^?KqHDFj@NMdsF zgQDla{pK9I$#sOb$%ES-&*$)xnq`J%Ow4xjLAkgdq%S_%TkoLk>sdW4KROxH2_n7KpuO z`Ibw9Qw>T(?IK|v^eoUY$}vsPo1?`B1Q!X)Fi$1m2hyT&%(elDVIf}z{Ye!38<==X zcT+s4nEVHzF&s+ejYqX8=7UrXAwAR+NFNH#$KM*2c}!Ug+3Yu)MKA<=9-p#q3Uyw z+OY2QB-s6YW(4B&?ocww`1 zw67@^ZTDaxL_3m;gULQJlH2&FFf$4Zi*eVftX8F`aZY7VT5Qe`$c_qI0&6SH=Yt4l z=djF3)Vb4w5pe{`=nTsuVTemIGo5grDY@OEMNlQDLC2>73Tx+HV(w{IUK>_i}Q9uJ(&NX^^O zSH_neXTW~62v&$W_py~-J2f>oWRhcttA5A7^RpM#Q`N&YvvzA7`B%;cZY@g|0pq5D zvyGD<1jzt9I)8g;L(F;nW|D}(?cnJmT=rcL2C^*?dRtT=63^}afuNrsIZABFWGHju zZI9ksv<(IqsB7;PW~G8MnHGH^KFZb2e&P#3(hh_grmY1VK2=vgu`RWscA6k&}~R08wcZK%AXA-+KF9H-2N%plMX> z=Aj&4c+BbwKr7A?bSNA=2&-tB4}SRoNt8*HuSJ)Z8I?D|1D0+f<|I=S*N<=E(c5p^6ub>gcz&R_pP=0mKmf^ z;*YZC?b`Et^+ZJ1m(iZg3gsdbM=^(gPSBDwIKH)^rFq+mBDPK~M`+@!n`+I=6^)TO zWJkUAd$wIEw$0hP+cTSDD2i&^A@^aWRvkHIz<4OBH^6XQuuk8qBc>#21s)>;>x~8t zSw~A-1(q8Hb=jvoQhsEY6M*eLbgk7LH8TiQc`rliMW}vxrST<+8;DzJSUaU!t z2bEQ|FC#)%c4E$O({HNOBGwIcxtjV)OYAGIJbbt++isifrRNM6-w!SYZOLSK-n&;X zZi!kLLBvyuvF}>Vzg)P_Sz%tM3hmgp$G{!@M(ad{v<3qKA!P16*FBavR5&PML7Wq=_RzVYYpsS6{~@R@IKl`CL5*J$H4&?xE+8&Q7hXhZ_W$hF0s7VyCXQ zuLZ|_{@1+Q!K2#Sc#aQqr!P&A(+u%8n(dpoCzl?RwKq%*&VRkT@lt5|L zztbLOqpym|9P*A{Cx(SyNoYGYB>bmAFiq&9JMEU(;K`CWr4etQh3*G1HsUpNb3Z1iVQKmyOd&zz zdoi#mr4;#BFvoddprLS}LH6QG0BTHv9HIY^Y9>W#Hd(nm1fy!^9-Kme?{1%)TTW&= z+B;BdAvAKNeL-V~xx2munjOkj?@vMWId^FyRh6|cpz*@ij}iyeoEKO(!b0?+%MVr8 zOmGp+KJb1$?0_Z##}aJ$vq5)hER=`A^L10=!5I;masU@r>o=#$OSvk{aLA`ir^*ynd4-hff&YTT660J-R{=z7U_vMaof+*1tukl6)Q=D}tx{ z1_LH@|5kz?A9Neh1>=dW3BUoZ;-gPSGDLb|Y6MY6NUv*Nm+f_~EtYi$U~+8gtS2rV zBzLe0lu23cuy^PVKhjW=OdMW+>FkUcl|)gjdaO?<5ds^iU^P&!pq+Z zrp?3tT;4c5)M!&HBKPA58IvjvMB?_%pVA8Ua0F+#LEya5;LB_?Z42TYWSns_3$Ro@1$tl15d6Zc<5V>Y?TwxvK(m*Zu;e_^jzxr*U>+p=6y_2I5dM zhDruoJ%_pm@+I~S+YA3P4rhQUf22XZNYQyvh$TF7rYMUw86Ss_ul_3dQxx(QL^(!Y zOPlMWYc@QM^?=NI`!Fu|>C5fuhR}IFZ{+FBn4_AN>KS_rYy4jK!_n%k;cQXdoX+H3 z0L};ah=)Iazsa%TP`vW7$nE4f;_Iv3<)L>{J5~%)Vg%2EmMCq3kk4{hh2ubw2XmuS z!8E29m|+%T2^=Cge$62e(}kQl`Xbs}oCs#j%QCb)V(VwqVHg^P1erQ`nOySDI{E1p z*tDXDwgX#kvAsxgW3iXsCGQtqcr~$Vs(I%^Z-gaPL}S<-td(cdA>oTes(hqXwo>!k zMCyia;-e|4nOVPCReLUT}+x7WyLYF8TnMMCB8&F{7 zL$fL}_LnF`5_}g$^kD9L^MbAvKK>9Hs0TP=mT2)KcHSi#%dUd|yUe$w>FiHsR$I0^ z4=g*-gl$7>htlr+xTm2DAC>li%R`$G2C3lBI{ZM{*;U&$)xz)AtyDq4%C7wB9QUkY zg5mwRz8beJsx(0Zd{5Q96;Igi;e&K#RNE&4_I;tWw|+qE>%KQ3PIEA^o{lNOj!7N( zu8XzM-9UX%r`+38*yLb&=Sq~cr2z=w4|pXr9@s}a1aNy%>Od{A&IY*Tr}KAqNR3r)Pa=G59#vtyvSOF}pz+XK^Y zPVy@OrK3RS4R~?(&h?J<7lKY{#HG&M6?Ru4M8>}_+xg;;rxmZZaf{zS0o#r0c7Nw) zgqk0DQ#ETt-|l;iIFz-1<8bLg0Y~`;M3S`8a#wM)UC=@Oa-6EnYf>;W^CWnPdibPV zj$aHo)hC)>S3rxPttJ3r_ILFTn(}*Fuz+DiEvKfk8=aXxLCFoV19M3dJO4i3 zpG<2v$o}%VZ#u&&Z{iYZp@vPJZ(Kt20jgLFrBBjMWd!kje7X`*&j4GfK3Lx@4Nq7U zv|3#iElEG!$Yc^5@fzFvA{mWu2Y13j4VrXt@v6=#v3!_?4hJ|>)O2sjhW|{G4lO87JCo1=p>;7{z z`BV;ijQEglv5q}I-tEfpC!zoPn>AD@hyDYLx}){RVgxJ|owE)&5E7vc zhD|J^l@h{ow{1%X90NPN%8O3Q#NzCvPIce`Bd$cKcBUBX>_@|6mS!2rh@ zA@)V^w0Btk8abGF9!9J}ja^pE>P#o$l=_1oD$N+rpMS3c1jQW2X3Uc(Wj#xp~FzguCD1O=1){^x@F$73Lr z03M1TAH(77*3u7yE3kc9D#&-%XVk9;p5jTfy2J+eFA3BGG);v0gM>Q`giUb#8604k ztt$3S%O>PaYP6BuU*wp!j3Xl4dlA?$3w;=%g)?gt<}mmU8MkJUj;S;LHSLRtobU(} zjmA~|Z4KOOeU+bRW#mzvCo!P%=OA|NN2sI;6mPZ~BP(y4l?#_TY*xY?h!tiZ?i5jF zAD!{Skvue+xy_gn@4Cq%1%44Rwj;G(ol2%|q+xI5aknI7*F5wE21z=33H;14eIW9H zEh;m_dp`TDPe)Y>iXEno}fsouViTif}Y$kf?s<^%zSy zg6ur+p5MOj*?sq)?&^E0s&93j)2I6O=YDIUW#5b(R!+a!n&@?F8r-q9I?nz&?QHXx zoyTktd#v3Kpq0&(yh_1K@ys^8Hf=G7xsj)oR3hUQq(Aa(@xFX-b3EkjD=)$5hgHaM zYm2+H-}M6CQDzTuXCNp!&~j#qh^1FDl+E}~89($_z?-M@L|FLXH>CCZa?=^u40LdO zufbCP)zd#g?QKSpo^8{q z`ScX?o>k&Y^-;(CB!xw4bnN`T0{GutF<-!B&;@nvMb4V4^jF`67d&g+WmWVHq<9XK z!u%?l!mX~w+ISArG0exIp*+YO+C310BupT7WH_9QNeQT!`bS|$LiX5++wPm?lWT+^_izBV+e#RgACdD>H zO@{JC^|+(qIi1`VZQ|<62d&VjHMQzG%xU0ZX1qbOLjqRuLor^VrI?RD1ptA=}w&;OY)uU5ui^N zo*rf!IVMzNuUUX%@Q+;z(1$B$;k7 zfh6SYf)YB>=)=zlL<3{_*oCDsDbOxX-rXvBf1o~K(s4)cFj)(ckpsOfbHnHcvU6wh zsaWcU3KGO@5b7}cTN$B9GJ$SAH$qVqAYF6K5AlO3gX0Q~vystmE)h7g0f!uZN{L`cfSV`g4+y8mp=p_YEQ0sBgM=H;EEI zd(tKi-25*jqriV8>x;voCP;fYqq4d<;3FJj4@W{>kpPrhlL^ceY6eh-TcL<=WhaQO z6~Yn<2LOTWs4;K?xj3|#I27#7ButP{MhQVKP813*z{w8;0{KC_Y@B=yoSY0y9RKRv z${zNgwfH&tfP7q>+*~Z2JPe?JYAM6*&74f3aK?{j_7EsQ-pUy&?q+HW1t?2M0l-ig z6#kEgLI68^Gb?i|lv7R!E0_hqO8p;Cx!JkcIROwi08kyIt5L z41lzR0{*YID64`MYAgtV8q&$k4Im=}&}Wp8R8T{e^qBzS_9!oqOroOy%$GgH8k6fk zx&HscoBj*dN3r^9NW1^x@p*VaoG7jzj`9@9&B?=|2mtbM|DWtP*YsxnzliytRhL;E z)VaIZADb{%hEhNmG`Q1_Yo-i#O26g7iI#eito84|fFG|BN3~e0N`F@6?blT>-mI`6 zuj&~;WzRzI$R?YocqQjTfuD)#VNFo%C-_!QX*0%_Qhg&PU5;?%oj~E-W=y&e zsx%8#CymP}=!n@b8WEuV8-XcaHI1@}oDx+<;xg_71Q;h~Kf--oKmSa@Qx=!5P08UR zex?4go+9*#zzCft^H;wColtAl>ay3CFUYLEbgUb`_v2-%h{15Bh^*0Fbu_l)af%N% zQ)osTD^oe=rzJPe6{gJ%lm5U(OFt1#{D>b1Wy36f(qG@Pu563&EmIaqQ^U=9IwfO? z8?%pLfu#CQD-g5)YWqn)760DrIFZyGkTlLpBDyv2S0yL({&tnO@f$kCF(_^oi~GYU z$Ttu465m|ChbCJ_@xwDxoAbBKAsu+BECtkt&{uPK`IRlJVi1O89(JGnE@ zpYH$SOpb|F4Z*;t7{hy0q{s7`-ts&_>LTF9HQ6We%yG*2=N3Cr3jQzscqRhz7@y9M z7*9yIJAmG|1oca+Q|l6L>W(G87Oj5%T$>FP>?giXuG;01ko0yn85XlI0)q1(y{g3J6J-$^b$m*y1pA9%bgU$o;7pfj1Yox5~D8lg>b})yeB?&x11yBT0LaRm7gkf z{0Z4$JBep=>roh%BRy(ObfQBMYI6c8Zj@08@!w4Bgt;+zlT>t(pTskUD|JiXF?!>1 zbS+K?3whqCH4)o)`*d-vx&J!wVr4FO%7}9ME8avP77p`KmJfp~hvm$tX@0)0O^&+l z&fAYP#ababTQGD7q30^(h`jJ=Ki@c);4zd#9`5&@A~&5du2Xw)9hF|l40%U zyN6y5b=T+*j5Hl~1d{vV^nvO171J0Or17U*rO@rG`1mMN0mFHHj z-gTv`LSM>idJU9@FCBRTUT%0v&_W~hqpoo0+f!Fr+;oc9 zIAHYl<2^KEBELF7%A?0DI(E??oNE28FOl-KUhbuPg%Mh*sM&9~i3Q%29mf8OjP3>iIE%G5x@NUutt-H6UK}H{_6#+Ea=g>#J9IFXrK~ z!a*eIL4`0f@ubOQD?W-UyHO_GEu9!7uEECVINrp5Jcj0CQEPJIzgvNe8N5L7;?bzH zN_i1{*?7RJ#jKgV@#rC(6Vvggu!ZaCfCdzs7hZm2JJuU$LMrH->sV%iMV3Bz)d*HH zY+kKgM0?J0bjkQlsOe!oH*fd&nPYU^&rX&;5!o$DL&%}ZFDF;*2C&TXs^lLkI`Lqw zN*g+lh#IFdftNbLS`B4xclua|31F|dT7ZJv1eP1t&jfJYHk+j?)w_(^6|h^N-I71) z=9^SEEU5(W_2xklC&Z0~eW5{9oscH6HYbM^I2{%SNhv2H>JF*@$GD}dq7sp8BPj`l z{D*N)#iUCg)y`j2ottJ$Ph~tJ*pVNQK>R#s#wHH7N%EpRz3%)IM= z8~?dq3lT{%)KapW6Ov6t)EV+wQ~fm!v91a*LK|i5YN*M9kXDX`g_(4HVqp$?gH={U zD#cop`zd4`M_DfO;5boP59gg!qePioRVO*P%&oZ7Lx#=GEtoG!7p@=dlBNsy46e=6 zh1Y4YSte9EvuP*j^UeA{hvTSvD{_%hca^l?f1R@!up^l$Jze@uuW@cyB1fBE5DAi; zR*U3X1v*PHO=TGfkX{daiEF|&LvlDmpSwBmFcCg{#5WAb2@ERU!*znXH z<*C)P`BYr6i_HVh4Zis1lxL%XsGT^>%WzBYtoGaX;XHj7mYE(IsY_%nr!UqHn?l|* zXFY0!pB?SmGg*5M;|}L!=bvzv=z3qSd8{2fjg@CNIDiXYcDSEyFy@b8-TF3mBI~3u zgTT=<%7}z{);O#kO6ft{msy%TMf{^9ecuNPzTA2KV9+|#5`yy>9mTYUoj^pVeaIJe z{N~t=ZLsRvm=~upZF7ZCacR=@MJeZjWnRm%rb_146iAxma{cg4EUmYPAC#)L>@-)r z-CHiaRU-~p_GnrcE+4E>x~V=sYIX9nxTvsuzBnh7*uEspy@R;on^nhc0811Yv{t-6PH=`};9OcC@Ndb=XzW7oQ zJN^2ShDtLD3Bzdj{F)q{;?cV+enZ7|4|L&k%?GIptX$`tG}%-;>l^a==IWXaKCcTt z_avdg{_AGr`^cqGUMqLMg**j_xm5=D-(RPE?$ILgdDp`x_mSo^4Qyhq^$*QEDt1ao zyL83rwI|uh>S*Y@ciN|V8t!*@{4F+{5Jp#ivPct5!Itz@t=}i9(^^_aUS5$I<)$Jx z`N*c?+u}VNw$X{xKlh&u5a2Z3%x{~sx|wDF?VxZ+`ee+57JrZ><*O*SM_R11)}+~7 z$yym#f7fPmpMRIzI5ko$E3#DBY|z!kO*V_cMdL#GK|JInk8h`Ny}zvQ_=rjL^jo+8 z<~N=t|Fvp9uL|_s=-9s3jr?Rvx7~pkX4Gwah8IiM+`0K7E=(p2`ASxD*wyNP&c6R3 zyFc+|c~`B@Ox;zTgaW_!V|l(~7Bi93BfhQo;bfqfwnYr75uLW?V)9@JDzA&Yz{%HU zG@X&nuxWtEEZoBQ?Ys}i)|_OKQv(GX&K>~UUF>Fs{JXsx#DV9D@bm)gP68oi@uxsw>Nsa}D!dr^ElwVWXC-gtgDJ4D%J$CT6k4iHUeU5f|?!MJ;?joHme$ zG&=jNvE2!Ss@wp{;e+>3&R+m}8wf97rq07j}}o8e6RzsCh`*%r4O?MF&~PvPyRol!6; zW;T06m@0a1p7olC@sMh4f34h>jH5w>RezxU!kE9PB@8?z!St($fIrx84F+WUV;pB3 znmR9tcEMOUeT8O86+Lj2RD7<@&DkgP`f>wZIt;f*UcqR!3hEQ?BU>HWZv9(l$c6AQ z-E?J0Va=he?qc)s)YN5lSzdZBc z!Z%$~=_1&2m)X7K*vG;#*K;I=w!q@Rz>aI7;`%eReefnDzWY;;O)4>&Qd$Wpd`al- z!UCaom9OMcesUE0Xf&hyPemS=)T7}KllVPaVhy|P2IHQB%S6K#TkW1rM{7Ixq0@sV zo@GTataT4W>;f_v`mP7pX>IW&{}Y;h!*3IffXULk?(uN9sYy5gZ)nd(#(TAbPj=m_ zO;nL8Ck(;&Cr+{HIKjWGQpYlkvh*M3+O^|5)C4$+VXb;ju^`0$GrX1KW@$UF?)ZKz=Rcb2TgG?C z1<4oj$!jJ2i*;xj53sxLpWf!GN0fxdW`}3pEH`=HA!O+U5`O=XSua1k%Wku9&-|4@ z5D`iz&;k&}zT}YU(|xF;@^tSUDp!x+@{Z85ROPl+ZRj6{xM7x*BdmujomiaD)S)*E zNX4!XggJ!bs1JZQE;%d(Irz8`R(c5S?OI)^WedKDBh5&+mSY26a5J8b7cEYAit9V} zZt@ewrt*MdA3Xc+=(T)TI??dG?qnF|aMZg=inM!`g|NSp;==|@*2Uhz->gC5F1+>n z7#*Ku#Wa2~Y}`1gA6K3Hbof5$tWrVA%|~waz*>Ad3u5$*c@HzsnGjs z?X4do=K2}$aY{5sy6;q0pIIVf8cJ!oVIP=a5J9eG3EN<$7VaNnw$Q_vRGh>68L!zG zS>AEBDPtE|37b`#>Cv9#oO;VgZkP5Z>3Tk5eBp@Pwdppy>inHi%gvYxKwupSy2UpN zRT!2Yn#;)CF4%fRqPC+HBql)v>!)F+UrU1O*$FA;E{?2oWBs(Q zexc_S`Arq6z^-M`slj5+r&dv$X4Nt)ZzT2N#)(5avU}ooV(n5?p5`otrqx(5QoMTS zeRq3n|KcSWe4;rFal}tH+72>KEc747dNTH6sNm@>a?^MQ82Mm)`6~LR!iD|C0uAn^ z>mMh6?+*a&+PS^Gj8nUN*nNSwm=GNi$<~Z;HN1K7Ak!cdB{apC*21?=85w8i%9nFv ziZ_YxYrUjXfL*M?VOL*2Ppm~g-8E~@>SMgBwN0X0Azpv=>^YiaWd0AkL(xN+lry8~ zffN##+BJwVh%SsNA5lPMvqQvBqIaiY2@_s+@pk@MMP?|rT)4QjRBoUZY3FOrDb8Xl1_wQJthZ7#a$=q)vS6If z1(Br8mIM)ZP(Yg1+Vavi392D}l6*}ue>(1#AqMA|XlVDhZ86@gzFHp#8+8i4h((`9 z${S|Q6jDz)*f=-OwJ&pL%@3>fr9p4(&gz%vW&AUHWahj+_|#G!o`)oEna%-oTxnl; zZ+H{+COSWK7id5J{8TY^KjyU8Qm{PFmRd0pvQM~b?r0~fbMK>BxRYz{qDgOxqn}Uh zt8<}KwkUeTo^b9+X<0c@6GIRUAAutTA3o_a2K5IU1VV9_5jeog7&Kaf7upQ zs5yt09uNQma2asOz|5eodYq_Myr>HafSxcHmw<_x0FNmj&|Clr;pXDu1)B45LU?%i zIR$`RoTj3}Tzo*F0KX{@6qS8v!o?#1H8+8nfS{%z2#AN*oR3G;fJ4>Z9*Gi``A4f> z^?!oS{9N1|YF6$j!5M*nE3LVv^Gr%2HNm9lD?(z5&-|WrFZ#c5k@IhqbHpzH81UTX z*>lv-Q_F83^oncLFAb2tC6yXY+Ka;nOycQB#hSyno3q-Gc$@MF?6(az>6G@~4w<9zn$d`w z(sm2?p9v3FySG>nco%y6(g_bO3JQX8mf5|(RyVpdxuS1aR~VzVNTW9Sqqd(bZqO=j5h`wSD{j9Y*8M`FIxJNuDOg>OFSbh&aju((mYvcTT4T2?s4qT7Gv&O#HNk{#~^A$%cmkOqm6gI z)TcDwLmo||O4m$c>uBC19M^QMYtwf@xHpV}>5t$G8Xt^o535a`Ij5A{^{{m2WObdl zMieaH@V4&WB8W7hJX7YVIY9^M#Q)F^b`psE_nZ_cO`N}44pf+p7@qZKn++?Q4YHe! zI+*pNoDI!L>15v@fbEY^4MCMIA@-LhMwg~OI4d7;){Jphm2uV`qE@80fLSjny2mLx zD=B(U(%VAQyZX~RzUlYvrnjf0chAaa*&_s^&%~4YfQP{^ntDp!O-2sA!80UrXZ7EWGU9U@c*3cNvEv%G>U zVaRD}c#~j(SPXPEcTeXlw~aAe1|gz^9i2=->Q}4V)j(>j)&BTorNHB9dtesk>X8R9 z>(y#jAutPTb@yws9E&&SV~-~=ub3*Lo;8n)xZ9I1k88TuGlS0+ly?fFD?dGbd~%Hd gP5-}d0tC_oj&y}X%`t&IAYMK$OgcJAB`M7R1uBSB>Hq)$ diff --git a/tutorials/notebooks/GenAI/search_documents/New_York_State_Route_373.pdf b/tutorials/notebooks/GenAI/search_documents/New_York_State_Route_373.pdf deleted file mode 100644 index 69f5c0d86a92401fae7901f98daad7cd7c2361a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 364158 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