diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41fdee0554..2834540916 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -199,11 +199,21 @@ jobs: source pygraphistry/bin/activate ./bin/typecheck.sh + - name: Full dbscan tests (rich featurize) + run: | + source pygraphistry/bin/activate + ./bin/test-dbscan.sh + - name: Full feature tests (rich featurize) run: | source pygraphistry/bin/activate ./bin/test-features.sh + - name: Full search tests (rich featurize) + run: | + source pygraphistry/bin/activate + ./bin/test-text.sh + - name: Full umap tests (rich featurize) run: | source pygraphistry/bin/activate diff --git a/.gitignore b/.gitignore index 9fb2c10c4c..f8a1ee9544 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# vim temporary files +*.swp +*.swo + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/CHANGELOG.md b/CHANGELOG.md index 57e82f8602..69fd423074 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,19 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Development] +### Added +* AI: moves public `g.g_dgl` from KG `embed` method to private method `g._kg_dgl` +* AI: moves public `g.DGL_graph` to private attribute `g._dgl_graph` +* AI: BREAKING CHANGES: to return matrices during transform, set the flag: `X, y = g.transform(df, return_graph=False)` default behavior is ~ `g2 = g.transform(df)` returning a Plottable instance. + ## [0.28.7 - 2022-12-22] ### Added +* AI: all `transform_*` methods return graphistry Plottable instances, using an infer_graph method. To return matrices, set the `return_graph=False` flag. +* AI: adds `g.get_matrix(**kwargs)` general method to retrieve (sub)-feature/target matrices +* AI: DBSCAN -- `g.featurize().dbscan()` and `g.umap().dbscan()` with options to use UMAP embedding, feature matrix, or subset of feature matrix via `g.dbscan(cols=[...])` +* AI: Demo cleanup using ModelDict & new features, refactoring demos using `dbscan` and `transform` methods. +* Tests: dbscan tests * AI: Easy import of featurization kwargs for `g.umap(**kwargs)` and `g.featurize(**kwargs)` * AI: `g.get_features_by_cols` returns featurized submatrix with `col_part` in their columns * AI: `g.conditional_graph` and `g.conditional_probs` assessing conditional probs and graph diff --git a/README.md b/README.md index 00ed8c5e2f..4756c86654 100644 --- a/README.md +++ b/README.md @@ -358,12 +358,12 @@ Automatically and intelligently transform text, numbers, booleans, and other for g = g.umap() # UMAP, GNNs, use features if already provided, otherwise will compute # other pydata libraries - X = g._node_features # g._get_feature('nodes') - y = g._node_target # g._get_target('nodes') + X = g._node_features # g._get_feature('nodes') or g.get_matrix() + y = g._node_target # g._get_target('nodes') or g.get_matrix(target=True) from sklearn.ensemble import RandomForestRegressor - model = RandomForestRegressor().fit(X, y) #assumes train/test split - new_df = pandas.read_csv(...) - X_new, _ = g.transform(new_df, None, kind='nodes') + model = RandomForestRegressor().fit(X, y) # assumes train/test split + new_df = pandas.read_csv(...) # mini batch + X_new, _ = g.transform(new_df, None, kind='nodes', return_graph=False) preds = model.predict(X_new) ``` @@ -371,17 +371,17 @@ Automatically and intelligently transform text, numbers, booleans, and other for ```python # graphistry - from graphistry.features import search_model, topic_model, ngrams_model, ModelDict, default_featurize_parameters + from graphistry.features import search_model, topic_model, ngrams_model, ModelDict, default_featurize_parameters, default_umap_parameters g = graphistry.nodes(df) g2 = g.umap(X=[..], y=[..], **search_model) - # set custom encoding model with any feature kwargs + # set custom encoding model with any feature/umap/dbscan kwargs new_model = ModelDict(message='encoding new model parameters is easy', **default_featurize_parameters) new_model.update(dict( y=[...], kind='edges', - model_name='sbert/hf/a_cool_transformer_model', + model_name='sbert/cool_transformer_model', use_scaler_target='kbins', n_bins=11, strategy='normal')) @@ -389,7 +389,6 @@ Automatically and intelligently transform text, numbers, booleans, and other for g3 = g.umap(X=[..], **new_model) # compare g2 vs g3 or add to different pipelines - # ... ``` @@ -397,13 +396,13 @@ See `help(g.featurize)` for more options ### [sklearn-based UMAP](https://umap-learn.readthedocs.io/en/latest/), [cuML-based UMAP](https://docs.rapids.ai/api/cuml/stable/api.html?highlight=umap#cuml.UMAP) -* Reduce dimensionality and plot a similarity graph from feature vectors: +* Reduce dimensionality by plotting a similarity graph from feature vectors: ```python # automatic feature engineering, UMAP g = graphistry.nodes(df).umap() - # plot the similarity graph even though there was no explicit edge_dataframe passed in -- it is created during UMAP. + # plot the similarity graph without any explicit edge_dataframe passed in -- it is created during UMAP. g.plot() ``` @@ -411,8 +410,20 @@ See `help(g.featurize)` for more options ```python new_df = pd.read_csv(...) - embeddings, X_new, _ = g.transform_umap(new_df, None, kind='nodes') + embeddings, X_new, _ = g.transform_umap(new_df, None, kind='nodes', return_graph=False) ``` +* Infer a new graph from new data using the old umap coordinates to run inference without having to train a new umap model. + + ```python + new_df = pd.read_csv(...) + g2 = g.transform_umap(new_df, return_graph=True) # return_graph=True is default + g2.plot() # + + # or if you want the new minibatch to cluster to closest points in previous fit: + g3 = g.transform_umap(new_df, return_graph=True, merge_policy=True) + g3.plot() # useful to see how new data connects to old -- play with `sample` and `n_neighbors` to control how much of old to include + ``` + * UMAP supports many options, such as supervised mode, working on a subset of columns, and passing arguments to underlying `featurize()` and UMAP implementations (see `help(g.umap)`): @@ -451,11 +462,11 @@ See `help(g.umap)` for more options from [your_training_pipeline] import train, model # Train - g = graphistry.nodes(df).build_gnn(y=`target`) + g = graphistry.nodes(df).build_gnn(y_nodes=`target`) G = g.DGL_graph train(G, model) # predict on new data - X_new, _ = g.transform(new_df, None, kind='nodes' or 'edges') # no targets + X_new, _ = g.transform(new_df, None, kind='nodes' or 'edges', return_graph=False) # no targets predictions = model.predict(G_new, X_new) ``` @@ -480,12 +491,21 @@ GNN support is rapidly evolving, please contact the team directly or on Slack fo #encode text as paraphrase embeddings, supports any sbert model model_name = "paraphrase-MiniLM-L6-v2") + # or use convienence `ModelDict` to store parameters + + from graphistry.features import search_model + g2 = g.featurize(X = ['text_col_1', .., 'text_col_n'], kind='nodes', **search_model) + + # query using the power of transformers to find richly relevant results + results_df, query_vector = g2.search('my natural language query', ...) - print(results_df[['_distance', 'text_col_1', ..., 'text_col_n']]) #sorted by relevancy + print(results_df[['_distance', 'text_col', ..]]) #sorted by relevancy + + # or see graph of matching entities and original edges - # or see graph of matching entities and similarity edges (or optional original edges) g2.search_graph('my natural language query', ...).plot() + ``` @@ -521,7 +541,7 @@ See `help(g.search_graph)` for options relation=['relationship_1', 'relationship_4', ..], destination=['entity_l', 'entity_m', ..], threshold=0.9, # score threshold - return_dataframe=False) # set to `True` to return dataframe, or just access via `g5._edges` + return_dataframe=False) # set to `True` to return dataframe, or just access via `g4._edges` ``` * Detect Anamolous Behavior (example use cases such as Cyber, Fraud, etc) @@ -552,8 +572,42 @@ See `help(g.search_graph)` for options g2.predict_links_all(threshold=0.95).plot() ``` -See `help(g.embed)`, `help(g.predict_links)` , `help(g.predict_links_all)` for options +See `help(g.embed)`, `help(g.predict_links)` , or `help(g.predict_links_all)` for options + +### DBSCAN + +* Enrich UMAP embeddings or featurization dataframe with GPU or CPU DBSCAN + + ```python + g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node') + + # cluster by UMAP embeddings + kind = 'nodes' | 'edges' + g2 = g.umap(kind=kind).dbscan(kind=kind) + print(g2._nodes['_dbscan']) | print(g2._edges['_dbscan']) + + # dbscan in `umap` or `featurize` via flag + g2 = g.umap(dbscan=True, min_dist=0.2, min_samples=1) + + # or via chaining, + g2 = g.umap().dbscan(min_dist=1.2, min_samples=2, **kwargs) + + # cluster by feature embeddings + g2 = g.featurize().dbscan(**kwargs) + + # cluster by a given set of feature column attributes, inhereted from `g.get_matrix(cols)` + g2 = g.featurize().dbscan(cols=['ip_172', 'location', 'alert'], **kwargs) + + # equivalent to above (ie, cols != None and umap=True will still use features dataframe, rather than UMAP embeddings) + g2 = g.umap().dbscan(cols=['ip_172', 'location', 'alert'], umap=True | False, **kwargs) + g2.plot() # color by `_dbscan` + + new_df = pd.read_csv(..) + # transform on new data according to fit dbscan model + g3 = g2.transform_dbscan(new_df) + ``` +See `help(g.dbscan)` or `help(g.transform_dbscan)` for options ### Quickly configurable diff --git a/bin/test-dbscan.sh b/bin/test-dbscan.sh new file mode 100755 index 0000000000..8e39b18fb7 --- /dev/null +++ b/bin/test-dbscan.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -ex + +# Run from project root +# - Args get passed to pytest phase +# Non-zero exit code on fail + +# Assume [umap-learn,test] + +python -m pytest --version + +python -B -m pytest -vv \ + graphistry/tests/test_compute_cluster.py + +#chmod +x bin/test-dbscan.sh \ No newline at end of file diff --git a/bin/test-text.sh b/bin/test-text.sh new file mode 100755 index 0000000000..949bd68735 --- /dev/null +++ b/bin/test-text.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -ex + +# Run from project root +# - Args get passed to pytest phase +# Non-zero exit code on fail + +# Assume [umap-learn,test] + +python -m pytest --version + +python -B -m pytest -vv \ + graphistry/tests/test_text_utils.py + +# chmod +x bin/test-text.sh \ No newline at end of file diff --git a/demos/ai/Introduction/Ask-HackerNews-Demo.ipynb b/demos/ai/Introduction/Ask-HackerNews-Demo.ipynb index 47e010af9a..8fd5a0b3a2 100644 --- a/demos/ai/Introduction/Ask-HackerNews-Demo.ipynb +++ b/demos/ai/Introduction/Ask-HackerNews-Demo.ipynb @@ -5,7 +5,7 @@ "id": "c39da4a9", "metadata": {}, "source": [ - "# Hello PyGraphistry[ai] - HackerNews visual semantic search with UMAP & BERT and \n", + "# Hello PyGraphistry[ai] - HackerNews visual semantic search with UMAP & BERT.\n", "\n", "`PyGraphistry[ai]` can quickly create visual graph search interfaces for structured text. It automates much of the work in cleaning, connecting, encoding, searching, and visualing graph data. The result is increasing the *time to graph* and overall results in as little as one line of code.\n", "\n", @@ -28,18 +28,7 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "385ea5a4", - "metadata": {}, - "outputs": [], - "source": [ - "# depends on where you have your data/ folder\n", - "#mkdir data" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "8e7f75b3", "metadata": {}, "outputs": [], @@ -49,17 +38,7 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "cbd6050e", - "metadata": {}, - "outputs": [], - "source": [ - "# cd .. " - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "503a96d2", "metadata": {}, "outputs": [], @@ -81,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "a73d67a0", "metadata": {}, "outputs": [], @@ -92,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "46f3b61b", "metadata": {}, "outputs": [], @@ -103,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "0c0bcb74", "metadata": {}, "outputs": [], @@ -114,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "25a407dc", "metadata": {}, "outputs": [], @@ -124,32 +103,290 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "e8edc98e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Index(['title', 'url', 'text', 'dead', 'by', 'score', 'time', 'timestamp',\n", + " 'type', 'id', 'parent', 'descendants', 'ranking', 'deleted'],\n", + " dtype='object')" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df.columns" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "9536276e", "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titleurltextdeadbyscoretimetimestamptypeidparentdescendantsrankingdeleted
0I'm a software engineer going blind, how should I prepare?NaNI'm a 24 y/o full stack engineer (I know some of you are rolling your eyes right now, just highlighting that I have experience on frontend apps as well as backend architecture). I'v...NaNzachrip327015873320262020-04-19 21:33:46+00:00story22918980NaN473.0NaNNaN
1Am I the longest-serving programmer – 57 years and counting?NaNIn May of 1963, I started my first full-time job as a computer programmer for Mitchell Engineering Company, a supplier of steel buildings. At Mitchell, I developed programs in Fortran II on an IB...NaNgenedangelo263415908900242020-05-31 01:53:44+00:00story23366546NaN531.0NaNNaN
2Is S3 down?NaNI&#x27;m getting<p>{\\n &quot;errorCode&quot; : &quot;InternalError&quot;\\n}<p>When I attempt to use the AWS Console to view s3NaNiamdeedubs258914883039582017-02-28 17:45:58+00:00story13755673NaN1055.0NaNNaN
3What tech job would let me get away with the least real work possible?NaNHey HN,<p>I&#x27;ll probably get a lot of flak for this. Sorry.<p>I&#x27;m an average developer looking for ways to work as little as humanely possible.<p>The pandemic made me realize that I do no...NaNlmueongoqx202216177848632021-04-07 08:41:03+00:00story26721951NaN1091.0NaNNaN
4What books changed the way you think about almost everything?NaNI was reflecting today about how often I think about Freakonomics. I don&#x27;t study it religiously. I read it one time more than 10 years ago. I can only remember maybe a single specific anecdot...NaNanderspitman200915493879052019-02-05 17:31:45+00:00story19087418NaN1165.0NaNNaN
\n", + "
" + ], + "text/plain": [ + " title \\\n", + "0 I'm a software engineer going blind, how should I prepare? \n", + "1 Am I the longest-serving programmer – 57 years and counting? \n", + "2 Is S3 down? \n", + "3 What tech job would let me get away with the least real work possible? \n", + "4 What books changed the way you think about almost everything? \n", + "\n", + " url \\\n", + "0 NaN \n", + "1 NaN \n", + "2 NaN \n", + "3 NaN \n", + "4 NaN \n", + "\n", + " text \\\n", + "0 I'm a 24 y/o full stack engineer (I know some of you are rolling your eyes right now, just highlighting that I have experience on frontend apps as well as backend architecture). I'v... \n", + "1 In May of 1963, I started my first full-time job as a computer programmer for Mitchell Engineering Company, a supplier of steel buildings. At Mitchell, I developed programs in Fortran II on an IB... \n", + "2 I'm getting

{\\n "errorCode" : "InternalError"\\n}

When I attempt to use the AWS Console to view s3 \n", + "3 Hey HN,

I'll probably get a lot of flak for this. Sorry.

I'm an average developer looking for ways to work as little as humanely possible.

The pandemic made me realize that I do no... \n", + "4 I was reflecting today about how often I think about Freakonomics. I don't study it religiously. I read it one time more than 10 years ago. I can only remember maybe a single specific anecdot... \n", + "\n", + " dead by score time timestamp type \\\n", + "0 NaN zachrip 3270 1587332026 2020-04-19 21:33:46+00:00 story \n", + "1 NaN genedangelo 2634 1590890024 2020-05-31 01:53:44+00:00 story \n", + "2 NaN iamdeedubs 2589 1488303958 2017-02-28 17:45:58+00:00 story \n", + "3 NaN lmueongoqx 2022 1617784863 2021-04-07 08:41:03+00:00 story \n", + "4 NaN anderspitman 2009 1549387905 2019-02-05 17:31:45+00:00 story \n", + "\n", + " id parent descendants ranking deleted \n", + "0 22918980 NaN 473.0 NaN NaN \n", + "1 23366546 NaN 531.0 NaN NaN \n", + "2 13755673 NaN 1055.0 NaN NaN \n", + "3 26721951 NaN 1091.0 NaN NaN \n", + "4 19087418 NaN 1165.0 NaN NaN " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df.head() # see the dataset" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "3a479ce6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
titletext
0I'm a software engineer going blind, how should I prepare?I&#x27;m a 24 y&#x2F;o full stack engineer (I know some of you are rolling your eyes right now, just highlighting that I have experience on frontend apps as well as backend architecture). I&#x27;v...
1Am I the longest-serving programmer – 57 years and counting?In May of 1963, I started my first full-time job as a computer programmer for Mitchell Engineering Company, a supplier of steel buildings. At Mitchell, I developed programs in Fortran II on an IB...
2Is S3 down?I&#x27;m getting<p>{\\n &quot;errorCode&quot; : &quot;InternalError&quot;\\n}<p>When I attempt to use the AWS Console to view s3
3What tech job would let me get away with the least real work possible?Hey HN,<p>I&#x27;ll probably get a lot of flak for this. Sorry.<p>I&#x27;m an average developer looking for ways to work as little as humanely possible.<p>The pandemic made me realize that I do no...
4What books changed the way you think about almost everything?I was reflecting today about how often I think about Freakonomics. I don&#x27;t study it religiously. I read it one time more than 10 years ago. I can only remember maybe a single specific anecdot...
\n", + "
" + ], + "text/plain": [ + " title \\\n", + "0 I'm a software engineer going blind, how should I prepare? \n", + "1 Am I the longest-serving programmer – 57 years and counting? \n", + "2 Is S3 down? \n", + "3 What tech job would let me get away with the least real work possible? \n", + "4 What books changed the way you think about almost everything? \n", + "\n", + " text \n", + "0 I'm a 24 y/o full stack engineer (I know some of you are rolling your eyes right now, just highlighting that I have experience on frontend apps as well as backend architecture). I'v... \n", + "1 In May of 1963, I started my first full-time job as a computer programmer for Mitchell Engineering Company, a supplier of steel buildings. At Mitchell, I developed programs in Fortran II on an IB... \n", + "2 I'm getting

{\\n "errorCode" : "InternalError"\\n}

When I attempt to use the AWS Console to view s3 \n", + "3 Hey HN,

I'll probably get a lot of flak for this. Sorry.

I'm an average developer looking for ways to work as little as humanely possible.

The pandemic made me realize that I do no... \n", + "4 I was reflecting today about how often I think about Freakonomics. I don't study it religiously. I read it one time more than 10 years ago. I can only remember maybe a single specific anecdot... " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df[good_cols].head()" ] @@ -164,10 +401,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "748116ab", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "OMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Encoding 3000 records using SentenceTransformer took 1.53 minutes\n" + ] + } + ], "source": [ "from time import time\n", "t0 = time()\n", @@ -183,23 +442,22 @@ "# set to False if you want to reload last trained instance\n", "process = True\n", "\n", + "print('-'*80)\n", "if process:\n", " # Umap will create a similarity graph from the features which we can view as a graph\n", - " g2 = g.umap(X=['title', 'text'], # the features to encode (can add/remove 'text', etc)\n", + " g2 = g.umap(X=['title'], # the features to encode (can add/remove 'text', etc)\n", " y=['score'], # for demonstrative purposes, we include a target -- though this one is not really conditioned on textual features in a straightforward way\n", " model_name='msmarco-distilbert-base-v2', #'paraphrase-MiniLM-L6-v2', etc, from sbert/Huggingface, the text encoding model\n", " min_words = 0, # when 0 forces all X=[..] as textually encoded, higher values would ascertain if a column is textual or not depending on average number of words per column\n", " use_ngrams=False, # set to True if you want ngram features instead (does not make great plots but useful for other situations)\n", - " use_scaler_target='zscale', # for regressive targets\n", + " use_scaler_target='standard', # for regressive targets\n", " use_scaler=None, # there are many more settings see `g.featurize?` and `g.umap?` for further options\n", " )\n", " g2.save_search_instance('data/hn.search')\n", - " print('-'*80)\n", " print(f'Encoding {df.shape[0]} records using {str(g2._node_encoder.text_model)[:19]} took {(time()-t0)/60:.2f} minutes')\n", "else:\n", " # or load the search instance\n", " g2 = g.load_search_instance('data/hn.search')\n", - " print('-'*80)\n", " print(f'Loaded saved instance')\n", " \n", "################################################################\n" @@ -207,10 +465,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "d6de7795", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# see all the data\n", "g2.plot()" @@ -218,36 +504,541 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "22ed4eec", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "

\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
title_0title_1title_2title_3title_4title_5title_6title_7title_8title_9...title_758title_759title_760title_761title_762title_763title_764title_765title_766title_767
16540.6044880.101652-0.0634970.3075420.8443740.1975610.8966310.6318570.315805-0.578581...-0.042918-0.322729-0.277031-0.319512-0.165631-0.5843830.2618680.429799-0.303072-0.377494
1538-1.103507-0.835217-1.2375200.5491960.3972460.199831-1.1968740.290311-1.1710760.513540...0.006427-0.731422-0.750713-0.4866370.841622-0.1986520.195885-0.5702500.050978-0.436235
27080.3260920.0457120.3082240.803963-0.063246-0.123905-0.7314680.2276430.261804-0.048012...-0.2065010.0344020.796114-0.2370420.1177020.649347-0.2994330.995765-0.009557-0.119748
620.926326-0.3926180.035194-0.161504-0.326212-0.1667370.0709370.950549-0.228309-0.056017...-0.5511320.639072-0.468963-0.2904770.117795-0.8035800.8048260.423588-0.092650-0.687976
14810.384588-0.8327600.0338760.2154920.593188-0.432190-0.2835620.4008130.045255-0.430429...0.028084-0.152095-0.2266460.2087030.1870910.1336190.4862500.5752100.730881-0.129466
..................................................................
1264-0.098364-0.2760860.5505860.5420780.321339-0.601650-0.540975-0.3333770.0940110.031201...-0.266734-1.1711370.190349-1.094334-0.9390850.294115-0.118376-0.473456-0.3218700.111786
11710.702274-0.0917610.348669-0.4317061.1911160.006005-1.105823-0.625805-0.1680520.075096...0.838124-0.3052360.3982990.1562320.1468670.339570-0.152106-0.456346-0.3934800.293989
589-0.406301-0.531044-0.563821-0.0126610.3802320.1879000.1690930.475025-0.7724570.188258...-0.478902-0.7819220.1352310.8473670.4511990.4208090.683643-0.7132180.390578-0.141390
23420.1289660.1684800.055048-0.287427-0.069591-0.533780-0.401158-0.270016-0.3983770.062334...1.068983-0.483162-0.373780-0.4115170.0445800.6025510.4239180.028719-0.1603960.211980
2782-0.1442290.703746-0.852380-0.084720-0.654991-0.3746480.142915-0.072289-0.0828890.965485...0.0686120.432348-0.718999-0.4656701.0386470.308591-0.3692320.004829-0.0208010.027217
\n", + "

3000 rows × 768 columns

\n", + "
" + ], + "text/plain": [ + " title_0 title_1 title_2 title_3 title_4 title_5 title_6 \\\n", + "1654 0.604488 0.101652 -0.063497 0.307542 0.844374 0.197561 0.896631 \n", + "1538 -1.103507 -0.835217 -1.237520 0.549196 0.397246 0.199831 -1.196874 \n", + "2708 0.326092 0.045712 0.308224 0.803963 -0.063246 -0.123905 -0.731468 \n", + "62 0.926326 -0.392618 0.035194 -0.161504 -0.326212 -0.166737 0.070937 \n", + "1481 0.384588 -0.832760 0.033876 0.215492 0.593188 -0.432190 -0.283562 \n", + "... ... ... ... ... ... ... ... \n", + "1264 -0.098364 -0.276086 0.550586 0.542078 0.321339 -0.601650 -0.540975 \n", + "1171 0.702274 -0.091761 0.348669 -0.431706 1.191116 0.006005 -1.105823 \n", + "589 -0.406301 -0.531044 -0.563821 -0.012661 0.380232 0.187900 0.169093 \n", + "2342 0.128966 0.168480 0.055048 -0.287427 -0.069591 -0.533780 -0.401158 \n", + "2782 -0.144229 0.703746 -0.852380 -0.084720 -0.654991 -0.374648 0.142915 \n", + "\n", + " title_7 title_8 title_9 ... title_758 title_759 title_760 \\\n", + "1654 0.631857 0.315805 -0.578581 ... -0.042918 -0.322729 -0.277031 \n", + "1538 0.290311 -1.171076 0.513540 ... 0.006427 -0.731422 -0.750713 \n", + "2708 0.227643 0.261804 -0.048012 ... -0.206501 0.034402 0.796114 \n", + "62 0.950549 -0.228309 -0.056017 ... -0.551132 0.639072 -0.468963 \n", + "1481 0.400813 0.045255 -0.430429 ... 0.028084 -0.152095 -0.226646 \n", + "... ... ... ... ... ... ... ... \n", + "1264 -0.333377 0.094011 0.031201 ... -0.266734 -1.171137 0.190349 \n", + "1171 -0.625805 -0.168052 0.075096 ... 0.838124 -0.305236 0.398299 \n", + "589 0.475025 -0.772457 0.188258 ... -0.478902 -0.781922 0.135231 \n", + "2342 -0.270016 -0.398377 0.062334 ... 1.068983 -0.483162 -0.373780 \n", + "2782 -0.072289 -0.082889 0.965485 ... 0.068612 0.432348 -0.718999 \n", + "\n", + " title_761 title_762 title_763 title_764 title_765 title_766 \\\n", + "1654 -0.319512 -0.165631 -0.584383 0.261868 0.429799 -0.303072 \n", + "1538 -0.486637 0.841622 -0.198652 0.195885 -0.570250 0.050978 \n", + "2708 -0.237042 0.117702 0.649347 -0.299433 0.995765 -0.009557 \n", + "62 -0.290477 0.117795 -0.803580 0.804826 0.423588 -0.092650 \n", + "1481 0.208703 0.187091 0.133619 0.486250 0.575210 0.730881 \n", + "... ... ... ... ... ... ... \n", + "1264 -1.094334 -0.939085 0.294115 -0.118376 -0.473456 -0.321870 \n", + "1171 0.156232 0.146867 0.339570 -0.152106 -0.456346 -0.393480 \n", + "589 0.847367 0.451199 0.420809 0.683643 -0.713218 0.390578 \n", + "2342 -0.411517 0.044580 0.602551 0.423918 0.028719 -0.160396 \n", + "2782 -0.465670 1.038647 0.308591 -0.369232 0.004829 -0.020801 \n", + "\n", + " title_767 \n", + "1654 -0.377494 \n", + "1538 -0.436235 \n", + "2708 -0.119748 \n", + "62 -0.687976 \n", + "1481 -0.129466 \n", + "... ... \n", + "1264 0.111786 \n", + "1171 0.293989 \n", + "589 -0.141390 \n", + "2342 0.211980 \n", + "2782 0.027217 \n", + "\n", + "[3000 rows x 768 columns]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# get the encoded features, and use in downstream models (clf.fit(x, y), etc)\n", "x=g2._get_feature('nodes')\n", + "# same as \n", + "x = g2._node_features\n", + "# same as\n", + "x = g2.get_matrix()\n", "x" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "67b15408", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
score
1654-0.38835
1538-0.33530
2708-0.71150
622.70326
1481-0.31601
......
1264-0.19060
1171-0.13273
5890.44605
2342-0.62951
2782-0.72115
\n", + "

3000 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " score\n", + "1654 -0.38835\n", + "1538 -0.33530\n", + "2708 -0.71150\n", + "62 2.70326\n", + "1481 -0.31601\n", + "... ...\n", + "1264 -0.19060\n", + "1171 -0.13273\n", + "589 0.44605\n", + "2342 -0.62951\n", + "2782 -0.72115\n", + "\n", + "[3000 rows x 1 columns]" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# likewise with the (scaled) targets\n", "y = g2._get_target('nodes')\n", + "# same as \n", + "y = g2._node_target\n", + "# same as\n", + "y = g2.get_matrix(target=True)\n", "y" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "f43b7806", - "metadata": { - "scrolled": false - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# visualize the results where we prune edges using the `filter_weighted_edges` method\n", "# this keeps all weights that are (more similar) 0.5 and above. The initial layout is the same (given by umap in 2d)\n", @@ -265,10 +1056,73 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "e79eabfc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
title
1647Is it normal to fall out of love with coding?
1412What landing page do you love?
2854Hackers falling in love
2770What do you love/hate about terminals? Would you change them?
1182Have you found something you love to do? If yes how?
\n", + "
" + ], + "text/plain": [ + " title\n", + "1647 Is it normal to fall out of love with coding?\n", + "1412 What landing page do you love?\n", + "2854 Hackers falling in love\n", + "2770 What do you love/hate about terminals? Would you change them?\n", + "1182 Have you found something you love to do? If yes how?" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# direct keyword search when fuzzy=False and a set of columns are given, does not require featurization\n", "g.search('love', fuzzy=False, cols=['title'])[0][['title']]" @@ -276,12 +1130,250 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, + "id": "c9a8e3bb-faf0-432f-be9e-b173528af866", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
title
2532How did you find your passion?
1182Have you found something you love to do? If yes how?
2509After almost 30 years the romance is over - What now?
2669Is it better to be good at many things or great at one thing?
1164My wife needs something to do from home to make money...
2469Does success in work bring you happiness?
2177As an adult introvertish nerd what makes you happy?
1650Anxiety is limiting my enjoyment of a wonderful career. Can you relate?
1853What do you wish you had done/known in your 30s?
1360Turning 40 soon – seeking personal and professional life advice
\n", + "
" + ], + "text/plain": [ + " title\n", + "2532 How did you find your passion?\n", + "1182 Have you found something you love to do? If yes how?\n", + "2509 After almost 30 years the romance is over - What now?\n", + "2669 Is it better to be good at many things or great at one thing?\n", + "1164 My wife needs something to do from home to make money...\n", + "2469 Does success in work bring you happiness?\n", + "2177 As an adult introvertish nerd what makes you happy?\n", + "1650 Anxiety is limiting my enjoyment of a wonderful career. Can you relate?\n", + "1853 What do you wish you had done/known in your 30s?\n", + "1360 Turning 40 soon – seeking personal and professional life advice" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g2.search('love')[0][['title']]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, "id": "85cf9c06", - "metadata": { - "scrolled": false - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "*********************************\n", + "Is true love possible?\n", + "******************************\n", + "1182 Have you found something you love to do? If yes how?\n", + "2043 Why aren't there many credible online bachelors programs?\n", + "2509 After almost 30 years the romance is over - What now?\n", + "2469 Does success in work bring you happiness?\n", + "2532 How did you find your passion?\n", + "1569 What do you wish you had known before you turned 40?\n", + "2669 Is it better to be good at many things or great at one thing?\n", + "1853 What do you wish you had done/known in your 30s?\n", + "1198 What are the books you wish your colleagues had read?\n", + "400 What Lived Up to the Hype?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "How to create deep learning models?\n", + "******************************\n", + "35 How to get started with machine learning?\n", + "959 How to Seriously Start with Machine Learning and AI\n", + "2172 Why TensorFlow instead of Theano for deep learning?\n", + "1833 How do you manage multiple learning projects?\n", + "1739 How to incorporate machine learning into day job?\n", + "208 Good ways to capture institutional knowledge?\n", + "1726 What do you use Machine Learning for?\n", + "2219 How do I start with test driven development?\n", + "1988 How to develop a growth mindset?\n", + "704 Best introductory video courses on ML and Deep Learning?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "Best tech careers\n", + "******************************\n", + "1328 What tech that's right around the corner are you most excited about?\n", + "366 Joining Big Tech in One’s 40s\n", + "3 What tech job would let me get away with the least real work possible?\n", + "247 What is the most exciting development in your field right now?\n", + "2428 Companies of one, what is your tech stack?\n", + "748 Companies of one, what is your tech stack?\n", + "981 Who here has built a profitable startup while keeping their day job?\n", + "831 What company environment has enabled your best work?\n", + "801 What are some of the best job boards you have seen (any industry)?\n", + "259 What was your experience starting a tech consultancy?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "How do I make more money?\n", + "******************************\n", + "1302 How do you earn your money?\n", + "975 Why can't I make as much as I make?\n", + "500 Ways to generate income when you're at home without pay?\n", + "1164 My wife needs something to do from home to make money...\n", + "1034 How do you motivate yourself to keep working on a project?\n", + "2496 Should I find a job or try to build a profitable project?\n", + "844 How do you decide when you've done enough work for the day?\n", + "402 How to optimize your career for happiness?\n", + "1870 How to get out of Tech and still make a decent living?\n", + "1987 How do you stay productive after work?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "Advances in particle physics\n", + "******************************\n", + "1277 What are the greatest discoveries in the last few years?\n", + "1200 Will there ever be a resurgence of interest in symbolic AI?\n", + "438 What tech were you convinced would take the world by storm but didn't?\n", + "850 Any scientifically proven techniques to boost concentration?\n", + "738 Has any progress been made on large format E-ink displays?\n", + "2528 Why aren't there any real alternatives to Electron?\n", + "1029 I'm looking for a good book on the fundamentals of CS\n", + "2399 What is the emerging state of the art in fuzzing techniques?\n", + "522 What are some interesting projects to reuse your old devices?\n", + "650 What things do you wish you discovered earlier?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "Best apps and gadgets\n", + "******************************\n", + "2638 What are the best web tools to build basic web apps as of October 2016?\n", + "817 Best-architected open-source business applications worth studying?\n", + "2769 What Android apps do you use?\n", + "1032 What are the best technologies you've worked with this year?\n", + "1439 What is the best enterprise software you use every day?\n", + "2826 Inspirational money making web apps made by hackers.\n", + "211 What's your favorite way of getting a web app up quickly in 2018?\n", + "2773 Best tech for a web site 2018? (PHP, Rails, Django, Node, Go, etc.)?\n", + "1923 What is good business advice for independent mobile app developers?\n", + "2658 What is the best way to promote your new fancy web application?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "Graph Neural Networks\n", + "******************************\n", + "1827 What was your experience using a graph database?\n", + "1825 Why GraphQL APIs but no Datalog APIs?\n", + "1155 Why are relational DBs are the standard instead of graph-based DBs?\n", + "1540 If you've used a graph database, would you use it again?\n", + "799 Were you happy moving your API from REST to GraphQL?\n", + "919 What's the best algorithms and data structures online course?\n", + "2907 What are the best resources for learning about algorithmic trading?\n", + "1436 Looking for a book on algorithms and data structures\n", + "377 What are some examples of good database schema designs?\n", + "2498 Building a game for AI Research\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "recommend impactful books\n", + "******************************\n", + "113 Great fiction books that have had a positive impact on your life?\n", + "2507 What book impacted your life the most and how?\n", + "104 What books have made the biggest impact on your mental models?\n", + "2737 Which books have helped you the most professionally?\n", + "523 Which non-technology book has influenced you the most and why?\n", + "1099 Recommendations of good cybercrime novels?\n", + "1933 Recommend books that give you insight into other professions\n", + "2837 What are the best books for professional effectiveness?\n", + "1764 What is one book you would recommend everyone to read?\n", + "815 What makes a good technical leader – any recommended books?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n", + "*********************************\n", + "lamenting about life\n", + "******************************\n", + "1218 Words of encouragement for someone lost in life?\n", + "1337 What do you regret in life?\n", + "2155 The Internet is getting lame. What's next?\n", + "741 I'm So Lonely\n", + "2165 Coping with Loneliness\n", + "514 When you feel stuck in life\n", + "1526 What should I say to my manager when my performance starts suffering?\n", + "969 How to cope with the death of a dear person?\n", + "2195 I'm a solopreneur and I feel demoralised\n", + "520 Failed interview, feeling unemployable and depressed – what do I do?\n", + "Name: title, dtype: object\n", + "------------------------------------------------------------\n" + ] + } + ], "source": [ "# Query semantically instead of strict keyword matching\n", "\n", @@ -317,10 +1409,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "302a0b53", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "gr = g2.search_graph('How to create deep learning models', thresh=15, top_n=50, scale=0.25, broader=False) \n", "gr.plot()" @@ -328,20 +1448,76 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "543f7b83", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "g2.search_graph('Graph Neural Networks', thresh=50, top_n=50, scale=0.1, broader=False).plot()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "6f2f9157", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "g2.search_graph('fraud detection algorithms', thresh=50, top_n=50, scale=0.1, broader=False).plot() # works better if you encode 'text' column as well" ] @@ -356,12 +1532,360 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "id": "09b941fe", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
title_0title_1title_2title_3title_4title_5title_6title_7title_8title_9...title_758title_759title_760title_761title_762title_763title_764title_765title_766title_767
15170.9791800.041072-0.5930980.2143040.962338-0.713328-0.9896970.1453880.0756080.488215...-0.6967080.139317-0.846404-0.025490-0.120986-0.0558430.6379300.1435140.585826-0.303448
16050.6886530.019184-0.227892-0.2392110.1897950.341207-0.120877-1.2968780.2069080.103815...-0.236452-0.3842940.3940590.244530-0.3649240.675864-0.271245-0.173634-0.298026-0.017564
1451-0.1847700.235804-0.400443-0.2115110.1148180.160413-0.1312620.500900-0.2752310.190890...0.091999-0.233226-0.072699-0.7134600.4236841.398612-0.2034360.473697-0.219005-0.128714
1372-0.9836800.548434-0.5843510.3537030.117870-0.0988791.095775-0.385954-0.5412510.007578...0.0470790.485933-0.285741-0.035659-0.1018070.1101451.122281-0.237854-0.5323320.939817
964-0.431375-0.915085-0.5808610.3954720.406366-0.1311931.074949-0.996813-0.183665-0.006735...-0.9463000.433078-0.1901540.137894-0.198106-0.261280-0.6958570.226295-0.670496-0.423368
11040.096140-0.0561720.0631500.2348380.117753-0.346006-0.744430-0.1511070.1430600.241910...0.500574-0.4781880.296040-0.612845-0.324935-0.4394640.4697100.5394910.906302-0.175188
370.281097-0.6086630.4235990.4207871.051380-0.0272900.602898-0.2847270.099539-1.925934...-0.300906-0.1112351.1238930.459886-0.2181240.5902450.296381-0.609109-0.147541-1.250704
228-0.131974-0.062444-0.8378200.162044-0.4514660.3191390.052473-0.631871-0.020183-0.478724...-0.1010251.011868-0.704747-0.454947-0.2272430.9617580.6868370.5102590.270457-1.069947
13400.6343220.3514940.0380980.234291-0.872616-0.458497-0.1796050.2568170.1226790.471110...0.6821620.1848810.3820030.2360480.035794-0.4627130.3330540.4479520.9125960.432614
1681-0.244261-0.050637-0.4746880.063758-0.309980-0.171460-0.609836-0.007839-0.3715130.509530...-0.222305-1.502060-0.571068-1.054443-0.434218-0.1450710.131197-0.6852010.0558740.055352
\n", + "

10 rows × 768 columns

\n", + "
" + ], + "text/plain": [ + " title_0 title_1 title_2 title_3 title_4 title_5 title_6 \\\n", + "1517 0.979180 0.041072 -0.593098 0.214304 0.962338 -0.713328 -0.989697 \n", + "1605 0.688653 0.019184 -0.227892 -0.239211 0.189795 0.341207 -0.120877 \n", + "1451 -0.184770 0.235804 -0.400443 -0.211511 0.114818 0.160413 -0.131262 \n", + "1372 -0.983680 0.548434 -0.584351 0.353703 0.117870 -0.098879 1.095775 \n", + "964 -0.431375 -0.915085 -0.580861 0.395472 0.406366 -0.131193 1.074949 \n", + "1104 0.096140 -0.056172 0.063150 0.234838 0.117753 -0.346006 -0.744430 \n", + "37 0.281097 -0.608663 0.423599 0.420787 1.051380 -0.027290 0.602898 \n", + "228 -0.131974 -0.062444 -0.837820 0.162044 -0.451466 0.319139 0.052473 \n", + "1340 0.634322 0.351494 0.038098 0.234291 -0.872616 -0.458497 -0.179605 \n", + "1681 -0.244261 -0.050637 -0.474688 0.063758 -0.309980 -0.171460 -0.609836 \n", + "\n", + " title_7 title_8 title_9 ... title_758 title_759 title_760 \\\n", + "1517 0.145388 0.075608 0.488215 ... -0.696708 0.139317 -0.846404 \n", + "1605 -1.296878 0.206908 0.103815 ... -0.236452 -0.384294 0.394059 \n", + "1451 0.500900 -0.275231 0.190890 ... 0.091999 -0.233226 -0.072699 \n", + "1372 -0.385954 -0.541251 0.007578 ... 0.047079 0.485933 -0.285741 \n", + "964 -0.996813 -0.183665 -0.006735 ... -0.946300 0.433078 -0.190154 \n", + "1104 -0.151107 0.143060 0.241910 ... 0.500574 -0.478188 0.296040 \n", + "37 -0.284727 0.099539 -1.925934 ... -0.300906 -0.111235 1.123893 \n", + "228 -0.631871 -0.020183 -0.478724 ... -0.101025 1.011868 -0.704747 \n", + "1340 0.256817 0.122679 0.471110 ... 0.682162 0.184881 0.382003 \n", + "1681 -0.007839 -0.371513 0.509530 ... -0.222305 -1.502060 -0.571068 \n", + "\n", + " title_761 title_762 title_763 title_764 title_765 title_766 \\\n", + "1517 -0.025490 -0.120986 -0.055843 0.637930 0.143514 0.585826 \n", + "1605 0.244530 -0.364924 0.675864 -0.271245 -0.173634 -0.298026 \n", + "1451 -0.713460 0.423684 1.398612 -0.203436 0.473697 -0.219005 \n", + "1372 -0.035659 -0.101807 0.110145 1.122281 -0.237854 -0.532332 \n", + "964 0.137894 -0.198106 -0.261280 -0.695857 0.226295 -0.670496 \n", + "1104 -0.612845 -0.324935 -0.439464 0.469710 0.539491 0.906302 \n", + "37 0.459886 -0.218124 0.590245 0.296381 -0.609109 -0.147541 \n", + "228 -0.454947 -0.227243 0.961758 0.686837 0.510259 0.270457 \n", + "1340 0.236048 0.035794 -0.462713 0.333054 0.447952 0.912596 \n", + "1681 -1.054443 -0.434218 -0.145071 0.131197 -0.685201 0.055874 \n", + "\n", + " title_767 \n", + "1517 -0.303448 \n", + "1605 -0.017564 \n", + "1451 -0.128714 \n", + "1372 0.939817 \n", + "964 -0.423368 \n", + "1104 -0.175188 \n", + "37 -1.250704 \n", + "228 -1.069947 \n", + "1340 0.432614 \n", + "1681 0.055352 \n", + "\n", + "[10 rows x 768 columns]" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "x, y = g2.transform(df.sample(10), df.sample(10), kind='nodes') # or edges if given or already produced through umap-ing the nodes, \n", + "sdf = df.sample(10)\n", + "x, y = g2.transform(sdf, sdf, return_graph=False) # or edges if given or already produced through umap-ing the ny_nodes=\n", " #and if neither, set `embedding=True` for random embedding of size `n_topics`\n", "x" ] @@ -376,13 +1900,82 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "id": "e68126cd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xy
217812.0678985.299919
122711.8311994.594526
684-3.1081384.623506
173310.2674676.992209
70211.2295307.411973
\n", + "
" + ], + "text/plain": [ + " x y\n", + "2178 12.067898 5.299919\n", + "1227 11.831199 4.594526\n", + "684 -3.108138 4.623506\n", + "1733 10.267467 6.992209\n", + "702 11.229530 7.411973" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "emb, x, y = g2.transform_umap(df.sample(10), df.sample(10))\n", - "emb" + "emb, x, y = g2.transform_umap(df.sample(10), df.sample(10), return_graph=False)\n", + "emb.head()" ] }, { @@ -395,80 +1988,446 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "id": "d148348e", "metadata": {}, "outputs": [], "source": [ "# this inherets all the arguments from the g.featurize api for both nodes and edges, see g.build_gnn? for details\n", - "g3 = g25.build_gnn() # we use the filtered edges graphistry instance as it has higher fidelity similarity scores on edges\n", + "g3 = g25.build_gnn(y_nodes='score') # we use the filtered edges graphistry instance as it has higher fidelity similarity scores on edges\n", " # ie, less edges" ] }, { "cell_type": "code", - "execution_count": null, - "id": "5989c286", - "metadata": {}, - "outputs": [], - "source": [ - "# notice the difference in edge dataframes between g2/5 and g3\n", - "g25._edges" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "59af921c", - "metadata": {}, - "outputs": [], - "source": [ - "# versus\n", - "g3._edges" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af1cd73e", - "metadata": {}, - "outputs": [], - "source": [ - "# Edges come from data supplied by umap on nodes\n", - "g3._edge_encoder.feature_names_in" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 28, "id": "764e7ba7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123456789...299129922993299429952996299729982999_weight
21.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.797920
41.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.547040
61.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.862698
71.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.801896
81.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.653791
\n", + "

5 rows × 3001 columns

\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 4 5 6 7 8 9 ... 2991 2992 2993 \\\n", + "2 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 \n", + "4 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 \n", + "6 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 \n", + "7 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 \n", + "8 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 \n", + "\n", + " 2994 2995 2996 2997 2998 2999 _weight \n", + "2 0.0 0.0 0.0 0.0 0.0 0.0 0.797920 \n", + "4 0.0 0.0 0.0 0.0 0.0 0.0 0.547040 \n", + "6 0.0 0.0 0.0 0.0 0.0 0.0 0.862698 \n", + "7 0.0 0.0 0.0 0.0 0.0 0.0 0.801896 \n", + "8 0.0 0.0 0.0 0.0 0.0 0.0 0.653791 \n", + "\n", + "[5 rows x 3001 columns]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g3._edge_features.head()" + "g3.get_matrix(kind='edges').head()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "id": "fc1955b1", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
0123456789...299129922993299429952996299729982999_weight
70430.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.01.000000
106330.00.00.00.00.00.00.00.01.00.0...0.00.00.00.00.00.00.00.00.01.000000
11800.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.01.000000
67690.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.724311
472010.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.514489
\n", + "

5 rows × 3001 columns

\n", + "
" + ], + "text/plain": [ + " 0 1 2 3 4 5 6 7 8 9 ... 2991 2992 \\\n", + "7043 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", + "10633 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.0 0.0 ... 0.0 0.0 \n", + "1180 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", + "6769 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", + "47201 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", + "\n", + " 2993 2994 2995 2996 2997 2998 2999 _weight \n", + "7043 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.000000 \n", + "10633 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.000000 \n", + "1180 0.0 0.0 0.0 0.0 0.0 0.0 0.0 1.000000 \n", + "6769 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.724311 \n", + "47201 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.514489 \n", + "\n", + "[5 rows x 3001 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Since edges are featurized, we can transform on \"unseen/batch\" ones\n", - "# y_edges will be none since we don't have a label for the implicit edges. One could supply it via enrichment (like clustering, annotation etc)\n", "edge_data = g3._edges.sample(10)\n", "\n", - "x_edges, _ = g3.transform(edge_data, None, kind='edges')\n", - "x_edges" + "# y_edges will be None since we don't have a label for the implicit edges. One could supply it via enrichment (like clustering, annotation etc)\n", + "x_edges, _ = g3.transform(edge_data, None, kind='edges', return_graph=False)\n", + "x_edges.head()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "id": "59d403f9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Graph(num_nodes=3000, num_edges=19100,\n", + " ndata_schemes={'feature': Scheme(shape=(768,), dtype=torch.float32), 'target': Scheme(shape=(1,), dtype=torch.float64), 'train_mask': Scheme(shape=(), dtype=torch.bool), 'test_mask': Scheme(shape=(), dtype=torch.bool)}\n", + " edata_schemes={'feature': Scheme(shape=(3001,), dtype=torch.float64), 'train_mask': Scheme(shape=(), dtype=torch.bool), 'test_mask': Scheme(shape=(), dtype=torch.bool)})" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# once built, we can get the DGL graph itself\n", "G = g3.DGL_graph\n", @@ -477,10 +2436,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "id": "8380122a", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'feature': tensor([[ 0.6045, 0.1017, -0.0635, ..., 0.4298, -0.3031, -0.3775],\n", + " [-1.1035, -0.8352, -1.2375, ..., -0.5702, 0.0510, -0.4362],\n", + " [ 0.3261, 0.0457, 0.3082, ..., 0.9958, -0.0096, -0.1197],\n", + " ...,\n", + " [-0.4063, -0.5310, -0.5638, ..., -0.7132, 0.3906, -0.1414],\n", + " [ 0.1290, 0.1685, 0.0550, ..., 0.0287, -0.1604, 0.2120],\n", + " [-0.1442, 0.7037, -0.8524, ..., 0.0048, -0.0208, 0.0272]]), 'target': tensor([[-0.3883],\n", + " [-0.3353],\n", + " [-0.7115],\n", + " ...,\n", + " [ 0.4461],\n", + " [-0.6295],\n", + " [-0.7211]], dtype=torch.float64), 'train_mask': tensor([True, True, True, ..., True, True, True]), 'test_mask': tensor([False, False, False, ..., False, False, False])}" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# the features, targets, and masks\n", "G.ndata" @@ -488,10 +2470,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "id": "63beefab", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([19100, 3001])" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# `build_gnn()` will turn edges gotten from umap into bonafide feature matrices, \n", "# and make features out of explicit edges with `build_gnn(X_edges=[...], ..)`\n", @@ -500,12 +2493,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "id": "45d3a37a", - "metadata": { - "scrolled": false - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# see the edge features which are shape (n_edges, n_nodes + weight)\n", "# notice that had we used filter_weighted_edges to create a new graphistry instance and then .build_gnn() we would get\n", @@ -516,10 +2530,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "6c150a8e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA20AAAHVCAYAAABi9BP7AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAEAAElEQVR4nOz9fXCnV5bfh30ILLqxwIKNdAdiV3PabPdMiww9DGfpoamdzJieqdkd72Ts0SgrrSTrxS6rVCnHeVHixLGtuOzYlmzJthyVX1Jrx3JkuxRLsmUpa6nWO57N7E5xRZHmDEW61S1wIHSBjUIHAvzrxgKLbizA/HHvZ77neQA0Z9e7ZVaMW4UC8Dz3uS/nnvdz7r1PfPDBB5yVs3JWzspZOStn5ayclbNyVs7KWflolqn/vgdwVs7KWTkrZ+WsnJWzclbOylk5K2fl9HJmtJ2Vs3JWzspZOStn5ayclbNyVs7KR7icGW1n5ayclbNyVs7KWTkrZ+WsnJWz8hEuZ0bbWTkrZ+WsnJWzclbOylk5K2flrHyEy5nRdlbOylk5K2flrJyVs3JWzspZOSsf4XJmtJ2Vs3JWzspZOStn5ayclbNyVs7KR7j8hhhtTzzxxN//xBNP3H7iiSfee+KJJ/7PvxF9nJWzclbOylk5K2flrJyVs3JWzsr/EMoTv973tD3xxBPTwN8EfhR4H3gD+F0ffPDBzV/Xjs7KWTkrZ+WsnJWzclbOylk5K2flfwDlNyLS9vcA733wwQcrH3zwwSPg/wV89Tegn7NyVs7KWTkrZ+WsnJWzclbOyln5//vyA78BbT4NrJX/3wdeGVd64okn/iDwBwHm56f/7ueuH8LfAmaAaeCo//xK//kAWAQOgV+CyT78t8Aj4AngfJ/MFLDTf/8QsA887HV+AJgD9oBf7v//ADBfnp3v43tU3tvHk31Ih73uUR8q/f1h73cBOOh9/0p/dqHXoTy33ak+Bsc+08dJ7+NB//sH+rup/vevALu9jSc6iPxxTE/2/w/Kt3v99w/2sTzqsDrq7/z+h3q9w17noPTzK33udexPdFjv977o35wHZvvfR/35dJ/DQW/vXP9ur8CJ8u1egeVMf/5EqfuItiaQta/tfAD8Uunbfhf6mPbJWjivmfLto97/wz6emT5+v3X+1j8o9fY6DB1/hdkH/ftfpq3VD/R2HpUxibv+7PT2q8dF3BfGzu0HCF5a/wNCWo5zuvT7S6Xf6T6H2T7GAxreCCeLZLpb4Oe45kq9g15PHLSPcZnr74/6N4/6PKZpayt8hNcTfZwzfQwfdBg7z5leR7byQW/viLamloVe1+8elfmcY4hTlgoz6V+Y7Pd+LhA8kkbPFRiIX7/S5/RDHUaPenvCSH423X9+sIxjn9AXBA/pfQkfn82UuuKNMD8s9Z7sv+UPR/1ZpT3xW3wRtsL+B8u8DwusxKknyo9zEAec+weEl5/r3z4i6zLmG47XsfxAb+s8wX15+A/19vZp8H6Chkfn+88v9XZse5bAW7463dv4oM+38ngI7zzs7xW+1pOnyQPlL7Z32Od/fvTtQ4JH4o/je9Tr/UBvQ/yvfF6+cq4/2+t//0D/XxrdZ0hzrucRkRXSi/wEhvKo/v2ww+uHynyka3HkJLlZ5YA05Foedfgo58Ql1145vdf7lV+Ivz/U2/wlIiPHfEKe+gFDvi/Mdsr7uvZTpc4PMKQR+aJ09UsFtk/2b11n//6gj9d6v8wQR3+wz+1XyjzUa6YIbYorykRxQbqrPMufh/1beewhQ74hvGd7/V9myEcPaXpN5UnC0/HJs08rBwUO0tVsn6v6gvLqBz+kLedZ9alf4ThfET6zZZyUecsLfrnM9SHhpdK1+oPfVhlU5dN5wqefGP3U8rD/zPf/f7n3fa7PQzkqzXxQnrku6iN7pV1pxm+rLqacPCzzdu1niUyr31Z6OGCoB8jvLR8w1OV95hqdL9+qI6tn/gpDuWn5ZY7jBYR+hE8tFba2p04yS2hJGeDaCUfpYDwW+cSTRHea7/3fhb/9wQcfLHFC+Y0w2r6v8sEHH/wU8FMAn/6hJz548/PAnwF+AbgNvA1MaDOb0KD6Cg0S34F/ex/+LHCXNskrwEUacN6kLeingFVgnQawBeB54Baw0v9fBF4oz6708W3SgLkAbPR27f4BcIfG6FTMp/tQZ4FP9+/v9LrngM+SRVvtU7pHFPjn+7dvAEvAc73uPvBa//ZiH+9c/70N3Cz9HzJUtmaAl/uze73duf7NLHCjz3kTeLF/d5MI+pd6vZ0Og+3ez6P+bL6391z/PU2z1tf6WIXjVeBa//sRbSmF/WYf3+UOl9sMFbXLwHXa+tzv41kCPkaUA/r4lvvfs30+lfgeAe+W95M+35c6jFfJWs6XfujjW+9zvkvzSiz1Oe7T1lnhQ293u4/xcp/TDsGFmT6++T6ulf7zMk1J6UTL+0R4LZafN/r4nd9hH880sNX7d24XaTgr07Q4HtdnsX+/AbzT60z35xdp67fc+73e25pPc0z6nG8V+NHn81ypt9nrLhMGKe44Fwg97NNwd5MwtRdp63G3/y/+L/UfcfiFPvdJf64BrWK4139vEOXupV53v3+32fs4T1vLkwxMYabB8nKBiTzgcwSPpM8lgnMbvf79DrNPdViu0/iOsF7tz+Zo/Ol6GcdqHzdEmG6OYLPUn9m/RdpUKO/QcGmaxs8g/OGgj6nS3k7/mQMu0dZqn4YTSzReI3+6TxxTt3vfCrWpMgf5inM/pPGWaeApGs3c63+rvGt4XqEJ2uU+rn3CO6/2cU36OBdo8F4Bvgv8lt7GTdqaXwW+09uB8DPhfamMc7nD59nevrJHnqYz73ofD6XeVRqevdvhI+0edvjt9HpXyrc7fRw6gSYEL1Zoa0Ov/wniVHOcOhmepPErYSZ/E57zvb01Gn5WJ8IBjdbOE3qpClM15KRvZcUKjZ6dz2afj87LVwifWyU0MtvHd5kG+40C26f7WG73Z4dkjWb699+l8ZjLNNoVf1/o8H2LyMjdvg7rfRwX+v86JKusugB8mxiCzlXF7SnCx6WRzT6mSZ/vDE390Xh9uY99hcjcNdravEgUxBWi5F7uY3du14kcv9T72OnjEFe2iGy+QviyPKvqFxv92xcJfT3sc9rsbSz0th92eDv2pT7e1/vfi71viFxZILLwtLLZx6HzZJdGQzdovFMav0ajx5N4dy13aTijHN9hSLv0+S8Smamcc97y9Nv998doclyeO9Pn5rz99g4xWMTjPdo6yKeVL8q7WtZo6/R8b2eZhgOX+zx2OzykGZ3w0uscMXiWCe7qsJsQPeBmb1P9Z4/I160+r2tEpm3ScO4TZdzqKsJ7lrZGY53tzT62T5VnN/v31wj9vd7fP9P726HJ8qqjQHSYbRqeKD/liUsdPrXcpa3PC8Qhu0WDt7rQhODuIxrO36StxWwf6wLD8lb/7rN9PO/0eS4Bf6p1eWL5jTDa7tJw2vKx/uz08oO9xu8F/nXgfzkHf3WvScq/QJuR3GvSfm787Yagej2v04A936vM0xigyKjRY8jvgIZcT/Vneglu9PezNESTCOd6vR1CgHvEM3+u92u9OwQxZ/vQZQYagirwCzTmt9DrP13GuUtDjpk+lqdohPRUf75b5qdBVI22T/dnq0TYH3b4aJSt9Xp6UjXaXiYIudrrnevvtwlj/mGi9F/o/V4hAuA52lo5XoXoUm/zgLZ+C8TAUMBfJ4JJBnOVRuCVea0SJWSepniNIwl6s+Z6W/t97NWomSUGpQb8IY2gN3v7N/oYrhBD3R96uzLQZ/qzbYILwt6I7Ln++0UaDs/QhGiNjqhwXyaMcJZ4OK8Q5V/F7MX+fNLbkmkcEsa11sep0bfS36loLPU2ni/tf4qsvUUBqhIss1xiGGZfJ4K2wrs6HaaJorJDo6W1/vdCh90iUWylvyu0dZEOXimwukpwWfhMCP1IMy/2ugrhO0TZv87Jgn+VCPjzxMi5159N+rMDsuYQoTPb+9kggl+edK7DQlireC7SaOjFMg6zCCiwdB2uF/is93eVSa91mMzTjMxtwnd+S6+z28e+y5CfiTPbNPp/msD2Xu/3JaLwbZY5QJQGlZJdopAuMsRb+e21DhsF4ixDL63KtriuYnGhv9vsY3vQ+3iF0NMPk8jSjdLWdm/7WZoAnyNGwlwfm3Lkld7+AjEobVOFQmVMJffZDouDPkcVrkMazU16vRvl2y0aDj3Zv9mk0cQLRG4p+14mBshhH4s0vtj711B4ps9Lg2uReMJV0Oht7dLwW1myQAwDCF/WaKW/u9D7ku9Bo6WpDutZhnxcvi28dAYs0OjHuX2CKJsPiVNwobQhTK8SXrANfBL4OHFAvNyfPyD8fYkYKq45NDz03X2i+DrfeRodLpV6ux1mzkuZPOljf0ToQNlxkeDJy70f+Y+Oluu9LWX1i/33XIfFbP//KYIrGr4XC1xnaLJPOIo34qcq2Q5xkM0So/8Fkomy2Nu81se5QcMxdRn51SIxLqoMHxcdCBrQE5qceqm/l58+y9DJdFpZ6W25zhPCkyw6SJWZ8ledJ1fLs/ne95M09faIOBuuEhqeMIzEqIdNaOtwhRiPs6O6lgv9+Q+Xd9doeLDF0OFzrfSxTvQd+ZnzhEbHU8Sp9Hx/vklbt30arutwWqet2/PEEbDWn71U5lGdAc5JfdNyQMPRRYZ6u/zxeRL90jn1Qu9vm+gJlkPCW9TPlJ86O3TI1bLc+/jhDg8K3DTk7pFgygGNX4j3C72vSwyLtsTLJCig/vGnOL38RhhtbwA3nnjiib+Thqu/E/jdj/1CST4B/ijwH+3BT9Aw9g8B/x7NLL3L91xS2yT6IzM7ogFum0Z8MsNtwljXSlf05/WZBtn9MrwJbQHWCGO6T5QCCbvW2yj19vvQJSbHPSGpAfdoi7ZNE/Jrva7Ea/iaXu9RGXP1MqsYHRIhetTb99vNEXwmxHhyDvQxz/Y56A2cKvUkIBFuuvdjRA6yThqqesVUnGXWGgTCRCVeAnMdJdi5Uo/e76T//7DPZ2y06c1TAXvU297v/58naZquLSRSOekw2CYpYHvEgKpKikJpqsBYXKjMcr+8V2hWWFDa1SCvuONzPU7CaL+3oUBXabBMiKIiDGR+rrMMVsbjGmzQmNK4PXFYwW5ZK39X3BdmKnXi7zTBPeG7RaJkd8szcad66ISB9KoiM0NSS1Wed0kg/5Awf3Fiq/89xrdaKu7NEpz2ewWmbK4qrgos4aJhUGnzLoG1dGgqWIWtdA1RsCblnfxjg+OlGtLyOOdUedE2J/OznV5fh49K7Vaf5xrhTRPaerm2EyLgztHWxHZ3y9ylQ+m08myNthoZks4fkDScRzQlSvwRHyq8jY6J6yq4FZZrfSzOd57QiO25nlVR2SdRG2lkmxgi82U+wpEOb3n3fPl20r83dU7cX2Qo5w6JYV75n2uoQ8E1ni3Pp3vfFc/FpcrHxeM94gizDeevk0kDc9LblSaUHxMiv2xns7yzvga/+LvX/5dPK2+miYPGNuTP/u9YrKNBtcMw8gyJkom308T5VnHF4trPEf6jkem87hNHibKi6gbStzLjkIYXB4TPTXpf4uhmaVf9Qj7lGBfLGEx1Fp+nyPrIUw56m/IG+agGvGMQ54SJcxafjJhC/PLO2d+PM9o0yjRuhVGl5Ul59mFG21j/kPbqGMQlYVLpVCdd1UHVe5zfOSLj9su3m2V8Rmoe9G99rtF2khy6R6I/8i7rTgieTTOM+Mu7q/Nyi9D9QWlvhvC4LaIL7pS+lF/Oe0JwrtKyOOo4NfjGOtuE8FOfqc+vkwwD9fWqX4jztUgPk17XjDCdtOc4DlvnsU7kq7hn1ot8WXmyS/jF/uhbi/SqI9u/P6z8uhttH3zwwa888cQT/zjwM7Qx//sffPDBf/PYj9Sy79Ggtk2Ld+ryeRX4bcB/xvdc0qu0n3tE8dsijH6WhjgaUBLhTP9OBrhHA/YdhoSzSQO8BDVDC3eq7N3tw9ZYmSKC6iaJYojQN0vbawwJ9TyJCCp8RF4JS2NERleZcTVyjhgKxttEgdRb+D7Zu7dKomYSh98buq6Ks/3slJ8azVzvsJEhaShJbDU9UgZAb0dmexJzFWYT4vGvaQsSkIqfXkJLJXwF1hHxIspQNG4U3BBl0TWbKn/vF3hWBWjS/54w9ALLeG/130ZBN4H3CD5vMEytsr/FAgsNRwjOqLQd9vbEcw0E56OAVZgsEEYqvk0RGjjo41RYz5X2IGuzQVIWfV7XQYYqg1RBUQk86r81klRQFPqzNLzcIGui08Ix3Olz0nN4v/RRlYJ92tqrANFhZl/C3LlK6+OySZwi52m07txl1jcJHklfdV2qkrHb6xt9u0kMF/nZPDFaKe+qsXxE6E+arYbhdqkrbeq0EJZTNFw96u/XGKaoOH8F/zxxaEkH1ZA8Il7NeRrtaNipUMgj5js8q9EmTdwndHPAcUWmGvgquvskQuH89vvvm0SemKKtoa2DqyoA8hMVWMd5p4xHRa46QMQ9FSAYGi7KLzM3qqDX2Dso34pj8h/ndUh4u/WE7UOi7PuNzglhpsFdjeA1gs/C2m9u9TErgxdKHXF0evT3ev+5xTA9UmVrpr8by80JoUd5gniwX57dIbikk6muyzJxWIq/K8RYmyVOhD3i7JgQPqLcg8jJk5RF+b5ycIHQyHaZ160+RtfniKScO6Y54hhaIPuq1wi+aNS+T/aO7fZ579HwRfktrhgdlN/rCKnOCR2Hyr7bDA3YPWKwTBjyDccuf9ggxpZ4qkNW/vY4Q0tnxz6RadZfLTBVzjyuLYhMUV5pYNbvqkNygWF6ZNWxVon8ujua34RkjfitWyFU8sVl+aVjmGWo91hU/G1TWeAa7zPEswMa7NUnlbcHRH4q56cZ6l2rJLKqgbJLeJbtKxd0uMoDKW3eJRkTrpNFfi8/gfDdaRK5nCKpfDphdgjd1HKnwGC1PFePE29rURfTkQHBPUhgQxng2imrxJHxWOQ7N4kMkCc9rvyG7Gn74IMP/jLwl7/vDy7QDLP3aPkJTxP36AbwLVp89c//H4H/GL6wzqs/1wC3TPJhr9C8qAL3i7TccIXwZVr+6Gu0vHND8J8vz57tQ1ohaQzLvb3fRvYBfZuk1ujp3+p9f5WGEG8Tr+lPkvSbd2lIttK/fbJPXybwDG0PDAy9PU+TFJ+nSSqKXg4J8aB889Xe5wot7LsIfLN/92laAPMO8CUa4X2LMKWvEANnmTAWCXKxj+VzBQ7v9Pl9rLdhLvAniVA5pIWKnyKC9Ub/7hcYGqHP0cLcv0DSja729iqRL5O85oU+n2pU7ANfL+/Xe79f7vN+m0Q9nNe1Xv+AxgA2abhk2qNo+jbDfVy7vf1P9nl9k6FXaY6Gm4t9XG/R8OkrJM1xucNDYX+5/zzFcJ+lRvrV/p0e/D3gH+xjVJFa7OPTiN+k4emnaHhlLnwVDJdJetvrNLw17aC2t0lb3/kOOxnUU8BnGHpe18m+U8fle5W6L5BUvRUankx63S/2cd6k4ZH4f7Wvyzdpa/YFYkheI7i8T1uj+zT6+i6hma/0dmQ9KySt5wYnC8xlItzmexvC5G0a/H+Shm+3CX1dJ3iz0mHrHq0v0XjSbVrSgbB+qz+7QFszU04Oe19GqVT4Vkm61DN9bjovrpZv3aNrSqrrOUuO/t3tsH0IfI0h7WkMXujt3qet3Xr//zOEPxnNuAD8ItmTNUOcX9B49WKZ+wGNv8zQ1uL1DrdPEOVZZeP5Po/XiJK0RMOX5wusJzQ58CUaTn6nz3emz/VGr/8zRPEyrUZ4XyUpRq93OH6Ohj86vnQmaSS+QlICNVxe6PD/JqH5CcOdATfJXix6H++S/T8bJBXyjQ4fev1XiBPmF0mU6HL/5vkO+9do+HKVGJiLNNx7l+whhLbGD2k0OUfSiS8yjLRNEyUW4tx8s8PeVPSVvgZjuUnvX8V6oX9j+tl3iSPquf5eWfaIxgcvEsfoWzSZew34BuGHX6St+SINJ3+EOJpu93EsESNvkSij1/qYfpqsm+Vch88Nsk9JhVqeuEnDvfPAf0mU5K/S1vdt4A8Az/0++Hf/dFvDLxHl+y3ipLlBo7mv93Y/TfSlKySiK29/gzgExIWFPu5bxIBQv7hN+JRKclWGxamX+rq8QWj5Oom+XOV4euRFGp1eYSjDx2WFGNnS1Qs0PH+tt3mPJoc/x/G9aTDk5bcI7UEcfdWQOCIppZcZ7nG6Q+Ox8zQ+MEeD47vEGT5LW/vrhIa3aGsrHulk2qbh97VeTwef8q6Wd2hr8mpv4/Xexw1iPK2RPX/KwPf7HEy53e+wEz6XiAPrWofltwjuaOQ8QxxOT9P44zKN1u70uqaoTpc2XyOZcj/C0LDR+bJIo0touPcNGl5+kuCo/OhF4tj8CsOUxMMOF2XbyyTtckLjRc9wfBvEzQ7fL5CU1lWaufLDJP11ofcnLn6T6Pcvlm8tP93H+Tv6eOZo96Rdp+0KO63893YQyaA8oM3QEwcukLwLOQHA6h9vUP5P4dmLjbm/z3AD5CzZRLxLvNWQDa+3+/M5GrI+oC3ASulqgyhrKsh6QSYMlRwRcZcQvIihx3CBeBlUQDeJN0MEfZtEnOhgeKfXq/tr6lwkYBX4ypAMx28Sj/2t3peGo9EZlUoVWIhHc5NEmfT+6FnYIWHq93u7q/17lbnvMkxXWaAt82b//2b/9hYh6iOSvnerw2y+t63BK0w1qPRsqGxYDnofRx1+kzJPvSwzJNImbgjXdRqeqOjdIgS6SjxFtjchCtUt4pmyDz2ZGtR3OjwXifFVI22LxJj8NsP0SD1SpgkoWM+TQyHOkejqEcMoskqQXlXxzdThxQJz11Pj06K39DbDVMIaTYVEiF0/4e16W/bIOm4Qj6qerLskxdS+LpKDSMRR5+nhDipCegj3SfSLXmeJRncThpG2mwz3TVnulXfnyvMJ4QE/TdZJr7UwOEci2RNizL9H0kSF9R2SkrHAMD1SngSJaqnEbdDwcIlEV6sQ2SQ4uUf2tY1pSKOz0p4Rz13a+twmiofKzAbhTxOixC4TBV0+6hxsz7kfkYj4TXKI0gbHPenLBYau80KB2YREsuS/0qFjuUmDtQ4UHWg6O4T3EvCPA1/+LLz2raaIqOhvMFRUDkg04kJv7z5tnTWSbxJDSQP2HokA3Snf7jCMCk3KHIUPva0N4sVfJvxPWbhSYHaHRk/V4+7e0tU+PqMuGkazJE1IHgAx2moKtDxOo9L5bBJvuEqq7Sg3d4ijY5kYIPtkHWfLHI/IIR4z/fuV/nyJxu/2SETjNk0Oz5CMmxppWyh9ybvo/S0SY15+5vvZPudFshdL5XzCMGX8bRIllP7v9OcX/3Tmtk+iTKsER++RKL0q1G5/vkrk+iLBZaPtCwQnpolBJU/R8aKRt1PgYbRRY0AnovCfK/B+p7+/SHiSc9UJMjZOalF2qbvs0WhJZ8mEOI+2OZl317LOUJ/a47iTTsfjvT6+86XuJjkDYbm3s0JSpQ9JFpCON79dLf1U+aReA5Evlfda3ifp5NO9/ztk/fdovPgSDe72sU30uFnCG5SHCyQ98g5Nj7tNaEi4r5LspPd6vZqdtMowimlEbLnMaYvj8uYtkuruM/mjsnG616O3IT3JtyzygR2SWXC3v3vYx7xMM8prWSeRyxpp2yC2wYTgrnR5s4zhbvnWYuBnobd3sz8fG3fj8pEw2lZ/Gb76txpSPHs7yvAu2RdyBPz4X4KdvwSv/zPwxj8MP/OnfjP8gb+ZfKEl4AD+wE81QD9X+pgmJ9ntkXzjpf7MVEc9fkaDFFzzNK+HDLAybRUGhcmzJN1QJnyDIUK6gCq218niXi5j36Uh0zmyuddxm/8v4srkVQrP0bzQMn49bDvk1MejUm+fKP30Mc+SkL8MTKGrEnSDELfvRbwZWtTtOYZKw2Kv82Tv72qvv8UwjH61w9MxzNOISnjK6OaJZ2y29zdmABNitMmgbpAwv2u50P+uuDBTvr9Cop4KzapcuO56q3dJHvVMeSeOqMh9nGzynyWpSRoSl8i6W0dherk826fh88c7rCYFds5nQk7xu07DKw1eFc0ZYgg9N5rXPMcPNpknqT86Ly4SXD6krfcWQ6WsMjOFxQ0S9VEhfdC//wRRGo0wzJCo4E4fq/S6TSKYVcFQmKlIUmCmMlXx4RlOTrFRaRT3PtGfV0PoE0R5lb6uMnQSGHkUZm7+l74qjPTqVdjC8VREafZqgY8GlPgNoUOVuQmBq33ojNgn9Hc4+uZJgnMPe50rBH8OGcJ1j+CddL/fx/dxhgfeOEd5mUbHVcKfnPM1okRqUC4ST7/G+A7hYUe9/nViAF2jrbvOiqn+vzDZ62P5JvDGt5ryJM/SKSefcm57NHzQCyzuyG8nxCPvXo0b5Fjr6+VbZaNOFx168nbxVZzSgJUOdHYIF8d3hZwyN93fHxEj1XZtz7HLFxYZ8kPx0DXTWbFDDueAOGUm/f2Yj8/R1kFxb2RDw9v1mycpsgckKjJDIkNmS0wIb36GnHSsLJ8wTHe82Of9kBg2UySat0lkBWXus719eXl1dGjkXic8WDpQVii7Fkha4w2S0viIRLDEUeXOdeKQ1rDYJrxdHeGAxlOFoY41aVf94ojsXqnOMQ2dSzQcuEFkvrhxlWFEzvHISxaJfvA4o+1JEr1WX3TeOv3OEXo8iXfXIu3peHPNq5F0QCJlRqesO0cOw3Ndr/f350pbF2n0JQ1PiHMEAq8JOfDMb+WTY7j47Y3SxhVy6IvOqcskgn5AVOcFQkO7hNcuEtx9isBW3JGXGBWt8kt9YKrXdQ2khw2iB8wTHmI5II7Z58qzSYenODpNggTXyjhOkpsHZD/eVYZ6tjC7yrCc699VvquO5Ji3CO4e0Hi1+qhzWxy16/7sG8Qx/XGGcvmk8pEw2g4YbkqWCPV2y6DWCMK88R/Ay3f+JvxT/eW3+N5RNaY6rBLDZorGbFZLXyLmKtkIqGU+6b9NPXDfk+Fgo0YqJlNEwXR/nJ7zWeIhPiTRmgkRZOu0BZTprvX+VfhlGo+IwHUe54gXV8YKiZQckUMpVDBVljcCtsEmVIgHd4fhkf8KCQ2ONUIc1rMoYBUSGjmmsmyW8daN7vbjODfJ5myV42q0rZM1q/C2CK8K00fEg7JNImEyXBWWQ3JAx4TgyH5pVwWXAkfrOfZdoqwYLam4f7fUWWdowB4xPFJ5UvpTOVMh0dNzl+CLjBGGexKNZOrJOmkNjvq3vnPs4/Ycl8q/71ZJERaOf4asaY20iXv7BEc1rtfKs0cE/w+JF1h+oTGh4V3xVjryPQVm+wwPM1CAjz2vENybJvuODvv3GqjS4SYx2lyz2dKGHtlVQkuVvuRnzkGlUb6y3+u5bir98h4VO//222pgqoA5pzUi8ITHGscjbQ9I+rOwlWcsEv40IZG2TeJ4ErbO4S7DkyWlFddafKu8QOXHdjaJQDYypJCdkGiHODVhuJlf3r5JcEB+VuE9W+YjX1EOOS8NdnFEA9t6KhvyE505Gum75Z3fTsocp4lRPceQF0sP8iyjKr7bJ7TomF0v2xU+MFQwhZ9jl7eIH0ejvyH7UCYMD2XZKG3McLrctL70s8Fwv6ByTgOD0qZtrBOadMwqY66HPGSX4f7QsdFmcY1cN4uK7yxxEIt74rFjqnz8kPDbDYbpy66p8rTiaJWbOwwPIoE4wcQtcUW+4FhVrg8YHnQ26e0IH/FA/UwDv8o4ZT6Ev7i2NdKm4eBanlbEFQ2QXZI1Il+ZkKwnOJ4eWZ+tE5qfJjhc11d6UGZWo01dptLBDNEFj2g6nvrV3uhbx1Ln43OI3nOS0Vb1OPHXcYtrjsE1dF10BJwjB9w5T8cq3khr4plrpXNZvJ1nKNMoY5MX6AibIfuGx0ab8ma1PzsiMkXnu7xaOEhPawwjbTCktYoXFdbihvCTNirP3izfa+z7+4jhQSQazMLMPrZo8llZMaHxxIqbJ5WPhNE2R46dfYFm0eshFTiHtLzkCQ0gz0MzUf8oLXH6j/fGNuCVK01JeJWWTrBAA94SLW/2HMN9Va8ST4+W9zzH97R9roxJRNN7J8LO9/ZWCfHO0fZniJBvk7CqHudX+u/7NEv/s73uDomsXCb3vFwmm5U1BBRQVaB9jqTgXe3fav2/0v+/0+vtj753zBMS5peQt4hH9TPEs3qTYZRqrcP0kwTpHxXYuun1Oi0FSUYtwdyg5Q3TYfYkLXL3PENDaaX/dm4V3hBjkf5eQfQZwnwVVBfI0cSQlAHX8rk+hqeJp95v7Wu9j9G7SaqCOdv7vUCitYdkn8ssLQVhnuGetiVCGxulvwOO72nb7+1dJUqxir9CUqbzAvFqLhNhNdOfP03LyZ7r7b9E1t72NhkekqAwk+ZUqNfIxnZhscgwdQra+s33sawy3NP2ObL37iLxqH6M7NM6IPxik+aBNXoifCbEQ2rfwkwlaIXs0bvB6XvaVJrnaGsLWaOtPhbxSPqqUYIVspn8MuFJ8g5hrUd0kewZEbY1he+wwBuaB0/4aFReZbguKqETIqRmCC9SYO32Z5X2zIhYJDi3S/a0vULSmDQ8vB5EwSc9Owf5k3M/oKX2zBIv6xzHo+7TJMqqwbFDMhWeI6ktO0RWSB+fKXC50dtSgYBG158kd2ldJRHB+f7sM739ZeJUUGbs0PYYXe7tbZC9sioZMyQKdEhb5wk5mt9vN0vf5/r/4sUi4YtLDO8ZhaRNC5dnycXt7n88YBiNUw659irsnyN4vMiH72mbJelArzDc0zZLlLmT5OYmkTF601eIAukzI5sH5LobeT+0PS3PEH641eH2HDE4XiEK1ZMFljooFokSer3DRqO4Kn/V4/4Ux/e0bdL44o8Qx4lOqleITFqg6S03abT0KnHM6fSl9+N+nU2CP++RqMgWOYp9geGetmdJlOUWMSA1jOf6HD5L9gYbXVggOPUicWwvkqwi5Y93mcqT5gmuOc7Tyio5pn+/j+F5cv2E/PQFwsPGRlvl5W4NkZeodFfeckD2tC0xPExohdzHJe9+lmz90ChdouGdNGx2injifCbkeiHlzhzHD+ygt3mb8K4ZGpyFtXh2lWFEXceYUcN9oh9DMnDk495/u8nwyP+PkcNyLpM9bZvl2aeJ80q+D9EDTtrTNqHhwhcI/h32718o8NCh8ilyANNnyBYXGAYt1voYX+7vdvoYrnE8o+Y20dmW+rO1Pr9PEaeHcBQXdVYtEHypZZ9G858lToCXaevzU5xePhJG2wFDa1Yvg8xPD8EqOX7+3wRe/qluHP0cPPOvwf+sn3rwT36Nttpvw5e2c3HhNm0j4gY5NhtySav50BAkeETyX1eJh0gPTzUy9GisMDyWfJdcwAw5TUjBdEC8AlskFxpisZ8jioQRJ7cA6m3QaNODeq6P+YgcJbpN7pRQUdwkF8VW76T7OyalnmOo3v41hl756h2qSoUGhZ5BvSsyCOGid5s+zgsEPx4SAViZqf0a8VT4W5ybKSb+vcbQCFJgzhP8UKl1ze7250a+qgHu881eb6qMXc/bbIf3AsH9++T0olmCPyp7h0Qp0Yuoo0EmNkNw9WFv74DHp0dukIteXT+FlWsAWT8Z3nwfw+8AfvN5+BcfxlN5wDBN7075W5y9X+a6z3Fh6p6KndLvg972KunrkCjFkKj1EvD75+AX9tqdJwrM6hWWXm3nqMBM3rNB8OEkDydlLFO97mp/rsNpQu4RXGcYaTMlUvxV6bpDomp3ynNh4RwWCU3e5Xh6pDTr2ldeoDJtuypjlcfNEMeKuLpP+Jm0sUOi1UfkgAr7X+F4euSE4IPwremR75Nop3NaJ3RdZUaldWlGmp8QY+GACO4tgg/ywm3aWqmYyGfq2txlyM+OiDHt+q4SRVyccUzyveq13SDR643e/xExYO+QI8DnyrdbJNKp41C8EFeEnYaNDgnpTt4iLbruyhINX+EDSfdSTq8SRVljZBxp05kiLGxvjayPdDDpfYzlpuuwV9qZJydeylPmSSRUnqJiNubjGu/ikms/S/bA6KwVlrtk2700ZAT0Hm2talSxetyNtu6Q6JD4qMx1fZRRE7LOOyRzZoVhpoNRiHWi10wIjW4RR6ARsUVi4LjmpqG6TtVoqw4MnWlG0RyHdd33uUmc3OKTus5R+UZ63CEG1Gllnez1VGfcIPt+lTMbHRZjZ9u4iF/yEmmv6iMHJINJuWBd+ar4OE9owvnNljbE4QnDo/11NEwYGjGu20lGm3SjIbTB0PhUx7HYh+PUeblPcMt600QXWSA3b/le3iOfPCT7atXXIXcX1/RIec08wX3LAaED8fyI8EedZI5POPwR4Ol/kLbRba80eAiv3g9OvABc1qrbhc8/bI6y+WrpAf/tdnN2vDzF9zyIj7Ybz/vNMw1wj+7DOd8/gg9+qRljGtq/uXxreWG7rc3fNwe7e80B8wrwgxfhH9rm1PKRMNr03u3QvCs10laVuWs0RP4uOfb7PeJt/fY9+NhfgN/6DwH/KPA//6f4TT/7R/lN/2pv6CZs34mX9VLv6zpRsvV+7JFo0D7JTxYJKxOaKT96kqYY7rG6ztA7qZE3S/K8F9oQuUJyoXfJHgI9dItkj84qx402BaCeAxX7a4ToHOeERhzX+nfvl3aMBGyVNs6V9hf6WK7RDKtphjnOEI++89/rzy52WJuGo/dHIe26P93fyRCf7G17WlFlxOvEoLvOcaNttbRBmfcDkvZoBGCR5DYrgDToniaRNgWVoXoIn3DeKgIabK6LkbYJDR/1OsrY3XMmfSzRcOA2EQCO7zIRgCr0RlZOi7RprFzt7arAvcfxSNt14sgQVxf73L/7MJdwrzGMtElf9ut87hZYLDIUitME93bKc72110h6ox79GmkzQvTdveCi+GKaqnBXcTLSZht7ZH/NBRrOVBoel2XCoK+TNBl5gGPWIKSMyeiKuHy5t7FBw81nCL93vItkTwkMU46F1yExEC/3uV0jxtbV0ucUw0jbLLk2xAvi94mycr20A1HwFsmelZ3+Xn52QBTCc338G/1ZNYpd849xPNK2R7zIkz4mPfLi73R/v0dwYafD4EKfj3go/tneZoHRahm7CgeEHlwL6WGBGE3XCB2rqMyQlP+rRNbMlW9UdmYZnh7p+PZG3y4QY0CF7uIIPhCcEkd0RtRIm+83yF4ax3+RpBUtETqwvWskVVD+aR1pV6NN3qWCaF+WCUknlEYgcnO6z/tygZlKcF0PDbkjkqGiIm2/14iRDuHZy4SWdbjJ15eIU8K+pwn/Xia0Uelrnlwm7druMXSQOd9bRLG+2mGqnLlE5Oh1EmnT2TZN8Ha1j0Wa3Ot9zxG5Iq5AIm1XiUNInlWNtt3+rbxpp8NEY0uceoY4bxb7zzMkYigs4FcfaZsiBrBOh8o7bdNnH2a0aWTaZ3W2TJc6S+RybGXqpP8W9zYJ/siTj8jhYJWGxS/xwPnMENkFj4+06bC41v/fJLi8QHiqz9QRNMQWyZaQejCXkbb6rfrMFXL4XuXBynzp/BHBFR2s8nodbsJqrLOp79qeTtsZQvvTJIp1FXi6hzg/+EvDe88OaSdEatzuAi9342iHdsLpNeCZ7eORtneAmSNY6vXX6NdFHcDC/R5pO4KL29GBf7HAd698a/mrHdZX9to4v9nncv0xBht8RIy2X6YB5i6xwEXCCckTfYMGjDtEUCmU98kpL7/1z9Ag+uYfbWeF/jngd8Iv32kne90kXoAJSdXQSwHxlukFnaVF6fR06bWcJ6f67NCI0mjeKlG8XyeMeYVh/rrKq9EvCQxiyGjkGSVb63+vMNzPMY60vUG8E3qODfcekBC2BsR3Sf76m73eA45H2iYM98cJB08Ym/QxbBKPcfUeKthlEJvl28qQVPQ8DWqOpKbUesJCI3nhhHbe63/PkujtG8STM0u8PsLYokdxnZzK93751nWkP9PQ3Sxj32GoKM6RNVijpf9otK6TE6X0JC3SmOgy8URrTO+QNAGF/dsM7zyqDHGHKKkHxHCShmSsRjp2Ca5QYPRa/39CvObz5FQtDT3LZqmnklnxyiJN7JPj2XfJqaNrNPjrqRNG6zR4PwL+tf7NhHjn9MrukxSk9dK3MNsnHjkVYr2N43KPRPPlE5CojQLhgHithZk4d4+cfGWK0U1yPYKG3QoxjBdKW75TSdcIdb0ekstXfVYFmrQ5yzA1fab3r8Bc7vUqP6vRFaPYKtAqJPImeYeK923CQ8Q5eYSRJ+d+RAT2Zh+La1UVK2G73+vUKIBGzoTg9Xx/Lh2+QcMV5zqhKdF6lw/7d8JbvjpHUqymSYRjbLTtkhNhHau8ZJacYLc5gt2DXm+XoRG/wjBNaKHM/V6vp4NGZc2xT5dvdvqz2+QOUCNtC+SI9UmBte29QYyheYaOmBpxqn+vkXTK1f78Hk0Gyc/e5Ljc3CaRoAmJTjoWnaGuxSG5jmeWrMvb5G4k+eHbvd1lhk64HRKZ2yKKtYaqML5Y2jPCCDFC5WeLpY1Nsr/lrT5vI9MH/ZnwV7atkr3G4uN7DPcaHRLZA0lXVh7sECfDMsmSWGSYXbBGdArHZDsVb+SnG71P+ZPtSyMbJF1vn6RKquQv0JxkY11gXOT3yjuNo0NyV+4WJxs5JxVlrgb8A45nV0iH6jAVRzYI/t8kd+GtEj1Ix9YWoeE9ortQ5qMBrNxxLOc4Lofu0PBKfBQHN2lroeG8TbaG2LYw18C6RehUZ7y8aKfPTUe36/6AyEjrrhMdQ95ZnRjbDHWnk2Atb1MGKIOUE+LoSvnu/7MHf9+favJ/dQQn6WGTxrO8Bkq+d5njp0eu0eArHUJw7wbRJ4WjuOiVTfPEeK7lTbIPcZNclzXuf1w+EkbbBwyF+kH5W2XK9/X5UflRuT8EfvkIfnCTxoF/moZBfwF+8Gvw1B+MYikyaHT4Q3nub3/sizKWqdGYxn/PkAMTGL2bHj2rP7UP61jvoDznhLoVlvXb+jPub9z3IYm6jcd00rjGY7TuuI3T1tL1q8rXSTCta1DhNx7DuJ36fjzW+k3t53HzEz4VB8ZjPijfiAt+N0NwnfJNHcN4/Eej34zqjGEsc4Yh/h1wfA3Gcx33Ox5nHV9t518AftsUfPVomIZc642/gZP7FXfq92P+MFW+GcPnJFwbw5LR96fxmTG8LSo0j/t23H+dS13vw1FbY3o6jU9wQr3T+GddR8tJ+CBsH5U2Kq2eGz0/Cf/GsK74OF4Py2l4dhKNVljVchK/O40HngTT8TqcRJvj+Y5pvY73NLzglO+myvPKQ0/79sPmcdKcT8O1cV04PvYK55PWueKHhp9/Q9I/H4ff43ZOG89pc3vc89r+aTRqvQrj02AxPXp2Eo09jh9VHJo+4f0YR45G707ipeP1r/2OdZaT6o7/PwnuBxwfw1j+jJ+NYfw4+D4uOnYaTE6aj3B9XBnP22djPaLWPYnfPm48Myd8+4hhnyfRraU6N40u6TxQR9VBoNNLfnueHO//iGbIWc/vdVqPYXDSnMb4cxLvP4k/1qjlGBcrrB9xMpzHeMLo2T7AznHdoc7Duifx4LEsqeMf960ed9K8x/2eJKPG70+qNy4fCaNtnhx08ALN2q1eG6MBr5I9YlfJxtZZhpdr/6PAwt+CL/6tZrctAzwP/wrwT3/w78Hf/APwz9HcA5dot2u/TjN9H3e79k/wvUt1/tU/Dj/LyZdrf4FcGKsn4wvEK7NEvCIzfcyf611MOH659gbZmL7E8HLtA0JsGq4S6UyH2SHNUyDM9Jy6wflOr6enSm+9hyFM+NVdrr1A0l3u8P1frr3EMJXmkFyuPcWHX64NSSGo8HZOEsMC8SJ/rs+7Mj3nda3XPyCXa8/yq79cW6/5NmGSr5L7uLyv5UdIeuQtjh9EohfI9CadCIecfLn2j/Cru1x7hkQm9OxdJhewLvDhl2s/BP6fwJ8/iofpM2Q910i08nGXa7/a5/+A45drv0rSly4R/L/a10Uc/QKJsl1neBDJLidfrv0j/Nou1zZqMd/HB/G6bpEDA24T+rpO8GaF4eXan+/wWSC4As2T/yQnX659kWF65BG/Ppdrf6HX3+11H/ZnlfZMG//VXq59juHl2kYAoK3FYpn7AcPLtRdo0YXHXa5txGuH4eXaG8QTfLHD+wJtfT1kRf7zLMFxyOXawvsqSTFa6HD8HDlgZIZkYxi5e9zl2nA8PfLl/vdNjl+uvVhguUEu177A6Zdrm4Y1xfHLtcWXqySKean0cdLl2p8jd4kt8v0dRPJO//tzDA8iMVo7lpum0yoHrvD4y7WF9yMi+4wG0uFxrf8tP3yFHEQyz6/tcm0jufKyaSKXbvD4y7U/R6N753LQn3m59jxJH5THPaLRmx5/yOXa9Ha9XFu4qZvI2y8wPIjk+TK3W0R+ql/MEz61XeYyIamrF3vb+4TPL5KU021+4y7XPk/2vH2S8OSxAVb/d57ykm0SIbcc8f1drq2cf55f38u1a2r5j37wPPB3wT//51oY6DbD27VvkPPkRbSrDG/XXqMR0MXe+ENyu/YR/Odvt6bW+zheJPpMxXXTetcZHkSywcmXa8+QjB6DJicdRLJDLtfWcILjl2tv9+cv0i6m/ncetsu1nyvtHZLU1TUabtbLtec5/XJtdTYN5VU+/HJtjfQnOfly7f0On1eJ3vaZ3v+/w+nlI2G03Qd+jiFDriHiHWKR79Fwc4WEY1U2F4kwmOntGXoE+GPAv/2FP9Ck8tdoSaSbwH9M4/rvk5yhLbI5RwkiNU0aXn+bxhxExN1ebYekIpmKAMN0oklv9lxvY7P/frfPRWG73/sxnUYjdZEYU7Y/ttSnCLPdIgruMjEM1kgawQFJy4DsedglRocpLjvE0FEJM71ORQKSCvcdhscYL5A9IIc0hF4noW+J5v3+bJmkvSwyvAAakl4JQ7ywHBChqyF6yPDIb5m187pY4Crf2yQXgi6StFwVTvvaInb/CsOUzhmGB4msEaa+QNLlVC5mSMrIBRqOTBiu+wpRUFWOD0mqiykI1tcpskVjPgvkaHPhpHF/gQZvDScPCakCVYEtXTq2RYapCwr4VcK8K6NW0ZE29vsYN2ny5Dw5fGGD5LRP09bkItnzJyPcIbn58pW6F2Kz9KvS4neuk8L2pPRIYeZ8HhSY6KiA4JH0+TZZl01iXChYVshhCirzayRFep6cwOc7aVdeoDBbKfDx2cXyrbSpYi1uzBBHywHDS30r7ZlCNkfoQuF1qX/nmDSmTAffJum002UOst2aHnmX7GGQt68y5AXQdBj5mUqd7Nz0nh2SZi//EIbTfczv0dJobpJ1XKXRg3UXCY6s9nHeIQ43x+bc5DcqfBq8Nwl/nia0C7kk/F6v57c7ZF+IBu9cr3OHKPFPMly71QJnefHbBWY3e/8qtqaLrxOag+GhCZWvyU9gKI/q3/dI+nC9XHudGJRHpZ01og/Yx9uEfjQo3u1jUZbJB1V4H3TY3Kfh0S2Cv/s03+1Nsq9RA8q1nCfGoDIDssdJXKlGgcq/esoCOR1yq8xLGrxZxn5Q4K+Ce7fA65BsoxBf7vS+bvdnd8kBNIsEV+Tta+QanCcJLk6TgylqxGGTyG/5qD8ahzVdeJUYMxf7N++Q03nvE6NG3qYsPK1oaMvPH5J01xXCT6Xtk3h3LXWLhfocDPURZfQK0cUg/FIda4XG00y3n/Rvz/XvLhIa3iNqpw7HA3Ko1aUy9qqj/Ojlm7B7k9/+S0nBvNGF9yqw9O04B/ZpML7wi3GOS7fC/FyHowdPQRzH92k48R0aL3pAHAf7hF4m/fl3SJrkNtEDKj3cJ3cQS2tjA/k7DB0tyiCdCcLjrf5+jdCTvL22t0p0le3eBoR+LnLcuLpHDqlxzcQ9dekJgaMwcZzy9DoWGJ72PKHBdY+hXD6pfCSMNj0SczTPwhLDO6lU7D9DDDi9HHdoxPHx/t0c2dj+GdqiiCyfhGawvQ38eeCfIOc3/0naMXPX+6DWiHvx/d7Jq3xPEj/7NyLA9KJOyBHdek8VYvWI7JvE2j/Xv3m5t/WQ5pX4dK+7R/bFLRHBcJnc6SDiylAVxjMdBke9rysMj6N9kYY4d3u9fbLvgv5MhLxDhJaCRmH/MtnDcJuGoHqR1mme8OcYXq4tcaz18V3t8FLQSdzP0Lxaenec+w1iKNLHp/fXNahGxX5pUyXtgHifhYvKgB5J+viWyR6l6+Ty2T3iiXF992mErpdMGE6IkfIZ4py42cf2aXLR6Aohetf+EmG4KrQK0yvE2FN46s23XxnOEWFad2lro0FixMV+L9E8i8+TI7dfKDCyPQ2pI4bCzGiQCtgGQ2NUeIu/lleIn0SjVoPmM0QpWSR4cIUWWVT4fK7MU6/tpMBHxr5a+v50b0NjTuVaL9xJSsQdoujPkms2tvt3E3Lk/3dJFEzv5Cy5J2yzw8xIo/NVqb1JFIZF2loIW5VPCF6o3F0t8FEJe5qhQnxAnE4Thkf+H5Kju/fJyVgQQVg9+cLZyOFLhDdtkQN/VEDlYRqJEC+mc9fxMks79OHd3vc1ggMq+deJk2SHRuOXGF6urVIxzhYwMjxFkyuKBPdlyM9ukoNQXKsLfZwvMVQWnZt4Vz2vGug3CB8xojXpdV4ggv0T5dvtDhO/U0H6JPHww/D4dZ040rmRjU8UmF0ll2u7Vu8S58U5YizIa+ZoolKltCq6kGwQ//bAo1fIPo61Dldl3klyUzmwRFsfDRqdDdeJ4r9PnIKLxMCT314lCuQWbd2uk6jPi0T5V6G/RBThasB+rPdzSIyQqqTKQ5Tj8h8Vwk1yJZGK3yG5DugW2S94i4brnyUKvryG3s9LJANI/LlD9KTt/re4skFk8/Uyt2r8SsOr/Vt1sl1ieFan5ifJAUc6Hj9GIvFP93bkSc7PTIIqw8dljcirg973J2iZI/MFps+So92r4XY0+l/novi2U/53HR+RC8mFI+S+rask3XC+j8dD845IhsFVQsP3aetZHSHyCTN65CE6ZxagLf4+vPpfNHivkGjWHDk4RKfaOjnYZJ+2LneJLJklUVRpdpEY7ldoesAsDXee6m08IJeK3+3zep7cV7xOopPCUge/kbZZclWDRbxe7FM10it/fJbs4dPAfo6cQl7lJv37C2Rf3ws0+qbD+klyuXbFC53arxCDar3PT7tls8/fsyHMWJjq7T7LcWPsqH/3WaI7yZP+EqeXj4TR9iuEMeoFVrj4/JAcDnKfMLYJYcQaMNv9e5WgCQl3f+8c7W3aHW/P0oy3l/vf/zFxO9EbtZN1vmdJeoiJjHmKeMpUTLdHn8oMNEQVTI9IJGdCQvsQ4pVoIWlKKh0KXxW1Khg96GOrjHGLpPA5lnvk4l2/14PrN8JRBnlEFPFdsmF1UuY6IUSiUKg/jm9qBBPns1BgKXxNA6rM1H4hKVhVwRZXVDQmZK32iXF9nmQOWIT1pMxnhuRPC08Zju1v9nrVk6riskGOsPf9Zm9TA3Wb4eZcPZ0Tsu4+d0zOa58Iwh1yUA7lmYeMbJB9J+LhdPmRwbo+CoFxe85DOqR/u1HqOS9hoWJi0RN/j6QJCXu91/cYrrd44O8tYrA4Tz3d4pCMVWVD2tnsbXrKn/SwR6Lq4yIdThNa1pCdEEVGQ04FyPRQ+Zfwne71t8hhKLulrwkx/MawrTih8gjDKzL8ps5FJ4ZGk/jq2kPo5BHhZ5UP7fR3ZkTIv2cYHhs+IRF85ygPmy5z2CztOEcNvkpXPquCdp6h/FCIylPq2hwSQd99ckwTXD9P+L3jWiSH/qiQPyDrK8/aIjRk5HiXhsPyWcXRBpFfM4RfHxLRo7PMbydlHBptB4S32z/EoSNcdDRM0/BljvAu6Vf5pgNVPJcn7RGcF49VOmt0sf4Nw4NWlN2OUViLN2O5KQ1Pk+hN7VeFeYvIGfFKx439Tpc2fVadOxvl3aSPQ76vsSDene/vTLuufM25zxEZLQ/fLN8otx7QeJCwFf5GtTQK5St7RD5BtgCI51W/mCI4IH1XvkKHn9HOzfLcaKZ4YLvy09qH4zsgeKnjR5hu9XYnHS4PCX9WFp5WHHM12qSjSt86J0/i3Se1J5+sRpvlkBye5XpS5qIj0gikxrHrNVPaOCjfqvdOkXXfIel/vtO5tQDfO51Lo39CeJf6jLhcMyfUQeTneySLxbUSdzVsJ0SPVa+tTqhzJMCg/Npg6Kx2bPKCzdLuOY5f3aLOdsTwmprt0p7wmPT3lZaq3ITIX+l9u7Q7hk8tFbbKJnFsg6HRtkuMzQmh+/qtRflV6e8eH46nHwmjDY4rboejvw+PfXF8I9/h6J2K2KB+/QgatP4Mof4/3v/+HacM9Gj4b/Wm+f+oyrHxflgZz/+0OuN3Y1iNvUofNp7T+vp+3j/uXR3TsfU45f+TFPmj8u6k+bsWwmFq9O40+B+N/h6jyIfN7aS/x9/Z/zTHx2KfddynrdcYv06C50njOKnP08Y67rP2Xf8et3dSG0ecDHcFmHXGqSsVHqeNqfZR171+X/+u/49/P44+PgwPxvj9YfVOgtvjaGE8hsfR0HjOJ43Beo9bP8c5Nfpu3MdpYz4JxrWf74e2xv3Ub+uajvnDFMfHRvnmNNyq/UyPnlX6rW2d1MeHtT/+/zTedNIanTTWk9o/bS2+n3Ucj+G0/sZwP63v09aiwulxYx/zhjqm8bgeR+MfNu5xH6fR5rjv+s1JNF6/Oenv8Th1CJ5UTuPxj2vzceUkWjytj5PGX2H5Ybha/3+crKz1HpfSeNoajfHqcTA7bQwfVvc0vHocrlSZN26j8pY6lvE7edNhaeDD6G8sF0+CyVhGntbWh+Hwafhv+8rp+v2vlodZHqcHfRgOj/nOh/Hix/H08Vo9TjZ8P+XD6n0kjDYjLnoH9Ca5wXaXBoRVYhEfMtywrDdwtjwzpU+P2ibl4X2Gsf4VEm9/Efh54E/TTlXYIhsWuktLr58eYr3LM+RGdj2JfirhrROPlONeIxuJD0nqmZEckV1voREEozk10uZvx3JIPOSzJIoxSzzMqyTtzu/XiOe9em0PiXdtv4xdD4sRI4j3Qu/Po/7O+W/39vQOCxMNFz1XevSMMlaPDQz33J1jeCkrZW6Uvp2jx+HOEq/5fYapZvcKzI0YCgPhqUdMb7VRVI+r13M5S04w1QszYbgHsuLtFPFo6Q223ljYV3i+T6IMwtEiLLdJhE4a2S796lnVq+qG99P2tG0Rr7+wWCj1ton3zYiJcIHgjbinJ1pak1Y2yjOjLHoPjd6uEq+0HvH9Um+ftvZ6QSEXnAvvzTJXo5HjoncPGh6sFpjoHV8leFQFpOtSI7nuK/AaAOkL4uHbp6Vm/IlPws++2zYurzP05h0RT7bw2SNe3VpX2jQaVD3mq72tR2Tv0CpD2jNiqddWj+Okfztb5m0Eb57wFXmE0cqjPp+KZ4cMU7Q3yreVFzh3x+t6HvaxGcGaEJxSLGyTDfKbpT1pjjJW+YBe6nkSQVsgkRPHVnF0nniHJyTCYhaB6yAPUi7qifVb+zAKLF3PEN4OSX1174+RAmGpR1qYHRG561oJ76pEKqfXSCqe3v2x4Ts9+ttI0FqBbY2mzZArE2AoN8UvYeN8jPCdI9kj4oJt1uiL8xV/jVwpD9YI7xYfapTNCC4Etx1/LTVKYlTMdqw/IXxvi0TTlRXuHZevyOPUC8R14ausf0CiAMLJ4+gPiLxRduyX7917+KjM8YCcCix8Kj/dLmthqrr0YzRX2QOJnkCijI73cVEHdSxpe49El2pk0b1qHxbBEAbKLvs/ySkvHs2WulXH2ijt2K7z2yO80W8rn6gySvp0DFVHMTd0lehda72euFr1FNfFH/Vr5XnNArIIgwlDPWCntKNOdo7gtbrEDsHleSLnbXOzf6e+PjZqtzu87pRn6kUVR5VzRjZ3yD7KWtTjJiRSB9EbnFMtVS5M+jNxT/l9n8gA185xznJ87z4FPp4VYB/jiNy4fCSMtnO0PGdo+baXCCNQuB3Rcv5FgssMT9q6SnKgZbjPMiS6K5CjwPZI8v1zDHOgloG/D/hngeXfDP/I32yJrc/xvcvbnnq35emKiOfIXRXPkf1mGqI3CEJOEySbJhcLKhgvk0MsNYpmOlwu9npLRNmvRpsKO/35jf5snewDNGxvH45PAjzo31wnQmK29KNyt9Db+TjZ2+ccl8oYrtFyu03POSQnjCkknyZKhwoOtHX9BGGKc+T0pZoStUAYjGs/NtoUpCqCB33sjsk5LpDTsSBK56SM6XIfh8rOLMMjrmf7GJ8mhoNKg/CeJweG7Pf6F3sdcXuarL15/io2puMckovKa+rDdbJ3orZZjWbHeal/ryPENbjU2/hEgZH7HerGWpnYhOFJmhcJnkEMkV1yCM88Q4UOsmdxt78/V/72HbR8cVMalsiFnwc0OnSenni302GuYSKDtO/rva6KlQJtnuO57pYF4jAQ9zSYxDvpUCUGGm7MEgeKeCnMKh1q+MrLFmjw/sPvBl7TDFMJVbinyR7Mp8jdXfU+GGlTmE+II+JGr6MRsc+Qn80Rh8YCw83vs70fYaKiMEX2dFaFdqbMwb1Jzv2o1LlKjIcr5XufPdPHasrWPjkAwn0eKoYLZY4PySmhO/TLVhmmnl2j0QO0NVpieLz2IxrujY1RjbYdQusQRfHjRJn2El551g3i3LhWvhWW0tCkz0eakyeJU3UNhf0iufT4YX9/pc9LHHINDgiPOirtfJzcm7rA8BAJlT3nD+GD4pLzWSAOWeXXWG5KK5fIaX0LxFlwjextf9jbc41miSJ4nUYT8ohz5IRV5fYnGKYKw/CONffUTBGZsEXSIGG4H+kqORBIvJwnuOJ8dUgdMaT/MT08Rw5V0hCY6v08S+TmMwSX1JPuM+TPykRPTl4o45YXScP0b4WPacx75d1if68irFx1z6s6yUXi1HEt5SNVho+Ljg6NnJ0+T/FcuvpYh9PjonbOX+UbAq+qZ4j/18nhNtZ1/67wmiWnGc8SPeJCmXftRz4hTe0wvHh+mvDkOTLR536xvZ+i0aF05v4sAx9z5DRox7jc/14kTh3XGoY4cJm2nsJ2iThDLhMd41KvN0e2u4grlRfqZJAXnKSzeTDhs+WZOuKNAg/THK8RXe0GQ4exDocJkSG269YL4VOLa3eD7JHTUaYet0loU1NCnjFPW5cLDMs2je4/QXS66yf0Py4fCaPtV8jG1G2GwmBC8sOrR0yk26ExZq1YCU/LeYt4/e5DzOYH/YOp0TNd5veBfw74k38T/nka1r1G21W6HUaup0qD42FpTmI5IIowZUwuavUoODcVK4m3Gp/75RsV8tOMts1SV6VuUuDjOPXAeYIUxPjVUHYcjxgqh67LNImkyOQmZB+GEQKJRw+byqx9VK/5dh+n8DpgeCGz9fRaQDxdKiz0MU9GMHVdxDONNonOUmEtjgpvDTKZDwQvHeP98q0edBmW47K+BvEmw71YjuOo17ctn6u0Oi/npn9CxmhxPBPigXP9XNvKYDVMxAUNKMukvHd9IZ5ai4adeGtuv+uosNggSp3t7va2Nxn2VRVj4e1eEI0viJdTo03F6wFRsPRQihMTYgTbz7hskotYFTTCRDi7FrYH8TDOcJwnyLvEC/HRZ+KCwsp3GqEa89KsOGu9I4ZF3JtluKdtuoxdgTfmZ9ulvnvaVEgnDPfWHhJBXvl7Veydg4KwRrwnxHDz2wlRrDQyztN4sePaJzQr/kwY7g9WBGyWOcgD7Uv4LRA+OkUUVuGzQWjCeYkf0r94MGG4f06YQZQJceD+6Nsdsod7qvQvb5+QstHr7Zd6NcI9V2C2XZ6bReI6V/6swuzYxcF9jtP09OhveXadT8Ul5ddJclN80YCzDWF7nuH+UZXhGaJr2LZtauC43sph11bVAGIkGX2fJoezKPfrXF37LUJLOqa3yjebJIpT5bxrVvWiI7JvWdxzfZSbwrPC1f1H4nPFlcoHq0wXjo79AVG8HatG8y7Ray6Q/cGuj/ikLkL5fVB+1AtOK8oSdQrXT31BeJgdcxLvrkW5pv4j/xvjsnipYQbZb6qBJh5puIg7rqn44LfKemGgfJowdFrooJyH722UqvqmvGtCHMni9v3Sxr/e3/9WYkivETwQd8UH6bHqAfLwPZI1M+n1F0pbE0LvwnGa0LO6yVhnk9+brQTRl2yvZhjAkEdUuWmZMMSLqmfLq8d4Ypvqij7TUa0Mkk/oLJIWD0bf1rE4TmVPldOnlY+E0bZAO5llmZaZeJkYZx468Aj4cRKWf4bmHfDkrGdpnus52mI/CfwY7bj8ZRrwfgTgqzTjS1fmU8CPlmfP9UGtkGOe/gTtqJn/2+8F/iv4zjpf/OE2rkVCSEaCvto//w7x6H6FeJPeJkfTSgjexXTQ5+a9IlWA6S1fJEQmk9DY8If+7Mc7vFYKzBb7OF/p8Pku8CUaUqnsAHyZhJuXSaqKSHiB3Ju12MfyLu2UL70Fa+Reo/eJEbvUQb/Sx/cJcldJNUI9+WmBHPF+jZxiJENbJlHP+T7vaqTslf8XyAbpH+/wfZt4YoXRx8p8b9HW7Fbv+xrNU7NDO262pnHt93m/QPPEfJOkgc328X2JeGXe6M+/SFvf8zS8foehl+upAleNGpX3q/2790n6yRf7c/td7N+qPGySbODLHXbvEaEy3fu82uu83uH2Mm3t9cKpVHqP3yLxQF6mnY5kMQ1NRu24qsCapt3/M9/hu0xLdbjf+/1Sh89N4o2dIVER4fpFkgZxjShjCpqt/nuZ0MwXSZRmg9zTNke8tWOmutx/T/d6XyGpkN+h0c9Xer+3ScqWnsL53sY6ibT/ODmO/MvEK/tmf7bY33+arMG3GTpTDsjphdcLfN7v758p33oK2zwRUOsdrl8hjrT53sdXCO29R/DpEsG5PRodPEPuadOgmSGnOd5heGqiAviz5CQ56fBtclrwGx1uN4jTgj7f50gUbdLbXOpwfIHhRvnFDu83+zh+jBjUzxJeo0H/PO1kS+F9jZwc+YsdTq+Se9rEGZWcHY7f03aTRmPzJFJtROKIts4TGn/9ZPl2oz9bIMbxUh/fm+REvKfISX8mmaiUXy5w2SWRlqvEKLnY5/sdmpydIcbCLo0m52my5BIn39M2jrTd7PD+EuFry7Q11lgey03XbaGP41na+i0X2D7f33+LOHquEDq+R+5dMsNls/+8SjJ05jrMVD5v9TFeJnzESD8kcqehU4025dKzhJdrqMkTNzoslCMqgF/sMH2LJAe929v/InHkvUGM7WfJqZMbNJ69RaPVK8TQfZqGW2/SaPUROf3Pud0kBqo0fKvP40uEvlReV0jU8aU+xzeJzLhBjMKr5M7ZQ3KS4cX+rsrwcVkh94pqyL5ITvkTV14g15eNHQmUZzeJvNWokG4p310mMnOhP98mOpZr9GSH4zvkdN6aKXS5fPtW6afOxxOoITg0a79fbRW/+m+072/R7u2bpsnq6ySKs0PukbsO/JXexyvATwLP/b3w3/x8o7FvFfgs9fbk4y/S1lHc0elwjZwe+1Sv916vt0ruiVS3m+p1nc8cuevRokNokcaTIWmWM70PcVSD6CVCT1/meHTrF0ka6SsM72lbKvCBIV68TdNJXDNPr36J6JPKgAOSqTLdn7/E8CqBQ+Kc/QdIWuvnafTxpzi9fCSMtl0aYpsqd4lhvvekP/9FctnuDknH0DO1QltQj4U+T0Ocu72fvwS8/PvaIizTgHkJeOk/aM9uAVf/Wqu7QZT3dWD25+Czf/I/5On/MfAC/N7/CfzedfjL3YWiZ3aWxuif7T+T/uwLNML6y+RuIseuwq/y5nyhGVArxHu2TkLQm31+IofeqSoYv9X/Xu9wmCcGyn7/foOG/CqVfv8aibTdJXnXCol5oixoMN0hd4bAMJK1SdJVZGx64O+SyzIrkzzo39wkRvE2SX1Q2V8nx+bKBMbt3Ox/6wk77HPcY3i/mGFuieyI5DOv9f/Nk98dfWtfznWdhtsT4uU8zzCdarm38TpRdt5neJfZOrkm4d8CfvAC/Of32/dHxHgR3gc0J8USyVs37QOGHkhTPaZoDOMpYrSZknm9j+82SWOpDFYvn8f8KmxdX4tepQozcUdYQ4y6XXIn2w5JsVnv8NE7p8K62uF9QFLttjs8/X+feIU1sO339d7GQ3KNgWsl/o/LOsM7WRR6E8KrvkX2/khfW8Q4uEvwWjy/2cf9GoH1e+QaAhVvyjuFl8a8dLhX4LNJ9ghbzOf3xM4J8fp/s9fZJ8fcf4sh7amwLZBTO/c57g1XoOmsepehx1TP9mGpU9N65Q/rNFxcZ+iQgUQAHK8e0C0anzPyoGFpH7d7+7/Y+7hNPKHSsON70OFtRFd6UMGF3NWpkuK3wkKFYpvsDZoldx6tk4QQ57Dax+S39/szackUVcen7NskHvx9Gq80OqfzcVJg5pgOSKT9PSK7ZhhmxCyQyJT88ySjzQjwDI1XvEfDb50SOjN1VH6ztGPf0oeOMPmBaYKTAkdhraEnjJbLd+8Q/H2rt3uTpEU9IA4IxyjveLI/E44X+7c7DPf+TdNwfJekumvwyhMnROYqhx/ReJIGsQr7HZJhcdDbEW6U8Ym39HfrDPcduudNBfuw17lPUj/Fg0OiX6z1Ojpx9srvjT6fC2UcOtefJPxC3niv9K1OscBxXWBc7pF9vK49/f93STTE8mHpke+P+tzhZKPNTK5LRKbuMdSxxJ+t3qbzc/3uERoWFuKKdLpLTvmGyBdl4+V/uc37G+RIBvng7d73XYZR3A2ynvLn28DCzweXbnI8PXKLRJy8J1aeIj/VsXWXpL9OyPoqkyH0covIQDius92i4cz58kzjeo/g6O3+XlqfMJSblpsMz4JQfuq8FT61vE9ob3yf5C5Jb3ZtD8hVUM5NHjkeyzbwC729FeI8eVz5SBhtKjh6a6pw22GYFrVLYzIzDDcXT3pbhv1VnCelzXeAf5IIHy3j58szPX6bhHls0AD/CrD3t2H/5+AvPwP8I/DlrwI/A/wnJA/tZbi0CX/XahngZ+DFv9TONTFdbpd4LLfL2EV+SCpCZR4qZlsknK/H/IiE988R42RC0sMekM3BwmezwFOlQ+G8Swif3kcNO2+XMdmeYW6NAwVTNSwPSaqWwlTv7zi9ckJSTmbIHgBKPcd0QPYYWY6IQFPIWU88E456E2uZlD4mDNdiwvE9bSoBpjvp4VYQ2+9BeTfp308xxNs6j2ngB58BnoI3/1qUg0sFLo5/n+ydkNFbpDU9YU8Sz4/GrVGzi8SglkFr9NT2JmSNhN80wWWIciIsVP5U6Go9PWjCYveENmDovRN2R0Qpn5BonF5McWCfpKBBUnsfkvRR0ymrk6AWx2IkQZx23MJZga/yUwVw5QkKtJoyvlv6Eo8PGcJ2QuBuH/IOYaDzh9FcKh1WBazWr3SyWb53fDtk39leqS8/U2GfkDThB2QvcDXa6nwq33Ee8nz79RuLCogw3R+Nd0LoTjj6TA+7OD1X6jou62uQqEDcH7U3KfMSPzQg5dOuvc4O5zhNZJ8wnoy+dYzyn8kJ84FEf6pcdewqi3MkRd71kCdKh8osYfmQ8DP5j/RVHTFjp4x0qlNF+tsia6b88ttKIxpE8wwP9lDuz5P1sf+DAt/KF6TRavCJ545HmFn2R21DZHnVWZyrsDRNzhSq/TKvvQJH+3ftrfeQyDLX+ZDjKc3i04TwbGnF7Bzr1np1HZTFwrHqF3tkS4O0vlt+i1NVsVcuOD/HPD16f0jw+3GG1hbDqxGqc7iuqTT9YWVSxi5Nu3YVf6WzI4ZG24TwzwlxHk8Y6h6O/VH5ttJplU/qUvYvXU4B/8po7K4z5W9hLWzkneoIGqCui/xZPJDO7pNtG/YlTus022eIU9sMM8Xkq5UPOz9lStXpxPPqfPTZFEMcVUZIr3skvb6WykMmpV1TeIVPLbZZ10wZot4+KTA4IvKz8sexjHIcFVZbPB7n4SNitE3TlEY9N/MM88BlXhdIiFhvXj21ZaG8m6UpnAIDcnHjHNn8P37mIktw86Xek2Vc/9878Jv+Is08/23AXwd+H03j1QU+TyTFYiJ322T/iEqb3l5/Fvs49olAni/1nqQhhG1Uo81FP0es+90CH+e0SBDbSwEV3EfEe2oUUQKRqc52mNnuFFlD4VjnoyHhWi6SyJtwcT6Wuq4HZN0XGDIzYaFAWhi1c0AujZzv4zhX6hmZc63rGhyREwh9v9Dfu8x13DLuBdo6zXP8tEDn9IjgnvOS0QrDc+XdArB1B2buNF+Bwm6JMFXTWCY0Y+4BZfMy8R7v0Iy0Gmlbp0Vincci2Xi9zXC9xwxRXJ0vsKhwhAgL6c9xiVcKCXFPb+MsQ0+lir59yUMWyTo/WdoVX6aJ0IJ4L6tncZEw2J0yFmE0LgqtinuU8R6QtAk9cfYl3qj4jHlSpXlIlMF+KmyrYNBA0tCoOGv/9VuFi0qB85op85EnasxPlXr2OVfqT5GUykWi8EkH4pH9uDYa8GM8q0bbIjmhcY4hD5wmazhH1lbet8DQsTBf2hOuRsSF2RzDdVsk8K7jdH0XGe4pVPkbt+G8dshhAOK08xZ/lX3jdbdvlShpTuOF8p1KiTxwmiGPFmbW12hbIEalfVHmJuz2R33B6ZE2Dfo6n4dkzc6N2hHejkF+6Fx08lQ4agRYb5bgeV1bZVqlvUrLwklYqlxXWDw5aq/KYvmM414keK/jVf5Q6Uw6cI0qPzjq7Twiayqsncd8aZfe9pPEWeZYNonyXmWuBpV069pV2e/aVsPiNJyq/KHK2n3CL9VvxjJ8XDw0Z7rUq+ung0Ld7cOUYfGxOl9r2xBD7UkaT9cRqhOq6ljnGUaw5XtjGna9IHAUb60r/5jh+J2UkMiosK145vgeEhw9KD/iubQhblHacw0XGepiVc6fG9XTIVbxVtg6R3md8vUkna3qEI63yg9py/GKx4sc11Hk/erDtrtH8GRx9M0Ox9fsgGHmT9VNDoguUHn2AsMyW+YtPE/qf1w+Ekab1r3WLww9gtUbqldCpiPD87vTIm0QD/aEIbFvln6sq8fbNqvn3nH9pm1aPPMm8Cf7zxLwLxEXgyGdzaR2TMjhFVOlbdudYejdts+p8owCM4lYheCg1Nvqf+vRqPDZZujlPSjvIOlbrosKSFUGD4kwnS71HOsO8WjUSJtK04QIgglD7xYk0iAoFeZVWXeseluc25gBaOA4/uoBEe4SvPNxjs5rl0R6j8q3Eqp96UGunly91I7Pvpz3NsOoo/A2jUnlU+FiROSo1BXd7MP6zs35VM/sFlF2JwWOOiiMtlh/QujT9qpnUwYGoTnx5qRI22F5b9kqczQCu1feGYWCKPr+dp2l1wmhddf9gKGHWCElzFwXPX06BYRLLcJMpdzIgWsuLtim9KWwEverY0Se5PpUmndMMITtpNRTwZKfVQHrHBl9K96LG47F+jUSv8kwGl7XvuJh5WfSvvzB9+JzTSF0nGM8m/Q6ervlTWNFRkXeeTwk6zZhCG89ueJZpVsdSdb1e+WIfEI8Eo5bHOeFepQrrdfxqKQKM+EoLPS8j7+t/EfcqLwdQsNVrqqUKoOqDHA9NAJ8Lk5It+KMcNK5Vfmhxks1WsWJKvNh6Cm3XfHWuSoHVNaEp9EWjTPhYl35jW1skyiC/GVSvrV/3wlLSJTMtiH8odICBcbSPwVuroVjmpQxOvaqGxwQOnTNDhniOmQbgWOZEHkh3xE3K64clu/Hh9tAjDfbET7CQ1gJE3Gq4sU5Gu/WGSfMxCcdnPB4o21SxiY8Jwz1PueuHlR59+Hof3Uyadq9/VUfOSRRnirnXLtpks2kE1XYKtudl3NUplb94YAhPjj26twaw0Le4FyULeKyfaiDqDdXR4Z07ticf+Xjrp3tqIPaFwyzGdRNpDfhOSntjmldOIgXytQjhmMR1+y3RtKq3IShHqdeIbzkreoQY7zYIedpOD/hXde7rp30JT8+YFgcR8XXCY/HefiIGG1P0jbgvcfxg0g2COH/bnKc7jWaRXqLbPC9QrxQC7SNiG+RvU5LtL1l36Rt2l0im2l/gZY7/nwf0wo5h2S5t/eTJCT68adoO1yr+/Jfpu04/I9+uo32Dz1IAu7vgcsH8Hu+3sa00dvVm/h54gG7xvAgEg2VK7T9Rou0Tbp3GHrrRRhDuOeAn+jfL/d2L/T5z9P23r3R5/rlDvNvEkT/KsODSDzUQKVtkRxEcpGkoL7Tx3dEDiJ5iVxzd1hgv9LHe4MW4fkFhifBuaH65xgeRPJJhlGBZVoO83Qf85cZpgPuA18nXtf1Po+v9Hm/RYS9UcBr/dtD2jJu0HKnnydHs+6Ub/Xq7PV5v9jn9Q1itOpJ/BLxQr7Z2/hah8ksDWffJp411/4qcO1jDTivrMfovdbrrhHF+2sMj6/W0yMT3Ozw/2Gygf5WgetUf36Vtn6v9/Y/Tdbe9jbJfUKLBRaXCS4f9jrrvS09TR40YR1odLpAm99K/5n0tr/cx/kuxw8iuQ78LG1tv9TnuUGur1Bx3SWGn3uToOH8VY4fRLJA29Stp7CWZUKD8zS4H9Fy+9/uff5k7+MmUcZuELxZpuXOb3SYfYVGC7dpNCys3+ptLPa5u5H6sPe1U/4/IPsib9A2WV8je9mulTmsEC/phOxpmun9q6h9s8Pmd5DT8pYJPl3s8Jv0saz1fj5DjGWPS77U21slTpgq+D3gyLkf9vnP9vm8zvAgkuoAeL638xpRNJZ6n5+k4aCnzC2Sg0je6vOdofELDyL5GZJK8wKNHt7oMLtKcOT1/uxVss9WfqYDbIfhQSR3aeusOPl6h8/ThL5f6fN4p9fz203a4SBP9m/u9TV4mRzUQq//mdL/a0ThearD5oXy7nqf136HxaXe3ts0XqTSqZL+47Q1XCH7YMcRi2mGsumdDq8f73Olf/8Wier9Q6WdtxgeRHKFHDqyQgwrn/0CkTdPk6PlN2hr/fk+z6+Tg0i+RFvzn+7z+SxRQG8WWE5IZEUl6+NEB9liqPjOkMOMrpQ2dmj4777dr5FIjY6Pr9Hw663e9qUOuyPaAQ0qt28SHH2Wtt4/29sWf271/ud73SsEV9Z6W0sdhot93DdJpEjD+Hb/Vh6rcj7payFOvdTrv05o+TpJlbtKDlU76vO72Od4haEMH5cVGn7vkvTRF/u8v0n24b9Io8fpk5v5XrlF0zN0WKjQ1zEccvJBJJM+luv92bf67xdoNLNGIrlLDA8i2SKHsEHk0zZtHTwwSt1GnaCWd2jr9IU+dg8ieY7sB1+l8eIbpY81Gu+4SKJU3yIGxhLJwHkG+BTRZ64QY+taH9taf/4pskfsTn9WDyKZ7nV/gURcXx3B+hGJVn65wEb++CkShZQG1TPvEbqxHNJ4m7rKbyHycwf4qwU+tdyk8dgfJeccrHLyQSSXiAPlG32eF/pYlxiWhQ6f30Nk4Jdo6/ZnOL18JIy2HRqibNAQeJGhF2pCI+j/rP9/kyiI67SFXiXK4pvEk3SHRrzTJMXjNgHShd6+zyTUTY7vaYN4Yr52D/6OA5IfMUV2H978SuP2fwD4Kdrq/mew9fW29e1O73ODodfLsXv6Db2vt2hE+l2S+nGxj/Umx9Mjq2DU+Nkgd9Xc7G2skU2ywrseRKJnaJccQT5NhIRh70kBw1r/ea+3sUUOatD41nBaJJ7Ct2hK6y2GnoaN3t5t4hVaKfWmS733iHK0x3GvzTv971mCU3op7zC8A2WWENkh2Ty9TjaqX6R541YZMlIjeOt9Xh5ooCdnluyBOSCHt8wQQblOTuv0+UIf0wvvt2dvEKPeunqc9SpfJMqZhlSNtMnANJw2aMaQ3qYVGiNa7j/uT5wdtafXaZlheuQiweUaaVspMFNIQhQd0571RG2SVNT9Dh8ZpWO92eGjYTQhnlaNOyN84ru47fh07lSvrcb8dzhZ8FeYzTLcH3en9+FabxD68sCkGYbHVC/2b26To6qFtfxsvs99tYzdk0P9X3hDW2OdUCp2VYhIm7MMIzryD/r7m4S/aCRtEvyeJzgnDFfI6XDyDg3cW8TDqjB3DrZX8cwTSt/u7W6QA53kgeLCPjmcYZ/Ih1WG0ft5mlFX6dA2Vml8411iTHpYhiduXiTpUCtknT3oR5zRo7xPDrqiw2idHM4jT18kkUDxyHp+q2Gso+UBMZ7k7RDFwv6XSRRNOXe7vFum0f2jUsd1XOH4nrb9PoZNIhfkAQecHGmzrcMynw3aGuu5nintKDcnRAZ6wIUH6Th+HV8HHX4XSQrXhLau+4RfiL/Q1luH2QaJUK3394vEoBI3p/tYFvu3ZgFQ3s/2uekUlEa2aLgyITzxO8RQkv5d53lyWMGDMu8VEtW42+u8Q6L1O8So1zmySHDFaMYCw9OYdXCqXygP7zCMispPN0l6ozSyQvBiqdfTmFlkuEdM3rbI46MOm+Qai0MSXan6gj+VDk8r1ckCiVrWMUiLd4kuBpFTHvImb79NjtI/JGl973Cchh2f8nuH6G0QXaDqPZY1oqNMExp+mzgY1BcvEwd/pdfz/dkyx9MjJ30untq8Q8Oj/T535fl2n5ey6z7R6Z2jvEAnwrne9ybHdba3yJ5in93sbdwhusMb/b26gvVreuRhH6dj2iPyU74hfGpRF9sr8Nim4cD7fez3ydpKj8ZrzpMASy1v0eA638dzkwQ0Hlc+EkbbDxBBf4khMoicBzRgyrAWaUDYJQr2JZL/OkcuztwlFu9lsrAX+jf12cXen0LevV6zNG+d7S1CpJ3UNN0H+BTNCv3TwO+iufSutsNJLv98UgB3iZHwFDEiLxLEcRzT5IhslfdpwthUWCpznentqMBdJgJutsBH2O73dyplXhS5U9qdLu+NaNquCpcEDTlC+HJ5r2C41OvoCX1II4TqRRIWnkI4X55Vr4zKI2UJajuPyOmkErLz3iWKgEJRGFPqTpe5qQDX0LjjUdgu9XltMkyhEfYLJNVlixxJbph9hxihF0u/i2Rfkeu+SJRoFSnhPiFKssVnByR6a1ui9BS5XNt2YHiZcG1Po08jB4a4DFHMxUEZnUWDR9zTU64RqtAXz5z3VBmn63yZGO+XidFWFYxZIvQPSxv7BT4LZM1OEvxV6Txf5jtD7sapglL6cUyzREjaljxpl/AGGBoa8jOLc7OdI6IkizvO4ZDjwkmjzXWR3q+QNbjbf18ZweIc4WWV70J4rG3Uda/Gojjn5v4lsmfAObmeTxFlRCW0jucp2rpKe/Lsyjvt70nC27eJgX+X0PA6MVTEaY1B+d88uSPwMtnjoZKi0bZHrm6hPL/c564RukScAEb1x9/KnzVI5AvS6z6RfcJknzjqpomXvcJM/lYNOw0bsyogxotjrw4560jT06O/VSSV3RYVrhmGeLZT6swSvJpjeJKlYxG3HpU5agja7xUaz3JtpREVQtd5jqRnG7HbZ7inTf49PmYcsrfFOosMU76Fk2suz5E/L5C9s+o9R4SudgivocBmnTiiHLMyxufOkd6ffMW5ybcOy987pZ7z2O2wfchxnJoQB8xT/XvxRDl7WOa3WMb5uKKCLJ5Wfc73F0kk98PakvamGKY1Ww5JJPkSw/TIqmPp7HuqvFMnW2RIw/MMD28Zz6cabfLOsRyqfAWiT6gnyYt99oikf6rHiW+bRB7VLBi/3Shj2yf6ibCo/F59UZ6pUSb/3SAyZ6yzHZIsN+elHid/FEcXyxirDlF1FBgeBFR1k13CE06SiztE93L8+2UM6n/qdHtET5tnGJW12NZTRA6d1P+4fCSMtnlamNHfCig9DRoSXyQ51FcJY5inhZGvEuGyQO460jK/3NtQECqQf5xsHn6hj0lEWaIfiUoLXW7RkPobwPydMJYZEp371C6wAt85go23Wx8v/EvAH4J/5f8O/K/gg59r7b5FC/eaCjShhWg/38exQ5D0Km2BL/W/V4nCY9qiSjs0wfVF4j25TpTceVow8GIbKl8kAkTD6oskjWKZeFMOiKf4Uh/rJeIBn+/jo4/xRXJ/hkJegalX5wbxLlamZJqHHr9FEqZ33jC8K8u1qkadhhQMvc6fJx59GZfG/DO9/hHNM7ZBw5MXSPqQwkuBBPHgvETu9tIpYL0vkojyk/27V0lKyE1iPJkqZXrkazQ6uE6E6DMk4uzJjq/ScGmTpBk4H8fz3T7Op/s4jQqqZF7ufX66z/N9WkrBhRPaW2UY0aC3+/lSb5UYVTJrlUAFGwT3dhhG+S70d9KkgnOmw+AGoYUvk2P7TY/Uw6ahvsMwuizMdkk67EXaGj3LyZ7f2wyjmV/sz80C2CZ0+A6h0+cIo79FvKVXCE9aILgCjW7eIUbYZwpslzg5PZIOl+v9x+PCr5c5mB45TzzTazTe5nz2SErcl0iK3DJDp9c14tlf6/9/luDqBkm5O0eyHmoK4SFJu3buR+ROw2dpa7JM7rs7RxSFTzLcs7NDeOeLBdaT3seXiILyhTK35/vPIYkYf4pGD0t9rNcYHmqxT0ulWSOp+TPEaTCh3Un0VG9vnbamykD6HK8SD/1n+t8Xe/9+a+RE3rVO0maNRCn7PksMP4iSrZx7gezlvkGjp4ckYq9xLI86Isb55/sY3it15b8qdlVGzdKil3R4X+l/LxOaUX7ZzhJJeVsg6ZGL5L6uHdraCw8j6x8jTl0jZp/t8zwkadSf6W1KC6+SPSeL/TsNYh0B8gRlwh7DEzF1DiyQ9MgrhP+skLTPLxBDfI+m97zKcYft2yQF/IAYRZu9r+f6/KZIeuRW//5qqWva2kWSWn+ZhgvSg1FreYrG6tNEJ9ohe/WXe7tLtNTLXZIOvUjuDtuk0U5Nj5wjhu1VPjw98jZJj9ym0dBn+3d3O1xfpNHj1MnNfK84T2XXNqFdiw5mtxQslLorJD1Svv4CTa+R5+oIuEFoeJsG6xrhcz7PEz6t3iYvqeVtGmw/T3SG52h80iyO1d7WDWLkrRKcmif6l7irg2utf/sSiUBfLeN8hgRUrvR6RttW+rPPEd3OSBkFVp/nuM4mz/vx8owOq5dIerJG+svkKqAvkOABBL/ukXvalJ8TsvXmWYbl3f7dF8ia3aHx9pcZpkcacPIU4XP9ufKilv3+nbJij/CkP8bp5SNhtO2T+4fmGCpW24QBGk68QzwChichoV5D8Z4RskqiJIvkItu9/qNhppIFAeKkjOsN4o39s4TAZ0jaxSzwxfcSot/qz77yz8A/fQH4L9rHT+zAc/8LmHy7jU/EcG4yg12yt2SfpCJu9J9V4qWu3jD6N2+RvWUas97tNkvC92+RNAa//zYJ/arkaLRVRq3SME0uQpa4/OaIxkTraZGGnfUUqrhWo22qj9MLfLeJAVbrrXXYqTibUmp5RFJxqof/7Q7j7xKGuFDqQMLqpjzqudqk4UiFJyRiqfB9j6RpzPTnb5FQ+jJJZdno4zZlRUXWtMR7JKdc54MpKzP9/X7/eYcoHLMMIxYTsq7niEd2laQxTBM6hDBhowrVc6RxZIqGsNgZ1btLUjI12ibEaFNYfJukRYh74pupcXdIWsIM8Ta7R016FQbWET4qRuKgxrmOoe3+TmO7ekNrWSswc23p35nS9RYxonSq7JN1WSWKzB6Nd93u33+7wPBmaXObIY6rdED4QI0QOae7/f/t8q20KcxVYuUh9Pff7b/fKH2vEnwS1sJ2o8zTMW0RYSYvrlnm8oh3SJqVc7pNUrblF3Dc+6y3c4WkyaoEwDCNZpukMa/RlKxzfa6HJHXGb5238J70cc71eg9J6rf7gFX+xDsdDo5lheDPe/23ey7ldfISyrdb/ZlySHmpsi18dki0aJfwaOWi/LDKgG2SHrlY4KMRdkgOoXibGI0LDJVQ25hmmLov33ubGFJrfWzSdeXjtxg6v3QALhB5rXExR+4tfEROi9MgXOvwmTBMmbrZ664QZXJCjCsY4tNmGd8ecV6ptEHwWp64RfjZLrk7bbPA0bTCR+TydFNBF4mzU77i+LYYZnUoN6Xr92nrpVzfIamdG+TQEOXkNMEH6Ve+sk90MvFKfi2tTROc2qTRyQMiexz7Bsmk2ST087hI290CJ+lqrs97mZyHMM8w8ntaWWF419lO/z022jRs1hlmQKwR/WyZnLLoWKTjCQ1W0vCEbO0QXvKVqdE4Zjk50rbcx/92mYuwVZ9W5zUbwMwm4aPDqeqArqF8XCfdNnGITAiP3yCprqtEZ9ojjrnp0uYq0QOkT8uj/n6LJg99Jq80ijVDDMB5cufp2xzP4nHs6wwjubu0NdDxU4u62HfImm30Ps+RyOosOc11h/B+x7g4atexvEWcpO+SaOBp5SNhtO2Rgx72SQRCpNshmwirIJ4lebDbJMd4mRCaShfkAmkVPgXAYXmm0rNNmMwmybWWOchw6qWwuwQBK2OeoV3Y+pfvw5f/OZK79u/Db/ntcPu95HMvk7QoyniN1ojYi0TgiMAq70YrpkjqyBbxaOvNdB7bxAtaCVYmoYFiPT2ss6X9WRINk1kKxwfle5m/hpEGuXniqwWeMNzcbJ+um/OGoeLj2ldme0AuYNRQ0PO1z3BfiIxfIX1ENvOqVBv1q9/aXzVq75DN0nsMc9JVZFX63ySeIzemO4+75Jhh8/Xt74gYPhOSEvQmScNxLa3veBznAsExGeB0//9ueT4h+/Eqg3WdVkewkOYsRj00cvQeWg7L3+eIYrRFlA29xxtEsZgmF27fJnRQ6VWBqHK6X9q33zdJ1EmFXppe42Rv7Rj3dCLZ7x6Nd4lH0qdGkfxrQgyfqd7mPYaXhK4xvPB70p/rFDko/xtBoLe7TpwPEPyG0KaGhbhR8UYFREW50p7Cbo5cFK1Ad80dk4qiDrbtArPpMgcIj6lznCZOmq3SXl0bFdAV4rne6jCTJ91n6FmXDl8nDij3pd0s/eySvTMHDB0QqwzxbqOMzbmJdyoUrrkOvmViKCkHxgr+QnmuI0mFcKHXET7QcGan9L9a4LxAlGVhpuJ8SNZqjezplT9LTxWPXbPKD8cySqV3jUbn40tr90h0qspy9QEVRJ1jm2Qv0Abh38obaeYc2b84TRPDtwj+anjqHJAWdslaqgc8IjIDwo+MvI+NNtdnkaQ7VlmxQ8O9GUJnh/2Z8J8liql8REPCTBYYZhHslHkoO3UCXCC4rDL/JMFFlevqHDxgKIM1YP1Rd9LgPSByYZ4cSKbTbYMYiuKOOs44olSL/SjvHjI0YIWB9PhhkbZ7RNGGyK2qj8hTlZnyRvmla7RC42kbJKJv5MVo70L5VqfFFDGONILdxwvDNPJa1Lssq8Q56vrfJzqWxveEwPwcDY5GBSGGljxqk2bcPCA8Vhla8du6ylB1WuFom98lupDGsEV5M3vCM3Ud4bHc38vnq35q0ZBUV6H8ln6ETy33iKPTNXNOjsHfcwUmjtP31YCE0OZrDPf5j/sfl4+E0TZN8rQXSYhRj7Qe+CVCLAoaDSXTaOYJMVnfdsxFlqHotVoiHsrFXlfjcYF4EZaIAjwhKRQK5KlST+VEQr0I/EXgL3+9eMr/U/grwN094N+kWXa/QDPnny8DeQ1+9j7808QjcomhFT9d4FSNLj0Dwk/hXOFz0P92P8NBqa/SJpHXfub7WC4WOCgchOMBw7xs29YAURAskQhVJdy6ZkdkzfSSyLyOiBBxbmMGsFHacA7imsa1RoRpGratt3iX7Du8RBjr2Gg7IClsVck5R/B1nhy7O09weKZ/rwDWS+O8F4jio+BWuVFxmSljdGxV+Z3r/ZrbvUgMd6Me0yRVdIkIVsde29Nj5XP/d/2sB1F8KrwtCgvHvUtwerfXvVT+X2C4l2eJ7H+UXqcIvmhMiKcqGiolwuwR2Vs4TxPAS5ws+IVnxb2j/r/7TJZKv7Uv16Y6XBYITzITQFjvEKP5yRFsNU4s4iEEZ5fK+/q39WdIqqcwqLS7SfbFOO4DsgbisUL4iKyLdCS/0mlzUJ6pKJ+GZ/LfJYYn+FVe4NxUJuTPT5IUFutKF/LCCbmofoPg/2Jpe5Eh73ScCmf5qXOp3mXnf4kYKjonlogxosyQpwjTvRO+3WPIf8Qfxwehw6pYO7bF8o0wkw4OiPG0Q8Nn4S0PEgY6oZTBJxltVTY5DtMpIQ5B61Q+vlfqVDkwTwyXCsdtwg8XiTFgyqz96vg5HD2ThwrbakieJ5Fpefti+XZc5A3i0gWGkUEYytwFhvvxjJTNEl3J+hosE4LXi4QX+r/8rxob1tO40SFzqcyt8qzKi6UlaV3jtupOF4lhWuWqDp6FXte2nZ985HFGG8Rp4Jicj/pC5acfZrSpI9in61rHoMNZGqxGm/gzS4zepfLOSFv9HmKw10ibdLJItg9o+I95nXDYI3S0VWAhfzkisrzKBmE+Sw5REyefJM4W29ssY6twP1+e24eOKnFBPuhcNfbGtE7/7kmGuphrdI4hjkpzF8rYq9z8p4CP/73wj/18M5LkCbZrBLLqqhb1w7pmjqXqvsLxoLd3j+Fe1jFf8P+l8v9J/Y/LR8Jo+yFafukyLQf4CvEs3iNeNI+XPaLl014gqWnPkeN29Rb9GC216BZtYZ8ie8cUildouaqLvY620nfJZmzTT75CTpRTiC0y9DLO0fJv79DCqRpIXyEIaTrIMs2L9nf8TuAv/k+Br8If/hdaxRu9cueCL/1cjoleIHvaIN4GGaqG0WwfyxHNiv8YEV4LHeZv9na+REM0hRH92Rw5FXCNEOEm2df0WWJEvkuO/KfD4ZO0vHIjmSo1T/VxHdHypd8p43Y+z9LyhueJJ/MqDU8UwBAvhQT8JcJEIHszIDnIB2Qv31tEOV8ke+fo47vZ53yLhiPXCJ56YlRl4Hf7GG+QVEsZ+TzDPW1v9edfIJvob3d4KOwvd3hdIREblSTpYYakrez29q6WfmUSRl43+5p4fPEUDdcPCXN1H92LNFxdJ3ncF0p7evUgEe8pspfGemvEq1g9qtULTx+7isoKibReoK2tp1hVpeoqDY/mydpOOqyuEWHqnr8J2TNn38JM3rPS+1ygreVJSoTpmBqjXybe/e/Q6Me9J57QRx+rEbNl4i29TKPbxV7f/VYQfrZIo6FPF9ia6gvhAUZNP9Fh8Ex5Jn5DaHOe8Di9xl/udTSY9gk/k7eIT4sMj/xf7///COFNCupLNLjeIZEZPffQ8GaRIZ55qt8NcqT9DYYRD2g0+oCczKXxe7G/03t6n+xpe6uP48fIPuVnabJlhjhfnqftafk22V+92OfyeodPPfJ/bJDep/HeuqftNo1PPkmidleIAuWR7Td7/367SfazzJA9bp8mUWN6/d/C0Mm038d1uX/zAnGMXO/zEq8vkkyAy4QO9OJ/qX/3XYKbKmfy3rHRdrOP44tkT9tKn49y88uEj3+bbAtYoO0terb/vUKMBvc76nA9IGukUTxDW6PrxMDbpO27eZZEFz9DouC3+jg0OnROqoA+08d0SNatKv7zvW15uemJa2Sv3ueJEbpH9vIvEjlziZziKl+RN4qjN2g0N9ufvUxSaa+QlK6nabj8Jg0PHxGfsXOTZ1X94ha5LmnCcE/bKsGpl4gRt9jH+HESDXmG4eFRGmsX+9iqDB8Xs1g0fic0HP4Rsv1ioz97lQ832momDiQKM1vqHNDg9wI5IIY+75U+nwWaYTBP9rStkYykJRre1T1tbxM8cj5bNN7jkf/VST+WQ+/S1sSrDRZpOPAJEmVfo9HBJ4gMXCPGgvTyJJHDOjvX+jheJPrM00SOXiPZKFd6vfc4/cj/KVoEUV43R6O9sc6mcfVj5Zny/sUCD+WeeuYmQ7n5DvD2z7exv0jDjVeI/Nyh8e5rHT613Ozw/TwxqMS9lzo8jORf7GN8QNbJPk8yxu7ReJy60+dpuPH/OKGu5SNhtO0zzL+/S0652iIe/teJEqdwUbF4SPaeuSfA3GKVxC0awrxD8o8nvW7tHxKy36Qh1xyNEGVOywxPJ5shwvA1ovBN+rvXiHfSlKC7dAVqGfjJvw7X/3q7KEqu/xaNA662b24S5FgjmzwlBBX4KhhfJ2lFG/3bmwzzre8RA0IF9Kh/e54oXxulH/cA6GHWW7lC9rhAUs92iJf+iBh8G8QIWWG4nwoiKG6SiNR9kmpovbskjbR6jiz7DJnyVu/3TYZ7GBSuGnaOweioOLJN9ictl28hiqm/HfsOiVwuEK/Mrd7+G8TLv0ZSNc51+FyiMYVbJA3JNd8lnis9tG8RPNdYdD7i8T3iMYIc5QyJKBvxuUnSrYSR7U2IEbhN1kavnHizyfAOMOnU9xYN6D2SYmKEabHAp3rqNnu9myRiuMNwL6JKporOLlEYKDDbJ/u69BBL69U4oIxluo/5tf58m/CA10kqnfQ5IXiz3uvL7xYIT3q9wPoWuVtHA13YLRODUCNUb58e1DVCk2vl240+rlmyl1fY/lXCV+zjtQKHdYJPCnTh7N8QvrJF9rTpDBkbNkcdlirffr9CLq29VWBQaX2aROFulbE4PlOZtkna2wKNP6x0eJ8jaW7bJCXZcewWWGwSHBH3jOasM4y06VCZYrinTZxTFmlcCDtp1hQ4v90iJx1Kr5WvyMM2GZ6wuEJwZ5vGj4WTMFOJ1xG2TPZ/zTCMbi2WMc9z8t2Lpl/R393p7b1JFJq7NBkkr/yrJGq/TGhknhhTppsdMDRKq7GxTWSCMHuLHDb0oM/r7f7+FsEpDTR5/yZRrOfJ+tqu43feKqkaymsdXraxUebldUXqF4fEWFbOLDLcny3/F0fFs0Mie6YZ7ruaJTTumis7Fol+pXIt7SqP14jTWj6q0ezBF4sku8D9eCq4O2Rf5SbDTBpl4xofvqdN+j8gGQKHZG/yNsMtE2OcrM9WaetXHRKVdiH7lZSZ86XuWMdS3qwQniuNbDHc06buQoGZ/WyWcSjrxnBRd3I8pt5tkC0Nm+VHmDneJ8mR/7cYZvBMMdyrfJNcTK0cvU8cBNKHuOYYKPOg11smesA0Qz7+iOwNNGJ2SA5XqvS3XL4T/6rc9FvpQaeQslj6UebDEC9WSFQYsgdNOaU+tkh4fJ3bQfnWYn+vkS0Wb5Ho+GnlI2G0zdMs3gUef3qkkbZ9cnqkJ/c9T06P3Ou/v0IOI9Hr76l0MDw9coG2qC/0d8vkVC0Vhy8Tj7LKjRuuVRqt5yIrxL5MmIGK4UIfNy/QTOxF4F+l3e76O38X/AMbwNvwE9t88m81b9n49Ei9N3oxDxmeHqknbpmcHqkC/1kaYq+QSFtl+D/Gr+30yAV+7adHHjA0xjw9UsV2ke/v9Mgf57jRZtEg26fhww5Z41l+/U+PFDeqcvclQuCLfdxfYHh65NvEEHiaRL32GR6ac8Cv7+mRGoAz/OpPj5Q5CYun+bWdHinu7fCrPz1SHJVe7/Ebf3qkCrBrCzlgo0ba3iF0+hwx4DXG1mk48BWivPxYgfUSp58e+RZDJf+AX5/TI52PEbBdws+O+O92eqQ4q/A1heuQnP7l3I8Ynh65yIefHjnD93d65JdJOtaPknV+nmRfKMw/RSJZuwxPj9Rb/aP82k+PVMG/yvHTI7/D8dMjv0N41zrf3+mR05x+euQMJ58e+TqJAM4yPD3yi30Mv9rTI6cYRtpU0raJ/LKdJX51p0fOcfrpkdM0Wr/R21ZZ+2xv84Djp0fe7HUv8/jTI/f5tZ8e6WmZGkGPiHw19XKJpB1+mexNUlZPkdMjZxieHnmB/35OjzRCuEhOj9ziN+70yHl+badHHvDrc3rkfP/9At/f6ZFv8N/99MibNPxRDj3Hr+30yFmGKYbTDE+P1PCsuP5rPT1SQ22Bk0+PNBPiK+UZHD89crs/f5mcHvlFjp8eqdNgjRaRVX5O+rtrnHx65AK/+tMjHecCjz898kuE9uRJf4zTy0fCaNsllyvrwdgnCDGhAfzrxNLXQFojXiOZ8jvEcl8mHuU1oji919vQqr3J8BCO9f7uAlGQf4ZhpE3jUGVjQjxFIut2+VZC80QnhfqX3yGU9m4f2C/+Gfh7aZTxj8APvgdvvT3cf7DB8cu1Zaz051/vz4ygzJE0C70Lzm+/v9Mb+nXiLVojkYZHNKR0rhQ4rJBLbyGXk5rmKvNfpK2zCrzf3WJ4KfgDkoIofDd6W9aDnAYmE1CRtzi3Q6JIV6/iSZE2CVRjY0LSyNYJnuoBlenuE2+TabKmwsyUugsdlrd7G98kys4donCf6/9fpOH42ySaRZ/TFjEOFazfYngpucJIZWtCoiQa3Wv9GxnrPXL4gXSn0F4o7U2IcT9PmK/Gseu5Werp7FhgiL8QxbVG2vT+zhOv6CJJvVqj0dZ3SD79Th+7a7TTx6PHdI/g4GFfA42wLcKM7VO41CLMHPPX+/Mt4nX/OvFQS18eoqBDQkXmXofNO73+1wusbxOP6gUaXgnbZSLUNIClwx2ShrfJ0GNpvQOiME4IvV8kfOWd3sfPMIxyi99z5NJd6eAecdYcEtxdoLG7DcKvZ0iqiw6Yimd6L1cJ75owdPQ4pofkcuFdIjO2iBf+Ac0gP0fjPe/RTmedoeGRfPot4i3Way285avzJG1NXF8jdDpDlCXlHKXefZqh8u1eVzhCnJirZD8WRFmc63PYIodU3STybY2c9LhPnAdTxBm2UWDm/KQjD0AyaiCsXdf5PnYzQRZLHQ3pcXqkSvc3iEKzThw052m4X+WmBpTG173ytzrDJpFzB7T1uEsMWyOnsyQdc9L7fI2caDlLZN0uyUBYI1EyswQc+0WCczqgIKltKqEXCY3cIzj5DeK02+/j/yYxiGdpa7FC9kgd9vHI66fKmN8ke5erHJ8lJzhOCF84KHWcm3qTPOCA8CszcXSE7ZV3C73thzTaUq6ulj7H0f9ZhjrOSU4yyzrDSNtO+f0OiV5WZ2Dl3Uej/++QA2imCO3VqNZhH+sDom9C+Ku0+A7Z0iHNuF53+pyl4XogB6P5SPPTDJ0/Y7isECMIEjldJRkF8hkddAeEfpRx8gbhpeEuH9+k8cL75KRqHZyzJNvGvnSGbBDHZtUt1NWltWq0HdDoYI44CA8Jf5wQHL1ZvtlgeOCP5YhhpK2u8R7JbKlRT0hGwDmSbqnht0N4irQpj9cpNU+c+7UoU362j0dH9AqPLx8Jo+2ICBMnvD/6MQVAIbFPWzijSnsMPXsQj4XIMluePSp97o7qQpj9w/L9zqjuI4YKqePaK3NQSKmw13EdAH8euPk34IW/0RDwF4GnbsPzPw/8yaQT/ePAz/6V9ow3+N6O0I2/PdwvcNTH9ceAnyNI6bgrfJyP6T7OyXZULsZwFDYqIbY7xXDtKN9XuMm89DwfMlzbWh4y7N+w+A5Do+1h//H/Cm/HocE4zRCn9ss7lcdK0MJCeDgm8WmPYVrqQWlTgVb7oMDsUXknDleY2399X+GrseF8HpI1rGNU6Nreg9LHXoGlczxguL51Ho69lrq+VciN61d4H5U61WibJjAd06Z0KP3sj75xPQ4JfjuGCtcDTl6X/VJH2heP9jjZW2s7vtslOGP7lW8dlHoKqn2GcxqPs8JTOJwfwbbihQLOusJmrnxTv9WrrwIoPc0QOqj8uNJXnecUx9fM+vKmPWJkVXiIA5WnV0PsiJPXruJAxYX6vsoMYXESvP373Oh/8YFT6o/HtzPqQ/5c+6vwk6e4Zofl+4rLe6NvrTM1alsaER9mT4HJdPmmvpffmR45xXE6ZNSnY4ZhhOKgtCFezjDsqypPyiE4WW5WOVBlWl0P4XjAkA7GPF84yTer7Lb/CpuxjKvpXmP+XI2CCufzBA9PovWjURvSv3OdGb2rMsR51rnV9Xw46kNcqWOYZbiO9uHaueZjg832HI+8w/pVru5xnPaqbJTPP85oq+ugTjKmTdd2hw+PtDl2S8Vzi3Cr9FrHItwejp67XoelXsVr64vXVYdQ7khTVe8Zw6LSg3Ql/rr+dU3qOsufHStkj1nFlao313GOcarqwPZbjbaxvrc3+t+2qy5WZX4du/RaeXWVmzCkq0r/FX7ici22+YChjK9yTVyQD1e+PN3/H6/ZSby28sLTykfCaDtPC68e0kKwSwTRNskpe8+RfThXyKlDc/27yyREaxqbZZpsthYwi7RoyvNkAa6Wby4Rb8gcSbnZJMA2PHuORDSeJ/sKZvvPCwzzqjfICXPrvd9DcrTotf57F/hLHSa/9y/Q7nl74rfDf/Dn4G24/BqxNIo77MU3m+X+PIkuXSH3pMz3MR31sT/X53SfMOjnSRTTqIiK0SY5AdJUJZnKIbnVfYYW7n2ehIAPySk5C70vN9vWCBL9+fPEiz/f5/FsmTbEq6dnw7Fb9kkIfY7kbz9LmIVrpXdfXDjs9fUGPtPfXSbEOs/QaTBL0tEekIixfVQcMfL1LDn5bJYI/VlyKM5lEhmdJV7EK8QQlhncIGk45zi+B03vkP1OE++gzHWJRiMvkNSR5xhGQIyePEn2jsz3d0uEDo346i2v8K5GGx0+cx0u8338OySlWPgskms3rpJDMA5o9Drp/V0luKzQmZD1U0gJs32y18q5XuNkJWKhwGyuj89Iy0Hvx5SrGUKm18hhLPPlb+GtIJS+LEaqL41gCxFUKlfShzh7lezNqbxusfc3T/b6ik8vEGVj0n/Lzw7LN679FaIszJKDg1SspPFFoqDpMZ0hRq+HTDh3heJMh50C/hrDVGlo66jyMOlwMcJxg3iOH/T2XbM9ktK8RdKJlEP0Z8J9jxyAtUAcJp8kJ+FWL7ly5jkSXdro755lmBp4mUT3Xih/1283++8nSaR9kfB213+JoZxToVcuXur9CzMPiBBnF4ljaol4vlVOHLtwuEQUloPR3xDcku8pL4ShvKnKTd8rB56ircWT/bk6wyfIydIaY0+TSNtir3eD8IuFDrtP0A7K2CB8+j4NTyxLBX4LBO+ukQyYbeJAgOC4esoSw+tTNgkvniWR4kcM6X+eXMWgjFbZe0joSBx1bjcI/jxF8Exec0T2uUsj6jYeTiZP0bkjTu2MfpQb6lviiLQszFdp67JEDl9xfhf6u8cZbYsM5d1OmbcG9AwNlz/JcQNsXGYJ3sGQJ1mc9yfKuCFRn6sE9+ZJqp3yaoakkC+Vbynjcz4Twrc1dGaJLlaL/3uIzn7v4zoNt3bL+K6VPtZJ6uoc0WuVJ//J+fbB778dPqkcforojFdpeDJHw+/nySFQM+WZBqd67w5DnajqbAdk/+cL5dmkt6keMk2LVEIOpRL2i6W9Qxru+s3HS7s7/Z3wqWW29/s82Ye43sfgPDdJhoG4aBbMQh/LJYbFyOXzRC/ywLDHlY+E0TZDjri+TEOGanHKoDyZ5yJhChMaUJ8mwlNj4BmiIE73tp8hFwjbznWSPqjw2CGKsgbDNYIwKs6LDL0f88QAVcn3mYS1RRRnldarRNg9RfZT7TDc8Mr/FXj2z8E//J8DfwR+z18bhni61rDYv3uGCNurfbzfpQk64bPf/94joXN6fUPneqEUvEdlLa4SIa1Ra2rh/mg+eleWaOulIBC27hFUEF7u70wHUSm8xlBROyB3Zbn2Y6PNg0gWiEf/Ktk7WYX6IsM9bXr975N9XiqnKnR6pR728ThOxzVN0hRdi32yf+gK2S+yS+7Fm+19+n6JGFB67zT2qpdHJX2L4Jnz8Zn1LhMv3yIRVq7TMySNUIdJPdVP/BR2Cry69iqR02RvZU2lqkabuKdypKdqsbe3SzZzu5/JcS4TnNrq766RPW0KpllyAIF9C7Ndcpy69FdpuJYDhldwaAypRDsfIzAabc5xvjyTNp4h6SXXGN5jZXqc9YStaTD+r9cUgrPWPyx/+79Gm+ko+/33x3qdPXIsvLCQt+hAcc/MFnGGyHcPSt3ZPodVoriKczojrjA8Ztk5zvb2NsheterAmervd0jKkLgsv9KzXJWoTXLCmvWf7u/kHcJS3rlLePciSde6RgxQFS6jdxqy8kiNFxU+5yMvgMi+yehbHREq2BC82CD44JiVq6skM+EykRXCTL4rDlwkqc3ymkPiURcGKv2medPbkKdXo22HtiVCXkp/L83M0nDPdrb6b+WAY5Sfa3A6ljXiwX6K8KUZwm+fIfsOjwqclojM36LhnftUnP8uw9Mj5c8qZ+NIm7Lr6TKeB0S/UUbP9zb2GcrtTSJzJ/2ddDVheNeX87jVn4lLO8S5XXUidZV9witMjZNnFfWC+x0OwkeDbdLhou50lRgH0rK4vMhQD1BXkk4r/p9UXHOjJBoH6niVn17j+4u0VbyF0G3VM+QL9fTIRbJW4p56yITwd2V5pWEdBvIJ5zNd6sLj97RpJMjbKn677gd93M8wNM4WyemRuwzvafsXH8LU7TgTnyH6zGVC2zoCjkq9/TIf10An1lT/+S6ROSfpbEsMdTGfzRRYy6t1XstjrnJ8T5s0sstxPXujwKeWXeL4XSrPH4zGIG1qyC6X5+Nv6f9XOaxsGvc/Lh8Jo+0+LZdby/MC8Ybv0ICjgN0l+8/miPG0Qu7N8FhohfA6sXjXaMB0H8Ji79dnG31MMkgJSk+JgsG9TSob08SzvF/6nhDjQkLzJEIJVQ/PPC3PdZl4wx/SsiGfBX7bN/qAvw78md/admL+s8B/RNslfpPvueffIifW0eelsDGf/7sk33rS695iGMafIfuKNCKMDJ0nXoZ5ctLUGlFytslN71sMDT5hSx+ba1M9Ymtkr9uk93OrtzdDmOm98u0MMa4tB/0b+rhV1FVs6wlsGhMSmcT+oP++S5jJPjmwwf4OyGXmb5LT2ExzUNFSWV8lJ0UuEqeADGaG5Gcvkj0YM4S5rpAT6xSw0JjxTq87V+YjHm/2bxcZ5pnLWJ+kMZObtD0VE7Knqra3Q/ZwqRjR23VuGosej6zw+Z5DosxH5VyGqXNBAbRB9ps51qU+31tE+dslCob844AILWnVfoWZipAetFkaHdpXLfdITr2GswrtKjEQH5FDlSD5/OdIHv6kw2ybhs/yI2F9h3hHFxjuS1sjRpqKoIruGm2P1qXy7BLDdTkgKedGh2cILun4EL+k0w1iDMzR8EXYTvo33yW0/4BEdZeJYV2jMYeERiqerRIlYaX3vcowC2CaRiP7NHzUibHS23PvjzQ5R06DrSenivNvkX1KkBNKhbdGvXLoEdlrt1HgNE1S7teJMXqfxlOWyd46aV7Farn/fbePf/ytRqtrcIvwdsheov0CF51w8uJ3+7P3yAE8B8QZsUo8385Jw0LZV/fIWMc1GRtt79PwQmUZhntFZkpdiNyckIiMNLRJ6Ppmf7ZMIkSukbLBQ7GWen3x94C23sqX94lhcLePY5EYg/KuqT6WRRruiSuU9+LHIjmwZp9kYUyI/HJvubQwT/ZHqsdATkEWvzXS73TYvtvHco/wzYskc+ECwRWzbBbIXqJpcoqoesEhOQzGvXPOxeyoxf79bXLqq7S81Pt+q4/TvbkaNTqyLvL4SNsmOf3YaKN6wDLZp7jF0KCFk/e4rZM9bZCshTqGQ7J/bJE4ap23Rt8y0UXvksirGS9LDO9pW2OYcixNrTG8p00+OYbL+70feftKn8vrxPGpk/MpQivK2QUiu5aJPNQovU/DCX92yH2me+Qsgq0Ol5vkAJTtPlf1AOc5YXgB9fsMj/yXFucJnh+Sswvc4zlF07Mg5x1Iy3OlvSNymvOk11nu7wxY6GwY44UO1Oo8vUfOQpgUOB4UmDi3lQJLy7eJLJwQPvQUjy8fCaPtCaL0zpA9MYdEGEO8e+dKPb85Tzy40+XvmdJGfTZV3vm8EoPt257fV2PGsYiItb2Z8my6POOE9/WbqfK/xf6PDfibwL8D/G+Af4Jm+S6359Ol6mH5ZPxzbjTPczRCVMjMMNyDNl3en+Nk+FVP0MyoP0p7Pqvjmy7fCiv3AJwrYzS6MlXqVZjOjtqp7VYDS2O8jvu08Y7nO1vaG/d3juMw3mcI7zHMajvC4iQ8rXiiolrnXmEnI644dVSenbZ+0xzHz1lOh88BwzWQhmdK20f9b43XMa7AcD0rvZ/rfQijSvuOs76jfL/P8HRBy0mCu87L+dR1P8locz0cx3miSDnuuma1L3H5pL58X8dUYeY7YStPguDFeB3G8/PbCjP/r7yrztV6lS+P8UnYjmFX+Xela/uaImmQ47mLP5W+qyyo8K3wEpfHsJWP+6y+t626NmOeJrzHY4Lh+MQXYew8HOMewfExTMYwHcPkYfl2hjg2Kt+hfGdxnM7Tvsf8xjXRcVHhrQJf5zuWwzA02nxm3fF8KqzHMK14fxqvPixtniPRrpNk1ZifVtlr++fJ/u1KS3VMzunc6NvD8u4k/HO8M6f8VNieH31b8eyQoQyYGtXdZzivc+V5hZ9GSl0TeZp84tGoj/Ol/ypXhO8YpxzHmF9UmVD7r/xyXM6N3lc5V2mv4n7l3Ucc5/3jta2//b72Ybu170p/4niVU2McUK6N5UrVZfz/PMflvGOs8xzDGo6vKwzHW/le5VlGy2o99ztDeNBJOFrXwrGLP7sjmMg76vwrzWi0Vbk0hseYhmp7Yz22wqvyZOFwEmwrnzrtZ5rw6jEt1uI4hNtp9cblI2G0fUA8dgen/K3yVX/0ykIicxCjYv+U7/X41j72yzMYbmzVq7w7Gpvfzoy+td6j8mz/hL/9f7qMvUYBjtX15Xgwf5Jmxv9+2hmmn4Hn/w+pfnhCmxBvYZ1nHfMuDYF2yxgOy98KM9ud5vjcxmum53OmPBuvTS2O2/z+qfKsevvH/e5xnKH7To+vXqK6xlXBcF7OeZ/h+ij49ks9Stv7nIwLU+Ublfva7kz5ZrrUqT/i22F5P1PmaXv2X40V4f1wVK+unwzStiqc9jle6vqpANXntV6lP59VBQ+GhwmIoxWu/q/wGPOHQ+Ihd1Oy8/DbMc6ZBjs/aqvimH+P5+6cphnSWe3rsPx2zWpU2/nVQ5kecfywkTHfqu8cY+2j8sKKP/Ojb+t6OG5hQnlW2dB4THVcFb57ozFJZ86Z0TPbrcJTODmm8ThrXd/XOvKryoucRx2r/R6UOqfxtDE9+Gy31NFYUen1/Uz5pqayPiRKxH6p48/428p/5APiuf0/Gj0THnUN6lztR7gKowpvClzkhw8ZOnysYxviwAzh6afKO4Z8vI674nSFw8HoWZX9UwxprX5zEu7af8Wjk8ZR6aDySecKcUTUta84UsdU+a7jrTqC7VQectKajnn2GD5V5lS+WXFxqjwfywTpY5fjdGLbY5yaZjiuk/iYNDqW4eNyGszqc2lO+fa4Unkgo78tVReoYxvjTaXl8fzG34/5RF3L+m110J6kJ0nj4seYZ/i3snC8znVuR6XdqdG3lV+N2zkJp+rYnHOdp//L98ZwqrqYayzOO3bbecgQD+qaV9qv43SewmkcEatrOF6z8XpLe85ZXrjHcfyrNFRxdo/Hl4+M0SbCVAH7iONenMoMfTddvlM4juuPmc0jchjF/qhvRm2c9n31NPp+miFi+bNPPHV1XBAirELtoNQ9pAXV/vB7OeThAkmhmgam7sHR/6WFVl8CfvffCb/7twB/HrYOEhqf7d/cbq8GCnRNgbDvOl6RcLwmKkN1Tfx2DLeTYFmJyb5VwMZrXhUfGCoPdS0UsJa6XjKo2pZjGhs+tb0657Fgrf094jj+VXzw+XR5XvGfUf0KhyqgLONxjWFsm9UwqoZQxdfa79QJ7YzHXtur61RpcYwL9m2pXuU630pLY5iPaagKqvGYK7484vh8Ks6PGbs4UhWlcanrVPuqMB3jPuU3DPs7aZ71G+ntJDo7Km2M6XG81lWonQRfYfJoVEchfY7jazqmnzFu1LmM8amuARyf++Ho20pP9TvlQaXZ03DHn4o3Y2NmzJtOWhuF8xjeFa/HMu4k/lojjZXPqgScBMMqhyq+jXHu0ej5mB89Ygg3641lWqWD+p3G4Uxpg9KGtGQZ88kKizHu1blVHBeH69gqHKtD4CS6rGt7Ei6M4eU4fF+jefZd6a86E07CmwrXistjeeM461qM2zxJRla6q7hyEv8f881qaNf2x+M6Km2ehHM+nxn9P5a/Or3qGB5XxuOuYzjp/5N497i9Kk8Oy7uaVjmme0bPKO+cb5UxY5k05hNj/j3mb9arpeozY7lZ+6/P6hzq77E8PE2GjHFijE8n4VXlBf5faaeWk3SuKucqjj4q34z7rzAa/4zXYCwX6zjGa3Ya/MY4Pj369rR2TxrzSeUjYbQ9SbtUbpl2mstlhntuNmkT+RrJHb1KLtWcJSdQLfT/52iX1r1Fy311z8urtPurFmi5wk/TLvV7jZYX62k/d0h+6zLNUPoJss/lbXLymGHOSa/3VZJPvtnH85PESn+blnv7Hs1wfJJ2IaRtXe3/QzzUM2QPnOHaA7IXS8Rf7fP70b8F078bePSHuMR/xaU/9Ne/t2vyU9+CT70GU+8lr/yLNGT9FvEa/Dg5Zeq7tJxj+9kkh1F8juyJutnn7eEFd2in43ihrV6eJZqBeYeGtB+n7QmYY+jBukG7wPCbZJ/hVXLSkMx0hbaG02TtZ0s7+7QrEA7JBYv7tEsbd2j7feb7N87rav/2iJafbL78s+RS0F1yp4/97fe5vtDH/wvkAAlx8wtkT9xbvY2vkEMIbpNL4c+RA0iukNMKZwnDvNrhtk48n1/m8QeRbNPwRZqbIvQkM7zc+3yRRh93yaWWiwW+m33Ov0hOeINc6mu/a+TC+bkyrnG61as0upj0Ma6QU6u+1OFzi+Hl2ldpm3h/joZTP0r2FV3r9SbE6+jdYsul3y+TAxs2yB6UOXJx97iskJQS6f+wf+/+w6/R8P4WYcrX+5jmext3aTi2RKO91/o8v0Zg/RbZb3SJdmmnsH2H44c3rfb/bxT4rPV3dcNz3aPrPpA12rp8jSiz36Th1tcKLJbJvWfSzTYNzuv9/1eIQNrs316k4csq2RNrlOiQxlfGl7h/p8PsOg0fVwoc5QXT5FTY18pYljrMni+wnvT2lRXfoa3fTJ/rjV7/Zwj/lZ+91WHS2SpP0vY97vexbzC89+kckWsvM7wg+xY5Ufbn+nyu9PEd9voTGm99vny7SS5/VUZcpNHoW+TOn6W+Bnt9DL9IvNjKuecLzK7ReLjKyEWy1+spQq9Gs79Ew50VcupyjbSZvSDuz9D425sML9deodGMPOskuel+qivklMNVsi/teXJ9jsbu0zRcmu9tvEmT+9douwq2O+y+2Nv8mV73FbIPd7nAcoccRKKCd50cyLDF0GA7R3jI5V5v0se82ue0QcM908Q01L7S+/kO2WP8Tm//i73ODm19NnufN/rYf64/++Eyhyu9/W3i5H2L3McmLsiXbxLF/xGN/pf7t/LYHXIQySrBqZf6HN8ge/mukz1eV/t41vv/831+i0SmnVbu9HGYCTShybJXaHqMuPJJGj2O0w/H5TaRSZCDZ+o+qyNy4uZlIucmNNy91uf4Gjnp+F0abA9720vklHQ6LN5hmOGz35+ra0Dki6l0tdzs43+1//8Gw5Nvd8ghS9dJlOj9Ps4LNNza72M/6P1d6r/l4y8S2F6h4cKEHKq11uHyIm1tNmnrdIXGw9SVp4i+4NkIn2Wosx0QfeyL5dk3aHj5SbJ3Vhp8kYZ/m4RuLEfAX+3v1vt4lJ87NJ7wDLnM3HKbtj6vkjVbo+nvP0x4iri739v7Zp/vk31cF0ftzvWx/AQ58f4Lvf8/z+nlI2G0Kci3aZM/JGF3nx+Szd0TwtS2yaWeR7SJbxHFebP/76L6bIfktd4pz7Z7vQnxtkxKezu9vS1y34kCuda71+s41jVCaBvkgkaNr/XSv/XpfUwYIqZpK3cZXixbPRrvAJ/6GWDuTzRs+xO/Hf7rPwd/pXe+MRzneh/7FrkzZJ0outbTmzAhXgLhInFvlbm6phdLH9UbcbfP5Rw5jMGIJMQYEOZ6cjXOZcTrhMm6BmOjbbP8vdXHsUZOaqwpjzUl7YgckjMhhvgh2YA8Ntqc9yzB4Ulp3/V+VNq92/+f7d8Kb5W+qvSKJxobGi7bhCFv9HeTAjPnMyGKyjph0iqyMGSwF8lhNOu9rZ1Re36rgk//fq3UE/d3ep1Zhh5L5+N67vR2t8nmYmlYWjV33J9JqafjZ5rg8gHDu2QcMwVm4stm/1uD/iQlQr4kbSigNWQmBMY6oGCYBy9ctohA2yzfCmufaZSNYVtTel0X5yUeqSBB6OcuEZIqXx5Z7HweEvySn0kbk/JOB5Z0ID876O1sEgNms9QV153DXbJOztFvNVC2GPIC+fEcoU0VbD28Gmwq44cMcWq9192kCdz5/rf8RX62SdJe5okzpeKoBioM076kdUq9dSK/xOlJr1NxuX4rDe8XmNi/dENpQ7mqjFSuHPXxu8bCU9rcLTBT3kEcIOtEDss/K02fZLRV2VPpz3XZ42S5qRxQiZ0jssVvFgpcDhme3FnpynW+X55Zx7akh60CS/lX5V3uf6t45TtTzNRvHhH+45wmtLWtuoS6gbRSFXrx9pDgxqTAquo/lUZniNEGQ1w5KM802sTpql9Mejt3yWEkGm73GepbDxlekzRT4D1P1kB5ekDkx+OMtrulXQ1X9YUqc332YUbbBsE7eVjFdQjeyc812u4T3qQyvkd4gka8MlteUL8VZsrvHcK3ITLsJKNNWloj8FRmKTvtw74f9vYfkAO7lHvSo/hd+bh6wAw5tEo5po51sYzJutKyvEBdcZbQ2thoEyfXiINaOMsvpwltrhO5+z7DA4GUH+KFNEKBz0mwrXqPa7be679P1nue8MO9EYzUM2txnNLffYbrfVr5SBht52mW+h6JYOg1E0mPaF6HbZpH4yqxaufJfRYL5Gbx5zh+fOpzREhe7H09TxibHr99cp/KPrlrYUJSE/W0iYhz5H6IGWIY+qwq9Srv53p7nyCn7ng3Gb2NN0i05QrxQs2RE3dUGFWYL0NzCV3pAPnpPwd/9Hn4u/8I/Lu/FXbbBd4i9Q0ifBV0N8jJapYZouAvdhh6H4bvdhneAXW9w12kPiBRIz22N4gBqMICDR+eJQLWuT/PkMAULq6DkTjLfofVYRnrw962wkYmd4HmYarHqR+Si4mvEXxTIZxneJJUnbfGmz9zBWYy501yR9hsaWeq/3+ZtpxPMzxxiQ636pWU6V8nR5k7L+cjDUzRcO8ywWPbn+nPP0buK5rp41w8oT2Z+iIRZlc6DFSo9WSqHDmucaTtOXLkf3WeLPZ30OB+iWz21kv2v7/SHn7jbzXBvkCOE54wVHweEG88BWbSNsRDLF2PyzQ5vVNa14iakEyASp+QO2XmSJRpmvAkBf8N4qXbI9cQLI1gq7JM6Ut4XuswuEbuRLpG6Ex+NE8UHfqYzD7Q2Njrz86VOtskbfsaOQZ8mtCrCt9i/+YSURAUvhpt8oTFMneVuVkazmrEu7YqPZD7hBTSD8jR9jcIrc+T+4dUjG8QhfR6f7dK6O0akS3yg4XezqSP8Vly55j8TMNh0r83WqYC+Gwfj4rAFaKcP0uUqvrtPYZyaLbP0fmbLnW5PDOKrAJtVOS53tZGn/fVPq6Z3qZ88ilCB7bn3WjnyJH/4odjqIrqLKGRZ4ncPdfnKW84SW6eI5E25aZ4s1tgv0H2zV0lfEmD7nr/WSORXtd7hfBplTz1iCWGkTazEq73MXmq3VEft++NMl0ma7tLMmemCU9YJrLyEzRa2SOnL+q4la4mBW5TNJx8vs/tPIlu7ZNrBeYJr5HPKpufI9FbeZaRNuXLU72etK4hdtDfVZzaItfBfKLD/x2i06g7LJAsgnrdw0nFd/KBCaHN6iyR/8DjDyKBnCoOwwi59Q5IhLce+a+C7nUG2+ROU/d51kib3/utTo5xpO0aifxI3+rEtcgbnyVGzPX+vyeHzvT2PkEMCzO9lsg9bdVoWyK0q156j2S7aew9Q2hInFIXOyrPpkp780Q3micy37JPw5FL5B5NdUT1EHH07f7NdSJLn+X4kf8TYjhL6xDc/Xhpo363w3DNlKHyGh3Z2iT3yzjVHZYYFk9+Vjde6f1/gseXj4TR9su0CWhpV6+MlvohLXw5IUcXz5dvHpEQ5TI5zn+519dzMkuOa1YIPVn6r5GbHeK9mO39P6AtyCqxpkXCSe//9f79cunzTUJot3u77/dnMjQXbpeh4q73ROb3ZG9/g+PHXasYfQP4yn8BT64T9/JP34TLvxX+IPAF+NzPx7Pk+FeIYH2LKLr2p3E4IZ67hT6mqT7nFWIM3uu/9epoEC72eelB2e7fCpNxWe5zn2cYpXG91shx3XO0NRgbbcskBcNI21vkuFeZ4QJhKPTxfZcQorikB/Q9hoz0oMDqPjlifEKY7hsdZo8IPr5NcM3UD3HLyN37JB1Nger8zjH0PL5NPKzOy/k4nvX+zNTXO2WOU8TLfNDHWb2J4/Y2GF5zAYmcalhsEO9Shbf4q6KzSA7BWWcYiX6DXAUhHMTfe8C/td7g+lvI0fUalQ8YXieyS3CQArN9EgWY7/MVjuOyRniMtA65TmGnP3vU4as3W6fULPEab5I7Im/3dt8qsL5NjnLfJIrHEVH0II4GcVij9155do8hv5OnyuM2+nzfJIqbR8W/ydCbLp6osEijGp4qZUYgXffbRHBXow3aWiwwxLNbve4WoZtH5XujG3o8l4lhYVTjgBhzO73913vbax3eM32uBySF1kibPHCZKFfyjJv93TxDD/90/9Gw1riCpBAd0PBsmXjIJ6XPHdraH5RvdWJWj/Nifyd8psl1LcpV+by8TL4hzDRgq4PuJo0PPiBrv9fhr6xQeVksdU6LtK0Q/F7rz6XrCcG9sdzUQTAhDjPx13WfZXg9RXXKbfV+3yVyR6XtHbLeGog7fc7Kly2iWAt316eOfxxpm+9jqdcaaEBv93aF4wrZ6yIdmL73ZF+HIxoeGGlT36C/myGyZ5bIrz0i17f69/L2AxLdcG6rZH+OOsYqcSjrTJCfKhd19opT830eGnlrxIkhL1OuaHSfxG8t66UN11hHwU2GfH++P3+c0absU5+aEJ5kMRoIuZCa3reRo3nCp+SZGkLK8h1CwxOyhYfRfOTb8PhI2zK5PsH/94iOtkt0gS1C66YaL5Csl1tEHiojlEu+rzzedZ8luHxAruhQdgtLeUE9Mn+WYWoqvQ1l3UWCf+pF4os4Sm/fMVS5Sa9/k8jBd8u7HRqt7BBntmWFbJNwze6VPudJxt8iQx6r4QrDVE0Ivb5BeMJ3GEb0TyofCaPtB8iFkRcZ7mmDLJb7fRZ7vSdJaPYyyTG+SAPkxxjef6L35i65J8domx75S71PieoSjSnp+ZwjUR09fiIipd4hYYh6tCQ0mZmRiwWyH+8CiUJBW/wnibdzqf9vHxLb2Gj7KeBPAT/+7extufq3YeFdeO3r8IeB5z74e/jJv/HX+Ekv8/iz8DPfGl7IOkc8MAr5R6XvxV5vkaTzbBOvwn7/+2Pl/0cM7ws5JPs3xvC81N+tlj6FTzXaDojgn6dFpGou+kOGF3QLq8tEmXNtze92DY6IJ2zS+79MLoFXiXB9naPjXC3j0MP0NLmrZ5OGj5f7N+eJw0JGt1R+LpFUNg2dpT52Fdh94tF1j0RVfueI59t+Veo0oirOXaExFulwrEx79PMiw3S1uvYKAkodx1UVPAjumS5jyooedpXli8RTXeGtR1SmLr6Iy3vlf4XjUYHZfoHPk4SuT1Ii9omSWul/ijDgp3r7zuewzHGW4WZkeZIG8GUijFXk5VUVthOGd5rpFafXvVzq0/uYKvVVdo3c+/+V8t69b8LCfoTLhd6PBnedj/M71+svEqWrGm22VXmiY9zqdZ9maOCOjbane//vE6V6sYzPokFyheyZdc9Wxf1L5RtxWuXHcapoCp8pTr9c20gEROG/Qhx3s+RuwcofJ6Nvq7NQuAlvDWbHLEx0BMrPL5H93cJMHmek8AJxFFwq46q8RqNkkdwtBacbbTtEfujB1qC2zlhuyreVA8L+gBhRjmWdRG0vkXtcXfPx2h6Onp0vcD9P9JFLJKVrgRjljudCaY8y93myl3uJpBUekpRJaeciMYido9GbRWIUSlc6CSzigHiifHhA9COfiyuV/zxFHLHSsbR+wFBXExbyDtfV92Pj4GmGPGyJ8ER1isX+bZXh46JclqdO9z7V8eRZwmIcVRsX11McEW+rPvKI8AX5N8Rwda3W+7unyf13R2RtKw2r9IsndT72A4m0nWS07fSfy/27eyTRSlpT37nC8LT1eRKFPiCp8jC8y1NcuVP+V05eKt9bb5/gj2tQjTbbnymwqut9QC79VgbJX2YY4uhi/+YywdVKixCnMTQYVz1bY81nFVfU8eqaiXtPEx1DWWXKqOOUJ9Won3M/6m1A7IArPL58JIw2GJ7oImPwb58fld8H5W//V3moHiHrccKzg1Gbh6Xu0ejZYflu/FPnUMdT2zgY1bOtKYbjOip/M6o3bq+OewxDiJA8HLV7RPMoPvfH/1ok9j98DmYfcfitKNfjcVXY1L6tMzV6B8fH++iEZ3VNnOsYVkccn38l/oPyrK6X5VH5/9Gojv+fNC7nMF77R6NvH5WxjNuo302Pvh/DxnYqDKdHMDqJJupYx2Mc49SYfur6Wb/2O57HwSntjenl8IR6j06oM6Yhf1cl4aQ2K72d1OaY1sdwPImOqvE0rus8x6XSxrjP2n7FGTg+rorjp/GP8XjHa3BQ2vbZSTg3hr24V/nn43jxabRxdMrfY/y1zzpHCA/x/bivyusPOA4v65021zFs6/e1zkn0afsHHF+fcX9jGmEEw/FaVV50NKpb1/YkmhrLknF9YTmmvTGfr3OofPwkWNc5jfnoeN5+O3XCtyfJO/s+rf54zcZwOY33HpDTHsfrNNYtpIXxWnNC23V8df3quzGsxvx3jEv1+/H8TtKD6pg4pZ/H4dZJuo4G+9Goz5NoaixDT6L/cfvjNsd4W2n/pDKG9Unwrc8+zGg7iS+Kh5aTxjoeS12vk+AyphHr1HGM+Y9jmObkUuX8mBYqrP1ffnCSfKu8tMJhvI4ntX3Su5NklbStvnNU/q5zGuPBmAc8IvKtwrLC0FLhY1uV74zpwDKmlfqtfKL2V3FhiuO4QmnjNNnxuPKRMNp+hRw6sE3SW/aIB+GQZiWbqnCeBgxDtFvESzGhAcKNkIZm9UBMiOd+ttTzWxjehVP7N+yvZ+WQpH/pzTA8O+n1H5HIHOWdaUOQ9JQdEr6lPNO7YjTEb4w0jhVsev3N/myLRA4mwNeBy/+nFureBP63PGL+h+Ev/hTwU3D3TXj67+yN78AH7ydUfkQOAFgA/kcmck/D//vtFu7dKrDbJgd5CDOJYLP/nieHgei5FFabfcwP+nezJGfdenWdXQPhDdn4LXxcK8fkes4SAque4i2SErBdYL7bv/UuMBjuU5slqTeu4yPiBT8guLDdvzfNcUI8fZWZSRNVIE9IKo9RUWnJfh3fIcGzCcGRaZJKAcE510+8F2a2BzkoRm90xcF7pd42WefKKGvEB4YHSAi7nfLOtaieUCNu2wz5xRaJ7gi3/dL+Tul3m0REtnrfRyR18CSh6VjFPeHpGHfIAQSTAhvxY5bwhAcFZlv9/w0C6y3aGjjeCtstwhsUGq6lOCtuwfEDfw7IviD5sekmMKSTk/jZpPcpnOU18lhpz/V4VOYsPRnhE34Vzyofmyv9/Qv973+J4LH0NWF44Ixw2irvnL/rtUn4+SY5xXRCUhBdHz3Nc+QQj7EMGEfadgnfczzSlfMSpx2fuLw9+tZxHZCoG0TO+b8wEZ6uj3QjDITTHMODXR4SfKyeftMEHbvzV+GHKFbVoSYePmCYDiQPqbg3xjPlgPJN3rlbxiLf2O9zOEfw2z62C8x2yrsFhvJBnUNYqmeIp/KE2f7b9uq7qQ4HefwRSdWelG+Ua1W/cN3qfCZEfh4wPAhEWN0btev72dJv5TX18BT7FN/l0yqYOx2m7pdSX3vQf5tKfI/QufSvTFQGyS9sH6I0Vx41LspII5LiQcV9x7LB6QZPbU+5BOHpVR9x/OKsay4emyWzTQ6oEG8PS/1ZQsOmo4/TI03t9xv11ar3WORn8q4JSdmekD2HyptHREewP3F+UsZGaU8+Lp80yu7f5wm/s95Wee/Y5AW285DQ2lhnE273Rs+kfeEhvglrcd5D9SwThraG7covhE8ttimtQXBPnJH/uYdWHlt1grExVse5Xdp5HM7DR8Roe0QLyW4zPLJcRiUDXGEo8Oq+CwXcLNkjsUxOZjFMu0BOmBFZl8uzsRFlf7ZXFXLTMURCDb3l/l5BO0PyWyFpTzLoWbLRXeVuvtdVeXTx94hgV4BrNI49GvYr4/db57pDjkd9E/jit+Ef+9PAH4Sn/yzwx/heEvwTC3BZK+AQLgvsOXJiCTDzdoO3Y6gwrcxf5V0Fd5+c+lRD/1MFLhPCWHwnTDcZno703qidA7J/6zwRUKtECZUBOC0FoExjUsYn89gnJ37Zn4qpntq7DBWRWdq6zJdxbfexCK8NImhmiFCekBxxPTwy2CmiNB2QfQe1X4vPHac4tlHgqLKmISDeekTvuD0NWxVZiLFjUTlwngrsaiBDjtFXCRN/d/u7jfKsOjP2yGl00qtGtcqWioeKl0beUYFZpXOFnUrMuFTck09A9vmZ335YxgZRbCt+TxjypE2CKxAa2WXoWPKdtOF8qkKs46I6VOocVISFs+S+QhSqjd5H5WfOUZxyHeTfRwxTeSckTdh9IPIwjTYIT3Tuh+SgoocFPv/rMg4Ir9yn0a3KscIUIrzl8cqKbXKojO0dMTzB03EKb5098+Q0P3n0PYaKyqM+lnmiwE9KX7O9L3Hf9D7XRZ7gtzsMT1GbEHqqss8xqqypTAvvqjR7ErPPTO0T9w7I2itDV4khNsfJKc/To78rfjuf70duOkeNGhVC1+KIyLkD4s1WIZsQfrtb+tuhpYbKk11T8cc1Uj+xzarQa3xX2oLIMfUUjcxqGE4I39skfGqV4f79SR/fEQ1vj8hesgcE18QlRbX4I98RhuKKfFBHzyzZezSOJAlvdbJK81V30jkjjB3HLuFD8mD73CF71x9naMl3xQNTNJ33hLYedzl+YfJJRZlSHRIw5LE6HXRmKgPVE6Wzu8QwWytzPUcMw+3y7d3+t/SoUa+jx3euyRgu6+SKGnmXepXrrJPJ/nUizBJ5fEAcbPRvp2hwVLbcLW3qMNARY/ADho4maaVGDHV+qZvMcxzWOgWWyzN5YIXHZn8/SwzFKjcta4TW1hjqKfKL/dE3lU+JR+OxT8ocbMNxSvdjHFSnfK+3t0lLPd3j8eUjYbQt0u77uEW71+MyUVLdOH8A/B7a5P5LWt7yJdrGwjnaKTBPk+jPAu3OpTdoGwynaTmpX6Ddn/A6yV/9Un/2BjlN5j2Sw+pplL+LGIpv0IC7SIxGvXQ/0b//Th//HPD7CYK8RQ4qmeltfIHcb3WN3Lch85/pY32a3IV0h3bgiEghYxXpZvtYVGCv9b6+0fv6TIfDaofVK/ROvt5f/Hv/BvBL8B/+4ZZPqSV00IGwSEutfJXvbWL4+38GPvswp0eu0u40eYkc3nJQYL/S//8E2XBdPUnP9nF9vcPS0+k+yVBgLtPuD1HB+ApDo2KfdvfOUW9jvT/7aofxW+T0z8XSDx1+N3v/N3vf1/ta1G/tb5+2Ni/28XtXjsb/Ag3nLvS6b9Lw6beRvVc3yd0ts+TkyCt9fFUoHNJObzpH9qrs0tb+KmHMMg2jGBt9nC/19qdpuD5PIgNP9TZeot3fsk6722SR4cbajd73N8mhOvTxvlrqrfY2XiMCdpFhWh60e1kWyN1CKzQGt0hbW+GzRIzta7R1+XqHwY+XeV4nwknBJXNfJgLpa72dnf7dMtmn9xwn72lbJkrzHA3uKvpv9X5+T+/jJqFPT9ybo8F9vf9c6XP8Zn/+Owis3+htXCJ3b9Hh9hZh+CqrKr2fICdjrvbxXS9zWCFOKBVPhdpPEqXoGzTc+t0FFh4QsdnH+QzxHK71/z9DFAVPH7vY5+iJbToo5HmyFefuHGdpfqLXe9+eMFgVgud7O98i63y5t/cC2dc8ITglHf4EDfe/0dt+Afhpohh8knbHjzLgGYIj3g32+d7+TYaRYJ0IP0L2qljvxd7Gz5B90Cp23hf2bu/fbzc7TBaJs2epj+91smn/qb4GRkO+xfHTI18sMLve57VP9ve9AXyb4T6zHRo+fLmPfZngZnViqWhKZzM0+v3FDvsr/flyn4886/dwXG6u03jn0+Q+MY2HnfLsm0SxvEr27Wx02Pxon+fPEP78pf79T/e6nyUOxptkn+5Oh98FokBe7/P4i8QAorxfICdlXibG5x1yDcVP9H7/IpGVP9H7+TY5oe7t3v6XaTR1v6+PzqNnaevt3F6m4c9tcvL0Jrk/6w1yGM4SDccWO+zfJYaRDsGb/Vt5rIrwpK/F5d7Op2kG7mtErt4gDqGrNF3u/T6PBYI/ysLTygo5aOigz++lPu9v0vDkLvApGj0+zgCkz6nqUzoyK88/IveWXiYyddLH8vH+7BdoNOx9jmvEebVETmyGHJohjegU2KLJnOvl3RxDB7Hl7T7+L/Z6r9Hg/Cwxnu7QaPoGkYGrRI1b6M+/SRzBS73v9/u3L3UY3SOnR05ocmWO3Mn2EjlkapVGqz/C0DmnvjBL7iir631A5MSX+7N9mnyf6bBdZLhGL5PDS77KcB/ZIY3fqKt8hsjPnQ6z6x0+tdzs8P0i2dO22uf3cofbXXKH4n6Hyc/1cS10eCwxLH+hj+X3dbj9bJ/ndeDPcHr5SBhtposZrtRztFee62WdkDC0hKqXSQ/bJkFIw7QK9FXi1Z6iAXV11D8k3VLP8AENsDulrkzViIEKoUx4k0RjVglibZQ2Znsba+Qo4llyeMUewzQ5yHG/NTqoLXVIQsLnief3HvHyVfg4ljW6UahbZB34F/93TWr93j8E//Wf+P+x9+9Bmmdpfhf26UxldZKprHpd5aSL6im6XDOl7ihP06Omx707mmWY8SzDLIslcZEEGF0wAQITMiZCgIUIE1ZgiYsDkMEQCqMbMgK8Zq2LBRLLLutVjHaYZnZbPVHRrepOspRd6SylMnm7cjPJqtSb7T/O+cz3+f3yzaxeCVAT8IvIyPf9vefynOc89/Occ+BfJ2dMT0nYqSz97D0Zrq5pNG8y3Bj+tHTztMO6wzB6Re/uww7jHonYTBimDRqxXyT3YlTBZnRQp9ZI4RbD5W2NkMNSV1w7n49Irr/G/SrZRKvA3SGrKPskGnNMaFn/9yOyCrNU+tNpE47KK743sm+ky9WxDwn9Khgp71zp1NFboNFtVVaVR0xxdbqnBUe75K6RGjhYYHgQi3NZU0qN5lenbYtEW3c4e6eWPAxRsioEgzwPSn0V3ZSkj3oQQF1p+7C3KU3sFjh1ZsePfGiU1FPmhHufrMoIG8TRl0ak8SqT9gitQOSZuKq4lTUhtGK9NZJ2oaysYzGIIQ/skxUw+xAnY3n2kFzIrTyclvLKs1PChzpnjvGQODeOYZuIGsdUo5vSgHxWjbK10v6UHAgi/Ti3GnzS1D7D+7sMAAon5OQw8e1Y1hjSnnMqnoyaHxCeo8AizQsXZeybZaxXSl15+Jis0JwQ2a7TB5F10ryw0/EyYZjq6L6TRZqjp5OrvtGRPyYrU49KH9VpWyztQWTclJwACsN7lp5nSGdVBrtK6Pw8LP3WOdNpWyInTSo/H5Io/V7BrzbE8zR5oNPv/EOcNuGArCYL/6z85mrnFYYrIK5+yW8G47QlpE3l2GMyR9LySX/vuFwd2yS0VXl0iZygvEh0s6qf3q4Hpe2Q1R9X/6b9tw8Zpq+b6qes+ZChvj0u49sjdOZ4HLO2zLwgmY+rS+o7g/ybhPcMQD3g2XvatsnqOyTlrtojTwntnjA8PVK7YIUE6ydEb56Wtp4f9bNb4Dsm6as7RA8vktWo8VjUNVtEdq30fnSqbUtbUdqTb1bJXOm0zUp78qPptAahpkSPOY5Nkj233/HiCdXKAmluuff/gLMHkchHm+WdMtX50vaGyAhx8XgOnrTFtEthqKvGNGebWwx1k++U+x/1/k6IvNAmqHV9lGX6C9qAz6LTT4XT9l/Tom47/fuEGFZTkh7pIYdG3VeJQXZEJv19cmLeBlmm1CF7lxhCTvZ94uBADFBX+pZpnriRSiPTqwwjxJZTULjE/S0iyDYZps7IiKvkiHCZ5phEy6fkCPKrJJVHY6emMEAiLo5nm8bI94jzYFRCo+cH3i2d/yxtufB3/istBPkPA/8hLcTwXaIBDQEttojEfaLgVJwKJmFco83zDvH7thgeka0QPyZHF68SQeC4IakBkPxq8U3v973y+5TGXG8xNEIVuqskMiJ8U2KU7ZKVw02GzK6w0Zi5R5xBnQedKA2szY5S7yx7yFDITcj9ce92WBzfrHzXcD7p7W2SVKPVUt5gwC65b2ix96uCWyRGoSte4m1l1J6G/ibD1MmxAlBgjvHtfPuIo+o8qVg0DhWY0sFOf3ePYUrZlKScaWgdE4Nzp8AozjRMdMh1EuZFaxX+yoEJmZMPaTLg2yRVVh6tSqIqExXZux3ubxNcb/Q2Vns/rqzNaPOm0VX7oOBxq7wTZghvVsdCpeMJXCck5VR5NmOYHmla2iFJe5oyjNQf0OhrjcaTVf5o3MKQF+sYxZdHactXPgskePEuwzTYNZI2NWVIUxsdJ9/ufbxHHL93iSP1hOghVw51wO8X3E87LozGfocYSDpJlHIHNLn1XhmjQS6DmBrwta7OnntPLpOUXHWq86uBe5/h/ozLva44s10dLleztghdQOTzKrlcu6ZHqpfqZ0hWwEYvf62/3+FivakBqoG4T1bPdAo+KnjU+NcBXyJX9qx0GJzbA5r+2iFHttcA8naH41EZt7JLPF7t/TrHlN81Tif9Tx5Rvk7JFQfOz4xGN6tEz6wxXLlx3NoOEJq/V95puCtfdDSk5T0SGJmWsemgGKM9IQETx6Q8PSRGs4GTE9oVBfLZQ7Lyc0ScgFNyb9gKw7v+5j27xKE8ITg/JsfST3vZ6kCf9zzscBr8OyAyycdA7TG5lgZypP42sUG1Mx4Q50O+3iE8fEBksfJPp0r9JP/odI3HstX7Fl8fkBS+KcNtBgbKtWOkKWmpmoDy8R4JnEpTOuJHxHkyWG1G2pTw6THDVPE9km0mHsc2230SkPbdPWJvS6P3++/y+kcMM3787T6xVRaJ/jwktvA2w0ebSDxBaO+I7OX196f9vXJcO2aN4aM99bO9vQ+ITLro+VQ4bUZgFT71r0ZdDkfv/KOUh5xCc8jwNLilURvz+nKV6oQYdyoumegJw/4VZvZrOfum1GHUhkwq7MJ1WMraxzFxthSQT4lAEo5qJB+TlY/aJgUXjvNYANQ2T0rl3wP8X4DfQnPgXqbla9wj3DjC7Xg8dSyu4FT4/L2uuozp4Glp07KUcgqEo4JvGM6V5cft+9Q0BQp8Yxo9GtW1bcs8GdWrfYiyOpZjEgVzzwRkX4B4HLcl/1Q+sj1hrA4RnOWDI7KHrc6BYz0sn8t0D8Zje0/L++cZRpjm4XuJszgc08U8npUWpP8xfo7OqV+NV9/XIMm8OhQcjZ9xG463zv8hZ0+Rcl6WS7mTUr4qb58qzypP+5uwyj8no98OS5njUreOoY7/Uh+HbVU5WWVbpYt5+HP8s1JusZRZJHRX8VMfYTPo4Gq9tLJQ/sv/VWaM6WfMK+PPVS46Rh2Psez0GdPeCS3dbp3mDI5xQmlLo3OM1xlDWpqnH8bypNKP5Y4Yjs86T0a/V5kgbzmv8o4rbbWtOrcavjDcc+vnyovj8VykN52XOlbLjduqcDknz5d2npS/Ou5xn1WOLDC0C/xbLGWrXKrjXyztHI7K+t8ARNVX0p0wLRE7pTr1VfbOk9kVZhjCUn9TL1eYq52jHKvtjm2i+ru41tGovHE8al86q7rovOc8Ph6Pp+q3i55xf8rDsdNW8eYcVxqh/K+24FjHzLPx7Hcsf6rjX+0eShtVFknXlQYqfipuINsTpMPKp/Nwe0yCzvZb5dS8fus4qoz2GX+v+vJw9E6+gCFvOG4dp/EzptF5cnS8IvaklB3bm+P5Htt0zmmtS6mjXHrC+f2Pn0+F0/YcQw+8fq6Pvy0847f6zqfWu+hvoZSv/2sb58G6OKdOrevvtZ9x/8z5PMbHGAfzokHjduqy9Lzxfv+zFZSgteIM+N20ENiXaAntv5m2AWB/OPbxWMbz86wxj8c+b27HODivvTFOar3zYBrT2DxamkcP9jVG3Tw6Wuxl59HSmXk5Z3yzOeVqP0ucxU2tP6aLMdzn8ci89s6Df4y782i+PhWWir8xbPP6hvlzM56DMQync95fRBMV1vp5Hp+OcTAPhvNgnkeLF8nB+swb85hH6+9j2GobGvCnc34/jz4ukuXjebHsSfk+HuO8eZvXhu2cV3fMX2O+Om9MzKk3hnPM77/3gnbHbc0bS/08xuf493HZCo/yYh4v1d/Pg2OsEy03j2+eRZvzZFn9PK+dMQ/XsV2k18Y4GI/7PL0yhmFcbrySdpFMOw/GeTRQ56LOB6O61aGYh9vz4JnHn/NoZQyLz9i+GON7DKs0d97cjuvOk/HnPfL5s9q/KM3S5zzemkfHY9yOddU82X+e7qs06Hgu4o1n8dZFPFF5dnbB7+fhpfLNvDLzcHjeXI/5aV7f543vIlnzSehnzDfz8D0uP28u5833KWdxMa/debx/EQ58PhVO2y8FfoC2XOgma9MQd8ky7DdJnvFN2vLnfVr04RVy6S+0ZdFv0NKd7tMQsU7bovUtsi/qBm3D+7fJBndoy9Xr/e9+b+9XkuXet0maikvWpmr8KG059R2y/PyjZIn358lt8Esd5i+TS59vAj/Uyz4m0bcXyEXWN8i+rWUiHGu07VLH2Wnv6yYt1WnS4fwBkg729f6d14jV9A2y9mtujFLlOyTU9Pu+CvwS+Hf+E77yR1sTNwse79I2A2+RKM96H8sH5FCEd3rzS0Qp3aFtZnafwVpv+24ZN72d5V7PuV8mj5GhGS39YqfD8Q2SFmOK06T3c6vXnZFNtfdptPZSn4MD2kZt03Hta7vDeKe3t0suBl6lbYye9LLf7e+/Ri4rfZe2iLlIDiIRZwvkMAcV+02SVmlk8WvkIBLTThyPaY9bhOcWSZqBguR6H+cXaFO+TdtUu8bwgIhdshdoUuZindDyjOwdkm6XyWb+ukr8FbK/6gGN/B73tr/e5+M9Wvxgubd3s/+t0eb2qyQF6CWGe0WOSer1BiF5cWaazwZJs/gc89N1xJm0983+/RGNpvf7uxOSskWHabWPc4Ps0bhOo8tv0ejgRwiulWeTPvbXC+7eZhiRnJG0m9t9XLdIGvhNwj+bHSerJEVzq+PMTeCmEh4TeTYjqVX7Ha6b5BSxbdpBAz/AMCVniZYS9y2SUmuAwTF8ieGBN09pvLbcx/Od3vdthrJggcajB7TUE494Xu84e5mkvU97++qKt/tn04nvkINOdnvbd2mHk7zdcSHNrXWYntA23T8i6T/KNfXaF8lBBDs0urhLowXl0A1y+uYbHb/vdXisu0ujMVP/djteXyeHS0AOrTkkp/MZ+VbPvdzfKftuEoP4WsfPO71vV9pcSfg6Se83jVtD2TbMGDCt714f69fJBbMf0OZYvfkjRK7+PJm3tQ7HyyR187iP7RUin4xm3yB671GH9cs02lklB+l8ubfp/L9J0uzk83XOHkRCb0v5PGV4bLrteQDFdSJ/lIm7RG/JBycdPxNyUNfVjqNZ/+2EHIi12+t+jsZza/3d62UML5K9Ttf7b9+l6Y4nhBYmfSw1zdTVgPu97tfLOA5IOuALNBp4rZd/q+PqcsfTXn9/o8PzkJxJcI0cNFN1+PjZJOna7gHzkKBvEVp5lTavY2N4Nnr3LtG3cPYsAetc7/2sE506pdGgtx/9GXLwzD2Szvp8r3eL8PAebT413F2l2u/1ldOLHT9LnNVD73Rc/FBv5y1yqMYuTeZ8SJPFnyUrOlvk8JeV/v7bhHav9n4fdji+0N/tkovTp/231d7eC73cfbKN5EWaDKtB5K2Ov6Xe9w9x1mY7pdHCDxP6U1e8WvChTn2NRn+7DPUmZIuVtsobNFqh4+ct2vzd4ixdfI9mk6z3d1t9fB4eZVr4NSKHtEvWOqzrDJ+FDss3ie30Vdr8fOoPIvkltImReBSK41SxddrALjM88WaV3FI/IUb3C+T0sYX++TohUB2Y6/0386ihMZJtXSZKwmVkncM1YqCelHJHRGmsklPuIBNbnQRhFwcv9LIrhLCvlfFcJ5uuV0v/LlFDTgY7pTHWC+fgZ0oU9/eBpr8waVjN5aYXufV7wB/7qUZtf//P8dfc++Vc/V2t3dMythc6vDoavnvc4b5OI1yNDw1R5/Vq73JS3jluOigq0NXe9lgATMhekuo8Ogfun5EunINTsidEpakDpaDS+Ibs77HMFZLKtdzbWCd0cK28E27pb5Em6K+V9ibkeGMdnUn//rhP0WIpbxuTMh6F0mMy90tkL4KCdULo0X7XCx5qexp8awUXlZZrmqm4Xib0XZ02+1gmc0vBkw68414i/H2V0NQyw3nWcDZdYZE4edKlvHVKI/urHUb5f/xMSd79Si/nWGxbBWcAyr6kmyk5AOcKQ9kl/UNk3pUyXgMc2wwPpznpcC9wlg8pdSHHmq/1dzNCS86fMu2w4FPZAqFDYV3uZaUBU1Jm/bdrDOWrhr0wrY/aOyljlH90Up5nGLlUdE0ITcnX6wxTgyrdSF9Lpe/Kw/T+rpODPZwn/47776dk/5c8WIMZ4nVGTn2UpjUAlIPrHTc7o7rCL6+c9O/Szz7RfS8QY2JCDgu50v+ke3EknoS30p5G4yVCD6u9/SsFXsietqWC82XifNXxPCan2C0zlOPKS2GsOl8n6lJ/51wrb672+uLIfi1rileVseptYd8hMtF3fhbHwmPQxEfjTTn+AglcaaQrW9URi8TuucbQwK4y7oTMqcZrldnKP8j8rXYYK60c9P6cvwnDw238Uw9OiEy8xPDwscuEd5Rp8vsLJMA16eXUx+oV4brIaXvc2xTuGeHNayRAIm3DcHVnnPqo7pNHnb8Kg/aD/WgHLhE7yjFoC+6QcxmUe5XmFxieQiqfVPupOm3qsfrs9D/bVD/4fanDIF1Ib+psbZBqJ0GctirHJ72cNpnlVsmcvED2v08ITWnbOUbxLT9qN1B+n/T2TN9U/ohreYve95TwzdXSnvRukKPiR/vIea10oa1R50wZJA0YcFgnsks4tbXHTtuEpnO1DcZ9nPd8Kpy2x+SI1n1yOpbREwn+x8jKxiZtkNvktDWF8ncYbgJ1Y+EVEtXcIIpxr7zrWX7f3yiqFy0jH5Goig7ZAsODSIwmbzI8WUdCeMDwcASV3fM0b9/TZCArMQskiqmTukuL4mjoaBCpMJaIQaeyXyUHkWySzZeHNO/+/h9OTvMbPx4jd4dE8WbkUJAV4O4f1PD+5fxrb8D//Qj4J2ihwQe08M6L8K0fb8dJz2jlr5CDKr7bi75LBJTGzBYtkvQROR7dTZ4+jxhGyg5Hv5/0Nui/f0QE/THZaKoilQF9tsidL0a3NSI2GArSExpNbfdxfY8cRKKCcwPrSa/vquuEnIy0RQwCFd4VGo1MS3+n5GCPfWKQ6rQbAKnKx8joDi0Cp9H8iBbRdg4+IIefvM/wtL6VUXu7tHlRsUCuJ/DZJYeaLBH6l059pmSvl7Qnzo4LftYI/WuEGYXeJ6cP6rxqHFSltUP4Rpwdk83U0rl8OH5cUVMZqfA88OCg1z9leNiRfLhENowr/w7INQAqa2h0ukUcko0CxwOiRB3Pbv8uD62Xd5W+NczkHedTw1sn0C2s0qXjP6DJcQ3dAxItfp+cHqns0MGtB5HoRDuGA4bBkErn18lBG8pRZcZiH+sxORTimDiHrgxOCU0dMORD2/ig/3+bRN6VNa7QarCs9LE+JfO5XcalEX5Eri+ByBXlyDvkmH33LD0gJ6y9X+oeMLwyYUqO3t8gh29dIQeLHPY2jolDv9ZxJc7u0/hefLoa/IAYcjDc27FMm8tVIk9g/p62hQ7P+ySaDlndrjJrrDenxEl5jziA8vW7/d17ZGXPOdK4Vn9f7/hWHkKb6++WdpXd2hEat08K3qHxxqTXtS0f9dIDIseVP7ujcS31NnSQ5BXpY43IEW2jIxqt2u82jVfUPbtE3m/0Nh+TbCVtn1lv//0ytofEJlAO7BCalNerPJ0wXAHdIDyy3sv+fG97Uvp2fDoS8+Stzy45FEa63ifHsRtndvzPerbJIRdw/j1tGzT8XyF6ThvpOsmUWe7tPSAHrajjDRZYd7N/Vv45nm3aHELDxTJnUwshB5EckIyZ9wktHpEVve8QB3yXYQD1KQ136qhJ/+8q/7vkIBJXYA+JPjfb4l2Gd9teJbrMsdimfL7DENentJUxg5q+U9duFnx8u/++S/hJR6o+Hi61Rw4fgYbz9/vYxk7TNqF1ncN9YoPoa2gTKYe+V8a2Wer6fJfYtPt9XAboLno+FU7bLyGREb3jQ3IhLrTBvEhOtdIBccVhvbyb0BDxIomqL/Z2XyQTOynv9glxwXBVR4X0Ik3QOUlHJCKmYl4ld85M+/9lhnfbuCn2iCwNv9Drvt/7vFnKGoUxArVKjNBqsOi0GW1b6jDP+t8NcuLmau/joJd/kRjD1jfqN2W4kVSGdxVwnUT0330LXvmbgP93L/CP831qfrGXrdEqaMzlXDkeHyOfKszV8q4qdIhgXuHsHS+ObUZOFDrp5VwZU2GuMZxHV4iMKhuNWSdKa+y0zXqZF8kx5Tr3q7T5vkyOZd8l0f5lckqVjoB8cY1c1LzMMCJ2qcC6zDANp0ajXB0xwGAqi0bVhKGzuE6jFVOTr5MT4mp7kNVScS9/2fYiWTGo+Nbg1qhz/g4JTS+S6KXRsglx/hzvo47Xm4RfpRdXlI4ZXu9gv7YhDqUXaWqewoSkISon6OOc9vcvMjzAwL6WyXxDosXKpMPer7iWVo3mVtwq6yAGlqtD8oxyw/7rvByTaOmlDudS79/gxnZv80Zp55ThXCo3dL6kH+VGLbvL8JLi6rRdJwYcxEBQnk7796ulvk7GDWIQG3gy+m2kX1pc63j8iKSMGTiRhw2gOJ4XibEqnKskaCL9HjNMCZKubjBckbSdFbKa6OoHJBX7aFR3n9CDtDkhsl2ZPSk4OSJHeKtX6u+7hF5OSpsHHefVadNQr/LW6LhlnBMDi5Asml3ORqE/InJvrDdtTz2g3oSswolHAxEnxDaQ9pS3N2iOQ53bG8QgvE54wv51po+JY7NI5PcDhrQIWVnSTpmQw0go5Vxd2iDpxG77MPhzmcgsedO5qeO4SYIGlSevFTxoa0hnJ4QWHJtwVKftkKw0rJaxGCAZ09SUOPPS8oQ4MJD0wQnDzKbzHm0RZap6UhsPhvIULl5pM1vBPp3XsdN2jehMnQKdZ+lRZ0j7wro6bZWHp+REXUbjqatB6hf1XX3ka22WvYKLKdELL9DmW3sOEgDUHtgl+mhS4JKmdkk2g/JN+qLj5SZxUk+IzaQsXGBoBygTq812QjLwbO8p2RYknyvDhFGbqOpNSOZMhUk7+6D/9gLRqRWOA8LfkIQz53uZ0K5zUQOuNximakIcRnXphOD4oudT4bRBHAv/fHc6KgPD1INantFnOL+t8W/jeqflfzWoThm2VQXzvP4tPy7ne42m01HdcZ9jo7biqrY7furYxngbj22Mx08yF/Pa5QT4jbQE4d/C97XKlX/1Yjj9r0Fl28+qU2FYZDh3zyo//j+v/mxO/TFuFMjj8mM8+n5MR7XemBYYlR2Pa14b82A7bzzn0V6tf9G7Z/HguI/6v8JVnwrbvN/n4WBMq7ML3s+DcTxf82A+r+95sI/bPY9/znvOkzfjfs8bk/UWODvHFb/1+3jc82CtvDKP1pnzbozLMZ8p486rO29cY5jGv19E7+NnPI6F0ffzaGEM70X9jcc3nr9a9jw8zuM96431y0U0w5yyY14b645avs59bWOMq3G5ee/n9Vs/L855X/udR3vjts6b83m4fNZ8z+O3eXQyD/55eqPWnUcLY9zW3+bJ4bGtMM9mGM/tvDlwni+yE8bPGA/jts+b8/N44JPYNufRwBjPVebUfsftjZ20efbIeXJ5PI4x3qqNMI//F+a8O2XoRFyElyrva/nz5qOWqf/Pey6SK+fR3Hntj3F2kRw4j3/n2UTzeGPc33ntnmdjfRL5PG++K91cJHvPg2/e86lw2p6nbZqckc28rmCskSXHu2Sl7SbJvV2mbbg04mm6yOdJeoTRps+TNCQj1a+RpfWbHaZTEhWb0bzpV8mqiFH6CYkeTEs507iMIrzKkGEdkwdEuPF3o8Pw+V72iCzZGyl3k+6EYepmXWkTL3fL51sdPy7Jip+lXu6YHNRAf2f0eIlhGqYRoyu93ISk152+nYjP5r8Nf+MbwG+BX/XPwa/ahNnvh8VfyvdznD4+hef+Z3D4X8LPcDaNb5/hfSI3yUEkCrMVsn9kpfzuc9xhm5GVoONezoi0ERPHVWlhqdc/IZtVb5B0O+fZvpZoNHmH4V0lywW+CYl4fUQO0zGaZpT7Uu+rRoHdH6PAu0kicK5S3yGHQog7x7NXcOrBBgvkQnYVldHoz3c4nyeb/yej9rY6juRZyKZty22RFRbTKNc4a5jdJXdHrXR4lAd3SQS4Ro1v0ubG1Rv5dYc2X8sk6ijOXWlW6L7C8CAS6Xyl43Ne5Hel4Ez+n/V+D8l8O5+uNtzuMEl34kM59ZjIPXFt1NtV14pbSMS8Gl32JX6u9N9eKmNYIysH9RLeS2U8rsI8IfLslKR37BO+2SerYsozVz3Ea11JWiUr0aYEvkL2JjlGZdltsu/jFkNZsEijUVPZXQlY7zi7S+66m/b2X+2wPe6/uxpzp8OxQ2j6DpGdx+QgksuEn18lKziusrtSf0B4HXJfp3wlX7qaOCO0fDqqa1R8jaxeXiX8WqPkdxleru3v66Pfpx2nnyEr3FdJaucL5BAaV1jukkNUrvXyNfNg3krbAo3WXib6YoWkcs3Tm0bm1zocr5BVzuOOW/HoRclPafrSrQU7ffx3aHSkbF6iHQLwMlntvEvup5LH1hnq/8pjL5C77KqxbYqjdop7fkzPXSV6+HmS6nxCbIOnZK+Ydo106yrsbu/zNo0GdskBKGZKuKKx3+GQlp8nq5Ly3iUia0/JlQ+uAGqTHZDVPnEkTbkCOunzcrv3/S6Nd4TnhNDvhLMrL+NHvaEOnpZxT3vdS/3dq1ycagnZt2if4uv5/v8y8Pf18W+SPVWU/m6RVVF1lW0ru9Z7OXl4nxj4ZmBpi90mB6KpX+attOmo2d8Bw4NIXKW9SWTnMUkZ95AYeUhddY2kZSrHpx1PN8gWpptEf6nznydZYjeIXHWcV8ghaau9znilbYNGC+o5ddCl3p408H7HoTq62lg+p0QfVx4RX0c0nXh7hNul3u/LZFXYcWkj75BtS+JQPXe5l7vK8Nns4/08TWY8JDLpoudT4bT9JdrkmZ4iIx6RvORTcmmfhvyMMIvL4YdkA+R2qa8Ruk0TqAc0hO6VcgeEUadEsdjew9K3QhuimD8q5XaJMBMWGU0DxzSkU7KvbEpSZCCpBZeIANWp2injl2lPSErUE3JxsA7DITm5abvAuUMY0PZ1CKcjPKokfDROF2l7E98jAmkbeOUt+Pyvh3/0twL/ICz+Xlpi9U8AW/BctyBX34O/9TsMjkbaeRv+AMn51+HdIQIAIpjo8JmSSHm3Vz5PSW7+EW3unhDFdczQkdgldLNPjExpdOy0TckGVnGnc/iUXAp63Nt9TGhYg3FKaKuORV7x/iyDCksMU1lV4F42ezBqY0ocYpXGvH6XCK14SfoRw3tQbOdx/y4NWtdHA0lF61WANcII2Sel8BN/Gm4aUmM45elTwq8awUtkDnTaDku7zrOOr3yqMbHD/AjnDklvUU7Z1pTsjTsp7cHQWRMv04Iz5cwjgmvf+Yxxq0zSwbGsRrDBBxjS1C5Dp0246/yJM2XHUqmrozejsa/ycdrHaWqyODAoIU/VAMVhafeYYXqRdVfJvjTHVudmUvoXFuHVaJ8SI7PSlLJDmp4QvSNczs8x2aOq0Vx1gM7vIpHdBgRmpT370vCVlqXN7fJbrbvf+3ja4dgv5cUPZC+eenVKZJzidpvILuF2XpQnFTYY7mMywKf8rE6b+rc6bban3IMhrz/hLJ05bzNiZIvPilsdPx375Y4j5UGVC1U+7xH6UM/U3zQ4D0rbNXBIKa8sc+xPGe4Lly5r/zoN/qZtoBHvoWwfEVmoPpaXIHtupAF5dEp0lXNcZftTogd06iseDd4ckH1IU5K27Z+2inpun9gnBksqrUu3J+W/sv28R1o5InM7Hvfj/s4AykWPdOG2HHVZDVa7X/qAoXy1b20sZUO1sXTaFjsO5OEpOTAIhun70ihEHlS7Z4yLnf59n2HKtjA59/KoOqM6a86FzyJDOS5ul0u9ld7ORx1fjnu/lFV/yg+75bcnzLfZpjS62S7v1AHaCNo94uEjIserjSJelOXa/hC7WMezPsJp0B5yIbynRvrfQIu07TYD+aA+U7LvudpWFwUq4FPitLmScND/+9k9XzLMZ2mDvE9yRA/I/ixzWK+TqJbCb7G/v0ND4COa53ujvNtmeDrMeq9j1OQO2ei9S/b1XCJRacstEgfQSNcy8fYXyFH+V2ge/oQmFF6kefX0vtcLjhy3UagHZG+CAk/iWO44kwHtY4vm/TueU3IM7Fb/P6N5/EbRFaRLpf1Jx+FtsuKo0r/Zy5zSIrZ36MB+qyP6716B/8Xvhf/k1zUH7g5twjcYSKXrS3D7JEdXTzp+XKWQyRfJvpOVgm8fm56RTfJPejsysEa00X0jHidl7AdkxeImYc5VEpFzpcCozVYZ0mqH7zY5yGRKjqW/QaLYOgLOvfnW93o/ju8p2fvh/B8XGBXWbnzWEND4e4nhXqf3iMK8Tpu/l4liuUVWI2t7C2SjfV1pu0McGg2+LaJA6rHZ0upt2jxN+/cTsgr6WSIYr9HwfolEEaVh6XuVHPk/JasNl8leFZ1MV1EPiZCeMOTreRHb90kk9HYfqwrzUq+rQJd/6pH/s9JulVMHvT2jdBpFV2lyoeK2BpKq8QONbhzbcv/tFsN5OSYGlTAt0XjptP++2fE1vv5AZXOlt1sNyBs0+pGPDLhcI4ccrBCas57yyrGfkD3MrpA8oc372Gm7TTbyX6LRyPXe1kulvDQlrTzqdZf6WG/13+6T+bnJULfcIivPGrt3yOqPRl9daZPXIauct3sdZbq8OyMrJYejuo/IgRLy1tWO7ylxzK73NqSfh0S/rhNaEmc3OXvk/7TDo6yB6Glhh092eqTGzDaRU/RyGmXLDOV4NVjXOhzqHghfKzseEifnJpFLy0Te3iaH20BkiAcquSo0JXuM1xmutEkXtzpMZsaMnbY1Imuvk1V/HXqIXrtHsnFeIqckrpT+T2lzpnGrrFkgPOfYbjHcI6uus9y093/S25f3dNx12lxdPqDpozuE13UKj8k+RWnK4MeENqe7xL6Sll0xNovgM1xswEpPhx1G9aSyc7G36bsqu+vc+MzIYS8LpfylUu5b5Aoc9xpCDrDzyH+NeM0a218m+HXcOov2V1fatDWkEel37Mw6J7eJQ3SLrLRNe7lbNPzbxwJZvVUObTPke/vSjnOv1k3iqCmDITQFcRDl1RrAWiZ2gHpTu8Ex/XyH4U5/95TQtHy+RDucjQ6HurTqTYidskRW34VTh0nZXunC4KIr6Y7raYFBPb5OgpvCudbLrTN8tOPu9PbeJ/Nz0fOpcNqeEg9egpEI90j0bpNEjZaIMNCpUvkb9dugEUWNbm2UvjQQ6zuj0DKh0d1jcqrVHsMIhU7blJxIs0UidjoMKrEPGaZkPKUpaqOtS7QJhERIdF5nRDDqoY+dNv8vd5zNyGlTExKhcNw75J6mnVJ/s7fxUelLI29KImfCruMkvumfP6QfOrLZAbgHvH0Et38d/AO/DH54Av+3/7xp2T0iJU/hL3SHTVwqaGRW+9ks/a6M8A1Z3ZoxNMgflO8KRA0rBbv4c+XlIcMVx21y5DskgqUTKW19RKMF01+ka383JeYSoZ8abTwmq6euLhj9VJDvEv7ZIgpdweh4pr3/R73fIzJ/OmfVCL7cx/2InIR0ufwu7+4RPvTZKJ9tQ/gVfvKnON8kp6pKe0YCN8s7nemqxJQh8utuf69DoKLX4BRmyH06ypad/nmV+RFO68gb8joMT7LaIHNtqpGGqRHMRwVWeXO3j1d5VMd9TA7z8TedNuWA7ZkS4gokDHPnt8iBIAcMZZHjOSKntVX+kmampX8dDGnY9BVhGssVnbZFEjTytMAqi1XyC+RUUflWGtIgUJ4JCyQlyLrSgzJ7jyhb7/PSyN8reJ6Q4ABEcW+X9nZJ6mN1Wg4Iz0FW7mxjh2GKlnpLXlgtddVZB7T5cFXk/YJbShs6Njq8NUNDJ1Onuq54OFfKeX/X+PP03S2Gqy0Q/l5keIeodPMhuaZGXlI+VDpzPOpeyErZVm/jkKRP1pMFIatDtr/V33vK3ZQE2JyDemKluDRN1OCYMuESWU2TVii/KUeekOPoj8q49onDrvOvjhL/po+a6q9cOSA60uDR+0SmbJUxqCMNCEwYypUZw20RWwxtixNCBxuE7533PaIfN8jWBFfjFogulc53idw9JoG0qsPHjzrSeZA/ql2zV97Nk93j9qQ7GGac+Jz2d5tkPqHNpfS0QtKvV/tnbQ+dmEXCw1OGp8w6no8Ybh2o6ZHjscg3BrfNklokTvV2KS8NK3ceM+R/YZS+lePaAfvl92mB7VHH0eUCk3zzoIzRNtUF2qPVSZeXpCPfuSK3WfBhH1tEVm8S3QHDDATtuGpnPyqw1cdxbJKAonbMBsnCWSWr1dodzvMGWcTxkV83CK1u8eznU+G0LZE7ZG4w3NOmx3tCIrhXyV0qCmJXodZIrvFtQrALvc5LNMRskRNtXqJNwhZnV9qMatnelCjxZZL3LSOt9PZmhJCWe10F0LT8V8G8xPBuE1d5DsjJgNfJPRk3e3/3Ge6BOmF4gektsg/mVod3k0Q2VPK3iMOpIXKLpG6pQBTGCnthuUrSWvfJvSjHtHl5CbIcOiOT9C/8uQbIP/ofw8d/K/ydJC9kBn/tArx0GqZdI6sGCiWIkadDd4uhADimRU9tQ0PlJmEwDTRX2m6Vto+JY369w/AZzq7S2deMrAhuEmG1TGhkwtDBEz0anPulzguEN9bJ/M4KOlUIKj2j5QrGSRnPfodZHNwgRpVzuUD20d0mqbZGrWt7OmnXOLvSdruUEw+bI3yPnbZb5Ch2x7RE6O2oj2GdOG1GJT8gEWpT/MaXaxshfExSV04Jbbmic1LG8xLzjYhZwZm0B1Emi4QPjQrPyIWkOq464OLsIdlfNOlt7pF9WEZsxd0ew6iueFvsbd5kuLpmXZ9jcryy8uT5Mp5DstJ2i9Cfzt4SOY1ulZz8Kf0oh5bJSVs6PipfHWuIXHHsTxnuHdFZuc7ZPW2uoG/2715qe43Gt9WRukb2Qj4i+0PfJ7Kr3qn0ApGd8tlah1MjUnqrKyl+XyYrLnTYHhOa3+jvXiRpVLeI81DrOl+XSWBvnaxE6txcJzJep1Ha8CQ86X6TtqfpZZJudY0EK9c7fK7uHhccyAvXOJseqVOj7DqkzX+/EQY4qzdvMTSiLbNGTsK7QhzIA7LyudXfnTDc06YjIj+4Sl5p9R5ZoV8jskhcThnuaYfIUSPqBhDoZVaInWIbByR4/JSsLq0TWaGu2CNH4U8JD58wTI1bLOP4oL9TrxyQE+9quT0iM5QrE5IRdMLQvpiWcmvEYZuSU8D9XefA1ZxbZB+V+kX562rFtQLzRY+y/JistJlt4Xjk17ExPuOs/LtW+vS3sSOxTpvr62SlzcCf+NAZeonoMG2mO+QEUevuETnheJyfz/Ryl2j4WeKsHpKvb9LmbLvgQtpV59wueINkM6zQAgpbDPdvjnljk8gN9fKLJDtD/fWUBKpeIPpmqfzfJIFLM098jguebpP5fJ/o+zWSLQBZafPztdLejMYjC71t7TMI/2hDjOlij0a39mMbzvcS4U0d2fsk+67W9VGGv0RWNZ2fi57nPv7442cU+W//WXnuuY//epqw1vHS4Dgg6WavE+O7bipeIgy0TLvvYJmmePSIXQa+TaKqK4SJNmmKrG7wXut1jDi/TvYEaGzUCPFhL/cq8eSPSl0J4SFDT3y5w/A8LT1yQibuKfBzxBlZI9ca7BEC1hCblf/C4niukujlEo2QjC690uvcL/Vf7eWOyIqBTptGrSkkMtsOiUTT67zQ+/r3gEufJ6G8NRLuWwe+BPwtwB+kTeI9+I9/Af6VPs4DctG0m+F99kg0bYkcVuEzI07bMjHU7zLco3OJbIydlPo7ZM6uEwV0QqKz1UiZkisO7hO60YC80/t4Sos0b9E2pE5IesNDQltuFF4j9wotEeGq4zMlaSyvkr090pmPQt4UDJXPLsO78lSuL5Jo7U2Ge/ggCnuDKBYIz/lM+9+DgjOd71kpd4cI/H3a/Lrn8BWyClYjj17ger+39UoZp4GPaoAcE6fZvu/2Nmq0zD7WmR+t3WOYUvp5YtAqA94gq0wnvV51OHdJrv1ah8PVmtcIrpVnBntuFjgekhULx2OkcZ04QNP+e1VoewzTJJ3Pxd4/He77/f9rBRc6B8qEqwwPB5jQ+N8AwwHhM1eclWGLJGikXKl0Jq+t97o6EVUGGqA7JkGoYyI7q8F83Nu/S4J5ju0+SeF6l2G6p/xwQuTqMk2PnDA8gKga7icMUyohqySmHSrTJ8SwMlCxw9BYPCSHZiww3C6wRVaAL9OMg2MSudaZEi8vlN/+GeA3AL+ZBFi2el81yCIvvUxWsVYZ3l82G32GRNofkAMFICsjyrex3pRHdPoNVu2TQzLqsfnVWDawcNDHcoc2d/eJneFhA/eIc+2qmk7R5f7dYIXwyV/vcHYvTQ0cKMelyymhxy90GO8V2F/tddVR2j2nHd4ZMball3UajTm2mwzTFNXryhBlu6r5Ogm8KbOqbaF95IE/ytNDhvupPMxmi/DIOrmn7RrDNHjHp202T976GEQQtiMaD92izf1jGr2YHvmsZ5fcNwa5mmlsR0yInTrOrlEWqN9eYLhK/0PAvwr8IeCn+jt52H4Mbum0KKcXGKYX1men/znOLXJdj07gPgmoyLt7xGla7n1vELtCvpySg/vE7YTIM4M0UxJY3yV6RAe2wj4ltugSw4UNOoxv02jhlfLOu92Ul4u9HOTwpgMa34yd/s0C0y2iP487zsRPfSputXOnJJ1SmSLtznp794nddYOhQwq57+6Xk7trX+79/3H4Lz7++OM3mPN8KlbaKjHWKIKOhxHUZRKtd3VrqXxWKFzqf8ulTftZLm3WPhcZMqhtLJSy9nHCWQay7qXSxyWaMB2P61Kpt8hwHAuln4of25437iXOPnVlZ8YQ/sXy2XZkWKOhdcz+VfyM8Tf+XHE+gLMWrJOxDPwRmof2vwfeBL4HX/rd8G/MwVFd3aR8Z1TWx6iP9FPLnjLEZ6UnRvhb5OwczeuvjrnSiZ/HdDivf9ubh7JKPzOGtHPC2blwjsfjGcNY+10Y1V0YtVvbe37OWBfnlBvT0pg/NbrH+K08VnFQfxvzw3j8Y16paVs+y6VMlQGVd8aP/KysqIpcGWCZ2n+FbUwvY/oQF5X+xrg9D5eM2hnPuWNwfsb0PobZ3y9xdk7rmE4Z0oCGQuWvOp7aPlzMh/P+xM8iQzhPOEuT/j3lLD7G/DrGQ6VBmA/HPBxXXeLpr5Bo9bz5qfLp+VE5RvCrI8bt2Pd4Hn3GfLoE/D7gx0lKV22v4qgGCOfJk0XOT48c07vvF0f9XJpT59KoruM5HbVb5f28ea6fxzwiPnUKqjyejd5V+WOd0/LbImfnxzbm6XZphVK+1rc97ZHT8n5c5zx+mScTrPs8Q9w4DmVKHY/j1H6YN6/z4KiyVTo/TwfOey6Nfh/Tw7jPixxARuUqv/jdz3W+xrJpntyWNma07ft/K3Hea90xfCcM52We3VNhH9OG/dd0/GrrwVm6892stMuoboWDUf2xDVxx4XzPk8PWmWez+Vvl5Tq+Oj/zxu8zT6/V32tfjN7Pk5H1ncE/cStfnwcLhMeXSUB/Xv/j51PhtC2TyPorJDpwRPJPXWmbkmOHXVkzIrZO9sEs06LbKyRt7lp/53LvWq/zBhHEtzpM1es2EvEGWZ1Y7DCukUmZlnIflnfLwBcJka+RlLWlXuc1cgjAjT5WSHR1iURd1vr4twmxuAKmYUSv8zrZC1K9/eXe50r/zVXMk1L/dbIqtUVWLE9ING2tlxMPpovW0yPv0CII3wImP9cEiKkRWyTl7j7tlvilf76N80d+KVz+W+CPfR3+638S/gxJMfnrq1YBHn/U6i72Mn9jXe6hDe7n+zKEKZ8f0aJ9j4gRdamM60avOqNFhFwR+CxJgzkkNFiNMCMzHqs+JacJrXTcu1KnQHqNs6uh0tZ6+XtM6Eej6UZve4dEcF/t82CKoFGzGdk0vt3n5mrv6wHDA1Cu0qKuL3ccPSKR8XF79i1f0uF9vZRzj4UKaZnQjpHchV7HtI4thscov05L+1kiUWNpzsjZCeHXXVrkzxM0j2mO1GOyx1DDQ5w9ITnmRo2Nqo2fB70tjSjH6wr9tL97SqKTM4Yrllsk/1+ZtFDaE9cr/d2ExkOvFtwavYestlrvJknN2u7vpG8YypJDGq3v0PD6RRI9NKqvPJvRZN2URFSvk4MaXJl+rYxbPhI26UWF7CqFPFLpbK2Xqbh7ibOGzO2CiwOGl2vfIbiWptQVM7LacUIOqzAqvdi/3yWnhV0nKXQq8DfIHpNqBEp3XyCb5F21uEMOn1gmqfmuthzQ6PBOqWua8wrZ0zYhR8evEt3nNQBH5GAZf7tCDsuBpH8ZoJyQ1bN1MveuQqkrtkmqqAbayegzvb5XT7xGUoe2CM8sMV9viq91klK1TVYUbhGZIs1qJD9P7IlXaTxwSvZO3iVppMu0eXpMbAo6vuzLfiA64YisWvmbeukWOURIHtkme0hdVVdOqRfkkVWSZaRNNOPsKXq3ej357W4fxwOyOjklx/KvkL1M10ha3RLDFUvtgyViT03JXsmDXs9VRzNZql69SVYqxNkOSY+Ufq4zX976bJO9+Ce97zt93AuEVu50OJ/ltLkqb58H/X+VLScdXldEVkrZamNdIhk1a2QPoni7yfBy7ep8qL8PyOE2MAwWjfFyhaHuWSSpfvuEzm4wvFzbvfwTkh6pc267i7T5eZEc3LHX8WA2hamsjwp+HpCV83WSwbBQ2jwltpcyxOeEZldcoc2f73RAlZeLhKfvkn1rVW9CAlB7tDl6mejPo96m+KmPNtkXyJxtd5y9zPAy9QmRsQYL18i1HfVRP75O9t9+vvf/Y5z/fCqctr/E8FhdGO47UXHtkNxpI0xTYvhBlj6XyUa/x6Uv38mQl0jqn3VheES0/Xtkcj0lScG8RHKXXQ4XVg+PsL290p/GwS7Jyddgote1nFEIoySOQ+WrAV8V4w4R3BLQPhHStqHAdgwzYnQK07T0c9j7EC9HZIPx4xHu9nr7/0Zpe43GAAqz6zQB/L1S95/4Bfj9fwp+4DfBX/NT8LVD4J8j2q9I08sP4W++RyTbG5wJ23zh5/rn5+GXfQQ8hG//Qhy4J73JpwWnkCsTpmU8wnhI6M13Ctx9ohyt60qm860DrHOhYPddFXLiu94vdlreLfR+VKy7ZQ6WGB4HL61PiRO10MdmuRoJlVamZB/kuL3KV8ckyrRTyu0yvHLDMVRFAXFKdSCmJE16Hg8vlT9x8KjUt8wBSaMyMHRQ+hZnx70dr/E4Io7F+HE8GqXO45TIAPlwj/BndfarTFjgLG+K6zpucQGh0ePy22kpOyVRT8dYxyIN6Nj659yLE4/8V545pxq2KiqN2mlp45TIbJ0zaVl+u0Tk6m5vp9KZDt9ywYXvqlG2dk77wjumqUcM+VBe0mGfFlwqn8W3410l86sOEDb6fxX6LkM5PiU0PyVGnLprhzgDO6Wu1+RobO6TayfGum+39P+YGGgGTB6R4+QN7smbxwU/Fdcaf8K+W945bmnCgJ+4GMs9YZwypL2lOb/NensrBZ/2u0r43lUGeXOJ0ESd54NSZ5noA2lbOQFD+q5j0+CsMFan7SnZO6bDq/6YEiNOOVX5wLk/JnvK/O2ktKMeUOdWma3Ml3+mRD7vk0MUIEEIDeLqtOkkXiKnl47l6WLHuzQ1JXrV8QnzIjlwR32gPL7IaVNvixOD/HXcjtmA80VPpW/KOCoM6mfxXp02eV0bYZXIlSnDldllgmthrDx1Utqx/+q0jcci7I5z2mF7nhzENCU68oTs1bI/bep69YM0/BGxqacFT857tXXUX8o/y9ZDmdRDj0k2irTvc9J/r3pO/bHIcOFjWvAgfFVvQqOpPYbXhtnuEZm/Mc1V+eycOTZ5U7tJXMqvyh2dsvoIZ/UXqr447/lUOG0fEwNWIjgm91UoKA7Lb06GSsDImBFEiGBwn4fGtG3WiMZReQdDxSNctndYfpcAZwz7PSplIE4No99kioPShjAJx0n5zWPlL3U4JCKIMjgtnw8ZXipomxU/4tPxn5Tfl0fwysh17M6Fn503+1KQ20d1dCt89qMCh5a//AM/RhKy/yjtfNc/wNApcwJPyvcn5Xc1hk8nsMcFBwpkH+dgDJ/4Wi7jO2VopFjGek8KaIJXy6p4FRrCJI7tZ4nhHFX4lua0t1x+q3it816dQ8eo0n2ezJ+/Od7aXp3fY4bG3kEpJ31U+O27Om06AOLbOo6r8qerSq7MaYhXflU5VBgdjzRZ+cTfq9DXoRo/Y9J7XN7XuTgtsNnXjBgcjquuCApHxZ8OiAaCT5U39nFc6okfxzSelypn/Ksw1/mo8qzKag3ao/Je2SnNHDJMIRVGaaDCXJ9K5xU/Y5mxOPr9KXHU67z6+0L57lwtMuThKv+k6cNS3qfSnjjQADpheGT6WB9ID+J9mdzFWHlQOSCOHEOVO45/nu6r8yWPVplT5Vt1PMZ4oHyXX8WdPA3DNMH62fbqeMa6cUxn6jxllXRV+briUadNmJcYzlvtb/wO4rAdlnfVPnGsvl8q7UFkgmWOSACpytPKV1XGKxusqwMqfrQbKq1BeM52pJuT0k6llaoDj0u78nMNECrrrF/HMZbNY5qRN8e6tPKwaWPzDOj61LaFp477SXl/nuye155wOM4qW8SP8+Rvjr3iFob40RldZj7/Q+bWufekUXp5U1DHY6n63Daq3XVU/uRVacHHPuUfGAaia3t+rzphNipX57jC5li0i5QJ1WGmv5fH1FXyqLpcGh3z5lhv+lQ+qbZJrXMwqqPNcsjZOXO+/S+M0p9Oaq3rM0/myI8XPZ8Kp+2X0rYw3actoV4nwJtO9RT4ERJJ9HQj71N5mbZ8u9bLXqadafFz5I6ddeArJKXqGi0V6utkI+UrHaYPSDra+73dHyUet5HcNSJc9ku5Ddqy7i4t4vJNEon7bh/XfZImJFxP+ti+0ssekPS2G+TUzBvkSHn7V7BKwEvAN/q7jYIzo2hfovk/H3TcqnRU9MK83+tvMlxN8JTFitN3aKtlLulv0ZasX6OlUakA1jvuH/TvnyObSZcIc79JB+4ne6e/FfgngR/7Kfivvtpu8z6mTdIybaLHCKeXWe7IWKOFWK7CN36u0ZAbXpfJyYimNp7QDiJ41P+bQnOTNj/fLXXtaou29O7y+R6JDK3S5uVKx/V3+pi/RtIM7nVcquCd+xdIJF2jSn5Y6jiW+X+419sr44KsvO7S5lWeW6LhQiNziZyU9Trw7T6uL5K5t73d3jecPT3yy8TZ/5BcmbBc4BobeF8lqc73abRnqsQ3Opz3GB7mcYukS53Q+HracXWLRAIVttPSvsbV18jhAzsdP47nFYarnj73ifJYoZGrKxdXOq5/pPdxjxiSdwjdbJAjrK/TyPcajd6+QdIy3urvJiSNUtz+HMMV8BOSGn6bltb7GdoczBiePOlpgqskMm+K9zd7m642HvZ3Ktj3CX1fo9HLXi+/1fv5EjEUpN0JOeVvlay0qbS+zNl72t6mObWfpfHNfXLPTTUIXulwrpFo73pv61VyJPi09/HNjttlGt3Idy/T+P0SWaH8PI1nxPctcmDPtY7Hr/T23TRfHYYDmly73tvbptGFKfLyxQ1ysJBpaN/r/Vt3p79TDzkHb9D4daOXe6HPgcbUKjF+Kl7E2S3aPGokXu34WaPpWQ1WjdVv9DY/6P1f5exKm84IfXzvFHyrL+7T5tiI81hvOm8TkrY96eMUt6ZvT0iw5AbhYw/ykdeXSSrdD5EUMHXktMPzbn9/nciRy2Wct8m87BPDVwd2tbdtSqArIF5ps9NxoVw/ouH/qx2n3yUZKl7y/A2y+nCV0OjLHfbV3u4XycFlN8gWgRdptPIWufZjvePQsd1juNJ23HHxYu/fVYIDcrjEdZIaf9jbV2fcJqvAN8mhPjNyAt9Vnn165AaNXjR4pzQeepNcY7DT32lPVdk9G32/1/8rS/aYv9J2nejMtf5eG8m0Ug8Ou0ujc8e3TE53rbTy3dJP1U8vMzyNWNkwdmbf6fB/rcM86X14J94Bjc5eImnQymdparW/nxB9uN7be0jsgDVCO8fkZMUVms54oZd7jxyVfwP4AYb74r0mZLnX/SHO3tMmPN8k9GedzxMaVe+9Tvip6k16/WvktO43+x80XF8j6fBjunibxofO2QMa7YmP7YJHaVG5P2GYAl6fRzTbQPr4Wu//355T1udT4bSZ5qBBKyOclvcLZA+Q71z+rfXWGJ4+tFbqr/Z3qzSE1lMCzd+WaGyzKtEJiSZo/68wjJwtj+A4KHVltDWGKXUV9pURDhiVqznftuH4NMB8PGHrpNQb91E/L5KjgBWgqwxxrnM4xvuk4Nj3wu7vpm6clHe75F6PtdKHTLMiwrQmAf4D4L2vwt/9j8Cv+gY8/FWt0e8SYrIxn6Xy3cEsByfCvMwQV3T4VjlLo2ulOX+HpDGs9XGtkMh1ncPLxFCudONn5+J5hjRdwAeGgsyV2Fkp73zV8RjBq/Qkj6m0pLl5tDLGz5MRXMImf1nONmo503B0QCnj9/Ny76PiqfYn74qfE8KvR+T0uKqonxJF6jvnxeiY8Emf8yK/q6UN4YPIA9/JRxq8da5XynjG83yltLlWylhO3FaZoYKTJiv9mIo0KeU1klfJapiXltuu47PuUulXI0B6MuJfaUanzeCQc1xl2CWSJaAjNE8fuK/Hv+dL3cX+ew0MiItKy5X+Lpd3GgKr/bO/yVvS9BrhmcrrC+Q6Gmm7rhqcEHqiwFN1V6UZ8e34a11xbp2D0tZY982bx6VReXEm7k0ZrzhT9rtyMGOIg9o3NNq4VNqW5y6Xvsb0bT+1HXEzT05L56dz3lX9t0J0svzwPJlfZaH9TAjdKo/UiTA8KVdjXfjVxTpttlllYrV9xIWfzVao46njUI9KI5WP5snsp2Wsqwz51bate5nsZ5K/lSmVryqv+3uVT9KUOmy1tFf14QpZhap1L3Laqo5wxbjaeBWvl3n2SluVrTDUgz6z0Tik25PyfUILGo35xjkSv7WudmR9HI/llElVlvhUmLQZhMXVrMov2lgV17ZdnULl1zy7Vno5ZmgDVftAHWp9+622hjiRd3yExTbFibiqOnksI8Y2HAz1x7hd7aXKmxW3Y7lbZfb4T724TA4WGcNiu2O7b2VOufHzqXDa/hLDvNGa+uD7Gc2bnZIDP2Zkz8kuwz1bJ+TCyGn/7RI54v6AIHSLRCP2O0wfkZOszKt9SG5On5JUGJmowrlD8sSFRUaoec7L5d0RWa3b7u8PySEHMomCc6e0scgwFYT+fpushCwzzP8XP/vkIIL90s42w1Ui8XjCcAnXfN3FUk7BN+2/ixNxpkLbJULrEcMIBR2ev36bTJqVtoF/69+E6/8m/KrfBH//H4AHpy0s4oCqBHBwkNDktPUpHp+SPWcnZL7EnxH7fSLM/H5Moj1HtHl/ROix7kMT94ckUjUl+dXLhEZUkFWgj2lnRoxuc/yPyX6QfTL3tbx/j/r7RXIZcU1PkY52yZ6BwzntyUOimFLXcjuERqpzZ+qURre0d0D2Lkx72UflnUr1EhHI8r/8ukMMTaPbxwz3PNi3OJNPjJg/4XynrfLGU7J/S1xOyYXf0gpkxelx6Uu8VNm1TXDtOx9X26VRaVBDzrLS7DLZX1f5bIc43lNCs0tk/sTZIZFn4myf7NdZJrjdJwdFnJD9nJf6d2n/hOHeYGHSGXRMyrG1gos9IgMr/ShPhcW5q7gVPw/LO2lAWne11MtRd0sbGiWH/c/5ddXUscpPT3ofD4kMFH/bHf/y6yXO6r79Ud1dIs+l/fEY6W2Jk0Myj5eIbFE+y8sG6BZ7+1VHikvb8848YTkuZercVgdDuSt9wfCia/lAGVF5ROdAvblbYDHqLSynNP7X8RIvu/27clD4t8k8Piy/iVttAo1hA6YazMIvLUL0tvYNxIZwTMoq+eeY4X4YYTolcmmbXE8iL6mHKw3slD5Wid5ZYmgHOFcPSTqbeNQpOyn9KWMPyL7WiquHHU/7ZE+rNP5RgcHxKBuF4yKnbYes6B8znL+9gld5ZnFUfzZ6Jw2ru6aEbi0n3e3272ulrLIJ4B9+Hv6rJ+0EVudA20xbTh6W/nRm6sqhbS6Uei4S1Mf5U5fvd/zIB1UWO//ytHS2SqOlukoM2deoXXqTtqK0RTLB1hjuC9Peq7r+IcMTJKv9+pT5Jtu0f9aOVYcu9fpue7CceKgHo/lop0wZ0grluw5apQvbVG9Sxqas2WGYfi5eTGlV/9Vnr8O/U+o/4uzVAOPnU+G0/QJJfTgmJ7AckwtwT4GfoAmSe4SYH5G0kEl/9w4hBJdKFaqPaSkCG73uQ5Jdt8HQOJLoFaQrxJncJIpSQjwihu4uOYlvCfiThNEeMDQOlokwc2waLsf93aVe3mjuVRoh3SNCZUb298Dw+NAdcuP8u0TBbxAB9JS2pF0Nbpee3SxZnTYjE8K+SO46khk0rlV+Km2jC7sd5vu0pfX7DAXSd4Av/CcdsCnR5FUC/KHfl7V7rc4/zVDynNAIw4F1rv7JjoMHJFrvXLucXY0mBfsmodMt4jiIR4XDBx10ldl4we+k973RQZ4QoadBvkTS9K7QluqnBU8zwgc63Scdv1dJgGKllK/KdZ9EVbdpcwBZMfiwoYr7REGvzmlvn1z27hi3iPKrQtO7qIwejtMjT8h+Og3TQyLQdoiRK/1/QO5Ykg9MM5Gujhjuxzgm6DTlWwABAABJREFUh+FQcKZfr5xZJmnWY+W/Q5vjGoE+7fVVbD9Jgjf2Jd0ox6aExmYdRzu0+3zE9Qa5n07+EbemGkMCI/6+T6NZYxqQE0OdFwMVKp0aNKC/N322zpkHvkgXylENQ5WzvH9ADJD7BceLDPcnzDhLZ95/tFFwUZ0IiBw6JvdUaaDU4NCUrDbY9gZtrhYZpvd8j8jkKU38iO8Nstq3QVYTlXuOa7zvbNLb0yDQUVKmXyPpffvEIdkpdackvVSHQboQP+JjSvTqfWIYK4u3+rv7vd41kiq9RlJ4J2Tun5QyOmLSZuVp+Ub6XOptbZD0S3r9D4kxVgMl6s0pCbZuESNa3Gr8vUu2DFwlvDkld3qaZq08XO6/mYZ7wNAZhKwUacA7zs2Os7fJvPmb+FHWTgiPaNge0Hh9ucOkgyYPmE7mXGnE6uxsEN7SgXuH7EPSKNTuOCB3HW4QY12bRx7fLv0oVx8RB8FxKE+rMeu8bJCgkTx5v8PpXY0wXJ26xvwgmY82mvs+DZzskZRtg+YGs6rsHjtt2zSaUY/XOpWWna8JkY1HHZb1/u53Pmn/b9Dmajy+TcLDB72MfUlbBlc2GKYV+r8+2lzqlg2iy5V/6gB533fPk5NVT8h9thC7btrb26al3V4D/jiRodLUPsPUVBc5tJ/EpTpJfMtr1WnTZFsl+uyUxhsLDPXGvV5He0Fbq65aqVMNOGinWe+Djsd3OUsXmwyzU6Q9A2xTwpvO3Xtk1VOntz7acX+y4GKB2F/nPZ8Kp22Flvu73P+vk0i+Xu5T4AdpRHBEctQ/6PXMEV4lxt0PkTSWxd7umySNZkLLv/0hsnx9p8O0SS4nVGh+iaExc0QUmN6+5aoyWe7vZLQJcQQlrDf6/yktV9hcWx2mJbIP7DJnj/xfJCtkVTH+YH+3WXBmCoT5uA96OZWETt+bhCA3+5hciZII13o5caxDeKO3sUVLFbhLVpdmBbcaCreJoqpO6Kt05NGRebk3/jJDT2kD+DdpicyvA/+n2/AXN+D/0X8/JlyvVlqBN9+P8PVvjewbpFe7Txj0DjlC/YDhMr9dbfcxu2/IlYjljntxZoRr1sG+ToxSBaZzv95/ly+k2VNy0aRK7Ji2j+EFIlB0eFyB2Sd7Dtd7XxsMDxNY723f7fUf0o6+de599hgGXcSFPOejMNfgEd8KSZXOmySV6QFxftZotOoWRvfOXCLH9Wocyq+75Lj+KdmAfUAzDg08QJuDmx0HBl4mHZZxrrvPZm9PAe143Tsz7e80iO3rFkkb0sDe7ThTJi0TWoEYNBMaD3nxNcQQFI8zmgG8QPYo3SDK/Wapq5Oz2nGyT1bTZD+NmGOG8myD0JMXsU+J7LpBjiY/Ic7JpP//kCGta/C+TuS3Y7LOZ0lw5RZD4xmazHncP087XtY7fK8wjAJPaPi+3MtXHXGn/2msQY6KnnRcvMgwxeWkt7FLrkBRR6jX6h6HXXKxqjy6RK5OmJGj59/r8Fh3j6QlGix0f5rO02J/98XSPyTqv06Or/bdZ/q4dMgmxIFa5+xKm7pCp25Sypww32nTOHmD7BXZJM7NeXpzt8OyTo5Uf1DG9jmSDqdBf52kXzmP8nqVh6/RaOuYRltfJPuvnJt1YghX5/QW2Y9vCrKPwanbRJbrTG2RwJR4dCXvacfPhKSmXe2fZ7R9nyckMGdg9TbhOcelzr5ecPwCjVbWiHN2teDVeTph6CAu93a+RBxOA2SrDPdJqtMdw60O5x6NxrRlDNJMyFUzFzltW0T2GmS728d9iRjWdzte58nu+myUscFwpc1nRvb8aRtCArk3SZrhKo2n3qPpzVOis24SHp4SPh2vtGlrQOw27aP6vNt/c4/zEg3Pt0mS0ja5fFzHQud6QqN3+V/avUYc95t93N+m4fY2CfC9SK4EEj+bZP/Yddq8VKfNOVeOf5GzTtu0w/al8m7Wx6dNskROnX+VrBx/ibOOknS/TZOp6s/DDv9NsofQ5z7Rw9f6u22a7yHvPCJ6+YQsNJkGerfU9dGO+xKxnb7YYfiDnP98Kpw2Da4Dhsaw3rIOyR3ikd6gEb/C9Favu0bzztdoDKMwWSAbl12oWSd3T+yQezagTeJ1IlzXaMpeJbnT21UpLxEH7A4x1CHMu1TaritzExoDTGje902yGfqAKMmbNAF3jdxT5OqZUdwZOUjEe0J8bx9GZl8mRuydDo8HEsxoym+VRlgaXEtE8U7InS4y9zFNYb3Yy5zQHJeXSRrRCXEGTIu703/bYCiUbtB/fFA6vUlOH6iW2hZt8reBL27Ai38D/O9+G/zCr2vhDK0EOfkEbr+fJXeNLg8U8CASHWEN8Jt9zDdJep2OPSQF9CUazWz1MS2UcneI0Wek/TbZfK0hoSOgcrvJcMFQHNd6nnT0Eo0vdsn+Rsej/ytdvFhQaaRJw1F6VDDeZngQyWn/rNM3KbiQvywnnxjUUImpKFxpk/YO+venZG5uE8F4jQQ/3GS92X+XXzWWlkk6zSFDY0Oavk3uadKpvtpxdYfzjQijas4tJLV4ifChUVTxrtM6I/g3JrHT4fscw6jsAbnrqeLW32CYymSbbrKWTm4X+JcYHkRimUu9f4h8OCTyzPkyiHCVGGXCIv0Ij8bgNWIorjJ0bITvKkM6MxrrBvvj3v54T9vniKGy3D8rO28TGSPMd8iq4GdJ4ORW/+0+Q+Nc3XJIDiKZkJScV0gakry0RAzbO+Quy7Xezp1eZ7PDdZOsfrxM0vRqXVf+lV06Vcr2Y6L7xMkRjf8OCY/rAOlE3KLRi3varpKVZ2WN83HYcVodRFe2YLinTdrXud3q/ap3F/o4jb5/rrRzwDAV8QbRaZBAjA7HQ8LbnyH3ai3T6EJ58UHp41bHnUbwHYbbISAHkRwydE5fIvJZWoThHh7tmxtE/lgGwp8G554S/TolzuoB0dsatwZDFgjPbXZYbhE6u0H20yhrpr3/4973HZJ9odyalc8HpZy8LnzH5LAVaWqnj2FCm1PvaRUXkD1HOnzaOOc92iKHxDF03NsdD7Pe/is8e0/bjMbn6i5lxNhpe5Hcn6Ypoa0nH+wQW1B5Jt2LtxdK3SnDFT6dR20N4dFJGeuhYxq9aHtqT7xMMguE704pr82qA3rMcMVundCmdtwWoTHtl8+Q1X5pCsLnN4j+lB8M8qgDtRHrmK7TaOHl8u6DjqvPEl1i0OdW/79A9IfPacfLJSITbHdK459b5Z2P/PVZMmfLxCcxmLJGDiL5iGQRSAfrDB9XBzVl7xOZdNHzLDr+H8Rz+uwi/719ZnPe/dUc738nfT8Ffhb4z/4s/NlfB7/0t8Lf+WPh7E/wzMPb//j89/P5tM7lbPT/vOe/K379NMrBCtM8PP3VnNsaZJj3W33+m8TtX+mYP2n9v1KYn1X/k9L/p/35y8XTp5Hf/sfnf3z+aj3/Q+OHv1y596lYaXtM289j3uuEYU6vUaUf759/nqwWmcKzRY4t/TbNczVP1Vz0CdkH9gFJSzoo79xsvkOLKhs1MYp5SLxoUyiMHhgFrvWnZPnXSIr9PCR7jQ47PG+RPHN6Hz/f298kJyNd7WXc/2BEzIjOaXkvPO/0uu+QaON9hvsB7pHovFGmI7Lk7MrYlJx042qnMG6Ro6ZNUXif4YbmCYlMz8jl2vcKnqDRxd/7Y/0HkblBNinVAZqMvUxCxABL/1Lr7HfQNk/+Nlr4abNd+7ZBoq3OhykedPi2SO75fu/qKjmyeYlhZHm/j/ftArr0UVc1Tkr/q2Tl9iE5rt3o9YQWrfxZckiE8D0kq7vHZN/RVbJivVrKuyqzS5vbCdmA/jaJhk16G6J8j+wNsj3IgRD3SBQXMu8+u73cfbJCbWpcFWKHZGXWg0fkkROy589I2yJtvn6ORt8nZBXgoz4m+de0o6PSfo2ErpP0lJ0ynneYn2LzkLbnCZKq7Eqp+1p/nLMbkt3Xt8zwMI+NDuO93vYywfUHtHTCtf7nNQszGv88Kd9nBPfbNJpdL+9q5G+HrCYfEtowcg+RD7KWfPqQ0JN8Y3qX4zF6a9TSCO89hnsTTGmDHIxS6Xaz9/sO2fNn+niNQL5b4HWeJ2Q/yZSG7yOyV3mDZC4skaO679HExpQczCDPOk91v44r9/sM97TJ94dk7wcktdios7R6jaSKbpEVsgel7rSPxwi8GQMeSb3Ty03IKuCTgp/Fgpf7BWcbtHk86Xi9TK7eUC5R2pN3TBNaY7jHVxyYen+J7B+BpA7tEJ0sb4z15pSskN7vY69jU5ary2YMV9mmNNqZ0ebV/YpTsj/mOySVUjlS7QhXQ1whhuiEtxge1AXDlYVrozZ2GR5CtNzbeEp4sq7AOr8zsnJ/TPYvQfYf/TzZw6MeV1+5Yi+t7JHdAzU9f4vIrBMix7YIPR+Vz121crm3/bTjW14WpreJ7rFvy7hqUW2B8bND5v2ErGJv0+Zwj+GBSPNkd32U4+rVw/6/wqAtsMNwG4Criev93XtEHmjPySPKvUmv+7iXET719xGx25SN6szxWDbJ9hPIGQ3um5LO3qPpyKfEThEmV8XeZXiK8wKRee+TfZLawMpO+eVqL/eQ7Gm7yvBybeXou4TP90a4fkrjw1Wyyv2UNkcLtHmQRt/qv2t3Tfv7aqO4kjoldpL687D/5vVP9dkiabiT/m63j08/ZJ/sDXTu3ilje0jS732+02H5D3t72hA/x8XPp8JpU6A5wBWGiuAJSWUxZefSqM4qZ495XSllFsu7euDEvHeQJWiVhsYl5JAEiLHhUr3taejZjqkj9N+ejOoK+xI5llfc2H+Fd6WUr0vO4z1tEq04Whl9rvhyHnxWOyyn/f/zxDm0zqXSlkziGGB4XP1KgbGOQ0UhzmRq4R4MdDy5lILjia45BFPgV9AuwvnpFfiXjuA/gCtv5WTBMQ06BzOSOmC5Oke1rk9tx99PGNLrCqEl04FWGQ6TOXWWyXHypoPVFF0fYZRn6ng0oCvt1flzDsb9VqfW9iCXco7heH5UTlyPaVpHxzxwaU/8LpU6q6VenfZKz36HGP/CVHllRgz+ynum+o7lxDzFX3FmfflQXNj/cmmjvlvmLHlLFxXX0l6lL8pvPo7NtLRKs9JErSstSlN+rjJEeqhj9vMJoWXbX2R4bYLtPi3jqrSgLNRgqLIDog+sKx7EU3XaDCLJd5VeKi9XQ8rxOs/OfeVhRu8on21D2jsubUIMEnHvuKpcqXpDnDme2rd1n5a6Y9k1hlmc1JSvRYZ9V55fJQ7XPF1Rn9VRO5U+5C/5w4BiLT+WpVU2LZXfnpxTd6wKqi6ZlXfWXRqVO57TXqVbx+EYfFdxUfX+SSmjvBnr3Qpv5TV51bpjmPyTjk5KO8cMVaDvVjmL92qvGDge2zDK4qdENjsWdUENts1KH8qC2qc4qLDY92lp0/6rPhs/dd6rXaLsFMaLZHd9Kl3A0I6SjrTHxjLA+nWuKj04X+fZF2OeMpXYNn1X9V19xNU8e+9peWfftmHQSnl6wjC1V7hq3covEHtueVROOfs8w34hMmXMi/NsqKrnfLfAkEbllzGfVD6rODhPf86rU+dzZfROHB9zdozKn7GMq+NTl5mqOpYN855PhdP2MTEkNdzmffbPZ/xeo2Dc1rjsvPZrmfHju9NS53RUfoH57VtPAcCo3OKo3dpP/VyNzArD6Zx658F0Mgf2Z+HihGF/dQynpUzFM8yHad581jYqTmznPsAfhT+/36I2K7Ro1uWrDKTXx9steiWT3HrImbDNn/+LcPpzsPIvHfHXfh14E37bBnywD3+YMLMO5Hqpvtlh+bERPupYFLoVB+MyiwzHXsvMm+tFzp+n8+Zs3P88ehzXG8/fGNbz/ub1U+uPabnCsjTqe0wz83h/3p+G6EW0Zt8no9/m8d4J8/Fa6b8+5+G21h/LJcjpffP4fZ7squ2f977+dh5eT0oZym/z8L3AcBy1XA0Sncff4/mYJ38qjBoj47bmwTiP7ij1T+aUOe//eAyU7/U3RnWrcz4PD/Pmax6vzBjicmlOmTHMY5wscBZv82TDSak7b5zn0eA8XJ9HN8LDqLx9z4N1DOcCw3bOkwtjXXjeHFeavajveXQzbx7q+7F+rrJpXvvz8GWZp3PaOg/H5/HTeb/Pq39eO+fRHuW3i+Tos/qubV9E0+c95+md82jkWc95OrC+m9cHDOes8tF4rsf6vLY3b2zj36o8qY9lThjafRfRznk0MK/debB80rZr++q8Ou6qA+t8n0cvFSZl71jHjevV3z4JX3NOvfN44jycOrYaxKnPbPTbPF02fj4VTtslsvH2RYanRxpBPaVt0vuItpS8Tja9LpONr6vkCOZbZNl+gZaWcIuc1DShbSy8Re64uN5hOqYt6Zqistr7NwVoSg4rMHJplOil3p+pCsu9Dz3wIxKFdqPizV73aoGJXsY0gfUy7hdIWqiRB5WNkZVLHRYJ+ibD43xvkdPJ3HS+Q47cvtnbnhJCsh9IitZLBQ8nZNM/vd6Lva9LJJXBgxQUYrfIxvQaNX8b+Bf2c2LRGv1Amf1hxGmLtkRuZPArf3EYtTkBfqZ/XgV2fwJu/AT8gbfgszfgt79NO+v7/TKwG73CKS3n5g/DTz3J4Rwv0ObSVS8jT+LvRsfNLsOVohUyFye09Ig9cqKUQuiQ0NZ6+Xu/t2/0blbq2f9xgfEjsmrhnOgAC6dzATkOe4mc4nWLpA6/WFDks0/D/UNyfDC93VulnHh6VD6vcfbIf/lBHpqRAxde6t+PyOmRi+T0yG0iLw56HzdJSpD4qXe2icebvZ1DhqvA8vV50VpTxpZpG5zpdaa9zktkNUr+kb+cB9sWZ/tkHsV1TfXz0A+fY5Ieo/B3peQF2rzdILGMG6VujVSbKnZKw5l9HJM7o24Relsgdy5NyKmHwiL/q6DqytRuf68Mu1TqOW7HPiMHDtwiaT8vMFxVWSSHyez23x6TUxKlBWX0hLZp/ZCGc3/fJoddbJEVkxtEtxwy5IcpOXzJVZC60uYc3SSb5F2plOZ3ep3rhDZuFZzWuvtED5mBcqWU14hT96lXd8mqzNX+9xJJo7rR+7f+hNBFlTXqV2kZPvnpkSfkZFcDZIskNfISZ/Wmn9d6ncob4vYlcoDWMY2OX2B4yq9jVF7YrnP7gPD8lMgK8aUcuczwAKHr5DAtZZljXyGHvqyT+ayZJeJxo8DuGLVDvPT8KZErzo28Lc85thvkDs/rJECpbFfOPiUHnSmXT4hT8pSkIq4X/ByRFGnbqDS1T3jkFtkGIy6g8a7jm/Ds0yOlp2NyV53j3iXzcp2LZbfPKdmyAkO+ta0TcoCK9ibkqoUbJF1O+tEeUM5NGPLwlByWBzn92fm5WcZbV8nqc0Jon96/tLxP7vqV5sWbNuuErBgpk2F4kIe4Nc3xOjmU5gbhf2kKYqPUOZAfxnZAlSGO6b0O263yTppWXmof0eGoOqDaKBAemRX8QLZi1Xc+pzT81Tm7RGS2ckU8yo8POxzaLJNRuxv9/0s0e+kBmZ+Lnmc6bc8999zvBX4U+Asff/zx5/u7q8C/38e3Cfyajz/++L967rnnngP+NeBHaHT4Gz/++OPvPquPv8TwwksNsmNy18aMNlkKpyWy78QlxlNyJ4L527br4zuFlLmxvtvt72VCGF6QfUSOq31ClLLK5riX83Jk31VhsFt+k4C2iZGnwQDZk6OR4bsZ51+uXRWjBuwuYfoxfvY5e7m2uPL+jH1ynLAGtIbuNnHa6gXZkH1BOosqIoX/Tv++SE7Lqwtke+Sy0ymJ1KwxFF7iwrS2OQtt3z/hSboC4LfSzm19Afhh4O8F/mWyGYQ+yEdw+CR7t5Z6m0+IYViNFHO5lxjewyPd1os8d8llkE/JnXw6QpdKu8I+JQLxtPQ/JQp9h8xVTZ3w3ZQEK8SrcFHGs8jZi1p1oGxvWsYhPD7bpVyl/apwxxFN+UED0/vhTjnL16Y2yh/7hF8dp05o7VfenJZ+xZnv98jeVfls/Ejzi4T/haNeri0fVv5UYTnftlPHKH9R3umUjXGrwwNRHjBMD9opdXyngbtM9oZMO4wPexn3qFX+6qzxfTw7NnG7Ty52Vj7tkWCV4xG38u8p8+lsp9ddLHWrLHBMy2QOq3F8Qk711OE5JTpgSu42mxLedm7E1TbZB6jsXyHzq8yShzXMn3b8PiTG3B4JSNlXdVRmZN/g/qjulDj3wvyU+brvIcPjxK0jblcZzply+hLhwynhJflEmtcZ0nmqbdfxQ45knzLc5ykfKLPm6c1pKa+xZL/Cop4zILNAgmvKTw17jdoDsj9yj+xj0xkxaFXtE+cf4ogKf+Uv6XqVBC/kkSoTpe8p2SIi/++WfrWTtkiAzzbEVdWblUflj2kvOyF7jV2FqOmJu5xdSZqSo+DlL4MYFU/VrlDuLhF5rk62b/WB81Z1+PgRZudBGq12Tb0n7FlO2w7DveIHDPWvYxInyhLLamM9T+jH4ME+cdoMhh2P6ionpGPxU/Xw8hyYoM3vR2Wc+yQ9VBzVPrRddoie1WlzLhwvDPcha5MrT2uQxflcY3gfpjptvKfNdpc5e7n2U6Kbt4m9KU52Cj6056oerXrTsdjnlNAFhH/UI5VWbFP7tb5zjPskzVEZb3vVd6iP9Fl9EnXPRc8nWWn7/cC/zvDqgH8a+E8//vjj3/Xcc8/90/37PwV8k1xt8ybt5qw3ecazSBMcU1qU5SptMnROFBbrJEI76f8PaEziys0KuY9lnaGimfR31xjeT3G9fL/SYXpcfndV4jphZAWo0SiZyPQ9jXEZ1aiRRouGroywTu7buUZWquxjiUTX13p7M4b7KE6IUIVEIBSG9uG9SOLHqNkxWf2h4FND7rj0c0IiZ0awF4ihOynwOzcquxlZxdR5u06Ozq/O2ITcr/SUbFCWFjTUhV3H1N8pvwuTEfA1B3lMuxLgAe084j90FR7vw+/uFbqXs7oEayfDe2RUFDWXWaFrGW8rgDhPzoXC9FEZl6sNU4YrXtcKrk8YOm2TXs4oXe1fh04BplOlglgnx+4fEgO/0twLxKkU9tqetO17cS/M4/QhaVp+Xiy/LZLVE+lOgSe9KRTta4HcY+fmd2lgsXzWmNd40EERj+JMWpf/nDMdi/pU2pPXVXbKAPnwMVkRrzAp656S47AnZGXjSmnvMolGV9yqqCFyQCUzYciHsw6ndVXirm5qZNYo5hNyTcV1wqPHBSfOj7g96bC+QOSG8vIKZ++atB7kqgXHrkG83NtT0U0YyowFsgq+Vt5NCs4gwaIrfTw6Ts7zGo1+r/cy0qZ41FFYJ4cn7HQ82Ye4dGzS1XopA03HVP11qX+fdjjl449GdZdIVF/5Mxnhp+o+rwOpjq5XnFScOUadNp2G3QKfTpv6o8pVy0CCMhowGuM65OtE3ykPHVuV4+rNsR5QZ41hmRDjf8Lw4AjrO7eQDJDrpay0vMTQybnEkO8h82J7ygBlxmqB+Rrh+6dlXL6/XGB3jHu9jQkxrK+T1Wsvu4bw3KS0sUT4xRVc510nRBzYpwGJalvotE3I/Cg35N9J+f2YBG4vEx3nHF0r7Tu+Kwznft7j6lp1nq13jQSwJySDapzRUd9VvqhPlS3SnnpNPKpXfLfdx/ICCaSoJ4VxvdSd57RBeLOuTkmP9ZkSXSEenEcDFk/IfB+T4K527jJxMKTdCbH5bG9CdOWTUm61t6e94BiqDVgd0Gq/KtPHNpuwiSv14yViCyvfTvv4Kt9cKe0ZCLTtCZE7BmyU91XH6zxrJ0FsWed7kawS63BPyCFOta7PhIbXF3p72q0vcPHzTKft448//v8+99xzt0avfyXwN/fPfwD4z2hO268E/uDHH3/8MfCzzz333OS555776z7++OP/30V9LNNSUJ6SO1uMbrl8OqMtiOzRjDKXG3WKXqYt316h7T1ao12cNzYEXyOOxbXe12vkhKXbHSZTKjS2VoDPk8jNlAgnmWitl3uNpDMo0F5laFCtklW6Ce3yvSu003Ru0S7+g2bkeZqY6RdXyLKs0QmjJzpo4vXV3t/ztHsmrhAl/3qvs0Auwdwt9T9PotKXiPB6ytCgf5Whkj5meCHkKx0nV4jTtk7SimbkbopthkLydodjl2Hqz+dJJAkS0ZJJvsBZAWBURUGxBrkdUcvzEfB/3W+U/NvvA78C/thfaADdhhvvNZhuk3vajklkEjLvr9DoUmNHB3iVNt9XiYDe6+9eZOhcKKid+xsk/cao7SktJU+BrqNzl9z1tEycViNOu738XRqtq0hN9btE7ob7AolU3yWKq7a3RouMT8gG4eu0uVdIa6jvFlxMGDp1lD5M7YTGc9JbdTjlv1t9XowMv0ZOab1NjN5D4qwdkMCB/d4iUXbpfI02l+MoHL3dTRIw+DxRENLGa0TByafeRVfp4hJDmXTS2xPXJ8S4Wx/htscWgBhYlY9u97GpyG4xnBcN9imNDTS0v9DLH5YxvUoU8DJZLbpGo0Uj6cs0Wf0FhqvrKl0jszXt57Dj5y4x6sSb8v4OkSXO7RKR9XeJY79H7pW62n97SAzhax2Px33sd0kk93N9rA8Jf9/p5Y2oqosmRB68RqLe8tISWYmQ1yErmdK8Ou8GcdpeLZ9r3R3iKC2T+0e/QOQ4ND7+QofvMcP0SPXcqwVnnyNpVDqZT8n9perkg/7uVSIDJwwNtOqoV91khFw5BVntUz58gchxVzaU3S8SvblKTj2VbuT1E5LatNpxtEeTz7dp87TX4X25vzc98vMkcq9suk70f9V7t4l8Xi3llRlrxL55kdClY7pE9NoHJACnrnCenYtTGp3pRB0QA/JOx52neXrP36z3vUJ2AHyBBE6OafQgDpWtx8QJOu79K9vFzwFxbK8T+XRETqqckLvv7tF45wahJw3Xazz7njYN9rp6LG9OCY3dJpcoV9k9G303I6AGCZSBljsh95DdICcC7hEbSxm6RuOLGtTUOblNeFhelF8OSVbDHZqc1mlTV8xbgdRGpvcvLe8UfHh37CFxigxgaAYZEIA4fdror5O7il8s5W+RA2BeJHw76fVfpNH2JSILNvvY1YGvMjzt8Zi2FeQKuSj+hKyGa7ot0Whp1sfsVpCqN8XPAZkzeUR8KcvvMKQLbY27xPmf9PefJ3a4gV1pUTilg3WGj3bcq+T+5Ff4b++etheKI7ZDnMMXe98+HxLaHDzPPffcP/Tcc8+99dxzz731C6PfTueUH7+bnfP+vHLPei4qN/5tXtnT0ft5Y5hxcT+1Ti0749l1P8mjgT8bfa+/z4NlDM95OB63N69d61c46grMRbCf935cd3bO3zzYB8D7f592RvsfuwP8Cvjbfype55xxjPs9b0wX4XRc55PQ3Hg+KzznlR/T1bz25j3z6l3UlvBwwe/jNs57Ts/5fFHd8/Awj06eVd+/ee+exc+n5fO47fPgugjWTzKvn+QZ46d+Pw++i2iL0W/n0dZFNDbG1RjfF9U5r8+Lnnl0fN7zSWn5F9PHmK7mtXNev+fxY/19rJPmyWH/X0QPF70ft/1JZfi89i6SfRfJ0U+qa8f4mNfGRbT5SWTKJ31+sfR83txexFPz9NFFsuc8HTmPD+e9u0jvVhieRd/n0cT47zwanffMg/GTwMyoXH2eZbecRy/nybVn6dB5/c6b42fBd175Zz3nzf95sF3U/kW0fZFsO0+GzKOp8/D0LDk6D4557x3j2Kb+JPXGvPhJ9IvPX/FBJB9//PHHzz333Md/GfV+D/B7AK4999zH75DN3lsk1aFGub7VP9+nRQsvk7tLjkh0zDsyVsk9GaY0LtJWrjZIFHaZdqfCBkHeNvGWt3qZP02iSe9z9iCSae/zp3t9+3iedgiG3vv9/n6LrJgYbXiP5ITT8bBBUg+NnD2gecv3GR7WMmOYHvkz/fOHJAX0HbLS9x65c+S4fzca+i2yOvGQbEA1srdG8oqN8G30v2lvw/1SBwz3tE1o0R2X4h2L0QdXAEzHuFfwK03UKNx2r+/K1IRhCoFtQFblVqBR4Ap8/D4859m05jq9APzLPw6rP94SgL8BP/yfB9dGHI3yO79GVV1ReofhnjYjxWsF5w9o93Zc62W2yIEgCx0/H3ac3SORYToshyRP3Gjot8ldgdKZz5TQ0wnNH5X3pLdFsoJyQO7UguHKIqUt76RxbnYZPju0+dsoeLtMcOpT03K3yX4c08c+JJG6JbJHZovc02au/h5ZNTMqe0xWRbYI74izY7J/SN5UfowfeV3a+9O9rX1yd9K3OkybhD+VPcuEVlzFl08f9LriWnn2iPAs5TdTC1UMpky5eqHcgGF0Td5cJTJO3P50aUP5UOXZVqmjTBC3jueE8POUpNy9Q1aWjMAe9nZdDXDsMyIfHpF77I5L/VOyT+m4l3lMVlbXSErzHqGpSR/bBg3fi73uIbnbc1rgOCL3mu0QkSHtCYM6TX5SFpquSS+3SfbA3CP7HA96f6aCbZCDaOgwbZCV7SmNn476eFzF2yUy67D/ZtriLsNVQsf6kOEe4vdoK0BTsqrpapB3oz4kKa11dcLxa5As9jF/0OuaOqQcn/b2fprIOfXmHpHhU5KOps0wLXhU3+wTmaL8+U6H1/FOafe27fV3rvCb9bPZ4X7E2XvalJXXOp6cNx/l/iGNB6+SFX9l4n7HxfM0++K44+7bHfb7hM42evtrZD/Xuwz31qrz9ss4tgpup30s0ooZCjuEFhc6vPKvPOz9k2uEblx13SZ7tNVF90gmkvvrpGXl3qz/fplhmvV5z04fj2l+B4TH3ib7VrXPnvWo+9RdZi3UuqdEnl0tZR239tn3+m8H5C7cGckw2CM8bBnlxHEfk6n06lBXvKqt4bNBo8+1/l2adpVNOtsle0jrirZbiqQZdbEwKi8P+tj2+p/yzIyYR0RuSWue7zAruFTuaL96ndTYZpPmV8u7ewVP0uj7pZ77zL5V8OHzDqHNVaI/lYn7JCPLZ5PcW1jxsUXsjH1i15309t4lq6PHpa7Pu73enyb3U36boV6e9/zlOm2PTHt87rnn/jrgL/T3DxkefvIZojfOfWa0SXYZXaGjgjFdZr98l6GOSv2lUmfG2U3ol/o7Ba7pXpazLkQILZb27L+2URWy6U+mBtmmdSXI+psG3JThhb/TAsch2QPgXoJLvZ8jolj13p/2upaZ0QSAd+QcEeHzmOTsKviEyfaFVzzK8AqOKVHMlnN+/FxxrECwvPipOHEJ2LpHxCB1zi6VcpZZIHM/FgDSik7OFPgN2+39JrD0BC49gbWPeprGe63uKbD1H8FvAv6xHydc+RbhNqWpne3Cz7zfrhKQto9ImoQ4M+XItKkaAJAWnXtpTWW/TBSptHFE0tA+6u8ek9OOHI/zLn4h83Fcvi8znD/xdjKnvccFZudYnvNdpf1TYsj4aOh8RPbfaHQflt98J76891B4ZyQ96iOSUiLfqmyUA7XfS2QT9AFx6D5ifmrClLO051idd3FW27P/sQwa84sHIUHmAGKkU/o7Lt9nhGcPRvgR9z4fMTwZTthrH8fEkFCe1Tmt/Flx63iUTW721/lRvir3qxw9ZUhnU3Lw1EGprwNiO1MiO3XUj8pvY5raZ+jcKfc/InLf8TmeKdlbKj8oPz2ApvKtsrPKd0o5YVamG2SouufgnLqO+6C8dzwQPqx6Vb2xRFIVhU96qXi1vUsMU7l0xCttCc9C6cfPkMMoxHeV9/Ko8z3Wm0eljWnpX73kZ+fiKblbTRq23+XSprwnrqsNUfVPtU/8DpHf1WahjFteEd/S30Gp43jHOKi6eVbal2+Pyp90MC1tV9zZjrBMiew+IbRyUtoyHVOnTTxOyzj8L31VmpIux3aZMIjvsaN7kbOlnSXvVdlZ4XFOn5VWNmVon1R7x7rVdlA/UvpdLnA8JY6O8yVfT0u/zo08on5yruzD/qrdU9uQpmubUzJHtrXCkFd0iKrzW2lXXFSaGtPRCtGvS6XcwejdYhmnZZQzU+bbbJRxjen2mGGgz/7ExXgFrsoX6Zc5+KnPGLfCIz6q/JM/hKHKtfEjLNJI1ZUXPX+5TtsfBX4D8Lv6/z9S3v9jzz333L9HO4Dko2ftZ4Psr1qh5Zi6IfqA5tHu0JDxVXLy4U1adOAyTSC/QssxXiNRoq/RIl+uhr0A/BAxNq72Ol+jIfyUlhML2US6TiJEX+0w7RBCmZDIx7SUc9XPSMbXSOTu58ipPXrnXyZ7eD4DfKWXPSC5sdfJ5uIbNI/clR6Fy6z8X+7tGKF278VC7+vN/n2zwyyDaDR9hRiURviXSPRnrePwywUP3yNH2tPrfJ6Wt7tFhJe43+jt3aFFQTRifV6m0Qalz5tkT41MbqRlsfdf8e2YdNhcDTjusCt0VnudSf/z+NxTWnRnCeBfBH4L7ZTJ3/g6/MJ34R8vleH7y0Nvvj88QdKVldWO2wnJKz8FfpCWS/w8LerzDjGqXqTN/fXe/EOGe9pu9nLbRCh9ub+v0TTH4wraA1rmp1FNo8R1T9uLwC8nq4evk83itlcjT3V1RJ5zFWSLRPoq/cuTCtmvkM3trt4e9LJfIRE4o51Lfay3ev0TGk1Pafxzmwh6ncEpmXv7FmeHvd5GH+cayXUfK0xX3RfJ3EL2R+z1dycMV7JvFxxs9PLbHWfKJNsT1z9Xxn0V+GLB7ds0RUQZz6R//1zHzU0SybtZ6m6SyOWUYSbA13r5GtD6GvNXQCa93SkNt9v9+w8S42qH4Wr4hOHhNzoqP0iT3+ODIpZpc7HS8XaHyECdhbvkmGuV4nWyp22bnBZ3Bfh66UcdQW/7bm/XiPerNJ651nFyk+HhWPLeI1o0Vf3g2A5ostc9Bds0unAPMWRPm0G3L3acXiN7UCErrmu9jgcavdHfb/Ry68CXGAbUDLyt97+7hI5v93Edd7jdj7TM8Ch2jY0vd9g3yT7EGsNaIMEVaDLue/39l8n1ExvkBOjz9OYO2VPzMll50kh/mWYXLBED+AbZa7vT2/sSkRf7tPl9kza3/1hva4Nkdkgf62XcEyIP3Kd0SFYWdOgWGe5p8yqWg46zHdrcfZlkGBzT9Lv6dUL2Er9DbCKNxpoNcIfGP/R3X6Txwfu9f8teJ7Si/JYWHJsyqzpsK73u1xievvlRH4809TrZ4z3pOPws0T83OzzbfayXiWxTF573bBDZKw5epc3hUsfnNm0+lclVdp+Ovr9HgjAQR6/aI9LSq+QaCct61oK8uEbD4zskm2O54+U24eF9gutFMvd7NLtWO2SJHNQ2dma/R8Ptl0nGx20aL7iyuUXD9+eIDtwiNOWKkAsDkAPKtjscrxHc3iCO380O2xbZk/0+ja49yv5Noj+XaNkyED33ZYYO05MO94Qmn2sAb4nhnra9/vsvJ9k+X2F4+Ee1/bRjPCXRwwZvdbxVurhH9PB6f/eApvdeJ3aR9vATEqRcIudrrDN8jjqcXyPZhT/Y+/83OP/5JEf+/2HaoSP/0+eee+5D4P9Ic9b+g+eee+5/0+H/Nb34n6Ad9/9+h+k3Pat9iCJ32bJGYBWYJyTVa48I5F0aY18mhuAuWT15SNID6O9cPoWkaeyQlCBIJEUD95ikBOyR1BojJ9Vpe0COkFb5bBJG2yGpHZdIitYqMfJVtkdkQ6xGiREOx7ZUfjOarYDYIumHix3HNT1hmxjv4lPFukmctp0ChwLyaW/7Q7IKsc1wVXGPEPQ2iWTpWCjMdDjEiY/pqbtkw+6l3l6NOIkLV6IqviGOpn3v9ncflu+uhGlYKbhOiTHNlLZ89meAX/3dJo3+Vdqt2z/RK3REbncc7zBM6Tzq+HZ1U3rUmVkqY9bYgxyFvEui1JC0A51Dlb1K2H73ynimZF6vkqiQc6BwFb/1ABHLqLAgR+LuE8Xus1k+28aUGIQaj47FOqvE8N8lKyo6fhpGNfIPmVv5dZc4oQckSj4lKdj2K7/Idzr3B8yPcFpnn0TgPS1UR/0jkmL0kKHiMbKnE7HX+9gs3zcJrh/2d66KbRY4HjKkCWUXDE/o3C5lfORN6XOP8LF9SHvHDPlLetgn824UscozZZPtTmm0v0eisRottqujTq9vwEzDYZ84x3VuTI2V1nRGDCooT4yIb5Jjs3VWdxmmxqpHHtL44WEZ71rvx/nVcDDgpkF23OEygAUJTE5ouswgi3icdfgMGK6Vuvskxa3yf5XtlDaqXq18p+6sV5hopKvb5O/FUk85/mGH3TkzGk5pY7zSJg9rsEDknqvjm6Wdh2QeLK9xbBtHZM4eEWdDulIOOs+UNqfkuoD3yMqPzpW4VIdoXFdDVD2jsy2eXEFZIStlOn7VHtgqMOpwbhX8W2e3t+NJucLn/OzQaED+sg1l4TKh50orjll61mA/Lr+dlH42GR7udFDaleakqWPCh1OilyCO9FEppy4876l64YTwx2YftzgVF89aaVOOC9OUs8frq2vlfZ2MA5JSprwwICgs2mS2IQ9r90pH2pXCLtwGpOfpIXGhIyQPL5GVY9uSD48JvR+QdEFtcEjARTm+RmhqgaRxXur9ySPy5B5DnabsWCDyW5trk7MOcpVnvlMHTAo+7Fc8KFempb1TYifukaAsvf8qq+tTbeSD8k7b1EDQKsNVfnF2RJuXA4aP9sFmwcUWz34+yemRf885P/0v55T9GPjffoJ+zzx16f2ECIjxsvysfH86+j4bfT8h3vnCnLZno3J+p7RT26j91fILozrnwaXRdMKwT9sfj4HR56fMx4uKobZXx+b/p6M2Kj7HMEGEZsUDDGGclXYXiTGpcq5tj53K2t+8/hm9Py31bf9SKVfnTkNh3I4wVdhPymdT3Gobju+0DuiYOGmHwD8I/Ma78Nvvff8oo/PoYEx79fMYRjoMFY+2W1M2Kn3No6l58zem7Vq/4m3clqu7J5yl6THu/OwzHr/4rr87pqejsmNaqjzAOb/bhjD47jx+q/VrO0sFR5Wu6piEYTbnf6X/efNQf6u8Mea9WmaM5zEu5o1rzPN1jipP+Lka2mP5y+j9WN6M5fA82VDH7fsqf/yrskXna0xL1vX3Sj9jmTiWKePycHZM8+js5Jw2K+0tcHZe6pxW/IzlbcVJ7XNMQ58U5vHvtU7lufFcjcdKqVthPxnVo9SrdDqGdUzf8+RI/W2M57FMXxrh5jy9N8aVgbGfphlhr436YE6dioexDhvLtnm0Mx7XyejdWDeO52sso5nT/rjeGPfzdEKVf2PemYfLsX1R+epkzt+Yf0/LvFX5dN4zr43x3IzHOw4Owln7qerCcdl54xaWMR7l5adzfhvz8Jgnno7K1uAKnD090j6EfR6+x7Q3pr/x3MEQF/Pam0df49/myXflufKx8rDPmM7GeK5y8/ScOlUOMYJrXr1aZ3H023my6yL+UPbXvhi1dzrn+0XPX/FBJP9NPzW6D8P0gvH7xdH7sUFVo1yL5f9YEFwkGBbK/4vqVVguam+8gjFu+7wxLM75G8N2OqfeGDe1/cVRuYVR3TH+fHda3s9re4yD8fdx+36eN+8LXDyWcfl5bdV2ZKRKC8+iizO/VcQf0cKy/zywfg/+tV8GH/85+FuGgvWTzGuFa15UcN78zcrnOo4TztLYvLZqnXl0Ow8/8/6P2zkXdxeMaXbOb/P6qu/g7JzOOAvPPBqtfZxyltbn/V00hjFcFb5Ke9Uhv4gHz5Mn5/FqLTsrZSt+xu2OcTrubx6+xzDOG8u8+mMc1zJjWphHd+fBPw+mT8zPc96dV3YebdTv58mo8e/n6bh546jydp5sGI/5vDm8SB7Mg2UsX8b9jA3feTIVhrx43ryOYZ1HW+fpzXl4nycLxmOcp9vPm7fz6GUe/47xU+EZy6k6ljF8477O0wlVltT2zsPNuN36Wf4cwzl2qs+j2XnyaDzuT4Jvx3DRM5YrF8Fx0efxc1Hd2Zzf5n0/T77623nzPY+mxvQ8D/ZfLL7HPOFvp8yHZx4sz9JNz4LxPNk4bqeWrfJjnl46D/ba5jzYL8Lvefg+729MI5+0zU/6fCqcthOylL1LIxyXyN3QPSOpF1OSVrVHNtjPSDqfqXe7JG1uVt4d9L4XR+/2+3tPcJyV9mr/vqvR95ry5xLyAW0JeZtMlOlwBx2uE7JHaY+kx0HSuEwTmJH0SFNKTW2rEQhICsqM4al/u7RUli2SgmUKxF6p/5Bs1HZ+hPeARE9Mf4RhCg0kBWqVLHXPSIraDhEUpm1Whlohy+wfkZS6VYapE6a3LpJ0nXF65B6hrf0Cu99NVzPNpiqCnQ7H0/fg0kGveK0Xvk9yEf7En2vh2d8Dt3493PrT7WejMfYhPdZ0wUc0WjH1a6+PZ5weuc8wjdR2ze0+6eUe9TEclH59pONdsg8HkiI2FoyrZG5NqVgt7dnWtPdf9yJslc+7hC9MdR1H7iG0d1TqHHUcVJzNGKaLnJI0ny2GG5Kl5ackraPmnzt+acQxmR55npKqtGdKMgzvCDP1dZdECJ0T09p2idypskvZIP6mJHo9xq3zaNSuwqVSVhaM6fuEHAxzwDA9yshk5Zsqzx6TOaV8nhJ5JkzKuMuElo8JfistHpSxK8dMoxRf9Z3GiHy8X2CpsvYjhjQlvqfkpNF9ImeEE5L6U/EtnM7vFsN0NHnphJyIahrolMhgU+PcV3LYcabu2SWpn9b13WLB5VoZj8+HRO46j/LNCUmPUhaqSxZJ6pmHbTj3pqYJ+w451GKeoVs/215NM1XGKLPGdKYeEPZLDFMhTfE1Vauuzh6R/XJTcrKq3x2j8y0vyw97ZTzH5a8atU8K/GOHV9ikAe0F58k0OVOH1ZUPabziyYTOkTLulBxooOxWb1bd8riM4XliA2kH7DO8C3G1t6VsqCtg0153mxzsopyc9vGO9at6lV7HQ59mZTw1PXKeY1EfYdYOkz/quKeEt571WEc9ecBZA19a2mG4/95UcBimR0qHjs/xSo/247xIJ9pYu+W9toCybowLx7nQ611iKBOURY7jaYHzkNCm+tNyEJtOGTctvz8mumyfRiOrxM6d9n6FTdj3CJ8tcdZm0/auek4dIN9Lo8IjTUwZ6k0fdYZ6o9rZFT/1Ub+bhm47u8ROcRxrHV75cZEmE9Y4mx4pnNWe2eHZz6fCaVshF5q+StvgKiHtEEfuTTLQm2Qj+yrZ4LtGjvf9Etnov0A2Y0ObpKu9ry/134/JQSRLZDOtAuxLDPe9HZINzwpay232d+a6vkkYfI3kMLsf74tE0d6kbcqEbCBd6rBeJ4dxbJI8fQ0CFQr9/Zv93UbB2WnHizCt9c8KTNvx949ojodwyNhrvT03Mi/1/5fIxvIt2ty+SvYdnJCb3zd6X58lhF3ziu903OikTvo47pZx09tRga7QNnRWJ0UFOyN52ccddp3e1YKPCcODSCZ9zH8b8PI23NrOJfBvEzoDOH4ftv5f8O//Zvi1P/N/4Nf+f35n2wP3k2QT09caUv/dfysBiNc7TpZpi3fi4RI5hOQ6udzS/mbkIBJx/KS3d5MYyZMynr0+ngnDg0juM3QW13sbbkDe7jhbG7WnADsiB/fAkL9OiYEg3S4zPB5cZfEm2dO2QfZYTMgBOkvkwIMlchCJCqny6y2GxpDOnHuBNEjEmbJnQq5nuMP8iOB9EhiS1yF7CPb7uxPawRQ6bbeJ4rlP9rVVnC2V8UIuoZ6Qjf7ithrzGtzOw20uPohEulkhCm2NRnuOR/lw1N8ZNPiAHOQwIQeRHNIU8Utl/MoOxzBjqHzdAzDrY7tSxn5C6P42MRRuc3ZP211iOGtEe4jTXXLww7S/+xIxWtwwf0QuqK1G2V3agVni+ybhBw33L/U+LhNDRT4/oMm0ehDJKjmIRGPwBjHmXqfNyyrDg0h2yTHw6hvpohre60TGG/Q7JDx+jRxEMqPRymdIEOkqcQxfYOhUHhGZsEGuc5E+DGyqO3QK7vXvX2R4EMkiCcaO9aYGzlqH45XSr7B4OAllPC+SY811rF+j0aZOxS5tXl9mqMt1hoTjOkPn2HF6UfSUBAjraoAy5HqHfUr0u0elO286I+JnQi4NvkoOTvsSMfANZCz0fuS5XdoBDRqWLxLH4kbp8yHRza8QuTw+iOSENpcv9D4MfjieFWI7fYEETOSR2yT4d5McqnZaylwll26f93gYhIGDKc3O+GL/Xb56hdh9VUacjr6/R3NA7FNHpdojJ7T5+zyxxeh9b9D4xnfy6goJni93vNxieBCJ8kunzQULD5BS7xhEqs4N5JCgN4guvU2zq3b7uD6k8fQdhntr18jF89qOOmvrxOHSDtBxukGCnjdJoOB6L3ef7Pu6TqOVKgu3en3p+k2GB5Ec9/oesGLgUJ39WsGHTvlrxGn/ImcPItGhXaHRyhv9N/nnMx1nlS7u9d/eYHgQyaT3pz0vbyrjtUfXmH8QybTD8iaN9x7TePE28Ls5//lUOG2/QLszZYecyKiRbeTmFPiTtAm7R5BUI3zXaATwXaKAH9AQIvIOaMy5SU67OS7v9IZ3e9sTEv16nii9zV5vlTBUdaB2ycbFJYaGqQeq2O4y2Sf0NtnYT+9DotkiJ2BdIfcH1SizhA3ZHKpR/R6NWO8R5bVBjJETcrP8Kbk/44Dhyo9KQmNLY08Y/YNEU7aIItJxmpCoznsdL+8yFEgq0/dIFGyLOMXidId2+o1OzumonRPaKU6Q1VjLHPe+nycRHIUrDFd5nZsNclKQsFQjZR/42X8LfmD/d8I3aZbAU9oEv907v9doWtr7SeKMbJM7njRwNWDfJitts/5nEMBoqQb7VSLkqpMnHRsxkj53OjwK1zVysM4GMYD1PX2m5F4yBSmE1n2MKG0UnNV2XP1RmD8hgZtDEjnbJiu8zvlGQ+n3jcHqnMknR8SpM9ptUEgHYp3hSpvO/H3OX2m71+FYLmOf9vEf0ub5lOFBJJulfI1KquDfI3JOHCnPNNR3ChweJgShCzMH9jt+1gm/VyWiIbvM2WOyHY/y4Snhd8d/QFabNhiutD0kfK7sMNj2LsPDlDRa7K+OfUYzPBbInWrSxjj6LC7uF1h2els7JINDmjKwtUnbqrpI9MwGjefUDR/R5qj2sUqj1w0Sfa4HDEBkjXiZ9PdT4rDrzMjzh0R+K38elroa/cu9n8dEL1bZbjDT/u+TVQODElvlty2aPnVVYKW3p2w30OEx4RCdol6odKM8UbdotG303xyPevMxudphLEumRAd6SvMjwvPi437/flrKXer1N3ubL9BO3pN+l2hBiLdJkEc5oWEoT9egyCI5ObOe4kr5fZkYoROGpwRKjz/ZYXyHOEjic5M44upX98ocEr7Tedvt7RyQ1TDl5lJ//4DhnbLq5i3i8JslAHG6t8t7x6GzsUvuWjM4ulHG8V4v9x6xQaZ9HBrw2gdj56Q+uzSe8WRo5Va1F6a9/8c8OyVtmyaP1OOH/X+F4ZTYQhOiU496v++T05+1VbR9ZuQwj/uE5o/IIR0Q/X3Q+9no77UFxrIOhqcyLxIe9jToww7DB+SUTB165+X5/u4+0cNrJIjyoLQ5JQedKYOWyEmYW0TO7pFsKXGpraJO1c6cZ7OtMKQ/de0usbe17Zz/A87aFsp4YToh+lMaFT/10RaTNyAZMLsddoM6wlrtdg+XWmP4fJfogb1S/h4XP58Kp+1jEn0+PeezCl+C9m/GcBOmaWe1vAQ4fjcrfczKO0obNb3ipLRR4aPUqfDZxkKpU9s+HbWzOGqD0hal3LiPxfK77dbxjuGqfVZc1fFR8Hkyp93ZnLrj+WLU5tPR99rnMUOcVJyO8TnGSR27+KjzIhwVfull3rgVjCel/HkwVPpwzBUWDmlnrbq69g3gf03Tzm8P6bGOa1bag7N0X/s8HdUTh2NcLZYyY/zX+av9zsOTdDFWZhWvRqoqLY/hqzBW2ChtmK4z4+yY/Lw0Bz/z6BLO8k+lWUZt1DlZHJWrT8XZuK+xjBnLmvF8z6O1pwxTZOfNreVc1aj9isfa7lh2nZSytW9KuaejuhVndT7rnI3paowf61QjpPZbx27bl8pvFc5Kt2NaGMv7Mb24qjGWi+PvlLq1/yorx7Khjm/Me2NYF+e8h2aYnl5Qd7F8n43+M3p3nq4b032ltaVSruK54miRs/AJU03fH8vs8XjGNO4zxvd4jp+WOpVf5/HKGE9jHNQ26jwKx1h21bmpv4/p+umo3JiWhHEsMypM8/iwjpXRuwrbGOY6tnl4GOv/Mc7m8dLpnHbG4zhPDo7LXvSM+xrbNeP5nye76zPmi9PRf8tU+Kqj5d/YBhVHMJ9HxnJiHs7GcIzHMo+ex/iutDKmubH8Oj2n3XG9MU2dN+9jXq605/fxfI9hr/D42QWTMbxjvckIlrG9Na+vi+AY+xzVJqpjr2MbtzvmzfPKjZ9PhdP2S2nL1/fJsvMRLTqyS6LA3ySR45s0D/U+ubfnBsOl6a/Tol73aZO7TltmvdrfT8idSN8u7UDuGrlG875XgR8lnryR1wlZPveuhx+lRSXeIdGAHyH77t4hx40aefGetlkf2w91ONwfUFPk1khKgSsoMkwVEJc6zk5JeqRRvhXa8vHbfaxf7zhfIZFuYZ6SKKtKY5fcHfOl3q4Rwnt8svTI9d73KW1J+B2G6QinfT5MvdklqaF3Ga5ufUCiLqs036imVrgaOKNFAXc6HN/o+K0pjpPez61e9ymJCt4nd6fc4Jz0SNqKwK9YAn4l7cr7XeBnOuB3gd/3Vfivf4pfuRJ6/DptfpdpET8jL0skpeZ6H+MjQk/SzCWyP+SIRtc3yGXGkw7fjKxgbtF4br33tdHLKAyv9za+APxs7/d1humRM7IyvcgwAvkCjT6kTyNw0u0yWS2DCN/xPW1G3y93PN3vc2Kq0CItteEWySv/Kkn1e6n36b5Io7K2r6D8OkmP3CXpXqu0VBVXg+pzv/93TN/s3x+RVdFv9j6MctJhWiUrNKZIrdPo8ts0OvgRguvv9nfX+thfL7h9m0SHVSjy7O0+rpsM0yPrvJg5MGV4T9uP9vKuSh13mFSIG2RFfUJSxIzsfwb4AaKkdwk9XiVZD9K6Y/gSkTH0+t8jKZHf6X2bHum8LNB49IBkJBx1vF4ldxftkEjnNzpu3+6flSN3enlXkWz7tV72mOidCW3OTmjp2Y9otGFk3JXexzTZe73D+5AWob9Lo3lliXg8pc3zlCYT7pa6uzS5uUb2Rl7r5b9Drp9Yp6XhSPfOo3rxam/3iMbntxje0zbp432H3NM2I6ssXyPX3Vxh/j1tl4huWSKZH1+npexBVrn2Ow5+lMiSnyfzttbhqPe0HfexvdLffYvomxtELu2Se6Fukb3kuzS58zLh5S+RLRny+To5er9m0LzUx2FKdH1cWf5ch9s2XKVwxfjrDPXISX836XiRzsyI+Xovc0Cj390Oz+doPKfefJ2s2lzveN/vn1/vdV05We84mJBVbe2KU7Iae733v89wH+wDot9f6+XfIvfq3iZXGtzoOHvY214hcuFFhjp8/Gx2OMyemNJ02Rdpcy+tvEq2m4yDg1WWv0tWRCF788aG/3WSony5v98j97St0uTAGg2P90j65/MkPfJ6qeudhTDcd/oykdOLJD1eu8fnnY6LH+rtvEXD822y8rTV4fss0YFbnL2n7SrRUdoFD8n9uBOSHmnWwE2yAvwCzV6438tt0ubS1E1X3U1fdYXqSwz3oCkrrpC7Qk+IrHu14EN4tTN3aXL8WmlvRpsXbZU3SCrtlMYDNzvOKl2YvVPvadvq4zM90v2m14gcWib2/aucTY90tfCbxHb6Km1+/jDnP58Kp22BKKpV4njNyOAXyV1sllsd1fFvlTD/Gknl8V0lFIXgSnkHQ4NyudSF4YZiU+qWaNHQ1V5uv7SxSpwaSJpmTccTjjEOTLkyVaSWdY9DXRnS4aHXudzxaD3xcXk07sskndLHsrNSzvaXy5+O4GKpU51n4Z0SI9F3wjfp78SJTpttrRJasM1qqImbxVKnjkWlWcey2GGX/sZ0UelwjWzWHf8ufB6+IQy/9wS++A+1RbVdGk08/5+3sr/+n/wpftnfBL/243+WX/uf/g74jcDfwXBT2893ZGzCv/zhkEb802mTDhzzacHxKaFlx3NC6Nhyzp+4EWfi+zKN5iqv+egUC5d8JD/4TMk81rJjZTrG7wpJy5sUOMW7tD4hKQr2e1jKnzIMCswY7oequDgajd/348f519Cf9LZrEORyh3+NKKMqq9ZIioVtSJPzaK2Wq3D4zBgGdMZ8CGfnxfmfkflcovGIeHNeqzxzjI7XNmCY7qTTdkQusXeM0sASZ2lgzIcqQvFQaXZWxkEvY/qUDpHyd7XDIx5re0sMecO6lHdrDPfqCOsxSX9bIfJMfM04O6dVpkjTayRie4WzchwyT9Y5GpVRJvluoXyHzKljkOetL2+IA/l1iWG0/0qvt9/rVfp4SoxO4alp6HU8l3s7bjWo7ayWOmOdv0ZWj+y/jrHqDOV4LVffrY36cA6Uratl7PK9sDt/x6WMRuo49c/H+Tso9TVepWVpZKV8dqwarOLNz5ZbLuX8bNmVUdsnDOlHXlNXuKJQ9eCMyNOT8puy+rCM0XafFhwL42kpc5nh3M97HAcFvsrLz4/gnCe7x+2pkxbIXrwKg3QgjFU2SfsVn8KyWuqOZbp6rTo0i8SeXCvvznPahF0erzx9UsrYnjbjtIzDeV5lSFMLDOl2jczpQqlT6XOtlKs6zgDWItliU+et2mzPE56ZjHAlXTpe61WaF1Yf5e4hQ170qTirj3K0ztl4rJWXlkqZxVG5+sjzE2ITXZ5Tbvw8165W+6v7rD733Me3aFGRm4R4jCAd0BDuoRE1wr5LNlNP+rt3+ru7xOuGhpDPkci9iHyZrCTpDcuAqyRv9QvEizYq9TwhQgX/q+Qkn4MOyxeJcN8iK3ZO6md7W9/rY7vdyx4DP0cUp8w5IdE/mX2cfrJAiwScdniukVz/ZVrUZYtEdE4YrjrcJUpOp8N+KsPdIYLOvRmTgscb/W+fKEBxv9+/r/e6jkcBu97hvE8Ie9Lbc9yQvRD0MkZLfU5IrvIyOVHwVYb7IJyPZbKJ9ZTs29mlRciukr2X7hGokeU9WnRpvePUPQWWe4UWufntfxPwa2kh5X+RTMAO30+43vuL8KuIk/k9hieKnnZ4FslpS09JVOyQsw7dIblE+UUi/HYLnjQYrtD40j0lNwuOfIyybhDnHrLx3Gef7AmtjqHPrP9/mUTmdzuc7nO7yzDiLr1c7X9ejPsK4Vfxo1w5Ln+7pd9XGW4mrsGXdeafLiXOHM/nC062yEEN0pH8eZXMyy5xaNf6GF19e40YoFskqrdKDsvxN3lXWWDE39WUq+Xd1VJX3lwiDthe//4F4ujf7/9fZ8h77pHUUBG3U5rceanAdMBwn9Q+w4CHY3AFzbGfkv3J6zR63CPR4Do314k8OySHRqz23x6T1ZIVGr7ds/Ea2RdynRZHuUcM4hfIiqXBAWlkk2QOHDC8NNexHXd8qJxdDTZeowyckFXHW/3zo17OugdkX/cSmQP5da+Xu9z7tP9NzhpzNwrOlG8zMldbZB+p8ll+ukv2tFTjEYb6qH5+1OF4hSZjIFHwo15mnt5UD6yRzIRdEhRY7+8UpTPidF6izf0Dmt5ap62wSL8v9zbdV3ib7GlzLnXKdDyqrlojtKJMcf6rnaKhp65wXK/2cu7LVUeJfw3ch73tV0iQxb129DG8RPY0vUT2XU0IrSjbt2h0+JRGK9LiIrlsWf49IVkvdxnuaTsmtpN0eMJwP97VXucdslfby8jl9+pcnPeYLaK+e0Kj4ZfIPrkDmn67zXzZXR+zn+RVcVntEW2XG8QWg8hLbawNmky7TvbBz2j0t9ZxsFbqul+ypigekmwvYXdOxmPR7nqlf98kq50HtHn5iIbr9dLHlOD8Eg2PDwjt6rR9RA6HeZ/GQxMiTybECZz0crtEh05o8yIebfMDsrp5m/l72pZpdOY75eONgo/v9t9vEn6Sb3xOybkVU5pMVX/KP1c5uyL2iMZvd8icSXs3iT0pHsWJcC4Tm6k+7qV9o9d/r4/zKvBH4b/4+OOP32DO86lYafuf0JYI36MpzBtEiGq7ngK/noasP0lDwlWacFsly8hrwI/3/9+kLRO/S0PedZqh/DP9vUT4w+XdywwVtkJ9Dfh7SRrFW+TQFKMH0w7Lryab13f6u7+PMPh3iYNyicZIX+lt/TiNkL7Syx4Af4icyHiDnNC2CfwUcRwV8se97jJt8WbW4Xmp1/1JmmD+Qdpy8YOOqyPapaLHvc7fQY5Ivt/LuaKnY3a1wL5EUmhudhge0IzY1xlu4F4nAmBGY4if7/0bmYYmhN7o47TPmzQ6WS7l3qfNoQZGTauhj+lPEQX+kCbk/1cktWSVOGsThqdHvkOb93s0YfBSh6PW1fA8IsbfKwxX2mTsb9CX/H9DR9q/D/z0V4Evw5/7Ha3ST7UBXbsPv/qtRoMvAn+EGGrQBO0tsrlf5fkr+/tdErV2PLskdeE1kvL0Ho2/dECu09LbXqcdgPmQnGY2bm+LNn8TIqBuEFpWaD6ipa9o6BpRnRFl8cMkPfI+UcITWmreu30urpGVtpf6eH+yj/8b5Kjel4hw1SnZpymf90lKsTjTQL5PjKxxIMDnPdrhFUYkfzVx0L7b+/n1NLq/R/jTYMcKOT1yu+PsRzsu3wP+LuJgvdXbULlo1J72vjQ0lAUGMu4U/Gz1325x9vTVVXIAy1Yf79/Vyxx13B4Bv4ZEx+8TJXalt6vi3Can4Woo7PR2r9F41kMipDkNXuWKYz+hscoyLfj2bdrcfY6h8QxN5hzQMpOdZ4MtrxZcT3sfP0pLJ3yrj3epj/UVmiL9EyT49ypJKTskKbkTkpL3FXJATV1p05H9EsPTI++R09B+ouPDQNeMltr4EU0OvVrqPqLJzQk50OZqL/9tYjhcp8l7HdWfIUEkjbtX+3j+NEmn1ZG/2nHzdu9bPrC9b3bYdfiuMv/0yKqbvtfx9aMknf79jte9Xubv4azefEQMZ9P47hPn6m7//afJQSk3iVx61HHz1T7On+h43qHJjLvAH+9lf4gEVAxmaQir/zXyb3eY/ig5PZLyuzLkOpnbQ3IYyA6N9pZ7/8rxX03jle92mNbJWVamXU9p87NLTo/8Mk2W79LkxD5Nbt4kwegbNP36bYbpka8Sp0mZdUoc4/dodPAjhNc9TGWj/6Z8OuztT/rf53rfP05Oj9wmqW9X+3g/w1CHj58NEswVB1+g0f7PEB5/jaTXVWfndPT9Hk3lqrsMUld75IRsF6jBk32Sqr1G46EVGh7fJjLX4N8dhqdHfpc4YzrBBtMNehrgM0BTn7dpc/LV3s63SGr3IxIovUXDvzpwk2YLrpOMiT9N9LABsS2a/nid2GI3ySmXpoVukhNJPUjrQX/3JYanRz6gzZPOvFsifI6BH6PRgtt8ntL41WCiNGo64esdhl2aLq+BydOOl50+ni+Rk5E/oqWFf5azDv69jt+vkTnz0LwvdhgMZhnw/YimP1wRfJ2zzuCPd1h+Q4fnJ2jy53M0GXLe86lw2oy+HhIvWKdNpWDUeK+Uk8AhHv0JwxMgbWuRnMbzEVkV85392579L5f6Rg4+KmUlQCNXpwzvfbE9DfZZr+9vJyTqcFraNxpey4kbiAF6SDbnPyU55xBBNuv/10ofGtrieJ/hUaUQxelYDhlGi13B2SfpU+LbOZCp61w8LTgTPufFsWqAOebD0v9jcpeRwsu2ZTbx7XPM8EQvBb2K84jhwQ1G1MSjeBJHU7K8bVv2p0D0lCLLHBLHRFq+vkeOmvvtPwVv/hT87X8/XP93WqNvtcrSx/KorQqfBq/KflrwvlzKSw9TQm/isuJxqYCm4evYZ6P29ohDpOMAmfvFUb8VFxpzRnIhex6qDDgip78Ju4rM9+LbubXslVJG/Diew9K3bRyVPqQHlXh1Dijj8f1+ea8hWWVT5a9VcsdQlYG75ft0Tl/yz17BrW1AcOtcOG97ZPWl1p3SDFxlhjiXvyF8rUFReW9Kw+dC/6yMrPLFiPiUGPSVlqXBg9JufWpkeL/34RweE/wvkhXdKtelF+niccGl9Cu+1RfirMryA4b0vkfwXfEjDBp98qf1xZ/llMHKdOWLtDedU9d39H7qGCvM4uyIrPofljrLZDXbca8RWSyNPCbpSeJCI8X58bGMbVSnTVkjbyg7faceqL+pNytNKxfrXtUxr1W4/KxeqnSizPRdlWtTguflgkMNbWFfLvAry2oZU6Cl86rfjua0cULubpwSPlGP7hP5IT2Lmzq2aYFZ+ehcVloRb9L0IsnemDHU/dWesn/xWOlcmqryUV1fZYT4Mgg+zuYYP9MCt31ORzBVOCkwzEbfITTkuKu9Y7lqhy2R1eopoR3LSD+Py3fthHn8L504HmGvescVsbHTVuVslV27RJ/5TjnjO51X9eK8uah2qTifMrSHTkblppydg8Uyzimxu06JzvcRxksMTzhXxk2J7VvpXvj2GT6z8pvw74/qTQucPh8xnHPK2Jxvxy/c9lPt0bHdII+Pdc8Y7vHzqXDajsjhHDBcLZiSpfNv9bIbZG/NFjFkrzJM/1uied0uPe/0djxeXsN5sbw7LWWnZKVvufevsDcyXSPEKr+fIel60/7btxgemvERbdXiEomeLJNje30OSSqZ0UBTDHbJap3RdgUDpd9Zx+12h/de78ul5l2yrHuf4T4KcfuIRPFO+7hMY1gkKTObJOWSXqcqQ4Wikend/n27191kmK8tHdwjjpJCWYFCx6VR5eeJcPN5StLmVkkE+9skXUhhuEKLPn3Y687IZblGBHcIDWwwjH6dlHHvkGOXFTaurjwP/M//DDkX+Du9sR/7d1q45w7fX6a6915SZN8t458RR3yJYbrIWwyvnVgt4xGeHZLesNjxuEkEqysoB+R49lMy97U9V+5WCy6cXw0/ncgHBWcr5XcViPxwSFIhj0gu+TZJfZYOjOq9Q4IICtvt8r0aHsfkiH0KzqTZmoq4wzBVxuchuV9qmUZTGrkbHW758EOGjrv08JAoOg3V9/r7b5EN7x/0NkxD1HCcddw/6eXsQ2V3VPAj7T9gOC8aFNVxVIZAUj6e9HfiYYfQ0yq5yPcJUUjSpLJDeny391MdG/egVV50TBv9/Xb//JDcJaZsWiD89y4xDqc0uaOynRKaUvY+oM3fAkkt2yXHXEMcz40+rkdkj8R7ZNV2n6Rzyk8nxMCY9P97JJV+maTmPSIBhRoZn5IN9lPCcwb/1nrZ++RIa/nwuOPrPnF0J71/5fO7vd2tgs/Lvc4mucCZ0t4qSVN0D0c1kMWBuLnU29qgiT3Ho1xVZo31pvPmSpGBxUckRW6f6Dl1me8M3DwgaYbO85QWUd/tOFgmsvWQoR2hXhLvkDQw26uPMu2QrDgddniViVMa7S2R1f+Tjp9VknJ3meHKzSk58n/KMA38HnH6DvoYxJl6XVrZI+m+0uISWYFTPj8l9GJgQXl6ROblMnEu32coRw9o8/+YHKFvUHKt/21y8Z42bTPHqqN8TJuDPc4ay/XzbPR9i8gXCJ9eGtWZEp2pDnQc2ooe+b/fx6HMXSKHzkxKXfWHc6cjrg0h7Muc3WcHsXOVg+8TvSf97va2tksfuwz3e0oz6kNhNNh3QNOvU5KSrANksMj5fUiCtjo3Op+LxH5dKuOpTvpTcp3KMtFpysejgo/3ex0XI6bk4Bsfbf/HJPtIfXlIbOEtztLFJtmaQy/3kOyl/Ijwpjh5lzjaR6Wuj7z5Z8hBNt/l2RfBfyqctl9CE9oObJ0INIgzcp0oXidE4WK6kAS4UsobxZj0dztEMPhut7QLObzgKlmVu07uj9GgURHUnOPrZMVtVt4tEaMFophMeRD2K2QZ9ogoQNNOVsnJQxNitNZoGCT1BZL2sEZO7Vkn0Y3rZN+H9a8T41kmr/1oUHmK0kLHz7Tg8Zg2t9fL91mH+xpRBNc7Pi4zjCJNyD4AHa5rZN+CeFeRyCT+7nM8akM8vUCiMkaQ13oZ50ClaMRJmKTTGj0V1+L7eoELYqyu935//sebIHkX+MqfyiXXD2iC/BvAravw//xdNIviJ+EffpT0QoWrK0k6JLV/YVsr4/HdMcmbF0/Sm07itY6L3V53nRhmtT1xqwIQrusM97MsljIVLkoZ56/miFtvnThVE7LqVPH9tMC5NGrvCRG2Oii1X3lB/Fwm8kS81Odpwdlyb0ODQKPhOhHm8pdBJvlLOTchMsm0PnE0JYa55cStypnS1nHpy7H5jOdFI9R0a3FwvbSlUhIX9PFcIvNzteBuRuhHvnC+1ojRtczQaIHIq7XSz7TXfYFEsa+U+uL9BWLw2O6E0I+PMF8ne3HWCe2Ls83StvJs2vu4SmShzu86idYrFy4VnK6T1B2j69Krgcirpa7y8YCkeUIiztVJmhT8KLccyzHRKeqNK6WOOLtK9gXqtGm41RMTXRVwD1QNyFWnTVilfXGzQ2QpZPXI8upN+jilawOX6k0d28OCxwmhuQmROQul3+vkNNVZGfeE8PIyuUcKsifrmAScFsmcTkp74mCB6C7T/3RyZqW8/a0x3KO3RgKll2l0r948IStmPhOiN+n9uUJ3jfDLVUIr6kTrOrbD/l6H7YShHlSOVlk2YUhT1TmoY5x0GLQDPKColjvvUSap7ypv7hRYJ0TuKbtPSzs1ACFf+CyOviuf1Zmm86mnpEeDfS8Q/aLTZn152Hu+Fsp3x2NZYVFnVpggq3naLLsFF+o9dbdzos6RV5Z7vx48BUn/VY5XuE0FlI6WGMp7f5MetG2qQ/SQ0I0yxOeEyP8qHyZEhkqjwnyVXElQ6R/i0C3QbIBJwZfBuaojnY9Dsnfasc+IrFkldxpPiIydMLRHa6om5MAyYVB3vsDFz6fCaVum5XFCjjPWmNohjsTrNOTt0HJzJ0QYvkw2h271/2+S6K1C9U2yfHmN5HQbPb3T4bC8xLJGNgw+Km1oLBtlWOnlNkgEe7m/M5qwRPbpKbxeownjzT62L/ayB+TCxxu0CZ2Qjea2r0KsEe3l3o5G5a0O72HHmfhZ7rg9JIYI/Z3KYJVEFVUSk/73BXLQg0z3Yv+/TJvT1/vYjLyt9zIb/fsdslKkYj2lzesbHQ8y8C3anhUVDx0OBd9aH/fYaVOp6biedNgPiCGwTIyYW728DupO/2ye+Q2iyK1rXyt93C+TyI5Gw0rHx4QW3flu/5Mel2lRmHdokdcv78M/8ALw714Cfjf/yHO/+ft72ow+3SxtKzRe6+/F6aSMxxW0VbKnTeGnobvQ39/s8J6SKwImo/Z2ySEXE6LMrpO88Rk5zGBvhG8NbpWFtKcjv0yctNeJoaYiWCIbix/T5vYNcsHxbRL51LgzvU7YTsl+RVemVokR8TnmR34nJMq52uGDppDE9evk4AKDHnfIyVpXaCtoOhBvEuUjrYz7VJ4Jv8a/33WQFsnxz7fIYRl1Y7irxiskiqqx6niUyUdEns3IsfrSwE2SdrxC5JlGlCtTE5KCucowzRxyKIxjN616uePutMN/h2EAZ5HGezo5wqKh9XmyN2qvv3PH9zGNH5Zo9PFyb2uvl18g8kx8e6jIpMN43NtznBr1GrdTwnPQ6GSJJotWSNT2RZIS93r/vNDxYt0d4lSpV9Y7vl1tppf/IplDHQYdXPFiypS0opN5jcj+6x0+AwXHZH/JfeKU2LeO3yWGukn+fo3oiwkxrtRLytVFsndkjSYr7/bPrmgflHfKwVlv3xMud/r7z/dx7tPmd6Xj9mXC+2+U3+UVHfZDYkBC2w9zg2SlVKdtqbf/Si9jG9oQ0op7tbeJs/Qa4YG1MhenHT6DGSckFf1lmmxwBejzJM3uBsM9bdoaW8TxuEvsKx2Sal+IB/Ejr00JTa3T5k+nakIOptqj0cotcn3RKcM9berC854NwlPHhF+18dS3nyPHzV/0iBP7nPb/FYZZH7c8aEBpr3++TWhvjYZHV5W1MdZ7ueulLgwv9dZeuUv21l/i/NMjtYW+QJySz9HobYfYT7do8lIduEWTHQaenpDVfUgAa6vX1U6UdoTzFgk4XSfXArm4oZ2tPlrsZR932NWbq2VMx+TC+jeJTjPLyOP2l8hVRa/2d496e9dKezOyurjUcSvtT/vvtzh75L9B/teJP7BJ7DjtSXnzmKycGxSsdX22aXPzOska+gLDg9vmPZ8Kp+0xbXPjLjlswuj6lBjVMuj3aJOkAHbSjLh+l+HStMpW5L5LTo+ckGVanSCIkS0BaGypBP7EP0Ojwr+P72ul2RNYlJp2gS04PO0M9Qb8ubfgnyOpdo+IETItsN8n0b9jWsqWEZo14jDtE4dOIS5hQyIfGtVGhly63yCbNg96vXdL/WOSL7xLhL6RNtMddknEQ6PcqMIu2Wi/R1KfKu6Nimx32GoU6WGH02Xt5f75HYZRG+cQslxd2zkhN80b2dLAOiaHLmhArhCGn5E0g53+9zaJNNVUP/vaIxmP7xFjSYF7QFJbPiCpmBOS/vWwj++7wB/5TXD9Nz3lNr+Zf+p3wB/75cCvgY+P+krHL20Nf7wf5br6Mo0ptIzVPjOGmw5u8v1Q/Y/swD/yX0awLq7wfUv8nT/TVviMjq2OmtujpSk8X7oyiGK5KUkvFt8qHCPOkBSeY3JoiqlsB0TgaewvkEig6R3WOSCRQIMG8vIxwxMdISsSB6WPZZohMk/x75A79YQZkmIm+qUjHcR7JOCzSwT95f7/PkmNEdebRB5pJEMcYvuGYWRxk0az6yQVqSqR3Y4Tj42vBpgZD0/JnU06hGM8Sy7idp9GEwaxlB3y2X2yP3WB4UqbQbBKZ1u97Fs0vuli9swK6NsknfOwj0Gj/T7DfXerJD1FWl3oY92g8d894kxu9e+bfTx1xXSjv9smMt5xLZLV1m1iiE/79/cZpkdOyMrp+0ROvVfqHpCVuSWy6ibs6rMrJO3XdDUzJ9Rz9wrO3uvjOiWB0c3e14TwgQa58kxdIF/CMC1K2lfGfUAi8ZAU66NS3/+bhC4NQn2v97dbYLnXf79PAiQTYvAekFNFr9F0nk7HCbmvb7mPVwdXXlwjB5wou+iwTGgHw2gn+JtO6wbD9Eh5ZEoygpZ6W8dEJop/nd1tsg/ITJAHNB25SFJPpVsdVe2rZeIwvscwhU9aWCUnQjtv8rDtTAl/6Qi4Yr1G6FbYdVoOO44/JEEfGGa6TDi7olQf9YJ4OurfN8gWAoM2NdvlvGebpOtBAmAVBmlpk+ARYiOtE9pbps3jFkPHzJWXSan7gKH8OyFOlXJa2qh2j88WbU600cRB3xL//XlZJ6dHuqotTWnj3if6cI1sk3iPRhfyy6TAqU2519/fY3ji9oSk4ztO7QVtAAOfPvJiXUXWRl0kTvtCHyckIHxA9gX7zEjq9T6NPtSfx+QQpesMn21yump10j1ttNrvq8R3EU71whrD522yv3uv4/CYs87d+PlUOG0wjJJW5TuP0RZG75/FjONHBfpJnzFsx8Cf/+fb97+NKKUjYPkEXnsrRoAGypfeevaRsxW+ef1fVOaTPL+Y/lU4Y1zP67+WGZf9JGOZV27827jeeXNYleSzHtut83temxeN46K+5sFe+3O14KI2NYwVkH/+n4W//g3gv4Tn/ghc+hf5fu7tc0tw6RguGTK9yvmb2lZ6R1WDAH+N4Votui7JasTxIv4777dn0Wx13J5V9iKcL5R2xnMrrZ6U8vZ1ynw6e9Yzpo+xA3oejOf18Ulot9JtbcP/4/Ff9Hnc3phmDQjNg/EXO0/z+OGT1h0/Yxk0fn+e7JoHz0VwfVJZKx08i4Y/qTypjs743fiZNx9jGhn3M++pDuYv5rmon18sDM+a1/p9/Lt8fZHMrf/H9ce/n6fXLnrOqzPG7bz+xuXnyZFPKpPOez6pbqyfz5NnVa6e1+/4t2fpy3G9855Pqnc/iRz4JP2N2//FPGO5cBH/axfUfp5Fh8/C7bPk7jyarO39lejjsYz9pLj7y5FfFz3Pko3jMv9N9XtR/b+cdj81TttY0VaknmdUL8ypV//GhDImmtrPPOao/S2M2pv3uKoFZ42cMcy17/Ngh2HkYV7deYwwTziM257Xr47a6Zzy8wTzPHjH+GTUhnhZ4uwcj9uBs/2O4R/jZlzOZ4mzbc6YP4Z59c+bpzH9MWp33OazaG+Js/3Mq88G8DfQzoP+o7Qzb+/RdrU6meOGxggZNzyvfJmY82gUzs7feJyc8/2id+fx8wUgDvpfIgGVWu50TvnxGM6j6Xm8P6bZefJq/L+Oe958V7qoe2bH/H6esmf0fp78m1d3Hg+N5UMN6Fw0jtrPPON4Hv+PcXZpTpmL+qrwjGlwPJ7x3NfP8+hrXnunnG1P2pvX3zycXISPeXJwXO4i+CpOXBm9iJcqHKYznicabHfGfFydh995cM/joXl9zaMR/07OGQdzyp7X3rw5uoieLpqXGgQa1/1EMn7Ux3njh7N6Y2H0dx79jdueB+OYlsb6bV6fF/0+j+bO49958nZeOdVd7WNc7lnPvLGO6fI8+MZzM4+n581Lrevnk1H5MY3NG8+8ORz3R/k8TxaoL+s4x//H83cRLZwnk+bpsjGc9RmPdx6tnadHxu2Nae28uWFOmXlzOW++l4jcvIiW583peTioz6fCafslDA8GuUpya31MofOElgk5JWuZbPA1bWiVbN4+pCFlwvDQEftbL+8mvb/D8v2o97te+uvZZN/fbyeiTaMyFcy0znViJx+QxQ5z3a8yPIjEJdojcshHzT12CdUlZRnolGG0cZ04k/axQw5H8ZjbdXKYh/XFpylf44NIhPdqwccRZw8iqeMxPXJC0m+c2wOSVrNYyrkQ5KbZawWfMuApOX10jG9ITr1wm+ZxlaSoLJNT4Dx4ApJ6AUkLuMowf1k8OWbbFvaqXIXPvQLTgsdrRHhOiTC9Suh3Asn1+ZPAfwT8LtrFJH+ctu7+rYIoc6fcaOamEidTIBcYHokm00xaGee50qr4udSbFXfios59jdauMTyQwkenQzr34I7jDo60L94nhA4c7oSk/x3036SHg9LeMsPDAE7JnHki4ROyN+K89Ej3YjhX68Rgm/Yy673+j5L7syp/yVPSqXLqgOFFrMqz1VIOIk9MLZSvTG2ccDb1Y300nicktbU6vMqaY4aHvKj4TZWE4UEkzzM8WMUxmiJsWpv9quRsax6dHfS610lqlvuKq7K7Xn6TlJX56wyVr+88qlq8bDOkKR/xKL6F0zSe49KGukcYxJX6CnJAiaw6ITwvjv3tYFTXdzUdcY3I9qr75Bt120n5ba38XvWwRtkauYdL3oWkG0vL8oJpVRBeqAapvGVK2dVS9qNSZp7eVKfKq8sMD6VYJ3ruuLd5jaFcWiv1K32JJ7daVLwf9HKT0peiEkIr9VRWH2XXFTJ/0o97xJznpV7OFEz5f0r44aCUVz+ZQiaM18lJdNKSByQsl/fSSpU/4muJ6LNZKXNEaMZxiKejDn+lKe0r0yNVR9Ka8lfbao3h3J/31HR3dbOy0zYnnJV1854ThvaHT4VhRvYuTYhKrfNhmrD0c8TZg0gqDx8QXb/Q6z3tn4Wd8luVkRUP6opFsr/4eq+jHr1GZLG6QpxrjzwitDvp/c5Ke9pZVxjKEPnfcuqPY4ZzUJ2dHXKCurjzOelwXSaHYSlflkp55RN9fNWmrLbFjPDI04IL8bdHeHisFw84qweqzF4gvHlCUpjl+6ujutDi7nWbwuoIpvOeT4XTJqFoOLsf4ikRlqck132PNgGPGW4cfUwY5oCGlG2yOVeFZN6rwugB2ZQuM+wTwvb9A4bH9F4iaWsLxKHbIBvzj8hRzRKC+6OmRLFvkZxgHQtxs9fLnRLhqJA2h7k6bXWlbbN/3i113fS8TI6f3SQbmW1niwj63QJHNRCPC+waOrvE+N4rv+2TjeiO3zx6aUCcLJC9D87plOH9ZFVwmd++QDb+VsYzD5/St2N0PivziWMf58yDLVQSxwWfbg42V1zD16O7j4jg3ST5z9Ljh2QvnvOigD4mCnEXuGwHdIT80zTu/1HaXss3aAn1m6OOfeqeNjWJiJz2zwtkA9NC5lbjpzYnTuUrQdOw8dnn7D17ggehG2lPha8xfNiHtFPeabDLryqdjYK3Y6JAHJK8LA1Cm4OjUm+XyBWDFuNH+IyyPSA8ogzY7L/fIUdtz6PvaYFdmSR/QebgiOHJhP6mcysP7/XfxE817ip9y5s6EIeEhjfJyXG7/f9mwcUuw0NK3N+iY62RLUwHhM+q3FWRKyO82sCxz4gi1IGUR5SBPhVe53McfJkWOB+QaxfcX6I8mZH9GRRYDXDpdK6S/T/unah72iqNrjI8RXiHyC4NmeMCr/LoUW+r1q3yZ0rowvFAZP9TIu80uI7JgTziTF2jbtMJqvVs9ynZa6i8Xytlqj6qn6vucTzK8QNCe/P05jJxJOQf+Vp8eQ2AtKBBftDxskXki/Tr/KnfVxkeZe+Yxc1BgU/atr266r1AgtAGNm1nv4xri9DeCdFR8soyw0OxNslc7RB6WSw4eFzGYbuehulcKk91fsXhApGn8u8JsY+0iRzLk/LbEVmtdU5XiF1X9ynVPW3OhQGH8x5trMrbygttiSnDk44vesSBMtX+KwziYInQoWXVR9pV/vaQOMXquxNC884LhB8dj9+VH3Xvb32UhVv9u+1VO6XatCe0efDkax30U2InVRxMCT0rC6seNXA7JfTjnGvTSk+UNvcJrT7grIO8T6758p0y33ryC+QsiwNiY43xJK89ZGinPCr4qY9yyutyILSn/vbwqFWG+yuFcanU9RE/Xg22T3T4Rc+nwmlbJScu3mV4EIAG0Qz4OonCfYbmgX9AQ8odhp71Ku2Kq3fIHRjrtFNojApOaNHvH6IdGLFETo/cJKeNbdCI+htkw/Ave76Ve/VJjJ1pKbdFy1bTGfgGIZDvkQ2zSx3mL/W6M9q5EJ4Kp229RE5kukxOXKrRF50fFddSx5kO700SxRLnb/d2vkJOj5Novkaix5vEYNIpMUr2JonI3KNtqLzR29iinWB0l+H9INf6eDRwb5GDQmqk6zbtXBej8mu0k8BeZigENsr31Q57nyKgKZMVEqnR8foauSdwhTaPXifxmV73lNxRdr+P5ya5LuAdzq60bfcx3+797TO8n+rLJGJr/a+Q1eT3yUbWJVr0Zb33+dmVggC1yM1e8Cd6oVeAf3cB+Dz8n/9sBg5ZBlbKv0rCS4Z/9EDW+f5xWW/+qbaA9ypZERY/e4Q+1gou5Dmd8G1yOqU4m2fgyQ8HHUT3h64BX+34uU8iyJdoNCeNn3QcK0Nukg3DGsMHNINGGjztc3CDKNIHJKJ6m/lpDiqURdrcfZ0ol+/1Pr/eYfrpDu8bNJpX0G8Q5bBOo8vv9PdfK7h+m2xqvkbjDXH7DuFdDdoP+++3Og5ukOj7jVJ3q9dZ7jhRgSwBP9zL62wc0+SZc7ZJAkhXyKmHhzRF6MlhyiZl4gT42d6PMkyjDeAHGNLZCTlk4hZtk/ombV7GKaR3ejuXicx2BeWVgutph+NrHbfv0OhLg/02OZ1SJ055Jr5fJHL1u/3dm0TGV4NLvfbLSYT1EY2W7zJcqb7O2dMj36OxvnV3+zsdkl0aT7zWx/Ogl1snJ79p3GoMrvc6rxScfaaPy0DF1d7eGrkqAuIQf4UcljFheIiEjp9BrFMa3Xt4wdfIMdfes2jw6oeJHP8emTfhUL56yMohOZV1QlbRr5PVM+nvS7ST+VbJnV4/2Osvdhx9kRj/8vk1YgivESP6ZsGNRjpk/qUn9bgroVvEWf0KkZ2utH2t9/MO0bnv9fa/Qgzzq8QwvE3jOfX3a72/D8jqy36HRVoxCHGVRmOXO9z3yby5qrXRx/AVct9hlafS1KsdT9LOGo13p4R3XiDO8irDrJKqw8fPAxKT1Am6S6Pz75B70+7S5hqGsvt09P19opdgmOniIy3Jg6rUjxjaWG+R00Lv0RwEVxKv0uhOHt4nB1kZ/D+h0eSd3qawy+cVJnr9jTLOt3sft4lzsE2TxbdJYG2L0JQrbWuEdq8Rx/0GOTl6l5weOaXNo6tL673cBjExrtPmRdtugch9ncYf4KzNptnyVRIw0AlSXipXIHbmLk12XCntndLk824v8zpNDtPx810arm8xpIv3+t8Pkjn7kMZLX+iwe8XD1Q63gd4lcirtVYbPYoflGzT6gGazvAT8OOc/nwqnTUOvLperuGtUa9LfeTqVzsdyqec7Eej3hfLOOisk5XCtvIMccb9W+rP/7xeYwcqTpPYYzbtGUhlcfZswTF85JNEN+5mUfu3r0qjcZXIk/UEZi1FcCdjIxoQs6Yufy+QESvEzIUaZxpinrZ0yxKPRotXSzoQs5zseyuerJAJ8Uup4iqOwOFafipcjhriqTtuEnGBpGspyacexzch82u9iebc8wjEkxcJLZCud6nQvk6jO4ajMGqFjaczxC5fjEu6K70tE4V2DIeEbAhVxercPgM+dwg/9WfhtvxX4A/D7/0IGpIdfL/1aIJNQLY0OmD9dKVV8ZuQEOY1O+boKq0OS3vd8KX+pDAXiOBuRM6BR6bbO2RJJ6XJur5FI5YShU11pTDSKWoM6JyQ4sUIU2PixbdE1IRFrI8sTkjZh3861dTSoNVykq0qL9iU9iFtp9KB/1wlVntXyrgLUedEItbywXiJpcl5av8hQnu0Rh0wannV86GhPShnllHO8z1C2CL9tOXblkDiRDdbIqu2sw3eFsMMxoZ3LI1yfMLzWQfqyrjhbKWP33VoZh3LVd9dK20sMo+Qzwv+QFNwJQ5rWeJqVsvbjd/sQL8elLccD4VsNPuW8enGNIc6UgScMUyiVf/Ir5fcq8wymUNpQR0Hkprh3PNKCsrK2o94c64E1EhBjBKt6ea28s21pSxoxdbDWnxBeUr6r2xSX6ssJ0ZnHDJ0C9fh4/lyx0emZkECODsNYdwuzPC9+1ZELpc5lQl+OQVo54SytjN9d4uyK5ROGeoyCA/ms8s4RQ9pQPiyX99L6avle537e8xHDjCTnWR1Q7cQJz94rJA7UE9JqdSSUqROG97RZf1LakaekJcdsuUlpUzoyAKC9UPXsRU7bhKHdWPEtfUhfk962q63Cebn0WfXhWI5X+3WR0Eydd8tp31R7abG0qR2wylmb7WTUnu+kS/uQ9sXDlMg760HmbgwnvQ15a+xcTRjabHTYlZHye7WjlatLpd0KCwWOKzQnb9zHec+nymlz0CoPifeI5HbD0MCtDpWKtBq4E0J4E4a5yLXc5fIOhhNbHY/vM36XmmsfDZ0ly+0R4lb5LBNB63sFl9ElJ06PXsJWeEuIV8lEa7RWowiyL+KU3J9VcXSNMJsRgpUyxiqUdhnmuIsfnd4JMZxVLhDGMDppusRV4tyekHxhceLKYTWQDgsOxKfCS+NaBl7nbDagwmhCVi9VDM5/VebOgU7m/5+9fw/uNEvzu8BPS5ZKllDWLzJDZG5W51SSM0X1lruodtG95a7tpj2zPTQzMdhjwja7xhh7CS94uRmzyxrDgsE2F2MIzGW9sYuxYQ3G2GA8zDKMPTGz7entcXuamilXb7rKWS0rrUqhDFnil6mRUEr+qfePcz79fd5XP2VV9xhTRMyJUEh633N5znOe+3nOeZ23eNxgaHw4nor4aoG9Om0a5deIQ/EMOe+gs+18HMP+BtpFi0JN/Iho0ENaCO6Nfx1+zSr8xm34xq12Dg5CGHa8xEUL2gXcGBoN4sBuzhh+BkK6mTD8rtAhOSNaneSF0heENhcILznNq0RYOm2N52v99wnhV/8eO22OpQE0K+tSDeBqiM7baTsghqy8NCvtz/qzSkfiRlzt9boqR2WSQSBxXeWb8xW31YDUyHIpxZt8yKjtlGHQSgNIp+28w32FxodXSTrwHqEB6eO84/gR4aUzstO+QtbYdVwofULkinMXf7adEBlk4Iz++xoJdigPK940/pUx7sKJbx2bSYHzpPTj+NXQnxCn7SpZf3VZNbbECVx0tGTvCTGe6vpfLW1dd8/1HZW+xa3jSdeytQZi1QcrDGnrrNcb603XaZHQwxrZba30cVrmLw6XS3/PlvlMCa6r3nQOR4RHxMWEXJ2tA6mxrF5UpmtgVZ52vOpoiLtqwNUACAydtoWCM/ubEZqs9CQfLhY86LRVuabDaf0JQzox8KL9UWl0QmjgiJz1qTbNWak3IQHU6lQoV6ttIa7U/TB02tb6uysMaaqoEmBozLszWde1rv28Mu1txZPzEVeHNLlgf1V2n5d+fPaQYRD8hOHOGwyDPNKJ8z8ozyYk0Oecxk7bBimutz/yirzo82rv1eJ4E4ZOuzxs8NNx3SF/xEW6VWZK09Xhs55yRhkq3dYx9kjAwDVQFi4Sm0y9M3aCq8N3rT+reklYlhjaG+vkI/KVf2vw3Xm7BtXUcawxXVxjaJdXPhFv4lbds8z89WYEp3b+s3Pqjcv7BR/+hpYZUVL+fV6ejUtlvNno7/H/tR9/n8+pO6/vcZv3q1fHOX9K3XE/43ZPm/vTyrz5j+d+Wbv3ez5vvufl3byxn9bn+Zx6T4N3Hk7H49fn9f24z8voq/Z3Pqpb4buMJsbPz+fUmdfPZe/HcF1AwrjCGJlT4D85hv/3LfjIPwZ/159oeQSGPC9bwDnEO4ZnTLeXrf/5nPfz5v1BaOdpfDR+fxneL+vjsjUZo6X+zKOrcdsPUi6jk3nvLqP7efi9jCzqu8vGvKz9uJ95OBvzztNwOq/tGN8fBK/zeOZpumSeLHgaDV9WvlW5Z38fRM/M+3uMk7EufL9+L8PdZe3mtXmaDJwH2/j3uP48fIz5bAx/fS48V0ma4mX4eZoMGMP/NFx9ENoYt5s31tPq1Dl+ULk1nt88PTLG4dPgfT9ZfVmZB8d4Hpfh5P1+atvLdPxl/X6QZ0+Dz+fvJ5suW4/Lxp03/hiGOu63YideJs/Hds0Yvg9qbsy1VZ4C2zycPW2NmfP8aXJ33N/74XBc5un3p8lsGMI2HvOy8d5PJ4zLh2Kn7ZSWY3pA8qpPuHimbZPmIe8xvCDDCL87XXv93T2SL24k6B45cHpOE+yb5NC2N+Pskyi0u0ybJL/dk497XDzTtlnG3adFJTZJdH+b4aHXE1o+tLAv0/JlKTgwxWbWcXBWxnBnyuh63Wnb7M/qeaMHNK/+Hsn/3SSHso3WbZKc+AcFj6fkUOtZh32/jydMRoL2SN50PdN23H+2+5wW+9/ixPXyA4a7BTajFzVyvUXOnHhwdZwf7dpKN8J+3Pt3t8RobhVqwrbX+1kmh613GR5KPul1tjt8rvWU0O0midBI+/fJpQaVbk37MgXklz8kYWelg+E3kXTSOzwjN/ysA7//34Gr/w78/a/Dx7+cgxWbfbD3GN6qYVhnElrxQO68M23y1XF5d4+LZ9oEyYhfjdRCaO+wt3lIUvi2Oph7vf4Sieqfk/OK9wj/QC4hcPf+kJzfkmfe630ckdx303tqakct0oa7Dp6Rk1amDD+6XHcb3HFUJih37tF4br+3FdfWOylzFLfbJD3qrMCwQPjfNRBXte0ZwzNt8vFmr39SxvajqDA8SO3cpgWHSzR5prxQZnmpj/JVWj8q/RoRhcg85Z30uM7FM21rZfwpuTDCVNXd8u6MXFp1QKOv5V5nnVxsIC63ex/bZb7rDA+Sb/b6Dwps9UzbVpnnQ/Kx7RWGlxhMaev4Lm1ddslOIX2MXZI5IPt/nfCIZZPhpRqV79xBUHapq9wlc26VlyD8u0Xo+JCcSbNvxclZ77fqCs+jQejb9lWOKzsq7Io11+II+N4F4DX4Qz81vAnP7BZtiu3S77Q8cw3GOt9LZc4ZXsTljuUSTX4Lv+MqM9xZMCvhsMOkbt3vuHB8z7RtkYsT1slZUW0i+/NSH/X814lds01sJ3ddDjp8Vwtu5dF1kgGhbJAezko/4qfKU2nEXUJ1nHUcf5/Q+W6fT5XPZ7z/mbbdUndKPpAtnUi3yrDxTluV5dWegsvPtC0R/l3vzx8Relon+mqN4eVsK2RnVB4WxkonJ2U+8ujT0iO3+5hb/X/Piy2Sj03v9j4WuHimrdrQni+E8K5yXDvONVaemWXiBVvPFnxWWnGOix0eZd0qbT3HNpu8fq/As0t2gMWH8IgH5cq09Kfuq3RR7ewHhB7m0cUWWbP3ev2NMu/VPp5n2sSZmQiPGRbhrPbtNhfti3H5UDht58QIURAel2cKimMaAk5LXa+0lggXy++j0seMCHWZ/Ix8WqCOzwiWU2LwCdc3+sCmQZyXNscM4Xd7WUar8/J/YXYeh+Wd9Z6QG4UOSz8wVIg6b5Dt65PS9knBzzFDfJ+Ufo5K2wqjuDsZ9aswmIfHo4Jn+14l52t8d1raUdqO6eOIoaHm+4Xy3r7sT7wslfrSlHPzvTimP3vCEIajUdtanEeF/aTUO5nzrvZ7OoJpTLvfXABfykCz0tkZwwWeFWQdAv+nL8N3Ab+CaJIfLgCIDCd+NJzHAkPhUun9hOG6HJV6dS1VRtVJrwaW7U2P9mc8ltGpMa0clx/ppdK58qPyonQ6bz46RONSeWOB0LRwC4tLIm0fzeljHm0ccZHO67txH+JRWUCpe1TaXNa20nqtN4ZvafT8MppXnp2XOho/GqYa9TMi08dzd42rvKg0UNemrmGFbYXL+a7SzRkX5cM8mVRhXCjPjks/1Tmu75UvR+WZLFyfz0bzqW1r0KPK6upUVJidj/M7L33W309KPQ3Xk1E7GM6njlMNS/sQB6595YmKi6o/qhwfr1nVPXVN/oVzWP2pZghVW0FHdLzu2gH+Pi5/izPpVDhOS5/ObUwXFvXSYnk3ljPCpM6tdk/td5E4/zMiY6pd5BwPCS+77v5f8VlpZWwraC+oOx3jMj1Y9f9JGbOugXOv9c5GY1uv6vBxcbxKl+M18Nkh728MV3qnwFRL5bHj8rzysOtcnyujKPWqjVf1x7z5QAKT1e6xuEY1aOe6jHXeIUPcK3thKJ8p78d6yXq1nzqXaivXeUhT6lNlqvbo2GarNFOf1cCw/FDHl5fGeBrDX+VoMXUGZZ7MrjKy4kncVrNrkdD0uF95d54svKx8KJy2FdqNNmf9902CICMGp7QbadyReJ7mvZ7SvO0Xe7t1mle+SrvZpSrNG/3ZI1r0YYN2643P9nq/9HbXyfcm1mm3LE07DB/5aOv4+Z1ETg5KPR2Slf7zCsPdgFViRKzTstXWaTcGfmeHid7Hz/T+b/afCe2WG6MZK1w80zbrzz9OIjy3e5u9PtYnCLF9nOwayQAvk522xfJzSouITPrPSyRnnN7+Vv97kXYD0idIDvRpx+sNEnn8GIn4rxAj5E6Hw+uO1/s8Xi71oNGAEZ218t5yQiJI7tKdddgfM7wu2HMSt3tb/Z313s8dQqcqvLUynkbLCzS63GN4K9xaH3dCmH+/132u11EQLTNc+1vQrna7yfBM2/PkUIeS56XewG2tujVmCOzfon0u4G/92+C3vQL/3f8LfgOxMhz0lTbnWx3OCcMDs7skCjchOebyl2VCorribMLFCOjLvb8p2fBz1+XjRJFsEPp/nsY7e/3dK33quzTYVxh+OuCAtn4aJLOOsts0mvB69QnhUemtljUSRVzvsM/6PI/6+48zDCpAbrmr5+FWGMqpJ72/SW8jf3uuqeJWZUGZE31MafY2OSv1naXtOjnTOiVnGZRdOkp+vqLKM/G61/t+nuB2uf//CWLw7ZJzaUb73clcJhHJF8n5FEgqzAr5dILzqGfa6Dg7JOchp+QG1pdoa7NGvs3zCdq6THvbpV7nxf7/NqFp5Zn4fp7QiPLgFbKjqWGv8XHYYbjR3z/ov9UByrpbHb5zQsuzUdu9Dodn2tYJXUhn0Nj45TL+ATGivM3Q9/uEVjSarpEdnZtk7d0t+jjhZ2nTOsaA1B0QUbXf5/Ncf75GLu+6TG8qM24WnLkrf1yeOcdzmsic9P53O95e7PPc7e2focWxXiI3tL7c+9kvsN8o854QuvuuPg93WWfl3VIf+4UO9w2yA7za3y2TG/E2ia5UV2iHXCP8rVxx7urEOzQacAfgRUI/twoebhFaWSbfYHRMZa+GcjXSnyv4OWT4yRJ57eVe9zHRGS90fH6Nxju3yMU264R+fH5ZcZer7kzJm4+Ic3OHRkfzZHcty8TeXCAypdoRZ7T1+xiNb67051NixypvtEENBCu7Njqc8vA+cdrqZsMqkdu+q3JyXKSVhYKLj5GdeG3AF4gOXOPimbaaeeK3SW37CXKG+xYN98qLtY4zdf4KyW66ReSqc3EHa6X3N7bZTmm3Nl4leu6UfBJFG2GBdrMqfb5LvZ+qNyE7uer17yr9Pu7v7pAb5C0Ge18m5822+m9lzQ7hTZ3BXWI/vMTFs2qbHc5P9P62e73v5OnlQ+G0HQI/RVNeh2RL/ZgIgnPaRsAhbYEUtDskBe0aDQk/TTYPTHuBHFi+S3PsrpDvjPhML/dhh+cKwy1cheOveq8tyFdJeuQhYfRd2kL4HYwfIobpfZJOJoGd9f69ene/1z3p85XIJ73eBo3g3ySMMI6uawiaMnaXxlhvkRSMewy3uu8Shl0m6VI7xCmaMfzQ5wkRoPc7nFv9/z2ScqSBoZExIWked3vbuwwjEhrdXp2+2vvfHtV72NsuEF+mvj/ruKK/1xgygiwDqVzFsWWbpEA86ni7Vtq6juJxv8P+doH9cFTPdIR7/efHiKLcId8oWiSO5Abw8l+Ga0/KBGdEQuyTsNuPkq+fSgzWPySRit8K3PgL8NpfaPV/D/Bv0O733+ab+b5fol2LOy04skzJ1cVrRNlvElqG0MPbxDldJXRlMaBxQuNDnQXpbJuWoqADvkgT8Nc7vk9JJGxKaL5GGY1w6cxTUHZC0vc0FN9hfrT2YR9T2nNZpPtDmuyqaYgwpDlTmwxKyRMqg9XSZpsc7la2+U5DXSdU3vZa+Y3y7M3SVt5cIgGzPUKvRv/fIkEKcbFD0r1WaWtrlNfUrL0C05Q4uHeJ4q67ERqIlc7OOz6XiLxWLkkDY1zcLbCIywfkEwUaLrPen8b6IvCzREa+QT4345wc4+0C5zsdbj9EXeXUEkOanPTnUxotazAq02Vd1/Fxr7dd2h6SVOJlGg1Nep17xGjSkdDgfocYil7aYZqisniD6LbV3of0VwN00pw6ZZ35lwstjP7e7nAo3+jwfp2IrKo3N4mcWSWf49EBEZatDou6bNb71Kmcdtws0gznnyVOxzItFfWnS11pW+d6QhwFZddih+Vqb6sdYdHw3SWy3D72aOv2iCZ/lmn0pq5Uzyov1sn32ZzfUYfbcY3JvVnmIA+8RzKHXM97xKm7Qr4Np92hTSFMO0RuGqhQnu4SGeW63CM8cpfckbXH0Mm1zhUa/T1td2yPpCOfkYCEto7O9hMurse8skOTbzpE7qJUO+KcyI9626HzVv/dpdmCfpZA+bdEW/t7hIePOw7G2RQGV+715wZ+5u20+Z3Js17vbWJPTUmq4bt9jq6jsnedbI7cJRsdysK9MpevkU87uO7bJPX4GvlE1LQ/89TFYoFde0Edo31Ucf0G2eDw2c8SG9sgxRv9vePV78/V8k6pc0r0pzJxkziAlm2ik7U/pD3xt09oV/tCOV7lYi1f7bD8qd6Pdv51nl4+FE7bXyNCa59M+pQIzHOSFz0lEYkpjYjdmVghGwsidZ8YhTskMqQCqc+M/E6JoTIlhvQRjQEcd0oi6Ea6qlGgYH5AFN0ew3MWJ2TnYVpgooy/WP7XyRNmjR2dNg3QxdKPQlH8PFPmfUDOEh6U9rvEiDsocCioZXwjOY5TjfQpMaoOSIRQp7yOt1dwooJXoEwZfrjRHShK2yk5O6IPY5kVuFTGOrN+EFTD0XU8K+3NUT9k6FCrdOd9XFuBvkcUmk7iA3KDl+v4kBhSu0TIGaVTmE+Ba1OGTptI8wqwM/K1yGPiUVi0zPc78Fo7hs7+GeCfBv5BvrmAOlzuKNTuNHqmxPiHKHjLAYlq6XeecNHA2y3vpD3nL19PiVFpew3cWcfxCeF1dzqkW3lZw5iCMttp2DvXSlMW6daItIEI21fHUNgs0o3zmfbn8uaU4Rkn6wnj2ggOaVZZYH91PQ7K3xZ5c4U4OdPeTmP1pNQbyzMNJh0ueWNKztQJk7gSP46j8auMcJfAuYu/JbJZbB/KQIv9TIkMds7y/5SLNPWo/y0raRTIoxSYxPf56Jm0N4bNtCVp5Lj3V9lQnaKctc4DchZtadRWGq36SFimBXca0O7sa+ApW9xpqeOr29ZG/VWnrUa/9xmeXXJs29S/7U+46HN5RAy4MZ0pg8W7Ys21UPao5+ouuvL3kARkZgV/BircqXDnRdld+eak/K50Z7DHHT5LDegokuWRulPlecJpmaP6VQPRYIh0Jr+Jexjqd8/XyNPn5Lr3ahPYZ8XhAqFp+VeHgoIf5+LNfNbbIfrwmBjRzneBBHLOybk/447z5K1FmE/I+hoMV64clmfvV3YZnsU8IjLJUm2jqhe0A8TnPglKKlcMJNuHa3VEbArtQeezV8bWthnLOohu3u3/H5Q6ymXX1zU+JTLuiMjVA1Kk7ymxRfaJTlWPQuhIXSu/Tvt75apwTUu/2uvVppMuTsj6ya+2kUYdQzwYZKn60ffKkL3yXvw4xrjNlAT9ILT3gDicUxIArH6KzuM4cCAedW6NoY/HH5cPhdO2RNIQb5Dr52WKZdpEbhMBtEGuvV2hbb9eJYcCV2hbnRLpIi2ycYcI6PXepj670WGake18hdzzxKDZ6H1ucNFpc6v4jDDvbYYEqVOw1GG+TXaRrvc+IDs5C+RqXuFeJReAVKdNY2yp96uwEGca3HdK3dtEYddnKjnPbCwSZb/e53mL4ZW1pljQ29zsYxmFOCNX5vrsVq+/X/qZ0dbjeWLYrfW+ny/zFp/COQ/f1SFdI8rzNsmlVqkaMam0sNhhEyZTio6JkKoCfJF8zFiGPiz1bpe5G5z4KLluXAFK//squXJ2A3Ifsou+URCiNXGLhOslNItbARLJhFjXm8C/QMtz+BmaM/fvwa0/nbSVNS7utK2SKLi4kL8s1lE5LhHacSqQD08fE2dYpX+71z9nuNNmOvO0v7tDjK3rhJZFj7xcDZKP9j4U4tL5Sn83z4jQaFwkckKHSedPXnN56DCpeJbKz4TIJGm0bpJKw9ajvNP4rcEbCM3eKH3dKO+lRfmoBk9u9zoapKcM+Uu8ShPyhYbABpHFBh2WyaUKkAyF6pB8lHyKw/lBPqRu9P86F6PPt4lM12iZ9DFvERpVD7g+x7T1W+xzfY6ke0rTyjPxvVHmrjF/hxgB4tHA4hFJqaTUu0UcSvGmYe18rOfO1JShTFuh7QBUeoOkezv+4/JevNwh9Poc2WmTB5zvtYLrY0IP0vI64UuIfqy0L88e9rbOZ4UEXxVNNTZ1QGT0VYZrqeOgfJLXz4ju0yE6JB/DVhRWma2D9DyhIenvKnG61goubnbc2LY6qOol69iHNo7O/S2SOfSErP0qcQi0e2YM6dYgySL58PiUxlu3iKGtqhCH0rI6cUI+Oj5eN+OBs1JP/qry9GqH8/le39TrNaITt4k+U99V+vH5ZWWV4Rkw7TdlpzSmDfE0BxASWJbPV8pzy4y2fvKgdVSxN0jgSxsLYsMq328y3C03AAFxWA9JKi0MHf/xXNSft/rfT2hy8RYJXK3QcHqT6MA9hp9NEY/S7oSceRO3h6Uv132D2OrSlM4rxGaTF2rQRrlxh4s22w6NZu6UZ8qA5ws+tvv750iG2G2Gu1vKr2mH4bnSr/xzo+NnjNszhjJ7nehGbRppV0d2SlJabzFM1YQEuu6QnXHtj6eVD4XTtkrLzV6i5R7fIArXG1ZOaV8L14sWCXqxngda73XWgM/13wqfjd4HNMReoxH2Z8jCfKy/f4YIFBfjc2Q3cIXGaC8QZnQX4rPE0fKGm88QBl8nETWZ+LXy/Pk+Fn2u93s9GXhCW9z7hBmN4hp1oz//DEkTleiMDL/eYft6r2fEzH4+TRTKJklNcqvdFMfXyZm2t3qdWx0v27Q83VdJKqpK9Ca5/eq7iENZhdJ3Ab+M7OhNSH50Pcdyj2FUuOIbotBnJK3srOP9kOGZoglRSJBUNdfMvGOVjzRo1Oaoz/sTHf5zGs2ozNc6zp4lHyo9Az5FjqqZNuCOomt/s8M/sMrV5tW6UXPeJFurV8p7PaF9cke2VtSsA7bdkf+bgN/3f+XvfeN3MfuJGP4TcnPmHi0F4pDhmbYbhJZn5NYlDTPxPd5p+zQxvDZpNOqZtk+Tb77InwpQjYQzGh9OO4zf2VFgZNZImOunUfLLaLxlussmMWpfYL4RcY+hgH69PzeyeNCfndHW1ej/C4TmNsnNeeLMKN2nGSoLcbYBfJIobPkH4iCptF4o+DHVoxoym8QIndLIwjQqZeYxUUjy14yWciN9a9Ds9/rbfRznLx87B+FWRi+XOXyKpJLR22pcuBYr/W/J/xpJ99MZUmdc7+9fIucqp73/Op/XiIP1Yq9fo94fp+mpNeIkrJN0qRMa7SmvlGdLRK+9RpTzTm/7Mgn2aeBPabTySRLJ/Xhpu8vwe4W7fY6fJDcE0+f+OtkFOye7c+q5l4jRfafP64QYYsq358iOgYa6+kt+kT8hzqFOgeLqLRovvEYMpXsMjeex3nTdJh0HL5Vxxa3PIDteGskGdZW3yguNpl9KswEOe93PkrTlKtMOe99XyjzvkDUzQAgxVJUhyvIp0e+7/ec14rjrEL9GzuOtk7WYdfgMhCwRGn2R8NwejR7E6U3ybcjnCK1sc/FM2yI5z6hMOeljPVfwo2M77WPc6P28SnastBcMaDyg0dhz5BbpdeLUqgsvK5s0ehFPBzS+fK2/l1Y+TnRQdXZmo//vEn1gkFa6td5pn5t2qnSmjXSHGPRXCC06P52dO4SHpS3HqPrpRRI009HWbqzlLZpcfJ0Eve/09ruEzp4nZ9qUz5WmtB3Vhxu9rwcdjldIxsNzZIf3dp/DezRZ8yot3XCPZjfepOlWHTYdLWWderMGgnUqJ7T1q/S3QltX+c+dOO3MPWKXWjR79vpcK61MiSN4p8B4i3ZK5Cd6fxu9/v0O16sMz7RdJY7hCQmKvVLaWqY0WfR6x8WUJpPu0E6nXFY+FE7b/0BjmPdISl8l3Cltsb5CjDgjpNtEUb5HzhWskktJtolnv0xy9u17jUb09wtMO2S7cqeP8aUC099BIv81arhCW+RdmjEz7c++wtBA2iPXQRvt0IE6YsjAW2SL+iHJad8j56k03BSu7v58uczHce4Sp/Pt3udX+ljvkgj2V4gCsf0i2VbfJwaXQmeLnD2g48G0hz2GjtM1kqLiXLYYHrLVwH2H5A1PuejcPSDXt66Qg/m1n3f6WEZGzmh5xUc0OtGJUDkavdH5PCjPDsiOQm0LETbn/bfKYFrqfYWcB7xHo703yvy3ieMvjWx3nP1e4GBn6KNtvBelbaTu9T843GjT6ILQ/kPgu/58FPSDjhMNjWv34eqfhxd+y+/iX/u18Ou+1ifUCXz2b8OPEMdNPImLmqYBSfv0auslLkbDIM7MMcMzbWvkzI6fHlgiztFOB891NmVGh7umJR2R1EVp/qfJ9eH7RBivEPoflwdEdjxDW9tZx4nnTL5CozcNIxjuvMpf++SD1G/1+l8ha3ePRiNXyBXdlHcqXWXAbv9fmtwmKRg1Zci+VjpcZjQsEhnyhCYvlMXiYpvQ9zpJQTlimIqufJqSdX+H4dkEI+cQGe7cZ0Te7fW2Bl+UBb8J+DzwB2i4f6fAYhBQuA76PK/Q8P02bR2/2vsTn4/6u2mB47i8r/Jbp3yRyItqqKjXVObQ1nyb6JN3yhyNocyI7jspbafMP9N20mHeIQYo5IY0Yffdg46LJwVn4naR6FI/w6DsMQj3VZKSt95/lL/iQx2l8bTVYf9p8kHbB+TTPuov+7lH0t4eEtpaJTbDSXl2l+gbddVyb6+83e31Hvcx3yTniKRJHZIq+5Uj1die9jndI+cfLQYTlTcTIn/k+wNyls4g5Fl/tsb8M23rJJCivQEJvN4lOwvO4XHBg0GseyTFdI/Q4mLH1WnpVzmmDXZI5Kk8dkhu71RuaCdUJ8JMCGWS85tw0RYYl12GZ9oOSQbG3dKvwc/3K+oU9YnBo9pWPpyROxQg5wXHNtZjYu9pk0m7k972kNgui6P5uB6+U2eO9dBWh924rDS9R1vnI3Ju+iFZF+FVx52RM22QYyZ7JG35bv/7EeE3bV+DH+rtAxIcc/6UPg3SOK+xzXaPyBOfKR8r/22WfrUx5Jta7pIAo9kldPxoY3oO+A7wdz0P9+8Hjkl/py494+JO22mf/7uE788Y2jmQ83V/jpwZfIP3T+X9UDhtv5jczPZxmgf/mOSdekbkNXK49BYNge6Q1J02PenPEONvgRbZ+AzDNI+btEg2/dnH+t9LJFq03Pv9DMO802Nyy9pSf2fEYIsQ0Fp/JsHqmdedtk+Rg7u3SHT7sPQ1b6dNZrlsp+11Eg13p00CMqq31f92p+2k9/MauWHtXbLTpiDR8fok2WkTH7fKXF+mRRrcaZt1vN7g4k7blKFQerHj5oT332l7QpjkdS7utB0Th9HzY58kRtQH2Wlb4OJOm9/aqgJ8m+y0nZJca6NKr5GdNgXQp0jKnIJJ2qo7bToTjndG0kXfI2v4KRqdVIHifFRo92lr4y1RKm/HdcxXAb4I/D7gDyVp7pe8scmnv5SdtikXd9qk5RnZaTvi6Ttt0p6G6tfJTtvrHT/uACjwb5EUrzOyM7/L03fapGkKztxpm/DBdtp0TuX/GcPzBa/1MZ4l/PmdxNi/R1vTByOcLZFIOyRIdK3P3UihTuph+d8ddbi40wahbxjutKns3Wlz51BD9YjIM3lZo3NCUnIOSTR93k7b1QLjGglQuDvyKRKdd07rfdwXiBHzApGBX6UpPncKjMAf8vSdtk8TOniNOPjeJqgugqajXiVBgVtkd0+n8zPEgal8rGH7SYY7bcpJDfsVhjttr3Ucr3Lx9kh5e4XhTpsBKLNM6k6b61h32j7e350yf6dNeXODizttn2T+TptGqH/LZ0uEFz5Fdto2icOr/nJcd8l2+1g3afracXWCXiQphMqCm2UOyv5XSQq1htwrvc8p0SP7JM1wkQTCjhjeHulOmwEBA1AGI5QhT9tp+xTZBatyfELW2XnMCF89JobwIo1uXydBhVc7TMs0+bbWx3uO0IoBpQ2GO21XSarmGVnPGwU/Gu7iTZp6lci78U7bNj//nbZ1stP2iEbDVf7KL5/m/dMjDVY45j7zd9qeI7vd6tRph+c2SSW+Qm5VdX4rzN9pk7YWiR12QHbaDPysMX+n7dn+zMwLuLjTJr5fYP5Om7h0neHynTZp56TP/RbZabvZ690jmwzutOkQL5LgqDbRPJvtYYftM+WZNpPZDkskoPIKjcb2SKaGZdbHfkhuGFd/6vC7E2n5r+432+/FXnejP7/f53XZTpvyQd9h3k6bDqI7bQdEJv1eLi8fCqfNXF2VzCoxOmSiUxJVsu4qjdhtt05DzL/W628SY9oxjNwulbYTYgxp5KzM+blCPOsVkoO9TJR8HaO2VXkzgtsoQ412OBeL/a+VeldKfednJNPyTMGZ7dYL/OO/NYJgmLZ0UupVA6TO7QpxmFZKP3VuGjVnZY6rHY9X5owBF+Ec40pjf50IvvreslT+rw6WeF4pzyu8dPjEfaXR2tZ2lGerfV6+n4czDeXxvBxrkTiF9X3F8WL5349TasRfIR/srvN5QqPXZ0q9un51jV2r/89DWPnD8NofPucjH9+EXwn8HvjB28BvA96Arb8cQfl7SZTecVe5yBtGy+R5GO6wiIsnpX7lIXErflZpcuAHfwV844fg3yt4O2OogFWki2WsK0R5Op44mOe0VZxVOlB2ud5npZ78Ven7GYZ0UHlTHDrWMwxpUBoVfyrey/hwVtpS5rZGoslejGE951edJ6P9GgGOUXEr7nTajspYlQ502maEfsd8WPFZ2z9T2laa8/3ZqO1YnlT5o35Q5vtO3nI+0qd/y+v0vw3iyUvSzhmR37avc6rrflbw7RxqW3E+Tz7WgOVYp7iOS6X9WnlnfXWP/VW9eU52UF2ntfK3uDCCruyXLsRXXeM6j2dG/awx5PnxXCH0WJ+pE8Tt4aht1cXCX2nlhOgs4ajzqHq9tlUX67SJV8eYlXZ1PP8+H/W7Ovrb4GuFZbzelaZPRvhbm9O3baUxHQVl1hk54yS8px1O31eaUuerw4TrZASDdsDKqG3V4eNSeXCBxguVNyudqN+eVip9w1APWuo6Vro9Gz1zXpWfqzy8Mmq7QnaZpIs6Djw9PbLiVptBWI65eF5QG6vi2nUe03TVa5U+pZeT0Vxrf2PadtyxrVj5zjK2l3ymrK86ucqIv4/m/PziL/YX/1YQ+4NfAnbhr5zDd5i3DzCFX/dlhnf+d6Pg734LTr8Gy99NPO2v07x8I4vb5MrTHpn7B36izfMjz3aAbNvL3/0nYP8Mrv0K4D78+jfhb/5kH/+Pcmn5UDhtM7L1OqXh2YjkIS2KZKrZQXm+SFJvbHdGS6nQa95neEHFQ5Iv7nj12bTDpGA3OgrZahaGI4apL7We48owe4QR6hx0NA7IlviURHUdZ6nMkf7bfhSkCu+TUmePpGrt9TqPyG7ZlESRT0gUdka2uQ/KWEaj3Z1aIlv/C6VexaO7Oo5xVtoakZyUtgpNCtyPypjudqqgKk5VLr63ODcNQufpHB8ToQrDXYpzcnmGNGIk+LDgU7w7lvOWtqUF4bPNtNRXADkfDVlpcbnUn5X+DhmunzdirpEzmGdlPvskFc8I7AKhW9dnrazBV2gRti8D61+Dydfg1+wC/yzwJ34V/Nyf5PZ3E4vkzw5pWTwKv/QqD0EUlusiXiq/VXpcJpHfdRovu05f/6GkPKgQ9hnutDmGuBRnRwxpSn6Z57RVGTMjNO1z+euM4a1wezQaO2F4a570PR21rWMt9rm7++uaHhc8Kk8gNLtO1mONIf+ckHRA4V4u9eUTU7p02vZJuu1CgV0ZPi1zOCN0LlzKcI1Bo73i0bmLP+WabX3mXBYZ3hLmz2p5Ny3Pfea894m83R/VpzwT32vkgoYpjfd2CX+N0yNdU+F1bGne7/PJe8qLg1LPto5xTmh5qdSvuq/ylHLCd4tlPvKcjoEydVreu/Pi7pb0s88wBRKSHqnuUM463jzd+LjArEyekjXyf/XmAcN0Q+n4iNgXkAsCqnwWH8ejZ/K8OJ4SA1Z5RJln1QnaLJUmhVlZLhz+FiZvdlRXHhAb57z0oww5Y0jnCwz1pjQtbtVXU7KrNyWySby7bgcMP6qt/q/pd449LTiWDqV56ejZAoswOJ9ZwZUG+2VFXXJEgkHOu8I05ren9Se9wPAmTstZn7fzU+dPiZ5Rp0s/roGyTPxW2VtTjpXDVXbq6Bwz32k7GNV1zaXfKdH1ron0rnw1k+KwPNMuqPwyLbB5+3KlKee3z3Ad5HPnoi4zwHeZzaZOOWd446W6fImhbP4xWsbFP9G/J/Lgj0a/f4UcTfrUffhkTzs57G1u/Qzc+Zkhrdylfebgu38iu2XbtOyzV36srfkuTV7XnbYvdvytP4KP/8TFnbYf7rD8vT/Uduq+CHz3V+HOV3lq+VA4bY+BnySXjkxoEz8lC35OFPrbtO3JZ8hNkZvkIPib/fdL5HD/ItnG3KSl+q2RrVSfaaDskaiExKaSOuz9eiNSZSgdzgNyTqFuCUPywWWwZ4hh/RY5hweNEd4gZyA0Pq+S3Pu6y6bgg2E6yh5Jq3i3j7lJzrhMe917pZ+zgnOZ0HEOSYREZlskKV7X+rj75JyRwr9GQzXMNnq9ewWf5/3ZfXLZg3O/y1BwuYY6OSoJyxmNbuh9TIkQ8M6NGqV0HMsOWbNdGhOb3vMe86/836YFV94hBoVG0pREbLfIuUsjR7vkPIoOyTqNBt4kxplrvUkMARUrfQ7WrQJRo+Ogj2+Ebo+GW9fAMe+S7w6amrkCfO4Pwt+8Ayz9yZZv8J8D/wrwh+LkScuQc0SbJIpfDe7zUk+lqAFqdPaw9+uV8CqWa32+nl3cIgL0GsObxlTy5vWLR3FWjWujhfLhuOyRb7hVw1Q5oQyYkVTvc/ItHx2jKUnXm3Yc7fYxXDvl2VqH616BY5ucU3KM/fLua0RuOE+LvLlCUt5cA3n2lJx5rcbVHpGLylQNjyn5/pkwqYjXyHf8VOaLZTx3qpz7jPDEBpHX21y8BvtNkm2hMbJFUlE1Ok6Ic7RF42V6f6aEv0nOpdJheIecaZiQnQTn+aDX16mWn876mKbTQOj56zRaeLv/fpYYjs5DGVnb7jD8XMB6h2+LrPU6oY8nfSwdsnVyDkecvUOjjzOyVtvkG3HiWj1tKpB6bL3Uqfqo/r1L0hon/fkekbVLpS4Mz06uELmkkShfv030nLTkhWAaeKbqbxD5rLH6s73fZYZX/suLGuYa4MK30d/d5fIr/zeJHpdHqgMjndwlwZ0Zwf8Kba12SGDonNC39HKfrONjckX9HtH/hx0WaVldLP0ol5VZ1S7QPtIxdi5PGNpOroFnmM2COKTxlfQknarr1shRi8tKdUBmxE7ZJOfq/dl5Sj+W3Q6vdHdEZJJl1udiepyyST2ljbXZf9+lyYJ65f8aoRXHEb7F0Xy2ydETbZuxrINhujcdvndojsghobOr5Mbz6gC5y3jOUKdo305pOvQukZ8TokevEvkzId/g03mcdJhqEGNK0qFXmH/lv7b8QXnWfbFvnjtdIN9p2yV0/E/89jbJ30bsoU3Caz/K8Gbk+wU/tWiL/ShZM2nvox2GR0QHuHbasiskJbmWt4izOO3z+iJDvTyvfCicNpXCKm1xn6Uh4AlJwTglefLWXSMGkV91V2FodE/7GP9V7+P3kDNvbuNeLc8qIyl4dMYmxLg4IKkDGmv0etdIZGxWnkmwh+W3RuukzEmYIEbFQoFXPM0IU6kQq+O2RM6NnJAbqHR0xc8JyVtfJwQ+Idv2CmXHOWO4ZsKo8hOPJ2U+tpvRdpKfLfDqXBiFtKz3ekZ9V0tbBRjlnUwyGfVz1vs6L33NiIE5JREs5+UanJOo6uMC0zUS0a1wazxMiIKGRJ+lhxUSwT4gOf81Ij92nq6SjSyFrHjSYXCdan/VaTMAohMjnBqVlabquEblJgwF/Tcn8SdoDtu/Cfy38PmPN6F7q8x/Qj54qqHpjqawQa4MPiZK3stEfGfqnspMgSutXiPrJr0YlRVHJyS6qnF3dfR+rcNaebgWcUaH69n+t4oJYgC7i+RY0o3Gr30pk1SO9j8lu0YThgJ+ytDBke8hNCsfMmorb9Yo7gkNZ5MyT88DVVyIK4ixZT9nNH5VDp0So8OAmM44BRczYmjXHW9l5lWyUyPtWxbJGlZFqWw1oKTjKb4Pyt8GoJRd8hzl2ZScUxROnYdrvQ8DNdUhXSR6TnhdZ/WXeF/u414jwajaVidEntXoFr4nBeYJ4Y0rZKdtvbQRZ8qOs1JnWnDoertewn5K0kmrPFSOVd101Pu7VuZzRvTmEkM5fkjoVF04IcEv+briUaftCkM6kX+uMUxTU64buKu0rCyxnxq0peBslWEQCIZ6aUIccp2/WYfV+Tonn4l/5yUurhEj0XnARV0xIfRYnY0xLasnnYcysDqQZwz1oDRgsMe1qTR1QOSosNR64sD5GfwZ7yjVMiM7LdosyprqxNvX++20nTCkW8vYkah2qnh0LScMA9naNeJPmrY9xOivO/LVBlNeaWdWu8dyxPCM5QGhgbqGPhM32kPS+ylDWXeF2AVVFhp4Vz5MSGByvYwBQ5liYFv4DaQo08c229gWk/fV9wZNlPOTMjcNg0mZz17/rZyqdnbFWS3aeM4dQnvacc5F23KF2MTSX+VP62v7wtAfeVr5UDhtv4gIoqpcNHA0JiZcZPbHRMFNGObWXiNRrB+kEc0niNCqStxnIvawvNeZqESyWn7ryJ2XehKqC1gJVuNX4pMoqxMkoypIqgFt/Rkheg0CI2EUnFWnTbzpOOx1PE8Ik5ijLhPpjBl5mqc4VeSPynOI83uNKFUN1mvlf9dKnFhse6XAZ1vnLZ5kEteg9nPK8IxUdayMkmlAa3RU4+6QnBuqjkxVgjXqdsJFxakhUp30s9Le+sskdUGHxHfSqjxRDUmVp7Rgm+qMOh+F4xOGwt10L42syiMPS7/y2b8K8Keb0t+lRdjWfmtzrP6LH6blZ3+RXK1lKMwQuaFVi17bLyVe2w8A3w18GmbvwuIngS34H/4q/GInt0Db1rwB/Cw8+Ll2g6BCWnoZO7buTorHCaFLCP1KU/Mivzodi8S502lSME+I0zErz6SbJ4Qmr5B1Vh6IooMOr0ZopdFJgbvyKIRm5UNKWwpO1gitaxCpRDRSFxjKs2OGDsOEYTqgcAqT75RFRwV/C0ShTxgG0owNCNOE6IwqC2DImxblUg0WQfC9RxRslbca8dVAUV5VQ821MggG2VUcO23KMMuU0MMVhvpOB1ZarW010JSbroHzMUCoMfCEGNbVefa9OLtCjJ3qYMv3yh7Xa0JSfe1vnB7p/CEO6OpoPuu0SwveLHgc681qiF8r40qvwrLOxQCAgTLb+1zaNCAoTeksq9uEcZHobuluQvS4Do7v1EvSn/0Kt/N6tvSrjLfP9fJ7Sgw+6zmuMCpDpAmIsyUexKHBE41xcWBAQdtCPFUby3koho8Z2gZn5EIKbRfhdT7KLXEkPVYdPi5nhL+UaXXe4ta+5snuWtR96sZzon8t4rJuElBwcI3hWcwJCYxD5F6l+Rp8HDtt1oU4/mNZB7nNcUKcGHGxSHZDHdcMozPiSK8wDG5Ddju1la6V99ohwqkes572e7UBqyzUYdQmmmezrZa2PqvyUXxUPXdMw/n/8a+GBiFrJ0x1DYRxLJdhGCS1rzNiNxukEeenRI5Wp822FmGZcNG2fVr5UDhta7Rbb96hnde7SdIid4mx+AWiKG8Rg3iNlgp5i6Hz9320yPtdYtN9ngisDdoNOF8giH+5w7RObo98p////SRPeIncHmma116v9wVys9Fuh+/7iTC4Tm7tkfg+Rxj8Ns1GhaS/LPX5eQPaLVo6hE6hgmtGoqvP9Pm65X2HoUHymY7DzQ6zqRUqus+TqNE9koJ3Rm7Wu9ZhlSHf7H3f6n1t0W7OeZXcdinub/Z+z2m2/XWigBRKfm9mgVyV/DzN+XbekC19BdYXuJgfXRXaTn/2eYYOug72hHx48Zy2lb1Lo5OXye1qh1zcETju836VdhOZtLFX6n2eGHiT3u5zDL/TptJ8hkanfizziPm3R670cTXMPkejpT0imJ2P8Hy9w/lcx6WpQiqPG33MT/Z5vkduvhz3t0WE+02Afwn4LcBv/p00z+3/C3/4NPmLRk7UDNWS/l5inbwF/DH4l99tNPgDX21dvAVcO4OVswbr8+/CC++2NIYzwq8PGX7s04jwlMgKlY84O6Ktt2liV2i0OC/y+w7DG0g/35/v9P8PaPR41mGWT19gmOa43dvcpMkuFdbniROwQYyQDXKO+pyWIqKRrnG11f9/oePgDvlOm/QNSb8T5bsdnuUOO0Q+HBF5pmyRnq52/O2T9NDb5HuRyo5qEG+RgIu7oTMiE2uU9Q3aOr5IHNePcfEiEm9CXOLi7ZGvFFxPe/9fIGT4PWSdX+o/M5Ie9wlyY+4x+TbThBiL39P7f5vwkjpjSvu+1fXe3w6NLl4teFih8Z2pPq+T9KZPlLberqbs2qHRxWskVVjd9xmG5/iOCI9v0OSaz17o41fHwaClMsogxBGNRtdp6WXWdUfgpPwt7a/QdAW0dVZf3AZuPwP/4pNGV1WOb5DPf+jcvdTxfo+ct/t4wcdxH/OjxMHb6fP/DLlz4IC2vp/pfWpEfY6kLt/tdW+Qs1QTEmxQJxhwm/X6vpdWb5KbQQ9pvGd62/eQIxbHNLvncyT1e73j4c0Oo3JlSnT1Qh/nMyS90dtH75KPj+91OKSVbdpa3aDRgvxwl9gEBndWie0kr09pjsO93u8G7Z6GIxLMmtButlRe3O51t4kRv9HhucVQh4+L6Z86JAc0HvLbfg86Xl+hqZP322lznupxs6nGO23P9T5vMgymbRJZoD3xMi3dVpm7QsOv9o5taxCszuclIqd1dJUltZjC/XliM3yMJie9s2GL3LNxQuwUaWqNON/S7kbvb7u3fbW/3yW3yx6Qj7Fvk9um/ZzLZn/2WWLbLZBbjHXUP8cw6+aE7HB9X3lGx9WrxIY2OPupPqddhnoT4mg+7HC+xuAeEtZp9Pgiw/K1/u57yJrdp8n2TxF7Ur0s3DPikH+Si2mXJ73dFwjvfY62Pr+Xy8uHwmmbEeE/JULrsDw/Y/4B8mOSimjETcOl1tfj3SPfo7GffYaHKiEKQFhqfwfkIO4C2bK23gEf7CISFaTRUpXglOHhf+uJG0ie7yGJAJt+pAF6SpSHcDvGGD9G2g4JY+wRBTQlqT5GGXRW7Xeh9Pe493FIDs9rMGtYLfV3pzRiNz9enEgXRow1jN/vIhL/r4LNuc1Kv6el3WMiVC2ugfQlDK7RGvk0Rd3hVOFOC+yVFmYdF2cdBnErzHVtNeCmZFdG2pmV/ly34/Lb8fdJFM35SPOHXLyIpKZ0rZV+HvX57hMFbrG/Y5KyxTHwUwC/s0mm/8XfCv/AX2o3mfwYyX12sOq07ZNF6ye5dSp+8Dr8Nw/zDScNS+lCXEjf+8SIm5KUyHrhhkrqgETrKk2dk53PcRGPlb9dY/n3gJzRPSntNILqZTXSvP2Kb9uI42VCoxUOeVReX2QoV/aJArMYDDsd4UVanPX3ys4qzyotSUPSSh1X+XRA+MxxTB2Sdisenbt8uFLwoxxeISS0yMVLN9Qnywwvw3HdhPmInLGT1uv8FhnytfVPGfKhY3jBQHVIXdOx7HINLruIZDqnrXCfE/21VOqrk6pMEYYTIl/EQZVvdbdHHeJ7A4PSg7BPSZE+zoihdlbe2Z/p5dDOwb71JPK9ynHnr/4SZ+elL3ntjHxHSpqmwKitMZbP9Zl6e1rGFpficZHonEdclM8WDfIp2V0QZvtW5jxT5uI8bHtOaFD4Zgx5Vj28V55PyQVNzq3ypjDoAErTy0Rmyr/ePCx/SFf2J32Naarq5gqLY8vr6n8dlMtKpWdluvNR9lR5+n5O2wEXLyLRvrOck4tIVhjK8ilDtaUOmHcRSeVh5y+PHJc+pgzP+x0ztHsY9aGOUk4o7w/Le209ZY009WQEOwwvIqn69Xj0u15Eop1d5aZrUJ22KcG3uFJe0fvTHtwrz5TjlUbVGdMyZtWbFm099f9eee5lQ3ujNrW/sdzVjqs64Ky0qTbBuDh/dcwYpsvKh8Jp+znaYbwHZMtRopJwZzQ774gcclxj+IFqI4Fv0gSfkWYja+70vE12wtxx8ZnOxh7xnndJNEDBcJ9hSt4iOYwtkd0n6Zs/SoTWVu/DMzorxGF4i3xXgz7G3V7PnSbTEvbKOw2WakwbmVHpv0sOnGv4bDJkiLskhUXYDklW2yIxPt0l8Cwc5LD6g4LHaX+mQNNgnBCl46F/I8NVERohVCnukHW37JKDnxoZ4632r/W/Nd7PSFrDFjFenNe10n67z/kBiY4aVbnPMPp1Rhz3d8klBtKCBsoaOfgvPRpxe0Db1VJpTMrPG0Rp6LTt9bkrRM6An2D4ce3qkArPHsnlFo9v978XabjeIhf4qABWGJ4XUijfI7Q1+xosamH8aWDhLyWE+88Df6wDWcNrs/LbiMnDBsDdDt8fe9j27epu5GKHb4PQsMGFxx2uZeKs++6IfAAeckhc40458wyhr3ERZ4sMzzZOiQz40T6lHcKf2x0mL1RSETzo8Lzdn/9YwfUW2cG7wlDAbxEjYh5diB+dthr522N4EYlKyjkpV+6StEtxobw67M83iVPgxTXVAdORWaXxuwa6ytw5OI5zn5ELe+71ccSbxkXFxRNyaP6EXFyzS4yhI5Lus0nbeb5CLoNQjv8skclTwhcn5NKBNfJRZPWWF5HAMB3OAETt7yGNFu72ul9neJPmMdkhnPS2hwwvUVIuPyQX2SySHVSDBO8wPK92hVyuda+PcZXEVNbIxVUPGKalS8/PMDwbbh1ZenH09wNy8YPz2et4VWbN05vqAXWN8kbcvkf03Fkf02cGd77e+3XHXvpd6fN8kzjuGqc7HQ7Po0mfzme7v7M/Awi+F85J/6k7KlMS7V/qfZyQlK5Vhpd5bBMen3V45LuF3udBgcVAortPBtauElqpwRxpUR3gGpsm+YDsPMtfZnhU22mvt73HMKtAO0x87Pe+5KN13j+lca/DoE3hHA9639oONRD0tPKAfB/VeSmTKi1rC02ITnXe6j8vctmm0Z5yeqnPzYtMbFsv6VB/K0M2+/NFht9zq0W5IE/Lw++S9Xc38B2iAw2grZLA7j0unmk7IPymPbNd4JSm1DPbRM5KD9MR7PsE36r6arPNSObWWXn2FgnMiY+3+nttmnk2CuRCO4M9rstJf7fVYapFW6wGOvf7nPYZBtW16Z6QDD/5vgZJ6XOb0mTcAfn27HhHblw+FE7bORH+Rkz82+czwpS+Y/T7uPRFqX9CjPkjhmPpGPrMCKJRhyVCMBL/k9K2MrXjHpdxn5S2CgOfOy9h1TASB9a1Xn1u1FbBXp22KsyP+v9GaCrObD/GeVUEZ6N6jmPdhQLTQqlXDS/7Py7964wIX12DGpF1fZ4whNtoy0KpV+E7Ln1UOCj1xU+Ft0ZmxJc0VXF0RCJtFWd1LCPflY51DqTV0/LOqJJ0KH5dv6Xy3rnZn3M/Ke/Fnf3OShvXQ0UrHfvMcSt9iCthZ9SfdSsdrFWiBfhTBfhfD/zTwD9GNJMdHzJk0pMY3v8JuRBDvjZossqQ5p2n9OIaVrqu6+K6nnKRLoy8jou05rSOyvO6tufld213ylCuqMCqgc+oT+frWM73tPwvn+qgrhV8zBj6yuJlvJY6upDlUFEvlXHr2tf/K/1I79IjpT8Y7sbIm7VUPhiPcT6qW99roFR5VddGPhUH8oO4H8ufSleeXzhnuL7HpV6dl3CYpSHuxdGM6IYlIluqHKn4OyrtxMsiQ9o+Y4izuo7uAJ4wxJl8UB0P360wlLviTB6x1HnXvxnBM55Planz9OZYD1QalL7Ul2NaWirP69pWmVD1lA6bcI37oOBitbyr+k9cOAfnW+fv3DRc69o5H39DPrkgDVZaZ9SvazvG7bzn7ng/JmebpekaFK76ZR6/q6uqHSQO5tlRVTdLK/ZxWRnDXWm36lzhfL+dNuGpetygRdW3dRzrHpefamuI33omUPwulDrWXyBr67pKu4tkZ2k8lwrTItkNVT6MeXtMW87NMas+XGQ+bufZQ0/K/2N5oxNcbY1qA8+z2eTTo/JM+0TYx7a3MIwd9arbnHu1sys/1FL5dLxmyv5qE1Wzpcr4eWvm/OoYqzy9fCictl9EIk8TsoMh0nVENmgL7y6N6ZBL5JKGFXKrj/Vd0El/ttd/rvRn18lWsoc+T/rfV4iiuk4icvtkV0bFZyRko8Psrt0KLY+5LjhEeK+QfHvntlHgMGo5KfPeIOe8NFrFk4Jbr11hsdHh3S34mfb6G2XOMs5Gr/eYMFB1Do2IbZAogopw0v8/63PbKP+fkTNRwna9j+98LOLCa4c9yHxjVO+cRLWdW31/VmDSGJGmFCgrDHfaNkr7U5KOK0zXSlvXESL4r/Z57ZV+rLdB0o8Oe50NcgvTGQ3vCrmrXLzYZJkIvPXyv8LgKk/faVvq9a8xPDe0TgIRkzLfaa9zteDI4rv1/u4KsLZEW+gNhmH2A1pY6/fTPLD/snfw9xEpLoL0MA5h/SDdiXcj04uEzq4RmtaQkparL2gakkPQ69n/Mommu2bzFP85uXbeenSYVM7yYTX2zAxYIgLfyLpy6rjMA2LwrJd6lmpYVqcNQju1fv0bYtyvlLkv0XjNvnb7GFWeaYgsEv5cIcbehKEcWiG7P3u9Xx0BFbC8WelMpet6Tgk/On6d2wnZaRzjzLpHfYzrJO3J9w8IDz8ofVe+OmHID9M+H+WP+on+W8NcXq/PpVFloGPMOr4fE3qwrTS9SqLUk4Kfse7TmJj034vk0omKM3lJI3GVRP7rVez2J+zSrxF6CG0vjP6uY10tdaf972WGdGbwQD0gjGtE7lVYpC1l8RrDVFD1yG4fY1b6XCd6W91QcamR5Y6z8kf5PC6L5GKKq6M+LNL8MtldUH+uk8DrOuEtbY0j2s6S6zJhSCdXafLOtZdfpOUp4XHb6rSdEJuiGtKTgp+xoT5hSFNThnrVeYiPalOYRXCZvK1lHIAQ9j1iC03IWaT360s9CsHl2M5YJzeeqlPVIdLZAbEFdS50iIVxUtpWp7LqCOsKzxLznTadDWWX9K0cWuv1pO8aZHQtVmj4Enfuwqu6baudpf2j/b0yqueaSFM3iMPmfPYY2kRjXG8ytMXOSfaAdKQugeHtyFVvWqa9frWP6PM4IPq/Fm2Nauf6XBjMRtCmq7bsypy2kPV3POlqPP64vB9P/A0rEjUkajku1bCZjZ6dl2fz+v52yni8+v+3MsZs9P5pdefNezb6bb15dS/r7/1wMO7rae1q3fE6zGszb+7zxrvs3bxS1+NbKU+D5bI+xfVl6z6b87f1n9Zu/G4eDi9bt8vwfRlexztj8/hnXrv3e1bLjCEOnkr05zRL9SHwv6GdvH1jAf5x4pHPAf6D0P28oervp9HZGK8fhM6exiMV3jGtjH9/K/R8Gb9+ENgua/9+8vODyrCnvb9snmP5Pw/Gp7V/2rgfhI7HeuRb1Rnz9MP78dgYng8iN7+dOvPKtzK/p/V7Ge1fRivzdPcHGbv2fVm/H7SPeWv1tH4/yDq+n558GmzvpwPm1Rv38UH0/Dw99q3QwXg+Y3k2j68+iJx4Gq28HzwfFP5vh9aeRqffCr19EP3xNLn2NPtj3jjz+rqgm+f8/7T+6m/fXTbPp9HpZbT6QWXLB6X1ee+fhsMP0uf7wfityuJvR8/Ah2SnTY9+lew2LZEdByOvzxKP1h+j4OsMr9BeI1cxuxu2Wp6tlPEmJNJgRKK+t77XLs9KvRppm5V6R2S72Jv7jCKsk+iyUZA6f2Gnz13410s9P+xshLWmFemJu9FxTm5aWx+NcYUWRXi2w2rkQjj934PDjuP5l7XS7yL5Hov4qTujRmWMvk9IhMporzixuD7uqta1rdH1YxJVqe8t7picl75OCa253kaVhZkO37TM2ffSwxjuk1Gd9d7HGY0WjLgalan0JdxTgvtKIxOGtzzR57RGzgm5Y+H4CwyjbZVGDku9RRJVto+Ki3Wy8ys89qcPJk+uwkVihuQirZAr/9ZoCeCfOod/EPhPaQf3tmk3E/TFFffPdjifYfjJjQqnu7k10rdEdsOMcPu/wtM1MJItfhy37uZYKs5cWwXyav+9TnYRjHBKN+6WuFMwllPyFwxlV0WtMmmx/F/llH1MGO4YWEyzkuaEfZGhLFopz5SF0rfjCas7Tc5HHjDiLF7FQT07ArmVtdLZFRKtltakfdsacXcXzbWt+sVIs/OsN8BOyEUIjr9G1q3qlsXy3v6Vu8oNI/fiA5LlAaGLCVlb8WMRpvVRW8g5MvWl76+Q7z85L3cqlSHqU/VDlTXiSViuEPlbo73uULi7Opa/RtyNcIuLA4a6G5LG67i1H+XPKUO+WCfZIOP1sB/ntEJ0QeUzdVqVsfWbYspC4VgouFsoz2t/tVRZ6voo291Z8bp09ZH4qvN03tK1vKfeckes6k378Ln9yE+T/vsJuWZdelggMkv+rbrfeSyU34eEdybEhhnrVftwbO2nK6Ve1eHjctzrCbe8PCH0fcTTZXctU6LHTUV0jSzqWtdD+arunDCUz9Y7YbhOlYel2cXyf5VNvlO/jLMKIJ/9WC/9icNzsmM66T/a1a6Nslh7RJmpjHtS+pPO6rzUSyelnlktZgJMGNKK+kRTQLq0aCZUPSfvKhuqDQ3Zka67vZaqh6VR+9V2qvRpmRb4fVf1mvgQj8oc9edl/SonxONYFl5WPhRO2yrtatNFcp2xW8a75KKA18kB21tkS3alt79JUm7WydWvHla80Z/NSFrLzf6MPuZL/e8lchWyTPhZ2gLu9joyqVvW+7SFeJ186X23P/sMYf5V2tapTLhOu350nbbx8HyB6ZBctX+zwzQhV/5rvFZG1zBY6bCc07LRnidC9Arw6TL+6wzznunPVsmVtNtlHHF8tcN+jRhLC+QK53XaFcyv0g7bHpH0oZt9bme0a07XiZGjIvxY7/+EXPX8PO0+i5VS712Sf71e5mZxi1uYHtAE0Wuj5xrdkz4OHX/XaGu5TK7hvUnSDFXy9H63adcCv1DwpZGy2sedEOfrhHzuYoXhldkrtHW/2X/2yGUURo9ukYPPR72/T/Xn+2Sdnc8+OQT+KklD8mIIldUN2nXZr5KUsU/1ds+W/vb62NP+7ia0xXuZEDM0ItghUrNaRjPgz9JunPwP7wC/BH7TfwX/GfDH4M5fbNVeJ4d8TalYpq3XHWIEfZb5V/6fkAPrj0la6azg7IjQmylPLzDfiHiX3Nol/8/IBUh7/ZkCWj59gSj3ewyv/BdlS71t/RCr6SgbNDpyDdYYnnFTkUCu/H+ey6/8V4FPyXou0XgJhudflGfKlgOSXn6b3Bq33f//NHGUdgmNq/Br8MlAzqsMP7zsHFdo14YvlL9rsGmBxqMaDa7zjT7myx3PO32uV2m0okH/KXLe9mO9r2Mi91+mXeGsk3KbKFuNkc/SeKUaXJ5VmtLWrV75v0qTFxqbKzQ68Oro14hh9nJpu0d4e4lGsxsdPg0H+tw/TfTqCTkbIl5eKTi70+elfFLX0sfW6D/sfaq/vPK/pjqdMAwsQoyus972Zn/+bq/nvKocV2+Or/xfp9HvUYfHZzMSjLhFDCzPw36qz/OI0O8rvf20132d3JBY5+9NoxNihKoT9silHjUVbJ12nfhzpY/HRCTu0tZtjVysIn4mZJ1dizPyKY1pH2evj/mxjruj/uzVMoebZYybhJa3SerzS8TRcZ102M5o63m94OeQpM+qrzb6uNoT8vIdcrHFbXLlv7Jgg9hmVYePyybDj5RPafbjp4n8Xetz+Szvn1Z2lQTgYPidVNuedbg+0eevTvVTB3fKM22fdS5e+X+H4ZX/OmLKv5P+/MVe13cGZ8Z6aNL7fo2o0hfIlf+HNHvxNk1eqgO3SVreOrHPdNo2en/bNN3xKrFnbhY465X/18mV/9qJN2m0UucpvSn/tdctJ+TTUp8pzww8fYLIve3+Xjtzl3zKwqLzukczO14h+vOwvxM/tVzt714jqYv3ie20zvwr/7UN13u9cdrjAfnMyH0a/X6SoV6eVz4UTtsJjeAf0BZPgaUwVQC+wfDWmj1y6x/9/9XybIN2i9B9EglRseyQHOxrNAKr56l2+rspuaHqp/uzfeKAGMlcIh+WfoPcLqagfIMYFfeI4a3B7y05W4SQxY3OkobmOvl+nYaVjKpghSZs3ui4e0Bup9okxt/d3tcbve1maf+zvd6UdnvOLolAOdcpiWgs9vb3yQUsD4hxt0t2TXeJ4aTyv8fFM206DxqGRiWMZojTHcK4a8DPjPo5o90Y5vu9/syPuHozl0ym80+H7z5t3cX3UZ/DMbkxSjrUwTTqeI9cJ2s91/uE0OPXyI2iW/3H+U8JzWwSo0b4xIc4PqPdqLTX29ZoFOS2Mh2L7fLbgMJin+djYpxrcK+P+tMJ1B9bAPjVNAn0MwXQ3VJRhB8w3CIC+Cc24c5m+9jKdwG/Bf7RH2ow/LIF+CvnDQ8TosRuAFf+Jrj9c20eP02CPOJAo1Qn/ogYDBScnRQwxbWCfVy2yZm2NRovzchtXY/Jd5U2iYOoca7BtFfG/ipNJm33/jQE3ibOcUWb7+Q7aWK3vNeA89lBebdDIugaXzrvLp98csJQngnPlOzca8w7H3fldKI02t8lNCWt63je5eJO2z1yOYoyG7KLavHs2CbDiw+cs7g+pNHuG72/B+R2sk0a3aufpmUsCL6NP6z3eif97wPCw85Nulslt9Puk3t4dOCVu4dkZ3JK6Me2U3Izn6y0399V/GiMqlddR/XipI8jzlynGXE43u7z0WgSNyc0+tZo8yz4vJ22WZnPZu/vzQKn8m1KW+cqx98m/LxKDMxVYgC6kS8e1Tfuyhi42aatszid0mT0O72NOnKN0LNrNGVIT9LdMU1+b5Er+avTttbnv0dbP53nHeIYvtXn7XzUUesdNqP793pf6u0jmn7z8wAUHB+QYIxBPenrca97l+jEKfmI8QKhFdfutMCnTaYtdUhuAZfXlHt7HQ51obr/MTmzrm6eEF14WVHni6fHRKW8S3hcnL1f2SI3+i4wtO0s0vwikVuUecvb8vAZ0ZuVjx8THtZGUE7IU+pR5eFimd9YD22SG62VXWdElh+SW36nRAfu0nDu+byqoyD0baCjBukOGX7GZoXcGHnecXnQ8SLNiUvxp921wlBm0GG53/v4annmJoY8JY3S+9npbeSbWoR9l8ZP4vGI3Go6HbXZ6v2/Sehol9hM+izqAPnRG0G1jScMy9c7LD9T+vsa8z8PUMuHxmnTO9YTrobVIY2I7pKrdyuRSGwaVxLC+qjfKW2xv96fPSbKzGcWFfqUHJb8GhFOCgsZWwN3udfbI9fEP0OuEKY/93sMRotNE3JuNUqpEX1EdvO86nrstClYZ8QpcydE4a1CouPHaMgZMWBnfR4aUbZ3HPEm3DKPRr+CRgI8Id/ymZHI9F6HT+auV2RT5vIecXpUEjUCJr41jozAWBQAEIUlTekYazi6+6HTppM57fDR/75W2tbolwYPtHX2UxNHRPBqQKgAd2lGyS6JmOsILJNIsMGAQ2I4id9Fhlf+3+39aGS55hpnh8QwU0H32/W/SdPyn8JyWuawOupPYfi498kfA47hP3hnqASmRPAul37sawH42E/FyP0twPJvhGt/tH1Mmz8C37HTfr6Zw7PIN0P8H3sHbr0Lf4ShYb7MxZuzdM7EozhTGSlTpLt50dqHRHaskOuHHxEj6S0SPHGsY0I3e8SY0cD8eu/7bsGR8kz6FK8qydPyv44jxBiTj2cMeU2Zu0Jk3H5H61uljy1iSEp/e4SeDOSIW3ckhEm8GkTY4mKk+YxEpdcY0pm8Nu1tXStTEC1Gq8W/t6mZyiKuT0jQbItG+3dJAEPDx083CIfy5JRhMObr/f0yycpwXotEr5mVAJEr4t9PfVR5qZOv3rHtIZFdBg6V5cp2x4AYuM7NwJJjVZxJX8pEd4RMk6/9Kc80ktcYxmHq2tJhNWin3IOh3lyi0Z5yVTkqvqfEYTY4cEoMRA3XGbkIw8DNLtkhNwB72GGZEjpz5+OIoex33isFF/Yr/LUoM0+JUyKNulP1iHzuwfU56zCtkHVeIw7PFXLjn/MQ55CghfbJLpE7jimtGBx3fq6hMks61NY6IndFnZQfZa67ncKmrTDtbbV1vJofhjyvLrys6JTpTKhfIQ7slOiZ99tpU/c55jGhW4vjwNBpM0Dl50y0seSnKUOnbcowJXi7/71AUkW1e6f9nbbNvLnIS6bk3SebDoejv6eEtvYJzqXPLaKj9ojtrEyXph73PnTWV4h+P6Hh8zH5XIlzEKcHDDPOqg0FkVPaGtKgzpD8p6y2HPRxq96kt/86ofsVwifOS5qppeJWJ1Bb55zQtHAq47Xf9E/GDqTy7K2Ci7cJL1xWPhRO2zpt6/EeSf2oglLl8f005CzQUgyeJd8ee4EWadeGW6MF6d8kUYwN2lbkl2mIvNbH+hzt6MwKLa0A8k2jDdpCrwG/gjhbbsvrHKgwVzucWzSnR6b4lYQg3yIRRQ3418mi3iJfapdRFmlbzBsk/UyClnBPSSSI/vz7O+42SRqP56w+RYuU3e+4UlDbz/f1/40Eb9MEhopHx+uzJJXibv8x3WWblp7wcv/7uMNzlbZeWyQdR2NJQQhtXX8p8CUak1yhpeu9VOZNh0/H0bWv/ZwQBr5CU0RnHT+PaWtlipbnmm71+jOy1X+PRiMfpdHgEY3GVEiQwMLH+7y+RCLgrtf3kHOJb/Znn+84Wenj3WW4i7TR8brEUGHMOiwqdpXn5/scDhimR2rMuxMgzy32+UEijBu971doO1c7JCVgMupPQ2e9wykTC+cK8Js/DbwFn/25OJIT5t80p7A7AZYfAn+Sxhg/+q/CX/jt8FtJHulSn+zzwBdhbQV+4GtxqJ7v/T0iuw1TEkFXIYgzlfAm2Tm4w3wjYpPhGcAfII6+MuD7SdRV/rxDBP0mSZG6QfsW+Zd7/e8ruH6TJtgnJP3INTCoJB4NCAB8J41mb5PAzC3CP1s0Y0GnSyWyRJNdGl/rfQzlmbJF+p70fsXtTv//NZIFsEdbsqt9jtvEQDRIdE5Lc5owpDMDSXdosmuz4NGA0iItLei49y8sN2hr+RLZQZ32/j/f+3uz436J6JUXGe68v0Tjhzc7rLfI7vxXSfroQ6J75KcnNHnzaocHEvV9qfSz0t9PSdrulCYTXixt98j3Cg32XO39ix96/U8Sveo6LpN0NNNA/xxJWzsj8ZA3+lgbDA3bI+B7iWP3LEmX11Gtf0MCiutE7tHh1YgZ6803yUb9em/zAslQERaffYXQ0nVy1mm3w/q5Ps8fJ/T7Pb29fGla6iH5ftMG+ah4jRk9T+5QMjAify0QGXKdrK0G+y5t7b5AHEEdw+/tOFVHXeu4m3V4DYS8QQKrd0jK6gGNXqc0e+km2R24QWhlp48nLbhDoMzSYVOO3QC+m6SCGQS/T2jqlY6nn2Z47OCgP/9o70cndK230z6oOnxctmj0ckyCUi/1eX+ZyNOXafy4OK+TUt5hGNyc9t8GlOjjXO99bhCdOu3zVhZ8hRz70d47pwXwr9HWZ6O3PSC7+zU9ckqjRY9pqF9Ud7Xc7fB/rv//032MF4gTvd3hu8MwQKMuX+/Pfoo4M+7c7ZBjKV9ifnrkSq8nfu6RIIzyR4dTR0u721Tksc0Gkc/Sn7LuZUKjBis/QbJWqt6kt/8qCX7/UppcpePnp2nyYJye+A5tfT5H1my7z+9VIlOk3RMSTHKn7RMMUzUhwdofILbTd3cY/jMuLx8Kp+2IJjR2SRRRojIycE4TrgrPPRJxWiEpB+5q6UXfJx8DVVG9Q6K0Gu8+MyKw1+FZJwayUaVDhmmMldmMGOwRT3oJ+DOE8c1fNZKkcbpKUuSM1J2QbdxdoniepTGLhr0Gi8YaZBdDA3Kz/3+XREU2yY6fY9nPSsfnIdnZU/EekoiqsMuI2yTdZZ98YNdo/ozhTtuMxgDv9d9VIE3JRxinZHdVg1Kc7pLzEEbdx1Gbt/rfRkac4wltTbwXQwdMBp2RtD9/b9GY8En/2wgYNPwbcbrXYT8ktKCB+UyHYbP38SWS7mfqh4asxtCEpPUsk+inEbEDcu5gvcNoZLU6edLxHjmzKI3dI4J1h6TGapxL5zWKNSU3+a8Jxzvt94+Wen/kp4IXcaaRAnHazjp+ntCM1O99i7ZQXwF+8re31MsfAv5hGtPMOhLfBu7C6V9sH6XWMHc8FbzypUbQpcsNojSVMyvkg7zjotGto1mVvtHvHyc7bRquBl00tqcMd3Pf6X3X748rz9a4mML7HlF00kXd8d0ishMuflzbyKW7DgdlTpDd21Oya+H8pe81YkiJw12GV4rLB2sk5U1eXhzNwah7neMCSQfaHbXXUDZ4cY+k7+wRY9WI6hFJW7vfcfRFEoDS6HiTyORDktpzQgJGz5DdnaM+xi6hmSWGem3Sn08ZpuEq0yfE6TgguxO7zN9pWyTf1zLg4Fpvkwi4eNEh01HcKe92aPpUfBpY2GYYZPESCINt4rjSR3Xa1C1Lva/NMleI3nxMkw0/WvpRb05JgGqbnFOTr7UJdDbOaXJQg3dK0lYNjkm/K/3dW2Q3SmdQnTZhmJoJobkJTRy5K0t5L36U43WnTXr8YofxLnGQ1smu9ApJQ4XwlHR4SDIupgw/rq0e1+44JB9+VrYrAzVCFxh+XFv9vUNSGutO2xExinUYhU26uEfS0fbJuurUKNsmvP9O2y7ZmToiwTjthSnhx/dz2tzpUI8bAKswmFkwJefIIEG+e32e7xAnZpvg1qDmFsOdtq0Cn/pb23erP9cWqHaPRZtLfr1HdPaUOFdbhPfPGPLrM8QhVw9Xp9QdJ/lFXaY8NFgxIXLKXdQdkqWjLDgg+PbzO2Obzd2y2eiZO3XaDncLLnVSxzaKAUZhqvpRuaczVotrWPFx0Of/qMPuzl3daXMT4hlytKeWNztOfqzD83af/zs8vXwonDa/03ZMvnVyQranjYJvkB2DCRejhdcY3uhyg2Fa2rP92R6J1l0bPdMb1nl0N2Sl19Ng3ScGfjU4rHdO8st1ABQGKv+j0sd14owZZRIOowmTMseN8szx3SFTwLpTUvG3ThO2wjnt9Tf6b9ON6DBVp1LlLAO5XWy/i8QZEI+no/koLIzGqsSfIzuX4onStua8+6wKrxnD77RdH/VTdx1kZOetcakBfYXQj30/IemCPQuPDZJ2UI11DYWNAns13KQHGXxKoz2jk8tEGOqEGn28Rs6fuNMBw9v8NKSEsRrJzsdnZyQKrUPuWprCJb5VPMJuf5S5a2A8CyyvwtXjFpE7L3XPiCO0RBx+YYNcdnDcxx9cB7gO/EHgX6J9420C/A6i1XZg+W+CGz8XnEsvhwxTrx3DcV2zk4KfuvMxT/Fr6CigbxDl+Yjs8rsLLp8qz1YKfmZ9OsqkIyIbIBHtK0SeWTSe7KfKAr9vV+vXvyFOmw7AWceBB+afkO84Vv46I9+pVB5o6M6IjJ2VMTReqrMozXmhj3Kl0q2K/Tpxuq5y0ZAxW8NgxhHRGxulrjsgzxFH1fcVZ/dLfflBZ3CDOJfu5N4gF49opCijj4m+ggQTpIcJkd0rfd7OZ9x2hQTQjGK7CzUl9HC19+FZvz2SwXG1t/H9HvlekHS8zjCtS1mjsX6Dtm7yQpXj6g3nT8GNcs/5zBjucFQ6Oyx11ghdGZgUFuWTc5wx/E6bBt9G73+HOKH26REL11k5Abk1WKdNWlJ+j40ziF6qcvyIyJ6qo5dJiqs6ao2keGr3nHf4dErcZavz2CHyR5xPCL9Jy9MCh3SvTFOfCKO6SfkjHxyR3WQdU+0KjVZtnUPCj9oKM2LfKUeqDp9XXHMDENWeE9YJl8vuWs64eKa+BoGFUfxcI3rvsL+TDwzAXCcOPiRAUWle50w5MZ6PwTXty3lOW5UNi4SHb5BAXLVJTsn5Z+8C087bI/qo3rpp211iewrnVaLHrOe7U7IGVRYuMty4mGezSQs3yjPXSPmoLoGL32mrvDgjNvnYLpV/xjoSYh9uMNy5q7LG4PM6kfETkvk1bkv5X/16ZQTTZeVD47RdZWgQ6xxBmO8GEVrX+m893WsMHZ818tFsjV/rPCACYzLnGUQoXSMR5JvE2N1lmB4pEWq0nRFvfoVmFCgMpv230cTq+EzIzUkQY2OZ4Yc/XWgNSnN8xzttGkunJH10u7e5SW7T01B9tvRTlYXCUaftnCFD1SvjpwydX5Wj8zHyKYNpBE7LXBfIrY3XyRXaq+WZigciGGQShZXlpI8n3CrEG8SIMTrsOrgGGosL5CzbRmm7z0WnTafJNFb7sZ43T5309tKAgsjn+iHVUZwQQ3dGDGMV5mnB+02SZ68Am5VnJ6VfFUZ12q6WflSE0mDtTyOuRkmZwPJCnCdhhdCtgs719n1VNtd6X9+0Hm/0iU6Bf4S2Ffd/Yxi23YbrxWmTXjSqT0r/h4RnpFWNbVOgdOJVOrVU2nNtz0nE2/nMGN7O5Rz96K34eZbIpClDgb9PDOcJSWudEV6GOGxH/X9pVj6cjdpqgFfDVqdNJaLBd0KTZwvl+RIXHQYjt8ozAz9LxHh5j/ji1WhR/lSZbIBDuWZE1UCH8CySAJu7IwYgJgx30IX5eu/P2xercXWdYWqLDlCVnQaw9soznUV5SaNZ+IVjgaRvrpIdFZ3RWcf3tP/UtisMz2tBox/5VUdDA+6k4EV5Ll7EWZ23NDAhl2UI1zlJ39d4McgxKfBovOnoQNJgHasaZQckC6LK8Wn/rR5QNinPdRzEo3M8I/bCKjm7u9Hx6hmZanBOCC8rp9w901iXX5yncvTZ0p9Fw3Sj/EzJ7ZbOqzruwu4c90nQckpkiEbiXu9HI/om2aXRAZJf5HHr7RPbYUJsBQOxp+W9fDjp+Fklju0yCb4rx54QZ1b5oNyfMAwsa7/VepcV9XK1TeTNB0THV3tqcdS+/q/uq2POc9qEWfsIcnmLNuhDojPUOdK0hvlGaauuV+cox6Xxal8uc3EH0mCeOmqX8PAS4U11uTgzyDLpsOkUSZPXiC4Qj9ozG0RPyhO1nu+0vXTKqg513DGvQ/TNeu9PW/EqCURIo5MCk/br9fIckpGkrrtG6OKQBJDUixYduhsM9cAJWe9FsmF0QvyHRWKP1rbOXR7WLr1RYLqsfCicto8Qpa9Cf4YoeBGooFwu9ZZG/6+U//1bIhk/G7fxGb2+/VSlu3TJT62zwhCO+sOozVJpZ7S6MqXPF7h8zpUJzsrfGpGzXv/vpOXg/lMFt/YvsywTg3Nlzni1b+FXkAhjFXQV7/4+Gz0bR5BqNKauT8VNXTPK84Uy77FgWyYOhu8qnVV6qHUWR++tszKnLQXf43Ua/4ijMf3W95U2lst752mp/aqMxrwwbz61b/FWaflp8Fd6HtP7IhlAGhzPb6H8uN4Loz7F76ULtETTIr8O+PXAD34HzP4K3Ib135OD6MLnLo7w1LlWp/p8ztw1dMZlLGNc10qjdS46C+PpiIPl0rauuWNV2SHfOm7dsbN+xWeln9p2LJvG86a8H/NQXfOKszH+xPXT6FwDYSw3KP0/Q+h0LKdhKPfmwVJxW/Fd8fI0eVDX57zUsd5s9H+VZbNR38wZr/LsCRdx8bT1Whi1H/PorNSbtx7PjOZd64gv39fd/nG78bpV3q5wL47qOuZ4LSj1K46eYYj38dyrk1jXfaxPF+c8s41GdOWlZaLHxngUT4x+z+v7vNQXF8IuL1ebospZ68sz1W4Yz2ueHK+8M89OqmsBkSm1f/FT9Xqlw7GMGeOormWlszENzSv2N09/z7MRx7J73HeFvc57HKizv4rvy8asf1feH9N1lRNnXJwPDHX6vLlU/VbXsK7N2OGbN0613yrPzZtb5bln5vRX17nK7MrbY74bz2tMs2N5OI/u59mAl60No76qvpsHwzy8jd9XHVZxM+73abL9svKhcNpgqIAViFWYwXBBFub8vUzzVn8XTci+VZ5XRqwKqxJMHWth1KYKt8U5P2PhPTZGxws+r/14PvB0eJdH7S3npW1lClNIqhCvfZ6W/2v7CsMicQrG86vrMK+PJYZKVDyM/6/rUJm84rTCP8bTmCEt1rXP81J/vHa1vcbJvDWb52ifM5+u6k+tPw/uit95Bkb9WRjVvYyuxvMZK5kxjsc8MO5zieYn/eIX4f/5TtImVDz/4f0YFRX31aH3/wUuRqaF8UeByU8kpea7f6KdX7xHInULwK3/HG7zV1h8BngB/v6fAH4Y+APkQ3ZTvhlm/MajFqndpJ0l+SNz5ncZvdUyXpO6rmMDwL6qAr+M/+fR4rj+WCmdlv91Diuux2NaqgMyT2aeM5+uKPXH8DrOcunDscY4HdM7XOTjMR+OcVQNq3k8Uum4thvz6rz1rHDV+Z3OqT+e19P4coy/5Tl1x3rr/ehhYVSfUqfq1rHT4bPaXzXKKp7H8tl5jx27uh5jp228LhXOeTQ+XouxzDxj/lo63hgv82Tt0+TvPF1T6W551I7ye54tMIZpjN+x/bHIRVof6/IKy2VzGeNtqfRj2zE+dNjU/WNaH8Nc6fl8Tv15fO985tH5vFKDPVWXj3nvabK7lnnyoj6v87+MNis+hK3Sfu3ftpVnYL68nWdr1TKe85huxzx1zkWYXWd5aSwL59HTmCYv02U1WLLIcJ3rOo7Xex4dVNzXPsXlr6ZtTnzn30K7aeQfp9kBPwKzN3MW8hMLtJtyAA7h6F1Yu0pufrHcg7/yc/Adz5Ptsh04eghrfwstr3GXbLX1/OEH9xtc68BabdvLr/6ZtoP3sf9l6+//9wh+SR//H/kZLi0fOqft221rOQX+VH92fX71S9t+u+N/u+X9hMhf7/Jlcoh0bc77KqRml7ybV34+eBuPVRmw1lkc1fl2y7jtWLn+jSxPm0d999cDtm8Ff+Pxnlb/K8DknRyAt5wC/wUt3eC18nysvD5IeYNco2167z2GTtsizS/7KPClJ/DK1+C3nQG/E/h9/yv4b/58iP8EOIaPPIa1Q3h5E05+Bv6TDwjPX4/yNLnz14sW/3rxzLfS/ucrwz9o+/eD51uZ77wxv1V81cDEuN+fD+6rfPzrLaPm9fc0WvwfQwf8TyF332/Mecb6vDJvXefpr6e1mUf33yrtno+ezWv/7dg5l/VzNuf5BynfCp/9T6mPL1ujD9L2g5QPwnffStsP2ubnYwN8u+VvxDqOx3iDdhnQ3/mX4X99APyTwJvw1pvtnU7bW+fwaneODlsVbh3A8wfD/u7RTIfP3oer/XDzDi3Y+/G/nIufRj4bP0k2kl4qbS0/2tv96r/Y+vsS8Lk544/Lh8JpW6YZd/vkOtwjhgePz2hGmWeaNvrvg/7sJi0/fZ1mSK7TjMU9cmvNddp1mvf7j/34zAOmC33sDZJ7vk5zwD0L9IDkntfIl/Xqgc7VPobRAnP2p/3ZhFwVu9Hnf7vXPSxjbJBPHdzq768So9W885P+bqXXM4f3FsnHXu9jPCzvjkie8nl/tkZbl2NycYrvJyR/+WqHwU8i3OgwnIzmc8wwt9qzN7fIzUMVn9dphvhVcoHJjf5spdTz3MJCh9mNFcsJyZ33fNwJOadooGSNXEAjzJ5FWuwwCtNzJBd6tYx3Uub9PI25hXOl4/4WueRml+aI3Ow/KwwvUVjpYz5HPvtwStJrPAvh2px0eD9K6MpxnY9nMVx787ifkPNZ8qXrt9Pb3iTnYKRz6cYD6AYF6trX4sc8Kw/VM23C7XmA4w7fpL8T7xskteBmH+td57pLi7Cd/Hn4jf8M/F3Pw3/6D+ewj4v2KHDbx2Hv84jk1d9ifuS35tmv0tbcSKY3Qd4iwlz+vEkusDgivFBl0gHhW/qc9xnKLki+/nGBaUac6Q1y5T99LP/2/xNymcYiOat2m5wf2eiw3i64MD1qgeBQGva86m2GZ9pWOs62yFKMo6rKFefuuT3l2k6H9UYZH+LAH5LzSsrPq/3dAokqT/ozv414k9C+9LBRcOV8xLf8sE5u8Hy+9z1lGOU+KfArI5f7PKT5t8kZavX3bXKmrLbVYJgUvEkX3kKs7rvV4X3M8FZZ9dzzRO/d6PVNC7xKbgXcKGMd0ujhJjmEf21Uxx2wavAvkfW5Rc5xnDH85uFthnrTOuoBcXbW53Vcnm2Sc2E3yAVlC30+z/X+va3tvPS50et+tP8+ILepKnOOybmVRSK/DahXZ9uI+41e5wb5FIW8etZh8rye/KOu2CM3Ans25xb57uBOGU8adW43CD06twWGtOwZsA0ic1ynkwLjGbm0QfwcknOsh+Qs1kdp8mGb6FXtimvkXJHn5dYJ/ShHLiueqRSHdT73S5/S9vs5EK5ntSvk2zqmsN1geLuiutTA4lofd5/YZisEv/LwAbnBe5F8V3KB0CMdDi+9GOuhR0Q2LPbxpe+VgiPlmTp1Ruy49f58iwQCtIflodsMPyNy1GG5Qc7NWc/L27QrP8rFTILNDp96s663evUq0VXacer7Se9HnrvZ+7xP+9zC0SNYewDsNJt9k9hbE7IGh+SD9WPc3qfZFOINcgvnpOPtAW3D7ZhcXPJu72u94LaWd8lN6Pdpcv/OnPHH5UPhtP01hh8AVCA+7j8aNPvkY60qo6PexyPyjTGdvYPSr46Yz05KP7We/fluhaHBPiUHiH2uoaHBZL3D0t8+ST84LOOp0PeJkSVMwqGzJH4gF4Qo2N3S1jCCXIZyTq4UdoyKn8Ne7wlDo/KAXBUrvPWiCxlWmBZLPcfw7wOydvUcyJQogYoTDTDbiu8Fcr18Fa5Thtf6+t5yUmCSFjxQ7TqplCyuwYx8i6bSjHR6OGp7xEXaqopPeHUcx7QvXqTxM5pQ02DVONHJcU2XycUATwhPHJBLIZzPeO2lw4pHnYzpqP6jPnaN8D7qP8eEzmFIy9abFvhrytus9HlQxhfv0tt+wVml/zGc3/z+wR7wf/9XmhT/3/67wO+Af+1xFu8oH1+2j6PRGkCCP+PifKTZA3IL3lHp94R830lceF6mzrPSzREJ8ohPcbzEkEZ9BzEET0o7FfsjQgN1Dhq4zlu5owyR548ZyrPpCFfyij9Thp+imBLerLynHD0q/VLm7hyfEBk7NtpMTXYN5RWXWjoRRnFpf8ckMFdxJv0Jc5VX8oOOQ4XPMavT9ri3qfgTT2eEN6a9btV9h6O2wgExzpYZwgdxPFy/qr+MXVScOUfxCkPdW502jRT5dZFhut0pMdLUTculvymhh2mBTf01xpN64DExiKcMeU1aqTQtLI9Kvf3Sp3y43/uWR+q4Fc/yvHNzHsIv3dbdN+ssF5gflzZTYlBXHMwKTAujd1VOHpdxqix0TV0/8VNlgn32ONY3ZXPVXdoY4qrip8JwVPpxTHejK+8e9TrSOUS26aBcVhxXJ6fK7wqLcM6T3eP+5L0FEiis9kjViStEpwqL9HhIPtVxWP4/JVfEj+m6Om3SwGOG9pWBtDFexMOU2GHiQvzWZwZ3D0sfdV1dC2VXlQmOJd06vzOG+st51TWwv0Vi12kTjW02L9ipek7cLhEada3EpTBM6Zf3HLQ/Dog/UWmFOfipxXlUGnpU6itTpAVxWO3RKRfpT/qvumfe+OPyoXDaNHCqQhKxleD3yv9e3SmxaHiulvq7BCFGW3d7XQ3AFfIdoaNRv0bwZWR37SrhQqIHCkPHOBy1HStaYfCZAmGf3AQlHrwsT+N2qfSjUNGI11BbJrt9046bqmCN2h/2v8dOmztIGtoKFuGkw2OUbpHcbrfa34svcVKZ1LYz8k2XihPbi/fD0bPqtImLxTK3eU6biuew1NPwUmhpgNneCP+UMJY7VdUgt35V/uvE+JKm3BVRcEqPCgUNKOejoFbYKTCqE1YNTfvdI3TiN8+sPyW8cVD6lh5UVkskmj8t89IAt7+qiDXO7GOX0O0eQwPBPlSKKgtxooPg2DCk2yWGcOrwPrKi19GJ1B/+R9sXe/8v3wv/5Z9pOQlfizC3qsEK5YE7APOMCNdKHpSmhfGwt1WJO2f5qwpuaaTie6+0qUb6wgi38o94rAGaKaEHnbAx/1RF7thLZLfwhOx87pW2OhTT/r8yQ8Xu7rs0o/KuDqLOgbJfmCqNnJa28pX8J39Y9ojyVtY+08eouJ2W+j4TT9L6LuE54VK3nBC5Ks1IK/ZZnTYNWuV7HVtZNCW6R5kl30wvaTsjjpByVecDcg35OIig8TPGmfrUgIg65JDc9AmJLAu7858xzIJwbavTVnVPpUPHWSafp6nvanBUOapuEbd1jsI+YxiM2Sf2wmF59ixD/TAt72EoZyHG9jpx3rRB6u6vcnq51BvzvnrL/uUXfz8p/UgXOvoVRnmu9lsNTe0AZY08rNwWrwvkllRlivrTtpXH/C0d7jJ0Ds5JwFlYdO5q4FP6qTp8XCo9nJZxtTWU6VOGN2taZqP/lZ/S69i+o78zELrIRSd5jeBWvnCuM+KwVx6eEhvVPnVOXMfFAtM8p23MS9P+bEL4ekqj9ysM5ZUOuXN3LSgw6bTU+dhWvnEdnZ96e0popdoxrtEyl9tsyi91qjpjiSGNVtksne/1n+94CDxsf9cAxZSsg87xOrkNktKnASKLc1OHVx6pOnSZ8Ok5wzIlGVXaO3vMP7pUy4fCafOa0X3aNqORBo2EKW3imwyvtn1MFlqFuEo+DLlJvo6us7HZx6oGQX0mwg6IA+QY94gyqApQQjwkH1j1I5Z+dM+tUjpMOmbCvUWMY8gH/qqBJDxThkQ5dtoUfItkK3uH7Ng87HCuk48gbhJjw/ZbxIjaGeFxStbofoFRfFskwspkOg1TYsyel7biUyG3VnB5xPAwsMwlfPQ2mwXfdJh3+t9Gnc/Ix493CR09YridPeuw+VFG0wBc/x1ygyZkc8dI3A5x2pYJjayW9wcd3xrK28QgXyrjue41Aq2AFcdnHfbt0kanxvrVmVglAQFhqelMRly3+7t1Ln6nbUqE4hNyi9UJoUEK7Brf0pfr6Fw2SdRaA/i49Od6nxKl6rx3OoxsEmLTQj0G/g3g9/yZ9rmA/12rc6sfUN5iqNB2yQeLx0reouxSBjisBsQhjc5c67qjaODIPpQ798octwiu5RFlZF2DHWJoQBSh46hQVIAnpa58v0KMH+fk+p2UelWeSd/uYGjUaUxDW4+x0r1Ck0XyijQnXFtc/E7bdpmL+NFptyyWfkwRVO48IYGMaXknTe33cQ02CNMDYhisdXi3iQ5xt0o5u9nHeFj6kEaV99Pe3z75IPQKCQ6ckB2bNSKHl0rbKcM0yCnZ5dgp458xNNaUEwtlHMesTvoZcUjkfx3EWanjd82UJ/I3ZRxl+liebBXcVmd3maEcd338zI+wrRa8n5Ab4Ez9n5GUcD90u99hfkLWdkquM39IUmd1RHYLXjSs3Y2ByFUdGWUZBU7l3ZToD+crLsSjtLXVYZdGHvf32kTqhp2CR/X7w973e8ReOie7PfK8vFR5ZI22btK5a3dGdv82yzzqfFwLdeADwstnHRYdnzNCV9X507a6rOySzzrYdp3YNfL4Dk2ezpPdtShbaxCeEQzKbR1rnQzxryxwrZYZ2kTymGqJ3s8OQ/mnDPV2a4gTOw5QCfsu+Z6ktoMBi7ou/igH1P+ulbTlvBZJtscS+VC2/ehYVRuv1pPmDGo4zz3CZ5fZbA877PfKM+WjtqGBuIoH9fC7wN/+dfgrZ9Gp0z6fbaJbjvpY0vcYtw+JTKfAvkbk3QpJ1dYBW+x11kpbi7y5SWx5ee1p5UPjtO2SiR8y3KqVeTSwZfDqvcPF6E817txCXaMhq0aWq9NmX+4mHJfnmwUmifOYIbNZz6iEhvoWYbQHxBk1sqLSk8AlJo3HBRJNWiFOj/Of57Qt9X6NwitEd4nBrCLUqNwr7e8TO1fFAjnfYmrXFonaPxj1YcTWvxX+V4hhqDH5oODEotOiYVLT/BZLXYne+l9nGI3SkZJuVKpbDHeldKqs43xdS8eQDjRkq+GoYbpc3qvQhE+czQg9bpd2Gi/O0WBBdQQ0XoVRo60q+ylRfiulrkpWxelvnSrHPSNKQ6NgpfxYNHoOet86bU8YOhZGBOWpJaIYqpEj7Un/RtJXSZDA6FblP528U+An/2iUyjVCy+74nPxIg+37F+A7luAvn7UDx9MOt4aFc90gEdc/Sc6L7BGBvELOBEgvx8SRq7yhw+kuSN1BrTJJ2QCRZzq0lVeqwNdQfVTeS7M6Usflnbyp0ya9Lfb5KFeEf4sh79lGo+uEZAecESNf40ojVlmoDKtOm0q10q1Oi86Fynps3LnGu2TNnX8NWgj3GN/uYsIwy4Myb400ZfIaMbbdwdkr9WtgYYXQjMETs0E0ZMSjxpK0zZy2Or3OywCM+FEGVGOtOm3HZI3ln+NSZ630p56zvvSgM6zxMg7ELI7+VsbdJ3S6T9ZMOTnWm1UPKM/Vbz7T6fZ/aXuJyB8N/oeEDuQhZfoqF3dH1XvuhgifaZrCX8sioR/H1/4wkn9Ic65MIVT23ieOwDNljHMiV/wo+iFJQ1SPKLOdwxmhpxNCK1OiG+hjLZaxZuW38G2Vfup8zohtpPGtU/XrOxw/wjAQXXWz/PM0R8vAd3VCdJQ0iJ27Z2afVrRBlSXVtrMow9S11WmrNpZOmzJr2ustknTOg9JWJwsiuxxfOa98qHaPRbtrq/+vA1LtlClZo3Gq+hqRD643DINB1Q5wDjMSWDKYpPyWHtUt0hOlT+0uea3abOrLIxI41F5SD9tn1QPTPu4W7Vbo5/8w/DiNj+SH6Wg87TTxU0uVU66ZsC8QmjXQcUr40XkqQ8f9HtNsVdOUt7koO8blQ+G0rQOfpCHlRXLAUWdBY/sLxKj14LMR+e8iH9/WIPge2rX/m/3ZVdrlJF8lN71sAJ8pz+50mLZpht5VIjR/gBimb3X41omxv9/H/0Jvf5dsG38/EQZvESKQWF8nh1pvkRv3jojivEEuEblJPpLt+B52lehWOiyzPtZHac7Sn+twvkq7MWcb+Fxvt176+TxJZdikCQYN+f3e17Md1kl/9zbNmL3RYXgAvAC83MdRsV7tdbb6WM93fC0zNMDu0G5lvdJx5txfZJjetUVbQ5njc1zcav8SScVUoX+eto5vEQPRaN2t3tadj72OhxfIQeKjUVtI1ObFDv+XSdRPB+BzZDfva4ReN8iu7jtE+V4nFwZokDjeeceJ0S0Fz/eQywycl/OZ9vns0I56bZBdlXpOY6OP/TLt5qVd4BOEf+xPI2iJ4e7IBqFlFZiwS7sTYtBp1L1OdhfuM7w98nMdznvksPxSn+st8oH4N0l0+RYJdmh0TXv/v/u8/XzP74Rf8s8Cv+hvhX/zL7WBtwhB3OabxPnCP9UcN0Y4W6XxnIa+TqB8eI8YkrfJDo0KxY/+fp52odJm/1tcv1XmfQ34eMHdXSLwNVR3+v/PkwsffHaT8I+8Kb/vE+fhC73OCY2WT4g8U7ZMyS7sTeIQ7fT/P0WMUA2jSZ+jxqgRbufwGhc/rv12b3ubtr5b5LC9gasFGo8e0WTCtPd5tff1InH4HtNky3f3/tY7vqXjO70vo6n09i8VfKuL1mk8cgL8st7/1wkv6Wwe0mTvRu9vl7amL3X8f6nj4wYx9j7R/34b+Fhpu9efXSGR7glNZoofev1XiV4VTvXitT4vcSataOBPen9vExl0ThzLz3XYt8glRTWI5fwNKiz1vuRn9cVWx6sy6wtEzqk39/pY12nrc4UE345ptsAa8NPkDPYNctPsHvCzNBlzm6Tm73dYvpPIp0+SAKuG41XiyE2IAalOWCZOSDVStS/U49PezwNCj99N5KKwf77DeJdclPU2Df+fI87j10jA7Xkaz/1k7/cTZQ5+EPigwyGtqBOv0mhex7vKLHl4s7f9HMNza4c0WbLR4fx4Xxd56xqNzneJrXeD7O44Py+aqTp8XLZJIF2+epFG518lxvaLtLV2HSyz0f/3GAYjp4Rua5uNPodrDC8i2abxzBUa7a31se+SDIsVcrHGRmn7FsMMAfXTHYYXkeiUjoNUb9N2lT7d+3ijj3GHOE8Pel+3yxg7RJfrcHyV2JwT4rjf6vPWnrlOsuFu0WTWDm3dXiI7SA+I/FHGGyhYJzh/jYs2Gx2GzxH60+b+GKFR7QbtzAOiN9+krdX3kdsjH9Lo/tXe7pAmE57j4qU192hr+DpZs22azHmZBOvUVdLiep/rOqGXWgxyfT+xnT5DW58f5vLyoXDafhENGY8IEysENOTOaAyxSmNoFc2UttA3iPK8SowHoycL5Nae+wTBPnMRKiNdJcJ1jdz25g7VcoelMtEqzTly91BGvUkIco+cb9GYVqk4pox6WMbQgJ6QG5cmDA0Whep5Gddo1nO9L4XNLRI1udnrXCXM4ny9EeqERM5mRDnbr46rhie9b9fGKN4puaHspD+/RYy+yrgbvf8N4nDdIDf51UjJhDDJLS4KgKv973USnXuOpCc4tjcJugZGUCGK7gZtnY10V6fN/oVTXECifjcJgz8s85JOapR+pYx5k6zRGuGPq+QslpHP2t8KQydLh/dJr3edpO6sE+Gqcy2PnBEaHPdXaWK1v9sgzsGMRPA2C86enfP+Fom2HtOMa5WITsEeMSCXaGspvs9o6+PZiudodLxG0sFUghps/BhNun7uL8Fv+93wjX8OfnOZkEQH/M3PwK1+SFDa0zB7rs+l7tbcInQk/7g2a2RX46zgbKPDdZMIfOXZhMgJcbfHRaftqKyD6wi5HXax1D3p8Hv2yzRX2xx1OE5IkMD5+/eEBApWCR06/zOyu+gcjkikV3o/7+2UV/T2+0SuGcE20KHxTH/vDhoMnZObBUcL/dkthrdHLvXnlYd1CMW7+FbvTIjz+9Hex2MuOm0GGHRUFvo8nus42yBOm3hV9+2P2i6RAJpOtPDtkNQln+lMa+wamBEv4uw6Q6ftGo32dvvfzxAdo25xvcVzddoMPqlbVvqc75ObnyHy0L6rHFdvaripG7yFV4f0uf5+i/CVtLRG5IjyUfoSd8rYtd7XCtnhEpeHhIbdBXmu4+1q6U/jb6njR1l7g+ziyRenRCZMSIDzBrkxUsdnn8i4M5IG6JjS7bWOs+tkF2KDBNW8VXS3wHGV0LQ07K5KDbzIN2sMMzAOCQ3c6nN8j+jVu2Uu2jTaLKskWD7W4eNyxnBnv877PtldrzroaU7bIbGn6vsKwymRCzeI0ybtiw9xfJPhsZBqq94obXcLfM6HAjskJbAexbDs09bkORot3ic8vNTnZvDiFuGXM2J3rtLWeZOLt0dqs1V7ZoOhDFkl+usW0T1HDHWVsqDaLdW+tihLJuQW9DMiWyqNysPalAayq6M0I+nPVS9B44sHJPA7potdhms268+FQbtT/TglNvE6sWFr0abVNp6MYLqsfCictv+BxsimBrhbcER2KM5pUdlDcrZNwazi2KYtuhGTdVr0wYUywvsWSUWb0ojta6UeJBVsr/T7UyQf/R4xnDU2Hvdxf4pcL2rqz5eJEnuXnGPQ0FvvvzdJigMkfVOBq4OwQXZ+HL86uPTnXyE7HDoHbxMj+53e56S3q1G1rxKGd4fEcaYMnSwJd5MmMA47DLskIlvPGExoDKmi2SNrJWNT5vQ2MQSn5ACr9XZIVFulV6NRZySdbZWkVXylwyTNLJGdIunhnKQavtefuZV9VNoqSE/J7vAejbZN69FRmJDI1ju9rzdImpFRRI29vT7HrV7/gBhOOsNLJFp6wvD7ZhoNzueQ0JOKyPML98ka1NvzjIC7m2l/kLTNLeKMmWtejemHNNrfJsb7GhdTqaSroz5vgwvVON5imF5xQOO7ux0Ha0SG7PbxVF4nJBDxXp8zW8CfoDPrP9fCe/9+33X7EskhBX76SYtiQ67sNVXiz5Eb/5QBf46c/TktOFMJm3qmvHu2z2ObZAFA45EtsltsX747Kv+fEZ49K/jxzNKDUlfe1FGekvMdX+515JMThvJMGvMsqJHdk/K3DvkpkYnrfY67DM9qKCPWiVyEpIPJD0awzxjKwEXi7L9TYDks8xTXR/3vZ3vd+2TH3rlOyY6pcJx0fNuXMvxrJO1VOtcYM+BlupPG/QFtTZ/0ft4maZJHxFExlea4tH3Un8lDU6I/3yG7qu4SnhDH7IRcNDEhxuK7BVc6XOu9v01yJlE8aFytkOCXxhRkp62m8C91XG92fOtc73S8K7Pm6U31wEGvt0aj5XoT6yptzXQ2pgxvybxPi6zvdnxL8292nL7DxZRT9YHO+gnRe67F1QK/hq87CysdnqsMd+uUiQdE57o+5zQ5vtrnL51pWE9IKus7JBXrlKHedB7aPSvkkgtpRZ34LLGvFmm0qU0gD79HAsrymk7zbh9D2M7IruoakQmeKdwj+nKN0M82F3eUajHIonN71Oc5o9l4BuMM7i7M7+abRZ3imIcMeRfCh9XhsK67pWs02lN/3SMBh5Uy36ul7b0yljyl3JR3FxlmJNSySezUBRq+zTJxJ3SX6EJthD1ij6wQe0Q9vNt/136UhQdkl1enfZfIrW1iF0zLHMSnNp82kXrcckY+37Nenikfz0ja673SzvG+UtpZvkZ0m/YXtDWVV3ZHbZRTV2j0Tp/jA0KzVQdII85NZ/ZZhuUdGn1+hdwr8cac8cflQ+G0/SKa0fiIfKPjiERcFRbXCYFNaEiYkp2IDWLUrdG8Vo2gGl2TuCdkJ2GHfDsEEnW5SnbarhNGnhAjUsMa2gIZOTogjHqj1PF2ninxxI1UrBeYKGMsk5So9T6Gho3Kpe60QdLqfH59Dn4U2tfJN7pqlGeFOMUq+TMS7Vwv/WosHRACNcpygyh5nbYNogxudLysMhRKk/7OM3frpT8NNUjEiDK3sQB4trx3DtdJGq4G9BWy8wXJ26bDKOy2dcdUAS6urvU6NdojE28QXNeo4wY5b6CPsER2YG13Rhxv8blUxl4qMDqvGsU6KPVvkO+MaYg4rrvaN4gRZxSxCsRl8p2dK+RMW6VliCEjTVeHv76XHzS4VcjSm87YVSLsHWtC5IXBA+nBiOgJ2VnU2RgswjEtR+EP/KX21e3f9nfAH/+z37Q4jJbD0HiT12dEMZ0TWj8kQRX5ywinNDkhMmlK5BpEno3lhO/Eu3JTXpZ+5EO4uC4nJPiwSC4kqPO8T2hmqTw3YDEp8zpiGJk2oGRmgnNwXCOw8przdu7KTGHaJYbjCsPo6A1iOCz2v43014hn1QuVDzWcxXHlYZ/p9FU4dSKvE0NZOSV/Cb9Gm3Kz6jf5VxzfII5FbatzKD9BUsv2Ci6do4a1TtVin5vfKD0pf0uz4khjU/ggzosy4YT56ZE6LjWgeMiQ5ay7V+ZW6eyAYYqUNL1OePqIpP9p0J+T7BtltFFx5YVjKzMnZGdM2T4lzvYS0RXKrquj/sZO22qpc5U4l+pAx5cGdNid40Gf17PEhrhO5Eo19urc7MOg1bWCB2WCDlvlV2WaznyVKepB8XNMZMcRQ9uq0sR6abNO9Is4cH72/TSnzWCwu5Xummvjzcp8/A7p04p8Md7FqvZItUHcjYXYFK7VNtHzB2V+KwVGeXiFONb+f0LsTHlDGqp2j0XZcL3/b7sbHf66C3aDOG3ubk5KnfeI06ZdMCttxa2yW55YGY3hu6MyZx024ZcnxzYyxGa7QnSQ+lH5KD4m/b0yy0yNsdNmEOuEi3b2boG9lmOajHXNIbR3gwQVxaP86E6bPoEwWp4lO5ja8vPGH5cPhdP2DC2P9ISWg2v6k0JthTa5l2jEvdnr1zSxF0jK2Ts0BLxCojALNGS8TC4J2aBtW75Mdh2e7zCJzBs042Wdlhe+z/CQ64QYHBqyL5OUp6X+98eJoDzrc9ZYmdBynye0KMZ3dtjpY/xM7+cWWfzbRDgYXVEweLX7UsfZef/7Tm/rjpv4Wez1npDDmLP+zIjmYulTw2NCctQnDBX5rf73IjmXtk6iVBsk5eeMlp98xvBSk1lv+xI5GD6hrdFLJDoDifIszsE3ZCe2OjhnvZ9Ka1Vp3Oltz3u/Ggd3SK75IUnvknmPaevxYp+XURiF0zrJcT4hDtqLJD1GPBtde458YPseiU4Z0PDDlAu0dTzq/d3u45vK43w0wIRTgamxqpFpusArJJr2MWI01f5WaUJxUnDxHKHlc2LcPiA7cq6Hc6HjZ50Y6dAMhWf7O/GskbPUcfCdhIbl6x3aeml4GRWekhvUrtORINKOiIT/vcCdPwv/+38LeBP+6h/iO/59eOXd9nql40wB/RI5MO1OwMvEgZJPXyB0oxG41HH+CjnU/VLBtcapBuvLDAM2Oqkagef9/e2Og9tEkd0mhoKO4zo54K8T9fGCb3c85S9li7vuk74OOjRLfZxXiFP6gBgvBrY0EJdJSp8y0bnbfqXjTgf4O7l4yP0lsovmjowBlBcZZghc7Xg0EPBSh3uHnMfdIg6xz+Td54lROiW0J/nIS8+QC17kdUi2gXy1Q9Jsp/3dx8mV7LXtQxIsWSGG4ivE6Ff3fZzIOh06jR9pSZy9QD4Iv0AcukPy8XGI/HuJYbrzBsPMA4NA8oCyea/PR31hoEZZOdab1Ui7SXSPjsNhx6Mfo1b/f5Q4KxMib+/Q6NF+XyDncdaIzbHPMBXMeU+IIXqHyOc1YvhCghTaKTcJXTpX6XaF3FTteqsrdDblhZdJeqTrCtG5BqPVQ6ckhW+dyJoTEnjbILxXHW9/zFTQdton3wLTsb5BzkIra6/1Pr+rw/Jmh+UWMfirQ+Tzy4o65pAEye8QG0/6e55mu8Fwh+p89P8SuSdggeHlUpZZn7frWINp2lg62NqCM6LfdE60cyF0qpzQSXY+d8o77Yh5zqy6Ahq+pWXtVWXxiyTY4kaBmwEnZNcT2losMpTjBrhvEXn2PMk6U+evMDw/rVy1vwn5pIc2Uc3eOaHZw1d7f+7yPqCtrTbCEo2W6HNeoMnaqjchN2nqaMsj4usROcNc6cKg2kvEKXbdheEakb0GNYTTuW0wLPf6+5d7He/0eIGnlw+F0/ZBi4R72Tb3vEjK+Nm8tt9Kf7X+4ujvp5X6/mlt3q+fWmeRp9c3onE+5/kHGbdGRMZE/EHaj8cTX7PR+zrG4pznl403D6fjvy+Ds0Z9x+8uG/OvR3nanD5IGc9t3vp+O2UeXOOxPiiOv5XxLuur0sxl6/9B2y1yeT/Wfxf4Kz8B33FE006H5IaICU2q/te/FT4L/Abgn4df/ibww/DaO9kVWSS7TPNgnvf/+9HC03jv/dZh3hoaEBn3+0Fl2bjOeC2fJqPn9T+Ppmdz3r2fDL2s3fuN/7Ry2RrVeX47eudptDj+Pa7/QeG/rN48OnwaPJe9u0yvPE1n1DV6P/n+rerlMRwfRNe/Hw/O07VPW9sPqlut++3I1G+F57+V/seys/6v835ZH09b+6eN9/PRuZeNVdf/g+qzy55/q7Li/Wyyef1+UDvnMllzWT8fRMaMnz+tfFB+uozm3g8/36ouu6z8fG2rb2ee38643y7t/8/KafuF8gvlF8ovlP8xyhf7z6/683D7zydd4h3g6s+1FI0X/yIs/efAb4Vf/ieB3/c6/L7n+cX/3R/l7/mNfDNM+t/+2flO2y+UXyi/UH6h/EL5n3/5+QYtf6H8Qvl2y4fCaTskVz+b/2oakGc4ZrQjJke0w4QPaduR2+Rw59X+9xskdexdcuB+Utrf6+O9R9tyvUsz0I573V2S6rVNtpGPaFuf98j2stu9hyTVYZcc2l4G/hTZ0t5keEW6sK7Rtnl3SIrQE9qhWtN1niXbsaYYLJHIp2lRkNRMU7VMG32T3ET2LsmFP+tj1fxy5+VFCZe0T/IAAQAASURBVI4zJSkWpyRF01vSt3ufe+Q63D1yMNy0pIfkuvKt/rtu/e93XP0sOfO2TVs3502H7y7Z6WDUzxmNLiA55DNyg9cmSTswTdKt8HNygHubXIazQW5iqykL0q0H2t8i6StevgHJg7/Xf36MnJd4j3yjaIHcqHWVdlh9n+GZT9fGswlnvT9TeZyX8zkkB3IPyM2b4hHyYdAtGg95Acpj5l9EstfbmrKwSKOHx6Weh+496C+NjiP3ppIckUO/9XD8dv/xDIJpnXdp9C0OTHmTrg7Jd1SOyJXb9ayd5ztNhTYl5R6ht1/+m4Gf+DJ8+ssNef8i8G8DX25yyvNom33MH+njbhP+9PtrKx2GAyIXIJcz/UjBtZf1mGZqOtQ5ubxA/J2X96aVXyfn7KRvyHnFmsK3x5BuTmiy0zQt6d25HpKLoA5Jqs02+R6jqVymi32NpO8ahTU927TJSrebve09ctGGcNZo5Vafx12G63yFHMjfJ9/+Oyd8OKGts9egf518OgCS+uJFJPfIDWhvk4Po++SyKUh64HH/8YztAfmA6wpN1q30/uWdPfJR7oel7SOSUr5EzmcacFC2T0jqpofunxCZPSFnwL7W4d5geBHJu+R7ds5JPa0e2+HpF5FU3XSfyAHTmHYIz5hCNdabB7Q12yLHA3YKLOprL4U5J5f3iKO3O0zKC+Wh9PvVDtchbQ2OiU6bkBS2tTK3+30eb5BLJOquxzPkTOBVht9/0875UZLuJR/8WB/n6ySVzO+vit+jDvcjogf2aUcrpuQ27m3yDbEpuRX0XZI+OSEpuspabQJ/S6+Q2yXlM22nZ0n67jtEr77dYbnbx9SW0eaQftSFl5WHZN1PCz73yWd0/lka3fwp3t/Reo+h/XFIbDvLjHzb9hrR5YcdnrdpuL1LzlVulvktd7xsEh7WnpBWzkgq8j65ZEPbpto9Fj+LI78qG98mF4jsER3pGHsE56ao3mV4IdgikePb5DKPbbLuYztcOpuSC2OkTflFe2GZ6PqxzfazDFONz2i8IUziw/RI6W9KeMVyXvDheuyVdl609PYIt+/ReO+crNlefy7+tMfWifz/2TK3PS5eRPLTNL7/4d7+LqGdp5UPhdP214hx7xknBfAhuYlJp26/t1slTpEKUYN8hSDVM1nn5ZlCldEz85gfMTQyVAbC5DMVVg+yf9PQVbmofKqie1j6qMpupczNWwpPSj1zeg+JYeW7RebfHul5CZ2UaR9Dw1sDZofkhZ/29jqVMvy0P5+R8ySnBfbF0p9GsMS8zPDj2gr4anTW3GtLNWg1BJ1b3Wqv8K2Q2wktzs330w6LQn+f0JHnKsTjjFx68Ijhh88VfEsMz3B4M6CwuWZLZF3WyE2Th+Qj3MsFjzXFVYNrv+BCp01B6LzOyC1Rj4nwsGiIKPhUUHsMhavG8zJDHl2b059rdFbenRFapsM+LfDLt45l2SnvhOmIrJmwnDGk/zPilMiv04KjE4byxfxzyDpXpblHnDYIvZ3+VVjWyneQfxL4TXD2d+b2Wc92bRMlIV1B+L+ek50RmTQl/EV5Juxrpa89hk4b5LtNnqk4IzKmwiFvinPl0yKRIWelXpVne4SeNDQ9jyPPebhd2bFIAkdTsoYLZQ7ynHOvwQn/tu3YadNB0DETLufo/DS+palD8j3KCpfBCuerIrZfnTbX1+DOXoFriRjYD8j5w2npc4mcj7Eu5CZUZY1tH5e2i+SslfCJf/lB2j4gBp6ypeLMvz2Ppq6YFvyqj6QHYT8kxh4M0yHr3/a3Q4KlwqwBN9abUyI75Gnn6tzkqapvpMml0scu0Y2PyzOI3jJYZPCHMs4ZcXwt1jtieGZKHlwmclwe3ie3C4vHKZHvOlCu8zHR58oV1/Swj2ngT13hjX7TDs9S7+ecBJmnxOYRh66TskJ8KjPFj3PRLpnRaENHQJy4zurSRWJjnRdcu8aVp8dlnziarskqkZ0nwG8lQe73K+JA+0NYqz2iXfOQXL4CWXdlQV2LyocLxL46LG2rnJDvjskN0dKRazLGi/aC9FttXp1qA2eVb7WVDWgoV+VT10CdoR2gntJBEU+eEbfe497WQH0NYkyJrNNurjabvPmE2BDCt9Rxs1L6qnh4TGysWoR9Shwu5+kcx2nf9lll9n7/0TaYEh3gmU/tqBViU9ZioOYB+RbkDheP7YzLh8Jpm9A+ovkO7WN33sqnEN2lIfI30Cb6o7RDkFdJpO4lcjD0T/bf30eLmL1NW9gbtI9XfrE/v9rbfIF2o/dXyEHOe+QjmPdoSP915MISo2kTQnT7tEX71Qyv71zrsMv8b5CrjWWY7yERpudpt43D0NC/SW6EukWLHv4EiVLLRBo9Kx0Wo8gemP9xWsT50+S65e/rY32xtP+V5CKSt8lNbBrGRsM+R66M/xotwnCr93Gfdpj81f63hvcN2jpv9v9f6O2+yNAZ+Bjto4s/Ti5QeZ52eHOF4Zmkn+zwufa1nxPgT/e/18kV0b+CfGxWBpyQCxXo+LtLotcvMbww5w3yPTt6v9u0Q64vdNgV3DLwF8jtkT9NW4dfRS4iudtxKdO79jdp9K0i12m7RZxVDdG/pz+vUSDno8LbpK3NDRKhq7vHN2iH+F+l8cc27aOtE4aRI6NpXyQXkSzS1vhzpd79DvuXCy4mDIMOAN9LLiK5R6LvE9ra3u0/G4T/nqety4/RaOoLZLfsDjHkqnFxSK44nnWcPU8MnXvk5rkXCA9/GVj8kfb3PZpMWvsNjVZ/9zf+z8DX4F/+kYa0PeDXkzCmWvs7OwJWyRbabkf6D9CE0l3g1/JNq+O///vgHyEXkbzWuzqn8c9h+f+045sO+50+N59J35BdujWi0Iye/mpi9P54r/f3Fly4A7tHLhDQWdqmHRH8NMNgwkqv+8UOzyrDj2vPiFyRzs5JFsV30VD7bv9b5U3v46WOC7/U8Jjc2PYy+YTJQX/2/YQPf22H5c/Q5M/Habudu30M5dlXabx2mxx7/HLHz/eQ3WmdUQ3uKe1Dre507tCW2cuafozwvLcEvtZhfavDb9s98uHiJfKNzE+Sj7PT5/5pold/kjgc4sXLhr5ELiLRCXKH/01yy6UO+AmN19b7eBOGN1+eFRxokCzR5NtXaPzspQzqTR2UX89Fvake8HIDx9XY99mXSPDgFpFLD/u4n6fxxI8S+v0C7TKAH+51P0uyPfxkzHUSRJqQAJc64YeIgVydtvXe93Olj8dEJu7SeG2NtjOkY/ir+jhvEJ37tY7/L5ALiBQ1CzS6/TSNlnbJx97vke9h7fW/P0lbW536jY5Db797izhrwvROn8P3E8dQY3iT2E6v9jZfJrx8hxjrtzsMOp9r5CISdeFlZZNc2HLSx/5En/cXyadiXqHx4/vttN1laH8YNFUu0ed+s4/jrdmQ7Ks7hPbWabLiTbIzukIuIpGHD2hrW51FnfCXyMeeF0j203gH8msd/u/udb9M4+EXySbBFg3f30V04DYXLyL5IhcvItnucLxKszmlHeH0IpLtPq9XyWckNnvd1xkG57Y7nrQDPsdwvc/I5Vbf15+d0Gh6qY+hI2g2hnbmLk2XVxvlvONlr+PidaI/5R/xU8td2hp+nlwmcp+23sKww/A25MMC53qvt8Gw/FCH8zf0/n6cxs93aF8euqx8KJw2jdxd2jZk3W7X2J3RkFejYVMasvS4D2mL94B8K2OLROtOaMR9n0TmzvuzLWKoQKJwR8RAdvx9Eh08Jow97fXe6u/rDtFdhmkee/1nmRiOLj5ki/SYRN+MaqyTiPAuF3caqmK8y3DXYZ0WtVgl2/QPyJa5zgxkq39KGEGnbb/j5qjDPul4uNfhNVoh7lbIrpaRtf0Ol9E98VIjSTob28RRrBFWhel9kq7hWo2dtu3y3vV/h+H2vlGydRLl1uk1krVKPpR8TIxO1/eEpNWd9fdTEsVbI+utYa1CnXYYXBedJyM3BwUXGk7iWqPNqOc9hju61WmbkujRGlFQdZ2lOSOmm+SbfutcdAL9Ts1Jwf0JoeVzEoQxWibfjqPy0p6KxZ0reUlD54QoVaOTfgvtbpmnME0Lfg5JOkUdV0NUeTAlqaxjZQn5jssijWb+od/0rzdr83f8GvgP/niTwDulU522lfKjB/GoT0iiOCS5JTTe3SUG6hrZ9dhk+HFt8Q2JoirPNLjlHw0212NK5M5dciut01CendNk5yGJHJ6U36Y/P0tk0z5JE3I+Ol3uAEC+bySdKSNWCN88IHQkHpyTtHNIdj6OSRR4r7y7S+hbR6tGfreyBN90MHV0z0iK0RZJMz8g3++rfHxIozMju8dlPNfCHZlpf2YA437vx7aOofxR36wSHqH39SzRq66jevGQ4N42BtgWGeqKU/JxXHnJYM97JG238vQ8p83+3inz3CbkLu3N05vKTg029dtxeebnKdSLE7Irt0s2yR1vvz9zB0sbYkrY0J3gw/K7znNKIuczhoEEcawNofx5UOZ1j2RaGLx4p+N/i8jqLRJMPCM6TDwu9Tb3y7ymJJJvMPaEfB92t/RlSuwiCaxW+0KZqU2kPDLYpSO5Suy7KS1YrC5Tz5yU/tYKfqY83WnbJmvseF8n6aPidLvDOXbazkfPNjvs2lMVl67jaYFzSpyFR0SGmrqrbBa37moe9X72R20do+onbxlXhqww32m71/uoskubUJng2rsT5G3hdRf3jDjQEPp2fVb63A7IMQMzEFZotHzU/3YN1DfysrJgh6HdNbbZzoje1471iMEyOaKxSGTWFWJ33+Wi0ybsOpPqlkPyWSnxbXm3968TCvk2qzDskZvHlUM7vZ8rJEhSi3bcXRrdGSQ+4enlQ+G0uRAHxBmScKdEAGqU7JHzDlXhPyapRivko8UiS0N2hxiXp/2ZW+o1yqKS10G5R860aRwfESI8Jmdf9him+ymMIUpCp01GUKFAIxRIOqjO0gkRbCofjVZ3XcaKcVbg1aldIZERCfiMCNwZ2QlUEO+VcaaEOCX+xdKfjsQe2QlUSajcZB6Vv23Fk3NYI/nRx8SQqMJUB3axj7c56ueUoWIwEKDhJR6XOo6uMDSAVTpVuKm4xWeNLNd6bqtXpf114gjs0Nb4Pjn3tk2c0GrsTTusGjVjp01n9JTsTjnuWpmPz+WfacedAq8aWRpp8ugVkiJZ+9sjO1kVFyqSGUlpEz9LhIeci4pOBfeQGDFH5FzNXhlL/tAI0tEWZ9Y7JHx0RPwoldR9hpFbne81YiRKcxaNLpUq7wJ/APhX/3gLk//THXn3emUZ9JxhfvSUaEO1sMzZkS1daPAp+6RRAy7uHCpPxI/OlTtndV102jTAdKzv9T7kkyfkY7CQNEZ/zhim5MxoNHNKZIf0KO6UYUvk3KtK/0qZ0zbhh53Sdomh03Ze4JVuqkGqg+k79cJBR/dCx7P4UZZD5JlG2hn5DqJnpCckKCLNyE/u0OgE/lLa7ul/THaTnKPOpgGMB70f205J4MXnh2TXXaf9hETSnxDeqXxjvQfEwRefVVdUY9f+5Nc9kvY6dtoWGX5DdItEvQ/7811C3/P0Zl03aV2df1qeqeeqszElwVWdXQMLygkNVuWiAVIDyDC0Tw4LLmbENjgs84Y4bf4+6H26FlOyS2XwzRS2LUJbfhvOYMg98s2oXSLHl4gB6zlH5b1BOPWXtLJPZKOyTONaPGo4Ky82Sz9HxD4zgGaARZw8Ikc8DjpuTsjOpHBNiS68rOySz7tIw8pqdaoBWGVYpcn6P4S+1V0GbSsM4kCdqQ58TNZMca4tKd3OiL47Jzz8mDhZOrHiyMCpsLomY7xUVaHsgtCo9FtTSV1H7SHtFZ0siFxQji8TVaVtcMzw0y8nvZ60p35VRjnPPYLvZZrarE6bNtthf6dOUz7WYJ3z1Tma0mysK6W/GY2HHhNn0vU7IgEp6b/idpecqaW3f0A2jB4R3hQn2qOu4wHDIn7eJZlP94kMu6x8KJy2VZLu9jJJj9Rgc9Ffpy3GY1qKgR9VXaVtBd8gwmmNtt06IYeFN4DP0BB4Sj66WJ99rMO0Qr5foyD4DCFCnbR1QkBelPFZmqBdJqlpnyXC4FmGl5Cs01LOjKbe6nOFCONF2hbzBvlGzTYRuipEjRXn8DpxTm6TyIJjGpF8nQg/+3mdHLLcJBEOmX29w/J6n9MiuQzGdJdt2hb/y/1vo4dXaeu11ce8Qw5nV8Z9gWbUqEiv0NL1XirzpsNXDYzXR/2oZCHK7KzX09k3gu532m71+kY7dTQ+1mF4juE32hzPKMvHybfeDggtrNDSVYzKuHP3SfLhUdN+pa0b5MOv1dkSvuf6+0/Tdo5/tPd3i2HeuvUPSMRWnltkeJh9iXzL8BWaUNohKQGTUX/S4zoRhtcJLStwjfKLiwkxfHRAXyPBiS1ykcKk92dA4SoR+h8la3ZG+HWXfMfuETEwpsTANeAhzjQ+NskHPu8wf6dNw2Wx1+HT5OvPP0zLZ/0zV1vlX3nQFucuydlcI9sOD4lQMqfuNb6J7Ff+o5a+MSHpR+J2wnB32GAYtEzMj9JkgIbpLcI/WzRlsUqMWmXUZ0lgRQNReaZskb4nvV9xu9P/f43IFh2tqyRNRhldjZpPklTlOseljrrV/iMadbAWybeIKLDcIN/50+Gb9j4/0/uadVg1ll7ofRmIobd/peD7Ftl5Xul4+gyJnOqw6ZA+JinJ0Mjkt/d+P8MwjWra//9U/3udfFcRIofVQw87Xl8ll2fR63+S6FWdsmWSjvYSyRy5TZPhBsiuljE2GKZyHdF4Ul3yLEmXh+xQ6yBCUi7p+HY+Oi3KrCrHDdI65xu09VknF88clWeLhJb8vukaCd59ss/zjNDvq729DoBpqdoU9PkblFgnhujz5APmGunVaVvrfV8na+tusM7qawwdqjPa2nsB2SpJZZvR+LAa+Abc7vS+Tvszv/u4Rr6PutfhkFZ0zqQFcXiP4Y6lwZ0bNFFnoOAx2bGQpl7peFpkeOzgoM/3o70fHYU1cuGWuvCyskUC+TrlLxH+3el4la/GwbZxeYdhlsi0/5Z26eP4/bkNwl/TPm9lwTL5Zqf23jlNh16jrc9Gb3vA8EKbGjR8gaSxLxIbZayHrhK7x7p3evs9slN8qz/XHtomutzAJMRpu0p2sjyWAvPTI3VWxc89stOp/DE4Z9BLWbfKfJvtgMjnSn9L5PtmOoDQ0lZ1YF9n+EFrxzIQ+HEab0H45zax2Szv9HevkTXbpq3rq0SmSLs6ymdkx/oTDL8ZB3EeP0NsY2XSH+Dy8qFw2tw+r1E3DSvTFs5J6tJDErHdZbidbURwjaS8uE15RFIGjDSaRuUzBbNRCR3HFZIKMCWGp4u9SIz/t0l6pB64W8MwTPNY6n3cI4LznBCb4xulPSTOnTsQy+W9hE3v+21ymPmk4Edb0RSjt/s6PCjtdRxkeHGtgDwmN5HJPOLbPnQuFklU7JzhTXkahOKlCqQlkv6i8lQZVmG6TaLaOj21n5OCW1NDTjvsKk6diH3i/EOi/vuEFk6IA7BV2jrWHklt2CJRRh11cXZGaO9dYqxslfkskbMw+8Tg9JAyxJjWmdfhcFx3ApyPkU7Xx8i4bRWsVUgKp05ZdQINZuyS9AhxMSn19sqPTqkOj3Ug6VYa/rskYvg2odsjQgfy4xZJHXKeJ2UsFVYNDDnuu6WO9Dklaz7PadsmPLoi8AquHZpg+IcO2uK8QNMm3wP8kYIsES9hKpR2SS4t4a9DhrJH58nAhFFJI5AGdYwAno/wvkOixNKasuUukSvb5GieTps4ekR44pA4vjNC6zr4SyTtWZ6S5pzDuwzTcJ3jUq9j+t9YFlhXnn9MgkWPya7/fsFj1QHKDvuekZ0I5ctSwbdy1bQo8aPBslhglO6uMIzabhPZ4N9HHbZzhgGMxdLWwMsaw/TIFUIrkGDKUcHLCUn3m5Z67xH60PCYFHxXPtDAfJsYbRqBNRBT5QkFfzvkTCQkqDPtdaoc3yS7J6vEkVgjaf3SzhoJREgLylYdhnsMU2inJONkhyYzJ0TXPSg4Eo/uHkCcP/urO5KVbpRJyhkd0UdE56pDzzqcOqYrZYwZ4U0DhdM+nsbiNhd32mYkyPyEpLL57og4CMr9alu4c3bW4VUuH5cxlAHKzW1in0lvGtruNmpUix/15WVFG0un7YgEKuTlfZIeOXbaZqNnW8TGgcjHCoPBPXXmWqm7Q4K4W+WduIUch6lBoCkJrin/zmiySpmhQ6ctNcaLMb+3+//2J00ekXXx54w4GwYEXCv1oThwfRb73KZkV0qbTIdI+tFm2yXn05yH9mDdvJjw9PTIGTnqY6B2nB65zvCG6vXS34xheqTpjZD0YuloTBc7xAmlw66fIS04B+107bfV8q4WLwpSV+zSdN4xTy8fCqfN6N0h2VFQCIi8U1qUwO3EDRLpXCHRq3Ua4a6RiK+LsEHzYnV2JuWZSNOTPqJFRDZI1O0Wibjt9ecTsl29VOpBBOhKf1aFAeSSkXVyicrVPqZ9HJHo8vX+7grZGdni4k5bVYy3iKC52ft6MMKPuD3p71R8t0gawClJkzMao0FldGmR7GB4yPaUti63yvtZwS0d3tvkPFI1RG2rEFovz6qhpvFoRLPi2zG8gGG1PHNNp8Tx0uhwt1Clr8J1/Otz2kIc0+d6vR2SzrBS4JsQY2KXXDaiY1yVxkb/uUEuzlghgmyj1/uvaUpwQg68r5dxLfulvTu4GlXumi7S1sn5Gj1+jqExbX8ad5OCi0rLdDwoZCu+x07bLeK0SdPLhN6e9Hd1p+1mwXdd28p/GkoaGBr08ox9KFfOyAUGHggflxmJSF4V+BvEwlroz05pC3Srd/bvvgTfuAv/SgGgIu0h2cqZtFfX+xgT2trcLs10lIRpxvCyief6/OStui4QI1RjQWf9Vnm/3X9X/jJdyF3q54jchdCPRp/G64SkW6p8dVbOibyqTpuO6m1ijFxneFkA/f0RkQnL5CIEYXf3a9LrG3j4KEnfu9nfKTsW+njKzhOG/GCAQNl5UmBbJnpNnqPUu8kwqHaD7LTdoq3L0ajtan9+hcjDq4RfT0bPHH+nvFOXqgPc7H2OpARPSNBIWQMJfDhfiAywjo7f2GnTYblV5gM56zNPb7rG64RNpI+KW7MpdNpukMycpT6u8nmrjOHaGkS9RXjC8a+RNVsvc1N+3yNn/iCG6hqxb7R3jko9Ch6vdthPCR9MSTRfQ/l5ois0KBcJz20V2OSXDcKvlZblz6tlTJ36M7J7r6G+UdoqT8XLBqG5kw7bhMjv1b4eGx0G5ZXzmxBd+LRiIEpZ5bw14mcFznmyuxZtBOm4Blssynp5sDpt8qn2ofRjwEg5WdtDHGrpxECIclv5Kw2NA1SQAI9190pb9ShEv+mcOP6EOG01iHmN8FzFrXLjhMgqL2IT3zOSwVbXoKZIageIq7HTJi3cKs+2er8fLfjYIHxuILvKBssekUMVt0dk9/D2qM0JTTfcJLeQ6lxrtzuHCXG4t0nwpLa1uP7iZULW52nlQ+G0/SLa4uwRp0VCM9rkgmgYuJgyhwatBLhGQ8AusZueJUaP9Sb92bXyjP73syQtQcSbhzwhRuQSiTrrVJwQo1xYZH4jD0acJwX2K4SpITtr1rtGFleDcoXstI3TI28QoX6j9LHa+zA6d4NGuBKgKSVrNGY8JAbTE5IaMiECepHsRkmgGtbCawrSNbK9ftbH2i1zVSg9W+AWp6ZOPFPq6dwq2LzhzHLS27lGjqsCm3Dx9sjqtE3JOUqVzQ2SP7/KMGqjclT5qZR0VDQi3GXWCBHuKblVUaF0g6T5KCwhwm2JCHzbSHfOy/mI48PSr//rRC2RVBV38JzXs6P+FghNrBPHuNKyRsEpoTPhGqdHSntrfU6P+3Nxb9rjhBhi4m9ChLKOqfSiIWvAZIlcf07Bhc7PITE2LjMi5JvF/vubnUAW/3ofxNtkDoA/fLddk/k7/kv4Cz8I/wbxuG8SoeikiIE96a9dtxnZjYTg2v+Vq/LhrLSF4Y5RNcgNFvn/hDhK4lZjVr7eYHhbYuV/8ey6XyOBMB0bYVKu9Kl/88ztM0SO7zOkAXc3DKiYkrJI0vY2RrBMGOqFjQ5HxfGk1BePOj4bRC6YHnOj11XGy0/PFJxahz4P5YnzuUrO513vbR+O2upEyE9VttadF+ehcT0h6ZETIl+OGBrTOp1XyS7aNaLvDFaKgyqjq9Pm/KW9FZLRID4p7TVwqxzfJXJbONSbBlYPy7NrJAAgHa0SOe4cr/VnTxjK7FXC888Qp8i5HRFnGYbyx0ApxFBdL+ugQ26g5YzQkrxxTIKek4L/q8SwVr9LLzPipGsoGtRbJOlmYz28U8arNL/Y4dT5FU6dMPGjbbBAdJfrc0ICJpPe9xLhmWvEsXHdhKHq8HE5IecUTxk6VPLhUXk2dnRmo2dTwkeL5X21R04Z8otOgTunPvs6jTZukN0n6b7SAP3ZLnFkdHwhcpsOh/J5rIf2+zius3LuJkNZ7DN1oLx0leyCXiWyTrvupLS9So4XnRB6W2XIQwZclcPSik7bjMg6eU27ASILJr0/6U/5s0H4z3XYKPNSf1ik9wqTcmdacFb1ou92SMAFkm3meitTpLtnyO2r66O2Fo/HyMNjWXhZ+VA4bcfko9KQ/E6Z0sOrX6IZb++SLf9tIjSMktwlzsYmSVExVeguw3MYS+WZRuMDkkZhqsQXSbrZ14miMJJqpGlCDi5O+7MvEka7x/DMiGkIa/2dBqq42SSH53UQNkiKh0JFhajCWOo4m5FUgjXazWYrJL1hl9zq9A5hWK9jPWR42YIEu0acLI3WTVokZL/34QUo095e4T8hhsCs979J0p8sKum7JC3mgKTPyFxuX0N2b8b9uMW+Rg5df7m/8xCsczHVCZIeOSW3Xe4RoXWvtIWkPpz1eb3FcEeujnHW29+nXTk+ISlSm0Rp6KBcpe0kawxChNBSGfcE+HMkomsqgfORjjWEFM513EWyA31Y1kAcrpf+3KUwLUVlu0eU34xkALqjKt2PnTb5wl2BXcJvVzqcWySd1qjdVsf3OQk2PCK8ZiDohOy6SYPnBWdPiLDWIbePcdkhV6ufQrtP/QY5DHpIGHGbMNge/cu5Pwj/B+A/XIUfOG7I+SLtcOI2uT+a9rFc0z4mDC9xqemRygBl3jG5nVfjc4vhujxh+HFtg12CLh8qi10zU1imHa4HBbd75NC68mlKHNy7xBGT5pyDKb2VzjbJYXhll46FDs4CSX+/Swxj4XNuUxKkWCUfj/5Kh+MdkuJ5lzhApySV7oTI1VVyLgaSxqbRruysjoT1toj+uEvSMzX2pFfr2VY45CH14lGH5UGvt0dSqE8Yflx7r7fZLziTR93BWO/9bRHZY4DwhBi7Xtwz4f3TI7119cvEoJGXpkR/jfXmlBi6++RMibBMiZ47IfLaoNwBuTxrm6F8/ir5SLLZEYfkiABkA/yMoewy6PwOoRXLInEq75PdshNysdQ+jfaWiB4+7fhZ7/OXH+4zzLY4JjdEUuB7i+yiHZILOlbIEQtpRVn9kJzPVyfIu8qB7VJH/joicuaAZpRKb8os5eiUiEbT2XTUDfxt8PSdtl1aitlJmR+EhvdIkN1SjfGx06buqwFNRjCo6wyYq1MPycUo8rCBiU0ic5d6O8+e2vYekRPusFb95DsdyjFetHN9f7eP7VpIZ3sMb/FWVysDnzD8uPak/9YpnNJs9SmxNQ5J6vEeTeZMSUrsw1K3ysI9wmfaC9VJP+vvr5AgwzmNpg2aOF9tP3l9nwThLLM+N22V6hwf97H2GN7kCY3Xvk7kGiS184Rhquw6kfHvEL4/Km0twvKT5DjLV4icuax8KJy2KvyN7p7QCEjnbcbwA65HZOt+xjCdyYVQmHgby1J5dlbajJ9R4Dma05/CySiDim1c72T0TOHuO6NDiyTSJA6mIzic61HpT9hUimOnTZyprI18HJMzgfbxuODurIwhUx4zvG3OuuLUckTWTfiPGeLEOS8QA8b3FSeua53rQnlWBZd1ZLbp6H1dW7goGF2nGdk1qALENbcfHSHbnjN02jSy7N+2lPmKx+NSf7H8LX2dknSWpREe7e+I0GAdX/peImmtFV/OS9grXS8yNOJ9J/3MSn/25RpZXPs6boW/0sL5qJ7zsF/7flyeHRGDvRoQKtejXt/ASO238qhzEWfir9JM5WFGz8XZEx+sjQZwwSshHJF8o98KnBzDv9Pf/TjNi7BtaSLfHQ1ffXM4iBw4Ke2cm/ip9C1e5LmK20qrdTpVnlW6qf8rC6aEZuSdMcwq8yozK53V4ISpPJW3lBkaXHWNTaMSvjG9VhkjH0o7lVdsL2/Lv8KpDPNyhuMyL3nZ9uJPWO1PvNe1EoZ5bZW1wuxuh7IYkrZ+Vp5XeSoOxJm6cSyLxbkkXOmhylh5GsLXC6O/1edV39V1cd5jvSl9SFvSRZV76rlTIh8pMFpvjeGc5JPab6UNyt/idrE8XxrVZVTnmOH3CCu+hanKcemF8tuxxM9s1Id1p8T+qTypvpLHpwxxflT6labOGN5OfZmOOyk/Y3krDsb2kXStPlggDso8eWupurvK9Gr3Vfp8v2J/ypsqSyl/V/mnThW/lQ9cH+eqjbDMfLqGyL86H9ddG6/ylmUsu6odWe3VQ4ZBNNcZQm9H5Vm1C2p/Ve66hrZdYnjnQV2DCvshbY3Oy/+Vb9z9lkZ9Jn7EtTJZPFRc1LWD0ISw2m+lndVRG+XlWNfW9a46oK6d+JtHfxUv1a+Zzqlby4fCafvFtBv5lmm37WwQQtNrPiM3aE1JCsMSTfDeIVuV+/23N9DJ/BvkY3pnJPXuNeJ8+WG9FbI1vdL7eY1ExOjwuaMjoVpvm+yOrZAbjSCHJWXgdfJh1QPyIULH2GGYIrfe67zX3zs/jS4F7DMdZ+4U3ept3Sn5JDk0+ymGAnBW3u/39tskxcXo7ITcbrVIix4sM7w98kVyY5vC2e1yI4bPkwixBh19PT5RxjT3+WMM0yM3yfkL16AapVXZr5FI/KeIEen1rc7rVq8/I6m4S+RGpxvEuFlh+HHtB+Qj3OfkAL11XyXpkeL0EyQl5B6J+K2QcxDXSaTIi0hmHd/LDA/kv0rOMjgv52OG3qTDaUqAUW6F60bv4+Xexw6h1cmoP9fXqB2E5zT8dsjuqzi7Qgw6DQVp75BGn9tkV+RTBT8Tsnv5HC3P/ZxGC6/1Nnu0tXyG4e2RGhxLRLiLM2WPKT3KGA3wWirO7tABvE62pqd9QoZnJUSv3FojH/P5bbRLSn73r4Hv/+PtK7sTvqnpXvqP2xgTcjubuF0jxqm4dB3udByYCnXecWVbI9Y6vgcd18sddBgatq8FJDaJXJz0MaZEdt0q05ePveQBspO5QM59zWj8UNNwz8iOzvMk7Vc01nXx9sganNrofb1IzjUf9mfKi3MaDWg4v0CTQcdE7n+MdvOYBr/nGtaJHnmNyEj52IDLYcfHRu9vt9d7kXwGZInhx7VfJfrlxdK2RsqXSAbAKwzPsW4wvD1S48f0yqvk9sjzjlNTWhdJ+tQi88+0fYrh7ZGTUsc+lHMGDN7pY/1Skip2n6TxPdNhVo6rN9UDN5h/e+THSGReY9l0vxUS9X+Fdn7lhOwcvNz71HirNodwbBAD0zWn92VarhkJvlvo+PsuosenHeZtktHwS8kumPzmTaUr5PZIszS8lfUxsTcWaLfFynMHvQ9x+hzZHbjR362Ry4iu0WjMud1juFOuQ7ZR8KM8FU8b5EP2irtJ7/P5Xu8BOf67Q+TVhNzsXXX4uNwn667x+1LHIYRWPkbsviojZqP/7/W+1OPeorw8arNB7FR16pShjQW5PXK9zG+5t3ue4e2R2nA6yWZ6vECT08K+xvz0yLu9j0+VZ88zvD1yh8bTd4g9tE3Tv88S2QNxpMzA2elwvNyf75HU1yk5j7ZDbo90h3Gb3FK6VOa5Q1J7n2G+zaYOfp2LmwUvFXzs9jYvk0ujvH3Y4nqbsfUSuX1Zh/IWF8+uu2P2KsPbI7Xb15h/e6SBivUOV03VdMy9Pu+d/v8n+vh/kMvLh8Jp+2vkKv99hlEoI50qew2tRwwjbAeE4I206fDp5S6SLXMjHQrxaekXYswtlv4eEsFk9A1CiBXOgwLrGcNbiWpqjgbjPmEAiQCi5HXwlokSdG4ScXXaINdr2/9KGUOY7EMn5rD0U/HtfBYZRq0XS9uFUu+g4PGg4ESDQSNZh3yltBXvs9JWfNVn4h2G8J2V95YzEsHwb+sZ3VghkZ+z0v6c4ZpNSepIbWt98XhAW8spoblquKqUfSftL43m4/oagZySm0rFpTdtOYYCT59hhaFB73hTYoyaKiVvaGitkDQL51WdYEiqsWO4vsskNQSGPOkOojvFwmY9aX9K6NB3PhM/OrfPkFQb5yLti58a4TIyJx6lm2Nyg5kG7joXI5zO/Yjg+pvXbx4QAbZHvHcZVA/EEKaT+kngn/vjTfu9RLsT+AD4Y6lS8SnepiTiaNTauhoG0taMGCcQ+SNeHKeun7LjhIvyzDamOE1LX/vkxsozkpKuYSLNyvfS0D7ZiHSOruUq4ZtHDGlRmXTMcKdM46vSoPh5SJZLGhD2Z0d1p6UPb987Icsof0unjqsjeETkMqXeQelDvpv2OjqY+6O2yiXx96jUnxaYdeh0bOQDjdIFEkx5TFIg1TWnBWfVaFRP6zy6ZlV+2oeBReGpusciLpRvVY5XGTwr708YnlXVqZsy3OFQzyin5Ikp4Z2DjrvHRH86prhcJlf+V9ml/J4y3K2wjXpEg/CQIesL+wpZH/ml6qxz4szLV48LnAuE5+x7rL+ctwavukDDVrxq5LpjeUYyVMS/O6bi6DFZM/ux71OyNpXWp71+dRoWGOrwcRFmd3y0H6uN53y93fdpRf7XcRCXFQblm/bNUamrbNImOCVyZUoC6WaFSB+PSNAPshNknzV13N2b8VyUwfLSlKZe1NviWtmpjXDAcEf3hNCWxV3xA4Z2gHKv0pTyYZehHSytaFdUW+OEpFZXnXRGeG63PJsylGdLpV6V69KeRR05JXZMtbOnJM29liqnxnJXGMSxsk+9pH2/xzDTiQKHwQV1zzM8vbyv0/aRj3zkFvAf0UyIbwD/j2984xu//yMf+chV4I/RAkxbwK/9xje+8d9/5CMf+Qjw+4Hv7/P4jd/4xjfeeNoYv5gW2YHmkXqI8ZB8v8TIuYi+RQ5qr9FsG6McO/3368TRWaB5+6+Tb+Vs0KJOrxNiEA7rbxBv+XUiFFQQHjaUiNY7nJtEqK71tjL/Csmbdbfg1f57uyPUnbZDcu3xLXJw+hY5X2CURmfLtA2jF2e9byP0RwWmRbIzpeA96f24U+m8TDHT4Zt0WD5Jbhla62Pf6r9XadGIV2mRqKPe3h2cezRmeoGcV9N4o6/Ha7T12uljPk+LSDhvyFlA12pe1EZBK42cdNh1yrWhPRzt91F8J4O7g3aLCIvK7Me0tXmFFuXTSNsr9V5juOlyRHZ5VkiEaJFER73pa4fhxzvPyG6Deen2d5uLOxs6NK7rq71/o+67hDZvkJ0SaDsy7hKO+9tieNAdwl/W2yJRpRWyo62TrtMm7R2SM4OP+rifJNHMa8QZMbKoEyC/PiTf8tonhuuUoaNPwdlRx8Nqh+8KjRbnGRGerVrs4/AabbEMr+4RRjSv77x36DbThFzt+hztA0hfBH4C+DzwS/42+Jd+JX/7l34Xd34iWQAVtypNSPBGGnmhw3aH7G7fKXPY7GAZZHDuyyRKfUxSTpVn57Q1kJ6udvyp6NaJPDNgocN3jSjsNS7utL3K8CISje+Vjjr/f4FG38vE6Pw4cdY0HJSdr9Dk7E6f69UO3wLZfdcBeqn/VAX//6fu34M7vdL8PuzTQABCgND8qbsgtpvTYaeHHdLtYWZEz4Q71IzooWd3aierkq2sZPkiKypZTrySEyV2bMUll5XIlmRbchzJuniTlEouxRfVWrKklbZWu97N7E6tNDsj7lBketluEgKNbhgtFFC/bggQ2BDA/HHOh9/nffFDc+yqVDFvFQrA+57rc57785xzXiJ3Dh2Q+y8nJBLxau9D546GjsrBF8gBL9Lyy+SkwiWGJ7a+Snjj50pdMzbkXVsMo9tV9hl5NrXngND4Wp+XToybNHoyE0AaPSY8SufPAaHJd8nhReLeURmHMmqJRlP7HRZmZtwljrmx991Mggck2+QWiTorvz5DDkVRof8UiVCZEfDZPs8pWd/P9jbl1UZMp4T2rxDDbFLeKxO2yLpBlNRVmjy4SqLR++Tqg+0OC9dRJfBlIl9XSaRTHqfuIh+e6/28SpTCzxKj8hqR61cJrkw6zK7QcMHsGWEpT1FmPdvrSutToqheJZG4AxLBm9CijTvk7lizpk7Jfv1LnD1NcPysk+wC5ftLRMe739t7gdD3k54JMfghBnbl+Sfk3lIj7Ja9TMOBVZIV8BINj1cJ3l8h9/VZt0b06nzUNSBZZdVp4uP7zxMny4skq2BKW88bvW9pY4Pg1Apx3Im76r+bve7LvZ46uON8joixqwRnlSPimbrdHE0OqQes0kTeWGdz/+er5d20w+plkmFwt3//HLm64QsMo1s6Zh/0fj5T2p32b9eJDeBzsf+uPPt9EomvNoeRNg1xM+lqZoWP52WYmbdDixLf5MnP9xJp+wfAv/Lhhx++ceHChVXgb124cOGngP8V8F9/+OGHf/jChQu/l3Y/6L8O/GDv92Yfz58icn/m8/doG/BUpCcEebRoT4CfoAm0t8mGZ1MHVRhWgDdIPv675L4EjYa3aYu8RVNCH9PCy248h2w0nJCDSFZ7/YfkwkkVGyNtKqLbDA8i+XGG6UR7Zex6XVbIgSyPelk3hs7195dIisROL68nRoFYvZkaUVtkI/NbRIF9lyicR/2b9VeIIqiwnCMei5UOk8dE6TJl4T4RIlOClB5EIoJ7CtY7HS63GTKkaYfVWySsvUlbt+px2iJ3sUj4tZ1jGl44L72Xy7Q1XyfK/zJhZPR5bJZ5WH6Nhg+1rn3p7btDNoPvkzRMeh8f0NblLu1Miku9nXvkoIgFhsrQd4gSUSNTBneO+hh+hpzO57x89ETqOZsQHBOOMusN2nreId7IsUfKlM07DC8af5/hwTp630znEEfHkTYF3AHDVLZVklqxQVL4Fgj+vEkMBJV28UqBqDfsiBwuQ2/vGdq6aPBpV91ltuDfoq3xfB/Tn/w9iYSv935e/+ttTpuEvq6Q6OAWoZUJ8MqP5hySL/1FuMrf5tP8bV76J+HP/kVaGuUekTCn8Po6vLcH/zKxC/W87pFDWnZIypjPgz6uuodxhyHeHNHGJI+utKfSttrhJGx3yOEHeuqnxNB4mzgVxDmVBp0l9n9KDgq4S8M14VaF/Vyf6xHDg0ju0wSwOK8Br+J1p7f/k72PN8nhLdLcPA3X79No8jHhq8u9v2OSTrlFlBR59AFx+EEOLHEebxKaf1TK7Pd5PSh1H5JrXzQ0dTAp+6DxgSmRq7fJQSTvE4eh3zT+jomx4EEtyq3T0p7GtPSiMgXDSJuK00Lv9w5x3EAO15JnTUo7yk3lwAa5K2mLRAvu9zZvEzrYIIbtHjn44Q5NLoi/K72f7xDZZyRps49jQvjIRUIHKpi2pwMB4nzbIScpajjLE6c03BMHjvucfrqP6z3i0NMpLHwPCtwg+O2hEQf9W3X4TYli/S6JJLjGOhzkWSdEv9gkhxyJz/5Wd3qaOLiVCxfJfbu3CzzkUyrw6geznGQ+Kr1HDCNFuzS+ssswAvtxRts9hvqHDr2x0ebBKZeJLD/sY3mHtlbKt02SJqhMW+3vpGENd3FFw/ig93O3fJPOx3Nx+4o4IW98hzjaNJTlUfJn9bil/v52aUd5u9vb36TBdkrwQryqenh1ij0gB9cISyNtt8n+3QPO6mzfpeFMxfU3STRYHH2zfxf/psyOmt0muor+VOvd7fB5Z1TnHo32TsmaKdeE3y5ZW/m/OoG69irD59t9LH+twEK+9aTnY422Dz/88L8D/rv+9/6FCxd+meZs+A3AP9aL/Vng/00z2n4D8J98+OGHHwJ/88KFC5MLFy78Q72dc5/58vdc+X9u9G3W3/PlZ27G/+N+5maUr+2M/x6Pa27UxpPGMGuOs8ZW/x/Pf/y9jqG2MVZ87edk1Pa4z3Ff4/HW9udL++PxjOc8htN4Dh/3/3he43WbtXaz1oY+ZmExnuPc6Ke2yejvCqtZOABRys+b//w57ZyHl7PmXt/X9fb3eWOAIT5UGHwvOFv/nrXW42c8j3G7tczJ6Pt5tH8eHY3Xbha++O2Ys+3VNmbhwZPmUmntNnFsqEipACvoICeN6VmvRtsSjenfI0raN4Hf/Rfh+hT4W72zP0C0qQl8+hswfzx7nE+ay3n0BGdhOotGx+Vm1R33M4s/fy88Zbym5/G2cbvz5/wej3nczhjfZ9Wt5U+ZjStjunwSvGqZk9H/58mHWWs7Htt5sJw1Dvs+j+fO4su1rv9XeJyOvs9a4zHMz1vLWbQ9XpNZczuvrH+fJw9m9f+kcY3b/F7meN66nidrniSHzlv7WTzSdk5mvK/jORm1McaB82jxPDyrczgdvZsFY0ZlZq3RGF6z4H9ee9avv2c9s9ocw8ByH4cPs3jheXR9Hk4+aa3HsBjT4RgHZs1z3K7/j+XoLJyehRuz5jVu/5Rh274b1xnT/yxchyFuP4lmzqPrWXx1Fnzld7X+eCz1mQWrJz3/vfa0Xbhw4Totgvct4JliiG0Tx+2zDE+tvNffDYy2Cxcu/Iu0g675VSS94mXOT4/8AZI7+hzNoncDZU2P1Hv6Q32gd2jAuELb42/0aa0P7GvECn6JFvr+rS/AW3da/qfH1f56kh6pF+4SZ9Mjv06OFN7u/f0g8QZ/h+YN1Bs5Ab7Sf09pm4i/0svukxSYa2RD9XVi/S/1+ekNq+mRP9DL3CXpkYZsv9Ths97LfUBDGD3dXyUpix73vEA8NBOat+krJH3jzd72tT6GDZJOtE4OIlnjbHrkGwz3tpzQ1tWw+pPSI13j+RnwhqR0dN32Iw/dVzuMLzJMj5yQtIRTmgK9TVPIX2KYHvltZqdHvkxLUVgi6WN6Y75GIsrf6uN+naQeGTGaZ5ge+Wyvo7fUiITpkRskPfJ1Pj498j2G6ZF3yP4sU6eu0dbvEo2YX+H89MhjzqZHfqWU2yBZg0ZyJyT3W6b8AwzTI++S9Mgf6PAxGqr38Tka7Zg69DUaPW3R1kuPmF7hKYmaq0wLswMSnb7Ex6dHHpBrFb5GPLLSz9dIFEM6vUnw5i7xTl6l8a7VXv6rJBJx/VL/59+gMZr/2y8D/2v4mz/XXPJH8Mo3E01cp63rTZIeuW5bhH6kzVXC4zb7nH6wlzmk4cUBoa9TcgWFXtZrZJ/fZu/nS8xOjxRnjbYukujS6yT1DRItX6KtxaT3/SLDQ4nmSXqkkZV9kh75GRJxmPb2v048+99PeNALNHqvXtnP0ejhW0QWTcrPUR+7nm6Fco1ivkpSAo3Uvkxk0zK5pPyEHIL1XbKFABqOfZfZ6ZGXaBEUZd+XiFxd5Pz0yAUavlwjkba1Pt8lcugRJD3yqyRK5T1vlnlM+Il82GjSHI0/KC/u9rnoRZ8lN5UDNT3yLmfTI82iOOZseuQ88Bo5XEh++KXe5nGfj9tJp8RzfoVheqSKmzLBDKFq4MxxNj2yRk+3aHTxVYZ7JB8T+fptwvOMxH2dRK+FG2Qr7DzJzt4hl8uvMEyP/BYtWvO4z0+4LpCIpbqFmUnP9v53abj5iPDTKzR6+0KHk9lBE5IeuUvSIzdJSuEa33t65B2yP3qPRkNf6vMTVz5Lo+mxQTJ+5M3qFXv9fR3DCeenR1Ydy+jVSzT6rFc0XOnlrpa63yZ8Ypwe+Vz5ZhbLWA69SVvbr5VyN3t90yM3SPqf+LXB2fRI9QqYnR65xPnpkRv9/ctk28B6n+uXCY+fI4cOqRO9xtl72tSxf4gcMGYbLxMd2rX6ArnW5mucTY+ckMjfFxmmR66S9NGKK2/3b9/PMD3yNo12VhlexXVE9hara89KjzzqY/kayXJ4rff/Rzn/+Z6NtgsXLvxK4L8Efs+HH374qG1da8+HH3744YULFz78XtvqdX4U+FGAZy9c+NA0C8P4BwyPKjX8LSMT6TQ0rAfZQLtP0jfmyBHOBzTi/KC8k7kfAn8D+HN3cmKf6R+Ws93jUm+hlFMwSnyORcXwgJzwd1LmMl/G5Fz2SznhoWIjbCBG22l5x2he+8QomyNpQzW94aC0c1D6FY4ybsfvWFVyxmVrmcPS5lJ5d1zWxXoqYI7tsLTrXB6PypnuM4Y3ozHVebpWwuSEHPriGlTYH5W/rXvI8HEehwzXSVyw7hxZ76PSnuOyfO1/vO4aOnVtKm4+Intk5kudSl+WqzRjv7PWz7HX9sbzlOlVXD4pbZieAaFvGB7/e1r6td2nZryD8IdKy5UOdRY4vzFOiSu1jbqOwmaW0VZpRrpyDrbvusq/7KvCxfGIHxXfPuq3DupngIN/GH7Lr4bv+4/g5HfDO3D0zYzJvsbtumauoWN1XEfkoIX90fs6n7qmB+RclYpbB6W867LE8MoMFdtT4nQS3s5d+LmOgkKesjBagwr/+jOLn1T8fUSMGuWDPM8lmI7Wy/FX+AiD6oSqYx7jiTjvOti/a1Dx0rq+my91XecPRm259nXup+XdGKb+vcgQH8WLE4bztR9lYF03jTZx5pghKo9xTPk8lpvjdXPuFQdrW8JPuXnCcN2Ekz8VTrWNSh9Vxrm+lPaqrIHgxsJojGMdp9KV/8vXFstcKw2P5YW0dDB655g/KHOrcqzqWY5rgaEsdd0qLY157Bg2fvuAIW6MZanzWeh/LzFc+1lPxVd1QmlzDNfK63xORu/qGqsnzZf/GcFnf1S34uMBw7Wq+DCuX2UuBHYVPjCkp7EcqjqEeqTwV7ca43Idb+U9Y3k4z9n1PG+M0mzVjSquSAdVV4Tw7JptM8Yj8e+QHL4jXCptSstjeV1pf8x3hIn8vuLFGHa1fP2/vn9U4CjOLzF8xjQ0HtN5z/dktF24cGGBZrD9vz788MO/0F8/MO3xwoUL/xDwd/v7+8RxBs3Jdf9J7R/RrPJNhidCHZI9TSckV/z9/v0iyefXE7pEs+yXaZ65d8ihHw97nbtkH8YB7cLadxhenutx+g/JhvLv9DrTMoZZe9re6G29T/ZvvEE8j3dJTuwcSYlyv5Z7xITNJmH4eySCt13mP8/sPW1v9HdbDPecqDQ57zd6X++XdvRq75McdhWrXeJZM7o2T/NybPSx0uuoUGwT5jUhF36bSmYu/ThEvNi/7ZJIa43I0dvZIJ6bCm/I3hOIl/Gkj/2gt/8UORShei1PyCEbW0SAbpO9BEsMN97v9LFMyaWnMpElmvdtpc9DfHyrt7nY+zPPfYHkhq8VWIj3eqAWCe0clfbsV5xS2E+J1/kS8ajdY2j8ytDvEBpzf4KP0RnpSljsl35heMGnsNgjRp5GmxH0gz4e5zGlrZk5/M7NserxPCEX2OoJlnmqeEj/m6Xft/r4pLX75HJPBeL42SQ8ZqmP76TXlwdIh5W+VE6WyJ4mI4GVd71BYH30Abz4Vxt+Pg38qqvAv/J3Ye53ww8Dq/BvL8Bbxw3Hrvd612hewis0r/oO8U7S56mX+YBcvC4PocNsvf+u9LVJTuXaIbh+QPBRhfm4z3GR8KJtwsNUEE76/FbL3E/IVQ/7JDoJ4cE+yo/1Ph6Vxr0yBiMdex3eyqC3iSdYR8h7BV7ywHd6P1Oy7/EOidLsEZ6kd1jFYImG15ArVcyaWCc0r7KifFnv/1t3SvbULRA6hOYJVvBKkyotG0RRfMSQb7jGO4TPXiT4ODZUjmg4r/y6SA7ogjjX5okTYbHDdJPs46aPd53Q9Sy5WdfuiIYjm2X8xyR6fUSMXqORu+RS7V2SwrxL9kBuEFkwpa3Z+30c7hGyb3nCAYksVAXU9V8iWQn3iDNAnrhHLg5Wv1BGVbk9IVk2Zqcoh6bEQbBY3lU5Lv5NiYL4Dtlf/pBEveZJBoVy5pi2Xh8QnUzF9lFv55CcSnxEIqirJMPhHjE43R/nvj91nCrDx8/9Ph+jf/JT5y1MV8h1FU96NhjqgMKm6hk6E+Z7WWXbI3IWwRItwr1M6GmbOKvF3Xul7rv9bx0/x+RETa8eUL7U8fi8R8MZo9fivnitvrLf29PIrXtQqz6iPFQ27xC9612GTqv9DhPXbkrOAdgl+CCPlheovy72uisMDZvHJBL4nfJO/kiBx/vl/+0+7u8y1FGUH2aF3GFIu/KBhwyfjf7zJsPLtTf7fNQn1YnERSOJ8mPr+qz3sbxBMlveYiiXZz3fy+mRF2jXBvzyhx9++B+UT38Z+G3AH+6//1J5/7svXLjwn9OzOj5uP1sN0amEnpa/628Z4Wn52+/HRDk4HbVlucejtsbvLAuz+xv/jMcx6/us8fozN6PtWvZxqTOr3Hh+dcxzo3IqTbP6Og/Gp6P6jL6P+3zSmMbjnjUnYTILVuOyVUk7HtWp4/U7zF6HMa6M5zQLD40anFd+/DOGTV2H2rZe6fE6WqZGpGbh16xxHDMbpmNcoPyuz/eC9+fB7kn0sTAqy4x64zHO+qkG3+PR+OrfwuBxKTeey/E531zvWU9dh7pGY7gez3hn+fPocUx7f54Isgnwwlbw5d3/sKWO/s4fg5cu9jt1/m1yWdoV4BJc+xM5uEGhdR4fmOcs7p9Ht2McGP9/fE7dyi+EC5ydey17zGz4+NS+at0njb/iwEIpV+XD/Ojdk/jYY4bjmgWXOtYxTp+HB+fVnWP2Gtj3mOecxzvGfP+Ys+OeK+3W9a1jHEfP69+z8GP8vfK9OtfxeGeN70nrct66wVlYz+IR9RnPbQzjyndnja3SvnOcn1Fn1hzGc/c5r+z3Cgf/rzLze4Hr90JjFUdq2zDs9zy6rs95tD0Lt2a1Iz2P4TY34/ssOp6FN7N00HG582iYUVtwduznweO89fhe1qHCqvK62t+T2n8SzJ+0Bufh0xgO58ly+XQd56w2a3+zfsbfqlwctzkuX2m+/h7ro7Pm/yT8eNLzvUTafi3wW4G3Lly48N3+7t+gGWt//sKFC7+DZlT+5v7tr9FSnd+lGZy//eM6OCbW8Qqx6PVi6rXy9MfdXm+fnHC2SDxIO8QreZ+crHdEU3S2iTfptLfru+3e9i7xRhhdWCeehT2G6QjzJPy/TnLk9RhuEEQw6rVH0gFqlBGSK23/C32sRvccwy7xYFRGDvFAnBBP6jI58nSlwMcIwE6pv0E8dHqtJBa9nEbnPMVni7P3WehF3yUIPSWeece8VWDiY4ToAQnzn3J2Y6jjMzK1PmrnmKE3T2+TefyusZ4T90PQx2de+G6vf0K8rTtkX6N97ZLTmMSDGmnbJJ4tca9GjvS+Oh899PsMo2eVoSyQSMJxae+w9OvjeBznlHi/dgt8bcu1nZK8+pVRe7vkziz70mPrY5mHZVymYAhrCO4JXz194pv8wiPJHavewxOyT8vo2hxJTzwu7clPTmn0IF6L90YpxkLeZ6fAbIl4/aZl3NLhFkNmLt7ooZyWsbsWGwTW9xmeiFbX9D4ta4DfS9vMcBP4l/oE/hgfEZ4R7qPRHMQhU0Gkpw2iYMofNgosthmmztST3Ka9zArB1SlDuq48zEib86l4dtLfLRK62WWYQlkfcceIxgnh11OCq66P/EcPqvTnHKvnfYFEJx+Xcbq+qwzvh6qRpg9IdBJyxYL44x5mcfSE8KMHff7WNUqhx3lK5JA8ZI5kb1SZpnJyTNK5XGMIr3V/z/0O70oHRgU2SaR/meG9U+L7/OjvLRL1ErZPkpvbhEYOiJxSbh6N3nkiqvJFvmUbW5zlz66f0d+LJAVVuByR6M5+Gd8p4RnKDh8jbdKXczhieIfaJuHjRtqUFVtEHm/3/jb67wMiI+dpayF97RP8kc4X+/vHBJf3GNKI8lCYVP1CPFAnk46cj7x4ieCU/Ep8k++6Hw2SUVTl5XmPuCKcDklUTVxRp1vl4yNtypQaRYbhGFSwXQf5r1kF8oLt8k08h0Tb5YPWVe+U/wkjeZ3fXJPxXNS73ie8C4a62i4xMuRb6mfShnzV57C395DQvbzQdsyqWiT3fdZy4tUKw0M5doluq9wcw3qHZEI5H/nyYoGH+HOPXEGxwVBHEU6OSXqC6A3VWVHr7Pbx2c8u4bvylCWGuO84l/pY9xg+yvz3SfbAJkO5POv5Xk6P/CZw4ZzP//iM8h8Cv+vj2q3PAm2T6gdkE6oMQAQ9IQeUbPUyqyQtbK3/PEWMiGuEAObJJlwBtNrbuUqMqMt9TMc0A+/pPi7bM+w/JchuuFrku0by7H1fN2+L1Efk8IIr5BjjSyS/9IBsCL5ENlOvEcGsUaSXpBptV4nXxj4k1GtEMF9lKMyhbbh1DxGEaP1tWN0NuVUBWCt11npfGh+n5C40jU3732aYErHWv6l8rJR3NU1grpRZouXkjtMjZUZudq39yoBNBXJNnMNpGf8aHwUtPsodty4E/lfIhnOVNnHkWXLJ5aNe5io52AbCMBfJfVVrNByBYXqk+ABRKK709wq/qvzuE6HhXKpTAXJIjuu3Tw41WCHG2Elva47coSQzlOYsp4NFI3mBGPyWocBHwXlKUuquEiE9IXnyrouGhWOe9vcLnE2P1ECzX2GmwaGwkf5nCf45kh75VC+nYDctRDpU0NmXTJ/S9uXexrSP41mGTpwjkoJWYStuskZDqF+g5V7cAt5ahP/6Mfz5pEmulT7Fbcc8JTh/tZf5gChJ8jPhJo6tEpxT+Ig/8ifXe5Uof/IwnWunzMYzx3iV7BsQ9ytv+lSZh4rghOCP5Q86LK+S/TBXSVrLM/3/rQKrK0S22L84MiW4t0KMnmq0HZJDUSB84CoxQOT3Gm3KvqNR3SlxxslfVglvF9cudZjUNFHl0ISGS/LCPSJPla+rRJm+TBxGwkBcniNpcHXO9W8I7uwSXISkgT5JbtJhe4nINOWpuOlaSNuukTxnjxyWoZE8T2TLJsGzVYb7qzyu/4ihMfBMr68BW41b5ZL6zWWGe5n8cb72f9LHKfylB/mifMW1UQZIc+LSFWKkXS5wUNdQ8T4l156sEGdxjcDIP9Wd9hnu+zkmB1WJU15FsdzfPSSHDF0izxLBnzWenB5ZcfCY6IHqeM5HfvpxRhsEF2CY1uxz0sfrgXDKVHH2Ck0GTAn+HJW6S71epeF9IusrHivTPPyiGm1juLgm8q6HhE9pSEEOM9N5pB6nzqPcU2f0iHtpw/bUSY4JXjumqr+Kw5f72Cov1MhRJ5L/+Twmer4yVUNuoZSfK+OssKpyE6KniDfeewuhH+HDqN4BuU8QQhfqyEsMr8DSQaLOWuv6bPbfyqMH5/Q/fv57nR75/6tnhXYSzHL/fYUA8QFN2T6mnci1SwOIp0EpLG+RRdrvv79K9kXM0wDyOiFKEelrxBN8q397lzDhldJe3euh0rhAvOWWWydRrWVyIhk0RNwiBt+EdmrMKg2prvf/6XAwz/pah43KmtGxsdEmgS71+Z7Q8nWvk9OuVmkn5zzdx/o6YdwqTV8hJ+55euRi7+cBYbqvEaX/LaLgQk6PfLn/bRRVxXG9//8C2VdXjTEv14bc/XKddkLYUil3lyhIK30+lQHI2DUYt/q710iEdplcEGk/dPjdZngp4w0avolreqrs6/0+5+eJAqgXeqX3+zQR/JAT5ZZ6fyojS4SYFZL3S3/H5PRI90Ic0E7RukaM9Kr87pF7W17u7c+T07gUDDI26XOLdhLShCET2iZeogkRZlcJLkP2DeiRXGJovGsEfKWP19PI1snez9c7fFTcVECu09ZFWpBe75PLtWuUSo+cSjMdZteJN/tuH98qDRdnCf67RGgv97GfEk/ebh/zMVGET2m4If96l+HpkV8lhrYny0LDmeU+pjWGF2B+m86/XuovTjrg7gL/6mP494F//Of5kf/0y0z+3nDjsVkEy+Qem40+/q/3MvKHRwz52R3iNZ3QcHGPZBA8Ry4BlncskdMaa6ReA+uUthaTMncVpiVy8ubd/rfCm97OLbImrrPOiZfIyXLTDktPc4WGrwp2T4/UwwuN/r9AlHdPj1wlJ7B9pbdfT7XVMH5IO7nsSm9vi1z6LY2qxOid9RLjt3v/1hXmq8SJt0Yufb1LZN+rZN8RJNJdLx3X0Xijz+uIKGjuU1PJgCjsr9PWcJ04eqoTSxhUh+JbtHV+jTgG1gmdLjFbbm73uT1LW+fVXk+d4RaRc/L9a2Tf+HZv79U+z1PiOf8i7YRHHbWeHrlHFEOdEofkAmphJn82ukD5Lg+5Sk6g3Kfh//3e/5d7v0b3jomsmBBH89P92/eTiJ8G/zy5UFol19MjVYCXyemR4vI94oT4DNFt3ibZCf6In18he7T2yd2UGuKvEKemjscbRP4819u5RyLKa8TQcu1nPbK2mjHxcp/3Asko+Fwf58cZbbeJYQzJnqj6iM6VzxJjGrK39NPEablK4x1vkoiosvwGoWEDCNLIAbkn9EVywqnyxeyM+rxFW8PXyphv0vBgm+DZc+RybfUUcWqV6F8abWu973u97svEOavjapfQ4bvkcu13ern1XvaLDDMqNojBtkxbt6qzHXfYXKLJQ9/pTHyZ6Pby5i+Quyyr3IQ4YNVVvkDkp/Rzg7OXW6trvEacSxs03i6fvU8zfC8Rh/AxcaK9XOr6qGN8lUSsv9zH8O9x/vOJMNqMghiy1HOktSoD3KAJvF2adStiH5R6MqNDsngyMsht6QrDOZJGuUdS6HaJIqmi56ECMnGZqkQ9JRtPN0na1BFBUEgoWy/DcS+/SiIQG73sYSmnIrHfx7VZvs0zzKeFpJeoQDrGCh/HskEibRp9KlPTAjMV4inxfGwSRd/2nOsOiYwqFB4TprFJIjCmJ1Um+YCkw+0y9PxWRa2mIBz2Ol58CYkSaNQajdkkeLZMlJD9Ulf47ZCUJ9MWDsm1DvWizV2S6iLspgSvNwm+VNw/ZnjZsgzYcTwmuKMXS7w3PcFT4+4RhaQabaZm7DA0tuZICpT9ymAvEVoyxWBa2tvt7x/2//UczhFcFo7OV6PtmLORtk1y5P82SWE6JjS8wzB6Zxs6eaRX4bhUYK7yfED4y2mBmTiyQxQ4aXD8SIcqiTUleZekPRyXsel11di/T3BcmPm/84C2BqZgCAthq4D88R8Nrhg1vf7X4dofhef5Mr/1Hvwzz/46+Cs/91G+6pdFAq02tdgF2rnrnSlv/QH4ccLPTgnvFLbymQPCCzbKmKVx11YeLt1rHN7rQ3Hu1RBeJDggL5AHzpNDbKRZDbjHJEXeb8fkEKQ94pyy7RWylq7BBnH86NleJYctybO2GXrsFeiC2/a2aTSmUqHyMiWyb9q/PV3qSsP7NL5hSuAGQzkHUQzkd44dklkizORl8ttHhMdWWaTCvNHHriw4KPM+Hv0N4ffySSNwyk0PDtpgKDddN8e+zPAgkoP+/14pZ/865+SfmyRDY5dcGGwZs3amhI/AUD9RyXVOGvemk1HmftTHdsKQ/zgnYaHRapRVWbFNtgiYAr5BUuCcF72fDcLDNglZ6wxyPhsFtq6P5ZUJKssab1PicJkyPKnwIaFFcc61kA6nRC5BeLkONHWrKsPHj2O27H5/t1Fgutf/Nm3wSY/yS9klT6/6yGOCu8cka+ch0Qt01u/TFHlluUabMuuo1K184ogmc6YkQKAcXmK2HLKPTWLELJPDQfZLWwtER7hPeKUOJ3UjiMNFetggKe3OYQr8H/4z4Lf8z+H7f7FVeAm+vF4G9QzNcilW25e34Lf+TT7aB/EX/s4wNVNZUeWcB/fIGy4yTI/cInpKlZt0+Fe8EFdguNXqSbCtssl32hxee/EBOdxJJ2St6+M4dNpUnvSk5xNhtOm926dZ5P6tIQCNWG7SJvYO8Zo+oiHbNXJPm6ct3aQB0nau9Hf3aMBZo3nr9EZsEo/fAcP0MtvbJcJZT5uej4VSbp4g0kp/V72TpoEsEO/0pPf5LLH294nX8lniFdULpWdSgXjC8J62m+X9jd6HCrHwPO5/a+wc9fJGAiRiDVQJetLHcoNESzQyn+1ljol3Z5GkT6wVWJ/27wdkL5pM8mr/tlH6/BRnveuQ/Q+rfezVa3NETo9cLe9uEIJV+TN187kyPoXztI/pOZJ+t8vZe9pOyrw3COO1nGtxRBiIXkcNmSlJuXPtr5HTCZ3fMUlPMu3hoLd3vfcz6562lTLOZ4mT4jYRVld6nzeJkL/O2XvaJr2OnnZhUXFZD9kCUU6WSJRWwwlyr9o+w7S4p/s34XOZCLIKb3HatTHStkvSeFYJnxGnhdkBSRe5RBMOlYbrc0pOonJtIbQzX8Ys/kuPGtMnpT1xXuP4eQJrjZhLNBqqsHUucNaBI87egLYj+Tf/HPz6Pw38Vfh7fwX+IvE+TPtEXLCbfKShyxOFheu1QtbyOtm/+ipJdXI8Ct3LxJhdIYbNAcFLvfPOcdr78a6nQ5KiUlPSnme4R2iJ8M4bhMc4ZnFlm9z1t97ncpPGO+Q10oNK93VyMIxGm/xJ40K8PyR3cZrKo9Ikzr9H0tfFDXn1/qjuRSKfNFzXSnkV0CsFJjqNNJRd0xtEwbje4e+e0UvEEHqm9yXOOXb56iUSEYVE66qMWiJ7+4xQ+eyQE+VulHbqKXqrvY58FGI4OJb7RKGv97QtEX7r2krX1/s7vevyvSlJSbzC8J426yoT3mKYOqwyvkr0m6sMT2/0cb5vkf23z/WxTxmmH8vj5IXymjmCo+v93XVy4vNVkvoor1FXOerz+zSJIh4TncC/p0Sf2iVOPI2eqwxxapuz97SpA1Q9wEjbJT7+njadZAdEPjtvT2Y8KXP8OGX4mIYLyq55hk5T21MmXmV4TxsE97bIvV+PGO6FE77PlLq7JL1wPB/licb2LMOi4v48Dfev93lfJMZLjbTJG8QpjbZNgrtrRBcTthrAV4lc5t8DvvmL/MGfbv+//NdH97S9D1/+xfDdud7ON4gM/ArDVNkjggs3y7v3Oqw+TTIM1soYT3r7N0btabSJ0+qREPq5Xt75GBy6TtZskUabrvcKiVjqkFknAYYbnI20vd1/K4/ukPV50vOJMNpOCPOfkojHYXmv1S2D0OCRkVpPjwsMoxvzRDnXGj4s76bkbgfKt6Vef45446ZE8Zsjnv6DUb/OwXcSmoakQnOeRCj0VskEarl9wlCWexlhozGlJwyy0VT47vU+7KuO07b2iQdoj3h8nLOC95AYq45VD9oBwxSch2Tt9HyqSOmR7A7/AUycv2tu6o4ew6VS7mH57tjHRlsVkPsFPgdk7R6XMjLkE4brqYBa6fPcZ7iXUIY4ZYivhyQFcJcYI49KeQ0Z+5sr//tNnDgp7SnE9f4qWHdLXRVs52MfDwkspwz30jn2PeJJmjI0sJyPc6wCpeLyGI4KMtfb/3V46LFyTOLGw9KOBq7v9Srq8Xae4otR8wOGdOjaWVbnw34fj/Qyy2ibEh5DmW8d9x5JY1Jx1aB8XMYifu2V+tJtbVP6UVETtuKx+Oj4xdkdG/klYO9/03Iz/qEfhN/wE03K/GQBmgCXiRxmjMKirqn4Ki0v0FJK9kkatFF6I6OVLuRh0um0zIXyTVkg7T1iyAtgmLIlfe+TDeG+F5a75d20z0Pcq7jtuKpskZalQ73VwkUlpUba9FTXse6V7yri01Jmd0Zd+4Dh3UR1fJArCISDc9eRJAwqf1tlGEmalu/HDCNO0zJmH+sdE+W3Gm22V3m1MuCA4UEJda7O13GecpbWxBX5jOsgfF3niieHo3enDGW+/cqDNchd34fEAJc/U8rUMVceX9djj+zllS89LHVPCd2cMOQrtiOs5Nljg8p2Km93LK6hOK1MOGIYaTuk0ccuwavKT8VDZb7wp4yr4przqfJAR9B5j/U0cuy38gb72GXIH85rz3WbJ/RRef4p4QvKHutOibPK+VS9RpqxnO1K1+KRMrziqM4KHSBjOSQsLLtf6lYdZI+zMlCcMvrm2CF8VT1B2hCuH+lVHQD7vZ29vBqsQQm0DeANs3W2sQgStou9vpkAlTc7190RjKqdUXGFUmfKMDOvtjlluGbqodKMuqMwcR2d2xj/HIs8xvXY48nPJ8poc3FFct/JeAWUDG2eLLr19GZDgCFBqLQJrAVi/FRmA/G0LzE0vKZlfBoJCwwvrayL4PjGgtZ5yaCm5OLGinC13COa9/GUOMRVXFXcqnddpimj0GurQVUVFZmrDND5Ggmy3DzDiywXiKCeY0g0MFR8PK3tcYHblAgf4TI22mr/c+VdjbTZ71xpb5weeUAUQJmofcqoFksd10D4VRzR0KlCULgdlTKVyemthDDLqkQ8JB5mcWyeRCKMKNmeBpsCWNyX+apEaLDIVKoyUpmR61f7NT22Kq4qRSelvSkR7gsFzssjOGpwVaOzKjWVgWv8VqVqfjQWlQOZ+GqBheV8r6JU29VgdixV8aqwGNNwfaZlbP4/NlCrMBdPpAcN94pflTYVWLYtHWiAGCGtSpsKlopHxcePFmuVdocAP9E2aTwD/Otz8FdP4c8wtGi6hi5PExZ17aW/usa/h+aR/TzD9EiFs+leKkoLZQ7SiHOXXuXjVU58wHBPm4rk4ehHnuN4H5H0GmWLysVYiXdc+8Qok86qkXzEWdlTjTbbHRteU4aGqUrwCbPpFYInGr1VWRb3HHOFieOcL3WqXJsSh0LlxX6X/uVr1cHnU402lV8VVw9rkM7k1c7Rtap8XD4wlgPCqiq6Y6NNw6caiypd6hPV0WW9qnwelDaEAwyVUA0660PW3/k9xRDeztm/nYeRtinRcU7K3MWLY4ZrI6x2CX3VPsQXcakq9TrApmSPuPCsRpt4XOV25afiVOXj4lF1KOwTJ708WPm/xJPTIzXOxEfxVsed61qV8xptOx39L/1XHUGe5NjlqdP+/nGpO6Wx1Gq0ScPC3PlZ33lUPnFY2nCNIOmIC5yVQ1OyzvNljJVv1PVWR5gSPNWhvl/eaWTNckLLQw5I486j9vuI6NnCsuqK8pJZOluV+ZXHyuPkLdVZ4do/ZPhUR0WlfxjCR5lK+aZc8L0ObG0O8dxxK88rjx9Heus4pgxh/KTnE2O0TQnQ5hky4EckpasquFVZ1ZJ1S8YxOaZdRFogeaQig95qCXbaxyQw54lSsU0WrwpxBZLIbh+VCdRTiaaEyHy3w/Aof/fWCQfHqjKtoiGBz5MDDmQkiySXekrSdSp8HOdO+Wb9nV5H5BSOMi5KORUAy1Xv4JTkQcsYfFRINUIrTIRV9VprsO4wZKbihgrszqgdFT6VQPFmh6H3eIEYv9aX+U4ZRsQqM/soTYChN12jR6agorvDMIJ8SNIPZUimA42ZdBWweidXGUZKDekr4BfImjl/hcUOwwiX5RbKj+s3Jesok4J4XPcLvCl1aznheFLKuW4KC+mhRrwelW++UxleYBildG2dZzV4HbtMswop8UZjSVo54vxjo+tY3HN4Ut4L41PiGRcWGv61rDB7WOoK6ynhUfMEZ2yvrnG3sz6qt9x/PtpAU5Hqjf7/q6ftFIL/FPidtDytwoymfUyVn6mEuT5Vca3073orvKthUqMxjtl5O3flxCJDp5VRvSoUJ5xVVqXPGoHdH70TX1TC90bf6KDz3QeEr2q8iAOWmWe4p6vig+1NCb5OGeKr8uNRKWdd53FcykN4u/0r+zROpAO/Ub5PyR5ZPdmu234Z22lpTz6qEVX5p/JK2QVR6IWFT6V15dfYQHWOiyQaKE9y73Lly8dkL1F13Ep/U4YKlOu2xHDtlWnqBF4j4dquECNYnaU6EnSWVSeLMtd56TCYFjhKByqGynN1DZ11jhNCc7a9V76LrzqBxRXpcI7s5VXPUNaoX8inqk52yJDW5E/VONAB6VgeMdSdxGudebOcZD7yZ9dYGFT5IB5s8/GRtl2GWRfnRdqmxAisRvKUXFk17ePaZuhYOeptmn1e68on5CVjXUMdsOo9Pg8J7sq7VonTtra1wjDNVTyrmWrKqGpguVdvSnBKXDCEN+Y/4p+0NE9LE/zdL8D2Hfhphng+S2c7ISLI8YlbOncq3ju+Kjd9qgNuWtr1f+FTH9dvjyHPtg8d0+KhuKhO4NyOGT5TGv5vE4dadWie93wijLYjsnFbRiBSidDQ8swPyQbwJbJpuy76JsmTtV0ReYFsVNULtUTLk90uY6oC1HbfJouxSRiuBHVAY7hvk02KMre3CEJuEgIz/a3m2h+Vskf9nd6EXYb3G21yNr1M5Xehw0wjYa/X3SCI8X7/5mlUm6Wd20SJsn412uq4V/oYN/t4VbxkblXoaGRMGCqz98m9Rj7O5R4hqoMCa8vu9Poy+lXOMoD3+98Kaud4RHBmnpzwqDJxSu59kcinhCm4BlVJcd4Pe78yChmvkZ/Hvf42ba+mNPCAbEpdJPiyRVu/agBC9p7ofTruc7tc+jW1VmVLRnRCNvQ+IPimAqIwXyfCZWnUnoa9dGXEUqFsOZmd89TYUghpPK0Q5UIFWHp7uo/zPqFp6Xunj1Pj3nmqDCmUZay2Lxzf6f8rjHYYpqWOvWWQgyQg+1HoY93s/UiH90tfChx5XnUMvEXjSQ/ISaIwvFNS41DYbnL28nXxUAG4By15fsJQWxYIt8kC/2u0JP0/xEcapvuB5WfVAbFPnBTC1miCY6oKn7xo7IFV0MpXKp5Ja1OyKV7FuSoyRoCEv17bZZKOOu1lVsgJb9sFBJtESXifGKV6fN8nkRBx5L3+XcVb2VONFhW3SW9vSg4QWSL3FVV+eVLmc1TqKotU5h6SjAp5u31AFAvnViNWKovCTN4g73ifxhtUZmt7t4liJv+sNF2NVvpYt/qPfA+eLDflo8J72scprz4i2SpLJCVXJ9UKUfC2aSfd7ZG1PexjmRI80zF3wJD3V2NQWNiu46+PJKVBPyE4Kk982OG4SA66OO5jWiLrvELuTrtIMl/eJ7QmX9ggSu4BcTwLB51S7zPMypEu5gnPEg/VtQ7I3ruj8qPutEoic+8zvCdPeB4zjHhoiC8TGXHeU+WCMk2c2yA0vsBQVzjvUfbZp479sT5y0H8/TfQona4q3etEfm0Sh7G8a8pwL+Zm/3uOOAM0nqb9m7rNrLlskpPK52nw1lDbH/09Jbil40J5+5jciQZDB5Y8fZ0Y3PKzjVO4fjc88Yg4mqoj2Dm8d2eoa8i/xjrbFtGXxEH31OmEkVfXMT9iKDfp9d8jeL/EMMq4TrJRKnzlU8sM9zBuk8NlpkQnEibqb/azyvCRT9zu7ckL//8i0varaEcuv0M7nvUqUQLqkf+/jTahnyCbc12YW+TI/79AQ8Ifoh2D7SEBHvn/DeBbZCPsV4Fv9ne3+pjWyR0Zd3q7/zRRTL/dxzchhLTby/3GXv+7hJB+G0HIN2gLdLe/m9D2fkyAH6NtTPSYdBnuQh/rswyP/P9pQqhG2lR6FoB/qsPuPXIoxc+QI/+/RWNwX+8w/9lS/58kAvEuOVVNxjzh7JH/b9IY+bXexgazj/wX9grW53vdbzA0Qm/RjmX96Q5L5/5Zhsr+Xdoa6vH8Ic7mR/9kh88qORHrN3QYv0GEymXOHvn/Nm3d79ACEdfJQSS1LoQJf5Z2yM3PEgEjYX+dnAL3HRo+/UaGR/6/xdm1v0rDEZ0VMrLnyP0+R7S1/I39vf1OynxkOu/3cV7tfd3pcFLJvEqO/P8FZh/5r8d3k7Z+E2Yf+X/Sy9zrbQmzCWeNtq+Sg0juMjzy/wf7ON+i4ZEM/zqNdn66w+AHyzxvMNzTViPmd4ky+Rs6zA7Jkf8TGs68yGwl4i6NJy30Of3G/n6Lhhu7NPpXuZW+6pH/d4hweKaP4xv9/W8msP42McbXyJHFJ70vhaPK6nqH7fMdPi9AYwqfJzvcIWf+rxDr9z+mEeCP/SzwB+E//ym++nNNIP4zJCr9Lok+TciR/xoU12lHpx9z9sj/b3D2yH8VXvmKcz+m8dQl2mbtX+h9v8BQeYbGc/ZpPMF1vsLsI/8nNH4hHf4wjZZ+qk//Fm19NYA88v/bHd7PkXvz/kYH42vEAJSfLZBoxPjI/9s0Olym4e8Sua7jhMardzl75P82jW9OevvbNNx4hcbb7/ZyVxke+f9NoryvkWPeD/u3G5w98v/btK2QVwkd6Iz6Orli4DK5zmGeOCE1WlW23urw+iFyGMVdGh7Ls/45wleVm1sd1s+So8bvkmiP775BjKtrDI/8/xZNF7hJ43fy56/1+j/O2SP/b/dxPEMUYQ/roLd1FfhLDFOadSis8vFH/v9wn+9fIbLyh3s/v0QOO3izt/914oT4NsHRF/vYndsXaPhzhxz5/4B2GMMXOjw05MWFSR+3PEuD7ai3c5XwWI2BKcMj/z/f5/EtcpXOzV5nkRzosUkUW/HnGk+OOqzTdEbhtEvTH79EW/tN2lp/ju/9yP+fIXqFynMdwymzj/zfo+lYn+7vfp7GSj9DW6tNouCv0fjxlVL3DYbOfzNlXmR4EIkR8LEcerOP/6u9jV/g44/8P6TpZBNycu1RH/sxiYrNMTzy/2fIkf8HtDW//hngVfjqj7axvUwOItmg0eoXGe5pewm48hX4+Z9tPO/znNXZfqyP7evl3U/3+XtFyiJJq/wCDS+2aXL4UmnvhMZvdKy8SuTnlIajN5h95P8bNN6w1t9t8OQj/6c0vc8AwsucPYjEs7/+eRp8f6r3cZO+a+Gc5xNhtOm5qdEnvVu7xEuhkJ2S3OEpseohx/1q6er9mCORID1BWvZb5Z2EOiWetinxTu6XserVWhyVu8/wmHfHIqHtlHktkkiO3hAVYMq7GpFQ6dsu7ZtyoWeLMjfDy0YaZsHHCN+0tK+XwzEZVdT7TCmnl6t6myDpRXqC9FLptdMgXyapKOMI2laBpQJfj5iM2MjjPI3hVY8ZJPp1QoTc4zJ2YbJEBFM1JJyXsFBJFB/GRtu0vHe994k3+D7DSI/OAIjypZereqBOetumhQhLI4tT4vHcJnuMlhiu2R5RtLeJN1yc0sOoQVRx5QFRPn12SDoOBX7W9dkqsBDOp2S9T0s504Ur/MRlcaXCx7HukAimjh+/1X1kU5ISZYRqmyjXztdxrjJb8Hu8s7SxVdqa9va3iJdd54rRVnHEOVV4T8kpkhBcEU4VtjsM0yPlj9KlffE3acinRac1rdEm0NVuH3ylWY6/5dfxT/7TP/fRPVmu2aMRrOQZY35WvfQLJII/JTxMHiX8jsrcpcNFcrCG7UuP4pIwk8/K709otFfpWdkibI32+/ektCOcXZ9DkuLqfI6IEq7sEU+dj5EU25PPufej4ivEW78zqqtBcUyic0YkhS1EFmjYyO+UixAZoPNxgeGeEVOj6kmdRlnEdeevoUZpQ6PN8djefWLg1FS9I4Z8fLvM6aSP4T65Kse5bTHUA8TJI2KsqGssMcQR13a3t6fs0SiBoX5i+qjjgyFeWV6nqmWUoeKMdbb7mNQv1CcsZ59Gxe6XtmyDMg/xw/WZEj6wS1vLytsfE/o5JKmS1Wir/amT7ZefhwUmFad02qwUmC8TuWUE29/SzHmPMvKQyPRdhrjvOm/y8UbbNpEPEH3ng1JG/eNBH6eRHHFniTi6xUVha10Y3g06JXqv+t0R0Z2eIoa/8BrPpcqKOULD8pM6PnWcyq+kDQ8RcWzqBbv9u7A1QqccPXk7+sMSMZid+yK5dsp5fgv49s/CHwT+z5+C/+reUJ4pvxRPvtvt7Sl3K5/cJrgl3YzhVGmt6tl7zD78RtoRlyF8Sv7jWKRZZc8i0QmOGD6Oc4vgnrrKk55PhNH2AUlNMb2mKlYi/G2aglAJpjL1XXJXzArNk7dO0uYOyUWc24TJv1X6lyCqwvCARji3CVNSx9HzoQK/RKIyCtqlXlfhuE6U34U+pzsk7UEjRtioRHg6mAzXKOTYi6kiv9D7PSECe4WkRy4UWOhN09sGSXnZZ5i6eMqQUXuBOcRrqBLsHFW4DP1Per+mN6lD1r0y9HkZQdojx7AzKmeofZ54ccdG20b/W6FxTPPUOW9hIrPbLfXfZyhUZapHI3ja1w7xmm0UeFnuNnE8rJNopgqtaWgKLg3LnTIW+zslqRcy4ePe3pQYbXWTr3i8XepBGIhC4ogwPvH2KYZpaxDhqGIh49kflZNpCkcZ7thoE/dUFreJoXibpOEaLZC+p+TIf9OZzat/iqGxqGKo0XpaYPYBYaime6nEjB9hBqF1iALhmDUkpc/HvbzKpwrWEeFJRmGE4Tq501FDkfLtsPwvHvrIT3/y7wB/Z+j5M1XpKYbG1gLw5R+Fkx+FU36OP/kvwo/8s73zdeBtuPOjLToz5ezeyp3SrvPeI3RmCl9VTKTvu5xNj1wn9LBOlBR5sEabayz8NS4U7gpueZiyQl5YnQ2PCc1VRfJdko7nON/rfa+SNLuqqByX8lXJ3yROkk0ScTwgvHyf8DDrPiR3pGloaigq+yDGpXL1PtmzpOPihKEMmBKDS7mp8rFAsjqOCL2aWTLhLE3Pjf423fIOwVP5+JTwybHcnJJ0LY0A5bXGxRK5e9Rx6liT/9wlEQiNsrsFBjoHTJ0UH6pyJtwh+C7O1Wee8F/5bjV4nZdwdA0ek0yf94hBYKr/28R43ij92t8GMY50FhwxdKwI2x2Slqd+NV/GoqNVQ9J1l77Up1wLU+OPyCXOK4Tm5Ls6yCDrI/08KaVRXDkiWzY0atbJPutlcjH6k557DFMyhU3VI5y/MrPezaqjaKXPd4lkO+yUtqrcgdC1fOIDhmnkB+XbIgkm1Od92jq9U/6X1+gAUDcwrfGY3PKiA/GY3DMK4Xm7hLbkheoZ+8A/ASy83fq4RHTOKW2dpD/nAaGV3wEs3WtRyQprnU8XyZaDU5I+DkMchWyZmtLopuoe0GhIXaW2ow1yQNLgfdTF3iF6rs4zncUasep04oOG9lyp67NJUqJ3CE8a9z9+PhFG26+khSnv0MKIVxkS9gMaEv8AjQg/IHf43KYh3a1eb0K84j9Es+bv0IB2hZYScbH/v0YL236NpOC81H8/TUL8Ms1fT4wlmeCEeHllNj9E7quSKH6QKLLfoTG9OyQ97Cv99yNaiP0rvawekgVaOPqZXu46DQFPiOCQseoZWugwUxm9Uca7Sksj+FYf6w+QfVES59eIp+YOuW9M4TShpTI49gWSqnOtj2Gjw/TzRKk8IemRd/u4X6SFoDU+5hmmR3rh9IS29i8xNJRc43nOT4+0zQkRRF/rML5IlHPvIDMt4ZTGNLY73F7q3671uqYWyCAUoC/3eS0xTI9c7f1e7uO63OfxOsP0yDeJ8H2WtvbPMsz11th4jigqH9CYz+s0PFG4TMp8HM97fZxXiJIkrOZJeuTnaYr5Vl+PVZJ6YHsbBb7C4lmCy6fEEBFvxX8Ne5W6rxLBfZfkmz9Nw1WN3jWCB8/RaEfh8zVieJkeOSUKxrS3KQ6eFJjpZb9L7ml7gdme3zskjWyZRutGBPX4/yBRcuzrJsGbu8QQvUpLj5z08l8rsDbN6FKf+/cRZfgNhlEpHQJzva8bfW4bvcx1IkDv0vBmlURgVVx/sJc5BPhrvdKf+nXo/vjtP/qLH3mUJyQ98oCz6ZEqfEs0vF/pYzRyt0iE1utlrvS6b5D0yMs0QfoiMfrov28R54GeZu9p+wxJs5v29n89LQC50OEtD3qByAQVr8/RaObbJD1yUn6O+ti3+vikpWoQv0pSArdo/OVzJJq7TKOdKW0tX6Hh6nf7eKz7oL9T6doiabO/QDMslX1fInJ1kRz6tNZ/PldgdpNG9xptazTcW+59G0nRgPkaWcune3nLPGYYaaT38WZ/91UiL+6SyNkSs+WmcuAqbZ0nvZ5OnVt9DCtEsfSeNpW6BVoK6w0STdrp724R/mR65JSkq6+VeU+IInqD8GcdzT46KV4kd5OJlxsEH79GjGsjSF/tY/82SR9c6/38EDGwhRt9Dl8ih7m80n+/02Gt8XeVpNK6H2mNhmOTPu63CO1qSK72uX6dHJr1qM9pnYZvz9DSxw7KuCfknrY9cred8lie/r2kR96l4fc+uR7iZRptXext3u/vvr/XqcbO6eh/HdxVn2M0hpM+b7cUqIjvER1rtfy8RKNPDaGlDpsbhIZ3aHxNPnFAnMIvkLvX5AtV7/FxW8rX+v+rNBq+RSLaGyRFXofBBlmbVWJcibtrxCi6TtMDdJJcI/zsORIQeLaXM+V/g6Rny1cXOkwWiU70GkMj64joVz9EMsmUEy8zzDCChm/vkVTnmh55SsO/B30+X+xjgtCP6ZEVL97u376f3NO23uenLqRzd404Bx3naodHdZJCw/cHNBra6P9/pff/H3L+84kw2kxTU1HQQ6AHRg+QFv4uEYA7ZNPrMbFY92lEZLuQjYh6tX3eI2kQW/2ddY6Jl0HPnGM6JF6XeeL9WyeRO8P3eohhmDojg36fRFKWyF6EQ5L2N8fwrifHrEdmltG2TjwWkIvBhc8m2dt0QLxkkAjSlKQUzRMGKRPXQK3pp9Wbcp8mRI2MnJDDRGRm86UP4Umvo4dXT5GG2VLpx37nSRCgMrYPyMZR8cax6x2UIT4inmcK/BQ0elAUrFt9PHrdPiCenHmG6Z1LvY7rrRK7RzYPP8XwAJ2xV9v0QIXJMUlZ2iHH+eptmxKlwflMSbTXfuv62a/wdf22CaPfLfDV8+ScKvO9W/6+V+Co91/F0EgMJHqgd3iHpDFWfFAQKtQg0ep1EjGC4LJwrB5IDUbxURzRI65wmOX53SSprMu93xPCJ1RkpFnpVCNPz7rrKsxciw0Ca+ct7b3X34ujB+X/x6XeCnFabDGENbR1UWBPiTdykfCQI+A/ugdP/2n4oT/9c/yqq8Dn4cIfht83Byf/WoPPhautkQ8P25yuzHH2zP8FYALrbzZlVANCpQWG/N45bZVy0o1GoPObZxilnRJjVodelRPydmG7QbItlklKnePYJPRwwNBhp+ffqJ28QgGuIrJR5mnEYEIUoiVCpxBc3iLRTAg/Ej/lkZc4K/veLf3vFJif0pblYoGZDiGdEVPO8gbpxPmukOwSZRIk1U3HIgxTgN8nMsfIqyhS+XjlwZbX+NgkzphlIuc02syEEb7WEf67JOK5QLJrhLswg0SjnLt8Z5HIGeWH34xorjC82kf+tt3HsE6cfI79fZJivUxkzgkNb08ZnkInrO6WuW4Qmv5zvwb45+DDfwUuPAV8Fv6xN2H3g+xpm/+f0BBiAb7/HT7KW/zwOLx1Dbj8GT5isv/WB8O0/sfEMVlT6qUXoxOugXqBOKpudd5zj0SMrbNFdDxlhs63J0XtIDJZPm9UvuojOiAuEX5J6UcZ4FqtkAjeKUN5dzCj7lxv10yP1fJevrYwAy7SxnovV7cEqKvWPoTZfSJnV0gEUJo1Gm8GlHxPnfSI4fYdtyk9TcM5ZeA8OUDEMcifFmj4u84wG0h9/jHRITR0FhhmGEibylFpqeooyo+d/l68gASIZsn4Kod1KEqz62R7wwrJTtgv49QmmI7aVd6vM9QBP+75xBhtAmaTCFK9DVMaQd/hbHqkgNFoWiFRiNsM0yOPaMikYJA4bhMEk4moGB0yTI88IER2RE7Kq+mRt4nAnvZ3RoIgaR4irJ72lTI3FeyaHul4dkp9EW2eKINVML5LFLUjIliXGBoHRgu2Sn0jgfvMTo887D+O3ZSX+5xNjxSmpkc6fpm1gn+HIUOSGVQDtc5PmI7TI2+P2jkmQnqFpEfeJQxNJqfQr2HqcXrkY4b7Fav3S2azSHB7SjzcT5FQu0J5u49ll6RHOh891FOScjclCpePwlBh/x4xQJ2XjymD4s8OQ0aqESQdzpGT/hRG30t6pAaPT8VdYaYgp8xH3FOJ1Hg6oOG0zgaVJmH0iDh+pFcNRBmo8JHPSOsUmH3AMKquQJsl+GXg4t6d/l7BsN/fiQv2pcG5yDA90rErgGqax3ppsyrGkIN+bNsIKESJetTfqej5PCk98g7hK292OHwHmNsC/jL8X+8C/xzMb/UPf6YN7sIRXNmhuSdvEQalZrQKc2+Gv1acg0RdZqVH6pTQySa+QU4WUylRwdbhNc8wPXKVRo/ynzu9D9s+ITTnGs/18o8JX10mHtPbZP2r0nVMIg+uTTUW5HUL5NAQ57dP0i2ta6q+/PchoXd5MUTBlJ5VdjUmqlF7nxgmKpirvT3xZOxIusv/sPTIB4TvQbzg4naVmxuERpyLEbEthlfR6Ag5KuM0Gin/eZekPe7T1lfnijz9IkmPFB/kQ/IQx3fMkObrM0/DcfUEFWmVZPFROCqHVVhXiRNVfIHQZp0HhN+Lt6tEkeQO8B34d4CvfAC/9mX4+V+E/6L3OQGe+zvDE6G7zfbRftxNmuHy8tuJOr5FUk/lxUtERq6SCHw1go/K30skxXfKk42289Ij1Ws0xJdJ2uCTnu81PfK0v9vjbHrkAUMdC6Jbyu/FHedc6VqDSl6lEVcdP7MMC3mhRsgm4YHj9Ej7PyaZYMrj4w4HHXpTkh75uLQ9ZShHhYnyH86mR1YdSUPrPom2vcNZnU3+fbu8k1dqIM8T2lwh6ZF3OZseuUF0leoQ+oDhIW710Tlwh6TZ7hA+rT65xDA9Up3AlN1Vhs/9PpZ3iC6/PqP/8fOJMNoWSSrGNVr4WMJeIV6/54nBdJXGUCWEG72egnOFpifoUZ6neYZeJAz60ujdHknTOOnfLpPIwS0SoThg6IHXaFymhZ8VKi5qTa06JXdluJg3Sd76NXKK5SExQJ7pY7pITlzSiJhnuFGYXud5QlDXSITkItGj5nq5IxJVpI/J9EiVDpU/xz3p5SYMc/sN/UMLq98i3nw9cM90OJz0MqcMjXD6mF8gxswqLfw+PjFOwvHvFzl7UaPKqmt23Meu8Fym4eLTHT6f6nVPiaIkjl7r47fuCllfmeyN/rNHvDDiw4skHUGD7CZtfY2a1bSiKySNyVxs6eK0j1WGrhft07R1qAzF+UyJoWa/c0TZsd+13vctcifVp3tbT5f2donHSeXItKpbpdxFhkLCcbneCgtxz2gcRMF+ngizS32ciySVU8NHet0hqTZTEiFV2dCWOC0wU5FYIKmzN5itRKhkyaBf6O09XcYvHVbnynUSaXuKCDVhptJ8cwTrE5LS8iJRhk85G2mjfxdnP0WjQ/o8pZ+LRLA+Imuy0Oej4qvgH6SKntIk5O+lHYX1F/5N+C//QDsea6F39CI5JalE2qSjpdKfc5AnOnfhttRhp9L+HEMeON/r6mCbdliukdPrtklUcdKH90Ev9zyJWpsuozEC4WfHfQzPknQo+cELDJ0f40jb8yRdRu/0TYa0cYU4LF8of9e6KoPynx0aTTg+H+WcckvnjnLxUvn+kIYnz5KDNrwS5oCkUtdIm2NfIimtlaaFQZVNysybJO1opYxB3KtyUxpZJWlm8hsVLseisX7Sy3pE+2rv9wY5XVf54ul6WzSaFO7CHnKNivJf2ajusskwU8O5r9BwRzmuMi0fXOh9y4N1NEgH6iETQgsvEMX5gETa1CH2iH700Zi6xbBNI9GdPw3/xAJ8+Rn4F+6190+T9EHlnjxFxdl1n/axqn+pO11ieFKhNHKdKNXPdniIT+oUk97eky7XvkicDsLAee8TnnCN8MknPYtEn9IBKk8Slx8TvHO+EHxVx9rv314k+pf4e4mGZ2ul7jHBE+czJadUQ2T+ArPl0AkN3vMkbfsGyUZb6m09R3QEHZITcjjKI0Knl4lecJUG24flf3WXZ4ksU34tEcP0CqFl57nF0KE8S2dzL6S6vMauuq04oLGqjF5iKDdhmGUF4eMQ+rnKcNsAhG9Xvnuvz+NFEjxSVn1AnKPO7SbDVE3bWCS64BbhSU96PhFG2z8gURQJRaa4Sy6qfEAMLr0CD4lCDg0BJQKjBnqf5ohXS4/r4ujdtJfdZ3jX1AlJp9ELpNIgIqpkGfZ8OHonY9olp+EtlLYPSvsK8gMSzbMfPaTOTeGr4qmytkgiWepJhyP47JFTax6TFDS99Cq6zlmls3oSt0l6XV1H4aj3UYXPcZ4w9EBVmKiI7hLPiR6dJYbGKgXeKgZ+9zkqYzJKZjlTEVRaHxcYC9edAgONIBiePFm9NnoSl0s952a/B2VcMhPxqc7HdT/pP7Z1XN65vq6fNDHXyy8yjMJMiUK7TYx3cUrGqtAy5WBK1vFo1J5rrxIJQy8YBY6O3zmMjTZx76CUN+ogfemJNNKtMNsj0eVHBTaLDO+WUalzzOK8BmGNfGmYC5P61LE8Jqkw4rO4oL0ifa0QY22HIY5ImxXelHLCaZshjtY1MZqmp1RlRF6pIintaWAezBgLREAfMbpPcYcs7B8F/twfgH8f+F9ehX9qKwjvYrsgR8O0YdfxsDSrIi7fseoSQ15TFStICuGUKJXSZ6Vl+dg2wwtTNSh0QuySdKkdsj5HZH+YuPqYYcpdpSMVWDMqbG9KvN7T3qYy5YThnUe1rn3If6b9/VZpFyL7qsNCuSFc/D4lDiwdR5UOpSUYnoDrWkgvtlsVUvn+QqkjPgoL90ctMty7K/9RDiwSQ1n8PSpwFC7295gh3kgTrm2VvbvEay8Nu/6ui22Ld8oEx1+jiuKvjsVjErFTBgsL1/GIoazQWaxCL14YZaoyeo+zPMQ5PDqGi7uRh28Df/4Ydu61tr0H87C0JenKs8UD4eNc9ss3CA3vlrpLpdy0zFel3N8VprMe6Vg4uX513mYNbPc6YzlT3wkj+z4v0iYOQeTclBjI4qO4KH5Z13mdlrrTMhbnU9uEGE/qgvURh5QHOlHV3w5LW+og0q1GorqP8rPCZ0rOFZBPCnsNwgNyebwyeq983yZ8Qzk0JXxxls42JbKcAhedauKo8KtyVLoZw2laxqqe7XyWyhgqXkyJ0993ewwjlcqAYyJ7qr4nXkF0pkckhVn6fxLOwyfEaNNDrIB+ihymcMTwskFTl1wslRQFkQCDWM8K/bF33f6m5Z2E6rcFskdsSpiTwk9mPEdO+npU+jkqdSU0mZxM35SJ09L+tIzjA4bM7qTD6ICh4FBREzmOS/mD0ofjlHH6zVx7609Ln/blfP1bAUb5+4DhoRz249o53oUyvilnBeFJqS+8apuOgfI/5/zvmGVGldG7lqcMmZVzEFZ13R8RZiM8JTbfVdzSyLF9531cvtvmAkO8rR62pRltiTeO57i054mJi6V8XXthWR0PdW1lytNS/lFpx996jY8Yeqns33KPGOLYyah8FWRG2oS9PKEqCTJFxz7t7zVYxnOURxwxpOVq5Mh/rDvP0AAaP+JmxcVThjij0HbuwmKJ8B1/Ks3pUBDWlQ4XR7Ct/EZclne5bstk/Z6iHXjyuc/Dv/udltmoAuicTNOhwEynx0eKg8hUJfg/C6xuwb/bC79B8uCKVuccIevoHHSWVTw7KPOuMkODrw7pgCHtWdZvzlOh75z3ibxQ6dMzzagN6cxxur5VBmiw6LG1/lgeiJsqUcuEt0zLfMZ1lXc65eYZ0kiVfZU3HZdvwqCOT2NpzGMdHwzxQbz1qemR1XCpYxXedT61j8rHx3JgucDMcrZXdQr5Iwz5rfzicFRXONhnlZOO3fKurWXlz8o5nwpDlW7H/GjU/0Jpo9LfI7I31QjilGHE8zwcrSR6CFw8DN+blrLHZWzO9TpJHTXSZjvjdus4lH/idIVBxUVhJu+3nO/Pe0xbrWMaz9txTZnNu+sz1qfsu65j1UkqPlc9yvmeMsQveYTwrThvezU9ss4H4pCe56zRVvuv9F7lfDWq6xoKdyNt4haErx6UNm3rKUJPtqNuPi1jOmQIM3mB3xcLrKrBYtuWVUZX3jCWGZVHVF4E4c9+d5zMgM8YtlUuQPQYx6AMqONWF2NU16fK99rHlCc/nwijzdMjb3P29Ej3s5xw9vTICTkl6gUSmj7ov79OLqOdp4Xhv58gxuXe19doYVZIuHS1l79C9pR8neF+nH1ywtICyZ/+GjkRzbSaHyRehjcYnh65Sjtt7Gna4l/v/0P28C2QU6cmfa4bxJhTeZUY6e+/2mF3l5b6VVNEXqWFbNc7bKvBCjk9coeW/79B0iN3yGWCr5N0mO+SFAho6Z6fY3i59mNycuddEtZ/kwgNEfyFPs55cnrjdWZfrg2NIVwkp3D5VCNnleTCf3+H8UXimZr0+TiHE1q+viHwWwxPj5yQFB1o+LfZ5/0C8Qrp2V2hrcukj2HS673WYbJETkecJ6kIV8iJTfdJaukpjR4WSFrNUW/vOsFX+zEqs0Nbe2lunlxWqpL5TO/zC+TUzVeYfbn2RpnPav92heDyCcPTI4XFhOG+kPkOH5WyuwxPj/wq2RO4RoxZT480QiC9bjO8XFvGPe3tv0OMHGF2QPbbOB/Xcvy8Q4TLch8f5ICIHRp9HTO8XPsmiba5T2+LthZf799uMzzdVn426XN/tcD2DYZG3DHZ2PxCgc8GSc/cA37mOw3fPb1r2sfssdWeSOYcDxjyM16jHTSyTWOq9XbtfwP4p4Hf+X8C/hL8/dvwZ3u9y/CF/2ejJ/P+F0mU4jVy4hy0NfXEwRc7bO+SVNp5onC9RBRk7cQrtHl+luGG9csd3t+i4eHrRCm6RWSC0cWXOHu59irD0yNfI8fZy890xjyknex3pbd7n7amnyvzWKLR3W6HxRc7SC+Ti30pIJf/bPc5fl///W4v9wzwZYaGpEaH6XovEaeB/E1+fLm3t0xOj9T5Ix91PS6RE3Htx7+NMi/ReOoc7cS0Z/s47zI8PbLy8W+T/aOrJO3t6T5PlaiXCjx04Fwlp/ze7+19maRayw+/RFJLl2nrqKf9dq93hSjjTxM6eL7P44hkTSifFoiecpWcDLrP8NCarxBjRVmpfHWd12hy9pRGh0YflNXzvZ8vE7n5Cg1/3gGufKq9+Oyd1tcXevv3OHt65NPAr70Kj7bgjxH94p0Oh68xzFKaMvtybdM6JzR6Fd7PdXi4j2q1zPUaT446vEejL+XdlEYbXyYp6/dp8u11zirN4+c20acgh21UfeS4j/dlGt1cLGXXSbruMjk98k0azz0lJwzeJDS8S/Qn+ethf6+uATm4Sj5Zn+/28X8/DZ9NyXuRZCq9T9K9NQhNP1wjW3qWiLGx1tu71+u+TPiMuL5L5Otmf/8yDUcekC0/rxZYzhN9conQmpFLiBHzNMPLtel1vFx7gRg66pkPyKmrPifk9MgNGk0oP6e9rec6zOrzFtHRXbMNGu59nuiTq+TgnSlJi50w+3Ltoz6Wr5F9o6/R1uePcv7ziTDa/gFNkKlILRHPsBatqUt69Ke9rpauebbVwpbZqoTukzBk9WjXULp1q7fx0ag9lQCFn0ab3gDTqixjXQltt8z3uLxTCE5JysgBSRVxrAq9vdJGNdpMjzwmQv8h2Uw6JYp2TcswuiBh7HA2vU/Bq+dsoYx9nuE6Uv7eIQrzKYkUTEme8pREjKr30jVzbWyvGm27ZD3gbJh57HkRb1zLRyR9xkcGYiSpeq5qKoTrXo22uo7Wca3EZQWg3/bIplzHNU+EssaJHkYNDb2l4sgRbS3dcLtHvGLOp67pLmGmrpH91nlY3nSZcXuufRUoSwSXheO0jL964TVAIWlp0wL7R73sbnknTI56+Yv9vY6FaR+bStyUoZetrgu97EWSPjEtY680XB/nI86aXiIPOCTrPSWRJelXQ0l+Ic5P+//WhSEdLjCEreOAYTRvngili2V8KhyORc/0lOHlvvIQv6mUfgQLAeXAVsv/+8BPAHt/qJ3b/Ksvwb+w17Tzn80c9UBXL7+8boxn4lTt4pik36mEyzurp1fnWsXDRYb8Z6+MQyed8IAhPRyS/UZ1faWvKUOj7YikOcqrHM8u4QfCfcpQ9okbte6U8J9p/1bLQxT66vmujoZFQvvTXndlBFfbcx8KhN849il5xA9TLJUdfpM+9hjKRulAGPhtylk5UGVaVXYrrmqAQaLeVS45r0PCM/Wcyz9rv0ulvLxL3ikPVs5RytRogrJPeFtnr7RfYSAtnxBdRrkpn3ZMwmbMs/1bpl55kymdx2RtxOe/vhWn59dpiu3vZcin9tMs+8S4EKdMLYU4MOV1NZ1UPaLi5XlP1bHUXZx3hYdr+nFGm7gnzlcdp6b2VplZs7DsWxo+ZQj3U3IeQKV/5Zl4YpRGHN3r5YTJLKNNHN4t/8u79kjkf5c4lqSRk15nlaHBAeFdjziLU/JW8WuF8A37nTJcg2q0uX6PCW8Xf2F4GMvO6N0RwVHpAYa4qPzwUUY6budDmd/T5Z2PbY559pTITX8rJ6t9AMNTLH2EYbUX6pjOez4RRtsFGuD17iu8F8kCQ0K186VcJapxHb/Pjd7V/+dL3drX/DllFkZl50p7tZ1xGcdL+bvWHY/bsuM5LIx+6lxEUInQfk9KO7Pg5vtThjBYYDjWMSzH46rwUIEdw13jssJxPM+58n7Wmo3XQZjOzyjjU72eljkZtVNxb67Ur3Oq7S+SdMAxnlZ8GNevuHTC+Ws7a43GcPKZhXO1n4p/c6N2xjgxXudxv3WMFT7jupxTrsJnjE8qeLPmX8cz7nMWfY/hOYZPLS8sx/CueFVhWJ9ZPGYMy8VStq77AmfhVvFmjMuz+BGjupT3437rfOtcHNOYr9R5+V3FbqFWHhPemOgXgB8H5vaa+/gl4Ed+O6/9rj/DHxs1McadMd6O13OMR+MhnUe/s3D6vL8rr5nF72a19yR6qvAfr/Us3B7jfK07xu3xOnPO+/H4Kq8Y87/xsi4QT/KYn9fxVrwRfswoX/F1jHuzvo358Kw6jm3cX4VB5W2VVmfBciw/anuM2q5zHbf9JB4/hsvpjDGOZQ3l+1x5P+7jo3r9j1nzOy3/j3Eccqn2Y4YGhGXHazHGnbpmYzhS6o3xYtYzi8Zn6VZ1Lk96xvXO4y0VRyodjuc25gOu5ZPof9z3LHk1Sw7NGvMsPmndE4bOlIXyfkynY3qb9f8snB7Pa0yr9ftYzsFZ3WjWu7oWzGirtjeGUf0+1oHqM6t8nd+Ypiu/exIun8djnoTz8Akx2g5oqT1bNM/F0yRaMCWRjJ+iWci3SRRoizbJHXJ55lskH9+jUOdI6uQdkr64RUNe3x30MW2TNIwHJKVQC329j3GFAHyfeNF2aCHUaX/3k2RB6/Hx8ySi47UCO8Tj4Hjn+jhMB73Uy90mhKB3vXr4Vvv/27Tw7EqvYzRnnRy+cExSBCCbMvfJZkmFsHPVy7zav22Q4+ohnpn7DDeGXyRejVOa4/39/nu+9DPtP2/RvDXLJJWkMuItkiJpBK4i/zEthcDvHthhlMZUsAVyopJHt5+QE8G2aWuyQULhGwwZafWSr3eY6qmvTN0c8vX+8w1yWtMWw2OAL5N0lTcZ7inSE7/A8CAA0x72+7caOdwnnlLTDqHh2DtkDZ4mp5TeIZ6z5Rnt7ZBjdo06bpIATI1C3yXMaoUoBdXxoFEs7tlvhc8qwf+NPnZxuM7T/vYZbqa3fR0d32B4QaZ8ZolcVD0W/lsdNuLcMokqbvR+forcE/O41FsgqTzTDpv7/fsdknax2t+tl3mvMqTJ9xnuwxAvoOHjRoeNkbbbpa4ee1PK9olncYWkWwrbnyRr9tO/CPxi9tyIc3og14Dn/0Q81VMaPr/An+HX//PwV34Q+B3w9w9bf87h4qcY3i1xCr9powPtCuy83ezAKeEFKh2bvZ07xHNterOe/inBKWG7DvxMb0NYbdBobr+Xkx8Kb3nHMi1Nz/0oe0T2SE91r8qkt+ea7xD5tUjj8YeEbg7I1TjWnfb+TaucljneJRvtpUM97F5BAUn/3aKt7Tt9PJcLPJcJ7im3KO1Jyzu0JVtlSNPCQNky19ta73O+1N9v93fyrJ8mfG6dyANpZouka8n3toicMx1zk8jqKbnP6t0Ob/mEx8W/yZAWDohMm5DojnAXxpNe13XzmSfZMRNysqxRa+f1s32MbxEe9o3ez/t9fCvkSHdp6pCWhiaOGrl9m6y7ePub9uDpv9jGOSG4Il9YZXjQ132SIfIL5GCFSe+r4tVh/yatKY/uElJ2fd8hfMm+LbNKUmzPe+zHaKprskvDb6Mh0hxkrcZrQ4dpTWfe5yy/l1cqM5WByj/x+R2Co9LsKW39LvY5T0rdDYY05XwekhT3OWbrNjDcdjBPaP8uiTjuEh3LPpRvZqLI432UO/Ky+/37PtlickCuShC/1dGmvY/7RA+YK20Kb2lNvYE+lrcZXvZ9Si653y3weKt/PyD0pH7qc0Kj9ymJfO2Veu8W+MAQL1yDSf+9Qw68McOh6sMHRL6qa1vX57u09f3JAoul0v95zyfCaPuQYarX6ej/+n7W//Mz6o/L89+jXc4pfzyjjJb/rPKn5f24Tv0+axzHM+rWMjLRcduU/+dGsJgFv1k/tb9ZcDnh7JjG4xm3cd76jNeqhrOd//Ho/zrGMQz9+zHD5zFn12M8Z9fSPu13vFaz1rniwax18v38jHr1/8ckOlqN71l1xgJoFr7XdRnDsfZ9XMY2q83jGeVre8echesYXozaqZ54SnnLzY/qj9esjg/OrqdjqmP1mykZs2j1vPUd41wds98WOIs3s/C/znEWX5m1PhU+s2AxHmPFk/G8zoPjGN613fP4wQZRet2zMTbajko90+u+C9z6T+DT7wB/B37Fm8C/DIsHfQA3Oesd8EK3K7D69lAGOI8KH9/N4rWzcGdM6xWvZ/HhMQ5VfjiGU+1nFn+ZhSuz+PUsfB7Pu47bco9LXcvNMexzzMfPowufSq+VT43LnMyoO6ZV39XnvHZqvQXOwukxwz4rjz4PvrNgfzzqE4ZwcXxVBxnjy1jpn9VPbW9uVPa88c1qY9aajn80vI/Lz5gvCFdG8H7Sz3k8Yyw7Hpdys3iN78YyfPyM4Vzrj8clrx3jF5xdyzp+n/PW8Hj0bhaOzuKz5+kX583D55jZz3myYBZfGa9Hhc9YztRx1fZmyYv6blYfdY2rHjQ3qlf7G9PHGHcqbGod/x7DazzmMR+tfc2C5XnrXcevrjmLJ9fnPBly3hr7fCKMNtMja5jRSdRoSg1farHPlzr1Z1baQ/02P6rru1npRP5t9O68FMxZ46jfxvMYh9kXOBt2Pxn1YxmjQjX87COyzJcys8Y2/oFhv2N4jsdc4b9U6lc4jtM0Fme0PU5Jsq7t6U2ZG5VZGJWra2IdRmVm4dTJqP6TQuFjfDuZUZ4yxiVmp2rU8nXNF0e/4Syu1u9VMXAOMgPhcMzZ8Y1xbbx+5+G0azhub2lUbpyWVft9Ujvjcs5jFvxm0WjFjzp3x1eZtIKl4sm434rzC5zFqTHM6nzHuFq9tpUGlhj2NcaFCqNxPxV29VvFS0btjMdJ+XuRKOBj+FrudMa7WfzrdPRt3KZ9cY92csbXgF8G/i/AXyObWkTOygyXZvOCul4qsPVnjM91vLPWalyuznees/xb2Nf1q/QE2dcyxpPxmgufMW7P4k3j8Y/xxvYqGP1deY4ws+74/3EKjwr/GJYVP+ZGfzOCeR1njUrOj9qpNOLfT43m5liWSpsVTuNUvvPWsdKmCvY41UldYK70MeYTdd6z8O90VGdMo7XdittVjqpsz8LbWe0+SR+osmKcxlfX0fE5lqr4V/411qcqXx6P5XQ01lkyvD51bmM6qTA1QvVxT9XrbN/39RnDdzyWMX9xjmNdYUz/9n1a3tVy80SfmKXbzI3aGo9llp4yi1fUts/TW87rY8x/xIG58tv2Z+mGdWxjnljHM4ZvbXNMy/WpfKfi9lgnrc8sOTxrnvW7fHMWrtT5jfnvrHLj5xNhtMEQUeY5izjj93Oj/+dn1BPZxoKg1h+XmzWu8ftx2TERjQlq3PessTDj+7j/8TiqMiCxj8uNhca4j9r38ajeeTA7ZTim8fqcN04VhROG7Y7L2O4pw/HWsk+CGaNvMDRubF8mOgunPm5843L1WxVI55Wp8Kh9j43w8f/nzbF+r3Mdj4MZ5cdtjZ869lm0OG6ztjULjuOys/qeBa9Z8xjjRxV8cJY2qwJ/Hm6N5/skHIPZsJk1vupVfBI8n/RtFt7XuX0va3jevMee5Vmwrf3M6qt+m4UP43YGePDTwD8M/C7gT9KOc9ymhQbgDOM4D6dr2+fNezy2WXxuloypdcbrM64zq/4xs8dj+Vnwm4WD47Eyo43xMzcqN4t+xzA7ZfZ8Kj6fV/c8XjVrHh+3NrP+H89n1jyPZ3w7b33Pw+vzaG4WzZ8nq8fjH6/5efOr8mEsC84b0/jbk+TQefJljCN+H+PDmJ/OgvV4XPUZ4/kseJz3jPubVedJvGr8fK/9ztInz8OF8+THrL/Pw8NZ+D6Ltp7Es8ZrP9bBKr2P4XAe/pyn9z6JRs+j84/jW76vTtYx3o2jlR9Hy+etwXlrP2u+s9qoeuUsHl7rn5GBT+jf5xNhtP1K2pGYq+Q44wNaio2X9D2mHYf7kJZq45H/Hsf/Qq+32utepB2z/Uu0HNE5WpqOx1rP0XKmn6EdDbrax/Ji//1eL79G9o98jeHJhft8/JH/lv0qsaDfJHtVFvrv13pb+31uX+plD8l+JY99n/S/N8m+LL1NNey+0GF22sfj0dTuv3iFdjfTRi931OHiiUivk9Mj75I9VuZCP93H4tjnaDnIq3189Dq3aOt6j5yItdZhv97H9zxnj/w/oa3rF/o79xhe723qdYLsUZijZVN9jaHH4oPy9yrZv/F6h/kqwyP/J8CnevlThvsob/UxXKWtz4ThPq6jPu+XaBleC5w98l+YHRfYeQz4UzS8Xu1zWurvn+l9ug/LyO8p7UjdpzqMzTP/Ejk2vOZ3n/Z3O7RcbWlujpbXfUQYkEf+f5a23lu09Vgl++Dobd0r83Gf0BWCy/T+tvvfSwXeMl2Z8mvkEMJ1Go66j+ArBT5rhP6uk6sPjmk0N+39XSe55+4l2e1/3yU086Xehnsz1st8XmS2klBh5pH/Jwz3dXyV4V6iUxpuuEflLjnO/AqNd8l3Xiew/iXafokJOVKb8u2g/22qxvt9zDcKfDxe+7lS1/1ZK4THbXVYfrWP1zkeMORn7xJ8mvR+hO1m7+cVwpvkZ5eB/+mvJGf+z/cPP0HbyPNjyzQq3Ia/9agRoZuNbsDL/1njDzcZeuXnaGt1QPNeTmk0vkbbO/VSgfVef/cD/fcCDff0rr9Ajvzf6b9vAb+mwPs6oYdVhkf+K3uc2hENj1+h0RY0PLlNo7EVQvNXyZ6Lz/d5vN37t+4O4bkLva21Pr5LNPyll/8+csLiAjnd7EqBizC7QaN7Dyu41OcrL5L3HPY6r/exv0euBxA/qhOryqbb/d1rRF58L3JTOfAsbX1Wez3Hcqu/W2F45P+EhmYP+nheJcep7/U+X+ltHveyr5K9Ue/0slcIH5mU8d3o3445e0HxAjnyX17uPmd54naHxRLDI/+9+uINciT+2719aXNKZDW9n1eI3PwCjSbf7bDwNNFnCS6rT6x1GF4k62TalzS8TK5zmTI8PXKdHPn/MtHHpI+bZN/RtT6GzT6flT6/S/3bk6IO7j+Sn09pNPQKOe9gm4bXr3G+Ie1zh+zrnWd45L/PSZ+bMlM595ChjmVW90u0/VabBG5rNFxZ63X3iAycZyifXiQ4qm4zKxrzNg2+r/f/l2hwfp6cpvl+H98Ncu/kBtk/KO+StuljnCd8/LM0mSXuOM7rfW73aLj9WRqu7XS4XCX4KC+4R3jdMu2qhqfKnI6Jjv0D5Z1r8lkaXs0xPPJfeqpy00festnHo/xUBxQ+9VHXeI2s2T0a7mm3bPU5XKLB9lEvN9+/v0z27fo8pvGi7yf48aXe/5/i/OcTYbTNEaV3haFy6fs52uLVd8u0RbbehDDr5fK/9S0j4j9V3nkSkkRomysMlcsTgtiOxbDmYRm/49gvfUho1UBYGNVZLuUhSG05N41OaIjq+KpioIHyFDEMar3ax2r52/FrMLnR9rjAUYW4wt1250q5lQJHv3us7XF5t9rheHHUhwpYXR/bdW2r0bZKtrvUjbU+KqS2uUIO63CcwrLCij4+nQHjOduf44KsWYX3cq9fxz8p47J8vUfPtXiK4EeFhfM7Lu9keielvOtV53NMNtLPWj9xSVhNypgcZ23PtpYYjm2Fs3DcH5VTX9cAheEmb8f0QYFNpSFxRrh6wMuEKJYTIowUGu6ZqAr/Kg0XNU4cn/g5S4moMKvG8WEZX3WWLJD1mTWfOo8lhrCu7SxzFrY+Gm3iZMVZL/qelPJ7ZL1PyOWpi6XdBQLDCUlpUtgflrkI28prVPiOiLPqo4vqXESBcwr88UN4+b+BX/s/g3/0OfhHgelf+eiCLPHRJkwZm+8wU64cFVgIhwpr19d3Kqsr/W+/SVuVd0kzq6WcsmqfoS0qXxM3hf8hoUP5g3hxXOCtvKl1pTvr7JcyY9knTMTTE0I3zmGu/P90b3+BIT76u+5jqTBYLX3T4W8ak/MRzspV51Plx1OjdoTNSvm7rkWlYdcYhvJvmeEhWs7rqPTnu4q3GhSOQ+NTevZv+XdVfOU3Ff+cb9V9Kp8QvhW/XGf/Fo/q+A4Z6jq1z8d9jsulbOU1y6WuRpZKp/CRfqvO5TzlOZWuxKmnSrurozYse8oQF8cyfPzskTWZI7J0wpCOnOPHGW2Vt8JQDvoI5zpGCB+cMJSTY13POV9kyLvVI32cT+1DnjTLaKt9Vh1oQqPh09G7yoOlddteJmu6PKM99Vrx5YihDlThcMBQVlWjzWu6hIm04yOOVDlnX4sMZfKYR4x1OBjaDuN2nevK6F1ts66Zh+Ktjn4mDO+SW+Qszdd2q/xfOqfc+PlEGG0fkFMeJ+S0pkPiwT0lpzxtEe/SFiEIEWmTBpC3SYRI5HqT5g3cIUrEm+QURU+JedC/HdCs9kel/53e7wG5Q00kXCaelU1yusxbhCj1QGyXcWvN63HSord/ldoD4qXaIt7wGqkQaRZ7v6fkNLXVPleRc71/e6uvw2ap78k9noK3RQTvHrnv5zYxYIS3RL/V+1qknSB02L/t9R+9e0cdLsLER0H6PvEYqZhVZdvx+f5tzjIAx7VK1vc2iQgogC+Wvuh17vbxGj05Jt5WT4+rSsp2Kfc+uYtFw+o2EV7vkdMZxZf3SGRTh8C0wOxB6U9Y61U9IlEdvZ/Oy/K1rRVyUuB75MS5Gr1douGKJ5iujtrbI97iQ2JAHxFcPqGtkbgvU9tnmH4DOeH0kLa2m4Qv3O5juUeiBo7V9Tim4fSU3E+1RO5uOiLe4a0CQ2F2RPjBtMPoMWf3N8CQNlb6+E4YnjClt3qdYRqyeKN3UL70di+71f+e9PJ3+zvHXp0sd0mkTV6w1f+v8Lnfv+8T+pHuVWpdTz3tRtosJz87IVHQ3QJfowjbve6EeOo1ECfAVx7Ar6hMXGsZ2mI8AL75t+GFv93cuf/yHPy3p/CfBD7VIKrPATn19YDc8WPkWxrf7/Oxvdu9jHLjhNAwRLm5S3BJwWzE8rsEf8aRtn0SuYecRKny4t+HhN+tkpPkFkvdXXJ6pO/Fi7vkJNIjolAIFxU3T2meL98gJ626VsKnplAZFbhNTjVcJZcFwzAVS2N+kRa5Et5GiDZ6G9Ne5jahuXUSHdXQUqHcLGORDtfJ3UmPycmW0qXrd6/D0YySk97eUp/HtMNCuKibHDC8X+u0/+/4K5wcp/zO6N0B4Yk7hO9tEWeDuoFye4+25ifklEllmHBcJGu2R+PZD8n6LZH77ITVFsM7WDW45FkaZcc0sqw6mbx5nxxyIh4edBg/JDJvSnjTUflbHj0h8vK8Z5OGL0Yk90mkVh1vp7f1Fmf5w8nonXJYfW7KWaPtmCj/1WicMuShG0Q/EbY6Kw5JxoF1K59wPs5fPJ8jbHIsh9S7bvey98p4lX9bxFkr39rq8NrpbauvKA+VEfLxRXLapwa8PGqJhheHvdx7RMfQwSCfnqfxpvu97DJndbbH5NRJI8uOT0NNHBV/lI+7RC/1OSH0sN3/Vod5RPBceI9h+w5Zs/uEHpcJb5kUmGyWuS0zvOibAsfbvT11wA948vOJMNoWaIrdtP++SpgAhOleI6HkNRpDfUhTEK/0egqMi7TEGg2c+V7nORow75V2fHeRKJiPejtrxBi7RhRgFZoJQ6VhmaZbnPa+ReZrhPh3ieKst8OxX+5zMTWvpmCskRTQayQaJiEfl5/ar5GVq4SRr/JR4hEHvZwGhEhzjXgfDggyy7iMAFwjnqxpn7dwPKSFyz9FDMpjkh75mKT3TRkStsbrtT5mlRffLRGh+JikSAqfGmr/gISnNaaOezkN8erhnjBMj5R57RIcvTqjLuQemytl7D4qZq6FxsEWSX99ihjnGqFXSHrkZWJInfTxrTH0hB70sq6h83I+GqhHpV8dG3pY5zvMXL/7vf1niXfO9pz7hLPpkRWO9H5qZGPC0OlA6WNKBMxi7/MauQT5EsH/Z2i0LPO9Rjxx4ssyDRc04lQSHJswOyDGskZqpeH6CDMZtLRZleurRJHRKXKF0NcR2e+51mG20ed4jcBafjYhvEvY7nE2PVLPuzgrHcIwPVLaXCH88oghDzkiiq6wkLdIixOSPqfS73yqA2CBhse/4lcShDFlQWSSSCbEO/SN05an8vt+jC//hR/m6V9q7asg+Vyj8XCdcPZ3qTcrfxHHrxE6/FQfyl2CD2ul/JUOO+F9hXiWVbav9zaEfzXaFnu7pjjquLtKZNASSY886WNwbWrdp8jl8eLmJcLbD/s7eaaK9SXCz5Wlfn+f8K7HBUbbJHXNvsRnx/eY4KZljpmdHvmIJnflpRDjCs7KTeWpcqDKfHFdvneRRj/KG9dIPNksc/Rql9Py7jKhZeE+LbDcZ8i75mlr8iyRM9UoWOjtPEN4+Sq5dFl6lU9dIsq7ZKCxern/rU4kX7lf+pTmlMPPEppcI1ES+bOG1uPevn3KA+VP0vAuwZkpcQ7WPqQ1jYMJ4d9GOdb6jzrLCsGxZxnK8PFzQgxocVkZsEl4k7j/cZG2A4Ij9an/n/Sx1TWE4KD4uNnnco0Yx8pJebE0rNI/To+klJV+dBiN5dCU8Abx+1na2j5F02Ed36eI4SYtXSYGdTXa1ojOpx4gTl0hjh9l2Wkp55ockjVQt3Mt6nUpY53tmFx1pA7xAeEtnyLpkdLcMwSXqtykj03H/hFD3WS/f5O31+cRbX2ulrlbx/VW9tf0yMsM9ftal/6/ui99nq7Pk55PhNH2CPh5mpWuV0ikkhlI0Ac02b1JA5JO2nvEgHmTBqxpL6cXfJXcXaF3Usvbd7t9TDskbLlDTqRR6OlRNXzsN70Ve+QobPUQGbieuAflm16pN4jnnt7Wd4nHZkJD7MvEm6BnqDJ/GBL2NlEGvA/i/d7XDomAvU/2nZ0Qpr3d52Q/+yTlYUo8Tlvk/h2IV+NOH68GX4XtCY1YNsm9HXXc92hejimJ+Lw7KrdD7nhbYHgbPb2Pt/vfMjEVABmVyqRMpHpGtmh4qldUL84R8ahUJWW3l32zj11vpO0fkDSbDeI9mhDP1maZz4QYk/WeNpnrJm1t9IAdE0W19uvjeHbJ/ULCUa+kxtUdco/htI9tZUZ7u7R10SCkt7tVyu2S/H+FT6UN56NSpPG6Q4wI8VEvoWNd6/N9h0RCD3p/Mnpx+4jhPUkav3Pk/j0Nco27NxnilI/4AElrOiH37xwSA/sBiTa8Q05T2yaCd0LulttmuHbyM1MzqkNAT69wPCX8TC/s5fKu4re0uUCEjhEx1+SI7PugwELjYJ8ILmE7JdF8x/So110B/sjfg+nPDk8Bk/e88BPDtOPT3k4zwn+Y//h/AX/pvwJ+hMYk9ADN8dGGi995l1zgtAr391rxHXJ/kdHFDRodik93+v9vk4iC873byx8Tx8FKn6uGx5TZ97R9QOQLhKY2SARKmpcvb5Io6Xqpu09k4XxZg3XC22FoUB6R++R0cq2S/Zbv9vqX+vxUFjcIr3DtNYo0RnVgrTKk6TF9z/fxvEe88JD9JvKsBc7KzWkfz7vkPqydMo67RM6JS3eJwjsl8nuNZFu4vm/R1nyBRq8aBvf79wkxqJR7c2Svab3Tj/J9qcBPBVn+o57jnN8mkWlpRdzXKIAYfUcM75lVDt8mkb19Yngb8Xua4LIOAvmKjhh5lnztpLf/PjGUx/xUHH2fOFSVGc+Q6PYWiQKeENmr8TaL3/rsknvaTogjz71u097ulNDBkx71FGWXDo+qZ6gjaYT67YihjlVxULzVkbdKMm0g0W3nqvx+1OdX4eCajOGyRaJS0OB9l6ZX7ZO9Z7eJA+qIZPasEt31LqFTx/iwv79D9Bnl5EHvb5HcR3aH8MA9Gp1XXkj/ps62RPRhnxOaPqyO6Tujiepsc7SzGWCYQaHNUB91mGkZN4R+7vQ+66Mutl/gIe5tEsevMkBcfKfMTSO+Pm/S1niJ3C2ok+FJzyfCaHuK5pmEtglPL+AhbTLLNEDcIgzoCgHgEtnYuUJClZ9haNlP+ju9ck/3Op8hgHYc830clwnTtP8pSZ28SNITVTRfIuFwieIWQcgFwkT0wL3Qf2/3uX2mf/+AxlAXiFK62v/eJnceLTBMYbDtW/3dMoleHBX4KExu0TZ2/qan4U8+hD/Xx6RBqeI6X+alsH+RhKlVLkU81+YFhhdh6k0zZO8BElOGkbbrfWwaOcsdPjcL3CGHnEgkFd4Qb6SErJB/kWxWd47OS09YTSc5JYeQXBn1WY225T7Ga4Q5mkrr+DTaoOHeTWJciNsabXou1/o43AakIL1ClHuVl5tk07zC0PloZC3T1uZyh6VpqDJXPaEv9Lo7HWYqZj4a5zof7OsywWVIuqBGv4xunB4pPSjQxMNVcm4FRHAuMjyo5ZjQ6y4N9xcYXgS739uvDo+b5ICZKtCMoM/y1ppeVXFPGjmhwd93rg/Eq24fGsOXCE8SFsJaHFvt5W6VcehggShX0tK1Ap8H/dvVUlc6FM5Tkr5qH1Uxq/S1SuA8ITh31Pu62uej53uXpOtqwIoD80QJu8bZfSOPSRTq/l+FZ38L8HN9YH+IaAo3CjAczASePYIXD1ub4uEqwdEjGryFpRvTnR+En1nmKqEH+e8tcuCKqUwLRMl5gXiHdQzcJI4KvdfTXkZcXiAyEuJI00jS6Xmrv7dvccX10ymqk+Jp4NOENp4lXmv5kXRSI222J0/YJM6lyg+VwVU2LRd4Ky9M69rlfLkpf1kjh8DosDjs8LHtI+L9v0gOUZA/mi2hXnGDtubT0v+UYQr3ZWLIrZb31/qYqtIIMdiXetvy8v3ShjigzN0jfOwFElFYIZkQJzRdQ11EnjPX4fKZ/n6vz3VKomvKszWCKyqckw4HcWqFGG3HhGYv97qPiNErnC73Ob5Y5iEtXyMOjWcKzJSzZvAoC897dNgfEiPnBtHxdmj4f73M8UnPKll3iAFUx2BWy80+v+VSdpVEnNQBPk0ys07J3vJrhIb3CY5AMnUe0vDlKkMcqnqPj8bLi4TOrpGMAPHsCsl6kD/Lu1bKe3F30tvb6XU9pEfcUY5eJXLsUi+nXFxiiGfyAlMp5QW3OBtpczvKZ8o7+eBN4ojRMXyjv9slBxLVR6fEAqERiHPsWc5Guowg3iKRO7enqMdVZ5VjVDdcpq3L+FCUXdra3CJO2xcYyuVZzyfCaLvAEGn9e4yYvvP33Ix6c6Pf86P6s+qO31O+U37PMczJrWMcj2E8zgXOzm/8I3OofY+9KnOcbX88ThXQWbCZBR9/vgP86MOEtR3TGK4nIziN24UhXOZHbZyM3p/OGAsz6o3nMQtO5639aanvzwln12lW2zAbbrP+hmEkosKvwstvJ6N3s3DyPNgwatfvx6P6CzPqjtutY5pFV/M0ox6y32QWbdUxjeEC3xuOwzDyMp7zrLHNGsMsOjyPdmr9MT84r7xP5VNPogH/rmmis/Bt1pye9P+svjnney0z/maQ6jy8HuPJrPfMqM8538Z4CWdhNv5+5t0h8E/Qjkb8Q3PwN0+bC/8BzTIZD2zue6e1J8FhjGe13hiOs2h01prOki8fh+ez5NH4/3Efs/DV9Xg8ejfmzWOafJI8scwpQ/idfkx7nNPOeevypP/HuDVut+JxldWM2hujETPen4evT+r/PHniz8no2yycOo+Xjvv5uL6U7efVG7f/JNjPGt+T5v4kGJ33zBrHLH7vOn/cM8a18bs6xvNkU40O2+95azILrxn9nrUWs+TQx9Hh+Pspw/6Vt2P+8KT1+Lg1ncV7zqMtYVfbH/NR343p9zwZNWvtZsFiPEbfTWgnTP4MLQr3JBlX/z+dUW7WmtU5jPn4k55PhNE2T/aNXKJZ5Xobj4mH5xmGJzxNyGZQIwJ+MyKzQ7zgl/q7ywxPe7lCizD4P2TT7CVynK6hZoiHbZVhatxKL/cBw5P7DJufkisMpsSLWcd+mVjb+8QzcJl4Ra+QNEMjYDXSplf/mV7uoPch3PS6GB15hmas2Z7RG09l2ydeEcP3T5M9GBMSKdshqVeHBe5GMw0B66lxL8FOmauPdZ/uMLtI9v0tlLKOfZ62Vs8wTN/rjnbo5R6T9BjT7fTaVPjMEc8JZB/VGsEH69rfQW+7jv2EeNrE1wnxdokDzxR4Twijq31OOLunbcLQk39UytdoDuTyznmCF2v9/0Pi1Z3v7V6i4eP13sYvkD2NtjffYSpdmQrgWs0ROtbrWsclo9LDt0bS1g6IN9II6COyR0L6c76XyD4W16RGIo00GAW5OOrXCOpcWQfpvwojnyOGnvC18m3Sfxu1mDLcr2Ck0YjFEaHvyySroO5p2+n/j2Grt144Vryt+CPOjNfliOEpZvJgI86HJDVsrZQ7LO1MGOKSdHCVrL2CasLsUxYXyd6+SZm73nP52iXIhoxN4F86ha8DPwz8qjn45VP4vUT6T1rZtb839CYLb9Ntn+ljuUhoeEKcMb7bKbC4yDDic6WXFW+d2xHBVeE6T/ZzG0lZ6v0IV/nZ7qhujT7JDxyf3ltl3zMkIvI0OSxoQvBjlSYLxZXHpcw22ctao4eHhNYOSnuWsQ3nD7mKQb6nvJMfVvk1lpvKAee5SnBNr76yWw/6ZULHJwx1hopflccqy8XJvV5u0udTZc4cWZcJw3Rr4WQU3X5XaHxMuhBv5InKWulgp7SxQ2S0dG6/Vdfx3eX+3mtTVkjU9Co5wEq5LlysM4607XF2/6pwcizypyOSFjrpMBIeE5JZdUrSqy1XZfj4qRENadMxXS4wdT6Vd5+WdnynrlV5qHhLqafOI55BrqJSbl0i0eAdmrwRp8UBadgsFfmE8ptS1rGro4yN0Glvx7LOWfzdZ6gTPCa6mFtBjE5PCG+8THSgKl/lMzr4J6W+9HzY4WVWm/LGeRr1UgYKOx/pa0L46WPCf54p8HAd1Ckd7yVCh6bXq4eO9ezNMkf6t889D/vvthtoXHN6G267sG9pUzk6ITpLrQuRlY5TnUh6fNLziTDaBMA+MWTMld4nqQZmvvgOhqcRivBTsq/AFBiJr7YxT/LhfTft7T4ixFH73y9tSlgqwPtEsdjtbT0qfSjE6hwkPtMh9km+LAUGKpxzRAjulj7HRhtlLKcdvoa/Z8HHlJH90s4O2f/lmEV+lVrH7hhsTzj6t8qmzItSV+K1j+pxsa74IWPfGZWr6+zYhTfkdKkTst/omBwmMCWpQCckDQuCXw9p6zkl+7YOCcO2vHCUGQu/A7JPQXibauC6zxEFYVr+N7IlntV1Mt3Rbyr/u8SQXmKYOjft43pIlBFx6lHpa4nsv/xpcu/NCsF/yF41+1AoSnO13LSMv0YlXRtIukGlt/3ybUzX0scSUTIqvcrcK3z2CZ8RjqZzHJQ+IGsmvtVnh6RCqFw6V8e9Q/DtuNRzXSx70MdfeZK4wmhM86UvcdRxiBvS7JQc/GKdqhDtMtxHLL3V9fOUQfdkLZa6jhUazxC29qsiLr4vEl4kXaqYyCN2ieLlHMWx1f73r6hCY56W1/1fAP/b0yaV/yDwZ4Af5yNmJD9xjnAW3otkX1/9Rnknz36KHG5T4SPPqN7+yuN9HI9pTA97G45BnHJdal3pTt41JXhRccV1rHJVhUsZJJ5NiTNSWXNc4LVEDOuDMl9pz0yPsdE2z/D0SMen7Ba2jxiesLdYvklPOsDqmDXcXBf5srzc8Xqa6C7BVWlPnl1l+bSUEZb2VSNTO7S1dvzyMvFafBfetc9HZP+uRpBjl2c4L/n3KUm72y8/80Ru+q7SqI4r/35A1lY5vkscDFNCg/Lsg9KHsK/62lKBiX1B5PfD0obzrfxfx2KV4ePHOVV+XsfkfOWns3h3fcQv+fN5e9o8/KeWEY+X+vwcVx0LJCW50vCUIZ8Yz2ell5sjjvPxXCotOZ5dGh3vEr6yQtJdP2B4SIpGV4WBuD0lete09HVcvkmHCzScGuOc9GGbFd7SWpVJ6mwQGeQ7cUt4VN48Hp+PdOP3KWf1bHUF+3zz3RZlUy6clm+Wd53lWY5R2atsro4Cyji0F8b9n/d8Ioy2v0+OQD4mEQjzeg9oE/4WOQJ8SpQBhYUeyruEaWwSL8Yq2Wi5SY6dh2yWrwrVHsk315oXqTfJHTky5Zqfu0c2Ly71sUtovpeRmMe7RNuwqbJC72+DILmeCTfvrjPcA3Zafi/0fkWa+73uu71PYblHvHp3S329fYcMI5Yqg3pIHPs82RArXHeJYNojHjsjMhptW+SahMqQDsimTvvcJbn7lt0hIWwNnMpsj8nlqBoiMiqvOlD5X+llPHnuhIZnVfn26PsjWu62Xmv7mvax3+/wdh5zJC9dD/JG7/+XCsy3yUlHc8TLPSHH0mtgQpil8Dzu7T1N8LIaoQpZFX09xjsMD2PYJYfQbBCFcpkhg5UJbhADCUJzPjLVTYaHBY49oFXJrQqysNsm+fimdrgx+E6Bi8rbVi+joaxgVOG0/C+RQwpcb+d6n/ONNnHFe5CEySYN1tKhxouKuPOvwt33632ef5PQmfxshRi1lG/VkNYIdSwP+jilzfdLWWlzkaHCYDbBKTmk4jFDfqYAO+jj2iLe7ykxRqqDQa/xOnEuVMX+lPBG5y6fkM98H3Blg1iqNQT6ewmyvA78ifbu/sO20Vw8rDi1QaPl7/Sm3iUKnzQHUU6UF1tlnOsMBfcDhiky4t4xw4NIHhAF9h1yUqpKofxjixhV9D7sf77/rwNsg6y1SoXK2ntEQRfHxYF1Qu96qVcYXmPj2iunzcjQ6bFaylTjpf69RY5Gn5RxbhH+NktuCqcdoujJl4/Ku3WCSzsMHTce/CS/UGl7kxxIsUQMFLMxIHrAMZF7jn2VhjeVLiF8f59kckgj1dH57T4u1+e0vxP+GgVbJLX+lOgJ1Yg47PMwmndAw7MdYqxuE1zxMBDxR75cD086JQr2Hm3NjQwdkb3A6ir7vW49JXCTnFK6X9qC6E8rfPxBJDpPNGRVmg9peowwlXd9nNG2TfACwlZqvbHjaKmUrTqWepnv6vxWSHaNde8xNNrEZWneMSwx1Ht8tvr4ZYHyeWlJZ8Y24Vvq166LOuA6cUao307JOglbaU4HiNHzLbI2Go+uU02ZnPa2FgmtjQ3kdYY0dkLDaXmd8Hivf9fJsU/wqD4aYFOSSUMfm9fubI7qVF3MNXN+BmU8xX6FrN1d4vhWNtZHOH6LHI60NKP/8fOJMNrmaQLqgKTDLBMGBAnHaihMSpkFElJXYCyRo3lVlldJuFqmstrrauFWQlJJPiztHdKQrEZXFggyWu6UeFcWyPGftu3v+d7vZYaX+631Mkdkk/4qSW241L/rEZV5q7Dbr+VOSx8aumskwmRKWVWyTXHRM3dMFA8Nnjr2eSL8hOMRCfH7/wlJlVCRu8TwTjqJ1PWZ9P8V8JcYepxOGEYQ1jhrtN0v32Xkl4kS5lo6L8d8QhiOeHGJpN/sdzhpfBspuEzwrabJLBWYVcXWeco89zmbSnaJHHjg/E5JKqVeq8dljCpAVfn13TFJuZ0n6RKugTQgrrhWy6P2HIvGhMLMupajlKtG8thok9YVxCqYpp4o0FQOF0hKyDZJOzgk6ULVQ16VsYMyNmGmABEe4tQswV9hZjmF3rSXWevlPiAKkGNa6u/0NAszhd4agbX8zE3PFbYKZ/8/Lf9PGNIho7/lGwoYPYTzJNX5iNxvKD+znkaJvMno03GZj2V1rOgQk49WpUX4jPFMfr/W63/EtKvnygU/onkD7/SG/nN49ptw5XcEz4Sl+G3Ki8qqMJsUWDkf4e04l4jhI64cEZzRCVHlFaWcPGtSfhtpuEzWptZdIKcWCwLxYkq29flO5XqHs6dHrpVv0tJxKaOyI7h1DIoPSyT1cJWs5/Ho7wqLXXJoBQSPLVPl5n4poxyQj4rrwnGJYRRhQpxxGqqXyVYJSMq3/HCR0KhwprelwSVuzpW6Om2qgarRNiHrp8NQua08eoqWgqestM398m2fpBCrJOqgmSc4ulXGLP+r6a2Wm5ZxKN/ky/JLSAS/ykHx8og4fapupWGqbHB95GGT0n59X9d+1qNclg/Vee8QA7OmRz7p0QFT9YoaGYJsAaj6JgQHpQMdB2sM0zcXSGrvpMxZWe//jxlkdA/0yzo+n4P+I6/eK7CQ1tShK87YpjqzayXuKl9rXfWsyWicS5ztA5KiqhFejc6LRAbO0tnkJWvlnWMS94SpY7LfStuQ4AUMryaBRH3HMtLxP2S4Zr6vuq9wVLdYLe/HY4E4Q+1P3Wbc//j5RBhtv4J2gsoi7TSXK0T515t2SvOsTvv7qwRRVoDnyck9UxpAXu3/C9S1/g5iqFwBvkyYjafkiUSVwbxaxgRZGCMG0172VeKx2aMx2i8SRrnK8CjvVeDzJPJ0tYzzgEQJrpAc/qvEs64gkqFWYvy+/m6DnMamwfWF/vv9Xk7mbDvfR9IjjURqGGj0TvrYJ4RpLtFO4aHXeYGWUrdZ+hD2G308z5HjiWWE0E4I+iyJUqz2eXjKlsS/wVCxr/CGCHSI4fq4j71GohSs9gPx7uhNep62v8s9Isulrn1t0XD6Rn+3Q7wxS7QNrhK4zO5lgm93CXN2T6TrP+3j10g8peHDAsNjvV8mdz2JZ85n2se0SVsbhdo6SbFSOb7ayyz19n8N2cPjs0MziqUJlZlKc5BIkXjraVoKBj3738fZo9invez3kWj6hDDuq7R10Th4tczzGomwavDtE3zTYHqZ3Fe1Q67ZWKbh4izBr/dOo+UVhpG0vf7umByrTh+ruGNU7QENr14lDP8LRFhYXgXx5f5eZaumwJ4Sr92NPq9r5Z34DUNesk+urFig0ZJKsYZTpS+jZSoKV0nK1P3ezxeYfbm2fcujF4hy/jLDfcbOcanD7s8A/9YW3NgKL1B5e6G3820S6XvmBfh9wJ/98N+EX/4D8IfJcYev0+5WeRP4oT65n6ct+k3abvQu8Q++CT9GlO6rREld6nB6lbaeXk3i3JRrXyDCeZuc+LhCUguF4ymN5txn/WKpu8PQbt2h8dbPMaT5td7nEVH4qwF8iZyke0JOyNV5MSF3e62Rtddw/Ty5FmDC7D1t85y9XPuk173S328wjNjNkpvO+So55dDo+CGNPztvcfZKH5cplcc0ufIc8c7vdbg9TzzjnyfGfOVpzlvFjN7WFUI/8jKIXLrZy2goHdCiLDt9bp8nnntlpfLVddapfUx4zZSkNc53uHyBpCN/jugnV4mD4Zn+zeidsvlFglPyLI0gjbO13v+U8NMpMcwudxjrBJr0Nm+QqM+1PoYtzu5pu8qT0yM3yTUH4vWtPm8Irtwi/PRJz13iAIE43HSK0+d/pbfpnirLbhCevkBODVwlkVHp7Tqh4Slnr4466u9v0mBUDf8FzsJlQvDVsp+mwVrnn7z4OtERZH8aH+pIGm0ajFu97kv9/Q7Zrzgld+9t9vcv0dZGHeMZGj+XF86TewXVnV5hqPs9JicSv1remRFyiziHTHP8DLmW6RWGRpZ8Vdn2EpGf+/3bNaKz+bzTx/0KMYo3e9ufJfqkskpcrA6vz5S6PtoSr5DslJdp6/OjnP98Ioy2I5pw2yT5sCLVlAiu75KUI5VDU9NUlBUcCiyNjXmiLNwld1rs04D+Tn8ncXo/Sw15f4dY5BsMo2DzNMb1VC+3TVIOFvo7vQgqxipFGp7Lvc5BKXtEBNl+H48MdocYh1XprYLxjf73feLtUuGl/73TYWtfx72dN4iiYX8ah4/I0ap6w+fI3W8qXjvEkNSrrkdzk6SL7Xa4CBMfvX/vEuamV6kyU1O/ZGzfGbVzTML+jvuUpqOZJjpei+0yhk2yZpC0pAMSwre/Y2LY75HUqv3Sxxskt1wcfZN4djeJcr3Y2zH9z/SlamwIDz3ox+QenEfk8kfn84ikb9VI3VaZowr0lLZuGq4aJ7YHQyNQj7bv6zrsEJoyimu6lXOZL20cEGNGepz0+vcITUvfOyQ9coXh3ouaynNMFC8FKh1mGpUPez/O1X0H42eLODRcWxUpDbo3iCdXp0jFB1NKpiSF6h1y15+wFldWGKZ1+k2hK91sE5qdEkXmlOA3xImxRBQwjU7vwDkqfVT6MgVHXrrLMCVHQ1LeJE9cJfynGjaWV0mteLtB1voucVJUHjjPEGcdyxT4s8Af+aE/AP8M8B8Cv78D9Ls0JvOAXNL1PtnAq9eAti7fLrDYJfh6t8O6KgcqUa6D/H3S52Uakw4cDb1dklYqjWucWHdK7hx13jqD7hJl5iGJ6LmOx6M6h+XbIWejcXdJSpsK8EFv580+9m2GRiSln5oNIo97v9eV1z2gpTqpRI3lpjSiQ2efXJXj3FS8XQudVK7RLrnDTMeM+5V1HMrTTaE6ZHgXpn0Jd4hMcPxjo22pj2ebZPAckRTFhwWOG0RWSv/rBbYbhG8/Jus2ZRjRvFveOT4dVRqX4soew71zK73eJsN72uRjj0gKbzWcdspvZZFjXybpa9KuDh8V+FWaU3CsC4yfBwwPUDkga+F8dLRWXeG8R5mrQfSIGBg1E+Sg/61eCEmfVce6Q7ag6NQyMi0OT3rdfZKqXiOb4tAew0jbrLm8TwwwCA3vEqNax7FOC3UycWqJtl53Ge7dgqyZPHVKsrSqPuZaKlenBB9gCM+qv2q4jXU2ryBaLe/kj48Jjm4U+DnPKjfpc5IedsihRJCU2inD/YYQPvUGZ9O4qz4p7gqTdaIr6XCsj/29QXSntwnMz3s+EUabXijD4p5stcAw8jNhGIa8yNDzPCEGxBLx7GhQrJZ3S6XPWk7Picq77/UAiVSWqx5i67nXaYXmiX2KoedRohFJV8rY7VerXI+fSo4/l2hIu8zZ9EjHskBO+jkofTj/y+SujEkZs4qfewRl+Ick0mbfjl2Po0xLBDWFbcJwP8fF0ucxw3WpClhdM4nUuo7NfmqY2u8+CljKHA2Ruwbuy1BRdA1OaAz8pMBPPHVdZDr2pVOhpjO6NhU3j2lrsEJwWIGqMWMfE+JROyJG2ymJ+KoQHpX+5ximEJwQpu/am7qgQFfJdL6X+28VxuVRe9BwXVoRFuKH6+l6i9Piu/jrI+6pxMv0pUMNBL2aiwV+wlV6lXfYngoXxCMq7VRvmXB1TqaQinM+s3DPR8EwIYaTCtWkwOCQ0NWYT3lKKwyFrHRQaaUqx9ILBGcdxwmz12WpvBO2l0btzTPcb+LaVPjNE0VO/FHxgyGdSTumTfp4orBzFzYaPK6LuF8VmQnhZ+KnZZkA/ynwp4DfQ3OvntLCZ/dJ/lgF2jIfecPq+tQolOM5JifGauCM0wMnhL9o4E+IbLNd10Jc3hvVheFBOyfkhF334dYxy5tWiEFWeaowk79pcE3IHtLal4agYz/obUkrlHLzDB2KUyJ/nc8h2ReyxGy5KR5aV0feQoGbcJSOLxa4HhNcMA2w0p5bEGoWgIarsJwjOoXzlP+sEH4CwyiJ63C5jFfD1xOn3Rsjvkx6vUr74vXTZJ+oKOpY5dm2AUP5Lw8QV0zdFq7y5SnhGRpt8v/LnHW2aEg7hopTtj3W49xSYLum0z0p0nZEDKvHnNUXqmFt+m3l3Sej/5V9S+U7nHUiOxdhZJlZOlYdSzVKJwTn54lDXFktPCwLT4607Y3Kroz+N5OsrokGdR3vMcnGgpyKLG6KU9LKcSln8MRyOpyUj5cZppva9yKhtaqziYuOWfwbywANI4jzSR58sbQnfh2TU7Jdg7ouE4Z4MeUsn9KonhAZ73rrRHRu1p0wfCptqs+ZQfOk5xNhtF0gyKgSAzkhqhpExwRpF8qPwFkqbVSFAIaAXJxRbn5Udty+/S+N3i8QYtMAGJepXoSlGe2bNuePqW8nM9qpPxUOxwwVF+dXjYWqLD9V4Fvnbb/2cVz6EZmFYR3LHMNx1TEIYxnlMkO417WzH2HqmOtcfTcr19t1rsx2rvy/wHAthE+dj0IbGh7W+VdYUurMgl2Fx/wMuM2Pfi+X9sf9PVW+VzidjGBz3hjqfDT8Ku5VoSBzrX2f1x69LXHJ+Qmb6u0az8uf6sm0nMqPfUt79j2GU4Xf/KiO+KKQgSgiC8QrXsfrulWcmOWtnbVWlL9lyHWtrVdxp+L4mJfVw4oq3MawFX4a5hXPx3Q4ruvvyuPqWtreSfle69Tyztn5VCdcndd4PmMHWJ17lQ/LpX2FvrQgP4E4YuRhS5SKc8C/Q8th+tPAb6blsZivVgm9MLWKZ6cM19H1XSHph5UXOqY6rzFt1Xkelb/H+A9n4Scs/Kl9z1pvcf6p8q6ORwWrtlf70zgZ84WKHxp+GjqOR5Da9qz5jPGs0kilS8fuerg+OrVqe08xG/8qrT9V2tZxXMehA6I6C2q/lafBWb5v+453rAc4dpjNe6Vhx+caOJ5Kc+O5judd9YAqw6sjSkeQ/LPyOvGq6gm1H0bvNC5r/2P8HetMsx7bl+fV9oX3fCn3cZG2ChPnWHkonKX3Md5W2D41+r/KvHHdKheqY8t2pEPbGs+l9j/HEBZHo3E/RWhxTEdH5GRYSl+u0Zh2YPZcx//XNahOjDEtV51CJ95ieS8dzsJjONtnbU8YGHxYKN+rjlz5pG2Kj+P11ol1OILtWCcbjwVmz2NWufHziTDa9Azplb/M8OhqvQ6XSlmtaD0El0herm2tkdOS5kvbT5dy1SP1kSe2/D0hKYlrBDn0sGn1zzPMyT4gHpaVUV0385vaNR6DG2chnseF/r7ejXbE0PDRCyZjXSBe8n0S9VktbUzKt6MyZgo850n+vV6tsbdyQkLTzgFyn9YabR0VeL7TG3OZeE6EJyQK5LhWy7vKiI3oQSKVFfn1FBk9OSLRmCUCeyM2wgfiCT9h6OmudR03ZG+Fc9SjImNYKe+PCD5eLuN2/4qMflK+W0/BfUqCAwd9rvPkIJTq5XU+KgX7o3J6bGu/zmNCPGnSoO05bz18rk3F5VNyOEV1qFRvtcLicilzQI4SXyF3J9qXwl4YTXof0py8Q8bo+jhHU3NOC4w1yB+RiH6NtNdHz7LGwhrxCqpUSYdThpEu5/iIeIZXCX7IG4T1g/Le+apQTcr4amRsrrQjHVLqQo77d93EjQVysJJj851Ku9EcvZuT/v8BQzqQN1WvpHORh1WFRFyv92hNellhssswI0Cj7XJ/d5Hgp319lH5g2OcR8P8og/t9vxqYwtcfx+Vf3MrOZ8KQHlbLO7uYEiVFb/c8ww3npkAZ9aleeno7wntnVNfxVKdEHd/DUkaY6PlWgVotdQ5IpOMy2T9SM1kmhK5cM8d+wDByTylnlgaE7uR7Vd7p6a94BsNtE1UOrJLUrTqWCZEvE4InJ+W7cFJ2yq+MHJipIA1BIm2H5e+qXzh+eZlzt0/Xrzo4/HGN5ImPS5sV/juEr6nI1shHnZvzcuzKqzGuGKFQphtl2SVbJpT9e6WcuO08p6Uf9YoJQ34mrzTC6zrVaMdYho8fryBRT3R+ayTb6aC8+zijzX2L8kCdDVUfqdHYNaLgLzLUsSZEFuyQE9Cl60rDiySNXWNCeAsHGDoxxnJoh8BbXKx9LJBDjJQB4px4WbMEKh7VSFvFqQnRFZWRld/vM4yWKT8rL1CeCKuxzibOKINqnYqj0qYRPmnp6dKe8KxRMuHj//K9iisPGR5K5dgmDA+UEy+8A7bO7RKJ9voYYV4jsrqO6bznE2G0HZM9HVsEmczJ9SjadYYHgfi31vghbdFN43CfnEbbY7Jvyvzt49G7LZK3rqKyS0P4u+TuoW1yN4+IuE8jKtvzGGfzZfV6bjLMtz7qdZbL3CRU+1ch8bj1A4ZHHju/6g1b6O2e0rJ+RCzvZVkl+8rWSaqeusw6ORp4izCWE7JR2rErZHRS++wQRrhNvD77ZHOsY94sMPF5qox5l+HdKZWZ3ifHa+/T9hXUdh6TvVqPyPqvk30FMkQNFxnSCdnSolF6wvAYbutC9rRt9nJbZK+S7bveznuPlpf9qI/bdVEgymj2Se58Ndpk9jskzWWD4T1/GiIq5FOSmjntsHQslbHq4Xd9quC3PWGzQ5R/CPO03A7Z9C/MdAZYhgKfQ9ra7hDFbJ3QtQrLHFEotsg+DedpuX2Spmt7KkAUmB2RPYwPiXB2nPVxfPM0fF0nBr7jlg7FiRpRXCJ7Rnf7t3fLO+kLcpCLgsn3J2Svb3Xg7PbvKtniOgS/YXg4jDxup9e728t8UMrJz8Rv4XxAcFXY0ufjmKYEH52jPGyO8IgNhqnW9uVcNktdeUE1EA7JnVsHpf5HgmSP5H2v0zZr3AWO/m7bpf7ngZ8FfpJcuNj7dX10/qzQcGST8JUqT+YJj7Y7DapdwkOWaDRZnQsqs/LhhVJ32t+NnWsrBFcgl9Iqs6RTFV7xpuKHzlINO+FdnT5VBiwTXlf5uCl7zh/C43YY7oGWj8uzzpObGhjSXDXoNAhcHx0o0w7fXcKflQuPOkzvlXEoy+W77g90XTQKKu86KOM/Kd+US/I770UT3ntkr7xKfNVPhP8KucIEsv/ogNAhfezi6JTh8foaD1OiLNa1NQpWZbq6hTQszxQ+ysID4gTTIJAnrxLZ6b2E4kTV6SovqTJ8/GwzpEGN6Mo7pcG7zObd9RG/lOP7nE3ZVk4sE2edZbdJZoj4o0wVXhrpwsC6lU84nymR8TCMeo7hco/ocfMEP3QUipeu32Ny3U1NTXStqiMWhnsO7xOdXF4P4V3KkU0iRzSYKi/cYXgg312iN9DHuN3H/m55J3+sBrY8S11xylBuQmTGlMYD7pfv0k+VzT4b5DoI10zck++r564SHr9DnDUr5ORKSht7ZF+3OuAxT34+EUbbMu0UliXa6SmeyichSAyvETn7HPEwLtFOkrlKA5oGyVcIo5innWrzFaKMXup1vkK8G7f6mJbIKU8uzOvEYJMJT4inf7eXfZ1sZN4u72QGT5O7dfSqfan/3utze62XPSQHtFwlp2BdI/ey1NQgGb0E9hrZgCnM6GP6Yu9zvZdTEEqor/V579E23+vFkWlP+ly+RLwTekuu9TYmtIyjl2lIr1J3hbbOGos3SYSyEu6LtNN1TkiU4TlymqEekXeJEF/tY6/tHJEIwyqNYD/oYze0bdRj0n+e6+VPaRvUNexu0U4YukoMPHEEsmaf7fOCEKX9fIl4qpZ7H6+Qk71ul/ktkbW/ylBRU5BeI4xSo+PV/n6Xs5E2FZd12tpc6X25yXiehnNXgE/1MiqlXyBr7+MhKXra7OsZgsvQcEBBKywmBH8VUK/1NqZ9jOtk389rBT564hdp63WD0MHr5KL6G0RhU+macvb0yFd7Oyppd4n39CazI23e5yWDfo0YCEsdzq8RniN93iS4c7fDb4shT5KGq6d8iXj9XunvT8leP/9/TDa43+wweK68E78hzgsNeJXapQ7HE3LP1xFDfnaHGKiXCM5JB9dpvEbeJB3ppfcgDdNJVHhfZYhnCv4l2gl/SzRvpX9XBflWgcUeTSm/QqNJvkwEiyGurxACvkojov8j8B8Av/6X4P/+a+An2sD+kU34ymFbi4M+vwlZG+Fzn+Ex19UgfpVGG9DWfNLHtkp491WiHL1Covwvlbo7DKOVWzS8+DyhLfrcv0jkqg7Auf7tUu9fp9hN2joeEa/2Km2NniE0o+GhrFgn3uLqxKpOIPq3t2lr+mqfK0RuaozPkpvKgavkBLl14qDy3TzB2WskmuDhS6/QaOKY4O8rtJNHjUZ+mRyuUHma98dOyviUCV6ArjMNsn3jBdrJyrbxiPDE7Q4LaVDlXVnhOrsWJx0+Ks6LRFF8kbbeJ73d7yO4crX3sdP/9uRqHQ5rHYZmb7xFeJZjWiK8fZehsbVOdKeXe505Evm4QU6PvE5Owj4hWSjqZlWGj591cu3OUe/7c33ec+RQrc92OH1cpO02Q/1jjxhI1j3u4/pcn7848ZDGw28QOlml6T6XaGssXV/p5aRhI87ikfPZo63DcwyjtbMibWtEj7TsTRq+6UTYoMH7eSIDNxlmeqn7nZR2NTyfI6ctijuO8zli/HtS5Lu0NV4nJ6LXSJtrrh4w1tmkywmNPUPwb4GcLqwBCNEztxnKTYizQkfRy0R+qgcIn/qoa3yJRMHep623Y9ApYWRZvqjz42XORtC0b75CdONXabjx73H+84kw2h7STlQ2ldHw7BFhbAL8gMZE9OxpdUvAS7TTWFTQXEBoi3+fpmS8T8KZOzQEWyeLv00YpUqGkbdpr/+YYVqPC39ElB69a0YDoHlFVJr1CnrJ4RtEgYMmWL9NQt4TIox3+1wkYBX46pnxnQrVCs0AW6JFozydZ7/P5w4RrCrWeugUCEbK3DCtl2Guz00YQzxdt8mpQqcj2J/SCP1eH5tETa+73t9Py/hvj8q5hhAvYmVsx73OaYfflHicjnrfrpMGmOHsU+KN9cSq75INvRsk71m4TWlruEYuBj8sfVRjYZ2cfDnp3xU48+X9pMPsl0bzs40Fck+Ua3iZeCzrnjYVnB1CC3N9fm/N6Pc2w+iBjNZnn5yUqQCqHnofo2yOV3iLV7WctLRNIgMrJEIro7QvDRnXeafM8zLxcms8aNzqgfRZI6k3O8SY17AdPw96nzUqCsGButZbJNpwmxicO+Skr0n//S65W1BYq+CZcnK3jMOTBX2ke8gBiWvEa1qFyA5Rxg5JNNqID/37HULDwkKlwAhPVaTkUe8RXjQlSqxeRvmonmbhV50hRioX+tjl1xsMo+7QTg47IhfbH5ET7H7Tj5FjRdXOvddkozegB+MN4PqvgX+NJnl/BP7WIfw5Grw1xKUHLx83wrFd5qXRYnRehcJTSvU0ixcTYkRplGz2YVl3nxjXiyQ17R2G8mxCvLhH5GRFvy33foXZHZLiqYyqJ9QtkAwJlRQVItdsltEmDsjjdBY4H/lRjWDZjtkO9jUhCpX84ai8c4463VR490u/azR+pzF7TFvyN3vZeySKpB6xWvqSd9HbmfS6B4Sf+X2JGLWeuqjSO2XoLHuT4cE9wl88MyogLR8yjFi+T6O528QBZbTFNFGdzu+Qy5hPCC7o7LYvoxBGOybEWBMeRhgmhD9V2lsm2yLe6P1eKn07v1WGBvGsZ4dsNTG64emjOh81oI1kPenZIvrUPIm0Vb5S5fWEyFTnvcYwavQWieCdEGNujeC8a2c/VT6pQ0DkS9Ulfe7R8HO3t3O3z+XbRPfYpcnBZ0ofe0SPWyIZKspDjSJl+21yIu+EwF2dUiPrNpEL6vSbZY5ms90tc9rirM72Rh/bbnknf9TBM0+7oBqGpzAfM9RRTklkWEeD8vMDGt4In/pskQidRrpOB8cwJbgrT1RH1Zm1yvD5JZqcVW+T/46Nu/HziTDa/kckF/VS/zGNw0cl4ymSB73K8OLrS8SgUclSmdDouUKiHqujd/4PyYWekGiWEcAF2iKZqliNhxWy6FPCiKrn8bD8XiCMTGZ1idxbc0Tydi+VeeulFtGNVChIIcqNDFdvjEboFZLmuEaUDetfId7+xyTNRa/bKsP9WfMdJo8YXpZa5yOzmJQyevcOGe5pO+nlniECc4XsgaiK2ilJJ3RuYwag8Fkh0ZgrRLHXsFG4OGbLzjHM2XbMGuZ6iY7KvJ8hxvl8Ked6H9PwZI/cbbNAlDuIp/ty/+3JdNVYn5R6Mg3H6NxkYCflnbD3tDcNasc7IevnvrI1hso0Ze6rxMiB4drXZ4cYbfYn/tLreGSyc1K/XiMKQjXa1nq9LeIIOCTRARU24aMT6LD0bRt6yY5JFOMZZqfYVJjJJ04Jn4DQ4RGhL5V9DToF5YTwpH1y/yQMjSPLwTDq4ZiMptjmGsO1GK+LRpv4rGFWedEWuTewKuWupc4OYVvp/6SUVXnZISfszpd2hNlFhnirA+IKiUZc4uzpkdK1jiaNoAX4KGz79w+DQ4sXgXfgv/0A/sd3W8GD92Fl2gb4+POw+CuBPw7/6BX4d/8y/CWiqEkPP0buv9LgVT4sErx6hsga36vwOU5pV969TBuvso6yXvJNaLQsvVbDTLxWtmlMTfr/ftfBd4XhaYT7HeaXC6yVjVeIY9OIUMUPld8qm0zPqvM5JdcTLDDk4xokEOeAcJG2hKPORHnH5TKmhTJHea78R56pYfMMMUzUR6pTohpttvV+aQ+GkdbKxw+ZreMskFTWuvYaq+o9J0QBN4Jrf67fVhmbDhllTC0nnimbnylzqzxLh6B0Y7vyY3H56fL9mKSYr5T+dNzqHNAxv1rqPslog/Bycdn56Kw4JYr4LN49bkuHZH3qGNRJxFnLVjrViaAecsjQWTFhSP/il3jk9gZ1vmq0LXHWQWWdAxIZM4FAulSXUAYIN8jewqcYpr5CUhorHzdN2KjSPNmLeVrKKT+OiM4mLahfqIuep7NNCM74Tp1XWEsv9H7UIdRLfXQYzpG9orarUTuWkdBgu0/280Gci9Kmep189YBkEC2P6vo4ZvsT52fpS/X5RBhtSySt6SbD9MgdgkSfJRGqZ8mkl2hhYJWbezQAfLZ/F8HXSArIPiHmzxJvYU0ZkoHT2/tcGdNYadRaXunlNggBmP4pQoqsEvEqSel4n5bK4dgPiffnCgnJP8swB3uRMNQqGD9DBOk14h1bKX0skUswNeLodfUiqIgreKs37CVC3At9XldL2zdJmoAMSdhOevkbJOJQmdKN3v5+h9lFWrreLYaKmvMyhaDCG7K/R1hoMN0i0Re9TQqca73uaXl/StLMnmWYz12NthVaisoN4oWbksjSSyT/2cjlLcK4VhieaCgxP8Nw/4vC7hphHCovt/oY7VcGdsowinSLbNReJV5JGeOztPU7KeVXGTLEHbKPYEJy/aU5n0sk59w5TBh64en9rZD0U/Fw0r89RQTJEg0XrtLWZUpbz8+VeV4rbUi7j8j6STO3elnXzHVfoeHxLG+tjhAZ9Ev9/TbBu88Sg8W+TClZIvnw2ySNr9Lh2Es3ISltPvNEOGsESgOfptHNNaIgXyt1pU2j0EY6FxjyomkfV6WvVbLXaEJSxA7IpayfJV76HXK4xQHBW+nZOdximGp7SvZ1PEfg+Gli9AmH53s7jlmhewD8ka1kRz7sc//qm4mw/ND7bSw/D9x8CC+8CT8N7P094LfDX/kMPPvh9/Mjv/xTjTl7IdAKzP+utgXuc2S/hvNaILJHmoNki9wq8F8itKvsm/a5vVDq7pU1kH+KF3X9q+x7RAwGnR2Xev+O7zmSHula0f8fG1LymioTLpUyKtRGGiFr/ohcVAyRB8q1WXJTOfAMubz4IpHhL5DUVRX6q8SZqzPkRcIvlAnP0+hc3vgSwyiYsBSGE8ITrhP+POWs0SYPeYYY5PsM77a81X9vE4eVqYoU+NLb/xyNpvbJIRn0fsSZnQ6Taf9m2uEuJWWY4aFJwnCRRGA06uRL4tQewSvTxK8QPPTQi0lv8wbJtvhUL6sjVWN80sf5JKNNZ43ybr/MuzqAb3Q4fVykTUNfPWeXOA9c+2Pa+lV9E7Il5zrZD7/ayynDT4gsf47QsPukxBMdAlOSpqyho8wcz0U4vUQMihsML9dWp3mObBfZJEGAFYb7aCHp3Su97meIbHyGZMN9iqGzW5klr79KWxeNNQMOOiKWiL7pc8zwEmvfTQm/FEfX+/cX+hik3Zoeaf09IiNsV/q5xtnLtV27l4js3OxjUI/b7vM3S3DK8KDBWtdHfUndeIfwpCc9nwij7R+QTJUpEW4HxMOlATQlzA4C7JrK84ikBllewvGdXqHxO9s9IMeb6g0T+XdJyBlC1CL7DtlHcVDeSViO6YCk1O0SxjMlnqKjUk4P+DFJhfGd71WMNDQMy08JU9YDW8epIfqotCMD2y99abQ5d706elMflvKM5lPTI32qITUdwcT6u2R9IBdEVqPNNVExqPCG5P3b9z4h4IPy7YgIJxmI3t/9UnaPnNY45azR9ohseBV2MqjT/t7UTOcmM1no3x8RBuwazxHcUwFyfRcIPRyVMTo+ha0wnJYxQlIWVOakmWmHpzBwHWt7piQcMvQyLxBcHperUWGFovV2CA8wRfqgjPEhiVR7WpPM2rWVXvfInimVTGlNWJqyqLGi560adTvMFvxTQhsnBKelLYWczNw5r5Io07S0U3lSdRLVvoRZhe2UodF2WspOifGrol8FZF3TSu91/fx2xJC+9hiOS55xwJD+5U3y6hOCUxq01fCUrzh3nQ1G6ZzvI85G2oxkuMYHDJWxaXk/R/BbOpSW9ggeOb//z9vwj/zBn4oG/r+n5Z7+bNZRfide1Eib7fo4nsqLNPb3ifzYL+V87KNGdut86ppUmnId58sYVb73Sbq+BtfjAm/LQwwj8WfKWYdBNdpqxMH+djnLxysdVLnpGCAHANjveCzOUZmnTLSNKeEX8gEPyKhrIBwf9X7VCaoMnCM8uDqDfJy7ZSh9Tgl/2yX049iVFVMimyteaLT5M89snj0lOLRE1lheM+1tymNdt4dEp9AxXNdHB4244ZzEQyMVMNTL5O3OV7lrOWXeeY/rpH5YeY1rcFjefZzRtkvkEv1v6dbnpPQzzzADwn5WGcqgusVHPledcLU9jbY6H/tYJNchjOdiH3tERzCbTL5iWzWFb0ruuFMOTjnrcKjzm/a+jMxprLvO4oU4d1DqVqPN9TsiB3XM0tkgMkgZukjofLGUm5J1l27qM2WIe7Yr7a8ylKm1zZ0Cl4ck9bbynEofyk91gROGj7grrBzzMk9+PhFG2yLxbl8jBzw4aRXxmzTr+N8Hfhz4DkkVeo4cRHKbNvEXiddinubZeJHsSzJ68SLJjzZCdFS+HxCvyZRmTYtwbtZVCFlOATrfx/cCwz1PMn4VkBs0b+FbHQYv9rIH5HjgqySsbuRgnXjEj0l+t3C9SZDleh/vfRIJklne7OPaJErSTXIQiUqgazFH9jvdYHhIySOGUarnel8qwycFtosk0nZETs9SyF3t47hH0nSu9XcqYZDcexmp332OyGZgGeYxDZ9kSCsksjLp8IIoIZ6keZXhQSTWldgU5s/1cWySNVrq5W6Qg0hkHjdIOgME/+vaP0vDbxim1V0jDE9v2Y3+XkPEeevJXiWRwyuEod4ljPXZ3veLxCN4g6HHFxJVMNdfWEhfPhq3NVpoaqZjo8NNxdz3S71tcXqfpEzLQ26QDfXSq/DWYNERoqCT2Tq368QzeUo8xM8z+zSzedo+oOpNr44I6VDhKH3dYIg3wr/ypMNed9LLGD2aEH4mfKrTSQXI9DY9rNcJfl0vc9CgcMyOaYEGRx0am72fys8gKaSXel/TMhb5mQLtAW3NLtPwxgjBPDGWhM+EYWRB4+smWctnSZr6Sf99s7ezTSI6a/1HXNChMenlpcObBJflXeuEvq7TC73RX1wEft2vhl/3I3z99/9+bpNIxWPCz3Ty7BOaE3bHhK7udfg8SxSoF4jyVevukGP6PdjqEuHt4vWVPmT73yYOFiM/ft8mkTZ5/WWiCBoBOSXK+vPk2ounicyC80+PPO593ehz9b3pkUsM8eywtDPp43ie7McV/4Wjczzp7RuVX6bhoAcXbRI947ne5juElqvyKSxVuFYZ4sVVWvBV5xwkSrJM9JsrDB3Ki72MPOEOMUakA3nSZbJn7nmiJD4ssJLmnJvRrSNyEMkS4e3S3DGhkQlxrhwRo02DWNmsLqQsPGKIU0ckCj/pbe/271eJziXPvNTn+Clm81sfcUhjfanM+0Epd42GR/PjBmY87hs0Mj7LaLtCW+srRKZOe/vPEdxb7WP5oNRdIvCVhnVUVKNNPiffFu9NxRvDRTjcIMayvGubrO91sibqoRcZXqvkPkFIBs58ac/MgKsM4b7cy4pTjrfqcTrm1Ivvk0yTsc72mOwTfbG8e5/G69QRjOw6P4gMmJT21HvUm6qevU9bB+FTH50tN0l0dKmPRV5jlsFlQh+bhB/eKHV97pBDg1ZoMubTnI30jZ9PhNH292mL43G7Gg5asFMa4H6BlrLy7/RyJ0QhPih/v0OU1DsEeHrt3iIbC13E2zSDQaXRFIed0u43CWO6yzCnfZGmGFjuPjm4wXcy93dpCLJJ9hr17JqPjinXk3JIFIYpCcN6wIrfVFiqt2qhw+yEnLq1TDu1a7m/v9Pb+YU+H+dFf7fUx7NFUsAeE4+k3nuJZ73MGxJh2CfHwZ6QFJqtMj7rVqPNOd0myuSUs971LWJsqNyPvTYaO08RT+LfKPPWsFpheIDGKQ03pjQclfgvjepWJUXG5yEVejw13Ca9n8d9DTZoTohLRGHcYJj7fYlG+J7W5/xU2GXWetG+Q456XmB4oIN4rNJ8mZzotE4EiIrsQZ+HXiiZlO1NyaEQKgQw9HAavd0lxrleR/HXR0Z+QA5l0UEz6ePcYLg3bptGd7dJuqvMeJt45Kricchwo70wO+pz2iK0eZ63VpgZmfxmf79Lo/V9QoceYAThDU+Rw4n2+s/TNDrd6HWFtfxstc/Vtk4Z0q5Olu3+/xHhZSo04jdkL6u8dEqi2d8sbXgQifzstI9DpXGVbEC3Tx1DxwxT31b7HDWsNNpUjjVoK57dJdG/2wxPIvWZ77D8gBzEcETu29H40AiS3t+hreO3aGv5DjnCXP4D8L8DXvnNbW2PgLU/DFf5u9zg9/OP/Qn4I5+nHf/lyR0L8OE9+K3EEIeky+wxPAn4NjnGvirT+6WcdR/SNtDLf1SOXautXq56lP2mQWadaYHZlDg/XKs75BRXFWDl9KSMeZns59DJV/+mtym//xZRaOTj8qxZclO5s1P+3ib7evaJnBPnjIAskdQ8T6N0vg9pdvgOMbyMMuyTw6JcwyOGe9r3GB48NTbalkhK2iWClw/KvL7T5ystH3f4rPb5L/Vxr5NDteT/Hr4xR+Ts2+WdiuSURNp2CD4oO1TyzU7YKHDUcLtHjEj5qAa8upPy/gNiBGvQTPscDhlugbHMKjlg6LxHuSCc1JtOaDreHoniukZPet4n1xxBaG9stE2JDlMjbepIS73/lTLPHRINn5A0Zuuqu0Dkt/ih3jXPcO9vfdb7+NVHxWlp5KD8vV36kF5XSXqk8nOOxtvnS919Ats9hlFe+bJ8a5OGY9u0ddCh5lo8oOG0OpHy0+e4f68y4JgcVlf3Qt8t9cSvKjchBxIJFw0vaHiofrPN8BEvLjK8L1X+KE9xnMeEHnXkfsDZVM07HS4/3/tdpx0cc58nP58Io22FlnO81H9fJcx3izATj5fdYnjkv1G1a8RTvEI75lUGME/z/rxOIkJ6ejxe+4gc+b/Sv3u88Wovt0eUt33OHvm/2sep8bHTx/c6IbQJ2Uxp268SYn6ul4cgv56NZ2mLf42GTAr6RWbvafsSDVnfI0dTU/rUwn+NePZU/DyCdY9GFEZEjsnepad7H0baLhPPCzTG+xLt4LUNEvoX9neJx/AS2eOiEn+LdsS8BtBqh89nGUba7hJGs8LsI/+PiDfvfi//JYZGjQbVJYaRNpXLRXLk/7Ved6XUpc9xs4/xhf5OwbREjpJ+miicJ8w+8l+DRO/sVcJ4l4hh+xy5++iow/GV/t5+J2U+jme9r83VDss7ZF/CfH9/rZdZ6u2/wtkIyA459W1C9rRJc5bz9MPDEbznSxlo66fRdZcolRPamrnPc63A6TrZ6yS/mBJvvriscjEl6RwabcLssNezb72ms5QIYSYOvdbbekD4wmt9THriIEfV66xRCal8aoGGKwp4vXoTGj58ntDK08Rjq5Il73u+w+cGjQ6NgAv3daKEqszJd17rZaTdA0JfJzTBKj5d6u0q4Dd7v18ikT89tfKMyqMXiLIknjn3Y3JAhF7bFRqNKfR9Xirt6Mle6z8vkdNHp+RIaQX8F0nk8Vb/0QCFRGN1GHhowzG0YyUBfuxvAL8N/tX/Bk7gwjp84S9nH8cXiXd4i+zbMHVJHmqWwytlrJ8pdbcJPui4uNzLqwDTy8vrDhg6eq50uLhfxTleI5HCSySSZqTNNg7IlTV3yUEb0opG2wLBy6Xe5ykNv422VKN8iSEf1yGwRcODZ2lrP+n1pOtbZd5G2q4RJVsnzRfIkf/i7xfIdRGrfV475OJlyOEkhwyzBG6SK1nG6VA6Z28x5OMHNNrb7uN6lWEK53F/d4kcyrNG9oC9Tpyowg0ar5LmtmlH/u+SvUlGGz/V57zC8Mj/zxC+vMZw28ARyf54jdD6lDhWxanPkzT2SYfXTbIH+jrDI/9XCf5cYyjDx886TYHXgJ7S9EePvd/sfXyORt/zM9qoz23OplEzGsMpOdL+CsGzPZqO9WkSfV0hcNwk6blrNH58pdTV2JrvY/CQHnUNiHzR2Vmfy70N5z5PjvzXCDdz4CbJxtkgB2BotFXnylrv6x7DI/8f0NZHp9YNcsLp1V7OgIC0+kWGewQ3CC9QbkpjEJ57iVw7o2xfIFekLBJD62US0Khyk9LXNm09XqbRFiRt+Ub/qbjyVv9WefZGb/sLRJ80YikuCssJs4/816B9jThBXqGtzx/m/OcTYbQd0LYE1EjbAWcjbd8gSpyeoE0SDdpgqPAukwu2IQv7Zi+7SwSvXm0Z7Rbx0G/SkOlnCZLqCZPYaqTtMmcjbT/DWY/hFgkhq7y9Qzy6kEjOQm9rq5fzDgy/qbiJ2BBP5Umv5wEt7pvXw7ZNPATvEMH6jQJbvUjXSRqjxsoiw0ibxwcLc49Pf1KkbZN4XqtXTCFxm3gzdknaWY206YHREK6M7Zi2xhAv7XGHjzBW+dfrtN7Lz4q0afAccH6k7XEf13c5G2mzDyNtepxVdoSHTM6jmtcKLJ4iRpteRud11NtbZ2iUOh+F7HYve5lE2u6WNdgjB4foidLwtT2IM2OdYaRt7LXSq7zB8LRO8ddniUR9xpG2VRJp0wBY6GU2yL1C4u6URLX3GUbajsia0mG2QYy6GmnzdNLxY5RYT+HPk32LRtq+wdlIm4rpONKm80ee9PNEOXiXCFphAjnO2P/1im8TReBBgRnkdHsYXop6wDDS9o1eRjo86u+kr02GkTYNE4XulOGeGJ0CzlEHhLjuHOThzr1G2oyQCAPr683do63hW2Us8s99hh5oafFuh+/fIN5qIwFvEb583NswWiWOrALf/60+gNtfhK8Bf+RXwx//u/CdxndVoE44G2nbp+HC2/23YxX2hzTFcMrZSJs0NCWHcIwjbSelHSOm8owJ/1/q/j7KsixL6MN+GY8X+SbCkfmc6VClszqoJKdTVS53q7rLXRTT6nZrxjMaadQwDEIaFgaDDAZJgI0sZGnpCy0PFsJIAlvg0UKDAEnLAgkYC2MQMGva7W73qGdaNV3KIlVFVgVRispwpGIi/DJjIngZT++l/7jnV3ufE/dFVo/stcp3rVgRce/52vvs77PPObE6eZfg0QUxV8qpQ2KVdVp+dCj2CCe8ddralbb3C86/keBpV9oynbUrbcqSdeLezZP0/S5xAuMB9Z7Odwk54tw+oot07xM2hLLVAATUl9vnlbYDQj4f07/S5irpspW2bxR4nZ8FsWKQVx1caVOH9K20mV6mLhaGQ2KlTXrMK21XCTrSuNYmyCttE2JPYLvSdkRHUwaC7xF8ZrDElbZ9+lfatrl4pc3Vjin1/qczOl7LK23w0Vba3qV/pS3bI4fl95jzK2171DboIfVK24gOv/v0r7QNqPcWTwkdOmD5nrZtwhZWdh0SF2GfEIf46JxLewZ9RnS4e4vQh9KAQY0JgdsDYqVtQgQNnN9dgsYsK4zyi8HXLP99ZuX7BmFPzIgrifKCxTvluzpvQq03/ZZX2lyoobT1NhGszI8rbevUK20PCB9A+aId7cqdiwinnF9pc46+Wuq/Szj4Fz0fC6ftEhE98PeIWE42QjcivGzLrBIHiuR3w/ROoZnfDXr6zEST/7cNido2Zk0529TgXKUea267bb+tI5EuLig7atoSTuupKIwwXKbGkfX9m/J3rptxvg78c3SM+HsIZ9W9FCsJV8Ka8W4fZ9QwOL52Dkh1ha/F70oqt9rUye20c+vfnkI4bH7yeBW29teWkwYV9nk8eU776vqupU/bbGm3nfNB04bzl+loynl4znpgXaGehxX64cy8lvGTeSnjuqXlVWqeyf1pJFovj7PlpUHP++w85/q+z+mE4qqlt/y+lUl9ir+VMbn/PDbHQvp+Of3O7bR1xWEfLjJuM9/N0/9tW/NUl1TOcWb6a8tlfl2ksi2s9i/NzIg9G3keW3nY8nEfnV1ED9a9nMrMLqjT4rud9/y7b1xZlv3NBbz0dRgcAz8J81/zXzP4l4B/FP7w1zuD5+foIugabW8RVym0MjmvTM2o5R/EgVrLcNLyoW2tEPK0paX8v3PW4meVCBLOG1y3MnvAef20jI6zfMjz0tZpYZZnM0/5LsuTUVOnT261vOdBR47Jb5m+adqyrE8rS8Vtlolt/wZg+8Y9THVXOM//re4RjlVqfm3bznVzX1AH1jJOhSOvgiyb174+W/5vyyx78jzkPlod6btnOW2tTMjznZ8WDoh56qMf8T3nvA0DsXIpf8hTrZySD/vG5HttkIyLU87j3yfLnDxX4ir3l8u29JLHajn7znOQZcEye8rHfrMOau2GFh953kdNe4sLvrc2U376xue8tnPueFrf4DLL2x019dty7fOxcNqeEql9OcXP6KxC4ax5p0LLdaw3JCIwRryMLixSvVx/nspaxjZXOT/GvKpFamvK+fHPUpl5qr+SyjieRSp/lv7O8GWYB+l7HtNKzxisbzSubc8xkNq23gnwuxKcWbEYRVk04xfeadPPNPWf50Kc+Fg2R/l8RwO7Y8jffezLsu38CusgtZVh6JtP+xGfjjvTVYZ5QY3T/H5ODav1Mnx+9++Vpm7G95zzcAxTmScNHDozjkcBl8vY7ln6lvHj/OgIQ0TjB9Rj8u+VVDePv4U180zmv0wveT4yrWR6yPTettV+b/ueUhuepDqLpj5N3XbM81TOspkWsuzK8mPW/LS4bfG4aOpl/PTNi/Ph+FYbOFp6oAdfffK4xWXGj/Tmk2mgD3b/bnGT22jxmemnpec+HQLn5y7Pa6bNrG/++fL7M2/GvuXBj3VpL7//r8L3DeH7doklcODzfxT+IiEbWtmxoB+XUPef4e7DXauXFpxvP/N/ljNT+vHdys8++rBcn8zoG2fma9+3sJ01bbTzN6Xmub5xt3SZdW/mw5Z3W1xlushj02HsG3+ei3YsGY8tjvP8ZZrOupSm3QX1+DOf9/F0hrFP/iyzKfp4rC2T7bK2jxZHee77nr6xa38tmnfOkbJ7ntrxnTCsJDz4OI8Z78/iO+fRMRgMX8bD2k8ZJ312nkGCFhd9srWVU33jXMYztpPlQaazjNs+/m9pSuc002hrE2XdmulD/d1HK6292dp2pG99NOpYsm05aOq1NGl5y2aeanmxbyx5/BlPH4XuPxZO2ypdzusTujzZTeoTdDROv5tuadO82TGxirBF3GF2nzhBUOdghTjNyKXda+md+zi8L2ZK3F8zLe3eIfLVXXLeICIGpnq5V+WYSH/MJ8/NCOG1SuzTukK3zHuTOMHmmC46OyTyxMfE3qcHqf9sqFLqfDchiLaII03XiNM1KeWmRLocRJ7yEXWETebaIE6DGhOMd0zsUZgTpz2uE6deXSNOSpwRewt2EzwkXDxMfdqeUQ2IJXwjKH73mRKpmBsEo90m0l/WSh3h2kowGMV9QuzzukmkhljXvgbEHqKH1NGUtYSzKZGu9ULCicv/Rmo8jesGkTaZ0yNvEgpEmr9N7J0QLuHJqSPeGWOE2PaHxN5DaV+4xFFu7zIdPW5Q39N2hzBG14nUplGpM07fNbylPXmIUn5MR6sLOlq6TsiIrfJjaqpzu15gHBG55qfEvhFTqObEqXmndPwIka5jrnvrtA2IQwrWidMj10v/q2XM2ZlcECc5riV8D6hlkvMork/Ku6sF9oxb4YLzTtxNYv/IOsGX1h0RqR7HxH6OIbGnQh6a0smzzHsT4pCYmwm3zssdQjZtlHav09FNXkEbEOmR7lsWdhXlKjG3U0IWZgP5DrH53lNfN0uf0paRzXEpf0rszxgSd8zdIVKPoNsHpG45JeTqBnE8+ieJex0/jBT/BN2GupeB/+0qcAv+9N/i0guw9X7c8bRXyj9HnNj6SYIelBMQB0mI0wzPMSG3pamTMmbTYdWL16lxpnyblTLXCZ55jjC+TgkaXS9jGFMfBGUbBj6d7wX1qbkQcs8o9O2E9xPi4IGNUud2gl3YbpV3R4QBdZNI6T4oP7cKLh8Q161sFVzvEHrkqOBSvbpJ7A0cE3zgvGwn+CACPWuErL1BnEiZM32Ed5tILZQP1DPaJAvq0yOPiZUW6XavtH+LOJ78BpHy/RxBKzrV11Kf8pTBRI3KJ8QpiJPUv3jaTN+npcwVOp5wLJul/xuE/bJGbJ1QFy57DBqr744T3Edp7L6D88Z4K8s9udXVobwiRIHtRoFhk/r0yGxjHdLhV/jtb1TqbVGfHinNk+DxBFnv7ZKGhpx33HQWlNWTBPcBoUe30pimpS11+Vpp54ia7w1IbxGnGo/K+KepL2XwDUIvqWu0IaRzvx0Q+z37bLa3idMjpT9t3izH75U62mwr1HqTUt8TVrNdCpHev0W919t6x9QnQMrfyh9ly3WCFh2ntsN16ud+GueI2HN4i4ufj4XTplE6ITbpKgAgDB2PU9XZukYwh4b0BsFMtwkHS2K6TZzMdy2926UTKDKSSn6T+uLEQzoEq8Tzkf+DVG5BXKC9Xt7JlIcEAanktohjvG8QjHpMN9k6bc+V/yXObLTqrXvE7GXiYIZp6mObMGR10jx8YZMQ0C+UcuvUTG4/4zQWmXtCx4jiUaNKg1dFpDOQDdhJglWmUUDeT30+Rxi8eXXrPWIONNJ9dMIp343ebBEnW24Qc3qdmIMFsWfssIxpK9U94PyR/8Lt2B2n5W4RTpu5+RpKI8J40jl7vsBtUGOW4BOfGt7u7bD/dcI5Ep71VH6rtG9E/Rq10yY9Pih1t4hrEXJ7zs844UL+spzPNcKRtb/stEl7GgEnpcxVOqP5hG4upP8hQWf3S53vLmU0WkaEgjwhnMIJYZBtlbIaiCfEIQC36E/XyThbI3hzSOxHkA+FR6WhM52NoucImXRIGFAQe7GUgRm3GpektjQYlKvy4TzVzXCsU++LWSX4QPlwknBhlNNAwzXioINjOr6UfmaprE6bxuk6YSCtJfxco6YzAxAvEHu+bhB7GzTEXijfDECsEs7JVmpvSBw6tJ/GL+1LD8oz6HhF3XJC6J0xscfmu4k9lAPra6n/FeDmGXz+b8Fv/QkY/3Y2fyRo/j4RiJSvbhGBlltEcFGaVnZBXN67T8gt58Agk3hXrwjrSfl2s5Q3NfAasSdGWaNczDjQ6Je/oU7/kvZHxD505R509CLPqL9s56D8XpS+lIfj0u5paVM7YYc4zEO9aYDkGiEf7xE84btNQm/LE5PSv86EDoYyQRtkM7UHkQ6mo3mz/HhwkDjJMkH8nRH69YCwbzSsb5XfE2L/Yp5v6eQmcR+kB+cMUjltFZ26W8QhK+qzLFN0um4RB/1MiL3bz6XvJ3R8cb3g6wXC+RQfyv41wrYTF8segwYGsoRHG8/xOo6V3lbiUdavpXfqwdyntouBAAjav1X+fp+wBSfUdC9+n0t1dV4ch/BIU5RxGBhp9dCEcJ4GhD2Rg5VndLrzBSLgNOf8QSTb1MGeARH4eIE4qdHLtbXfs4NmHyvEtVW3qFM9IQIcy2y260QQwXdvF1wpc5RP0MnmrMt9Dx197aZ2nkvtTujsG3VkfrTxtog5g9CDG4RzZkDlEREI3yDkQn5uELZvlkkvcPHzsXDaTuny+ncJgpOoDgmi98j9+8TpTt6rMSUODHmHTkBtEMepD6iP/H+f+tj6N8s7nz1iE6UO2lepDyI5pT71bFL698h/N05bV0a7X8byAbHyYuTrHULRUuDSGZkQp9Rs038QSY7kj6gPItkvdd8q3+Z0Cush9THRGnpfJ5TrLnGogUrigLhz6QpxEMl9QsGpDHSMFP5j6oNIhGWbyGMWFsd5RCjQY+oI2C5xV9aIi4/8N9o6o9vkfcr5g0iuEAc1LMrfR+ndEXFaosdDG+V8UuBZFJg9dnlCOCpj+g8i2SxjcPPrSvn/YcHXdsKF8M0JA8xVpifE8fWPCWNYeB5TH/+r071LfRiMq9InBK2IQxUWqdz7RCTO91lZPiQOLMn41klXWcgPKvw9wri/TjcP7xMrdivEJui3Cg7WE5xGvR4TBt4JcdKnvPMt4i6yQ+JghREf/cj/b5S2DoHfTnfK1Z8o5TyIZEEnX8x136Xe7D0mDkz6esK18kwnQQXlN3lXg0UDeFrwsFtwNmf5kf+PicyDIfWR/2+X3+1BJI+IwwseUl8q/ohaNkm7G3SyeJ96b4KrhetEFJNSX3l3QEeP6ooc6IFYxbhHOCqOTxkuXYvLe3Tz+J+Vtu4RwYG7xKqXq7zi283868RBLaulniuw7wBv/PHu2wnw6T9tUPC386t/JfzBp6vwb53B1+GHfq4g5Dr8u1/v7iTV4d+mPvJ/QhxQMSQOgJgSB7VAODwnxBHsM0IvjolVaHXQLpEVoi7dJg6B0sif0tH8OnEdxZh6pU15Ir0OiYOnvkF95L8Haqi/bMcjstUDR8QKjnQwpaO9dTo5oL7Jju1R6fdbxIE20u8bBG0pV8yq0T7YJxyZLLvUCY4/P67CK2+uESvFe4RD/s0C731ildAj/98hHMX7dHQ4puOpU+KQhQGRPfAWkVHxiOBVDfkDglbUiQeEfTWgkzfKFQMvO6WMjqfy9Jj6VNZpav8KcT3DhPrIf/WlemVccNkXJPPZ4/xBJNpBdwl5atDmWU6bOlfdNaHfaXM13SAACW5l2V0Cx9uEzB0ROvBaquvx8APqlUNluPwzWgLLdhm/QQnl3j4RXLJfZf2UuEJqg7BH7hF6eFzac86OqY/8F++TMjYDO8oPbYyj0t4gwfKQkOfaAq3Ndp9aB2jHuWovPnQkB8ThK9+gtlEWxOEfymzlkfwjLebHA5OkS6iP/F/n/EEk6gcd7bNU18exfI2wiZRJFz0fC6ftu+iOJl2hyxzJK237hDD5HEEERp8HRKqfkQ8Vx+vUGw83yzsZQs/2dYL4XipjMmpjpMH2JtSn5oyJ5epDugl6nTjdSUXxOuEojYiJMcrwKhGpfYE4ilSGdiXhBrEyt0OkpUnEClX7+Rxh7LhcrPH7OrFM/bmEFwX0a0R65AYhEBTsYzqh/VrCw3qpa3RoRJcR9Arh5CyI1AjxZEppNvihm4/XqFfDXihtyugQjnyeq9yOhhqEEJiltqE+gn5MRFxmpbzM/BL1kf9wfqVto8B8h/qOlFEp53yflTrH5Z1XTIzLewW1c3+TOKVqjUiP9Mh/HZ1p6X+LCBzY5ow4OVXau0GkQ+wRPHODOBZa3H2WON6W0r9C7JDzR/5LZ3PiyP8J/Uf+n5W/Xyt9TVJ7/v05Qhjr5LoidJtQdvLrHpGCMOH8kf/CMC84c9VZh21cfr9E/562d4iTJTfK2MXJT9DN+28iVijkzzuEsT8u+LuScKZCeY3AtQGNMSHPxO0wwaODJA+8SKSDaXy+QD0vOjA6bDuE7JrTGYLHxHUS8t6YOuV8K+F2t/T7ecJQ0Bk0KilPmLEgDPKIsOtAjOjkxbyMX9kxJNIRXyYuIj+iM+RvlLY+TRhYrlq+XvqYln5XCwwv0R3brd4ZlP9fJRzMLUIW2sbrxMWx8pLl5StXl57+LFz6p87gj/wI/J4fhT/wGz48IvLVr3cyUloelvFb1zGpZ/aIo9YHxPzfII5fdw5PiVWZTeLI/yfUR/4PiJXkGf1H/qsrXBmVL5034Ve3qCtOCy7VF/dLu+qBrDeHxH2jG2UcLxM0otPguymxmnCTTrbl++9eIeSFBv6n6XhFI+w1Opn2iOB701ZPqJ3T26UfbRZpESJo9iKRNfGIji7HxNUNrxLGr6uEryb8b6S/53Rzqu2iXl6ho9vXCRvqM8SpnzcJQ1P7Z0B95P/LRBbRBudX2sTDa0RAUuN9yPkj/3Uw85H/20TK9gax6nOdj37k/xr1kf8vEzaePOG7LLvnqR3fjQldSam/Qj0G6f8z1CttR8S1StoWG3Q8NUrv1okMCXlYxzIH6pVbLxNyWsc/2z0+64TedJx36GSjgbOdMr5PEhk5OwTOnWedYKjt39t0PKOjfZMIBpolMOb8kf8jurl8jXqlbZfYArVGRyvaDeJht7SpfJ4RDmI+8v+98v1ThK2m3lRPqOOVLS9TH/k/T/iBoAtpUzuJgjflwwadrHdulUNm+I05f+S/9oG26gdlXNqMFz0fC6ftF+kiXEZNrhMRSSNgc+CnCCfGFbJdInpmSoFRjhW6KOSD0s+YTgm9RXjOD+kEytvUl9MqeDcIA3mcxmRZHRmNDRl0nzoq+dcIRtsmjp/WCFHB6u07jiflnasoVwniOEjfXJlSsFLe/xRBIAo5L9d+TFwdMCz17hJG5UaCa49QCAtiVVHHQQFn6mmO8J6UPh42bV9L7+6Xel626KPz/u2C97XUlnBDREzFY1/U5tvlb+llTp0SYD0N6bdLeZfVJ4SgMVra1oUwTI/Lt7vUq4OetLaeYL9Pt3pxrXz7gFghFq+mHb1JKBfnXEPYAMestLdJ7FfIK20qWMc5Lv3sEVGrVeLC6gPiWOgptZNqe5aRbqC+l2xRyhxSR9jWCbrKz4g48l8jxhXne4DaAAEAAElEQVSFXSI4Y+Rxt7T7JsEDwukK7jGxEqnh+iD1Lc40AozIjYhVk/bZo75u4grdnEyIYMJfI1a3ZqneqPw8IKKXD8pYPVXwbxDGgVeYGHiYJNxuU6+0LQij/riM/zlitTSnesiH7v9yPoep7ymxejEmnKQ9OllyTFyVYeDAyKUrnMoO6f9e6meFbi41EOH8kf/O4w5xpL3tZWd6j4ieGog6oJsb8XxI0NSA4MOvlLF4tPUunX4S1+LGy7WVq8oMDdtDIpsCwmnR0dEZHQDf9w3gR38SXvhJ+KfoJusvdjD+HLFHcIc6Sv8o9T8kVtoOCaMJ6mt0Tss4nxA8r56bFpztlz50PDYKvNsETUEYeToltrVBvbqW/xYXrkrp7EFcn6HMynrzXWJP+Rodn2gUmsUxJXjWFXflt3LpUYF/RMgL5cRGwfGb5fsTgrbVaRmXGsvi8VpqT2MRIs19QjiZmS5dNfxpgvflg6+Wft4j7AvT/yBWfu8ThuKkjPvniUwlgyjibEIE2rxr0RWBfeqVtmxbzAidsFr6yfJU/bxBXMDsPCsfjomMnF3OH/lvmmTrnOTnIUGzrjZOy3hcYVTPT3n2StsHRIAcIgjcOntZZ+aVNm0s7bh14hoa4Vuls+F2qFfatql5yvl6TGT3qF/MvsnP+0TmhCv7e3Q0Y4DhoJR5jzqAJs5HhA0obY2J1fj98vMmkfXlvEtTBvv2iRVk6x4nXJoZ46qZvJZP4HYs2ge+e7O0YRB8hbjOSYdyQr1CB2HnG5SEkOmnBWfiJz8fENluBuYOiGsv1gl7TOf8lM7eHBBZAe2R/98u7/86Ia/XqS8K73s+Fk7bkM64Oyb2kWVlChEtmxAG/wZxV4P1dK7W6CJaEqzRwufpmGufEJ5bhIMmI52k747FFcBVwnhVWQ4IprpJHM4wT+9WS9vH6bdG0Y00dseZx2Fk+loqv0JcNmsUtHXabhKn/xgZMqVR/EyJqMluaudGKfeIENbZOZQpbHdArGAYVTByJzymbYyJy1XnxH4KFavzvklcvgnhsN5symk8Doi5Et/QCXUVnYxs1OyEWCV1PjbSmBX6gwSbG6hPqdPcKGVdTXRlTPrQUblBMPiEjh7dB7BK3G2nIbuZfowejQjjXAW3IIwXxzghnCPh8d2MWIGQhpzLAR1fOn/S8w3qi3shDq4YU++vybQMsak5Oyz2ZyQMgh+MIM+IqK+0quLUQXecH9DNt/wqH+i0TVN9DWjx+Fxpwwig+FgnLiBvH6PI8r/OkEb0gDjUYUrsOXVVdZ1YcZ3T4Vw5dVz+FtfuGXFPYcatsNmO/a3QzcNzTfn8N2VcGlarxMrWzfTdIFnmrzmx2r9Bfflw5n/HlMvuUwe/jGzPSztXEuxz6vk0ICTt57m5SRiQGjlj4lJyyzqOLSKI4UEbu8Rer53UtvAoOx3nGnHXmfSmYyTvS3eu/FDenf0srD4E7sLjPwxXPgf8y/CjX4Uv/2ysBN0nNr9/hc5wOqbWQ2OCX6UHZZH0Lt7Vi2OCr/aJvaxnqc1HBb5rRHqkfHKTCCJtEKs0pDYGBJ2vpvm5QegLnXrx1erNFcK4d4zSh0b7TeKwIw36TUIuGYx6jtAtyh/xZADYttaJtF2/ZbodEHohr4RBTdfKcO2dEyJgpGwdEQGBswTjhLARjon9xRr4OQUty8IVYpX/lFhxzOVMYZ4RtKBc1onITtsJ3RyLH20kYWppSvvqSnnnOQHjMgZl/3p6Lx9e9EzTT4bHdMRZgXeZ7M7PE2rdZfnsIM2JvXjXCJ3qfKi3Dgj6OaG2ya5R8/+EcLbFt3JbGodYaWtlHcQKel69U947747veSJwCbFCtkbwv+PNtCxutWeuEzpC+srlDNbkORBGf7IdoAzxMYCQbbEzgl/dR6dsp8An32W9CZEmLY6zXXpCxz836NeLh8S+2Pz+ec4fanVGnEXhnN1MY/QZE3a5gbE8pmXPx8Jpc8DrdEx9hZjUJ0SKw7iUXyMisJ7YKKNvpG9XU7si7yohhPvKyYSjppyELQEbYZFohoQhPSYU6TS9k/l1NteIKIOOgnvx9MqHhGJQYAvradO/gjUfRDImjHTrCY+4sF2VkO3oEEIoDBWvjCZeNqjnUfxkHBuJs23z4c+IORAnPrn9k9Se+DQCk8e3To1vCkx5zoyijcvvK4TjZfvOgYbIlKCRK6mugt4o0Sq1YW3dUfqx/Wwo2+aQmBsdAenDldZjYm6kR1fxfGwPgp7zI1zCm+cPgvZyv+upTisQTxN89pVpGWJPzTqxOil/6sCT+tNRXktwjglaWSOCFuOENwW5AnpMveKhgytu7PdKaUN+cm4yjtpnksbg+KDmpzGRHiN9jwkeUiYcU8uktfQ36d0653ErD0LgMs+DsGko5ro6fJafEXshhUd5I66zPFsQDq7lB6Vd+7WMin7cwGOA4nGpbz1hl15zXWWN+PcZE7JAAyTT7pRw1jO+s6xWjkiLOkC5vOkvtuv8jol0tRzUG1A7NtBFXP888OL7Xf2vAaNvwY1fA3/ofwbrfxrW/wdr3PrPT3ntf0+XP7MC7/9YLRN1CjPNyMvCsppg05nI9D2lpi0Nr1ZHqu8g6EGjXbknfdhGu9JmexkXk/LOqHtuR8dJ3Zl1wyT14VysEQ57np8ZtZx3bn13naCrcYIz8xKpL+lunNozODlIZTP9XU1jk/fEnfIzj10411If2kSzUlZ7Y4XgnTUi8Lsg7IsckMo20Vka45jQbwYi5wlX4p+Eex2vPpq6kt4tqPXaMSGvLDPm4pU2bazMVxlu6eUi2Z0f+VwdKq22jkSGTZpwddN3mX78W5jFwzLZrWMzS/BAyLNs9+T64s5y9iEdZtqbEbixD/nAsZLay3rJctKFNDPivP5Sh+Y5kFZOCDtAXm9X2lr54Dt1gH9n3nR8WXf4yJvZroHztk6L26wLIJy8rE+0qZV30mbGe9uutom4GPeUa5+PhdP2lDpi0v6cESkARm+fEBEgy50QikFnL0ctps27tZ53MqrGxRkRxTlpxnBGHJShs5TL2caA+khXx64gVNk6dscEkYbh6stp04eGxJz6bg9S/bz6Yh3HJMwa07PUptGZXG6e4JpR4z1HiWxjmsZtO/P0/0n6X7yYkgP1mO3TejnilL+3+KaBa5DK2vY0lTUK7BzMqemjxWWuS3p3msqcEbSlwBqmsmepzpCgsUVPm47DAIK0l+ff9rKjnJ9M85bL85fxetpTfpDK2N5JgnPa1G/7zTQq7ZPgbenfn2F6J72S3tu+8sKyLb7zj3TtPJ82feR++6K1J6kN5UymmWkqk2WM/AXn5VmeZ3mepkyL20yLbap0Lm+dZXXtW5o6TWUyDw6burkP4cl07XjET+ZraUAatt3M4/NUt6VHOE+PeX6zLO/j5Rbf0kqW93lcp01d+SHLU+GbN9+Ncud5yHDkfvgPSgO/77QLw/7bdDl0X6/p3SCEeG/5LNN17k9ZmOVZnjMdgsx3wuRYhReCz3QOSW3YF5znxUxjedzL6CzPzwrn6SHLskWq4xid5zzvLR5WOC9/Wh23SsiujFttlgz7GcEbWf9lejxN9fLYs97O8ibDkmVLS9Mtr2V8Ztw5945xhRqPc2p8ZToXtsxnffI7jyuXkU8y313ktOU2ss477Xm3THbn55RaL+W/c3pehi3Xze9a+mn1Q+b/TG9Q64KTVC6v/LWwtLKwlfcnzTvhML0x86oBB9uRdh3zMjma67f8mOegtRUzDNlOUWZnXGX94TsDrLaRx7AMT8vs7Pwu15F3R+Vd61u0Y/H76jPabXnkpKdc+3wsnLYhceS/KV0n1Kcozoljj031GRP7nG4Sy6GbdF7rbWIvkUvNt4nT6K4TR97uEekw0EV7XQZ3Kf92+XudyOE1wikjbRD3LJhO5lhkjEn5fUxEDLbS2G8Qh2C4zCqObpTynyj9mUOtw6eQp7y/RRhLW6Wupwzdpj46+IQ4KWpBbC49JIg8M4hRyS1iGd0IxPOlzIzzR/7PqZf9Z8Rx1MIqs3m8/zYRWbxZ3l2mNujyXVl9x8fep06PnBJ3ch1QH4wxJo5eVVG56uNR0zfLmA+p0w91XrYIelNQjUo/t4iVtgPiTihT5macTxO6QaRQzhN8s/LeuVEAbNHRibnfwi0O1lK55wijyrkcUh8Vf1DqP0995L8RUujmaZz+z7SsUnZ1YpTw3Tpt0t4xQdOrxD0/T+h40VSlIXHE8XaBQ/oeEvRiythpav+YoGlxpoCeElHuW/QbEXO6fHSja1vl/SqxyfwW9dzYl1HZWWpLObVHRwMeugSx6f96gT3jdkJ9sEpWpjcSfuSZT1ArtWkZy+OCq1mBVz44JfarKc/sxzkYUx9EMieuMJilsiPi9Fj7daXNSO8WNZ3NiFRkjyk/JVKAdPpWCHmyS50+q7zKBtC4lJcPxdEmcQTzOwlP8sOk9K/svkqkHd4i0pKUZzo+xwX3yr9Reb9F7PkZlX4+zKu5WwpPgN/zKvzDfy+v/9F/q9qLJQ6uE7Sv4b1JHLAjXk6oU69vEft1b5bxyHfXiP0pN4i51yAUB8roa9SGoDjQeB2lvpSlPvLMiFqOT4h52yD0wAYRpDlOY9klDLQbhKxYJeTtber9RLapHL5FnGBt/9oXJ8RqFAmOTfrTIx2zsnxCyDeIbQJraazqkTER2b9GpDPeKvA9TngbEDwnbNLWcYJthZDPR8ThRZt09ClsGvdZphxz/sh/afGEmqamxH78MeevbnqeesuFsu0mtQ7vezRyz+jmNV+XovPru2c5bTM6G0E9ntOarXtG6MQbhE6dEPOxQZzyfYuQg9K9+JX/3c/o3GnEq/e30ljWCXnW4mFCyLaHxNUkroBDyK7sRDgX6+X9LqGPMi1bd7d8u1HKj4i00EUqNyecFu24YYNXT39f4+Ij/21vRuxr/kTB8ZDY1nSTWpdfS+3Nif24U87b2Q/T2PMzJe7R1T+wDWXNasLjlNhG4/utVNfnLueP/FcmXfR8LJy2Fep0OxlhQaSBnRFG5iox0ZdTPZc3/bae2tWY92eY6rofYUgYm6OeH40r/5817fv3RtO345Eg14nDKPJ3HcCMA8cyTOXy8rvvZYQcqRCeRWpf/NjHWmpXRWkb9iFjOg7bbuF17L7PeLQtqFMM1og0gAynsFivxeUa9XjEqTAIZ8bFKLVpPfHcjnMtfZs141hvvvsu9+c4hcuxDptvGqxDztOveLjc1Mn40BHyf9MLdKTWiVSjzFdGojI9Dan7tV3nqp3v3N4p5+cJgt80qHNfuaxG4CLV0wgU/icJDy3/OHbxI15nRBqNPNuuWqmU56mNASF7HPMGYYDlR3iUSxuprYwz+cgn83GWZa3syrjO82w5cTuiNgBnxEpAblc+vEI9LwadzlIfKp0FtXxYI9I8xfdp6mdKKG3Hr9P2OME1SnjTaTtL7WbYZwmnWY47VudV4ybjK8vqLD/8udK0PUx9mDp9ObXp2LNsldchUr6kTY0U4chw5X5b/fVvfgCDPw6f/+OdcfwW8Pr/8g2+ePkNfvnTP8D/nL8Ev+VnQ3k85MPjMH/1N4ld7TeAL/Ch1/a7vwrzn4LfkmDbIGhF2KWfrCukC6iNbeuID8ucJfinPTjMsjTL9SG1HL9Ib0rTiwaPEMGU3F+mg8up3T45PyV4Vx7IzqcyoeXbVhdnvMoP0o98kOXsIrUrjPZxmUizzWPJuMptrdNN/eXm/9y2PNjHXzrcwpr12BnnUyez3FshtrE4rim1HacdkP9vdXj7iAvxZCDOn2xPXCl1suxeNP9nXSIeoB5Dxo/2FD1jz3wgbuecpwGoaSvbcJnG/dbaPT7Ca5vqhw1i9TaPO7eX5az4sv1sF9p+Hhfpb+ky2wijpnyWha2Oy7oJaj5XB50R8sc0U8uJB3k5zw8JB63sgPNzk+linRp34sVxZd50PPa12pTLT4Yty6S2XPt8LJy2E7oTYXaJjfhT4qTGQzokfJX61KENIpJ6TEQL7hKI9kSYFeJOsLfovPUD4kRE32n07BGR173S1k8T0aR3qA3uAWGMjIl7x4wMf4VghPup7WFqY620axRN3NwnTtvZJVbkHhJ3hLnSprFGafOrxCEdu6Wvb5c601L/Qen7CXF6JKXuiPrUKYXKhCBilfqAuHvnoLSxT0Qe/HtBRGOdk91UNwsk6eAucWrYAbGCoqG2S3165EZPO0Y21ohTrb5KJ9Tuc56Zt0vdOV1E6JBuY/eMOFp7SpxEpuCYEgfV7NKdPOcBEq0gmhH3H32diLDuEFHSYen3Wvl5q7Sv4nY+hqnfWWnPo6VVmsJzTBxjfkqsru0S990NiJOfJsRJf9nptj1PZLpPrWzdEG45ec7VBOl/kMpA8MMxcXrkMSH8PKV0n6CDvdLuG4TQFM6d9L9GmKsEH6R+v06cDHtEfU+bsqZ9Ms6UExD3OR6XdzPqg34OEg6UN65mrBMy8asJ1+9Q39N2TPCkhxeIxzlxUqR4VPYsyt/ifY9w1oya79Mpna8QcuVu6UN5NidWBM1IeEAcRHJAxzfS5Jzz97Q9JGSYEUwIIzbTmafL7hKyPa9m+Shr3qK+M+4qcQLhIUFTyt53iDvo7hJyy9PoBsQhQeL7AWFw3CPkp/JaA0mnRSPqWlNOJ+9ugvGYkN/HdKeYbQNvPIH/1W/8F+HXAH/m74Y/+7e6oxZ3CWFwnzg1YFoAPeHDiyQfENdVbBCr0G8Rd5nNiJXxdwj6kQ9OU9Mj6msy8up5X3rkdmlzTH1Pm/p9SK033yFOBFwjTnheJ06ymxKHSn2bWCHaT2M8Ik4zfJ/69MhvEnc9XiZk6ylxGM2YkCHZwNNfvkvMm9/US8fE6sExcarfAR3/qHOlI+X4BqGjxkTmic7AKZ0empT+XK35NmFPqMeVO48IuvKk0Tl1BpM6IdsWZ3Qy03kQDldxnZdxGsc9wpCXRLeJFY6DBI/0054k3T7aNMqWEyJlVB0pz/rkv+fN/zvEqcYQsjWPYUHce6a9adlsY90tsKjr9ku5VSLTS/4XF45PeB6XfmRhneVVzuNlm9BxEHe57qXx7nMeZ/vUAXT5X304JuyAA+IuwwlhaxwTNKVdO6G+p+2A2ukflPf3qAPqjp9SXrrx+4KOX7X5pdF7pY4675Bab/pNvCjDcnrkvTKmHc7TxbtlDM7ZfsLjiPpaJWW89ugasSqfH3XKTxO205j6vui+52PhtGns5FUmhZ1ImdN51hpjbbRUQztHWdoI0jqRupU97vYd1JGxYWoPIlIKQTRDwpj1gA0do9aJWCei0rltx529bdvOKzHiyDaywZMF0ZA4fvxZ+HHVZ5TqZ2bJUf0ZEUGwHZ22HDEg4XCD2sDMUSgjho5LWMRVXq1aT3WzoeZYB813nzYaY9pQO25XBlqnRIGWD76RTnPECGKVxnLrhLIz/cv6s9S374RTGss0MSYiwyPqAydWiTQIUnuZZ4TH1JHsCA0Ies+palmoZ1rdaNo7SXgQF20065TztC8P2U6O7NvGiIhmtquNKrI1YnPyLPU75fxBJK4CQDi/GWerxNyIg6v0p9hsUK/yGtV1ZXBa3ikfNIAy3TxKuOnDt7C0qwDj8l4ayIayThipzTGhqKwrDNNUXlzrOGmw5RU5nTZh8vs6gc9MP9nwy6soWYZlnt2ghl0YrZtlTeu0Ob7MJxmfU2I/UJaFl1PdzHfiXJjGBL7zfK0TToxGfTa4pPMM15R6TrOsyytZUMse1ugs+j/1t+DHgD91Df7wUe0VrzUVB3zIqBn3WWbmKL1OW8a3MkLDTnrItJrlr220TttF9C1f53bEaV5RURZdIfa35fdZ36wX2JTjV1I5dZpw5xUD4cy85CM/kOpmHvebOqaavzJedcUpwaNfojPe3kvlWxqRLvL4Wn5fJw5+mqc2lKftKt6Mmp6HxPaIzLt9+CH10a485PmyzjCVUwbn8bQ6vH0slwPW2cbTWHacfbI7P+Il0212Mnxne+ohn9bGyrCI/2zjZrmm7bJC7HvLthOEftEezE/mJWHJclc6y7yp/s/jzOnptjugtnuUcfJXtmFGPeWynZjx6dxkWpJ+M66zDSF9ZvGm3SLcrV3qI304ptbOzjoyP3kuLX+c3ttm1hWD9Ludbx/pc4M6S6Ut1z4fC6ftEnUEwb9n1FEFv2lQrhJEkJ2IlVR22FPfyOcqdZ+DnrL5J5dfSe0MU3srPW1mx6uFIyv0tjzEUm+Gt8VVNnYULotmrNYZUY8n/z1P7SzS+xH1eBc97fbB3odHFVl+t2j6yAa1CqKde/tdSeX8v8V3biuP3Tmbpb/76CZ/y22rONvy8/R9lOplWmmdvEGqcxF9tLQwaMrZzjyV7eODJ6mPjLtMF339tm3aXl7tyPS7jKfE6aD5maey0mvfvGRe9Her0FZ7yq0SV2CsFjysEil5trNY0k+bGmmdDPdlav7JMmwl/diX9N1+GzZ/07zvk40axcK/0nxv28owaDxomPXRTh9dXPTTypqz9L9zm2EWj+2YSW31ybF2bpzDrCOW8XgeS/vdvhxbO65504bvcltZRy3o55+WfvNPH75HAmmlfwMYH8HvIJbNf4K4XKytPKznRzgdX6atVl7nedIgzHhq5802cmDxItmU5UP+lunEv9t+5z3/Q83DfX23eOiTG328lmVwtj8yHUMtm1v6auf4OeCH6RZOd55RZ0TNU6290QYMlun+TN9ZNjkPC2p4Wt7TVssy3e9ZFi6TD6uEbdCOa9mT+1701MttLZPdbXvCK4ytPWK5ZXTbyou27z6az+VzULy1Y1aJ1MAWllZHLcN3i9OWroQ7t9vadX1yqU92LpvvQdOmOM8Ocx7foHnf8lKfnmtlh9+yrdTy9EV2Y/stO2b5p6+9LMvy00evz6J54f9YPEYU/SH9nfdp0HzL/y+o6y6WvGvbWFD3kd+37fY98yW/+54MZ253cUH5XKftd95TroVlWRuL9LsPF7mddnztHLVjWtA/pj6YL8J13/z3jacP9na8z6KjZ83xMhp5Fu20NAc1fvrG0vf0zeMyXPThMX/vm5M+Hmz5p2+MbXt5DHC+n2X4XsbTub1l/LyM1vtorU/O9MHRx6t9fNoHd1uvD2c0ZdrvLf7a9+1Y22cZX/bV7Rtri6uL6KyPF5bx7UUwt+Nv+eNZbfbNc/ssmh/fLaP7ZbKzrd+Hx2W81ddWn2zum7MP67cTcwz888CfoAsX/3rgXyAudmyQ04fLPhnWjnEZ37T8t6zOMjrMbcF5PJHe05S5aCxtnWVwtPD3zeUyOdBHI33j72srf1vQpR7+HrprIKCGoy3bJwOW4Y2mXP57WRstntqxXKS/+mRxH/8vk5EXwdDX37Ix9o11WZm23b45ukgW9o3rInrNdXtYdCn/9435WfKnTz730d+ydp9Fc32wX6TH+uRC23ef/Mnf4Xx/F81R2377dx9dXKRb+/p71hj72n4Wz+bnY7HS5qWtB0Sq0BmRIz2hA+gduuXEh8Qy6QNixWJS/t4rv9+mi1TtEcux68RemBMi33qX2B9DGUt72/s94oSqPSKft13uNT/8A+Kuo3upbfdHHZR3x3T5rGsFnjNi2X2axmV/7sk6KLjQS3ficwrKO+XdQRrfLhEV2CH2xs2IPWZzIr/7tIzriIiWH6f5uU+kTr6fcAORqSNOp3SEekBnS7jn6ZSggTaqMizfHpUf9ynkCIsXphv9eKdpZ1ZgWCT8CeO0wYnL3pNSd0HsL8lzcdRTl/RN3FlXWpA21wsud4jcd+vtERejSiPO+R6x5yMLjQGRyjIr7eW9dNLUIo3noNQbE/s+fTcg9n1B0G1O08ntSdMnRNTupCl3SOS5i7Nj4lFwjct3+d12j+nmdo/gYSNUpwXe3YJX5cUk4V6enxH7cfYJ4SnOzsrvfeq0qr4oV0t7b5f2JmWcJwQf7hH8abrsZSIP3wub3y5wPCRkA4TselzKGjVcECe/QtDFURrnlNgjDHGhqzCYTilfH5b230n1d4m9BtLfPrEPboP66HN5xBW8eelXetyh3p9qahDEnUCZfnZK2RNCdsH56POstLNH7GN0L9qcOA3wtODyHh19HxR45YUMt3Ta4lu5ul7amBU8HJbx5Si7em2d2Pd7lPq6XPpaJfbiQS1LPnzuEZuEZCYBe5/IAfx9pbM/lxDxsJu3TEtnhA4wdSqnR+4QF1a7MiIv3S9DkF82iIi9sslVBOHJ9C1NPiTmTP2lXN0m9k6qf0yhUrc4njViz4n6RftiUsa5Tezzkn63CbqRRu3LOZK+7Uc4pXfHP0/flA3S/wHBIwfEtKlz99PY5X9P2tsg6OBegu8BNU+r6ycEXz8g+HFCpJTuECdJHxN6ckCcNbAgDh1xfG8TOkJ7ybnQNpoRe71MCTsm9taeEPrYca1T2w59j3JXfXdCrLLsFFwIu+lzWUYsmv/VKfaZec9H+2qV0IUkeFob64xOjx+W/tR3nhpt3d00FuE5JnSwdGQafosX7a775X/ltDJfOlNe+e2IOjXxjJhvCHqSNmzbNh2nh51J1xB8YL/tSpv2qyvGplj6zMr3Y0Knzgn5mPGREwoOUp2N1N6i4GlS4LlCPdfKC+nWZ7e0/w5xh1o79knCo7bFXvkuDvNYbHdCvc/uXWp7qO/5WDht/x3gc3QE92nqI/8PiE2M308H5Iw4Bldl8SJxBKvC9AfpNk16SMAmXa64CuUa3bGo30tMxovl95g4tlan5AeJDZjrdMpuTBDjJJV7r3xTUfwgQSBvEkpjSEc8XyD2m2yV/yn/K7xulJ+rZdwK7hF1Xre/RwVn89LXLSLXeA14veDn/VJOxtJo+l5CeL5HOBEzYqPxVeCLhNF/j26D5SdKG+8DLwOvEIcGzApenyvfz4Dvptu8O6cWSHeA1+iY9KCMf6u0KdwU+HSe1wo8WQBMCcd2gzBSv48wNtdLHeHaKnUXdALADfsvFlzeJA7RyYrhpMD66TL+NeKQCYXT9xGbVt8o8H2ROI7ZDfou498kjiCfE06PgmyLcPamBc9fLO9VLgqN7DztEDy3QkfrGmoD4njjV+g20D8AXuV87vcBcczyBqHwNwlahhCAA+pcdo1AlcWX6PhiQhzK4jx9f8HP22VM2qtbxLHBZ8APEAbaLUK4qrgepTbt94vE0ejy6LjAc4d+I0JDb4WOBn6AmKON0uf3F7y+TSi/2wTdbBfcPiw4+8FS9x06PhyXOm/S8di1AvvnyvsFcQAChJG1U/6/k/DjPHmUP3R8OC1w6tipHH+QMNCHdAo6y7P7dLR0RPDNEbGJfotO1miMGJi5RjfHO0TQR+dkTjcX+cj/BXGI0m3iQAbxqCwY0PHoaXnvWDYLzl5OuJ6UdtQVlwu+TVO5U8prZAwIefYG9bHPV4gjn79IN/86HfKxeu114vCNh3R08WliX8mIju8mBRevEQr+JeBTAD9UGn6LsLr2C5CfBX6+IPfPA18G/vxPwIPfDn+qG9TL73ewXCtjeTnh7BadDJ8RuvKNMk/PEfyqA/N9ZezbxEEb0odttE7bvdLO95U2KfV1eJfpTeXwzTI/OpQGG16m3mtyRlxTsk4EWL5AHEOu0fSF0ial7OtEMEWDeJM4fGNMGNS3CxwzwkjPDrsy5AZxxdEp4QzvF1x43YZG8ZdKP98maOxaaV+5ckw3Pwelzztl7OrNzyYYbhJ88RydPH+DMPSlBeXyPcJZO6Pj/41SVxmr0zsp8Gg7vUq9V29MJ3eOiCPqbxLB4vUC25jQacue9ws8OiETOh56vfQnrXyKjh+flVZmYE274VH5nS98XhS41ZkGlCbUNpY/L9Oxp47QiLjSRf4/opPd8kgOeGlrQOgXZVN+7pXxf6n8v1H6uEM4MbvEkfIGOD4oZa9Sn2atPrxOBLC26OSePHSTCIRtEYGSG6Xc/dL3+6Xsa9TBOfWL++W+wHmnbUpHC9+f3umYf4qw5XUUXyGC4N9PbaMsCpwHBZ7XCP15DHyLjjZvN7h9h25+vkTM2S6dX/HZhA9pNzt+2vevUF8/ICwHdDJO+vhC6f9Psvz5WDhtC0JATXt+Zs23ttwg/T1M5XUQzoj8e9/NUzun1PeQ0NPfGecvirSMEZQc8XmS/l8hIjCLpj7UF0BmWEnv8pgup7GcEQZ267SJl0VqX6dM42gZvucFBojgbItfBbjt2t9Zqptx3OLNCF0fTmjqn1Ff3DyldvCsu2jwR/ruO8cuTjKNWVb8aGg4hpYWhWuQ2s8wtu3LyC2+z9L/mR9WUpu5Pw2heSo/T+Va+KRRGnxPU7kBQbcrS8pJB6sJ3kUal/PU8qFPLpfptk0tkK5aGdDOxVmqJ378dtK0MU//P2natt9MlxnulVS2Vf75vf0KQx5zy9viJcsvYTtN9Z+kOq38k0YzzUB9uS9NeemhrZvhzG0Jj7JTejHamXE5Sn8/oR5rht/VgUz/Gr/OR24PatzlejnIkOVelpG57/Z95r08V8J1ynn6c+yWGRA8YR8npW3HtEhtWJ+mDgRvZHlwwnl5/eEktMKr/bkP/IfA7m+H/8XfBf/ib4Pf/Qc/xGkLU5btzkvmW8fU1rf7E+prAWxjQPDramrvpKlvmwP69WarB7Iuk/8y/jItDVK5zOd99NHyZTtfs1Su5RtlWpYVWe7L31nnZzy271q+zzyS34vrPJ/OZYajD7aWFobp/yxP+vRgn5z2Wpn8vU+mZzofNGVHLH/a/vLY87hty3mCOuVtpWlPOXTWfLeeuDxJ37KsyzZDpsssm/r4f0ANf9/YlXHqK5o2TlIb4r+dA3Wk710tanUl1PBkuZVtwBZu/3/CeR2QZYH/r6S2+2Capm9Z/oizvNCQx2YAKs91H18t66u1vfrKuwrqWMSt48i2tw4+nNcFLZ4uej4WTtsv0nm5+0TkWwCM4MzpNuaeEkdzrhPL2ftEStW3CaVgygtE1Ps+ccH0LnGs/vtEdOWAiJYcEJuTHdNO+Xud8+mR1n9AHLf+1wkicHn5gGAYlcrdUu+wlJ0WeI1MuCI0LmXuE0wgM0ukOggLIu1nnTiifp9IedPZM9oEkdJhGt1R6ueYWDU6SXjYI46VhThae5dYYp8TJ7AdECtZRi+ycDKV7l26uTOlapdaCB8kXKhscjRqRhwLOyIi2DoNO8SKzYiImkCdArZPRNXGdPOzSx39mhErDx6TbWTWKNGMSJfZoZuHdeJkp4d0dEApbzRsTBdxnlA7YfvEaq/C4KvEscvCZXkj/kaYrxRcPiTobUBEsXeJ9KQJMfc+tnWfWC2g1D1M5Yywuso8pD6NTdpT4E6J1XZ5ZJ7w47gHpe9NItVXo+yYiOpnI+kktS/PjKijZfL+iKDN9jmgo19pzzKmap7QyS7nSfv6/YSDAyKdZ6+UuU8ch7+W6ij7jCaTvmlouAJ7lMa4TVySDHXkTxyoAI/p5m2V2pl6m6DdnFopntfoorPiVhzY/pyg3XVilS5HYJUR9pPTI+U1rz6QNqQ3Shuufm4TQbQ9IgXdVVZl14y4RmJUxvI2sdrq1QGU8e4mfLvaOyr1Z8Rcypc5QDElrqyh/G1a4IhYnRsTx5gfECuXe2VM/8CPE+mRLm07Cd/oBvN3frHr47uGdOfZ/8H/GgZ/EP5VuDSFzT/Zjcf0ohndvBvx1zA7LvDuUh/nnw3SURnnGsGXtikOsm4SDoiI+AGRrqjMUs6pNx8TGRGmDB4QxtJOeXc/jc05ulza2CltvkO97WFIx+d3iWzTY2ocXU24kTYHhE64S6wWk76rc8fEiXFT4uqJR8DfoKPlu2nsrkQI1wbdCglEsPmk4ELHX764l9o+ob5q6LiMZY9IG5uV9qXFASGzsn2xT8dHytEcZDsgshOsu02kv5m2/k4qOyFoaJ2wDy5aaRPGLM+V2fcJHjylThtd9rjibZ8a5K3TdpVuzlzctuwBnf6R9kYEz0wI+bpBrChbd5eaX4RHnQoXH6qiXNB52KajkbcJ+j0q7++lPlzRXicyVLYJPs0yaqf8vEPYwMoz5bLZFjsFn48Jean9CJFyuU2dYtjabG8RJ3f7zvT1fYJG76ZxHpV+B5x3lHaIFOsZoT/VFTuEnegjbuUNqK8ycOzqKnHiOOX7DerHq0b+Wmnv7fK+7b99PhZOm8iVeMYE8eWVozEh/NZTHQXZRvNuTIcMlypdol9PbdjfFWoDYY04flMH5SpBVOtp3Jmxh6WcBqbOw0aqOynvzcdd5/zlruNS1nY0cnTarhJ7UGRijSKNQvu1nXGCKePnJOF8LdW/mto2GpCjKaag2K42gzBAnRphvTMiVWJKpNRtJJzI3NZdS/BadpjK6UAr2MacFwDOrfPiOKwrnjNcEEpRpWL/V1P5bFwYibPMGqHwhqkNcb2e3jlunRbh2aCjEXExTf0tCKdZvpHerxLOu3PSrlBeIY6zP6U2RDIuDKZspPf50cj2hwaPlrGcDkt2AFQWV1OZHKXKPKkMyDgSPzNqfh2n/hSq4sWgEKkNlYT4kP+lt/zIo8qmMWHcOPfj0u8x4VjJhzpK0qQGyxU65WJaF4Q8W0vlINJ+p+n/vJomzToO6J8XnU6j+INU7oxwcLI8MzI5J45RNx1Q+hYn9m1AYJ2gdR0bYWjpLDt84/JeOsiyQNiUZ86tbV2h3gsqTTnPwqa8HTft+O6I4PMsu8+IdHsj3xDznHURxJ7QMaGDsuy2z5U01jnwO38BJr9Q9s/8YlfnEbDxi3D7rXD6V4CNGbz0TkRy3/lH4XcB/+636CweN2IbaXqOztM5A74F/+TDuJfL8bkyMktjV5Zm+phRO63iQjpWrpHqa+COUzsG/dQD9qM8zPTqPKpfnPtR+b+1GaTNNUJmGywb0BmByiDpUdpWdmX7QvqCkMd5zMKlLjIi7/t1YsVD2+AKsU3RsVwl+PaACERmma1+XUk4HxEyY0zQsvpM3lwpsGfbIjtX4ke6VoeMCFmQbQVl1oD6aglX8rJuFBfLnhnh+Ga7bEzIKWXAMtmdn1NClkCslGZ7ZE49h+o5eduxZxtrQsi0Vq5AbUcKlyv0yivHoQ5rYXFebdMx+H8e3zj1kW0qaXGdWmYOSjnrKn+uELpMmsp9qBfUodJKlgXqP3HV2mytPSwtZf1h2igEz8+p9SYEPjNd2O4JtY7Mj7jN32apjvJDPPrNcQpb67Rpp4wTrH39t8/Hwmn7Lro8/VW6HODniCj5ARFNeY0uMjAh9hFoIN4p9dYJ5fI6QUwrdFGQ10ufGnU30rsp8Mny96iUNzd/vZQzkkP5W2FgVM5yRtH1xF8nCHKN2NehYvgsHRMcEHtAIKIwwzLWTbpJfY7O+88GjwI1K8bXyrv3E840ul4lCOU16g2qlHdGEcbExspZwbEE9mrCw7j8vlna2KXLy/409aWOm+Xn/TK+28SenOyEfhL4TKlzQOxleJlaeLknR4WV8Q31sv8GsaftVcKw0hgZlzJbpe6cLvp6QOyX2SL2XmpoKcBP6aKQLxe4FsQeMst+Ls2FwvIV6kid8A3p5nuz9HlEKHCV6c1Sz2jbtLR3kzj4QaExJ1Z6d+lywzeJCN2EEK43iBz+YcHbK4SA8zkgNh7rcEHNXxCHD+joaIS0TttrxCEAroAcE7TqSt11QpE9T5eTrkJ6PcG5RUTZxc+Ebq5WCeXzSilr5HSHUA6fpF/xbxOR3BHBcwfERuTXSh/vEgbKC4QhuUMcApPl1EqpK64zjV6jo1+fDWoHKiu4FwpcW8Qq+FaqK2+uE9HKBwU3rxNOnAGJzF/bxIr6mNiLdUrnBzxPR+/KJ2XfmHCaVL6uhkI3F2NquhVfLxDK/jYhAzW07hCrHQamlJ0vEofbTMq7zxMG/WuljSel7RcJXST/f7qM+7TAKz+YjfE6sfcqG1xTOjp+ldgfsU/sf9EBGdHxnRcjv0rolxep98NoDI+ILW2vELKdUl4Zf1zmYgLwe4HfBvxviDSMf57YtFs8iu/5qzHfeU+bRvOrxGEZVwm+hOVO27j8/1k6OUGpPyhwXea83nTeNkqdTxKrUNMynjsJ7hNiH9KYWJWb0cm9W3T8aGbEZ+jm3ODja0R2gQbgNcI+0RAd0PHTc6l8XlVUv9wm9PgxcaiZNOC86USJnzG106PsV9Yclz6UOd9N8NxBaXdS2r5B2CA3Up97xMrxi4TjPaa2LWalL2X7JMEi3rSdXiEcOp2423SyYp+OxG4Qe9q0Kcbl20VO2y4h887oeOVlYp/SfsHZS2Wcz3La7pfxu4dNmZ5X8edlvC8XGHWeJ8SeMelEXl1L8I3o8PsCwcMT6qCVdtgRHS1/gqAxnZwWL+Py7dXSzgodbd8mDgdxfC8QOnCPyCpaI1Zupd1rxGrrVoFbGf48oUe3Sv8PEn62iZX3G3Tzkp02V6+yTaTdALESuEFtt+ukK4MHxIFUnyIyO16ldoDmxB7PtTJG9ad2p/jJjz7Aa0R2ilkC7qt7SPDmjFjdXC3vP835PW2TMpbPEbbTZ0r/f4Llz8fCaZsTewAe0zGNy+3HhPKdEMg4LnX9prDQyyWV1yg/btoYEQd9nFDns+opq2ghUmqOU3kj06up7lFTxrHIaLYxJYyMR0Rk3HEKn8JbGCGcKR2RAbVQhXAkjeROCEXb4se2Toj9aJPUT8ajOFY4OFb/dt4cf4t3I4NDIop3RI0Tn+PUpn0eEw6Qxv4kjRvqk52gphmoNy/btkJV4S5c4i/TnnMhfNlZnqb3+aQz5wpivs9SuxPCEM34Niq9Shi1jlcBa7qO/TjOR6ld+15Qz+kjwlHu63ctlX9M0FFfe/KEc5hpWTzKF7bRRjIhVqPF9SmRrjJJ70Zp7KZiOB+PUtkJQcvSr22IS8erwWRdx24aX/tknDl2ZZLt2+9jgk40nvN8K3cmCU+2Zx35VHgcn/1BvdfRepkPdYAy/yg7HIt59vafU6AmxDxb3vnJvNLCb3saQtIrhGzJ8klYMoy2Yb++y07bhOBB+UEHPadGnhJpPVkWDujm6jh9U75kPNrHovw4v1lXSDPqktOEP9uz3zNCNq0RKZkT6jkcNu9pYMzjs49DYg6FnRO6/W4/BfxTdJbkv0p3MoV5VJMaP8oiqytrlGV9qxMaa1k3ZfmjrH5MLR/68KQeeEykOWV6E4/HqZ1jgr4yHBlPzoHvFs3/wjZKbWc4tV3E7Tx9k8/UG8J/mmB2TO1+W7dsPE5tZptI+ByTZR33Sfqe5V2rm6W7UWpXfm6dNmVQSxdZPl0m9HLWvYdEuuZpqi+fSyvaX8sexy2e7Nf3p+ndR0mPzPQyoE7Jcx7PCNwOiWCf/J7psdWzyoghNV2LC/uYph9lEFzstNnPhFoGT9Lf4sZMMOdlzvl9eM7FkNp2tj3pNtvp2UbN/UpzR6m9bCtqB0w477RlnW+A+oSQcWeEoysu7fMR9aN8zjJrUr5lfBlo83lEyJWsL/N8Tzhv/2Xdluv6WMa2nO8JFz8fC6dtQKQqmiphWk8WXmPOp6jllJarqR29XqPkOSVlg4jyr9F5wEZwcwrEeiq7TqSamSZk2sWAYGCjFsfUqT9jgtE2CKdxNbVt2oPjhPrSwY307SphuOm86Ay10UwZQthzH+JnTOzvUHiMCSbKaaYyd56vvNIm3mj60oBxLsdEJPka8FuAfxP4/XT5votUV1zattEPx+reQWnpOrVgmxLL+jk6NyZWUnNaUp4D6zhn+bvl80rbIMF9lUj/sP5aej+jTqUYpz6ci2FqS1o9pV5ps3/nKKdHktoQHohUiKvE/Bm5H6Q2Mq2cpr9tzzal9YyLjEcIRS3dul+jXWkbl3YU7qYgyNeupq8TSuxKwY/4FnbpzQiqjiUEvah8pS2d4AkxF0Yd20ecadCNqVe67P+MSCmRtpU7E0LZyI/rqT1xneVRTu/wWzaUNcAG1POoEZAjfyoNo8Qz4jAJ4fG7fJ4dB2WC/Wj4OEdjwvCbE7JJWhF/Oao9bmCXDzNOsozOTtuYyGKw3zWC97JecW6zLMwrA37TSM/8kHG7QZzAZh8aAPKxOBM2El7Fh/O+QfC3ZTeautJRX3qS7613nXB4pJ8PFd0I+GliqfAfA37rj8Cf/kl4p8bPBrHSRsLBGiU9k5o+dKh1miDkkfJHeB6Vdx4hnttR/sgjpnWvE0awtOl8SBP+L46Ew7LS7zi9k858sk6DcCx03NSF60TKo+WyTrCPXE+47DfrEvGT7YO10v6Y4DVpVNodp3fypPS1xnla0fFeT++GxMpkdtrk2WuEvvHxm+3Yj/x0vZRzHPYtf1t2zMVO2zH1NUTysmPXPpLG+mR3frJdKBytTFLPjAl+9XlM0GOWJRm+LwK/71fA3/zb3RZTH+Wfelc7SZxJK8ucNvsZ058Or+PluJV/2nzCov6Wdu37hJo3poSsy3I507fBT2lO/Smc8rF9jjnvtK1R6znnOOsPdTh0+H9MyGDrQaR0PmnGCrVcb1fETJcep/Iu9mQ7Lq+0ucK22lPXJ8OmTXSlp1z7fCyctksEMXoMuKsQmUA18Hw3av528oeEM7RKCPPVps5qqjdK71jSh8K4baP9e9SUGRITCOGsrTb9XG76gjBw2rbXmz5kapUiBMEsqPFjvdyGgmpIKGPLT1O5HDnMY88Ohu9ovgvTIL3T8RgBXwN+nHDuFgmGYdO2P45HA3OlKePj2BTC0pTOQF/beQ766Gat55tjaeeppRO/TTmPx0w/g6ZOphMNp5Wmj2ywZwMow/OE87BmpZCVR0tvy/CTeSjPRVsu0/kq4WzPqQ8EGSU4Mv1nHs88mmmbpr7f8mqs34fNu1EZi+PMeMoKPNeRtlqlPyIcbPHR9iU8Gb8tvsVhK7PkgTmxhwxCHjiXLT2S6tK8y7C2fCR9Kc/ynOY+pgT/SnsaVn3yJ8uxPH8Z9rPm3bCnLoRTYlTbee6T9y3fL9MrmaZX07sFIduUZ/T0IVx5TMKVeb7tWzwqh9u6p5ynnYwf6dUxKxs+/NYKnxM6a3IKvPKT8Ft/M/zGf5+NyzV/Wy07xH1wQMiSVeq9S330fZm6n0x/y+YtB4lmPW3nd2vNN+lY/lWO5O/TBp6WnrIOynSZM0ZaeLQlZtTwZBxmPdw3ZvHetjPoGUsffbcyoaXdHIhSxghr265jkEazPICQA8voXDsg/9/KnvaxjWy7tPTT0ld23ObN/7me7WV5BEEjl6l1aqaHNfplzYAu+/hf/9sRfIWgL50Z5z3DozzPui8/GZdZRq0TK2fiVV3f9pH5LOvhbNe19klrO60uKdfiYcB5Osi6SbxkOObUNkpb3/Eqq7PNSTPW3G7+lvHtM+op344h88yUoIc+e8mnjzcv95Rrn4+F05YjdXqaIs0I1IzwQI1kGM0wWnM9vdsgVhByRNSI4Sj12b6DQHJuz/71qhWaEsE0jcOIYV5pkyDHhCEnk4+pV6n09iXmYYLZCIKreTosGkUyk/0uUpvj1E4bXZ5yfqVtjTqaKwMbJVlL7Q6b9kltGwFR0Y9LvcPS/jW6XORDaibNkcC80iY+ZdZDIrJqVKcVAEauN4g0pjE1/UkDjg9iNeyk6f864VRKPxBL87ZhREXhvFbq5mj8KJX376x0r6bv4l3hKp4UVHn+xtS0ALHacUbsQxoT85ejfpkexdHVVCe3d5xgVfBIr4NUpl2Ry2NWYY0Jvj0iIsXS05ga7/KH45wVHA+ICLrzc0LwCKn+nHoOnHd/rie85Gec2nBudYwV4tfTOKapXl6Jkp/zSqzfpEWjfsJu9HJOZAJABL3ErTSbo4+5ruMycqyMG6W+5Q1XsuS9o1Le+5uuUq+0uQI6o5ZRGcZsPGe8ZthnxOFILX40Vlxp8xCaK9SOhXgwZcc5bul7Nf2dV9pI7+wj49bos/O9QW38Zd4ULsspK7I8WLbSZt0zzq8iZVl/kOrl7IQN4OeA3/SV2GP16YKTrwO3f7LbW7Hg3+fXfQJ+7dOf4df+v76nO70kM7SI/CHgPvyf/mjQjHM5S/CLwxGxKpHhOSTo23bk2w2CR7IcGBNbHCDmS/mR9cgatU4eE3N7mt5Jk2NCTmSZtiDko3COCbqcUh/5n/VEhjenibkSomwUd5bfSPWVh9eJFDF1pCtt1jlJcCjP1wh+zXbAKjU9u9I+pXb4Wzsly++15rsriK6MXiN0kitJWd9nHF3ktE2oV6HMZBCeY0JmteN0rPn/MUF3tkczBuXiFcLe9FG2Zp2R501D/pjY8+c4lKt5JeoJtT2sbZPtnjx27Z5W3ucsknEpc1LaOU7jVFc5VuvkVWThcU6zPdfaTmPOr2pnWfiYenWvPThEfSRc0p915DV5y/Fmms+rZq2ey3Th6qT0k+ki6wXLP6b2OYTzGrHavZF+X2vGArHCLo8ob9py7fOxcNo86vZh+fFEpClxxK/RuRO6Ayu26YB8SEcA2wThvFF+HxJHZFO+P6A7HOt9wsA4oDsgwI2TEEdkbxBHizqm4/LNyK9EqJA45fzRxUbyoDuKdUIcB21aiWO/TxwW8IROuQ6ojdVxgc/joV1l04CmvFPpHxCM+Xbp6z5xJYKpER6XDuFkHBMHwmgYaaCPiMvGVwpsD4gUiAO6TZZ3ieVyHSdxv6DbwO0RtQooSt0d4ujiUSlzrynnHFLKTKgF24zzR/47n9PSd4746IxSxrdHR4degnqXEAA7RDQGYmP7Lt3cOXaj4tKKUdJtunnIxvBD6msNxoQQ/vkGvjlxMMcRYRhLMydEpNPnmJhXeWGFOPKfpt97xIEbe9SGhe0d0dFPjnxvELQMceT/u9T4lq58DggjVNrTaT6mo7E9aqP4Gp0yvEdcc6ExtEmkecyIfW3TArM8Qyn7hJhv4fkW/fsi8jUJq9R7QpUBRsb3CB69QQR8DohDlsYJRw9KW+L6feLo+g3iOGi/TdP/8j3EhbfX6OZgTmyEh0iBUn49JvaBKFdmdPPraom4yEf+q7hOy1gOyxjfoz7yX0V7n5hrjS9hOCR4Eeoj/zcJeb3LeWf6zdLOu8Q8q9DfIfZnqCwnBB9S2pLm36A7evq4fNst394vONG4XCMOmtmllvHy8Yw4qEiD71H5X7l8jwignJYy2wWO3YIz6x6Xd8qfSfn2NrU+G1Mf0X2fkPPjUueNhDNpZQ7c/wD+2R/+Hvhh4F8D/o+l8W0irFwE7F8mjMYcQICax1eIzfxTIpVZeXTS4A3iWHr1wJhODquDlOX3CP02I45p18FSf08JeaE8nBU8vEknL/cI2a0dsZH6UnZB6IQ3iT1MwqqNoJ3itQFTQiZOUrk3CT6Djra83mCNkCPy8ilxWJO4ei/BJo96rL16fVz+fz+1tZHKDKhllsGgh8ShVfrtOr4HBE05B9tp7Jul3BvEFRL2reGvjdM6J/k5KOMwGGTf7xE8/oi4cqhPdudHOa4+OaZ2pCjwb5f2rhA61b43Cdob0dHEboJPp/g5goeduyz/1E+7hJzOq54tLB/Q0edh+b5dYHmOoN9D4gA4WfaIWN3Rxr1P6EOdtqNS7y5x5P+YwLv0ckTw5UPCxng7wSgsR6Uvg3V71PO9oLOf1olrg7TjhgnHAyLVdI/gJx28/LxL7O+dEPrzCR3dXC84y88eIc+dsyPiOhjtSelbGXuPsLuyzPb5eWIh46iUVyZd9HwsnDaV8BNCWSgAsrK7SSipHP0clXrX6ZCmQ/c8IRgHdILyeeKkKE+58p2ODURUPB/fv0W90dJog4ytA3aTONSBUv4mkTLh0fka02vEyZfvFVi2Sl2jfwPi9LON8rfGvUJGwaqiGpZ+ZcAbpa+DBj/iVgPWyMxNQrjbdo5AaTg+n/CgsMmR4M1SxtVIIx7CNS/fnxAn1qngr5VxezrQOnGK4ohaeB2kMo7dJxvnOYr5PPU+qxxFlHk1Nl1h1DnYJPLCs9OmYyrcB8R9V6Pyc6P0cUZsgL1R2l4lHGMdASM11wnDMjttRradf5n/BrVAER7f6TDrZEPtLF4n6FF6lo4UQrY3IE7sEvfXCg6cT/Hg/WNDamEmrTp/pnbMiLm5SSiLMREQuUHQyryUU1lJL8eEwWXU3ROz5qmNKZ2wnRGrGDfpV5gQJ6tajlL/uNS5SShK+UenbUT9ZJl0QpxOCCHP1gl5Jm79Jh4XhGEuzd4gHMgbqa5BnxFxiABp7M7BPiEvspPkYTZrpV3xLDxbhPOX591VumyM2Lc8IuzStXJNIzuvIPncpJvXo/LthIiKPpfKuxr3PLGx3HnZJ3jY+SW9E9/yw3qpf0bQr3QLsdIk/+cVzLPS5mVCpm8SPCe806buEeF4KjfHBL8avLmacGIgZJbKbzQ487Ra55qbwJ8D/nXg3yrI/Gt0lvddPhQ0mx+Ew+l8yNNG5SHoLffle3nGeRZ/T6j17PWEewi+Fo/SljpIPlb/b5b294m5fa680xG+QWSNSs85KLGW4HRedqlpEWKVxDJj6sN7cv8j6pOWNfDVUdokC4I3TxPeIGj0YXmn8a5eUF9dI07LhVjNFq/q5xy4MfAgTekUCI88mWlqQgRgrDMuP869smFMbeMsewbEYUuzAk+WnRkX2lNtIKF9Nyb0SV4l9VHXZnsTzutGA07aVbYvb2Qe7juIRLmxSTd30v0w/eRH2fh8+X9S6j1PrOSuJFzYh7wkb8yI7Ceo9wJme0Z7dFrwI01ByHvKOOU/5artGazUJmptthlBC8I1J+RjplFxeaP8XqHWmxSYPEnbMWU7O+PMNqx3Sj1nq2V8jkEY5M1T4rqV9dKmgSkfA/XKuL3S3k0ufj4WTptCJxvA0/S/AspomN8GdAJBpI6IDfMQJ+ZYVqPtlG7S8sk3U8IQJPUxatp7nNqcEjnOg6bcaSrjO4k1Czcj1seEQ3dKnHyTYT2hzt21D50pBatKck44XCfE6VMnPfjJeJ2l77MGHvs5S7Db7iCVE48Zx8fUq0AqaMd50uBEfDi2WWo7zyuE8e1z3Px/luAWrzPqE5CMhPlkAXKa6pxSn0x3Sm0gZ9o9bupCPQdn1DgbEidESl8LYu7ztzzPtv+EOPTEMYpX+4egQec+z4d4NbDgSnAur1Pg0/JaxttxTzkdlzn1Ksk8lcvznfmg5a8z4vTWTCv2ld+fLGnXftt5tU/lT2uMkcrlVWhhsP3Mh5m/dAyzTGn5UdlAgkcFnnF7QtC8ckD5o1w5ph5fhkHetA+DS45dvInbQWrnhDAMMi1k+nFMp4RCzMawNCcMyhBhF3+r1DQg32RnOuMvy44VQn6Ir2nTngZU5qEsX+Rr62d+cH4zDpxvnbbMc8J5SlwaLT06RuFxHK0uEX/CeELNr/YtToTZcRlIyTizH2GpOv+9dLmTv4XOwvgSHy7pOBfKE6gzP/LfWZ4od/MY1Au28zh9o+Aq6zRhy3i0neyUZNrMc6ssdu6yXnJcUKfWSnPCMyR4qc8xUI6rzx1HpuVZ08Zxqqu8NJgl7WWdaNlMg9KYckBa9RoUaU3HwnazjlbHZVmQbbI8hhNqmhP/NHUsm3Wzf6vvlj25v0z7x823Vgcte7JezfZcnkdl6in1HmJhkB6F17GcpvqOsbUH/V85nGkD6v34rR6Sfh4TtHjM+fnRtsyyXp7URtDehpCrGbdP0v9Zl2Y73FMc5Unnw3Fn+lcvtDabuM56TttGe66dq4zvrDd9nCd5rLWz+2gl67es88RB5sM8RvUNxCnA+cm64Dj93Z562T7PdNouXbo0Av4fdPz9y4A///Tp099/6dKlXwH8WTrH+j8HfvPTp0/PLl26dBn494D/EZ3T/qNPnz7duaiP76K7j2JAd6fGJkGs49LIjLhr5JBOV4wJT/Y2EZndL78/RzC+UYbPEkg1ovRZgtG8p21IRFTs47PEcruTvkFEPial3Kt0kbI5EcF4lXC4jKbKhBt0+wkc+03irpFTumXlIRGtMIJlmuWI82lMi9LPK8TK1hZ1/q34GRH3qZykdl4hlqY3iNSkGXUKxGeIiIyRJ6MFa/Tf0+YKmve0vUAcEZwFtfe0TYkVwi06OvEAC4j0oUGag+x0yRCU7wfl3WcIJeEeQ+EyCuPqnCt5d8p4b6Q+R8QKgSuGL9PR5ZT6nrZRwcdVQkhNiTsKR0RUxrY3iYj0Qflp72lbLf0qVD9V3tuvUac5EW3eTf0OiPQ5DejN0saniZQm7yYZN+3tEafHSQebBC3PS5mHhHDP97QJy4CgvePUnn+/Uv53JVD+e57uThuF+qulzgHn72nLgQTHRsLZKUFvY0LGyMP5MQ1N+n+VOjXxURmzK0oq+heIPX3vEamYNwrOHJP3lUEo7DFxD5LG8JCgZXEpD9wuOLhJNwdQr5a9T6R7H1Pf0/ZKKZMNM+XZnI5WlYtj6nva1ku/3hml7PBkQHGyTshDFeHL1HvwLDsi7tIZEvMiLCvEPW1G+U84f0/bPhHx/ywhQz9NGAp36GTQhEjReYmOTnTCjOjKX9OCH6PIjk2D/pi4kxEi/f5lYvV3SNyxOCfuaRtR39Mm3amHDoh72lz5pZR/ldqY1agQLy8nnL1ArA6/AiFQ58QSyJ+juwzqk8Afuwl/a49XXjy/59EgnbpDulQXvUJ9TxtE2pZ3iEHozQNiJeZO+XsnwfYSdZqS2QRjIpXySYH3VpmPSXn/YmnziODlCXU6+iZhZG0QdHer9KNsnadvw9LebeoMiFPiXqkDOrpyjOrKV+hkpPMsbmdlfAYflcMrxD1tJ+Xdy8Sx488T20dulPaHxMm214l72uyzddYodT9DvSdvQqy8XKPjJedgXNp6oZTbI+5pu0Lo2eulrLpw2fM+wS9ndLzyEmHjbRQ83invoHZ25s3/yrFn3dO2SdzTJs9PqG2sWfn9IkHr0v116nvasr7VmVFu3aHTaY59nf6VNvXhZ8r/Mzpau01sfxHf2iRTIs3T9GED8jo714gU2U/QzecZccfftIxzq9TfJe51vUbIQGlFJ9A2sx3QZ7PtlbGpD7W7h3RzII3uljov0+mtA2q9CeEcag+9SH1P25y4py3ThXP8aWLOdulwrp2yT72nTdtC/hEf+Tkk7pPTdvo05++Ja5+PstL2BPi+p0+f/uKlS5eGwNcvXbr0V4H/NfBHnj59+mcvXbr0b9Nd0fnj5ff/++nTp5+8dOnSbwD+EPCjF3XwlEDoPL337xxpzZ7zoinX1pn3vGvLzVPZ3H6us2jKtd57Wy7DkX+3S/MLlsPcjq/FQV9fNGXbcff1NV/yd67/rHctTtq28jiWjWnRfJdp+sZ+0Tzk9lq85N9942PJu2Xz3Vc3t93CC+fHtAy/fbTaRwfL8ND23+KPj/Au02tfP+2YW9hWesr1zfsy/PXRdTsv8pWOSx++276WzWvuo31vvb7UyL7x9/FTW6aPFvvqL8PRMrnYN65WLuTfNP+3c5nrt/JsGT22ZftgWiZLlvFI/t6OdZj+76vXJ3va9vI851WiZfy1THb18TScNxj7+Me/h837vp++Pvp4kebbMj5o8eL/bwKr/3SXBXmPOm3NCP9v/yf2uPUK/IvHdGmTf4HaazMtw4jiEP6rfw9+a0+/fTKpha1v/kjvnqUD++ig7b8P3y2+FpynlZZes2zq45cWjmVj74O3D/4+OuyTN8twQs/fy2DrG/cyGu3jtWWybdm39lkGW9/3lSXffRZLyrbyoK9+n77ug7WPhvvaze+z/JhTp272lc9jXSYz2vnqG3sL10X2Rp9e7vvJ4+7r61lyK+v8i8bS6pcMS9tWO5Zl8r4dazu2XN/fzlmfTO7TG33l2ueZTtvTp0+fAr9Y/tXJfwp8H/Aby/s/A/wrdE7bD5e/Af488McuXbp0qbSzdBCbRJ65+dcG9lzKNUK0QURjDol9TuZ+j4k82IfE5sxr5d31VO46nXe9Q31yyyT9f0isbq0VBOwSewVcsoZYoZkRN76vEyshEHtuDqk3pl5JYzKv9iT1cZ2IihoFHRPRXCPZpp6tlnbmpZ0b1Hd9PU9stH6+lBkTkTThNfpuWpP9jKnzswd0c+gKJaWOecJGSeZEtNG0lJsFH8KqQXitfLtORK9c/RlRpxiNqfcVtlGb66XvDSKK6WrZA2IvltF952BOXDZ6UMbk3ofjVNfVJQ0Zy1wjmHFE7GEU13tEZPFGwvc+sVIsfT9Pvc/Sdl1xMoo+TP27OrGR4BF3zs+N9L94NGK+Wfr9oLTtau844Vf68724yLRs33OCbsV3qxTtY0JEcR3P8+X/h6V9V1xv0PHeNWIvTl75tT9X2laJvS/yzHPU+/dciZH/+9J18oq7vK7A3it/3yBO63SlzX2sa0R0dZZwpkw0qwBipWFMzIt4M6rp/6a2Dajpx/63Egyuzsrvppy44rMg9qqeNrjIaSPyhvv5pmmcOTX6coHzOrGC6mqMslQeEfY5sSp1k9jgf52QgRot8qbyfIWOzsRDVqpjYgVyXMY6TDiWpqRN4dkj+HxMZCO4+gax8pBXEYfE3klSOWlemtY5mhP0e9DUXS3vrhAr7+q5PeKiVuWovOQ8qhc303ezINyP4wreLnGAh07lSWnna8DKm/DLfxz4Z9bgH/6/wd/+3m7Pm3m2A6pc0V/+V2D8C/U+kicEzzjPWW9m3eOYledG7cXjNerFQf+HkLdZPqsPbhIrD1luHJW6m9QyVXq17vXyfzb+XGlT790gMgnURTNCJowJmSp97RP0cVDa1w5wJcU+pVFl4Y2Cx0NC/885T8szYv4dg2NcEFlK6kHxo702pFsxkKaeI1Z0xgSvudJuOdt33q5zXoe3j6tRyvQM93ViNUk6GZxvonqU9SPC/uhbaRtTZz1BnLyoDXqN0Bmumqp3Mw1Q3u0TOtcVY+HJe9q0P1s9dETIhhUCr88TK3RZFqsDz6hP3NROkk03CZtPPt0ssLiqZLm1hIPnibTOU2IOzDoYFPxeJTIt2vk+47wt5vguU5+lME7jOCH0v+8pY94h7OGsP4/paFQbIj+PiKw87VpXt/OBMvLmlKCBQU9dn2uE7Std3aC2l/qej7Sn7dKlSwO6FMhPAn+cLptn8vTp0/+mFPkg9fU8ZbXy6dOn/82lS5ceFVh+oWnzdwC/A+C/SyhrhaFCbEQQ6OX0/5D6vifrrae/M4GvpPejnnqjVIbm2ypxnPq0p/5q+r9ts31Hej9ovq2l/zU256n93O56wodjhzqSIY5UgGvEsb7+b/18R4v95v4yjFDDZTsZH6up3Goqs6B2Xi4T6aerqZ8B9Rgup/bzaUfCm3Ga+/Mx0JvpgFJuGY6dg0V619Laoqlj+WEqs4wW1on0xxaX/mjgjpof29IWGqb3C+q0s1PiInnHl9MSWtiyYM24uNz8n9tbpx6XdLIMjyupnLjPUcI+WPv4vn2f8dbirOWraarrYzlpL7e73pTNdfI42voabNJeS9stjTtXLV2Q2vOeIHEpblW24lLZ19IXqS6pfWVcxm3mI/dxOOaW/leb361sm9FPz9mxybSTYZ817zJ+dNylXeeghSOPK+NSeTps2m3L0rzP8Esf7dzKS5cJustwWa9PxmRaanVbHsvlpm6f7lPWzYh5bPXWnLp/DcmM72w0ntPTp8C/cwo3vxf+oT8Kv+K/Bz/7m2rvJCGope+Wt7NcHS35Ll6y3FsjDnTKNNfSTSuzWjy3NDDoKS+O8hysEk6+31t+EB257fWmDeHuG5MBYeegT+720XufTPxw/npwI/6VLZbJNpHB4pbf1nvaNEjV2j+z9H+WgcuetVQPQqflH2XfOudXpxbNu4wj65F+Qz2PWQcqM/voRppd4TweoN7naFxj1MDT6uNWD/ku6wn7kEZyv9luanE9TN+zXM1yJdNFK3+y/ZVx6hzk9rT5WpyI62yrOl+X6afrjIfLPe0pq+0z20RnTZstXeRxQNir6+kn41Zatq9MKz6ZT/K423Lt85GctqdPn86Bz1y6dGkM/CRd6vB/q+fp06d/AvgTAFuXLj3VmJ/1/LTLmfNUdtH8PWvaycuNrtqdNe2dNfVp2po35fL7LMjyu1nTphFmyy2WtLtI/5P6Wknjnqe/ZwRxz1N5COJpcbtsnHkcLKkjbhZNHb/14XzO8n5z38K10lO3xaXl+tKYrJMja5mOrN8HX4anDw95DPldLj9r+lmkd/nvs/ST+xikv0nt5N+ON9PRrOd/21+hhueM8/Scx04qm8fW1svtteOCmpZbPGbeyv3lsm0KwWJJfR2XPLYMm0J0xnm4W9psYcnv+p4+vC+TT1nGiLdhz/e+Hzg/12eEE3iW/u/jw1aeWpb0PsvGPrrO/ee0r5aPlsnyzA+Z7lWamXZa2PvmpC9l5yJ+aHmmb87PSjtZJomP/L6vjTyHLc08S17MqXHS/j7rqdvqrmU81vJDy0uLnrbyvMyassvg//CfY+Av/N5uU86v/GPAX4D/6itdfuWED4m05Yk+GpJGW73d8soZ5+e6lfst37cypq+9M/ph92+a/1u5Nk847JuLZXzV6qt2jpfJK5r28/eWr/vkwuKCtlq+avXlMr5qeaJvXvpo9aLVsVaG9OEy03bb1px+GyHPW/5NaiuPM9dt6agP93mspPd5XBkH+fsynGQcD6j7crwX2dh9NAn1GPvopJU1fX306Ruo+VXdlZ3Rdi77aE9Z7RxlPsnzY5k+mdj2tWycWZ63NHBGBBAyv/bRis8yHmrLtc93dHrk06dPJ5cuXfoK8D3A+NKlS7+srLZ9grhS6AHdCuMHly5d+mV0q4OHH7WPleZn0LwfND8rPfVoyuZntalH01Z+v5K+53J9P31jXTaWActhacu25frGm9vLCrCFvx1nbmOF8zhoYfNn3lOmnY+23776fTC19TIOltHARf31tZUzdZbNRdtmO4Z2jpf10Yfrvj7pebcMx8tgbuduGVzL2uzji2eVb/v3acee3y+jsay4+nBt/RY2mnp9NNaHi/xt3pRbxp9tfxmmFvZ23PlvYe1r96J+29+rPfXsY96UX8ZzcB5XffO3jJ5aGbJs/C2O23Fk3C+aNumBJ9Nc28cy2oAaNnrK981/nyzvg/Gj4CL3yS+hfN/YW/hauunjl2VytR3TMtjyWKq2LbBKd1rEO78bvgz88n8GfvlfgL+zDV/tynxUHdvC1wdnXxvyQVuepkz70zcPfbqt/f+jfLto3G0/s54yffTYyu0++m3L9emKPrmZx7SgH4fP+nkWXi/ivWXPs2T0MtrOeGr/v4jPMvy5/76/l/W7jNdo3vXhvq3PkvcX9d+Hq765yPqprduOuR1f31xcpH/7eL0PHzTjumjO2/f5aXnpor/bvvr4cJnNsKyuTx+unkXz1rvwuXTp0mZZYePSpUvfBfwA8F8CXwF+fSn2W4D/pPz9l8r/lO8/fdF+tu/kaSNbvsvf+yKuNO++06cv4vJLacd6evz/bcaT24AaNxfV6/ttfZr/W3gvKt+H53nzd9tGO4fPGv9Fc/tRYf+lfL8I7mc9y9pd1s53Qg8tfvva/ajt9dHUR+l72f/tXH3Udtr3i2f8/ijw9dH7R3n+vyU/fL4T2nkWXp5Vblm9ZTBlfs9y9CKZcRHNXTT+ZXj4pciwZXUvaueXQjt9dftkWquD6CnTtptXNy7q+zt9niULPio9tmN7poxpkQTwV4D/6x8GduC7XoV/4FfD3/+dy9O+btrnO5U3y2TLs9rqK/NR5/CXKpO+07rt2J6F776pW9besrFchONnPd8JPj7q/Lcrh/T8/0vpf1ndi2Dtkz3Pwvl3yiN55fijzFf7/0fhn4vGtAyGPh30neqvi/7/pbb1S3m+k3l6lj607kcd10dZafvvA3+m7GtbAf6jp0+f/uVLly7dA/7spUuX/gDd5d5/spT/k8C/f+nSpXfp9kf+hmd1cAJ8m25j3IL6cu0JcXzuT5d3b1MfQz+iy8a4TpcP+haRz32fODTkQWn/Lt3N6AfEkcm+c5Vqr3y7Wv4eAT+VxnS//G2O74DYjDum21j6LrFR9qcJD3q7tP2AyHc15/cecSkoBQ9vl7r7xCEq75Q23kn9t+lCw9Kv8HxQ+nqTyJl+m7joeFZw55LzV8v7ScKH/TwiLmUcEJcc7iT4KGP2wtYDIv/di833y3h3S7371KsHJ2WcbxKHzjhvwk3B5dvlb3OscztnBbZ5Gas4/mrp4z6RW7xeyrxb6jq+o/L7rOBjs4wt14XYqH1a8PEmcRxyznXfKGXvl76+TlyuLT5W0v/XCs7uEpcGO75J+f+AONzl68Tx1NKXz6T8PCQOoJFH7hPRn4MC61HB70HB21pPewdlzOsJF3vUy/37pa13iTzujfRdwWXO+2kZk+N0bnbpgvhjIgd/r/T/RmlnUOoflrJD6rvZpK09gua/XsY2LfX2iGs7lCPt84CODwd0dPcVYk7epcP/VwoepJ8FcajGiOCvQ+JAkbul/FcJXN+no6krdDx0nMZxn9gYrgzYL/8/Ln0o9+YEfUNcmq0sfUzw+98oZZ6UMc2o5dkuQd8b6f8TgldPS58zglY36HhSPEhzwmAZYZ/Tze+w9PEOcZBSlgXC43gdyxFxuM1R+XlccDmio+93+XARiLsEj7xJHOoxLXXFt/phg05+mxKjvDCKOiT02pzYJH9Yyk0I+SyMx6XsSfl7mzgki/L3NqHvDsu3RwWePYKvp8SdlPfK/+qVDUJ23CV42ZWejQLvfeJyW4iDj66UNm//WBxGlFdnxMGMBRu8wWtrb8Dr8B//K3SKteTprPzt7lQzL8H9G4Qcv19wOin49lCeNeIgjWl69xZxAIQwrhJ8uU7I58elz2+Wtu4SOvGYOKiA8jsf3CPd7dPJ6Hucv2tppfQ3IQ4TU/7sEzSpzr1HpEp9rdTdJuhsp+DVMZ4Q9gbEwWHS7TzBoHyZEEeNv03oxAfElQcD4joQ0phyO8fU16jkw5IeF1zdI65u2Snl7lPbFvME35jQhcue/TIOx3Rcfp8SNHxUyqoPLnp26XCoPll25P9hgfU6oedOqG0s6Uc+eljKydd7BA8f0x0SQRmjNpJzuJu+qTNbWHbo5smx3iMOD5qU8T2km1vn8wnBK+q4WRm7DoiHhB2kn28X3GjPHRO0cFBwcETQ0X4qq9ywzXvU+2lbm+0uwbe+Uz4eEzT6DqFfnPcxtW0hXtSxtkHBzzsJP/nZIfTOuLwTt47hiKDdM7p5u0fw/WnPWOTNny7tvQt8o/R10fNRTo/8L4hrLvL7beBX9ryfAv/Is9rNz4jYJPcy3YkspwQxaNi/Thj/W8RJg5dL/ZvEXWfrpXwm8s3yTqReK3VeL+2f0qXgU8p7L5aO1evEqX4KynFqf5LKiXiJ+TXqQ0H26SbUiX61/N6jyzX9nlJfRT2kO1nGk6RuEgypwWNerEaP/WogvECcWCh+NIxeJ04telLqvFba0BDQ8JUxNgoOP5vwIGFuld/rdHP6ShnvCeGY36BjiFnBu30pCCHu0jihm++N0vanqTegvkuchrYG/CricBWIS3AXBI1My9hl3HXiVCvxRRnfmJizl+juOrlJGIx5k6qC9pUCl/gStnW6e0fGxF1Jp6X882UMV6mNveeJUx51+NcJ43yrlLtCGFKvUt/T5t1vC0JwvV9w6QlVGmUqK0+C8h6rPeL+k9xeVhDZ0H6OjrZWSjkV1jFxAISOP4TT9hpxN9s16jvbXiOczGsEj2/R3ZV0UnD+OmF0eyfahDBcJ8SplAY7Xi3tqOR0jjaIuyTb9AQdoQExtzpM4tp7ynTUoaOhtTKu7YKXvYQzDY1XiVMQ5fVr5ee1NP4RcYmn8MhLnyy42SLukLyV6u4QcmFCRzPrBa+/qrRxQtDWawTvXSvllRNbCbd75f/vIYwrnbQx4SiqfHWs5wSdCbtlRwV3lPJ3qA9/GNDJDcd6WMZyo7T1chnXPnEymDQq3wxL/TvEHVcGoj5N3G01Je5mGpfv09Ke9+6pH4TtuPTxXCm/V3D9KYLOR9T3tL1GyPqXU10dKI2uhwXGfAenuu9X0dFHDlz4bbO0K86UbzPCWBmWsdwofy8Ix+OzhBM0TvUof6+U/zUUd0/h1321dPq17wW+AP+XH+Pv+11wey9kVpbj6k0dsOfp6HpMxz+nBb6X6fh2RhjAN4n7FvfLuF8h7mnTrvg09T1tnytzMEnjMBB2Su2c3ibks4Fm5ZqO750yFts4LjjTZnmVmMcpcd+k+N8gTgrWJjIQAiGH7tDxnIGTzxCnVd8kdO0NglZ0gKSFDWLudX7F6Uqpq032mLgYeETQlLpbG+Qq3R1yBtK2iJNbz4iTDK8RunDZY4BQeT8p49bGG5d2XyrvsuzWKcmy/CrBYxB33mUnSVpSZ26kstfp9Mw6IetfJmw8ZfQmHa08l+rqKA4I/jwsY893Uir/5C0f5+qzpY156eMOcU/bLh2+P0nowF2CptaoD5VRzwwKHl8g7ml7SJwuO6G+p+0mHW+5sLBO2NnOgW2eEDaROt/Hk2Svl7ri/7TA+ukEt47WK+XvAzq6vpbac87lNWkFIshyq+CtpQv1sHPmHYHZbtce9lRTbcMN6ns5fXSCXyMWBV4hdNuy5zva0/b/q0dDW+WdjbhjOgSfEZcWWk4jez3V20jfx6ncCqFYrSex5HcSzSh9z+UgVtg0inQepgSDbqQ2NJiNFmzQCbn8XeNVeK4k/NhHhnFMvXKjMzUjmNZ+dVSuEAa1bYh3cZ4dJiNjZwnHMl0+cegK9XH764TRfrkZ74CYS/E+78GZT54fjZn1VFY68f+V5ruPBuk8jXuQ8Lye3lvfb9aRFtaIuaD5RvNOHI6aH+EdErSXcWD0f5V67sdNOzptGoeeUOcYxsTKWIZH4TdK7WpYiMfV9P1KgnGD8/iZpjGIS0qZzdSn+MgngMqfUEf2M37XEhxXqedK+s80pdJeEMbVqPyv0TEjFKlOjjjTkc70vEF/5DfTYqaLE+KkNGXXWoJVXmxpK9O8zo24Fhd53khjn6f/lZWkfsZE5N26jmU1taEsyzJE3oKQZ/LulFgJFVZxK+2dEcEu4VpP/WTHyzFl2O2rrSv/5OjzmJgPjbrM2xvECkF+J16H1LQuzlcSHpWZG025lfL9lHB8ddoyHMJltPYKNS3oeCwKvpXpua595Plr24KgSw0m3w9SnXHP/1PCcM86Os8TnNctWd/ZhrKf8u1sAav3gX/nK/Clr8Cv/RmYfw83fn1t4Gq4m4EzTX04D8LTjsW+NtI7de86IUtOCJ3mMeTS2YI4aADCKF9QZ3Rk+WPgQZps6Wmcxqt88bs4hrBb8vilM/X6rPSljnQOr6R3GuTCqLMjLfnujFrXSO8Gd5TPmZdmZax+95vf1V9ZJ4rPLM/6ymWd2j7iAeoTWccFJi/KzrR90aPOtU9lSh6D/7c6UNme5YD9iotZet9Xd9CMMdvDUGdltXoo22Ir1HM4TWXsVx2YZd8GobOUVcqvVi9lO11+zLpMHjwl5kBaEM4Jtd4b02+zGUj3XZ8NJR1kOy7jGGo7Tjslf892cX6ki3Eqn3kx/4hb+1LWXmn6Io1zTNjy7Zj6no+F0/aILn1on4h8Tqk91jndpW/HdGkPO0TUbFj+d7n658pvV6lcmr5ayr9DpJRs00U0fOdy+j6hEEwfhDpNRaIyGqNT4crDDvVkaKy9T6QFSDwK1m+V7/ul7JQu3UtDwJWF62Xc9wgGnhNG/JyI3hj13yRSMEfUqYxTOuFhWgaE4nR18YBwCCcEg/j3Cl3E4AO6FRtKnYfUqXVzYgXjoPTzRoHb5XKf/TJOU07W6FY27lNHzuxDoXrStDMjlv3XiEioBqqriNnpMDKyoFvZelR+H5TxXC91TVvJkeVDuvl9o5Q9TmNaJZycWalvG+NSZo9Ix1sh0mKv0dHIhIh2U3A0LHA5l8NSz36zQDTKu0/cobNS8PhtQrBepeONtwveD4nV4xwVe0TwkUbdCvBDwBe/B/7vPwN/rtR9RDd/Gd/Sqc+k9DEtYzTyrPEhfjZSX0Z3TYN9RKyobRL3ZM2INDXbl2+GxL1Bj4io3GW6dIa+TcAP6WgLwpEWJzsFz3+eWGm0L/lwSNwnqfw7IdL/slJyRU4ll1MptgnetY+D8v+DhB/f5cifvCnvHJd3WbYoH6ac571jOmN4nbgDbEpHj9sFbuXShDBAjMbqEGkEzImAnbC7Ijiki/Ln1cnM64M0zneI1aP36ehFmT8hHPMTaj4c0M3pTvltKsugwHs/4duVYOGZlzKTMjbh0mk5Ld9dqVau2Pfdgh/xOCdScXZLOeseE1FfDSFhbHVfTiE0BVi9slHGLs7uE/da6gRsl76MvpPa05jaJwy2vlWN/PcfAt796/DqXxee7+EnrsK//gT4PXTC83Z09vfuFAC1xsfwf/55+I+I7JcpnawaFTjOiMwOjbUJMXc3iBTaSRnbW6Vr4TEDZa98N0jxJOGd0u+41D2mftRLytqrBI8cEOnqyoM3qFc8nFONUeWIttEpXYqd/Sof3yJWEpX3pqY/LmORlo+IrQvvJtgeUJ/aNyPSyJQVylNX9sZlnDuEjpRH3ihlv13aGRP6uHVs2xWl/GhbqO9OiJTkd4hU2mMie+SiZ4/a/jgtv/MY5gWmPcK5t+w+cc9qpsH36eSN+mVMNy9XU91tavknPA9LWQg7U32Xn10ig2VAbLmQFk/p8LVJt1o0IzKAcqDojJBhEE7gEWEHaM+8k8a5TdgfY2LbzYRIEd0jeCW3qW1ywHmb7VtlfMfpnfJxh5DV3yzfDwh+gtpGofR3TDcfp6UNCJl4j1hN89kjaF0H+ojgsRHBu9p0U7p50zHeSXV9vkWdXnmXDu/tilz7fCyctkuEB54V3Ao1cQ4Igh2kOm35QSo7TG34LvfT9jdIZdt2NTLbb4PmZ9jz3pULevrOzJjHDvV+gCE1XLntvqdvXI7N8eTvi/SbVLavrzz+Fi8tHu1rlVppr/aUy3V9387ZsPkN5/vvi0a1+LDerKnj72ywtnNtubMGpzTlMs5J3y2z4DxseV76aCS3vwy2OefppIWnHeMyfnCuMi0Mm/ba+v7+JvBP/kyM0XaW8Z2PYzpLZfp4rW9eVpo2nEv/X/S077Oa2mlhHXJ+nHCe3l2FaMclreRyua88t5nmM66HPXUh5iA7vo4t9+fPnJo/Mi32yb6VBqYVajhbWKdN/bwyk+Faaeq3uFxGZ8vodZHanjft5b5aOb6MploZmWEX361O4oLx9c1pH13nsqQ6w6ZuH8+19JNxqTPfx08tzoRlpWmvHVeWIX38fdb8DUGHmT4A/tNH8A/8PcA/DfxP6aw9o4AtcoY1TrJcyzo442m4pMwyml+lc86yvF0ldEYfjlvZLJ4y7dnGjP6+leG5zQyr7ec5yv1mmd3y2LD5u5U1rU5QNvi0+lAdukyPtO+W2Uc07/p0eH7aucq82eJymexu22txCOfr5X4cn/Av46tWBmXYptR6Ic99tiuyrugbU+bZPly0sqOVp7muT6av3F6WF8vk40VyrY/X+uY7y2Gftu2Mj75x+OSFDGHL89fKIp9WH+R3mWdy3WxTLoMt80Eruy96PhZO2xXgC3Re8KvEXqFjIsp+RncU5REdgFvEpt91uvzULeqUlS/TebP3Sp0bwPfTrepdJm5E/wfpNgBfpsuThU5H3Chl3int/Six0vBNOk/dNJAhsc/r1xMHIhip/1GCAd6g3vQ6Br63/J7T5dV+bykrHoYFvufoIqBbRKTBKLWrWE9K3ctlLLMCz21itW694PybZaxfJjZLGun+kVLugIjGKaBdibxexnq9jOHN8rNVxrBDl6f7KhGtmBW83iztLuhyr7/NeaH0IvB5IlI8psut/kyCm9KOkUHnvm+pnfLdqPMPF/x+i0jH8JAUc8kXdFGQfTpa+nTB5Vap+3PUKwJGcF6ly0n/G0QEyHI/RKQufLO8+zKx3+BeweOAbh6fp5v7rQLzXoJvRuzZ2iHy1f9BOlo6oE4xcAXmgC46+2ppf4WO1iGE4Y3S5+foNsl+QJcHfrWnvR2CnsXF8wQtu1Li2P25RigqjYO/n1iBvl9+XIX6chnnXWJ1fVhwcKeUmRUcH9LJj9ulnBG2EyIKa8SQhLMTYlX+Gp2MepE6EujjISSDAvePlPd7dLRxVN4ZJZRPXyIiy28T0dKbdHT5VTo6+JGE62+VNq7R8dDnE25zhN+I+E75/07BwW06PpxT587nzIEJsQK7ShwRfErsmVSeLejmRnq6VvB3SKwM3aKTNRqp+6Xu9fKzQ6y2rhJ7YL6vtCfsCyKL4kXgZ0rfd4g0NY2IT5X+x8Qqg7LT/bV7BdZrwK8G/jO6ufjhMr4rdHrl5fLe7IfP0PHDt8pYbxErA18rePyB0oer/xpFp6XPL1LvabtLx4frRAR/i1iB+Hz5+9ul/7yn7duE7Noj9m5/k4421X1fIKLuG8QKvHru08Q+7Tt0/PSklLlW2nuDkFELIoPgy6XNd4k9ScqnKWFoSfsj4sCwHy5tAvx9K2XwP1le/sSPAP8N8B786XvdpO+Xzrbgh382VotOy3g+VT5/tbyb0e0Tv1762yuwfH+Bc4M4MOEHiX1I68CXiMj9vTLGG8ThDmNCJqgTBsS8QRhlG8Te+5uE/HEVYr/gwtWDUzq758tl7D9X2tik0w2z8m1W2vpmGetK6ecLdLT0sKDUzJwtQq/fJGhlt8zVDTpacC/PPc7vabtHJ9u/TPD6hMiiuFnG+VrB0zcKDGO6PVUHpZ1bxP58s2A26ehni4vTI7epV9KP6HjoC3Q23gNiD/YPELbCsuce3Vyqu46oHSEKDp4vbd6kXnnZpqMBaW+DDo/fJmTuiA6/d6j3tP0cYaxneF6m3r/ranGrh94s4//+Muav0dHAi8SK1w6xz82V0R2CptbL+2sE7W6W9nZL3VfL9326+XGc7uXbLXh5lW5u9gtebtLJvOzgmPmgDvxezttsrpJ/Ob3bKLh6lUiPnJbvrxF7RH8d5/e0fa3gY5duz6f6c0LHA7cKzvLzFt0c/gD1nra3S3/akxtECrdZYavl/ec4v4I2LPV+PZFV9Q/Szc+Ps/z5WDhtT4iUwG1ic/MJsanX1JwJkabg3y7tHhOpA+t0yN6mY94BsWS5Q6QDzco7Ny+6ofEhsfS7T5dKcJdYWt0r3x4TjsaEEO67xObCnPICcXCBxssJkY4gbC6Jn6Ry84QTYd8jcq9ViBqgwzKWeYFrVvBjOs2YSF1SMO+mdu6VsZvmtUc4bYd083ZKOLWDhG+Z3vlZJU4wmxGnt+2mMb+bYNWI19n4gNhQ264iQRhhGs73qCMWZ8QpTGvESWkK/QfUudL2Relvm0jH2CBSU04SPttUiY0Cl+mw0sLlMr5xwcdOKX+fSB17j2DkEXGQyiPqk7tMWTGas0co1vvUp1bqtEI3fy7xXyEU1A6RSiJNzUp90608mONK056Gxymh+OQvnweljf2E7xPOO20GYzT89xK+TWXeI/blaRAqS3SQjqlPrjqmPunMuZJnNP5OCPqcEPshpbf87JQ2nCvTSw4Ix+AeQQumbEHMyw5x6tqCkF17pa64znCfUs+BshOCp5Qnyo9T4kLN01R3l9hnIs3I7xqryocptTzbIeh7QiitKXFi7ziNSdpVee4RARcdmzndXGQ6U44Jy04ao4ZujlCflvZNkxX+EZHubVDsXsHfPp0yHpa6GkemOEHscRDfGhJXSjnxoz7J0f5p6e9tIk31gNBZo1JnlPAIsQfPb9Y9JIwfA4fHpS1lMYQxJm0/oOOVFUK2qCOVkwbYBoSueEisVIvPKZEW7YmueU/bspW2+6U9U9kAthbw3TLdIfAHfrKzkL9E58W/BPyzfHhU4Dt0c7dDBKs0vJ2LWelX+avuvV++f5C6u1/GsUvsqZuUH/HiHPpbmaATK8+rA4V3QgQljohDYfaIoMc7dPrBoKJ68SGhZ44IJ0C5opw0qL1KHB4mXJPS7iK1Y6BG2ld3DAmdfp/atpgRdKBNpjw9JtLNpUNx/IjYz/aotCHN7adxHROBlotWHXaJ9EvnYqfAvUPw+DU6fuyT3fl5j9BLEOnQ2UFapHFOCJ36uMCoLNgp37SJHhIrPco3eXhCLSeEx0Nd1E0r1Htk86MdZ9D1A0J/61Q790/o5mBK2GcHxFzpQEPQtwGr1QLbEbE/fFK+GTSapnLqQGk1ryjtU9tdb1E7bWfl+wlhQ5wV2ORx8aGee698P6STsVk/QvCDvobfteOk7/xoi2WZ/YCQu+vE4sy4jFF8D4h034fUj3bcPeKApXeJRZdlz8fCafs7dIJBxO9TE+5jOgIxsrlDbHpXaRv1UpmOiDx8DSoR/i4hRCalvu8kVh0jBfyILhpiNG+HyOM3inha2vo5QmEfl3ffojYAJoSDYhuOV2cBwqhX6HsimQJ6h9rJWVArxm8lnGosvU0IA52R9VJvmyDan0+4dc+NguCYmmk0unRWNTZ0jk/S33MiMq2w3i/4z4YSBBOpdEbUJ/MovPYJwbeaxpXbUSHbxowucjwtdY3WSzvS45xQxApfFadCbkhtpBhoOCCcJ8esoW7+8/ul/Tfp39OmMbZB7DcQF3PCmR+Ufs9Ku28Se2GkL+Ex4q/iNqpqvxRcWuaEWO2ap/Hbnop2jzCOIIwxy2nYf9Dg2yhodmYuE7n4BwTPKyQ1dqSDI+Lqh0WqPyF4zci7jtuUmFMSzmYE/6tUpP/2ybSnnFjQyS1lwBuEE2VfE+o9bZP04/6ofTo+zHvaVBCulsj7Gg3iWsNAQ0An1DmRviB4MzsWGoDKkGnp/4yQZ3PiOgaNtAPCmJ8QgRZ5X0Nggzhq3Dl0rFDziTDptB0kXGhk+gwI51F5KkwaheL5lDg44P3y8wYdXeqUafQql/PcyuPrdPSm/Fwh9qoJl4EF4RuX3xPCER8S+z2leY2jEyJYmOvq8An3RoJd3ZeNLL/N0rcNQiaKMzNcnCsNwwnBrxqARswzbWaezkEgCKd4h4hQQxeR/24HoDL9Nt09ACqNH6Njij/VzZUrTOL2mNBzs9L/hIh8T+jmbp3Yn5id9yM6GesBKDq66oMDwqHKssu5uE/MW05tGxV8PSAOqpkStsYxkW2yQ6w0vEHQ54h6T5s6INO6PDQvOJBunVNRe5xg2SZWB7Pjb1aHvKt9YTtrCQ7l6QHhoImnbSKwafu71IF5qA+Wu05/ZoOPttkTQgdC7E+aEMFIn/x3G4RT9+UVL5ox6JifUR+cYfBPW/E+YWdkmStfH1If+a/Ode60mc6I1VNtgdaRhAh+OZ5tQn9NCPmvwzJL7y7TOS+XCTtJPexK4oRuTo+JfWHaGtrEQ+IUVp33R2kMyhthOSrjXCUWHlqbbZsIZkl/90sbJ0SwbifVs/+sNyn1vYLnkNohPqVzzsRPSxc7xJkD9qHucZ7lTedum8iU0pnPjzbtzxG6+duEg7zs+Vg4bavE5v8b1BvZXVGZ0aU46MFuEpGBEZHioUMzIpZvVaLX6ZY/PTRhTKTzOJGbZUwzIk1ultrTCDwmNiZKbJMypi0ivcFJe4EgBI0Mf1tHp22TSC+cEqmHm0SKxyahJHUaXXVRwI4KzmRAj6g9TH0abf8EsQI2Te9G1HfOaHgY9dkg0gRUyqelL8djWp8wG3nPaXFb1KlTvr9Rvh2kPjdTe+JUIaBy9LuPbUMw+hlxvPsp4URoxN0o5RUWKt0bxHUQ0qnGt31R8LJFbZR6aukWodSkqZvUimpKCDnn/hqdcb6Syi2INAb7n1IfLS2d+UwIR3uLcNqgPjzBNLwtwiCQVtv2VomNzSqP6wQtQzhAOkNDYrOz9DIgaE8ekp7Xyjeo05NWiSsRdJilb+dSQyUbd64m2PfNUnaa4NOIkK/bR2c3054OqriXvuVPiDQzceV8mho0KeP4RBqL8kz79VYah7wH4bTJ+9LsjdTfjVRX3lwnjF5hy7JI+ZDl2SDV2SBobkqk5okTnWH57JDgrZweKX6MZArTEyJdWONpM9XXUJav5b1TOrxuEGlX0sNGwaMHXznP+2UMt6jvJnsulbd/ZaH0tUW9Opuj6Kfl+7i0t17q3CSc3lEZrwb3C6nt5wknRyNBA1sDTNo3QCAfalxrcA2IK05uEXMsvWhobRDOizLK+ZgmnK4QB5FkeSj80qT1xXd22rhGRECyIL9PZ3W9SZdT9O2X+S2De7y9CPo9TXicEPpG20B+mxBpigZ+pNUXiAwW5Z70LL50UMT7gJDfu5w3qgelf1N0rxF6R1k+oJtbHVp5XXlrf+qNeRmrfH+c2pHntA9uEHQmv4wIulDO6oxIv/KUsksefkKtF4RFeXqdTqco9+SzNYJ3tXWuE7SxRtDPZg8e85Np8IxI9b1F3LE2T+Psk93tk+0P+26dtmsEDyonjwn6MTA0KmORh+Z0c3GNuILCutIWxB1qeQsPBEtku8cn63zlsfaHvCtd3EzltQtMyVY+Z74flB/tOGXqJjG3NwjHS/0F4Wxlmw1CVyrrLjffhWmHsFV9py2YaXS7fDd9cUidvurjvOQxQVxnI37yY0Agy2xpT97UHspO2wHB93m+fXbL91uELf98T//t87Fw2taIe7deoUOckVtTqWZ0ObGHdAxpjrqG3Mt0AG8QqxJfIgS1RPel0udZqX+zvFOhvly+jwjDfJja80S5OXGU+JB6NeRLxP4vV8a+SBDkBrFCOCxtvE7sm7iVxnmS2toquFEYGsXPTojRVGH4IpFqdIs4An6DLp9XR/GLhCJS0X2ejhAPiRTIVSLSNqZj0M8TDti1NFbKWD9Nl3+8Q6x0aEAa8X2RMHqyUHqRuItmr7R3i27fwiiVu08Yiet0ee0KVAhjZUF9ktrn6aLmMtc6kd5zq9Sd00VgTef4FF1+t8pHGrS/aWnjVbr8fQWNDs06sU9Ph++MLj9aQ/5ewoO0KEO7omR/M2JPm6t/JwVvClkNauExIrZN3D8yIFKVNKAV1K8SK4DeMTdO+N2nE0KPiWOBIfjLZ4f6fhYNh+y0UfCzQeyR2KBTJmM6WhU/Ks4hccfKrOBTfn1A7GnT6Tgl0kZUVhSc3SIihQZuNuhosU/x3ydW4dboaG9BOHKHBZ4ZkT6xoKMNHcJ3qfe0KZNWS91x6WutwHqd2LtE+padthmR/vHJgoNbRFTyVqq7XfCyRkRHNT6/RETzpa0sz94h9vqO6WjxiEhPfCHBr+zQKZkTR45rKMmnr1PT2ZxY0blDrPDfoV7xGNDJ8WPinjwNi2t08ugBsXp+vcAoH36ecAJeLOWPiUyNTxF3Cp0S91+OCT3yJWIPbpse+ajAptO8V+B6hTDIRwSvQ+xJWi/9W/eA+mj1fWIvkXJJ3fd54i4zDf0h9V4/5fPtAteUMDSNWt8k5l6DPeuSMbXBnZ02+UzefVJg01C5C/wHPx/G3G/6L0PO/RyRgj3+Ctz6Xff4fQ/hD/5dfxb+9G+I5aKXqTe1zeFv/Ufw18sY9wl5+1ngD/5KOPtZ+IfoZNtLxJ6ULxCp/MJvUOKUCHYNiLvtDjm/p00D+EUiMDQhUl4fEHvP1oi9tzNiD7Hz7FxoE50RToOGonvBp+Xd6wRONTQPylikZVfqN+lobFzm6S0ie8MfnVTxo2N7SB1Ef52QSddKm7eJlYUXSjsfEE6bjlxrxLePtGbg9JCOhj9fvstXnybk6UXPPeqUR2V6tkcMrminqlMndHrgu9M7+96gvgz9OeJOPwj9LI+c0PHFIXEnrN/WiIWM/EgTn09jvUNHB/sEnbnvW1luip8BLYMBBvs2S98flLqvEtkVBoEO6XTJWmnvJvWetg062+V7qA8RMTChbdLabAbarxE2RHY23dNmWxB72h6W9sapvTkRjFsr9dWfxwQP32lwu0no4c3ybqe0/VoZwwPijsEpIR/0HV5NdX2Oyli+QGTfvV7G8L9j+fOxcNqmBKJd4jdq45LujGCqB6XeIyIitkos6e+W33eJPSD247uHdIwxK+/eK+9kWAW7y97HxPG5h0Q6S3Yyjsv43qJ/T5uMtk0srzrut0vfpmgaeZymci7Na8zuUzt/rhhoFGr8z8tYnlDvadugMxYfcH5P24LY03ZMGNsq3gkRndChWynt5RSwPeq8Yx1CjbzdNGbTeUxPgGDoHWIfgNF0BQCEwWs0SqPeZ5b6mhCBgHvEJZOOc4NwICl1tomlc6Mp7pXZoV4xmaZy0vYR9b16b6fv0uN9Il3XVKRsyEp7u9TH44prgwRT4uheU4A14HwepbZU4CvE3tJB+V9lPUzfxgT9+CiAHlLvaZtSbwY2pVHDfUi9L0RY7lHvaXtAGIj3CL4+oV6Ndz5mBL8eEManUU0Fq4Ghs9KvqR86daZRayRJb/mR9lSq94jDWR6U+vdK/fcIw3VOpNWJ24MyFmWSvCmuhdux5zndpnbaFoSsFD/HhDw8TnXlTXF+SKwu3S1llA/KUelPheOPuD0hUk83CD43UjsmDFZpYZBgUK4Iu3y4SqTOKP+yLPDRaZwQKwDKa4Mo4jHrBWWH/Ad1ipMBGh3daRrnTvn/LeJwHnlpNeHmGvWeth0i4uzf8rzGrHJ4mOoeEdFo3xuIaHXfmDrVb0o4ma5MPKF/T9tVQj5r/FhmWnC2RlzDsU/ttImD7LS5h/ltYr/gLuF7jehSA23nHpFKJ5z8j4Hf+xvgH/974Bf+C/g3COW6z4fLMO8TKWvS9v0y/n/jZ0M+v0tczWFgwbQw8SIOzZAQtjmRDpezU6Dej6RMUs48SHC9Xfp1fmaErniPCCrmPW06bdKoOkNdf0jcBaVuzgGsUZqLObEvUINYOp8TwSDL3iP0oPZQPg9gjaCpCaHzJtTXGiknRtQpdRc5bXvUh5sdl7FuEDaWvOXx6xc98r96fEL/CYTyY3bkxX+2sWxnm9jbK18byIU4M0A60lmfEIEkiDTCPlln0M+Dh6RV5a08f0bQ1ZT6+pj18l3aEq4V6j150pS2wSTBtk84VZbbIzLXDGDYpvJ7nX6bTV13N73bod7GskrIufvEFo2sN33eI2yVberD44R72tTRFrtH2DLuMd2gzo7wEDTpQdjWOZ/2uFvwc7e095CO10+4+PlYOG2XqFNI8t85eprTCFbST1veNlabNmTAYU/9XJeed/btz4Dz/dPz3h8NC5r3K00Z61pWhef42zEMqMdMKutPOy77XKWGxbY0Tvv6adtcNi8tHrNhDfXx42c9fWQ4Whhz5Lrvfe7TZ9HgcUC916Ide56veU+5vv76aKcPvy2NtvSS56XvJ+Of9Hff/DiHmaaGdBGddwhnox1nHy5bXsj4WcZDKxeUa3GSH8c8bL71wdjHb4umjZa/+vgj43EZj2eaoqnT0mqLL4jgS4axb45Xe/6nedeH24z/DFfL8wvqsfbNi3+35TN/ZN6AGnd5PH18voyHWvmyDMZlshvOw7KMTvr6zeNvYbHt1SVl8rs+3dTK3xb37bwLU9vHavN+Gb9m3dfKg/zevmfUY5SP2nH16YAW/j755JNXC1pcOK5WzvTiZgX4BeB3/hfdMtmPEZuTjJQMaj7MfWT85X77+KCPry+i4QU1nvpkfJ9+yz+LVL4Ptys93zNO++a9jzdbXdryTKaZPlnQR9+23ZbP48w4pGkvz33fk2HIcqi18frose9p+aIdW+63HV/L95l2+2jnWTycdWU7X316aJlM7OOZdk7E15A6INPX7mrTxyJ977Nr2r5bedrXfh9c6hpS+T789tG2z7zBR8bjtGe8Pm1/jqtPT4rbVv5fNGerTZmLaB4+Rk5bZtQRESkWCKMwHkEsgoapjj++c/9QJqTLTV9D6iiviiRPgvVH1PvsVqkFXjuWbDSOUtutM9TWMeIKwUTZWVulhtO2JOosSEYEEY2an8vUY3ZsuR1hzv1kGHK7KwnfLR6NEBlt990w1etzRPtg9Z190oPfjEPS+yykrCd+cr3VVN8oUl//C/rnrJ2nrEhyfccwoJ6Xlq78ltMj8lzlOos05j6aukKkUfw1zs9fq+iHTfujpr0FMZeZN1Z6yrXz3NKV8IzoolPWkdcynlqaGBLpg3Ae/oxz6GRJ5tMF5+clt51pLD8Zhiy/MqwtX6hA+nhxyHneFIctHba4zYpNPiP15TzaVuYff2d+t152NDNs9nvag6/892WCrvKcDJufjKM+OmvnMsvXbOyIi8xH7Ty28rlv3G15x+X8tPOY8ZPnX75Xp13m/Jy2dO1crFDPS67b0kKr+7LDk3HSGscjzuNM/Oa2V1Ifc/rh9W/hzitt2TG+iL4zr7d6M4/hw8ojuhNJvgL8C8Dfew0GR93O/p/sp7c+3dLSgrCIe3E5o6YRqPvoMzIzL+RDmNo5938DnK0Mz3gQzzPOj+Vy03ZL03k8ffSd+Us4fFoaHaUxtP3MOY/fVlaIr8vU42t1eH5avmzhyXSeZd2yJ9tzfQ4HhExtZdOo+cn00yeD+vhfOml5O+vkFuYWF1nPOL7LzbgzTjO+R+ldDq5nGdDaAXB+Tlvaa21g4Wxlbju2lmegtv8zbjLt2kfbXrbzsj9gPevm7BW/Zf0JNe/mH7+fPQM228j2jPN2Ec3Dx8Rpy0f+j4hl+ymRcmO63jGROrBBnEJnOpLpkSO6/co5ReSY+kTJU2Jfmu+cfNPM3BOzXto7IVIgptT3Cx2XsbxF7PF5VNrMy/Pb1CfaTYj0kj3i4BNKHw9K+47HdLa870SDRaeIUucecTrjMXG8r8R+nzh2dEp/euRjIq3NfiZEOqhLxCvESYjTMoZcxzQ152qfWHY/7pkDH9udEBuyZQpx+pA4oGNEnb5Fgcnl73XiAIQMt8y1TuwrgEiXmRArUyfE6W6eaGd/pj4MiFxy8WUfd6lP7NynWxoX/l0iPct2xNkOkT5kuob4ML3OtJoD4loKhdEC+CvEaZgDYu/NHnE07ZBIeZkTe7eGCUc+kzQ+4YT6UAuINCB53XFJIxrdHv97QtDJCXGVxwMidUL6lx63Sztjgl8npa8T6oNIptTpvG8XGDPvbxCOSZ/i36NOzb1b3h8R+07vEukeKkSNnSFx3P+k9JNll7IBIlVjnfoUP7/JdwuC5/z/hEhLhqBviBRR4ZTehmUsECnGU2p55jwoX/17SsjyISGblImmEdmPSksZ8TY1nS2I9EDlhbI9y8ABoT920ljUJ6ZImzb0iEhHFd+rpe48tWPKm/2Ib+WqumVGzI88rNFl2thlYr/FUYJjRMiTCXGYyCpxYuU81Z0Q6e4D4uh6iCP1IfhEPCijlWWHBF/sEPTv6ugGkXpkPVJ76op96j12UDtt0qUyTnzvl7JeA3FcYH4ztWPa5IS0f/MtQuE6mN8PXD/qNt3cBP5l2PzrXWbBiEjZuk+knCo7PHJ7hzCmjqmvyniUuhLvECfdOv52pU15bbriKZFKPyHSqEcEn6mjpC1xu0NcDWLKm3omB1a1NYRjjzB8j4lUrPvEAU7Hpc310tYuseXC9Ejp4C6RLiovqBcdizQljygfvDbgMbEHcERcn6FcWPZ43sGU4Cv1sLRySKSnPctp2yVsLYi97nkMC4L+1WEQ22gmhI2l87NDXOUiX59QH0Tyfvl7JcFznL7nQGq2e3xMM79X/t8h5mNCN+cHRErvjLBTxPmIsEcM0k3Kb2XljKCpYwLv6jJ12JzYM3xA0Jy4XaG2X7W7Wpttl45msg56P5XLNEp5f0DwUuuAOfYDOnkvHk+J7QXHTR1tsbvUp0cqs7UnxaM42S3tO8Y2VXOnjOUuYTu9Q+B82fOxcNqGdJszT4jDP/KdKyrJLSJX9AYdEjxlZ4s4Icrc79uEcB0QJ0UelZ9xqXOLUOI3ypim5duYEM63if0eCvIN6ojAGt2GzSFxHPcovbNtFahG6xaxx+wGcaHiKR3xDcp4Nku5GwVujXxxJDOK1y2CAW8SB7UIz2n5tkUwsfdEeLjFJLWh4QGxj2OLMPolWPG4KP3eJqJyM+JUQo25LUKB5ciWJ7UdlPaF/RZ19GxAGKPOQXYWNFT87li3iL0jKmnhcnO8ysrxezjHJuH45xUeDeebaew5OrROXMjrvskj4rTH7LArqDeJwye2y3eNgAVxOqL1psTBNRPCSBaeCbF/U1hUDDup3+vExmmVh7Sa2zuko2XvsROGTYKW80qbOBHfzrfOk/N3Wr4tUlkvPT+loyOV2E26Dc86ILcTnDcJWpZG5eFp6tc2pmWMcyIokXk4PyqNAR0d3CKCAxrLtzh/euQW51clVhLOdHheIHDt3G4Qp+FqDE85v6dNuKRZ8TAnLlSHiOxr3E3K+5UyljmdXNBIEhfKhWPi6PibxN62AUE/yiZp5Sq1sSbNCcNNOrmS6UzjwJOEp8SJmOJhpYxPI1rn/zpxMp79jYhDh4ThVvn2oODoFvVR4MozaecmYUxPiIM8DqgP4VDmnxI8R6mnfvOgjNWCN+fhBcL4ynWPiH00Bg3GaXzOzzXismwDTlkvXk84UxbdpN7TpkGzmXChwebYNU6uUfO09J11k8G7LepT3wwyDQscrd5UD2wCf2YGW/9eODknwO2f7ebjDUL3/tp/Cf7iPwb8HuAd+DvvwneVk19+59fjfqubpfwOIacnBK2tFFz5f5Zdnyhj2iFWjvym8aaM3yTkT14peIEIGKgrt4hDq9YJm2RGnB5p8MF25Dn3pW4RtKmddETIGuWsulkZn+2KbF9oH90inD+DFwvi0BFpbkI4Y58oY3074cJ+hO8qtU7re4ZEUEXZJW8eUdsQtznv6Cx63omv7Kz5P8Rpsc6jToF7Qp8nAr7qDO0BdZgHyW2mun2BkBFxANmzVtqcky0ieLNFHAqlIyJ9TwlHKu9pm1IfojMm7DFxq+5+rrTxuIyx1fmOd0HYceJSWaV8lk+zzaaDuFHaU58pH28RMuftUuf58ntA8I2Pdo90k+1sAwk3S72Vpt5p6e9aeSdcjmGNOIVTGf+wtHOF+oRcn/fLOIV7j443trj4+Vg4bQr6DToiuU44bDKkwkajd1zKu+JwlTgB5wpxz4flBoSTNiYQrfC/kv6n/G8/R+XbNWLCNXhtO7/XmL9COJXXiIkeF3iOCGPasYsDGVpBOCROKBNWnUkNkCxYNYQ2iWiWgtR+rpe2VMQqBRXOdeIYVzdja9ypsK6kdjXGhcHxXy8/EvM8vTMiuUmslGaBJC42Sv0r6V0WXscEA69ROz+k8ZLamqZyGubi+Sr19Q/XqJWKYzgmTvayvxNiBXezfHdeLpey4mxK0KNO2SodbVwhFPqYcHQdf3badJQ0AlZSHQVkNn4VStKFRtaj1K98KRxjwlG6QghEDUPpUQEGwc/Zsch0u8xpu05EZR8Txqv8OiHoWANP/LkZOPOr9GIkU54ZEEezk9o4IVaUx6lfFU5+5FENM4Wz8zIv73RYVOLKBJ07DWB5c1y+yaekd8Kus+1qusa09JbnYUzw4aKpqwOSVz3ld+ExSKWhb18aBDPqqzw0SsfE8dDZaB8TfGe/OQAlDoQ9z+lmqj8m5JSGsrw5JuZWnF2jM77O0vvcnrBJ435z7OLxGjU/OJZp6iNvvlefDQg6g3BerhFzq/Pld3F60NSFWv7M0pivEifgjQm9dJlYCfObp6Tav47cWVNGGHW6lBMasKfUOCS1IfwQWQGWzfruCmGEyyPiXfmhHpjQza8HUujwb9CtHp0C3wB+7Z+ks4b+8j8BT3+c7/pVdEcvbsDm12PlKMtYdbky+IA6Yq7uViY4L44/y9lst6j7lFsndHbCKXEittF5aX5M8L62gnJNXG1Qz9dmejcu4zgi6KWllZPyLtsGA+J6iEX57iqcfKMels4n1LacOi7rkkFqw74XdDR0lZAjWYe3zylxCIo2T5adOvGOE2I+Fs3/4ka9BDXd+owIm8d5gMji8N2Y2gbV7pGvMw9LU+JP23dOLU/VL31O2wEhQ7Levl6+S2fSt7aYMl99q/7JTps6U7odE7JefvbKgJME2yNixTDrKuG0L+ndMfg4NucU4k7IVUJeylsQV2noL7ROm2NXNzgH2YdwnD4GI7Oc0rnNvChvThPMg566Ptpx1+n4X+e5Ldc+Hwun7YQuKubJc1eJ+1+OCcH8U6Xs28Rq0R7hsUs43yYU2A7h8W6U9u4TKSUKa99pgKhQNsrfq3STYkTJo9U1NmQ2I75HRNrFsIxdw3SXSE0bprGOiFSRSSk7K/AOiCNsZbKD8s2Vhpy+QGp7ThzvPiLSRA6Ipft56iuvLA2Jpf8jIlqq8l8nhDjEHnBXtUxn2SVScDRmxe284H+3jC0LpAlxqtaESB3Za8odlDaykB2k7zMideAycUn0iEgtEd5RwrHPHpEm+pg48nVKROHtV+N8Qofzt4lITp4TFedO6f9rRGRrn/r0SE8qGtOlxEwIwS780p3G8dcIx9h+fRzPIbHqDJGmqZLI82lqwWNqJ5XU1rvUq47Sus8hHe63CeWjA0WCZ0YYeSokVzQdp/zgWLfpBN7bCQcnpb93CcVl0OE0ta/z67wre3IkUPpqH2mPVFaHb7f081PlXT6pUroZETw/oZuLRWlzn3rlcoe4RkT+8dkllKjwHJb/D0vd6+ldpm95c0hET41WG2w6o+PPGXVa2D6xCmOmg7idEKd5OabHhNF2n1h5U6FnGDKdzRPO3i3wKJeyLBjQ8ctZKaczvE+c4jUhItxrROqlly6vFFgPyru71OlKe8Qppe8Rhsc2cZqf5bKhclbwq1KHSJX35Dr5T6dwThwB/4BYzXYsu8R8OAcPCdkOsQqo0/MuderjBl16uTjbIwINGos71CelQgRVVwhHTNrMPN3yt/rsPcLJgDq9cNi0oyyZFDxdJ7ZCHBB8/YDQcxrzf3MP/od/CvgPf7w7hek/Bf4c8Je71Ku7xL7MbToZOySCKTk9clz+N51Y+fN++ZZpxSevLIypA4cHhJ3z06Xfe0Sau0GwHcI52yWcKINh2wRvmU10jwieHNPR2QNiO8dVglbk0Q2CFlcImZXti/3ysyD4K8tTZfMBkXInL98n7DCdyKyPhTev1vY9h8Q2ljmR9XJEnMQsj5/2N1E9+9T2h3WybJkT8iPL5ZMCq0Hg++X3BwTdzunwvkHoc+vulr911Gd0c6muFA/OSYuXPbp5lb+2qVOAp3T4ep/gizPq64AMxNxP7TjGR0SaoPbMLqFjpalDOvreJVIlj4hTlPPYtRe0AeR5nzmRLjxr3g0I3bxC2HbOg22tUz/aMBPq7QPyj/jJj7aYAQ3H/pBIi5wQOkBaVI6PiJXX/LxJN8c/RVyrNejpv30+Fk7bBl3Q623gM3RLqQqZA+J42R8m9qZs0TH7O3RM/hKRpuJk/SCdM6ixtUl338PXCKFwA/h+umjct+jutYAwADeJo0F/hMiH/XkiijMsY5qUcj9c6twlDKxfRxDkmwWm+0TE+YtEZOsT5X8IgejS+3Ol/E1CWas4VFAaPaMylnkZzwt0USLhf73gZwf4gVJPh3kOfJnI15Wgh0QapREE78MY0DHPXSK18AO6a3NeKePNUZAbhOFzh9i/YNSO8v5zhHIxteDlBDfEMvqg4OSHqAWAsOkw7pd3X6ajszeJ49fHRBoVBRfeOXKfjtZeKPNhwCEblzpynyrj/yqRXy9jf38Zx4zu/iHp9QZhuCmchqWvTeKOpP3U34K400bDfVra2+Lie9p2CJ4bELyiEWZ6xivEPUmvUqetQRhbpr0poJ4jaBnC6BsRm5XHnDfqvkQEWbYJYTsucL1NNydGYwd0c3KLzvCZFRxP6Ogmp/qaIjYhjAcNkh8sbZwQV5AIz4v0GxHbhDJaB34NsfL1Jt28/wjdnGRD8g5hpGwX3DwsOPshOpn0Dh2Njktfb5R3RshfS+N4g9ijokGnMfBJOlq4Vd7Nqe9p2yFW2ifEPUpDOtmlXPHqqyzPNL4OiNSqI+KY6S3irsUzIgh2rcCY92QZJJoTckXY5wWfI7q0lp8reLtNLQsGdHN1AvwM5+9pe5m47+tRweUPlfbeoMP3kI6OXiKu/VLBf5qOH94gUpJ0fL5Z4PwCcYSz8kzYjgs+jKhqLH6q4P+niVQvjdnXiP0PL1Pf03aXiD47B68m/Kj7XicckG8Q9whtEvfXibMXiJR5V5HeKH3dIAw82/v7CafVVbocxJI/NL50TK4Sco9S/9uEzGr15gNC99ygm7fngL9KrMq/TOg5aek2hEX9TeCXA38D+Mdf5k9eusdPldffT0c7f5W498rAo8bUJuHMjRNst8pY/gj1Plkd9g06nn+OSFs/JYIPD+lob0TsYT8rMF4r+N8ouL1b2v8BIkD0BrEaeIduvn+6vHs1waCddEDcqfUGYZhuEjTvPCmzdIzvE7bTo4L3Y+L4em2nVwuevkXojDuEk71F2DJz6swdddqyZ4cIyswKfJ8ucH+NOFL+FTp+vMgBhLhuQb1qkDrbIzO6+ftM+a2em1DbWN8osL5MN1c62SMifXAz1X2TWN1xweKQsDUgbJscIPa5V36+t5T7JnHnmE7MDnGXqTbCLhEMNpDwM0RgcZMIsGzR4fKrBO0YmNsizpO4UcrdJ4JeN+nsuByc2y140ibqu6cNQuf7blzg/zRh87ly+llin3TWm9DR1zcJW+V1Qn8e08lL8ZOft+nm5/uIOdst8L1axrDH+YCv/LNR8HG9aXdEx/c/QujaHyj9/4csfz4WTtsxwWQq0bzS9phuUv4yHYPKBEYUh3TOgQbcG8RSrQecQDeBerQaCuPS/ruEYQhxH5UGvkbBCc9eaTPdJUcMRwSjuWFYAWtaiWPfIQyEJ3RKbEBE8hy3sNiuhmerLIwouJyscHpAbNgt19l8aFT6aGjsE0JsQRy6opG3Xr59kNqFOHTiPWKPjo7TVWKD7psEIwxSP0bt3k79bBMRGgXdw1R3ROx/8JkRh7KYzy+epmXcOow6bzLoglhhe0is/MmgO4Sitb3DAvdbRGTqNPUxJVZkdIh1GIfE4RbOwZhIUfp56jts5sSmVw8PmBEpgyecP2lQOj4gIvdGVe8Sc2C/7xG0YoRrLbV3TBgFrrRpqBykcoecX2nLESij8sfEPO4Te3CMuj0gorn29TbdnDnPGlbHhBGpgjdCOCUOwxHXm8Q+jAMiMHKP/s3sD9O31fR+Qlwo/5eIzdkqRHGgsX1IOKZT4g7FIYFrD/pxNUOnbMHFK237RIqGtC99QxhRI+IC5nYFa0Y3vwaRNNw1Ck6IYNgxseK8TdxTZAR5tcDwDhHMgDBWSe1lOtulm+vniLuYXHXPRtnbCYfOswZKvlfO1VuNZ1fcDUDtEQbRhIjwvkfoAH2BEbHSZpR5P43LgNcpkRkCceDNDkFn8rzR/l1itef9VPeYWG3KgcOdhB9KWwaqpsQhKgNCp/hOXXiN4Me10u8uQbfOp87FiEhxz6vtM2qZPidknAET4dHIU28OOa83lQ1jOmNuTGf8KSO2idWOWWn/fwKs/6VYPdsGXvweeI17/KE/Cr/xKvxGIxJT+LuNDnySD4X3r9aQ0Lo1p8kJLoTw6Kc6GaohCbHStkvIcVemdAonhJ3wJrG6Ja9Im2YIGdF3DnaIFT5XXlxpM4jiqtqISBHbKfhQd2wQgWoNdmWWzpv3VJ0S/DUlaHtMyCfnRLq4W8rdJVZ0lUnCpyNxkdOm7jIY5CrbA+JABx3KA559EMke51fa2lUtde1DIi3bstnGul/auU/cnzcnVtoMWFh3h9oxVD89pE7t1GFrYfmAjr9PiOCrCwfaHtqLz6U+jgg7Tt16n3qlbUCsXr5H4PY6gfdtQv5sEPcea2O8R511sJLaFKZDzusbA+In6Z3yUbk3KOUgMocm5f+cbrkg7oE+JHQCdKwsbM9RP3sEHRuo1q41AD0haFd+NOi+Ruie/Pw8HW3+J8SqOPz/SXrkZSLq+wKRe39C5BnP6CJgEzoiuEEgYVTqbxIbudfpohw+AyLKav640eqXiJSVrVTHiA+pPSdcprpCMJEnO75MRI6MGL5MnbanMtVo/WT5/YBuZcOxZ4Y2erVW4N8nNh/rnBkNUwC+WP5eIzbJagzZh+V0kjWaXqQmSBlEBa3z+BJh9K8Smzxt+3Zpa49w2sT9B8Qm/CHhjAzSe6PmCv0bdBGkLLyuUB/8kvENYYRDLaBeIvLphVGl4Wqh3w6JVa2bBJ3Oqffi6czfIQ46edTg8Q6x0rYo7dwh9hHqyAxKuxrcm3TCMB/dLr6HxKXh09LeDWqBIjyT9P6TxL4zI7AKV1ejXyz11ku74ii3t0841iMiQv9yKqcDptOvEltJZSj9rRPpXqsEDbxIKMsxQS83y89xaSfz6w3CUNHA0NGACFSIM42pEZGSvCzye4VwjhwfRNrlpLzTkZY/t6hpTudwk5BT81K3FfgaNRm3K8QhQsoCxyvN3iSCAdI3nL9ce0I4Ai8T6ZHiT/7SkZqUnyt0Sk9DYVT+f5mgdZXzFSK4omzRsYbgkUxnypit8v+AmBdpaECnD5xn971cp5M7t4nVGiOi4lG+0bh39XZC8M8LqfyTAt8GkRozK98PCNoUtmkZy4vEXkHL3aFOE9rkPC2vlHLWPSq/lT8GwxyfMuIanayzf419AzPXgO9OOHueMO4G9O8rhHA8XiJ4RdrUOJs1f0PM+Smd/NFQ+YBYNVmmN7UJNulSi75B7N86pZvftQTLIn1Xjp8Q8pn/A13I/Pvowv1bwG+mm9yXCE9RArvO8pNI1uHmT503vAbEwRSbRGDDgKi8/0nC+Z0WXHySjlegzkxQNizojL8zIgVti6CZI+IgKUr/6wUPyhoIB+haKS9NjTi/p22R6k6oL9dW7o8JmpsRtLFFpI578NyI0KNXCTlykdO2RwR5DAbJm56WuErHvy/zbKct2zoQuMxjEG55UJmgntLG0gb4buoUcwOzWwQPeyotRHq4+ukFQk7bTg5k+LiC9VL5f0p9EInBqefpyNQg/R6B8/XUt07buLSr3fUisW91M41T/bpf3qu/DfxJK9lpczuUNPYS9XH3MyKg/HJ6p3y8QywW6HyZdbHGeb1pwMjFh1vUdvZZwk9+nLssd10s0hbSVsiXa2ubrxXYrlI/yrKXCt4O6eil7b99PhZO21OC8XLkbpZ+5k2Z/F1HYkoohikdYVpXZerkzFO5aXqnwzJrfs5SWd8tUr1havOkqbtCKI+2bf9/QqSPnBHG1zSVcwwqf8cNEVmfU7c7pYa1xc8TajzMUjsZF+J7nv6/nOpqnIiPHJmbpX78GRGCY9HglQZXfjsjjF7hUl/msQ8Ig5Hmex5TO6cKdfvIBnAL/wD4/Zfhv34Cvy3hKref2854kR6GzbdpaifDY5sGGzLdO+8tvnP/timucl+2O6XOpzcqnmllmv7Pq0p9vKlwtm5bLuMx4154p039M+o5y3RrBHPa4GfKeRy07zIvz3u+nzVt5ei5j+0MUlk4Pxez1Ebm01zW9xnmacJ1K5dOCToQP+LR+stkonUzDC1u/Jbba+FYJpfP0v8try+afoRBGO13SE1n+ZvzI8wrqb7fn0U77fxkmuqjE9s/pYY3809bTzzNmz7kiyepfIY/00RuL9dtx6bu8CfLhdyGssgxP+F8H3lusry2rxYexyMvZnmj45rp0/lzrBmeLHsWzTf1gGNcSX+3dkBuq8Xrhzif0YXYfwb4HXQ5Zn+ALoL6V3uQnAWDyIQPlXiecxIesr7J+M7Ni4dZ885y2aiXLhYETbdz2ieD2r+fNPUzPZ+lsm1QuG2nj/9b+DL8uf9Mk09S3T5565OnIferjdfq1UFTf968s36m23lTJ9NlbrPVjXneMpm0spimrWxrZNkJdWZNi5c8bxmWPr72XSsXB+l9tjsMBrY01c595rk+ehI3g6YvCB5uYfLHAGarA9pgUEtrOfMl6yrnsZU72hCZLrJcactnew4iOyjDZrujBr4+PGbbf9nzsXDajJzOiON/XWkbEc7BHSLlaItII1qj85pvEulz68TqkYyYI0MHxHHmRqQOiJW2GbGycZbae0SkMZ0SkYgh9UrbOnEK0IjOm5bpzojJHdFFAz5JnHjl6hJEOugqEZUaF1jXiOVZBewi/R4VnGnUbpU+jFS6gmX0dkpE+IwsrFPf57RKKE0jqneI/XgagzmK/0Lpa41YmXIFx7m9TaQeZOIWFwepz5tERFLmGhIrRM5VbmdK7I10dXRaxv6YiEQ5H2PqPW0QkShXLf6fT+J4bOva16DAZFRfPI7S+DYK7K4o36Y+vtx2huW9eyG2E5wKsi0i2mb0+04ZW14xEp4j4qCJ28SethViZXeFjt6cg8fEyumYOooljKYsrpf3zxG0DJFuvE+syG1w3ml7iTg9Ur55TDd3dxKejfqv0kWobhGpfvLruHwbERvTTwgelt7n1KujD4kDjK7Q0Vyr+Cn9izP5akGsKI6IlTYIBW40+zIRPV0hIpqHxDyOE8xT4pQpI4U5YCQeVRoQUdctIjq8lb5fJrK9lIXS3kuEwntY+sjybEisRI2JSPopMS/Cf0YcGDWmXqHMK20Lgs6EXRiH5dsJ9YplnhsjwodEpHmz9K2sHRHpqOqKCbHStkcX+TRLQP6+RawcnlDvaXMB5sU0bnlpSBzycodYjfF0WaO2+6WvG0R2wEvEke25rrS+Qeiaa4Rs1zA1+q1eVc777Ro1zm4RR/4PCywnxHUuBiltz7GPiJMopQ8NOp0J0rcjuvm4Uf6/TMjDVm+qL9UDN4jV2FEzFvWctHSzwDAiDjYyA4SbdAw+KEi+R5cj+gXgj/1r8Df/OfgJ6o0+LpOJeArSrkYWRnYKVkoXyvhNgkdGBP2q17YJ2+WT1LbOdUKGyJsTwl5y9flFgpZu083rvPS/Rqy8SCsGEV1JEjQN7NZJv1HG5snSj6lPg8405Yr2OI3lXkF9pifLXCtju2ilLacmzgoOXGmbEJcXi4s+2Z2fFWo+b39T+nmO0JnqOftTFmgLvkgY9q60Xef8nrbsgKiT1gi5DbHFwXTC/MzpZMud0oardHeoD+bYot7Tpv69TqwQTgg+3STkcrbFRpzf0zYi7NQXqdP6pRVtlAGxdWKUcNXi+h1CPvtuj1jl2iBS2aGT16uE7TtucKRug7BLIQ6OEj/tI26dM+HSRt4naHda2nI1bo16lc7nvfJd23i39H2rp//8fCycNpF5Qr2XxXeZKSeEEID6aO5cb0Hktp7QTexl4s4KDbfjVG6a2vX7ZWJfgXUdgw6PhOhYbE+5bkqQXr9CTkFo2zOCeEx7EX4NqixIHiXcKHBzJGxOGEWTUv+M2G8iPMI0Td/m6Z3jVZgYzRoQJwapoMS3eDwt9TOOZ6muefRHhEGdo1uPm3FCLD3niIj9Doh0vRxlEbZ5amNGnMrmt2mqo0AWF+LAMX0z1W2jNjoFjl3HMC/RqwCl80eEwLE/BabGimmCOhqOT6EsXSlMbUv6yPDYh98HCUYFa56/TCvzpr2W13wyLduv8wxh0PkIkw6LfcoHAyJooqHhTx6n9C2c8s6EMLaF1UAChLEo/qQ55Umf4p8knNmG7zV0M38bVJkQilN6lp6E47SUW6Q2xcOQ87idpv/lU4hrE9ZTe9I3BB8qH8T5kEgLdj6mhDzLc+q4/P+EOAHtKMFt2UWCcUHQoI6naUOZzicFXxk/jsm5GRAGu2WU5Sucl88DavqdELQ/od6zB8HXE2ojx/mdNn3ISwaKnF/Hq3zNND8jHGjl+HFP3Ukqo2yQLoQHQvcpm07o5NUKIVv8Lo+vEbI6z5WyRqdNHPhbXlL+uvozIPyeVYKWj6h1o/Ml3H7L/ApBy2fl95NS75A6lVfbAUIGONYjCCLw5S8Qt9tv/3Pwu4E/8o/A7/yPY/OXQtjJJYCXVhbUKbvCpzOhTpiksWY54NiPCPyrZzNd+C3L7ixDjlMfx8SpxfZtuRPCljhKf0+obQvrqocnBK/ZTh9N+Rw27w1wy+fSik7AsifbUdJ11gGP07iWye78CIf0qy7L9siCwJtBGAj5ukFHe48JvShe5gmmPh7O2SlTal0woObVFi+O/ZCgjwm1HMrv7OMR9Up2lj9Q2wXiNuM1y4t1wn5vZaz180rbIUFz4io7bWfEHByld9L4hLAflAn2qc7NK5LaSX4XFxABh/zOZ0LMbztn4tKxqCeVsdLPIecfcZP5Txxf9HwsnLYpsVl9QEQBs+E0p5Ojx8QphFeIo0ZnxEmNHuqwUdrdJyZ+lW41a49aiPnOx02UR0S06g3CaN8pfcpEErblDso4Hpc+3yAYbafAZSR/nTjmdpfzy+67hDEjYe9Rn/CmQtQpoLx7q/zvARprxHG0EJvV3yx9eVQ2xGmOp8ReJIkwCwEjJQPiWFiF9AHhDB2kMRqV2C/lhGWPWg8uqDeQjghiH6Zy+0Res3OQBdsZ9aXUE7r5e6uMbYeYyxHdXDws5edlXJM03kfExv7tVBdC0SqItgmhapTsCmEU7RAHHlwtZR7Q7e8QF/a9l9oTvnlq+5BQrG+V8gq57ISqeHS4x6Uf8Wi/zvGUOEYZgl59JgXWvYKbUXrvHGXnzmiZY26Vo07WKREZPyHu9nlIbPCWDh4Rx+/PiZXdCbFSe0qkOmgY7RPC/R4hfybUK4IZlvzsE7JrSMc3wq4MeJNuTh6kvqTnIbEfUAE+JmSSJ5tCyElXErJDo+yAkANGFWcFPw/TO3/79xmR2qYTMSA2eUurM2r+ekAo5jXCYdJ5UaFq9GmgKJ+NtmqYCEOWi9b3BNvDUvdhGrfPCh3On5QyzrPyPDv0maY8aEO5t5PqvUdteM6IQ0eUq6PyLhu7ewmuAREwGBBRYMvN6PTWdoLRgII86xxb95i4CFpD5koaX5ZXEKlR7xOG2YTgr4wzV/EGxFztEsfKQ73ye/n/w97/B2mWpXl92Kcyldkvmcrul6pIqqJ60l3UdEW3yt3q2faMeqc1GwMbu14WLVohYa1BRkK/sBCykLFNCFkOY/kHSCAjCOSVVwJsZFgJVoEVgBBivathR4uGHc3uuFvlrqjuIpvsysjaJFNvVZKptzJ5s/3HPZ/5Pvfmm1k1IwlaEX0iqjLz3vPjOc95fp/nnEvOoKzwdKdNXfEO0b075Jtr0t5QbypfJoTmduinNz1HLiKZlXoGd7YanKfAP3af3Eh2lyz4qDX+8wB/Cv5ga/x/IgdSRvSF5SjyvOphZcMJueRMHtklzs87hPaE/R3Ov/J/rcxbHQlZ23v0A3o7RHdWfrhPHEANUXW6tCkdOofDNr7zqPJU+eEO0AdEjhqAkJYflbGfI7pR2+68skt0cOUr5y2Pq3Of5rQ9IDcg6/jKu5ZT4tiNiZ47pG9jvd/eHdLRs/ZAdWjGra24gMg/HWMDVRAamjcXbSdl5Qf0z9LXQJIBtBP6FweN2rN7RK/oQLhm0zY37QLhlKb2SPBJnWbQy/lVp015Ps8ZPSYXBq6VZx8QWVrtzlnrX36Sbywzwg/77Z3zPCR21dBpetDgeL7AIe3VNZU3dSw/JI72aWlr8WKlXyD27zv09fK88olw2v4OkoI0Jh+oU9lrgJgKpcG/RlK2LpMtXpXGOv3ov5dfaIjZT302bmMekUPdRo7WCXHukt2vykTW00B1Ua+VOgckOrZcYB3CRMPDGlGcztut1jXmO22n7bn1Tuh/+FE4ZbDLZOu5ZoHUyKQK3HHE9TphHiMY4nFK/0OS9mMKjUrgGklRrIxbP247I7fTrdPH+zH9i2nWOSsA7GOljLtOIlQj4rC5JtDfgTug/xFGIyW2rXN03jUYoHBaJ5eQTcq8LhPD2cjUMuGLK+Q7XjqJKpAl+mcChFGlPXSyzAUXv66t9LZA0tOklRlZ79qfsKzR//yBbYfFOvKzRUNH2qtOlo7nOsGb814o8x0XOHVYpRcNi2np3zEofTie/CdNzVP8pk8vkltHVSAqgHViXMk/lwndGKU7oS+TDohsgET9nqf/AXiIUhWPp+XvSrMVx5T6BqF0qqaEVqGjK43EKs+mhNeUTRosdT6OoeGh8+1aSHPSkvKqOm3S8jpxCMecNWTWG7w79Gm5yk5I2to14vC4ztaVpizOZ0Jkp7Jbg8g+6q710gCn9mmWxmWSYrpEPsBcaflg0FbnsMpNZbKRbAituBul7NF5XKOPM+dYnbZJ6/N5skaHZT6muq+1f/OcNg1/dwV3Wtsrpe6kzK3K8QkJ4o2IfDX4JV+LR2lrRj4M7i7Xbmn/LYA1MkSwTH/QgP2H6S4s+fforoP9Cp0VKJM1Qhhz9ptMyi7xOiZBJR0sh18mfKZ8XiVBnjViQ7hGh/SNzTqOoC2RtR+V59KKcklaUadX+ShMB4RmRoSHDahqZ1whzkG1y5yHPCZd1OdDHT4sM0J/p4SWlZ3C6nye5rRN6V8sd8rZG4FnBeYrBI/SoHjboU8+rvESZ9dmRCfTITtt8t2YyKtF+psEtRwS2QC5wVO9pyx2vbUTqh2nHtohzkw99iK/eKHGFSJDTHmv9aSZKVkD5Ybwa7+eZ7NVWvCZa1RpVPYdE116hbOOkjxSYYIEGy+XZ5bD8m5cnmvbCsPQaXMDYnVOW+eubD8lumeevVTLJ8Jp07jw39Hgb4XJ8Pki2Z4+IkSjwXVIokAi9ZAIIaOOB2Uc5a9KYFSeHZU+T8jZrhnx/N2qrekNEGODApPEZZtTctmEyta5Lpff9d4dw/E11GQWYVa4rZQ+Kxzi3PmflLZGUirO69ynROAsDOqKx0P6a6HD4Rw0xsSrOIEYGcIlrIckIiaspvuoaJwHpa24sj8j8sKrsJJ+fFbX0zWSbqqhXMc6pI+PCo99y+D+VHA6Z5WH86504HjSvPRjFE06FFcWo4XTQb+un8puodSpczmkX+yv8pql0nLFY6XRafl9VtoN4bTvuhZ1TeuazMrYFQeP6dPREJe1jyP689EAHxZxpqN2yFl5dUD40MCK4/q8zulw0NZyWOp4/oeCq3qIWX5WTooHaUXnzDkcF7jqnAyeVTpWng1ltzJh3nxqf0uDPiHOVZXptTjHZfoytq6f/dS5VjiWBu+qDqj0rYyo9DBMf65rYfFZHcN5ndDHhziofFrp4rD8XvurbaucqHOs+Iesf10rZa1tDkoflWaFv85XurWfQ/r0VnVz7UN4xJE/RwXOKh+qHK+wV/0uripua33hVHdVPB7WigJTox9ViEzpcuJ/JfCDdB9k3KYLmf8FviW0hL/qkkX6eF2irz+qLK50ohyhzHWhvHONhjp6KEOksarrKg6cvoEbcWhfNSA8pOPDMoZ1h3wvjQ3towqnPLxEeLzqzGGpekCbZCh71Kvnye5apGGLwYZqj1TdYUAFYr+4Rk/Kc2VrlftDHj6in2lQ+dD1XyC8ZNshLtwFr7it5Cs5D3nFeYpDadc1q3094eza2mbemFX3KBvk37ruBiUsQzob6k1x7XwpsMjn83ZJK6s7/4qfg0G72t9Q7lb5I28O7bfFQdvar/KgrvXQvhqWT4TTtkC2Z0ft9wVCLCP624u13nPld3dI7GuVRPSNgltnubStuwMSjU7Fc+W54yvYjPgZjfH5Svk3LW1dtFUixJYH8D9HfztYZ3OxwGhU95B+5EVFKsEtEW/+gKQdjMoY9mnkdVTaWxeSBinDLRccuW08XEdhcB0UTEarjBj692rBic5K/YZIxe0afadtrdWtEY/KJM5tRtZ0kXwqoO78CK9rYDRKR9XUW8dwzjpGjmUfRuHcZajvjgdrUmlXJ7vSiBExYYVEKIWt4mStvLe/0/Kz9uv6SU8GB+o8xFWlUYWpxlddf+m6Op/ip9JQpd/aDrI2NRI7Km1VLHWX3Yg/bbwa+Zf3LPZd6XKJXBhUZctQ8AqrfCO+KO2F5aS90zAY0pzOTJ2jv68N2viv4naVfiqqhqEwymMGSlxziCHpuh0TJbtW+lN2rZWxdISrfDLyLU04f40+ZVOdy9AYEeZKZ8qIyitVBta2ygLHrTJEY8I1WqPPe0ulrnBqGFTdMqWfxun6VnnqnHRoZ/Tly7S1f57IJnEtr1p3ZdBWnSM/Tct71wOiVzSaqiyvPP5kMO8TQgOr5V3FtbrJ89+2rbQ4dNqq3KyyRMPtCZGzVW9WGSO+V+j7WVXPKVdG5dkJ/Tl/a2IuxJD5LDL2Cl3K5J8F/jG6L/r+EF0u59fS9LQ0HeLZbg0iSCtD/XlCn3erbNAmEr+2WxjUs191X8VDpRX1c7WTFonck3frWNVOsTwavK/n8R1vRn8NjwbPnPM8eWs5IDyoQ277KlcqfQ2N+Pr3Kv3voLkGNeDp3KuuGcKjXTrUmzVYPc++GPJUtSflW22cIV7E7/Pl78rDw2fqwKPyXFxW2nXsowKzMsr6VbYe0p/3lL5NW522ob0gvVpOBu+0M6p8rHIesiOtjqrsq/7QYZtnZ1dbyCI91fTIqteqTBG30OfF2pbyvrYZ0up55RPhtD1Hd+vLKblJSo9zh24ip8Br5CzRdfrfULtFbvHbopv4m8TTNUXqTeLdXm5j+WxC/+aYdbJV+TzdV80n9A90u1WrEbLS+tukL0TeIMy/SBegOy3tXm8/N+luj/lcq3tI96HYZXIr1bj9fpmc6VkixkklmtcIsb5EHKW1NoYwvEa+ZWb718m2cTWsjumncr5G0uuWyW1dwvBK62uLCC9xP25w3yJppwpN2vM3SD7+GvkGjfBA0ndUMhXftDntl7rbbdzXiOOosTbm7O2RI/Ih8Ft0a+QtpwpdBcdh+/s2+T7OLnF8Rw0+BaoR09vk9shV+srYmyOv0eVY24/OxkZ5pkF6m9we6VkB5zMhZ4kcV+NrmyiG9dbH54iSv02+pWPZpVvfXZL6A+Evy1aDv+KipmCoSN8gAljlPSH0pmJZJ/S/QbcuB3Q0Kr8+pKP9EaHvI/oXjTj2bXJ75E5rM24w3GJ+is0a/fOpb7T+Hjac7bdnJ+SWRsj3pBTcyo9rdPg2wvo6Z1MrxkSeWVSEzkfnyLFutLlttfc3Bv1p8EuvOgJvEId70sao/CXvufYbBLcjutsjP0eizRWvOqo6n9XRvM3Z2yMNGN0khsUtoiCln1fp1vAxubBgnXyrc4dufSatf/F4RIfvJbp1u9Xq75GzBq+0+YjvDbJ+x3Tr+0aZ5zA9ctLGULfstDm91vCg0XuVpAS+0Z4vNnhsu0ucqqXW1xUi26XXq+2ZEXB3BuTxK61fcfZZzt4eKQ1c4+wugbBvkpQu6eOYGGsGLJbbv4OGi2vt+biNuUdor8rxNfLB++vkBrlxgcWbeevu5Yskhcvz6rcbTr6lGFfoCOdlckD+DXIYyLJOLMOv0R2G+S66zwX8s7+eL/+xH2eTszttq63rF+kf3ZB2Rg0XIzoZfNhwUfl/laTLSRenRK5p8L3c5rbf8HWb6L8X29R2iWxXh50QWpCmqnF+QpyA9QbbhJxxl3evEjp01+EFcnvkfkPbBrnNUhiutDle5+L0yDFxFLyV9WViz203+D/b8DRPdteySuTeArkApNojJw1edaZ+/IQOXzeIs6KudO11wC83mNZLW+jvykzp+P1lIqdrkHKIF/9+jew83SS3Rz6mOyP/GfrfYxw3uFtmb29Xi/Zcm+oG3XqrH67T4X2vvVOPXSP27MP23GcG1xbp7IAD4uB+jr7Tdky3if0CsYePic3rGAvkvgJvYtzlrN6ctfbKzFul38dt7i81/NSiU1bl7tYAhm0ih/QvJkQ2v0ZSwC3bdPL6c+SD7bf578ntkYd0QaoHhJAkqgkxqn+61b1DDlA+oCPYXXKW4l06Qjglh4JF3hGdE3SfvvHus8MG0y45VK3ylRkndMSkdywhaqRo4NeLSH6SCI1Nzl5EQmvn3BR+U7qz0YvkrMFK+7lPvg5fdypqNFPj/2Gb30prMyKCUyI+ae9UrM5Fh0khdkw/qqQwWiSHyx8UPE4anvfINroEvtvgu9/wco/+RSTepvMeMWYekrMq1ttpbYUbzuZHv1veT4hTPaV/EYmRFRl0Ri6uUdB8SM5eephWQ0ZDfdLmdae1kRZUCqvkgpT7wFeZfxFJdSTHdBclTMr8ZmRt9ohi/UqDse7gWITH9TEKVvG42MZToNwjhoaOZe1vt9URf9C/lIYy3j2ifGqUcVZw6Np4eYZRPIMeD+hfxPMhHa9Iw0bU6nhH5Z121w5RUl+hf2ZOOeMFEfMU/w4dfdYINPQvIvlJQkfy5xahuR1yycJOe/8eZz+hsNmeuTOjI+G7afvdqKS8vd9gWSeH/u+Wtrtk10mjfo8obOXKHbJzWHlPg22lwSFu99v7R0Q+1Y+O3uX8i0g04pz7jFzK9AG5iGRCf3d+odV7Qg6eT4mxv0v/IhIN3fut33HrQ1m8RXdYXDo+aOOK703CD/dIesyE+ReRGDQYt/6st0tHZ3fafF4gOxCT9vsW0QPCskmcXuXyLv1LuLboXxwgnAtt/s/T8ZM4e0gnO8TnKrmIxD4hqUOLDXb5pdKHPL04+H2LXOLkfHYJ/SwxX2+qB7bpZOQK/YtIthssd0kg03pLrf0HxNj7v//l0PxrP985Nb/Q1uCVPx4Hd7vBMSYOlXgHePUfh9f4cX7DH4TfsAT/9W8Jbgw2LF5tHbi4jTA/ftTN7Ze+0k30R5/kJs6vNNg/JHbIFuHxWevqPkntEk/vEPpXj3sVuXpM20C5oM2jXFZmVftip/1bKP17lGGXBFj36F9EskJHX9Kgcmmv4VA+WiO68LziONoUOu2P6GSnPC4/Ps1pe0D0BPQvIqm0rA4b0w/UynMjOtobET2unDZI/yGh+UNyaQX0ZcSkvYM4kOq7WrbIRsBCm8cOoYnDho9NuotE1IHya919vUf41MDspPW/TeyZ7QKnNLXX5qVDMmljbNO/wEhb5S6xTQ45e37wHeLQ0+C+Q3SaO493Ci61n4c2CsSGMYDhz2l7t9XwU8sDsgbqij1yOd2o/NSme9Jgcqdtv7S1aMf9RWLjSjsXlU+E0+ZOwxPCKDptR5xVXAoghZUGmAg6LPUlWJnPZ1OyM7RX+jVSfUTfiLC/aenTD/4tz6lnHeEzOgD98xMS8YS+wTRpz6elnrg5KW2MlqoQT+k7bZP2/DFJ+RKmCbm+dUKEW+1/uT2reFSoUOoZTbWec61RB68VV9nYdkY/x78KJGGz3xm5vroKL3Gq4aZhaHFu0D9b5LzFyRJRxkulvkap0VsdL+c3dNrE2R5naaHSkrRvPxRcVLqtODkih4jFo7ThGDrW7gZUp02+cU4Tsqs3oU/7ruWEvlLUWKv9Ga2qxpk8N8Sjc6/R6JpONCFOmzR6VN49Ln/Lf66BssG51PWp+NHQkI/Fo2lcB6Uvne15il/Z5RydrzhzB9v5izfnJ8yuuThTRkxKm8oHjuG44hWCS/9WKWu0Qp8/Djh7zld+UrEpO2q0s+JZuJQZJ/T5X4PP9ZDvlJuLRPZXmCqdSecGkw5Lf4ulH2nUOpX/J4SmHGuPnG+dEL6Rh9VDwjUh+F6mfz5B2er17TVd/aT0a7GvSZmXNO2YZnccDNq6Ts670r5zlJeVvxrXOhTSdMWZ8k0j8KT0V3EtLwn7IxI0qo5q/V1cuDaTObhQZg31ZqV/HX9lnfQmLNKq2SQGJVznAxJosl/as3eJLSGNGkxZI/KvygQN2u/75+GXfh/8kofwS/4Q8KNEuVwm2xvLfCtCemkEv3RC56mswuGTjDGhH2RS3rrOOiz+kw4mhC+rDlpuoFRZ87j0Ka5dN/kQkhliP9Ll0F6TrqS5I2KbKB+OCJ0dlf51DuHp6ZHCWXXapMy3yp95snvYn3QH0WW1nfJNHqxOm3JIujlu85dvKH3ZrratTlu1IZZK2/OctspL4nNC5Em1U3TOKt8cl+fKkGH/1Q5QDgin349z7Sf0ZeQB/U8XSBs6aidcbLNNyjPlo/NbKPVcQ+evvIHoD/n5celX2lX2DecubsWLsl0Yqk2kHJIXTwdtLdKnN3yqey6iefiEOG0Qgq0/6z/Igvt7JYCF8qz+gz6B1+f2tTx4X+vN+7u2HzLPeW2WmA/PEO6FOX0MYZs319rfwpw2Q1zN62NWftpmifljnAfPEH7mvKvPhn8PxxjWvWiNh7QzFLbDuZ3Sp7F561Dhqc+Gcx5G44Z9Dec47/eL4JjXn21ng/ZDnpi3JufRwHlrdx7NXvTsIvqct9bVSLyI3+bxx3n4Hs5z3jrW4rtTzh97WIZ9nbfGdf7192ddg+GYT6t3Onhe6QHm9zmUu/PwCX0cDmlsaKAP1/s8Oq7j13ZDOM/D27x+hrBwQZvhWs/7nTltz6OvebQ+hB/mw1t/DuXUEKaLaGgej1Yan8cr8+CbhyPoB2eG8NdMgNq2yquL1q/CPA+OYftTzs7jojkMxxniaIiXYV8n59Q9AfjPgV8O/PPAXwJ+F9nenDeBweTPo+d5cxjObziPIQ1UHhvic1in9jHjLO403If9zFu/Yb/Dvk7n9DPknWERrtk5OJqH5ov6mgc35Xmte9E6DPsTzvNos/5tMHb4fN76M3g3j06H7+paDv/VlOo6r/PwOpR9Q9ycR4/z4BrifAhjfWafF9HIeXh6Fjk+r6+L5O4Qt0N6uQjOebi5qHwinLZFkro4pp8eCSHiy2R7eY0cQDa94jL9w4GXSbRpodQx3WiVXIU9pn849JAcCnSMdeI9P0/OLVeEO65evRHBy2QxHpPdnuXSZkQOLF5udadk18eUgVX6V5XW1CCjn5RxfXalzKni54Rc+e85HPFtdL5GT422mbp0ZYC3R2Tr/6TgeFb6XiNXs88Kbp2PZUyu8J2RNVqnH5HwnN0iXdTnCmejNmulD3F1hURnjUA6r8ulfY3+j+l/mmJS8ORYJwPYLUa6LpM8931Cw2Ny9uWgtJEmxuQs3Ijsrq7RX6fjMr6w1QiSEWLhdK7H9GlamrtM0meukDz0Oq9KE+Ki0nIt5rqLb0vNpXcnysjVIjkTIH6c9yL5ZMIaOTfpPKWXUemv4lnjU5xN2/zlcddsnkCtOLMerf2kzKdGyGckvWZEbm6UN1zrQ0IrEHlminTF7UHBhX0ZIV8r9Z1rbStvGiWGbA6sk5vFVun4ZL3gQhm32N6PCa6dp+NqFCyRNL5j+rul9jvmbHqkc7xCvgfneJYFwte75Zl6o85bmlonacJXSv0xZ6/8t48J4R/h3Cef21ikH61XdgqzfS60Z1eI/loq8zqlf+V/beuO1SoxFCp8yq1x699dD9N4FolMqTgbczY9clJwJFzuNAq7cnaNPn1A6NLfD8mxBufjrp1zq3Sm3lSGP094vO4WqOd2iTwUJnWLc1wnaY+nZd7qSOWnux7aKu54VLxfJp9y+RbR/lHg/wX8q+3lz5EPT1YB58QudxNY+et9PbxKp1c9m3xQ3p2SFC2N2joPZeES3do7N0o920rP4zK3CqJyQJq7QnaatY2mJOX2Svm74vSA2CLj0veIPp9eZMDOWt/uxtd526drvz63h36pthaE9ocpe+rEMcGjn7uQHn13pc1Ve0O+9p9tJ0ROOCcIjUP0yzwHQPpUdslXrrs7f+py+UVequmRu4RP5eNZaasd9Tx9GaJMsJ7v6hoMYd8lxySGNpu4rrbYjJxVVOYskDTOK/RtiGqjQD8dcmhn7xXYa9FGqHauz6uNoU2kfSHuVua0hfDmlfa385xnL9XyiXDaVsgB3NfJBQ8HRL7NgLfJt2deJA7MiO4A4jU6RDxqP79EX4GsA18kRHiljfUlkj7xaoNJ4aLQXmvjC9MCEYAK8P0Gz/fQ5Q4vk3MUb9M3YnaI0boGfKH93Kc7nPulBscBIdJrDd61Nv8HxPg000JFSnv+dhvzfut33N6tAp8n+dVv009posA8IecZZMI9InDfIkz7TmtzvfWx1XD6Gjlnclxw+2GD7yb9iwlk7Ft0Z7xnDWfP0x2mvU2cLBp81cD4En0npQrCVXIG4i2S7ug/v+mzUeZ7j6zZLboDqy8S5WVbx9omF5FA8uBV9N/dxpkSuvg8OeTvxzkX2s9rDV9XydmE6rRttHbmmU9bfy+WcccNlhk5oL5FLkVYaHj0+3AaTS/SHeReaf2/Sdbe/nbL2ApaOMtzW/S/zaWCq0EH6Ghvtc11s9WZEHq7R4ISI3JRz0tlDb6H5NS/RFIqxM+EBGQc+/MNl0fkjIJy5hbzFeY9YtDJ65ALJvbasxO6vHWDKi8R2tkk5wCuEZn0XGsrrtfoO2xvFtyu0b+IRHxDd7j6M+QiEgh9W89b3ibkQ+nKEEhq6bQ9q7y3T84zXCepL9ttnLeIobBLzmwtkLN9w5TAz9M3bjQoR3R8NWrw3uJsJsMrJOgxab+vN5y9Ss7k6AR9iQQP3iJ8f6v1NSUK/zadPFtrz6+T7+Zph7/d+vdcjvykXpPXaTgat349P7hEeHdGt86TNuYrpa36RYdEY+2N8pw297dIGjMkaKiz8QrB/Ut066ZTpkxcoH8RyUGr8xY5dzUmxiLEoDZIQvv9bpvbF4i+8EyQaZHz9KZ64Dq5iOQ+Ma68iATicFwntKM98Wabp4GzvYa3WyQw8hY5G1Vl2mMSZNZpu0FHl7/kpTagHhR0KZKvAL+3Nbq0Av/uUQ5z79IJxu8GrsCtu/nw9Rca/quTI518D3GitEFoc/g8kc3Sz2oDbdTme43I823ieLxCLhdTZukEKbuV7V7087j9vtn6lQ6fEP2zRi4ieUgnk66Rj5FruI4LnOeVTTo9qTw/oOOhzze4pZXX6eioyu5Z6cdnd4ktsEjO9FbZckKng9WZ0tmEbilvkACevPoC3bm2WcHbS4SHtRsN7NS0+Ft0fCjsBrWrcwP5kLSya5EOzzfJGS9lsTR/RC7t08GZ0g+u6Djb1otOdhsepnRr/pnWfqvN6w06vbhbnrkuztM11w74In0nS5k7JvawQZglclGecg+6Sz0229/fTYKFzqna6W/Q8RbERtogNluli6WGW53/LXJByhr5znMNKJ+Q4N/r9AMHMzpae9jmvd3avNnG/zHOL58Ip22B/vW/NbLqc42Sk0E9f1egrZU2YxLdWaAzgMbl/Yj+lbfV8H6O/vW4GvMQoWVkSKdNWCocXo86JoxWYdeIr22qsqXUs50GwqTAtkAM39rOqEgdw8jKuPyuQl4p/VjX9sJhtLjizxsA18rzCsOYGHLPlWcqprXStgpJI4vOs+LguVLPddLJsS+LeJ6VPnQwFkvfwv48faek7iCt0L/CtbaD0Jp4cU2lm0ojy6W9fQq/wn9p0KY6mDT8rXB2N006mZU+nU9VvnX9VulfK1zpY7X8Wxv0Ny34GbU+xE3Fo1Hi0eCfho/0Wx0/YbLfcetHWKSZip/FMvdDQi8Kbo1yeVhF4Bq4E+C62/dQWQqrY1Y8HxS4lV0a+pCrySteqyO7WtraZ+Wv1QFuq8xwjaUHaXZMzrQ5T8h5A3lE2hCvlPcQeaZs0HCSd1zHKs9UuJ5lqXNcpR/VPiVr4fgnhBbkj4o35dZCaSPfndBfS4Mt4qjqgKFM8N1R6XNc6lU4lZ9r5OIc6U3amXF2Tes4VdYZiBvT5+PqlFQcOOaYyM2F0r/rrU5dLu2fJ4Zhpfdlzq6Va1/5dY0cuK+8Im+JU+eh3JtH36PyrtKwsA51vvqr4lZDWLqxr6PSt/MaPqsyWYdFuajDJEzi9FvzEPhZebnYkPO7gV8N/ArgN/49wC/A//I4QrFNSpikpSrvql6WryjzEMY6t6HtVGml0l2lFelljZz71QGvelL8VJlT30ujtd8T+lfHi66hvL3IabNPyC6286522wrRbxeVebbL0GkzKFznAn26q7Lp+VK/0v1QrklHdZxpqavTJu8N9dAakYvWUw6ob+QZn7m2lV+0NSpNVZkwJnbtkL+Ga7dG+Er9s1TmUu0A4RrabPWd9DW0w6rdIwzS/FAnVphWB+/9e9xH7Vw5NbSDDsrvykbP+Q3tJYtzf55crjSv3rB8Ipy2Y7oI3W776eHZI7poxz4dEu7SRXMetnYT+jtWRse22887dNGPbTpC8UaXLZI6Yb+b5CYdt5dPW5tdukW5034+ajAckpSAJRLRfY8usrJNLqK4QxjNue4WuO+1sU3VuNN+GvFXIeloiIcd+umRx/TTI41mbpHvB20V/Gy2Me+SHSKZ3BuQ3O3wtssTkqYl7AoL8a1S2yZMtkPSw/ZJNN91uF9wYhmRW/R2S3sFl0Jui6QhrpDoiOWE7DCskrSse63PB4SJJq3OYasvbO5OfdRwbbT1Q/ppnVMSDZa2J/Sd7HtEOEqP90jE50NCt6afHLT3D0h2DfTTOHaIkXqPRD8Vfs7ngOB/jUQVpU0ViIb2iNCAO09VuOy3sXeJwS/e75R6rqPwL9G/2Uu6udvgNRpoJOqQ8OsD+pHRkzb2VhnXeWo4ujPgFdFH9G+PvEdf9mwReqg2WC3SnsryXutvt8B9l9CC9G466Yi+TDglvPmwtRXX99szd0zqGrjbANk5VFYuk2CL8z0sbeX7FSLjnJO3WU3JDYNDeTYp/45JgMb5jInSdRdFWWSqbN2NgsiVahhtkjQc8T6UBdLuIbm9VLnhTr649l3VAcqObUJb0gFkzcT3MeEHbxVeJ1FmI8tL5BKQ98muiDJF2eAOpzyvsXFAdiVtu0/kubu6B+3vTSITn5CdhCOy3hqHh+V3dZA7qwt067dJt1anxDCRl9RfRu7H9J02DbWqm7y5ULkH4fUJ0V9Dvekc7Wut4c95GGzaIhd3HJPb5pRVrp9rOyEZG+L5PaLXt9sctE9cnyoTToBf84D5h6AeN+B+AvjKEWz8lS60//tX4I8cwb/WkHG/4zMv8ZAPXGfl0ozsgkkb4tGdra023/fb8DvEOVIuVlo5oVvPZeIs3Ke/03ZS+nmP/gUxB2Qn06BXxbFjTujfWq1MUv64xvOCZJZtssbiQNpTp8pbd3i60yZ9TVpdf1YYqtx+RHSq+NdB9bbSBcI3Om1HrQ95eNLGVk5M6V8IdFLeqTOHc9HuukfklfDuk6yHk/JPXl8jO/baI+pDdbPrI9/ukawuZdSIZNHUetut7ntlHva5TZz3O/SdNunikNgQwlcduiWi58TDHuEby6zAtEu3Lr7XzpDGh7jdITcd0/5W1q0Qe2ZMaFF5UevUsk1ujfSG7HtEh59XPhFO239NEHJC/0ybwuCULh38iFz9u0L/+loF7T36ylbjQ2FyjwgzGcf0Pxdsl0QNdSS+VmDaIulEEqIGgQJRg2GpwV4dDIXbIvkgsobApMAxbfNdJCkFIzrD+VGrLxMrUPzpuDKuzuz75EOom8SI0tAfGpQ6jhr2Gn9GK4R9kVzFPmn9TMhW/z6JHGuMDZlAI8ciHagcRg0OU/isu9twofMyTCFwbhDH7JTuUxNPiCBQ4Y/oCz6/7SON7pL0xo/o7/qplDRy3yfGUhW8I/JZii26K2CN1CjQpK0xUUjvE7rSyZmQrf8TcqbNm6VrNErjVaP6kDjdu/QViAJu0uD0drgV+gJWh3KLOOkUfFn2Sz3XSIMd+pdnaLjKizqDI3J19S4JWmgkG6hQAT4iDrAKXroyKCMev0mUr+u9Usacp/g1DCC78+Jkiw7X8qHKW6Xt/MXxhA7nS0RZ/ByJ/irPVolTS3lXBf4puUrbtVbuWd8ibw4DBAt0NGRAyOuia+Ra58fIvQEt+cC1c94HJGJ9v8xXZ8s5KBud+4zwhFfuO/bQkNkt8LrWk9bXpMxPmlpq/X1EJxM0VqWBeyTdsuqAkwaLhkd1yg9IoEt+kvZOiMEwIZ8u0FEwAOP6TomzdVDaahwof3TYDohsFx86mF7BrjG4T3TWMQlQaby5VsrnScG1fRpV3qO/WwnhrcXB79sNxrobXwMd5+lN8aRO8ndxu090qfpml8ilA7p1/gVyzXul312Snm5ww+AOZLf8hOg9iDP4i38Dflm1fBVuI5KPayenwL9yBH8/8J/QOW5fD+2d0NGj+NdQNTBqAEM7QXo5as8MdOtEPSTOq7QtrfhZDmWRcvkhOVpwSvTfI3ITpDx2ROwqdzUMVlXYD9uzA/JJEOhnFPkpnfOKQVRli0GGKVnTCZFdT3PadgZj6rDUdjNyU+Aa0YGHZP2lPfXxA8KH2he7hIcPyed9IE5VpTthcE2Gc9kmASxIIG2HBCrFl86bgQz5VRvwPmfPtE2I7ha32hqH5LuKjjkhtOXGy7TM0T4/IPc6aLNaDJZXHtOOU9aJjw/ae+d0QF9v2p80N6Gfij8lTvs2/VJtMddMXGoHe950ldDgfbIrXWW2RTx+nTjuoznjD8snwmkbAz9IJ2DeoMtlPiIMrZf/j9Ih6y/QBagu03ngq3S5wxt0iPnT7ecP0Ak8PfxrwJeBn6FD1OU21veXZ6+0uvfIOaL3Wn+/gRixX6d/CF4iXAV+Ld2CfZMYWP8IYfBvkKjIMp0B9OXW15+myzn+cqur8lpusF5v9TboBO1PE4WtsaDRMwL+QUL8L7W2P0W3C/RFOkf0w4b/I7pvwigE/0ESmbxHBJoRkHHDobAvtTm/Qz5M/SFdHvTnyMe1T8hHm99vY92iU6JfIUY4dOdPPt/m6ZgbdHSik0Xr52fIVv4P0XcqpnQ6cdb6cMfg7284VjGOSE6956NO25x26ejtdXLmo7Y1JdCozRsN/p8ijoeK6wdIcOLn6Ojp15I8/jt0107XM21X6c65/IdkFwA6QXWj4ULDfQr8cHtuFMj0Xo2YXToaeoOcU7lLx186Tdfo8tXfBP5yw9sXiENY+9uiW78xcVyuE1rWQd2mozsdMM/9zIiy+H5ifN4jwYwxXXbRew1HV4jB+FKb70+1+f8AMYjrx7U1aPbpDBodEQrONHDuERvrFeYbEXfpvielcftr21x36Ghjn052nTSY5c9bhB7uke/gXKej36+0vn8dOZz89daH55C+QHbZv0H/EhGVlGOJn6327gbhM3cddGpcz6U2Pg1vP9V+/sNE0d4jSuyF1q+R8m1yRldjROPiCh3PulMtzbkrplxx7id08mVE99HZr9Gt3cv0FTt0MueA7tuHrvO11tfrBdeTNsYPET78dQ2On6Lj39vAf0QCTK/T8YP4vkECKj/b8PjlNs87RJ7pEE/ozthcbf1tt3p+UP4nGz6ukyyTt8h3t14vbR/Syc0xCbC90GD+GjFwrtHJ+4NW52dIMGedfCj5sOHsJt26nbQ6lxtuvtnGlg/s7weJE36Z+R/XNghDg/Xdhq8fImfa3m941Rn79ZzVmw8bvq+Ts1f3SCDqdnv/FXKGeoPIpYcNN7+yzfMnicH9A639n2113ybGqrs168TJGxMj2jNEv+wz5PYeGUxr/RU6Ie6X0w/oGOAngT8J/Nz3wx/a47dc+sa3ZN4/2Mb5RpvX5Ya7WYPXXZSvk6ycW3Q89xfasy+QqP4GcRyu0+nXr5EghLSgIa/M0vmZtnW6SieL5XWvLr/f3imfDlv/4/bvZaKTNhoMOhLO7wqd3qk6fFjuE8PXANHn6HjlZwiPvwF8b2tTN0BPB3/fobMz1F37hG+rQ3W9jeP9Ata9T7f+K3S6coUOjwYC3Y1ap1ufq6XtN+gH/9VPr5AzVgb4DDLV8k06XfErWz8/S87jGnDepJNVLxMHe5POFlwnu6JfJXp4nWx+vEQn97TFNsjFc57P3mz4ebPBoyN8nf65QnfifoYE/79ccE+D5SfoaOEHCf39ZGv/OUKjP97avEmCeT9M/1KP04aXnTaft+lohTaH/5zu7PdNztLFN+loyDX7kI6XvtBgcMfSM22P6PTHUnv+Jmcvw/nTDZZ/rMHzk3T8/HJ7d175RDhtj+gA1kEbk0jWhGy/LtERybskHUMDQONqRKfEjL5tkmjnGvmA84dE0W6TDxwbTTMSskZ2t06IM6lxrKe/TGcYjOhHtXW6KD83SRS2RtpXiZOpsTWlE8butoxJZFIhrFA5aW38qYNl9OwKSR0cNTxsksiaESrbT0kkTacDEkU2IvaQGF1bJN3SHb5NujXbI7nx4n63/b1OPmxYI0lbDSYjhqM2j3foR9d36NYPEvkY7rS5xf4cST3RwdFArTttMpkR/hpEuEL/49pVkGqYfUinrO4SJa8DbnT7hET4Ic6vO5ZG+rytao18lNHxTulH9jSOT8nHtXUonI90vEt4Z5EYmrS/x23sd4njZMS39mf0yl1cle0aoWXpYVLgFd81Cg9R6nWX96jhbEJSg42eL5A1kfZ2yzwvE4fAFGKVo0EhcXmZfgqP9PBzzI/WirOhYSqulAE6LO446YAsEf56TKdEDZQYURfXmyTleK2MO2P+TptG3GbDzzpJbblc5rNLzpmIs0l7/6TVOSYfLNaYF88a7yuE5jQ8LpPo7UnBxyo5rK4cXSxzkEcqnW2R2ys/aG2N1lZF+00izw7bHJTnd9vcTOFcbTj5sOGJ1tddOnr+OZJqS4PhTqt7Qi7DGZFUsi1Cp85rkdzeuEV2lyZEZhqwWWrvdcLdrdfBs626yGDTv9HG/FGSbg4dD+uYT8kulNHjVToeF2cGBk5Knc0Ct3Rjf0a9d8ma1d3zeemR23RrNy3zUWfrUNbo+yb57tWotfkmccSU535jTV1moM5UqgOyk2VQ9oAY/18nF2p9yPydNp3BGixYb+P8Lz6Co4/66dTaCFd/OnrcHSpl4gHw5qW/yK8DfvvX6aznn+BbnsH3bvItwfs/edCQ8xr8tT8Hf7DB+pgcU7hP/0PIzqEee3iB0LIBglUSDF8gMuiU8LB22j7hrynZcaq8po5TZ6y3et9oML9QxraO9sG8IJlll6R0npB0v3t0a6oTqS02T3bXYltp1V2Yao8YAL9P/wyWNtKV9kyZ9G4bW5mrEf8NzvLwvJ22TWKHqF+q3WPZIscTaO3u0AVrJvRl8TXO7rSZTXJC0vshKbL7DY53Cb+MC5zKrEl7/i7Z5dttz9x5Ep97dHLNOW1z1mb7BkktlAYdq17W9vXWZpsEEQxCWly7gzafRyT1/5COFr9J/8Za+9yi/4HsPfJR+hG5fXyN0OJ7ZKft/dLW8s3Sbo8cURo6d8PyiXDajPZN6QjqBSIEXOAZnbd+QGfgrpMD8CMSRV0hSuw62dmhvd8gCnutPHMhr7S6J8RgNQ3SehOiOGqEWAfsOmF6332G7CboDPnzObrgm7nl62Snymie0U4dr3WSRicTS9RVMV4nDHiNMMBqwc9p+13GNqXkRZJGAVFC/lwhEc81+ueKaoTjWqujQXtKnBB3Ca6TtAsNHMiOnFEvhf4GfeG1UOq4BjVKp3FOee64h2SbW2NyjdzuJF5HhKmktyfkYKsCR0PnaoNzn9BHpREZ3GjVVSL0pROV/QvEKdkq8xA2BY3rf9zGWCepLvOcLOjWua6X2/MajuL7gNweJ47sb0Jyy41+6WzKDyrlUcFJ5aHqtEl7OpwzIhTljWkZSxlyjTiula+vEkNlSpwHDSfHFmdTEvVbJTsflTZrMX3iObJroNO5SOhbo8exKt2o0K60d5MGx4v0U2mm5PKLjYI7DWjoG1gLBTfKjVn727YGfYRZHlF2SVe7bYzPFDwskh26NbITISzXGpzKlT2ylnskIKfjpYy4Sv/CH41ysw4ek52Byuvie0pSL3UM5Gvp04uONsjHUq+2MR4S2n/IWZmkblEXuTN8Qta2Oiw6pPK/umY0aLNDnDBl72cGfdt2r/S5BPwzbY6vNvika7NKpJFJ+1kDMxVn0kp17A4bDFcIDdmfsCuja/qs+kKnFaIr6li09gckdVq9CVl7x3BO8qmy1GfOcUau3B6RdK2rre4uoYdrbcwHZCdoQlLvICnnGoWur/LbwMLQaat2yrj0UWXKtfacf4hue+F3kbz1HyNWv8z1YicftI2ERbrdITJbnpRftCk26O/Qj1t/zs0djipTpvRtJx3bFfr6fYM49doLwqL9pe45LXWUI679vKJeUJ4fEVtjjz6/qjMqTda/fSYt+K7yrnV0fC4TnSqfamNpH8pTth0Rm0kentBPHRS/VafVHSplZS06euqeg4KLFaKHxIU40457nny2YMJZpw0i95TfBnVGRGYuErqA2ChX6N+CCQkyV5uoyvFjOntYW1UcGoi8SmjUrB93whbp603bHhDZNbSzj8och3ShXBkX2KuNrF0zJsELbfPRoK1FO07b+CHJprqofCKctmWSirFBrvw/pB8BeJVErzfoFkRGuEkW0XSb28So1XC5TbbyX6AjbJ/t0wlsyKJKmKvkGundAt8aUSSTVu82cShdtFfpRxFWyBmSNbot0efJ1fyvtHpHJLKgchuTrfl6iF/hWp22V4lRtEHOwokfGfdV4rQpZF4hUQQFl8adcI/ptuGrklaJQ9JGbpNcdqP8GjszkgKwQz9qvtFgk7kVeKaqOeaIOHyuwTBqY7RG5X3cYD8kjrlCdUxfUKg3pw2mDaIop6UtxNG4Sa43XqEf1fJaagX0owaLBqV4VlCbbnKNGAXPEUWqE6uBOm1jXye7jtXJekQU28vE6RvRvzzhWhv7FeLY3uLsLUcGAryoRFzIX5YtkpozIkZzjcrTxtMIti8V/S1iAGtASt86ycetj0dtrJdaHc8jaLgeEb6BpIW5w6fButbezXPYRuTMnLwOOUTtMw1gDaCbRNj7T0WtTDqhf4W5bddKPcuM/pX/yoHFgpsNEjnfKG21A6vzZcDA+RwSHqjyTBmxQgy1CVGQL7Y5CJOG0ZgEDlS+7uxDt85j+nQLSYXVubtBXwYukGvbJwUWZefLZHdpQq7b17h8lZyRvNlg3yFp6Moz8b1R5q4hfps4etXgcoxbxFHRaL1F/1D7VXLOSN13Omi7T+hhiWQB+JkCi7SicaKcVy/aRpzdIIEGszw0jDXQnP+0wK7RLV9S+tBRg8juCd16XGvPRwUG9Zf9uLOlLLtGfy2dm/LJnVSDc2sFPuXtBtnlXiYye7uN9Qo5I1Md4KH+h44m18kuq7LMua+Qq94NbCjfnNcr7R9X6bYZvg78MeBXLMMbx50x8HUSAboNiy/DrffjNEG3fq+QNPib5Jy5jsVK+11aWSaf4xGHOgg6v3VXy7aTMpcDEkS8XPo+JLcZ3yAXRVxv/UhP6t4xMWbPKwb7zJ54RLeeys4RkX0ee7moLJDzqdDPorKIP3lQfB+0dht0tHhAbEbtL23VK4RWIHcY1EwDbbEbJEAmDVW7p5YZ+SzNIfkEhfaqQQiv/Ne+NgCyQmcHqXcg2Ri2vU2CwC8SPbpB9Ll0sUR2/nxW5eE2Z22i6rSd0NnDa0TPnZAMtVcLPt5v72+2v5+jkw3jAY7U6zQ8aGcfEFn+0qCNgcRbRFavEdtJO1wdYEB4l9wOXttaNgnPrzV8fHbO+MPyiXDaPqZjOv9Ny0+FxArwz30G9j7qUilPyr9K6Iv0BYtpDIvlmTsRp3OeSawng3/HZPev1q2GkX8/Kb/PSDRIoV/ntTinb2Gy7il9WKal/qzMrwpVSvsaHRsRZT0cbzpoX2Fwzov05++aPSl9DvE45Wz/01L3dPBefNq+4rq210CreILQjviG/noM4ReOaoQKDwW+4wGOn5TnNTWr0pb0d8JZpbc8eOeYtZ5zeMJZ+tNInc1pN4QRzs5nWuq4fnXc5QG8FV86Sufht+4sTAf1pJmF9k+6gj6P2H44p5PBc0qbSn/iXphrUGNafs6LIs+jV3E0LPZRDXPn6pjWOebsegx5cTg/8Q19ehriVrkjHh3/dNCXtFLbVnxU+VjrDedQ1+oiWTLEv79bx+eV52u/zv2UpGrOo4G6qzGUG0MZeh49Vfquc624lKee0F+fip8npb9FIpuGOKp4VS6fDOZQcXV8QduhfKnydEjXx4NxTgbPa/t59Ol6VL1tPeWn9KE8WCht1VtDfTfUq8N+6j/nrVMx5JehbB3RX5fz6NRnVf4McVn/qYeGODLYZ+B4uDbDvnt0IQAndB/ofvG4s/K/C/gHbsLvvJ8c4OlZXqhzGepP12oe7VcYRvRpr+rOWRnjCWfnPY+OKkzDNgbNhnWrDh+WIdwVpiEs58nuWob6S9sNztojzqPaH8qFoQ06pIfzeFg5UfFd104eqnbPPFzA2fGrnKjPquyq+rrKq1POrmXlfd8tzKk35K0a/Hd9tb2qPmLQfjp45pzrZkXFw7CdRZhPOdvvcF0sQ3xRfq/yZ2FQVziXmN/vcI0q/V5UPhFO2xO6lMddcrvLlH6kdBH4fR8lj3lG58jtkJ0JoysPyNmATXId6BHJzd8lTHaHXBE7anV36RB4WJ6/V2Dabm2NJi+SaMud1uYBuW79LjE+6rWjS+Rsh/Mx4gTZZlUQmGYwae2NOsgwlYCXG8ynJOq/Sq4OXiVX/b7X2j8gxGbu+2NyVbvCbEKijXdJ5EF828cQpxKq8/c2vUNye091BozyPCBnfpxfjTht09/tuDvoZ0o/rXDS4DCP2MjqEtkZM+Vh1tr6qQeZ1Gi1t0fWNJ49wqwf0d95GNFFhlYaDJvk9ksjT1vkTNtSw8+E/jX0RicrrvaIELg3GHe1zOeA0NAS2XWTD4ZRP9d2n5zxqjsgE3IZxRGJVhqNlm52S71Rm8MBZ502aW9KPnEgvb1Hror37EvdxfiIjkbeK/O0nlHEKYnM7xIHRZxNybX3K8Tgq+kdlm1ydkk5Abk57IDw4RZ9429Edur2yC6hsmuH/pX/m+R85WP6qdGbROA7n932twplUp4d0F+Xk9bfEYkULpEzgidE7t0lhoPwiGvxOi39rhLFNCH0WOVupblTOn5YpU9nmwXGLZL+NYw+u8ZbnL2ifYHccHdIzmRskjOeRoLtS/53rIWCb+XqCrk98j1yY694WiI6Z4WcEd6jo1ll3RbZcVIGKYc9+2rbCX35MyH8vklf960WeB/SN9QmxLlxJ9bdpUWiN3foO9jKB/l1p9Ud7p7P22mzv3tlPtuEZ5bpy/H7RM48JnTiuMIyIxk30tyUfNNpQuStdCTtbpL1VsZJ2w8aHJW+3e1xbpXna3FtF8v4lUf26OjrXhuz932d98nB+w3g1n34EeAfB/4gHH6UG7EPynir5dl9cuX/CTnXrdG+STJR3K1fJTpBB0YbQx3vee0qT10L6VA+lEeeNFiUQ+LAdXOXangufVh2iDw6IVkNI6KrJq0vZfJQz1SZoTxRj7vjX2FQri7TrZk69aDMe0SyvZRZ6pgRwdd+aTu8PVL7V/4UVmloiJdNOrq7S9ZMnLiLVG1ecabsdRe68j/kjKRy3L4npZ9DsgsuXSs/9+jrAB02+9wmNtEaZ3fatsk9DAY/ql0kPpTVwuB5tbXS34zcqrlLPyNI+/MJ/U8QidttcvYfQnvSm7SwVvBe57bE2V2/7QbLXeLXvE//Ruh55RPhtP2ddDcY+YXx60RQ7pBFf4lslXoT4l26RX2VpEBM288fpMswkJDX6W7X0Yi83Np4kx9kG/YeSWNQkP5qsuAa9WOSQuDC/RDZ1pUpfpDk936TbsHeI8T6vSS95iVy29EBSQ283mAak9sjT4nCrlEZt+J/gNzwdpMcyF6lu01svcH6A/SVOO2ZxsU98ukBmX1Mt2bCvtTmJny0vt9o/zzUbfrEVfJdnJdbW5nf8irdDT9L5LzUS3S3MskM0D9A7NrXfiojrhHn9AfIOmqcj9s/UzZP6Iw6DZLbJI3ugFwtu9Lqawi8QW4I1FkZtXrfRy4yMQXhe8nZq7vkzN+IrP11+sJMJfISHQ1sEQP1exuMe2VeECNdw+VNkjfvFekawdfo0jO+QM7TvUVnAF0e9Pdh+31MlNlVuluhdA4+JAK24tu10SD83obrCTn4PWl1f6Dh5x1yRsuUOVMOXdtJG8/nE2JcTOjWT4Uwa+O+RK5X/4Ck6L3KfKdNx3+ByIkZHb1+gw7/v5oEiOTPW4QXNbrMa/+hNu6dNg9x/XPkIop1urUQt98gRpvBGy+BeYUuXeal8uwl+uuig21K6SaRXTM6hWYA4QcJ790ljvhl+umRW21cb4/UQFsiKTkaOMvEsYb5t0d+o8H0cnvu7ZGr9KPQt0lKkEb+Nfq3R+6Qw/k/RG40/T6Sov0q3U2UiyR49hq5PdKUmjE5dzptsGtEyUvVIX6LpF9v063payQlbURSfWet/oRORr5e2u6QT4XovFxp9dVdkNsjHV+n0BTo9Ta+zp3yTX68TNLZr5N0Lx1idcV9QpvSh8ZejaYv0V1WsEzkFA3eFzirN6GjfQMkayTtbUwunDmgW/sxOcszI2eIVsj50y+TdCrl4feQlLaV9rcO1Z0Gh2mrh/Qvy7jZxlEe1h0R06Tq5ZFeqvIhMQK/n462vpV/e9IAfQH4eXIQ7N+hY+A/9B+z+ut/Fb/mS93td/p6r9LdjqfueYsEJK6V59fbu6/Rvz3yNrnV9w5xhuXhtTYHZaxO74SOBqSpz7c1GBMeuUX04Y0Gg47hGjm7vUFfhw/LfRJIN/DwOTo6XyOB3DcbCqvsHgY7afPUboL+GXnLCbk9UnvTuh+Qm2T99xq5PVLHZZ3QCg0X3yzwqZ/2ia2rs7NK3+6xfLPB/33t7zU6PHtT5yNye6RHHZ6Qb5VdoW87G1xZJ47aTTqbptKOzqe3R25x9vZIYw3acc5li8i6Fbo10m6AOIRjOjlAg8s1eYOkJz9u798k/FT1JsQ22SV2zNvt3aS9u9FwBqGLd+jw+30kjXuzze8LxJ50baVF5zlm/u2RJw3OH6Rz2md0/sktuouFziufCKftb5LbXHbpJqpyMVpyQieQ9siZixPi8dtO4XFMdodkvgWSR2vEdVTqHZDvGqnYFsr4RtBkghrVWhrU2yFCzDFktB1yw80TshOmIblGdoV8VqMKGoi7pX+DcgpW6EdNVILC7zv7eEh2c1SsO8TQdc6OUyOJ28Qpqs4J5Lsd6/Q//KyR7E6bu4ziRANsj6zZpNTdpv9ttIeEUXRqhjtttj8mt0cKu7tmS0Qx2V78CcMecdBqWyNzR63ODnF6J2StjsnO5wmhxx2iNKSfRbJLZLG+2/zixLUyArbT8GjE0jWbEV7bL+NqmB4QgbPU8LxFaMAdLucLMXoeFXzT2m+XegZhDgieq3FzWuo9JvQqv8zo0628J39opB+TnW5pv0aXpQeDQ+7e7hDjWvyckF36ocNmG+WJtCfNaPBttzGkFduphCt9iTPnKK1Q6omnilujnBA5II7EwRK5kKfSlLypvBGW5TIfFbSyw/bCtEfOb0xKXypJ+V6nbUpfvi+QM22zApNzr3Ks8tU+cUCkpe0y/oRE4Z1rxbd4rPTtbtwuiRhXXOo8KCcOye7BlI72HhLdU52WyusVnodE57lWnmkzKrs/aOuO4ZTQkTu60g+EphzfNvK4OFB2rRR4/Wl/Bgmr02YQSZyclH5dW2Wz8FT6togz+XQenU2InHyh4FP6VT65k3pK5Lo4ss2IrK2yZo0+nU+I3FcuOm/l5iIxOJXP8qhzP6afraLs2S9tHrRx/qWfDOz/46/mRr4V8qmjU+BX/o5fxT/9D8OPfPy7+JE/8ru6bxXs0Vmfn4fv/Urr/A2+5VH9v/9Sd8Rkr+FFWlFuQmSO8qLaFsqVqqcOyr9HZLdKmtsj8n6VyHNhMDihPqiO/nllh/C+Ol3elE5cU3dnLio7hO4gMv1JqVN1J8QOmNC3sfbo21h1frabDdpWp+2kPNfOWSRyYYgXeWm79bNHds/UC/skuKwO9N0Jnfx6QmSIZbHAoiw0EKweNUCyRxwy5dqEvg3sPOV1+3HnyiIOlH8+cxNjm+hk7Q517oRuzauNMiO85ny0s+VD8VNLtZGVX8Kus7ZL8Crce+SIiXxQi3AaQFT3jLi4fCKctkO6qKUKT4esGlYzuu8eHJLtxFViZO2T7c53SD72Jv0r/4/oojN+sd6FuEeizZDtyjWCSBflEf0r/40eKORUSFskReCniNDYIkSgsakSckdHA3tKorVGGFeYf+W/BnxVjKvE2LlP/8r/fbJ1D0nrqe2ro6cBotPmLsGUs1f+q4hVkDrcT0hEbUzSIu61dl4Ba3ncxr1LbmQygibeHede+12ir/2cMP/K/2WSvuHaybhXWn2Fhor+kI5W3CkbXvl/QpTS/Qa7UeAlotCk0Q/o6PGrJHK7Qy4EWSS3cY3p6HtC6OaUGMI6GSfkgLFOn3jR2HJdJ0T47ZD0sAW6ddsi19tOyDpopEAU1X36V/7LAxadmPsF3yNiyFjccVWxqFykM2lslSiCD8l15fKB87xHnLHj8k7nViW1SqJlB/Qdq03Od9reI0rVuU9Iet5PETpyzR6Q3SXXYUIU1L3W90/Rv/LfQ8+rJMVmRmSSuJQuVOIf0r/yv0b+dknalAbpfpkTDW93ifFbg1DieYVc2a5TZkDFNZEPVtscVW41PRJym5xzd47LdPTzQcGb9Gr5qPVzj0SV1Rm2qVf+zxp+tui+77VAdhC36HhOOp6Qj3ufkB3JEbny/7DUc14a7uJqXPrTuFMHLNG/8l8nQmPItgcklU9neY3Ie2W7F1B5ZsJvE8pL7kyIs21y9bcR/s0yvnygkSKdaLzIl9B32qRLja4PylwhO7zKrJ8s/WySoOyIfOxbw1RYNP7uEWfDegav7pPMgveIw7HUxtGGOODZr/zfIvLZHT7fGSDe5eIr/9caDHV3qx5l0A7ZplxC9SfhV+3+LvingN9Kd8vkpCHvztlJfJPuLhNpR5zrWKwRuWcAZEbfvtAgnzH/yn9tJ+lW2Fcb7g9JWuwWkWNL5GKZMRc7beoF8VR33Oz7oMD1LE6begISAKsw1GDcmH56nTwn7WmrbJHNAHdcNwnNa09U+VdlyGarVwOUw7nIl/LafZJR6/KLa/nCIKI0NSK2sPpwjQSwtLvkl+0CpzwnXh7Sv/Jf515cLtK/8n/E2eD0CQlUnJZn6lphXyC2nXbIAWdtlFnBh4FP6W7a3m0SO9LiGp6SndU9YtOOiExaJb5LtQn2S1vLu63dT5OLeZbmjD8snwin7TlyY8oG+Y6HDpxGRr0N7hr9G868jWeVGDWmOlbD19uMnpAb2F4hRtxGgesKuUp0ldxKNCHKT+W0SAjl1da3O0U+kyAXCCEqpG6R3aZrBfZDOkJaJjcyrdKlJmgMqTjceTFattzmdkrSWlaJ8Xt7UE9D1X5epU+QztOIxVr75+03NTKmQbhEtzavEqNgRlJottrfG8Tp0AiHpMAodJz7LfrCS+dA5Ti8iWhK52xoCOoweWOaTvOIKA3TF3wng2/QpbhIpxT8QEdbI5JipGKWVkbkdi6NiifkhiGFqAbTErnh7TIx7nTaZuTWSR0d+7tKdkwUGjNitD5Xxl0kBpBG8Hr79yoxIG4x/8r/NfIpDXF/mdDZjI5mdeSFV0fMOpCboQ7aWMvkG2Z1bU3hWSBpRwZ55Nd9zl75L63XnanTgjPXrBoR0uiwaJxU2oNELCdExiwT/nyROLgrhC7FmcET5clwzDG5kWtGnNI6Hw2BDZJeq1N4leBd3hTnE+JQ1kwt8XebpMjZRplwjURtR0SeSesVr1PiFEhzU7IWyhjnpIzZKH9v0Of1BbqNBtd50n6OSdqzhpeGsjQ6pUuPWW7vbtDJrwnh/5vkRs0p0UXy7HHrb7fgELJjdUS3bgaFDLjcbHh4TOS9juLt9nyh1bOtxqAOiXThfBz7MpHxR/Svm79c8CLOrrd56diNWz8n9D+crZ6WJ12vMU8/0zZq7W8RfaE+mLQxpDNIdonG0TpJy5KWjgoencus1VUu7Zd6L5Id/f327AYxCL0x+oDwymXiA62V5xtEPqtrhFvjTTvlCjGmlYl79NPph3wAuf1Snn+1/eMm3cf5FoDf2QBZA34PnRd5i29FNzb+egfHPv0baNWJLxQcCre8a0BQPNwmu+oGJqWpK4TmZmWdNkhA6xr9W6RHnP00x3lFR+GQOA8b5CZY1/ql9mzo6MwGz9y9V5bIe9UeOSG3a2qLWbfaWNqGN4leqPP7DP0r/ymw6LRNSPoopZ8qUyzaQuqeacPFDfKNU21LbZIpcc7H9Hfg1MNjsot8lXxK5BH94Kb61Z1g9beyXjpTxi+SYJ8BvHm3R+4Q+axOUz6aFr9IdsxulnGHetP2e8QurXb2CR2ur9OnC9fuZbJmOw0GbSHt/DEJEmiPOrcx/bJLp/+9nVj5s8HF5RPhtEEW0386Wr47JQp7cfC+1q/t6+8M2lPeV6asdWu/8/7B2XHtb9jed/Pa1DnUsYd1h3OobYawD/usKTpD/AzhnIefOu8Z8/ExxNcQ/iVisNa+5+GkjrN8wRgVL/VdXVPoK37rnM5pN29tav/19xr1GtLjvD6Z8+x00G64PkOY6jzgbL8VvovwUfufN948ejwPP0N6GsJXxx3WWZhTp/Z53hoP21b8zOOdSkMXrbN9nMypN8Sh5SLar3BW47XOcR5sF+Gs1qvKu45dnw37sa+lOe/m8bPvZpzF2zyaGcqn4bjz1o45vw/b+Xwe3w1p2zWcR8fn8ed5PFHnM+yn8tZ5fDJPFtb+5tHBPJwN5wHnj7kwp80QJ0/j/eGz83jyvLGlr5PBOwb9LQz6Y1Bn3ljzaOg8OJ6lLee0Ha4J59QX3koLtZwH30W/D2XGPBnzLTw78D7wL9IdlPnngd9M5938FN/yQubNcx4eKi9rxJ+W3+fR+Xk4FdbheEP+nic3zitD2Tp8dt461fa1zBtzHnzz5M48mprHL8N6wz79e8ZZeJZJgPI82M+TNUOYDbgN5VeFY4iTeWszlIMXjXsebubJNTiLvwX6smQevc2Dr5ZnkaNDh/g8uSceh/OuPsZwzuf1e1G9YflEOG2XOLu4GvhDpXWecBsi0HfLg/bz2g6fD+sPBeQ8ph0uUoVj3kLO+zfPGZvnZJ7HRBYF6zyGuEjR+a8arPMMsHlCaN7z4VxVgqYl+twdx3lMPE8YzVM085i4Cp9TzvY7G8Bd/y0N2p8niM+D0Z9DOqj9KzjPo8fz1mnemtd6J4O6FbdDuIZ9zhPgQ/5wHSt+hnwC/X7n4WO4drXM46Ph+tXfh//s9yIlMxz3ovnOq2+p6+Acpel58GpgSAPnyYd5MmheAGPYppZ5eBK+4dyrQXAR79V1HD4/r71158mW4ZrNg5k5z4brI0/P45PzeKnCcp4SncfXQxjqfE45Szcwf3wGfVWcLM+pM2x7nnwe0sNwjIrPCv/x4NlQNg9xssB82GudYbDi9Bn6exqezsPZPFlKqTeEcV7byrcX6Zrh8/PolUG782hs3vvZ4J3wua7f4sNhp3fp0iTdYv7R5+E/fQy//Xx9s0CffxznorkLj8cMLpK3T5t77X+os+aVCtOw3XDsi3bsan91LefZEcPxhms/pLGhE/80HoazuJhHn/NgOo+G5smH08H75dL3eXbFefw4xPu8uVfahf58zpvXUI76bDiv83TRPF6ch4t57xi0G44znFd9fzp4flG/Q1qft7bD8olw2rw0wDMHblUe0W2Fehj7A/ofxzsgqSVL5LawHXK+YIuc65jSbd16UNWt/vvlmduzu/RvO7O/ehbIdAyJ84Dky9ec3iX6Z7UekIP7i60Pb1BzbuP20/EXyDc8VgsMpuD43hQG2ngftN89u2c+vHny4ucDsh1t+01yMYD4WaCfJjUtsC+W/ozGuQW8RD///IAcQjel6EHBiYTrlvsOuVCgRoist1Nw51pVQe3cfO/5jg8bTJ5bXCq4qalmW/QvCZiRFJkH5GPX0KWF7bU+nJe0sVTgWyFnMPbLGEvkzJbznJY+TIt1fjXKKF0fk5sk7dNUjlnpS9qetLGEhfa357+WyrvVgqPa3z79SxEgNoP19su/yrcqCueySfLcXVvTej+gz8PiyJRlaVh+nZALFUwLM53miJzloODM9BQvh3DN5wlUUxvk5fv0D6wfkPNP22S32ZTGUeljQnLvPee0SXAtfx2S81j2tUXOg5kKIk8YIJiWZ9Z1Dick3cj1XGywWF85ojwz5fWApJmJW/nAswDKpgkdv3hOQhpUsQnXFmfpbJvsGNn2PGUnLSirZuQ66glJGzok57jE9xL5OPas9AORE6aUKldHZH09QyYPQ/h4Sm5GhRxor7RgXWWQ6+I7206IvltqY6oHt8iZOsd0/F3ioClb/H2H0Ir8tVbwozw4LXU812u6lbpikfMvIpGW/cwP9C8qWqIvx7fIuc+D0le9AGXaxhEWUwxPyOd3JuTMeaWRA3J2ZZekeh8U3EPSn7RRIA7PAUn7qjtSC+Rc1SHRZZ613GvPPqTTI1VXql+3yXlsz5ndp5OH1zbJbQYie4Xu4MwhcO9xd13e/wduX4Y/TMev8rxr67ovkDNtWwXXpkl6JkgZe0joVRqRDtW9B0TnqXvss+pubQNp4LyyQ9Zd3v6owa1+mNDx1gs83RiusgiS3lbtEY+OCKd1D4lsHJHPTi2WfiE6yBRgx3lQxlB/H5CLLNSP8vlwLlsNH94MLK06TuV57d4pSeszdfiEXA7nvBbpXzKlLabddkBSP6Vb5eOkjKuNKE536d/rMM9m81Kh++VZtYvEh/jVhlbnrqa73oVOe+1338vf1X62KEfv0z97a3puTatdI/pP3TSif7zGIrveJ7b8JmcvLBmWT4TTtkTyY6+Sa5MP6RumG0SwrhMlNCK50R7yHLX6CpNFco2sRqNXNPtsl+TWn5DrpqelvyMiYA/J92iMNq20egpnF81rWynwSNyr5PrYew2GjVL3cqu/TlLV19t4Er3GhQxPe79BDOFr9D9DID5pv8skx+WZSs4+NOTVCWsFdpXyEbkadUbyqDVEzJu/UuB2fI0yi7hQCK0N+hOnCgGYf/7ohHxnZ7XAep0YLQqAtTKOczAX2rldb7CpsGRMCNNdpcsp17GuDLxB/xzGPqFhjWHpZ4mcEVgnAszxZqWd4zu3a8TBqwJsQpTGdUJj0PGXgvUyWYODUn9t0J954tucPdNWc7SrkPUWujX6QYdFQnsaRUb8nyc0fUTOtC2RddEBEeYRuaZcY881Vz6opMSZPK/D4Zqdp/g9SC7tzUhwZYnQt0bPrI1V6ca+xbcO8Iv0v9uoAT4e4HZKbjpTFjiv9TI36eRaaStfD40R18L+Vcr1Gup/5yeAf2gF3j4Kw4vc3fb3GwUBE77FaP/2/6PbENDAWSLnRD0f4tw1KJVrk9adc6oRYmW/vHdIrrW+Tkd7BtrW6PhUB9913m5936Avl66W/p+0v4VTB3GDBG00+mrw5To5H7HS6jlfDb51cguh5+qmg7bKkFWig14gtK/clg/Vq66jPD4e4OzFNr78uEacDWWNTpswKQ9eIN9Eg/MvItFYV5bS6mgsu872oz2g7pFPVtp76V9Y9oi+0V4YEafIddwp/b7YcL1FX0ceEN66TL43puyi4GyT6EzfLZJzQevkTJu6Qvx8ps3bYKJyfI0ErcYkeLlBd9/In/1zuThnAdj4CN74eneV/z5w+304/MPw8DfDn/nX4T/97b8MfvgXu8Fvko/LavjcJEr9g/a8RoU32yS+yLdupfidP935iMft1ZjIvQn9s8ETos9ce2Wmsq3qtHllkX7gYImsqQEnWj83LujHMiMB2OHOpuWUbv3V1dXBg44GVsg9APKcbdXllYcVlcoJeWq5zcczbdoP85y2E0L7i23868TOED5tJ3WgdoGX+J3QD2KOCQ3bVmdkneiMawUX1X4dEfuk8rLyUFt0NHjvnO7R13M6bepUAwt32/uKq6o3LerjapdCApX1mWVG/9MulD6UPyPOfqfNgJn2/Zh+2ST6dYmO9l4sczivfCKcNhnvCYnOaMzKkDoDPjskEUSI4SyCIRcNqJxcGA2f5zhrvNmfvx+WZ0eDPr0xyd0n69nf0eDZYunH/t1K1VDx+cHgb+to3NToloq1Gmqn7Z/9iDt/992UPl6nxGnTwK340bhz3kul38VSr85niLcZUcoqn/peQwOyZuK6rmMVXo8LrhfJYVXLMbm5UrikqcMCh/jVeKhwVNrTsK0wn5a+67yn5Z/Fvo9bf/7UkXFNxNOo/BN2iw6eRqE3mx3QdxwqXjVEjugbQ3WdF1pfT+jTQHWkLMIrbVgqLTtu5YuaRuhcrFfXxzkP+VXHSvzZf6WpSi+Vzl3T6kiJM98rZ3w3z2k7pL8eB+W561GdRfnLsYeyTboZ8pJtqjN/MHgnXpUBVT46N/FTnW7ncEofR/IS5MOjyoRv4eIfBf63R/y2u9mxFf59YP2vwu2/3N9paz4b79Ln20o/dW7OSZzJ7+JnaMg8pv8hWf/pFB6V98sFXtdqqfRdeRjOyjP5wXfynnVqilaVDcqnKodn5DMwR5yl5aM5bR1feSpdSL/y9TycaCQO3x+SXZGqt6Rh6V16EE75ZbG0q46r/D3UFaPSnzxzSl+OVx7x7wNCFxW3lVaM8qunj8rPoXyu6y1+Ky9S4FMHOk/lt+9rsZ42jmtV4Va2jQpeNQCrreOaqcOt484S5EI2n+2RHZ1f/F/BL/v6L8Ifp4tG/Hk6L9GoJ5yN+tTnGhwQxTcL/ioN1b+rrq66pNoF4mqJ6MLzSrXZdFqGsnNoT11UlAk628rpqucMHEmzlQ8qPWpP1Lnq887j4eHaymf26Tud06EeGurmqveGuuSA2EPWlzekpZrCv0gfliFuHWs2p16tq1x1LpWXYb7NVmH22RGRcZJilQmVl4el2hO130P6OBu2Ef4qC4fyR5wdlzby/RFn18w60oj69Wm0+olw2p4DPks36ZfpvN0j8t0blcdrdNuJD+h7vSO6m2Kukm+crdF90K4K1avtmYgxYvIGWZSbBa51EgV6nnzqxCjlIYkoLtEJyJVWb0zSZlbbMwlygdwuqfFyu/3cbHN7s9U9JNf6XyUf13Z3xEjFEmG6utP2Brk90o+THzS4HGOp4fYJieZC9xFXt35XiUNjdGXc/r1GbhnSiDZasES3pp+jn3q23uay2f6+2fCySz9qfqvNQZjXyA1RwgP5Xs9iq/c5+jcRTcn29Cq5mvU1oviMmDgvIy46czvt91vt3XUi9J6jv9W+Qncr0C2SClIjMuJMAX3Q5nSNbLkrkEYkQvsiicSPiA7dIM6dRsNtEnV8jo5WnY/puatl3EWSBqXTdo18THRW6hsNrf1tkSutjX6vEzqb0dHsDolEjkjqio4GhPYOSIR80vp+o8Fh1FP636CLqKoE3yQpji+VPhSWEyIgVb7i7JDw1rjBcJP5RsQL9KNqb5C0QSOXr7XfnyMG3U2y1mvkBsJrDfbKh+P2u3wxbnOvuHXnCGIgKP9uFvxstXc3yhw223ir5KbEUZvvm8QBnLSfVZ7xSgfkH9iDw7/eRUe/QlI8P9P6MDVHHr9CFLBrqDEP+Uiyc6/8cJOs2S0igzW4XiWOiN/UXCe3KJq+PmlwuGZH3VS+Jc9vtfq75KbGV+j4gYYLo9lrxBh6k+zOOS+DBo8Jz0FuIpOv/K7idbJj80Z7vtjGt612tjyy0+YjXbhG6w1mjZMJY7mj8AABAABJREFUMaTVc7cLzj7bxneX7EqZ7zVifMlrr9HRzvMNx+7cqy/q78I1InLvxfbcTZ09QntVb7puaw2+W0QWOTefyefuVo1JKqXjeouisvBVOn21Q3i5OkPiUme5pt3dbLjZJvpduBdbf9o310i2jumPIzraG5Hvh54QPnDX/3Lrd0Y2sNVh7iy8TOTfbpuXc/hlLzTAfxPwI8Bv+9/A9/3ebsvuK/QNkiUSxdKRk/HWiVH2Atz6S9HBZky9ToxoP1tzg3weZqPhYoXc7Hyl1X2Rvg4flk3i4Gq7OO8p4b/PNjwNjeZhMbVuRI4ayLcWd2hut+mrUyf0bSxl6W36dtFzZOdPHlauSCc6FfttPjfae22bJc7qIfH0Wvs5paPHW+Q204/oZPFnyZpoK48L3NVpk49XGhyv00+gUCe46+Vu8udIVtcS3Vq+QWThIjkO4g3Kn+OszfYRHS28WZ4pH18nO91mH3kD5Sp9vQnd2h2T7JxbpV9ThV9q+KlF/+N1+rfcLrU5KVOkXX2JfWLfv0ZkqGWn/fscScF8Zc74w/KJcNqOgF8gubSmBkgQnmn7KslvNd98iwh/DTi/Q7ZIx9jbbZwdOuTfpZ9HSnl2Uup65mKn9fcVOoI1D3VK8nT1/EeEWD8kUeWvEEb7gDifKi8Nl/fbu7prc5+k/22T72/t0hlIy5x/pu2rxIDcavDeaWM9ae0VVOLGAJuGwAG5lthxJuQMIiSTYpMY7xAH15TUael7TPLot1rbD+gLJCMa7xDBuEsYQkH8oMG+SITAMGpzhzgepgAoqDZJmt0KnTBWEAjfhHybZJukzt4nawgxTI9avXdIxMt11sk7Id8H+Rq5TnuLfpriA2LA3iGCS0fHv3eJ4/418l0Sda/zEZ4dOpoel3GkNxXXTuv/PXKObGVOf7skj1xcXCHR+hn5RlbF2Qp9p81IqwpZQ+2I/tkhFY50sN36fYcERA7I9dL+bRRT5bhNorziTNlTv4m2RX8HwfKAfNtOJ29W5nlE+PAj4mir0EbknOukPL/bnv8MMQ4+IN+YHBMjadZwX9MjHQO+lcHEfUL79+mvy0nBueu5RD57MqWjgSd08kw8/Lqfh8Vt+P6/3imx39xg+Sb5EKu7v8oO6fE9+udyl8iOuMZCDTbcJ+eh7jf86PgpmzTuhdcI6h45Syau5dGl1t994GdbH3fImTF/Fw/7RF9sE36+W3C/T86qyE81kj1u/e2RsxYjOvpdIob7KXFINlt9DYAJ4bkF+uew7pG08h0SuVbu67TtEp0lzvbpZJH4fL612SQpeJT+VujW0OCU+gCylkOnbbP1uUb/Ku0qs4Z603VbJTppRNL6PSOmnlOX+WyZvvzZJJ8ymzRYHhAdqUN0SOyIbWKfiHdIwOouZ6PlC62/x/S/0ya8k/bvZwnvG+T4Gvm+mcE3Ay8GKg4L3ih9v0PsJ/X45iO48Y324A8Cf/b3wufpLPpf2Sb4s2VyWwWRp+SsgZGdhpxv0O2cG+B4nuzqvE9fjh6Q735uk7Ov2k9r7f1FO20avTrmdYf1LjnGAv0dXsqz+rcyRd1l8Gh50Gaf6Ex14GM63BpQ1QZVJypzl8h3zMalrbJ4sc3H3Xr1k7DrUA7xskk/2Pp+m7+41tF6QL5heUxsOG29E2InQV9GaXdpi8lzR8QeU+Y9Kj9tN6W/C79LJ2t0Ql1/y3F7v9reK1eVj9rbNT1S22tCX2/S2t4lm0EG0Wj4UV5+yFm62CRrR8HlYYPBzyc9X3DyHtFhB/QdSAhvfoUEMdbo1uei8olw2pbpPHEjYutkq1Dje0YXOTigQ9Y1kj/6HP2IzRbdQt8iTswinRJy52NC8qbrM79dZF72ZWKkWm+PKFE9fZ0v6xmc0igzGgzZqTom5+ButL4+bDh4udU9Ih9bNSK6VuaqQ6nxVQNhSw1np22c6ySSu9LGkJFutt81sCDfjJkQYbBIoq8K15sk93lGorGWjdZXFbCXyRnEU3IOaJe+YXy99b9HohbXyC6FCnOpzYvWp+8tUzoh4/slssOn8T6irzTcLdSB1sm6Ts4HHRGjxfXVGHqJfPNnQpyUVbpoig6jDoLf8HFeRqhd+yvk23YKcPXodfqpDEbartFPR3M+E2J83Wj9ajTb/1Ib8yodrRy2Z0YTa397REmpACD8pUG9RgIi8oYGnooCsn5H9NNIpDfnOS74uk4nR/Yb7m6VeV4ntCx+DuinR9Lm9mJ7Ly2ukShqjbpaNLBdk5tEuburcYvw5Qk5pyTNLZWf6+T7UMd0tKLjpCFn0KPiVoMF+ruWEJp9kewYv0j4x2iiQZpJmZty9AlRvrcIjy62zq8/7PDwY62Pz5BzJi8T2bRHzl5pZCrDqiJ9iU4JOnfbj1rfGh6ubXXabhLcH5Ao6JiO3lfLXF9o85EPpa/dVvcmkbMQeabzf50YPodErsgfys0lQnfyOmV+Nxuc4sdvLEJo2b5tW4MoypYxke2Wy62denWPyKnLDTcvF5ypT9VRL5BAxzrRyfLSDRJQWaN/RlbeUub6O+RbVFfb388RvS/tDfWmsmydjjccd9rgF4+PSJBwncgKjbqXyBkd6WejtTc4epP+xSfuOmpQV+f0M20cDffqFLgLv0H0uPLnOXLG0t18DesZsQ2OyfoaAJEOtUekUW0I53aD7Npeh6RgKKC/2gD6AeD7gN+9DH/muPPEIEJSJjwubScd0Bs/n2yWy4QOTTleo+Pnz7S1uUfOAS6RgOqYjt7UhecVL/7Spjggu686/YvlGfTPvZ4O/l4gxjxlbPuhTPsGsV9o81kmZ5wOyM5qda5H5Mzpemmrjep8DAgos5Uh0v9QD7k0yq4DQsu7RI9ep6N7gy3y65g4bRP6TpuyS5pS119tfTymkxUGa9dbvSUSNLzaYBGXC0TWqQNfpr/eJ+Tyj5fJMQiDfPL5IgmwbxA7pupNSHBDGq12trx4vfRRi/aUu9yuu/JH51c5eUQ2OZ4ftLVske/NrZGMoA0uLp8Ip01DRwPlOv1zQxLT68QjfYl+CuItkqZyj6Q2aOQs0hFOTXFcb2O9Vp7daDCdtPdXiZH0GrmwZEK8ZyMFRhhfJ2eJfP46/Z0YnTqZxo/v3Wlze73VPaCTmzLNi4Tp9crN/XauVTHeJtvyN8julnBqIL1OdjVU9rcbfKYJVKfNqMMLrZ5K+pSkDNHa3Gp4f4EYyeJ+RNJiZyTqrRF/s/W/Qy6teKmthYYeRBmrHF/nrNO2TRwHDYjbhGFV/uM2nxutrQJMp/MGSTdTedsWIiBvkdQqlaeO/W36htAeXQqLOFkkOwiu/bX28x4x8jXWXyKXndjnrfbcscdlPsK00GC83tou0/GXa60Qe50oQml12N8q2RE0AinPWU8HyB0s4RoaeLfpn8eDBFpMOdGAVJHdaPPdIWs7aX/rBBolrQa9xtGsrcFL7f1Ow8O4wf0qZ5UlBWdLZG1nJA3LZ/Kl/KWSUtmNiLH+OnGQ5C/b6qxeG+DW6Kw86pwWyUeDb9LRnU6jeFceaezqsCpDKDg5JLIB6AhiHTa+3v1pypmw3Gjz0dbz8qTL9He8HU9H7lXCi5Q5jYhhpqGi0W2RXvfJeR6N5dt0dLpCaOo14rS9QrcOD+jW6Db97IGbRLcc0XcupafXyS6X8kyH9IB+eqRy6Ta5JXBE7OoZoeVTzqZWSg9LJD1S2S4/XSs4OSSG3AK5VOE2iZor33TaLhfYDRAZJJAeDNYY7Kz6zvnXNaTBcZsEyHSklZWVzjRkdSJfJLJoRPhaWAyazMhxCnX0Hh0N6aBprN9q7Y16v0ZukpR/rzI/PfJWm8d98rFoi3bALSLHlUXy/iIdzY/ITdknbY41eLxOZNbrdGtkCnA1Jl8nu8C32pxPgGUjoWsNia81QLbodtgmwPox/JpfA7/mLfi//cvZ2jNSYbTidut4JQ7ujLM0NSH2wq2G03fIMQPpaY3QzwYXO23qmCPCu58lNp70d6NNcZGLyyLJ3FokaYsVhlO69TdF2cDMPjnms0Z2g5X71WnTqblW2k7pp0e6A/tZcmRH/bLMWT3kBqi6cULsjx3CUy+RAJU2jwEQdYB0AnGobfs60fUbxAnSgdJWeZ3+JWOSmXLAYKi2iTrSNaXBcoeOFl4n5Kf+eKX1sUxHSxBnUdlRHaUZcaZpMGtnT8jxKB3fWg7pp6W77sqaByQ1XFrcJvbDbeKkW7yB+XZru0m3Nre4uHwinLYndAA/bD8VvhKERGQaww4dUr36VqflkGy/r9It5H2CvGl7tknSgezXZ1sNph36V4gfkLS0vdbnETGsjW5MWr0t+hkE7pbN6KdmLrc+7pFdCFNzaHPSYTklN1YdkNRNDfsTEo2gtTFdZ6u0NYd+rc37QRtv2n63nzvkjMsm2U2YEUFz2MZQeYlvFZYRyyW69T0kOz3iUWPufpmrUXMj2FttzMet36roKPCZhnKHs07bFv3dnpMGu/pKOHXM667F/QbvTmuvADgkufXVuKj1Nunvto3ots7XClwP6WjAOqZ+DSP0E/pXE1fDfIlcOT5t/clDBgecj3S8RQycBTrakL/cOT1p7X33Pv2dNulhh1zRq/Egz0k3wl6dWI1HHVAI7R22cR8UfJvKbIBBJWbEeYu+vNgjARKj71P6Bqw8I86m7flHZGfayOxQoG8SB9i1PSUpFI9Iyskm/R2QEZ388h4AYVFO7bT+xq2+/FUDDeL2fulbJV4dB/FjGvoh/XXRKBZnKkdlkbQ6pVsDnaTvv9c1qnbdpIz1a4Hv/63wX/6b8B+SXdYxoamDgttpg1+Z6NyNvC63322r/K9Om0GPrQLLCZHX4vqAyHZp6i7hJXla+QMJNohvjWnl6ZROQatP5KVlQneXS387RIasEMPRurOGgwlJ07GtY4hT57RGaEXc3SEGruutg29wRJxRcLZU5rbD2bQ86UHYd4kT6dhDp22JyPv3yI7iJv3P71Q5XnnkMTEs1Q/CslhgcX0MvI4Ibd9vz6WRfRKxd+0vE4foQXun3tMZcX0hqdhmfVjUVzqlBhKOyOeO9hsuRvQ/JyEffEBS++W1OyR4IB0sFthdj8ainW7ehsUPW2XTRGQmnbIJsPFnun//7N8D/9VfgX+GKOvdAkBDzod08vIhoY2VNoQ4XiPywcCQgZwZffmjo3Fe2SI7kvLKJp0tsknSZzeJDFN2zwZ/Q/jfMSecTUVU31bHzLrqnVViYy0R/aXTdkh0pm03CR15ccuE3Cy7SI5+zHPatBeUy/LwMQkOaBtUv3ub6P9Re/8R/cuyFsj6OJ+90tek1R2RIJLysdp4niWj9GmQfpWklFqE74A4ZfKrNG6wTzk3JvKj6k2I/t0laZC+PyA8pQyxKEffJ2u2TWynVZJ+PSa0qP32qNSpZavh527rTxvwhIvLJ8Jpc3dGY1PFUv8pBFQkU7rFPiYOmUb2yZx+FsuzJ0T2DJ9NSx8yz7z+bF+V0LTBckhfWRg9UdHVPih9C6MpLJBom+0O2xhH5Z041GA6Ls8O57Q9ntOHeH1S2osLIz/VKaxrYL/C7xwof+uE17XUYDdiW3FCaV/xvlSeaVAwgFuDrUY6XUv7dG3qWk3JWi4RQ3K4Zv6u4q5GuP0/GbyvtCB8db0rjdX1OC19HpX+nCtE0MwITQ9pdkYMi2psaciOCjzSdF3Pg8G87WthTn/SUYW74sZ6NbW1Om2OS4Hf9TM4Yz/PlXYVP+LwkPl0PpQv0krFmT+lMZ2cYeqE9eQBaU+4h2siflXe1q24Gcok5UHFsTBWGq1n2qxX8X5EX7bY9ojQlPg9Lngdji0uaudDnhL+Pwnc/TfD++KzrpUyWv6228qH1jsdtK03vlH6HtLkvHV3jMpXQ/4Z8lyljSqrK79UGpXnTwfvV+Y8s/+C1p7uq21rHZ1v4ZZfhzpmHmzzZLR/22etJ78YGHDNxftS+Qnh9cXSruK80qR8Xo1G2wzXU1iqzq3rUfFX+bjiu8638tpQ/lTeqvXlZesqZ47p02SVa+q+2m+dU8WrsmCx1avroAwZ6rF5NOC40vfqcKGHSJiSCNuf/ivdWbd///vhT/1F+HH6C9+ErM0cY1TwIf5d94qnOh9lwDJndfiwzLPHnM4Qp8qwqgMZPBM/Pqs6yiItOYchLFVW1udDXV552DrKiXlLAX0eHzptlfaHPD38eTDoW5xX+VH14cKc/p4Q3VbtZusdlHq1rfKowkh5P7TZKg9An5aE3bWq49vfMMA65BFlxWFpM6QV2xySlNxa37+dl30/IamatS307eiqX6r8Oq98Ipw2dy0kqCUCvA6DKQCPSz3a7+7cuJAH5ZnRdAlzj1yxafTLZ8NFqEJmRqI/9mndZaI4ZuRQ8UF5ZiSU8u5o8MwFfEw8eonIKL7MtUQiyEv0U6KqA+chZD8sekKYVjgOyA6ESgASfTkoOHOcSqQTInCFyR0xo5H+85KBYVtTlcSJAuqgPBffq2S9ZcpJeV/pwVKFggaAOJBmqjCckaiPa+p6CtPioK0C6KTU2yvtqpE+IUwr7dmnhupB+du5SmdDh71Gyk9Kf/a1XOqLVyPIE2JUTcg6O/aIrJ/reTLo7xGhIXfooBNUkzl4VDHYx1CZ7tPRhLyuHDgscEv7GpWjNt6Q/52juBgaNdUItd6T0tYIcOXhWuxH+GsE1bUyzW1C+HNCP/peZeCEyLr9gifrQVJ4Kq9UOKrDVXEwac8q/zwmClYYlDsTslYHJHr7LVy0UKLvXINp63eFZDZcBn73Zfhr+/CvFfwoP6rDPuEsnUnLe4SnHtPfnV8gu6vVcR+Ryzr8CLWKve58TIjzLQ9X+VP5etrmq9HoswmhP/m2yk5vghR9rk81bgxQqD+qrK5yT3pfILTh88eEjyf0HT+NilHBge8mhLfUOfK3sqYGWyflHfQdlrpD7VrKi1VOCXc16uu7qnvVgcJceXlCaFUnaERkep2HeNVxnJCziVVeOa6wVz1Zd9lqMLSWul7SeeURx/dCKeWUuJ21etVBlC5qwEoYpSfh9ndpetUXGkATErlZIkJHwvhx4Mf/IvwO4I/R7bpN+giqY8iPE87ShfpbHSmdn9J3ptR755XHBYfiQN58TPSqz6BvxM8Gfwt7DVIIR22jvK51qp6pNoGodf7OqfJw1fXutB0T/LhrW3l1iJcJWWdpa0J20YRJ3OuICKc2mHpvuBNp385FJ+Sk9Kv9Oin/qr0ubENbQxm/x9kzbdqRE6KjlT/OY5HQvXL9sLSxVH4WpmpnOw91qkW/Y1Ke2Y8wTAgeayyj8v2wCEdlvwlx5s8rnwin7WP6jobCqv5ePVMN3+PBT5ltuOOgMKjRq9ngb8epu1SzUnfYvj437982TwbvT8vftW93P+r4NdpBecYcmKvRa5/CA0k9GOK2CqWKQ393vJPSh+0q7LM5/VqnGloq9wrz8Zxn9l2N/pNBPWE9Ke/9eVLa1mhRfV9/r2s6bz2mpf1wLefNVwYd0tfpnHrzaM8xK90N4a/wLpY6rvmQH+q8a9RwSG/D+ViEWbhq/YqfSju2WZhTr863Rt/h7Hzrjrg/nyO0Wumsros8MNxRr+MP12g2eD9P1gzXZDinhVKXOe0r/fh+SDOV/08Gf8/rcx5di48hLw/pYfj7PJpdGrybh7OPT+DSycU0r/G8DfzIfs40VDlpGcrb6ogOYa9zWCzth/Q81C3z5lOfS0OV9s4bex7/1CixMNW2lSYrLS8O2lQYqx4c0rM6yDlMOUtzNcosThy/0tJQLsH5cqnib3HQ1zAQs1B+H9JvnY9zEBcVd46n03jeGlTd71g1GDik43m6bCinq5xy7Jq6NqSjYRmu/VBeVd09lKUng98rzVRcit/heg/n2ZtA7WTIeIsFiafA/57Osv4tJL//q8DWWdtgOPZw7qf0eXNGsqeGOJ9XhjJzHt8P9cTJnD6G/dUpw9nLS6pMWChtK8qk/wpjXZshD5/HF5UHlW/LnMVLnX/FqXJgKIvn0bnOYt0lPi7vh3bckP4WSts6Rq1rv0M5VG3ZiuuhvKvrIux1fYe2QbU9anthrjJ4KEMo74b9nScnhrhl8G4eLEMeGdYblk+E0/ZL6A75LdAdyrtKvGXzkmfAF4gHv0EOIa6QA75r5Jsrb9P/vth6ewYdYq60seqzV9vvy+Tgutc5v0UO6c8ajGv0oycrwBfp8mWXyNmdt0h0ZK3Na5Hk5b5Jl/O72+YmTIfklhm/1TWmO+y5RfK+q4Pmoo8azmYNHnF23H5+gZxV+gLZ0rWfz5PIw7jAcUwuMxm3tp5pG5PDqLQ2t+kOfG6RCOFlzn6nbY3sPlhuAd/V6uyUud8u84acL1kga1X7MYIM3aHPnfbsCyQavUL/NqWNVn9GLnBZIJdVXCO7PbalzXGb7uDtzQb7PokkrZL1nhLD+A3ynbZ7xMhYIge7r5PzY6tEAL3Y2m2RiPObpb7zcj777d8m3dp4a+o9cr5tiXwbzm+sbLd+xVHtT3pco38Rydul3ja5ylzeXOOsgfd5ctPpZbo1e9x+fqGNvUwuPFimu5XsBhGCX2ztd8hNjXVHeUJ2dhWgb9Ct+5SOR18gt57dZH7k9z6Jzq3Q0d4pORu412A+oe+o3CTnmO6TM6rXCs6WGi7E9So5D7ZO/zttq4TGVXZG7T5LbqbaavVvlDlskuMtB4S/l9p8dATEXZVnl94ArsKt7a7eBolEPqSjwbeIAaJMHLd+Vxrs0rpRd7936dxnBSbXYlTwqEG+SKdP6m7EUcOXFyc9JN9pGxN5cdJwKhy3Sl+7DY7b5FuBh/S/02Yw7IttDJ/JT9629gVyMF1efr3hYtpguUaixeq+VfqH2sWleHlIvt+nrFH3fZ7o1Wpgrrc2twvObpDvtC2Sz+lAvtM2K/19gRyNeoFOt0ofGrDDnbY77e/PkwP+m62uMqvS2WrDlbR5jXyTbbPA8iqhe2npOpFLyv432jyn5ErzN8iFiCsNtkf09dI62ZlWdi0SnTAhO2DqpwUiQ66Wekd0/LhDt3au2x4xANUVyoorZOfwLbLDCznTdpPw3G7rY492U/ffSbfYuw0xVbifkOtrJaq7JOqidfv7ge8Bft8vgx/+RbgHX7zdvR4RmnqT7GarM14iZ7M/Q75tpwy73P69yMU7bZutz7ore7vNm9bnSpvKW2Utziv36J+jm7Sfw90fL4q6Sv9MW7WxIJdrrJDLhp6jW7+b9G+AVde7U+vuzS06fEH0yzJn8TIm9p661EtHdsmZrQ1yU/iU+d9pq47R5TbuDrmQ7JSQjnBukLOY4ud+a7dFt8afJzuwi+TcpnQ9tNmqzfd2eabN9TqRrw/a+8+Rc5xVb0L4cZfI0S+0d+50ip9a7rZ3b9L/TtuY6AFl+GWyq2mmylqD6/Kg30mD5S1iO30XnUz6Nzm/fCKctr9J0hRUjBoHe0RxbZOPpY4IwUzJgXtTCyXIHfrflXFBXaSlwbO90o+M8YgcpnW7+hFJobAfYanjTogxbX86ogdEMO+Q7Vrri4dHDf6aYztr/Uw4+502nTbl8IxccLI2wM8uEaAVn5DD2K6LcJyQlBzoGEbHx3k7133yTZId+uckTsgHiEfktr0aadglB0v9fp3zUtBBDDCNJt9bdJwgV5cfk+887XH2rIFF/Lmeu/SNll0iTCFGgBc5iONJ6X+HpCr53gPcGl/S7TL9CPHeAE+n5ObBCaEp115+0ZCBGBY6gEbUHpK19N8yfVqRVg9Kf/vlfaXBBULLkGMSBw1GI6t1l8R6KwW/e0Q5b5dn0HduFcozwq/S41LBm8azKQnSssEUaWKXpKw9x3zFX2lP+FRsrpVrsUsMVx19aV8ar/j2siVxvUP4wDladuk7ba6975ZKH6eDuXipi06bhqryEULXykL7+xPf7MbaJCncj0p9+5DvXQ9TP5WvC+W5MJm2AuFDcSa96bhYNBAPCa2pQNUju4Sf3QGUrpUd0vRaGUtcKuOnhK6sd0LWb5ezTtshkbf2t0+uiq9GnGNKy7uDtsJ4SNJGpYsKMyRYMiU6wDW0je/EpzwqLif007MO25weEOPlkPPPtFWnzXlvl+fK+gmhG/upa6YzuUKCoNoMOmfy7owYwyv05e1i+fugwb9CnKbt8k5cmoY6pS+7RiQ9ekLfaXPuGvTqUPG6TyeP1Lnyz3HBqXrmhHzX7EH7W14SxjVCA8r4Sfv3+/4GvPxjufH/Np0DvdP60qnQIb3P2Z2sTWD9r8Db//ovcovuRsrf+HvgN96D//IP5wbI5V8OPIG97fiAf5TYcjqZzmdaxlEXnle0o9R38kelfeX/FvNl97C/CX3e056wzNp7caVOlXaWyHfAVuivwYzQyKj0K4zVvtPwV24rQ0bl71pc3weEppWT+4R+1IMGbZSx8kalLee72PpYJsFr5bpwLtG/bGNMAiy23S7z0FYU38rEoc02oa/nqv7QRlDfiIdq01YbhQL7hP7Fg9oZ4qcW4VTe13GEQUfQgJi+hLh+wNmzauq+LUJ7yqSLyifCaZvS3YwkwBoGEsRjOiK6035/QAwMDWMjSjo8I3JTog7dAZ3hdZ84CAdkt6kiTAdjQgyFd0mesQpuhRi3h6WeBDFpz94hxOBHt1XoGtSrRCFbV4WoIelH/K6Qm3lkhLr1q8B7p/UjIa+SD0lDPrZ7hzhyKtA7xIiqzu9pwaXzW23vPqJPoDpKRtgVxu5i7La/J8QQqvOxbBb4NRSWiKB7SP9WoYpviCFltMuzfs77I8Kwq62OAkij7jH51puCeVrwWY0UHYpJe6/h6BjvkDzwzdbve0TwuyMFCQgYEfuI/lkPnaSFNq/jhp/3iEGngeN8pGMdnDH9G51cA+sdE1qpNGt/Cin5Stjq76etziPCt+LbotO2Sm7a0vidkrXdIUJZI9I12Wx4lVYeEUGvUJ2Wf96MRcGZCkPla/CipspYHrZ/OtjvtucTsrt8p+HwIUl3eUyc7WpUHdLxhpHKOwTXHxJFoQEIHW6VSeJRfPv3Y+KIQnaO/f2EXB6gQVVlyEkb/4Tw1ynwk0SWrpAdBPlAh8kUE4MCa2SX0sDTMjHclImVzuTxScGPjkVVdjonH5XfD8lRHXGtjHe3Zpt8FFVZeEB42HLccDElcmnUYDIVb0LkGcTI8UIJvyHkh2jdpdgs7XVgDRBppNtWXTQiZ1nk6ftkrSf0LxRQh4rLvfLuQ/pnKQ323SfOo2uvwexOkMaLelHYlSfVaVNX3CU6WjnuGPP0pjpbp0dnsfK1ePQM9QHZpZ4QebtHdukO6G6IOyD6QL0u7sWX46j3aPV2Cvy1aHBrp/j5G53kSft3lzirZrzcIbdiK3cNAq2VeddxT9uYm+Sc3GGb95+g47MDOsfqJbq1VXes0e1yuYbbnE35dhf5P3ENtuFP/QTwg/A/vAP8YeAvtM6fwBXTlYCtd7s5bbf1mRB9LA2tEV14XtklQd9jsqOno2m/6pl5srsWda5jKreqXJEPodOZz5W62lgjOntWx2yLOG3LZINiyMOOo2N8SHQrRD7Om4u8pKzcbGO7yTElAcRJGUP9pvxSxqsP3ckS5mNiix0RvNeg0YTouglxGp2Da6Qz7Zx0SC3abKsNDu3bTRIEkUZ1vhZIoK7qTVr7+8RWqe+OiIyvDjT0b4pU5xoIgZz5XyL8eMTZ7+lWfQ0dnh83OA1eKZMuKp8Ip22JfFD7Kp1DopIdEYX/GZJys04QtES3VXuZ/pX/G+RswQJJeTOKvNb6eYks5HqDSUU0JsLZehMSaVMRLNIx8KiNoZDUoLxBdmeE2Z/CukJHONdI6tIhSTm80uYo3CNyRa0K0f7F60skqu52/l6BUwH0mYarvdJ+gyhHyyKJXMpMG4S5VeTrpc310pdKftzmstz6u052IirjrjfY9ojjca0901ARLus4t1HpR+Mcsit2XHBwRCJTGsTXWn0F2HMNR9dIuuIhoVPH04Fy3hqlVTiJMxXuhE5Rmu5nP9KPa3+ZCKh6c+I6oUNx/CLdmqu4FBruwEza3xtk614lTWszJh8TVSleJ2tf+6sKV1xcaf1LN+JJnKjLq4EnTDptvjsg9CZ+xmXe19p8jRRuEKPuKqFlDS6VTb0cR5wZkKHMZ4OzSrziTMPsM+35CnEaP0M/x33W+hMH7sQskm8U+W0oaQUSzNKBr7iVlsSjc4JuDcXPqOHnamkrP4gjjZFlurW3f53nG/RvEK2pxfU7VrS/b5R56wyu0U9BErc6bS/SV5QaGsp7HcNrBXeWDZKl8FyrO6aT6deJgSBNvVTqv0h2gq6Tb//Jl9eIbpkSuep6T4k812GRj6W7ynO7RBbJQ+rEA7q1ukGMptrWHTP10H6bzw1ySReEpqT9emnQFcJXvjOFrzptT1qfyqjT0p+w64yPOZvyrM6D6PRJw7H6wvXX0L5R8G6gTj2w3sbVcXI9hGVCeFt7QX37iHz3VCOvyuyHdHSjzSHuaXPT4Vor81R+bxX8+E69pN7QaVO+WU/aNACjHFsjMkm9oQzRKa0Bsqvkw+HLrd9Ja2eq64izsn1G5MoKfdkCcZCeEIfvW+NOgK8Afxb4vcDvuwn/1/udVaogBjbe7eTlfXIERd5Vhozpp+TOK8v0AwejMu960Yc2HpzVM/UZ9O0Paa2uz2mDq9qbkOChssDAwgbBnTtsfmNQHp4QXV/19xLhQ+E878r/UyIbhOd6+/c8HfoXiOyqY6jLR/QvvoF8Q9W5bRD5fYWk5l4jMlyakuZpc/0M/U+zjEpf82w2Hciq89VBS/Rp9F57f43I2qo3aXM6JHZ4tbMNAF0jR3sqXRzRXzMdMW0h9d+YyPhqs27QT9WEztFeKPPeaWNc5+LyiXDaVsjH+D5HzrQd0E1kh44o3yYpXSouhc9tkreu4fhlsmuiUfflNuaUMN+XCbPcbu+XiIDVkP8eEj2lwTdudY0yrAJfohNIiyTX9UuE0dZIREch9RZJ83ip1XcMz8ddbzCN2/w3iYFl5GFGDLdRw9kpHVH7QfJjOkb+YoPtfqunIrL9223e+3SCxnNrMs5aw+FbdAysYywhOtfX6PKBPyQ7HevkQ6Qn5GzChD5jv0py843u+ZHHUan3PhF8aw1/Q6dNI3KNLir1pPWtwlZwjUnuPQ1/V8g35G7TpY9cJ8JZOoOkj3k+QnyZdrTScDsmBsqULgdbpX2n4EFlrxA2KrNCnDYZf4sYjm8Rp1E6cz57Dab7dGtzrY11l+wAywOfaXUWG96+QAxg+9slO8tjIkyvEp5zp2SbOMkrRDFUR+NtQg/3yu9X6NbWXWCd1WW69bpJjPsvk92/m/TPirjDMiGBg1nBmVHpeyRQcov5kV+/32Ig43tIGt5iw83bDaY7hE9vkSjnvYKbKpOWWltxrbNxuc3d8xunzD/TplFxq+HgJRJJvVnmcJ8Y/xOynksN3zNiZE6JPFO2mKb3Ap0i3CPRxht0ssZ12WnzuEzOsRhIMY1tRscPV+jTmTxaP6LqR8pVsgt0PHpA0mke09HyZfLR4e0218t0azZq9T1HdUgnf26TbANae8/7Hrb5aWiqR75MPjSv0ecu4qSNcbX1t93av0GM8xEdHbgD8Ra5UfX10tZIuQ6JAc3P0w/UXGtroF6dkpRU8fJGwdlNct5LepOWdPx1Fo6I/nqf0GYNPrm2NaD4bsG3hoofnN1tY3yRyHF3mNQD18nHbe+TrACfQXYDNJrMzpnSybGbZAd2l07OvULOtH0PHS3vD+bv8YgxCTaoE/ZJ4Kg6bWut7xpMe0x2z3caLlbpp/29Rc4sqXNX27svkZ1jZc0CHd1+kaTfv1nmcL2McZ2OVqqjeK3hUH1/mfDucfu5TM4ra5zyBh3D3qfLgfzKffhXfh9wF/7lf/tbBPCln+xwomzQAVIWrBPb7CKn7T79HcsJnf34xfZeHn+dbh2fttN2mf6ZNmV6tUdOGlyfa/OXzh7RycGb5Zm2j7JhRnT5TcLD2gXKiboDe5tOZvvO4MxQD41bH/Xs3i06ejP7ZZMO3y8THbjV4DNwc0j/TJsO9VaD403Onmnbb+9WW72rrZ62hLz6Nv1UT+lN+T/PZttpc6t2uzLpc0TuPWjvtTPlpcukuHmx23DxBtGfBh7ETy2XW7svkuCS33h7k9jz8uaUyAdl8Jv0NzIgu3VfIlkEn+fsmbph+UQ4bUd0aRAftb+duAQxoUP4V+mQe4+k4myRiLwO1nvEILxLtil36Ijlm3SLpjBeJh/Ylli327vLZYyvkJ22e+QiEhn7cav3VToiMp3MtjLa++TDxsvES1+l/6FRcXOPbFFvE0drh/6FFRqeVTF+lf4FECt0ynKFTgCbmqKx8B5x2nSKD0hu9mJr94ikMCwXPNwv84akXR0QZWk07zJJ89gubRWSRtGOG8wTct5gQl+Ybhc8qdyqYNNgnhFH9AT4y22Me8QgNvK02dqekpQAPzy5S+jUtsutvopy2uB6h1zrXR311bIGm8DXiLHzYRl/ufWzSSdc3U53fhpPpgactLG/RtIBljibzjgh6bg63Vsk4LBAjJmDNu5ua6+haH8TIgxXifDV0LXebqlnxHCNPv26hhrF0q6O1FqDc5N+muVOw9s7JPJ6QEcvD0hK0DFJvT4iNDgrONMIkGdWOZtzbxFnOthfac/3SLqVfPghidgrG56joyvlkbsl77Y5/kzBtfJsjfCsuL1X/p6Ry1AgNCnOaLBU/hFnh/TTt79C5Ip3EijPTsmHz5UJ9WyqwQqNvRn9nbZ3iROnk6rjqTKvdKa8e0A+Sqpy1FhRMT8h3/49LPAdFDy7AaDsvQ/8bOvPtrt0NDVp/Z+0duLiIaGRO+Sc0x4JuEF/pw36u2Wb5Nzku+3nNslykF43SVobxFjU6d2jk63C5675DnG8p+3dCZEZY7IzdYek9p6QtbpL/9Id4ZqSVDFxMS515Omh03a/wf4CMWiU4+6QfpWzelPndbf8Lv26zit0el6a03gctTb36Xh9q8z3EfBzJCVZGaYBJr/sFDwanBKPl+no6IDsMOrUjVq7D4mDIP04r6+1+crLJ3T0qEM8IqnTymHX9S5Jg9VZVW9C9LhBPC9pklbUHTtE1y6TdPNZ+am8kp+WgX/iG+RWkb3283/+v+48j3+RTmh8Fb7e5nSfBEN2idOmbKuO/7yiXhBP4vyYbu11nsX/05y2D+lwbPBV3lsudWZkZ+wK/TNt1cZ6h2Q13Sd6c4k46JdLW20XBvOZkrTcRRKgH+LlfoN/1OYpTe/QP9O2S1KjTwi/ao9MG+zSro67vHbQ3msXTMndEyNyzktak8b26GcdLLSxDdLIa9VpU9+s0A9Q32l9HBH+u9vaqPMmhG8o78SLQSH15RE517lFn1Y+bPhdJQFE07inRKbUXfAD8qHzVTq5+gL9ok75SoPnfXLh30XlE+G0LZNt5Jsk7eyIfq6tEbCtVv8FsuV8k+Rhf0hu7lHILJJDt6aGjelkzGuE8DYaTKck4nNS+psQJjign56l4r5NvnmxTMdotwmjKWyrQnyVRAw3yI6fxOSuh9GdF4nTpMGjUK2K8ZWCow2yYyGc09b2FeIkS8ivEgdHQbFIjDsjSK/QT4eZNvggEUijn0bRr5BUAtcdkobkfG40OHYbHp+n2/l5lf5OmwLDdXiF+VGbGq2XpjTqpLU1OtqqtKBSftJg8qYwlXd1VGRkdzf2yHe+TAd0vackr/8WiWIvE6PKtXf9t4ig0zjfIDtOGlIvt3VQoFbjVyNhgdy8qtPhtv1iG+9Fstswav0+T38HRAW+Q6J+lees96DVEybhqgYeBT86nJBUNm+anZLAwmLDwUskxVd+3aWfMqXhPCGXCd0kt6lC6GWRGBE3mW9EjMiu2qiNq6FoyvErnE2PdPdvlQRv3D10p2jacPHCoO2Y3PgnbjXexKPjufPt7ZHSgfQNUdgrxKmR553PE6KolWfKlglxGNwh0plSnimbVJgvkAPkKt+lMoebnN3RnbU6N0nq2w3OXhLjjY8Tks6+3vp7lVw48YjcKHnc6r1Ctx67dLxxi76cVZ6dtDE+Q8cPa2Qn8jZxmDVUdNocQ0fFM5WvEGdkRHgXQsuzQdtdcg7J4JnzUY5DLgR0t3SPyH71nDw+oaOVF4kDqh48JOmop2W+wr5KaFNeOWG+07bYxnqV7Dqs0k9Vvz3oRx55vrW5RQxObQZhmRDj9DqRS7tE3r5EzuFpR9wiF4K8SmhIQ3adXGI0JjroRoPJM8fKMue+SnZY1gmPONflNvaInIU9IbLwhNxQpxyQDtVh8oE0uktu194nadE6FNcIrSyRLBgvjzQwOiVnUo/JURbxMwMe/1VY+qsd7Osfwi9daC9/Bg7/BVj99cAPwW/4rfAbvgp/5JvJHtKR+Sq5ffQ6Fzttq22uh2S30Xmbrr/Q1uU2T3falgmfQz+QZBF/6kydNsdTvh4Qm/GUZHOMSLrmemk7pR/0ndKtz0skhU+db5ByWE7p1m2xjX+DTlfv0k/XvEnsDp3kMbFHDGxCdtpse5sEG91pM/1fOpam5DVa3Vfp77SNyVmw1dLGckJnD4+JnlN/aNtqO9xr79XR8m51lJRXK6Wu/co/4qeWRWJPuWZrZEd7hY5utInEoXBqs1ymX3SybxOHX5l0UflEOG16/O4kSbRHZFflhG6SRs6NyKrgdIIkFC8c2SbG/Kw9e0AEGKWe25WQyMAxuVnwPjnYuUv/Q4xL5HCmY+wS4/Q+YTSjXUacp2SHYpfsWFFwoEFyTEccT+jf1Oj8jDQZ1TEVyt2EVXIOruLHQ/UaZZDb4A5INEynbUIYf7PBtDDANySyU9NSjonxIFyQdakCaYfsDuzR/yBs3WnbIrt7Ou61H2kMQjcnJMKtYJPJDujnoksfe4RGdNjEZ02P3CHGsQdyJyTa+kHD2XGZt5GbJbKzqdPmruMhZ2/o1JA1Iqah8iFxCOUR5/OYRMs0ENxpk94WSn2j2bt0Rsm8nbYdcg5L4XtMaLnutCn4pX/p17JJR6uPy7gaiB+WZwY+Ki687EN+3Sfnth7Tv+Ro2t5fa+13yLq61irg86K1rpUBA+db27vD5o4AJKAzIvJCJSdv7pGrrSnzVkaO23Np9LDAdUKM/lF5ppNwUurWnTZlnE6986nyQXl2Si5AmJBzVBq14uU+83fadoh8HTptW+TscZ2jay3frNLfaYPQlfi3Tx1TaV8aqDpA2SFfLxLahjjx6iro78ZqbOySC2p03HQM1WWUegaTHPe01dFJP2jvVkvbffqX/xhQHBNagezyHhLnW901I4EmcaaDZeBoQl/GLpd26q8RSTmd8HSnzf42Cd0Ks+2r3pQf9onDrsFX7QYDYzWzA2K4Kn+22jvX1jm63iNykcdjEsRRfzmedKcDIfy1uPsljg8IXSrP5XVhVI5vEnpbITrgtOHHYI16BpKNo95010N6GBFH1L6lCeWAO21b7ZlBE+XKAv1Ltv5psuN0GRifwis/383jDvD8j8P1H4c/8MeA3wr/xDfptsTuwOd2YPZX4E8T51tdeF7R0RNPjn2f/s2FPnua0yY91oDC0GmTlgxAD3fatLGkH3lil9DrSWkDuRhHOSFdye8Q/pnnSFZcbBL6XSLZMoelL0g2zg5JiV8tz2alnv0tEAdlv7w/KLDZdoXgU5ozzdC5PCx4OqBbo6HTVvWNz+TDVaKXHWOL8PMmZ3falE/Sxbi9k3/mFfW7eg5y+dgm2Wl7rvUnTtR9Bpsng371D9QVVSZdVD4RTtvHJH1mWv75TIHhc+stkY/66eRRnh2V+qeljn3av8+qIXNSxpFwdVKm5b3tKH1qXB4P2s4GfR+XvxX+FQ8M4D8p41dcQP/mSJ+JF5XrkwLLAn1cDvHu2NAfS6ewzuHJOX1S3lclV5X9ED7HrumRro9j284dsIp7ncqK74rHGX2DpK6nyrfiWNzW9RziTXobjjWkY9dwsYzhO3Fg5LWuQ6X9Sr8W28oPM87ykzi1Py/oqXOt6yduKx8cE/zrTFb4XINqQMtfdT1dm8prlX7FoXg6Gfyr9Ggf4sC0IOvV+Z3Sx/tx6ecbdKlR30MXTav0qVPoztGw2LdzGfLuyeD3IX8J17w1qbKu9mmdIW4rPk7p49i1EP+2ZdBWGOWnul7D+TDAo3A/Yf56zUp/S6XOYsFhxU91yE9L2yFuZ/SdtiEMx8yHZ8gntb/jOXXtu8oz+WGx1BvSzwlxJId8KT0+KfhnTh3rzXteaUD5cTLoS4etvqvrOm/dqv6q639a+pUe4SwuYX56ZF3Debg4oa+/7Fv4jsvf1dCdDp5VmqtO5Hl0MG/ew7mvDOo6t7pG8p9lKEuHumGo94e8Jg3V9TuPHxYGYwzlt/pqniyt9LsweF5p5XQwxrx+hrJAGuTfocsDnQI/DPwO4J8MbEul7UUG7HA8x6h2X+Vj18Fyyny9DdFFw/GHcqHKzyHt+dN5nQ7qCpN2T7VdhjjU2YGzAc4K+zw+nCc7an2dwErvFdZF+rQ3hK/id1ivzr/Oo9oaPrMPSl91HtoITwiNVLlb2zjecJe00vI8OSr9VLqwzZNz6nPOc8dZGrSl1J2ne4b1huUT4bRpQMjUo/K7DpBRRyOjEsCT9s4oln1Z/7DUHZGokErycFCvRmSrAoSkU9VIkMZrFbg1ilafyXS2V/gtkHxsHRyjunWu1Wg0Iq1gk3CroDkhkdpDumihv0PSM6YDvMoAB6WPOhedJ+duv4ulnnisOD6g78gahZiRNag4ER/CJtzipzoHB0RgzciZN8sx/V0I5+nOyyHZjbGMSn9HZM2OSGTbuVYDWTw676HDWtegRm2PCINLI+LBtV8ma+Y6V6WtAnBNdTaqAUeb90GpV9ejGiKH5BMJR6X+0CgZ8ppFXM2rpxBeKG1qVFyeGvJ8xWnFywFJrzoh/Frp5bD0625vxaXR+Kr8dSgqD9dSZYH17Eu4pX3Hpzyra+q/R4O24tr5qGgrbjXKxaN0IYzOrcJX5yBvOoa72q6375QJlfeUi/Vv12eFXKgxdBatBwlaOQdliHOXb1zrId9URVtxL28clvkIb911rTS1WPr2nXBVnaF8kh/Ez6TMzfWuxmjFn7LlMaE951pxKhxDXVINJuH3DK3tpZUpfcMf8h3IIb2OiBNQxxLfNdgm7NJUNTJn5Vn9vcoT5W6FQb1gP4/LO8iusLiqsBwP+lGWn9Cnzbq2ymLxNiM6UrggcqPiRvxVvTx02pyDeqvCUWlZHSM/ilNhMiAtfuSpSgvSQNXvzlN9VWW7tGaGjv1WHa2Oc92fo2+TVRgO6dOcvHzgf1t0h47u0d02+Xvgl3wZTv6FPs1WfTwsdbxK+weDd0MddF6puqA6EXUda3BwmfCQ+JMe63yPyt/S6jx70L8r7R6WtgvkHPhQD0k/jwlvHRA5IMzqwirrh5sJlXaVq1WuPCl/n5R+qx1ex5Xm6pwr/asXqg1XcbVA7GFxY8ZCXSt1r/BUvWmpPsU8O3serSgPHs95Vm1k8Vhtusr3w1JlbbXFHs2pW8snwmlbpH8JxEp556K75aoAHpU2/r5K0o1GJN1Egf1c66NemzoiF4Esl7q2e648d6v1hKTCCcNie269A/owmmrA4LlwOO/n2j/Hqow6KvXWiGC0H43GaiSskHMntl2dg58VssVtP+JT3CsQdG4q3tfIOtqfOHcsGXC5zOExSb+rOKG0r3DWta3CS2W4UN7XfqZkbU0xWSR58XVNKo6hT3Pi1H/DthChWWlrStaqrsUSobG6Nv4TX6ulzaj0r9AatZ/SpfN0Ds7L+WiED9fP8W1T39e1XaWPHx2SShfQp2XpaEqfpoXdOtBPfXDOwrtSnon3pcHzRfr8Kr34t46Y81S42scCuQK/jjnPiJgQWlTGQD/oI1z7Za51DhP6617xXXFdZVylwRn9793pEA9ln3xIaQsd/yyU+if08apcqTy0XMb1vTC5jhV+o82u/5DWDRQI/zw6G5W2zxH+sb38IF87h8rDq2RtfF7lT9UFlaY04iofSp/DZ2sFXzU9stKZ85LOKj6E46TUr7AOcTKURWsFnjreYqlH+d05+LfyxqCC9LhUftZo/yp9PFback10yqF/hrOu8WOC+6HeXCVR9rqWFXbor4XjV9mqLK71nGedQ9X5p6U/dSL0ZVcdQ+fGd/LWULfoFFU5s0zkuLS8Sn9dpF15U1impc0aoXV5tNpH82SN83Qu4kneXSKyYVT6FUdD+2xIUwC/8+fh4Oe782tX/xJc+Utw8GPwTwI/9fEK/AdH8MfoHxikG/jf/+NdVgQkUCCetFm0o4Z8bD3LbPD3UI9rUw0DEFUurA7ar9KXGZWnZ8ynAds6Vs0eGg3eVZuAQft5+FbuWsdxp8TZqPJLuVhpaoE+rVQa0u6Vbmu9VWIrC0/F52HBd8WV5XjQ36z0ZaqmfbpmlXerXIGzdlzl7zrHKrtqn7W/Q8KLzxEeq/ge2nsVFnGrLqv24rDesHwinLZlchGJBzSNlIiwU3LodZscLHYhbpJLOryI5BUibBboH/B/RK4mvt3G2yffWJrRv4hklf7FBsKnc2De/yq5BEPlsNLaLpe+V+grRC93uE//IpID+heRrJPD/mvkOyw6WkZQaG1eJcS+0dp4u9ZtIuRfbb/vE+PEA90amgqUkwL3mP6hZVr766TcLHWM5on7ldbfzVZ3p8yHBvMr9A91+qwqzFGBc0QuKrFMSV65sB6Ti0iOCK05r43WVuG+22DdaP+ukwhJNRJc91ttXvtkt0F6eJlc+T9t726S752oHDU8Pbx+jdw6+hxRlBtESNjnLXIFdRVQM3KGYokcsNWR2irjrpOrtRWytwqOan/SowIbcqhdg3qbnDcYkTxw36sspD2j17S/x3Rra3TtChHirss+/bV9SCdXhpHfCf3U6Flbgw3657HWyEUkVYFbRuQ7bcqJU3LeQnpUmCuTbhJBvVR+ijOjeF70Y9sTclj/dsHdjH5EV/qh4EYZIM3YVoW92saVNpQhEB6akkPlzn9S8LRRcLtE5Jmwy8tXyLkRaV5lDrmIpM59RkenN0l09QahAcurrZ8J/YtIrjR87pCzHGP6Fzo4t93Wt/U1/F4il7McFZyukQirMgtiqMibB+QiA8gZ2VttDHnDa+Gdj5Hj2laZZFBit8xHOU6buzhR102JXhQv04aTG3R8f9LqXCF8c5U47HW+Gn5jckEXpQ9lbnWA9smFSbTnXt4j7Vn3mPDIWsPBy5y9iET55G71CdGXK+QCHHl9l9wifbP1ud3GfYXcmqejtk4i7WPCY15OtUX/4hLXf4VctHaN7MZWQ/JW+32L7GSoKzSOLxc8VrpVhwnLbUJLt8g5/WvEOLxKaGXU+rrc6o8L7FP66ZEnRE5NyG6BNLpe3k/bXJ6n/0kQdch66/t9gB8+gv8j8B/+Fvj//mgOm9IN+tofD11rXKvvDsq8dYQXyzPoy+6h07ZEvs+3yPlX/l8DPku+/UfDQbWxDogtOKMfOFpv9eThPWIzUOYzIZeeCbv0Py94OGvjQefQ3iD2h/jYILJTu8V1WCGZA9qQ68ShUY7vtbldK3BuEH1+jVwg5Nm368QOEKdrJCNKe3Ros90n8kz60+Z9teDj/dbmJgnkVb0pftTr1q12trLcTyxY3Gm8Rf8ikkUif7yFUzl5UOBca7BcoV82G6zaxtttjBtcXD4RTptG6YR8j0oBAHFGXqKbnAb/ZUJA1wnDyEwS7CM6xF9rz7xO/XJ5tkUnUGQklfw6uSr6BrlYRKH+Av0ta+ud0r/G9gZhSoWnRvyYfEdGgS6jHtAttk7bVfLBYugbrRqfbjE/1/o5oSMkx7jfYPKjsdP2+xE5zzMj394wWqdgcZxxgeUKcVx3Cx514DR4VUQ6AxrqN8h3uMQl5AOI98qYVzlrqB3TXe7hGrzEWQFQGc6I/wYx7NfIml6h/522gzbWHvlApW136e8Qa8hcL7ALp/VuEKfN62N1BEfkQPsi3Tq+SD5uuU5/10N8jsjO9GEZ32jQuMynRp03Wv8Kp8v0nTbp8UFru0E+PF/7c33GBRfyl/Usl4mx4njVaZP2VCCHdHz2Al1g5ZBuLaT/JUJn91qbz5KPeN9o9fboB4QOyEVHtLndIKlDhw2+5+nzcC0VZyuEN5eIQS4fOh+dJp3pahRdJTJpj3xfEWJgKgMrblXOlL40cKRZ+XDG2VuydNomhBaWCR8oHw6Jcqw7cIvkI87i9pjQz0mpq9Om4jdiqgIXP5fp05kBiJfI1dLXyG61hpgf/b3f/l4mzslG6W+pjXGDXMNtAETj6gaRZ9DxirrlkOidMblM6LMkjVNeWiIR1RvkxsQlcmPjKvmEyAbhK8fbG7SVppVdkNvpdojccg00Tu6TTI1r5IO4h+3d9Vbfna3L5Jupypp6BEEcaPTL3xA6qjpq1NpuEgcROnqRZ9Rf9qOxdUocDnXaCUlt0k7YJEEZ9aaG/mUiL94jPKHMXCd6W56YtPGvkWDLmMgEbZD10h/EUNXRvN7+vUBfHlSZIP6OiX41ILZOPllzg6Tj6tvU9ZZOrjd8TsjtkYul3g5J/VPnet27+qzKlD1CM3tEjpoWd5U+TW21OYzbeDqf4mPW6nMN+Angqz8K/+xvhL/7Bhz/HzvlfrfrTzrQCD8kwedq4wmvcNSgzryirF8pz+Rdi3C6hjpt0v4NsnGgLTihT/fi92ppq4EvHM5HmoLseipLapkQ52mR2BM3Cf0e0+nOl0gAZkZoSjtvk36AYpEEPl4iNzVeJTahNDUr9Xx3SNZA2861uE904Dyb7Qr5iLvP3iMbPWtEPkEnm6su9znk0iz7uVr6ndDZN8qEWrTxNsia0eZ1g2wC6JtM6fhgvTxXLtRyjdi+VSb99+L2yE/Lp+XT8mn5tHxaPi2flk/Lp4UT4D/4d7uth7/7N8Lf9dfh77rL6t95H/7G327gnu4Aflo+Lf9dlU+dtk/Lp+XT8mn5tHxaPi2flk/L37ZyH/gvfywZTpf8+Bf/LrxB9yHN/wx+xRT4N+BX3AHuweyo2x363/0thHV4wcWn5dPyt6p86rR9Wj4tn5ZPy6fl0/Jp+bR8Wv62lV3gj5KjLxsflXS592H0H8B3vwL8A8/Dn/iD8Dd+E/yLsHgIn/06LLz7twfuT8un5W9l+UQ4bUfAu3TREtpPc24n5OO4X6HLL73bnj9Pl6Nq3uwmXV7tHXKzzHvkYoWH7ecv0OUc75MzEj6zfNTejVv7FeCn2jj7DQYPcpqv72HPr9Dll98jN8v9FMlZvkcnoLy8wPMIK2Vulmmrv0TO8JiDvNPm53kS86bN6V1qsMzIF9fX6L5nudrqvVeeTxvubP8VcvZgi3wA8pSco3hIDoYv0qWe3ycf9X3Y+ntEzs/V83CekxJf9+lfAT9t7d8l5xc9p1jPvj1ouFskOdL1sO4x8E77fZWcN/xqG+Mu/VuO1sgHHWd0tLXf8OB5Rc+F3CXns4TZCwK2G74n5FIN4atrcJ/u0zWXG9yb5DzOUuvnCt2B2zvkgLnnwLx1bZecP/xa68NxV8t8PIOwTXduxTNZW20Mb2TaJR8hdlzz4O0PurURJ/V8zS79slPqiQvPM0EimH4g95COFz2f49khz6WOCR3stLrfpH9uZo/ICc+QTMl5HNeUhjM/Qjxp756n480dzl5CQqtzj9DeV8nlLMoA+fBDwl/KnhH5gOdee/48nUzaam2fb23eI+clxvSvSH6P/jXV8v0COYD9ITkzVOXdA3Le7JDwqzIEIh+m9OXZFjlTsUbOmnku0/M3yibPGa7R8eQOkWGLREZ4/tO5z4gs3GmwbJHzjjVlybOLdxpcXm4xJjThGcC1NkYL3POzra87dHy12+D0UL1nE8X3NtE3ys9F8uFoz3Ask0sZIAfT9+jWwvNu7xKePyBnjTyjd1DaThrMnnVxjs79Qav3sPRzVGBfbPN7nlxOIs42yU2Bz7c298gHiCHnncYNB9sNFs96Q75BtUj/9sgPWn9fJec9HtDJnwmhvaHeVA/sksu/PEs4bc9W6OTAlMhr5dJe62uttXuXyMOfI7SlDDugowP5RVk0JXoPItfu0L+4xPUfNXxt0q3fYzq6VCbu09HeErEvZsBfbuN41nHccOfZPs/83m1z8xzaCdE9zmOLyJ1JG1t6kEb8SLdz2ySf4vEyoS1y1l9eP2pzetjGeIHQxx1yWc+D1vb91naHfNjYs9fq36rDl4Dv/v3A1x7Dtd8EXwb+0P8Afstfg7tdf877FwpOF8u/i8om/Y+5ex612iPaMlM6nakOfExH+w8ID3uJ231yZnBELuO6Utp6kYZniT2nqHwRhhF9u8fyAR19jlrddxuc20QWSmcfkavzvUCj2iPvEH04bv2Jy0eEppQXB+Tj0tq1j8iZbOnhtMxDfe35tOc4eyvmcXtfbY1jIh+nBR93S7udNt7PEN0BHf7vkA9+j+h/xuVOg3WbftkkMnZcxlDmKIvUVcd0+NYe9ZKvMf2iTvlKa3+PjqY+4uLyiXDa/iY5zKpiVLk8JgJQ41HnSMIeEaJYIcTu4nkRCeXZQftb4vEAreMfljYaego4YVCoytgKKJljQgxmnRvaXCfkCn2VirDXCwxkiqEjU/Hh95Q01KrTZj8KL43Rip8JMfYnpb2HY3VUheOE/jeUdskV+rsNl8I6IQ6eYwjjSXsmM+8VnNT2OwWXGhHeGlQVpms6oo9vCK1UnB4P5q1SVflbNMCFYY/cBnVU2jreEyLUlko7aeGECMsTglsdvaUy3mLp1/W1v2qgK6wnrQ/npoM2z2nTUNklhpVrCcHtIt367ZX6h/SdNucrr47KO2lQPFpPwXvCWafN9Twq43pweofIC+FbIjwiDuTXSamjUtd4lhY0sHQypYlHxCiapywpsCyWcWet7YT+2u7TvxJYutkrdatMekRuq4U+jsUFBLfT8ne9QGdC6GjoSNuvSvCQ0MciMaiOCW4rf7lWj9uYyhlvIlsuOJEPdWCUz8ownTb7XSlzd45Lrb248Fldm1WyhvKKMnKV/q2SMzpjy3XUWZ0QZ6zqjH0iO3V8vHjF9XX9JgUu6X1K6MH+lJEa087HMR8S2V3bOo9pa/OI3Fy6R1/3PSzj+62maowauHN8n+sEiAN56ZTwr0aQtDod9OHaVt1U5V7lvwnz9WZ9J1wjYhw7t9WCR502jeFR6UOd6N/CYh3pVjtkQsohcWTErzixr6HTJp7kA3lEPOjw+P2zqufVwc8ROUKDT3lW5ZA0OiEyRPrRgZwQWaO+Ua7Idxrs1baY0ZdTrreOmzRb4ZsUOKXrx+SmRmXHqNQ7pa/DlyDXCd6hu7Bk76/BHwG+DOu/vn/ZmeW44HrG+aXqJejbXfLJjMhr8QBZH2lyQmhR2c5gXsKoTVF58Zg+jQrHEvP1kLyhbJ8Q3SIsk9LWMfbo60GdUvGkfWvbNSJzFguc6jLpUntPG2OBBD2di7aibefZbFWe+cyxd0jA13XQuZSXj9Jdz4573OZuv/KG+K3FeezQ100TYscZCNG+sD/12W5pa5kUOHfL7/NsjFo+EU7bx5z9gKFEc97zWXn3LPVPB39Dv68hM88GP4d9+M/xFghDD2FYKr9XGDVw5sEwb/x5c58Hm3UW5rw7Lf+G9YfldPBzCMuw3/PKPNyfcnZM4VocwDUcY/iz9lfxWSPvQ9zPW3vbDOH171Pmr0HFaS1DfHNOvVpfGC6i0+G8K+x13GHdeWs8r8+Kx+Fchjjhgr8rPBfBUNvU3+fNcx7sQ3qpuJ7NqTfkheEc6vvzcDkP7tp2Hqz1Zx2r0twQhlp33hjPgtt5cutZ2g75aR7vzGszD2fz8HcRLQz7qfNYGDwb9rc4aM85dZ8m++bha568noeb4fwX6dPlPPk3j1aHfc5rex69D9/Po6t548+Tr8/ybjjus9JJrTPki3lyfDifIT7mrf3w3Ty4hnge1p9X76I1nFe/trtovYb8DmfnetF6DN8Px38aTczD6UXvhvMZwjGsy+DZefbZcO3/qY/41lbELi0Q8UX4IeDP/DydZf114C+QFIAbwCvwJ/5klyFwXql0ZznPHjnPRhj2NcTbeTiscmIe7VY78yKjfjZ4b1/z7L55dslF9DBvfefR3ZBGh+Ui+2eezTYccyiH540zTy4M681bg3ltKszPwnvz5Os8uh/2OQ/GeeUT4bSt0p0zXQFep7tW04iNXugM+B7yTYsX6bbf3yffU7lGtuvX6HbPxyTNbB34Irka+kob68sk1ezVAtN6+3ev9CdMRu3XiHe+39p9mW5L1cjjCvClMsa7JCXI6MXb5NsyG60+5Dr6JXLl/7j9bkqTkWe/3aJHv9RwNiPffxuT70l9nqSafQ/5hprthXnS2m+RKM0eSdF6m6SpvUM+wUBr8yrwWvv9SYNT3Ho1782GFyO0MuUt4LtIZOV5umtrb5NPLUBSGZ2ba2oxakl7bwTwbbJrNCJX/q+R72Wc0NHADt1a3qK7lvVFQmu2daztBuPLJM1wQna83m7jGI2bAW/RresSHV0bRRqRa7nlDelH4bFBUqqMOL/VYHTccYNvRlIEtuh4br2NdZ9EGJfa8xfp+HOt9f8mZ7/TttveGbF3F06eUxlt0dHzccHZmL7jAh3trZJrwT8k39T6HpIW7NXYy+S6XGn0yyT6+FKrMyn4mbT+V8rYb9H/Ttv9tk6rdOs+T2neIzvNKw0+yBrttWfSkfzlFe8r5HNEO3RrLf0qO8T1mOD+Mt1aiNsr9K/8F9/QXUH/mTY3n23QX5cnZLd/v8GzRGSRO53T9qzy3j5JzbtOJ8cOWx8bDa91B3i54XWpje0aLpU5vEX/O20nZL29ylp+rDJjkXznru6krLf2r5Lr6w9a/18m13e/XfByq/VVdzdu08mzMfm0x/OETqatjx269TZ1U51xQCd7r7X+TA2/Ta4bXyK8O6Nb50mD/5XSdpeknZkeLV2skZS+9YZPd43ckVgmn494pb1fpKPNDXJdv5/4UA/V3Qjnu9LGG7c+h7t17jQ6P1Oa3iL64j6JXC/Rl+PfJOv2fGtzi6TSudvjs7qTf73BpU6G7l6Ll4g83Gt4e5UcfXiLROefL7h83HA1JobmjTaOO8jKMncXlCFeh++O3BZxQN5q47prpY5SJ8n7Yzpe+jLZ7XiO0OgtOhqj9S39vE8+K7NHt5Zvtv6U39LYuMH+Hv30ZnGzTicHzFJ6TNLi5LU36OSKcn6NfL5il04mXWtjzxqOLhM5UnX4sGzSrbs0y28CfhfwL//j8Cv/aJd3+xNtMm/Dl/9k2lbDWLlxl9hTi2T3q8qWE7r1U2cqMyYNlhv0PzD/Ckl5m5HvtPlNP8g3TqUTdy4ndOu4Qf9bf9XusbxDR5/KriU6PN8kO05b9L/TdkRnQ4pzZZf2MeTYhHL8NSJnvPL/Ed06rrYxrtGt+z1iY1yjo0d3LRdIGqJ2wBfpZ++4+zemo3Po79S/XvCx155/jhxleZv+lf/SlzB9F50MgGTv3aD/XTzI8Ze3SRr3Vpvf5+jWzl2/ywXuU3L86XXOXvk/peP5LzVcHDZ4bgJ/mPPLJ8Jp+xt0Z0mqEtWwUrDNgP+I5OqbO79D0gDH5HzaiJxXMb3nBZLP7rmQTXJWQIMVuoV9QM5t6WCpdDfJGRBzcR+XvyUMt45XSUrdFklZUJhrvL/Txp00OKZtvgutnXO8TEeY79H/Bg7lp4aC87nS2t5rP3caHvZIrvq9QXvTI3fIVv2MGLtuCfv9my26tdlsfSicN+mfbVEBqdw8n+J5Khlmr419t+B3q8FdhekOcdxGRPhaTtoYM/Kha9ODpuTMk2ulcKW18XzJDhHQ4zltHWvS5v1eg/2ApNgttzqmR262+awSw8j8eIWcSntMcsod75SkHkzofw/rMvPTI2tQRN6hwEzrb0wc9vsk1WM06O+AGAWeDYSkVUo3GkD36eO7RjMhqUw6T3uEzo7pePIBnaJaIh8AvtzwPSOGz4RuLeXfYzpDQhmzQ6Je4qyuofRwl/lO22W6SO+fp1ubyiPKgL9AUiflr/tErpjW8ZhOwU+JI1dxvUlkn050dbw0inVCNeLk/8vl2WX663JCt3bSxoR+atAxMWyUOfZ9QNZnTFKU9olRKu8bFFhtc9wlclN+hBiHlc4MHN2lO8dhUK/CI26nxKF+Qs7ubpO0MQM2U3JO0jVRz9wj55Sgo8XNgu8rRBbeJ7QzIeeAIYE1aXLcnk/ImWOdGQM3h62O6ZHbRA/UtuLvoM1nu+AWOvmxT2j+PknTHZO1UAdsET7QWPyQjuc+IrpMI/6UfpDSgBPEeDGYAjHaNtvfV9rPnTa2qXnqTVrdR0QPbBIe2iXndDzboy6btWem1KvvT+nkwh2SErzY8P4OCcQqR3YaHGtEfqj3IA7rL5AAB8RINd1yTFJRdfAmRKcu0ckRYfd8r8ENzw6ekpQ/5/24jSlfSLfyp/hVFr5AaGVCDNstsoY6c5DAsPM4Ifyl06wTslba6oyvEl3+XunHsZV16rqhc1KLuksYuAP8S8Af/aOJ+PxQq/RnO/vxp1vbujYWeV1alR6qzJ/R8cAuscUg53c18D+gW29l+F7Dm0H6e4SH1RPyi/rbPrVDqgM5xMsW/fQ9dbbrL50py07o1nKf0JR20z2iD9caXPt0/LbZ3munC6c0NSFnRbXnd+loc7fgE2IvaAdop1hO6PjAIAYNrjvERhq1Pr/Z3j8iNoryw+LmxQHRd/oGhw3G++TbdBZl7glx0uUvfYMJuatAnGgvrJLvANfyjQbLn2/t77Rx73BxeWan7dKlS4t0G88PPv744x+6dOnSLwf+PTp5+18Av/Hjjz8+vnTp0nPAHwP+R3T4+5GPP/5486K+fwmJMr5KPuDqeZZdusV6m0TKr9MhQWK7SefNu8CrdNHtdwiy1oHvJow2bs++h+xafLa902s2ArHSxj8gZ5oOSYRzgY5grKeAlSnc4YNc6LBJjNYvkHzhDRIBkHEXSYRujUSndE6W6EfDFIBvNdxtFZxJSEbYthrM1ViitR21eW2SA7EaYwpWd+wW6QTxCv0o8i269X1AlNmVNpctOuFxg36ky3KTLkoBiSobYZVhIcp/scy7RummZPdBR/ykwX5EBNcSUaovtrYzcgB/RLd79iLZ9Vrj7E7bDl2U7QaJ2j1qdZ5r8Mng0ueb5MO1HxCDYInsTF4jOdLS06zhREGmMfBmez5p754v9SfEoL5NBNUHxGBaLGPKnw/pom1rg/72idJ4nuwYrBNanpFD59LnMqFJiLJ4i+y0bRHnZ6290wgYE/p/kewenRB5sU+itpOCHw0Zed81MFpu4GWNfIxenNciXalc3yK7j47pTpPOBORjoiNyQYhK+nvKu7cIroVljU42fa7AcKf0rRwwmunO8Ab9j6RbdEDq2awdOrx+kezA+7NmLGyS81vypw7RThv3TWLw7RI+04jRUVokCvpNOqOy0tmdVneDjo8+anOrAZxFOrlxSOTyIYng36J/jmCNZDosNHwvNliNVp+SaO4tOpn0DtFFrokO4FskKCYvLRG6+xyhl106+fIKMTJGdPLF8yVvtN/vtfFtu0cnN40477Z5vt6ebbV6621MDesFco7wSsPzq+XdRpuXTtuYGKkGQAz+TOnkqMa+tKnDfzz4nQbrvfbsC0RfbJJzQEO9OSbBQ3XMzTLPJ+TD72sF3yckQ0UH75Qu0i4P7LV+32jtzQRwh0o6oc3tqI31PFnfDWK7TIizCnF8P0tkubt1BjX2Gy50qIT9Cw12bZkxCUzJmwfE3lig0ztvtrF327wmBW8jstP2OnGwZoRHxGF1fnUopANlrE6v8toA0eskAKcj9xI5y3q1wbDT5qFMH7d38+StZYt8QP0WrePX28R/rg38OvA/A/7eN/mnLn2jd3HTsHxA1h3OnimHOPqvkA9SW3eLjgZWiKN9i1z2ps67Qv9jyxMiexZJYPERHS1eJ86OcnKIl/daH+5mjeh2vz5Lzjpuk4/HqwMNZNUsAW1JCB8rx2+TYMY6CVCpXx+257fp1ma3jbFOR4PK6UVySdJyw9kX6Ntsx3Q88jzJXjlueFxqYxhYmLT3t4mTLN9YDEjo7L9G9OdjkiF2g365R7eenyfBpQd0sl27aJcE3ZWxszK326WtxQDH260/bbYN4Mc5v3w7O22/Dfj/ER36rwK//+OPP/73Ll269G8B/yTwo+3nf/Xxxx+/fOnSpf9pq/cjF3X8HPmCukSqAFAZHdMxyj6dd75BtiJlDlMg7tIR4msk4rtAjE8XbZ0Q4l575tboMUlJe0K2OHUi9xt8l8l2tU7FbTriM3KwWp7RYH6OMMiYpCO8Q0c0r7W6B3Se8hL5IvuYbMPrHOpMzciNOM+1cY3w3Gxt9frFD218o9E6OK+SVBWLilC4rxCCXCCKvBqEN9tYK8RpW6dbr+cafLca/EZsFlu9G61/Dcgxkc3OW7h2WrvVNt7QadsiSmm5PbtNn9ZWSSrQzdZWR2Kn4etGe7dBdtB07CFOzy2SimVwQeX1SsOZRtxue6bwM01iseFIJ/FFOgGtYJ4RA9z5arzoNO6SW7mcj0brAkm30vm5T5TVNZIW8bjh7dWCo9qf9DguuHiR0PIpMWwfkB2sMTECxbUCeVLePWrj3i541sldoqOLz5K04dtkJ+ImMQY1uCbkJjCVlDg7JA7PZTqh9wrzI7936aK4y3Trd7vB+5AYU7cJX8mntwjdLNGt0VLr4zWSCv4qSfM4bM8uE+W40PB2Qj898oQYjjeIA+La3CD8I2+ukdRndwcqvk3jUJ4pW9xRHxOj7LC9u9Hmo8H3gBgvu61vla8ZCxCZ6NxPiAFo+uNJ698LDWg/XyN8pfN/tY35Cv1LPzQuVaKvkgCIQaPNNgZ066bsPGrzHZMdA+XKuMAjH7vLJq/Txjlu466R24pfJDsQt0l2QG3r5SLOZ4WOLuRX1/9awckB2bmTxy+3MQ4bzm7R8b26szoj14nRqPyTX0d0PLpe6ui0qTsgsmunzUd94SUcS4RvhnpTPXCd0MiI7BDfJhchHLU5fIbsiPruFt36bpV+b7X294nedidsSgJZzntMDGp1wj2S8k55v0bsm+v0L74YkbTeUetD411dcUhujlZmvU5/Z1dcqXO1DwxUTBuMBhmUNYfEqb5W8Kq8c7wTcrFHtZ3cAXUH4xodv0lTe20OY7qg5y7d7sgNEnA0gLlOu/Kfvg4fFuXYQYPv//A+vPk+fOlPdjfyfQQ8+HPwA78HfsUv/waXnsA/t/wr4Q/8dP+2FIXgu3SH3hx0j28R7h/6692rWZu39qaO/D59G8ug9m1C/zptBhvk4V2Cf4NW2rU3Scq/jr/6rpYZkTsGiaVlbwNVFr9C0iPlBx3QKf2LgdaDgm/R1A4JnCl7TPVfIjp/qeDnOh2t1gDWGtmpEleuKa3vd+lo4TU6WXZMR9PaIQYW3Gm71cbQ9r1c+jtlPo9AbIGbpY9aDtt4V9vfa60/Zc02kb1TkiZsUNrAeC3vEf26RucEvtzGv6g8k9N26dKlzwB/H/B/Bn77pUuXLgHfC/yGVuX/SZdN/KPAD7ffocso/kOXLl269PHHH3/8LGNdVCTcIULr+6c9m9f2vP6eBZ7vpO5F4z1Ln4uDn0+rezp4Nm/8eX3VtICFp9S9qNRoo47dRfWG4zzLeAvn/D4sF/X17c7rOynfzpzmlXk4Gq7vd1L+Vsz9vPG+k/U6Tw7Mo9NFzu/norG/Hbkw7P9ZZNGz0sJFvPc0GM/j9dmcd5VPn1YWz/ldmfHfRMYJX4XpvHZDOM6TLd/O+PPqXjT2d6J3zpO3834O6z8r/BfxzrPWPe+dgYLhs2H94bO6Rk/D37ej57/T8jQenIf3b5cHzysLPLve+nb7fdrvT2s3D/9DeOe1nWcvPMt4te23WxboDGVT09eAn6cLDhl446/Cr/jdwG/+afhtPw/8X+A//lN9gbFE36ovTtsL/8nT4bhIz8yrO/z9aTS4cEGdee0vkjH/XZVnkf3fiS5+lvd1jO+kzJO7z1L/Ox33vy0b8LzybwC/g8jpK8Dk448//pvt749INtmLtKyM9v4RZ3cGuXTp0m++dOnS1y9duvT1w+HLc8qMfjR+3vtaTs95NizP2p9/n5a/T8+pe1FfF7W5qJ9Z+Vn/nVfmzb+Of964dZ7DOZ8H49PgsK95MM0brz6ft+bDuZ+e8/t5cH47c3gWQ9Bxn+ZAnTf+s9LPPDw8S7unlXlwDce6CMdPW/+L4LqIJ8+j8fPkwLx25/FKpcshTOfBdV6Zt57nrfF5P+fBNoTjIhifhdfn8XTlzWft57z6w76etvbn9T3v3dNk6NNo6lnHn1f3It1ykSypeHjWtRquy7D+efA/K08+C60+rZ+n8d55z86T7/PGfFa9fB4cz6Lrn4bfoQyZN/7TdM958A5p4lnlzXl6/WnwPK3/oewcrt1F+u3bqVvbXETXTyvn6cR5/HMKnUP2DeA//i7gP4NfdQ/+vuW+dfrtAjFo+jRemjfM0/jgPPvovD6fplfqz+Hzi8qz8tN5NPc0/DwrfT6tXCQ7nqX/72Sez7ruwz7m/f608lSn7dKlSz8E/OLHH3/8X3ybMF1YPv744x/7+OOPP//xxx9/fvXp1YFvf6dtXmTi29lpOy9yMdw5mlf3or4uavMskZTFwb/zynmRmafttM2L7Hw7Ee9549UI/EV4PS8CNS+qcd5uzbNE+Z8laj/v94vKRZHIp43/rPTz7UZ3vt3I30U7YBfh+GnrfxFcF/HkeTT+tJ222u48Xql0OYTpPLjOK/PW82k7axfRYqWlZ91pexZen8fTw92xZ+nnvPrDvp5lV/8iWjpvfvPGfhpNPev48+qep1vOk7HzcPysazVcl2H98+B/Vp58Flqt/T2rDpm32zJvp20Ix3/bO20X0d6zZHOcB+OzyIlnzWKx7ney0/a0HZf/pjttQztr3npe1PZpdWub70TPDuufp6fOyDr/mAF/bhv+3C3gH4Hv/re66wlvfAdADOB5mk1W6w5/P48PzrOPzuvzaXql/hw+v6g8Kz+dR3NPw89/mztt38mO4rcrN+bN7dsp3yntP0t65N8L/P2XLl361XQbx88DfwAYX7p06e9ou2mfIecKH9Clu3506dKlv4Nc2nhuMU91l+7sgAf5vDnOHNu75EauRZKbby6/ecDml95p/XnW6YTcUrhPokF36PJJ98nBbQ8rm+N7SJeDOiGH9D0b4xmsSYPpLrlFca88Mw/5fpnXUuvDHHpvg/M6ZM8YSCBTcl5ki5z18tyfMENuvJuRq/WfJzdD3W3Pt9vvHky1/V1yDsiLEsTjHrkx6h65LEV8W3bIeQv7Ngf/oNU3giRear72SsP7R/Q/luj5MIl9k9zUJr6HZ9o8DLxGbp3y7EA9YzXh7IeKN8maSSOu/1ZpS3v2kNxmKb05Z88srJGzdrvkZqMRuXVqgdw2eUgOFJtXDjlXtET/A7r3Cb2YN+589unWcJsuB/+g4dI1UAi5NmuEBu6TA+O1v21ybsJAjPy12OoJ+y7JzZ+W90acpL3DNq7nw6Z0Z1p99qTMfUbORcrrj8nNcq6tdDshl2UYNRNnXoK0Tc47wvwzbfcJb6yQ27d2yXmCu0TOeabN+qOC24f0ZdLD1lZcb5ILX/7/1P1/kKVZmteHfTovN+uSl1t1lRVJZVRNURXVU3RTnqJ7i25mt5nxaCZmtjXDovVKlgGDZAOWw2BskATIa7NhGRPgCGkDgZD5DeGV7AUDwqvALAvrXQ07mt1Wt3unt0e5VWRPkkV2pbKUZPJWXTK5lZeb4z/O8+3v8558b/Zg+Y/yG3Hj3vu+58dznvP8Ps8577MKt9u0X0Q9w6dj5X1Bu+l3nhftF5vE2PWqkQep/KP41slY4NcxHOJ9Zk3V1xrtE8u0D24Hv1BYBzppDKJFjX0WfWlvmeSfZMES3sMlubobsGgvrfZxPI62n8a9+/iEs82o/yj6WsI8TOB5BeNbe3FG+EAXHTa1g3lJtD6JPppob4/2gTcf4pcoq4x0n2SN7quPi3hf9TF+lYtk8SzakF6V/tJeIh3II5z1sKxeoixGCD9EvVO8/0b7uLbxqx/EK7M0ftH+AJ/+uYm3GG3jw0akvwbpmWTwJNrpx9i3Md/m0xb1ipk5PghqH8ux0xiv5OFWwLobZe/jQ3Yy30j2a/+yLu37bDCPg+2VAaaBBuse0eNmlNlLsIsPNPfaL3OK5Yr0wkH0NcAHfUm3NFgeDPH+szGmFe1bk76QTtC8iYdFB8KPdNMkPdMeWcmBSfyf07bjZtH3PODSvk/R5KJrB/ObcLpN2cck2SC8bQD/4gbeSKbrwV+Ctb8E//qvhs//QmngLTyJQbiaH+mnS2k8YN48oW1jSbbng0imqU6uKzmh8TQUOaM+tfdRZyjkaxuffin61Z5S8YsMdNmImhedWzAM+Hcx32tfvfSb+EqyUPu3ehS+kx4ZYrrV3GoPl5xP2QJ9bI/WNpt0nezYGT5lVzJX8AkPgm+TsweRiB/2KfNyOZ5NME9lvq1x28Q90d4Yn2I/wgeRyDdZwge9HNK+MpyynSSTzrs+1mn79re//YPADwK88MIL/yLw+7797W//lhdeeOGvAv9DygmS/xPgx6LKfx7/fzae/9TH7Wc7xu8um1KQWRv3c+DrFOGwSRFOQpZSkVexoJVBv00beTOsoEeYEbdon+ymiR3R3iypzc4SFjI8e/goYp0ms4M3Gn+V9tHFmtS8CVnG/EGCQwpxCRswMpg14WIEEdws6oqw5wmeFcwcEnJylIQb1dchMHIcRXRz2gd3nHL2yH8JbhkRUoo6olgELvxv46OHs0CSMshH/meHV8wlJUzCZ25HRjwU4aJN/UPsOMn4H+J3Z2m8Ujqi0V18EI6OmM6bthtMJ11H/mveZzH2Dym6YowPQXiEBfkjfKrlBmeP/D/AhrAU71v4pLMlFh/5L+Uj4adx9/CrLw6x4hfd5/ZkhMiolvCVka9ycl41z8K3nId8ScE9pn3kv/Czhzc/L2H6eZDa0jj1ight7pehKsUgQSmcSfbsY+UrY7a+hDPRnPDSYBnwddrGiZw60YL4S05mHwvzS6nNbdpH/jcJt5JJutTHUrS7SzHkDuLZahrPPouP/FffJ/iEV8kzyRbVWcGnxCpgoOeSTZKJQxzwkdMlo0WXZEwe4zKFX2T0N5w98l/Bi018JLnkecPZI/+X8JH/4/j/IMrs0j7y/wgfgT3DB6sMsIEr+pHuER+fJNyMo70m+pBTsRH4+RAfFJXfe3eY6krGSP40aYwymsBO2jRg+AAfkCBncT/hbB8H1MCvx5HRI7qRnl7GsllzpvmQIy0DHczD38KHEZH6lUP5Ndp6Mx/5ryCH9K0MUdHTJnY2VK6Pj/yXQX0fOxxDPN+SP9nRFS7kUEnXEH2Moz3Ru54p+NbgQ2vk8OaA3ls4UCLY34p+NM8r+Mj/JXxAj47872GnR3QreSdHRvr/UpTdxq/fkV2kOZTDke0LOdY9uo/8z7wmHSedIbrexjpVfcvOGvLPd+S/cCCHWs6kxn4K/K6fOafBv/YLRThepxxVOAX+Az4iRNmH0mETuo/8ly0gupbdJZkrm0zBUtXNp8yKp3KQFqxfst2jS04q0U529GV7KLD6kP/vjvyX3SV+Ee419gEO2GhhQzbGY+wAapwHtI/8n3HWZtPJuGAalHyUvFyKdqDQoRZKsu5QfQXGZctKpk9xoHynwq3uSVaCg5oKxDSYvkWL97Fd/yTV1aVA3NdwwEgy6bzrv8t72v5d4C+/8MILf5iy7/MvxP2/APwnL7zwwgcU3Pymj2tInn9mPP3XZ077hZNT2kpAzHqa7kkonsR/OSDPOMvkuX/Sb61yLKVyGb4lLJxn8X1clREs2agXXNm4lEDU6X/Q7ifDt5yeSXhLqIrhhDPhN7cpmI7TM7Wv+hnX+qgfwdlL7S6lcWU8HtGeO+Grn+oqcnlCW9k9S/d1KqbgzYaa4FO9jG/BkY3BacJPfnaa2hike3k+paDyPIPprIu25CjoEq3OsQGgcfVpj6ef2pJwy20JvtP07CTVqXGRI+QyIiVMM82q3QupfOazun+1l41n8VwXHnXlecv8kMtn/sywyNkTHWrFXY6paE8rOUcL2lW/Gt9J1Ydg6kqdyHwIbT7LCjjPk+CTohLuRAtHqe5xR1+ZXkht5yOtcwAnG1Vqr+YH4SHjOvPojPZ4+tFv5gPJSfFVhvO0ap/qdzbsVS5fWU+sYDmeZaCujD/BkXkiz012pDQ2GU9HVfl8P8/PaQXfccJ5NlSygZlln/qdYxmYZUum+Vz3KJXR+Pq0+RssR2fpvmCREXhEG77seGTZkHki36vnTPVm1W8SjMKV5FOGQfI5682T1F7GTw7GCI81TUt35TkapP9Zbme9Xct56V7httY5Gf4ZbQM7z1/Wr6pTy3jJCdVVf5Ijx6lMPY6aZvJcqT3JdtWfp/HlvoQPjSnj6hln25chXvcpOstj16ryPJUhtbHoqmkvjzvrVNEEx7SFaX29RTlr/dOUYwT/o7j3p0xbmS9FZ2o608gz2nq21jE1/2c5kXW5+BCcQVAHqOo2e9X/LtmR51BwndK23dSu+FZtdc135v+6z1mqr+CV9ES2gbtsNtkTR9U9yQbJp0zT+tRTXdspeQ66ZGvGgXSy8K45k+zPNlHGSZYNXXMmvOS+Vzj/+udy2r797W//F8B/Eb+3gF/bUWYK/Gv/PO3C2XzX7JDV5fJ3fX/R/3wp3zpHwajudbVxXs5r17Worfr3Ini6YMh1Mlw97HCcpnK5va62usZ8uuBZ3Wdu97w+uuY0l59XfS2ay7rMopzi/JuqfB5b7WzXcJHudbXZBRN4Hup57aqrsWc4F/V5Hl2c10cXHS+i7dzeIvi76K++umi5ppeu+V5Ury6re104qWkqKwrRd9d4pTzqev+8V24rt3NafXf1UcO11HGvq2wtm04XlKvh64K9/p0d6uwk1/Dl+c28vohv8u+M8y5+7Gr/PBo8b+665HgNw3cq23KZLvqq4TwPnkW4n3N2LnK5TNvn0VKN29xeF4yST11XhqvW0zVvLsLhx+m7ejznybwuXVDzdF23S78twm8Nbz2eRfLi4/RKfXXx+3fK/zV/LKr/ndgBdbmsOxfRYq7X9WyR7q7LnKdvF9WpHb6FtlotILuI713Ku5e+Tjkj/efhS3dKClndb91sV1dd8Hbdy/N3uuD+x+H8PJzVtJxxVsu/Lr5fJJ/O0+dd/XfxzqLyi/qtf2f61LMuPso4+E74YtHz82TTeXLg49r/Tsr9d1lp+//Z9QJnHScZXVkY5VWvmtCWqv9wlpC7hMF5wraLmLv6rgVNv2pXz5exolsEh9pZjvunVdt1X12Eu8iQrfG1nNpYTuVqZu5SXCwo08UY+q+9KCechb9rrur6Xf3VcGU60JjUZ35et1XDkOtnWqxpoMarykM3Tup7eWWva15quLqEXq5b02UXTdXj6aLXfKluPe7c3qL6+V6O2tdw68rKqo9phWrcNW4W0WAXn9bjyLDpc9pRp5/6rPHT1VeNh9qAXFS+63/mzy6aFfx1PnwXH9V4zM7Yd2pw1zB08VTNS3llItNdV9u5XE1nXXir52QRLyziw66xdT2v26vlcy7TRecZpnpOu+i0nr+6bl7ByJ9ahixxtv/Tqm6fs8EOqjI1XUofiz9qOOv6Oesl97Nclcvjrp91jauej9ogU/0uuq3napFuh+4xwdlx1+11wd/FK/X8d9XL8NS8me8vc3asXXSwnJ7XMqCLt7p0Vq0Du2RrF092yZtabiy66vbrfut7v/UUeucc3b+H0/UAjv4RLP8ijP5j+Ma/Cr/xDwD/MoXp1vFmfXD+4SrOk+5T9tAppxk+ygv/v+3C34hbWs3SmJSR0DXXi/CyVH1nHGjlNs93bYNl/umShbluDWsXLS9X97vkQn1Pq4i6uuzEPLaadmoazHIF2o6oyuh5DjDW/XXhXX1K5i2l5yecpcNFcya5uQjmruu5cNrg7OR1OTc1sy9X9ZZpK4N+VV/38iTUyqYWUDVRL+O0wJz2URNnLaSWq/9dhFf/puNeV/tdcKuuUpgy/F0KpksxqfyUs/10MWr9m/R7APzpgOd/RBvv0K3wa8FV08jHMWxWnF2w63fNeF2Kt6v/Zc4KrVy2/nQpSugeU1d7S1WZ2jDIgveUNv336R5P3d8iXutS5Bn3/Y66+Vldrovu8pXptcZjF55q/NSrWV346cKjUnJqx7YeM1WdRbSf+1hOuOh6Xo/xvDZ7VXuZZ2o86ltjy32obpanNX7VRnZQauV9njzrpfYXBUCo/s85y+NdfXXRUNecnYfrzM/fiazJ9+ZVG9mx76LR01S2lvG5XeFYxoR+13UX4XyRvM4ya0Y3LjIc9Xhznxn22kirU7jy/VxPv2s5nsss0oWas0y3eT5yH4tou5Yvfdp2Rb+jnozgrhXVut88/lxfbdQyqJZTpDp53HlcSqmtaXQRrdefus+aDusUxRoW2RjZgc9jzeM/T57BWRx2yVtS2cxXmV+7xl1vK6gvpRAL5uN076f+OnzhPeBvUzbj/ae0cx6FhDHemDeI/3kvRL88G+x6bJnezsPBIt7Ss/P4uLYbMs4yrurMn+80sNQll2va6rIRuua9HlOmowxLTad1nS76ybSR8aj7XSm5i+i2liG1/ujCxaJ2a3yedz0XTtuIkka8SXlr+hXKBr9jvPlxBryJN95fp2yi/YDCG5+kvCBO+aArwBcpL1zcpCBlDfgM5YSUAeXkmCuU01612fd21H8Y5VfxaXnfh09Ju4RPRxLhNJSNiN9H4etvBuwXgC9jYtChKwrGjCh7X0cURroOfE+UVRp2nxLcuRLlruHDMwaY4bJg6gfOTgOe6/gkmyHwGiUT4EPg8xTnbIijt2/GuJuAdQcLvwN8mMgbePP+RnyuRRs7lDe+fwr48xQh+FrCvU61vIlPwsvMfQu4B/xM4PIi5ajSl/EmVPDpmwTMb9JmvmncP6V9euSbFKH8Hj5wQji6HnVPKZtK9yn09hJwgzIfx8A3Ul31tRvjvhWwH8ZHJ5t9Ifo5oWwIHVDmYC1+fxD4kCBZx/Pfw6fmaQ/j9Si3i/OjPx/zcJDGpfE0eKPy3eh3CR9CIkFzJdr4FPBO9PsKPhRF1z4+7XKMaXIN0zL4tEDRrfTaEtZrUHhySJED36LQySTKfp7C0w9wYLMXOLiBDxz6QhrndbxhWLnoDT65VTzz+Sh7HGN9iPnlNt0CVTjrUWjsK/iAjm9S8P+V6ON+6usGpput6G8vcPYmRSZtxu9LUUfybBxjvxf3TykZPcrjlyzYCZhfpPDNdbzRWvQN3px+AW/U3gnYvg/vvdSewSzPtvBBQ2NKcDkfnHGdwvOSTfvR7iV80tuAs6dHfg+F3zV2jXEQuPt5Cm28GHBnQ/mlaOctfMiD5PnLCddPov0vUfhYemM5ft+OtgY4WP4ShQfeiz4+EXCOgLdjjG9E+5u0lfk0YHkt4IHCD5sUebGCDwW4hk8hvBe/N6Kc6u7HvVH0sx9jfIUi27WpfS36PKa991M8uhrtCmc3ov+TaPdSjPd9ihySjar9GF+INh9i2hR9LNrTpkMGvkSRM0T99/EJo9/HWb25F/i+QpmfUdQ7Cvhfintfx/tGrmK5tB/9fjbGqdPzDij2wW0snz6ND67RYQdr+NTRMZYJN7F8bjibsSIZciXaEI9IJu4HLqTXtO/rSwn/w8DtRrT/hfh+QqFf0ehtynyPot17+DCpK/hU6HVMy7vR32rC4TKWWXlP1wfRjmTsceDkCcXWWIvPK/HsXawzbgUsz2JetBg1D7guUeyDq5y/p+0hPjxuGnDcjXH/LKaVuxR+/Dhj+IMoI31ygO2RO8SA/k3gNwN/7UvwT/9uYdx3KRO4TSGClUDiiCJsNiiTPOejYz2/+IvtQ4bex/JL4zmI6pLToskux2Ij4P9MtPM2Bc+38GFjO9HWLbwXcSfAXMW231s4CLAa35Ljn8IHjVyJ8k8oMnAY7a1HuS18OMtVCg1m53EXH7wzpMh72VBgWTGm6GXdk819Bx+gphX8u/iwpKw3ocirt7Gt8hrWnxPKNAo/+XoQ+P1c4IPoYwt4lTLdkkmXsIzXXI0CrlXaVy9g+TK2nb5AkUn/dxZfz4XT9ksoAxpT+GIdG2wyPk4oCJXQ0mc/7q1TCEMEOIryjykEtoQPB/oAG+aX495W3JMybKKdtaiv9nQC1RgrsxzxHgUcMtx1QuH1VGaf9tHXYwoDjFOfYlQZqn0sCAXzPH5LyEuo6jCCC1FOmx2luNYSTLsUoSpDdRVvKhUjDvDpWooQnkRbEq6XA4bDwLnweBRju46V/CyeC09yOmT0ZadNuFiLeuN0Lztt05iLXpqDLACm+HhXGfXTKDehOK4KjmW6ADs5UOZONHodH6U7xAEDGUYat3AxT+U0F9Poe4xpWPjei/FcwA7bdTxHGp8U7SD61bdgHEQb4zQeKSbBeQ0bCsJjP/AgfO9EX9eiTG5PKwFjfMIptGlZ0dgckBxgxSAHlMCDZMARfiXBJTxn+5j++xW+Z5hf5dAN4r/mJzsoUhDrMb6jwMck4LvIYiNCxpuctqtxv4d19VUc7BCfXsPO9BHeHC2cSel9IuFaxl0tJ06xcgbLTRkGq5ge5Bxnp038MMS0fkSZV43nmILvIyzPtAlb/LqaxjWpxiPDT0bH5fhM8El1yzgYsY71gsaoYMV1Ct800b4Ompnj+dbcgQ0QySvhR/ev4xNaryX4RA9r2AgXHh8HLq7hANZ2jFm4bTAv9XEA7hp2VGQgiuYVuLmCV4+k+/arunLUJLvmCd+7FIMq6z4FQzWPWa+I7kUrn8Cv1FjFJ95J1kiOSLeMovxqKkPgQ46raH8QsI2x4a6yO9H2Bdpy/DE+EEK6OsvR4xjf1fRcjo/0puTSmLY8JdpeT/ekIyWn5BCtYQN6jGVC3V7ttAmmbKuIR6RTr6Z2lWp1JWDfTW3sYxk3wwazVk+y3jzFjvYB1v/QphU5C6IF6YGGs4d9SPZKxk4wDzacpantKD/GcvRSKic7YAUHEWodXl8zrB+m1Xh0OuoU8/fHOW2ytUQjkiWClXF0+h7wx/8u/J4V+NW/BX71W/Df/AL8WTyxMig/gd8ZJaJeg4u/DK7/k9LPkCJ7tKpVj0e8Ieemy2lTUPgqlmmiZc2J7J3rmF9OME3JaVvFtLuGg01Zv0rO5MDPsCqn4JvksHSG+KFemBSv6ZpieXM93VuNMUnuyoYmxixavUrbUdLihXRW1p8NdjizXoQip/awDaa2sqyR3Snb7EmCU/boGu1Ldsq1hAvh7rzruXDaFH09xMeWylDbx8el5vcBDaKeIjaqt4KP/31IYQZFTHr4fSR6t8Qyfh/SE3xE8iE2RBoKcW+n/g+xoSWn7QArnd1o60nc28ZMqWcHWNHupvEOcIT0KPrMS8THUWcn2lD/ORJGamdO+9UIOv5YuFA0RMJY7TyMck9oO7+zuKc0sx1sVO+mcQmPuxSBvUP7xKEZPrq431EXfAS06GMWz7dpH7e8i+dMc18LAM3tEXacdwKfB9jhkUDTpfnRfMpwnOPVYEVW1JfGPcCrxaKFo+i3ifHs4WO/NT71J6dNcMg4P0z3pez6+P1yChqA+eVJaqdJcKlfzZ/w2E/f4pF9Ck9NqvbEuw1tGhTPZTzuJZgu0N5TJaftQ2wMCCa1/WG6J8NRikxG7Azz6z6OoDa0DTw5bfMEn5zZx6mtCXYA60uwLNE2OjVPWrWaYcMT7MDn+VYgR/g+jN/C9aMEr2SicPuI9krbKTY0JVfkSFKNRfDJ2TpIsGg8U/zqhW3a8kzlRUcN5g3JIRncuqfnolnR2iS1W9OZeG8Qv3OgJ6euyBHeT7DIUNjBck+BwW2M751oT7SuSKpw+YiicB/hVPkRpjXJ+z28qqyxSa9JFpJg2cGOmVJuGmxsPEnlVHcfH6ctmCW7NS+68mrUQaoDDrgIZ8N0X3Mi/hafgZ0Owf4Inx6nMnlvSt7T9ggbSwqaiJekB3ZSO8KT9GzGu5yOCcXAHuHXPswD5mcUeSOa2004O8Svd5ANITpvaNsGedyid7AjK/jlQIH10jjhtcFyJssJOYhZRx7jec56ept25oRsnT3aMnuXtu0kubdE2w7QPIzxXCv4rKCbjNLlhB/J0ybVE68dpbYVLNN4FazZx3os6w/Nfde1g/0hzb3GrfEIL9t0y+58CUfqu4lv6c5fqkntU4j33z+GtT8H/wrFwPkDlPPbNzABCRgJ7TAS/vE/sewWjOIRjafBdhu0V9pqvEh/7OAVnIvY/pBtuYy3vMhGULBFq++SIWAalsy+jPlF7TQ4ICo7XEGGrNO2aaczyjYfxJhrm+0knkue6Z7GsUP7lQREm0K37FJdc/z6oCZ+q91J/FfQMF+PsC4QbexE+R383s8chBF/ie9lZ+ZL9Cl/oaH9fr1F13PhtEn4ruAX5knYHWMnRV5zLjdM/8fVfUVpJRhWsEBfSXXre+pD7Q5Sez2K8FE0Jkc+pgmOBhsOQwoRi/lGMSbVHSbYh9hjhzajamzjeD7BK2Fypk5pK5HVuH8Rr4JorFpB0O+j+K12FG0k1ZHyO044Ejw9nEo2SnjUeBQVm6c6DV4p0vjF2Kp/mfY8j+JeTok6wPOsuaqdtlH0LeZShKZH24DOOCbqaNn7Qnp+mcJgqitcCY9qY4gVsAzOcbT5DNOY8KTfiuAITtXJsEI7ZWCIhaL6l64Yp/Go3iHt+dvHzkmmOc3PCk4DyO3NseMq+KBNy3JyhZ9BKi9+l9OmcWocB5jv1LfwJP7I+JERCl5lvZD+Z8Eomie1kfk5810d4SRgE8407+pHinCM50mG6xjTzSHtd8tkfOfVplxnhKPh4inxw5y2nKrlBqku2FgRDStDIEcxj9PzMQ5caExZ/oH5SjQwSx/RY5a7WmkTDaie2pMcu0BbXoiWZCgu4fS8EZZneR6zXqnxreyJLLsu4gyGcbqnudVciA/HCR/ZaROdKzWUCm9D2mnacr6Fg2FVV5Fy8cE04Mq6L+NygGUW8TvrBuFMfYhXNN4BfpG35MhSwkFTtQXtvXgzLI8Es/AJfqHwND2TnJPePE5jvhzfSjUkwSI7Is/9CjZQBafmVlkGWd9cxlfmJY1bPKJ+VxP8wk8Pr7Rl3CoQK9gFkwxg9SE4M/0OcaaNZNeItjO7mu5dwrSusWVauYjfXSoYx1in6/2qcuKlB4WfLHck0wWraEb/x9hBkz55gmVJpsfagM5Xgx1p8X4et4Jyulc7bfPqnuhRwa0cSLoAViwZyAHwt7An9RvuwZc+B3/wj3lZSISnCOPFNs2rb+lt0YW6GqcxZnszX5cw/fQwvlfxwRgNbb6Wo635lp0imZnhmmCYZddKtmneNJcqpwCW5Khs4CXsnErWCXbRPVgfaRyiP8mfS+l3XkF/QqHXGseCU7Il2ybiz0u09aLalI2u8sLbGDu9am+K/Y3lVC7DAtZbY2w7dZWrr+fCaZtS8kYVZVKQYooj7DNKPuoErwoNU50ZXkHawg7LJn5x4RP85nV54U8piLqPoxTQjvKqj7fwXhhFLbNh3UT7b+MX/WpF5O3U9ibtiK4M5xWcXiNhJS99CR9QtIK9/22cenKKCVvC8+24r6jrKMYqg/gBJTLxdtQTbqHk+CrK9Ai/KHaGI2qHtB2MLfwCQ3DkZYZfTC0jRBGGebS1mXAiQ5T4LZzJuJ1GuevA7/oi7P1kecVKL2B+h7Zgm0Ub4EjmSYxxGjArvUMCSLDP8Srvh1Fmglc2NrHRmMfaC5xv4mitXjz9LhYgosf3cfR3B++Vyiukq3H/IPV3iqPZ+zga+g28KiaBr6tJbYKV2k6MUYJV0dMZDiBKyNbtPcYRI9HvE9qKN0fBhLOLtOlXhsKAgt9djOsDvA9zm3bk/zDg2wx4L6U6ivZNEn4URNBq7zxwJjo9pJ362rB4pU2yQ3M7x3tIJnFvhl/IDBbUg6gv+CcUWXOfQnfvJlxLnokX8rVJe6VtjudX0fg9TNd7qa7GLJw3OPr7TpQRn0wDJuFCslR1DjCPSnGLnyU7xGf3A0YFnpax8S0nSGOfU9KeLlDo6gFlfmapvpw2BQc+wPuPcsQ/wzmirJyJD9/DskyBBvEwWAY+wNFgGRcbCR7RuQwxGYLH2BGC9ou6h1ieCD71OcH7L7OTs4WdXumSecKPyikyfhR1JDMa2i+n/gCvgsrhGiX8aNUS/M6m9wLmR9hgzPJQ45cTqsi78L0TZaU3G87KcekA4bvBRqFW2mQ3CI/SNwqI5Hl5n7Z8bij75oRnyWoZ/9sxBjlZ6ifLygx/vhTQkZ2iIOkxlomHgYs+1sOzuLcScIrORJsKhmQaFZ57+CXTkn07OKOkwc7SA9rbNmSEaiVONoV4+EO8nUJyVDymlcGDVH4TG+/S4R/irJ39KJtXLaQLF117MR69k016TnbNAdZXcsTOu3Zo2x/ivX7A+i9s4z0eYOUANgh+5l24/S784WX41gn8Mfy2+lMKUR2UOX0rVd1M8J3EmJ7i/YrgbJEc1Na1RaHPMbaXjjBdi84mOCNiGvcUCJIdLf0pe0LfkunCrXTphPZK/wG2WxtsS8tOJrUpW117/WubbTvKjdO9zcCFghCiUaL+4+hXNla+xA971bMj/NLwWq9ux+fdBIdoD7wyL96cYRkrvp+nurrkH7yb2nuP9op+1/VcOG0DfADIS5Tc0SO8ZClhcg+n6l3HhuYFyoZN5ZfuUBTHazh6ASVf9DVssK2leyI+wbGE862Jdl+nreAUfVDkQw7V61ioSlHco73MvZt+j/AGz4eUjYivxfNjCpP0Y3zrOC98BwslRWb0Udv3sJOkQxpkqKiPC1FuGuNTRPlVvElb4+hho0fRuHvxLaECzsMeUDaMvkIRfEd4j8GVwNMpZfOncJidtk9G+xPMaDejTY37b/9kwdHN6HMUdbSyQozpID3fDTjUtiJ/inaMAl/EsyFWLJ+Mvq5iIzmvfMmQuEOhJxlABzgKqcM85CAfUTarruMophTvAOdTX8UpPAPaB5FI8E1Te9dTvxJSp1ihCZZ1HNWVw9nDOdav4EjVXRyV0rVPmd8D2hGzdUxn4GyRhvaqY3baoNDeCK9Yy1C/RJmzIc6rF/9dp9CRlIn4dY8yXzJUZFw0WDFrdecuZd4ntA/MGOEDCurrA7wnYSXgk8Mk5+0VbMwr1egW7VUzzatwJoPzVYxrybIxPlxC8PewPSFjSQGdW4GDG5R5mmP6hnYgrKFt7LyG0yOb+M7ybIzpaRz9HOCVOckzyab9qHsZp9FpFV8BEShzMU5jP43nFyiHj8xjbLc5a5TdwYZkQ/sgkjuUuZGxvIo3pB9R5mo56r0U5eVQQ9E134XxfRMHrmQMvY7To2XU93Fq2St4f4RSKD9F0VtN1LuKDYh72CC/k+rKqJKTJIdAdKE5uhJtSK/KAOvhvYN30/NbFH6SYyddexLlJXvUzivY+BtjvgQbgHJ2BddK1P8U1hfSm6K/1zirN2X8X8MHZowxX7+EV0Glb65juaS9iHfwoRia3ztRXwHgezhwLEd1DRuqYzy/OrxFdCVZJtiH2L65QqED2RB70d8rOPX3OPAt20AG4BrWj/ew7XKC6eGlwF0T9+7i1Mmr2NC8RqFl8Ir55cDDOME9xTJFDtw6pstJ+s409Tp2cMcU+ngxYPlWzMs1vPd3iPdEXud8p03pdHLUmzTuKea/2wHHUmcrvkaY7qCdHvkJ8IbgK/jEvGEqPEpA/+4T+AHgT/40fOPzxXlTlG4N7v6d4giAeVx0pPEcUGTNDcw/cmxqvEjOSI5NY9yfxFszZNPcwsGWbdor1gp8iHZFaztR9xXKfF6izJvgvEmhqQ8DLbJv9vC+aOkMjeXDhBLxWrbZZtHvGMszBf360YcCvgpw34l7e9FefRBJ1j93UruyAa8HzvKlRdJXsD/wIbbrJVOUFSOHW7as7NF6BU0O8z1sy3+Ksweh1Ndz4bT9E7w6peiNiOcpjgb9JAW5ivgrwqbo2TjuKeo3p0zmLmViFSXcwKe17eCo6SY2GPbxxmv1sYKXlBVxVlqUorv9KKvDhBT9+XHMaNt4D1CPMnFyGt7HERGijw2ssLSMreXnDbpX2qC9bKwTylaijnAmPCgKvJHqa+VJ0bNDrHgVuRziNKxejO1DHIXYp8yh8psl/MeYqU/xSud92o62Ih8b2JjRykaOOO1R5jBHc+qozTfi9wCnggzwCoKcQI1LDDqnnXN8TFEYq3jfg+qCHcQnFJxv0D7IRUpBkVetTn4VK8pdHNntJ3yt4lPC1N8p3relKNpJtKdIqJSvxpNXUw5xSsBu4BGcd679MZucTePT1cQznQinMerUR13qbxMrH0XLNBbBKIW8h1ffRc+7OB9fONqK/t9PONA4Ffg4xoa1jAmt9oJXXWQESBgPcOSsvjLtydFRhHQ7xv+TeH/KSdTbwXQjQ6/BAR2tbPxdjGvJMxmuciTmtFfJ5cxnuniIDzGA9sZo8eYAG+6HaUwE3N/EK0KiP0VSn1IU5la0IT6Q7JBskmE3or16m1ejNIZMZxpjn+Iobya81dHnnWjnPnYspCQViW1wAEu6Ygs7QDr9V6udouMGn/4r2SEa0QEIRzhDQXDJaRPtjeO+VnSFh/exU5v10RHej6e6DW06knG2H/hRdsQ23lM7xauEMsgUNBDOHuGN8porRfO1AiJHXmXkbCgIkZ02zW3WTTv4dE0ZNHtYZtR6UytYTfQlPSOjSWOTvr6PAx87OBWrwSsbkheSzxdijN/AAQTZIeLLMXYGs+zapszZe3ivJNg+GFDmZTW18QzvbTnA6b/fxLryp2OMD+PZRWzwi6em2H7pYUf0fcq851WwRwkPCqJt4aDkCM+j7KZsW0gfahVfToaCJNl22serI8MYxwe07biHeA/gAGe6XOZ8p039CE/H8cn2wmGCrUt250u6T31OMN1uAL/uAd5YqwiihKMUlQZ6nyI0/uzn4d8A/gjwv41OvgU/RaFt9bOd4JPumkQ3W7QDP7WsA68SSn9uYp3d4KyH7Rij+pDMGeGVNg0TrF8PKHSzi3H7YYJTPCf6ln6eBFoe4aCTxrKf8C1dX9ts72H5rHvvp/qi0W8mXO7TbaPMKbTX4FVg6cIjLN8226j9CLeyW4l60j1a2BAeZ9HeBpaLh5xd9XuXMr8/gW35Pra/Fl3PhdP2Aj5MQ585ba+c6nn+LOGJr9vJUYleVaf+v9RRNpcRUefygm8Zn7SVYejhzY0ax3JH24tgnldlVVfGYWYCUh2NYYDTUVS/l9pbSs/Uly7BfVLhjA78DVKdDH+NDxIO9UwG+m1KFO5dvCqW56Hur4ZVuKhxmMvoW3OWx51hqsfQhbtlHP3vpfYzvgdVPX3y/NXzkD/1uGtamHOWVvO9TLN5PLOqzUF6lmlqET8tp/boeFbPRV1uqWqnl+AGb5g+pQ1TnvuMmwxrnudZVUdG4zz9z7yTeaEeu+imvvJ485iPq/o5oNCFs3pMNY6o7nfRaOb9ecfzug7Vb/WnMQl38/Rc/FrLZeFHv2e0aVdjm3KWprN8kcNZj72rziJDJvNBDcuFqq74MfNClyzJzlfGt+DMMqmW8aqnaG+ehwu0aa3mO+H7hLOyKcuQjP96rrOsm9PGTz2eHmV19zVK4CfTcS2Pc3v6KK1Q9FHrDP2u509wZt3aRWc1zF1jE16WOQtf/uR5l06oaX/GWR6UbBKcec6W0kdXlxzP8k19ixayLZLhzPOfdY/k1XKqI1zVNJH1VRcPdtGi9kXl8WT8zKs29J31Sv0RvDVvCYY8911XLfO6+DW39XFXlkH6r+9lOCsAcsO1osmT/X+iCL0/EmXfhtv/VZuHs27Jckv8pO6zbOrCRRd/ZFqp9fZy9cnjzjya4cntd/FWpp+sD2rYBx11M2y1Hsz3sszu8hEyvB+HI8HSVQfO9lffyzZ5l1zuGht0819X//X1XDhtA7wk+RI+qveI4oHu4zShBh9tOsaIu43fYbaH0xQzstZwOsExPhb1Hj4GVEuTPZxOs4SXONW/vOkRRvQBxbP/LkoUArwi+F2YKRSRBO/tUGrMLmWJ9vV4foTf57YenxFOj2xS/4qe5GjmqxTG0nvHtAQu/PQC5ldp7wmAshysKMIQRzUUYVRaipbCe6nMerQxpMzpXZxPf5pwvx3t3cJpiVMcSbwVeFcETxkIeneS5Kii+6KHe7QF9RRHP0c4FeQVzqZHalzXo67SNhSVUXrkFRanR+7i9JtjvPLWj7JKeRGuj6P8erSjaI8YX+/2Wccnxl2gfXy72lbE+S5OsdK4NJ7DgGkn9dvD6ffqdy3auBt1H+P0yHHV3iOcJaII1xqmZUVo93BahF5FkI11MO1NUntNlH01tX8ZK/fr+KjhEwrPTWI813F0WXTe4OPqZfDdSW2Id0Uvt+g+2UlRaqWvSJ6Ixw8DZq3s5vTIAd6Hq+i2cKaUR/EXWFnowIRXEvx9zr6nTTR5A6f07mKaEf9s4/TICT5cpR99gHloiuWZoo8Nzna4mnD7CMszySZFd8cJxqyAj6I/pWhp7CfYqM1yWnjMhszLtE9hm+Bj31/CJzs2OMW7Rwm83Q1YJhRev53GB5Znwrfk6gjvL/2uNM6s6IXDV/FK516UexnT/ACn0BHt6cQ+pdjB2fTI/Wo8mn/pviMs44/xNoDLOKV0SnnH0RcuwfRJafMy1jFX8NyrLaVHbtN9EImMZ9G+5NExTs8Gy/0DTHvZ8Fd0fRR1Phm/88mYt7EemUb/shd0eqTk7Q2cyjSMe5/EKeWv4L1f2Y6Y4NVS8dANLJ8bLMvkCKwEbJLjTbSh183sU+hKKxZHAXudHimb5JRCF1q9PsXBztsUnjtO7R5EG+tYr1+h0KJoaBbtv4z3tAmXkikKgKwl/EzSR3rjcsCuumO8vUG65yq2aaSDx9g+OM/Z2saZMuKrl7CNJ77SFgs4G9zO/7UqJTmkzKJlYu/7bqSFPoaXH8QglfrxBI4OYbha7u19GAdzXIV/vBv7pr+34OOF3ws3fwj+JJSN+FvwX5/a+TgOWP48JYitNHbNv4z7fA2xroDCZzcpdKCVpx3a72mb4lX2Mc78kRMOfpWT7K67eL/3Opav0q/iy7tYLw4o8/xKwm0P24PLOD2yttkeBWyvY/p7GnXuJHzsRJ07ONUw601oZ5/0KTQuuhD/XMfpqLpkN93FMnsHby3J6ZGXMS02tO37y7Qv2Rf38J72T+FtPouu58JpE5OLEK5iAQBWhNqTtYodKjlKV7HyXMP5u/v4XTXrFIJ9SGF4tXOLgrRLWHlIya/hlJObtI8iHtD9nrab2GiTwX8zlTnA6VN97CCMsUAXo06wwlzH72yRQ5GNVjFbfk/bDZw+oT628F6TvXh2A7+7QkL2BnbWxOT91M84wSLmbgLnwuOUMjcajxSRnAEp8ZuUlJSfjj5E4OvxbDP1eQXvUZKhdkLJkZfyucFZASCGk4IQTiZ487Pm9DLtPW2T6OsA06jqytiW/JYhczXBLjhV7iZ22nR07HX8bhoFLHqUebzG2feQaXzCpxTYM/zupJvRZ/2etmEqfx2/p22K96+IL0WPj7Bgq9/TNqSd9ipcZFqWEQM+yW6Q+stOm2hvggMkclY+Ef8PaL+n7SqFlzejzov4lRg3o9wB7RMsJVwV6LgeZY8CZ0f4dLWbdEfBMs5WaL8MVY6b+FDjkdMkRZeNoitRfjvgvUE7LeOQtuwCHzUumam2FBQQzd7CuFZdlZfT1mBaWMbzJ/lwlHChlSMFUFZpv7vpBNPALJUVjyvYomCPFLjws0qbzhSAuIHTb9Y5+5427UtUSusy7Xdcqr1+9HGTMleCX7R/LZ5JnhH3bgUsR1jvjHFa5os4vS5HXI8D/ut4X1o/cC6a30xlxFc3caDlZqormpbsIuCWbJfc0hxMAoacDr6O31mkIOH7wNMn5p3VaG8XyxrJxYwDGf3ibzAdZR01wPMjuQeFXnbjt/SX2lHQ7DT6kjwc40DsBNsJ2zgdWnpTafyrWD5uYJ7QvTWst+UoNtG/nAk5GJIJ0glrqT2wMS6D9mp8LtGWB1kmCH8nWL8qaClbaRbwzWinVef5Fp1cDXw2eCtWL5WTrTLF76pSyrz0WZYpBwHHTXwoRYP36a2l50cUvriM99bL+RQ+JPtXsG0nXCy6FDRQoEHjkY0neAXHeat2YCd8Jd0T7/5EfOYU/n/lFK4+tkF/SKHlW4cwOiwr1CPg7m6xawTPAFj/D+EP/q+BP/4r4A99P/Bj/Pf+rX9oQpnAqz8BP/YPTFMEHEO6V20a7DzJIZIDMohnJxTdeYP23jXRlOy8Lc7uaVPg4wYOKOvl2n1MU/NUbhrDOcJzIKdNcyE5tMhmu0yhhRvp3n2KPJHMkQyHMjdZl+s+OE1a7UjPCn+PsI7M1wQHfq+k+1nuyTlbxfuW19J9yYV8rWN7CiyTbnD+9Vw4bf+Ukse5TTvKpBUK7Yd4B+dhT3GEbYBTjaX0FLHeoH165Igy6VL4E4pw2qD9joQdvK9jO9r7uXRP+xlGmLEbfHrkhzhyM8Bvfgef1LQT92SEDVO72QHYjnIy5Ec4v1hEnxWiiLYfOJtjT34U/Uthvx/tvIPz4lX/HczwO7RPjzwMfB7igxp6UV+GGPi9VzPa+edj2nnYB5R84x3Opnv2AuZD2hHIfiq3Q/u0nrc4KwAkbIb4cJt3A8ffwkvdI7xiC97vcojfGzSJ8RwlfGYjZS9gaeJ5gyMvKxQakZFzn/YpaoPobxPT1iHeg7mJI1haaVPqlJzwabS3h4MDUjAKGDRY0e9EXw8xv2ick6izgQ9NGHW0J/iahIsnmJbn+GAh0b6Mztppi4DlRxFC8euIQpfbaU4UeWxwnryMRwncffwybTm2TzF/qV/hTPuxFImU0dbltCkI1Ivx6LTFfbwP5x3KHOWT2GTAD3B0UFHRt7DseifheiONW069cPsAO2kKdOXTI4ULzfleqi/eVMBA9LaMZciUwifPsDyb45dcN7RPh5O8OqYd7NGcSRbn0yPl2ID3M2Q60x6IJnCxQzuFXJcMuU3sqAieeYXrfawrtikyoR91Tyh0ohPTephWN3DUeUShV83BCO/XkZHSx3Q3xAaF6OQ0tTFIeJQjOsHyWQbAId6rvIwPhIEi23USrGSAjDXpGT3LcmMT74GZRZkxpkfNp2h4ik8a3sUOrAyznEaYddMm3i8oY0pyvMH6Szy3gel+hHl5iJ1lfaTnpG+e4v1i0unfjN/a53KI97fJcR5EXTmYwrnoS0Y0WCcIfs0bWC8pmCv74gjv+dxPeNT8zDEfbODDXj6IZ2/Ft2BuEs77WG9qHJo/6XWV3wi4pNtneBVji7ZtMcPnA7xN+3CnrBdFh9OAV4FR9StZ2OC97St4z6Z0zaJrF2cIKCAmu+Y+5nE5Bb3OVnxtYb0EDoBl2aLgwBLeW6yyO3gR4QGF1sRPOpRKupw/A6z+Q7jzHxUr/Y9dhL/4FP4z4BnM/4FlQhN9SL90OW2yuyRTPijNfETXojPZr+ITrRCN4/tZtCV9KB2zhwMg9emRDT6R9DGmH+1VVL8DLAvV5hZOp87ZSsK1VuvWsH3wAZYtCsJkp3gXnzI9Su1JfxwEnPlo/0k8m2A5r2srPu8m/O5imSV7UnjMMlZ8D20HEgqNHlJ4SIH79zh7emV9PRdO27exMMiCd5Y+cywoT3D0TkpAdaQYTrBCOYn703Qvt/0s/T6J9nJUqW4v1xccuXzdRy/9F6w5jVFt96o2qOoJjtzHCW2FmJ028HvRBLcUtyJogvGINk7Ud8at6qsfjUGwa5wnqW6NEymifO8Un2YkZ0xCI+P7BBs+Mhx6qdysaiuv7AhWKdIMu4x4UlvZeMz4q2lU93pV/S7aEl7zKkZXu6e0x6M2j/HBL+pznsqfpmentHGcDYiMV41dc6iyirTl+XuW/tdGcs0Xeiba7ioHplv9z+OtcZl5rsapxqu5l0FZ091xaiPTXO73GW38LHOWh/OV28g4rOXESdXGtGojy4Xjqk5N51OKgurCrfAhHoWzcgPO0nwXzsEBmBo3s47yNV/ot6K6uicDRnwtGSYaFv4ync1p4/YkjUuOAbRlfU07GaZaB2T6PqFNJ/pf85U+S7RpRPyiMUCbr2XkZPypnVqn5d9d+kH0cUob31mf1TJLuMuysGveZjhlK9fL8kHl1Y8CjAqAqh/JqzmWfZkuMy4y7amdmo/y2Ou5XUq/s06o8Z3nupbzms8sJ0jlhd95ajfDn4NQ8wqmrHdq2pxXbdS2wQBnqOSx1Lq7liG5L40tl8twHGFazPLtpCqX6Tzj6VlqO/OpaKOLzjSeQXznue+6arnTZWtkOD/Oaavlu/CU9UOWYVl+H6V7wq3m+1lVdgp8+xm8cESx2L8K/PDT8nLu3/4r4bf9/TM8CW05WOuhLHeWOCvva/xkHhKcpDIa74A2HdS0kuebc/oVbJKFPSxX9T/3q7b0OU73REe13BUehLsjzs555gPZPbo/Tc/rOplX6nt5vjNuRTe1zNbVpY+6ytXXc+G0ZYdMyky/s9GpqL8ExVEqf4w9f03gU9pGSr+6J8O8wVG7elIEV6xat2DS/RkmIlK5rDQaTLD1uHQvOzNP435thMqh0ZifYYNFhpoYWjhT3fxb0UeNO+NOyqLBaSxZAahcD0fXoK3cMx6PUl9SdFpBmiT8ZKdczKb2j2Ksuc8+NtQ0jhw5ydEoMbEu4UD1NHdZaKyke9kByP3r/wltI0xlNC6NTe1r3NlAV5v9dK+X2h5UzwRbdkay863oltqdpzriJc2NcDmp2hZ/PU3jEB7r9jLMeqa6uZxwoTKKvmXci1aOqjqCUXBKsYv2GkzDWV4IBxP8HpzMh3leJH9UV+OZ0J1iI9gy7am8njVYzs1SuWwkSWFoTsTfqkuCVys3GbeZLubpXi/6GuLVS2inFwuWGu55Kp8VVYNl0QTTB6l+5penWIlNUt1ahi1X7eQAgsprHlVXtJ8VtJ7XfNtLzzJNNem/5lljaCrcSj5nvhW+Nb+TVEZyKCvlLJ+Er0zzywlGyce8mpHrStZKNizTlu2ketmgeob5podPlxR8A9rOcMZ3DiJM8QttRSvQNjLF46J9wao6NS4y7eVngjvrgVl6ludDBpTmRcZsnreMV41d9zJtZ1zm8nmcwluGv1eVyTI+y7BMe9IrakP8IBtBcyYdfZrakNGeZchxen5EkQHZuM7lFBjVPIpfsm2RDU3hR3IrB3WyvM2GaJbfgkHjyTiTvlt01XZJljXZRhOdfFx6ZG2TSabnzB/Nx4T2KkrWM+JhZaBkeliOMe0C17ZS5S3gtwCjvw9/GX7pq3Dz97ZPYZXNpEBWw1m9oHEKFtGu5l73NIeCs0fbuVK76ks0lO0Arczldo5p2wu1zSRcLkWZrHv1Hltd2c58imkw63cFlbLtnXGRL/FJpgvpT9GgZEKmlWwjZ33ZNd+CW/jKfF/TX5aduY+nnH89F07bt/Hk1Z5nVxRMv6UEeukZ6V6tnLKBnCNl+f8stTGlEGCOHE07ymeBJmUyrdqbVr8laEjw537ryKN+X6jGqza6nDbVybiT4hJj1xGTHOGbpjZ0f4k27qRg+qmsIhn1eKZV28fVf41nGTNyhi33l4VrhlFGRjaW1I766tHdL1gpin5y+znKOK0++eoqk2lBQqZHe3zCSb+q06/aEhxyJk5p4zvTdReuoA1XjgTmtk9SW8dV+frKiinTYKZl/ReMGv9Jeq55z0GMWfXp4tfME5IlR5zFQcZ1xmUdLZ9WZQVTdgzqMWmlTUZWvTozp+BOOFK7NR1KTuV5zEZyxkON20yLc9rzkfmQqmyWM7Pqv/CZZWV+Xkffu2SkDIGMC9FYlmHQ7rc2mFS3DiLlel0rQ5mWu+DLdJN1Sxf/1vIsw6no8VH6rbFqHrpWl2r9pfuZfvIn15VcrOe51mc5CizYsrFW06DwkaPZOdJdr/SQnsnYg3Zwpl7B/7iVtprO8njrSHmGe4mz8roL5np+Mw7ySome9arytew4ru7XK231SkRe4c30Xeth0RY4w0jP8pjynGq+azrOc5VhqfGVHe08nrrNLtuoLiP85/5quSf5Wcv5RVdNr1nWdPH2x111fxpztkcWrbR18XDWSZlOZsC/DYz/evl/hFPpesD0k/C/BP7qB5SVuG9SculmOMfwBP7Pf72k09X9i27r7LA837Vukb7toukebbpVmZyBUOuO2s7OsEkuZDtRfWU7JcNznO5lWoJ2MKie91pfC+YuuZN1Q75qGaJ7OaNMvFnbdFlv1gGIzI8Zj8ecfz0XTtsKPjXpLj6Vb4LzkufAGzgieg2/s2yFckrOOiUyob1rn8MnFvUoebHfgxXc5ejrM3HvhHKiDAHLGj4gaBjlnuCT4o5xJKSP9zZ8lpJrvYxzXT+LJ22MTzYaRJ3X8X6QGzFWAgd7Af/VgGeMT4+c0uLjjwS4xvBGjHULb9qm6vNhlMsC9zTuDSk5vsr3FlEe4L0Lb+D84A18WhBR52XKKTs72Hhbpfv0SDktYrbblBOy5oGHi5TNtHfSuMH530t4rgb4EmMQbTyKft+gRDYGeF+IDtm4HuXneB/iIMbzCQoNTjANqr9jfHqkTkXdp/1C6e+Ofqb44IXX8CZ37WtZiu91/EJy0YT6mwcsiuBJ8LwWY9CehlEqf4j3dojnepR8dh3c08eHMeiUpF3KaUea+9ye6HFE+/TIz6RyO/idSsLFmHbQoYdpb4JPpGswvW3iDft9yrx9As/ZjMJzwpU2OefIZ0N7RUFzcJ0yh/sUurpEoZlbdEd+t2hHXj+D964sU3jljYBpE/PnLUx3W/hkzXWK7OpTgjRvJFyPaZ+wdg8bw2PsMErx7sT/FwM/N/E+sOuYf7YpimcF74PYDRgki2QgHmF5JtlyiF+sfj3hdjf+fxrLlv3Ayypl3nfwwQg5yv8a7dMjZ/F7kHA3Sr+Fhx7lFDkpP8Gyhk/G28M8OabMmaLmn8apm7ejrRneo3MHn0x2RPv0yEHg6Y3oQwdViZ+0cipeB+/huYNlgXi+if+v4z2D9emRK6nvx5guBBP4he2KAINX9ISXOwlntygyXMbnKtZ1a5gP1N4b+F1iI8yXpDaEU41vI41N+mIL7+eT/pKcG+N5G0ad27QPHTlK98A0eyXqD/GhG6/hgzxEv/ei/nGM59P4/YlZpml1aYQNUZ0eeYT34Yu/pJduByya2+OAfZ8yd5/G2RHSx6/jfeMr+EXIcwofnuAVusPo81a0NY+276UxXMUv117HtLIb/a1SaGwcbclfyEa07KPvwSsFWtXR+yBXKXzyLGAb44NIDmO8nwgYdqP9IT586CrnH0SyTaGXvLJyB/Ov5OldCn/XBvy8uqc9kOrzANOtys3wu7XXMJ01MW7JgmUKju9Q5m6XQocX8CFn4uFDLP9kVx4D/E+Bfw/4w78a/ptfKILyZ/lI8H72r1s2bkQbktWigdt856dHDrHTL+dpNf7vBsx34/8+ZX6OKPP/iai/m/CzifevS/5IFvawHpIOzLxOwHcYsH2ONv31ow/ZbJLNr+L94Vlvkvrap+jzV/DJ1uKfm5w9PVL7qD9N+/TIS9HfCJ+nsYppcYYPILrL2YNIjig88BlsG9+jzM+fZfH1XDhtL2DHR4acVg90X8arDLRB+q/Phepe/i3mG6Y29D3Eh1BI0fQ76koh66SyDN8yZ8fQ5ywsVM+XFtTJBnmPs+PO5Xup7Tntpe0BJtb8Waa7PxlivY5+xHDQfueH8N6jPWaVy+2I8TIcPc6OX0yTcbdMG1fZaatxoef5Wk5t6nemmeXqf56DLloY4KjvcmrztMJLTYv5WYYnj+tCVV5tDKt7Ofdc90QD9Zzn8dRzL1xmutSY8lzV+M/4qWkg4zf3m9uq51u0K0F+QjceMu/UvKy+VT/DO034yTwgAZvlT9e41Xa+8hiWq/oZ5qVUP+Ms91HjOOOfjjLDqj21r+BKpvmax1RX+KajjMplmZLxtmhOc5lMX0u0x5XlSE07NZ3VtHehqtOr6mb5XMO1SKbUvFrjg44ydbk5DuLkcStiX48r95v5+8KC9uu6i/izC+Y5bZlVj2Fe9ZPnrJYR0tFdcjPzoXhLKwkZnpq+u2ivXz3rJdzUOr+mEQVjajnYhdeaz2uZnGWa5jLjuNap0pUadw2baLQLHtkXmV5qeDUvWmnI9ktNF138uWh8+Z7mW+PQlWHR6oV+1zZNbrML5/V4unRM15XxVMvTPM5My+ddFwIG0WoOtiwae023XTZo5pca5+pXfSyluvSBvwG89wvlBd2/dgV+7Tr8/S34ajtQnOl/qepjgFd6apxmOlhJdRXgzjRQ07faO67GWY8xz0F22up5qmHrVf2QxqHycnaznqtxryvryKXqeebDrBdzm130fKHjt9pTP11jg7PyuoZp0fVcOG097DgpagiOvEzi9wgLB61+iXBHFO9Z0Si1owhkL90b0j6xJt9TtHWQ2hmmPrSp+UKCT5M6jXI5KjZIdTUZ+X4/Pb+U+htH2aXURx6zYM7CVasVutSujIgx7dXJcYJTUdSV1I76OMEnby3jyJ6YRnhfTuMU4V9I7Qu3mkt9tEogvGQhWY9VOFA/y6mcCF/4y8Q/Tf1rXpcCduFKbaj9cTw7if/HtGnmUupPcBH3VqLtcdzPgm2Ynk0x7anPQTxfwcIt42uY2pnjCJ5g06XyEkgajxxn9a1yef4kbISrcepb5ev2GtpCbCmVV/SuodCOyg3xce8ysDLsosOsBEapXua/jJ+TVH+S2lAKTo+2wyt607j6lEjYhdTuJdqGZ8az2lB5rUitxPclitwQbJm/ahofVv8zrkfRx5CzuJXchHZwhNTHKJWr6/YwvYhehddsFKmujLwh5i/JgtP0TPSjFBC1XctIKWnRdE1nJ6l8xp3wpLoah/TKNPrNuNbqunhgXOG7Txv2bCAJrpXqv9ropXuibfGxDOw8riPafJXpQIa75qCWTYJfdZ5yll9J93KQS05Hpo1a3szinnCQ52uePhc5S2O107ZMOwsk62mNRzBnGsk0nHW+5KhWwmse1tg192pL9S9W9yQnar6UU6D51rwIJumgbG8IP2CZkdscp+dZj6u+9vZMq/GojZWA4VIFyxG2dcacHcdK1Uam78zHeQ71nbevZHglt/U8y+YxZ/XmGMumbGPNacvbMecbsJkHFaTKslR6NcvJLLvn1f+LeC6gHRRSuTyPoju1leVfxqHalANe07xwJn4h/rcQ9NeA9WP44hb8yv8+/Mpfw4u/94/x8LiNC7WZ9cgUyw6VOaKtM/N8y4kUHHImBHOesx6WQTU/jyhzn+dATtsyzjyqdaCu3O4YB1+EqwzzCtZjWUeMU3vCwXFqJz/PMjjTxSg9U/km1R9hGT6mLeME27jqiwrOEd0wd13PhdMG7Uhc/ui+jIa82tMVyepX/3M7vxP4Fd/+Qb70l/8o/K8o69RXgS/Dl75KOT/3TjT6Ac5juE+Zkd/KR+ekn/xIWamuI4iL4M+Rtz5nx9v1H9rEkyO2OTqd6+c6ObKfy9Tfgm9GeywZn1118+9lzo6B1LbmblbdX6r+d9VX23V/mRb6nIVNz+AsfhbhvR4PeDVw6ZzyXXNWw0P6X4+1x1nYu9rP41R72RGh+q5hJz3L9/P8ddFHDVN/QXtd9Ns/p1zGU76Eny76y3iox5LxkxVEppcuPJ9WbXX1XY9l0Zi6aDjjTPc1N5m+6/GdN9bM3/mZrtOOeuLDeaqbZVSGs8aV5AOYp085K4fq8WQcnnJW/nXRm2DOY1+mPY4uHqzrdfWzqG4Xby9X5XL7kmd1mSXafFfPfS1fapmwVP2netZVd9FYqfqtYevSOxnmer5IZajq1fQj+ponmOVYCw5oz/GiceV7XbB2yaZMc11zX8uLrrnKc1vzcy33a7lOKt81Pznq30V/cHaMuY/T6rsLrrpPOvrpKl/bF4vmPs9rF40sgmMRbF1lFl11Wd3r0hmZZ3Qt+l/D0qvK1LjLuKht0EW8uMh2UVvvAvd/HO7+uNP1ehRD/zp/j+Ubfw+O7vAFrsAf/2m+8DYlR/KLpeBv/DrO7X6M9xncpOzZ0MkxD/GLacPD+x98lY8MtZ/6WtlWV88ZnJ3j8/hSc9ClUzXm2qbokgVzzs5BzZddvHlem/VYah3f1V4Xv3bpzS4aze3Wn4+jeXiOnDZditzpOu14dtrxLD/P5XJbD4Bf8f/6o5z85nJQz9o/gqsP4M2fLqeuvgXc+Xul7CZwZbf4bA8o9Pyb/zfFZ3tM2Rua+6gRnceh3yKuvKm131FuXpWh+l2PM/ef69XjzxGx/L/rQ1W/rpNhyvfys/z8tCpbjzE/69PdR91fPbasxE5p00fdV9cY6znrgq9uo4tWz8NfDX8XzWZ89TraWYTvRfe6YOgaY30vK6vcb4az7ru+5lW5GiY6ntewdrXd1e4iOLv4qi5b97WITzJOanjq/4vmoes74/N0wSfXqWVgHmOvoxzpfxcuuviqxlU9nl76XbdR03E9D1kx1jJ0EV66ZNki+q/rnSdTu2hgiXb7KrfE2XF2yYKMwyyTzuO9rvnvmpcueUjHvVoOfSd47GpjqWqPBf/Po5+a5hfh4rxx5bbOm8Maf3W5rjr1/HfhvEu+1vDVNCdeXOoo16WjzpOjuV4N13kypYvf6zZr3Oh/r/rfJfe78L0I/4vkahc91H3VVw1Xrpvbz2M97+qiQeiWVXVfGZ4uWq/b7eLHLFPlY4H3oCrzZRMYP4Tv/uMb8Ns24Pdswj+9Df8LvOhwSHHOXqYs3UwoSzk3KM7cFB8NPcabVqf4hX3AytfaY1+kTzIOumSXni1ySOp5rK8uWbBobmv5XJfPv/NzOU1dMJwnY/Oniz+he2xd8NQwdV3PhdM2oaxaPYrfq/hklwYfa/s34/n7FLpawZvl9yjBggF+QeUMb/Bfohyo8KUfKW+2/znKUvZq1H1AWVB7FDDp5XvjqK90B8G0iZdvFT2Y4CX1fcqLaJ9E3f8cM/8Wfumg0nC0tP8efhkhFL56P9rcwcvTa9HHN7GHr1Qa5SOLyU9jjBvR1/t4I/Imfon0LJ7NUn2l3OziFy3O8fKw+HwUz7bxy4aJOk/wZusZTusY45dObkS9DdpC8jDqvR+/V/BLuXMkejfqLuH0htzOFJ+0NAj4ZzitdYt2TvMK3ig8j/6epO8tCr2prlJH1ddBwHufMkcN3uya031m+MWYPxlt9qOfbRzBGeMN2m/jF3WL2fei7AFOB/sJCp2oX6UezPHRtvvxWcU0Jjzq/1Z838cv/NVSvtpr4ploTOk943gmutlPeBlgGq0dAKXpHFN4ch8fDkDA8yFOj+gHHt8LfCsVT+MUXU1wis9RtLmHBe0o2pjilw4rjeFBwku+dqNP0Z7o7pAyhxOK7DoNuMVforkBfiHoId6g/QBvFBeuN6t7uwm3Wzg1Q+PZj/8HUXct3XuP9rwoZWmCD4ESvc6xfJDckwLeTXVWKHN7HOX2A95DnGbWYHrcwAf8CLfTgD+ntZHG2I96m1guZVkg3E6j3DFlrnejrUf4IJ4jnHooPvyJaEt6ZpOiU3RAj+ZIfSgRYwW/2H2CD3PJEXWdtNdQeF1z8yHWM+/F9ybWA/s4ML6T6jZxT/KnifE8xi8uh8KHOtL/CB+60MPp/A/jnuhOgclePBd+dhKup7TTgfai7EXagUTNrWi/T+ENbfLXeHYpenMS48l6cxPLmZWA92HqV7BsYz0nmvtWwNTH+rtHoY9vYDkxoCTZvE2bFybYNhhj+pbsku4bR13Nm65etLePFzYmmEcOKPPzEzHud7GuFA9IXoyiL/HInDKnH9Cml8NoZ4KP9t+l0NoFrMd28aER88DTDk5/kzySDJAc28W6pJanslU0L5u0eeQp5v3V1LfGOqR94E3XtYcP3prhY+X38YvYG9qvosgyYl7936HQjPS4nKXaaduLtrXVBHzglQ4Q28A0uh0wneL528Q0P6HMg/hF+uk4+tlMsA8wP373fxoAcxu+H/hzwF+kMO5bMaAH+MQbGXwbqZN9nNd5Ie5v8JEC+RplQWMfy573ab8c/WncF31fxvRxEPc+xIfkSBZonqRjZFfomlHoV3aSnKJvRP29hI93o06Dbc5so4B1qsrMsXy8BfzhVfiZQ/grtOliG7+8exz3RHvSXQeYdkWL76Wx7XE27fGdgOXHsI3bw4cyLbqeC6dthRIg6FNOdFnH75bYwwT/BjYar+Oc5yEleHCVgrQm2vws7X0FnwL4DNz5kbJKvBp9fRYb7y8FTAN8eqT6eAMLBQI+KYI+Pj3yM5SJXsInXX0Pzmse4ZPlLkQbn477hzE2nbg3wYbZVXxC5lV84owMHhF2VqKfjj63aZ8euUI5OUeE/QZnj+UXzE+wsSg8aazj6GOMnYtl2qdH3qGcnrOT2hfut6OvF3FAKC+T36acqDPDBsH1aE94J+A7wSkEgl1XNi5k7M4C9mNsRAofY0pQiiin0yP7FBq5GWOUoMl7XqYx1rsB/yk2yGWkC2dTHGB4nZKRuxzj0fiWcabuOl7tVX9zfNKWcPwMn8rW4LkhwSNB/AqFznsU46bBzuJa4PuV+L9LmY9LVXv7FKPmmPZeg3UKbSmCtYMVuXChvWIaC5T5G2KFto1P+vs0DtDIye0HnDdx4OINLKCvY2ddCrHB/COF8HqUlezRaXgjylxK6eRLxuQSlhNEfcmFN2jvQTmlKArRjYynPSyTNAffQ5tvB/F/jTIXwu2I9tHIM3x65K3AzfV073qqu03badN8Lkf/4CPEj+OejBuNf5/26ZFHFGV9A58eKT7WGMAGotKsZGC9TpvOZnhfxCexXL6FZaCuO3gvtE630wmCdwKGx5imPhttiQayPngZ2zdq+1WM7+tYZsgxeyP6+IB22s00YBGvQ5n3ixT9NMTzcJXCp1Dm+Uk8v5PqPsbGQg5evobpiigvWTeJcR5hHr8c7cpQvUk5ES6f/CcDSTJKzsJxtD3Ejssqpg/JZY2feLaK5Z70hZzyg+gvy/GVGO9+jPcKZW7k0AiWl7CxdhRwXqPQkgzLWeD0Bj7R9JAyr5+kGKLiZTlUkmkKhE0xPRJtSScc4Ii55l8yZB2fQDnBJ+ruYZ3cYF0pXaF9RKs4GPsZvJ+4F2NYin7Ec/uUE5ilf67hoO3VwMMAn6i8lvDaxw6+ZMos7l9J+JE8VeBGNHUPHx4hHrmFAxrXAx+PYjwrUW+Vjz89cgvvzxIO7gYOe1ie3gk4s+zOqxm69wAvPoGdjGyPzALeT2FbTGW3KXyzgnXBHWxvzKPtVYq9cyXVlfzq4dONn1Bo8WaCXTpzBGXyX4lGvgr8JeA/+9XAZfjTP13uD3B65A6FSG9hJbgTjV0OwMWgEV351De9wCC7S0G+qxT5cBAwiobWA6zN6Hon7n06jbGH6U173t6gvSdfMvcS1qknmJ7u0pZ74FPK96O/1dTeaZSVTf4qRU5CoZ3fdVhk3mfjnuZcsiyfHvmQQn+v4Pkd4QUnBcjE969w9vTIJuB+Ay9YvUaZnj/B4uu5cNr+GWXis0Mk5SaFqwjHE7zKM8OR830KkiUwp7SPdVaElMd2/HqUyVAkf6Iy2Hno4VWZvVSmwS/glNE4oRCVPPAmwfcYOxhSEE/xKVR7FGZt8Aoi6d4yFiJT7BA2tJ22vNL2DK9k7UcbxxV+Dvhom95Hgi/49SPHoEnl+gnvpHIiUMGklZYm7mkuslMoXEiY7SecyJg8THDKCBtS5kxGhNpRJHyGo9a6pnjFNtPNY3xsrQ6YyYqJhD/hQEKWqCt8qrz6UhBL9aToB3i+Z2lsexUuGqw0MiziCeFRODlOfUjgLUX5Pm2D/kmCS/1q/sQbMqIHgU/RveYxt6cV0adxTzSYBarwqD6EZzibgvUYHw6Q8adnMqTg7KlvB5hfNU49lzCVfFF0VnjcC1iEP60QTTm7WVyXxiPa28OOseDei2d5xWmEDx3I8kL0ofqPMa5VTlfGrVaOwHTeYGNO8Ivn8qqhDFk5bcJvH8uQabQzxfJMc9rg4+klM2p5NqPQxSHt4E9D+7CKIywTazrbx0ES4eeAs/u8dqOe9MVR4Fntip8191kHiG8a7CAcYno7pC3PBviFs8KPnMID2ns6RHfiOeH+ANO8HJZ+wqkczIOq7iFt+SMYFeVu4r8CLjlgIZktGtjD0X3RiuZlSlsH9LHjJ3qQIzBN9WDxSpvwLRoWLhosj7PeFK00+ARM6WT1e4RtVOFlhg/QkmxVnQG2B3RvlPp/hOWtcJkNa40NbHA22GahGrvsmzmWP4epzj6ed8EuPjjE73k8jO+82iXcSI5nGpB+zHhpMF2I3+VgSz+prRNsW8xSXRmb0j2y2eTIZtgl7yUfJqmdJ9gpFH6k+xZdks/TgEuvY8qyU+PdY3Fqe25P8w6W6cupTNbPKgPG8YDCO1kOaH7nqa0h5uGGtpzIq/GyNcSnWlEfQSF0GYpSrL/vF4rV/zkc4fsRLGTk9UkJCtAZPolGxHVqvS448njUjMa+gm3U3dRlg2lFcrqHZdogxrzH2ZW2Jn5L5p2m9vYxjaqcYFWWjHxQMN88odgp4hEwneST0HVJJj3G9KmxZfkjmZBlbA/L7xntS3JHuiTLpPOu58Jp+yV4BWEdv6dtGM9lUF2Le5cpXuslbBRcjc8wng0pkYFshK4BfMIR19W4dxOnDcgbnqR+FD1SBFmCboA9/WW8ynMDGxinqW5WPqS2xjgSqD6vR5mjuLeE39M1xpHJVUxkMgZFqINoR8LwE5SI7naFn2n8nkYfUgzCpwIwirrKOVRk4RP4ZDIRv/D4jDKneTyzeL6eYLtJYaYx7VQn4WIr+rwUOLhOm7lmlOiH5uAmbYGvsQlu4ekTmFmGFKYdc/Y9bcfYkFsL3FyL8aiumE0yUHBuJTgl1K/jpfQ9PKfr2AiUIO/j6OzVwLkMEGJMa9gQ1kf9CzZFBeXkqfw1/J62KX5v2jKep+tYcGpFe5zwK169SDttJNMyCQ9K6RrQPtVOikx9yLk7jjJjvBJ2SJv+r1LmfSvqCMd9TC8jvAe7wYaDHEa1cRTjf5bGU7+/RdcMrxZqbhXMUfqF+Cs724ok5/SPWYzpOk7FvYpxLcPiUgduD7HhKKdNsuAKpgeir5uprvhhSDs4I9zp+RZeXRJ/yRDr0Y6Qy/kS/chpG+CVFqXkKc1MzrXwM05jl9KVXJPCXKMtC3qYRnZw8OFywq3KLgcub+LVxas43XY9nj1IuNJ4JDtFqyPsnF7HDqjkmQIngl8yUgE/vetI47mScCFabrCcAKfmjLAO0hiFH+k+4eQYv9esj9+plXF2Bb+nbSlwJ7tQska67TjBLvq9TJs+upy2CX531HoqKydOeMp6U7bACMvDixS6ekYxxqTndvB7QfN72nrx7Gqah16M50q6p/7FEw3Ww3JUJF9I86LovmSZDO4Rtm9k7xzT5n3xzmUsx6/hFMJRPBMuxJtNwlsP06hoTHqlwfYRtGlZTpVoRWOTzhaM09TOdWwEy0c4wraVaGoXn7R3E6/KXw4Y1P5FvA0gz33XJb0s+PK4t9N4dO/jnDbBnY1myY5sZ6xinSk8SpeLHndwVlCDnd5BwovmRs6OnH85bUu0bSfZNpJZH714E+wxiyD+KPAbgd+wCv/uAJ7uwu+nreCkHIR0GXo7fMSo6/HJclyr92s4WCRcZHxPA+ZsA2anDco8ZZuodtoyLeR7Ayx3ezjVVDIL2pll4CAHMfysD+U8XaOtF1V2H78nOd/PfKJVYul5ycARZaou077WMA9DmdM834uu58JpO6FM3mP8otopNswOKERznyIgHmHBvYeVVUOZ/A8pCNyIdpVeuE25+ZB2RPB9fE9Gzx4WUI/w/gsZeY/w5IipJzifeSfgaPAeDAmgb+EIRo8ieDajb41NE3yEIxSKbEp5K9AigyVHw4g693Famoyyh/iIVaVl3Y/nH6b6ys9ucFqbIgeK6h/hg1p6eJ+JGGcPHyG7h5XoIU6R0JL3txJO8j6QEd4XI6NXRpCYfwfvH9Ec1E7bDjY0FPl7gLME5Mgo0qwo2jzwJJwPou6T1O6AtpGiyPOsgl1G6QYW9KK9D7BRuh1zIaUhRdnQzqWep4+iT3KwtcehwYJR42kwLw2xg7iN57lPOx1hCxsOQ87uaVPq0pS2A3s5ldPqw37ChVZSVAbKvGilbTc+T6Ps/cDZLnau5GRoLmeYXxVMlKEoY0iGl1aSSDib4r1LGq+cmPraiTYy7YEjeQ3eRvAQ89cpdlx3cJTwBO/x3MP8BWV+HiVc5Dndpr0qdRplNZfP8IvfoY13rcII5w1e5dignW45xfw1j3uqI5w+xdFTyWoZZlppE1/vYRmmVZ1TylzIGdKYtnCEVzTQw9kGWvmQk7lDe9VCTsw+Xml7StEBW3gv2HK0rTRA8TCBI/HDlHZKsOZXRvZDTDP9VP4SjtbvU+ZO/LCDV+W0cjbEe0cko4gxKIVX2SRNtCP8QOGTMXbaNN8K1EzS7x1sEGvlZYx1heSv2p1iXSHZNKbtqHU5bWrvQRqP5HgTOKj1pnhkiFdEhlgfK7gjPaeVoSle2T6kzPMmlhdN3FdwUDJ9FdN15psj/DJ64UKZIR9S5qpeaWvi91OsD46w3DxIeNR4TgPOEdbb+3iOxJtygLXS0Ut1Gry3WPwoPEhWS7bPAial92mestMm/Sb92dCWp3tpLsSrgk1yQLCAsxokGxocsDvPadvF8kj2ouSFdOohhbdW+XinbRvbk2D936edHjnHOnOYymYbazs9k1xRWxOckkuMdzvBJ1nV0H5NhuZEc/svbaRKm3jjuaISPwp8/bCsvK0DP0w5POKnMFPsYWW+QiHq5LR9C9OGVrc1l2pigh3SPRyo2sY2xgm2EcUPe7TPddjgrNO2G+1vpHuSj6rXw/tN5RMc0tabUObtIbY/tvAcHeE9elPaV7aRNWd7UX6IA2cD/DqLp9geHaZn+dqJehs4M2Ozo//6ei6ctgt4789LOC98gh2pGSUH9YAywOxFD1M9GQIrlHxqXb3og3ve/6ao8OvYKL6V6qzh1aBRtNcETBLcI0xAh6ncGKfiDCk55QNsVCitQVGTT2HFeBPn2opgl/Fq4hjvadvHh59IoGjSB4GzeeDjVtR9Sgmu3MMC/FXaaQxzSh6uHBxF0WR4iAhXo9wYG4c5ejDAe0C2sUASbsdR/jZ2OhSNgZJb/wpW1ONo+1O0HaUxXo5eSfjWpbQfzaWMj1ewEBVzaR/NTZzyJoE0C1hvBRwTLMQvpL407tuYjuVojRLOpAQnOE9+gPcsaMXrKiUydA1Hp7LTdhMbfVKYnwoY5QheCvhmOGgwSP1KGcgQ7sf9qxR6nMXzu3iVFbynbRsbbAp+rNPmw22caqkxdO1pU654gyNZTbT9Knac13DKyHXKvBzEM/HrY8oq2QBHt49whBjsSH0KByLloI8Dhpfo3tMmnElA38O8L5zdw3wj/rxF+x01ck6FsyPMh3VuviLZ97CzosCRaHaOFeTtwMHN1NbNVHeV9kqbaKNP4aVTnCJ3HPdk3IyxgXQJR5cnlLm5ielHBlqf4sxLweeVNhlLkonjNCaVuY0dgJew0zeP7zs49fWQMs/rMc47OODVRPuvxxiPKfQlWXQnPgpWQJFJomlFWwWnxngPGySSZ1p5m1B4SNkSKie+Ogy8iXfnge8naWyqmw8a6cf/VSzbNf9rFDpS/3L6+3jv9t30XPJNDtdlrFu0Eqkg4nG0LfmsVWDRhxw/BRbBh1w1WE5pHDNsBGW9qedatblKmXv1Kb5+Of4rcHCCV6uUqjsJPEpeiN7vRJt7UVa6p8HXOna4xlgevBgw7XL+njatyDXRjhwN9SfH/Shw8Skc+FrB0f5TzJtNlL0Yz16i0IDGdgc7xtcpcyU76jVsI0im3sE0JZmlgPAUr4S/ksahVGQoukrySY79OD6fDJg2o/+rWN9Jr1ymrE5kHV5fW7RXAg/xHvgjbLPoXpbdp6kd3VvBMl8BEPGtLo1bPCiZINvvRnzLNryLgwiytdYodCceliMg+I6xLfYSZ4/8lw3BPbynTRHsV3D+7u34CNkbwL8DfOkn4Re/WE4ZGeNla620SfGcwstf836tGxTZOMG0Iz0q/bqC90nKgepjWhGY8isbHFC+x9k9bd/CeyOh0N9BtPMqDlZtxvM7WJ/KxsrXLMH0MrazFYC/GSgD08Ug+n0V70NUMC7vaatX2nJwst7TpsCQ/BQFfu9S+OO867lw2qC9YqBUJdJ/qmd1Wf2u69b1Oe0uf9pVljJxP7YEjOBvPzlbh6r8fMHnFBsZp+mT/89SG7ks1f0c9erCT25X/ZPq1jibV+VqfOTvbLAuwnmGoW6j7k+fk4626vqLaCSX07hzNJiO+jWsi+io7lOX+ph1PD8Pt/WYZh33unig616+NDeL5r/uK8PU1Re0jz3PtFa3B56/LhxnWLvKyOFYhMOaBj9OJtBRJ+O7677q5HIn5+AvX4t4p65b82PNF118tGjuFtFo3W5dp+t+Pfa6jy68d9FMXSf3k2XPeXI3r1oskhWZLnNZONtn19i72q3neim1k+stGm9XG4v4uJ7T2YJ6NcwnHXW75qmux4KynFO3i4/rOiyoV9NyLTczLnRvEX3Xz7poOvNW5t8ueq/vL8JRF63kMjV+6vu1fuqqV+N3Ubsa46Lx1vTTow1Hl17J/c46ytW81kVTNa938WRX2102CJyFMc9919Ulwxe1mZ/X1yI6zXVyUDHT2CK6zW0s+syqclRt1WNR2Y/6zQjqIuoMgJaUfxj41Bfh1/8g/KoL8O//e6W+8tYrpNbzsUi+1d132QvnyaMaJ3Q8g256ovr+OL7NzxfZX3WbLCifbcAu/PSqcvmqabbuY9H1XDhtM4qXeRjfpziCt4+jVtt4s+kyPlRDUY0ZxWPXStgWTtdYirbZ8vLpadzfwvcU9ThMsL1xCpefwP+cdhrCEe2TsXTC1BbtdCfBolUhPTvAy9/yuhWF3oqyR2m8BMxaGcppcopES7kTdbbj3k7ca/Behy28AX8bpzOJaHSccoOPyVY/h5gQt/HSd8Y3OJVjRPt43mMsR0TcWi7OK227eAVHfSpqqahNxqkiVTktCRxhAdOVYNf/ASXCfYxX0IhvjesQr0Sd4LSZIe2UQI1bdHeAD3ZYSTibBW4bnF6hFIR92puxFcUXrxxjhtdq7wFOF9nBG7R1QpPGowM69ihR6aM0B4dVv+AIt9ICRphHiN8ah/hX11b6nfE4wFFFOZy6lAo0oX1IhFKpdW9Omw7UxylOtRZPaxVHK5GKlh8mPIoedV+HgCglrivFRjhbinrfivv7eA/aNk73EH9ptUHRf8mgHm2Z9BDjWviTU5lX4HZpH0QyxzQkmhUtQ1uhKSNmgFMda1kkup5yVp6JnrSKKNxKdm1hhSRea9IYj2mvRqndJo1dsGv1ag9nYtQrbUPah1I8xbJrlOpOcNpqxnef9use9ExZEuMK3w3tA1e28KEIwpNk/YSSQncc9/cDzou0dYDaBdPybpRT3UOckrSM52cV84h46yFtvTpNODvBgfbHOB1/hvfyqj0SfFrd2sYrRMqSyXKrKz1SMk5yj3SvwXSjdkT7+6m8Vh3UxlG6t4dXiJSWOMDyRzpxD9PZbvSr9PZtnEq+l/AlOfKMdiq/6LvB8kxj10q29J94JMtE6VyNUbq7wXpGfCVZOMOrH0qnHdGWIZlHtXp2EGMZ47lV8O0iPtjrw3Rf6aaSU8KPxpPl7Rxn14hGJzhVVDoAnKIufaDVs6yD6kurE1Osi7XFRuM5TPe6ZHfdnmQTOAsj2yOyPy7h+YR2+uwQr7xIJkhXKUNE9is4G0R95INIZFeBV9r66ncLL01lQw6cc64lwyN8ytYceOePluWv3/8G/KOvl3driBE0GacF9kdYJsiOO6CdWi2ako0lnpRNLVrRamIPy+ABTtHNK6viJclT3ZNMHSd8ZP3YpTfB+uMQ655sZws9NZ1o/h7iLBD1sx1jlbxoMD9q3EcUeTyhfUmWiU8lCz/uei6ctj5l2bHBqQNi8BzxvBll7kf5y1hIX8XL/u9TEHkLL90vRRluOU3mcvR1C+dHa/lT6TRr0cdd4Df8Zjj50XIcp4jtEjaYl3EaIphgBvhYagn8Ht4DN8IpNu9RUjm0RDvBqSZKkRvHbyk18aaUrATsIHAmg/RmwCuj+xZ2hG5SGHAbK8QbOHdbDqEMH3C6g9qVwXUYYyDKXo+++nifxBrt96Ddwo5kZtyr0f7D+C9c3aT9bjSizFIaW27nCC+hj+Jby+FisJUYb06PhPa+rgmmNR1i0nDWaZuncct562EjXamqSoPYxakiUv5NqqPN66KBOU65mNM+tECKTzBKOY4DPhnzSkm5iQ8imeP8/z7eGKssCyh0Ma7aG8UYRVtKdxN/ZYO6j3P+xUP1Stst7LSd0k7JvUlRbE/wpuR+3L+BDZlb+H0tN/G7iZSuc4gNDfV9Pdo4xodpjTFN9Tgr1OeU/Hkp1RexgpZx8yLtQ2KExwE25NRWlklNlLscz5v4XMZpNsJdw9kj/9WXaPYGTm27QXtepljx6BTVfvQxx87aFPOz+hpiRXoD2wnz6Ps2NvhUdhUHcnRPONRc6HAmsGE2iD72Y7zXsAzUpTnciXb7+Bhy4UC8dZn2MeR6voV5WPMrPSLdcoxTosbY2Jb8kWMkupcxdgPLv5XAlWheh/RcwzaZ+ntK4WnJ1z2c7t7HqYy38Z4lME3JUZCT08O69FbC2SdwemQP7+06jLY09xN8uIRglW6tnTY5rSRcSO5dx5d4JutN9SXeG2HdcIl2oPcWbUduhg/6ksxRv7doO4aa2/tR9iY+6EUO+hp2nsaYLm7itMDMVxrvSvRZH0Sia45lwlqC/TrG/wi/400yTrpCRmIvjUPOimyjI3xohNLWRCtEn2uYpjVPOpxM9oXsEvGN9GAT5Wuaeoz16q2AdRXrNChzqBSzVc4eTFFfCgJInstGkuwknl/hrOyeV+2obLY/ss7WdYIPJ1rHtoQc4Js4YDDEPCc9rbnN/H+Adb2MfNkbV/GrhxSM0muiuIUNRXnNN3GkWIp7DytS3ZNn/INfh98K/PbfCfxf4O8f2xOeW2+QcCuZehXrUcmqU0xTCiaLHm5iGSV5uIN14C3sBJPqjbFNrTnq06bRtXh+HfNd1pvQDmIqZVroawJlN1NfmS4OaM+Z+EKyRnb8ZSzjv4Ud3Zu00yPB+/SkSz/A03Pe9Vw4bf8MH0crgS0BrPtCeIMFBDgn9hAjqMEeuQSKAg7suQ0JUgUYjrHwknEg5+o94M/8qA18lQcbBQ2FGB7ThjVHB6B9HO0sjU2TfYA3VooXexRmldPUw5FiMbja0gbtE9obfAepD8EkWParZ/PUfkNbsEho69rDqyXC90HC4wGOJGh1SNch3qR6gCNs+fl+6n9O+yCLvKL3FC9HZ3yDFdtp+q1Ijgx3OWcyLlX/FB+cIhqV0tN/vS6A+C2cjfAxs5rvGV7BkUBQ9HsJr5g1WGnIyFyq2gIb7MvxrUidcNREGzI6TrEB1mBnbCnhQ0JVTuajqvw0tQeOaoouNMdasdB1gFdW5Iyp79NUT0pP9DPBUWTRg1ZPxKdSaApEaJVlH89Xgx0nOXDZadvHq63i4dPUXnYMdGncMtQ03iwD9mivUOv5AGcMqGyDZZLgF55yX0u0cStHiYTLSXom/OzH8wuprvqQo6z9flrRgvZR8Zm/9mnvZ5HjJ/l9iN/DJJ7LgQnZE1LmR6ld8aTGdIj3CYguDjAN5PFoHHJUtCdMK9XqG9qvFcl8s4/nQpF3rW4J31qhkgEjWhFPCE95pW0P07rwJ5rXeMTPgk+yRvwqWNRnP5V/xNnXYuzhlTHhRLoLbKtpzgZY10iXSC/2aQeIRMuCJctPtZEDfv3UnuSecNFgeVzTmZ7JABbdSoYqYn5E+wCaFfyOwayjRKtqV3OrPS6SNdnmkNyX/hfdXYxxSJ9kp01jP0hjVRs5eCQ8Sq+LXyQ7ppgP5vhAkKdpDNLDotuGNo8OsI4a0KaVE0wrcupzv9KNogMd2y74n6Zn4jXZFWDdnB29Pj7yX1lCwnPW4fWluZG+y/On8UgGLZLd+dI8CwbNb7ZHTmjrTMmEbBcocD2lLWtOA1bhV/z/BK9qgp3k3KZk4zEOfrOHVxk0YAEmILOgbPCGL3VySHm/2+qfgt8N/MqL8Fueljc//5TlS87M0XiyPSnbraHolUe0+VWgaRyyNfSKBeEq66QZll976V6D5Yfw0cRzydyntPWmrsxrtZ0tlK1UdQSnbGnda7AdJ1jEs+oj2wSZtjMs0hWa70ecfz0XTtszfHKPhKiMQgmaOT4NTulPioxKQDQ4ijaI8lsYCdtw5vTIZ/gAkFpBCPla6t5IMClCLEdBglz97rH4FKwtrHxlGG9iIXiKIzjPcEqQ4Bmm+nqWjd6sGDewcJ/QjuRewGlBG7TTt4RvKRAtEaufBjuUY9orLY8ws2iMYAVzgqPSmstjfIJoXqKWUb5D21k5TeMGH+IgJyfjm6izE79lXGiMU9onQGrFrYnypzhFRTQiQ0F1NY9gZa8UCNWd4Beq38crLJqDTZy+8mEajwyBBi+hy7DLcy5BJqNpM/WrcWk82TmQAFUqjOS+jEwpr23aK5J1ezJwZQyCT9ZTOSla4VH0JbrSpVPUjnAqwjGF3zbwKXPC6RJWIDsxfsmLBgt3KWUd+38cbatv4UxtKe1BCqpL8Qs+0d4DHCjZiT7Fh4INvHoow0kKcopl12N80ig45TsbPMKtVsHATqjgUn9P8eEVTRqPePMCbQNSMkT1JffEX6f4ZE8pHTkEckZP8MqdZEcfn/CnfvJqzByfqJvpR1HWKe3TERXU0CWHQviXU5WdWBn6K8A3sQ54ELBIXkh2NPFf9CZ8q40hXuWVrfQhnqN+VV58JjoByzrJjqdY1h2ncqr7BKcS97GB1U/jgbZzeUyhN6X2yWBREGUHB4LkTI8wvmXMk/AqXbGHD9ZQGTkvtdOm9iT3wBkvklm13mxijBqLnDc5B3IupOeUdTLFUXk5yDopVv01eE6lDzYwbYvW5BxKRmiccsrUXnbaetggle4WXcrQbCi01094Fh+ItuSoao7ex6uM0pHiaen3Bp/GKP2eHU/pbQVJBLvmcJuz+7j2sIx9yll5mnFzgnWWnBoZq8KnDGLpZumJ85w2HSY0xQ55tmsUIJQM+Tin7UPaNqCM7myP1Lp2JZV9jDO/trF+3k7jW6bg6wjz8ITu0yOlFyXTpV/Ej2ykStsUptY9EYgmQh1qkqQENYgR8G8Dg6c+JeUHYfD/bJ8eqa4abD8r0D5IXYBTEWVrC/bstD3C2wQ2OOu0PYq+NjAN7uBVSbUp3hQMqjNK7Wku5IBJl4C31MjvyJds2gf4MDfRnmyYBq+2zbCs7uETLi/RvqTzN7DtdB8HAhZdz4XT9kvw6X+X8UlmMoLnOG1IiLmEBdEAn6Y2xEd0r9FeaXsI/NRfgJ/AikXv/ZKyGUefE9qpCMMoJ0aWAhjSjggNol9FyMSo66nME9rGy8WA/2KCYT3KyujtB6x/HLh5Ff7MrtNARbhytrJiXEv31nDayDD6EJMJ5lGqL3zLYJ1i51FlR/ideT1suK1GG1OcyiXlOY8xqs/ThNt675DqjrEy1lxfoK0wpWRW8Ht2dE3xSZUXcdRwDSvOFbxaO6KdvilGbhJMaziqJjypr1nAeYV2nrIElOZCdCI8rtJefVFAYDWN+xJn9w2v4nQRzdUaTpvs0z46XTSjcmtR/xmO7C3jE0LXsWF/OeEotzdP94WLMe10IV2iafGznst50vzlVQzxnfDe4BPOlit8z9LYlzC9DLC+Et/KMJ4nnD3DKYMazxrdOe/P0hhUTgabjNF1bBCJvzRG8ZdWooSz1Si/nnAt426MT+kT7hra6ZGi2x5tmhWOc0qseHqAX6EyxbJL+l/ztk57n4d4VvOjcYle1lMfWk0e4wBPVuh9PBeZznKUdQ0HolZpywzh9jhwlPsTfMKRYL6CV8Y1z2NMU+NUXnwoB3sN2z0yZtXGMW3DT7jSXIDlptoZY50mXKxjxyLX1WqcZNcpft+Por/g+ZfTJmNX45QenFLmRDw/S2VkgI0TXOIh8ZoCcmPaJ/Xl8YOdBuFb45nhbBfRmfTmYSojPEnn13JPeiLL4otYZ4zSGB+mdnXvEuZlyQ05/Br/lPYqiOhiHOUk72RgZt0luGXwivfXsKwWjlejTTk9l/DKlOZIQQDhWjwnQ/EyprMxDnRrvDLKs/yRTJODmh23p3julJmgV/sc4VRI0dRjnDafxygbTM61+EgwZB1eX7PoSwGhLOfGWN4IDjgb2Mn/s62Vryxb1J76kdMmWad51arRlcCVbLM+bVmsuodYToiOSWUFu3R5H/hbPwsrP1uebVKckNd/sbTxTeD6z7dP8t2jzPWN1IeCkuM0hndx6utXfhi+cg/4VwM5LwHvwLcP4YWY3G8/gT8V9bK8V8aXbC/Ne9ah4skBliG6Ztgmlg4S/qXTtQ1DOkI2pfTHOLU3p/2aCdE+OEgpfNd0cYh1MtiW1XyLv8dYxo7T/VxXl+w/0abKrXP+9Vw4bf8MO1dydERUui+vW6s7UpgNXkU4xV6vCFJe9xLFy/4xirMjAdzDEYEJ7bS+nMYwi3KKSqqPbLAocraX+tWeGnnl0E656OMVCCnlPo4cTLGj2AP+IHB51+2oTzltEqxyFvdS+xqLUj807gYbGw1WrHs4MqRyMvKepn72sHGY8Q3tVXpFXDS/clikaDSeLDQPaKd5nNB2lsVcMuCEs8dVO9kYUGqIIoaiIzmlU9rRljleIleagPAtGs3769TePo5+NzjAIPhEV6IFzUE/4VFGrODQOCZYKM6x0Nc4NLY5xukklRetCU4pPc1BFqzikYNU/qijPdWVQNP1OJXbT/D3YwzqW2XA+6glMBucWruHVxQEn5QBOOU2r0ipjHCuOVYaymlqW/SpNDE5FTJ06kvjBq82zHGWwASnBx7SNlzVrmRCg7ckaNy7WCmJLuY4FVt4E3+RxiO4VhJ+9lIdjUc0MMDZBFqxybKowbJQRuU+RR48wXM5oS2f8wq+7uW5zU6bxrCHDfs8Rjnp4hvdy3MjgzinR4L5QquaR9GuMgnEh+IlrbKqL+FqjPEtY0p6qe4jR5dz6rLo4ACndUl/SZaoz10cIFpJdZs0DjlwGo9wC6Yp0X2TYCfVmWGdJRrq0U4XVkAn62kdlS6caAUHFjttam8v3Ve6nXCQ9aZWRyf4ALBh1a94dYh5d45x36eddtxLbSqlahkH4kSDwpkuLVZk2SVdnmlFl+h6iOW4eCSPSzq3wU6HnO9DnIJ1gFe5FZyRXAVnsUgGiUcbvOon+SlaOcSBsxGeQ9GqnolGegk/oivZRyT4pOOmOLig1UvJVOlm6S7ZMrUDlS/pEtU5in508FeDeXKXbtldt9dg3pPMyDAIJjm5w7if6UnyQnafZLvsU7UxS3UlJ8D6STyn+2pbukxyGYptu5PGeZ+yZ+sq1p37+IX06mMfO8py2pQVAvClHwJ+JwWpb1FSKRt4QRvKZ/DCBE4feJxge6/BNCe5Klmg59KDu5x12hosm0R/B6k94aOJOoJBKbHHqT3ZSQ2eL+FQ/JPh05Xl1DTdO8Ryr8H2imhR455WdXVJN2X/QzR03vVcOG2/jPK+hBHlnQVXsHO2hx2PNzGTXqfQjNKo7uD3Zkzj+8sUIr1PQcQ68Hnsna9GnS9hj/xOfG/ig0g2o85X8OTJuBnTNiKGAecW7Q2pX8bM/y42xAbx/QUsKG8An4uy2Si5it9tdh2nLZz3nrY3o8wmPkBCG1m/J8a3FeUUFVb9L+H3tN3Hy71SJIpWfo4SoVii7P0b4c2rDynvmbmHTy+bYeGxFf9vA9/AOfUSVC8Dn8ZCahzjuIsNPQK2NZye8L2cXWnTNcLpQV/EhqHmY5z6IfC3gVdj7+AMggllPoe097TtxLhfxkaFDIGV6HeMIz69wONVnCowxumh6/g9fTKaFaiY403bOzgy+oW4nwWzxiPltk2Zm/Xo6wF2wBXp/gR+9+AjyjutxjiKq6DADo6EiceuYFo+xYqFhIsxDgZ8pCzw/qpNnBo1ptCqUh8uY4f5Bj64YBblNE7dl/EgI0gRY/X9OdrvaduM+RlSgoxdRsQHOHAypMwtmMf3AxYpRPHpbZxWdx+n+F6lyAvN2ZsJ12vRhiL2n064fZf2nrYTvIpwO3BwI+7Nab+TcgsblQ2ezz6Fl8BG3BTLM8kWrcJcwoc3KEXkJkXWyBiT/FzFaWyiFzlzmovLtOns3aj7ybj/QfzODvUShUdlFGqe16PPuwnXTdz7CvA2hY6+gIMAL0dbMhKI+q9heXMTrw6MMe89on2AyTJ2ZN/AEdZdypzqXWcyYq5iY/bT8fv96F91H+OMi378Xwv4VvHpaOsxB9KrCpgsJby8kp7dwodT9WlnslyhnUJ2TNGro5gPZQVIjk/Tb9H+gLIaIHxfjfY+wC8er+W49KZWba5S5mYU41QgSfdWsHN1Hculx1je3sJ7wPZjXu4EjCvAZ7FT/SDgWMOO3BgbedIJ2akiPR9RZMi1wKH2jSpNdC9wMcAOqGhpHOOXzv1m4PLL2Li9iI38lynzLafr9RjDZsA4jPtXMS3v4NWDuzh7RjJrhh3VUYxBMnZCO8VUNPU6dtYuR71PYifxJn7n7DzgEq1JFy66tvAL0sVXr8a4VzCPvxI4XOpqJF1yVtSnHKlsj8wCrldj/KNUdgsfTCH6u0vhT8lc6fJbmIcPKXMrOaHxHFLoRXI6B6trPfTNgP/zeHXndtRXgHibgu9PYh24jVcOldUyIGXFSOn9m8APAn/+ffi7d+GvRMXwdr7ngdOKr1DshQf4tOmrFN5ScG0JH9A2jL4/x1mbTTz25XRvKdp5Fcu9pxR+ew1vN/kiZ99vOo5nOwGP9KdswBc5+5402RpfxKueDyk6+/V4Jl2v1X0FRPrYr1mjfUkXvolP+pZM+hMsvp4Lp20CfB1HxjVwMaJSAf5mPH8PG63yzvdwapkU+xTvAVnCKZgb2Kl6SCHeBxQBoEiVJnac+pAnPcFGjowNMZsciX18THOf9guEt3FkdTnqPIu23sVHpRJ9vIf3AOgErFWsxCVUZMDnaKYYUMp8hfb+gy3aqwsbqb4chgletZTinWCD8zjhYSfg/DDaUORDOfNS2jJy5JBvBF42aJ8IKTxt4GjGNs5HFk5fA/6PwA8BP4dXrHTNAldSDFqN0craFk490LjEZIr0NOlbxnxdV33tx2cD760SLWhOhlFWTolwIgd1GxuyY5yu9TZ2ABV9UkRaOFYUcBXv58oCUQp2H5/s1cMGJFFnO/DwEBvnivYPU3sNdu7FK+C0Kl2KWmnvhhw3XTJ0pDymAd8epjPw3hcJ7V7At0Z7n4civ+9jh0BRRjm3iuKB512yJ+9pu093FGwv2lckNK8MbFNw/Texs629AZlu9nAUUM7vA4rhn3EteSaHLkdbJZN0iQ4lj4Sf/XielYjopo+NX0UeB9gJlLGYnSStAjUUw1GO/zO8x0cy5hRHIEcUnO5jGZaDRrNq7HN8HP9GjGcP70PJcyNH+j5eCZBizatQoqmaD5VitBv336W9H24HB5weJDgf4MMKnlDmr4d1RI7CjqO9BgczBphWL9PWR5Mot5PqyhgTHT3BKfCS7dBeGZwmOHv4xFft6bgf9d/HNDGM9raxjDrFqxxgnSKjVfMxw3MrPpOu2MS6WePU0drZSAXrzSbBs4UdMY1Nx+bfx2l9mletYm1Gm1co+jXLZ823VtyO8Z4x4VJ9DbFBv4WdqwntlWzp0j0sy8UjkokNZetGP2CaRhs/jh1TBVzl5Cit8AgHtnpYZr6PI/oTrFcGONVftHKAHbKdNDatlol/lcWwg/czS55qRWcn4NS8bGLjXPpQgdDLtFei5PBc5uNX2iRPZ7QD/bIXDmmvepx3SfflgIToVnVlC+zjlEJwkG8jYNdiwkNMt3O8HeY+pnnNnfqZ4lR6yW2wLVDLOrBckFPzIPoWHqapLfH1CQ6O5JU27cnuAUc/D8NBDOB3ALfuwr8B/FvAn41ON+CrwE9Fe6vYcdL+sW28+KCxHCZ8D3Bmh64ZDohnnSD5qFWuJeDn47lw1mD5ka8H8Uy0Lv0pGt2K9vMlnhFvgPegCX/ZJpJ9IZtA8mlE+3o7xjzGtiL8/0l6pBT4EOdCSwgowiMvWUiQYmgw0Y2xYBhgx0aKT56whMLKgnukNnV/SBEiIhKlG0mp9FK9y3i17xQb3dmYk+Oj8SjqrD4VIZBjKI9dY7wcbef+tVqQnbYx3pQ/Tu0LP/s4miGilIC+nNqW4sr9DBNMMnSa1AdR5yIfraR/pIjG2OmZ47kaYgMH2vMjI051cwTsa5S86h52VmoBIAZWREn40VzJ8BmlNsCKqR7z5Rif6srZPIk2dVy56EC0MMDzeIJpTOPqp3az06YI9hCfVilHfZTqyUgSjMvYGdV4RK8ZziW8Uqk5uIjnT3MgGLKz1cPG/BDzSaZlMG0pTUbvj8tKEcxrMgQyD49pBw2kyIQjwak2wPSyjA/GUMRumPpVG1ISMurFc13R2my8ia/yvJxi+p9gp20c5S/QTgvKNK9+hWsZrcJDxq0MFF1yEHpVecmHel6yrNG4lrFxIT6Z0pZnRzhopH5kfKiOcKKxZz6bYN4TvUtGiDeI+lLsws8kwSLZ1MPBiiGm92F8xhjXJPjG6bloVzgbcZZGDhMusuw+wUdNP+Ws09bj7Nw1VTvCj/A6xg5Hrpt1Zw/PgWR7rfumeO+ODLyV6vlFvIotWTKK9iT/5LQp6KWAqeZbZUhjzoHFPt4rnscj41JlshyX3pQeEMwy6tR/xuMypiXZBZLjsjWkq8Svl7EMU/9LqZzksnAvmaBxrNDenyvDfxC4VTnJNxnpma9kX5ymNkfpW07OZdpbBjRfl2jLQsGu+grEZFqZprLCSw+nlGenTXSQ94xqnEfV88wbWTcLH6LFrF9HtOe+65I8zYGDzMuSaZrTj1tpO6It/yRLsj2S8aM5BK9cix6zjXWAgwcDTHerqW6mqX4qr7LgtNZs9+hqElyiVdGA5kT0lW0x6exxfMsekawbypCYJWD+UADxJyjeyNfg5R8qB05KfqxGnwooaF4yPrPdknlNl2y2bEPMUp0xXiyQjhhFfye0eZv0fF7hAiwT8z1dWU4p60O6dYx1jOhcAQTZJitVXV0XsT11gueh7r++ngun7QXauaRL6Xd2iHKUIUdAcgQi11tObRH3l1MbdTn9p2pb/fUX3K/hUZt5LLpH1U5Xu7nsjLN95bHWcIOVRS+V69PGX40LGUo92sqmxmsWFjU8ub+Mc41HfSxV9/K48zhVf5mzOM51oY2/GocZ3lyWKKeIc56LXH/OWdi68Nkl7HO9/Omn8rlMpp0uOqtxkcemsjJS+9WnHk+fs7is288wZbiWqvZq3OWxdeGxns9aCWUc9eimk5r2BFOe23xfZTU/y9jIIdXR/Vw3j6++umhz3oFLtZ9xUc93nudML8JhLfe65gDaMiDT7BD4iy8BN+Dbf8fGzh42fLU6uRftK711Cvx+HB3tGmeet5NqPDIEallZz2kvleuis1ou1XqD9LyWXTWNdvFZLlfjW3AtcxaWLEfrtlXnNNWp9UGXHsh0U+s2qjr9qu3MV3o+68BbF6y5TJbVGR/Qjb8u+avnoomMv0zH5+nCWtfWeOuaj1r31+PI/WU817xZ65rMm5ku6vbq8rldBUUWybPcXy2j+5iWshyr5VD+XeuVLj1M+p/xKziyrsztztKYumi+7vO8/xkPtQ7PVx5v1rldtLVIduer5vM8r/p9WpXLdJv5pi5Tt7WIh5cWtPNxY6ntrzw35+mMWm5Ixur6q6dw+8eLU79OSR18l3hH6p2SSnzxFfjKr4evzOD//XeKDrmNM8b2KFkdSjMXPPs4iwzKytMz2letA+jASa1fu2w4jbeWL112dk1ztVzVvUynNb3WvNhFyzWv1n0sup4Lpy1fUuynHd/z9Jzq92kqm8vr/lKqc5rqzqvfuY26/Xl1P38vdbSZ21tUf6njWf7fBUvddv28hkk4yHDVfXXhA87iNffV1eZpVWfe8cnwdM1FxmXXeHO5+qphy+Oo79djzeUW0UU95kVzUM81dNNnjYOu+ci0ex79d9FXF0675qQLXs4p31W2C3f1POS6fRaPQWVOO+p10UuP7wyPXXS1qP0umM+7FuE3j6UL/i581fyU/9d187VoDlr3PgOsw8bf8YqiUqAU/W/wYT6rUWaKV2666C3jYdG9RbjNTuZ5dH1afej4zjK1i35yu4vouUsG13DXcqyrnzlt2qzrsaBunzZsXbID2mPQuBfpj9PqtwzQWoZ14XeRrDtPFiyCvat8Fy5q3Vhf581blyzJ+F8EzyJ7YxEcmW5rvVfDqd81jDX8i/RElyzJ/3MfXXUWwV/TRqaBDFMXnhf1xTm/a3uiC2eL6Pi8qwsfi+TOovqiu+wI1rAtGtN3Mv9d9FnPd1c7NV/UVxctLRr3x8muDNuPYgfrCsUZe4+yerhGrNy/Bz/TB/4A/Jr/kJJj+JPw4g68qPdrrFK8tuTVXNuHa9+kCLsjePCL7feOdtlsXbIy46OLv+qxZ9x08cfH1cm/u+y4j+PFeny5j++E5p8Lp02eOZR5Xaf9Lo99SoTndXxiiw7V6FGWH7XBd4TzqV+jHUlYi3tKvbxMIcTX8FK74FD5tfg/iv4bvP9DS6rysg9TuS0K8pVS8hrtpfTH6feIsll2TMkFvkF7g6T2/1zFB5Fo826T+lca6TS1fS/ujRPOlPL16cDPhYBZxpqiHfdwvu4Ip83N8KEDY3xIRR8vU1+N7xXKnL5C2ed2hA8iuRLjnVEiOMJhjiR9Mtqf4P0SNykbfDVu8H7EpQ58g/cozfG+lllq+xSnz4wTvsBL8o+j/ksBw3Xap/OpP6WZ3YmyyvM/wOmD9wJ/wvVRjEmbr0dxX5E1zf0VvKdJqT6nAWsfpwodUTbqXk39jqPNOd54P6TMzXrUH+NTnvqUeboe8EKhuVdpp22Izj+MvsaYDtYxH86jzCOc1iy4JHglyO7h1LkRPu3sUno2x8cI9ylzcgOn84hf9+LZAOf3azVpgmkayhzcwO8bUmrDCmVzf47q6dpMOFsJ+OaYXg4DFjlF2odymzbN7cR/4Uww3aOdDreEj1DOuO3h9Mg5jn4vUTY3vxjf2qizg9OetJ9piHP+9Y6xW9Gm5N2N6Fe8N8YvvL9MoZcDnCIieabUtr005iPME4qoiqfu0k4X0XguxFiksG9z9iCSl3FK0GG0uUb7IJI9nG74WtSdUvhBqYgvUfhY/AKWZ8L3TZyOpLSj19M4c1RWeu278N6F3Ximg0gafBBJQ6GV1/C+nE+luqI76SHNgcajOZKem1DmRenuyxVehLOblHk8iTKreKXlGnYq1Y54UqnWq6lvRbH7tA/JWgl4XsH6YhPzTJ+zelOybxw4eCl+byXc3sEpd0eBv6u0DyKRvJW82I+PZLb2st7De6Mko9axHLmYxnkrnu3hPUxgnh1G21cD509wipVkzSt479tx4PsVfGT/KM3FHMuVBsthop9PY715F5+6dxW/IuAaliE7+DU4d9LYlHYpmaJUxmvR/wHtg0h6+BC3e1jn6zVNtwM/36LQ2DW8R2+E6Ue6cNG1hTMDpN9fwjbebjx/KeCsZfe8+j/Ce8V7CV/9qs465kHp6UPKPN7C2y8uBh77aXwDfJz+eqpL6ifrJ9kaei6dmWECp9Pew/rsFsV+Upq0ZPft1McOZ9OMc7rpWrT3CNsBR5S5vIbx/tEmxU3gNwK//i/Df/mbitd3ARNLXmbfoXWk9nf9Ynv/+xTv3/00pr8mqnwK0+hW1LmLU26z3iTV3486d7Cd3WA76hZn6eIU20lQ9KXsONmTwqNw0kQ746i7Rvvao8iZezHO/Sh3i/Ov58Jp02l7e3i/iojqAAvADSyElrBBJqNtQkHkLkUgblA2EO5G+Wdx7yHeIHuSyj3G+570TqpneBP4Bj4adBdHnuUUSmht4JOLJAT0wlbwy7UF+zGF1i/iSMP7CTcqJyU5SmOXYFqiLViJOtpUuoPzu7dxrvC38AZcCTq1s4GNiB18nKyUquboAc7t36J9PGs2XIRzMd4Bfrn2Ce0XnItpBnjjtYwvRYiFd7Az0Is6SuHSNaN9QtVh9KlDE2QwL2Mn9WnUPcWbifcp9HOKTxDboX34xhSfGircH0Z7y3iT/IgyvzqkZRM74TpRLBs7wtkjvAE2R2ZktEnwqj3RaN6DplcXyAiSUfIh7Recy9CWYBSco6o90bP6Fy6U569LQRi9x2ZAex+WnLYH6ZloT/h+QJmPPbw3USk6Kj/D8uIAH/ct2TJN7e0lPG7SPiBAc7cSZbqinHopq2hPPCc50eCTybYxf4LpRvLvMMG+HfVFK6R7gj3PwTZn39MmuJSmNAW+slk6Fc9De6VNcmwv6m1EGSnRKW159iFWUsKv4FNwSopvhl+aO8ZzK6eth41C0ZnGLj5UgEpyXI5cHR2XUSLjWPSh4JCMGcn2bfzS5SXax83v4OOste9lG8sz7WfYxvN3EP9zipIciTE2sA+xDFlJv4VHGbMNPtFTdZ9EH6PoZz/KXcC0At7DIZkt/bUU30+xLtoJXAtnCix+K/Cd+UAGsw5jkfExTriT05ZXziRPHlPoW7iV3myiTJbjkj/SA4J/iOnyGAdPtrH8OsHvhNqnzPMmpukGnwAIRcaKlxt8iAf4hcJT/DJr0V5D++Xa4BQo6UE5iRrDbhrXJnZORVub+KTfIT7cRzo6yz3J8QGmxyf4kJI97DwcRN0LlLndx8FoOYi9qKtAUzZ8T/HLtY9py1PBNMAv127woT8Nlg3T1N4A67mGs85JvnbxvD8LOMYBt3TqQfyuDeauS4dnSHcpeCR7RDbNKWUenuATo0Uf2u/3Id43LbvmFL/TTjhU3R0st2SX6tUbU87SUK2HZHdJLu/E/RN8mI7mZZq+FZwY44NIdNIlWDdrfvo4OKs2JgJAx0VuAPd+E/xu4Nfdgq9snT01bAm/oToUvarrmmFd9366JxkoednDvDnGryfKelPXNpb921h/HmN5Ma3qyBb7AM+Z+FH73fc5u6dN9luDAzH5Er/exwcHyf4473ounLYT7ODsYoH4DBsDMngm2BsXsmqnTQJxCysR8KELivRLEIngG4zYg+hziok+R/NknB5joS0hJeUiBap7YjT1pWjiMT72ej/61aZF9S+nTKtkMkY1fgmV2mnbxs7TDL/4UQQvhbGNDVXV1ylccpT3aSsnGSDb2OgSvsX0ci76qe05Ngy1GpFpIAvqPkXQ7VGEWDaeZQyBnQEJtq2qnRkWnHJSRFNSGqKjYZQR85xSaEYnIQ3SGKR0NUb1pXJZ8GSnbQsfRPIIG25ysDQvwoGE4wS/y6hPe4ldxqiE8jZWpDJkNJ4jvGo8wMaHBJ6UhOipn55JUHU5gep/Oe6L53Tt43cHCd/iIRkFMhTktMnJE79JCYoHRQfazK+ggfi1SeVkiKot8ZcUsowAGWR7gUMd+tLltD3GMmlAMYCEE0X1tzEtqC8ZTwpoHEQdBTDED5INYP46wqfVkp5lhXOa4BJ+Zio4aJ82Kd4UrWk+l7EhK7pWQED0vhuwPKUdcBNuwXx7glc3DxPudE/9K9iR6UzzI6dNwQvRka5s/Aj/x9hplSJt8ErRFsUYkeHex8FB8KoceM4UHJjigyvk/I6xfMt7F06iz4upvSfYQZRyX6adjjrgrCGguo/xAS0N1kNZhuiAAdG25lF6RTJCOBP+ZlFmlNrLjrHa206wD2nL8UVOm2hZp0WCjRfJwSzHJX+kB6SnhjiAI3gH0ZZ0/AzbjA2Wt9PUX0OhKcEhXhaNZDtC9omMRrBOkP2Rr2xwaxVFPCI7ocGno4ofTzD/S8802PmSQ5WDy1DoR6uKDT60R+0O8EufJdsVMBKPaGyPcBZPdtpmCT/ieQW1xWtyOrIcnWH7hfgvGSyZrxMvz3Pa9jG/iYYVhNzDhzbJ4O6S3fmq7Q8FwDIMsrGEv0EqKxocYqdfDsUBdnqeYccV7PDlwI7GI1kH7T1P9VjES9vx/xG2q/Re3kxTwpn0vxYXTjBtaVxLeE6XsC2U8f7fzuCXK7I1jcL/EjDYgj8XgP0oFjw92gbspH3aLQk+yWfdk3wUjfcwbwoPDW29SYAkW+yAIu/z/CkgdVLhNtvIcgJlk0juH+BAiex0yf5hepYvvYohB6OU8XLe9Vw4bSPKNosHOFVCBuo+djh+A2b0mxTFeJ922oEQs0J59867tN/Tpnf/DGm/p+1n8FI6FESuRR157D+ADd138Kk4y7TTI38g6r+Hldi/jA3Zb+CjpJcpRu3n8CE9N/HmfzmJywHrlSh3nTLBOcosh0iTvhw4U9T6ZvR1iWI0fJqy+XMrcDXFynAOfB92cDaxQpEAGMfn8zhV9f34XA8Y9J62V/FKwDzhdiv+3w681M7Yy5R0h4t4JfZ6tCmhCD76WcrmK5xNjxxyNj3y+wK/72LmUurfzairiOYehUbv4HfyHHP2PW2KVr8S41rFTryc5Tdx5Psd/H6/dbwS982ED839tehDRoWUyE1sCEmBvhm4kkAWb2gVaD/wplStHmePF16Pvu9R3q25Q6GbEU6PBL8io8fZ9MjPpXLbtA1U4TsbPuD3Fjb4aO8m2v5Kws8aPlHrOn5PzizG3+B0ahk8Mi70nqQPsKB+E7+nbRcf4z2iyAbBmS/hTAL6+3Gg5F0Krn8DXtkVf97CTskmXmVYp9Dlz0T578O4fhe/p+0yTu/QMxltooutgPk2To3hzYKMf+VHDMs27VX8fewg/QA2wlai3A9gebaJ6XuVMg8NjiDfpLwTR8aC9PTlGGP9njaNQTJRY5/jjeu3KfS4SZkXyQI5FHfwitYh7fe03cHv+2qizPdFe6P4Lfq8E58BNgzuUvjh3ejjeoLz64Gnz+FVUskzBQ0mlHlbj/b2KHN6F5+wdwHz7jzKP6HI1jup7j5FbmoV6TF+P9bbmDbXYw7U/wi/CmQNv5tLOLsV/csJuhztvUeRBwoYySH+Mj6G/1K0J/o4oe20gldwh1FXcm0r8KqAQaazd3F2yTjgeCnGsoX5+uWA4atY31zDpzDuRr+fx/JC9PsF/GqqAcUukfG/kXCpYNgY66oXAybZowqoyRgfUej2Kk6xnOAsn73AhfSWAkxfjn7exemD70f734udoHdop0e+kcb2Oo7qX8eO7lVMKwpCrFFobIxXO2WHKzD2IOpKxk5wMG6LoqvW8LaLtzCPKGVvGrBcxau7IyzbPsH5hzJs40wZOX6vxLi/SnEuHse9z9Etu/MlO3GAHRXxra45Ze5kpw7jvsZ9I41hROGp9zg/PfIgyiiwkQNecWbUR/yjVf4aL+9T5knvCH2LQmu3sROzQ8H3bdrBlosJ3inlJG45ims4mHuDYsddxrQzpcz7L/9V0fk2hdm+izI5j4HfBfxW4E/+B8AfgW8dOpVSRtcUvv9vmH6h0No8+nsz3VPw5VWc4SU9dg+/XiDrTaKtt7Ct8t20tyH9HEVX3a5wu0GRsV/CK7Y7nH1P2wo+OX5C+9T3e/hEYV29gOX7se30JoU2/gKLr+fCaVMEQd8SmHLIRaBKp1pO5fpVnUFqR5Gt5Y57Ofo5qMpA+2QYefUD2v33OAvLUsfvpVSPqv6idiS4T6png/TR8rva0bWMo5mKbOV6y7RxoXKqM08wZxxmmPNHuOnRxhdY6KktCf56LlSvHksNZ57H7LQJtro/qrby/AhXeXz9jvrzjjKCYVbVI91TOzXe6va7xpUNvXruM60ucXZOZlUdzW8eT8ZpPX+91G5NBzUsdXs1fvvfQbk6ciierPsVLi5UsOT7mc9qWtd/RYyPKzzPOTvGLlqvL8mcPA+k30u0XzEwT/UyXLl+vlfTiuaontPct/C5XNUbpD8KMkB7vK9QlNefpxgOamOO01AFX42z5fRMH7WdcVSPO8uOmnbqMS6iiyw7xJuZliVnc/1Mhxeq//WnR7duqelkTnt8XXKza07rMeW6A5y2VtdV4K6WFZledU8rJZrHmuZq2QFnYVO7mR4yHvLYSW0If3TA2kXfGb9U97vkZYZjmfYYL6T2VL9r7tRmTac1X2f5WNsnghPO6qdB9RHMXTSS5Vgep/o4TbBOK7hqGbKIpmsdT3U/yyw5oae05ybTahf9dtFOxnGmp65yi65c7pSzY6rtvo9z2vIYoNu2yvipeaSLXrpop6b5TDMKvitYkvvIc1/roYyL2o6uv7M8lezQfc1B3W6XrJM9t5SR12VQ9Sme4Pz3wW/65fDib4MX/0v4r/9+8aKCwLpsNo0n3++yl2v8Zh7Qle24+rns7EV2Y5fN1mUP6rn4UbB20XIXTmuYu67nwmmbUqLduzjSe4yX2hVtfA9HDLRiotxh8N4TRW7fxftfevidPko9UkTjXRzpFsIeYY95J7U3ob2M2eDJmUR9RVYe4mXTdzGj3cdL+/0Yx0b08SFOrwHnqvdTf4qe7eH9D2J2KWWizns4rUgR1k18AMKDgEMv83yY2nkPHwCxg5fwT/Hm44YS5RnhlZpt2ntlMk6f4UMaHuO5nKQ5yEpPRLwVfQ6r8ancDo5WrFAiI1mwKeVMdKNUgfcDx9/C79UY4U3J4BULpdQMaKfNfkDbgJ7ivTZH8Vz40njewytCGvdGwLUc/T2kfTiD0sm2aadp5rRCRTCn0Z6ixAPaLylu8LwO8N6nbdovBFZb4AM3tBqQl/sP8JxOUl/iOV2PMO1LyDW003vBL4IX/+1iensPpz4Lp30c7VXKkPh1P5WbpDFNcMqZ8LiB90BpvjXeKd2KfxunrWluwalfgnmGX8gMTh8a4jndx6u3m9G/aAX80lTNa3aoFHXOskA8u4RXRT67UTr+eTy34s2VBJfw8pUL8P4z+GsUPnlGW55tY3rSqpZwu4f3eUg2aRVFsmgXr7QtYRmxgTeV5zH2YyzCTw426JrhSHJD+7ACEq5FM9IVuxSZsIxTjTRvkgdS+lo1fRpwasX0Gd6zJh4WjKI7RWcFi1ZEJesGOKX6lCJfJjjNXnUPcJZBHx9Eshzw7US5I7y6doRldI+zKW2iUaXq9mI8H+CVfBnZRzHe9zHNjCgrXaKPRSttmr9v4pTMHbwPq09bjj/AGVXixxk+fExzPA98bOH9QRr/AG/DuB/43cLpwJrT7Sg7xitJDwMO0faUdir5FKdRPaG9p02G5xLeSzzBK/oa1zejnOyLk7g3wvsG9wLmUwrdnmLaOEj9DdM92VUf4nd8PsGBgA9wRtOTgFv6UHgEOxS7cU82mehK8jrbRqKpEYVPjvCL5xU828P7zffx4Ua1c5KvRwlP4iul7ktX7eN3432c0yadIj0+ie/sxMzxO7X2aOs56SPRnpwayTi11eA0fuK/0jezzm2i/HGU05zWsg6cCfV+GssMnwshPXccMCql9hF+B5lkf9ZRDV4RynaAbJ9ZlOE+RWDLAABvIFPHK8A3/1sY/SX4zfH/dwI/Bnyt0HK90rZNoZt3q3uZxvuYN4d4u4n4RtccZ4U8jt+a6yNM5xPa11b0+Q28WvYIp1eKJ4VHbQGQ7BeM4452D3EGwQ7eh3/e9Vw4bTOcg/yYQkyZcBsK8T+kIPcAGyH7OMooY+MAKyYxrgwZ3VObVPdENE9ob5w/Sv03OHV3ipntOGDRhtYDLBiVWgjOnW6wUJNjuB/tbUdZKQYpSaVCaP/ZIWZiGZ5ZMYqYJSAlFAdp3AdR7oT2njY5i5NUTnhUPrxgH2JjIjPeAXYQ5VBIyRzhPW2neK+fGJKoJyerwYIjR5XAe2NEFxnf4LQsKYkDvKn1GO+rWcaCTXjIsGkPySnekL6HoyW5L6UI7uF0Xzltwplw3lCEwHGUeYRTgTX3U0zzh9hp08rocjxTGtou3qC9nOA5xYb1PlY2mj8pbeFWKwcyLgR73d4+5ovjVHc7lTug7XDIASaVBytP4Xcf73UVfx3ilYEedl5lAIhfFfRZTm2Ij6bpOdioOcGHq0gRZ5zkS/wsw2wnYGmwY7BDe1+l5kz0kGXCKW2ZJNkA5kMZdFJKp7QVq/oQz7aMn0Dudiqv/T8DinH4owHPJeCvPCurb/+HS/A/e1KCo+Iv9Sv6PqK93/MQBwMkm2SQi68lX+XYiHY+pH3gzSmFLzQW8bx4TzIwO0jCfzY6pSPknNc0JUdQART9Fl/sBUyPsHN8iA/BmuGAnYIh0hEzHIiTchadKfCzH/Br/5sCTUepnOo2CZ4elpF5X49wlw1cyXnhTLpTzwTrSWpXxpBWNcCpaTn4M6R9iIT6WaIdcBPN7+D9w9qbLFmc5bjGozFqrmWoSR/JUJITIn04wXOvfmfYznxK25GWjpSTJr2mfoTnbEBnmvtoFYL2KpsMQzk6kv8KovVpbw0S/wu3ktunFB4Rnagd9bWNZchuqid5LuNdtCx5OqPQ2DDa2uXsQSSSmdtpHPpuEi603eIx1quSD5IN89TeJLU15ewqV76UUiqYZU9o3KKVPWxAn3c9oh0Ie4odctWVzTjEe0fhLG7zQVvSm+KbWaqj7ywnsn4apj5zxlY9FtldCtI8xnTZYPqQvSAaVgBEvKE9bepTvCM5orE1qZ0j4B8/g39BDH0Sg5fRJEMmR7D+91hQfwX4fjj6vG0FMJ1NaQfQHkc12ZXLqQsFhfMBTbpkx00wXeh5DhzMaV/ijSyz97HcHeLFmSbhRLb8MT6IJ1/i1530W4HS867nwmkbUvYtfYCP1VTURgbbjJLvKWF2neL13qcg6w7e0zaN7zcpXuyYgrx1Sm6zoiOXo84X8eTdie9NfGztpajzvfgwChG6Iop9vNL3vTiyJOEf20ggYNrFnv4I79+Y0N7TJmGwTHtP21WKwJaQkDCQkjqN+1/EK0U3A14ZTG/gPW1v0t6MTtSVklOUVYp3H+eofy7h4RvR9vVoY5uS1/0KdpBOAq/X8KrIbbwaITyBj+tdxkx2k7KnTY4btPcVae5zO9kxUJR7RtnDoHkcRlIp14YAAHPMSURBVJ16T9sJXgXTnrablJz7Ce39cOprJ8b9Ej6xTAbmSuB2jPe0EXi8GmU2KFEzKeAreH/ZFO/LkJC5jh0GKbzPUvLQRYPj6GeOVxoeUubmSuDyPj4KXDxzHb/WYZfCq+OO9uSsjGnvafsMVs47WDBlfOegA4EfrbR9gFdMxvHsQeBoDa+03cSvPphFOR0mchNHl+X8ylEfpb4/R/vI/02KnFjBe9q6opzTuD+i5L7LeRxFP1/CdCRD/3bCwWbgZS9w9mY8u0/Ze6MI39sJ92u0j/x/l7azPMPK7nbg4Bbw//hH5d4XUlkZ9CvY2VQWQ584PfFJgfVuwCeDahPvkRwH/g6xc3KT9p42GTRjbFwOaa+YQqFfHSFP1H8v6tyO+pv4yP9sIN/BQRLN85Vo61O0Tym8TNk39A6F7r+AnUAd+b+EN5bfofDDWuBb+1jGAe+UQkc6GVE0I0eyCXysB7yPKHTxKj7BVqdkyxh5HWc13KW9H+59fPT1Ht5L9BY+FGc9+pRRLDnfq/CioFHe09bHe9qG0ZYO5pFD/AW8wqA9SdlpU1BJcngQcPcp9H0t7m/y8XpTfHUV71/7ADtDd7Czr9WA61jGy0D+LD7e+yD6/J6oL/n0GWxQrQYcawmPY2xsv4jls5wQyQoZmS/jPW1aAdlO4/p8jFeG34xCS6uc3dM2w3vamoQ30e0bOODwGt6brr1Y+5y/p20UcEtmZfviAZZT4i8Zw1uYpl7Dr/7QvqnbMfYDimzIe9q0L2gV67RF1xY+bW9Kke2vUPYpyZHfjXuSdVl2z6v/G9huAge8MgwnFFqVnTpKZbfwPuVRfH+KsuKzjW21dc7uaXsXywmN55Ayj7einIKcWqTI1zcoOPsCDlp8kkJve3jv5E28p03B7THe7/kMrxCC97RJjt/DgaVM6z8KrP10KXcNeOXvebXzIXD1H8Cn37Fd0Ys2vwZ84k8XGvxd334DfvHr/K0wwgXjmOLXSadJlr5C+3Ah8J62xxT9L91B1L+EbZXvpn3k/yWsI2u6GAVuNWfbFB54jfaR/5dpZ3Qs4z1ta7SvWeDni5j3PkOZn/+Yxddz4bQpgqCo8wqeIHnS0E7dEfH20/8hNoLkDOn/Urqnvi503BODDtJHzHIxYFqh3a+cNt3LcPRTH1JiK7Tz3zXmldSmjN55aj+P82JVXgZLjsBcwCl4anOY6nX1p/HPU3kZcxpjj/Z4VwIeCYsBbTyupLkg6gmOC9X/QepD9Ue051pRwDxutSUhq7Z05bzoDJ9obTndF44zTuSk5zErClbjUGNUGT3votVeVb+em14ar/CY25ODUveR508rwHnF4ri6X89fjza8GbZh+p/byzCJ1jV/KpdxnGmodtoyfkV74gP1nWlC/DxK7Ylfh+n+LNoXfubVffWr35ne5FjUl8YjnAkvohfdq8cqXMvA1HgupHv5OQmGC6mccCt8aXzZ4MhzuB/PZQxorJr/GT7pTSu0c7zCrKBPP/V7nPqQzBBudV+0qt+ZN8TL4kPNTx77oGov/xesGneeW81v5r267pC2LOqS5UrDz0YZqUwO3FzER3ZnealxZPmiesLdhfRfeMxyvKtu3peS51pGUtargmHOWXmW4RvhV2Vk2ay+lImS50p4yPJ3muDo43kRnvN4Mp9cqNpZNM5cX/SleqeclaG57oi2Lq5tCNG2cC+ca9yqRwWv8Avt9Mjc90kaV02bOSBZ65GsGwRLpu8831lmTxNuF/ESqfwo9aG6csD7VbtzvFLfRVMXUvkVvEqVP6e04a51eH3pufAsGZR1ZMbrx620ifbE55l3deV5zDpwimlnRHv8GnuWR8Oq7oB2qjupXG03ZVmiK8uQmt5FIxnm2m5SOekMwVDbVFkOZHppcHYP+H2ye3gLzE1s2ymrR6tMHwDTF77Od/8W+Mq3fxH4dfAXD9n4HX5VhHAlWZ91cpatWaZnm0z0tYwDY3p+kuqOaF9dc5Zxmz/CbfZdalrJ7dbj6CpXX8+F0yajb4pX2I5oL5Of4Nxy3TumKBVFJxqcZ99L5ac4ba7BEaxn6Z4EsyLVgkWKs5/am6TnEmT91I/KKGIC7XSRPAbBO8EploKJjnLHlIkWLEdY+c7SB7x3SfidpDap2mjSmJ7Fcx3rmses9p/Rni8xYsaN8KgInPoSQeteTtfTWGXY5vlRu8d4n5aEzyRgUhRHbenSXINpoR7bUsKlcAyOKNc0Krjy6obGPO0ok+FR2zNMJxO8EpQj4nOcotdUbcnRURpVTi1W/09pKz/h+ymmi4b2/PUSbJoDwTTh7KW21LfmJdMynOUL6D7yX+nJ6lftKjVM8zHEcya6EC+r7lNML3ke82/xjMoLL5Izetal+DUmGaYT2imCU9ptnWCaOklls1xr0v8n+MrtqFwNBzjoJdxmmhV8dd0pbVp/lv6fprFMOSvPRCd92vOT5Zlkh5zZZczPYCcw4ztHPDOdK7VRH9E+MV49zzQpo67G9YA2/Sqd+Ig2n6j9Wp6JH5ZSG3ou/Mv4y/N7IbUnetMYhXe13SQ4cl3dE79musgy8GgBTlQn6yz9z3va8tgE35w2fUuuyIhS37PUhvhMeBaucqBDMjbzkMYgehI8k1RPz7KeO0o4lVOf+b9JOHtW3RPeM24ER9bF4oNjLL+lx3TJWM182DUfE9rplyc4VVTzrLFm/V7L1aw31ad05HEqk2WNZJPoXnALphPMw5qjjB/1leVTpinp69qGUlnhS/Kh1uH1ldsWvrKNV8vTj3Pacn89rAfzPMomEU4zzJpXldH9WscIv+LhJpXppd953sD80+W01bIo6/WntPm6wXaCyi9jGZ/nQjSX6+Y5znNY95t1gOYgO20Z30uUFbk7/1e4+PKvgj+4Ar/9X+PN3/FXuU8722I92lnDp0dejedXKCusgqOe81ofNAl/te2tS+PLc5Zltv7P8Z5syTYFOUTTdbuagwltmXTe9Vw4bceU5f7d+L9D26GS8vhZvHF4gjcgSxGvxe8H2OvdxHsUtNl5A28CPMApAA9xpPoR3mO3S5msn8ETvRm/czRzEv3/DD4uvIl7X+NsOtEu7SjmMJ5JYAo3W9G+6qzEWB/j99hIuMxovwvnZ3Gq1qPo430cfX4Qzy5SiOYBFi5fT7h9RHuvQ4OjSn0clduiLB0fRBuPMTHu4UMGxpQl+d34/wgf7V6PZ4YP1Vih/Z4vGXW7OEVS0ZLMJBqrVjgO4t7XA74PcARJ0f31qDvHB0rsBH738VL4Ju1I5RSn9O4FvsWMKqc+ZngT8ds4rWgHH07Qx687WKWkXB2m8Ulp91O/02hvGyt9GUYyhpQ6OI12e1W/Pdr7sjQHwuEotae04Yc4tQna+xvntN9HIuWTI1viP/HFMY7Yid8u4gML9jEdaD/D+7QPb3iCeS0bRRKUosHThLNnOMdckVPl0tfXboxHc/W1uK+UmUncm+O9XXOcBz+g/YLdw+jzfUqK4tcTjkQrIwo9ZMd+CytB9SGZd4zTQvbi3jbmH/HmBSzjDilyR+OZUmjgBMuzOe19AiOcjjPF+0rExzI0e/gAJqVLiuY0BkVLM51tUWhZ/L5LeyXnNL734/59rGAF3zHe1yQ9skKRAVuUtMIeRV4IbxtYmcqw3Yw+9rC+0UEWktfSPXLcFAgBp9sdxlwcUWhhI3C7i50X0et2fKtug9/5KGd1FPUe4EOF9vER/cKL5LzorUnPGpyyIx7VoV5Z9sjQzzwywsYUeE40fqL+w4D9nTSerDfFS7XebKIv6e8hlmNyAqXnFIjYx3r2EG9f2MWb/xt8GMJ9LMNkVO3Ef+m0acI7+JUXDzhrePXwCtPlKCce2cMHoegwPenhE/wqik3MDw/xyo0c0c3UrwzG92kbpru099/sY1qRTnyM34WneRLvSifvYFrLjon0/CEl3Uz09gCvxGpPlGTjY7znS7pRY+ySt7r28J4+BYNI496nvT+7V9WfV/ek+6RP1F6/qqNg9ph2sGEP72/fwDiWTpRNNsav5lDdTSwntKdauko6VKt80jP52qJ9KJ3kleZCdLaPZabazvbIs6grp20c3wf4MLVvYtoR3pVVsE+ROeKXBs+v8K25EJ8tY157G+CHgB86Zp2/yu/7EXj9VgD/i8A2/Jp3AwEv8tGy26/5ajRwC3o/Dn+Ttt4k+n+A5cYA65pjfECgZLauh5Q085WEj72ExwGWQyMs4x9gvp9y9iCSjcDbz+DDqN7BftCi67lw2n4ZJbf0ASX38yoWlHt4k/z3UhD+jLKPYBXnqd/h7J62r1CI4AHen/MFitEH3lf1JkboHQqi9a6ZdSxwvoKJUM7MGBufh6ncVjyTQv8yJsx3KIT9IO6N8bvOnlJo8fNRdoIN06vxGVPyvbexAa0oTF5p6wfOTvF72lYxk34mxrgV5ZQKI6PiTQrBHWKFrQjqfsBxOcHep+w5EXzgPW3KNZaSX4+xbAa8L1MUplbhZIjeodBGDzsuN6JNOVngOe514Bvaq2FjbJC8GThWuukQ72lT+picxr3A212850MG1JC207YdY34ZCzMJyCHOt55SlDIU2rwaZb6J90tcSPi6htMQpLBP8XvItnHA4wv4XU/aQwQ2YvYpwugejl5t4IhfL/q8jvex7eL3tK2m9vZwGsQYK7NrlD0ZMqi3ObunbYwdADlt2mfaUGhkiyLgLlFodSOeK1DTDxy8iIWx+HWXMl9SooqoyWi/j52cL9B+T9tmjPMi3tNWR+90aqMc4y9jZ2YU/XwZOz1SFLc5G1zaDZx/JZ7dp9CocP0Wdt7XKHn5wu3btOl8hgM+twMHN/E+t5up7rcodDPC+3t2YkxfxlHYXoz1y7RPwz2ke0/bw+j3M9hZlmFzOcYoA1rpkQpafSGNlaj/btS9Hbi4T+ExOX3gPW1ygjTPi/a0jSnv0fs5Ch19CRtuL1H4HWw83cX7gI5jvOP0mQbscgjUlmRnQ9lvpOjwDt7TpuDXCu09bZ+m0P83on/VfRw40Z7iPQpdfDrwplPp1ilzIL26jB3+K1Hn1YSz27Tf07aGT3S9iud+EnW0B3OLxe9p0/iJPt6Ltj+P9cUm7T1tXXpzF+/rvoP3NiryfSdgkByYUfYfX457ewHL5yi0KSd/P+69RHtPm4y8jRjHWhr3GMuEW1g+K7ilS47vy1iPiy63MT1+HqccSldKV7yN9818g8KT38fZPW0EDrSXeJ9CDzKSr0cf+wHHp2NMOoxsjUJj44D7fc7uaRth26nB77yUQ7yO6fAowT3G72k7pPDOdayPJdNX+fg9bZsU+p7gg6PuUXhrGG0+intfijpZdp9W/7+J7Q8FXahgmOM9bbI3wfsFb2GnU7bCN2g72ev4Pa9gZ186V47uId7Tpmc5PTFf71Hm6c34v0Lh4TvYSd6myPyXsJO9jedGtvMKpt01HMy9SbEDxEPXcTDsBgXn24Gf1/BpvNsx1jdoy0IFOmWPfo52auAA4E8C/2Pg9/zrFBf9W/AH/mHp+B6OzktQvg73ftz7rldTe6fYYd6h7F99I5410dStwFtNFyMKDV2Je1sxPtlCO5h2pzhYsIz3tF2hfU0Dlq8EjmYU/r8N/DCLr+fCafun2CkQQUhoKSI6pwhtCbkpRTBvYeNVDpIiUop66dAaRY82KNMvBXYp3ZOi2cERhO1o7y1s7CmqrahjXml7Cxt8h3HvHUwI8vZ3ou5F/MLrhzjiTfzexs6UHEOtPjzEQkbRsOy0vYMPgFDd+9jR24i2RGybqZ23o1yDDUo5U4f4iO8cWVW0WlGqvfg+wRFKOR3b8X0afTxIOMkGWI/2YQcT7GAKpx/SPjZbEUtds2hDyliRL70kfROvmmo8gl3ORo6cNzgSLuc7O217qZzmW2lXA7ypXJGt3bin8T/E0TcFBOQYbWKjRs7GFK/IyTh+D6+CaOVKlyK7iupcDlx+SPuQp6MYwwk+jCWvRurK8B2mZ09ovw9Mp8PpkAsJbF1y2hRcOKJ95P+IMmfb+HCSPk5n3cdR6reijmSIVtqmOCqs9oXHd/GqnuZbY23oTrH5ENOFeF08olWDt/BKkfjzGNPNDo6KTij8eD/Ky1gjxraFjcx8aWUIHBUXz2o1VkEwyUtdu9hgmeAo7TIOKkg+KNAg/vowyjfY0W6wUppi53CGsxvGMcZdLI96OLVsjHkRHHzqR/sbeO7ktCmae4RXH5SGpgDYCTYaRVM/F+1tU2hgKepqVU2v7SD1o1W1Bu+P2sD7KPejPa0CamxyjLajPdHJKXbgs7MpA2qC6Ud1nwQOR/j02L2oI52mPuQ0HWP9Jb21j1Ml5QBJlojfNyiy4RjzgYy/dwJ28csY08cMOzbisz5+rYnkHpxdact09gDP2z6mMRnoGpsMz/vY0XiKX0CueXkP76dpot338MqHeLPBdodwKcM60+0E6/08b9JhA5x9sU17pV/jei/hRrry3YBdelsHr8wDPzOsww5p72+/j1dBGhw4HVDoucG0IrlwiB2oHj4sTHM3wwderdFOJ5c8ldwFZ7I8jnlRvzt428s+XmnbwwHC81badhMcmmPZQtJVB3jP0MelRz7ENih0r7SdYhm7SztdTkGgIX6F0xRnM0lOHeK5UF2tyoDTYvXaiIY2DWW7R9cWXqmRHaZskUPMz9L7shE0J2Pa2Vei3f30rSCCVmVFv5r3AV6lPaHIHtkYChQJl0u0M8W0lyvj+iLw3VuUVwLs/yfFy7pNceJ2gJ/Am/i2otLAr53KelPXBpYfl9J9rbRlutUl3L6b6iirZwnLeukAyVHZo7KFcn9gfn07tSeZdN71XDhtPbx0LoGvKOAULxcrGqFyF3FahuoNU1uKHmheV6p7KpvvaZJXqrZWov8+3uyscjIaT1O5CY6YDWgrsTEW+CLYcQXD5Sh7lMpl/Kxi5TSI8UmwZqdtFRtscgwzfi5SmEztDVM7ikyCDZPleK6+V/DKlKJ6GY9P8YqcVoDm6Z4ErqJwGqsMI7WvKNAwjT87d8K3mOgybQGgumBhKsdfRomUtHCsOZjjU0vz83FHXeF9ksqIkU/wSlu+r/rqs0+ZE+FCfej5ECveOWWuFHA6wvs8R4EnrWBoTubpW3CKtxTYkJIQrOIRRZezMQ1eiRnQ3oCeaRnaRpVwNsTzLaN7jHnrCd7jJngu0k7PXU5wrkRZjf0ER96VYjINeEQv4hm1Idw2CRbhqL5Eez2KUpZwlvE+i7qa69yXHNcGG4JZJmU5JnyKvy5WuJWRRcJlnge1qxTlrnkRD4k2+lFOgQEFZzJ/ybjQ+MZxX46S+lUwSEb7OI1RNCeDRFFRldGYRlVd4UJzq2uMZabwLRyM8b5ctSlZKKNY+kLPJDOgPT+CZSW1X893dtqyDhD+xb/KGlG7edyXMU/nuoLnInbK9PxiwqtgPsIrwoJpBb/LSjjTqZ1aJRuncWbjSs6Ygix5vrPTpr6ybpKuyOOZYFwPqnakA0SHWefLcOzR1nOaY/1fwXypflewTruU2pTuAcsJwaGxix+gTa9ycHQJrypzGa92yvjV3MkmkE7P7da6Y4z5SfZGnu+sY0Tr4pcZbdo/ps3DosODhEfJAelByVjpCzAN67nkfZZB0Ka7YyyvdK/W4fWlwJroKvOydJVW+RbJ7nxJ50qPK9iQYcg2ifgV/C7VcRp/nu8j2umfGh94vgSf+HiW6ovPBrSdH137LJZdavMI87Xo7TjBI74TrYAPKDumjVuV68e4FBDJ/C/nTbBoDkQvz2jbAWPaq5orJGRqBWYjOrkH/MkfgF/8GyUXUkw3Oot7XaKPGc6uEn5kH+XTinUpCJ2fKStlnNqULFOgS7p0UbsX8Ts9j2nLpPOu58JpW6YsnzY4dWASn2yE3KIgcA2nCT6lDPZ6fEb42PnbOErWoyxP3sbL5pfxUrWiNlrCnOBj1qVI1J48azFpP31WcFrdQXyvUFICckpJXpkb4eP4NbbbUfYpPtZcuBnHWPs4IihnUhEU4v4t7DC8GH3sJPwcxLNbtCOwxL0VHIWVEDuJ5+P4vIgZUquB16PMSfy+HTAqWrOGj3nW3E5wJF3zLlzofXOjuKd0tyyItUJ0MT3XpVUCtaF7L+K0DgmQcYznZoJvigXzVZzWMcGrjepPjqnGrTQACd1hwDfGqaaPos1rWKEe4OjaVXz8/ntYwc0psuoqTjGUAX4jxrCfxqXxHGKD9mbUl+O0gR29K3gOFAHK6WBqT8bLKm1Dex3T8hyfPLZN24GV4SMaE+1Nop4c3kvxTBHaNc6mRyoyfDuNU/SgKLmUkOSMjCzhTMESKc5RtCEeztcc07/KgaPZSp0Sb4q/lFIiJ5P4Fs52KYpPtAKWZ+MYe8atnum/HBMwzb6I6eTFNIYlrEQbTIOSIeB0xyMsz2TIyZC/jI/AF15FPydYuYked1K/cr6fJvxcTmM/wTJT9HhE4Yl6pe12lP0QB1HW4pNlx4Xo4xbmw5t4teNmPLuPeVh83eD0SCnwfcr83sJGtOSZDKcJ7SO/V+L+i/F7K+C7jvf6fBKvvOW6I5w2LGNuFct20doVLGOPaL9cW+mR0gG70ffNBP9lnDZ7lfahHkdRVjy/ig3uXoUDBQQVONnFaYW6ZIiL9nLgUPJ+lGCUYyXcvhjPd7CxfBWnsffj2fXA67ewEax7WikRnTWYt9bx3OeXiEt+K41StAg24q5GH+upzVO8Gq409w2sK28G7NIza/gAkk/i9Mg9bBCL5xTtF40e4aPq+5iWZatIN0vmLGGZpYCwVldUTnTZYMN/nTZN7WGdcQsb9tIvkr+yzy/z8emRgk36TjaSbDyiTd37OKdthvWJ2hff9lKZdcqcXMFbbQ6wHTOiyBHpggmm+5WEl/VUt6GdHnmcxiP5q2CL5GS+Mu0vUfB9I8adZfFN2kf+S2et4blT1gX4yP9TTCs7ce8aduA/kfB2LcrNMZ9rHMKl8LqDA723ac/3CrQNEKKxnyQ2u/4N+PVfhl/178DhFz/aA5RpLztAc/z6rGnVbBPPbqZ7uqYUGr+J50yOteZbdrwc4oay2tnHNvJa1e778S28bGIcn3c9F07bP6Y4y8o1HdNOYRLBnVIIbQML1T3KJLyPPXW9y0dpS3vRz4iCyE2cy3sRp6Lt4HSSfRwZ2sNRRMG0TXv/laIRMgz3aaemyRgFb9Dcj2cDvEfpG5Qc2gdRdkpZPu3Rji6PcR51Vohghutho3cfKy3VeQ+n/Wnf4AepncM07n3sRMzx6sIAp4/28J6D96KNg2jzLbwsL4djjNMU13BqSY4ibQY+NrHBtorTZoTTffxOogHtl/CCl/UlSCZY2c3w/h3Nh1ZlwalkE7ykv4bpdIe2ID2hGFIPopxglyDuY5qaU+hvh3Zkfi/wIcUxxobhN/ALigWfHC2NR8p1jKPrg1ReQv4Q7w/rRb+ivSWsaN8J/D7BgQJFGaG9n0GRM6JdtSfHoqF9cMcKZ69tLPD3sbM1xC9V3U1wSziu4T1qcjAm2Ig8SvjRb6UFEf1J8IrupSjX6Vb8+xj/fbwXosEyQEbJHm2FKLrJhuEI88JeGjc44KQApPhsjjdG6/8p5tlNbAzJQMsKTXwoZSQjrJfKz3D69CThQjBK/q1iQ6qJ/9/EDp5odwWnHWY5qjFIJmrsc8xra3iD/wPaq/M9fMDQVoJlFG29m3At3O7ER++r60W771OMkPfxXt8PcIruDK8yDdI9HUaxn/C0hPlyExt8TeDw3WhD4xljp0P971L4X3WfJjxJ3q8AP48P6iHGrtRN4WWGg1wrFJmqZ5JvwucQp7PL4D/FK1SSZ4r4KysDvFqn+ZnHs0eB70PsmO9jZ0sGrNqR3pQeuBQwq1+N7e24pzHOsW0wwPJHAeAN2if1rQe+l/F+1Sk+1GeE7RNF06Hw0yUKrWve9EwyagOvBKrdhsITsi/6eB+Z0vFWsI6SfBA/yHnewY7l/YDjPk6rPcL7Tvs4cCVabrBjIVqUThAeJccexzj2OHsi3wHmtW/gvbUK1qxFufcCvnHqW7p3SNsh7rr2cbqz5n4b2wsNTlvM6YeLrj3aB4IoDVL/waviOudAek64ldMnHamtModYvspJupjq7iT4ZviF6ZtYTiuQmu0eXY+w/dzDqZLrFBnxjDIvl6Nv4Uw2nuZGcyV9qEBME3XfwvbMJZwKqLRe8fJb2GY6iHsKZginBzg9cjnazfM9Au7+VzB8jKP2MwrR9KOTP/HjMP5x+N9F538IfopyuEdD20aZ47Rk2ejSn6Id4Sdfe1jvZid9Hx/q12BdJZkompNdf5H29Q3a+zE3sUw673ounLZfir3s2xSgZQQcYIK/h/Onr2CmGVCiCutxTxsaFfXaxsjTcr4E+Rpl06Tu3YzfisCOUx+v4X1uUij/n/beP7jS87rv+1zcArwGguU11ltul9pwS3GH7JZrUjukJdGUKTJkaDGUnNSya01cu7Y6aaZ140zradLOdDpNJp2mnantuI6nrpMmThvVrh1XsmONRrJd2gxtmsyS9LIwd0Ci2NxdBGsY8N1FgGABX9z+8Zwvv+d9cQEsGYkLle+ZwQB43/f5dZ7znHOe85xznqw09imT9hBl89fBCsk5qm4ey/iEYIoS2DqFTxvPxbcb8e0YthRr0WujJfcbCVEpheNRj5j7CbwIJynBmpMUpnIOW9OkNJ3DG5wFfLmsNjtSHM8lPIjR6sRykTKn92IGn3HfwxZGxYjkTdspSuIA8EZaJ6aZeUl4aWwP1+qRog4+Kd2KvmszpXmWwDkR3w9wttFxfInqHVhRzUqKlJj7KBYo8GZFbZzDrjravJ3FinyOVZzAiSeOUdaA6IfA3x14s7cZ9Z6N54pp0OZIm+5Vyvzci0+KtNGRkjVDWVf3UtbEVcp8aO5PRr0v47iSLMyOYVoGx29o3BJimkfNofAjoSuFRPS2gBVbKRc6iZai+edjPLP4JFKK0Q3MS6SAgpM8iPf0MD3cxWjB34u6pNw+hJO9qM1z2NVJCpBw18EbEAl+8STRSl63otHbcZIMqCY5kXK1GP+fTPhZwqcPAm34hHNlFm1T1hI41uwGVX6mzKp9fBKuOLJlCv08gE//tI4079p0aNMrZeksNpxB1T3yFKbpk1R5QZtivdQmSwYTnQLrVG0Zn1p+GK+PB7Gh7e74kXJN/H8GW6ZP4I2KDA0P4WyqUvrGsYv4WRwkL0X6nii/gzemMrqdxYay06msTpLFf6QgqX+9+O4oZQ4kV8Xnx3A2Q41Ta+k43th1scueeNQAr6VzePMr45LoQ3W0Ge26/wBWVLQp78fvzMclN1eirWP4BOkyPj3QKWcb06yUZMUUCacnsDzrB95O4Ridc1Q3ijKgacOVeddJvCHpUz1pawf+TuFEGzIaKM53JXDRwRuhLXyJsOZZ/HVAoTMZUYQ3oh2tudUY13UKPR6LeqQgila0OTuKTxDGqG5+JUdFn+fwZlcb30m81s5QddmUzOjHeI9HPeJJMkhP4+RYe8EiPjEWDk7HuMfwGr8P+BAHb9pksBEv6TPaPfIoRR4exTxjDetYor1JjEcZBjvYU0pruM9uo9Vm1HkKe8FIHozatMn9/xyW3SepJoVaxCe92uTKCDMd/b2BdUnVq437nTFu8Nypn3dE+1cp83lv4HMl2jhO0Rs0DtW5g0MEpG8KOhT6n9pML4SgnVTRJvAtUcGvwQ9+G2y8XHSvvAkcUDZZq9H2WSw/1ymbfeEnwzxlQ/UQ3kAvxfi0dqSPdbFHiOILjwQ+urV6nwv8PBP1vUyRQyeBX2BvOBSbtgEWJmKWm+mZ5qiPmcMG3jjJ0tSnIOaHfype/g14/JKtD4uU2MWNVL92yfkZWBkfT8+kiFzHTFuLWotA3+mbGzimTNaatVR+Oz2TEFyjmrp3HSsza1HfBFZGtqlaMVXnAAsPKWI6rdQ79aVP9fRBZSTQNDdqJ49d9Y5hpViKVx7PNSxEVVbj7qeyEvKkvglfsoD18WY141TMrM/uTdtG+l84EA6lyAh3ojf9rfqldEmIr6e6xFfEdK9TvYtHtKC683zr93j8iH6k6HTSe9Wlvon+8/ypvk6qXyeoYMuuxiJmqo1MFhKav9xPtftXngT+Itz36WLhPo6Vu+eo0jJUaV8MW0IGvGkT7al/2QUm90XjFi31o8x9wJ/9LFz/O/AXMb2sYUtY3sDldvvpvWhmJ3AmesuwhoUd2Gp8PfXxOlYstE41Rq3x9fR3P41ZZcDrUJuAjNv6Gt1O/wuPfZzZKpcVLtQv0d8EVV6UT9C0vvSt6CafGqhPwokEmsrmdjMfVT9IY9epQ6aBjfRM45bCpXWiPqt/a1RpKuNbPFa6QaapLBv6qbxSgKvPOmnPPEnrabvWhnBwPdUjfi+3yR2qPLjPbr5Hqlvjz/QrOZfnUPxU7eU5W8PuwbmtLI92Uj2iZc0ZVDdtGr/4Rm6vTg9aB5IL9Xd5TOJFOk3I8yF+PRhRRkYb4TiPQ3jLOof6qnEJhxqX+jdOlb+Bdcv8jeSY1qXGlXGsOrT+Mx8QXShuaCP9aE77mG6vp3YmE05EyxrzIH2rtaS5HeA1fKNWNvNL0ZB4h+Yi88e8dnPbJFxJ/9oLcnuZj/ZT3VkOj+LdGcSv1Q/Nb14D2ziGchzLVPVF9Jj1C+Fdsl+0P0p3aVM9tRR9kN5lvSfjQrSv+b9OVcfLMiDjS+PNJ3x6JvzfSGVFm+J1ol2NW7xGuoTmoI83UVlXFF3lNab+fAKYvgoP/ZKfnY9+fXDRusavA/w2nJ6Ef3gP/NBv44xTz/P2YvzkLD4mO0NRFCgd/66LlN3nnTXkLlB2bufY7RJwD4UgVinKzBEj8d9Tetyp+K521PbMC9GXp6O+8xQr1XHgb7EnHIpN2xS21J1j75T/T2KrgSwVOko/g63J/K/ANfi/L5Xd6ywFd8ejjjbVuKqn8K5eO29Zeo7hU4Wn8Xy3qfq0j+OToCfx3TlL8ftJvACOUeZ7Cp8WPIpdHk9RTfmvuIyTOG31SWxl6lDNHimF/raoZweno+2m8anN+eifFqsWktIPL+O061KslnDQ5OM4++BrOMaQ6OMDlHm9hIXBMZzyfwefsGZLFxQLxSPx92K0eRfFGq5xgzNDthO+s9Umb5Cn8cnCY3hzIwtmPeW/3JOW4v1Zqin/sxWUwOMCTvmfrX767gnsXqm1/ChO+T9LNbnFnZS5V5s6nSDGNSrl/6M4pu2glP93Rj8v4k3cOI6jewhbtD+ccMQPAN/5zdz35O9x33PwT7ZtZRdeH0/tLlDNVNjBp3xi3mDaW6PM7RyO3Xk8+ikXVgl3+fBD0MzPnOHI07P8w38fB8mt8rY0HF6z7/mLFIOOcLaOXUVnsLVslBKRcaa5Bc/Rajzbxm5PA5zyf5ri8dHD1tCn8UnSY9gqexRbso/htbET7/JGZxtnKDuNT42Uflr0DXYjnMbuej0Kb3syvsmC+WmsuM9hepoJ/K1g6/MpnPJfvGMcJ9dYwG5mE1iREH/S2CWwO5S5mKKa8n8C84D7sWK0iq3BRyn8SLjuR/1P4RO9x9LYzsSP+g2F9+gKjA1sTe9ig+MTUf8beC1J2e8DH6PqjTCDZaAMQCfxqdAj+O6rB1NZuamJdy3iVOtdqtfd5JT/4M2X5NxZvAE8jS3y4/jkZBzzqGzMegyHH8zEj5TLrGiK9jvYZfYxfOo7h9fMbVT5+FHsBjbN3in/78cnsjLqKOW/PEsInJ7Gp1FL8ewMdpt9DLsuz0a541h57eKNW5YJmjfS+2mqKf/78e08zgb9GN5YblB0kkex1880dl3dDvzIsNrBXjn3RTkCXx/GbosnsVw/gWmlR5mr4xRa0CnLLNYJpOx3sO6ktd7H7vMnop8PYzrTGJTyfwmfJPWoxnzNcHBM2zxV99VVyhp6FLvfLlLW+1McvGmbxa6o4NjKzPMH7J3yfx7zgvH4fTbGUk/5fxqv4VUcFkFtPGcwnx6nmpwsw2vR/8dTn++j8MmrOFvl3TimTXqKaGoKb1RFu8fi/16U1UneEmV+1E/FZ/ewp5iyZs7Hs49h3W4M34ss3aue8l91z+CrDESHE1Qz/os3PwxsvQkTPwr83BHgW+E7/xj+6Mtl86Yj5Uvx8UejoKxUd1MINMPr8e5x7BJwKQYoxWgRB2Rmy5EU/A+lsoL1KPckVo4fifYP+6btVsNBi/lrCU8APzQGF3asYH2t4VaOdwwzhK9lGw28R/B5YPB7/JOvFJ74HHalgt1Gq/cKNgG2ZmEOljbg+DzQgeFq9cRCm8LlW9DH9sGfAO8dPR/GdXNQn24Wh18L2K/tW9mvBhpooIH3NWwD/+A63PtF+JYj8I2fhE/eB73/oXrXzdchHIpN2wZlM9vDu3pZAlbwce7zWMnSCYdifzaj3HHgIxdhcK18P4v9+pdxkO8lnEp8kmKpUKyj+qC4Dp2KPUdR9hQ0KMu0LBs6WXieYuXJQfbPYeuIlMTLwD8CZnfKBn2ArfZSVjYppyFyNbhCsfrP48BZWS+y+wJR5rdxbMtSlH0d+8RfxCdYWziujBiHrH49HOMiy56COXUqPIbvtOhHHUvYTUB3Ng2wBX0RJ2jIp3lypdnCiTYUv9GP+rKbwCK+SLZDNaaC6LMspfJB3qYkLLhBsYjr5GcyxiO60QnRKtW7ehT/dTHK5bv1lqPc1cC3+jye+jcd+NDdWy/jqwwu4YuRx6OemXgmXGh8A2zN1Kn0jajvEr4fLlux+hT6voLjGMZizPPYGrZKoeF1fPcN2Af+48+Xf17Ea2gZ++ivUlW8Fb8Re6g9Y9p0crCOT0Vk/T5KmQe1JTpYju90Sep3/afwL38S/gpwYgMmNuymKPeODRwPuUM1Nk/16SRVVuw6CGeivRdwEhDdAfV8tHEJZxK7hv35ezjhSp9CH0oUFCgGfJ+lTnZ0eqx3Wruyiks+yWrZwwkVeqlsPv0UjxO/fD7V8Ub8zvxMvLKP4zfkGrOMrwTQehbtdik0dQXTi05HwAkyNHad6smrQby9fjoPPgmZxfPcx/FIGt96wuUsZR5/J+p6I96vUGSG3Ep12ih8L6d+vo5Pllao3nk4TtVNUyeIstJvUuhsNspfxZ4J2/hUZoNqPMybOFnOKj7Bn8WnSlq3an8OW9WXo4xOzSSDtC7aOPmCeLtONTfj54Xo+yKOSxJ9bDPaPVKy4gVshF7ESVwkS1WP7oeSHNAJqiz86sv1eKa5GOBTJp3iid8uBp5Ev+dxcqYOduNaw/rBEtXkNqI7yYSL0Qd5DYD5vvSUGewOtoj5rBJsaX6245lOMeUxIQ+VLnZpm8VxWHILfR1nsNUYFOPcx9lOdSqyjWM9NbYFdse0LcQ3t+P1tY69QPqYDiV7j+DEbn1Myzp100mb1uMlDo5p07xrfUgPuoBP/9uMdimsg2SuTvd0Il0/aVvDnlr5W+lYUzhBhfTVHNMmGTiTyupEvM1ul2PpXZIvo8YyH/2Xu6D4nnAt/UsyTTJQ/e1ib7NZLIe7mEeoHvFChbvolLUT9S1h/qET7NWor53GchXzc+kCdZ1tjmpcs2hpAmeUnsCZwTX2B+cojOUC8AvX4c5fhjt+Gb6XchT7nZRMIBroWhRcoQgkVSbkqiOaNBHfFlYORLzbFMJ+Ax+PbqayUFVqn8cZ7l7iwE3lodi0beILY8HjFkFIcL1KYUaXccyZFAsxv0Xgj67ZRXQh1SvC0YZHxDaWng3StxII2pi8il0wetHHHJOzjo96V6hmj5R7K5ipianM4XTPPXb7GV/GmQGXcWYlKWEi9J1Uhnj+avyttjrYBWULL6zbMDNW+QvYXUkKpQTvGg68b+MNgRhXP+FRDDXHtGkhyo1EzOQK1eBRCYl5vCnuJ7wKhAtwFp/M2LTx0nG8lHcJ9kXMNLR5u5LKS4GScMnKUS6rPvcp+F2JvkuJzW1MxrfaEF/AaZaFD7CSeoQy70r8kOddimAf+6ZfwMqB2hSIjlcoa0pps9Wu+JXWiAR+n2rw8NIiHD/vTGVSwNXWCtWTVa2rJSx8ptJ7KYnjODXvSvRLqeFfTf2UYqEN4hLe+HPemVjFJ+QuJUVHSrfavoA3sn2cXUu8ZpTgX8YGJ611CffFaOfVwJvoByzoNL/Cs56LJ0oBAG+6JB+0SdM7rV0px1qzN+LvK3gTlelb61SbNm1yxrBb7SbedGZ+tozpSR6ocvHRmLRRFV5Ej/OY/2geNaZxzGM0JvEH4VxKZ12568d4ZFjJynw+ZZU7VCe+XaR6wbHwoL/BcRzCt/qvOjQHa5i2pJBJrokH6jsZtNSuxqhvt3HSivURZYU/zYH6l2XfDlYIF/BmShsaKYnamM2kbySbJLvEHzSeKbxpVMiC6EP0Plb7W9nuslImPi5eOUpuZjnQj79XqCrvknPbqd5JfKVEDxvvNLfS27T5Ek1pQ5L1E+FRvEu8dxpfYC1epvFKT5lOdSirn/ScC9hop43S6xj/km1aux28ee7hjcsmhU7nqMZiakMmI7MMcj3MF8SjJdulF+2k30vpG/FR/ai86Fd6xRTmo/IMk2FebUsuaiOx30ZLhhfxc4WFbGEaFj5uxovgKtWMzcJb1kfEvzapGiYkR6RjzeN7y0S3cuuTfiia30jtgnWe9fi9Es8lX0aNRxmV1Z8FPAfq7zUsS8UL+hjnMsTMY5mtdSyjxhrFeCBjlgxYMgzLqJLbXsXzm/t+Lfo5kfqd+bh0timquo6MytK329igovcP9vDpBJR0ugD/PcU/9NcoKet/BQd49mKQsmoKltidyriPiU+LSRu0vCDb2FqTFR2wUns+kCELUr39GhyKTdsM8CmKcnWOvWPafoBCAF+k+NDO4NifMzjzyzd+C3zjNfhLF4uVKvv1P0GxEv8Ojml7mpIi9AUc0zaHff2V3vV7MdG/GP2T774Ur2ng0/gGdVkyvg/Tz8v4JE4W58fj989RNnA5pu1nqca0dSm+4G8Bv8HeMW3jwHezO6btKzim7cXo6yei3K9jReHfwUqYLPwSPMvsHdP2GtWYtrMU118JxwGjY9rOYwt+O747Q/G5/3X2j2m7SJnDduD7U1Q3KZsUuhlEHYvx7M8Fjl+mmmq4y+iYtll2x7S9xP4xbV+mytCnKTR3NPrwYtTxaaoxba+xO6btTsrprHiIhOiomLZPc/MxbccD7xeBX8UKtNbUQ5T1UY9pO/7dwLPw2e/b2z1yVEzbb2Eh3o22NRaAP41PVWXoUkzbs4Gf1xl9T9uXidi2vwQPb8JnXvF9T32q7pGKwZBy9+dwTNsiTpV/hP1j2n4Vn2Z+OsZylTKvqxTetYnTrg9wTNskvnJkMXD+HYHLWeDfxUa6F+PZTIz9I1gZPs/umLb5eH8ax7TNxzen8PrR2pRCoU3RBIWHEO+/Erj5DI5regMrUF2qGct67I5p08b+aIxxgWpM2/Vo7wn2j2n7baoxbVKQ2zim7Tl2x7Tdjw18/aj/kxSZ8HLgezzGei9lvf8yVtofpKyHFwMn+d7C32J0TJvWsTaBj+A4rkUKf3kw8P8lnP24T5nLD1No9VWc9RAKjb3K6Ji2F7D3wXGqMW3P49P5Y/HzYDx7jmpM21i8fzHwf4LqnaPrlDU5RaEj3Teqb7aonjQSfX0t+vgslhdzMQfilaPkpuTAQTFtz7F3TNuLlFCSuwPf4ofPRJ2fj/E8ik+/L8Q4jqVxd9kd0/ZL3FxMm+hyAdOj1tXncUzbp6PvL0UdR3Fs7LPYwPQiptEz0fcvxrMPx+83GB3T9iI2yByj0FiXMmezePOlDdIshT6fxZuu6/gU8zhlvT0ceHqB3TFtP4/vO5UBZJp3HtMmo9Aqjmn7DQqt9OLZU+ze6OzUns1S1rz0Chn5cx8G7B3TlnWs53BM26vsjmm7G6/hZcq6Ep+QkWmVMo93pXcyMNXl0GsUmng6vvstyho+QzWm7RSFp22yd0zbc+wf0/YV9o5pWwj8PMTomLbsdXAp2pJONCqm7ecptPAs9tT4Ertj2v63KPNwfMsTFGGeT7d2AjHLwGeBzwH/0QX4F2cLQ9TG4l6q8Hog+EkciHgzMW1fwa5ED7E7pu2XotwPBIK/RGFA90TZPeBQbNq00V3HlmYxYD2XhUNWA1nitEFZS2VVqJ/KazH0caaprLyt4Qw5qYq30zqPpe/UL/VD1sj6d1p84FMmsCVblgKNG5zVqp/GpU3UGj7+zm3IgiFlUL872Hq6lupcH9HPjOuM022qYxHjVqYu4U+CSd9m617G8TrOoDSZ2uincplJqm/CQ6aRvGlT/6W4ZXwLr2o7M8Z+6iOBNzEW4Usni6P6oHZVVmPeoErLohewRVw0o1O4PmacwpU2r5r7Uf3VSZvmZT3V0U+4EuxEm2p3DQsC1S8Fuj5WzeXbEA3U8SPItJzxeAPPlazCsuSC43jr62083ul/0b+MXer/xoi+ic6Eo0yr+RSoT3VNSED2Gb1p07i303d6nul/myodrEWbg/Stfvrp2Rqmc73X2u5TPf2+TpUXZJ6zhhVFUln9LT6T+7GN3QKFK8mkTapzqk1Anaeon+IdmgutQ60f9VuuXVoj2QKd+3SdKg2002+9F/7VjvC2lp6J7jN9j1Ol/bdpKuExyyyB5lf1rWEj1FaqJ/Nj1X8duzoPqGbxu5a+q5dV+9u193Vau0aV7jdTGdHceqpDdD2O5zXLPNL3fcxXxDu0VrTxG4+/ZeVfo8qn1M+95GbmA7mf+Z3mT3SpMa5Fn7I8E042KDSXM+Tluc64AJ9kbrA7g7FwnGkSTANZT8l1Z3nUSePcwutAY53AdNFnt/xspzb0TG1I74Eqfet9pqEs08UbtvGJmnCttVafH9UtmhGurlGlJZUTvrRm6jK8DvV+i5ZkMNK8ij5ht/dN/j/PMXu0rRMwjU3yqk+VHtfT86z3ZH6pPmn80jvqOFSd45in1+VQl7JBFH1nPtAf8SzLQPDa0JxoXKKDXFa4rfPWHaprMMtuzYFoKsuJjEOF9oB1zMxfsgzoY9kvWSQ6PKrBtVOFWbitA38dePQsfNdn4NuBxc+V765RhcwwpEj1sXIzSL/bVBW4cUz0E1ShLixUrt5+DQ7Fpu2PceyDLEUihGU8YT0svDrY/ayD3UAH8LaD+GXsT6vF2Ut1inj0TJYiqCpoK9ilREyhT5UxZybTo1h5dCx8A7v1yAKvPnQoBLhIEQYrFIusLvlej2dZCG6keiR0pLjJEkaU6bH7zqjlKHMp4aeHXajErHrRJ82L8JgXzA52A22n+jLurmLXIzF/CdNFqr7efaqCUC40q1RduHrYhQ6qLpmag7xR2aQa16G6FgMXUsJuoyrYpGwtYRq9iudSNNpJ7W1i99gOvoMnbzaEM/XretSrDe0iu7NXSWiqH1Juhb9xTKtqQwqfXDVUj2h4Gc+L5q+f2pUguRz9W8WuMWvw9o3Ei1TXqmhoDLsugL+Twi36r7tSifbWor2V+HuLspZEZ2Clsk01RofLpcEldiue2nisY9eNAXZJXcenRxIcndRGhis41XKm6TzvPRyfIIW3gy2nmSeM43i9PtVLczU/6m8Pb1aWsLKgTWg//l/Ga0VjJJWVe55wLvpoY7djrRutL9HlEna90WZMMkv8+TLVC13HqfJ3GbxkKFA/pSjkdTiO15XoUXMjmE7ta56l9CymssKlZIC8VMax58R0+lbjncF3Iraxe6HmV/WJ74pupIwtYjoQbxG/WKWq5Kt/a+k7lVUbm9ilcgvz9pWEkx6Wq5pH9UseCMKZLN5amxpbnSdlfibeKL2ovmlTO+Jxqm8Rr3vxvT6WXx1M35o30ZnchJewLjaNZdZmak/8RnJ5iWq8Tj+eyW1SLol9vCYE4iOZd3Ww63yf6qZAc6+TmazXZVoUDfSxoq91ILmtdSi62E7vpe8tYx6yinnUCl4/K5i3ay6kO6jNMUzn4ininZqfPtWNfh+vxR6WcdoUTCR8T+JwAMnTrdReluF1uBpjUBnhoIdp/3p6RurXINWjZ4tU9Y9+PM/6iPSPpWjzSDzvxzOdqMqFvYvlpuQ0WO6BPRvUhjYrGo/WkeYt6z2CeyiJEJ/H/E2yRZtY1SXjySYO+9jA4RqaC+Gpjfm4aEp0pH52UluiKenA+laySrxANNfBPKSus0mmSIdQ/6Qj5VheME0c7VMVnBqMGu1j3+i/+bnC0J/Eit1XsMKoMlewYpMDBKewL6gWqBiGkJTLCsR4FjEDvcL+gZwckk3bbZRTyU18bCwGIMLbohz16vhd7pGb+MLRk1GWDwDTcP9FW2HkInIWK2PHKEe5Z/Giuyv6tIXdI2+U6ngQL7B+9G+Ue+TZ6JME11T0XQS5jWPIxikLW5fvzVJcvHSh9BrFLWSc0e6REmqj3CNvi3YltHR0fzX6+QAW3GeinBj0AF8cmIWVaFD9PhrfHaV6GnAy/m5Hu7ogVBvOY5S5msTukVJ2pLAM8EW2Uta6lDk6m8atfkkITwX+6gygh5UTMYozVGltitHukVLMRKPZPXKd3e6RY5Q5vQ8rAmJs09itRxuC1fhe7pHCc5vd7pFzmIFLCZJ75Bi2ot3Lwe6R6uedONB5Hitmx2Oc91MEYCfG9HbK/7PAA6UOCccuVffIB1K7UoKvsL97pC7wzsYtuUeeSXg+lvAl98i31/H95ePTr/jCXQn5bCXexgJUOJNiDQe7R47jOKTJ6J82QmvR7lnMs7VOT2O6GafM0TiFBh7Am5kz2MtjPZ7JPfIsVYNN3phvY8XxFKZbKY6n8PrR2pzG8RbaRIkXbeCEMFpf4i2r2DvkJFYUxqOd+zGetZaPYrk4ldqTe6R4YnaPlNJ0Lz6x+yB7u0cuYzqSe+S92J1QfT6LN+pnsFJwOt4t4ERDpzHv3KDqHtmP52cx/WhjlN0jtdbBSajOUE3mcSfeVN6P7+TKZRU6oPFMUuhCF2lr/o8nnAgvmh/JuTNYuZM8lew8hnWRUe6R6nuHm3ePJNq6F8sLGZfEKzMf38ZrpUvVPbKDNw5nMB3LKl93j9QY76bwItV7OsrPY7ktHU/8+Fgad5fd7pFzOLSF9H466q+7R2qs41hPmMObEV3krE3fMbwWzmIjquYVLHOlU96HN/Qn8VUjJwLH6zi5w3G89iSLpRPcwJsq6U4yjMjoPcDukVpXfXa7R17AKf+1idH4bsY9UjJGxrzVNG5tBsD6wkHukWNU9am8wRIMYtyaR/FS6efSscQPz0TfJN86jHaPzAYU8XiN52bdI3+B4h55hjInomUZw8WLs3ukjB7HsJdP3rQdw2tXuF2OPpxM/ZR7pPTU+7FORoxVc6BNcDf6lnWiunvkLIUWHsDukVeiDq3z8Rg/MeZTUCYpC07wxYtT8f/dWLhdA36MEgvwrd8CP3hnaenLv1veb1AWkdwjNfHqxCK73SNl/dPgjlEFKXKqYyHaqF85UIM6HR9qEOHebKf1fYZRZd8tEup13+y3+7V3M3W2a79vtt392t/ru3b6e79v94Nsbdxv7PV372Scdea7F+xXV3uPv7+a8K9a7144ei/gh4C/fVuVD77bftzsetiv/M2u5VF84Gbafif9qtc/qr29vjkId/utvYP6uN9ar78bq73fD/ZbK++ERx9U90F8p96P/wD4kQ/tf9XEu+Hbe7U9ts+7DO9k3Y7Vfte/v9n+7/XdzZbfjx72W3uZvurPRo1jP9yOgq8mzztoDd5Mf98trWf8fDVhL1n4TnjFO+Gv+flevOVm4N3O67uV9weN5aDyo9p6N2vzZmlwL14zqs696vtaK/wHjf/dzMfNvr8pOIiwXwb+8e/CH/4ScBme+rGSzOJfpQPvRMDfBByKk7Y1SiBsj2JlkFVpHbtDDiiJXtYou2ptbGUZWSYF578Cf7RdEja8Gd9oZ79G2b3PRR2X8Y5e1i1wRs8uPraVC8waTsmrGDNZSGQFuUrZOPcpVoHPx/MdnNloMfo1hTOHno/nsjZv4IxSixQr5lSMc4kSIzmOre2ysEM1mc1VfCHx6xSL5jLVO6qEh2wN7cR4ZZ3Uid4aPiWQBXAMp57tRR1yz9Cxuix23fhZin7P4nT2mTmtRPlX8fUMPXzhuOh9Mcq2sWUsW6Nu4Ax+Oj2U1X4TZxyUtXoKG1V2KHOp0+u1+F5GFaViVruyVl0LnL+Gfa0nsMV+KvowFz9fCZzIPXYhjeMoZe6PUviK3BU05zq9yG4oX8FW4XFsxZJffR+7HB1NeHwdz0EvxnqFcmf95g3T+DTw8c+XDnyRQruzMS6N8RLVuCu5VlxM+J6iSr/gdL5ym1jClkH1q4cvJR0LHCpmeBX4wS/A0islic0sdo/cwqeRGzE2nfDJ6riJ16hOMd5gNM9fxEkKtGaIPrwVbSpJVQ+vz0vp+yuYZnp4TWiMMuyJn2XXG+FuHq9dnVrq9FmeIMfwej9GdV42qcbYyg1Fp+FbONvqNFW3ItH3FL7wdoMy1z3s5iJj5xjl9HIWuzfKCrse9WqtTqf/tU4vYh6ufrajvulXHEYwi13ZrkSbS9htRzS1g9dhN/ryGr6K5Dx2l9IcCd/iq1MUGtlOY1fm3zY+adKJkIwfqzgraIfCpyYSHjU/a9jNXGWvRT+ym9A0vhhelu4udokUn9cp2iV8fY7e9fCJjuTIXGpfcy9PFtH+EqZXfSMXK8kO8BoWH5ARehEnVdOJmvi4rtCRHFjAac7l3ruJ18fr2CV3AfOla3gtz1LmuY9PveYoPFayT7Tdo+pxsRl1apzzFD56Hru1aqztaPsqvqhcJyo6CVlN430Ny8ovUej2LayHKLGF1vk6TtY0hvnsK2ls17EnlnjhUUwrco/s4muOdPqkedMJ3xV8knydqlfYMuabmpc5qmukH/MjfGT3QdHPMfb3FFO2x00cL6qT4lmsO2jNwW43/MzLL2M5AdW4Ps3xdrS5QtWjZC3680aMYRa7Ey7g06sJihyfo5ryfz7+bmO327VoZy69E5+s42Uez9MYZT41nj7WSaRj6cRUp2aScdvsnfK/F+O5gN32JUfrerh0tH4qK9rMut1s4ERrTXoD0ZdXsZ5E9Os8dgUXPnTStkY5lfvYq2lgpMIXU6cGVOOxLlIW2QXgC8D4Ipz8yyWJyE8DP0nJfgXOKLmMmYraEzG+hhX8JezqJJAi9wVMtOP4bqo94FBs2qYpWV+m2Z09UqlMB5SjXwl/uTvMYpekO+M5H4JvXIVPvlkygs1QCOUOSlIZbTCORltPY0Et16s34/tjOHvkJ7CvvFxduthPeDX68izOHinf5mewO5s2Zjra7Ua/bqfQzqn4H+xyILep4/HdSezn24nxbVGNJ+rE2AaUhX8qcCHaeoSSkWo+vtukGtT5NHYpU/ZIuVBcxa5L6vsEZZG9xu7skeeopkI+FmOZp8znvYGXAVbAiOcfprppPYXdZuSCkxXqIwnfgnWqrmBi9k8HjiUoOjGu2yluV+BsWVfj9/1U3SOPYoGktnoUd9p7qMa1aZPyFN70zUTfHg+cdALft2NGrbk/QTUDH/G/3COleG1GfXJV07jAvEpM/ByF1tv47ikp0HdEHQ9TMoD1Yj6mY9w8W5D95C+WNSGhL4F/nJIVqh3tLmBhrw3LUXZv2p7EsSlv4fvOupQ5m8WuE9pEnsJZIu+Jvh2fhUdf83PFN8lNbQ0r2gTOTmH3yLno3zSFFqWAZXgDu7dMUviENky3B56VnXUWr9N7sOFDm7FFyhw/i92llWkUCj/T5v1YzIVwK2URbLwRj7gncHMKGwNOpbLagExj9/Fe4PUZHMsipeIZrDhcxG7jRyk8eDVw3KPQ5sewW5U2JzMxdine2thoo/I4dsEmyp+Psqej/Fz8LeFN1HMGxyGuBF6OY1dIKZ39qP9ZfEfWk5gHKXvkGM7E/ABlzbzEbvfILl57i1TvX9KG+Bol/kSngT3KPMuFXMaMEzg26sPx92sU/qOyS/FMvOsKzip6FCuDd1D4/QaF341j933JubMJZ/dg98h24O2laEc8aoDdBJ+mzOF84CAr3FIkJ7BsGseGjqeoZo/sYoUs8/GXsAFnGntA3Y7TkK9hl8kpvKk8iXnFUvTnMcqaaOPY68coHkoyGOTskdKljuM4LvHoNnZ5k6tefdMmHnIi1aGN+JVo/0lsrFJsk2TFy9gD6wK7s0dOB95Etx/DCreyR14MXEzi7JEfocyXDNh3JBxKh5ROoA3FGzGGP001HXyfMod3Rp0PYbdrbVZPYwPVXdGHy4Evufce5WD3SBlZtGHsU9bQI1jGX6HI4cep8u48NwLxZsnxFcyT8qZN7usncEybNlcfxLrENGVNvUb1uqE7KLSiNbxM4WviE+v4Kogz2I1d8iXrPYJXo/9Pxf9TFDwrbKFPobO7KPQtg4EMNjPYGCEjFtiwdxm7R8pIchLHnZ3CBvXjFH3hjfjurRjrR7GBVUabNpaBjyXcgzfbt1P4AJgfjVPNHtmP9w9TaI6zFOI8imGAmcsChVAeiXd9HHtzmiphnKdkmvyZ/wT4VvjN7ykWh1mq2SOnqFp8wQr+OXa7R0qR/gSO3Xki2v9p9oRDsWmTsqa4jPwja1J+tpW+zeVkVdOHW1QVwVz/Tq3uXCfp+ajvcr1baRzbjG5jp/bdIP20Uz15jJupzq3a3/m7+vgG6f+MQ/2W9W4Urut15vYGted1nOSx5z7kMtvsnst6/4QTUvn8Xf6/jZlL/ZQm41u4qPdF85L70E7PNAd5nLn8JtV+5Xmq465e/1YqX6ebvAEfVZ/e5fmu476OYynbjHif5y/PXa43j7VCo1FBHkd9zegnj2Un/WyxW5juhcNMK7nP7RFlZILVGPLc1nFZb3fUvOT/M+g56X2dD8iyOWA3LjJtDUY8y7SY8bsXbkl1Cbf1cez1fR3XYwlHGe91fjZqPW1RXUv1d/W2oHoaU+eFB8mI+jdb6f/cTqb3/ea3Po91Ghk1D6PmcKJWrj6no9bKGNX5qPOpunzQN3m9Zvm013oao9puncfV1/x2ra3M+8ZTHZk+Mg3m51mG5vHsRWej1r3K1vFTl9OqdzyV1zd1njJqLdbXTR47tW/r7xjxTR3nuZ8ZV3nu6/3Nm6g6T800MEqX2RlRx6i5h93jGoXrUXJ1a4/39XFkHOzUnu0He7W/F1734t2CvH5kRISqnlFvJ9Ntfdx1vlKnKZVV/wV1fbjOw/VNfRwZZ6PoN/OOOj/YjweKF43SE0atsQFVmsrvMz4zL9G6FE6El7peLlxlvpXXmp59wygGUieGUQwyd0wgC+/f/gl45Cfg234Fvu0vwH+7WFU8MpL0v97vpZTuxRD2gUOxadvC2a5ux+4s6zhr4BY+VpfFs4tdF3Xcfw34eBxbvk6x/Mmyr1ONBZxwY5titVL7k/HtEiYiJRSQq80qDsifpprpqx/1yb1yBR+XS3jPl+5xNfVbp3kamzbl6+m7QWpzjepl1CL6vDjySWsPW9Jl2Z5O+NFpwWKq5yI++dUpgBZLH8/RLD5GV31aEzppnIi+SnnVvMrAsBllNVZtZjvYgrOC3U7G8Amjxie3nduo3qsI1UQkUzgoeza9m8Juf9PYpWKALwFewi6nfZyFs+4eeRUf61+Kvvfx6ZLmexvT4xw+FZvHbr2yUPcx7S1TTURCfJfpdg7T5AT2FBjU6prEWZ/UF1klVVeHYjFbjnqOxO9nLgCnCv2IrtexxWwT0/IAu2MuJVxcZ/emTbSn05pFnJxpluoa1km36PGy5mK2VDSHXZf7MSadOGwknJFwtolPm6axC3PdwkkNZ1rrOziDaB+f5s2ntkTfHewetxzvZ7ErmmgFvL7WcPKcfFqWXQu1/gj8bGF3UKhmRO5Fu0oEoex64iFS7nr4xHAi2uhRde/axHO1FPV3sTxbxQZIjVE8fAyvuzlMZ8LXPOZ1wrtOpuonoDrx7uOEFGvYtWY54fFCqu+NqOsK5rs9nJBpCq/RTewmJ36q+VvGlzS3Y2xyJ+qm+vJ3U9jVSNe/7GCefynqUtmVeCacLuNY+yz7buC50SnyJjbmrKW/e1FmAyuM3ahvCesiwvENCo2Kjrv4xIf0vYwmxBzMRX1v4qyHPZx1bi+5KTkgBW8SnxKJ/qew14FkomSx+M+babyrgbd5PN8dHFLRp6pHyBWvn8a2g93G+lRhPH0rHWINz4XGJXdRzc9WPOtiuS25uYPX5hqWkZKBKqN1qTHsxPvVwItoeSnebeCTQYU8ZOV4E9OBdKI6PxWvmUo47qf/+5g3iNeKH/ajb9cZzW8FPRxSo7WtBFkLeI13cehEhkHtmXAgOd7Hpzq5zABfvzOVvtWcTVL1HniLwoc1PvV3NZW9hD0FpJf2ccI6sM4zzm68aK1rnFrDovs17Koqma55nMKunpv4VBB8hYTmeyLer6Z6pJN1sEzO30mnzLqy6lzEfG+Wqs62hWXdLMa9eGUHe/RobXZj7P92XXDCbkVunt3uUdmClJHbi/qWgc8/W46uf4QiLHpYMHUxMUohncTHkxnEeGajP1IC6+3X4FBs2iYoR83rlCPX49jVYQIz+7spzP3N+K6LYxLuohzBnoC3bwq+97KZ+xhFedRx8TLl5PSOeKZ5vDP6JGXzGD7eP43dEFbScymNq/gCzQkcuzGFXXi08ZrA7inTOOvQ6zE23e+3hrNHnoihdXHGpQW8kPNmnXh2D16AcuPRRuoevODupqqUEc8kJLRgpMi3MYM8jV0ptIhPYDiJ3QTFsI4F7tXve/Bxfd60nYj6tWGcjvqETzHUsfTNVOCvvmlbiL8ljLajHimpk1hQd3EmUQksbTA+QHEHOMnuLKdqC3zSLsaUGc3pwN8N7GJ9KsYrRVFCaxxn4zpB4R1Q3bSdTLiQ8qI+SlnpxvsB3nxBmefjWGjMYWF1DNNjP55/kJQ98j7gnjIeXc/QxcaP4+X12/MphVeKuvqltkVbch1cS33uRLv3xP9r2A1rPMZ7V9R9J9Hpu+GuN8s7KQRSuvpUU3eT6tDaJo3nPkYHg0uxEX8+Hf2bxlm7TrPbAvxBilCewoJMLqXKsLZehlCJf5DSL34m3EqRFL7U3hiFbjQ20c1dqazW7hSmR1LfoZo98jSmtzamsaOY5rT5Ev2oP1KMulgZyMqI5vwUu7NHbgTOPojn8iTVTdtY9E8Grw6mlRnsKitFuouzUS7H+wns2nkvhS9JURI/01ycosz17TiG5jQ2ytTdI9ei/PGobzqVyZu2E9g9UrJno1Z2iaocmsB00cd0LTknBfsqVsiOB16Es6UY40lsqJAxtU9ZW+JRorm7sQJ1NOoTfWhNi8bARoQlqpn0xrCRSbQnvrqON/bT0Q/Jzbz5FO61fnai/i52Y9c830XZ8EnPkGx5E69lbejU9+Pp/yNpnOKjc3iNgdf1VLQnXi5XbeFmDNPmHN403x04XcOubBtR/31YwV9JfRGN9jBvXKHImxNYXt2J6UJ61rEoq7HlEx+t4fUoex/eFIg+NnFGUtHUKoWGpEetUgwlJ6Ie8aFpHL+tdb0XZBrcjG817iXMD6RDZN49SPXkZwuYl4yn36RvjuO5loyQ0fMuTHtHot3NNL5O4EXlVXYttVMfz6k0XsnM3CcocyO+LKPOqcCF1q76dzq1oX3GDNXskeIbxzD9CrdXotyd2D3yJN6kiteADdzHscxQfVkP0FqT3kDU/TrOOAo2gncCh6JRxbTJ3fbtSZrBsIOtQQOqinY/Ie1uqsGOsnLfgy3QStf5vwDf/G3w2G86YHATn3RkBf8YVbgYyBCTm8cpnveBsf1fv3dwUEek1NzMt/vVW1e4DoL8/SiFbb9287ft2u96G+90bDl+Y1Q7+d1edbZr39Xr1hjyWPaqa6z2e79+jY14dlD/Rj17p8S7H572g1HtHDSP+r+Oy5vpd5vRc7JXm/vVsV+5Oi5vpv6R7R2AwHey5m62D/X+3wwt3Qy97IfP/d7fbD2CUevkoPVS/3u/7/Zq56C29qur3u5+Y3yneNrr+4P4zUF4qj97p/x/r7b36vcYo+fo3fCYeh0HQZ3GR/HsvdbzQeO4mfZvBr8HzfdBdJnpeL95uFkYNe6MR/2917qrP99vHkfJ1XfTx4O+G/X7ZmR4HfaT6e+Wp3+1+GcdbmZNjtKN3kl/bmYNv5M662XVzih6y/14J3AQf3yn8zhqfHv9P4r3Zlp8J3T4bmjophW3+vN3Uu6ngF/+zbIr/uYZ+J7vsnX3ZiAj5CYHdihO2lpUCUIWQ1nbNH5Z1PN3Gu9Ees9Y+SPv6vVNm+pztTWW3lH7XotoIpXJ5VXHeK3+uoBR3eNUGclYrd7x2rfjI97l9lSPTtTqwqFezxhV3NZxnt3t6hu3Ot5zf+rjofbNqHGpf/X+jKXnGTd1Gql/V58XQXaFqM93not6f6k9b1PtU338ql/9yPM0qv876X19jvJY9qovjy3jPtNsXh95PHvN5ai+jloz4/jlqLLp9dvt5j61a8+y9TOv51E0WF8/Gadvtxl/TFDFnU6Wclm1re+2R/SzTlO5r/V+5HnNfEXtZ9zk+Wqze9x1vjRqTurfkb6H6typD5lmM15yvaP4Vp0uM+8YozqmCq3Uxj1qblVmUKs/l81zPIpuGfFsFG+or8W8vvO61rjqyus4jsfQt/X5qY9v1HocNY46f8z0m8vWcd5m9xzk9kZ9m+eqvoYzLjKfG0Wz9bFnF648j5ku6uuqvr7rMiPTen2so3joBNU5GkXfo+oYRVcaT50/juKfeymsdVobRYv53aCGhzw24YRaHfvJtkwPdR6bv6vLGbVX5511nNbb1RoZJV9H8dVR+NwLRq2xOk3l8dT16J3aszyWel/q+sxE7dv6fI7SW2A3fmH03NXljr4bpduo3rpOWOdh+ZtBrb78vJ3qrfetPm9bVHFS12VH6Y2jdMVR8z2ovcu8MPPD/O5tvpMLCnYYTYikv0cht67wZcSMU444PwfcuwoP/5/wkc/ARzbh5V+quhnU6x0lIA4ieg7Jpm2NkrlLrjdd7HPbx5eo/gpOgS9fXLmeLVFOQo8Dj71Sjni/QPEnzv6ua5QTzLewK8qN9GwtvpW/7TR255nC2b8Uz6Aj4XGcMlj9UbrzTvRdTP8tnD5+At9EP4WvM5CP/ybOstXDWbFmqGYJbWM3PrnMjWP3giWK++1U1NehmvJf7lSz+GhcY5Fb1DKFtuS7r7g4uVW1Ke4FPYrLCdhX/zJ7p/yXb/wC1RgGcCa7C9iHvEf1Em6Nbzb+V9rYXM8WPkLvYJdPxU0t4KxMcqE5Ft8PsE/+ItWU/+vYpVNrTf7qfcoJ+CymY82JXAW3o663KCn6Z7BrVg+v5RmcSe8lCn2IyYJjAeWetUVxHZhJ7cp9W66Fa1T9/tsUmhQex6IPb1Hmb45qyu0p4OkvQGtQ0lK/jGlMdHcJ0/IAp1qfw0w3x2UJFGuxjmO91tMYFnG8mehgjrL+L0Q7/+EX4J/9PjyH3SjXcVzlRqpf60Y4k8uR+IxclrJAEwhnYPcVeVRcCjx/Efvoa31l3/ylhJsejle5gmPqwHMxTTUGVq49N9L/coMFZwp9PT0TfYPj+rIL3zJVHrKJ00UrTnUQZUVPUxTXsus4A1qPKo/pR73TOPZLLkljUU7f5rFrjBMUOnsTX5WQFVniO/VX8yx+voi9YTYw/52Pny9FXUpJPofTwrcxH3gr+ipXOtGIQhpWo39ZR5Dr8hp2V17BWRE70dY4Za2vU2hhmWp8p8r2cTr7McpaE13MUY0pXMFZCd/AbltdfH2OcNbDKf/HKOtiLto6mnCt+sai73K9n8b8V4pdm2pMWy/6obGCQ03Es3I9kpsrMd6FNPal1JcejoeTTFSMkXj/fPR5ljLPa1hWz+Espdeoxp4Jl+tY7gkXkgnnsR4hEH6W8CXTqmMZy4svYRqQO6LWwEK8m6aa8l/uisIbqc5X8dpcw2nypa/M4Cy5Kzh+cpHq9SriWXKTXMRXpaxjdzvx09spNKPL37VGpihzLj1MfElta3xyA80yvA5LVHMTbGC+NYvjyOU2O4p3Z+hRTfm/Hr9zH8TvFCeYXXelY3WoxnjquiNtlLo4yyoUXqlYVbD83sCyUu+kk9XHskCZE60vZSNWhvt1TPezOHRL3oLT8Vs6oDZv0xTaXY42LlPk6xrmF+JL0j9uj++u4GzrvXiX90zLeP1L7ozS2aQn6ZmuJJLr+zjVlP8PAk+8hpV2wQDfi7FCNeh7PZAmBGXo4UA/+cMuY6VYMUTPAz8PdD9XfER/AvhV4L+jGo8ikCL3RazkjmG/2T3gUGza2pihTlMNmJY/9QT2k5/Cgd+TeCHop/UnYPpfeGOj+yGmsV+1/Gjrz4TXtfS+jzdKWtCTUecUXkTyWVb/5RssoaSyK3iTpvF0cbyiGBZU737TmPVeSlYn+iIBJQIfj+8UXNxNdXRwmtf1+FvKmMp38UZGgkvj3Erz0MX38vRxbJ/63w0cb+HAWuFdm7iZhOdsaMjzs13DT2Ze61jIaA46qR4JWNIYt+K7CayYZ7rQHGiTo42W5qAbfVhOZdXWZqpD7eWNtHC2ncp3U7+vU005fCTh8Qhlrm7DCSe0ednERiG1r41sVn4z3rrpu7wxEs1pI6MNuu4KnAZaM8DRat9zfJ/mT3QjvAtfakP90catm95L6R5E3dqIap5EB8KPnjNjPN+e6tP8aJNwLbUrnIku16heBSGhk0FrVIrZ7emdeMDtWJnXOtU1GbdhBU50I5rP60v1ZT6RcasNu/A4wHFl0+l7xdTlslIUNA6Na4LCuzR3mqu64g6WabfHOylymV8Jz6LPaZxmPgv0QRq3xr6NYxj0TnRYV2S6OOZIoG+7VDOSqX95Heb+ifa1+TiC12FeD9mI1cVxqXnTlmk185c+pnmNR3jcoeB7At8PpbLqv/jmTno/jZX4LFezkU1yMb8Xr+niTZv+1zjFozU29X0j1SX6yAbuLJv6mL41HtGLFNwsN7WWNjGu1SfRqnAvPMoAoDEKR3p/NOqSTOvGsyOUdak5GMPxNvot3qVxCkeqL5/kSC5lPi4jktbJNlUeqtOELo6jz5sarRHhaordfGwa00Sbavz1Drt5u3ClcUim1zdtkv2Sw9loqc1Z5qWaL813m6r+IB6SdcA896Mgb8byWhbvrMthqPKIQe3/61RpW+9zH3bS2LTuwXKqS1XH6lL4snTZPD71SZuizCekL+hbtTHObs8FKHPUT99OYjpT2YwL0Zt4uvq7hWkLrNcpkdFMeq/1RCq/nb7TmNdTu+I5MuCIb43S2XLfZvCayjq/aFRrUnO/S3ASha9iK0cmDFmc6swLbI18O5AfC/MZvJiU/Websjn8U5SLuV/9ZvjF3yuXJq6nerUblVDWpGXmPgIOxaZtinKNgX6fwJahJWyteQIHbZ7ECvEU5T6Lk1GWM/AN1+Dpi543bWCfxC4TxyjBlE9jgj0bfZrEwbQinKfwfURtfIeEFpE2009SNuyyrE3hu3/Alw+KYLuU+2C6OBby8fh2DV8kfZKygT8afy/ggNW8aZO1/bbAmWjobkyPU9HmdPT1CRzcLOb9OA7anqOauW0JM9bHsBInA8fJ6MMCvtfoEtVEJCeiXgXav4qTs4iZ3ouv0pCF+S6KNSUrmHNUrUO670YgJgW2JG5G39eoWpt0D5YSkezg090OhUbuxolIJIzEOHRyd47i3gw+0dJ3T2BhJWH7KE4wM4sVq9sodKo709ZwAC8xLiWYWMAZ6h6l0NIy5icaj/rzVvTzzsClLHMSHsejzYdwlrYPk/jXk+XnsZ8tdWsTKFzciWl5B1sEs8FBzFxMGUx7a/g+nmvR7mP4QuOjeDOmIGv0+0k4ch4eecUB/itUM7+JH4s2hDNZTi9G/45QaHGUEnERKw+aW7BFexWvwwt4nd6H6e4Nqve0iSdN4vvKSLidoawhrQ0p9lLStclaSPi4O35kpb87jUGeA1P4hFGWbs3fBpZ34mc7+LR+OcqcwskJevH/o1QTkUghb1M9KZrAG/RH8QmzxvhS4OVezJdPU+hbJ39tyl1mwoVkhnjnAwnX/WjjKSzfH8N87kz8qN9QeM9D+CTsFJb1ncDjU/gkKW/YNqLNj0V/wJdlSwYOMA+VR8Aj2Ir9YCqrUw3xrkV8f980vifueOBzLfogZUpr/BiFr0mnOE1ZTzew8U9yVDxqBxvzHov3b8a30mXA2eSyjOpQLOaDKKtEJHN4zdxGoT3V08X3mU1HmTPxfA6ftNyPFUrRrO51nQwcCaencTbjpcDbGWy8egxn5JQB/jg+vehinpBlguYNqpvj+6LfJzD/mccnrY/FePs4Ecmj+K7IacpcvRbjehKfXnewN8x9UW4Q+PowZU1ORh8l109gWtHJyXEKLcioM0s1C6d0jjspfE1rvU/h0XNR7zHKvVmis6M4qcRyjPdUfNvDCvkxCv2cZP9EJPP4AvrNwPm5GPcEvovxAcp6HBtdzdugU3nJrlV2b9oGMW7d0zadvlUeCdHeNAWPM5jndnBSjjtS2Wl8ypTHcwbzaW3M8wZZoLsadSfqOIUG7sWXty9EXafxCdkCpqkpqklTwIlIelH2XDxfwve0rVJ4xVR8dyK+u4hPzk9QeJ50u7HASd7I5rUOPviYodC5nm0Frs4lXIs3P0yZG84EMvIGSAS2FI0/TLk8DqwE3o2zngiUivwx7J5yKQaY72nLO+JrFOZ5Hvjh34Mffwq+8/vhD7/Xx5BS5J7ELjmPRPs/xp5wEB030EADDTTQQAMNNNBAAw008E7h730Zfvd74Zv+K3jwM/BnJg50g9wLDsVJ27/EfvTaNcsaLl/vbUrcW5+yc5cbxgI+ll2kWC8+8iYMV+G38H1H7ahrMp5dxqd505TNtFL/En1Zw/64U8AL8WwF34l0BLujKdbnxSgzh32GX8DWkYupXllPdNQui6HismQNkWvDMr63TFYMWS8G2Bomq86LOCYrj1+W7dnA24sUA8EcdlV4EVv9LuM0ulsx1lVsJZIV9k181xVU72LR6ZZcs45FvQN8mrcwYjzC2Sq+W0kWYFkdLuO06x0cwyRQHAfYyrhNicNax2madboxje+z2sF+96KlfuB0A8dxqT1ZiERzs4GvfmrjReweKRo9j+98U3yNrGbLMSYZeFYwrep0VGtH1tDz+DRB49J4+lTvHtI9MZfS3+30nXzJl3Ec2jTw8ReAmTKeC5jOdAp6DdPyDr6nTeOcwNZhfQNeD2sxD5ex9fvlwM0Cvp9KuL6K7y7it2HwSjnB1SnpGnab0SlBD5+0CWeyIPZinJNUU2pnuIxPtKYouADHa/TjmU6+tD5l3OvguC/R9wuB7wVMK2BaWaZ67csOhQ7rMW2aX1njl9KzRYx3jVk417cT0f4OhQbEH8TPdnC8Z5/CDzWGjfS3Tll2MB6PRJ91aixa12lPl6p7pMY4gdeV5i7zAvFK8TOlVhf/3MIxP3p2FMfVvhT1zcW3fRyXKtjC8X3ysJjCcVTiMQuMjmnTCTN4Paic7uoS7rQmdOq8ncquxjPxH50YDbCc03ft1L7qGYt3M9hNTzJIvKRNWY+ivTU891pLL8eYruBTR3lL6PRTNECUn4/6XsIGbMXO9jGfrMtNybE+PhkR/WoMknOSN318GrlCmZfXoj55F1zDsYs6yZf8W8NrfBXHbEruEeVz/zO08Yn+UtSlNSKeuIpPknXyvU3hSVorHRwTNaCsw53ozxs4FERzO4t55FpqdyrwsIJpRZ5jcrMWTc1TveR4izJvG1gnW8cnnTpEuIppRFdmTeNYM92jt4LjiqcCH0ewp8JesJjq2A4ciA/MYn7aoerGuhdIpui0R7jMfdjBLuc9LFPlVSD9bDZ+b+DYUnnQ6eRWa1ink+A1Kvk0oOBH7zqMPml7M/rejf8v4pi4VXw/p2LMFNe9SFX/1FxJ77qK3TfFU0VT+l96dAfT8ia+I3AJX98lvWIs6pb+KjkoXQEcZ6zTtp3ol/ij6GUsviOeXwTOzlOY0nSqcIAD3pdq79Yxk1+uIXeeMkFywQKf1kGZaBFaNxArZi0Ff0CZpC/8dfgQ8EnKKd8dFKYjZnh+RPs1OBSbNrkO6Jh0Gk+sCFjHzdqMZB9plXvbZWsSWpvQ3SiLP/u96n9dhjyFlYPb8CLspHpFTN3ok2I/SHXLnWYqjWEKx2t0qfr/6rkU4COpjFxboRB6/k7vulj430Y1EYmEZcaZ6q+3MZX6rMWj8voWvOkQwxBTF46EGym4GY96n4W9xqB4om7CtZRw4Vf93KjhVxsD9U99n0zvBeqv6lScmYSuBHSmwW58L9/yTaq01004VlmwgFTftTnTsf4k1ZgY0aNoWH0QQ5qIb49g9zjNvRiZ/LzFeEl9HKQ6NR4w01O9UuCEVykaWiOTVPEzDW9PZDfq6aTvhOuMR7l+aP3p+6zgqVr1o4/jRIR74VyKxThe/6Jvbof2JExtVP3l9b3a6mDXOuFMioBoJc93HTLtaa1rI91Jz+TDvxXlMv/qU+hbNN5N7zMtCsd6LqPRTvytDc8Au560qdK0DCpdvH60NrVGxOPGa+OZxDFOWst9qolDRGdtHDrQxe6RWgdSFDINCL8Ddq/DbRzTptjFTG+iIXDMUAfHNcmV/kg8u4F5dpeqDFJZvdO6auP1ovWrfh7B8yt+IfqUPBO+87gUS9xNfRRfAfNLlavjJPNvtak+SzaI50ipncQJRERnep95rDbEqi+vOWrjmaQozsLPQZs21afvoawlbW7UrtqSDNAayf1coyq3hEcZ/zLP2KYql9TeZno2merPfALMi4RXtXs7puntVK6dvq2vZxkYNK4jmDfqfV030PhEF9qgTVGdU41N4xK/Fx42Me5V9zZVHivesYl5iviAvgPTQV0/G0VT05g3aR41nsnat1mG10EGd9GV1l039U86XZfdm7ad2rO6HNd6r2/aMu1MpndHqMa3ak3p7yyHMw1AlY7EJ8RPxeP327Rl3iVayHy3LgOkV4uuumnsmgvVKxpV2czb2lg/6tS+W8XGQtFD5oU6nFC70n0E21TnT4bDzB/VP/VZa6OiUAl28CKZqr0XU6yXERLUCb1bp7oYhRBdvqtOTbC73nngx7HV56+dgX86C5+ttbEHHIpN2w3KOJQNRpaeTWwBG2Cf4yWcwEFW2gGONxteLr9fp5pBSxamS9GWrHLTqX2dXixhK8IiBe8XcPZIWfa02ESEnfhuGVugx+OZFMOFqGMpnl3DVrRs8QZnrRrHlqwpbEW6gi0YUuCzYJzFfu396O8CVnJkyZCFeBELnFm8EJXBT+30U1+yotaLOmTxV5ltPK9ZOV7Gpw4LCScZJuJdP9pbx0JdjO4KvoD+NnZnodyMvklwraYx6t0E3hzrGwl9zeUSngtZlOYxMwXTZju+m8fWKCmDOu3cxvR4EWeBXIw2if+vU+h7KZ7n7JGygMo6LwGm08m6Qi58r0V9Y3iNLOETVRlNtBGYx5u62yjCZPg6tO4q49FaU3tgC5zwuBx4zJmfsuDLwkKKxVV8+i4r5iLO5Ck6WIv+LURZXod/tuGTX22mpaBpA7nI7hNd8R5lw5vCimHeHECV9rT+oXoaeyHa0MnyAPOLTtSxiq3WMr5difEeiTrn8OlpP54JtwvsnT1Sc76anmX6Ft10cLyfLPQXsMDsRRsXEh4056p/jWr2yE0cRyzeIXpciLbFw8bxJkunHRq7LPyax3lMt1mJyca+HtXT1T5O2tLHMWYzWAYoDkz8QvX0U/2D+H476leiH51KdHCGYNGM+OA6jvGBasbQDvY2WMPB/JIvC1GHyvbZnT1yNd5l/MjSvRX1XMaJVTawgrWJY6VXUtsa2xWc7AgcMyZZsYx1lPqmTX+D42SuUGSfaPIKnrNRclPzpvUoXCvuXRtxyTnJMvGOCexhoBO2BUwHc/j0XWtzLT0TnxE9Ce9gXqX+53GPUdVTujiTrXhiH2fTkx4wwJ4c85jvijZvx8Yw0ajabGNdQ+NYxAY/rVmwJ4noWcaAMao6gfjAYuDsaMKHTtskF5U1WHxjBc+bZI8OJURr0v+mqXqTjIIlnDFxG/PTNoVPrGB5JdlXp8P8rIflL+ydPVL0v5TqvR5lr0d7ugB6G9PtIOrux5iPprLzmE9sJryM4TmSfJEhN8MCzn45Fv+rDtHvMvaikI6wjDeZ6q/i78DJ0MTHt7H3yAbmJ5v4pP86ZS7zyd461ZM24lvpthPYiCMQnekEHMwHNEfCx+X0/yXgg4uBDCmmubA6lZnUOj4+7lMV8j2M3G480+ZDk9LHu2YxeTEMEYnKCl6K9tZmS/DhL1Iu7H6dfeFQbNqmKfF3F3GApzYoUiJ3gGcx8Z+kCFopv2dwgG/rQ/Cv9+FT/6/TkLeJ6wAobpPjUf4EJUhVz85En+ZwgPYchai/A28Mp6kGIk9gpvQdFMJ+DS/sZzFBnqfMt5KYKLlCFyeVeCy+zcr+8ehvFyci0SaljRnrZpTtAM9gBeMubCk5QjmdfZFCq5/ATE/C4pNR92rgQArTNk5EMsPuRCQXcCKSS5TA8HOMTkQixec0xY0Nqneq3EcJlJ6kmojkLNWTtjepnrRlfINPPQY4oP1GjHuNMidiGjOpHXAiEm1uz8a7k7WyOtq/gROw3Bf4XsYCZJKSaKIb/Xop8Pok1UQkSm3bocz9HZQgaKgmItmiBHSP42DyzajvFD65lwFnB7ukqJ934kQkssyJ5j5Amb9jgbeHsUGo9amC7E/8Y/PHLt6IncC0vIM39eJ1wrc2DxIWT0UdazgJTj/qfoaypmcpdCc3y7twUojTAJ+CP/kGPPH71UQkm1hRvU6hHZ1+CWfrOG16N+rcKxHJm1SV22fjueh1NZ5JudX6PI2FpTZji4GzZylXFVykrEPN3ctRxwwO9Jch5TxWNMQL5MFxOvBzNxbKp/D6maeaiERGp/E0nswftL52sBv4cvTzFE5OsBj/f5RqIpIOpiGlYxfNbeAEFUfT2LdxoqN7KLzrzfhba1+gRCTTeJ6PB97OJlz349kz2DXtaWxcuY8iE2QQIco/hF2rT2Ej1As4wdESNh5J0dLG8RGqiUhmKetQPGiSQgeSdx+m6BoXov2ciORVLIeuUujiocDPHJZ9H8WnOpM46dMxqolIpnFSDRmDZmK83Wg7G2U2KHx0mmoiEimW2hxKdgxijK/HeJ/GiUjepNDxSnwzSm7mRCT3Uk1Esk6ZLxkS5QZ2EvMlGYwex3xhFScCOYPlyMfwpupi9OMYVoS7WBG9O41DmxDSe/GQOwOH13C698VoXwmIdKIlPn40xj8duH09cPkJfJrxMjaSnqYk5JiMZw/HGN9gdyIS0UoPy+az7E5Eog3bduDiDsq60VqXN84CpqmHE570cw827pzCiUhkUJ2J8X6A/U/a5rFBTjh4kELnz+E1/gAlYcpBJ23a8KjNVbxu9d129PfBGP90+nYeJyJ5noL7sxSepfF1Ai+nqSYiOU/V+L8Zz+/l5hORXKTQdJuC59M4EckaZV5OUfAvGbiAE8rpwKjL6EQkd1H0gC5ORKJDDCUiWWB3IpJL8eyRGj4VIqG9zseoGnBF/0cpdC7668T4H8SndxtR5iEKr+SBKDSTKtyhMOjlaPyj+jgQ9GJCUIbfpzDZJ7m5RCQ3sGVyIp5/iOodO4KlQF6PsmH7uW8D/mf42X9rxMcFWsPhcM+X7xW0Wi1txv/wVvelgQZGwDfR0GYDhxca+mzgsEJDmw0cZmjos4HDCHcNh8NR27zDsWkDaLVaLw+Hw4dudT8aaKAODW02cJihoc8GDis0tNnAYYaGPhv4eoODEuo00EADDTTQQAMNNNBAAw00cAuh2bQ10EADDTTQQAMNNNBAAw0cYjhMm7afvtUdaKCBPaChzQYOMzT02cBhhYY2GzjM0NBnA19XcGhi2hpooIEGGmiggQYaaKCBBhrYDYfppK2BBhpooIEGGmiggQYaaKCBGjSbtgYaaKCBBhpooIEGGmiggUMMt3zT1mq1vr3Val1stVpvtlqtv3qr+9PA+w9ardbfbbVaf9BqtV5Pz2ZardaXW63WXPz+xnjearVafyvo9fdarda5W9fzBv7/Dq1W62Sr1fqNVqs122q1/p9Wq/XD8byhzwZuKbRarU6r1frdVqv1WtDmfxPP/81Wq/Vi0ODPtVqtiXh+W/z/Zrw/dUsH0MD7AlqtVrvVar3SarV+Jf5v6LOBr1u4pZu2VqvVBn6Scnf5GeAzrVbrzK3sUwPvS/h7wLfXnv1V4NeGw+Fp4Nfifyi0ejp+/gLwU+9RHxt4f8IfA//ZcDg8A3wE+I+DRzb02cCthhvAE8Ph8AHgQeDbW63WR4C/CfzocDi8B/gj4LPx/WeBP4rnPxrfNdDA1xp+GPj99H9Dnw183cKtPmn7FuDN4XA4PxwOt4D/A/iOW9ynBt5nMBwOfxNYrT3+DuDvx99/H/iz6fnPDgv8DtBttVr/xnvS0QbedzAcDv/5cDg8H3+vUZSPO2nos4FbDEFj/yL+HY+fIfAE8AvxvE6botlfAP5Uq9VqvTe9beD9CK1W6wPAnwF+Jv5v0dBnA1/HcKs3bXcCvfT/5XjWQAO3Gu4YDof/PP5eAu6IvxuabeCWQLjrfAh4kYY+GzgEEK5nrwJ/AHwZeAvoD4fDP45PMv29TZvx/hpw9D3tcAPvN/gx4D8HduL/ozT02cDXMdzqTVsDDRx6GJZ7MZq7MRq4ZdBqtf4E8IvAXx4Oh9fzu4Y+G7hVMBwOB8Ph8EHgAxTPmftubY8aaKBAq9V6FviD4XD4T291Xxpo4KsFt3rTdgU4mf7/QDxroIFbDVflVha//yCeNzTbwHsKrVZrnLJh+9+Hw+E/iscNfTZwaGA4HPaB3wA+SnHJ/dfiVaa/t2kz3t8OrLy3PW3gfQTfCnyq1WotUEJvngB+nIY+G/g6hlu9aXsJOB3ZfCaA7wG+cIv71EADUOjw++Pv7wc+n55/X2Tp+whwLbmpNdDAVxUipuLvAL8/HA7/x/Sqoc8Gbim0Wq1jrVarG39/A/AUJebyN4BPx2d12hTNfhr49TglbqCBrzoMh8P/YjgcfmA4HJ6i6Ja/PhwO/zwNfTbwdQytW02TrVbrGYrfcRv4u8Ph8G/c0g418L6DVqv1OeDjwDcBV4H/Gvi/gJ8H/iRwCfju4XC4Gkr0/0TJNrkB/MBwOHz5FnS7gfcBtFqtR4HfAi7guIz/khLX1tBnA7cMWq3WN1MSN7QpBuCfHw6Hf63Vat1NOdmYAV4Bvnc4HN5otVod4B9Q4jJXge8ZDofzt6b3DbyfoNVqfRz4keFw+GxDnw18PcMt37Q10EADDTTQQAMNNNBAAw00sDfcavfIBhpooIEGGmiggQYaaKCBBvaBZtPWQAMNNNBAAw000EADDTRwiKHZtDXQQAMNNNBAAw000EADDRxiaDZtDTTQQAMNNNBAAw000EADhxiaTVsDDTTQQAMNNNBAAw000MAhhmbT1kADDTTQQAMNNNBAAw00cIih2bQ10EADDTTQQAMNNNBAAw0cYvj/ABujkDsmxu05AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# see the way edges are related across the first 500 edges.\n", "plt.figure(figsize=(15,8))\n", @@ -528,21 +2565,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "9ab619bf", "metadata": {}, "outputs": [], "source": [ "# to see how to train a GNN, see the cyber or influence tutorial" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f170fa3a", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/demos/ai/Introduction/simple-power-of-umap.ipynb b/demos/ai/Introduction/simple-power-of-umap.ipynb new file mode 100644 index 0000000000..c61a4c8c04 --- /dev/null +++ b/demos/ai/Introduction/simple-power-of-umap.ipynb @@ -0,0 +1,7538 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "id": "af4a54b9-1959-4fda-a00c-534be66e09a4", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import pandas as pd\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from sklearn.datasets import load_breast_cancer, load_diabetes, load_digits\n", + "\n", + "from collections import Counter\n", + "\n", + "import graphistry\n", + "from graphistry.features import ModelDict" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "b28209f4-6809-4cb1-b6a8-e0d65cbbe07d", + "metadata": {}, + "outputs": [], + "source": [ + "graphistry.register(api=3, protocol=\"https\", server=\"hub.graphistry.com\", username=os.environ['USERNAME'], password=os.environ['GRAPHISTRY_PASSWORD']) " + ] + }, + { + "cell_type": "markdown", + "id": "49752d24-00a6-480f-be5e-62134c9598d8", + "metadata": {}, + "source": [ + "# Explore Data in a Whole New Way\n", + "PyGraphistry is a GPU Graph AI visualization tool that unlocks graphing in your data. \n", + "\n", + "In the past loading, transforming and interacting with large multivariate datasets took a vast amount of time to set up pipelines and processes. Graphistry makes time-to-graph + AI + interactivity 100x faster. \n", + "\n", + "We will explore how to see data, explore relationships, create new graphs from batches using sci-kits like api, and build a GNN model one could use in downstream DGL models. \n", + "\n", + "We will quickly analyze breast cancer, diabetes and digits datasets from sklearn.data\n", + "\n", + "Add your favorite dataset and explore it with graph AI and Visual exploration! " + ] + }, + { + "cell_type": "markdown", + "id": "d434a151", + "metadata": {}, + "source": [ + "## Tumor: Malignant or Benign " + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ec079ad1-12d8-419c-9f35-d4ecad825635", + "metadata": {}, + "outputs": [], + "source": [ + "data = load_breast_cancer()\n", + "\n", + "good_features = list(data['feature_names'])\n", + "\n", + "df = pd.DataFrame(data['data'], columns=good_features)\n", + "df['target'] = data['target']" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "df071dc0-df4c-4701-8794-57864c37fc0d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
mean radiusmean texturemean perimetermean areamean smoothnessmean compactnessmean concavitymean concave pointsmean symmetrymean fractal dimension...worst textureworst perimeterworst areaworst smoothnessworst compactnessworst concavityworst concave pointsworst symmetryworst fractal dimensiontarget
017.9910.38122.801001.00.118400.277600.30010.147100.24190.07871...17.33184.602019.00.16220.66560.71190.26540.46010.118900
120.5717.77132.901326.00.084740.078640.08690.070170.18120.05667...23.41158.801956.00.12380.18660.24160.18600.27500.089020
219.6921.25130.001203.00.109600.159900.19740.127900.20690.05999...25.53152.501709.00.14440.42450.45040.24300.36130.087580
311.4220.3877.58386.10.142500.283900.24140.105200.25970.09744...26.5098.87567.70.20980.86630.68690.25750.66380.173000
420.2914.34135.101297.00.100300.132800.19800.104300.18090.05883...16.67152.201575.00.13740.20500.40000.16250.23640.076780
\n", + "

5 rows × 31 columns

\n", + "
" + ], + "text/plain": [ + " mean radius mean texture mean perimeter mean area mean smoothness \\\n", + "0 17.99 10.38 122.80 1001.0 0.11840 \n", + "1 20.57 17.77 132.90 1326.0 0.08474 \n", + "2 19.69 21.25 130.00 1203.0 0.10960 \n", + "3 11.42 20.38 77.58 386.1 0.14250 \n", + "4 20.29 14.34 135.10 1297.0 0.10030 \n", + "\n", + " mean compactness mean concavity mean concave points mean symmetry \\\n", + "0 0.27760 0.3001 0.14710 0.2419 \n", + "1 0.07864 0.0869 0.07017 0.1812 \n", + "2 0.15990 0.1974 0.12790 0.2069 \n", + "3 0.28390 0.2414 0.10520 0.2597 \n", + "4 0.13280 0.1980 0.10430 0.1809 \n", + "\n", + " mean fractal dimension ... worst texture worst perimeter worst area \\\n", + "0 0.07871 ... 17.33 184.60 2019.0 \n", + "1 0.05667 ... 23.41 158.80 1956.0 \n", + "2 0.05999 ... 25.53 152.50 1709.0 \n", + "3 0.09744 ... 26.50 98.87 567.7 \n", + "4 0.05883 ... 16.67 152.20 1575.0 \n", + "\n", + " worst smoothness worst compactness worst concavity worst concave points \\\n", + "0 0.1622 0.6656 0.7119 0.2654 \n", + "1 0.1238 0.1866 0.2416 0.1860 \n", + "2 0.1444 0.4245 0.4504 0.2430 \n", + "3 0.2098 0.8663 0.6869 0.2575 \n", + "4 0.1374 0.2050 0.4000 0.1625 \n", + "\n", + " worst symmetry worst fractal dimension target \n", + "0 0.4601 0.11890 0 \n", + "1 0.2750 0.08902 0 \n", + "2 0.3613 0.08758 0 \n", + "3 0.6638 0.17300 0 \n", + "4 0.2364 0.07678 0 \n", + "\n", + "[5 rows x 31 columns]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "e6c6f61c-0923-4860-8045-18dfeffe69fa", + "metadata": {}, + "source": [ + "# UMAP\n", + "\n", + "Reduce the data into a 2 dimensional graph -- the edges come from similarity in features. \n", + "\n", + "UMAP is a powerful way to see the parts of the dataset. One can not simply confirm if a predictive model will 'separate' the data off of visuals alone. UMAP provides the tools to explore relationships that can help feed insights and potential treatment strategies. \n", + "\n", + "What can you find in the data?" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "28ae2a26-c7e3-457a-8a50-78031797fad2", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "# let's split data and train on half the data\n", + "df_train, df_test, df_train_target, df_test_target = train_test_split(df, df[['target']], train_size=0.5)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "a3527e13-7e14-437f-b423-6643e15b9a08", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (284, 0) in UMAP fit, as it is not one dimensionalOMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 15.2 s, sys: 745 ms, total: 15.9 s\n", + "Wall time: 16 s\n" + ] + } + ], + "source": [ + "%%time\n", + "g = graphistry.nodes(df_train)\n", + "# fit on specific features by calling out via X=...\n", + "# plots are sensitive to scaling, we use_scaler='robust' for good umap separation \n", + "# (thought None does better in RF below)\n", + "\n", + "g2 = g.umap(X=good_features, use_scaler='robust') # y = 'target'" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "65758e38", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g2.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "b773839a", + "metadata": { + "tags": [] + }, + "source": [ + "## DBSCAN as pivot \n", + "\n", + "Think of DBSCAN as a way to pivot by clustering in features of interest. \n", + "By setting `cols` one may pick out features from the matrix and have dbscan only focus on those.\n", + "Coloring by the `_dbscan` label in the UI finds clusters across those variables. \n", + "\n", + "Contrasting UMAP coordinates versus dbscan labels is a useful way to see total behavior against some part/pivot of interest. In the following, we see k-clusters in the `worst` (case sensitive column selection) meta variable. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "97d11165", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
worst radiusworst textureworst perimeterworst areaworst smoothnessworst compactnessworst concavityworst concave pointsworst symmetryworst fractal dimension
66-0.900440.64410-0.82082-0.729950.79066-0.23246-0.47392-0.330950.168280.58154
701.934280.117401.873552.41938-0.393660.167060.245030.85155-0.35829-0.69391
490-0.162820.68958-0.12018-0.13056-0.18349-0.14923-0.35499-0.349870.525760.09121
67-0.52379-0.17240-0.52187-0.45097-0.07006-0.67788-0.26686-0.28479-0.60145-0.66861
3002.144190.081442.015262.802970.613841.225331.659221.050140.313200.93080
.................................
5440.00981-0.076150.055050.00421-0.15680-0.01070-0.29445-0.29685-0.844610.23179
48-0.24326-0.50449-0.19812-0.213230.610510.060050.39452-0.32773-0.042670.13888
519-0.10790-0.39450-0.09593-0.128100.54712-0.04518-0.27551-0.172080.479070.26341
173-0.71604-0.91486-0.68511-0.59497-0.31693-0.73187-0.69935-0.56084-1.40338-0.34172
341.022070.189320.968801.178360.450382.228891.310410.929532.409822.09875
\n", + "

284 rows × 10 columns

\n", + "
" + ], + "text/plain": [ + " worst radius worst texture worst perimeter worst area \\\n", + "66 -0.90044 0.64410 -0.82082 -0.72995 \n", + "70 1.93428 0.11740 1.87355 2.41938 \n", + "490 -0.16282 0.68958 -0.12018 -0.13056 \n", + "67 -0.52379 -0.17240 -0.52187 -0.45097 \n", + "300 2.14419 0.08144 2.01526 2.80297 \n", + ".. ... ... ... ... \n", + "544 0.00981 -0.07615 0.05505 0.00421 \n", + "48 -0.24326 -0.50449 -0.19812 -0.21323 \n", + "519 -0.10790 -0.39450 -0.09593 -0.12810 \n", + "173 -0.71604 -0.91486 -0.68511 -0.59497 \n", + "34 1.02207 0.18932 0.96880 1.17836 \n", + "\n", + " worst smoothness worst compactness worst concavity \\\n", + "66 0.79066 -0.23246 -0.47392 \n", + "70 -0.39366 0.16706 0.24503 \n", + "490 -0.18349 -0.14923 -0.35499 \n", + "67 -0.07006 -0.67788 -0.26686 \n", + "300 0.61384 1.22533 1.65922 \n", + ".. ... ... ... \n", + "544 -0.15680 -0.01070 -0.29445 \n", + "48 0.61051 0.06005 0.39452 \n", + "519 0.54712 -0.04518 -0.27551 \n", + "173 -0.31693 -0.73187 -0.69935 \n", + "34 0.45038 2.22889 1.31041 \n", + "\n", + " worst concave points worst symmetry worst fractal dimension \n", + "66 -0.33095 0.16828 0.58154 \n", + "70 0.85155 -0.35829 -0.69391 \n", + "490 -0.34987 0.52576 0.09121 \n", + "67 -0.28479 -0.60145 -0.66861 \n", + "300 1.05014 0.31320 0.93080 \n", + ".. ... ... ... \n", + "544 -0.29685 -0.84461 0.23179 \n", + "48 -0.32773 -0.04267 0.13888 \n", + "519 -0.17208 0.47907 0.26341 \n", + "173 -0.56084 -1.40338 -0.34172 \n", + "34 0.92953 2.40982 2.09875 \n", + "\n", + "[284 rows x 10 columns]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "X = g2.get_matrix('worst')\n", + "X" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "1829f1ff", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "-----------------------------------------\n", + "DBSCAN found 284 clusters with 0 outliers\n", + "--fit on feature embeddings of size (284, 10)\n", + "-----------------------------------------\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# suppose we want to cluster and color by these variables,\n", + "g2.dbscan(cols='worst', min_dist=0.3, verbose=True).plot()" + ] + }, + { + "cell_type": "markdown", + "id": "b4354d70", + "metadata": {}, + "source": [ + "Suppose you wanted to study part of the features matrix, like all entries in 'symmetry'" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "d866936a-2ace-4f77-af35-a2cea7174427", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
mean symmetrysymmetry errorworst symmetry
66-0.188310.597800.16828
70-0.59833-0.62800-0.35829
490-0.71374-0.323270.52576
67-0.798790.46603-0.60145
3000.039480.055590.31320
............
544-0.48292-0.48524-0.84461
48-0.31587-0.57035-0.04267
5191.03569-0.052850.47907
173-0.646921.70007-1.40338
340.66515-0.192862.40982
\n", + "

284 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " mean symmetry symmetry error worst symmetry\n", + "66 -0.18831 0.59780 0.16828\n", + "70 -0.59833 -0.62800 -0.35829\n", + "490 -0.71374 -0.32327 0.52576\n", + "67 -0.79879 0.46603 -0.60145\n", + "300 0.03948 0.05559 0.31320\n", + ".. ... ... ...\n", + "544 -0.48292 -0.48524 -0.84461\n", + "48 -0.31587 -0.57035 -0.04267\n", + "519 1.03569 -0.05285 0.47907\n", + "173 -0.64692 1.70007 -1.40338\n", + "34 0.66515 -0.19286 2.40982\n", + "\n", + "[284 rows x 3 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# with new features you can add it too graphistry API to run further modeling\n", + "X = g2.get_matrix('symmetry')\n", + "small_study = X.columns # save for later so we can call out only these features during fit\n", + "X" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a938ae8d-e280-4299-af38-1b945d38a22b", + "metadata": {}, + "outputs": [], + "source": [ + "# add the target back so we can color by in UI\n", + "X['target'] = df_train.target" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f6eeb6de-b418-4b84-92c7-b28fa241ce97", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (284, 0) in UMAP fit, as it is not one dimensional" + ] + } + ], + "source": [ + "g = graphistry.nodes(X)\n", + "gq = g.umap(X=small_study, verbose=False).dbscan()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "baf3980c-df0a-479a-8ee0-4fc57109881e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gq.plot() # finds that `symmetry` features are also a good indicator of target on their own" + ] + }, + { + "cell_type": "markdown", + "id": "c8780fe0-ca07-4412-ba2a-1ddde26d46db", + "metadata": {}, + "source": [ + "# Transform Test Data into Graph\n", + "Can add batch onto closest neighbors of existing graph (from fit above). Otherwise, if merge_policy=True\n", + "it will create a new graph from the batch. " + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "8de9e1bf-290d-4901-96ef-4dd8ac9b5887", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------\n", + "Infering edges over UMAP embedding\n", + "---------------------------------------------\n", + " Mean distance to existing nodes 1.89 +/- 1.10\n", + " Max distance threshold; epsilon = 1.00\n", + " Finding 7 nearest neighbors\n", + " 68.76 neighbors per node within epsilon 1.00\n", + " 1995 total edges after dropping duplicates\n", + " ** Final graph has 348 nodes\n", + " - Batch has 285 nodes\n", + " - Brought in 63 nodes\n", + "--------------------------------------------------\n", + "CPU times: user 7.17 s, sys: 54.4 ms, total: 7.23 s\n", + "Wall time: 7.28 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# with merge_policy=True, will cluster minibatch to closests elements of existing graph -- useful if you want to find\n", + "# centroids in the old variables (imagine labeling goldenset with other targets, this would find which parts of minibatch are likely similar to known annotations)\n", + "g3 = g2.transform_umap(df_test, min_dist=1, merge_policy=True,\n", + " fit_umap_embedding=True, n_neighbors=7,\n", + " sample=None, \n", + " return_graph=True, \n", + " verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "6c032e7c-0fc9-4364-9feb-eddb0d8e3c6b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g3.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "084f07f9-db66-4018-8d01-74a189a3c7ad", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------\n", + "Infering edges over features embedding\n", + "---------------------------------------------\n", + " Mean distance to existing nodes 7.13 +/- 4.26\n", + " Max distance threshold; epsilon = 6.00\n", + " Finding 7 nearest neighbors\n", + " 138.57 neighbors per node within epsilon 6.00\n", + " 1891 total edges after dropping duplicates\n", + " ** Final graph has 285 nodes\n", + "--------------------------------------------------\n", + "CPU times: user 3.09 s, sys: 24.4 ms, total: 3.12 s\n", + "Wall time: 3.13 s\n" + ] + } + ], + "source": [ + "%%time\n", + "# with merge_policy=False (default), it clusters just by the minibatch df_test here\n", + "g4 = g2.transform_umap(df_test, min_dist=6, merge_policy=False,\n", + " fit_umap_embedding=False, n_neighbors=7,\n", + " sample=None, \n", + " return_graph=True, \n", + " verbose=True)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "7f9d3612-b2e0-4500-b5ba-4c11c3577dc8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g4.dbscan(0.2).plot()" + ] + }, + { + "cell_type": "markdown", + "id": "9ab6b089-9c3c-4ad9-bd9f-c3e4b14c87e1", + "metadata": {}, + "source": [ + "# Regressive Targets\n", + "Diabetes dataset with risk scores" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d175607a-e108-45e5-aa10-05e306532589", + "metadata": {}, + "outputs": [], + "source": [ + "data2 = load_diabetes()\n", + "diabetes_features = list(data2['feature_names'])\n", + "diabetes_df = pd.DataFrame(data2['data'], columns=diabetes_features)\n", + "# we add target to dataframe as we want all the data for visualization (think coloring by histogram in target)\n", + "diabetes_df['target'] = data2['target']" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e1bbc28b-9d10-4ff3-8c28-3308b552bbd8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
agesexbmibps1s2s3s4s5s6target
00.0380760.0506800.0616960.021872-0.044223-0.034821-0.043401-0.0025920.019908-0.017646151.0
1-0.001882-0.044642-0.051474-0.026328-0.008449-0.0191630.074412-0.039493-0.068330-0.09220475.0
20.0852990.0506800.044451-0.005671-0.045599-0.034194-0.032356-0.0025920.002864-0.025930141.0
3-0.089063-0.044642-0.011595-0.0366560.0121910.024991-0.0360380.0343090.022692-0.009362206.0
40.005383-0.044642-0.0363850.0218720.0039350.0155960.008142-0.002592-0.031991-0.046641135.0
....................................
4370.0417080.0506800.0196620.059744-0.005697-0.002566-0.028674-0.0025920.0311930.007207178.0
438-0.0055150.050680-0.015906-0.0676420.0493410.079165-0.0286740.034309-0.0181180.044485104.0
4390.0417080.050680-0.0159060.017282-0.037344-0.013840-0.024993-0.011080-0.0468790.015491132.0
440-0.045472-0.0446420.0390620.0012150.0163180.015283-0.0286740.0265600.044528-0.025930220.0
441-0.045472-0.044642-0.073030-0.0814140.0837400.0278090.173816-0.039493-0.0042200.00306457.0
\n", + "

442 rows × 11 columns

\n", + "
" + ], + "text/plain": [ + " age sex bmi bp s1 s2 s3 \\\n", + "0 0.038076 0.050680 0.061696 0.021872 -0.044223 -0.034821 -0.043401 \n", + "1 -0.001882 -0.044642 -0.051474 -0.026328 -0.008449 -0.019163 0.074412 \n", + "2 0.085299 0.050680 0.044451 -0.005671 -0.045599 -0.034194 -0.032356 \n", + "3 -0.089063 -0.044642 -0.011595 -0.036656 0.012191 0.024991 -0.036038 \n", + "4 0.005383 -0.044642 -0.036385 0.021872 0.003935 0.015596 0.008142 \n", + ".. ... ... ... ... ... ... ... \n", + "437 0.041708 0.050680 0.019662 0.059744 -0.005697 -0.002566 -0.028674 \n", + "438 -0.005515 0.050680 -0.015906 -0.067642 0.049341 0.079165 -0.028674 \n", + "439 0.041708 0.050680 -0.015906 0.017282 -0.037344 -0.013840 -0.024993 \n", + "440 -0.045472 -0.044642 0.039062 0.001215 0.016318 0.015283 -0.028674 \n", + "441 -0.045472 -0.044642 -0.073030 -0.081414 0.083740 0.027809 0.173816 \n", + "\n", + " s4 s5 s6 target \n", + "0 -0.002592 0.019908 -0.017646 151.0 \n", + "1 -0.039493 -0.068330 -0.092204 75.0 \n", + "2 -0.002592 0.002864 -0.025930 141.0 \n", + "3 0.034309 0.022692 -0.009362 206.0 \n", + "4 -0.002592 -0.031991 -0.046641 135.0 \n", + ".. ... ... ... ... \n", + "437 -0.002592 0.031193 0.007207 178.0 \n", + "438 0.034309 -0.018118 0.044485 104.0 \n", + "439 -0.011080 -0.046879 0.015491 132.0 \n", + "440 0.026560 0.044528 -0.025930 220.0 \n", + "441 -0.039493 -0.004220 0.003064 57.0 \n", + "\n", + "[442 rows x 11 columns]" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diabetes_df" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "1f07666e-edf3-4585-b5a1-cc28dac9b04a", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.model_selection import train_test_split\n", + "train_diabetes, test_diabetes, train_targets_diabetes, test_targets_diabetes = train_test_split(diabetes_df, diabetes_df.target, train_size=0.5)" + ] + }, + { + "cell_type": "markdown", + "id": "bb779dee-8df3-4096-adbe-49a76fcb7667", + "metadata": {}, + "source": [ + "This time let's add target during umap fit" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "994c5a46-6e9f-49b2-a5fa-49095d473cd4", + "metadata": {}, + "outputs": [], + "source": [ + "g = graphistry.nodes(train_diabetes)\n", + "g5 = g.umap(X=diabetes_features, y = 'target', \n", + " use_scaler=None, # 'robust',\n", + " use_scaler_target=None, #'standard'\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "15933c92-6f40-40be-b5ab-bf300e67e359", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g5.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "da4eef58-517c-4908-bff1-7bb5c4872617", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "----------------------------------------\n", + "DBSCAN found 11 clusters with 0 outliers\n", + "--fit on umap embeddings of size (221, 2)\n", + "----------------------------------------\n" + ] + } + ], + "source": [ + "#predict on unseen data\n", + "# notice you don't need to add y=test_diabetes.target, graphistry knows what column from fit\n", + "g_pred = g5.dbscan(verbose=True).transform_dbscan(test_diabetes, y=test_diabetes)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "7a14df9a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# will predict dbscan label from fit\n", + "g_pred.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "9a1d000d", + "metadata": {}, + "source": [ + "## Add your Favorite Model \n", + "\n", + "We will use Optuna to demonstrate a sample pipeline with HPO" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "6477f87a-82c7-471f-acfa-1bdec88eb655", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001b[32m[I 2023-01-20 20:53:08,954]\u001b[0m A new study created in memory with name: Diabetes\u001b[0m\u001b[32m[I 2023-01-20 20:53:09,092]\u001b[0m Trial 0 finished with value: 0.3958282204544128 and parameters: {'n_estimators': 125, 'max_depth': 131, 'min_samples_split': 62, 'scaler': 'standard'}. Best is trial 0 with value: 0.3958282204544128.\u001b[0m\u001b[32m[I 2023-01-20 20:53:09,399]\u001b[0m Trial 1 finished with value: 0.42954660431688363 and parameters: {'n_estimators': 222, 'max_depth': 185, 'min_samples_split': 6, 'scaler': 'quantile'}. Best is trial 1 with value: 0.42954660431688363.\u001b[0m\u001b[32m[I 2023-01-20 20:53:09,594]\u001b[0m Trial 2 finished with value: 0.38437314665755473 and parameters: {'n_estimators': 197, 'max_depth': 190, 'min_samples_split': 65, 'scaler': 'quantile'}. Best is trial 1 with value: 0.42954660431688363.\u001b[0m\u001b[32m[I 2023-01-20 20:53:09,685]\u001b[0m Trial 3 finished with value: 0.4333005750494967 and parameters: {'n_estimators': 68, 'max_depth': 152, 'min_samples_split': 13, 'scaler': 'robust'}. Best is trial 3 with value: 0.4333005750494967.\u001b[0m\u001b[32m[I 2023-01-20 20:53:09,922]\u001b[0m Trial 4 finished with value: 0.4318469685060231 and parameters: {'n_estimators': 215, 'max_depth': 130, 'min_samples_split': 50, 'scaler': 'standard'}. Best is trial 3 with value: 0.4333005750494967.\u001b[0m\u001b[32m[I 2023-01-20 20:53:10,143]\u001b[0m Trial 5 finished with value: 0.4056859590113563 and parameters: {'n_estimators': 220, 'max_depth': 40, 'min_samples_split': 55, 'scaler': 'robust'}. Best is trial 3 with value: 0.4333005750494967.\u001b[0m\u001b[32m[I 2023-01-20 20:53:10,264]\u001b[0m Trial 6 finished with value: 0.35028481664246147 and parameters: {'n_estimators': 121, 'max_depth': 160, 'min_samples_split': 91, 'scaler': 'robust'}. Best is trial 3 with value: 0.4333005750494967.\u001b[0m\u001b[32m[I 2023-01-20 20:53:10,511]\u001b[0m Trial 7 finished with value: 0.44191045092853387 and parameters: {'n_estimators': 174, 'max_depth': 113, 'min_samples_split': 26, 'scaler': 'robust'}. Best is trial 7 with value: 0.44191045092853387.\u001b[0m\u001b[32m[I 2023-01-20 20:53:10,771]\u001b[0m Trial 8 finished with value: 0.4570822140378319 and parameters: {'n_estimators': 229, 'max_depth': 171, 'min_samples_split': 27, 'scaler': None}. Best is trial 8 with value: 0.4570822140378319.\u001b[0m\u001b[32m[I 2023-01-20 20:53:10,884]\u001b[0m Trial 9 finished with value: 0.4421353551018513 and parameters: {'n_estimators': 109, 'max_depth': 100, 'min_samples_split': 47, 'scaler': None}. Best is trial 8 with value: 0.4570822140378319.\u001b[0m\u001b[32m[I 2023-01-20 20:53:11,152]\u001b[0m Trial 10 finished with value: 0.4596624150532256 and parameters: {'n_estimators': 245, 'max_depth': 66, 'min_samples_split': 29, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:11,432]\u001b[0m Trial 11 finished with value: 0.456070643241286 and parameters: {'n_estimators': 246, 'max_depth': 61, 'min_samples_split': 29, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:11,845]\u001b[0m Trial 12 finished with value: 0.4557118546030289 and parameters: {'n_estimators': 249, 'max_depth': 10, 'min_samples_split': 31, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:12,191]\u001b[0m Trial 13 finished with value: 0.45365489784188473 and parameters: {'n_estimators': 178, 'max_depth': 67, 'min_samples_split': 19, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:12,489]\u001b[0m Trial 14 finished with value: 0.454454400785531 and parameters: {'n_estimators': 159, 'max_depth': 81, 'min_samples_split': 39, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:12,829]\u001b[0m Trial 15 finished with value: 0.38346335477400595 and parameters: {'n_estimators': 197, 'max_depth': 34, 'min_samples_split': 80, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:13,417]\u001b[0m Trial 16 finished with value: 0.45348976701727883 and parameters: {'n_estimators': 239, 'max_depth': 157, 'min_samples_split': 2, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:13,541]\u001b[0m Trial 17 finished with value: 0.44613313430354085 and parameters: {'n_estimators': 59, 'max_depth': 100, 'min_samples_split': 39, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:13,918]\u001b[0m Trial 18 finished with value: 0.45506726860199953 and parameters: {'n_estimators': 193, 'max_depth': 5, 'min_samples_split': 18, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:14,383]\u001b[0m Trial 19 finished with value: 0.4561936629751806 and parameters: {'n_estimators': 227, 'max_depth': 78, 'min_samples_split': 35, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:14,577]\u001b[0m Trial 20 finished with value: 0.39086287030920086 and parameters: {'n_estimators': 97, 'max_depth': 44, 'min_samples_split': 72, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:15,019]\u001b[0m Trial 21 finished with value: 0.4500610108687939 and parameters: {'n_estimators': 228, 'max_depth': 81, 'min_samples_split': 38, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:15,473]\u001b[0m Trial 22 finished with value: 0.45960740078894025 and parameters: {'n_estimators': 209, 'max_depth': 85, 'min_samples_split': 23, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:15,930]\u001b[0m Trial 23 finished with value: 0.4559439244521766 and parameters: {'n_estimators': 208, 'max_depth': 112, 'min_samples_split': 23, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m\u001b[32m[I 2023-01-20 20:53:16,283]\u001b[0m Trial 24 finished with value: 0.45533500184764475 and parameters: {'n_estimators': 178, 'max_depth': 54, 'min_samples_split': 12, 'scaler': None}. Best is trial 10 with value: 0.4596624150532256.\u001b[0m" + ] + } + ], + "source": [ + "from sklearn.ensemble import RandomForestRegressor\n", + "from sklearn.model_selection import cross_val_score\n", + "import optuna\n", + "\n", + "def objective(trail):\n", + " n_estimators = trail.suggest_int('n_estimators', 50, 250)\n", + " max_depth = trail.suggest_int('max_depth', 2, 200)\n", + " min_samples_split = trail.suggest_int('min_samples_split', 2, 100)\n", + " \n", + " use_scaler = trail.suggest_categorical('scaler', [None, 'standard', 'robust', 'quantile'])\n", + " X_train, y_train = g5.scale(use_scaler=use_scaler)\n", + " X_test, y_test = g5.scale(test_diabetes, test_diabetes, use_scaler=use_scaler)\n", + " \n", + " rlf = RandomForestRegressor(n_estimators=n_estimators, max_depth=max_depth, min_samples_split=min_samples_split)\n", + " score = rlf.fit(X_train, y_train).score(X_test, y_test)\n", + " return score\n", + "\n", + " \n", + "study = optuna.create_study(study_name='Diabetes', direction='maximize')\n", + "\n", + "study.optimize(objective, n_trials=25) # normally have more trials, here to demonstrate" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "560a471b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'n_estimators': 245, 'max_depth': 66, 'min_samples_split': 29, 'scaler': None}" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "study.best_params" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "0a859318", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "cliponaxis": false, + "hovertemplate": [ + "max_depth (IntUniformDistribution): 0.011453822466583852", + "n_estimators (IntUniformDistribution): 0.014155810306063011", + "scaler (CategoricalDistribution): 0.015838737969375006", + "min_samples_split (IntUniformDistribution): 0.9585516292579782" + ], + "marker": { + "color": "rgb(66,146,198)" + }, + "orientation": "h", + "text": [ + "0.011453822466583852", + "0.014155810306063011", + "0.015838737969375006", + "0.9585516292579782" + ], + "textposition": "outside", + "texttemplate": "%{text:.2f}", + "type": "bar", + "x": [ + 0.011453822466583852, + 0.014155810306063011, + 0.015838737969375006, + 0.9585516292579782 + ], + "y": [ + "max_depth", + "n_estimators", + "scaler", + "min_samples_split" + ] + } + ], + "layout": { + "showlegend": false, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Hyperparameter Importances" + }, + "xaxis": { + "title": { + "text": "Importance for Objective Value" + } + }, + "yaxis": { + "title": { + "text": "Hyperparameter" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = optuna.visualization.plot_param_importances(study)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "4450a842", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "colorbar": { + "title": { + "text": "Objective Value" + } + }, + "colorscale": [ + [ + 0, + "rgb(5,10,172)" + ], + [ + 0.35, + "rgb(40,60,190)" + ], + [ + 0.5, + "rgb(70,100,245)" + ], + [ + 0.6, + "rgb(90,120,245)" + ], + [ + 0.7, + "rgb(106,137,247)" + ], + [ + 1, + "rgb(220,220,220)" + ] + ], + "connectgaps": true, + "contours": { + "coloring": "heatmap" + }, + "hoverinfo": "none", + "line": { + "smoothing": 1.3 + }, + "reversescale": false, + "type": "contour", + "x": [ + -4.25, + 5, + 10, + 34, + 40, + 44, + 54, + 61, + 66, + 67, + 78, + 81, + 85, + 100, + 112, + 113, + 130, + 131, + 152, + 157, + 160, + 171, + 185, + 190, + 199.25 + ], + "y": [ + -2.45, + 2, + 6, + 12, + 13, + 18, + 19, + 23, + 26, + 27, + 29, + 31, + 35, + 38, + 39, + 47, + 50, + 55, + 62, + 65, + 72, + 80, + 91, + 95.45 + ], + "z": [ + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.45348976701727883, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.42954660431688363, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + 0.45533500184764475, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4333005750494967, + null, + null, + null, + null, + null, + null + ], + [ + null, + 0.45506726860199953, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.45365489784188473, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.45960740078894025, + null, + 0.4559439244521766, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.44191045092853387, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4570822140378319, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + 0.456070643241286, + 0.4596624150532256, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + 0.4557118546030289, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4561936629751806, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4500610108687939, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.454454400785531, + null, + 0.44613313430354085, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4421353551018513, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4318469685060231, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + 0.4056859590113563, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.3958282204544128, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.38437314665755473, + null + ], + [ + null, + null, + null, + null, + null, + 0.39086287030920086, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + 0.38346335477400595, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.35028481664246147, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ] + ] + }, + { + "marker": { + "color": "black", + "line": { + "color": "Grey", + "width": 0.5 + } + }, + "mode": "markers", + "showlegend": false, + "type": "scatter", + "x": [ + 131, + 185, + 190, + 152, + 130, + 40, + 160, + 113, + 171, + 100, + 66, + 61, + 10, + 67, + 81, + 34, + 157, + 100, + 5, + 78, + 44, + 81, + 85, + 112, + 54 + ], + "y": [ + 62, + 6, + 65, + 13, + 50, + 55, + 91, + 26, + 27, + 47, + 29, + 29, + 31, + 19, + 39, + 80, + 2, + 39, + 18, + 35, + 72, + 38, + 23, + 23, + 12 + ] + } + ], + "layout": { + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Contour Plot" + }, + "xaxis": { + "range": [ + -4.25, + 199.25 + ], + "title": { + "text": "max_depth" + } + }, + "yaxis": { + "range": [ + -2.45, + 95.45 + ], + "title": { + "text": "min_samples_split" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = optuna.visualization.plot_contour(study, params=[\"max_depth\", \"min_samples_split\"])\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b9df8675", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "colorbar": { + "title": { + "text": "Objective Value" + } + }, + "colorscale": [ + [ + 0, + "rgb(5,10,172)" + ], + [ + 0.35, + "rgb(40,60,190)" + ], + [ + 0.5, + "rgb(70,100,245)" + ], + [ + 0.6, + "rgb(90,120,245)" + ], + [ + 0.7, + "rgb(106,137,247)" + ], + [ + 1, + "rgb(220,220,220)" + ] + ], + "connectgaps": true, + "contours": { + "coloring": "heatmap" + }, + "hoverinfo": "none", + "line": { + "smoothing": 1.3 + }, + "reversescale": false, + "type": "contour", + "x": [ + -4.25, + 5, + 10, + 34, + 40, + 44, + 54, + 61, + 66, + 67, + 78, + 81, + 85, + 100, + 112, + 113, + 130, + 131, + 152, + 157, + 160, + 171, + 185, + 190, + 199.25 + ], + "y": [ + 49.5, + 59, + 68, + 97, + 109, + 121, + 125, + 159, + 174, + 178, + 193, + 197, + 208, + 209, + 215, + 220, + 222, + 227, + 228, + 229, + 239, + 245, + 246, + 249, + 258.5 + ], + "z": [ + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.44613313430354085, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4333005750494967, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + 0.39086287030920086, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4421353551018513, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.35028481664246147, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.3958282204544128, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.454454400785531, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.44191045092853387, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + 0.45533500184764475, + null, + null, + 0.45365489784188473, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + 0.45506726860199953, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + 0.38346335477400595, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.38437314665755473, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4559439244521766, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.45960740078894025, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4318469685060231, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + 0.4056859590113563, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.42954660431688363, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4561936629751806, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4500610108687939, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.4570822140378319, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.45348976701727883, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + 0.4596624150532256, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + 0.456070643241286, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + 0.4557118546030289, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ] + ] + }, + { + "marker": { + "color": "black", + "line": { + "color": "Grey", + "width": 0.5 + } + }, + "mode": "markers", + "showlegend": false, + "type": "scatter", + "x": [ + 131, + 185, + 190, + 152, + 130, + 40, + 160, + 113, + 171, + 100, + 66, + 61, + 10, + 67, + 81, + 34, + 157, + 100, + 5, + 78, + 44, + 81, + 85, + 112, + 54 + ], + "y": [ + 125, + 222, + 197, + 68, + 215, + 220, + 121, + 174, + 229, + 109, + 245, + 246, + 249, + 178, + 159, + 197, + 239, + 59, + 193, + 227, + 97, + 228, + 209, + 208, + 178 + ] + } + ], + "layout": { + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Contour Plot" + }, + "xaxis": { + "range": [ + -4.25, + 199.25 + ], + "title": { + "text": "max_depth" + } + }, + "yaxis": { + "range": [ + 49.5, + 258.5 + ], + "title": { + "text": "n_estimators" + } + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = optuna.visualization.plot_contour(study, params=[\"max_depth\", \"n_estimators\"])\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "027ca6b6", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "colorbar": { + "title": { + "text": "Objective Value" + } + }, + "colorscale": [ + [ + 0, + "rgb(5,10,172)" + ], + [ + 0.35, + "rgb(40,60,190)" + ], + [ + 0.5, + "rgb(70,100,245)" + ], + [ + 0.6, + "rgb(90,120,245)" + ], + [ + 0.7, + "rgb(106,137,247)" + ], + [ + 1, + "rgb(220,220,220)" + ] + ], + "connectgaps": true, + "contours": { + "coloring": "heatmap" + }, + "hoverinfo": "none", + "line": { + "smoothing": 1.3 + }, + "reversescale": false, + "type": "contour", + "x": [ + 49.5, + 59, + 68, + 97, + 109, + 121, + 125, + 159, + 174, + 178, + 193, + 197, + 208, + 209, + 215, + 220, + 222, + 227, + 228, + 229, + 239, + 245, + 246, + 249, + 258.5 + ], + "y": [ + "None", + "quantile", + "robust", + "standard" + ], + "z": [ + [ + null, + 0.44613313430354085, + null, + 0.39086287030920086, + 0.4421353551018513, + null, + null, + 0.454454400785531, + null, + 0.45533500184764475, + 0.45506726860199953, + 0.38346335477400595, + 0.4559439244521766, + 0.45960740078894025, + null, + null, + null, + 0.4561936629751806, + 0.4500610108687939, + 0.4570822140378319, + 0.45348976701727883, + 0.4596624150532256, + 0.456070643241286, + 0.4557118546030289, + null + ], + [ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + 0.38437314665755473, + null, + null, + null, + null, + 0.42954660431688363, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + 0.4333005750494967, + null, + null, + 0.35028481664246147, + null, + null, + 0.44191045092853387, + null, + null, + null, + null, + null, + null, + 0.4056859590113563, + null, + null, + null, + null, + null, + null, + null, + null, + null + ], + [ + null, + null, + null, + null, + null, + null, + 0.3958282204544128, + null, + null, + null, + null, + null, + null, + null, + 0.4318469685060231, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ] + ] + }, + { + "marker": { + "color": "black", + "line": { + "color": "Grey", + "width": 0.5 + } + }, + "mode": "markers", + "showlegend": false, + "type": "scatter", + "x": [ + 125, + 222, + 197, + 68, + 215, + 220, + 121, + 174, + 229, + 109, + 245, + 246, + 249, + 178, + 159, + 197, + 239, + 59, + 193, + 227, + 97, + 228, + 209, + 208, + 178 + ], + "y": [ + "standard", + "quantile", + "quantile", + "robust", + "standard", + "robust", + "robust", + "robust", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None", + "None" + ] + } + ], + "layout": { + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Contour Plot" + }, + "xaxis": { + "range": [ + 49.5, + 258.5 + ], + "title": { + "text": "n_estimators" + } + }, + "yaxis": { + "range": [ + -0.15000000000000002, + 3.15 + ], + "title": { + "text": "scaler" + }, + "type": "category" + } + } + }, + "text/html": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig = optuna.visualization.plot_contour(study, params=[\"scaler\", \"n_estimators\"])\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "fa378193-667c-428c-8962-e0a0fb5fef06", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "g5.get_matrix(target=True).plot(kind='hist')" + ] + }, + { + "cell_type": "markdown", + "id": "b3589f00", + "metadata": {}, + "source": [ + "Fit a model without target. One dimensional targets are used by UMAP during fit. (n, k>1) targets are ignored during fit. " + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "f81a96d9-a45f-4bf4-a302-86af6d2aae15", + "metadata": {}, + "outputs": [], + "source": [ + "# let's removed `sex` as a feature, which splits the data strongly, and generate a new model,\n", + "feats = ['age', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "363c5a6a-5183-4aae-9439-7756ccbb8bb1", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (221, 0) in UMAP fit, as it is not one dimensional" + ] + } + ], + "source": [ + "g = graphistry.nodes(train_diabetes) # \n", + "# this time we scale the data \n", + "g6 = g.umap(X = feats, # y='target', # don't include target for fun (which helps supervise umap fit when 1-dimensional)\n", + " use_scaler='standard', #None, #'robust', 'kbins', 'quantile', 'minmax'\n", + " use_scaler_target='standard', \n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "3509fac0-434f-4a08-bb54-256825b66af3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g6.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "f7379c1b-65d8-4350-b38b-b57f54cd97b3", + "metadata": {}, + "source": [ + "# Digits" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "0eb0f820-7118-43bb-8419-52acb4a4f925", + "metadata": {}, + "outputs": [], + "source": [ + "data3 = load_digits()\n", + "digit_features = list(data3['feature_names'])\n", + "digits_df = pd.DataFrame(data3['data'], columns=digit_features)\n", + "digits_df['target'] = data3['target'].astype(int)\n", + "digits_df['names'] = digits_df.target.astype(str)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "e3aa6bdd-b0b6-46a7-93ae-041321bef461", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (898, 0) in UMAP fit, as it is not one dimensional" + ] + } + ], + "source": [ + "a, b, c, d = train_test_split(digits_df, digits_df.target, train_size=0.5)\n", + "\n", + "g6=graphistry.nodes(a).umap(X=digit_features, \n", + " #y='target', this obviously works great to separate clusters during UMAP fit.\n", + " use_scaler=None)" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "a1156045-87df-443d-b75f-63d418941924", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g6.bind(point_title='target').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "afad90db-df22-4da6-abb9-cb161ef008c6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------\n", + "Infering edges over UMAP embedding\n", + "---------------------------------------------\n", + " Mean distance to existing nodes 6.19 +/- 3.87\n", + " Max distance threshold; epsilon = 2.32\n", + " Finding 7 nearest neighbors\n", + " 145.83 neighbors per node within epsilon 2.32\n", + " 6293 total edges after dropping duplicates\n", + " ** Final graph has 957 nodes\n", + " - Batch has 899 nodes\n", + " - Brought in 58 nodes\n", + "--------------------------------------------------\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g7 = g6.transform_umap(b, min_dist='auto', verbose=True, merge_policy=True)\n", + "g7.bind(point_title='target').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "be9b4506-960a-4204-b6c6-194d7fa9135d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------------------------------------\n", + "Infering edges over UMAP embedding\n", + "---------------------------------------------\n", + " Mean distance to existing nodes 6.24 +/- 3.87\n", + " Max distance threshold; epsilon = 2.38\n", + " Finding 7 nearest neighbors\n", + " 145.97 neighbors per node within epsilon 2.38\n", + " 6245 total edges after dropping duplicates\n", + " ** Final graph has 899 nodes\n", + "--------------------------------------------------\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g7 = g6.transform_umap(b, min_dist='auto', verbose=True, merge_policy=False)\n", + "g7.bind(point_title='target').plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "987a2bce-ffed-4724-a8a7-d3dc07f48262", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([[ 0., 0., 5., 13., 9., 1., 0., 0.],\n", + " [ 0., 0., 13., 15., 10., 15., 5., 0.],\n", + " [ 0., 3., 15., 2., 0., 11., 8., 0.],\n", + " [ 0., 4., 12., 0., 0., 8., 8., 0.],\n", + " [ 0., 5., 8., 0., 0., 9., 8., 0.],\n", + " [ 0., 4., 11., 0., 1., 12., 7., 0.],\n", + " [ 0., 2., 14., 5., 10., 12., 0., 0.],\n", + " [ 0., 0., 6., 13., 10., 0., 0., 0.]]),\n", + " 0.0)" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "digits_df[digit_features].iloc[0].values.reshape(8,8), df.iloc[0].target" + ] + }, + { + "cell_type": "markdown", + "id": "050acfb4-301e-42bc-bc7b-961bc4793608", + "metadata": {}, + "source": [ + "# Build a GNN model " + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "d0d2c3c0-cfa4-4335-b2d4-fa77ec0eae94", + "metadata": {}, + "outputs": [], + "source": [ + "g6 = g2.build_gnn(y_nodes='target')" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "7507c3d8-89d1-4d49-9534-9c2e50376934", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Graph(num_nodes=284, num_edges=4678,\n", + " ndata_schemes={'feature': Scheme(shape=(30,), dtype=torch.float64), 'train_mask': Scheme(shape=(), dtype=torch.bool), 'test_mask': Scheme(shape=(), dtype=torch.bool)}\n", + " edata_schemes={'feature': Scheme(shape=(286,), dtype=torch.float64), 'train_mask': Scheme(shape=(), dtype=torch.bool), 'test_mask': Scheme(shape=(), dtype=torch.bool)})" + ] + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "G = g6.DGL_graph\n", + "G" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "e237ce99-191d-473d-80bb-49211978fd5f", + "metadata": {}, + "outputs": [], + "source": [ + "# run a prediction task from https://docs.dgl.ai/tutorials/blitz/index.html" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3.9.7 64-bit", + "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" + }, + "vscode": { + "interpreter": { + "hash": "aee8b7b246df8f9039afb4144a1f6fd8d2ca17a180786b69acc140d282b71a49" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/demos/ai/OSINT/Chavismo.ipynb b/demos/ai/OSINT/Chavismo.ipynb index 2457cfee06..95ad9f30b3 100644 --- a/demos/ai/OSINT/Chavismo.ipynb +++ b/demos/ai/OSINT/Chavismo.ipynb @@ -45,16 +45,6 @@ "#! pip install --upgrade graphistry[ai]" ] }, - { - "cell_type": "code", - "execution_count": 29, - "id": "b6f55e41", - "metadata": {}, - "outputs": [], - "source": [ - "#cd .." - ] - }, { "cell_type": "code", "execution_count": 3, @@ -63,6 +53,7 @@ "outputs": [], "source": [ "import graphistry\n", + "from graphistry.features import ModelDict, topic_model, search_model, qa_model\n", "\n", "import requests\n", "import pandas as pd\n", @@ -317,9 +308,9 @@ " filename = f\"chavismo.xlsx\"\n", " open(filename, \"wb\").write(r.content)\n", " df = pd.read_excel(filename)\n", - " df.to_csv(\"data/chavismo.csv\", header=True)\n", + " df.to_csv(\"chavismo.csv\", header=True)\n", " else:\n", - " df = pd.read_csv('data/chavismo.csv', index_col=0)\n", + " df = pd.read_csv('chavismo.csv', index_col=0)\n", " return df\n", "\n", "df = download_chavismo_data(get_fresh=False) # set to True to get latest data\n", @@ -398,7 +389,7 @@ "metadata": {}, "outputs": [], "source": [ - "RENDER = False # set to True to have plots generated inline, or paste the URLs into a tab to see the graphs" + "RENDER = True # set to True to have plots generated inline, or paste the URLs into a tab to see the graphs" ] }, { @@ -409,8 +400,25 @@ "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=e17a8abbcddc472c932cdb5b2c0fc2c2&type=arrow&viztoken=c8e856ba-5b7b-4592-b22e-6dfac7b411a9&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813426&info=true'" + "" ] }, "execution_count": 11, @@ -440,8 +448,25 @@ }, { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=9b8312e901dd47999a91f39f66880983&type=arrow&viztoken=5fc71180-3c6e-4ff7-adc9-38938b6da275&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813431&info=true'" + "" ] }, "execution_count": 12, @@ -450,10 +475,10 @@ } ], "source": [ - "# one can also create a hypergraph with any number of columns of interest\n", + "# Create a hypergraph with any number of columns of interest\n", "hg = graphistry.hypergraph(df, ['Agent 1','Agent 2', 'Relationship'])\n", "gh = hg['graph']\n", - "gh.bind(point_title='Agent 1').plot(render=RENDER)" + "gh.bind(point_title='nodeID').plot(render=RENDER)" ] }, { @@ -477,39 +502,86 @@ { "cell_type": "code", "execution_count": 14, - "id": "9939d27f", + "id": "6699dc5c-16b2-4471-9a6f-9241c238d830", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "CPU times: user 2min 34s, sys: 11.3 s, total: 2min 46s\n", - "Wall time: 2min 31s\n" + "_____________________________________________________________\n", + "\n", + "sentence-transformers/msmarco-distilbert-base-v2 Search Model\n", + "_____________________________________________________________\n", + "\n", + "Updated: {'cardinality_threshold_target': 2, 'n_topics_target': 11}\n", + "_____________________________________________________________\n", + "\n" ] + }, + { + "data": { + "text/plain": [ + "{'min_words': 0, 'model_name': 'sentence-transformers/msmarco-distilbert-base-v2', 'cardinality_threshold_target': 2, 'n_topics_target': 11}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "%%time\n", - "g = graphistry.nodes(df, 'Agent 1').edges(df, 'Agent 1', 'Agent 2')\n", - "# since we have edges, let's featurize (rather than umap, which would overwrite explicit edges)\n", - "# X = None will featurize ALL the columns and setting min_words=0 will treat them all as textual\n", - "g2 = g.featurize(y=['Relationship'], \n", - " model_name='msmarco-distilbert-base-v2', \n", - " min_words=0, # force textual encoding\n", - " cardinality_threshold_target=2, # force topic model (with low target cardinality)\n", - " n_topics_target=12)" + "search_model.update(dict(cardinality_threshold_target=2, n_topics_target=11))\n", + "search_model" ] }, { "cell_type": "code", "execution_count": 15, - "id": "bcf9a948", + "id": "9939d27f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 2min 35s, sys: 9.96 s, total: 2min 45s\n", + "Wall time: 2min 27s\n", + "____________________________________________________________\n", + "\n", + "Search model over features with `y=Relationship` topic model\n", + "____________________________________________________________\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'y': ['Relationship'], 'min_words': 0, 'model_name': 'sentence-transformers/msmarco-distilbert-base-v2', 'cardinality_threshold_target': 2, 'n_topics_target': 11}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# save search instance after featurization \n", - "# g2.save_search_instance('data/chavismo.search')" + "%%time\n", + "\n", + "model = ModelDict('Search model over features with `y=Relationship` topic model', y=['Relationship'], \n", + " **search_model)\n", + "process = True\n", + "if process:\n", + " g = graphistry.nodes(df.sample(len(df)), 'Agent 1').edges(df, 'Agent 1', 'Agent 2')\n", + "\n", + " # since we have edges, let's featurize (rather than umap, which would overwrite explicit edges)\n", + " # X = None will featurize ALL the columns and setting min_words=0 will treat them all as textual\n", + " g2 = g.featurize(**model)\n", + " g2.save_search_instance('chavismo.search')\n", + "else:\n", + " g2 = graphistry.bind().load_search_instance('chavismo.search')\n", + " \n", + "model" ] }, { @@ -564,124 +636,124 @@ " \n", " \n", " \n", - " 0\n", - " -0.253210\n", - " -0.092555\n", - " -0.086723\n", - " -0.157253\n", - " -0.204900\n", - " 0.122437\n", - " -0.529797\n", - " -0.015322\n", - " -0.564774\n", - " 0.769105\n", + " 1935\n", + " -0.187781\n", + " -0.387294\n", + " -0.160111\n", + " 0.533505\n", + " -0.012384\n", + " -0.036983\n", + " -0.227363\n", + " 0.305134\n", + " -0.053135\n", + " 0.242913\n", " ...\n", - " 0.170976\n", - " -0.685452\n", - " 0.295997\n", - " -0.593129\n", - " 0.390818\n", - " 0.249091\n", - " -0.099062\n", - " 0.051298\n", - " 0.319292\n", - " 0.244462\n", + " 0.295774\n", + " 0.358959\n", + " 0.566532\n", + " -0.852727\n", + " 0.118316\n", + " -0.122535\n", + " 0.347825\n", + " 0.101922\n", + " 0.386412\n", + " -0.644331\n", " \n", " \n", - " 1\n", - " 0.246941\n", - " 0.124175\n", - " 0.269999\n", - " 0.181342\n", - " -0.505962\n", - " 0.210211\n", - " 0.140408\n", - " 0.468697\n", - " 0.321780\n", - " -0.128226\n", + " 1583\n", + " -0.389066\n", + " -0.087771\n", + " -0.775325\n", + " 0.130028\n", + " 0.172289\n", + " -0.208622\n", + " -0.874529\n", + " 0.382446\n", + " 0.483579\n", + " -0.309687\n", " ...\n", - " 0.896930\n", - " -0.324542\n", - " -0.291376\n", - " -0.565900\n", - " 0.524987\n", - " -0.196209\n", - " -0.519527\n", - " -0.216939\n", - " 0.862336\n", - " 0.193277\n", + " 0.152333\n", + " -0.175365\n", + " 0.676532\n", + " -0.393536\n", + " 0.014875\n", + " -0.383976\n", + " 0.081081\n", + " 0.298928\n", + " 0.596412\n", + " -0.605296\n", " \n", " \n", - " 2\n", - " -0.068820\n", - " -0.323506\n", - " -0.206149\n", - " 0.559626\n", - " 0.145691\n", - " -0.100530\n", - " -0.492642\n", - " -0.207871\n", - " -0.306911\n", - " 0.365237\n", + " 2351\n", + " -0.423137\n", + " 0.182216\n", + " -0.133435\n", + " 0.217782\n", + " -0.094416\n", + " -0.097829\n", + " -0.876501\n", + " 0.797395\n", + " -0.277968\n", + " -0.045989\n", " ...\n", - " 0.702710\n", - " 0.152173\n", - " 0.309572\n", - " -0.461615\n", - " 0.666504\n", - " -0.016534\n", - " 0.877414\n", - " -0.203894\n", - " 0.450191\n", - " -0.544430\n", + " 1.015161\n", + " 0.453668\n", + " 0.440656\n", + " -0.040266\n", + " 0.693482\n", + " 0.169744\n", + " 0.060993\n", + " -0.500294\n", + " 0.649334\n", + " 0.195239\n", " \n", " \n", - " 3\n", - " -0.193803\n", - " -0.272143\n", - " -0.208212\n", - " 0.341019\n", - " -0.175586\n", - " 0.149454\n", - " -0.245428\n", - " -0.008559\n", - " 0.279371\n", - " 0.312212\n", + " 452\n", + " -0.095392\n", + " 0.142223\n", + " -0.686644\n", + " 0.674334\n", + " -0.228214\n", + " 0.109001\n", + " -0.440772\n", + " 0.124842\n", + " -0.066046\n", + " 0.171612\n", " ...\n", - " 0.451480\n", - " 0.413026\n", - " -0.211110\n", - " -0.550950\n", - " 0.556309\n", - " -0.521065\n", - " 0.327162\n", - " -0.200601\n", - " 0.148922\n", - " -0.181214\n", + " -0.009296\n", + " 0.564043\n", + " 0.178982\n", + " -0.222556\n", + " 0.523386\n", + " 0.331242\n", + " 0.360143\n", + " -0.011475\n", + " 0.105367\n", + " 0.146013\n", " \n", " \n", - " 4\n", - " 0.099981\n", - " -0.147359\n", - " -0.181383\n", - " 0.436541\n", - " 0.026173\n", - " -0.218141\n", - " -0.193041\n", - " 0.030840\n", - " 0.436779\n", - " 0.392634\n", + " 8\n", + " -0.477632\n", + " -0.784202\n", + " -0.383131\n", + " 0.669990\n", + " -0.100068\n", + " -0.294655\n", + " -0.627293\n", + " 0.058967\n", + " -0.455835\n", + " 0.461948\n", " ...\n", - " 0.505176\n", - " 0.505908\n", - " -0.286257\n", - " -0.614761\n", - " 0.811958\n", - " -0.615687\n", - " 0.479651\n", - " -0.345834\n", - " 0.185110\n", - " -0.311448\n", + " 0.381159\n", + " 0.021592\n", + " 0.348291\n", + " -0.903526\n", + " 0.694809\n", + " 0.018819\n", + " -0.002837\n", + " 0.023364\n", + " 0.385524\n", + " -0.437104\n", " \n", " \n", " ...\n", @@ -708,124 +780,124 @@ " ...\n", " \n", " \n", - " 2713\n", - " 0.149379\n", - " -0.222494\n", - " 0.303324\n", - " 0.306326\n", - " -0.254602\n", - " -0.536148\n", - " -0.470110\n", - " 0.565999\n", - " 0.020586\n", - " 0.609108\n", + " 334\n", + " -0.593350\n", + " 0.112945\n", + " 0.123807\n", + " 0.948721\n", + " -0.276408\n", + " -0.603181\n", + " -0.392917\n", + " 0.388957\n", + " 0.126814\n", + " 1.126764\n", " ...\n", - " -0.090419\n", - " 0.125347\n", - " 0.540859\n", - " -0.566799\n", - " 0.642269\n", - " 0.503141\n", - " -0.070126\n", - " -0.351428\n", - " 1.435632\n", - " 0.075295\n", + " -0.089558\n", + " -0.331218\n", + " 0.120006\n", + " -0.712097\n", + " -0.205538\n", + " 0.562405\n", + " 0.525867\n", + " -0.204776\n", + " -0.197538\n", + " -0.018287\n", " \n", " \n", - " 2714\n", - " 0.202084\n", - " -0.421907\n", - " 0.331125\n", - " 0.261079\n", - " -0.179134\n", - " -0.532431\n", - " -0.164233\n", - " 0.277176\n", - " -0.106925\n", - " 0.391598\n", + " 1264\n", + " 0.476763\n", + " 0.199641\n", + " 0.226375\n", + " 0.824276\n", + " -0.438520\n", + " -0.420465\n", + " 0.386475\n", + " 0.275413\n", + " -0.350755\n", + " 0.047801\n", " ...\n", - " -0.046802\n", - " 0.067547\n", - " 0.484514\n", - " -0.824181\n", - " 0.475694\n", - " 0.329913\n", - " -0.104037\n", - " -0.155081\n", - " 0.928627\n", - " -0.082177\n", + " 0.755453\n", + " 0.358454\n", + " 0.348341\n", + " -1.133082\n", + " -0.210484\n", + " -0.764606\n", + " 0.916726\n", + " -0.284010\n", + " -0.056577\n", + " 0.407399\n", " \n", " \n", - " 2715\n", - " -0.627377\n", - " -0.391843\n", - " 0.218678\n", - " -0.014267\n", - " -0.460290\n", - " -0.329174\n", - " -0.482513\n", - " 0.604713\n", - " 0.011763\n", - " 0.018444\n", + " 1171\n", + " -0.270009\n", + " 0.170292\n", + " 0.052011\n", + " 0.060369\n", + " -0.265923\n", + " 0.717389\n", + " -0.561747\n", + " 0.256904\n", + " 0.061957\n", + " 0.049001\n", " ...\n", - " 0.275013\n", - " 0.164754\n", - " 0.408749\n", - " -0.332821\n", - " 0.696610\n", - " 0.529032\n", - " 0.067081\n", - " -0.382973\n", - " 1.094504\n", - " 0.503912\n", + " -0.322604\n", + " -0.409145\n", + " 0.270570\n", + " -0.290132\n", + " 0.037762\n", + " 0.646035\n", + " -0.226534\n", + " 0.178052\n", + " 0.890680\n", + " -0.204422\n", " \n", " \n", - " 2716\n", - " 0.148124\n", - " -0.041698\n", - " 0.083552\n", - " 0.132032\n", - " -0.663597\n", - " 0.103373\n", - " -0.261431\n", - " -0.024310\n", - " 0.381935\n", - " 0.062252\n", + " 589\n", + " 0.217439\n", + " 0.188192\n", + " -0.186874\n", + " 0.108394\n", + " 0.318829\n", + " 0.049164\n", + " -0.460243\n", + " 0.502261\n", + " -0.304636\n", + " 0.176173\n", " ...\n", - " 0.362344\n", - " 0.360328\n", - " -0.020871\n", - " -0.640752\n", - " 0.638189\n", - " -0.118096\n", - " 0.245733\n", - " -0.404834\n", - " 0.754788\n", - " -0.139678\n", + " 0.700581\n", + " 0.730317\n", + " 0.152944\n", + " 0.017145\n", + " 0.597685\n", + " 0.536023\n", + " -0.020815\n", + " -0.774539\n", + " 0.354638\n", + " 0.153618\n", " \n", " \n", - " 2717\n", - " 0.148124\n", - " -0.041698\n", - " 0.083552\n", - " 0.132032\n", - " -0.663597\n", - " 0.103373\n", - " -0.261431\n", - " -0.024310\n", - " 0.381935\n", - " 0.062252\n", + " 2342\n", + " -0.477632\n", + " -0.784202\n", + " -0.383131\n", + " 0.669990\n", + " -0.100068\n", + " -0.294655\n", + " -0.627293\n", + " 0.058967\n", + " -0.455835\n", + " 0.461948\n", " ...\n", - " 0.362344\n", - " 0.360328\n", - " -0.020871\n", - " -0.640752\n", - " 0.638189\n", - " -0.118096\n", - " 0.245733\n", - " -0.404834\n", - " 0.754788\n", - " -0.139678\n", + " 0.381159\n", + " 0.021592\n", + " 0.348291\n", + " -0.903526\n", + " 0.694809\n", + " 0.018819\n", + " -0.002837\n", + " 0.023364\n", + " 0.385524\n", + " -0.437104\n", " \n", " \n", "\n", @@ -834,134 +906,134 @@ ], "text/plain": [ " Agent 2_Source_Evidence_0 Agent 2_Source_Evidence_1 \\\n", - "0 -0.253210 -0.092555 \n", - "1 0.246941 0.124175 \n", - "2 -0.068820 -0.323506 \n", - "3 -0.193803 -0.272143 \n", - "4 0.099981 -0.147359 \n", + "1935 -0.187781 -0.387294 \n", + "1583 -0.389066 -0.087771 \n", + "2351 -0.423137 0.182216 \n", + "452 -0.095392 0.142223 \n", + "8 -0.477632 -0.784202 \n", "... ... ... \n", - "2713 0.149379 -0.222494 \n", - "2714 0.202084 -0.421907 \n", - "2715 -0.627377 -0.391843 \n", - "2716 0.148124 -0.041698 \n", - "2717 0.148124 -0.041698 \n", + "334 -0.593350 0.112945 \n", + "1264 0.476763 0.199641 \n", + "1171 -0.270009 0.170292 \n", + "589 0.217439 0.188192 \n", + "2342 -0.477632 -0.784202 \n", "\n", " Agent 2_Source_Evidence_2 Agent 2_Source_Evidence_3 \\\n", - "0 -0.086723 -0.157253 \n", - "1 0.269999 0.181342 \n", - "2 -0.206149 0.559626 \n", - "3 -0.208212 0.341019 \n", - "4 -0.181383 0.436541 \n", + "1935 -0.160111 0.533505 \n", + "1583 -0.775325 0.130028 \n", + "2351 -0.133435 0.217782 \n", + "452 -0.686644 0.674334 \n", + "8 -0.383131 0.669990 \n", "... ... ... \n", - "2713 0.303324 0.306326 \n", - "2714 0.331125 0.261079 \n", - "2715 0.218678 -0.014267 \n", - "2716 0.083552 0.132032 \n", - "2717 0.083552 0.132032 \n", + "334 0.123807 0.948721 \n", + "1264 0.226375 0.824276 \n", + "1171 0.052011 0.060369 \n", + "589 -0.186874 0.108394 \n", + "2342 -0.383131 0.669990 \n", "\n", " Agent 2_Source_Evidence_4 Agent 2_Source_Evidence_5 \\\n", - "0 -0.204900 0.122437 \n", - "1 -0.505962 0.210211 \n", - "2 0.145691 -0.100530 \n", - "3 -0.175586 0.149454 \n", - "4 0.026173 -0.218141 \n", + "1935 -0.012384 -0.036983 \n", + "1583 0.172289 -0.208622 \n", + "2351 -0.094416 -0.097829 \n", + "452 -0.228214 0.109001 \n", + "8 -0.100068 -0.294655 \n", "... ... ... \n", - "2713 -0.254602 -0.536148 \n", - "2714 -0.179134 -0.532431 \n", - "2715 -0.460290 -0.329174 \n", - "2716 -0.663597 0.103373 \n", - "2717 -0.663597 0.103373 \n", + "334 -0.276408 -0.603181 \n", + "1264 -0.438520 -0.420465 \n", + "1171 -0.265923 0.717389 \n", + "589 0.318829 0.049164 \n", + "2342 -0.100068 -0.294655 \n", "\n", " Agent 2_Source_Evidence_6 Agent 2_Source_Evidence_7 \\\n", - "0 -0.529797 -0.015322 \n", - "1 0.140408 0.468697 \n", - "2 -0.492642 -0.207871 \n", - "3 -0.245428 -0.008559 \n", - "4 -0.193041 0.030840 \n", + "1935 -0.227363 0.305134 \n", + "1583 -0.874529 0.382446 \n", + "2351 -0.876501 0.797395 \n", + "452 -0.440772 0.124842 \n", + "8 -0.627293 0.058967 \n", "... ... ... \n", - "2713 -0.470110 0.565999 \n", - "2714 -0.164233 0.277176 \n", - "2715 -0.482513 0.604713 \n", - "2716 -0.261431 -0.024310 \n", - "2717 -0.261431 -0.024310 \n", + "334 -0.392917 0.388957 \n", + "1264 0.386475 0.275413 \n", + "1171 -0.561747 0.256904 \n", + "589 -0.460243 0.502261 \n", + "2342 -0.627293 0.058967 \n", "\n", " Agent 2_Source_Evidence_8 Agent 2_Source_Evidence_9 ... \\\n", - "0 -0.564774 0.769105 ... \n", - "1 0.321780 -0.128226 ... \n", - "2 -0.306911 0.365237 ... \n", - "3 0.279371 0.312212 ... \n", - "4 0.436779 0.392634 ... \n", + "1935 -0.053135 0.242913 ... \n", + "1583 0.483579 -0.309687 ... \n", + "2351 -0.277968 -0.045989 ... \n", + "452 -0.066046 0.171612 ... \n", + "8 -0.455835 0.461948 ... \n", "... ... ... ... \n", - "2713 0.020586 0.609108 ... \n", - "2714 -0.106925 0.391598 ... \n", - "2715 0.011763 0.018444 ... \n", - "2716 0.381935 0.062252 ... \n", - "2717 0.381935 0.062252 ... \n", + "334 0.126814 1.126764 ... \n", + "1264 -0.350755 0.047801 ... \n", + "1171 0.061957 0.049001 ... \n", + "589 -0.304636 0.176173 ... \n", + "2342 -0.455835 0.461948 ... \n", "\n", " Agent 2_Source_Evidence_758 Agent 2_Source_Evidence_759 \\\n", - "0 0.170976 -0.685452 \n", - "1 0.896930 -0.324542 \n", - "2 0.702710 0.152173 \n", - "3 0.451480 0.413026 \n", - "4 0.505176 0.505908 \n", + "1935 0.295774 0.358959 \n", + "1583 0.152333 -0.175365 \n", + "2351 1.015161 0.453668 \n", + "452 -0.009296 0.564043 \n", + "8 0.381159 0.021592 \n", "... ... ... \n", - "2713 -0.090419 0.125347 \n", - "2714 -0.046802 0.067547 \n", - "2715 0.275013 0.164754 \n", - "2716 0.362344 0.360328 \n", - "2717 0.362344 0.360328 \n", + "334 -0.089558 -0.331218 \n", + "1264 0.755453 0.358454 \n", + "1171 -0.322604 -0.409145 \n", + "589 0.700581 0.730317 \n", + "2342 0.381159 0.021592 \n", "\n", " Agent 2_Source_Evidence_760 Agent 2_Source_Evidence_761 \\\n", - "0 0.295997 -0.593129 \n", - "1 -0.291376 -0.565900 \n", - "2 0.309572 -0.461615 \n", - "3 -0.211110 -0.550950 \n", - "4 -0.286257 -0.614761 \n", + "1935 0.566532 -0.852727 \n", + "1583 0.676532 -0.393536 \n", + "2351 0.440656 -0.040266 \n", + "452 0.178982 -0.222556 \n", + "8 0.348291 -0.903526 \n", "... ... ... \n", - "2713 0.540859 -0.566799 \n", - "2714 0.484514 -0.824181 \n", - "2715 0.408749 -0.332821 \n", - "2716 -0.020871 -0.640752 \n", - "2717 -0.020871 -0.640752 \n", + "334 0.120006 -0.712097 \n", + "1264 0.348341 -1.133082 \n", + "1171 0.270570 -0.290132 \n", + "589 0.152944 0.017145 \n", + "2342 0.348291 -0.903526 \n", "\n", " Agent 2_Source_Evidence_762 Agent 2_Source_Evidence_763 \\\n", - "0 0.390818 0.249091 \n", - "1 0.524987 -0.196209 \n", - "2 0.666504 -0.016534 \n", - "3 0.556309 -0.521065 \n", - "4 0.811958 -0.615687 \n", + "1935 0.118316 -0.122535 \n", + "1583 0.014875 -0.383976 \n", + "2351 0.693482 0.169744 \n", + "452 0.523386 0.331242 \n", + "8 0.694809 0.018819 \n", "... ... ... \n", - "2713 0.642269 0.503141 \n", - "2714 0.475694 0.329913 \n", - "2715 0.696610 0.529032 \n", - "2716 0.638189 -0.118096 \n", - "2717 0.638189 -0.118096 \n", + "334 -0.205538 0.562405 \n", + "1264 -0.210484 -0.764606 \n", + "1171 0.037762 0.646035 \n", + "589 0.597685 0.536023 \n", + "2342 0.694809 0.018819 \n", "\n", " Agent 2_Source_Evidence_764 Agent 2_Source_Evidence_765 \\\n", - "0 -0.099062 0.051298 \n", - "1 -0.519527 -0.216939 \n", - "2 0.877414 -0.203894 \n", - "3 0.327162 -0.200601 \n", - "4 0.479651 -0.345834 \n", + "1935 0.347825 0.101922 \n", + "1583 0.081081 0.298928 \n", + "2351 0.060993 -0.500294 \n", + "452 0.360143 -0.011475 \n", + "8 -0.002837 0.023364 \n", "... ... ... \n", - "2713 -0.070126 -0.351428 \n", - "2714 -0.104037 -0.155081 \n", - "2715 0.067081 -0.382973 \n", - "2716 0.245733 -0.404834 \n", - "2717 0.245733 -0.404834 \n", + "334 0.525867 -0.204776 \n", + "1264 0.916726 -0.284010 \n", + "1171 -0.226534 0.178052 \n", + "589 -0.020815 -0.774539 \n", + "2342 -0.002837 0.023364 \n", "\n", " Agent 2_Source_Evidence_766 Agent 2_Source_Evidence_767 \n", - "0 0.319292 0.244462 \n", - "1 0.862336 0.193277 \n", - "2 0.450191 -0.544430 \n", - "3 0.148922 -0.181214 \n", - "4 0.185110 -0.311448 \n", + "1935 0.386412 -0.644331 \n", + "1583 0.596412 -0.605296 \n", + "2351 0.649334 0.195239 \n", + "452 0.105367 0.146013 \n", + "8 0.385524 -0.437104 \n", "... ... ... \n", - "2713 1.435632 0.075295 \n", - "2714 0.928627 -0.082177 \n", - "2715 1.094504 0.503912 \n", - "2716 0.754788 -0.139678 \n", - "2717 0.754788 -0.139678 \n", + "334 -0.197538 -0.018287 \n", + "1264 -0.056577 0.407399 \n", + "1171 0.890680 -0.204422 \n", + "589 0.354638 0.153618 \n", + "2342 0.385524 -0.437104 \n", "\n", "[2718 rows x 768 columns]" ] @@ -972,8 +1044,8 @@ } ], "source": [ - "# the resulting X = features matrix\n", - "X = g2._get_feature('nodes')\n", + "# the resulting X = features matrix, sbert encoding\n", + "X = g2.get_matrix()\n", "X" ] }, @@ -1004,95 +1076,89 @@ " \n", " \n", " \n", - " Relationship: sanctioned, sanction, violation\n", - " Relationship: smuggling, bribery, in\n", + " Relationship: occupied, functions, sanctions\n", + " Relationship: laundering, overpricing, international\n", " Relationship: integrates, company, in\n", + " Relationship: complaints, corruption, traffic\n", + " Relationship: sanctioned, sanction, evasion\n", + " Relationship: facilitators, colleagues, student\n", + " Relationship: designates, charge, rights\n", " Relationship: connection, business, in\n", - " Relationship: complaints, corruption, conspiracy\n", - " Relationship: suscribed, traffic, contract\n", - " Relationship: occupied, functions, sanctions\n", - " Relationship: overpricing, currency, illegal\n", - " Relationship: laundering, international, trials\n", " Relationship: members, family, enemies\n", - " Relationship: facilitators, extortion, friends\n", - " Relationship: designates, colleagues, charge\n", + " Relationship: smuggling, bribery, currency\n", + " Relationship: conspiracy, suscribed, contract\n", " \n", " \n", " \n", " \n", - " 0\n", - " 0.065003\n", - " 0.055670\n", - " 0.071783\n", - " 0.079073\n", - " 34.442679\n", - " 0.054766\n", - " 0.063643\n", - " 0.053862\n", - " 0.057605\n", - " 0.050000\n", - " 0.052458\n", - " 0.053457\n", + " 1935\n", + " 0.072898\n", + " 0.553233\n", + " 0.089311\n", + " 0.068496\n", + " 0.075216\n", + " 0.058883\n", + " 0.059063\n", + " 0.091499\n", + " 0.067527\n", + " 42.147305\n", + " 42.766569\n", " \n", " \n", - " 1\n", - " 0.050119\n", - " 0.050523\n", - " 0.051003\n", + " 1583\n", + " 23.982221\n", + " 0.053704\n", + " 0.050000\n", + " 0.055351\n", + " 0.090587\n", " 0.050000\n", - " 0.051689\n", - " 0.051122\n", + " 0.050001\n", + " 0.062470\n", " 0.050000\n", - " 0.050509\n", - " 0.050418\n", - " 0.054442\n", - " 15.039365\n", - " 0.050809\n", + " 0.052716\n", + " 0.052951\n", " \n", " \n", - " 2\n", - " 0.082737\n", - " 0.052691\n", - " 0.050000\n", - " 0.062643\n", - " 0.055349\n", - " 0.053101\n", - " 23.987324\n", - " 0.052330\n", - " 0.053825\n", + " 2351\n", + " 23.982221\n", + " 0.053704\n", " 0.050000\n", + " 0.055351\n", + " 0.090587\n", " 0.050000\n", + " 0.050001\n", + " 0.062470\n", " 0.050000\n", + " 0.052716\n", + " 0.052951\n", " \n", " \n", - " 3\n", - " 0.074388\n", - " 28.567443\n", - " 0.065518\n", - " 0.063843\n", - " 0.060323\n", - " 0.117900\n", - " 0.064166\n", - " 60.674413\n", - " 17.229793\n", - " 0.065414\n", - " 0.055578\n", - " 0.061222\n", + " 452\n", + " 23.982221\n", + " 0.053704\n", + " 0.050000\n", + " 0.055351\n", + " 0.090587\n", + " 0.050000\n", + " 0.050001\n", + " 0.062470\n", + " 0.050000\n", + " 0.052716\n", + " 0.052951\n", " \n", " \n", - " 4\n", - " 0.067568\n", - " 31.116316\n", - " 0.058412\n", - " 0.060998\n", - " 0.056463\n", - " 0.060142\n", - " 0.057811\n", - " 0.117512\n", - " 37.838020\n", - " 0.059851\n", - " 0.051573\n", - " 0.055335\n", + " 8\n", + " 0.072986\n", + " 0.053850\n", + " 0.051025\n", + " 0.053534\n", + " 16.497892\n", + " 0.050000\n", + " 0.050001\n", + " 0.065366\n", + " 0.050000\n", + " 0.053286\n", + " 0.052058\n", " \n", " \n", " ...\n", @@ -1107,246 +1173,227 @@ " ...\n", " ...\n", " ...\n", - " ...\n", " \n", " \n", - " 2713\n", - " 0.051717\n", - " 0.053141\n", - " 23.986537\n", - " 0.073292\n", - " 0.059816\n", - " 0.053714\n", - " 0.050000\n", - " 0.052808\n", + " 334\n", + " 0.072986\n", " 0.053850\n", + " 0.051025\n", + " 0.053534\n", + " 16.497892\n", " 0.050000\n", - " 0.051797\n", - " 0.063327\n", + " 0.050001\n", + " 0.065366\n", + " 0.050000\n", + " 0.053286\n", + " 0.052058\n", " \n", " \n", - " 2714\n", - " 0.072604\n", - " 0.052956\n", - " 0.092982\n", - " 23.941857\n", - " 0.063406\n", - " 0.054355\n", - " 0.061778\n", - " 0.052354\n", - " 0.054615\n", - " 0.052002\n", + " 1264\n", + " 0.072986\n", + " 0.053850\n", + " 0.051025\n", + " 0.053534\n", + " 16.497892\n", + " 0.050000\n", + " 0.050001\n", + " 0.065366\n", " 0.050000\n", - " 0.051090\n", + " 0.053286\n", + " 0.052058\n", " \n", " \n", - " 2715\n", - " 0.082737\n", - " 0.052691\n", - " 0.050000\n", - " 0.062643\n", - " 0.055349\n", - " 0.053101\n", - " 23.987324\n", - " 0.052330\n", - " 0.053825\n", + " 1171\n", " 0.050000\n", + " 0.051786\n", " 0.050000\n", + " 0.050037\n", + " 0.050001\n", + " 0.054220\n", " 0.050000\n", + " 0.050705\n", + " 18.039779\n", + " 0.052556\n", + " 0.050917\n", " \n", " \n", - " 2716\n", - " 0.071095\n", - " 0.299774\n", - " 0.070829\n", - " 0.064280\n", - " 0.060561\n", - " 0.064907\n", - " 0.062544\n", - " 25.575909\n", - " 20.649126\n", - " 0.051986\n", - " 0.070271\n", - " 0.058718\n", + " 589\n", + " 0.050000\n", + " 0.053772\n", + " 23.990746\n", + " 0.059230\n", + " 0.051608\n", + " 0.052662\n", + " 0.060380\n", + " 0.072165\n", + " 0.050000\n", + " 0.053006\n", + " 0.056433\n", " \n", " \n", - " 2717\n", - " 0.071095\n", - " 0.299774\n", - " 0.070829\n", - " 0.064280\n", - " 0.060561\n", - " 0.064907\n", - " 0.062544\n", - " 25.575909\n", - " 20.649126\n", - " 0.051986\n", - " 0.070271\n", - " 0.058718\n", + " 2342\n", + " 0.072986\n", + " 0.053850\n", + " 0.051025\n", + " 0.053534\n", + " 16.497892\n", + " 0.050000\n", + " 0.050001\n", + " 0.065366\n", + " 0.050000\n", + " 0.053286\n", + " 0.052058\n", " \n", " \n", "\n", - "

2718 rows × 12 columns

\n", + "

2718 rows × 11 columns

\n", "" ], "text/plain": [ - " Relationship: sanctioned, sanction, violation \\\n", - "0 0.065003 \n", - "1 0.050119 \n", - "2 0.082737 \n", - "3 0.074388 \n", - "4 0.067568 \n", - "... ... \n", - "2713 0.051717 \n", - "2714 0.072604 \n", - "2715 0.082737 \n", - "2716 0.071095 \n", - "2717 0.071095 \n", + " Relationship: occupied, functions, sanctions \\\n", + "1935 0.072898 \n", + "1583 23.982221 \n", + "2351 23.982221 \n", + "452 23.982221 \n", + "8 0.072986 \n", + "... ... \n", + "334 0.072986 \n", + "1264 0.072986 \n", + "1171 0.050000 \n", + "589 0.050000 \n", + "2342 0.072986 \n", "\n", - " Relationship: smuggling, bribery, in \\\n", - "0 0.055670 \n", - "1 0.050523 \n", - "2 0.052691 \n", - "3 28.567443 \n", - "4 31.116316 \n", - "... ... \n", - "2713 0.053141 \n", - "2714 0.052956 \n", - "2715 0.052691 \n", - "2716 0.299774 \n", - "2717 0.299774 \n", + " Relationship: laundering, overpricing, international \\\n", + "1935 0.553233 \n", + "1583 0.053704 \n", + "2351 0.053704 \n", + "452 0.053704 \n", + "8 0.053850 \n", + "... ... \n", + "334 0.053850 \n", + "1264 0.053850 \n", + "1171 0.051786 \n", + "589 0.053772 \n", + "2342 0.053850 \n", "\n", " Relationship: integrates, company, in \\\n", - "0 0.071783 \n", - "1 0.051003 \n", - "2 0.050000 \n", - "3 0.065518 \n", - "4 0.058412 \n", + "1935 0.089311 \n", + "1583 0.050000 \n", + "2351 0.050000 \n", + "452 0.050000 \n", + "8 0.051025 \n", "... ... \n", - "2713 23.986537 \n", - "2714 0.092982 \n", - "2715 0.050000 \n", - "2716 0.070829 \n", - "2717 0.070829 \n", - "\n", - " Relationship: connection, business, in \\\n", - "0 0.079073 \n", - "1 0.050000 \n", - "2 0.062643 \n", - "3 0.063843 \n", - "4 0.060998 \n", - "... ... \n", - "2713 0.073292 \n", - "2714 23.941857 \n", - "2715 0.062643 \n", - "2716 0.064280 \n", - "2717 0.064280 \n", + "334 0.051025 \n", + "1264 0.051025 \n", + "1171 0.050000 \n", + "589 23.990746 \n", + "2342 0.051025 \n", "\n", - " Relationship: complaints, corruption, conspiracy \\\n", - "0 34.442679 \n", - "1 0.051689 \n", - "2 0.055349 \n", - "3 0.060323 \n", - "4 0.056463 \n", - "... ... \n", - "2713 0.059816 \n", - "2714 0.063406 \n", - "2715 0.055349 \n", - "2716 0.060561 \n", - "2717 0.060561 \n", + " Relationship: complaints, corruption, traffic \\\n", + "1935 0.068496 \n", + "1583 0.055351 \n", + "2351 0.055351 \n", + "452 0.055351 \n", + "8 0.053534 \n", + "... ... \n", + "334 0.053534 \n", + "1264 0.053534 \n", + "1171 0.050037 \n", + "589 0.059230 \n", + "2342 0.053534 \n", "\n", - " Relationship: suscribed, traffic, contract \\\n", - "0 0.054766 \n", - "1 0.051122 \n", - "2 0.053101 \n", - "3 0.117900 \n", - "4 0.060142 \n", - "... ... \n", - "2713 0.053714 \n", - "2714 0.054355 \n", - "2715 0.053101 \n", - "2716 0.064907 \n", - "2717 0.064907 \n", + " Relationship: sanctioned, sanction, evasion \\\n", + "1935 0.075216 \n", + "1583 0.090587 \n", + "2351 0.090587 \n", + "452 0.090587 \n", + "8 16.497892 \n", + "... ... \n", + "334 16.497892 \n", + "1264 16.497892 \n", + "1171 0.050001 \n", + "589 0.051608 \n", + "2342 16.497892 \n", "\n", - " Relationship: occupied, functions, sanctions \\\n", - "0 0.063643 \n", - "1 0.050000 \n", - "2 23.987324 \n", - "3 0.064166 \n", - "4 0.057811 \n", - "... ... \n", - "2713 0.050000 \n", - "2714 0.061778 \n", - "2715 23.987324 \n", - "2716 0.062544 \n", - "2717 0.062544 \n", + " Relationship: facilitators, colleagues, student \\\n", + "1935 0.058883 \n", + "1583 0.050000 \n", + "2351 0.050000 \n", + "452 0.050000 \n", + "8 0.050000 \n", + "... ... \n", + "334 0.050000 \n", + "1264 0.050000 \n", + "1171 0.054220 \n", + "589 0.052662 \n", + "2342 0.050000 \n", "\n", - " Relationship: overpricing, currency, illegal \\\n", - "0 0.053862 \n", - "1 0.050509 \n", - "2 0.052330 \n", - "3 60.674413 \n", - "4 0.117512 \n", - "... ... \n", - "2713 0.052808 \n", - "2714 0.052354 \n", - "2715 0.052330 \n", - "2716 25.575909 \n", - "2717 25.575909 \n", + " Relationship: designates, charge, rights \\\n", + "1935 0.059063 \n", + "1583 0.050001 \n", + "2351 0.050001 \n", + "452 0.050001 \n", + "8 0.050001 \n", + "... ... \n", + "334 0.050001 \n", + "1264 0.050001 \n", + "1171 0.050000 \n", + "589 0.060380 \n", + "2342 0.050001 \n", "\n", - " Relationship: laundering, international, trials \\\n", - "0 0.057605 \n", - "1 0.050418 \n", - "2 0.053825 \n", - "3 17.229793 \n", - "4 37.838020 \n", - "... ... \n", - "2713 0.053850 \n", - "2714 0.054615 \n", - "2715 0.053825 \n", - "2716 20.649126 \n", - "2717 20.649126 \n", + " Relationship: connection, business, in \\\n", + "1935 0.091499 \n", + "1583 0.062470 \n", + "2351 0.062470 \n", + "452 0.062470 \n", + "8 0.065366 \n", + "... ... \n", + "334 0.065366 \n", + "1264 0.065366 \n", + "1171 0.050705 \n", + "589 0.072165 \n", + "2342 0.065366 \n", "\n", " Relationship: members, family, enemies \\\n", - "0 0.050000 \n", - "1 0.054442 \n", - "2 0.050000 \n", - "3 0.065414 \n", - "4 0.059851 \n", + "1935 0.067527 \n", + "1583 0.050000 \n", + "2351 0.050000 \n", + "452 0.050000 \n", + "8 0.050000 \n", "... ... \n", - "2713 0.050000 \n", - "2714 0.052002 \n", - "2715 0.050000 \n", - "2716 0.051986 \n", - "2717 0.051986 \n", + "334 0.050000 \n", + "1264 0.050000 \n", + "1171 18.039779 \n", + "589 0.050000 \n", + "2342 0.050000 \n", "\n", - " Relationship: facilitators, extortion, friends \\\n", - "0 0.052458 \n", - "1 15.039365 \n", - "2 0.050000 \n", - "3 0.055578 \n", - "4 0.051573 \n", - "... ... \n", - "2713 0.051797 \n", - "2714 0.050000 \n", - "2715 0.050000 \n", - "2716 0.070271 \n", - "2717 0.070271 \n", + " Relationship: smuggling, bribery, currency \\\n", + "1935 42.147305 \n", + "1583 0.052716 \n", + "2351 0.052716 \n", + "452 0.052716 \n", + "8 0.053286 \n", + "... ... \n", + "334 0.053286 \n", + "1264 0.053286 \n", + "1171 0.052556 \n", + "589 0.053006 \n", + "2342 0.053286 \n", "\n", - " Relationship: designates, colleagues, charge \n", - "0 0.053457 \n", - "1 0.050809 \n", - "2 0.050000 \n", - "3 0.061222 \n", - "4 0.055335 \n", - "... ... \n", - "2713 0.063327 \n", - "2714 0.051090 \n", - "2715 0.050000 \n", - "2716 0.058718 \n", - "2717 0.058718 \n", + " Relationship: conspiracy, suscribed, contract \n", + "1935 42.766569 \n", + "1583 0.052951 \n", + "2351 0.052951 \n", + "452 0.052951 \n", + "8 0.052058 \n", + "... ... \n", + "334 0.052058 \n", + "1264 0.052058 \n", + "1171 0.050917 \n", + "589 0.056433 \n", + "2342 0.052058 \n", "\n", - "[2718 rows x 12 columns]" + "[2718 rows x 11 columns]" ] }, "execution_count": 17, @@ -1356,7 +1403,7 @@ ], "source": [ "# we've reorganized 68 relationships into N topics and we see it has understood the semantics correctly\n", - "y = g2._get_target('nodes')\n", + "y = g2.get_matrix(target=True)\n", "y" ] }, @@ -1378,7 +1425,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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vzK5tz0JCQlkZ//9/64zZswgMTGxJsIFKJUI/Epjx44tVXdN7bcmOTs7V/szDz30UI1kKGhoFi9ezEcffVTu+z/99BPDhg2r8Xr37t1bKmenPXl5ebz77rs1Xrc9tf1vBmru+q71pz4VRXEG1gLPq6r6h6Io7wFzALXov28BY2qgnvHAeID77rvvWncnhLgZzGxZw/s7U2mR4hRS8HfuzeJE4FcrISGBgQMH4uHhAdiSadeVZcuW1VlddUFVVVRV5csvv6zvUKqkOF4Hh8rHXQoKCipd8Lht27ZaNoea5OPjg4+P3WXCNMUdtUmTJlV5v9U5/pLq899MddXqiJqiKE2wddLiVFVdB6Cq6klVVS+rqloILOXv25u5wL0lPt6uaFt520tRVXWJqqo+qqr63HHHHTV/MEIIUcP8/f3JzbX9OcvJyaFfv354e3sTGBhoN3XT0qVL8fX1xWg0MnToUM6fP09ycjIbNmwgIiICk8lETk4O4eHh2pdtUlISZrMZvV7PmDFjtGTvLi4uREZG4uXlhV6v1+rbtm0bJpMJk8mE2WzW0vzk5+czbNgw3NzcCAsL01br79WrF8ULjDs7OzN16lQ8PT0JCgri1KlTVW6LlJQU/P39MZvNdOvWjUOHDgEQGxtbau2ygQMHajlOnZ2defXVVzEajXTt2lVL0v3999/j7++PXq/XVt8vFhUVha+vLwaDgcjISACsViudO3fmySefRKfTcfz4cVxcXPj111+xWq24u7szbtw4PD096dOnj5abc8+ePRgMBkwmExEREeh0ukqP8+2330an06HT6ViwYAFgy68aExOjlSk5ilrVeMtr+169evH888/j4+PDwoULS+37yJEjPPjggxiNRry8vMjJycFqtWrHERsbS0hICP369aNjx46lkqMvX76cTp064efnx7hx4ypdX67k6NLMmTMZM2YMvXr1on379kRHR2vtkJOTo7VnVY9/x44d5Z6juvg3U961W1Nq86lPBVgOHFBV9e0S29uUKDYE2F/0+wZghKIoTRVFcQU6AinAHqCjoiiuiqL8A9sDBxtqK24hhKgLly9fJikpSVvhfvz48SxatIjU1FTmzZtnd1QhJCSEPXv2kJ6ejru7O8uXL6dbt24MHjyYqKgoLBYLHTr8nTHl4sWLhIeHEx8fT2ZmJgUFBbz33nva+61btyYtLY2J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1KkKjz8rKws/Pz9MJhMGg0FLjP7II4/g7e2Np6cnS5Ys0co7Ozvz6quvasnUT548CcDJkycZMmQIRqMRo9FIcnIy06dPJycnB5PJREREBFarFZ1OB9hyYo4ePRq9Xo/ZbNZWtY+NjSUkJIR+/frRsWNHXn75Za3uzZs34+/vj5eXF6GhodpSJF999RVubm54eXmxbt26Ss/5iRMn6NGjhzaqumPHDgAmTpyIj48Pnp6eREZGauXLO0/5+fnaMRgMBtauXcv06dO5cOECJpOJsLAwrc3AlpYsIiICnU6HXq8nPj4esI0C9urVy+65Lc+pU6cYOnQovr6++Pr6smvXLgoLC3FxcSk1QtyxY0dOnjzJf/7zH7p06YLZbObBBx/Uzpu9a+1az9ONqNY6aqqqnigeEVNV9SxwALgHeBgoHhH7EHik6PeHgY9Um91AK0VR2gB9ga9VVf1NVdXfga+Bms96K4QQdejy5cskJSUxePBgAMaPH8+iRYtITU1l3rx52khQSSEhIezZs4f09HTc3d1Zvnw53bp1Y/DgwURFRWGxWOjQoYNW/uLFi4SHhxMfH09mZiYFBQW899572vutW7cmLS2NiRMnardX582bR0xMDBaLhR07dtCsWTMA9u3bx4IFC8jOzubo0aPs2rWrTHznzp3Dx8eHrKwsevbsyaxZs4DyU0gtXryY5557DovFwt69e2nXrh0AH3zwAampqezdu5fo6GhOnz6t7b9r166kp6fTo0cPli5dCsCUKVPo2bMn6enppKWl4enpydy5c+nQoQMWi4WoqKhS9cbExKAoCpmZmaxevZpRo0ZpScEtFovWXvHx8Rw/fpxff/2V119/ncTERNLS0vDx8eHtt9/m4sWLjBs3jv/85z+kpqby888/V3reV61aRd++fbFYLKSnp2MymQB444032Lt3LxkZGWzbto2MjIwKz9OcOXNo2bIlmZmZZGRk8MADDzB37lxtxPbK/Jnr1q3T6kxMTCQiIoITJ05U+dyW9NxzzzF16lT27NnD2rVrGTt2LA4ODjz88MOsX78egP/973/cf//93HXXXXTv3p3du3ezb98+RowYwb///W+g/Gvtas/TjapO5qgpiuICmIH/AXepqnqi6K2fsd0aBVsnrmRL/1i0rbztQghx3Ske8bj77rs5efIkwcHB5Ofnk5ycTGhoKCaTiaef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/JHk5OQyZZ977jmee+45MjMzadeuXan37F0jV7ajxWIhNzeX/fv3k5mZyejRoyuN5WYnHTUhhKhDFy5cwGQycffdd3Py5EmCg4PJz88nOTmZ0NBQTCYTTz/9NCdOnCjz2f379xMYGIherycuLo6srKwK6zp06BCurq506tQJsN1q3b59u/Z+SEgIAN7e3litVsCWDPuFF14gOjqavLw87Zaan58f7dq1w8HBAZPJpJUvycHBQcthOXLkSHbu3AnYbk3auz25fft2Ro4cCYDBYMBgMACwe/dusrOzCQgIwGQy8eGHH3Ls2DFatmyJo6MjTz31FOvWrStzKy0vL4+zZ8/i7+8PwOOPP17q/aCgIG0fHh4eHDt2DIBPP/0ULy8vzGYzWVlZdufcXW1MV0pMTOTpp5/W2vW2227T3rN3Ps6cOUNoaCg6nY6pU6eWOufBwcHa53fu3MmIESMAtNG6iuKuTGhoaJmOLsC3335LaGgoULZ9q3KNtG/fnqNHj/Lss8/y1VdflZuAXvxN5qgJIUQdKp6jdv78efr27UtMTAzh4eG0atWq0hyM4eHhJCQkYDQaiY2NZevWrdcUS9OmTQHbAw4FBQWA7TbegAED+PLLLwkICGDTpk2lyl5ZviKKolxVXKqqEhwczOrVq8u8l5KSQlJSEp999hnvvPMOW7ZsqfJ+7R3D999/z7x589izZw+33nor4eHhXLx4sc5ishdfyfb9v//7P3r37s369euxWq306tVLK9+8efNK91lR3BWpyr6vVJVr5NZbbyU9PZ1NmzaxePFiPv30Uz744INq13UzkRE1IYSoB05OTkRHR/PWW2/h5OSEq6sra9asAWxfrunp6WU+c/bsWdq0acOlS5eIi4vTtrdo0UKbS1ZS586dsVqtHDlyBICVK1fSs2fPCuPKyclBr9czbdo0fH197c6VK09hYaE2N27VqlV07969wvI9evRg1apVgG20MCMjA4CuXbuya9cuLe5z587x3XffkZ+fz5kzZ3jooYeYP39+mTZq1aoVLVq04H//+x8An3zySaUx//HHHzRv3pyWLVty8uRJ/vvf/2rvlWzX6sa0fv16XnnllTL1BQcH8/7772udmN9++63C+M6cOcM999wD2OallScgIIBPP/0UgOzsbDIzMyuMG+CVV15h/fr1FTfQFbp27cratWuBqrUvlG7H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\n", "text/plain": [ "
" ] @@ -1393,6 +1440,58 @@ "y.plot(kind='hist', figsize=(10,5)) " ] }, + { + "cell_type": "code", + "execution_count": 19, + "id": "46d25a40-deb2-4aac-96c6-d5b3e84a8d1d", + "metadata": {}, + "outputs": [], + "source": [ + "g2._nodes['rel_topic'] = [y.columns[k].replace('Relationship: ', '') for k in y.values.argmax(1)]" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "e81a96ce-407a-47ad-a31f-d6ac1798c4d2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1935 conspiracy, suscribed, contract\n", + "1583 occupied, functions, sanctions\n", + "2351 occupied, functions, sanctions\n", + "452 occupied, functions, sanctions\n", + "8 sanctioned, sanction, evasion\n", + " ... \n", + "334 sanctioned, sanction, evasion\n", + "1264 sanctioned, sanction, evasion\n", + "1171 members, family, enemies\n", + "589 integrates, company, in\n", + "2342 sanctioned, sanction, evasion\n", + "Name: rel_topic, Length: 2718, dtype: object" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g2._nodes['rel_topic']" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "feba6d2b-12a9-4143-ba22-7a3fadd3d430", + "metadata": {}, + "outputs": [], + "source": [ + "g2 = g2.nodes(g2._nodes, g2._node)" + ] + }, { "cell_type": "markdown", "id": "53574e47", @@ -1403,143 +1502,29 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 22, "id": "ce53de1d", - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [ { "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Agent 1RelationshipAgent 2SourceEvidence_distance
2497Gustavo Adolfo Hernández Frieri (USA, Colombia)International trials. Money laundering. Bribery. Illegal Currency traffic. Company connectionGlobal Securities Trade Finance (Cayman Islands)Court documentThe Operation Money Flight case mentions that Frieri laundered money from Ortega through a false structure of mutual funds.12.718029
2498Abraham Edgardo Ortega (Venezuela)International trials. Money laundering. Bribery. Illegal Currency traffic. Company connectionGlobal Securities Trade Finance (Cayman Islands)Court documentThe Operation Money Flight case mentions that Frieri laundered money from Ortega through a false structure of mutual funds.12.718029
109Alex Nain Saab Morán (Colombia)International trials. Money laundering. FraudDevis José Mendoza (Colombia)Recognized communication media (trustable)79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam.13.068510
1744Nervis Gerardo Villalobos Cárdenas (Venezuela)International trials. Money launderingGrupo Swissinvest (No information available)Court documentJudicial investigation in Spain points that through \"the structure of transnational character\" of Swissinvest group, \"money laundering operations were made\" inside and outside Spain to “raise capital from crimes of corruption” commited through Pdvsa.13.110929
659Diosdado Cabello Rondón (Venezuela)Complaints for corruptionPedro Fritz Morejon Carrillo (Venezuela)Recognized communication media (trustable)Accused of laundering around USD $1.300 millions in Panama, Costa Rica, Madrid and USA through companies, using money from corruption, drug traffic and terrorism.13.302184
\n", - "
" - ], "text/plain": [ - " Agent 1 \\\n", - "2497 Gustavo Adolfo Hernández Frieri (USA, Colombia) \n", - "2498 Abraham Edgardo Ortega (Venezuela) \n", - "109 Alex Nain Saab Morán (Colombia) \n", - "1744 Nervis Gerardo Villalobos Cárdenas (Venezuela) \n", - "659 Diosdado Cabello Rondón (Venezuela) \n", - "\n", - " Relationship \\\n", - "2497 International trials. Money laundering. Bribery. Illegal Currency traffic. Company connection \n", - "2498 International trials. Money laundering. Bribery. Illegal Currency traffic. Company connection \n", - "109 International trials. Money laundering. Fraud \n", - "1744 International trials. Money laundering \n", - "659 Complaints for corruption \n", - "\n", - " Agent 2 \\\n", - "2497 Global Securities Trade Finance (Cayman Islands) \n", - "2498 Global Securities Trade Finance (Cayman Islands) \n", - "109 Devis José Mendoza (Colombia) \n", - "1744 Grupo Swissinvest (No information available) \n", - "659 Pedro Fritz Morejon Carrillo (Venezuela) \n", - "\n", - " Source \\\n", - "2497 Court document \n", - "2498 Court document \n", - "109 Recognized communication media (trustable) \n", - "1744 Court document \n", - "659 Recognized communication media (trustable) \n", - "\n", - " Evidence \\\n", - "2497 The Operation Money Flight case mentions that Frieri laundered money from Ortega through a false structure of mutual funds. \n", - "2498 The Operation Money Flight case mentions that Frieri laundered money from Ortega through a false structure of mutual funds. \n", - "109 79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam. \n", - "1744 Judicial investigation in Spain points that through \"the structure of transnational character\" of Swissinvest group, \"money laundering operations were made\" inside and outside Spain to “raise capital from crimes of corruption” commited through Pdvsa. \n", - "659 Accused of laundering around USD $1.300 millions in Panama, Costa Rica, Madrid and USA through companies, using money from corruption, drug traffic and terrorism. \n", - "\n", - " _distance \n", - "2497 12.718029 \n", - "2498 12.718029 \n", - "109 13.068510 \n", - "1744 13.110929 \n", - "659 13.302184 " + "2498 smuggling, bribery, currency\n", + "2497 smuggling, bribery, currency\n", + "2482 connection, business, in\n", + "1744 laundering, overpricing, international\n", + "2487 connection, business, in\n", + "Name: rel_topic, dtype: object" ] }, - "execution_count": 19, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res, query_vector = g2.search('money laundering', top_n=5)\n", - "res" + "res.rel_topic" ] }, { @@ -1547,7 +1532,7 @@ "id": "d81d93d3", "metadata": {}, "source": [ - "# Search to Graph\n", + "## Search to Graph\n", "\n", "Pull in neighborhood data from a given search\n", "* the resulting graph will contain Agents connected to Agents that have been involved in Money Laundering (or whatever you wish to search for)\n", @@ -1556,17 +1541,34 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 23, "id": "01278b51", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=5392c6cefae944b38d192740ece8db4a&type=arrow&viztoken=d8174842-dda1-4b4a-9ce9-973a97e2e136&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813586&info=true'" + "" ] }, - "execution_count": 20, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -1578,7 +1580,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 24, "id": "69143805", "metadata": {}, "outputs": [ @@ -1608,6 +1610,7 @@ " Agent 2\n", " Source\n", " Evidence\n", + " rel_topic\n", " _distance\n", " \n", " \n", @@ -1619,6 +1622,7 @@ " Hermágoras González Polanco (Colombia)\n", " Recognized communication media (trustable)\n", " Colombian druf trafficker, leader of Guajira Cartel, according to the Narcogram, he is linked to Tareck El Aissami.\n", + " complaints, corruption, traffic\n", " 13.883661\n", " \n", " \n", @@ -1628,6 +1632,7 @@ " Robinson Ruíz Guerrero (Colombia)\n", " Recognized communication media (trustable)\n", " 79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam.\n", + " laundering, overpricing, international\n", " 13.998826\n", " \n", " \n", @@ -1637,6 +1642,7 @@ " Luis Alberto Saab Morán (Colombia)\n", " Recognized communication media (trustable)\n", " 79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam.\n", + " laundering, overpricing, international\n", " 14.068014\n", " \n", " \n", @@ -1646,6 +1652,7 @@ " Jaime Alberto Marín Zamora (Colombia)\n", " Recognized communication media (trustable)\n", " Denounces links between drug lords, scam groups, money laundering and a network of SAIME offices. Ditter José Marcano was pointed.\n", + " complaints, corruption, traffic\n", " 14.180918\n", " \n", " \n", @@ -1655,6 +1662,7 @@ " Amir Luis Saab Morán (Colombia)\n", " Recognized communication media (trustable)\n", " 79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam.\n", + " laundering, overpricing, international\n", " 14.181194\n", " \n", " \n", @@ -1697,15 +1705,15 @@ "668 Denounces links between drug lords, scam groups, money laundering and a network of SAIME offices. Ditter José Marcano was pointed. \n", "110 79th Court of Guarantee control of Colombia investigates money laundering, conspiracy to commit a crime, illicit enrichment, fake export or import and aggravated scam. \n", "\n", - " _distance \n", - "2233 13.883661 \n", - "108 13.998826 \n", - "111 14.068014 \n", - "668 14.180918 \n", - "110 14.181194 " + " rel_topic _distance \n", + "2233 complaints, corruption, traffic 13.883661 \n", + "108 laundering, overpricing, international 13.998826 \n", + "111 laundering, overpricing, international 14.068014 \n", + "668 complaints, corruption, traffic 14.180918 \n", + "110 laundering, overpricing, international 14.181194 " ] }, - "execution_count": 21, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -1717,17 +1725,34 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 25, "id": "09685c42", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=710e32ad2c574cf1a4ae0e11e13909ab&type=arrow&viztoken=cc06093d-e095-4474-b5d6-db43f7b33759&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813588&info=true'" + "" ] }, - "execution_count": 22, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -1738,7 +1763,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 26, "id": "bcfa273d", "metadata": {}, "outputs": [ @@ -1782,8 +1807,8 @@ " Included him on the list of sanctioned officials for being \"responsibles or accomplices of serious violations\" to Human Rights, \"important acts of corruption or both\".\n", " \n", " \n", - " 1191\n", - " Jesús Rafael Suárez Chourio (Venezuela)\n", + " 2363\n", + " Xavier Antonio Moreno Reandes (Venezuela)\n", " Sanctioned by\n", " On June 25th, 2018 the European Union included him on the list of 11 officials sanctioned\n", " \n", @@ -1795,15 +1820,15 @@ " Agent 1 Relationship \\\n", "1384 Katherine Nayartih Haringhton Padrón (Venezuela) Sanctioned by \n", "1265 José Miguel Montoanda Rodríguez (Venezuela) Sanctioned by \n", - "1191 Jesús Rafael Suárez Chourio (Venezuela) Sanctioned by \n", + "2363 Xavier Antonio Moreno Reandes (Venezuela) Sanctioned by \n", "\n", " Evidence \n", "1384 The only non military officer included on the decree 03/09/2015, in which President Barack Obama suspended visas and froze assets of government officials, for Human Rights violation. \n", "1265 Included him on the list of sanctioned officials for being \"responsibles or accomplices of serious violations\" to Human Rights, \"important acts of corruption or both\". \n", - "1191 On June 25th, 2018 the European Union included him on the list of 11 officials sanctioned " + "2363 On June 25th, 2018 the European Union included him on the list of 11 officials sanctioned " ] }, - "execution_count": 23, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -1815,7 +1840,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 27, "id": "653acdfc", "metadata": {}, "outputs": [ @@ -1871,8 +1896,8 @@ " National Audience and the Anti - Corruption Prosecutor of Spain investigate alleged bribery and money laundering. Involved: Ministry of Energy and Mining , CORPOELEC.\n", " \n", " \n", - " 1126\n", - " Ingeniería Gestión de Proyectos de Energía, C.A. (Ingespre) (No information available)\n", + " 2252\n", + " Técnicas Reunidas Terca Ca (Venezuela)\n", " National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC.\n", " \n", " \n", @@ -1881,8 +1906,8 @@ " National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC.\n", " \n", " \n", - " 2252\n", - " Técnicas Reunidas Terca Ca (Venezuela)\n", + " 1126\n", + " Ingeniería Gestión de Proyectos de Energía, C.A. (Ingespre) (No information available)\n", " National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC.\n", " \n", " \n", @@ -1906,9 +1931,9 @@ "1165 Javier Andrés Alvarado Ochoa (Venezuela) \n", "1330 Juan Carlos Torres Inclán (Spain) \n", "676 Duro Felguera (Spain) \n", - "1126 Ingeniería Gestión de Proyectos de Energía, C.A. (Ingespre) (No information available) \n", - "1468 Luís Barrios Melean (No information available) \n", "2252 Técnicas Reunidas Terca Ca (Venezuela) \n", + "1468 Luís Barrios Melean (No information available) \n", + "1126 Ingeniería Gestión de Proyectos de Energía, C.A. (Ingespre) (No information available) \n", "2283 Víctor Eduardo Aular Blanco (Venezuela) \n", "360 Carlos Eduardo Borges Polar (Venezuela) \n", "\n", @@ -1918,14 +1943,14 @@ "1165 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved: Ministry of Energy and Mining , CORPOELEC. \n", "1330 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved: Ministry of Energy and Mining , CORPOELEC. \n", "676 National Audience and the Anti - Corruption Prosecutor of Spain investigate alleged bribery and money laundering. Involved: Ministry of Energy and Mining , CORPOELEC. \n", - "1126 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC. \n", - "1468 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC. \n", "2252 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC. \n", + "1468 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC. \n", + "1126 National Audience and Anti - corruption Prosecutor of Spain investigates alleged bribery and money laundering. Involved Ministry of Energy and Mining , CORPOELEC. \n", "2283 Member of the Strategic Execution Committee of the Financial area. Official Gazzette 39.182, May 20th, 2009. \n", "360 Director of the Internal Operations Office (in charge), of the Sectoral Vice - Presidency of Public Works and Services. Official Gazzette 41.182 of June 28th, 2017. " ] }, - "execution_count": 24, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -1937,17 +1962,34 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 28, "id": "f103792c", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=a936df2d05dd4196addee7b8527d6a46&type=arrow&viztoken=d4ed2c99-1df4-4a35-a032-f398f4580209&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813591&info=true'" + "" ] }, - "execution_count": 25, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -1958,38 +2000,72 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 29, "id": "423315b6", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=b810f623437f48b4aa82a3b005810eed&type=arrow&viztoken=bccdca8f-215c-41b7-a1c5-28f14f95acb5&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813594&info=true'" + "" ] }, - "execution_count": 26, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "g2.search_graph('drug trafficking').plot(render=RENDER)" + "g2.search_graph('drug trafficking').dbscan().plot(render=RENDER)" ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 32, "id": "e2604442", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=fc826e3132da4cd391f0b4c5aeea939e&type=arrow&viztoken=07862a3c-a473-4e11-b8d1-750a6d4dba93&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813596&info=true'" + "" ] }, - "execution_count": 27, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -2000,23 +2076,39 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 33, "id": "b4f5ebcf", "metadata": {}, "outputs": [ { "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], "text/plain": [ - "'https://hub.graphistry.com/graph/graph.html?dataset=3ea11287101d47d7ac6748a04a669e98&type=arrow&viztoken=be9ab400-53d0-4b08-9a1e-c0cafc7fc5b7&usertag=8a6d667e-pygraphistry-0.28.4+72.g2a02e2b.dirty&splashAfter=1668813599&info=true'" + "" ] }, - "execution_count": 28, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# paste in url to see in new tab \n", "g2.search_graph('oil and energy companies').plot(render=RENDER)" ] }, @@ -2034,14 +2126,6 @@ "\n", "Join the Graphistry-Community Slack! \n" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "91380fec", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/demos/ai/OSINT/jack-donations.ipynb b/demos/ai/OSINT/jack-donations.ipynb index 7abddb9f20..1f02d64a2d 100644 --- a/demos/ai/OSINT/jack-donations.ipynb +++ b/demos/ai/OSINT/jack-donations.ipynb @@ -6,30 +6,39 @@ "metadata": {}, "source": [ "________________\n", - "# Jack's money went here. \n", + "# Jack's Money Went Here \n", "\n", - "## Where is twitter likely to lean more and less now that he's leaving? Where will there be matching donations?\n", + "Where is twitter likely to lean more and less now that he's leaving? Where will there be matching donations?\n", "\n", - "Jack Dorsey is pledging over 466 million dollars and wants matching donations. His rational is simple -- billionaires can spare a tithe to help communities and people, and compounded over a few hundred of his closest friends, have a tremendous impact. \n", + "Jack Dorsey is pledging over 466 million dollars and wants matching donations. His rational is simple -- billionaires can spare a tithe to help communities and people, and compounded over a few hundred of his closest friends, have a tremendous impact. What edifice could be built with donations to these entities? What do their service offerings look like when seen as a whole? What are their moving parts?\n", "\n", "This dataset is based off of the tweet https://twitter.com/jack/status/1247616214769086465 which lists pledged organizations and their donation. \n", - "__________________________\n", - "### We will learn how to quickly data science this dataset. We will select feature representations and visualize the resulting graph using UMAP.\n", + "__________________________________________________________________\n", + "\n", + "We will learn how to quickly data science this dataset. We will select feature representations and visualize the resulting graph using UMAP.\n", "\n", "Featurization is the foundation of datascience. Likewise, Graph Thinking requires edges between nodes. Many times the data we have from databases/dataframes is tabular and row like -- with no incling of an edge table. This does *not* have to be an impediment for *Graph Thinking and materialization of datascience workflows*. \n", "\n", "UMAP is a powerful tool that projects complex, heterogeneous data coming from potentially many different distributions, down to lower dimensional embeddings and projections. The embedding estimates similarity between the rows, or nodes of the data, and thus forms a graph. \n", "\n", "Standardizing a feature set across the databases used in every modern company and then sending it to UMAP serves as a powerful graph generation tool. \n", - "____________________________\n", - "Here we demonstrate how to Featurize and use UMAP to generate implicit graphs. The features may then be used in subsequent modeling using your favorite libraries -- sklearn, tensorflow, pytorch[, geometric, lightening, ...], cuGraph, DGL, etc. We demonstrate 4 featurization methods -- (latent embeddings, transformer embeddings, ngrams embeddings, one-hot encodings) that may be mixed and used to make different features for different columns, automatically. \n", + "__________________________________________________________________\n", + "\n", + "Here we demonstrate how to Featurize and use UMAP to generate implicit graphs. The features may then be used in subsequent modeling using your favorite libraries -- sklearn, tensorflow, pytorch[, geometric, lightening, ...], cuGraph, DGL, etc. We demonstrate 4 featurization methods -- \n", + "\n", + "* latent embeddings, \n", + "* transformer embeddings, \n", + "* ngrams embeddings, \n", + "* one-hot encodings\n", "\n", - "Furthermore, when we `g.plot()` the results, it is layed out according to the 2-dimensional UMAP projection of the data -- nearness in that projection represents nearness in the resulting features. We will test this empiracally using the different featurization methods for textual, numeric and categorical data. " + "that may be mixed and used to make different features for different columns, automatically. \n", + "\n", + "Furthermore, when we `g.plot()` the results, it is layed out according to the 2-dimensional UMAP projection of the data -- nearness in that projection represents nearness in the resulting features. We will test this empirically using the different featurization methods for textual, numeric and categorical data. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "a069ef73", "metadata": {}, "outputs": [], @@ -39,17 +48,7 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "97443b1c", - "metadata": {}, - "outputs": [], - "source": [ - "# cd .." - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "b7de987a", "metadata": {}, "outputs": [], @@ -66,7 +65,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "461a22ec", "metadata": {}, "outputs": [], @@ -76,7 +75,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, + "id": "950f6310", + "metadata": {}, + "outputs": [], + "source": [ + "RENDER=False # set to True for inline Graphistry Plots" + ] + }, + { + "cell_type": "code", + "execution_count": 5, "id": "90875a39", "metadata": {}, "outputs": [], @@ -89,32 +98,177 @@ "id": "9acb2823", "metadata": {}, "source": [ - "## Data cleaning\n", + "## Data loading & cleaning\n", "We already added the dataset from the twitter link, downloading a copy (as of May 2022) from the google drive. We need to remove the first few rows to make a valid dataframe. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "0ffe9b64", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
DateAmountCategoryGranteeTwitterLinkWhy?
03/21/2022$2,000,000Social JusticeREFORM Alliance@REFORMhttps://reformalliance.comREFORM Alliance is committed to transforming t...
13/10/2022$1,000,000Crisis ReliefWorld Central Kitchen@WCKitchenhttps://wck.org/World Central Kitchen is serving thousands of ...
23/10/2022$1,000,000Crisis ReliefSunflower of Peace@SunflowerFundhttps://www.sunflowerofpeace.comSunflower of Peace is providing medical and hu...
33/10/2022$1,000,000Crisis ReliefRazom, Inc.@razomforukrainehttps://razomforukraine.orgRazom is supporting Ukrainian people in their ...
43/10/2022$1,000,000Crisis ReliefNova Ukraine@novaukrainehttps://novaukraine.orgNova Ukraine, a Bay Area-based humanitarian no...
\n", + "
" + ], + "text/plain": [ + " Date Amount Category Grantee \\\n", + "0 3/21/2022 $2,000,000 Social Justice REFORM Alliance \n", + "1 3/10/2022 $1,000,000 Crisis Relief World Central Kitchen \n", + "2 3/10/2022 $1,000,000 Crisis Relief Sunflower of Peace \n", + "3 3/10/2022 $1,000,000 Crisis Relief Razom, Inc. \n", + "4 3/10/2022 $1,000,000 Crisis Relief Nova Ukraine \n", + "\n", + " Twitter Link \\\n", + "0 @REFORM https://reformalliance.com \n", + "1 @WCKitchen https://wck.org/ \n", + "2 @SunflowerFund https://www.sunflowerofpeace.com \n", + "3 @razomforukraine https://razomforukraine.org \n", + "4 @novaukraine https://novaukraine.org \n", + "\n", + " Why? \n", + "0 REFORM Alliance is committed to transforming t... \n", + "1 World Central Kitchen is serving thousands of ... \n", + "2 Sunflower of Peace is providing medical and hu... \n", + "3 Razom is supporting Ukrainian people in their ... \n", + "4 Nova Ukraine, a Bay Area-based humanitarian no... " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "df = pd.read_csv('https://gist.githubusercontent.com/silkspace/f8d7b8f279a5ffbd710c301fc402ec43/raw/95a722f5c65812322eaf085c1123b58d3ec3da3a/jack_donations.csv')\n", "df = df.fillna('')\n", "columns = df.iloc[3].values \n", "ndf = pd.DataFrame(df[4:].values, columns=columns)\n", - "ndf" + "ndf.head()" + ] + }, + { + "cell_type": "markdown", + "id": "50f59d83", + "metadata": {}, + "source": [ + "Notice that the Category labels are mixed and interwoven. \n", + "We will show how to standardize it without having to do data cleaning or mapping" ] }, { "cell_type": "code", - "execution_count": null, - "id": "e52b4e5d", + "execution_count": 7, + "id": "ac1b493e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array(['Social Justice', 'Crisis Relief',\n", + " 'COVID-19, Girls Health & Education',\n", + " 'Social Justice, Girls Health & Education', 'COVID-19',\n", + " 'Social Justice, COVID-19', 'Girls Health & Education',\n", + " 'UBI, Social Justice', 'Girls Health & Education, COVID-19',\n", + " 'COVID-19, Social Justice', 'UBI',\n", + " 'COVID-19, Social Justice, Girls Health & Education',\n", + " 'Girls Health & Education; COVID-19', 'COVID-19; Social Justice',\n", + " 'Girls Health & Education; Social Justice',\n", + " 'COVID-19; Girls Health & Education', 'UBI; COVID-19',\n", + " 'COVID-19 & Social Justice',\n", + " 'Social Justice, UBI, Girls Health & Education', 'COVID-19, UBI',\n", + " \"Where it's needed most\", 'COVID-19 '], dtype=object)" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "ndf.Category.unique()" + "ndf.Category.unique() # seems like there are 4-6 topics here" ] }, { @@ -122,24 +276,40 @@ "id": "b454348e", "metadata": {}, "source": [ - "# Create the Graph\n", + "# Featurize\n", "\n", - "We will use `g.umap` to featurize and create edges. The details of how UMAP is able to create edges between rows in the data is beyond the scope of this tutorial, however, suffic it to say, it is automatically inferring a network of related entities based off of their column features. \n", + "We will use `g.umap` to featurize and create edges. The details of how UMAP is able to create edges between rows in the data is beyond the scope of this tutorial, however, suffic it to say, it is automatically inferring a network of related entities based off their column features. \n", "\n", "Here is the dataset as graph, \n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "c986ff93", - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "g = graphistry.nodes(ndf).bind(point_title='Category').umap()\n", - "g.plot() # fly around the clusters and click on nodes and edges. " + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (285, 0) in UMAP fit, as it is not one dimensionalOMP: Info #273: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" + ] + }, + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=ae47f85d8eaa4edfa6a3bc0c1124e313&type=arrow&viztoken=41ef5acc-41e3-49e9-99ac-2a57158b31c8&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009074&info=true&play=0'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g = graphistry.nodes(ndf).umap()\n", + "g.bind(point_title='Grantee').plot(render=RENDER) # fly around the clusters and click on nodes and edges. " ] }, { @@ -147,7 +317,7 @@ "id": "255c8496", "metadata": {}, "source": [ - "## The above featurized every column over the entire datase. Exploring the nodes and their nearest neighbors indeed clusters similar rows -- all in two lines of code!" + "The above featurized every column over the entire datase. Exploring the nodes and their nearest neighbors indeed clusters similar rows -- all in two lines of code!" ] }, { @@ -155,17 +325,39 @@ "id": "d76e628d", "metadata": {}, "source": [ - "# Some light analysis and enrichment \n", + "## Light analysis and enrichment \n", "\n", "Lets convert Amount column into numeric, and then see who is getting what by category and grantee." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "a8ced06c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 $2,000,000\n", + "1 $1,000,000\n", + "2 $1,000,000\n", + "3 $1,000,000\n", + "4 $1,000,000\n", + " ... \n", + "280 $13,333\n", + "281 $2,000,000\n", + "282 $1,000,000\n", + "283 $2,100,000\n", + "284 $100,000\n", + "Name: Amount , Length: 285, dtype: object" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "#ndf.columns\n", "ndf[' Amount ']" @@ -173,7 +365,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "8077b2d0", "metadata": {}, "outputs": [], @@ -193,10 +385,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "b0e0c683", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 2000000.0\n", + "1 1000000.0\n", + "2 1000000.0\n", + "3 1000000.0\n", + "4 1000000.0\n", + " ... \n", + "280 13333.0\n", + "281 2000000.0\n", + "282 1000000.0\n", + "283 2100000.0\n", + "284 100000.0\n", + "Name: $ amount, Length: 285, dtype: float64" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "ndf['$ amount']" ] @@ -206,17 +420,51 @@ "id": "ac95f782", "metadata": {}, "source": [ - "## Many of these categories are not distinct. But due to data coming in with different notation, it seems distinct. \n", + "Many of these categories are not distinct. But due to data coming in with different notation, it seems distinct. \n", "\n", "We will show in the next section how to deal with this by using the graphistry pipeline to convert the `Category` into a latent target that organizes the labels.\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "6e4fcbaf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Category\n", + "COVID-19 $153,882,590.0\n", + "COVID-19 $85,019,328.0\n", + "COVID-19 & Social Justice $505,468.0\n", + "COVID-19, Girls Health & Education $4,265,000.0\n", + "COVID-19, Social Justice $1,800,000.0\n", + "COVID-19, Social Justice, Girls Health & Education $250,000.0\n", + "COVID-19, UBI $8,000,000.0\n", + "COVID-19; Girls Health & Education $9,920,000.0\n", + "COVID-19; Social Justice $5,090,080.0\n", + "Crisis Relief $7,500,000.0\n", + "Girls Health & Education $30,300,000.0\n", + "Girls Health & Education, COVID-19 $1,250,000.0\n", + "Girls Health & Education; COVID-19 $12,000,000.0\n", + "Girls Health & Education; Social Justice $2,500,000.0\n", + "Social Justice $84,119,845.0\n", + "Social Justice, COVID-19 $300,000.0\n", + "Social Justice, Girls Health & Education $9,934,000.0\n", + "Social Justice, UBI, Girls Health & Education $1,100,000.0\n", + "UBI $10,210,000.0\n", + "UBI, Social Justice $1,000,000.0\n", + "UBI; COVID-19 $35,000,000.0\n", + "Where it's needed most $3,000,000.0\n", + "Name: $ amount, dtype: object" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "current_funding_by_category = ndf.groupby('Category')['$ amount'].sum()\n", "current_funding_by_category.map(lambda x: '${:3,}'.format(x))" @@ -224,21 +472,66 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "59b71456", "metadata": {}, - "outputs": [], - "source": [ - "fig = plt.figure(figsize=(15,7))\n", - "current_funding_by_category.plot(kind='bar', rot=52)" + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig = plt.figure(figsize=(10,5))\n", + "current_funding_by_category.plot(kind='bar', rot=82)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "382780f5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Grantee\n", + "Vital Strategies: Resolve To Save Lives $38,000,000.0\n", + "CORE: Community Organized Relief Effort $30,000,000.0\n", + "Clara Lionel Foundation $28,877,000.0\n", + "Reinvent Stockton Foundation $18,000,000.0\n", + "CARE $16,000,000.0\n", + "Give2SF $15,000,000.0\n", + "Open Research Lab Income Project $15,000,000.0\n", + "REFORM Alliance $12,000,000.0\n", + "World Central Kitchen $11,585,500.0\n", + "Indiana University Foundation $10,025,000.0\n", + "Name: $ amount, dtype: object" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "grantees = ndf.groupby('Grantee')['$ amount'].sum()\n", "grants_sorted = grantees.sort_values()\n", @@ -248,78 +541,123 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "d7d0ff87", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# largest grants\n", - "fig = plt.figure(figsize=(15,7))\n", + "fig = plt.figure(figsize=(10,5))\n", "ax= plt.subplot()\n", - "# ax.set_xticks(range(len(label_list)))\n", - "# ax.set_xticklabels(label_list, rotation=19)\n", "res = grants_sorted[-10:]\n", "\n", - "res.plot(kind='bar', rot=52)" + "res.plot(kind='bar', rot=49)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "id": "14330bfc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# smallest grants\n", - "fig = plt.figure(figsize=(15,7))\n", + "fig = plt.figure(figsize=(10,5))\n", "ax= plt.subplot()\n", - "# ax.set_xticks(range(len(label_list)))\n", - "# ax.set_xticklabels(label_list, rotation=19)\n", "res = grants_sorted[:10]\n", "\n", - "res.plot(kind='bar', rot = 52)" + "res.plot(kind='bar', rot = 29)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "id": "2ad231a8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Total Pledged $466,946,311.0'" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "'Total Pledged ${:3,}'.format(current_funding_by_category.sum())" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "217026ee", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'Total Pledged $466,946,311.0'" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# and this should be the same too\n", "'Total Pledged ${:3,}'.format(grantees.sum())" ] }, - { - "cell_type": "markdown", - "id": "50f59d83", - "metadata": {}, - "source": [ - "## Notice that the Category labels are mixed and interwoven \n", - "We will show how judicious choice of parameters can standardize it without having to do data cleaning or mapping" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "ac1b493e", - "metadata": {}, - "outputs": [], - "source": [ - "ndf.Category.unique() # seems like there are 4-6 topics here" - ] - }, { "cell_type": "markdown", "id": "b0565e61", @@ -339,31 +677,12 @@ "____________________________" ] }, - { - "cell_type": "markdown", - "id": "22c6b5c7", - "metadata": {}, - "source": [ - "In the following, we concentrate on the textual `Why?` column as it describes the row/entity in question. Further, we select `y='Category'` as a target variable, and will encode it using a Topic Model as well as standard One-Hot-Encoding.\n", - "\n", - "\n", - "In the following we will show how to encode textual and categorical data using \n", - "\n", - "1) Topic Models\n", - "\n", - "2) Sentence Transformers\n", - "\n", - "3) Ngrams \n", - "\n", - "And see the resulting graphs. We will use the Topic label generated by `y='Category'` to color the graphs, as well as `$ amount` \n" - ] - }, { "cell_type": "markdown", "id": "2255d688", "metadata": {}, "source": [ - "# Topic Model (latent-) features" + "## Topic Model" ] }, { @@ -374,208 +693,609 @@ "We encode the data using Topic Models. This turns the textual features into latent vectors. Likewise, we can do the same for the target data. \n", "\n", "\n", - "Notice that we set `cardinality_threshold_target` very low and `min_words` very high to force featurization as topic models rather than one-hot or topic encoded;\n", + "Notice that we set `cardinality_threshold_target` very low and `min_words` very high to force featurization as topic models rather than one-hot or sbert embeddings;\n", + "\n", "1) encode target using a topic model, and set `n_topics_target` as the dimension of the latent target factorization. This choice is based on the fact that there are really only 4-6 or so distinct categories across the labels, but they are mixed together. The labels are in fact Hierarchical categories. We can use the topic model to find the lowest moments of this Hierarchical classification in the distributional sense. \n", "\n", - "2) and like\n", - "wise for the features `Why?`, and set `n_topics` as the dimension of the latent feature factorization." + "2) Encode the `Why?` column as a `n_topics` -dimensional factorization." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "71ad1fe5", "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (285, 4) in UMAP fit, as it is not one dimensional" + ] + } + ], "source": [ "g = graphistry.nodes(ndf).bind(point_title='Category')\n", "\n", "g2 = g.umap(X=['Why?'], y = ['Category'], \n", - " min_words=50000, # encode as topic model by setting min_words high\n", + " min_words=1e9, # encode as topic model by setting min_words high\n", + " n_topics=42, # latent embedding size of `Why`\n", " n_topics_target=4, # turn categories into a 4dim vector of regressive targets\n", - " n_topics=21, # latent embedding size \n", - " cardinality_threshold_target=2, # make sure that we throw targets into topic model over targets\n", + " cardinality_threshold_target=2, # force topic model over target `Category`\n", + " use_scaler=None,\n", + " use_scaler_target=None\n", " ) " ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "8cb9e6cd", - "metadata": {}, - "outputs": [], - "source": [ - "g2._node_encoder.label_encoder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b650ef59", - "metadata": {}, - "outputs": [], - "source": [ - "# pretend you have a minibatch of new data -- transform under the fit from the above\n", - "new_df, new_y = ndf.sample(5), ndf.sample(5) # pd.DataFrame({'Category': ndf['Category'].sample(5)})\n", - "a, b = g2.transform(new_df, new_y, kind='nodes')\n", - "a" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dc99ac85", - "metadata": {}, - "outputs": [], - "source": [ - "b" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5076e613", - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure()\n", - "plt.imshow(g2._node_target, aspect='auto', cmap='hot')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d95f4e1b", - "metadata": {}, - "outputs": [], - "source": [ - "g2._node_encoder.label_encoder" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "577b32ab", - "metadata": {}, - "outputs": [], - "source": [ - "g2._node_encoder.y.plot(kind='bar', figsize=(15,7)) # easier to see than before" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cd1e7ffc", - "metadata": {}, - "outputs": [], - "source": [ - "# likewise you can play with how many edges to include using,\n", - "g2 = g2.filter_weighted_edges(scale=0.25) # lower positive values of scale mean closer similarity \n" - ] - }, { "cell_type": "markdown", "id": "93e6ae81", "metadata": {}, "source": [ - "## We have featurized the data and also run UMAP, which projects the features into a 2-dimensional space while generating edges.\n", - "\n", "Plotting the result shows the similarity between entities. It does a good job overall at clustering by topic. Click in and check out some nearby nodes. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "0cdf2370", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=039654b935e6476dbe4a232e28609ae1&type=arrow&viztoken=c8fd440d-2b3a-4fbf-868c-f6c93e141154&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009084&info=true&play=0'" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g2.plot()" + "g2.bind(point_title='Grantee').plot(render=RENDER)" ] }, { "cell_type": "code", - "execution_count": null, - "id": "7a970c06", + "execution_count": 21, + "id": "b650ef59", "metadata": {}, - "outputs": [], - "source": [ - "X = g2._node_features \n", - "X" + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "'SuperVectorizer' object has no attribute 'get_feature_names_in''SuperVectorizer' object has no attribute 'get_feature_names_in'" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Why?: relationships, relationship, trevortextWhy?: thousands, kitchen, kitchensWhy?: multiracial, language, analysisWhy?: foundation, partnership, barbadosWhy?: humanitarian, distributing, distributedWhy?: vulnerable, coordinated, outbreakWhy?: marginalized, globalgiving, emergencyWhy?: sustainable, livelihoods, livelihoodWhy?: healthcare, results, childrenWhy?: movementhub, strengthening, snapshots...Why?: washingtonians, incarceration, restorationWhy?: leadership, confidence, confidentlyWhy?: entrepreneurs, entrepreneurship, tomorrowWhy?: coronavirus, families, primarilyWhy?: california, disproportionately, lgbtiqWhy?: individuals, undiagnosed, disabilitiesWhy?: engineering, criminal, completeWhy?: disparities, nonprofit, socioeconomicWhy?: simultaneously, immediate, richmondWhy?: constitution, employers, nationwide
1030.1402770.1600640.1931840.1548806.8990200.0887430.1616050.1260510.084490143.538295...0.1575010.1233250.1076980.17914319.0654360.1214030.1595800.1324810.2476540.115000
620.2136410.38310415.8832800.1558440.2338540.1972960.2214450.2696280.2038880.218177...68.43184619.1420020.4399620.3541340.3268610.5306093.1059930.3180490.378531234.320552
110.1560880.2123510.2416470.1632090.1522430.1922230.2301880.2146024.3081810.157184...276.3394970.6211900.1706340.1333030.1769930.1870970.2653650.1136090.24968926.072265
2440.1933660.1533920.1227790.1264480.1139650.2102250.2016950.1605180.1611350.175002...0.1297570.1461170.15929330.2629570.10615730.7819270.1228150.11921467.8701430.139393
240.1625940.1303150.1578150.2585911.7916016.2796980.54100645.6672350.22850150.486164...0.1607950.2305750.1673350.60355224.34663632.9227700.2992010.4051750.23685141.980704
\n", + "

5 rows × 42 columns

\n", + "
" + ], + "text/plain": [ + " Why?: relationships, relationship, trevortext \\\n", + "103 0.140277 \n", + "62 0.213641 \n", + "11 0.156088 \n", + "244 0.193366 \n", + "24 0.162594 \n", + "\n", + " Why?: thousands, kitchen, kitchens \\\n", + "103 0.160064 \n", + "62 0.383104 \n", + "11 0.212351 \n", + "244 0.153392 \n", + "24 0.130315 \n", + "\n", + " Why?: multiracial, language, analysis \\\n", + "103 0.193184 \n", + "62 15.883280 \n", + "11 0.241647 \n", + "244 0.122779 \n", + "24 0.157815 \n", + "\n", + " Why?: foundation, partnership, barbados \\\n", + "103 0.154880 \n", + "62 0.155844 \n", + "11 0.163209 \n", + "244 0.126448 \n", + "24 0.258591 \n", + "\n", + " Why?: humanitarian, distributing, distributed \\\n", + "103 6.899020 \n", + "62 0.233854 \n", + "11 0.152243 \n", + "244 0.113965 \n", + "24 1.791601 \n", + "\n", + " Why?: vulnerable, coordinated, outbreak \\\n", + "103 0.088743 \n", + "62 0.197296 \n", + "11 0.192223 \n", + "244 0.210225 \n", + "24 6.279698 \n", + "\n", + " Why?: marginalized, globalgiving, emergency \\\n", + "103 0.161605 \n", + "62 0.221445 \n", + "11 0.230188 \n", + "244 0.201695 \n", + "24 0.541006 \n", + "\n", + " Why?: sustainable, livelihoods, livelihood \\\n", + "103 0.126051 \n", + "62 0.269628 \n", + "11 0.214602 \n", + "244 0.160518 \n", + "24 45.667235 \n", + "\n", + " Why?: healthcare, results, children \\\n", + "103 0.084490 \n", + "62 0.203888 \n", + "11 4.308181 \n", + "244 0.161135 \n", + "24 0.228501 \n", + "\n", + " Why?: movementhub, strengthening, snapshots ... \\\n", + "103 143.538295 ... \n", + "62 0.218177 ... \n", + "11 0.157184 ... \n", + "244 0.175002 ... \n", + "24 50.486164 ... \n", + "\n", + " Why?: washingtonians, incarceration, restoration \\\n", + "103 0.157501 \n", + "62 68.431846 \n", + "11 276.339497 \n", + "244 0.129757 \n", + "24 0.160795 \n", + "\n", + " Why?: leadership, confidence, confidently \\\n", + "103 0.123325 \n", + "62 19.142002 \n", + "11 0.621190 \n", + "244 0.146117 \n", + "24 0.230575 \n", + "\n", + " Why?: entrepreneurs, entrepreneurship, tomorrow \\\n", + "103 0.107698 \n", + "62 0.439962 \n", + "11 0.170634 \n", + "244 0.159293 \n", + "24 0.167335 \n", + "\n", + " Why?: coronavirus, families, primarily \\\n", + "103 0.179143 \n", + "62 0.354134 \n", + "11 0.133303 \n", + "244 30.262957 \n", + "24 0.603552 \n", + "\n", + " Why?: california, disproportionately, lgbtiq \\\n", + "103 19.065436 \n", + "62 0.326861 \n", + "11 0.176993 \n", + "244 0.106157 \n", + "24 24.346636 \n", + "\n", + " Why?: individuals, undiagnosed, disabilities \\\n", + "103 0.121403 \n", + "62 0.530609 \n", + "11 0.187097 \n", + "244 30.781927 \n", + "24 32.922770 \n", + "\n", + " Why?: engineering, criminal, complete \\\n", + "103 0.159580 \n", + "62 3.105993 \n", + "11 0.265365 \n", + "244 0.122815 \n", + "24 0.299201 \n", + "\n", + " Why?: disparities, nonprofit, socioeconomic \\\n", + "103 0.132481 \n", + "62 0.318049 \n", + "11 0.113609 \n", + "244 0.119214 \n", + "24 0.405175 \n", + "\n", + " Why?: simultaneously, immediate, richmond \\\n", + "103 0.247654 \n", + "62 0.378531 \n", + "11 0.249689 \n", + "244 67.870143 \n", + "24 0.236851 \n", + "\n", + " Why?: constitution, employers, nationwide \n", + "103 0.115000 \n", + "62 234.320552 \n", + "11 26.072265 \n", + "244 0.139393 \n", + "24 41.980704 \n", + "\n", + "[5 rows x 42 columns]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# suppose we have a minibatch of new data -- transform under the fit from the above\n", + "new_df = new_y = ndf.sample(5) # pd.DataFrame({'Category': ndf['Category'].sample(5)})\n", + "a, b = g2.transform(new_df, new_y, kind='nodes')\n", + "a" ] }, { "cell_type": "code", - "execution_count": null, - "id": "789b09d8", - "metadata": {}, - "outputs": [], + "execution_count": 22, + "id": "00fc2685", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Category: justice, social, 19Category: crisis, relief, covidCategory: needed, where, mostCategory: education, health, girls
10318.0417990.0500080.0566750.051518
6218.0417990.0500080.0566750.051518
1118.0417990.0500080.0566750.051518
2440.05001010.5489160.0510250.050049
2418.0417990.0500080.0566750.051518
\n", + "
" + ], + "text/plain": [ + " Category: justice, social, 19 Category: crisis, relief, covid \\\n", + "103 18.041799 0.050008 \n", + "62 18.041799 0.050008 \n", + "11 18.041799 0.050008 \n", + "244 0.050010 10.548916 \n", + "24 18.041799 0.050008 \n", + "\n", + " Category: needed, where, most Category: education, health, girls \n", + "103 0.056675 0.051518 \n", + "62 0.056675 0.051518 \n", + "11 0.056675 0.051518 \n", + "244 0.051025 0.050049 \n", + "24 0.056675 0.051518 " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "y = g2._node_target # we've reduced 22 columns into 5\n", - "y" + "b" ] }, { "cell_type": "code", - "execution_count": null, - "id": "126d5473", + "execution_count": 23, + "id": "cd1e7ffc", "metadata": {}, "outputs": [], "source": [ - "## we can inspect the topics from the column headers\n", - "label_list = y.columns\n", - "label_list" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7396c76b", - "metadata": { - "scrolled": false - }, - "outputs": [], - "source": [ - "## and see them across rows of the data\n", - "fig = plt.figure(figsize=(17,10))\n", - "ax = plt.subplot()\n", - "plt.imshow(y, aspect='auto', cmap='hot')\n", - "plt.colorbar()\n", - "plt.ylabel('row number of data')\n", - "ax.set_xticks(range(len(label_list)))\n", - "ax.set_xticklabels(label_list, rotation=39)\n", - "print(f'See the abundance of the data in the latent vector of the corresponding targets')" + "# likewise you can play with how many edges to include using,\n", + "g2 = g2.filter_weighted_edges(scale=0.5) # lower positive values of scale mean closer similarity " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "b9dd69ea", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# find the marginal in the category topic distribution\n", - "y.sum(0).plot(kind='bar', ylabel='support across data', rot=79)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "bcf88b65", - "metadata": {}, - "outputs": [], - "source": [ - "## Looking at the above bar chart we may read off the most " + "y = g2._node_target\n", + "y.sum(0).plot(kind='bar', ylabel='support across data', rot=19)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "id": "63b817ae", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "--------------------------------------------------\n", + "Topic 1: \t\t\t\t Evidence\n", + "Category: justice, social, 19\n", + "-----------------------------------\n", + "-- Social Justice, 92\n", + "-- COVID-19; Social Justice, 8\n", + "-- COVID-19, Social Justice, 2\n", + "-- Social Justice, COVID-19, 1\n", + "-- UBI, Social Justice, 1\n", + "-- COVID-19 & Social Justice, 1\n", + "\n", + "--------------------------------------------------\n", + "Topic 2: \t\t\t\t Evidence\n", + "Category: crisis, relief, covid\n", + "-----------------------------------\n", + "-- COVID-19, 70\n", + "-- COVID-19 , 55\n", + "-- Crisis Relief, 8\n", + "-- UBI; COVID-19, 3\n", + "-- COVID-19, UBI, 2\n", + "\n", + "--------------------------------------------------\n", + "Topic 3: \t\t\t\t Evidence\n", + "Category: needed, where, most\n", + "-----------------------------------\n", + "-- UBI, 4\n", + "-- Where it's needed most, 1\n", + "\n", + "--------------------------------------------------\n", + "Topic 4: \t\t\t\t Evidence\n", + "Category: education, health, girls\n", + "-----------------------------------\n", + "-- Girls Health & Education, 16\n", + "-- Social Justice, Girls Health & Education, 6\n", + "-- COVID-19, Girls Health & Education, 4\n", + "-- Girls Health & Education; COVID-19, 3\n", + "-- COVID-19; Girls Health & Education, 3\n", + "-- Girls Health & Education, COVID-19, 2\n", + "-- COVID-19, Social Justice, Girls Health & Education, 1\n", + "-- Girls Health & Education; Social Justice, 1\n", + "-- Social Justice, UBI, Girls Health & Education, 1\n" + ] + } + ], "source": [ "# Let's see how the category columns are supported by the data\n", "from collections import Counter\n", @@ -585,7 +1305,7 @@ " top_category = Counter(ndf.loc[indices].Category)\n", " print()\n", " print('-'*50)\n", - " print(f'Topic {topic_number}: \\t\\t\\t\\t Evidence')\n", + " print(f'Topic {topic_number+1}: \\t\\t\\t\\t Evidence')\n", " print(f'{y.columns[topic_number]}')\n", " print('-'*35)\n", " for t, c in top_category.most_common():\n", @@ -597,7 +1317,7 @@ "id": "efe62b1e", "metadata": {}, "source": [ - "### We see that different spellings, spaces, etc or use of ;, , etc map to the same topic. This is a useful way to disambiguate when there are many similar categories without having to do a lot of data cleaning and prep.\n", + "We see that different spellings, spaces, etc or use of ;, , etc map to the same topic. This is a useful way to disambiguate when there are many similar categories without having to do a lot of data cleaning and prep.\n", "\n", "The choice of `n_topics_target` sets the prior on the Dirty_Cat GapEncoder used under the hood" ] @@ -607,24 +1327,15 @@ "id": "530cde56", "metadata": {}, "source": [ - "## Let's add the Category Topic Number as a feature to help us visualize using the Histogram Feature of the Graphistry UI\n", + "_________________________________________________________________________________________\n", + "Let's add the Category Topic Number as a feature to help us visualize using the Histogram Feature of the Graphistry UI\n", "\n", - "This reduces the naive one-hot-encoding of 22 columns down the the number set by the `n_topics_target=5`" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "db1b9ea4", - "metadata": {}, - "outputs": [], - "source": [ - "tops" + "This reduces the naive one-hot-encoding of 22 columns down the the number set by the `n_topics_target`" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "id": "5724c75f", "metadata": {}, "outputs": [], @@ -635,10 +1346,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "id": "ad387dc0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "0 Category: justice, social, 19\n", + "1 Category: crisis, relief, covid\n", + "2 Category: crisis, relief, covid\n", + "3 Category: crisis, relief, covid\n", + "4 Category: crisis, relief, covid\n", + " ... \n", + "280 Category: crisis, relief, covid\n", + "281 Category: crisis, relief, covid\n", + "282 Category: crisis, relief, covid\n", + "283 Category: crisis, relief, covid\n", + "284 Category: crisis, relief, covid\n", + "Name: topic, Length: 285, dtype: object" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "g2._nodes.topic" ] @@ -654,20 +1387,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "id": "5d46b0ab", - "metadata": { - "scrolled": true - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=e306d4cb9d9c46e2b451e1739b42fd1f&type=arrow&viztoken=194b1f39-29fa-40e5-b80e-790bf099ecaa&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009087&info=true&play=0'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g3 = g2.bind(point_title='topic')\n", - "g3.plot()" + "g2.bind(point_title='Grantee').plot(render=RENDER) # color by `topic` in histogram" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "id": "6c17e7c4", "metadata": {}, "outputs": [], @@ -677,10 +1418,26 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "id": "c3ad0af4", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "topic\n", + "Category: crisis, relief, covid $289,401,918.0\n", + "Category: justice, social, 19 $92,815,393.0\n", + "Category: education, health, girls $71,519,000.0\n", + "Category: needed, where, most $13,210,000.0\n", + "Name: $ amount, dtype: object" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "topic_sums = ndf.groupby('topic')['$ amount'].sum()\n", "topic_sums.sort_values()[::-1].apply(lambda x : '${:3,}'.format(x))" @@ -691,7 +1448,7 @@ "id": "058f5eef", "metadata": {}, "source": [ - "## hence we have Crisis Relief, Social Justice, Health Education Girls, and UBI occupying the main topics across the target" + "Hence we have Crisis Relief, Social Justice, Health Education Girls, and UBI occupying the main topics across the target" ] }, { @@ -700,8 +1457,8 @@ "metadata": {}, "source": [ "------------------------------------------------------------------------------------------\n", - "# Let's move on to point 2) \n", - "# Sentence Transformer Encodings\n", + "Let's move on to point 2) \n", + "## Sentence Transformer Model\n", "\n", "To trigger the sentence encoder, just lower the `min_words` count (which previously we had set to higher than the number of words across the `Why?` column) to some small value or zero to force encoding any X=[..] columns, since it sets the minimum number of words to consider passing on to the (sentence, ngram) embedding pipelines. \n", "\n", @@ -710,97 +1467,690 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "id": "0c4ceacb", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (285, 7) in UMAP fit, as it is not one dimensional" + ] + } + ], "source": [ - "g2 = g.umap(X = ['Why?', 'Grantee'], y = 'Category', \n", + "g3 = g.umap(X = ['Why?', 'Grantee'], y = 'Category', \n", " min_words=0, \n", " model_name ='paraphrase-MiniLM-L6-v2', \n", " cardinality_threshold_target=2,\n", - " scale=0.6)" + " use_scaler=None,\n", + " use_scaler_target=None,\n", + " scale=0.5)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 32, "id": "e137b52c", "metadata": {}, - "outputs": [], - "source": [ - "g2.search('carbon neutral')[0][['Why?']]" + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Why?
28Climate Justice Alliance (CJA) formed in 2013 ...
27The Climate and Clean Energy Equity Fund (Equi...
138The Richmond Rapid Response Fund (R3F) is a wr...
29The Deep South Center for Environment Justice,...
113For 40 years, Futures Without Violence has pio...
46DC or Nothing, Inc. is a nonprofit organizatio...
134To support Oxfam’s response to the ongoing imp...
54With the support of #StartSmall ALIMA is opera...
161To support the \"AEGIS Study\" Fund to address S...
39The Caribbean Climate Justice Project seeks to...
\n", + "
" + ], + "text/plain": [ + " Why?\n", + "28 Climate Justice Alliance (CJA) formed in 2013 ...\n", + "27 The Climate and Clean Energy Equity Fund (Equi...\n", + "138 The Richmond Rapid Response Fund (R3F) is a wr...\n", + "29 The Deep South Center for Environment Justice,...\n", + "113 For 40 years, Futures Without Violence has pio...\n", + "46 DC or Nothing, Inc. is a nonprofit organizatio...\n", + "134 To support Oxfam’s response to the ongoing imp...\n", + "54 With the support of #StartSmall ALIMA is opera...\n", + "161 To support the \"AEGIS Study\" Fund to address S...\n", + "39 The Caribbean Climate Justice Project seeks to..." + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g3.search('carbon neutral')[0][['Why?']]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "id": "a222ef95", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'$13,776,250.0'" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "'${:3,}'.format(g2.search('carbon neutral')[0]['$ amount'].sum())" + "# make quick semantic estimates\n", + "'${:3,}'.format(g3.search('carbon neutral')[0]['$ amount'].sum())" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "7bbcec3a", "metadata": {}, - "outputs": [], - "source": [ - "g2.search('sustainable homes and communities')[0][['Why?','$ amount']]#.sum()" + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Why?$ amount
237For the #FirstOfTheMonth rent relief project a...530000.0
184Funds will be used towards their mission of pr...1000000.0
142To support in its efforts to empower people wi...4720000.0
225Supports the 30-day Rent Relief program and fu...200000.0
253Funds support the Navajo Water Project - conne...1000000.0
177To support the COVID-19 Resilience Fund, servi...2000000.0
122For over 60 years, Public Health Solutions (PH...200000.0
226Funding to be used as leverage in negotiations...300000.0
29The Deep South Center for Environment Justice,...300000.0
110Mission Neighborhood Centers (MNC), founded in...1000000.0
\n", + "
" + ], + "text/plain": [ + " Why? $ amount\n", + "237 For the #FirstOfTheMonth rent relief project a... 530000.0\n", + "184 Funds will be used towards their mission of pr... 1000000.0\n", + "142 To support in its efforts to empower people wi... 4720000.0\n", + "225 Supports the 30-day Rent Relief program and fu... 200000.0\n", + "253 Funds support the Navajo Water Project - conne... 1000000.0\n", + "177 To support the COVID-19 Resilience Fund, servi... 2000000.0\n", + "122 For over 60 years, Public Health Solutions (PH... 200000.0\n", + "226 Funding to be used as leverage in negotiations... 300000.0\n", + "29 The Deep South Center for Environment Justice,... 300000.0\n", + "110 Mission Neighborhood Centers (MNC), founded in... 1000000.0" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g3.search('sustainable homes and communities')[0][['Why?','$ amount']]#.sum()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 35, "id": "1cc5bd36", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'$11,250,000.0'" + ] + }, + "execution_count": 35, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "'${:3,}'.format(g2.search('sustainable homes and communities')[0]['$ amount'].sum())" + "'${:3,}'.format(g3.search('sustainable homes and communities')[0]['$ amount'].sum())" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "3cc28169", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=6c44a692de41484f9e403eea134435dc&type=arrow&viztoken=479610e9-66b9-483d-a242-5dd476faaa08&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009105&info=true&play=0'" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# see the queries landscape -- paste url with .plot(render=False)\n", - "g2.search_graph('sustainable homes and communities', scale=0.90, top_n=10).bind(point_title='Why?').plot(render=False)" + "# see the queries landscape -- paste url to see graph if g.plot(render=False)\n", + "g3.search_graph('sustainable homes and communities', scale=0.90, top_n=10).bind(point_title='Grantee').plot(render=RENDER)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 37, "id": "6bf9f793", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "'SuperVectorizer' object has no attribute 'get_feature_names_in'" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Why?_Grantee_0Why?_Grantee_1Why?_Grantee_2Why?_Grantee_3Why?_Grantee_4Why?_Grantee_5Why?_Grantee_6Why?_Grantee_7Why?_Grantee_8Why?_Grantee_9...Why?_Grantee_374Why?_Grantee_375Why?_Grantee_376Why?_Grantee_377Why?_Grantee_378Why?_Grantee_379Why?_Grantee_380Why?_Grantee_381Why?_Grantee_382Why?_Grantee_383
1030.4437810.228207-0.0959600.2334590.0899190.2619630.181132-0.332808-0.1311690.098321...-0.112939-0.0398010.344712-0.1484540.0923070.5542710.7291100.292012-0.2359180.717677
62-0.117390-0.122771-0.457182-0.2898800.0919840.300274-0.013144-0.2189640.0343230.037846...0.2690200.1146750.1340280.085543-0.3067460.0370340.1676200.0815010.109638-0.272466
110.0664930.095128-0.273875-0.1083200.2081530.3931890.2077410.060979-0.1894270.035519...0.117062-0.0895520.2476550.2489770.0262500.2749580.396113-0.1091530.155618-0.087428
2440.2300280.1674710.2090630.0971040.0820540.183794-0.266914-0.023539-0.543348-0.263615...0.0631710.154695-0.307326-0.1970530.221207-0.0982220.054051-0.118295-0.1543150.197405
24-0.1696910.559551-0.129676-0.3666600.267032-0.058975-0.0054590.0622950.0509210.362040...0.1126640.112096-0.1164510.187891-0.1420400.025833-0.6957160.0177720.0102840.043964
\n", + "

5 rows × 384 columns

\n", + "
" + ], + "text/plain": [ + " Why?_Grantee_0 Why?_Grantee_1 Why?_Grantee_2 Why?_Grantee_3 \\\n", + "103 0.443781 0.228207 -0.095960 0.233459 \n", + "62 -0.117390 -0.122771 -0.457182 -0.289880 \n", + "11 0.066493 0.095128 -0.273875 -0.108320 \n", + "244 0.230028 0.167471 0.209063 0.097104 \n", + "24 -0.169691 0.559551 -0.129676 -0.366660 \n", + "\n", + " Why?_Grantee_4 Why?_Grantee_5 Why?_Grantee_6 Why?_Grantee_7 \\\n", + "103 0.089919 0.261963 0.181132 -0.332808 \n", + "62 0.091984 0.300274 -0.013144 -0.218964 \n", + "11 0.208153 0.393189 0.207741 0.060979 \n", + "244 0.082054 0.183794 -0.266914 -0.023539 \n", + "24 0.267032 -0.058975 -0.005459 0.062295 \n", + "\n", + " Why?_Grantee_8 Why?_Grantee_9 ... Why?_Grantee_374 Why?_Grantee_375 \\\n", + "103 -0.131169 0.098321 ... -0.112939 -0.039801 \n", + "62 0.034323 0.037846 ... 0.269020 0.114675 \n", + "11 -0.189427 0.035519 ... 0.117062 -0.089552 \n", + "244 -0.543348 -0.263615 ... 0.063171 0.154695 \n", + "24 0.050921 0.362040 ... 0.112664 0.112096 \n", + "\n", + " Why?_Grantee_376 Why?_Grantee_377 Why?_Grantee_378 Why?_Grantee_379 \\\n", + "103 0.344712 -0.148454 0.092307 0.554271 \n", + "62 0.134028 0.085543 -0.306746 0.037034 \n", + "11 0.247655 0.248977 0.026250 0.274958 \n", + "244 -0.307326 -0.197053 0.221207 -0.098222 \n", + "24 -0.116451 0.187891 -0.142040 0.025833 \n", + "\n", + " Why?_Grantee_380 Why?_Grantee_381 Why?_Grantee_382 Why?_Grantee_383 \n", + "103 0.729110 0.292012 -0.235918 0.717677 \n", + "62 0.167620 0.081501 0.109638 -0.272466 \n", + "11 0.396113 -0.109153 0.155618 -0.087428 \n", + "244 0.054051 -0.118295 -0.154315 0.197405 \n", + "24 -0.695716 0.017772 0.010284 0.043964 \n", + "\n", + "[5 rows x 384 columns]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# or transform on new data as before\n", - "a, b = g2.transform(new_df, new_y, kind='nodes')\n", + "a, b = g3.transform(new_df, new_y, kind='nodes')\n", "a" ] }, + { + "cell_type": "code", + "execution_count": 38, + "id": "142b85db", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Category: covid, ubi, 19Category: 19, it, ubiCategory: justice, social, mostCategory: 19, it, ubiCategory: education, health, girlsCategory: crisis, relief, neededCategory: ubi, 19, it
1030.0500030.09846017.9763740.0509140.0515390.0501210.072589
620.0500030.09846017.9763740.0509140.0515390.0501210.072589
110.0500030.09846017.9763740.0509140.0515390.0501210.072589
24410.5175000.0683720.0500040.0640940.0500200.0500030.050007
240.0500030.09846017.9763740.0509140.0515390.0501210.072589
\n", + "
" + ], + "text/plain": [ + " Category: covid, ubi, 19 Category: 19, it, ubi \\\n", + "103 0.050003 0.098460 \n", + "62 0.050003 0.098460 \n", + "11 0.050003 0.098460 \n", + "244 10.517500 0.068372 \n", + "24 0.050003 0.098460 \n", + "\n", + " Category: justice, social, most Category: 19, it, ubi \\\n", + "103 17.976374 0.050914 \n", + "62 17.976374 0.050914 \n", + "11 17.976374 0.050914 \n", + "244 0.050004 0.064094 \n", + "24 17.976374 0.050914 \n", + "\n", + " Category: education, health, girls Category: crisis, relief, needed \\\n", + "103 0.051539 0.050121 \n", + "62 0.051539 0.050121 \n", + "11 0.051539 0.050121 \n", + "244 0.050020 0.050003 \n", + "24 0.051539 0.050121 \n", + "\n", + " Category: ubi, 19, it \n", + "103 0.072589 \n", + "62 0.072589 \n", + "11 0.072589 \n", + "244 0.050007 \n", + "24 0.072589 " + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "b" + ] + }, { "cell_type": "markdown", "id": "5a3033a4", "metadata": {}, "source": [ - "## Clicking around to nearest neighbors demonstrates good semantic similarity, as seen by the Paraphrase Model `paraphrase-MiniLM-L6-v2`" + "Clicking around to nearest neighbors demonstrates good semantic similarity, as seen by the Paraphrase Model `paraphrase-MiniLM-L6-v2`" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "id": "9d33ea95", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=51fe80f88c464b5eb049dd382cfb9b46&type=arrow&viztoken=ab98054f-1141-4657-b76d-9a98b4753917&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009108&info=true&play=0'" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g2.plot()" + "g3.bind(point_title='Grantee').plot(render=RENDER)" ] }, { @@ -808,70 +2158,81 @@ "id": "7cbb210c", "metadata": {}, "source": [ - "## Suppose we wanted to add the Grantee column as a feature: \n", - "To include it in the sentence transformer model, reduce the` min_words` threshold to include it. If we want the column `Grantee` to be encoded as a topic model, set `min_words` to between the average of `Why?` (higher) and `Grantee` (lower) and `$ amount` (which is just 1). This may seem a bit sloppy as an API, nevertheless useful across many datasets since if a column is truly categorical, its cardinality is usually well under that of a truly textual feature. Moreover, if you want all columns to be textually encoded, set `min_words=0`. " + "Suppose we wanted to add the `$ amount` column as a feature: \n", + "\n", + "To include it in the sentence transformer model, reduce the` min_words` threshold to include it. If we want the column `Grantee` to be encoded as a topic model, set `min_words` to between the average of `Why?` (higher) and `Grantee` (lower). It nevertheless is useful across many datasets since if a column is truly categorical, its cardinality is usually well under that of a truly textual feature. Moreover, if you want all columns to be textually encoded, set `min_words=0`. \n", + "\n", + "The `$ amount` column will be passed in and scaled according to `use_scaler`, while `use_scaler_target` selects how to scale targets \n", + "\n", + "(exercise: `use_scaler_target='kbins'` to see the difference in `g._node_target` \n", + "\n", + "or scale the dataframe directly (this transforms the batch dataframe)\n", + "\n", + "`a, b = g.scale(ndf, ydf=ndf, 'nodes', use_scaler_target='kbins', n_bins=9))` " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 40, "id": "4ef2870c", "metadata": {}, - "outputs": [], - "source": [ - "g2 = g.umap(X = ['Why?', 'Grantee', '$ amount'], y = 'Category',\n", - " min_words=2,\n", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (285, 22) in UMAP fit, as it is not one dimensional" + ] + } + ], + "source": [ + "g3 = g.umap(X = ['Why?', 'Grantee', '$ amount'], y = 'Category',\n", + " min_words=2, # don't set to zero or it will stringify the `$ amount`\n", " model_name ='paraphrase-MiniLM-L6-v2',\n", " use_scaler=None,\n", - " ) " + " )" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 41, "id": "97bdaa46", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "['Why?', 'Grantee']" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g2._node_encoder.text_cols" + "g3._node_encoder.text_cols" ] }, { "cell_type": "code", - "execution_count": null, - "id": "05b61370", - "metadata": {}, - "outputs": [], - "source": [ - "# just for fun, can we find outliers (which we know will be influenced by the numeric $ amount)\n", - "from graphistry.outliers import detect_outliers\n", - "\n", - "# organized by amount\n", - "embedding = g2._xy\n", - "clfs, ax, fig = detect_outliers(embedding.values, name='Donations', contamination=0.3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b608b9cb", - "metadata": {}, - "outputs": [], - "source": [ - "# the different models\n", - "clfs" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 42, "id": "33f3bc17", - "metadata": { - "scrolled": false - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=22d84e2ef2de4cb4830ea1c6c9dc2f70&type=arrow&viztoken=b5067b0e-4c9b-4341-8c41-ce05998aacd1&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009127&info=true&play=0'" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g2.plot() # color/size the noded by `$ amount`" + "g3.plot(render=RENDER) # color/size the noded by `$ amount`, mimics graph above as they use the same embedding xys" ] }, { @@ -879,7 +2240,9 @@ "id": "f014b4e0", "metadata": {}, "source": [ - "# Lastly, suppose we want a plain Ngrams model matrix, and for a change, one-hot-encode the target `Category`\n", + "## NGRAMS model\n", + "\n", + "Lastly, suppose we want a plain Ngrams model matrix, and for a change, one-hot-encode the target `Category`\n", "\n", "Set `use_ngrams = True`\n", "and set the `cardinality_threshold_target` > cardinality(`Category`).\n", @@ -889,84 +2252,585 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "id": "8c1a588c", "metadata": {}, - "outputs": [], - "source": [ - "g3 = g.umap(X = ['Why?', 'Grantee'], y = 'Category', \n", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (285, 22) in UMAP fit, as it is not one dimensional" + ] + } + ], + "source": [ + "g4 = g.umap(X = ['Why?', 'Grantee'], y = 'Category', \n", " use_ngrams=True, \n", " ngram_range=(1,3), \n", " min_df=2, \n", " max_df=0.3,\n", - " cardinality_threshold_target=400\n", - " ) # this will one-hot-encode the target, as we have less than 400 total `categories`" + " use_scaler=None,\n", + " cardinality_threshold_target=400 # this will one-hot-encode the target, \n", + " # as we have less than 400 total `categories`\n", + " )" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 44, "id": "e1e2683c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'https://hub.graphistry.com/graph/graph.html?dataset=aeb09ebc8a914fe8851b7bc4ea255c9c&type=arrow&viztoken=f768c875-ee7d-4cea-b514-a3c8ba0d59bc&usertag=f680a57a-pygraphistry-0.28.7&splashAfter=1672009131&info=true&play=0'" + ] + }, + "execution_count": 44, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g3.bind(point_title='Category').plot()" + "g4.bind(point_title='Category').plot(render=RENDER) # umap-ing ngrams is not as useful as sentence embeddings as you may visually see, however they can be useful graphs nonetheless. Press `play` in the UI." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 45, "id": "d570f001", "metadata": {}, - "outputs": [], - "source": [ - "g3._node_features # a standard tfidf ngrams matrix" + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
reformalliancecommittedcriminaljusticesystemthroughoutunitedstatesby...mayor officefor homelessmatchhospital2mgo towardsgrant 2mwill go towardstotal grant 2mclinics
00.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
10.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
20.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
30.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
40.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
..................................................................
2800.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
2810.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
2820.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
2830.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
2840.00.00.00.00.00.00.00.00.00.0...0.00.00.00.00.00.00.00.00.00.0
\n", + "

285 rows × 3889 columns

\n", + "
" + ], + "text/plain": [ + " reform alliance committed criminal justice system throughout \\\n", + "0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + ".. ... ... ... ... ... ... ... \n", + "280 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "281 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "282 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "283 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "284 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "\n", + " united states by ... mayor office for homeless match hospital \\\n", + "0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + ".. ... ... ... ... ... ... ... ... \n", + "280 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "281 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "282 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "283 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "284 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 \n", + "\n", + " 2m go towards grant 2m will go towards total grant 2m clinics \n", + "0 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "1 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "2 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "3 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "4 0.0 0.0 0.0 0.0 0.0 0.0 \n", + ".. ... ... ... ... ... ... \n", + "280 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "281 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "282 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "283 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "284 0.0 0.0 0.0 0.0 0.0 0.0 \n", + "\n", + "[285 rows x 3889 columns]" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g4._node_features # a standard tfidf ngrams matrix" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 46, "id": "338010f2", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Pipeline(steps=[('vect',\n", + " CountVectorizer(max_df=0.3, min_df=2, ngram_range=(1, 3))),\n", + " ('tfidf', TfidfTransformer())])" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g3._node_encoder.text_model #sklearn pipeline " + "g4._node_encoder.text_model #sklearn pipeline " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "id": "e7582131", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "3889" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "## vocab size\n", - "len(g3._node_encoder.text_model[0].vocabulary_)" + "len(g4._node_encoder.text_model[0].vocabulary_)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "id": "9e691b4d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "'SuperVectorizer' object has no attribute 'get_feature_names_in'" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xy
1036.100185-1.109381
626.937139-2.348813
116.991597-2.461275
2445.651282-1.004279
245.893190-3.356526
\n", + "
" + ], + "text/plain": [ + " x y\n", + "103 6.100185 -1.109381\n", + "62 6.937139 -2.348813\n", + "11 6.991597 -2.461275\n", + "244 5.651282 -1.004279\n", + "24 5.893190 -3.356526" + ] + }, + "execution_count": 48, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# or transform new data: \n", - "emb, a, b = g2.transform_umap(new_df, new_y, kind='nodes')\n", + "emb, a, b = g4.transform_umap(new_df, new_y, kind='nodes')\n", "emb" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 49, "id": "5bc7b2c0", - "metadata": { - "scrolled": false - }, - "outputs": [], + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Naive Indicator Variables\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# we include the naive indicator variable for completeness.\n", - "y = g3._node_target\n", + "y = g4._node_target\n", "label_list = b.columns\n", "\n", "fig = plt.figure(figsize=(17,10))\n", @@ -981,22 +2845,22 @@ }, { "cell_type": "markdown", - "id": "ec83a920", + "id": "22596c6d", "metadata": {}, "source": [ "# Contributions\n", "\n", - "We've seen how we may pull in tabular data that exists in the wild and quickly make features and graphs that allow semantic and topological exploration and traversals. \n", + "Input tabular data that exists in the wild and quickly make features and graphs that allow semantic and topological exploration and traversals. \n", "\n", - "In this way one can quickly track a variety of datasets and (in this case) gauge growth, investment, and promise fullfillment and transparently using Graph Thinking and analysis.\n", + "Quickly track a variety of datasets and gauge growth, investment, and promise fullfillment and transparently using Graph Thinking and Analysis. In Jack's case, we see the possibility of a multibillion dollar edific erected around Covid-19, Girls Education and Social Justice. Further downstream modeling might tell us what such an edific is able to manufacture as a force for Good.\n", "\n", - "Encoding text, categorical, and numeric features while exploring the relationships can be time consuming tasks. We hope that Graphistry[ai] demonstrates an exciting and visually compelling way to explore Graph Data. \n", + "Encoding text, categorical, and numeric features while exploring the relationships can be time consuming tasks. \n", "\n", - "Now you can mix and match features, augment it with more columns via enrichment, and pivot large amounts of data using natural language search, all using a few lines of code. The features produced may then be used in downstream models, whose outputs could be added and the entire process repeated.\n", + "PyGraphistry[ai] demonstrates an exciting and visually accelerated way to explore Graph Data. \n", "\n", - "Let us know what you think!\n", + "It allows quick Mix and Match featurization models and types, while pivoting on large amounts of data using natural language search, in just a few lines of code. The resulting features may then be used in downstream models.\n", "\n", - "Join our Slack: Graphistry-Community\n" + "Join our Slack: Graphistry-Community" ] }, { diff --git a/demos/ai/cyber/cyber-redteam-umap-demo.ipynb b/demos/ai/cyber/cyber-redteam-umap-demo.ipynb index 9ed84b308b..b07a7403f8 100644 --- a/demos/ai/cyber/cyber-redteam-umap-demo.ipynb +++ b/demos/ai/cyber/cyber-redteam-umap-demo.ipynb @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "f9de6fd3-b87b-4dc4-8d1c-b8f3feceb5e6", "metadata": {}, "outputs": [], @@ -31,20 +31,39 @@ "import pandas as pd\n", "import graphistry\n", "\n", + "from graphistry.features import topic_model, search_model, ModelDict\n", + "\n", "import os\n", "from joblib import load, dump\n", "from collections import Counter\n", "\n", "import numpy as np\n", - "import matplotlib.pylab as plt\n", - "\n", - "from sklearn.cluster import DBSCAN\n", - "from sknetwork.ranking import PageRank\n" + "import matplotlib.pylab as plt\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, + "id": "8e1747b9-c903-4398-9aa0-b52b69fce021", + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(137)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6d2669fd-6164-4376-81bd-79c6c6f4112f", + "metadata": {}, + "outputs": [], + "source": [ + "RENDER = True # set to True to render Graphistry UI inline" + ] + }, + { + "cell_type": "code", + "execution_count": 6, "id": "59e1cc0b", "metadata": {}, "outputs": [], @@ -74,12 +93,12 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "id": "fe6e61b0", "metadata": {}, "outputs": [], "source": [ - "# cite data source\n", + "# data source citation\n", "# \"\"\"A. D. Kent, \"Cybersecurity Data Sources for Dynamic Network Research,\"\n", "# in Dynamic Networks in Cybersecurity, 2015.\n", "\n", @@ -103,10 +122,153 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "id": "efe68cf8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
timesrc_domaindst_domainsrc_computerdst_computerauth_typelogontypeauthentication_orientationsuccess_or_failureREDfeatsfeats2
30526246155805C7048$@DOM1C7048$@DOM1C7048TGT??TGSSuccess0.0C7048 TGT ? ?C7048 TGT
592820137690C15034$@DOM1C15034$@DOM1C15034C467??TGSSuccess0.0C15034 C467 ? ?C15034 C467
21160461116992U2075@DOM1U2075@DOM1C529C529?NetworkLogOffSuccess0.0C529 C529 ? NetworkC529 C529
218232822019C3547$@DOM1C3547$@DOM1C457C457?NetworkLogOffSuccess0.0C457 C457 ? NetworkC457 C457
28495743145572C567$@DOM1C567$@DOM1C574C523KerberosNetworkLogOnSuccess0.0C574 C523 Kerberos NetworkC574 C523
\n", + "
" + ], + "text/plain": [ + " time src_domain dst_domain src_computer dst_computer \\\n", + "30526246 155805 C7048$@DOM1 C7048$@DOM1 C7048 TGT \n", + "5928201 37690 C15034$@DOM1 C15034$@DOM1 C15034 C467 \n", + "21160461 116992 U2075@DOM1 U2075@DOM1 C529 C529 \n", + "2182328 22019 C3547$@DOM1 C3547$@DOM1 C457 C457 \n", + "28495743 145572 C567$@DOM1 C567$@DOM1 C574 C523 \n", + "\n", + " auth_type logontype authentication_orientation success_or_failure \\\n", + "30526246 ? ? TGS Success \n", + "5928201 ? ? TGS Success \n", + "21160461 ? Network LogOff Success \n", + "2182328 ? Network LogOff Success \n", + "28495743 Kerberos Network LogOn Success \n", + "\n", + " RED feats feats2 \n", + "30526246 0.0 C7048 TGT ? ? C7048 TGT \n", + "5928201 0.0 C15034 C467 ? ? C15034 C467 \n", + "21160461 0.0 C529 C529 ? Network C529 C529 \n", + "2182328 0.0 C457 C457 ? Network C457 C457 \n", + "28495743 0.0 C574 C523 Kerberos Network C574 C523 " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# small sample (get almost equivalent results without overheating computer over the 1.6B events in the full dataset)\n", "df = pd.read_csv('https://gist.githubusercontent.com/silkspace/c7b50d0c03dc59f63c48d68d696958ff/raw/31d918267f86f8252d42d2e9597ba6fc03fcdac2/redteam_50k.csv', index_col=0)\n", @@ -115,23 +277,32 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "03610297", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(50000, 12)\n" + ] + } + ], "source": [ "print(df.shape) # -> 50k" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "66c5126e", "metadata": {}, "outputs": [], "source": [ "# here are the post-facto red team events\n", - "red_team = pd.read_csv('https://gist.githubusercontent.com/silkspace/5cf5a94b9ac4b4ffe38904f20d93edb1/raw/888dabd86f88ea747cf9ff5f6c44725e21536465/redteam_labels.csv', index_col=0)" + "red_team = pd.read_csv('https://gist.githubusercontent.com/silkspace/5cf5a94b9ac4b4ffe38904f20d93edb1/raw/888dabd86f88ea747cf9ff5f6c44725e21536465/redteam_labels.csv', index_col=0)\n", + "red_team['feats2'] = red_team.feats" ] }, { @@ -146,10 +317,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "3641d3b5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(19013, 12)\n" + ] + } + ], "source": [ "process = True \n", "# makes a combined feature we can use for topic modeling!\n", @@ -159,9 +338,9 @@ " # and one of just computer to computer \n", " df['feats2'] = df.src_computer + ' ' + df.dst_computer\n", " ndf = df.drop_duplicates(subset=['feats'])\n", - " ndf.to_parquet('../data/auth-50k-feats-one-column.parquet')\n", + " ndf.to_parquet('auth-feats-one-column.parquet')\n", "else:\n", - " ndf = pd.read_parquet('../data/auth-50k-feats-one-column.parquet')\n", + " ndf = pd.read_parquet('auth-feats-one-column.parquet')\n", " \n", "print(ndf.shape)" ] @@ -177,10 +356,289 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "d67c86b8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indextimesrc_domainsrc_computerdst_computerfeatsREDfeats2dst_domainauth_typelogontypeauthentication_orientationsuccess_or_failure
00150885U620@DOM1C17693C1003C17693 C10031.0C17693 C1003NaNNaNNaNNaNNaN
11151036U748@DOM1C17693C305C17693 C3051.0C17693 C305NaNNaNNaNNaNNaN
22151648U748@DOM1C17693C728C17693 C7281.0C17693 C728NaNNaNNaNNaNNaN
33151993U6115@DOM1C17693C1173C17693 C11731.0C17693 C1173NaNNaNNaNNaNNaN
44153792U636@DOM1C17693C294C17693 C2941.0C17693 C294NaNNaNNaNNaNNaN
..........................................
19008846310748263C11843$@DOM1C11843C528C11843 C528 Kerberos Network0.0C11843 C528C11843$@DOM1KerberosNetworkLogOnSuccess
190091439463077937C8470$@DOM1C8470C528C8470 C528 NTLM Network0.0C8470 C528C8470$@DOM1NTLMNetworkLogOnSuccess
1901033398153173300C716$@DOM1C716C716C716 C716 ? ?0.0C716 C716C716$@DOM1??AuthMapSuccess
1901118353851102472U7365@DOM1C16126C586C16126 C586 ? ?0.0C16126 C586U7365@DOM1??TGSSuccess
1901227372458141156NETWORK SERVICE@C6215C6215C6215C6215 C6215 Negotiate Service0.0C6215 C6215NETWORK SERVICE@C6215NegotiateServiceLogOnSuccess
\n", + "

19762 rows × 13 columns

\n", + "
" + ], + "text/plain": [ + " index time src_domain src_computer dst_computer \\\n", + "0 0 150885 U620@DOM1 C17693 C1003 \n", + "1 1 151036 U748@DOM1 C17693 C305 \n", + "2 2 151648 U748@DOM1 C17693 C728 \n", + "3 3 151993 U6115@DOM1 C17693 C1173 \n", + "4 4 153792 U636@DOM1 C17693 C294 \n", + "... ... ... ... ... ... \n", + "19008 8463107 48263 C11843$@DOM1 C11843 C528 \n", + "19009 14394630 77937 C8470$@DOM1 C8470 C528 \n", + "19010 33398153 173300 C716$@DOM1 C716 C716 \n", + "19011 18353851 102472 U7365@DOM1 C16126 C586 \n", + "19012 27372458 141156 NETWORK SERVICE@C6215 C6215 C6215 \n", + "\n", + " feats RED feats2 \\\n", + "0 C17693 C1003 1.0 C17693 C1003 \n", + "1 C17693 C305 1.0 C17693 C305 \n", + "2 C17693 C728 1.0 C17693 C728 \n", + "3 C17693 C1173 1.0 C17693 C1173 \n", + "4 C17693 C294 1.0 C17693 C294 \n", + "... ... ... ... \n", + "19008 C11843 C528 Kerberos Network 0.0 C11843 C528 \n", + "19009 C8470 C528 NTLM Network 0.0 C8470 C528 \n", + "19010 C716 C716 ? ? 0.0 C716 C716 \n", + "19011 C16126 C586 ? ? 0.0 C16126 C586 \n", + "19012 C6215 C6215 Negotiate Service 0.0 C6215 C6215 \n", + "\n", + " dst_domain auth_type logontype authentication_orientation \\\n", + "0 NaN NaN NaN NaN \n", + "1 NaN NaN NaN NaN \n", + "2 NaN NaN NaN NaN \n", + "3 NaN NaN NaN NaN \n", + "4 NaN NaN NaN NaN \n", + "... ... ... ... ... \n", + "19008 C11843$@DOM1 Kerberos Network LogOn \n", + "19009 C8470$@DOM1 NTLM Network LogOn \n", + "19010 C716$@DOM1 ? ? AuthMap \n", + "19011 U7365@DOM1 ? ? TGS \n", + "19012 NETWORK SERVICE@C6215 Negotiate Service LogOn \n", + "\n", + " success_or_failure \n", + "0 NaN \n", + "1 NaN \n", + "2 NaN \n", + "3 NaN \n", + "4 NaN \n", + "... ... \n", + "19008 Success \n", + "19009 Success \n", + "19010 Success \n", + "19011 Success \n", + "19012 Success \n", + "\n", + "[19762 rows x 13 columns]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# make a subsampled dataframe with the anom red-team data at top...so we can keep track.\n", "# we don't need the full `df`, only the unique entries of 'feats' in `ndf` for \n", @@ -192,7 +650,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "5f62b7b5", "metadata": {}, "outputs": [], @@ -203,10 +661,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "id": "5ffd6aac", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "749.0" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# total number of red team events\n", "tdf.RED.sum()" @@ -222,59 +691,35 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "id": "72c53f98", "metadata": {}, "outputs": [], "source": [ - "# some enrichments\n", - "def pagerank(g):\n", - " from sknetwork.ranking import PageRank\n", - " adj = g._weighted_adjacency\n", - " pagerank = PageRank()\n", - " ranks = pagerank.fit_transform(adj)\n", - " g._nodes['pagerank'] = ranks\n", - " return g\n", - "\n", - "def cluster(g):\n", - " \"\"\"\n", - " Fits clustering on UMAP embeddings\n", - " \"\"\"\n", - " dbscan = DBSCAN()\n", - " labels = dbscan.fit_predict(g._node_embedding)\n", - " g._nodes['cluster'] = labels\n", - " cnt = Counter(labels)\n", - " return g, dbscan, cnt\n", - "\n", - "def get_confidences_per_cluster(g, cnt):\n", + "def get_confidences_per_cluster(g, col='RED', verbose=False):\n", " \"\"\"\n", " From DBSCAN clusters, will assess how many Red Team events exist,\n", " assessing confidence.\n", + " \n", " \"\"\"\n", " resses = []\n", " df = g._nodes\n", + " labels = df._dbscan\n", + " cnt = Counter(labels)\n", " for clust, count in cnt.most_common():\n", - " res = df[df.cluster==clust]\n", + " res = df[df._dbscan==clust]\n", " n = res.shape[0]\n", - " n_reds = res.RED.sum()\n", + " n_reds = res[col].sum()\n", " resses.append([clust, n_reds/n, n_reds, n])\n", - " if n_reds>0:\n", + " if n_reds>0 and verbose:\n", " print('-'*20)\n", " print(f'cluster: {clust}\\n red {100*n_reds/n:.2f}% or {n_reds} out of {count}')\n", - " conf_dict = {k[0]:k[1] for k in resses}\n", - " confidence = [conf_dict[k] for k in df.cluster.values]\n", + " conf_dict = {k[0]: k[1] for k in resses}\n", + " confidence = [conf_dict[k] for k in df._dbscan.values]\n", " g._nodes['confidence'] = confidence\n", - " return g, pd.DataFrame(resses, columns=['cluster', 'confidence', 'n_red', 'total_in_cluster'])\n", - "\n", - "\n", - "def enrich(g):\n", - " \"\"\"\n", - " Full Pipeline \n", - " \"\"\"\n", - " g = pagerank(g)\n", - " g, dbscan, cnt = cluster(g)\n", - " g, cluster_confidences = get_confidences_per_cluster(g, cnt)\n", - " return g, dbscan, cluster_confidences\n", + " conf_df = pd.DataFrame(resses, columns=['_dbscan', 'confidence', 'n_red', 'total_in_cluster'])\n", + " conf_df = conf_df.sort_values(by='confidence', ascending=False)\n", + " return g, conf_df\n", " " ] }, @@ -289,31 +734,201 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, + "id": "504781dc-9fbe-467c-9b4d-2e907133cfb7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "\n", + "A topic model for computer to computer + metadata cyber auth logs\n", + "_________________________________________________________________\n", + "\n", + "Updated: {'n_topics': 32, 'X': ['feats']}\n", + "_________________________________________________________________\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "{'cardinality_threshold': 2, 'cardinality_threshold_target': 2, 'n_topics': 32, 'n_topics_target': 10, 'min_words': 1000000000.0, 'X': ['feats']}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# this is a convienence method for setting parameters in `g.featurize()/umap()` -- just a verbose dictionary\n", + "cyber_model = ModelDict('A topic model for computer to computer + metadata cyber auth logs', **topic_model)\n", + "\n", + "cyber_model.update(dict(n_topics=32, X=['feats'])) # name the column to featurize, which we lumped into `feats`\n", + "\n", + "cyber_model" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "id": "6909cc90", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (19762, 0) in UMAP fit, as it is not one dimensionalOMP: Info #276: omp_set_nested routine deprecated, please use omp_set_max_active_levels instead.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--------------------\n", + "cluster: 3\n", + " red 0.66% or 22.0 out of 3331\n", + "--------------------\n", + "cluster: 39\n", + " red 0.41% or 3.0 out of 724\n", + "--------------------\n", + "cluster: 9\n", + " red 1.15% or 3.0 out of 260\n", + "--------------------\n", + "cluster: 38\n", + " red 0.38% or 1.0 out of 260\n", + "--------------------\n", + "cluster: 13\n", + " red 0.43% or 1.0 out of 234\n", + "--------------------\n", + "cluster: 8\n", + " red 95.06% or 77.0 out of 81\n", + "--------------------\n", + "cluster: 1\n", + " red 100.00% or 53.0 out of 53\n", + "--------------------\n", + "cluster: 10\n", + " red 91.84% or 45.0 out of 49\n", + "--------------------\n", + "cluster: 12\n", + " red 82.61% or 38.0 out of 46\n", + "--------------------\n", + "cluster: 22\n", + " red 95.65% or 44.0 out of 46\n", + "--------------------\n", + "cluster: 18\n", + " red 92.11% or 35.0 out of 38\n", + "--------------------\n", + "cluster: 19\n", + " red 82.86% or 29.0 out of 35\n", + "--------------------\n", + "cluster: 15\n", + " red 86.67% or 26.0 out of 30\n", + "--------------------\n", + "cluster: 27\n", + " red 92.59% or 25.0 out of 27\n", + "--------------------\n", + "cluster: 32\n", + " red 100.00% or 27.0 out of 27\n", + "--------------------\n", + "cluster: 28\n", + " red 100.00% or 26.0 out of 26\n", + "--------------------\n", + "cluster: 6\n", + " red 84.00% or 21.0 out of 25\n", + "--------------------\n", + "cluster: 2\n", + " red 87.50% or 21.0 out of 24\n", + "--------------------\n", + "cluster: 35\n", + " red 100.00% or 24.0 out of 24\n", + "--------------------\n", + "cluster: 0\n", + " red 100.00% or 23.0 out of 23\n", + "--------------------\n", + "cluster: 11\n", + " red 100.00% or 23.0 out of 23\n", + "--------------------\n", + "cluster: 30\n", + " red 81.25% or 13.0 out of 16\n", + "--------------------\n", + "cluster: 17\n", + " red 93.33% or 14.0 out of 15\n", + "--------------------\n", + "cluster: 21\n", + " red 100.00% or 15.0 out of 15\n", + "--------------------\n", + "cluster: 23\n", + " red 100.00% or 15.0 out of 15\n", + "--------------------\n", + "cluster: 4\n", + " red 100.00% or 14.0 out of 14\n", + "--------------------\n", + "cluster: 29\n", + " red 100.00% or 14.0 out of 14\n", + "--------------------\n", + "cluster: 7\n", + " red 100.00% or 13.0 out of 13\n", + "--------------------\n", + "cluster: 37\n", + " red 100.00% or 13.0 out of 13\n", + "--------------------\n", + "cluster: 14\n", + " red 100.00% or 11.0 out of 11\n", + "--------------------\n", + "cluster: 5\n", + " red 100.00% or 10.0 out of 10\n", + "--------------------\n", + "cluster: 25\n", + " red 100.00% or 9.0 out of 9\n", + "--------------------\n", + "cluster: 33\n", + " red 88.89% or 8.0 out of 9\n", + "--------------------\n", + "cluster: 20\n", + " red 100.00% or 6.0 out of 6\n", + "--------------------\n", + "cluster: 36\n", + " red 100.00% or 6.0 out of 6\n", + "--------------------\n", + "cluster: 16\n", + " red 100.00% or 5.0 out of 5\n", + "--------------------\n", + "cluster: 24\n", + " red 100.00% or 5.0 out of 5\n", + "--------------------\n", + "cluster: 26\n", + " red 100.00% or 5.0 out of 5\n", + "--------------------\n", + "cluster: 31\n", + " red 100.00% or 5.0 out of 5\n", + "--------------------\n", + "cluster: 34\n", + " red 100.00% or 1.0 out of 1\n", + "CPU times: user 3min 40s, sys: 39.2 s, total: 4min 19s\n", + "Wall time: 2min 7s\n" + ] + } + ], "source": [ "%%time\n", "process = True # set to false after it's run for ease of speed\n", "if process:\n", - " g = graphistry.nodes(tdf, 'node')\n", - " g5 = g.umap(X=['feats'], \n", - " min_words=1000000, # force high so that we don't use Sentence Transformers\n", - " cardinality_threshold=4, # set low so we force topic model\n", - " n_topics=32, # number of topics\n", - " use_scaler=None,\n", - " use_scaler_target=None\n", - " )\n", + " # ##################################\n", + " g = graphistry.nodes(tdf, 'node') # two lines does the heavy lifting\n", + " g5 = g.umap(**cyber_model).dbscan(min_dist=0.2)\n", + " # #########################\n", " \n", - " g5, dbscan, cluster_confidences = enrich(g5)\n", - "\n", - " g5.build_index()\n", - " g5.save_search_instance('../data/auth-feat-topic.search')\n", + " g5, cluster_confidences = get_confidences_per_cluster(g5, verbose=True)\n", + " g5.save_search_instance('auth-feat-topic.search')\n", "else:\n", " g = graphistry.bind()\n", - " g5 = g.load_search_instance('../data/auth-feat-topic.search')\n", - " g5, dbscan, cluster_confidences = enrich(g5)\n" + " g5 = g.load_search_instance('auth-feat-topic.search')\n", + " g5, cluster_confidences = get_confidences_per_cluster(g5)" ] }, { @@ -321,40 +936,581 @@ "id": "54c13cba-bc36-4d49-8e7a-7dc05b27610a", "metadata": {}, "source": [ - "## Plot it\n", - "Color by `confidence` and hover over `red` team histogram to see where events occur" + "## Plot Graph\n", + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `cluster` assignment" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "id": "279fef41", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g5.name('auth 50k topic feats no target').plot(render=False)" + "g5.name('auth topic feats no target').plot(render=RENDER)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "79ece955", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
feats: c9990, c9994, c9997feats: kerberos, u1, u7feats: c528, c5252, c5281feats: c612, c6121, c6125feats: c2446, c2444, c24464feats: c13713, c13130, c13134feats: c586, c5866, c5864feats: c467, c4674, c4667feats: unlock, c1111, c11114feats: c625, c6257, c6255...feats: c5299, c529, c5294feats: c16616, c16168, c16663feats: microsoft_authentication_package_v1_0, microsoft_authentication_package_v1_, microsoft_authentication_package_v1feats: c1065, c10658, c10652feats: cachedinteractive, remoteinteractive, interactivefeats: c3888, c3884, u608feats: c2327, c2323, c2727feats: negotiate, service, c14514feats: c8282, c8280, c8289feats: c1964, c1968, c25685
00.0529920.0500290.0514130.0514030.0500190.0612120.0514190.0504630.0573040.051460...0.0513920.0639230.0502670.1259011.2587630.0524620.0515190.0511450.0519620.054784
11.6098710.0500300.0514200.0514100.0500160.0914860.0514260.0504650.0610340.051467...0.0513990.0690570.0502850.0620531.3217390.0531820.0515270.0500770.0519720.057155
20.0519750.0500300.5577470.0543090.0500160.0701150.0514570.0504750.0609110.051500...0.0514290.0688270.0502900.0619311.3859450.0532100.0530940.0500770.0596950.057138
30.0520890.0500320.0515340.0515230.0500230.0690800.0515410.0505013.7819850.051586...0.0515110.0745020.0502960.0899172.5851250.0529920.0516500.0517860.0521320.056803
41.6125390.0500310.0514820.0514720.0500160.0703620.0514880.0504850.0610270.051532...0.5660140.0690570.0502950.0620661.3220350.0532630.0733810.0500770.0520590.057233
..................................................................
190080.05185622.4777297.1830050.0513550.0500150.0613630.0650230.0504472.8514670.051411...0.0800291.2553180.0563170.0565650.0570330.0669030.0514680.0546991.6110460.054593
190090.0519610.0770695.7110640.0514310.0500160.0514970.0696930.0504720.0508320.051490...0.0931340.0515010.0553220.0511991.5924400.0579840.0515500.0570413.2042790.051984
190100.0523280.0500350.0517080.0516964.0515620.0517750.9875260.0505570.0509830.051765...0.0516826.6525120.0503030.0514190.0835640.0522650.0518370.0500060.0523770.054756
190110.0520750.0500320.0581360.7985984.0513700.0549017.3887750.0504980.0528610.051575...0.0579752.6554570.0502780.0533640.0535340.0523060.0516390.0500210.0521180.054182
190120.0522230.0559720.0516310.0640400.0500180.0516950.0516380.0505321.0696967.039859...0.0516070.0516980.0519440.0920370.0513860.0521620.05175526.0603540.0522690.052257
\n", + "

19762 rows × 32 columns

\n", + "
" + ], + "text/plain": [ + " feats: c9990, c9994, c9997 feats: kerberos, u1, u7 \\\n", + "0 0.052992 0.050029 \n", + "1 1.609871 0.050030 \n", + "2 0.051975 0.050030 \n", + "3 0.052089 0.050032 \n", + "4 1.612539 0.050031 \n", + "... ... ... \n", + "19008 0.051856 22.477729 \n", + "19009 0.051961 0.077069 \n", + "19010 0.052328 0.050035 \n", + "19011 0.052075 0.050032 \n", + "19012 0.052223 0.055972 \n", + "\n", + " feats: c528, c5252, c5281 feats: c612, c6121, c6125 \\\n", + "0 0.051413 0.051403 \n", + "1 0.051420 0.051410 \n", + "2 0.557747 0.054309 \n", + "3 0.051534 0.051523 \n", + "4 0.051482 0.051472 \n", + "... ... ... \n", + "19008 7.183005 0.051355 \n", + "19009 5.711064 0.051431 \n", + "19010 0.051708 0.051696 \n", + "19011 0.058136 0.798598 \n", + "19012 0.051631 0.064040 \n", + "\n", + " feats: c2446, c2444, c24464 feats: c13713, c13130, c13134 \\\n", + "0 0.050019 0.061212 \n", + "1 0.050016 0.091486 \n", + "2 0.050016 0.070115 \n", + "3 0.050023 0.069080 \n", + "4 0.050016 0.070362 \n", + "... ... ... \n", + "19008 0.050015 0.061363 \n", + "19009 0.050016 0.051497 \n", + "19010 4.051562 0.051775 \n", + "19011 4.051370 0.054901 \n", + "19012 0.050018 0.051695 \n", + "\n", + " feats: c586, c5866, c5864 feats: c467, c4674, c4667 \\\n", + "0 0.051419 0.050463 \n", + "1 0.051426 0.050465 \n", + "2 0.051457 0.050475 \n", + "3 0.051541 0.050501 \n", + "4 0.051488 0.050485 \n", + "... ... ... \n", + "19008 0.065023 0.050447 \n", + "19009 0.069693 0.050472 \n", + "19010 0.987526 0.050557 \n", + "19011 7.388775 0.050498 \n", + "19012 0.051638 0.050532 \n", + "\n", + " feats: unlock, c1111, c11114 feats: c625, c6257, c6255 ... \\\n", + "0 0.057304 0.051460 ... \n", + "1 0.061034 0.051467 ... \n", + "2 0.060911 0.051500 ... \n", + "3 3.781985 0.051586 ... \n", + "4 0.061027 0.051532 ... \n", + "... ... ... ... \n", + "19008 2.851467 0.051411 ... \n", + "19009 0.050832 0.051490 ... \n", + "19010 0.050983 0.051765 ... \n", + "19011 0.052861 0.051575 ... \n", + "19012 1.069696 7.039859 ... \n", + "\n", + " feats: c5299, c529, c5294 feats: c16616, c16168, c16663 \\\n", + "0 0.051392 0.063923 \n", + "1 0.051399 0.069057 \n", + "2 0.051429 0.068827 \n", + "3 0.051511 0.074502 \n", + "4 0.566014 0.069057 \n", + "... ... ... \n", + "19008 0.080029 1.255318 \n", + "19009 0.093134 0.051501 \n", + "19010 0.051682 6.652512 \n", + "19011 0.057975 2.655457 \n", + "19012 0.051607 0.051698 \n", + "\n", + " feats: microsoft_authentication_package_v1_0, microsoft_authentication_package_v1_, microsoft_authentication_package_v1 \\\n", + "0 0.050267 \n", + "1 0.050285 \n", + "2 0.050290 \n", + "3 0.050296 \n", + "4 0.050295 \n", + "... ... \n", + "19008 0.056317 \n", + "19009 0.055322 \n", + "19010 0.050303 \n", + "19011 0.050278 \n", + "19012 0.051944 \n", + "\n", + " feats: c1065, c10658, c10652 \\\n", + "0 0.125901 \n", + "1 0.062053 \n", + "2 0.061931 \n", + "3 0.089917 \n", + "4 0.062066 \n", + "... ... \n", + "19008 0.056565 \n", + "19009 0.051199 \n", + "19010 0.051419 \n", + "19011 0.053364 \n", + "19012 0.092037 \n", + "\n", + " feats: cachedinteractive, remoteinteractive, interactive \\\n", + "0 1.258763 \n", + "1 1.321739 \n", + "2 1.385945 \n", + "3 2.585125 \n", + "4 1.322035 \n", + "... ... \n", + "19008 0.057033 \n", + "19009 1.592440 \n", + "19010 0.083564 \n", + "19011 0.053534 \n", + "19012 0.051386 \n", + "\n", + " feats: c3888, c3884, u608 feats: c2327, c2323, c2727 \\\n", + "0 0.052462 0.051519 \n", + "1 0.053182 0.051527 \n", + "2 0.053210 0.053094 \n", + "3 0.052992 0.051650 \n", + "4 0.053263 0.073381 \n", + "... ... ... \n", + "19008 0.066903 0.051468 \n", + "19009 0.057984 0.051550 \n", + "19010 0.052265 0.051837 \n", + "19011 0.052306 0.051639 \n", + "19012 0.052162 0.051755 \n", + "\n", + " feats: negotiate, service, c14514 feats: c8282, c8280, c8289 \\\n", + "0 0.051145 0.051962 \n", + "1 0.050077 0.051972 \n", + "2 0.050077 0.059695 \n", + "3 0.051786 0.052132 \n", + "4 0.050077 0.052059 \n", + "... ... ... \n", + "19008 0.054699 1.611046 \n", + "19009 0.057041 3.204279 \n", + "19010 0.050006 0.052377 \n", + "19011 0.050021 0.052118 \n", + "19012 26.060354 0.052269 \n", + "\n", + " feats: c1964, c1968, c25685 \n", + "0 0.054784 \n", + "1 0.057155 \n", + "2 0.057138 \n", + "3 0.056803 \n", + "4 0.057233 \n", + "... ... \n", + "19008 0.054593 \n", + "19009 0.051984 \n", + "19010 0.054756 \n", + "19011 0.054182 \n", + "19012 0.052257 \n", + "\n", + "[19762 rows x 32 columns]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# see how the model has organized features\n", "X = g5._node_features\n", "X" ] }, + { + "cell_type": "code", + "execution_count": 45, + "id": "87b32e09-3ca4-49de-b8c3-2b40ffa2b01d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAD4CAYAAAD1jb0+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAABG00lEQVR4nO2dd3hUxfrHv7ObpghKk4ugBpSaDjGACKh0uJZwudKuYEW9cm0/BRRF9FrAAogiiIggF+lNBZEWIXQCBggBQoAAgZCEQDopm31/f2zJtrO9nc37eZ482Z2dM/OeOee8Z+add94RRASGYRhGfih8LQDDMAzjHKzAGYZhZAorcIZhGJnCCpxhGEamsAJnGIaRKUHerKxJkyYUHh7uzSoZhmFkz6FDh64SUVPTdK8q8PDwcKSkpHizSoZhGNkjhDhvKZ1NKAzDMDKFFTjDMIxMYQXOMAwjU7xqA3cH1dXVyM7ORkVFha9FYRiGcSthYWFo2bIlgoOD7covOwWenZ2N+vXrIzw8HEIIX4vDMAzjFogIBQUFyM7ORqtWrew6RnYmlIqKCjRu3JiVN8MwAYUQAo0bN3bIuiA7BQ6AlTfDMAGJo7pNlgrckNKKalRW1/haDIZhGK9jU4ELIcKEEAeEEEeEEMeFEB9o01sJIfYLITKFEMuFECGeF9ecs1fLcCq3xKt1zpo1Cx06dMCoUaMcPjYrKws///yzB6Syn6eeegqrVq1y+vgpU6bgiy++AABMnjwZW7dutZr/zz//xJ49e5yuz14WLlyIy5cv678/99xzSE9P93i97qawsBDffvutXXnvv/9+m3lmzpyJ8vJyV8WyiqnMly9fxtChQ91eT107X1vY0wOvBPAwEcUAiAUwQAjRFcA0ADOI6F4A1wE86zEp/Yxvv/0WW7ZswZIlSxw+1h8UuDv58MMP0adPH6t5nFHgKpXKYVlMFfj8+fPRsWNHh8uxF2dktAdHFLg97eqMQqupcWxUayrzHXfc4VInQYq6dr42ISK7/wDcDOAwgC4ArgII0qZ3A/CHreM7d+5MrpKenm70/cjF63Tk4nWXy7WXF154gYKDgykyMpKmT59OpaWl9PTTT9N9991HsbGxtG7dOiIiOnfuHD3wwAMUFxdHcXFxtHv3biIi6tKlCzVo0IBiYmJo+vTplJaWRvfddx/FxMRQVFQUZWRkWK3/9OnT1Lt3b4qOjqa4uDjKzMykkpISevjhhykuLo4iIyP1MhARLVq0iKKioig6Opr+9a9/ERHRmDFj6D//+Q9169aNWrVqRStXrtTn/+yzzyg+Pp6ioqJo8uTJ+vSPPvqI2rRpQ927d6fhw4fT559/ri9Ld/zdd99NkydP1stx4sQJOnfuHDVr1ozuuOMOiomJoZ07d1JeXh4NGTKE4uPjKT4+nnbt2kVERO+//z7961//ovvvv5+GDx8u2YZERFOnTqXIyEiKjo6mCRMm0MqVK6levXrUtm1biomJofLycurVqxcdPHiQ5syZQ2+++ab+2B9//JFefvllIiJavHixvv3Hjh1LKpXKavv36tWLXn31VercuTN98cUXlJKSQj179qROnTpRv3796PLly/p8r732GnXu3Jnat29PBw4coMTERLr33ntp0qRJ+vK+/PJLioiIoIiICJoxYwYREQ0bNozCwsIoJiZGL7fUdalXrx4RESUlJVGvXr3oH//4B7Vr145GjhxJarWavvrqK/39+uCDDxIR0R9//EFdu3aluLg4Gjp0KJWUlOiv3/jx4ykuLo6WLl1K8+bNo/j4eIqOjqYhQ4ZQWVkZERFduXKFHn/8cYqOjqbo6GjavXu3mcznzp2jiIgIItLc82lpaUZtePDgQclnxxp14XxNdRwREYAUsqSTLSWaZQKUAFIBlELT824CINPg9zsBpEkcOxZACoCUu+66y+YFsoXhyU35JY0Gf7WTBn+1k56Yu8ctf1N+SbNSu4a7776b8vPziYjo7bffpsWLFxMR0fXr16lNmzZUWlpKZWVldOPGDSIiysjIIN3LKykpiQYPHqwva9y4cfS///2PiIgqKyupvLyciIgGDhxIly5dMqs7ISGB1qxZQ0REN27coLKyMqqurqaioiIiIsrPz6d77rmH1Go1paWlUZs2bfSyFhQUEJFG6Q4dOpRqamro+PHjdM899xCR5kZ//vnnSa1WU01NDQ0ePJh27NhBKSkpFBkZSWVlZVRUVET33HOPpAKfNWsWERHNnj2bnn32WSLSKGZdfiKiESNGUHJyMhERnT9/ntq3b6/P16lTJ30bSLXhxo0bqVu3bvoHTHdeugdFh+57Xl6e/hyJiAYMGEDJycmUnp5Of//736mqqoqIiF566SVatGiR+QU3oFevXvTSSy8REVFVVRV169aN8vLyiIho2bJl9PTTT+vzjR8/noiIZs6cSc2bN6fLly9TRUUFtWjRgq5evapv19LSUiopKaGOHTvS4cOHjZSBtetCZKzQGjRoQBcvXqSamhrq2rWrvo0N79f8/Hzq0aMHlZaWEpHmRfjBBx/o802bNk1f79WrV/WfJ02apL+2TzzxhP5lo1KpqLCw0Exmw+/Tp0/Xv3QuX75Mbdu2JSLpZ8cadeF8HVHgdvmBE1ENgFghxG0A1gJo70APfx6AeQAQHx8fcBtwbt68Gb/88oveJlxRUYELFy7gjjvuwLhx45CamgqlUomMjAyLx3fr1g0ff/wxsrOzMWTIELRp0wYAsHHjRrO8JSUluHTpEhITEwFonP4BzeKmd955Bzt37oRCocClS5eQm5uL7du345///CeaNGkCAGjUqJG+rMcffxwKhQIdO3ZEbm6u/lw2b96MuLg4AEBpaSlOnz6NkpISJCYm4uabbwYAPProo5LtMWTIEABA586dsWbNGot5tm7damSbLi4uRmlpqb7sm266SX9eltpw69atePrpp/XyGJ6XJZo2bYrWrVtj3759aNOmDU6ePInu3btj9uzZOHToEO677z4AwI0bN3D77bdbLQsAhg0bBgA4deoU0tLS0LdvXwCaYXjz5s31+XTtFBUVhYiICP1vrVu3xsWLF7Fr1y4kJiaiXr16+rZLTk42a1+p69KzZ0+jfAkJCWjZsiUAIDY2FllZWXjggQeM8uzbtw/p6eno3r07AKCqqgrdunUzOzcASEtLw7vvvovCwkKUlpaif//+AIDt27fjp59+AgAolUrceuutuH79umR7PfHEE+jXrx8++OADrFixQm8rlnp2OnToIFlWXT5fSzi0kIeICoUQSdCYTG4TQgQRkQpASwCXnJbCSd5/JAJHswsBANEtb/N29QA0I5jVq1ejXbt2RulTpkxBs2bNcOTIEajVar2yNWXkyJHo0qULNmzYgEGDBuG7777Dww8/7JAMS5YsQX5+Pg4dOoTg4GCEh4fb9CUNDQ01Ogfd/7fffhsvvPCCUd6ZM2faLYuuXKVSKWkjVqvV2Ldvn8U20SkzAJgxY4ZdbWgPw4cPx4oVK9C+fXskJiZCCAEiwpgxY/Dpp586VJZORiJCREQE9u7dazGfri0UCoVReysUCofs51LXRao+QLr9iQh9+/bF0qVLLZZh2P5PPfUU1q1bh5iYGCxcuBB//vmn3TIb0qJFCzRu3BhHjx7F8uXLMXfuXL0slp4de6lr52sJe7xQmmp73hBC3ASgL4ATAJIA6KZdxwBY7zapZET//v3x9ddf65XgX3/9BQAoKipC8+bNoVAosHjxYv0kSf369VFSUus1c/bsWbRu3RqvvPIKHnvsMRw9elSyrvr166Nly5ZYt24dAKCyshLl5eUoKirC7bffjuDgYCQlJeH8eU3kyYcffhgrV65EQUEBAODatWs2z2XBggX63vClS5eQl5eHnj17Yt26dbhx4wZKSkrw66+/OtRGpufcr18/fP311/rvqampFo+TasO+ffvixx9/1E9U6c7LtB5DEhMTsX79eixduhTDhw8HAPTu3RurVq1CXl6evhxd240ePRoHDhywel7t2rVDfn6+XoFXV1fj+PHjVo8xpEePHli3bh3Ky8tRVlaGtWvXokePHmbnIXVd7MWwvK5du2L37t3IzMwEAJSVlUmODktKStC8eXNUV1cbTdj37t0bc+bMAaAZdRQVFVlte0DT0/3ss89QVFSE6Oho/XlZenYuXbqE3r17231+cj9fV7DHC6U5gCQhxFEABwFsIaLfAEwA8IYQIhNAYwA/uCyNFZbsP48t6bmerMIp3nvvPVRXVyM6OhoRERF47733AAD//ve/sWjRIsTExODkyZP6N310dDSUSiViYmIwY8YMrFixApGRkYiNjUVaWhpGjx4NABg0aJCRR4WOxYsXY9asWYiOjsb999+PK1euYNSoUUhJSUFUVBR++ukntG+vsXBFRERg0qRJ6NWrF2JiYvDGG29YPZd+/fph5MiR6NatG6KiojB06FCUlJSgU6dOGDZsGGJiYjBw4EC9ycFeHnnkEaxduxaxsbFITk7GrFmzkJKSgujoaHTs2FHfQzFFqg0HDBiARx99FPHx8YiNjdUPSZ966im8+OKLiI2NxY0bN4zKatiwITp06IDz588jISEBANCxY0d89NFH6NevH6Kjo9G3b1/k5OQAAI4ePYo77rjD6nmFhIRg1apVmDBhAmJiYhAbG+uQt02nTp3w1FNPISEhAV26dMFzzz2HuLg4NG7cGN27d0dkZCTeeustyetiL2PHjsWAAQPw0EMPoWnTpli4cCFGjBiB6OhodOvWDSdPnrR43H//+1906dIF3bt3199TAPDVV18h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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "x = g5.get_matrix(['interactive', 'c17'])\n", + "x.plot()" + ] + }, { "cell_type": "markdown", "id": "632d6d0f-8212-4f4a-a920-7600d7456351", "metadata": {}, "source": [ - "## Put model into Predict Mode\n", + "## Predict | Online Mode\n", "\n", - "Once a model is fit, can predict on new batches as we demonstrate here\n", + "Once a model is fit, predict on new batches as we demonstrate here\n", "\n", "There are two main methods\n", "\n", @@ -367,23 +1523,131 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 20, "id": "7b44d418", "metadata": {}, "outputs": [], "source": [ "# first sample a batch from the normal data (auth=df)\n", - "emb_normal, xp_normal, _ = g5.transform_umap(df.sample(200), None, kind='nodes')\n", + "emb_normal, xp_normal, _ = g5.transform_umap(df.sample(200), None, kind='nodes', return_graph=False)\n", "# then transform all the red team data\n", - "emb_red, xp_red, _ = g5.transform_umap(red_team, None, kind='nodes')" + "emb_red, xp_red, _ = g5.transform_umap(red_team, None, kind='nodes', return_graph=False)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 21, "id": "d0aebbbc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
xy
09.2325930.724252
15.324008-8.997888
210.624950-0.399632
39.591936-0.037859
413.842589-3.487622
.........
1900810.19344112.514707
190094.766062-1.102680
190109.568494-1.873951
1901111.638880-0.451751
190123.685098-6.050752
\n", + "

19762 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " x y\n", + "0 9.232593 0.724252\n", + "1 5.324008 -8.997888\n", + "2 10.624950 -0.399632\n", + "3 9.591936 -0.037859\n", + "4 13.842589 -3.487622\n", + "... ... ...\n", + "19008 10.193441 12.514707\n", + "19009 4.766062 -1.102680\n", + "19010 9.568494 -1.873951\n", + "19011 11.638880 -0.451751\n", + "19012 3.685098 -6.050752\n", + "\n", + "[19762 rows x 2 columns]" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# all emb's have this form\n", "g5._node_embedding" @@ -391,16 +1655,50 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 22, "id": "8a8d5aa9", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# scatter to see how well it does.\n", "plt.figure(figsize=(10,7))\n", - "plt.scatter(g5._node_embedding.x, g5._node_embedding.y , c='b') # the totality of the fit data\n", + "plt.scatter(g5._node_embedding.x, g5._node_embedding.y , c='b', s=60, alpha=0.5) # the totality of the fit data\n", "plt.scatter(emb_normal.x, emb_normal.y, c='g') # batch of new data\n", - "plt.scatter(emb_red.x, emb_red.y, c='r') # red labels to show good cluster seperation" + "plt.scatter(emb_red.x, emb_red.y, c='r') # red labels to show good cluster seperation\n", + "plt.scatter(emb_normal.x, emb_normal.y, c='g') # batch of new data, to see if they occlude " + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "f9f98708-f18f-4248-96fb-498a4becad89", + "metadata": {}, + "outputs": [], + "source": [ + "#g5.transform_umap(df.sample(200).append(red_team)).plot()" ] }, { @@ -410,17 +1708,25 @@ "source": [ "## 96% Reduction in Alerts\n", "\n", - "This indicates a huge reduction in the search space needed \n", + "This indicates a huge reduction in the search space needed.\n", "\n", - "Since we have clear cluster assignments along with (post facto) confidences of known anomalous activity, we can reduce the search space on new events (via Kafka, Splunk, etc)" + "Since we have clear cluster assignments along with (post facto) confidences of known anomalous activity, we can reduce the search space on new events (gotten via Kafka, Splunk, etc)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "id": "14d207db-9a58-45a3-9876-058632389f17", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "94.11%\n" + ] + } + ], "source": [ "# percent of RED team labels we get with 10% confidence or above\n", "p = cluster_confidences[cluster_confidences.confidence>0.1].n_red.sum()/cluster_confidences[cluster_confidences.confidence>0.1].total_in_cluster.sum()\n", @@ -429,21 +1735,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "id": "755a3f27-935d-4ba8-96cb-cbff11fdf00e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "18998" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# number of data points not to consider (and it's more if we look at df proper!)\n", + "# number of data points *not* to consider (and it's more if we look at df proper!)\n", "cluster_confidences[cluster_confidences.confidence<0.1].total_in_cluster.sum()" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "id": "5fd1cc50-0900-4694-8400-c426e314ec2e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Alert Reduction 96.13%\n" + ] + } + ], "source": [ "p = cluster_confidences[cluster_confidences.confidence<0.1].total_in_cluster.sum()/cluster_confidences.total_in_cluster.sum()\n", "print(f'Alert Reduction {100*p:.2f}%')" @@ -451,10 +1776,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "id": "0ee508a5", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "plt.figure(figsize=(10,7))\n", "plt.plot(np.cumsum([k[2] for k in cluster_confidences.values]))\n", @@ -477,27 +1822,146 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "id": "e0c6a16d-a899-43b6-a7ba-75b45f855a78", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3min 14s, sys: 38.6 s, total: 3min 52s\n", + "Wall time: 1min 34s\n" + ] + } + ], "source": [ "%%time\n", "process = True\n", "if process:\n", + " # ################################## # an example of setting features explicitly, could use ModelDict \n", " g = graphistry.nodes(tdf, 'node')\n", " g6 = g.umap(X=['feats'], y =['RED'], \n", - " min_words=100000, \n", - " cardinality_threshold=2, \n", + " min_words=100000, # set high to bypass sbert encoding\n", + " cardinality_threshold=2, # set low to force topic modeling\n", " n_topics=32,\n", - " use_scaler_target=None)\n", - " g6, dbscan6, cluster_confidences6 = enrich(g6)\n", - " g6.build_index()\n", - " g6.save_search_instance('../data/auth-feat-supervised-topic.search')\n", + " use_scaler_target=None, # keep labels unscaled\n", + " dbscan=True) # add dbscan here\n", + " # ##################################\n", + " \n", + " g6, cluster_confidences6 = get_confidences_per_cluster(g6)\n", + " g6.save_search_instance('auth-feat-supervised-topic.search')\n", "else:\n", " g = graphistry.bind()\n", - " g6 = g.load_search_instance('../data/auth-feat-supervised-topic.search')\n", - " g6, dbscan6, cluster_confidences6 = enrich(g6)\n" + " g6 = g.load_search_instance('auth-feat-supervised-topic.search')\n", + " g6, cluster_confidences6 = get_confidences_per_cluster(g6)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "a98ef657-5307-41d9-ae31-79c1794b3728", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
RED
01
11
21
31
41
......
190080
190090
190100
190110
190120
\n", + "

19762 rows × 1 columns

\n", + "
" + ], + "text/plain": [ + " RED\n", + "0 1\n", + "1 1\n", + "2 1\n", + "3 1\n", + "4 1\n", + "... ...\n", + "19008 0\n", + "19009 0\n", + "19010 0\n", + "19011 0\n", + "19012 0\n", + "\n", + "[19762 rows x 1 columns]" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "g6.get_matrix(target=True).astype(int)" ] }, { @@ -508,17 +1972,45 @@ }, "source": [ "### Plot\n", - "Color by `confidence` and hover over `red` team histogram to see where events occur" + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `_dbscan` assignment" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "id": "16e09a7d", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 30, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g6.name('auth 50k topic with supervised umap').plot(render=False)" + "g6.name('auth topic with supervised umap').plot(render=RENDER)" ] }, { @@ -532,55 +2024,590 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, + "id": "1731ae44-57e0-4c3e-bad0-ac486bba589c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 C17693 C1003\n", + "1 C17693 C305\n", + "2 C17693 C728\n", + "3 C17693 C1173\n", + "4 C17693 C294\n", + " ... \n", + "19008 C11843 C528\n", + "19009 C8470 C528\n", + "19010 C716 C716\n", + "19011 C16126 C586\n", + "19012 C6215 C6215\n", + "Name: feats2, Length: 19762, dtype: object" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tdf['feats2']" + ] + }, + { + "cell_type": "code", + "execution_count": 32, "id": "099b9d38", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (19762, 0) in UMAP fit, as it is not one dimensional" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CPU times: user 3min 5s, sys: 38.7 s, total: 3min 44s\n", + "Wall time: 1min 35s\n" + ] + } + ], "source": [ "%%time\n", "process = True\n", "if process:\n", + " # #####################################\n", " g = graphistry.nodes(tdf, 'node')\n", " g7 = g.umap(X=['feats2'], #y =['RED'], \n", " min_words=100000, \n", " cardinality_threshold=2, \n", " n_topics=32,\n", - " use_scaler_target=None)\n", - " g7, dbscan7, cluster_confidences7 = enrich(g7)\n", - " g7.build_index()\n", - " g7.save_search_instance('../data/auth-feat-just-ip-topic.search')\n", + " use_scaler=None,\n", + " use_scaler_target=None, \n", + " dbscan=True) # add dbscan here\n", + " # ###################################\n", + " g7, cluster_confidences7 = get_confidences_per_cluster(g7)\n", + " g7.save_search_instance('auth-just-ip-topic.search')\n", "else:\n", - " g7 = graphistry.bind().load_search_instance('../data/auth-feat-just-ip-topic.search')\n", - " g7, dbscan7, cluster_confidences7 = enrich(g7)\n" + " g7 = graphistry.bind().load_search_instance('auth-just-ip-topic.search')\n", + " g7, cluster_confidences7 = get_confidences_per_cluster(g7)\n" ] }, { "cell_type": "markdown", "id": "836883cb-bc66-4a40-9ca8-f01fd38b6f2a", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "### Plot\n", - "Color by `confidence` and hover over `red` team histogram to see where events occur" + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `cluster` assignment" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "id": "c1e586a3", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "g7.name('auth 50k topic only ips no supervision').plot(render=False)" + "g7.name('auth topic ips-ips only, no supervision').plot(render=RENDER)\n", + "# very similar to graph with metadata included, showing that ip-ip is strong indicator of phenomenon" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 34, "id": "5f93d747", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
feats2: c586, c585, c5864feats2: c1961, c10196, c1901feats2: c16916, c16169, c1616feats2: c3636, c6363, c6365feats2: c4944, c4444, c8444feats2: c1065, c10652, c10585feats2: c15556, c15550, c1555feats2: c5999, c10999, c599feats2: c17693, c6937, c3937feats2: c8882, c8880, c8889...feats2: c2890, c280, tgtfeats2: c3333, c3303, c3033feats2: c11187, c1118, c1111feats2: c1798, c1772, c1778feats2: c3435, c3434, c3597feats2: c2106, c210, c10000feats2: c1085, c1080, c1081feats2: c457, c222, c452feats2: c1268, c1226, c12689feats2: c6604, c16604, c16048
00.0512690.0523700.0595630.0530120.0510560.0510730.0591190.0520267.8934050.051389...0.0500000.1013700.0595511.2192620.0512732.6995793.2442510.0511430.0597300.051639
10.0512710.0534840.0665290.0530600.0510570.5618000.0677010.0520467.8513410.051392...0.0500002.7418990.0689651.3686531.0247590.0511450.1084730.0511450.0703190.052000
20.0512640.0532570.0645780.0531300.0510510.0510670.0655620.0520797.3910630.051386...0.0633430.0513200.0666751.6714340.0512670.0511380.0975290.0511390.0677570.051922
30.0512510.0524770.0655900.0529940.0510410.0510570.0634030.0520097.8922310.051369...0.0500000.0513073.2639923.7472290.0532710.0511270.1920250.0511270.0636630.051661
40.0513140.0535180.0664850.0531121.5838720.0511080.0676940.0520947.6626360.051438...0.0500010.0513720.0690201.3703690.0513172.3258170.1091280.0511830.0703080.052039
..................................................................
190080.0655380.0528860.0571710.0517410.5664110.0515130.0574980.0516740.0642830.051968...0.0515460.0518784.1037730.0568660.0713950.0516170.0663170.0516170.0581580.052165
190090.0715230.0533260.0525520.0528671.1014340.0524830.0522880.0527540.0551940.585756...4.6553730.0530990.0521180.0525880.0529690.0526580.0517380.0526590.0520800.053095
190100.0521270.0523843.6722151.0932620.0517640.0517880.0516490.0519800.0536860.052330...0.0500010.0522240.0515280.0518650.0521320.0519120.0701560.0519130.0515000.052221
190114.1885900.0527292.7033011.6086440.0516190.0516420.0551510.0518170.0534840.052138...0.0500010.0520400.0552760.0548900.0519570.0517550.0596970.0517564.3860740.052217
190120.0518940.0521220.0516370.0518350.0515722.6382632.7346150.0517630.0532820.052075...0.0500010.0519800.0513620.0516600.0518992.2122430.0511210.0517040.0513380.051977
\n", + "

19762 rows × 32 columns

\n", + "
" + ], + "text/plain": [ + " feats2: c586, c585, c5864 feats2: c1961, c10196, c1901 \\\n", + "0 0.051269 0.052370 \n", + "1 0.051271 0.053484 \n", + "2 0.051264 0.053257 \n", + "3 0.051251 0.052477 \n", + "4 0.051314 0.053518 \n", + "... ... ... \n", + "19008 0.065538 0.052886 \n", + "19009 0.071523 0.053326 \n", + "19010 0.052127 0.052384 \n", + "19011 4.188590 0.052729 \n", + "19012 0.051894 0.052122 \n", + "\n", + " feats2: c16916, c16169, c1616 feats2: c3636, c6363, c6365 \\\n", + "0 0.059563 0.053012 \n", + "1 0.066529 0.053060 \n", + "2 0.064578 0.053130 \n", + "3 0.065590 0.052994 \n", + "4 0.066485 0.053112 \n", + "... ... ... \n", + "19008 0.057171 0.051741 \n", + "19009 0.052552 0.052867 \n", + "19010 3.672215 1.093262 \n", + "19011 2.703301 1.608644 \n", + "19012 0.051637 0.051835 \n", + "\n", + " feats2: c4944, c4444, c8444 feats2: c1065, c10652, c10585 \\\n", + "0 0.051056 0.051073 \n", + "1 0.051057 0.561800 \n", + "2 0.051051 0.051067 \n", + "3 0.051041 0.051057 \n", + "4 1.583872 0.051108 \n", + "... ... ... \n", + "19008 0.566411 0.051513 \n", + "19009 1.101434 0.052483 \n", + "19010 0.051764 0.051788 \n", + "19011 0.051619 0.051642 \n", + "19012 0.051572 2.638263 \n", + "\n", + " feats2: c15556, c15550, c1555 feats2: c5999, c10999, c599 \\\n", + "0 0.059119 0.052026 \n", + "1 0.067701 0.052046 \n", + "2 0.065562 0.052079 \n", + "3 0.063403 0.052009 \n", + "4 0.067694 0.052094 \n", + "... ... ... \n", + "19008 0.057498 0.051674 \n", + "19009 0.052288 0.052754 \n", + "19010 0.051649 0.051980 \n", + "19011 0.055151 0.051817 \n", + "19012 2.734615 0.051763 \n", + "\n", + " feats2: c17693, c6937, c3937 feats2: c8882, c8880, c8889 ... \\\n", + "0 7.893405 0.051389 ... \n", + "1 7.851341 0.051392 ... \n", + "2 7.391063 0.051386 ... \n", + "3 7.892231 0.051369 ... \n", + "4 7.662636 0.051438 ... \n", + "... ... ... ... \n", + "19008 0.064283 0.051968 ... \n", + "19009 0.055194 0.585756 ... \n", + "19010 0.053686 0.052330 ... \n", + "19011 0.053484 0.052138 ... \n", + "19012 0.053282 0.052075 ... \n", + "\n", + " feats2: c2890, c280, tgt feats2: c3333, c3303, c3033 \\\n", + "0 0.050000 0.101370 \n", + "1 0.050000 2.741899 \n", + "2 0.063343 0.051320 \n", + "3 0.050000 0.051307 \n", + "4 0.050001 0.051372 \n", + "... ... ... \n", + "19008 0.051546 0.051878 \n", + "19009 4.655373 0.053099 \n", + "19010 0.050001 0.052224 \n", + "19011 0.050001 0.052040 \n", + "19012 0.050001 0.051980 \n", + "\n", + " feats2: c11187, c1118, c1111 feats2: c1798, c1772, c1778 \\\n", + "0 0.059551 1.219262 \n", + "1 0.068965 1.368653 \n", + "2 0.066675 1.671434 \n", + "3 3.263992 3.747229 \n", + "4 0.069020 1.370369 \n", + "... ... ... \n", + "19008 4.103773 0.056866 \n", + "19009 0.052118 0.052588 \n", + "19010 0.051528 0.051865 \n", + "19011 0.055276 0.054890 \n", + "19012 0.051362 0.051660 \n", + "\n", + " feats2: c3435, c3434, c3597 feats2: c2106, c210, c10000 \\\n", + "0 0.051273 2.699579 \n", + "1 1.024759 0.051145 \n", + "2 0.051267 0.051138 \n", + "3 0.053271 0.051127 \n", + "4 0.051317 2.325817 \n", + "... ... ... \n", + "19008 0.071395 0.051617 \n", + "19009 0.052969 0.052658 \n", + "19010 0.052132 0.051912 \n", + "19011 0.051957 0.051755 \n", + "19012 0.051899 2.212243 \n", + "\n", + " feats2: c1085, c1080, c1081 feats2: c457, c222, c452 \\\n", + "0 3.244251 0.051143 \n", + "1 0.108473 0.051145 \n", + "2 0.097529 0.051139 \n", + "3 0.192025 0.051127 \n", + "4 0.109128 0.051183 \n", + "... ... ... \n", + "19008 0.066317 0.051617 \n", + "19009 0.051738 0.052659 \n", + "19010 0.070156 0.051913 \n", + "19011 0.059697 0.051756 \n", + "19012 0.051121 0.051704 \n", + "\n", + " feats2: c1268, c1226, c12689 feats2: c6604, c16604, c16048 \n", + "0 0.059730 0.051639 \n", + "1 0.070319 0.052000 \n", + "2 0.067757 0.051922 \n", + "3 0.063663 0.051661 \n", + "4 0.070308 0.052039 \n", + "... ... ... \n", + "19008 0.058158 0.052165 \n", + "19009 0.052080 0.053095 \n", + "19010 0.051500 0.052221 \n", + "19011 4.386074 0.052217 \n", + "19012 0.051338 0.051977 \n", + "\n", + "[19762 rows x 32 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "X = g7._get_feature('nodes')\n", + "X = g7.get_matrix()\n", "X" ] }, @@ -590,14 +2617,18 @@ "metadata": {}, "source": [ "# Conditional Probability\n", - "Let's see if can give us good histograms to tease out red team nodes? This is to baseline the above UMAP models, and we find in retrospect, UMAP wins." + "Let's see if conditiona probability of computer to computer connections can give us good histograms to tease out red team nodes? This is to baseline the above UMAP models, and we find in retrospect, UMAP wins. \n", + "\n", + "The conditional graph is however useful to see aggregate behavior, and coloring by 'red' team shows topology of Infection" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "2d6f58dd", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "g = graphistry.edges(tdf, \"src_computer\", \"dst_computer\")" @@ -605,49 +2636,159 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "54b83f83", - "metadata": {}, + "execution_count": 37, + "id": "f3b44db2-b34e-4398-8c5a-7a10bbe5d681", + "metadata": { + "tags": [] + }, "outputs": [], "source": [ - "def conditional_probability(x, given, df):\n", - " \"\"\"conditional probability function over categorical variables\n", - " p(x|given) = p(x,given)/p(given)\n", - " \n", - " Args:\n", - " x: the column variable of interest given the column 'given'\n", - " given: the variabe to fix constant\n", - " df: dataframe with columns [given, x]\n", - " Returns:\n", - " pd.DataFrame: the conditional probability of x given the column 'given'\n", - " \"\"\"\n", - " return df.groupby([given])[x].apply(lambda g: g.value_counts()/len(g))\n" + "x='dst_computer'\n", + "given='src_computer'\n", + "cg = g.conditional_graph(x, given, kind='edges')" ] }, { "cell_type": "code", - "execution_count": null, - "id": "fd738336", + "execution_count": 38, + "id": "3b2af6a2-4f10-4707-beb8-4f3447d3e3b8", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
src_computerdst_computer_probs
0C1C6121.000000
1C10C100.333333
2C10C29970.333333
3C10C107180.333333
4C100C5280.500000
............
17831C9990C5280.250000
17832C9992C5861.000000
17833C9994C99941.000000
17834C9997C5860.500000
17835C9997C6250.500000
\n", + "

17836 rows × 3 columns

\n", + "
" + ], + "text/plain": [ + " src_computer dst_computer _probs\n", + "0 C1 C612 1.000000\n", + "1 C10 C10 0.333333\n", + "2 C10 C2997 0.333333\n", + "3 C10 C10718 0.333333\n", + "4 C100 C528 0.500000\n", + "... ... ... ...\n", + "17831 C9990 C528 0.250000\n", + "17832 C9992 C586 1.000000\n", + "17833 C9994 C9994 1.000000\n", + "17834 C9997 C586 0.500000\n", + "17835 C9997 C625 0.500000\n", + "\n", + "[17836 rows x 3 columns]" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "x='dst_computer'\n", - "given='src_computer'\n", - "condprobs = conditional_probability(x, given, df=tdf)\n", - "\n", - "cprob = pd.DataFrame(list(condprobs.index), columns=[given, x])\n", - "cprob['_probs'] = condprobs.values" + "# the new edge dataframe assess conditiona prob of computer-to-computer connection\n", + "cprob = cg._edges\n", + "cprob" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 39, "id": "5258aee1", "metadata": {}, "outputs": [], "source": [ - "# now enrich the edges dataframe with the redteam data\n", - "# since cprobs lost those labels during the function cal\n", + "# enrich the edges dataframe with the redteam data\n", + "# since cprobs lost those labels during the function call\n", "indx = cprob.src_computer.isin(red_team.src_computer) & cprob.dst_computer.isin(red_team.dst_computer)\n", "cprob.loc[indx, 'red'] = 1\n", "cprob.loc[~indx, 'red'] = 0" @@ -655,114 +2796,218 @@ }, { "cell_type": "code", - "execution_count": null, - "id": "9b3af1cd-6423-4484-8b99-81fad821f118", - "metadata": {}, - "outputs": [], - "source": [ - "# full condprob graph \n", - "cg = graphistry.edges(cprob, x, given).bind(edge_weight='_probs')\n", - "cg.plot(render=False)" - ] - }, - { - "cell_type": "markdown", - "id": "42fb3dff", - "metadata": {}, - "source": [ - "## Learning\n", - "The conditional graph shows that most of the edge probabilities are between 4e-7 and 0.03, whose bucket contains most events. Thus the chances of finding the red team edges are ~ 1e-4 -- slim indeed. UMAP wins." - ] - }, - { - "cell_type": "markdown", - "id": "9d2cd536", - "metadata": {}, - "source": [ - "Likewise the transpose conditional is even worse \n", - "with prob_detection ~ 6e-5" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "18eafcff", + "execution_count": 40, + "id": "7ff921fc-3ecd-4404-acd7-8db943a4ebcc", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
src_computerdst_computer_probsred
0C1C6121.0000000.0
1C10C100.3333330.0
2C10C29970.3333330.0
3C10C107180.3333330.0
4C100C5280.5000000.0
...............
17831C9990C5280.2500000.0
17832C9992C5861.0000000.0
17833C9994C99941.0000000.0
17834C9997C5860.5000000.0
17835C9997C6250.5000000.0
\n", + "

17836 rows × 4 columns

\n", + "
" + ], + "text/plain": [ + " src_computer dst_computer _probs red\n", + "0 C1 C612 1.000000 0.0\n", + "1 C10 C10 0.333333 0.0\n", + "2 C10 C2997 0.333333 0.0\n", + "3 C10 C10718 0.333333 0.0\n", + "4 C100 C528 0.500000 0.0\n", + "... ... ... ... ...\n", + "17831 C9990 C528 0.250000 0.0\n", + "17832 C9992 C586 1.000000 0.0\n", + "17833 C9994 C9994 1.000000 0.0\n", + "17834 C9997 C586 0.500000 0.0\n", + "17835 C9997 C625 0.500000 0.0\n", + "\n", + "[17836 rows x 4 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "# let's repeat but with reverse conditional\n", - "x='src_computer'\n", - "given='dst_computer'\n", - "condprobs2 = conditional_probability(x, given, df=tdf)\n", - "\n", - "cprob2 = pd.DataFrame(list(condprobs2.index), columns=[given, x])\n", - "cprob2['_probs'] = condprobs2.values" + "cprob" ] }, { "cell_type": "code", - "execution_count": null, - "id": "74913e34", + "execution_count": 41, + "id": "b4b10152-cac9-4497-b016-dd67b54cdcf2", "metadata": {}, "outputs": [], "source": [ - "# now enrich the edges dataframe with the redteam data\n", - "indx = cprob2.src_computer.isin(red_team.src_computer) & cprob2.dst_computer.isin(red_team.dst_computer)\n", - "cprob2.loc[indx, 'red'] = 1\n", - "cprob2.loc[~indx, 'red'] = 0" + "# add edges back to graphistry instance\n", + "cg._edges = cprob" ] }, { "cell_type": "code", - "execution_count": null, - "id": "22f4ac54", + "execution_count": 42, + "id": "9b3af1cd-6423-4484-8b99-81fad821f118", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "cg2 = graphistry.edges(cprob2, x, given).bind(edge_weight='_probs')\n", - "cg2.plot(render=False)\n", - "# same conclusion as above..." + "# full condprob graph\n", + "cg.plot(render=RENDER)" ] }, { - "cell_type": "code", - "execution_count": null, - "id": "db832e1c", + "cell_type": "markdown", + "id": "42fb3dff", "metadata": {}, - "outputs": [], "source": [ - "# # let's see the probs better:\n", - "# for src in red_team.src_computer.unique():\n", - "# for dst in red_team.dst_computer.unique():\n", - "# if dst in condprobs[src]:\n", - "# print('-'*30)\n", - "# print(f'given src {src} -> dst {dst}')\n", - "# print('-'*10)\n", - "# print(f' {condprobs[src][dst]*100:.2f}%')\n", - "# print()" + "## Learning\n", + "The conditional graph shows that most of the edge probabilities are between 4e-7 and 0.03, whose bucket contains most of the events. Thus the chances of finding the red team edges are ~ 1e-4 -- slim indeed. UMAP wins." ] }, { - "cell_type": "code", - "execution_count": null, - "id": "21f51de6", + "cell_type": "markdown", + "id": "9d2cd536", "metadata": {}, - "outputs": [], "source": [ - "# for dst in red_team.dst_computer.unique():\n", - "# for src in red_team.src_computer.unique():\n", - "# if src in condprobs2[dst]:\n", - "# print('-'*20)\n", - "# print(f'given dst {dst} -> src {src}')\n", - "# print('-'*10)\n", - "# print(f' {condprobs2[dst][src]*100:.2f}%')\n", - "# print()" + "Likewise the transpose conditional is even worse \n", + "with prob_detection ~ 6e-5" ] }, { "cell_type": "code", "execution_count": null, - "id": "c3a008f6-75ed-4045-b13c-494cb015d185", + "id": "e0cbef82-421d-489e-8666-84d412cae5a9", "metadata": {}, "outputs": [], "source": [] diff --git a/demos/ai/cyber/redteam-umap-gtc-gpu.ipynb b/demos/ai/cyber/redteam-umap-gtc-gpu.ipynb new file mode 100644 index 0000000000..5b8db6ae70 --- /dev/null +++ b/demos/ai/cyber/redteam-umap-gtc-gpu.ipynb @@ -0,0 +1,1034 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "beb5e3e3-f8cd-40ed-bc63-8a862000f192", + "metadata": {}, + "source": [ + "# Analyzing Network Identity Data and Red Team Response with Graphistry AutoML + UMAP\n", + "\n", + "We find a simple model that when clustered in a 2d plane via UMAP allows fast identification of anomalous \n", + "computer to computer connections" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f9de6fd3-b87b-4dc4-8d1c-b8f3feceb5e6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# ! pip install graphistry[ai] \n", + "! pip install --user --no-deps git+https://github.com/graphistry/pygraphistry.git@cudf-alex3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0215906c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import os\n", + "import pandas as pd\n", + "from joblib import load, dump\n", + "from collections import Counter\n", + "\n", + "import numpy as np\n", + "import matplotlib.pylab as plt\n", + "\n", + "import graphistry\n", + "from graphistry.features import topic_model, search_model, ModelDict" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b34bebd-c91d-49fe-82c9-ec1c83a4a6c1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "graphistry.__version__" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8e1747b9-c903-4398-9aa0-b52b69fce021", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "np.random.seed(137)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6d2669fd-6164-4376-81bd-79c6c6f4112f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "RENDER = True # set to True to render Graphistry UI inline" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "59e1cc0b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "graphistry.register(api=3, protocol=\"https\", server=\"hub.graphistry.com\", username = '..',\n", + " #os.environ['USERNAME'], \n", + " password='..'\n", + " #os.environ['GRAPHISTRY_PASSWORD']\n", + " )" + ] + }, + { + "cell_type": "markdown", + "id": "877b4e50-8fa8-4663-bba0-91b661fc735f", + "metadata": {}, + "source": [ + "Alert on & visualize anomalous identity events\n", + "\n", + "Demo dataset: 1.6B windows events over 58 days => logins by 12K user over 14K systems\n", + "adapt to any identity system with logins. Here we subsample down to a small set of 50k events to prove out the pipeline. \n", + "\n", + "* => Can we identify accounts & computers acting anomalously? Resources being oddly accessed?\n", + "* => Can we spot the red team?\n", + "* => Operations: Identity incident alerting + identity data investigations\n", + "\n", + "Community/contact for help handling bigger-than-memory & additional features\n", + "\n", + "Runs on both CPU + multi-GPU\n", + "Tools: PyGraphistry[AI], DGL + PyTorch, and NVIDIA RAPIDS / umap-learn" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe6e61b0", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# data source citation\n", + "# \"\"\"A. D. Kent, \"Cybersecurity Data Sources for Dynamic Network Research,\"\n", + "# in Dynamic Networks in Cybersecurity, 2015.\n", + "\n", + "# @InProceedings{akent-2015-enterprise-data,\n", + "# author = {Alexander D. Kent},\n", + "# title = {{Cybersecurity Data Sources for Dynamic Network Research}},\n", + "# year = 2015,\n", + "# booktitle = {Dynamic Networks in Cybersecurity},\n", + "# month = jun,\n", + "# publisher = {Imperial College Press}\n", + "# }\"\"\"" + ] + }, + { + "cell_type": "markdown", + "id": "554c0d85-1c8a-47f0-87ec-1629d7f7ba3b", + "metadata": {}, + "source": [ + "# Get the Data\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "efe68cf8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# small sample (get almost equivalent results without overheating computer over the 1.6B events in the full dataset)\n", + "df = pd.read_csv('https://gist.githubusercontent.com/silkspace/c7b50d0c03dc59f63c48d68d696958ff/raw/31d918267f86f8252d42d2e9597ba6fc03fcdac2/redteam_50k.csv', index_col=0)\n", + "df.head(5)" + ] + }, + { + "cell_type": "markdown", + "id": "93bab916-a6c1-4a63-95de-2e8d2a72d8a6", + "metadata": { + "execution": { + "iopub.execute_input": "2023-03-20T17:41:26.708147Z", + "iopub.status.busy": "2023-03-20T17:41:26.707740Z", + "iopub.status.idle": "2023-03-20T17:41:26.711459Z", + "shell.execute_reply": "2023-03-20T17:41:26.710695Z", + "shell.execute_reply.started": "2023-03-20T17:41:26.708118Z" + } + }, + "source": [ + "# Graphistry UMAP in a single line of code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "29e99375-5b24-4760-b5ed-909f51949f7f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# umap pipeline in one line\n", + "g = graphistry.nodes(df.sample(1000)).umap(engine='umap_learn')\n", + "g.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03610297", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(df.shape) # -> 50+k" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "66c5126e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# here are the post-facto red team events\n", + "red_team = pd.read_csv('https://gist.githubusercontent.com/silkspace/5cf5a94b9ac4b4ffe38904f20d93edb1/raw/888dabd86f88ea747cf9ff5f6c44725e21536465/redteam_labels.csv', index_col=0)\n", + "red_team['feats2'] = red_team.feats # since red team data didn't include metadata" + ] + }, + { + "cell_type": "markdown", + "id": "3c6615aa", + "metadata": {}, + "source": [ + "# Modeling\n", + "\n", + "Make sure you `mkdir(data)` or change path below\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3641d3b5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "process = True \n", + "# makes a combined feature we can use for topic modeling!\n", + "if process:\n", + " # we create two types of models\n", + " df['feats'] = df.src_computer + ' ' + df.dst_computer + ' ' + df.auth_type + ' ' + df.logontype\n", + " # and one of just computer to computer \n", + " df['feats2'] = df.src_computer + ' ' + df.dst_computer\n", + " ndf = df.drop_duplicates(subset=['feats'])\n", + " ndf.to_parquet('auth-feats-one-column.parquet')\n", + "else:\n", + " ndf = pd.read_parquet('auth-feats-one-column.parquet')\n", + " \n", + "print(ndf.shape)" + ] + }, + { + "cell_type": "markdown", + "id": "32d1755d", + "metadata": {}, + "source": [ + "## Red Team Data \n", + "Add it to the front of the DataFrame so we can keep track of it" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d67c86b8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# make a subsampled dataframe with the anom red-team data at top...so we can keep track.\n", + "# we don't need the full `df`, only the unique entries of 'feats' in `ndf` for \n", + "# fitting a model (in a few cells below)\n", + "\n", + "tdf = pd.concat([red_team.reset_index(), ndf.reset_index()])\n", + "tdf" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5f62b7b5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# add a fidicial index used later\n", + "tdf['node'] = range(len(tdf))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ffd6aac", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# total number of red team events\n", + "tdf.RED.sum()" + ] + }, + { + "cell_type": "markdown", + "id": "4264d547-b4a9-49d1-bc68-894f1e839c38", + "metadata": {}, + "source": [ + "## Enrichment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "72c53f98", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def get_confidences_per_cluster(g, col='RED', verbose=False):\n", + " \"\"\"\n", + " From DBSCAN clusters, will assess how many Red Team events exist,\n", + " assessing confidence.\n", + " \n", + " \"\"\"\n", + " resses = []\n", + " df = g._nodes\n", + " labels = df._dbscan\n", + " cnt = Counter(labels)\n", + " for clust, count in cnt.most_common():\n", + " res = df[df._dbscan==clust]\n", + " n = res.shape[0]\n", + " n_reds = res[col].sum()\n", + " resses.append([clust, n_reds/n, n_reds, n])\n", + " if n_reds>0 and verbose:\n", + " print('-'*20)\n", + " print(f'cluster: {clust}\\n red {100*n_reds/n:.2f}% or {n_reds} out of {count}')\n", + " conf_dict = {k[0]: k[1] for k in resses}\n", + " confidence = [conf_dict[k] for k in df._dbscan.values]\n", + " # enrichment\n", + " g._nodes['confidence'] = confidence\n", + " conf_df = pd.DataFrame(resses, columns=['_dbscan', 'confidence', 'n_red', 'total_in_cluster'])\n", + " conf_df = conf_df.sort_values(by='confidence', ascending=False)\n", + " return g, conf_df\n", + " " + ] + }, + { + "cell_type": "markdown", + "id": "9a3da6e3-b280-4c69-b0e0-4a92d9aac231", + "metadata": {}, + "source": [ + "# The Full UMAP Pipelines\n", + "Fit a model on 'feats' column" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "504781dc-9fbe-467c-9b4d-2e907133cfb7", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# this is a convienence method for setting parameters in `g.featurize()/umap()` -- just a verbose dictionary\n", + "cyber_model = ModelDict('A topic model for computer to computer', **topic_model)\n", + "\n", + "# umap_params_gpu = {'n_components': 2, \n", + "# 'n_neighbors': 20,\n", + "# 'min_dist': 0.1, \n", + "# 'spread': 1, \n", + "# 'local_connectivity': 1, \n", + "# 'repulsion_strength': 2, \n", + "# 'negative_sample_rate': 5}\n", + "#cyber_model.update(umap_params_gpu)\n", + "\n", + "cyber_model.update(dict(n_topics=32, X=['feats2'])) # name the column to featurize, which we lumped into `feats2`\n", + "\n", + "cyber_model" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5474ef79-b2dd-4299-bee7-e12d94c79613", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# if you stop processing during execution, sometimes calling this will unblock you on subsequent calls should it give an error.\n", + "#g.reset_caches()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6909cc90", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%time\n", + "process = True # set to false after it's run for ease of speed\n", + "if process:\n", + " # ##################################\n", + " g = graphistry.nodes(tdf, 'node') # two lines does the heavy lifting\n", + " # gpu version, will detect gpu and run\n", + " #g5 = g.umap(engine='auto', **cyber_model, verbose=True).dbscan(min_dist=1, verbose=True)\n", + " \n", + " # cpu version\n", + " g5 = g.umap(engine='umap_learn', **cyber_model, verbose=True).dbscan(min_dist=0.1, verbose=True)\n", + " # #########################\n", + " \n", + " g5, cluster_confidences = get_confidences_per_cluster(g5, verbose=True)\n", + " g5.save_search_instance('auth-feat-topic.search')\n", + "else:\n", + " g = graphistry.bind()\n", + " g5 = g.load_search_instance('auth-feat-topic.search')\n", + " g5, cluster_confidences = get_confidences_per_cluster(g5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "01632281-2ace-4917-9932-86b507b3d9e3", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# nodes dataframe is now enriched with _dbscan label\n", + "g5._nodes._dbscan" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9c1ba011-2aaa-4663-a319-4478502b1b8e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# the UMAP coordinates\n", + "g5._node_embedding" + ] + }, + { + "cell_type": "markdown", + "id": "54c13cba-bc36-4d49-8e7a-7dc05b27610a", + "metadata": {}, + "source": [ + "## Plot Graph\n", + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `cluster` assignment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "279fef41", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g5.name('auth test').plot(render=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "79ece955", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# see how the model has organized features\n", + "X = g5._node_features\n", + "X" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "87b32e09-3ca4-49de-b8c3-2b40ffa2b01d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "x = g5.get_matrix(['interactive', 'c17', 'microsoft'])\n", + "x.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "632d6d0f-8212-4f4a-a920-7600d7456351", + "metadata": {}, + "source": [ + "## Predict | Online Mode\n", + "\n", + "Once a model is fit, predict on new batches as we demonstrate here\n", + "\n", + "There are three main methods\n", + "\n", + "`g.transform` and `g.transform_umap` and if dbscan has been run, `g.transform_dbscan` \n", + "\n", + "see help(*) on each to learn more\n", + "\n", + "One may save the model as above, load it, and wrap in a FastAPI endpoint, etc, to serve in production pipelines." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b44d418", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# first sample a batch from the normal data (auth=df)\n", + "sdf = df.sample(200)\n", + "emb_normal, xp_normal, _ = g5.transform_umap(sdf, None, kind='nodes', return_graph=False)\n", + "# then transform all the red team data\n", + "emb_red, xp_red, _ = g5.transform_umap(red_team, None, kind='nodes', return_graph=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fe3e5058-6ac6-4d1a-a368-66ecd5dd703b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "emb_red" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2b6c471-338a-40d6-92a8-03c2505c433f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# transform_dbscan will predict on new data (here just red_team to prove it works)\n", + "g7 = g5.transform_dbscan(red_team, None, kind='nodes', return_graph=True, verbose=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ad82c787-c246-440d-9ed6-97ddc2805491", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "_, ccdf = get_confidences_per_cluster(g7)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5e0760fe-40c0-45b9-a787-d4f98d557c24", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(f'total confidence across clusters {ccdf.confidence.mean()*100}%')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2911840d-ffd7-4815-97fd-53bc43cbc522", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g7.plot()" + ] + }, + { + "cell_type": "markdown", + "id": "ace3e171-2e33-435e-82d7-7158d7931d14", + "metadata": {}, + "source": [ + "# We can simulate how a batch of new data would behave" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "03672813-db4e-4d0c-a5f5-598ab165986c", + "metadata": {}, + "outputs": [], + "source": [ + "# cpu version\n", + "plt.figure(figsize=(10,7))\n", + "plt.scatter(g5._node_embedding.x, g5._node_embedding.y, c='b', s=60, alpha=0.5) # the totality of the fit data\n", + "plt.scatter(emb_normal.x, emb_normal.y, c='g') # batch of new data\n", + "plt.scatter(emb_red.x, emb_red.y, c='r') # red labels to show good cluster seperation\n", + "plt.scatter(emb_normal.x, emb_normal.y, c='g') # batch of new data, to see if they occlude " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a8d5aa9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# gpu version\n", + "# scatter to see how well it does.\n", + "plt.figure(figsize=(10,7))\n", + "plt.scatter(g5._node_embedding.x.to_numpy(), g5._node_embedding.y.to_numpy() , c='b', s=60, alpha=0.5) # the totality of the fit data\n", + "plt.scatter(emb_normal.x.to_numpy(), emb_normal.y.to_numpy(), c='g') # batch of new data\n", + "plt.scatter(emb_red.x.to_numpy(), emb_red.y.to_numpy(), c='r') # red labels to show good cluster seperation\n", + "plt.scatter(emb_normal.x.to_numpy(), emb_normal.y.to_numpy(), c='g') # batch of new data, to see if they occlude " + ] + }, + { + "cell_type": "markdown", + "id": "b53dd8ed-39b2-4000-9ec7-139d1e2a6a85", + "metadata": {}, + "source": [ + "## 96% Reduction in Alerts\n", + "\n", + "This indicates a huge reduction in the search space needed.\n", + "\n", + "Since we have clear cluster assignments along with (post facto) confidences of known anomalous activity, we can reduce the search space on new events (gotten via Kafka, Splunk, etc)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14d207db-9a58-45a3-9876-058632389f17", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# percent of RED team labels we get with 10% confidence or above\n", + "p = cluster_confidences[cluster_confidences.confidence>0.1].n_red.sum()/cluster_confidences[cluster_confidences.confidence>0.1].total_in_cluster.sum()\n", + "print(f'{100*p:.2f}%')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "755a3f27-935d-4ba8-96cb-cbff11fdf00e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# number of data points *not* to consider (and it's more if we look at df proper!)\n", + "cluster_confidences[cluster_confidences.confidence<0.1].total_in_cluster.sum()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5fd1cc50-0900-4694-8400-c426e314ec2e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "p = cluster_confidences[cluster_confidences.confidence<0.1].total_in_cluster.sum()/cluster_confidences.total_in_cluster.sum()\n", + "print(f'Alert Reduction {100*p:.2f}%')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ee508a5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plt.figure(figsize=(10,7))\n", + "plt.plot(np.cumsum([k[2] for k in cluster_confidences.values]))\n", + "plt.xlabel('Anomolous Cluster Number') # shows that we can ignore first clusters (containing most of the alerts)\n", + "plt.ylabel('Number of Identified Red Team Events')\n", + "print()" + ] + }, + { + "cell_type": "markdown", + "id": "5f168ac8-2324-4f47-b0d7-e4a0b041624f", + "metadata": {}, + "source": [ + "## Supervised UMAP\n", + "Here we use the RED team label to help supervise the UMAP fit. \n", + "This might be useful once teams have actually identified RED team events \n", + "and want to help separate clusters. \n", + "While separation is better, the unsupervised version does well without." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34ad4768-58e5-493e-a5e8-6f4748168e05", + "metadata": {}, + "outputs": [], + "source": [ + "# g.reset_caches()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0c6a16d-a899-43b6-a7ba-75b45f855a78", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%time\n", + "process = True\n", + "if process:\n", + " # ################################## # an example of setting features explicitly, could use ModelDict \n", + " g = graphistry.nodes(tdf, 'node')\n", + " g6 = g.umap(X=['feats'], y =['RED'], \n", + " min_words=100000, # set high to bypass sbert encoding\n", + " cardinality_threshold=2, # set low to force topic modeling\n", + " n_topics=32,\n", + " spread=1,\n", + " use_scaler_target=None, # keep labels unscaled\n", + " dbscan=True, engine='umap_learn') # add dbscan here\n", + " # ##################################\n", + " \n", + " g6, cluster_confidences6 = get_confidences_per_cluster(g6, verbose=True)\n", + " g6.save_search_instance('auth-feat-supervised-topic.search')\n", + "else:\n", + " g = graphistry.bind()\n", + " g6 = g.load_search_instance('auth-feat-supervised-topic.search')\n", + " g6, cluster_confidences6 = get_confidences_per_cluster(g6)\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a98ef657-5307-41d9-ae31-79c1794b3728", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g6.get_matrix(target=True).astype(int)" + ] + }, + { + "cell_type": "markdown", + "id": "0cc72ab4-c0da-4541-b32b-aa771d6e510f", + "metadata": { + "tags": [] + }, + "source": [ + "### Plot\n", + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `_dbscan` assignment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "16e09a7d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g6.name('auth topic with supervised umap').plot(render=RENDER)" + ] + }, + { + "cell_type": "markdown", + "id": "88169a53", + "metadata": {}, + "source": [ + "## A model of Computer-Computer and metadata features\n", + "Here we include `auth_type` and `logontype` " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1731ae44-57e0-4c3e-bad0-ac486bba589c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "tdf['feats']" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "35b03bc4-915b-431b-ada5-d8281a4ece6d", + "metadata": {}, + "outputs": [], + "source": [ + "%%time\n", + "process = True\n", + "if process:\n", + " # #####################################\n", + " g = graphistry.nodes(tdf, 'node')\n", + " g7 = g.umap(X=['feats'], #y =['RED'], \n", + " min_words=100000, \n", + " cardinality_threshold=2, \n", + " n_topics=32,\n", + " use_scaler=None,\n", + " use_scaler_target=None, \n", + " spread=1,\n", + " dbscan=True, engine='auto') # add dbscan here\n", + " # ###################################\n", + " g7, cluster_confidences7 = get_confidences_per_cluster(g7)\n", + " #g7.save_search_instance('auth-just-ip-topic.search')\n", + "else:\n", + " g7 = graphistry.bind().load_search_instance('auth-just-ip-topic.search')\n", + " g7, cluster_confidences7 = get_confidences_per_cluster(g7)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f291e227-ae14-4205-96dd-3c1de29d12e6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "cluster_confidences7" + ] + }, + { + "cell_type": "markdown", + "id": "836883cb-bc66-4a40-9ca8-f01fd38b6f2a", + "metadata": { + "tags": [] + }, + "source": [ + "### Plot\n", + "Color by `confidence` and hover over `red` team histogram to see where events occur. Alternatively, color by `cluster` assignment" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1e586a3", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g7.name('auth topic ips-ips only, no supervision').plot(render=RENDER)\n", + "# very similar to graph with metadata included, showing that ip-ip is strong indicator of phenomenon" + ] + }, + { + "cell_type": "markdown", + "id": "6cf68ed4", + "metadata": {}, + "source": [ + "# Conditional Probability\n", + "Let's see if conditiona probability of computer to computer connections can give us good histograms to tease out red team nodes? This is to baseline the above UMAP models, and we find in retrospect, UMAP wins. \n", + "\n", + "The conditional graph is however useful to see aggregate behavior, and coloring by 'red' team shows topology of Infection" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d6f58dd", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "g = graphistry.edges(tdf, \"src_computer\", \"dst_computer\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f3b44db2-b34e-4398-8c5a-7a10bbe5d681", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "x='dst_computer'\n", + "given='src_computer'\n", + "cg = g.conditional_graph(x, given, kind='edges')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b2af6a2-4f10-4707-beb8-4f3447d3e3b8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# the new edge dataframe assess conditiona prob of computer-to-computer connection\n", + "cprob = cg._edges\n", + "cprob" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5258aee1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# enrich the edges dataframe with the redteam data\n", + "# since cprobs lost those labels during the function call\n", + "indx = cprob.src_computer.isin(red_team.src_computer) & cprob.dst_computer.isin(red_team.dst_computer)\n", + "cprob.loc[indx, 'red'] = 1\n", + "cprob.loc[~indx, 'red'] = 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7ff921fc-3ecd-4404-acd7-8db943a4ebcc", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "cprob" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b4b10152-cac9-4497-b016-dd67b54cdcf2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# add edges back to graphistry instance\n", + "cg._edges = cprob" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b3af1cd-6423-4484-8b99-81fad821f118", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# full condprob graph\n", + "cg.plot(render=RENDER)" + ] + }, + { + "cell_type": "markdown", + "id": "42fb3dff", + "metadata": {}, + "source": [ + "## Learning\n", + "The conditional graph shows that most of the edge probabilities are between 4e-7 and 0.03, whose bucket contains most of the events. Thus the chances of finding the red team edges are ~ 1e-4 -- slim indeed. UMAP wins." + ] + }, + { + "cell_type": "markdown", + "id": "9d2cd536", + "metadata": {}, + "source": [ + "Likewise the transpose conditional is even worse \n", + "with prob_detection ~ 6e-5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e0cbef82-421d-489e-8666-84d412cae5a9", + "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.8.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/demos/demos_databases_apis/gpu_rapids/part_iv_gpu_cuml.ipynb b/demos/demos_databases_apis/gpu_rapids/part_iv_gpu_cuml.ipynb index 14e67afb7f..849887d4b9 100644 --- a/demos/demos_databases_apis/gpu_rapids/part_iv_gpu_cuml.ipynb +++ b/demos/demos_databases_apis/gpu_rapids/part_iv_gpu_cuml.ipynb @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 2, "metadata": { "vscode": { "languageId": "python" @@ -101,43 +101,43 @@ " \n", " \n", " 0\n", - " 61\n", - " 26\n", - " 937\n", - " 2019-04-05\n", - " 113.47,20.34\n", + " 32\n", + " 185\n", + " 357\n", + " 2017-06-16\n", + " 117.81,22.87\n", " \n", " \n", " 1\n", - " 30\n", - " 19\n", - " 972\n", - " 2019-08-17\n", - " 117.61,20.24\n", + " 66\n", + " 86\n", + " 84\n", + " 2020-03-30\n", + " 110.07,20.52\n", " \n", " \n", " 2\n", - " 27\n", - " 134\n", - " 760\n", - " 2020-05-30\n", - " 115.11,23.5\n", + " 28\n", + " 26\n", + " 862\n", + " 2019-05-12\n", + " 116.16,23.02\n", " \n", " \n", " 3\n", - " 55\n", - " 44\n", - " 864\n", - " 2016-08-17\n", - " 119.14,21.56\n", + " 69\n", + " 193\n", + " 607\n", + " 2019-03-11\n", + " 112.21,23.25\n", " \n", " \n", " 4\n", - " 24\n", - " 184\n", - " 938\n", - " 2017-09-30\n", - " 113.64,23.54\n", + " 34\n", + " 27\n", + " 4\n", + " 2019-08-06\n", + " 114.56,20.99\n", " \n", " \n", " ...\n", @@ -149,43 +149,43 @@ " \n", " \n", " 995\n", - " 69\n", - " 72\n", - " 887\n", - " 2019-10-26\n", - " 115.18,23.8\n", + " 52\n", + " 128\n", + " 435\n", + " 2016-10-19\n", + " 115.3,23.67\n", " \n", " \n", " 996\n", - " 33\n", - " 29\n", - " 651\n", - " 2020-06-15\n", - " 117.05,21.3\n", + " 67\n", + " 116\n", + " 97\n", + " 2016-04-24\n", + " 117.69,23.92\n", " \n", " \n", " 997\n", - " 18\n", - " 101\n", - " 517\n", - " 2019-04-14\n", - " 111.96,23.58\n", + " 32\n", + " 55\n", + " 915\n", + " 2018-11-07\n", + " 113.63,22.74\n", " \n", " \n", " 998\n", - " 65\n", - " 19\n", - " 974\n", - " 2019-05-22\n", - " 112.48,23.63\n", + " 72\n", + " 68\n", + " 148\n", + " 2020-05-23\n", + " 116.39,21.25\n", " \n", " \n", " 999\n", - " 23\n", - " 42\n", - " 156\n", - " 2020-12-10\n", - " 118.72,22.49\n", + " 56\n", + " 19\n", + " 932\n", + " 2016-04-23\n", + " 116.2,23.54\n", " \n", " \n", "\n", @@ -193,23 +193,23 @@ "" ], "text/plain": [ - " age user_id profile date location\n", - "0 61 26 937 2019-04-05 113.47,20.34\n", - "1 30 19 972 2019-08-17 117.61,20.24\n", - "2 27 134 760 2020-05-30 115.11,23.5\n", - "3 55 44 864 2016-08-17 119.14,21.56\n", - "4 24 184 938 2017-09-30 113.64,23.54\n", - ".. ... ... ... ... ...\n", - "995 69 72 887 2019-10-26 115.18,23.8\n", - "996 33 29 651 2020-06-15 117.05,21.3\n", - "997 18 101 517 2019-04-14 111.96,23.58\n", - "998 65 19 974 2019-05-22 112.48,23.63\n", - "999 23 42 156 2020-12-10 118.72,22.49\n", + " age user_id profile date location\n", + "0 32 185 357 2017-06-16 117.81,22.87\n", + "1 66 86 84 2020-03-30 110.07,20.52\n", + "2 28 26 862 2019-05-12 116.16,23.02\n", + "3 69 193 607 2019-03-11 112.21,23.25\n", + "4 34 27 4 2019-08-06 114.56,20.99\n", + ".. .. ... ... ... ...\n", + "995 52 128 435 2016-10-19 115.3,23.67\n", + "996 67 116 97 2016-04-24 117.69,23.92\n", + "997 32 55 915 2018-11-07 113.63,22.74\n", + "998 72 68 148 2020-05-23 116.39,21.25\n", + "999 56 19 932 2016-04-23 116.2,23.54\n", "\n", "[1000 rows x 5 columns]" ] }, - "execution_count": 112, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -230,12 +230,13 @@ "df['lat']=np.round(np.random.uniform(110, 120,size=(samples)), 2)\n", "df['location']=df['lat'].astype(str) +\",\"+ df[\"lon\"].astype(str) \n", "df.drop(columns=['lat','lon'],inplace=True)\n", + "df = df.applymap(str)\n", "df" ] }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 3, "metadata": { "vscode": { "languageId": "python" @@ -243,38 +244,18 @@ }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "['time: 0.03180466492970784 line/min: 31441.928478420414']\n" + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (1000, 0) in UMAP fit, as it is not one dimensional" ] }, { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 113, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "['time: 0.14064184427261353 line/min: 7110.259433612426']\n" + ] } ], "source": [ @@ -296,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 4, "metadata": { "vscode": { "languageId": "python" @@ -304,38 +285,18 @@ }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "['time: 0.02227895657221476 line/min: 44885.40550625031']\n" + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (1000, 14) in UMAP fit, as it is not one dimensional" ] }, { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 114, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "['time: 0.0287002166112264 line/min: 34842.94260026035']\n" + ] } ], "source": [ @@ -350,7 +311,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 5, "metadata": { "vscode": { "languageId": "python" @@ -358,38 +319,18 @@ }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "['time: 0.023025786876678465 line/min: 43429.56900260569']\n" + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (1000, 14) in UMAP fit, as it is not one dimensional" ] }, { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 115, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "['time: 0.0024895787239074705 line/min: 401674.38386140653']\n" + ] } ], "source": [ @@ -411,7 +352,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 6, "metadata": { "vscode": { "languageId": "python" @@ -419,61 +360,30 @@ }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "['time: 0.003930246829986573 line/min: 254436.94588602122']\n" + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (1000, 14) in UMAP fit, as it is not one dimensional" ] }, { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 117, - "metadata": {}, - "output_type": "execute_result" + "name": "stdout", + "output_type": "stream", + "text": [ + "['time: 0.0022179365158081056 line/min: 450869.5325013168']\n" + ] } ], "source": [ "g = graphistry.nodes(df)\n", "t=time()\n", - "g2 = g.umap(X=['user_id'],y=['date','location'], feature_engine='torch', n_neighbors= 2,min_dist=.5, spread=.1, local_connectivity=2, n_components=5,metric='hellinger')\n", + "g2 = g.umap(X=['user_id'],y=['date','location'], feature_engine='torch', n_neighbors= 2,min_dist=.1, spread=.1, local_connectivity=2, n_components=5,metric='hellinger')\n", "min=(time()-t)/60\n", "lin=df.shape[0]/min\n", "print(['time: '+str(min)+' line/min: '+str(lin)])\n", - "g2.plot()\n" + "g2.plot(render=False)" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "metadata": {}, @@ -483,18 +393,25 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 7, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (1000, 0) in UMAP fit, as it is not one dimensional" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "['time: 0.004134837786356608 line/min: 241847.4560960093']\n" + "['time: 0.00446544885635376 line/min: 223941.65338544376']\n" ] } ], @@ -509,18 +426,25 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 8, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "* Ignoring target column of shape (1000, 0) in UMAP fit, as it is not one dimensional" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "['time: 0.06711641947428386 line/min: 14899.483730403068']\n" + "['time: 0.11818180878957113 line/min: 8461.539134001174']\n" ] } ], @@ -542,18 +466,25 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 12, "metadata": { "vscode": { "languageId": "python" } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "! Failed umap speedup attempt. Continuing without memoization speedups.* Ignoring target column of shape (220, 0) in UMAP fit, as it is not one dimensional" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "['time: 0.0008151054382324219 line/min: 269903.7323037323']\n" + "['time: 0.008098324139912924 line/min: 27166.11439590581']\n" ] } ], @@ -570,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 13, "metadata": { "vscode": { "languageId": "python" @@ -582,15 +513,15 @@ "output_type": "stream", "text": [ "\n", - "Int64Index: 3728 entries, 0 to 3749\n", + "Int64Index: 2410 entries, 0 to 2821\n", "Data columns (total 3 columns):\n", " # Column Non-Null Count Dtype \n", "--- ------ -------------- ----- \n", - " 0 _src_implicit 3728 non-null int32 \n", - " 1 _dst_implicit 3728 non-null int32 \n", - " 2 _weight 3728 non-null float32\n", + " 0 _src_implicit 2410 non-null int32 \n", + " 1 _dst_implicit 2410 non-null int32 \n", + " 2 _weight 2410 non-null float32\n", "dtypes: float32(1), int32(2)\n", - "memory usage: 72.8 KB\n", + "memory usage: 47.1 KB\n", "None\n" ] }, @@ -622,34 +553,34 @@ " \n", " \n", " \n", - " 1046\n", - " 71\n", - " 144\n", - " 0.205078\n", + " 671\n", + " 51\n", + " 123\n", + " 0.017956\n", " \n", " \n", - " 642\n", - " 41\n", - " 74\n", - " 0.176112\n", + " 2123\n", + " 167\n", + " 194\n", + " 0.663975\n", " \n", " \n", - " 811\n", - " 53\n", - " 152\n", - " 0.079932\n", + " 1761\n", + " 139\n", + " 78\n", + " 0.113361\n", " \n", " \n", - " 2699\n", - " 171\n", - " 70\n", - " 0.140091\n", + " 2444\n", + " 191\n", + " 3\n", + " 0.999991\n", " \n", " \n", - " 1466\n", - " 101\n", - " 144\n", - " 0.050159\n", + " 2441\n", + " 190\n", + " 152\n", + " 0.544303\n", " \n", " \n", "\n", @@ -657,14 +588,14 @@ ], "text/plain": [ " _src_implicit _dst_implicit _weight\n", - "1046 71 144 0.205078\n", - "642 41 74 0.176112\n", - "811 53 152 0.079932\n", - "2699 171 70 0.140091\n", - "1466 101 144 0.050159" + "671 51 123 0.017956\n", + "2123 167 194 0.663975\n", + "1761 139 78 0.113361\n", + "2444 191 3 0.999991\n", + "2441 190 152 0.544303" ] }, - "execution_count": 78, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -676,55 +607,16 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 16, "metadata": { "vscode": { "languageId": "python" } }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "g3.plot()" + "#g3.plot()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "vscode": { - "languageId": "python" - } - }, - "outputs": [], - "source": [] } ], "metadata": { @@ -733,7 +625,18 @@ "language": "python", "name": "python3" }, - "orig_nbformat": 4, + "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.15" + }, "vscode": { "interpreter": { "hash": "21c4dad877b49e935d0a60da22bc51e9bfc4901bc58e488dc71d08b8faef6557" diff --git a/docker/test-gpu-local.sh b/docker/test-gpu-local.sh index 12667b3a04..158584f9b6 100755 --- a/docker/test-gpu-local.sh +++ b/docker/test-gpu-local.sh @@ -45,5 +45,4 @@ docker run \ graphistry/test-gpu:${TEST_CPU_VERSION} \ --maxfail=1 \ --ignore=graphistry/tests/test_feature_utils.py \ - --ignore=graphistry/tests/test_umap_utils.py \ $@ diff --git a/docs/source/conf.py b/docs/source/conf.py index 319295df56..1f47612c1a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -37,9 +37,10 @@ #'sphinx.ext.autosummary', #'sphinx.ext.intersphinx', "sphinx.ext.ifconfig", - "sphinx_autodoc_typehints", + "sphinx_autodoc_typehints" ] + #FIXME Why is sphinx/autodoc failing here? nitpick_ignore = [ ('py:class', '1'), # Ex: api : Optional[Literal[1, 3]] @@ -53,13 +54,24 @@ ('py:class', 'graphistry.layouts.LayoutsMixin'), ('py:class', 'graphistry.compute.ComputeMixin'), ('py:class', 'graphistry.compute.conditional.ConditionalMixin'), + ('py:class', 'graphistry.compute.cluster.ClusterMixin'), ('py:class', 'graphistry.Plottable.Plottable'), + ('py:class', 'graphistry.plugins.cugraph.compute_cugraph'), + ('py:class', 'graphistry.plugins.cugraph.from_cugraph'), + ('py:class', 'graphistry.plugins.igraph.compute_igraph'), + ('py:class', 'graphistry.plugins.igraph.from_igraph'), + ('py:class', 'graphistry.plugins.igraph.layout_igraph'), ('py:class', 'graphistry.feature_utils.FeatureMixin'), ('py:class', 'graphistry.dgl_utils.DGLGraphMixin'), ('py:class', 'graphistry.umap_utils.UMAPMixin'), ('py:class', 'graphistry.text_utils.SearchToGraphMixin'), ('py:class', 'graphistry.embed_utils.HeterographEmbedModuleMixin'), ('py:class', 'graphistry.PlotterBase.PlotterBase'), + ('py:class', 'graphistry.compute.ast.ASTObject'), + ('py:class', 'Plotter'), + ('py:class', 'Plottable'), + ('py:class', 'CuGraphKind'), + ('py:class', 'cugraph.Graph'), ('py:class', 'IGraph graph'), ('py:class', 'igraph'), ('py:class', 'dgl'), @@ -84,6 +96,7 @@ ('py:data', 'typing.List'), ('py:data', 'typing.Literal'), ('py:data', 'typing.Optional'), + ('py:data', 'typing.Callable'), ('py:data', 'typing.Tuple'), ('py:data', 'typing.Union'), ('py:class','pandas.core.frame.DataFrame') diff --git a/docs/source/graphistry.compute.rst b/docs/source/graphistry.compute.rst index 6ea4bdedbd..c610034aab 100644 --- a/docs/source/graphistry.compute.rst +++ b/docs/source/graphistry.compute.rst @@ -1,29 +1,58 @@ -graphistry.layout package -========================= - -Subpackages ------------ +ComputeMixin module +------------------------------------------------ -.. toctree:: - :maxdepth: 4 +.. automodule:: graphistry.compute.ComputeMixin + :members: + :undoc-members: + :show-inheritance: + :noindex: -Submodules ----------- +Chain +--------------- -graphistry.compute.ComputeMixin module ------------------------------------------------- +.. automodule:: graphistry.compute.chain + :members: + :undoc-members: + :show-inheritance: + :noindex: -.. automodule:: graphistry.compute.ComputeMixin +Cluster +--------------- +.. automodule:: graphistry.compute.cluster :members: :undoc-members: :show-inheritance: + :noindex: +Collapse +--------------- +.. automodule:: graphistry.compute.collapse + :members: + :undoc-members: + :show-inheritance: + :noindex: -Module contents +Conditional --------------- +.. automodule:: graphistry.compute.conditional + :members: + :undoc-members: + :show-inheritance: + :noindex: + +Filter by Dictionary +-------------------- +.. automodule:: graphistry.compute.filter_by_dict + :members: + :undoc-members: + :show-inheritance: + :noindex: -.. automodule:: graphistry.compute +Hop +--------------- +.. automodule:: graphistry.compute.hop :members: :undoc-members: :show-inheritance: + :noindex: diff --git a/docs/source/graphistry.layout.gib.rst b/docs/source/graphistry.layout.gib.rst index 51352d8212..50b21ec335 100644 --- a/docs/source/graphistry.layout.gib.rst +++ b/docs/source/graphistry.layout.gib.rst @@ -1,3 +1,7 @@ +:orphan: + +.. ^ FIXME + graphistry.layout.gib package ================================== @@ -11,3 +15,5 @@ Module contents :members: :undoc-members: :show-inheritance: + + diff --git a/docs/source/graphistry.layout.graph.rst b/docs/source/graphistry.layout.graph.rst index 72d559ad11..283119ece6 100644 --- a/docs/source/graphistry.layout.graph.rst +++ b/docs/source/graphistry.layout.graph.rst @@ -59,3 +59,7 @@ Module contents :members: :undoc-members: :show-inheritance: + +graphistry.layout.gib + + diff --git a/docs/source/graphistry.layout.rst b/docs/source/graphistry.layout.rst index 7675db6e35..b2c1f8c43e 100644 --- a/docs/source/graphistry.layout.rst +++ b/docs/source/graphistry.layout.rst @@ -1,16 +1,59 @@ -graphistry.layout package -========================= -Subpackages ------------ -.. toctree:: - :maxdepth: 4 +edge Module +----------------------------------- + +.. automodule:: graphistry.layout.graph.edge + :members: + :undoc-members: + :show-inheritance: + :noindex: + +edgeBase Module +--------------------------------------- + +.. automodule:: graphistry.layout.graph.edgeBase + :members: + :undoc-members: + :show-inheritance: + :noindex: + +graph Module +------------------------------------ + +.. automodule:: graphistry.layout.graph.graph + :members: + :undoc-members: + :show-inheritance: + :noindex: + +graphBase Module +---------------------------------------- + +.. automodule:: graphistry.layout.graph.graphBase + :members: + :undoc-members: + :show-inheritance: + :noindex: + +vertex Module +------------------------------------- + +.. automodule:: graphistry.layout.graph.vertex + :members: + :undoc-members: + :show-inheritance: + :noindex: + +vertexBase Module +----------------------------------------- + +.. automodule:: graphistry.layout.graph.vertexBase + :members: + :undoc-members: + :show-inheritance: + :noindex: - graphistry.layout.gib - graphistry.layout.graph - graphistry.layout.sugiyama - graphistry.layout.utils Module contents --------------- @@ -19,3 +62,4 @@ Module contents :members: :undoc-members: :show-inheritance: + :noindex: diff --git a/docs/source/graphistry.layout.sugiyama.rst b/docs/source/graphistry.layout.sugiyama.rst index 41b83f7cb1..40ffaf7e83 100644 --- a/docs/source/graphistry.layout.sugiyama.rst +++ b/docs/source/graphistry.layout.sugiyama.rst @@ -1,3 +1,5 @@ +:orphan: + graphistry.layout.sugiyama package ================================== @@ -19,3 +21,6 @@ Module contents :members: :undoc-members: :show-inheritance: + + +.. FIXME:orphan \ No newline at end of file diff --git a/docs/source/graphistry.layout.utils.rst b/docs/source/graphistry.layout.utils.rst index de1d80140d..76b71fdc52 100644 --- a/docs/source/graphistry.layout.utils.rst +++ b/docs/source/graphistry.layout.utils.rst @@ -1,6 +1,11 @@ graphistry.layout.utils package =============================== +.. toctree:: + :maxdepth: 2 + + graphistry.layout.graph + Submodules ---------- diff --git a/docs/source/graphistry.plotter.rst b/docs/source/graphistry.plotter.rst new file mode 100644 index 0000000000..98079a1bc7 --- /dev/null +++ b/docs/source/graphistry.plotter.rst @@ -0,0 +1,17 @@ +Plotter Base +---------------------- +.. automodule:: graphistry.PlotterBase + :members: + :undoc-members: + :show-inheritance: + :noindex: + + +Plotter Modules +---------------------- +.. automodule:: graphistry.Plottable + :members: + :undoc-members: + :show-inheritance: + :noindex: + diff --git a/docs/source/graphistry.plugins.rst b/docs/source/graphistry.plugins.rst index d3e64fc1ab..492e4ac3fb 100644 --- a/docs/source/graphistry.plugins.rst +++ b/docs/source/graphistry.plugins.rst @@ -1,17 +1,4 @@ -graphistry.plugins package -========================== - -Subpackages ------------ - -.. toctree:: - :maxdepth: 4 - - -Submodules ----------- - -graphistry.plugins.igraph module +iGraph ------------------------------------------------ .. automodule:: graphistry.plugins.igraph @@ -20,10 +7,10 @@ graphistry.plugins.igraph module :show-inheritance: -Module contents +CuGraph --------------- -.. automodule:: graphistry.plugins +.. automodule:: graphistry.plugins.cugraph :members: :undoc-members: :show-inheritance: diff --git a/docs/source/graphistry.plugins_types.rst b/docs/source/graphistry.plugins_types.rst index 2b9b21ee1c..1b07a10b54 100644 --- a/docs/source/graphistry.plugins_types.rst +++ b/docs/source/graphistry.plugins_types.rst @@ -1,6 +1,12 @@ graphistry.plugins\_types package ================================= + +.. toctree:: + :maxdepth: 2 + + graphistry.layout.utils + Submodules ---------- diff --git a/docs/source/graphistry.rst b/docs/source/graphistry.rst index c9fbcfa4dd..2fd55094a2 100644 --- a/docs/source/graphistry.rst +++ b/docs/source/graphistry.rst @@ -1,42 +1,88 @@ -graphistry package +plotter +======= +.. toctree:: + :maxdepth: 3 + + graphistry.plotter + + +Plugins +================== +.. toctree:: + :maxdepth: 3 + + + graphistry.plugins + + + +Compute ================== .. toctree:: :maxdepth: 3 graphistry.compute + + +Layouts +================== +.. toctree:: + :maxdepth: 3 + + graphistry.layout - graphistry.plugins - graphistry.plugins_types -graphistry.plotter module -------------------------- +Featurize +================== +.. automodule:: graphistry.feature_utils + :members: + :undoc-members: + :show-inheritance: + -.. automodule:: graphistry.plotter +UMAP +================== +.. automodule:: graphistry.umap_utils :members: :undoc-members: :show-inheritance: -graphistry.pygraphistry module ------------------------------- -.. automodule:: graphistry.pygraphistry +Semantic Search +================== +.. automodule:: graphistry.text_utils :members: :undoc-members: :show-inheritance: -graphistry.arrow_uploader module --------------------------------- +DBScan +================== +.. automodule:: graphistry.compute.cluster + :members: + :undoc-members: + :show-inheritance: + +Arrow uploader Module +============================ .. automodule:: graphistry.arrow_uploader :members: :undoc-members: :show-inheritance: -graphistry.ArrowFileUploader module ------------------------------------ +Arrow File Uploader Module +============================ .. automodule:: graphistry.ArrowFileUploader :members: :undoc-members: :show-inheritance: + +Versioneer +================== + +.. automodule:: graphistry._version + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst index 1943a5cf72..9b10c2c91c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,8 +1,65 @@ -PyGraphistry's documentation (|version|) +PyGraphistry: Explore Relationships ======================================== +.. only:: html -Quickstart: -`Read our tutorial `_ + .. image:: https://readthedocs.org/projects/pygraphistry/badge/?version=latest + :target: https://pygraphistry.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + + + .. image:: https://github.com/graphistry/pygraphistry/workflows/CI%20Tests/badge.svg + :target: https://github.com/graphistry/pygraphistry/workflows/CI%20Tests/badge.svg + :alt: Build Status + + + .. image:: https://github.com/graphistry/pygraphistry/workflows/CodeQL/badge.svg + :target: https://github.com/graphistry/pygraphistry/actions?query=workflow%3ACodeQL + :alt: CodeQL Status + + .. image:: https://img.shields.io/pypi/v/graphistry.svg + :target: https://pypi.python.org/pypi/graphistry + :alt: PyPi Status + + .. image:: https://img.shields.io/pypi/dm/graphistry + :target: https://img.shields.io/pypi/dm/graphistry + :alt: PyPi Downloads + + + .. image:: https://img.shields.io/pypi/l/graphistry.svg + :target: https://pypi.python.org/pypi/graphistry + :alt: License + + .. .. image:: https://img.shields.io/uptimerobot/status/m787548531-e9c7b7508fc76fea927e2313?label=hub.graphistry.com + .. :target: https://img.shields.io/uptimerobot/status/m787548531-e9c7b7508fc76fea927e2313?label=hub.graphistry.com + .. :alt: License + + .. .. image:: https://img.shields.io/badge/slack-Graphistry%20chat-orange.svg?logo=slack + .. :target: https://join.slack.com/t/graphistry-community/shared_invite/zt-53ik36w2-fpP0Ibjbk7IJuVFIRSnr6g + .. :alt: Slack + + .. image:: https://img.shields.io/twitter/follow/graphistry + :target: https://twitter.com/graphistry + :alt: Twitter + +.. Quickstart: +.. `Read our tutorial `_ + +PyGraphistry is a Python visual graph AI library to extract, transform, analyze, model, and visualize big graphs, and especially alongside Graphistry end-to-end GPU server sessions. Installing optional graphistry[ai] dependencies adds graph autoML, including automatic feature engineering, UMAP, and graph neural net support. Combined, PyGraphistry reduces your time to graph for going from raw data to visualizations and AI models down to three lines of code. +Here in our docstrings you can find useful packages, modules, and commands to maximize your graph AI experience with PyGraphistry. In the navbar you can find an overview of all the packages and modules we provided and a few useful highlighted ones as well. You can search for them on our Search page. For a full tutorial, refer to our `PyGraphistry `_ repo. + +.. .. image:: docs/static/docstring.png +.. :width: 600 +.. :alt: PyGraphistry + + +.. Click to open interactive version! (For server-backed interactive analytics, use an API key) + + +.. .. raw:: html + +.. + +For self-hosting and access to a free API key, refer to our Graphistry `Hub `_. .. toctree:: :maxdepth: 3 @@ -10,6 +67,13 @@ Quickstart: graphistry modules +Articles +================== +* `Graphistry: Visual Graph AI Interactive demo `_ +* `PyGraphistry + Databricks `_ +* `PyGraphistry + UMAP `_ + + Indices and tables ================== diff --git a/docs/source/modules.rst b/docs/source/modules.rst index 2d0d70fd92..ced1d0941f 100644 --- a/docs/source/modules.rst +++ b/docs/source/modules.rst @@ -1,5 +1,5 @@ -doc -=== +Modules +##################### .. toctree:: :maxdepth: 4 diff --git a/docs/source/versioneer.rst b/docs/source/versioneer.rst index 804c171da3..1f5d4bae40 100644 --- a/docs/source/versioneer.rst +++ b/docs/source/versioneer.rst @@ -1,2 +1,6 @@ -versioneer module -================= +.. versioneer module +.. ================= +.. toctree:: + :maxdepth: 2 + + graphistry.plugins_types diff --git a/docs/static/docstring.png b/docs/static/docstring.png new file mode 100644 index 0000000000..a61e42c592 Binary files /dev/null and b/docs/static/docstring.png differ diff --git a/graphistry/Plottable.py b/graphistry/Plottable.py index ca0aaca31d..8a483ddade 100644 --- a/graphistry/Plottable.py +++ b/graphistry/Plottable.py @@ -84,7 +84,7 @@ class Plottable(object): # embed utils _relation : Optional[str] _use_feat: bool - triplets: Optional[List] # actually torch.Tensor too + _triplets: Optional[List] # actually torch.Tensor too _kg_embed_dim: int diff --git a/graphistry/PlotterBase.py b/graphistry/PlotterBase.py index 7d22469d8f..0b9dbe9235 100644 --- a/graphistry/PlotterBase.py +++ b/graphistry/PlotterBase.py @@ -165,23 +165,20 @@ def __init__(self, *args, **kwargs): self._bolt_driver : any = None self._tigergraph : any = None + # feature engineering self._node_embedding = None self._node_encoder = None self._node_features = None - self._node_ordinal_pipeline = None - self._node_ordinal_pipeline_target = None, + self._node_features_raw = None self._node_target = None self._node_target_encoder = None - self._node_text_model = None self._edge_embedding = None self._edge_encoder = None self._edge_features = None - self._edge_ordinal_pipeline = None - self._edge_ordinal_pipeline_target = None + self._edge_features_raw = None self._edge_target = None self._edge_target_encoder = None - self._edge_text_model = None self._weighted_adjacency_nodes = None self._weighted_adjacency_edges = None @@ -190,6 +187,7 @@ def __init__(self, *args, **kwargs): self._weighted_edges_df_from_edges = None self._xy = None + # the fit umap instance self._umap = None self._adjacency = None @@ -201,6 +199,13 @@ def __init__(self, *args, **kwargs): self._use_feat: bool = False self._triplets: Optional[List] = None self._kg_embed_dim: int = 128 + + # Dbscan + self._node_dbscan = None # the fit dbscan instance + self._edge_dbscan = None + + # DGL + self.DGL_graph = None # the DGL graph def __repr__(self): @@ -295,7 +300,7 @@ def style(self, fg=None, bg=None, page=None, logo=None): :param fg: Dictionary {'blendMode': str} of any valid CSS blend mode :type fg: dict - :param bg: Nested dictionary of page background properties. {'color': str, 'gradient': {'kind': str, 'position': str, 'stops': list }, 'image': { 'url': str, 'width': int, 'height': int, 'blendMode': str } + :param bg: Nested dictionary of page background properties. { 'color': str, 'gradient': {'kind': str, 'position': str, 'stops': list }, 'image': { 'url': str, 'width': int, 'height': int, 'blendMode': str } :type bg: dict :param logo: Nested dictionary of logo properties. { 'url': str, 'autoInvert': bool, 'position': str, 'dimensions': { 'maxWidth': int, 'maxHeight': int }, 'crop': { 'top': int, 'left': int, 'bottom': int, 'right': int }, 'padding': { 'top': int, 'left': int, 'bottom': int, 'right': int}, 'style': str} @@ -309,15 +314,18 @@ def style(self, fg=None, bg=None, page=None, logo=None): **Example: Chained merge - results in url and blendMode being set, while color is dropped** :: + g2 = g.style(bg={'color': 'black'}, fg={'blendMode': 'screen'}) g3 = g2.style(bg={'image': {'url': 'http://site.com/watermark.png'}}) **Example: Gradient background** :: + g.style(bg={'gradient': {'kind': 'linear', 'position': 45, 'stops': [['rgb(0,0,0)', '0%'], ['rgb(255,255,255)', '100%']]}}) **Example: Page settings** :: + g.style(page={'title': 'Site - {{ name }}', 'favicon': 'http://site.com/logo.ico'}) """ @@ -334,17 +342,10 @@ def style(self, fg=None, bg=None, page=None, logo=None): def encode_axis(self, rows=[]): """Render radial and linear axes with optional labels - :param rows: List of rows - { - label: Optional[str], - ?r: float, - ?x: float, - ?y: float, - ?internal: true, - ?external: true, - ?space: true - } + :param rows: List of rows - { label: Optional[str],?r: float, ?x: float, ?y: float, ?internal: true, ?external: true, ?space: true } :returns: Plotter + :rtype: Plotter **Example: Several radial axes** @@ -537,9 +538,7 @@ def encode_point_icon(self, column, comparator=None, for_default=True, for_current=False, as_text=False, blend_mode=None, style=None, border=None, shape=None): - """Set node icon with more control than bind(). - Values from Font Awesome 4 such as "laptop": https://fontawesome.com/v4.7.0/icons/ , image URLs (http://...), and data URIs (data:...). - When as_text=True is enabled, values are instead interpreted as raw strings. + """Set node icon with more control than bind(). Values from Font Awesome 4 such as "laptop": https://fontawesome.com/v4.7.0/icons/ , image URLs (http://...), and data URIs (data:...). When as_text=True is enabled, values are instead interpreted as raw strings. :param column: Data column name :type column: str @@ -606,9 +605,7 @@ def encode_edge_icon(self, column, comparator=None, for_default=True, for_current=False, as_text=False, blend_mode=None, style=None, border=None, shape=None): - """Set edge icon with more control than bind() - Values from Font Awesome 4 such as "laptop": https://fontawesome.com/v4.7.0/icons/ , image URLs (http://...), and data URIs (data:...). - When as_text=True is enabled, values are instead interpreted as raw strings. + """Set edge icon with more control than bind() Values from Font Awesome 4 such as "laptop": https://fontawesome.com/v4.7.0/icons/ , image URLs (http://...), and data URIs (data:...). When as_text=True is enabled, values are instead interpreted as raw strings. :param column: Data column name :type column: str @@ -828,10 +825,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, edge_source_color=None, edge_destination_color=None, point_title=None, point_label=None, point_color=None, point_weight=None, point_size=None, point_opacity=None, point_icon=None, point_x=None, point_y=None): - """Relate data attributes to graph structure and visual representation. - - To facilitate reuse and replayable notebooks, the binding call is chainable. Invocation does not effect the old binding: it instead returns a new Plotter instance with the new bindings added to the existing ones. Both the old and new bindings can then be used for different graphs. - + """Relate data attributes to graph structure and visual representation. To facilitate reuse and replayable notebooks, the binding call is chainable. Invocation does not effect the old binding: it instead returns a new Plotter instance with the new bindings added to the existing ones. Both the old and new bindings can then be used for different graphs. :param source: Attribute containing an edge's source ID :type source: str @@ -851,7 +845,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, :param edge_label: Attribute overriding edge's expanded label text. By default, scrollable list of attribute/value mappings. :type edge_label: str - :param edge_color: Attribute overriding edge's color. rgba (int64) or int32 palette index, see palette definitions `_ for values. Based on Color Brewer. + :param edge_color: Attribute overriding edge's color. rgba (int64) or int32 palette index, see `palette `_ definitions for values. Based on Color Brewer. :type edge_color: str :param edge_source_color: Attribute overriding edge's source color if no edge_color, as an rgba int64 value. @@ -869,7 +863,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, :param point_label: Attribute overriding node's expanded label text. By default, scrollable list of attribute/value mappings. :type point_label: str - :param point_color: Attribute overriding node's color.rgba (int64) or int32 palette index, see palette definitions `_ for values. Based on Color Brewer. + :param point_color: Attribute overriding node's color.rgba (int64) or int32 palette index, see `palette `_ definitions for values. Based on Color Brewer. :type point_color: str :param point_size: Attribute overriding node's size. By default, uses the node degree. The visualization will normalize point sizes and adjust dynamically using semantic zoom. @@ -885,6 +879,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, :rtype: Plotter **Example: Minimal** + :: import graphistry @@ -892,6 +887,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, g = g.bind(source='src', destination='dst') **Example: Node colors** + :: import graphistry @@ -900,6 +896,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, node='id', point_color='color') **Example: Chaining** + :: import graphistry @@ -916,6 +913,7 @@ def bind(self, source=None, destination=None, node=None, edge=None, g3b = g2b.bind(point_size='size3b') In the above **Chaining** example, all bindings use src/dst/id. Colors and sizes bind to: + :: g: default/default @@ -924,8 +922,6 @@ def bind(self, source=None, destination=None, node=None, edge=None, g2b: color2b/size2b g3a: color2a/size3a g3b: color2b/size3b - - """ res = copy.copy(self) res._source = source or self._source @@ -1002,6 +998,7 @@ def nodes(self, nodes: Union[Callable, Any], node=None, *args, **kwargs) -> Plot **Example** :: + import graphistry def sample_nodes(g, n): @@ -1056,7 +1053,7 @@ def edges(self, edges: Union[Callable, Any], source=None, destination=None, edge If a callable, will be called with current Plotter and whatever positional+named arguments :param edges: Edges and their attributes, or transform from Plotter to edges - :type edges: Pandas dataframe, NetworkX graph, or IGraph graph. + :type edges: Pandas dataframe, NetworkX graph, or IGraph graph :returns: Plotter :rtype: Plotter @@ -1101,6 +1098,7 @@ def edges(self, edges: Union[Callable, Any], source=None, destination=None, edge **Example** :: + import graphistry def sample_edges(g, n): diff --git a/graphistry/_version.py b/graphistry/_version.py index c9b3980271..3bb0a87502 100644 --- a/graphistry/_version.py +++ b/graphistry/_version.py @@ -52,7 +52,7 @@ class NotThisMethod(Exception): """Exception raised if a method is not valid for the current scenario.""" -LONG_VERSION_PY = {} +LONG_VERSION_PY = {} # type: ignore HANDLERS = {} diff --git a/graphistry/ai_utils.py b/graphistry/ai_utils.py index 1b18dd4404..0f58cf3256 100644 --- a/graphistry/ai_utils.py +++ b/graphistry/ai_utils.py @@ -1,9 +1,17 @@ import pandas as pd +import numpy as np import graphistry -from .util import setup_logger -logger = setup_logger(__name__) +from .constants import DISTANCE, WEIGHT, BATCH +from logging import getLogger + +try: + import faiss # type ignore +except: + faiss = None + +logger = getLogger(__name__) # ################################################################################################# @@ -33,7 +41,7 @@ def search_to_df(word, col, df, as_string=False): res = df[df[col].str.contains(word, case=False)] except TypeError as e: logger.error(e) - return pd.DataFrame([], columns = df.columns) + return pd.DataFrame([], columns=df.columns) return res @@ -127,3 +135,350 @@ def get_graphistry_from_milieu_search( ntdf = ndf[ndf[node_col].isin(gcols)] g = graphistry.edges(tdf, src, dst).nodes(ntdf, node_col) return g + + + + +# ######################################################################################################################### +# +# Graphistry Vector Search Index +# +########################################################################################################################## + + +class FaissVectorSearch: + def __init__(self, M): + import faiss + self.index = faiss.IndexFlatL2(M.shape[1]) + self.index.add(M) + + def search(self, q, k=5): + """ + Search for the k nearest neighbors of a query vector q. + + Parameters: + - q: the query vector to search for + - k: the number of nearest neighbors to return (default: 5) + + Returns: + - Index: a numpy array of size (k,) containing the indices of the k nearest neighbors + - Distances: a numpy array of size (k,) containing the distances to the k nearest neighbors + """ + q = np.asarray(q, dtype=np.float32) + Distances, Index = self.index.search(q.reshape(1, -1), k) + return Index[0], Distances[0] + + def search_df(self, q, df, k): + """ Query by vector using annoy index and append distance to results + + it is assumed len(vect) == len(df) == len(search_index) + args: + vect: query vector + df: dataframe to query + search_index: annoy index + top_n: number of results to return + returns: + sorted dataframe with top_n results and distance + """ + + indices, distances = self.search(q.values[0], k=k) + + results = df.iloc[indices] + results.loc[:, DISTANCE] = distances + results = results.sort_values(by=[DISTANCE]) + + return results + + +# ######################################################################################################################### +# +# Graphistry Graph Inference +# +########################################################################################################################## + +def edgelist_to_weighted_adjacency(g, weights=None): + """ Convert edgelist to weighted adjacency matrix in sparse coo_matrix""" + import scipy.sparse as ss + import numpy as np + res = g._edges[[g._source, g._destination]].values.astype(np.int64) + rows, cols = res.T[0], res.T[1] + if weights is None: + weights = np.ones(len(rows)) + M = ss.coo_matrix((weights, (rows, cols))) + return M.tocsr() + +def hydrate_graph(res, new_nodes, new_edges, node, src, dst, new_emb, new_features, new_targets): + # ######################################################### + g = res.nodes(new_nodes, node).edges(new_edges, src, dst) + + # TODO this needs more work since edgelist_to_weighted_adjacency produces non square matrices (since infer_graph will add new nodes) + #g._weighted_adjacency = edgelist_to_weighted_adjacency(g) + g._node_embedding = new_emb + g._node_features = new_features + g._node_targets = new_targets + g = g.settings(url_params={'play': 0}) + return g + + +def infer_graph( + res, emb, X, y, df, infer_on_umap_embedding=False, eps="auto", sample=None, n_neighbors=7, verbose=False, +): + """ + Infer a graph from a graphistry object + + args: + res: graphistry object + df: outside minibatch dataframe to add to existing graph + X: minibatch transformed dataframe + emb: minibatch UMAP embedding distance threshold for a minibatch point to cluster to existing graph + eps: if 'auto' will find a good epsilon from the data; distance threshold for a minibatch point to cluster to existing graph + sample: number of nearest neighbors to add from existing graphs edges, if None, ignores existing edges. + This sets the global stickiness of the graph, and is a good way to control the number of edges incuded from the old graph. + n_neighbors, int: number of nearest neighbors to include per batch point within epsilon. + This sets the local stickiness of the graph, and is a good way to control the number of edges between + an added point and the existing graph. + returns: + graphistry Plottable object + """ + #enhanced = is_notebook() + + print("-" * 50) if verbose else None + + if infer_on_umap_embedding and emb is not None: + X_previously_fit = res._node_embedding + X_new = emb + print("Infering edges over UMAP embedding") if verbose else None + else: # can still be umap, but want to do the inference on the higher dimensional features + X_previously_fit = res._node_features + X_new = X + print("Infering edges over features embedding") if verbose else None + + print("-" * 45) if verbose else None + + FEATS = res._node_features + if FEATS is None: + raise ValueError("Must have node features to infer edges") + EMB = res._node_embedding if res._node_embedding is not None else FEATS.index + Y = res._node_target if res._node_target is not None else FEATS.index + + assert ( + df.shape[0] == X.shape[0] + ), "minibatches df and X must have same number of rows since f(df) = X" + if emb is not None: + assert ( + emb.shape[0] == df.shape[0] + ), "minibatches emb and X must have same number of rows since h(df) = emb" + df = df.assign(x=emb.x, y=emb.y) # add x and y to df for graphistry instance + + # if umap, need to add '_n' as node id to df, adding new indices to existing graph + numeric_indices = range( + X_previously_fit.shape[0], X_previously_fit.shape[0] + X_new.shape[0] + ) + df["_n"] = numeric_indices + df[BATCH] = 1 # 1 for minibatch, 0 for existing graph + node = res._node + + if node not in df.columns: + df[node] = numeric_indices + + NDF = res._nodes + NDF[BATCH] = 0 + EDF = res._edges + EDF[BATCH] = 0 + src = res._source + dst = res._destination + + #new_nodes = [] + new_edges = [] + old_edges = [] + old_nodes = [] + mdists = [] + + # check if pandas or cudf + if 'cudf.core.dataframe' in str(type(X_previously_fit)): + # move it out of memory... + X_previously_fit = X_previously_fit.to_pandas() + + for i in range(X_new.shape[0]): + diff = X_previously_fit - X_new.iloc[i, :] + dist = np.linalg.norm(diff, axis=1) # Euclidean distance + mdists.append(dist) + + m, std = np.mean(mdists), np.std(mdists) + logger.info(f"--Mean distance to existing nodes {m:.2f} +/- {std:.2f}") + print(f' Mean distance to existing nodes {m:.2f} +/- {std:.2f}') if verbose else None + if eps == "auto": + eps = np.min([np.abs(m - std), m]) + logger.info( + f"-epsilon = {eps:.2f} max distance threshold to be considered a neighbor" + ) + print(f' Max distance threshold; epsilon = {eps:.2f}') if verbose else None + + print(f' Finding {n_neighbors} nearest neighbors') if verbose else None + nn = [] + for i, dist in enumerate(mdists): + record_df = df.iloc[i, :] + nearest = np.where(dist < eps)[0] + nn.append(len(nearest)) + for j in nearest[:n_neighbors]: # add n_neighbors nearest neighbors, if any, super speedup hack + this_ndf = NDF.iloc[j, :] + if sample: + local_edges = EDF[ + (EDF[src] == this_ndf[node]) | (EDF[dst] == this_ndf[node]) + ] + if not local_edges.empty: + old_edges.append(local_edges.sample(sample, replace=True)) + + weight = min(1 / (dist[j] + 1e-3), 1) + new_edges.append([this_ndf[node], record_df[node], weight, 1]) + old_nodes.append(this_ndf) + #new_nodes.extend([record_df, this_ndf]) + + print(f' {np.mean(nn):.2f} neighbors per node within epsilon {eps:.2f}') if verbose else None + + new_edges = pd.DataFrame(new_edges, columns=[src, dst, WEIGHT, BATCH]) + + all_nodes = [] + if len(old_edges): + old_edges = pd.concat(old_edges, axis=0).assign(_batch=0) + all_nodes = pd.concat([old_edges[src], old_edges[dst], new_edges[src], new_edges[dst]]).drop_duplicates() + print('', len(all_nodes), "nodes in new graph") if verbose else None + + if sample: + new_edges = pd.concat([new_edges, old_edges], axis=0).drop_duplicates() + print(' Sampled', len(old_edges.drop_duplicates()), 'previous old edges') if verbose else None + new_edges = new_edges.drop_duplicates() + print('', len(new_edges), 'total edges after dropping duplicates') if verbose else None + + if len(old_nodes): + old_nodes = pd.DataFrame(old_nodes) + old_nodes = pd.concat( + [old_nodes, NDF[NDF[node].isin(all_nodes)]], axis=0 + ).drop_duplicates(subset=[node]) + else: + old_nodes = NDF[NDF[node].isin(all_nodes)] + + old_emb = None + if EMB is not None: + old_emb = EMB.loc[old_nodes.index] + + new_emb = None + if emb is not None: + if 'cudf.core.dataframe.DataFrame' in str(type(old_emb)): # convert to pd + old_emb = old_emb.to_pandas() + new_emb = pd.concat([emb, old_emb], axis=0) + + new_features = pd.concat([X, FEATS.loc[old_nodes.index]], axis=0) + + new_nodes = pd.concat([df, old_nodes], axis=0) # append minibatch at top + print(" ** Final graph has", len(new_nodes), "nodes") if verbose else None + print(" - Batch has", len(df), "nodes") if verbose else None + print(" - Brought in", len(old_nodes), "nodes") if verbose else None + + new_targets = pd.concat([y, Y.loc[old_nodes.index]]) if y is not None else Y + + print("-" * 50) if verbose else None + return hydrate_graph(res, new_nodes, new_edges, node, src, dst, new_emb, new_features, new_targets) + + +def infer_self_graph(res, + emb, X, y, df, infer_on_umap_embedding=False, eps="auto", n_neighbors=7, verbose=False, +): + """ + Infer a graph from a graphistry object + + args: + df: outside minibatch dataframe to add to existing graph + X: minibatch transformed dataframe + emb: minibatch UMAP embedding distance threshold for a minibatch point to cluster to existing graph + eps: if 'auto' will find a good epsilon from the data; distance threshold for a minibatch point to cluster to existing graph + sample: number of nearest neighbors to add from existing graphs edges, if None, ignores existing edges. + This sets the global stickiness of the graph, and is a good way to control the number of edges incuded from the old graph. + n_neighbors, int: number of nearest neighbors to include per batch point within epsilon. + This sets the local stickiness of the graph, and is a good way to control the number of edges between + an added point and the existing graph. + returns: + graphistry Plottable object + """ + #enhanced = is_notebook() + + print("-" * 50) if verbose else None + + if infer_on_umap_embedding and emb is not None: + X_previously_fit = emb + X_new = emb + print("Infering edges over UMAP embedding") if verbose else None + else: # can still be umap, but want to do the inference on the higher dimensional features + X_previously_fit = X + X_new = X + print("Infering edges over features embedding") if verbose else None + + print("-" * 45) if verbose else None + + assert ( + df.shape[0] == X.shape[0] + ), "minibatches df and X must have same number of rows since f(df) = X" + if emb is not None: + assert ( + emb.shape[0] == df.shape[0] + ), "minibatches emb and X must have same number of rows since h(df) = emb" + df = df.assign(x=emb.x, y=emb.y) # add x and y to df for graphistry instance + else: # if umap has been fit, but only transforming over features, need to add x and y or breaks plot binds of res + df['x'] = np.random.random(df.shape[0]) + df['y'] = np.random.random(df.shape[0]) + + # if umap, need to add '_n' as node id to df, adding new indices to existing graph + numeric_indices = np.arange( + X_previously_fit.shape[0], + dtype=np.float64 # this seems off but works + ) + df["_n"] = numeric_indices + df[BATCH] = 1 # 1 for minibatch, 0 for existing graph, here should all be `1` + node = res._node + if node not in df.columns: + df[node] = numeric_indices + + src = res._source + dst = res._destination + + old_nodes = [] + new_edges = [] + mdists = [] + + for i in range(X_new.shape[0]): + diff = X_previously_fit - X_new.iloc[i, :] + dist = np.linalg.norm(diff, axis=1) # Euclidean distance + mdists.append(dist) + + m, std = np.mean(mdists), np.std(mdists) + logger.info(f"--Mean distance to existing nodes {m:.2f} +/- {std:.2f}") + print(f' Mean distance to existing nodes {m:.2f} +/- {std:.2f}') if verbose else None + if eps == "auto": + eps = np.min([np.abs(m - std), m]) + logger.info( + f" epsilon = {eps:.2f} max distance threshold to be considered a neighbor" + ) + print(f' Max distance threshold; epsilon = {eps:.2f}') if verbose else None + + print(f' Finding {n_neighbors} nearest neighbors') if verbose else None + nn = [] + for i, dist in enumerate(mdists): + record_df = df.iloc[i, :] + nearest = np.where(dist < eps)[0] + nn.append(len(nearest)) + for j in nearest[:n_neighbors]: # add n_neighbors nearest neighbors, if any, super speedup hack + if i != j: + this_ndf = df.iloc[j, :] + weight = min(1 / (dist[j] + 1e-3), 1) + new_edges.append([this_ndf[node], record_df[node], weight, 1]) + old_nodes.append(this_ndf) + + print(f' {np.mean(nn):.2f} neighbors per node within epsilon {eps:.2f}') if verbose else None + + new_edges = pd.DataFrame(new_edges, columns=[src, dst, WEIGHT, BATCH]) + new_edges = new_edges.drop_duplicates() + print('', len(new_edges), 'total edges after dropping duplicates') if verbose else None + print(" ** Final graph has", len(df), "nodes") if verbose else None + # ######################################################### + print("-" * 50) if verbose else None + return hydrate_graph(res, df, new_edges, node, src, dst, emb, X, y) diff --git a/graphistry/compute/ComputeMixin.py b/graphistry/compute/ComputeMixin.py index 8fd9895b95..7a9b2f71c7 100644 --- a/graphistry/compute/ComputeMixin.py +++ b/graphistry/compute/ComputeMixin.py @@ -347,6 +347,9 @@ def collapse( :param node: start `node` to begin traversal :param attribute: the given `attribute` to collapse over within `column` :param column: the `column` of nodes DataFrame that contains `attribute` to collapse over + :param self_edges: whether to include self edges in the collapsed graph + :param unwrap: whether to unwrap the collapsed graph into a single node + :param verbose: whether to print out collapse summary information :returns:A new Graphistry instance with nodes and edges DataFrame containing collapsed nodes and edges given by column attribute -- nodes and edges DataFrames contain six new columns `collapse_{node | edges}` and `final_{node | edges}`, while original (node, src, dst) columns are left untouched :rtype: Plottable diff --git a/graphistry/compute/chain.py b/graphistry/compute/chain.py index 057d56d328..4920b74c9f 100644 --- a/graphistry/compute/chain.py +++ b/graphistry/compute/chain.py @@ -90,28 +90,27 @@ def combine_steps(g: Plottable, kind: str, steps: List[Tuple[ASTObject,Plottable def chain(self: Plottable, ops: List[ASTObject]) -> Plottable: """ - Experimental: Chain a list of operations Return subgraph of matches according to the list of node & edge matchers - If any matchers are named, add a correspondingly named boolean-valued column to the output - :param ops: List[ASTobject] Various node and edge matchers - :type fg: dict + :param ops: List[ASTObject] Various node and edge matchers :returns: Plotter :rtype: Plotter **Example: Find nodes of some type** - :: + + :: from graphistry.ast import n people_nodes_df = g.chain([ n({"type": "person"}) ])._nodes **Example: Find 2-hop edge sequences with some attribute** - :: + + :: from graphistry.ast import e_forward diff --git a/graphistry/compute/cluster.py b/graphistry/compute/cluster.py new file mode 100644 index 0000000000..585b17acd8 --- /dev/null +++ b/graphistry/compute/cluster.py @@ -0,0 +1,438 @@ +import logging +import pandas as pd +import numpy as np + +from typing import Any, List, Union, TYPE_CHECKING, Tuple, Optional +from typing_extensions import Literal +from collections import Counter + +from graphistry.Plottable import Plottable +from graphistry.constants import CUML, UMAP_LEARN, DBSCAN # noqa type: ignore +from graphistry.features import ModelDict +from graphistry.feature_utils import get_matrix_by_column_parts + +logger = logging.getLogger("compute.cluster") + +if TYPE_CHECKING: + MIXIN_BASE = Plottable +else: + MIXIN_BASE = object + +DBSCANEngineConcrete = Literal["cuml", "umap_learn"] +DBSCANEngine = Literal[DBSCANEngineConcrete, "auto"] + + +def lazy_dbscan_import_has_dependency(): + has_min_dependency = True + DBSCAN = None + try: + from sklearn.cluster import DBSCAN + except ImportError: + has_min_dependency = False + logger.info("Please install sklearn for CPU DBSCAN") + + has_cuml_dependency = True + cuDBSCAN = None + try: + from cuml import DBSCAN as cuDBSCAN + except ImportError: + has_cuml_dependency = False + logger.info("Please install cuml for GPU DBSCAN") + + return has_min_dependency, DBSCAN, has_cuml_dependency, cuDBSCAN + +def lazy_cudf_import_has_dependancy(): + try: + import warnings + + warnings.filterwarnings("ignore") + import cudf # type: ignore + + return True, "ok", cudf + except ModuleNotFoundError as e: + return False, e, None + + +def resolve_cpu_gpu_engine( + engine: DBSCANEngine, +) -> DBSCANEngineConcrete: # noqa + if engine in [CUML, UMAP_LEARN, 'sklearn']: + return engine # type: ignore + if engine in ["auto"]: + ( + has_min_dependency, + _, + has_cuml_dependency, + _, + ) = lazy_dbscan_import_has_dependency() + if has_cuml_dependency: + return "cuml" + if has_min_dependency: + return "umap_learn" + + raise ValueError( # noqa + f'engine expected to be "auto", ' + '"umap_learn", "pandas", "sklearn", or "cuml" ' + f"but received: {engine} :: {type(engine)}" + ) + +def make_safe_gpu_dataframes(X, y, engine): + """helper method to coerce a dataframe to the correct type (pd vs cudf)""" + def safe_cudf(X, y): + new_kwargs = {} + kwargs = {'X': X, 'y': y} + for key, value in kwargs.items(): + if isinstance(value, cudf.DataFrame) and engine in ["pandas", 'sklearn', 'umap_learn']: + new_kwargs[key] = value.to_pandas() + elif isinstance(value, pd.DataFrame) and engine == "cuml": + new_kwargs[key] = cudf.from_pandas(value) + else: + new_kwargs[key] = value + return new_kwargs['X'], new_kwargs['y'] + + has_cudf_dependancy_, _, cudf = lazy_cudf_import_has_dependancy() + if has_cudf_dependancy_: + # print('DBSCAN CUML Matrices') + return safe_cudf(X, y) + else: + return X, y + + +def get_model_matrix(g, kind: str, cols: Optional[Union[List, str]], umap, target): + """ + Allows for a single function to get the model matrix for both nodes and edges as well as targets, embeddings, and features + + Args: + :g: graphistry graph + :kind: 'nodes' or 'edges' + :cols: list of columns to use for clustering given `g.featurize` has been run + :umap: whether to use UMAP embeddings or features dataframe + :target: whether to use the target dataframe or features dataframe + + Returns: + pd.DataFrame: dataframe of model matrix given the inputs + """ + assert kind in ["nodes", "edges"] + assert ( + hasattr(g, "_node_encoder") if kind == "nodes" else hasattr(g, "_edge_encoder") + ) + + df = g.get_matrix(cols, kind=kind, target=target) + + if umap and cols is None and g._umap is not None: + df = g._get_embedding(kind) + + #if g.engine_dbscan in [CUML]: + df, _ = make_safe_gpu_dataframes(df, None, g.engine_dbscan) + #print('\n df:', df.shape, df.columns) + return df + + +def dbscan_fit(g: Any, dbscan: Any, kind: str = "nodes", cols: Optional[Union[List, str]] = None, use_umap_embedding: bool = True, target: bool = False, verbose: bool = False): + """ + Fits clustering on UMAP embeddings if umap is True, otherwise on the features dataframe + or target dataframe if target is True. + + Args: + :g: graphistry graph + :kind: 'nodes' or 'edges' + :cols: list of columns to use for clustering given `g.featurize` has been run + :use_umap_embedding: whether to use UMAP embeddings or features dataframe for clustering (default: True) + """ + X = get_model_matrix(g, kind, cols, use_umap_embedding, target) + + if X.empty: + raise ValueError("No features found for clustering") + + dbscan.fit(X) + # this is a future feature one cuml supports it + if g.engine_dbscan == 'cuml': + labels = dbscan.labels_.to_numpy() + # dbscan.components_ = X[dbscan.core_sample_indices_.to_pandas()] # can't believe len(samples) != unique(labels) ... #cumlfail + else: + labels = dbscan.labels_ + + if kind == "nodes": + g._nodes = g._nodes.assign(_dbscan=labels) + elif kind == "edges": + g._edges = g._edges.assign(_dbscan=labels) + else: + raise ValueError("kind must be one of `nodes` or `edges`") + + kind = "node" if kind == "nodes" else "edge" + setattr(g, f"_{kind}_dbscan", dbscan) + + if cols is not None: # set False since we used the features for verbose + use_umap_embedding = False + + if verbose: + cnt = Counter(labels) + message = f"DBSCAN found {len(cnt)} clusters with {cnt[-1]} outliers" + print() + print('-' * len(message)) + print(message) + print(f"--fit on {'umap embeddings' if use_umap_embedding else 'feature embeddings'} of size {X.shape}") + print('-' * len(message)) + + return g + + +def dbscan_predict(X: pd.DataFrame, model: Any): + """ + DBSCAN has no predict per se, so we reverse engineer one here + from https://stackoverflow.com/questions/27822752/scikit-learn-predicting-new-points-with-dbscan + + """ + n_samples = X.shape[0] + + y_new = np.ones(shape=n_samples, dtype=int) * -1 + + for i in range(n_samples): + diff = model.components_ - X.iloc[i, :].values # NumPy broadcasting + + dist = np.linalg.norm(diff, axis=1) # Euclidean distance + + shortest_dist_idx = np.argmin(dist) + + if dist[shortest_dist_idx] < model.eps: + y_new[i] = model.labels_[model.core_sample_indices_[shortest_dist_idx]] + + return y_new + + +class ClusterMixin(MIXIN_BASE): + def __init__(self, *args, **kwargs): + pass + + def _cluster_dbscan( + self, res, kind, cols, fit_umap_embedding, target, min_dist, min_samples, engine_dbscan, verbose, *args, **kwargs + ): + """DBSCAN clustering on cpu or gpu infered by .engine flag + """ + _, DBSCAN, _, cuDBSCAN = lazy_dbscan_import_has_dependency() + + if engine_dbscan in [CUML]: + print('`g.transform_dbscan(..)` not supported for engine=cuml, will return `g.transform_umap(..)` instead') + + res.engine_dbscan = engine_dbscan # resolve_cpu_gpu_engine(engine_dbscan) # resolve_cpu_gpu_engine("auto") + res._dbscan_params = ModelDict( + "latest DBSCAN params", + kind=kind, + cols=cols, + target=target, + fit_umap_embedding=fit_umap_embedding, + min_dist=min_dist, + min_samples=min_samples, + engine_dbscan=engine_dbscan, + verbose=verbose, + ) + + dbscan = ( + cuDBSCAN(eps=min_dist, min_samples=min_samples, *args, **kwargs) + if res.engine_dbscan == CUML + else DBSCAN(eps=min_dist, min_samples=min_samples, *args, **kwargs) + ) + # print('dbscan:', dbscan) + + res = dbscan_fit( + res, dbscan, kind=kind, cols=cols, use_umap_embedding=fit_umap_embedding, verbose=verbose + ) + + return res + + def dbscan( + self, + min_dist: float = 0.2, + min_samples: int = 1, + cols: Optional[Union[List, str]] = None, + kind: str = "nodes", + fit_umap_embedding: bool = True, + target: bool = False, + verbose: bool = False, + engine_dbscan: str = 'sklearn', + *args, + **kwargs, + ): + """DBSCAN clustering on cpu or gpu infered automatically. Adds a `_dbscan` column to nodes or edges. + NOTE: g.transform_dbscan(..) currently unsupported on GPU. + + Examples: + :: + + g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node') + + # cluster by UMAP embeddings + kind = 'nodes' | 'edges' + g2 = g.umap(kind=kind).dbscan(kind=kind) + print(g2._nodes['_dbscan']) | print(g2._edges['_dbscan']) + + # dbscan in umap or featurize API + g2 = g.umap(dbscan=True, min_dist=1.2, min_samples=2, **kwargs) + # or, here dbscan is infered from features, not umap embeddings + g2 = g.featurize(dbscan=True, min_dist=1.2, min_samples=2, **kwargs) + + # and via chaining, + g2 = g.umap().dbscan(min_dist=1.2, min_samples=2, **kwargs) + + # cluster by feature embeddings + g2 = g.featurize().dbscan(**kwargs) + + # cluster by a given set of feature column attributes, or with target=True + g2 = g.featurize().dbscan(cols=['ip_172', 'location', 'alert'], target=False, **kwargs) + + # equivalent to above (ie, cols != None and umap=True will still use features dataframe, rather than UMAP embeddings) + g2 = g.umap().dbscan(cols=['ip_172', 'location', 'alert'], umap=True | False, **kwargs) + + g2.plot() # color by `_dbscan` column + + Useful: + Enriching the graph with cluster labels from UMAP is useful for visualizing clusters in the graph by color, size, etc, as well as assessing metrics per cluster, e.g. https://github.com/graphistry/pygraphistry/blob/master/demos/ai/cyber/cyber-redteam-umap-demo.ipynb + + Args: + :min_dist float: The maximum distance between two samples for them to be considered as in the same neighborhood. + :kind str: 'nodes' or 'edges' + :cols: list of columns to use for clustering given `g.featurize` has been run, nice way to slice features or targets by fragments of interest, e.g. ['ip_172', 'location', 'ssh', 'warnings'] + :fit_umap_embedding bool: whether to use UMAP embeddings or features dataframe to cluster DBSCAN + :min_samples: The number of samples in a neighborhood for a point to be considered as a core point. This includes the point itself. + :target: whether to use the target column as the clustering feature + + """ + + res = self.bind() + res = res._cluster_dbscan( + res, + kind=kind, + cols=cols, + fit_umap_embedding=fit_umap_embedding, + target=target, + min_dist=min_dist, + min_samples=min_samples, + engine_dbscan=engine_dbscan, + verbose=verbose, + *args, + **kwargs, + ) + + return res + + def _transform_dbscan( + self, df: pd.DataFrame, ydf, kind, verbose + ) -> Tuple[Union[pd.DataFrame, None], pd.DataFrame, pd.DataFrame, pd.DataFrame]: + + res = self.bind() + if hasattr(res, "_dbscan_params"): + # Assume that we are transforming to last fit of dbscan + cols = res._dbscan_params["cols"] + umap = res._dbscan_params["fit_umap_embedding"] + target = res._dbscan_params["target"] + + dbscan = res._node_dbscan if kind == "nodes" else res._edge_dbscan + # print('DBSCAN TYPE IN TRANSFORM', type(dbscan)) + + emb = None + if umap and cols is None: + emb, X, y = res.transform_umap(df, ydf, kind=kind, return_graph=False) + else: + X, y = res.transform(df, ydf, kind=kind, return_graph=False) + XX = X + if target: + XX = y + if cols is not None: + XX = get_matrix_by_column_parts(XX, cols) + + if umap: + X_ = emb + else: + X_ = XX + + if res.engine_dbscan == 'cuml': + print('Transform DBSCAN not yet supported for engine_dbscan=`cuml`, use engine=`umap_learn`, `pandas` or `sklearn` instead') + return emb, X, y, df + + X_, emb = make_safe_gpu_dataframes(X_, emb, 'pandas') + + labels = dbscan_predict(X_, dbscan) # type: ignore + #print('after dbscan predict', type(labels)) + if umap and cols is None: + df = df.assign(_dbscan=labels, x=emb.x, y=emb.y) # type: ignore + else: + df = df.assign(_dbscan=labels) + + if verbose: + print(f"Transformed DBSCAN: {len(df[DBSCAN].unique())} clusters") + + return emb, X, y, df # type: ignore + else: + raise Exception("No dbscan model found. Please run `g.dbscan()` first") + + def transform_dbscan( + self, + df: pd.DataFrame, + y: Optional[pd.DataFrame] = None, + min_dist: Union[float, str] = "auto", + infer_umap_embedding: bool = False, + sample: Optional[int] = None, + n_neighbors: Optional[int] = None, + kind: str = "nodes", + return_graph: bool = True, + verbose: bool = False, + ): # type: ignore + """Transforms a minibatch dataframe to one with a new column '_dbscan' containing the DBSCAN cluster labels on the minibatch and generates a graph with the minibatch and the original graph, with edges between the minibatch and the original graph inferred from the umap embedding or features dataframe. Graph nodes | edges will be colored by '_dbscan' column. + + Examples: + :: + + fit: + g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node') + g2 = g.featurize().dbscan() + + predict: + :: + + emb, X, _, ndf = g2.transform_dbscan(ndf, return_graph=False) + # or + g3 = g2.transform_dbscan(ndf, return_graph=True) + g3.plot() + + likewise for umap: + :: + + fit: + g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node') + g2 = g.umap(X=.., y=..).dbscan() + + predict: + :: + + emb, X, y, ndf = g2.transform_dbscan(ndf, ndf, return_graph=False) + # or + g3 = g2.transform_dbscan(ndf, ndf, return_graph=True) + g3.plot() + + + Args: + :df: dataframe to transform + :y: optional labels dataframe + :min_dist: The maximum distance between two samples for them to be considered as in the same neighborhood. + smaller values will result in less edges between the minibatch and the original graph. + Default 'auto', infers min_dist from the mean distance and std of new points to the original graph + :fit_umap_embedding: whether to use UMAP embeddings or features dataframe when inferring edges between + the minibatch and the original graph. Default False, uses the features dataframe + :sample: number of samples to use when inferring edges between the minibatch and the original graph, + if None, will only use closest point to the minibatch. If greater than 0, will sample the closest `sample` points + in existing graph to pull in more edges. Default None + :kind: 'nodes' or 'edges' + :return_graph: whether to return a graph or the (emb, X, y, minibatch df enriched with DBSCAN labels), default True + infered graph supports kind='nodes' only. + :verbose: whether to print out progress, default False + + """ + emb, X, y, df = self._transform_dbscan(df, y, kind=kind, verbose=verbose) + if return_graph and kind not in ["edges"]: + df, y = make_safe_gpu_dataframes(df, y, 'pandas') + X, emb = make_safe_gpu_dataframes(X, emb, 'pandas') + g = self._infer_edges(emb, X, y, df, eps=min_dist, sample=sample, n_neighbors=n_neighbors, # type: ignore + infer_on_umap_embedding=infer_umap_embedding + ) + return g + return emb, X, y, df diff --git a/graphistry/compute/collapse.py b/graphistry/compute/collapse.py index ddf0885805..e9b06e512c 100644 --- a/graphistry/compute/collapse.py +++ b/graphistry/compute/collapse.py @@ -32,15 +32,15 @@ def unpack(g: Plottable): - """ - Helper method that unpacks graphistry instance + """Helper method that unpacks graphistry instance + ex: - ndf, edf, src, dst, node = unpack(g) - ----------------------------------------------------------------------------------------- + ndf, edf, src, dst, node = unpack(g) :param g: graphistry instance - :returns node DataFrame, edge DataFrame, source column, destination column, node column + + :returns: node DataFrame, edge DataFrame, source column, destination column, node column """ ndf = g._nodes edf = g._edges @@ -51,10 +51,7 @@ def unpack(g: Plottable): def get_children(g: Plottable, node_id: Union[str, int], hops: int = 1): - """ - Helper that gets children at k-hops from node `node_id` - - ------------------------------------------------------------------ + """Helper that gets children at k-hops from node `node_id` :returns graphistry instance of hops """ @@ -65,17 +62,14 @@ def get_children(g: Plottable, node_id: Union[str, int], hops: int = 1): def has_edge( g: Plottable, n1: Union[str, int], n2: Union[str, int], directed: bool = True ) -> bool: - """ - Checks if `n1` and `n2` share an (directed or not) edge - - ------------------------------------------------------------------ + """Checks if `n1` and `n2` share an (directed or not) edge :param g: graphistry instance :param n1: `node` to check if has edge to `n2` :param n2: `node` to check if has edge to `n1` :param directed: bool, if True, checks only outgoing edges from `n1`->`n2`, else finds undirected edges - :returns bool, if edge exists between `n1` and `n2` + :returns: bool, if edge exists between `n1` and `n2` """ ndf, edf, src, dst, node = unpack(g) if directed: @@ -92,16 +86,14 @@ def has_edge( def get_edges_of_node( g: Plottable, node_id: Union[str, int], outgoing_edges: bool = True, hops: int = 1 ): - """ - Gets edges of node at k-hops from node - - ---------------------------------------------------------------------------------- + """Gets edges of node at k-hops from node :param g: graphistry instance :param node_id: `node` to find edges from :param outgoing_edges: bool, if true, finds all outgoing edges of `node`, default True :param hops: the number of hops from `node` to take, default = 1 - :returns DataFrame of edges + + :returns: DataFrame of edges """ _, _, src, dst, _ = unpack(g) g2 = get_children(g, node_id, hops=hops) @@ -119,11 +111,7 @@ def get_edges_in_out_cluster( column: Union[str, int], directed: bool = True, ): - """ - Traverses children of `node_id` and separates them into incluster and outcluster sets depending if they have - `attribute` in node DataFrame `column` - - -------------------------------------------------------------------------------------------------------------------- + """Traverses children of `node_id` and separates them into incluster and outcluster sets depending if they have `attribute` in node DataFrame `column` :param g: graphistry instance :param node_id: `node` with `attribute` in `column` @@ -157,67 +145,57 @@ def get_edges_in_out_cluster( def get_cluster_store_keys(ndf: pd.DataFrame, node: Union[str, int]): - """ - Main innovation in finding and adding to super node. - Checks if node is a segment in any collapse_node in COLLAPSE column of nodes DataFrame - - -------------------------------------------------------------------------------------------- + """Main innovation in finding and adding to super node. Checks if node is a segment in any collapse_node in COLLAPSE column of nodes DataFrame :param ndf: node DataFrame :param node: node to find - :returns DataFrame of bools of where `wrap_key(node)` exists in COLLAPSE column + + :returns: DataFrame of bools of where `wrap_key(node)` exists in COLLAPSE column """ node = wrap_key(node) return ndf[COLLAPSE_NODE].astype(str).str.contains(node, na=False) def in_cluster_store_keys(ndf: pd.DataFrame, node: Union[str, int]) -> bool: - """ - checks if node is in collapse_node in COLLAPSE column of nodes DataFrame - - ------------------------------------------------------------------------------ + """checks if node is in collapse_node in COLLAPSE column of nodes DataFrame :param ndf: nodes DataFrame :param node: node to find - :returns bool + + :returns: bool """ return any(get_cluster_store_keys(ndf, node)) def reduce_key(key: Union[str, int]) -> str: - """ - Takes "1 1 2 1 2 3" -> "1 2 3 - - --------------------------------------------------- + """Takes "1 1 2 1 2 3" -> "1 2 3 :param key: node name - :returns new node name with duplicates removed + + :returns: new node name with duplicates removed """ uniques = " ".join(np.unique(str(key).split())) return uniques def unwrap_key(name: Union[str, int]) -> str: - """ - Unwraps node name: ~name~ -> name - - ---------------------------------------- + """Unwraps node name: ~name~ -> name :param name: node to unwrap - :returns unwrapped node name + + :returns: unwrapped node name """ return str(name).replace(WRAP, "") def wrap_key(name: Union[str, int]) -> str: - """ - Wraps node name -> ~name~ - - ----------------------------------- + """Wraps node name -> ~name~ :param name: node name - :returns wrapped node name + + :returns: wrapped node name """ + name = str(name) if WRAP in name: # idempotency return name @@ -225,17 +203,16 @@ def wrap_key(name: Union[str, int]) -> str: def melt(ndf: pd.DataFrame, node: Union[str, int]) -> str: - """ - Reduces node if in cluster store, otherwise passes it through. + """Reduces node if in cluster store, otherwise passes it through. ex: + node = "4" will take any sequence from get_cluster_store_keys, "1 2 3", "4 3 6" and returns "1 2 3 4 6" when they have a common entry (3). - ------------------------------------------------------------------------------------------------------------- - :param ndf, node DataFrame :param node: node to melt :returns new_parent_name of super node + """ rdf = ndf[get_cluster_store_keys(ndf, node)] topkey = wrap_key(node) @@ -259,14 +236,12 @@ def check_has_set(ndf, parent, child): def get_new_node_name( ndf: pd.DataFrame, parent: Union[str, int], child: Union[str, int] ) -> str: - """ - If child in cluster group, melts name, else makes new parent_name from parent, child - - --------------------------------------------------------------------------------------------------------- + """If child in cluster group, melts name, else makes new parent_name from parent, child :param ndf: node DataFrame :param parent: `node` with `attribute` in `column` :param child: `node` with `attribute` in `column` + :returns new_parent_name """ # THIS IS IMPORTANT FUNCTION -- it is where we wrap the parent/child in WRAP @@ -300,8 +275,6 @@ def collapse_nodes_and_edges( # outside logic controls when that is the case # for example, it assumes parent is already in cluster keys of COLLAPSE node - --------------------------------------------------------------------------------------- - :param g: graphistry instance :param parent: `node` with `attribute` in `column` :param child: `node` with `attribute` in `column` @@ -328,29 +301,24 @@ def collapse_nodes_and_edges( def has_property( g: Plottable, ref_node: Union[str, int], attribute: Union[str, int], column: Union[str, int] ) -> bool: - """ - Checks if ref_node is in node dataframe in column with attribute - - ------------------------------------------------------------------------- - + """Checks if ref_node is in node dataframe in column with attribute :param attribute: :param column: :param g: graphistry instance :param ref_node: `node` to check if it as `attribute` in `column` - :returns bool""" + + :returns: bool + """ ndf, edf, src, dst, node = unpack(g) ref_node = unwrap_key(ref_node) return ref_node in ndf[ndf[column] == attribute][node].values def check_default_columns_present_and_coerce_to_string(g: Plottable): - """ - Helper to set COLLAPSE columns to nodes and edges dataframe, while converting src, dst, node to dtype(str) - - ------------------------------------------------------------------------- - + """Helper to set COLLAPSE columns to nodes and edges dataframe, while converting src, dst, node to dtype(str) :param g: graphistry instance - :returns graphistry instance + + :returns: graphistry instance """ ndf, edf, src, dst, node = unpack(g) if COLLAPSE_NODE not in ndf.columns: @@ -376,32 +344,26 @@ def collapse_algo( column: Union[str, int], seen: dict, ): - """ - Basically candy crush over graph properties in a topology aware manner + """Basically candy crush over graph properties in a topology aware manner - Checks to see if child node has desired property from parent, we will need to check if - (start_node=parent: has_attribute , children nodes: has_attribute) by case - (T, T), (F, T), (T, F) and (F, F), - we start recursive collapse (or not) on the children, reassigning nodes and edges. + Checks to see if child node has desired property from parent, we will need to check if (start_node=parent: has_attribute , children nodes: has_attribute) by case (T, T), (F, T), (T, F) and (F, F),we start recursive collapse (or not) on the children, reassigning nodes and edges. if (T, T), append children nodes to start_node, re-assign the name of the node, and update the edge table with new name, - if (F, T) start k-(potentially new) super nodes, with k the number of children of start_node. - Start node keeps k outgoing edges. + if (F, T) start k-(potentially new) super nodes, with k the number of children of start_node. Start node keeps k outgoing edges. if (T, F) it is the end of the cluster, and we keep new node as is; keep going if (F, F); keep going - - -------------------------------------------------------------------------------------------------------------------- - + :param seen: :param g: graphistry instance :param child: child node to start traversal, for first traversal, set child=parent or vice versa. :param parent: parent node to start traversal, in main call, this is set to child. :param attribute: attribute to collapse by :param column: column in nodes dataframe to collapse over. - :returns graphistry instance with collapsed nodes. + + :returns: graphistry instance with collapsed nodes. """ compute_key = f"{parent} {child}" @@ -456,16 +418,13 @@ def normalize_graph( self_edges: bool = False, unwrap: bool = False ) -> Plottable: - """ - Final step after collapse traversals are done, removes duplicates and moves COLLAPSE columns into respective - (node, src, dst) columns of node, edges dataframe from Graphistry instance g. - - -------------------------------------------------------------------------------------------------------------------- + """Final step after collapse traversals are done, removes duplicates and moves COLLAPSE columns into respective(node, src, dst) columns of node, edges dataframe from Graphistry instance g. :param g: graphistry instance :param self_edges: bool, whether to keep duplicates from ndf, edf, default False :param unwrap: bool, whether to unwrap node text with `~`, default True - :returns final graphistry instance + + :returns: final graphistry instance """ ndf, edf, src, dst, node = unpack(g) @@ -527,7 +486,6 @@ def collapse_by( """ Main call in collapse.py, collapses nodes and edges by attribute, and returns normalized graphistry object. - -------------------------------------------------------------------------------------------------------------------- :param self: graphistry instance :param parent: parent node to start traversal, in main call, this is set to child. :param start_node: @@ -535,6 +493,7 @@ def collapse_by( :param column: column in nodes dataframe to collapse over. :param seen: dict of previously collapsed pairs -- {n1, n2) is seen as different from (n2, n1) :param verbose: bool, default True + :returns graphistry instance with collapsed and normalized nodes. """ from time import time diff --git a/graphistry/compute/conditional.py b/graphistry/compute/conditional.py index 101eee9829..df96c1c31f 100644 --- a/graphistry/compute/conditional.py +++ b/graphistry/compute/conditional.py @@ -66,7 +66,7 @@ def conditional_graph(self, x, given, kind='nodes', *args, **kwargs): Useful for finding the conditional probability of a node or edge attribute returned dataframe sums to 1 on each column - ----------------------------------------------------------- + :param x: target column :param given: the dependent column :param kind: 'nodes' or 'edges' diff --git a/graphistry/constants.py b/graphistry/constants.py index 1e9f862e92..f6fda05fd9 100644 --- a/graphistry/constants.py +++ b/graphistry/constants.py @@ -7,22 +7,36 @@ DST = "_dst_implicit" NODE = '_n_implicit' # Is this being use anymore?? WEIGHT = "_weight" +BATCH = "_batch" # for UMAP reserved namespace X = "x" Y = "y" IMPLICIT_NODE_ID = ( "_n" # for g.featurize(..).umap(..) -> g.weighted_edges_from_nodes_df ) -DISTANCE = '_distance' # for text search db column +# for text search db column +DISTANCE = '_distance' +# Scalers +SCALERS = ['quantile', 'standard', 'kbins', 'robust', 'minmax'] + +# dbscan reserved namespace +DBSCAN = '_dbscan' +DBSCAN_PARAMS = '_dbscan_params' + # ############################################################### # consistent clf pipelining and constructor methods across files -DGL_GRAPH = "DGL_graph" +DGL_GRAPH = "DGL_graph" # TODO: change to _dgl_graph ? +KG_GRAPH = '_kg_graph' FEATURE = "feature" TARGET = "target" LABEL = "label" LABEL_NODES = "node_label" LABEL_EDGES = "edge_label" +# ENGINES +CUML = 'cuml' +UMAP_LEARN = 'umap_learn' + TRAIN_MASK = "train_mask" TEST_MASK = "test_mask" @@ -38,12 +52,10 @@ # scikit-learn params SKLEARN = "sklearn" - # ############################################################# # Caching and other internals CACHE_COERCION_SIZE = 100 - # ############################################################# # Annoy defaults N_TREES = 10 diff --git a/graphistry/dgl_utils.py b/graphistry/dgl_utils.py index f82614dff1..257c13a701 100644 --- a/graphistry/dgl_utils.py +++ b/graphistry/dgl_utils.py @@ -229,7 +229,7 @@ def dgl_lazy_init(self, train_split: float = 0.8, device: str = "cpu"): self.train_split = train_split self.device = device self._removed_edges_previously = False - self.DGL_graph = None + self._dgl_graph = None self.dgl_initialized = True def _prune_edge_target(self): @@ -335,7 +335,7 @@ def _convert_edge_dataframe_to_DGL( 'destination column not set, try running g.bind(destination="my_col") or g.edges(df, destination="my_col")' ) - res.DGL_graph, res._adjacency, res._entity_to_index = pandas_to_dgl_graph( + res._dgl_graph, res._adjacency, res._entity_to_index = pandas_to_dgl_graph( res._edges, res._source, res._destination, @@ -370,7 +370,7 @@ def _featurize_nodes_to_dgl( ndata = convert_to_torch(X_enc, y_enc) # add ndata to the graph - res.DGL_graph.ndata.update(ndata) + res._dgl_graph.ndata.update(ndata) res._mask_nodes() return res @@ -396,7 +396,7 @@ def _featurize_edges_to_dgl( edata = convert_to_torch(X_enc, y_enc) # add edata to the graph - res.DGL_graph.edata.update(edata) + res._dgl_graph.edata.update(edata) res._mask_edges() return res @@ -443,7 +443,6 @@ def build_gnn( :param inplace: default, False, whether to return Graphistry instance in place or not. """ - if inplace: res = self else: @@ -504,30 +503,21 @@ def build_gnn( return res def _mask_nodes(self): - if config.FEATURE in self.DGL_graph.ndata: - n = self.DGL_graph.ndata[config.FEATURE].shape[0] + if config.FEATURE in self._dgl_graph.ndata: + n = self._dgl_graph.ndata[config.FEATURE].shape[0] ( - self.DGL_graph.ndata[config.TRAIN_MASK], - self.DGL_graph.ndata[config.TEST_MASK], + self._dgl_graph.ndata[config.TRAIN_MASK], + self._dgl_graph.ndata[config.TEST_MASK], ) = get_torch_train_test_mask(n, self.train_split) def _mask_edges(self): - if config.FEATURE in self.DGL_graph.edata: - n = self.DGL_graph.edata[config.FEATURE].shape[0] + if config.FEATURE in self._dgl_graph.edata: + n = self._dgl_graph.edata[config.FEATURE].shape[0] ( - self.DGL_graph.edata[config.TRAIN_MASK], - self.DGL_graph.edata[config.TEST_MASK], + self._dgl_graph.edata[config.TRAIN_MASK], + self._dgl_graph.edata[config.TEST_MASK], ) = get_torch_train_test_mask(n, self.train_split) - def __getitem__(self, idx): - # get one example by index, here we have only one graph. #todo parameterize case if we have RGNN - if self.DGL_graph is None: - logger.warning("DGL graph is not built, run `g.build_gnn(...)` first") - return self.DGL_graph - - # def __len__(self): # this messes up scope. - # # number of data examples - # return 1 # if __name__ == "__main__": @@ -607,7 +597,7 @@ def __getitem__(self, idx): # use_edge_scaler="zscale", # ) # # the DGL graph -# G = g2.DGL_graph +# G = g2._dgl_graph # print('G', G) # # to get a sense of the different parts in training loop above # # labels = torch.tensor(T.values, dtype=torch.float) diff --git a/graphistry/embed_utils.py b/graphistry/embed_utils.py index 10798d70a3..9e64fdfa10 100644 --- a/graphistry/embed_utils.py +++ b/graphistry/embed_utils.py @@ -6,6 +6,7 @@ from .PlotterBase import Plottable from .compute.ComputeMixin import ComputeMixin + def lazy_embed_import_dep(): try: import torch @@ -20,6 +21,13 @@ def lazy_embed_import_dep(): except: return False, None, None, None, None, None, None, None +def check_cudf(): + try: + import cudf + return True, cudf + except: + return False, object + if TYPE_CHECKING: _, torch, _, _, _, _, _, _ = lazy_embed_import_dep() @@ -30,6 +38,8 @@ def lazy_embed_import_dep(): MIXIN_BASE = object torch = Any +has_cudf, cudf = check_cudf() + XSymbolic = Optional[Union[List[str], str, pd.DataFrame]] ProtoSymbolic = Optional[Union[str, Callable[[TT, TT, TT], TT]]] # type: ignore @@ -89,7 +99,8 @@ def __init__(self): self._device = "cpu" def _preprocess_embedding_data(self, res, train_split:Union[float, int] = 0.8) -> Plottable: - _, torch, _, _, _, _, F, _ = lazy_embed_import_dep() + #_, torch, _, _, _, _, _, _ = lazy_embed_import_dep() + import torch log('Preprocessing embedding data') src, dst = res._source, res._destination relation = res._relation @@ -125,7 +136,7 @@ def _preprocess_embedding_data(self, res, train_split:Union[float, int] = 0.8) - log(msg="--Splitting data") train_size = int(train_split * len(triplets)) test_size = len(triplets) - train_size - train_dataset, test_dataset = torch.utils.data.random_split(triplets, [train_size, test_size]) + train_dataset, test_dataset = torch.utils.data.random_split(triplets, [train_size, test_size]) # type: ignore res._train_idx = train_dataset.indices res._test_idx = test_dataset.indices @@ -153,13 +164,13 @@ def _build_graph(self, res) -> Plottable: g_dgl.edata[dgl.ETYPE] = r g_dgl.edata["norm"] = dgl.norm_by_dst(g_dgl).unsqueeze(-1) - res.g_dgl = g_dgl + res._kg_dgl = g_dgl return res def _init_model(self, res, batch_size:int, sample_size:int, num_steps:int, device): _, _, _, _, GraphDataLoader, HeteroEmbed, _, _ = lazy_embed_import_dep() - g_iter = SubgraphIterator(res.g_dgl, sample_size, num_steps) + g_iter = SubgraphIterator(res._kg_dgl, sample_size, num_steps) g_dataloader = GraphDataLoader( g_iter, batch_size=batch_size, collate_fn=lambda x: x[0] ) @@ -209,7 +220,7 @@ def _train_embedding(self, res, epochs:int, batch_size:int, lr:float, sample_siz ) model.eval() - res._kg_embeddings = model(res.g_dgl.to(device)).detach() + res._kg_embeddings = model(res._kg_dgl.to(device)).detach() res._embed_model = model if res._eval_flag and res._train_idx is not None: score = res._eval(threshold=0.5) @@ -222,7 +233,7 @@ def _train_embedding(self, res, epochs:int, batch_size:int, lr:float, sample_siz @property def _gcn_node_embeddings(self): _, torch, _, _, _, _, _, _ = lazy_embed_import_dep() - g_dgl = self.g_dgl.to(self._device) + g_dgl = self._kg_dgl.to(self._device) em = self._embed_model(g_dgl).detach() torch.cuda.empty_cache() return em @@ -288,6 +299,17 @@ def embed( ------- self : graphistry instance """ + # this is temporary, will be fixed in future releases + try: + if isinstance(self._nodes, cudf.DataFrame): + self._nodes = self._nodes.to_pandas() + except: + pass + try: + if isinstance(self._edges, cudf.DataFrame): + self._edges = self._edges.to_pandas() + except: + pass if inplace: res = self else: @@ -404,25 +426,44 @@ def predict_links( where score >= threshold if anamalous if False else score <= threshold, or a dataframe """ - + logging.warning("currently `predict_links` is cpu only, gpu compatibility will be added in \ + future releases") all_nodes = self._node2id.values() all_relations = self._relation2id.values() if source is None: src = pd.Series(all_nodes) else: + # this is temporary, will be removed after gpu feature utils + try: + if isinstance(source, cudf.DataFrame): + source = source.to_pandas() # type: ignore + except: + pass src = pd.Series(source) src = src.map(self._node2id) if relation is None: rel = pd.Series(all_relations) else: + # this is temporary, will be removed after gpu feature utils + try: + if isinstance(relation, cudf.DataFrame): + relation = relation.to_pandas() # type: ignore + except: + pass rel = pd.Series(relation) rel = rel.map(self._relation2id) if destination is None: dst = pd.Series(all_nodes) else: + # this is temporary, will be removed after gpu feature utils + try: + if isinstance(destination, cudf.DataFrame): + destination = destination.to_pandas() # type: ignore + except: + pass dst = pd.Series(destination) dst = dst.map(self._node2id) diff --git a/graphistry/feature_utils.py b/graphistry/feature_utils.py index ba6227da29..2a60194ca2 100644 --- a/graphistry/feature_utils.py +++ b/graphistry/feature_utils.py @@ -3,6 +3,7 @@ import os import pandas as pd from time import time +from inspect import getmodule import warnings from functools import partial @@ -23,6 +24,7 @@ from . import constants as config from .PlotterBase import WeakValueDictionary, Plottable from .util import setup_logger, check_set_memoize +from .ai_utils import infer_graph, infer_self_graph # add this inside classes and have a method that can set log level logger = setup_logger(name=__name__, verbose=config.VERBOSE) @@ -47,6 +49,16 @@ SuperVectorizer = Any GapEncoder = Any SimilarityEncoder = Any + try: + from cu_cat import ( + SuperVectorizer, + GapEncoder, + SimilarityEncoder, + ) # type: ignore + except: + SuperVectorizer = Any + GapEncoder = Any + SimilarityEncoder = Any try: from sklearn.preprocessing import FunctionTransformer from sklearn.base import BaseEstimator, TransformerMixin @@ -54,6 +66,13 @@ FunctionTransformer = Any BaseEstimator = object TransformerMixin = object + # try: + # from cuml.preprocessing import FunctionTransformer + # from sklearn.base import BaseEstimator, TransformerMixin + # except: + # FunctionTransformer = Any + # BaseEstimator = object + # TransformerMixin = object else: MIXIN_BASE = object Pipeline = Any @@ -91,6 +110,28 @@ def lazy_import_has_min_dependancy(): except ModuleNotFoundError as e: return False, e +def lazy_import_has_cu_cat_dependancy(): + import warnings + warnings.filterwarnings("ignore") + try: + import scipy.sparse # noqa + from scipy import __version__ as scipy_version + from cu_cat import __version__ as cu_cat_version + import cu_cat + from sklearn import __version__ as sklearn_version + from cuml import __version__ as cuml_version + import cuml + from cudf import __version__ as cudf_version + import cudf + logger.debug(f"SCIPY VERSION: {scipy_version}") + logger.debug(f"Cuda CAT VERSION: {cu_cat_version}") + logger.debug(f"sklearn VERSION: {sklearn_version}") + logger.debug(f"cuml VERSION: {cuml_version}") + logger.debug(f"cudf VERSION: {cudf_version}") + + return True, 'ok', cudf + except ModuleNotFoundError as e: + return False, e, None def assert_imported_text(): has_dependancy_text_, import_text_exn, _ = lazy_import_has_dependancy_text() @@ -101,7 +142,6 @@ def assert_imported_text(): ) raise import_text_exn - def assert_imported(): has_min_dependancy_, import_min_exn = lazy_import_has_min_dependancy() if not has_min_dependancy_: @@ -110,7 +150,36 @@ def assert_imported(): "`pip install graphistry[ai]`" # noqa ) raise import_min_exn + +def assert_cuml_cucat(): + has_cuml_dependancy_, import_cuml_exn, cudf = lazy_import_has_cu_cat_dependancy() + if not has_cuml_dependancy_: + logger.error( # noqa + "cuml not found, trying running" # noqa + "`pip install rapids`" # noqa + ) + raise import_cuml_exn + +def make_safe_gpu_dataframes(X, y, engine): + + def safe_cudf(X, y): + new_kwargs = {} + kwargs = {'X': X, 'y': y} + for key, value in kwargs.items(): + if isinstance(value, cudf.DataFrame) and engine in ["pandas", "dirty_cat", "torch"]: + new_kwargs[key] = value.to_pandas() + elif isinstance(value, pd.DataFrame) and engine in ["cuml", "cu_cat"]: + new_kwargs[key] = cudf.from_pandas(value) + else: + new_kwargs[key] = value + return new_kwargs['X'], new_kwargs['y'] + has_cudf_dependancy_, _, cudf = lazy_import_has_cu_cat_dependancy() + if has_cudf_dependancy_: + print(f"Using GPU: {engine}") + return safe_cudf(X, y) + else: + return X, y # ############################################################################ # @@ -135,7 +204,8 @@ def assert_imported(): # # _featurize_or_get_edges_dataframe_if_X_is_None -FeatureEngineConcrete = Literal["none", "pandas", "dirty_cat", "torch"] + +FeatureEngineConcrete = Literal["none", "pandas", "dirty_cat", "torch", "cu_cat"] FeatureEngine = Literal[FeatureEngineConcrete, "auto"] @@ -143,13 +213,16 @@ def resolve_feature_engine( feature_engine: FeatureEngine, ) -> FeatureEngineConcrete: # noqa - if feature_engine in ["none", "pandas", "dirty_cat", "torch"]: + if feature_engine in ["none", "pandas", "dirty_cat", "torch", "cu_cat"]: return feature_engine # type: ignore if feature_engine == "auto": has_dependancy_text_, _, _ = lazy_import_has_dependancy_text() if has_dependancy_text_: return "torch" + has_cuml_dependancy_, _, cudf = lazy_import_has_cu_cat_dependancy() + if has_cuml_dependancy_: + return "cu_cat" has_min_dependancy_, _ = lazy_import_has_min_dependancy() if has_min_dependancy_: return "dirty_cat" @@ -157,7 +230,7 @@ def resolve_feature_engine( raise ValueError( # noqa f'feature_engine expected to be "none", ' - '"pandas", "dirty_cat", "torch", or "auto"' + '"pandas", "dirty_cat", "torch", "cu_cat", or "auto"' f'but received: {feature_engine} :: {type(feature_engine)}' ) @@ -167,8 +240,9 @@ def resolve_feature_engine( def resolve_y(df: Optional[pd.DataFrame], y: YSymbolic) -> pd.DataFrame: - if isinstance(y, pd.DataFrame): - return y + if isinstance(y, pd.DataFrame) or 'cudf.core.dataframe' in str(getmodule(y)): + + return y # type: ignore if df is None: raise ValueError("Missing data for featurization") @@ -188,9 +262,8 @@ def resolve_y(df: Optional[pd.DataFrame], y: YSymbolic) -> pd.DataFrame: def resolve_X(df: Optional[pd.DataFrame], X: XSymbolic) -> pd.DataFrame: - if isinstance(X, pd.DataFrame): - return X - + if isinstance(X, pd.DataFrame) or 'cudf.core.dataframe' in str(getmodule(X)): + return X # type: ignore if df is None: raise ValueError("Missing data for featurization") @@ -222,10 +295,7 @@ def safe_divide(a, b): def features_without_target( df: pd.DataFrame, y: Optional[Union[List, str, pd.DataFrame]] = None ) -> pd.DataFrame: - """ - Checks if y DataFrame column name is in df, and removes it - from df if so - ___________________________________________________________________ + """Checks if y DataFrame column name is in df, and removes it from df if so :param df: model DataFrame :param y: target DataFrame @@ -266,17 +336,15 @@ def remove_node_column_from_symbolic(X_symbolic, node): logger.info(f"Removing `{node}` from input X_symbolic list") X_symbolic.remove(node) return X_symbolic - if isinstance(X_symbolic, pd.DataFrame): + if isinstance(X_symbolic, pd.DataFrame) or 'cudf' in str(getmodule(X_symbolic)): logger.info(f"Removing `{node}` from input X_symbolic DataFrame") return X_symbolic.drop(columns=[node], errors="ignore") - def remove_internal_namespace_if_present(df: pd.DataFrame): """ Some tranformations below add columns to the DataFrame, this method removes them before featurization Will not drop if suffix is added during UMAP-ing - ______________________________________________________________ :param df: DataFrame :return: DataFrame with dropped columns in reserved namespace @@ -396,9 +464,8 @@ def is_dataframe_all_numeric(df: pd.DataFrame) -> bool: def find_bad_set_columns(df: pd.DataFrame, bad_set: List = ["[]"]): - """ - Finds columns that if not coerced to strings, will break processors. - ------------------------------------------------------------------------- + """Finds columns that if not coerced to strings, will break processors. + :param df: DataFrame :param bad_set: List of strings to look for. :return: list @@ -428,9 +495,7 @@ def check_if_textual_column( confidence: float = 0.35, min_words: float = 2.5, ) -> bool: - """ - Checks if `col` column of df is textual or not using basic heuristics - __________________________________________________________________________ + """Checks if `col` column of df is textual or not using basic heuristics :param df: DataFrame :param col: column name @@ -469,9 +534,7 @@ def check_if_textual_column( def get_textual_columns( df: pd.DataFrame, min_words: float = 2.5 ) -> List: - """ - Collects columns from df that it deems are textual. - _____________________________________________________________________ + """Collects columns from df that it deems are textual. :param df: DataFrame :return: list of columns names @@ -498,7 +561,6 @@ class Embedding: """ Generates random embeddings of a given dimension that aligns with the index of the dataframe - _____________________________________________________________________ """ def __init__(self, df: pd.DataFrame): @@ -536,14 +598,12 @@ def get_preprocessing_pipeline( encode: str = "ordinal", strategy: str = "quantile", ) -> Pipeline: # noqa - """ - Helper function for imputing and scaling np.ndarray data - using different scaling transformers. - ----------------------------------------------------------------- + """Helper function for imputing and scaling np.ndarray data using different scaling transformers. + :param X: np.ndarray :param impute: whether to run imputing or not :param use_scaler: string in None or - ["minmax", "quantile", "zscale", "robust", "kbins"], + ["minmax", "quantile", "standard", "robust", "kbins"], selects scaling transformer, default None :param n_quantiles: if use_scaler = 'quantile', sets the quantile bin size. @@ -563,16 +623,24 @@ def get_preprocessing_pipeline( KBinsDiscretizer, MinMaxScaler, MultiLabelBinarizer, - QuantileTransformer, + QuantileTransformer, RobustScaler, StandardScaler, ) + # from cuml.preprocessing import ( + # # FunctionTransformer, + # KBinsDiscretizer, + # MinMaxScaler, + # # QuantileTransformer, ## cuml 23 only + # RobustScaler, + # StandardScaler, + # ) from sklearn.pipeline import Pipeline from sklearn.impute import SimpleImputer available_preprocessors = [ "minmax", "quantile", - "zscale", + "standard", "robust", "kbins", ] @@ -599,7 +667,7 @@ def get_preprocessing_pipeline( scaler = QuantileTransformer( n_quantiles=n_quantiles, output_distribution=output_distribution ) - elif use_scaler == "zscale": + elif use_scaler == "standard": scaler = StandardScaler() elif use_scaler == "robust": scaler = RobustScaler(quantile_range=quantile_range) @@ -621,25 +689,28 @@ def get_preprocessing_pipeline( def fit_pipeline( X: pd.DataFrame, transformer, keep_n_decimals: int = 5 ) -> pd.DataFrame: - """ - Helper to fit DataFrame over transformer pipeline. - Rounds resulting matrix X by keep_n_digits if not 0, - which helps for when transformer pipeline is scaling or imputer - which sometime introduce small negative numbers, - and umap metrics like Hellinger need to be positive - :param X, DataFrame to transform. + """Helper to fit DataFrame over transformer pipeline. Rounds resulting matrix X by keep_n_digits if not 0, which helps for when transformer pipeline is scaling or imputer which sometime introduce small negative numbers, and umap metrics like Hellinger need to be positive + :param X: DataFrame to transform. :param transformer: Pipeline object to fit and transform - :param keep_n_decimals: Int of how many decimal places to keep in - rounded transformed data + :param keep_n_decimals: Int of how many decimal places to keep in rounded transformed data """ columns = X.columns index = X.index - - X = transformer.fit_transform(X) - if keep_n_decimals: - X = np.round(X, decimals=keep_n_decimals) # type: ignore # noqa - - return pd.DataFrame(X, columns=columns, index=index) + X_type = str(getmodule(X)) + if 'cudf' not in X_type: + X = transformer.fit_transform(X) + if keep_n_decimals: + X = np.round(X, decimals=keep_n_decimals) # type: ignore # noqa + X = pd.DataFrame(X, columns=columns, index=index) + else: + X = transformer.fit_transform(X.to_numpy()) + if keep_n_decimals: + X = np.round(X, decimals=keep_n_decimals) # type: ignore # noqa + # import cudf + # assert_cuml_cucat() + _, _, cudf = lazy_import_has_cu_cat_dependancy() + X = cudf.DataFrame(X, columns=columns, index=index) + return X def impute_and_scale_df( @@ -794,8 +865,8 @@ def encoder(X, use_scaler): # noqa: E301 def get_cardinality_ratio(df: pd.DataFrame): - """Calculates ratio of unique values to total number of rows of DataFrame - ------------------------------------------------------------------------- + """Calculates the ratio of unique values to total number of rows of DataFrame + :param df: DataFrame """ ratios = {} @@ -864,6 +935,7 @@ def process_dirty_dataframes( similarity: Optional[str] = None, # "ngram", categories: Optional[str] = "auto", multilabel: bool = False, + feature_engine: Optional[str] = "dirty_cat", ) -> Tuple[ pd.DataFrame, Optional[pd.DataFrame], @@ -873,8 +945,7 @@ def process_dirty_dataframes( """ Dirty_Cat encoder for record level data. Will automatically turn inhomogeneous dataframe into matrix using smart conversion tricks. - ______________________________________________________________________ - + :param ndf: node DataFrame :param y: target DataFrame or series :param cardinality_threshold: For ndf columns, below this threshold, @@ -883,17 +954,22 @@ def process_dirty_dataframes( threshold, encoder is OneHot, above, it is GapEncoder :param n_topics: number of topics for GapEncoder, default 42 :param use_scaler: None or string in - ['minmax', 'zscale', 'robust', 'quantile'] + ['minmax', 'standard', 'robust', 'quantile'] :param similarity: one of 'ngram', 'levenshtein-ratio', 'jaro', or'jaro-winkler'}) – The type of pairwise string similarity to use. If None or False, uses a SuperVectorizer :return: Encoded data matrix and target (if not None), the data encoder, and the label encoder. """ - from dirty_cat import SuperVectorizer, GapEncoder, SimilarityEncoder - from sklearn.preprocessing import FunctionTransformer + if feature_engine != 'cu_cat': + from dirty_cat import SuperVectorizer, GapEncoder, SimilarityEncoder + from sklearn.preprocessing import FunctionTransformer + elif feature_engine == 'cu_cat': + lazy_import_has_cu_cat_dependancy() # tried to use this rather than importing below + from cu_cat import SuperVectorizer, GapEncoder, SimilarityEncoder + from cuml.preprocessing import FunctionTransformer t = time() - + if not is_dataframe_all_numeric(ndf): data_encoder = SuperVectorizer( auto_cast=True, @@ -906,7 +982,6 @@ def process_dirty_dataframes( ) logger.info(":: Encoding DataFrame might take a few minutes ------") - X_enc = data_encoder.fit_transform(ndf, y) X_enc = make_array(X_enc) @@ -929,11 +1004,17 @@ def process_dirty_dataframes( # now just set the feature names, since dirty cat changes them in # a weird way... data_encoder.get_feature_names_out = callThrough(features_transformed) - - X_enc = pd.DataFrame( - X_enc, columns=features_transformed, index=ndf.index - ) - X_enc = X_enc.fillna(0.0) + if 'cudf' not in str(getmodule(ndf)): + X_enc = pd.DataFrame( + X_enc, columns=features_transformed, index=ndf.index + ) + X_enc = X_enc.fillna(0.0) # TODO -- this is a hack in cuml version + else: + # X_enc = cudf.DataFrame.from_arrow(X_enc) + X_enc.index = ndf.index + X_enc.columns = np.array(features_transformed) + X_enc = X_enc.fillna(0.0) + else: logger.info("-*-*- DataFrame is completely numeric") X_enc, _, data_encoder, _ = get_numeric_transformers(ndf, None) @@ -1024,6 +1105,8 @@ def process_nodes_dataframes( feature_engine: FeatureEngineConcrete = "pandas" # test_size: Optional[bool] = None, ) -> Tuple[ + pd.DataFrame, + Any, pd.DataFrame, Any, SuperVectorizer, @@ -1033,15 +1116,12 @@ def process_nodes_dataframes( Any, List[str], ]: - """ - Automatic Deep Learning Embedding/ngrams of Textual Features, - with the rest of the columns taken care of by dirty_cat - _________________________________________________________________________ + """Automatic Deep Learning Embedding/ngrams of Textual Features, with the rest of the columns taken care of by dirty_cat :param df: pandas DataFrame of data :param y: pandas DataFrame of targets :param use_scaler: None or string in - ['minmax', 'zscale', 'robust', 'quantile'] + ['minmax', 'standard', 'robust', 'quantile'] :param n_topics: number of topics in Gap Encoder :param use_scaler: :param confidence: Number between 0 and 1, will pass @@ -1055,6 +1135,7 @@ def process_nodes_dataframes( :param model_name: SentenceTransformer model name. See available list at https://www.sbert.net/docs/pretrained_models. html#sentence-embedding-models + :return: X_enc, y_enc, data_encoder, label_encoder, scaling_pipeline, scaling_pipeline_target, @@ -1067,7 +1148,7 @@ def process_nodes_dataframes( X_enc, y_enc, data_encoder, label_encoder = get_numeric_transformers( df, y ) - X_enc, y_enc, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa + X_encs, y_encs, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa X_enc, y_enc, use_scaler, @@ -1089,6 +1170,8 @@ def process_nodes_dataframes( return ( X_enc, y_enc, + X_encs, + y_encs, data_encoder, label_encoder, scaling_pipeline, @@ -1132,7 +1215,8 @@ def process_nodes_dataframes( n_topics_target=n_topics_target, similarity=similarity, categories=categories, - multilabel=multilabel + multilabel=multilabel, + feature_engine=feature_engine, ) if embedding: @@ -1153,8 +1237,7 @@ def process_nodes_dataframes( logger.debug( f"--The entire Encoding process took {(time()-t)/60:.2f} minutes" ) - - X_enc, y_enc, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa + X_encs, y_encs, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa X_enc, y_enc, use_scaler, @@ -1168,10 +1251,11 @@ def process_nodes_dataframes( strategy=strategy, keep_n_decimals=keep_n_decimals, ) - return ( X_enc, y_enc, + X_encs, + y_encs, data_encoder, label_encoder, scaling_pipeline, @@ -1183,7 +1267,7 @@ class FastMLB: def __init__(self, mlb, in_column, out_columns): if isinstance(in_column, str): in_column = [in_column] - self.columns = in_column # should be singe entry list ['cats'] + self.columns = in_column # should be single entry list ['cats'] self.mlb = mlb self.out_columns = out_columns self.feature_names_in_ = in_column @@ -1241,28 +1325,43 @@ def encode_edges(edf, src, dst, mlb, fit=False): edf (pd.DataFrame): edge dataframe src (string): source column dst (string): destination column - mlb (sklearn): multilabelBinarizer - fit (bool, optional): If true, fits multilabelBinarizer. - Defaults to False. - Returns: - tuple: pd.DataFrame, multilabelBinarizer + mlb (sklearn): multilabelBinarizer ##not in cuml yet so cast down to pandas + fit (bool, optional): If true, fits multilabelBinarizer. Defaults to False. + + :Returns: tuple: pd.DataFrame, multilabelBinarizer """ # uses mlb with fit=T/F so we can use it in transform mode # to recreate edge feature concat definition + + logger.debug("Encoding Edges using MultiLabelBinarizer") + edf_type = str(getmodule(edf)) source = edf[src] destination = edf[dst] - logger.debug("Encoding Edges using MultiLabelBinarizer") - if fit: + source_dtype = str(getmodule(source)) + + if fit and 'cudf' not in source_dtype: T = mlb.fit_transform(zip(source, destination)) - else: + elif fit and 'cudf' in source_dtype: + T = mlb.fit_transform(zip(source.to_pandas(), destination.to_pandas())) + elif not fit and 'cudf' not in source_dtype: T = mlb.transform(zip(source, destination)) + elif not fit and 'cudf' in source_dtype: + T = mlb.transform(zip(source.to_pandas(), destination.to_pandas())) + T = 1.0 * T # coerce to float columns = [ str(k) for k in mlb.classes_ ] # stringify the column names or scikits.base throws error mlb.get_feature_names_out = callThrough(columns) mlb.columns_ = [src, dst] - T = pd.DataFrame(T, columns=columns, index=edf.index) + if 'cudf' in edf_type: + # lazy_import_has_cu_cat_dependancy() + # import cudf + # assert_cuml_cucat() + _, _, cudf = lazy_import_has_cu_cat_dependancy() + T = cudf.DataFrame(T, columns=columns, index=edf.index) + else: + T = pd.DataFrame(T, columns=columns, index=edf.index) logger.info(f"Shape of Edge Encoding: {T.shape}") return T, mlb @@ -1273,7 +1372,7 @@ def process_edge_dataframes( src: str, dst: str, cardinality_threshold: int = 40, - cardinality_threshold_target: int = 100, + cardinality_threshold_target: int = 400, n_topics: int = config.N_TOPICS_DEFAULT, n_topics_target: int = config.N_TOPICS_TARGET_DEFAULT, use_scaler: Optional[str] = None, @@ -1283,7 +1382,6 @@ def process_edge_dataframes( ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - #confidence: float = 0.35, min_words: float = 2.5, model_name: str = "paraphrase-MiniLM-L6-v2", similarity: Optional[str] = None, @@ -1298,6 +1396,8 @@ def process_edge_dataframes( keep_n_decimals: int = 5, feature_engine: FeatureEngineConcrete = "pandas", ) -> Tuple[ + pd.DataFrame, + pd.DataFrame, pd.DataFrame, pd.DataFrame, List[Any], @@ -1319,9 +1419,9 @@ def process_edge_dataframes( :param src: source column to select in edf :param dst: destination column to select in edf :param use_scaler: None or string in - ['minmax', 'zscale', 'robust', 'quantile'] - :return: Encoded data matrix and target (if not None), - the data encoders, and the label encoder. + ['minmax', 'standard', 'robust', 'quantile'] + + :return: Encoded data matrix and target (if not None), the data encoders, and the label encoder. """ lazy_import_has_min_dependancy() from sklearn.preprocessing import ( @@ -1334,6 +1434,9 @@ def process_edge_dataframes( MultiLabelBinarizer() ) # create new one so we can use encode_edges later in # transform with fit=False + _, _, cudf = lazy_import_has_cu_cat_dependancy() + # assert_cuml_cucat() + T, mlb_pairwise_edge_encoder = encode_edges( edf, src, dst, mlb_pairwise_edge_encoder, fit=True ) @@ -1354,7 +1457,7 @@ def process_edge_dataframes( # add the two datasets together X_enc = pd.concat([T, X_enc], axis=1) # then scale them - X_enc, y_enc, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa + X_encs, y_encs, scaling_pipeline, scaling_pipeline_target = smart_scaler( # noqa X_enc, y_enc, use_scaler, @@ -1374,6 +1477,8 @@ def process_edge_dataframes( return ( X_enc, y_enc, + X_encs, + y_encs, [mlb_pairwise_edge_encoder, data_encoder], label_encoder, scaling_pipeline, @@ -1385,6 +1490,8 @@ def process_edge_dataframes( ( X_enc, y_enc, + _, + _, data_encoder, label_encoder, _, @@ -1415,7 +1522,11 @@ def process_edge_dataframes( if not X_enc.empty and not T.empty: logger.debug("-" * 60) logger.debug("<= Found Edges and Dirty_cat encoding =>") - X_enc = pd.concat([T, X_enc], axis=1) + T_type = str(getmodule(T)) + if 'cudf' not in T_type: + X_enc = pd.concat([T, X_enc], axis=1) + else: + X_enc = cudf.concat([T, X_enc], axis=1) elif not T.empty and X_enc.empty: logger.debug("-" * 60) logger.debug("<= Found only Edges =>") @@ -1426,7 +1537,7 @@ def process_edge_dataframes( f" {(time()-t)/60:.2f} minutes" ) - X_enc, y_enc, scaling_pipeline, scaling_pipeline_target = smart_scaler( + X_encs, y_encs, scaling_pipeline, scaling_pipeline_target = smart_scaler( X_enc, y_enc, use_scaler, @@ -1444,6 +1555,8 @@ def process_edge_dataframes( res = ( X_enc, y_enc, + X_encs, + y_encs, [mlb_pairwise_edge_encoder, data_encoder], label_encoder, scaling_pipeline, @@ -1501,22 +1614,23 @@ def transform_dirty( data_encoder: Union[SuperVectorizer, FunctionTransformer], # type: ignore name: str = "", ) -> pd.DataFrame: - from sklearn.preprocessing import MultiLabelBinarizer + # from sklearn.preprocessing import MultiLabelBinarizer logger.debug(f"-{name} Encoder:") logger.debug(f"\t{data_encoder}\n") # print(f"-{name} Encoder:") # print(f"\t{data_encoder}\n") - try: - logger.debug(f"{data_encoder.get_feature_names_in}") - except Exception as e: - logger.warning(e) - pass + # try: + # logger.debug(f"{data_encoder.get_feature_names_in}") + # except Exception as e: + # logger.warning(e) + # pass logger.debug(f"TRANSFORM pre as df -- \t{df.shape}") # ##################################### for dirty_cat 0.3.0 use_columns = getattr(data_encoder, 'columns_', []) if len(use_columns): - X = data_encoder.transform(df[use_columns]) + #print(f"Using columns: {use_columns}") + X = data_encoder.transform(df[df.columns.intersection(use_columns)]) # ##################################### with dirty_cat 0.2.0 else: X = data_encoder.transform(df) @@ -1544,20 +1658,21 @@ def transform( # this function aligns with what is computed during # processing nodes or edges. ( - X_enc, - y_enc, + _, + _, + _, + _, data_encoder, label_encoder, - scaling_pipeline, - scaling_pipeline_target, + _, + _, text_model, text_cols, ) = res - # feature_columns = X_enc.columns - # feature_columns_target = y_enc.columns logger.info("-" * 90) - + + # index = df.index y = pd.DataFrame([]) T = pd.DataFrame([]) # encode nodes @@ -1613,14 +1728,14 @@ def transform( logger.info(f"--Features matrix shape: {X.shape}") logger.info(f"--Target matrix shape: {y.shape}") - if scaling_pipeline and not X.empty: - logger.info("--Scaling Features") - X = pd.DataFrame(scaling_pipeline.transform(X), columns=X.columns) - if scaling_pipeline_target and not y.empty: - logger.info(f"--Scaling Target {scaling_pipeline_target}") - y = pd.DataFrame( - scaling_pipeline_target.transform(y), columns=y.columns - ) + # if scaling_pipeline and not X.empty: + # logger.info("--Scaling Features") + # X = pd.DataFrame(scaling_pipeline.transform(X), columns=X.columns, index=index) + # if scaling_pipeline_target and not y.empty: + # logger.info(f"--Scaling Target {scaling_pipeline_target}") + # y = pd.DataFrame( + # scaling_pipeline_target.transform(y), columns=y.columns, index=index + # ) return X, y @@ -1665,7 +1780,6 @@ def _hecho(self, res): logger.info("\n-- Setting Encoder Parts from Fit ::") logger.info(f'Feature Columns In: {self.feature_names_in}') logger.info(f'Target Columns In: {self.target_names_in}') - for name, value in zip(self.res_names, res): if name not in ["X_enc", "y_enc"]: logger.info("-" * 90) @@ -1676,6 +1790,8 @@ def _set_result(self, res): [ X_enc, y_enc, + X_encs, + y_encs, data_encoder, label_encoder, scaling_pipeline, @@ -1689,8 +1805,10 @@ def _set_result(self, res): # label_encoder.target_names_in = self.target_names_in self.feature_columns = X_enc.columns self.feature_columns_target = y_enc.columns - self.X = X_enc - self.y = y_enc + self.X = X_encs + self.y = y_encs + self.X_orignal = X_enc + self.y_orignal = y_enc self.data_encoder = data_encoder # is list for edges self.label_encoder = label_encoder self.scaling_pipeline = scaling_pipeline @@ -1707,40 +1825,67 @@ def fit(self, src=None, dst=None, *args, **kwargs): self._set_result(res) def transform(self, df, ydf=None): + "Raw transform, no scaling." + X, y = transform(df, ydf, self.res, self.kind, self.src, self.dst) + return X, y + + def _transform_scaled(self, df, ydf, scaling_pipeline, scaling_pipeline_target): + """Transform with scaling fit durning fit.""" X, y = transform(df, ydf, self.res, self.kind, self.src, self.dst) + if scaling_pipeline is not None and not X.empty: + X = pd.DataFrame(scaling_pipeline.transform(X), columns=X.columns, index=X.index) + if scaling_pipeline_target is not None and y is not None and not y.empty: + y = pd.DataFrame(scaling_pipeline_target.transform(y), columns=y.columns, index=y.index) return X, y + + def transform_scaled(self, df, ydf=None, scaling_pipeline=None, scaling_pipeline_target=None): + if scaling_pipeline is None: + scaling_pipeline = self.scaling_pipeline + if scaling_pipeline_target is None: + scaling_pipeline_target = self.scaling_pipeline_target + return self._transform_scaled(df, ydf, scaling_pipeline, scaling_pipeline_target) def fit_transform(self, src=None, dst=None, *args, **kwargs): self.fit(src=src, dst=dst, *args, **kwargs) return self.X, self.y - def scale(self, df, ydf=None, set_scaler=False, *args, **kwargs): - # pretty hacky but gets job done -- - """Fits new scaling functions on df, ydf via args-kwargs - (ie use downstream as X_train, X_test ,... or batch - when different scaling on the outputs is required) + def scale(self, X=None, y=None, return_pipeline=False, *args, **kwargs): + """Fits new scaling functions on df, y via args-kwargs + + **Example:** + :: + + from graphisty.features import SCALERS, SCALER_OPTIONS + print(SCALERS) + g = graphistry.nodes(df) + # set a scaling strategy for features and targets -- umap uses those and produces different results depending. + g2 = g.umap(use_scaler='standard', use_scaler_target=None) + + # later if you want to scale new data, you can do so + X, y = g2.transform(df, df, scaled=False) # unscaled transformer output + # now scale with new settings + X_scaled, y_scaled = g2.scale(X, y, use_scaler='minmax', use_scaler_target='kbins', n_bins=5) + # fit some other pipeline + clf.fit(X_scaled, y_scaled) + + args: + :: + + ;X: pd.DataFrame of features + :y: pd.DataFrame of target features + :kind: str, one of 'nodes' or 'edges' + *args, **kwargs: passed to smart_scaler pipeline + + returns: + scaled X, y """ - # pop off the previous scaler so that .transform won't use it - self.res[4] = None - self.res[5] = None - - X, y = self.transform(df, ydf) # these are the raw transforms, logger.info("-Fitting new scaler on raw features") X, y, scaling_pipeline, scaling_pipeline_target = smart_scaler( X_enc=X, y_enc=y, *args, **kwargs ) - - if set_scaler: - logger.info("--Setting fit scaler to self") - self.res[4] = scaling_pipeline - self.res[5] = scaling_pipeline_target - self.scaling_pipeline = scaling_pipeline - self.scaling_pipeline_target = scaling_pipeline_target - else: # add the original back - self.res[4] = self.scaling_pipeline - self.res[5] = self.scaling_pipeline_target - - return X, y, scaling_pipeline, scaling_pipeline_target + if return_pipeline: + return X, y, scaling_pipeline, scaling_pipeline_target + return X, y # ###################################################################################################################### @@ -1753,9 +1898,7 @@ def scale(self, df, ydf=None, set_scaler=False, *args, **kwargs): def prune_weighted_edges_df_and_relabel_nodes( wdf: pd.DataFrame, scale: float = 0.1, index_to_nodes_dict: Optional[Dict] = None ) -> pd.DataFrame: - """ - Prune the weighted edge DataFrame so to return high - fidelity similarity scores. + """Prune the weighted edge DataFrame so to return high fidelity similarity scores. :param wdf: weighted edge DataFrame gotten via UMAP :param scale: lower values means less edges > (max - scale * std) @@ -1815,21 +1958,40 @@ def reuse_featurization( memoize=memoize, ) +def get_matrix_by_column_part(X: pd.DataFrame, column_part: str) -> pd.DataFrame: + """Get the feature matrix by column part existing in column names.""" + transformed_columns = X.columns[X.columns.map(lambda x: True if column_part in x else False)] # type: ignore + return X[transformed_columns] + +def get_matrix_by_column_parts(X: pd.DataFrame, column_parts: Optional[Union[list, str]]) -> pd.DataFrame: + """Get the feature matrix by column parts list existing in column names.""" + if column_parts is None: + return X + if isinstance(column_parts, str): + column_parts = [column_parts] + res = pd.concat([get_matrix_by_column_part(X, column_part) for column_part in column_parts], axis=1) # type: ignore + res = res.loc[:, ~res.columns.duplicated()] # type: ignore + return res + class FeatureMixin(MIXIN_BASE): - """ - FeatureMixin for automatic featurization of nodes and edges DataFrames. - Subclasses UMAPMixin for umap-ing of automatic features. + """FeatureMixin for automatic featurization of nodes and edges DataFrames. Subclasses UMAPMixin for umap-ing of automatic features. Usage: + :: + g = graphistry.nodes(df, 'node_column') g2 = g.featurize() or for edges, + :: + g = graphistry.edges(df, 'src', 'dst') g2 = g.featurize(kind='edges') - or chain them, + or chain them for both nodes and edges, + :: + g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node_column') g2 = g.featurize().featurize(kind='edges') @@ -1842,25 +2004,25 @@ def __init__(self, *args, **kwargs): pass def _get_feature(self, kind): - kind = kind.replace('s', '') - assert kind in ['node', 'edge'], f'kind needs to be in `nodes` or `edges`, found {kind}' - x = getattr(self, f'_{kind}_features') + kind2 = kind.replace('s', '') + assert kind2 in ['node', 'edge'], f'kind needs to be in `nodes` or `edges`, found {kind}' + x = getattr(self, f'_{kind2}_features') return x def _get_target(self, kind): - kind = kind.replace('s', '') - assert kind in ['node', 'edge'], f'kind needs to be in `nodes` or `edges`, found {kind}' - x = getattr(self, f'_{kind}_target') + kind2 = kind.replace('s', '') + assert kind2 in ['node', 'edge'], f'kind needs to be in `nodes` or `edges`, found {kind}' + x = getattr(self, f'_{kind2}_target') return x def _featurize_nodes( self, X: XSymbolic = None, y: YSymbolic = None, - use_scaler: Optional[str] = "zscale", - use_scaler_target: Optional[str] = "kbins", + use_scaler: Optional[str] = None, + use_scaler_target: Optional[str] = None, cardinality_threshold: int = 40, - cardinality_threshold_target: int = 120, + cardinality_threshold_target: int = 400, n_topics: int = config.N_TOPICS_DEFAULT, n_topics_target: int = config.N_TOPICS_TARGET_DEFAULT, multilabel: bool = False, @@ -1869,7 +2031,6 @@ def _featurize_nodes( ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - #confidence: float = 0.35, min_words: float = 2.5, model_name: str = "paraphrase-MiniLM-L6-v2", similarity: Optional[str] = None, @@ -1885,15 +2046,19 @@ def _featurize_nodes( remove_node_column: bool = True, feature_engine: FeatureEngineConcrete = "pandas", memoize: bool = True, + verbose: bool = False, ): - res = self.copy() + res = self.copy() ndf = res._nodes node = res._node - + # print(['ndf:',ndf]) + # print(['X:',X]) + # print(['node:',res._node]) + if remove_node_column: ndf = remove_node_column_from_symbolic(ndf, node) X = remove_node_column_from_symbolic(X, node) - + if ndf is None: logger.info( "! Materializing Nodes and setting `embedding=True`" @@ -1913,9 +2078,14 @@ def _featurize_nodes( X_resolved = resolve_X(ndf, X) y_resolved = resolve_y(ndf, y) - feature_engine = resolve_feature_engine(feature_engine) + X_resolved, y_resolved = make_safe_gpu_dataframes(X_resolved, y_resolved, engine=feature_engine) - fkwargs = dict( + #feature_engine = resolve_feature_engine(feature_engine) + res.feature_engine = feature_engine + + from .features import ModelDict + + fkwargs = ModelDict("Featurize Params", X=X_resolved, y=y_resolved, use_scaler=use_scaler, @@ -1930,7 +2100,6 @@ def _featurize_nodes( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, min_words=min_words, model_name=model_name, similarity=similarity, @@ -1954,6 +2123,7 @@ def _featurize_nodes( old_res = reuse_featurization(res, memoize, fkwargs) if old_res: + print("--- [[ RE-USING NODE FEATURIZATION ]]") if verbose else None logger.info("--- [[ RE-USING NODE FEATURIZATION ]]") fresh_res = copy.copy(res) for attr in ["_node_features", "_node_target", "_node_encoder"]: @@ -1965,21 +2135,24 @@ def _featurize_nodes( X_resolved = remove_internal_namespace_if_present(X_resolved) keys_to_remove = ["X", "y", "remove_node_column"] - nfkwargs = {} + nfkwargs = dict() for key, value in fkwargs.items(): if key not in keys_to_remove: nfkwargs[key] = value - ############################################################# + print('-' * 80) if verbose else None + print("** Featuring nodes") if verbose else None + # ############################################################ encoder = FastEncoder(X_resolved, y_resolved, kind="nodes") encoder.fit(**nfkwargs) - ############################################################ + # ########################################################### # if changing, also update fresh_res res._node_features = encoder.X + res._node_features_raw = encoder.X_orignal # .copy() res._node_target = encoder.y + res._node_target_raw = encoder.y_orignal # .copy() res._node_encoder = encoder # now this does - # all the work `._node_encoder.transform(df, y)` etc return res @@ -1988,17 +2161,16 @@ def _featurize_edges( self, X: XSymbolic = None, y: YSymbolic = None, - use_scaler: Optional[str] = "zscale", - use_scaler_target: Optional[str] = "kbins", + use_scaler: Optional[str] = None, + use_scaler_target: Optional[str] = None, cardinality_threshold: int = 40, - cardinality_threshold_target: int = 20, + cardinality_threshold_target: int = 400, n_topics: int = config.N_TOPICS_DEFAULT, n_topics_target: int = config.N_TOPICS_TARGET_DEFAULT, use_ngrams: bool = False, ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - #confidence: float = 0.35, min_words: float = 2.5, multilabel: bool = False, model_name: str = "paraphrase-MiniLM-L6-v2", @@ -2014,6 +2186,7 @@ def _featurize_edges( keep_n_decimals: int = 5, feature_engine: FeatureEngineConcrete = "pandas", memoize: bool = True, + verbose: bool = False, ): res = self.copy() @@ -2032,6 +2205,11 @@ def _featurize_edges( **{res._destination: res._edges[res._destination]} ) + res.feature_engine = feature_engine + + X_resolved, y_resolved = make_safe_gpu_dataframes(X_resolved, y_resolved, engine=feature_engine) + + # now that everything is set fkwargs = dict( X=X_resolved, @@ -2046,7 +2224,6 @@ def _featurize_edges( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, min_words=min_words, model_name=model_name, similarity=similarity, @@ -2063,6 +2240,7 @@ def _featurize_edges( feature_engine=feature_engine, ) + res._feature_params = { **getattr(res, "_feature_params", {}), "edges": fkwargs, @@ -2088,6 +2266,7 @@ def _featurize_edges( if key not in keys_to_remove: nfkwargs[key] = value + print("** Featuring edges") if verbose else None ############################################################### encoder = FastEncoder(X_resolved, y_resolved, kind="edges") encoder.fit(src=res._source, dst=res._destination, **nfkwargs) @@ -2095,13 +2274,30 @@ def _featurize_edges( # if editing, should also update fresh_res res._edge_features = encoder.X + res._edge_features_raw = encoder.X_orignal # .copy() res._edge_target = encoder.y + res._edge_target_raw = encoder.y_orignal # .copy() res._edge_encoder = encoder return res + + def _infer_edges(self, emb, X, y, df, eps='auto', n_neighbors=4, sample=None, infer_on_umap_embedding=False, + verbose=False, merge_policy=False, **kwargs): + res = self.bind() + if merge_policy: + # useful to cluster onto existing graph + g = infer_graph(res, emb, X, y, df, infer_on_umap_embedding=infer_on_umap_embedding, + n_neighbors=n_neighbors, eps=eps, sample=sample, verbose=verbose, **kwargs) + else: + # useful to cluster onto self + g = infer_self_graph(res, emb, X, y, df, infer_on_umap_embedding=infer_on_umap_embedding, + n_neighbors=n_neighbors, eps=eps, verbose=verbose, **kwargs) + return g - def _transform(self, encoder: str, df: pd.DataFrame, ydf: pd.DataFrame): + def _transform(self, encoder: str, df: pd.DataFrame, ydf: Optional[pd.DataFrame], scaled): if getattr(self, encoder) is not None: + if scaled: + return getattr(self, encoder).transform_scaled(df, ydf) return getattr(self, encoder).transform(df, ydf) else: logger.debug( @@ -2109,45 +2305,126 @@ def _transform(self, encoder: str, df: pd.DataFrame, ydf: pd.DataFrame): "before being able to transform data" ) - def transform(self, df, ydf, kind): - """Transform new data""" + def transform(self, df: pd.DataFrame, + y: Optional[pd.DataFrame] = None, + kind: str = 'nodes', + min_dist: Union[str, float, int] = 'auto', + n_neighbors: int = 7, + merge_policy: bool = False, + sample: Optional[int] = None, + return_graph: bool = True, + scaled: bool = True, + verbose: bool = False): + """Transform new data and append to existing graph, or return dataframes + + **args:** + + :df: pd.DataFrame, raw data to transform + :ydf: pd.DataFrame, optional + :kind: str # one of `nodes`, `edges` + :return_graph: bool, if True, will return a graph with inferred edges. + :merge_policy: bool, if True, adds batch to existing graph nodes via nearest neighbors. If False, will infer edges only between nodes in the batch, default False + :min_dist: float, if return_graph is True, will use this value in NN search, or 'auto' to infer a good value. min_dist represents the maximum distance between two samples for one to be considered as in the neighborhood of the other. + :sample: int, if return_graph is True, will use sample edges of existing graph to fill out the new graph + :n_neighbors: int, if return_graph is True, will use this value for n_neighbors in Nearest Neighbors search + :scaled: bool, if True, will use scaled transformation of data set during featurization, default True + :verbose: bool, if True, will print metadata about the graph construction, default False + + **Returns:** + + X, y: pd.DataFrame, transformed data if return_graph is False + or a graphistry Plottable with inferred edges if return_graph is True + """ if kind == "nodes": - return self._transform("_node_encoder", df, ydf) + X, y_ = self._transform("_node_encoder", df, y, scaled=scaled) elif kind == "edges": - return self._transform("_edge_encoder", df, ydf) + X, y_ = self._transform("_edge_encoder", df, y, scaled=scaled) else: logger.debug("kind must be one of `nodes`," f"`edges`, found {kind}") + + if return_graph and kind not in ["edges"]: + emb = None # will not be able to infer graph from umap coordinates, + # but will be able to infer graph from features of existing edges + g = self._infer_edges(emb, X, y_, df, eps=min_dist, sample=sample, n_neighbors=n_neighbors, + infer_on_umap_embedding=False, merge_policy=merge_policy, + verbose=verbose) + return g + return X, y_ def scale( self, - df, - ydf, - kind, - use_scaler, - use_scaler_target, - set_scaler=False, + df: Optional[pd.DataFrame] = None, + y: Optional[pd.DataFrame] = None, + kind: str = "nodes", + use_scaler: Union[str, None] = None, + use_scaler_target: Union[str, None] = None, impute: bool = True, n_quantiles: int = 10, output_distribution: str = "normal", quantile_range=(25, 75), - n_bins: int = 2, + n_bins: int = 10, encode: str = "ordinal", strategy: str = "uniform", keep_n_decimals: int = 5, + return_scalers: bool = False, ): + """Scale data using the same scalers as used in the featurization step. + + **Example** + :: + + g = graphistry.nodes(df) + X, y = g.featurize().scale(kind='nodes', use_scaler='robust', use_scaler_target='kbins', n_bins=3) + + # or + g = graphistry.nodes(df) + # set a scaling strategy for features and targets -- umap uses those and produces different results depending. + g2 = g.umap(use_scaler='standard', use_scaler_target=None) + + # later if you want to scale new data, you can do so + X, y = g2.transform(df, df, scale=False) + X_scaled, y_scaled = g2.scale(X, y, use_scaler='minmax', use_scaler_target='kbins', n_bins=5) + # fit some other pipeline + clf.fit(X_scaled, y_scaled) + + **Args:** + + :df: pd.DataFrame, raw data to transform, if None, will use data from featurization fit + :y: pd.DataFrame, optional target data + :kind: str, one of `nodes`, `edges` + :use_scaler: str, optional, one of `minmax`, `robust`, `standard`, `kbins`, `quantile` + :use_scaler_target: str, optional, one of `minmax`, `robust`, `standard`, `kbins`, `quantile` + :impute: bool, if True, will impute missing values + :n_quantiles: int, number of quantiles to use for quantile scaler + :output_distribution: str, one of `normal`, `uniform`, `lognormal` + :quantile_range: tuple, range of quantiles to use for quantile scaler + :n_bins: int, number of bins to use for KBinsDiscretizer + :encode: str, one of `ordinal`, `onehot`, `onehot-dense`, `binary` + :strategy: str, one of `uniform`, `quantile`, `kmeans` + :keep_n_decimals: int, number of decimals to keep after scaling + :return_scalers: bool, if True, will return the scalers used to scale the data + + **Returns:** + + (X, y) transformed data if return_graph is False or a graph with inferred edges if return_graph is True, or (X, y, scaler, scaler_target) if return_scalers is True + """ + + if df is None: # use the original data + X, y = (self._node_features_raw, self._node_target_raw) if kind == "nodes" else (self._edge_features_raw, self._edge_target_raw) # type: ignore + else: + X, y = self.transform(df, y, kind=kind, return_graph=False, scaled=False) if kind == "nodes" and hasattr(self, "_node_encoder"): # type: ignore if self._node_encoder is not None: # type: ignore ( X, y, - scaling_pipeline, - scaling_pipeline_target, + scaler, + scaler_target ) = self._node_encoder.scale( - df, - ydf, - set_scaler=set_scaler, + X, + y, use_scaler=use_scaler, use_scaler_target=use_scaler_target, impute=impute, @@ -2158,6 +2435,7 @@ def scale( encode=encode, strategy=strategy, keep_n_decimals=keep_n_decimals, + return_pipeline=True ) # type: ignore else: raise AttributeError( @@ -2171,12 +2449,11 @@ def scale( ( X, y, - scaling_pipeline, - scaling_pipeline_target, + scaler, + scaler_target ) = self._edge_encoder.scale( - df, - ydf, - set_scaler=set_scaler, + X, + y, use_scaler=use_scaler, use_scaler_target=use_scaler_target, impute=impute, @@ -2187,14 +2464,17 @@ def scale( encode=encode, strategy=strategy, keep_n_decimals=keep_n_decimals, + return_pipeline=True ) # type: ignore else: raise AttributeError( 'Please run g.featurize(kind="edges", *args, **kwargs) ' 'first before scaling matrices and targets is possible.' ) + if return_scalers: + return X, y, scaler, scaler_target + return X, y - return X, y, scaling_pipeline, scaling_pipeline_target def featurize( self, @@ -2213,29 +2493,29 @@ def featurize( ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - min_words: float = 2.5, + min_words: float = 4.5, model_name: str = "paraphrase-MiniLM-L6-v2", impute: bool = True, n_quantiles: int = 100, output_distribution: str = "normal", - quantile_range=(25, 75), + quantile_range = (25, 75), n_bins: int = 10, encode: str = "ordinal", strategy: str = "uniform", - similarity: Optional[ - str - ] = None, # turn this off in favor of Gap Encoder + similarity: Optional[str] = None, # turn this off in favor of Gap Encoder categories: Optional[str] = "auto", keep_n_decimals: int = 5, remove_node_column: bool = True, inplace: bool = False, feature_engine: FeatureEngine = "auto", + dbscan: bool = False, + min_dist: float = 0.5, # DBSCAN eps + min_samples: int = 1, # DBSCAN min_samples memoize: bool = True, + verbose: bool = False, ): - r""" - Featurize Nodes or Edges of the underlying nodes/edges DataFrames. - ______________________________________________________________________ - + r"""Featurize Nodes or Edges of the underlying nodes/edges DataFrames. + :param kind: specify whether to featurize `nodes` or `edges`. Edge featurization includes a pairwise src-to-dst feature block using a MultiLabelBinarizer, @@ -2248,11 +2528,11 @@ def featurize( :param use_scaler: selects which scaler (and automatically imputes missing values using mean strategy) to scale the data. Options are; - "minmax", "quantile", "zscale", "robust", + "minmax", "quantile", "standard", "robust", "kbins", default None. Please see scikits-learn documentation https://scikit-learn.org/stable/modules/preprocessing.html - Here 'zscale' corresponds to 'StandardScaler' in scikits. + Here 'standard' corresponds to 'StandardScaler' in scikits. :param cardinality_threshold: dirty_cat threshold on cardinality of categorical labels across columns. If value is greater than threshold, will run GapEncoder @@ -2291,20 +2571,21 @@ def featurize( but at cost of encoding time. If faster encoding is needed, `average_word_embeddings_komninos` is useful and produces less semantically relevant vectors. - Please see www.huggingface.co or sentence_transformer + Please see sentence_transformer (https://www.sbert.net/) library for all available models. :param multilabel: if True, will encode a *single* target column composed of lists of lists as multilabel outputs. This only works with y=['a_single_col'], default False :param embedding: If True, produces a random node embedding of size `n_topics` - default, False. + default, False. If no node features are provided, will produce random embeddings + (for GNN models, for example) :param use_ngrams: If True, will encode textual columns as TfIdf Vectors, default, False. :param ngram_range: if use_ngrams=True, can set ngram_range, eg: tuple = (1, 3) :param max_df: if use_ngrams=True, set max word frequency to consider in vocabulary eg: max_df = 0.2, :param min_df: if use_ngrams=True, set min word count to consider in vocabulary - eg: min_df = 3 + eg: min_df = 3 or 0.00001 :param categories: Optional[str] in ["auto", "k-means", "most_frequent"], decides which category to select in Similarity Encoding, default 'auto' :param impute: Whether to impute missing values, default True @@ -2314,7 +2595,7 @@ def featurize( can return distribution as ["normal", "uniform"] :param quantile_range: if use_scaler = 'robust'|'quantile', sets the quantile range. - :param n_bins: number of bins to use in kbins discretizer + :param n_bins: number of bins to use in kbins discretizer, default 10 :param encode: encoding for KBinsDiscretizer, can be one of `onehot`, `onehot-dense`, `ordinal`, default 'ordinal' :param strategy: strategy for KBinsDiscretizer, can be one of @@ -2322,6 +2603,9 @@ def featurize( :param n_quantiles: if use_scaler = "quantile", sets the number of quantiles, default=100 :param output_distribution: if use_scaler="quantile"|"robust", choose from ["normal", "uniform"] + :param dbscan: whether to run DBSCAN, default False. + :param min_dist: DBSCAN eps parameter, default 0.5. + :param min_samples: DBSCAN min_samples parameter, default 5. :param keep_n_decimals: number of decimals to keep :param remove_node_column: whether to remove node column so it is not featurized, default True. @@ -2329,16 +2613,22 @@ def featurize( not, default False. :param memoize: whether to store and reuse results across runs, default True. - :return: self, with new attributes set by the featurization process. + :return: graphistry instance with new attributes set by the featurization process. """ - assert_imported() + feature_engine = resolve_feature_engine(feature_engine) + + print('Featurizing nodes with feature_engine=' + feature_engine) + + if feature_engine == 'dirty_cat': + assert_imported() + elif feature_engine == 'cu_cat': + assert_cuml_cucat() + if inplace: res = self else: res = self.bind() - feature_engine = resolve_feature_engine(feature_engine) - if kind == "nodes": res = res._featurize_nodes( X=X, @@ -2355,11 +2645,10 @@ def featurize( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, # deprecated min_words=min_words, model_name=model_name, - similarity=similarity, # deprecated - categories=categories, # deprecated + similarity=similarity, + categories=categories, impute=impute, n_quantiles=n_quantiles, quantile_range=quantile_range, @@ -2371,6 +2660,7 @@ def featurize( remove_node_column=remove_node_column, feature_engine=feature_engine, memoize=memoize, + verbose=verbose ) elif kind == "edges": res = res._featurize_edges( @@ -2387,11 +2677,10 @@ def featurize( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, # deprecated min_words=min_words, model_name=model_name, - similarity=similarity, # deprecated - categories=categories, # deprecated + similarity=similarity, + categories=categories, impute=impute, n_quantiles=n_quantiles, quantile_range=quantile_range, @@ -2402,12 +2691,17 @@ def featurize( keep_n_decimals=keep_n_decimals, feature_engine=feature_engine, memoize=memoize, + verbose=verbose ) else: logger.warning( f"One may only featurize `nodes` or `edges`, got {kind}" ) return self + + if dbscan: # this adds columns to the dataframe, will break tests of pure featurization & umap, so set to False in those + res = res.dbscan(min_dist=min_dist, min_samples=min_samples, kind=kind, fit_umap_embedding=False, verbose=verbose) # type: ignore + if not inplace: return res @@ -2415,19 +2709,18 @@ def _featurize_or_get_nodes_dataframe_if_X_is_None( self, X: XSymbolic = None, y: YSymbolic = None, - use_scaler: Optional[str] = "zscale", - use_scaler_target: Optional[str] = "kbins", + use_scaler: Optional[str] = None, + use_scaler_target: Optional[str] = None, cardinality_threshold: int = 40, cardinality_threshold_target: int = 400, n_topics: int = config.N_TOPICS_DEFAULT, n_topics_target: int = config.N_TOPICS_TARGET_DEFAULT, multilabel: bool = False, - embedding=False, + embedding: bool = False, use_ngrams: bool = False, ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - #confidence: float = 0.35, min_words: float = 2.5, model_name: str = "paraphrase-MiniLM-L6-v2", similarity: Optional[ @@ -2446,13 +2739,9 @@ def _featurize_or_get_nodes_dataframe_if_X_is_None( feature_engine: FeatureEngineConcrete = "pandas", reuse_if_existing=False, memoize: bool = True, + verbose: bool = False, ) -> Tuple[pd.DataFrame, pd.DataFrame, MIXIN_BASE]: - """ - helper method gets node feature and target matrix if X, y - are not specified. - if X, y are specified will set them as `_node_target` and - `_node_target` attributes - ----------------------------------------------------------- + """helper method gets node feature and target matrix if X, y are not specified. if X, y are specified will set them as `_node_target` and `_node_target` attributes """ res = self.bind() @@ -2462,7 +2751,7 @@ def _featurize_or_get_nodes_dataframe_if_X_is_None( res._node_target = None if reuse_if_existing and res._node_features is not None: - # logger.info('-Reusing Existing Featurization') + logger.info('-Reusing Existing Node Featurization') return res._node_features, res._node_target, res res = res._featurize_nodes( @@ -2480,7 +2769,6 @@ def _featurize_or_get_nodes_dataframe_if_X_is_None( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, min_words=min_words, model_name=model_name, similarity=similarity, @@ -2496,6 +2784,7 @@ def _featurize_or_get_nodes_dataframe_if_X_is_None( remove_node_column=remove_node_column, feature_engine=feature_engine, memoize=memoize, + verbose=verbose, ) assert res._node_features is not None # ensure no infinite loop @@ -2511,10 +2800,10 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( self, X: XSymbolic = None, y: YSymbolic = None, - use_scaler: Optional[str] = "robust", - use_scaler_target: Optional[str] = "kbins", + use_scaler: Optional[str] = None, + use_scaler_target: Optional[str] = None, cardinality_threshold: int = 40, - cardinality_threshold_target: int = 20, + cardinality_threshold_target: int = 400, n_topics: int = config.N_TOPICS_DEFAULT, n_topics_target: int = config.N_TOPICS_TARGET_DEFAULT, multilabel: bool = False, @@ -2522,7 +2811,6 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( ngram_range: tuple = (1, 3), max_df: float = 0.2, min_df: int = 3, - #confidence: float = 0.35, min_words: float = 2.5, model_name: str = "paraphrase-MiniLM-L6-v2", similarity: Optional[ @@ -2540,11 +2828,10 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( feature_engine: FeatureEngineConcrete = "pandas", reuse_if_existing=False, memoize: bool = True, + verbose: bool = False, ) -> Tuple[pd.DataFrame, Optional[pd.DataFrame], MIXIN_BASE]: - """ - helper method gets edge feature and target matrix if X, y - are not specified - ----------------------------------------------------------- + """ helper method gets edge feature and target matrix if X, y are not specified + :param X: Data Matrix :param y: target, default None :return: data `X` and `y` @@ -2557,7 +2844,7 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( res._edge_target = None if reuse_if_existing and res._edge_features is not None: - # logger.info('-Reusing Existing Featurization') + logger.info('-Reusing Existing Edge Featurization') return res._edge_features, res._edge_target, res res = res._featurize_edges( @@ -2574,7 +2861,6 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( ngram_range=ngram_range, max_df=max_df, min_df=min_df, - #confidence=confidence, min_words=min_words, model_name=model_name, similarity=similarity, @@ -2589,6 +2875,7 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( keep_n_decimals=keep_n_decimals, feature_engine=feature_engine, memoize=memoize, + verbose=verbose, ) assert res._edge_features is not None # ensure no infinite loop @@ -2600,39 +2887,43 @@ def _featurize_or_get_edges_dataframe_if_X_is_None( memoize=memoize, ) - def _features_by_col(self, column_part: str, kind: str): - if kind == 'nodes' and hasattr(self, '_node_features'): - X = self._node_features - elif kind == 'edges' and hasattr(self, '_edge_features'): - X = self._edge_features - else: - raise ValueError('make sure to call `featurize` or `umap` before calling `get_features_by_cols`') - - transformed_columns = X.columns[X.columns.map(lambda x: True if column_part in x else False)] # type: ignore - return X[transformed_columns] # type: ignore - def get_features_by_cols(self, columns: Union[List, str], kind: str = 'nodes'): - """Returns feature matrix with only the columns that contain the string `column_part` in their name. - - `X = g.get_features_by_cols(['feature1', 'feature2'])` - will retrieve a feature matrix with only the columns that contain the string - `feature1` or `feature2` in their name. + def get_matrix(self, columns: Optional[Union[List, str]] = None, kind: str = 'nodes', target: bool = False) -> pd.DataFrame: + """Returns feature matrix, and if columns are specified, returns matrix with only the columns that contain the string `column_part` in their name.`X = g.get_matrix(['feature1', 'feature2'])` will retrieve a feature matrix with only the columns that contain the string `feature1` or `feature2` in their name. Most useful for topic modeling, where the column names are of the form `topic_0: descriptor`, `topic_1: descriptor`, etc. Can retrieve unique columns in original dataframe, or actual topic features like [ip_part, shoes, preference_x, etc]. Powerful way to retrieve features from a featurized graph by column or (top) features of interest. - example: - res = g2.get_features_by_cols(['172', 'percent']) - res.columns + **Example:** + :: + + # get the full feature matrices + X = g.get_matrix() + y = g.get_matrix(target=True) + + # get subset of features, or topics, given topic model encoding + X = g2.get_matrix(['172', 'percent']) + X.columns => ['ip_172.56.104.67', 'ip_172.58.129.252', 'item_percent'] + # or in targets + y = g2.get_matrix(['total', 'percent'], target=True) + y.columns + => ['basket_price_total', 'conversion_percent', 'CTR_percent', 'CVR_percent'] + + # not as useful for sbert features. + + Caveats: + - if you have a column name that is a substring of another column name, you may get unexpected results. Args: - columns (Union[List, str]): list of column names or a single column name that may exist in columns - of the feature matrix. - kind (str, optional): Node or Edge features. Defaults to 'nodes'. + :columns (Union[List, str]): list of column names or a single column name that may exist in columns of the feature matrix. If None, returns original feature matrix + :kind (str, optional): Node or Edge features. Defaults to 'nodes'. + :target (bool, optional): If True, returns the target matrix. Defaults to False. Returns: pd.DataFrame: feature matrix with only the columns that contain the string `column_part` in their name. """ - if isinstance(columns, str): - columns = [columns] - X = pd.concat([self._features_by_col(col, kind=kind) for col in columns], axis=1) # type: ignore - X = X.loc[:, ~X.columns.duplicated()] # type: ignore - return X + + if target: + X = self._get_target(kind) + else: + X = self._get_feature(kind) + + return get_matrix_by_column_parts(X, columns) diff --git a/graphistry/features.py b/graphistry/features.py index 7567b159db..32e83a3a28 100644 --- a/graphistry/features.py +++ b/graphistry/features.py @@ -1,6 +1,6 @@ -from collections import UserDict from .util import setup_logger from .constants import VERBOSE, TRACE +from .util import ModelDict logger = setup_logger("graphistry.features", verbose=VERBOSE, fullpath=TRACE) @@ -21,8 +21,8 @@ # ################# graphistry featurization config constants ################# N_TOPICS = 42 N_TOPICS_TARGET = 10 -HIGH_CARD = 4e7 # forces one hot encoding -MID_CARD = 2e3 # todo: forces hashing +HIGH_CARD = 1e9 # forces one hot encoding +MID_CARD = 1e3 # todo: force hashing LOW_CARD = 2 CARD_THRESH = 40 @@ -30,29 +30,61 @@ FORCE_EMBEDDING_ALL_COLUMNS = 0 # min_words HIGH_WORD_COUNT = 1024 +MID_WORD_COUNT = 128 LOW_WORD_COUNT = 3 NGRAMS_RANGE = (1, 3) MAX_DF = 0.2 MIN_DF = 3 -N_BINS = 10 KBINS_SCALER = "kbins" +STANDARD = 'standard' +ROBUST = 'robust' +MINMAX = 'minmax' +QUANTILE = 'quantile' +# for Optuna +ERROR = "error" + +SCALERS = [STANDARD, ROBUST, MINMAX, KBINS_SCALER, QUANTILE] +NO_SCALER = None +# Scaler options +N_BINS = 10 IMPUTE = "median" # set to N_QUANTILES = 100 OUTPUT_DISTRIBUTION = "normal" -QUANTILES_RANGE = (25, 75) -N_BINS = 10 +QUANTILES_RANGE = (5, 95) ENCODE = "ordinal" # kbins, onehot, ordinal, label STRATEGY = "uniform" # uniform, quantile, kmeans SIMILARITY = None # 'ngram' , default None uses Gap CATEGORIES = "auto" -KEEP_N_DECIMALS = 5 +SCALER_OPTIONS = {'impute': ['median', None], 'n_quantiles': [10,100], 'output_distribution': ['normal', 'uniform'], + 'quantile_range': QUANTILES_RANGE, + 'encode': ['kbins', 'onehot', 'ordinal', 'label'], + 'strategy': ['uniform', 'quantile', 'kmeans'], + 'similarity':[None, 'ngram'], 'categories': CATEGORIES, 'n_bins': [2, 100], + 'use_scaler': SCALERS, 'use_scaler_target': SCALERS +} +# precision in decimal places +KEEP_N_DECIMALS = 5 # TODO: check to see if this takes a lot of time +BATCH_SIZE_SMALL = 32 BATCH_SIZE = 1000 -NO_SCALER = None EXTRA_COLS_NEEDED = ["x", "y", "_n"] # ############################################################### +# ################# graphistry umap config constants ################# +N_COMPONENTS = 2 +N_NEIGHBORS = 20 +MIN_DIST = 0.1 +SPREAD = 1 +LOCAL_CONNECTIVITY = 1 +REPULSION_STRENGTH = 2 +NEGATIVE_SAMPLING_RATE = 5 +METRIC = "euclidean" + +UMAP_OPTIONS = {'n_components': [2, 10], 'n_neighbors': [2, 30], 'min_dist': [0.01, 0.99], 'spread': [0.5, 5], 'local_connectivity': [1, 30], + 'repulsion_strength': [1, 10], 'negative_sampling_rate': [5, 20], + 'metric': ['euclidean', 'cosine', 'manhattan', 'l1', 'l2', 'cityblock', 'braycurtis', 'canberra', 'chebyshev', 'correlation', 'dice', 'hamming', 'jaccard', 'kulsinski', 'mahalanobis', 'matching', 'minkowski', 'rogerstanimoto', 'russellrao', 'seuclidean', 'sokalmichener', 'sokalsneath', 'sqeuclidean', 'yule'] +} # ############################################################### # ################# enrichments @@ -72,12 +104,14 @@ NGRAMS = "ngrams" # ############ Embedding Models PARAPHRASE_SMALL_MODEL = "sentence-transformers/paraphrase-albert-small-v2" -PARAPHRASE_MULTILINGUAL_MODEL = ( - "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" -) +PARAPHRASE_MULTILINGUAL_MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2" MSMARCO2 = "sentence-transformers/msmarco-distilbert-base-v2" # 768 MSMARCO3 = "sentence-transformers/msmarco-distilbert-base-v3" # 512 QA_SMALL_MODEL = "sentence-transformers/multi-qa-MiniLM-L6-cos-v1" +LLM_SMALL = "sentence-transformers/llm-en-dim128" +LLM_LARGE = "sentence-transformers/llm-en-dim512" + +EMBEDDING_MODELS = [PARAPHRASE_SMALL_MODEL, PARAPHRASE_MULTILINGUAL_MODEL, MSMARCO2, MSMARCO3, QA_SMALL_MODEL, LLM_SMALL, LLM_LARGE] # ############################################################################# # Model Training Constants # Used for seeding random state @@ -87,41 +121,30 @@ SPLIT_HIGH = 0.5 # ############################################################################# -class ModelDict(UserDict): - """Helper class to print out model names - - Args: - message: description of model - verbose: print out model names, logging happens regardless - """ - - def __init__(self, message, verbose=True, *args, **kwargs): - self._message = message - self._verbose = verbose - self._print_length = min(LENGTH_PRINT, len(message)) - self._updates = [] - super().__init__(*args, **kwargs) - - def __repr__(self): - logger.info(self._message) - if self._verbose: - print("_" * self._print_length) - print() - print(self._message) - print("_" * self._print_length) - print() - return super().__repr__() - - def update(self, *args, **kwargs): - self._updates.append(args[0]) - if len(self._updates) > 1: # don't take first update since its the init/default - self._message += ( - "\n" + "_" * self._print_length + f"\n\nUpdated: {self._updates[-1]}" - ) - return super().update(*args, **kwargs) - - -default_featurize_parameters = dict( +# model training options + +FEATURE_OPTIONS = { + 'kind': ['nodes', 'edges'], + 'cardinality_threshold': [1, HIGH_CARD], + 'cardinality_threshold_target': [1, HIGH_CARD], + 'n_topics': [4, 100], + 'n_topics_target': [4, 100], + 'multilabel': [True, False], + 'embedding': [True, False], + 'use_ngrams': [True, False], + 'ngram_range': (1, 5), + 'max_df': [0.1, 0.9], + 'min_df': [1, 10], + 'min_words': [0, 100], + 'model_name': [MSMARCO2, MSMARCO3, PARAPHRASE_SMALL_MODEL, PARAPHRASE_MULTILINGUAL_MODEL, QA_SMALL_MODEL], +} + + +# ############################################################################# +# Model Training {params} + +default_featurize_parameters = ModelDict( + "Featurize Parameters", kind="nodes", use_scaler=NO_SCALER, use_scaler_target=NO_SCALER, @@ -154,60 +177,87 @@ def update(self, *args, **kwargs): ) +default_umap_parameters = ModelDict("Umap Parameters", + {"n_components": N_COMPONENTS, + **({"metric": METRIC} if True else {}), + "n_neighbors": N_NEIGHBORS, + "min_dist": MIN_DIST, + "spread": SPREAD, + "local_connectivity": LOCAL_CONNECTIVITY, + "repulsion_strength": REPULSION_STRENGTH, + "negative_sample_rate": NEGATIVE_SAMPLING_RATE, + } +) + + +umap_hellinger = ModelDict("Umap Parameters Hellinger", + {"n_components": N_COMPONENTS, + "metric": "hellinger", # info metric, can't use on + # textual encodings since they contain negative values... + "n_neighbors": 15, + "min_dist": 0.3, + "spread": 0.5, + "local_connectivity": 1, + "repulsion_strength": 1, + "negative_sample_rate": 5 + } +) + +umap_euclidean = ModelDict("Umap Parameters Euclidean", + {"n_components": N_COMPONENTS, + "metric": "euclidean", + "n_neighbors": 12, + "min_dist": 0.1, + "spread": 0.5, + "local_connectivity": 1, + "repulsion_strength": 1, + "negative_sample_rate": 5 + } +) + # ############################################################################# # Create useful presets for the user # makes naming and encoding models consistently and testing different models against eachother easy # customize the default parameters for each model you want to test # Ngrams Model over features -ngrams_model = ModelDict("Ngrams Model", verbose=True, **default_featurize_parameters) -ngrams_model.update(dict(use_ngrams=True, min_words=HIGH_CARD)) +ngrams_model = ModelDict( + "Ngrams Model", use_ngrams=True, min_words=HIGH_CARD, verbose=True +) # Topic Model over features -topic_model = ModelDict("Topic Model", verbose=True, **default_featurize_parameters) -topic_model.update( - dict( - cardinality_threshold=LOW_CARD, # force topic model - cardinality_threshold_target=LOW_CARD, # force topic model - n_topics=N_TOPICS, - n_topics_target=N_TOPICS_TARGET, - min_words=HIGH_CARD, # make sure it doesn't turn into sentence model, but rather topic models - ) +topic_model = ModelDict( + "Reliable Topic Models on Features and Target", + cardinality_threshold=LOW_CARD, # force topic model + cardinality_threshold_target=LOW_CARD, # force topic model + n_topics=N_TOPICS, + n_topics_target=N_TOPICS_TARGET, + min_words=HIGH_CARD, # make sure it doesn't turn into sentence model, but rather topic models + verbose=True, ) # useful for text data that you want to paraphrase embedding_model = ModelDict( - f"{PARAPHRASE_SMALL_MODEL} Embedding Model", + f"{PARAPHRASE_SMALL_MODEL} sbert Embedding Model", + min_words=FORCE_EMBEDDING_ALL_COLUMNS, + model_name=PARAPHRASE_SMALL_MODEL, # if we need multilingual support, use PARAPHRASE_MULTILINGUAL_MODEL verbose=True, - **default_featurize_parameters, -) -embedding_model.update( - dict( - min_words=FORCE_EMBEDDING_ALL_COLUMNS, - model_name=PARAPHRASE_SMALL_MODEL, # if we need multilingual support, use PARAPHRASE_MULTILINGUAL_MODEL - ) ) # useful for when search input is much smaller than the encoded documents search_model = ModelDict( - f"{MSMARCO2} Search Model", verbose=True, **default_featurize_parameters -) -search_model.update( - dict( - min_words=FORCE_EMBEDDING_ALL_COLUMNS, - model_name=MSMARCO2, - ) + f"{MSMARCO2} Search Model", + verbose=True, + min_words=FORCE_EMBEDDING_ALL_COLUMNS, + model_name=MSMARCO2, ) # Question Answering encodings for search qa_model = ModelDict( - f"{QA_SMALL_MODEL} QA Model", verbose=True, **default_featurize_parameters -) -qa_model.update( - dict( - min_words=FORCE_EMBEDDING_ALL_COLUMNS, - model_name=QA_SMALL_MODEL, - ) + f"{QA_SMALL_MODEL} QA Model", + min_words=FORCE_EMBEDDING_ALL_COLUMNS, + model_name=QA_SMALL_MODEL, + verbose=True, ) @@ -221,7 +271,7 @@ def update(self, *args, **kwargs): if __name__ == "__main__": - # python3 -m graphistry.features -m 'my awesome edge encoded model' -p '{"kind":"edges"}' + """python3 -m graphistry.features -m 'my awesome edge encoded model' -p '{"kind":"edges"}'""" import argparse import json diff --git a/graphistry/hyper_dask.py b/graphistry/hyper_dask.py index 5da16298f9..1b4ee15647 100644 --- a/graphistry/hyper_dask.py +++ b/graphistry/hyper_dask.py @@ -602,7 +602,7 @@ def df_coercion( # noqa: C901 if engine == Engine.DASK: import dask.dataframe if isinstance(df, pd.DataFrame): - out = dask.dataframe.from_pandas(df, **{ + out = dask.dataframe.from_pandas(df, **{ # type: ignore **({'npartitions': npartitions} if npartitions is not None else {}) , **({'chunksize': chunksize} if chunksize is not None else {}) }) diff --git a/graphistry/layout/graph/graph.py b/graphistry/layout/graph/graph.py index b04dd4842e..4cbeac9182 100644 --- a/graphistry/layout/graph/graph.py +++ b/graphistry/layout/graph/graph.py @@ -8,31 +8,55 @@ class Graph(object): - """ - The graph is stored in disjoint-sets holding each connected component in `components` as a list of graph_core objects. - - **Attributes** - C (list[GraphBase]): list of graph_core components. - - **Methods** - add_vertex(v): add vertex v into the Graph as a new component - add_edge(e): add edge e and its vertices into the Graph possibly merging the - associated graph_core components - get_vertices_count(): see order() - vertices(): see graph_core - edges(): see graph_core - remove_edge(e): remove edge e possibly spawning two new cores - if the graph_core that contained e gets disconnected. - remove_vertex(v): remove vertex v and all its edges. - order(): the order of the graph (number of vertices) - norm(): the norm of the graph (number of edges) - deg_min(): the minimum degree of vertices - deg_max(): the maximum degree of vertices - deg_avg(): the average degree of vertices - eps(): the graph epsilon value (norm/order), average number of edges per vertex. - connected(): returns True if the graph is connected (i.e. it has only one component). - components(): returns the list of components - """ + # """ + # The graph is stored in disjoint-sets holding each connected component in `components` as a list of graph_core objects. + + # **Attributes** + # C (list[GraphBase]): list of graph_core components. + + + # **add_edge(e):** + # add edge e and its vertices into the Graph possibly merging the associated graph_core components + + # **get_vertices_count():** + # see order() + + # **vertices():** + # see graph_core + + # **edges():** + # see graph_core + + # **remove_edge(e):** + # remove edge e possibly spawning two new cores if the graph_core that contained e gets disconnected. + + # **remove_vertex(v):** + # remove vertex v and all its edges. + + # **order():** + # the order of the graph (number of vertices) + + # **norm():** + # the norm of the graph (number of edges) + + # **deg_min():** + # the minimum degree of vertices + + # **deg_max():** + # the maximum degree of vertices + + # **deg_avg():** + # the average degree of vertices + + # **eps():** + # the graph epsilon value (norm/order), average number of edges per vertex. + + # **connected():** + # returns True if the graph is connected (i.e. it has only one component). + + # **components():** + # returns the list of components + # """ component_class = GraphBase @@ -73,16 +97,22 @@ def __init__(self, vertices = None, edges = None, directed = True): self.components.append(self.component_class(vertices, edge_set, directed)) def add_vertex(self, v): + """ + add vertex v into the Graph as a new component + """ for c in self.components: if v in c.verticesPoset: return c.verticesPoset.get(v) g = self.component_class(directed = self.directed) v = g.add_single_vertex(v) self.components.append(g) + print("add vertex v into the Graph as a new component") return v def add_edge(self, e): - + """ + add edge e and its vertices into the Graph possibly merging the associated graph_core components + """ x = e.v[0] y = e.v[1] x = self.add_vertex(x) @@ -116,6 +146,9 @@ def get_vertex_from_data(self, data): return None def vertices(self): + """ + see graph_core + """ for c in self.components: vertices = c.verticesPoset for v in vertices: @@ -128,6 +161,9 @@ def edges(self): yield e def remove_edge(self, e): + """ + remove edge e possibly spawning two new cores if the graph_core that contained e gets disconnected. + """ # get the GraphBase: c = e.v[0].component assert c == e.v[1].component @@ -147,6 +183,9 @@ def remove_edge(self, e): return e def remove_vertex(self, x): + """ + remove vertex v and all its edges. + """ c = x.component if c not in self.components: return None @@ -165,24 +204,42 @@ def remove_vertex(self, x): return x def order(self): + """ + the order of the graph (number of vertices) + """ return sum([c.order() for c in self.components]) def norm(self): + """ + the norm of the graph (number of edges) + """ return sum([c.norm() for c in self.components]) def deg_min(self): + """ + the minimum degree of vertices + """ return min([c.deg_min() for c in self.components]) def deg_max(self): + """ + the maximum degree of vertices + """ return max([c.deg_max() for c in self.components]) def deg_avg(self): + """ + the average degree of vertices + """ t = 0.0 for c in self.components: t += sum([v.degree() for v in c.verticesPoset]) return t / float(self.order()) def eps(self): + """ + the graph epsilon value (norm/order), average number of edges per vertex. + """ return float(self.norm()) / self.order() def path(self, x, y, f_io = 0, hook = None): @@ -203,4 +260,7 @@ def __contains__(self, G): return r def connected(self): + """ + returns the list of components + """ return len(self.components) == 1 diff --git a/graphistry/layout/graph/graphBase.py b/graphistry/layout/graph/graphBase.py index 0e1b8f51e4..725f45daf9 100644 --- a/graphistry/layout/graph/graphBase.py +++ b/graphistry/layout/graph/graphBase.py @@ -13,41 +13,6 @@ class GraphBase(object): loops (set[Edge]): the set of *loop* edges (of degree 0). directed (bool): indicates if the graph is considered *oriented* or not. - Methods: - vertices(cond=None): generates an iterator over vertices, with optional filter - edges(cond=None): generates an iterator over edges, with optional filter - matrix(cond=None): returns the associativity matrix of the graph component - order(): the order of the graph (number of vertices) - norm(): the norm of the graph (number of edges) - deg_min(): the minimum degree of vertices - deg_max(): the maximum degree of vertices - deg_avg(): the average degree of vertices - eps(): the graph epsilon value (norm/order), average number of edges per vertex. - path(x,y,f_io=0,hook=None): shortest path between vertices x and y by breadth-first descent, - contrained by f_io direction if provided. The path is returned as a list of Vertex objects. - If a *hook* function is provided, it is called at every vertex added to the path, passing - the vertex object as argument. - roots(): returns the list of *roots* (vertices with no inward edges). - leaves(): returns the list of *leaves* (vertices with no outward edges). - add_single_vertex(v): allow a GraphBase to hold a single vertex. - add_edge(e): add edge e. At least one of its vertex must belong to the graph, - the other being added automatically. - remove_edge(e): remove Edge e, asserting that the resulting graph is still connex. - remove_vertex(x): remove Vertex x and all associated edges. - dijkstra(x,f_io=0,hook=None): shortest weighted-edges paths between x and all other vertices - by dijkstra's algorithm with heap used as priority queue. - get_scs_with_feedback(): returns the set of strongly connected components - ("scs") by using Tarjan algorithm. - These are maximal sets of vertices such that there is a path from each - vertex to every other vertex. - The algorithm performs a DFS from the provided list of root vertices. - A cycle is of course a strongly connected component, - but a strongly connected component can include several cycles. - The Feedback Acyclic Set of edge to be removed/reversed is provided by - marking the edges with a "feedback" flag. - Complexity is O(V+E). - partition(): returns a *partition* of the connected graph as a list of lists. - neighbors(v): returns neighbours of a vertex v. """ def __init__(self, vertices = None, edges = None, directed = True): @@ -96,12 +61,21 @@ def __init__(self, vertices = None, edges = None, directed = True): v.component = self def roots(self): + """ + returns the list of *roots* (vertices with no inward edges). + """ return list(filter(lambda v: len(v.e_in()) == 0, self.verticesPoset)) def leaves(self): + """ + returns the list of *leaves* (vertices with no outward edges). + """ return list(filter(lambda v: len(v.e_out()) == 0, self.verticesPoset)) def add_single_vertex(self, v): + """ + allow a GraphBase to hold a single vertex. + """ if len(self.edgesPoset) == 0 and len(self.verticesPoset) == 0: v = self.verticesPoset.add(v) v.component = self @@ -109,6 +83,9 @@ def add_single_vertex(self, v): return None def add_edge(self, e): + """ + add edge e. At least one of its vertex must belong to the graph, the other being added automatically. + """ if e in self.edgesPoset: return self.edgesPoset.get(e) x = e.v[0] @@ -127,6 +104,9 @@ def add_edge(self, e): return e def remove_edge(self, e): + """ + remove Edge e, asserting that the resulting graph is still connex. + """ if e not in self.edgesPoset: return e.detach() @@ -143,6 +123,9 @@ def remove_edge(self, e): return e def remove_vertex(self, x): + """ + remove Vertex x and all associated edges. + """ if x not in self.verticesPoset: return vertices = x.neighbors() # get all neighbor vertices to check paths @@ -168,6 +151,9 @@ def constant_function(self, value): return lambda x: value def vertices(self, cond = None): + """ + generates an iterator over vertices, with optional filter + """ vertices = self.verticesPoset if cond is None: cond = self.constant_function(True) @@ -176,6 +162,9 @@ def vertices(self, cond = None): yield v def edges(self, cond = None): + """ + generates an iterator over edges, with optional filter + """ edges = self.edgesPoset if cond is None: cond = self.constant_function(True) @@ -185,7 +174,7 @@ def edges(self, cond = None): def matrix(self, cond = None): """ - This associativity matrix is like the adjacency matrix but antisymmetric. + This associativity matrix is like the adjacency matrix but antisymmetric. Returns the associativity matrix of the graph component :param cond: same a the condition function in vertices(). :return: array @@ -207,27 +196,46 @@ def matrix(self, cond = None): return mat def order(self): + """ + the order of the graph (number of vertices) + """ return len(self.verticesPoset) def norm(self): """ - The size of the edge poset. + The size of the edge poset (number of edges). """ return len(self.edgesPoset) def deg_min(self): + """ + the minimum degree of vertices + """ return min([v.degree() for v in self.verticesPoset]) def deg_max(self): + """ + the maximum degree of vertices + """ return max([v.degree() for v in self.verticesPoset]) def deg_avg(self): + """ + the average degree of vertices + """ return sum([v.degree() for v in self.verticesPoset]) / float(self.order()) def eps(self): + """ + the graph epsilon value (norm/order), average number of edges per vertex. + """ return float(self.norm()) / self.order() def path(self, x, y, f_io = 0, hook = None): + """ + shortest path between vertices x and y by breadth-first descent, contrained by f_io direction if provided. The path is returned as a list of Vertex objects. + If a *hook* function is provided, it is called at every vertex added to the path, passing the vertex object as argument. + """ assert x in self.verticesPoset assert y in self.verticesPoset x = self.verticesPoset.get(x) @@ -263,6 +271,9 @@ def path(self, x, y, f_io = 0, hook = None): return p def dijkstra(self, x, f_io = 0, hook = None): + """ + shortest weighted-edges paths between x and all other vertices by dijkstra's algorithm with heap used as priority queue. + """ from collections import defaultdict from heapq import heappop, heappush @@ -300,7 +311,11 @@ def dijkstra(self, x, f_io = 0, hook = None): def get_scs_with_feedback(self, roots = None): """ - Minimum FAS algorithm (feedback arc set) creating a DAG. + Minimum FAS algorithm (feedback arc set) creating a DAG. Returns the set of strongly connected components + ("scs") by using Tarjan algorithm. These are maximal sets of vertices such that there is a path from each vertex to every other vertex. + The algorithm performs a DFS from the provided list of root vertices. A cycle is of course a strongly connected component,but a strongly connected component can include several cycles. + The Feedback Acyclic Set of edge to be removed/reversed is provided by marking the edges with a "feedback" flag. + Complexity is O(V+E). :param roots: :return: diff --git a/graphistry/layout/graph/vertexBase.py b/graphistry/layout/graph/vertexBase.py index 07cb8d6794..1a950273f0 100644 --- a/graphistry/layout/graph/vertexBase.py +++ b/graphistry/layout/graph/vertexBase.py @@ -7,17 +7,6 @@ class VertexBase(object): **Attributes** e (list[Edge]): list of edges associated with this vertex. - **Methods** - degree() : degree of the vertex (number of edges). - e_in() : list of edges directed toward this vertex. - e_out(): list of edges directed outward this vertex. - e_dir(int): either e_in, e_out or all edges depending on provided direction parameter (>0 means outward). - neighbors(f_io=0): list of neighbor vertices in all directions (default) or in filtered f_io direction (>0 means outward). - e_to(v): returns the Edge from this vertex directed toward vertex v. - e_from(v): returns the Edge from vertex v directed toward this vertex. - e_with(v): return the Edge with both this vertex and vertex v - detach(): removes this vertex from all its edges and returns this list of edges. - """ def __init__(self): @@ -25,15 +14,27 @@ def __init__(self): self.e = [] def degree(self): + """ + degree() : degree of the vertex (number of edges). + """ return len(self.e) def e_in(self): + """ + e_in() : list of edges directed toward this vertex. + """ return list(filter((lambda e: e.v[1] == self), self.e)) def e_out(self): + """ + e_out(): list of edges directed outward this vertex. + """ return list(filter((lambda e: e.v[0] == self), self.e)) def e_dir(self, dir): + """ + either e_in, e_out or all edges depending on provided direction parameter (>0 means outward). + """ if dir > 0: return self.e_out() if dir < 0: @@ -42,7 +43,7 @@ def e_dir(self, dir): def neighbors(self, direction = 0): """ - Returns the neighbors of this vertex. + Returns the neighbors of this vertex. List of neighbor vertices in all directions (default) or in filtered f_io direction (>0 means outward). :param direction: - 0: parent and children @@ -58,24 +59,36 @@ def neighbors(self, direction = 0): return arr def e_to(self, y): + """ + returns the Edge from this vertex directed toward vertex v. + """ for e in self.e_out(): if e.v[1] == y: return e return None def e_from(self, x): + """ + returns the Edge from vertex v directed toward this vertex. + """ for e in self.e_in(): if e.v[0] == x: return e return None def e_with(self, v): + """ + return the Edge with both this vertex and vertex v + """ for e in self.e: if v in e.v: return e return None def detach(self): + """ + removes this vertex from all its edges and returns this list of edges. + """ E = self.e[:] for e in E: e.detach() diff --git a/graphistry/plotter.py b/graphistry/plotter.py index 3ed7c06118..00f32dfdeb 100644 --- a/graphistry/plotter.py +++ b/graphistry/plotter.py @@ -8,13 +8,14 @@ from .embed_utils import HeterographEmbedModuleMixin # type: ignore from .text_utils import SearchToGraphMixin # type: ignore from .compute.conditional import ConditionalMixin # type: ignore +from .compute.cluster import ClusterMixin # type: ignore mixins = ([ CosmosMixin, NeptuneMixin, GremlinMixin, HeterographEmbedModuleMixin, SearchToGraphMixin, - DGLGraphMixin, + DGLGraphMixin, ClusterMixin, UMAPMixin, FeatureMixin, ConditionalMixin, LayoutsMixin, @@ -32,6 +33,7 @@ def __init__(self, *args, **kwargs): ConditionalMixin.__init__(self, *args, **kwargs) FeatureMixin.__init__(self, *args, **kwargs) UMAPMixin.__init__(self, *args, **kwargs) + ClusterMixin.__init__(self, *args, **kwargs) DGLGraphMixin.__init__(self, *args, **kwargs) SearchToGraphMixin.__init__(self, *args, **kwargs) HeterographEmbedModuleMixin.__init__(self, *args, **kwargs) diff --git a/graphistry/plugins/cugraph.py b/graphistry/plugins/cugraph.py index b5f070af72..da68452d11 100644 --- a/graphistry/plugins/cugraph.py +++ b/graphistry/plugins/cugraph.py @@ -223,14 +223,19 @@ def compute_cugraph( :param alg: algorithm name :type alg: str + :param out_col: node table output column name, defaults to alg param :type out_col: Optional[str] + :param params: algorithm parameters passed to cuGraph as kwargs :type params: dict + :param kind: kind of cugraph to use :type kind: CuGraphKind + :param directed: whether graph is directed :type directed: bool + :param G: cugraph graph to use; if None, use self :type G: Optional[cugraph.Graph] @@ -239,16 +244,19 @@ def compute_cugraph( **Example: Pagerank** :: + g2 = g.compute_cugraph('pagerank') assert 'pagerank' in g2._nodes.columns **Example: Katz centrality with rename** :: + g2 = g.compute_cugraph('katz_centrality', out_col='katz_centrality_renamed') assert 'katz_centrality_renamed' in g2._nodes.columns **Example: Pass params to cugraph** :: + g2 = g.compute_cugraph('k_truss', params={'k': 2}) assert 'k_truss' in g2._nodes.columns @@ -360,6 +368,7 @@ def layout_cugraph( **Example: ForceAtlas2 layout** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') @@ -367,6 +376,7 @@ def layout_cugraph( **Example: Change which column names are generated** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') @@ -377,6 +387,7 @@ def layout_cugraph( **Example: Pass parameters to layout methods** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') diff --git a/graphistry/plugins/igraph.py b/graphistry/plugins/igraph.py index a5bab3ac19..b7bdc0d405 100644 --- a/graphistry/plugins/igraph.py +++ b/graphistry/plugins/igraph.py @@ -49,10 +49,10 @@ def from_igraph(self, :param merge_if_existing: bool :returns: Plotter - :rtype: Plotter **Example: Convert from igraph, including all node/edge properties** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a', 'b', 'c', 'd'], 'd': ['b', 'c', 'd', 'e'], 'v': [101, 102, 103, 104]}) g = graphistry.edges(edges, 's', 'd').materialize_nodes().get_degrees() @@ -62,6 +62,7 @@ def from_igraph(self, **Example: Enrich from igraph, but only load in 1 node attribute** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a', 'b', 'c', 'd'], 'd': ['b', 'c', 'd', 'e'], 'v': [101, 102, 103, 104]}) g = graphistry.edges(edges, 's', 'd').materialize_nodes().get_degree() @@ -198,7 +199,8 @@ def from_igraph(self, return g -def to_igraph(self: Plottable, +def to_igraph( + self: Plottable, directed: bool = True, include_nodes: bool = True, node_attributes: Optional[List[str]] = None, @@ -309,8 +311,8 @@ def compute_igraph( :rtype: Plotter **Example: Pagerank** - :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['c','c','e','e']}) g = graphistry.edges(edges, 's', 'd') @@ -319,6 +321,7 @@ def compute_igraph( **Example: Pagerank with custom name** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['c','c','e','e']}) g = graphistry.edges(edges, 's', 'd') @@ -327,6 +330,7 @@ def compute_igraph( **Example: Pagerank on an undirected** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['c','c','e','e']}) g = graphistry.edges(edges, 's', 'd') @@ -334,7 +338,8 @@ def compute_igraph( assert 'pagerank' in g2._nodes.columns **Example: Pagerank with custom parameters** - :: + :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['c','c','e','e']}) g = graphistry.edges(edges, 's', 'd') @@ -447,6 +452,7 @@ def layout_igraph( **Example: Sugiyama layout** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') @@ -456,6 +462,7 @@ def layout_igraph( **Example: Change which column names are generated** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') @@ -466,6 +473,7 @@ def layout_igraph( **Example: Pass parameters to layout methods - Sort nodes by degree** :: + import graphistry, pandas as pd edges = pd.DataFrame({'s': ['a','b','c','d'], 'd': ['b','c','d','e']}) g = graphistry.edges(edges, 's', 'd') diff --git a/graphistry/pygraphistry.py b/graphistry/pygraphistry.py index 0a8dd76310..2051a32523 100644 --- a/graphistry/pygraphistry.py +++ b/graphistry/pygraphistry.py @@ -1942,6 +1942,7 @@ def nodes(nodes: Union[Callable, Any], node=None, *args, **kwargs) -> Plottable: **Example** :: + import graphistry def sample_nodes(g, n): @@ -1992,6 +1993,7 @@ def edges( **Example** :: + import graphistry def sample_edges(g, n): diff --git a/graphistry/tests/test_compute_cluster.py b/graphistry/tests/test_compute_cluster.py new file mode 100644 index 0000000000..c93d0e279d --- /dev/null +++ b/graphistry/tests/test_compute_cluster.py @@ -0,0 +1,73 @@ +import pandas as pd +import unittest +import pytest +import graphistry +from graphistry.constants import DBSCAN +from graphistry.util import ModelDict +from graphistry.compute.cluster import lazy_dbscan_import_has_dependency + +has_dbscan, _, has_gpu_dbscan, _ = lazy_dbscan_import_has_dependency() + + +ndf = edf = pd.DataFrame({'src': [1, 2, 1, 4], 'dst': [4, 5, 6, 1], 'label': ['a', 'b', 'b', 'c']}) + +class TestComputeCluster(unittest.TestCase): + + def _condition(self, g, kind): + if kind == 'nodes': + self.assertTrue(g._node_dbscan is not None, 'instance has no `_node_dbscan` method') + self.assertTrue(DBSCAN in g._nodes, 'node df has no `_dbscan` attribute') + #self.assertTrue(g._point_color is not None, 'instance has no `_point_color` method') + else: + self.assertTrue(g._edge_dbscan is not None, 'instance has no `_edge_dbscan` method') + self.assertTrue(DBSCAN in g._edges, 'edge df has no `_dbscan` attribute') + + @pytest.mark.skipif(not has_dbscan, reason="requires ai dependencies") + def test_umap_cluster(self): + g = graphistry.nodes(ndf).edges(edf, 'src', 'dst') + for kind in ['nodes', 'edges']: + g2 = g.umap(kind=kind, n_topics=2, dbscan=False).dbscan(kind=kind, verbose=True) + self._condition(g2, kind) + g3 = g.umap(kind=kind, n_topics=2, dbscan=True) + self._condition(g3, kind) + if kind == 'nodes': + self.assertEqual(g2._nodes[DBSCAN].tolist(), g3._nodes[DBSCAN].tolist()) + else: + self.assertEqual(g2._edges[DBSCAN].tolist(), g3._edges[DBSCAN].tolist()) + + @pytest.mark.skipif(not has_dbscan, reason="requires ai dependencies") + def test_featurize_cluster(self): + g = graphistry.nodes(ndf).edges(edf, 'src', 'dst') + for kind in ['nodes', 'edges']: + g = g.featurize(kind=kind, n_topics=2).dbscan(kind=kind, verbose=True) + self._condition(g, kind) + + @pytest.mark.skipif(not has_dbscan, reason="requires ai dependencies") + def test_dbscan_params(self): + dbscan_params = [ModelDict('Testing UMAP', kind='nodes', min_dist=0.2, min_samples=1, cols=None, target=False, + fit_umap_embedding=False, verbose=True, engine_dbscan='sklearn'), + ModelDict('Testing UMAP target', kind='nodes', min_dist=0.1, min_samples=1, cols=None, + fit_umap_embedding=True, target=True, verbose=True, engine_dbscan='sklearn'), + + ] + for params in dbscan_params: + g = graphistry.nodes(ndf).edges(edf, 'src', 'dst').umap(y='label', n_topics=2) + g2 = g.dbscan(**params) + self.assertTrue(g2._dbscan_params == params, f'dbscan params not set correctly, found {g2._dbscan_params} but expected {params}') + + @pytest.mark.skipif(not has_gpu_dbscan, reason="requires ai dependencies") + def test_transform_dbscan(self): + kind = 'nodes' + g = graphistry.nodes(ndf).edges(edf, 'src', 'dst') + g2 = g.umap(y='label', n_topics=2, kind=kind).dbscan(fit_umap_embedding=True) + + _, _, _, df = g2.transform_dbscan(ndf, kind=kind, verbose=True, return_graph=False) + self.assertTrue(DBSCAN in df, f'transformed df has no `{DBSCAN}` attribute') + + g3 = g2.transform_dbscan(ndf, ndf, verbose=True) + self._condition(g3, kind) + + +if __name__ == '__main__': + unittest.main() + diff --git a/graphistry/tests/test_dgl_utils.py b/graphistry/tests/test_dgl_utils.py index 7aaf424b7c..baaef46135 100644 --- a/graphistry/tests/test_dgl_utils.py +++ b/graphistry/tests/test_dgl_utils.py @@ -74,7 +74,7 @@ class TestDGL(unittest.TestCase): def _test_cases_dgl(self, g): # simple test to see if DGL graph was set during different featurization + umap strategies - G = g.DGL_graph + G = g._dgl_graph keys = ["feature", "target", "train_mask", "test_mask"] keys_without_target = ["feature", "train_mask", "test_mask"] diff --git a/graphistry/tests/test_embed_utils.py b/graphistry/tests/test_embed_utils.py index e979f6f26f..307bdd0266 100644 --- a/graphistry/tests/test_embed_utils.py +++ b/graphistry/tests/test_embed_utils.py @@ -1,51 +1,157 @@ +import os import pytest import pandas as pd import unittest import graphistry import numpy as np -from graphistry.embed_utils import lazy_embed_import_dep +from graphistry.embed_utils import lazy_embed_import_dep, check_cudf import logging logger = logging.getLogger(__name__) dep_flag, _, _, _, _, _, _, _ = lazy_embed_import_dep() +has_cudf, cudf = check_cudf() -edf = pd.DataFrame([[0, 1, 0], [1, 2, 0], [2, 0, 1]], - columns=['src', 'dst', 'rel'] -) -ndf_no_ids = pd.DataFrame([['a'], ['a'], ['b']], columns=['feat']) -ndf_with_ids = pd.DataFrame([[0, 'a'], [1, 'a'], [2, 'b']], - columns = ['id', 'feat1'] -) +# enable tests if has cudf and env didn't explicitly disable +is_test_cudf = has_cudf and os.environ["TEST_CUDF"] != "0" -graph_no_feat = graphistry.edges(edf, 'src', 'dst') -graph_with_feat_no_ids = graph_no_feat.nodes(ndf_no_ids) -graph_with_feat_with_ids = graph_no_feat.nodes(ndf_with_ids, 'id') -graphs = [('no_feat', graph_no_feat), ('with_feat_no_ids', graph_with_feat_no_ids), ('with_feat_with_ids', graph_with_feat_with_ids)] -d = 4 +class TestEmbed(unittest.TestCase): -kwargs = {'n_topics': 6, 'cardinality_threshold':10, 'epochs': 1, 'sample_size':10, 'num_steps':10} + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + def setUp(self): + self.edf = pd.DataFrame([[0, 1, 0], [1, 2, 0], [2, 0, 1]], + columns=['src', 'dst', 'rel'] + ) + ndf_no_ids = pd.DataFrame([['a'], ['a'], ['b']], columns=['feat']) + ndf_with_ids = pd.DataFrame([[0, 'a'], [1, 'a'], [2, 'b']], + columns = ['id', 'feat1'] + ) + + self.graph_no_feat = graphistry.edges(self.edf, 'src', 'dst') + self.graph_with_feat_no_ids = self.graph_no_feat.nodes(ndf_no_ids) + self.graph_with_feat_with_ids = self.graph_no_feat.nodes(ndf_with_ids, 'id') + self.graphs = [ + ('no_feat', self.graph_no_feat), + ('with_feat_no_ids', self.graph_with_feat_no_ids), + ('with_feat_with_ids', self.graph_with_feat_with_ids) + ] + self.d = 4 + + self.kwargs = {'n_topics': 6, 'cardinality_threshold':10, 'epochs': 1, 'sample_size':10, 'num_steps':10} + + + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + def test_embed_out_basic(self): + for name, g in self.graphs: + g = g.embed('rel', embedding_dim=self.d, **self.kwargs) + num_nodes = len(set(g._edges['src'] + g._edges['dst'])) + logging.debug('name: %s basic tests', name) + self.assertEqual(g._edges.shape, self.edf.shape) + self.assertEqual(set(g._edges[g._relation]), set(g._edges['rel'])) + self.assertEqual(g._kg_embeddings.shape,(num_nodes, self.d)) -class TestEmbed(unittest.TestCase): @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + def test_predict_links(self): + source = pd.Series([0,2]) + relation = None + destination = pd.Series([1]) + g = self.graph_no_feat.embed('rel', embedding_dim=self.d, **self.kwargs) + + g_new = g.predict_links(source, relation, destination, threshold=0, anomalous=False) + self.assertTrue( g_new._edges.shape[0] > 0) + self.assertIn("score", g_new._edges.columns) + + g_new = g.predict_links(source, relation, destination, threshold=1, anomalous=True) + self.assertTrue( g_new._edges.shape[0] > 0) + self.assertIn("score", g_new._edges.columns) + + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + def test_predict_links_all(self): + g = self.graph_no_feat.embed('rel', embedding_dim=self.d, **self.kwargs) + g_new = g.predict_links_all(threshold=0) + self.assertTrue( g_new._edges.shape[0] > 0) + self.assertIn("score", g_new._edges.columns) + + + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + def test_chaining(self): + for name, g in self.graphs: + logging.debug('name: %s test changing embedding dim with feats' % name) + g = g.embed('rel', use_feat=True, embedding_dim=self.d, **self.kwargs) + g2 = g.embed('rel', use_feat=True, embedding_dim=2 * self.d, **self.kwargs) + self.assertNotEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) + + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: + logging.debug('name: %s test changing embedding dim without feats', name) + g = g.embed('rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed('rel', use_feat=False, embedding_dim=2 * self.d, **self.kwargs) + self.assertNotEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) + + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: + logging.debug('name: %s test relationship change', name) + g = g.embed(relation='rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed(relation='src', use_feat=False, embedding_dim=self.d, **self.kwargs) + self.assertEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) + self.assertNotEqual(np.linalg.norm(g._kg_embeddings - g2._kg_embeddings), 0) + + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: + logging.debug('name: %s test relationship change', name) + g = g.embed(relation='rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed(relation='rel', use_feat=True, embedding_dim=self.d, **self.kwargs) + self.assertEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) + self.assertNotEqual(np.linalg.norm(g._kg_embeddings - g2._kg_embeddings), 0) + + +class TestEmbedCUDF(unittest.TestCase): + + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") + def setUp(self): + self.edf = cudf.DataFrame([[0, 1, 0], [1, 2, 0], [2, 0, 1]], + columns=['src', 'dst', 'rel'] + ) + ndf_no_ids = cudf.DataFrame([['a'], ['a'], ['b']], columns=['feat']) + ndf_with_ids = cudf.DataFrame([[0, 'a'], [1, 'a'], [2, 'b']], + columns = ['id', 'feat1'] + ) + + self.graph_no_feat = graphistry.edges(self.edf, 'src', 'dst') + self.graph_with_feat_no_ids = self.graph_no_feat.nodes(ndf_no_ids) + self.graph_with_feat_with_ids = self.graph_no_feat.nodes(ndf_with_ids, 'id') + self.graphs = [ + ('no_feat', self.graph_no_feat), + ('with_feat_no_ids', self.graph_with_feat_no_ids), + ('with_feat_with_ids', self.graph_with_feat_with_ids) + ] + self.d = 4 + + self.kwargs = {'n_topics': 6, 'cardinality_threshold':10, 'epochs': 1, 'sample_size':10, 'num_steps':10} + + + @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") def test_embed_out_basic(self): - for name, g in graphs: - g = g.embed('rel', embedding_dim=d, **kwargs) + for name, g in self.graphs: + g = g.embed('rel', embedding_dim=self.d, **self.kwargs) num_nodes = len(set(g._edges['src'] + g._edges['dst'])) logging.debug('name: %s basic tests', name) - self.assertEqual(g._edges.shape, edf.shape) + self.assertEqual(g._edges.shape, self.edf.shape) self.assertEqual(set(g._edges[g._relation]), set(g._edges['rel'])) - self.assertEqual(g._kg_embeddings.shape,(num_nodes, d)) + self.assertEqual(g._kg_embeddings.shape,(num_nodes, self.d)) @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") def test_predict_links(self): source = pd.Series([0,2]) relation = None destination = pd.Series([1]) - g = graph_no_feat.embed('rel', embedding_dim=d, **kwargs) + g = self.graph_no_feat.embed('rel', embedding_dim=self.d, **self.kwargs) g_new = g.predict_links(source, relation, destination, threshold=0, anomalous=False) self.assertTrue( g_new._edges.shape[0] > 0) @@ -56,44 +162,47 @@ def test_predict_links(self): self.assertIn("score", g_new._edges.columns) @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") def test_predict_links_all(self): - g = graph_no_feat.embed('rel', embedding_dim=d, **kwargs) + g = self.graph_no_feat.embed('rel', embedding_dim=self.d, **self.kwargs) g_new = g.predict_links_all(threshold=0) self.assertTrue( g_new._edges.shape[0] > 0) self.assertIn("score", g_new._edges.columns) @pytest.mark.skipif(not dep_flag, reason="requires ai feature dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") def test_chaining(self): - for name, g in graphs: + for name, g in self.graphs: logging.debug('name: %s test changing embedding dim with feats' % name) - g = g.embed('rel', use_feat=True, embedding_dim=d, **kwargs) - g2 = g.embed('rel', use_feat=True, embedding_dim=2 * d, **kwargs) + g = g.embed('rel', use_feat=True, embedding_dim=self.d, **self.kwargs) + g2 = g.embed('rel', use_feat=True, embedding_dim=2 * self.d, **self.kwargs) self.assertNotEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) - [g.reset_caches() for _, g in graphs] - for name, g in graphs: + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: logging.debug('name: %s test changing embedding dim without feats', name) - g = g.embed('rel', use_feat=False, embedding_dim=d, **kwargs) - g2 = g.embed('rel', use_feat=False, embedding_dim=2 * d, **kwargs) + g = g.embed('rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed('rel', use_feat=False, embedding_dim=2 * self.d, **self.kwargs) self.assertNotEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) - [g.reset_caches() for _, g in graphs] - for name, g in graphs: + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: logging.debug('name: %s test relationship change', name) - g = g.embed(relation='rel', use_feat=False, embedding_dim=d, **kwargs) - g2 = g.embed(relation='src', use_feat=False, embedding_dim=d, **kwargs) + g = g.embed(relation='rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed(relation='src', use_feat=False, embedding_dim=self.d, **self.kwargs) self.assertEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) self.assertNotEqual(np.linalg.norm(g._kg_embeddings - g2._kg_embeddings), 0) - [g.reset_caches() for _, g in graphs] - for name, g in graphs: + [g.reset_caches() for _, g in self.graphs] + for name, g in self.graphs: logging.debug('name: %s test relationship change', name) - g = g.embed(relation='rel', use_feat=False, embedding_dim=d, **kwargs) - g2 = g.embed(relation='rel', use_feat=True, embedding_dim=d, **kwargs) + g = g.embed(relation='rel', use_feat=False, embedding_dim=self.d, **self.kwargs) + g2 = g.embed(relation='rel', use_feat=True, embedding_dim=self.d, **self.kwargs) self.assertEqual(g._kg_embeddings.shape, g2._kg_embeddings.shape) self.assertNotEqual(np.linalg.norm(g._kg_embeddings - g2._kg_embeddings), 0) + if __name__ == "__main__": unittest.main() diff --git a/graphistry/tests/test_feature_utils.py b/graphistry/tests/test_feature_utils.py index f3738b3707..c357381365 100644 --- a/graphistry/tests/test_feature_utils.py +++ b/graphistry/tests/test_feature_utils.py @@ -15,13 +15,27 @@ process_nodes_dataframes, resolve_feature_engine, lazy_import_has_min_dependancy, + lazy_import_has_cu_cat_dependancy, lazy_import_has_dependancy_text, FastEncoder ) +from graphistry.features import topic_model, ngrams_model +from graphistry.constants import SCALERS + +np.random.seed(137) has_min_dependancy, _ = lazy_import_has_min_dependancy() has_min_dependancy_text, _, _ = lazy_import_has_dependancy_text() +has_cu_cat_dependancy_text, _, _ = lazy_import_has_cu_cat_dependancy() + +HAS_CUCAT = False +try: + import cu_cat, cudf + HAS_CUCAT = True +except: + cu_cat = object + cudf = pd logger = logging.getLogger(__name__) warnings.filterwarnings("ignore") @@ -127,7 +141,7 @@ target_names_node = [['label'], ['label', 'type']] # test also sending in a dataframe for target double_target_reddit = pd.DataFrame( - {"label": ndf_reddit.label.values, "type": ndf_reddit["type"].values} + {"label": ndf_reddit.label.values, "type": ndf_reddit["type"].values}, index=ndf_reddit.index ) single_target_reddit = pd.DataFrame({"label": ndf_reddit.label.values}) @@ -136,6 +150,14 @@ edge_df2['dst'] = np.random.random_integers(0, 120, size=len(edge_df2)) edge2_target_df = pd.DataFrame({'label': edge_df2.label}) +# ############################################################################################################# +what = ['whatever', 'on what', 'what do', 'what do you', 'what do you think', + 'to what', 'but what', 'what is', 'what it', 'what kind', 'what kind of', + 'of what', 'know what', 'what are', 'what are the', 'what to', 'what to do', + 'from what', 'with what', 'and what', 'what you', 'whats', 'know what to', 'don know what', 'what the'] +freedom = ['title: dyslexics, experience, language', + 'label: languagelearning, agile, leaves', + 'title: freedom, finally, moved'] # ################################################ # data to test textual and numeric DataFrame # ndf_stocks, price_df_stocks = get_stocks_dataframe() @@ -162,6 +184,44 @@ def check_allclose_fit_transform_on_same_data(X, x, Y=None, y=None): allclose_stats(Y, y, value, name) +class TestFeaturizeGetMethods(unittest.TestCase): + + @pytest.mark.skipif(not has_min_dependancy or not has_min_dependancy_text, reason="requires ai feature dependencies") + def setUp(self) -> None: + g = graphistry.nodes(ndf_reddit) + g2 = g.featurize(y=double_target_reddit, # ngrams + use_ngrams=True, + ngram_range=(1, 4) + ) + + g3 = g.featurize(**topic_model # topic model + ) + self.g = g + self.g2 = g2 + self.g3 = g3 + + @pytest.mark.skipif(not has_min_dependancy or not has_min_dependancy_text, reason="requires ai feature dependencies") + def test_get_col_matrix(self): + # no edges so this should be None + assert self.g2.get_matrix(kind='edges') is None + + # test target methods + assert all(self.g2.get_matrix(target=True).columns == self.g2._node_target.columns) + assert self.g2.get_matrix('Anxiety', target=True).shape[0] == len(self.g2._node_target) + # test str vs list + assert (self.g2.get_matrix('Anxiety', target=True) == self.g2.get_matrix(['Anxiety'], target=True)).all().values[0] + + # assert list(self.g2.get_matrix(['Anxiety', 'education', 'computer'], target=True).columns) == ['label_Anxiety', 'label_education', 'label_computervision'] + + # test feature methods + # ngrams + assert (self.g2.get_matrix().columns == self.g2._node_features.columns).all() + assert list(self.g2.get_matrix('what').columns) == what, list(self.g2.get_matrix('what').columns) + + # topic + assert all(self.g3.get_matrix().columns == self.g3._node_features.columns) + assert list(self.g3.get_matrix(['language', 'freedom']).columns) == freedom, self.g3.get_matrix(['language', 'freedom']).columns + class TestFastEncoder(unittest.TestCase): # we test how far off the fit returned values different from the transformed @@ -237,7 +297,8 @@ def test_process_node_dataframes_min_words(self): 2, 4000, ]: # last one should skip encoding, and throw all to dirty_cat - X_enc, y_enc, data_encoder, label_encoder, ordinal_pipeline, ordinal_pipeline_target, text_model, text_cols = process_nodes_dataframes( + + X_enc, y_enc, X_encs, y_encs, data_encoder, label_encoder, ordinal_pipeline, ordinal_pipeline_target, text_model, text_cols = process_nodes_dataframes( ndf_reddit, y=double_target_reddit, use_scaler=None, @@ -260,6 +321,74 @@ def test_multi_label_binarizer(self): assert y.shape == (4, 4) assert sum(y.sum(1).values - np.array([1., 2., 1., 0.])) == 0 +class TestFeatureCUMLProcessors(unittest.TestCase): + @pytest.mark.skipif(not lazy_import_has_cu_cat_dependancy, reason="requires cu_cat feature dependencies") + @pytest.mark.skipif(not HAS_CUCAT, reason="requires cu_cat, cudf") + def cases_tests(self, x, y, data_encoder, target_encoder, name, value): + self.assertIsInstance( + x, + cudf.DataFrame, + f"Returned data matrix is not cudf DataFrame for {name} {value}", + ) + self.assertFalse( + x.empty, + f"cudf DataFrame should not be empty for {name} {value}", + ) + self.assertIsInstance( + y, + pd.DataFrame, + f"Returned Target is not a cudf DataFrame for {name} {value}", + ) + self.assertFalse( + y.empty, + f"cudf Target DataFrame should not be empty for {name} {value}", + ) + self.assertIsInstance( + data_encoder, + cu_cat.super_vectorizer.TableVectorizer, + f"Data Encoder is not a cu_cat.super_vectorizer.TableVectorizer instance for {name} {value}", + ) + self.assertIsInstance( + target_encoder, + cu_cat.super_vectorizer.TableVectorizer, + f"Data Target Encoder is not a cu_cat.super_vectorizer.TableVectorizer instance for {name} {value}", + ) + + @pytest.mark.skipif(not lazy_import_has_cu_cat_dependancy, reason="requires cu_cat feature dependencies") + @pytest.mark.skipif(not HAS_CUCAT, reason="requires cu_cat, cudf") + def test_process_node_dataframes_min_words(self): + # test different target cardinality + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + for min_words in [ + 2, + 4000, + ]: # last one should skip encoding, and throw all to dirty_cat + + X_enc, y_enc, X_encs, y_encs, data_encoder, label_encoder, ordinal_pipeline, ordinal_pipeline_target, text_model, text_cols = process_nodes_dataframes( + ndf_reddit, + y=double_target_reddit, + use_scaler=None, + cardinality_threshold=40, + cardinality_threshold_target=40, + n_topics=20, + min_words=min_words, + model_name=model_avg_name, + feature_engine=resolve_feature_engine('auto') + ) + self.cases_tests(X_enc, y_enc, data_encoder, label_encoder, "min_words", min_words) + + @pytest.mark.skipif(not lazy_import_has_cu_cat_dependancy, reason="requires minimal feature dependencies") + @pytest.mark.skipif(not HAS_CUCAT, reason="requires cu_cat, cudf") + def test_multi_label_binarizer(self): + g = graphistry.nodes(bad_df) # can take in a list of lists and convert to multiOutput + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + g2 = g.featurize(y=['list_str'], X=['src'], multilabel=True) + y = g2._get_target('node') + assert y.shape == (4, 4) + assert sum(y.sum(1).values - np.array([1., 2., 1., 0.])) == 0 + class TestFeatureMethods(unittest.TestCase): def _check_attributes(self, g, attributes): @@ -370,19 +499,21 @@ def test_edge_featurization(self): def test_node_scaling(self): g = graphistry.nodes(ndf_reddit) g2 = g.featurize(X="title", y='label', use_scaler=None, use_scaler_target=None) - scalers = ['quantile', 'zscale', 'kbins', 'robust', 'minmax'] - for scaler in scalers: - a, b, c, d = g2.scale(ndf_reddit, single_target_reddit, kind='nodes', use_scaler=scaler, use_scaler_target=np.random.choice(scalers)) - - + for scaler in SCALERS: + X, y, c, d = g2.scale(ndf_reddit, single_target_reddit, kind='nodes', + use_scaler=scaler, + use_scaler_target=np.random.choice(SCALERS), + return_scalers=True) @pytest.mark.skipif(not has_min_dependancy or not has_min_dependancy_text, reason="requires ai feature dependencies") def test_edge_scaling(self): g = graphistry.edges(edge_df2, "src", "dst") g2 = g.featurize(y='label', kind='edges', use_scaler=None, use_scaler_target=None) - scalers = ['quantile', 'zscale', 'kbins', 'robust', 'minmax'] - for scaler in scalers: - a, b, c, d = g2.scale(edge_df2, edge2_target_df, kind='edges', use_scaler=scaler, use_scaler_target=np.random.choice(scalers)) + for scaler in SCALERS: + X, y, c, d = g2.scale(edge_df2, edge2_target_df, kind='edges', + use_scaler=scaler, + use_scaler_target=np.random.choice(SCALERS), + return_scalers=True) diff --git a/graphistry/tests/test_text_utils.py b/graphistry/tests/test_text_utils.py index b4ecc713af..710bdc5ece 100644 --- a/graphistry/tests/test_text_utils.py +++ b/graphistry/tests/test_text_utils.py @@ -55,18 +55,18 @@ def setUp(self): @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") def test_query(self): for g in [self.g_ngrams, self.g_emb]: - res, _ = g.query('How to set up DNS', thresh=100) + res, _ = g.search('How to set up DNS', thresh=100) assert not res.empty, f'Results DataFrame should not be empty, found {res}' @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") def test_query_graph(self): for name, g in zip(['ngrams', 'embedding'], [self.g_ngrams, self.g_emb]): - res = g.query_graph('How to set up DNS', thresh=100) + res = g.search_graph('How to set up DNS', thresh=100) assert not res._nodes.empty, f'{name}-Results DataFrame should not be empty, found {res._nodes}' #url = res.plot(render=False) #logger.info(f'{name}: {url}') - res = self.g_with_edges.query_graph('Wife', thresh=100) + res = self.g_with_edges.search_graph('Wife', thresh=100) assert not res._nodes.empty, f'Results DataFrame should not be empty, found {res._nodes}' #url = res.plot(render=False) #logger.info(f'With Explicit Edges: {url}') diff --git a/graphistry/tests/test_umap_utils.py b/graphistry/tests/test_umap_utils.py index ca0c3897ba..c6b4f0aa74 100644 --- a/graphistry/tests/test_umap_utils.py +++ b/graphistry/tests/test_umap_utils.py @@ -4,9 +4,12 @@ import warnings import graphistry + +import os import logging import numpy as np import pandas as pd +from graphistry import Plottable from graphistry.feature_utils import remove_internal_namespace_if_present from graphistry.tests.test_feature_utils import ( ndf_reddit, @@ -20,18 +23,31 @@ edge2_target_df, model_avg_name, lazy_import_has_min_dependancy, - check_allclose_fit_transform_on_same_data + check_allclose_fit_transform_on_same_data, +) +from graphistry.umap_utils import ( + lazy_umap_import_has_dependancy, + lazy_cuml_import_has_dependancy, + lazy_cudf_import_has_dependancy, ) -from graphistry.umap_utils import lazy_umap_import_has_dependancy, lazy_cuml_import_has_dependancy has_dependancy, _ = lazy_import_has_min_dependancy() has_cuml, _, _ = lazy_cuml_import_has_dependancy() +has_cudf, _, _ = lazy_cudf_import_has_dependancy() has_umap, _, _ = lazy_umap_import_has_dependancy() +has_cudf, _, cudf = lazy_cudf_import_has_dependancy() + +# print('has_dependancy', has_dependancy) +# print('has_cuml', has_cuml) +# print('has_cudf', has_cudf) +# print('has_umap', has_umap) logger = logging.getLogger(__name__) -warnings.filterwarnings('ignore') +warnings.filterwarnings("ignore") +# enable tests if has cudf and env didn't explicitly disable +is_test_cudf = has_cudf and os.environ["TEST_CUDF"] != "0" triangleEdges = pd.DataFrame( { @@ -65,74 +81,228 @@ class TestUMAPFitTransform(unittest.TestCase): # check to see that .fit and transform gives similar embeddings on same data @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") def setUp(self): - + verbose = True g = graphistry.nodes(ndf_reddit) + self.gn = g + self.test = ndf_reddit.sample(5) + + with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=FutureWarning) - g2 = g.umap(y=double_target_reddit, - use_ngrams=True, - ngram_range=(1, 2), - use_scaler='robust', - cardinality_threshold=2) - + g2 = g.umap( + y=['label', 'type'], + use_ngrams=True, + ngram_range=(1, 2), + use_scaler="robust", + cardinality_threshold=2, + verbose=verbose, + ) + + self.g2 = g2 fenc = g2._node_encoder self.X, self.Y = fenc.X, fenc.y self.EMB = g2._node_embedding - self.emb, self.x, self.y = g2.transform_umap(ndf_reddit, ydf=double_target_reddit, kind='nodes') + self.emb, self.x, self.y = g2.transform_umap( + ndf_reddit, ndf_reddit, kind="nodes", return_graph=False, verbose=verbose + ) + self.g3 = g2.transform_umap( + ndf_reddit, ndf_reddit, kind="nodes", return_graph=True, verbose=verbose + ) + # do the same for edges edge_df22 = edge_df2.copy() - edge_df22['rando'] = np.random.rand(edge_df2.shape[0]) - g = graphistry.edges(edge_df22, 'src', 'dst') + edge_df22["rando"] = np.random.rand(edge_df2.shape[0]) + g = graphistry.edges(edge_df22, "src", "dst") + self.ge = g with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=FutureWarning) - g2 = g.umap(y=edge2_target_df, kind='edges', - use_ngrams=True, - ngram_range=(1, 2), - use_scaler=None, - use_scaler_target=None, - cardinality_threshold=2, n_topics=4) - + g2 = g.umap( + y=['label'], + kind="edges", + use_ngrams=True, + ngram_range=(1, 2), + use_scaler=None, + use_scaler_target=None, + cardinality_threshold=2, + n_topics=4, + verbose=verbose, + ) + fenc = g2._edge_encoder self.Xe, self.Ye = fenc.X, fenc.y self.EMBe = g2._edge_embedding - self.embe, self.xe, self.ye = g2.transform_umap(edge_df22, ydf=edge2_target_df, kind='edges') - - # @pytest.mark.skipif(not has_dependancy, reason="requires umap feature dependencies") - # def test_allclose_fit_transform_on_same_data(self): - # check_allclose_fit_transform_on_same_data(self.X, self.x, self.Y, self.y) - # check_allclose_fit_transform_on_same_data(self.Xe, self.xe, self.Ye, self.ye) + self.embe, self.xe, self.ye = g2.transform_umap( + edge_df22, y=edge2_target_df, kind="edges", return_graph=False, verbose=verbose + ) + self.g2e = g2 - # check_allclose_fit_transform_on_same_data(self.EMB, self.emb, None, None) - # check_allclose_fit_transform_on_same_data(self.EMBe, self.embe, None, None) @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") def test_columns_match(self): - assert all(self.X.columns == self.x.columns), 'Node Feature Columns do not match' - assert all(self.Y.columns == self.y.columns), 'Node Target Columns do not match' - assert all(self.Xe.columns == self.xe.columns), 'Edge Feature Columns do not match' - assert all(self.Ye.columns == self.ye.columns), 'Edge Target Columns do not match' + assert set(self.X.columns) == set(self.x.columns), "Node Feature Columns do not match" + assert set(self.Y.columns) == set(self.y.columns), "Node Target Columns do not match" + assert set(self.Xe.columns) == set(self.xe.columns), "Edge Feature Columns do not match" + assert set(self.Ye.columns) == set(self.ye.columns), "Edge Target Columns do not match" + + @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") + def test_index_match(self): + # nodes + d = self.g2._nodes.shape[0] + de = self.g2e._edges.shape[0] + assert (self.gn._nodes.index == self.g2._nodes.index).sum() == d, "Node Indexes do not match" + assert (self.gn._nodes.index == self.EMB.index).sum() == d, "Emb Indexes do not match" + assert (self.gn._nodes.index == self.emb.index).sum() == d, "Transformed Emb Indexes do not match" + assert (self.gn._nodes.index == self.X.index).sum() == d, "Transformed Node features Indexes do not match" + assert (self.gn._nodes.index == self.y.index).sum() == d, "Transformed Node target Indexes do not match" + + # edges + assert (self.ge._edges.index == self.g2e._edges.index).sum() == de, "Edge Indexes do not match" + assert (self.ge._edges.index == self.EMBe.index).sum() == de, "Edge Emb Indexes do not match" + assert (self.ge._edges.index == self.embe.index).sum() == de, "Edge Transformed Emb Indexes do not match" + assert (self.ge._edges.index == self.Xe.index).sum() == de, "Edge Transformed features Indexes do not match" + assert (self.ge._edges.index == self.ye.index).sum() == de, "Edge Transformed target Indexes do not match" + + # make sure the indexes match at transform time internally as well + assert (self.X.index == self.x.index).sum() == d, "Node Feature Indexes do not match" + assert (self.Y.index == self.y.index).sum() == d, "Node Target Indexes do not match" + assert (self.Xe.index == self.xe.index).sum() == de, "Edge Feature Indexes do not match" + assert (self.Ye.index == self.ye.index).sum() == de, "Edge Target Indexes do not match" + + @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") + def test_node_index_match_in_infered_graph(self): + # nodes + g3 = self.g2._nodes + assert (g3.index == self.EMB.index).sum() == len(g3), "Node Emb Indexes do not match" + assert (g3.index == self.emb.index).sum() == len(g3), "Node Transformed Emb Indexes do not match" + assert (g3.index == self.X.index).sum() == len(g3), "Node Transformed features Indexes do not match" + assert (g3.index == self.y.index).sum() == len(g3), "Node Transformed target Indexes do not match" + + @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") + def test_edge_index_match_in_infered_graph(self): + g3 = self.g2e._edges + assert (g3.index == self.EMBe.index).sum() == len(g3), "Edge Emb Indexes do not match" + assert (g3.index == self.embe.index).sum() == len(g3), "Edge Transformed Emb Indexes do not match" + assert (g3.index == self.Xe.index).sum() == len(g3), "Edge Transformed Node features Indexes do not match" + assert (g3.index == self.ye.index).sum() == len(g3), "Edge Transformed Node target Indexes do not match" + + + @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") + def test_umap_kwargs(self): + umap_kwargs = { + "n_components": 2, + "metric": "euclidean", + "n_neighbors": 3, + "min_dist": 1, + "spread": 1, + "local_connectivity": 1, + "repulsion_strength": 1, + "negative_sample_rate": 5, + } + + umap_kwargs2 = {k: v + 1 for k, v in umap_kwargs.items() if k not in ['metric']} # type: ignore + umap_kwargs2['metric'] = 'euclidean' + g = graphistry.nodes(self.test) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + g2 = g.umap(**umap_kwargs, engine='umap_learn') + g3 = g.umap(**umap_kwargs2, engine='umap_learn') + assert g2._umap_params == umap_kwargs + assert ( + g2._umap_params == umap_kwargs + ), f"Umap params do not match, found {g2._umap_params} vs {umap_kwargs}" + assert len(g2._node_embedding.columns) == 2, f"Umap params do not match, found {len(g2._node_embedding.columns)} vs 2" + + assert ( + g3._umap_params == umap_kwargs2 + ), f"Umap params do not match, found {g3._umap_params} vs {umap_kwargs2}" + assert len(g3._node_embedding.columns) == 3, f"Umap params do not match, found {len(g3._node_embedding.columns)} vs 3" + + g4 = g2.transform_umap(self.test) + assert ( + g4._umap_params == umap_kwargs + ), f"Umap params do not match, found {g4._umap_params} vs {umap_kwargs}" + assert g4._n_components == 2, f"Umap params do not match, found {g2._n_components} vs 2" + + g5 = g3.transform_umap(self.test) + assert ( + g5._umap_params == umap_kwargs2 + ), f"Umap params do not match, found {g5._umap_params} vs {umap_kwargs2}" + + @pytest.mark.skipif(not has_umap, reason="requires umap feature dependencies") + def test_transform_umap(self): + np.random.seed(41) + test = self.test + assert ( + self.g2._node_embedding.shape[0] <= self.g3._node_embedding.shape[0] + ), "Node Embedding Lengths do not match, found {} and {}".format( + self.g2._node_embedding.shape[0], self.g3._node_embedding.shape[0] + ) + # now feed it args + min_dist = ["auto", 10] + sample = [None, 2] + return_graph = [True, False] + fit_umap_embedding = [True, False] + n_neighbors = [2, None] + for ep in min_dist: + g4 = self.g2.transform_umap(test, test, min_dist=ep) + assert True + for return_g in return_graph: + g4 = self.g2.transform_umap(test, test, return_graph=return_g) + if return_g: + assert True + else: + objs = (pd.DataFrame,) + if has_cudf: + objs = (pd.DataFrame, cudf.DataFrame) + assert len(g4) == 3 + assert isinstance(g4[0], objs) + assert isinstance(g4[1], objs) + assert isinstance(g4[2], objs) + assert g4[0].shape[1] == 2 + assert g4[1].shape[1] >= 2 + assert g4[2].shape[0] == test.shape[0] + for n_neigh in n_neighbors: + g4 = self.g2.transform_umap(test, n_neighbors=n_neigh) + assert True + for sample_ in sample: + print("sample", sample_) + g4 = self.g2.transform_umap(test, sample=sample_) + assert True + for fit_umap_embedding_ in fit_umap_embedding: + g4 = self.g2.transform_umap(test, fit_umap_embedding=fit_umap_embedding_) + assert True class TestUMAPMethods(unittest.TestCase): def _check_attributes(self, g, attributes): msg = "Graphistry instance after umap should have `{}` as attribute" msg2 = "Graphistry instance after umap should not have None values for `{}`" + objs = (pd.DataFrame,) + if has_cudf: + objs = (pd.DataFrame, cudf.DataFrame) for attribute in attributes: self.assertTrue(hasattr(g, attribute), msg.format(attribute)) self.assertTrue(getattr(g, attribute) is not None, msg2.format(attribute)) - if 'df' in attribute: - self.assertIsInstance(getattr(g, attribute), pd.DataFrame, msg.format(attribute)) - if 'node_' in attribute: - self.assertIsInstance(getattr(g, attribute), pd.DataFrame, msg.format(attribute)) - if 'edge_' in attribute: - self.assertIsInstance(getattr(g, attribute), pd.DataFrame, msg.format(attribute)) - + if "df" in attribute: + self.assertIsInstance( + getattr(g, attribute), objs, msg.format(attribute) + ) + if "node_" in attribute: + self.assertIsInstance( + getattr(g, attribute), objs, msg.format(attribute) + ) + if "edge_" in attribute: + self.assertIsInstance( + getattr(g, attribute), objs, msg.format(attribute) + ) def cases_check_node_attributes(self, g): attributes = [ @@ -195,6 +365,7 @@ def _test_umap(self, g, use_cols, targets, name, kind, df): model_name=model_avg_name, feature_engine=feature_engine, n_neighbors=2, + dbscan=False, ) self.cases_test_graph(g2, kind=kind, df=df) @@ -227,7 +398,9 @@ def test_edge_umap(self): df=triangleEdges, ) - @pytest.mark.skipif(not has_dependancy or not has_umap, reason="requires umap feature dependencies") + @pytest.mark.skipif( + not has_dependancy or not has_umap, reason="requires umap feature dependencies" + ) def test_filter_edges(self): for kind, g in [("nodes", graphistry.nodes(triangleNodes))]: g2 = g.umap(kind=kind, feature_engine="none") @@ -240,7 +413,9 @@ def test_filter_edges(self): f"{kind} -- scale: {scale}: resulting edges dataframe shape: {shape}" ) logger.debug("-" * 80) - self.assertGreaterEqual(shape[0], last_shape) # should return more and more edges + self.assertGreaterEqual( + shape[0], last_shape + ) # should return more and more edges last_shape = shape[0] @@ -252,27 +427,36 @@ class TestUMAPAIMethods(TestUMAPMethods): def _test_umap(self, g, use_cols, targets, name, kind, df): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) - for scaler in ['kbins', 'robust']: + for scaler in ["kbins", "robust"]: for cardinality in [2, 200]: for use_ngram in [True, False]: for use_col in use_cols: for target in targets: logger.debug("*" * 90) - value = [scaler, cardinality, use_ngram, target, use_col] + value = [ + scaler, + cardinality, + use_ngram, + target, + use_col, + ] logger.debug(f"{value}") logger.debug("-" * 80) - - g2 = g.umap(kind=kind, + + g2 = g.umap( + kind=kind, X=use_col, y=target, model_name=model_avg_name, use_scaler=scaler, use_scaler_target=scaler, use_ngrams=use_ngram, - engine='umap_learn', + engine="umap_learn", cardinality_threshold=cardinality, cardinality_threshold_target=cardinality, - n_neighbors=3) + n_neighbors=3, + dbscan=False, + ) self.cases_test_graph(g2, kind=kind, df=df) @@ -305,8 +489,8 @@ def test_node_umap(self): ) def test_edge_umap(self): g = graphistry.edges(edge_df2, "src", "dst") - targets = [None, 'label'] - use_cols = [None, 'title'] + targets = [None, "label"] + use_cols = [None, "title"] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) @@ -327,21 +511,23 @@ def test_edge_umap(self): ) def test_chaining_nodes(self): g = graphistry.nodes(ndf_reddit) - g2 = g.umap() + g2 = g.umap(dbscan=False) - logger.debug('======= g.umap() done ======') + logger.debug("======= g.umap() done ======") g3a = g2.featurize() - logger.debug('======= g3a.featurize() done ======') - g3 = g3a.umap() - logger.debug('======= g3.umap() done ======') + logger.debug("======= g3a.featurize() done ======") + g3 = g3a.umap(dbscan=False) + logger.debug("======= g3.umap() done ======") assert g2._node_features.shape == g3._node_features.shape # since g3 has feature params with x and y. - g3._feature_params['nodes']['X'].pop('x') - g3._feature_params['nodes']['X'].pop('y') - assert all(g2._feature_params['nodes']['X'] == g3._feature_params['nodes']['X']) - assert g2._feature_params['nodes']['y'].shape == g3._feature_params['nodes']['y'].shape # None + g3._feature_params["nodes"]["X"].pop("x") + g3._feature_params["nodes"]["X"].pop("y") + assert all(g2._feature_params["nodes"]["X"] == g3._feature_params["nodes"]["X"]) + assert ( + g2._feature_params["nodes"]["y"].shape == g3._feature_params["nodes"]["y"].shape + ) # None assert g2._node_embedding.shape == g3._node_embedding.shape # kinda weak sauce - + @pytest.mark.skipif( not has_dependancy or not has_umap, reason="requires ai+umap feature dependencies", @@ -352,11 +538,13 @@ def test_chaining_edges(self): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=FutureWarning) - g2 = g.umap(kind='edges') - g3 = g.featurize(kind='edges').umap(kind='edges') - - assert all(g2._feature_params['edges']['X'] == g3._feature_params['edges']['X']) - assert all(g2._feature_params['edges']['y'] == g3._feature_params['edges']['y']) # None + g2 = g.umap(kind="edges", dbscan=False) + g3 = g.featurize(kind="edges").umap(kind="edges", dbscan=False) + + assert all(g2._feature_params["edges"]["X"] == g3._feature_params["edges"]["X"]) + assert all( + g2._feature_params["edges"]["y"] == g3._feature_params["edges"]["y"] + ) # None assert all(g2._edge_features == g3._edge_features) @pytest.mark.skipif( @@ -366,19 +554,32 @@ def test_chaining_edges(self): def test_feature_kwargs_yield_different_values_using_umap_api(self): g = graphistry.nodes(ndf_reddit) n_topics_target = 6 - + with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) warnings.filterwarnings("ignore", category=FutureWarning) - g2 = g.umap(X="type", y="label", cardinality_threshold_target=3, n_topics_target=n_topics_target) # makes a GapEncoded Target - g3 = g.umap(X="type", y="label", cardinality_threshold_target=30000) # makes a one-hot-encoded target - - assert all(g2._feature_params['nodes']['X'] == g3._feature_params['nodes']['X']), "features should be the same" - assert all(g2._feature_params['nodes']['y'] != g3._feature_params['nodes']['y']), "targets in memoize should be different" # None - assert g2._node_target.shape[1] != g3._node_target.shape[1], 'Targets should be different' - assert g2._node_target.shape[1] == n_topics_target, 'Targets ' + g2 = g.umap( + X="type", + y="label", + cardinality_threshold_target=3, + n_topics_target=n_topics_target, + ) # makes a GapEncoded Target + g3 = g.umap( + X="type", y="label", cardinality_threshold_target=30000 + ) # makes a one-hot-encoded target + + assert all( + g2._feature_params["nodes"]["X"] == g3._feature_params["nodes"]["X"] + ), "features should be the same" + assert all( + g2._feature_params["nodes"]["y"] != g3._feature_params["nodes"]["y"] + ), "targets in memoize should be different" # None + assert ( + g2._node_target.shape[1] != g3._node_target.shape[1] + ), "Targets should be different" + assert g2._node_target.shape[1] == n_topics_target, "Targets " @pytest.mark.skipif( not has_dependancy or not has_umap, @@ -412,27 +613,35 @@ class TestCUMLMethods(TestUMAPMethods): def _test_umap(self, g, use_cols, targets, name, kind, df): with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) - for scaler in ['kbins', 'robust']: + for scaler in ["kbins", "robust"]: for cardinality in [2, 200]: for use_ngram in [True, False]: for use_col in use_cols: for target in targets: logger.debug("*" * 90) - value = [scaler, cardinality, use_ngram, target, use_col] - logger.debug(f"{value}") + value = [ + scaler, + cardinality, + use_ngram, + target, + use_col, + ] + logger.debug(f"{name}:\n{value}") logger.debug("-" * 80) - - g2 = g.umap(kind=kind, + + g2 = g.umap( + kind=kind, X=use_col, y=target, model_name=model_avg_name, use_scaler=scaler, use_scaler_target=scaler, use_ngrams=use_ngram, - engine='cuml', + engine="cuml", cardinality_threshold=cardinality, cardinality_threshold_target=cardinality, - n_neighbors=3) + n_neighbors=3, + ) self.cases_test_graph(g2, kind=kind, df=df) @@ -465,8 +674,8 @@ def test_node_umap(self): ) def test_edge_umap(self): g = graphistry.edges(edge_df2, "src", "dst") - targets = [None, 'label'] - use_cols = [None, 'title'] + targets = [None, "label"] + use_cols = [None, "title"] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) @@ -489,6 +698,200 @@ def test_chaining_nodes(self): g = graphistry.nodes(ndf_reddit) g2 = g.umap() + logger.debug("======= g.umap() done ======") + g3a = g2.featurize() + logger.debug("======= g3a.featurize() done ======") + g3 = g3a.umap() + logger.debug("======= g3.umap() done ======") + assert g2._node_features.shape == g3._node_features.shape, f"featurize() should be idempotent, found {g2._node_features.shape} != {g3._node_features.shape}" + # since g3 has feature params with x and y. + g3._feature_params["nodes"]["X"].pop("x") + g3._feature_params["nodes"]["X"].pop("y") + assert all(g2._feature_params["nodes"]["X"] == g3._feature_params["nodes"]["X"]) + assert ( + g2._feature_params["nodes"]["y"].shape == g3._feature_params["nodes"]["y"].shape + ) # None + assert g2._node_embedding.shape == g3._node_embedding.shape # kinda weak sauce + + @pytest.mark.skipif( + not has_dependancy or not has_cuml, + reason="requires cuml feature dependencies", + ) + def test_chaining_edges(self): + g = graphistry.edges(edge_df, "src", "dst") + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + g2 = g.umap(kind="edges") + g3 = g.featurize(kind="edges").umap(kind="edges") + + assert all(g2._feature_params["edges"]["X"] == g3._feature_params["edges"]["X"]) + assert all( + g2._feature_params["edges"]["y"] == g3._feature_params["edges"]["y"] + ) # None + assert all(g2._edge_features == g3._edge_features) + + @pytest.mark.skipif( + not has_dependancy or not has_cuml, + reason="requires cuml feature dependencies", + ) + def test_feature_kwargs_yield_different_values_using_umap_api(self): + g = graphistry.nodes(ndf_reddit) + n_topics_target = 6 + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + + g2 = g.umap( + X="type", + y="label", + cardinality_threshold_target=3, + n_topics_target=n_topics_target, + ) # makes a GapEncoded Target + g3 = g.umap( + X="type", y="label", cardinality_threshold_target=30000 + ) # makes a one-hot-encoded target + + assert all( + g2._feature_params["nodes"]["X"] == g3._feature_params["nodes"]["X"] + ), "features should be the same" + assert all( + g2._feature_params["nodes"]["y"] != g3._feature_params["nodes"]["y"] + ), "targets in memoize should be different" # None + assert ( + g2._node_target.shape[1] != g3._node_target.shape[1] + ), "Targets should be different" + assert g2._node_target.shape[1] == n_topics_target, "Targets " + + @pytest.mark.skipif( + not has_dependancy or not has_umap, + reason="requires cuml feature dependencies", + ) + def test_filter_edges(self): + for kind, g in [("nodes", graphistry.nodes(ndf_reddit))]: + g2 = g.umap(kind=kind, model_name=model_avg_name) + last_shape = 0 + for scale in np.linspace(0, 1, 8): # six sigma in 8 steps + g3 = g2.filter_weighted_edges(scale=scale) + shape = g3._edges.shape + logger.debug("*" * 90) + logger.debug( + f"{kind} -- scale: {scale}: resulting edges dataframe shape: {shape}" + ) + logger.debug("-" * 80) + self.assertGreaterEqual(shape[0], last_shape) + last_shape = shape[0] + +class TestCudfUmap(unittest.TestCase): + # temporary tests for cudf pass thru umap + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") + def setUp(self): + self.samples = 1000 + df = pd.DataFrame(np.random.randint(18,75,size=(self.samples, 1)), columns=['age']) + df['user_id'] = np.random.randint(0,200,size=(self.samples, 1)) + df['profile'] = np.random.randint(0,1000,size=(self.samples, 1)) + self.df = cudf.from_pandas(df) + + @pytest.mark.skipif(not has_dependancy or not has_cuml, reason="requires cuml dependencies") + @pytest.mark.skipif(not is_test_cudf, reason="requires cudf") + def test_base(self): + graphistry.nodes(self.df).umap('auto')._node_embedding.shape == (self.samples, 2) + graphistry.nodes(self.df).umap('engine')._node_embedding.shape == (self.samples, 2) + + +@pytest.mark.skipif( + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", +) +class TestCUDFMethods(TestUMAPMethods): + @pytest.mark.skipif( + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", + ) + def _test_umap(self, g, use_cols, targets, name, kind, df): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + for scaler in ['kbins', 'robust']: + for cardinality in [2, 200]: + for use_ngram in [True, False]: + for use_col in use_cols: + for target in targets: + logger.debug("*" * 90) + value = [scaler, cardinality, use_ngram, target, use_col] + logger.debug(f"{value}") + logger.debug("-" * 80) + + g = graphistry.nodes(cudf.from_pandas(ndf_reddit)) + g2 = g.umap(kind=kind, + X=use_col, + y=target, + model_name=model_avg_name, + use_scaler=scaler, + use_scaler_target=scaler, + use_ngrams=use_ngram, + engine='cudf', + cardinality_threshold=cardinality, + cardinality_threshold_target=cardinality, + n_neighbors=3) + + self.cases_test_graph(g2, kind=kind, df=df) + + @pytest.mark.skipif( + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", + ) + def test_node_umap(self): + g = graphistry.nodes(cudf.from_pandas(ndf_reddit)) + use_cols = [None, text_cols_reddit, good_cols_reddit, meta_cols_reddit] + targets = [None, single_target_reddit, double_target_reddit] + + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + + self._test_umap( + g, + use_cols=use_cols, + targets=targets, + name="Node UMAP with `(target, use_col)=`", + kind="nodes", + df=ndf_reddit, + ) + + @pytest.mark.skipif( + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", + ) + def test_edge_umap(self): + g = graphistry.nodes(cudf.from_pandas(edge_df2), "src", "dst") + targets = [None, 'label'] + use_cols = [None, 'title'] + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + warnings.filterwarnings("ignore", category=DeprecationWarning) + warnings.filterwarnings("ignore", category=FutureWarning) + + self._test_umap( + g, + use_cols=use_cols, + targets=targets, + name="Edge UMAP with `(target, use_col)=`", + kind="edges", + df=edge_df2, + ) + + @pytest.mark.skipif( + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", + ) + def test_chaining_nodes(self): + g = graphistry.nodes(cudf.from_pandas(ndf_reddit)) + g2 = g.umap() + logger.debug('======= g.umap() done ======') g3a = g2.featurize() logger.debug('======= g3a.featurize() done ======') @@ -503,11 +906,11 @@ def test_chaining_nodes(self): assert g2._node_embedding.shape == g3._node_embedding.shape # kinda weak sauce @pytest.mark.skipif( - not has_dependancy or not has_cuml, - reason="requires cuml feature dependencies", + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", ) def test_chaining_edges(self): - g = graphistry.edges(edge_df, "src", "dst") + g = graphistry.nodes(cudf.from_pandas(edge_df), "src", "dst") with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=UserWarning) warnings.filterwarnings("ignore", category=DeprecationWarning) @@ -520,11 +923,11 @@ def test_chaining_edges(self): assert all(g2._edge_features == g3._edge_features) @pytest.mark.skipif( - not has_dependancy or not has_cuml, - reason="requires cuml feature dependencies", + not has_dependancy or not has_cudf, + reason="requires cudf feature dependencies", ) def test_feature_kwargs_yield_different_values_using_umap_api(self): - g = graphistry.nodes(ndf_reddit) + g = graphistry.nodes(cudf.from_pandas(ndf_reddit)) n_topics_target = 6 with warnings.catch_warnings(): @@ -545,7 +948,7 @@ def test_feature_kwargs_yield_different_values_using_umap_api(self): reason="requires ai+umap feature dependencies", ) def test_filter_edges(self): - for kind, g in [("nodes", graphistry.nodes(ndf_reddit))]: + for kind, g in [("nodes", graphistry.nodes(cudf.from_pandas(ndf_reddit)))]: g2 = g.umap(kind=kind, model_name=model_avg_name) last_shape = 0 for scale in np.linspace(0, 1, 8): # six sigma in 8 steps diff --git a/graphistry/text_utils.py b/graphistry/text_utils.py index 6af12f3655..63fa5031d0 100644 --- a/graphistry/text_utils.py +++ b/graphistry/text_utils.py @@ -1,32 +1,23 @@ -import os -from time import time -import numpy as np import pandas as pd from .feature_utils import FeatureMixin -from .ai_utils import search_to_df, setup_logger -from .constants import WEIGHT, N_TREES, DISTANCE, VERBOSE, TRACE +from .ai_utils import search_to_df, FaissVectorSearch +from .constants import WEIGHT, DISTANCE +from logging import getLogger from typing import ( - Hashable, - List, - Union, - Dict, - Any, - Optional, - Tuple, - TYPE_CHECKING, - Type + TYPE_CHECKING, ) # noqa -logger = setup_logger(__name__, verbose=VERBOSE, fullpath=TRACE) - if TYPE_CHECKING: MIXIN_BASE = FeatureMixin else: MIXIN_BASE = object +logger = getLogger(__name__) + + class SearchToGraphMixin(MIXIN_BASE): def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) @@ -34,162 +25,156 @@ def __init__(self, *args, **kwargs) -> None: def assert_fitted(self): # assert self._umap is not None, 'Umap needs to be fit first, run g.umap(..) to fit a model' assert ( - self._get_feature('nodes') is not None - ), "Graphistry Instance is not fit, run g.featurize(kind='nodes', ..) to fit a model' \ + self._get_feature("nodes") is not None + ), "Graphistry Instance is not fit, run g.featurize(kind='nodes', ..) to fit a model ' \ 'if you have nodes & edges dataframe or g.umap(kind='nodes', ..) if you only have nodes dataframe" def assert_features_line_up_with_nodes(self): ndf = self._nodes - X = self._get_feature('nodes') + X = self._get_feature("nodes") a, b = ndf.shape[0], X.shape[0] - assert a == b, 'Nodes dataframe and feature vectors are not same size, '\ - f'found nodes: {a}, feats: {b}. Did you mutate nodes between fit?' + assert a == b, ( + "Nodes dataframe and feature vectors are not same size, " + f"found nodes: {a}, feats: {b}. Did you mutate nodes between fit?" + ) def build_index(self, angular=False, n_trees=None): - from annoy import AnnoyIndex # type: ignore # builds local index self.assert_fitted() self.assert_features_line_up_with_nodes() - - X = self._get_feature('nodes') - - logger.info(f"Building Index of size {X.shape}") - - if angular: - logger.info('-using angular metric') - metric = 'angular' - else: - logger.info('-using euclidean metric') - metric = 'euclidean' - - search_index = AnnoyIndex(X.shape[1], metric) - # Add all the feature vectors to the search index - for i in range(len(X)): - search_index.add_item(i, X.values[i]) - if n_trees is None: - n_trees = N_TREES - - logger.info(f'-building index with {n_trees} trees') - search_index.build(n_trees) - - self.search_index = search_index + X = self._get_feature("nodes") + if type(X) != pd.DataFrame: + print(f"Converting from {type(X)} to pandas for semantic search index") + X = X.to_pandas() + self.search_index = FaissVectorSearch( + X.values + ) # self._build_search_index(X, angular, n_trees, faiss=False) def _query_from_dataframe(self, qdf: pd.DataFrame, top_n: int, thresh: float): # Use the loaded featurizers to transform the dataframe - vect, _ = self.transform(qdf, None, kind="nodes") - - indices, distances = self.search_index.get_nns_by_vector( - vect.values[0], top_n, include_distances=True - ) - - results = self._nodes.iloc[indices] - results[DISTANCE] = distances - results = results.query(f"{DISTANCE} < {thresh}") + vect, _ = self.transform(qdf, None, kind="nodes", return_graph=False) - results = results.sort_values(by=[DISTANCE]) + results = self.search_index.search_df(vect, self._nodes, top_n) + results = results.query(f"{DISTANCE} < {thresh}") return results, vect - + def _query(self, query: str, top_n: int, thresh: float): # build the query dataframe - if not hasattr(self, 'search_index'): + if not hasattr(self, "search_index"): self.build_index() qdf = pd.DataFrame([]) - + cols_text = self._node_encoder.text_cols # type: ignore if len(cols_text) == 0: - logger.warn('** Querying is only possible using Transformer/Ngrams embeddings') + logger.warn( + "** Querying is only possible using Transformer/Ngrams embeddings" + ) return pd.DataFrame([]), None - + qdf[cols_text[0]] = [query] if len(cols_text) > 1: for col in cols_text[1:]: - qdf[col] = [''] + qdf[col] = [""] # this is hookey and needs to be fixed on dirty_cat side (with errors='ignore') - # if however min_words = 0, all columns will be textual, + # if however min_words = 0, all columns will be textual, # and no other data_encoder will be generated - if hasattr(self._node_encoder.data_encoder, 'columns_'): # type: ignore + if hasattr(self._node_encoder.data_encoder, "columns_"): # type: ignore other_cols = self._node_encoder.data_encoder.columns_ # type: ignore if other_cols is not None and len(other_cols): - logger.warn('** There is no easy way to encode categorical or other features at query time. ' - f'Set `thresh` to a large value if no results show up.\ncolumns: {other_cols}') + logger.warn( + "** There is no easy way to encode categorical or other features at query time. " + f"Set `thresh` to a large value if no results show up.\ncolumns: {other_cols}" + ) df = self._nodes dt = df[other_cols].dtypes for col, v in zip(other_cols, dt.values): if str(v) in ["string", "object", "category"]: - qdf[col] = df.sample(1)[col].values # so hookey + qdf[col] = df.sample(1)[col].values # so hookey elif str(v) in [ - "int", - "float", - "float64", - "float32", - "float16", - "int64", - "int32", - "int16", - "uint64", - "uint32", - "uint16", - ]: + "int", + "float", + "float64", + "float32", + "float16", + "int64", + "int32", + "int16", + "uint64", + "uint32", + "uint16", + ]: qdf[col] = df[col].mean() return self._query_from_dataframe(qdf, thresh=thresh, top_n=top_n) def search( - self, query: str, cols = None, thresh: float = 5000, fuzzy: bool = True, top_n: int = 10 - ): + self, + query: str, + cols=None, + thresh: float = 5000, + fuzzy: bool = True, + top_n: int = 10, + ): """Natural language query over nodes that returns a dataframe of results sorted by relevance column "distance". - If node data is not yet feature-encoded (and explicit edges are given), - run automatic feature engineering: - ``` - g2 = g.featurize(kind='nodes', X=['text_col_1', ..], + If node data is not yet feature-encoded (and explicit edges are given), + run automatic feature engineering: + :: + + g2 = g.featurize(kind='nodes', X=['text_col_1', ..], min_words=0 # forces all named columns are textually encoded - ) - ``` - - If edges do not yet exist, generate them via - ``` - g2 = g.umap(kind='nodes', X=['text_col_1', ..], + ) + + If edges do not yet exist, generate them via + :: + + g2 = g.umap(kind='nodes', X=['text_col_1', ..], min_words=0 # forces all named columns are textually encoded - ) - ``` + ) + If an index is not yet built, it is generated `g2.build_index()` on the fly at search time. - Otherwise, can set `g2.build_index()` and then subsequent `g2.search(...)` - calls will be not rebuilt index. + Otherwise, can set `g2.build_index()` to build it ahead of time. Args: - query (str): natural language query. - cols (list or str, optional): if fuzzy=False, select which column to query. + :query (str): natural language query. + :cols (list or str, optional): if fuzzy=False, select which column to query. Defaults to None since fuzzy=True by defaul. - thresh (float, optional): distance threshold from query vector to returned results. - Defaults to 5000, set large just in case, + :thresh (float, optional): distance threshold from query vector to returned results. + Defaults to 5000, set large just in case, but could be as low as 10. - fuzzy (bool, optional): if True, uses embedding + annoy index for recall, - otherwise does string matching over given `cols` + :fuzzy (bool, optional): if True, uses embedding + annoy index for recall, + otherwise does string matching over given `cols` Defaults to True. - top_n (int, optional): how many results to return. Defaults to 100. + :top_n (int, optional): how many results to return. Defaults to 100. Returns: - pd.DataFrame, vector_encoding_of_query: - * rank ordered dataframe of results matching query - * vector encoding of query via given transformer/ngrams model if fuzzy=True - else None + **pd.DataFrame, vector_encoding_of_query:** + rank ordered dataframe of results matching query + + vector encoding of query via given transformer/ngrams model if fuzzy=True else None """ if not fuzzy: if cols is None: - logger.error(f'Columns to search for `{query}` \ - need to be given when fuzzy=False, found {cols}') - + logger.error( + f"Columns to search for `{query}` \ + need to be given when fuzzy=False, found {cols}" + ) + logger.info(f"-- Word Match: [[ {query} ]]") return ( - pd.concat([search_to_df(query, col, self._nodes, as_string=True) for col in cols]), - None + pd.concat( + [ + search_to_df(query, col, self._nodes, as_string=True) + for col in cols + ] + ), + None, ) else: logger.info(f"-- Search: [[ {query} ]]") @@ -204,19 +189,19 @@ def search_graph( broader: bool = False, inplace: bool = False, ): - """Input a natural language query and return a graph of results. + """Input a natural language query and return a graph of results. See help(g.search) for more information Args: - query (str): query input eg "coding best practices" - scale (float, optional): edge weigh threshold, Defaults to 0.5. - top_n (int, optional): how many results to return. Defaults to 100. - thresh (float, optional): distance threshold from query vector to returned results. - Defaults to 5000, set large just in case, + :query (str): query input eg "coding best practices" + :scale (float, optional): edge weigh threshold, Defaults to 0.5. + :top_n (int, optional): how many results to return. Defaults to 100. + :thresh (float, optional): distance threshold from query vector to returned results. + Defaults to 5000, set large just in case, but could be as low as 10. - broader (bool, optional): if True, will retrieve entities connected via an edge + :broader (bool, optional): if True, will retrieve entities connected via an edge that were not necessarily bubbled up in the results_dataframe. Defaults to False. - inplace (bool, optional): whether to return new instance (default) or mutate self. + :inplace (bool, optional): whether to return new instance (default) or mutate self. Defaults to False. Returns: @@ -226,9 +211,11 @@ def search_graph( res = self else: res = self.bind() - + edf = edges = res._edges + # print('shape of edges', edf.shape) rdf = df = res._nodes + # print('shape of nodes', rdf.shape) node = res._node indices = rdf[node] src = res._source @@ -240,43 +227,55 @@ def search_graph( indices = rdf[node] # now get edges from indices if broader: # this will make a broader graph, finding NN in src OR dst - edges = edf[ - (edf[src].isin(indices)) | (edf[dst].isin(indices)) - ] - else: # finds only edges between results from query, if they exist, + edges = edf[(edf[src].isin(indices)) | (edf[dst].isin(indices))] + else: # finds only edges between results from query, if they exist, # default smaller graph - edges = edf[ - (edf[src].isin(indices)) & (edf[dst].isin(indices)) - ] + edges = edf[(edf[src].isin(indices)) & (edf[dst].isin(indices))] else: - logger.warn('**No results found due to empty DataFrame, returning original graph') + logger.warn( + "**No results found due to empty DataFrame, returning original graph" + ) return res - + try: # for umap'd edges edges = edges.query(f"{WEIGHT} > {scale}") except: # for explicit edges pass - + found_indices = pd.concat([edges[src], edges[dst], indices], axis=0).unique() + emb = None try: tdf = rdf.iloc[found_indices] - except: # for explicit relabeled nodes + feats = res._node_features.iloc[found_indices] # type: ignore + if res._umap is not None: + emb = res._node_embedding.iloc[found_indices] # type: ignore + except Exception as e: # for explicit relabeled nodes + logger.exception(e) tdf = rdf[df[node].isin(found_indices)] + feats = res._node_features.loc[tdf.index] # type: ignore + if res._umap is not None: + emb = res._node_embedding[df[node].isin(found_indices)] # type: ignore logger.info(f" - Returning edge dataframe of size {edges.shape[0]}") # get all the unique nodes - logger.info(f" - Returning {tdf.shape[0]} unique nodes given scale {scale} and thresh {thresh}") - + logger.info( + f" - Returning {tdf.shape[0]} unique nodes given scale {scale} and thresh {thresh}" + ) + g = res.edges(edges, src, dst).nodes(tdf, node) - + # add them back so they sync with .dbscan etc calls + g._node_features = feats + g._node_embedding = emb + if g._name is not None: - name = f'{g._name}-query:{query}' + name = f"{g._name}-query:{query}" else: - name = f'query:{query}' + name = f"query:{query}" g = g.name(name) # type: ignore return g def save_search_instance(self, savepath): from joblib import dump # type: ignore # need to make this onnx or similar + self.build_index() search = self.search_index del self.search_index # can't pickle Annoy @@ -287,6 +286,7 @@ def save_search_instance(self, savepath): @classmethod def load_search_instance(self, savepath): from joblib import load # type: ignore # need to make this onnx or similar + cls = load(savepath) cls.build_index() return cls diff --git a/graphistry/umap_utils.py b/graphistry/umap_utils.py index 5cd092f29d..f9a133ef26 100644 --- a/graphistry/umap_utils.py +++ b/graphistry/umap_utils.py @@ -1,17 +1,21 @@ import copy from time import time from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union +from inspect import getmodule import pandas as pd from . import constants as config +from .constants import CUML, UMAP_LEARN from .feature_utils import (FeatureMixin, Literal, XSymbolic, YSymbolic, prune_weighted_edges_df_and_relabel_nodes, resolve_feature_engine) from .PlotterBase import Plottable, WeakValueDictionary -from .util import check_set_memoize, setup_logger +from .util import check_set_memoize -logger = setup_logger(name=__name__, verbose=config.VERBOSE) +import logging + +logger = logging.getLogger(__name__) if TYPE_CHECKING: MIXIN_BASE = FeatureMixin @@ -39,22 +43,34 @@ def lazy_cuml_import_has_dependancy(): import warnings warnings.filterwarnings("ignore") - import cuml # type: ignore + with warnings.catch_warnings(): + warnings.filterwarnings("ignore") + import cuml # type: ignore return True, "ok", cuml except ModuleNotFoundError as e: return False, e, None +def lazy_cudf_import_has_dependancy(): + try: + import warnings + + warnings.filterwarnings("ignore") + import cudf # type: ignore + + return True, "ok", cudf + except ModuleNotFoundError as e: + return False, e, None def assert_imported(): - has_dependancy_, import_exn, umap_learn = lazy_umap_import_has_dependancy() + has_dependancy_, import_exn, _ = lazy_umap_import_has_dependancy() if not has_dependancy_: logger.error("UMAP not found, trying running " "`pip install graphistry[ai]`") raise import_exn def assert_imported_cuml(): - has_cuml_dependancy_, import_cuml_exn, cuml = lazy_cuml_import_has_dependancy() + has_cuml_dependancy_, import_cuml_exn, _ = lazy_cuml_import_has_dependancy() if not has_cuml_dependancy_: logger.warning("cuML not found, trying running " "`pip install cuml`") raise import_cuml_exn @@ -73,22 +89,22 @@ def is_legacy_cuml(): return False -UMAPEngineConcrete = Literal["cuml", "umap_learn"] +UMAPEngineConcrete = Literal['cuml', 'umap_learn'] UMAPEngine = Literal[UMAPEngineConcrete, "auto"] def resolve_umap_engine( engine: UMAPEngine, ) -> UMAPEngineConcrete: # noqa - if engine in ["cuml", "umap_learn"]: + if engine in [CUML, UMAP_LEARN]: return engine # type: ignore if engine in ["auto"]: - has_cuml_dependancy_, _, cuml = lazy_cuml_import_has_dependancy() + has_cuml_dependancy_, _, _ = lazy_cuml_import_has_dependancy() if has_cuml_dependancy_: - return "cuml" + return 'cuml' has_umap_dependancy_, _, _ = lazy_umap_import_has_dependancy() if has_umap_dependancy_: - return "umap_learn" + return 'umap_learn' raise ValueError( # noqa f'engine expected to be "auto", ' @@ -97,34 +113,34 @@ def resolve_umap_engine( ) -############################################################################### +def make_safe_gpu_dataframes(X, y, engine): + def safe_cudf(X, y): + # remove duplicate columns + if len(X.columns) != len(set(X.columns)): + X = X.loc[:, ~X.columns.duplicated()] + try: + y = y.loc[:, ~y.columns.duplicated()] + except: + pass + new_kwargs = {} + kwargs = {'X': X, 'y': y} + for key, value in kwargs.items(): + if isinstance(value, cudf.DataFrame) and engine in ["pandas", "umap_learn", "dirty_cat"]: + new_kwargs[key] = value.to_pandas() + elif isinstance(value, pd.DataFrame) and engine in ["cuml", "cu_cat"]: + new_kwargs[key] = cudf.from_pandas(value) + else: + new_kwargs[key] = value + return new_kwargs['X'], new_kwargs['y'] -umap_kwargs_probs = { - "n_components": 2, - "metric": "hellinger", # info metric, can't use on - # textual encodings since they contain negative values... - # unless scaling min max etc - "n_neighbors": 15, - "min_dist": 0.3, - "verbose": True, - "spread": 0.5, - "local_connectivity": 1, - "repulsion_strength": 1, - "negative_sample_rate": 5, -} - -umap_kwargs_euclidean = { - "n_components": 2, - "metric": "euclidean", - "n_neighbors": 12, - "min_dist": 0.1, - "verbose": True, - "spread": 0.5, - "local_connectivity": 1, - "repulsion_strength": 1, - "negative_sample_rate": 5, -} + has_cudf_dependancy_, _, cudf = lazy_cudf_import_has_dependancy() + if has_cudf_dependancy_: + return safe_cudf(X, y) + else: + return X, y + +############################################################################### # ############################################################################# # @@ -157,43 +173,47 @@ def umap_graph_to_weighted_edges(umap_graph, engine, is_legacy, cfg=config): class UMAPMixin(MIXIN_BASE): """ UMAP Mixin for automagic UMAPing - """ # FIXME where is this used? _umap_memoize: WeakValueDictionary = WeakValueDictionary() def __init__(self, *args, **kwargs): - self.umap_initialized = False + #self._umap_initialized = False + #self.engine = self.engine if hasattr(self, "engine") else None + pass + def umap_lazy_init( self, + res, n_neighbors: int = 12, min_dist: float = 0.1, - spread=0.5, - local_connectivity=1, - repulsion_strength=1, - negative_sample_rate=5, + spread: float = 0.5, + local_connectivity: int = 1, + repulsion_strength: float = 1, + negative_sample_rate: int = 5, n_components: int = 2, metric: str = "euclidean", engine: UMAPEngine = "auto", suffix: str = "", + verbose: bool = False, ): + from graphistry.features import ModelDict + engine_resolved = resolve_umap_engine(engine) # FIXME remove as set_new_kwargs will always replace? - if engine_resolved == "umap_learn": + if engine_resolved == UMAP_LEARN: _, _, umap_engine = lazy_umap_import_has_dependancy() - elif engine_resolved == "cuml": + elif engine_resolved == CUML: _, _, umap_engine = lazy_cuml_import_has_dependancy() else: raise ValueError( "No umap engine, ensure 'auto', 'umap_learn', or 'cuml', and the library is installed" ) - - if not self.umap_initialized: - umap_kwargs = dict( - { + umap_kwargs = ModelDict("UMAP Parameters", + **{ "n_components": n_components, - **({"metric": metric} if engine_resolved == "umap_learn" else {}), + **({"metric": metric} if engine_resolved == UMAP_LEARN else {}), # type: ignore "n_neighbors": n_neighbors, "min_dist": min_dist, "spread": spread, @@ -202,20 +222,31 @@ def umap_lazy_init( "negative_sample_rate": negative_sample_rate, } ) + + if getattr(res, '_umap_params', None) == umap_kwargs: + print('Same umap params as last time, skipping new init') if verbose else None + return res + + print('lazy init') if verbose else None + print(umap_kwargs) if verbose else None + # set new umap kwargs + res._umap_params = umap_kwargs + + res._n_components = n_components + res._metric = metric + res._n_neighbors = n_neighbors + res._min_dist = min_dist + res._spread = spread + res._local_connectivity = local_connectivity + res._repulsion_strength = repulsion_strength + res._negative_sample_rate = negative_sample_rate + res._umap = umap_engine.UMAP(**umap_kwargs) + res.engine = engine_resolved + res._suffix = suffix + + return res - self.n_components = n_components - self.metric = metric - self.n_neighbors = n_neighbors - self.min_dist = min_dist - self.spread = spread - self.local_connectivity = local_connectivity - self.repulsion_strength = repulsion_strength - self.negative_sample_rate = negative_sample_rate - self._umap = umap_engine.UMAP(**umap_kwargs) - self.umap_initialized = True - self.engine = engine_resolved - self.suffix = suffix - + #@safe_gpu_dataframes def _check_target_is_one_dimensional(self, y: Union[pd.DataFrame, None]): if y is None: return None @@ -229,8 +260,16 @@ def _check_target_is_one_dimensional(self, y: Union[pd.DataFrame, None]): "as it is not one dimensional" ) return None + + def _get_embedding(self, kind='nodes'): + if kind == 'nodes': + return self._node_embedding + elif kind == 'edges': + return self._edge_embedding + else: + raise ValueError('kind must be one of `nodes` or `edges`') - def umap_fit(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None): + def umap_fit(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None, verbose=False): if self._umap is None: raise ValueError("UMAP is not initialized") t = time() @@ -238,21 +277,20 @@ def umap_fit(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None): logger.info("-" * 90) logger.info(f"Starting UMAP-ing data of shape {X.shape}") - if self.engine == "cuml" and is_legacy_cuml(): + if self.engine == CUML and is_legacy_cuml(): # type: ignore from cuml.neighbors import NearestNeighbors - knn = NearestNeighbors(n_neighbors=self.n_neighbors) + knn = NearestNeighbors(n_neighbors=self._n_neighbors) # type: ignore cc = self._umap.fit(X, y, knn_graph=knn) knn.fit(cc.embedding_) self._umap.graph_ = knn.kneighbors_graph(cc.embedding_) - self._weighted_adjacency = self._umap.graph_ - else: self._umap.fit(X, y) - self._weighted_adjacency = self._umap.graph_ + + self._weighted_adjacency = self._umap.graph_ # if changing, also update fresh_res self._weighted_edges_df = umap_graph_to_weighted_edges( - self._umap.graph_, self.engine, is_legacy_cuml() + self._umap.graph_, self.engine, is_legacy_cuml() # type: ignore ) mins = (time() - t) / 60 @@ -260,35 +298,75 @@ def umap_fit(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None): logger.info(f" - or {X.shape[0]/mins:.2f} rows per minute") return self - def umap_fit_transform(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None): + + def _umap_fit_transform(self, X: pd.DataFrame, y: Union[pd.DataFrame, None] = None, verbose=False): if self._umap is None: raise ValueError("UMAP is not initialized") - self.umap_fit(X, y) + self.umap_fit(X, y, verbose=verbose) emb = self._umap.transform(X) emb = self._bundle_embedding(emb, index=X.index) return emb - def transform_umap( # noqa: E303 - self, df: pd.DataFrame, ydf: pd.DataFrame, kind: str = "nodes" - ) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: - try: - logger.debug(f"Going into Transform umap {df.shape}, {ydf.shape}") - except: - pass - x, y = self.transform(df, ydf, kind=kind) - emb = self._umap.transform(x) # type: ignore + + def transform_umap(self, df: pd.DataFrame, + y: Optional[pd.DataFrame] = None, + kind: str = 'nodes', + min_dist: Union[str, float, int] = 'auto', + n_neighbors: int = 7, + merge_policy: bool = False, + sample: Optional[int] = None, + return_graph: bool = True, + fit_umap_embedding: bool = True, + verbose: bool = False + ) -> Union[Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame], Plottable]: + """Transforms data into UMAP embedding + + Args: + :df: Dataframe to transform + :y: Target column + :kind: One of `nodes` or `edges` + :min_dist: Epsilon for including neighbors in infer_graph + :n_neighbors: Number of neighbors to use for contextualization + :merge_policy: if True, use previous graph, adding new batch to existing graph's neighbors + useful to contextualize new data against existing graph. If False, `sample` is irrelevant. + + sample: Sample number of existing graph's neighbors to use for contextualization -- helps make denser graphs + return_graph: Whether to return a graph or just the embeddings + fit_umap_embedding: Whether to infer graph from the UMAP embedding on the new data, default True + verbose: Whether to print information about the graph inference + """ + df, y = make_safe_gpu_dataframes(df, y, 'pandas') + X, y_ = self.transform(df, y, kind=kind, return_graph=False, verbose=verbose) + X, y_ = make_safe_gpu_dataframes(X, y_, self.engine) # type: ignore + emb = self._umap.transform(X) # type: ignore emb = self._bundle_embedding(emb, index=df.index) - return emb, x, y + if return_graph and kind not in ["edges"]: + emb, _ = make_safe_gpu_dataframes(emb, None, 'pandas') # for now so we don't have to touch infer_edges, force to pandas + X, y_ = make_safe_gpu_dataframes(X, y_, 'pandas') + g = self._infer_edges(emb, X, y_, df, + infer_on_umap_embedding=fit_umap_embedding, merge_policy=merge_policy, + eps=min_dist, sample=sample, n_neighbors=n_neighbors, + verbose=verbose) + return g + return emb, X, y_ def _bundle_embedding(self, emb, index): # Converts Embedding into dataframe and takes care if emb.dim > 2 - if emb.shape[1] == 2: + if emb.shape[1] == 2 and 'cudf.core.dataframe' not in str(getmodule(emb)) and not hasattr(emb, 'device'): emb = pd.DataFrame(emb, columns=[config.X, config.Y], index=index) + elif emb.shape[1] == 2 and 'cudf.core.dataframe' in str(getmodule(emb)): + emb.rename(columns={0: config.X, 1: config.Y}, inplace=True) + elif emb.shape[1] == 2 and hasattr(emb, 'device'): + import cudf + emb = cudf.DataFrame(emb, columns=[config.X, config.Y], index=index) else: columns = [config.X, config.Y] + [ - f"umap_{k}" for k in range(2, emb.shape[1] - 2) + f"umap_{k}" for k in range(2, emb.shape[1]) ] - emb = pd.DataFrame(emb, columns=columns, index=index) + if 'cudf.core.dataframe' not in str(getmodule(emb)): + emb = pd.DataFrame(emb, columns=columns, index=index) + elif 'cudf.core.dataframe' in str(getmodule(emb)): + emb.columns = columns return emb def _process_umap( @@ -299,31 +377,41 @@ def _process_umap( kind, memoize: bool, featurize_kwargs, + verbose = False, **umap_kwargs, ): """ Returns res mutated with new _xy """ - res._umap = self._umap + #from .features import ModelDict + umap_kwargs_pure = umap_kwargs.copy() logger.debug("process_umap before kwargs: %s", umap_kwargs) umap_kwargs.update({"kind": kind, "X": X_, "y": y_}) - umap_kwargs = {**umap_kwargs, "featurize_kwargs": featurize_kwargs or {}} - logger.debug("process_umap after kwargs: %s", umap_kwargs) + umap_kwargs_reuse = {**umap_kwargs, "featurize_kwargs": featurize_kwargs or {}} + logger.debug("process_umap after kwargs: %s", umap_kwargs_reuse) old_res = reuse_umap( - res, memoize, {**umap_kwargs, "featurize_kwargs": featurize_kwargs or {}} + res, memoize, {**umap_kwargs_reuse, "featurize_kwargs": featurize_kwargs or {}} ) if old_res: + print(" --- [[ RE-USING UMAP ]]") if verbose else None logger.info(" --- [[ RE-USING UMAP ]]") + print('umap previous n_components', umap_kwargs['n_components']) if verbose else None fresh_res = copy.copy(res) for attr in ["_xy", "_weighted_edges_df", "_weighted_adjacency"]: setattr(fresh_res, attr, getattr(old_res, attr)) # have to set _raw_data attribute on umap? fresh_res._umap = old_res._umap # this saves the day! + #fresh_res._umap_initialized = True + fresh_res._umap_params = umap_kwargs_pure return fresh_res - emb = res.umap_fit_transform(X_, y_) + print('-' * 60) if verbose else None + print('** Fitting UMAP') if verbose else None + res = res.umap_lazy_init(res, verbose=verbose, **umap_kwargs_pure) + + emb = res._umap_fit_transform(X_, y_, verbose=verbose) res._xy = emb return res @@ -366,9 +454,9 @@ def _set_features( # noqa: E303 def umap( self, - kind: str = "nodes", X: XSymbolic = None, y: YSymbolic = None, + kind: str = "nodes", scale: float = 1.0, n_neighbors: int = 12, min_dist: float = 0.1, @@ -382,58 +470,72 @@ def umap( play: Optional[int] = 0, encode_position: bool = True, encode_weight: bool = True, + dbscan: bool = False, engine: UMAPEngine = "auto", - inplace: bool = False, feature_engine: str = "auto", + inplace: bool = False, memoize: bool = True, + verbose: bool = False, **featurize_kwargs, ): - """ - UMAP the featurized node or edges data, - or pass in your own X, y (optional). - - :param kind: `nodes` or `edges` or None. - If None, expects explicit X, y (optional) matrices, - and will Not associate them to nodes or edges. - If X, y (optional) is given, with kind = [nodes, edges], - it will associate new matrices to nodes or edges attributes. - :param feature_engine: How to encode data - ("none", "auto", "pandas", "dirty_cat", "torch") - :param encode_weight: if True, will set new edges_df from - implicit UMAP, default True. - :param encode_position: whether to set default plotting bindings - -- positions x,y from umap for .plot() - :param X: either an ndarray of features, or column names to featurize - :param y: either an ndarray of targets, or column names to featurize - targets - :param scale: multiplicative scale for pruning weighted edge DataFrame - gotten from UMAP, between [0, ..) with high end meaning keep - all edges - :param n_neighbors: UMAP number of nearest neighbors to include for - UMAP connectivity, lower makes more compact layouts. Minimum 2 - :param min_dist: UMAP float between 0 and 1, lower makes more compact - layouts. - :param spread: UMAP spread of values for relaxation - :param local_connectivity: UMAP connectivity parameter - :param repulsion_strength: UMAP repulsion strength - :param negative_sample_rate: UMAP negative sampling rate - :param n_components: number of components in the UMAP projection, - default 2 - :param metric: UMAP metric, default 'euclidean'. - see (UMAP-LEARN)[https://umap-learn.readthedocs.io/ - en/latest/parameters.html] documentation for more. - :param suffix: optional suffix to add to x, y attributes of umap. - :param play: Graphistry play parameter, default 0, how much to evolve - the network during clustering - :param engine: selects which engine to use to calculate UMAP: - NotImplemented yet, default UMAP-LEARN - :param memoize: whether to memoize the results of this method, - default True. + """UMAP the featurized nodes or edges data, or pass in your own X, y (optional) dataframes of values + + Example + + >>> import graphistry + >>> g = graphistry.nodes(pd.DataFrame({'node': [0,1,2], 'data': [1,2,3], 'meta': ['a', 'b', 'c']})) + >>> g2 = g.umap(n_components=3, spread=1.0, min_dist=0.1, n_neighbors=12, negative_sample_rate=5, local_connectivity=1, repulsion_strength=1.0, metric='euclidean', suffix='', play=0, encode_position=True, encode_weight=True, dbscan=False, engine='auto', feature_engine='auto', inplace=False, memoize=True, verbose=False) + >>> g2.plot() + + Parameters + + :X: either a dataframe ndarray of features, or column names to featurize + :y: either an dataframe ndarray of targets, or column names to featurize + targets + :kind: `nodes` or `edges` or None. + If None, expects explicit X, y (optional) matrices, + and will Not associate them to nodes or edges. + If X, y (optional) is given, with kind = [nodes, edges], + it will associate new matrices to nodes or edges attributes. + :scale: multiplicative scale for pruning weighted edge DataFrame + gotten from UMAP, between [0, ..) with high end meaning keep + all edges + :n_neighbors: UMAP number of nearest neighbors to include for + UMAP connectivity, lower makes more compact layouts. Minimum 2 + :min_dist: UMAP float between 0 and 1, lower makes more compact + layouts. + :spread: UMAP spread of values for relaxation + :local_connectivity: UMAP connectivity parameter + :repulsion_strength: UMAP repulsion strength + :negative_sample_rate: UMAP negative sampling rate + :n_components: number of components in the UMAP projection, + default 2 + :metric: UMAP metric, default 'euclidean'. + see (UMAP-LEARN)[https://umap-learn.readthedocs.io/ + en/latest/parameters.html] documentation for more. + :suffix: optional suffix to add to x, y attributes of umap. + :play: Graphistry play parameter, default 0, how much to evolve + the network during clustering. 0 preserves the original UMAP layout. + :encode_weight: if True, will set new edges_df from + implicit UMAP, default True. + :encode_position: whether to set default plotting bindings + -- positions x,y from umap for .plot(), default True + :dbscan: whether to run DBSCAN on the UMAP embedding, default False. + :engine: selects which engine to use to calculate UMAP: + default "auto" will use cuML if available, otherwise UMAP-LEARN. + :feature_engine: How to encode data + ("none", "auto", "pandas", "dirty_cat", "torch") + :inplace: bool = False, whether to modify the current object, default False. + when False, returns a new object, useful for chaining in a functional paradigm. + :memoize: whether to memoize the results of this method, + default True. + :verbose: whether to print out extra information, default False. + :return: self, with attributes set with new data """ - if engine == "umap_learn": + if engine == UMAP_LEARN: assert_imported() - elif engine == "cuml": + elif engine == CUML: assert_imported_cuml() umap_kwargs = dict( @@ -446,16 +548,32 @@ def umap( repulsion_strength=repulsion_strength, negative_sample_rate=negative_sample_rate, engine=engine, + suffix=suffix, ) logger.debug("umap_kwargs: %s", umap_kwargs) + # temporary until we have full cudf support in feature_utils.py + has_cudf, _, cudf = lazy_cudf_import_has_dependancy() + + if has_cudf: + flag_nodes_cudf = isinstance(self._nodes, cudf.DataFrame) + flag_edges_cudf = isinstance(self._edges, cudf.DataFrame) + + if flag_nodes_cudf or flag_edges_cudf: + res = self + if flag_nodes_cudf: + res._nodes = res._nodes.to_pandas() + if flag_edges_cudf: + res._edges = res._edges.to_pandas() + res = res.umap(X=self._nodes, y=self._edges, **umap_kwargs) # type: ignore + return res + if inplace: res = self else: res = self.bind() - res.umap_lazy_init(engine=engine, suffix=suffix) - # res.suffix = suffix + res = res.umap_lazy_init(res, verbose=verbose, **umap_kwargs) # type: ignore logger.debug("umap input X :: %s", X) logger.debug("umap input y :: %s", y) @@ -463,12 +581,10 @@ def umap( featurize_kwargs = self._set_features( res, X, y, kind, feature_engine, {**featurize_kwargs, "memoize": memoize} ) - # umap_kwargs = {**umap_kwargs, - # 'featurize_kwargs': featurize_kwargs or {}} if kind == "nodes": + index = res._nodes.index if res._node is None: - logger.debug("-Writing new node name") res = res.nodes( # type: ignore res._nodes.reset_index(drop=True) @@ -476,9 +592,9 @@ def umap( .rename(columns={"index": config.IMPLICIT_NODE_ID}), config.IMPLICIT_NODE_ID, ) + res._nodes.index = index nodes = res._nodes[res._node].values - index_to_nodes_dict = dict(zip(range(len(nodes)), nodes)) logger.debug("propagating with featurize_kwargs: %s", featurize_kwargs) ( @@ -491,16 +607,23 @@ def umap( logger.debug("umap X_: %s", X_) logger.debug("umap y_: %s", y_) + logger.debug("data is type :: %s", (type(X_))) + if isinstance(X_, pd.DataFrame): + index_to_nodes_dict = dict(zip(range(len(nodes)), nodes)) + elif 'cudf.core.dataframe' in str(getmodule(X_)): + index_to_nodes_dict = nodes # {}? + + # add the safe coercion here + X_, y_ = make_safe_gpu_dataframes(X_, y_, res.engine) # type: ignore res = res._process_umap( - res, X_, y_, kind, memoize, featurize_kwargs, **umap_kwargs + res, X_, y_, kind, memoize, featurize_kwargs, verbose, **umap_kwargs ) res._weighted_adjacency_nodes = res._weighted_adjacency if res._xy is None: raise RuntimeError("This should not happen") res._node_embedding = res._xy - # TODO add edge filter so graph doesn't have double edges # TODO user-guidable edge merge policies like upsert? res._weighted_edges_df_from_nodes = ( prune_weighted_edges_df_and_relabel_nodes( @@ -520,6 +643,9 @@ def umap( **featurize_kwargs ) + # add the safe coercion here + X_, y_ = make_safe_gpu_dataframes(X_, y_, res.engine) # type: ignore + res = res._process_umap( res, X_, y_, kind, memoize, featurize_kwargs, **umap_kwargs ) @@ -539,9 +665,9 @@ def umap( "kind should be one of `nodes` or `edges` unless" "you are passing explicit matrices" ) - if X is not None and isinstance(X, pd.DataFrame): + if X is not None and isinstance(X, pd.DataFrame) or '': logger.info("New Matrix `X` passed in for UMAP-ing") - xy = res.umap_fit_transform(X, y) + xy = res._umap_fit_transform(X, y, verbose=verbose) res._xy = xy res._weighted_edges_df = prune_weighted_edges_df_and_relabel_nodes( res._weighted_edges_df, scale=scale @@ -553,7 +679,7 @@ def umap( else: logger.error( "If `kind` is `None`, `X` and optionally `y`" - "must be given and be of type pd.DataFrame" + "must be given." ) else: raise ValueError( @@ -563,9 +689,12 @@ def umap( res, kind, encode_position, encode_weight, play ) # noqa: E501 - if res.engine == "cuml" and is_legacy_cuml(): + if res.engine == CUML and is_legacy_cuml(): # type: ignore res = res.prune_self_edges() + if dbscan: + res = res.dbscan(min_dist=min_dist, kind=kind, fit_umap_embedding=True, verbose=verbose) # type: ignore + if not inplace: return res @@ -580,23 +709,26 @@ def _bind_xy_from_umap( df = res._nodes if kind == "nodes" else res._edges df = df.copy(deep=False) - x_name = config.X + res.suffix - y_name = config.Y + res.suffix + x_name = config.X + res._suffix + y_name = config.Y + res._suffix if kind == "nodes": emb = res._node_embedding else: emb = res._edge_embedding + + if type(df) == type(emb): + df[x_name] = emb.values.T[0] + df[y_name] = emb.values.T[1] + elif isinstance(df, pd.DataFrame) and 'cudf.core.dataframe' in str(getmodule(emb)): + df[x_name] = emb.to_numpy().T[0] + df[y_name] = emb.to_numpy().T[1] - df[x_name] = emb.values.T[0] # if embedding is greater - # than two dimensions will only take first two coordinates - df[y_name] = emb.values.T[1] - # res = res.nodes(df) if kind == "nodes" else res.edges(df) if encode_weight and kind == "nodes": # adds the implicit edge dataframe and binds it to # graphistry instance - w_name = config.WEIGHT + res.suffix + w_name = config.WEIGHT + res._suffix umap_edges_df = res._weighted_edges_df_from_nodes.copy(deep=False) umap_edges_df = umap_edges_df.rename(columns={config.WEIGHT: w_name}) res = res.edges(umap_edges_df, config.SRC, config.DST) @@ -625,6 +757,7 @@ def filter_weighted_edges( ): """ Filter edges based on _weighted_edges_df (ex: from .umap()) + """ if inplace: res = self diff --git a/graphistry/util.py b/graphistry/util.py index ce7249c934..025e8853b3 100644 --- a/graphistry/util.py +++ b/graphistry/util.py @@ -10,28 +10,31 @@ import warnings from functools import lru_cache from typing import Any +from collections import UserDict from .constants import VERBOSE, CACHE_COERCION_SIZE, TRACE # ##################################### + def global_logger(): logger = logging.getLogger() return logger + def setup_logger(name, verbose=VERBOSE, fullpath=TRACE): - #if fullpath: + # if fullpath: # FORMAT = "[%(filename)s:%(lineno)s - %(funcName)20s() ]\n %(message)s\n" - #else: + # else: # FORMAT = " %(message)s\n" - #logging.basicConfig(format=FORMAT) - #logger = logging.getLogger()#f'graphistry.{name}') - #if verbose is None: + # logging.basicConfig(format=FORMAT) + # logger = logging.getLogger()#f'graphistry.{name}') + # if verbose is None: # logger.setLevel(logging.ERROR) - #else: + # else: # logger.setLevel(logging.INFO if verbose else logging.DEBUG) - #return logger + # return logger return global_logger() @@ -39,6 +42,8 @@ def setup_logger(name, verbose=VERBOSE, fullpath=TRACE): # Caching utils _cache_coercion_val = None + + @lru_cache(maxsize=CACHE_COERCION_SIZE) def cache_coercion_helper(k): return _cache_coercion_val @@ -46,8 +51,8 @@ def cache_coercion_helper(k): def cache_coercion(k, v): """ - Holds references to last 100 used coercions - Use with weak key/value dictionaries for actual lookups + Holds references to last 100 used coercions + Use with weak key/value dictionaries for actual lookups """ global _cache_coercion_val _cache_coercion_val = v @@ -65,30 +70,37 @@ def __init__(self, v): def hash_pdf(df: pd.DataFrame) -> str: # can be 20% faster via to_parquet (see lmeyerov issue in pandas gh), but unclear if always available return ( - hashlib.sha256(putil.hash_pandas_object(df, index=True).to_numpy().tobytes()).hexdigest() - + hashlib.sha256(str(df.columns).encode('utf-8')).hexdigest() # noqa: W503 + hashlib.sha256( + putil.hash_pandas_object(df, index=True).to_numpy().tobytes() + ).hexdigest() + + hashlib.sha256(str(df.columns).encode("utf-8")).hexdigest() # noqa: W503 ) def hash_memoize_helper(v: Any) -> str: if isinstance(v, dict): - rolling = '{' + rolling = "{" + for k2, v2 in v.items(): + rolling += f"{k2}:{hash_memoize_helper(v2)}," + rolling += "}" + elif isinstance(v, ModelDict): + rolling = "{" for k2, v2 in v.items(): - rolling += f'{k2}:{hash_memoize_helper(v2)},' - rolling += '}' + rolling += f"{k2}:{hash_memoize_helper(v2)}," + rolling += "}" elif isinstance(v, list): - rolling = '[' + rolling = "[" for i in v: - rolling += f'{hash_memoize_helper(i)},' - rolling += ']' + rolling += f"{hash_memoize_helper(i)}," + rolling += "]" elif isinstance(v, tuple): - rolling = '(' + rolling = "(" for i in v: - rolling += f'{hash_memoize_helper(i)},' - rolling += ')' + rolling += f"{hash_memoize_helper(i)}," + rolling += ")" elif isinstance(v, bool): - rolling = 'T' if v else 'F' + rolling = "T" if v else "F" elif isinstance(v, int): rolling = str(v) elif isinstance(v, float): @@ -96,49 +108,54 @@ def hash_memoize_helper(v: Any) -> str: elif isinstance(v, str): rolling = v elif v is None: - rolling = 'N' + rolling = "N" elif isinstance(v, pd.DataFrame): rolling = hash_pdf(v) else: - raise TypeError(f'Unsupported memoization type: {type(v)}') + raise TypeError(f"Unsupported memoization type: {type(v)}") return rolling + def hash_memoize(v: Any) -> str: - return hashlib.sha256(hash_memoize_helper(v).encode('utf-8')).hexdigest() + return hashlib.sha256(hash_memoize_helper(v).encode("utf-8")).hexdigest() + -def check_set_memoize(g, metadata, attribute, name: str = '', memoize: bool = True): # noqa: C901 +def check_set_memoize( + g, metadata, attribute, name: str = "", memoize: bool = True +): # noqa: C901 """ - Helper Memoize function that checks if metadata args have changed for object g -- which is unconstrained save - for the fact that it must have `attribute`. If they have not changed, will return memoized version, - if False, will continue with whatever pipeline it is in front. + Helper Memoize function that checks if metadata args have changed for object g -- which is unconstrained save + for the fact that it must have `attribute`. If they have not changed, will return memoized version, + if False, will continue with whatever pipeline it is in front. """ - - logger = setup_logger(f'{__name__}.memoization') + + logger = setup_logger(f"{__name__}.memoization") if not memoize: - logger.debug('Memoization disabled') + logger.debug("Memoization disabled") return False - + hashed = None weakref = getattr(g, attribute) try: - hashed = hash_memoize(metadata) + hashed = hash_memoize(dict(data=metadata)) except TypeError: logger.warning( - f'! Failed {name} speedup attempt. Continuing without memoization speedups.' + f"! Failed {name} speedup attempt. Continuing without memoization speedups." ) try: if hashed in weakref: - logger.debug(f'{name} memoization hit: %s', hashed) + logger.debug(f"{name} memoization hit: %s", hashed) return weakref[hashed].v else: - logger.debug(f'{name} memoization miss for id (of %s): %s', - len(weakref), hashed) + logger.debug( + f"{name} memoization miss for id (of %s): %s", len(weakref), hashed + ) except: - logger.debug(f'Failed to hash {name} kwargs', exc_info=True) + logger.debug(f"Failed to hash {name} kwargs", exc_info=True) pass - + if memoize and (hashed is not None): w = WeakValueWrapper(g) cache_coercion(hashed, w) @@ -281,6 +298,90 @@ def deprecated_func(*args, **kwargs): return deprecated_decorator +# ############################################################################# +# MODEL Parameter HELPERS +def get_timestamp(): + import datetime + + return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + + +class ModelDict(UserDict): + """Helper class to print out model names and keep track of updates + + Args: + message: description of model + verbose: print out model names, logging happens regardless + """ + + def __init__(self, message, verbose=True, _timestamp=False, *args, **kwargs): + self._message = message + self._verbose = verbose + self._timestamp = _timestamp # do no use this inside the class, as it will trigger memoization. Only use outside of class. + L = ( + len(message) + if _timestamp is False + else max(len(message), len(get_timestamp()) + 1) + ) + self._print_length = min(80, L) + self._updates = [] + super().__init__(*args, **kwargs) + + def print(self, message): + if self._timestamp: + message = f"{message}\n{get_timestamp()}" + if self._verbose: + print("_" * self._print_length) + print() + print(message) + print("_" * self._print_length) + print() + + def __repr__(self): + # logger.info(self._message) + self.print(self._message) + return super().__repr__() + + # def __setitem__(self, key, value): # can't get this to work properly as it doesn't get called on update + # self._updates.append({key: value}) + # if len(self._updates) > 1: + # self._message += ( + # "\n" + "_" * self._print_length + f"\n\nUpdated: {self._updates[-1]}" + # ) + # return super().__setitem__(key, value) + + def update(self, *args, **kwargs): + self._updates.append(args[0]) + if len(self._updates) > 1: # don't take first update since its the init/default + self._message += ( + "\n" + "_" * self._print_length + f"\n\nUpdated: {self._updates[-1]}" + ) + return super().update(*args, **kwargs) + + +def is_notebook(): + """Check if running in a notebook""" + try: + from IPython import get_ipython + + if "IPKernelApp" not in get_ipython().config: # pragma: no cover + raise ImportError("console") + return False + if "VSCODE_PID" in os.environ: # pragma: no cover + raise ImportError("vscode") + return False + except: + return False + else: # pragma: no cover + return True + + +def printmd(string, color=None, size=20): + """Print markdown string in notebook""" + from IPython.display import Markdown, display + colorstr = "{}".format(color, size, string) + display(Markdown(colorstr)) + # # def inspect_decorator(func, args, kwargs): # import inspect diff --git a/mypy.ini b/mypy.ini index fd6b4d9ece..5b4403e91f 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -python_version = 3.7 +python_version = 3.8 # TODO check tests exclude = graph_vector_pb2|versioneer|_version|graphistry/tests @@ -31,6 +31,9 @@ ignore_missing_imports = True [mypy-dgl.*] ignore_missing_imports = True +[mypy-faiss.*] +ignore_missing_imports = True + [mypy-igraph.*] ignore_missing_imports = True @@ -90,4 +93,7 @@ ignore_missing_imports = True ignore_missing_imports = True [mypy-cuml.*] -ignore_missing_imports = True \ No newline at end of file +ignore_missing_imports = True + +[mypy-cu_cat.*] +ignore_missing_imports = true diff --git a/setup.py b/setup.py index 5817609f6a..3ad1513235 100755 --- a/setup.py +++ b/setup.py @@ -10,12 +10,13 @@ def unique_flatten_dict(d): core_requires = [ 'numpy', 'palettable >= 3.0', - 'pandas >= 0.17.0', + 'pandas < 2.0.0', 'pyarrow >= 0.15.0', 'requests', 'squarify', 'typing-extensions', - 'packaging >= 20.1' + 'packaging >= 20.1', + 'setuptools < 60.0.0', ] stubs = [ @@ -33,14 +34,18 @@ def unique_flatten_dict(d): 'networkx': ['networkx>=2.5'], 'gremlin': ['gremlinpython'], 'bolt': ['neo4j', 'neotime'], - 'nodexl': ['openpyxl', 'xlrd'], + 'nodexl': ['openpyxl==3.1.0', 'xlrd'], 'jupyter': ['ipython'], } base_extras_heavy = { 'umap-learn': ['umap-learn', 'dirty-cat==0.2.0', 'scikit-learn>=1.0'], } -base_extras_heavy['ai'] = base_extras_heavy['umap-learn'] + ['scipy', 'dgl', 'torch', 'sentence-transformers', 'annoy', 'joblib'] + +# https://github.com/facebookresearch/faiss/issues/1589 for faiss-cpu 1.6.1, #'setuptools==67.4.0' removed +base_extras_heavy['ai'] = base_extras_heavy['umap-learn'] + ['scipy', 'dgl', 'torch<2', 'sentence-transformers', 'faiss-cpu', 'joblib'] + +base_extras_heavy['cu_cat'] = base_extras_heavy['ai'] + ['cu_cat @ git+http://github.com/graphistry/cu-cat.git@0.03.0'] base_extras = {**base_extras_light, **base_extras_heavy}