From ce5b1207e09ef3a182222fe35d806ce3c9854437 Mon Sep 17 00:00:00 2001 From: Nathan Evans Date: Tue, 15 Oct 2024 12:58:58 -0700 Subject: [PATCH] Collapse graph documents workflows (#1284) * Copy base documents logic into final documents * Delete create_base_documents * Combine graph creation under create_base_entity_graph * Delete collapsed workflows * Migrate most graph internals to nx.Graph * Fix None edge case * Semver * Remove comment typo * Fix smoke tests --- .../patch-20241014220522452574.json | 4 + graphrag/index/create_pipeline_config.py | 27 +--- graphrag/index/flows/create_base_documents.py | 64 --------- .../index/flows/create_base_entity_graph.py | 97 ++++++++++--- .../flows/create_base_extracted_entities.py | 79 ----------- .../index/flows/create_final_documents.py | 59 +++++++- .../index/flows/create_summarized_entities.py | 50 ------- graphrag/index/operations/cluster_graph.py | 46 +++---- .../extract_entities/extract_entities.py | 21 ++- .../strategies/graph_intelligence.py | 4 +- .../extract_entities/strategies/nltk.py | 2 +- .../extract_entities/strategies/typing.py | 3 +- .../operations/merge_graphs/merge_graphs.py | 32 ++--- graphrag/index/operations/snapshot_graphml.py | 18 +++ .../summarize_descriptions.py | 56 ++------ graphrag/index/workflows/default_workflows.py | 21 --- .../workflows/v1/create_base_documents.py | 34 ----- .../workflows/v1/create_base_entity_graph.py | 67 ++++++++- .../v1/create_base_extracted_entities.py | 84 ------------ .../workflows/v1/create_final_covariates.py | 1 - .../workflows/v1/create_final_documents.py | 11 +- .../v1/create_summarized_entities.py | 36 ----- .../index/workflows/v1/subflows/__init__.py | 6 - .../v1/subflows/create_base_documents.py | 41 ------ .../v1/subflows/create_base_entity_graph.py | 32 ++++- .../create_base_extracted_entities.py | 63 --------- .../v1/subflows/create_final_documents.py | 5 + .../v1/subflows/create_summarized_entities.py | 51 ------- tests/fixtures/min-csv/config.json | 26 +--- tests/fixtures/text/config.json | 26 +--- tests/integration/_pipeline/megapipeline.yml | 13 +- .../test_gi_entity_extraction.py | 22 +-- .../verbs/data/create_base_documents.parquet | Bin 121089 -> 0 bytes .../create_base_extracted_entities.parquet | Bin 55577 -> 0 bytes .../data/create_summarized_entities.parquet | Bin 58252 -> 0 bytes tests/verbs/test_create_base_documents.py | 58 -------- tests/verbs/test_create_base_entity_graph.py | 107 +++++++++++---- .../test_create_base_extracted_entities.py | 118 ---------------- tests/verbs/test_create_final_documents.py | 29 +++- .../verbs/test_create_summarized_entities.py | 129 ------------------ tests/verbs/util.py | 2 +- 41 files changed, 446 insertions(+), 1098 deletions(-) create mode 100644 .semversioner/next-release/patch-20241014220522452574.json delete mode 100644 graphrag/index/flows/create_base_documents.py delete mode 100644 graphrag/index/flows/create_base_extracted_entities.py delete mode 100644 graphrag/index/flows/create_summarized_entities.py create mode 100644 graphrag/index/operations/snapshot_graphml.py delete mode 100644 graphrag/index/workflows/v1/create_base_documents.py delete mode 100644 graphrag/index/workflows/v1/create_base_extracted_entities.py delete mode 100644 graphrag/index/workflows/v1/create_summarized_entities.py delete mode 100644 graphrag/index/workflows/v1/subflows/create_base_documents.py delete mode 100644 graphrag/index/workflows/v1/subflows/create_base_extracted_entities.py delete mode 100644 graphrag/index/workflows/v1/subflows/create_summarized_entities.py delete mode 100644 tests/verbs/data/create_base_documents.parquet delete mode 100644 tests/verbs/data/create_base_extracted_entities.parquet delete mode 100644 tests/verbs/data/create_summarized_entities.parquet delete mode 100644 tests/verbs/test_create_base_documents.py delete mode 100644 tests/verbs/test_create_base_extracted_entities.py delete mode 100644 tests/verbs/test_create_summarized_entities.py diff --git a/.semversioner/next-release/patch-20241014220522452574.json b/.semversioner/next-release/patch-20241014220522452574.json new file mode 100644 index 00000000..ac1f1552 --- /dev/null +++ b/.semversioner/next-release/patch-20241014220522452574.json @@ -0,0 +1,4 @@ +{ + "type": "patch", + "description": "Collapse intermediate workflow outputs." +} diff --git a/graphrag/index/create_pipeline_config.py b/graphrag/index/create_pipeline_config.py index 0632ade2..e2778f3b 100644 --- a/graphrag/index/create_pipeline_config.py +++ b/graphrag/index/create_pipeline_config.py @@ -49,9 +49,7 @@ from graphrag.index.config.workflow import ( PipelineWorkflowReference, ) from graphrag.index.workflows.default_workflows import ( - create_base_documents, create_base_entity_graph, - create_base_extracted_entities, create_base_text_units, create_final_communities, create_final_community_reports, @@ -61,7 +59,6 @@ from graphrag.index.workflows.default_workflows import ( create_final_nodes, create_final_relationships, create_final_text_units, - create_summarized_entities, ) log = logging.getLogger(__name__) @@ -173,17 +170,12 @@ def _document_workflows( ) return [ PipelineWorkflowReference( - name=create_base_documents, + name=create_final_documents, config={ "document_attribute_columns": list( {*(settings.input.document_attribute_columns)} - builtin_document_attributes - ) - }, - ), - PipelineWorkflowReference( - name=create_final_documents, - config={ + ), "document_raw_content_embed": _get_embedding_settings( settings.embeddings, "document_raw_content", @@ -267,10 +259,9 @@ def _graph_workflows( ) return [ PipelineWorkflowReference( - name=create_base_extracted_entities, + name=create_base_entity_graph, config={ "graphml_snapshot": settings.snapshots.graphml, - "raw_entity_snapshot": settings.snapshots.raw_entities, "entity_extract": { **settings.entity_extraction.parallelization.model_dump(), "async_mode": settings.entity_extraction.async_mode, @@ -279,12 +270,6 @@ def _graph_workflows( ), "entity_types": settings.entity_extraction.entity_types, }, - }, - ), - PipelineWorkflowReference( - name=create_summarized_entities, - config={ - "graphml_snapshot": settings.snapshots.graphml, "summarize_descriptions": { **settings.summarize_descriptions.parallelization.model_dump(), "async_mode": settings.summarize_descriptions.async_mode, @@ -292,12 +277,6 @@ def _graph_workflows( settings.root_dir, ), }, - }, - ), - PipelineWorkflowReference( - name=create_base_entity_graph, - config={ - "graphml_snapshot": settings.snapshots.graphml, "embed_graph_enabled": settings.embed_graph.enabled, "cluster_graph": { "strategy": settings.cluster_graph.resolved_strategy() diff --git a/graphrag/index/flows/create_base_documents.py b/graphrag/index/flows/create_base_documents.py deleted file mode 100644 index 3f1ba29e..00000000 --- a/graphrag/index/flows/create_base_documents.py +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""Transform base documents by joining them with their text_units and adding optional attributes.""" - -import pandas as pd - - -def create_base_documents( - documents: pd.DataFrame, - text_units: pd.DataFrame, - document_attribute_columns: list[str] | None = None, -) -> pd.DataFrame: - """Transform base documents by joining them with their text_units and adding optional attributes.""" - exploded = ( - text_units.explode("document_ids") - .loc[:, ["id", "document_ids", "text"]] - .rename( - columns={ - "document_ids": "chunk_doc_id", - "id": "chunk_id", - "text": "chunk_text", - } - ) - ) - - joined = exploded.merge( - documents, - left_on="chunk_doc_id", - right_on="id", - how="inner", - copy=False, - ) - - docs_with_text_units = joined.groupby("id", sort=False).agg( - text_units=("chunk_id", list) - ) - - rejoined = docs_with_text_units.merge( - documents, - on="id", - how="right", - copy=False, - ).reset_index(drop=True) - - rejoined.rename(columns={"text": "raw_content"}, inplace=True) - rejoined["id"] = rejoined["id"].astype(str) - - # Convert attribute columns to strings and collapse them into a JSON object - if document_attribute_columns: - # Convert all specified columns to string at once - rejoined[document_attribute_columns] = rejoined[ - document_attribute_columns - ].astype(str) - - # Collapse the document_attribute_columns into a single JSON object column - rejoined["attributes"] = rejoined[document_attribute_columns].to_dict( - orient="records" - ) - - # Drop the original attribute columns after collapsing them - rejoined.drop(columns=document_attribute_columns, inplace=True) - - return rejoined diff --git a/graphrag/index/flows/create_base_entity_graph.py b/graphrag/index/flows/create_base_entity_graph.py index 39880a45..68ae2193 100644 --- a/graphrag/index/flows/create_base_entity_graph.py +++ b/graphrag/index/flows/create_base_entity_graph.py @@ -7,26 +7,76 @@ from typing import Any, cast import pandas as pd from datashaper import ( + AsyncType, VerbCallbacks, ) +from graphrag.index.cache import PipelineCache from graphrag.index.operations.cluster_graph import cluster_graph from graphrag.index.operations.embed_graph import embed_graph +from graphrag.index.operations.extract_entities import extract_entities +from graphrag.index.operations.merge_graphs import merge_graphs +from graphrag.index.operations.snapshot import snapshot +from graphrag.index.operations.snapshot_graphml import snapshot_graphml from graphrag.index.operations.snapshot_rows import snapshot_rows +from graphrag.index.operations.summarize_descriptions import ( + summarize_descriptions, +) from graphrag.index.storage import PipelineStorage async def create_base_entity_graph( - entities: pd.DataFrame, + text_units: pd.DataFrame, callbacks: VerbCallbacks, + cache: PipelineCache, storage: PipelineStorage, + text_column: str, + id_column: str, clustering_strategy: dict[str, Any], - embedding_strategy: dict[str, Any] | None, + extraction_strategy: dict[str, Any] | None = None, + extraction_num_threads: int = 4, + extraction_async_mode: AsyncType = AsyncType.AsyncIO, + entity_types: list[str] | None = None, + node_merge_config: dict[str, Any] | None = None, + edge_merge_config: dict[str, Any] | None = None, + summarization_strategy: dict[str, Any] | None = None, + summarization_num_threads: int = 4, + embedding_strategy: dict[str, Any] | None = None, graphml_snapshot_enabled: bool = False, + raw_entity_snapshot_enabled: bool = False, ) -> pd.DataFrame: """All the steps to create the base entity graph.""" + # this returns a graph for each text unit, to be merged later + entities, entity_graphs = await extract_entities( + text_units, + callbacks, + cache, + text_column=text_column, + id_column=id_column, + strategy=extraction_strategy, + async_mode=extraction_async_mode, + entity_types=entity_types, + to="entities", + num_threads=extraction_num_threads, + ) + + merged_graph = merge_graphs( + entity_graphs, + callbacks, + node_operations=node_merge_config, + edge_operations=edge_merge_config, + ) + + summarized = await summarize_descriptions( + merged_graph, + callbacks, + cache, + strategy=summarization_strategy, + num_threads=summarization_num_threads, + ) + clustered = cluster_graph( - entities, + summarized, callbacks, column="entity_graph", strategy=clustering_strategy, @@ -34,15 +84,6 @@ async def create_base_entity_graph( level_to="level", ) - if graphml_snapshot_enabled: - await snapshot_rows( - clustered, - column="clustered_graph", - base_name="clustered_graph", - storage=storage, - formats=[{"format": "text", "extension": "graphml"}], - ) - if embedding_strategy: clustered["embeddings"] = await embed_graph( clustered, @@ -51,16 +92,40 @@ async def create_base_entity_graph( strategy=embedding_strategy, ) - # take second snapshot after embedding - # todo: this could be skipped if embedding isn't performed, other wise it is a copy of the regular graph? + if raw_entity_snapshot_enabled: + await snapshot( + entities, + name="raw_extracted_entities", + storage=storage, + formats=["json"], + ) + if graphml_snapshot_enabled: + await snapshot_graphml( + merged_graph, + name="merged_graph", + storage=storage, + ) + await snapshot_graphml( + summarized, + name="summarized_graph", + storage=storage, + ) await snapshot_rows( clustered, - column="entity_graph", - base_name="embedded_graph", + column="clustered_graph", + base_name="clustered_graph", storage=storage, formats=[{"format": "text", "extension": "graphml"}], ) + if embedding_strategy: + await snapshot_rows( + clustered, + column="entity_graph", + base_name="embedded_graph", + storage=storage, + formats=[{"format": "text", "extension": "graphml"}], + ) final_columns = ["level", "clustered_graph"] if embedding_strategy: diff --git a/graphrag/index/flows/create_base_extracted_entities.py b/graphrag/index/flows/create_base_extracted_entities.py deleted file mode 100644 index bfbf4d23..00000000 --- a/graphrag/index/flows/create_base_extracted_entities.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""All the steps to extract and format covariates.""" - -from typing import Any - -import pandas as pd -from datashaper import ( - AsyncType, - VerbCallbacks, -) - -from graphrag.index.cache import PipelineCache -from graphrag.index.operations.extract_entities import extract_entities -from graphrag.index.operations.merge_graphs import merge_graphs -from graphrag.index.operations.snapshot import snapshot -from graphrag.index.operations.snapshot_rows import snapshot_rows -from graphrag.index.storage import PipelineStorage - - -async def create_base_extracted_entities( - text_units: pd.DataFrame, - callbacks: VerbCallbacks, - cache: PipelineCache, - storage: PipelineStorage, - column: str, - id_column: str, - nodes: dict[str, Any], - edges: dict[str, Any], - extraction_strategy: dict[str, Any] | None, - async_mode: AsyncType = AsyncType.AsyncIO, - entity_types: list[str] | None = None, - graphml_snapshot_enabled: bool = False, - raw_entity_snapshot_enabled: bool = False, - num_threads: int = 4, -) -> pd.DataFrame: - """All the steps to extract and format covariates.""" - entity_graph = await extract_entities( - text_units, - callbacks, - cache, - column=column, - id_column=id_column, - strategy=extraction_strategy, - async_mode=async_mode, - entity_types=entity_types, - to="entities", - graph_to="entity_graph", - num_threads=num_threads, - ) - - if raw_entity_snapshot_enabled: - await snapshot( - entity_graph, - name="raw_extracted_entities", - storage=storage, - formats=["json"], - ) - - merged_graph = merge_graphs( - entity_graph, - callbacks, - column="entity_graph", - to="entity_graph", - nodes=nodes, - edges=edges, - ) - - if graphml_snapshot_enabled: - await snapshot_rows( - merged_graph, - base_name="merged_graph", - column="entity_graph", - storage=storage, - formats=[{"format": "text", "extension": "graphml"}], - ) - - return merged_graph diff --git a/graphrag/index/flows/create_final_documents.py b/graphrag/index/flows/create_final_documents.py index 29504000..29f28e52 100644 --- a/graphrag/index/flows/create_final_documents.py +++ b/graphrag/index/flows/create_final_documents.py @@ -14,20 +14,71 @@ from graphrag.index.operations.embed_text import embed_text async def create_final_documents( documents: pd.DataFrame, + text_units: pd.DataFrame, callbacks: VerbCallbacks, cache: PipelineCache, + document_attribute_columns: list[str] | None = None, raw_content_text_embed: dict | None = None, ) -> pd.DataFrame: """All the steps to transform final documents.""" - documents.rename(columns={"text_units": "text_unit_ids"}, inplace=True) + exploded = ( + text_units.explode("document_ids") + .loc[:, ["id", "document_ids", "text"]] + .rename( + columns={ + "document_ids": "chunk_doc_id", + "id": "chunk_id", + "text": "chunk_text", + } + ) + ) + + joined = exploded.merge( + documents, + left_on="chunk_doc_id", + right_on="id", + how="inner", + copy=False, + ) + + docs_with_text_units = joined.groupby("id", sort=False).agg( + text_units=("chunk_id", list) + ) + + rejoined = docs_with_text_units.merge( + documents, + on="id", + how="right", + copy=False, + ).reset_index(drop=True) + + rejoined.rename( + columns={"text": "raw_content", "text_units": "text_unit_ids"}, inplace=True + ) + rejoined["id"] = rejoined["id"].astype(str) + + # Convert attribute columns to strings and collapse them into a JSON object + if document_attribute_columns: + # Convert all specified columns to string at once + rejoined[document_attribute_columns] = rejoined[ + document_attribute_columns + ].astype(str) + + # Collapse the document_attribute_columns into a single JSON object column + rejoined["attributes"] = rejoined[document_attribute_columns].to_dict( + orient="records" + ) + + # Drop the original attribute columns after collapsing them + rejoined.drop(columns=document_attribute_columns, inplace=True) if raw_content_text_embed: - documents["raw_content_embedding"] = await embed_text( - documents, + rejoined["raw_content_embedding"] = await embed_text( + rejoined, callbacks, cache, column="raw_content", strategy=raw_content_text_embed["strategy"], ) - return documents + return rejoined diff --git a/graphrag/index/flows/create_summarized_entities.py b/graphrag/index/flows/create_summarized_entities.py deleted file mode 100644 index a9a5d59a..00000000 --- a/graphrag/index/flows/create_summarized_entities.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""All the steps to summarize entities.""" - -from typing import Any - -import pandas as pd -from datashaper import ( - VerbCallbacks, -) - -from graphrag.index.cache import PipelineCache -from graphrag.index.operations.snapshot_rows import snapshot_rows -from graphrag.index.operations.summarize_descriptions import ( - summarize_descriptions, -) -from graphrag.index.storage import PipelineStorage - - -async def create_summarized_entities( - entities: pd.DataFrame, - callbacks: VerbCallbacks, - cache: PipelineCache, - storage: PipelineStorage, - summarization_strategy: dict[str, Any] | None = None, - num_threads: int = 4, - graphml_snapshot_enabled: bool = False, -) -> pd.DataFrame: - """All the steps to summarize entities.""" - summarized = await summarize_descriptions( - entities, - callbacks, - cache, - column="entity_graph", - to="entity_graph", - strategy=summarization_strategy, - num_threads=num_threads, - ) - - if graphml_snapshot_enabled: - await snapshot_rows( - summarized, - column="entity_graph", - base_name="summarized_graph", - storage=storage, - formats=[{"format": "text", "extension": "graphml"}], - ) - - return summarized diff --git a/graphrag/index/operations/cluster_graph.py b/graphrag/index/operations/cluster_graph.py index 731c4b5b..b993789d 100644 --- a/graphrag/index/operations/cluster_graph.py +++ b/graphrag/index/operations/cluster_graph.py @@ -14,7 +14,7 @@ from datashaper import VerbCallbacks, progress_iterable from graspologic.partition import hierarchical_leiden from graphrag.index.graph.utils import stable_largest_connected_component -from graphrag.index.utils import gen_uuid, load_graph +from graphrag.index.utils import gen_uuid Communities = list[tuple[int, str, list[str]]] @@ -33,7 +33,7 @@ log = logging.getLogger(__name__) def cluster_graph( - input: pd.DataFrame, + input: nx.Graph, callbacks: VerbCallbacks, strategy: dict[str, Any], column: str, @@ -41,63 +41,64 @@ def cluster_graph( level_to: str | None = None, ) -> pd.DataFrame: """Apply a hierarchical clustering algorithm to a graph.""" - results = input[column].apply(lambda graph: run_layout(strategy, graph)) + output = pd.DataFrame() + # TODO: for back-compat, downstream expects a graphml string + output[column] = ["\n".join(nx.generate_graphml(input))] + communities = run_layout(strategy, input) community_map_to = "communities" - input[community_map_to] = results + output[community_map_to] = [communities] level_to = level_to or f"{to}_level" - input[level_to] = input.apply( + output[level_to] = output.apply( lambda x: list({level for level, _, _ in x[community_map_to]}), axis=1 ) - input[to] = None + output[to] = None - num_total = len(input) + num_total = len(output) # Create a seed for this run (if not provided) seed = strategy.get("seed", Random().randint(0, 0xFFFFFFFF)) # noqa S311 # Go through each of the rows graph_level_pairs_column: list[list[tuple[int, str]]] = [] - for _, row in progress_iterable(input.iterrows(), callbacks.progress, num_total): + for _, row in progress_iterable(output.iterrows(), callbacks.progress, num_total): levels = row[level_to] graph_level_pairs: list[tuple[int, str]] = [] # For each of the levels, get the graph and add it to the list for level in levels: - graph = "\n".join( + graphml = "\n".join( nx.generate_graphml( apply_clustering( - cast(str, row[column]), + input, cast(Communities, row[community_map_to]), level, seed=seed, ) ) ) - graph_level_pairs.append((level, graph)) + graph_level_pairs.append((level, graphml)) graph_level_pairs_column.append(graph_level_pairs) - input[to] = graph_level_pairs_column + output[to] = graph_level_pairs_column # explode the list of (level, graph) pairs into separate rows - input = input.explode(to, ignore_index=True) + output = output.explode(to, ignore_index=True) # split the (level, graph) pairs into separate columns # TODO: There is probably a better way to do this - input[[level_to, to]] = pd.DataFrame(input[to].tolist(), index=input.index) + output[[level_to, to]] = pd.DataFrame(output[to].tolist(), index=output.index) # clean up the community map - input.drop(columns=[community_map_to], inplace=True) - return input + output.drop(columns=[community_map_to], inplace=True) + return output -# TODO: This should support str | nx.Graph as a graphml param def apply_clustering( - graphml: str, communities: Communities, level: int = 0, seed: int | None = None + graph: nx.Graph, communities: Communities, level: int = 0, seed: int | None = None ) -> nx.Graph: - """Apply clustering to a graphml string.""" + """Apply clustering to a graph.""" random = Random(seed) # noqa S311 - graph = nx.parse_graphml(graphml) for community_level, community_id, nodes in communities: if level == community_level: for node in nodes: @@ -121,11 +122,8 @@ def apply_clustering( return graph -def run_layout( - strategy: dict[str, Any], graphml_or_graph: str | nx.Graph -) -> Communities: +def run_layout(strategy: dict[str, Any], graph: nx.Graph) -> Communities: """Run layout method definition.""" - graph = load_graph(graphml_or_graph) if len(graph.nodes) == 0: log.warning("Graph has no nodes") return [] diff --git a/graphrag/index/operations/extract_entities/extract_entities.py b/graphrag/index/operations/extract_entities/extract_entities.py index 77f29dd6..96bec73b 100644 --- a/graphrag/index/operations/extract_entities/extract_entities.py +++ b/graphrag/index/operations/extract_entities/extract_entities.py @@ -7,6 +7,7 @@ import logging from enum import Enum from typing import Any +import networkx as nx import pandas as pd from datashaper import ( AsyncType, @@ -41,15 +42,14 @@ async def extract_entities( input: pd.DataFrame, callbacks: VerbCallbacks, cache: PipelineCache, - column: str, + text_column: str, id_column: str, to: str, strategy: dict[str, Any] | None, - graph_to: str | None = None, async_mode: AsyncType = AsyncType.AsyncIO, entity_types=DEFAULT_ENTITY_TYPES, num_threads: int = 4, -) -> pd.DataFrame: +) -> tuple[pd.DataFrame, list[nx.Graph]]: """ Extract entities from a piece of text. @@ -59,7 +59,6 @@ async def extract_entities( column: the_document_text_column_to_extract_entities_from id_column: the_column_with_the_unique_id_for_each_row to: the_column_to_output_the_entities_to - graph_to: the_column_to_output_the_graphml_to strategy: , see strategies section below summarize_descriptions: true | false /* Optional: This will summarize the descriptions of the entities and relationships, default: true */ entity_types: @@ -124,7 +123,7 @@ async def extract_entities( async def run_strategy(row): nonlocal num_started - text = row[column] + text = row[text_column] id = row[id_column] result = await strategy_exec( [Document(text=text, id=id)], @@ -134,7 +133,7 @@ async def extract_entities( strategy_config, ) num_started += 1 - return [result.entities, result.graphml_graph] + return [result.entities, result.graph] results = await derive_from_rows( input, @@ -145,20 +144,18 @@ async def extract_entities( ) to_result = [] - graph_to_result = [] + graphs = [] for result in results: if result: to_result.append(result[0]) - graph_to_result.append(result[1]) + graphs.append(result[1]) else: to_result.append(None) - graph_to_result.append(None) + graphs.append(None) input[to] = to_result - if graph_to is not None: - input[graph_to] = graph_to_result - return input.reset_index(drop=True) + return (input.reset_index(drop=True), graphs) def _load_strategy(strategy_type: ExtractEntityStrategyType) -> EntityExtractStrategy: diff --git a/graphrag/index/operations/extract_entities/strategies/graph_intelligence.py b/graphrag/index/operations/extract_entities/strategies/graph_intelligence.py index 1536df34..072d5bed 100644 --- a/graphrag/index/operations/extract_entities/strategies/graph_intelligence.py +++ b/graphrag/index/operations/extract_entities/strategies/graph_intelligence.py @@ -3,7 +3,6 @@ """A module containing run_graph_intelligence, run_extract_entities and _create_text_splitter methods to run graph intelligence.""" -import networkx as nx from datashaper import VerbCallbacks import graphrag.config.defaults as defs @@ -113,8 +112,7 @@ async def run_extract_entities( if item is not None ] - graph_data = "".join(nx.generate_graphml(graph)) - return EntityExtractionResult(entities, graph_data) + return EntityExtractionResult(entities, graph) def _create_text_splitter( diff --git a/graphrag/index/operations/extract_entities/strategies/nltk.py b/graphrag/index/operations/extract_entities/strategies/nltk.py index 9403c5a5..8f9aefa0 100644 --- a/graphrag/index/operations/extract_entities/strategies/nltk.py +++ b/graphrag/index/operations/extract_entities/strategies/nltk.py @@ -57,5 +57,5 @@ async def run( # noqa RUF029 async is required for interface {"type": entity_type, "name": name} for name, entity_type in entity_map.items() ], - graphml_graph="".join(nx.generate_graphml(graph)), + graph=graph, ) diff --git a/graphrag/index/operations/extract_entities/strategies/typing.py b/graphrag/index/operations/extract_entities/strategies/typing.py index 45d3f1b8..e1c548b0 100644 --- a/graphrag/index/operations/extract_entities/strategies/typing.py +++ b/graphrag/index/operations/extract_entities/strategies/typing.py @@ -7,6 +7,7 @@ from collections.abc import Awaitable, Callable from dataclasses import dataclass from typing import Any +import networkx as nx from datashaper import VerbCallbacks from graphrag.index.cache import PipelineCache @@ -29,7 +30,7 @@ class EntityExtractionResult: """Entity extraction result class definition.""" entities: list[ExtractedEntity] - graphml_graph: str | None + graph: nx.Graph | None EntityExtractStrategy = Callable[ diff --git a/graphrag/index/operations/merge_graphs/merge_graphs.py b/graphrag/index/operations/merge_graphs/merge_graphs.py index ca654e6e..80ab20ef 100644 --- a/graphrag/index/operations/merge_graphs/merge_graphs.py +++ b/graphrag/index/operations/merge_graphs/merge_graphs.py @@ -3,14 +3,11 @@ """A module containing merge_graphs, merge_nodes, merge_edges, merge_attributes, apply_merge_operation and _get_detailed_attribute_merge_operation methods definitions.""" -from typing import Any, cast +from typing import Any import networkx as nx -import pandas as pd from datashaper import VerbCallbacks, progress_iterable -from graphrag.index.utils import load_graph - from .typing import ( BasicMergeOperation, DetailedAttributeMergeOperation, @@ -35,15 +32,13 @@ DEFAULT_CONCAT_SEPARATOR = "," def merge_graphs( - input: pd.DataFrame, + graphs: list[nx.Graph], callbacks: VerbCallbacks, - column: str, - to: str, - nodes: dict[str, Any] = DEFAULT_NODE_OPERATIONS, - edges: dict[str, Any] = DEFAULT_EDGE_OPERATIONS, -) -> pd.DataFrame: + node_operations: dict[str, Any] | None, + edge_operations: dict[str, Any] | None, +) -> nx.Graph: """ - Merge multiple graphs together. The graphs are expected to be in graphml format. The verb outputs a new column containing the merged graph. + Merge multiple graphs together. The graphs are expected to be in nx.Graph format. The verb outputs a new column containing the merged graph. > Note: This will merge all rows into a single graph. @@ -51,8 +46,6 @@ def merge_graphs( ```yaml verb: merge_graph args: - column: clustered_graph # The name of the column containing the graph, should be a graphml graph - to: merged_graph # The name of the column to output the merged graph to nodes: # See node operations section below edges: # See edge operations section below ``` @@ -90,8 +83,8 @@ def merge_graphs( - __average__: This operation takes the mean of the attribute with the last value seen. - __multiply__: This operation multiplies the attribute with the last value seen. """ - output = pd.DataFrame() - + nodes = node_operations or DEFAULT_NODE_OPERATIONS + edges = edge_operations or DEFAULT_EDGE_OPERATIONS node_ops = { attrib: _get_detailed_attribute_merge_operation(value) for attrib, value in nodes.items() @@ -102,15 +95,12 @@ def merge_graphs( } mega_graph = nx.Graph() - num_total = len(input) - for graphml in progress_iterable(input[column], callbacks.progress, num_total): - graph = load_graph(cast(str | nx.Graph, graphml)) + num_total = len(graphs) + for graph in progress_iterable(graphs, callbacks.progress, num_total): merge_nodes(mega_graph, graph, node_ops) merge_edges(mega_graph, graph, edge_ops) - output[to] = ["\n".join(nx.generate_graphml(mega_graph))] - - return output + return mega_graph def merge_nodes( diff --git a/graphrag/index/operations/snapshot_graphml.py b/graphrag/index/operations/snapshot_graphml.py new file mode 100644 index 00000000..07a174fa --- /dev/null +++ b/graphrag/index/operations/snapshot_graphml.py @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Microsoft Corporation. +# Licensed under the MIT License + +"""A module containing snapshot method definition.""" + +import networkx as nx + +from graphrag.index.storage import PipelineStorage + + +async def snapshot_graphml( + input: str | nx.Graph, + name: str, + storage: PipelineStorage, +) -> None: + """Take a entire snapshot of a graph to standard graphml format.""" + graphml = input if isinstance(input, str) else "\n".join(nx.generate_graphml(input)) + await storage.set(name + ".graphml", graphml) diff --git a/graphrag/index/operations/summarize_descriptions/summarize_descriptions.py b/graphrag/index/operations/summarize_descriptions/summarize_descriptions.py index 40af8dfc..07754473 100644 --- a/graphrag/index/operations/summarize_descriptions/summarize_descriptions.py +++ b/graphrag/index/operations/summarize_descriptions/summarize_descriptions.py @@ -5,10 +5,9 @@ import asyncio import logging -from typing import Any, cast +from typing import Any import networkx as nx -import pandas as pd from datashaper import ( ProgressTicker, VerbCallbacks, @@ -16,10 +15,8 @@ from datashaper import ( ) from graphrag.index.cache import PipelineCache -from graphrag.index.utils import load_graph from .typing import ( - DescriptionSummarizeRow, SummarizationStrategy, SummarizeStrategyType, ) @@ -28,14 +25,12 @@ log = logging.getLogger(__name__) async def summarize_descriptions( - input: pd.DataFrame, + input: nx.Graph, callbacks: VerbCallbacks, cache: PipelineCache, - column: str, - to: str, strategy: dict[str, Any] | None = None, - **kwargs, -) -> pd.DataFrame: + num_threads: int = 4, +) -> nx.Graph: """ Summarize entity and relationship descriptions from an entity graph. @@ -43,25 +38,10 @@ async def summarize_descriptions( To turn this feature ON please set the environment variable `GRAPHRAG_SUMMARIZE_DESCRIPTIONS_ENABLED=True`. - ### json - - ```json - { - "verb": "", - "args": { - "column": "the_document_text_column_to_extract_descriptions_from", /* Required: This will be a graphml graph in string form which represents the entities and their relationships */ - "to": "the_column_to_output_the_summarized_descriptions_to", /* Required: This will be a graphml graph in string form which represents the entities and their relationships after being summarized */ - "strategy": {...} , see strategies section below - } - } - ``` - ### yaml ```yaml args: - column: the_document_text_column_to_extract_descriptions_from - to: the_column_to_output_the_summarized_descriptions_to strategy: , see strategies section below ``` @@ -99,9 +79,7 @@ async def summarize_descriptions( ) strategy_config = {**strategy} - async def get_resolved_entities(row, semaphore: asyncio.Semaphore): - graph: nx.Graph = load_graph(cast(str | nx.Graph, getattr(row, column))) - + async def get_resolved_entities(graph: nx.Graph, semaphore: asyncio.Semaphore): ticker_length = len(graph.nodes) + len(graph.edges) ticker = progress_ticker(callbacks.progress, ticker_length) @@ -134,9 +112,7 @@ async def summarize_descriptions( elif isinstance(graph_item, tuple) and graph_item in graph.edges(): graph.edges[graph_item]["description"] = result.description - return DescriptionSummarizeRow( - graph="\n".join(nx.generate_graphml(graph)), - ) + return graph async def do_summarize_descriptions( graph_item: str | tuple[str, str], @@ -155,25 +131,9 @@ async def summarize_descriptions( ticker(1) return results - # Graph is always on row 0, so here a derive from rows does not work - # This iteration will only happen once, but avoids hardcoding a iloc[0] - # Since parallelization is at graph level (nodes and edges), we can't use - # the parallelization of the derive_from_rows - semaphore = asyncio.Semaphore(kwargs.get("num_threads", 4)) + semaphore = asyncio.Semaphore(num_threads) - results = [ - await get_resolved_entities(row, semaphore) for row in input.itertuples() - ] - - to_result = [] - - for result in results: - if result: - to_result.append(result.graph) - else: - to_result.append(None) - input[to] = to_result - return input + return await get_resolved_entities(input, semaphore) def load_strategy(strategy_type: SummarizeStrategyType) -> SummarizationStrategy: diff --git a/graphrag/index/workflows/default_workflows.py b/graphrag/index/workflows/default_workflows.py index 70cb2cf3..896a861a 100644 --- a/graphrag/index/workflows/default_workflows.py +++ b/graphrag/index/workflows/default_workflows.py @@ -7,24 +7,12 @@ from .v1.subflows import * # noqa from .typing import WorkflowDefinitions -from .v1.create_base_documents import ( - build_steps as build_create_base_documents_steps, -) -from .v1.create_base_documents import ( - workflow_name as create_base_documents, -) from .v1.create_base_entity_graph import ( build_steps as build_create_base_entity_graph_steps, ) from .v1.create_base_entity_graph import ( workflow_name as create_base_entity_graph, ) -from .v1.create_base_extracted_entities import ( - build_steps as build_create_base_extracted_entities_steps, -) -from .v1.create_base_extracted_entities import ( - workflow_name as create_base_extracted_entities, -) from .v1.create_base_text_units import ( build_steps as build_create_base_text_units_steps, ) @@ -79,16 +67,9 @@ from .v1.create_final_text_units import ( from .v1.create_final_text_units import ( workflow_name as create_final_text_units, ) -from .v1.create_summarized_entities import ( - build_steps as build_create_summarized_entities_steps, -) -from .v1.create_summarized_entities import ( - workflow_name as create_summarized_entities, -) default_workflows: WorkflowDefinitions = { - create_base_extracted_entities: build_create_base_extracted_entities_steps, create_base_entity_graph: build_create_base_entity_graph_steps, create_base_text_units: build_create_base_text_units_steps, create_final_text_units: build_create_final_text_units, @@ -97,8 +78,6 @@ default_workflows: WorkflowDefinitions = { create_final_relationships: build_create_final_relationships_steps, create_final_documents: build_create_final_documents_steps, create_final_covariates: build_create_final_covariates_steps, - create_base_documents: build_create_base_documents_steps, create_final_entities: build_create_final_entities_steps, create_final_communities: build_create_final_communities_steps, - create_summarized_entities: build_create_summarized_entities_steps, } diff --git a/graphrag/index/workflows/v1/create_base_documents.py b/graphrag/index/workflows/v1/create_base_documents.py deleted file mode 100644 index 1186b1d4..00000000 --- a/graphrag/index/workflows/v1/create_base_documents.py +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""A module containing build_steps method definition.""" - -from datashaper import DEFAULT_INPUT_NAME - -from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep - -workflow_name = "create_base_documents" - - -def build_steps( - config: PipelineWorkflowConfig, -) -> list[PipelineWorkflowStep]: - """ - Create the documents table. - - ## Dependencies - * `workflow:create_final_text_units` - """ - document_attribute_columns = config.get("document_attribute_columns", []) - return [ - { - "verb": "create_base_documents", - "args": { - "document_attribute_columns": document_attribute_columns, - }, - "input": { - "source": DEFAULT_INPUT_NAME, - "text_units": "workflow:create_final_text_units", - }, - }, - ] diff --git a/graphrag/index/workflows/v1/create_base_entity_graph.py b/graphrag/index/workflows/v1/create_base_entity_graph.py index dadaece5..0b77b438 100644 --- a/graphrag/index/workflows/v1/create_base_entity_graph.py +++ b/graphrag/index/workflows/v1/create_base_entity_graph.py @@ -3,6 +3,10 @@ """A module containing build_steps method definition.""" +from datashaper import ( + AsyncType, +) + from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep workflow_name = "create_base_entity_graph" @@ -15,8 +19,53 @@ def build_steps( Create the base table for the entity graph. ## Dependencies - * `workflow:create_base_extracted_entities` + * `workflow:create_base_summarized_entities` """ + entity_extraction_config = config.get("entity_extract", {}) + text_column = entity_extraction_config.get("text_column", "chunk") + id_column = entity_extraction_config.get("id_column", "chunk_id") + async_mode = entity_extraction_config.get("async_mode", AsyncType.AsyncIO) + extraction_strategy = entity_extraction_config.get("strategy") + extraction_num_threads = entity_extraction_config.get("num_threads", 4) + entity_types = entity_extraction_config.get("entity_types") + + graph_merge_operations_config = config.get( + "graph_merge_operations", + { + "nodes": { + "source_id": { + "operation": "concat", + "delimiter": ", ", + "distinct": True, + }, + "description": ({ + "operation": "concat", + "separator": "\n", + "distinct": False, + }), + }, + "edges": { + "source_id": { + "operation": "concat", + "delimiter": ", ", + "distinct": True, + }, + "description": ({ + "operation": "concat", + "separator": "\n", + "distinct": False, + }), + "weight": "sum", + }, + }, + ) + node_merge_config = graph_merge_operations_config.get("nodes") + edge_merge_config = graph_merge_operations_config.get("edges") + + summarize_descriptions_config = config.get("summarize_descriptions", {}) + summarization_strategy = summarize_descriptions_config.get("strategy") + summarization_num_threads = summarize_descriptions_config.get("num_threads", 4) + clustering_config = config.get( "cluster_graph", {"strategy": {"type": "leiden"}}, @@ -40,17 +89,29 @@ def build_steps( embed_graph_enabled = config.get("embed_graph_enabled", False) or False graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False + raw_entity_snapshot_enabled = config.get("raw_entity_snapshot", False) or False return [ { "verb": "create_base_entity_graph", "args": { + "text_column": text_column, + "id_column": id_column, + "extraction_strategy": extraction_strategy, + "extraction_num_threads": extraction_num_threads, + "extraction_async_mode": async_mode, + "entity_types": entity_types, + "node_merge_config": node_merge_config, + "edge_merge_config": edge_merge_config, + "summarization_strategy": summarization_strategy, + "summarization_num_threads": summarization_num_threads, "clustering_strategy": clustering_strategy, - "graphml_snapshot_enabled": graphml_snapshot_enabled, "embedding_strategy": embedding_strategy if embed_graph_enabled else None, + "raw_entity_snapshot_enabled": raw_entity_snapshot_enabled, + "graphml_snapshot_enabled": graphml_snapshot_enabled, }, - "input": ({"source": "workflow:create_summarized_entities"}), + "input": ({"source": "workflow:create_base_text_units"}), }, ] diff --git a/graphrag/index/workflows/v1/create_base_extracted_entities.py b/graphrag/index/workflows/v1/create_base_extracted_entities.py deleted file mode 100644 index e18266b3..00000000 --- a/graphrag/index/workflows/v1/create_base_extracted_entities.py +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""A module containing build_steps method definition.""" - -from datashaper import AsyncType - -from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep - -workflow_name = "create_base_extracted_entities" - - -def build_steps( - config: PipelineWorkflowConfig, -) -> list[PipelineWorkflowStep]: - """ - Create the base table for extracted entities. - - ## Dependencies - * `workflow:create_base_text_units` - """ - entity_extraction_config = config.get("entity_extract", {}) - - column = entity_extraction_config.get("text_column", "chunk") - id_column = entity_extraction_config.get("id_column", "chunk_id") - async_mode = entity_extraction_config.get("async_mode", AsyncType.AsyncIO) - extraction_strategy = entity_extraction_config.get("strategy") - num_threads = entity_extraction_config.get("num_threads", 4) - entity_types = entity_extraction_config.get("entity_types") - - graph_merge_operations_config = config.get( - "graph_merge_operations", - { - "nodes": { - "source_id": { - "operation": "concat", - "delimiter": ", ", - "distinct": True, - }, - "description": ({ - "operation": "concat", - "separator": "\n", - "distinct": False, - }), - }, - "edges": { - "source_id": { - "operation": "concat", - "delimiter": ", ", - "distinct": True, - }, - "description": ({ - "operation": "concat", - "separator": "\n", - "distinct": False, - }), - "weight": "sum", - }, - }, - ) - nodes = graph_merge_operations_config.get("nodes") - edges = graph_merge_operations_config.get("edges") - - graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False - raw_entity_snapshot_enabled = config.get("raw_entity_snapshot", False) or False - - return [ - { - "verb": "create_base_extracted_entities", - "args": { - "column": column, - "id_column": id_column, - "async_mode": async_mode, - "extraction_strategy": extraction_strategy, - "num_threads": num_threads, - "entity_types": entity_types, - "nodes": nodes, - "edges": edges, - "raw_entity_snapshot_enabled": raw_entity_snapshot_enabled, - "graphml_snapshot_enabled": graphml_snapshot_enabled, - }, - "input": {"source": "workflow:create_base_text_units"}, - }, - ] diff --git a/graphrag/index/workflows/v1/create_final_covariates.py b/graphrag/index/workflows/v1/create_final_covariates.py index 1fdab708..0f8191ab 100644 --- a/graphrag/index/workflows/v1/create_final_covariates.py +++ b/graphrag/index/workflows/v1/create_final_covariates.py @@ -20,7 +20,6 @@ def build_steps( ## Dependencies * `workflow:create_base_text_units` - * `workflow:create_base_extracted_entities` """ claim_extract_config = config.get("claim_extract", {}) extraction_strategy = claim_extract_config.get("strategy") diff --git a/graphrag/index/workflows/v1/create_final_documents.py b/graphrag/index/workflows/v1/create_final_documents.py index 3fa21e31..33425e4e 100644 --- a/graphrag/index/workflows/v1/create_final_documents.py +++ b/graphrag/index/workflows/v1/create_final_documents.py @@ -3,6 +3,8 @@ """A module containing build_steps method definition.""" +from datashaper import DEFAULT_INPUT_NAME + from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep workflow_name = "create_final_documents" @@ -15,21 +17,26 @@ def build_steps( Create the final documents table. ## Dependencies - * `workflow:create_base_documents` + * `workflow:create_final_text_units` """ base_text_embed = config.get("text_embed", {}) document_raw_content_embed_config = config.get( "document_raw_content_embed", base_text_embed ) skip_raw_content_embedding = config.get("skip_raw_content_embedding", False) + document_attribute_columns = config.get("document_attribute_columns", []) return [ { "verb": "create_final_documents", "args": { + "document_attribute_columns": document_attribute_columns, "raw_content_text_embed": document_raw_content_embed_config if not skip_raw_content_embedding else None, }, - "input": {"source": "workflow:create_base_documents"}, + "input": { + "source": DEFAULT_INPUT_NAME, + "text_units": "workflow:create_final_text_units", + }, }, ] diff --git a/graphrag/index/workflows/v1/create_summarized_entities.py b/graphrag/index/workflows/v1/create_summarized_entities.py deleted file mode 100644 index 53821814..00000000 --- a/graphrag/index/workflows/v1/create_summarized_entities.py +++ /dev/null @@ -1,36 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""A module containing build_steps method definition.""" - -from graphrag.index.config import PipelineWorkflowConfig, PipelineWorkflowStep - -workflow_name = "create_summarized_entities" - - -def build_steps( - config: PipelineWorkflowConfig, -) -> list[PipelineWorkflowStep]: - """ - Create the base table for extracted entities. - - ## Dependencies - * `workflow:create_base_text_units` - """ - summarize_descriptions_config = config.get("summarize_descriptions", {}) - summarization_strategy = summarize_descriptions_config.get("strategy") - num_threads = summarize_descriptions_config.get("num_threads", 4) - - graphml_snapshot_enabled = config.get("graphml_snapshot", False) or False - - return [ - { - "verb": "create_summarized_entities", - "args": { - "summarization_strategy": summarization_strategy, - "num_threads": num_threads, - "graphml_snapshot_enabled": graphml_snapshot_enabled, - }, - "input": {"source": "workflow:create_base_extracted_entities"}, - }, - ] diff --git a/graphrag/index/workflows/v1/subflows/__init__.py b/graphrag/index/workflows/v1/subflows/__init__.py index 857d20c4..37e20367 100644 --- a/graphrag/index/workflows/v1/subflows/__init__.py +++ b/graphrag/index/workflows/v1/subflows/__init__.py @@ -3,9 +3,7 @@ """The Indexing Engine workflows -> subflows package root.""" -from .create_base_documents import create_base_documents from .create_base_entity_graph import create_base_entity_graph -from .create_base_extracted_entities import create_base_extracted_entities from .create_base_text_units import create_base_text_units from .create_final_communities import create_final_communities from .create_final_community_reports import create_final_community_reports @@ -17,12 +15,9 @@ from .create_final_relationships import ( create_final_relationships, ) from .create_final_text_units import create_final_text_units -from .create_summarized_entities import create_summarized_entities __all__ = [ - "create_base_documents", "create_base_entity_graph", - "create_base_extracted_entities", "create_base_text_units", "create_final_communities", "create_final_community_reports", @@ -32,5 +27,4 @@ __all__ = [ "create_final_nodes", "create_final_relationships", "create_final_text_units", - "create_summarized_entities", ] diff --git a/graphrag/index/workflows/v1/subflows/create_base_documents.py b/graphrag/index/workflows/v1/subflows/create_base_documents.py deleted file mode 100644 index c3e52098..00000000 --- a/graphrag/index/workflows/v1/subflows/create_base_documents.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""All the steps to transform base documents.""" - -from typing import cast - -import pandas as pd -from datashaper import ( - Table, - VerbInput, - verb, -) -from datashaper.table_store.types import VerbResult, create_verb_result - -from graphrag.index.flows.create_base_documents import ( - create_base_documents as create_base_documents_flow, -) -from graphrag.index.utils.ds_util import get_required_input_table - - -@verb(name="create_base_documents", treats_input_tables_as_immutable=True) -def create_base_documents( - input: VerbInput, - document_attribute_columns: list[str] | None = None, - **_kwargs: dict, -) -> VerbResult: - """All the steps to transform base documents.""" - source = cast(pd.DataFrame, input.get_input()) - text_units = cast(pd.DataFrame, get_required_input_table(input, "text_units").table) - - output = create_base_documents_flow( - source, text_units, document_attribute_columns=document_attribute_columns - ) - - return create_verb_result( - cast( - Table, - output, - ) - ) diff --git a/graphrag/index/workflows/v1/subflows/create_base_entity_graph.py b/graphrag/index/workflows/v1/subflows/create_base_entity_graph.py index 009da03f..2ab85b01 100644 --- a/graphrag/index/workflows/v1/subflows/create_base_entity_graph.py +++ b/graphrag/index/workflows/v1/subflows/create_base_entity_graph.py @@ -7,6 +7,7 @@ from typing import Any, cast import pandas as pd from datashaper import ( + AsyncType, Table, VerbCallbacks, VerbInput, @@ -14,6 +15,7 @@ from datashaper import ( ) from datashaper.table_store.types import VerbResult, create_verb_result +from graphrag.index.cache import PipelineCache from graphrag.index.flows.create_base_entity_graph import ( create_base_entity_graph as create_base_entity_graph_flow, ) @@ -27,10 +29,22 @@ from graphrag.index.storage import PipelineStorage async def create_base_entity_graph( input: VerbInput, callbacks: VerbCallbacks, + cache: PipelineCache, storage: PipelineStorage, + text_column: str, + id_column: str, clustering_strategy: dict[str, Any], - embedding_strategy: dict[str, Any] | None, + extraction_strategy: dict[str, Any] | None, + extraction_num_threads: int = 4, + extraction_async_mode: AsyncType = AsyncType.AsyncIO, + entity_types: list[str] | None = None, + node_merge_config: dict[str, Any] | None = None, + edge_merge_config: dict[str, Any] | None = None, + summarization_strategy: dict[str, Any] | None = None, + summarization_num_threads: int = 4, + embedding_strategy: dict[str, Any] | None = None, graphml_snapshot_enabled: bool = False, + raw_entity_snapshot_enabled: bool = False, **_kwargs: dict, ) -> VerbResult: """All the steps to create the base entity graph.""" @@ -39,10 +53,22 @@ async def create_base_entity_graph( output = await create_base_entity_graph_flow( source, callbacks, + cache, storage, - clustering_strategy, - embedding_strategy, + text_column, + id_column, + clustering_strategy=clustering_strategy, + extraction_strategy=extraction_strategy, + extraction_num_threads=extraction_num_threads, + extraction_async_mode=extraction_async_mode, + entity_types=entity_types, + node_merge_config=node_merge_config, + edge_merge_config=edge_merge_config, + summarization_strategy=summarization_strategy, + summarization_num_threads=summarization_num_threads, + embedding_strategy=embedding_strategy, graphml_snapshot_enabled=graphml_snapshot_enabled, + raw_entity_snapshot_enabled=raw_entity_snapshot_enabled, ) return create_verb_result(cast(Table, output)) diff --git a/graphrag/index/workflows/v1/subflows/create_base_extracted_entities.py b/graphrag/index/workflows/v1/subflows/create_base_extracted_entities.py deleted file mode 100644 index 34660e01..00000000 --- a/graphrag/index/workflows/v1/subflows/create_base_extracted_entities.py +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""All the steps to extract and format base entities.""" - -from typing import Any, cast - -import pandas as pd -from datashaper import ( - AsyncType, - Table, - VerbCallbacks, - VerbInput, - verb, -) -from datashaper.table_store.types import VerbResult, create_verb_result - -from graphrag.index.cache import PipelineCache -from graphrag.index.flows.create_base_extracted_entities import ( - create_base_extracted_entities as create_base_extracted_entities_flow, -) -from graphrag.index.storage import PipelineStorage - - -@verb(name="create_base_extracted_entities", treats_input_tables_as_immutable=True) -async def create_base_extracted_entities( - input: VerbInput, - callbacks: VerbCallbacks, - cache: PipelineCache, - storage: PipelineStorage, - column: str, - id_column: str, - nodes: dict[str, Any], - edges: dict[str, Any], - extraction_strategy: dict[str, Any] | None, - async_mode: AsyncType = AsyncType.AsyncIO, - entity_types: list[str] | None = None, - num_threads: int = 4, - graphml_snapshot_enabled: bool = False, - raw_entity_snapshot_enabled: bool = False, - **_kwargs: dict, -) -> VerbResult: - """All the steps to extract and format base entities.""" - source = cast(pd.DataFrame, input.get_input()) - - output = await create_base_extracted_entities_flow( - source, - callbacks, - cache, - storage, - column, - id_column, - nodes, - edges, - extraction_strategy, - async_mode=async_mode, - entity_types=entity_types, - graphml_snapshot_enabled=graphml_snapshot_enabled, - raw_entity_snapshot_enabled=raw_entity_snapshot_enabled, - num_threads=num_threads, - ) - - return create_verb_result(cast(Table, output)) diff --git a/graphrag/index/workflows/v1/subflows/create_final_documents.py b/graphrag/index/workflows/v1/subflows/create_final_documents.py index bc883552..191bbd9e 100644 --- a/graphrag/index/workflows/v1/subflows/create_final_documents.py +++ b/graphrag/index/workflows/v1/subflows/create_final_documents.py @@ -18,6 +18,7 @@ from graphrag.index.cache import PipelineCache from graphrag.index.flows.create_final_documents import ( create_final_documents as create_final_documents_flow, ) +from graphrag.index.utils.ds_util import get_required_input_table @verb( @@ -28,16 +29,20 @@ async def create_final_documents( input: VerbInput, callbacks: VerbCallbacks, cache: PipelineCache, + document_attribute_columns: list[str] | None = None, raw_content_text_embed: dict | None = None, **_kwargs: dict, ) -> VerbResult: """All the steps to transform final documents.""" source = cast(pd.DataFrame, input.get_input()) + text_units = cast(pd.DataFrame, get_required_input_table(input, "text_units").table) output = await create_final_documents_flow( source, + text_units, callbacks, cache, + document_attribute_columns=document_attribute_columns, raw_content_text_embed=raw_content_text_embed, ) diff --git a/graphrag/index/workflows/v1/subflows/create_summarized_entities.py b/graphrag/index/workflows/v1/subflows/create_summarized_entities.py deleted file mode 100644 index 4ac2dd5b..00000000 --- a/graphrag/index/workflows/v1/subflows/create_summarized_entities.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -"""All the steps to summarize entities.""" - -from typing import Any, cast - -import pandas as pd -from datashaper import ( - Table, - VerbCallbacks, - VerbInput, - verb, -) -from datashaper.table_store.types import VerbResult, create_verb_result - -from graphrag.index.cache import PipelineCache -from graphrag.index.flows.create_summarized_entities import ( - create_summarized_entities as create_summarized_entities_flow, -) -from graphrag.index.storage import PipelineStorage - - -@verb( - name="create_summarized_entities", - treats_input_tables_as_immutable=True, -) -async def create_summarized_entities( - input: VerbInput, - callbacks: VerbCallbacks, - cache: PipelineCache, - storage: PipelineStorage, - summarization_strategy: dict[str, Any] | None = None, - num_threads: int = 4, - graphml_snapshot_enabled: bool = False, - **_kwargs: dict, -) -> VerbResult: - """All the steps to summarize entities.""" - source = cast(pd.DataFrame, input.get_input()) - - output = await create_summarized_entities_flow( - source, - callbacks, - cache, - storage, - summarization_strategy, - num_threads=num_threads, - graphml_snapshot_enabled=graphml_snapshot_enabled, - ) - - return create_verb_result(cast(Table, output)) diff --git a/tests/fixtures/min-csv/config.json b/tests/fixtures/min-csv/config.json index 73a46f0d..53986d99 100644 --- a/tests/fixtures/min-csv/config.json +++ b/tests/fixtures/min-csv/config.json @@ -10,29 +10,13 @@ "subworkflows": 1, "max_runtime": 10 }, - "create_base_extracted_entities": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 300 - }, - "create_summarized_entities": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 300 - }, "create_base_entity_graph": { "row_range": [ 1, 2000 ], "subworkflows": 1, - "max_runtime": 10 + "max_runtime": 300 }, "create_final_entities": { "row_range": [ @@ -108,14 +92,6 @@ "subworkflows": 1, "max_runtime": 100 }, - "create_base_documents": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 10 - }, "create_final_documents": { "row_range": [ 1, diff --git a/tests/fixtures/text/config.json b/tests/fixtures/text/config.json index 473e7d8b..af1eba3f 100644 --- a/tests/fixtures/text/config.json +++ b/tests/fixtures/text/config.json @@ -10,14 +10,6 @@ "subworkflows": 1, "max_runtime": 10 }, - "create_base_extracted_entities": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 300 - }, "create_final_covariates": { "row_range": [ 1, @@ -35,21 +27,13 @@ "subworkflows": 1, "max_runtime": 300 }, - "create_summarized_entities": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 300 - }, "create_base_entity_graph": { "row_range": [ 1, 2000 ], "subworkflows": 1, - "max_runtime": 10 + "max_runtime": 300 }, "create_final_entities": { "row_range": [ @@ -125,14 +109,6 @@ "subworkflows": 1, "max_runtime": 100 }, - "create_base_documents": { - "row_range": [ - 1, - 2000 - ], - "subworkflows": 1, - "max_runtime": 10 - }, "create_final_documents": { "row_range": [ 1, diff --git a/tests/integration/_pipeline/megapipeline.yml b/tests/integration/_pipeline/megapipeline.yml index a6004b9b..fc84d6f1 100644 --- a/tests/integration/_pipeline/megapipeline.yml +++ b/tests/integration/_pipeline/megapipeline.yml @@ -19,9 +19,10 @@ workflows: # Just lump everything together chunk_by: [] - - name: create_base_extracted_entities + - name: create_base_entity_graph config: graphml_snapshot: True + embed_graph_enabled: True entity_extract: strategy: type: graph_intelligence @@ -37,9 +38,6 @@ workflows: ("relationship"<|>COMPANY_A<|>COMPANY_B<|>Company_A and Company_B are related because Company_A is 100% owned by Company_B and the two companies also share the same address)<|>2) ## ("relationship"<|>COMPANY_A<|>PERSON_C<|>Company_A and Person_C are related because Person_C is director of Company_A<|>1))' - - - name: create_summarized_entities - config: summarize_descriptions: strategy: type: graph_intelligence @@ -47,11 +45,6 @@ workflows: type: static_response responses: - This is a MOCK response for the LLM. It is summarized! - - - name: create_base_entity_graph - config: - graphml_snapshot: True - embed_graph_enabled: True cluster_graph: strategy: type: leiden @@ -59,8 +52,6 @@ workflows: - name: create_final_nodes - - name: create_base_documents - - name: create_final_communities - name: create_final_text_units config: diff --git a/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py b/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py index 31a83a26..d72f10b3 100644 --- a/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py +++ b/tests/unit/indexing/verbs/entities/extraction/strategies/graph_intelligence/test_gi_entity_extraction.py @@ -2,8 +2,6 @@ # Licensed under the MIT License import unittest -import networkx as nx - from graphrag.index.operations.extract_entities.strategies.graph_intelligence import ( run_extract_entities, ) @@ -119,8 +117,8 @@ class TestRunChain(unittest.IsolatedAsyncioTestCase): # self.assertItemsEqual isn't available yet, or I am just silly # so we sort the lists and compare them - assert results.graphml_graph is not None, "No graphml graph returned!" - graph = nx.parse_graphml(results.graphml_graph) # type: ignore + graph = results.graph + assert graph is not None, "No graph returned!" # convert to strings for more visual comparison edges_str = sorted([f"{edge[0]} -> {edge[1]}" for edge in graph.edges]) @@ -162,8 +160,8 @@ class TestRunChain(unittest.IsolatedAsyncioTestCase): ), ) - assert results.graphml_graph is not None, "No graphml graph returned!" - graph = nx.parse_graphml(results.graphml_graph) # type: ignore + graph = results.graph # type: ignore + assert graph is not None, "No graph returned!" # TODO: The edges might come back in any order, but we're assuming they're coming # back in the order that we passed in the docs, that might not be true @@ -173,9 +171,11 @@ class TestRunChain(unittest.IsolatedAsyncioTestCase): assert ( graph.nodes["TEST_ENTITY_2"].get("source_id") == "1" ) # TEST_ENTITY_2 should be in just 1 - assert sorted( - graph.nodes["TEST_ENTITY_1"].get("source_id").split(",") - ) == sorted(["1", "2"]) # TEST_ENTITY_1 should be 1 and 2 + ids_str = graph.nodes["TEST_ENTITY_1"].get("source_id") or "" + assert sorted(ids_str.split(",")) == sorted([ + "1", + "2", + ]) # TEST_ENTITY_1 should be 1 and 2 async def test_run_extract_entities_multiple_documents_correct_edge_source_ids_mapped( self, @@ -210,8 +210,8 @@ class TestRunChain(unittest.IsolatedAsyncioTestCase): ), ) - assert results.graphml_graph is not None, "No graphml graph returned!" - graph = nx.parse_graphml(results.graphml_graph) # type: ignore + graph = results.graph # type: ignore + assert graph is not None, "No graph returned!" edges = list(graph.edges(data=True)) # should only have 2 edges diff --git a/tests/verbs/data/create_base_documents.parquet b/tests/verbs/data/create_base_documents.parquet deleted file mode 100644 index db873e668c24eceaf76693324df4c48fac975409..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121089 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%0A!Gh`-`CfrHPri-wUoMlcu%d>{c_!ZEHC7150v>@ zTk5mATFNTNulw11EGkb!`=l+%K=})NtN&yDItIF$Gki_*y&7D(D;n$4{u}FAzN{rZ z7wwgm)>xnQeVa6P!CqD@aQ)L3q+oMLNyfO1;klYZ-@S+C(h}HS$?BiB?GJUV9&ZQO zP(AdXdbtlmX5l?W>@>Frl8!vJOke9%>Ihy zo}g^QKdGauaY6ZNe|>J>_&t_;`YMB&gPu^DJg!Mn+4ucO9*^Yls&GDrrJ_!GXbQ-` z-2WWk@NpgnNcqqCp7D{bLjL}Tp%UNAM=>`2(s(7GStKE#iSe(nUmgd)|EZP#Ev%J? zUim|zZ~S<}_|fr?Qg&jpR(~&$3KpLDw6A3_OJayDyzYj z(>vwsWxb&4zH z^KlSQi|22XP}TAGI{*7ZQKY+M{G#zj`K}UjMaHKLsj#aNpU^NkW&DQuT%5Vf-@URg k(3{%a)s;Fv37Ws3n+a diff --git a/tests/verbs/data/create_base_extracted_entities.parquet b/tests/verbs/data/create_base_extracted_entities.parquet deleted file mode 100644 index d7ec39bec886117e2d69c90d7270433f4ada14a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55577 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 z 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 LC_o5iP|^Pd?gpe4 diff --git a/tests/verbs/data/create_summarized_entities.parquet b/tests/verbs/data/create_summarized_entities.parquet deleted file mode 100644 index 80e377c441ce5046990164e3a15b961b3eabeccc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58252 zcmb6Bd3Y1$`UZ}_lTKjLOx~u`W=PXEouqq7)9g!uO4_Ehr5oL#6)KZt(gw1WEG?~4 zX+2ayMMcG<;!+e96?fdXDsH$OH{A7D6&I9(3V7gX{60CK-}U?VdwnnFqD_;`yz{=# zazFQTztiFBG%85NXMZXcznogoq7W$%gV2HJ>7nw1G_-Uu$`22Pg52g%FdSQ^9g4?? ztE;MHEYgc9oiECd2Ev2-NOZ7DT#B?3Jzc#y7EqY7M@L8Xqh@hY++;8qtJbu(ba{t_ z5MLPx$Krh0D`+|RTy;#W$ZLss`FJ1_R-7jepwPf3gt%QdAiBz^Hz=Ck-5m32YtlJx z=|*9U3;334eKsxUk3^Sg1>Yc?g^$Oh`Y<07mT6;=MAR!>5b$XwtRp@)ocdEd3d7TK zRkj9%tOE^5=@Vk!XkeK5NH!2{M94DGh_Xk8z~E5aREM&Ck%T8G)LxE|Syo4dBR<=E zNGXKlf%w=3#8y)y>i+;C6MW~990D2Pd{4tq1H2yp7joAkPV;5GPw?}JV0@W25%vY5 zf;TQSNhuh=X0aPD@91oAcGq=tD|))!ZME*s74Axc7+&h*<2(m92zO`D*0gu7aJ4n{ zySkg&+m==lc`i9Y=*!W`JB`|!j%Z{9oReFThzntl5FO+KF^=bafx$qW4|2hPC(1|1 zxcCqs=lDP<#>FFCAnc6_d`y793S2l5g0FEAKQ|1w8t`(yNQe)FIX>)zZ+nGsOz?4| zk?6)4=Z^|Pa173!nne#>&HLJ;mc8VSRIM~SCMJ=b4Cv_yqL7@H7F?hzfkw`ERjti-w6;QrNcw1vxOwV=0Tnq>KIB_~JH9^6IPtZ&jjRt%I7v;l) zf_RrK8H^>oLmVIDv@Wi0C<@mK!HYUR8VTyO;{N*KXaFu5fP3=`d^`~qVv?69>vi1d zPyoK?jSP=P`2z-S2)-n29tLCZ>HWo`lP{UHHAbV&?DTug9;?aY_c{$Wr_I7U%szwB z;UT3liW|Lra8jKE$(_}IFY+l}Cw>zyq!Rs~n{5q@EU^kon2ERe@`piB7UYM*F zzhH9kf>p43bxxDXXtUVOPQhz2du@W#@s5j=DxyXN$Xwt8c1X>2B*9SdvC} zxI4SXt!a+BAy{!C#?=SB8^NM9CyG+0$0xu9qMC;qZYPj7$`hp3I#NLBmmzX#)no=) zlPWcXxAj?X4ZIw!VR5XfGj_^(_w!55p=);&HAn5*p^iW0~jj zB2n;~Fdy8$o{9|#19QY=OxH0K2!bUAhlc{ZaCKgrFv|6TGZ6W-(P^~m-yjfYxqzzpGXro&?9^x`0!CVmxu}anIC7PR4^71cia4^)`Q5>n8YUs-;N5m%;)rhWy0ho z;#^d~4hnf^K2(AcyL`R?A(ivN;FwMvs68Laxt2g&c;&dk6$LLH5x54pxNqNnITslg zqO*143)&8z{~*cJ8ovVh4G$Mdz^d z2BXPlw)zbwBky#0y*8`UW43vHPC@W^t^Z%_^sB?-<=~2qolRZct*$Pv&ehr8GO&P@ zyL;Vj-O=Ns+NOo>oq1e1G9mPbT%$nDg5FF$10d_4V zkHsU=Fb^l?_qO zm+<1hDKg?0XEscvg_n>?5iu?zmN&cF+}&Jli@R-QQ(ISKQ^!ENXvYHhJ0BL}Ty0PY zZ-fjw6c~1OB-05v_NEh#_O_NLxNtqpN@r7T&uohW@=SX}r`uKE)V6}_cKg>-d!q|y z*K_URAjEF)%b9(oCxJ_)93+$ogj$H@VzOIcFQSw@HyDj1hS{xjHVk`M@U3c1Hj3bA zXcXyc+iSVHPFHtbV^jCBI(QxNaCP8^U~O?%4dP!}O7h;xLNX9;Tbn+qtG=70^<1Ms zEaNA#hamL?g;(^Jh)3`RAgglTpb*_S>!`Vf%+_%N9}R2%(dZArWD8-g6i!_Vsclpc z*so|R7#JZqd{oxWg&+{c;*fR{(MlM62%`T`lI4|4Jhaiqu|0N@GT4Ir~j_VGD$KbzI zW(x=6fw^xfa6KknMu&ZZPm_OOj9DPt@24Sy2$CH{dR`RX_6mU!=0X`AJA!3va`^33$3SWQ~7|kt2rQ|Q9x7x^H43ktg%$hG6m=w4{ zn74R@kHraN=1*XD6&g&{^JC(jDDcKVywK;-f)G zRYDY&#|r`6CkVq_EE0`IMmg}QsCyk9jKpF@lX05lJj@meodOT|b&UU@nx4^oSr!%i zsZ1S%DaXT7Qi!n*3D^?=yf|do@#m3LG&ls_Z})mE4yWDXhc^Yg-EZ=lJvOt>Y%yARgPC_ay-q(QFTdCC^!hypA0RKI z)6eUs{-#bIwF(}K)$0}P4x_+Z3?{n=E@?2OQX|9w9>R`OFbWQ*VDcCRo6X_1@NhMo z!D4g@kS7I5k2bir$7;3-CbP|A$u2m39vF|{GdXo0-U45C@D7jN={5L0Mx)v8 zu-R=6kJT@j{a&5N=NBNY+D(FwH$i^)nT?S54R(*!XZ0J+f=&?p@V3X}v3pGpi`VIK zIGq-Q(_?pdA>BBfIzLPlq-C4mYc=|9yx9StFu_z9tybP|v-0HgIE*5eB)C5K`UG%q+?*33=Qz zWFS_3Us@5kBp6|UkA=j3hnzvIdZ`8f#~-AMF8Bqk#Gz!7)~nkz=k(KbcryN44DYy5gNtu&FRX~NCF1o5f?56 zFzSaKR|!s284GM4=D*qZ4H+COwrwATh%gGd696gGD9Zz17=;KB6Hjdaet(^@8R_*7 zQSHC+)U9dBEonQqq>;QOx;9Nei+azBsP3lL=(rG@K zN-iXI+Eq`xj<|oC+r=xviA))3?w5oNWvZ+g4hs5tRQn(?u`>m1dKVMA)=o&J?*9I! z)lDmo$t7j2QFtwkj|WBrs$1DldphM3CsPFQKLEEeB=C5Lg44mBj|2eE^LOWk1W4t4 zIIe#UB}t;0Bxnfi^~e51r~$8K%O53&_~T8Trx5$M0+#XD=X8+B!@}^8FskQPnl7Rs z6bIhPOT-|nCkBURCT7~{!AQi1E7IvmRL6-&iXsqj!(40_t{u*VaMPWMucG7$0L4P4 zAL%eh(Ex2@lW)p-E)>}8ilgDlDA6tFLjYXx8}eJKQE1x*bRawu!2ejJ+DJ`)aX?Hs z4ty?|b$=zkj}&|oHS*!yOwu2~Ba6_`459%z2YCnT(cg?}PGx3pU@pi&G0C?i9~XbX zKAawvh)ymyfcN{1J_r z9)KHAbn*`C^q1uA0C&BBhz)`hfUv>uGdS#ai^1%)`W-f#ofrQ9PU`t%;byPd>~T0u zMuX4bcUX-E!S8kW;LHv?fETCFv?aUuk+i%OjqP3CTzf;s`b?_B)iwV%jgQOF3jCVf zl~eMV5_RB*(qSp|stl}<<_R#f0YFH2e>&V<`TezfX`ZN_r%|c);Y^&z*i<>RUdwg6 zp2~)*MTmy6B8TLIb053*;Zj;I#K0@{jx;n(>}kC;wGhK|eR#QyhO&#BV_d%!4Fy76 z3<@`hwPq>7>mZK?1K@hWfL~xg%^5h0=s3SoP(<Irz_y&c!(sEc6}*0n&&cy8 z@BeG;PE}7MU#r@lOOtoHyWDNb7t`8aObghPFQ=JaPV0OojqDU=*U$V)LX5ppmVv_x zd?x)Yi^F(s9sSX@WztGsK_wY0hT8Fg=PlWuh3qL`?(gDfxU6HOPnXNCrwU4@+Iv`K|A#tefn-?03dZ-$Ib4=#})WaNL0*a>TCds{O~Yt$eo>J-p6xSt-IIt9W})J z@IlNBDfuGR8BRF{cs#_9F=LEe2tz40S=Dr!(s2P?l}C+0D19oYXXsZsv69!4{sivO z0Ky$i1bmZM&RvS)t;Z6kmxI*JuTd-qcj!7XZYUaI=8C${8@sSeE*mF;`y~mPzZN>8}85_ns3->Llxt~R) z%qLnX+Lq)}kkpy$Gci|0fl=*0RQ|PQ)^rI{rO~Pb)Z`ouo*34=2Lp@=(Gks8h$rq= z0%Z2U%Co;0xCc!2>C1l3_D6!j$mqxpa;lM>cp_{1HG*tzpFf;NHb-{fm!@A2CY(Bd zCEk~=6aYE$L4iHTsyY@i*Jdf9%z}yLum@}ZsU-O@JDmalV;WPD;0W84j|Vw<7yxEW zrOanWv1XhCo&(29Aa9f@IY?<9As7h{@?RsJTf<1Cb1%t#ftWYJUXAmhny3Wpj^iEd zxtoZoJ+g~zey7oIvN!=>0(9~MLt^&}e!=VU8;rcc?wfvwaJXyTZSH<|C)ZU6#nOuT z*NK|aG<=t2YO7d(gm3_6g}5Ca)Bz+J5#m@UXUv&1Qvkq=ucl*(=m@(|6^inH&3+2X zOQuV*X@D>W{>z@tVE0qFKzYjoyjxOHM&WxY=D#H&FHxU@HxS>!aW=CbpOH+8m`f@Al$@w^-9e7&6#vAhC>pR#cpFSqI7ZYy^#iu52y638vM)a! z=@rd?B0liRcu+IlE5es#Wp}rC00ndGn}v81UPR#hQH|}9W>KC8A^}WbRDUl@`m>t- zS@?renp@q}f?q5+_7lSIrd|bt_?d!TKcgf2p)&Ccvm)2E_=J=Ucsn0n;66-^@-gvB_W{)R^A?-g;Wa~I z;vsh1p_=wPz)uY(-VY9IbDDh?yVol0@GYQg-7PKiw~|z?5M-^gN18-1`=JyG8RGGc zi;GvhT`P}4K^SMglTpAoZu*KUjp^}a+TuefsOm4FMg#uh>-djJ`1lix2_u0Sl&$YZ zO5VFE0fh>K3`FsjZ=KsiYzAJ;z*~8n$LDkajyHP*yUFRb!eG2+qs6r2E(!BX5!uu> zKS7{6T&cqsYIa^G`7~QoYILdI(N-!@DORd!56}mdG5u>|EyHF5DH0I;#oi)t^kAGz z3`4(L0laS`(V zbSt4%#z%n!u8iYPvN<0&2$ly?f!QmAY~I`hXNjr}8u1k<;Oe7=;oz7_lTJJ)xym($ zczjIH4l8VJgm8uwHseZ$j0sE!tP)fkVPTMu8xPWT{aBAsdj!+u_+xnOpH+?2p$g*1e~5&Vn< z%HTmhN>m~a_bmeG1+`*qJX4z7p!vT;wLydUAN#sjo>MM)q3_^)XY zZa00XIYj~gg%!ofr+y;0?ce!qKZj!O{?@Cqp*RWhW2<_R7jG(ZZ(%p(o;$K&;)GUz zR?>T+9JS(S3`s9h?3F_lj}QIkAxI&}yi-!+A^2BJ>q(@?A({x{=Sxs*GMUXot_AP? zTLKXBC_=%xFdZ!gJm#$8@1%sVk6Et3hw#kQtVCN?N&)!8%@+2T9104k{kCoIk=}@E zWzOUWC4cAObSsJwjVQMNFy$SJ%p4*fM?q|}YUU?@z}|GcsLCZhdNCITgA4|M&^sp< zO(}}!cccY&98J*mO)a(O4%68{57tAtSWvW+kc@4G#lJ)ikrDr*K3b1F%v!AZR_+1f zG02pr)4<7uX1kPJJCtqB5u7WbV_@tf>xhdi9*@;-bpV@fv3htwVo)kuya4)npT%LZ zIj1gWr#)#@gRAYBLI&l|9hn$sjUUXiRi>jcys4Om8;vm<`{aGcy{C=r3GLhhW>=Bx zdRbx0pF*mK^Ri=bkC0(%iFt*LQOKri3HLH62#w??U?o$B+7b2k%HeOXg|`Sb5#_C1`}=3dS9wRf%@C`y|!SW%nyJFDqk4td!( za?vPLWo`H(4{4cuCF%j-a>goFnJC~F{kv^sm`gU=b~M^pq@+r_IHp@YkV8xlnAx*g z>T9!RVy^XwFL^bG0x+e&dC^=ktSv`D1;8*;qKX|h(@;AOSZd%XvTk4 zGc$S2=UHStR%=(zQR?3osg_HLA*jlRg`Y-L8YLsEwB4Wu_t4?J%jT}4V*>cjl5*{N z*~(A=P(pA_*uuP4UXw=9DRxZQ4ki#(;#aNUs`@oh6?<8W8chF@r6|B;E#)r;>M9yw zPP2p=>|@B12{{ya2&Srv^bX+@EPHHes-O|rt1O6@e8BcBqJS=EP0NTn3aWSfkR?T) zKB~nE1ry1^hgB%dblGMOfvJz+rz&Q}^l)G#f^%xvsP>vR)mjDkWt>?@5%AD*`-9Q3&G<7z0 zdmhc6=F{YyyH3<~Ns3W)V;8}b=nW|VT~pjMrwBD$b@#&4A~J50bG%-t!DlfeLUpOk%svz^ql zFGx{>{k^_oX*P9##unzOvd6^tjEUu zqrcElC&zI*#kNV1j@g;7#WeW;w>69+)7V1+Q(d#G6lc0snJliulm|lG$YS8X*xvze zY>2Qo+8}2~Xfz_rWskT?aI^QRJU~D?z$Y6qA;Fsp!4VFb$w-u`TTVQJDGrSgZPsua@JV%eD7%E^K-LvK7-~t+~)ij{;uD9#yKdRtW(c zkm52Guiv25#S-6B*ECudou(G5jkAEM| zXU$+9(F3717zA>D3Rfy`esET+L1!~^6srS-=_lNkA02GdK8CEu;5OcjgAW*S{ zhhdvjS5mJk#DjK#4elKNu?>eVv=aX_bkR5J1jH)vKW9wkE}c^bs2VAhR@1K&zOIW4DT() z_ByQ6Qb5#5JP^DkV@$3L$1pS1B%bOQOOei#kJ#f9$!_B1W*4gXks>Z-+}Sh3>{OLD zCPOh3k%psXSi?!GXl{g$x(X1d+G@~j()wj#lI;g8!_24U@*$8`1Sc;e z&L?zDlelOZB%)%pXqu@0*DOQP$u(nZP%QK$xX+FG_@g{b7Krc0Geyj2 zPRc7p*_s;lnmnkHDqnTBlY>#Ux1e$*gr}fF8?CQAR-8r!Q|x683K5q9bLkVJ_~#Dx zlVUk!G~S!oY_woyD?U4T}LB z#$aw%Hysncf;H{@O(fn0Y{=pzcxyhyNeNYLGGVR)>=-Mw*&vkwx52(Pd<~`Uq;Rmz z^gS`T1X3TVfPjPo`hxTH9aXdd1uSzpJM&TV&Z?$wH2)-4%)Y^lR8Zi+<=nv=*xy#D zUT9@+)8aRmFhvF6uop-G#4BdeAoi!@d-F9*iSA$Xkxt)eR^Q;#Oi<8OVPi@Hu#rZ? zj;ev|2b~8#w-hYnUv)2J)0;fgr*=&$O?GC#~XS7&6P7e@nR-@G{I2}ONSiFAtkR9@>*=N)l z?Gq!*H(PuTD9deL!RR+Q{Z^}!hh~q{X9iZz3<8PiJjYhE0ZK*_)Q>53gAbZDHj~-s zG1_>q)dO^|UpHN>y2xv_0FpGAfUI@+{XS?fK`+PX_j#e{@S8olsXKC~@}$T%{%ysM zp{#MDczVBe`rfR~JoJzZJa4ocz0j}mn1T4U0y_){6slAUpS<6Q?>8dT#Lrgb92eD+ zPJW!WksjMbVQq`YX0jWsUc1v_h9SX?LxoF>D1A;7w2>Usy6Tg49$*knJ^{#U8(abU zR34AlXEGbiKAX`Z@J5}_XXoLYAlBebeuvNR6g;5g@PH1(Bp7&)T_+gNZ7iEQslQC; zck=MhY4JM^0Fw<4pThyoCX3kur}B7tyUsuVb}{>Qaq^gf{dy7ecFx&Q%~b}*tj3Wp zz+F$d=Pt%)^MC?;mm;|_d|b&c%b@+dSHRs8f|*OqWXqxX=-s&Ap2L&A2!2XBYhag2 z^>53uw7RppE$2LZn?yyLkM2-+N);ES%zv3O(}Z-k+i2{dnbC$d!-2s#$QppqjY0O| zMxhlN_eOYJD8*{YaXsaUL~z1}8reN1_^NX4`?8~tiJxU8y~y{iL%V<2IQ;$y{tpu42ZjY@!ef-t^BJ@uD( ziWN`oBB%beP90C1*pa5cbWyLjFxA=Ve=Q5u?0n0N0_?@s3Wwa|73p}+1E~s{FOg_$ zzdquD#IO1qqY>C?Yw4^L-#QNoom=mR)I*bFQ{}ZsaF&?{lqJ)(c}-{ugr$mh=Pq zm#0@}WU}MgnM)XZX6@N7{dow^Rc~T8$nZO5AoQq&DxOuzGwb>PNG?9drO#g~YPz(% zuL$m}p{LE=>1r965>306lJ}HwLk&Rc<1qzHP^Edc1V8UUQD&h+6J!gq_7p5NrW=t^ zbG$`U#O|h(gQD?4Q8vhQTHM_l5#{P`{O$H)c_SYR3YcGp8kp~vY6$%(35^Tr#od^N zzmO3seBWxQ2Jp`f0Igc(5Y^xKAbARnpF&Cy()7BycK;Ps(F9nDI7uN27an|4nG;hVJ2t zsSC37dl=hG`OKy)96TSdTro#6@@yK^6A^Zo0+Psv2)3V(hVb(W_QX20|MSI zlLI)5391hlLx=4EB+~nNGzMHvl-XO2B~tcPTBUKS9;hSw@e6gtY8upkVbzmM<&~a< z-(S*b&N&GQb^Q_&y04lZ{HYArEmGCyFrT!;%&QjRA1WDRNeT4AkFT6P0y$BY zt_F_T3#vd5-kpc*OQUZtoO)R{9nPF+&78PYuD>1iPRal{KDZXS=l7CYg#z&Q!Nt&k zZsN3=66j&+(wTiZOmA-G0d_kes4%lq3SC}47mctZ1^8c!2}ZM-xlaYwsoy21Iesvr zzDr6J0{g>UMWJwJAF-A4Bx3kBYw_#0QvmZy^q35cv(HLh-$5@8lrH>6cEuvOKQcHt zhIi%T^8weE{I1CSiWrecyb$W}A_@D%>QzeoXFi0mC-U&4WhhXRzOuCuR~TXPm}Zt} zU|J_np-}c`MmafPCrjTz^HyqHnlZ-YCdD)U0rgg z$hA|~-qY3%0-(yq_MR?}apB%9jJo$Vfc5jIRH(poSqC{BoSaU->h?qNMC~4)5rdu z3yj3M7m0bAypkrN`0aO3+$Gm+1p2hBke#8{{YSe`9wOYoX%bg1gg6q`sXwdNxKrHp zMqe~C>^`ObBhU8LV(q?+hK&SKyUjv)Z@i)6-)ePtzIBWW0ZRQNuzBhoqTh>D{sP=p zihM*79fEEm^MID=$t0|JjV1-5!}x%}9xt$3Xjq^)KI{C+shZ10W4|8Ed3~k^y z_q@lB^D|YIDH2u;#cUypD?Y@vrBrMq=d$s0WFXG`T?T}wJ1owboN;GO#w-^$UU`nu)pRhotvAh<5H;ExUFKT7cu%y7M0 zM*AMbCHAk{oU@ELmkb5)CykU4ir{B*#aH4ofcv)np8@F2_S$|dg)fdO;Xg`?mrL=p zQX~-B%pT?JEaLi%?61;UC!QTBg6cmqDnJiPXS{&;72-Lr%{BEAC4pl7b%nOe3*DP4 zPV~Sjzj85GEd_0OH2-@@k|i`y{9+46>EegTV30}6N8BqDBQKE26B;;npU_OK>YO^E znSV#azN48BE&M4oZ_i-u850jK)Zaq(`@~9+(KfkS-Ts$)_qrB~k@^I+P7r&;yc<3*n7}anmIX<6!7WA_i|ShWs~h0p3|Ij{rdtn4DqcnRC}t(CcBb zL;o2{j*6Q{#o544_4GFl#KjZ!baq1^nivmg764&+ExRg*e`Hcj`=Mx3pQr?aALmu7 zI%pu|g%PMtl)`2nv}*#sx}Lq)&!lsCgF@tgTLPF%bV8 zCnzolEK|=Cq$`2DnrlBsz*q_!UDrUq!m;N6RYfh!nH|+5Wd6KV!b&BmTe$9l!$kyYnbAvXLt$is&&=(`=I-QHvCmRe=U++TLkjy_BL)c5aZ0jMV@HJ-b^Xk z6P~#oUs23FYGWs|VRB;3*ET$wTXCWU7?+YOfEu36OxHj^z`)v z>c-pRWNVZE&XK+UMYv%R{9$Sn3W;CFM@;&2Xv0|qF+gi8CyCBflf?!I>7ag;(_!P@siQ{)FJj|A}g8@5FbMk$vr++qFAB6>C1> zS|U*&^x?-Ms(o7a*`@mqr{HJ-1%Jie-FQY0g?NRfHHDh4k!x?r)L$d2JtUj|j41z% zZgsVF@$U=o^be9#t0Yt_56YW-)QF=A*DZLp1VEQ|HBb&8bg7E7oY~1EX#5DmyB5pq zd)m6Xf7{f8FJDa7Czy*bB|b#F@zCrY+E4VvvFfAw_!p(RO${R+{|V9V-li7Sn!15! ziJKl0(e9BzP_?Qqc^ttpa2&DgDpM8BX(@j_*l=g1_-ky)CcObhC1qqbU`8LevhP}RV){k??aoI-A&j3Gf$xd-7&=+_sf*V`eKpoSQ%lxwtK;#okN?y)n-HVv3 z+g1N|s;s%<6;P2}SBQpjA*NuT1b#JrG6SfzD6=gauUUU?dv;PwPHOX-+CWMV^ts0; znz)F7CfR>9WLF%Y87$tSy(v@Gf*~RrYfyAX&U`Efj%Jt-Fc&US4)U?e;lMCvsT4oS z{9KKJxW2qxp9hs)lphZW$w1mfAdRkT@9F&JZ$#IDbhzd$!h0`f9^%MonC&*}iwJg4 zel<(51=UCxIhHwpf+#uB$30cj;{YbfRLLsj&O&h|R7jPCAq)z6=ls7^}g4v-__ z`!1uRu~LDcKsk-Cxfoi*|60VvE+gSiKdFYhUQv{ioO=W>k54S4K@b+iY%AsCHegY> z;@>6eGfFn2Ah}6AzDZ1XyP8_&^C%{d!uMO$N=kb+hsmWt`J7VE`3zVwN^!9v=7}D1 z5U8GXSJm0t;-x8fVDc1XVpx4y-!-*z=xjp#zDPg6Sk$z*T$T-m$LgjA&r<59tqaNl zAmC5`0W?+}r5~<>MoR?m8Np{<`|i<5DG%?#cel^H#5}c}j&Pt6_vIqN^s+Q*k~Etn ziZfKLtJdQxeEtj~-r1jP$`sX}L8elI)N#qb(c!-l^XCO}t_x7-Zyw{(t1!79b8bA- zga4*&e<2t-&wRK@E0tnt4b*EhO903L!p1k+$)U)2?dJJoqNZc2fdWr^`b*n0{ud znU+~p=W4BYw}A#|^|2F*?2r#MDBV~Xbo&*bmmHQd2h_}i9LrnI!jK&2qlhs5*ekmMW~ zW@nrKfy|elPMg05Nv>(^fUPyI_C`2yy{l(MBUoV9z!7@KiUm+mdwcPn9#z^uDlgBg zPk`>8iw86T6wp>yYM!QGkCFQY+*gKg^Z-0HErxvx0sQ1H&=Wqj4aG(t7a{xjgWdX1 zh~6*LvRC!EVc*W=t2FFbsP!CFB^MC?cZ@F}46e2n(D$z6THRe;?zz>;4AK7`UuB4t zuG&r)Lvy2oY*do{q7nW2UWDZ(LrnS6{+QRb5)< z4n4lP1!A!~3f$`KtK?`HXHl4-w7+hu`J)`0B{km+vo&=9`9nB*6)u!Of59JQZag2G zC}{j1p~+~1DO(Jc?IU9-{3{7cr+PEeYLSp6VhDFoR)|$X0A72KM*-4rh6UnCjOMl zSwjPN7G~;&3(M)hqEsS>z~>U$KL#j~|Hye0bf`q5$kz01>92k54?HpSZJh z>i)*5W9I2gN)bQ4u#xonCN5b4@`$~b3EMXkWNve-dn>7E+WH-Z6#kiJ7n`3<%; zX%ZAyjhC`V(%tW_`U|e;mKUGH_hqAa@fpomf^xD{o)`udj?2iHD*%go_+e2x1eXV)scLi^t?{$3BvY{n1Y>uQ;&)!er?qcpkB!Wrld}FCeNdz zr{9#%EM#?c>c;iVh05AR3uf|}C*}B2!@fc7t(7x30Kv7dZ`;Sr3)%QTHMV?ehSVQH zFPZ;W!ZAcP#EZ7>_TQW`4OR}P#Nv?$YFR_}``Y+SOoM zNeMA7A=uLbw7-8821LYeOB#f`u)lM#E$)h{$rFpl-7I*I`oZAo%P8qqBsk6GtGlZ zhS-Wf06q+FfU2sCdJQc!E=Hfpy@eM{4WG_hlb>=|S zCYnDs$sU_Twf>>&c6t`#agQyU=VDNB-#biu!|V{d2m`}Yk*j7F1=-)z#|sPRzeSR7 zfg5XB5x#!cblbv`Pu1e*ncfce=agoQeb|Uk?I9yR=2Lv7G8MeO#mugBqHKUBw1+aH zCy9w`uTEvxM;4sfsU=Y7I$X+NXblUEn6+24_ zWpx(_mD$-+Je{pNx-&n3yY69s7zA+imAmHt6`qGst;6=`&@tHq5wn~-~8bis~N1=-8v|LnxQtw(Py(dUTY z83Dz{N%Z_lM7DQsXtnM51%8R*M|&txeJV~flO<%(hp(;1Z!br>=g$(b-S2r3p{#ec zy1MFmJPR`?Vhibd9{K_Muh57QzrPZj6xx65lP3u{Y$u8AEl4ED=9_Y2A22{>%O z6H2Hk+v?n1uxWM2_i4m`$PNglojCs{T&74KA>oJ~A>|#e&dzqvotd|uL^L4E2yvf$yUB8)kQJoPFZV6D)M66-yuH;7|IGR5a$s0PG>Rt28bn=EM zsL2?bOMXqjG5$4CqLVRB-N231bfpZraPytiAQ!{S?`8%f&?FkONp8O=8Ir^rX+pyONsKO^lDe9`?ue#`Fn75FLSUa^R#w>iajJ(Kb+0HC8$fD!=^rbI3JBM z`ZmbRgK{P_7vD^^t=Cu9Hm%h%3glzyR)sK9CZ8}7Q~L_0uM*L%O!_H_V(s~iw86a{*Il-;lze=lKot)-xy#eSISes1JZ!^8vJ zw1j{8kV`Ez#Rwh_7zY+@Nw3;PNOX8$nFvJ51`tU z3+8`DlAmE1Ei3)3`PSnE4Jc+KMoRGs_Vv-sS`Lew(izb$oVR928FfUmYv@sR&2*JS1MtHbu19p6(`+h@RjkC1Xb7G?z!!I6Yz59|)+$zy+`$y{gy2coTW0-9aSd`vNm*9fOo%7;s&YE^bFo;iqD-w53i!l;Bt zBltKV{2wmC*C_G6D47T_)(hC}Tm65bRKK#C*j-J4POaFATzWl$U!d{TGRVr;m6F~d zo+#Fr5}@5%y$J}^QCyd4`sfzMSEG9Jfsx|0iEkI{R};NPk-QbQ({~QEX6!6YbCuCC zc)ADhH?Op->@+U9pN4&{I`J`3f#ALs!htiahrN_J>IhmZ!1*2Uj|cs@;UY& zRU_+V6Q#s_xKI@?oIf(m92s_1u==Ok>Iptg_4HB!m9(bzBi^w=)2OPf#zmX8zhl{| z%C>SN(y^;A)ii0Ti)q-&9MeBumvaI8WL@$CV*Uc6_yTHmQyXr6mI6lBQfCT zguQy%1+d$Sz(~{7%I{F^zuw)vX?o-gG0|Q=KYF1Gj^T2$y@7dK3S`*UO{xuL$(Q7+ zU#@0li_7(C&-R9fCckX?#Js4c5fR_H z-p41FGfN966>o1-zu3?Ir3IF%+?&#>GE@5iDy&keE&RdztJ||=El^VbT!PQZfDc+% zSiH34fjDTh{P_2~*nj0=suU9cZBHrTn=ug5;(K*KS;xlT6whC4XRftBa0$d0cYXLx z^aT$yttfs$=vIH90_WZ9=FOSzo}S$b#@G%FB0B}8}9{&@qWZ!D4luxf2GXU zI!p}UiV{-b@EITbGGB7JK=MB3@NH0BZBXGY0PYv#O&1y$R#ck_4kl@xNpl{kdiWsp zCx-$Q*FJ*xT?inO$}0I%U*gqc$s*Q-O`B>|3yr|!;CBz>0}{N)$-F;?Z|+8MVu&DB z1(z~wq<9iDJvHpdWvZb?C{nU{$GH-6T0K4S*EZys(mpfs)y66NwyE1x6W`kA; zQ9a&)qAb;{kyMyKs<1_%9myf%E6puZE2;P-hJ^FcZI!cu&Sa(YsgvVtTz*^Xlvg)$JLn#~+M*C7G}-@SjX0 z&DxshQ14Naozudzl74-w_c~(3bm0Rppx)b%96G*zToN{!g&Eg-_!V0HX%72S173+| zFRztFN_NFH2Vj~OUxXVsD&c`5pnTalbGP=-_vqoFu^6*xLrRcc|03*4#Ghr!^snvWlUi}XgBWvwofg8gy$1`oykKcu}4T$5%0_kSLHfOBIz7$@UooQ%0mKtPx< z1Qik8WC+TGB50yv8*GU3paZ6mPNB4=9E-%StPIw$!vN#niI0 zT=(akc3u5`_wT;_->?7m+Vy&A*;a zNXtkG?K2B^uEuk4TaMxYSGSQ9(rL3`etJG*G3SmZY3BR8>AeNmHA8Xz50iU?z7XaB zKeazS&Qn7SXE>;;LBT1UrHWh3e`>kR+QoBWiI}l~_A2PqFze|wQx&ZmL*w+~^m_4L zW|pB)NAzq3&ZBIMWi5IcWyNq;B2IAJ*_Md?;&i(!fS;UNko?KVhdK=Kh3*WSp=@ zmGjVQ)2>pt+7xO&vf4K#tZU`$CGX|?mliUaUC$n6+#Rcr`WHOKr24lvcW+G6O!}az<-LU>e_baH6x;nVu`#C>BP5V`>vl7O|aSFO*4S()oVxSMH zc}EoE6K1dHK0AWGV?w(vfh#t9oFQTh!hd^kng3dz!D-RDL@`$Va_ZiBAzkYveR~+i z9&TNtV0*SYkL`ZN%-x&F*gGF(Y6UKP`^P<2)8d?aWLr0zUcpZK@>ZHsOcI&dor8SS zjs8foL)R;0xNn3r|LA`ytA7)5^%r?mrmq%bPcqz#%@2uE5C;gmlX z_VG{_1|V9oPRN+g4}1bQ&LjB8jHIy(u=i|vPTh&85lfOUnbvdkjxbrfk!m;L zdcWNC)COYZJa-!Ea^Sw9x>%wAK`QBj;T^YTZVp+7rZk<-;u|j6Lhj%SS*mo?#Lpn8 zSGRNDCNu5!Q*!RuaNZt4j~}MKd${8-2=X4NoT)ZZ1L{+K2WjKJTgM%LB0)mWZ|+Q@ z7g<3&4>fLMBj^6uH!#FMUDCBgZW%7AN|l+7BW9jXUvifuad0@3&qpNKM$#+kD4mA7 zXeXPon-7nquj}!(Z;hm?g)Dp+oB`4?YU#o3=D8}gSLlQh^yOlHStKg?SMIa>bmql( zMAeabc`rz~Up}Wt*}Ti2`~0LUA#}&MvMN8JlkT`;MV-cna5O#3@MH{AlJn7SjQUK= zXh1_BS!3ZP*%M?~t-7u-;xQN#sCD%}yeemH#s<2we$!#x@^qLA>w+Ql5k4wf*sTPz z2p}@WwOY$fB1i@1a;6r1!Kl{Gl2_6$GcV;Z7zhS5h=v{1z~ z5Z(5tC^G<#1G$C&Hj2CS5jXWkXQ(ip=WZ{iYh9QAV!FmgiLEo8ge@s5y)tsDDLDH- zu#lUt;NS0pE6>OGYUvSu?*&@177Z@`_HQ(`kY;=7Pe*CuJ>a#tnz>)bp4Vzz81^@8 zebSUkfBwXGTY`TAza*46`pXK-W)|G#H%8FuSwhCY9F(h2qKn>UPUxlgUZDN&(m*@y z_VixUx3o0@Ze{fH5$hLgbSN?F+OSY={s=vPwOaHzd3}0W-!(>YttsVn_pc0$0<+Pr zg*U6POz}MR{V0FQU|>yesX%9&OJ9$n>mD$?n?a9!RG$bQm6QIsr-bnLdGIg{FSWcv z>_%DNpN!&9Sz)CsC1=SWjBG|5cPxe+=jc7$KK9nn1zjZl&Lmu2E?kLSY-7cK_4}t} zwML;^#a)X=k@+M`UDdc89ltTMi4NDhVgBD3=Os90ocwB~!OqeFtchLr4ZlLetxhZd zPKR3frJv}c6`X&CGu+Lp3vs-)$C{Mr?zDDnoY^Op6iM09wn?4`>iueQ=Dg5L-qzGW zvxlQiyXb-VuFRxH51nhDPiHE$9#9Et+}za_=;0SC z>hm2F9px3q5>KUN?_IQS2}xd(Nc*#;MGjA8|L%HPav#0AkPECj{Z!(caVK{28~d3a zfiv67A5LawbDzCQ-$>%8sOT@Na340*&*B!|A@jI#XX~KtNHtEL!F6fS=OIc|a}WQE zf0skce~cE74i~3(yoaxPsw+jU;K-dC=pR~Jg}bc}ff-ld!ru`^ALu3({3fk%z`$(| z(*U6dj?d*bL(^mG3-Sg!&A=_(nfD$vhECf49V`bmwDSEWE6mUghkWIa9%Ff3HmQS^ zRg_(Q?_FX0eK}u~>?1rp3daV~yl`%f!>}y{ww61d5tV3@qdI3`5Z5A{-b_oh8uWAP zYphMlHrlzhKzcuaC>hEPY!>{`=V)|z!t%5Yl}l~u@*Su@k3NpFdwM$XT(xvqRLX7P zb_tK2Vdr5w+(h5w(JQF?k}gds`2K#V2f6+^{sLp*E7Et03a4n!1*rx#|HPuJi*j?C zA*M=h)y!^y;lz-8kblxkH;>hV_yC|AEjQQiO{?mRZ5+&R!`7aWlOQ7l__--`rZ?e) zthTuk(FM{r8h4oj*38q|F*O4z{JfG?JXAFSd<_Ordi0m3wl2$RxDUMU`!i z&9n%nefu%FZJ~WQaV!yDie#G2foGPEL1SfbBpuLaAf(Jv#$=lrn5E5mb_g(Q;T&p$twGdaUPn2Czz`%8wg=DIBEB-nZTt^^unrbt zw_G zZH2B(9m?zM#|aAN1a5F)*x<2_SXNf&QeUKVhdhCMM`*rDbPg@N0KV0w*hNMon%CPsh&$ zvx;cZgm2zCI@y>yS7c&}r%fR2NL>=_b0SNv4mR@ZZw8p(=wdkcf;a%zNQqXY8J3lL zx|yN4Sd}6U=LQ^3{U+mf4$wj~h?zclCtsB2g4NN2?j!aZaDZH$C7qiKTbw>otOWfH zw3H$+uE0xTvHC2ZDw}^3(oB|RH#2FftQDBG;{0+4?j~aejtB)6g=wXj%2Ys^US2Wf zOpb)HZ7pPRg-u^&2;|r(TwmkFAZ|wF)WLacc|dNg2dM@1t-HZjE)V?5kY9)X&Cf&s z6z$n5KTMM|70Ksi_03U-G(mV})fEvy7;#F2d#8C;??zdT+wvH(TjYIxjG_;FZ+^nZ zXWl2|Tb*b)LYq&0eAwIZ&@hS68Dn#kJW8~GxuDc)stxQT{(VGWG^Vty+*Udo$L*;6 z&UP6bX1iGMWt^SP2Zy5JD`MHOwPM}Hh7rLQ;!@Sr$O# zuR|d3U}PEQ&NHYtYTRoMF|N*wYrg5cu<8$fni6*&P`1r35w<~2>qYH11W8SNBAX84 z1ORrkMbcVpyJv3joOqQ{U)6y)G#&?N*LNiFJ9FrFMpoaDpujIXerMP*wlWB?@Us5G z#5ba6fcp|+*}!>;|GXsix)Bxk58Cx7FG`$WLOt^h4o$Yh7Z0gKI^9>gttw#Knv8Cc zrqJ9Ad_+1vBC63CDSF;e_}`JJMq{GL?^eKs4ljn2Zc=KEB8{^C;0NsJ`qthM8cVg; zDOJ6pP%LFp@28A^yIfp99#pWCAxe8TwEJ$kYBJWS-c|NbLbg8S{WQe#AY)(2_I<`E zJ{wwAoNv6rIT4wnt~zD+X(l&l82>lv#NAFVo|uvjEQrXm1py4r(5+7TX}BnHwe5Ln z4byz$Um7fnxKEQb7{wORf`&^Ld2FictXXk%C)paS<{m4d0Uy(1Kc zLvtSF*veOe2m!<&m&>Y4^>`#fR|89EzwU1c+O4V?z&)BiWt>w4bn2VPcGe9y%SW2# zM*M01JG>#cPYr+pSUzn%>*+Z~d=sFGu<_yl@@7+Ast9R=Av}l(Bva$=U~0%Bet0+v z?HU+&FVft9;+%}AjOD#JwHc{RslgZ5)IuvG7W;if`IGymu)muj0#a{=dP&6t@2geL zznKloGDhxK2?TUK3_YzjzO&_KEFNN#5YrVPN}%xSZ|qQdoQbRJK55-e%x z=~9iR_cYjKfJOZ{Z66%w-j;;9zO&N4%Z%c3lD!gIC`f2Z9Hl>8W=?di`bZSAb6d1J z(Qw;3quo713y&fgO3rj*P+<*hG?}^en$CoxHJEt0{{kQ@6q3<0+flaFJpBbTlProS3`nFi=oA3lhf?wWs^muE&6NKtYpb$W^0iwq!nWDfOjv))YG#_)qOQI-iDP2)e4XTJ%?;RfU?;}Z_%b>9|LSC4a@vocWrVq z`5v`-ca-(^NDa6=IAWY*gSt&-v|%QvN`tY>H7{(*ah>xwt}8+$OSOZ6U=$AP&?#=< z$S*RtkKdv>aTrH=TNL*Yupp;@)CS>Z4W`tyaRI6Pm{hL0u08xn*?mQVju4DyT^wB= zMt*MGZOLTW*165XW$}F5=ysoe+Q#76;d5$Gil2G@=fDMN#|0@1DZS^LkR=zG#1$&} zMZw8x@F|*S@eMI5Y+pv_`BanwC}@d@PKVsTXU-J$L~BPlx5_lDf| zxk}`J(Phf2ON{9a%LT$G@NlLE+fTg*&&n;F9CM;?NyoQ@9%8{^a(yoCJ|yGzVR*&0 zDMd%Q+u8Xc)8c+l)}H44kxA?6HN8upQ}=v&`b9mMB~Z_$%`oYMD8Tcd_edG%;w#?Y z7=MCNT(pl zb=J&F#Bz_sexIW6BBQvdLuFJ9(F$~}@&5s-cgXd&cXhy#H$eJHPIo>n%CF;i7K1#x z-YAdI;0*3=GQC4rqV287`%1F)EE(vGhL@dbS>DL?g_7jZnJbjlcWQ2QZLS2y|>Lx1@ZhkxeAr0aLI%QeG03^fwBh9p?t2V1_Beu zI~|9$vTToUYPjWH$)w3awLSoYfhqEyDViX=_|@^;)27}TIHx)vfY2XB{Hj~Y$%vnl z)8hYzUpebLV#0%Kj!FbZ(EX;ql90nCXQSeN(FDnlXJc6uQ*@`9TVis$D#N+VcrApa z_1@M5g%)2Vni(C#*uGyG#jm=2$7qLbq9brtVmsS2{zN7wmdpDy&Z6g_ZQ@l5+1wd{ zlM=jgPD*rzl@sl#=C6J!g+;B!W!t@fJbavJX*7GA5?)8^ZAYB*#f)efCdgl4tDehk zk7S%A2B))d%Hk*k2jrNrbby=Osm9SFS{)q8a(3QL$fw<>McO!^+uo4wuVkQ}($XkV zYC$vmi;sU0OU#8vV%1pD4@dEP4LI<>A8!*8nUq(tXxj*_u*Vx+wB4AFb$V8i*t#k<% zgs8Pncf{JL`+*si%I)um7XMGgT6!A*OMeq<`{tA6`Fxv}Q^sOGSkU)kSj3n3g2r%+ zCm~nUhtaK8~&dg2;>?gzaSFL82=SwqQOIV`CVhb%coo{rOk?`c(Ej85Q zmNKbxsuTmMJcSI)`1;bflHhTWWq~uLBckc<#Q&HXe^3$@R8zw=jRxZbvT~`hlTH!&SzIv`OSQPmxaP=={_(i>*m^~xGd(bX@!$}+ zEu7q{gJ`uVoV-K+(q2a}^CRNyeT0}`C6pwKu!z!PiREpAG5T1H(MRc?`S?ah+%>_l z>#%x_spuV(3JziLms{LvvjDq^h~}^c)N}WVOf9Q{FsTVw`6(=Yf<<{pPbBSEo_4WdW#;ayv%SvsMW2KNnbKa!D$t?ZyZnpq0+`soJ`g%pn+Cz&5ObEViL@RjrWZSRJAa~=6zDwB&_qnGaA}`SReEU^DQDMs!15qPbJzOO&^(9;F6s*Gy+yG z-lJFHl-XoGLUC#y`zyn5NaDhbC7)Ei#_p|G^(~YXEmVmtSoy|b52^|(D=IxrgS%e~ z@0~yP(FCTTs6O#nc+Xnl&cx)sozrMW#)MaUJ`+}k!8l7hlV_tB0o@9aSl~0EZ(^+X zi1^IfW;9PgH@h>O{+Q(5FPVo{^Z$(y-K`T~T?u*=E`6ghnN_p#o|FjY(rEteB(5EO zXmIXL+H{;Mz4aYI(l;7-^V6_$WyQh2+Ri7$S^fwK{K<6u$;j+wuG^IxbQ0Q<&V9(~ zucM;Ts;`5PJ#k-uZhsV>Lvq|wt+Se)wH5loQ11UC-udCSw10a#boI4fzd;*n~bKx*#0t&eRf~TaqMeF{-mgZOIu}!~>^D z$0@S?q3V-l?`nBpD@kr;?Pd0=ej&?irJZW`ZRXozou%A>0k*1TMf9UgPA1S_GLc0w z|7NgZ@tJ%_k$8gT4@O{VzCW9(JafObCl^B3wifOXcR0oTNdz>h(}&U%3Tp4KHXOXg zS0sU%-10qRg!AOO75CEoO!7SjKyVb?#WQJ&i`ic&=ouAeM%1V^CDM%ek z59iRCF=!*x+XvB}BwxC!?~0ngq85ATuJPe}>q*}VMzLb${}x4q_zb9SY~@poHqZ`= z;KMH{>n)(S8LK~)?HUt04@m+4EqbOH)mt!bMogQaM`PfI|2T~MIaO~=8V@sCL2|;Y zx8ZJXO2cr^Q{QULO3z5DNlwa4Ho9xuC{@S9N!EbJz&pE{UX7tLjb5}g<2J3OB?k1j z>(VeM;$5*pks6V*$nbDCtKdFt!p0Kc>YSJ6o`+?3;VO6Qcx{``5rVXTe%rA_NxpsW#q?!C*Y2y<0L%0 zzCrPuCK%yD-y3wIlGM-~3oTA3pEI6-_!;@5QS6I`nrye@RM?8S`sdTs}0So%mZ+TV#Xqi5Ko*RhSl1O4pZGO!|m z6xk@I*{r7Fi9^LG6>oDp&Wk`^INRw|V3RY#^Z;@i#blp^<){e}vqGPXH4$;#;z%W* zh^SE_K#GI_w^%P5592V=mSoTN=~qe8#l6;A_Iw z$3T65ON^}5oADzjC~f9j4YT?h$&$BNO+jTbteJf> zcC@3^bC_K_2|#uD0msG?UGeq&qouDT0alDV(+NhB+jf!92p1z-yg2#cCewwhV2Ew! z^OEqh3`+;l4M9UmV{cPh#>=FCG`Oux=Qe7qxO01jI2 zt53<3DlHQ&SPaKcDKDa%^VwqCWS9*Sgr!5#igY$odptV}bDKDmfYxxk!Z=Qe^DJ^mc+DvJ)UzwNqhac5?s27Of<`DAwd)`WoRBmD5}fv(6t3zHQRJek8e{ z<2|;(k$CN>dSUk4P0`&9X77h%T{QEU&xFl7~qr=cb%%B@#O3N6p{0&2 zI9tktMvThKtG*el8H~}J#kxYs{*bU)=DdP*iBJv65{9*y-R6!EzEP3e%{2ww@C?T6 z87#Rw+njf^tS=NN$j~w|Odhx5mMvi<{hwJx#pM&^D*UC{FzKiNGm)sFceUWoa88uX z_Ad5dZ5gjX7|~#|xVrOssMheZ8~%qtqT^;_{C64=eXJ5)>H67$L~{LQNhJCIEsh8Q zS@aWa`akoCY?C&}cTbh{ydo=WqRzoGV}43Pqy_~>vxoMJq%q-16>euE3gTe=P;+3W z1h2g_@$i=xnTD#wxUH%3L&&cgdB0&7<7bpH`ndy6r zB-~SK?qv4o%@MXn+ODX!mT*&Io$nvcwlz`7NFg5Cb1mRRG@ay zwH7jH{WPIB7>J^`tNDvsG}u-N{E)b~EpDq3(v^m^VD!$P!*So2KBSM^DQli9w2qln z9aoy8cQ)jd0u4734|< zu_uQJPe)h3sbn%bN{KyRq8{I~p>w+V#c0Fb`qE2M__3};lC>%N?kWiuP<|78NUAr; zs_o5sjTkRkXIK@_T5v2JPIe!UIkZK}EsI!EtQY^bA+HrmGIH&0MtN)JM|_1Ib>vLl zFj=-45h_b$#9l7-4$vPRso_p5`SLK!>PW80QSUJf=0(n272%ot>*0r$1MpHY<=quB4FVZ$)+&!ia<;s}n4mBD6kGR6d(% zGd>>4ds*V|R^S2kEaB*1#Yz82%saFqlF9JDppuQAK|ie0{~eddy;5&tRbp5k9~~WV zamQTTe~ZM!0MP#fJJ<$r^nX(EoEYq4EJ%ONzy=Vh!-?+LpN#HCFdhx^ecduY|H`4X?X9fBZy!Q4Z z+1Xn2H#&P~=zH;;zg2eP-jrj|!D}EbMGbu=l1m*-RT^$?Ed3)%1BOFZI`4}!D|J?x z){-A$Ul$qZ3^~}j$wGt)Y;~J-Z?ZaZaTMjEO4n)w*O=~WOu^4WBu>h1G$P z-47}ZroqB?up0Sjj-Oa|otJ#k8fccEY?jXqFjVc}M~^pD-Kq(4eVYyp>88YO;L64e zu{AQVd_PU+-)=OoXN3i2*FT289}$|z2aF`oNZ@l^IoWHv0qey-!>h|El6v_|c`(on zm6QwxXo6o>OP^zN;Cv8M&04ok4~&=MnE-ZSfOn5k_dSnPQ*uP&z=L|QGEfOAx<(6f^ z4dI=|y%%j+H;e`3n;xu!zWp~S$Q$V+1DsQ6Y_<&3!{M3SlXk-cW9coad|o5u`~&DT zxN?eL7J@DnDXveR7`Qj+|d~N zoSSJhJT`*MVtHeR>6oSfbKF+4GB05QgiF2IIKkD@A6p<;qt8sm*v2+ny^D?)ICq;R zozUbMp#uR-e0Bu>@H;jvhH;vdbdSTK162W|*%rfn+4Q?1LQFZ`tD~Qf=HD8N4w%if zkgda=^NDyHN8QV$M%+tb4Doo0?4ixnd z!p2-WoJ~mQ*wIM#@N_EZkGAaj4%##eFk`ZnnZZAhZ$cJg^ITvF0tqQyr9>a|9ld`7 zeOut(8qu*K=6_E+E6@HfX=gW$DZ6P3nZGaxdg17idwwggj*OagN(xMk$UN}e=@wVQ ztd7tq%WesOR}DH9jc!{CI~o^ynHzqP+r|i4MPQZ8^7dCUu8uNM6zu7Vs5-|OR@BIh zj;ayG-5EkBQ zjJ-88Zz&SXo|{FqS#0FBa0ydF=j9qkjIRzOOtyc$#;TEY-mNO}wpc#9LO;kiJbeo> z@Z5N3s3{I_UgzdURnW_NIG#@$AnAX8m#PAK40!?4%n*<>tArG2f`M4{mS|+=w6r|a z##pj%XAVw6I4yu9P}Xgo6ATxqi^maa7)biU>w^)XVX!n>4l`GW$$<)eqJhcuUzpr= zyWAfqS#;B&I0&9(b_acR5o7DJN$_R)H990QdQSauyy%orl64?aSrN3cZk^5=8snyvXn*pXv6?vc?5TEG)-3WU5glt zJ)NOG$?7w{pmt{+KNm9IM z@xzJWrrxlG4$LKLkt*?M7;ptQf*6x`S>{Rt&q;PYCy|xd=$U-Rxb|g=^y-0`7e*~<1u4Z9}ozo+*FS~eX+vOWEKU&qktj@ELT{6p$ro zwSw!JLQhuX$n2pcp0-yP-J!wc#@pV>I6pUk@5E#%8Y}}cWQ|ssLnGd!*(#>Klf@74 zWgbm!<|d3jn}$;?Hz&Wd8W$mB0^_1zPdU-eOLI@;quC9l+6i}%q3atb>uOVVHOTsM zL(k^=V?(>{tPH%My7Gbwx93v*k_DlR^~zZ|+fW+J_E!{)372xuC^{`=!sPNFBKF*H6maA(PqXgM0N1*PXjHH4j6<}JMq(>)d61w z=ZgruNW3o+Lx{%3D0W@cluI?eMf(@=^CA=C#MT*lfhjl+@pW4K7iN2wFGALp5#qPX zED6%rB4j~-LDiAU?mWRdUZN3cnC*ONY}8e_9E_##J6U!y_D`gKP4Ef1z*K^!U448a zwJCOt!oi*XrlIqq&=NHLYDkQtXvE|Xk>xvm5Kw(fn!Y8RG0dfr?n2OqMac~cJBz{q znLyl!QI=@Q#V8yRnwE_a%Sh9VJkyLl$x+@$Bo3QDndloJ>*AHW=hy8qlBT2?-B$pD@9_oL1b&U#V8DaEneYbN=KkZP;U zpCOC8X8XqUqv4!jI&TS+AnnI~o&fXJ^c@2j!JMBvPAOiyEbTa{2wY}PUS{~x+T$M+ z%Wj~5dAj0`gfBTR-LSrvnUQcg?E-h9@I3YY%J?0z;@@#Z;)0}h@RIaA$jnj{VO(UH zU`#-XxMVG!qI@*w%}+*KcH+C2fGwpsfBK`!HxobZxB6EdR;RDkr;n{!Hs^pKkF-i- z${)}Pi7d3w2d24y&K}RumVVqF1Gp@XX*?0fT~qT3$`eZZsY;OX-eTg@_T6YaI)!F&Tl7qF%l><`` z&51+1k;4}a-A~7{ME{@0f*%?BMKygYS`x?Bgmo?Q;{}q>2spg=8)}fYxSJ6B{2Hx1!+3xESY#o*>O?Yl_1cAF4GZVyDD*KINcn<|Dcz(Iumd6(|LMM+Xk8l$P|-Sa>Mn| znjjRi6D}Z5siIZMESjWTV7z%@e`sDBE!>bA6@+O%etng2%O-C3G+J20kLbV@HL8I( zal*@U$&-ee$-Z}3e^D)qNJrl{k1R^PS!!cfzTTpgcwUl~A11Uj!qr#P-OQ!gP4CL; z-TW`BQo18e1zfc<`FPI>F8Wcra~c3i?V>Src3J(0>N3j_#(qfZA1|&EnjyRUd z@_!Z8qBl*Q zRIguj(@aS}d9rIvg2ff;;n}Y5K*#d8JVc)pmS0g-&y;mMC^78bX!-aO8F;hfLfX>`DSwENM7Ro8ITx;2$vycOCu%k1r(Gn_1^m`LOKO67c!5xv+b`Ef(= zZIdl>nPxW1>l(VT2I5_8>GJ3sM!t+NoLk@nzP}Ac2Qa-ITa8_l)&A_wcc%`!Nd{!< zu#U=|I2)B`2Q1PB7H-O;)i1Nlb3=tOgXw)?fUZ-4#*C#`DwtZ+)7-knL}B{KqmfvS zG6f@K9TUVa{>liM`JAGfgMCC^azz;VSZ4;EU(d9P z1j3p8z9|1>Iglg#rm2Z>icUSQ6gRS+ez_39zaoSC3DKvnCH{v+(aRMrVJ26f+Ir%i z?nPQGI`o!Ds=^7!Y)jVA_-!~x;Slvh7}=y!`-=zq6D8(Fi8cYN#`#RIp7TBtcNRl25XCmRyR&eF4tg)Sr z7|i{l64F))GZe6i{n1HP3dVi#518kn$DF3eksLVhhW1|~43l(p0ybcC-M{EFk!&lX zUT*1+secP!yOX+x<3@esF8LyrTNDO76wd1u-kCdBZwl|YXQyS5q>qu-Gnu~ZM*GCn%IDkAhG&kHHx4?fi+jD1jK4PB8k z*}MMSxcW5V4*@ymirFYOe6qsG@8lHulz+XLclD?*%XNVF$Vi;W9ybiJf&mrT zt0KY+;{s}ur51J+7f^x-0j_P!Hr<1^KLR0=f)Ghp@`C|Jx`dHhv=BQA{tf@lDxB;3t}tpaA|3gz&%-+SaLWaR)p2_uj-=Z<=$LzihjfZd z_)8K^5qwgt;gkSi%cY-)^#hg7mu z=L-ox;$GMCwcS&OMw~@a_sio{2@HYZ_O+&8dM`0G<{fJTKQfnoWIT`Fcl-=PUyq<4 zM3d9p+iQXCzw`}rCEIF!i!8m9AG0{&L%PS$xP{yS)eURW9K3XmX_~S2@f}jfe$)Gg zwzYz#Gp@YJEk=jd5yol&kn=927`5eYKJ(o*NMZT z8Z(`Bh)-C=zw#9K&_m2<;gu(Fgl|e@Xo!|4u_=d=7#Cl%o)f5dFbPZ@#ZMiD@f!C^ z!tqfu`ewBJW%*}`oA|X6Abc@LLD(uOt0?^8%{1&6h9S8F!8sB8KuwOuf}8<>T{dOE#X0Uw6=3rk4M) zBXE^;UjUqn$qn3bLrB7bfF$?g4MAl zFVOmtoIT&Ly^Qa8QUe5U+ic%liN9Y-V6Fte=#nLO-By-eKxR$^+Sf4PRxXUCapGg} z{&>3HYI%A{LYsL;Nd)-v{zC)1#t{G4Qj1>ZnV_z^PjY2$S@vim$g628Ue%d#e0 zdKr6^8eM+eyn6#o$E_OwepB{ejId-lHK8}UQF}e`luLBOdrb3LbgX}0%MW^2SfsMN z!q|Uj0>2XPucRx^;h&(%{)4g47-PtFBrcpn;!T%D{Ko!cv?8qQTZ@0*xPTz_3DPyr zzAY27F+|xp3NP!B}b zlnAd4amkg|DgwTJKslyQImTrq8{|rVZAxB0LLZ6rNtE7+(!gJ1_`k-ueqlQ5L%Z~< zZ1b(;Jo0Uk&Bpl@!n)Ulx^PNWhQq@Gbj(#c#uY(USBLng$@4H&x-A4R>un((;JP2& zUj5_Sv|(w-!v1+z7`DYZmu}P1z0E4o1xmj=MZb6wuq=!m;s$wtl?2=h!L6ts8`AXW zm}B3Gdkih4zc--Wbp5O)KUI0~_*6dcePS4(%HQocN1r_ig6<=JX|#Y=KpA{HnOBjpX@Z z-T_{}X>#^`#Ke2<m*YsQT&2)euaIa{+Ma*_)U!f%es0eo zVy3r@u^7I=x=c6mETn_xrnjJ!LU2-;%-b@>#2xBqNK~U4-A11iXYocItwgw!hn{H1 zh2}=)fUzvRHrzK${$FE7$JzhiV@21lCLh1o*5JRF_>aVXe3<^4khqIA^YNb_?BAhG z3`_|*Jf$F<1o?oTOS|czj4cu5sc9@kH@B-EOW>y1r3&9gJi#GvRhTU&-@Nujt%sSm5KHXwT?xQOWFkLIUTQ>T}H6 z`~3wXTtz0IQkXY8VPcKQGWG2rTgMV1x?>f;sBSd5ZPMWi$dymFMU~v5KL-UvUn33bP>rdvt z@c`#8VJ25q_I7`kXHwHay(k^->!a^Jv-n+3{Yl!dBlLj)!7C#`y_b`v$o36l{>oe> z7JoczVz?7y5{S0RJ+IYR%k}#%5Mc0%2pD*!d4Q6CLR}q@qG|G%R6U++4^xc8Wrj1AbvHU3pH^+|-2Q@LkhUZ3wd_^1p^rA2oRr3#$IPn7dh6xVa! z_%{_X!%a^o_E*tAl_!>CaqzWhpsB5C6SPk#p2f^}4Y;KZbk+xX51*rte?Yxnpqg6f zzpAL=B`U2Lj2}3t;dQ}JW^DbbQFJzgU4kJQ><3MvU%w4HR2XC0M8hny#ewcKVg}OS zZbx}q2d6De{m{QVA+Cf#4Q|V3Oz6a4;w~0lr;SDtVt{m2cknmxQq{YWhEm@oLJ_Rh zOgb8ojX)lQwSx|X+@ON(FDgPwDwL9bj$GYz7#v$>CZy1#*^az|}x=zC4 z>2+IcB_J5=-Upd5Y=tN<{HM?x5BgPtXN+u>tE6b#y4 zESxaz7Wr7j5jj7Dp7e>%H*Q1h69%t%Nbro*iV1|U{I@nbTP)9?S&1H6bDb!mZ^85O zw;2mx4qPoj3K)Yua3y zE?pzE10am_F6Q^a)QVOeIJPXAi0*BxyA!0#<|a#lj5s9nlZEXt$Tq^i6$Cm2=W{I) zZ|vWw5$){l^78R8xMPHj`5}hs7*zsY(&}y@PYo8qComENoHSPqN887eK7BA54|D{1 zZV(6IgnGcp-Kx;Ip$v7K%2HeK$?uryj zXhht-I|yfpxQiJ;e$XKE+}U7D*SFQQie!mY`Pr;bZnz0-oDO9}9Tcu|%PM*lrJDk^JaT6|^Mu=H=X?l6OIOaA@)H8{CwHkGx&7t}BY4koP%s zXm(9@EmA~>xIHzQgWc{S8CmWcB+zF#oz|LEm+ODXAa!TB5zZP6A-!p6C?1%{XRzu2 zwy2003(r{@_9!AlLjA@t2p2^Sb%z25H=EZ|uP8EU#)@19VF^3o0YnZrwYfi+kE+UJ zY-K?o73E-)2J@tWvP#FJjJIQ-V*b#Z#jH*vu4!Pw{Ea4Y%*+q*J3=53Z6Ba9I(+Wb zIsH2;#Xz@q+a=q+>`#>Rq6&WK+IHL9asx9%FerxNW~i?*21BxOSzETx`a7&1O>t3Z zS?iu%U(;&(Ab5}pr&kS z$FtB%DrHU0q#R#E;-;|9-{NODv3iIu4CmIT8Q*qrX0iJa&Q`*Vfw@(M#}0jSbeCny}{ziC}Hcms%samkmodtN3)$R$cm4rHyZ)kN46sQ?C}AcFPQ7rWTN@JEvuIwd6q61%xIiTn<7xa=M~5f&qDb~K3TdKUIgT6 z9#QB~#{`ilolZQ+QR{r15#tm&EAgNJ0N z4|Wc#@eHYTS!+Gc!P%KZYcl`+Lkdk3lgG=O2tHiKc`{A^UY$?=-d6Hf?`N zdQE#1wjh{sL;}?M?b=lQ5bn9QR%j8IE?KJ5EdQG(nn=8(9Na#BNiI6d9wH&p5o z&WW6X^6#j`1AZ}{Rd176svgHM)YIUuF}+07qVa^y#s>Z+WAQMjkB9?xQ~^*b(Mu3F zVHs*Xm+%wxXGq>dJA~d&GoH}~u?Tgh{3Iv#K0sCQgf`0GW>RB5W|}MwA>?IK1mR6Z zT$fTTr>~R0X_`ib^`?#P(*Qr- zOe4eTx8ZzAc-pvv(s21MQ9pWB$?XpBeN{HInPcY9Y@Xu>QM4NN5t;AI$-|)4f81-w5(eAEofJvbd zjH=lXa`mu~oH@;6V#jQbe=rP&uNFwg)SZ8H8i6TMMGCSoq+|wWgl?J<`p@LMaT?d0 zkWIUEv?-D%YIVlSCR9^KTBPK5#yFD?&V#^kj?yIQIodfzBN~S5e7{8dx1+y8ux-P# zMcNFNKUGAT1U^3;k5zJ{@!#Qh{(;dr{8s(R z=x=1-O%D9QSpUFp@w~uyG?!fE{TikoPHP~p5P)j!XiS0W4LUd)*)f&TXRGv?D z6rS}4?vzG03mriyn%ig^mxTXnP8;e=)Lyh+Bf816=Ay)E;u3YffwZeGG|)_{nn@CR z2{$t5DymzdAKg$Jk~TeAmr}04Nzz!-Tdtkh3d3D1JsAxgb(`r{nX$okU%VIZi@i|H zpUc(g>zu*-Ik)daRe&O18T2gisK62zOJKC#iodzpoAMDAeZO8`MJQ%eRX;LG{|J}k z_J{v7Th3DxdQ>gZpcJ0nVi+IRd%GbkMjIS|H(B^l`$QJGTUCECNpKXE!6pT8w8P~w z_(w+f%+aEbY;G{plvoW)aA1fl_>@eA!eCv&YjLv0EIlw)er&2dy{KY}NDdNn)yhi2 zugO^&*)ziQ1uSIuME)JH*6{^_Fu0Gm=p>I@6!=u-r883%8#2Raj*k9|$6+rB+VF~S z!FrtRTX13-XrSM!RiY@Ej#SWSePUfWxt5p}#yC0__JjSRN=6dD?Ju*9_S_!3;WNi_?rvkPpvz1a@iVH{v?6DC7Au)(;A=*G<XGuG_|~t;x)_T_jQI^eZQaIw?Do=dWY=7 z+2LGY@7L?~d_G*08VFJu88z7;+Pa|6bw$sny9&ysJY(S0kCG) zR?cG})QDjEOPTRWbTlLv%#95@-m_qZO|eiC4b?m+I; z@~!{@*p(4w8mxA05RpnDFUV9C_Y1%ejWEkG=hStEFLCm$45j#mpZDXr?8<0AOB%lz zSp-~rN~$<^a{sv_Yg@^RMHMYNonYcfg?yc24#=} zhqblW;30{jOcCT98;C_>d>X!|V*+MI-$X!$?VwEG(q+WAQVW&xms#J8dgx=>Aa}>} z=yxzyv`dUZYdcuhy1fyt_7T8D50!_K&&ohTa#jv<1h9nyVd=j`^Y!u3F%Y&TMkm;! zW23Dx#^|c}IDLGqG1gWcV~tH*e8q3RvC0@5UG0cAB*Z%s9FA&uXRJO^@2IYFzh7Iy|-nPmTqa%;q2xaw3N!-Q;FIj!=h7qmED^G09$fNh_%+IpPQ z`oSbneed%pSsyauB8mIjSB1e82OO2EVY*>OI~5|vO z$Goi)l`Qb2}AW^y)Ws@=`S#| zo#T#Vi-KG2oCj8eHgCLtyl*nVh#|m(cnQF4Eihw5!a!3X)vgi&b0uN`0McYa_|P;`*-~m11(W#th@1~2Grm-^+8uPy2iWXjb_o4qcnX~2qy(Y6K5!K3O0aBV zn{>dUf27j^4#K2aL3}I++G`CU2%4d$!P*7!%?h}1K)Tpz*yy8dS9Lxk?tCBb?hU2` zI9qpuA6T|UWd24=2nD6B8);b?9o;Gr*G(97kutT$6qYGrtIk zl+o-iK8J}sK(N)300cXa^>6lqLY(ltti)Q+&dgtkYU^hPvEe~XkXukVbX-Ormq|}Z za@lk_a}EZdfb{jP(cu3^WY!P|yhdi?u~lV7Wt# zieOawF9&QPECGx)5LRUp%fgxM92l1E5|;l3yd>_o_pgaHQ0P#EG955Ql{4o>k7 z{1gwkU*)l2oZ``ahl0J&29H3$Yb zZDZAMrppi@1M;bnoHI@hRB6Zu2xH-e2G>(kXmO~xjr{=z=J;W>dp#emCt&UeM?^jB zBZN-^48hf4IJ4H7k=s{|2{kx_IW;v&{BYzDiXc_n=z0xeRDFVTubxigZoNE8HqyiE z_zmo)-M6?89YRqIqCN*YFOgz|GwQNR2FY2-Jdz8g@EL)TaNW~xq^Y1FVmQro4{i7D zNr2ErTJ9Q!-2QmC&Hq>e?s_w2lW%d_3;tGQM>cx*SZrH4b`++lipKsROm`V7%f)&my4J zRFjrymFhuv4l73L@d8E{xD*P~EUAteiCA>!$^hvRbV@EttF4+%1o?xB3Y4;liQ|Lty7aS30#3%`Fay8_y8-Go~BO(am zT<9kwOb&&o;o7A?NpHc-hgqRV#TlTrOa}1e&>2j824qCFPU8+(i@dRhYk|yh?7(r1 zI+65{!(Jx2$Frm*wTc@`k@4I{2d}+HxiRbrMVVHJeLWLF%1H!fUElR z$3pw*fl)ZYj3X~Z*?ds{Y#G|h3IPa>UVRqT2q4dKdmJPr(U~Y>c$DUruQEQ#3C>07 z3G7AEC7{pJ9#YTHFBtz9!w=Ci)}IQDBmWf*0s1Mz2iydRDiI`GSo#sMc0y9P4m~B>tR%$|+5id5FSo{_ePLaRLMtnmn5RR( zg$Sd_{p0XS(1{)xfzME?L&9C*nsY+s4?4;*At^S3+^y57MpITbDiWXgDExpV<(y8u z8EsGpIPsk@QSq_B5jAcsu_01q0rzRrKMJ4DE46~qMVTClzKZ~e$0ps>a+oiW&!K-z z!DEBqCI`0n&ER|;>DukveKYy7zcjX8yendEBAe(>v>R-Cdt6*XRjkz(n*b?8eWJa( zD%S2;JR_Uw&{lS6Wh@k^$YKi&!VKN(h2dp+(y8Qh-<0)gVn3u{wSQAn%@We-OM1nS z(n+DGv3g{jqJY^mlx!Q(vNG{3bSsWpZAOoYDcKa=Rn}_lYb^?wgKDxd!Xkql-knMG zktlj}B=X7QO}3N!Be0f+Wa&QC7=d~eq}+_nB2FNFo#}P$6A@H(6lIAZE=E|>@KEKD zfojS{pGBgt5=^_$vlgDiLEJI1!MSxcY{#AP0J7=GN2CVIGibgzawgo}?MAdV2|9eW zDmVoD5qJs`S0jSokT}{P-bCfu(0BrY+w(~wN9i?H!XBGJ7<#Og^Sf=K431#{x#q)&y?$_hPJmGl7(U>{(v~ zz!BbIc)ABv^p#WrX|^_~_z`<2O8<$z$|BaM@}C#kp}Uy>I(ma7$EKUwfOAKd(opGW ztPWTY>l9W9>wJiqo5nZklF$*k@F=~CW4c6a)sxo~&G8%soM5o!TG7@JVosr;*4Czc zJ-;>uE{9+lL3T~RpMmb{W->9yb(_~6F}}N-?oQ(KY}K7}EzAdz6(2<2hjFY(40!Y1)MAd-g6Ul5jh{M6!BGy_JMD%uC`+LjqS;CK|L9$Zab z6!5bwJ$N26qTU8H8cK4|lde}vV|JC%i5#mCv5 zpGI8;=z0X^3>`za;F067n!PWvdI@4yaClvi2ofMop-WNsWC2vC1`olhr7s)KW+xKc zc5~z2;TXr+x_sT=a;Hu8V{xSddXPP6ZAdJ7JEF2XUrK~K&6Ff&3>zI@Fyq->AgL4E!Vt- z>z+5B-RoPp0w7}$3#)@3fH5i?rTwY?DNWqLdH9KeJv>`I>d%0vXIr?$1H+)5W3tpZ zXfeRav)>n&crX+fel@;&#OaNLO#*-@Pyi7=Cu9UcFTNM@J6(c!dz1(;69uP_sQO0X zs)u|D^79g`l=wvjZWb^y{73i^65vNLqq&WvxmY>c>&wpU0V2W0VPtV}N}N!M;gDYX zNtKWA!7dq=M@kZ+0kz?TDmFB|u!{1PCTMd|dHm{|29L9yHXr(8c4;(vpUqvVe3Z_K z(y|glj4F;fUNSrA`N8bU3C3HM(}b9Q3P1M=bg{9!2R$orLwH zBwh=FnjN^Sv(ER#mGX?H8E{n~KAH$UXJ|S_-H8`I=2DC1|CL$#P=K5YkTXYQ6-Q(u z)^neJJE(FJr++3pc_IC(b#t|KsS>EERol@SV|sGQXUQ_4-dVF^UBKR+0DVU2+JU^;nr8hQ?TAm_SX&@or>%By(Th-JA4 zU7;bz)MX~FTjN8fsiE(0eJP~s!jg#eL~E6;Kc zT*3x8>XZ0sk107il8dT^JrlwH#wGRzC1b_Un5KswF$Gr%+-ErGfFBy|PmP`kp!@y# zM2(2zLN}cdi$pss27Y66!vl;VQ=u7ZhM;7JKQWF(%K{l8=YWud6*@ce`Z11XV=(%% z2@HTX)P%9JZ!n97Zl)$;aSd_?QO{+OFR4K3dEgqx%ge3%z5r(1P?>F_KDI%&0>aeK zG9a_{MmkxQ$IFA7P63qTP*WrkDkQkmP?iWH=mW!8;}<;l4UY0P!N6|o*Gg}p49Yst zC!yIV(3%6Smk{#f)67-w$*bJKeRZD{uT#hjrYL~tw5AaVQQHF5a`Ms9=w+z@oJEP} z%b?-&l{%~?U5={KoWr91m`b`vvrZ0@T!uN?pux z{J?QMHr3<6Zz+Nx72J?*dj;-SBIg_~Kd3Y+VGlVG1a)w`(OT6!)0eC#^5)N#mZ{7g z?5jJN=7)4981w>3hz@<}HAot0-w>j)w#{D(;PfGGrb7AoEdeUdfv!7AE%?~mt6k3v znee=d@I10uYkN1qeHBOBeaJ;hxY9l?(sWC9?F7*pL8^$CqtR!AxU(7{pfgvoimMnA zn2(l<6Mq@;em&~f2N#T2GNG6Cnnowr0-1``Hb~)s{&(X~M^KQO2X`Iu7`WeQr#r}_ z1~9}qFc#NL8&|ng+<#mMhXk>!2&6AdM=QV35YL#pa81=Xm?a!I%nAWO_&@_ZuExQTQMuL&dssQ^2*uHKp$eG~O?Z1JoeiX{mjkCq> z&IZj2h%=Fu;yIdxM^?Ka^hJfEtncyQQX>u(jt1$_xtmycshTL6CxHF#oHD-u?>xe3 zBq1wQku1o7S-w@YxY-Bb;}wTE0T-~;XENum%N$QGHELJRJUd78c??!%D4ENA%Q^5Z z$9XPv9rS+xphlQqfJ2Ym z<-$4tL_YJ;3vlxnzzql_v)wbuH5H~W=oc{a-+7SNsTjmulM*(KMF2S?TNmM{$w>*+ zOFA}|(MJ>}8$`^Z_S24!9 zh;%MW0q=SV`-gYt^gIKisj->~J=PsmvJbUB3Ue%bkvWSEpT+8OZJSPGgx01EE2p0F z7eF%v3J(Q`ojMz$eHy-Z{){muo55s5_Hk!R%fHa@P~|z1`vxZ7JFtp~=_XH>YF-LJ zGlUTG*SDh0QRtEqc_DPm7x_+bVz_(y9Jokyui)_@l`Lf1`q)TFtTz9dCUshu!7E_I4)_J zd#gan4+HY|o=FA`_@2Z-a0f;t=c)uyk3kEg5LL>SS*8-G5S{g{j2!D!bC}>TLvUDD zFs|L{A1zDc`zFpHiHny6JndB?8CR|f1j=G^6nw+Nt>k#)RHhMPKVfU)IgLV66 z^v!|Qf(_Km7eRs6(N^kmeEh>m13T!-8Bg$U@BCRGgUI&SR4sjKt!vJMWRx?5b-zes*TxjCs4<3fY7QW!-1ErHl*0Nx?X^Cr8} zKvtg>K&J%LuVLnIIm|s@5=Q3Z^2@7-D~B*QCa@2oo@O;Ld=_t9j9!ov7oJ3kKExO8 zm_zf=$3#H4Y9qFoz+a6?8bv0J!tzoS3%B^;-8cur`hP!?G;Sdh3n6iDC*o4NhM@I; z7{3JS(QCViFGxx?))aA6v}8dmgqJ$sa)D96suIH0?qa0oQ`=ME?kR-YIZ;&{d>l#* zzb=RKi@N6LIxA!@P9-l+%{qrcDA{ZgsDO|?A-L}f4i|c_G;mQAP3<{{_WGbBLiGWt z`*sq0Dv9LSf^&HIx)$dh4hREnd_4M(ROFmWA6}m~uDq)Q3kvO|c5-+j1bZzkN6cPr z_c2i6A#h^dhbCL0J!Z!<<;=4d@>vU<8oNmMvaFR#{;ux;fk?*H2^=6?`FrcGd&(c@ z5xbs33DAMD0Ci@dQiSkT)R{%}wuSKB8O~wkIPhYyyzo^W&i5v}W#TTC<|7J3-OptW zXlH~g=Prk)uzH882~Ag-Dnx)zu0_P0hV1uf@N6BX@J*j(^-*}n`&ktft{0J$h0sR_ z8F;k6l?lXQ#0BEdT+HfI;7P}_%24KM`&uy7!6`g@%K`=eSJW&7{~~Mpu1!>{ujU1xjx1>=+MDUDMR)8{e(Ng-gCG;y8G(c?m3A;Hb7(Yc>gHf(h zSsDvhdQd50V`&Xneh+J6PU6Q-;vztjraL;#-S@ZqUMuxkrH2 zc9zMRet#(TX6@igvRROuQ>N*=f+0f;N{s*H4!I%=j@@|?4leElFQ%U{+s~MwaI)p} z#5na)4<}T)Fo-brfAt!d`5v=1l08^S^`c9=-(jW*Y-tVE+QdG25gZg$X6XL zK+^SAeDFKM83?yO$UAhP+XaO338w;|`xnfnb;(v4oPt@3uC z6RI+5oo$`9Py|Qx7&u+blgTCk4mh1eVG5?wMiE%8R{SKfN1&MEY?@`YIt}X9jCZ^` zH@!&5;Es*nlKf)GS>oq3v{YsS_))gSb_;XskRrbg(q~Xr>Kza?&4#WK*gHgU2y0r) zx|I0I!L3abl@O{GS#2=25z0)^OHyA8>HWjEv2;uXMWD1w4i5szks-blQfQi53fJm^hzygtqSgilDJwV};kugbADn7Bx7g&W?Zk$`(gceEie5j54$ zg6?fADs04B+?xc-pC);99=+6@<)+ltrEywvh6P}egGrHokBbztr#kBP`WBIfya7|1yUl3Y>(Eq zh!B+-qzpBHa;XI=IE?UWmYO1vZ`iR1%^U=Qq*i@=!4mO!wBWBI4Ymhz^ zs`=IE{bI=Ek-K~}cB%6em$5G=?aOn7;H_e^WIJ}3xc?H>c1VxhK9O(1UNxUpdFR^5I3TxbLzP!R#G{pkf9iK|H5TUa$ z!EP#<*TZY9MWN;7U9Bh`@Lkl*L=emXmEs+5<~*)DANh6LXF|!HfMoRr-65qg8LIm2 zv0&hoeu`o&!ZFNeoF$)egom=uVgjfh+ElW>gIwWm1(dRER$GVktY#N9>I*f@57?$3 zF#UTOU*gd1BfkiT`_TzqoAB@Xx1oEI@J)bD16d+ih}j*QZ?d8DY6&!7)rH9K5WkME zZ1!=tdz*HX=f@ZCP=3FSemVrL4Fxwv>b0e0i;+cCQ=-#iYULY+TGy5FBu zPUQba`b;F!<`-fr4g>sE)1oJ zmE^0L2E=({T$S!?aiIfY3BX~;*xbIz0ZVnR#se}`6gTyd*jttLc{4-adWL0<~#*MSmT_QzQa7i(ZWB54>89u81ymh z&dkh?0kXyPsyp-*#-0g7Y0pgB&b?Wc*$B~gZ6*w=HZ$o8He8cg2?29MCX6H)*D&QW zrE;zC7!y!=7gG)>m9s`Mb24F2;ichjmHSD7J4m9eoR4JTOxAK3?yTilPFCXbO{<0O zfAWn&CVM%ItnB3mP5Y){41{f_8!#V?ZKq}n(N-sIS!wh`nJ=UE*~FnTCTr!Ltd*p! zgKG2v4+nz?+(OASbt9+lRxxfUoqPZ3BBFLKoaQjLj>36n6B@7?dBkD00J_&~D9Ekg zTZ4&x;M;1gtya--CXH66CF01hHR!7vXk!9UVj~&94v50DJHOt*L;_$U4(?UiQ;@k( zewP)-+0q{EyNyA6TGQ+;*DwK4*U*d^=yErTcmt~z-jzW&;p_&hYcHE@6W;r8YPsL+ zz<4YNneD+*LKPUivTC@xka~BA%p^lQ7Zc7YnvmJxXV9Vj_(K+cGHyB#s9VcyXrGAi z74f6t1V!u6;l*fjFdmpSndAIf#L&2ohEg$jlZUU6OVUimnUm}K^ZO1#5#Z5X6TuE6 zXq56Sbo5%=YLIS>^Ek%jMU#2aDaWy)1Ou615Fb^plu(%lbW97!eM|nmfz5n3qIVuAo_HEP&32EARp^RUv-l&J4jqq74Z{j2Xpn{WAYddTt(rX;CCR2Tf0-0#D6+O3ur?Pd9 z^2Y40#qZK;j^j&S$`6=pC*9}eE#4dV1Bh%5b&wGzueMq50)KYrwrJ*F1bHtakR|tPO0q&8!QA;aV4%0)c<(=U+#_%>5yt7ky(OG_|%)b>DfU_tmy$L9*#~ z5&D%zdt%X=4Uj1v{6bX(^%yYkjm$w$EI>=LJ2wV1+XKn%ff+uKw)nSu*Xk`oE_4F? zHXwi;AoW)4djy*+yW0U16ii4w za9izni(I$FSVCuf1{T4L<&=!&Aemp~7>+wE0P+2Z!vt~NXBSp*R;deN)SOS%91#n_ zWqgE6A0d5>C$QExpcbf%QIifX6GPJE(?LuIv?SozI+h;WGRQNW0)%}N^38-SHhD+{ z0qwc(Jv3X}dd{)qn4rem1l8@KBN+e4CvV7L14H|X%^b32oj0|fhm~Hjswt9`ktSKVM#m_3+)wXR@ zx~mszbY{3>1j|^5z}@o*zqiyEh`&Dz$GE0TUHl#C7mnWDPA*fzB?l$$BtOi9%bsh9 zGuH+^m^OWaHNh62SQYKC>Gd)3332gp2{xm{9^+Vdetw1w*P~9t)ScQ-gEf>DWt@R3 z85(LQUpz*=LMm5ks3wJLrohcJ!%iVUAcNl-Z&IeG5u1uFDlHudn&&5GlJosE=Z`tX zT(^Lo=r}~YtY2`AOH}uBU3ZyGIwYzFtT=kVlA=D>&TmCMqY^P*n$-n4TO(89M^yM_ zUB;d{T;F|;lfPS86uJzjrpci%RkN#}sPjjaQXZ68uP#GxoyfUTk7mlD0=oi;n(`zU z$^Fl)yL0~tdceA4USC4Jz62Z-og2qu`fkcQKdkFI`OH|<=J#qMuZ0%NwAJIJdUUMt zrAk(VG(j4GM+`KGmFoHYGG-zUqhcbCl7v`+?KpCK1x1X&;zl^W$UKuY9}z)Ua)jQS zIu$UZn^y45Hg9((TN>L|%tM!+n^WIe;00_Y`X|`H)Nd8|DfNvxkAH5Vw_y;fZMuk& z@=<6~V_Rg!E?wVy66(W}3I9?bQyyLb2CL-ZVCb4t-%7--dFw1*%*$r-WwZRUrbH+u zh`q02CdZbO-QM`J5LWzEgKoA1kjJW`zv|T7C{b<+W!s{ssKJs6gi=2FR zy5cbUY}UaPnphgN6XP;th2&Ua$_32G?K5Y)FLDj$Y%sA9U$Oe`gn%VVNJa@^X6Op` z0ZFO)r=$;f_!ZQ!D=Gg|O6Rk(Yc!N1gx3t8;KuJ=S1>n?3`cQvTSWDdp@%fBr0|k+ zFCRi@;ThDlQhp4u6eZ_)bJU+es>DjPZjpg(w^3D%zG_E1Z4yAOLVoAK2dHf_=xpr3 zwm|a_L9vEp?X}MQ6D zeC2v8bD|f9`9v=|P({?ODkip_?S(`E4e5f*y)a5H_wtHz31Od6nUulNTzIPTrogSi zDawJizXT`4(}$6LBP3htt^2Locx0 zkMk{13UMrlp>!;#2;+k4;jultRx1-0Qp=VSofE^!9%$FL6GuX+wQ@3l8hw*vo+xI< zJx-2$+fOFXczfi2qNz?-!~*9v%dOrH)9@NuslU0wDLIw|@kf z6JbKA_Y(6BZ|65W^wko;*M^562tGW-S;wi~zHQ#)db;Er?y37y{lBVwK2-Uupe5m<6n@P^DZB?jp8HS=KSA?=TU)3BYXCf% zr%J{r3&0uxpDP1Fd>kE3Ps8F=*p*ZuxPTW1E35{vE$dZtpG*%0TMr2r@KAuD2g(E>e`S=ml8kFh}`{Vsyyu(U7L&0N0aTtq3@uObF$^D_AykC;aDc9$xj=XRn6o0DB zIHs|H-{+4%WoEl8tT-royOOL{0c`X)D&OcFC=-EjyQQZ_h_WuGL5fVBauh6H`+fLj7qfcENLC2GGk=yZguWs677 zKcZLU`$K!o2(W&zD}qfDKuM&r2AV%yf%yEtYVo3<V1h1`~@tjx699T6KgoD?eZ7o z*;_lKyyyQX#BG(s7X9G1PX}@whd4>!V={>1(hG`C9>%Kwc;i-ibiE)dWfesc(m^n? zN8SR68ZQiDBDVQb|B*tK0cp7Gawra9iJcd`LZ8QvLIah@Y=D16y-$BaG2)ugLHFY3 z7r5ZhpxYi3HeGZ!IU zgX=El0p?b9-yZ`a&z$tU$?2sUpCod3#8Px2y;$hs9zWaKywwVGetc@(-pNmU&)-~ZaK#lnRClE#tZl9 zmml!p){cG>3!tUh^fd&V+mXsc!t4O8#jb^}T;Y639sO@;&_tTx)OC8jUXYuWo?4{J zEG|mVfi0h@`VW{#7Pwht$<5KoZ=2(>N!k&3-S0TG%3nBrGJHke|4x8}ei&dTsl$mi zJ|i?k#PNmLCL;-xu3}4>=Y;Qrp%$Zu-(t>kEfQh8RXzt3S|1<6o zChN@W9P{g(=)ynn*@_&mbNl8?-h7UOlwv9#$>0(Xt+<;HNa~xatgWO&9Q%;nrb-1_ zJ5zl>lD{5F7x~3QxYy2}*5(mQ?5--1V4dso=yalr2?P zu+{pBgoveTe)S^9UBsu)a+nytIfh^MI~VOw^ft#D1X|TeaO8md1t?rp_bEyIe2C|| z{3PHyQro!MuVAk?dV&x^=CGB%f|(C-nMfQ)T&9qkE2y+`+!46-(2TqwuoGe>=`9)1 z)#nvBxDjh|^$<)jUJ;B-&(R7W#>nY6a#Wy{X1Q>Hk~v8VK!a5K6m(u^gy3O-K7=c$ z$IbxfDZp@`1KNXKW4stWuG1&A3yfn&@N|KkI0K->gfeitfgOlaMb?yoj|q-aRNQKv z#Td9*2JYnKDA?%Dvr>HS|IkpMBFE%}oQ#ljN zivo<8mn1;JS|P*IXL=SR=a3w7$6W>a|6rJ$7Z72@ z6kZ@f051mi6;UYX&x;DhvV-8ABqty!An5 z`O)tAals6DFtWUvo`u`*FZRz%f$2zn^~^s%H?mqYTRWQBkJGe)bpSw0JZk{B+>VDY zG_f-GR`z*TzFiGv6L|YP4L}Z?pf#k1{oUfCjK~DdfGUooaslgX41|Fd6HOr}_qxyF=XGS!$;Ydp`H&3}5m zoqaO>;p=(%@G|=tzC26uylyd>+M(EHf`8eCq)laCW8Y}XPJn;R@s@`Awu;P>*fK+o z%Qm^B)z&z*Hn-LcT?$!FYpHRzrLL*Q(wH^N)=*tuN{iX|v{jeRZOKkG z)mFt6%&Kb4hv!V~_aD2eQY~?i9BZ+pW_4C)mbA0WnOdf=W?wHiB(_wS>f6c;BcEMS z_V6>?%1ib2?0apEB`vm8_VX&5D@y0iE;Iax&&|w$bx7$k+qwQs8&vGpdiM7^-lDg_t&+DxfWd*Zf8PVm1u)dR9YAZ^Obv8pm zv#p`Zv%Hd$g3Roqnp($yTlcCCcz;GKY`+KVWnzCf+FDj%EHhMhl$V*CMz+^~U;qEd z`x?!#jbS_L|FEu&C2iKy99ISWZR~b~ZPHpbx!zGdxxO9#zBu^%T;*VCRUVT+@_K1W zba`pPtm@44hx^A-63uRhx~hf}cs{X%-L|lATdbv7u#Q>Ak^O5n!p|MHm@3b5svAl= zstolmTP^z;mbp2FvF+J)mRd(4?2q5q(@;^C)oCqFZ1XIm&eAruHnzjk7|kBHCe!5m ze-C>Yvd5#@b5Q29|H6TuX);xr(%@rGU+4mKD-ju~Y|L|0Rqn3S`S<+UWSsxAi zvazZmqut6r=lNAwO9@33d6YUK0`2x2eQhxix< I{Z{(_0>Gw-<^TWy diff --git a/tests/verbs/test_create_base_documents.py b/tests/verbs/test_create_base_documents.py deleted file mode 100644 index 1e182e26..00000000 --- a/tests/verbs/test_create_base_documents.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -from graphrag.index.workflows.v1.create_base_documents import ( - build_steps, - workflow_name, -) - -from .util import ( - compare_outputs, - get_config_for_workflow, - get_workflow_output, - load_expected, - load_input_tables, -) - - -async def test_create_base_documents(): - input_tables = load_input_tables(["workflow:create_final_text_units"]) - expected = load_expected(workflow_name) - - config = get_config_for_workflow(workflow_name) - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - ) - - compare_outputs(actual, expected) - - -async def test_create_base_documents_with_attribute_columns(): - input_tables = load_input_tables(["workflow:create_final_text_units"]) - expected = load_expected(workflow_name) - - config = get_config_for_workflow(workflow_name) - - config["document_attribute_columns"] = ["title"] - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - ) - - # we should have dropped "title" and added "attributes" - # our test dataframe does not have attributes, so we'll assert without it - # and separately confirm it is in the output - compare_outputs(actual, expected, columns=["id", "text_units", "raw_content"]) - assert len(actual.columns) == 4 - assert "attributes" in actual.columns diff --git a/tests/verbs/test_create_base_entity_graph.py b/tests/verbs/test_create_base_entity_graph.py index 0294ff45..86868585 100644 --- a/tests/verbs/test_create_base_entity_graph.py +++ b/tests/verbs/test_create_base_entity_graph.py @@ -2,7 +2,9 @@ # Licensed under the MIT License import networkx as nx +import pytest +from graphrag.config.enums import LLMType from graphrag.index.storage.memory_pipeline_storage import MemoryPipelineStorage from graphrag.index.workflows.v1.create_base_entity_graph import ( build_steps, @@ -16,16 +18,48 @@ from .util import ( load_input_tables, ) +MOCK_LLM_ENTITY_RESPONSES = [ + """ + ("entity"<|>COMPANY_A<|>COMPANY<|>Company_A is a test company) + ## + ("entity"<|>COMPANY_B<|>COMPANY<|>Company_B owns Company_A and also shares an address with Company_A) + ## + ("entity"<|>PERSON_C<|>PERSON<|>Person_C is director of Company_A) + ## + ("relationship"<|>COMPANY_A<|>COMPANY_B<|>Company_A and Company_B are related because Company_A is 100% owned by Company_B and the two companies also share the same address)<|>2) + ## + ("relationship"<|>COMPANY_A<|>PERSON_C<|>Company_A and Person_C are related because Person_C is director of Company_A<|>1)) + """.strip() +] + +MOCK_LLM_ENTITY_CONFIG = { + "type": LLMType.StaticResponse, + "responses": MOCK_LLM_ENTITY_RESPONSES, +} + +MOCK_LLM_SUMMARIZATION_RESPONSES = [ + """ + This is a MOCK response for the LLM. It is summarized! + """.strip() +] + +MOCK_LLM_SUMMARIZATION_CONFIG = { + "type": LLMType.StaticResponse, + "responses": MOCK_LLM_SUMMARIZATION_RESPONSES, +} + async def test_create_base_entity_graph(): input_tables = load_input_tables([ - "workflow:create_summarized_entities", + "workflow:create_base_text_units", ]) expected = load_expected(workflow_name) storage = MemoryPipelineStorage() config = get_config_for_workflow(workflow_name) + config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_ENTITY_CONFIG + config["summarize_descriptions"]["strategy"]["llm"] = MOCK_LLM_SUMMARIZATION_CONFIG steps = build_steps(config) @@ -37,34 +71,36 @@ async def test_create_base_entity_graph(): storage=storage, ) - # the serialization of the graph may differ so we can't assert the dataframes directly - assert actual.shape == expected.shape, "Graph dataframe shapes differ" - + assert len(actual.columns) == len( + expected.columns + ), "Graph dataframe columns differ" # let's parse a sample of the raw graphml actual_graphml_0 = actual["clustered_graph"][:1][0] actual_graph_0 = nx.parse_graphml(actual_graphml_0) - expected_graphml_0 = expected["clustered_graph"][:1][0] - expected_graph_0 = nx.parse_graphml(expected_graphml_0) + assert actual_graph_0.number_of_nodes() == 3 + assert actual_graph_0.number_of_edges() == 2 - assert ( - actual_graph_0.number_of_nodes() == expected_graph_0.number_of_nodes() - ), "Graphml node count differs" - assert ( - actual_graph_0.number_of_edges() == expected_graph_0.number_of_edges() - ), "Graphml edge count differs" + # TODO: with the combined verb we can't force summarization + # this is because the mock responses always result in a single description, which is returned verbatim rather than summarized + # we need to update the mocking to provide somewhat unique graphs so a true merge happens + # the assertion should grab a node and ensure the description matches the mock description, not the original as we are doing below + nodes = list(actual_graph_0.nodes(data=True)) + assert nodes[0][1]["description"] == "Company_A is a test company" assert len(storage.keys()) == 0, "Storage should be empty" async def test_create_base_entity_graph_with_embeddings(): input_tables = load_input_tables([ - "workflow:create_summarized_entities", + "workflow:create_base_text_units", ]) expected = load_expected(workflow_name) config = get_config_for_workflow(workflow_name) + config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_ENTITY_CONFIG + config["summarize_descriptions"]["strategy"]["llm"] = MOCK_LLM_SUMMARIZATION_CONFIG config["embed_graph_enabled"] = True steps = build_steps(config) @@ -84,19 +120,22 @@ async def test_create_base_entity_graph_with_embeddings(): async def test_create_base_entity_graph_with_snapshots(): input_tables = load_input_tables([ - "workflow:create_summarized_entities", + "workflow:create_base_text_units", ]) - expected = load_expected(workflow_name) storage = MemoryPipelineStorage() config = get_config_for_workflow(workflow_name) + config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_ENTITY_CONFIG + config["summarize_descriptions"]["strategy"]["llm"] = MOCK_LLM_SUMMARIZATION_CONFIG + config["raw_entity_snapshot"] = True config["graphml_snapshot"] = True + config["embed_graph_enabled"] = True # need this on in order to see the snapshot steps = build_steps(config) - actual = await get_workflow_output( + await get_workflow_output( input_tables, { "steps": steps, @@ -104,15 +143,31 @@ async def test_create_base_entity_graph_with_snapshots(): storage=storage, ) - assert actual.shape == expected.shape, "Graph dataframe shapes differ" - assert storage.keys() == [ - "clustered_graph.0.graphml", - "clustered_graph.1.graphml", - "clustered_graph.2.graphml", - "clustered_graph.3.graphml", - "embedded_graph.0.graphml", - "embedded_graph.1.graphml", - "embedded_graph.2.graphml", - "embedded_graph.3.graphml", + "raw_extracted_entities.json", + "merged_graph.graphml", + "summarized_graph.graphml", + "clustered_graph.graphml", + "embedded_graph.graphml", ], "Graph snapshot keys differ" + + +async def test_create_base_entity_graph_missing_llm_throws(): + input_tables = load_input_tables([ + "workflow:create_base_text_units", + ]) + + config = get_config_for_workflow(workflow_name) + + config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_ENTITY_CONFIG + del config["summarize_descriptions"]["strategy"]["llm"] + + steps = build_steps(config) + + with pytest.raises(ValueError): # noqa PT011 + await get_workflow_output( + input_tables, + { + "steps": steps, + }, + ) diff --git a/tests/verbs/test_create_base_extracted_entities.py b/tests/verbs/test_create_base_extracted_entities.py deleted file mode 100644 index 57ca6003..00000000 --- a/tests/verbs/test_create_base_extracted_entities.py +++ /dev/null @@ -1,118 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -import networkx as nx -import pytest -from datashaper.errors import VerbParallelizationError - -from graphrag.config.enums import LLMType -from graphrag.index.storage.memory_pipeline_storage import MemoryPipelineStorage -from graphrag.index.workflows.v1.create_base_extracted_entities import ( - build_steps, - workflow_name, -) - -from .util import ( - get_config_for_workflow, - get_workflow_output, - load_expected, - load_input_tables, -) - -MOCK_LLM_RESPONSES = [ - """ - ("entity"<|>COMPANY_A<|>COMPANY<|>Company_A is a test company) - ## - ("entity"<|>COMPANY_B<|>COMPANY<|>Company_B owns Company_A and also shares an address with Company_A) - ## - ("entity"<|>PERSON_C<|>PERSON<|>Person_C is director of Company_A) - ## - ("relationship"<|>COMPANY_A<|>COMPANY_B<|>Company_A and Company_B are related because Company_A is 100% owned by Company_B and the two companies also share the same address)<|>2) - ## - ("relationship"<|>COMPANY_A<|>PERSON_C<|>Company_A and Person_C are related because Person_C is director of Company_A<|>1)) - """.strip() -] - -MOCK_LLM_CONFIG = { - "type": LLMType.StaticResponse, - "responses": MOCK_LLM_RESPONSES, -} - - -async def test_create_base_extracted_entities(): - input_tables = load_input_tables(["workflow:create_base_text_units"]) - expected = load_expected(workflow_name) - - storage = MemoryPipelineStorage() - - config = get_config_for_workflow(workflow_name) - - config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_CONFIG - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - storage=storage, - ) - - # let's parse a sample of the raw graphml - actual_graphml_0 = actual["entity_graph"][:1][0] - actual_graph_0 = nx.parse_graphml(actual_graphml_0) - - assert actual_graph_0.number_of_nodes() == 3 - assert actual_graph_0.number_of_edges() == 2 - - assert actual.columns == expected.columns - - assert len(storage.keys()) == 0, "Storage should be empty" - - -async def test_create_base_extracted_entities_with_snapshots(): - input_tables = load_input_tables(["workflow:create_base_text_units"]) - expected = load_expected(workflow_name) - - storage = MemoryPipelineStorage() - - config = get_config_for_workflow(workflow_name) - - config["entity_extract"]["strategy"]["llm"] = MOCK_LLM_CONFIG - config["raw_entity_snapshot"] = True - config["graphml_snapshot"] = True - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - storage=storage, - ) - - print(storage.keys()) - - assert actual.columns == expected.columns - - assert storage.keys() == ["raw_extracted_entities.json", "merged_graph.graphml"] - - -async def test_create_base_extracted_entities_missing_llm_throws(): - input_tables = load_input_tables(["workflow:create_base_text_units"]) - - config = get_config_for_workflow(workflow_name) - - del config["entity_extract"]["strategy"]["llm"] - - steps = build_steps(config) - - with pytest.raises(VerbParallelizationError): - await get_workflow_output( - input_tables, - { - "steps": steps, - }, - ) diff --git a/tests/verbs/test_create_final_documents.py b/tests/verbs/test_create_final_documents.py index c25b69ad..ac42fb7e 100644 --- a/tests/verbs/test_create_final_documents.py +++ b/tests/verbs/test_create_final_documents.py @@ -17,7 +17,7 @@ from .util import ( async def test_create_final_documents(): input_tables = load_input_tables([ - "workflow:create_base_documents", + "workflow:create_final_text_units", ]) expected = load_expected(workflow_name) @@ -39,7 +39,7 @@ async def test_create_final_documents(): async def test_create_final_documents_with_embeddings(): input_tables = load_input_tables([ - "workflow:create_base_documents", + "workflow:create_final_text_units", ]) expected = load_expected(workflow_name) @@ -63,3 +63,28 @@ async def test_create_final_documents_with_embeddings(): assert len(actual.columns) == len(expected.columns) + 1 # the mock impl returns an array of 3 floats for each embedding assert len(actual["raw_content_embedding"][:1][0]) == 3 + + +async def test_create_final_documents_with_attribute_columns(): + input_tables = load_input_tables(["workflow:create_final_text_units"]) + expected = load_expected(workflow_name) + + config = get_config_for_workflow(workflow_name) + + config["document_attribute_columns"] = ["title"] + + steps = build_steps(config) + + actual = await get_workflow_output( + input_tables, + { + "steps": steps, + }, + ) + + # we should have dropped "title" and added "attributes" + # our test dataframe does not have attributes, so we'll assert without it + # and separately confirm it is in the output + compare_outputs(actual, expected, columns=["id", "text_unit_ids", "raw_content"]) + assert len(actual.columns) == 4 + assert "attributes" in actual.columns diff --git a/tests/verbs/test_create_summarized_entities.py b/tests/verbs/test_create_summarized_entities.py deleted file mode 100644 index c36c9b53..00000000 --- a/tests/verbs/test_create_summarized_entities.py +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright (c) 2024 Microsoft Corporation. -# Licensed under the MIT License - -import networkx as nx -import pytest - -from graphrag.config.enums import LLMType -from graphrag.index.storage.memory_pipeline_storage import MemoryPipelineStorage -from graphrag.index.workflows.v1.create_summarized_entities import ( - build_steps, - workflow_name, -) - -from .util import ( - get_config_for_workflow, - get_workflow_output, - load_expected, - load_input_tables, -) - -MOCK_LLM_RESPONSES = [ - """ - This is a MOCK response for the LLM. It is summarized! - """.strip() -] - -MOCK_LLM_CONFIG = { - "type": LLMType.StaticResponse, - "responses": MOCK_LLM_RESPONSES, -} - - -async def test_create_summarized_entities(): - input_tables = load_input_tables([ - "workflow:create_base_extracted_entities", - ]) - expected = load_expected(workflow_name) - - storage = MemoryPipelineStorage() - - config = get_config_for_workflow(workflow_name) - - config["summarize_descriptions"]["strategy"]["llm"] = MOCK_LLM_CONFIG - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - storage=storage, - ) - - # the serialization of the graph may differ so we can't assert the dataframes directly - assert actual.shape == expected.shape, "Graph dataframe shapes differ" - - # let's parse a sample of the raw graphml - actual_graphml_0 = actual["entity_graph"][:1][0] - actual_graph_0 = nx.parse_graphml(actual_graphml_0) - - expected_graphml_0 = expected["entity_graph"][:1][0] - expected_graph_0 = nx.parse_graphml(expected_graphml_0) - - assert ( - actual_graph_0.number_of_nodes() == expected_graph_0.number_of_nodes() - ), "Graphml node count differs" - assert ( - actual_graph_0.number_of_edges() == expected_graph_0.number_of_edges() - ), "Graphml edge count differs" - - # ensure the mock summary was injected to the nodes - nodes = list(actual_graph_0.nodes(data=True)) - assert ( - nodes[0][1]["description"] - == "This is a MOCK response for the LLM. It is summarized!" - ) - - assert len(storage.keys()) == 0, "Storage should be empty" - - -async def test_create_summarized_entities_with_snapshots(): - input_tables = load_input_tables([ - "workflow:create_base_extracted_entities", - ]) - expected = load_expected(workflow_name) - - storage = MemoryPipelineStorage() - - config = get_config_for_workflow(workflow_name) - - config["summarize_descriptions"]["strategy"]["llm"] = MOCK_LLM_CONFIG - config["graphml_snapshot"] = True - - steps = build_steps(config) - - actual = await get_workflow_output( - input_tables, - { - "steps": steps, - }, - storage=storage, - ) - - assert actual.shape == expected.shape, "Graph dataframe shapes differ" - - assert storage.keys() == [ - "summarized_graph.graphml", - ], "Graph snapshot keys differ" - - -async def test_create_summarized_entities_missing_llm_throws(): - input_tables = load_input_tables([ - "workflow:create_base_extracted_entities", - ]) - - config = get_config_for_workflow(workflow_name) - - del config["summarize_descriptions"]["strategy"]["llm"] - - steps = build_steps(config) - - with pytest.raises(ValueError): # noqa PT011 - await get_workflow_output( - input_tables, - { - "steps": steps, - }, - ) diff --git a/tests/verbs/util.py b/tests/verbs/util.py index 2d6d5b6d..f4e764da 100644 --- a/tests/verbs/util.py +++ b/tests/verbs/util.py @@ -26,7 +26,7 @@ def load_input_tables(inputs: list[str]) -> dict[str, pd.DataFrame]: # all workflows implicitly receive the `input` source, which is formatted as a dataframe after loading from storage # we'll simulate that by just loading one of our output parquets and converting back to equivalent dataframe # so we aren't dealing with storage vagaries (which would become an integration test) - source = pd.read_parquet("tests/verbs/data/create_base_documents.parquet") + source = pd.read_parquet("tests/verbs/data/create_final_documents.parquet") source.rename(columns={"raw_content": "text"}, inplace=True) input_tables["source"] = cast(pd.DataFrame, source[["id", "text", "title"]])