From 45458412e852af4b269a756e028b635e047dde99 Mon Sep 17 00:00:00 2001 From: Taylor Turner Date: Fri, 14 Jun 2024 13:11:45 -0400 Subject: [PATCH 01/14] staging/main/0.12.0 (#1145) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: Upgrade the models to use keras 3.0 (#1138) * Replace snappy with cramjam (#1091) * add downloads tile (#1085) * Replace snappy with cramjam * Delete test_no_snappy --------- Co-authored-by: Taylor Turner * pre-commit fix (#1122) * Bug fix for float precision calculation using categorical data with trailing zeros. (#1125) * Revert "Bug fix for float precision calculation using categorical data with t…" (#1133) This reverts commit d3159bd13911892e74c264966fba011d50f20e95. * refactor: move layers outside of class * refactor: update model to keras 3.0 * fix: manifest * fix: bugs in compile and train * fix: bug in load_from_library * fix: bugs in CharCNN * refactor: loading tf model labeler * fix: bug in data_labeler identification * fix: update model to use proper softmax layer names * fix: formatting * fix: remove unused line * refactor: drop support for 3.8 * fix: comments * fix: comment --------- Co-authored-by: Gábor Lipták Co-authored-by: Taylor Turner Co-authored-by: James Schadt * Fix Tox (#1143) * tox new * update * update * update * update * update * update * update * update tox.ini * update * update * remove docs * empty retrigger * update (#1146) * bump version * update 3.11 * remove dist/ --------- Co-authored-by: JGSweets Co-authored-by: Gábor Lipták Co-authored-by: James Schadt --- .github/workflows/publish-python-package.yml | 2 +- .github/workflows/test-python-package.yml | 2 +- MANIFEST.in | 1 + dataprofiler/labelers/char_load_tf_model.py | 41 ++- .../labelers/character_level_cnn_model.py | 279 +++++++++++------- dataprofiler/labelers/data_labelers.py | 6 +- dataprofiler/labelers/labeler_utils.py | 7 +- .../tests/labelers/test_char_tf_load_model.py | 2 +- .../test_character_level_cnn_model.py | 15 +- .../tests/labelers/test_labeler_utils.py | 43 ++- dataprofiler/version.py | 2 +- requirements-dev.txt | 1 + requirements-ml.txt | 8 +- requirements-test.txt | 2 +- requirements.txt | 2 +- .../structured_model/keras_metadata.pb | 29 -- ...iables.data-00000-of-00001 => model.keras} | Bin 635392 -> 694688 bytes .../labelers/structured_model/saved_model.pb | Bin 544918 -> 0 bytes .../variables/variables.index | Bin 2660 -> 0 bytes .../unstructured_model/keras_metadata.pb | 29 -- ...iables.data-00000-of-00001 => model.keras} | Bin 635392 -> 694688 bytes .../unstructured_model/saved_model.pb | Bin 544918 -> 0 bytes .../variables/variables.index | Bin 2660 -> 0 bytes setup.py | 2 +- tox.ini | 17 +- 25 files changed, 247 insertions(+), 243 deletions(-) delete mode 100644 resources/labelers/structured_model/keras_metadata.pb rename resources/labelers/structured_model/{variables/variables.data-00000-of-00001 => model.keras} (88%) delete mode 100644 resources/labelers/structured_model/saved_model.pb delete mode 100644 resources/labelers/structured_model/variables/variables.index delete mode 100644 resources/labelers/unstructured_model/keras_metadata.pb rename resources/labelers/unstructured_model/{variables/variables.data-00000-of-00001 => model.keras} (88%) delete mode 100644 resources/labelers/unstructured_model/saved_model.pb delete mode 100644 resources/labelers/unstructured_model/variables/variables.index diff --git a/.github/workflows/publish-python-package.yml b/.github/workflows/publish-python-package.yml index 75b9a41e2..4ed9e1bf3 100644 --- a/.github/workflows/publish-python-package.yml +++ b/.github/workflows/publish-python-package.yml @@ -20,7 +20,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/test-python-package.yml b/.github/workflows/test-python-package.yml index fa84b3d3a..3c88e7211 100644 --- a/.github/workflows/test-python-package.yml +++ b/.github/workflows/test-python-package.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.8, 3.9, "3.10"] + python-version: [3.9, "3.10", "3.11"] steps: - uses: actions/checkout@v4 diff --git a/MANIFEST.in b/MANIFEST.in index 12480abd8..0ace6ebe9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,5 @@ global-exclude .DS_Store +global-exclude */__pycache__/* include *.txt include CODEOWNERS diff --git a/dataprofiler/labelers/char_load_tf_model.py b/dataprofiler/labelers/char_load_tf_model.py index b168e9234..a4a44e03a 100644 --- a/dataprofiler/labelers/char_load_tf_model.py +++ b/dataprofiler/labelers/char_load_tf_model.py @@ -237,7 +237,8 @@ def _construct_model(self) -> None: model_loc = self._parameters["model_path"] self._model: tf.keras.Model = tf.keras.models.load_model(model_loc) - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + self._model = tf.keras.Model(self._model.inputs, self._model.outputs) + softmax_output_layer_name = self._model.output_names[0] softmax_layer_ind = cast( int, labeler_utils.get_tf_layer_index_from_name( @@ -252,21 +253,28 @@ def _construct_model(self) -> None: num_labels, activation="softmax", name="softmax_output" )(self._model.layers[softmax_layer_ind - 1].output) - # Output the model into a .pb file for TensorFlow - argmax_layer = tf.keras.backend.argmax(new_softmax_layer) + # Add argmax layer to get labels directly as an output + argmax_layer = tf.keras.ops.argmax(new_softmax_layer, axis=2) argmax_outputs = [new_softmax_layer, argmax_layer] self._model = tf.keras.Model(self._model.inputs, argmax_outputs) + self._model = tf.keras.Model(self._model.inputs, self._model.outputs) # Compile the model w/ metrics - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] losses = {softmax_output_layer_name: "categorical_crossentropy"} # use f1 score metric f1_score_training = labeler_utils.F1Score( num_classes=num_labels, average="micro" ) - metrics = {softmax_output_layer_name: ["acc", f1_score_training]} + metrics = { + softmax_output_layer_name: [ + "categorical_crossentropy", + "acc", + f1_score_training, + ] + } self._model.compile(loss=losses, optimizer="adam", metrics=metrics) @@ -294,30 +302,33 @@ def _reconstruct_model(self) -> None: num_labels = self.num_labels default_ind = self.label_mapping[self._parameters["default_label"]] - # Remove the 2 output layers ('softmax', 'tf_op_layer_ArgMax') - for _ in range(2): - self._model.layers.pop() - # Add the final Softmax layer to the previous spot + # self._model.layers[-2] to skip: original softmax final_softmax_layer = tf.keras.layers.Dense( num_labels, activation="softmax", name="softmax_output" - )(self._model.layers[-4].output) + )(self._model.layers[-2].output) - # Output the model into a .pb file for TensorFlow - argmax_layer = tf.keras.backend.argmax(final_softmax_layer) + # Add argmax layer to get labels directly as an output + argmax_layer = tf.keras.ops.argmax(final_softmax_layer, axis=2) argmax_outputs = [final_softmax_layer, argmax_layer] self._model = tf.keras.Model(self._model.inputs, argmax_outputs) # Compile the model - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] losses = {softmax_output_layer_name: "categorical_crossentropy"} # use f1 score metric f1_score_training = labeler_utils.F1Score( num_classes=num_labels, average="micro" ) - metrics = {softmax_output_layer_name: ["acc", f1_score_training]} + metrics = { + softmax_output_layer_name: [ + "categorical_crossentropy", + "acc", + f1_score_training, + ] + } self._model.compile(loss=losses, optimizer="adam", metrics=metrics) @@ -370,7 +381,7 @@ def fit( f1_report: dict = {} self._model.reset_metrics() - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] start_time = time.time() batch_id = 0 diff --git a/dataprofiler/labelers/character_level_cnn_model.py b/dataprofiler/labelers/character_level_cnn_model.py index 3194a2616..2cbb7051a 100644 --- a/dataprofiler/labelers/character_level_cnn_model.py +++ b/dataprofiler/labelers/character_level_cnn_model.py @@ -74,6 +74,133 @@ def create_glove_char(n_dims: int, source_file: str = None) -> None: file.write(word + " " + " ".join(str(num) for num in embd) + "\n") +@tf.keras.utils.register_keras_serializable(package="CharacterLevelCnnModel") +class ThreshArgMaxLayer(tf.keras.layers.Layer): + """Keras layer applying a thresholded argmax.""" + + def __init__( + self, threshold_: float, num_labels_: int, default_ind: int = 1, *args, **kwargs + ) -> None: + """Apply a minimum threshold to the argmax value. + + When below this threshold the index will be the default. + + :param num_labels: number of entities + :type num_labels: int + :param threshold: default set to 0 so all confidences pass. + :type threshold: float + :param default_ind: default index + :type default_ind: int + :return: final argmax threshold layer for the model + :return : tensor containing argmax thresholded integers, labels out + :rtype: tf.Tensor + """ + super().__init__(*args, **kwargs) + self._threshold_ = threshold_ + self._num_labels_ = num_labels_ + self._default_ind = default_ind + thresh_init = tf.constant_initializer(threshold_) + self.thresh_vec = tf.Variable( + name="ThreshVec", + initial_value=thresh_init(shape=[num_labels_]), + trainable=False, + ) + + def get_config(self): + """Return a serializable config for saving the layer.""" + config = super().get_config().copy() + config.update( + { + "threshold_": self._threshold_, + "num_labels_": self._num_labels_, + "default_ind": self._default_ind, + } + ) + return config + + def call(self, argmax_layer: tf.Tensor, confidence_layer: tf.Tensor) -> tf.Tensor: + """Apply the threshold argmax to the input tensor.""" + threshold_at_argmax = tf.gather(self.thresh_vec, argmax_layer) + + confidence_max_layer = tf.keras.backend.max(confidence_layer, axis=2) + + # Check if the confidences meet the threshold minimum. + argmax_mask = tf.keras.backend.cast( + tf.keras.backend.greater_equal(confidence_max_layer, threshold_at_argmax), + dtype=argmax_layer.dtype, + ) + + # Create a vector the same size as the batch_size which + # represents the background label + bg_label_tf = tf.keras.backend.constant( + self._default_ind, dtype=argmax_layer.dtype + ) + + # Generate the final predicted output using the function: + final_predicted_layer = tf.add( + bg_label_tf, + tf.multiply(tf.subtract(argmax_layer, bg_label_tf), argmax_mask), + name="ThreshArgMax", + ) + # final_predicted_layer.set_shape(argmax_layer.shape) + return final_predicted_layer + + +@tf.keras.utils.register_keras_serializable(package="CharacterLevelCnnModel") +class EncodingLayer(tf.keras.layers.Layer): + """Encodes strings to integers.""" + + def __init__( + self, max_char_encoding_id: int, max_len: int, *args, **kwargs + ) -> None: + """ + Encode characters for the list of sentences. + + :param max_char_encoding_id: Maximum integer value for encoding the + input + :type max_char_encoding_id: int + :param max_len: Maximum char length in a sample + :type max_len: int + """ + super().__init__(*args, **kwargs) + self.max_char_encoding_id = max_char_encoding_id + self.max_len = max_len + + def get_config(self): + """Return a serializable config for saving the layer.""" + config = super().get_config().copy() + config.update( + { + "max_char_encoding_id": self.max_char_encoding_id, + "max_len": self.max_len, + } + ) + return config + + def call(self, input_str_tensor: tf.Tensor) -> tf.Tensor: + """ + Encode characters for the list of sentences. + + :param input_str_tensor: input list of sentences converted to tensor + :type input_str_tensor: tf.tensor + :return : tensor containing encoded list of input sentences + :rtype: tf.Tensor + """ + # convert characters to indices + input_str_flatten = tf.reshape(input_str_tensor, [-1]) + sentences_encode = tf.strings.unicode_decode( + input_str_flatten, input_encoding="UTF-8" + ) + sentences_encode = tf.add(tf.cast(1, tf.int32), sentences_encode) + sentences_encode = tf.math.minimum( + sentences_encode, self.max_char_encoding_id + 1 + ) + + # padding + sentences_encode_pad = sentences_encode.to_tensor(shape=[None, self.max_len]) + return sentences_encode_pad + + class CharacterLevelCnnModel(BaseTrainableModel, metaclass=AutoSubRegistrationMeta): """Class for training char data labeler.""" @@ -280,7 +407,7 @@ def save_to_disk(self, dirpath: str) -> None: labels_dirpath = os.path.join(dirpath, "label_mapping.json") with open(labels_dirpath, "w") as fp: json.dump(self.label_mapping, fp) - self._model.save(os.path.join(dirpath)) + self._model.save(os.path.join(dirpath, "model.keras")) @classmethod def load_from_disk(cls, dirpath: str) -> CharacterLevelCnnModel: @@ -301,15 +428,7 @@ def load_from_disk(cls, dirpath: str) -> CharacterLevelCnnModel: with open(labels_dirpath) as fp: label_mapping = json.load(fp) - # use f1 score metric - custom_objects = { - "F1Score": labeler_utils.F1Score( - num_classes=max(label_mapping.values()) + 1, average="micro" - ), - "CharacterLevelCnnModel": cls, - } - with tf.keras.utils.custom_object_scope(custom_objects): - tf_model = tf.keras.models.load_model(dirpath) + tf_model = tf.keras.models.load_model(os.path.join(dirpath, "model.keras")) loaded_model = cls(label_mapping, parameters) loaded_model._model = tf_model @@ -333,35 +452,6 @@ def load_from_disk(cls, dirpath: str) -> CharacterLevelCnnModel: ] return loaded_model - @staticmethod - def _char_encoding_layer( - input_str_tensor: tf.Tensor, max_char_encoding_id: int, max_len: int - ) -> tf.Tensor: - """ - Encode characters for the list of sentences. - - :param input_str_tensor: input list of sentences converted to tensor - :type input_str_tensor: tf.tensor - :param max_char_encoding_id: Maximum integer value for encoding the - input - :type max_char_encoding_id: int - :param max_len: Maximum char length in a sample - :type max_len: int - :return : tensor containing encoded list of input sentences - :rtype: tf.Tensor - """ - # convert characters to indices - input_str_flatten = tf.reshape(input_str_tensor, [-1]) - sentences_encode = tf.strings.unicode_decode( - input_str_flatten, input_encoding="UTF-8" - ) - sentences_encode = tf.add(tf.cast(1, tf.int32), sentences_encode) - sentences_encode = tf.math.minimum(sentences_encode, max_char_encoding_id + 1) - - # padding - sentences_encode_pad = sentences_encode.to_tensor(shape=[None, max_len]) - return sentences_encode_pad - @staticmethod def _argmax_threshold_layer( num_labels: int, threshold: float = 0.0, default_ind: int = 1 @@ -383,47 +473,7 @@ def _argmax_threshold_layer( """ # Initialize the thresholds vector variable and create the threshold # matrix. - class ThreshArgMaxLayer(tf.keras.layers.Layer): - def __init__(self, threshold_: float, num_labels_: int) -> None: - super().__init__() - thresh_init = tf.constant_initializer(threshold_) - self.thresh_vec = tf.Variable( - name="ThreshVec", - initial_value=thresh_init(shape=[num_labels_]), - trainable=False, - ) - - def call( - self, argmax_layer: tf.Tensor, confidence_layer: tf.Tensor - ) -> tf.Tensor: - threshold_at_argmax = tf.gather(self.thresh_vec, argmax_layer) - - confidence_max_layer = tf.keras.backend.max(confidence_layer, axis=2) - - # Check if the confidences meet the threshold minimum. - argmax_mask = tf.keras.backend.cast( - tf.keras.backend.greater_equal( - confidence_max_layer, threshold_at_argmax - ), - dtype=argmax_layer.dtype, - ) - - # Create a vector the same size as the batch_size which - # represents the background label - bg_label_tf = tf.keras.backend.constant( - default_ind, dtype=argmax_layer.dtype - ) - - # Generate the final predicted output using the function: - final_predicted_layer = tf.add( - bg_label_tf, - tf.multiply(tf.subtract(argmax_layer, bg_label_tf), argmax_mask), - name="ThreshArgMax", - ) - - return final_predicted_layer - - return ThreshArgMaxLayer(threshold, num_labels) + return ThreshArgMaxLayer(threshold, num_labels, default_ind) def _construct_model(self) -> None: """ @@ -449,17 +499,13 @@ def _construct_model(self) -> None: max_length = self._parameters["max_length"] max_char_encoding_id = self._parameters["max_char_encoding_id"] - # Encoding layer - def encoding_function(input_str: tf.Tensor) -> tf.Tensor: - char_in_vector = CharacterLevelCnnModel._char_encoding_layer( - input_str, max_char_encoding_id, max_length - ) - return char_in_vector - self._model.add(tf.keras.layers.Input(shape=(None,), dtype=tf.string)) self._model.add( - tf.keras.layers.Lambda(encoding_function, output_shape=tuple([max_length])) + EncodingLayer( + max_char_encoding_id=max_char_encoding_id, + max_len=max_length, + ), ) # Create a pre-trained weight matrix @@ -474,7 +520,6 @@ def encoding_function(input_str: tf.Tensor) -> tf.Tensor: ) embedding_dict = build_embd_dictionary(embed_file) - input_shape = tuple([max_length]) # Fill in the weight matrix: let pad and space be 0s for ascii_num in range(max_char_encoding_id): if chr(ascii_num) in embedding_dict: @@ -485,7 +530,6 @@ def encoding_function(input_str: tf.Tensor) -> tf.Tensor: max_char_encoding_id + 2, self._parameters["dim_embed"], weights=[embedding_matrix], - input_length=input_shape[0], trainable=True, ) ) @@ -502,8 +546,7 @@ def encoding_function(input_str: tf.Tensor) -> tf.Tensor: ) if self._parameters["dropout"]: self._model.add(tf.keras.layers.Dropout(self._parameters["dropout"])) - # Add batch normalization, set fused = True for compactness - self._model.add(tf.keras.layers.BatchNormalization(fused=False, scale=True)) + self._model.add(tf.keras.layers.BatchNormalization(scale=True)) # Add the fully connected layers for size in self._parameters["size_fc"]: @@ -514,29 +557,35 @@ def encoding_function(input_str: tf.Tensor) -> tf.Tensor: # Add the final Softmax layer self._model.add(tf.keras.layers.Dense(num_labels, activation="softmax")) - # Output the model into a .pb file for TensorFlow - argmax_layer = tf.keras.backend.argmax(self._model.output) + # Add argmax layer to get labels directly as an output + argmax_layer = tf.keras.ops.argmax(self._model.outputs[0], axis=2) # Create confidence layers - final_predicted_layer = CharacterLevelCnnModel._argmax_threshold_layer( - num_labels, threshold=0.0, default_ind=default_ind + final_predicted_layer = ThreshArgMaxLayer( + threshold_=0.0, num_labels_=num_labels, default_ind=default_ind ) argmax_outputs = self._model.outputs + [ argmax_layer, - final_predicted_layer(argmax_layer, self._model.output), + final_predicted_layer(argmax_layer, self._model.outputs[0]), ] self._model = tf.keras.Model(self._model.inputs, argmax_outputs) # Compile the model - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] losses = {softmax_output_layer_name: "categorical_crossentropy"} # use f1 score metric f1_score_training = labeler_utils.F1Score( num_classes=num_labels, average="micro" ) - metrics = {softmax_output_layer_name: ["acc", f1_score_training]} + metrics = { + softmax_output_layer_name: [ + "categorical_crossentropy", + "acc", + f1_score_training, + ] + } self._model.compile(loss=losses, optimizer="adam", metrics=metrics) @@ -564,22 +613,18 @@ def _reconstruct_model(self) -> None: num_labels = self.num_labels default_ind = self.label_mapping[self._parameters["default_label"]] - # Remove the 3 output layers (dense_2', 'tf_op_layer_ArgMax', - # 'thresh_arg_max_layer') - for _ in range(3): - self._model.layers.pop() - # Add the final Softmax layer to the previous spot + # self._model.layers[-3] to skip: thresh and original softmax final_softmax_layer = tf.keras.layers.Dense( num_labels, activation="softmax", name="dense_2" - )(self._model.layers[-4].output) + )(self._model.layers[-3].output) - # Output the model into a .pb file for TensorFlow - argmax_layer = tf.keras.backend.argmax(final_softmax_layer) + # Add argmax layer to get labels directly as an output + argmax_layer = tf.keras.ops.argmax(final_softmax_layer, axis=2) # Create confidence layers - final_predicted_layer = CharacterLevelCnnModel._argmax_threshold_layer( - num_labels, threshold=0.0, default_ind=default_ind + final_predicted_layer = ThreshArgMaxLayer( + threshold_=0.0, num_labels_=num_labels, default_ind=default_ind ) argmax_outputs = [final_softmax_layer] + [ @@ -589,14 +634,20 @@ def _reconstruct_model(self) -> None: self._model = tf.keras.Model(self._model.inputs, argmax_outputs) # Compile the model - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] losses = {softmax_output_layer_name: "categorical_crossentropy"} # use f1 score metric f1_score_training = labeler_utils.F1Score( num_classes=num_labels, average="micro" ) - metrics = {softmax_output_layer_name: ["acc", f1_score_training]} + metrics = { + softmax_output_layer_name: [ + "categorical_crossentropy", + "acc", + f1_score_training, + ] + } self._model.compile(loss=losses, optimizer="adam", metrics=metrics) self._epoch_id = 0 @@ -648,7 +699,7 @@ def fit( f1_report: dict = {} self._model.reset_metrics() - softmax_output_layer_name = self._model.outputs[0].name.split("/")[0] + softmax_output_layer_name = self._model.output_names[0] start_time = time.time() batch_id = 0 @@ -729,7 +780,9 @@ def _validate_training( for x_val, y_val in val_data: y_val_pred.append( self._model.predict( - x_val, batch_size=batch_size_test, verbose=verbose_keras + tf.convert_to_tensor(x_val), + batch_size=batch_size_test, + verbose=verbose_keras, )[1] ) y_val_test.append(np.argmax(y_val, axis=-1)) diff --git a/dataprofiler/labelers/data_labelers.py b/dataprofiler/labelers/data_labelers.py index 7172e7472..a6d9932b7 100644 --- a/dataprofiler/labelers/data_labelers.py +++ b/dataprofiler/labelers/data_labelers.py @@ -141,11 +141,11 @@ def load_from_library(cls, name: str, trainable: bool = False) -> BaseDataLabele :type trainable: bool :return: DataLabeler class """ + for labeler_name, labeler_class_obj in cls.labeler_classes.items(): + if name == labeler_name: + name = labeler_class_obj._default_model_loc if trainable: return TrainableDataLabeler.load_from_library(name) - for _, labeler_class_obj in cls.labeler_classes.items(): - if name in labeler_class_obj._default_model_loc: - return labeler_class_obj() return BaseDataLabeler.load_from_library(name) @classmethod diff --git a/dataprofiler/labelers/labeler_utils.py b/dataprofiler/labelers/labeler_utils.py index b6070ff72..3a24886f3 100644 --- a/dataprofiler/labelers/labeler_utils.py +++ b/dataprofiler/labelers/labeler_utils.py @@ -358,7 +358,7 @@ def __init__( def _zero_wt_init(name: str) -> tf.Variable: return self.add_weight( - name, shape=self.init_shape, initializer="zeros", dtype=self.dtype + name=name, shape=self.init_shape, initializer="zeros", dtype=self.dtype ) self.true_positives = _zero_wt_init("true_positives") @@ -435,11 +435,6 @@ def get_config(self) -> dict: base_config = super().get_config() return {**base_config, **config} - def reset_state(self) -> None: - """Reset state.""" - reset_value = tf.zeros(self.init_shape, dtype=self.dtype) - tf.keras.backend.batch_set_value([(v, reset_value) for v in self.variables]) - @protected_register_keras_serializable() class F1Score(FBetaScore): diff --git a/dataprofiler/tests/labelers/test_char_tf_load_model.py b/dataprofiler/tests/labelers/test_char_tf_load_model.py index fbfde0c49..c6d70f740 100644 --- a/dataprofiler/tests/labelers/test_char_tf_load_model.py +++ b/dataprofiler/tests/labelers/test_char_tf_load_model.py @@ -272,7 +272,7 @@ def test_fit_and_predict(self, *mocks): ) # predict after fitting on just the text - model.predict(data_gen[0][0]) + model.predict([data_gen[0][0]]) @mock.patch("os.makedirs", return_value=None) def test_validation_evaluate_and_classification_report(self, *mocks): diff --git a/dataprofiler/tests/labelers/test_character_level_cnn_model.py b/dataprofiler/tests/labelers/test_character_level_cnn_model.py index ad549cc53..e120a9754 100644 --- a/dataprofiler/tests/labelers/test_character_level_cnn_model.py +++ b/dataprofiler/tests/labelers/test_character_level_cnn_model.py @@ -9,7 +9,10 @@ import pkg_resources import tensorflow as tf -from dataprofiler.labelers.character_level_cnn_model import CharacterLevelCnnModel +from dataprofiler.labelers.character_level_cnn_model import ( + CharacterLevelCnnModel, + EncodingLayer, +) _file_dir = os.path.dirname(os.path.abspath(__file__)) _resource_labeler_dir = pkg_resources.resource_filename("resources", "labelers") @@ -272,7 +275,7 @@ def test_fit_and_predict_with_new_labels(self): ) # predict after fitting on just the text - cnn_model.predict(data_gen[0][0]) + cnn_model.predict([data_gen[0][0]]) def test_fit_and_predict_with_new_labels_set_via_method(self): # Initialize model @@ -301,7 +304,7 @@ def test_fit_and_predict_with_new_labels_set_via_method(self): history, f1, f1_report = cnn_model.fit(data_gen, cv_gen) # test predict on just the text - cnn_model.predict(data_gen[0][0]) + cnn_model.predict([data_gen[0][0]]) def test_validation(self): @@ -368,9 +371,8 @@ def test_input_encoding(self): max_char_encoding_id = 127 max_len = 10 - encode_output = cnn_model._char_encoding_layer( - input_str_tensor, max_char_encoding_id, max_len - ).numpy()[0] + encode_layer = EncodingLayer(max_char_encoding_id, max_len) + encode_output = encode_layer.call(input_str_tensor).numpy()[0] expected_output = [117, 102, 116, 117, 0, 0, 0, 0, 0, 0] self.assertCountEqual(encode_output, expected_output) @@ -464,7 +466,6 @@ def test_model_construct(self): "dense_1", "dropout_5", "dense_2", - "tf_op_layer_ArgMax", "thresh_arg_max_layer", ] model_layers = [layer.name for layer in cnn_model._model.layers] diff --git a/dataprofiler/tests/labelers/test_labeler_utils.py b/dataprofiler/tests/labelers/test_labeler_utils.py index f59a43e3f..c14fca54f 100644 --- a/dataprofiler/tests/labelers/test_labeler_utils.py +++ b/dataprofiler/tests/labelers/test_labeler_utils.py @@ -1,6 +1,6 @@ import logging +import tempfile import unittest -from unittest import mock import numpy as np import pandas as pd @@ -235,9 +235,7 @@ def test_verbose(self): self.assertIn("f1-score ", log_output) self.assertIn("F1 Score: ", log_output) - @mock.patch("dataprofiler.labelers.labeler_utils.classification_report") - @mock.patch("pandas.DataFrame") - def test_save_conf_mat(self, mock_dataframe, mock_report): + def test_save_conf_mat(self): # ideally mock out the actual contents written to file, but # would be difficult to get this completely worked out. @@ -248,28 +246,25 @@ def test_save_conf_mat(self, mock_dataframe, mock_report): [0, 1, 2], ] ) - expected_row_col_names = dict( - columns=["pred:PAD", "pred:UNKNOWN", "pred:OTHER"], - index=["true:PAD", "true:UNKNOWN", "true:OTHER"], - ) - mock_instance_df = mock.Mock(spec=pd.DataFrame)() - mock_dataframe.return_value = mock_instance_df - - # still omit bc confusion mat should include all despite omit - f1, f1_report = labeler_utils.evaluate_accuracy( - self.y_pred, - self.y_true, - self.num_labels, - self.reverse_label_mapping, - omitted_labels=["PAD"], - verbose=False, - confusion_matrix_file="test.csv", - ) + expected_columns = ["pred:PAD", "pred:UNKNOWN", "pred:OTHER"] + expected_index = ["true:PAD", "true:UNKNOWN", "true:OTHER"] - self.assertTrue((mock_dataframe.call_args[0][0] == expected_conf_mat).all()) - self.assertDictEqual(expected_row_col_names, mock_dataframe.call_args[1]) + with tempfile.NamedTemporaryFile() as tmpFile: + # still omit bc confusion mat should include all despite omit + f1, f1_report = labeler_utils.evaluate_accuracy( + self.y_pred, + self.y_true, + self.num_labels, + self.reverse_label_mapping, + omitted_labels=["PAD"], + verbose=False, + confusion_matrix_file=tmpFile.name, + ) - mock_instance_df.to_csv.assert_called() + df1 = pd.read_csv(tmpFile.name, index_col=0) + self.assertListEqual(list(df1.columns), expected_columns) + self.assertListEqual(list(df1.index), expected_index) + np.testing.assert_array_equal(df1.values, expected_conf_mat) class TestTFFunctions(unittest.TestCase): diff --git a/dataprofiler/version.py b/dataprofiler/version.py index 1136efae1..b41e1c451 100644 --- a/dataprofiler/version.py +++ b/dataprofiler/version.py @@ -1,7 +1,7 @@ """File contains the version number for the package.""" MAJOR = 0 -MINOR = 11 +MINOR = 12 MICRO = 0 POST = None # otherwise None diff --git a/requirements-dev.txt b/requirements-dev.txt index cff8f51a0..f6343283c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,6 +3,7 @@ black>=24.3.0 isort==5.12.0 pre-commit==2.19.0 tox==3.25.1 +tox-conda==0.10.2 types-setuptools==67.7.0.1 types-python-dateutil==2.8.19.12 types-requests==2.30.0.0 diff --git a/requirements-ml.txt b/requirements-ml.txt index ff525fec1..6da08b313 100644 --- a/requirements-ml.txt +++ b/requirements-ml.txt @@ -1,7 +1,7 @@ scikit-learn>=0.23.2 -keras>=2.4.3,<3.0.0 +keras>=3.0.0 rapidfuzz>=2.6.1 -tensorflow>=2.6.4,<2.15.0; sys.platform != 'darwin' -tensorflow>=2.6.4,<2.15.0; sys_platform == 'darwin' and platform_machine != 'arm64' -tensorflow-macos>=2.6.4,<2.15.0; sys_platform == 'darwin' and platform_machine == 'arm64' +tensorflow>=2.16.0; sys.platform != 'darwin' +tensorflow>=2.16.0; sys_platform == 'darwin' and platform_machine != 'arm64' +tensorflow-macos>=2.16.0; sys_platform == 'darwin' and platform_machine == 'arm64' tqdm>=4.0.0 diff --git a/requirements-test.txt b/requirements-test.txt index 6c981cf9c..725b23849 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,5 +1,5 @@ coverage>=5.0.1 -dask>=2.29.0,<2024.2.0 +dask[dask-expr,dataframe]>=2024.4.1 fsspec>=0.3.3 pytest>=6.0.1 pytest-cov>=2.8.1 diff --git a/requirements.txt b/requirements.txt index a45dc34ae..152b5eb36 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ python-dateutil>=2.7.5 pytz>=2020.1 pyarrow>=1.0.1 chardet>=3.0.4 -fastavro>=1.0.0.post1 +fastavro>=1.1.0 python-snappy>=0.5.4 charset-normalizer>=1.3.6 psutil>=4.0.0 diff --git a/resources/labelers/structured_model/keras_metadata.pb b/resources/labelers/structured_model/keras_metadata.pb deleted file mode 100644 index dcc84a213..000000000 --- a/resources/labelers/structured_model/keras_metadata.pb +++ /dev/null @@ -1,29 +0,0 @@ - -`root"_tf_keras_network*`{"name": "functional_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Functional", "config": {"name": "functional_1", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "dtype": "string", "sparse": false, "ragged": false, "name": "input_1"}, "name": "input_1", "inbound_nodes": []}, {"class_name": "Lambda", "config": {"name": "lambda", "trainable": true, "dtype": "float32", "function": {"class_name": "__tuple__", "items": ["4wEAAAAAAAAAAgAAAAQAAAATAAAAcxIAAAB0AGoBfACIAIgBgwN9AXwBUwApAU4pAtoWQ2hhcmFj\ndGVyTGV2ZWxDbm5Nb2RlbNoUX2NoYXJfZW5jb2RpbmdfbGF5ZXIpAtoJaW5wdXRfc3RyWg5jaGFy\nX2luX3ZlY3RvcikC2hRtYXhfY2hhcl9lbmNvZGluZ19pZNoKbWF4X2xlbmd0aKkA+lMvaG9tZS91\nYnVudHUvbmV3LWRwL0RhdGFQcm9maWxlci9kYXRhcHJvZmlsZXIvbGFiZWxlcnMvY2hhcmFjdGVy\nX2xldmVsX2Nubl9tb2RlbC5wedoRZW5jb2RpbmdfZnVuY3Rpb25TAgAAcwYAAAAAAQQBCgE=\n", null, {"class_name": "__tuple__", "items": [127, 3400]}]}, "function_type": "lambda", "module": "dataprofiler.labelers.character_level_cnn_model", "output_shape": {"class_name": "__tuple__", "items": [3400]}, "output_shape_type": "raw", "output_shape_module": null, "arguments": {}}, "name": "lambda", "inbound_nodes": [[["input_1", 0, 0, {}]]]}, {"class_name": "Embedding", "config": {"name": "embedding", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "dtype": "float32", "input_dim": 129, "output_dim": 64, "embeddings_initializer": {"class_name": "RandomUniform", "config": {"minval": -0.05, "maxval": 0.05, "seed": null}}, "embeddings_regularizer": null, "activity_regularizer": null, "embeddings_constraint": null, "mask_zero": false, "input_length": 3400}, "name": "embedding", "inbound_nodes": [[["lambda", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d", "inbound_nodes": [[["embedding", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout", "inbound_nodes": [[["conv1d", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization", "inbound_nodes": [[["dropout", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_1", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_1", "inbound_nodes": [[["batch_normalization", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_1", "inbound_nodes": [[["conv1d_1", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_1", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_1", "inbound_nodes": [[["dropout_1", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_2", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_2", "inbound_nodes": [[["batch_normalization_1", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_2", "inbound_nodes": [[["conv1d_2", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_2", "inbound_nodes": [[["dropout_2", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_3", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_3", "inbound_nodes": [[["batch_normalization_2", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_3", "inbound_nodes": [[["conv1d_3", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_3", "inbound_nodes": [[["dropout_3", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense", "inbound_nodes": [[["batch_normalization_3", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_4", "inbound_nodes": [[["dense", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_1", "inbound_nodes": [[["dropout_4", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_5", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_5", "inbound_nodes": [[["dense_1", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 24, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_2", "inbound_nodes": [[["dropout_5", 0, 0, {}]]]}, {"class_name": "TensorFlowOpLayer", "config": {"name": "ArgMax", "trainable": true, "dtype": "float32", "node_def": {"name": "ArgMax", "op": "ArgMax", "input": ["dense_2/truediv", "ArgMax/dimension"], "attr": {"Tidx": {"type": "DT_INT32"}, "output_type": {"type": "DT_INT64"}, "T": {"type": "DT_FLOAT"}}}, "constants": {"1": -1}}, "name": "tf_op_layer_ArgMax", "inbound_nodes": [[["dense_2", 0, 0, {}]]]}, {"class_name": "ThreshArgMaxLayer", "config": {"layer was saved without config": true}, "name": "thresh_arg_max_layer", "inbound_nodes": [[["tf_op_layer_ArgMax", 0, 0, {"confidence_layer": ["dense_2", 0, 0]}]]]}], "input_layers": [["input_1", 0, 0]], "output_layers": [["dense_2", 0, 0], ["tf_op_layer_ArgMax", 0, 0], ["thresh_arg_max_layer", 0, 0]]}, "shared_object_id": 52, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, null]}, "ndim": 2, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, null]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, null]}, "string", "input_1"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, null]}, "string", "input_1"]}, "keras_version": "2.6.0", "backend": "tensorflow", "model_config": {"class_name": "Functional"}, "training_config": {"loss": {"dense_2": "categorical_crossentropy"}, "metrics": [[{"class_name": "MeanMetricWrapper", "config": {"name": "acc", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 54}, {"class_name": "Custom>F1Score", "config": {"name": "dense_2_f1_score", "dtype": "float32", "num_classes": 24, "average": "micro", "threshold": null}, "shared_object_id": 55}], [null], [null]], "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2 - root.layer-0"_tf_keras_input_layer*{"class_name": "InputLayer", "name": "input_1", "dtype": "string", "sparse": false, "ragged": false, "batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "dtype": "string", "sparse": false, "ragged": false, "name": "input_1"}}2 - root.layer-1"_tf_keras_layer*{"name": "lambda", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Lambda", "config": {"name": "lambda", "trainable": true, "dtype": "float32", "function": {"class_name": "__tuple__", "items": ["4wEAAAAAAAAAAgAAAAQAAAATAAAAcxIAAAB0AGoBfACIAIgBgwN9AXwBUwApAU4pAtoWQ2hhcmFj\ndGVyTGV2ZWxDbm5Nb2RlbNoUX2NoYXJfZW5jb2RpbmdfbGF5ZXIpAtoJaW5wdXRfc3RyWg5jaGFy\nX2luX3ZlY3RvcikC2hRtYXhfY2hhcl9lbmNvZGluZ19pZNoKbWF4X2xlbmd0aKkA+lMvaG9tZS91\nYnVudHUvbmV3LWRwL0RhdGFQcm9maWxlci9kYXRhcHJvZmlsZXIvbGFiZWxlcnMvY2hhcmFjdGVy\nX2xldmVsX2Nubl9tb2RlbC5wedoRZW5jb2RpbmdfZnVuY3Rpb25TAgAAcwYAAAAAAQQBCgE=\n", null, {"class_name": "__tuple__", "items": [127, 3400]}]}, "function_type": "lambda", "module": "dataprofiler.labelers.character_level_cnn_model", "output_shape": {"class_name": "__tuple__", "items": [3400]}, "output_shape_type": "raw", "output_shape_module": null, "arguments": {}}, "inbound_nodes": [[["input_1", 0, 0, {}]]], "shared_object_id": 1}2 -root.layer_with_weights-0"_tf_keras_layer*{"name": "embedding", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "stateful": false, "must_restore_from_config": false, "class_name": "Embedding", "config": {"name": "embedding", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "dtype": "float32", "input_dim": 129, "output_dim": 64, "embeddings_initializer": {"class_name": "RandomUniform", "config": {"minval": -0.05, "maxval": 0.05, "seed": null}, "shared_object_id": 2}, "embeddings_regularizer": null, "activity_regularizer": null, "embeddings_constraint": null, "mask_zero": false, "input_length": 3400}, "inbound_nodes": [[["lambda", 0, 0, {}]]], "shared_object_id": 3, "build_input_shape": {"class_name": "TensorShape", "items": [null, null]}}2 - root.layer_with_weights-1"_tf_keras_layer* {"name": "conv1d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["embedding", 0, 0, {}]]], "shared_object_id": 6, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 64}}, "shared_object_id": 56}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 64]}}2 - root.layer-4"_tf_keras_layer*{"name": "dropout", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d", 0, 0, {}]]], "shared_object_id": 7}2 - root.layer_with_weights-2"_tf_keras_layer* {"name": "batch_normalization", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 9}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 11}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout", 0, 0, {}]]], "shared_object_id": 12, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 57}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer_with_weights-3"_tf_keras_layer* {"name": "conv1d_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_1", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 13}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 14}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization", 0, 0, {}]]], "shared_object_id": 15, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 58}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-7"_tf_keras_layer*{"name": "dropout_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_1", 0, 0, {}]]], "shared_object_id": 16}2 -  root.layer_with_weights-4"_tf_keras_layer* {"name": "batch_normalization_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_1", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 17}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 18}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 19}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 20}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_1", 0, 0, {}]]], "shared_object_id": 21, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 59}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  -root.layer_with_weights-5"_tf_keras_layer* {"name": "conv1d_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_2", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 22}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 23}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_1", 0, 0, {}]]], "shared_object_id": 24, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 60}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  root.layer-10"_tf_keras_layer*{"name": "dropout_2", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_2", 0, 0, {}]]], "shared_object_id": 25}2 -  root.layer_with_weights-6"_tf_keras_layer* {"name": "batch_normalization_2", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 26}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 27}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 28}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 29}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_2", 0, 0, {}]]], "shared_object_id": 30, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 61}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  root.layer_with_weights-7"_tf_keras_layer* {"name": "conv1d_3", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_3", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 31}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 32}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_2", 0, 0, {}]]], "shared_object_id": 33, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 62}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-13"_tf_keras_layer*{"name": "dropout_3", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_3", 0, 0, {}]]], "shared_object_id": 34}2 - root.layer_with_weights-8"_tf_keras_layer* {"name": "batch_normalization_3", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 35}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 36}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 37}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 38}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_3", 0, 0, {}]]], "shared_object_id": 39, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 63}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -root.layer_with_weights-9"_tf_keras_layer*{"name": "dense", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 40}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 41}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_3", 0, 0, {}]]], "shared_object_id": 42, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 48}}, "shared_object_id": 64}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-16"_tf_keras_layer*{"name": "dropout_4", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["dense", 0, 0, {}]]], "shared_object_id": 43}2 -root.layer_with_weights-10"_tf_keras_layer*{"name": "dense_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 44}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 45}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["dropout_4", 0, 0, {}]]], "shared_object_id": 46, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 96}}, "shared_object_id": 65}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 96]}}2 - root.layer-18"_tf_keras_layer*{"name": "dropout_5", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_5", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["dense_1", 0, 0, {}]]], "shared_object_id": 47}2 -root.layer_with_weights-11"_tf_keras_layer*{"name": "dense_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 24, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 48}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 49}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["dropout_5", 0, 0, {}]]], "shared_object_id": 50, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 96}}, "shared_object_id": 66}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 96]}}2 - root.layer-20"_tf_keras_layer*{"name": "tf_op_layer_ArgMax", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "class_name": "TensorFlowOpLayer", "config": {"name": "ArgMax", "trainable": true, "dtype": "float32", "node_def": {"name": "ArgMax", "op": "ArgMax", "input": ["dense_2/truediv", "ArgMax/dimension"], "attr": {"Tidx": {"type": "DT_INT32"}, "output_type": {"type": "DT_INT64"}, "T": {"type": "DT_FLOAT"}}}, "constants": {"1": -1}}, "inbound_nodes": [[["dense_2", 0, 0, {}]]], "shared_object_id": 51}2 -root.layer_with_weights-12"_tf_keras_layer*{"name": "thresh_arg_max_layer", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ThreshArgMaxLayer", "config": {"layer was saved without config": true}}2 -root.keras_api.metrics.0"_tf_keras_metric*{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 67}2 -root.keras_api.metrics.1"_tf_keras_metric*{"class_name": "Mean", "name": "dense_2_loss", "dtype": "float32", "config": {"name": "dense_2_loss", "dtype": "float32"}, "shared_object_id": 68}2 -root.keras_api.metrics.2"_tf_keras_metric*{"class_name": "MeanMetricWrapper", "name": "acc", "dtype": "float32", "config": {"name": "acc", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 54}2 -root.keras_api.metrics.3"_tf_keras_metric*{"class_name": "Custom>F1Score", "name": "dense_2_f1_score", "dtype": "float32", "config": {"name": "dense_2_f1_score", "dtype": "float32", "num_classes": 24, "average": "micro", "threshold": null}, "shared_object_id": 55}2 \ No newline at end of file diff --git a/resources/labelers/structured_model/variables/variables.data-00000-of-00001 b/resources/labelers/structured_model/model.keras similarity index 88% rename from resources/labelers/structured_model/variables/variables.data-00000-of-00001 rename to resources/labelers/structured_model/model.keras index 95732bf16a505547c7a91a728e53951fa1f4d850..795d637da084c50f855834c4acf639ee783b2bc6 100644 GIT binary patch delta 32333 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

dy%rca-OGR){~0>` zXBOdSlHD)#GH{m6fY4>9q{~IFF3+w6(AzbD7+G9|NCNZ@FQ9kIfVeKtsf6+p4Q28! zPME<5D0bMpy_A>Al!Y$Ob#-~3t4p%XRpt4`s$8y8h0 zRJl5@O2+r)8dsMWR3gy}b$~9?1G?A?=sgY~#+@qH^nfy6Kv@|OS7oje${TFLtn}49s;9isOL>z_`8n=lFLzbBxuD7`Tvcuvw#{cXgaCU zie?ct+R&UwjdnE4sL_FDH8mEPwRqPCaLB49eQ0B5Eh83g;^-Jc+l)4iwgv5Gw5@2b zK-*^4akmhNwc`dZArR}p4R%Bzwg5NS4FMdp>IjS>fKyZ*fguFqaiD*#400ZS3h1ZW z&`-0WgAooLjBw~+ghO8javb{kXaSupN6V3~M$3_N);My`8b{7KYeUAi~^gl=zmQ+IcgJ3_GN%dxNX8s@&FwT=>dQ~<9AJQ@4;y+Hkk)!0pe)t)w^qd(YACVb& zD$jt7|7i(-AMG*2t2$RK>0GpQabi{H((c8y(LIzlId^Oz8#&e1j5oF9ju^-`ozmIW zwPMMl?ykivo4iZH!s}q5VrxpbLg)L+iVO!{rqXJZJmV)bQt5d(L_R8uY`;Qe>|>J5 zE}*MRWLDohoF0w!HQ9&gNSi`dvHXvIa_XilOO_5{X~x&)hw?~^a%KLL-?~+181jct z$FPb-Y+GamG+9XNB>%MDXkHi_gzq*bBuxc!@- z%6sVA5>uMN*InMk6B$ZFii@B8Rvn?~l2vE%RTE88QY3Pk60lIP#bKgm2f-u=Ema?8JLq|%`9>-TL@3~qWzrz#0e%88~ZYrU1Jf~5a=W^*(?zs^2 z^PPdii{rWEo*EniY|pja^<3X7YiXKHW|Vx}*U*17GL48oTm=l``mRJ95|6 zxWW#tlu=jP5&N#jwQ<=sDZ{QddBl-8uSVt)ar}}p?s5q^qx^{3aaW(cJFJ5Dl6z{9 zlHlHpAtm9&T|X~tZKcV3kt&apU-%lEPiCKaQu`tDOWE2EDXi^RlCk-DFDJB8#$D~M z_hR~UwO`z22UkjqYp>9I4GH})q=4MG%kHv!g!lS&S&fY7QXaqY)rec#V5PNxPi-Sa zek*I_cM6UCUebuid;Os-`VEvRQ?F6-k}v#9>mwm@SVsTHQuK4lpFHr@-s|O! zq|OWL`ovuwN9en-YWcXUxzQsl6z{98@1!Et=w}VFFl+5 zxvZsWN>x$vvX7zp7qXbQk`*F(gl2?6I;@0p= zzgsG<;f2WGWtIFxp^|?}Dsh~bVBlY68DP3XUzGgYmjiVfP*nvCk^jgHyyjtm*%|Zy zN*t(Oh+(1mLLQ=Bk=BXLm+VSsR>ki_#`D>>$vSxmRXPo8m(QSbD?&j-m=@|8u4Q@q zgkt{ZD26493K{u2zzm|RbVkXxfWDCNddi?7vOU10TE>+DyOtp*Qm?}2qs65R!NHDz zrV`^aFs7;GMak6#23W~AeUaBuNez)}0ulo|6%1S}F`%$4M)RiS9u$?P&hzTen~ORN{Dw_J_NqLpc#c? z_WD#{y`|(3xj|OUjS9uwBou>lANK&Ey5-z=n2+*evXBFgP62z3Np?I^&BKuz zeAz9E$+h+xb@m#>E+z-KNecyW4Gqx5BBRbt$qc?=4wHw9mSPWk*0R4G!K73=l}lvTB}XiLKl@04hI5$> zR$^p0o64m|@u^WGc{D&9`jdlMZ|}IG#ErIIJcM(;aD96eMRa9fIn~ySV#F{j0F!!qh`yH3(1J;-4!)tq5K9p?W?Z7vJ zpYWJ+MFCbNn7EFQ0vqWDDDf!$GlREFsK5?+*>I&!v(AJz5;xux2QC4cY0 b@dz!#*FcN41l~owci>O(-r?KK<30WlFQW29 diff --git a/resources/labelers/structured_model/saved_model.pb b/resources/labelers/structured_model/saved_model.pb deleted file mode 100644 index 76274cae0f961b72df8dc3cd055b56e60f3de2b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544918 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 diff --git a/resources/labelers/structured_model/variables/variables.index b/resources/labelers/structured_model/variables/variables.index deleted file mode 100644 index 627e9a5776c6bef4df06e87785049587a60eab50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2660 zcmbW1ZAcVB7{}-CEZ1JRx?9CeW4G&SrI$TVH!FfV{NnkU3Jt|_q4lJi6Ew+ zHxx07vZ62u34(|sD2Ui1$qz+FekkmN^hQxc7?n{`vr}weqML1DcVXf8{O9@2vjf0n z#*yJ<93XRsTv!w?EGgSiygm{tC=JUS3f6`TBl4Q^P+1X^>;c@X&win=MLNCm#eR_I zZiX=>E-P)Ss6joZ*2cwvSlikj)x{;DNTj^Dpdu39BvyvXi%GT0P-#V&ao{qyahW7( zVCT#gEa%o+b)_W{VOWG`t~-Y=<*vohrVLpGP6^Vbj93h9%CJRv7P)i9dZi@})2V{tkcK*&XQ%R6czmNU!Q@TD+;lVW7r)0Tps^IGbGRvs<=Fsba5aa{ z`vv5Znnw2C2l=!9;vgp=(kzF;%cwSQ4t4ni)bErgE??_qc`vPlbPj#;3)Rxeduo0f zpKd1;qZe=&MG{;;uz+3Q4T^eW48|Mf4p{r|5isSab7Lg3ebt?s7S$UVQu?z{kH!3idVyQ~6o6$GCY`V0MBRP_IMEp7LZXz*n0K zfShCi@CyKSOZOG??Jyt4_?e5q;nF}4YkfO7K7&8ZGX1RE{Pgdu>MQD+*S==-C*`u& Af&c&j diff --git a/resources/labelers/unstructured_model/keras_metadata.pb b/resources/labelers/unstructured_model/keras_metadata.pb deleted file mode 100644 index dcc84a213..000000000 --- a/resources/labelers/unstructured_model/keras_metadata.pb +++ /dev/null @@ -1,29 +0,0 @@ - -`root"_tf_keras_network*`{"name": "functional_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "must_restore_from_config": false, "class_name": "Functional", "config": {"name": "functional_1", "layers": [{"class_name": "InputLayer", "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "dtype": "string", "sparse": false, "ragged": false, "name": "input_1"}, "name": "input_1", "inbound_nodes": []}, {"class_name": "Lambda", "config": {"name": "lambda", "trainable": true, "dtype": "float32", "function": {"class_name": "__tuple__", "items": ["4wEAAAAAAAAAAgAAAAQAAAATAAAAcxIAAAB0AGoBfACIAIgBgwN9AXwBUwApAU4pAtoWQ2hhcmFj\ndGVyTGV2ZWxDbm5Nb2RlbNoUX2NoYXJfZW5jb2RpbmdfbGF5ZXIpAtoJaW5wdXRfc3RyWg5jaGFy\nX2luX3ZlY3RvcikC2hRtYXhfY2hhcl9lbmNvZGluZ19pZNoKbWF4X2xlbmd0aKkA+lMvaG9tZS91\nYnVudHUvbmV3LWRwL0RhdGFQcm9maWxlci9kYXRhcHJvZmlsZXIvbGFiZWxlcnMvY2hhcmFjdGVy\nX2xldmVsX2Nubl9tb2RlbC5wedoRZW5jb2RpbmdfZnVuY3Rpb25TAgAAcwYAAAAAAQQBCgE=\n", null, {"class_name": "__tuple__", "items": [127, 3400]}]}, "function_type": "lambda", "module": "dataprofiler.labelers.character_level_cnn_model", "output_shape": {"class_name": "__tuple__", "items": [3400]}, "output_shape_type": "raw", "output_shape_module": null, "arguments": {}}, "name": "lambda", "inbound_nodes": [[["input_1", 0, 0, {}]]]}, {"class_name": "Embedding", "config": {"name": "embedding", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "dtype": "float32", "input_dim": 129, "output_dim": 64, "embeddings_initializer": {"class_name": "RandomUniform", "config": {"minval": -0.05, "maxval": 0.05, "seed": null}}, "embeddings_regularizer": null, "activity_regularizer": null, "embeddings_constraint": null, "mask_zero": false, "input_length": 3400}, "name": "embedding", "inbound_nodes": [[["lambda", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d", "inbound_nodes": [[["embedding", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout", "inbound_nodes": [[["conv1d", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization", "inbound_nodes": [[["dropout", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_1", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_1", "inbound_nodes": [[["batch_normalization", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_1", "inbound_nodes": [[["conv1d_1", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_1", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_1", "inbound_nodes": [[["dropout_1", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_2", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_2", "inbound_nodes": [[["batch_normalization_1", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_2", "inbound_nodes": [[["conv1d_2", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_2", "inbound_nodes": [[["dropout_2", 0, 0, {}]]]}, {"class_name": "Conv1D", "config": {"name": "conv1d_3", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "conv1d_3", "inbound_nodes": [[["batch_normalization_2", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_3", "inbound_nodes": [[["conv1d_3", 0, 0, {}]]]}, {"class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}}, "gamma_initializer": {"class_name": "Ones", "config": {}}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}}, "moving_variance_initializer": {"class_name": "Ones", "config": {}}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "name": "batch_normalization_3", "inbound_nodes": [[["dropout_3", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense", "inbound_nodes": [[["batch_normalization_3", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_4", "inbound_nodes": [[["dense", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_1", "inbound_nodes": [[["dropout_4", 0, 0, {}]]]}, {"class_name": "Dropout", "config": {"name": "dropout_5", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "name": "dropout_5", "inbound_nodes": [[["dense_1", 0, 0, {}]]]}, {"class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 24, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}}, "bias_initializer": {"class_name": "Zeros", "config": {}}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "name": "dense_2", "inbound_nodes": [[["dropout_5", 0, 0, {}]]]}, {"class_name": "TensorFlowOpLayer", "config": {"name": "ArgMax", "trainable": true, "dtype": "float32", "node_def": {"name": "ArgMax", "op": "ArgMax", "input": ["dense_2/truediv", "ArgMax/dimension"], "attr": {"Tidx": {"type": "DT_INT32"}, "output_type": {"type": "DT_INT64"}, "T": {"type": "DT_FLOAT"}}}, "constants": {"1": -1}}, "name": "tf_op_layer_ArgMax", "inbound_nodes": [[["dense_2", 0, 0, {}]]]}, {"class_name": "ThreshArgMaxLayer", "config": {"layer was saved without config": true}, "name": "thresh_arg_max_layer", "inbound_nodes": [[["tf_op_layer_ArgMax", 0, 0, {"confidence_layer": ["dense_2", 0, 0]}]]]}], "input_layers": [["input_1", 0, 0]], "output_layers": [["dense_2", 0, 0], ["tf_op_layer_ArgMax", 0, 0], ["thresh_arg_max_layer", 0, 0]]}, "shared_object_id": 52, "input_spec": [{"class_name": "InputSpec", "config": {"dtype": null, "shape": {"class_name": "__tuple__", "items": [null, null]}, "ndim": 2, "max_ndim": null, "min_ndim": null, "axes": {}}}], "build_input_shape": {"class_name": "TensorShape", "items": [null, null]}, "is_graph_network": true, "full_save_spec": {"class_name": "__tuple__", "items": [[{"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, null]}, "string", "input_1"]}], {}]}, "save_spec": {"class_name": "TypeSpec", "type_spec": "tf.TensorSpec", "serialized": [{"class_name": "TensorShape", "items": [null, null]}, "string", "input_1"]}, "keras_version": "2.6.0", "backend": "tensorflow", "model_config": {"class_name": "Functional"}, "training_config": {"loss": {"dense_2": "categorical_crossentropy"}, "metrics": [[{"class_name": "MeanMetricWrapper", "config": {"name": "acc", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 54}, {"class_name": "Custom>F1Score", "config": {"name": "dense_2_f1_score", "dtype": "float32", "num_classes": 24, "average": "micro", "threshold": null}, "shared_object_id": 55}], [null], [null]], "weighted_metrics": null, "loss_weights": null, "optimizer_config": {"class_name": "Adam", "config": {"name": "Adam", "learning_rate": 0.0010000000474974513, "decay": 0.0, "beta_1": 0.8999999761581421, "beta_2": 0.9990000128746033, "epsilon": 1e-07, "amsgrad": false}}}}2 - root.layer-0"_tf_keras_input_layer*{"class_name": "InputLayer", "name": "input_1", "dtype": "string", "sparse": false, "ragged": false, "batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "config": {"batch_input_shape": {"class_name": "__tuple__", "items": [null, null]}, "dtype": "string", "sparse": false, "ragged": false, "name": "input_1"}}2 - root.layer-1"_tf_keras_layer*{"name": "lambda", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Lambda", "config": {"name": "lambda", "trainable": true, "dtype": "float32", "function": {"class_name": "__tuple__", "items": ["4wEAAAAAAAAAAgAAAAQAAAATAAAAcxIAAAB0AGoBfACIAIgBgwN9AXwBUwApAU4pAtoWQ2hhcmFj\ndGVyTGV2ZWxDbm5Nb2RlbNoUX2NoYXJfZW5jb2RpbmdfbGF5ZXIpAtoJaW5wdXRfc3RyWg5jaGFy\nX2luX3ZlY3RvcikC2hRtYXhfY2hhcl9lbmNvZGluZ19pZNoKbWF4X2xlbmd0aKkA+lMvaG9tZS91\nYnVudHUvbmV3LWRwL0RhdGFQcm9maWxlci9kYXRhcHJvZmlsZXIvbGFiZWxlcnMvY2hhcmFjdGVy\nX2xldmVsX2Nubl9tb2RlbC5wedoRZW5jb2RpbmdfZnVuY3Rpb25TAgAAcwYAAAAAAQQBCgE=\n", null, {"class_name": "__tuple__", "items": [127, 3400]}]}, "function_type": "lambda", "module": "dataprofiler.labelers.character_level_cnn_model", "output_shape": {"class_name": "__tuple__", "items": [3400]}, "output_shape_type": "raw", "output_shape_module": null, "arguments": {}}, "inbound_nodes": [[["input_1", 0, 0, {}]]], "shared_object_id": 1}2 -root.layer_with_weights-0"_tf_keras_layer*{"name": "embedding", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "stateful": false, "must_restore_from_config": false, "class_name": "Embedding", "config": {"name": "embedding", "trainable": true, "batch_input_shape": {"class_name": "__tuple__", "items": [null, 3400]}, "dtype": "float32", "input_dim": 129, "output_dim": 64, "embeddings_initializer": {"class_name": "RandomUniform", "config": {"minval": -0.05, "maxval": 0.05, "seed": null}, "shared_object_id": 2}, "embeddings_regularizer": null, "activity_regularizer": null, "embeddings_constraint": null, "mask_zero": false, "input_length": 3400}, "inbound_nodes": [[["lambda", 0, 0, {}]]], "shared_object_id": 3, "build_input_shape": {"class_name": "TensorShape", "items": [null, null]}}2 - root.layer_with_weights-1"_tf_keras_layer* {"name": "conv1d", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 4}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 5}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["embedding", 0, 0, {}]]], "shared_object_id": 6, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 64}}, "shared_object_id": 56}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 64]}}2 - root.layer-4"_tf_keras_layer*{"name": "dropout", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d", 0, 0, {}]]], "shared_object_id": 7}2 - root.layer_with_weights-2"_tf_keras_layer* {"name": "batch_normalization", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 8}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 9}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 10}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 11}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout", 0, 0, {}]]], "shared_object_id": 12, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 57}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer_with_weights-3"_tf_keras_layer* {"name": "conv1d_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_1", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 13}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 14}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization", 0, 0, {}]]], "shared_object_id": 15, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 58}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-7"_tf_keras_layer*{"name": "dropout_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_1", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_1", 0, 0, {}]]], "shared_object_id": 16}2 -  root.layer_with_weights-4"_tf_keras_layer* {"name": "batch_normalization_1", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_1", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 17}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 18}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 19}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 20}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_1", 0, 0, {}]]], "shared_object_id": 21, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 59}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  -root.layer_with_weights-5"_tf_keras_layer* {"name": "conv1d_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_2", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 22}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 23}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_1", 0, 0, {}]]], "shared_object_id": 24, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 60}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  root.layer-10"_tf_keras_layer*{"name": "dropout_2", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_2", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_2", 0, 0, {}]]], "shared_object_id": 25}2 -  root.layer_with_weights-6"_tf_keras_layer* {"name": "batch_normalization_2", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_2", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 26}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 27}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 28}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 29}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_2", 0, 0, {}]]], "shared_object_id": 30, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 61}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -  root.layer_with_weights-7"_tf_keras_layer* {"name": "conv1d_3", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Conv1D", "config": {"name": "conv1d_3", "trainable": true, "dtype": "float32", "filters": 48, "kernel_size": {"class_name": "__tuple__", "items": [13]}, "strides": {"class_name": "__tuple__", "items": [1]}, "padding": "same", "data_format": "channels_last", "dilation_rate": {"class_name": "__tuple__", "items": [1]}, "groups": 1, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 31}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 32}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_2", 0, 0, {}]]], "shared_object_id": 33, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 3, "axes": {"-1": 48}}, "shared_object_id": 62}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-13"_tf_keras_layer*{"name": "dropout_3", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_3", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["conv1d_3", 0, 0, {}]]], "shared_object_id": 34}2 - root.layer_with_weights-8"_tf_keras_layer* {"name": "batch_normalization_3", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "BatchNormalization", "config": {"name": "batch_normalization_3", "trainable": true, "dtype": "float32", "axis": [2], "momentum": 0.99, "epsilon": 0.001, "center": true, "scale": true, "beta_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 35}, "gamma_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 36}, "moving_mean_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 37}, "moving_variance_initializer": {"class_name": "Ones", "config": {}, "shared_object_id": 38}, "beta_regularizer": null, "gamma_regularizer": null, "beta_constraint": null, "gamma_constraint": null}, "inbound_nodes": [[["dropout_3", 0, 0, {}]]], "shared_object_id": 39, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": 3, "max_ndim": null, "min_ndim": null, "axes": {"2": 48}}, "shared_object_id": 63}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 -root.layer_with_weights-9"_tf_keras_layer*{"name": "dense", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 40}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 41}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["batch_normalization_3", 0, 0, {}]]], "shared_object_id": 42, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 48}}, "shared_object_id": 64}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 48]}}2 - root.layer-16"_tf_keras_layer*{"name": "dropout_4", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_4", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["dense", 0, 0, {}]]], "shared_object_id": 43}2 -root.layer_with_weights-10"_tf_keras_layer*{"name": "dense_1", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_1", "trainable": true, "dtype": "float32", "units": 96, "activation": "relu", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 44}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 45}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["dropout_4", 0, 0, {}]]], "shared_object_id": 46, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 96}}, "shared_object_id": 65}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 96]}}2 - root.layer-18"_tf_keras_layer*{"name": "dropout_5", "trainable": true, "expects_training_arg": true, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dropout", "config": {"name": "dropout_5", "trainable": true, "dtype": "float32", "rate": 0.073, "noise_shape": null, "seed": null}, "inbound_nodes": [[["dense_1", 0, 0, {}]]], "shared_object_id": 47}2 -root.layer_with_weights-11"_tf_keras_layer*{"name": "dense_2", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "Dense", "config": {"name": "dense_2", "trainable": true, "dtype": "float32", "units": 24, "activation": "softmax", "use_bias": true, "kernel_initializer": {"class_name": "GlorotUniform", "config": {"seed": null}, "shared_object_id": 48}, "bias_initializer": {"class_name": "Zeros", "config": {}, "shared_object_id": 49}, "kernel_regularizer": null, "bias_regularizer": null, "activity_regularizer": null, "kernel_constraint": null, "bias_constraint": null}, "inbound_nodes": [[["dropout_5", 0, 0, {}]]], "shared_object_id": 50, "input_spec": {"class_name": "InputSpec", "config": {"dtype": null, "shape": null, "ndim": null, "max_ndim": null, "min_ndim": 2, "axes": {"-1": 96}}, "shared_object_id": 66}, "build_input_shape": {"class_name": "TensorShape", "items": [null, null, 96]}}2 - root.layer-20"_tf_keras_layer*{"name": "tf_op_layer_ArgMax", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": true, "class_name": "TensorFlowOpLayer", "config": {"name": "ArgMax", "trainable": true, "dtype": "float32", "node_def": {"name": "ArgMax", "op": "ArgMax", "input": ["dense_2/truediv", "ArgMax/dimension"], "attr": {"Tidx": {"type": "DT_INT32"}, "output_type": {"type": "DT_INT64"}, "T": {"type": "DT_FLOAT"}}}, "constants": {"1": -1}}, "inbound_nodes": [[["dense_2", 0, 0, {}]]], "shared_object_id": 51}2 -root.layer_with_weights-12"_tf_keras_layer*{"name": "thresh_arg_max_layer", "trainable": true, "expects_training_arg": false, "dtype": "float32", "batch_input_shape": null, "stateful": false, "must_restore_from_config": false, "class_name": "ThreshArgMaxLayer", "config": {"layer was saved without config": true}}2 -root.keras_api.metrics.0"_tf_keras_metric*{"class_name": "Mean", "name": "loss", "dtype": "float32", "config": {"name": "loss", "dtype": "float32"}, "shared_object_id": 67}2 -root.keras_api.metrics.1"_tf_keras_metric*{"class_name": "Mean", "name": "dense_2_loss", "dtype": "float32", "config": {"name": "dense_2_loss", "dtype": "float32"}, "shared_object_id": 68}2 -root.keras_api.metrics.2"_tf_keras_metric*{"class_name": "MeanMetricWrapper", "name": "acc", "dtype": "float32", "config": {"name": "acc", "dtype": "float32", "fn": "categorical_accuracy"}, "shared_object_id": 54}2 -root.keras_api.metrics.3"_tf_keras_metric*{"class_name": "Custom>F1Score", "name": "dense_2_f1_score", "dtype": "float32", "config": {"name": "dense_2_f1_score", "dtype": "float32", "num_classes": 24, "average": "micro", "threshold": null}, "shared_object_id": 55}2 \ No newline at end of file diff --git a/resources/labelers/unstructured_model/variables/variables.data-00000-of-00001 b/resources/labelers/unstructured_model/model.keras similarity index 88% rename from resources/labelers/unstructured_model/variables/variables.data-00000-of-00001 rename to resources/labelers/unstructured_model/model.keras index 95732bf16a505547c7a91a728e53951fa1f4d850..795d637da084c50f855834c4acf639ee783b2bc6 100644 GIT binary patch delta 32333 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

dy%rca-OGR){~0>` zXBOdSlHD)#GH{m6fY4>9q{~IFF3+w6(AzbD7+G9|NCNZ@FQ9kIfVeKtsf6+p4Q28! zPME<5D0bMpy_A>Al!Y$Ob#-~3t4p%XRpt4`s$8y8h0 zRJl5@O2+r)8dsMWR3gy}b$~9?1G?A?=sgY~#+@qH^nfy6Kv@|OS7oje${TFLtn}49s;9isOL>z_`8n=lFLzbBxuD7`Tvcuvw#{cXgaCU zie?ct+R&UwjdnE4sL_FDH8mEPwRqPCaLB49eQ0B5Eh83g;^-Jc+l)4iwgv5Gw5@2b zK-*^4akmhNwc`dZArR}p4R%Bzwg5NS4FMdp>IjS>fKyZ*fguFqaiD*#400ZS3h1ZW z&`-0WgAooLjBw~+ghO8javb{kXaSupN6V3~M$3_N);My`8b{7KYeUAi~^gl=zmQ+IcgJ3_GN%dxNX8s@&FwT=>dQ~<9AJQ@4;y+Hkk)!0pe)t)w^qd(YACVb& zD$jt7|7i(-AMG*2t2$RK>0GpQabi{H((c8y(LIzlId^Oz8#&e1j5oF9ju^-`ozmIW zwPMMl?ykivo4iZH!s}q5VrxpbLg)L+iVO!{rqXJZJmV)bQt5d(L_R8uY`;Qe>|>J5 zE}*MRWLDohoF0w!HQ9&gNSi`dvHXvIa_XilOO_5{X~x&)hw?~^a%KLL-?~+181jct z$FPb-Y+GamG+9XNB>%MDXkHi_gzq*bBuxc!@- z%6sVA5>uMN*InMk6B$ZFii@B8Rvn?~l2vE%RTE88QY3Pk60lIP#bKgm2f-u=Ema?8JLq|%`9>-TL@3~qWzrz#0e%88~ZYrU1Jf~5a=W^*(?zs^2 z^PPdii{rWEo*EniY|pja^<3X7YiXKHW|Vx}*U*17GL48oTm=l``mRJ95|6 zxWW#tlu=jP5&N#jwQ<=sDZ{QddBl-8uSVt)ar}}p?s5q^qx^{3aaW(cJFJ5Dl6z{9 zlHlHpAtm9&T|X~tZKcV3kt&apU-%lEPiCKaQu`tDOWE2EDXi^RlCk-DFDJB8#$D~M z_hR~UwO`z22UkjqYp>9I4GH})q=4MG%kHv!g!lS&S&fY7QXaqY)rec#V5PNxPi-Sa zek*I_cM6UCUebuid;Os-`VEvRQ?F6-k}v#9>mwm@SVsTHQuK4lpFHr@-s|O! zq|OWL`ovuwN9en-YWcXUxzQsl6z{98@1!Et=w}VFFl+5 zxvZsWN>x$vvX7zp7qXbQk`*F(gl2?6I;@0p= zzgsG<;f2WGWtIFxp^|?}Dsh~bVBlY68DP3XUzGgYmjiVfP*nvCk^jgHyyjtm*%|Zy zN*t(Oh+(1mLLQ=Bk=BXLm+VSsR>ki_#`D>>$vSxmRXPo8m(QSbD?&j-m=@|8u4Q@q zgkt{ZD26493K{u2zzm|RbVkXxfWDCNddi?7vOU10TE>+DyOtp*Qm?}2qs65R!NHDz zrV`^aFs7;GMak6#23W~AeUaBuNez)}0ulo|6%1S}F`%$4M)RiS9u$?P&hzTen~ORN{Dw_J_NqLpc#c? z_WD#{y`|(3xj|OUjS9uwBou>lANK&Ey5-z=n2+*evXBFgP62z3Np?I^&BKuz zeAz9E$+h+xb@m#>E+z-KNecyW4Gqx5BBRbt$qc?=4wHw9mSPWk*0R4G!K73=l}lvTB}XiLKl@04hI5$> zR$^p0o64m|@u^WGc{D&9`jdlMZ|}IG#ErIIJcM(;aD96eMRa9fIn~ySV#F{j0F!!qh`yH3(1J;-4!)tq5K9p?W?Z7vJ zpYWJ+MFCbNn7EFQ0vqWDDDf!$GlREFsK5?+*>I&!v(AJz5;xux2QC4cY0 b@dz!#*FcN41l~owci>O(-r?KK<30WlFQW29 diff --git a/resources/labelers/unstructured_model/saved_model.pb b/resources/labelers/unstructured_model/saved_model.pb deleted file mode 100644 index 76274cae0f961b72df8dc3cd055b56e60f3de2b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544918 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 diff --git a/resources/labelers/unstructured_model/variables/variables.index b/resources/labelers/unstructured_model/variables/variables.index deleted file mode 100644 index 627e9a5776c6bef4df06e87785049587a60eab50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2660 zcmbW1ZAcVB7{}-CEZ1JRx?9CeW4G&SrI$TVH!FfV{NnkU3Jt|_q4lJi6Ew+ zHxx07vZ62u34(|sD2Ui1$qz+FekkmN^hQxc7?n{`vr}weqML1DcVXf8{O9@2vjf0n z#*yJ<93XRsTv!w?EGgSiygm{tC=JUS3f6`TBl4Q^P+1X^>;c@X&win=MLNCm#eR_I zZiX=>E-P)Ss6joZ*2cwvSlikj)x{;DNTj^Dpdu39BvyvXi%GT0P-#V&ao{qyahW7( zVCT#gEa%o+b)_W{VOWG`t~-Y=<*vohrVLpGP6^Vbj93h9%CJRv7P)i9dZi@})2V{tkcK*&XQ%R6czmNU!Q@TD+;lVW7r)0Tps^IGbGRvs<=Fsba5aa{ z`vv5Znnw2C2l=!9;vgp=(kzF;%cwSQ4t4ni)bErgE??_qc`vPlbPj#;3)Rxeduo0f zpKd1;qZe=&MG{;;uz+3Q4T^eW48|Mf4p{r|5isSab7Lg3ebt?s7S$UVQu?z{kH!3idVyQ~6o6$GCY`V0MBRP_IMEp7LZXz*n0K zfShCi@CyKSOZOG??Jyt4_?e5q;nF}4YkfO7K7&8ZGX1RE{Pgdu>MQD+*S==-C*`u& Af&c&j diff --git a/setup.py b/setup.py index f8b5eaf8e..eeca6629b 100644 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ setup( name="DataProfiler", version=__version__, - python_requires=">=3.8", + python_requires=">=3.9", description=DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", diff --git a/tox.ini b/tox.ini index 55fa50147..21d418e98 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py37, py38, py39, py310, docs, pypi-description, manifest, precom +envlist = py39, py310, 311, pypi-description, manifest, precom [testenv] @@ -16,32 +16,37 @@ deps = -rrequirements-reports.txt -rrequirements-test.txt commands = - python3 -m pytest dataprofiler/tests/ --cov=dataprofiler --cov-fail-under=80 --cov-report=xml:dist/coverage.xml --forked + python3 -m pytest dataprofiler/tests/ --cov=dataprofiler --cov-fail-under=80 --cov-report=xml:coverage.xml --forked +# add "docs" to `envlist` to run the docs build #[testenv:docs] #extras = docs #changedir = docs #commands = sphinx-build -b html source _build [testenv:pypi-description] -skip_install = true deps = + {[testenv]deps} twine wheel - pip >= 19.0.0 +skip_install = true commands = python setup.py sdist bdist_wheel twine check dist/* [testenv:manifest] -deps = check-manifest +deps = + {[testenv]deps} + check-manifest skip_install = true commands = check-manifest # skip isort for infinite loop issues between tox and top level settings [testenv:precom] skip_install = true -deps = pre-commit +deps = + {[testenv]deps} + pre-commit commands = pre-commit run black --all-files --verbose # if you use the walrus operator on Python 3.8 disable the flake8 check From 50da93f0bca6b0add053acdafd34e2f48f61fa1b Mon Sep 17 00:00:00 2001 From: armaan-dhillon Date: Mon, 13 Jan 2025 14:28:55 -0500 Subject: [PATCH 02/14] Staging release 0.13.0 (#1165) (#1166) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: Upgrade the models to use keras 3.0 (#1138) * Replace snappy with cramjam (#1091) * add downloads tile (#1085) * Replace snappy with cramjam * Delete test_no_snappy --------- * pre-commit fix (#1122) * Bug fix for float precision calculation using categorical data with trailing zeros. (#1125) * Revert "Bug fix for float precision calculation using categorical data with t…" (#1133) This reverts commit d3159bd13911892e74c264966fba011d50f20e95. * refactor: move layers outside of class * refactor: update model to keras 3.0 * fix: manifest * fix: bugs in compile and train * fix: bug in load_from_library * fix: bugs in CharCNN * refactor: loading tf model labeler * fix: bug in data_labeler identification * fix: update model to use proper softmax layer names * fix: formatting * fix: remove unused line * refactor: drop support for 3.8 * fix: comments * fix: comment --------- * Fix Tox (#1143) * tox new * update * update * update * update * update * update * update * update tox.ini * update * update * remove docs * empty retrigger * update (#1146) * Add Python 3.11 to GHA (#1090) * add downloads tile (#1085) * Add Python 3.11 to GHA * Replace snappy with cramjam (#1091) * add downloads tile (#1085) * Replace snappy with cramjam * Delete test_no_snappy --------- * Update dask modules * Install dask dataframe * Update dask modules in precommit * Correct copy/paste error * Try again to clear Unicode * Rolled back pre-commit dask version * Add py311 to tox * Bump dask to 2024.4.1 * Bump python-snappy 0.7.1 * Rewrite labeler test * Correct isort * Satisfy black * And flake8 * Synced with requirements --------- * [Vuln Fix]: Resolve mend vulnerabilities related to requests. (#1162) * resolved check-manifest issue * updating keras version pin to <=3.4.0 * adding comment in requirements.txt to trigger mend check --------- --------- Co-authored-by: JGSweets Co-authored-by: Gábor Lipták Co-authored-by: Taylor Turner Co-authored-by: James Schadt Co-authored-by: Michael Davis <36012613+micdavis@users.noreply.github.com> --- .pre-commit-config.yaml | 8 ++--- dataprofiler/__init__.py | 16 ---------- dataprofiler/tests/test_data_profiler.py | 40 ------------------------ requirements-dev.txt | 2 +- requirements-ml.txt | 2 +- requirements.txt | 7 +++-- tox.ini | 2 +- 7 files changed, 11 insertions(+), 66 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7baeb59ec..fd1768f0b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -48,14 +48,14 @@ repos: # requirements.txt h5py>=2.10.0, wheel>=0.33.1, - numpy>=1.22.0, + numpy<2.0.0, pandas>=1.1.2, python-dateutil>=2.7.5, pytz>=2020.1, pyarrow>=1.0.1, chardet>=3.0.4, fastavro>=1.0.0.post1, - python-snappy>=0.5.4, + python-snappy>=0.7.1, charset-normalizer>=1.3.6, psutil>=4.0.0, scipy>=1.4.1, @@ -80,7 +80,7 @@ repos: # requirements-ml.txt scikit-learn>=0.23.2, - 'keras>=2.4.3,<3.0.0', + 'keras>=2.4.3,<=3.4.0', rapidfuzz>=2.6.1, "tensorflow>=2.6.4,<2.15.0; sys.platform != 'darwin'", "tensorflow>=2.6.4,<2.15.0; sys_platform == 'darwin' and platform_machine != 'arm64'", @@ -108,7 +108,7 @@ repos: rev: "0.48" hooks: - id: check-manifest - additional_dependencies: ['h5py', 'wheel', 'future', 'numpy', 'pandas', + additional_dependencies: ['h5py', 'wheel', 'future', 'numpy<2.0.0', 'pandas', 'python-dateutil', 'pytz', 'pyarrow', 'chardet', 'fastavro', 'python-snappy', 'charset-normalizer', 'psutil', 'scipy', 'requests', 'networkx','typing-extensions', 'HLL', 'datasketches', 'boto3'] diff --git a/dataprofiler/__init__.py b/dataprofiler/__init__.py index 2e89d3e2b..5f218bd85 100644 --- a/dataprofiler/__init__.py +++ b/dataprofiler/__init__.py @@ -20,22 +20,6 @@ from .validators.base_validators import Validator from .version import __version__ -try: - import snappy -except ImportError: - import warnings - - warnings.warn( - "Snappy must be installed to use parquet/avro datasets." - "\n\n" - "For macOS use Homebrew:\n" - "\t`brew install snappy`" - "\n\n" - "For linux use apt-get:\n`" - "\tsudo apt-get -y install libsnappy-dev`\n", - ImportWarning, - ) - def set_seed(seed=None): # also check it's an integer diff --git a/dataprofiler/tests/test_data_profiler.py b/dataprofiler/tests/test_data_profiler.py index ef7664cea..9ebdfa039 100644 --- a/dataprofiler/tests/test_data_profiler.py +++ b/dataprofiler/tests/test_data_profiler.py @@ -56,46 +56,6 @@ def test_data_profiling(self): self.assertIsNotNone(profile.profile) self.assertIsNotNone(profile.report()) - def test_no_snappy(self): - import importlib - import sys - import types - - orig_import = __import__ - # necessary for any wrapper around the library to test if snappy caught - # as an issue - - def reload_data_profiler(): - """Recursively reload modules.""" - sys_modules = sys.modules.copy() - for module_name, module in sys_modules.items(): - # Only reload top level of the dataprofiler - if "dataprofiler" in module_name and len(module_name.split(".")) < 3: - if isinstance(module, types.ModuleType): - importlib.reload(module) - - def import_mock(name, *args, **kwargs): - if name == "snappy": - raise ImportError("test") - return orig_import(name, *args, **kwargs) - - with mock.patch("builtins.__import__", side_effect=import_mock): - with self.assertWarns(ImportWarning) as w: - import dataprofiler - - reload_data_profiler() - - self.assertEqual( - str(w.warning), - "Snappy must be installed to use parquet/avro datasets." - "\n\n" - "For macOS use Homebrew:\n" - "\t`brew install snappy`" - "\n\n" - "For linux use apt-get:\n`" - "\tsudo apt-get -y install libsnappy-dev`\n", - ) - def test_no_tensorflow(self): import sys diff --git a/requirements-dev.txt b/requirements-dev.txt index f6343283c..8c7c78684 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,4 +1,4 @@ -check-manifest>=0.48 +check-manifest>=0.50 black>=24.3.0 isort==5.12.0 pre-commit==2.19.0 diff --git a/requirements-ml.txt b/requirements-ml.txt index 6da08b313..31f9ca633 100644 --- a/requirements-ml.txt +++ b/requirements-ml.txt @@ -1,5 +1,5 @@ scikit-learn>=0.23.2 -keras>=3.0.0 +keras<=3.4.0 rapidfuzz>=2.6.1 tensorflow>=2.16.0; sys.platform != 'darwin' tensorflow>=2.16.0; sys_platform == 'darwin' and platform_machine != 'arm64' diff --git a/requirements.txt b/requirements.txt index 152b5eb36..3ccc4c6f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,20 +1,21 @@ h5py>=2.10.0 wheel>=0.33.1 -numpy>=1.22.0 +numpy<2.0.0 pandas>=1.1.2 python-dateutil>=2.7.5 pytz>=2020.1 pyarrow>=1.0.1 chardet>=3.0.4 fastavro>=1.1.0 -python-snappy>=0.5.4 +python-snappy>=0.7.1 charset-normalizer>=1.3.6 psutil>=4.0.0 scipy>=1.10.0 -requests>=2.28.1 +requests==2.32.* networkx>=2.5.1 typing-extensions>=3.10.0.2 HLL>=2.0.3 datasketches>=4.1.0 packaging>=23.0 boto3>=1.28.61 +# adding comment to trigger mend check diff --git a/tox.ini b/tox.ini index 21d418e98..4ee6081bd 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py39, py310, 311, pypi-description, manifest, precom +envlist = py39, py310, py311, pypi-description, manifest, precom [testenv] From c0f86fbaa78708bab117efbc7a84b90e5b86af97 Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:48:47 -0400 Subject: [PATCH 03/14] chore: update mypy dependencies (#1171) --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fd1768f0b..394b00f12 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -93,7 +93,6 @@ repos: # requirements-test.txt coverage>=5.0.1, - dask>=2.29.0, fsspec>=0.3.3, pytest>=6.0.1, pytest-cov>=2.8.1, From 48d0fd50118dc9d1ed95265fbe71c6cb01febf9b Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Wed, 12 Mar 2025 11:48:17 -0400 Subject: [PATCH 04/14] chore: refactor release process (#1170) --- .github/workflows/publish-package.yml | 52 + .github/workflows/publish-python-package.yml | 38 - ...st-python-package.yml => test-package.yml} | 2 - .pre-commit-config.yaml | 4 +- MANIFEST.in | 2 + dataprofiler/__init__.py | 4 +- dataprofiler/_version.py | 524 +++++ dataprofiler/version.py | 13 - requirements.txt | 1 + setup.cfg | 11 +- setup.py | 5 +- versioneer.py | 1741 +++++++++++++++++ 12 files changed, 2339 insertions(+), 58 deletions(-) create mode 100644 .github/workflows/publish-package.yml delete mode 100644 .github/workflows/publish-python-package.yml rename .github/workflows/{test-python-package.yml => test-package.yml} (97%) create mode 100644 dataprofiler/_version.py delete mode 100644 dataprofiler/version.py create mode 100644 versioneer.py diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml new file mode 100644 index 000000000..663f7754e --- /dev/null +++ b/.github/workflows/publish-package.yml @@ -0,0 +1,52 @@ +# This workflow publishes the package to pypi. +# For more details: +# https://docs.github.com/en/actions/guides/building-and-testing-python#publishing-to-package-registries +name: Publish to PyPi + +on: + release: + types: [created] + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + # fetch all tags so `versioneer` can properly determine current version + with: + fetch-depth: 0 + - name: Check if current commit is tagged + # fails and cancels release if the current commit is not tagged + run: | + git describe --exact-match --tags + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.11' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f requirements-ml.txt ]; then pip install -r requirements-ml.txt; fi + if [ -f requirements-reports.txt ]; then pip install -r requirements-reports.txt; fi + pip install setuptools wheel twine + - name: Build + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + TWINE_REPOSITORY: pypi + run: | + python setup.py sdist bdist_wheel + - name: Test build + # fails and cancels release if the built package fails to import + run: | + pip install dist/*.whl + python -c 'import data_profiler; print(data_profiler.__version__)' + - name: Publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + TWINE_REPOSITORY: pypi + run: | + twine upload dist/* diff --git a/.github/workflows/publish-python-package.yml b/.github/workflows/publish-python-package.yml deleted file mode 100644 index 4ed9e1bf3..000000000 --- a/.github/workflows/publish-python-package.yml +++ /dev/null @@ -1,38 +0,0 @@ - -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -name: Publish Python Package - -on: - release: - types: [created] - branches: - - 'release/*' - -jobs: - deploy: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - if [ -f requirements-ml.txt ]; then pip install -r requirements-ml.txt; fi - if [ -f requirements-reports.txt ]; then pip install -r requirements-reports.txt; fi - pip install setuptools wheel twine - - name: Build and publish - env: - TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} - TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} - TWINE_REPOSITORY: pypi - run: | - python setup.py sdist bdist_wheel - twine upload dist/* diff --git a/.github/workflows/test-python-package.yml b/.github/workflows/test-package.yml similarity index 97% rename from .github/workflows/test-python-package.yml rename to .github/workflows/test-package.yml index 3c88e7211..dda103be7 100644 --- a/.github/workflows/test-python-package.yml +++ b/.github/workflows/test-package.yml @@ -7,8 +7,6 @@ on: pull_request: branches: - 'main' - - 'feature/**' - - 'dev' jobs: build: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 394b00f12..7d776ea75 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: rev: 22.3.0 hooks: - id: black + exclude: (versioneer.py|dataprofiler/_version.py) types: [file, python] language_version: python3 # Isort: sort import statements @@ -41,7 +42,7 @@ repos: rev: v0.982 hooks: - id: mypy - exclude: (^dataprofiler/tests/|^resources/|^examples|venv*/) + exclude: (^dataprofiler/tests/|^resources/|^examples|venv*/|versioneer.py|dataprofiler/_version.py) language_version: python3 additional_dependencies: # Keep up-to-date with the respective requirement files [ @@ -117,6 +118,7 @@ repos: hooks: - id: pyupgrade args: ["--py38-plus"] + exclude: (versioneer.py|dataprofiler/_version.py) # Autoflake - cleanup unused variables and imports - repo: https://github.com/PyCQA/autoflake rev: v2.0.0 diff --git a/MANIFEST.in b/MANIFEST.in index 0ace6ebe9..1705367f6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -18,3 +18,5 @@ recursive-include resources *.pb recursive-include resources *.py recursive-include dataprofiler/labelers/embeddings/ *.txt +include versioneer.py +include dataprofiler/_version.py diff --git a/dataprofiler/__init__.py b/dataprofiler/__init__.py index 5f218bd85..ed54be241 100644 --- a/dataprofiler/__init__.py +++ b/dataprofiler/__init__.py @@ -1,5 +1,6 @@ """Package for dataprofiler.""" from . import settings +from ._version import get_versions from .data_readers.data import Data from .dp_logging import get_logger, set_verbosity from .labelers.data_labelers import ( @@ -18,7 +19,8 @@ from .profilers.profiler_options import ProfilerOptions from .reports import graphs from .validators.base_validators import Validator -from .version import __version__ + +__version__ = get_versions()["version"] def set_seed(seed=None): diff --git a/dataprofiler/_version.py b/dataprofiler/_version.py new file mode 100644 index 000000000..669959883 --- /dev/null +++ b/dataprofiler/_version.py @@ -0,0 +1,524 @@ +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. + +# This file is released into the public domain. Generated by +# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer) + +"""Git implementation of _version.py.""" + +import errno +import os +import re +import subprocess +import sys + + +def get_keywords(): + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "$Format:%d$" + git_full = "$Format:%H$" + git_date = "$Format:%ci$" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_config(): + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "pep440" + cfg.tag_prefix = "" + cfg.parentdir_prefix = "dataprofiler-" + cfg.versionfile_source = "dataprofiler/_version.py" + cfg.verbose = False + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +LONG_VERSION_PY = {} # type: ignore +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except OSError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print(f"unable to find command, tried {commands}") + return None, None + stdout = p.communicate()[0].strip().decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, p.returncode + return stdout, p.returncode + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print("Tried directories %s but none started with prefix %s" % + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs) + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG):] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r'\d', r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %s" % r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%s*" % tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%s'" + % describe_out) + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = ("tag '%s' doesn't start with prefix '%s'" + % (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], + cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post0.devDISTANCE] -- No -dirty. + + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post0.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + + The ".dev0" means dirty. + + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + + Like 'git describe --tags --dirty --always'. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} + + +def get_versions(): + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + + cfg = get_config() + verbose = cfg.verbose + + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} diff --git a/dataprofiler/version.py b/dataprofiler/version.py deleted file mode 100644 index b41e1c451..000000000 --- a/dataprofiler/version.py +++ /dev/null @@ -1,13 +0,0 @@ -"""File contains the version number for the package.""" - -MAJOR = 0 -MINOR = 12 -MICRO = 0 -POST = None # otherwise None - -VERSION = "%d.%d.%d" % (MAJOR, MINOR, MICRO) - -_post_str = "" -if POST: - _post_str = f".post{POST}" -__version__ = VERSION + _post_str diff --git a/requirements.txt b/requirements.txt index 3ccc4c6f5..0530826f2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,4 +18,5 @@ HLL>=2.0.3 datasketches>=4.1.0 packaging>=23.0 boto3>=1.28.61 +versioneer # adding comment to trigger mend check diff --git a/setup.cfg b/setup.cfg index dd0e2235f..8ad51bd86 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,10 +1,19 @@ +[versioneer] +vcs = git +style = pep440 +versionfile_source = dataprofiler/_version.py +versionfile_build = dataprofiler/_version.py +tag_prefix = "" +parentdir_prefix = dataprofiler- [flake8] max-line-length = 88 extend-ignore = E203 +exclude = versioneer.py, dataprofiler/_version.py [isort] + multi_line_output=3 -skip=dataprofiler/tests/data/,venv/ +skip=dataprofiler/tests/data/,venv/, versioneer.py, dataprofiler/_version.py profile=black include_trailing_comma=True force_grid_wrap=0 diff --git a/setup.py b/setup.py index eeca6629b..f0c8c7a81 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ from setuptools import find_packages, setup # Load package version -from dataprofiler.version import __version__ +import versioneer here = path.abspath(path.dirname(__file__)) @@ -53,7 +53,8 @@ setup( name="DataProfiler", - version=__version__, + version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), python_requires=">=3.9", description=DESCRIPTION, long_description=LONG_DESCRIPTION, diff --git a/versioneer.py b/versioneer.py new file mode 100644 index 000000000..fcbc15bd1 --- /dev/null +++ b/versioneer.py @@ -0,0 +1,1741 @@ +# Version: 0.19 + +"""The Versioneer - like a rocketeer, but for versions. +The Versioneer +============== +* like a rocketeer, but for versions! +* https://github.com/python-versioneer/python-versioneer +* Brian Warner +* License: Public Domain +* Compatible with: Python 3.6, 3.7, 3.8, 3.9 and pypy3 +* [![Latest Version][pypi-image]][pypi-url] +* [![Build Status][travis-image]][travis-url] +This is a tool for managing a recorded version number in distutils-based +python projects. The goal is to remove the tedious and error-prone "update +the embedded version string" step from your release process. Making a new +release should be as easy as recording a new tag in your version-control +system, and maybe making new tarballs. +## Quick Install +* `pip install versioneer` to somewhere in your $PATH +* add a `[versioneer]` section to your setup.cfg (see [Install](INSTALL.md)) +* run `versioneer install` in your source tree, commit the results +* Verify version information with `python setup.py version` +## Version Identifiers +Source trees come from a variety of places: +* a version-control system checkout (mostly used by developers) +* a nightly tarball, produced by build automation +* a snapshot tarball, produced by a web-based VCS browser, like github's + "tarball from tag" feature +* a release tarball, produced by "setup.py sdist", distributed through PyPI +Within each source tree, the version identifier (either a string or a number, +this tool is format-agnostic) can come from a variety of places: +* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows + about recent "tags" and an absolute revision-id +* the name of the directory into which the tarball was unpacked +* an expanded VCS keyword ($Id$, etc) +* a `_version.py` created by some earlier build step +For released software, the version identifier is closely related to a VCS +tag. Some projects use tag names that include more than just the version +string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool +needs to strip the tag prefix to extract the version identifier. For +unreleased software (between tags), the version identifier should provide +enough information to help developers recreate the same tree, while also +giving them an idea of roughly how old the tree is (after version 1.2, before +version 1.3). Many VCS systems can report a description that captures this, +for example `git describe --tags --dirty --always` reports things like +"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the +0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has +uncommitted changes). +The version identifier is used for multiple purposes: +* to allow the module to self-identify its version: `myproject.__version__` +* to choose a name and prefix for a 'setup.py sdist' tarball +## Theory of Operation +Versioneer works by adding a special `_version.py` file into your source +tree, where your `__init__.py` can import it. This `_version.py` knows how to +dynamically ask the VCS tool for version information at import time. +`_version.py` also contains `$Revision$` markers, and the installation +process marks `_version.py` to have this marker rewritten with a tag name +during the `git archive` command. As a result, generated tarballs will +contain enough information to get the proper version. +To allow `setup.py` to compute a version too, a `versioneer.py` is added to +the top level of your source tree, next to `setup.py` and the `setup.cfg` +that configures it. This overrides several distutils/setuptools commands to +compute the version when invoked, and changes `setup.py build` and `setup.py +sdist` to replace `_version.py` with a small static file that contains just +the generated version data. +## Installation +See [INSTALL.md](./INSTALL.md) for detailed installation instructions. +## Version-String Flavors +Code which uses Versioneer can learn about its version string at runtime by +importing `_version` from your main `__init__.py` file and running the +`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can +import the top-level `versioneer.py` and run `get_versions()`. +Both functions return a dictionary with different flavors of version +information: +* `['version']`: A condensed version string, rendered using the selected + style. This is the most commonly used value for the project's version + string. The default "pep440" style yields strings like `0.11`, + `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section + below for alternative styles. +* `['full-revisionid']`: detailed revision identifier. For Git, this is the + full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac". +* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the + commit date in ISO 8601 format. This will be None if the date is not + available. +* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that + this is only accurate if run in a VCS checkout, otherwise it is likely to + be False or None +* `['error']`: if the version string could not be computed, this will be set + to a string describing the problem, otherwise it will be None. It may be + useful to throw an exception in setup.py if this is set, to avoid e.g. + creating tarballs with a version string of "unknown". +Some variants are more useful than others. Including `full-revisionid` in a +bug report should allow developers to reconstruct the exact code being tested +(or indicate the presence of local changes that should be shared with the +developers). `version` is suitable for display in an "about" box or a CLI +`--version` output: it can be easily compared against release notes and lists +of bugs fixed in various releases. +The installer adds the following text to your `__init__.py` to place a basic +version in `YOURPROJECT.__version__`: + from ._version import get_versions + __version__ = get_versions()['version'] + del get_versions +## Styles +The setup.cfg `style=` configuration controls how the VCS information is +rendered into a version string. +The default style, "pep440", produces a PEP440-compliant string, equal to the +un-prefixed tag name for actual releases, and containing an additional "local +version" section with more detail for in-between builds. For Git, this is +TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags +--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the +tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and +that this commit is two revisions ("+2") beyond the "0.11" tag. For released +software (exactly equal to a known tag), the identifier will only contain the +stripped tag, e.g. "0.11". +Other styles are available. See [details.md](details.md) in the Versioneer +source tree for descriptions. +## Debugging +Versioneer tries to avoid fatal errors: if something goes wrong, it will tend +to return a version of "0+unknown". To investigate the problem, run `setup.py +version`, which will run the version-lookup code in a verbose mode, and will +display the full contents of `get_versions()` (including the `error` string, +which may help identify what went wrong). +## Known Limitations +Some situations are known to cause problems for Versioneer. This details the +most significant ones. More can be found on Github +[issues page](https://github.com/python-versioneer/python-versioneer/issues). +### Subprojects +Versioneer has limited support for source trees in which `setup.py` is not in +the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are +two common reasons why `setup.py` might not be in the root: +* Source trees which contain multiple subprojects, such as + [Buildbot](https://github.com/buildbot/buildbot), which contains both + "master" and "slave" subprojects, each with their own `setup.py`, + `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI + distributions (and upload multiple independently-installable tarballs). +* Source trees whose main purpose is to contain a C library, but which also + provide bindings to Python (and perhaps other languages) in subdirectories. +Versioneer will look for `.git` in parent directories, and most operations +should get the right version string. However `pip` and `setuptools` have bugs +and implementation details which frequently cause `pip install .` from a +subproject directory to fail to find a correct version string (so it usually +defaults to `0+unknown`). +`pip install --editable .` should work correctly. `setup.py install` might +work too. +Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in +some later version. +[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking +this issue. The discussion in +[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the +issue from the Versioneer side in more detail. +[pip PR#3176](https://github.com/pypa/pip/pull/3176) and +[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve +pip to let Versioneer work correctly. +Versioneer-0.16 and earlier only looked for a `.git` directory next to the +`setup.cfg`, so subprojects were completely unsupported with those releases. +### Editable installs with setuptools <= 18.5 +`setup.py develop` and `pip install --editable .` allow you to install a +project into a virtualenv once, then continue editing the source code (and +test) without re-installing after every change. +"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a +convenient way to specify executable scripts that should be installed along +with the python package. +These both work as expected when using modern setuptools. When using +setuptools-18.5 or earlier, however, certain operations will cause +`pkg_resources.DistributionNotFound` errors when running the entrypoint +script, which must be resolved by re-installing the package. This happens +when the install happens with one version, then the egg_info data is +regenerated while a different version is checked out. Many setup.py commands +cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into +a different virtualenv), so this can be surprising. +[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes +this one, but upgrading to a newer version of setuptools should probably +resolve it. +## Updating Versioneer +To upgrade your project to a new release of Versioneer, do the following: +* install the new Versioneer (`pip install -U versioneer` or equivalent) +* edit `setup.cfg`, if necessary, to include any new configuration settings + indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details. +* re-run `versioneer install` in your source tree, to replace + `SRC/_version.py` +* commit any changed files +## Future Directions +This tool is designed to make it easily extended to other version-control +systems: all VCS-specific components are in separate directories like +src/git/ . The top-level `versioneer.py` script is assembled from these +components by running make-versioneer.py . In the future, make-versioneer.py +will take a VCS name as an argument, and will construct a version of +`versioneer.py` that is specific to the given VCS. It might also take the +configuration arguments that are currently provided manually during +installation by editing setup.py . Alternatively, it might go the other +direction and include code from all supported VCS systems, reducing the +number of intermediate scripts. +## Similar projects +* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time + dependency +* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of + versioneer +## License +To make Versioneer easier to embed, all its code is dedicated to the public +domain. The `_version.py` that it creates is also in the public domain. +Specifically, both are released under the Creative Commons "Public Domain +Dedication" license (CC0-1.0), as described in +https://creativecommons.org/publicdomain/zero/1.0/ . +[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg +[pypi-url]: https://pypi.python.org/pypi/versioneer/ +[travis-image]: +https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg +[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer +""" + +import configparser +import errno +import json +import os +import re +import subprocess +import sys + + +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" + + +def get_root(): + """Get the project root directory. + We require that all commands are run from the project root, i.e. the + directory that contains setup.py, setup.cfg, and versioneer.py . + """ + root = os.path.realpath(os.path.abspath(os.getcwd())) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + # allow 'python path/to/setup.py COMMAND' + root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0]))) + setup_py = os.path.join(root, "setup.py") + versioneer_py = os.path.join(root, "versioneer.py") + if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)): + err = ( + "Versioneer was unable to run the project root directory. " + "Versioneer requires setup.py to be executed from " + "its immediate directory (like 'python setup.py COMMAND'), " + "or in a way that lets it use sys.argv[0] to find the root " + "(like 'python path/to/setup.py COMMAND')." + ) + raise VersioneerBadRootError(err) + try: + # Certain runtime workflows (setup.py install/develop in a setuptools + # tree) execute all dependencies in a single python process, so + # "versioneer" may be imported multiple times, and python's shared + # module-import table will cache the first one. So we can't use + # os.path.dirname(__file__), as that will find whichever + # versioneer.py was first imported, even in later projects. + me = os.path.realpath(os.path.abspath(__file__)) + me_dir = os.path.normcase(os.path.splitext(me)[0]) + vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0]) + if me_dir != vsr_dir: + print( + "Warning: build in %s is using versioneer.py from %s" + % (os.path.dirname(me), versioneer_py) + ) + except NameError: + pass + return root + + +def get_config_from_root(root): + """Read the project setup.cfg file to determine Versioneer config.""" + # This might raise EnvironmentError (if setup.cfg is missing), or + # configparser.NoSectionError (if it lacks a [versioneer] section), or + # configparser.NoOptionError (if it lacks "VCS="). See the docstring at + # the top of versioneer.py for instructions on writing your setup.cfg . + setup_cfg = os.path.join(root, "setup.cfg") + parser = configparser.ConfigParser() + with open(setup_cfg) as f: + parser.read_file(f) + VCS = parser.get("versioneer", "VCS") # mandatory + + def get(parser, name): + if parser.has_option("versioneer", name): + return parser.get("versioneer", name) + return None + + cfg = VersioneerConfig() + cfg.VCS = VCS + cfg.style = get(parser, "style") or "" + cfg.versionfile_source = get(parser, "versionfile_source") + cfg.versionfile_build = get(parser, "versionfile_build") + cfg.tag_prefix = get(parser, "tag_prefix") + if cfg.tag_prefix in ("''", '""'): + cfg.tag_prefix = "" + cfg.parentdir_prefix = get(parser, "parentdir_prefix") + cfg.verbose = get(parser, "verbose") + return cfg + + +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" + + +# these dictionaries contain VCS-specific tools +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator + """Create decorator to mark a method as the handler of a VCS.""" + + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + + return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen( + [c] + args, + cwd=cwd, + env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr else None), + ) + break + except OSError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %s" % dispcmd) + print(e) + return None, None + else: + if verbose: + print(f"unable to find command, tried {commands}") + return None, None + stdout = p.communicate()[0].strip().decode() + if p.returncode != 0: + if verbose: + print("unable to run %s (error)" % dispcmd) + print("stdout was %s" % stdout) + return None, p.returncode + return stdout, p.returncode + + +LONG_VERSION_PY[ + "git" +] = r''' +# This file helps to compute a version number in source trees obtained from +# git-archive tarball (such as those provided by githubs download-from-tag +# feature). Distribution tarballs (built by setup.py sdist) and build +# directories (produced by setup.py build) will contain a much shorter file +# that just contains the computed version number. +# This file is released into the public domain. Generated by +# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer) +"""Git implementation of _version.py.""" +import errno +import os +import re +import subprocess +import sys +def get_keywords(): + """Get the keywords needed to look up the version information.""" + # these strings will be replaced by git during git-archive. + # setup.py/versioneer.py will grep for the variable names, so they must + # each be defined on a line of their own. _version.py will just call + # get_keywords(). + git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s" + git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s" + git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s" + keywords = {"refnames": git_refnames, "full": git_full, "date": git_date} + return keywords +class VersioneerConfig: + """Container for Versioneer configuration parameters.""" +def get_config(): + """Create, populate and return the VersioneerConfig() object.""" + # these strings are filled in when 'setup.py versioneer' creates + # _version.py + cfg = VersioneerConfig() + cfg.VCS = "git" + cfg.style = "%(STYLE)s" + cfg.tag_prefix = "%(TAG_PREFIX)s" + cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s" + cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s" + cfg.verbose = False + return cfg +class NotThisMethod(Exception): + """Exception raised if a method is not valid for the current scenario.""" +LONG_VERSION_PY = {} +HANDLERS = {} +def register_vcs_handler(vcs, method): # decorator + """Create decorator to mark a method as the handler of a VCS.""" + def decorate(f): + """Store f in HANDLERS[vcs][method].""" + if vcs not in HANDLERS: + HANDLERS[vcs] = {} + HANDLERS[vcs][method] = f + return f + return decorate +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False, + env=None): + """Call the given command(s).""" + assert isinstance(commands, list) + p = None + for c in commands: + try: + dispcmd = str([c] + args) + # remember shell=False, so use git.cmd on windows, not just git + p = subprocess.Popen([c] + args, cwd=cwd, env=env, + stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) + break + except EnvironmentError: + e = sys.exc_info()[1] + if e.errno == errno.ENOENT: + continue + if verbose: + print("unable to run %%s" %% dispcmd) + print(e) + return None, None + else: + if verbose: + print("unable to find command, tried %%s" %% (commands,)) + return None, None + stdout = p.communicate()[0].strip().decode() + if p.returncode != 0: + if verbose: + print("unable to run %%s (error)" %% dispcmd) + print("stdout was %%s" %% stdout) + return None, p.returncode + return stdout, p.returncode +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return {"version": dirname[len(parentdir_prefix):], + "full-revisionid": None, + "dirty": False, "error": None, "date": None} + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + if verbose: + print("Tried directories %%s but none started with prefix %%s" %% + (str(rootdirs), parentdir_prefix)) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs, "r") + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except EnvironmentError: + pass + return keywords +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = set([r.strip() for r in refnames.strip("()").split(",")]) + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)]) + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %%d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = set([r for r in refs if re.search(r'\d', r)]) + if verbose: + print("discarding '%%s', no digits" %% ",".join(refs - tags)) + if verbose: + print("likely tags: %%s" %% ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix):] + if verbose: + print("picking %%s" %% r) + return {"version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": None, + "date": date} + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return {"version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, "error": "no suitable tags", "date": None} +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, + hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %%s not under git control" %% root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty", + "--always", "--long", + "--match", "%%s*" %% tag_prefix], + cwd=root) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[:git_describe.rindex("-dirty")] + # now we have TAG-NUM-gHEX or HEX + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = ("unable to parse git-describe output: '%%s'" + %% describe_out) + return pieces + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%%s' doesn't start with prefix '%%s'" + print(fmt %% (full_tag, tag_prefix)) + pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'" + %% (full_tag, tag_prefix)) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix):] + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + # commit: short hex revision ID + pieces["short"] = mo.group(3) + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], + cwd=root) + pieces["distance"] = int(count_out) # total number of commits + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"], + cwd=root)[0].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + return pieces +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"], + pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered +def render_pep440_pre(pieces): + """TAG[.post0.devDISTANCE] -- No -dirty. + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post0.dev%%d" %% pieces["distance"] + else: + # exception #1 + rendered = "0.post0.dev%%d" %% pieces["distance"] + return rendered +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%%s" %% pieces["short"] + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%%s" %% pieces["short"] + return rendered +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + The ".dev0" means dirty. + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%%d" %% pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + Like 'git describe --tags --dirty --always'. + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return {"version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None} + if not style or style == "default": + style = "pep440" # the default + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%%s'" %% style) + return {"version": rendered, "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], "error": None, + "date": pieces.get("date")} +def get_versions(): + """Get version information or return default if unable to do so.""" + # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have + # __file__, we can work backwards from there to the root. Some + # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which + # case we can only use expanded keywords. + cfg = get_config() + verbose = cfg.verbose + try: + return git_versions_from_keywords(get_keywords(), cfg.tag_prefix, + verbose) + except NotThisMethod: + pass + try: + root = os.path.realpath(__file__) + # versionfile_source is the relative path from the top of the source + # tree (where the .git directory might live) to this file. Invert + # this to find the root from __file__. + for i in cfg.versionfile_source.split('/'): + root = os.path.dirname(root) + except NameError: + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to find root of source tree", + "date": None} + try: + pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose) + return render(pieces, cfg.style) + except NotThisMethod: + pass + try: + if cfg.parentdir_prefix: + return versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + except NotThisMethod: + pass + return {"version": "0+unknown", "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", "date": None} +''' + + +@register_vcs_handler("git", "get_keywords") +def git_get_keywords(versionfile_abs): + """Extract version information from the given file.""" + # the code embedded in _version.py can just fetch the value of these + # keywords. When used from setup.py, we don't want to import _version.py, + # so we do it with a regexp instead. This function is not used from + # _version.py. + keywords = {} + try: + f = open(versionfile_abs) + for line in f.readlines(): + if line.strip().startswith("git_refnames ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["refnames"] = mo.group(1) + if line.strip().startswith("git_full ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["full"] = mo.group(1) + if line.strip().startswith("git_date ="): + mo = re.search(r'=\s*"(.*)"', line) + if mo: + keywords["date"] = mo.group(1) + f.close() + except OSError: + pass + return keywords + + +@register_vcs_handler("git", "keywords") +def git_versions_from_keywords(keywords, tag_prefix, verbose): + """Get version information from git keywords.""" + if not keywords: + raise NotThisMethod("no keywords at all, weird") + date = keywords.get("date") + if date is not None: + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + + # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant + # datestamp. However we prefer "%ci" (which expands to an "ISO-8601 + # -like" string, which we must then edit to make compliant), because + # it's been around since git-1.5.3, and it's too difficult to + # discover which version we're using, or to work around using an + # older one. + date = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + refnames = keywords["refnames"].strip() + if refnames.startswith("$Format"): + if verbose: + print("keywords are unexpanded, not using") + raise NotThisMethod("unexpanded keywords, not a git-archive tarball") + refs = {r.strip() for r in refnames.strip("()").split(",")} + # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of + # just "foo-1.0". If we see a "tag: " prefix, prefer those. + TAG = "tag: " + tags = {r[len(TAG) :] for r in refs if r.startswith(TAG)} + if not tags: + # Either we're using git < 1.8.3, or there really are no tags. We use + # a heuristic: assume all version tags have a digit. The old git %d + # expansion behaves like git log --decorate=short and strips out the + # refs/heads/ and refs/tags/ prefixes that would let us distinguish + # between branches and tags. By ignoring refnames without digits, we + # filter out many common branch names like "release" and + # "stabilization", as well as "HEAD" and "master". + tags = {r for r in refs if re.search(r"\d", r)} + if verbose: + print("discarding '%s', no digits" % ",".join(refs - tags)) + if verbose: + print("likely tags: %s" % ",".join(sorted(tags))) + for ref in sorted(tags): + # sorting will prefer e.g. "2.0" over "2.0rc1" + if ref.startswith(tag_prefix): + r = ref[len(tag_prefix) :] + if verbose: + print("picking %s" % r) + return { + "version": r, + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": None, + "date": date, + } + # no suitable tags, so version is "0+unknown", but full hex is still there + if verbose: + print("no suitable tags, using unknown + full revision id") + return { + "version": "0+unknown", + "full-revisionid": keywords["full"].strip(), + "dirty": False, + "error": "no suitable tags", + "date": None, + } + + +@register_vcs_handler("git", "pieces_from_vcs") +def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command): + """Get version from 'git describe' in the root of the source tree. + This only gets called if the git-archive 'subst' keywords were *not* + expanded, and _version.py hasn't already been rewritten with a short + version string, meaning we're inside a checked out source tree. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + + out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root, hide_stderr=True) + if rc != 0: + if verbose: + print("Directory %s not under git control" % root) + raise NotThisMethod("'git rev-parse --git-dir' returned error") + + # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty] + # if there isn't one, this yields HEX[-dirty] (no NUM) + describe_out, rc = run_command( + GITS, + [ + "describe", + "--tags", + "--dirty", + "--always", + "--long", + "--match", + "%s*" % tag_prefix, + ], + cwd=root, + ) + # --long was added in git-1.5.5 + if describe_out is None: + raise NotThisMethod("'git describe' failed") + describe_out = describe_out.strip() + full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root) + if full_out is None: + raise NotThisMethod("'git rev-parse' failed") + full_out = full_out.strip() + + pieces = {} + pieces["long"] = full_out + pieces["short"] = full_out[:7] # maybe improved later + pieces["error"] = None + + # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty] + # TAG might have hyphens. + git_describe = describe_out + + # look for -dirty suffix + dirty = git_describe.endswith("-dirty") + pieces["dirty"] = dirty + if dirty: + git_describe = git_describe[: git_describe.rindex("-dirty")] + + # now we have TAG-NUM-gHEX or HEX + + if "-" in git_describe: + # TAG-NUM-gHEX + mo = re.search(r"^(.+)-(\d+)-g([0-9a-f]+)$", git_describe) + if not mo: + # unparseable. Maybe git-describe is misbehaving? + pieces["error"] = "unable to parse git-describe output: '%s'" % describe_out + return pieces + + # tag + full_tag = mo.group(1) + if not full_tag.startswith(tag_prefix): + if verbose: + fmt = "tag '%s' doesn't start with prefix '%s'" + print(fmt % (full_tag, tag_prefix)) + pieces["error"] = "tag '{}' doesn't start with prefix '{}'".format( + full_tag, + tag_prefix, + ) + return pieces + pieces["closest-tag"] = full_tag[len(tag_prefix) :] + + # distance: number of commits since tag + pieces["distance"] = int(mo.group(2)) + + # commit: short hex revision ID + pieces["short"] = mo.group(3) + + else: + # HEX: no tags + pieces["closest-tag"] = None + count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"], cwd=root) + pieces["distance"] = int(count_out) # total number of commits + + # commit date: see ISO-8601 comment in git_versions_from_keywords() + date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[ + 0 + ].strip() + # Use only the last line. Previous lines may contain GPG signature + # information. + date = date.splitlines()[-1] + pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1) + + return pieces + + +def do_vcs_install(manifest_in, versionfile_source, ipy): + """Git-specific installation logic for Versioneer. + For Git, this means creating/changing .gitattributes to mark _version.py + for export-subst keyword substitution. + """ + GITS = ["git"] + if sys.platform == "win32": + GITS = ["git.cmd", "git.exe"] + files = [manifest_in, versionfile_source] + if ipy: + files.append(ipy) + try: + me = __file__ + if me.endswith(".pyc") or me.endswith(".pyo"): + me = os.path.splitext(me)[0] + ".py" + versioneer_file = os.path.relpath(me) + except NameError: + versioneer_file = "versioneer.py" + files.append(versioneer_file) + present = False + try: + f = open(".gitattributes") + for line in f.readlines(): + if line.strip().startswith(versionfile_source): + if "export-subst" in line.strip().split()[1:]: + present = True + f.close() + except OSError: + pass + if not present: + f = open(".gitattributes", "a+") + f.write("%s export-subst\n" % versionfile_source) + f.close() + files.append(".gitattributes") + run_command(GITS, ["add", "--"] + files) + + +def versions_from_parentdir(parentdir_prefix, root, verbose): + """Try to determine the version from the parent directory name. + Source tarballs conventionally unpack into a directory that includes both + the project name and a version string. We will also support searching up + two directory levels for an appropriately named parent directory + """ + rootdirs = [] + + for i in range(3): + dirname = os.path.basename(root) + if dirname.startswith(parentdir_prefix): + return { + "version": dirname[len(parentdir_prefix) :], + "full-revisionid": None, + "dirty": False, + "error": None, + "date": None, + } + else: + rootdirs.append(root) + root = os.path.dirname(root) # up a level + + if verbose: + print( + "Tried directories %s but none started with prefix %s" + % (str(rootdirs), parentdir_prefix) + ) + raise NotThisMethod("rootdir doesn't start with parentdir_prefix") + + +SHORT_VERSION_PY = """ +# This file was generated by 'versioneer.py' (0.19) from +# revision-control system data, or from the parent directory name of an +# unpacked source archive. Distribution tarballs contain a pre-generated copy +# of this file. +import json +version_json = ''' +%s +''' # END VERSION_JSON +def get_versions(): + return json.loads(version_json) +""" + + +def versions_from_file(filename): + """Try to determine the version from _version.py if present.""" + try: + with open(filename) as f: + contents = f.read() + except OSError: + raise NotThisMethod("unable to read _version.py") + mo = re.search( + r"version_json = '''\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) + if not mo: + mo = re.search( + r"version_json = '''\r\n(.*)''' # END VERSION_JSON", contents, re.M | re.S + ) + if not mo: + raise NotThisMethod("no version_json in _version.py") + return json.loads(mo.group(1)) + + +def write_to_version_file(filename, versions): + """Write the given version number to the given _version.py file.""" + os.unlink(filename) + contents = json.dumps(versions, sort_keys=True, indent=1, separators=(",", ": ")) + with open(filename, "w") as f: + f.write(SHORT_VERSION_PY % contents) + + print("set {} to '{}'".format(filename, versions["version"])) + + +def plus_or_dot(pieces): + """Return a + if we don't already have one, else return a .""" + if "+" in pieces.get("closest-tag", ""): + return "." + return "+" + + +def render_pep440(pieces): + """Build up version string, with post-release "local version identifier". + Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you + get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty + Exceptions: + 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += plus_or_dot(pieces) + rendered += "%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + else: + # exception #1 + rendered = "0+untagged.%d.g%s" % (pieces["distance"], pieces["short"]) + if pieces["dirty"]: + rendered += ".dirty" + return rendered + + +def render_pep440_pre(pieces): + """TAG[.post0.devDISTANCE] -- No -dirty. + Exceptions: + 1: no tags. 0.post0.devDISTANCE + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += ".post0.dev%d" % pieces["distance"] + else: + # exception #1 + rendered = "0.post0.dev%d" % pieces["distance"] + return rendered + + +def render_pep440_post(pieces): + """TAG[.postDISTANCE[.dev0]+gHEX] . + The ".dev0" means dirty. Note that .dev0 sorts backwards + (a dirty tree will appear "older" than the corresponding clean one), + but you shouldn't be releasing software with -dirty anyways. + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += plus_or_dot(pieces) + rendered += "g%s" % pieces["short"] + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + rendered += "+g%s" % pieces["short"] + return rendered + + +def render_pep440_old(pieces): + """TAG[.postDISTANCE[.dev0]] . + The ".dev0" means dirty. + Exceptions: + 1: no tags. 0.postDISTANCE[.dev0] + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"] or pieces["dirty"]: + rendered += ".post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + else: + # exception #1 + rendered = "0.post%d" % pieces["distance"] + if pieces["dirty"]: + rendered += ".dev0" + return rendered + + +def render_git_describe(pieces): + """TAG[-DISTANCE-gHEX][-dirty]. + Like 'git describe --tags --dirty --always'. + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + if pieces["distance"]: + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render_git_describe_long(pieces): + """TAG-DISTANCE-gHEX[-dirty]. + Like 'git describe --tags --dirty --always -long'. + The distance/hash is unconditional. + Exceptions: + 1: no tags. HEX[-dirty] (note: no 'g' prefix) + """ + if pieces["closest-tag"]: + rendered = pieces["closest-tag"] + rendered += "-%d-g%s" % (pieces["distance"], pieces["short"]) + else: + # exception #1 + rendered = pieces["short"] + if pieces["dirty"]: + rendered += "-dirty" + return rendered + + +def render(pieces, style): + """Render the given version pieces into the requested style.""" + if pieces["error"]: + return { + "version": "unknown", + "full-revisionid": pieces.get("long"), + "dirty": None, + "error": pieces["error"], + "date": None, + } + + if not style or style == "default": + style = "pep440" # the default + + if style == "pep440": + rendered = render_pep440(pieces) + elif style == "pep440-pre": + rendered = render_pep440_pre(pieces) + elif style == "pep440-post": + rendered = render_pep440_post(pieces) + elif style == "pep440-old": + rendered = render_pep440_old(pieces) + elif style == "git-describe": + rendered = render_git_describe(pieces) + elif style == "git-describe-long": + rendered = render_git_describe_long(pieces) + else: + raise ValueError("unknown style '%s'" % style) + + return { + "version": rendered, + "full-revisionid": pieces["long"], + "dirty": pieces["dirty"], + "error": None, + "date": pieces.get("date"), + } + + +class VersioneerBadRootError(Exception): + """The project root directory is unknown or missing key files.""" + + +def get_versions(verbose=False): + """Get the project version from whatever source is available. + Returns dict with two keys: 'version' and 'full'. + """ + if "versioneer" in sys.modules: + # see the discussion in cmdclass.py:get_cmdclass() + del sys.modules["versioneer"] + + root = get_root() + cfg = get_config_from_root(root) + + assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg" + handlers = HANDLERS.get(cfg.VCS) + assert handlers, "unrecognized VCS '%s'" % cfg.VCS + verbose = verbose or cfg.verbose + assert ( + cfg.versionfile_source is not None + ), "please set versioneer.versionfile_source" + assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix" + + versionfile_abs = os.path.join(root, cfg.versionfile_source) + + # extract version from first of: _version.py, VCS command (e.g. 'git + # describe'), parentdir. This is meant to work for developers using a + # source checkout, for users of a tarball created by 'setup.py sdist', + # and for users of a tarball/zipball created by 'git archive' or github's + # download-from-tag feature or the equivalent in other VCSes. + + get_keywords_f = handlers.get("get_keywords") + from_keywords_f = handlers.get("keywords") + if get_keywords_f and from_keywords_f: + try: + keywords = get_keywords_f(versionfile_abs) + ver = from_keywords_f(keywords, cfg.tag_prefix, verbose) + if verbose: + print("got version from expanded keyword %s" % ver) + return ver + except NotThisMethod: + pass + + try: + ver = versions_from_file(versionfile_abs) + if verbose: + print(f"got version from file {versionfile_abs} {ver}") + return ver + except NotThisMethod: + pass + + from_vcs_f = handlers.get("pieces_from_vcs") + if from_vcs_f: + try: + pieces = from_vcs_f(cfg.tag_prefix, root, verbose) + ver = render(pieces, cfg.style) + if verbose: + print("got version from VCS %s" % ver) + return ver + except NotThisMethod: + pass + + try: + if cfg.parentdir_prefix: + ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose) + if verbose: + print("got version from parentdir %s" % ver) + return ver + except NotThisMethod: + pass + + if verbose: + print("unable to compute version") + + return { + "version": "0+unknown", + "full-revisionid": None, + "dirty": None, + "error": "unable to compute version", + "date": None, + } + + +def get_version(): + """Get the short version string for this project.""" + return get_versions()["version"] + + +def get_cmdclass(cmdclass=None): + """Get the custom setuptools/distutils subclasses used by Versioneer. + If the package uses a different cmdclass (e.g. one from numpy), it + should be provide as an argument. + """ + if "versioneer" in sys.modules: + del sys.modules["versioneer"] + # this fixes the "python setup.py develop" case (also 'install' and + # 'easy_install .'), in which subdependencies of the main project are + # built (using setup.py bdist_egg) in the same python process. Assume + # a main project A and a dependency B, which use different versions + # of Versioneer. A's setup.py imports A's Versioneer, leaving it in + # sys.modules by the time B's setup.py is executed, causing B to run + # with the wrong versioneer. Setuptools wraps the sub-dep builds in a + # sandbox that restores sys.modules to it's pre-build state, so the + # parent is protected against the child's "import versioneer". By + # removing ourselves from sys.modules here, before the child build + # happens, we protect the child from the parent's versioneer too. + # Also see https://github.com/python-versioneer/python-versioneer/issues/52 + + cmds = {} if cmdclass is None else cmdclass.copy() + + # we add "version" to both distutils and setuptools + from distutils.core import Command + + class cmd_version(Command): + description = "report generated version string" + user_options = [] + boolean_options = [] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + vers = get_versions(verbose=True) + print("Version: %s" % vers["version"]) + print(" full-revisionid: %s" % vers.get("full-revisionid")) + print(" dirty: %s" % vers.get("dirty")) + print(" date: %s" % vers.get("date")) + if vers["error"]: + print(" error: %s" % vers["error"]) + + cmds["version"] = cmd_version + + # we override "build_py" in both distutils and setuptools + # + # most invocation pathways end up running build_py: + # distutils/build -> build_py + # distutils/install -> distutils/build ->.. + # setuptools/bdist_wheel -> distutils/install ->.. + # setuptools/bdist_egg -> distutils/install_lib -> build_py + # setuptools/install -> bdist_egg ->.. + # setuptools/develop -> ? + # pip install: + # copies source tree to a tempdir before running egg_info/etc + # if .git isn't copied too, 'git describe' will fail + # then does setup.py bdist_wheel, or sometimes setup.py install + # setup.py egg_info -> ? + + # we override different "build_py" commands for both environments + if "build_py" in cmds: + _build_py = cmds["build_py"] + elif "setuptools" in sys.modules: + from setuptools.command.build_py import build_py as _build_py + else: + from distutils.command.build_py import build_py as _build_py + + class cmd_build_py(_build_py): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_py.run(self) + # now locate _version.py in the new build/ directory and replace + # it with an updated value + if cfg.versionfile_build: + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_build) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + cmds["build_py"] = cmd_build_py + + if "setuptools" in sys.modules: + from setuptools.command.build_ext import build_ext as _build_ext + else: + from distutils.command.build_ext import build_ext as _build_ext + + class cmd_build_ext(_build_ext): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + _build_ext.run(self) + if self.inplace: + # build_ext --inplace will only build extensions in + # build/lib<..> dir with no _version.py to write to. + # As in place builds will already have a _version.py + # in the module dir, we do not need to write one. + return + # now locate _version.py in the new build/ directory and replace + # it with an updated value + target_versionfile = os.path.join(self.build_lib, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + cmds["build_ext"] = cmd_build_ext + + if "cx_Freeze" in sys.modules: # cx_freeze enabled? + from cx_Freeze.dist import build_exe as _build_exe + + # nczeczulin reports that py2exe won't like the pep440-style string + # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g. + # setup(console=[{ + # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION + # "product_version": versioneer.get_version(), + # ... + + class cmd_build_exe(_build_exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _build_exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + + cmds["build_exe"] = cmd_build_exe + del cmds["build_py"] + + if "py2exe" in sys.modules: # py2exe enabled? + from py2exe.distutils_buildexe import py2exe as _py2exe + + class cmd_py2exe(_py2exe): + def run(self): + root = get_root() + cfg = get_config_from_root(root) + versions = get_versions() + target_versionfile = cfg.versionfile_source + print("UPDATING %s" % target_versionfile) + write_to_version_file(target_versionfile, versions) + + _py2exe.run(self) + os.unlink(target_versionfile) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + + cmds["py2exe"] = cmd_py2exe + + # we override different "sdist" commands for both environments + if "sdist" in cmds: + _sdist = cmds["sdist"] + elif "setuptools" in sys.modules: + from setuptools.command.sdist import sdist as _sdist + else: + from distutils.command.sdist import sdist as _sdist + + class cmd_sdist(_sdist): + def run(self): + versions = get_versions() + self._versioneer_generated_versions = versions + # unless we update this, the command will keep using the old + # version + self.distribution.metadata.version = versions["version"] + return _sdist.run(self) + + def make_release_tree(self, base_dir, files): + root = get_root() + cfg = get_config_from_root(root) + _sdist.make_release_tree(self, base_dir, files) + # now locate _version.py in the new base_dir directory + # (remembering that it may be a hardlink) and replace it with an + # updated value + target_versionfile = os.path.join(base_dir, cfg.versionfile_source) + print("UPDATING %s" % target_versionfile) + write_to_version_file( + target_versionfile, self._versioneer_generated_versions + ) + + cmds["sdist"] = cmd_sdist + + return cmds + + +CONFIG_ERROR = """ +setup.cfg is missing the necessary Versioneer configuration. You need +a section like: + [versioneer] + VCS = git + style = pep440 + versionfile_source = src/myproject/_version.py + versionfile_build = myproject/_version.py + tag_prefix = + parentdir_prefix = myproject- +You will also need to edit your setup.py to use the results: + import versioneer + setup(version=versioneer.get_version(), + cmdclass=versioneer.get_cmdclass(), ...) +Please read the docstring in ./versioneer.py for configuration instructions, +edit setup.cfg, and re-run the installer or 'python versioneer.py setup'. +""" + +SAMPLE_CONFIG = """ +# See the docstring in versioneer.py for instructions. Note that you must +# re-run 'versioneer.py setup' after changing this section, and commit the +# resulting files. +[versioneer] +#VCS = git +#style = pep440 +#versionfile_source = +#versionfile_build = +#tag_prefix = +#parentdir_prefix = +""" + +INIT_PY_SNIPPET = """ +from ._version import get_versions +__version__ = get_versions()['version'] +del get_versions +""" + + +def do_setup(): + """Do main VCS-independent setup function for installing Versioneer.""" + root = get_root() + try: + cfg = get_config_from_root(root) + except (OSError, configparser.NoSectionError, configparser.NoOptionError) as e: + if isinstance(e, (EnvironmentError, configparser.NoSectionError)): + print("Adding sample versioneer config to setup.cfg", file=sys.stderr) + with open(os.path.join(root, "setup.cfg"), "a") as f: + f.write(SAMPLE_CONFIG) + print(CONFIG_ERROR, file=sys.stderr) + return 1 + + print(" creating %s" % cfg.versionfile_source) + with open(cfg.versionfile_source, "w") as f: + LONG = LONG_VERSION_PY[cfg.VCS] + f.write( + LONG + % { + "DOLLAR": "$", + "STYLE": cfg.style, + "TAG_PREFIX": cfg.tag_prefix, + "PARENTDIR_PREFIX": cfg.parentdir_prefix, + "VERSIONFILE_SOURCE": cfg.versionfile_source, + } + ) + + ipy = os.path.join(os.path.dirname(cfg.versionfile_source), "__init__.py") + if os.path.exists(ipy): + try: + with open(ipy) as f: + old = f.read() + except OSError: + old = "" + if INIT_PY_SNIPPET not in old: + print(" appending to %s" % ipy) + with open(ipy, "a") as f: + f.write(INIT_PY_SNIPPET) + else: + print(" %s unmodified" % ipy) + else: + print(" %s doesn't exist, ok" % ipy) + ipy = None + + # Make sure both the top-level "versioneer.py" and versionfile_source + # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so + # they'll be copied into source distributions. Pip won't be able to + # install the package without this. + manifest_in = os.path.join(root, "MANIFEST.in") + simple_includes = set() + try: + with open(manifest_in) as f: + for line in f: + if line.startswith("include "): + for include in line.split()[1:]: + simple_includes.add(include) + except OSError: + pass + # That doesn't cover everything MANIFEST.in can do + # (http://docs.python.org/2/distutils/sourcedist.html#commands), so + # it might give some false negatives. Appending redundant 'include' + # lines is safe, though. + if "versioneer.py" not in simple_includes: + print(" appending 'versioneer.py' to MANIFEST.in") + with open(manifest_in, "a") as f: + f.write("include versioneer.py\n") + else: + print(" 'versioneer.py' already in MANIFEST.in") + if cfg.versionfile_source not in simple_includes: + print( + " appending versionfile_source ('%s') to MANIFEST.in" + % cfg.versionfile_source + ) + with open(manifest_in, "a") as f: + f.write("include %s\n" % cfg.versionfile_source) + else: + print(" versionfile_source already in MANIFEST.in") + + # Make VCS-specific changes. For git, this means creating/changing + # .gitattributes to mark _version.py for export-subst keyword + # substitution. + do_vcs_install(manifest_in, cfg.versionfile_source, ipy) + return 0 + + +def scan_setup_py(): + """Validate the contents of setup.py against Versioneer's expectations.""" + found = set() + setters = False + errors = 0 + with open("setup.py") as f: + for line in f.readlines(): + if "import versioneer" in line: + found.add("import") + if "versioneer.get_cmdclass()" in line: + found.add("cmdclass") + if "versioneer.get_version()" in line: + found.add("get_version") + if "versioneer.VCS" in line: + setters = True + if "versioneer.versionfile_source" in line: + setters = True + if len(found) != 3: + print("") + print("Your setup.py appears to be missing some important items") + print("(but I might be wrong). Please make sure it has something") + print("roughly like the following:") + print("") + print(" import versioneer") + print(" setup( version=versioneer.get_version(),") + print(" cmdclass=versioneer.get_cmdclass(), ...)") + print("") + errors += 1 + if setters: + print("You should remove lines like 'versioneer.VCS = ' and") + print("'versioneer.versionfile_source = ' . This configuration") + print("now lives in setup.cfg, and should be removed from setup.py") + print("") + errors += 1 + return errors + + +if __name__ == "__main__": + cmd = sys.argv[1] + if cmd == "setup": + errors = do_setup() + errors += scan_setup_py() + if errors: + sys.exit(1) From aafeef6d8a8139a6d197c117e28b6801861c48bf Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Wed, 12 Mar 2025 12:34:11 -0400 Subject: [PATCH 05/14] chore: Update publish-package.yml (#1172) --- .github/workflows/publish-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-package.yml b/.github/workflows/publish-package.yml index 663f7754e..9a230cd27 100644 --- a/.github/workflows/publish-package.yml +++ b/.github/workflows/publish-package.yml @@ -42,7 +42,7 @@ jobs: # fails and cancels release if the built package fails to import run: | pip install dist/*.whl - python -c 'import data_profiler; print(data_profiler.__version__)' + python -c 'import dataprofiler; print(dataprofiler.__version__)' - name: Publish env: TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} From ed8188a409e02854daabf132ce4672e383099f80 Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Tue, 18 Mar 2025 13:20:13 -0400 Subject: [PATCH 06/14] gh pages update (#1173) * chore: create publish-docs.yml * brought in docs directory --- .github/workflows/publish-docs.yml | 41 + .pre-commit-config.yaml | 14 +- MANIFEST.in | 12 +- _docs/README.md | 59 ++ _docs/docs/Makefile | 20 + _docs/docs/make.bat | 35 + _docs/docs/source/API.rst | 16 + _docs/docs/source/DL-Flowchart.png | Bin 0 -> 7609 bytes _docs/docs/source/_static/custom.css | 50 + .../images/DataProfilerDarkLogoLong.png | Bin 0 -> 20019 bytes .../images/DataProfilerLogoLightTheme.png | Bin 0 -> 118089 bytes .../images/DataProfilerLogoLightThemeLong.png | Bin 0 -> 177437 bytes .../images/branching_workflow_diagram.png | Bin 0 -> 131890 bytes .../_static/images/histogram_example_0.png | Bin 0 -> 14056 bytes .../_static/images/histogram_example_1.png | Bin 0 -> 11387 bytes .../_static/images/histogram_example_2.png | Bin 0 -> 12592 bytes .../missing_value_barchart_example_0.png | Bin 0 -> 24758 bytes .../images/missing_value_matrix_example_0.png | Bin 0 -> 37730 bytes .../add_new_model_to_data_labeler.nblink | 3 + .../source/column_name_labeler_example.nblink | 3 + _docs/docs/source/conf.py | 84 ++ _docs/docs/source/data_labeling.rst | 365 +++++++ _docs/docs/source/data_reader.nblink | 3 + _docs/docs/source/data_readers.rst | 184 ++++ _docs/docs/source/examples.rst | 24 + _docs/docs/source/graph_data_demo.nblink | 3 + _docs/docs/source/graphs.rst | 196 ++++ _docs/docs/source/index.rst | 605 +++++++++++ _docs/docs/source/install.rst | 145 +++ _docs/docs/source/labeler.nblink | 6 + _docs/docs/source/merge_profile_list.nblink | 3 + _docs/docs/source/modules.rst | 7 + _docs/docs/source/overview.nblink | 3 + .../source/popmon_dp_loader_example.nblink | 3 + _docs/docs/source/profiler.rst | 965 ++++++++++++++++++ _docs/docs/source/profiler_example.nblink | 3 + .../source/regex_labeler_from_scratch.nblink | 3 + _docs/docs/source/roadmap.rst | 58 ++ .../unstructured_profiler_example.nblink | 3 + _docs/docs/update_documentation.py | 86 ++ _docs/index.html | 1 + _docs/profiler_options.html | 1 + _docs/setup.cfg | 7 + requirements-docs.txt | 7 + 44 files changed, 3011 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/publish-docs.yml create mode 100644 _docs/README.md create mode 100644 _docs/docs/Makefile create mode 100644 _docs/docs/make.bat create mode 100644 _docs/docs/source/API.rst create mode 100644 _docs/docs/source/DL-Flowchart.png create mode 100644 _docs/docs/source/_static/custom.css create mode 100644 _docs/docs/source/_static/images/DataProfilerDarkLogoLong.png create mode 100644 _docs/docs/source/_static/images/DataProfilerLogoLightTheme.png create mode 100644 _docs/docs/source/_static/images/DataProfilerLogoLightThemeLong.png create mode 100644 _docs/docs/source/_static/images/branching_workflow_diagram.png create mode 100644 _docs/docs/source/_static/images/histogram_example_0.png create mode 100644 _docs/docs/source/_static/images/histogram_example_1.png create mode 100644 _docs/docs/source/_static/images/histogram_example_2.png create mode 100644 _docs/docs/source/_static/images/missing_value_barchart_example_0.png create mode 100644 _docs/docs/source/_static/images/missing_value_matrix_example_0.png create mode 100644 _docs/docs/source/add_new_model_to_data_labeler.nblink create mode 100644 _docs/docs/source/column_name_labeler_example.nblink create mode 100644 _docs/docs/source/conf.py create mode 100644 _docs/docs/source/data_labeling.rst create mode 100644 _docs/docs/source/data_reader.nblink create mode 100644 _docs/docs/source/data_readers.rst create mode 100644 _docs/docs/source/examples.rst create mode 100644 _docs/docs/source/graph_data_demo.nblink create mode 100644 _docs/docs/source/graphs.rst create mode 100644 _docs/docs/source/index.rst create mode 100644 _docs/docs/source/install.rst create mode 100644 _docs/docs/source/labeler.nblink create mode 100644 _docs/docs/source/merge_profile_list.nblink create mode 100644 _docs/docs/source/modules.rst create mode 100644 _docs/docs/source/overview.nblink create mode 100644 _docs/docs/source/popmon_dp_loader_example.nblink create mode 100644 _docs/docs/source/profiler.rst create mode 100644 _docs/docs/source/profiler_example.nblink create mode 100644 _docs/docs/source/regex_labeler_from_scratch.nblink create mode 100644 _docs/docs/source/roadmap.rst create mode 100644 _docs/docs/source/unstructured_profiler_example.nblink create mode 100644 _docs/docs/update_documentation.py create mode 100644 _docs/index.html create mode 100644 _docs/profiler_options.html create mode 100644 _docs/setup.cfg create mode 100644 requirements-docs.txt diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml new file mode 100644 index 000000000..d27bcc0f8 --- /dev/null +++ b/.github/workflows/publish-docs.yml @@ -0,0 +1,41 @@ +# This workflow builds and publishes the latest docs to +# the `gh-pages` branch. +# For more details: https://github.com/marketplace/actions/deploy-to-github-pages +name: Publish docs + +on: + release: + types: [created] + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + defaults: + run: + shell: bash -l {0} + steps: + - uses: actions/checkout@v2 + with: + # fetch all tags so `versioneer` can properly determine current version + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.11' + - name: Install dependencies + run: | + pip install pandoc + pip install -r requirements.txt + pip install -r requirements-ml.txt + pip install -r requirements-reports.txt + + - name: Build + run: | + cd _docs/docs + python update_documentation.py + - name: Publish + uses: JamesIves/github-pages-deploy-action@v4 + with: + branch: gh-pages + folder: docs/build/html diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7d776ea75..666cde4b4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ repos: rev: 22.3.0 hooks: - id: black - exclude: (versioneer.py|dataprofiler/_version.py) + exclude: (versioneer.py|dataprofiler/_version.py|_docs/) types: [file, python] language_version: python3 # Isort: sort import statements @@ -16,6 +16,7 @@ repos: rev: 5.12.0 hooks: - id: isort + exclude: _docs/ language_version: python3 # Flake8: complexity and style checking # https://flake8.pycqa.org/en/latest/user/using-hooks.html @@ -24,7 +25,7 @@ repos: hooks: - id: flake8 additional_dependencies: [flake8-docstrings] - exclude: (^docs/|^dataprofiler/tests/|^.*/__init__.py) + exclude: (^docs/|^dataprofiler/tests/|^.*/__init__.py|_docs/) language_version: python3 # General fixers: format files for white spaces and trailing new lines, warn on debug statements # https://github.com/pre-commit/pre-commit-hooks#hooks-available @@ -32,17 +33,17 @@ repos: rev: v4.0.1 hooks: - id: trailing-whitespace - exclude: (^dataprofiler/tests/data/|^dataprofiler/tests/speed_tests/data/) + exclude: (^dataprofiler/tests/data/|^dataprofiler/tests/speed_tests/data/|_docs/) - id: debug-statements - id: end-of-file-fixer - exclude: (^dataprofiler/tests/data/) + exclude: (^dataprofiler/tests/data/|_docs/) # Mypy: Optional static type checking # https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy rev: v0.982 hooks: - id: mypy - exclude: (^dataprofiler/tests/|^resources/|^examples|venv*/|versioneer.py|dataprofiler/_version.py) + exclude: (^dataprofiler/tests/|^resources/|^examples|venv*/|versioneer.py|dataprofiler/_version.py|_docs/) language_version: python3 additional_dependencies: # Keep up-to-date with the respective requirement files [ @@ -118,12 +119,13 @@ repos: hooks: - id: pyupgrade args: ["--py38-plus"] - exclude: (versioneer.py|dataprofiler/_version.py) + exclude: (versioneer.py|dataprofiler/_version.py| _docs/) # Autoflake - cleanup unused variables and imports - repo: https://github.com/PyCQA/autoflake rev: v2.0.0 hooks: - id: autoflake + exclude: _docs/ args: - "--in-place" - "--ignore-pass-statements" diff --git a/MANIFEST.in b/MANIFEST.in index 1705367f6..e9f8fa9b6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -17,6 +17,16 @@ recursive-include resources *.json recursive-include resources *.pb recursive-include resources *.py -recursive-include dataprofiler/labelers/embeddings/ *.txt +recursive-include dataprofiler/labelers/embeddings *.txt include versioneer.py include dataprofiler/_version.py + +recursive-exclude _docs *.html +recursive-exclude _docs *.cfg +exclude _docs/LICENSE +recursive-exclude _docs *.md +recursive-exclude _docs *.nojekyll +recursive-exclude _docs *.png +recursive-exclude _docs *.py +recursive-exclude _docs *.rst +recursive-exclude _docs Makefile diff --git a/_docs/README.md b/_docs/README.md new file mode 100644 index 000000000..0f925ac58 --- /dev/null +++ b/_docs/README.md @@ -0,0 +1,59 @@ +Visit our [documentation page.](https://capitalone.github.io/DataProfiler) + +### How to properly write documentation: + +#### Packages +In any package directory, overall package comments can be made in the +\_\_init\_\_.py of the directory. At the top of the \_\_init\_\_.py, +include your comments in between triple quotations. + +#### Classes +In any class file, include overall class comments at the top of the file +in between triple quotes and/or in the init function. + +#### Functions +reStructuredText Docstring Format is the standard. Here is an example: + + def format_data(self, predictions, verbose=False): + """ + Formats word level labeling of the Unstructured Data Labeler as you want + + :param predictions: A 2D list of word level predictions/labeling + :type predictions: Dict + :param verbose: A flag to determine verbosity + :type verbose: Bool + :return: JSON structure containing specified formatted output + :rtype: JSON + + :Example: + Look at this test. Don't forget the double colons to make a code block:: + This is a codeblock + Type example code here + """ + +### How to update the documentation: + + +1. Set up your local environment +```bash +# install sphinx requirements +# install the requirements from the feature branch +pip install pandoc && +pip install -r requirements.txt && +pip install -r requirements-ml.txt && +pip install -r requirements-reports.txt && +pip install -r requirements-docs.txt && +pip install -e . + +``` +2. And finally, from the root of `DataProfiler`, run the following commands to generate the sphinx documentation: +```bash +cd _docs/docs +python update_documentation.py + +``` + +3. View new docs +```bash +open index.html +``` diff --git a/_docs/docs/Makefile b/_docs/docs/Makefile new file mode 100644 index 000000000..81ca02cf5 --- /dev/null +++ b/_docs/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = buildcode + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/_docs/docs/make.bat b/_docs/docs/make.bat new file mode 100644 index 000000000..6247f7e23 --- /dev/null +++ b/_docs/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/_docs/docs/source/API.rst b/_docs/docs/source/API.rst new file mode 100644 index 000000000..fdbf2242b --- /dev/null +++ b/_docs/docs/source/API.rst @@ -0,0 +1,16 @@ +.. _API: + +API +*** + +The API is split into 4 main components: Profilers, Labelers, Data Readers, and +Validators. + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + dataprofiler.data_readers + dataprofiler.profilers + dataprofiler.labelers + dataprofiler.validators \ No newline at end of file diff --git a/_docs/docs/source/DL-Flowchart.png b/_docs/docs/source/DL-Flowchart.png new file mode 100644 index 0000000000000000000000000000000000000000..696eeb5dc8e5b8d10dcb1afd7d6f165301904cb6 GIT binary patch literal 7609 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�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 I($M#R0n&7#*8l(j literal 0 HcmV?d00001 diff --git a/_docs/docs/source/_static/images/DataProfilerLogoLightThemeLong.png b/_docs/docs/source/_static/images/DataProfilerLogoLightThemeLong.png new file mode 100644 index 0000000000000000000000000000000000000000..ca86fe167d7197e3bb8ccadce91aaae376f27de8 GIT binary patch literal 177437 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%0A=ay5NB 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 r6akxWxj%7T)KQ8?CD{ z=4Rd}PDXF%J1m?qWEYY6mx9cEOch_{y+`xqR03t&*iUdH-HA6`7Y4B@{}$Xj{keieF3X z0M)*>Ut6nO6m72-)1bURdx-QlU($`^58R6WYHR&L5e-(L3LXEIle$!6fuSXs3ePOi zRex^aFY-WiPA6B_yfyx-mfEH|4Dd+!>0+4Bx#<*hp#VVQSU)G>BsQN8YyB-EN*akU9AI5dY+#9<;ERbsjPV4~5~CseL>O5gTm8o`!m(PRVZOjH*{~*6hfvKP?Klus* zGvUSTpiYoy#J7i6aeRG(N)7%?SSe_h6&dm(eS#XRL2TG1$Xd~|mw|jfiE615Y0))V zp>W~{2XUD_=_o@7UgyD&%xE~zmkPAEL(Q)&`}uT zIgy;2!M@~7M4KU+va6sQK4e*#e+-)xMH2p*O_l0=7<3ax%Y_=DPAM*p;5$ z_}GtzBXOfrYP@_C7!j)eQkS%26=jWxHtx_llCkNArQmq9v0`TC=OlDpDYR^gi_J#U z+RB%nl4L~VJ$4x-t*R(u2qsxQk;D!Oq#E}s6eL}K{4!csSE&-`5oNs+tANull7DVE z9cWlMK?S{Ub-0KR(AM@}@Sk+#pqtcI8~3fa_H1dH)Gu0<*{5$355jBOb67r7Rd_kS z?Xhroe%ScTp4XHL7AeI8mVnli>`HYX62<=X9-;OKwt2Kn7oAQ|QmBf?Po>{eTyw zA?ARFRhnhlVawl#1{U~p2#59dF;Ik{YYZj*1B=ZLp#fvwP&mM14YYCXDPB5mk<*f|ac zapaV+RHA>#Mq^+ag`V;XM+09pUQh-9R0SnZ}IapAXfNLiQ!mZgGL!nxQ9 ze;%L_-7FoqZlOMUzrh-#c5YS1M%oU>)WME(F0vNe6W2z&YUs7eF+%aBK_>b@8iF`s zJS`|>9-(Mqfzw^>!6h*@U{Q(ZspWzbut>vY(jOD>8J0aGt7Upnr8o{$sBr&r; ziQGIwc`r7SxtBiAQ*)ISty_BD!Z{)CbZZo9n(2GD2Od(zy8LTzI1RV3-o*_h49>^d zidk2));ym@9APqNO6NbKYTuLk@uXTC|Jrp{Lj$xH?$Y#q^WxiVqdY+9kmVO8Gb%N? zdpebjQMayNxKno0ZfK`>eELsl5(GTD?#j`G$<(466e0Ez-sh&DEW9O_ykEv$HfT*C zZdl}>VdSe)Iusa#M*UAe>i5aif3sg_UL`UYq7+7JAq~QI{;}st>$Desjh|R)0b=bb zR{{i7%0_&($~I`m(HDT5p-e0oHdP{U1t|2Z@ebQvNrR1Qf9+@zY{xrRwcBX4Bv~x4 zB(71k5}|@YV-2OtPcHyv;{W>sD3}-1-Agk_ueYjn#}a|`A77ck<%{O4El(ED)8NeV zN4fT8^r=rDsLJsR>2J)8|Jbq(+=zg@Z@@uba;o}NsuO1B57m--sf|DP5>Zslezdu0cRSUMx+WGGM$ujL?wydn5> zh^Snb-qARtJ@f%z4Q*I85(@|m6tcw_YJ90(RbK_qR-%5)kz{izS>#XhEeD}(cuWjD z7qK7EmfSZY{iNV^Kw_!HFHJM-Mu|&Zd|qv?DnDuspNqQL_LF-JSEm5ri2E1_wF_y=d>*gn=JZ?_3R13?_MN0w-yM6{EW^SVVC5=HTcF#2f$6>48oS)tUkxjJk)(9IX2?_~E4^dl2&b zgbp)|{b~vmUerD(=7US5K~c;azSjd$y-AFc?*}RgOcOdSq8>T)rCu%o73IBW=_~!% z?$ygX8`-fu=N|k(@7@l+h?EVQE%$M%`yRC* z3}FwM7u?Dbn_YF}4v?5I>}iYPdTbL+xp(9zd8{(NXu@cYD4RBN1r?vU&|LPhbN<5d z;Hg4$dOz_G zDu;TKyrZ@ zF;!IrIKuEKET4Qbo66*cid2{cZs_TYkzslvIWn8rp=OCzQ&2dxg1MsEsar$!U#vNm zz87SQs9788wv(O>R*#?J|E$!O@=jM|3%6mUI5KkF!SYSlB7b`5PJ(fCSH8AiA2gq@ zNRJJF;6)Quy{8mi>0TjGj_4not(>XxqAeC@nba zt$=-DgB7Jg`CNdGtBUaDxC|`px;0t32$CmT8HU)A9KU<>C+skw?Rv571ij0k@v7On zQr~?3SLmVsWOUxY#H5F_hB+$eubI4PaaX}bF}Nc;o^LP38YIjb!4q6U*f2!mX_uJ?M`R zdNN4gx)B>lpR0(6Q;J{OfuKQ6%)DvEBf$f`!uHQe8aaQbZm+Ua* zRDcA@e1o@xm%4Rz5V*fLXr~wDLiGq+@j@om-*U#S!E#PMLunok(QSLRU&JO(B%elj?5q>drB#T=`2_-q z=;&+%qFWF|S;fDSw~~^TiijOqS+>iD-9Yk;a@bJS^zKy)?6K|l^u`H*H(NLN`%s>a z`Z^U3mMo6()e`|$)d${VsT=E|x1s1tnb~4<2&$iR(8pyZ|B~{Aru6Tm%1p5=d!)bjE z^lt2VrTg%Z*>Vzmwsc_k2*vi}s{4*b;|JULo*xAkzn({>D;E3aT@yrjd+FkRtgY>y&(j%>dm)!+N-ICNgA4s7VWD3V`S> zGV%p1oH@UK0s>IHK0T}*J8s?i?6pE-GF1xAF*_F-F6tNFrkPHh)9b}2zis58wtGx6 zfRt6%SnW3-RAq>IUhXa%5;n3#{Jv$@RO*0Kmif2wW&+rgCKM`f`;DDU4_9fh@8j2z z)Fs&YfnPjY=%~cfn$Vpo{Wa zwVe!?*#Q^*Wb->_np_J^(eEag@E*#{(r+F%7&%Uj>P z1g+bDMQxhicSP1z0?u_*FbgqE@M1<2t$;!YH#z3@!Qn4}bhhL)wv3(WwgM6FjiMmy z9m|6ai9;QSvY<0sCD6xvkf_W4w2KzddUP<#+k9%V2BgxQzW8*9x{1+W#6PuvOD2M; zbI#t2Ndpc8d2P*OA$-K$(d)OV=-#plf7sl!)BT?JksbeE5gSCfeB@J9F0TzvOr^yO zRWxM@L(DjGV-kRPuZ_J&)f$nz?63NM zJGknW<@3?F&)4||iAZleuibhMykpHJ=yP{T&*^)au!gd9IX_R9>35$y*XP%~T<-BB zG4!p|3kkd#F6))fErTpRn-;&dC3r!Q#PvGk=XktJ(>>qM! z=kdsQp6&dci4=$_=8jOj9DWehmz7!BPoyJl3$o-HwkdEh$+gmOkG9)MM^}C?+2&j^ zeNO!kl*cU3swF@}I$X-%Z!GE?Mo&k-j z`1NM1B>4gD)PwMZyLIkV@LM{nIz_-dAPY(WPWyLr@tFC^(EbZ8(#OMXXD9iue15$< zxzE#S0$I2+5B7!|39qh@oej3D&ANz>N(>j24RhjJ^oD10JTS$&K z)NVLGla$}6rR&&p4ZU!rjO(p!0^FV52OkliWnuHIsg1m9W6CA#D$tvC!6Vpi2H!42 zA=AX|k5|*5AXRM=xkEIe1G7?u z33)g}9)7<4i`f65-~T7(x?H=X8br=RMEi8AWFkV`pz;Z{(vr=z2zhTl?}g(9XmbBw zgIgK_DmW9%ezi<-?(Fn*#06Eh#ArWk@U)cJ`FdO;Ce+A z4uM@m)%Gws)N4_+d{-14C*8I+vUXVN5Polmqa%8BME-Pu=eA)(C%1pM@(Kg03iyt>&z{pF&Cwu??2wGg1r-S*Tmb| zA7AwRtjJ(v&RZ=0P0jEFE*tb^WpowyaZVAU`?dP5)$M7L?88x6?mGsUOq7pp7=a(R(4pBmjAlAKQb_UOE?UD5oM z?{87F?N*mz{*PMFe}UK>LWf*Xfx61{jc9(R-wy{ckH`8XJ;wpVIgF#{vF#^RHffm^ zpfUkaX!1x+>$taAI;%*+WVxXhJ!@hV3qWy;y;h`i;b1^hqxpU)RNGaLH1Hf>yTKgg zpcoEek`PI9i1)km+sqCE{r?3>JUM^AlXm#EAwF#SU(gwC(@~`HuruoZi&2N0i*6B3fJo>rJT1<_)ub1aw=c>%c-4UxnFUK(vlkZI!;fQMX( z-CU>n$JlMb=7wux3%@Y>CRK|XA6>5Obz%q6{4)Gn*O#U!+?dK;VsN6Gg4XXhvTOf$ zTx1~L3eLF$4hcile2a0c*zgje?zlCepfS45=jXbJdWt0E>*#6M-)Lp6hp^aX9`F!1 zC=qjmr)r?_0r3kBPVEG_uP6!w{zEy{K^UB%mz~N&1%Jh9?4v}HlAOv^M4>hLR`=9% zT>UNi58xU?SS8RFz^aeNwfuwqo;hR5Ndug@%{9>*Q-19aSF`$pSHn{((Ji~V=vo1| zGea~w~j2qF`tEkh$r;Ft;9*0h4c}{H_ycn*`oM9B=zH?_&U;|cI zD$`ppwCpj)liHgVYd}e)h3KSK(6{OiDvjJrMh?iRAvgsk_rm_5Q1M(=G_33|uhg?X z^GMW*13Zey6mZ&Y8t6Bb!z2n&QR!U`^2B^=*6_k22t~10K|hx;bsX>t>1E~YRY zgK_`4Z|85;1=DMlk^{R~SW?8DNq<7h|2@Z3+6r7~45#$_qe<3L!KbDqO_O-k7c?>O zI3#gD6WgA~$V}`35GFu9BQpk;SihUfapd(ID$pMgGiH?_w%>9z?-@I%s&o?!p&lV-ha`?Tup-iYiP1`7wNPLNc_}TS*mxwkyyqs~k)+Uf9$OV@)+$l3h63 zz=7TN(e21(Zlvv~URUsVrQ+U$D>>YB&&yZ#YQ`b!+L%?*XCg#)!|l`jC*n_SUl;rA z-A}4S%#=%L0NB`P8z}jeZO%jSEwVJdwcotqd~)&YdE#s(Qg!or!P--%Et_wCUH6%ljq!q z+QA+dBMsQ%hJMgCIHIXri7f;?xU^a+h!1ZNv_$`zvu}N3>=;7>VXbu!WzqE9ZX&F{_d)0!6C5Cv^~Yve z4Y21&BRv^(Ne7BZUyK6Q^NoV}|2w@E5O39QjZwAAw*%!L+b~eMMI@4L5gqYNKw-BC zK<*3}zvKN|J(r;om97jJ4()e|fYUlALlTB_4vJUZN= zD~j&4NHJv>-w2?xk;#0e=;CF`o~kB`U^uN0EkG3)^4VoZgS98euQRte!rml7gZQiW zXh#_IpO~29dUVF;i_lrx0W;$+>7E+^?Iv;6dtj&6s9e?yjB=I)5}ohS6>a+pZP zf53txK(lEX78nd3hUC0~eOSaq+inzOFmpho7@`6=8<lZNwGV7oDE6#OS+etaz{BEF5pI$HhPDj(@tOq&K>_6&Z%OAWb zTqD1axC@JqbEIIT)}IiN0R|l;%pp(Z;qyh`VLo>wW6^Jq|HcpWLK=l)#Z{0~*nuAG zC)NEsP%`1k6^sSd-qng_li>fM>@A?8?7OaUI;2IUTS1YO&Y=W@P*EBIN9pdIp+RYp zZV(Vbx;uyN?q=w&A!fb{@B4ZG-}isxx!<)|vu0h)S}?!d=bU}^#!J1aM~{3Gf|fd= zN4$yaN;tgJ%h<98AQ-%R%_d=`TW4EGFso(MB=LmY1UrtioTz{?M94 zF&I4#nhh~=iDxCHZZI7`y^DGCvfz1MYY187Topx?Mb#Ta?w1Xh`=e?q%0z(J;X=6E z^@b9ayr9qoOr&Kv^h`LSuvoHXeA9FUr*>TTSO4r|Qov`d0lfv2Hu#iJibOK(4o7$$ zoCKqDCpwJB~iNr3Srq71aKtQ(BeBC+rN&z@`2LCk9qB|vAbQu1(~rb^bw^dO;B6Cb@Qe(D_q|x6Mj)egXEzG7Y|+<>6?6xS%WqQxx-v3s~y% zXjoqj1OgX2U^W=3h+_piZ$~<)_{dcKlvwLG6BjD~ZMyjKupLv&KLbvIp}A)9J2PB# zJsWXM+4d(tXWO$~_#9g)f~eAr7)iX*NQ-oBC4ttSSerMYZTUZc{Ophh{7YKc{-J0E z=AEf&ShXjsY;KPhc154rCmm*aiys)3n@X2ESzQ(amai1hR*c3!xbL1G$Lf0^Vot|* z!97HmlMXB`JM$J(p5DiBGJ`rpecT(yHb(}^a7B80R4U}sG?q17;^^`3cX0$-9l+S| z-Cg`8O3v&o7v_6SSHj|F-Fn3zhSQMnCw&L}oo6h( zxCp!U1bt~0KP9iua%C?ZCLXynKy4X8B0s>6CiAC>K%2RV@-vVBfh(oP+BG`MgarD0 zD&pIPRKy$;E7R?*Np>4y#*4c27U^IT_Wxvk@RXAA@r+xasIa}Y)0@W7w-efzY}6dL z7s-A6rpfH%T7n(r6- zIx}N3)5_tSll#CvP@H}mPX zcYvRim+A;gTCgrf%rfyEEp+XJFQM0ouLQ9cVdQNP102tc=txNrP7A!zL*_D-lzIT& z$KK=30Wolk>&u!<_8SM>PJk$u*czSl4(St4M6N@lwHP=&-qtz=ohMW%uDfmEkQS4e z%J2evTTET_R*dPV5ytJ23gW4~K3bcCX`ZS^#GhgX_Pg{xefH=ywOF>N@VeaXRA~;? zgc)wpfLOmVJZNKdd1zl|o0*wBiF`EH^F6#+@XU9kzc8VEST{>$bw4JYOcb|1~ zky7)HUYfkV0#1=-CTZW5aOS!JU3>)js&wZtK;*qnytMD!jnH8xXTF^eOVUL`Hw&xl zi^KT&diRlpmfpg^k>f}f(#}l}@xwjvh3A70ZQ_Qr7o*eLCq@tc)P7844FI388H>6@ z7>{y_gs9UExJ>Qcm9(pC=-Rm!g`GE7a`0ATs%6a!vq?D;{i#xT0=uYOPJaGZM>O!S znqBS&cUunM1r^i&-&(Dr=1py?<->f05Ds(DjS+>gEWgob(Wq~R*~M5FeA|o zS_@?jgO5_cpWO^}AO%WGmgv#9z@azHv@*Zu4y9TtIjwzX2@p6ez`qVKGm|F5`jq2% znM=>6&EczX&7?wEG<`#HR)@ zVM$+@hs;>&CE37E?0n9-*)A0S1fhcGuK^Dt~^8KVe{q|3zx$fqLk6Kum-=s1p!MyKk=bTsI7a zZ)zfP=jq*LqE)sgRdAabK+#>>f3x}Z=-eB~*Z}L}&k{-FYc-3gXL6Sl3Vg7+&-boU zFAQ4giQ$UY5}S14^I~u1J=P!c1~6}tXhdaD98uB|TtA-9_rZx@0_q4|FsIfH z`L=@Q^6DUea>m;3o1>JB)%{~XXI z8`T%LYDgZmgV}N>C&Y8%NlFBX$a{I~n;1|&u(36WEN{&?JoUvP`UUIizzbS+H594r zO_PC#g7)iV=;L@pjjtwjU=urg$PaiHP$lG#w0s^yhvj338PHs7X>|QX_M7*(zoVeEAe@5 z2hNL6tyG~WajBe3t7{l|3o2(VwjGsGH}ImH6vHH}{Da0JfR~#z?Y}{;v@Vty zYo=5Ldc=Z^*rhXC$)mhP-(iGvhfQZ`L@d*FDA!-x`ZWZ@uRjsYmA9>IL08 z|MOw}4CTA_W915X_Y9wUsozsh*2?X~nmO)Eh`Es7>01`)M{8FZ5$;oC2Ijn6c`>iB zVcH@}S*RGtUIBVf5j7be`^|A)$C( z&!s)(X>--1wd}FfO)4f5KD5{_&f-fhu8?D}qfkWiJm(^Wk8h3ULau=neSIBmxuK+9 zY67z3MZpu3${|SKo*`}P+9%?KRkI_W6D0IQpBtqBm=pUm+zGS_?Pqc<*`XU-#pnFYc!>xkm<|GxZx0`09+Bw|Y(Hy*C`?(DXO z!{HXoabmTf#fie<)9o;qC%#dNS;9cf;D&uq|WCmxej{XjiDSl^|B|{ z;#_oXzhs+RAnuBuaGjwqOmjLDsOIGq)Nd5LOE7nyT&I3gEjBvgQ4;NBTc!(JW>_!% zEfQ(<34E~t$r#H|=`dsMWh?oB)AgPWovPncwN-S~YG(?Vt8csF8XCgHliT-d9dYb; zoCyiTF2X{f`XAi)QJD($l|YU($@VUXeSGdWp}&p}me(E_9vcE=cA?}2oaJnv2-p)p zE)dAFa;F5h_Q|o4GkKsX9O8IHE#^e3aET%5m}7HQ%p$#~b*F%A21h3J_J#2s!QaR$ zC>RY2KD737PdeBz^ z?#)6TbjnhhYP`D}@<`L(D10Hx%2+NVZ=AO+HB9~vrt+}u%7N>+#G&n0hCbIvzMvqmtbI_!2C zJ3nm|)?aWRv&qu*czv!rO|s^k!7)zgWg}@xW*1qHc)WAz zembV1u{~3{Z!B}O`mZ+FBl1NKlRVjRzkD1moD%u418l(tvhMdd8Ao!flZ9b0T*q5j zG^Pk(uFK1JTz{i2AWaHFN5Zr*Wx+T+l1n*;a_2^Vsa~OCQnlIXGZuI#qu{;GRP=bP zbnhg}0;77W+dCV$O8`2uN!=VK#tJ1^zT<`?B8%yjtjoaCJOR=E1qNs8%`^W2?97h& z0l1GE6L`*b=QictE#pOU1a>rn%xbGM=~t!@hCU8y^{c+w`$fX*?oOivs@^*nF)vvz z{&PT!VDMgQIc5?G(|sb5lS|6jNR@_asivj)98~ly*!6I!g-c#f%0wIRDjMA|Psl2f zn;haWI+pU8wWRa8w$7(?n2I^iLoz5jM7qAuUbraf_l3a%@;s$nlTGa#=1r&b87tx| zO_tbr#gazK(~nQy*YF%K|C)<+Gt0GxhtJ!z5+T%|w~L)DkyHhYCrdi_e{a;c#fHq* z_J2|=Ay5wdNO^eG#MIeth*7zop-l7O>n1YX?jU}=;1IRul{*oZ{rz&;BW`M zVQrIL)hw&eEC)a?NMJ`C8E4=7dt(8kId~tK0~+{`-&Gz-U9PWbghu5qTJ939n~1Rg zHQY=XzsVNsmuZ2sD)aUTdH2{`GjyFdcXxfd)pgeZIg8fzKuqN@Kh@>j-C4|hcrJ;c z^w%)=>r!CYkC@RU)tvjM;MZ_p5|D%2gLikwDMkC=@cM73+JxrwIu~}dM63fGcR)8H zkil)E^I_}UsfL%n?AsTJzNQEGvz%fn{^4+&Z;A@NckN9fbrdKn@+IzG zx_47JmU&RSqYYmvm#fXhoW;cQhTo0`!+4pkuECVqY#yk!Lbm=S2w5UB^+jg?_MH97 ztML~(Pn@PcQKfkXJDng6*Lzj10MyOBqd5ZK%eK5}U?pHg88yXO+-XFSFd~<;HS`?E z3M2c-8x;O90RBRs|M^v#7VAPJF%M}Y$oL1*-*OWE3gTp&w8aJRxjEA|;aZ97V76sy zI*)+?l~Ma1{X*~e^f&#?3-9*lFD3Hed?tfwH4E44!l!xpB`;gA5y#>K@%%a4cVBT1 z0eY(bb6Zf8lPssrhcw(jBMQ$jQ_a4gWuyr)6|9RS%*GnSPGkNnmpxH}0;7ad~Q zMJR{~jgQ7kkof#~Zv$lx%GCktU4Dcc5<%HNWs*t6-TCs}I;O7u=?r3^G@<5)T2+iK z_RMyhu6b36OV@>ZV$s1CFBiOAC$NVh8@wJjF=gYCLNVboR+lSmI(`z(K#OYLzz(J~ zaD^7?>@-xL(I%k++%)s!^-tp)?iFZaiwExxS*>7`SfT<=H2{dSIj zhoW}kmNdKJ$o*r@Ek%&_#r)4Vpsley$_1=H^~Hb9?SD-2fBnXrm@LRKOH_wkDSxCB zhg+;&g_c4EhI@R-O}s*_!{!X@pPK2M6$`$9Y1TdTb8SpRUvCenrEMYr!%mBX!wyF4 zqjq?zH8CWy$)w;40G8f?nVXZ^i^w!0<~4YZj(Rk?)MTl7SCPKNoCopYg}%&3&m-un0T)n4s>KasF5 zN_L?!x}2SeiXb6dpv8bVMIk}jkR(xwMuHVzUzzPAS+zI;oo!6I)Cckj_LcXbKYbZm)YrP_uBp)Y+BlasGK<&@Epi{cUa< z5xJpF{b{WD-a&T{Ps3>UX)NmEd_qTY4~4u;6tp*LeF#*bMMW6&b2;Dh{Jn$z>%slM z=fHcF^pVd{QYu>|%w`-fD1fKzC*HteCzXYO@r%!@+FC=vmmAz_fX zSfv0gG~s~4EUkjpY!i%zOeALfS9=Mc3^O<*IIyuVYNkj;LxpPbSMJe`GzDs!0V=mw zy`2TQxun07`Qsqtz&DfSOp}?o`@vxQ&nzu|Vwk-Syo)$eG-NhD!ijQS*`^?R?) z(HB)%NC0<7hVPT!uj$&)x-!z!m&S6{a`qbMcp$dtZCz2y)az2<%V}bLD>+B&Ru=S! zLnz@nhZWn_K$1oaK+8N)`yOfcA5W#fz~{et1#;GH4V)Bx$6y@S$zF>|C?y*tPekWd%(6%`Vxy@8A+qdjZt z3b>cp*iF)@6MkWgK6FufxwG7OW7&elJX^rWu@5dqdq3=r@ZnHyUMyOY!u*_=O%XRV zNVsZdCgj6M$glA3Y*KSI!LJH0j<}hPLsi4u-R{U8dSkeh#9i^m0x&H7w9*+s*~tGr zxGc4KyddK7+uSJvxFfBo@#RCM_gz*1Kxu>*03?uvIiGtLRR(14eGmYu(m^in-zDAc_8K8-_Rhr!1 zFKQ)8gkI+6SmAh9HHCivI{O)5G`>q&SBzIU$(-nbF?{icJ?I^uODf&vN0%^at$wSA z#uWMtuFFO-wS3JX2&l7#5#yB&K~iw=M<6u5I__dUK1+vy~v))K50c^>)F9_5OxhF8=8TVMD*%j{qDm;VnF{3~Yv&rkeG0f~fy;vtV5 z;?tlw7&iG zxk{2zvki2dpYEb=m@2Q$C%Y#YBpEt3R&|hMFMz|JYLyj;vVANaP7PAdW=ZH^f3eD7 zxg4meVUU=yYn-TK1_D|3oEaZP>eMXO6e-T(9P$@Z?D1OB-nu#I4TxSP@p!!V6u;)% zpM`m2Cxi66w^2R>+%ANk@2t(!{_vvyj+_7UmH+=fSyfF_L%z^fF;u5}O1{Y}&{S7b zoW~nORVE-U2DWKRmc%2hBJH4JkISDEC7;U9^-%MTi3hsJ$dQ0>e20CwByv&}FQ@#B zJht?W?UblF_Q0rtEb+V>`p)ud;ZeK(%D~S;^}__QEe1_=4Y@5I|e$@5K$-bwfb+&XQp=Un+$zvcDVLol2xm}*R zLD6!Dk+YEq-VvoMQ^SoJ>rkTRc9*y&>L{ql_w$*rA3P)U0^9}^b%YpimNrxw8P0gc ztCsgbj6l5p(ifLxo_x$R!ZGHrO!Yt6PNd!*`1h>WXs2o8rZve$!LHt58iPrG*k#kR z44DAO^|JFsY3r0Fj64HeU%!)PfK|6z+`%w2E>w4VR@(JrIkWNE!epbJl=U4G8z&u#Fr$l3PKkwTMsT<) ztfMZ`C7918YNtWh><#4%XBh?R=Ax3zvi2qnZ+OTc>=519s!}s_G`Nd$WwBHTw2+g>t zkW5Pwm;uAuD=B5MslyT7^;iS3yx$SQ=q1`AD1lS~-JIk?FIpLieTv@@-y8UaajpO= zs!=H_&C4>hKH*_05@kygH|I9i+34p>;ZMo%)EqJYfiW`|#^Jd8ZO<(FaY(}*6VQmk zuBfpe9tSVCZVluO-07Yk-y1j1%GpfR3CePSM)e0ov_oRG=zwnnpV&i}(f~Iy z-1I!?Zb&NIIW*7Szmi97wH=LG)k>P! z9(l%6Qne1KPx)J-tCQ75braK@QZZR({=OKYYd(lZ3v&sv)cZL} zt-!a*%BR~VzqihTP|T{@%j-d_alR$p9Y`R zm5U+8ocEGy_G-3~c$k?3ER>Ecbvyh{%=D*)eDAW`=`=!G!=7YKSr>eSvm_o`b3$y# z+YHUvmZ)jIFxyg81++Wr@nqhonf7Bx9se-Rq9?rX?+s3*!bwA9)u4J41oQU7#P>w*`0Hc;ojLjU za}VG-Zzu8~&n!_exAYSXF>`T)n@MfoOkN4Mn(7BsMD|am7#VPAjSl~)L^sji|8c~sE6cfTT_nOZCEfwsxy~{qwkR`*n8I61%L_Vm z?prjU-x$zmg|9ZE`8bdK6Eddvb3 z@6WF7a$*!VGhTu({ciSYUBY~&%nmzhK)Ov|#_GFm?kmM0DjNOW{ATM!eFXat*yx-d z|D?LeyEeiPYV3HMxMH2^d8R_|IvQEq^7BzK4TtYQNp|tm1ifc{oKKB=GeVGpzgt9W zEvUrAGhP9{Nz52$x{-a`=7rwZozJ(V>eC7mEuEaMh|sMb^_8VQ**p9pgZp#6JB^v1 zYHY0URlcFd{(L>IzNpJVoC#F@D>6~iU40H4Xmv3tv$}0M`iIwPkhBigNB#s~L;qs- zB5ax{beH0D9Lk}Q$T%TlwV@pr2Q3(7@z~Se#_v)k)jK750lg`bGxupNe;T$es!xYs zOc`4W;cy-MxGe95%(b@z`o17st+2ec!^)Fk$+xkn8%D)e11kmM7G!M=yz)}!b5 zA(JvmD0LPen*iV8*mTXi9EY4X&y=zA`!LrPvOvb-V}K5@=DYJdd5-Au`3<}qNQg6> zPX(me9sSdB07eYREqoMGTp@JZXo)tV3NUqqiY+@D_ab(_IAby2(q6@3${C5m*7I9H zZEnQKzhYssp?E1p{~kuVAi6PY8}RML+m;#WUB~q^SN6X?;Z7_81byZw?>%pkHJEIN z3S2!6=vIjx+z4(>&UP4WWDBE4vEA>F6CB;~Um6xDOuGwfeJ?y0xAoTLs=1e{ml=0} zyd!w)?H4`MFiiuI^Qqfd>Sg7_i+FYTWJ4OtGi@&R2zk6Kyda?Kx)$wjG$F0{-!1R| z;`!jyTb*KFcPqjtnrVU+yy#YEvneGy1lT*>iReTqApvH>-SRlK~MuawUrg?^Eqc#ddLOYHK%!Iz0kMnawBVR zHW^lvowaG%Jkcs?)YH1i39kuBC)J0meH#(eRKf9n_zRg!!={G;X zw#*p&Q0dqYNfw!+LN0xR6Lm*NJ=}@i<7yHCP39Q8k%CT&(zyGm-afQ4x#86bUBm>i z0Dfy)7Rvo{F7Tk8{jz)(cQ_k^?E$gZ!;3n!b4%qJ~Y=``2~I*f=L-~E!^P* z?z_)|{^jW7-Nrp2R{#o)=B~R@QeMH_Tk;BSBNPno$4bN#2}=c)-r|G+Y8X{uGPRr0 zN((+-$Cwn7yWzt6yv4vO#M<%hIZxezYz_C$vk|No{ z?%?D?|D!vR5mV1ZN;v$5_RqOKQJEV-MYxmG_=g5=5}i%{ z!d*>9Q4zZ(h4q(aa_V{nW}q~YI2dX3+tMj9DM)(`8e@OW1FiO}XsCq*n^TgWYW1`1 z7Mm#0$J*X^kmvng6j0yv`>=(yW1K9ZS(}?oWnc1!;+wSsqmU&9T@+zyY%TqY1TV~v zjSlxhA9tIl;DE~-`{xsAmOSFQ$@8Q_;r+pSE5G%fr0IhWu87xHk>&Y|o|4qb} zBK;<0-Q=Nx@$cX4&UeIj)l-V27w?HH5%em#@BOG1T7b0v{Gm9aerwmCCgr5IcWBMdZ1!C|`1}o=Vk+ zp4=;`5uN#gPYma8s^tc4r47xDWmq-e z5!ZQ?++-)oXT)`e=i)1m-8GE~=wUmh`(;TP<^P=-`k&u>$KVaJF+nJk`vMkd+R~}S zqf!KM_XsLq==ybr9d83fNk-upS3Hf^cJ;jU$axvQ=?KqcjFA`GV3R-M&{J~^DFjyfHYaidI+{Z zAI-rnQ?W*$1*UD}2NS5a%xaf0_}P4&ucc^J_J9sZLc7m}RWgbYs$;eb&R}U~Qgn1Umcce*OdnjK`vWwo8kdC6i*%B-EC^>0$h6A{%-hO`A%*&$S9}UeGv#@k+(lr+xUqE$Q75M{W`<+0>ICH? zVa25Vv*vX6paHe!AL7?9>`zZm=ftNW6`}_51WiSyXk11Y;B_EmZyfJf0MfaF^b^hC z>RA16;h`S{U;4g`TYoXidZ2Tc%!^nbd5vP+;$F+{{iqlO3J0&)oha zQ~XbEG2k;2-jf;$D|8}Ug!$+=?4`R{H9SRK^S#cA@7R9LV2Q&DOYN7Hzp*hJ94^EB z-{^R;Ia(=R(bGRDm#XdazZ+NA)~~;I^?@Av?PvL+^Po3w7GUGG?P>VnlT_KJqFl!L zjJ37cFcoY3!HM#G*DET&7QmsHLuAa8pq0--8Nl*oDKj-pKR_?^+iR4xCC2n23HkZ*&5P2H_vUFWLwLH`7612_bXLR*4$mw@i<~-q7xqXxoN@#`}KR)jD&%Upz=tqdg80F8tcNU!zR~r z5JJVMe|AqDRT>i0Gtiqb;yFL4xNvjUO-r(4GNnY~+thEN#=OgpOEbtu=f@U3j4SpNaH<0C!^s9v&UO9R^04$tsPF%a_nP2xLkm7xLloz zLP1W4eqGMX?%6U3YHiJ84`ldvYYdh(9tLrQN;XfGO)T$RoE2~C$F=&vN@jg2Vx1=o zu|4kUdTFV8Y`L%kq(}5FND499NL*NUH2`!7f_`?3I6(zJJ!(4dN$ zR5D>jGj<*yY^D-s3V~tus}rA*h#1@jcdiXTO;?o#>8*Yzdfs30DwdnEV9tFvjSRay zweO+Q^76c!Z+*wgIdR>LYus6WH;=)!>*BJ${mTAolxo7)J?NCK#ruk8c9rzkKmARC zlOMK0*HJ2hB@E-t5x%*@?UM= zbuF#V7m#O*keiCiG5+MmOCL+)<6YQBc-=lqsb6A>QOkA4Ajf2*^8mKPbFB@by)N^Zf*TjW#X<74%W~Y>r3T(l%0O-B2NMjm|Po7 zXDsTKEq0yPxx#z|DT@@S$Gw_p+5O@;d#f(;Jis3wAOoZw!yCOZakJeD=W1VS#QQeb zj4KGltbnwWskxM*Wx|VN?A_Yi+Fku7WIEh2#q;u7Z6nU&1Md8sYY^oL6R~Q(V$=r{ zx@!d{9l5R*51*yxrU|w@75pfv#WVgeN;}A7z3#%UIl#U%FCB4|YpA7C<`M8IcK=J< zYjVLTGo_roaW8@Zdo>k_L!N>6!#Bo2^*DFNs@AgBiA4I@-x?49GdBA3+nF_`ums9J$9XOxC?e;LcmtUU;Fge zXfat2g|U9QUelv;K+1}&`u2Ky(c+n0b;WezBYAf(>e-4td%=EjHk?=M%VM=ci4pMY zw+61m+7ia|w)Uwm>ooc%an^B>T&d;DCC=khE)By49#s8&pZ370TBE}qS8T{H!I8zD z1NQ}p8pM3pc}-k%GF=EZ$)gtiq|a5V@n+XLeEQdZ43gJezu<~dYRK({`m?_}i2vb+ z3cCeJc9ShtO$DthEv6P|a1BNKaa$=~kuoFF*pO02G^kNjVC! z39=z{6+7mN%@G#q${>GX-15GmIbz|09HmVQ1!#y+vsNM@5kiH+E_ErbZYH=_>+~jO zsobmW4e!Cuu7ng@M^Ry9ABPnooLc^)gi)8kUXzP!Tu$Qobf@`Ket6l31};1u4XJLt zo=V&Xj#*=)KIJ}IzN2Z0ypI`~Apt%!;VsINuSIFdvWxGg*v7w$mEHQ5CO{qr+Pfgr zIu+z3B%V#`wz`=9p3|9_p3J_;MsoB35qq#-<@zeYW!GUA!HGL_26M=H(((Js6HJ!qjVI-I%y#QxDY-7Y& zQbW1t_w0EpP}_5;e7T-o^B1M&pG2hJ18{Z(eT|RSX=H=$lUM$S)?`TI-|s$jJEnofeyvd9g-` z-rX==IZ`vEznszlQA_s8KS|Ur4Sjz8+yaFP5*LUvYO$Eg66}UK%RF4E>Ws4IS z%z^zf!5k{JR?2V|gR7riFs+fmT5^s{Ea65Y`NP<)JM`h1ip)7QF}^GO!@6ln$a)XC zO@%~hdnDIwufFI+(&!&$l7EN|S#Aw!R*bKAB%F8?EeR=Gj_T086K7%gpnA(?CM}2I znakGE7iYh#mcOEq0Fzmz6z85{?aTslknZ7+?PGkod>*?bHLvc<%uev(RYgbYg}eIF z#;^WE=T$Pr?6;@6wNd%j(;DYW<8L!{{fDVCihYNsDjM~ykCS@7Gk=&EdDJV;xE_8y zEi9B_@!e~uw_)liF{b^<_q8*sn7N`sm!gm~kd{?y;3a%maoSo|Ps=h!6%&+5X8+4A zQ9p`yGdV zROva}V1?f2AsUC9Tn zam<&2h23uoISCYU-vdiZ z`|r{LQBh+QT++P{0$DguH1Bilh+BvYX7@u}U-^7%Fp&FnGbQso84Z4FnQlu+%V_;$ z)QfdZ5`KiJd5PeT);C(Kwi|z{nnp0dxwVp-^31Wv>wK`lb(b+#H8dS;V6vL{&|Uji zF;`-%;a(wh-53G`CD78b5l!u!54ggU&wst3|NhT|KTRtP0>=dV?=}X{1HHdmifMh9 z1lVixMVJB0L9FM_Y2@-E{H{;6t@bzKz{Iud_4}UtGbEy`q`YRT2e&VkxY2jDdnRMkPu?pRa zbe1kh^dov0ZhP5yvHNG>qNitDXKFbS36~$4u3K9gk1_YYV1iC#DzD90(%M%$>jvn_ zAAZiaAm$4fiXI=HfnU#1DO-nivJf2SH^KpxubIqhmVZpXK_}zIpj{LYZlF%lnaOlu zz&qf~q4mag>S83Q8xH<@?p;2678_f)`mpgVu@RA&y7du6Ca8kd9FHA&BEtVjfntr9 z)2DGY7^TvPnm<_=)+5YGow>=K+MMvd;-313uE^8o@WQ@P_|<8EO-AW^ta&9Hb6>Dt z0ndR|PkFrY*Yr|^O!b7CxlM&s`yd<0sw}cA=MDr(w|12f04r_^-BBvFMU3NkCR~*# zzohaM#yZiJQs75eHTGEV2qVbPCXTp5(XVP1UfB-Qy@2i$d^lLpKlChg>8*nzk9bf= zt~MDb*073Nic#%<9J(0<-qoxcp`*u|HAKU|6uf7n{PkJy8a`i^=l8_(XQuOWhu(G! z=IF$tt(6U@zm4lR`>Y$XgKyU3-qOAoaa~e4j=iRl8eRtBd=g)P8lw)T>eW<4*C;y( z0UAWo9*kCGLLYW*VYE=+6e0H|8BGz-!8RM5P#z{We{JC#cOwyKe)T$O#zI8wN4xJc zdgUMC3!Q<4-TqQevh*}r*N-aHjz4}syAvAVBK$U98)*T{uAmK%+iN+9x8A;w}dU`FHwq)$XwRF|UVU_O_GnWZwdjL+O3-{{u$QdB{^GCuaoMy|EL9(~RYG!Z zaTdlWabioOM|k()vBLM%z{$|-pQ2Iv0zrm78{|jv{%qGZd7|KWuH5mum+y9+PMvq{ z)O@_~KTIJNr0BMpX4iDsM}ooW=Wjhy1o@Dws>n9L&$y`dskv=+YMi}9;u-R)ja}++ z1l;|I_3tK^e~&7QMzQX12?)~xB1u>i_#OTddI9C1F+D#X&(1L>gdq|2$%3jj0w6^!=tehndvkn@$^Kd5B6&mVqGo;uVsr732MN=qu5CAt|y>jnVA2 zX)nFP$FBA-R#Z3YmpbMTpi9+17RKKC$%xhZuOuS6huR73JE>31AQ@%NhH4=JLg8^% zXU)bu)t}OF=f>IYCuMJMJ;pm8Xn6|>0lS6t2#Y@HWYh%xS}qhEF?Y;;GA^4uC*UtM zc2>y27+uyFx!+1l)=~0K#U5y+yr6_!cR)Qt4%MYlsn@IQP@MBNS=0c(QPR_YKPvx< zWoN!N$qGm8wlRyS4qAHm-&<#I!je-^->06DuKcuXM&`(eQ@b~6X>~AtUf^86T?V)< zC%sB_IqDLiFr0?mcg?NjC5g^99c|X~wGj6D`$&Q85LqvhpE7@lc^I-YlBvs!)7NF< z@LUdGHN+m5eYF}ns1xQbjB&a4)ly4`$?oQh)3^&Vm?XR*`ueq*k`z7S=lKth2KVc{ z5(nK@k?c});l}&QJ(vy!PqSdV`tPNbb1*Y_S`6+Vfejf#1758O;9i{reJ(eXwILjD zm@XvTjpolA`?8$F&1b=)+0i~VhsH){C{RK5dO~xw#s@?jm3-tsu5&bfBiH;nGE4Q! z!r*FLC>f8m#kHSxJgsbgHLSmw#HxDMps*)nD(uUm=D`85rKWfg(_fb~40hL+UNHwr5SvL{Ows@Q`i7a|M`PPSk zzFzYqh?_}$d=|x-(L?hppIjn3pyD<2K;;+Fugq4oysJSkdm~hBCF(;H;$N~cVoWk% zm#&U@ch9JItdb!cOp0h)P^Pg|AS*-i}0)cw_C5L_TT}l?gS78?- zo&t|&;O&T(I~_B-MRarm0k@1jap=ti^rq7qa-0Y{>}kC2(Z2~}mtf9Ux_ZGz&F1w* zqLdb!)+B(_QT78k3gnkC8x2$_yk)0opWnn z`N_#G6ybb07lFzk)(_=pW6AEuUBVP;O;sKtCP!og5!Tu1xXEbZ*pQU5`)VOW%@B>g zwUM#@ovrhjtsm8kklk&_YT)^C{{iW-jC7QDQmJ0N@Dur0<4R}oo&3Q|Jt6#Wp3a|* z0H)O_smJQB|M;5rUVBh<5oKK@Oz%Enb8j*1v`t;Oo`%3-9d zNk=;~tE#DaMTY8<{kj<`$5XSBv44F5NbKmP-s~8sLdVARJ(qSXXPv|blb*I?W2?|e zMjF+xQFei_?ukac@mUQ9S>en(&m1DJmP!Y**C~%mJiJu}Fvj%@sxVay^4o<{)#Lk( zA$O8vSGrHzQ9DR@y5oF{Sb6OUGqt%C2-7^w3cQWtL{O!C&1Xv8k4;bBTc55_!)aYU z&Q~7LI(k$4_2zY+@G9kpP>$$TliK^J221lvw#pp2i(9P6h}z!2E)dW9_<>rx5ruzG zkF|uaJBwQ};cot1$oT>w#dqLYHQ*#yh?&)R_n)6muU;5{g$|3syY4Hq4OX)COLL=D z_H;@2EJ|m(6JI(Q6|NCXjzY22^(h;Vzcmd?lHpDOY2Oq;-{D|2LvHAd_nH{K4><2A z%3l^O*|tuvo8}N#J=Q|2P%=o$mFTJ+GqticYT3C#bX>3d+#`#&PFG9=P zM}EiooR5^v&CB*|F(S8_+haHaVdEvgYk=nY+QPn53R7%su{Cf#k-se@)5yzqMW1Fqn*Ge6$CV+WLNQK=&cR&Rs<7ptvuwkdtw-2H z#5No{1n1eh8BK(Ar#RZJ$sgG2-yjqTgk*!Lj|r{w-u7oaI+#hz{X`)zB zFeeo25!jb3W7*wTmYSB<71KZD-m=${g_EgMTffMv#ZGIoTRuzNta_cJ00D!xHKN0D zbU~MyzPjL8?z(lsLIlu;EsoS*0OTi~XvxsxT_QeO75k_(&7O_Ln{zG0#*odh1`6>(^q< zEAwPbC{@B6wMkxBz>1Ac(1#d2EdM#??%R&*Y$8TWor4-)GRw^J?B zxbpfuPUq3Fmg5^69?Pm@5gWZ)`-*;4_u{Ie{a`O}@X z@6V#6UB%4vJH=HVCVq(N=2k8~UDQ)aCY0|@`pE-eG~Ao_x-7^hsj+N^7g8n~&dS$$6@%9yNDbbF z>r9IXhrlihF!B@*mE7hGgG}9Faq>9C3zQ-*LJ~Jejvgh6TowKNJ);>&mdKw_F3l?R z>C<*a;fTe)C%Es7&0fDWw&PkUA6gJS?-F`VN`G_{C)#~ZQv6ox3SNr|v38=Fn|=9? z$kr@5)lQUcA^CC`0C1;{S96kKxTZeT^H7P?Z|AuPv2Yv$&jp{Jy(ioayKBN8D>JB> zP>qEv607<(?|R>%=2k^tNfODWAFT!AYw;bPdyf|!cLGyT!%to5qh1{UXmtO~fF=h9!Cael zXFIWo9@WclDa4Vv-_(uTH@6lue_REx9gIn01Kc=E)x|G1nzjQux|H2C#ofoMIjmw# zYnNnHy@mni__AVi^8J}lg=pUet3-SB<>}v0i=1-KYy=M}Lnn&qcEUYqiHG{uDRqYMWyChWW);?0+{;tZUtQYfEE-9=7v8N~ze(^;J z*FAI2Xy(pYcvor(XpNm`QqWIF4_am{s|4R^hcBF5qYlOikY~-FR|tG7_t0E>} z{8!fV$Izi?l=Z~Kfi63?a!>wAzU{BiaB_KL*Jh4!Qygef^?Zbi9l!s!>IruneuzV1 zGQizl=o?A_a@$kxQF>W<< zRYVKO`2|*|!3$@W{>bX5T71)!Ki0(Pi483nJ?j)TTncbIo>o(<@&8cnh+c&sx{OC1 z4Rz3652kO7s}#!6BAx|27ExqkNafWZ zbw9xc{AvbPU^;-0*grkziY&11?+8p-C?&4=SQ^>GXPgVSpO9dD>!oHhyAW-g0@IZ!B3`>AXKr;5oQf zTQj4>Y>MUiA?`%5GQZIRW?hxxeSQ!Z@8G;Frfgi!?G3goc(kAp_i&*O{wOwQ*p)<~ zbhXq!k9Jp^!(X*wy4LpL)kIAA$Ppps>M@c(GhkcFbgvS+){@!**Ia<#Bb>T(rrOhZ zI9)s6f#iC_`9oC2(f#0k;bp_NXa}Lr&9%O5JH>!*kRi>#beR8r0@7gSu4d5)ok)`? zQ$;(`SJArmH?|D%=h9`tW$yQW(8?2&zMiu*oVgpb42-S_m&It~&MSR4PZyGM4vh44v~0mN&2D3hW4#`p56&0z90|3d zyMjJkdjg6G!;2p`qn0nFc7=az7$4aN^9?LhmDUT*uiT&z!}?YKhqAYhin8zecvTcc zQjw4lm6j6e9Fxe(PH&e5a$*)Vhn*2H#!61Kn*9f4cp~eL3nM(&)$TLQM))o zk#EAkP{t><0*Eyddf_;K%l$z8SGyQkMQ z#`x%>rfSSm0@*;a=;2;|V{$pNwNl!c@T0qkI{p}(9=;jdw2T-CY~DISTd05RV$F2w zucZ7W(Z>c;B13&QTdde89P{YSylFSm^ zdi{%l^zB$4!QUs7l^#T1n?0YNWs2EBS9>ho`#Aw!`Dm%N;S9LzlHTrbHc}rgCW4d7 zqh}hki@g*UydlNqAj6i^=fEGHw4Q#nAVjxG-TDBsDdB<@=b@u~dF=7x*nsD1nXMn} z`)+hWntaEYHjK{#`7i4PJ@3hgDz8MgPAuYVGmn{}+u1(ev0$hX%-6%rlgf3)FbK6) z=5#0V?@@O>g&PdZLbU#W{yYFLS$V_nBF7&8s+^nb_Nw3Wxb&(u(cgk^X6Jf32)tfC@|6kd`{~_i7|34(hT?@QH!@SKDm=o3d z!cjeC+kRkn;K#Sm<*oA>oK-$5!awk*89QYi9$m@u?#c8{&B5C*`ynmCYX3Er81V(m znsJtPzO*>c@EOgs{XJ<^pIVDhBafBx!*lVh-e<3fVH_6m`QD?%14@<6)aBn{k*7yv zi*?4{B#bu!4BStmyI|$%0XZdiTzD=dCV>5Z01kde?6;LL_|;6}?Ovdp$s_a^A=>+BBf8`Ns;K`^G7-^d5vD8V&e zL8aR5e;%FEa#AC=;dg0jOcVW+Q-!NUPnWQOdZ}2B^YrzfvKHOxkO`A|1UI@Bc6adK z+?E`{WUlGQB@WKYje^%j3oRrY8F!aam1)v_3ljdV9`mV=Kbo%Yg2%3FNxE4JjHt;o z6s-CtrcOlfqj1*~wM)c3yDEJrjPI6`@h^4fitouMznLWlS=Yr4Ei$baS~VoL$#zwO zlR2x-2vZ)o$cH7r-7HCq$bO)B1Yih8=xeTy5yuG2%YgH56(56kJAO+A4ih>6Kf$1? zeUZ*92u%$O005kxD`m!~HWZcRR8?N18?16~L9#}o7IB+PBTSWCj<*C7^Wjps)JH)-PFIJjj4J={i{Zb^?V-UeM$3f&O3rWj#JZ@r2}Ag59!xP0+;VaS0-XPoG5C&z@X-Aqz;bN959`Q zhJdG+CA|ZIX)pa^PdB>w{R99PsCUA@f3pph6c-P9h_EQ~^qvd;plQ6+UWz+IZ(Jvf zIF|?P0D^?{s=yrdDK64t9?{ZDEn6!C0Nv zS!2Kyc*_kn%5j;-Gy)CPsGU1(Q$~rXw}a$ST9TH6B1~yLi$hcMF4bUP-=ip#bKO!k z!x%Sv({d@QIfOAc8fw=)8apEb1HkdJY$hOf3%sxSH*o>}ovVz3YrZ%VSRk@dq2l6y z#(h++axg7kTcGNn|FSxz<@d9v_?nB4jP%5RW!4>lHQgPz9pS%!yIay9Bu&_Mz$oK?#X=ws1Bf>-L2vrC(Uosw7w)uqMh< zGhtH&iS;LCv=G7BUCIVkv?j+1VI$mre9q`NibRRUD8B$u`G89VDT8e0Wpa%TD}=LXTR7k zqoyO9COLLpSs(OfKC`xX_~-eBsko$`rrc@9x1UzeP@9?=D0@^kYE_d!VnkhV3U;rA z&u8PXu{?9vh*|KLte2l zGGH00e&*-WYQi24dtMXLCeQS$(FJ?-ZOr=P+C=yzJ3Fx z=8H)1=g4sVm6HC;N<~~cKh@4u?zg+?+OWePS&IDNS~E7L%yYad!T@rZ&sa{NPvgbqhh_gZ9on6g>$%Ip$Bd@GV$0Cx86q;>dxeb#qjO8WQ(MZOLiv@@9i8*ojp<;@J7R)k_sM z|6wR#@cViY4k|$1?Q$0{*^47k1^PdG3cB;RLCK>VO8*pz*2n+slT*Ll^#DR8y&8vt zKQR2cO>-2&%q04@JfLqvSmnD0{wv`jZFqI>i%xlIoFU*G7TU9)cz@?jp^{Kb>No;& zYLs7rh;^(ec9WnO_3fWD0e&MOd$Qv0xZvJC@vdWtcug#%#LZQ(X-Mh>IFkI%0TrN~ ziU;2Vz~0e#itHuu2Ys5tc!HmL%0;YcBe|In_ZE}1mwl{8LBv;WLN(*gwFO6A~?sL$ls>xe^ zI0fBH77nyHOvB;o@RGZJc$lp=uGoN^_wVC3sjKSI#`HGtK4Ffyncn0M5Z-7PtVQ$W z%+eTYUR-@uYk_}g^PDn5=5$Hpmi|zCUG`Ht#9B=ngH)yWw9Xc4$wr*&J}Yo%uJ!V( zKgndx6gcLrK%6wZ65)mpOLfi`?cobQ5XP=GC|h%zR2_OGu|Zviv8O4AGi7LsIv>Lh zk(KRLzH~rov3hL(R5@cvU`{UPg6!F&0w`sXbmn8(W2*k^Q@`^Bmh?YPC-@HCsbRkb zFp{$NPd6eMoW=OyoPV2vx_(!W@1FwmbxMXAuUBd`Jy`E7a;nA!V}?uA z;Q6Fzna2m)4A!RarC0xbcw3CPgQE3gsS+F4H&vuc8%Or!cXFuh6w)t%bp0NOBz-pCAv z78?!fD0O{Fy=v_NqXSnb2S6At%2jV?g|+E4%&Z@&?v`la#OiY_Ld$7u-y?h?8891pg9H-Ht0R>gIMj{TvW0$Oi>m_~g^^JhAvn<|tOwivzXU z?dKek|08PtcOe)LN$@;_IVZBfiGYFF@%(ZN!1pPZcE6WWa;}9r_W6NjZc`_n<4{8A z{j1~$N3el&eOIhk_L)%@&X9_yo6Zp6==)JPL`jZ4=3U<-0Sk=p>_YzhZ`eWg`^b{k zHi05sTQ%f7wu9W*dpnq@bWu|3@Q>NMBW%#YN4P?d^xkX-KYcE^I z%KaNlSs!J|XcZN?vDqE;O0H(G1|wY#VRCDP9RP#0?pO0=7pAKZ`1!J#=v_C{`k$YK z(vpxP1p?i2K=V*Q>|}ggFexVyu({Bo=*v9&c^MnTZ&sO1;F|PmbV=yYV}q@Vy6#Je zU;n~_Rf@4a%WQL^sHQ8Df#-`aLDlI^&sr_6{3Pv6H*1-Uoo%l$9YphjQ|-JCqo2wH zqrZ2qlOtZ(KtlAxd~U=YD2g`zUJ1G}-5L9Ht_n8YEt|QPose(yMk5XHTYEir#Uqn| z4o@T4@nW5YaFJ3mZ4zztlrS&*6ht!%eP1Hb2&HEldFp;RV%3VcB-*dved2@2Foyuv z=wIhzDC{G6IXlcTz)%+>x1Ej@%r-#L#NgqSO^@whVYGX_44htCHt0@{Lj5FIQ-|}b zm67NB0jz!{y*HO;zb(q3_ki{y%9AAf{EJ;j>%*r`Mg~FGi6PbM2TTV(iqeDVpKi`S zPFZmyUlN{M1HcqpJhV()048Kp!AXWm+^wq4V^P0;&8z^j$hTley#fnVUA1)Pjh;Q1 zw`umfhgwMxN>ikWpQXSgyEq=b{%h~5-16!o=%M<^vl=TTIE1a9>PpJLCQzQvwRkU* zB!pVcIS`tAmC5sBd9hLI61Za!skS|jMdi!BYc4bmNnn-#y8NXN559 zjdrWUKeX626H+ALoaX1iDXit&C+hmThqB13G;+1AWsx~t8z^w|H|UhP&nwVxY^_Ki z#03(1z4cnHFJJ8J1v6_J!;>8cQK4$#`JEE=sHhp(Sv96t6%IidJ%y>PY~k^(1+LQ+ z?_+3=?TEyn1FkN>o|K6|mSu5Z;jE^%dNPzL0BduoIG>0o@cwTNTDp6RQ`MRs@8brL z*I!{1F`Q~?j&ydzRBQQ4mXL+mrnDMPsiW0|GSyK_Vb~?WX5o_U&*s1@?&mBeZ^nKd zu&hUQRbc1vdM)|-7XM}+$G#Ayh}0HHaj;(?4g|_Q`1;h@ip6lQB z9{(rr&K+!ooC_2Uu$;o7fzq!zelBBw-Ozcam+`<-J*h~sA8^!}Fpc0du6ZhTfn*kI zuEk~HIv8OEd_k^JPlG!5z1P#@5SKs9teH95`vVgvhV7o6%vj_X9l9;Y$K``1?M^sRG5h@b>UV=(*s+HeS!)Q^De zA?)Kty2tZ#{Jh%R6q|vQK$J6}PZYs$se%o|R0k-@*0N4%P|;g?!lOFvHrYKAsoBAB^QYcv3I8G|Cq{B=EB) zAVAN+tKToAA#YYQ4uoEr0pD?Y^8t$?SZp{^Q?3*D8KwT|PWUPhmBY^c=PtDa3yVZb z(g!TjLDNa-7kR|7m%ow$imm>tR;{cehVJ6rqpr--Vn+c3B-TgY5^9c{Cz#9tcmY+f z!NoWnf+G%i>lUm$?I&B^vIh(;FXSZJiI~p5&Do?cV zgBVR4@75g;OL{X)`IHwlf81D{B#yNu77NtAWvJn(|EW6nc5Ekc52S58Fkuax+`0{7 zB!(4f7O(}5p^x)=mw;*OmpA1yieG{+Tbz{I_X{KbMJ;mr=zjsV#>($|C_JH7Um48A zFjw!pzfYl}h(jAk=fB1q5KifHz7&ZZ@AvY<<};d_JN0_9m;;WYe)sqPTGbOftFuU3 z6xFHwl&1KwWjp6&lRl@GA`WIg>yb-EIiDc~`%!TkS7ZKNxrehfjp(4hGT~M=+9L~E zJtZega3|76ofi_MhapCtH?e_Vu8cHBiBPUX!ZWMzN&G(jm)N#Cb!t#anz50`OGpHW z1Z4(d!7G(17>aos{hC7`w*+Gn)AB1P5WcN->=@e#`Rr3<@Yq}nB9V}8Z0Pq2Qhj#x zwJ^(_kz&XO3StP_2mQe=FnP~C&aWpdy^1sc>M0kxGL{Voc~_pOXj>piMx;)#(hoLG zSi?4OCf=sVWJnqi%Iv>FGU0Bwt`qUOEt#qgx!^x<=gb5Hq=aogJPS)viM7jhZ7@Hg z-+`^f%A}VtSMwRTK45Cvu&j;PF_3uB(f7&kI7B|~jbsJyF0^`_{u}YY2*0kf17fpQ zQhyo2Ea@?LO{cq_ zj4A>wTVk|sUFcc<^tnTmN~S+P4(*I~75s9H-?U8&yS0`lg9X!Z>bD8j{Lgm3jxp+U z{k3Bqe|K8UTWDADKR{bul+lyPN3dRcx2U<$+Rs(glMLIVudhzLnn#DdrHX_*fml0E z-LHnk?j@=3HMhG6Vw&d9FMz9~itcp;O^)&(vWNS$231))Hq`h0fAGBcEt5j5$enHm zkdO>VQox}RBH{AJks)Sc|oT7>@Tp&g5 z-|mx8rr7{R{UT^yU{PdpOXMbYD&UqaQD6DfV?7LUs&q=(fQ)UiJX-qThoAh>`nj~aldbGW@Pw>X?5xhp-&v-O(Q9%y?a{3y6l=^ z0Nn^imL=uYv@V23G9&xjZumpDI`JXTYB$jZleMMZoNNQFL>-|`%S-h+(8s(Nq(O|7>ObaR$knGX6F~%WWQI`c%yUx`?e*G z&?IXURPs#d>$Q-1)d8w5$1(1r+88#i8` zTRUS8>RehOv*W<(r~2Wb?AveG(U$uE)dDEPBY5S7saCw=tj=YXFD>cI{yOLh=I_)yk>N}*$vxTQR|JNhUzfo5XO=G_+mI7AOO z7s)xt+=H+|ZWz7Nd&Z6j+U~aQ zFgd;7dL^xJ7Cg5pq9k*x_zAN%7jv_?Y4il!_9Mu4INtRDE(mI;r|te2y>UTGA${_W zRB+=GFrHZ`yvwy#1y|^@>OO|ybe{>0jUMd1Du4BF+_ukc%bDvRDI}*`g!iUc-;30! zk6giQnR0YKF*$2RdxyQ;_*&*P-_66V4lz4t^c!akT9F8N?d?j@t*)YM)1=dlFZ2G> z{sS57_#9J4N!&ZJ2hY|oHXI%e6G5rQ=vhjPs=SFf%d*udWn)+BQDvU3iTF_@D94wN zZ*f{ac5)vbHcwHc6$FClO`0}z*w=uE3Nno>YQfOmxLVrk;x%yD{Ru~@?Da_&1__2* zPz|~pE4-F{eMYNJV=&{0=kjr@pMRM>h;8x9ySs_%2fU;m^Zw^N!ze6;l@p)F)|~=f z#o(373MkjgPhYFcg2;sRr}3T?xqn|<^m-l~?m`3a_So;9Y8?NjC(@MNRGKx>wF9;0 zPz!aW3eJ3Eirk;KiqRiDHYp)un<-{Z?nmTJ|Ixtm>2er2N}OOf|5V(!&+iksJM6yh z5b;X$0c|&WG`E0Hke0zy>sh|1Kl1kp*Zv#jyv3+=XWb^mlD_elkE=$i5lI1 zk|;-WmFSz+xjA`^E;F@-I=AWf&ej1n8lIt$5*BV;2qp7yb@^3baq|VtH(QE+y$@dm#`2{3(MKJ%yR}(V6L^OTfGMX(jkDZ$+u~zzzf8j4f7xU+ z$=O59(^0K<_}nDl>^L11^zlhm6xPw|{U6R6bzs6^8R`48%g|u3(Lnxvoo<&13|4(A z5tjOG#6=o7o{o1Pj7t*`*TsFuGI;Ntc*;EjD-eK1`A@|if97eZwBie75yX!lp8BK1 zPR9TIJBLcd7AjWTa(5%5_27%-h<(DGS9yuA80$@hz(y3=Z}%QpDe3)SUUt{RKQBRk zQ^)ABgI=km?wE?)a0lX``emP}L6tHuK?=qpU4IDf8U2_`h=SyI*&3})Qliu5zmH+fcf zm^1z7$VEjNJDVK5sUAUan{!DBaXks`+yDn?9$KGDsLVblAolm$prcS_R5>9*YIagb zy6&gnrJxa)DQ7$!VzT%K*yOL9h7-rP4iVC@S4v-Zu{%FA#RU`Oyq|3%-7>CA1OX*=@9DJxNlOzC%&jZ?;Jx(_wRh0ZFu z&gq7Yn02P9A=}?>;EQKH_kugfB}s!6PZJigC~tp9fkW2r6;6?O3Y)bR)XWYnJ8nNx z!eCPXzroh~Wn0a|;j&S6e6#knUP-5MsK*b=dDX0<2q#+VMrw%~u=K-n&(vs={BiFcrN#8f+xs6VG%vZNz z4fS_E(4vdr(F>3 zL#q})(iCT9Y~U}cz12E*-?5>6F5R&<2*u3Cuu@j${&$c%oJ0Y%fG<)8eHbc`e8q0v znAN|rh$F4D_DwZyZgQwnAXsfq(^ZziIZLG*NV>4(*SB2-XMbnOFY!{mapWtR;U-? zO^rI~+xhh+qvW8WtmE>2UhKlTf$D zKb0Zu-OB}~RNdcY843D_^tnB(f+!J0g&($p&+uSZmA8|pe5*M?9)|ays=!VFp*Vt@ zDkg@uB#j<-h_X3WRsI8X-9gQ?^lm8Ei;p%`OUTPm;X9(b^nVjZw3xM`cuUz^8*uNr zp>^bud+=I{Y<1sShf^eAcO_9z6T%<}zL0xj19#9@Z}4F+quPO8<-K4~c80%Cz{=ee z>9pfJYYP?-=@{6rN!ZJm4YR86irI6AZ=LP!TaUqOM-@-<-r+s=X|J2HG8eXhg5uvz zd&i4DGG>q4m;b2B?NeHG%!a7*K5yCm)=xE)<#f=9li8{COu;^`TCDD(ZUDpIC$jNK zYLj^yesikNnb(?~{N?Ilk+qgN)sqNwGsOFqj201cEC9p!M*}CWqgeu|$$Pm>vTP8R zRLn=G@p9Pe^F4cLTA%kNs$FX;T1Ne>qtE;LEWD;J)(bTa-Q9TB_u&&4s-SEw!D>nk zn$81lT?Ux7E>e-<-du95#m$56m)}~t8c1S}3ksr6V$}uVM9b%08%4A83!M{!8%S53 z?9?nTHJm84))k~PA`0y)?tQ%`Nf3~jvfoylMr^UftsI42n$5U5Std*qi?Z*3_V9uHst&4aK)D^Oq9tIhYY5kx%ulM^( zJoF?4aG&w>kC-H@hRVX@i{9%NQi>s@1Ds=6fg}W`Q^>_cBFQ;Om1*~FvzT(xi*~No zg3;+XHx=Qgir%s;&Duq^#cZD-k%{pa*`*g@)iLNlU(d=onL~P3JC?|Zj_aMGC2oR2 zvx6;yyU5SoSaXkQ02gQ%yYmh9qyazN)TpO^K_-1jmnQYQ%;L&%q)zd1Hi-fv0|h*hsv+hqKyojMjI@!f6i!C50acKDC2V@f`(TH{tsCh28a7l6%|Ip}#( zE6*A+(AVDBc0q@FEN>8(h@nDv*aK_i)W&iK-;7+Nvk=_>I{C6}-)O&SW0*jV&-|()&4dINEy8M)|4PavHX(@_+ps{wFpPgCsB7$V(_Gi1=Kc%dhLLyq zF=4TPl4=p_l3X>MruJDb%8?_pS?~6vzD{#~?z4{G&ChgXgP)!%>D-md?!QQ>e~{wB zVt)P=QayPnisFhx6tW(VwnAAZ>jE@WWP7Gp&Kl9PL3uIE4DQ$?yGaDLqFusJS>_th zlB%x)6Vo}0j|ei8nFA{!GiGU%pIvwL5rw)46ZMui*@n0WEO~n{QpXb56Nx$B%Xzgt z1)=Z6I?MV>I>juDRWVxH`?b&S==frb+GBcG9wNnPwvLN~HUGNHkcTQbTrzI@p_teC zz`B%omy?D6tzsQo$qkwby8}VJ65O4RtE9H+4l$!!=UohbT(+Z?Jl<{=@@;fkh@I6R zf4E~ON-D7dJ7+HHDbn2BRqeuoKEP4(r=KC>vS~m!iH@{e`$(#v_gh6A6ghY!$`=Jk zE3Jf50y3(T3uI-Q9;vk08TQpugwa?TY~S!VjHa*+QWKE-$~=;B&0vKV@gO%K=%Htu zOMH5$L9MPK3uqP(dNn#{2lbb|sFoA7!|~vIZz9pl%oG+i2~RlAAB z6h?2||Ezr>{6-BmA))hg5Q)}h;z89}4BGAgv8+e@z2hngd9lCA->u<8e?@q8)n~sh zsA*%-_xrAySu^BO)kmPv%psl^4x6m3Pi+TcWed&G)p?d6` z7krO#Z{+zZI|pG$J0FmOgk{rWGDDn1hh0J9--n0f93Rwf@jW{)Z8}f_QZUG>?J0C9g~rnJAYmJ$ z;W>8V3kwXDm`cKobU9eGQ7vBBEen6#+rpM2nOpF1?7rm9wa91B)?M&%cI572D~_^C z+VUCQuGxdJkH|-`s-(xwU@J@z2l41yyI2z&`M{DIo6B9 zi_D8GQub_q@3i39BGJp@hPTC??;Jaq1mhHcMxYE3FS#_PYB>hNO_C!5B|!jVtk?I) zP{dH!<40EmsIfi8#w$IqRDF2C(K!tPB{@ku__Du*z zzo#v=V{|BFB`n}}7u_V-$@DJ#&}Ic3P_-u36d8ps5JicIIIx1I8}ZX7{qYT`IRf5? z-w2~w#gWIb8W|@U@{Ld{5dxWHZP!;1nx3=pNA2*|&UKF8J)dWi2h+Ec&%xeNf`V{| ze4j3Fr_<4vDKIRk7052#MndKrs^+(k_bY=XWpJHi9bXhGp2@CMIc6+?S*S;otR@Mj7MrnO{>NOTFD*u(aI|sv! zP-N!Ia0d0pF%*nuXUlx=@cV&>N7lj(j?l+u%gryJB;uIxm8KXUTCs1ZbU7`5zjffT zZLc!de?RW?$_ai_v%SRIW@LZ-v>?Itaa&%?9vsL5cPFQ`s;_XmWl&q&xb2L74Rf$VrZcOY0hqmEMC&JJe%y@;k?{&+6X%LR zhH_Qid&>Fxo_X5RxXt^uA@yI*(Ms6ZjRWZX9%>_o#+lbQPTp&`WuU>)AS-nn+jtbg z;2(G9*JCDkoV79nez198B8PxJapyR#lqt<8KHa}lJinlZy#W7vNJx$Hsfp7ZKixCE zxz=GuW6?gAcua**xpn)^X{rr%(vJXkO{ysMeYdReDdPvgRePt_fn1D-6swMA!o_2< z@Rc5q#$8WmVd+RW zZfTkcx`VoT7j%!yoP~E*aQi%T_7W0eC-f@)o<8?*Wi+&;_9fRoMeAeEeAbv%V*D?p z8(?Yl_ld9Mn5!Sh=Y}q{B$KmVDMmv=NADhZdUE*l%CC=sEIuiN6T-QU`D|BQBGn>h z-@A2X3+B@e3!=&gmfRl{zm+sRFn?1onT=t{1cAw5KiW7>M;diEIYDD`-=k4`QuJQMj(*2B zN%uB4VEZ$DLR{}^zUqEMO?>f0zX6;%G-igGXLtO0&eZY3=0Qj^mEKqoI7fSzIl(1j z>6K0E#I<4#+8=jt7gDYI=$=)eA#xXp5_&4>sclPbv{CH$YY}t|9#a{6*9ktwN}^U1 zY&f5nq`&>k02Tk5*TZ0E#rxGuZDfbDMvp|cF&=cJ_k9`SFHr&_fnS}65W5tJFpL{pD0*6^qC-_lHz;o5u2T>rg zch1nu1BS)(?x=3&c$L8;d}riRU1x7)QycBjPj%}S6?F>^pC5y&0 zLh=y%Ybm6}Qca{r4G2%QrtXeHDRy)RjhC3>Qqi9-T{I@GSCM;gaxJS@bFt6Zo+8$FdyQ1G*))O!;6fj9=ki=h`f-W$#wht z#aBa%cZ7##jJ@65qmB(7IWkPkZyAe^ustp778dE}jg=A6O16n~VjMHu&j1el_QYib zp5eR~F-S0*!>q~fX>zAop{b=|_E5xO3i{C_?9Gb#1Ay3`6cg-wy?l~^f5N>Q?DcQb z`Csh36Pb{Nx{pd@3h3OlV{PC&vh|xiYB|s4j;+gWMbu8VY&(zkfEAQ=H323tB44S@ zq8$mK)ELY&YRN$EF|%~TEX+GxGL?)H*raM}XpxD8qt`7xCJU9-PS=aiM^#x#VEp7OoOQumEs};IU-y!?EOLg4u`;gh#B+1O6#%KhS zpq(sb*sTrir!&JGEZhFg`1`kS@#zD$zc*qsUeqOX{rmx7v1yps(b0JWTWzL76mo<) zdc`=ut>U7VGRyR}ZZ%#h2pi)Pu+l2+^XJ2iV6YAKC0H*$J;`yxZ2pHaaT z>YN<+=GenL1#LMoLJhL{O^N@jnyp)?G|hf%QR#)G{c&9rR8*K;sIR0uA^(GZ^k+wl zi={M2!_e|lb4GHjVY5s!x|l$*ME9Y)14LPm7jIQaOkKETx?>LV-br2>O{QXwuzmCh zhRF}`f?Fy5cG#h7)tFT?v%G-ldlJeLj#jnx=3pFUsO>|PqjXNF1#hb{oWbQevkz72 zh`;NEwr;bO*4qig=P%y-mRJNg3LHT2%6<#A#MVk-fA2Y4e7Q0j;$~Jw=3(WQv~x4W zIWd-bj%UM5-0)Gr)Es@;h-bhzr^LpUSbr0AHh%L-G6x*K#M9~oRinHn13?WTK9E_< z1Aw}*jqV3d6!{x;$^rIrTeo$xL-2h3LVUJZXkWqrIF$Bj$LJJ2b~m_vnM^~130k1U3$c6p$)E7edPMKVY)o=Zo^P|Tz1tGqB(#PZ z)3Zip)bCv=B{#IEh8iy!Z3jrhUw!?#)pQm&kl+1<`Kb^BT=}+h?v2EpI0bdgD|9!Omm)>>czp>s{p_f#_ z3n3?%XshpI*0$BuSm)e;5QZ6ipuU`xDO-HE6zP|T^&xQ9vL=`dntyevj{GW;JG_yV4?2N&A9%@P4iTe-c z*P3OQ)ls16TM7z_`aX!KK+Cr{BODe$oOZMY1ed^^L<*a#FR%)t`?BJBm#vM!cdR%q7r?os$$;y{^;|3z{jf}$ILB?sfbgr|EusioIGbC-U2ViggcH1wE# zW@BdQDE(M%?WcY<;{aVh#$|r+H8)b7$8P1BNzN;*VAj!zOE3wB?+VWQ%P0BEHSY!5 zd*vv`%TX(XS&kMoQN4;mI~|~l{K$M>qg{?4 z-Jc$bK_A6Gv?1&&c!NTHx~QgEaV9U4R3D5nco?{JG;>VBe2QNIU~72Ez{eg?-#x0ZyM`)G%Na zX*$oxoSw9o0zZGfp9bu?Bcp9(jzP}J^YMQ#2zEHlQtm(cG)cvty&PoZWES_S(p^ID z4=jChZ|L#~xUA#oapd&!c`(sKv8@?c&>3vPzN#AV)zYxLGWcz&+r0wc_oqIxeME^g zNE3Hh9VK(mQ|$F_bYWXw`&iC&r@KKfE?$XWoFpIcYbxcfqw(!2{#LcYAYgc<{K!79 zRP7Ll^mkecye`rs|C}-Pn5W?Fb1|E#j>>6@$uZwP#^^8WHsH(saE0sVE5xoIn@}AZ z&8n%pOpG|?mc|$AJ$&uTtFG3qzQOYBd&r|gMdEJ$y|Pt{jPHeOUP)&qRL-r(CNn`B zt?B4zq*QZjK|m4i-u%cVR?tVm9$7K8c&S3mhLP^U6n%e#grV0=uFLARaoeJ)#jA!q zpqA|4E6tgT6Pxw~y0vF;Kg)3X2)FXvoi0UwwzXhDy#`Cl0guopluOF+~p&z zlJ6IGS;YL)Y$2uUy>AwJp?j=6ef%dk?mwZauEX`;UUvDjIlf|cIR`R9|Drv6v0sP)y@ zL*FO}kNzdmlxY3H_Eg4igrsvi1d($az9F4)&5Ed7m&$6BlHGR$|`s1PMFGY5#~p!YI{q(^br_YgA2!wf;;3EQRoK}+!|v@gvD zbxK-cev{Bro(9gxe}}H&Yp+*0wBPSJ*Vp`%&pP?UYLQNAa|kkBiTgg`l9qZ!pN4=U zhb4h!oJ7pR9gg7pjJL?I+APkXg{~Zzp=z;rzmW7uVWK0g^~dD#a)pG=xyyOve9H$u zHDeegUePw!8?QSmLy>OsOrV|tEF8zSAck4ErmEF~eQd(`v;6FPOvyKomRAE6r?7qT z6a4D(8J=I_bnZ+}pF)f+%}g3|n(ma9aEy$|sBeb?QP%UW8ZuLiI_cfK)MmiSXBHfI z?N8V(XEqdp&-{^o*d^2Kv!M!7ABXT~k|U95gI-bN-IruWv=F6P-Q=CghVkRpryxHj zdbtz|KxbXbQ&fBEov**yBM<5}m!m%Se$#3@M?+_ct>sJ0as|MrNKyDHtHbHsPOS=!95T^`l2xkxT?e#ZD77k!Kt|DrEm3lsFY!*Y%VC>j(b zbJ+m#+HBxf-z`rN4!Khaaiy0Thd)YrRTc^+jJlGrqaAk}``8-%5$xW$0HQTKuZLQ^ z66Lj@1eCfgSt=vh7Brenn=OB1B>O1>Ln_tsx<9wEpKi}|Q>LidLD%3H(W4G1 z_GEHk^5Mp>-yVJ|@3z{<74BAf9<%Rld{{wjg;|q_QXz)6V6kaHMNyr`4#O9Yg%syw z+!dMV@NDj#3Ca#WrW?vruq)v<4!p^X zT$c=7>Gd(=s|nR+6(t^Lj^uAhVxV}uz=vl#Gdma0j{lfcqt;* z?_{1<1qWH(?Qs_ppqjoKFPwl&=DYXa3X|}zvE`Vz@C_-XulI^EC~@Vlu}XZwh$Fa5 za>#6@Vb=&R8CO5SbPLKT?U*e&OT9tDJ(moXjm#k7JKxa4^@K38xZyFuTMHo> zpW^%QJXktj6cDr^E4hNb9J~dQp-E;;nsj_S*ApM5NXaaAYBMGceMCPj-8P{1`FXS> z#-bxHgWNR0Zy4ZepnO;rhM{+v^pkBnO8xz}fU8|rZE zWQ*UVb{9|6NMw#>gE}QHcs1X<3xuBcJcTq$x9KR^@*OXs*U8c*j2RU6`g<=`o7>O}^HHAh}9ANGxw zh_$5m2ZY4MO@URhEHLt-zaoeWvLcF55hQ&b9yq5UGpl_J5E}Yb?yFren;Xz?zY4v+ z=Z*KBd*D%P)d9yzuV^Lyc#ne}N*3)}rnnK;b$LLAmpxPnl6Y?8-LX=~u`48ghr~u4cwgbW_R6nRK*RkBt9A3v zOA-L^L*?}QZ{;fIRdEgr{&YzeG$_7=*~5ea8fCfLv7BpQzRBAd^lPbuvE}~9c;D%H zlu1y0(gRqwRe!$yYvdAJkA(FuFh?YHqol6m)(YuZ5CeQQA&3od`i-33f(IiKm>oC>oY z=CVC&+$z8Oowd@`zmte!e^xu%AP&Qw3U^iVzUDp5SxOYO%#RYp4+}J(X+bWUWZIb6 zNwM+HB+~6XND;zoSmt1YA@94JE?<7-_z#a*6MguL8Gw%Vv0QK{c4AgY3OG{*6ys&* zZp#}s3`EQYu`MzU+G^G~<&*dyi8_IJ7x4ugi!%!KFt1Tai82Xemx%qt-(Gj{O6NJr zYFxLQqWj`duLRTr99A_cgu=*!w&%;o-T?Pd`53;&uM`t>*V5jn`|6Ze&~D=D)H0B| z`S(9Po@S}E!zXLSAu2;2Kewiw|50M`Uq?eD8G19Df|hvfWtL@~eP7E|4G ztvB%3wd+e?D4n`9_(fh1XxU_&2gH-h+;2CRJ{v=}HwkqMSAXxj*UGxj`#e$)LGZ?N zOuMgsA5cY$6R^e45SRnuht}c+Sflu{k6Yh}EcGiUAgRpnt=YW6+}%Ug4T`U|h?}Ir zxaUjtf|X?^diDKQ$$n5M!HF(ei^+Dq>$bw~ZlNc773aeO-qO>cN)3$R4(<4MH~=r? zDedKwbeB}wFomjzPTO>J_6ILBA&I(ljK%-(i+V}{?vvKYQLnc?4ieg>{jHUY2j3K0 z77bIC65@^u$hG<|%c5kME}E9-fPe*$<2RqB?*CAIq)i*wj8hjd-Z5${1@Qa!DFp$- zt{~{YMDz8`Z_M?Xm=@GFSBy$0cMbcj7qN!Jv&2gu>TXY4i)XU@taM70TKyv1GGAcu zz=%!%V7?3@j2)F&$)UJ?_Dk!8H1g@_F8MMx#kouV^kp{PgkUFV6Aat`Vmtr6EroI zUd8^G*0`y31mzzVS?8^8{%^7>OT|Y*RyBr19=IV_hU;mjbv@trbw5^DAqsY#33=$z z#g+n?u2KhIPC#3IM>5yT||Js zqm#(i`8W_6@6sgKwa+*S{;ekK;&jQusmmVB_w#292(3Enj|Zjlpe_(j zQk)egD0GhlRa3B^Z)#t{hhEC#Lv2acRS{_SlrDx+E(RhMorYuG8#FkH67FuJ_5j-t z8z)$K*UQ_@=>k2&4|L(cRDwe7hS?2guAPmO=+j%bM1DR!s|4V~Y2FicZPgB;VNLHn zi$*Gj&$j=H9Kul2O;rh4qRv!&0t#c_J2u^ z+BR&suRcNhQ2 z01^4>aa|Hr;mh7h?SPr$`FO`0vM^_14u&`c%I4jjC}ITmq*P|2GzQS|4Qt|S zq~Q+fIM!QRPs04DN+gIzD2;OkFg;YPk3l77!94RDwc+QD$tKXg+rn|tCQ14FKXIQE z_4QoEemQ??y!aV|7FQdnAKBG-yhn8or195BdT)v{U<=$=4=CfzVp>yMy31-@B-)?+ zONIRMGVAGZO2xH1t;thNL){scr!Cu(o?e8dCD{7Gf3rAf`FFGChAJ%EqeNxf*z+2_ z+SBEz+Kbh4yJ*O@>@?LnlTZ8ue>Mq%dNZ1Po>dI*u3L)H{Y!=vxyg_u2XXd^b(Bb> zT3saw#T@}^?kBCmzVm+?KAzR*JPu->2=GQ#;Y8nKUg9FAFll&|%bT>4~1LYVQY$oan ze90hD`t&VYG#@1{7VMmu^N&6)G8MLV7d0KBT8xgKi@Xalbm@aa5uCusG?hU|nfxPu zn+%9niL&o5|3yks_-K|U>*vTIA-S50ySE%5CaV|Ytq?!qtT!nl)^J0~V--F&g>`eY^)!QM0d=s7KF_0z2nc_HD* zh`##77YC0By94cTdApy%{;Uui-P9qKwuKS0ye3OoE5M~R(-OyGaDK zyUV|7cdMhpKms@P^5P+$1dYwGzEGdfM8tK@Vj)3v|98iD}}=inO) z_ePHQL?5MEBZRy&dXZc{U7W_acBO|b|HS}4=^xK|8iu_kyPWlZ(iZ!kF5FOGUGA!H zni%^mDi$$H^07Hsw{=f@8*osl?t0c46_{TI5=7H2klbi|C9T=n@yf7JKG5hDFX|ST zv%oJ(n}3R!T=h7TNHj5?YuNLta-*f@l|WM5$g3&3q?K*egQpvVFeKbbpU_1Az^a{T~&LkkeK+|*3X+szuh_a`{sIra0}CT*w8 z{SSB2cw#XC;2*t)n$yy}5!tjyH7$hrB0mq!_9K28N5%#K%na5XZ3t{5L*DYkJzqv* zyLKv|v5x$&Jn*$CKc^#Mf7rm7tjfkUVj*FbN0h8pTz87B{cxjk?iT;-(?U?o;BxOF zP@C4d#(&|(;Z0)qX(H{&%M~b|F52(mA&Tf)c+m4j5jUOeyYBWt&l%!ZHDmTFTD|?i zci#YZxsYdQg^pv0(X-9@xReD|nE=qWo~P-1^%K7%%+D@vaz)k4=VD50CxzZn0lT(22TY z8UMjHud;WCVMfaBNHNhN=Zy|X?iK}pWzbSIkxODlls3)x zuo3Frd2dFBHJ8!u7=2`s54D5w^*nJc=luC!sGn3(&Hj@wYWF*Jok(cMHLk_0XOp$H z$0HK!mietjemK@mas^uXcEMqI`83?o2d$Zbh!-gOeKN29WeJ+K*7+uQ<#&$R+x9?I zYLe3Z6Bez_SapsysL>G=aQO@E`*#cSJi*uZ1|`xO@w9R~INJ7kMR%hz)pV2LA(y4( zj0VRS(s?T~1DYWM#d4nA4y*g!k@*eo#bSB)X1;{LBMrqZ8T@dRo;}E$M$b-42#Bu@^`+%#|pU-4Z?U^CIgCCQga@D8t)#-d#dt6+iCog4?*ude*_d;(Kd%g$0 z*u!5BdAtAqlJmd7UTcV`4+X4zSN^(S=BL2B;vLVaVF%tm_DW*756TMpgJ(O@9{ zlA%>f7&pgEZ)Tgi?^X%Dd!$8IcTd^#8GGx11lL#S#_emzY~RxT@U2I!M<|{oFBg@I zTe7&usjmtQ)t7%b1N7qDyON`#8zi@K4g(Bzth!1*ih`Fq_7HrmvKN=)%2GfEMur%W zS-*#7_it?>4JU4f9w?sxawJjx-j4LP7RHv|!0@dQQ zypJ_OIMkwNuY?G~gP9Yy==t$f5%*|4vI*Y>o;ZX;TmPK25{6IJP^Aqzsy~A{{CX0t zZhu^E_+!IuAGAA$gBT#MeIDJzIGDu_zY7qedv&Ni_1cJGBy&v#?UdN5AA=a`6yDHW zig(N}%kA*Sdybk9;&S)~0{Y7~44{t@sNo;JNpoYb8Co8Z%__Q|Ao73o6EIaNVzmh0 zoG%=YAgkPyw~P-ob7IQWi_EYsjGGhK zuqZ8d*oO0Wr8fGiTd2wW7zPL5$`_THAd&K0s?GXRLGRSKp|fPy2vXW5i6fp7AP}=) z;FgL>20TX;X`Bo;!`mV>$wb=RUFMZgTk$hp0ryvAor8wEZ?PoA!P4}m?Sg&XMna@c zv+#c+K~R$ua~JzNaMPpm=_9Zb%STL88-7LLd;!E!e(UO$pR(NFV?3N(O>R}D@W zr|kXBzcb>ABj`Ew$iMY3r7d%ds-|}~gF)oiTpV3AUpizEduLeHPYG2pp4q2HBeR@g zSR;7&N2Cg@^T^&gPapCw4Z^yi`2(eyT&>NVNn7D3eXr%Sw$MJ=KxaYXo!UB>qA2IY zx1t=(+n=Ltxk5Yc72uCT;LMO3*jB%#xdp23bnO*9S}a`va-!ZRu&@PyTbX-wc04@T z*0pEMT-Qq_>}RP>?QxMIajRgoBUE?kd)`W78#qd0t#^6OD${>;FRWPS%2$vuInqj9 zAPfr(PA1y@xJqXCt(tVq8BNu<1Ud71mZDg!poegP_%?xRB(arb);*=pPm#ZAC(Rbh z`t^(I125H=^@9ZCFh5VgF$p=?W!C!~c7z)~!mz3jh4t7uQ_#Fw7Wh1v?UYzN&W~`Ycz@cDnJdSmMMiUAMP{6}C4za^xKLQ@VTCov<0{HJKd1No(ai@TogE%&Z{(*vU`?GKp5_4cP?g*XXdMH`ndwE^}4{WZHxkW<$=^vtJ|6C)M{^$CC`1rDbWb(CuZigmy6@NBw zeLwfWveXK%j`DPy%p~`h{qj5HvN$c%gxK)W@mw^EML6d;}nGdl@2CwYd2L1?#x&Syi@CoUOV7Zk;ixshit8l zvuk4Mhr^gS*`=i+05|~jG98S>G_l57HLWeXgMfEVXWJOmyV9K=-jxYChRj0Rc48uc z9r_(?;u%s7EG+!gdNw-h(Qo+bhZSKy{Qz1h5fz$AkE$^(nR{zm_sn}5>4e8h4@5($ z&_bHoGk$%TefH?5i3@072vAB&b6W4wJqY}ZKME&GutOXkISnPg!dd-2Ole}-;$6Xw zn35P}=^)akiAccs$T>=&v0?3SM&qof-lQX_$xoi=)Vk9sUp*6755TOF85p|`3Bu-0 z!?{bCEqcmDV@JLs)@;!BTd2@$>@&X4C!%CD{f38{>If zed^>zCO;L-;7?f`+>j?RS{{l1GY5-Q@XyDodV6UV7GC)-hjK+s!MR{w5$6^@McMW8wxxl9fHzT4e6hZ*?x}iWsWv>olq4<_5BE1 z^k4XXlo`YPcFS@o#oaNPCywa05gef*LpJtXJK`d&fS!FVxu|IFi?-7`w3AT0(l98YoS&+0y&c&JZAw}5^>$S+r#)2{K^=Tv~p}w^M;tV zNdKg#jqM-sO+LLXSUnGVx>pc1{Uk#LPfIk2Cz1A5%au%hU$>M-+&U?&6zoSUa0a&J ze}FvuZDn2L?>_N{5vIY3evj^Yy5NaxA+PIkU2^x=sh)<~im&&SV+&m{d&sn3CC_y2 zN1AdZi!aEJfB0uiEinL%4x^*W_;H&D%ITvDe9)q`DC?k4lM7@RteYZ2`2Zxj`CXSH z`z?{(d*;M48$n5rR=5FVsG`hP9`4i<3yDK^xA#60lF)ylHBqcwt^^*35EfZK8x-`ptg`-v2AQ$tem7trmkA&-45i#%833+JbXAmb?q)H4zKz7<4bwG)@=H39ZkgQN-NGLh zT#L)b@lB0^)|}5vU$BziMEy3Escdb1=AY=+JaH4n{SA8yENBu{!>j#VuFN4rp?EAy z(8!0@g})~^crS$&nOj4gAn;zT(lJoh5w?}exjJ8SI{L}bC_Kg)bPpY+e1@?Qu3tQC zKFBbrbjiKAX_F5>Dc2})@*MYFDY4Aa#BHHo>HioU)5N>>y*LG_re;RGM&3X^!Y9aRh%0T^dko?Jv zI0TYg`>q0v3Vk_hD}Hd;h`<)-(CF)A@?axuq@F@^I7zCDDk9?19>tQKvDtj}<%Si! z_FZc)0gxO$xe(%u>4GjUd`2W}w4i(pZwZ*>)T*CIJCpIHnh(8Dw)Mcg84TN15B1-T z+pD$03$hP+VY#b=5>!^ZVCij0> z8Katf&!jop{(gggB9BI%MULeMUU1>o{#R4A zce<)0Iea#3AfSN6x3bm^62@e1ms%)ovp|EF^E9= zih!NX^cTHT$5|X0Y)e>_?yn^v<@Jp~fuhw%-AAle73J#@7tN__-Q{UH86Ofq1-U;% z+4_4;w}ECCj$Q_+l2s2z0uPES-lM5p#!+mcts;}#Qh!!%02*<@bc>&+^zLN>4%})- z@bZAmu~dtIGI-aYf-45+jU;LJJ0U!u3&=a^S*eLlLUTkN{Fk`bm9GsE=O@lg`5SS~ znA?B7ab5D+v+E>djd#N|g~IyDa!wM~Eg8;#{(kL-z!U>sQX~xBjO@!Ik=iL^Wa^83 z*b;IXBhZt3K8ZKHASnA{u}5IMr&UEgv`yZF;=DLLR@3}_sE7j6F}^c_Gx#W6Nh^HI zf=wionItPBv3%==Nb0TbIbEgpwmT*BLv6DZj7f@yepV`B#m4eW z$^=6=?jmof4LY`a(Yjddh8eHTo}USzdp7eeCZ;XtBsX^18pQEEUg+mBCn_E+7EsL) z3FPiVa&s;9mphgtPD;iD?;N-I3sX7*>5eQh`m%Gf=6<(9h)dYfK8>G$@LAto5l-6j zsS_)EkgrSL`NYER8Y+|DY8d>r$&m5?N*4d=V=j?xmF-jEBGOZz`REdmyz-7SpE8;F zbC%8AuL6?;}_3Q(S(lztLd_ zDNlon#}w_u)H2qR@%)?trmq^&R{lb4FWxscsry_`+xLjlOfx;EsGOom5B<`aE=9IbL#qv`E8ihi08h5^oyH`#*jh@?add`(Y^N!b`9a*%_(UeKfCr z5dM(9{zz?bfL2`Y<)aG8vd-~~rKEERk_0DNBh+*SI9>9m1IOisLV`4*NTPi|bx_E&5m zR)$R6ZMSa00qv#{b(Pxs?=k=QDy=H#T7^#Fj$IJ*=ri@G*iS_I4?_6pgTK1Bi(fjo zzl-4{diL@o$+sh~vz$1!%Ma=q;1epPj_XWf;gplPNe0JlxexSeaocEJ!}Xj*MlR{t-p2n#OG9?COu z==?pFEg0%T6YT<|LYLLg^O}7a)NPzdyQdZ)R(~XRc#-;O=)(M9-;Z5^?tb_w|6sNC zV4k6Thl8j#+95O7 zWWPA<6XwD{)*eF*w*mfsf6FBPQe{`O_u%+!E7fth3;D%scsA9@WCu;PFjF>g`@8u3 z%&8Ns?Q-hrIWzlD<9wtMDER$C zzi^4teEG9cGn~nCl7QN_+;rR91A0#EWOMHICR;KSad;I$@Hi!e!CR!(EKbItWaI>b zoH}2K=6#%B5Aa4%H_laC!QvCyu9~ZM6n^Aoi!L1ZQdhax(;JCFI!njV-we56+&-y) zIs?a;nt{C#>ewPRm9ff`974l*Bjnd?r5R9SGhQ>`Cv#XP*qvn9>}#b@ZG^fT4TX`7 z3q3}?0z8xMxmnhF*pwOivA`CZdgNxs&~HaC;Vzu;u!j(b5`-`dKaS@BeVpol&`7QGF~GErCTuEn%Z_Wlfv`bW zY#oXO;o(4@Gve8b8 zaAo%NiNvRGhUe=3~*#~>r9#_aa+fvO3L;V6{f+; zOO4)y{Z@SFL8j-jcXNqhBcjvtXBfkY+qAHAE5cg~ol$_)3Pd)lPylwF;9A$>3p3rg z4m(rCSOH8BHj)G5ce>7=gKhdQOl-BeZ^|dzENxP%3q@^#ECwm2{&7-bXv&%TQ0lU+ zcXUG2QOGI7^YxK=VYhLzT_eHPvEdSd5)$wMgbun6JG)?+(M$F>V>)+Cha2m55d=#Q zGR|HHCHtsjFvqT49-R|tU>9TdSm-uE$oGSCqKHun6Tx2Gb-69C*$$E%?=C#$uF-D| zJo}bffJEU54!i+nph)1=g8!5BHjyoFN}TqQ`KrMU#T@ewEoq~j)bsw0vVJC^>CvB_ z{0(~YSprNoe_wRt`)$o*Z7-a*-nzfctNGZ5xBFY*G%O7b&tN*b%hmD0>S%8cT>=qe z&80Lt03w<{7)vc{m?Kl0-mzheQzy;a<@lxHnbM$k&pJ?(NqanevE)N_T1p?SrjxB9 zj?l7<3yRkrU2Z*apC=JDS5VsJ1fs%(^j24!G>6+f-cM8`b5Y~RzG&N75ygA;3kE?( zF>76K0&;7agwn7X(J;7jrnc#}?6+~x12AKK6C%Uf$_HEw+^7jcjhc4sC#aNs}pL#Aj^Qxzd zoz0Esh06R#oag_fd?k`eV*xhOnWlJq<#mp&KgYi-%5b2zX6xRBv+xc5kwDhi(by;C zpMHI0azga6fep3agocl{-!4@ZCD$0WV#9T>)t&-ku=o}@fb<-5m;ut3)+!S>$}RNj zzsIFDRh-6@H!*$6U$BQqu&jF?j-mTM{<<+vT?DA9qlNdk?Z+i5+Xp%8*(=xME;_1PnXbllsD3Y_T{D=k}R>rIO9$3TBhzYB)6-C?rs@)^8JOF`DIootpQ2l-m z1sVcuk!~&crP&!cC3=1#>SQD`D-Z@2-9FidC$RI@#d@zcTR68e+6WsxOvk(IV4da3 zVEAQeQ#P%c;+lu!ge5@r45l|-IcE)zOs;w#Rem6|MeUbL6O^Add(czY)heW{|K{VM zB-xd+K6VpblyCg|cBcHQ?0JeFBv1u0IdnPaw96*n{9e%eK5(0pdd*WP%x=))g4Z;~ zyIN(seyzbA)|_PosSN+b#v%RUJhbuKem~&qmg0Fq$VIl-wciu#kI^PYtcua2QQ>D8 z;W8RH2wmvUo%Ob+vutUyE&c>4n7`zcx4EWcl%9dPg|_9aEf;jh47b&#%|j}{zBWE~ zuo``hT;2J?>_dTkZcj@9J-8m3`$?&jcA@y;Py!uvHhOv4C%~oY%*ye095gGOS3~P2?nuSs<*jHytydT0x4}5He~bXlX@4aIdrc z5SJTD7eD`s7y)mP#eUpVj_C9P+87wL4eiN>WzWV*C$MWKXhVt9>XdN3!(I=08%7Dp<(#)k{Rc z=7rEofU5GLfx;(Eb&jGv$fgxnMLuAX zn*_u+t8-9+3$-fiYPWOOV+2&cGaCxp1)s`~1U~o<8k+>A7@*!qz(EH;I+YGU06+OO zcPj(<7BjjX7$W}8Mtw3cgT9Ah!85OvF8R1#IX3>}tTz5kug;V+FD@sW=i!|$3y0ZC z|5~OHoH-ngX6b8MH?Rew8E@v2HSHVuqDQAXL7-1;i$AGQPm0HLtyfjdRaCo&e@AGezW;F zMQ7x4i>kO`md)f|46~j8-bWxp30_?2G4q=J;F3C^cqdqEOy@N7Y3@4YlK+XbHX1IKg03*JhqRS@KtxM zuV>b(bZoXc70$7@Z5=f9PGls51j&dI-O98bR2HR7`AAY@E3ud&T zeCfDNse#Ww_OSTDy;J7a_9>x!7|@MedX(-@n!3h?fIdd|FTXVvZvX8ebcY1xQ`VY+ z-y#j;c?zY|T*FVb750cRKq>Db6TYwY3ksdKP&xN?H09C`&8lBCr_Yyo{RV)59s|`2 zEH_WFY^x@yDUcbJlCK)-xEv`pGur2<>=Xj`~frWp`dtB7mBG^Y;TM%R5%Jyf=s1(0)aJ9h30zkA3>@hCa3#ZRj(3MBF=j zzWCC;YEFo1+R&Q+0zcf7S(#aIf0HVAT(&b_QIZdqrP5Z|9=c^7acQGR@3nie)Ebi( zdrYTe!9FG1WEJ7&OCrzyk^f^va(bAH0c+Wd#L#q&Mon*_b*d+)DDQJMQ` z;?IEUjmKv*#=>ZiFEyVWI~=O8U-e%pgmQ9Q{Vq@(edt01Z0|=^xWAZ;D=NDNl3Q?o zkGi+3p$gh-ToCshNO$TWS(5T>Uh29gn7(_fRyi6}SS zjLR&-MAvN4aaw`TinJTm(|q>km;}ULRBE!0zVwmT)=2(G8C@(Mm<)^K+quo(`6zI- z_m<82$@2RSR10y(X(oebXA*tC-kz9ZV-%erTszmgWw0%{m7dp41If7LwIUI9&BZ}Ju=W_R%-x7=s=(*p zW*AKO*(>x6Un$TO)Chn}p;K45-L&TUDPk{V=|3+_5&SRs`ZRCbA8H)f(w_vquFD}A zpU*?X^RtwqTdf@2YlVtDrW7j5Jt8WJG|?z z^DuYK-H|9DZKX~tUf7q`!#a&b(e3Cq_G9UOa`r^^=qo1S)1{*{0~=rs=7Tsxl}0M3 zaKMmfqT!D({)%-{J2O7D<mDrLZS=Z)+X4Gz{yntwGKX74EZ71vVHz;e+@it*F zm-plnXCH%HZXDUNnCrz1!JO73@xH4;G!7hjOlHGQU~e39$q~9JFNKI9tqmviLRUfo zJ}Z$Fu>L^Gw`B905RAS_h$r=8?Ku&{Ey^b(V{$i{Ij*k|zUUU)wWWs#Cz*JR{Ge+A zufh|B!OqY&E|xyXr^{&a^ML2Fsw`WnPBt;?F>d?`52gbtce`;3y2i=Pr{l`op??bc zgwq=ZB2(OeCZ~rzAFAgQ(+cfFty7fiiUWeRv6+dLCFC9nF85Lo0@7*-rE%Gx?Qcew z#uW1&rONA;vLE&UwRG_223A@dN7$VY=^k^}O23OEj24UxOoU6kWRwRsJMRN7+(7CY ze!{Y3TL^w>U5{qBA@PQc1Hk`Q)Ia9}3ISqa5YPYB_rItto(w zg=K|Q7E%TeSHH+w%uFQ%V1A3Mp4X=*&<9rn%sxj>aUi0|nvRiuwXon~+NLGNSKUk?YV!@91 z#&7xkmor9<3M78mr0w?bCZ`EN=ng_x<0$UHu#G_zqAfscl^^w^b zG*kYvYA%zHdVBJSJ;3s$xT$(Z8)tl56?Zr-?p{P<^j1T0d2Klm6#LWNdLIs4sj zOHxk*8%*yR_CLR7kYG{mb-ebIp#S*0ywte4`|S^|(mei@oSix8qTTloc;@o+<+Oar zH*U8P{{_t6QC<*~UoI=}-wGy^=fQ`Vsc^r|B3__`U#5Bl z9bs2ikanToI24-=0TQNPW&5CJkE)~vyWf9u*^c;56qX)V>Fsz1tr1ZB(V^vRP|z1L>)%Po&Pjsza-} z=#q=Y>A{%edI{|5L|MZmNnPx*f$v!K(jD}1xi`sq`^ot#*~qwB3&q*jXIE{(nXU`c z42hy4)X$==M~RWUPss6>jEGb49AoZ8m|}FF%iWOdHTccW0!GbRJO8 z@9%2Q)-bf9kZ9p8((sZf2Cy#D-b(c0VWG#n%jtL4gZ@r?QD`LtWnbI+VwcP&Cn%xY zdBSO@fzvnUo4u{Ct@U^gl5w$xXyk_RZC$7vU8q~kDWsF&k$vh?$Z#NLJmK6>F!q*F zFE&_lH5Hd29hQT0Qqo>$yf2qrY4e4hb$)JW&~tQpzE zXQ7#)k|8-nA>$VK39&4%6pi`pje?85#^P6{-GT!PfR#@-T+bIz7FuNm1j|)!a5(js zJD|t1x@H*K6ou~5*)W(*8TAj=U7xPP{C%yw&>RmZm;ogg-Y2*3FI)Zo>?`R&B8c(!8Ox^dgr06lf~L!t zs`=6P^=!48#Y#+i=gI6_7o-eo?GRuaHTyRw0j(crU^vrNEGMLtLda$I-awsw!*iR9 zZ+V-ypYWMww%%XNCdAB_)HE;-#oMbE_48rzk^@M|v^5Ps_tb`~c64F8Jl8_@kTA>h zzg+o3woI4+YSY`tT)DSR`=m%FHd4lwUt8-Q`E4PkqsgmD;%RN%hY&KB4nYo@n+vi6 z!e$^@R|?8N@<%m91TDHnD&CfrK!#iI-*F(06YVJx>A37!~@Pw1F?ophnB49BKDPMLC6ZyR}Ei0({O0@ z7TE?DVgY_dSp;gPgy#w4t$(2Q%^ay_;Po;zvJsMDP4UsE+nte z0BcUD(H7b4rl-a|786f@{t3USjv3&0#IEaC@~*wYI+ZTC4r^I@RJ)rhNaKz~d=TgN zQ|mgnbJPXr{CN+Ri8)hy7<}BJK_hMM@Q&&Fb9|4oa(!&TJW$2$?d=PG@6w;n{YwR7Y6U^f$GxKed&a$aK;Y!OI9Xb383P%8RMx>RU}=PnPA< z1$R))G0aN{c&3mu-qkpaJI*+ztdDq*if6 z&u-@B%*(xLx>ZfDKebSGFzR6Det`Gfnv70uJ+%6}0c>2$TEAkm_dRr>#iCj~??LLe zDgkVfTM~Q!GuVP_XvWZYXo65}jYs&5fEP&AmyeJU7q?kR2E2UCpoN8e=ba43Cu{Jz z>Us!DPxzWuWW~hYt7VwGve%m?(%5Ae-@f9=Q&7VeWrU~pGATw6xKSs1)Joj``z_3W z)*0|#^^-HdrC9FY&SZ{FH@;xtdxYXlI47dZ)#aucUlSX~JL zc;Z4JAW9~tFU*M=NR?lrj^;V>e)09%Wq{2Cnma*j=TJNr+}j`&Q%3+#{$s=R|JU{Y z%D+Ol`nlaaRpN{+nHa;!ZkvP~8nqdGgwW@b51k#9{-!0m6ud^!vk@)2H4C)FDEwjA z^ix*U&ok~NJyXW0bHs9F;u}*f)ImXt13EA&g7axVXO8-zN>20C&`RiDm0RN_kfXDmdm2QK?@TIMHmhlPm z00JZo=@Vf?vg<{>zEV^AYlZdux2@P9FFbqQb7Q8D$JeRq_f`6=7X0XkK}>T1)ccq_pXaIG zwJ(;|FC!yr(kPNW&T*;(GY+_X`(P`AKq?~p9IP+IJ+XA+dAXZk9((M-?k;-Ot8m8l zBfD|@=0!x3tS3Z~h-EIwch@L|1`<r2KCqb^y{s>^jE%nA@m-zZ+06F&IE?r;18*{qJ9OBIQpqm}NJvaN?)?Vp!C!;@oThLM1-;Ht(U|b%56^_tnZ5G#D_OR+d{QY2$F{KzL`O|{< zF41*}kq2Rk=ZPAZE|Zq>I17McS8D}4epxu8G*L4YdwS=9!F}U>S1oAfklWrx`bQp- z?92KoIU4`YRtS0*GhAZYf{YjG>@T`k!DA!>TQBI`QWb)h8^8}=cG zf@;)#ma#j3fya$idaMrdZL29qjg{!x4s zD4`oz!x}Rq!!lYlzvVF3FnXeeH*{8Uk@YrF5%Z4|tEDD)wg5MzJX4m>*%5G84xv(b zArRFg-fcOKUOlNNFmWFM!PqnAqMu6KSG~wIL|Ov*Orli%2|Q);q(|dl4ZO}RnmA$8 z(?y&AhOV39%H@7JUf&ZZOIy&3cO$5D1jfi85(U_}}XbLi<4GdEK zGHTbeJ=1g?JoBHuRP5r}-CnKX$!^>`A`xVKnMC}}x?nYee+wtqz4+Sir_Izwrp8zl zirpUYEr9B?p^mg}8JT1)9?x?DCbi&7y_e_PqvtCxy){rFe%Q3HPQ|A7Lj2ra3h9Px ztU7!=PksW;Kw1qZz4ybRw$%xSi?&xCWHDVIA(WhyY|s1hGlP_gSd4#Dc8PPXKsIhV zEA9Jvq=dhu`bxMf&wiLzx5BUvY)``c!n72>I?x^#;wydhXEN#cg4}8?khbgit-<8# zfUdBIzTrmqiQN=`G!%)f6C7Dm!$G3>4z%uFHdkP$zaW0!28_s2?8?s!xFlWU{C)S| z{C zfh0X|lBVymA8RttYBv9D(6oBdi@#~$y7ffYu*K_`g4plYlmL&oUh<8jri)l*o!P~mpD3CwlMqlO zd?bmF*?$-hbiXUxyeTW#6{Z|Xh?@bXZD3@g)= zV=f3q&5_6!kv_ELnT1+|sBZP$EIXLONNhK+s~F6$XXUhpOJ#G8KH zcN^b7m+5=CxYj>aY!%)cvQ&AiuO`vAbqS1}Av31q%kCQLxqnh}w3Rv3CpI?%7nzx3 z`*4x`+y%4d#^MDf(=B z;=5AUIk-}V9haF^RaGBXzW>Af<~c=ImyNRs&jjC-uWl@v@g*_%ee01k&#j2$E(6Eb zgU63yZtR_W(j>iDdZtV%=pVu+k-}EtUBNq!Nhk<13yHMvX&ijCew-K#vVvy4dtn@a z+B}Iz{gbYCm-K1_Rf*3jM+MoOs4DTaG|KVTbgmbxPE&Tey+DL0_7#XPF0V`5StGW9 zPzqMW5JZuJhjE8dW&QC3oT}mL&Uy#IUJczg&a>N4)*0uNGWi0{t;@O`79hzK=9L9k z>B4D(hNoU#fWDP`*>{lICFQt#h~T}D24k5N>igb_Z3G4!?({FKT|8P6IopqouG882 zKBC|Q%}q77sctuG)EmM8A1|a#BK<&z1wW$}w|-Np+xhP1LU6w0If|LX+b7E6>}rU& zZ-1d9&k0k~u6pn)DezHU0QPc_Sm+c}oR8gJ$QV)0lrq}7I7#N~iSd~Q!j?0{2?C!; z!z%MW<_<8KcZN=v5XsfD#IIkBKlY+h=&L3c>8fM~^ET;D-%t)k5R5pO;|2uA=BHEQ zj1p|;XCgjFimU}a?0-8#kjZQr9bH^B{4R&THTR*of>5mnGs*-Lbe<+=M`s(}4!@mK z$$zI;?~raxM?1ZbKa1Q)px$)uO+}&@W$qjt9Nc4~wzh^~FqdcgE$#U>#y>Y63IOed z3sfVO^(JaFre<1#Z>f$Hr?+&M`uUc+=3;FWX^_ff7F%2sGazW2vK3lZ_-s7yEuYqRy{uVdJ1zyXh1#g7($~%J z-RvLSiR?n2jT;<V5&UWs#_ct%oB;wV&W<)AE>pkqf!Qkm38)J;_x<3XpZ_0Y{~6X)`hAbXV?jj}L{t<+ zY=}~o-h3-lShQx)^BNeTD}x?An&hC`8TUl2`@s%h z#sEMTti%>y>xA+7&e>tORC(VSEAF~`Ki6c{v~F-%1@`L|Az9K=VPe=7$($JvCXL-a zCaU(}w(Ya%d*>b=O&Huv#Gn)2{B?-F0<;z`5J|Hz}#TG7i-P@ss+Q$(-Fff2~ z_+WHp)GQL%&?xn!r@qSMI7375HXaB8`S zFJ6RlgJc-eJR?JqESYMv2P=O^(D*YEaYPy&XJRagDo3e{hB+!K&)g-<8t5_N2CGbdm(HZ+XrTGJ~&(GxQ!Q(gS7Z?<5w$APRdPtTV7r~OZjlUE4z-IL6S(5@%zfJjU%zz&3ct9ctNnV zSH)h`V%s6&rvwJ}T;%D}$1`p3OcbYUekklLM_o4oT(lJL!*{%)4%+ADZiI;))9-b7 zufzPbz@Y811dU9K z{xDUP{DMY|@RSktEqdDl_o*wgN?j}1AhSt%%;41_C)QVlduT#BN6C-w$h|M11;{)*!5S3gc8R8v zx!Bca84|Z5zb%$$U%oWG|GKr!UOk$f>q3b2X<@I(g9IQ-uZ~H7WE5dO(;~fxB9YCw zGjNi=u9V*QYUJ?7Sa}|!ga<~Eh@|m#ehKVqvL%247p{)L?BP}`4s1BASRj1@2fNPb z9^6HAQ2hP057S=7e9ogmT}U!!1y18vF$#H2db9HC7ub`buj<(R_s@Lze_8;AZm&GM z19HN0{T3gKX|8YFYU`UPCHQPs0Nq8Ccs7f&Mvj>PNtccz0G13NI^~SR4#O`^(O<&@o6)f)F-_i`=rnjn*!KbiiktR5-_DzXMRc;#bKreBwnv;?s??;`ujWq-1+N!1yXSRCf zi6P7Bld&nXs;j-LkR%P+J>BdxkdA9(S3hH^f&hO0_KHb$Ng)LY$y?$CO&I`JB}9d1 z-_FeEA-iqV{}6~aZ6%>w>WhHqMsh5A#Wis_2Yy(R3jlHu>)(Mdydzyz2ruB#TzgE8 zpGrP(*d+PxSfY%#r3I*vZ}FvT-^<~3(M|OLsx13fX5qT|Ed;#BNls1Af9xg#!+SyR zn3J#~diw^BN}(N=70oz&WtMq;&UleLVZmfzg2m9J>iBAWqwyt5l|%f+x$%TN$R+BS zR~+G&?mUc$MS#@+#5-1BrR#~6UpgDgTWFM_QusV!o{N>OmmtMrQ7|B5!plQxJG_DW zgu+p!s-3USe%Ib>bn+3`T*+t62Gr{_ockp*rM^`h{*Xa%xEs2@sk-<&`e4vimRZP= zNXKV6OE)X6GM5Un6(+HH7HZe=^h>l8|nrZd;OOdPv=pDg6)Us2nQ<;Wlw%E<{NW(3$sOu@f=-?cL& zs>d9-%}=%CZ$+BQPcQEhiFG=0D5BZGz^G!x&S-Jjc3!nJIHkDk@ZK z(F>U{LW&c2%~onY%&YB6Ucu1gH2184Q!J!7TeKef!!#r>{VESG3@LV{xXrROZnboyQ2V;8S#{_bK~}*hyJFSXA6?@+XL*K5k`q{O#S)s^EMq` zhZwuDQbj32AFV#~usg_D#z-XrY+`TXO#&v%OpaDTU^Dg_$zAxmXq){c8?ix1K`|qXEYfqZC#jNI=joDw4#YEQS#TJ>PC|3Jl1L;N%q) zbhEUGAbLH!vtv<-pT4wJ2NM(&h%p6+ZY0p#t?;vKFT1~X|l`3u`L=hoAbiFg7js73LxH0O_O#SgI7*R4kc}HhWj=0vN}MSm@X!E*v}Qhqp|WdlLT)eGJmk! zPy73~o?=ci1?YHyu#vu~1n29n9VGYW@+=}PF;W3Q&y+CQt||Ji467mH zd6)eTYdJts4`_8wYO)>Eku*P9p?Nns->)IH_;JR8*^p;eKu-s~{62FvW~5rplU{Gu zAV|Ri)vv9OXKQXgU4O&~e`U=Pe(I+7zH#e%v^KsJ;krwYPt9%?i=6W2fL=5m(F^V#n9^Fc}l$$M9P`Q54BzO~?yO+Q>Gb?EZXhV=;|Euf=%4R-!$?~Pp#j98am zf11qmz%Vx}wo?)5LbJLXB$$QvvyEwKRs4+hhm<62vjvep&&)qkjX=qc5TH zCjGJC=FFA8V*As1@7AQ^B1`*MTf%-5i&n5}v(y?{cD-y;hPWCG2$`Hjqa!Icm0J|> zdxMG83=<2?I#fJvzu*P}cHYS3&8SfiuH&3D4FGuA9frD|iBP!yN4Yc2LPheY*?nJ3 zV#I!r93hh+2>PhK42y8+$oU=J(6d*I4@6Ziah$qaeZb~%x2gmcZlk3RUp~RqN(n!k znxsR1`6gRe7oS5u^A~-Lk8z^egR1~*Tr^vA z8GeG0Xq^H(1v?q|&SsA+yo-$U_E=>^DDx3+>FEmLd2-H|{L-D1|28y2!(G}PpzQy4 zv+WEIh_Rxd=8iI-RJ;NDRIDyqTP{4TU-X9k#&{P$5KR0u(qli6rXv{BqQ^T{O7GkR z$__iI6^6$lw%yCK*sS(3t3(~2u?-Q6%Wy0~->U1$8`Wu^z1^ev$hzUIsV|Qi;aWA> zcT#iRb0s8e4>jC5L$@)z_k+Q;_!}&PO(a%a%%H)kDBtDAtg{<$uE>U7LIX4+LFWuP z$-WJ;1&Na}K|*u}WWN2s&ejn+5tsAj*M(RjO~KH{{m```3BoU6-C#s%$} zFhl#hLp)nZ->!!19?YHn0R5e~+?^|OT5nPG$;CS~#&cL(hp|FhYzKxKK1FL_D+#MB zF_Ce#>NPoS))n|LI$|sstG>VE{k4Wt!&cmL3QUqgGLXi+P0CpI(MnBCEZTU-6fDAo z^}NwLQ>FO=l6I+?b7z_U_k9=cxOS&YB-*XiJ1%SJAn8awPjy zEK8BvQiKGs;SJI%8;r&FzCC<%*Ose^$8xuXDV z&`Zf#?@+OEqGM>Co)+91)ZZ9Mo0>qE-OqP)HFh0XR}Qy`Aq*SF<}}PY45 z%7tebC14rmZ%@tlFz!8Ag!gy$Z&+=1!EBtm|KcD&2}qp^xz!hobHef~);;$)7dI^X zOn5#QpduXGlL-%ttWx+^Gef&-q?bTjKeMa$a4Y?ui{Rp4o~!cSS?_G1(-Bvag zR;3Y(S(2J*-+sRJk~xo*^#M2f^76elzxoC%!jZ#K5hZ!0DRr}yXHGZw((U)fE{##V zRW8lQMKuk)-JQA0&+SRpMRHZ#+n56ZynYoODUota4c4}g{hS?#c+*zDmeQxAI376l zP?)t6$?x1rWr9f*?AHhR5QFhBRYluL?UKbzLR~4lqYOK}i3j-DK)r1L1Krr3oq3dB zmb=T7vvX8Cq5|9X(bHtdVFT$*2>(AC23h`*mZh7v2C*D|b-#ez`ufC{`gj$+7jTr3 z`N#IW`u=rK@5#(#J~KgB0Mm0~tuiKH>CcY74d3J zKk4K;?Ri=INoI1c#6StqJ z5zn_ZM|SnS@t3db7B*H}Z8VZOAZRHvRiTopZz0|OS#GS!wLzF(FTfHZCj+ptW9=H_ zT^bJ+5g6Y%;afL7Haa)SblPy4hM~rT7A6ZTMlIYRr2EiZSJ!Q?cpI)knSZU2T1Rb? z);JsY9zW;GR&^hibE-&K@|1D8zY2it>L$(7CV>3Xj*gpx!0ysVtXN+K-jn7^5-RQT z#}7JioUkY&*MxX~h$1+gtFf&Z^S1=I<)Bxc+VyU{J?d?H{@&v2<-mZhN>|ok0#Tfi zMEhl%2~`m4Nr72|rqo~=^xRo!S%CgA(pBtx*ruER@5xNew&<_%Pt_->>5<>M6wd{n zKa_tQCY_pgi8;G*j_Fo2n-v4JeGwDGE|HWnxP+R`N9Z8?=0hcdBM;;6));L@9u|C9 zL+(<=!dKhfCw7890u7sS&z?%WXN#0k$2+rpatk=mmrlNU4Z5QZ3F1RySX*56cCeF( zi=tUil_a@a993R6+^ECLU;bu#fhDw*!}Nm=@|>2T9AdTBaEC0;S2>vZtuoNnIS{FM zS@v%HArpcy**G)*IRHaa0rqm{No_NqF>Cynl&X8#L~INpw=JZg^<1cA2q_p(_XbL- zRq#+ULv_N+E#IngljZdDHDS_Fkx4D}!n*8E(%nHg20#KI!T^SjXkq)Le|1zk7rN2+ zh}VlIC*GiUt?i=j)6rq3>05p^JeJ8iE8VJ##ab8tnhj&bJO6%XWA9cUzzqIRR`tt483|x$ z)A{HWUmbSg)`Ncn)67QJXOujA1;(+U8Y49cgPb!O_2O ztvu$@A5mbbxk}Q4yGI|I$J8dwDFGNAiYqNGtqfvFyw@6X)OASa1Zj+srfmN>MPY%> zSjcmhMlY6HIxr5`=H2Al(bYP8M{##yq5G+Bs~WzTlbsSC=!h+!n321w5-(kqG2%vJ zTVuGx?YpVJlpzEO*-MW6RP{ZeFjJ!w%;1aMH);LRpv`wz7%8y1vi_wqajZNR%!&L7 zdoamf1*ua&Yc}Q^K<7Jl{+5FXRCd^c2gEo$Kwx0eaL|nrFa-AT>kU#@U zD6)Z!8;XZy(4JXnumMph+;Z}&qS*eO=ERYE-SVomPxAWv-z|B=h1PLEc+6zUtlEWM zN|#1ebFjjcCg;)XfHu>zoMYR43{_a^ZPe{ptrWG1FIjwinHOseraop`1-F8AQ;uJG zB)knhfHt_Oh(^W7OmF-azJXh{AP|sb2)p&-fmU^}xPHnP56Zyjgd7cxSCKN^svo%6 zBpryQKQ3~78t|yhyx3E+LC@7-y}5?s1g?m~lWeR8eG#f&g{ieQu-*~4bmVj5_NhDf zV9X8$_9eOKee9{Zc!u-Zw_4OdI3Qg6G+?|2>Lkx&2vWoWopROD_-9@pV_*NMM6Z9! z0F)vnrevk^=JeJ6|4M+ufZjpE3oq&m&q+Ny#J$O28CEk2%#sWq$o>SXc}lpB$`h($B9q$DUvXf6{BCxo?Lct zGl0KvVlHh%+c4fbtzh5mD?8-Nh3cJ+A~f1PzFy_)t+5zFXq&qMIkNYylnUCnLfi-+ zmyMKYoeW^50=n3j5pa$`zUa5YFtLY6i|$FS9KziW;|z98f6E08BUWXuVZS9XUpUp5 zYfn#A=3+JPakILlud>gxKVxgi5dTg!q=tGXSPiBIlhNA*$oMx6@YV-}W z0LDA`GojA3;l0YvF5NG!-DDybb~{?PzDOo3A@=e`Yq#a%;)10o=De>u;MU$jgAs8> z?++5|m`k2ui=PKxotG+k)J$?n;w^z1UH3BKVGZOC-3?DbW1KB!^RZ;wa@YWYm4_+@ z;z407Y(;t1&x?w9&aLu;yG zb*FQO0ZgXgZN5lzH-!SLZ{%zu5Q<^%(SapglCMZ>CDG&+6Y+&?+L)W9Xg;KPk zrib1*eKd{ycI}6MYJLOLG#q_8DX9O)L2(Q~QWzl>H*hbschOYnh;0lxlE5`&;1s*ny0e_ba-JQM* zbMZ^1d(VE1lt>PL+>G>Yky(j(A7tb$#3kyNRVqUH_;(KvhKo9=3Zyz-|)Z!v9TB-_*7-K2YzAV2qnBQDCzV;*P? zFS*3Dyg*%?r@2~gQ6hb_+bN_=X|YnNzeD$Quxlyf!To}sH6@N5pD*uFJagmhS+3QD zo9Oe@o(KY2l-YCqpm!Ao(rI?Gc~~63l!vWv&e~G%BWWdvYHv~ zc-2L?PdEnFoC1^IfaQ=onxL#(RfpaZJptz>ZsXG`q9_fh-U>p6e-^t0-%PW&923Q& z!xRHHyOt-J*>-Bmmj+NR>aOnHSvq_az>GSUv*=m{a45eM0+XDaJeh0XTa(dZXG`bP^ee_x@tCWM_3}`ZYUm~!#xfYWHPrzk zfZy*CWRn9rN?Ih)Q}L=A=d#M)_<$GuZ_?AgRvI3nmie7JJ*Acu zip!JSA&N!3sBKYgaSra z8GsfstKtwviua=WIUH`EgztyvByQy zlh-AwlSLmSA)<#56=`Z9z#gx|5KFm>)1eV0T?9Z2U7xk-_4QZg z=q|my0g&OY2ik4ks2<>ix|lS>T|Kcx!TX+rzaC8; zPWs`w;9#TFE7R$J>75@yP31VNNGLOv`m)yVwH=G`$+pT)=6AbkW25q^^Vmg0!{ZL= z1N~Xk&bFol1;HiO^&Dkc;q>B6x((JB}Tsbikiui=3-N^R587Xy`D8O}ipsxJN z6#RW(>x^Jd;`;UBc4F$c!`DA0nFZz34odm9HfJsN*I6IWyLXQ*>X-A<*Q7`QchBOR zb^Gj4O_8bmZTjDd6~xrkm(u{CkR;eGbEBstvA>E`NB7y*b@Kt$&g50;AX!@Z zH-lYr_Onb4oV&d~t8+TJx;$GzU=P9Xv|Hz|vWM6IDg`LOed$rvEMVAPOPDjV)*p6< z(D=2iOGUi>OMHo;Pue$3W^k<(1svM&QlmLeu;PB^8+VPcwN@TBw%^nfK4+Xk#HY%; z`o!2+z8&#tmxRDzt2)75TWxiVa_|uth6!U+rxJwg0FhjVnmv4na|Zh00Q@a$Eb;!# zh1z+s^4u@$4Wx@stCuCb-@N*?A(4sdC1{A4;=6iP01FbX!h3|*xUR$byqZ1_ZXf5u z(B-_Sm1r%7^8KQQ>C;lg1Il`>$`)NEKJjo!V!CCkvPsv{%&2u&=#1L!u7sb;rd?b! zHTsRv!hlhz)9PE}kSwJzMj$Z_y^6^)H3)&6K5_qxF;AVk*uq*ciEW?e9cW()as;^3 zbAT??=yr>lxsUMt7Oj6dw|G!k9vqO`8=OO$6c~q%{VpDSEgc*If@PueEtX-aZNy}!v3B37T~4Upwwj1FKVAW%d`t+J|I z!38Y!<4XI%!bKT$$~YBvD!8vAu7zc!x^$nxAcEMCp&3$bebDoRGn2IJ&{a}jlxs(2 zz88+cB$~H0Z7MjJH4jsBq(kSH56iQ2jS(KP^kLTLyV=ozlO~NG24>&w=r#5o52pc~ zDgAw;*%4G9)!a%U+fQ{%A=yhx*K{pi(@?E{%JP0^&rW6~169{GgcM+Q#kql8djo*? zkFwLEr*DO#4}Q-2rhQT*8FlBgE{qq&BD zl@Dq??rq7}lg3j+O>s{#cxR6?n}E`nhkphN0;2wjX)}B+t$}nO7RN;Tp)bZu?Zly& z?T&M7(rUZcPFed!d)uN3xBq%0^-#3FvKW|g^_jxehI*f&-_CDoNnEg#{nIDXm+~~q zZ5>jQ1l!05XHX*m@xfO>V}l}@6U%)b6^k*7xZcxwyY@(hD+deI$K~J9Uq0n_apLCt z`xerT*5+&@vAN(Xit%UuMPMWe*LDQ>fC$h|XG-&N!7qm1$6fz$G1Sf3?}jfL6d#H9 zd>0G)!hdaDwR1zfJAGYN)Lv>ED?xw#b!Vl%d>qgAnKJIFS39Pl0)E`_eq!-b!B#VC z+h>7*u}RWnCkZ*@qC1P61toV4ITCiwg?u}L_qJ6!z+I3IHbX^hoz03mkyai{DDU#r zk*nzLI;g_E>wsIwUTv@5ZveyU3eaVVy~YnveI+AdE6*1c0q67+s|u2|UwnA-ejM9) zIBuLbXHts7{RPR~&ea0@?&{V0t}51fcQb(y>#5h!Wo@4vi1C(sNLYTY$x@gfg;n@s zdyCz^bh3_^P7H1U1CG6uma=Av(QLsBi!N!g{V^jl4SkAm6(&vC|o*f zYh!P3zuG2_thv<;p5>v0YwW0QG%LMVz;%q*{I6td>qS$o(vtM%=f}tVbi-Nh3r9^DvgxiBN>Dc0L(;;D!eJ$lQ=E!m!Cb018aqWvoVX@VGug zE~l_t>Gd3mIIYAYv5%LL`$&iYH)i}OaAUtc0r*9=VE~ndwE>{VtiI{iB!12qc_4;y zMc|)X2*!fH#HTa%6;Fui^1U4hk1A=lzQ3E7T~nSuZB`z(c7bA)>#+*Cpciiy(s8ZD z3gEYkEu<_IFkX5`=1)IV3oA^z-^OBIK+|V{bCH=uyrlJMd=pn_30K|dGXd54&h;2N zFob!z7i5Lb?nq4F(d(nzb30Brj3jY9;*m24p(-WL8|;$g8^~$scS8GuTi2|f*UA48 z;3_`H88w@0y@XEj?y01{`#mn~9L=S(n#g~f!AiO6ZRauk&H21T>T2cUZhsug(o@}YYrqnO z26`FlB<#(_rmOxAO@jZruOupjUI7+4j2?9%p1Qo| z*nV#bF?}+j6b4&&V*pcqpeNkAYKtFTCy>rQf1pQS3n6HbQ?Ma{t%)K5x2Q~&3i{09 ztew$Sw_g7(qJCtd`V6uW{a~6~OU%XG{3p=cVIaa=T^7UGDx6dKGW=2U=-=V=qXym; zyH7Jcd&YDPu!zXU z`Wj(U5#lKgRjrs_5~*@L|Jb4~1nSY5DqnXh)U;9h1blH^m}UhbzaCvlP9BZoz2K9r z8`lNl2JN!;8L1f=?x3> zDf;r#p=g7WF-*P?NC*-@!WYrdidB4#2KG!=KXY4e#fR3oJPE|8jIAcmudFhKDbvIh zXN#AOyLmedGZZ8#6&%tBE-U8K+gPT+AgbTnCEzgVB?=rWd`43ay7=6m$+&oXgB9?4Di_7pn%sYk&2qY5W~e}7z0PtPPU8no<~ z`-o?ahwMfO+(tPi`e{#H)+GtbOa5$)q`i+*HEerJdzP$TbtFxC9_}yC!<5!aRRhyS zu)BhL#!-YC10bVG06KXR!e(9>2TiI1X>oGMYe5b6i=n4}H&##f-tHqJ`g%v9#0*6$ zP>fbJv$|EW{FY%_!o~w?Vj;dYUpE?717PCobN&nTQd z(sWNxTKl%OJ0s4z+*>6YGrX#XsagJ(0k`uDF&h0oA+-4bwED_eZ4>Y(?Zm5dGTVf>Rbts*AtTOQafX zDUSK}YHddts6ffbl#{_YkuG^9tXCIL@yn zvwQXp2*5@TWa?#^40fM_CM~EJ2fNm8n^Ai}e!IVk2Rf@&XO8E@XATTrFDHwp!-77w zCdkvA+?w8}uQSNBG|W|{%|ZM9^i7>SPiUGW&r(>kLT?xLLN?2Fj16eEL5F!*zj#<$ zHANeJC1dX|{*T@N=c(fP-@9~Mtv@QepH!FqYOKrqy=v~2UiaNq`d4w&p|?~k+OwS9 z`Xm1wp!d<5(Zz;uHSRO4AO59)vMH;n`64eoS}LFG^E0jH4N$Q1oM7TGfXWux}~ zLJ4-Fv`qOYji^&wo|e1u%QT2Z14u4vgTRvielcZyGkCG6({_;E4})&38i%bVd2aQ< z>wJyWjkNyl;O;$ensc{_WNMneb=UM>@>PmW61l1BsMO`OY40y7;(W^C>3YHXgj`#< zkLyqQ^11VZ-s;sm`o;g*Gm-FP;0tER^Q>G25j&i_`~!#14wqX48ck9PI8Qq}Hq zEpCxhAMg8TlZH96>LhQl#il%mL+0oO+LHqL@TPUCI~9flVNWP50a2hU2tK}^t7uIP zWiQfMCCOYxtBf-D>t-WlEN+=P{2S;x5J>kQc7DFaDC1`PEwQtO>9c_L1AVXxXe^mK zM`1ni+WY6*{!d#0{A%#=ZZet77I&GrXKkh5(n9^|+f_@v@0BT>XF6;s(2O3R_qRij zsBmIBrLr4DfMXXfBz6RO7cYysTH&+kKIt2W`Qa6X8e2P-KLueJeTX3|Z34cTfJe?S z^fCh!Rv2Z$*vtuYr%b39CCIubEC`rGZ%JfL$(J`I01RDx9beH$$iFV`)9E3fl8$Ht2d7j&d^MaE;Ucb}*V@D7&K#nBAAN4-@eqzmF%tqAHXo;Dqqz`+9ItA zL9fDyUD^*~k3LRm-$KA1J3Wphg1y3mGkVB(l;Z~prA)c@thzUD9YMYYHOhOM=A(UavnYsq}uZxF7s-`~Gs~82 zoX0LCP(~z#kr7s^WlyADy&Nin0~BHyiZPmG9l*Nq*d&OhPgnDr2;UTt1ikDWVFP*y ziZ%0J^TT8|=d}LS`tRDkpAT4yl8}q9)SlR&t7}Z(rhZPqHAosr16U*uvsv#*MIdqm7}d`hQ-r!02o=!hZvd4f;$?oAkp(sc-f)QIE9;uhv{i zRrUAND`i^b)RzGK4aNhs|B~1~dm_lLHvnkr|0@*P7beN#xAwj3gh0XGZ^HUAvtJ^E z#}>lOCq_5XPD0oIbx*~)7Hy#2LCM-%6_i(*cP7gp`{~AhYBFrAh|kT*X)QiAuz4+3 z_X{@JL$KCSm-BDe7cS5Bmit$mOa3cNl_BT}PCfbELSMXa*IuiTFb{lPXoUuS2piU_ z2(ZeIW1*>7P(RGp*7isQN9E$>fw-O$wegoLk6m+qbg|qI0(JyAaFlm2RxFJ56^Y;22&p$O$w?n4 zV=LM9af;khbxH?`1b!byzYVs+;3896N{U+wD1-9@U8zF!si9@jdRu2Fu(Olizn;}_ z`2&slL*r*U({OP!_m_VLS`4st69d+Kza+ZCB|C!E7X+l9=l*d8S(?YxW^iRi3an)R z?lLn$I7HgsJtRJ3diDM-e)SJcgvgfLqpRHM(2agm_TXv@;#VfDbQZnYl5ZjuFYTIV zNt{o8+0NuSt#sAr@VvP1$WpA3!I-De=12~7XC4JeYzAZNi0}bs%#pR)7$TvFhBXq-1qUW0o4y&w@xc#s`eDpOLY`UCXJ~ z-uStb3a)JFz#m-WLX@7j!Qw_)8vo&bUheMh9Yr+RQjRVdUK?%9G|-J%NEY#Ttydn% zNHdYEIPAGU^7i)DSl&K+FyrxshY80lgd|wa6N>Hzcj-5Iaf79o(-S&*C>|vyz6Z`pwAgzRX!Ye0ZH&lC$FM-y%MalzQ!JtMpR^HG-Cf` zrQ<^1v+AQ{lW_VQGdZ|a;ITs*lK}Up{beZHKV;M+Bxnx{@Q8#Jpnczki#Qy*iD+u3 zC~DMpF+o$Ou+&*m0DZntbVtS-BK+_7>f7$SqniVaul<*PX!KrkOmhe^Y*T0mvr|+! z%84H?y0q++MfG^B1OmYmfBdr<-}mjk*KH-H4c?CR4;x63nur4VkXTam5`oAcKM1%W zeIR;X*L#j#u!P-720)_@H105jxs+527p8s)yzN3!3_wOFPC*>J) z$aADsUo0@~wX3J!T50ZODW0vVoc_fh1D=WwFaE>=N}n|O9_xt_A4Xxyoy8h&A=XsS zyftX_{EFtTqGyc$2Bl79rDm)C#QX)nU$c; zM1?c1!nsTgG1avz`V3LSZvkk`$b&^U|1sPD>$ny_;K;R*Q`=es@7Yti}J!lB|cmyamKql6*!DR+iD_Otee6pFG3(h+yKSyppo z>*g6{7In%K+A@OoUJeMw@p+u_o9$3&09mI2e27pl0QKepGWAdI=ZhXH$9Img_iL<# zCv79hX&wOn(W{3YIrhIE^p6|&ul!zLUoSXyY{Y|bUOi0)m5u+|7C+C! ztly^zV;Rd{`gwmYS+4Ze)7(x(qRH(-?+R|w7W`?XiM%ya*Q)4R4foV#NID`dEvAzv zA(eI46Dt`8@Kf-VzC4YM=J}*Us%7&wkwAwFT_1O)sAW7m;Y?=O)*O`KMPer!NYR2u z?TO7{q5tC;{1fVVIULaL9u=Itt(Wxe$~8n%rO36>OTS$wYxNuTgyqMAF1(ug;dM@w zns7+V=}$bMU~o2i_%Y#pE~-SSW#rwIr|ERRG8vep6u_Tw%5ByU&QcV4i1~o3!4uWR~If^R1Xv4UIsbS%gV|cwiCiJEI7Lbg<>N7 zhvyo$S#&%pnsz7tW8afCFHW*Ac0Gx3pwBW^ZS>cI%8R8aHHpLUPmFrTjp5vX>__pg z@cVMO^>Gz}eA6h5^_$Trhm2RD7vo#DzMPak9_9Xf#eebZMCk$%#vDZUvTSTZL?SZ4vlApf^9QS{`>PKes9dGy4e_iam>{YwfV5u z2=3r%M2PQ5d!@}t&r+`V^YOtCfW=Rfj+pJt??vCp*I!lihmZ6t*+fFa$_nBY)jO}G zT22T=Fc;fxHcLT8Y%NWwA9J0t;P)ib9t+;jefr5kVyew@%&E=bXNj zl9t?w?G#TPNvVh}JHH*+H*8}qge<+vK}XgZF`!`Y{?RmUsP0$NGLV`?geHES> zho^e>yQQ*d7Uj4c@xXlCRdtxPZ@11;xiOjNPxKtpZaEH&*S*&B^4~L|5u>v~DYWd> zy>5nwT3WTU6cQ`lZ&X}~cRfmhLaiT0I-AGlnbx_h9@_u6f8UFGuQ}&jB%T`6Ag*&? zetE!_4>mGmi0*zr-njADytj9BS<=7Fa@ng#o+`|qg4KlJima`7S^6Ox{HVxHnrn@h z6nLr{uQK|ANg6K;4s1GZ%J`X#KFb~T@6RcC{C!#)J$q0WzBlu=Zy_gT)z%t`STA%x z*6F_9W`_9t)7p39pA|;r=2Z#UH;A+>>91Buq&Wv&6pSNHE#xgV>vfNcd3^H~vH|1~ zF)Op#zzE0`g?TX2UUiZGdy{+-PW-URgjGh-5>E@u$;l~_y@6rjV6_L&8~(fHDGuG6 z^<+6(Y54i(CEO)vr)peDE_9~6Fex|-h>b#*cj?`FDuqCv`+r&hz_VHcSea|5q(tm7 zm+d$yMa~`leylUU1pQ6F1W1pEix|;?8W^tVWyGTpo)liT{tYh{9-INnJRKb`Q4_i;mIufT?t$42OxPs9bH& zkzBV6{Jl+TI*<|exYyt4hZl+K(~TTj)%b#W+93KKBkn?1NswGvfVV~qsW10ce>7nr zEN&ZJ7uI0Cm`Zc{)V=L2iS=ks+`=O)nBOMQmL@FpFpxFe!DLTLvnHj*(=F*tyTkt) zE1^DU9;;wpKRs~snic#BNn|M7P%6qmJ%4>fkqnW(eB})S-g!B7p$H0nTO7Ql1Yj3yS&)B6XWZ_bJxV}IwhrFx zi5JBMzoHBp>enc`-^%irI0YVQ^s+rii7xw*U8eH4VN)vQxEFqJxz_L9YJmAiD`|xU ze)}t_BZIYmKzqB|RzX>pz?IupF>GC+XBLQwCyD~yUDAL2q$2F> z%R`X+e z-YP8(N)^`Hi%lP6FMHGFLa(x&fz|*3aBHxSSI!M(2>^)4DBC1+?QO-C>hvyk2l0Q+ zc1~M78b&q<5Y~ejpJH7ZaFZI^)irIhOhxI%VQnc5Y=WFyaDk(Q`(^hFp*7#~m8jcr z+pgV${5Mzq{8kk?h*BDP>UjdyR5{u9vtoqQA;*vSxC7~c_!FX<0F3^mtmvsty1K4m zagP93vt8(YL>jMsZl5q>YGf;kgFUCiaOiPn=-;s0@dyZ7ani~9-*>w}_t94!h^(xv z!IIGhsD;mLL!zap*zYy~*}Uy0Fs=JVyC@`8EhO_N^Op{qRg;_YPfk_L9X@gPA8a#v zQvN8;%sPK~y_8zZd zkVp3?NkmLQ?K|U4<>9V>qSRuk@UYNeboldT{IL|*LrB+H!vw>Dhc6fS2Qe@<9Eskn z=E|ftlD1kN&|2(GLVemUENRy&b;dqWgN=pJm!1RthQVHI`l2nI1#4Tz&TL`EugEjZ z-#`n(9tZ@YhXi9&|MgTHQL6m@EryVM&qh7R3F4yQcfI#^MPzqPLt*=n0uv{vEmfjBiKKQo(;f zAq|(Vfxa><~aX_ z7F^~hYA!)(z2vQM@?#W&nxkQ66m>@E8$qf0RPN$au+2eYhFgJx|JP50Y zZ%Y#;DVX90{v(Mr3cvZDZB(Fg?Z^0r?$P!ZfCN+@S^!TR_b2ezWcp>m8(scB$B(o> zu!9D)n()Vvbe+YLk5bKfX5%qL!)`0L9w%9jd$yBEMjMiG7e%7AXrNtXWo)?Sbdjbm zn9K#(@9*KIh>``&(BE;c5Ge?UHX6BYIdbVgR&6hV=y@6lFeutb1yAc2!L^reagIL@ zyXato&NWT<6H0pbXTigb9@&O@L`;6Qx$QCOS#aFl1nF4o2pwMo0IZDF#|eP>=>? zWsO+d)o!}=)SfT6csGrv96sz?cH^jq$O6&e8O*RH>mL}m*y_Xjcy%>Z&^6(NUXwV^ zq}xO)L_qw-J-Ld}AX(z4`YK%AW;v!BIBX>g-Ds3|ZI8SaiH!TP{hR?2kZei=VHt+a z90MR&aB&I>W%wV!C8u^h<3Y&{{c(j?o6k2c%hVNQEQ?I`Zk{02X8IZO-?0DN0~9~g z3{rO$^lY);Fk?tAWgYmM0p`lmjhX8ax8gr>A}e0peVFLQd6A@8w;Cs{vh_LJz}pI< zZqIHn@=i6y^j5RVTdKAW;#vOmDL;CVe^q%xlZN7fo$I%v?6!35L|4eWyd0}rgE zZ~!YQ=zYxn9xA?~^;dPl9PN{YF()mVtN1I*h^BsYSwBR$F&;q zMP^cV!N=tKsaBE9nP|dtt?E<;DTHWD8maJ{$AXy)=$;Lb*YEG8%$M4kxN*^i5SD5m z3k(FfYSZH;6;A)|2jzAHwj3GTZDUt^8t!^-ArNVhn*!=Fz-ngS}v zUrXL?1{YID%Efh-F6i7|QfMm;-1n<@v{@QkU9pl$sUfC_E`mN@aZ3ke5nPaLfLmj> z4D@EKttYo*R31tOq3tAn-4hDQyct7PGyP4xm=Y!}tYnzH_c^YkDXsFrjmA7WH>N4Rn$3SD-S%ZJ`woR$*7fvzZ*4bb4gfD3jsyUmoXXpQf zm>J7IG8s?>kTfo{lx^GYUX!?H3HF~{zsl8hxgCENkGcKc74cwS;>+b#8Tq1Mk~Y?F zCi(>8+s7j(LZX3=gR+~GZ-VHaV}1;!nJDS!>Vn>0wYkTuV#CDEmM66+r5M@j}U$YC=SLC_7{8*8okG0g)dhp1383`+ySR}ylSt+Ops^>(}4UqY{5 z8+up!VbQtcLp!=YAwb^HXH@Hh9E*D_9u!1rY}v<83gLIsfZFQk!L_L%`kOI9$PA>u z{&ZJ;_~eOhDS5dY9H?JZ&D6gD%93;_i8=`+76q2SK@u_-ibibBnE{ZjDK5z7^cNto z=H&;5SE;;eE@%282o}XiV3HlQqS`w1-(LFmrZpD6Hgwe2xnR}4Uw9^&D0!NY$5pq& zBRAwWkrq;F;mDDPNr)^?8Mal~yK|E1Z22)r2QCqN3`9Ehsb}mHH1Y%e!1JJc%`J$`BsNbH~6fLK@o(la+ zBqjmk%aw-9P)a-mOa|`x#X~SNsII5y{(kAO;>qQq4-?p$Kvr|CSt{ObiPzqo5NZ5Hx&ckS!xzE^A3{c_NOCO`0G%oBT&p5@4k(n(D@bVV;W zZe?CPul(pvD$@I4)|K=b$E}X#DlQwcS9RayYkS^eD;Mjah_y;&>7c7xpZS66*0v>9 zUmMV9g|zVy z_mh1F^d>CRUIpZPHwm7tU2*X5>^_({9lo4>_Fmum zghvhJWKO@&_D$t>$RRTV5U(`EXuNg=5&SqU!A zU+&cj_ipnA&Z#%eS{h$&m|1%Ww4KWK_Vjao>~*-0_|>hZ#^HcVvjIoAU1fcy-y(c* zteP~z+{Aa)#f7G-~9TULB%O*{{28u`xr|vC-1fs%>yF4%wTn z(Ta8sd~%!0?)9)xEC!qET-aRkOeUl8M`ZP!ee2h?SIgDWSevY4C?c(@LIWUF8n3^A z?7c7Jqjx4Ym~!ZH+P5U;H$g`8fMF2Bv6y_d2+GfJ%wRr7)>1Q`t$t|D%B#e#w$)Medu`?|@X9^y;sob=6K;MCEp* z`V}`vaU5CkGVn5LtG)oUX7SE@*v1Ubx1v`~f@wr#LV3YhA$I@91F5;Sf^(=O!AQHR z)+++kP``%+K~DV{+m5f;^g4S}>QU9VdFPF8f;E{ZpR!h^7k^Mcahe}csO&R&fh;!5*_HV$}l4^ ze2Jspn_8Az{UgSxopbkZxP^}cke^7da==`k%A9Szd!Z6^E^y&>xk$%okQVH9n$C=a z%3V*sdI|J){PfT&M1t#GGIvn;1|MP8Cv&;p=w>2X&*d?9@hDAm;>FbZ>F|%WDJ)rs zBxvg^g1DxOvfLcau`9)?UKxll2ADzS^uxj)RW&$ME|^&!hPj$H2B!R-xtq5txx@}o z)UEDTF0W-T_0`{TlI$40Xr)E+K&;D3!2=Iq$+7{0ZN#Oh9Q_?9L>-)+G&ACXCZD}Jw2}TI^X|ja3CXC%Pc2nv{7`|DWQguC62#S1 zIJc!Yvq=J4*hfv*EHx@dQJF%|JjYgiyg%={`<~xiy-p@g->b_|6OPhbn8@KA_HOmO z^e8pgnh#i_wl(iF-R1*QoFy?1>{Jz=X})*+eI%7d7wTYQfc_`TfDHw9l`}R0E(rKjzGBakFBRjF*IW z)g!1FV&|+JXU)`ez6>9Lqbc6n(j#w@#>-JWOOuGeC)jzg@-SUKn=YC*)Na%}&;R^|IV^gKl- zi&(J z1}t?>Pq$jFzRWh=X(xOuFtWN4{u%z!?RfuzSfqoX$V<#U^XY(81G_ zyt%I3?cI?1O+A)NiL>hF>96`E9$mp9J2cvT<*Ym6w}`$pdzaDH`pM4AD1H~a9W}Xe za#MHrpQBX(3;Mtq(}MGfwH|PwPq}@3K6W2kbez=acAojhYxb2RebP4< zK(1$(<%bmS-gMoc>6J+)@mSb9<{nH7TIrA<4n0Od}>#7a!~s;OOJZ1TMyBb-7sGUnN>;d z$tN0u<)qW#a6Q824u;`7^9J4}RT?_`h>l(T@#mZ1L})1 z=(D8F45efcer{6yC1_K|E-M z;?@|VJ+v?su!zjRog-yg!$(k!o6!(u=8KSTFB(mc*VHro3nsZH7RQ|xQBd!h(hi@B zu|8WOlM75cLJ9|(BX2b{h)Yz3?IuqzX=cw!-&X*P1a_WZGoP=_pC3Tk%60T!563ji z>gboJ9uSv|*7BS-uuBp_ZlA{{MRxsr7Tz?AM}ijPMRUI|U+taxOfWI}HmXq`3u0`T zu~gFO6l>7B_3}dhYFOYTB;Z!&`mV;wnry1TzRxZZKV>$X%j$_i{Azq4oJ7?N6#40QF)SyPR8 zq%<1%l@MLDun9Rvu~c~OlWQ=+gfQ13mIC-d-8A2cTfUub|3W8k2e-pX-(~aZ>E|@w zgZ?4Rb`ikZ36`}wYQd(^3)C3*lL)MN_?3| zx@L2n-5(6L86~~*hd(v)K6^qLgMK{3q#9W=Rv|5M-E8JTXD3!D`|OUto>Bai*f~^oXLUuE#MKnaDz50(W<=a|Ni{W4X?lg> z!c5zbD5R$88gi_xZ9oomp;Suo4qW6W|hcJ(t(W)$USc9V{yXMGvoV!BW zrSBg${3P`235j-G1B}IuCky?ZTdkjy)AP34(X-^fHh!%jx;0KVoWO{_@|s#jr&5r3 zthvvKbyDiP&Us~KA%j6+;G+Wc+Jzi=T%LPB4yG{2CK>Bp)5?HUxq9StoOgP<_-=Qd z4saarYPSN=A#zgD)#=a&2pqyB+rpF={^{0nn5&bct7>ryPF_dzw;!h}fL&i3I8{1I z8j0#U*YptGvY9q~I)CVSX1@8Fu_h3|R#kn|oC;C9HR8+fJMIo;jN_H@5!eQNMjtgR zW6~7P><`FqV0sMH!7EIIU}NR5`cOKP*v?%43KRfHQzD{+YscR19$i=EH$8~NU3ir0 zkx+>i&;G0>Wu9u3lvPS|tadFkxwQY%Su7;A`Wm-d@r@thPaC`bulF|#E-V4gJkG`!eIdwnc*41XMb74P9jQF@dN!4%}X=yL9PY&Nrb?p2CJC|dXW-Avj6sG@0 z;Mkd-=o)^1j{7&NH})>qu5?x-T(PB8IT{Ufs0hc1L=)*eLJo5Xktu9D>}N}KQwrB`u5I(5Mp2b zv<7wzEbl)3ec)hPVW~2jxA;cqUkxqf!MziU1%NM@y1qD^1Ki+h)@7CX5$G}(ba{b; z6hCRp3m?Dxh*yNtWjhY_9vcW|@FSSaWkKfht$DHCmC3^lmcviX1zpxxV{^EwazH}SRmeK&?dPK;-E6@CfrD3gc6%*2sHlCSWnL!b z<=bhVn|hu@xPyX#f(b|^OEEDIjV#vqax(%P?FXs3N6Dm5nHCmcSW+&srDl{WNwV%_ ztt1lY!J?~6{-50Gkr;hpE}q^iDO&N%(FOLBTy;@ml1|ri{XYvz7TTStVw4?Ay|wLB z3$A?rbL2FPDpd^vqlLhl7kwP0iimoc!)=_ixAtwEzs~N1!$nA*lqk zc1waYuVygO9?ZEagAfKkmN`8w-wt8S;cbrZa^!)~`Zmi_&94>6!i-;ZiQ)o8KG{}i zRO55#%V`<0a+S?>F263E|GuG{IJw>z>yg^W8Gd}wG4hrBh)AM^nB)f~aBibhat6*+ zQb^b5qm0 z%dym7KXU-lARzXcf&!r+h1MM=xcau?iS!b(VG5VSUn@^2Ex>O|7n+gi+!*8dLI>%BkR9_Dlv+f1s;O4&=1;%tCMzcl~;!Kk4dbx=@(K^l$H}!4u zdr2qs49w^pbRab6?6ldDVJ&CLa;E~_<|{G%1Li9$DOcQpn1?xOiNLF%{DC^5S`mun zq=Tnt(yib(V!jS_Pz;ThB9|)1iLGF?a#_+M8U#VR`^-Sr={@$Mxi#UXAU#XWMl+{f zFUSKcVAj3|wqQEJQ_|I?s>DM#Iuo*CqV#i{3I>{8s8DAI_Bx$;!+oF7&7IV@WyY12ev}Nat1rtsv?O)v z895*||HgCC!)d?>P6(jM#%@+XxAd3}n4C%59qLr)LHzgO9&aznw_08 z)7wTYR(si;B9WJ_VFYjsC1L)QNt%3~Y?xfB zD>y!&D5VMl!AGh833TiqFWB=J0rG4ZE2ZZk&pQCCnXE7Yq9h`VE>nMd(@UTB9*_L8 zIj1_-M6c#S!Pgk9c~eM%_FBTh24&rpfAM9kOEkrt9aia)hNY)lXqup2gCxy*(_0c# z{6nq+WAEa|`FU{Y((@>Y;nf-ch#!>$huK7`a`d8`{iok9%OhsXR`rsned!5nRL=%2 z#3*+W_&nHu3v>U~x;Ql!G}SCgO|*DczJr)JVxyD+<7MM>w_L=ME?q(3J zx{hee9^%$$eXzkP(w0DW4j|eewDsT;xD=LR=WP+5FnQDCctzG-n5vpbvEW?pNcazV z*RP=|IeNntapR@vTiccIwPiEHZ}DqFlew=1%imot3heYi?n6tQq@dJiq*kU_*<96? z4<~}oV-1{YnJYcYbHJ9YO-3x*fWA(GscRLxrItbqC9WyW?R750+vJPz!1W39(oqo! zM#XR$5W-Cq+W&M*N4oRl_53HRp3*zEwW)2N{wb>I4CHWM?S=}eE&}JECY}2H{8CC8Iv8$1(D@Rp&Txy*VDkr{Dkw9fMBOSY$uGJpPu%cMj zWs_Yd#>cuaE*RBWIQ) zJBho0_Ig&itVEN9+w)3T>|mgdZXw>)`LRa4oup*#RiG3-1t>-D&3QEXyM^}+V&=Gm zQQyveK0K1O!8@duACAn^i5T{tsnpEVPPUPrD_m&)D+6~me(J$K@Ww~3km;2!Nsy4- z`h3}kL=qB^m8$(Ue)~*!I^(^%$^zLyVGrM~WgcHXodi_tftqO!o%S(7LU{rMwdNAu zzhcCka;PrWCJCrY0(uR{g&R=*VGhICJjq8~(xP<|m(NZ^B1WWzN^1+GIR~uie*67e zSvGo~@L}`dwV`^!%}?rJfg`X$-%UD3Jl|!78F-4=K8l|AG3!%Z!U6za5bEOfronD{ z&zqg{*MD?;K+Qqep>aScflWUhn>}23@mKX6gQwRK&EhBOvurb#E=$6Eyp_o0m$>6N zSDx=U*SN5W_R-wHui`d;%ngefh%@=5OZ^<6H{5me*aBC;tF1 zcg{a`;&@IrbW9+kVEj<0F5|*;MD$C$KU$;tle`ZV+_kc`#bww-U4obzxwuH<^}eL!cj|ShwBYp-CjP^TkZ*Q+3Udicj}cSF%&p>L z8>7+PnC0^&d)ad=WH5tWvKp&{5$Xcbivj0^TL3Bt&^oNzqD}3M$ls*oQ=?_ZLutAZ z-|+`OIP{DO0QQY;RQN>)a8x@f1Wi8Xs4z0_aAt#DJo(IR{$U}x$2Wfcarv$oe(_@H zh(m_j~pU5?(sI;Y>I-TiZ95j48K0 zw0n>Or1FMXWrx*Hn0|dTZZ4thVeyBJiOzvcc?2-i>7A%n(xbU2!T$FNWi~%@`c9nO zxHslAuIFN0aw3p6t{GP{OI=NciigZ9c^=Bhx7okm1p~6aRh7eHi>A+b`nq582iL(P z`fJ~qwROFX${q1H@ev`9(gKxUa~{u}_!QOf{D`Ck?cyk|@5ERH83!x=< z&h+O7dYVfkyL-E6JGPL(bx#FRB+gJH2*1HRu9p*&7s`7K?i=4Kj*#6AGy*^V<=bKH zdi$cD=49mnS{rokVZlU1kBkZ`QNbbcUKL)pYhg}aT-?Sh`%H1gy4LpX7g)Z{^Nc*k zugJg&`x}Y8X@~Z7x}^0A+2E$9A4{ZJGUH6*f3mm-`2|>UC(xEO|6(_FWR)8d7{jMm zB|k9#pzCT+)a3agjO@9Aa{{LVw_Ov^V55BuXvq`vEBnlws~_rM>Fud(l&Qt(VYc{P z&jt(YYJCridP_R~PHqSg_Ys|6t*Ee_?u*T&s8*W)7=B|xY?Gi!zcYs49+AUpf8v80!74@ zkIHSo_ubgT#<4H;nv%Xk^=&}P2XmcEJ-xpC*8BoP`$3P+FwEp%A8qFbthx?qSKGT% zmim9yNwZDXC$)8sQ1rj`*lScLCvMFsXb8GEzVJ5FMeX@6?FeZ>=-5DIa2^P#xj^(;*ONe1lXaOZbE;B{?wP??JqKqtid)(kxe3=VdZ&$V<; zMn|s((J+k@-XC$@+i8-0XkkE10h5D0^`XmUirl~$XQXEN)<{SIy5p*EJHF#zfCNz1 z24*o`%^S1Qu66H3!tUkcy8|?ebJ=P}Jrwod%HLvdS8u!(5m!(kyF4Lt@nf&O)4UJwnL^bTle z|7n5~)HBawuqS!awtgsjH+cH=wNV>JTA z;UrryO85 zi@u0)s#4J>(%I@X4LB*+Ne)6iiv9+&3YJDc;ym=F&nNO;L?MX+nq6|r@=}V46GMF} zf$QS~a`L+--oJaP5>`Raa~HNoh54!w2|e{w7V#Fv8dODR&SU}S)Wnst)M)I-@Z;N} z6KAeaUSGmBLEo0q)1F=9*TJawOntOs@wz^SeLfo!GC(j<64;&Y2Ym4}_8hQGGO7|D zL0Xv?I@+Ale??r^`qCwMz&ov;PEFB*RNfys3BpNZQ%{Y>%XMY8TP_~d zyp;b>?46P=ce+@S;UoD-M@dpjF}kwYT+cn|#^8YY?d4q~9oAuxWEpRuj79YNa%RUy zs;Quwjd^ue*7z7#V>bI5?2|{Oxpcn&Lqbxr*S7x4itk{;g>_*?%&^(s)x*p3;!7`w zVQmg-7Lv~anH`|D`LO02{*%YO#trP5C7=w%)NzHF{Z0J!S6TR^pw>5s5aM6Lxl3fd zfvan`F-6=6lx&yzwe6I$l{Fh78i_dmxNA>^d!2S~Z|_y005iK(?kARpUzp{2Tk}Ue zbXD+u?XTz8f<`Cj`lE7mmb4|>>ZfbDU?{Mf&lZ744WyV8bo~u$FQU=s7 z79M$`^pgiF>0mREOwCV(WJatli8+!y9CXcY$|p7GjnI5dD)=P42|q$&xeKo@ICEs5 zI17c%O-#0-osv-9M-KpvT2w5Qezp^DS`k>T-PPUQJ#Q5(9c5H3r_w&>I?ML9qg)+~ zNdLs{GD5WL}$s+yrj&#jSU?+2X03tMhrTcr%L3lUB9RGSn-%g=Djbua?2uxsmsdc zmcJX}en_ylLvIc<-gzCiK(Yxf;VPiR_;Fz@4~f#hdr|F5Fwid8v`96?ci~+Xt^GlS@D(&4s^p`3fzi}-a)GW z`W{0Izt@9&waIDB74MY?7n@2Gb=J%~YLl`3%jP{FF;m$v;``gU&82`w2ANQgcPj_E}$4 zt^HCsf3@gnCv8wk$LOfhn4B@7fT-E91e+vrd*^2>&uuTB^Y5(qun>q3efB7zU*cpllI(Rtm7-0cten(8k(*qWX}{h~Qe75hm)qnlP;EElo_46ku0TewsVj+|I< zG8&U`bOd>E#FHK+;?(!67A7+ic+AkBLwDjCp;zx5&AL@X2D_%WgG7h)s*`Z#D>Hcq z>Hz5AR4VpuCsh8|7-L^m73>yr5gzKvzPQzGWsIFc+v1%P%>ik`YX~G^VdYJC zW;1sdOPWyiK69HyHZwUtO>hL_jOZ1$H9(qxN3)~}A8F~nlXtkVeKRpKvyVsuD`|KM`X>lAT30a9UGP86=;$N$`~N` z+1g?robV)Au&ZyI*W>X`i;K?lC*{^Ltk97cT7MASRyQw^gb%lzYzNv%UbFbE{%3G5 z`jB=#Z{h5~*yEZ*2e?RX`FZPGTWD8ZQFgRx(?|?##&fW>q zY^3y)SXETxE3Ia7mLCPaU$p7ec{j3n^_{3~G@_t?O|NI5B&w>JH=mqi>loQEyn}21 z)ij(OE@NS>F@UHZ?odloxikhd4_Jcb!2R@QYBi*#3)6G!duYUV(4-FckNP3;ZxP{n z3e!1oehB%&2smR&Zo=%ej)8w5Qd^=BoHLVHY`KWOzD*YH67K+e7zjT01L~K~7HJ8H zt5&4u;l`W^bzTgsHffGh=Tyw+VEc62&KSd+yfNVVpjKcL8C^^^C`-uA)s}m;B@&E)7cDd|5$CGWHavGWKH7LQRg7AR)tNG_QGM zFoAK(ZsB{b^N%K(efnZ5z#OZw4gN9b8DiE3ESWOBaZj1lN(iSz(%P0sc1s9;f9W^) z*$hYyOAHE%W&Z^P(r;WZ+OwMI}T;PY}+X;8?Q)!{@-S^Mp-(0cQL0G^`au z=ytV;9~jAkO(Y2z0MFG~2V`t&A60afDhTUadMdC&KJj~*lzJ>()kJRL=ME@1bYeiY z1!z7v#gzVgmSLk&nmijoaYPSV=txp07aK0lz`6rd@9}J0m-aSDZfEtPZWIsrq+kP3 z;aWY8KV%$N*)KfL2%67MZY;zG$u3t{NQ#er8*lk~ro`aaiQfcPUOi*@{M-!-X?~#t zNy1C+A4Sr^jUsSxyEXSAin5AoflDWCWdS{!BL?GPpn(1c$mlF)(SKTs8H&7mZ1?i7 zz918RU2@%K{0zxnd8t}*h9&%lS9Jc?w~bW(-GCkh^l|sP1%rVZS5ap=TTQA4T&9C_ zF5(8tWFW%eab6X4R?+-u6@9ILdbyzTcsoN zzN^&>aiLCz-hiij4bB~toJ{fP-B!YD8=Y_MhKEd&g}JiiOMPXR?9M*EUa6A>2!#Rvh(`5GJ7yPtXIaivumyE-G@ zK!F}rK{rmX_6_c2t&BC!w|1V9w)QuZsgBzi!}h+NFO_)AplMR&xBF1-vh@5?Y;eYE zE=gKRX-xR*Ov~k1`DgCgzq>w@%WEnUe=F+JpU-L-U8l}3^;UNqXB7PQrH(L34hOC{ z)JIaBA$|3+y`YLZ3Zbp$!b@X*D?j{GmI2AY z8gsnF_0s^UE7pJLp;0=LJeziE8ynQzd>JQV*p}oWmSITi8FQLmXEm)}bwmgAflST* ziBA0wm&5u(>E;*NV*eiBHiuPk`RJL?YXQ+_Nlk)ghLN}xpVTZUZ!v*5iLl$ylJxI5 zi`{5DcOoK-K54uoI*Tz5J#z%P4CvZtlSAf{i-tW1Gx|QRm2&gln^-BedGQkIJrTYJ zQGQ&Se&c7)&&?IyLSN#D0ZkFYM$66PUr9!6^v92%@984XoQ1fAT9g;0OSo(uqWLt8 z;KBqpnx=s6TQO5^4ja#=rl;phN$@Dr%uFD1BSQcS{P`frZiX*^TU8TE6ngd8h@)9w zOiN0@0Inh_>5N z+r;(v>ie8WC4$GZ!^qM?fmRNxwJg@4YR@4F8G>r-oR%1%xf}}X1BF`-& zNG{6=p+?I{NJGEta?uAXqceo*Bw4Nq&E1SmpuBxNMEn{F@I_ky4Pn&79>& z&dxPRm^}CRX>~V8SA*k){P&^ChEBSTeCzn^<<&ewLS7#>Oq|bU1eTi8aSfrsYH937 zI(X-lF*$ZUl>#kUYfE0sC2V9pQX(aNuv#BHo!TGTqt^1~+#+g^aOFrMK6|rgLw-MY zIC%BTR~e`;d4i)kbCfh~1u5{>))wT$uD%?YndWC0Q{U9PeBvp!~lTb-lMa=y1TnL^|B3Pu!xO8T2XpOOeY!ft2yf zp_O+P9V3qljOv=44zI5Gi_MiiuOJH9GTl4br7hZVG_DgKjQegiw#++7Fmpr%_yOVBi&%+Y)H`53G5|V0 z&pR})9LI=`;BhcDBuS$BOSVfXv2kE$ZI6DaOgE`0<#X4M2KP!)wH(?8k~bPAa(MlRU_TTa?mI9SrdX; zGwI9GYdL|LLV>J*%A@O@G!7Lrjgg$!p{S|bq55;EY6S@)Yxlb`g>Iz8D`z|AJnUE&0SA3e@wrsN<=DnKb$W_PR~Oq_#~h5~>pG zQ(@3$?HwXtFXd_*b$sJR)5Wrn50Yz`FK;ey3|Vd_S{ht4A|3iEZf3RHc{VoFIO7gI z9cj=OyvSE&;meHqCGXj(vy}R1jbEO}DqJ#km471Q2)L%Uy25U%1 zpdjPh3#b%$pbkQdhRmPWmo(2Sy6})wjCv>Riujv`ii{5}XQ^ga13NqeG9Bu)N12B| z@`N)FD=r~dlDo0U>5^#(NicoV-jO8{VnC8Ns-a9qHlW!Evoi+s?+?yuE>X4g$symfxt>+qtF z!#HD03*BvVE*Yfz;pZ8OJ#0>A z{HBgrZWxqmE*M`mkg1l*KM^@@ULK-||S16liRR&4f{u5q62BJsQw2L4E+g!(b z78|O}tSf38w_)ku-=rD?agIr;Vbq`cjmf~(R87pFBEhTg@C8!iPTTstT_V4O4??Hh zZjcdJDgt_PAp2{Uc<+J^{%KXwAEI2%*=+SbA>yCDjwTQjH?xCH(1Lm{Ti9hAqE|hf zA-4zzEciH-j#T$n2D_QR3=4pwMv(>xe+%lu2s4m#hQZL;@a;r`CW5C(mUN{-L023W z3A9+wL-JEseiHBls6*}oFg&0Vl4(Lw#q?=PY8kUxp{jlT-__%{iN=@f@2dkDnw{dPypH z^S@3|f|rO7Qn=>7#ryCamER}3D0mUm`3@;nQp6s%dds)`?H`NPC(gWCi9%s%1WeeP z5hW*){$#j#5fm0ir(98iP69$X(A`&oo37{ni~IP8BlG3np@tGBccZbG&(e4;xvQ|S z5c$mhPH&>T>JXIr1agIYCDZUh%3S3;-h8Qte7%~j_OI8>DE=ukcP4&CZ44D!e*tx8 zO<~_?&peqw;%IB#)gkjBN?2ja^jU)pQ~2YDESO*Rd;M7B`_<-y-FXvUoTX(%?y-b; z``4Jl+hE;eE22(k>sn}fgZK7&-rE|VN`u1W6jJuTH}YdxH25vY0)6tRI{t9-a;RTq&-(hhpyp*B@JT80H5d0&OJ&@*!J~Zmx@v_=+UXXlN&-qtaKP+i*@UwA zt>ewc)~R!CdPa=qG;W-}Jg6HvqDaInmLwH|sCrAqwXV24x_t0;9XJ=0CW4y9Zfc;* z;uUt=F08<+$yekg)13j3cAG9d)|bMGB?O74x0QTh*EsJd!H?d&@wPY^>bU$zT{%^n zu|R1>_VAHWTjk6O1uNz`wpS20MX_^aF!pD!@sFmLH#ck1f-cU^LEy46 z81DJaFe&bQ#Dr7b(%w_g&sT|cRnTwD$nTq}{H2DW<85)R+0k;Ka+%=!FznFgi@Uwi z+C4~om{zVrJfVFHw%#!Lk%1}BGuIjz?cC(ZqvuwqMm5s6L{XC{phbpn#9uNaBIf7 z({74|*>&Io_7( z2$!lTy_f0W{O1D=XcqmE5#sx7F>=u!o znjsZ|o|FR~da~h;hy7C6%&$uh6ewj~I-j$@^jN5r z^)L7K4^>#bx=Zy(j@oh#%bjQ(fkbt84Q>qhN+SxRq1{Kw#of_$0!oo}lXXq91PJFh z3`vykza*WK?0`FwM@KOPsmnpkiScn7ZJjsjdG-Hj_Wx znlR0GYTJSlg=(R*As+V>os!qe5On+}A_xLZ23UxeGb2ayrf&979lYMusv#&TNlgH=(&d^CVQ8A5iX^%HinIX$F zpFg`!Qxc1Hjq`G{&rq@$DxdG)61ANv;I$a-@N;1*X;PVwgKO7EPk@0Ugf$GNH(iNB zBI8la>>x%d0zpTu$f4UKTi+>f@c-O~g|MB{b-x&U`W_e5EF|fKfU>cGl8>|d%52A6 z{AInQ%erad1RDiT0)fya*|_nTXMP}8&xsd*>8sVLvp|FI{Cm>@o51iYNiD(1*G207 z3Q0;zN|nefkwX2SAoxmM^L9I5Utb=|P_L8VTwTmiB8H$}J+4;RUu||L#Oq{mYjBlJ zk&sf+3pF4_79-$l#4Tds_2PKNlFwvhCei3{K6+=S9M+AJ>D(eWx~3&d`IeI)QVecdxg|Uso<77dDr#R> z@W~o6k`J*g&hYiN#ax2&m#4)NrN5ySY=Mtw^E-%gvM;H{>t2(872tMNU zeoQMRy*@kX4zIUi<~dkO_G*pj#$bywUAxOi?GmcxMpUVtv;w8c-`36g13-nvS5PSM zNElgJZjs(g=`6R!1MztrdgTu#V9NJJcLW!O2X2t7JG8nwKOh@Dy`nrq2MQg0<$<LOcfz$aRjDc1Cu%EB3ChY_+zyMRq#znz1bmAMt#Z1ETom%ztP5%OY4 z@B=0x1cM>;7mr6-pzU!N+~eS7WowJ#7f}%tf`Lm3>_M4Y*}FJkEcp=%;Iq2D3)&X^ z2Ajdpy*l8>LGT|OW&{^A65j&;ly`KrMeCtWG_1hgsE8rNg%C)vSwKTgch7Eq5k>H~ zt(6TL{8B}m+BiU`C|Wu@*nur7aJZ-t4EjIVsDm;`Ia@8e1oUKR7nH@~Q+e$*(MCEL z8L5bA>&xq!S<4>~G+%rgH?%Xx%E2D@@Ngl7koe*b7f(m@;#M=Xo0TbOP=p_$%ny?X z7l!^J6meY%KG>tc4J~xB7U&&8_~I3;a9s*BH&+nVgY9?Rui~*w#nVaN4Sitc)$rG} z^H6n0Ia=;;szLZMU=C%gZtNqnLF6x9uIenBY5(!t`2R` zF-6&ayH(H1%mp9>f~2Sj?kS+7)zDTJmbjLY;I~uDH%!98ZjkC%(6x9bE0r7UncSs)D}xURuL8iD)h{skUz7;c;8GH4+1kVfGkX|Z%^=%#;U+`uuoVgK#h zhs@{-bgVigaLL6E`_+d8j{Myrk@z)6MD%YmBH}QBX$aQ1Ng^V#_;J}Jk-$CbS91hE zkbj{$f^)3D`W!*vyY~BL>lc|La2%F?^$`(8;vVGtb3_F43(z$BYLfg<9f>6pV~bW( z+AHRau-IpcJfL(4p@k0}zZwywEeK*1%pE|~Edu-E7LrS=wxGf`Rse%lx!WAbMW9)?%w*i{O9T z@?xK098utrR_T+4fJYGQh9VxQR~(%eqneeS0&b081mPjM*kcPF4Pt}E>n?U1IAUS* zPibqh1D1Mu@yg#exZ<$Y2E!bUa&dKrhE8ScQvWVpc(pVBJ?f`p`@fkd7?7M=*;_#4 zC-hesnxBaBl{4z6Or4b%{btrcnE%cM{(<@QR~Ul-aMn7bZP6$U#E3wa0N(|R{sM2q zAlLWBb%=lz4sr>I#ajFl-Egk_2N*ID~_yB}@#71i?FDJFQ-n>DMsEiI$dQ9=8c)Yh?k6`%Hlx3k~#53Xp!u3aHZLaXaj+%*-Is)T&(g z5Av};Q4@uL;TSxei4&B>eO|`cF6pM0Q?_{V6duI?drcHzbiN^VRzL#}0%rgSb09wh zY;n_4wRmB($pWAjYG*KafF^TWz^H#IeEij6f&W3G`x_&#KGAN?JQ`zD4&F+25u;40YSm#+qWzX zG7KuZ3E~VAbf7KT94f+rhHy%bl}&zE^0EBli~5G|HTvb!Fx)MIO3s&!2y=5uNd$b+o&fg;nFS@l&paY0g{XbCB@U7o)Q$hM zj#aQlnc6INn4*K7ot2BAE!u5CXl-S0>WsF7G`k`&2OtfHp}>Fm2m0eT|DO)^s$+ye zNJ^T6ds;b03XuHww?=3W8dR~sb3l@O@C%FwUUaZvN52dcPE4{;L56ny@dy5KME)hG z0Ssnp3RRg`cCo568V!l2RxPS8%z~w^TS5yA-`SAzX|bahTpNTa4DebY+5l5zQN9EI zg7)D=SzqKk00*`}gb#TM93H>uePAw@CDeVp10 zf8#$q?fz5beu>ubeP{yan#Do{wcI*d*;~0-p@8!IE4#P4agqf8TXj^RwFloB6x`2XBUE%E1!Z?GGTpCaO0OMy9C`aRmaG}3}--gzd7(vTV@H-Yl;YB#$PhSdjmf*FT z?#yI0fAzz|`4^v;us<>!tAj+`90nHHfPP-#M73O`R=t!vZbc5X zQxr!afsob(q}dC?TPQ#K=1d1?M@y7F?vfCX3Qqp6$64HC1=cY^>kXlH@Y3eRJ%B;5 z$AGla4&M%L2-9b){u`@}F|a#pr3prGQ(v!mR4ne>)a|?s=6i`vb1| zM|*dfxBEJjSlzAs1>~PgCLPar;jQ^Hv%kcaE;sv7U=2OhUx)7!1GfX+(Vtd)`o8uK z%HdU@;uElx&YlMW-wE+b3m*O_TVk ziEr}PwK4yyHzAYqd;fkwf3y^C;W6>^UEPvv!@Ih_jfNO+)|a`uMRT^y%l$EHxV)$h zmRbC(K>D(72wxk=p$IOHizxm);EJtK&Mhq~$2a*a*w0lL4&me7KMlCw&tAZ?p?}uO zA;e0lGCt|Wqv+>b+;5u1uerlF`6~c-^#t^%E9O^N+<&EWOBVNc&EL-l?%yI*SQWU) zKb~$1PQ&^576&W&iVIGwUBsohYvXMl_b3R`xAhR_o( zIL?mXaE8G1(94)4JX!wNW|EMrF-iZHO#!g~Et~$@Wz+9g{eQHu_dWf|_mxK9)JvCH z&aZ2OKgn{Vg)G2(j9_2x6lcm|f`Ut$nMDy4D3Re_x(kZ`kVI-xaS3ELi>G{1AbxQG z%kKVbyZ@8!Ue6NJ`2mTSqpgGIqO=?ZJ}(Mem!1i#@w-Fia(4$;NP-3fqER5d1Alxu zc=3rArR$3>9_;=~LiFV+mo$TmPXV+*t3BMm^<$_9SG>Un_wE>^_}4`3 z=*u;}e*fejzT|IMX?!xWWX`|#w5#VRe*qQFl7+2*M~hn35Mq-Ie?13n!BdKl=v>Cm1pf*R-p)PKLJr&;6~enU@#_X2;jS~mhOT)-i0 zrThK){0jn4@!(p-LmCg&UzUCm|LKJH7lb2W5;$B#7zcqWh^2lD=g^s2Ko$w!><_K3 z{c-HCUV~Z;-Tr3K7hSQWcV(^n=R;p?#bm=Xk-t3j@l*OM=5d8r{bSYjFVL67TXYEd zf)Mn<*WdhxiC+!+U*wlU(0YciB$$#w-iO=p#b-cr%_XO?aQ081O}HHN`wC7x?e;gD zc4COHSJLAbW#A{lpD^w4W!%4;$C1G4(th5wTTx;)|F=?we;MxY);oVbZhyBp_8*5z zP|O7}H{hkmV8zK7vA!ep0$|Ldw+HFe553Iy|MAVbtCnl=>g=y3!B1izzgo)zbqId# z%fceV-_LTtNl91u#D7jTY~^~Ar7w_Lp2_0v^zuv=A2Q+H!~dQS#DBlrzkvHIzpw{< zW#OV7!#RC8{<~!&}+nFZr5hq^cDh z<0)ceuWzehF0#)7ZsMi9>i2xDFlm2`$oMW;|7L0Z??U3|=SSZ(iKn6PvEqN6AN@b( zG^?TzAPxfER}toag~Bfc7@q5b%3ZnTDzC0cf>wER3PPD5 z2E8@>xBjhI$+}Fqf#o)M)z#?Su25~p=Rb`OuV8xrxmaEl%;T?u^6iM>3&YMRN6S49X5cG|mLIdQ*USoK;fwtQ%@hWy2To%xC+cusXr-3{&aLi3UXv*guFb9AH;%+4K{d*Jx{U@Te(Z2 zcmq%RLqWW_G_*1Q^2>wC>TtStRA|2&i<^=xOz^z+skzqt6$pRuiSIDbcepr^ZPvC+5c3LR&4V*pW7clA8~I-7kwDl zz*NI4H(p&sD?8Po)1NnRHpe&j!}ycUM~#HPJZ0iB|1d-JRH!u{u{8;yn(9F9nVJKK z?a;_hAI!u=oooszmq)SBr`Z9L^gEqL=h4raFm=++lcVh~cYd1bz2rI3ue@cV>9B(s zDW^+Zi)BW1_4>oM+DQWu+p;VLgw^NXRdUy)M+#ZHb^5v^tQ#^@Z>Dzz^fp}4sgWE= zHC=Dy~eG--iHDFi;3|s#E-n-01>mvR6 zypoQ%of>M%xqM?FTD-$@U8aoh+`;k2LT~qpN1M+jA8~7W_?E+(@e6Mz=O4P^SES&Cm$>H<1$_mv{Ac zY**kV)5@6so=9ONrQn^X9CjfG1#_xJT$RS2X$XtO%FJc9SY19-t-kq;Zql^WSb=Gi z0cKCm(4~~q%!VE%pL{0=>qGKK@?U2icomfS@ogFH`_K0}kKTWH7yaa9|4WAlcW2(- zd#))}QzSlCFmamG?L|qdXa6bl);m`HFHB>_60+aqzC2wLM4Gbhz`>G}p8+mTCF&Wr za2%cK&K$3V2sAM`(6s9kPL1p^{sGua~m69@HFo%05+yc@4wza7E9Esjr( z|Y1rH=mk3INoe^TFiOC;%R&v4$y_b*>^hcz_n8QH0GoXbEO zdcI0r&zv+ED*gUNS-dz*L77ALXu%EU;jO`MYQ#J5lwbGz{ORP3yo4w12dlC(?j2S~ zq?(QVd?Q`&a7zfQJrK(4izi`j-z)pEfkADq>HoZOV>V4!#WvKH#(G2i;LRaxO-A^yoyh-Tb{L-idBjBo-&iT+MdoL z-?|u`_*-CY?`j0vTD4Vctf0`$N7n%1^ElmXQqie!ZK|p z+Awu?odF#3mu8q5@}KS6R#T7at%%Nf%=S1%gYLR2muLA^U+v~S0}PKbbfQeP-lKVy z@yJ^Bz}Eq!T$bS+7m&mG>b`o1?Zh-Bc%Q`ObGo$R>pssLUp0_Kk1K`dfoH2q)C;&St8Q&E~ zPE0mMuJ@ofRSsd-^N_0Ktg~`+JkA=zg)X)4h~5QOcQ}?&pJeI@X}xJAD_kF$@1^jVr!Eebr5JG zB?{EPG!CNP{ru7%!FTL1WB*e!zWKbvn>SW$2^cLj0I<=1ydh0rK9@&q<1le}B%^dE zt8}wU6^%uY8aAWn_FTOx_o0WB=>x4JVO+$t$_#B1o$ihM^=g`gvC8Rkfzj7CTd-M4 z)r(u@?5$Tkq(r_^GU>^2KGoB%%}1KA=hW^nRE`xmzf(h2{sQ?ZkxZ(1a6{Upyfg3V z1Pz&(LEwPgPu`JYZdIg_EbqDUB?vH!1WqN_gN&4{L%R;s=4++LvSv+;rjw(uu98{LtG#Pa^ zc2M4>O;WK;Di08l=3r*=M-D|}PsU?g()lyxLJ4<4B zC>W5(BT%Kp^Y{6@8k+OM$M3fx*{c)u6pt;09_LG;XyX=*wrjB54W78yT!ogzk0t8o zffL_;$SLa>9oq&ahU{@*E$&)OI3C(aKwhG%RYdkIa2x7_y;K__yf1t!vu`X9KQ^@D zhx;L z!O7(DI6cS6E{krw;wU1{W+%FcT6C=8O$FjckC`kq7 z_FMkZF%b&tJ&3skL~vgyrNGtAX0#?ly2@u=gEBG)3?n!vf*c0wE%fU~_yoaG4;neO@$Ecj}T9C&Fo5pa9#932RGeMWZ zdTY}2c>}FTl0XrLrC4kniVO)iK(|9jR6_P)s@dp(_Oa?bwX}lWN_%y8*Y3}kqR=)E zKYw)@++qRT-X~vEf*wO|Ki^w$5_{mw^ZoRkcR+xGoS`7UrzsRL5F_8FoA@Q97zd_W zkE?C})urHVp%*|Hd)^Ghf{9f6=?*H3?OQ2Z=7Frj{K7f#Uzy3t)wf6-RwTHc<_eBQF9S3%28$;Y< zm8EX9WC0M}uPGY|ei&tLN(=?qdo>kq{bg3@!T?eepG!hNn6Ik8;st2;^i5|YUjpvB zC^@qF`Mwi-tAW=t{`7IoFX=jeL+?XoBheIxBF{&Ud3w(soqP0Q`oU+h&$D%YyYw|r zS1V6GJAcWYjRIVp`r_qA&81mzUVto^u25?>lq9r}Si51e4E-^QYV)+z(f*628J)oN)b z$-Se;e*QFH!xy{LH<4*)hXcF0+w!v09{}-oJE^?G5XAm1JZuR5W9P zd2_e3+A zlvB!06pDN$d&2mtL5Oa*!+q4YR(jgt_mRa}blC#1_6SrOd646w0r18E$w)=>x@k$s@Th?agQ2cK2U6p(&D~ z5-oD=M(*i{Rv?KHt&^F*eq&65Qqb%)($3ng%}I3v3}@@ygr{iu;5t8_ZI!L^AZ~Y? z+b8%X-4&4|*x>e5p7d0Tef}eclOWQpYdbpsrXS=2@FV#y*=A(71Jj#t92VF3Fq;2b zXaXb^hvL^f+VT2&PBj=kD^1ytE*dn=2TiGSpiD!NR=Q#LY0*b*z^67HVNiZ+^m(qC zWA(qv^J`_~n^TS7zc8hp7=I$n-XPJM1Mc)?Zr*zizYp(7j?v$)?DS|# zGOtawViUKwm6;zwMAo5`j+noss1KfLcklGgr5YxH+c#&O;rI9ZIF-bos3CYaA#MAx z;(g^w5tg@G)2-=&H*d|-dAR7^0eKPN%tKJ`{kDYkhI7aUckuggsS2B@W!(N&9zD8K zP(CHI2F?qxfa(W{L3RXZ`5;I?Z_VDZZ*OHtc5OOT$>Grza8k}5#O6p^qfc~YHd%QU zsXpV6`V(|Cv&$)-Ron;TmMUli@>h5z2PSG3_^KKxpx>|9kaz87QEU80U92+mkp>2Z zX0A5TURQsfeSX9DyF=LZ8)HO4@;cFKbMsIsc{aaMEr0s%Pk>U8yl)Ps0z&rlhn$Z- z!wpvsu<|>Qy#>Q!2FMxn30IG_o&a_;hc>KJZu^PNdvonn>2-m_Ee2lmtV+l-=f?mZ z9y2hel{PmyWZDQ%(!XnsZj?A%a)wcSk6MaGT(*W#UU@wG(a;gWg14pprIf;=Hy?b; zXN8*tyPgQnlrQy}?F2EQc}@*7Ct^KChf^h|#r^`ZW`mq8jxd(t4JEof);nWwheq`8 zJF#ic^%RTAou~pDZ1T9wWA@Rrnl}{deL%=wQ^D?F8_sHfJ>l+5Pb4XQVYX@I=`vc` zw)|TPa@u^nPIQO$NQ5%t^uxHwpG6G21IwY$@UcN>FaMyV^j2cF^^j${_MlP!i)E4{ zPFETOoqJnbnAZ&}=NvPVimA=+qaH7x6;WfC6+pdtc~87f_H%)>H_4TNs&10-ZT!2| z4|hU2$;3;Wn}yYgx}Ci>+#=-`bmhWDGo@#*uuC|e-`~vRBlYIa327-c$qS!>`7|$C z%Pb0J)fHFCW2y2ydInC)*M=q2D?N)nIJH`Myo3uU;}3!Kvxaf+PE`9=USDirp!~k{ z&~ei6!(KxdZ@k_*+*TgWcq9EDNCHxZo?m|HSF*mj9%?D4CExGnCrL$UEa4?9DXHy+JiJbcwS&& z@O`JBU(V~S`}(E9FE@qDiPW|qciyx+*;uQ|z?;X|AcO8kncGV{J$Ds{!KZ1tBfwDB zIBLcf3u2FL;`O4tqrCo5`Bi7{vBG=Z2IrsHytsurNta>Y^NC#Y7;&Ij`E;BjO*SFg z;2CQn@fy8Yqy%_6HiM*VC0`r>FWF3%-VA_y4Itnw*NGU-0S;^rFo)F)8r!v};X)_q zwx(++FgO{d0%C4|r(<>>#~F>OSKPuUcJyzM_jzAJ%Kd^z7{u7q9F4EGr{1I)l~>~` z(bbynKW!uA;O(TR%o?@1_GP!TI@cX`y}f}i9J69O)#-+^j@;MZ&f`vZn5b%|l`mbd zO0DVs-5B6*Z%p56-Mkb6GOY`U^PY^*H(qBR@>1ZqTyHoc7;Dq7ArONNWq`W?ZIA%h`^U?z zl#urqQI;dIzvQT=ixQdnG(=Mq6v1}->TYuSrv<{iSXMK^^d!QntqM?UTHDB~if<&I z-Q7XM>hp@vOX*@CjZ~Jj0D8l-P1^EFfMh{n`geQZ4G`YC*|qBf2fcX4ars`?jE*+J zgIC0h0gr_hMDIW5y`O`i4gyuFeszf<^!C{{$Z{rxuwlKAQO`F)zT@IGgfRi4Od z(0g2%zA@4HU~k^Uac`Dzo@<`xE=_M8;G{2nJVe>3v~WZ3pt#3}Iq`a+$joEa$qw%^ z>6|A*_g~x}-gQbp*Vbxmy0>G;T#9qJzh_qfY16vbqto8+9x~TJo(tJx#)x^9s8_2( z#v6XKU_3$+Frzh)nc4x8%E#81Yv+Nlx;M@3?5o&Xe#XDIGWK3@Zt_sFX-syrtE1of z`|)c=yr)O)#tuM1k=>XLu{TlETh``%Q0(B^n7qUFYT?tfHll+Xqx;%yb85`5L4=(h zU+O*@rFc=hR?&&#HMB408N|jSTduVX@TVt9_ixo+c&@u-OeY3?LGafUS7NMwI{k5w zw>vP|=AoQ!YNrzmg{!Zy6eZ;i<~#LPgxq>dE%~Tx{_?c;VSK2g&&Tde+#SA&jJVDg z+Z}RXPl?>XK1ZXTeV7FHhKua>*b>NXzTe<1v~^${(;v>~71hiaBT;I6-hH&KB^3}n zO)L)p2U)#N&j95&;9JESG7oW|pO0}kl1mP2?(}2YIXe3ixYa%P-QJ8K2F|#j{m7nl z0#nKD-f{e_XFn^%jkfx!zrJzr?2QTJOIw|0(Z@k9j*|2INd^qNCp-K;`(oN%n@>Sx zYdoXTj)7E+?HQ~D=l*Qv$n}73gy+i8X*6X*^sgaHT_?9^AH9YF6z9QR%?3eOmP@gI zBkkHq%HI3#WA^KE*3d{4Prh!hi{g@QjhAR55OR6|`1IYEHO~xRZM>!@tP!X6Vl;1n z%YoaU_f6V^!7>omwlN4KWeWQ$`C_G<-gcF|k0}kJm3d*P_--&G)+@V9nn^GHMEqvo z#~*|HUNO9?*8{<9MqxTp`ZVBBYe=?zT(czqS;ujdOU<*00JgIe#4@QN&yEEP4z1g!yCUV?y{>{BQH%YNk6ib)-31Q)+O2FXX;0>iO1i=-F z#h&(Jir)MK@l-{AUJN}1$Fac1R-493n^%&B6kssr)G_Y@wWFW#UkLW&RW2eXY=bCv zh?jgi{k5*__v{i8y*deP}u4FZpD>ek_DftjpVJ$##e4@C0u-(lRe8)iG23g)w`Sy+Cz zQ0qkvW{tM9zV8o7k)C>REi3=(P<=+|DN(EVyop*V!7DP|!Hl-;yb=PK$stfcu*-LS zeW3X=oq&M=ueWw%6h+vLRXvgpQU(n;Rn1TPNHzT+pO>S=}QW1jDoZKq-tDQD2B zpt5GO^LM;W-lapydjYGLf1hHAwu;THmVb`wE{#dGMVv=dn+FkPt5CY$wrf+eZ-6Z< zl-VD-;5hjeyCQ{)Zb_Ao#GBfh@Z?%IK4#m)V#(qSySW4h7kH^P~4`&U%kpMQcYHP>ltwA#L5z^O#BHHRRH% zW!;fs14@&hhUhC8O*!J_6tY1u?moi8mqv`bB^AZm`$3RckE>Gp|B*Be1E}@uU@kDl)?v!hTgm!M6Y{-VXwy zJ1N3+5)5N;H+5blTY&h_tG$B8PIbR&LAj1lx@roK!JT7HwDr95wovpbAyt`t@rZ5m zt=v0S&nslgEUNjN2z6C&5$UPjctX1Fjz!(srn^iAya%vWS%7XlFr*Y<8q-s&#;wq& zWynb$=#m|v+;M$vSM=jY`s+J)n*@dD(XdWT5x(Xtr{>V68HyFCSJW=QmS)qO;G5uXH>w1)hNKUSO6G)uCD{be)#4WAzpG|l&l+qNmnCT1s`nQym zKa6@e#?V`K<{}#)j7zAGXUh{gR4GFC2`c{`&Nv6}R^tQVk{cOYa4hxOBwz2KDWYS~ z`R@@br(_C~2U5`VQJ%eXd=BAvN=LKagmGM}hqe8HsD2S|=GHFAUh`|LOS32UhOR#*HF3ep2p1oarh0m}` z!r-i14P4Vls$0{u%YZ2av9TZch+7w)DaS-^<4Q908sgYWppx)}@*%ZY5JrXN9g7-E zZk$@e8Y;_k@qtdt#cM2V6$WA3o!${qR>4A2Vh1HJ65cJptYZ9OmZ6Wj;DDhg+QyiX zm6pn9s_W3)b*tx>)^AH-QX{mtHYRGRxwspZI==J5+H|5ke_a9AHQ^P;1ElN7lux~* zI<8=sF06Gm)mvnkV=MJW>K-|6CB~HXF@x{8>_f0-BA;3${L3Yp_w=t-B4#M<9P&HL z5}Dan5ajiQBs?Ws2(JZLYf8rOaNt7`pblPmRZOV9NdYB=GnECg8!A$j_XllED|#ns zr&yxz{pRkQWR>tsf_G9LRK7gf;L5nWn5HrAHm^(6n;ER>XxAY*X_n47g<(RJ{Gp(o zw6T>DXeF!9a7f-OU}DdAY%0J3$7r&Jc0uOX%4@t+OjItX8{C9Tc%GS|+gF5q@Y{!!!hK;zqnn6r+@mDguu zu|;O40UOix?q53{X87j)4gF0}04}hD2&>&K6p|(d!noI`!|Opkrko@_G(X_@F%8~| z;Jxi(4ASS|$GTZM$tzi$AFol_NWw|NPBL)&iIB~jEi+8CZACp>^T$0yX!4+178%9 zN^-dWn(E}C1Rb{t?E#MZpsH6ommGtRiJI;<5l}=XM73)f?>-+d=gdaMp$i}(klltA5^nfY!xcA6_Ha(R*V_!z8cl7sqpC7^^9Em?1$@{ z?2@x1TgxOi$qo~4G3zDVP<2Udr{7%iPFB8xC!1)7nIB*-(WZ~Js@&H;&TC4?(d<^G zP+(WBO%|zhZJ1pO8`pCnYCL-Dsn@#*E}O$U+gjwvID~q-NZy6W1<0~%+ZJf)8JsPt zR;EFB+(&p_w-9(MU`FTAO8qD+cCg-@jH$1tnKacsIN>(QGj8J%rrmGlJkg`hAvAhN z5`3HP(xsDbaUbyK^|}*qw`6L~XgRhto+Xsd4S6=*cT2inXXf?MI_1f$_dn};FHFfx zWL*jmg+xMlE>QB3?F&5~ronubo`mQAV`8!5s*LE@>)d-}rbW8hKx{@KxlgHM<dV$KCY54Ej-{!Ks&C**58k1;m!wlR<3f>*%1kOX zO+O(!n}BZI(TgFW1U3W|nfFVHVnYq|RCPD(I6a;CVq3Q>Lp^2XuDuI27q*>5EVo8@ zdPgfyNvNvKNNtQd;#{>pn548=6CtEy)j%Dn7CaJ+QHf}`y=?nbUFIR5)xdGpwyJlp zD7i8>W0l@XjY&*PetK0+=Ql9zqoSi5eV(Juw3ocPclvIgg>xg{g?4T9<7WHuxDsZ~ z$+i=j<^qOJ4}~x6o!tF~r>kjqLb-|2bwld}(J_r^N2>|u`fY+mkB=`kDvMS{%(z{5Z1}-p1A|mDB&HD6(J@2EP8HvE@4WdLMjyCz;Hd#&&MU&IJ zEV&xmw6ueQ*F5-F%=Cs9`bpuo>e_xSzr$WcgJ`3y) z^yM>dB5gG-PZ{cs-CNMi-h0hOr$Az18vHa7fVZ$ zZkC;My?7AtGY8eSaxWONHFCwOld$#JJE`}_<2O=iW~p?2x_99UknDsA_YFR*vZCso zdt3+@>>Kcgdk&p*Ts4yzqxmCiLuk3}g&urx_Gaz^iXV1^o6c+!C5gLdjIV@sbd?0v z0OHdYOJvqpb^QG^Pa&3bBIt?9;jgOYftx-oLM*)U|DJtKU6ZMcX=!V$F!pcFwNUl^}( zxDQeLL2xQ=#YBfk1Y(Mh$woN>mQ$7NfcOqHs zHtaR>b39g^UCCvWDSLq{N{hgX`(RpshtEXKd!b#ABL~LVueK#UI+FqNrJF;~E=F2` z0>BN*^5I)$G&!bx9ZB|7IdGNF&a~VgE82bb?tB;AuEqiwepbNeO1?_a0hB~V0Q|8> zkK}0C1=$v=4CyvrATa6;7~c|#yleN;4Vg|#6Uyb4=?O@sHx_-Am!hOcRg~{u+S}9H z63RW6jRZ9j``ib1EY}{0!wPP=SG@?ICVh>T8A;aI*iR?nG%yU5J|l&< zin3G8t1(Ath?Dk66io}|4{iX8!Oc?Ky)%)6{04(l*hPk(i8KIWo>PHfped|$rknES z{%Z#g6kUWcjT4L$g9Z5f>@kJkfMlDXrmTvlVBZCdYK5sS(rrQ>5}Mi!;Qckgf;kzh|| zNs-BDwdgY8I0H%-)!mL^;s2Y03AaqGjj?BYC^cCh!^qYtHTFL2VS zRFEr$y?=Vr<74uCR5pM@RX&l(gBf=)xvyOlm#D96h#lZ1K5Uz<+&<8r@0!!=2QlKl zamryqH;>S5mn|WR-~GvWhylZ(95NRqJ4J{f+fGbLL?sg?7M65VmV@vjH|+h8 zct80C3m}Jc+kJbqo)){KVq*Hr&~<*geO1z!NM{FZH_0`!9Qf0_HqDZAS%N3j9I-@%Ql(P9k!%T?)EcndV02FV4Z<;xiBpltl-ZOP?N8b7t0G9E+?E+Uh<$HLa|%|#6uWTnf* z`+EiD2bDz0Q^*GrOlAEzB@e<4V6MG3DJD zXI{$8t+p<=N8a9R3>@K68169{U1nx8P$yzH*`D6IB_ywQ~gf zstbq|n`FuE2>Z1%?gg^Tq8d^W67$Km#Aow6L9wR;`TU*`JgenGk8fMk5Vsoh)CTT3 z#@lKpBl7tz$xoCg4^nDx9OA2DB94Wx=l80X5lVG1(i{TdiJp%YYdY6DE2VSRFAvNyZMOw-BJCKm>k8Z z`X|h0Z4#x}Nnf~1xZwv%I#VJ=B0iF!wTeMUtf{g zZeb;l!x9{MT`dm4ir|hsUU9SrlP|=KKt1nG)@=k^i=BmglZCFSMzXX;rule2{DT-LnXN1ZA_n{n!sd8+*BL8GXnVVjgvkCw~Tp?RK(@02wzCV1&b zM@fdsW_-Pacx`%s20KM8`?(L10nsJ94!5yN&oRCVIpaG_uI@CP%_V6`mCTXpQV|l&eOpW|*U0FjiN$rs?r>Hw9+ctObL?-3y z6k)&NVU0L=tA?KrX}_TFp3ifwRQ5vk>%)X3vh&LFi6t-5@{0GB%*mP1=r}Z4t4e})v^DB~Fdt*KYX+0aW-FbclzKQ43s1F~73&RJF`iwfCF-c*{F!~hl zDCQ=0B%hCxu#B5!>`mFhdj>DE4^)P8Wnqi5Bj-}htDkeZQxR~?%9wnd=oU`b8(DXF zmOOv~h}QHJ93xZjh8ceJ7dZ=$;*rJbcN0~N=JR=t1Xe`z=@NA^n1FJgv1=d6{l+}10<3np^Kfgdd<=2vUABD)tTU+~k{hj^BxmW=LRBquHh7^3hze zDtdpvr0H2t6(#j5Ueh>FqC=>d`MIEIl3IKDJ^|8Z9VX>45iY_$(xFRlias2g_9?l< zBN4TCZjCFK!lO-OZ)zIN#gDcWqt*~IdnRlS+tC{;sbGkW%TbBvCZ^g@@?cWxF_-ZHHKmlQF$FhSCvsb8#qNq%gkBfgc5$GZUB*#0o z&`c7i47Rdx;kVd;$h4S}Nb3OjuKAe3Uk3NyCEDoGrf<%}{7ifp|3=5AHxnzGq0o?TwWNS-q*AtUXVUTi7$w ztSI%U!xj9&xlG}%XKER_E}?l2!dqmE|}TcsfeOT6Jk%&l+4$g zRD`l}MhiG*;BH#O$$lH#P*-SEV3Y6&KGOh6@{)k$fOW1GnsRR;rq{bRGA}ay$xQLu zlpU`&cx4^!lP92Sb2ww7`KewlKW;a2yIQsMFo$bO4EyVbbq}kXg~$Z#F7AmUB-DXYjS5L_g-N>2ykWSaKQ zot*XWVVBMzU4Pv*YF!mqpX`p&7fijMjblOyFGS9+wYMcYuX(IT^;{P{QOgBjcJgwc z>7~B9P{->R=Z(CRx~m40R}phl_TU3&6!Sx7qKMKORupo7k12D{DPVi{7E$lv{xs>3 z9iMK$o>Ki4AF(r!zYTRHrBU$qsI)D18x@T{MLcB=$p>agBHO!0LM5+6txtoZmtYNz zNN6^lcns_VY)5YekDt56q>qt*!diHlz(YB6E)ek=H9hT}-WVcWK@<|G69dcYAx~d( zJg};srizq8&Y*sRUV0&pf)~BGajZCi{eoapc8pWdYpsUNax$kku}$1jTCy-Er(PGO zItvMrT3-?-cJ12Y60P#E3XjV^RQgmG=b|jmzT@W(51{K7qNJgtYuIS;h({rhN!ox| zJGzHt1EC9?DRE%G2wQsxQmqz4|K;>^f4vu{@4mu6?K z!&(<)d9K$)qqFDeu!ewbLds2}!Op>1tcOh6j5afp+2G@N&6*}}nag#V+;;vOLoUqC zNf~kZ=smp`)jab8U6%dAR3^p`-YiI87+0Te5iCbY)|)A0+GyY)JPH&kOi zTJqwi&iUD>VeIiPgE|&o5gsO~a>G91BCrmLz2##G>%`7ZbaRQ(`M&9IH(}ddpU)ID*eJe z3jewYf>1wg{*u!&QUneEKy5@G?} z(n}?`Q-o_kF`YMTUD{0rQX}%Ki510r<{yT=rXtzQPRTNb-Gh=y+?t&xe~Za2OIv_- zzzJQd=f;r1b~h+T1}m4nsY~;;(va}}myySXrKVWs-<7iwwQN(}dZ|Qrj}mRErot(j zJpzqFY{r99qml{o4OvJH>2Z z$a55HKf9ree!OKZw#t>3=6>JIt6q}s$gIkMF$KQK?)d)5C}wK;>tw!S;KbZr|G zTN-Uf12Zewt`jUn4YBanoB;~Roz|Qw`u69-3yGgp2ri;vvt`v)Cb1{s z(Nm)rvBtOu_sbundKPspP4YOrYipJ~T_=eiJXOsh23Q%#?iD0!_n z(q9#8#{4KQu6?$YPiGCdWts|RwzSwT`l2ci;tH+cq7d;pbQdyJCQ19Sq*81#my%-z z-$qdq0 zbFlB~nu7hiPDwEChKY^(V$?C|31QpD_Cad`D0CAq(}nSLA)+M9H3%5pWj5=Pbz5#M zn=9qJFZ{?d?9JSc4WbH0SydijN^+Opoz4Tbs41(g^^Y=Z+MDTwM_-h(XS@jCCXsAG z$B{H6%bYWDZ;;b<_HqAXiYl&Yg_B#Ij99051Gi7#dnf&{#mO<;@Uxs2>{CUHUTf*B zOW-87+}nUhli0ep=RF`IkCq?tBu?O^uosmt>S<18x*uJ?OUp&K-Wsquky*z|m z?~)^0No*s1VOwFjbj;`+d)CITK+~*x-tl+9893aG3N!S}0W!WrH>rpm=o2F2=9P@N z05ezU7ynM>tzbv2;St5)14eoy(PPB6CqPY&eD)GT8Bk;kDd3 z8Q&59@xGxj!z?cUK`^%44z_}VVAlQ79qfYQ5t0@SB~1KG>1vafS)W`G>O<1ObaG1`!1k}Fs)oL=A(%An^ea%Kem zqDhw6r}q>l9n=k|6r%(Uf=*mIDR`JIA=V&?d*F%i1%tL+pk6h`;*F zF>e_=*}koZCwSd&f>KQ`=(|w`v)+hnay;t|_)A(|4^D|!(;BdA_c=ZZ9XxOCbcC#z z#pDH$!yv$7M}*Ie%8+7A35WoI2#RlB}x=|wNPJ4BF{mQKL{1QA?x zhlDhObf=^OQi{?@N+aDV-3^jb(s9sCv(pA_Ip3~b3NS5Ni{L_ zny3{1x8mq^AP=g8tI`2=3LAXMjS{%h>xK9NHq->&2=5jEhsE#G-)w6~NQz|iJ%u_I zrPd?Bz-}ALdPr4@@hqo|I@*U>X2Ct}wIoANRd=k=r`Us~ZX@2c!UH&RHk9=lzrk+D z@as?Qdt@1y1`0AmkhuA)C9!LAwX+f2qIsW%3@n3tud4ZME!YUio!RgkbY1#O&NblI z{q?aU{;xN9=&S$aD@M~k>-%oe9%4pDtHrZh{qZHa8$z>LEIyne#36W!2jpB?TR?Z_ z%6y((RjjNqtgt3XDvp%GX@RoKC|5Xj%D;Bwv^!~hXgXcn%V7d3ab?Fezb#Pmc7&kK9V5ApULe+-Wj894 z(QLS-1IPp6dq@57zRrsTD4&iwQ}J;8`a?&wbI1BNAAy zw$8T37IK8Wg;G&*#+A>Y&B8VE{*gByGhvf6a zg(8$SFkrV^v6hn>4S&gA^YB^vKP5R$y*x{KYUVj{iq7WjaOJ}g>7XLckenk|RVb~> z&>BBqq$_6K3QQO3p$;nAaP%n}K3d8ZIo|dtesFU&fny00(7&!y2L6>HrxkS5sFIEe zBTpGodu)@4!vYnXxVQ$NAP0TK3T}yGXpIzV?rm@U`mry-ROw>uTLPsP=GXA{ zd!0S?7UZILxA~kw9ZN20p631;7gcuYuFy#xp-G?tXB3>)b;bb=TvJ)AN?E0x)MlvH z%FOyoxrW(1p)6|0qyYwxqX!_Hms7eeA>O@HA$W^pMr#r#{oV`MPq#%|+D9Pkfv2-= zj-%905gu5X@;;_(^sqx&?qOoZzMA5#Ulk3*_D*Fj4sxmFiu_lkTb0<{R)|ew zy8#%T3k*9&7}HjjiGg>ikRPr_>fqo{Tzawh)ZG53EJ?=P2pSW4Y|k0X`m1k16rSc& zdy<+b^@8Vq*K}~CorS`Mud_MGFc=F73{VyH8U%Wrs6Xi{+CfiajCcs+P7wJI7h*yd zNn|*i>lLmSzHNkKJDi;->_z;BFTWLhH)25?xP|j2K8o@Ss$J1j0SjoA!cTr>jRlJs?s!B0tF-KgS{G`Q9%!a(@lk7@kEukS^l1kr}L` zeh#8lldz!(UM0ep9w1Jzb6;9u8HdZA?+?WQ+baCFYX^t7|MR!8RklkK*rBF#(ryfi zc!$9G(#viyhk6AfT007O*8bo=`@VIya-qMmSGJSWi#6*DNyZeE8}gf0I3#WkU5GHiTr6pz%;(tWR4`R2pDGVj-DNK zOnm7zNSRH2Sb?DdNN8_E3F}X}#9BMP_!+=NQ3y^Rp3o{#x8LT<8o|%%;F2iPjUhcx z&%g#I5E2GBBcTrE)?U0f2I`c9q;co@K6!44k%1xX9rzg~Vb= zw_V|WBu*d@h#pV^&a%o^yPd(0yyWng>Ap#HqFG@*mr~#f)1_cj%OQp16QXkqXSMrK z$?0@O-||{3YHT`Aio`&~GTh6lt?JEM5lw(K2a0hX`t%`d*sR^M;xSI-aHY4%8I90) zb;iX?=axPq_qL&y%2D;v?x24jBhb!4#UA6*sRb6gl`edf;FBEu0NymoFm5cG)foGi zCZ5vUh_lP|N2F`HwXDA83?4awIj^gn4c^;HNXgRJDN zcQJN^S?lM%Wx-XLenfI)70B}V!?p=`^krz zjeO%yO6`csJNOK$cfoQL7WnCa09ge7{X;N~3XVxc-XPET(043PX~PJ^fXvpnbYcZV zs>5vf+XtmoVQ)LNX&T}Y3s@1l5mFlXE>V*&O-~3bxUXs59mcQ-TSQp;MN5_`9yKgb zqB?(X3+8r0gb4rf7gN8dhA}hA6Lsci)L1fci`vM~(3VFb1)-Ofb!# zzJ@a?5pp4_zJ8_Z-s37k`M^J*!QL|F zpj8>2inYZYiXP$H+JO#R@oQ9U$uYiMe?{UPhIbsq_VmdJvc5fTTHyT*y&;8P7>Xkd z2rS)uN-)&tv7OPsU%B8c&sDPok@J#QHPHO=+(c(ibu>E?-_?XaWt`5GSW!9Ch#9oR z=576|z?m6^TK(MQt-Or>iG-p=_1A-3{%R~)L*G-rafIJW^`U&V2G)qAYY|Vf5SK%a zeL01ZisX>q%<}1nR%)Zi89`FJstM$W4Zi~-g8h67mXhKK#gjMJaH(EY&vfRK$D*q_ z_l2Sl^$CnB5!5GdJ{I^)NZ@l%y2k#)(xsHeyRC0?9{Ia7M5wKbM+i2{2-y)dMn;uMA|EzsL3&h(D&*YL#CBXCEaL!q>kpd6$YQ0~v`J}Szs_G##r-k4ZZU8rW^(DGT$D|$=YB{# zuL6h|eM*5Rz?6-41X=6;=73l^fy_@P576?h<77Gh62~l^RIRW!xF7C=%>D+CUw1dz z^58FDjbkl%bZ8>6z2E0uS3>q`IZVyy=+2~-0;=_)ltH5^9*TZ)Q=)5t8*oBZQuu)W?mx_mVt5n!l8rUkLi z=z*$fpIJZK~u52 z+WNi{tTnRJCcdM|YsNy2C&X=ou$xhVU-=!k{>;N=X-+V~M~LF@5sSMDVxtX$#(@N9 zt|_W+DwEinvrPhAavw3KFmB~cU=a9y`p&UQh>c3PvdIqX!L+ zeEX%@exGz)4jNihO^5*XYLJEpw13 zynQCvDSy9LG=N^qK2mt-V}ykaCKC)b3~xOa_H2>sV`Omi=Y}e)rKPUwJB(@j-uf>X ztijqE-}7FiUvQ}z*hK{yGOKE2JiC%y9bO)-s$4Beb5aj6;dhD!;1Z&o$!mYy13_i2 z47_e^7LS#m`HEh0(SjWv)TormI7LTf%h=gv&!q|3-Lo78!ycitK&~jrVE<35oR$j^ zlkkV(lxxY3Pr1IMZQ`)wn4lR`S8zQ(f|V}8DAud1Fkmb_XhjRul;-WK>+~3K45hd| zaTsHfKS-PY;GDlgt#dE)l|$n@?kWY?5Yvi)71HhpFj+guuu}M622^$&6O6`S<(3;jTf8Nv z4>k+)uURXRbqsD*t7n_ODmhR8EQQfxaqq_N^L7Z=f%{v*YcA!SmM>!@)FWykw2rd> z=GjOUG6CUeOT6HB0u9pq`_IsBd5bKDBZPK{%#kH+{gP&A1~$K=0w?G+Iy#Iw$#Qql z*GpcYT=C5c)(MgM*{oMvx19NPR-3PXO*%CMRhd~Owz$8#*>Amt7c z^S#%^(XIE>gFQyD3i#a}^okk+log59xPGu$-D!FhJ0t&G|9bT@)iJiAGc>hWwuwVA zPcw^*#eE?x>-I_Cs|cP1?Z>Dqm59ejnw9?nVt@tA>g`7Lt_l&tU-e>UotisZpF(gC(6m^L?x*6nc?;w*T@*=CfQY_aa(|zyQqh89ti$ii7wL1c2 zWWE=ZYP(5r43M$}Ssj5RZ>u)_IYgDn8*^I0{rDODJ7-+2&aB%>g^Kx8>+Ej;d;*6u zIfb8js6&24del5rB*lZO-7MK)Ji#eexq)i??v29OC=CIB0)vR!&eF$Sj@&&j`No%nd*xtkIiyLZJM=1#TwnXYOnrK+x}VDNg?JlXjC$l3I`nxcbhoS;Zp^)7 z1n`plW7=mI)W}gQ)sJxFZDx|bJW64W0nfAW0ZOpI_s3dsfl>nWK23a9BWx6Gql4Nc zdWtg>s(Zu^Uz^30M>$}=!d*;dAgeXmA5T=txRKuExD=kF2VFtG?P)kNsQ!S-F|lsm z*L>va+(otCzn)M>4@{ih0Y1?yY9!Zlb?%M?^?b+SVW8)r>*|bn#sNs6|HTMr@wlH+ zJ8(~Rm>w>fp2Uh@&xFcOfrLh$w=$aR=h2-GT$#IfsuYlUsD6DEO&|9W zYYa-^iq&fQkpCIemk|ov%kd;Y#_2X$dgY@TUDa2O9JCF%47WcFSi|aPeoe8(j{iDG zaFQZhg0EKzPn`oE+>B4K)`2vo_jkBv79i@8lnd-rbvfejUdr`@A3~EO53^yu5GjZQ zN3xz1{O?eBi2kcWmEv%0Ct3P_(R8gD-j6fGOffDEZSy}w-!3N!>>^`wy4AX-^%wAYU@We8hDBzB`FRxQPM45PIS!gz_*K2faM|P zG!rbLW$~kw{mY;StC!@Ki>a=j`u(Ficn-_ozaJ%Z$+is#HUFBs8&koUWRcPjmqz{y zRDYCwzd1ablgt5*r4xtZA zmKOPQk|URmDtxaZ@<;jdn%pXv8~z17914vb;L1}7`}D!iaz6iAYPXu5Ap&ni)9l&J zr|bM5pPp~2oupOZvEF@q>$i!nUhe+WYnhB#0wuBe;Rda)=NdY*0S?*6A)8Mhg279e zkqh+$qeq~xrnFsf)WzU>*l4-V)8o>1?yZBc(LG><)?h-mTz@fjl1K3I)u=Xk61ICn z3L04cFjdElVs70fsBiwBm+?)u!)wE_%|=J0`>xs5M|acNMDXz>w%uBgCj0mAk>Zqd zKk^jCr>Tl7`$EG=qk^3I7I1{~d}ZI*8FZjKNARXRQ_0gCI|Y5ld!g%&>1!oRzvHQL zp;xi^wErAy`BheNsY)dDw*lC?I1<;V#)rUx{0>mlRydDATtJAUusl}Vrljpa;sn^% zrY?baIEz}yHvcj6G*CiOh4%F}?++j@`bynJB#H z$qjMN%&J!t%Opo*Z$_r)&gUl*=Nn9b9x;vDf-<=^TkHDk@By7CAQALI7Uy?KR5o9w zhsXWXxzXP=1>PZ7A(E00|9D5OIcKqNb@27 zYtTWBKN^xgQKh{(x2$dN17^AhdMZcTWcr?lfJq`&wiL#Z3`s);09+C}$GzI3ZGh-L z=dfdl!3XO+>hj0IHlH?PCKq5z?b5b_yw@PR%@|_W+>m4d(q`S$1-LEOfajS%3GwQI z-?R9=A=OKn^p7kL(wsTJ&_Teli?(*Men7{Qz+eL`4nePr-vS`*h@IU4gU<8oBxtWk zfOHt1Ykr=ZPx6~pDWiN!1uY}Dnn-?YXDA1 z0>H(dTn!OLLATh}IQ=wAd~Osvc-JqTgSc_Q@A^+uL63?~qt)x{R-z~OFsSW)CQafV z5o%rmySC8f-O^6R(76;IL%$CkAXhxI`uCJ|AK(z_$BM+{sCx+C{yV~Ao!Z#*3yeS- zsz@2=zT57cLuHVxtZkK>z3mF(FHid*W46nbzsQZM1SG=<-QIazkE;@ zCWVk~sym=l;SAGI%$UoNF$o_yhf!Y^g>2rEo&s^@BjVyGM<w~hq_<WXJHs27DAhlwqg2P97}oam0f!eiXAKgrgl1a9XuW z6GHwD&=cy>J%2v6w?7P&FpA`U&PXh~ZT zyMlnJ{uua`#>boa#exu771Y+)Weq;Ygp*j}5xx?<7u0_ntzORrHgGIL+QyTly}G5CEa@ zg3cB)4eY)wA5s|mWisTyeY`h6Uw6KlU&(s6o4m&SgLC55hoh^L`4=dMz%O5-&?=2V zW1{QaneMTmgD%pvV1HI+CbGH#tnBwtF!0I)Fr1sUBsWnEo4#f|Dvv8w%b<6xQlf?M zK@d`cd86^qRk7DKKm+mir3igv=F!K}eRwDiAPXnj2%gg>+HHD|2GOPS?sd2k;=ViJ zU()%;bJcE_R?dI-Lv32>3HP3)309Ro@^m-8jO&0{w-?rc#Zb~%8=pUL8Y>?dXz%X; z))yO^k9QuV`$~Fsli8i@&T_sFt|HAJC}s8_&tHgAZ<<*C6Z34U^WCj4r&WO)M)dwj z12X6if8-omV1_@?vZ|)6^0i5l+%bG{Xa;Q1fA#BF7n%yaY`FUU!kRvTF|a?{DB**% zdt07s^`YTYq;cyp$q~#k1L82SH;hJ!w39A#He9dk=y!!5UxGfWOtBgbD|_Sg76Z!*^}Q~olhPQ7v`VL zI6fJy2^ViMvz$RUFm6tgq}o>G#jHAt%bWKT9BCJu9mEj=oLcS1mB)DXo` zT5QtV%FC|{neR&8mDHB#`{QxwjIJ0b%T?2RRfYQL7Wh6sL($O9#&6$-ywzgK$5Xa-7B`tet0l7zT)0HO60%iK!f0gB~H z9qws4Ko?A#!^MeNaby5f<{02RlWGR&Cn9kBon&Y!f@3}z9cw4b;TtEtL6b#z@K6fN zh8o&~DCi3HHyfjj&*={B6r``|hM2h57Ql)}8iBj=)}fC}*tm4$j?)|BeA=7oo+L&$ zW;F(nFdIXfiC{3b8T|S)u$#K3p_G9bC<1LY1LyrU-%ot)cFaFU?xC#Js5{f&OlWT9 zBh{VfFVv>Ls{96>cfrg43jluY2IP#N81M%a)l%DqOy8zzrs8ulc zvCMafkz;UIE;LPyYCVKhzba~D)?=&C?7eAXiT-&iN((L@NYJ~8A?}2=qXb}Teg@fA ziQDyHsdrw9X`8qs8N=IcVCZu8t8IV+pBN+Lwk3e6eC5j6{`B_t*`fqe=;3Izd|DtK zp`t_#8?tJKft=>;e)ulfE-LHG>6lXa)ZQLs-z@R*z6`C61~q^dr^6VNA5|V&lSM3D z(?k%V@3x4hvUEygOq-1_a|KQ*Iw*Kc7?>^ftw}<10kW%A2@K5mu#UsU zT@|9&dB>>VSf1moV!dhv87I@C{9GIPpo6MIXt~5AWCaD33~B(T*}dZ>S5`1V0|>;u zkdMBWIW{X}BBoMeLU%~YWO4RiOsftG)-#W@yi>s8vN6z!s2=Y7f1!=yD0 z?V)KesD4R(M?pz4oEL3oC7$Q(CCJ{C`g`b$-zdQ=eM1Y-Yhzm>xH3uf`koj@PZrSW zYIYC2D83f(iK!aT4`gZ~GEX0AJfA;eIFM715&@F8%bg z5WV{gDzOqR9}<59Z@Z{@5RX*&s5#K}3_280uD(+*T{0E&8 zzKR9~l6nBSMQQpL#lv+bVGzfYmV>R}b_c~;!(v>+sp96A1#;bK>1@zTySh%OQZiC` z&1VBPN^(hRc0sZ!iQ~kr6|#Z!J(-!5l3;cLk}!wtN|j?m5_9xsmfOe-a?#vw zN`ys(RqPA9AvGwI#z=jNM-#Zq;UCJRsM{4WnPF(VzNk_R`VHSD&sKQd+st&Y@=os zED9>6fv(v81oAwtNr~bqkh53vm`?r0t>F3+Y74zmGm#Vs0gDDut-rALsDNRaR_)skZDt?Z#i;{nzj@Z(S=#b0Iu;-U%NlXZsitK^iV-nR%vt?kL;2PiV*Gro=6LEn0}|@wt`G6Lig1u zFPX#wAj)I+`!ehVJRG(gTCw()*e=`T*HC5*FuF?^fpK3r|5<@VS$HeLQQHrpkL6X= z;F*;^0J1L$pDVp6a_Fh^8#GqsX`o2DOpDGSF}{D>Qn9lv`#ZOOwRRGjpR|B@%Nmv% z`p2Q5NvGyjp`Yi;`LlrqOrrs&vN_f_S8~sHMkxl8D>baFPP2WcC?iSU*~hMTc#6se z^CWP|fYk)^ya5r8q;Mw>4dYtvK-iJYL%N*F0~MCTo%wLFCghcj9G71pbM-($!{v=0 z(Qwdx=Kjp9JxWrJ_W0Inc;}m#eWTBV*D$Z5ch33QbvKt|tK8z@a+bbxoleo%&ru#< zoc>Q1^K|F0#d8b@bCY{4<*6L1i!G2Fooz7-{`O62j4WG3Y zhsV_R643u1MY1jBU#_u7SeNOK<~2f#9}i(UxK{TZ{(bB-s(P9*DGToa2{Ij9+1Fgw zm!(|Ana5wII8d|xelgMcA`G@{UvOk{3~gu`1JIxUZ?|$Zfx@i3Sb;ZSAy+fV=aZo~ z{wrpf&eY{`Jto(3KFK{e2F}DJgAfZ|rCW(1dWHs?gVUMI5=YfoRyy*UEH`h>`u@x` zK&t)kTYIY9HFZ;YiZ*wjt^zik5PCT|aggavOZnqnA%ydh%z}p7sPtUHwZ_YEi;lH4M~9hSX6BX$2Cfghcg{*QYJLplZeF_%P#0)iYB6R~1a< zGeFiF%$~bTZ}fV*B=`*6NO#s9k{+oXd7KC)X7stuybJYK+$?Vt+B5Eb{iitbz+3S= z8Q9z?PW~u$NjN)0;H=TUlZU*pkI^RW(wNZ5P#(1#O|!dcfQpmoO>R`Ie=XMx&Mz(Y zu$F_ymT~jzLqq4Fly!7mN)y2FGXO;}j4P+CI3O`d05)P}%FCuDCewrKRixqHpX*-T zztX30l$BurX@KCq;;tL3GCE49esblgBDriQ<7#^s-JZPvj}>*Yo>@Cfp8QX)H!Bf4 zruC>i%p~%!Kv^)Y)whbdY_%&sT7T0bpfP?pfmCy@d5GIuZavtO8_fJmTqpeSs8&Eu-nWy)PT98KNXY{t@4QWt(4ZtJ;JkM&xtSAx6 zSC7Y*CAJQfBhwGakQ4r;j4HQh4R5kWa1<(Pq#H5DyxUMa1!r|LP|t$o5K6iSh_&vz zv$d4U$5l0)z;D}DpfA6w$q_DHJw>2nyWzM>Ni8impvkp4)is|L!2KA9BmOe*x8hOt z`G|b74tq2CQj|_nNnG)aYHGOV2~ZcG)h9&5a}@qgBTXiS)x0tuF0uo5A#5-Z#9?!T znX-LPpNN}!E9H1h+muCC1L$2JfDy;b*Y~I^6y8N&wNkXG&KyWEg_9c-64VR7Zwchz zocbwJrgfqm$mX4SMR1OYeUl%}6BHxgo&Ut}uK8E0V8uJX@|lg^f0{oofaeH+m+zJD zjZ(hJwu$E9VyWq_oq;j4dZZ4Cfh)94J-+b5Eyocx#rK@wW`=vkPi9taRl0hL|1%+C zUEQLP)rrLEemZ*hWFNI{siGf{P0@jm`Z&K7z>{wvRIT(G-~VO-dUaIWO^lr2_qU&w zEnNjhWXZK;xpSi|36vflrFmbw^Sk{rfLy!~g?IAR_zOF6s_S|HMl%DDE~OVqVcy06 znGxLr24ONszy_@=b|_HUy25?4-)J?G=-7H~GM)vqMO2T-_eydjRMiX!;bNrnABOUy znly^!IiY#j9q6JKs#i|Xkn`aTAqGa*O)FQQ7piyn$&=FzVKao6XREqu9BXAqz(zkZ z{Jo+TGZ^R;2x2W8G30u(6Zp2u*#ShWV2# zbAMrHF8v00j%I4}rHN|)X`WR8Dd9UrWRj`y~71MRmK1MYZ;_R`0>4SmV0{F)OyQKnd4=k@e?U-+9Zgut`7(-rq2Lsy>%}rz6Tvyttzhaj=rhH zpG!wakkSQVIG7wh$m&l3*y^@;9=HHJ+2Cjz$c924*hTMX9~M?(i883-LNjV6^BaUw zJ#-(sXE8|c2>2V%WK*7wmpmh#`PT}s?rP%8of!GIuXzz-jtfQ?%d>y9-c-^0trUeU zxOTS-+)+K_fL|wjiElZ8$PNRI)}!5=1x3H@w=%GKsQL`VYT*ZY=Mc*~1sL2Xq|Def zArTyi!Wkmx8y|N@Mo{q6fZ8@rsEk~+|G42*(^3G@#?)A4tn z_8JD$m~DAL%ysbYnfm|?UvcTZmz|_%b$yur$L(Sf2-{ze*AG4K+yrepJ%8|fgLx!CXhi|$>>d!%zlK`^C-Sy- zJp>DpI+%EAjHGWA%3?)Y{GZK;V_Yg9mbFf)Z#CZUsqe=U^;>(qQB7UD=vsU5PZ`e&TT(>QbzGl>Jv ziV*7qg0MhZLLXo?+jNa!aTFMY5(W?tx4Alx7wK|J`}s&8{7bp*g%BQVH=x&v9F8!` zp~}OAS|Fypz^9w)dhZp&9JUG-27}H7p?7zaV(v}V0A2dUlA+96wD z*D%8562$m~+uND$asUd%kni7hJwN!yQCv41s{q@Mdm>>u@1Ju}zzwBfLt&CNFemvy zoTz{$5MUAlp36{rUHt;Yxc3k+v!+P~57H;?3jA(lOzpmJ|8@2Rdx*!;hGC-=D9+X+ z`sYmp{FD(??lR9C^Oi6P8R<4sEpiD+q&i0^r6(-C4`cKgLQm|h;0N1Af@J!%`P>_i zOKRiK(R^m>J&%@LRd{bH$D6bDx3PnhLYU@W!9i{`Pfb2g*0JSGRSAn)71w#l5`+%| z2p5a4A7BYE6P&VOQYoT$W_yxjS$6^K&nW;%I=fx99JL1NvMXrKa+_m?DJ%wRfLZPy zFGiT2nJE1Wlu|P8S_GRtr<(6Z1t171^rS%)SAc~rv}(iO%zXM?wbCtV&wUdZ9O*{x z3AzHOO~M6`_@?{xL+(0zgBn$LEk8=Y?-7PEgDh*vsXbk)#=+1WBl~sXIjl8IRNYRA z%4!-ky3uGE5J2bVRe2*18kgs4K@LZ34PqZTMu^32J5UX_2 zM9R3kg<(V2IR_zgrz2_PrWw43;-OyXG6Xs(?TwKwi_y3$7Ln9{ndYQ zP(aKnM!X>v6mR>GEMNQId-foE;@=exspv!I)!V~rBR22#%Nz;+l`l`T+|aXuC<=>0&t#O25~lhFz{@)7LCrzRu7I&IwP)EsB5Pz%6^J9f zkON9{M4n3@xtRk*s1Q^(OuR^1_l}tIk>{!mrMn$S532Y?DD+rE@xURp4vNhAhbhoP zl>MbO!b(&<8MwfR0)QbP;WKv51K`lz>ScWdAB}<=?fwNgNg&1*{HlG-VMG2gvN<4h z>ZXF1%RO;+j+CY7SMIk6RVN&M8sc>CX3NMAa98JahPRInKg~0zL?z_#*p?90cWSVC zel&S!dDyAJ;`xlV!03O*ado@4CR`ljF#$qM7MKr2UQ~Qq*_(P4adsqcOj&H!+m12L zJgE|(Pk`<{wn~!OO%jK;UP;|0oBN6@53R|!N{XxM^R2*8M=w;_mNtTejx&LEnV(O`=Q|ND(Q}xcciy?&6Hr?oKzT+*0=d*{g5QsE|JhEW)UnWfs*pU7z@&#jP2F%ON z^R>)i+ERCdL6$lEoR|gF64s1|MK_bQ*yy$@+Ovn`S_WTol;vgVNroJ=K_KVkcV3`Q z19LsO*em(1LPpbnpKZfX6_;%C{xv^o$NM40h>Kt$>T-5?_|KFyk=5Fa-h*E~C@y2G zESo1-Z^!|ypT>tx1yxKNK+m=`=tAJk5qs*L#Pj*^n!SdL{%aLDv4+SDo&$d1ARNxA z@AnRV6yWF}_Zf-@KGl8n3uN0()V^X!jQJshQZzJ%NR#yZ4P|Eq#-FdLz@IaQzTz5Y zQKBtM&GB%M?-NIP;031XdS^237PyENM?L)UB=tS>=AFhkRqEv{sax;iPd?vl3?%mh z*^8{2tCniyNZ1*Xo8<6a15UYg>u9SI?}8Ave1V>+>Hl_hqe;+fl&eCmatW#g*L=C- zWkbJ`x_hnf?EZ-0o9YUm{juV_ZkY4+j^v%Odp1vz+q!CgB-8b)N9|8RPY|ANdy$xDV^1sm0Nw31a!dX!isBbml)hC%>^@y|Kh# z2gpYM^gxUBrBtMUx8blrp40~wCJ-JjEYtTQ zqlCB7^Wr2Q)r7&_uQdJ>UMPF&^d) z=87sUA4$m+;n2oeUG&U@h4$5{ zz+~@|<-=x`2VVwkG^w7w4maVdlUi}!ZTJNzZMRIRHuxoD@$&ZYME3HinG|QduM>s+ z&EtDM{ppQ2{*#*5;YMzNT@PZI@5w@!7&bs~Kcg?)sLVd0yD1Jy??H3EoM>F?>dn-x59?j-ayK9^S9(S8@J~LmYuL ze$nTQXxhNU(h|W_ZbTn=k5oC>BIf^#{#6C`0RF<_hDNalslTeb{qn0FnZB}#{j;@f zfqBX=E|rUDGJ89ujMRyYZY0%$(C1@5M#0U-k?Zi;x>^(E5=CZ2|3s~bpbmT{gkqB! z99OVgclfvlAnrE6%wVn)%eicR?Q1XdJWuPNACS4Gy?yF=sLnf&6Ltab+@moJEXHeei&IgapT=aEd z_Rz0^>K|Z_%)77C%+}n|7VmhTNh)BADEeT0?u;K!qd$w8D6+6tdo?wmwcqzhZnDgI zQta1)T^v)$Z`vKIDaPxn=Z+Xla4E`Kr~4SnP9c0TI4DIYDO*)0Aw)`YBBb=%vZ%)3 z#j{}ZaoR5F7>;3(g>jRMpRL6G1lx`P=E7>x#%8uh_CLSTDy=PQK!|(Bb9!R2yjMLl z_$fcb?@jTHY=u{df(DU;#V63a=%{n?O*3+Es^;v9mczQA!e+W1U}FNGiBZO6@Ne7g zmJLX(t>#ZwfTFQO;4Y!;b$;}=nTGlCKV2rx>T5e|lk|J6W|2PeOVR0Cy=ykpFT6VH zHoa}fFH@-rpu4z7uJRlbe96gg26kJFqZ$uehkS1Ql9Qni=h0eUisIq=fDkWKcewdZ z>dCyfr1Z+7{AQI}qP7_Y8BQQYT(=RN9UnBOZcZqXn8bXY{h@%%a!M%cy>DJkBDWSr z#1T}xk6P?(GYvl;ibTeRj|wSDTs|;Pidy$)I?lu)PWU^})!easUx?r})wIVOfj8rc zAE`PnnN_Ih7t?E2o-YOHj6l=qxMV>>)Wvi6y(Vo}-#5*Trbj2&a{Mnir@_u>p8(pXe?ZFv^>;I8Iv$>;G$lK6(dD(7=>pJF%quRpbcIb#VpI z%XM{UPycjF_5ST;qcuiBn{Edi61Dph6kka_K)9ImgVXSXfbqN3Ae<{vBDcqp&_=I8 z3w^385vz-5gZtvz)^tA$J{LOKyn8e>1G(+4M;iI)o1|1!umuD(=Mwce8=z_b*e_he zh^-@6L;WzP)u&?cHL%fHfTCl3dp%SVp2CHol3U>$3>@+d?uXpp?_*cwI6w=F8qMEM z{U2K+#=rnvmA?QQmv*=~v|gp6lI6ClMm^2_w6-X}0bO%}?2r*=vuSv@?VZWrd8f-( zY22}%LT200u!A^QFtXqOa6%5Pdrjz6~q}>OFLnctW`ka94=#TV2m*yV8du9p9lR_9}HozZL+KD2kV#*6kz!2gZ z=lV{}!|?z2seyAd)sC10OIOFm-Y@-+lC6s}K~X3*(t7*yf7a@No_R{H|7*|rV2NWU zni_BDu=RXXh%^1~wFOjTQUo=*;a(t-2=%QH$Ylie7)YIWrZfdnnk@d=*f0|t9_9RB z2AmHn3i}cB^TfzZ>&(0Jl#ddTtTSB?x^DmIe9HtC*)0dQNy>6?q0a(^{?e}ZqrC?~ zF%QlZUxWYrj!(+bKTI9EbzBmbIsQ}=bL9%pc$`))uV}p)aer&wvKrlj-Ju{#ixD@) zhEl?xA;bL}YjXKV#b6pgjT$w2K_KmQ3pkFg4}-I$0=T}R^rcItzd49YCoc)s;s!ph zkHV8L7$5z+Gx|$C``6&F`uh6T@YlS9iZ3tvkr?SZ3xn;%@Hlgt-tih+fWKL*I%FIV z>Y)oJi;8r*kH=b}hHhjo6{xpOQrhvwI#b+SG)oxgId=V*^fyy=iumJ@*R#^L|2==O z$M5Y2+;zYF8Wf9fRp9>}{LH!NpAYgu0pI|wu)EK{N)d*+-L)0>oOU4Uv-$ywl7s4e z$rR68r|i#`57c`ei|TRSKX)|EfPoRrA(ODpv#Ddzk)%Tw4jMQ32sjlbM1e2!CnQr& zLIv}jfcb6+D9*YC+nht6|GhhyYd6&Nmi4Q#GV_^hClzz8zr|l0Yxzc#lvq%vW2;~O z|MIpIaPJ=urhB9Gyt_mO_HQr1w!P!s`lI1;AWV^RSSyzQGg?FvhuoiM7wK)z-j8X6 zS~Nu_Ta}8-Td+=}EFo$g``fu1x(pxaLFS9I*0Bm6I=xYAYN#23Xp;QP$O+-*JqPZn z4?xJIY_jJ4dBQ)F^T?B9Z7LEpTbq; zjw7(y`-82}w@(w2)C(f6ZQLyf^hDFRXEqfnU|l{~^)cJ)L@&mhJ>4{m9e4~lk8WLn zp$*{^qJRxr4wyKJ>VZ9$m5Tb|P_^T_FkcUn{69OXNPN}j9t9E0vUnKO|D$&m-b)XG zAwG~uM&i*x{#3Ht$K^;p6=m4kE{xjh@jf4TKK(XST0V}T#_j6-_#;4~1XWHLVW021 zHmZOU+95*IqHq5>5onoZ#*#uQeqy2cYE3gD^wHhB3XOD3SJ9R z|9f8_+Ar2?&R@)(M11!jyy$mrU<%h0*7@h#n^)~{gYiA;a%zv7>%lSEKQxHfW3NHM z&|zSBm3YXKnm8j z;rwq$Qz^9m$!fh|po-TiZiD;Xm)mJ>%}xTJpQO(v&qL;Ns4$FC|2Hn1f2P8yX0IrE zM^y1Wfhh6-F9D=v%zB*$K54BUynVjKq{+(L_e5kWG<=?IZ8&&>K6zV|5#C#bdN1fn!QKtHNLPIi%>XHUG( z<9zG7SW^a}db8~i3jK3jaQ`$|LY0AS_)a7_uU}F9Z=FLM5s8k$x32*{Vgu-(Lf~It zyNLo%cAvFBpMLfSscjQq&c`VVU*I#hdcYOup>ao)K)Ubg8K^F=M0ES{CvcXY-hPAB z52?MUa^DW1BA6J-xa2%OJc>~AgRwVsum_dXWPs=M6Hv>403*BVkZbn2EcqW$GcLP! zx2C6VniSE5Q6-z?0*37ua4e6E5?+G+sP+OCM}LA9OyG+d(^`U--UFx>;Gz}qX?_B0 z^u&na_2pT>)RMMmh=zUnn2z;XvR~lQN15Un(|jx)kDW)+(tT`Z(1t0oqUU|(e8_;P zk!M|F_A>nEq|&dY`|_$aYCteu=l6_f{$xVqI#>A53olnh!Om*$PX(ib!dr#yyti2u zpEII&a1muB)TF~vCKB~MM)QWCSTE|dIlN8oo*>?0xV@7Q@yJI&MM4PEJ&CTMOzo_He+-5UMNB{ERt%x3V|U)VRJ z^)aC*tF+Us+j3+%h@(-ei5R!zh=MrD&BaJp-V+xmTH-v1AoGdj)jcp|td4**N%a(d2ZVxDSi(;6Y@B+IGhm; z7zSY|i&pAi$hWtz!B{0%!?+Lm7Mie1u%rX^1HKEjk~Qdexn@_R;_YuT-BVXg*u>NbmPJ9z}A7lRl^z!U!`@mqE+#`A$ zs(tm$B)!qCs~M$ef<87D&^vm{UDIo^|LlA(uRJHgimsLRp3b(RV!O0R?~cU$9%DgZ zlaP?am1avnfqx}(x%x?&dg^e$H48)NPU2}cT`RgAWdN?IQl~jc$P3B>h?;g7R|u2S zuU~dfRrL1s>~BtL=PCBJxQ+}kkOV>9Sf=i4aMYw|Lf+p82ekK(X;6s+s6;K{!f;2x zvI!2w9tu8bkT~dM`fObZq_O0^kB%_?Q>rX1KOz^n^!s8k94A8r>ZnKs$-`}@Rk-U- zYF@%6p^f}!>hb1i_}6Tr*@r6_Z$lA70{)$W`lqrJA_(0iLtDuH?)qg)5;3Lc|_5uV`4IN&$*&l+}Dd42Sri>F@P@oDqX zL6KhJ*e3i z_4&NVIgax-CS$JsoW_^}np>sz5x ztGji#ba)I?wn>6U0*J2f+LtLCw~zh-D{5`opzs(*LntNVyw*MU3zb5jfkLqmq1rV| z;nr670(b6)tNMi|mX~1prtIQ{eVWD~_?8$X3iUa}-y;-pK%fI}4{Jr1uZEK5R@_(ZNU|)>suxhnVLi9(tMIDNCaHU{&!@(4r_MQb>iLQheoXob&m^owh2|>cLQl5;DQg-UWwe{*$S|{co?Yl}@ zBub`g>S~K?1jRd6we#!WNBvkHwzyn#e^efFZU2q^0zMaf%D~#!ioVgr)3FuHQk~K? z7>AO5!;)4HgKx%Dn8A7Q5H6R~_IrSck^)6w$G#O%UYu zJjH1asIZ>E8xnTlx8BFSr|8bqL9PCo=joaHMH=(o0VjFy z5~&f1P5l*v@?zbAeT1}zMNg)#hTxUlC=J5FOlk6+k7*XxJ=}AQ(siGA+ATPopQfI= zVJu1MU7Gpk_>Yn{a|^X3s1rp)@64kDj(FcV;E^@PlYPUN>^672{1hCK%gKk6l z@h=PbySCk3yvOBAWPdFs9!Im*j|7&w_(gi{^pV1k<>kYp7_EmFSKDlqxCqslUyN~P z6~A?*ogyD0A~KwGw<%}8J@pX45KHf4+w*V83AD@0PZ3>Rr|_U9xaoR9sCK`Zcx-FE z2kiu2)$u$jA^9tc6?9GkpS_?Z%E+;d@hUM$lIR}Jiyl>Cr*3c?ICkOH_)(gyS;v=C zmq#})`|wz9-*D6c?XxNnWRkQ|Cyc(dpVNol^6fG5g+ianIa3$>B7=2`Oh|i&_A^-$ z1_|cHY2h(d9f@%jHr$_V9@iaX63|kaZE2(M(qyRguJ|W#;(AxP3Op|uNlnoU`pEK6 z?qhz`jYbu|)MWCQq4%bKygc2P`^AdHE|>h=U^AS%QPxBszXpg)83nAeWk=U9*Df7i z&(PKX6GX%y5V4}MJ3m^SRu!MQbcyzae~IeUhzkXkE2gd%&FCVy>iWnv6*M9CwR(Jh zIAwgLSV>wcNQIL&r6;n9V2`hqCSNy^dh9jeZKN+;*_su{mDEhx1*+e159_}bCZC4VW(EA^a3dO6{J=ME6>=ckbjyIOl7et(weWv*9SLS)=WpY^dY5w>?V2J zo<)JB_Q97Uc^ad;o-PKc4RXkSuY{{S)l>NL%{{{r9ZZIB{?B23eeMK%E2Ti$VEi;sr zn%9kd>)>!z%JlZyTeP%R7Q4^$|5aLZR@0`NAfT`&+b-=-U|$0kxe<>`W9UA!tto54 zdXxRbi}$B(GPg+frWiQ!W-6j2U7>{go|XT|%S28QgtE}fP#gFQ+FaU07&&HhFDk}s z4X*^$2Pej#pEXXq{tJmhyD0=q4u+*O!yWjq*?r zVT#FedB!N{`XcpCM@96nKtV0TZhU14pqi%0f5!&-G26aw?HqzM7$!)@fay$~Q&eNB zC>t5SlV5&8LuGcr?Yzb|yt#q$psqA^Y$D?sq5D5rfsu{kZ>#;yAB&+oF8@6hi)OU} zne0DVzWV_=Pz8u5JzQh zOc!XeLhhruGWx8O!>jUfA7I9ijE44sjB4PQvhPlSp_KSWd^#dFfDxsLzPDHil-0DknbIU=&@G1ak>xX>4h%z9T}mm9 z(-F{PNo)m_&s5cps^9z7=r(?b2=-s^ZwT>!+5Z=wgW&G2)lysBtaezr5TbR{{YSpc zOx%y%rYL@8W#!bgw6x9~>Pi?VtOsO0YD~FN!Pdr}b2QB)*8k~rLGUSabj6kL7bwC< z$6>VqD0XPnbAJR62Rzy5G4K;16P?!~pZ_*7ad%0~Q(cFlaAmZEUMezvxZw%T3JoDF z%V?S>%gLgebuHO%RquAGO!-rB1+={S)R|5u@O3tu#G)4}xq1&yh4`>av4mmo@{+9l zzSFP9EUu-^5FucDTxs!U<(1MGJe zN9?VCe+;11_6hWrkz!pXjQK3GT!cM^TV}RtI;Ux}NMlx=)c?~V%4@NQVdD3?UMRuv zE{zCoGp%X|$Vcueo4-HhS0^GdfW1wfOp21Yuu;*R$f9uC-cc)QV-=a1NNX`D>l?7u zVb|zTpfJ_B>>0you@KPC!7$i&=Jh58)CSw6f&ZNV{I$r5rs)2=1|49;uL1y+N_Q)f z7Q1|S91>VlXt;O=VP=sjLQNWd(aT?RH@iYcd2xztyVfQa#oNW?}chk;O^8R7-x$z<;t5 zu%E(&0#5;B$$M@)!){j{hWqa|jnBQgIXPjW;kuYYnmpA_yEGoMbdvyw^(Ro739JwL z=rE!s%cpZp8$fA03wi)k1(G=uh|q}#utyT%7PlTES+PqAWbwWstUt<9eDygc;gC(L z#DBM_YRnhl+h544UDE;>x&Lte?4nI_!0)nJ?f5nGQd8EnXoRbN;34{?9L78r5q=V? zR2Tw%!1g^dA|SA*KzPgbGKIJjNsl{m4mAgVK;91KT4Rj&9XJb34GT9EvMZZSt>y-! z5s9|+OIs42CYej~QMN)w9$WGLA9c2r4u@CeiFtLq$Xf!`?Us&Bz!&9loX~@eco1fg zivW_dO8_$d3Bh}C3HYLc88?x?f<~}kbZWK1Ua$wGWhWJX9I5;WwGI0(Y!6F^tZS=h zB2Un5qhe0>$Tj`ap4+l2aLLpoEYR;r)Nn9fN57--eG}6MWXy(ilAV$D^W^|230G*I zUzfAv_PcZZ$Sdqcdy;CKME=9#4k_PP3QZ=CZ8oOe>Z%xyq>BCVL*qBJN_(_q?R5Zf zoo;mP>8@BN?|yi4C(t{@@6^u=MHgkzpg5$!?~DkwZHP^%o*XmtM>J(i`XfTf(7_BQ zEqrK{i_^tyD6hO;nz$>l6_j=r&&TV~)GHsH2OFba%3>UBJBX#zpK+8Eplj_gDo_tp zhH`+I7=~e{wrsg_5r%NtLE$b{EKo%7rS|nab!zMycB)8qFMthhOfNATaNxP0q((XP zfuF?ge(+>ReN#f@O1@-CGrr+qZtZb5mO1!kMeHv#K?K*JFUpD{IN+Yq%yg!Q_9iRY z8G%T}gnSdo1@L>lF)x3FjaryR?sEIn(4E-Jc+|L*x|mU_?>q|JI zRxH|if-dmU59RS0_RNq6wSgTV=Qsg!E&s8n`t?swQNR(Enjhp)EWq0zs^?@>H!lf1?K88kCM$*-6%{C#V%^9 z3f~XARG+)#pVgs(Pp-Q3q$UQ#Z#lwnGrZ*n&bAS+#Z=phq5hKf_n2>uYn;V4`~u$x zPaCBg(6+dHeUA9TK9sq1wbm0|62gS$NM&FQiPiQTkU4Xk5BXo_b%4p_f2}G+*>7EdidZVf4<$!843tX-_J8q zB*o-PA4#c^#Z@JTIO>Gx!)L$&Zvp9(%h0^?T)d$o;E&+>>d#`W`DceQxwy%idl`0} zM=X@A30kw8qVOKSh)mhj>?uHVq7m>5y_%&!jKTQ^I#*F>@IWMs5t4%f_N$2qW=zh` z?~oPGjaSi23U0vj`^N-bm2YTWeyWhw*UsPB)}hlVq_j%aet&CY@TWU!-p;;A&~Yk~0O*d!O)XW_IpPJ+1TXJm3f>vpuhtfoqU=JP@opqt$E= zt5N_q`o-gD{pt39yl4>5>`A^|r})+rmv=qA5nV_=6FjLZJyds@7D9k}_s*A>tj^=t zmx(rq!aH`;MuoHM%7!wlEw3Eh=&JWy`w>z$;ZYDs!ebxFcG9C1vvh&Ox5eVHMQ1@k zoVsn(-jxjekL8e{@GBnrB-dT>a?4=Z0U0-d8j{N0_qBtf_dP(QGp3+(gQG1Ya)Y!! z^w*=w=<=MjYIP%}&f6Q8sun9R%xu`gDP3?j2sUY5Ul`(N$7Ha3S4x=%-=8rYBMoQl zSM5}%n1_5wK;vf3m{@m(jegvx8Ox3D#ZX$5ukg z^pyeAMm!nx5y6{&yM=SN*cKFu8ri<8GYqgTOb9pJsyxDnv28jEA5{PjuQ|BTrgmDH z+{B1j=^F}?z?Ou9ki6*Bu+htM+==SxsV^fN{88_E;=WmHFCS(Z{-QAfur%;35c&+d=%H2j!ha zSDbxquyP`xRJ2zjhCiHh&_;WM$>TWovrfyeid0}f?9u|n3(|6Oa_RNv_(%?@ENs!S zllMK_QIqw^uK_%I+lgZvnXa31xI)N&{`G02rX%-)hEu1#B65AeF1P|s59dFFyg?3V zwV(pN3VYZOP5_6YD39oGb5<*hvHHp8fZJWQkDd!kR+IvEIfor6a2?7D3wyWBNbGEV z3iS)cmrm0(!#9Vr5&6RXhzo0G$;|ZJFiVfAM0>Yu0|bE*z`X~f-if8QWyqZZkq#2? z?90ju-KQtqu$h=SQ|`f%Be(@C!+jf>RHLIagC%?*rP1i%f7Hc{y8|+U=U(ZjCKjDE zZO(H4_}JqA^s#V4L;)cZ_+VatKBrSb#Z!cZTHx0P@{KI!d-?q!f*{*cUt~S*lx?hj zQ!7*XOWW4<+9fsXl@xrB+i*|!cP;s+8EBSnJzsl?PKn{CiNj*lnt9?JZGSlN!k=kA zGKKq`l`vT#e?hj5r^fTXDaybJJ`CB4xH!M<>7zY@m^$hJ?imuHlIkA?j{nA&ZYr32K~b9 zq)sb==83}5bZgbYt>CdI0T>oRUUdo|SJ)3$`EnLqHN0<&X@jF$a0u0)>;`b?>01p# z8ey~;vwq>D`Z8mP;HZW5DCu6+rMr}WaRIXA8*bTaayvYYy{pvMnZ9BO_@Bf2QhDql zf@vGh9>`{Vg5if=Db&z}W_o@Zn0~j8Y{Wv!Q@RT5%P*!|S~dSnUo+JNV4;mKN%k!_ zM*9l_dEiod?~U3ePnByZMsuT zBe|@TS{bKB)wPol@5hg8B_017m;~5_o;B1;H=+4P zbwk?YLZNM7#4jfty|#y)rY0aT9Jl|4Y-wT1c&0-e#u{IGP~H(PsWW>22D@H7U~ zws8EJBK;X0D+nyIj1MMQJTuU=JSB6P7Om1`tn;OBqhw{zpsW~)W-UVpRN&M@_NHf0 z!hSqxGj^zbM11AOukVx8j|ukkHh1V@o7$8$PNP;Gy;EWI6(>JsLbEaX1g0;z{x6zs zudx2o?p2NxdpdBe_8hxqCw z7-+tlNxJtLd1Z{M+1_ZV5Q`3HZ4T%Go$Z(cwX%*vGY|dAw`S?I?re!-s!AVkJ7d}|1g``w~i2U zDr=ZDdYC{f?LN#jSIU8aWaA2HTqyR6B&J;J>SXj+8Em9-S~Jb2G2d!g7#tZtJ3%Qk z6+DSQ!sRe4zx0_%MIZ^bkAIHKgI6AR4>I(-rg^-<(CfN&I!fdA2(g^0yXKbiiz9Se z;Cx-N-S`K7pEnc5k^b*29MvwLVNDS-k-<&$j9q>c8gSaNOrKxp7$Lmzc)7k}Y!Ru~ zxJJTcJt_)0VdD=d3URf!WvX{I*8inWdZ(O@RNg5IuSxRwX`>LoHxk7rH=5PfRU_M(vN1>G?KHVvI(Zx0 zsBFZ<2JB2fQ)^!3YWVqN%f0fK>s)XkVy3?4=irm+8ANt%q!T$?yiIK8h6-46!&KiF zZFoP2v`=m5HDi|jGa~8L$-i*4e&-qMayJOwS3~a5#khq$Hd&GA`l&;M4<1;nk8+$n z(hYagSTbP{goZLIM@U3r!pQ*$I_xsEPXqf0#PR6QgJ7M)_PLF7R`W=Dt^0)Ioc&Pt zV!uxfVw2bBl4gHi;}YCr4~UB%;36i9qS&Rx<2bxqN;f9>G5|vXmOb0xSY2gHmg~jt|0ctG-?D= zexiwBHyI~A6p_}L~S zMk8WUy1{Vek=2)ha73-*{eK{n?2?G)4TdtXV7NSI@13J|pwiITkh0CKgyCxxOx$6+GVhhb}ZIFH41aZV;12};K zt6{GMVR-vA=)}bZ(D2F54VFwppK9t`MDhIC&kr_3?BLV%Rr3 zZ(FqIifsXf%u_D9lOB?t*ljSd5J>%>3~GW;Jlx2-Y1Lx z%b@dj$0DHjP4NwF1f(6UqN|#N)?Di`DnVhgqa3a;$5s1U$6m@aMe++4`&N6zO9br> zX#sq`xuL>;=wq~T2L$}50+_2reD!n5&EE%e=v#c_@wg2-LQiD^yX)T z8cZ@;BO{vLbX{&79K#r;r-(}?RRk5E%2$XA`^&;!vCxe|YhOS4f-3bdib~iJ0Nd>J z2yi=5a66EIcH5tT?9yra{|QA!qu~EWQOQNwVb5)*A|sZP<;T-`SGHzBB_Y|OD;>j9 z5h7{H9z=JQ!Ca&p|2Ub`2%%ajjDDint#W;;oUF)^DEae-vDDNR7a9Q27`kN=M8hS| zRnaYat&3s~mjV~V$MaEDEbz(Rn-Z$Nqxn!?Nx=8Q>MK)GtZtN<*Mh(9nR1rA*!X_$ zFDH4QbTUK1Tft-Wn<^|khFzpV*X7jmjSrfvRo>)Ia$cS`(8`_+$W_FUjTWoK1~$lJ z?ojfpoUT-<@TD9V)W`?Oe};HfEp4 zz49)Rhwo$D-Op65idc5cQ>gZR^SDq=DsA~@zFujz)ODzV%wcN=Qx=b8Cma-T{(-+D zh9q|nml0igw+2i@eauuG-UH(^ymmy^MBd@o&ae45>DmLUMapu2t1UH;dE$Gj(Ic;1 z_m$Z+dC<=6-F>jtTX5>;U7`JiCA&0v?BcPuV|QMjI`Tp2e@|zb zEu4&DPq8$9vrxmJvtMz&$zjCaCvfu1v6>cF_w{n)s22&|0d!jUFjUU+eG5qyiy21E z>Q?(VH$lsjt*q`-Zrnnr=M$eu#zO?@jr-sDER%@DsxL&SMH4MM@7r|zFHq8r)~y(& z5ZiCpfft`G7HAR^Ze+4;AjVP>9CsLy>*uKyxwWWjZt~_O(2w`V@Vu=Y?>Xp7SO{=y z+)DnPv$8S2QXjQco}aKa%6LP41y#0ZNSyK(WQTb^P2^hd$1|_`$!M9q?fQRbw8Vxc zHBadX5iZb^zH)?#zZFNe=PeAms+cK!E~yg9*sS93%O6&<P??)&})q@*dlzB%fEve2$pj|m@ip6|c8br+vT zV2cyqesjS==)WAqnek?Y^-ij+dv6jVz0)oI?%MMV7g|vJ?4iezam9-#j6cv%(fYwH zRY}v6q@ml!i%^Zh=lIqh;$}NdYw>?!wp@~WHU4s|!hrIn1o3G0a>W%!@$iZk-)^;BI`ZN?(tEzo0``0;AXYCq0`7B;S&7S1fG~|JA%pq4|r!-@(|Q@xSJrGydznbh!f zY`V^9qU_b>K{Z8+*+{Amb@9WD^HX1RnsGg@pZcDPt$mDZEYuzT151@%2tDl_>_Jzu zcErETbYwS4u=;S!!K}x&mve?65nJwQ-56D!V%Ge6is16uxgN8cbblsDKkjUV_=HUM zF}iAKpTX%QH$7svZgh$^zD9V&M(?cT=ZZ_#hI-fkvrUgZ=}hFbPG~TgWpOQuQ=|z; zMS-XPmS0rD$@?UBj}7aq9;@2xu(h43d&`9&B4|z=ny}r&ALxyDT75*G#Za)ko7sNQ zPxcWueH3bp{FgPpzJ#F+%}AIBgruTZWR8mxCv!JLTD*3r~%BNJJgs1W9I# zt&5U4l@@!sX({`qUh16sr|KuFGO&<1w{6|>!!U2L1vr+y6$tLDj`Ci9;~S1g*CRi* zahsKy&MvU(7NN*k=0Nb0Lcan*LG_Ftpc2$b<5Kzqf?{ zzrDBaQ7KOiGu?2BXurrLYI71hb5(JXHv6l-dj3b<0L?~NOknx{EC+X?e2X5&x*v{WN)c+YU8yBV=<-%Sw|r*-wR&g`@%u(yrMB zUSrKL6WZw;Il`hC&24tP1Y*+(?t9ctub~ye>n#fhn$=ZzTPxj{&myH>!*G%{`RJ?<+%EB`XSR=5?Z;Xpmgf$rNWwO>$iCqT1DPT2txAJ?&ZU9o0Mfp9cf>47iBmXgLcQ;Rmpn>*t zi*LOiYXE*Y9CA3(Vqe9TFvG%t?C)SK7jT`S-HI|Jw@aCU%%=!~xYmYn_B0p-n*-rm zm~+bgKVn>`pZ&F{Zjdx86(I>@<^BWL_VC!Oq2{7R47vFRIK0$?~#lDEW1)ZHg z%^*U-vSN7C<}Gxyu36o0mNia1D8Q4MbbMOicy&(AfpX-HHJN&nm7Km!i3!Go7JMiH z@6@q~3z~aYK6SJF`z}EVQpW{hF{wq>v>5a$mo_jXwYu5wtR{5N>Zbi|+jkwwx@Ch} z4j^q#2D*Oq>Y%*|<%QcWJRalFuob`k?W^~@Q)_?hj{5xlJ=lT-cExPrC}@10O_rbJ zpCszeKPbQ~SN*EpK9M_DHgOf7`+xv{>>5aXA61VDz?5?eM?bcD&am~`UH#;O$HQRrXyN(iKPwydC$W_cDw8)?AeVCz>B!b?PKHst-i>E! zr+yzP#hK@sKbtdA@l1B%bYraLn@3jqcSgFeS%rjY|7>tv^T9Sa0{g553K!zgb;11s z`c5oiqCqR@zDoh;n?V3T+8mHqtiOAV9NS*TSKgL?;3qQ@YatTHs^wEek2v|OPV!Gg z{Vb%-1z`(mJu$Y>0Mh=(cIlociNZ4#lak=lrRcd9QWe81pyCt{LwY9sxSy^4VJ$uX zc7#|ac$1j6a+;iUfw5EOP%|ts7exO28TsN4-tYWv#j@hS=@ta0*g?}wBVK!c?_H`Q z7*{dvNv57^b6i(_IO*H(nv>dhCiUN?O9+(_Muth`O*;9Xe!~$Sn*%AdEYvJ^5C;gm zdT#gMc0bf$zie8W_)q=pf7~~bOt~P>*sk8W1}O4|Hj}@Z7C0hILM*I~JRkl$074A& z^iV(0MW9n4^2WXQr$QU>bcuhXlXx6w|HY&4Y_R-{2fy!scW{Tp8t?0^F(I}`Wv3+7+At4|ot9~i+%`4! z$&pI$_LrKKvdm(cg=sDI!Gp(|0L&ID#w9^JFrqUJ^l`<%1||7mMmhiDeygdLEBlKa z!mykAQTJ_y&%ax2UiEWUqaSyVaE>+Ij}2>$4S-j*hk>!2q%aI za=NjkvzHDH3>a>wwpeK9m97k}I9bq4#%PZD%Lh=U^M3+5v$69RaBVf2K6 zGJtj!I!`P*Z5XjuV zNmc7^U_|Ln-^^IV!uwPG3)QwH<iK{xq@Ocg_z|_1t^oG1`k!%?M>-sNAI3e)|D0->AvHcUO5=qaNL*5~7ZQ&{Vx7 z21-G52gOGRM6A)nPhGYBl2*{gV11kNGR6E`m+Y2Eep|Mc>2_~Kxkk9Nz~u)+zuSZ3 z?%w>HZ4JE4n!98z6=x^<#`~Hf)3y=3|#R(h-G6% zH{nq1RM_7?V^$|d){G?U_{On`g9SGegMD*lcZUk3bUT-L?t49Ts?r5*j-;3W#d!Ea z|5*;d4s`B7{r%F2yu_OeC0h{!_MCvR^C&g_u{nS8RDQZz`I!!N+S0#NXZT431iQbA z+NrkMhE&ZdQ(b>ZDGp>Dk=g__=SI)~Kq@B@yjIUae+@L%rrzQZCQ3&0 z=87unCFQZ)lkngAuUB5`x#YRw#4zIq?wxn8c@dz}m6>bimz?l)w-S`_=AcJ13CcGa z=Xf1OrSfbtTZMKsNBFw8KGBfzmD(*a(l!4=vUc3F3A}S>{j-3z@|{g<63g@-t<2^0 zuLzt_GDJ^=2Iv$-=+e*oK^eukY!Lk{{Ktb#3K9pwCVAIu4YJ?`Wy8z;gS+i&xa^=wT=|C;y({r=Yg*42bFe`EZt{do-H#)cUZeXq zmvd{sej2{VFFhPo(0Oru6m(Idpr|HDdGVff!9(+hQCP?+ASrX^-`}*bMs9a#-NSZ% zRZyjY%_{uZm8uQqD%C-6uo^kv571TzQ0~5Prcf1Qo(lT&;~Ij?Ey6kAipcy9;Pzp+ ziTqT3HDdKVnfSd9!L{h=H{19Z@4Q{P6igd>dSBYc{R|0x{(G175c0@yGwia2gam?D zi3sjN@9VZO&@0GLVS2(IMT)4>YYEjHhFZlx&fLFxnZ?m8f!*D0Z9*NNsa7NGIK!Rq zIFEhW7Wm4tSR%jP#s73S8K@V@O`9T?X95U zX!YcCxNgjKR18BQ*)nRZ*+P@N{Hp)LF~YvU!^h)VMG=}`|GXRgqk~3NvT0G|BrX?g~uS&1toyTf98IT z)ibPn&J2+4;(#tyt5X=w3qSm&?FKxrU>!ZNcKiywZWxG&!Ktop&@}8(H8`q5>nlc) zT7^0-X!t_V&^e@GM;Y=Sdy0i5s(!~8msFhF_5}FtnuU!hKuP5Hh1!j_%kpKFH_u0&830dhMBE2aMSO?$)uV# zW3?cs;_U9L3h^G5!JRo`2huB+y*i<%zHZUz+F|p%+B79vP81%nqt88G8jr_qTxz?} zt?n>w^WWYtrQ`gaW4{g(Uz+U$GI1`B^A6#bNwyap)=eon4a1137eG?R^z-Y#C`I0y z;oYsL>&`k@Vi(@FfB>|D!4wEf@BSH<_B2m@g=$W^vqX7?l~`wr!TOTqFf8xa{OdV!xQQ1qknH!vD)y3u+T=evOmQ)2XnQ2K z_X(-#t1bz<7!XYZZbu9w3oo3c2cT^QC+TKXbwD+oq{*c9r@JqJe4fpvX<&dSZY)hA zdf_2^kbF2ja%u*Vw~U~TdKq-H+o9hwm?`_u--I4*TQ0&qSsP#O>d*9E9rF%oJ`}^U zyLRupjD6h!RQav5=uULsTj_9U|6wIU8NP1Z8CQ;UXi3HByk$YUTArT6d|;OzPQl#B z{Eby8cZk6Rz$B&YyE5IGYTu4Oe5Zmnf%M6udYG)7Nb8TeVr^juwDC{+@cRh#iz~l1 zTR=3Su^OX`eCU{SC<|~5UHowklioXBQY!3Xpu0G8i(($Bs#J=%i#;U20^$QM(^Dh7 z<4@(Lp!+x;0YQ+#kC16z9sF%NSUKvX`WlLCC_=t4TBkUxuQYSEXpxwzZX?2@*%)U; zG$JKYX2e98MEuC4+CWt0g{r|5Lduor`0FT25&#wesxea#BWg1R``s3p_ooL7n?QJJ z-6cfrzEau#6N^~IE49?Lpb=p*!sEt$Vt7&`4a}BHY-ZkbIv+~fm^FYF?q4WADaC7I zEKqR2ZQbw4j-?Pub03w*eGYnPL)QY^&n;4zW*ic9Q$B|?vV*Q~0s*6Z3rYX_zvUZt z!MTYsc_P7iAoRiI-*@S+8|ti854pZ12dbC(#caxznFykV{^M*lFTG~b2*!KTRmet_Ri%=OZ~hf;3O!TO(eX1 zHsg0Z?Y4HkS~|8lLW@8n{DO|##zsi`i<@d8pM^fLoj@e)(ihhq^+hR;*&a|NMftmc_vPj{>Quw{9+9Is0tl?-QZEZGr&Y8Lz+^{an! z>Vx%=(UWN;F9S3S2ea4tSFu@hw9bY(N3DW{;dqs2Mik!m%V%n4Vc(v~?{eZ?8dvzb z>OqgsW~O)!f8iT{u@^E{=I5`vMkD%c*4reRsk+OIJC=p}JVos8?!NgGsYz@^0pM`g zY6Z80P)Ou%0|X8ecL$hYc$ZQ4544-LiG6?RtbpC6m@*(bG;84T$G?J=5e;+CWEKaiD?b z5jM4(l&x7w$JwUg)xKshjNWqBv{Zj>8uS1P{19%z2m{j_Ni1~9#M|e zx|4E-DjL4PJ2ZanQ+G3U)obYS=OA{*UVV;^kM%sgvSx~4E3l+qOMTz}Xeg0$10+HyJHABlf(sv0h1F))ku zK%ti7B$Bzw0V(kOBa6TxkpWcd@$uA);aJ1@IQm}DDTOrJ;36;NscPQu%eg|=zvLAp z(~ldlL$+dH^Oc|&X4|;~V-pGYw{U8oGU`0@L9qg$jX?oC6JfrEJ5qIfGU>Qi?$!e3 zKbIqBNr#}Jlr9`@(87-g`h}LSKLR^adXqSa?d2H& zl(T}aW6}1^pvm|_ZF^}&W}}QbY>kj&yaXn zc!ojeSrp`d*1#!msd{i!4+KFnwviI_W;--0Wns>|rT(eWckr^+5u!q{H{;iDl&A^c zPG5T}+r2}Ao2>H-ki*r|`tj_ey05g&G9+eg&tB5mg+3awQS(5I*>|=vMj&#>Yy7t0 zr}$cri$6qH>dtg7&mG(zLk-Q5Pt|M47x`s;fuO}ybLY8}k5v)^;JFElNwzy$XVwrU zv;wtE(netpxHic!_aGdppH(c`j@9@xDy)Xw!&1(&nPMaO*xrIiXgVw^U%A*L>)Wl! zzfw_Fy=a(d_aNxGE3oWQ1R3f;&(AQWOchAf5zO|83bj^1WOETpU7Nsqx%WA@I~is_ zcxoZUx3uFjY^>AMF+bbd;wqp>`h8k&KH{O(C*xYDSA46^v;VoZda0 zJD;SSB^vc0!s0(&rD8}hrd@CdE;z#!-UEoold9Vsb5W;`7-)t057+|+6GOMD0nQu)lk%4|i@mvCj=S7(11#SG#1D z?z_>OSY5tumwM6p@q(qeUYlHg+~XYph(lgx=4Mwer1{HJu^#JBuF>8Q6EYuuHU14%hcB5Id20ej3CV zBJUW<9%2pJxa=LPqWwEhdpcT&e+`T~%Un@6BY{D*Yy_9niU$4<~C1nW+^0(eWw&-)MPv>XP)od1uzHEBQ}r6oU&`ci_3vyR6KX@Ek@wkp%pl zCGn4YZ8U`ZKS7&e9J5*xk$MP-luvfENv%#|U-8e&DuN@1{9h}P+P+72#a{a}RBn7a zbJ->C{Q2`8@JCs=Ra*Wj8Jc1gj)o&$&`gG79QX2*Z}_u4I)d{efYw9Z!h&7xey`45 z7K;R^KNkGZO6Hj1f7%oY_8|J=c6`+iBUol;m`b-~R676ZW~NWH;C`OjJ4G-90eVuu zP&v?jXQ`lr=EJC(yBP+WKO{|WA1GOLfpQLm;dm5>fkGr54G1(LJ;Kc@vf$s$g7^sP z1MVY;(0k#QRT2a8aYgU+UX~XnUCeaTEgSywvxmf`lKJ$OhR>_Bbv?yMBzIKng7L*V zvw;;E%N5kioP0A}2RtB%(?4Vc38v2JhV@OP!ufoyyF%H z&dU8mBa-<~^8_$@rl zierd!mr5v8m4G#Iem2if?)688RQ99IO;NNrv}v*!TJls3b@I!ki(}8m4hk5sMOdxe zIJEOS9MgyNp`Ac_lf$M7%(Ot%8(UQCfuYV~AlItgG(Tz{iv>_rvrnj9LM*V*5DDGiCFFNazLHy>e^`9UH}eug^6^;S zTt;GQpFxuHqUrEuWxMGlmBXNSMvKZ}-QH(LTe0U%g#XrKw;Hh4%xBH{8BV~?@CVAL zrMq2_Ht8nPntwgB{=Yas1eYHx#FrFSmoFWBjI(02j7_ZsS_7Li=;Xwng!6!HP1?2n~zkvFUN=73O~sIxeUm^x(BrKd9XMn8`lN`ZM<{)7~ug#ZQS;D~eJ zl(z%$rh0gR(%?nVvi&O7B;#54UsSk*?3RBut)L3BJPYB{^`ctO-ne7VuQltI7)mti zvZpYy)i6xdeaipPq_n-qiuu^i7m$Va>4`~AUhey)fM9b8m7I4pbYDz$HFBR8-`FR& zv2R~qf~oqtvdR4cLZ(c$5*yfs9aH%x)nE4%x-K>8sfIP2qt&6e^;v|en4*rdWOLVN zDsFU2c7|n+(<$nf^$RVPuBUcNgmy;W6f;R$SzS}Ox})IBHGF9J8jrEdaV}F|$Sa{6 zxE18Ugn?U1=uaz9bX>=#`6lQAJW0w<^}BLknS7=Tj7kw*NzCLSRo{m3K!ZuQE44lB zJ1(8}iuS`tsCPi-`Mnde@)vGp>Yq0wX;-yL&>{L}Jvh0%ven$6AQ3y7c~J`exav*n z+5i!rfD$3!ELs3KvlJfvY;n8?X>z)ba!)LoE$goPNWIX+ahh?)lljHxY0b>N9~WzL zEvnrigUVUvh`%Iw(vAM3zd!MoR245Ab$=?C__<2eZwo zeQo_2QBgjU&zkuVEq_>zKNS+aHmP0*5;{d|OQD7Cfq^Sp#I~&Oprx#;w-hgxb`%6A zKF^fLYj5n38pgzond(>9>%}i{a1o|VOlZnaQzWm3<(F%nkX`I~jEQhR6jBpm6_G)V zlldv(6L;DhS)T;z6lsyhI01B25qBIlLsn`0(G1C{l;>AUj+7?$c@*1e>923P=?H21cV>KsYWEkh}syo9> zhi)7Y?7OK4TnPpd+6JnJ7eADs+VoCSR7;#Yp{mU0nN2O}!OrxK#!3ZJRT|8c&I;XS z$?^jDSZ>zNWGCFZPpvVx`#||j4c-ni#@LSg$$Qw{beFYQ;lYy_TNKj&$NKEPu{V29v zbKl6a;-m&6Z^vL1v-A?J@1q5OgF}2jOxZi_XI4=eZ~T5t>Kwvb0-HS`6rcX7_Z?Wi z#U>lDG^QZnjjCG$Fmq{#u>v#Jg`jA7$)9?||Jbh{Ne2ZU`fHl3sg`XFMK*LLPWhUL zj+^9OI&C{QQO*@An5m{P(eamD(lnLq1q340Pp>k)*}2vvrI#aI*rfMCECXWjyw5lX zq{jssh}Tf!lW&&O$EZ7+Rq!C~SUtRQ;v*-4BLHWVK+tbRh#|3TKx;pfrseYzr zwmjZTnElu)EsZ^yz``=I-DdSP?w0je%LIvT-UpmhIrB=4KGv#q{Mq-6=P>K)_M>zC zkw-QA&k!t@dpcu^E~t}zD3~~mEOo(azkU7)M;X;r4myLg2yrcV`;Y8Q##hG+3UcK> z=AshTdLXalAoYdYyNo~-$>{j-qYzNVFS_61rVL=^)5+cC-tLN~5)S$YOST4YT+~|> zn;3$SC_{@dKFj(0cE(ekZ|s-!d{iz zlRK+msz+SJCe8J86?Sty!Wl1c_5I+Iri}G$SM5OAKo0%&QD zDrR6rziNuwefF2l4iPzpuU9r_f6=gi;#RLwsCH@rbN$Tb6mN)DR+p7w;)6Nme9_T& zVwoVvTIEJKZBuHRPKVOgAAo$m5mdqY>~m; z%ri;-dFr}+MiY51Y3}SsiL!Up<$0Y^!bkd6-}S2-+eZ5e+oUr-DbBQ8cfU%l2tsk5 z!3SBo9nM9^r<9Geh!2UHM)Ww=@z2ycWOlr^K}N-!*6!UK!K^mm`jTkx`B<2G>(lm# zZZBSLy4Cl^s!)t4w_2^8=ZTl0ej*P(KSx$;@%fe3Z#xXIsTG;6y2}DTK4hl6@1Az> zm}t6<_PD|M<=48)^KVGDvjeD37DJ9o1(I^RmQGj2;|6)RUu1X1WPBytqhY9%p7QCP zV^a_#wM;(dJ9{aEh;n`e@hy%Wr{g#~bx-G6&(C#g3}LbxSNtWNOvPm!)%$t_lnqhe zjZQ0Wzz)6^xLEMn>bvv==p$Lo<7Fy0Z|{vE_1v!!XnHl8Q_*;2Iz0)qafRz8-}(bg4a1;t?1sQ6yf_3lE?PW^KUxy z9tU8kf|SqTOatVA<{E@v{~ms}cAMu`-~wVM0^g4@=~?qswOo(>wVm2x@T^1hmeRw6 z)t;|oihA$JN_8JLD*#ezGfzeAaym}|f4?c^81FD%8R&4MeDvFA-pp$Q9yQOYy)#{E znx6p76M8zV#}S*Bd2eXhFY3-(Fo`;#tvqSL)JD&PF2s`;#i0M7rTrGsRLE4eS;u4o zv@-*=(nEJM#v!$RId1}*8Gogo1#B#t%N3OKb#jdq#o&`<(J%7tiUM+Z1Cmspo+=9P zmuBhhjca}Cx(YBYI(6rNpE`)cz+p~9u9gDEHOofHP6%62j5bor{i<8vBV><4Fyk|A z)VI!U&p*^&-3(fsr2OQ_A(n(=MnJJ8@#dl0^ylY#3b(RlaY=RFS~*(Mq;L$gKcikM zl&v3SeS5?XwFp{Gw|RQuQwTx#pwq(ZWe@IO$t@q9PUja5BT@vrbO!W?=kRAQDsJTSAI6@HJx~@Kb@Z z&GO`GtXW++oAgy&MWHO82ji|h!F#!WjELaZS8dcC{7?p5rpQX2*Prd%Hgd@VQ7Xb@ zTkR!`V(TOai=u!PV~hxYfKA8e=dV5-&>J<|8FKSp>ypyh+Ku_=>SNF|A0tA8jd8Qj zsAVQ!Dt3NHLsq5E#Ns=NQZ)nCgR`pWiMAohF_|aw$KH_yyp&rA)6Mmp?nkErb2Fsk znL@IZ5 z{GP7*zMMH6VET?EFqq(d+OhzwM}$D|tD>D5Da~Q3xOK0nyD6{7Ab@gm*>rOPW&sMR z807}@kGdSjret{BBvHcMGutDR;n%8mUxR2e1%%+6cwz!w(Xn>8eWTSI`5W06;S!Qj zpP$cT^y<%HxV89oi_gu<^Y_VTIjQWp-fuoYQ8FLk&NZ&OnekhVfyS)r@I@F3=rzjp z>%bJtGid0o5vskpfq9n^g?>dgEpm<@C2W(CS)yx`#h-d&=H*7Fbdw9w$80?_#%HNB z)9xsg$<86QLsG~fsrqQ5AzT=hWTC|~H@NthAsJ`G{!9l0|!#OzxZ&{LcOa~)Ba=R)Gyapr5QY zwhY)q8Nx#*7QW`ESRZhYH{a+RNST@$aqCfeeYBM`rT;)F%ryOa_w;*EBh}tgg~or} zrLyne<~XY-`gGhGq+)J@qHt?~I%WRDyD}FbAE7n28F<-ap=QTXF~Y=&XWX##bL31I z&+3Eo7wHDpRrz8E5wdQLhJ_4npZ2qo%&`OZxg>T2x-=S*?XnBKvp2jyZjE(c zW!Et9!>@QXXU1Qi4`WtapoX}EqDs;_t!wr{t0bwdrHcW`-OU}7vwF=cH%`lN8&OzX+nq>sjR854hq+@__j>Agn$md zD;f&{!{PiMCcyYG7f^U#5m8U7&XtS9G(T*8Rp&zYegC}oy}#e(nJ3QKXYaMwTAS5^5;MhLMycSGy;`%A%l1yv z^Hwblo`*Ir<3 zt#R}1wRC8FuKm;(5sbIh8UVP`fZIwWAk<1v55Mm!if6aYJ~P_@YUYOai6U#wEo5~M z2}wO@KgW}QQ>}8P8&#bwA^G=p`0R!W{9ZH0Rhe_Yu*vt|)wi_p?V*HHa;DHRMPo0I zYS(9Lj={wXsN54-XO^G|rb%BOA#~RX45Z3E^&$Y#^ATomRRcPeA*sH2@uNXk$+Pg+ z@-Kp!p(bYSIxs-*=6YqQ0QO(8&-?&@g*9pBB27>fE0s7W5;S+$&%CQQWw|sCc^V~6cM&CN6i}SD%cu|=I z0g2)rUoZppEl_IoKm!RRMxC!9y+*A+aa%!YKYzgsfk9li`81Rn z3P4X39EsLM`RVO1XCCkeZnhMKAuBv3?JYskAkjIK?6=wSBsye%PkVLo4^{5f@z_BP z?v<^&$j(o8FDi!Scpw1IK(^0_K^5xVgIe(F=#S(lu1OLNi*k_TpBI=H{cBVK?b7m4 z(R*O=#J<%c=K1H~Ek7%LZvLN*qv&w!#;=V-J4CF^KwxgIMhm2NF*)0=PREG8Z#S3pW>&ef-q8u%9veS5-3o221Yp=P6GwGL^pj z{T-&Qq?s>6-yzIghl3X}^*g&%vogeu0D1xI(8kA)fO*QA0Ys+592e3V4V$P4LJ#sSiz0+|(@OcKbY(dy{3 zzcqAi(%$}hEzD^3Cg&?y`aBDG9DceOD(8z(G{?P~$#VhG@w<3P3ch@X4@a36Ll*X( zT@6a?e~q|s-Tu|11S~C1)yeZ((8Z9YJuX9GDPABRSC$P%{(ov@PLW?%iV;yT|N1{O zzw)(e)zracUROI=;75=K8T`FHt}^2}G<&Pix#Ujab`~@40@m%9a9&+D=z(c-n2GN& ztOKqe_<$X}`-~lrgS5g@W+S?Eg&?dw@AIK8MDP2`ye)$fdRgMnmwwg~8Ve^hn8#}Q zI~?wa#JnYdF7`%GtoSG@-$5SY&ogzMms|%e;3Zl03mTXu5Sst7; z@C;&^7KZeXpc4w%gMhjYh4?Nw0W%u(CVj4z&pv&V^@QPXk6fS0BWToACr|*qp32Wc z9i0=5#k}v@x~-MM`U`Msy06cJxc9pddv5WOkp4DSt%ERHTm|a3C z{eey(oG0I~004-HU&!S<(436VuXJBf02ACz>h2rvU-bG0fKzUq%QvFw7vCsomhAuP zjPoTjYA}R9`L(l?EOwP@vlKL4m2Gn3pm+xjIRpqoFf{4{FiT|=ovL?YTiyZNR`*et zrfzux7DXWHHoGQ;Y0#ei%C|KB@;UqW_A7?`fripfVUb;0XLhvHxuu05-yoEpxLCq( z7F6PrWXtlC|M|4S>i`aY_w%UcX9gG$@dEgfq=-vR9q~9WT{9KpP4&};nj^cV{=n#l zg-1^S{C}}*>(K4Pb1eBtNB11z8}9#n2tV5Y`4H8hz2FXF36qNiu*rI^4q=~w79j-Y zPPA4TKgXX%N16{ZZFlIZS#cJk)0 zrS#8E2IZ?vMk#QJh<8ZX@69)^>ED|_S+PQ!f9tNK>vuwMJQ2dLC-1hXhi#TVlU_DC&3*OnAOF4v)4x~fbU0nenufgSI>1OJz!s#x3oKco z_7%q}nba&rg6KUe$n&LS)K#71_yHM`1PKX8O@;8OltEI1k_q)ZSC z_F;o=fkx5sVRux3B7`jXjMaw{QMd8ZZEOGgSHJ$)*_=(8@;e~+0-A6x(M$6$_quHe zX?{F@HuKu~o#YIJIkUfk-0^-Hv;avGWES)esxa`+(3_B%9spO9EPy#~SmzPG{CzjS zt{WZ~Os_=vcNn5K_hyM!=P{ohvM1wI&{_Kl;4_&~ znDhHZum4<5CMtV*^XMTf1JjF`^w*D+uW*p6`tvBo+<5)ECHf3)d=K|_y6R&^MK%8i zg#L5d>2M9s_nA}*T522z#(S54dQ`3KR(6ihC;4~CzMF8ndv`Hu&woI_=F@J;>Yh*k zmMWZw4KEWdej)k;#dMMRD*@y2A7EfKNY+QnTrz%qTCRKl!9|>pRYrkWw?1tTNM`gv z)#|V^{OS5<0QI3me{St8t*RyA zqg^w(e4i~`jGkdyh0G6H)xnGb;Ped{(mRY*e0Ls-Ldp#9P6P(pegE+Cl3`hwZC}>2 z%@7@eH~-ubxLEWeai%a<3A3~LT0%4J)nY1aM8X!!)p*SwS0 zRu6`8n0>PSUdR!J>Um5juv#x^3Et-K7Xkgg-c2?Ew5k!-JV&p2>7;X*xOeQ}Zg81A z`Kx14l$t`VppJzTV9>EJTm{y>C*ZaZgQ;ESw7fcPYYF%K{<@fI1&$9~;T%a8_uUuv zj%)%pN$pqqXLi}~rtz!asK3$&w_$b_LHHqdT(%e^dh5@}WxGdAs1S4B;V|Tl%chtP zN%=eUXc{PaCx*lZ49zD3j&d*Q6@CGGc~k~7R%oeS2?*|PPMo%Se?7*5DqLQ5llvwk zx3T%BXkX$lq?pf7+~(Ro-ZAp|3Vbt?e5-X@|GL-adE(jgp~s;9_Qa+?d~oqv2mYZK zkPU%b}Liu`7&?>E&=A`Z^%vS?&IywB|7PM zzgD_wqPuwiuTQgCf>RD>2M#zzK+UON?)t+XoLalvy_yDKo%e=u9$^5i9O*w{9C%_0 z1S%!KT1qz<2d^jp0DSfpkmZ(^IE+;E7;rAD-)<$1ym^~shxaEBSQb;=c3o-mx46U| zM{T}7rfm(pcu(=~XEMceMJOalI5~oeh0iyPjh5v=cT2fP#tA4(3qgk1EqgFay_a$E z_J={>_`eKzrRp_}(zsBmeFQjJxEQG_$G#+*b!ZU*ri+K3gik{+(1>RQKxd9a?^_LV z;G)jM`)5-^TY!{!79R_7HSpUujH^5^=@&Z}%sGG-ApeIY&~5UPv+aEw*;+LYSccWg z*M8z*h6*UQ33;N`@Tl;sp;8W_f8DW7R|q49hE~m&$Sq_(xBvd(cE@*t=g`jocda%j zfY*v)u1mk}`d<5u{f}=iJ?G-B8Ho<6fXck*yY_iQ>X|ozKqQv~s5Lm%IU1#_u{c9{ zXb@w77G?ybvCF5--jl)NruDelM%5LqUs~vJ*17*bzY)nOCak~@oTtoz8G8H}0JC-> zK$$$W!bj2TAoY{u*f0pz1x-@2fge#Ay~Mz=OL&DJzz?ZRZ3Bzf;o(nqE8lqYivcUK zwYlxf#G{#5wf{E!uUIw;lX*J-f={pKaA#@0W096e`wPgOkQphPK<+wcw7I37s(7j9 z^e`K|h*qED62~#yLs=79QhjCQi7g)D5QQK&h9~^CB7t4o&q6A$t7UD8nVpx6 zs=Ph7RXTq~&41sWpqnL;cU{W!Mr1yavFEAPIs#_8V-285OWXD5#P49c8yu^5bT~qv z)15$5*RnI(YNRS53HKTtV=;*W+74G&LZVMEnHahI<_vah0*vv%W!Iw-d^+;Rh56h<3@RJ?rl5zamv2=4noQSYdvp2n zjix_wIhf`qnj+?y=viaSfbON)6!4?g7Uyc7~x zhmn%@_0eizn1}F%h)bB6_4XREYOucn+*TG0nAPNuNbDQ==NX!la9SQv ze9mvF>;jq9cFqEmxP8IxY#qJi%N|sV+n}%E_`;Bo(f3Lc%);(n7v`dVq1g4WLfM)} zPjOsAQeIhru(sNuU*Uc)gYf*M7vLccf+>iFYguofU4`=$yuzvUT7!byAOL?B9%Icw zK9T^<3GoC%o~Bz7?aCnN+h=Z7&gSyDGhXgaN$%2SHUj15F zW<1gMgy}{|-wF^kzeDF(#U@}#kAS?%j@5r#t1l0l@gQ#7cVW+;wfG5tMYFdN*u_18 zqa_XozTnInbxFPDfzN4Rp6kpLod_KdiQ*20yDK9jfWTsIkKLaH)*9^9Ykt`Lip3A3 z%uj}6akSa!XuW}b-@Qs$Xs~s8)Za~ z-H`DBXjJ9r0#i`(`7VQ{<+WF{`Hfc`q}h9(iG20jNB2qiomaxfN=@o;mU`bsLDD#7 z9W#Z|p)b+#ajqi9{yQ(noEu12YwX>zd_d%b22GZspMO>#xA7q z${nwV97zj&+jpF;OkCRrJjX$h&6tgpI+a4BHKD<%ytlHtkZF71ed~cmIo1hfn|mkU zT64cXp{rC30Let^(dXGCe=yEvVd^yz$@54FPJa-bp{756r-)>h@S|C7Wx`!&{I3r_^2tDNjFaX z=x!acGpc@tBbAOWWd9NZbv%2o@XogA_w`(eC3aohXHzLEVvUh)_i#tRPa zJ{itQX{PlV6jGf0HSN+gvN*7rTqRn`9 za^v&nqJ91hfhx3$@?+Un`M# z;f7yZz5U@<3x9m!c9Ml%(wmM2E1qa2DEbDig8lBw#0!g(==`!g5dZF592)! zS)bDR%ST$EeEfcHo+#~G&N5&NL@>y0XBvucEneq;vQECCpJ{afAGusc_EU`$baos_ z>>BZl3n!`E8>{%_doxlcs&o}PB6el)VD$B_gpa=1;Z0JM5XC{ZMvfUlr6iLKz!_e; zQibrmkyOXxhNlF!TY9JO=GY#|)N~R7QZAqhEVmY)7N{#hfC;@hEu@aS?N?8qf~cjm zs<3Q5%X|C7i&oL5&SM{ij_5AU0N}^_$m;c&%6T(%r|-p(G?hUrqw8p@@MAFeX7s#T zTIrg#7Z;JgQh@0Q*0{~Q=Hp8=Qe5GA1A z5wb!@S-YH1_({I55LKX2b>B~Au7t~AW)zt^JW)y;&a@p(G>BMKt*A{mJZ)ui9lrq% zmmMAh4$FxYvq&T2*$5m?^^KpsH9%S7FjXJMpOjdjBu;i}Ng3S>IEFy@JCHOG(T?-J zDkN>b;XKh2?pf$8@@kBVX5~Y6HB_oPWTj2H%*1a8pI!%i9tT57YF%)wmp+@4)xPg$ zg@@SAE1zSO2Knym@uoc!dMw;4laC;116?=-$KYY4iq3z3Ow+tXoQV?(^GWJ$$ex#R zhMjvxe~_+Yd(kFoVBq~>Y6USTF6O=TnH}huAJu`a(VI#gZ!{W=`~>~k1#7PpJ?Wpm zxk6$21qJUAhx%UE;yd167 z)Er55sp(u>T!#lG%`?gRmAQNt81}DaO3#W&yq3(#kfm4jmc#`EjKW8mTw>Zy6cu1O zaWNlfcOTzA(q`MCr3mE=e46=BNf(3`*ekx%s?BD65v?25Y1YDI0^_$CDRFQ!O$^;) z4%nX(5@Wk9@%}RrHSybx4zj7{r)o!_$Z?B89Is!-x#xYND*Qd)SdPFBomkp@G`&DF zl^*I4v(81^kqI1X?{a|nyvoZ)sCLS%Ix}mRbJkT89&EIFFFzLKg{tg$>jlqlJP=ej zCWdRyK*=D`C2FRpeBgx+OkSw|l~PgKt0yr7`pWd(D3V4e%!}q~L$F{KS&o z@o+I}uXIWOP1iy0&gKFx@W?I}%hDsM_0`?qNE_VND=T&Xmw#%aU4~yttL?u@D_d8q z%*yw|zba7$+8a`_NqWp+ESpz{Xr@jknv56xSEhB}lm7aze%}$>5HaC)Om0Dnz~8y| zF94?56x^Q_-x4Q^@?S1MS;GI+O}~l_P6P193u*he{$%2RiXN#P@ckd+-EsS$Ocwf= zU<+_Z>LvA<&;RcoJ*1_;{wSEVz5Z9S{QCmY_TY|MbaXpk{dpVzzSr3T9Gq(AvnZ8> zBe#b``K@h_UkLNw5>`oQ%To?G*|`H%y33$=_;gO`ai*LnD1khIKGy1v$ibWxNLa;B znVoClQkTy^ZaoFmB$v`7uoDbGwLkM&RwQHy0#-ma0c?Gnh5(HIB3{K}F=fEtcquQ>s*a;Z;9dRe}9uZQ7$k5BbN_k z-M*mVPuk3DSXPj0Sl)B-R#x;6mr-zRlW9ZP#SiP1!H*3ofu}x|Ko5~~BV9o+!00vk zK4{(BLDd>y7^plNPk6I50i1!C0Puv!j#vh|)IuQQ>iN7sO(G3&0Feq*Z_Px7M>fdD zefkSbuT+A(P52~fGBRQd$ll!qSnK&1R;<+LcPRdpI3}q&VAVOj{pnQX(%$a5CTu4@ znA65%H4-3_DAZ-&-eh&@LHtV@87`H|fD=r%?#I`N>Ytz+Pqqjl4R+nH!=UlroRwcE85vs!xE3KY#GB<7~v+il6P`Whu- zAU3uf6w=N}F3KDDc4)PxO}0#AB|$+Yjzw?GzUHJC^$<0mENhjhlSqpiU2cP0HDx-) zK+f2_dWD%g%R_GD-#0!_Zq%96o$2%gN5mP;2~vsCN%UG?=z0zL;EfdDn?YHEr0lasl4LiK zoH>G#$H5_I4~dSAfN{%$0}O+0D&p2mSw0j3RoA?fFUTSdN4A5zt{*n+H%76pHA3d} z!ysq02SraQ@VYk0)&H~%&U4R%QoDf;aK_99G`{dtsUvkc!(2{ke$%=X3J} zv(qZ(ffKw}R5>VZbD_*br_$5mS1C7oD_8&f&JF-|O8avSm{JT*Bl+7j09-qoB5mH)X?I^o#*O2BKc>s>^I%LbJx82VS@xuV~YSc%!O-D`9G@vZ!Tt7}}W7Uv`n|Wd*>z{@s))HPyjxWD{WM!V1z~US}#4`|= zn`Bio*HG+B99sa&W+^t?^Y&4o=X`b^Ad;4RRtVMMIVU3Q$0J1j10Oc$-kMXzqt5pTSA+ z#&^DYM1B66^SIzJV)tAFE4&&ssRjYtI)Tg-P&1xDb^7Yi$EvFF=}`(o*I*J*caS~TuS@xo7WgN;1B0rFmSzRsPZ zo2L`mB_}auZb*eJQ}jQ+y3~Ds9m32 zE|WZtxp0{cbe5fQc^l{1(AJESVn3QKeQ(lOlY&R7bhSW`3^f*%5sc7`pHS zjlU0%UEj<#DD8;sO(c*J<^c^29ayn<`joH8`bVlk>%gn1^&XK0L8M3o>|$qK(F3DVl0LUf zX=etz#qn=F3w`)`!*4R`70i#U3s>_T`cVK>@q*cPUyr>7`TNhHiDqZ28!Gqm15aAz zIgHHb2=_CMIpJmwlfko>hl%eS6(7t-K#16%%;f!Ba8!p`;c6lieNrdyYj87lm!W)F z$DB%LEsHwV;#su)I<+(;2kiG!tzMl9kXGr-Ie5B97Ta0L*p$q^DR#a_ReJnsi?u7! zCtq)`{N8}Sbo+93fYqG*9dtlvz)2k&bUo< zJ0bciN)F(J!!wNHqoGREw-M(Fhok|}(_17noepnY?@?q-5lAC)#%H|$K!VhX?!m(a zkd=4^61)f!n1h*TkaI?x3R7)gmz=^SAZG|h-k6nnSxjWuGa+pGZTY)(Jy-A;2y5kC zN^G>`)OIiv_&B{&7ffa~UdFfNNGRoMz43v>iOLo7b2+^AEDSSX)hy;Ug)D$dL5Y=2 zJ^aEj%-h=(SYCWoseGn(6()$Xw4p7wNmB{GIDV_@X=vQEJZ`MeVf{Re+(3|s7->+i zxxsu`ey)wmIFAevQY#8MO_){$L}lib2hP zS(K|5INJChv*s>bd+4}XFrSdPvOkuyz*c0=^p;Dxj-)A2AbGl@Wd)8&8sTucdUU6a znDw6ckHzBkPTsePxrep(R)pBbOioU3+4y^ca0@@G;S zLFnVXJ;L<^Mgc2GgL4Iu28GNMI*|zCoM}sx=se*+v%TIy;n-ruQZ|!AH`)9k$@-bM zMNg(0ncq6{l0iwE&w-zCESM5dR^%Fr=c-IjPVO-CJw26^dJ07ktCulvjBx49a0)_B zg(Z0*_=Df3!EczFfW8@mAUTN+7fp|_o*;b1`Q^FW{UE|x1i7o zZM�{dx`}p?03G2I-ar^SkS2CZlC8c@7F;A5E}t(E?vT3w~$$lUB3c0xz1F|LHX@ zb5myYz>DlQ@w`*(TLiR1b~~YZEf?=iC3L)$Uni&!;%;9+BT0cqRMQe$20^ z;bL5}pPnSv;k08pB=8-VBTqriki1g+V`hi`U8$n5&N%CnbT80RcRSx~4((lcpYCj1R@xMd|>>Slw`ZjQ5xI3qAPrGwV-H zImOs{xr}&Og%_Ke4rJhgpZ1)N9MY9NHv8$ zn`Zd>gn@LMF#Ct!C`i4QRvWg6Ca3G35NtQ|V?bH-ZUBv|EaisnOmRJplET>(3?Mtk z@dcr7T&JqwBOhVGc!o+L<0MtIRW3yeu`Xf|tI{lhG-wPj1X|hp<+Lm9ggeJ>z6pB*ZG_Z6_Ec_ZwiXgT zqNp7cWGBVJaLupYN2JgXzd`-P4W^9peMFB`P`E@i({{nvLb(&qa6y8Ng-?spht(YB zO?cbF9;@?Ok%&&5v6XOYma(3(XrwviDwZc6b)r|j?8uQa4_^yC6|Tuqs+AfxY}(?3 zppSnk2><~C1>1;7G~EdI&H1WstCyWZBcHqNcOKp|O?qQH|Ft`-^G})jn|?6C0}uhP zn+XWSp|6+z1I>4SHSw9ijhTa5EYNaFnRt z;)lQT<$u5hBq-1}vNG)oGhsVDI{8K`!ZI-{H_qc#;aH47PFf0&ypF3mJL-h5ay}ok zo!6-xk|C4P{PWqGC%~_6wj9SOr!rc|&rD~^#`#2CjV9=d`kqB9P98D@YIGCUJ+QO9Y{^|dei*87-+ z-E&T7d>spnElAq4@xK7dEq7j@;yKUnx9>j+c0JDnoP8q(|zpqmsD``)Z;6_oAV=@Q1 zX#-Kpm_w0HRPXof444N1y6$SZE@nmi9C+C!-Nzn7-6YSi zw0Cs(R>!V1(W-l)FjbN~0O#p_4+wjC7yKRjVQql3!ua6No{5eGYrRmbZ5cyT@ZjT6 z)Bp+#XMm85(&bnqOh&y+xC@0P4Pw>gU%lw*<4Sj042U zky-=002o%5;Mj0yvV{ec`hxGb3<|&ekwI=(z`to_riVMA1v`n)YLR2cyTS@;fn7rf zWSGT-@-EnV00xfr*3na_$Zf=GuOEYUk28fg@Od3vpK1X2X50Tpoo>Jy#=(d^=+Zb; z+UMx7qx1yk(C%HX$#&5^-&#rVU)w`+-=S0-v|m^wkfbh_$g_b`FZO!s?0z5&rg zMq=RPaHj}RN`^tDwl;hWNWrgn*Fe2rqJs4K0^!#X;}ubwCiHH!RbL?+&=UKg+2!ws zfZ8TjHcCFqYVc4oQMJoF8KQUSq$}W+#==yC;ygOlg8}uqr|uBAyxN0N$Brnd4rIh> z_H(5A&Jy=lV~&;(f1T)xCI8=Dc~x2v-`)#TTPcTgnm!%p#W8VT9UTfbPzE`m(?A^o z>oV%9x72m1A2d)qZ^Yg=3Yo$szGlA&;KwC&)I>67@jV&MV06(2{^KC|Dna{GDW|4` z5;Uz)xmv0;+V^q|o@2o((%gsmos*(J?K%WfP2URQS{$>7&)#B52nO{Mt~h2l{Vow-#`t%Q-rnKJnOV6U_oS$G(hD%XFG7nuz6uQ!O_16@m| zsnS~hv`AT)R`F?Am}8IEDqbWTron@1iAnjE(1 zzq#A50dUmh0Z@nUO9*hsxq*X-%TL_i(6qvhHIR^?(Ppc1?Xz1dY5bo(0ibv#kTZQ~ z3ymj{2hF2Cq>LGLr(hvo zwFc1sUJPQ3opMYg)MO~o!~b4~>(8clrg4rzlOv5N&UrjKS~iWCoUS$$ zj*cJ^xN~km={^#Mi#E021x%ZEcQy|D7{OZAh7sH}iqnTry**UHuok3ILnOd54I`Z_kY(ly#4Cvc27Lklo@v>(N5wrY9r_nYkyN zyg64``w4T>rQI0uF{Vo*j9AKVi^eq0<7*HSlAagDMdY=fW#%19q{hX05NH0>ML-gT z<@z9fQi~v2H|Io6D-j!+{eNDTA{9C+-6bI0S-iu>2b2r;U~BT*KfR$re%&xcC0dao z>7ZU6Qq9e4G-Nbcou%O9<+3g@d-KV-*yh>y9KBwLfDm>sZ@!ITxQqAQb$!dl5oSyzM;(kJj4RSo*66778%xw6kX-$_Ws z8JaI2g3k|++^d=r!z+|rI!lhFTqK$`k?%4$lKhFEWr7XydVGo}FOcJ3uR7EH{Ai<~ z$NDEu(0q|{TxY>)Sa1rt#t)+oMY9~Se$EzydbEJOzcNCm#&KU@GK}t}^PT>)0*sOm zRW@0TE>di&H*?v6PdcuP!aQ2+@FqIiPB8#ExBsJG9iQL13%UX-IQ7pAQC2*eo+MO%MWKwHh;Mz)XSC)Y!(W`zUNLWEC zSPm9mrgC+v zdDvJRhmmmF%aZ$Pbp5j9wcgvfW!(=y;uLTWndYX^ru-0OI|Oq8=TXH*iIbOMdAc`4 z>!@}g4McB6M6jRPuJ7lLJ}asqp(ht4emEUJW2C?nlGZe&q@dpoH<`0Un49|P4wlus zTl3>$c(%X3&-*XI(*im3o5}j-Yr?Swmoc0RwH!@8=Q<`RFCPFL`LZTsV`EAxfOpm1)6_8#m?YBn?E zMbzTnSXWav3pQH6%u0OKn-$HhXU1MQ&XV?ofEqyq(?O-sk6(8;<+F)+W=a)3iHc(- zpT9)35}}hSpsNyv%Whg*hnYNPMkCNTEw#dKwN;3ikHZAT)7{jXoN69~KHJJnoXJyF z7P>#XaH7r&AkKAKycY2%*cAL`M{zacRb)|S!0LV02Hhp?Nu-#<7G=r*xx^cM-*_(eLB>FVkWLZMsr&4NvE+ zP`*NW?#xIF4vU3ZK9;E`FhXQq^Va?Nm*3viHa(%&6L?B0*CI#w@XJkAW7m4Z?1*>! z(iO0rB&`O-%V#ccpKcjopOgwnH#L+C2Z_Y-h!)BXb;}xEnZu2aRN**;an79Vu&34q zOli$1!K~3Um*gqz{FR@^&r>^I4Zp`%Eyb%w$j@Gh#YJ!JMerfVL@*Bm{_5-nCqacm z@8fKlKllDG(-Iv6J~x-1iHy;o^!s0oAi5UXCOewMcgr||X5Xnec}VoGfl-0ez{+L7 z!-DY5S;OK@S_YXHnU{e|A*EG#;mKoyHTe3zjGpFm8MzlGX?ZMqQvNZi*?AS;Qv5d6 zG6-dcw5UHVcS-0cer85kay4Vsgi`=eewjYq2;-2`vd6C{keEYIliF2~vnpfMLXXoklk9yXwrOmT^r$n-xztELxjGfD+-DD0*+Y(B*-iF8hY!upTfWZq)11&8>A)m!8EqY{wdXvb| zq?^pj3?(y=o;{$zy*1sQxh{Qp!+@Ne7JVgI(soJ99Q5am+|1J^KxO7Npj8ixI_Lj} z!V3b{PZUsLG^cOFr98;qdo@?n_z(#56v2{k3O}xr8$5W?55^0`CyFeN3SB?#1K{>f zh>str74DMC)XTkRRn1i*9?2k|%6^fOw(nEvxiWg3&aS*t2ef|@bKGg5tl0%J4}Bnc zxV!QhWYmlv$3~b1E;=e-z^QvTu=V6E(-w7KDbQq<^~zv9@*Q-xO^S95 z+Kmpr<#_TGrCY!A*{xDpTV=4SaS-t>QyQk&-(#(8Ta{~Ft|GEhA``BBn>W-ZW|eF9^s*_X-bm^@iel`n7)ATUt=9TE%7C8X2f zxI9_c+3koQQ%|>iqQSKeA;m3*DAeT0Ws_&qlYJfy4IV&vSN?kK_-VnFs+;m84;*_4 z*gSv_luk9qgFy2*eFb8#f3HFa2A_SLiSV^wgv%(L&j^#jADK29M!dK%I93xFm|-;n zc&zq=1*VRpL9Ee_#cOHI@rQ#bQ8$ZsKqe(EILG+dAHoefvK70XR`J?`$k9v%nOKRL zryhZW=PUzYNHo*_*M7+3Ic`{4^N?ttvZS>FwhL*069EE= zOc}HB2VPOJB(Lz&)(M{szQnp`wCE^k!%{03kbk*agvVfk;;; zNB83y-v#-6GnXR7p5|7U|IbRjax*J)0YQUx^TxD+DaE4I{KV=W+4e-0f*mF&i_OJjLMG7CvG>FvbYSm+JVUWdJc)uyo$<;5Hio(Zm z3cyiaa81T&rlnI|5(14NNj9P&#CEKJ@u~?+hngcfYJaE9o6z}1lOR)1!_jG`gmX>TDF*^k3ad z^%~6ER)>0p<`OD*Zx!*2iQvnii3!=u@l(zU^SRuHG z6WvD+bn9fo3#;}CdoP{EQmzt7`bMP;^zKQ3Wx5QLOu&Cm{HE(pXvMkz&i&vrkS2V+ zbbC{v&9N(^X&&X|siRbM*tAT93H2m%iWh&&dp?on_Lt@5nYP1f>)km^0Ba8pFtt6s zbl6#5V{_3v3TcARMsZ5e1)~Z*^3k1Urkhj=XKox4Z!`qjE%)dK>8AKg^%oChQjjKe zHn`hCsem@o?#xHh{^Fc7O<@WmP>GTGOHsO^=wx-9IaY9Uc zaS%WOqdTEzaL$4*i|QWM1xf0JOuJQNr7^#dBxrgcA@hxuLU^%LmMWI`SouCOJ#V~{ z9=BR|uW8YXuM3fPmftXL_3kcAWsqZ@Cu-koURr6EUY8D;@5DyxnTR_+8yXb1Vk%Aa@Eyy!r&JU`+TMXoovU8bYO+7PSTyo3 zA=1fC=Tm0+EQ9wXtTYX9``mQA&DM3NlmJ|#e;GXKGElq}gC=XQ%)=Yfg)-AhTS#d% zIr`iSN_re-H9{PBI0p56{pwYw0tQxLi}0<@14X9K#vAvMM4GC7a6_DTwY2k%Sh*Qo zVZxdSOOV#{H9jnTx@8CizY_sF=LOi|gxgfHdS*jgBwGF4n z>8PwdDDC~mn=_WAe}-7!wWQ#Im=m{w3LnB6Isjm8Z<* z4+$-TXUVM>2m@#Q7#@iCqKl&P6f|$!3Agv3Ot$(-B`xa{}cV7 zQn*SsB!2nlYE65;gAlJr)=&UtCk%GS;o8yNjVr=K=w=5P?tGUBG z^s?SpkvM?r<&D)KiqFS3-t8Cep~EkXpI1;NT2Kt}=F8q|>V1&+*BT3=X*K|>Y_s2Q zMWp(xv~m_35?Q~cTA6AerS14geMP*Zp7N^Nig?dYZtW!L?7jK^vhR6+p;ejaO&U-{ zX&T79(tqr`W~+g6TiGw`vOb472wV?KHqZU6JKd*>#iTxc1pg0jk0hJ6dKp0~AF$_#CQ+#|8ME_VaLfW1LLI9mBe zFq^3q%S&h{Ei&`YPZ4;3ECWx?5`clP?ASc6c0)#M*uI9C^miCv109+tIHs39q?ybD zG#7AScScoV%;rZY-lLKPo=80$|a(lti9;6InBv^X^{ViA!I?}b^fvu zM~JYPoIv?36;O=as488!{JZ>ZhJ#c~ip}-9n3mH$8G}NHM;ezMW5jre+kAE|=PaA3 zmkNA}6q6WEKYI7wrtNkElCiC#oFL>L z!qKjq^QJnx&5*U##F+{5)rmbB+(tJ^4BSF^lr0#x_g? z)W!geD$U_1IRzi_N7~O|Pk>(06I^^`Zz7OY#FdRQ*CY4$^0bHoOKiDYXdqR1K1!T9>mBPYZ>9H0f@=ZXY{wvd1)3#i&M&Xh?k$AvuoC~J2#_<<#R zIgw>zFlI$Pr!CmhUil@1&T5+LE}(0bz5WhtnD>zh#SSC=-fo6~;&+EIQU4zB%L!=} zZBY)HUbGna0zrKoYM6PD^Y*V+s@{QAY=0iLI`}*;s+d>JDzQ!i@dt zpf^Q~s+Q~c?v`&osgHp_DDPKk^9ZpHg9UZp%?!$%)3=nNnXdfH(Kz$=oDhw%iqifR zuuMJooE|3@xvY#=S8hr6cwObVp_qb$weN?M*1sO4c&!1LyOFyW`ktyd0juY{QzQn= z|81h(v)Y=C+`w(>lw>#p&Ifb#+&mQ5jYD?k>(6rSX-A|`++Mu`9A2Ni?F9-Y2O7n9 zCF~gCr&jF=3@J2d{sgVSD7#obJu|>=aMx36IAn78e7`fI1PSJT6x}I`2+?K^;u@cU zpzVdLb?*IKOF?46v4C=#*XsiaoSt7ORp`;p7z-9SM;kOnVeB&LeIwi#KGIuf8~7}avu<=-i{$*&$K6ydm{SH z+YpE$98ZK#ftLO|@T;4u3MXY0b++3A-HdC-6Ww!?_A*;%8pFo@9D!A#Fi^Kdhnxs@ zk@UWF*;^j!UB8y<`i;l2EkY)XJe5mSIlI8cVdC=`qnPb%|JSbcE0KX)LsKG5_iDKv z3O)DRwyL#&0=T-rsAdiLCAp>s)+W&*0oV1+$>*sfuHilW2^Bwy^@ATF64+U5Ii?t98PfxoqiioqEgV$;$h{sxj94U}}CEI(hx4 zeMy`+1zzfE{uBLFNuj=t5V`NR8K8KtP9XiJ7pA*XALvhf@^|n`9xF**u?{>rd9`xv zYkinYu~Kbx&QE-k7ETN+-Om~eC;x3d$t z7x(s-2KK8$NH|UgZ>Y3=tRi2tB=#mDFwvc)_D@32n?W z!sl&3&D+@c_(lcPx{@brRF0119hc3syy*w#y;erDCssgQ3y8%FI-Ny8Kv$-5$pJUA zeFfCZ%K*dmWU2%*KgJ;9xR3I9?l#m;^`QGT+W0VlS{&l36HwYeg(U$8vRa3;Ly{X0 zSe;-@#^U2PUv$d}oGqWLCq}%K0yC!{^f@grWb7p!Y~18T-d%Ste8%k_qrsn8psO@a z^pnr{b5$>KSGpXiz>5$v?vZb)^<5gH1eNEULH$W~f8F(CON5n8hxd>w&TW7Zk*)|N zHck3{6t994clRR_*U~62tLPD@MIV@?47&HIphI?Wz=vnrSp1$XtvXG<6eMN&6e|#o zYlBz>x-K<>YC-?|OBY;6b4*Va4VH55P9{5B)y70y^s@@!#oej8WnY+zS>!RO38+32 zz<=S=|B{aI*;0)D^X*hpSv!2TLm(3#^}{38kUd%!A&3p4W;%q*k6^hJ@i|%zSh(5O z*Qr~i2A$XrYl1-zzPJ(?d%uln7ow^`Hno)c~IU>rU_{8*eH zb-POSy&xOH7=8#cSXFF?Uy zhw@u}?e8R*YE$dCQC;UnH-V51jp@ATuwG4-#G2C7T41yEgwC>CmOAtmW+uU;(qXvR zML;^v0G-lFfI+nUpSI3AEXr?v_cIJJbV_$4NJ>d}sf47`Eg>Z^^dKOe1|Ud?gn~#* zcY~BlHwYskj37v#HGA*x{`ouS_=ne}mooFt`_5X=dY=3K+`-hQ8o@04awEZH~G!a^4X^O z->^_x>*Mo3qYdwLbj)2wUxrPFFESPWtO(Lsa`kWz92zn6O1kmBwg0Xl!uu9{(PTsZ zL2F2ZT+@o#oMliGtgj(#xb{?MdoGUB#I&vUVyEB+i!`chA6`D&Fev}=GQintMzJy< zs~ef!=)2uWOg;v+_mp@9@G(C;qM>CNU$y%%)QXjZwy~d^gBk_(1$#$9gn)z$V)9&_ z?jtFKjfAuk>~Mcwzl^a!!L1yLBT)i8q`n?=B6-PSFt&E49Bt%_SAIxl21!{FL>Cz3 zZ{~F1688VLZZBe9UY5TUR&Pti!;(6ts9F9q6Im609AeS<_+5mlVp3=n-31;s&5ir( zf*mrL9Kr_am_o`dtzP)_>K%ti)7E{Wr+AT7(4=oxIh5HSm&Nc2yB?6a%VB?nJsP89 znt3kDgP@+y!&6F@hd!naQ5Jf9s)k34gYwa4rgY99tTpUGD&>AE; zoaQ}fAbrYRg=-g{W0hV8dNZgWP^b_Y8M1ZJG`^jItgG49xjPVt8HzuN?@2w>IVl$6 zw6-_u{;Oe4CQ+P;_z*EexqEN|hLDY+zsz8lP*O{Hg(WnEWj4+-IKAR!S8va6WKI}$ zuCArL>eHlO0X^~5!Lc2_NYW+!P&tjQ&SNUq*u6c|ZO)w_SUbs6JuJUU#nDmSvfn*{ zF-Ms(vZV}kjRTA)S9s&3tu*N1UndZPfYffnYnFy0c+GkMb~2nC7s`jJbNj`?^VPt8 zu}BQNi6Q1TrW3?0hn1iaN6hCxl$ru|KiAct+REfF64wQ8x=d-VIVA2j+in&{ zENU3ZSAB`gc8r)Ju6xkh=I}9T9D~n6h>3O{!E*H8?;Y`$PUNwA!uefiBsn12+9_> znVgU=JMw^^am2(n)}axDS?;n>H{ltw>H%Of#SLEGWgUly*cbd%8jZl23ee?d?RlD- zXl*Y_C-L5mB19Bl)*QiwP+_hC^1&ah!Q`Y^y-x`}c#kWk3B@Fw+|JQ1)`-siyJKyp zx5gzOo3#cv=xlYig_xR|K2TbY{bnUG)p0@~pX^In$NXf9T(DnK&@cAo+Ic-%m9 zn%#o|9imgZ-5nFMNIBF>3n>Fl3Kps|6g_PNAr$h1FnK_j^b*t;|B%!JH08W68fjVP zOL5eaN)G-p&#m^L!}Ig*`&PjwU`tlzz8#A#mp7s!f6${tEgRJQ2MZDlDFIHQcy-V| zI*&o6V@^fk<|g2{wta737q1E{5HUUS=ai_a_)u=L&2ZL?c_&>Vtg?WH$vypfJtxzl zeEF|Rae;}k9LuX3U#o=$ zJgvPxIe05{ZhZ3ReOI5-5#Kf)szcC9U0M9&Q{L<0Ia80wv$KO%d<9eQ7Oh-i8)d^W zJF(SjHY`EJ`#0gtPDxTa8*&d3`pz;GF%Y@oTp?`7{mT{TF9t&iB}JSZ&CYDZGg7G) zEmr#%pHPZVN%@GMFz0ZO&|t;TX1O$rKp3;k_Pi4C4v{Pp@3KF2_1h29(JABc6_Yu- zeFbLaYp|#2%L@GDLdsV!c=bEOuiHc^Dyy^I|JQS&$WL@AHAM%W3OnrQbdq6kru7{T zcZw$r*e!V@%!j5j?YAuN-t3+(qnxD2Zb3}xd(KCGc>2M2BXcKJ5$?*uYNx_Nd}zA4 zm^Iu8L&>62=OcZ!{^i~MQ)wwO$z~}}DtS&sN;F2vDCB++0J*t#Cyk;mXPj6Vi{yMW zmPP~;a&v6$fMWL`_9$3k-xls6ntQ`K!l~MkT`myO-_;vMld=TmDZ>|_N1@I7wnqXr zB;{#>>wd_1GLfR9K2WxfcD71_PcdXeCP|(wQ?dRXp4?t+LTzitrgJX-Rn=fvs4bTr zI&TUXvp+pWq;}qi4marL(VQBUTK#J-WuOeyAKJIO6khkcp}2KRP92OkA7&YPrSTW< z|LRTuaCLmKFbdkx%!iXZ=62s(d7UhD{Ax9lL%v429GQRl!ez|%m=d0CYV+pxgB|l@ z|B>(RA8Nk|ngwX_qM**%b1_6`1c8T$HCGY<(&b2_m}eC^ z0@`wZaPfj%B!g4LbeSlL0MQ|wg=3%-&;jO)824Zd+@U}Rfzy}FlX@VUfS(MD<=R*N zvwqWN=+%kMy@B2=AI49wcB$+n4;qj77$BJABd>CpHEP(L zM^l$$_AEFFVhW-6V0MkJRD;Qt6Q2cB;KqiQ!SZq|^9b3pEm`))*L-Lt1SgebftOp* z@@{L^{!{c!JHuyx@=dEXXiJ4JR!MY-M;`gXpsbfXO$K`!lIBjZ739~rqR`~2ZHwyJ z?fnzt`xOiQW#Fd5A98nR?C~A0&;`r?VP0drk>lCg7NF1eZx3qtS4^+xmQU*9vtdrV z6~`*;I@85Y;~mq~OM#I^rm%gq;0ghqxO9PJ)0SI$IAxQ^LWp2y+@~b2TeCjbCPpm9 ztrq7O=dy8y@OJ!>iF}g1x0n_Oxa?vNQC?3ye&FjY^rj|0w8zJmfHhkjd3>E|$E}90 zER>*6}kSfx$(x zooqmCFdkNpUc99s>AcoAnkmbg`1$52mN}XTm-2?{gW1b@k}Qpc3h8#-u^~+!7H(>f zSfb9a@M}G#-3Q<>DQ(pe+IOE+3DL3EVi3mg}rMu|+Jh#-{oc(>Q&*k$-_ zUPP8uj=&E-Yq9`&O8tr1^!+}D2!8^YqjR*6Bf^CaZ<}e9lUX!vd0(s@UkZCd4wYYO zmEH_t<$UfcBCA+K+KiJZZGQtRfcE%+&Mv3^0yym2dbPtCPl}X^5Mxqtfld^b+GtfI1l*?e7Z;Q+7^e< z-n`9i&5FT&d{WK$BxTTet6eVMWsUglbLH2azGa%>>@%|gi?|2IIl?!?B;r8$A(k7$ zOmnmC;TP`BZ!ky1(4G1e(i3~|_2nuMR?Zo4Od)2;JhpWx>bC3i!7q;YWy%tgg}508 z$TL`7=A>5QJAKL0&n=MS@jgeAW$BM(Js5|T`c*+jTqhM<^`cfHxF za(ltC=7qR2;-*b@<)Axw{O;rE1lYedTHh=9;MAFQ;#S=&?V7EhYxhB>H$pvi6n~3y z=bm2zp{boYGSo2+*+;KiwnrS=M{j>=#&F1yv-jL|n?Gk%wPL~aU{r@;l4mSo0PDluW{nzWv&D}%B3l!^o&du#A_s3zf?^#O<75?XT3aW-S?Lr zC1`r8if!-1A?8%(V~|~}U2|pjgXTEx>vtdrpDEoBFwV^yznFRFq3-_U_%GE*3RVEd z1;3cn78$5ZEenb3{M2epou_fjPjtG+wWHCg!?x-21VEM&kM;AXQgM=QBk2mai|UNt zT#UMG^4ci|qWdW*%t9WiA3GJd($y9&{e=nyoGN$l2?YdQP6X-ZTW@{Rr%8M>PE}I` z5#>ANYo7zVr%8Nl6_m`YQ9kv74HMveqi?O-M5~_w8A-pIZJ?b z=n9C2L)MxdR@!Vtw8HHcDmP?Y7STR~TzZ>Cq-^c#Au^}xOfB4ZUez}mAqe@-bsCQt z9@TeT5Y@k}5EuV0iyD{kEiS>q&fWa47NB=jB<>WecAn;@%Yq2*Y;lTMZDWa=8pGGh zRl2Vi1y`51!W1ghc6kk6u4$=~-h6}0`mT?Tp>~Y@%j_Cdl|PPhP2Zucon5>PGx#Ow zyZ4E>pq%M99FWjlF^HZlJZ(L_QNoahB&@-NXGeSzcf%cA5>j7UaR2XKI(UriiS_m~ zUKxS*Vm*w?1qpRR;#6pCAqXsC*AKu|4(CzvmquDYF}w&dVB1 zZ|&Rnt^#Rb!Nq&m&W!VJ9397BE*$qNXbxEQ^$lrD-h6Zp0%$EMXO7|LuJ1x{khreV z&{C>UToO7-oXmGkeLliJHC#pI41|c>->u-ne+9E;*Ux8fAnzIRb#LmYU(&L>FQ_(Q2Xg4y#+&BJ>z zb~2UINQh{%5&}L_pe@;G&H@MdJ60CVhrA#-MWsEvVKsrRrvlymIYXoi6ZC-BgP_MR zZ2^o*3pvU1cx<`m5D1(464XaFDHdIg6m)0FtjFe`}K@f)la0lKFII6}I1S&EyYb1=#1LwmifPT*g zSG^G@`dhpgUd9XVXMLvWKc`Xl$BEOHH!U_I!BpxL)R=CR=<*1&AS7TJ7 z$3}H{%Wnsz=m}cLBTH2yuuqtXML zG}f~e3k%kSlmiC{0huD4Cr1<#+s1YK45Fyx!FYW3NQnv*Fre){yFH`V)y0rGm7ao$WCOz$SU=z@)!6t6#Zb2MfMgEdP~E zv%R#NPCU;J3=|$cM`Ahkv2UZi)CH@WJHh4s7#V>YA;vYGpL`-1Bb*#R@QjTn+Fw11 zv`b6iqDFa9?*hisr+MBbiYg_|1`@G)N6jG`@q5%}M1DOqZ zJupzNYTZ>?r5o9_QRK6!M;whoL*CtskpLHPxbjW!zveRl1O1HI?#;%|kEE81Rbwee zN~s(XIdRwcU;g-d87Ve_>lrhZqM%5n?s!Kwh&D%_q6*@D>698WTVWF+6QM!tT&Vrx zXiF4dPxB`hFPNm00u`4ANkKQ3yRhZR8IG6}E(@+Oh3%G#R=C2*SA8k@jB_rr?QpSh zhI zs|p$X>nbp)w@}QH!phNL%`^6%W{t8f&ECU!?jekgz-1X6&r=Kssrvu#|ALWC<~rW9 z`(Jb9e@SOEG8Khb1S1r#<{iOK76n57uF0VCY|WTg00hMWa8Tw5sHB7s%_3C|?&dxI zF_AyzS$;!ob4v4h=ZU1Yh<$p`m!%ySozVd~oT{K4>8^njT^Hk1pSRK?jetGF(_19* z-}e%}4psr3r1FMeUth~e&IRpRID^*+4LrkRF`s`W9yFt!erYl+|H1qu?M{~8JKw!l z*N@wdqd(nUC(lP`KUq?z4%5` zFWHABKzH=g^5mt?U3fVz>r}LhnQ6UXS{Vf#-rO4&+|qi$CY3n*!scayUv=R@V9bBN zF)3-_$ujW1FFN&Z;Mw+!N861`$Isj|B7HY~EL+~)lbP;K)Y*;WmzWL5E4s#z>O>Pjyu_W zQfk~9oOQT)f$qBxkex@y9~WVMhvUUy>t_L`I4k?Px{IC8Tcc8I_@$<3TSA~udUdbZ z($;md`5^+EkXm*YI9PUM1MTbH)-gv7h*hOqh0c7d>e^PCc!tM}U|lGP_TL7mojR}( znu1(bi#u|n)}SsJ2h8&=<~ziSaS3f;zs$GshQO`0KDUCj-!bQBw%@-_7r4Q8!KDH7KGbzC_(4;PWa zr>DE@;h2gaD3a_J^t}ZT3j91qMdXyxo!%`GS{!0ic`6mcTkF+D zELlGr2e5v=ToSy-$xg&A9IiBuH6 zyO7*4CB23Fc>0t0^T6N*Nfdo=}O(;zaFX3EZ@?8H*N<-(GRwm(1yKG(gleaMGPA^O; zpMxKR7O*5}1~5Ot=QMe5N6qg6wZX9fQi1uSll|PV%2I0x(~ih!!ZSVXNj(9(Pz=+F zLD(7@l;1uJ^)^c{v$CXGcE1F%kjj1PC`T|JD+9Qt@*I0mp1A|nUwJP_N}^zy``-uE zRU^ebnvVw3kD0O>F^0X#X~n9O_&)i|`gFi&r~Kix1F1bZxSGiWy2V1{#>aM9(g)hx z^8qbP-u){-D+@ICJbbr^9lq$dCsgGG&6car-9M-Sw3#Z*k=rHJNyeqOIw{TXt8BY zu`d7+vL(-vu$&Aa)V-BVuqe?Uk1YlSv&$r!IP~GlTYHuGc%f+JJDH+Awc$?j0SUN) z*<#oP!p(X}rBrq`<-NWpY}wTYSaxp`(>Ci9&%5oowD}UtpthTrmh8OKfLCvKj%2+6 z{?o*5NnuS|zPzqLSpA92Xm53QgZQjsShEv^>HvlkNyd0wtv5$?uv8COcwvW{*{?(Fw1E-*7_+AqpixLDgufYEBC zBjy|hA(o_mWx5+=LXQLrJj${FD6QYZ@2kFs^w{@JMP~reT?i%%Wt6DX9OJl6r>QaY zMlGJc(Vpv2GG~wMFHilt5IA!4-ONRf06KeaYo+Ybv>ns!?zNe-^8-Bhk?gG9)p(i* z=vAKSqg@8Kp_kttJqB9!>A@E=z#%I;_)?I`-J`QRQDPdnvMW5V{LCl!yBALnJi%B_#Q?V60D%5X6(olFlRL%1DS)RDV3~Pp* z$N&gM(D7?n?`S-Bu3Pl)JN^8Ynm4(3(oZ0Y1&N7g9N@mIbfRn|2u;3b?=CuEk zgc?|Yy_Mjzp0T3GLSypI@2Sy>M&G^4+1j(>WS6retDT0;q`I}FrtXf#nuqCTpB~AS zDTc#_cRU#6P9ZYeW$9o|wfK>jjvMB_n;@p%uz5Sje93R;k2u>H>?tj2jv!IW@(yj5 z8g4 zd3?_Hn7n?)ED{-D3!9a^$g*1{_I%gEd35C~oIky3#mA=v*c)sr{XlyDaAH>)k zAGj%Fod{WSE0T~hdg5o}4&7ZIw--R1Atcry6zFzx<(L&>j(Mt4+EIch%nBd%@}I!m zSjiA;$B2o26ghkB)HU53kcfO7pFS4IOi;ThED*_ca5qSiAAITH!}&@T7Rb01Ytq0n zHbr7mF6NufE-0_%@D&H8Cwb9$iDSl(d!(Y{aLWcvaZ9{<$Ae0K(6lcB-Lo73ulkMm zQiHj2c)P4M(955u8Jql5dako!z9-$JiKYKI!liiX<&tUrDCi|(1s zD06<6Q_e|EBHg`daA?O(&;GvsF}E^VzOlE_cg_)HJ-FOLkuQSGgm}N74SRC{L0$`- z=kJ&TopJC25xvN8(}&AH2&Yo}BNIh8UrY7%1aK*m?n7eWf} z)?_(GH|Cvyxtwu%8NbM4BYfY`Iz}uv@^Hdw@|t_TLXK4pgrtGFzDI}t(C_KzkP7!n zh!7`&L@!n{S*)NYmnjcVRh@xh^9;=3uv!x2fB%K4OGyQ#M*`Jg)RGf79pS=!^9ciR z7E#v)9K;=3rt^ALUE}v_X7W^IbDdb1&Jy1ae9(-D-2G$)HNkFi{QO||>%Bd(EmZ2m zXTJ#MN2OaVn(FE|83UaI=EANbK3FsrKJwB1W2;_B1kdkcfI(~`yDFve3^YBl+R1IB zp)8886;w7=h}Uj#0g8h{{l2lXn)EYV!zwd8cBrOoD4l~n=X^@FVWglpO9hOPLSm3R zTTeYy!>}behmsI#;I@5mqw#+YbkqL881cQUVX5)A z1^|;Z0OB;CUpo}%n0}?sU7=w%Fq*~k%L~&O$4KvTD}~WG>JQIz>bb-WQajSb{5f&) z>Dx78*k-8F{oR8xbh=IU`J9mxFaij6jAwa#6%wCsfsjC_SGMR;GkrmspRC z{Dqgtkxh|eCxCo*e82aL1Z(<>Gdcw>xb2UAI+0VY5~nhvBm`TgWQ|?Ic!CJ*47EPG z6_rR?(bq)xc|ZHbb)&%m`4E)ALHqeihn?&pLkrX+?enr17h^RL?~>Gnx0@=qo3;w zBF9GmEwxsEWT8?wP*MHTUMkVZNoaZ#2z5vJSHG$7GzZw5e&#I`{g`BQ0U-YW zwY3_9+u~rPwD6Y;_8-}`$iG%DwynQAH2+@KSW7V-jrVy!mo};3+>Tn4%hJ^v-f0ts zIy|MZC8M7|_-Q>+wos<1PLVTu*>;VUk8B|Ai8yNnM-oqio+#Cug}=4dU^sx;sVs9l zuJ*3V-5nzccBL~!i!;9cv@tH$I3n@}j5&W6=SkOhW&<^8kMJ2bCwb|}ZVvLNG)Ic! zR0>p4DRw40p>ZL}r*3bTc<$MWCe~a5;FqVvHDvCNur_7NodXckNgQIXzH6}0z{_#w z;K%Ttm{+MiSG8JC0-!@)e9QZ)a+e<8pZ76nEgm~Hm{APt`C-GgadbA!pHVyOV{_1p83#y8WDs&VL?nML&$E@R6F&j{rbrBfjo7x#C-Gx0QKOJG8Ss zHGJv+!R+J5VQu5jfqfH7LWBS_VhPMP7?r7cbjb^iaTjg!lgFp#Q29cf55}2Or z>FSzhmGQS{+vgkyRT@4kI^npv zn4JhD@yd{Gzj7YeiV6XjdlWGhoaF)WFckq7MF*0q*A!Vu^neJr=l*>H4g-NRNV>Ki zlx^glSH<)1{y90`XZ!R1xl^@=3ul%lzn)GUhmM4dTs4k-*$%s$lHRQB8w^1{2qL$c z4t?ZqC6oBg;uS~(*qCd4uIgbb^xY>`kv#>@i506TgQa!YtNGaQjsNK}JGVR4gT;9= zbm6ha`OJAt@_A_YaqCx(CvLk{F?}?u!AC6YmnYlg3TOJ=qf=_l+j8VA=PfZ)SNygY zU&s|KnbBxnjo?6=?xVfA5|le<;I^^4?DGZZw9iI2 z=muOez;*gBn0(*Of)wQYX+bVuKrjRyDEWxAxW$KXCIQ!!*S}Ugb`eC=tbqg=(p4p?!@B_TR)nnGuc|?Y!zrDVyle=Srq*wzz);Rw=)#n^TIy{`5zSN=H3Gy^KF}! zpFm1O71^EisO|V%aJc9NG)_9f8b9`RH5v=5pECuj^{6>HFF{I^mneCu^tdJ}2Bkb} z5t>Y${U#!A6AND>#^C*q?^r(9O9FAcr)9vrGunZ#h?VN~b6H<098?Rg?N@pA3%+eNs zu7r*{t~q(9bvV1K(KdJ55k_TKT-5moK#v4zMj58SNQ55LbRK+sEz3^`S3$&vAZ`8e znAk_qexLj4qFTZN;)H$$4AOeBJn}*y}esfF#_Q znqvgSKCbfkL;Y+-d4HaUxZ4yF%Nz`vo7cISfqV<@WU18{Z(VNjS8dTPLsdsO;|C2O zH0x;)EyxGS_V&dW^Eah@?JRK%#pfO;wcD?myijGIViqGwRnK>$If`;vOUt4cX8&o;@$+U8ty zJJ~XKO$s=lz;Ul7v+2Qy!7$ZKaM`$SgW@NcYX}wT<}!n9JYRjOl7}x)Y((&v-De;s zB>_Nv-lj+lWXXIpf4sYplS;M+05MVBTGJ&)vu0KHT3U=2=XZ=UfbmVhyj~b+o^vy# zeH^nvo=jn)OU^SXc4S&FCP^Y;++i;*%)xmvB3NtvWAm@Uv^;J3)FF_C`KBiNkG}Aq zBanu|?@-qNzS2K4l;f55nK{2FXqY^eQX0uPX3v;)XSi}mw=hmy1dYoA&Ke4zLLY6? zRBukhCyS0TiN~xW6^G}*lS%-c2FokqxXP`BmWMxEDe*wgqz)UD=k;R)HUpk)Pvy;w zli1{xkO3JM@c2>4b+_CIZ9EN^)pPxgU)0|PTGFPgR0Aq`DLkqlRwHBLbgn)efxZK- zvU@&sMeQiD_PR-bVF)usx zTjFOnA$NM*5AsDiI_8B1Mbt8DNAEPZD+OnofRFJ^Z>c^eCyLx>Vl@)yIrxjFU>?A^ zKB@#aBs~fj`v3%p-tclAx!)bW0HoHEpPN9Ujcn2FObU=Hc3oj3U)o-9|Jmjqh=Hl1 z<-i>#^jUZlx%q;^1HZ?wBz#llpJlI|T9q|+ksABpYW8_hC+CVGHTOGdfSt7il;Q=q zFE3EyEc0j;^4x4nbYIvtw8zp8cOXBtdhjI=`CJSCYRBkrs@8ii5AQ#?@Fy>Ar4Ltq zDHrIn zPh(T68&Z}lYe@;>$*{_91VTI~w#VFBAp- zJQKyXn*K#-PEK=ONQ~u%Fe?2rJM{F27hu$1+v#C>1EX}A1@Z3pg5P_9bhPV{6{jwG zS=VR?87%C?!)l_(vPf-BgY{2&t1sOILN!{HZD)l=JZ8&&Yzwk@vj_But*7>t58kXcgvpgKFf3{;vxesF&2S2KoHLvUzNNr}uknT>A zxGWTyT$6L~Fka=OFuXB9eeLa1iAb8%04BK3ilQy_S-Ul8cl ziE?+duLobCf+-dHd?JP}`6$Qh&(KgQNA}^#Po`NVrW%b=dAcpUDwUo}Aq~+XUhKgN z&ZQ$?t^MbK+`McQ8`1VL@~-VuYw1HZ{7JCb7{%oH0WpI4bJBqZ3aQ+JLCv(%Mz!DL zb>Gg5e97h3w=mGIx4p(#8sm8sTGvZ$d1KQbvzKwO1yUTpe+hnH)E3|$FCh4o*p`dZ zYAiMQJx3xu8&!QKzVXuUFCxwj2XK@Zs1@L&d7-9{ z$?%RGW6AM8vwk*|TgTC#l8;b$u?IG-8}F~JhMTgI#x%ENdKUKU=bgrqs`+7JT&IiF zUTYuD_FgY~H*Fg|t7f5U{hLPm*Ifl_Trv%>*qs_1`^E~ul)T-S}w%_>&<-lN1f zEw}>Ta|e6qeR-E}Xl$=9aQ1K{o-?oj#nQi{{qOpJLYT@t_}g z zl0uYc^9ZKzMG~>%r_K7uq1dwA*On+$N%;&!OBqvGKr7S`o^7A|D%yTF{oBpf)VJ}m zanGDw%q-^;wiFy*EX|%9#^$8;*8N$zQo6|d70Yv}UX#MPrg-E!Q-}j|$*%hyA^P^b zBH(p|feq)A_fCQwYqkT*$_J`?oOcz@=HBWVy_u3Q-g^GaNWRYM%UKGmk7DzTha+Qu zF2az+g{01A!dFxK%apr3)xDVF0LM`F)6)p-2eKmSL1ISN+as=9yl5-;Fi;(JO6aqV ziGmZt2cxo7N7=-*pL`ZNn2~8_$e+wrQXLJ}=suZOj*W0yzEN)TQq^Pof+76|4>)ds zyVhI{R?{FSH1n2w+cz5lhP`oDj=*wt)0;O|PdwDlM@Gn>UEN$QbP816t89x!INa%u zT|)Wl{@6%vWkPTDy7VS9QlV+$Id)E57YjZ;w(S08S!jFmx=Mdn^vr<_!j*WTI(nI3 z^opayz}qO-WYXltb*&HGFAOG{HAu%xN-t)QW!AMte|F1hNft=(J$vqXD_>8>2RCjcM0Ere?55Z#U)+D5qS@waHn@aCL8zZPe|)4 z`ekx0Pf6)Xu-o17XZAW*YVYsc5MgA6>RZJ!&K35tjXxEBDPlzbiRke5?CUNq)laP!* zmvsqyt1*~N`}QU2VTyn9n9xO$x5TL}spi z>N*t3)%y3RqKU1}502F8rA~D=ZP&-o4o>DOC{MO9Rm6KZ>&HP_Ji2ceAligs>*8+V z+uQs@Zv_m5Uq9X!epB<$t_1$6AEw~&n@*mUl&O!pC3&K&?oLx}2fjYS+GKed_kKTD zGdOten!HXjrZ1YXqyC?>JiG7)8CVTB%wNH@|9Ln6x>cBy7CK3hq6N(imA?F+*TMWf z=1%%x?xc_4XDHXdzoMANz<<_Pga#;-5y?o#uzz0U-+cq{rvz#2G*qH=`Udj9FY?ci zwr=JC8*8(MVv@o?Mbv*@OB1`75z}(W*6~sN=SBYMMX(DmVpj7-4%WWhe>Ermen~r$ zaLz!xkwWRbe_rI@CrHfu-^0BBJ@S+_-T&vZMWVrFi)>CX>izx0{`JZU{+RcF4DUz( tXJz{9vNKe`WoP(2B;oyk-@gpj6`?WRXP(C7*iR7fOH1vpYB|8_{2$1jOnm?V literal 0 HcmV?d00001 diff --git a/_docs/docs/source/_static/images/histogram_example_0.png b/_docs/docs/source/_static/images/histogram_example_0.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8301363678d43fb36f795ec59f86c18897b992 GIT binary patch literal 14056 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 literal 0 HcmV?d00001 diff --git a/_docs/docs/source/_static/images/histogram_example_1.png b/_docs/docs/source/_static/images/histogram_example_1.png new file mode 100644 index 0000000000000000000000000000000000000000..062dfdbb9829f3032b4c1afd55fefc61a08b5d56 GIT binary patch literal 11387 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 G+kXRhHtTNy literal 0 HcmV?d00001 diff --git a/_docs/docs/source/_static/images/missing_value_matrix_example_0.png b/_docs/docs/source/_static/images/missing_value_matrix_example_0.png new file mode 100644 index 0000000000000000000000000000000000000000..21799cddfe73821d7ed15fe29b805df8f2e1879a GIT binary patch literal 37730 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 literal 0 HcmV?d00001 diff --git a/_docs/docs/source/add_new_model_to_data_labeler.nblink b/_docs/docs/source/add_new_model_to_data_labeler.nblink new file mode 100644 index 000000000..4c5fe646a --- /dev/null +++ b/_docs/docs/source/add_new_model_to_data_labeler.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/add_new_model_to_data_labeler.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/column_name_labeler_example.nblink b/_docs/docs/source/column_name_labeler_example.nblink new file mode 100644 index 000000000..c39e674fb --- /dev/null +++ b/_docs/docs/source/column_name_labeler_example.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/column_name_labeler.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/conf.py b/_docs/docs/source/conf.py new file mode 100644 index 000000000..80168effd --- /dev/null +++ b/_docs/docs/source/conf.py @@ -0,0 +1,84 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +import re + +sys.path.insert(0, os.path.abspath(f'../../../')) + +# -- Project information ----------------------------------------------------- + +project = 'Data Profiler' +copyright = '2024, Jeremy Goodsitt, Austin Walters, Anh Truong, Grant Eden, and Chris Wallace' +author = 'Jeremy Goodsitt, Austin Walters, Anh Truong, Grant Eden, and Chris Wallace' + +# The full version, including alpha/beta/rc tags +# release = '21.01.20' +from dataprofiler import __version__ as version # noqa F401 + + +version_clip = re.search(r'\s*([\d.]+)', version).group(1) +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.napoleon', + 'sphinx.ext.intersphinx', + 'nbsphinx', + 'nbsphinx_link', +] + +# Don't execute the notebook cells when generating the documentation +# This can be configured on a per notebook basis as well +# See: https://nbsphinx.readthedocs.io/en/0.2.15/never-execute.html#Explicitly-Dis-/ +nbsphinx_execute = "never" +nbsphinx_prolog = """ +`View this notebook on GitHub `_ +""" + +autoclass_content = 'both' +autodoc_default_options = { + 'members': True, + 'member-order': 'bysource', + 'undoc-members': True, + 'exclude-members': '__weakref__', + 'inherited-members': True, +} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build'] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "furo" +html_title = f"

v{version_clip}
" +html_static_path = ["_static"] +html_css_files = ["custom.css"] +html_favicon = "_static/images/DataProfilerLogoLightTheme.png" +html_theme_options = { + "light_logo": "images/DataProfilerLogoLightThemeLong.png", + "dark_logo": "images/DataProfilerDarkLogoLong.png", +} diff --git a/_docs/docs/source/data_labeling.rst b/_docs/docs/source/data_labeling.rst new file mode 100644 index 000000000..db76fe791 --- /dev/null +++ b/_docs/docs/source/data_labeling.rst @@ -0,0 +1,365 @@ +.. _data_labeling: + +Labeler (Sensitive Data) +************************ + +In this library, the term *data labeling* refers to entity recognition. + +Builtin to the data profiler is a classifier which evaluates the complex data types of the dataset. +For structured data, it determines the complex data type of each column. When +running the data profile, it uses the default data labeling model builtin to the +library. However, the data labeler allows users to train their own data labeler +as well. + +*Data Labels* are determined per cell for structured data (column/row when +the *profiler* is used) or at the character level for unstructured data. This +is a list of the default labels. + +* UNKNOWN +* ADDRESS +* BAN (bank account number, 10-18 digits) +* CREDIT_CARD +* EMAIL_ADDRESS +* UUID +* HASH_OR_KEY (md5, sha1, sha256, random hash, etc.) +* IPV4 +* IPV6 +* MAC_ADDRESS +* PERSON +* PHONE_NUMBER +* SSN +* URL +* US_STATE +* DRIVERS_LICENSE +* DATE +* TIME +* DATETIME +* INTEGER +* FLOAT +* QUANTITY +* ORDINAL + + +Identify Entities in Structured Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Makes predictions and identifying labels: + +.. code-block:: python + + import dataprofiler as dp + + # load data and data labeler + data = dp.Data("your_data.csv") + data_labeler = dp.DataLabeler(labeler_type='structured') + + # make predictions and get labels per cell + predictions = data_labeler.predict(data) + +Identify Entities in Unstructured Data +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Predict which class characters belong to in unstructured text: + +.. code-block:: python + + import dataprofiler as dp + + data_labeler = dp.DataLabeler(labeler_type='unstructured') + + # Example sample string, must be in an array (multiple arrays can be passed) + sample = ["Help\tJohn Macklemore\tneeds\tfood.\tPlease\tCall\t555-301-1234." + "\tHis\tssn\tis\tnot\t334-97-1234. I'm a BAN: 000043219499392912.\n"] + + # Prediction what class each character belongs to + model_predictions = data_labeler.predict( + sample, predict_options=dict(show_confidences=True)) + + # Predictions / confidences are at the character level + final_results = model_predictions["pred"] + final_confidences = model_predictions["conf"] + +It's also possible to change output formats, output similar to a **SpaCy** format: + +.. code-block:: python + + import dataprofiler as dp + + data_labeler = dp.DataLabeler(labeler_type='unstructured', trainable=True) + + # Example sample string, must be in an array (multiple arrays can be passed) + sample = ["Help\tJohn Macklemore\tneeds\tfood.\tPlease\tCall\t555-301-1234." + "\tHis\tssn\tis\tnot\t334-97-1234. I'm a BAN: 000043219499392912.\n"] + + # Set the output to the NER format (start position, end position, label) + data_labeler.set_params( + { 'postprocessor': { 'output_format':'ner', 'use_word_level_argmax':True } } + ) + + results = data_labeler.predict(sample) + + print(results) + +Train a New Data Labeler +~~~~~~~~~~~~~~~~~~~~~~~~ + +Mechanism for training your own data labeler on their own set of structured data +(tabular): + +.. code-block:: python + + import dataprofiler as dp + + # Will need one column with a default label of UNKNOWN + data = dp.Data("your_file.csv") + + data_labeler = dp.train_structured_labeler( + data=data, + save_dirpath="/path/to/save/labeler", + epochs=2 + ) + + data_labeler.save_to_disk("my/save/path") # Saves the data labeler for reuse + +Load an Existing Data Labeler +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Mechanism for loading an existing data_labeler: + +.. code-block:: python + + import dataprofiler as dp + + data_labeler = dp.DataLabeler( + labeler_type='structured', dirpath="/path/to/my/labeler") + + # get information about the parameters/inputs/output formats for the DataLabeler + data_labeler.help() + +Extending a Data Labeler with Transfer Learning +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Extending or changing labels of a data labeler w/ transfer learning: +Note: By default, **a labeler loaded will not be trainable**. In order to load a +trainable DataLabeler, the user must set `trainable=True` or load a labeler +using the `TrainableDataLabeler` class. + +The following illustrates how to change the labels: + +.. code-block:: python + + import dataprofiler as dp + + labels = ['label1', 'label2', ...] # new label set can also be an encoding dict + data = dp.Data("your_file.csv") # contains data with new labels + + # load default structured Data Labeler w/ trainable set to True + data_labeler = dp.DataLabeler(labeler_type='structured', trainable=True) + + # this will use transfer learning to retrain the data labeler on your new + # dataset and labels. + # NOTE: data must be in an acceptable format for the preprocessor to interpret. + # please refer to the preprocessor/model for the expected data format. + # Currently, the DataLabeler cannot take in Tabular data, but requires + # data to be ingested with two columns [X, y] where X is the samples and + # y is the labels. + model_results = data_labeler.fit(x=data['samples'], y=data['labels'], + validation_split=0.2, epochs=2, labels=labels) + + # final_results, final_confidences are a list of results for each epoch + epoch_id = 0 + final_results = model_results[epoch_id]["pred"] + final_confidences = model_results[epoch_id]["conf"] + +The following illustrates how to extend the labels: + +.. code-block:: python + + import dataprofiler as dp + + new_labels = ['label1', 'label2', ...] + data = dp.Data("your_file.csv") # contains data with new labels + + # load default structured Data Labeler w/ trainable set to True + data_labeler = dp.DataLabeler(labeler_type='structured', trainable=True) + + # this will maintain current labels and model weights, but extend the model's + # labels + for label in new_labels: + data_labeler.add_label(label) + + # NOTE: a user can also add a label which maps to the same index as an existing + # label + # data_labeler.add_label(label, same_as='') + + # For a trainable model, the user must then train the model to be able to + # continue using the labeler since the model's graph has likely changed + # NOTE: data must be in an acceptable format for the preprocessor to interpret. + # please refer to the preprocessor/model for the expected data format. + # Currently, the DataLabeler cannot take in Tabular data, but requires + # data to be ingested with two columns [X, y] where X is the samples and + # y is the labels. + model_results = data_labeler.fit(x=data['samples'], y=data['labels'], + validation_split=0.2, epochs=2) + + # final_results, final_confidences are a list of results for each epoch + epoch_id = 0 + final_results = model_results[epoch_id]["pred"] + final_confidences = model_results[epoch_id]["conf"] + + +Changing pipeline parameters: + +.. code-block:: python + + import dataprofiler as dp + + # load default Data Labeler + data_labeler = dp.DataLabeler(labeler_type='structured') + + # change parameters of specific component + data_labeler.preprocessor.set_params({'param1': 'value1'}) + + # change multiple simultaneously. + data_labeler.set_params({ + 'preprocessor': {'param1': 'value1'}, + 'model': {'param2': 'value2'}, + 'postprocessor': {'param3': 'value3'} + }) + + +Build Your Own Data Labeler +=========================== + +The DataLabeler has 3 main components: preprocessor, model, and postprocessor. +To create your own DataLabeler, each one would have to be created or an +existing component can be reused. + +Given a set of the 3 components, you can construct your own DataLabeler: + +.. code-block:: python + from dataprofiler.labelers.base_data_labeler import BaseDataLabeler, \ + TrainableDataLabeler + from dataprofiler.labelers.character_level_cnn_model import CharacterLevelCnnModel + from dataprofiler.labelers.data_processing import \ + StructCharPreprocessor, StructCharPostprocessor + + # load a non-trainable data labeler + model = CharacterLevelCnnModel(...) + preprocessor = StructCharPreprocessor(...) + postprocessor = StructCharPostprocessor(...) + + data_labeler = BaseDataLabeler.load_with_components( + preprocessor=preprocessor, model=model, postprocessor=postprocessor) + + # check for basic compatibility between the processors and the model + data_labeler.check_pipeline() + + + # load trainable data labeler + data_labeler = TrainableDataLabeler.load_with_components( + preprocessor=preprocessor, model=model, postprocessor=postprocessor) + + # check for basic compatibility between the processors and the model + data_labeler.check_pipeline() + +Option for swapping out specific components of an existing labeler. + +.. code-block:: python + + import dataprofiler as dp + from dataprofiler.labelers.character_level_cnn_model import \ + CharacterLevelCnnModel + from dataprofiler.labelers.data_processing import \ + StructCharPreprocessor, StructCharPostprocessor + + model = CharacterLevelCnnModel(...) + preprocessor = StructCharPreprocessor(...) + postprocessor = StructCharPostprocessor(...) + + data_labeler = dp.DataLabeler(labeler_type='structured') + data_labeler.set_preprocessor(preprocessor) + data_labeler.set_model(model) + data_labeler.set_postprocessor(postprocessor) + + # check for basic compatibility between the processors and the model + data_labeler.check_pipeline() + + +Model Component +~~~~~~~~~~~~~~~ + +In order to create your own model component for data labeling, you can utilize +the `BaseModel` class from `dataprofiler.labelers.base_model` and +overriding the abstract class methods. + +Reviewing `CharacterLevelCnnModel` from +`dataprofiler.labelers.character_level_cnn_model` illustrates the functions +which need an override. + +#. `__init__`: specifying default parameters and calling base `__init__` +#. `_validate_parameters`: validating parameters given by user during setting +#. `_need_to_reconstruct_model`: flag for when to reconstruct a model (i.e. + parameters change or labels change require a model reconstruction) +#. `_construct_model`: initial construction of the model given the parameters +#. `_reconstruct_model`: updates model architecture for new label set while + maintaining current model weights +#. `fit`: mechanism for the model to learn given training data +#. `predict`: mechanism for model to make predictions on data +#. `details`: prints a summary of the model construction +#. `save_to_disk`: saves model and model parameters to disk +#. `load_from_disk`: loads model given a path on disk + + +Preprocessor Component +~~~~~~~~~~~~~~~~~~~~~~ + +In order to create your own preprocessor component for data labeling, you can +utilize the `BaseDataPreprocessor` class +from `dataprofiler.labelers.data_processing` and override the abstract class +methods. + +Reviewing `StructCharPreprocessor` from +`dataprofiler.labelers.data_processing` illustrates the functions which +need an override. + +#. `__init__`: passing parameters to the base class and executing any + extraneous calculations to be saved as parameters +#. `_validate_parameters`: validating parameters given by user during + setting +#. `process`: takes in the user data and converts it into an digestible, + iterable format for the model +#. `set_params` (optional): if a parameter requires processing before setting, + a user can override this function to assist with setting the parameter +#. `_save_processor` (optional): if a parameter is not JSON serializable, a + user can override this function to assist in saving the processor and its + parameters +#. `load_from_disk` (optional): if a parameter(s) is not JSON serializable, a + user can override this function to assist in loading the processor + +Postprocessor Component +~~~~~~~~~~~~~~~~~~~~~~~ + +The postprocessor is nearly identical to the preprocessor except it handles +the output of the model for processing. In order to create your own +postprocessor component for data labeling, you can utilize the +`BaseDataPostprocessor` class from `dataprofiler.labelers.data_processing` +and override the abstract class methods. + +Reviewing `StructCharPostprocessor` from +`dataprofiler.labelers.data_processing` illustrates the functions which +need an override. + +#. `__init__`: passing parameters to the base class and executing any + extraneous calculations to be saved as parameters +#. `_validate_parameters`: validating parameters given by user during + setting +#. `process`: takes in the output of the model and processes for output to + the user +#. `set_params` (optional): if a parameter requires processing before setting, + a user can override this function to assist with setting the parameter +#. `_save_processor` (optional): if a parameter is not JSON serializable, a + user can override this function to assist in saving the processor and its + parameters +#. `load_from_disk` (optional): if a parameter(s) is not JSON serializable, a + user can override this function to assist in loading the processor diff --git a/_docs/docs/source/data_reader.nblink b/_docs/docs/source/data_reader.nblink new file mode 100644 index 000000000..8d7215f46 --- /dev/null +++ b/_docs/docs/source/data_reader.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/data_readers.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/data_readers.rst b/_docs/docs/source/data_readers.rst new file mode 100644 index 000000000..877ea56dd --- /dev/null +++ b/_docs/docs/source/data_readers.rst @@ -0,0 +1,184 @@ +.. _data_readers: + +Data Readers +************ + +The `Data` class itself will identify then output one of the following `Data` class types. +Using the data reader is easy, just pass it through the Data object. + +.. code-block:: python + + import dataprofiler as dp + data = dp.Data("your_file.csv") + +The supported file types are: + +* CSV file (or any delimited file) +* JSON object +* Avro file +* Parquet file +* Graph data file +* Text file +* Pandas DataFrame +* A URL that points to one of the supported file types above + +It's also possible to specifically call one of the data classes such as the following command: + +.. code-block:: python + + from dataprofiler.data_readers.csv_data import CSVData + data = CSVData("your_file.csv", options={"delimiter": ","}) + +Additionally any of the data classes can be loaded using a URL: + +.. code-block:: python + + import dataprofiler as dp + data = dp.Data("https://you_website.com/your_file.file", options={"verify_ssl": "True"}) + +Below are descriptions of the various `Data` classes and the available options. + +CSVData +======= + +Data class for loading datasets of type CSV. Can be specified by passing +in memory data or via a file path. Options pertaining the CSV may also +be specified using the options dict parameter. + +`CSVData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* delimiter - Must be a string, for example `"delimiter": ","` +* data_format - Must be a string, possible choices: "dataframe", "records" +* selected_columns - Columns being selected from the entire dataset, must be a + list `["column 1", "ssn"]` +* sample_nrows - Reservoir sampling to sample `"n"` rows out of a total of `"M"` rows. + Specified for how many rows to sample, default None. +* header - Define the header, for example + + * `"header": 'auto'` for auto detection + * `"header": None` for no header + * `"header": ` to specify the header row (0 based index) + +JSONData +======== + +Data class for loading datasets of type JSON. Can be specified by +passing in memory data or via a file path. Options pertaining the JSON +may also be specified using the options dict parameter. JSON data can be +accessed via the "data" property, the "metadata" property, and the +"data_and_metadata" property. + +`JSONData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* data_format - must be a string, choices: "dataframe", "records", "json", "flattened_dataframe" + + * "flattened_dataframe" is best used for JSON structure typically found in data streams that contain + nested lists of dictionaries and a payload. For example: `{"data": [ columns ], "response": 200}` +* selected_keys - columns being selected from the entire dataset, must be a list `["column 1", "ssn"]` +* payload_keys - The dictionary keys for the payload of the JSON, typically called "data" + or "payload". Defaults to ["data", "payload", "response"]. + + +AVROData +======== + +Data class for loading datasets of type AVRO. Can be specified by +passing in memory data or via a file path. Options pertaining the AVRO +may also be specified using the options dict parameter. + +`AVROData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* data_format - must be a string, choices: "dataframe", "records", "avro", "json", "flattened_dataframe" + + * "flattened_dataframe" is best used for AVROs with a JSON structure typically found in data streams that contain + nested lists of dictionaries and a payload. For example: `{"data": [ columns ], "response": 200}` +* selected_keys - columns being selected from the entire dataset, must be a list `["column 1", "ssn"]` + +ParquetData +=========== + +Data class for loading datasets of type PARQUET. Can be specified by +passing in memory data or via a file path. Options pertaining the +PARQUET may also be specified using the options dict parameter. + +`ParquetData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* data_format - must be a string, choices: "dataframe", "records", "json" +* selected_keys - columns being selected from the entire dataset, must be a list `["column 1", "ssn"]` +* sample_nrows - Random sampling to sample `"n"` rows out of a total of `"M"` rows. + Specified for how many rows to sample, default None. + +GraphData +========= + +Data Class for loading datasets of graph data. Currently takes CSV format, +further type formats will be supported. Can be specified by passing +in memory data (NetworkX Graph) or via a file path. Options pertaining the CSV file may also +be specified using the options dict parameter. Loads data from CSV into memory +as a NetworkX Graph. + +`GraphData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* delimiter - must be a string, for example `"delimiter": ","` +* data_format - must be a string, possible choices: "graph", "dataframe", "records" +* header - Define the header, for example + + * `"header": 'auto'` for auto detection + * `"header": None` for no header + * `"header": ` to specify the header row (0 based index) + +TextData +======== + +Data class for loading datasets of type TEXT. Can be specified by +passing in memory data or via a file path. Options pertaining the TEXT +may also be specified using the options dict parameter. + +`TextData(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* data_format: user selected format in which to return data. Currently only supports "text". +* samples_per_line - chunks by which to read in the specified dataset + + +Data Using a URL +================ + +Data class for loading datasets of any type using a URL. Specified by passing in +any valid URL that points to one of the valid data types. Options pertaining the +URL may also be specified using the options dict parameter. + +`Data(input_file_path=None, data=None, options=None)` + +Possible `options`: + +* verify_ssl: must be a boolean string, choices: "True", "False". Set to "True" by default. + +Data Using an AWS S3 URI +======================== + +Data class for loading datasets from AWS S3 URI. Specified by passing in +any valid bucket path that points to one of the valid data types. + +`Data('s3a://my-bucket/file_name.txt')` + +Possible `options`: + +* `storage_options`: must be a dictionary where the keys for boto3 initialization are set + If `storage_options` is provided in `options`, the below variables are retrieved from the dictionary provided. Otherwise, will retrieve from `environment variables `_. + + * `AWS_ACCESS_KEY_ID` + * `AWS_SECRET_ACCESS_KEY` + * `AWS_SESSION_TOKEN` + * `AWS_REGION` (default `us-east-1`) diff --git a/_docs/docs/source/examples.rst b/_docs/docs/source/examples.rst new file mode 100644 index 000000000..3637da6ac --- /dev/null +++ b/_docs/docs/source/examples.rst @@ -0,0 +1,24 @@ +.. _examples: + +Examples +******** + +These examples provide a more in-depth look into the details of the ``Data Profiler`` library. + +Basics +------ + +.. toctree:: + :maxdepth: 0 + + Overview of Data Profiler + Data Reader + Structured Profiler + Unstructured Profiler + Graph Profiler + Labeler + Adding Models to a Labeler Pipeline + Creating a Regex Labeler + Creating a ColumnName Labeler + Merge Profile List + Dataloader with Popmon Reports diff --git a/_docs/docs/source/graph_data_demo.nblink b/_docs/docs/source/graph_data_demo.nblink new file mode 100644 index 000000000..40408c3ae --- /dev/null +++ b/_docs/docs/source/graph_data_demo.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/graph_data_demo.ipynb" +} diff --git a/_docs/docs/source/graphs.rst b/_docs/docs/source/graphs.rst new file mode 100644 index 000000000..23c2d316b --- /dev/null +++ b/_docs/docs/source/graphs.rst @@ -0,0 +1,196 @@ +.. _reports: + +Graphs +****** + +Graph Your Data +=============== + +We can plot some of our data as seaborn histogram plots. Below will demonstrate how to do so and provide examples. + +The following plots are currently available to work directly with your profilers: + + * histogram (numeric columns only) + * missing values matrix + +Below shows how to do so with examples. + +What we need to import +~~~~~~~~~~~~~~~~~~~~~~ +.. code-block:: python + + from dataprofiler.reports import graphs + +The main functions that is used to plot histograms are in graphs. **You will also need the `dataprofiler[reports]` requirement to be installed**: + +.. code-block:: console + + pip install 'dataprofiler[reports]' + +Plotting from a StructuredProfiler class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With a StructuredProfiler class variable, we can specify what columns we want to be plotted, and plot them into histograms. + +.. code-block:: python + + graphs.plot_histograms(profiler, column_names, column_inds) + +These are what the variables mean: + + * **profiler** - StructuredProfiler class variable that contains the data we want + * **columns** - (Optional) The list of IntColumn or FloatColumn *names* we want to specifically plot. If specified, `column_inds` cannot be specified. + * **column_inds** - (Optional) The list of IntColumn or FloatColumn *indexes* we want to specifically plot. If specified, `column_names` cannot be specified. + + +Additionally, we can also plot the missing values matrix for a StructuredProfiler: + +.. code-block:: python + + graphs.plot_missing_values_matrix(profiler, ax, title) + +These are what the variables mean: + + * **profiler** - StructuredProfiler class variable that contains the data we want + * **ax** - (Optional) MatPlotLib Axes to plot the matrix within. + * **title** - (Optional) The title of the axes we want to define. + + +Plotting an individual IntColumn or FloatColumn +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +With a column's Int or Float profile, we can plot their respective histograms. + +.. code-block:: python + + graphs.plot_col_histogram(column, axes, title) + +These are what the variables mean: + + * **column** - The IntColumn or FloatColumn we want to plot + * **axes** - (Optional) The MatPlotLib Axes to plot the histogram within. + * **title** - (Optional) The title of the axes we want to define. + + +Additionally, we can also plot the missing values bargraph for any column profile: + +.. code-block:: python + + graphs.plot_col_missing_values(profiler, ax, title) + +These are what the variables mean: + + * **profiler** - The StructuredColProfiler we want to plot + * **ax** - (Optional) MatPlotLib Axes to plot the matrix within. + * **title** - (Optional) The title of the axes we want to define. + +Examples +~~~~~~~~ + +Histograms +---------- + +1. This example demonstrates how we can take a StructuredProfiler class and plot histograms of the specified columns. + +.. code-block:: python + + import dataprofiler as dp + from dataprofiler.reports import graphs + + + data = [[1, 'a', 1.0], + [2, 'b', 2.2], + [3, 'c', 3.5], + [None, 'd', 10.0]] + profiler = dp.StructuredProfiler(data) + + # This will plot all IntColumn and FloatColumn as histograms (The first and last column). + fig = graphs.plot_histograms(profiler) + fig.show() + + # This will only plot the specified column, 0. + columns_names = [0] + fig = graphs.plot_histograms(profiler, columns_names) + fig.show() + +.. image:: _static/images/histogram_example_0.png + :alt: First Histogram Example Image + +.. image:: _static/images/histogram_example_1.png + :alt: Second Histogram Example Image + +2. This example demonstrates how we can plot a low level profiler. + +.. code-block:: python + + import pandas as pd + + from dataprofiler.profilers import IntColumn + from dataprofiler.reports import graphs + + + data = pd.Series([1, 2, 3], dtype=str) + profiler = IntColumn('example') + profiler.update(data) + + # Plot the axes + ax = graphs.plot_col_histogram(profiler) + + # get and show the figure of the plotted histogram + fig = ax.get_figure() + fig.show() + +.. image:: _static/images/histogram_example_2.png + :alt: Histogram Column Only Example Image + + +Missing Values Matrix +--------------------- + +1. This example demonstrates how we can take a StructuredProfiler class and plot a missing values matrix. + +.. code-block:: python + + import dataprofiler as dp + from dataprofiler.reports import graphs + + + data = pd.DataFrame( + [[None, '', 1.0, '1/2/2021'], + [3, None, 3.5, ''], + [1, None, 1.0, '2/5/2020'], + [None, 1, 10.0, '3/5/2020']], + columns=['integer', 'str', 'float', 'datetime'], + dtype=object + ) + profiler = dp.StructuredProfiler(data) + + # This will plot the missing values matrix for all columns. + fig = graphs.plot_missing_values_matrix(profiler) + fig.show() + +.. image:: _static/images/missing_value_matrix_example_0.png + :alt: Missing Values Matrix Example Image + +2. This example demonstrates how we can plot barchart of a column's missing values. + +.. code-block:: python + + import pandas as pd + + from dataprofiler.profilers.profile_builder import StructuredColProfiler + from dataprofiler.reports import graphs + + + data = pd.Series([1, 2, 3, None, None, 4], name='example', dtype=str) + profiler = StructuredColProfiler(data) + + # Plot the axes, can be a list of multiple columns + ax = graphs.plot_col_missing_values([profiler]) + + # get and show the figure of the plotted histogram + fig = ax.get_figure() + fig.show() + +.. image:: _static/images/missing_value_barchart_example_0.png + :alt: Missing Values Column Only Example Image \ No newline at end of file diff --git a/_docs/docs/source/index.rst b/_docs/docs/source/index.rst new file mode 100644 index 000000000..a20aa5ff0 --- /dev/null +++ b/_docs/docs/source/index.rst @@ -0,0 +1,605 @@ +.. _Data Profiler: + +==================================== +Data Profiler | What's in your data? +==================================== + +Purpose +======= + +The DataProfiler is a Python library designed to make data analysis, monitoring and **sensitive data detection** easy. + +Loading **Data** with a single command, the library automatically formats & loads files into a DataFrame. **Profiling** the Data, the library identifies the schema, statistics, entities and more. Data Profiles can then be used in downstream applications or reports. + +The Data Profiler comes with a cutting edge pre-trained deep learning model, used to efficiently identify **sensitive data** (or **PII**). If customization is needed, it's easy to add new entities to the existing pre-trained model or insert a new pipeline for entity recognition. + +The best part? Getting started only takes a few lines of code (`Example CSV`_): + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + data = Data("your_file.csv") # Auto-Detect & Load: CSV, AVRO, Parquet, JSON, Text + print(data.data.head(5)) # Access data directly via a compatible Pandas DataFrame + + profile = Profiler(data) # Calculate Statistics, Entity Recognition, etc + readable_report = profile.report(report_options={"output_format":"pretty"}) + print(json.dumps(readable_report, indent=4)) + + +To install the full package from pypi: + +.. code-block:: console + + pip install DataProfiler[ml] + +If the ML requirements are too strict (say, you don't want to install tensorflow), you can install a slimmer package. The slimmer package disables the default sensitive data detection / entity recognition (labler) + +Install from pypi: + +.. code-block:: console + + pip install DataProfiler + +If you have suggestions or find a bug, please open an `issue`_. + +Visit the :ref:`API` to explore Data Profiler's terminology. + + +What is a Data Profile? +======================= + +In the case of this library, a data profile is a dictionary containing statistics and predictions about the underlying dataset. There are "global statistics" or `global_stats`, which contain dataset level data and there are "column/row level statistics" or `data_stats` (each column is a new key-value entry). + +The format for a structured profile is below: + +.. code-block:: python + + "global_stats": { + "samples_used": int, + "column_count": int, + "row_count": int, + "row_has_null_ratio": float, + "row_is_null_ratio": float, + "unique_row_ratio": float, + "duplicate_row_count": int, + "file_type": string, + "encoding": string, + "correlation_matrix": list[list[int]], (*) + "chi2_matrix": list[list[float]], + "profile_schema": dict[string, list[int]] + }, + "data_stats": [ + { + "column_name": string, + "data_type": string, + "data_label": string, + "categorical": bool, + "order": string, + "samples": list[str], + "statistics": { + "sample_size": int, + "null_count": int, + "null_types": list[string], + "null_types_index": dict[string, list[int]], + "data_type_representation": dict[string, list[string]], + "min": [null, float], + "max": [null, float], + "sum": float, + "mode": list[float], + "median": float, + "median_absolute_deviation": float, + "mean": float, + "variance": float, + "stddev": float, + "skewness": float, + "kurtosis": float, + "num_zeros": int, + "num_negatives": int, + "histogram": { + "bin_counts": list[int], + "bin_edges": list[float], + }, + "quantiles": { + int: float + }, + "vocab": list[char], + "avg_predictions": dict[string, float], + "data_label_representation": dict[string, float], + "categories": list[str], + "unique_count": int, + "unique_ratio": float, + "categorical_count": dict[string, int], + "gini_impurity": float, + "unalikeability": float, + "precision": { + 'min': int, + 'max': int, + 'mean': float, + 'var': float, + 'std': float, + 'sample_size': int, + 'margin_of_error': float, + 'confidence_level': float + }, + "times": dict[string, float], + "format": string + }, + "null_replication_metrics": { + "class_prior": list[int], + "class_sum": list[list[int]], + "class_mean": list[list[int]] + } + } + ] + +(*) Currently the correlation matrix update is toggled off. It will be reset in a later update. Users can still use it as desired with the is_enable option set to True. + +The format for an unstructured profile is below: + +.. code-block:: python + + "global_stats": { + "samples_used": int, + "empty_line_count": int, + "file_type": string, + "encoding": string, + "memory_size": float, # in MB + }, + "data_stats": { + "data_label": { + "entity_counts": { + "word_level": dict[string, int], + "true_char_level": dict[string, int], + "postprocess_char_level": dict[string, int] + }, + "entity_percentages": { + "word_level": dict[string, float], + "true_char_level": dict[string, float], + "postprocess_char_level": dict[string, float] + }, + "times": dict[string, float] + }, + "statistics": { + "vocab": list[char], + "vocab_count": dict[string, int], + "words": list[string], + "word_count": dict[string, int], + "times": dict[string, float] + } + } + +The format for a graph profile is below: + +.. code-block:: python + + "num_nodes": int, + "num_edges": int, + "categorical_attributes": list[string], + "continuous_attributes": list[string], + "avg_node_degree": float, + "global_max_component_size": int, + "continuous_distribution": { + "": { + "name": string, + "scale": float, + "properties": list[float, np.array] + }, + "": None, + }, + "categorical_distribution": { + "": None, + "": { + "bin_counts": list[int], + "bin_edges": list[float] + }, + }, + "times": dict[string, float] + +Supported Data Formats +~~~~~~~~~~~~~~~~~~~~~~ + +* Any delimited file (CSV, TSV, etc.) +* JSON object +* Avro file +* Parquet file +* Text file +* Pandas DataFrame +* A URL that points to one of the supported file types above + + +Data Labels +~~~~~~~~~~~ + +*Data Labels* are determined per cell for structured data (column/row when the *profiler* is used) or at the character level for unstructured data. + +* UNKNOWN +* ADDRESS +* BAN (bank account number, 10-18 digits) +* CREDIT_CARD +* EMAIL_ADDRESS +* UUID +* HASH_OR_KEY (md5, sha1, sha256, random hash, etc.) +* IPV4 +* IPV6 +* MAC_ADDRESS +* PERSON +* PHONE_NUMBER +* SSN +* URL +* US_STATE +* DRIVERS_LICENSE +* DATE +* TIME +* DATETIME +* INTEGER +* FLOAT +* QUANTITY +* ORDINAL + + +Get Started +=========== + +Load a File +~~~~~~~~~~~ + +The profiler should automatically identify the file type and load the data into a `Data Class`. + +Along with other attributtes the `Data class` enables structured data to be accessed via a valid Pandas DataFrame. + +.. code-block:: python + + # Load a csv file, return a CSVData object + csv_data = Data('your_file.csv') + + # Print the first 10 rows of the csv file + print(csv_data.data.head(10)) + + # Load a parquet file, return a ParquetData object + parquet_data = Data('your_file.parquet') + + # Sort the data by the name column + parquet_data.data.sort_values(by='name', inplace=True) + + # Print the sorted first 10 rows of the parquet data + print(parquet_data.data.head(10)) + + +If the file type is not automatically identified (rare), you can specify them +specifically, see section Data Readers. + +Profile a File +~~~~~~~~~~~~~~ + +Example uses a CSV file for example, but CSV, JSON, Avro, Parquet or Text should also work. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load file (CSV should be automatically identified) + data = Data("your_file.csv") + + # Profile the dataset + profile = Profiler(data) + + # Generate a report and use json to prettify. + report = profile.report(report_options={"output_format":"pretty"}) + + # Print the report + print(json.dumps(report, indent=4)) + +Updating Profiles +~~~~~~~~~~~~~~~~~ + +Currently, the data profiler is equipped to update its profile in batches. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load and profile a CSV file + data = Data("your_file.csv") + profile = Profiler(data) + + # Update the profile with new data: + new_data = Data("new_data.csv") + profile.update_profile(new_data) + + # Print the report using json to prettify. + report = profile.report(report_options={"output_format":"pretty"}) + print(json.dumps(report, indent=4)) + + +Merging Profiles +~~~~~~~~~~~~~~~~ + +If you have two files with the same schema (but different data), it is possible to merge the two profiles together via an addition operator. + +This also enables profiles to be determined in a distributed manner. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load a CSV file with a schema + data1 = Data("file_a.csv") + profile1 = Profiler(data) + + # Load another CSV file with the same schema + data2 = Data("file_b.csv") + profile2 = Profiler(data) + + profile3 = profile1 + profile2 + + # Print the report using json to prettify. + report = profile3.report(report_options={"output_format":"pretty"}) + print(json.dumps(report, indent=4)) + +Profile a Pandas DataFrame +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + import pandas as pd + import dataprofiler as dp + import json + + my_dataframe = pd.DataFrame([[1, 2.0],[1, 2.2],[-1, 3]]) + profile = dp.Profiler(my_dataframe) + + # print the report using json to prettify. + report = profile.report(report_options={"output_format":"pretty"}) + print(json.dumps(report, indent=4)) + + # read a specified column, in this case it is labeled 0: + print(json.dumps(report["data stats"][0], indent=4)) + + +Unstructured Profiler +~~~~~~~~~~~~~~~~~~~~~ + +In addition to the structured profiler, the Data Profiler provides unstructured +profiling for the TextData object or string. Unstructured profiling also works +with list(string), pd.Series(string) or pd.DataFrame(string) given profiler_type +option specified as `unstructured`. Below is an example of unstructured profile +with a text file. + +.. code-block:: python + + import dataprofiler as dp + import json + my_text = dp.Data('text_file.txt') + profile = dp.Profiler(my_text) + + # print the report using json to prettify. + report = profile.report(report_options={"output_format":"pretty"}) + print(json.dumps(report, indent=4)) + +Another example of unstructured profile with pd.Series of string is given as below + +.. code-block:: python + + import dataprofiler as dp + import pandas as pd + import json + + text_data = pd.Series(['first string', 'second string']) + profile = dp.Profiler(text_data, profiler_type="unstructured") + + # print the report using json to prettify. + report = profile.report(report_options={"output_format":"pretty"}) + print(json.dumps(report, indent=4)) + + +Graph Profiler +~~~~~~~~~~~~~~ + +DataProfiler also provides the ability to profile graph data from a csv file. Below is an example of the graph profiler with a graph data csv file: + +.. code-block:: python + + import dataprofiler as dp + import pprint + + my_graph = dp.Data('graph_file.csv') + profile = dp.Profiler(my_graph) + + # print the report using pretty print (json dump does not work on numpy array values inside dict) + report = profile.report() + printer = pprint.PrettyPrinter(sort_dicts=False, compact=True) + printer.pprint(report) + + +Specifying a Filetype or Delimiter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Example of specifying a CSV data type, with a `,` delimiter. +In addition, it utilizes only the first 10,000 rows. + +.. code-block:: python + + import json + import os + from dataprofiler import Data, Profiler + from dataprofiler.data_readers.csv_data import CSVData + + # Load a CSV file, with "," as the delimiter + data = CSVData("your_file.csv", options={"delimiter": ","}) + + # Split the data, such that only the first 10,000 rows are used + data = data.data[0:10000] + + # Read in profile and print results + profile = Profiler(data) + print(json.dumps(profile.report(report_options={"output_format":"pretty"}), indent=4)) + + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: Getting Started: + + Intro + install.rst + data_readers.rst + profiler.rst + data_labeling.rst + graphs.rst + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: User Guide: + + examples.rst + API.rst + +.. toctree:: + :maxdepth: 2 + :hidden: + :caption: Community: + + roadmap.rst + Changelog + Feedback + GitHub + Contributing + +.. _Example CSV: https://raw.githubusercontent.com/capitalone/DataProfiler/main/dataprofiler/tests/data/csv/aws_honeypot_marx_geo.csv +.. _issue: https://github.com/capitalone/DataProfiler/issues/new/choose + +Versions +======== +* `0.12.0`_ +* `0.11.0`_ +* `0.10.9`_ +* `0.10.8`_ +* `0.10.7`_ +* `0.10.6`_ +* `0.10.5`_ +* `0.10.4`_ +* `0.10.3`_ +* `0.10.2`_ +* `0.10.1`_ +* `0.10.0`_ +* `0.9.0`_ +* `0.8.9`_ +* `0.8.8`_ +* `0.8.7`_ +* `0.8.6`_ +* `0.8.5`_ +* `0.8.4`_ +* `0.8.3`_ +* `0.8.2`_ +* `0.8.1`_ +* `0.8.0`_ +* `0.7.11`_ +* `0.7.10`_ +* `0.7.9`_ +* `0.7.8`_ +* `0.7.7`_ +* `0.7.6`_ +* `0.7.2`_ +* `0.7.1`_ +* `0.7.0`_ +* `0.6.0`_ +* `0.5.3`_ +* `0.5.2`_ +* `0.5.1`_ +* `0.5.0`_ +* `0.4.7`_ +* `0.4.6`_ +* `0.4.5`_ +* `0.4.4`_ +* `0.4.3`_ +* `0.3.0`_ + +.. _0.3.0: ../../v0.3/html/index.html +.. _0.4.3: ../../0.4.3/html/index.html + +.. _0.4.4: ../../0.4.4/html/index.html + +.. _0.4.5: ../../0.4.5/html/index.html + +.. _0.4.6: ../../0.4.6/html/index.html + +.. _0.4.7: ../../0.4.7/html/index.html + +.. _0.5.0: ../../0.5.0/html/index.html + +.. _0.5.1: ../../0.5.1/html/index.html + +.. _0.5.2: ../../0.5.2/html/index.html + +.. _0.5.3: ../../0.5.3/html/index.html +.. _0.6.0: ../../0.6.0/html/index.html + +.. _0.7.0: ../../0.7.0/html/index.html + +.. _0.7.1: ../../0.7.1/html/index.html +.. _0.7.2: ../../0.7.2/html/index.html + +.. _0.7.6: ../../0.7.6/html/index.html + +.. _0.7.7: ../../0.7.7/html/index.html + +.. _0.7.8: ../../0.7.8/html/index.html + +.. _0.7.9: ../../0.7.9/html/index.html + +.. _0.7.10: ../../0.7.10/html/index.html + +.. _0.7.11: ../../0.7.11/html/index.html + +.. _0.8.0: ../../0.8.0/html/index.html + +.. _0.8.1: ../../0.8.1/html/index.html + +.. _0.8.2: ../../0.8.2/html/index.html + +.. _0.8.3: ../../0.8.3/html/index.html + +.. _0.8.4: ../../0.8.4/html/index.html + +.. _0.8.5: ../../0.8.5/html/index.html + +.. _0.8.6: ../../0.8.6/html/index.html + +.. _0.8.7: ../../0.8.7/html/index.html + +.. _0.8.8: ../../0.8.8/html/index.html + +.. _0.8.9: ../../0.8.9/html/index.html + +.. _0.9.0: ../../0.9.0/html/index.html + +.. _0.10.0: ../../0.10.0/html/index.html + +.. _0.10.1: ../../0.10.1/html/index.html + +.. _0.10.2: ../../0.10.2/html/index.html + +.. _0.10.3: ../../0.10.3/html/index.html + +.. _0.10.4: ../../0.10.4/html/index.html + +.. _0.10.5: ../../0.10.5/html/index.html + +.. _0.10.6: ../../0.10.6/html/index.html + +.. _0.10.7: ../../0.10.7/html/index.html + +.. _0.10.8: ../../0.10.8/html/index.html + +.. _0.10.9: ../../0.10.9/html/index.html + +.. _0.11.0: ../../0.11.0/html/index.html + +.. _0.12.0: ../../0.12.0/html/index.html + diff --git a/_docs/docs/source/install.rst b/_docs/docs/source/install.rst new file mode 100644 index 000000000..bdf4c3bb4 --- /dev/null +++ b/_docs/docs/source/install.rst @@ -0,0 +1,145 @@ +.. _install: + +Install +******* + +To install the full package from pypi: + +.. code-block:: console + + pip install DataProfiler[ml] + +If the ML requirements are too strict (say, you don't want to install +tensorflow), you can install a slimmer package. The slimmer package disables +the default sensitive data detection / entity recognition (labler) + +Install from pypi: + +.. code-block:: console + + pip install DataProfiler + +Snappy Installation +=================== + +This is required to profile parquet/avro datasets + +MacOS (intel chip) with homebrew: + +.. code-block:: console + + brew install snappy && CPPFLAGS="-I/usr/local/include -L/usr/local/lib" pip install python-snappy + + +MacOS (apple chip) with homebrew: + +.. code-block:: console + + brew install snappy && CPPFLAGS="-I/opt/homebrew/include -L/opt/homebrew/lib" pip install python-snappy + + +Linux install: + +.. code-block:: console + + sudo apt-get -y install libsnappy-dev + + +Build From Scratch +================== + +NOTE: Installation for python3 + +virtualenv install: + +.. code-block:: console + + python3 -m pip install virtualenv + + +Setup virtual env: + +.. code-block:: console + + python3 -m virtualenv --python=python3 venv3 + source venv3/bin/activate + + +Install requirements: + +.. code-block:: console + + pip3 install -r requirements.txt + +Install labeler dependencies: + +.. code-block:: console + + pip3 install -r requirements-ml.txt + + +Install via the repo -- Build setup.py and install locally: + +.. code-block:: console + + python3 setup.py sdist bdist bdist_wheel + pip3 install dist/DataProfiler*-py3-none-any.whl + + +If you see: + +.. code-block:: console + + ERROR: Double requirement given:dataprofiler==X.Y.Z from dataprofiler/dist/DataProfiler-X.Y.Z-py3-none-any.whl (already in dataprofiler==X2.Y2.Z2 from dataprofiler/dist/DataProfiler-X2.Y2.Z2-py3-none-any.whl, name='dataprofiler') + +This means that you have multiple versions of the DataProfiler distribution +in the dist folder. +To resolve, either remove the older one or delete the folder and rerun the steps +above. + +Install via github: + +.. code-block:: console + + pip3 install git+https://github.com/capitalone/dataprofiler.git#egg=dataprofiler + + + +Testing +======= + +For testing, install test requirements: + +.. code-block:: console + + pip3 install -r requirements-test.txt + + +To run all unit tests, use: + +.. code-block:: console + + DATAPROFILER_SEED=0 python3 -m unittest discover -p "test*.py" + + +To run file of unit tests, use form: + +.. code-block:: console + + DATAPROFILER_SEED=0 python3 -m unittest discover -p test_profile_builder.py + + +To run a file with Pytest use: + +.. code-block:: console + + DATAPROFILER_SEED=0 pytest dataprofiler/tests/data_readers/test_csv_data.py -v + + +To run individual of unit test, use form: + +.. code-block:: console + + DATAPROFILER_SEED=0 python3 -m unittest dataprofiler.tests.profilers.test_profile_builder.TestProfiler + + diff --git a/_docs/docs/source/labeler.nblink b/_docs/docs/source/labeler.nblink new file mode 100644 index 000000000..f862443fd --- /dev/null +++ b/_docs/docs/source/labeler.nblink @@ -0,0 +1,6 @@ +{ + "path": "../../../examples/labeler.ipynb", + "extra-media": [ + "../../../examples/DL-Flowchart.png" + ] +} \ No newline at end of file diff --git a/_docs/docs/source/merge_profile_list.nblink b/_docs/docs/source/merge_profile_list.nblink new file mode 100644 index 000000000..39102658b --- /dev/null +++ b/_docs/docs/source/merge_profile_list.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/merge_profile_list.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/modules.rst b/_docs/docs/source/modules.rst new file mode 100644 index 000000000..0593459df --- /dev/null +++ b/_docs/docs/source/modules.rst @@ -0,0 +1,7 @@ +dataprofiler +============ + +.. toctree:: + :maxdepth: 4 + + dataprofiler diff --git a/_docs/docs/source/overview.nblink b/_docs/docs/source/overview.nblink new file mode 100644 index 000000000..4c118878e --- /dev/null +++ b/_docs/docs/source/overview.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/intro_data_profiler.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/popmon_dp_loader_example.nblink b/_docs/docs/source/popmon_dp_loader_example.nblink new file mode 100644 index 000000000..1a288a318 --- /dev/null +++ b/_docs/docs/source/popmon_dp_loader_example.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/popmon_dp_loader_example.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/profiler.rst b/_docs/docs/source/profiler.rst new file mode 100644 index 000000000..56d16a274 --- /dev/null +++ b/_docs/docs/source/profiler.rst @@ -0,0 +1,965 @@ +.. _profiler: + +Profiler +******** + +Profile Your Data +================= + +Profiling your data is easy. Just use the data reader, send the data to the +profiler, and print out the report. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + data = Data("your_file.csv") # Auto-Detect & Load: CSV, AVRO, Parquet, JSON, Text + + profile = Profiler(data) # Calculate Statistics, Entity Recognition, etc + + readable_report = profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(readable_report, indent=4)) + +If the data is structured, the profile will return global statistics as well as +column by column statistics. The vast amount of statistics are listed on the +intro page. + +Load a File +~~~~~~~~~~~ + +The profiler should automatically identify the file type and load the data into a `Data Class`. + +Along with other attributtes the `Data class` enables structured data to be accessed via a valid Pandas DataFrame. + +.. code-block:: python + + # Load a csv file, return a CSVData object + csv_data = Data('your_file.csv') + + # Print the first 10 rows of the csv file + print(csv_data.data.head(10)) + + # Load a parquet file, return a ParquetData object + parquet_data = Data('your_file.parquet') + + # Sort the data by the name column + parquet_data.data.sort_values(by='name', inplace=True) + + # Print the sorted first 10 rows of the parquet data + print(parquet_data.data.head(10)) + + +If the file type is not automatically identified (rare), you can specify them +specifically, see section Data Readers. + +Profile a File +~~~~~~~~~~~~~~ + +Example uses a CSV file for example, but CSV, JSON, Avro or Parquet should also work. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load file (CSV should be automatically identified) + data = Data("your_file.csv") + + # Profile the dataset + profile = Profiler(data) + + # Generate a report and use json to prettify. + report = profile.report(report_options={"output_format": "pretty"}) + + # Print the report + print(json.dumps(report, indent=4)) + +Updating Profiles +~~~~~~~~~~~~~~~~~ + +Currently, the data profiler is equipped to update its profile in batches. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load and profile a CSV file + data = Data("your_file.csv") + profile = Profiler(data) + + # Update the profile with new data: + new_data = Data("new_data.csv") + profile.update_profile(new_data) + + # Print the report using json to prettify. + report = profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(report, indent=4)) + + +Merging Profiles +~~~~~~~~~~~~~~~~ + +If you have two files with the same schema (but different data), it is possible to merge the two profiles together via an addition operator. + +This also enables profiles to be determined in a distributed manner. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load a CSV file with a schema + data1 = Data("file_a.csv") + profile1 = Profiler(data) + + # Load another CSV file with the same schema + data2 = Data("file_b.csv") + profile2 = Profiler(data) + + profile3 = profile1 + profile2 + + # Print the report using json to prettify. + report = profile3.report(report_options={"output_format": "pretty"}) + print(json.dumps(report, indent=4)) + + +Profile Differences +~~~~~~~~~~~~~~~~~~~ + +Profile differences take two profiles and find the differences +between them. Create the difference report like this: + +.. code-block:: python + + from dataprofiler import Data, Profiler + + # Load a CSV file + data1 = Data("file_a.csv") + profile1 = Profiler(data) + + # Load another CSV file + data2 = Data("file_b.csv") + profile2 = Profiler(data) + + diff_report = profile1.diff(profile2) + print(diff_report) + +The `.diff()` operation is available between two profiles, although there are different +outputs depending on the type of profile being differenced. For example, for numerical +column profiles (e.g. integers and floats), two valuable calculations that +`.diff()` returns are `t-test`, `chi2-test`, and `psi` (Popoulation Stability Index) +for understanding distributional changes. + +The difference report contains a dictionary that mirrors the profile report. +Each data type has its own difference: + +* **Int/Float** - One profile subtracts the value from the other. + +* **String** - The strings will be shown in a list: + + - [profile1 str, profile2 str] +* **List** - A list of 3 will be returned showing the unique values of + each profile and the shared values: + + - [profile 1 unique values, shared values, profile 2 unique values] +* **Dict** - Some dictionaries with varied keys will also return a list + of three in the format: + + - [profile 1 unique key-values, shared key differences, profile 2 unique key-values] + +Otherwise, when no differences occur: + +* **Any Type No Differences** - A string will report: "unchanged". + +Below is the structured difference report: + +.. code-block:: python + + { + 'global_stats': { + 'file_type': [str, str], + 'encoding': [str, str], + 'samples_used': int, + 'column_count': int, + 'row_count': int, + 'row_has_null_ratio': float, + 'row_is_null_ratio': float, + 'unique_row_ratio': float, + 'duplicate_row_count': int, + 'correlation_matrix': list[list[float]], + 'chi2_matrix': list[list[float]], + 'profile_schema': list[dict[str, int]] + }, + 'data_stats': [{ + 'column_name': str, + 'data_type': [str, str], + 'data_label': [list[str], list[str], list[str]], + 'categorical': [str, str], + 'order': [str, str], + 'statistics': { + 'min': float, + 'max': float, + 'sum': float, + 'mean': float, + 'median': float, + 'mode': [list[float], list[float], list[float]], + 'median_absolute_deviation': float, + 'variance': float, + 'stddev': float, + 't-test': { + 't-statistic': float, + 'conservative': {'deg_of_free': int, + 'p-value': float}, + 'welch': {'deg_of_free': float, + 'p-value': float}}, + 'psi': float, + "chi2-test": { + "chi2-statistic": float, + "deg_of_free": int, + "p-value": float + }, + 'unique_count': int, + 'unique_ratio': float, + 'categories': [list[str], list[str], list[str]], + 'gini_impurity': float, + 'unalikeability': float, + 'categorical_count': [dict[str, int], dict[str, int], dict[str, int]], + 'avg_predictions': [dict[str, float]], + 'label_representation': [dict[str, float]], + 'sample_size': int, + 'null_count': int, + 'null_types': [list[str], list[str], list[str]], + 'null_types_index': [dict[str, int], dict[str, int], dict[str, int]], + 'data_type_representation': [dict[str, float]] + }, + "null_replication_metrics": { + "class_prior": list[int], + "class_sum": list[list[int]], + "class_mean": list[list[int]] + } + } + +Below is the unstructured difference report: + +.. code-block:: python + + { + 'global_stats': { + 'file_type': [str, str], + 'encoding': [str, str], + 'samples_used': int, + 'empty_line_count': int, + 'memory_size': float + }, + 'data_stats': { + 'data_label': { + 'entity_counts': { + 'word_level': dict[str, int], + 'true_char_level': dict[str, int], + 'postprocess_char_level': dict[str, int] + }, + 'entity_percentages': { + 'word_level': dict[str, float], + 'true_char_level': dict[str, float], + 'postprocess_char_level': dict[str, float] + } + }, + 'statistics': { + 'vocab': [list[str], list[str], list[str]], + 'vocab_count': [dict[str, int], dict[str, int], dict[str, int]], + 'words': [list[str], list[str], list[str]], + 'word_count': [dict[str, int], dict[str, int], dict[str, int]] + } + } + } + + +Saving and Loading a Profile +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The profiles can easily be saved and loaded as shown below: + +**NOTE: Json saving and loading only supports Structured Profiles currently.** + +There are two save/load methods: + +* **Pickle save/load** + + * Save a profile as a `.pkl` file. + * Load a `.pkl` file as a profile object. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load a CSV file, with "," as the delimiter + data = Data("your_file.csv") + + # Read data into profile + profile = Profiler(data) + + # save structured profile to pkl file + profile.save(filepath="my_profile.pkl") + + # load pkl file to structured profile + loaded_pkl_profile = dp.Profiler.load(filepath="my_profile.pkl") + + print(json.dumps(loaded_pkl_profile.report(report_options={"output_format": "compact"}), + indent=4)) + +* **Json save/load** + + * Save a profile as a human-readable `.json` file. + * Load a `.json` file as a profile object. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Load a CSV file, with "," as the delimiter + data = Data("your_file.csv") + + # Read data into profile + profile = Profiler(data) + + # save structured profile to json file + profile.save(filepath="my_profile.json", save_method="json") + + # load json file to structured profile + loaded_json_profile = dp.Profiler.load(filepath="my_profile.json", load_method="json") + + print(json.dumps(loaded_json_profile.report(report_options={"output_format": "compact"}), + indent=4)) + + +Structured vs Unstructured Profiles +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When using the profiler, the data profiler will automatically infer whether to +create the structured profile or the unstructured profile. However, you can be +explicit as shown below: + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + + # Creating a structured profile + data1 = Data("normal_csv_file.csv") + structured_profile = Profiler(data1, profiler_type="structured") + + structured_report = structured_profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(structured_report, indent=4)) + + # Creating an unstructured profile + data2 = Data("normal_text_file.txt") + unstructured_profile = Profiler(data2, profiler_type="unstructured") + + unstructured_report = unstructured_profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(unstructured_report, indent=4)) + + +Setting the Sample Size +~~~~~~~~~~~~~~~~~~~~~~~ + +There are two ways to set sample size in a profile: samples_per_update and +min_true_samples. Samples_per_update takes an integer as the exact amount that +will be sampled. Min_true_samples will set the minimum amount of samples that +are not null. For example: + +.. code-block:: python + + from dataprofiler import Profiler + + sample_array = [1.0, NULL, 2.0] + profile = dp.Profiler(sample_array, samples_per_update=2) + +The first two samples (1.0 and NULL) are used for the statistical analysis. + +In contrast, if we also set min_true_samples to 2 then the Data Reader will +continue to read until the minimum true samples were found for the given column. +For example: + +.. code-block:: python + + from dataprofiler import Profiler + + sample_array = [1.0, NULL, 2.0] + profile = dp.Profiler(sample_array, samples_per_update=2, min_true_samples=2) + +This will use all samples in the statistical analysis until the number of "true" +(non-NULL) values are reached. Both min_true_samples and +samples_per_update conditions must be met. In this case, the profile will grab +the first two samples (1.0 and NULL) to satisfy the samples_per_update, and then +it will grab the first two VALID samples (1.0 and 2.0) to satisfy the +min_true_samples. + +Profile a Pandas DataFrame +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: python + + import pandas as pd + import dataprofiler as dp + import json + + my_dataframe = pd.DataFrame([[1, 2.0],[1, 2.2],[-1, 3]]) + profile = dp.Profiler(my_dataframe) + + # print the report using json to prettify. + report = profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(report, indent=4)) + + # read a specified column, in this case it is labeled 0: + print(json.dumps(report["data stats"][0], indent=4)) + + +Specifying a Filetype or Delimiter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Example of specifying a CSV data type, with a `,` delimiter. +In addition, it utilizes only the first 10,000 rows. + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler + from dataprofiler.data_readers.csv_data import CSVData + + # Load a CSV file, with "," as the delimiter + data = CSVData("your_file.csv", options={"delimiter": ","}) + + # Split the data, such that only the first 10,000 rows are used + data = data.data[0:10000] + + # Read in profile and print results + profile = Profiler(data) + print(json.dumps(profile.report(report_options={"output_format": "pretty"}), indent=4)) + +Setting Profiler Seed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Example of specifying a seed for reproducibility. + +.. code-block:: python + + import dataprofiler as dp + + # Set seed to non-negative integer value or None + dp.set_seed(0) + + +Profile Statistic Descriptions +============================== + +Structured Profile +~~~~~~~~~~~~~~~~~~ + +**global_stats**: + +* samples_used - number of input data samples used to generate this profile +* column_count - the number of columns contained in the input dataset +* row_count - the number of rows contained in the input dataset +* row_has_null_ratio - the proportion of rows that contain at least one null value to the total number of rows +* row_is_null_ratio - the proportion of rows that are fully comprised of null values (null rows) to the total number of rows +* unique_row_ratio - the proportion of distinct rows in the input dataset to the total number of rows +* duplicate_row_count - the number of rows that occur more than once in the input dataset +* file_type - the format of the file containing the input dataset (ex: .csv) +* encoding - the encoding of the file containing the input dataset (ex: UTF-8) +* correlation_matrix - matrix of shape `column_count` x `column_count` containing the correlation coefficients between each column in the dataset +* chi2_matrix - matrix of shape `column_count` x `column_count` containing the chi-square statistics between each column in the dataset +* profile_schema - a description of the format of the input dataset labeling each column and its index in the dataset + * string - the label of the column in question and its index in the profile schema +* times - the duration of time it took to generate the global statistics for this dataset in milliseconds + +**data_stats**: + +* column_name - the label/title of this column in the input dataset +* data_type - the primitive python data type that is contained within this column +* data_label - the label/entity of the data in this column as determined by the Labeler component +* categorical - 'true' if this column contains categorical data +* order - the way in which the data in this column is ordered, if any, otherwise “random” +* samples - a small subset of data entries from this column +* statistics - statistical information on the column + * sample_size - number of input data samples used to generate this profile + * null_count - the number of null entries in the sample + * null_types - a list of the different null types present within this sample + * null_types_index - a dict containing each null type and a respective list of the indicies that it is present within this sample + * data_type_representation - the percentage of samples used identifying as each data_type + * min - minimum value in the sample + * max - maximum value in the sample + * mode - mode of the entries in the sample + * median - median of the entries in the sample + * median_absolute_deviation - the median absolute deviation of the entries in the sample + * sum - the total of all sampled values from the column + * mean - the average of all entries in the sample + * variance - the variance of all entries in the sample + * stddev - the standard deviation of all entries in the sample + * skewness - the statistical skewness of all entries in the sample + * kurtosis - the statistical kurtosis of all entries in the sample + * num_zeros - the number of entries in this sample that have the value 0 + * num_negatives - the number of entries in this sample that have a value less than 0 + * histogram - contains histogram relevant information + * bin_counts - the number of entries within each bin + * bin_edges - the thresholds of each bin + * quantiles - the value at each percentile in the order they are listed based on the entries in the sample + * vocab - a list of the characters used within the entries in this sample + * avg_predictions - average of the data label prediction confidences across all data points sampled + * categories - a list of each distinct category within the sample if `categorial` = 'true' + * unique_count - the number of distinct entries in the sample + * unique_ratio - the proportion of the number of distinct entries in the sample to the total number of entries in the sample + * categorical_count - number of entries sampled for each category if `categorical` = 'true' + * gini_impurity - measure of how often a randomly chosen element from the set would be incorrectly labeled if it was randomly labeled according to the distribution of labels in the subset + * unalikeability - a value denoting how frequently entries differ from one another within the sample + * precision - a dict of statistics with respect to the number of digits in a number for each sample + * times - the duration of time it took to generate this sample's statistics in milliseconds + * format - list of possible datetime formats +* null_replication_metrics - statistics of data partitioned based on whether column value is null (index 1 of lists referenced by dict keys) or not (index 0) + * class_prior - a list containing probability of a column value being null and not null + * class_sum - a list containing sum of all other rows based on whether column value is null or not + * class_mean - a list containing mean of all other rows based on whether column value is null or not + +Unstructured Profile +~~~~~~~~~~~~~~~~~~~~ + +**global_stats**: + +* samples_used - number of input data samples used to generate this profile +* empty_line_count - the number of empty lines in the input data +* file_type - the file type of the input data (ex: .txt) +* encoding - file encoding of the input data file (ex: UTF-8) +* memory_size - size of the input data in MB +* times - duration of time it took to generate this profile in milliseconds + +**data_stats**: + +* data_label - labels and statistics on the labels of the input data + * entity_counts - the number of times a specific label or entity appears inside the input data + * word_level - the number of words counted within each label or entity + * true_char_level - the number of characters counted within each label or entity as determined by the model + * postprocess_char_level - the number of characters counted within each label or entity as determined by the postprocessor + * entity_percentages - the percentages of each label or entity within the input data + * word_level - the percentage of words in the input data that are contained within each label or entity + * true_char_level - the percentage of characters in the input data that are contained within each label or entity as determined by the model + * postprocess_char_level - the percentage of characters in the input data that are contained within each label or entity as determined by the postprocessor + * times - the duration of time it took for the data labeler to predict on the data +* statistics - statistics of the input data + * vocab - a list of each character in the input data + * vocab_count - the number of occurrences of each distinct character in the input data + * words - a list of each word in the input data + * word_count - the number of occurrences of each distinct word in the input data + * times - the duration of time it took to generate the vocab and words statistics in milliseconds + +Graph Profile +~~~~~~~~~~~~~~~~~~ + +* num_nodes - number of nodes in the graph +* num_edges - number of edges in the graph +* categorical_attributes - list of categorical edge attributes +* continuous_attributes - list of continuous edge attributes +* avg_node_degree - average degree of nodes in the graph +* global_max_component_size: size of the global max component + +**continuous_distribution**: + +* : name of N-th edge attribute in list of attributes + * name - name of distribution for attribute + * scale - negative log likelihood used to scale and compare distributions + * properties - list of statistical properties describing the distribution + * [shape (optional), loc, scale, mean, variance, skew, kurtosis] + +**categorical_distribution**: + +* : name of N-th edge attribute in list of attributes + * bin_counts: counts in each bin of the distribution histogram + * bin_edges: edges of each bin of the distribution histogram + +* times - duration of time it took to generate this profile in milliseconds + +Profile Options +=============== + +The data profiler accepts several options to toggle on and off +features. The 8 columns (int options, float options, datetime options, +text options, order options, category options, data labeler options) can be +enabled or disabled. By default, all options are toggled on. Below is an example +of how to alter these options. Options shared by structured and unstructured options +must be specified as structured or unstructured when setting (ie. datalabeler options). + + +.. code-block:: python + + import json + from dataprofiler import Data, Profiler, ProfilerOptions + + # Load and profile a CSV file + data = Data("your_file.csv") + profile_options = ProfilerOptions() + + #All of these are different examples of adjusting the profile options + + # Options can be toggled directly like this: + profile_options.structured_options.text.is_enabled = False + profile_options.structured_options.text.vocab.is_enabled = True + profile_options.structured_options.int.variance.is_enabled = True + profile_options.structured_options.data_labeler.data_labeler_dirpath = \ + "Wheres/My/Datalabeler" + profile_options.structured_options.data_labeler.is_enabled = False + + # A dictionary can be sent in to set the properties for all the options + profile_options.set({"structured_options.data_labeler.is_enabled": False, "min.is_enabled": False}) + + # Specific columns can be set/disabled/enabled in the same way + profile_options.structured_options.text.set({"max.is_enabled":True, + "variance.is_enabled": True}) + + # numeric stats can be turned off/on entirely + profile_options.set({"is_numeric_stats_enabled": False}) + profile_options.set({"int.is_numeric_stats_enabled": False}) + + profile = Profiler(data, options=profile_options) + + # Print the report using json to prettify. + report = profile.report(report_options={"output_format": "pretty"}) + print(json.dumps(report, indent=4)) + + +Below is an breakdown of all the options. + +* **ProfilerOptions** - The top-level options class that contains options for the Profiler class + + * **presets** - A pre-configured mapping of a string name to group of options: + + * **default is None** + + * **"complete"** + + .. code-block:: python + + options = ProfilerOptions(presets="complete") + + * **"data_types"** + + .. code-block:: python + + options = ProfilerOptions(presets="data_types") + + * **"numeric_stats_disabled"** + + .. code-block:: python + + options = ProfilerOptions(presets="numeric_stats_disabled") + + * **"lower_memory_sketching"** + + .. code-block:: python + + options = ProfilerOptions(presets="lower_memory_sketching") + + * **structured_options** - Options responsible for all structured data + + * **multiprocess** - Option to enable multiprocessing. If on, multiprocessing is toggled on if the dataset contains more than 750,000 rows or more than 20 columns. + Automatically selects the optimal number of pooling processes to utilize based on system constraints when toggled on. + + * is_enabled - (Boolean) Enables or disables multiprocessing + + * **sampling_ratio** - A percentage, as a decimal, ranging from greater than 0 to less than or equal to 1 indicating how much input data to sample. Default value set to 0.2. + + * **int** - Options for the integer columns + + * is_enabled - (Boolean) Enables or disables the integer operations + + * min - Finds minimum value in a column + + * is_enabled - (Boolean) Enables or disables min + + * max - Finds maximum value in a column + + * is_enabled - (Boolean) Enables or disables max + + * mode - Finds mode(s) in a column + + * is_enabled - (Boolean) Enables or disables mode + * top_k_modes - (Int) Sets the number of modes to return if multiple exist. Default returns max 5 modes. + * median - Finds median value in a column + + * is_enabled - (Boolean) Enables or disables median + * sum - Finds sum of all values in a column + + * is_enabled - (Boolean) Enables or disables sum + + * variance - Finds variance of all values in a column + + * is_enabled - (Boolean) Enables or disables variance + * skewness - Finds skewness of all values in a column + + * is_enabled - (Boolean) Enables or disables skewness + * kurtosis - Finds kurtosis of all values in a column + + * is_enabled - (Boolean) Enables or disables kurtosis + * median_abs_deviation - Finds median absolute deviation of all values in a column + + * is_enabled - (Boolean) Enables or disables median absolute deviation + * num_zeros - Finds the count of zeros in a column + + * is_enabled - (Boolean) Enables or disables num_zeros + * num_negatives - Finds the count of negative numbers in a column + + * is_enabled - (Boolean) Enables or disables num_negatives + * bias_correction - Applies bias correction to variance, skewness, and kurtosis calculations + + * is_enabled - (Boolean) Enables or disables bias correction + * histogram_and_quantiles - Generates a histogram and quantiles + from the column values + + * bin_count_or_method - (String/List[String]) Designates preferred method for calculating histogram bins or the number of bins to use. + If left unspecified (None) the optimal method will be chosen by attempting all methods. + If multiple specified (list) the optimal method will be chosen by attempting the provided ones. + methods: 'auto', 'fd', 'doane', 'scott', 'rice', 'sturges', 'sqrt' + Note: 'auto' is used to choose optimally between 'fd' and 'sturges' + * num_quantiles - (Int) Number of quantiles to bin the data. + Default value is set to 1,000 quantiles. + * is_enabled - (Boolean) Enables or disables histogram and quantiles + * **float** - Options for the float columns + + * is_enabled - (Boolean) Enables or disables the float operations + * precision - Finds the precision (significant figures) within the column + + * is_enabled - (Boolean) Enables or disables precision + * sample_ratio - (Float) The ratio of 0 to 1 how much data (identified as floats) to utilize as samples in determining precision + + * min - Finds minimum value in a column + + * is_enabled - (Boolean) Enables or disables min + * max - Finds maximum value in a column + + * is_enabled - (Boolean) Enables or disables max + * mode - Finds mode(s) in a column + + * is_enabled - (Boolean) Enables or disables mode + * top_k_modes - (Int) Sets the number of modes to return if multiple exist. Default returns max 5 modes. + * median - Finds median value in a column + + * is_enabled - (Boolean) Enables or disables median + * sum - Finds sum of all values in a column + + * is_enabled - (Boolean) Enables or disables sum + * variance - Finds variance of all values in a column + + * is_enabled - (Boolean) Enables or disables variance + * skewness - Finds skewness of all values in a column + + * is_enabled - (Boolean) Enables or disables skewness + * kurtosis - Finds kurtosis of all values in a column + + * is_enabled - (Boolean) Enables or disables kurtosis + * median_abs_deviation - Finds median absolute deviation of all values in a column + + * is_enabled - (Boolean) Enables or disables median absolute deviation + * is_numeric_stats_enabled - (Boolean) enable or disable all numeric stats + * num_zeros - Finds the count of zeros in a column + + * is_enabled - (Boolean) Enables or disables num_zeros + * num_negatives - Finds the count of negative numbers in a column + + * is_enabled - (Boolean) Enables or disables num_negatives + * bias_correction - Applies bias correction to variance, skewness, and kurtosis calculations + + * is_enabled - (Boolean) Enables or disables bias correction + * histogram_and_quantiles - Generates a histogram and quantiles + from the column values + + * bin_count_or_method - (String/List[String]) Designates preferred method for calculating histogram bins or the number of bins to use. + If left unspecified (None) the optimal method will be chosen by attempting all methods. + If multiple specified (list) the optimal method will be chosen by attempting the provided ones. + methods: 'auto', 'fd', 'doane', 'scott', 'rice', 'sturges', 'sqrt' + Note: 'auto' is used to choose optimally between 'fd' and 'sturges' + * num_quantiles - (Int) Number of quantiles to bin the data. + Default value is set to 1,000 quantiles. + * is_enabled - (Boolean) Enables or disables histogram and quantiles + * **text** - Options for the text columns + + * is_enabled - (Boolean) Enables or disables the text operations + * vocab - Finds all the unique characters used in a column + + * is_enabled - (Boolean) Enables or disables vocab + * min - Finds minimum value in a column + + * is_enabled - (Boolean) Enables or disables min + * max - Finds maximum value in a column + + * is_enabled - (Boolean) Enables or disables max + * mode - Finds mode(s) in a column + + * is_enabled - (Boolean) Enables or disables mode + * top_k_modes - (Int) Sets the number of modes to return if multiple exist. Default returns max 5 modes. + * median - Finds median value in a column + + * is_enabled - (Boolean) Enables or disables median + * sum - Finds sum of all values in a column + + * is_enabled - (Boolean) Enables or disables sum + * variance - Finds variance of all values in a column + + * is_enabled - (Boolean) Enables or disables variance + * skewness - Finds skewness of all values in a column + + * is_enabled - (Boolean) Enables or disables skewness + * kurtosis - Finds kurtosis of all values in a column + + * is_enabled - (Boolean) Enables or disables kurtosis + * median_abs_deviation - Finds median absolute deviation of all values in a column + + * is_enabled - (Boolean) Enables or disables median absolute deviation + * bias_correction - Applies bias correction to variance, skewness, and kurtosis calculations + + * is_enabled - (Boolean) Enables or disables bias correction + * is_numeric_stats_enabled - (Boolean) enable or disable all numeric stats + * num_zeros - Finds the count of zeros in a column + + * is_enabled - (Boolean) Enables or disables num_zeros + * num_negatives - Finds the count of negative numbers in a column + + * is_enabled - (Boolean) Enables or disables num_negatives + * histogram_and_quantiles - Generates a histogram and quantiles + from the column values + + * bin_count_or_method - (String/List[String]) Designates preferred method for calculating histogram bins or the number of bins to use. + If left unspecified (None) the optimal method will be chosen by attempting all methods. + If multiple specified (list) the optimal method will be chosen by attempting the provided ones. + methods: 'auto', 'fd', 'doane', 'scott', 'rice', 'sturges', 'sqrt' + Note: 'auto' is used to choose optimally between 'fd' and 'sturges' + * num_quantiles - (Int) Number of quantiles to bin the data. + Default value is set to 1,000 quantiles. + * is_enabled - (Boolean) Enables or disables histogram and quantiles + * **datetime** - Options for the datetime columns + + * is_enabled - (Boolean) Enables or disables the datetime operations + * **order** - Options for the order columns + + * is_enabled - (Boolean) Enables or disables the order operations + * **category** - Options for the category columns + + * is_enabled - (Boolean) Enables or disables the category operations + * top_k_categories - (int) Number of categories to be displayed when reporting + * max_sample_size_to_check_stop_condition - (int) The maximum sample size before categorical stop conditions are checked + * stop_condition_unique_value_ratio - (float) The highest ratio of unique values to dataset size that is to be considered a categorical type + * cms - (Boolean) Enables or Disables the use of count min sketch / heavy hitters for approximate frequency counts + * cms_confidence - (float) Defines the number of hashes used in CMS, default 0.95 + * cms_relative_error - (float) Defines the number of buckets used in CMS, default 0.01 + * cms_max_num_heavy_hitters - (int) The value used to define the threshold for minimum frequency required by a category to be counted + * **data_labeler** - Options for the data labeler columns + + * is_enabled - (Boolean) Enables or disables the data labeler operations + * data_labeler_dirpath - (String) Directory path to data labeler + * data_labeler_object - (BaseDataLabeler) Datalabeler to replace + the default labeler + * max_sample_size - (Int) The max number of samples for the data + labeler + * **correlation** - Option set for correlation profiling + * is_enabled - (Boolean) Enables or disables performing correlation profiling + * columns - Columns considered to calculate correlation + * **row_statistics** - (Boolean) Option to enable/disable row statistics calculations + + * unique_count - (UniqueCountOptions) Option to enable/disable unique row count calculations + + * is_enabled - (Bool) Enables or disables options for unique row count + * hashing_method - (String) Property to specify row hashing method ("full" | "hll") + * hll - (HyperLogLogOptions) Options for alternative method of estimating unique row count (activated when `hll` is the selected hashing_method) + + * seed - (Int) Used to set HLL hashing function seed + * register_count - (Int) Number of registers is equal to 2^register_count + + * null_count - (Boolean) Option to enable/disable functionalities for row_has_null_ratio and row_is_null_ratio + * **chi2_homogeneity** - Options for the chi-squared test matrix + + * is_enabled - (Boolean) Enables or disables performing chi-squared tests for homogeneity between the categorical columns of the dataset. + * **null_replication_metrics** - Options for calculating null replication metrics + + * is_enabled - (Boolean) Enables or disables calculation of null replication metrics + * **unstructured_options** - Options responsible for all unstructured data + + * **text** - Options for the text profile + + * is_case_sensitive - (Boolean) Specify whether the profile is case sensitive + * stop_words - (List of Strings) List of stop words to be removed when profiling + * top_k_chars - (Int) Number of top characters to be retrieved when profiling + * top_k_words - (Int) Number of top words to be retrieved when profiling + * vocab - Options for vocab count + + * is_enabled - (Boolean) Enables or disables the vocab stats + * words - Options for word count + + * is_enabled - (Boolean) Enables or disables the word stats + * **data_labeler** - Options for the data labeler + + * is_enabled - (Boolean) Enables or disables the data labeler operations + * data_labeler_dirpath - (String) Directory path to data labeler + * data_labeler_object - (BaseDataLabeler) Datalabeler to replace + the default labeler + * max_sample_size - (Int) The max number of samples for the data + labeler + + + +Statistical Dependency on Order of Updates +========================================== + +Some profile features/statistics are dependent on the order in which the profiler +is updated with new data. + +Order Profile +~~~~~~~~~~~~~ + +The order profiler utilizes the last value in the previous data batch to ensure +the subsequent dataset is above/below/equal to that value when predicting +non-random order. + +For instance, a dataset to be predicted as ascending would require the following +batch data update to be ascending and its first value `>=` than that of the +previous batch of data. + +Ex. of ascending: + +.. code-block:: python + + batch_1 = [0, 1, 2] + batch_2 = [3, 4, 5] + +Ex. of random: + +.. code-block:: python + + batch_1 = [0, 1, 2] + batch_2 = [1, 2, 3] # notice how the first value is less than the last value in the previous batch + + +Reporting Structure +=================== + +For every profile, we can provide a report and customize it with a couple optional parameters: + +* output_format (string) + + * This will allow the user to decide the output format for report. + + * Options are one of [pretty, compact, serializable, flat]: + + * Pretty: floats are rounded to four decimal places, and lists are shortened. + * Compact: Similar to pretty, but removes detailed statistics such as runtimes, label probabilities, index locations of null types, etc. + * Serializable: Output is json serializable and not prettified + * Flat: Nested output is returned as a flattened dictionary +* num_quantile_groups (int) + + * You can sample your data as you like! With a minimum of one and a maximum of 1000, you can decide the number of quantile groups! + +.. code-block:: python + + report = profile.report(report_options={"output_format": "pretty"}) + report = profile.report(report_options={"output_format": "compact"}) + report = profile.report(report_options={"output_format": "serializable"}) + report = profile.report(report_options={"output_format": "flat"}) diff --git a/_docs/docs/source/profiler_example.nblink b/_docs/docs/source/profiler_example.nblink new file mode 100644 index 000000000..142ebd97f --- /dev/null +++ b/_docs/docs/source/profiler_example.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/structured_profilers.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/regex_labeler_from_scratch.nblink b/_docs/docs/source/regex_labeler_from_scratch.nblink new file mode 100644 index 000000000..3d98c5f1e --- /dev/null +++ b/_docs/docs/source/regex_labeler_from_scratch.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/regex_labeler_from_scratch/DataLabeler_from_scratch.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/source/roadmap.rst b/_docs/docs/source/roadmap.rst new file mode 100644 index 000000000..93886690b --- /dev/null +++ b/_docs/docs/source/roadmap.rst @@ -0,0 +1,58 @@ +.. _roadmap: + +Roadmap +******* + +For more detailed tasks, checkout the repo's github issues page here: +`Github Issues `_. + + +Data Reader Updates +=================== +- Read data from S3 bucket + - All in the current `dp.Data()` API paradigm, we want to enable passing an S3 bucket file path to read in data from AWS s3. +- Pass list of data file paths to data reader +- Pass in linst of data frames to data reader + +New Model +========= +- Transformer model from sensitive data detection + +Historical Profiles +=================== +- Some questions about Historical Profiles / need to step back and rething design to start: + - Meta profile on top? + - Stored windowed info inside? Etc... +- Branch with current state of Historical Profiles +- Two example notebooks of current state: + - Notebook example `one `_. + - Notebook example `two `_. + + +Conditional Report Metric +========================= +- Based on what is populated on other metrics in the report, have "secondary" / "derivatives" of that number (or that number in conjunction with another number) populate in thie report as well. +- For example, if null_count is not None, then populate a null_percent key with a value of the dividence of (null_count / sample_count). + +Space / Time Testing +==================== +- Automatic comparison testing for space and time analysis on PR’s + - Standardize a report for space time analysis for future comparisons (create baseline numbers) + - Include those in integration tests that will automatically run on code when it is changed in PRs +- Could be an optional test, if the user thinks there is concern around the change driving an issue in the library performance + +Testing Suite Upgrades +====================== +- Add mocking to unit tests where mocking is not utilized +- Integration testing separated out from the unit testing suite. Determine how to only run remotely during PRs +- Backward compatibility testing along with informative warnings and errors when a user is utilizing incompatible versions of the library and saved profile object + +Historical Versions +=================== +- Legacy version upgrades to enable patches to prior versions of the Data Profiler + +Miscellaneous +============== +- Refact/or Pandas to Polars DataFrames +- Spearman correlation calculation +- Workflow Profiles diff --git a/_docs/docs/source/unstructured_profiler_example.nblink b/_docs/docs/source/unstructured_profiler_example.nblink new file mode 100644 index 000000000..5b6829754 --- /dev/null +++ b/_docs/docs/source/unstructured_profiler_example.nblink @@ -0,0 +1,3 @@ +{ + "path": "../../../examples/unstructured_profilers.ipynb" +} \ No newline at end of file diff --git a/_docs/docs/update_documentation.py b/_docs/docs/update_documentation.py new file mode 100644 index 000000000..377c88c3e --- /dev/null +++ b/_docs/docs/update_documentation.py @@ -0,0 +1,86 @@ +#!/usr/bin/python +"""Script which auto updates the github pages documentation.""" +import os +import subprocess +import sys + +sys.path.insert(0, os.path.abspath(f'../../')) + +from dataprofiler import __version__ as version # noqa F401 + +# Make the rst files from the current repo +subprocess.run( + [ + "sphinx-apidoc", + "--templatedir=./source/_templates/", + "-f", + "-e", + "-o", + "../docs/source", + f"../../dataprofiler", + f"../../dataprofiler/tests/", + ] +) + +update_index_rst = True + +if not version: + Exception("There must be a valid version argument.") + +# Check if the source index file has already been updated +source_index = open("source/index.rst", "r+") +source_index_lines = source_index.readlines() +source_index.close() +for sentence in source_index_lines: + if sentence.startswith("* `" + version): + update_index_rst = False + +# Update the index file if needed +version_reference = "" +if update_index_rst: + buffer = 0 + source_index = open("source/index.rst", "w") + for sentence in source_index_lines: + if sentence.startswith("Documentation for"): + doc_version = "Documentation for " + version + "\n" + source_index.write(doc_version) + elif sentence.startswith("Versions"): + source_index.write("Versions\n") + source_index.write("========\n") + version_tag = "* `" + version + "`_\n" + source_index.write(version_tag) + version_reference = ( + ".. _" + version + ": ../../" + version + "/html/index.html\n\n" + ) + buffer = 1 + else: + if buffer == 0: + source_index.write(sentence) + else: + buffer = buffer - 1 + source_index.write(version_reference) +source_index.close() + +# Make the html files +build_directory = "BUILDDIR=" + version +subprocess.run(["make", "html", build_directory]) + +# update the index file to redirect to the most current version of documentation +index_file = open("../index.html", "w") +redirect_link = ( + '' +) +index_file.write(redirect_link) +index_file.close() + +# update the profiler_options.html file to redirect to detailed options docs +index_file = open("../profiler_options.html", "w") +redirect_link = ( + '' +) +index_file.write(redirect_link) +index_file.close() diff --git a/_docs/index.html b/_docs/index.html new file mode 100644 index 000000000..fb51eaca9 --- /dev/null +++ b/_docs/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_docs/profiler_options.html b/_docs/profiler_options.html new file mode 100644 index 000000000..831f653ff --- /dev/null +++ b/_docs/profiler_options.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/_docs/setup.cfg b/_docs/setup.cfg new file mode 100644 index 000000000..c9c21e52f --- /dev/null +++ b/_docs/setup.cfg @@ -0,0 +1,7 @@ +[flake8] +max-line-length = 88 +extend-ignore = E203 + +[isort] +multi_line_output=3 +profile=black diff --git a/requirements-docs.txt b/requirements-docs.txt new file mode 100644 index 000000000..36517b45f --- /dev/null +++ b/requirements-docs.txt @@ -0,0 +1,7 @@ +Sphinx>=5.0.0 +sphinx-rtd-theme +nbsphinx +furo +nbsphinx-link +pre-commit +tornado From 09c2062c05d97e8021190931ac6ac8fdf80091cb Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:39:27 -0400 Subject: [PATCH 07/14] Update gh-pages workflows (#1174) * chore: update workflow to properly install pandoc * chore: update build to build to a LATEST directory --- .github/workflows/publish-docs.yml | 9 ++++++--- _docs/docs/update_documentation.py | 7 ++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index d27bcc0f8..764a2d168 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -22,13 +22,16 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.11' + python-version: '3.9' + - name: Install pandoc + uses: pandoc/actions/setup@v1 - name: Install dependencies run: | - pip install pandoc pip install -r requirements.txt pip install -r requirements-ml.txt pip install -r requirements-reports.txt + pip install -r requirements-docs.txt + pip install -e . - name: Build run: | @@ -38,4 +41,4 @@ jobs: uses: JamesIves/github-pages-deploy-action@v4 with: branch: gh-pages - folder: docs/build/html + folder: _docs/docs/LATEST/html diff --git a/_docs/docs/update_documentation.py b/_docs/docs/update_documentation.py index 377c88c3e..7be79612d 100644 --- a/_docs/docs/update_documentation.py +++ b/_docs/docs/update_documentation.py @@ -62,14 +62,15 @@ source_index.close() # Make the html files -build_directory = "BUILDDIR=" + version + +build_directory = "BUILDDIR= LATEST" subprocess.run(["make", "html", build_directory]) # update the index file to redirect to the most current version of documentation index_file = open("../index.html", "w") redirect_link = ( '' ) index_file.write(redirect_link) @@ -79,7 +80,7 @@ index_file = open("../profiler_options.html", "w") redirect_link = ( '' ) index_file.write(redirect_link) From 9919af4552fbd6140a8d48683bdb928a0b1ab455 Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Thu, 20 Mar 2025 13:50:53 -0400 Subject: [PATCH 08/14] Remove Versions from Intro page (#1175) --- _docs/docs/source/index.rst | 127 ------------------------------------ 1 file changed, 127 deletions(-) diff --git a/_docs/docs/source/index.rst b/_docs/docs/source/index.rst index a20aa5ff0..735f4fe38 100644 --- a/_docs/docs/source/index.rst +++ b/_docs/docs/source/index.rst @@ -474,132 +474,5 @@ In addition, it utilizes only the first 10,000 rows. .. _Example CSV: https://raw.githubusercontent.com/capitalone/DataProfiler/main/dataprofiler/tests/data/csv/aws_honeypot_marx_geo.csv .. _issue: https://github.com/capitalone/DataProfiler/issues/new/choose -Versions -======== -* `0.12.0`_ -* `0.11.0`_ -* `0.10.9`_ -* `0.10.8`_ -* `0.10.7`_ -* `0.10.6`_ -* `0.10.5`_ -* `0.10.4`_ -* `0.10.3`_ -* `0.10.2`_ -* `0.10.1`_ -* `0.10.0`_ -* `0.9.0`_ -* `0.8.9`_ -* `0.8.8`_ -* `0.8.7`_ -* `0.8.6`_ -* `0.8.5`_ -* `0.8.4`_ -* `0.8.3`_ -* `0.8.2`_ -* `0.8.1`_ -* `0.8.0`_ -* `0.7.11`_ -* `0.7.10`_ -* `0.7.9`_ -* `0.7.8`_ -* `0.7.7`_ -* `0.7.6`_ -* `0.7.2`_ -* `0.7.1`_ -* `0.7.0`_ -* `0.6.0`_ -* `0.5.3`_ -* `0.5.2`_ -* `0.5.1`_ -* `0.5.0`_ -* `0.4.7`_ -* `0.4.6`_ -* `0.4.5`_ -* `0.4.4`_ -* `0.4.3`_ -* `0.3.0`_ -.. _0.3.0: ../../v0.3/html/index.html -.. _0.4.3: ../../0.4.3/html/index.html - -.. _0.4.4: ../../0.4.4/html/index.html - -.. _0.4.5: ../../0.4.5/html/index.html - -.. _0.4.6: ../../0.4.6/html/index.html - -.. _0.4.7: ../../0.4.7/html/index.html - -.. _0.5.0: ../../0.5.0/html/index.html - -.. _0.5.1: ../../0.5.1/html/index.html - -.. _0.5.2: ../../0.5.2/html/index.html - -.. _0.5.3: ../../0.5.3/html/index.html -.. _0.6.0: ../../0.6.0/html/index.html - -.. _0.7.0: ../../0.7.0/html/index.html - -.. _0.7.1: ../../0.7.1/html/index.html -.. _0.7.2: ../../0.7.2/html/index.html - -.. _0.7.6: ../../0.7.6/html/index.html - -.. _0.7.7: ../../0.7.7/html/index.html - -.. _0.7.8: ../../0.7.8/html/index.html - -.. _0.7.9: ../../0.7.9/html/index.html - -.. _0.7.10: ../../0.7.10/html/index.html - -.. _0.7.11: ../../0.7.11/html/index.html - -.. _0.8.0: ../../0.8.0/html/index.html - -.. _0.8.1: ../../0.8.1/html/index.html - -.. _0.8.2: ../../0.8.2/html/index.html - -.. _0.8.3: ../../0.8.3/html/index.html - -.. _0.8.4: ../../0.8.4/html/index.html - -.. _0.8.5: ../../0.8.5/html/index.html - -.. _0.8.6: ../../0.8.6/html/index.html - -.. _0.8.7: ../../0.8.7/html/index.html - -.. _0.8.8: ../../0.8.8/html/index.html - -.. _0.8.9: ../../0.8.9/html/index.html - -.. _0.9.0: ../../0.9.0/html/index.html - -.. _0.10.0: ../../0.10.0/html/index.html - -.. _0.10.1: ../../0.10.1/html/index.html - -.. _0.10.2: ../../0.10.2/html/index.html - -.. _0.10.3: ../../0.10.3/html/index.html - -.. _0.10.4: ../../0.10.4/html/index.html - -.. _0.10.5: ../../0.10.5/html/index.html - -.. _0.10.6: ../../0.10.6/html/index.html - -.. _0.10.7: ../../0.10.7/html/index.html - -.. _0.10.8: ../../0.10.8/html/index.html - -.. _0.10.9: ../../0.10.9/html/index.html - -.. _0.11.0: ../../0.11.0/html/index.html - -.. _0.12.0: ../../0.12.0/html/index.html From 5a1ee0afc842ba74a0627dd5d8137b6cb9102c7a Mon Sep 17 00:00:00 2001 From: Shania Mahmud <92530831+shania-m@users.noreply.github.com> Date: Wed, 30 Jul 2025 12:22:29 -0400 Subject: [PATCH 09/14] chore: Workflow permissions (#1182) * chore: permissions for publish-docs --- .github/workflows/publish-docs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 764a2d168..546cb42c3 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -11,6 +11,9 @@ on: jobs: build-and-deploy: runs-on: ubuntu-latest + permissions: + contents: write + pages: write defaults: run: shell: bash -l {0} From 1a844301f3ba970c22e0943ac97d2547afa04c80 Mon Sep 17 00:00:00 2001 From: Mohammad Motamedi <32690690+mhmotamedi@users.noreply.github.com> Date: Wed, 30 Jul 2025 11:51:41 -0700 Subject: [PATCH 10/14] docs: add architecture.rst for algorithm rationale, testing, versioning (#1181) * docs: add architecture.rst for algorithm rationale, testing, and versioning details * docs: remove manual table of contents from architecture.rst for Furo compatibility and edit content --- _docs/docs/source/architecture.rst | 48 ++++++++++++++++++++++++++++++ _docs/docs/source/index.rst | 1 + 2 files changed, 49 insertions(+) create mode 100644 _docs/docs/source/architecture.rst diff --git a/_docs/docs/source/architecture.rst b/_docs/docs/source/architecture.rst new file mode 100644 index 000000000..469308993 --- /dev/null +++ b/_docs/docs/source/architecture.rst @@ -0,0 +1,48 @@ +.. _architecture: + +Architecture & Design Overview +****************************** + +This section describes the design rationale, algorithmic choices, assumptions, testing strategy, and contribution process used in the DataProfiler library. + +Overview +-------- + +DataProfiler computes numeric statistics (e.g., mean, variance, skewness, kurtosis) using **streaming algorithms** that allow efficient, incremental updates without recomputing from raw data. Approximate quantile metrics like the median are calculated using histogram-based estimation, making the system scalable for large or streaming datasets. + +Additionally, DataProfiler uses a **Convolutional Neural Network (CNN)** to detect and label entities (e.g., names, emails, credit cards) in unstructured text. This supports critical tasks such as **PII detection**, **schema inference**, and **data quality analysis** across structured and unstructured data. + +Algorithm Rationale +------------------- + +The algorithms used are designed for **speed, scalability, and flexibility**: + +- **Streaming numeric methods** (e.g., Welford's algorithm, moment-based metrics, histogram binning) efficiently summarize data without full recomputation. +- **CNNs for entity detection** are fast, high-throughput, and well-suited for sequence labeling tasks in production environments. + +These choices align with the tool's goal of delivering fast, accurate data profiling with minimal configuration. + +Assumptions & Limitations +------------------------- + +- **Consistent formatting** of sensitive entities is assumed (e.g., standardized credit card or SSN formats). +- **Overlapping entity types** (e.g., phone vs. SSN) may lead to misclassification without context. +- **Synthetic training data** may not fully capture real-world diversity, reducing model accuracy on natural or unstructured text. +- **Quantile estimation** (e.g., median) is approximate and based on binning rather than exact sorting. + +Testing & Validation +-------------------- + +- Comprehensive **unit testing** is performed across Python 3.9, 3.10, and 3.11. +- Tests are executed on every pull request targeting `dev` or `main` branches. +- All pull requests require **two code reviewer approvals** before merging. +- Testing includes correctness, performance, and compatibility checks to ensure production readiness. + +Versioning & Contributions +-------------------------- + +- Versioning and development are managed via **GitHub**. +- Future changes must follow the guidelines in `CONTRIBUTING.md`, including: + - Forking the repo and branching from `dev` or an active feature branch. + - Ensuring **80%+ unit test coverage** for all new functionality. + - Opening a PR and securing **two approvals** prior to merging. diff --git a/_docs/docs/source/index.rst b/_docs/docs/source/index.rst index 735f4fe38..8225be28f 100644 --- a/_docs/docs/source/index.rst +++ b/_docs/docs/source/index.rst @@ -451,6 +451,7 @@ In addition, it utilizes only the first 10,000 rows. profiler.rst data_labeling.rst graphs.rst + architecture.rst .. toctree:: :maxdepth: 2 From c035a05c1759e5da72ae663ba57c54f2cb3d7acd Mon Sep 17 00:00:00 2001 From: Ryan Soley Date: Thu, 18 Sep 2025 14:02:18 -0400 Subject: [PATCH 11/14] ops: drop python 3.9 & resolve vulns (#1192) * ops: drop python 3.9 (EOL) * ops: add whitesource config * fix: don't add python 3.12 yet * ops: add whitesource config to MANIFEST * fix: remove `--forked` to fix coverage * fix: remove tests that depend on `--forked` * ops: update vulnerable libraries --- .github/workflows/publish-docs.yml | 2 +- .github/workflows/test-package.yml | 4 ++-- MANIFEST.in | 1 + dataprofiler/tests/test_data_profiler.py | 2 -- dataprofiler/tests/test_dp_logging.py | 6 ------ requirements.txt | 6 +++--- setup.py | 2 +- tox.ini | 2 +- whitesource.config | 2 ++ 9 files changed, 11 insertions(+), 16 deletions(-) create mode 100644 whitesource.config diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml index 546cb42c3..74dd68dd9 100644 --- a/.github/workflows/publish-docs.yml +++ b/.github/workflows/publish-docs.yml @@ -25,7 +25,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.9' + python-version: '3.11' - name: Install pandoc uses: pandoc/actions/setup@v1 - name: Install dependencies diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml index dda103be7..47416a938 100644 --- a/.github/workflows/test-package.yml +++ b/.github/workflows/test-package.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.9, "3.10", "3.11"] + python-version: ["3.10", "3.11"] steps: - uses: actions/checkout@v4 @@ -36,4 +36,4 @@ jobs: pre-commit run --all-files - name: Test with pytest run: | - DATAPROFILER_SEED=0 pytest --forked --cov=dataprofiler --cov-fail-under=80 + DATAPROFILER_SEED=0 pytest --cov=dataprofiler --cov-fail-under=80 diff --git a/MANIFEST.in b/MANIFEST.in index e9f8fa9b6..6cb4c1844 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -20,6 +20,7 @@ recursive-include resources *.py recursive-include dataprofiler/labelers/embeddings *.txt include versioneer.py include dataprofiler/_version.py +include whitesource.config recursive-exclude _docs *.html recursive-exclude _docs *.cfg diff --git a/dataprofiler/tests/test_data_profiler.py b/dataprofiler/tests/test_data_profiler.py index 9ebdfa039..5dd12e69d 100644 --- a/dataprofiler/tests/test_data_profiler.py +++ b/dataprofiler/tests/test_data_profiler.py @@ -29,8 +29,6 @@ def setUpClass(cls): def test_set_seed(self): import dataprofiler as dp - self.assertEqual(dp.settings._seed, None) - dp.set_seed(5) self.assertEqual(dp.settings._seed, 5) diff --git a/dataprofiler/tests/test_dp_logging.py b/dataprofiler/tests/test_dp_logging.py index 7f78903ee..99496e314 100644 --- a/dataprofiler/tests/test_dp_logging.py +++ b/dataprofiler/tests/test_dp_logging.py @@ -22,12 +22,6 @@ def tearDownClass(cls): root_logger.removeHandler(dp_logging.get_logger()) dp_logging._dp_logger = None - def test_default_verbosity(self, mock_stdout): - # Ensure that default effective level is INFO - self.assertEqual( - logging.INFO, logging.getLogger("DataProfiler").getEffectiveLevel() - ) - def test_set_verbosity(self, mock_stdout): from dataprofiler import dp_logging diff --git a/requirements.txt b/requirements.txt index 0530826f2..e32f32851 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,12 +11,12 @@ python-snappy>=0.7.1 charset-normalizer>=1.3.6 psutil>=4.0.0 scipy>=1.10.0 -requests==2.32.* +requests>=2.32.4 networkx>=2.5.1 typing-extensions>=3.10.0.2 HLL>=2.0.3 datasketches>=4.1.0 packaging>=23.0 -boto3>=1.28.61 +boto3>=1.37.15 +urllib3>=2.5.0 versioneer -# adding comment to trigger mend check diff --git a/setup.py b/setup.py index f0c8c7a81..f1f799446 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ name="DataProfiler", version=versioneer.get_version(), cmdclass=versioneer.get_cmdclass(), - python_requires=">=3.9", + python_requires=">=3.10", description=DESCRIPTION, long_description=LONG_DESCRIPTION, long_description_content_type="text/markdown", diff --git a/tox.ini b/tox.ini index 4ee6081bd..caf70d437 100644 --- a/tox.ini +++ b/tox.ini @@ -16,7 +16,7 @@ deps = -rrequirements-reports.txt -rrequirements-test.txt commands = - python3 -m pytest dataprofiler/tests/ --cov=dataprofiler --cov-fail-under=80 --cov-report=xml:coverage.xml --forked + python3 -m pytest dataprofiler/tests/ --cov=dataprofiler --cov-fail-under=80 --cov-report=xml:coverage.xml # add "docs" to `envlist` to run the docs build #[testenv:docs] diff --git a/whitesource.config b/whitesource.config new file mode 100644 index 000000000..1cfbc1b13 --- /dev/null +++ b/whitesource.config @@ -0,0 +1,2 @@ +python.path=python3.11 +python.pipPath=pip3.11 From ebb7ee177a04f593efda7f640c9f74a66293faad Mon Sep 17 00:00:00 2001 From: Ryan Soley Date: Mon, 22 Sep 2025 16:13:09 -0400 Subject: [PATCH 12/14] ops: properly configure whitesource (#1195) * ops: properly configure whitesource * ops: add whitesource config to MANIFEST --- .whitesource | 3 +++ MANIFEST.in | 2 +- whitesource.config | 2 -- 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 .whitesource delete mode 100644 whitesource.config diff --git a/.whitesource b/.whitesource new file mode 100644 index 000000000..5187a171c --- /dev/null +++ b/.whitesource @@ -0,0 +1,3 @@ +{ + "settingsInheritedFrom": "capitalone/whitesource-config@python311" +} diff --git a/MANIFEST.in b/MANIFEST.in index 6cb4c1844..3f426b7bb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -20,7 +20,7 @@ recursive-include resources *.py recursive-include dataprofiler/labelers/embeddings *.txt include versioneer.py include dataprofiler/_version.py -include whitesource.config +include .whitesource recursive-exclude _docs *.html recursive-exclude _docs *.cfg diff --git a/whitesource.config b/whitesource.config deleted file mode 100644 index 1cfbc1b13..000000000 --- a/whitesource.config +++ /dev/null @@ -1,2 +0,0 @@ -python.path=python3.11 -python.pipPath=pip3.11 From 5a381d50cd7de754717c6b4be948e24001cbfabb Mon Sep 17 00:00:00 2001 From: Ryan Soley Date: Fri, 26 Sep 2025 10:47:41 -0400 Subject: [PATCH 13/14] fix: use core config (#1198) --- .whitesource | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.whitesource b/.whitesource index 5187a171c..37dfa8e25 100644 --- a/.whitesource +++ b/.whitesource @@ -1,3 +1,3 @@ { - "settingsInheritedFrom": "capitalone/whitesource-config@python311" + "settingsInheritedFrom": "capitalone/whitesource-config" } From 60256a3f435870a0e0162f618ed72e66d456fda1 Mon Sep 17 00:00:00 2001 From: Hashwanth Sutharapu Date: Mon, 19 Jan 2026 18:30:52 -0800 Subject: [PATCH 14/14] fix: rename TestColumn classes to MockColumn to fix pytest warnings Fixes #1147 Pytest was generating collection warnings because helper classes named TestColumn and TestColumnWProps were being detected as test classes due to their 'Test' prefix, but failed collection because they have __init__ constructors. This commit renames: - TestColumn -> MockColumn - TestColumnWProps -> MockColumnWProps This makes it clear these are mock/helper classes, not test classes, and eliminates the pytest collection warnings. --- .../tests/profilers/test_histogram_utils.py | 22 +++--- .../test_numeric_stats_mixin_profile.py | 70 +++++++++---------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/dataprofiler/tests/profilers/test_histogram_utils.py b/dataprofiler/tests/profilers/test_histogram_utils.py index 3be8cdcae..10c88b344 100644 --- a/dataprofiler/tests/profilers/test_histogram_utils.py +++ b/dataprofiler/tests/profilers/test_histogram_utils.py @@ -32,7 +32,7 @@ def mock_sqrt_return_nan(profile): return float("nan") -class TestColumn(NumericStatsMixin): +class MockColumn(NumericStatsMixin): def __init__(self): NumericStatsMixin.__init__(self) self.times = defaultdict(float) @@ -75,7 +75,7 @@ def test_ptp(self): def test_calc_doane_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() with mock.patch( "dataprofiler.profilers.NumericStatsMixin.stddev", new_callable=mock_stddev @@ -177,7 +177,7 @@ def test_calc_doane_bin_width_from_profile(self): def test_calc_rice_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() # Case 1: min, max, and match_count are set expected_dataset_size = profile.match_count @@ -230,7 +230,7 @@ def test_calc_rice_bin_width_from_profile(self): def test_calc_sturges_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() # Case 1: min, max, and match_count are set expected_dataset_size = profile.match_count @@ -283,7 +283,7 @@ def test_calc_sturges_bin_width_from_profile(self): def test_calc_sqrt_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() # Case 1: min, max, and match_count are set expected_dataset_size = profile.match_count @@ -336,7 +336,7 @@ def test_calc_sqrt_bin_width_from_profile(self): def test_calc_fd_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() with mock.patch( "dataprofiler.profilers.NumericStatsMixin._get_percentile", @@ -359,7 +359,7 @@ def test_calc_fd_bin_width_from_profile(self): def test_calc_auto_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() with mock.patch( "dataprofiler.profilers.histogram_utils._calc_fd_bin_width_from_profile" @@ -396,7 +396,7 @@ def test_calc_auto_bin_width_from_profile(self): def test_calc_scott_bin_width_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() with mock.patch( "dataprofiler.profilers.NumericStatsMixin.stddev", new_callable=mock_stddev @@ -418,7 +418,7 @@ def test_calc_scott_bin_width_from_profile(self): def test_calculate_bins_from_profile(self): # Initial setup of profile - profile = TestColumn() + profile = MockColumn() # Case 1: bin method not in set of valid bin methods with self.assertRaises(ValueError): @@ -457,7 +457,7 @@ def test_calculate_bins_from_profile(self): dataprofiler.profilers.histogram_utils._hist_bin_width_selectors_for_profile, {"sqrt": mock_sqrt_return_none}, ): - profile = TestColumn() + profile = MockColumn() actual = histogram_utils._calculate_bins_from_profile(profile, "sqrt") self.assertEqual(1, actual) @@ -466,6 +466,6 @@ def test_calculate_bins_from_profile(self): dataprofiler.profilers.histogram_utils._hist_bin_width_selectors_for_profile, {"sqrt": mock_sqrt_return_nan}, ): - profile = TestColumn() + profile = MockColumn() actual = histogram_utils._calculate_bins_from_profile(profile, "sqrt") self.assertEqual(1, actual) diff --git a/dataprofiler/tests/profilers/test_numeric_stats_mixin_profile.py b/dataprofiler/tests/profilers/test_numeric_stats_mixin_profile.py index e112781ab..cac04bfc9 100644 --- a/dataprofiler/tests/profilers/test_numeric_stats_mixin_profile.py +++ b/dataprofiler/tests/profilers/test_numeric_stats_mixin_profile.py @@ -18,7 +18,7 @@ test_root_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -class TestColumn(NumericStatsMixin): +class MockColumn(NumericStatsMixin): def __init__(self): NumericStatsMixin.__init__(self) self.match_count = 0 @@ -31,7 +31,7 @@ def _filter_properties_w_options(self, calculations, options): pass -class TestColumnWProps(TestColumn): +class MockColumnWProps(MockColumn): # overrides the property func median = None mode = None @@ -117,9 +117,9 @@ def test_check_int(self): def test_hist_loss_on_merge(self): # Initial setup of profiles - profile3 = TestColumn() - profile1 = TestColumn() - profile2 = TestColumn() + profile3 = MockColumn() + profile1 = MockColumn() + profile2 = MockColumn() mock_histogram1 = { "bin_counts": np.array([1, 1, 1, 1]), "bin_edges": np.array([2, 4, 6, 8, 10]), @@ -161,7 +161,7 @@ def test_update_variance(self): Checks update variance :return: """ - num_profiler = TestColumn() + num_profiler = MockColumn() # test update variance data1 = [-3.0, 2.0, 11.0] @@ -209,7 +209,7 @@ def test_update_variance_with_varying_data_length(self): data1 = [] mean1, var1, count1 = 0, np.nan, 0 - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler._biased_variance = num_profiler._update_variance( mean1, var1, count1 ) @@ -221,7 +221,7 @@ def test_update_variance_with_varying_data_length(self): data2 = [5.0] mean2, var2, count2 = 5.0, 0, 1 - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler._biased_variance = num_profiler._update_variance( mean2, var2, count2 ) @@ -239,7 +239,7 @@ def test_update_variance_with_varying_data_length(self): + (-11.0 - mean3) ** 2 ) / 3 - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler._biased_variance = num_profiler._update_variance( mean3, var3 * 3 / 4, count3 ) @@ -252,7 +252,7 @@ def test_update_variance_with_empty_data(self): Checks update variance :return: """ - num_profiler = TestColumn() + num_profiler = MockColumn() data1 = [-3.0, 2.0, 11.0] mean1 = (-3.0 + 2.0 + 11.0) / 3 @@ -284,7 +284,7 @@ def test_timeit_merge(self): Checks profiles have been merged and timed :return: """ - num_profiler, other1, other2 = TestColumn(), TestColumn(), TestColumn() + num_profiler, other1, other2 = MockColumn(), MockColumn(), MockColumn() mock_histogram = { "bin_counts": np.array([1, 1, 1, 1]), "bin_edges": np.array([2.0, 5.25, 8.5, 11.75, 15.0]), @@ -331,7 +331,7 @@ def test_timeit(self): Checks stat properties have been timed :return: """ - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data to make min call prev_dependent_properties = { @@ -402,8 +402,8 @@ def test_from_dict_helper(self): fake_profile_name = "Fake profile name" # Build expected CategoricalColumn - actual_profile = TestColumn() - expected_profile = TestColumn() + actual_profile = MockColumn() + expected_profile = MockColumn() mock_saved_profile = dict( { "quantiles": None, @@ -429,7 +429,7 @@ def test_from_dict_helper(self): test_utils.assert_profiles_equal(expected_profile, actual_profile) def test_histogram_bin_error(self): - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data for calculating bin error num_profiler._stored_histogram = { @@ -475,7 +475,7 @@ def test_histogram_bin_error(self): assert sum_error == np.inf def test_get_best_histogram_profile(self): - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler._histogram_for_profile = mock.MagicMock( side_effect=[("hist_1", 3), ("hist_2", 2), ("hist_3", 1)] @@ -509,7 +509,7 @@ def test_get_best_histogram_profile(self): assert best_histogram == "hist_3" def test_get_best_histogram_profile_infinite_loss(self): - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler._histogram_for_profile = mock.MagicMock(return_value=("hist_1", 3)) @@ -529,7 +529,7 @@ def test_get_best_histogram_profile_infinite_loss(self): assert best_histogram == "hist_1" def test_get_percentile_median(self): - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data for calculating bin error num_profiler._stored_histogram = { "histogram": { @@ -541,7 +541,7 @@ def test_get_percentile_median(self): self.assertListEqual([10, 10], median) def test_num_zeros(self): - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data to make num_zeros call prev_dependent_properties = {"mean": 0} @@ -568,7 +568,7 @@ def test_num_zeros(self): self.assertEqual(subset_properties["num_zeros"], 4) def test_num_negatives(self): - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data to make num_negatives call prev_dependent_properties = {"mean": 0} @@ -595,7 +595,7 @@ def test_num_negatives(self): self.assertEqual(subset_properties["num_negatives"], 4) def test_fold_histogram(self): - num_profiler = TestColumn() + num_profiler = MockColumn() # the break point is at the mid point of a bin bin_counts = np.array([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]) @@ -670,7 +670,7 @@ def test_timeit_num_zeros_and_negatives(self): Checks num_zeros and num_negatives have been timed :return: """ - num_profiler = TestColumn() + num_profiler = MockColumn() # Dummy data to make min call prev_dependent_properties = {"mean": 0} @@ -702,14 +702,14 @@ def test_merge_num_zeros_and_negatives(self): Checks num_zeros and num_negatives can be merged :return: """ - num_profiler, other1, other2 = TestColumn(), TestColumn(), TestColumn() + num_profiler, other1, other2 = MockColumn(), MockColumn(), MockColumn() other1.num_zeros, other1.num_negatives = 3, 1 other2.num_zeros, other2.num_negatives = 7, 1 num_profiler._add_helper(other1, other2) self.assertEqual(num_profiler.num_zeros, 10) self.assertEqual(num_profiler.num_negatives, 2) - num_profiler, other1, other2 = TestColumn(), TestColumn(), TestColumn() + num_profiler, other1, other2 = MockColumn(), MockColumn(), MockColumn() other1.num_zeros, other1.num_negatives = 0, 0 other2.num_zeros, other2.num_negatives = 0, 0 num_profiler._add_helper(other1, other2) @@ -717,7 +717,7 @@ def test_merge_num_zeros_and_negatives(self): self.assertEqual(num_profiler.num_negatives, 0) def test_profile(self): - num_profiler = TestColumn() + num_profiler = MockColumn() mock_profile = dict( min=1.0, @@ -815,7 +815,7 @@ def test_report(self): self.assertIn(disabled_key, report_keys) def test_report_no_numerical_options(self): - num_profiler = TestColumn() + num_profiler = MockColumn() num_profiler.match_count = 0 num_profiler.times = defaultdict(float) @@ -833,7 +833,7 @@ def test_diff(self): Checks _diff_helper() works appropriately. """ - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.min = 3 other1.max = 4 other1._biased_variance = 1 @@ -881,7 +881,7 @@ def test_diff(self): self.assertDictEqual(expected_diff, difference) # Invalid statistics - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.min = 3 other1.max = 4 other1._biased_variance = np.nan # NaN variance @@ -931,7 +931,7 @@ def test_diff(self): self.assertTrue(np.isnan([expected_var, var, expected_stddev, stddev]).all()) # Insufficient match count - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.min = 3 other1.max = 4 other1._biased_variance = 1 @@ -980,7 +980,7 @@ def test_diff(self): self.assertTrue(np.isnan([expected_var, var, expected_stddev, stddev]).all()) # Constant values - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.min = 3 other1.max = 4 other1._biased_variance = 0 # constant value has 0 variance @@ -1028,7 +1028,7 @@ def test_diff(self): self.assertDictEqual(expected_diff, difference) # Small p-value - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.min = 3 other1.max = 4 other1._biased_variance = 1 @@ -1075,11 +1075,11 @@ def test_diff(self): other1.diff("Inproper input") self.assertEqual( str(exc.exception), - "Unsupported operand type(s) for diff: 'TestColumnWProps' and" " 'str'", + "Unsupported operand type(s) for diff: 'MockColumnWProps' and" " 'str'", ) # PSI same distribution test - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.match_count = 55 other1._stored_histogram = { "total_loss": 0, @@ -1112,7 +1112,7 @@ def test_diff(self): self.assertEqual(expected_psi_value, psi_value) # PSI min_min_edge == max_max_edge - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.match_count = 10 other1._stored_histogram = { "total_loss": 0, @@ -1139,7 +1139,7 @@ def test_diff(self): self.assertEqual(expected_psi_value, psi_value) # PSI regen other / not self - other1, other2 = TestColumnWProps(), TestColumnWProps() + other1, other2 = MockColumnWProps(), MockColumnWProps() other1.match_count = 55 other1._stored_histogram = { "total_loss": 0,