diff --git a/.gitignore b/.gitignore index 856ee6b5..b5c79f86 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ __pycache__/* .cache/* .*.swp -*/.ipynb_checkpoints/* +.ipynb_checkpoints/ .DS_Store # Project files diff --git a/docs/examples/.ipynb_checkpoints/pyEQL_demo_1-checkpoint.ipynb b/docs/examples/.ipynb_checkpoints/pyEQL_demo_1-checkpoint.ipynb deleted file mode 100644 index d39be5c6..00000000 --- a/docs/examples/.ipynb_checkpoints/pyEQL_demo_1-checkpoint.ipynb +++ /dev/null @@ -1,523 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# pyEQL Demo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Inspiration: `numpy` arrays\n", - "\n", - "`numpy` defines an *interface* for creating and manipulating numerical arrays. Because this interface is well-defined and predictable, many other numerical codes can build on `numpy`." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 1, 2, 3, 4, 5],\n", - " [ 6, 7, 8, 9, 10]])" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "import numpy as np\n", - "\n", - "array = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])\n", - "array" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(2, 5)" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "array.shape" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "array.argmax()" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "10" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "array.size" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### pyEQL aims to create a well-defined interface for electrolyte solutions\n", - "\n", - "Available methods include:\n", - "- `get_activity_coefficient`\n", - "- `get_amount` (for concentrations in any units)\n", - "- `get_pressure`\n", - "- `get_temperature`\n", - "- `get_volume`\n", - "- `get_dielectric_constant`\n", - "\n", - "and many more" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "\n", - "

\n", - "NOTICE

\n", - "

\n", - "The example below is using a *development* version of `pyEQL`. There are some subtle differences compared to the released version. Specifically:\n", - "\n", - "- The stable version does not support the `engine` keyword argument\n", - "- The stable version requires solutes to be input as list of lists rather than a dictionary\n", - "- The stable version uses `get_xxx` methods (e.g. `get_pressure()`) to access pressure, temperature, and volume instead of python properties.\n", - "\n", - "If you want to try this example, clone and install the `develop` branch from GitHub.\n", - "

\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "from pyEQL import Solution\n", - "\n", - "s1 = Solution({\"Na+\": \"0.1 mol/L\", \"Cl-\": \"0.1 mol/L\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1 atm" - ], - "text/latex": [ - "$1\\ \\mathrm{atm}$" - ], - "text/plain": [ - "1 " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.pressure" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "298.15 K" - ], - "text/latex": [ - "$298.15\\ \\mathrm{K}$" - ], - "text/plain": [ - "298.15 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.temperature" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1 l" - ], - "text/latex": [ - "$1\\ \\mathrm{l}$" - ], - "text/plain": [ - "1 " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.volume" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.9322989671350115" - ], - "text/latex": [ - "$0.9322989671350115\\$" - ], - "text/plain": [ - "0.9322989671350115 " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_osmotic_coefficient()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.0780726282259545" - ], - "text/latex": [ - "$0.0780726282259545\\$" - ], - "text/plain": [ - "0.0780726282259545 " - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_activity(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.10046862144792715 mol/kg" - ], - "text/latex": [ - "$0.10046862144792715\\ \\frac{\\mathrm{mol}}{\\mathrm{kg}}$" - ], - "text/plain": [ - "0.10046862144792715 " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Na+\", \"mol/kg\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.1 mol/l" - ], - "text/latex": [ - "$0.1\\ \\frac{\\mathrm{mol}}{\\mathrm{l}}$" - ], - "text/plain": [ - "0.1 " - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Na+\", \"mol/L\")" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.22962675104721783" - ], - "text/latex": [ - "$0.22962675104721783\\$" - ], - "text/plain": [ - "0.22962675104721783 " - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Na+\", \"%\") # weight percent" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.0018034419870333782" - ], - "text/latex": [ - "$0.0018034419870333782\\$" - ], - "text/plain": [ - "0.0018034419870333782 " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Na+\", \"fraction\") # mole fraction" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### with pyEQL's modular \"engine\" system, switching activity models / equation of state models is easy\n", - "\n", - "Currently there are 2 options: `\"native\"` and `\"ideal\"`.\n", - "\n", - "The `\"native\"` model is built on the Pitzer model and has been the default in pyEQL for a long time. The `\"ideal\"` model represents ideal solution behavior.\n", - "\n", - "**Regardless of what model you choose, all the properties and method calls work exactly the same way**" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.7784212946835681" - ], - "text/latex": [ - "$0.7784212946835681\\$" - ], - "text/plain": [ - "0.7784212946835681 " - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# native engine\n", - "s1 = Solution({\"Na+\": \"0.1 mol/L\", \"Cl-\": \"0.1 mol/L\"}, engine=\"native\")\n", - "s1.get_activity_coefficient(\"Na+\", scale=\"molar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.7784212946835681" - ], - "text/latex": [ - "$0.7784212946835681\\$" - ], - "text/plain": [ - "0.7784212946835681 " - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# ideal engine\n", - "s1 = Solution([[\"Na+\", \"0.1 mol/L\"], [\"Cl-\", \"0.1 mol/L\"]], engine=\"native\")\n", - "s1.get_activity_coefficient(\"Na+\", scale=\"molar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1.0" - ], - "text/latex": [ - "$1.0\\$" - ], - "text/plain": [ - "1.0 " - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from pyEQL import Solution\n", - "\n", - "s1 = Solution({\"Na+\": \"0.1 mol/L\", \"Cl-\": \"0.1 mol/L\"}, engine=\"ideal\")\n", - "s1.get_activity_coefficient(\"Na+\", scale=\"molar\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Future `engine` options could include\n", - "\n", - "- PHREEQC / phreeqpython\n", - "- WaterTAP\n", - "- pyeqion2\n", - "- OLI Cloud API?" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.9.7 ('md')", - "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.9.7" - }, - "orig_nbformat": 4, - "vscode": { - "interpreter": { - "hash": "20cd9c7c08a0db6a75cb79507bbd68d727d0a89c194dd19a90b8f7137b80c950" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/examples/.ipynb_checkpoints/pyeql_demo-checkpoint.ipynb b/docs/examples/.ipynb_checkpoints/pyeql_demo-checkpoint.ipynb deleted file mode 100644 index 3e526a09..00000000 --- a/docs/examples/.ipynb_checkpoints/pyeql_demo-checkpoint.ipynb +++ /dev/null @@ -1,846 +0,0 @@ -{ - "cells": [ - { - "attachments": { - "b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "id": "305d1216-9791-43dd-8d7f-ec90aa72a307", - "metadata": { - "tags": [] - }, - "source": [ - "# `pyEQL` Overview\n", - "\n", - "![pyeql-logo.png](attachment:b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png)\n", - "\n", - "`pyEQL` is an open-source `python` library for solution chemistry calculations and ion properties developed by the [Kingsbury Lab](https://www.kingsburylab.org/) at Princeton University.\n", - "\n", - "[Documentation](https://pyeql.readthedocs.io/en/latest/) | [How to Install](https://pyeql.readthedocs.io/en/latest/installation.html) | [GitHub](https://github.com/rkingsbury/pyEQL) " - ] - }, - { - "cell_type": "markdown", - "id": "90c14b65-36f0-4bb2-a3bf-f8e725cc897e", - "metadata": { - "tags": [] - }, - "source": [ - "## Installation\n", - "\n", - "Uncomment and run the code cell below, if you do not already have `pyEQL`" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "abb1f51c-38fc-4543-8b59-057b8c591ba9", - "metadata": {}, - "outputs": [], - "source": [ - "# pip install pyEQL" - ] - }, - { - "cell_type": "markdown", - "id": "112bdcee-502c-4cb4-8e48-80f23aee844c", - "metadata": {}, - "source": [ - "## Main feature: The `Solution` class" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "55f1aea5-a5b8-49b8-a8e8-20856c4be6e7", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "from pyEQL import Solution" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "c7193cc4-0830-461b-979e-49be9fabfe3f", - "metadata": { - "tags": [] - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-07 11:18:03,638 solution.py _get_property 2084 Partial molar volume for species H[+1] not corrected for temperature\n", - "WARNING 2023-11-07 11:18:03,648 solution.py _get_property 2084 Partial molar volume for species OH[-1] not corrected for temperature\n", - "WARNING 2023-11-07 11:18:03,922 solution.py _get_property 2084 Partial molar volume for species Mg[+2] not corrected for temperature\n", - "WARNING 2023-11-07 11:18:03,951 activity_correction.py _debye_parameter_volume 231 Debye-Huckel limiting slope for volume is approximate when T is not equal to 25 degC\n" - ] - } - ], - "source": [ - "s1 = Solution({\"Mg+2\": \"0.2 mol/L\", \"Cl-1\": \"0.4 mol/L\"}, temperature=\"20 degC\")" - ] - }, - { - "cell_type": "markdown", - "id": "a74a8257-7312-4c93-a89a-4a521009217d", - "metadata": {}, - "source": [ - "### Bulk Properties" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "d3155177-a702-403a-9833-210ab2fed820", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1.0138757383570756 kg/l" - ], - "text/latex": [ - "$1.0138757383570756\\ \\frac{\\mathrm{kg}}{\\mathrm{l}}$" - ], - "text/plain": [ - "1.0138757383570756 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.density" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "9aac5f2e-b7fc-4d72-ab17-0f5b40f683b8", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-07 11:18:04,061 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-07 11:18:04,079 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n" - ] - }, - { - "data": { - "text/html": [ - "3.299995263108893 S/m" - ], - "text/latex": [ - "$3.299995263108893\\ \\frac{\\mathrm{S}}{\\mathrm{m}}$" - ], - "text/plain": [ - "3.299995263108893 " - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.conductivity" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "a2caf642-26d9-42cc-af85-262736f3107d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1 l" - ], - "text/latex": [ - "$1\\ \\mathrm{l}$" - ], - "text/plain": [ - "1 " - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.volume" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "bfb9d952-dd03-495a-9bf7-639a5d5ec683", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1 atm" - ], - "text/latex": [ - "$1\\ \\mathrm{atm}$" - ], - "text/plain": [ - "1 " - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.pressure" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "ce4a3e73-3a4c-4674-bc90-9b679f18ca95", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "293.15 K" - ], - "text/latex": [ - "$293.15\\ \\mathrm{K}$" - ], - "text/plain": [ - "293.15 " - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.temperature" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "7895882f-31a7-4817-ac52-66494723373c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1286752.4185332006 Pa" - ], - "text/latex": [ - "$1286752.4185332006\\ \\mathrm{Pa}$" - ], - "text/plain": [ - "1286752.4185332006 " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.osmotic_pressure" - ] - }, - { - "cell_type": "markdown", - "id": "17992986-53d2-49cb-9200-b93706d066a8", - "metadata": {}, - "source": [ - "### Composition" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "012154b4-7de9-4484-973f-30a28d96d92a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'H2O(aq)': 55.221652761186476, 'Cl[-1]': 0.4, 'Mg[+2]': 0.2, 'H[+1]': 1e-07, 'OH[-1]': 1e-07}" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.components" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "ccd6cc51-c3d7-4980-bb9a-abacc47f7108", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'H2O(aq)'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.solvent" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "4251a60d-58f4-4083-8c67-f0bc3813c70a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Mg[+2]': 0.2, 'H[+1]': 1e-07}" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.cations" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "e25db309-a041-4e5e-bbff-9a7bf4c11c94", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'Cl[-1]': 0.4, 'OH[-1]': 1e-07}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.anions" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "2a8c0a98-9bef-4c42-9eb8-84bfffb087d1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'H2O(aq)': 55.221652761186476}" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.neutrals" - ] - }, - { - "cell_type": "markdown", - "id": "a0a74dc8-f48b-41fa-8e62-106d8e2e56d5", - "metadata": {}, - "source": [ - "### Species Concentrations" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "3e1201bd-d509-49ae-84ec-b1af704a9902", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.20000000000000007 M" - ], - "text/latex": [ - "$0.20000000000000007\\ \\mathrm{M}$" - ], - "text/plain": [ - "0.20000000000000007 " - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Mg+2\", \"M\")" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "d4fa6515-ccb2-44e4-bb30-fb9f9bff6a99", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1.3987118404647676" - ], - "text/latex": [ - "$1.3987118404647676\\$" - ], - "text/plain": [ - "1.3987118404647676 " - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Cl-\", \"%\")" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "2656ed7a-27c1-4c02-9d8c-b8db62c1ea3e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.4 mol/l" - ], - "text/latex": [ - "$0.4\\ \\frac{\\mathrm{mol}}{\\mathrm{l}}$" - ], - "text/plain": [ - "0.4 " - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Mg+2\", \"eq/L\")" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "ad9cd84e-ae7c-406e-8360-4518e112e0d7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "4886244.60412788 µg/kg" - ], - "text/latex": [ - "$4886244.60412788\\ \\frac{\\mathrm{µg}}{\\mathrm{kg}}$" - ], - "text/plain": [ - "4886244.60412788 " - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_amount(\"Mg+2\", \"ug/kg\")" - ] - }, - { - "cell_type": "markdown", - "id": "1bbd0fcb-c145-48d1-a917-c77ae2d9e7b3", - "metadata": {}, - "source": [ - "### Transport" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "be744f20-22df-4e46-ab48-2fbd8a63cdc2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.0" - ], - "text/latex": [ - "$0.0\\$" - ], - "text/plain": [ - "0.0 " - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_transport_number(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "8d849212-aad4-4b95-ac3a-572346b0a6fd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.40998795156327783" - ], - "text/latex": [ - "$0.40998795156327783\\$" - ], - "text/plain": [ - "0.40998795156327783 " - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_transport_number(\"Mg+2\")" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "d467b3fc-032c-4a90-a102-7ad796723629", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.5900109897851136" - ], - "text/latex": [ - "$0.5900109897851136\\$" - ], - "text/plain": [ - "0.5900109897851136 " - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.get_transport_number(\"Cl-\")" - ] - }, - { - "cell_type": "markdown", - "id": "f00b0f7a-ef35-45d4-8e81-26ae48733096", - "metadata": {}, - "source": [ - "### Speciation" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "40da1bdd-6c43-4d22-a648-03bfdd69e88a", - "metadata": {}, - "outputs": [], - "source": [ - "s1.equilibrate()" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "3e3ce899-3907-4e07-ac53-205c4a3ac31c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'H2O(aq)': 55.238455538403954, 'Cl[-1]': 0.38323989957700755, 'Mg[+2]': 0.18323990520853942, 'MgCl[+1]': 0.016760093825573405, 'H[+1]': 1.2403230417432767e-07, 'OH[-1]': 9.844314720800745e-08, 'HCl(aq)': 5.431780489909693e-09, 'MgOH[+1]': 7.932661202804441e-15, 'O2(aq)': 3.1477649388058775e-26, 'HClO(aq)': 8.450946375546259e-29, 'ClO[-1]': 3.367672345557701e-29, 'H2(aq)': 5.442728186726209e-35, 'ClO2[-1]': 0.0, 'ClO3[-1]': 0.0, 'ClO4[-1]': 0.0, 'HClO2(aq)': 0.0}" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.components" - ] - }, - { - "cell_type": "markdown", - "id": "1a271802-e715-4505-8e86-e987f257def3", - "metadata": {}, - "source": [ - "### Saving `Solution` to a file" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "id": "d76cb8ab-facc-4a6e-9a3d-143730d2d5cf", - "metadata": {}, - "outputs": [], - "source": [ - "from monty.serialization import dumpfn\n", - "\n", - "dumpfn(s1, \"test_solution.json\")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "fd9967de-0881-4c68-942f-b56da4033701", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'@module': 'pyEQL.solution',\n", - " '@class': 'Solution',\n", - " '@version': '0.9.0.post1.dev3+g22e5c4a',\n", - " 'solutes': {'H2O(aq)': '55.238455538403954 mol',\n", - " 'Cl[-1]': '0.38323989957700755 mol',\n", - " 'Mg[+2]': '0.18323990520853942 mol',\n", - " 'MgCl[+1]': '0.016760093825573405 mol',\n", - " 'H[+1]': '1.2403230417432767e-07 mol',\n", - " 'OH[-1]': '9.844314720800745e-08 mol',\n", - " 'HCl(aq)': '5.431780489909693e-09 mol',\n", - " 'MgOH[+1]': '7.932661202804441e-15 mol',\n", - " 'O2(aq)': '3.1477649388058775e-26 mol',\n", - " 'HClO(aq)': '8.450946375546259e-29 mol',\n", - " 'ClO[-1]': '3.367672345557701e-29 mol',\n", - " 'H2(aq)': '5.442728186726209e-35 mol',\n", - " 'ClO2[-1]': '0.0 mol',\n", - " 'ClO3[-1]': '0.0 mol',\n", - " 'ClO4[-1]': '0.0 mol',\n", - " 'HClO2(aq)': '0.0 mol'},\n", - " 'volume': '1 l',\n", - " 'temperature': '293.15 K',\n", - " 'pressure': '1 atm',\n", - " 'pH': 6.90646518824501,\n", - " 'pE': 8.5,\n", - " 'balance_charge': None,\n", - " 'solvent': 'H2O(aq)',\n", - " 'engine': 'native',\n", - " 'database': {'@module': 'maggma.stores.mongolike',\n", - " '@class': 'JSONStore',\n", - " '@version': '0.57.4',\n", - " 'paths': ['/home/ryan/mambaforge/envs/pbx/code/pyEQL/src/pyEQL/database/pyeql_db.json'],\n", - " 'read_only': True,\n", - " 'serialization_option': None,\n", - " 'serialization_default': None,\n", - " 'key': 'formula'}}" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.as_dict()" - ] - }, - { - "cell_type": "markdown", - "id": "7175594b-e6ab-4779-b4ea-a21265337f11", - "metadata": {}, - "source": [ - "## Units-Aware Calculations" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "0a4503fa-d37f-43b0-b62c-093fe1d3ee56", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "1000.0000000000001 ml" - ], - "text/latex": [ - "$1000.0000000000001\\ \\mathrm{ml}$" - ], - "text/plain": [ - "1000.0000000000001 " - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.volume.to(\"mL\")" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "4b3c06c0-a73d-4ba3-8ec4-8d196867208c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "0.26417205235814856 gal" - ], - "text/latex": [ - "$0.26417205235814856\\ \\mathrm{gal}$" - ], - "text/plain": [ - "0.26417205235814856 " - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.volume.to(\"gal\")" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "c086ca8f-cdd7-4698-94e0-d7de1f5abd79", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-07 11:18:04,616 engines.py get_osmotic_coefficient 462 Cannot calculate osmotic coefficient because Pitzer parameters for salt HClO3 are not specified. Returning unit osmotic coefficient\n", - "WARNING 2023-11-07 11:18:04,621 engines.py get_osmotic_coefficient 462 Cannot calculate osmotic coefficient because Pitzer parameters for salt HClO2 are not specified. Returning unit osmotic coefficient\n" - ] - }, - { - "data": { - "text/plain": [ - "12.630074635540739" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.osmotic_pressure.to(\"bar\").magnitude" - ] - }, - { - "cell_type": "markdown", - "id": "e42ec30f-eb5f-4f0f-89ce-332288e03db4", - "metadata": {}, - "source": [ - "## Contribution Opportunities\n", - "\n", - "**Benchmarking**\n", - "- Compiling additional validation data for activity, conductivity, etc.\n", - "- Quantifying error associated with different models\n", - "- Refactoring unit tests suite to separate benchmarking\n", - "\n", - "**Documentation**\n", - "- Writing tutorials\n", - "- Writing expanded docs\n", - "- Cleaning up / updating docstrings\n", - "\n", - "**New Features**\n", - "- Better viscosity model\n", - "- Expanded unit testing (increase test coverage to 90%)\n", - "- Additional properties\n", - "- Additional mixing rules / models for mixed electrolytes\n", - "\n", - "**Database**\n", - "- Expand database doverage to include additional species\n", - "- More viscosity coefficients\n", - "- Add 'sho' parameter\n", - "- More diffusion coefficients\n", - "\n", - "**Software Engineering**\n", - "- Additional refactoring (e.g., `mypy` linting for robustness)\n", - "- Bugfixes" - ] - } - ], - "metadata": { - "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.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/examples/.ipynb_checkpoints/pyeql_tutorial_database-checkpoint.ipynb b/docs/examples/.ipynb_checkpoints/pyeql_tutorial_database-checkpoint.ipynb deleted file mode 100644 index 187b5e9a..00000000 --- a/docs/examples/.ipynb_checkpoints/pyeql_tutorial_database-checkpoint.ipynb +++ /dev/null @@ -1,1270 +0,0 @@ -{ - "cells": [ - { - "attachments": { - "b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZkAAABkCAYAAABU3k29AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAR5wAAEecBLFYGiAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURBVHic7Z13mBVF1sbf7q6qvmkGBhB0FUUxLuaEAVcQw2JAUQdXUdYIhjXrqru6ez/FtLrmBAYwKyMmTCgC5ohpxTVjQgVJAzd1VXX390fNrKMyt++d6b6xf8/TDz503apzx6FP16lz3qOhTGz77oqdNZcab20VeQma5pbLjl/guvrg99O7Oy4WvbVV4r1ymxMSEpKXAQC2B7AugP4A1gGwNoAEAANA46/GtwJw2v78FsDXbX9+CeDNtv8O8RmtHIsOefn7tXWNHGcAOhx7gUD0/pd36bmsHLa0M+L1zxqzMn6YBn1t6IbgDia+MmS178tpU0hNsgGAT8ttRDfZFcCLZVh3fQD7t62/PYB+Ps//A5SzmQ3gcQDzfZ6/q1wA4MI8998HsGWJbCmakjuZobPnR2K2c7rrar1011Hru8hprt3yxB83er/U9gDA/jM+728Df3Y19Gz/O1fTF67VtO41k7bVRDlsCqlZQidTHGsDGAdgFIDfl2jNdj4A8AiAWwEsKPHaHalqJ0NKveCGDUvspQsi8+E6a6i/caC5jqkBxzRPe2fmoAO3eiKpaU6p7Gl++N09tJUr9nUN6ADgaroLTbPh6q9M2iN0MCEhZWJHAKcBOBBleE61sXnb9TcALQCuBvB2mWypWsoSLgOAwx94YwvdkWNd10no7ca4rqZp7jfSJpPuHrvzoiDXb546jzXkFh/h6NpgAHDbzoVcV2vViDbxzj/t/EWQ64fULeFOJj+bALgewPCA5u8uTwA4Feocp1RU9U6mbE4GAI657ZleTMPxrutuoNmuBqBtO+FYgDvlxuP3ey2IdU++7qnVXNM52XG1dTRNc/+3bTL0/1qaddMdx+y/Moh1Q0IQOpnOMAD8FcD5AGI+z+03KaiH/r+hEgmCJnQy3aG5eaoxYGf9ABvOgZqraZrraIALHYDrui/naI/brj9lb8uv9c65aupmjuucomlIOAA0zWhzMs70b17Vpra0jLa95jhw2kdrZHqYo6xIbDE3G5bl4tqHc38f/8EvG0NqmtDJ/JY1ADwIYBcf5ywFLwI4BMCPAa9T1U7G11jn1nNXbhLjuX6xnNWH5dLLnhix0fNen2lpGW2jBdMuuGzyp5rEqZrmNgEO2nY2wxNaaqMJE2779/nnH/t1N83T/m/CpAPc1IoxgKu7Rnt4TLd06Lckzz+y4H80pptdTeawgauTdWwjJzTR8ANUZkpISEhxbAngUaj042rjDwBehUpKKEvSUjXgq5OJALuYtj2AihyjlrUAgKeTaeeic4/6z2XnTDxTM3JnusDWGhzAATS4A+G611xxzlVTzr78jMe6YlcymYzEcz1PdVOpP2hQ4TFX1wFgocvoxeclTywqvkq41cSIYTicEptSh2cyqa7YFRJS52wHYAaApi5+XgL4EOow/gMA30C97H0HIAtgZdsYAKBQ9TMxqJqa1aEy17YAsC1U5lpXnofrQqU874kwKWCV+OpkGM+2GrkcoZwbVFhF57Cfe/n4VgD/vP7UCaMBHAXXNdQZjcsA9+SbTr5wC9d2rjrppmTBD/Ubz5jQHz/JC6GvWAsAHE2DOodx34FjX3LK9ckVxdppilxPmxvENqhj5wwSb0yEZzghfjIIwEflNiJgtodyMD29Bv6KFVCH7w8DeBpApsDPCQDL2q5VpSMnAIyA2pXsC6ChCJuaADwHYC+oOpuQDujeQwqHCLmcSWFQkSMRIXoeOXl2pAvTuCdfe/6DZqb13Ghm5YpYJsWimZVm25+7J6zUxHuPPHuDQiaafOTZu8RbWyfFcumBscxKM5ZJs3g2TSPZldOWNtl/64qDAQDKeS8quEGtHGHSMpYbDV2aJySkThkA5SCKcTCfAPgLgDUBjAEwDYU7mEJIQaUpH9a2xikAPivi8z2hvtO6PtpUE/i7k8mmllNuESqEQXiORDJiNXRRqmHcrVe8N/mA044xo+ICHe7OutuuPOOuD7h3TPvT+BsOfGDiVA34jSRNMpnUN/3o+xOcXOoIwNUAzXU0DYCb1TRcfMh9N8/sxteEwXlvRghxdOI4nIq5YcFmSEihxKGq6XsVOH4hVNbZ3VjFv/WAWAmVRn0DgCMA/AuFqQv0gvpuOwBIB2ZdleGrk9G5XGpybjBuESa5EZXZvuiGHtBRj16z3AXOemL/sYdqcE91XZdpcKE5YC5w3lP7Hrrjczn5zz1mtrS2f+axkUc3GG9/egmg7QIdLqDBBeBo+nym6WeMeHTKV939nlTy3i4nhtQJYYSG5zEhIYVzLYDNChw7HcBRAJYEZ05eXAB3AXgKwBQA+xTwmU0BXAfgmODMqi58DZdFqbuEcItQzg3GuUGc3OrdnVMD3P0eu+u+WC5zdDSdWhhLp1ksmzLjmRSLZ1J7Uif3yPO77Lc1ALzwh303aFy5uCWeSQ+PZ1Msmk6Z0XSKxTKplxpbs2P9cDAAYFpWH0PkCJPcMHh46B8SUiC7obCHrwuVsnsAyudgOrIYwEgAF6Ow3dTRqNxi0pLj605m0Osty79bb1eXCW5QbhHKRbedTDu7zZg2b/bQoQdHcsbFuoZ9NNeF60LTXHcdwH3gzcHDZiOX2snVdFXIpWuuC81xoP17x9eem7SqsFpXmDhuIv1eip6SG9I1csQ2aHgeExLiTQTAxALGOQCOBTA5WHOKxoEqFJ0PpWXmVWN4C9SOLRewXRWPr04mmUw64297tpWKXAMTlkF59nd+zj9szpwUgFM/3Hzwiy7cS+EiqsEFHDRqmnuMq2kWgOUONAea1mrAPWXQB2/O8tOGFY0rmgzeQE1Ddx2DOlJPh04mJMSbv0CpKHtxDirPwXTkdqjzmYs9xq0PlTzwr8AtqnB8DZcBALWySxnnBuGcMM59dTLtbPrBG9MaMqlDYpmVP8bSKxsT2RWJWCalxVIrI9FMqjGeTi2IZNPNfjsYACDS6W0Ky6CWRZjgRkS6rd6fCgmpaxIAzitg3BQAVwZrii9cAuCeAsadi+JSoWsS351MRPKfCLeIKSyDcL5GMpn0fQ0AGPD5R+/GU0uHxrKpB6LptB1Lp7RYNuXE0ulH4uklwzf87MP/BrGuaVt9CLcIFZZBrRwxhFULToYBGAglF7I7gIMANLdd+7X93WYAzHIZGFLVHAnvbLLPoN78q4WTAXzlMaYJ6nymrvFdQlvP5Zb8vJOxaL9W9AEQiKLy6gsXpgGMT/fo9bbt2DdCx5UNra1/9+v8ZVWQXKYv03XDNgixDepYVnZ5UGsFhAlVCLcrgCFQzmMNFKZj50B1E/wQwBtQtQof+2DT9vCWFZmF8h8CH4T8L2ZZqELBkJ8hAM4sYNzpUKnD1cJyAGcBeMhj3BkAboIqBq1LfHcyVMhFVFiEcctgnBtcrFgTATmZduKtS291gae0EjQWMqXs4wiL2IQ4tmGQGJyydvQsEB2qGnk0VMZOsVXWHedZt+3aD8AEAC9DhQ+e7oZ9WwCY5DHmHJQ3vr09vB8o9yN0Mr9mb6jiy3zMAPBk8Kb4zjQo6ax8mWRrQykIPFISiyoQ/89kZHYRE9xgghtEWCQi7DX9XmNVlMLBAAARub6Uq+w5JqQOLFxainW7CIParv8XKtf/SHTdwXTGkLa534ZqjdsVWuCdhXNoF+f2izEFjLk7cCuqj+YCxuRTGK50LilgzOjArahgAjgvMX78+SHMDcpza/m/RvkwOe9nCrVLoyKXSSaT0vtTZWEwgHehsmE2LMF620Cp6c7swnrLoSql87ElSt9+tx0CJemej4VQ+lUhPxOH6myZj1fbrmplFryFMQ8A0FgCWyoS351MMjk+QwVPM6Eq/ykX/f1eo5xQYfUjnBMqLYNyXqnnMecBeAXleSgPh3JuRxX5uUJ2AeXazewOb1mR+/Gz4m+IYi94NyC7qRSGBIxX/U8ESnyzLgkk84tyaxHhOUKFZZjCqi0nY+XWMIXVtlOzKu08RoPSW7oEqtNguYgBuAOqJ3qhjfGegffZ3aFFzOcnYaisa+zhcT8NpaZc7bQA4B5jvH4WNUswTsayFpqCq1oSzgcEsUY5eHXH5igToifhFmEWN6jFK83JnAbgpHIb0YHTANxc4FgJtRvIx0CoMGApiUOFO/IxD8A7JbCl2hjqcf9ZqIy8aqcVKmyWj11LYUgl4nt2GQCY0vqBcK7OZESuz+yhQxNt1fpVTURb0peLGGGEONIgxKTG4nLb1IEtAFzehc8JKKmMjwF8AZVGuqLtTw0q178ngI2g1GWLlQoaD1VPcFkBY+8CcKrHmEMBvF6kDd1hf6hiwnyEu5jf0hfqdyYftZSJNx3AH/PcXx+qVKDuOugG4mSIlfuBCctQB/+cRNP22qiBJkxOKrO6mTAM2zAIMwzH4aSSdjL/gur+VwgLoNIvpwN4AcXl8K8HlTE0HoX3zrgYqpmT19veO1C7gkF5xhwCVXdRqvMPr1CZA+DeUhhSZewM79DmC6UwpEQU0r59CFRora4IJFxmOvb3jFsGFZxQzg0is9XYv/s3RKVcXdUAKefJhKyUncweUO1fvWiFkrpYH2rHMBPFF4l9CbVj2hDAiVDNnrzQofSoehQw9i6P+/1QOoXbvvD+uc6Gavcb8ks297j/A9TOuVaYB8CrnMHrZ1KTBONkUnyBcjCWQYVFiJQ10S3OdKzVVZGpKjbVMtlKcTKFhKLmQf2SXw5/lGEl1HnLVgBeK2D82ihMv+peALbHmFJlmY2G924/DJWtmo097r9REitKhwvvVOZNSmFIpRGIk9lrx/UXUs4dKizChGWY3KqJnYyRE2tQzg0qLINyTiJ29qdy2wRgJwBbe4x5G2qr/k0A638OYBcUFjI6GYCXaOoCeIfVRgGIFrBed/EKldVKdlQQ5At5AsD7JbGitLzncd/rZ1KTBOJktGTSodxayCwrSjnvwSxrvSDWaWMggHG/unoHsRDj2d9RbjVQkYua3MLwXmYl7GS8mkBloB6WQdb02AD+DO+CyhiURpUXXruDRiipjiBZH96ZbI+iuvS2SoUOYAOPMZ+XwpAS4/WdBqLwc9OawXcnM7W52Xh1xz1GUWFtTIW1GuVWnAm+hd/rdGAwVDFUxyuQ2hwm+AZMWAlmiT5U8n5vLGg95rndmws5ZwgKAm/ZjqsBfFoCW2yoAkyvdtvHwLtA72F4n/UEHTI7DN4H12GobNWsBlWAmI9S/E6Wmk887lOoDLO6wjcnM7X5xMSMEaOP7rco8xyxxb/VGz8HExxU8AFueYsDfYFyaxMmBKjkIEJQIqxzTZ5+6dk9D77k4VFjSyHd8msGwbtfhVftiZ8shbfibhO8HUQhYai94b8OW0e8QmU/QCVOhPwWL3UEQKXN1xqFfKdCfjY1RbdTmCeOG9ejaZl2cNRacRgRfHUqBKNC6EwIh3KuUW65lHMB9cP9vvsmlw8quSsFdwilGhXClZIbVLCooOIAU8gR0w457uVMNDH1iwE9Xkkmk04JTNrW4/5XUAf+pWQaVCuATfOMOQRKUy0fdwMYm+e+CSW97zVPV9gO3vpr98E7QaFe8XpblwAqIdTsNwuhEgDy7YB9a0lfLXTZyVx9WnJAj1RmTCSd2ZM6mTgTnFEpDSK5QSU3DMk5k2IOkfLKRGr5M5qqJ6hq4unUGstodCsmxFhB+IFEEIMQblBBHUkEIVzsRA1r2/7fpBfddMqF09Ms+vjZV54dZJuDtT3ue4WugsABcB3yS/cPA9AH+R80s6BSg/MJrB6GYJxMITIyhXRGrFe83tYXI8CeT2WEQ5UJ5Nthh07Giwl/v277RC4zKpZJb29IYVIhKBWWQQQ3COcGFUKjQswybHHzGt9/XcrK7JLQtPynd7Ec736x3npJwsloSsRYScTqgnKDCGYQKgzTFr1tbo2hunHwZX+/7q20GXn8on+Mexv+/8PySnAoV3XxVADXovMMMAIV7spXE9Ne5HhOnjFDobLV/NwhEwB/8hjzH3hnEtUzXr+XtbiLaecn5HcygSQlVTIFOZnm5qnG+tvlhkQzmZFmLr0xFYIZghMihEFsYVAhDCqlS6V4nIjsbRt9/F4grY8riYFfftkK4NYkcPs+2w7bkQgx2iDWUCqoIQk3CKEOpYxIwbcxKd3sb5fd+U02Fn/O6Nkw68qxe6V9MiPucb9culCtUE3M8sm8D4d34eVdyO9kdCiHcFVR1uVnOLzfxIM+8C91iDMfJ6F4pWSvNt2Vql7uB17t2L0SImqOvE6meeo8tvqyr4ea6ZX7kKxci9qSUiHUrkVygwmhU2FlDCkmw7anbvfm7EqoGykpScBJvj37FQCvvLDn/v1twQ80KN2HSRGTghuSUMMW1KCUrimFGJNN8/2OnTLr5SyJzbr38B1quVJ8BvI7mT2gYtf5dncfQRXt5UslPhz+Opl850CAOk+408f1ahGvB6mXYnE1Y3nc93LANccqncyYpz5rNFp/HB5t/W6YIXK9mBSMCaETYRlUcIMIbjAhlhCbP0Bz+uO7P/eIX2/mVc2uzz72LYBrpzY338y4OcQi1kGEso0MoXZ7wuAO4TxOKB1GKN159LS5X2RisZdSkY3fmjNMq7VeJLM97q8BYB2o5IR83If8TmYrqEN6P1Ji4wBGeoyZjYDbidcAXg/SWnYyXt+tvncye874vG+cW3s4K5cOjnAZpbZkhHPDEPx/YTEixTdM8pYVcf78ofdOLlb3qi4Y3dLCoQ6uZ0066bwNpSAjpKC7UEp1KbkhOTUkYYYkfF1TsDVt+tUew15d+MayKHvjva2aaiWU8BlUSnOvPGO2gLeTuQdK/DPfg+twAP8oxrhOGAVvxeUpPqxT63g5Ga+3/Wom3Mn8CgIAf3gz059mW3czs6nNiLRMagtKpDCItAwmZdvuxZprity08Tdd9GG5ja4mxt146acAPr3q9Kvu5lTsSQ2+myAsTiQ3iKS2wblBKO9JLDYsTiKDt/9v7oE3N4nUSqHaf6HUeDtjUwCPecyxFOp8J19Pl8MA/BPdT6zwyipbCVXlH5Ifr/q7Wswsa8crizYQlZVKhmw3d+Vo8MzmVFjMEJzQttAOFcIwLEvXBX8Xtnz87MvOrKTDyKrjjKvPWArgAdd1Hzz36ns3lRbZVVC2OaNStwU3JLEMIomRS6dr6ZzmI+R3Ml4iiu3ch/xOZiCAbeAtUJiP1eCt7vwolExPSH683uZZSawoD/W8i1slhMBpVW/VwqDSMogUOpFCEslfZNR4ZsKZR9fdYX6QaJrmQqXA/uf4m2f05SQ3xDDo9oQKxrLWx3N3WruWHmJegpxrFjjPY1Bpr33yjDkC3XMyh8FbV2pKN+avJ0In0zn152RM3XmDWtYwdZjPU9ThM2MNiVevPmbPWmiLWtHccsJeiwA8fOTk2U+5zNwWRAShklxOFnrcL7QwjUM1ezohz5g/oXvNzLxCZd8CmNPFueuNenYyXt+t/pzMnK2alu/z9KdvEsmX9kr0fu36vXeoux9CuZly1LAcgJfLbUcAeDmZYsQC70Z+J9MXwG5QfeOLZSMoKZl83IvSqVYcC+DrEq3lxcdd+IzXM8Srvqua8fpudfd8JQDw5IgNy90TQ0PXJW5WJbxJ0HVJbYnaPpgsJV6Zcj3gXSvTzutQnRQH5hkzGl1zMqMLGHNfF+btKq+hutuVe7Ul71sSK8qD13dbUhIrKohKyXQ4Diok0pVrVVXjb3VjvnwH1SHF4fXWpqHwlE4X3kWQzSi+mZkG1QsnH+9AnaOFFIZXHdFqJbGi9BjIn7IP1GGNVaU4mZDapJA2z8UUp92F/CGrRgD7FDEfAGyP/LsjIOwbUyxeD9IIvFtUVCNN8G5pUneJVKGTCQmSQop1iylO+xoqlJSPQkJfHfESw7QBPFjknPVOIW/rXgri1UghbeZDJxMS4iOFhK6KVY2Y7HF/JApvZkbhnVU2A+VTs65Wvod3rx2v9szViFcPIhfeaf01R7eblvnEl/DuhNgZ/fHbzKDn4a2G2hm1LENearwkWoDilaJboPrVdNbCuZhmZrvD+3wgDJUVjwXVJXL9PGM2KpEtpcTrO30L1fU1pMo4DOoNoeO1ZVkt6gLNU99Yd+TTH3uJM/6ayfjtd+94TfHTxi6wL/Lb5yB/F8HOuN9j3kLbIt/jMc8y+C9ouIHHmi6A3/u8Zjl4Evm/4x3lMy0wvH4vn+vivBd4zFvRvY0IADS/+m1ULE39fnn8x/fnDBtWa2rAFUtz81Sj54jegzOR2LBcJNZXGEQMnb3ooznD+n5ebtt8wutw10LX0sXvQ/6zlKFQPWHy1enE4K24/BgKS14I+S2fQDWm64x8ytrVyg4e9z8piRUVBgGAZY6xTYSQUX2WNf5p7D0vvh9b2Tr7lhP2W1Bu42qV6657ypzvpoZZkcTuGUYbbca4pIRLQm07SnYAUC9OpquhyacB/IjOFQMMqB3u1XnmGAVv+6YUbVlIO+973N8EKhvLq6amWlgDwACPMe+WwI6KgwCAgL4dIdS2aYRJJncSscSuf7l5+mexTPrF+a/rb7W0jPY6xAspgMv/enlDtqHXXt/z1j3saCwmKOPCoFwwZnODOpKZNmes36B5Lps3SKuFnhteHSa7KgYqoVo8n5JnzGjkdzJeWWXfAXixSLtCfuYVj/sagJ2gwmq1wE4FjHk1cCsqELLNJ24f2bq8p7RtR0hmE0ltKoghmLkxF2Lz9bfNLJmw6S0zzZUrZ5195dnhoVUXuOGkv69jxXo058zEjpIyh1PKBaFCMGbblNmSElsY9GtLY7Pf2Cr+ETStVPIlQeOVQdSdTJvJyO9kdkDnzcz6Afijx/xeNTkh+fkcKisvn3TQSNSOk9nf4/5P6JpET9VD5m6kLR46b9EVXNCtDUKHUGL2FVTYhhAGZdS2JelrSXYkYebRV59x6dtmNvPMiTdfNLfchlcD94w5dbtMIj4qS6PbSGoKQSmXhNmSUEcyZktiSsHoB1lde27m8HXml9veAPDKtulOW4P3oKRX8h2SjwYwYRV/fxC8MytLKSNTq7wOFZbsjH1RuKxQJUOQ//wJUG3Eq/17dgkCAHMG9U0BeBHJ5Mv77TBmEyHJMMbYpkJygxNmEyptzphhOGInJsTQ24895+toOv0EkQtnjG5pCdWaO+Amk/r097/cOxNJNOcibF2bMC4pE9KgtmTM5pTaklAuKH3F0s0Z00ZuXqtnXya8s/y6K9UyBaprZmf8Gat2Ml4yMm8DCPsndZ9nkN/J/A7Ajqj+MNJQAL09xjxRAjsqkl++zSWTznQk5wGYd8TD7/cVnO9CTDFcStIkKLOpsAxBmU2kWE8wfhaxm055cuRhsyKpzP3DZz36RXm+QmXw6o47Rnm0z8FPv/XJn0Q01lcSygUhnFPqSGraglJbELaCE/KsFmEzpxy+a60L5W0Jb9nz7u6I7wdwGTovKl4fwFb45YHrevBWXA53Mf7wMIAbkX/XeAqq38mc7HFfAphWCkMqkU7/59994BaLAEw7cvLsJykXOxlSjBDU3IAIqVNCbUmZbUsRFSJygGHazS/uuvfcaC77UCrqPjtszpy6SYP+fPPN+y6nPY/K0fgBnLAGQSgX1ORt4TBbUmoLnS6SEfMhrhuzbzjpgHrZ+XlpiK1E93cL30HVHuyVZ8zh+KWTGYv8tTkCqn4mpPsshmphMTTPmIOgCqq/LYVBATAQKuyXj5dRx0XenhX/bb1OZgGYdf5FEwcSSvaXgu0mqTCk4DanxCA2cQRlg4mQu/RoTS37ZOOtHoyvzE5Za8HHNfu2/u1a622Qi8VPSeuxETajkIRwSZiQKhxmC0JsTul8x4zeL8miFyf89cS6cbxt7Odxfy78OVi/D/mdTDOAszusdYjHfDNRh/pSAfIQ8jsZAuB0AGeUxBr/ORPe8lx1vTMuSlZmwgXjvwBw1aXnXjqZCLInp+xgIsVaUkhdUmFLym0pWR8hxWm5iHb6gt+t/Vwsk7mrafni2QHZX3JaG3vtYEXjp6UoHSYIldJgXBDGBWEqJEZN22b0JYeYU0+95u/voj4P+3aG93nMYz6t9RCAG9B5zUt/qIfcLCjF5Y095pvik10hijsBXAzVO6gz/gLgFqw6E7CS2QzAOI8xS1DnO+MuaZedd9l5ywA8OLU5+YgV57txRg8hNt2SUGYTIWxOqEGJ2UNQOUZQcXgq0eP7eKp1sKYK6KqWdCz+YY6QjTilsAm1BKVLJaO2pMTmlNk2pXMsatz959uvrMuiqw6cVsAYvw5CMwAeBXBEnjGjoZyMV23MCh/tClGkoNLB851bUKiztQNLYpE/aAAuh7e0/z0oXp+vpuiWQOboliSHyiB55skDj1lHUDmKEH4YobSPZFSnkhiSMo1LsWZKxeCrGs4iTZyZhqTU5cQ0JDFtQWhKEPaAo9G7D3zo9lrNFCuG7aHi7Pn4EP6qGtyN/E7mYKiQjJeTmQbltEL85QYAJyL/A3kU1K5gUkks6j4nAxjhMUYAuL4EtlQ0vqkw7/Pw7V8DuOa53ZsnG7ZoplxMMCiL60LCoKJ19RpQHxXUnCsZ24dTE8Kkrs3YjQ60O/d4dloYw1dEANwKb9HLG3xedxaABQDW7OR+b6i3znyFgUCouBwUn0IVzx7rMe4aqPTxdwK3qHsMRv7U+XZug2oZXtf43k9mj5ktrUNeee42ycy5grIlkrKcYGZNaHFxZn5gkUjOMtkKQc0f4yuarvvDS0+HDkahAbgJwOYe437CqltmdwcbwL0eY/7icf8bAC/4Y07IKvgbVDgyH1GoF4Ztgzeny2wP4Fl4N9tbAeAfwZtT+QTWtMxirLdgkTQ3zWWCmd2p7PaiBapJVcfrgyAW4ozNFyZrldRsFdS0F60mfhfEOlUIhXIwRxUw9hoEE6P2clxeu6t7EcrIBMlPAK4sYFwPqHOxSnQ0g6Fsayxg7MWo47TljgTiZKY2NzPBWKNgT0ZEIwAADddJREFUzBbMlJyY3wexThsCqkFZxyuQh4XDzPmCMsmpaQvGpIzQtYJYx0e2gLf8eHfZGMAcAMcXMHY+8otWdod56F6Ypa4zgErExShMdLQfVJvtc4I1pyjOgap38WpyB6jdWCEOtS4IxMmYVkMfQSO2RZnNKbMlY0E6mZKRpfRrbpq2YKYUzLRzhHV2BlApbAn1j/UDqHCRnzuvdaE6VH6AwhRoAeAsBJtp09Uw3FwoHbSQYHGgDvcLSa4gUBlnDyN/h82g2RAq3f4yFHaGvQLq7CncFbcRiJMRVO/DKbMFNaWgpm1RM1/zqKpBd3PfSmZywZgtKJMyGumsn0mlsRlUlssCqEPYW6H0uwYD6FXgHBGoXdGZUG9qn0Fl2NACP38rut5iu1Duh5LwKJbwwL90fILiHsKjoHapN0BJApWKgVAh4A/h3dyuHQlV7FuLYrddxrfsso5wFulD4EhuC92wpdQc+UMQ65SaQfPm8ReHDvheUNabM9PmxKzGM5kN2q6OmT6LoWQ9VkLVNXTMBOwD1YxpLRTuUH7NCwBO6uJni2ERVEq9l8xHRySUcwopHfdDZfr9u8DxDOr353ioF5UWqMP3Vp/t6glgT6i6qgPgXQPza06G+v0L6UAgTkZEzF7clbbOTGnYts4cu6qLMDsiqPkVZ2ZPizLbYqxadjJe9Gm7gmAO1D9YEdD8v+ZuFOdkZkA5p0oiicruGHkl1E62O1wF1Rnz/CI+Y0DJBDVD/T69CnVO8hpUyLOY54wG5ei2gQr37gylCN2VZ6IL4O9QqgXlYEOo1O+KJKCdDO1lSCYNqXYyWWlV2j/iLmMx+g2n5mZShQK9Oj/WOw9CheWsEq75OIDlUG+lhVCJobLmchvgwb3ovpMBgAugGptdh+J3DRTArm1XO7xtvu+gzv5W4ufwKQWQABCDkhpaHV3fmXdEAhgP4A4f5uoqUShnWZEEs5MhrIkw2ya2lIZta/1aG2rGydjE/FYyJgVjtjAZvfq0ZM/Tr0kuL7ddFcYSACdAhTVKTQ7AAygs220JgEeCNSfEg5ugQrV3Qu1sugMDsE7bVQoWQSlNPFui9aqSQA7+OYs2CXXwbwtmLtl27qRShUoCJ2Oa31qU2ZwxKYhp29FErYTM/OIhAFujPA6mnUJVbx+FevsNKS/ToVLh/RJNLQVPABiE0MF4EoiTkYQ2CWpKTpktSW1klrVjG+w7ySKSs4gtTFNyEgtDZoqZAIZBhXq+KbMtLwP4soBxlRgqq1cWQWWSHY/KFtL9ESo8tj/CYsuCCGYnY5o9OGM2NyPSYrQkoTI3QPWCjlgmXdCenm1RZguT9S3Ful1kKoDhUEVwr6Fr6b35+B6qgn8LAHtAHfJXAi68JWK+RmGFgSGlwwUwESr78R/wlqEpJcsA/B+UbZMQ1sEUjO8P5pOve8rkjJm8bSdj0UjgTmZZIjE0leixMhPvcWXQzuaoKdcsF6a5QtXKmHaOmEFlZflBFqqm5XyoDJoeUFk0p0K9xb8KVTtjFzCXgKoZeABK0XhrAGu3/XcgMj7dQIdKRc3HPajPXj/VQArARVBp8ycAeL+MtrwD4Bgo8dUklG0hReD7wX/ESDVJFpHStnXbsaW0RaBO5sd+a57GgUuF65pw3VNTDYm1vyXa8f2/+25pUGtyYi7glPUX1JSS0UJkJiqFDJRj+XVPdQKVbcOgHFFHR52GCmUE9vMMgF3RuSJzO6GMTOWzEiot+Bao7KkRUF1Qd0BASUttvA/V9mEaQiWIbuP7/6isE+2pUds2bCF1KXRdskDilvMGDWKRrHNRFs44OGAaXFdzobsa9oauzZg/YNBx6341770g1uaULpDUXIMzanMz0juINUqMhEr7rBUO87j/FoCPS2HIKlgEFdOvZvxIXy6WuW3XBCiByu2gRDS3hVL+XgsqPbkYBFRm2xcA3oT6vXgLKgxcSTwJoGrPtn13Mm6c9ZCuKYVt6wa1pS6k707ms80Hr8Vd59ZMDJvprpOBBqq7iMBxuatrK1wNa8DVHp232fbXtfznzWuSPsdPbdP83mLMFiwiBTUbx018m04av23NZNBVOX0AjPEYM6UEdnRGK6qnMVelsgLA821XR3pC7WDvh5JS6ozZAI5E4aHicvMOKr/HTqf4v5PRSQ+NmbZh29KgQtcYWeLn/K/tMGznJa52rQ63SXNhuXA03dV+dF3neV3DEAda1NUADbrrAieN2GHY1rtRefofXnrJt74vWYP+KJkpVZo2dZbHnd6o7IyYeuIEqOK0zrCgzpVCao/lbddLyO9ktoNqPVANDqbq8f2QXJqRRk6pzVWxorRJ3Bcn4wLa87vtf2wu2nhLLh6PZWIJno7FeTbWsDgXix+33dsvjl/eEB+ZiTV8mI01WOlYnGfiCZ6NJbaWpOmRWcNG7uyHHQAgYuYP7dlznJmS6KwWQma1QCPy95IHVF1DNZ0vhRSPl8RKAt6tk0N8wncnk9NZI6cRyQm1OTXFvHmN3Raxm9rcHH1yv8MuzcUSJ6XjCTsdS/BsLGGlY/GPU7HG5iEvPDkbAIbPevqLdGzd5mw8cV/mf2MSPBNvSGTiDTc8uf9hp7jJZLe/sxMxFwoakZJQW1BmW1QPnUxlcBa8+32UU/4jpDS8AO/MwX+iRGUP9Y7vP2TbjCSESW1hRiQ32bKWltHd2pJOHXv8mi7pfWsm3jgsk0jwjNq98Ew88Yxj9Bizz1P3fd1x/N5PX2/98ckHLuKJxHmZeGJ5NtbAs7GElU0keDraOGbqxz/cOP3Qcd1KO/5qNfxkUVNY1LQ5M2XOZN2VwwjpPv0BnO0xZj6UtllIbfMlgNc9xmwOlZocEjC+OxkeYQlJTCkotQWJdOvQ//ajzxmSpg23ZWMNa2eicZ6JJng21pDNJhquPWjqreftN31Sp82PDph621PpSGxsJpaYl4kneCaa4JlonGfjjYMWx3rcceuRZ3S5Y2TL6NG2ZGyxZKbkhNmSRAsVYwwJjn9C9bzJx60Ii+jqhUIa2N0IYEjQhtQ7/jsZQuMWM23OopJT2qXYt+u62g2nXHhsLhH/RyaWoOlYgmcTDVY21rAk09Bw9hF3/PteFFBIN/aua7+JpBvH52LxB9rnSMcSPBNLxHhjzwtvPHXCiclkskvJD5ZJFyqRzIjkphk6mfKyCZTacz4EgMklsCWkMrgP3mm/FCoJZOvgzalffHUyQ2e7EWFGdGGqzCsnEiv60P+Ks66IX/G3ay/IxBKj0rGEyMQTVjYa56lI/NNsjx4nnHB98s1i5hvdkuTjb7zwxlQs/o90NLEsE43zTDxhpWMJkY7G9onkev7rmr9dU7T+mE3YQotFlEgmpT2K/XyIbzAo9QKvl4W7EGYA1hMroKRpvFgTKhvtKKgeMyE+46uTae2RapCE2ZxQW5hU5nRalAT+hAl39E81Nv0rE41vmY01WOr8JcEzsYZn0vH0aadfcnqXO2z+9Yq/vsJ79joxHWv4j5ozzrOxBisXiw9YHon/Kznh9m2Lmc+i5neC0C851d/hEfZS81S32H4YIf5wKbx7aVgALiyBLSGVxe0oTPIoBpUQ8jqU1l+YEOAjvnruQfPcXgkrNSyWy/SOpNJ9ornMcw+P3PStQj571jUPDdZcebzmIgLX1QBAc2BrcCZfdvaYmX7ZOG7iRNqrNTHG1Y29XM3VXACaprmuprmOixkNK/rem0wO81tIMigmQxWVdcadHverGR1KnNMrZRlQXRjPDNackAplUwBvoDg1gAVQrSrmQBVBfuu/WfVD2beHyWRSX7zG4INcDXu7jqOrVwgHmosVuuvccO2J+38SxLon3TB9a013joNOYmrFNmcDbb7j6DffcsJe1dBorV6dTBxKz+rwAsYuh+pVUrWyHCHd5ih0L3V9MVTx5jIoPbOr/DCqXiirkznirhlxYsSOcV13Uzjq1dR1bU2DO98k9Oabx+wSaJ/zY6a+2svNWeNcVxuoabrrAIAOuJqWdXTt7rsPHVKxfbPbqFUnMwlKr+k5KFHPdkwAB0GFvgYWONfhUO2CQ+qb2+BPyvJtAI7zYZ66oWxOpnn622u7Uj9Wc9CknIurtTmZ1xb2ST84Z1hpQlZJ19U/nfbeH204I1xA0zTNdf4XkdXfbOovH5i0bcXqktWqkxH4+SB/EdSBvQCwIYCGIuaZCuAQf00LqVJ0KM26I7o5T+hkiiRIuey8ZGnPkaBuHG3tbzXHcUH06dP33MCr2ZSvJDXNAfDUyKc//s7W9dGaq0UBwNU1V9P0zVqXOHMQxmTLSd+2q1g+h9IxCwkBVET8aKgXlrNQAUcF9ULZsihS/Xrfk2poWJqJx3k2Fl+SNhuuL7WD6cjjIzb+wNKNK7LR+KfZRIOViSV4Nhp9+tm91g8dTPXxDYChCDXKQn6JBPBXAHujfK0eQkrJ4HdbN9jh7RV/3nzGj/Fy2/I/kkl9h3dXDt3xndTY9iy3CmYyVFFqZ9eUslnWPQTyf6981zIAW5Xe5JAqg0KFvT5Ecb9ft5bD2JDuUKEP8ma3KupeQifzy+sNqOZVISHFsCuA66A0z0In4zNlO5P5H5pWkX3WWzQt7DVRPThQVf9/QdiDPaR4Xmi7TgEwAKrb5jYA1oMSXl0HqkdRKB8VUneEOxmV6rxlecwMCQnxoiJDVSEFE4fS7uoMDiBdIlv8pD+AfQHsA1UPsyZU6vKPUJl+nwKYCVVHs6BMNoaEhBTA/wNaVLz6zZBm0gAAAABJRU5ErkJggg==" - } - }, - "cell_type": "markdown", - "id": "305d1216-9791-43dd-8d7f-ec90aa72a307", - "metadata": { - "tags": [] - }, - "source": [ - "# `pyEQL` Tutorial: Searching the Property Database\n", - "\n", - "![pyeql-logo.png](attachment:b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png)\n", - "\n", - "`pyEQL` is an open-source `python` library for solution chemistry calculations and ion properties developed by the [Kingsbury Lab](https://www.kingsburylab.org/) at Princeton University.\n", - "\n", - "[Documentation](https://pyeql.readthedocs.io/en/latest/) | [How to Install](https://pyeql.readthedocs.io/en/latest/installation.html) | [GitHub](https://github.com/rkingsbury/pyEQL) " - ] - }, - { - "cell_type": "markdown", - "id": "90c14b65-36f0-4bb2-a3bf-f8e725cc897e", - "metadata": { - "tags": [] - }, - "source": [ - "## Installation\n", - "\n", - "Uncomment and run the code cell below, if you do not already have `pyEQL`" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "abb1f51c-38fc-4543-8b59-057b8c591ba9", - "metadata": {}, - "outputs": [], - "source": [ - "# pip install pyEQL" - ] - }, - { - "cell_type": "markdown", - "id": "1b8efc81-17bb-46dc-8a22-63e71ae458b7", - "metadata": {}, - "source": [ - "## First, import the property database\n", - "\n", - "`pyEQL`'s built-in property database contains physichochemical, transport, and model parameters for hundreds of solutes. This information is used behind the scenes when you interact with a `Solution` object, but it can also be accessed directly." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "55f1aea5-a5b8-49b8-a8e8-20856c4be6e7", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "from pyEQL import IonDB" - ] - }, - { - "cell_type": "markdown", - "id": "23b21981-7568-4e29-a93c-4017a32629b4", - "metadata": {}, - "source": [ - "## How to Search the Database" - ] - }, - { - "cell_type": "markdown", - "id": "084e5aa5-041b-4135-a083-76a4d8e555d7", - "metadata": {}, - "source": [ - "### Query an example document\n", - "\n", - "You can think of the database like `list` of `dict` that contain structure data. More specifically, the database is a list of [`Solute` objects](https://pyeql.readthedocs.io/en/latest/database.html#the-solute-class) that have been serialized to dictionaries. We refer to each of these `dict` as **\"documents\"** (consistent with MongoDB terminology) or \"records\"\n", - "\n", - "To see what one document looks like, use `query_one()`, which retrieves a single record from the database. The record is a `dict`." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "91459416-322a-49c5-a9ee-bf74c160a7e2", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'_id': ObjectId('654e5f131ed012c187817e6a'),\n", - " 'formula': 'Ac[+3]',\n", - " 'charge': 3,\n", - " 'molecular_weight': '227.0 g/mol',\n", - " 'elements': ['Ac'],\n", - " 'chemsys': 'Ac',\n", - " 'pmg_ion': {'Ac': 1,\n", - " 'charge': 3,\n", - " '@module': 'pymatgen.core.ion',\n", - " '@class': 'Ion',\n", - " '@version': None},\n", - " 'formula_html': 'Ac+3',\n", - " 'formula_latex': 'Ac$^{+3}$',\n", - " 'formula_hill': 'Ac',\n", - " 'formula_pretty': 'Ac^+3',\n", - " 'oxi_state_guesses': {'Ac': 3},\n", - " 'n_atoms': 1,\n", - " 'n_elements': 1,\n", - " 'size': {'radius_ionic': {'value': '1.26 Å',\n", - " 'reference': 'pymatgen',\n", - " 'data_type': 'experimental'},\n", - " 'radius_hydrated': None,\n", - " 'radius_vdw': {'value': '2.47 Å',\n", - " 'reference': 'pymatgen',\n", - " 'data_type': 'experimental'},\n", - " 'molar_volume': None,\n", - " 'radius_ionic_marcus': {'value': '1.18 ± 0.02 Å',\n", - " 'reference': 'Marcus2015',\n", - " 'data_type': 'experimental'}},\n", - " 'thermo': {'ΔG_hydration': {'value': '-3086.0 ± 10 kJ/mol',\n", - " 'reference': '10.1021/acs.jpca.9b05140',\n", - " 'data_type': 'experimental'},\n", - " 'ΔG_formation': None},\n", - " 'transport': {'diffusion_coefficient': None},\n", - " 'model_parameters': {'activity_pitzer': {'Beta0': None,\n", - " 'Beta1': None,\n", - " 'Beta2': None,\n", - " 'Cphi': None,\n", - " 'Max_C': None},\n", - " 'molar_volume_pitzer': {'Beta0': None,\n", - " 'Beta1': None,\n", - " 'Beta2': None,\n", - " 'Cphi': None,\n", - " 'V_o': None,\n", - " 'Max_C': None},\n", - " 'viscosity_jones_dole': {'B': None}}}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "IonDB.query_one()" - ] - }, - { - "cell_type": "markdown", - "id": "db042f2d-2926-40bb-b84c-9fc5174618d0", - "metadata": {}, - "source": [ - "### Query a specific document\n", - "\n", - "The `IonDB` is a [`maggma.Store`](https://materialsproject.github.io/maggma/getting_started/stores/) that can be queried using a MongoDB-like syntax. The basic syntax is\n", - "\n", - "```\n", - "IonDB.query_one({field: value})\n", - "```\n", - "\n", - "where `field` is a top-level key in the `Solute` `dict`, such as `formula`, `charge`, or `elements`. See [this page](https://riptutorial.com/mongodb/example/26813/pymongo-queries) and the `maggma` documentation (link WIP) for more detailed examples." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "5e0b4774-5274-4df1-8a91-7a9d43f675bd", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'_id': ObjectId('654e5f131ed012c187817f46'),\n", - " 'formula': 'Na[+1]',\n", - " 'charge': 1,\n", - " 'molecular_weight': '22.98976928 g/mol',\n", - " 'elements': ['Na'],\n", - " 'chemsys': 'Na',\n", - " 'pmg_ion': {'Na': 1,\n", - " 'charge': 1,\n", - " '@module': 'pymatgen.core.ion',\n", - " '@class': 'Ion',\n", - " '@version': None},\n", - " 'formula_html': 'Na+1',\n", - " 'formula_latex': 'Na$^{+1}$',\n", - " 'formula_hill': 'Na',\n", - " 'formula_pretty': 'Na^+1',\n", - " 'oxi_state_guesses': {'Na': 1},\n", - " 'n_atoms': 1,\n", - " 'n_elements': 1,\n", - " 'size': {'radius_ionic': {'value': '1.16 Å',\n", - " 'reference': 'pymatgen',\n", - " 'data_type': 'experimental'},\n", - " 'radius_hydrated': {'value': '3.58 Å',\n", - " 'reference': 'Nightingale1959',\n", - " 'data_type': 'experimental'},\n", - " 'radius_vdw': {'value': '2.27 Å',\n", - " 'reference': 'pymatgen',\n", - " 'data_type': 'experimental'},\n", - " 'molar_volume': {'value': '-5.0 cm**3/mol',\n", - " 'reference': 'Calculation of the Partial Molal Volume of Organic Compounds and Polymers. Progress in Colloid & Polymer Science (94), 20-39.',\n", - " 'data_type': 'experimental'},\n", - " 'radius_ionic_marcus': {'value': '1.02 ± 0.02 Å',\n", - " 'reference': 'Marcus2015',\n", - " 'data_type': 'experimental'}},\n", - " 'thermo': {'ΔG_hydration': {'value': '-427.0 ± 6 kJ/mol',\n", - " 'reference': 'Marcus2015',\n", - " 'data_type': 'experimental'},\n", - " 'ΔG_formation': None},\n", - " 'transport': {'diffusion_coefficient': {'value': '1.334e-05 cm**2/s',\n", - " 'reference': 'CRC',\n", - " 'data_type': 'experimental'}},\n", - " 'model_parameters': {'activity_pitzer': {'Beta0': None,\n", - " 'Beta1': None,\n", - " 'Beta2': None,\n", - " 'Cphi': None,\n", - " 'Max_C': None},\n", - " 'molar_volume_pitzer': {'Beta0': None,\n", - " 'Beta1': None,\n", - " 'Beta2': None,\n", - " 'Cphi': None,\n", - " 'V_o': None,\n", - " 'Max_C': None},\n", - " 'viscosity_jones_dole': {'B': {'value': '0.085 dm**3/mol',\n", - " 'reference': 'https://doi.org/10.1021/cr00040a004',\n", - " 'data_type': 'fitted'}},\n", - " 'dielectric_zuber': {'value': '3.62 dimensionless',\n", - " 'reference': 'https://doi.org/10.1016/j.fluid.2014.05.037',\n", - " 'data_type': 'fitted'}}}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# a document with the formula \"Na[+1]\"\n", - "IonDB.query_one({\"formula\": \"Na[+1]\"})" - ] - }, - { - "cell_type": "markdown", - "id": "381b0bae-436b-44b2-b651-bf8766ee053f", - "metadata": {}, - "source": [ - "### Only return a subset of the document\n", - "\n", - "If you don't need to see the entire document, you can restrict the data returned by the query (in MongoDB, this is called \"projection\"). To use this feature, pass a second argument that is a `list` containing _only the fields that you want returned_. Note that there is a unique identified (field name `_id`) that is always returned." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "1063fa68-50e3-441c-89f9-32a52314d6a7", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'formula': 'Na[+1]',\n", - " 'charge': 1,\n", - " 'molecular_weight': '22.98976928 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f46')}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# a document with the formula \"Na[+1]\", where we only want the formula, charge, and molecular_weight\n", - "IonDB.query_one({\"formula\": \"Na[+1]\"}, [\"formula\", \"charge\", \"molecular_weight\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "2829357c-45f7-487f-b89c-978bf28bf126", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'formula': 'Ag(CN)2[-1]',\n", - " 'charge': -1,\n", - " 'molecular_weight': '159.903 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e6b')}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# a document with the charge -1, where we only want the formula, charge, and molecular_weight\n", - "IonDB.query_one({\"charge\": -1}, [\"formula\", \"charge\", \"molecular_weight\"])" - ] - }, - { - "cell_type": "markdown", - "id": "d7ffc305-5e92-41fe-96fc-8507ee9be76a", - "metadata": {}, - "source": [ - "**NOTE**: Be mindful of data types when querying. `charge` is an `int`. If we tried to query `charge` as if it were a `str`, we would get no results:" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "0e697fdb-5667-4280-9f09-f45c9a5c0ec2", - "metadata": {}, - "outputs": [], - "source": [ - "# a document with the charge -1, where we only want the formula, charge, and molecular_weight\n", - "IonDB.query_one({\"charge\": \"-1\"}, [\"formula\", \"charge\", \"molecular_weight\"])" - ] - }, - { - "cell_type": "markdown", - "id": "ce6abcd9-5739-44a6-8993-a6ca1d6f0c47", - "metadata": {}, - "source": [ - "### Query nested fields\n", - "\n", - "If you want to query a field that is not a top-level key (such as transport / diffusion_coefficient), you can place a `.` between the field names at each level, e.g." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "068c1ad7-bb98-4c38-af9f-0fa73b9b4551", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'formula': 'Na2CO3(aq)',\n", - " 'size': {'radius_vdw': {'value': '2.27 Å'}},\n", - " '_id': ObjectId('654e5f131ed012c187817f31')}" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "IonDB.query_one({\"size.radius_vdw.value\": \"2.27 Å\"}, [\"formula\", \"size.radius_vdw.value\"])" - ] - }, - { - "cell_type": "markdown", - "id": "ef08b109-26f3-40ba-9bc6-6345c1a60e4d", - "metadata": { - "tags": [] - }, - "source": [ - "**Note** that in the `Solute` documents, **most quantitative data are stored as `str` so that there is no ambiguity about their units**. In the example above, the value of the van der Waals radius is `\"2.27 Å\"` (a `str`, including a unit), NOT `2.27` (a `float`).\n", - "\n", - "You can easily extract the value by turning the `str` into a `Quantity` (see [Converting Units](https://pyeql.readthedocs.io/en/latest/units.html)), or by using `python` string operations to split the value and the units, e.g." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "d3be0fcb-7704-457f-8726-ec140ab5cf01", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2.27\n" - ] - } - ], - "source": [ - "# string operations\n", - "print(float(\"2.27 Å\".split(\" \")[0]))" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "fd89fe2b-0697-4f17-98d4-50634660c112", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2.27\n" - ] - } - ], - "source": [ - "# pint Quantity\n", - "from pyEQL import ureg\n", - "\n", - "print(ureg.Quantity(\"2.27 Å\").magnitude)" - ] - }, - { - "cell_type": "markdown", - "id": "261da6c7-1033-432c-b2d2-334661cec4f1", - "metadata": {}, - "source": [ - "### Query multiple documents\n", - "\n", - "`query_one` only returns a single document (a single `dict`). You can instead use `query` with exactly the same syntax to return a [generator](https://realpython.com/introduction-to-python-generators/) of all documents that match your query." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d7c3936a-ed30-4865-acb6-81e2a6d415c8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# all documents with a charge of +2, returning only the formulas\n", - "IonDB.query({\"charge\": 2}, [\"formula\", \"molecular_weight\"])" - ] - }, - { - "cell_type": "markdown", - "id": "86ff455f-5e3c-40fa-83a2-eadb74595a56", - "metadata": {}, - "source": [ - "A generator is not very useful unless we turn it into a `list`. You can do this with `list()` or with a [list comprehension](https://www.w3schools.com/python/python_lists_comprehension.asp)" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "82e73a80-9987-4866-bf24-55628a7eb2cc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'formula': 'Ag[+2]',\n", - " 'molecular_weight': '107.8682 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e6e')},\n", - " {'formula': 'Au[+2]',\n", - " 'molecular_weight': '196.966569 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e76')},\n", - " {'formula': 'Ba[+2]',\n", - " 'molecular_weight': '137.327 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e83')},\n", - " {'formula': 'Be[+2]',\n", - " 'molecular_weight': '9.012182 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e85')},\n", - " {'formula': 'Ca[+2]',\n", - " 'molecular_weight': '40.078 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e96')},\n", - " {'formula': 'Cd[+2]',\n", - " 'molecular_weight': '112.411 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e9b')},\n", - " {'formula': 'Co[+2]',\n", - " 'molecular_weight': '58.933195 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ea9')},\n", - " {'formula': 'Cr[+2]',\n", - " 'molecular_weight': '51.9961 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817eae')},\n", - " {'formula': 'Cu[+2]',\n", - " 'molecular_weight': '63.546 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ebe')},\n", - " {'formula': 'Dy[+2]',\n", - " 'molecular_weight': '162.5 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ec0')},\n", - " {'formula': 'Eu[+2]',\n", - " 'molecular_weight': '151.964 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ec5')},\n", - " {'formula': 'Fe[+2]',\n", - " 'molecular_weight': '55.845 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ecc')},\n", - " {'formula': 'Ge[+2]',\n", - " 'molecular_weight': '72.64 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ed1')},\n", - " {'formula': 'Hg[+2]',\n", - " 'molecular_weight': '200.59 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ef1')},\n", - " {'formula': 'In[+2]',\n", - " 'molecular_weight': '114.818 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ef7')},\n", - " {'formula': 'Mg[+2]',\n", - " 'molecular_weight': '24.305 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f26')},\n", - " {'formula': 'Mn[+2]',\n", - " 'molecular_weight': '54.938045 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f2a')},\n", - " {'formula': 'Nd[+2]',\n", - " 'molecular_weight': '144.242 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f4a')},\n", - " {'formula': 'Ni[+2]',\n", - " 'molecular_weight': '58.6934 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f4f')},\n", - " {'formula': 'Pb[+2]',\n", - " 'molecular_weight': '207.2 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f62')},\n", - " {'formula': 'Pd[+2]',\n", - " 'molecular_weight': '106.42 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f63')},\n", - " {'formula': 'Po[+2]',\n", - " 'molecular_weight': '210.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f65')},\n", - " {'formula': 'Pr[+2]',\n", - " 'molecular_weight': '140.90765 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f67')},\n", - " {'formula': 'Pt[+2]',\n", - " 'molecular_weight': '195.084 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f69')},\n", - " {'formula': 'Ra[+2]',\n", - " 'molecular_weight': '226.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f6b')},\n", - " {'formula': 'Ru[+2]',\n", - " 'molecular_weight': '101.07 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f7b')},\n", - " {'formula': 'Sc[+2]',\n", - " 'molecular_weight': '44.955912 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f87')},\n", - " {'formula': 'Sm[+2]',\n", - " 'molecular_weight': '150.36 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f8e')},\n", - " {'formula': 'Sn[+2]',\n", - " 'molecular_weight': '118.71 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f90')},\n", - " {'formula': 'Sr[+2]',\n", - " 'molecular_weight': '87.62 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f97')},\n", - " {'formula': 'Tc[+2]',\n", - " 'molecular_weight': '98.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f9b')},\n", - " {'formula': 'Ti[+2]',\n", - " 'molecular_weight': '47.867 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f9f')},\n", - " {'formula': 'Tm[+2]',\n", - " 'molecular_weight': '168.93421 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fa7')},\n", - " {'formula': 'UO2[+2]',\n", - " 'molecular_weight': '270.02771 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fad')},\n", - " {'formula': 'V[+2]',\n", - " 'molecular_weight': '50.9415 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fb2')},\n", - " {'formula': 'Yb[+2]',\n", - " 'molecular_weight': '173.04 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fba')},\n", - " {'formula': 'Zn[+2]',\n", - " 'molecular_weight': '65.409 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fc2')}]" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# using list()\n", - "list(IonDB.query({\"charge\": 2}, [\"formula\", \"molecular_weight\"]))" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "c6dd37ed-9d07-47b3-be85-aecaade0b880", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'formula': 'Ag[+2]',\n", - " 'molecular_weight': '107.8682 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e6e')},\n", - " {'formula': 'Au[+2]',\n", - " 'molecular_weight': '196.966569 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e76')},\n", - " {'formula': 'Ba[+2]',\n", - " 'molecular_weight': '137.327 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e83')},\n", - " {'formula': 'Be[+2]',\n", - " 'molecular_weight': '9.012182 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e85')},\n", - " {'formula': 'Ca[+2]',\n", - " 'molecular_weight': '40.078 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e96')},\n", - " {'formula': 'Cd[+2]',\n", - " 'molecular_weight': '112.411 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817e9b')},\n", - " {'formula': 'Co[+2]',\n", - " 'molecular_weight': '58.933195 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ea9')},\n", - " {'formula': 'Cr[+2]',\n", - " 'molecular_weight': '51.9961 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817eae')},\n", - " {'formula': 'Cu[+2]',\n", - " 'molecular_weight': '63.546 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ebe')},\n", - " {'formula': 'Dy[+2]',\n", - " 'molecular_weight': '162.5 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ec0')},\n", - " {'formula': 'Eu[+2]',\n", - " 'molecular_weight': '151.964 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ec5')},\n", - " {'formula': 'Fe[+2]',\n", - " 'molecular_weight': '55.845 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ecc')},\n", - " {'formula': 'Ge[+2]',\n", - " 'molecular_weight': '72.64 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ed1')},\n", - " {'formula': 'Hg[+2]',\n", - " 'molecular_weight': '200.59 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ef1')},\n", - " {'formula': 'In[+2]',\n", - " 'molecular_weight': '114.818 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817ef7')},\n", - " {'formula': 'Mg[+2]',\n", - " 'molecular_weight': '24.305 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f26')},\n", - " {'formula': 'Mn[+2]',\n", - " 'molecular_weight': '54.938045 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f2a')},\n", - " {'formula': 'Nd[+2]',\n", - " 'molecular_weight': '144.242 g/mol',\n", - " '_id': ObjectId('654e5f131ed012c187817f4a')},\n", - " {'formula': 'Ni[+2]',\n", - " 'molecular_weight': '58.6934 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f4f')},\n", - " {'formula': 'Pb[+2]',\n", - " 'molecular_weight': '207.2 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f62')},\n", - " {'formula': 'Pd[+2]',\n", - " 'molecular_weight': '106.42 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f63')},\n", - " {'formula': 'Po[+2]',\n", - " 'molecular_weight': '210.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f65')},\n", - " {'formula': 'Pr[+2]',\n", - " 'molecular_weight': '140.90765 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f67')},\n", - " {'formula': 'Pt[+2]',\n", - " 'molecular_weight': '195.084 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f69')},\n", - " {'formula': 'Ra[+2]',\n", - " 'molecular_weight': '226.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f6b')},\n", - " {'formula': 'Ru[+2]',\n", - " 'molecular_weight': '101.07 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f7b')},\n", - " {'formula': 'Sc[+2]',\n", - " 'molecular_weight': '44.955912 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f87')},\n", - " {'formula': 'Sm[+2]',\n", - " 'molecular_weight': '150.36 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f8e')},\n", - " {'formula': 'Sn[+2]',\n", - " 'molecular_weight': '118.71 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f90')},\n", - " {'formula': 'Sr[+2]',\n", - " 'molecular_weight': '87.62 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f97')},\n", - " {'formula': 'Tc[+2]',\n", - " 'molecular_weight': '98.0 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f9b')},\n", - " {'formula': 'Ti[+2]',\n", - " 'molecular_weight': '47.867 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817f9f')},\n", - " {'formula': 'Tm[+2]',\n", - " 'molecular_weight': '168.93421 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fa7')},\n", - " {'formula': 'UO2[+2]',\n", - " 'molecular_weight': '270.02771 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fad')},\n", - " {'formula': 'V[+2]',\n", - " 'molecular_weight': '50.9415 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fb2')},\n", - " {'formula': 'Yb[+2]',\n", - " 'molecular_weight': '173.04 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fba')},\n", - " {'formula': 'Zn[+2]',\n", - " 'molecular_weight': '65.409 g/mol',\n", - " '_id': ObjectId('654e5f141ed012c187817fc2')}]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# using a comprehension\n", - "[doc for doc in IonDB.query({\"charge\": 2}, [\"formula\", \"molecular_weight\"])]" - ] - }, - { - "cell_type": "markdown", - "id": "94600f07-a63e-4004-8107-a1a91103d494", - "metadata": {}, - "source": [ - "## Counting Documents\n", - "\n", - "You can use `count()` to see how many documents the database contains" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "bf68990f-bade-425f-8fa5-d6f67c9a15ea", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "346" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "IonDB.count()" - ] - }, - { - "cell_type": "markdown", - "id": "7272f19b-5871-44f0-a4b6-da817115ceab", - "metadata": {}, - "source": [ - "Count works with queries, too." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "43a45291-e0bb-4d9d-8b8b-b20f3e49773a", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "7" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# number of documents with a charge of -3\n", - "IonDB.count({\"charge\": -3})" - ] - }, - { - "cell_type": "markdown", - "id": "b1dd7b65-f54d-4998-aad1-ad73d6c7fe7d", - "metadata": {}, - "source": [ - "## More Advanced Query Syntax" - ] - }, - { - "cell_type": "markdown", - "id": "22a1209c-35ed-4096-8e53-d016b4187a41", - "metadata": {}, - "source": [ - "### Match multiple items with `$in`\n", - "\n", - "If you want to query documents that match _any one of a set of values_, use `$in` with a `list` of possible values. Note that the `$in` operator and your `list` constitute their own dictionary, e.g. `{\"$in\":}`. This entire dictionary is the \"value\" of your query for the associated field. For example:" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8bed2683-ca20-4b8e-9bde-c4c86fb0e511", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "5" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# all alkali cations\n", - "IonDB.count({\"formula\": {\"$in\": [\"Li[+1]\", \"Na[+1]\", \"K[+1]\", \"Rb[+1]\", \"Cs[+1]\"]}})" - ] - }, - { - "cell_type": "markdown", - "id": "ff2b2305-1d45-45cd-aa53-31eccffb8afa", - "metadata": {}, - "source": [ - "### Greater than or less than - `$gt` / `$gte` / `$lt` / `$lte`\n", - "\n", - "In a similar manner, you can query fields whose values are greater than / less than or equal to some value" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "7f7e52c5-6963-4848-99cb-32018adfb12c", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "76" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# all solutes with a charge less than 0\n", - "IonDB.count({\"charge\": {\"$lt\": 0}})" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "747d56b6-859f-4a15-9fa5-ef63229a7436", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "108" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# all solutes with a charge greater than or equal to 1\n", - "IonDB.count({\"charge\": {\"$gte\": 1}})" - ] - }, - { - "cell_type": "markdown", - "id": "4ad07153-ead4-4a95-a83a-7055089cbd84", - "metadata": {}, - "source": [ - "## Unique Values\n", - "\n", - "It's often useful to understand how many unique values of a field there are. To do so, use `distinct()` with any field name" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "7587a871-ed15-4ab4-b2a7-77018e67a1c1", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['U(ClO5)2(aq)',\n", - " 'LiClO4(aq)',\n", - " 'Sb(OH)6[-1]',\n", - " 'Ba[+2]',\n", - " 'RbNO3(aq)',\n", - " 'KBrO3(aq)',\n", - " 'H3O[+1]',\n", - " 'CsNO2(aq)',\n", - " 'Re[+1]',\n", - " 'KHC2O.1H2O(aq)',\n", - " 'Ni[+3]',\n", - " 'H8S(NO2)2(aq)',\n", - " 'Sm[+2]',\n", - " 'B(OH)4[-1]',\n", - " 'CoI2(aq)',\n", - " 'ZnBr2(aq)',\n", - " 'Sn[+2]',\n", - " 'USO6(aq)',\n", - " 'Ir[+3]',\n", - " 'Ag(CN)2[-1]',\n", - " 'KNO3(aq)',\n", - " 'Ga[+3]',\n", - " 'Zn(NO3)2(aq)',\n", - " 'NaHC3.2H2O(aq)',\n", - " 'Ni(NO3)2(aq)',\n", - " 'S[-2]',\n", - " 'HS[-1]',\n", - " 'Eu[+2]',\n", - " 'ZnSO4(aq)',\n", - " 'BeSO4(aq)',\n", - " 'MnO4[-1]',\n", - " 'K2CO3(aq)',\n", - " 'Pa[+3]',\n", - " 'SrI2(aq)',\n", - " 'FeCl2(aq)',\n", - " 'Eu(NO3)3(aq)',\n", - " 'NaClO4(aq)',\n", - " 'Zn[+2]',\n", - " 'SeO4[-1]',\n", - " 'NaCrO4(aq)',\n", - " 'CsOH(aq)',\n", - " 'Na3PO4(aq)',\n", - " 'KCSN(aq)',\n", - " 'HSO4[-1]',\n", - " 'Mn[+3]',\n", - " 'H4NClO4(aq)',\n", - " 'NiSO4(aq)',\n", - " 'IO4[-1]',\n", - " 'Sr(ClO4)2(aq)',\n", - " 'SeO4[-2]',\n", - " 'Ag[+1]',\n", - " 'LiI(aq)',\n", - " 'SiF6[-2]',\n", - " 'HF2[-1]',\n", - " 'CoBr2(aq)',\n", - " 'Pr[+3]',\n", - " 'BaBr2(aq)',\n", - " 'ClO2[-1]',\n", - " 'MgBr2(aq)',\n", - " 'Ho[+3]',\n", - " 'Be[+2]',\n", - " 'H2O(aq)',\n", - " 'Po[+2]',\n", - " 'P2O7[-4]',\n", - " 'RbCl(aq)',\n", - " 'K[+1]',\n", - " 'ClO4[-1]',\n", - " 'Mg(ClO4)2(aq)',\n", - " 'NdCl3(aq)',\n", - " 'Au[+1]',\n", - " 'Rb2SO4(aq)',\n", - " 'Na2PHO4(aq)',\n", - " 'Th[+4]',\n", - " 'Fe[+3]',\n", - " 'Ra[+2]',\n", - " 'Tl(NO3)3(aq)',\n", - " 'Rb[+1]',\n", - " 'KF(aq)',\n", - " 'Gd[+3]',\n", - " 'NiCl2(aq)',\n", - " 'Rh[+3]',\n", - " 'Ag[+3]',\n", - " 'Cd(ClO4)2(aq)',\n", - " 'FeCl3(aq)',\n", - " 'NO3[-1]',\n", - " 'MoO4[-2]',\n", - " 'Tl[+3]',\n", - " 'CuSO4(aq)',\n", - " 'Tm[+3]',\n", - " 'OH[-1]',\n", - " 'Zn(ClO4)2(aq)',\n", - " 'Th(NO3)4(aq)',\n", - " 'HNO3(aq)',\n", - " 'AgNO3(aq)',\n", - " 'Cr(NO3)3(aq)',\n", - " 'Tl(NO2)3(aq)',\n", - " 'CaI2(aq)',\n", - " 'Pt[+2]',\n", - " 'U(NO4)2(aq)',\n", - " 'LiNO2(aq)',\n", - " 'Na2CO3(aq)',\n", - " 'Np[+4]',\n", - " 'LiNO3(aq)',\n", - " 'VO2[+1]',\n", - " 'KCrO4(aq)',\n", - " 'PO4[-3]',\n", - " 'Ca(NO3)2(aq)',\n", - " 'Li[+1]',\n", - " 'SrCl2(aq)',\n", - " 'KPO3.1H2O(aq)',\n", - " 'CH3COO[-1]',\n", - " 'PrCl3(aq)',\n", - " 'In[+3]',\n", - " 'ZnI2(aq)',\n", - " 'SmCl3(aq)',\n", - " 'KI(aq)',\n", - " 'K3Fe(CN)6(aq)',\n", - " 'CdSO4(aq)',\n", - " 'GdCl3(aq)',\n", - " 'Os[+3]',\n", - " 'LiHC2O.1H2O(aq)',\n", - " 'Sr(NO3)2(aq)',\n", - " 'H2SO4(aq)',\n", - " 'Hg[+2]',\n", - " 'NaNO2(aq)',\n", - " 'Cd[+2]',\n", - " 'H5N2[+1]',\n", - " 'Mg(NO3)2(aq)',\n", - " 'KClO3(aq)',\n", - " 'P(OH)2[-1]',\n", - " 'Sn[+4]',\n", - " 'Tm[+2]',\n", - " 'U(ClO)2(aq)',\n", - " 'HCO2[-1]',\n", - " 'BO2[-1]',\n", - " 'KBr(aq)',\n", - " 'K2SO4(aq)',\n", - " 'SeO3[-1]',\n", - " 'Ta[+3]',\n", - " 'YNO3(aq)',\n", - " 'Cu[+1]',\n", - " 'Er[+3]',\n", - " 'Al[+3]',\n", - " 'HSO3[-1]',\n", - " 'Tl[+1]',\n", - " 'BrO3[-1]',\n", - " 'Li2SO4(aq)',\n", - " 'Co[+2]',\n", - " 'ZnCl2(aq)',\n", - " 'HO2[-1]',\n", - " 'I[-1]',\n", - " 'Au[+3]',\n", - " 'CSN[-1]',\n", - " 'NaHCO2(aq)',\n", - " 'Ca[+2]',\n", - " 'P(HO2)2[-1]',\n", - " 'Ba(NO3)2(aq)',\n", - " 'Dy[+2]',\n", - " 'Cs2SO4(aq)',\n", - " 'F[-1]',\n", - " 'Pb[+2]',\n", - " 'EuCl3(aq)',\n", - " 'Ca(ClO4)2(aq)',\n", - " 'Al2(SO4)3(aq)',\n", - " 'PH9(NO2)2(aq)',\n", - " 'RbBr(aq)',\n", - " 'CuCl2(aq)',\n", - " 'Co(H3N)6[-3]',\n", - " 'Pb(NO3)2(aq)',\n", - " 'CSeN[-1]',\n", - " 'Ce[+3]',\n", - " 'RbOH(aq)',\n", - " 'P3O10[-5]',\n", - " 'NaOH(aq)',\n", - " 'Sm[+3]',\n", - " 'Yb[+3]',\n", - " 'C2N3[-1]',\n", - " 'BaC4O.3H2O(aq)',\n", - " 'Fe(CN)6[-3]',\n", - " 'RbNO2(aq)',\n", - " 'Re[+3]',\n", - " 'LaCl3(aq)',\n", - " 'CrO4[-2]',\n", - " 'H[+1]',\n", - " 'K3PO4(aq)',\n", - " 'Ce[+4]',\n", - " 'Cu[+2]',\n", - " 'H2CO3(aq)',\n", - " 'BaCl2(aq)',\n", - " 'NaBrO3(aq)',\n", - " 'Zr[+4]',\n", - " 'CsI(aq)',\n", - " 'CoCl2(aq)',\n", - " 'Ac[+3]',\n", - " 'Ti[+2]',\n", - " 'Nd(NO3)3(aq)',\n", - " 'NaBr(aq)',\n", - " 'La(NO3)3(aq)',\n", - " 'MgC4O.3H2O(aq)',\n", - " 'PO3[-1]',\n", - " 'CrCl3(aq)',\n", - " 'U[+3]',\n", - " 'HCl(aq)',\n", - " 'Tc[+2]',\n", - " 'Au(CN)4[-1]',\n", - " 'HOsO5[-1]',\n", - " 'WO4[-1]',\n", - " 'PHO4[-2]',\n", - " 'ClO3[-1]',\n", - " 'K4Fe(CN)6(aq)',\n", - " 'Br[-0.33333333]',\n", - " 'Sr[+2]',\n", - " 'Cr[+3]',\n", - " 'UO2[+2]',\n", - " 'Ni[+2]',\n", - " 'Tl(ClO4)3(aq)',\n", - " 'Pu[+4]',\n", - " 'NaHC2O.1H2O(aq)',\n", - " 'MgI2(aq)',\n", - " 'TlH(C3O)2.4H2O(aq)',\n", - " 'Co(CN)6[-3]',\n", - " 'K2PHO4(aq)',\n", - " 'Mn[+2]',\n", - " 'NaNO3(aq)',\n", - " 'ScCl3(aq)',\n", - " 'CeCl3(aq)',\n", - " 'MnSO4(aq)',\n", - " 'Ru[+3]',\n", - " 'CsNO3(aq)',\n", - " 'HCO3[-1]',\n", - " 'H4NCl(aq)',\n", - " 'Ag[+2]',\n", - " 'Nb[+3]',\n", - " 'CNO[-1]',\n", - " 'H4IN(aq)',\n", - " 'In[+1]',\n", - " 'Ge[+2]',\n", - " 'HI(aq)',\n", - " 'ReO4[-1]',\n", - " 'MgCl2(aq)',\n", - " 'CsF(aq)',\n", - " 'N[-0.33333333]',\n", - " 'HClO4(aq)',\n", - " 'CsCl(aq)',\n", - " 'KHCO3(aq)',\n", - " 'La[+3]',\n", - " 'Ba(ClO4)2(aq)',\n", - " 'Bi[+3]',\n", - " 'CaBr2(aq)',\n", - " 'Yb[+2]',\n", - " 'CaCl2(aq)',\n", - " 'UO2[+1]',\n", - " 'Mo[+3]',\n", - " 'KClO4(aq)',\n", - " 'KOH(aq)',\n", - " 'LiBr(aq)',\n", - " 'SO3[-1]',\n", - " 'NaPO3.1H2O(aq)',\n", - " 'AsO4[-3]',\n", - " 'Br[-1]',\n", - " 'Dy[+3]',\n", - " 'IO3[-1]',\n", - " 'Sc[+3]',\n", - " 'H2SNO3[-1]',\n", - " 'Np[+3]',\n", - " 'Fe(CN)6[-4]',\n", - " 'RbHC2O.1H2O(aq)',\n", - " 'Nd[+2]',\n", - " 'Pr[+2]',\n", - " 'HBr(aq)',\n", - " 'MgSO4(aq)',\n", - " 'PO3F[-2]',\n", - " 'RbI(aq)',\n", - " 'Cu[+3]',\n", - " 'Pm[+3]',\n", - " 'H4BrN(aq)',\n", - " 'MnCl2(aq)',\n", - " 'CsHC2O.1H2O(aq)',\n", - " 'Y[+3]',\n", - " 'Hf[+4]',\n", - " 'Na[+1]',\n", - " 'H5C6O7[-3]',\n", - " 'Co(NO3)2(aq)',\n", - " 'NaCSN(aq)',\n", - " 'NaHCO3(aq)',\n", - " 'CsBr(aq)',\n", - " 'W[+3]',\n", - " 'NO2[-1]',\n", - " 'V[+2]',\n", - " 'SO4[-1]',\n", - " 'B(OH)3(aq)',\n", - " 'KCl(aq)',\n", - " 'Cl[-1]',\n", - " 'SrBr2(aq)',\n", - " 'PF6[-1]',\n", - " 'YCl3(aq)',\n", - " 'Pb(ClO4)2(aq)',\n", - " 'Co[+3]',\n", - " 'S2O3[-2]',\n", - " 'H4N2O3(aq)',\n", - " 'Cr[+2]',\n", - " 'NaF(aq)',\n", - " 'H4N[+1]',\n", - " 'Au(CN)2[-1]',\n", - " 'SO4[-2]',\n", - " 'Tc[+3]',\n", - " 'NaCl(aq)',\n", - " 'Eu[+3]',\n", - " 'Ru[+2]',\n", - " 'V[+3]',\n", - " 'Cu(NO3)2(aq)',\n", - " 'Fe[+2]',\n", - " 'Nd[+3]',\n", - " 'SO3[-2]',\n", - " 'BF4[-1]',\n", - " 'Sb(HO2)2[-1]',\n", - " 'B(H5C6)4[-1]',\n", - " 'Mg[+2]',\n", - " 'Cd(NO2)2(aq)',\n", - " 'SO2[-1]',\n", - " 'NaI(aq)',\n", - " 'Ti[+3]',\n", - " 'Cs[+1]',\n", - " 'HSeO3[-1]',\n", - " 'LiOH(aq)',\n", - " 'LiCl(aq)',\n", - " 'RbF(aq)',\n", - " 'WO4[-2]',\n", - " 'Pd[+2]',\n", - " 'Tb[+3]',\n", - " 'In[+2]',\n", - " 'Re[-1]',\n", - " 'Na2S2O3(aq)',\n", - " 'KNO2(aq)',\n", - " 'TcO4[-1]',\n", - " 'U[+4]',\n", - " 'BaI2(aq)',\n", - " 'CO3[-2]',\n", - " 'H4SNO4(aq)',\n", - " 'CN[-1]',\n", - " 'Sc[+2]',\n", - " 'Cd(NO3)2(aq)',\n", - " 'Na2SO4(aq)',\n", - " 'IrO4[-1]',\n", - " 'Lu[+3]',\n", - " 'Au[+2]']" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# list of all unique `formula`\n", - "IonDB.distinct(\"formula\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (conda: skagit2)", - "language": "python", - "name": "skagit2" - }, - "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.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/examples/.ipynb_checkpoints/pyeql_tutorial_osmotic_pressure-checkpoint.ipynb b/docs/examples/.ipynb_checkpoints/pyeql_tutorial_osmotic_pressure-checkpoint.ipynb deleted file mode 100644 index 8d7e6336..00000000 --- a/docs/examples/.ipynb_checkpoints/pyeql_tutorial_osmotic_pressure-checkpoint.ipynb +++ /dev/null @@ -1,466 +0,0 @@ -{ - "cells": [ - { - "attachments": { - "b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png": { - "image/png": "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" - } - }, - "cell_type": "markdown", - "id": "305d1216-9791-43dd-8d7f-ec90aa72a307", - "metadata": { - "tags": [] - }, - "source": [ - "# `pyEQL` Tutorial: Calculating Osmotic Pressure\n", - "\n", - "![pyeql-logo.png](attachment:b51ca3f4-e8bd-4b0a-a599-5f6724ad8fe5.png)\n", - "\n", - "`pyEQL` is an open-source `python` library for solution chemistry calculations and ion properties developed by the [Kingsbury Lab](https://www.kingsburylab.org/) at Princeton University.\n", - "\n", - "[Documentation](https://pyeql.readthedocs.io/en/latest/) | [How to Install](https://pyeql.readthedocs.io/en/latest/installation.html) | [GitHub](https://github.com/rkingsbury/pyEQL) " - ] - }, - { - "cell_type": "markdown", - "id": "90c14b65-36f0-4bb2-a3bf-f8e725cc897e", - "metadata": { - "tags": [] - }, - "source": [ - "## Installation\n", - "\n", - "Uncomment and run the code cell below, if you do not already have `pyEQL`" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "abb1f51c-38fc-4543-8b59-057b8c591ba9", - "metadata": {}, - "outputs": [], - "source": [ - "# pip install pyEQL" - ] - }, - { - "cell_type": "markdown", - "id": "1b8efc81-17bb-46dc-8a22-63e71ae458b7", - "metadata": {}, - "source": [ - "## First, create a `Solution`\n", - "\n", - "`pyEQL`'s built-in property database contains Pitzer model parameters for many simple (binary) electrolytes. If such parameters are available, `pyEQL` will use them by default." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "55f1aea5-a5b8-49b8-a8e8-20856c4be6e7", - "metadata": { - "scrolled": true - }, - "outputs": [], - "source": [ - "from pyEQL import Solution\n", - "\n", - "# 2 mol/L NaCl\n", - "s1 = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"})" - ] - }, - { - "cell_type": "markdown", - "id": "23b21981-7568-4e29-a93c-4017a32629b4", - "metadata": {}, - "source": [ - "## Get the osmotic pressure\n", - "\n", - "Note that the osmotic pressure (and most `Solution` properties) are returned as `pint` `Quantity` objects (see [Converting Units](https://pyeql.readthedocs.io/en/latest/units.html))." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "5c037d7c-0a16-4d0a-b2e7-ad2d43a4d3bb", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "10224795.514383134 Pa" - ], - "text/latex": [ - "$10224795.514383134\\ \\mathrm{Pa}$" - ], - "text/plain": [ - "10224795.514383134 " - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.osmotic_pressure" - ] - }, - { - "cell_type": "markdown", - "id": "2b7800c8-e23a-4d6b-9d36-77ac51226fb4", - "metadata": {}, - "source": [ - "If you want the osmotic pressure in different units, or you only want the magnitude, use `to()` and `magnitude`, respectively" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "55f0b945-fe6f-464e-a855-30ec0e5292c5", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "102.24795514383135 bar" - ], - "text/latex": [ - "$102.24795514383135\\ \\mathrm{bar}$" - ], - "text/plain": [ - "102.24795514383135 " - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.osmotic_pressure.to(\"bar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "51adb7d2-40f0-4072-adce-9ca2d980e5ef", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "102.24795514383135" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s1.osmotic_pressure.to(\"bar\").magnitude" - ] - }, - { - "cell_type": "markdown", - "id": "6b754001-1ee7-4348-882a-6e6f6e046b93", - "metadata": {}, - "source": [ - "## Use a `for` loop for multiple calculations\n", - "\n", - "You can rapidly get estimates for multiple concentrations (or temperatures, or solutes) by using a `for` loop. Notice how in the example below, we use [f-strings](https://realpython.com/python-f-strings/) to insert the desired concentration (from the `for` loop) into the argument passed to `Solution` and to print the results." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "53ab967d-1cac-4e3a-9a4d-11f9b28f5bd2", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "At C=0.1 M, the osmotic pressure is 4.63 bar.\n", - "At C=0.5 M, the osmotic pressure is 23.07 bar.\n", - "At C=1.0 M, the osmotic pressure is 47.40 bar.\n", - "At C=2.0 M, the osmotic pressure is 102.25 bar.\n", - "At C=4.0 M, the osmotic pressure is 246.95 bar.\n" - ] - } - ], - "source": [ - "for conc in [0.1, 0.5, 1, 2, 4]:\n", - " s1 = Solution({\"Na+\": f\"{conc} mol/L\", \"Cl-\": f\"{conc} mol/L\"})\n", - " print(f\"At C={conc:.1f} M, the osmotic pressure is {s1.osmotic_pressure.to('bar'):.2f}.\")" - ] - }, - { - "cell_type": "markdown", - "id": "ba4ff669-b6c0-4592-b9be-1b088b548cfc", - "metadata": {}, - "source": [ - "## Compare different modeling engines\n", - "\n", - "`pyEQL` contains several different [modeling engines](https://pyeql.readthedocs.io/en/latest/engines.html) that can calculate activity coefficients or osmotic pressures. At present, there are three options:\n", - "\n", - "1. The `native` or built-in engine, which includes an implementation of the Piter model (Default).\n", - "2. the `phreeqc` engine, which utilizes the USGS PHREEQC model with the `phreeqc.dat` database.\n", - "3. An ideal solution model (`ideal`) which does not account for solution non-ideality.\n", - "\n", - "You select a modeling engine using the `engine` keyword argument when you create a `Solution`. Let's compare the preditions from the three models." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "6962da9e-f510-483f-8ab6-df29a054441a", - "metadata": {}, - "outputs": [], - "source": [ - "s_ideal = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"}, engine=\"ideal\")\n", - "s_phreeqc = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"}, engine=\"phreeqc\")\n", - "s_native = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"}, engine=\"native\")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "2a627a29-e7b4-458e-86bb-e23b71ae8f65", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-10 11:48:57,162 solution.py get_water_activity 1934 Pitzer parameters not found. Water activity set equal to mole fraction\n" - ] - }, - { - "data": { - "text/html": [ - "95.73878424096024 bar" - ], - "text/latex": [ - "$95.73878424096024\\ \\mathrm{bar}$" - ], - "text/plain": [ - "95.73878424096024 " - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s_ideal.osmotic_pressure.to(\"bar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "29ef5458-fc42-44de-a3b5-05e80987f9e8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "95.73878424096024 bar" - ], - "text/latex": [ - "$95.73878424096024\\ \\mathrm{bar}$" - ], - "text/plain": [ - "95.73878424096024 " - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s_phreeqc.osmotic_pressure.to(\"bar\")" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "5807fbde-dddd-4883-8bf0-1014ce08833b", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "102.24795514383135 bar" - ], - "text/latex": [ - "$102.24795514383135\\ \\mathrm{bar}$" - ], - "text/plain": [ - "102.24795514383135 " - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "s_native.osmotic_pressure.to(\"bar\")" - ] - }, - { - "cell_type": "markdown", - "id": "c49fb2e3-71a3-49ff-9f17-35e64f6f6d54", - "metadata": {}, - "source": [ - "## Plot the comparison vs. experiment\n", - "\n", - "We can make a plot showing how the 3 models compare by combining the two previous steps (using a `for` loop plus changing the `engine` keyword argument. Note that this example makes use of `matplotlib` for plotting." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "d38dd675-0767-4eea-ab11-d85c4613e59e", - "metadata": {}, - "outputs": [], - "source": [ - "# create empty lists to hold the results\n", - "pi_ideal = []\n", - "pi_phreeqc = []\n", - "pi_native = []\n", - "\n", - "concentrations = [0.1, 0.2, 0.3, 0.4, 0.5, 1, 1.4, 2, 2.5, 3, 3.5, 4]\n", - "\n", - "for conc in concentrations:\n", - " s_ideal = Solution({\"Na+\": f\"{conc} mol/kg\", \"Cl-\": f\"{conc} mol/kg\"}, engine=\"ideal\")\n", - " s_phreeqc = Solution({\"Na+\": f\"{conc} mol/kg\", \"Cl-\": f\"{conc} mol/kg\"}, engine=\"phreeqc\")\n", - " s_native = Solution({\"Na+\": f\"{conc} mol/kg\", \"Cl-\": f\"{conc} mol/kg\"}, engine=\"native\")\n", - "\n", - " # store the osmotic pressures in the respective lists\n", - " # note that we have to just store the .magnitude because matplotlib can't plot Quantity\n", - " pi_ideal.append(s_ideal.osmotic_pressure.to(\"bar\").magnitude)\n", - " pi_phreeqc.append(s_phreeqc.osmotic_pressure.to(\"bar\").magnitude)\n", - " pi_native.append(s_native.osmotic_pressure.to(\"bar\").magnitude)" - ] - }, - { - "cell_type": "markdown", - "id": "a651b33f-5572-40a2-8587-bd7af7a71170", - "metadata": {}, - "source": [ - "We will include experimental data from the [IDST](https://idst.inl.gov/) as a benchmark. The IDST gives us water activity, which we convert into osmotic pressure according to\n", - "\n", - "$$\n", - "\\Pi = -\\frac{RT}{V_{w}} \\ln a_{w}\n", - "$$\n", - "\n", - "Where $\\Pi$ is the osmotic pressure, $V_{w}$ is the partial molar volume of water (18.2 cm**3/mol), and $a_{w}$ is the water\n", - " activity." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "008d1e80-536b-4346-9527-462deacd6b70", - "metadata": {}, - "outputs": [], - "source": [ - "import math\n", - "\n", - "# water activity at [0.1, 0.2, 0.3, 0.4, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4] mol/kg\n", - "water_activity_idst = [\n", - " 0.99664,\n", - " 0.993353,\n", - " 0.99008,\n", - " 0.986804,\n", - " 0.98352,\n", - " 0.966828,\n", - " 0.953166,\n", - " 0.93191,\n", - " 0.913072,\n", - " 0.89347,\n", - " 0.872859,\n", - " 0.85133,\n", - "]\n", - "\n", - "# calculate osmotic pressure as -RT/Vw ln(a_w). Factor 10 converts to bar.\n", - "pi_idst = [-8.314 * 298.15 / 18.2 * math.log(a) * 10 for a in water_activity_idst]" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "1082bad0-c9e1-4e16-941d-fd908ea402fe", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 0.98, 'pyEQL prediction of NaCl osmotic pressure')" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHgCAYAAABDx6wqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/av/WaAAAACXBIWXMAAA9hAAAPYQGoP6dpAACkeUlEQVR4nOzddVhU6dvA8e/QDaIimGC3gljYCeiqqGviKirqrrXq4tqKtcau65a71hprd3d3YhcWdmAB0jHn/YOX+TligAIDeH+uiwvmnOc85z7DwNzz1FEpiqIghBBCCJFN6ek6ACGEEEKI9CTJjhBCCCGyNUl2hBBCCJGtSbIjhBBCiGxNkh0hhBBCZGuS7AghhBAiW5NkRwghhBDZmiQ7QgghhMjWJNkRQgghRLYmyY4QGUylUuHv7695vGDBAlQqFXfu3EmT+u/cuYNKpWLBggVpUl962b59OxUrVsTExASVSkVISIiuQ/qg/fv3o1Kp2L9/v65DyVA+Pj44OjrqOgwhPoskOyJdqFSq9359++23ycpv3rwZDw8PcubMiYmJCcWLF2fw4MG8fPkyWVkfHx8sLCwy4jIytaVLl/Lbb7/pOoxP8uLFC9q2bYupqSkzZsxg0aJFmJubv7NsUjJoYmLCw4cPk+2vW7cuZcuW/ax41q1bh6enJ7ly5cLIyIi8efPStm1b9u7d+1n1ZhWPHj3C39+fc+fO6ToUIdKFga4DENlXo0aN6Ny5c7LtxYsX13rs5+fHtGnTqFChAkOGDMHW1pYzZ87w559/smLFCvbs2UOxYsUyKuwM980339C+fXuMjY1TddzSpUu5dOkSAwYM0NpeqFAhoqKiMDQ0TMMo09apU6d4/fo148ePp2HDhik6JiYmhsmTJ/Pnn3+mWRyKotCtWzcWLFiAs7MzgwYNwt7ensePH7Nu3ToaNGjAkSNHcHNzS7NzZkaPHj1i7NixODo6UrFiRa19c+bMQa1W6yYwIdKIJDsi3RQvXpxOnTp9sMyyZcuYNm0a7dq1Y8mSJejr62v2+fj4UK9ePdq0acPp06cxMNDtyzUyMhIzM7M0r1dfX1/ruj9XUitIZhYcHAyAjY1Nio+pWLEic+bMYdiwYeTNmzdN4pg2bRoLFixgwIAB/Prrr6hUKs2+ESNGsGjRIp2/7nQtsyTN0dHRGBkZoaeXdTokIiIi3ttiKTJW1nnViHTj7++PSqXi2rVrtG3bFisrK3LmzMn3339PdHS0plydOnWoUKHCO+soUaIE7u7uqT732LFjyZEjB7Nnz072hl+lShWGDBnC+fPnWbt2barrflvSmIsVK1YwfPhw7O3tMTc3p3nz5ty/f1+rbFLXSEBAALVr18bMzIzhw4cDiS0MY8aMoWjRohgbG1OgQAF+/PFHYmJitOqIiYlh4MCB5M6dG0tLS5o3b86DBw+SxfW+MTvbtm2jTp06WFpaYmVlReXKlVm6dKkmvi1btnD37l1N92DSuIr3jdnZu3cvtWrVwtzcHBsbG1q0aMHVq1e1yiS9Fm7evImPjw82NjZYW1vTtWtXIiMjU/Q8r1q1ikqVKmFqakquXLno1KmTVvdT3bp16dKlCwCVK1dGpVLh4+Pz0XqHDx9OQkICkydP/mjZ+fPnU79+fezs7DA2NqZ06dL8888/WmWioqKYNGkSJUuW5JdfftFKdJJ88803VKlS5aPne9vZs2fx9PTEysoKCwsLGjRowPHjx7XKxMXFMXbsWIoVK4aJiQk5c+akZs2a7Nq1S1Mmqcv23r17fPXVV1hYWJAvXz5mzJgBwMWLF6lfvz7m5uYUKlRI8/p40+3bt2nTpg22traYmZlRrVo1tmzZotm/f/9+KleuDEDXrl01r6ek18+7xuyo1Wp+//13ypUrh4mJCblz58bDw4PTp09/8Hl58+/Kzc0NU1NTnJycmDlzpla5pL/V5cuXM3LkSPLly4eZmRlhYWEAnDhxAg8PD6ytrTEzM6NOnTocOXJEq47Xr18zYMAAHB0dMTY2xs7OjkaNGnHmzBlNmRs3btC6dWvs7e0xMTEhf/78tG/fntDQUODD49/eHnuX9Ldz5coVOnbsSI4cOahZs6Zm/+LFizV/F7a2trRv3z7Z/x2Rfr7sjyxCS9u2bXF0dGTSpEkcP36cP/74g1evXvHff/8Bif/4e/TowaVLl7TGSJw6dYrr168zcuRIrfqio6N5/vx5svNYWVlhZGTEjRs3CAwMxMfHBysrq3fG1LlzZ8aMGcOmTZto27ZtmlznxIkTUalUDBkyhODgYH777TcaNmzIuXPnMDU11ZR78eIFnp6etG/fnk6dOpEnTx7UajXNmzfn8OHD9OzZk1KlSnHx4kWmT5/O9evXWb9+veZ4X19fFi9eTMeOHXFzc2Pv3r00bdo0RTEuWLCAbt26UaZMGYYNG4aNjQ1nz55l+/btdOzYkREjRhAaGsqDBw+YPn06wAfHMe3evRtPT08KFy6Mv78/UVFR/Pnnn9SoUYMzZ84kezNr27YtTk5OTJo0iTNnzjB37lzs7OyYMmXKR+Pu2rUrlStXZtKkSTx9+pTff/+dI0eOcPbsWWxsbBgxYgQlSpRg9uzZjBs3DicnJ4oUKfLR58TJyYnOnTszZ84chg4d+sHWnX/++YcyZcrQvHlzDAwM2LRpE71790atVtOnTx8ADh8+zMuXLxkwYECatqxdvnyZWrVqYWVlxY8//oihoSGzZs2ibt26HDhwgKpVqwKJb46TJk3C19eXKlWqEBYWxunTpzlz5gyNGjXS1JeQkICnpye1a9dm6tSpLFmyhL59+2Jubs6IESPw9vamVatWzJw5k86dO1O9enWcnJwAePr0KW5ubkRGRtK/f39y5szJwoULad68OatXr6Zly5aUKlWKcePGMXr0aHr27EmtWrUAPth11717dxYsWICnpye+vr7Ex8dz6NAhjh8/jqur6wefn1evXtGkSRPatm1Lhw4dWLlyJd999x1GRkZ069ZNq+z48eMxMjLCz8+PmJgYjIyM2Lt3L56enlSqVIkxY8agp6enSW4PHTqkSU6//fZbVq9eTd++fSldujQvXrzg8OHDXL16FRcXF2JjY3F3dycmJoZ+/fphb2/Pw4cP2bx5MyEhIVhbW6f+lw+0adOGYsWK8dNPP6EoCpD4P2fUqFG0bdsWX19fnj17xp9//knt2rU1fxcinSniizdmzBgFUJo3b661vXfv3gqgnD9/XlEURQkJCVFMTEyUIUOGaJXr37+/Ym5uroSHh2u2Ae/9WrZsmaIoirJ+/XoFUKZPn/7B+KysrBQXFxfN4y5duijm5uapvs59+/YpgJIvXz4lLCxMs33lypUKoPz++++abXXq1FEAZebMmVp1LFq0SNHT01MOHTqktX3mzJkKoBw5ckRRFEU5d+6cAii9e/fWKtexY0cFUMaMGaPZNn/+fAVQgoKCFEVJfJ4tLS2VqlWrKlFRUVrHq9Vqzc9NmzZVChUqlOw6g4KCFECZP3++ZlvFihUVOzs75cWLF5pt58+fV/T09JTOnTtrtiW9Frp166ZVZ8uWLZWcOXMmO9ebYmNjFTs7O6Vs2bJacW/evFkBlNGjRye75lOnTn2wzrfL3rp1SzEwMFD69++v2V+nTh2lTJkyWsdERkYmq8fd3V0pXLiw5vHvv/+uAMq6des+GoOi/O/1s2/fvg+W8/LyUoyMjJRbt25ptj169EixtLRUateurdlWoUIFpWnTph+sq0uXLgqg/PTTT5ptr169UkxNTRWVSqUsX75cs/3atWvJXlsDBgxQAK3X6+vXrxUnJyfF0dFRSUhIUBRFUU6dOpXsNfNmDG++zvbu3asAWr+DJG++Pt8l6e9q2rRpmm0xMTGa12dsbKyiKP97rgsXLqz1u1Sr1UqxYsUUd3d3rXNFRkYqTk5OSqNGjTTbrK2tlT59+rw3lrNnzyqAsmrVqveWedffUpK3n+ukv50OHTpolbtz546ir6+vTJw4UWv7xYsXFQMDg2TbRfqQbiyhkfSJN0m/fv0A2Lp1KwDW1ta0aNGCZcuWaT6xJCQksGLFCry8vJL1Tbdo0YJdu3Yl+6pXrx6Q2MwMYGlp+cG4LC0tNWXTQufOnbXO+fXXX+Pg4KC5ziTGxsZ07dpVa9uqVasoVaoUJUuW5Pnz55qv+vXrA7Bv3z7gf89Z//79tY5/ezDxu+zatYvXr18zdOjQZGNv3tXV8jGPHz/m3Llz+Pj4YGtrq9levnx5GjVqlOy6gWQz5mrVqsWLFy803Qjvcvr0aYKDg+ndu7dW3E2bNqVkyZJaXSefqnDhwnzzzTfMnj2bx48fv7fcmy10oaGhPH/+nDp16nD79m1NF0XStXzs9ZcaCQkJ7Ny5Ey8vLwoXLqzZ7uDgQMeOHTl8+LDmvDY2Nly+fJkbN258tF5fX1/NzzY2NpQoUQJzc3Ot1s4SJUpgY2PD7du3Ndu2bt1KlSpVtLpTLCws6NmzJ3fu3OHKlSupvsY1a9agUqkYM2ZMsn0peX0aGBjQq1cvzWMjIyN69epFcHAwAQEBWmW7dOmi9bs8d+4cN27coGPHjrx48ULz9xcREUGDBg04ePCgZjC1jY0NJ06c4NGjR++MI6nlZseOHSnuok2Jt/921q5di1qtpm3btlr/M+zt7SlWrJjmf4ZIX5LsCI23ZzwVKVIEPT09rbEknTt35t69exw6dAhI7B55+vQp33zzTbL68ufPT8OGDZN95cmTB/jfm8zHEpnXr19jZ2f3OZem5e3rVKlUFC1aNNmYmXz58mFkZKS17caNG1y+fJncuXNrfSXNMEsaeHv37l309PSSdc+UKFHio/HdunUL4LOnUye5e/fue89dqlQpzZvFmwoWLKj1OEeOHEBiF8SnnKdkyZKa/Z9r5MiRxMfHf3DszpEjR2jYsKFmfFLu3Lk1Y66Skp2krtO0TKSfPXtGZGTke59rtVqtGacxbtw4QkJCKF68OOXKlWPw4MFcuHAh2XFJY2LeZG1tTf78+ZMlF9bW1lq/o7t37743lqT9qXXr1i3y5s2rlTinRt68eZN9MEr6+3n7bzCpOy5JUmLYpUuXZH+Dc+fOJSYmRvP7nTp1KpcuXaJAgQJUqVIFf39/rUTQycmJQYMGMXfuXHLlyoW7uzszZszQHP+p3hWzoigUK1YsWcxXr17V/M8Q6UvG7Ij3etenNHd3d/LkycPixYupXbs2ixcvxt7ePsXTh99UunRpgHf+g09y9+5dwsLCtD4lZ5Q3P1EmUavVlCtXjl9//fWdxxQoUCC9w8oQ7xvDktSip0uFCxemU6dOzJ49m6FDhybbf+vWLRo0aEDJkiX59ddfKVCgAEZGRmzdupXp06drPvmXLFkSSBzk6+XllZGXAEDt2rW5desWGzZsYOfOncydO5fp06czc+ZMrZac9/0uMvPvKK28/TeY9Lv7+eefk02RT5I0dq1t27bUqlWLdevWsXPnTn7++WemTJnC2rVr8fT0BBJn4/n4+Gh+B/3799eMWXxXMpkkISEhVTGrVCq2bdv2zt+ZrBmWMSTZERo3btzQ+lRy8+ZN1Gq11uBVfX19OnbsyIIFC5gyZQrr16+nR48enzTAs1ixYpQoUYL169fz+++/v7M7IWlwdJs2bVJ/Qe/xdreBoijcvHmT8uXLf/TYIkWKcP78eRo0aPDBJvtChQqhVqu5deuW1ifrwMDAFJ0D4NKlSxQtWvS95VLapVWoUKH3nvvatWvkypUrTabHvnmepG69JIGBgZr9aWHkyJEsXrz4nQOmN23aRExMDBs3btRqoXq7u6BmzZrkyJGDZcuWMXz48DQZpJw7d27MzMze+1zr6elpJcS2trZ07dqVrl27Eh4eTu3atfH399dKdj5HoUKF3htL0n5IXfdokSJF2LFjBy9fvvyk1p1Hjx4lm5J9/fp1gI+u1Jz0t2FlZZWiD1gODg707t2b3r17ExwcjIuLCxMnTtQkOwDlypWjXLlyjBw5kqNHj1KjRg1mzpzJhAkTNC2ab6/unZoWsSJFiqAoCk5OTsnWGBMZR7qxhEbSdNYkSYu3vfmPARJnZb169YpevXoRHh7+0bV0PmTMmDG8evWKb7/9NtmnpYCAAKZMmYKzs3OyGD7Hf//9p9V1sXr1ah4/fpyic7Rt25aHDx8yZ86cZPuioqI03UFJdf3xxx9aZVKy4nHjxo2xtLRk0qRJWlP/QftTu7m5eYqa3B0cHKhYsSILFy7U+qd96dIldu7cSZMmTT5aR0q4urpiZ2fHzJkztabhb9u2jatXr6Z4JlpKFClShE6dOjFr1iyePHmitS8paXnzuQoNDWX+/Pla5czMzBgyZAhXr15lyJAh72wRWbx4MSdPnkxxXPr6+jRu3JgNGzZodck8ffqUpUuXUrNmTU332YsXL7SOtbCwoGjRosmWMPgcTZo04eTJkxw7dkyzLSIigtmzZ+Po6KhpXU1KPFJyy47WrVujKApjx45Nti8lrUrx8fHMmjVL8zg2NpZZs2aRO3duKlWq9MFjK1WqRJEiRfjll18IDw9Ptv/Zs2dAYsvL238bdnZ25M2bV/P8hoWFER8fr1WmXLly6OnpacpYWVmRK1cuDh48qFXu77///uh1JmnVqhX6+vqMHTs22fOjKEqy14FIH9KyIzSCgoJo3rw5Hh4eHDt2TDNt+u21dZydnSlbtqxmsK6Li8s767t+/TqLFy9Otj1PnjyaqbUdOnTg9OnT/Prrr1y5cgVvb29y5MjBmTNnmDdvHrlz52b16tXJFnaLi4tjwoQJyeq2tbWld+/eH7xOW1tbatasSdeuXXn69Cm//fYbRYsWpUePHh88DhITvZUrV/Ltt9+yb98+atSoQUJCAteuXWPlypXs2LEDV1dXKlasSIcOHfj7778JDQ3Fzc2NPXv2cPPmzY+ew8rKiunTp+Pr60vlypU1a3acP3+eyMhIFi5cCCT+41+xYgWDBg2icuXKWFhY0KxZs3fW+fPPP+Pp6Un16tXp3r27Zuq5tbW11lohn8PQ0JApU6bQtWtX6tSpQ4cOHTRTzx0dHRk4cGCanCdJ0qJ/gYGBlClTRrO9cePGGBkZ0axZM01CPmfOHOzs7JINah48eDCXL19m2rRp7Nu3j6+//hp7e3uePHnC+vXrOXnyJEePHk1VXBMmTGDXrl3UrFmT3r17Y2BgwKxZs4iJiWHq1KmacqVLl6Zu3bpUqlQJW1tbTp8+rZkqnVaGDh3KsmXL8PT0pH///tja2rJw4UKCgoJYs2aNZoG+IkWKYGNjw8yZM7G0tMTc3JyqVasmG38CUK9ePb755hv++OMPbty4gYeHB2q1mkOHDlGvXr2Pxp83b16mTJnCnTt3KF68OCtWrODcuXPMnj37owsY6unpMXfuXDw9PSlTpgxdu3YlX758PHz4kH379mFlZcWmTZt4/fo1+fPn5+uvv6ZChQpYWFiwe/duTp06xbRp04DEdaf69u1LmzZtKF68OPHx8SxatAh9fX1at26tOaevry+TJ0/G19cXV1dXDh48qGmJSokiRYowYcIEhg0bxp07d/Dy8sLS0pKgoCDWrVtHz5498fPzS3F94hPpZA6YyFSSpkxeuXJF+frrrxVLS0slR44cSt++fZNNfU4yderUZFNi38QHpp7XqVMnWfmNGzcqDRs2VGxsbDTlypQpo4SGhiYrmzQd911fRYoUee91Jk1nXbZsmTJs2DDFzs5OMTU1VZo2barcvXtXq+y7pjMniY2NVaZMmaKUKVNGMTY2VnLkyKFUqlRJGTt2rFa8UVFRSv/+/ZWcOXMq5ubmSrNmzZT79+9/dOr5m8+Jm5ubYmpqqlhZWSlVqlTRTNtXFEUJDw9XOnbsqHnOkqYHv2+67O7du5UaNWpo6mvWrJly5coVrTJJr4Vnz55pbX9fjO+yYsUKxdnZWTE2NlZsbW0Vb29v5cGDB++sL7VTz9+W9Fp4+3e1ceNGpXz58oqJiYni6OioTJkyRZk3b957r2H16tVK48aNFVtbW8XAwEBxcHBQ2rVrp+zfv19TJqVTzxVFUc6cOaO4u7srFhYWipmZmVKvXj3l6NGjWmUmTJigVKlSRbGxsVFMTU2VkiVLKhMnTtRMv066vncts/C+12ehQoWSTWe/deuW8vXXXys2NjaKiYmJUqVKFWXz5s3Jjt2wYYNSunRpxcDAQOv18/bUc0VRlPj4eOXnn39WSpYsqRgZGSm5c+dWPD09lYCAgA8+L0lxnz59WqlevbpiYmKiFCpUSPnrr7+0yiU91++bFn727FmlVatWSs6cORVjY2OlUKFCStu2bZU9e/YoipI4nX3w4MFKhQoVFEtLS8Xc3FypUKGC8vfff2vquH37ttKtWzelSJEiiomJiWJra6vUq1dP2b17t9a5IiMjle7duyvW1taKpaWl0rZtWyU4OPi9U8/f/ttJsmbNGqVmzZqKubm5Ym5urpQsWVLp06ePEhgY+MHnTKQNlaJko9Fs4pP4+/szduxYnj17Rq5cuVJ0zO+//87AgQO5c+dOspk7acHX15d///2XOXPmpNn4hf3791OvXj1WrVrF119/nSZ1CiFSrm7dujx//pxLly7pOhTxhZFuLJFqiqLw77//UqdOnXRJdABmzZrF06dP+e6778ibN2+ajSsRQgjx5ZFkR6RYREQEGzduZN++fVy8eJENGzak27n09fXZtGlTutUvhBDiyyHJjkixZ8+e0bFjR2xsbBg+fDjNmzfXdUhCCCHER8mYHSGEEEJka7LOjhBCCCGyNUl2hBBCCJGtSbIjhBBCiGxNkh0hhBBCZGuS7AghhBAiW5NkRwghhBDZmiQ7QgghhMjWJNkRQgghRLYmyY4QQgghsjVJdoQQQgiRrUmyI4QQQohsTZIdIYQQQmRrkuwIIYQQIluTZEcIIYQQ2ZokO0IIIYTI1iTZEUIIIUS2JsmOEEIIIbI1SXaEEEIIka1JsiOEEEKIbE2SHSGEEEJka5LsCCGEECJbk2RHCCGEENmaJDtCCCGEyNYk2RFCCCFEtibJjhBCCCGyNUl2hBBCCJGtSbIjhBBCiGzNQNcBZAZqtZpHjx5haWmJSqXSdThCCCGESAFFUXj9+jV58+ZFT+/97TeS7ACPHj2iQIECug5DCCGEEJ/g/v375M+f/737JdkBLC0tgcQny8rKSsfRCCGEECIlwsLCKFCggOZ9/H0k2QFN15WVlZUkO0IIIUQW87EhKDJAWQghhBDZmiQ7QgghhMjWJNkRQgghRLYmY3ZSSK1WExsbq+swhPggQ0ND9PX1dR2GEEJkKpLspEBsbCxBQUGo1WpdhyLER9nY2GBvby9rRgkhxP+TZOcjFEXh8ePH6OvrU6BAgQ8uWiSELimKQmRkJMHBwQA4ODjoOCIhhMgcJNn5iPj4eCIjI8mbNy9mZma6DkeIDzI1NQUgODgYOzs76dISQghkgPJHJSQkAGBkZKTjSIRImaSkPC4uTseRCCFE5iDJTgrJ+AeRVchrVQghtEmyI4QQQohsTZId8Vl8fHzw8vLSdRhaVCoV69evf+/+O3fuoFKpOHfuXJqdMz3qFEIIkTZkgLL4LL///juKoug0hrp16+Lj44OPjw8Ajx8/JkeOHDqN6c6dOzg5Oen8uRFCCCEtO+IzWVtbY2Njo+swtNjb22NsbKzrMIQQ4svl7w/jxwMQHBzBsWP3/7dv/PjE/RlIkp1sTK1WM2nSJJycnDA1NaVChQqsXr0agP3796NSqdizZw+urq6YmZnh5uZGYGCgVh0TJkzAzs4OS0tLfH19GTp0KBUrVtTsf7sbq27duvTv358ff/wRW1tb7O3t8X/rRR0SEoKvry+5c+fGysqK+vXrc/78+TS77re7sU6ePImzszMmJia4urpy9uzZZMdcunQJT09PLCwsyJMnD9988w3Pnz/X7N++fTs1a9bExsaGnDlz8tVXX3Hr1q00i1kIIbIVfX0YPZqXA4dTo8Y83N0Xc+7ck8REZ/ToxP0ZSJKdTxQbG/ver/j4+BSXfXt68PvKfYpJkybx33//MXPmTC5fvszAgQPp1KkTBw4c0JQZMWIE06ZN4/Tp0xgYGNCtWzfNviVLljBx4kSmTJlCQEAABQsW5J9//vnoeRcuXIi5uTknTpxg6tSpjBs3jl27dmn2t2nThuDgYLZt20ZAQAAuLi40aNCAly9fAnDo0CEsLCw++LVkyZIUPQfh4eF89dVXlC5dmoCAAPz9/fHz89MqExISQv369XF2dub06dNs376dp0+f0rZtW02ZiIgIBg0axOnTp9mzZw96enq0bNlSVtUWQoh3GTWKx98Nxva3SbS/uQ5bW1Pyz/89MdEZNw5GjcrQcFSKDCogLCwMa2trQkNDsbKy0toXHR1NUFAQTk5OmJiYaLaPHTv2vfUVK1aMjh07ah7/9NNP713zpFChQpqxJgA///wzkZGRycqNGTMmpZcDQExMDLa2tuzevZvq1atrtvv6+hIZGUnPnj2pV68eu3fvpkGDBgBs3bqVpk2bEhUVhYmJCdWqVcPV1ZW//vpLc3zNmjUJDw/XDMT18fEhJCRE05JSt25dEhISOHTokOaYKlWqUL9+fSZPnszhw4dp2rQpwcHBWl1NRYsW5ccff6Rnz55ERUXx8OHDD15fnjx5sLS0fOc+lUrFunXr8PLyYvbs2QwfPpwHDx5ofn8zZ87ku+++4+zZs1SsWJEJEyZw6NAhduzYoanjwYMHFChQgMDAQIoXL57sHM+fPyd37txcvHiRsmXLasboJNWpS+97zQohREbZv/8OLVosp3/YTsazD8XICFVsbJonOh96/36TDFDOpm7evElkZCSNGjXS2h4bG4uzs7Pmcfny5TU/J91eIDg4mIIFCxIYGEjv3r21jq9SpQp79+794LnfrDOp3qRbGJw/f57w8HBy5sypVSYqKkrTLWRqakrRokVTcpkfdfXqVcqXL6/1pv9m8pcU0759+7CwsEh2/K1btyhevDg3btxg9OjRnDhxgufPn2tadO7du0fZsmXTJFYhhMgOVq++grf3WmJjEzhYuzPK8SOJiY6RUYa36CSRZOcTDRs27L373r5/1tvdJm96ewG477///vMC+3/h4eEAbNmyhXz58mntMzY21iQWhoaGyWL53K6ZN+tMqjepzvDwcBwcHNi/f3+y45IGOh86dAhPT88PnmPWrFl4e3t/VpxJwsPDadasGVOmTEm2LykBbNasGYUKFWLOnDnkzZsXtVpN2bJlP7mLUQghsqN//jlFnz5bURRo1aoUy8teRXXw/xOd2NjEMTs6SHgk2flEqbl9RHqV/ZDSpUtjbGzMvXv3qFOnTrL9KRlcW6JECU6dOkXnzp01206dOvVZcbm4uPDkyRMMDAxwdHR8ZxlXV9ePrleTJ0+eFJ2vVKlSLFq0iOjoaE3rzvHjx5PFtGbNGhwdHTEwSP4n8eLFCwIDA5kzZw61atUC4PDhwyk6vxBCfAkURcHffz/jxh0EoFevSvztcAY9f///dV0lDU6GDE94JNnJpiwtLfHz82PgwIGo1Wpq1qxJaGgoR44cwcrKikKFCn20jn79+tGjRw9cXV1xc3NjxYoVXLhwgcKFC39yXA0bNqR69ep4eXkxdepUihcvzqNHj9iyZQstW7bE1dU1TbuxOnbsyIgRI+jRowfDhg3jzp07/PLLL1pl+vTpw5w5c+jQoYNmFtnNmzdZvnw5c+fOJUeOHOTMmZPZs2fj4ODAvXv3GDp0aJrEJ4QQWV18vJo+fbYwe/YZAPz96zBadRDVmDHaY3SSvusg4ZFkJxsbP348uXPnZtKkSdy+fRsbGxtcXFwYPnx4irqqvL29uX37Nn5+fkRHR9O2bVt8fHw4efLkJ8ekUqnYunUrI0aMoGvXrjx79gx7e3tq166d4taa1LCwsGDTpk18++23ODs7U7p0aaZMmULr1q01ZfLmzcuRI0cYMmQIjRs3JiYmhkKFCuHh4YGenh4qlYrly5fTv39/ypYtS4kSJfjjjz+oW7dumscrhBBZSXR0PB06rGH9+muoVPD330359ltX8N//7sHISY///ybbGUVmY/Fps7G+VI0aNcLe3p5FixbpOhTxHvKaFUJkhJCQaJo3X8ahQ/cwMtJn6dJWtG5dOkNjkNlY4rNFRkYyc+ZM3N3d0dfXZ9myZezevVtrzRwhhBBfnkePXuPhsZiLF4OxsjJm48b21KnjqOuw3kuSHfFeSV1OEydOJDo6mhIlSrBmzRoaNmyo69CEEELoSGDgc9zdF3P3bij29hZs3+5NhQr2ug7rgyTZEe9lamrK7t27dR2GEEKITOLkyYc0abKEFy+iKFbMlh07OuHkpNsbL6eEJDtCCCGE+Kjt22/SuvVKIiPjcHXNy9atHcmd21zXYaWI3BtLCCGEEB+0ePEFmjVbRmRkHI0bF2Hfvi5ZJtEBSXaEEEII8QHTph3lm2/WER+vpmPHcmza1AELi7RZADejSLIjhBBCiGTUaoXBg3fi55c4A3fgwGosWtQSIyN9HUeWejJmRwghhBBa4uIS6N59I4sWXQBgypSGDB7slux+jlmFJDtCCCGE0IiIiKVNm1Vs23YTfX0V//7bnC5dKuo6rM8i3Vjis/j4+ODl5aXrMFLlzp07qFSqj95sVAghvjTPn0dSv/5/bNt2E1NTAzZsaJ/lEx2QZEd8pt9//50FCxboNIa6devqPIaMtH///vfeMV4IIT7V3bsh1Kw5j5MnH2Jra8revV1o2rS4rsNKE9KNJT6LtbW1rkPIEAkJCahUKvT05POBECL7uXjxKR4eS3j06DUFClixY0cnSpXKreuw0oz8587G1Go1kyZNwsnJCVNTUypUqMDq1auBxNYBlUrFnj17cHV1xczMDDc3NwIDA7XqmDBhAnZ2dlhaWuLr68vQoUOpWLGiZv/b3Vh169alf//+/Pjjj9ja2mJvb4+/v79WnSEhIfj6+pI7d26srKyoX78+58+fT7PrVqlU/PPPP3h6emJqakrhwoU11/2m27dvU69ePczMzKhQoQLHjh3T7FuwYAE2NjZs3LiR0qVLY2xszL1794iJicHPz498+fJhbm5O1apV2b9/v1a9hw8fplatWpiamlKgQAH69+9PRESEZn9wcDDNmjXD1NQUJycnlixZgqOjI7/99pvWc9SrVy/y5MmDiYkJZcuWZfPmzWn2HAkhRJJDh+5Sq9Z8Hj16TZkyuTl6tHu2SnRAkp1PFhEbQURsBG/eND42IZaI2Ahi4mPeWVatqDXb4hLiiIiNIDo+OkVlP8WkSZP477//mDlzJpcvX2bgwIF06tSJAwcOaMqMGDGCadOmcfr0aQwMDOjWrZtm35IlS5g4cSJTpkwhICCAggUL8s8//3z0vAsXLsTc3JwTJ04wdepUxo0bp3Xz0DZt2hAcHMy2bdsICAjAxcWFBg0a8PLlSwAOHTqEhYXFB7+WLFnywRhGjRpF69atOX/+PN7e3rRv356rV69qlRkxYgR+fn6cO3eO4sWL06FDB+Lj4zX7IyMjmTJlCnPnzuXy5cvY2dnRt29fjh07xvLly7lw4QJt2rTBw8ODGzduAHDr1i08PDxo3bo1Fy5cYMWKFRw+fJi+fftq6vXx8eH+/fvs27eP1atX8/fffxMcHKzZr1ar8fT05MiRIyxevJgrV64wefJk9PWz3nRPIUTmtn79NRo1WkRoaAw1ahTg0KGu5M///ruHZ1mKUEJDQxVACQ0NTbYvKipKuXLlihIVFaW1HX8U/FGCw4M12yYcmKDgj+K7wVerrNlEMwV/lKBXQZpt049NV/BH6bimo1bZXFNzKfijXHp6SbNt9unZqb6m6OhoxczMTDl69KjW9u7duysdOnRQ9u3bpwDK7t27Nfu2bNmiAJprrVq1qtKnTx+t42vUqKFUqFBB87hLly5KixYtNI/r1Kmj1KxZU+uYypUrK0OGDFEURVEOHTqkWFlZKdHR0VplihQposyaNUtRFEWJjIxUbty48cGvsLCw9147oHz77bda26pWrap89913iqIoSlBQkAIoc+fO1ey/fPmyAihXr15VFEVR5s+frwDKuXPnNGXu3r2r6OvrKw8fPtSqu0GDBsqwYcMURUl8fnv27Km1/9ChQ4qenp4SFRWlBAYGKoBy8uRJzf6rV68qgDJ9+nRFURRlx44dip6enhIYGPjea/yQ971mhRDiTbNnn1b09MYq4K80a7ZUiYiI1XVIqfah9+83yZidbOrmzZtERkbSqFEjre2xsbE4OztrHpcvX17zs4ODA5DYzVKwYEECAwPp3bu31vFVqlRh7969Hzz3m3Um1ZvUcnH+/HnCw8PJmTOnVpmoqChu3boFJN6AtGjRoim5zPeqXr16ssdvz75637WXLFkSACMjI60yFy9eJCEhgeLFtQfsxcTEaK7n/PnzXLhwQavlSVEU1Go1QUFBXL9+HQMDAypVqqTZX7JkSWxsbDSPz507R/78+ZOdRwgh0oKiKEyYcJDRo/cD0L27MzNnfoWBQfbt7JFk5xOFDwsHwMzQTLNtcI3BDKg2AAM97ac12C/xjd7U0FSzrU/lPvRw6YG+nnbXxJ3v7yQr61PRJ/XxhSfGt2XLFvLly6e1z9jYWJNYGBoaarYnLRalVqv5HG/WmVRvUp3h4eE4ODgkG+cCaN7wDx06hKen5wfPMWvWLLy9vdMsznddu6mpqdYCWuHh4ejr6xMQEJCsS8nCwkJTplevXvTv3z/Z+QoWLMj169c/GpepqelHywghxKdISFDz/ffbmTHjFAAjRtRi/Ph6WXaxwJSSZOcTmRslvwGakb4RRvrJ7xfyrrKG+oYY6humuGxqvTmotk6dOsn2JyU7H1KiRAlOnTpF586dNdtOnTqV6lje5OLiwpMnTzAwMHjv9GlXV9eProGTJ0+eD+4/fvy4VtzHjx/XatH6FM7OziQkJBAcHEytWrXeWcbFxYUrV668t2WqZMmSxMfHExAQQOXKlQEIDAwkJCREU6Z8+fI8ePCA69evS+uOECLNxMTE06nTOlavvoJKBb//7kG/flV1HVaGkGQnm7K0tMTPz4+BAweiVqupWbMmoaGhHDlyBCsrKwoVKvTROvr160ePHj1wdXXFzc2NFStWcOHCBQoXLvzJcTVs2JDq1avj5eXF1KlTKV68OI8ePWLLli20bNkSV1fXNOnGWrVqFa6urtSsWZMlS5Zw8uRJ/v3338+qs3jx4nh7e9O5c2emTZuGs7Mzz549Y8+ePZQvX56mTZsyZMgQqlWrRt++ffH19cXc3JwrV66wa9cu/vrrL0qUKIGHhwe9evXin3/+wcDAgAEDBmi15tSpU4fatWvTunVrfv31V4oWLcq1a9dQqVR4eHh81jUIIb5MoaHRtGy5gn377mBoqMfixa1o27aMrsPKMNm3g04wfvx4Ro0axaRJkyhVqhQeHh5s2bIFJyenFB3v7e3NsGHD8PPzw8XFhaCgIHx8fDAxMfnkmFQqFVu3bqV27dp07dqV4sWL0759e+7evfvR1prUGDt2LMuXL6d8+fL8999/LFu2jNKlS392vfPnz6dz58788MMPlChRAi8vL06dOkXBggWBxFaZAwcOcP36dWrVqoWzszOjR48mb968WnXkzZuXOnXq0KpVK3r27ImdnZ3WedasWUPlypXp0KEDpUuX5scffyQhIeGz4xdCfHmePAmnbt2F7Nt3BwsLI7Zt8/6iEh0AlaK8MXf6CxUWFoa1tTWhoaFYWWlPuYuOjiYoKAgnJ6fPepPPLho1aoS9vT2LFi3SdSjvpVKpWLduXZa6jYWjoyMDBgxgwIABn12XvGaFEElu3nxJ48aLCAoKwc7OnG3bvHFxcdB1WGnmQ+/fb9Jpy86kSZOoXLkylpaW2NnZ4eXllWxRu+joaPr06UPOnDmxsLCgdevWPH36VKvMvXv3aNq0KWZmZtjZ2TF48GCt9VLEp4mMjOTXX3/l8uXLXLt2jTFjxrB79266dOmi69CEEEJ8REDAI9zc/iUoKITChXNw9Gi3bJXopIZOk50DBw7Qp08fjh8/zq5du4iLi6Nx48Zaq80OHDiQTZs2sWrVKg4cOMCjR49o1aqVZn9CQgJNmzYlNjaWo0ePsnDhQhYsWMDo0aN1cUnZyptdTpUqVWLTpk2sWbOGhg0b6jo0IYQQH7B7923q1l3Is2eRODvbc/RoN4oUsdV1WDqTqbqxnj17hp2dHQcOHKB27dqEhoaSO3duli5dytdffw3AtWvXKFWqFMeOHaNatWps27aNr776ikePHmnGfMycOZMhQ4bw7NkzjIySz46KiYkhJuZ/qxyHhYVRoEAB6cYS2YK8ZoX4si1ffonOndcRF6emfn0n1q1rh5WVsa7DShdZohvrbaGhoQDY2iZmnwEBAcTFxWm1JJQsWZKCBQtq7mN07NgxypUrpzW41d3dnbCwMC5fvvzO80yaNAlra2vNV4ECBdLrkoQQQogM88cfJ+jQYQ1xcWrati3D1q0ds22ikxqZJtlRq9UMGDCAGjVqULZsWQCePHmCkZGR1uqykLjGypMnTzRl3p7Fk/Q4qczbhg0bRmhoqObr/v37aXw1QgghRMZRFIXhw/fw/ffbAejbtzLLlrXG2FhWmIFMtM5Onz59uHTpEocPH073cxkbG2NsLJmuEEKIrC8+Xk2vXpuYN+8cABMm1GP48FrZflXk1MgULTt9+/Zl8+bN7Nu3j/z582u229vbExsbq7W6LMDTp0+xt7fXlHl7dlbS46QyQgghRHYUGRlHy5YrmDfvHHp6KubMacaIEbUl0XmLTpMdRVHo27cv69atY+/evckWu6tUqRKGhobs2bNHsy0wMJB79+5pbvRYvXp1Ll68qLnRJMCuXbuwsrJKk0XkhBBCiMzo5csoGjVaxObN1zExMWDdunb4+rroOqxMSafdWH369GHp0qVs2LABS0tLzRgba2trTE1Nsba2pnv37gwaNAhbW1usrKzo168f1atXp1q1agA0btyY0qVL88033zB16lSePHnCyJEj6dOnj3RVCSGEyJbu3w/Fw2MJV648w8bGhE2bOlCzZkFdh5Vp6bRl559//iE0NJS6devi4OCg+VqxYoWmzPTp0/nqq69o3bo1tWvXxt7enrVr12r26+vrs3nzZvT19alevTqdOnWic+fOjBs3TheX9MXx8fHJUisVf447d+6gUqk+epNSIYRIT1evPsPNbR5XrjwjXz5LDh3qKonOR2SqdXZ0RW4X8elCQ0NRFCXZjLmMVLduXXx8fPDx8UmzOn18fAgJCWH9+vWabQkJCTx79oxcuXJhYJA2jaILFixgwYIF7N+/P03qA3nNCpGdHTt2n6++WsbLl1GUKJGTnTu/oWBBa12HpTMpXWcn08zGElmTtfWX80emr68vg96FEDqzefN12rZdRVRUPFWr5mPz5o7kymWm67CyhEwxG0ukD7VazaRJk3BycsLU1JQKFSqwevVqAPbv349KpWLPnj24urpiZmaGm5tbsnuTTZgwATs7OywtLfH19WXo0KFUrFhRs//tbqy6devSv39/fvzxR2xtbbG3t8ff31+rzpCQEHx9fcmdOzdWVlbUr1+f8+fPp9l1q1Qq5s6dS8uWLTEzM6NYsWJs3LhRsz8hIYHu3btrnpcSJUrw+++/a/b7+/uzcOFCNmzYgEqlQqVSsX//fq1uLLVaTf78+fnnn3+0zn327Fn09PS4e/duhlyrEOLLsGDBOby8lhMVFU+TJsXYs6ezJDqpIMlOKimKQkRErE6+UtvjOGnSJP777z9mzpzJ5cuXGThwIJ06deLAgQOaMiNGjGDatGmcPn0aAwMDunXrptm3ZMkSJk6cyJQpUwgICKBgwYLJ3tzfZeHChZibm3PixAmmTp3KuHHj2LVrl2Z/mzZtCA4OZtu2bQQEBODi4kKDBg14+fIlAIcOHcLCwuKDX0uWLPlgDGPHjqVt27ZcuHCBJk2a4O3trak/KVFZtWoVV65cYfTo0QwfPpyVK1cC4OfnR9u2bfHw8ODx48c8fvwYNzc3rfr19PTo0KEDS5cu1dq+ZMkSatSoQaFChVJ0rUII8SGKojBlymG6dt1AQoJC584VWL++HebmyW+FJN5PxuyQujE7ERGxWFhM0kmc4eHDUvwCj4mJwdbWlt27d2um6QP4+voSGRlJz549qVevHrt376ZBgwYAbN26laZNmxIVFYWJiQnVqlXD1dWVv/76S3N8zZo1CQ8P1wzSfXtsS926dUlISODQoUOaY6pUqUL9+vWZPHkyhw8fpmnTpgQHB2vNlitatCg//vgjPXv2JCoqiocPH37w+vLkyYOlpeU796lUKkaOHMn48eMBiIiIwMLCgm3btuHh4fHOY/r27cuTJ080LV/vGrNz584dnJycOHv2LBUrVuTcuXO4uLhw584dChYsiFqtpmDBgowcOZJvv/02RdeaHmTMjhDZg1qtMGjQDn7//QQAP/7oxuTJDWUNnTfImJ0v3M2bN4mMjKRRo0Za22NjY3F2dtY8Ll++vOZnBwcHAIKDgylYsCCBgYH07t1b6/gqVaqwd+/eD577zTqT6k1aB+n8+fOEh4eTM2dOrTJRUVHcunULAFNTU4oWLZqSy0xRDObm5lhZWWmtxTRjxgzmzZvHvXv3iIqKIjY2Vqt7LiUqVqxIqVKlWLp0KUOHDuXAgQMEBwfTpk0bIGXXKoQQ7xIbm4CPz3qWLbsEwK+/NmbgwOofOUq8jyQ7qWRmZkh4+DCdnTulwsPDAdiyZQv58uXT2mdsbKx5szU0/F+dSZ8W1Gr1Z8X5Zp1J9SbVGR4ejoODwztnHyXN6Dp06BCenp4fPMesWbPw9vb+pBiWL1+On58f06ZNo3r16lhaWvLzzz9z4sSJj11aMt7e3ppkZ+nSpXh4eGiSm5RcqxBCvO316xhat17Jrl23MTDQY8GCFnh7l//4geK9JNlJJZVKlSX6SkuXLo2xsTH37t2jTp06yfanpGWhRIkSnDp1is6dO2u2nTp16rPicnFx4cmTJxgYGODo6PjOMq6urh9dy+btm7+mxpEjR3Bzc9NqtXr7+TAyMiIhIeGjdXXs2JGRI0cSEBDA6tWrmTlzpmZfSq5VCCHeFBwcQZMmSwgIeIy5uSFr1rTF3f3zWrqFJDvZlqWlJX5+fgwcOBC1Wk3NmjUJDQ3lyJEjWFlZaQbQfki/fv3o0aMHrq6uuLm5sWLFCi5cuEDhwoU/Oa6GDRtSvXp1vLy8mDp1KsWLF+fRo0ds2bKFli1b4urqmibdWB9SrFgx/vvvP3bs2IGTkxOLFi3i1KlTWrcrcXR0ZMeOHQQGBpIzZ873TrF3dHTEzc2N7t27k5CQQPPmzVN1rUIIkSQo6BWNGy/m5s2X5MplxtatHalcOd/HDxQfJbOxsrHx48czatQoJk2aRKlSpfDw8GDLli3J7kH2Pt7e3gwbNgw/Pz9cXFwICgrCx8fnswa9qlQqtm7dSu3atenatSvFixenffv23L1797Naa1KjV69etGrVinbt2lG1alVevHiRbGxSjx49KFGiBK6uruTOnZsjR468tz5vb2/Onz9Py5YtMTU11WzPDNcqhMgazp17gpvbPG7efEmhQtYcOdJNEp00JLOxkBWUU6NRo0bY29uzaNEiXYci3kNes0JkLfv336FFi+WEhcVQvnwetm3zJm/ed882FdpkNpb4bJGRkcycORN3d3f09fVZtmwZu3fv1lozRwghxKdbvfoK3t5riY1NoHbtQmzY0B4bG/mQktakG0u815vdMJUqVWLTpk2sWbOGhg0b6jo0IYTImvz94f/XAJsx4yRt264iNjaBVq1KsbvuXWx+m6zb+LIpadkR72Vqasru3bt1HYYQQmQf+vowejRbt96g7/EiAPTqVYm/Hc6g5+8P48bpNLzsSpIdIYQQIoOEDxzC+sUX6HR8ESOph+nEsQyL34dqzJjERGfUKF2HmC1JsiOEEEJkgAcPwmjWbBnnrpfllsErxsfvgbFHIDZWEp10JmN2hBBCiHQWEPCIKlXmcO7cE+zszPE4vACMjBITHSOjbJ3o+CzwITo2WqcxSLIjhBBCpKMNG65Ru/YCHj8Op0yZ3Jw44UvVnfP/l+jExmoGLWdHrcu3Zvxm3V6fJDtCCCFEOlAUhV9/PUbLliuIjIyjceMiHDnSDcdFf8Lo0YldVzExid9Hj84WCc+TkCd4zfJi8LLBmm3NXJox6ivdtlzJmB0hhBAijcXFJdCv3zZmzQoA4NtvK/Hnn00wmDTxf4lOUtdV0vfRo7UfZyFqtZpz584xfvt4NsRtwOyJGT+8/AF7W3sATIx0u3aQJDsiw925cwcnJyfOnj1LxYoVdR2OEEKkqdDQaNq0WcWuXbdRqWDatMYMGFANlUoFCQnvHoyc9DgFNyDObG7eucnenXt5/Pgx5SjHHaM7DKg1QJPoZAaS7IgMV6BAAR4/fkyuXLl0HQr+/v6sX7/+o3dZF0KIlLhzJ4SmTZdy5cozzMwMWbasNc2bl/hfAX//9x+cxVp0bj+9Tbfl3bgTcgcffDAxNqFu3bqMqTwGfX19XYenRZKd9Obvn7iI1LtexOPHJ2bxH3rxZzOxsbEYGRlhb595Mn4hhEgLx48/oEWL5QQHR5A3ryWbNnXAxcVB12Glm6i4KI6GHCWOOMyLm9O7eW/Mzc11HdY7yQDl9Pb/q2UmG3g2fnzi9nTMftVqNZMmTcLJyQlTU1MqVKjA6tWrURSFhg0b4u7uTtJ9YF++fEn+/PkZ/f99xvv370elUrFlyxbKly+PiYkJ1apV49KlS1rnOHz4MLVq1cLU1JQCBQrQv39/IiIiNPsdHR0ZP348nTt3xsrKip49e3Lnzh1UKpWmNSXpXDt27MDZ2RlTU1Pq169PcHAw27Zto1SpUlhZWdGxY0ciIyM/en1Jkurds2cPrq6umJmZ4ebmRmBgIAALFixg7NixnD9/HpVKhUqlYsGCBenxqxBCZHMrVlyibt0FBAdHULGiPSdO+GbLROfw1cOan8vkL8Nol9Fs8drC4A6DM22iA4AilNDQUAVQQkNDk+2LiopSrly5okRFRX36CcaNUxRI/P6ux+lkwoQJSsmSJZXt27crt27dUubPn68YGxsr+/fvVx48eKDkyJFD+e233xRFUZQ2bdooVapUUeLi4hRFUZR9+/YpgFKqVCll586dyoULF5SvvvpKcXR0VGJjYxVFUZSbN28q5ubmyvTp05Xr168rR44cUZydnRUfHx9NDIUKFVKsrKyUX375Rbl586Zy8+ZNJSgoSAGUs2fPap2rWrVqyuHDh5UzZ84oRYsWVerUqaM0btxYOXPmjHLw4EElZ86cyuTJk1N0fW/WW7VqVWX//v3K5cuXlVq1ailubm6KoihKZGSk8sMPPyhlypRRHj9+rDx+/FiJjIxM199JRkiT16wQIkXUarUyYcIBBfwV8FeaNVuqvH4do+uw0tzdx3eVClMrKPr++sq+C/t0HY7Gh96/3yTJjpIByY6i/C/BMTLKkEQnOjpaMTMzU44ePaq1vXv37kqHDh0URVGUlStXKiYmJsrQoUMVc3Nz5fr165pySYnC8uXLNdtevHihmJqaKitWrNDU1bNnT636Dx06pOjp6Wmer0KFCileXl5aZd6X7OzevVtTZtKkSQqg3Lp1S7OtV69eiru7e4qv7131btmyRQE08Y0ZM0apUKHCh57KLEeSHSEyRkxMvNKlyzpNojNw4HYlPj5B12GlqejoaGXnzp3K2LFjlaL+RRV9f31lzNoxug5LI6XJjozZySijRsGECRm2WubNmzeJjIykUaNGWttjY2NxdnYGoE2bNqxbt47Jkyfzzz//UKxYsWT1VK9eXfOzra0tJUqU4OrVqwCcP3+eCxcusGTJEk0ZRVFQq9UEBQVRqlQpAFxdXVMUc/ny5TU/58mTBzMzMwoXLqy17eTJkym+vnfV6+CQ2KwcHBxMwYIFUxSXEEK87cWLSFq3XsmBA3fR11fx55+efPddZV2HlWYS1An8su0XlKsKMRExAPRx7EP1GtWpWrSqjqNLPUl2Msr48clXy0zHhCc8PByALVu2kC9fPq19xsbGAERGRhIQEIC+vj43btz4pHP06tWL/v37J9v3ZiKR0n5cQ0NDzc8qlUrrcdI2tVqtOTd8+PreVy+gqUcIIVLrxo0XNG26lBs3XmJpacTKlW3w8Ciq67DSVI3fanDi9QnqUx8vWy/c3d0pXry4rsP6ZJLsZISkwchJayskPYZ0S3hKly6NsbEx9+7do06dOu8s88MPP6Cnp8e2bdto0qQJTZs2pX79+lpljh8/rklcXr16xfXr1zUtNi4uLly5coWiRTP+jzwl15cSRkZGJGTBdS2EELpx8OBdWrZcwcuXURQsaM2WLR0pW9ZO12GluRYlWnD29FnKFi/Ld22+w8Aga6cLWTv6rODtRAcyZLVMS0tL/Pz8GDhwIGq1mpo1axIaGsqRI0ewsrIiV65czJs3j2PHjuHi4sLgwYPp0qULFy5cIEeOHJp6xo0bR86cOcmTJw8jRowgV65ceHl5ATBkyBCqVatG37598fX1xdzcnCtXrrBr1y7++uuvNL+m1Fxfly5dUlSPo6MjQUFBnDt3jvz582NpaZmsZUgIIQD+++88vr4biYtTU6VKPjZsaI+9vYWuw/ps0bHRDFk7hIp5KtK1XlcAhngOoZ1rOwrnKfyRo7MGSXbSmw5Xyxw/fjy5c+dm0qRJ3L59GxsbG1xcXBg2bBjt2rXD398fFxcXAMaOHcvOnTv59ttvWbFihaaOyZMn8/3333Pjxg0qVqzIpk2bMDIyAhLHwhw4cIARI0ZQq1YtFEWhSJEitGvXLt2uKSXXN3z48BTX0bp1a9auXUu9evUICQlh/vz5+Pj4pF/QQogsR61WGDNmHxMmHALg669Ls3ChF2Zmhh85MvO7desW/df2Z2vkVuyv29O2WlvMTc3R09PLNokOgEpR/n+hlS9YWFgY1tbWhIaGYmVlpbUvOjqaoKAgnJycMDHR7b09MtL+/fupV68er169wsbGRtfhiFT4Ul+zQqSH6Oh4fHzWs2LFZQCGDavJhAn10dNT6Tiyz/Pq1St27tzJtWvXiCSSBaoF9CzXk9HNRmNokHWSuA+9f79JWnaEEEKIdwgOjsDLaznHjj3AwECP2bO/omtX548fmIm9Cn9F/5X9ufHgBp6KJyqVinpV6jGmzhjMTM10HV66kWRHCCGEeMuVK8/46qulBAWFYGNjwtq1balXz0nXYX22A4EHWHx/MQBe+bzo1rwbdnbZb4D12yTZEe9Ut25dpIdTCPEl2r37Nl9/vZLQ0BiKFMnBli0dKVFC9zcu/lRPQ56SxyYPAF6VvGh3th1uhdzo26Avenpfxl2jJNkRQggh/t+cOQF8990WEhIUatYsyLp17ciVK2t27zwNeUq3pd049OwQF7+9SKE8hQBY7rtcx5FlvC8jpUsD0sohsgp5rQqRemq1wuDBO+nZczMJCQqdOpVn9+5vsmSio1arOXXqFHNnzuXEsxO85jX/Hv5X12HplLTsfIT+/9+VPDY2FlNTUx1HI8THJd0Z/u0VqIUQ7xYREUunTutYv/4aAGPH1mXUqNqaFdezks0Bm7l/8j7BwcEAdMnRhcpVKtO+WnsdR6Zbkux8hIGBAWZmZjx79gxDQ8Mvpn9TZD2KohAZGUlwcDA2NjaaRF0I8X6PHr2mefNlBAQ8xshIn/nzW9CxYzldh5VqarWaRjMasfflXtrSFhcTF+rXr0+lSpXkfQtJdj5KpVLh4OBAUFAQd+/e1XU4QnyUjY0N9vb2ug5DiEzv/PknfPXVMh48CCNXLjPWr29HjRpZ8wbBenp65LfIj+qlCsO8hvTz7oeZWdbrgksvsqggKVuUSK1WExsbm8GRCZE6hoaG0qIjRAps2XKd9u3XEB4eS8mSudi8uQNFitjqOqwUU6vVzNgzg0r5K+FWyg2A0MhQTgedpkGZBjqOLuPIooJpTE9PT1ajFUKIbODPP08wYMAO1GqF+vWdWL26DTlyZJ0xmc+ePaP70u5sCtlEReOKBJQIQE9PD2sz6y8q0UkNSXaEEEJ8EeLj1QwcuJ2//joFQPfuzvzzT1MMDbNGa2h0dDT79+/n5MmTFFAKYIQRZezKEJ8Qj5Geka7Dy9Qk2RFCCJHthYXF0L79arZtuwnA1KkN8fNzyxIzruLi4xi3aRxXrl6hfFx5AGqXrM3gOoNxtHfUbXBZhCQ7QgghsrV790L56qulXLwYjKmpAYsXt6JVq1K6DivFZu6byYQLEzDCiEq2lWjXpB1FihTRdVhZiiQ7Qgghsq1Tpx7SvPlynjwJx97ego0b21O5cj5dh/VRCQkJmskGvRv0Zs7ZOdQvWJ9BrQZhYiTjR1NLkh0hhBDZ0tq1V+nUaS1RUfGUK2fH5s0dKVjQWtdhfVBEdASD1wxm552dXPzhIqYmpujr6XPO75ysl/MZ5JkTQgiRrSiKwtSpR2jdeiVRUfF4ehbl8OFumT7RuX79On/M+oP5N+dzK/4W03dM1+yTROfzSMuOEEKIbCMuLoHevbcwd+5ZAPr0qcxvv3lgYJB5k4XrD65z+uBpbty4AUAL4xaULVOWIU2H6Diy7EOSHSGEENnCq1dRfP31KvbuDUJPT8Vvv7nTr19VXYf1XgnqBDr+25G1j9bSne7k08tHtWrVGFp7KMbGxroOL1uRZEcIIUSWd/v2K5o2Xcq1a8+xsDBi+fLWNG1aXNdhfZC+nj4PIx4STzyPczxmovdEcubMqeuwsiVJdoQQQmRpR4/ep0WL5Tx/Hkn+/FZs3tyBChUy5/3h9l/ZTzG7YuTLlTgjbNbXszhy4wg96/XUcWTZW6qSnZCQENatW8ehQ4e4e/cukZGR5M6dG2dnZ9zd3XFzc0uvOIUQQohkli27SNeuG4iJScDFxYFNmzqQN6+lrsNKJjo6mt5LerPwwUKa5WzG+r7rASiTvwxl8pfRbXBfgBSN2Hr06BG+vr44ODgwYcIEoqKiqFixIg0aNCB//vzs27ePRo0aUbp0aVasWJHeMQshhPjCKYrCuHEH6NhxLTExCXh5leTgQZ9Ml+goisLZs2f5888/iXkQgxo1z+OeEx8fr+vQvigpatlxdnamS5cuBAQEULp06XeWiYqKYv369fz222/cv38fPz+/NA1UCCGEAIiJicfXdxOLF18AwM+vOlOmNEJPL3Pd+mH7+e3sO7IPs2dmALjlcqNdlXY0r9xcx5F9eVSKoigfK/TixYtUDZpKbXldS+kt4oUQQujW8+eRtGy5gsOH76Gvr+Lvv5vSs2clXYeVzJ+7/qT/0f7YYMNAw4E0rNuQqlWralZFFmkjpe/fKerGSkpc4uLi6NatG0FBQSkqL4QQQqSVwMDnVKs2l8OH72Ftbcy2bd6ZMtEB8K7ujY3KhnLW5eji2wU3NzdJdHQoVassGRoasmbNmvSKRQghhHinffuCqFbtX27deoWjow1Hj3anUaPMczPMDQEbaDerHUmdJbYWtlzpf4WDAw5SyK6QjqMTqV5S0svLi/Xr16dDKEIIIURy8+efpXHjxYSERFOtWn5OnPCldOncug4LgIiICP5d9S+tNrdi5ZOVzN49W7PPwcZBh5GJN6V6nZ1ixYoxbtw4jhw5QqVKlTA3N9fa379//zQLTgghxJdLrVYYOXIvkyYdBqBduzLMn98CU1NDHUcGarWaU6dOsW/fPmJiYqhMZSxsLWhcobGuQxPvkKIBym9ycnJ6f2UqFbdv3/7soDKaDFAWQojMJSoqjs6d17N69RUARo6sxdix9TLFjKuVJ1YyYs8IvOK8sMACBwcHPD09KVCggK5D++Kk9P071S07HxucLIQQQnyOJ0/CadFiOSdPPsTQUI+5c5vTuXMFXYcFJLbo/LjnR+7G3eWI/hH+9PwTZ2dnuSt5Jie/HSGEELrn7w/jx3Py5ENcXWdz8uRDbG1N2b27M53vbkzcryNRsVHExsUCoKenxx8ef+CRy4MV362gUqVKkuhkAZ90b6wHDx6wceNG7t27R2xsrNa+X3/9NU0CE0II8QXR14fRo9k6dj8PE2pTsmQuNm5sT7Hlf8Po0TBunE7CWnxkMX77/OhcpDNTO0wFoLlLc5q7yMKAWUmqk509e/bQvHlzChcuzLVr1yhbtix37txBURRcXFzSI0YhhBDZWFxcAgOfViIH9RifsJfiJXPy1YlFWP0+9X+JzqhRGRpTaGgoO3bsYNHVRTzlKYtuLmJC3ASMDI0yNA6RNlKd7AwbNgw/Pz/Gjh2LpaUla9aswc7ODm9vbzw8PNIjRiGEENnU06fhtGmzikOH7gF1qF/PiY775kHuDRAbm+GJTkR0BDsP7eTKySvEx8dTjWrkyZeHqV9PlUQnC0v1bCxLS0vOnTtHkSJFyJEjB4cPH6ZMmTKcP3+eFi1acOfOnXQKNf3IbCwhhMh4p049pFWrlTx4EIaVlTGLF7ekWbMSYGycmOgYGUFMTIbFs/nsZrpu7oqF2oIudKFQwUI0adKEPHnyZFgMInXS9HYRbzI3N9eM03FwcODWrVuafc+fP09VXQcPHqRZs2bkzZsXlUqVbLFCHx8fVCqV1tfbrUcvX77E29sbKysrbGxs6N69O+Hh4am9LCGEEBlo4cJz1Ko1nwcPwihRIicnT/omJjrjx/8v0YmNTXycQQrmLEiIOoSXqpfU8KiBj4+PJDrZRKqTnWrVqnH4cOICT02aNOGHH35g4sSJdOvWjWrVqqWqroiICCpUqMCMGTPeW8bDw4PHjx9rvpYtW6a139vbm8uXL7Nr1y42b97MwYMH6dmzZ2ovSwghRAaIi0ugf/9t+PhsICYmgWbNinPihC8lSuRKTGySxujExCR+Hz063RKe0MhQ5u2bp3lcvmB55jWcx60Bt2hUtREqle7X9BFpREmlW7duKefPn1cURVHCw8OVXr16KeXKlVNatWql3LlzJ7XVaQDKunXrtLZ16dJFadGixXuPuXLligIop06d0mzbtm2bolKplIcPH6b43KGhoQqghIaGpjZsIYQQKfT0abhSp858BfwV8FfGjNmnJCSoE3eOG6cokPj9Te/b/hnUarVyIOCAkmNsDkXfX185cPFAmtUtMlZK379TPUC5cOHCmp/Nzc2ZOXNmmiVe77J//37s7OzIkSMH9evXZ8KECZq7qh87dgwbGxtcXV015Rs2bIienh4nTpygZcuW76wzJiaGmDf6gcPCwtL1GoQQ4ksXEPCIli1XcP9+GJaWRixa1JIWLUr+r0BCwrsHIyc9TkhIkzieP3/O9u3buXnrJrbYoqgUHr1+lCZ1i8zrk9bZATh9+jRXr14FoHTp0lSqVCnNgkri4eFBq1atcHJy4tatWwwfPhxPT0+OHTuGvr4+T548wc7OTusYAwMDbG1tefLkyXvrnTRpEmPHjk3zeIUQQiT333/n6dlzEzExCRQvnpP169tRqtRbN/L80KKBaTAb62X4S35c/SP57uVDT9HDQN+ASa6TaFizITkscnx2/SJzS3Wy8+DBAzp06MCRI0ewsbEBICQkBDc3N5YvX07+/PnTLLj27dtrfi5Xrhzly5enSJEi7N+/nwYNGnxyvcOGDWPQoEGax2FhYXJPEyGESGNxcQkMHryL338/AcBXXxVn8eKWWFubZGgcarUalz9cuBt3l4Y0pGuxrnh4eGBra5uhcQjdSfUAZV9fX+Li4rh69SovX77k5cuXXL16FbVaja+vb3rEqFG4cGFy5crFzZs3AbC3tyc4OFirTHx8PC9fvsTe3v699RgbG2NlZaX1JYQQIu08exZB48aLNYnOqFG12bChfYYnOpB4i4ce5XqQUy8nbWq3oUOHDpLofGFS3bJz4MABjh49SokSJTTbSpQowZ9//kmtWrXSNLi3PXjwgBcvXuDg4ABA9erVCQkJISAgQNONtnfvXtRqNVWrVk3XWIQQQrzbmTOPadlyBffuhWJhYcR//3nRsmWpDDv/09CnfLf8O1qUaEGXul0AGNZ0GN83+h4LE4sMi0NkHqlOdgoUKEBcXFyy7QkJCeTNmzdVdYWHh2taaSDxjurnzp3D1tYWW1tbxo4dS+vWrbG3t+fWrVv8+OOPFC1aFHd3dwBKlSqFh4cHPXr0YObMmcTFxdG3b1/at2+f6liEEEJ8viVLLuDru4no6HiKFbNl/fr2lC6d++MHpgFFUbhw4QL9N/fnYPxBjgcfp71be4yNjNHT05NE5wuW6m6sn3/+mX79+nH69GnNttOnT/P999/zyy+/pKqu06dP4+zsjLOzMwCDBg3C2dmZ0aNHo6+vz4ULF2jevDnFixene/fuVKpUiUOHDmFsbKypY8mSJZQsWZIGDRrQpEkTatasyezZs1N7WUIIIT5DfLyaQYN20KnTOqKj42nSpBgnT/bIsETn8ePHzJ8/n/Xr11M1vipOBk5MrDMRYyPjjx8ssr0U3S4iR44cWosrRUREEB8fj4FBYsNQ0s/m5ua8fPky/aJNJ3K7CCGE+HTPn0fSrt1q9u4NAmDEiFqMHVsXff1Uf55OtYcvH9JrRS+Cg4NpSlMMDQ2pU6cO1apVQ19fP93PL3Qrpe/fKerG+u2339IqLiGEENnIuXNP8PJazt27oZibG/Lffy1p1SrjxuccvXmULcFbUKHCp7gPnZp2kg+tIplU3wg0O5KWHSGESL1lyy7SvftGoqLiKVIkB+vXt6dsWbuPH/iZHr98jIOtg+Zx5/mdaVKqCe2rtf/AUSI7StOWnYiICMzNzVN88tSWF0IIkXXEx6sZOnQ306YdA8DDoyhLl7YiRw7TdD3v45eP6by0MydenODyd5cpYJe4Ptp/Xf9L1/OKrC9FHapFixZl8uTJPH78+L1lFEVh165deHp68scff6RZgEIIITKPFy8i8fRcokl0hg2ryebNHdI10VGr1Zw8eZJ5s+dx5sUZXvOahccWptv5RPaTom6swMBAhg8fzpYtW6hQoQKurq7kzZsXExMTXr16xZUrVzh27BgGBgYMGzaMXr16ZamBYdKNJYQQH3f+/BNatlxBUFAIZmaGLFjQgjZtyqTrOXec28HtY7c1C8i+tn1N9WrVaV25dbqeV2QNKX3/TtWYnXv37rFq1SoOHTrE3bt3iYqKIleuXDg7O+Pu7o6np2eWSnKSSLIjhBAftmLFJbp23UBUVDyFC+dg/fp2lCuXJ93Op1ar8fjbg10vdtGOdjibOFO/fn0qVaqEnl76z/ISWUOajtlJUrBgQX744Qd++OGHzw5QCCFE5peQoGb48D1MnXoUgMaNi7BsWWtsbdN3fI6enh52ZnbwAlT2Kvp90w8zM7N0PafIvj75rudCCCGyt5cvo+jQYQ07d94CYMiQGkycWD/d1s9ZfXI1jjkccS3mCsCfbf/E+5Y3nhU80+V84sshyY4QQohkLl58ipfXCm7ffoWZmSHz5jWnXbuy6XKu8PBw+iztw3+P/8PZxJnTg0+jp6dHDosckuiINCHJjhBCCC2rVl3Gx2cDkZFxODnZsH59e8qXT/vxOWq1mtOnT7N3717MY8zRQw87CzuiY6MxM5EuK5F2JNkRQggBJI7PGTlyL5MnHwGgUaPCLFvWmpw50z7x2HhmI5sObiJ/aH4AKjpU5Hid41QuUTnNzyWEJDtCCCF49SpxfM6OHYnjcwYPduOnnxpgYJD243NWnlhJu+3tMMKIH4x+oGXDljLLSqSrT3plHTp0iE6dOlG9enUePnwIwKJFizh8+HCaBieEECL9XboUTOXKc9ix4xampgYsW9aaqVMbpUuiA9C6cmucDJ2okaMGPX17UrlyZUl0RLpK9atrzZo1uLu7Y2pqytmzZ4mJiQEgNDSUn376Kc0DFEIIkX7WrLlCtWpzuXXrFY6ONhw92p327dN2IPKOizto+HtDoqKjANDX0+fCoAvs7b8Xx9yOaXouId4l1cnOhAkTmDlzJnPmzMHQ0FCzvUaNGpw5cyZNgxNCCJE+EhLUjBixh6+/XkVERBwNGjhx6lQPKla0T7NzREVFsWbjGrzWerEnZA/D1wzX7LMwsUiz8wjxMakesxMYGEjt2rWTbbe2tiYkJCQtYhJCCJGOQkKi6dhxDdu23QTghx+qM3lywzTrtlIUhfPnz7Nr1y4iIyOpS13CrcP5rv53aVK/EKmV6mTH3t6emzdv4ujoqLX98OHDFC5cOK3iEkIIkQ4uXw7Gy2sFN2++xNTUgLlzm9OxY7k0q3//lf18t/E76sbUxR57cuXKxQzPGfL+IHQq1clOjx49+P7775k3bx4qlYpHjx5x7Ngx/Pz8GDVqVHrEKIQQIg2sXXuVLl3WEx4eS6FC1qxb1w5nZ4c0PcfwHcO5FnONBFUC8xvMp1q1alnynokie0l1sjN06FDUajUNGjQgMjKS2rVrY2xsjJ+fH/369UuPGIUQQnwGtVphzJh9TJhwCIB69RxZubINuXJ9/vo5arVaaxHAOW3m0HtNb/5u/Tdl8qfvHdGFSKlU3fU8ISGBI0eOUL58eczMzLh58ybh4eGULl0aC4usO9hM7nouhMiuQkKi6dRpLVu23ABg4MBqaTat/EjgEXqs70Epy1Ks6b3ms+sTIrXS5a7n+vr6NG7cmKtXr2JjY0Pp0qU/O1AhhBDp4+rVZ7RosZwbN15iYmLAnDnN6NSp/GfXGxsby4EDB5h/bD5Xlavcjr7N/Wf3KZC7QBpELUTaS3U3VtmyZbl9+zZOTk7pEY8QQog0sH79NTp3Xsfr17EUKGDF+vXtcXH5vPE5arWaI+eOcPrAacLCwihOcdrmbMuwr4ZJoiMytVQnOxMmTMDPz4/x48dTqVIlzM3NtfZLN5AQQuiOWq0wdux+xo07CEDduo6sXPk1uXObf+TID7v++DpfL/qaB1EP6E1vctvkxsPDgxIlSqRF2EKkq1QnO02aNAGgefPmqFQqzXZFUVCpVCQkJKRddEIIIVIsNDSab75Zx6ZN1wH4/vuq/PxzIwwNP382lK25LXej7xJBBDnL56T3V721FpYVIjNLdbKzb9++9IhDCCHEZ7h27TleXssJDHyBsbE+s2c3o3PnCp9V5+aAzTR1aYpKpSKXVS5mNZ5F4dyFqVKkShpFLUTGSNVsrOxKZmMJIbKyjRsD6dRpLa9fx5I/vxXr1rXD1TXvJ9f3/MVzPOd7cjriNLPdZtOjUY80jFaItJMus7EADh48+MH977qVhBBCiLSnViuMH38Af/8DANSuXYhVq9pgZ/dp43Pi4+M5cuQIhw8fhnjQQ4/Lzy+nZchC6ESqW3b09JKvzfDm2J2sOGZHWnaEEFlNWFgMnTuvY8OGQAD69q3Mr7+6f/L4nPkH5/Pk7BNiQ2IBsCtoR3m38tQoUSPNYhYiraVby86rV6+0HsfFxXH27FlGjRrFxIkTUx+pEEKIVAkMfI6X1wquXXuOsbE+M2d+hY9PxU+ur+O/HVn2YBnOOONt4Y27uztlypTR+iArRFaW6mTH2to62bZGjRphZGTEoEGDCAgISJPAhBBCJLd583W8vdcSFhZDvnyWrFvXjsqV831WnW0qtGHFgxUUdihMn859MDExSaNohcgcUp3svE+ePHkIDAxMq+qEEEIk8fdHrdJjTHxNJk48hKJAzZoFWb26DXlmT4ctCeDvn+LqlhxdwtNXTxnUdBAALV1bcjnvZUrmLZlOFyCEbqU62blw4YLWY0VRePz4MZMnT6ZixYppFZcQQoj/9zoyHsufJwL1UKhD796uTJ/ugdGUn2D0aBg3LmX1vH7NhNUTmHpvKuaY06pSKxztHQEk0RHZWqqTnYoVK6JSqXh7XHO1atWYN29emgUmhBAC9uy5TceFNvSkHuPZR5uvS1N+RlMYP/5/ic6oUR+sIyEhgZMnT7J//36MYo2ww44qdlWku0p8MVKd7AQFBWk91tPTI3fu3PJHI4QQaSghQc348QcZN+4AigIby7fl+7pVKf/HZDCeA7GxKUp0Vp1cxYz9M6gbVRcVKgrlK8Rx9+M4FZD7G4ovR5osKhgSEoKNjU0ahKMbMvVcCJGZPHkSjrf3WvbuTfxw2aOHC7//7oGpqSEYGycmOkZGEBPzwXruPb9HkRlFiCcebyNvBrkPwtnZWWZZiWwjpe/fyRfN+YgpU6awYsUKzeO2bdtia2tLvnz5OH/+/KdFK4QQAoB9+4Jwdp7F3r1BmJsbsnhxS2bPbpaY6Iwf/79EJzY28fFb3vz8WjBXQb5x/IbGORszqeckXFxcJNERX6RUJzszZ86kQIECAOzatYtdu3axfft2PD09GTx4cJoHKIQQX4Kk1ZAbNlzEkyfhlC1rx+nTPfH2Lp9Y4M0xOjExid9Hj9ZKeDad2USxScU4fPmwZtvcb+ayo+8OCuQskNGXJESmkeoxO0+ePNEkO5s3b6Zt27Y0btwYR0dHqlatmuYBCiFEdhccHEGnTmvZtes2AF27VuSvv5pgZvb/dxV/12DkpO+jRxMbF8d2V1cGnh3IbW7jt82P42WOA+9e9V6IL02qk50cOXJw//59ChQowPbt25kwYQKQ2HSaFW8VIYQQunTw4F06dFjDo0evMTU14J9/mtKlS0XtQgkJ7xyMnDBiOI8ePuDesWOc1dfHE0+u2V5jTrs5GXcBQmQBqU52WrVqRceOHSlWrBgvXrzA09MTgLNnz1K0aNE0D1AIIbIjtVphypTDjBy5D7VaoVSpXKxa1YYyZeySF37HgoE7Lu7gu03fUdShKDUcapInTx66NulKwYIF0z94IbKYVCc706dPx9HRkfv37zN16lQsLCwAePz4Mb17907zAIUQIrt5/jySb75Zx/btNwHo3LkCf//dBHNzoxTXcez2MYLignjBC0Y2GknNajWly0qI90iTqedZnUw9F0JklCNH7tGu3WoePnyNiYkBM2Y0oWvXih+dJaVWq7kTfIfC9oUBSFAn4PufL8Pdh1PMoVhGhC5EppNuU88XLlzIli1bNI9//PFHbGxscHNz4+7du58WrRBCZHNqtcLUqUeoU2cBDx++pkSJnJw86Uu3bh9f9ybgVgBlfi5D7Tm1iYiKAEBfT5/5PvMl0REiBVKd7Pz000+YmpoCcOzYMWbMmMHUqVPJlSsXAwcOTPMAhRAiq3vxIpLmzZcxZMhuEhIUOnYsx6lTPShXLs8Hj4uLi2PPnj2sXLKSO9F3CFYHs/vS7gyKWojsI9Vjdu7fv68ZiLx+/Xpat25Nz549qVGjBnXr1k3r+IQQIks7fvwBbduu4v79MIyN9fnjD0969Pj44n7bTm3j+tHrhISEYIYZ3+f7no6NO1K+YPkMilyI7CPVyY6FhQUvXrygYMGC7Ny5k0GDBgFgYmJCVFRUmgcohBBZkaIo/PrrMYYO3UN8vJpixWxZtaoNFSrYf/C4qNgo6v5Vl1OvT9GDHpS0KomnpyclSpSQ1Y+F+ESpTnYaNWqEr68vzs7OXL9+nSZNmgBw+fJlHB0d0zo+IYTIcl69isLHZwMbNwYC0K5dGWbPboaVlfFHjzU1MsVAZYAKFUZORvRp3wcjo5TP0hJCJJfqZGfGjBmMHDmS+/fvs2bNGnLmzAlAQEAAHTp0SPMAhRAiKzl58iFt267i7t1QjIz0+e03d7791vWDrTIbAjZQuVBl8ubKC8CC9gt4+OohdUvXzaCohcjeZOo5MvVcCPH5FEXhjz9OMHjwLuLi1BQunINVq9rg4uLw3mMiIyPpvqg7y58sp1nOZmzsuzEDIxYi60u3qecAhw4dolOnTri5ufHw4UMAFi1axOHDhz9ypBBCZD8hIdF8/fUqBgzYQVycmtatS3HmTM/3JjqKonDu3DlmzJiB3pPEf8MxxMgtd4RIJ6lOdtasWYO7uzumpqacOXOGmJgYAEJDQ/npp5/SPEAhhMjMTp9+hIvLLNauvYqhoR5//unJqlVtsLY2eWf5g9cOMnzmcDZs2EBkZCQ1ctdgl9cudvTdgb6+fgZHL8SXIdXJzoQJE5g5cyZz5szB0NBQs71GjRqcOXMmTYMTQojMSlEU/vrrJDVqzCMoKAQnJxuOHu1O375V3js+Z+6BudRbUY+ZwTNRDBQaNmxIr169aFihYQZHL8SXJdXJTmBgILVr10623drampCQkLSISQghMrXQ0GjatVtNv37biI1NoGXLkpw50wtX17wfPK5VpVZYqawoalGUb7p9Q40aNaQ1R4gMkOpkx97enps3bybbfvjwYQoXLpwmQQkhRGZ19uxjKlWazapVVzAw0GP6dHfWrGmLjU3ybqtL9y/x3X/fkTQPxNbCljPfnuHUD6co4lAko0MX4ouV6qnnPXr04Pvvv2fevHmoVCoePXrEsWPH8PPzY9SoUekRoxBC6JyiKMyaFcCAAduJiUmgYEFrVq78mqpV8ycrm5CQwM5DO2l5oCUxxFBuZzl6u/cGwMnOKaNDF+KLl+pkZ+jQoajVaho0aEBkZCS1a9fG2NgYPz8/+vXrlx4xCiGETr1+HUPPnptZvvwSAM2aFWfBAi9sbU2Tlb137x5btmwhODiYilTklfEryhUql9EhCyHekKp1dhISEjhy5Ajly5fHzMyMmzdvEh4eTunSpbGwsEjPONOVrLMjhHif8+ef0KbNKm7ceImBgR6TJzdg0KDqyQYh33t+j+9WfEfp56WxwAIzMzPq1K+Dq7MrenqftMqHEOIjUvr+naqWHX19fRo3bszVq1exsbGhdOnSnx2oEEJkRoqiMHfuGfr33050dDwFClixYsXXVK9e4J3lm85ryqWoSzzgAeOdx9OwYUPMzMwyOGohxLuk+uNG2bJluX37dnrEIoQQmUJ4eCzffLOOnj03Ex0dT5MmxTh7ttd7Ex2AyY0nU8CgAKObjKZ58+aS6AiRiaT6dhHbt29n2LBhjB8/nkqVKmFubq61Pyt2A0k3lhAiyaVLwbRps4pr156jr6/ip58a4Ofnhp7e/7qtXoW/oteyXhSxKsKkdpM029VqtXRZCZGBUvr+nepk580/5Df7rBVFQaVSZcnlziXZEUIAzJ9/lj59thIVFU++fJYsX/41NWsW1Cpz7do1Rm4YyZroNZhhRmDvQPLnTj4jSwiR/tJlzA7Avn37PiswIYTIbCIiYunTZysLF54HwN29CIsWtSR37v+1XL969Yrt27dz/fp1SlOaQINA+rn1k0RHiCwgVcmOoijkzZuX2NhYSpQogYFBqnMlIYTIVK5ceUabNqu4cuUZenoqxo+vx9ChNTXdVtGx0QxcOZB9t/fRXmmPvp4+Nd1qMqr2KK1b5gghMq8UZytBQUE0b96cK1euAJA/f37WrFmDq6trugUnhBDp6b//zvPdd1uIjIzDwcGCZctaU6eOo1aZ60+u8++tf4kjjlC7UIZ/PZzcuXPrJmAhxCdJcbIzePBg4uPjWbx4MSYmJvzyyy/06tWLgICA9IxPCCHSXGRkHP36bWXevHMANGxYmCVLWmFnl9htFR4VjoVp4tph5QuWZ2CZgVgaWzK86XAZgCxEFpTiAcr29vasXr2amjVrAvD48WPy589PWFhYshlZWY0MUBbiy3Ht2nPatFnFpUvBqFTg71+XESNqoa+vh1qtZsyGMfxx4Q82ttpInXJ1dB2uEOIDUvr+neKPKMHBwRQrVkzz2MHBAVNTU4KDgz8vUiGEyCBLl17E1XU2ly4FkyePObt3d2b06Dro6+vx9OlT5s2bx7ILywgjjMn7J+s6XCFEGklxsqNSqQgPDycsLEzzpaenx+vXr7W2pcbBgwdp1qwZefPmRaVSsX79eq39iqIwevRoTWLVsGFDbty4oVXm5cuXeHt7Y2VlhY2NDd27dyc8PDxVcQghsreoqDh69tyEt/daIiLiqFfPkXPnvqV+fSdehr9ky/YtzJo1i4cPH+Jl6MX3Jb5nw3cbdB22ECKNpHjMjqIoFC9ePNk2Z2dnzc+pXWcnIiKCChUq0K1bN1q1apVs/9SpU/njjz9YuHAhTk5OjBo1Cnd3d65cuYKJiQkA3t7ePH78mF27dhEXF0fXrl3p2bMnS5cuTXEcQojs6/r1F7Rtu4rz55+iUsGoUbU1rTlz9s/hx4M/UkmpRC1qUbp0adzd3aU7W4hsJsXJTnqsr+Pp6Ymnp+c79ymKwm+//cbIkSNp0aIFAP/99x958uRh/fr1tG/fnqtXr7J9+3ZOnTqlmRX2559/0qRJE3755Rfy5s2b5jELIbKOFSsu4eu7ifDwWOzszFmypBUNGxbW7H8W/owQJYTLepf5s+2flCpRSofRCiHSS4qTnTp1MnagXlBQEE+ePKFhw4aabdbW1lStWpVjx47Rvn17jh07ho2Njdb094YNG6Knp8eJEydo2bLlO+uOiYkhJiZG8zi13W9CiMwtOjqeQYN28M8/pwGoU6cQS5e2JkcuAwJuBVCpSCUAhjYZSmRsJD96/IiVmbTmCJFdZdo5lE+ePAEgT548Wtvz5Mmj2ffkyRPs7Oy09hsYGGBra6sp8y6TJk3C2tpa81WgwPtv7ieEyFpu3XqJm9u/mkRnxIha7N7dmUtPj1F4amGaLW3G64jXQOLtbya0miCJjhDZXKZNdtLTsGHDCA0N1Xzdv39f1yEJIdLA6tVXcHGZzdmzT8iVy4zt270ZNqwqmzZtYM/GPYQmhPJa/ZpTt0/pOlQhRAbKtPd7sLe3B+Dp06c4ODhotj99+pSKFStqyrw99T0+Pp6XL19qjn8XY2NjjI2N0z5oIUTG8vcHfX2iBw9j8OCd/PVXYhJTs2ZBNlW5wa3FA/nrXE2io6Mxw4yxJcbi7e5N3hwynk+IL0mmbdlxcnLC3t6ePXv2aLaFhYVx4sQJqlevDkD16tUJCQnRWsV57969qNVqqlatmuExCyEymL4+jB7NnIItNYnO0KE12FHnJja/TmL9w83cjL6Jvb09vr6+DG4/WBIdIb5AqW7ZCQ0NJSEhAVtbW63tL1++xMDAIFVTNsPDw7l586bmcVBQEOfOncPW1paCBQsyYMAAJkyYQLFixTRTz/PmzYuXlxcApUqVwsPDgx49ejBz5kzi4uLo27cv7du3l5lYQmRzarXCdLMGvNbfj/+zzUSYx1Jh1V94nl4Oo3/iX09Hfq76mJHlC9GjRQ+5zYMQXzIllTw8PJQZM2Yk2/7PP/8onp6eqapr3759CpDsq0uXLoqiKIparVZGjRql5MmTRzE2NlYaNGigBAYGatXx4sULpUOHDoqFhYViZWWldO3aVXn9+nWq4ggNDVUAJTQ0NFXHCSF04/79UKV+/YUK+Cvgrywu8bWigKI2MlIUUJRx45Sg4CDl6sOrug5VCJGOUvr+neJ7YyWxtbXlyJEjlCqlvR7FtWvXqFGjBi9evEibLCwDyb2xhMg6Vq68TK9emwkJicbMzJCffqrNZvU4Ng/ehXECYGQEbywtIYTIvtL83lhJYmJiiI+PT7Y9Li6OqKio1FYnhBApEhoaTefO62jXbjUhIdFUrpyXf/+tTETEQb7dFIxxAsQZ6EFsLIwfr+twhRCZSKqTnSpVqjB79uxk22fOnEmlSpXSJCghhHjT4cP3qFBhJosWXUBPT0W7Hg5U63CFwMCjVN+9m9b7zvN0UB8M4xJg3DgYPVoSHiGERqoHKE+YMIGGDRty/vx5GjRoAMCePXs4deoUO3fuTPMAhRBfrtjYBMaO3c/kyUdQqxWcnGxoNVDFtJe9sAqzYsMRV+ru24cydix5Ro9OPGjUqMTvbz8WQnyxUp3s1KhRg2PHjvHzzz+zcuVKTE1NKV++PP/++y/FihVLjxiFEF+gwMDneHuvJSDgMQA+PhX5/XcPFINoFkwbR1mrsrhUrAC16qJ6O6FJepyKGxMLIbKvVA9Qzo5kgLIQmYeiKMyaFcCgQTuIiorHytqQyt5P2Pnnb5rp409Dn5LHOs9HahJCZHcpff9OUctOWFiYppKP3TRTkgUhxKcKDo6ge/eNbN58HQDnStZcqTORPVbP+W2rI4O+GgQgiY4QIlVSlOzkyJGDx48fY2dnh42NDSqVKlkZRVFQqVQkSLOxEOITbN58ne7dNxIcHIGxsT7Nm5tTqlQopnrFeWacg6rFZFV0IcSnSVGys3fvXs2Kyfv27UvXgIQQX5bIyDh++GEHM2cm3vbFOl80Xs3VOOVJwMTEhF8b/Iqriyv6evo6jlQIkVWlKNmpU6eO5mcnJycKFCiQrHVHURS5e7gQIlVOn35Ep05rCQxMXIw0T+3bPK21lFOGxWlebjyNGzfGwsJCx1EKIbK6VK+z4+TkxLNnz5Jtf/nyJU5OTmkSlBAie0tIUPPTT4eoXv1fAgNfkC+fJbt3f8PiGd9gZ2yLXz0/WrVqJYmOECJNpHrqedLYnLeFh4djYmKSJkEJIbKvO3dC+OabdRw+fA+AklUTOLL1O2xtTYHCPCj5AEMDQ90GKYTIVlKc7AwalDgLQqVSMWrUKMzMzDT7EhISOHHiBBUrVkzzAIUQ2YOiKCxefIE+fbby+nUshsZq4jw3EFQhkOCIjtjalgSQREcIkeZSnOycPXsWSPyHdfHiRYyMjDT7jIyMqFChAn5+fmkfoRAiy3v5MorvvtvCypWXAShYEFq0hK224bQtO5Bi+WRBUiFE+klxspM0C6tr1678/vvvsp6OECJF9u4NonPndTx8+Br01NSrCzVr6FGhQnkmNvbD0tJS1yEKIbK5VI/ZmT9/vubnBw8eAJA/f/60i0gIkS3ExMQzYsRepk07lrgh5wtotYa8xerxjdcYub2MECLDpHo2llqtZty4cVhbW1OoUCEKFSqEjY0N48ePR61Wp0eMQogs5tKlYKpUmatJdHr1qkTfaQa0rVyTGX1mSKIjhMhQqW7ZGTFiBP/++y+TJ0+mRo0aABw+fBh/f3+io6OZOHFimgcphMga1GqFP/88weAfdxIXq2CTw5D/FramWbMSwFe6Dk8I8YVK9Y1A8+bNy8yZM2nevLnW9g0bNtC7d28ePnyYpgFmBLkRqBCf79Gj13TuvJY9e+4kbih2nVJtbnB5wol3LlchhBCfK01vBPqmly9fUrJkyWTbS5YsycuXL1NbnRAiG1i79irduq8nNCQWAwOo5R5BbIN7zGu/WBIdIYTOpXrMToUKFfjrr7+Sbf/rr7+oUKFCmgQlhMgaXr+OoXX7/2jdeiWhIbE4OICfnwUzf/Xl8MBDFHcorusQhRAi9S07U6dOpWnTpuzevZvq1asDcOzYMe7fv8/WrVvTPEAhROZ07Nh9OnVax+3brwAFvZpHmfaDL62beGmtwyWEELqW6padOnXqcP36dVq2bElISAghISG0atWKwMBAatWqlR4xCiEykbi4BIYN30HNmvO5ffsVhQpZU8cviB3//EgHr7aS6AghMp1UD1DOjmSAshApc+bCHRp5/cPLoMTbxXTqVJ6//vLE2lruiyeEyHjpNkAZIDo6mgsXLhAcHJxsbZ23Z2kJIbI+RVGYNGkHY8eeIDbWDEyiaNfHgkW/tNR1aEII8VGpTna2b99O586def78ebJ9KpWKhISENAlMCJE5XLoeRLdO6zh16jUADkWi6TMhPyPa99VxZEIIkTKpHrPTr18/2rRpw+PHj1Gr1VpfkugIkb20GzWCcpX+5tSp1+jrg69vQW5f8pdERwiRpaS6Zefp06cMGjSIPHnypEc8QohMICoqjh9/3MXKv4wAI0ztXrNhcRcaNSqn69CEECLVUp3sfP311+zfv58iRYqkRzxCCB0KjQzl5Kn7fP/dAa5eTeyqdvGMZd+KcVhZmuk4OiGE+DSpno0VGRlJmzZtyJ07N+XKlcPQ0FBrf//+/dM0wIwgs7GEgCWHltJz/AKi9lZHSdDD3t6CBQta4O5eVNehCSHEO6XbbKxly5axc+dOTExM2L9/v9ZS8CqVKksmO0J8ycLDw1myZDNjJl0g8m7izX09mzry34I25MolrTlCiKwv1S079vb29O/fn6FDh6Knl+rxzZmStOyIL1GCOoEtR7aw7O9LrFsXR0wMGBor/DytPv1715J7WgkhMr10a9mJjY2lXbt22SbREeJLdP3xdTxntuTeurLEXywNgIuLHStXtqNIEVsdRyeEEGkr1RlLly5dWLFiRXrEIoTIILcvJXDnd0/iL5ZGTw/GjKnNiRO9JNERQmRLqW7ZSUhIYOrUqezYsYPy5csnG6D866+/pllwQoi0s/XsVuqVbMjYsQeZOvUIimJJgULmrFzenmrV8us6PCGESDepTnYuXryIs7MzAJcuXdLaJ338QmQ+4eHheM3zYs/18+Td1o9HtxOH6XXv7sz06e5YWhrrOEIhhEhfqU529u3blx5xCCHSmKIonD17lp07d3LnkB3s7MWjeIWcOU2ZM6cZLVuW0nWIQgiRIT7pRqBvCgsLY+/evZQsWZKSJUumRUxCiM90JPAIJw6e4FHgazZsgFs3SwDg7l6E+fNb4OBgqeMIhRAi46Q62Wnbti21a9emb9++REVF4erqyp07d1AUheXLl9O6dev0iFMIkULjNo5j3Nlx2F+ry6uNtYiMBGNjfX7+uRF9+lRBT0+6m4UQX5ZUz8Y6ePAgtWrVAmDdunUoikJISAh//PEHEyZMSPMAhRCpUzlvDRI2NuHh8sREp0KFPAQE9KRfv6qS6AghvkipTnZCQ0OxtU2cnrp9+3Zat26NmZkZTZs25caNG2keoBDiw+49v8fcvXMBOHnyIf07XIEzlVCpYPBgN06c8KVMGTsdRymEELqT6m6sAgUKcOzYMWxtbdm+fTvLly8H4NWrV5iYmKR5gEKId1MUhQ2HN+C915v4BDVnNlky+89AEhIU8ue34r//vKhXz0nXYQohhM6lOtkZMGAA3t7eWFhYULBgQerWrQskdm+VK1cureMTQrzD8+fP2bJlC7fv3MbyZUFeravHP/evAdC+fVn+/rsJOXKY6jhKIYTIHFKd7PTu3ZsqVapw//59GjVqpLltROHChWXMjhDpLCo2itFrRmN50xJ1gsKliwaEbutIbJQaKytj/v67CR07lpM1r4QQ4g2fNPXc1dUVR0dHoqOjsbCwAKBp06ZpGpgQQpsyZgwzj/7JLzVf0TCyOaH7anHqVAQAcwqd42uvEth4l9dxlEIIkfmkaoBySEgIffr0IVeuXOTJk4c8efKQK1cu+vbtS0hISDqFKIQAUBkYMHD3K/zX5ubkv5U4dSoCAwM9DjS8j+/d9djkNNd1iEIIkSmluGXn5cuXVK9enYcPH+Lt7U2pUomrr165coUFCxawZ88ejh49So4cOdItWCG+NDP2zKCYbTEaOzcmpN9g9q69wphzy4lnP6tKtGJvvXvknfkvjBsHo0bpOlwhhMiUVIqiKCkpOGDAAPbs2cPu3bvJkyeP1r4nT57QuHFjGjRowPTp09Ml0PQUFhaGtbU1oaGhWFlZ6TocIXj9+jW9F/dmcfBiHPUd+a3cFvr02c7Dh68ZxQHGsQ/FyAhVbKwkOkKIL1ZK379T3I21fv16fvnll2SJDoC9vT1Tp05l3bp1nxatEAJInE4eEBDAjBkzyB2cG5MoG9jaEi+vVTx8+JpixWxxP7wAkhIdIyNJdIQQ4iNSnOw8fvyYMmXKvHd/2bJlefLkSZoEJcSX6PiN4/Sc0ZPNmzcTExND3HMnLOcP484xa1QqGDSoGufOfUuNvQshKdGJjYXx43UduhBCZGopTnZy5crFnTt33rs/KChIs7KyECJ1jt84Ts2lNZn3Yh6PYl9x/LgDf/31kmfBURQvnpPDh7sxbZo7ZtMmw+jRiV1XMTGJ30ePloRHCCE+IMUDlN3d3RkxYgS7du3CyMhIa19MTAyjRo3Cw8MjzQMU4ktQpUgVKlpU5PnFXKzdas/zZ4/R01MxaFA1xo2rh6mpYWJCk5ToJHVdJX0fPVr7sRBCCI0UJzvjxo3D1dWVYsWK0adPH0qWLImiKFy9epW///6bmJgYFi1alJ6xCpFtPA97zqDVg/jt69+wtbLl1atoCp/yI2BFIBBDyZK5mD+/BdWq5f/fQQkJ7x6MnPQ4ISHD4hdCiKwkxbOxILGrqnfv3uzcuZOkw1QqFY0aNeKvv/6iaNGi6RZoepLZWCIjXbt2DfdV7txT36ONXRs6Oozj22838/RpBHp6KgYPdsPfvy4mJp+05qcQQnwxUvr+nar/pk5OTmzbto1Xr15p7nBetGhRGasjRAqEh4ezbds2rly5QlWq8joqgftrq9By9woASpXKxYIFXlSpkk/HkQohRPbySR8dc+TIQZUqVdI6FiGyJbVazZgNY3h27RkOsQ6oVCpKxrdk//zKHA9ObM0ZMqQGo0fXkdYcIYRIB/KfVYh09v3y7/nrxl/kJCd+5mM4dsiGjRuvA1CmTG7mz29B5crSmiOEEOklVffGEkKk3ogmI8ill4sqr3z4dWo0GzfeRl9fxYgRtQgI6CmJjhBCpDNJdoRIY5vObMJnro9mEL9erCW1z//Jtt8tefYskrJl7ThxwpcJE+pjbCyNq0IIkd7kP60QaSQmJoal25bS/Xx3FBRq7a2F5Ytq9OmzlefPI9HXVzF8eC1GjKglSY4QQmQg+Y8rRBq4fv06W7ZsISwsDBdcMNLPwZrf9Nm2eTUA5cvnYf78Fri4OOg4UiGE+PJIsiPEZ7j99DbfrvgWl1cumGKKtbU13sokJk48y4sXdzEw0GPEiFoMH14LIyN9XYcrhBBfJEl2hPgM7vPcuRl7k5e8xK+EP8uXv2bDhqMAVKiQhwULvKhY0V7HUQohxJdNBigL8RkmN5xMAYOCNDQeSJ8+V9iw4ToGBnqMHVuXkyd7SKIjhBCZgLTsCJFC0bHRfL/ie5ysnBjaYigAbvkb43xyMlP+f90cZ2d75s9vQYUKkuQIIURmIcmOECnw8OFDBq0YxMrXK7HAgo7VO3JwZwj9+2/j1atoDA31GD26DkOG1MDQUMbmCCFEZiLJjhAfEBsby969ezl58iTFleI46jnStkB3+nQ/zObNifeHc3FxYMGCFpQrl0fH0QohhHgXSXaEeI+5B+Yy/+h8GsU2QoWKimUrkv/5VwwduJ+QkBsYGurh71+XwYPdpDVHCCEysUw9QNnf3x+VSqX1VbJkSc3+6Oho+vTpQ86cObGwsKB169Y8ffpUhxGL7OLao2t8u/9bjsYe5b7ZfRo0aMm8eTF8++12QkKicXXNy5kzvRg+vJYkOkIIkcll+padMmXKsHv3bs1jA4P/hTxw4EC2bNnCqlWrsLa2pm/fvrRq1YojR47oIlSRjZTMW5Iujl0IiQ7FWd2Nr77aSmhoDEZG+owdWxc/PzcMDDL1ZwUhhBD/L9MnOwYGBtjbJ5/ZEhoayr///svSpUupX78+APPnz6dUqVIcP36catWqvbfOmJgYYmJiNI/DwsLSPnCRpQQEBdBzdU9mtphJ5eKVARjbYDo9emyi3/bEZLtKlXzMn9+C0qVz6zJUIYQQqZTpP5reuHGDvHnzUrhwYby9vbl37x4AAQEBxMXF0bBhQ03ZkiVLUrBgQY4dO/bBOidNmoS1tbXmq0CBAul6DSLzSkhI4PDhw7Rb1I4zkWf4bv13KIrCv/+eoUyZv9m+/SbGxvpMmdKQI0e6SaIjhBBZUKZu2alatSoLFiygRIkSPH78mLFjx1KrVi0uXbrEkydPMDIywsbGRuuYPHny8OTJkw/WO2zYMAYNGqR5HBYWJgnPF+jRo0ds3LiRp0+f4o47R0yPMNbtNzw8lrBz5y0AqlZNbM0pVUqSHCGEyKoydbLj6emp+bl8+fJUrVqVQoUKsXLlSkxNTT+5XmNjY4yNjdMiRJEFhUaG4rvYl6jHUVSmMqampvg28qXCqW50aLKT169jMTbWZ8KE+gwcWA19/UzfACqEEOIDMnWy8zYbGxuKFy/OzZs3adSoEbGxsYSEhGi17jx9+vSdY3yEAMDfnzM3DrK6+D4MMaR1ydZUK+/O99/voequ+QxCzc7q3zBvXgtKlsyl62iFEEKkgSz1kTU8PJxbt27h4OBApUqVMDQ0ZM+ePZr9gYGB3Lt3j+rVq+swSpEZKYqS+IO+PvWW7mP2iYL8UesPYkPKUaXKQqrums949tHIoziHDnWVREcIIbKRTN2y4+fnR7NmzShUqBCPHj1izJgx6Ovr06FDB6ytrenevTuDBg3C1tYWKysr+vXrR/Xq1T84E0t8ef7Z+w//nv6XQ/0PYTpqFAA9Ro9m3rWddA96ykgOMJ59PO8/lBq/T9JxtEIIIdJapk52Hjx4QIcOHXjx4gW5c+emZs2aHD9+nNy5EweLTp8+HT09PVq3bk1MTAzu7u78/fffOo5aZBYRERGs3LSSgYEDiSGG0etGM7H1ZH7Rr0ucfn3GBK3Dm40Yk4Dafyy5xozWdchCCCHSgUrRtO9/ucLCwrC2tiY0NBQrKytdhyM+k6IoXLhwgR07dhAVFcUZzmCazxTfIv4M7L+PS5eCAYhRTcBIiQcjI3hj3SUhhBBZQ0rfv7PUmB0hPubCvQu4/OLCzPUziYqKwt7enp87/EGuc51p3GAFly4FkyuXGedaB/8v0YmNhfHjdR26EEKIdJKpu7GESK0+a/twLvIcr3jF4gaLCQ62pX79NTx8+BqALl0qMMPhDOaT/4Zx42DUqMREZ/T/d2H9/5geIYQQ2YckOyLLUxQFlUoFwL/t/qX9kvb4V/2VX399yLp1ibP1ihTJwaxZX9Hg6BIYPf5/iQ7877skPEIIkS1JsiOyrOjYaPot70d4VDjLei0DoGieYviazeKbr/YQFhaDgYEegwe7MWpUbUxNDeFQgnaikyTpcUJCBl+FEEKI9CYDlJEBylnRo0ePmLTq/9q787ioqv4P4J9hYAYBxQUFCRRzIUkWxVCgnys0lhlqT6ZZKRYaqUmWPtgjYFJRpmmPkks9qZXmkmkmpSEJuFAYiyAgkeKSgrggIsjizPn9oUyODAgIDDN83q/XvHTuPXfu98vxvubr4Zx7I7Dq2ipIIEHss7HoJHkEAQE/IiHhbwC3H/Wwbt0YuLhY6zZYIiJqEnX9/ubIDumVyspKHDhwAL/99hushBUGSQdhdD8//LKlEkuWrEVlpQoWFjJERIxEYOBAPuqBiIhY7JD+2JywGe/9+h7G3xoPE5igX79+8DCbgDlz9iMn5xAA4JlnHLFq1ZOwt7fUcbRERNRSsNghvVBSVoLXo19HkShCkiwJ745cgrVrT+HLL7cBALp2tcDKlU9i/Pi+6snKREREAIsdauGqVlqZm5oj4vEI7M78EWPNFmLMmH0oKCgBALz2mjsiInzQvr2pjqMlIqKWiBMaqEU6VXAKXsu98MX+L9Tbnnx4EhA1Ga+9Eo2CghL07WuFQ4f8sXr10yx0iIioRhzZoRal6lEPs/fMRsKtBPyV8BcmeU3G2jWpCA2NRWlpJWQyKRYu/D/Mn+8NuZz/hImIqHb8pqAW49q1a9izZw9OnjwJb3jjmvwapvdYhKFDvkFych4AYMiQ7li37mk4OlrpOFoiItIXLHZI55QqJYJ3BOPwicNQqBSQSqUY7qFA+d5hmPOf36FSCbRvb4qlS33h798fRkacgExERHXHYod0bn/GfizNXAoAGG49HM7tx2P69IM4c6YIAPD8849ixYpRsLGx0GWYRESkp1jskE7c/TwrhbMCE3+fiE7ohlMx/fHBlj0AgG7dLLF69Wg89VRvXYZKRER6jquxqNn9fOxn9PuoH3L+zgFwu/DxNZqPzfM7YsuWDBgZSfDmm4ORkfE6Cx0iInpgHNmhZlNZWYmYX2Pg/5s/LuIiZu2YhZVPbsaMGXsQG3saAODmZoPPPx+DgQNtdRssEREZDBY71Cxyc3Px448/orCwEE/jaZwwz0G//Nfh4rIa5eVKtGljjMWLhyMoaDCMjTngSEREjYfFDjWp/Gv5mLppKiwuW8AZzmjbti18H5qG38JT8UlGKgBAoeiJ1atHo0ePDroNloiIDBKLHWpS7/30HvZd3gdzmGNMn+eQEGeGt9+OhhBA585mWLFiFCZN6sfnWRERUZNhsUON7u6VVh//62McXXUUj1cE4J23z+PChWIAwNSpbli61BedOpnpMlQiImoFWOxQo1GpVPgg6gP8lP0T4oPiYWxsjKuXKmF7cC4+2XUCANCrV0esXfs0RozooeNoiYiotWCxQ43i2rVr2LBzAxadXQQllFgW9Qks/h6GBQtiUFxcAWNjI8yf74WFC4egTRsTXYdLREStCIsdeiBCCCQmJiImJgaVlZXwkfigrXFPfB/RAYm//wwAGDToIXz++Rg4O1vrOFoiImqNWOxQgx3OPozpO6fDt9wXHdABXbvaw+mEO1auTMGtWxfQtq0MEREj8dprAyGVcjk5ERHpBosdarDAHwKRWZ4JSIBZnZdh6dIc5OQkAQD8/ByxatVTsLNrp+MoiYiotWOxQ/Vy90qrz8d/jsDNc9E9IwCvb/sdANC1qwUiI5/CuHF9dRkmERGRGosdqpOi0iIEbApAJ5NOWD11NYQQOJlohr9XjUXKpTOQSIDAwIH44IORsLQ01XW4REREaix26L5Onz6NkO0h2F66HcYwxvjD07AsPBv79p0EADz6aGesWzcGXl72Oo6UiIioOhY7VKOysjJER0cjOTkZPdETAyQD4XBhIsY+EY3S0krIZFKEhAzB/PnekMmkug6XiIhIKxY7pNXqX1cjMiES42+NhxRSdGjvBNUGG3yfehEAMHRod6xd+zQcHa10HCkREVHtWOzQbYsWAVIpEBKC/Gv5mHtwLspQhj7Sfnh5F3AsKRapGIYOHUyxdOkT8Pd34/OsiIhIL7DYodukUiA0FABgExKCBf0XYH/MGXhvvICxRXuRhOGYNKkfli9XwNraQsfBEhER1R2LHcKJCyfwstmP2BgwCX1DQ3HjRgWyzrph6JZYvIUDWGb5JLy+/RThT/bWdahERET1xmKnFRNCICUlBdOjpiNJlQSFXQG2j56OQUvewwZIIYcSP3u9hBn7voCFhUzX4RIRETUIi51WqrCwEHv27MGpU6cwHMNReMUU8tjxGJxejLI7hY7KRIYnD3+l61CJiIgeCIudVkapUmL+d/ORmp2KIaohuHVLijPZTji9oy1UqmKEyw5BXqGEkMlgVFEBhIcDISG6DpuIiKjBWOy0MtsTt+OTrE8AIUHnvGGI222K/PyzAICt/bIw4fh+YPFiSEJCbhc6dyYts+AhIiJ9xWLHkN21nLzKxMET8dm+bzFuXRGK8mKwFcPRs2cH7PXORa+vtgKLF//TvupPFjxERKTHjHQdADWhO8vJ1yrskH81H+Xlt/D++/EY+V4J3syLA6RShIYOQXp6IHr1sNQsdKqEhNzerlTqJgciIqIHJBFCCF0HoWvXr1+HpaUlioqK0K5dO12H0yiUSiVi42Pxe/gYvHPgJr4Y7IJl16bjXyd2IBwHsP7h8fD+eR369Omk61CJiIgapK7f3yx2YHjFzoULF7B7925cvHgRaTdOwX1TBt7JS0L5nVVWaf+aCedtK3kHZCIi0mssdurBUIqdG2U3ELApALK/ZXBQPYy0NBPExADFxZUoQzjkuL3KSlJerutQiYiIHlhdv785Z8eAzNk6B1v+3oLvLyTgm01y7NpVieLiSnxmmww5lIBMBknVcnIiIqJWgsWOAVk48j1Y7p2Eks8n49TJcrRrJ0fC6AsIvLD79iTj8vLbf4aGsuAhIqJWg0vP9ck9S8m/TfgWO1J3YNuMbUifMBvRe3NQVOINAHjhBWeseSgFbT9ex+XkRETUqrHY0Sd3lpLfunULG126IeB4AMSlTvjvQ08gKD8G32E4HB074bPPRmPEiB7AorSal5MDXE5OREStAicoQ78mKF998010XLEC+4cMx1Rhh2mHzmGxiMW7xiNhvCgUb7/tBbmcNSwRERm+un5/81tRT+Rfy0fApgD0bd8XjzkPx3PxB3DyzlLyr3v/Cy/tXYeHH+6g6zCJiIhaHBY7euKJdU8g/cI5xO21xcfZQ1GGeMihhNLYBC9mb+M9c4iIiGrA1Vh6oKJCiQF/zwE+m4nibFuEGsWr75kjvVUJyXvv6TpEIiKiFosjOy3Uf6P/i5LSEgxqOxEzZ/6EEycuAzDBFw7H8MrpX/lkciIiojpisaNr9ywnLykpwaKti7A0cw1Cv+6O+IJ9OIHh6NLFHL/8Xy5cd+zkUnIiIqJ6YLGja3eWkwshkDF+PPbs+QnpcWYIiR6Ad5XxCJUMx6yZjyE8fATar/gQcOVSciIiovrg0nPofun51X+/iY5LVmCX+zAEnh+GV/PjEI4DWPPQM3jsh9Vwd7dt9piIiIhaOi491xM3ym6gu2Qzgro6IjwpFk/iIORQ4uiYGQjY+RmkUs4hJyIiehD8JtUhlUpg66Y/cSvyNbyXNwnld+6bI2QyPLZ7DQsdIiKiRsCRnWamUqkQ/mM47G89hi+W5SEh4W8ARljZ5Q/IC+55MjknGxMRET0wFjvNqKioCJPWTMXPO8uARBUgjGBhIcO+x3PhtXfPP6usuJyciIio0bDYaWz3LCUHACEEkpKScMr/3/DOvoWfK0cAAP71XF/8r3sa2i39nMvJiYiImgiLncZ2Zyk5ACAkBGln07Dkf19iwH/TMPfaAYRgOBx6tMO6tc/A17cnsCiTTyYnIiJqQix2GttdozK5+WfRP+0M3jlcgbkiDoukIyALC8WJ+d7/PJl80aL7fxYRERE1GIudphASgptlt9Djg8UovbPC6oseT2NKzFfo0YNPJiciImpOvKkgmu6mgpVSE5iobkFpbAKjinI+mZyIiKgR1fX7mzdyaSrh4TBR3eKTyYmIiHSMxU5TqFo6vngxJOXltycgh4be3k5ERETNymCKncjISDg4OMDU1BSDBg1CYmKibgK5q9DRWErOgoeIiEgnDKLY2bp1K+bOnYuwsDAkJyfD1dUVCoUCBQUFzR+MUlnzUvLFi7mUnIiIqJkZxATlQYMG4bHHHsOqVasA3H4kg729PWbPno3g4OD7Hq/rp54TERFR/bWaCcoVFRVISkqCj4+PepuRkRF8fHyQkJCg9Zjy8nJcv35d40VERESGSe+LncuXL0OpVMLa2lpju7W1NfLz87UeExERAUtLS/XL3t6+OUIlIiIiHdD7YqchFixYgKKiIvXr3Llzug6JiIiImoje30HZysoKUqkUFy9e1Nh+8eJF2NjYaD1GLpdDLpc3R3hERESkY3o/siOTyeDu7o6YmBj1NpVKhZiYGHh6euowMiIiImoJ9H5kBwDmzp2LKVOmYODAgfDw8MCKFStQUlICf39/XYdGREREOmYQxc7zzz+PS5cuITQ0FPn5+XBzc8PevXurTVomIiKi1scg7rPzoHifHSIiIv3Tau6zQ0RERFQbFjtERERk0Axizs6DqvpNHu+kTEREpD+qvrfvNyOHxQ6A4uJiAOCdlImIiPRQcXExLC0ta9zPCcq4fV+eCxcuoG3btpBIJLW2vX79Ouzt7XHu3DmDnczcGnIEmKehYZ6GozXkCDDPxiCEQHFxMWxtbWFkVPPMHI7s4PaDQ+3s7Op1TLt27Qz6HyfQOnIEmKehYZ6GozXkCDDPB1XbiE4VTlAmIiIig8Zih4iIiAwai516ksvlCAsLM+gHibaGHAHmaWiYp+FoDTkCzLM5cYIyERERGTSO7BAREZFBY7FDREREBo3FDhERERk0FjtERERk0FjsaBEZGQkHBweYmppi0KBBSExMrLX99u3b8cgjj8DU1BTOzs746aefminShqtPjhs2bIBEItF4mZqaNmO0DRMfH48xY8bA1tYWEokEu3btuu8xsbGxGDBgAORyOXr16oUNGzY0eZwPqr55xsbGVutPiUSC/Pz85gm4ASIiIvDYY4+hbdu26NKlC8aOHYvs7Oz7Hqdv12ZD8tTH63P16tVwcXFR32TO09MTP//8c63H6Ftf1jdHfexHbT788ENIJBIEBQXV2q65+5PFzj22bt2KuXPnIiwsDMnJyXB1dYVCoUBBQYHW9keOHMGkSZPwyiuvICUlBWPHjsXYsWNx/PjxZo687uqbI3D7zpd5eXnq15kzZ5ox4oYpKSmBq6srIiMj69Q+NzcXo0ePxvDhw5GamoqgoCC8+uqr2LdvXxNH+mDqm2eV7OxsjT7t0qVLE0X44OLi4jBz5kz89ttviI6ORmVlJZ544gmUlJTUeIw+XpsNyRPQv+vTzs4OH374IZKSkvDHH39gxIgR8PPzQ0ZGhtb2+tiX9c0R0L9+vNfRo0exdu1auLi41NpOJ/0pSIOHh4eYOXOm+r1SqRS2trYiIiJCa/sJEyaI0aNHa2wbNGiQmDFjRpPG+SDqm+P69euFpaVlM0XXNACInTt31tpm/vz54tFHH9XY9vzzzwuFQtGEkTWuuuR54MABAUAUFhY2S0xNoaCgQAAQcXFxNbbRx2vzXnXJ0xCuTyGE6NChg/jiiy+07jOEvhSi9hz1vR+Li4tF7969RXR0tBg6dKiYM2dOjW110Z8c2blLRUUFkpKS4OPjo95mZGQEHx8fJCQkaD0mISFBoz0AKBSKGtvrWkNyBIAbN26ge/fusLe3v+//TvSVvvXlg3Jzc0PXrl3h6+uLw4cP6zqceikqKgIAdOzYscY2htCfdckT0O/rU6lUYsuWLSgpKYGnp6fWNvrel3XJEdDvfpw5cyZGjx5drZ+00UV/sti5y+XLl6FUKmFtba2x3drausb5DPn5+fVqr2sNydHR0RFffvklfvjhB3zzzTdQqVTw8vLC33//3RwhN5ua+vL69eu4efOmjqJqfF27dsWaNWuwY8cO7NixA/b29hg2bBiSk5N1HVqdqFQqBAUFwdvbG/369auxnb5dm/eqa576en2mp6fDwsICcrkcr732Gnbu3AknJyetbfW1L+uTo772IwBs2bIFycnJiIiIqFN7XfQnn3pO9+Xp6anxvxEvLy/07dsXa9euRXh4uA4jo4ZwdHSEo6Oj+r2XlxdOnjyJ5cuX4+uvv9ZhZHUzc+ZMHD9+HIcOHdJ1KE2qrnnq6/Xp6OiI1NRUFBUV4bvvvsOUKVMQFxdXYzGgj+qTo77247lz5zBnzhxER0e36AnVLHbuYmVlBalUiosXL2psv3jxImxsbLQeY2NjU6/2utaQHO9lYmKC/v3746+//mqKEHWmpr5s164d2rRpo6OomoeHh4deFA+zZs3Cnj17EB8fDzs7u1rb6tu1ebf65Hkvfbk+ZTIZevXqBQBwd3fH0aNH8emnn2Lt2rXV2uprX9Ynx3vpSz8mJSWhoKAAAwYMUG9TKpWIj4/HqlWrUF5eDqlUqnGMLvqTv8a6i0wmg7u7O2JiYtTbVCoVYmJiavw9q6enp0Z7AIiOjq7197K61JAc76VUKpGeno6uXbs2VZg6oW992ZhSU1NbdH8KITBr1izs3LkTv/76K3r06HHfY/SxPxuS57309fpUqVQoLy/Xuk8f+1Kb2nK8l77048iRI5Geno7U1FT1a+DAgZg8eTJSU1OrFTqAjvqzyaY+66ktW7YIuVwuNmzYIDIzM8X06dNF+/btRX5+vhBCiJdeekkEBwer2x8+fFgYGxuLpUuXiqysLBEWFiZMTExEenq6rlK4r/rm+O6774p9+/aJkydPiqSkJDFx4kRhamoqMjIydJVCnRQXF4uUlBSRkpIiAIhPPvlEpKSkiDNnzgghhAgODhYvvfSSuv2pU6eEmZmZmDdvnsjKyhKRkZFCKpWKvXv36iqFOqlvnsuXLxe7du0SOTk5Ij09XcyZM0cYGRmJ/fv36yqF+woMDBSWlpYiNjZW5OXlqV+lpaXqNoZwbTYkT328PoODg0VcXJzIzc0VaWlpIjg4WEgkEvHLL78IIQyjL+uboz72Y03uXY3VEvqTxY4WK1euFN26dRMymUx4eHiI3377Tb1v6NChYsqUKRrtt23bJvr06SNkMpl49NFHRVRUVDNHXH/1yTEoKEjd1traWjz11FMiOTlZB1HXT9US63tfVblNmTJFDB06tNoxbm5uQiaTiYcfflisX7++2eOur/rm+dFHH4mePXsKU1NT0bFjRzFs2DDx66+/6ib4OtKWHwCN/jGEa7Mheerj9Tlt2jTRvXt3IZPJROfOncXIkSPVRYAQhtGX9c1RH/uxJvcWOy2hPyVCCNF040ZEREREusU5O0RERGTQWOwQERGRQWOxQ0RERAaNxQ4REREZNBY7REREZNBY7BAREZFBY7FDREREBo3FDhERERk0FjtEBmbRokVwc3PTdRhUR7GxsZBIJLh27VqTn+vKlSvo0qULTp8+3aDjMzMzYWdnh5KSksYNjKiJsdghakEuXbqEwMBAdOvWDXK5HDY2NlAoFDh8+HCTntfBwQErVqxolM+qqKjAkiVL4OrqCjMzM1hZWcHb2xvr169HZWVlo5yjuUydOhVjx45ttM8bNmwYgoKCNLZ5eXkhLy8PlpaWjXaemrz//vvw8/ODg4MDAOD06dOQSCSQSqU4f/68Rtu8vDwYGxtDIpGoiyMnJycMHjwYn3zySZPHStSYWOwQtSDPPvssUlJSsHHjRvz555/YvXs3hg0bhitXrug6tDqpqKiAQqHAhx9+iOnTp+PIkSNITEzEzJkzsXLlSmRkZOg6xCbxIEWcTCaDjY0NJBJJI0ZUXWlpKf73v//hlVdeqbbvoYcewldffaWxbePGjXjooYeqtfX398fq1atx69atJouVqNE16ZO3iKjOCgsLBQARGxtba7szZ86IZ555Rpibm4u2bduK5557Tv3EeiGECAsLE66urur39z6UTwgh/Pz81A/mGzp0aLUHT1Y5ePCgePzxx4Wpqamws7MTs2fPFjdu3Kgxto8++kgYGRlpfYBhRUWF+tiysjIxe/Zs0blzZyGXy4W3t7dITExUt616uOn+/fuFu7u7aNOmjfD09BQnTpzQ+Mzdu3eLgQMHCrlcLjp16iTGjh2r3ldWVibeeustYWtrK8zMzISHh4c4cOCAev/69euFpaWl2Lt3r3jkkUeEubm5UCgU4sKFC+qf470/lwMHDojc3FwBQGzZskUMGTJEyOVysX79enH58mUxceJEYWtrK9q0aSP69esnNm/erD7flClTqn1ebm6uOtfCwkJ12++++044OTkJmUwmunfvLpYuXaqRd/fu3cX7778v/P39hYWFhbC3txdr166tsV+EEGL79u2ic+fOGtuqclm4cKHo3bu3xr4+ffqIkJAQdZxVysvLhVwuF/v376/1fEQtCUd2iFoICwsLWFhYYNeuXSgvL9faRqVSwc/PD1evXkVcXByio6Nx6tQpPP/88w0+7/fffw87OzssXrwYeXl5yMvLAwCcPHkSo0aNwrPPPou0tDRs3boVhw4dwqxZs2r8rE2bNsHHxwf9+/evts/ExATm5uYAgPnz52PHjh3YuHEjkpOT0atXLygUCly9elXjmP/85z9YtmwZ/vjjDxgbG2PatGnqfVFRURg3bhyeeuoppKSkICYmBh4eHur9s2bNQkJCArZs2YK0tDQ899xzGDVqFHJyctRtSktLsXTpUnz99deIj4/H2bNn8fbbbwMA3n77bUyYMAGjRo1S/1y8vLzUxwYHB2POnDnIysqCQqFAWVkZ3N3dERUVhePHj2P69Ol46aWXkJiYCAD49NNP4enpiYCAAPXn2dvbV/s5JSUlYcKECZg4cSLS09OxaNEihISEYMOGDRrtli1bhoEDByIlJQWvv/46AgMDkZ2dXWPfHDx4EO7u7lr3PfPMMygsLMShQ4cAAIcOHUJhYSHGjBlTra1MJoObmxsOHjxY47mIWhxdV1tE9I/vvvtOdOjQQZiamgovLy+xYMECcezYMfX+X375RUilUnH27Fn1toyMDAFAPTJS35EdIW6PFCxfvlyjzSuvvCKmT5+use3gwYPCyMhI3Lx5U2v8bdq0EW+88Uat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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# plot the results!\n", - "from matplotlib import pyplot as plt\n", - "\n", - "fig, ax = plt.subplots()\n", - "ax.plot(concentrations, pi_ideal, label=\"engine='ideal'\", ls=\"--\", color=\"gray\")\n", - "ax.plot(concentrations, pi_phreeqc, label=\"engine='phreeqc'\", ls=\":\", color=\"green\")\n", - "ax.plot(concentrations, pi_native, label=\"engine='native'\", ls=\"-\", color=\"navy\")\n", - "ax.plot(concentrations, pi_idst, label=\"experiment\", ls=\"\", color=\"red\", marker=\"x\")\n", - "ax.legend()\n", - "ax.set_xlabel(\"Solute Concentration (M)\")\n", - "ax.set_ylabel(\"Osmotic Pressure (bar)\")\n", - "fig.suptitle(\"pyEQL prediction of NaCl osmotic pressure\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd14cb5f-f9a4-4006-ae26-2ef827d2412d", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python (conda: skagit2)", - "language": "python", - "name": "skagit2" - }, - "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.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/docs/examples/.ipynb_checkpoints/speedup-checkpoint.ipynb b/docs/examples/.ipynb_checkpoints/speedup-checkpoint.ipynb deleted file mode 100644 index 4654bfa7..00000000 --- a/docs/examples/.ipynb_checkpoints/speedup-checkpoint.ipynb +++ /dev/null @@ -1,336 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "c45d3fd6-8af1-4df7-ac05-2805da805893", - "metadata": {}, - "outputs": [], - "source": [ - "from pyEQL import Solution" - ] - }, - { - "cell_type": "markdown", - "id": "a376cef5-2e52-4aa7-a365-57337b20171b", - "metadata": {}, - "source": [ - "### Before optimization" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "bdf1fb10-a567-499d-a0c2-2e3ea4e7fdab", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "298 ms ± 4.11 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "b6ce2ea9-8a86-4140-bd82-35f72f06fbbc", - "metadata": {}, - "outputs": [], - "source": [ - "s = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "3d391433-2a16-4470-8c40-2b43cda68b35", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "27.1 ms ± 277 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.get_activity_coefficient(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "7ef3de2d-15cc-4f3e-8753-1b9de8238aa0", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-04 17:15:55,353 solution.py viscosity_kinematic 599 Viscosity coefficients for NaCl not found. Viscosity will be approximate.\n", - "WARNING 2023-11-04 17:15:55,408 solution.py viscosity_kinematic 599 Viscosity coefficients for NaCl not found. Viscosity will be approximate.\n", - "WARNING 2023-11-04 17:15:55,460 solution.py viscosity_kinematic 599 Viscosity coefficients for NaCl not found. Viscosity will be approximate.\n", - "WARNING 2023-11-04 17:15:55,489 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,507 solution.py viscosity_kinematic 599 Viscosity coefficients for NaCl not found. Viscosity will be approximate.\n", - "WARNING 2023-11-04 17:15:55,535 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,644 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,678 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,788 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,822 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,932 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:55,964 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,071 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,104 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,211 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,242 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,348 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,384 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,495 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:15:56,528 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "142 ms ± 1.96 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.conductivity" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b30d7f1c-9630-4e21-b275-cb3befc2433f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "5.27 ms ± 153 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.ionic_strength" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "40a55c8b-947d-4806-8094-2188f244816a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2.43 ms ± 18.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.get_transport_number(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "314d44f5-88c1-44a8-b0e2-3e072e3ad8ab", - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "'break' outside loop (668683560.py, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m Cell \u001b[0;32mIn [8], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m break\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m 'break' outside loop\n" - ] - } - ], - "source": [ - "break" - ] - }, - { - "cell_type": "markdown", - "id": "e8ae1012-8728-448a-bebe-03752f97a578", - "metadata": {}, - "source": [ - "### After optimization" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "2f1739e4-da68-484f-b691-9be13a00bc94", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "85 ms ± 1.46 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "cc95a42c-1151-4756-9289-6aee0717fe81", - "metadata": {}, - "outputs": [], - "source": [ - "s = Solution({\"Na+\": \"2 mol/L\", \"Cl-\": \"2 mol/L\"})" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "3940edb9-94d6-45bd-a6db-c535d4968045", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "14 ms ± 239 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.get_activity_coefficient(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "185d5272-84a1-4944-bb39-948cc970989d", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING 2023-11-04 17:30:41,861 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,874 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,912 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,917 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,953 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,958 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:41,995 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,000 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,036 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,042 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,078 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,084 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,119 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,124 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,160 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species H[+1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n", - "WARNING 2023-11-04 17:30:42,166 engines.py get_activity_coefficient 314 Ionic strength too high to estimate activity for species OH[-1]. Specify parameters for Pitzer model. Returning unit activity coefficient\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "41.6 ms ± 639 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.conductivity" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "c3cd2d5b-f3a1-4909-aa18-caeebc60ae4e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "527 µs ± 7.91 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.ionic_strength" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "366a8d79-d08b-48cc-ae9f-6e3dd1e25b3a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "549 µs ± 11 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)\n" - ] - } - ], - "source": [ - "%%timeit\n", - "s.get_transport_number(\"Na+\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c0d007b0-ec00-4c06-bee4-40d04e6cebf2", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "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.10.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -}