diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8d3d9da --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +/legacy +*.pyc +Results/* +ex_Fuzzy.egg-info/* +build/* +*.gexf +*.log +checkpoint* diff --git a/Demos/.Rhistory b/Demos/.Rhistory new file mode 100644 index 0000000..e69de29 diff --git a/Demos/iris_demo.py b/Demos/iris_demo.py new file mode 100644 index 0000000..9cca0d8 --- /dev/null +++ b/Demos/iris_demo.py @@ -0,0 +1,71 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" + + +import pandas as pd + +from sklearn import datasets +from sklearn.model_selection import train_test_split + +import sys + +# In case yo urun this without installing the package, you need to add the path to the package +sys.path.append('./ex_fuzzy/') +sys.path.append('../ex_fuzzy/') + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools +import ex_fuzzy.persistence as persistence +import ex_fuzzy.vis_rules as vis_rules + + +runner = 1 # 1: single thread, 2+: corresponding multi-thread + +n_gen = 30 +n_pop = 50 + +nRules = 15 +nAnts = 4 +vl = 3 +tolerance = 0.01 +fz_type_studied = fs.FUZZY_SETS.t2 + +# Import some data to play with +iris = datasets.load_iris() +X = pd.DataFrame(iris.data, columns=iris.feature_names) +y = iris.target + +# Compute the fuzzy partitions using 3 quartiles +precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +# Split the data into a training set and a test set +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +# We create a FRBC with the precomputed partitions and the specified fuzzy set type, +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=True, tolerance=tolerance, runner=runner) +# fl_classifier.customized_loss(utils.mcc_loss) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1) +print(vis_rules.rules_to_latex(fl_classifier.rule_base)) +str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) + +# Save the rules as a plain text file +with open('rules_iris_t2.txt', 'w') as f: + f.write(str_rules) + +print('Done') \ No newline at end of file diff --git a/Demos/iris_demo_advanced_classifiers.py b/Demos/iris_demo_advanced_classifiers.py new file mode 100644 index 0000000..97633cb --- /dev/null +++ b/Demos/iris_demo_advanced_classifiers.py @@ -0,0 +1,84 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" + + +import pandas as pd + +from sklearn import datasets +from sklearn.model_selection import train_test_split + +import sys + +# In case yo urun this without installing the package, you need to add the path to the package +sys.path.append('./ex_fuzzy/') +sys.path.append('../ex_fuzzy/') + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools +import ex_fuzzy.persistence as persistence +import ex_fuzzy.vis_rules as vis_rules +import ex_fuzzy.classifiers as classifiers + + +threads = 1 # 1: single thread, 2+: corresponding multi-thread + +n_gen = 100 +n_pop = 50 + +nRules = 15 +nAnts = 4 +vl = 3 +tolerance = 0.1 +fz_type_studied = fs.FUZZY_SETS.t1 + +# Import some data to play with +iris = datasets.load_iris() +X = pd.DataFrame(iris.data, columns=iris.feature_names) +y = iris.target + +# Compute the fuzzy partitions using 3 quartiles +precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +# Split the data into a training set and a test set +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +# Create the RuleMine classifier +fl_classifier = classifiers.RuleMineClassifier(nRules=nRules, nAnts=nAnts, fuzzy_type=fz_type_studied, linguistic_variables=precomputed_partitions, + verbose=True, tolerance=tolerance, runner=threads) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop) + +str_rules = eval_tools.eval_fuzzy_model(fl_classifier.internal_classifier(), X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False, return_rules=True) + +# Create the FuzzyRules classifier +fl_classifier = classifiers.FuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, fuzzy_type=fz_type_studied, linguistic_variables=precomputed_partitions, + verbose=True, tolerance=tolerance, runner=threads) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop) + +str_rules = eval_tools.eval_fuzzy_model(fl_classifier.internal_classifier(), X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False, return_rules=True) + + +# Create the RuleFineTuneClassifier classifier +fl_classifier = classifiers.RuleFineTuneClassifier(nRules=nRules, nAnts=nAnts, fuzzy_type=fz_type_studied, linguistic_variables=precomputed_partitions, + verbose=True, tolerance=tolerance, runner=threads) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop) + +str_rules = eval_tools.eval_fuzzy_model(fl_classifier.internal_classifier(), X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False, return_rules=True) + +print('Done') \ No newline at end of file diff --git a/Demos/iris_demo_custom_loss.py b/Demos/iris_demo_custom_loss.py new file mode 100644 index 0000000..fd7505c --- /dev/null +++ b/Demos/iris_demo_custom_loss.py @@ -0,0 +1,146 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" +import sys +sys.path.append('./ex_fuzzy/') +import numpy as np +import ex_fuzzy.rules as rules +import ex_fuzzy.eval_rules as evr +import matplotlib.pyplot as plt + + +epsilon = [0, 10E-3, 50E-3, 10E-2, 50E-2] + + +def new_loss(ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.99, beta:float=0.0125, gamma:float=0.0125) -> float: + + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + def subloss(ruleBase1, X1, y1, epsilon_val): + + X1 = X1 + epsilon_val * np.random.uniform(-1, 1, X1.shape) + ev_object = evr.evalRuleBase(ruleBase1, X1, y1) + ev_object.add_rule_weights() + + score_acc = ev_object.classification_eval() + score_size = ev_object.effective_rulesize_eval(tolerance) + beta = 1 - alpha + + score = score_acc * alpha + score_size * beta + + return score + + epsilon_list = [0, 10E-3, 50E-3, 10E-2, 50E-2] + weights = np.array([1 / len(epsilon_list)] * len(epsilon_list))**2 + weights = weights / np.sum(weights) + + score_pondered = 0 + for epsilon, weight in zip(epsilon_list, weights): + score = subloss(ruleBase, X, y, epsilon) + score_pondered += score * weight + + return score_pondered + + + +import pandas as pd + +from sklearn import datasets +from sklearn.model_selection import train_test_split + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools + +try: + n_gen = int(sys.argv[1]) + n_pop = int(sys.argv[2]) +except: + n_gen = 50 + n_pop = 30 + nRules = 4 + nAnts = 4 + vl = 3 + tolerance = 0.0001 + fz_type_studied = fs.FUZZY_SETS.t2 + + +# import some data to play with +iris = datasets.load_iris() +X = pd.DataFrame(iris.data, columns=iris.feature_names) +y = iris.target + +def load_occupancy(path='./demos/occupancy_data/'): + train_data = pd.read_csv(path + 'datatraining.txt', index_col=0) + X_train = train_data[['Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_train = np.squeeze(train_data[['Occupancy']].values) + + test_data = pd.read_csv(path + 'datatest2.txt', index_col=0) + X_test = test_data[['Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_test = np.squeeze(test_data[['Occupancy']].values) + + return X_train, y_train, X_test, y_test + +X_train, y_train, X_test, y_test = load_occupancy() + +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) +X = np.concatenate((X_train, X_test), axis=0) +precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +# Standard loss experiments +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=False, tolerance=tolerance) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop) + +eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False) + +og_accs = [] +for eps in epsilon: + X1 = X_test + eps * np.random.uniform(-1, 1, X_test.shape) + og_accs.append(np.mean(np.equal(fl_classifier.predict(X1), y_test))) + + +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=False, tolerance=tolerance) +fl_classifier.customized_loss(new_loss) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop) + +eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False) + + +accs = [] +for eps in epsilon: + X1 = X_test + eps * np.random.uniform(-1, 1, X_test.shape) + accs.append(np.mean(np.equal(fl_classifier.predict(X1), y_test))) + + +plt.figure() +plt.plot(epsilon, og_accs) +plt.plot(epsilon, accs) +plt.ylim(0, 1) +plt.legend(['Original Fitness', 'Epsilon Fitness']) +plt.xlabel('Epsilon') +plt.ylabel('Accuracy') +plt.title('Accuracy vs Epsilon') +plt.savefig('iris_epsilon_t2.pdf') +print('Done') \ No newline at end of file diff --git a/Demos/iris_demo_notebook.ipynb b/Demos/iris_demo_notebook.ipynb new file mode 100644 index 0000000..ed08ec6 --- /dev/null +++ b/Demos/iris_demo_notebook.ipynb @@ -0,0 +1,189 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 9, + "id": "b124910b", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import sys\n", + "sys.path.append('./ex_fuzzy/')\n", + "sys.path.append('../ex_fuzzy/')\n", + "\n", + "from sklearn import datasets\n", + "from sklearn.model_selection import train_test_split\n", + "\n", + "import ex_fuzzy.fuzzy_sets as fs\n", + "import ex_fuzzy.evolutionary_fit as GA\n", + "import ex_fuzzy.utils as utils\n", + "import ex_fuzzy.eval_tools as eval_tools" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "f9cd5125", + "metadata": {}, + "outputs": [], + "source": [ + "# Choose the parameters for the genetic algorithm\n", + "n_gen = 50\n", + "n_pop = 30\n", + "\n", + "# Max number of rules and max number of antecedents per rule\n", + "nRules = 15\n", + "nAnts = 4\n", + "\n", + "# Number of linguistic variables to use in the fuzzy variables\n", + "vl = 3\n", + "\n", + "# Tolerance for the dominance score for each rule\n", + "tolerance = 0.01\n", + "\n", + "# Type of dataset used\n", + "fz_type_studied = fs.FUZZY_SETS.gt2 # Also t2, gt2" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b5ec47a9", + "metadata": {}, + "outputs": [], + "source": [ + "# Load the iris dataset\n", + "iris = datasets.load_iris()\n", + "X = pd.DataFrame(iris.data, columns=iris.feature_names)\n", + "y = iris.target" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "c67beaed", + "metadata": {}, + "outputs": [], + "source": [ + "# Split in train and test\n", + "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "67cc0b71", + "metadata": {}, + "outputs": [], + "source": [ + "# Compute the linguistic vatiables\n", + "precomputed_partitions = utils.construct_partitions(X, fz_type_studied)\n", + "\n", + "# Create and fit the FRB classifier using a genetic algorithm\n", + "fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, \n", + " n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=False, tolerance=tolerance)\n", + "fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e165f460", + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "------------\n", + "ACCURACY\n", + "Train performance: 0.84\n", + "Test performance: 0.74\n", + "------------\n", + "MATTHEW CORRCOEF\n", + "Train performance: 0.7814353363244656\n", + "Test performance: 0.6790830119639542\n", + "------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\javi-\\OneDrive\\Documentos\\GitHub\\exFuzzy\\Demos\\../ex_fuzzy\\ex_fuzzy\\vis_rules.py:268: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.\n", + " fig.show()\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiQAAAGxCAYAAABSsK0dAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABfyUlEQVR4nO3deXgUZdo2/LPTnX0jC9kgK0QWQcAAsgdICBLkmRlnRkZBQMFHXhQFxo1xQ8aRT19HeRTB8RFERgbxVccZICwJkLCLYGBkESEL2QkJkBWy1vdHUZ00WTvp7lr6/B1Hjq5UV1ddZWFy5b7uRScIggAiIiIiGTnIHQARERERExIiIiKSHRMSIiIikh0TEiIiIpIdExIiIiKSHRMSIiIikh0TEiIiIpIdExIiIiKSHRMSIiIikh0TEiLCihUroNPpLHacrSQlJWHFihWtvqfT6fD000936/wHDx6Es7MzLl++3K3zmGv9+vXo1asXqqqqbHpdIjkxISEi1UpKSsIbb7xhlXMLgoAlS5bgiSeeQHh4uFWu0Za5c+fC3d0d77zzjk2vSyQnJiRERK3YtWsXfvzxRyxevNjm1zYYDHjyySfxP//zP6iurrb59YnkwISEyAauXr2K//7v/0ZoaCicnZ3Rs2dPjB07FikpKSbHpaSkIC4uDl5eXnBzc8PYsWOxd+9ek2Okskl6ejoefPBBeHl5wdvbG7Nnz8bVq1dNjt26dSsSEhIQHBwMV1dXDBgwAC+99JLFSwFbt27F6NGj4e7uDg8PD0ydOhXp6ekmx8ybNw8eHh64dOkSEhMT4eHhgdDQUPzxj39ETU2NybF5eXn43e9+B09PT/To0QOzZs3CDz/8AJ1Oh40bNxrP99FHHwEQyzPSV3Z2tsm5/v73v2PAgAFwc3PDkCFDsH379k7d07p16zBixAj069evxXv/+Mc/MHr0aHh4eMDDwwNDhw7F+vXrje9PnDgRgwYNwtGjRzFmzBi4uroiIiICn332GQBgx44duPfee+Hm5obBgwdj165dLa4xa9YslJeX48svv+xUvERqx4SEyAYeffRRfPfdd3jttdewZ88efPrpp4iPj0dpaanxmC+++AIJCQnw8vLC559/jq+++gq+vr6YOnVqi6QEAH7zm9+gb9+++Prrr7FixQp89913mDp1Kurq6ozHXLx4EYmJiVi/fj127dqFJUuW4KuvvsKMGTMsdm9vvfUWHn74YQwcOBBfffUV/v73v6OiogLjx4/HuXPnTI6tq6vDf/3XfyEuLg7/+te/8Pjjj+P999/H22+/bTymqqoKkyZNwv79+/H222/jq6++QmBgIGbOnGlyrldffRW/+93vAABHjx41fgUHBxuP2bFjB9asWYOVK1fim2++ga+vL37zm98gMzOz3Xuqra1FSkoKJk2a1OK91157DbNmzUJISAg2btyIf/7zn5g7d26LfiZFRUV47LHHsGDBAvzrX//C4MGD8fjjj2PlypVYvnw5XnjhBXzzzTfw8PDAr3/9axQUFJh8PigoCP3798eOHTvajZVIMwQisjoPDw9hyZIlbb5fVVUl+Pr6CjNmzDDZ39DQIAwZMkQYOXKkcd/rr78uABCWLl1qcuzmzZsFAMIXX3zR6jUaGxuFuro6IS0tTQAgnD59usU5O3LncTk5OYLBYBAWL15sclxFRYUQFBQkPPTQQ8Z9c+fOFQAIX331lcmxiYmJQr9+/Yzff/TRRwIAYefOnSbHPfnkkwIA4bPPPjPue+qpp9qMG4AQGBgolJeXG/cVFRUJDg4OwqpVq9q9z++//14AIHz55Zcm+zMzMwW9Xi/MmjWr3c/HxsYKAIQTJ04Y95WWlgp6vV5wdXUV8vPzjftPnTolABA++OCDFueZNWuWEBgY2O61iLSCLSRENjBy5Ehs3LgRb775Jo4dO2bSigEAR44cwbVr1zB37lzU19cbvxobG3H//ffjhx9+aFFmmTVrlsn3Dz30EAwGA/bv32/cl5mZiUceeQRBQUHQ6/VwdHREbGwsAOD8+fPdvq/du3ejvr4ec+bMMYnbxcUFsbGxSE1NNTlep9O1aJ255557TFoX0tLS4Onpifvvv9/kuIcfftjs+CZNmgRPT0/j94GBgQgICOhw1IzUWhEQEGCyPzk5GQ0NDXjqqac6vHZwcDBiYmKM3/v6+iIgIABDhw5FSEiIcf+AAQMAoNWYAgICUFxcjPr6+g6vR6R2BrkDILIHW7duxZtvvolPP/0Ur776Kjw8PPCb3/wG77zzDoKCgnDlyhUAMJYgWnPt2jW4u7sbvw8KCjJ532AwwM/Pz1gGqqysxPjx4+Hi4oI333wTd911F9zc3JCbm4sHH3wQN2/e7PZ9SXGPGDGi1fcdHEz/5nFzc4OLi4vJPmdnZ9y6dcv4fWlpKQIDA1ucq7V9HfHz82uxz9nZucN7l96/M1apj07v3r07vLavr2+LfU5OTi32Ozk5AYDJfwOJi4sLBEHArVu34OHh0eE1idSMCQmRDfj7+2P16tVYvXo1cnJy8O9//xsvvfQSiouLsWvXLvj7+wMAPvzwQ4waNarVc9z5C7moqAi9evUyfl9fX4/S0lLjL+F9+/ahoKAAqampxlYRALhx44ZF7wsAvv76a4sNjfXz88Px48db7C8qKrLI+TtDuq9r166Z7O/ZsycAsdNtaGio1eO4du0anJ2dmYyQXWBCQmRjYWFhePrpp7F3714cPnwYADB27Fj06NED586d6/RkXps3bzYpCXz11Veor6/HxIkTAcA4gZmzs7PJ5/72t79Z4C5EU6dOhcFgQEZGBn77299a5JyxsbH46quvsHPnTkybNs24v7XRJtK93bx5E66urha5PtBURsnIyDDZn5CQAL1ej3Xr1mH06NEWu15bMjMzMXDgQKtfh0gJmJAQWVlZWRkmTZqERx55BP3794enpyd++OEH7Nq1Cw8++CAAwMPDAx9++CHmzp2La9eu4Xe/+x0CAgJw9epVnD59GlevXsW6detMzvvtt9/CYDBgypQpOHv2LF599VUMGTIEDz30EABgzJgx8PHxwcKFC/H666/D0dERmzdvxunTpy12bxEREVi5ciVefvllZGZm4v7774ePjw+uXLmC48ePw93d3eyJy+bOnYv3338fs2fPxptvvom+ffti586d2L17NwDTMtDgwYMBAG+//TamTZsGvV6Pe+65x1gG6arevXsjKioKx44dwzPPPGNyv3/605/w5z//GTdv3sTDDz8Mb29vnDt3DiUlJRadpK2xsRHHjx/H/PnzLXZOIiVjQkJkZS4uLrjvvvvw97//HdnZ2airq0NYWBhefPFFvPDCC8bjZs+ejbCwMLzzzjt48sknUVFRYewEOW/evBbn/fbbb7FixQqsW7fO2Fl09erVxl/Gfn5+2LFjB/74xz9i9uzZcHd3x69+9Sts3boV9957r8Xub/ny5Rg4cCD+53/+B1u2bEFNTQ2CgoIwYsQILFy40Ozzubu7Y9++fViyZAleeOEF6HQ6JCQkYO3atUhMTESPHj2Mxz7yyCM4fPgw1q5di5UrV0IQBGRlZSEiIqLb9zVr1iysWbMGNTU1Jq1MK1euRHR0ND788EPMmjULBoMB0dHRJomLJaSmpqKsrKxF52UirdIJgiDIHQQRdd6KFSvwxhtv4OrVq8a+DvbgrbfewiuvvIKcnJxOdSrtroKCAkRGRmLTpk0t5kCxhUcffRSZmZnGsh6R1rGFhIgUZ82aNQCA/v37o66uDvv27cMHH3yA2bNn2yQZAYCQkBAsWbIEf/nLX/D73/++xYgha8rIyMDWrVuxb98+m12TSG5MSIhIcdzc3PD+++8jOzsbNTU1xhLXK6+8YtM4XnnlFbi5uSE/P98mo2okOTk5WLNmDcaNG2ezaxLJjSUbIiIikh1naiUiIiLZMSEhIiIi2TEhISIiItmpolNrY2MjCgoK4OnpaZx9koiIiJRNEARUVFQgJCSkw5FqqkhICgoKbNrDnYiIiCwnNze3wyH7qkhIpOXDc3Nz4eXlJXM0RERE1Bnl5eUIDQ01/h5vjyoSEqlM4+XlxYSEiIhIZTrT3YKdWomIiEh2TEiIiIhIdkxIiIiISHaq6ENCRET2SxAE1NXVob6+Xu5Q6A4GgwGOjo4WmZKDCQkRESlWTU0NsrOzUVlZKXco1AYPDw9ERETA2dm5W+dhQkJERIrU2NiIc+fOwWAwIDIyEs7OzpwcU0EEQUBNTQ3y8/Nx9uxZ3H333d1KSpiQEBGRIt26dQuNjY2IjIyEh4eH3OFQK9zd3eHk5IQLFy4gKSkJ8fHxnZpzpDXs1EpERIrW0ZTjJC/p+eTl5WHHjh24detW185jyaCIiIjIPvXs2RN5eXm4du1alz7PhISIiIi6zWAwoL6+3nYtJAcOHMCMGTMQEhICnU6H7777rsPPpKWlISYmBi4uLoiKisLHH3/clViJiIhIo8xOSKqqqjBkyBCsWbOmU8dnZWUhMTER48ePR3p6Ov70pz/hmWeewTfffGN2sERERGowb948/PrXv5Y7DFUxe5TNtGnTMG3atE4f//HHHyMsLAyrV68GAAwYMAAnTpzAu+++i9/+9retfqampgY1NTXG78vLy80Ns1OysoC//Q3oYusSdcKwYcDcuXJH0U2HDgHffAMIgtyR2Cc/P2DZMsDdXe5IOiW3LBcf/fARbtXzB0t3+Rp8Md1nutxhkI1Yfdjv0aNHkZCQYLJv6tSpWL9+Perq6uDo6NjiM6tWrcIbb7xh7dDw1lvAp59a/TJ2b+RIYMAAuaPohjlzxOyV5BMUBDzxhNxRdMor+1/BptOb5A5DE/p59cP0CaYJiSAA1dXyxOPmBlhiGpS0tDQ8//zzOH36NHx9fTF37ly8+eabMBgM2LZtGx599FFcu3YNDg4OOHXqFIYNG4bnnnsO//f//l8AwJNPPony8nJs2bKl+8EoiNUTkqKiIgQGBprsCwwMRH19PUpKShAcHNziM8uXL8eyZcuM35eXlyM0NNTisVVVia/x8eIvTbKsf/0LOHsW2L5dxQlJVVVTMvLCC4CBU/fYVGoqcOQI8PPPckfSKYIgYE/GHgDA40MfR5BHkMwRqVsPfY8W+6qrAbmmJKms7H5DXX5+PhITEzFv3jxs2rQJP//8M5544gm4uLhgxYoVmDBhAioqKpCeno6YmBikpaXB398faWlpxnOkpqZi6dKl3bwb5bHJT9c7Z9YTbjd9tzXjnrOzc7enoDXHAw8Azz5rs8vZjZAQ4OmngW3bgOeflzuaLrp4UXz19wfeflveWOzRmjViQpKZKXcknXL26lkUVRbB1eCKj6Z/BBeDi9whqVp1dTXOnz8vdxgWtXbtWoSGhmLNmjXQ6XTo378/CgoK8OKLL+K1116Dt7c3hg4ditTUVMTExBiTjzfeeAMVFRWoqqrCL7/8gokTJ8p9KxZn9WG/QUFBKCoqMtlXXFwMg8EAPz8/a1+eZPTAA+Lr4cNAF4ely++XX8TXu+6SNw57FRUlvqokIUnOSAYAjA8fz2TEStzcxJYKOb7c3Lof//nz5zF69GiTP8jHjh2LyspK5OXlAQAmTpyI1NRUCIKAgwcP4le/+hUGDRqEQ4cOYf/+/QgMDET//v27H4zCWL2FZPTo0di2bZvJvj179mD48OGt9h8h7QgPBwYPBn76Cdi5E5g1S+6IuoAJibz69BFfMzLEzgMKX8ckOVNMSKZETZE5Eu3S6VTTv7lVgiB0WDWYOHEi1q9fj9OnT8PBwQEDBw5EbGws0tLScP36dcTGxto8blswu4WksrISp06dwqlTpwCIw3pPnTqFnJwcAGL/jzlz5hiPX7hwIS5fvoxly5bh/Pnz2LBhA9avX4/nnnvOMndAiia1kmzfLm8cXcaERF7h4eJvoKoq4OpVuaNpV019DdIui3V+JiTUloEDB+LIkSPGJAQAjhw5Ak9PT/Tq1QsAjP1IVq9ejdjYWOh0OsTGxiI1NRWpqalMSCQnTpzAsGHDMGzYMADAsmXLMGzYMLz22msAgMLCQmNyAgCRkZFISkpCamoqhg4dij//+c/44IMP2hzyS9oyY4b4umsXUFcnbyxdIiUk/frJG4e9cnEBbv+QVnrZ5ljeMVTXVaOnW08MDhwsdzikAGVlZcY/4KWv//7v/0Zubi4WL16Mn3/+Gf/617/w+uuvY9myZcY1YaR+JF988YWxr8iECRPw448/arb/CNCFks3EiRNNMrs7bdy4scW+2NhY/Pjjj+ZeijRg5EixP2hJidiXRFX/HwkCcOGCuM0WEvn06QPk5Yllm1Gj5I6mTVK5Jj4qHg46rspB4mgY6Y93ydy5c5GUlITnn38eQ4YMga+vL+bPn49XXnnF5LhJkybhxx9/NCYfPj4+GDhwIAoKCjBAtcMW28cxjGRVej2QmAhs2iSWbVSVkJSUADduiCUDqS8D2V5UFJCWpvgWEvYfoeY2btzY6h/okuPHj7f7+XfffRfvvvuuyT6pq4RWMY0nq5PKNqrrRyKVa8LCAFdXeWOxZyoYaXP95nWcKDgBQGwhISLzMSEhq0tIEOcTu3ChaVoPVWCHVmVoPtJGofZn70ej0Ih+fv0Q6m35SRyJ7AETErI6Ly9A6hSuqlYSJiTKoIIWEmn+EZZriLqOCQnZhCrLNhxhowxSC0l+vmJXwkzJSgEATOnDhISoq5iQkE1I85EcOACUlckbS6dxhI0y+PkBnp7itgIXOcy+kY1L1y5Br9MjNlyb80MQ2QITErKJPn2A/v2B+npg9265o+mEhgbg0iVxmwmJvHQ6RZdtpHLNfb3vg7eLt8zREKkXExKyGVWVbXJzgZoawMlJHGVD8lJwx1YO9yWyDCYkZDNS2SYpSWyAUDSp/0jfvuJkKiQvhbaQNAqN2Ju1FwCH+xJ1FxMSspkxYwAfH6C0FDh2TO5oOsARNsqi0IQkvTAd125eg6eTJ+7rdZ/c4RCpGhMSshmDAZg2TdxWfNmGI2yURaElG6lcMzFiIhz1XL2cbCc1NRU6nQ43btwAIM4M26NHD1lj6i4mJGRTUtlm2zZ54+gQR9goS/MWknbW0rK1lMzbw33Zf4TuMG/ePOh0OixcuLDFe4sWLYJOp8O8efMsdr2ZM2fiF+kPKZViQkI2df/9YpeMs2cVOYKzCUs2yhIWBjg4iPOQFBXJHQ0A4GbdTRzKOQSA/UeodaGhofjyyy9x8+ZN475bt25hy5YtCLNwZ3lXV1cEBARY9Jy2xoSEbMrHBxg3TtzesUPeWNp06xZw+bK4zYREGZqPdlJI2eZgzkHUNNSgl2cv9PfvL3c49kMQgKoqeb7MbJ279957ERYWhm+//da479tvv0VoaKjJKsCCIOCdd95BVFQUXF1dMWTIEHz99dcm50pKSsJdd90FV1dXTJo0CdnZ2Sbv31mymTdvHn7961+bHLNkyRLj6sEAMHHiRCxevBhLliyBj48PAgMD8cknn6CqqgqPPfYYPD090adPH+zcudOs++4qJiRkc4ov22RkiD94vL2Bnj3ljoYkCuvYapwuvs8U6HQ6maOxI9XVgIeHPF/V1WaH+9hjj+Gzzz4zfr9hwwY8/vjjJse88sor+Oyzz7Bu3TqcPXsWS5cuxezZs5GWlgYAyM3NxYMPPojExEScOnUKCxYswEsvvdS9/463ff755/D398fx48exePFi/J//83/w+9//HmPGjMGPP/6IqVOn4tFHH0V1F+7dXExIyOakhCQ1FaiokDWU1jUv1/AXjXIoLCGRpouPj2S5htr26KOP4tChQ8jOzsbly5dx+PBhzJ492/h+VVUV3nvvPWzYsAFTp05FVFQU5s2bh9mzZ+Nvf/sbAGDdunWIiorC+++/j379+mHWrFkW638yZMgQvPLKK4iOjsby5cvh6uoKf39/PPHEE4iOjsZrr72G0tJS/Oc//7HI9dpjsPoViO7Qr584vcelS0BKCvCb38gd0R04wkaZFDTSpriqGKeKTgFg/xGbc3MDKivlu7aZ/P39MX36dHz++ecQBAHTp0+Hv7+/8f1z587h1q1bmDLFtGN0bW2tsaxz/vx5jBo1yqQlbvTo0V28CVP33HOPcVuv18PPzw+DBw827gsMDAQAFBcXW+R67WFCQjan04mtJKtXi2UbxSUkHGGjTApqIdmbKU6Gdk/gPQj0CJQ5Gjuj0wHu7nJHYZbHH38cTz/9NADgo48+MnmvsbERALBjxw706tXL5D1nZ2cAYh8Tczk4OLT4XF1dXYvjHB1Nh6vrdDqTfVISJMVpTSzZkCykss2OHYAN/p2bhyNslElqIVFAQsLhvmSO+++/H7W1taitrcXUqVNN3hs4cCCcnZ2Rk5ODvn37mnyFhoYajzl2x2ySd35/p549e6KwsNBk36lTp7p/M1bEhIRkMX484OUFFBcDJ07IHc0dmJAok9RCUlQkjniQiSAIxgnRWK6hztDr9Th//jzOnz8P/R1LUXh6euK5557D0qVL8fnnnyMjIwPp6en46KOP8PnnnwMAFi5ciIyMDCxbtgwXLlzAP/7xD2zcuLHda06ePBknTpzApk2bcPHiRbz++us4c+aMtW7RIpiQkCycnADpDwVFjba5fh24elXcjo6WNxYy5eMDSMMaZZzE5pfSX5BbngsnvRMmhE+QLQ5SFy8vL3h5ebX63p///Ge89tprWLVqFQYMGICpU6di27ZtiIyMBACEhYXhm2++wbZt2zBkyBB8/PHHeOutt9q93tSpU/Hqq6/ihRdewIgRI1BRUYE5c+ZY/L4sSSd0pThlY+Xl5fD29kZZWVmbD7QrHnkE2LJF7Mvw7LMWOy110qZNwNy5wNChQHq63NHcdvw4cN99QEgIkJ8vdzR0p+HDgZMnge++A371K1lCWHN8DRbvXIxJEZOwb+4+WWKwF9XV1Th//jwGDBgAty50KCXbkJ5TVlYWLl26hIceeghRt1s0zfn9zRYSkk1iotg/7dQpIC9P7mhu4wgbZVNAx1ap/wjLNUSWxYSEZOPvD0gj1xSz2B5H2CibzAlJfWM99mfvB8AOrUSWxoSEZDVjhviqmISEHVqVTea5SI7nH0d5TTl8XHxwb/C9ssRApFVMSEhW0vDfvXu7NCuz5TEhUTaZW0ikck1cVBz0DvoOjiYiczAhIVndfTcQHi6uZ7d3r8zBCAITEqWTEpKsLFkmsDEO9+V08UQWx4SEZKXTKahsU1AgNtMYDMDt4XakMKGh4vOprbX5KKiKmgocyxMno5rSh/1HiCyNCQnJTirbbN9u9ureliW1jkRFAXdMp0wKYTCITWqAzcs2aZfTUN9YjyifKET5RNn02kT2gAkJyS42VlyaoqBA5vlIOMJGHWTqR5KcwXINkTUxISHZubgACQnitqxlG/YfUQeZRtpI/UdYriGyDiYkpAhS2UbWaeSZkKiDDC0keeV5OF9yHjroMDlyss2uS9q2ceNG9JCWQ+ikefPm4de//rVV4pEbExJShMRE8fXECeCOBSpthwmJOsiw6u/eTHEI2PCQ4fB19bXZdUm92kocUlNTodPpcOPGDcycORO/SD93iAkJKUNQEDBypLidlCRDAHV1Tb/gOG28skktJDYs2XB1X7IGV1dXBAQEyB2GYjAhIcWQtWyTmQk0NIi9a4ODZQiAOk1KSEpKgPJyq19OEATjhGicLl5+giCgqrZKli9Lr0XbWsnmzTffREBAADw9PbFgwQK89NJLGDp0aIvPvvvuuwgODoafnx+eeuop1NXVWTQ2ORjkDoBI8sADwGuvAcnJ4kRpLi42vHjzco1OZ8MLk9m8vMSFkEpKxAnShgyx6uXOFJ/BlaorcDW4YkzoGKteizpWXVcNj1Uesly7cnkl3J3crXb+zZs34y9/+QvWrl2LsWPH4ssvv8Rf//pXRN4xL9L+/fsRHByM/fv349KlS5g5cyaGDh2KJ554wmqx2QJbSEgxhg4FevUS5yZLTbXxxdl/RF1sWLaRyjUTwifA2eBs9euRdmzfvh0eHh4mX9OmTWvz+A8//BDz58/HY489hrvuuguvvfYaBg8e3OI4Hx8frFmzBv3798cDDzyA6dOnY6/sU113H1tISDF0OrGV5G9/E8s2999vw4szIVGXqCjg+HGbdGw1DvdluUYR3BzdULm8UrZrm2PSpElYt26dyb7vv/8es2fPbvX4CxcuYNGiRSb7Ro4ciX379pnsu/vuu6HXN62lFBwcjJ9++sms2JSICQkpipSQbN8OrFljw+oJExJ1sdFcJDX1NUjLTgPA+UeUQqfTWbVsYknu7u7o27evyb68vLx2P6O744dea/1WHO+YSVqn06FRhrWdLI0lG1KUuDjA1RXIyQHOnLHhhaWEhCNs1MFGc5EczTuKm/U3EeAegMEBLZvOiSypX79+OH78uMm+EydOyBSN7TEhIUVxdRWTEsCGo20qKsR56wEgOtpGF6VusVFCYpwuPiq+xV+uRJa2ePFirF+/Hp9//jkuXryIN998E//5z3/s5t8eExJSnOaL7dnExYvia0AAYOasiSQTqWSTnQ3U11vtMuw/QrY0a9YsLF++HM899xzuvfdeZGVlYd68eXCx6ZBD+bAPCSmOlJAcOwZcvQr07GnlC7L/iPqEhABOTkBtLZCXB0REWPwS129ex4kCsbmcE6KRuTZu3Njq/okTJxr7hcybNw/z5s0zef/VV1/Fq6++avx+ypQpJv1QWjvv6tWruxuuIrCFhBSnVy9g2DBAEGw0aysTEvXR65uSECuVbfZl7YMAAf39+6O3V2+rXIOouerqarz33ns4e/Ysfv75Z7z++utISUnB3Llz5Q7NJpiQkCLZtGzDhESdrDzShuUasjWdToekpCSMHz8eMTEx2LZtG7755hvEx9tHCx1LNqRIM2YAf/4zsHu32Crv5GTFi3GEjTpZuWMrp4snW3N1dUVKSorcYciGLSSkSDExQGCgOADmwAErXkgQgAsXxG22kKiLFVf9zbqehYzrGdDr9IiNiLX4+YmoJSYkpEgODsD06eK2Vcs2xcXiAm06XdMvOFIHK04fL5VrRvUeBS9nL4ufn8yjhUm/tMxSz4cJCSnWjBni67ZtYkOGVUjlmogIwJnrlKiKFUs27D+iDE63a7WVlfJMFU+dIz2f7q44zD4kpFjx8WLfkcxM4OefgQEDrHARdmhVLykhuX5d/PLxschpGxobsC9LXDuE08XLy2AwwN/fH/n5+QAADw8PODjw72ilaGxsRGVlJfLz83Hjxg00NDQAaDn9fWcxISHF8vAAJk0SO7Zu386EhO7g7i52NLpyRcxaY2Isctr0onRcu3kNnk6eGBEywiLnpK4LCwsDAGNSQspz48YNXLlyBdXV1XBycoKrq2uXzsOEhBRtxoymhOT5561wAY6wUbeoKIsnJNJ08ZMiJ8FR79jB0WRtOp0O4eHh8PX1xf79+3H58mV4eHiYrHZL3ZOanYorVVcwuvdohHmHdfpzgiCgtrYWDQ0NqKurQ2VlJYYOHQo/P78uxcGEhBRt+nTg6aeBw4eBa9cAX18LX4AjbNStTx/g6FGLdmxNyeJwXyXy9PREXFwcUlJSUFBQYCwPUPcVlhaioLwApR6l6KHr0aVzODk5ISYmBpMmTWqxGnFnMSEhRYuIAAYNElf+3bULeOQRC568oQG4dEncZkKiThbu2FpdV41DOYcAcLp4JXJ3d8evfvUr1NXVod6KaxjZm39u+SfOZp/Fc4nP4XcDf9elczg5OXW71YoJCSnejBliQrJ9u4UTksuXgbo6cXRNaKgFT0w2Y+GE5ODlg6htqEVvr97o58cynlI5Ojp2+a9waoUBaNA3wNHZscv9PyyB3ZVJ8aRp5HfuFPMHi5H6j0RHixOfkPpYePr45sN97WXJdyKl6NJP4bVr1yIyMhIuLi6IiYnBwYMH2z1+8+bNGDJkCNzc3BAcHIzHHnsMpaWlXQqY7M999wH+/sCNG8CRIxY8MUfYqJ/UQpKTY5FsldPFE8nH7IRk69atWLJkCV5++WWkp6dj/PjxmDZtGnJyclo9/tChQ5gzZw7mz5+Ps2fP4v/9v/+HH374AQsWLOh28GQf9HogMVHc3rbNgifmCBv1CwoCXFyAxkYxKemGK5VXcPrKaQBAXFScJaIjIjOYnZC89957mD9/PhYsWIABAwZg9erVCA0Nxbp161o9/tixY4iIiMAzzzyDyMhIjBs3Dk8++SROnDjR7eDJflhl9V+OsFE/BweLTSG/N2svAGBI4BAEuAd0NzIiMpNZCUltbS1OnjyJhIQEk/0JCQk40kZb+pgxY5CXl4ekpCQIgoArV67g66+/xnRpoZJW1NTUoLy83OSL7NvUqYDBIOYQFy9a6KQs2WiDhTq2slxDJC+zEpKSkhI0NDQgMDDQZH9gYCCKiopa/cyYMWOwefNmzJw5E05OTggKCkKPHj3w4YcftnmdVatWwdvb2/gVyhEQds/LC4i9veiqRVpJbt5sauJnQqJuFkhIBEEwdmjlcF8ieXSpU+udvc8FQWizR/q5c+fwzDPP4LXXXsPJkyexa9cuZGVlYeHChW2ef/ny5SgrKzN+5ebmdiVM0hiLlm2k+Ud8fIAuzipICmGBkTYXSi8grzwPTnonjA8fb6HAiMgcZs1D4u/vD71e36I1pLi4uEWriWTVqlUYO3Ysnr897/c999wDd3d3jB8/Hm+++SaCg4NbfMbZ2RnOXHmV7jBjBrB0KXDgAFBWBnh7d+NkzTu0cninulmghUSaLn5c2Di4ObpZIioiMpNZLSTS1LDJyckm+5OTkzFmzJhWP1NdXd1idUZpNjfBamvKkxb16QP07w/U14vr23QL+49oh9RCkpkJdPFnCqeLJ5Kf2SWbZcuW4dNPP8WGDRtw/vx5LF26FDk5OcYSzPLlyzFnzhzj8TNmzMC3336LdevWITMzE4cPH8YzzzyDkSNHIiQkxHJ3QnbBYmUbjrDRjogI8bW8HOjC/EZ1DXXYn7UfAPuPEMnJ7KnjZ86cidLSUqxcuRKFhYUYNGgQkpKSEB4eDgAoLCw0mZNk3rx5qKiowJo1a/DHP/4RPXr0wOTJk/H2229b7i7IbsyYAbz7LpCUJC5F0+WlE9hCoh2urkBICFBQILaS+Pub9fHj+cdRUVsBX1dfDAsaZqUgiagjXVrLZtGiRVi0aFGr723cuLHFvsWLF2Px4sVduRSRiTFjgB49xD+Ejx0Dxo7t4omYkGhLnz5iQpKRAYwcadZHpeG+cZFx0DtwSXsiuXABD1IVgwGYNk3c7nLZprS0qWm/b1+LxEUy60bHVg73JVIGJiSkOjNmiK9dTkikmdVCQwF3d4vERDLrYkJSXlOOY3nHALBDK5HcmJCQ6kydKvYdOXMGyM7uwgnYoVV7ujgXSVp2GhqEBvTx6YNIn0grBEZEncWEhFTH17ep70iXWknYf0R7uthCIpVr2DpCJD8mJKRK3SrbMCHRHikhycsDamo6/TH2HyFSDiYkpErSfCT79wMVFWZ+mAmJ9gQEiP2BBKHTdby88jz8XPIzHHQOmBw52brxEVGHmJCQKvXrJ3YbqK0FUlLM+GBjY1OnViYk2qHTmV22kYb7Dg8ZDh9XH2tFRkSdxISEVEmn62LZJj9fXOnX0bFphk/SBjMTEmO5JpLlGiIlYEJCqiWVbXbsEBs+OkUaYdOnjzipCWmHGSNtGoVGYwvJlD7s0EqkBExISLXGjwe8vIArV4ATJzr5IfYf0S4zWkjOFJ9BcVUx3BzdMLr3aCsHRkSdwYSEVMvJSZyTBDCjbMOERLuar/rbgeQMsVwTGx4LZ4OzNaMiok5iQkKqJpVttm3r5AeYkGhX8xYSQWj3UA73JVIeJiSkatOmiR1cT50Sp6DoEBMS7QoPF/8xVFUBxcVtHnar/hYOXD4AgBOiESkJExJStZ49gdG3uwDs2NHBwbW1QFaWuN2vn1XjIhk4O4vrEwHtlm2O5h7FzfqbCHQPxKCAQTYKjog6woSEVK/TZZuMDHE4jqcnEBho9bhIBlLZpp2RNs3LNTqdzhZREVEnMCEh1ZMSkr17gerqdg5sXq7hLyJt6sRIG65fQ6RMTEhI9QYNErsP3LoF7NvXzoHsP6J9HcxFcu3mNZwsOAmAHVqJlIYJCameTtfJsg0TEu3roIVkX9Y+CBAwsOdA9PLqZcPAiKgjTEhIE6SEZPv2dkZ8MiHRvg4SEmn+EU4XT6Q8TEhIEyZOFBd7LSgQhwC3SkpIOMJGu6SSTUGBuGbRHVKyOF08kVIxISFNcHEBptz+HdNq2aa8HCgqErejo20WF9mYr6+4ngDQNMT7tszrmci8ngmDgwGx4bEyBEdE7WFCQprR7uq/UutIUFDTLyzSHp2uzbKNVK4Z1XsUPJ09bR0ZEXWACQlpRmKi+PrDD0Bh4R1vsv+I/WhjpA2H+xIpGxMS0oygIGDECHE7KemON5mQ2I9WWkgaGhuwL0scE86EhEiZmJCQprRZtmFCYj9aWfX3x8Ifcf3WdXg5e2FErxEyBUZE7WFCQpoiDf/ds0ecKM2II2zsRyvTx0vlmkkRk2BwMMgRFRF1gAkJacrQoUCvXuIU8qmpt3cKAnDhgrjNFhLtkxKSrCxx7SIAKZm3h/uyXEOkWExISFOaz9pqLNsUFQGVlYCDQ9MvK9KusDBArxebyIqKUF1XjcO5hwFw/hEiJWNCQprTfBp5QUBTuSYyEnByki0ushFHRzEpAYCMDBy4fAC1DbUI9QpFtC/noCFSKiYkpDmTJ4sTpeXkAGfOgB1a7VGzkTbS/CNToqZAx1WeiRSLCQlpjpsbEH97qZLt28EOrfao2VwknC6eSB2YkJAmmaz+yxYS+3O7heTK5bP4z5X/AAAmR06WMyIi6gDHv5EmTZ8uvh47BtT3uSD+Q2dCYj9uJyQplWIyMjRoKALcA+SMiIg6wBYS0qTevYFhwwAHoR4OWbfno2BCYj9ul2xSHPMAcLgvkRowISHNeuABIALZcGioB1xdxQlKyD5ERUEAkNxLnB2PCQmR8jEhIc164AHgLoj9Rxr7RovzkJB96NEDP0d5Id8LcHZwwriwcXJHREQd4E9o0qzhw4EYDzEhuerDETb2JvlebwDAOLf+cHV0lTkaIuoIExLSLAcHYHJvccr40zfZf8TepIQ3AACm1IbKHAkRdQYTEtK0ux3FFpI92XeJs7aSXahrqEOqRwkAIP6Km8zREFFnMCEhTfO/JiYkh67eZVxfj7Tv+/zvUaGrhV81MOxCudzhEFEnMCEh7aqqgkO+OOzzF9wlTpJGdkFa3TcuE3DIzJI5GiLqDCYkpF2XLgEAbrr74Tp8m1b/Jc1Lzry9fk0mgOxsoKFB1niIqGNMSEi7bk8Zr+svjrA5fBi4dk3OgMgWym6V4fu87wEA8Zf1QG0tkJ8vc1RE1BEmJKRdtzuNuAy+C4MGiX8k79olc0xkdWmX09AgNKCvb19E+ESKOzMz5Q2KiDrEhIS0q9mietJieyzbaF9yxu1yTdQUk1V/iUjZmJCQdjVLSGbMEDd37gTq6+ULiaxP6j8SHxVvXGSPLSREyseEhLRJEIwlG9x1F+67D/DzA27cEPuSkDblluXiQukFOOgcMDlyMhMSIhVhQkLaVFoqZh86HdC3L/R6IDFRfItlG+2ShvuOCBmBHi49WLIhUhEmJKRNUrkmLExc6Rcwlm2YkGiXcbivtLovW0iIVIMJCWlTs3KNJCEBMBiAn382TlFCGtIoNBpbSOKj4sWdUkJSWgqUlckUGRF1BhMS0qZmHVol3t5AbKy4zVYS7fnpyk+4Wn0V7o7uGB06Wtzp6Qn07Clus5WESNGYkJA2tZKQAODwXw2TyjWxEbFw0js1vcGyDZEqMCEhbeogIUlLYwu+1hiH+0bGm77BhIRIFZiQkPY0NgIXL4rbdyQkffsC/fuLc5Hs2SNDbGQVt+pv4cDlAwCAKX2mmL7JkTZEqsCEhLQnNxeoqQGcnIDw8BZvS60kXP1XO47kHsGt+lsI9gjG3T3vNn2TLSREqsCEhLRHGmHTty+g17d4W0pIkpK4CKxWSNPFx0fFQ6fTmb4ptZAwISFStC4lJGvXrkVkZCRcXFwQExODgwcPtnt8TU0NXn75ZYSHh8PZ2Rl9+vTBhg0buhQwUYfa6D8iGTsW6NFDHAn6/fe2C4usx2S6+DtJLSSXL3PdACIFMzsh2bp1K5YsWYKXX34Z6enpGD9+PKZNm4acnJw2P/PQQw9h7969WL9+PS5cuIAtW7agf//+3QqcqE0dJCQGAzBtmrjNso36lVaX4sfCHwG0kZCEhADOzmIykptr4+iIqLPMTkjee+89zJ8/HwsWLMCAAQOwevVqhIaGYt26da0ev2vXLqSlpSEpKQnx8fGIiIjAyJEjMWbMmG4HT9SqDhISgMN/tWRf1j4IEHB3z7sR4hnS8gAHByAyUtxmx1YixTIrIamtrcXJkyeRkJBgsj8hIQFHjhxp9TP//ve/MXz4cLzzzjvo1asX7rrrLjz33HO4efNmm9epqalBeXm5yRdRp3UiIbn/frF7yZkzQHa2bcIi62i3XCNhx1YixTMrISkpKUFDQwMCAwNN9gcGBqKoqKjVz2RmZuLQoUM4c+YM/vnPf2L16tX4+uuv8dRTT7V5nVWrVsHb29v4FRoaak6YZM9qapoyjH792jzM11fsSwKwlUTNBEFouX5Na5iQEClelzq13tmLXRCElj3bb2tsbIROp8PmzZsxcuRIJCYm4r333sPGjRvbbCVZvnw5ysrKjF+5rPtSZ126BAiCOE+8NGV4G1i2Ub/M65nIvpENg4MBsRGxbR/IuUiIFM+shMTf3x96vb5Fa0hxcXGLVhNJcHAwevXqBW9vb+O+AQMGQBAE5OXltfoZZ2dneHl5mXwRdUrzck0bSbJEWv13/36gstLKcZFVSK0jo3uPhoeTR9sHsoWESPHMSkicnJwQExOD5ORkk/3JycltdlIdO3YsCgoKUNnsJ/4vv/wCBwcH9O7duwshE7WjE/1HJP36iX8419YCd/yTJpXoVLkGYEJCpAJml2yWLVuGTz/9FBs2bMD58+exdOlS5OTkYOHChQDEcsucOXOMxz/yyCPw8/PDY489hnPnzuHAgQN4/vnn8fjjj8PV1dVyd0IEmJWQ6HQs26hZQ2MD9mXtA9DKdPF3khKSGzeAa9esGxgRdYnZCcnMmTOxevVqrFy5EkOHDsWBAweQlJSE8NtTdBcWFprMSeLh4YHk5GTcuHEDw4cPx6xZszBjxgx88MEHlrsLIomUkLTTobU5qWyzY4e4BA6px8nCk7hx6wa8nb0xPGR4+we7uQFBQeI2W0mIFMnQlQ8tWrQIixYtavW9jRs3ttjXv3//FmUeIqswo4UEAMaPBzw9gStXgBMngJEjrRgbWZQ0XfykyEkwOHTiR1lUFFBUJCYkwztIYIjI5riWDWnHjRtAcbG4HR3dqY84OQFTp4rbLNuoS0pWCoBO9B+RcKQNkaIxISHtkFpHQkIAj3ZGXNxBKtswIVGPqtoqHM45DMCMhIQdW4kUjQkJaYeZ5RrJtGliB9f0dKCNkeikMAcuH0BdYx3CvMPQ17dv5z7EVX+JFI0JCWlHFxOSnj2BUaPE7R07LBwTWUXz4b5tTcrYgtRCwpINkSIxISHtMHOETXMs26hLSqaZ/UeApoQkN1ecfIaIFIUJCWnHhQviq5ktJEDTfCQpKUB1tQVjIosrqizCT8U/AQDiouI6/8GgIMDVVRzf3WxqAiJSBiYkpA2C0OWSDQAMGgSEhQG3bgH79lk4NrIoqXVkWNAw+Lv5d/6DOh3LNkQKxoSEtKGgQGza0OuByEizP67TsWyjFl0q10g40oZIsZiQkDZIrSNRUYCjY5dO0XwaeUGwUFxkUYIgNHVo7Wi6+NZwLhIixWJCQtrQjXKNZOJEwN0dyM8HTp2ySFRkYedLzqOgogDOemeMDR1r/gnYQkKkWExISBu6McJG4uICTLn9RzfLNsokTRc/Pnw8XB27sDgnExIixWJCQtrQjRE2zUllm23buhkPWYXZ08XfqXnJhnU5IkVhQkLaYIGSDQAkJoqvP/wgrsNGylHXUIfU7FQA3UhIIiLE18pKoKTEInERkWUwISH1q6traoLvZkISHAyMGCFuJyV1My6yqGN5x1BZWwl/N38MCRrStZO4uAC9eonbLNsQKQoTElK/rCygoQFwcxMX1usmlm2USRruGxcZBwddN350caQNkSIxISH1a16u6ey6Ju2Q5iNJThYnSiNlaL5+TbewYyuRIjEhIfWzwAib5oYOFRtaqqqA1FSLnJK6qexWGY7nHwcAxEfFd+9kXPWXSJGYkJD6WWiEjUSnM50kjeSXmp2KBqEB0b7RCO8R3r2Tcfp4IkViQkLqZ6ERNs01n0aeo0PlZ7FyDcCSDZFCMSEh9bNCQjJ5sjgg4/Jl4MwZi52Wuqhb08XfSSrZ5OezkxCRgjAhIXWrrBQX1gOA6GiLndbNDYi7vbI9yzbyyinLwS+lv8BB54CJERO7f0J/f8DDQ2z6ys7u/vmIyCKYkJC6XbwovvbsCfj4WPTUXP1XGaThviN7jUQPlx7dP6FOx7INkQIxISF1s/AIm+amTxdfjx4Frl61+Ompkyzaf0TCuUiIFIcJCambhUfYNNe7tzgEWBCAnTstfnrqhEah0dhC0u3hvs2xhYRIcZiQkLpZoUNrcyzbyOs/V/6DkuoSuDu6Y1TvUZY7MRMSIsVhQkLqZuWERJqPZNcuoLbWKpegdiRniOWaiRET4aR3styJWbIhUhwmJKRegmD1hGT4cCAwEKioAA4etMolqB1W6T8CmLaQcKIZIkVgQkLqdfUqUFYmjpqQ/uK1MAeHps6tLNvY1q36WziYI2aBFu0/AgDh4eLDvXkTuHLFsucmoi5hQkLqJbWORESIs5hZSfPVf/nHtO0czjmMW/W3EOIZgoE9B1r25E5OQGiouM2yDZEiMCEh9bLiCJvmpkwRf39lZDRdkqxPKtfER8VDZ4FVnFtgx1YiRWFCQupl5f4jEg8PYNIkcZtlG9sxJiSRFi7XSLjqL5GiMCEh9bJRQgKYlm3I+kqqS5BemA7ACv1HJFz1l0hRmJCQesmQkBw+DFy7ZvXL2b19WfsgQMCggEEI9gy2zkVYsiFSFCYkpE4NDcClS+K2FaaNv1NEBDBokHjZ3butfjm7J80/YvHhvs2xZEOkKExISJ1ycsSZypydm0ZLWBnLNrYhCIJJh1arkVpICguB6mrrXYeIOoUJCamTNNwlOlqcT8IGpIRk506gvt4ml7RLGdczcLnsMhwdHBEbHmu9C/n4AN7e4nZWlvWuQ0SdwoSE1MmG/Ucko0YBfn7AjRvAkSM2u6zdkco1Y0LHwN3J3XoXaj6hHju2EsmOCQmpkwwJiV4PJCaK2yzbWI9NyjUSdmwlUgwmJKROMiQkQFPZhvORWEdDYwP2Ze0DYOUOrRImJESKwYSE1ElKSGwwwqa5qVMBgwH4+eemQT5kOScKTqCspgzezt4YHjLc+hdkyYZIMZiQkPrcvCmOsgFs3kLi7Q1MmCBus5XE8qRyzeTIydA76K1/QbaQECkGExJSn0uXxFXufHzEXqY2xrKN9aRkpgCwUbkGaEpIsrKAxkbbXJOIWsWEhNSnef8Rayy61oEZM8TXtDSgvNzml9esytpKHMkVhy9N6WOjhCQsTOytXFMDFBTY5ppE1ComJKQ+MnVolfTtK3Zdqa/nrK2WdODyAdQ11iGiRwT6+PSxzUUNBiA8XNxm2YZIVkxISH1kTkgAlm2sQZp/JD4yHjpbtnyxHwmRIjAhIfWRaYRNc1LZJilJXN+Gui8l63b/EVuVayQcaUOkCExISH2kaeNlbCEZMwbo0QMoKQG+/162MDSjsKIQZ4rPQAcdJkdOtu3F2UJCpAhMSEhdSkvFL0DszCETR0dg2jRxm2Wb7pNG1wwLHgZ/N3/bXpyr/hIpAhMSUpeLF8XX3r0Bdyuuc9IJXP3XcozlGlsN921OaiFhyYZIVkxISF0U0KFVcv/94ojRM2eA7Gy5o1EvQRCMHVplTUiuXgUqKmx/fSICwISE1EZBCYmvLzB2rLi9Y4e8sajZuavnUFhZCBeDC8aGjbV9AN7eTRPssWxDJBsmJKQuChhh0xzLNt0nTRc/Pmw8XAwu8gTBjq1EsmNCQuqigBE2zUkJyf79QGWlvLGolc2ni28NExIi2TEhIfVobGzq1KqQhKR/f3GQRm0tkJIidzTqU9tQi9TsVAAyzD/SHOciIZIdExJSj/x8caVfgwGIiJA7GgDiUjos23TdsbxjqKqrQk+3nrgn8B75AmELCZHsmJCQekj9R/r0EZMShZASkh07uGCsuaRyTVxUHBx0Mv44YkJCJLsu/QRYu3YtIiMj4eLigpiYGBw8eLBTnzt8+DAMBgOGDh3alcuSvVPQCJvmJkwAPD2BK1eAkyfljkZdpA6tsvYfAZpKNtnZXAuASCZmJyRbt27FkiVL8PLLLyM9PR3jx4/HtGnTkJOT0+7nysrKMGfOHMTFxXU5WLJzChthI3FyAqZOFbdZtum8G7du4Hj+cQBAfFS8vMH06iVOv1tXB+TlyRsLkZ0yOyF57733MH/+fCxYsAADBgzA6tWrERoainXr1rX7uSeffBKPPPIIRo8e3eVgyc4pbIRNc1z913z7s/ajUWjEXX53Icw7TN5g9Pqmfkks2xDJwqyEpLa2FidPnkRCQoLJ/oSEBBw5cqTNz3322WfIyMjA66+/3qnr1NTUoLy83OSLSKklGwBITBQ7uKani31vqWOKGO7bHEfaEMnKrISkpKQEDQ0NCAwMNNkfGBiIoqKiVj9z8eJFvPTSS9i8eTMMneyIuGrVKnh7exu/QkNDzQmTtKi2FsjKErcVmJD07AmMGiVus5WkcxTTf0TCjq1EsupSp1adTmfyvSAILfYBQENDAx555BG88cYbuMuMXyLLly9HWVmZ8Ss3N7crYZKWZGaKQ1g8PICgILmjaRXLNp13+cZlXLx2EXqdHhMjJsodjoir/hLJyqyxk/7+/tDr9S1aQ4qLi1u0mgBARUUFTpw4gfT0dDz99NMAgMbGRgiCAIPBgD179mDy5MktPufs7AxnZ2dzQiOta16uaSX5VYIZM4CXXxYnSKuuBtzc5I5IuaRyzcheI+Ht4i1zNLdx1V8iWZnVQuLk5ISYmBgkJyeb7E9OTsaYMWNaHO/l5YWffvoJp06dMn4tXLgQ/fr1w6lTp3Dfffd1L3qyHwodYdPcoEFAWBhw6xawb5/c0Sib4so1AEs2RDIze3apZcuW4dFHH8Xw4cMxevRofPLJJ8jJycHChQsBiOWW/Px8bNq0CQ4ODhg0aJDJ5wMCAuDi4tJiP1G7FDzCRiLN2rp2rVi2kUo4ZKpRaMTerL0AZJ4u/k5SQnLtGnDjBtCjh5zRENkdsxOSmTNnorS0FCtXrkRhYSEGDRqEpKQkhIeHAwAKCws7nJOEyGwKHmHT3IwZTQmJICi2uiSr00WnUVJdAg8nD9zXS0GtpB4eQEAAUFwstpLce6/cERHZlS51al20aBGys7NRU1ODkydPYsKECcb3Nm7ciNTU1DY/u2LFCpw6daorlyV7ppKEZOJEse9Ifj7Af+atk8o1EyMmwlHvKHM0d2DZhkg2XMuGlK+8HJA6Uis8IXFxAabcrkJwtE3rFNl/RMK5SIhkw4SElO/iRfE1KAjw8pI3lk6YMUN8ZULS0s26mzh4WVz7Svbp4lvDFhIi2TAhIeVTSblGkpgovh4/3tSwQ6LDuYdR01CDEM8QDPAfIHc4LTEhIZINExJSPhWMsGkuOBgYPlzcTkqSNxalSc5oKte0Npmi7FiyIZINExJSPpW1kAAs27RF0f1HgKYWkpwcceVfIrIZJiSkfCpMSKQ5SPbsESdKI6CkugTpRekAgLioOJmjaUNwMODsDDQ0AFyygsimmJCQsgmCKhOSYcOAkBCgqgpIS5M7GmXYmylOhjY4YDCCPJS5HhEcHDiFPJFMmJCQsl25AlRUiL8opPq+CkiztgIs20gUX66RsGMrkSyYkJCySR1aIyMBJyd5YzGTlJBs2yY29NgzQRCMCYkih/s2x1V/iWTBhISUTYXlGklcnDhR2uXLwNmzckcjr0vXLiGnLAdOeidMCJ/Q8QfkxJINkSyYkJCyqTghcXMTkxJAbCWxZ1LryJjQMXB3cpc5mg6wZEMkCyYkpGwqTkgA9iORqKb/CGA6F4m919qIbIgJCSmbRhKSo0eBkhJ5Y5FLfWM99mftB6CC/iMAEBEhvpaXA9euyRoKkT1hQkLKVV/fVMfv10/eWLqod29g6FDxD217nbX1RMEJlNWUwcfFBzHBMXKH0zE3N3E+EoBlGyIbYkJCypWdLc6W6eoK9OoldzRdZu9lG2m6+MmRk6F30MscTSdxCnkim2NCQsollWuio8V5SFRKmkZ+926gtlbeWOSQkpUCQCXlGgk7thLZnHp/ypP2qbz/iGT4cCAgQOyScPCg3NHYVmVtJY7mHgWgkg6tEiYkRDbHhISUSyMJiYMDMH26uG1vZZu07DTUNdYhskck+viqZ6ZdlmyIbI8JCSmXRhISoKlsY2+ztqpmdtY7sYWEyOaYkJBySQmJSkfYNBcfL858n5HRNBu+PUjJFPuPqKpcAzQlJLm59tnxh0gGTEhImaqqmpZ/10ALiacnMHGiuG0vZZuCigKcvXoWOugwOXKy3OGYJzBQHP4rCOJoLyKyOiYkpEyXLomvfn6Ar6+8sViIVLaxl4REah2JCYmBn5ufzNGYSadj2YbIxpiQkDJpqP+IROrYeugQcP26vLHYgpSQxEeqrP+IhKv+EtkUExJSJg0mJJGRwN13Aw0NwK5dckdjXYIgNPUf6aOy/iMSrvpLZFNMSEiZNJiQAPZTtjl79SwKKwvhanDFmNAxcofTNSzZENkUExJSJg2NsGlOmkZ+505xqR6tkqaLHx8+Hi4GF5mj6SKWbIhsigkJKY8gNI2N1VgLyahRYj/d69eBI0fkjsZ6pOniVTfct7nmJRt7mjyGSCZMSEh5Skuben327StvLBam1wOJieK2Vss2tQ21SMtOA6DyhCQiQhxtU1UFXL0qdzREmseEhJRHKteEhYkr/WqMVLbZtk3eOKzlaO5RVNVVIcA9AIMDB8sdTtc5OwO9e4vb7NhKZHVMSEh5NNqhVTJ1KmAwAD//3DTdipZIo2viIuPgoFP5jxh2bCWyGZX/tCBN0nhC4u0NTJggbu/YIW8s1iCtX6Pqco2ECQmRzTAhIeXR6Aib5rRatrl+8zp+KPgBgAoX1GsNV/0lshkmJKQ8Gh1h05yUkKSlAeXl8sZiSfuz96NRaEQ/v34I9Q6VO5zuYwsJkc0wISFlaWwELl4UtzWckERHiw1A9fXAnj1yR2M5ql3dty1MSIhshgkJKUtuLlBTAzg6AuHhckdjVVos2xj7j6h1uvg7SSWb/Hzg5k15YyHSOCYkpCxS/5G+fcVJOzRMSkiSksT1bdQu+0Y2Ll27BL1Oj4kRE+UOxzL8/ABPT3E7O1vWUIi0jgkJKYsddGiVjB0L9OgBlJQAx4/LHU33SeWa+3rfBy9nL5mjsRCdjmUbIhthQkLKovEhv805OgL33y9ua6Fso6nhvs1xpA2RTTAhIWWxgxE2zUllG7VPI98oNGJv5l4AGkxI2EJCZBNMSEhZ7KiFBACmTQMcHICffgIuX5Y7mq47VXQKpTdL4enkiZG9RsodjmVx1V8im2BCQspRU9PUcdBOEhJfX7EvCaDuVpLkDLFcMzFiIhz1jjJHY2HNV/0lIqthQkLKIS3z7uUFBATIHY3NzJghvqo6IdFq/xHAtGQjCPLGQqRhTEhIOZqPsNHp5I3FhqR+JPv2AZWV8sbSFTfrbuJQziEAGpp/pLnwcLGudusWUFgodzREmsWEhJTDzjq0Svr3F/8Ir60FUlLkjsZ8h3IOoaahBr08e6GfnwaHazs6AmFh4jb7kRBZDRMSUg4769Aq0enUXbZpPjurTqstWxxpQ2R1TEhIOew0IQFMh/82Nsobi7k03X9EwrlIiKyOCQkphx0nJBMmiDOUX7kCnDwpdzSdd7XqKk4VnQIAxEXGyRuMNbGFhMjqmJCQMty4ARQXi9vR0bKGIgcnJ2DqVHFbTWWbvVniZGj3BN6DQI9AmaOxIiYkRFbHhISU4eJF8TUkpGkxMzujxtV/pflHNF2uAViyIbIBJiSkDHY6wqa5adPEDq7p6eJq90onCIJ99B8BmlpIrlwBqqrkjYVIo5iQkDLYcf8RSUAAMGqUuL1jh7yxdMbFaxeRW54LJ70TxoePlzsc6/LxEZdmBoCsLFlDIdIqJiSkDExIAKirbCOVa8aGjoWbo5vM0dgAyzZEVsWEhJSBCQmApoQkJQWorpY3lo7YTblGwo6tRFbFhITkJwhMSG4bPFicFPTWLWD/frmjaVt9Yz32Z4sBxkfFyxyNjXDVXyKrYkJC8issFDsK6vVNf4XaKZ1OHWWbH/J/QHlNOXxcfHBv8L1yh2MbXPWXyKqYkJD8pBE2UVHiuiF2rvmsrUpdXFYq18RFxUHvoJc5GhthyYbIqrqUkKxduxaRkZFwcXFBTEwMDh482Oax3377LaZMmYKePXvCy8sLo0ePxu7du7scMGkQyzUmJk0C3NzEob+nT8sdTetSMsVVAO2m/wjQVLLJylLf/P5EKmB2QrJ161YsWbIEL7/8MtLT0zF+/HhMmzYNOTk5rR5/4MABTJkyBUlJSTh58iQmTZqEGTNmID09vdvBk0YwITHh4gJMuf17Xollm4qaChzNOwrAjvqPAEDv3oDBIC7LrIaJYohUxuyE5L333sP8+fOxYMECDBgwAKtXr0ZoaCjWrVvX6vGrV6/GCy+8gBEjRiA6OhpvvfUWoqOjsU2JP2lJHkxIWmhetlGatMtpqG+sR5RPFKJ87KjPj8EAhIeL2yzbEFmcWQlJbW0tTp48iYSEBJP9CQkJOHLkSKfO0djYiIqKCvj6+rZ5TE1NDcrLy02+SMOYkLQwfbr4evy4ODmoktjNdPGt4VwkRFZjVkJSUlKChoYGBAaaLqIVGBiIoqKiTp3jr3/9K6qqqvDQQw+1ecyqVavg7e1t/AoNDTUnTFKTurqmvzb79ZM3FgUJDgaGDxe3lTZra0qW2H/Erso1EnZsJbKaLnVq1el0Jt8LgtBiX2u2bNmCFStWYOvWrQgICGjzuOXLl6OsrMz4lZub25UwSQ2ysoD6erEXZ0iI3NEoihLLNvnl+Th39Rx00GFy5GS5w7E9JiREVmNWQuLv7w+9Xt+iNaS4uLhFq8mdtm7divnz5+Orr75CfHz7f1k5OzvDy8vL5Is0qnm5phNJrT2ZMUN83bMHqKmRNxaJNLpmeMhw+Lq2XXbVLJZsiKzGrITEyckJMTExSE5ONtmfnJyMMWPGtPm5LVu2YN68efjHP/6B6VJxnAhg/5F2DBsmNhpVVQGpqXJHI7Lrcg3AFhIiKzK7ZLNs2TJ8+umn2LBhA86fP4+lS5ciJycHCxcuBCCWW+bMmWM8fsuWLZgzZw7++te/YtSoUSgqKkJRURHKysosdxekXkxI2qTTNXVuVULZRhAE+5x/pDkpISkpAdjZnsiizE5IZs6cidWrV2PlypUYOnQoDhw4gKSkJITfHg5XWFhoMifJ3/72N9TX1+Opp55CcHCw8evZZ5+13F2QejEhaZdUtlHCrK1nis+gqLIIbo5uGBPadouopnl5Af7+4jZbSYgsytCVDy1atAiLFi1q9b2NGzeafJ+qlLZmUiYpIeEIm1bFxYkTpWVnA2fPAoMGyReLNF38hPAJcDY4yxeI3KKixBaSzExg6FC5oyHSDK5lQ/KprGya8TI6Wt5YFMrNDZh8ezCL3GUbqVwTH2mn/UckXPWXyCqYkJB8Ll4UX3v2BHx85I1FwZqXbeRSU1+DtMtpAIApfey0/4iEq/4SWQUTEpIP+490itSx9ehRsVIgh6N5R1FdV40A9wAMDhgsTxBKwZE2RFbBhITkw4SkU0JDgSFDxAVmd+6UJwZjuSYqvlOTIGoaSzZEVsGEhOTDDq2dJpVt5FqTUurQarfDfZuTWkiys8VZhonIIpiQkHzYQtJp0jTyu3cDtbW2vfb1m9dxouAEACYkAMTZ6pycxGQkL0/uaIg0gwkJyUMQgAsXxG0mJB0aMQIICBDn4jp0yLbX3pe1D41CIwb4D0Avr162vbgS6fVAZKS4zY6tRBbDhITkcfUqUFYmTkcq1eSpTQ4OTZ1bbV22ad5/hG5jx1Yii2NCQvKQyjXh4eLMX9QhqWyzbZttZ21l/5FWMCEhsjgmJCQP9h8x25QpYteFjIym/3zWlnU9CxnXM6DX6TExYqJtLqoGXPWXyOKYkJA8OMLGbJ6ewMSJ4ratyjZSuWZU71HwdPa0zUXVgC0kRBbHhITkwQ6tXSKVbWw1ayvLNW1gQkJkcUxISB4s2XSJlJAcOgRcv27dazU0NmBv1l4AnC6+BSkhuX7d+g+CyE4wISHba2gALl0St5mQmCUyErj7bvE/4a5d1r3WqaJTuHbzGjydPDGy10jrXkxt3N2BwEBxm60kRBbBhIRsLydHnN3L2VmcF53MYquyjVSumRQ5CQYHg3UvpkYs2xBZFBMSsj2pXNO3rzjJFJlFmkZ+507rzlzO/iMd4EgbIotiQkK2xxE23TJqFODrK3ZdOHLEOteorqvGoRxxSlgmJG1gCwmRRTEhIdvjCJtu0euBxERx21plm0M5h1DbUIveXr1xlx+fU6u46i+RRTEhIdvjCJtuk8o21kpIkjOayjU6nc46F1E7qYWEJRsii2BCQrbHhKTbEhIAgwE4f946vw/Zf6QTpIQkJweoq5M3FiINYEJCtnXzpvgDHGBC0g09egDjx4vblm4lKa4qxukrpwEAcVFxlj25lgQHi+swNTYCly/LHQ2R6jEhIdvKyBBXhuvRA/D3lzsaVbNW2WZvpjgZ2pDAIQhwD7DsybVEp2PHViILYkJCttV8hA37JnSLNB9JWhpQXm6587JcYwYmJEQWw4SEbIsjbCwmOlr8z1hXB+zZY5lzCoLQlJBwuviOcS4SIothQkK2xQ6tFmXpss0vpb8grzwPTnonjAsbZ5mTahlbSIgshgkJ2RYTEouSyjY7dojr23SX1DoyLmwc3Bzdun9CrWNCQmQxTEjItpiQWNTYsYC3N1BSAhw/3v3zsf+ImZqXbARB3liIVI4JCdnOtWvib05A7ABB3eboCEybJm53t2xT31iP/Vn7ATAh6bSICPG1ogIoLZU1FCK1Y0JCtnPxovjau7e4fDtZhFS22bate+c5nn8cFbUV8HX1xdCgod2Oyy64ugIhIeI2yzZE3cKEhGyHI2ys4v77AQcH4Kefujc/lzRdfFxkHPQOXIW50zjShsgimJCQ7bD/iFX4+Yl9SQCxc2tXsf9IF7FjK5FFMCEh22FCYjXdLduU15TjWN4xAEB8VLyForITXPWXyCKYkJDtMCGxGikh2bcPqKw0//Np2WloEBrQx6cPIn0iLRuc1nHVXyKLYEJCttHY2NSplQmJxQ0YIP5erK0F9u41//Ms13QDSzZEFsGEhGyjoACorgYMBiCSf4Fbmk7XvbJNSmYKAE4X3yVSySYvD6ipkTcWIhVjQkK2IY2w6dNHTErI4qRp5HfsEBukOiuvPA/nS87DQeeASRGTrBOclvXsKQ5jFwQgO1vuaIhUiwkJ2Qb7j1jdhAmAhwdQVAScPNn5z0mtI8NDhsPH1cdK0WmYTseyDZEFMCEh22BCYnVOTsDUqeK2ObO2Gss17D/SdZyLhKjbmJCQbTAhsQlzV/8VBMGYkHC4bzewhYSo25iQkG1ICUm/fvLGoXHTpokVhB9/BPLzOz7+p+KfcKXqCtwc3TC692jrB6hVTEiIuo0JCVlfbS2QlSVus4XEqgICgPvuE7c7M2urNF18bHgsnA3OVoxM41iyIeo2JiRkfZmZQEOD2OMyKEjuaDTPnLJNShbLNRbRvIVEEOSNhUilmJCQ9TXvP6LTyRuLHZDmI0lJAW7ebPu4mvoapGWnAWCH1m4LDxf/bVdXA8XFckdDpEpMSMj62KHVpgYPBkJDxWRk3762jzuSewQ3628iyCMIgwIG2S5ALXJ2Fv+jAyzbEHURExKyPiYkNqXTda5s03x0jY4tV93Hjq1E3cKEhKyPI2xsTirbbN/edpcGaf2a+Ej2H7EIrvpL1C1MSMj6pGnj2UJiM5MmAW5u4vIqp0+3fP/azWs4UXACADu0WgxX/SXqFiYkZF3l5eJc5gAQHS1vLHbExQWYcrufamtlm31Z+yBAwMCeA9HLq5dtg9MqlmyIuoUJCVnXxYvia2Ag4O0tbyx2pr3Vf439R1iusRyWbIi6hQkJWRc7tMpm+nTx9fhx4MoV0/ek/iNT+nC4r8VILSQFBe2PtyaiVjEhIetiQiKb4GBg+HBxOympaX/m9UxkXs+EwcGA2PBYeYLTIl9fwMtL3JZmJiaiTmNCQtbFETayaq1sI5VrRvceDU9nTxmi0iidjlPIE3UDExKyLo6wkZWUkOzZA9TUiNvG4b4cXWN57NhK1GVMSMh6BIElG5ndey8QEgJUVQFpaUBDYwP2Zu4FwOnirYIJCVGXMSEh67lyBaioABwcmn5Qk03pdE2dW7dtA9KL0nH91nV4OXthRK8R8ganRSzZEHUZExKyHql1JCJCXOuDZNF81tY9GWK5ZlLEJBgcDDJGpVFsISHqMiYkZD0s1yhCfLw4UVp2NvCvn24P92W5xjqkhCQrC2hslDcWIpXpUkKydu1aREZGwsXFBTExMTh48GC7x6elpSEmJgYuLi6IiorCxx9/3KVgSWU4wkYR3NyAyZMBOFbj5NXDADj/iNWEhQF6PXDrFlBYKHc0RKpidkKydetWLFmyBC+//DLS09Mxfvx4TJs2DTk5Oa0en5WVhcTERIwfPx7p6en405/+hGeeeQbffPNNt4MnheMIG8V44AEAYQfRgFqEeYch2pfT+FuFo6OYlAAs2xCZyeyE5L333sP8+fOxYMECDBgwAKtXr0ZoaCjWrVvX6vEff/wxwsLCsHr1agwYMAALFizA448/jnfffbfNa9TU1KC8vNzki1SIJRvFeOABAH3Ecs24kHjodDp5A9IyTiFP1CVmJSS1tbU4efIkEhISTPYnJCTgyJEjrX7m6NGjLY6fOnUqTpw4gbq6ulY/s2rVKnh7exu/QkNDzQmTlKC+vmmkARMS2YWGAi53iwlJj1KWa6yKq/4SdYlZ3exLSkrQ0NCAwMBAk/2BgYEoklZ0vUNRUVGrx9fX16OkpATBwcEtPrN8+XIsW7bM+H15eblVkpJf/QqIjARGcPSj5dXVAf/f/wdcugT07i13NHZPEATMDl+OEzf2YM64OLnD0bbp0wF//9sdd4iU75FBj2BUr1EY2HOgrHF0adzfnc29giC02wTc2vGt7Zc4OzvD2QbDRGfOFL/IClxdgWZJJclLp9Phf5/9A4A/yB2K9v3Xf4lfRCox/975cocAwMySjb+/P/R6fYvWkOLi4hatIJKgoKBWjzcYDPDz8zMzXCIiItIisxISJycnxMTEIDk52WR/cnIyxowZ0+pnRo8e3eL4PXv2YPjw4XB0dDQzXCIiItIis0fZLFu2DJ9++ik2bNiA8+fPY+nSpcjJycHChQsBiP0/5syZYzx+4cKFuHz5MpYtW4bz589jw4YNWL9+PZ577jnL3QURERGpmtl9SGbOnInS0lKsXLkShYWFGDRoEJKSkhAeHg4AKCwsNJmTJDIyEklJSVi6dCk++ugjhISE4IMPPsBvf/tby90FERERqZpOkHqYKlh5eTm8vb1RVlYGLy8vucMhIiKiTjDn9zfXsiEiIiLZMSEhIiIi2TEhISIiItkxISEiIiLZMSEhIiIi2TEhISIiItkxISEiIiLZMSEhIiIi2XVptV9bk+ZuKy8vlzkSIiIi6izp93Zn5mBVRUJSUVEBAAgNDZU5EiIiIjJXRUUFvL292z1GFVPHNzY2oqCgAJ6entDpdHKHY5by8nKEhoYiNzfX7qa9573b373b630DvHd7vHd7vW+g8/cuCAIqKioQEhICB4f2e4moooXEwcEBvXv3ljuMbvHy8rK7f7AS3rv93bu93jfAe7fHe7fX+wY6d+8dtYxI2KmViIiIZMeEhIiIiGTHhMTKnJ2d8frrr8PZ2VnuUGyO925/926v9w3w3u3x3u31vgHr3LsqOrUSERGRtrGFhIiIiGTHhISIiIhkx4SEiIiIZMeEhIiIiGTHhISIiIhkx4TEglatWgWdToclS5a0eUxqaip0Ol2Lr59//tl2gVrAihUrWtxDUFBQu59JS0tDTEwMXFxcEBUVhY8//thG0VqWufeulWcOAPn5+Zg9ezb8/Pzg5uaGoUOH4uTJk+1+RivP3dx718pzj4iIaPU+nnrqqTY/o4Vnbu59a+V5A0B9fT1eeeUVREZGwtXVFVFRUVi5ciUaGxvb/Vx3n7sqpo5Xgx9++AGffPIJ7rnnnk4df+HCBZPpdnv27Gmt0Kzm7rvvRkpKivF7vV7f5rFZWVlITEzEE088gS+++AKHDx/GokWL0LNnT/z2t7+1RbgWZc69S9T+zK9fv46xY8di0qRJ2LlzJwICApCRkYEePXq0+RmtPPeu3LtE7c/9hx9+QENDg/H7M2fOYMqUKfj973/f6vFaeebm3rdE7c8bAN5++218/PHH+Pzzz3H33XfjxIkTeOyxx+Dt7Y1nn3221c9Y5LkL1G0VFRVCdHS0kJycLMTGxgrPPvtsm8fu379fACBcv37dZvFZw+uvvy4MGTKk08e/8MILQv/+/U32Pfnkk8KoUaMsHJn1mXvvWnnmL774ojBu3DizPqOV596Ve9fKc7/Ts88+K/Tp00dobGxs9X2tPPM7dXTfWnre06dPFx5//HGTfQ8++KAwe/bsNj9jiefOko0FPPXUU5g+fTri4+M7/Zlhw4YhODgYcXFx2L9/vxWjs56LFy8iJCQEkZGR+MMf/oDMzMw2jz169CgSEhJM9k2dOhUnTpxAXV2dtUO1OHPuXaL2Z/7vf/8bw4cPx+9//3sEBARg2LBh+N///d92P6OV596Ve5eo/bk3V1tbiy+++AKPP/54myuva+WZN9eZ+5Zo4XmPGzcOe/fuxS+//AIAOH36NA4dOoTExMQ2P2OJ586EpJu+/PJL/Pjjj1i1alWnjg8ODsYnn3yCb775Bt9++y369euHuLg4HDhwwMqRWtZ9992HTZs2Yffu3fjf//1fFBUVYcyYMSgtLW31+KKiIgQGBprsCwwMRH19PUpKSmwRssWYe+9aeeaZmZlYt24doqOjsXv3bixcuBDPPPMMNm3a1OZntPLcu3LvWnnuzX333Xe4ceMG5s2b1+YxWnnmzXXmvrX0vF988UU8/PDD6N+/PxwdHTFs2DAsWbIEDz/8cJufschzN68hh5rLyckRAgIChFOnThn3dVSyac0DDzwgzJgxw8LR2VZlZaUQGBgo/PWvf231/ejoaOGtt94y2Xfo0CEBgFBYWGiLEK2mo3tvjRqfuaOjozB69GiTfYsXL263SVYrz70r994aNT735hISEoQHHnig3WO08syb68x9t0atz3vLli1C7969hS1btgj/+c9/hE2bNgm+vr7Cxo0b2/yMJZ47W0i64eTJkyguLkZMTAwMBgMMBgPS0tLwwQcfwGAwmHSIas+oUaNw8eJFK0drXe7u7hg8eHCb9xEUFISioiKTfcXFxTAYDPDz87NFiFbT0b23Ro3PPDg4GAMHDjTZN2DAAOTk5LT5Ga08967ce2vU+Nwlly9fRkpKChYsWNDucVp55pLO3ndr1Pq8n3/+ebz00kv4wx/+gMGDB+PRRx/F0qVL260EWOK5MyHphri4OPz00084deqU8Wv48OGYNWsWTp061amRFwCQnp6O4OBgK0drXTU1NTh//nyb9zF69GgkJyeb7NuzZw+GDx8OR0dHW4RoNR3de2vU+MzHjh2LCxcumOz75ZdfEB4e3uZntPLcu3LvrVHjc5d89tlnCAgIwPTp09s9TivPXNLZ+26NWp93dXU1HBxM0wO9Xt/usF+LPPdutetQC3eWbF566SXh0UcfNX7//vvvC//85z+FX375RThz5ozw0ksvCQCEb775RoZou+6Pf/yjkJqaKmRmZgrHjh0THnjgAcHT01PIzs4WBKHlfWdmZgpubm7C0qVLhXPnzgnr168XHB0dha+//lquW+gyc+9dK8/8+PHjgsFgEP7yl78IFy9eFDZv3iy4ubkJX3zxhfEYrT73rty7Vp67IAhCQ0ODEBYWJrz44ost3tPqMxcE8+5bS8977ty5Qq9evYTt27cLWVlZwrfffiv4+/sLL7zwgvEYazx3JiQWdmdCMnfuXCE2Ntb4/dtvvy306dNHcHFxEXx8fIRx48YJO3bssH2g3TRz5kwhODhYcHR0FEJCQoQHH3xQOHv2rPH9O+9bEAQhNTVVGDZsmODk5CREREQI69ats3HUlmHuvWvlmQuCIGzbtk0YNGiQ4OzsLPTv31/45JNPTN7X8nM399619Nx3794tABAuXLjQ4j0tP3Nz7ltLz7u8vFx49tlnhbCwMMHFxUWIiooSXn75ZaGmpsZ4jDWeu04QBMGMlhwiIiIii2MfEiIiIpIdExIiIiKSHRMSIiIikh0TEiIiIpIdExIiIiKSHRMSIiIikh0TEiIiIpIdExIiIiKSHRMSIiIikh0TEiIiIpIdExIiIiKS3f8PaXqfV78OdxQAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAisAAAGxCAYAAACju/aQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABU30lEQVR4nO3deXxU5b0/8M9kJivZyEogCQRBSEAWw5ZQBGQrIK1XvXB/yqbQSlEUKFZxwaVcaXuVUhdQLyDYouIV3Cq1xJbEJSIEAgoJi2zZCQlkJ+uc3x+HM5lJJsksZ+acM/m8X6+8mEzOzHkyjskn3+f7PEcnCIIAIiIiIpXyUnoARERERJ1hWCEiIiJVY1ghIiIiVWNYISIiIlVjWCEiIiJVY1ghIiIiVWNYISIiIlVjWCEiIiJVY1ghIiIiVWNYISILzz33HHQ6ncuev1+/fli8eHGXx6Wnp0On0yE9Pd1037vvvotNmza1O/bixYvQ6XR46aWXnBrbO++8g8jISFRXVzv1PPZ65plncOutt8JoNLr1vERawbBCRG710Ucf4ZlnnnHosR2FFTnU1dXhySefxOOPP46goCCXnKMja9aswYULF7Bz5063npdIKxhWiMitRo4ciZtuuknpYbSzc+dOlJeXY+nSpW4/d0hICObPn48//OEP4OXaiNpjWCFysytXruDXv/414uLi4Ovri8jISIwfPx5ffvmlxXFffvklpkyZguDgYAQEBGD8+PH417/+ZXGMNGWTnZ2Nu+66C8HBwaZffFeuXLE4dvfu3Zg+fTpiYmLg7++PxMREPPHEE6itrbX7e/j888+h0+lw+PBh03179uyBTqfD7NmzLY4dNmwY7r77btPn1qaBTp06hZ///OcICAhAREQEli1b1m4qZtKkSfj8889x6dIl6HQ600dbGzduREJCAgIDA5GSkoKDBw/a9D1t2bIFc+bMQWhoqMX9RqMRr776KkaMGAF/f3+EhoZi3Lhx+PTTTy2+pzvuuAN///vfMXLkSNPr+/e//x0AsGPHDiQmJqJHjx4YM2YMsrKy2p1/wYIFOHPmDA4cOGDTeIm6E4YVIjdbsGABPv74Y6xbtw779+/H1q1bMXXqVJSXl5uO+dvf/obp06cjODgYO3fuxAcffICwsDDMmDGjXWABgP/4j//AgAED8OGHH+K5557Dxx9/jBkzZqCpqcl0zNmzZzFr1ixs27YNX3zxBVauXIkPPvgAc+bMsft7mDhxIry9vS0C1pdffgl/f39kZGSYzltaWooTJ05g6tSpHT7X5cuXMXHiRJw4cQKbN2/GX//6V9TU1ODhhx+2OG7z5s0YP348evXqhe+++870Ye71119HWloaNm3ahF27dqG2thazZs1CZWVlp99PQUEBfvzxR0yePLnd1xYvXoxHH30Uo0ePxu7du/H+++/jF7/4BS5evGhx3PHjx7F27Vo8/vjj2Lt3L0JCQnDXXXfh2WefxdatW/Hiiy9i165dqKysxB133IHr169bPD45ORmBgYH4/PPPOx0rUbckEJFbBQYGCitXruzw67W1tUJYWJgwZ84ci/tbWlqE4cOHC2PGjDHd9+yzzwoAhFWrVlkcu2vXLgGA8Le//c3qOYxGo9DU1CRkZGQIAITjx4+3e86u/OxnPxNuv/120+cDBgwQHnvsMcHLy0vIyMiwGMeZM2dMx/Xt21dYtGiR6fPHH39c0Ol0wrFjxyyef9q0aQIA4cCBA6b7Zs+eLfTt27fdWC5cuCAAEG655RahubnZdP+hQ4cEAMJ7773X6feye/duAYBw8OBBi/u/+uorAYDw1FNPdfr4vn37Cv7+/kJBQYHpvmPHjgkAhJiYGKG2ttZ0/8cffywAED799NN2zzN+/Hhh7NixnZ6LqDtiZYXIzcaMGYMdO3Zg/fr1OHjwoEX1AwAyMzNx9epVLFq0CM3NzaYPo9GIn//85zh8+HC7qZv77rvP4vO5c+fCYDBYTCmcP38e9957L3r16gW9Xg9vb29MnDgRAJCbm2v39zFlyhR8++23uH79Oi5duoSffvoJ//Vf/4URI0YgLS0NgFhtiY+Px8CBAzt8ngMHDmDIkCEYPny4xf333nuv3WOaPXs29Hq96fNhw4YBAC5dutTp44qKigAAUVFRFvf/4x//AAA89NBDXZ57xIgR6NOnj+nzxMREAOL0VUBAQLv7rY0pKioKhYWFXZ6LqLthWCFys927d2PRokXYunUrUlJSEBYWhoULF6KkpASAOC0CAPfccw+8vb0tPv74xz9CEARcvXrV4jl79epl8bnBYEB4eLhpaqmmpgYTJkzA999/j/Xr1yM9PR2HDx/G3r17AaDdlIQtpk6dioaGBnzzzTdIS0tDREQERo4cialTp5qmh/71r391OgUEAOXl5e3Gb+17skV4eLjF576+vgC6/v6kr/v5+Vncf+XKFej1epvGEhYWZvG5j49Pp/fX19e3ew4/Pz+H/lsQeTqD0gMg6m4iIiKwadMmbNq0CXl5efj000/xxBNPoLS0FF988QUiIiIAAK+++irGjRtn9Tmio6MtPi8pKbH4q765uRnl5eWmX97//ve/UVRUhPT0dFM1BQAqKioc/j7Gjh2LwMBAfPnll7h48SKmTJkCnU6HKVOm4OWXX8bhw4eRl5fXZVgJDw83BbW235O7SK/51atXERMTY7o/MjISLS0tKCkpsbjfVa5evWoaCxG1YmWFSEHx8fF4+OGHMW3aNBw9ehQAMH78eISGhiInJwejRo2y+iH9dS7ZtWuXxecffPABmpubMWnSJAAwrZqRKg2SN9980+Gxe3t747bbbkNaWhr+/e9/Y9q0aQCACRMmwGAw4OmnnzaFl85MnjwZJ0+exPHjxy3uf/fdd9sd6+vr65LKw+DBgwEA586ds7h/5syZAMSVQu5w/vx5JCUlueVcRFrCygqRG1VWVmLy5Mm49957MXjwYAQFBeHw4cP44osvcNdddwEAAgMD8eqrr2LRokW4evUq7rnnHkRFReHKlSs4fvw4rly50u6X5969e2EwGDBt2jScPHkSzzzzDIYPH465c+cCAFJTU9GzZ08sW7YMzz77LLy9vbFr1652AcFeU6ZMwW9/+1sAMFVQ/P39kZqaiv3792PYsGHt+kDaWrlyJbZv347Zs2dj/fr1iI6Oxq5du3Dq1Kl2x95yyy3Yu3cvtmzZguTkZHh5eWHUqFFOfQ+AWCXy9/fHwYMH8Ytf/MJ0/4QJE7BgwQKsX78ely9fxh133AFfX19kZ2cjICAAK1ascPrckvLycpw9e1bW5yTyFKysELmRn58fxo4di7/+9a+47777MHPmTGzduhWPP/44/vd//9d03Pz583HgwAHU1NTgwQcfxNSpU/Hoo4/i6NGjVisVe/fuxalTp3DXXXdh3bp1mDNnDvbv32+qwISHh+Pzzz9HQEAA5s+fjwceeACBgYHYvXu3U9+PFFAGDhyIvn37tru/qykgQOxNycjIQFJSEn7zm99g/vz58PPzw2uvvdbu2EcffRT33HMPnnzySYwbNw6jR492avwSHx8f3HPPPfjkk0/afW3Hjh3YuHEjMjMzcc8992Du3Ln45JNPkJCQIMu5JZ988gm8vb1NAZOIWukEgdslEmnVc889h+effx5Xrlxhr4OTsrKyMHr0aBw8eBBjx451+/knTJiA+Pj4dlN6RMTKChERAGDUqFGYO3cufv/737v93F999RUOHz6syLmJtIBhhYjohpdffhmjR492+1WXy8vL8c4776B///5uPS+RVnAaiIiIiFSNlRUiIiJSNYYVIiIiUjWGFSIiIlI1TWwKZzQaUVRUhKCgINNOnERERKRugiCguroavXv3hpeX4/URTYSVoqIixMXFKT0MIiIickB+fj5iY2MdfrwmwkpQUBAA8ZsNDg5WeDRERERki6qqKsTFxZl+jztKE2FFmvoJDg5mWCEiItIYZ1s42GBLREREqsawQkRERKrGsEJERESqpomeFSIi6r4EQUBTUxOam5uVHgq1YTAY4O3t7fJtRRhWiIhItRoaGnDx4kXU1NQoPRTqQGBgIPr16wdfX1+XnYNhhYiIVMloNCInJwcGgwEJCQnw9fXlxqAqIggCGhoaUFhYiJMnT2LIkCEuCywMK0REpEr19fUwGo1ISEhAYGCg0sMhK3r06AEfHx+cPn0a+/btw9SpU53eU8UaNtgSEZGqObNNO7me9N+noKAAn3/+Oerr6+U/h+zPSERERN1OZGQkCgoKcPXqVdmfm2GFiIiInGYwGNDc3KyOyspXX32FOXPmoHfv3tDpdPj444+7fExGRgaSk5Ph5+eH/v3744033nBkrERERNQN2R1WamtrMXz4cLz22ms2HX/hwgXMmjULEyZMQHZ2Np588kk88sgj2LNnj92DJSIi0oLFixfjzjvvVHoYHsPu1UAzZ87EzJkzbT7+jTfeQHx8PDZt2gQASExMRFZWFl566SXcfffdVh/T0NCAhoYG0+dVVVX2DtMmFy4Ab74JuKBiRRo1cyYwY4abTvbPfwL/+IebTqZiOh3wH/8B3Hab0iMxuVRxCZsPb0ZDS0PXB5PLhBnCMLvnbKWHQSrg8qXL3333HaZPn25x34wZM7Bt2zY0NTXB29u73WM2bNiA559/3tVDw4svAlu3uvw0pCFvvw1cuwa4fPGBIAD/7/+JJyPgo4+AixeVHoXJU/9+Crt+3KX0MLq9QcGDMPs2y7AiCEBdnTLjCQgQs7WzMjIy8Nhjj+H48eMICwvDokWLsH79ehgMBnz22WdYsGABrl69Ci8vLxw7dgwjR47EmjVr8D//8z8AgAcffBBVVVV47733nB+MRrg8rJSUlCA6OtrivujoaDQ3N6OsrAwxMTHtHrN27VqsXr3a9HlVVRXi4uJkH1ttrfjv1KnAmDGyPz1pzMsvA1VV4u/M/v1dfLLa2tag8rvfAYZuuuVRfT2wcSOQlwc0NQFW/nhRwjd53wAA7h9xP2IC2/+MIvcI1Ye2u6+uDlBqy5WaGqBHD+eeo7CwELNmzcLixYvxzjvv4NSpU/jVr34FPz8/PPfcc7jttttQXV2N7OxsJCcnIyMjAxEREcjIyDA9R3p6OlatWuXkd6MtbvkJ2XbHQUEQrN4v8fX1dem2vW3dcQfw6KNuOx2p1OefA8ePAydPuiGsXLki/uvnB/zhD/L8uaZFRiPw6qtiUCkqAvr2VXpEKKouwqXKS/DSeeEvP/8Lgnzl3+CKbFNXV4fc3FylhyGrzZs3Iy4uDq+99hp0Oh0GDx6MoqIiPP7441i3bh1CQkIwYsQIpKenIzk52RRMnn/+eVRXV6O2thZnzpzBpEmTlP5W3MrlS5d79eqFkpISi/tKS0thMBgQHh7u6tMT2WzIEPHfkyfdcLLSUvHfqKjuG1QAcb4tNla8nZ+v7Fhu+C7/OwDALVG3MKioUECAWOFQ4iMgwPnx5+bmIiUlxeKP9fHjx6OmpgYFBQUAgEmTJiE9PR2CIODrr7/GL3/5SwwdOhTffPMNDhw4gOjoaAwePNj5wWiIyysrKSkp+Oyzzyzu279/P0aNGmW1X4VIKW4NK1JlJTLSDSdTubg4sdv9xg9qpX1XIIaVlNgUhUdC1uh0zk/FKEkQhC5nGyZNmoRt27bh+PHj8PLyQlJSEiZOnIiMjAxcu3YNEydOdPu4lWZ3ZaWmpgbHjh3DsWPHAIhLk48dO4a8vDwAYr/JwoULTccvW7YMly5dwurVq5Gbm4vt27dj27ZtWLNmjTzfAZFMFAkrUVFuOJnKqa2yIoWVOIYVkl9SUhIyMzNNAQUAMjMzERQUhD59+gCAqW9l06ZNmDhxInQ6HSZOnIj09HSkp6czrNgiKysLI0eOxMiRIwEAq1evxsiRI7Fu3ToAQHFxsSm4AEBCQgL27duH9PR0jBgxAr///e/xyiuvdLhsmUgpUljJzQVaWlx8MmkaiJUVsbICqCKsNDQ3IKsoCwArK+S8yspK0x/30sevf/1r5OfnY8WKFTh16hQ++eQTPPvss1i9erXpGjtS38rf/vY3U2/KbbfdhqNHj3bLfhXAgWmgSZMmWSTCtnbs2NHuvokTJ+Lo0aP2norIrRISxH7X+npxVmLAABeejJWVVlJlRQXTQNkl2WhsaUREQAQGhLnyDUDdQXp6uukPe8miRYuwb98+PPbYYxg+fDjCwsKwZMkSPP300xbHTZ48GUePHjUFk549eyIpKQlFRUVITEx017egGt10vSRRe3o9kJgIZGeLU0EuDSusrLRSUWVFaq5NiU3pcLUikS127Nhh9Y93yaFDhzp9/EsvvYSXXnrJ4j6p/aI74oUMicy4rW+FlZVWUlhRQWUlsyATAKeAiNSGYYXIjNvCCisrraRpoMuXgcZGRYdiqqywuZZIVRhWiMywsqKAyEjA11fcR72wULFh5Ffmo7C6EHqdHqN7j1ZsHETUHsMKkRkprJw65cIVQYLAyoo5nU4VTbbSkuXhvYajh4+GN/Ig8kAMK0Rm+vUD/P2Bhgbg3DkXnaSmRjwBwLAiUcFeK5n57FchUiuGFSIzXl7iiiDAhVNBUlUlIEDbW3HKSQUrgrhzLZF6MawQteHyvhVutd+ewtNA9c31yC7OBgCkxqUqMgYi6hjDClEbUljJyXHRCcwvYkgihSsrR4qOoMnYhOge0egX2k+RMRBRxxhWiNpgZUUBCu+1YupXieNmcERqxLBC1Ib5iqDmZhecgJWV9hRusGW/CmlNeno6dDodKioqAIg75oaGhio6JldiWCFqo29fsfe1sdFFK4JYWWlPqqyUlraulHITQRBMYYX9KiSXxYsXQ6fTYdmyZe2+tnz5cuh0OixevFi2882bNw9nzpyR7fnUhmGFqA0vLyApSbztkqkgVlbaCw8XryIJuH1juEuVl1BSUwKDlwHJMcluPTd5tri4OLz//vu4fv266b76+nq89957iI+Pl/Vc/v7+iPLgnykMK0RWuLRvhZWV9sw3hnPzVJDUrzKy10j4e/u79dzkAEEAamuV+RAEu4Z66623Ij4+Hnv37jXdt3fvXsTFxVlcjVkQBPzpT39C//794e/vj+HDh+PDDz+0eK59+/bh5ptvhr+/PyZPnoyLFy9afL3tNNDixYtx5513WhyzcuVK01WcAWDSpElYsWIFVq5ciZ49eyI6OhpvvfUWamtrcf/99yMoKAg33XQT/vGPf9j1fbsCwwqRFS4NK6ysWKfQiiDzKy2TBtTVAYGBynzU1dk93Pvvvx9vv/226fPt27fjgQcesDjm6aefxttvv40tW7bg5MmTWLVqFebPn4+MjAwAQH5+Pu666y7MmjULx44dw9KlS/HEE0849zresHPnTkRERODQoUNYsWIFfvOb3+A///M/kZqaiqNHj2LGjBlYsGAB6hz43uXEsEJkBSsrClBorxX2q5ArLViwAN988w0uXryIS5cu4dtvv8X8+fNNX6+trcXGjRuxfft2zJgxA/3798fixYsxf/58vPnmmwCALVu2oH///vjzn/+MQYMG4b777pOt32X48OF4+umnMXDgQKxduxb+/v6IiIjAr371KwwcOBDr1q1DeXk5fvjhB1nO5yiDomcnUikprJw+DTQ1Ad7eMj2xIPAihh1RoLJS21iLYyXHAPBKy5oRECBeskKpc9spIiICs2fPxs6dOyEIAmbPno2IiAjT13NyclBfX49p06ZZPK6xsdE0VZSbm4tx48ZZLKtPSZHn/Tps2DDTbb1ej/DwcNxyyy2m+6KjowEApVJFWCEMK0RWxMeLVd+aGuCnn1q34HdaVZW4zAhgZaUtBfZaySrKQovQgt5BvREXHOe285ITdDrNXabigQcewMMPPwwAeP311y2+ZjQaAQCff/45+vTpY/E1X19fAGJPi728vLzaPa6pqandcd5t/hLT6XQW90kBSRqnUhhWiKzQ6cQVQYcOiVNBsoUVqaoSGCheMZFaKdBga76/CjeDI1f5+c9/jsYbf6TMmDHD4mtJSUnw9fVFXl4eJk6caPXxSUlJ+Pjjjy3uO3jwYKfnjIyMxIkTJyzuO3bsWLtwohXsWSHqgEv6VqRSKqsq7SkwDcR+FXIHvV6P3Nxc5ObmQq/XW3wtKCgIa9aswapVq7Bz506cO3cO2dnZeP3117Fz504AwLJly3Du3DmsXr0ap0+fxrvvvosdO3Z0es7bb78dWVlZeOedd3D27Fk8++yz7cKLljCsEHXAJWGF/Sodk8JKWRlQX+/y0wmCwJVA5DbBwcEIDg62+rXf//73WLduHTZs2IDExETMmDEDn332GRISEgAA8fHx2LNnDz777DMMHz4cb7zxBl588cVOzzdjxgw888wz+N3vfofRo0ejuroaCxculP37ched4MhkmJtVVVUhJCQElZWVHf7HdsS99wLvvQds2gQ8+qhsT0se4osvgJkzxekg2QLL//4v8OtfA3fcAXz2mUxP6iEEQexFuH4dOHsWGDDApaf76epPGPjqQPjofVD1RBV8Db4uPR/Zr66uDrm5uUhMTESAA82t5B7Sf6cLFy7gp59+wty5c9G/f38A8v3+ZmWFqANSZeXMmdaeWKdx2XLHdDq3TgVJVZVbY25lUCFSOYYVog7ExgJBQeLFDM+elelJuSFc59y4IsjUrxLLfhUitWNYIeqAtCIIkHEaiJWVzrlxRZBpJRD3VyFSPYYVok7I3mTLykrn3FRZqW6oxg+XxR052VxLpH4MK0SdkD2ssLLSOTdVVg4XHYZRMCIuOA59gvt0/QAiUhTDClEnpLCSkyPTE7Ky0jk3NdhKzbXcX4VIGxhWiDohhZWzZ2VYEWR+XSBWVqxz0zSQ+c61RKR+DCtEnejTBwgOFlcEnTnj5JNVVIhPBDCsdESaBiovB1x0SXpBENhcS6QxDCtEndDpZOxbkaoqQUGAn5+TT+ahQkNbL1LnourKmfIzuHr9KvwMfhjRa4RLzkFE8mJYIeqCbGGF/SpdM98YzkVhRaqqjOo9Cj56H5ecg8gWO3bsQGhoqF2PWbx4Me68806XjEfNGFaIuiB7ZYVTQJ1z8YqgzPxMAOxXIdfqKFSkp6dDp9OhoqIC8+bNwxmn55e7B4PSAyBSO9nDCisrnXPxiiA215Ja+Pv7w9/fX+lhaAIrK0RdkMLKTz8BDQ1OPJE0DcTKSuekyooLpoEq6ytxslRMnWyu1SZBEFDbWKvIh9zX/bU2DbR+/XpERUUhKCgIS5cuxRNPPIERI0a0e+xLL72EmJgYhIeH46GHHkJTU5OsY1MbVlaIuhATI/Z9VlQAp08Dw4Y5+ESsrNjGhZWVQ4WHIEBAQmgCegX2kv35yfXqmuoQuCFQkXPXrK1BD58eLnv+Xbt24b//+7+xefNmjB8/Hu+//z5efvllJCQkWBx34MABxMTE4MCBA/jpp58wb948jBgxAr/61a9cNjalMawQdUFaEfTtt+JUkMNhhZUV27iwwdbUr8KqCrnB3//+dwQGWgarlpaWDo9/9dVXsWTJEtx///0AgHXr1mH//v2oqamxOK5nz5547bXXoNfrMXjwYMyePRv/+te/GFaIujvzsOIwVlZs48IGW/araF+AdwBq1tZ0faCLzm2PyZMnY8uWLRb3ff/995g/f77V40+fPo3ly5db3DdmzBj8+9//trhvyJAh0Ov1ps9jYmLw448/2jU2rWFYIbKBLE22rKzYRqqsXLsG1Na27rviJKNgxMGCgwC4zb6W6XQ6l07FyKlHjx4YMGCAxX0FXVQMdTqdxefW+mS8vb3bPcZoNDo4Sm1ggy2RDWQJK1y6bJuQEHHjPEDWqaBTZadQ2VCJAO8ADIt2dC6PyHUGDRqEQ4cOWdyXlZWl0GjUhWGFyAZSWDl3Dqivd+AJjEZOA9nDBVNBUr/K6N6jYfBiUZnUZ8WKFdi2bRt27tyJs2fPYv369fjhhx/aVVu6I4YVIhtERwNhYWLmOHXKgSeoqACkxrqICDmH5plcsCJIutIy+1VIre677z6sXbsWa9aswa233ooLFy5g8eLF8OPlOdizQmQLnQ5ISgK++UacCrKy7UHnpH6VkBDA11fu4XkeF6wIkppr2a9C7rBjxw6r90+aNMnUh7J48WIsXrzY4uvPPPMMnnnmGdPn06ZNs+h7sfa8mzZtcna4qsewQmSjIUNaw4rd2K9iH5mnga5dv4bcslwAwLjYcbI8J5Hc6urq8MYbb2DGjBnQ6/V477338OWXXyItLU3poSmOYYXIRk412fIihvaRubIirQIaEDYAkT0YGEmddDod9u3bh/Xr16OhoQGDBg3Cnj17MHXqVKWHpjiGFSIbORVWWFmxj8yVFe6vQlrg7++PL7/8UulhqBIbbIlsJIWV8+eB69ftfDArK/aRucGW/SpE2sawQmSjqCggPBwQBAdWBLGyYh8prFRWAtXVTj1Vi7EF3xd8D4CVFa3y9A3PtM4d/30YVohsJF0jCHBgKoiVFfsEBQHBweJtJ/tWTl45ierGagT6BGJo1FAZBkfu4uPjAwDtro1D6iL993HllZ/Zs0JkhyFDgK++ciCssLJiv7g48YXOzwcSEx1+Gml/lTF9xkDvpe/iaFITg8GAiIgIFBYWAgACAwPh5cW/sdXCaDSipqYGhYWFqKioMF2k0RWb2DGsENmBlRU3ksKKk5UVU79KLPtVtCg+Ph4ATIGF1KeiogKXL19GXV0dfHx84O/vL/s5GFaI7OBwWGFlxX4yrQgyrQSKY7+KFul0OvTt2xdhYWE4cOAALl26hMDAQIurDpNz0i+m43LtZaTEpiA+JN7mxwmCgMbGRrS0tKCpqQk1NTUYMWIEwsPDZR8jwwqRHaSwcuECUFcHBNhyxXijESgrE2+zsmI7GfZaKasrw5nyMwC4GZzWBQUFYcqUKfjyyy9RVFRkmnIg5xWXF6OoqgjlgeUI1YU69Bw+Pj5ITk7G5MmT210VWg4MK0R2iIwUP65cAXJzgeRkGx509aoYWABeF8geMlRWpM3gBoUPQph/mByjIgX16NEDv/zlL9HU1ITm5malh+MxPnrvI5y8eBJrZq3BPUn3OPQcPj4+Lq12MawQ2WnIECA9XZwKsimsSFNAPXsCLviLw2PJsNeK1FzL/VU8i7e3t0v+eu+2DECLvgXevt4u6TeRA9uqiexkd9+K1FzLfhX7yDANxJ1riTyDQ2Fl8+bNSEhIgJ+fH5KTk/H11193evyuXbswfPhwBAQEICYmBvfffz/Ky8sdGjCR0uwOK2yudYw0DVRVJX7YqdnYjO8Lb2wGx+ZaIk2zO6zs3r0bK1euxFNPPYXs7GxMmDABM2fORF5entXjv/nmGyxcuBBLlizByZMn8X//9384fPgwli5d6vTgiZTgcGWFzbX2CQwEQkPF2w5MBf14+UfUNdUh2DcYSZFJ8o6NiNzK7rCyceNGLFmyBEuXLkViYiI2bdqEuLg4bNmyxerxBw8eRL9+/fDII48gISEBP/vZz/Dggw8iKyvL6cETKUEKKxcvAjZtrMnKiuOcmAqSpoDGxY6Dl44z3kRaZtf/wY2NjThy5AimT59ucf/06dORmZlp9TGpqakoKCjAvn37IAgCLl++jA8//BCzZ8/u8DwNDQ2oqqqy+CBSi/BwIDpavJ2ba8MDWFlxnBMrgjLzxZ9J7Fch0j67wkpZWRlaWloQLf2kviE6OholJSVWH5Oamopdu3Zh3rx58PHxQa9evRAaGopXX321w/Ns2LABISEhpo846a8rIpVIujGrYNNUECsrjnNiRRCba4k8h0O10bb7/guC0OG1AHJycvDII49g3bp1OHLkCL744gtcuHABy5Yt6/D5165di8rKStNHvkyXiSeSi119K6ysOM7BaaDS2lKcv3YeADA2dqzcoyIiN7Nrn5WIiAjo9fp2VZTS0tJ21RbJhg0bMH78eDz22GMAgGHDhqFHjx6YMGEC1q9fj5iYmHaP8fX1ha+vrz1DI3Iru8IKKyuOc3AaSNpfZUjkEIT6hco8KCJyN7sqK9J2umlpaRb3p6WlITXV+qZLdXV17a6SKe1yJwiCPacnUg1WVtzEwcoK+1WIPIvd00CrV6/G1q1bsX37duTm5mLVqlXIy8szTeusXbsWCxcuNB0/Z84c7N27F1u2bMH58+fx7bff4pFHHsGYMWPQu3dv+b4TIjeSwkpeHlBd3cmBLS2AtKcQKyv2M6+s2PHHDS9eSORZ7N5uf968eSgvL8cLL7yA4uJiDB06FPv27UPfvn0BAMXFxRZ7rixevBjV1dV47bXX8Nvf/hahoaG4/fbb8cc//lG+74LIzcLCgF69gJIScUXQmDEdHFhe3vpLltcFsp9UWampASorW/dd6URTSxOyisStEbjNPpFncOjaQMuXL8fy5cutfm3Hjh3t7luxYgVWrFjhyKmIVGvIEDGsnDzZSViR+lXCwgADL8Vlt4AA8bW7elWcCrIhrBy/fBzXm6+jp19P3Bx+s+vHSEQux52SiBxkU98K+1WcZ2eTrdSvws3giDwH/08mcpBNYYUrgZxn514r3F+FyPMwrBA5yK6wwsqK4+xcESQtW2a/CpHnYFghcpAUVvLzO7kosDQNxMqK4+yYBiqqLsKlykvw0nlhTJ+OGomISGsYVogcFBoKSKvvc3I6OIiVFefZUVmRqipDo4YiyDfIlaMiIjdiWCFyQpdTQaysOM+Oygr7VYg8E8MKkRO6DCtssHWeeYNtFxvDSWGF/SpEnoVhhcgJNldWOA3kOKmyUlcHVFR0eFhDcwOOFB0BwMoKkadhWCFyAisrbuDvD4SHi7c7mQrKLslGQ0sDIgIiMCBsgJsGR0TuwLBC5ISkJPHfwkIrf/Q3N7deF4iVFefYsNeK1Fw7LnYcdDqdO0ZFRG7CsELkhJCQ1lmKdiuCpKCi07VWBsgxNqwIMvWrxLJfhcjTMKwQOUmqrrSbCpL6VcLDAb3erWPyODasCOKVlok8F8MKkZM67Fthv4p8uqis5Ffmo6CqAHqdHqN7j3bjwIjIHRhWiJzUYVjhSiD5dFFZkaoqw6KHoYdPD3eNiojchGGFyEmsrLhBFw22vB4QkWdjWCFyktSzUlwMXLtm9gVWVuRjPg1kZWM47lxL5NkYVoicFBzc+rvUYkUQKyvy6dNH/Pf6deDqVYsv1TfX42jxUQBsriXyVAwrRDKwOhXEyop8/PxaQ1+bqaAjRUfQZGxCVI8oJIQmKDA4InI1hhUiGVgNK6ysyKuDFUHm1wPiZnBEnolhhUgGrKy4QQcrgtivQuT5GFaIZMDKihtYqawIgoDM/EwADCtEnoxhhUgG0oqgkpIb/Z9NTa1Lg1hZkYeV5cuXKi+hpKYEBi8DRvUepdDAiMjVGFaIZBAYCPTtK94+eRJAWZn4iZcXEBam2Lg8ipVpIGl/lZG9RsLf21+JURGRGzCsEMnEYipImgIKDxcDCznPyjQQp4CIugf+FCWSiUVYYXOt/KTKitnGcLx4IVH3wLBCJBOrlRU218pH2hiuvh4oK0NdUx2OXz4OgJUVIk9nUHoARJ6ClRUX8/UFoqOBy5eBggJk1VWj2diM3kG9ER8Sr/ToiMiFWFkhkkliovhvaSlQd4mVFZcwa7I171fhZnBEno1hhUgmPXoACTd2e684y8qKS5gtX+ZmcETdB8MKkYyk/Vbq81lZcYkbYUUoyDctW2ZzLZHnY1ghkpHUtyJcZmXFJW5MA50vycWVuivw0fvg1phbFR4UEbkawwqRjKSw4lPJyopL3KisZNadAQDcGnMr/Ax+So6IiNyAYYVIRlJYCa5nZcUlblRWvtMXAWC/ClF3wbBCJKPERMAHjQgRKsU7WFmR143Kynch1QCA1LhUJUdDRG7CsEIko4AAIDlenAISvPRAz54Kj8jD9O6NGh/ghyhxB1tWVoi6B4YVIpmN7ieGles9InhdILn5+ODQ0J4wegFxftHoE9xH6RERkRvwJymRzIbHiP0q17zZr+IK3w0KAACk+A5QeCRE5C4MK0Qyu7mnWFkpMbJfxRW+i2kBAKQ29VJ4JETkLgwrRDLr10MMK5fqoqSLA5NMBEHAd4EVAICUqwHKDoaI3IZhhUhm0TpxGqigMdJ0PUOSx5nyM7jqVQ+/JmBEXqPSwyEiN2FYIZKZd4VYWSlFlHgFZpKNdD2g5GLAJ79I4dEQkbswrBDJ7UY55QoiGVZkJl0PKDUfQH6+soMhIrdhWCGS2xWxssKwIj/TlZbzARQWAkajsgMiIrdgWCGS243KCqeB5FVZX4kTpScAACkFAJqawKYgou6BYYVIbm0qK1wRJI9DhYcgQEC/0H7oFdxbvJNTQUTdAsMKkZwaGoCqKgBAmS4K164BJSUKj8lDSFNAqXGppmsEoaBAwRERkbswrBDJ6UZVBQYDIgaEAgCngmRi6leJTTFdfZmVFaLugWGFSE5SD0VkJJKG6AAwrMjBKBhNK4FSYlNYWSHqZhhWiOQkVVYiIzFkiHiTYcV5p8pOobKhEv4GfwyLHtYaVlhZIeoWGFaI5CRVVqKiGFZkJFVVxvQZA2+9N6eBiLoZhhUiOXVQWeGKIOdY9KsAnAYi6mYYVojkZFZZGTQI0OuBykqgiDvDOyUzPxMAkBJ3I6xIlZXCQqClRaFREZG7MKwQycmssuLrCwwYIH7KqSDHXbt+DblluQCAcbHjxDtjYgAvL6C5Gbh8WcHREZE7MKwQycmssgLANBWUk6PQeDzA94XfAwAGhA1AVA/xdYXBAPS+sTEcp4KIPB7DCpGczCorANhkKwPTFJDUryJhky1Rt8GwQiSnDiorDCuOa9dcK+HyZaJuw6GwsnnzZiQkJMDPzw/Jycn4+uuvOz2+oaEBTz31FPr27QtfX1/cdNNN2L59u0MDJlK1TiorXBFkvxZjC74vEKeBTM21Eq4IIuo2DPY+YPfu3Vi5ciU2b96M8ePH480338TMmTORk5OD+Ph4q4+ZO3cuLl++jG3btmHAgAEoLS1Fc3Oz04MnUpXr14GaGvH2jcrKzTeL7RVVVeLCFWnmgmyTcyUH1Y3VCPQJxNCooZZf5DQQUbdhd1jZuHEjlixZgqVLlwIANm3ahH/+85/YsmULNmzY0O74L774AhkZGTh//jzCwsIAAP369XNu1ERqJFVVvL2B4GAAgI8PMHAgkJsrVlcYVuwj9auM6TMGBq82P65YWSHqNuyaBmpsbMSRI0cwffp0i/unT5+OzMxMq4/59NNPMWrUKPzpT39Cnz59cPPNN2PNmjW4fv16h+dpaGhAVVWVxQeR6plPAel0prvZt+K4DvtVAFZWiLoRu8JKWVkZWlpaEB0dbXF/dHQ0SkpKrD7m/Pnz+Oabb3DixAl89NFH2LRpEz788EM89NBDHZ5nw4YNCAkJMX3ESX9BEalZm+ZaCcOK4zoNK9LPhaIibgxH5OEcarDVmf3VCACCILS7T2I0GqHT6bBr1y6MGTMGs2bNwsaNG7Fjx44Oqytr165FZWWl6SOffzmRFrRprpUwrDimrK4MZ8rPADDbDM5cr17iFsEtLUAHfywRkWewK6xERERAr9e3q6KUlpa2q7ZIYmJi0KdPH4SEhJjuS0xMhCAIKOhgrtnX1xfBwcEWH0Sq10VlJSeHK4LscbDgIABgUPgghAeEtz9Ar2/dGI5/0BB5NLvCio+PD5KTk5GWlmZxf1paGlJTU60+Zvz48SgqKkKNtEoCwJkzZ+Dl5YVYdhuSJ+mgsjJwoNhzW13N36n2kK603G7JsjnutULULdg9DbR69Wps3boV27dvR25uLlatWoW8vDwsW7YMgDiFs3DhQtPx9957L8LDw3H//fcjJycHX331FR577DE88MAD8Pf3l+87IVJaB5UVb29xCTPAqSB7dNqvIuGKIKJuwe6ly/PmzUN5eTleeOEFFBcXY+jQodi3bx/69u0LACguLkZeXp7p+MDAQKSlpWHFihUYNWoUwsPDMXfuXKxfv16+74JIDTqorABAUpIYVE6eBGbOdPO4NKjZ2IxDhYcAAKlx1qu2ALgiiKibsDusAMDy5cuxfPlyq1/bsWNHu/sGDx7cbuqIyON0UFkBxL6V//s/VlZs9ePlH1HbVItg32AkRSZ1fCArK0TdAq8NRCSXTiorXBFkH2kKaGyfsfDSdfJjij0rRN0CwwqRXLqorADiiiCj0Y1j0igprHQ6BQRwGoiom2BYIZJDbS1QVyfetlJZGTBAbLStrQXMWrqoA6aVQJ011wKtlZXiYoDXGyPyWAwrRHKQpoB8fYGgoHZf9vYGBg0Sb3MqqHOltaU4d+0cAGBs7NjOD46KEq8UaTSKgYWIPBLDCpEcOrgukDnzqSDqmFRVSYpMQqhfaOcH6/VAnz7ibU4FEXkshhUiOXTSryJhk61tTP0qsV30q0i4IojI4zGsEMmhk5VAEoYV25g2g+ts51pzbLIl8ngMK0RykMKKDZUVrgjqWFNLEw4XHgZgQ3OthJUVIo/HsEIkB2kaqJPKyk03AT4+4qKhS5fcNC6NOX75OK43X0eoXygGRQyy7UHca4XI4zGsEMnBhmkggwEYPFi8zakg68yXLHe6GZw5TgMReTyGFSI52NBgC7BvpSs2XbywLU4DEXk8hhUiOdhQWQEYVrqSmZ8JwI7mWqC1slJcDDQ1uWBURKQ0hhUiObCy4rTi6mJcqrwEHXQY02eM7Q+MihJ33RMEoKjIdQMkIsUwrBA5SxDsrqzk5nJFUFvSFNAt0bcg2DfY9gd6ebVWVzgVROSRGFaInFVbC1y/Lt7uorLSvz/g5ycefuGCG8amIaYpIHv6VSRssiXyaAwrRM6Sqip+fkCPHp0eqtdzRVBHHGqulbDJlsijMawQOcu8X6WD6wKZS0oS/2VYadXY0ogjRUcA2NlcK+FeK0QejWGFyFk29qtI2GTbXnZxNhpaGhDuH46BYQPtfwJOAxF5NIYVImfZuBJIwrDSnvmSZZ0N1al2OA1E5NEYVoic5WBl5dQpoKXFRWPSGKf6VQBOAxF5OIYVImfZWVlJSBB7cevrgfPnXTguDXE6rEjTQJcvA42NMo2KiNSCYYXIWXZWVvR6IDFRvM2pICC/Mh8FVQXQ6/QY3We0Y08SGSleJZIbwxF5JIYVImfZWVkB2LdiTqqqDIsehkCfQMeeRKdjky2RB2NYIXKWnZUVoDWs5OS4YDwaY36lZaewb4XIYzGsEDmLlRWnmPpVHNlfxRxXBBF5LIYVImfYcV0gc1wRJKpvrsfR4qMAgNS4VOeejNNARB6LYYXIGTU1QEODeNuOsNKvHxAQID703DnXDE0LjhQdQZOxCVE9opAQmuDck7GyQuSxGFaInCFNAQUEdHldIHNeXlwRBFguWXZoMzhz7Fkh8lgMK0TOcGAKSMK+FRn2VzHHaSAij8WwQuQMB5prJd09rAiCYNpm3+l+FaC1slJa2jo1R0QegWGFyBmsrDjsUuUllNSUwOBlwKjeo5x/wvBwcWtgACgsdP75iEg1GFaInCFDZeX0aaC5WcYxaYS0v8qIXiPg7+3v/BNyYzgij8WwQuQMJyor8fFiT25jI/DTTzKPSwNk7VeRcEUQkUdiWCFyhhOVle6+IkgKK7L0q0hYWSHySAwrRM5worICdN++lbqmOhwrOQaAlRUi6hrDCpEznKisAN03rGQVZaHZ2IyYwBjEh8TL98Tca4XIIzGsEDmDlRWHSM21qXGpzm8GZ47TQEQeiWGFyFGCIFtl5cwZoKlJpnFpgEuaawFOAxF5KIYVIkdVVbUmDAcrK/HxQGCg+DRnz8o4NhUz3wzO6SsttyVVVq5cAerr5X1uIlIMwwqRo6SqSmAg4O/YPiE6HZCUJN7uLlNB56+dx5W6K/D28satMbfK++RhYa3/LVhdIfIYDCtEjnKyX0XS3fpWpCmg5N7J8DP4yfvkOh2ngog8EMMKkaOc7FeRSGElJ8fJ8WiE1Fwre7+KhE22RB6HYYXIUaysOCSz4Ea/iqvCCisrRB6HYYXIUTKHlTNnxK33PVlNYw1+uPwDABc010q41wqRx2FYIXKUTNNAsbFAcLB4MUNPXxF0uPAwjIIRccFxiA2Odc1JOA1E5HEYVogcJVNlpTutCHLZkmVznAYi8jgMK0SOkqmyAnSfvhWXbQZnjtNARB6HYYXIUTJVVoDuEVYEQcDBgoMAXBxWpGmg8nKgrs515yEit2FYIXIUKyt2OXv1LMqvl8NX74uRMSNdd6LQUKBHD/F2YaHrzkNEbsOwQuQIQXBJZeXsWaChwemnUyWpX2VU71Hw0fu47kQ6HZtsiTwMwwqRIyoqxOU7gCxhpXdvICQEaGkRlzB7IpdvBmeOfStEHoVhhcgRUlUlKAjwc37L+O6wIsjUXOvKlUASrggi8igMK0SOkLFfReLJfStVDVU4UXoCgJsqK5wGIvIoDCtEjpCxX0XiyWHl+4LvIUBAv9B+iAmKcf0JWVkh8igMK0SOYGXFLm7ZX8Uce1aIPArDCpEjXFhZ+eknoL5etqdVBbeHFU4DEXkUh8LK5s2bkZCQAD8/PyQnJ+Prr7+26XHffvstDAYDRowY4chpidTDBZWVmBhxixCjETh9WranVZxRMJo2g0uNS3XPSaXKyrVrQG2te85JRC5jd1jZvXs3Vq5ciaeeegrZ2dmYMGECZs6ciby8vE4fV1lZiYULF2LKlCkOD5ZINVxQWdHpPHMq6FTZKVTUV8Df4I9h0cPcc9LgYCAwULzNvhUizbM7rGzcuBFLlizB0qVLkZiYiE2bNiEuLg5btmzp9HEPPvgg7r33XqSkuKkMTORKLqisAJ4ZVqT9VUb3GQ1vvbd7TqrTsW+FyIPYFVYaGxtx5MgRTJ8+3eL+6dOnIzMzs8PHvf322zh37hyeffZZm87T0NCAqqoqiw8iVXFBZQXw0LDi7n4VCVcEEXkMu8JKWVkZWlpaEB0dbXF/dHQ0SkpKrD7m7NmzeOKJJ7Br1y4YDAabzrNhwwaEhISYPuKkHzpEaiFVVlwUVnJyZH1aRUlhxW39KhI22RJ5DIcabHU6ncXngiC0uw8AWlpacO+99+L555/HzTffbPPzr127FpWVlaaPfP6wITUxGoGyMvG2i6aBzp3zjBVB165fQ84VMXmNix3n3pOzskLkMWwrddwQEREBvV7fropSWlrartoCANXV1cjKykJ2djYefvhhAIDRaIQgCDAYDNi/fz9uv/32do/z9fWFr6+vPUMjcp+KCvEiPgAQESHrU0dHA2FhwNWrwKlTgNYXzn1f+D0A4KaeNyGqh7zBrkvsWSHyGHZVVnx8fJCcnIy0tDSL+9PS0pCa2r7EGxwcjB9//BHHjh0zfSxbtgyDBg3CsWPHMHbsWOdGT6QEaQooJASQOVR72oog08UL3XE9oLY4DUTkMeyqrADA6tWrsWDBAowaNQopKSl46623kJeXh2XLlgEQp3AKCwvxzjvvwMvLC0OHDrV4fFRUFPz8/NrdT6QZLmqulQwZAnz9tYeEFalfJdbN/SoAp4GIPIjdYWXevHkoLy/HCy+8gOLiYgwdOhT79u1D3759AQDFxcVd7rlCpGkuWrYs8ZTKSouxxbQZnCKVFSmsVFQANTWt+64QkeY41GC7fPlyXLx4EQ0NDThy5Ahuu+0209d27NiB9PT0Dh/73HPP4dixY46clkgd3FBZAbQfVnKu5KC6sRo9vHtgaJQCldSgIHFzOIBTQUQax2sDEdnLTZWV8+eBujqXnMItpCmgMX3GwOBldxFXHpwKIvIIDCtE9nJxZSUqSlxkJAjiiiCtUmx/FXNssiXyCAwrRPZycWUFAJKSxH+1PBWUmS/uau32nWvNsbJC5BEYVojs5eLKCqD9vpXyunKcKT8DQIHN4MxxrxUij8CwQmQvN1RWtB5WpFVAg8IHITwgXLmBcBqIyCMwrBDZi5WVLpkuXqjEkmVznAYi8ggMK0T2cOF1gcxJYeXCBaC21mWncRlV9KsAnAYi8hAMK0T2uHpVDCyA7NcFMhcZ2Vq4yc112WlcotnYjEOFhwCoIKxI00BVVeIHEWkSwwqRPaR+lZ49AW9vl55Kq1NBJ0pPoLapFsG+wUiKTFJ2MIGBQGioeJtTQUSaxbBCZA839KtItBpWpCmgsX3GQu+lV3g0YJMtkQdgWCGyh1RZYVjpkKm5VukpIAmbbIk0j2GFyB5SZcWFzbUSKazk5Lj8VLL6Ll8lK4EkbLIl0jyGFSJ7KDANdPGieNFgLSitLcW5a+cAKLwZnDlOAxFpHsMKkT3csCGcJDwciI4Wb2tlRZBUVUmKTEKoX6iyg5FwGohI8xhWiOzhxsoKoL2+FdX1qwCcBiLyAAwrRPZwY2UFYFiRhfk0kCAoOxYicgjDCpE9WFnpUFNLEw4XHgYApMalKjwaM1JlpaaGG8MRaRTDCpE9WFnp0PHLx3G9+TpC/UIxKGKQ0sNpFRAAhIWJtzkVRKRJDCtEtmppAcrLxdturqzk5QHV1W45pcOk5tpxsePgpVPZjxauCCLSNJX9RCFSsfLy1p4HF14XyFzPnkBMjHhb7futqLJfRcIVQUSaxrBCZCupXyUsDDAY3HbapBuX11H7VJAUVlTVryJhZYVI0xhWiGzl5n4ViRb6Voqri3Gx4iJ00GFMnzFKD6c9VlaINI1hhchWbl4JJNFCWJGqKkOjhiLYN1jh0VjBvVaINI1hhchWrKx0yHQ9IDX2qwCcBiLSOIYVIlspXFkpKAAqK916apupul8FsJwG4sZwRJrDsEJkK4UqK6GhQO/e4m01rghqbGlEVlEWABVdabktqbJSWwtUVCg6FCKyH8MKka0UqqwA6p4Kyi7ORkNLA8L9wzEwbKDSw7HO31+8MiTAqSAiDWJYIbKVVFlhWLEgTQGNix0HnU6n8Gg6wRVBRJrFsEJkK6my4uZpIEAbYUW1/SoSNtkSaRbDCpGtWFmxKjM/E4CKVwJJWFkh0iyGFSJbNDcDV6+KtxWorEi72BYVqas/tKCqAAVVBfDSeWF0n9FKD6dz3GuFSLMYVohsIV3AUKdrbdR0o5CQ1lkMNa0IkvZXGRY9DIE+gQqPpgucBiLSLIYVIltIU0Dh4YBer8gQ1DgVZOpXiVV5vwrAaSAiDWNYIbKFgsuWJWoMK6Z+FbXur2LOfBqIG8MRaQrDCpEtFNoQzpzawkp9cz2OFh8FoIHmWgDo00f89/r11v4jItIEhhUiW7Cy0s7R4qNoMjYhMiAS/Xv2V3o4XfPza/3vx6kgIk1hWCGyhQoqK9KKoOJi4No1xYZhIk0BpcalqnszOHNssiXSJIYVIluooLISFATEx4u31VBdkZprNTEFJGGTLZEmMawQ2UIFlRWgtbqidFgRBMG0bFkTzbUS7rVCpEkMK0S2UEFlBVBP30peZR6Ka4ph8DJgVO9Ryg7GHpwGItIkhhUiW6iksqKWsCL1q4zoNQIB3gHKDsYenAYi0iSGFSJbsLJiQZP9KgCngYg0imGFqCtNTa3Lb1TSs3L5cusVAJSg2bAiTQMVFHBjOCINYVgh6kpZmfivlxcQFqboUAIDgb59xdtKVVfqmupwrOQYAHHZsqZIG8PV1yub9ojILgwrRF0xvy6Ql/L/yyg9FZRVlIVmYzNiAmMQHxKvzCAc5esLREeLtzkVRKQZyv/kJVI7qV9F4SkgidJhxXzJsmY2gzPHFUFEmsOwQtQVqbKicHOtRPGwotV+FQlXBBFpDsMKUVdYWTERBMEUVjTXryJhZYVIcxhWiLqikmXLksRE8d8rV1qH5i7nr51HaW0pvL28cWvMre49uVxYWSHSHIYVoq6oZEM4SY8eQEKCeDsnx73nlqoqt8bcCj+Dn3tPLhfutUKkOQwrRF1RWWUFUG4qyNRcq9V+FYDTQEQaxLBC1BWVVVYABcOK1vtVAMtpIG4MR6QJDCtEXWFlBQBQ01iD45ePA9DYlZbb6t0b0OmAxkb3N/0QkUMYVoi6wsoKAOBw4WEYBSNig2MRGxzrvhPLzceHG8MRaQzDClFnGhuBykrxtooqK4MHi8WBsrLWLOVqmt9fxRxXBBFpCsMKUWekaQK9HujZU9mxmAkIAPr3F2+7q7riEf0qEjbZEmmKQ2Fl8+bNSEhIgJ+fH5KTk/H11193eOzevXsxbdo0REZGIjg4GCkpKfjnP//p8ICJ3EoKKxERqrgukDnpCszuCCuCIHjGSiAJKytEmmL3T9/du3dj5cqVeOqpp5CdnY0JEyZg5syZyMvLs3r8V199hWnTpmHfvn04cuQIJk+ejDlz5iA7O9vpwRO5nAr7VSTu7Fs5e/Usyq+Xw1fvi5ExI11/QlfjXitEmmJ3WNm4cSOWLFmCpUuXIjExEZs2bUJcXBy2bNli9fhNmzbhd7/7HUaPHo2BAwfixRdfxMCBA/HZZ585PXgil1PhSiCJO8OKVFVJ7p0MH72P60/oapwGItIUu8JKY2Mjjhw5gunTp1vcP336dGRmZtr0HEajEdXV1QgLC+vwmIaGBlRVVVl8EClCI5UVV28XYupXifWAfhWA00BEGmNXWCkrK0NLSwuipWV/N0RHR6OkpMSm53j55ZdRW1uLuXPndnjMhg0bEBISYvqIk36wELmbiisrgweLbTRXrwKXL7v2XJn54h8jmt5fxZx5WDEalR0LEXXJoY5BnU5n8bkgCO3us+a9997Dc889h927dyOqk79U165di8rKStNHPku1pBQVV1b8/d2zIqiqoQonSk8A8JDmWgCIiRHXfjc1uW/tNxE5zK6wEhERAb1e366KUlpa2q7a0tbu3buxZMkSfPDBB5g6dWqnx/r6+iI4ONjig0gRKq6sAO7pWzlUeAgCBPQN6YuYoBjXncidvL3FwAJwKohIA+wKKz4+PkhOTkZaWprF/WlpaUhN7Xgu+7333sPixYvx7rvvYvbs2Y6NlEgJ0l/d3TisSM21HrG/ijmuCCLSDIO9D1i9ejUWLFiAUaNGISUlBW+99Rby8vKwbNkyAOIUTmFhId555x0AYlBZuHAh/vKXv2DcuHGmqoy/vz9CQkJk/FaIXECqrKhwGghwT1jJLLjRr+IpU0CS2Fjg++9ZWSHSALvDyrx581BeXo4XXngBxcXFGDp0KPbt24e+ffsCAIqLiy32XHnzzTfR3NyMhx56CA899JDp/kWLFmHHjh3OfwdErqShyoogiG0YcjIKRhwsOAjAg5prJaysEGmG3WEFAJYvX47ly5db/VrbAJKenu7IKYiU19AAVFeLt1VaWRk0SFwRVFEBFBeLFxSW0+my06ior4C/wR/Do4fL++RK414rRJqhrv3DidREmgIyGIDQUEWH0hE/P2DAAPF2To78zy8tWR7dZzS89d7yn0BJ3GuFSDMYVog6Yj4FJPf8ioxc2bfiUVdabovTQESawbBC1BGVL1uWMKw4SJoGKiwEWlqUHQsRdYphhagjKt4QzpyrwkpFfQVyrohzSx7XXAuI+6x4eQHNzdwYjkjlGFaIOqLByoqc1wiSVgHd1PMmRPVQd2BziMHQ2pHMqSAiVWNYIeqIRiorN98M6PVAZSVQVCTf80qbwXlkVUUiTQWxyZZI1RhWiDqikcqKry8wcKB4W86pII/uV5GwyZZIExhWiDqikcoKACQlif/KFVZajC34vvB7AB4eVrjXCpEmMKwQdUQjlRVA/ibbnCs5qGqoQg/vHrgl+hZ5nlSNuNcKkSYwrBB1REOVFbnDijQFNKbPGBi8HNroWhs4DUSkCQwrRB3RYGUlJ0eeFUHdol8F4DQQkUYwrBBZc/06UFMj3tZAZeXmm8WVuFVV8sxoSCuBUuNSnX8yNZMqK0VF3BiOSMUYVoiskaoq3t5AcLCyY7GBj498K4LK68pxuvw0AGBc7DgnR6ZyvXqJ675bWoCSEqVHQ0QdYFghskYj1wUyJ1ffirQZ3M3hNyM8INzJUamcXs+N4Yg0gGGFyBqpsqKBKSCJXGGl2/SrSLgiiEj1GFaIrDGvrGiE3GHF4/tVJGyyJVI9hhUiazRcWXFmRVCzsRnfF3SDzeDMsbJCpHoMK0TWaGjZsmTgQLEfuKYGyMtz7DlOlJ5AbVMtgnyCkBSZJO8A1Yp7rRCpHsMKkTUa2hBO4u0tLmEGHJ8KkpYsj40dC72XXqaRqRyngYhUj2GFyBoNVlYAy6kgR5j6VWK7Sb8KwGkgIg1gWCGyRoOVFcD5JtvM/EwAQEpcN+lXASw3hmtuVnYsRGQVwwqRNRqvrDgSVkprS3Hu2jkAwNg+Y2UclcpFRYnb/xqNQHGx0qMhIisYVois0XhlJSdH/N1rD2kzuMSIRPT07ynzyFRMrwf69BFvcyqISJUYVojaqq0F6urE2xqrrAwYIG69X1tr/4qgbnM9IGu4IohI1RhWiNqSpoB8fYGgIGXHYieDARg0SLxt71RQZsGNfpXusr+KOWlFECsrRKrEsELUlnm/ikauC2Qu6cb2KPaElaaWJhwuPAygmzXXSlhZIVI1hhWitjTaryJxpMn2h8s/4HrzdYT6hWJwxGDXDEzNuNcKkaoxrBC1pdGVQBJHwoq0ZHlc7Dh46brhjwXutUKkat3wpxJRFzykspKba/uKoG53peW2OA1EpGoMK0RtabyyctNN4oqgujrg4kXbHtPtw4o0DVRcDDQ1KTsWImqHYYWoLamyotGwYjAAg2+0ndgyFVRcXYyLFRehgw5jY7vRZnDmoqLEiysJAjeGI1IhhhWitqTKikangQD7+lakqsrQqKEI9g124ahUzMuLTbZEKsawQtSWxisrgJ1hJb+bTwFJuNcKkWoxrBC11U0rK91yfxVzbLIlUi2GFSJzguBRlZXcXKClpePjGlsakVWUBYCVFU4DEakXwwqRudpaoL5evK3hykr//oCfn/itXLjQ8XHZxdloaGlAmH8Ybg6/2X0DVCPutUKkWgwrROakKSA/P6BHD2XH4gS93rYVQeZLlnUavLSArDgNRKRaDCtE5sw3hNP4L29pKignp+Njuv3+KuY4DUSkWgwrROY0viGcOVuabE0rgbp7cy3QWlm5fBlobFR2LERkgWGFyJzGt9o311VYKagqQH5VPrx0XhjTZ4z7BqZWkZHi1r+CABQVKT0aIjLDsEJkzgMrK6dOWV8RJFVVhkUPQ6BPoBtHplI6HaeCiFSKYYXInAdVVhISAH9/cUXQ+fPtv85+FSu4IohIlRhWiMx5UGXFywtITBRvW5sKYlixgiuCiFSJYYXInAdVVgAgKUn8t21YqW+ux5GiIwCA1LhUN49KxbjlPpEqMawQmfOgygrQcZPt0eKjaDI2ITIgEv179nf/wNSKlRUiVWJYITLnYZWVjsKK+ZLlbr8ZnDk22BKpEsMKkUQQPLaycuoU0Nzcer/Ur5IayykgC2ywJVIlhhUiSXU10NAg3vaQsNKvHxAQIO5xdu6ceJ8gCMjMzwTAzeDaMd8YTnovEJHiGFaIJFJVJSBA09cFMmdtRVBeZR6Ka4ph8DJgVO9Ryg1OjcLDxetCAUBhobJjISIThhUiidSv4iFVFUnbvhVpCmh49HAEeAcoNCqVMt8YjlNBRKrBsEIkkSorHtJcK2kXVm4013LJcge4IohIdRhWiCTdpLKSWXCjX4WbwVnHygqR6jCsEEk8vLJy+jRQVXcdx0qOAWBzbYdYWSFSHYYVIomHLVuWxMeL/cJNTcAnWVloNjajV2Av9A3pq/TQ1Il7rRCpDsMKkcTDNoSTeHm1bru/P6e1X4WbwXWAe60QqQ7DCpHEQysrQOtU0OHL7FfpEqeBiFSHYYVI4qGVFUAKKwIuNvNKy12SpoGuXAHq65UdCxEBcDCsbN68GQkJCfDz80NycjK+/vrrTo/PyMhAcnIy/Pz80L9/f7zxxhsODZbIpTy9stLzAhoMpfD28kZy72Slh6ReYWGAv794mxvDEamC3WFl9+7dWLlyJZ566ilkZ2djwoQJmDlzJvLy8qwef+HCBcyaNQsTJkxAdnY2nnzySTzyyCPYs2eP04Mnko0geH5lJU6cAhrZ61b4GfyUHZCa6XScCiJSGbvDysaNG7FkyRIsXboUiYmJ2LRpE+Li4rBlyxarx7/xxhuIj4/Hpk2bkJiYiKVLl+KBBx7ASy+91OE5GhoaUFVVZfFB5FJVVeJyGcAjKytxcYB3f3EKaFAPTgF1iXutEKmKXWGlsbERR44cwfTp0y3unz59OjIzM60+5rvvvmt3/IwZM5CVlYUm6ZdDGxs2bEBISIjpI076K4fIVaSqSmBg6xSAB9HpAO8EMayE1zGsdImVFSJVMdhzcFlZGVpaWhAdHW1xf3R0NEpKSqw+pqSkxOrxzc3NKCsrQ0xMTLvHrF27FqtXrzZ9XlVV5ZLA8stfAgkJwOjRsj81aU1wMPDCC0BLi9IjcZl5cb/FD1VfY86I8UoPRf3mzBGrKz/7mdIjIXK5e4fei3F9xiEpMknpoXTIrrAiabs/gyAIne7ZYO14a/dLfH194evr68jQ7DJvnvhBhOho4JlnlB6FS21fdR+A+5Qehjbcfbf4QdQNLLl1idJD6JJd00ARERHQ6/XtqiilpaXtqieSXr16WT3eYDAgPDzczuESERFRd2NXWPHx8UFycjLS0tIs7k9LS0NqqvUruKakpLQ7fv/+/Rg1ahS8vb3tHC4RERF1N3avBlq9ejW2bt2K7du3Izc3F6tWrUJeXh6WLVsGQOw3Wbhwoen4ZcuW4dKlS1i9ejVyc3Oxfft2bNu2DWvWrJHvuyAiIiKPZXfPyrx581BeXo4XXngBxcXFGDp0KPbt24e+fcWLohUXF1vsuZKQkIB9+/Zh1apVeP3119G7d2+88soruJvzwURERGQDnSB1u6pYVVUVQkJCUFlZieDgYKWHQ0RERDaQ6/c3rw1EREREqsawQkRERKrGsEJERESqxrBCREREqsawQkRERKrGsEJERESqxrBCREREqsawQkRERKrm0FWX3U3at66qqkrhkRAREZGtpN/bzu4/q4mwUl1dDQCIi4tTeCRERERkr+rqaoSEhDj8eE1st280GlFUVISgoCDodDrZnreqqgpxcXHIz8/nNv5uxNddGXzdlcHXXRl83ZXR9nUXBAHV1dXo3bs3vLwc7zzRRGXFy8sLsbGxLnv+4OBgvpkVwNddGXzdlcHXXRl83ZVh/ro7U1GRsMGWiIiIVI1hhYiIiFStW4cVX19fPPvss/D19VV6KN0KX3dl8HVXBl93ZfB1V4arXndNNNgSERFR99WtKytERESkfgwrREREpGoMK0RERKRqDCtERESkagwrREREpGoeG1Y2bNiA0aNHIygoCFFRUbjzzjtx+vTpLh+XkZGB5ORk+Pn5oX///njjjTfcMFrP4cjrnp6eDp1O1+7j1KlTbhq19m3ZsgXDhg0z7RqZkpKCf/zjH50+hu9159n7uvO97hobNmyATqfDypUrOz2O73l52fK6y/We99iwkpGRgYceeggHDx5EWloampubMX36dNTW1nb4mAsXLmDWrFmYMGECsrOz8eSTT+KRRx7Bnj173DhybXPkdZecPn0axcXFpo+BAwe6YcSeITY2Fn/4wx+QlZWFrKws3H777fjlL3+JkydPWj2e73V52Pu6S/hel8/hw4fx1ltvYdiwYZ0ex/e8vGx93SVOv+eFbqK0tFQAIGRkZHR4zO9+9zth8ODBFvc9+OCDwrhx41w9PI9ly+t+4MABAYBw7do19w2sG+jZs6ewdetWq1/je911Onvd+V6XV3V1tTBw4EAhLS1NmDhxovDoo492eCzf8/Kx53WX6z3vsZWVtiorKwEAYWFhHR7z3XffYfr06Rb3zZgxA1lZWWhqanLp+DyVLa+7ZOTIkYiJicGUKVNw4MABVw/NY7W0tOD9999HbW0tUlJSrB7D97r8bHndJXyvy+Ohhx7C7NmzMXXq1C6P5XtePva87hJn3/OauOqyswRBwOrVq/Gzn/0MQ4cO7fC4kpISREdHW9wXHR2N5uZmlJWVISYmxtVD9Si2vu4xMTF46623kJycjIaGBvz1r3/FlClTkJ6ejttuu82NI9a2H3/8ESkpKaivr0dgYCA++ugjJCUlWT2W73X52PO6870un/fffx9Hjx7F4cOHbTqe73l52Pu6y/We7xZh5eGHH8YPP/yAb775pstjdTqdxefCjasRtL2fumbr6z5o0CAMGjTI9HlKSgry8/Px0ksv8Qe4HQYNGoRjx46hoqICe/bswaJFi5CRkdHhL06+1+Vhz+vO97o88vPz8eijj2L//v3w8/Oz+XF8zzvHkdddrve8x08DrVixAp9++ikOHDiA2NjYTo/t1asXSkpKLO4rLS2FwWBAeHi4K4fpcex53a0ZN24czp4964KReS4fHx8MGDAAo0aNwoYNGzB8+HD85S9/sXos3+vysed1t4bvdfsdOXIEpaWlSE5OhsFggMFgQEZGBl555RUYDAa0tLS0ewzf885z5HW3xpH3vMdWVgRBwIoVK/DRRx8hPT0dCQkJXT4mJSUFn332mcV9+/fvx6hRo+Dt7e2qoXoUR153a7Kzs1mWdZIgCGhoaLD6Nb7XXaez190avtftN2XKFPz4448W991///0YPHgwHn/8cej1+naP4XveeY687tY49J53qj1XxX7zm98IISEhQnp6ulBcXGz6qKurMx3zxBNPCAsWLDB9fv78eSEgIEBYtWqVkJOTI2zbtk3w9vYWPvzwQyW+BU1y5HX/85//LHz00UfCmTNnhBMnTghPPPGEAEDYs2ePEt+CJq1du1b46quvhAsXLgg//PCD8OSTTwpeXl7C/v37BUHge91V7H3d+V53nbarUvied4+uXne53vMeW1nZsmULAGDSpEkW97/99ttYvHgxAKC4uBh5eXmmryUkJGDfvn1YtWoVXn/9dfTu3RuvvPIK7r77bncNW/Mced0bGxuxZs0aFBYWwt/fH0OGDMHnn3+OWbNmuWvYmnf58mUsWLAAxcXFCAkJwbBhw/DFF19g2rRpAPhedxV7X3e+192H73lluOo9rxOEGx1GRERERCrk8Q22REREpG0MK0RERKRqDCtERESkagwrREREpGoMK0RERKRqDCtERESkagwrREREpGoMK0RERKRqDCtERESkagwrREREpGoMK0RERKRq/x8jURGCTy/vrAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGxCAYAAACwbLZkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABlz0lEQVR4nO3dd3xUZfbH8c+kB0JCDwmEptJ7KAKLiAUERIVV2bUgGlQEUUDURRQRXbEgolIsgOiuhf0pIioWdCm6gnQLoKD0kFBCSQiQkGR+fzxOSEiAlJm5c2e+79drXrmZdk+CJifPOfc8DqfT6URERETEIkFWByAiIiKBTcmIiIiIWErJiIiIiFhKyYiIiIhYSsmIiIiIWErJiIiIiFhKyYiIiIhYSsmIiIiIWErJiIiIiFhKyYiIjS1atIgJEyaU6z0GDx5M/fr13fY8b3n33XeZOnVqkft37NiBw+Fg8uTJ5Xr/t99+mxo1apCRkVGu9ymtxx57jHbt2pGXl+fV84pYScmIiI0tWrSIJ554wuowLHG2ZMQdjh8/ziOPPMLDDz9MpUqVPHKOsxkzZgzbt2/nrbfe8up5RaykZERE5AxvvfUWaWlpDBkyxOvnjomJ4ZZbbuGZZ55BW4dJoFAyIuIlEyZMwOFwsH79egYMGEB0dHT+L54DBw4Uef68efPo3LkzFStWJCoqil69erF+/fr8xwcPHsz06dMBcDgc+bcdO3YAMH36dC655BJq1qxJxYoVadmyJc899xynTp1y29fkdDqZMWMGbdq0ITIykipVqnD99dezbdu2Qs+79NJLadGiBatXr6Zbt25UqFCBhg0b8swzzxQpR2zcuJGePXtSoUIFatSowfDhw/nss89wOBwsXbo0//0+++wzdu7cWehrP9OUKVNo0KABUVFRdO7cmZUrV5bo65o5cyb9+vWjcuXKhe7Py8vjlVdeyf96K1euzMUXX8zChQvzn1O/fn2uvvpqPv30U9q2bUtkZCRNmzbl008/BWDu3Lk0bdqUihUr0rFjR9asWVPk/LfeeitbtmxhyZIlJYpXxO6UjIh4Wf/+/bnwwgv54IMPmDBhAgsWLKBXr16FkoSnn36av//97zRr1oz//Oc//Otf/yIjI4Nu3bqxadMmwPQWXH/99QCsWLEi/xYXFwfAH3/8wU033cS//vUvPv30U5KSknj++ee5++673fa13H333YwcOZIrrriCBQsWMGPGDDZu3EiXLl3Yt29foeempqZy8803c8stt7Bw4UJ69+7N2LFj+fe//53/nJSUFLp3785vv/3GzJkzefvtt8nIyODee+8t9F4zZsyga9eu1KpVq9DXXtD06dNZvHgxU6dO5Z133iEzM5M+ffpw9OjRc35Ne/bs4eeff6ZHjx5FHhs8eDD3338/HTp0YN68ebz//vtcc801+Qmgy48//sjYsWN5+OGHmT9/PjExMQwYMIDHH3+cWbNm8fTTT/POO+9w9OhRrr76ak6cOFHo9YmJiURFRfHZZ5+dM1YRv+EUEa94/PHHnYBz1KhRhe5/5513nIDz3//+t9PpdDp37drlDAkJcY4YMaLQ8zIyMpy1atVy3njjjfn3DR8+3FmS/41zc3Odp06dcr799tvO4OBg56FDh/Ifu+2225z16tU773uc+bwVK1Y4AecLL7xQ6Hm7d+92RkZGOh966KH8+7p37+4EnD/88EOh5zZr1szZq1ev/M8ffPBBp8PhcG7cuLHQ83r16uUEnEuWLMm/r2/fvsXGvX37difgbNmypTMnJyf//lWrVjkB53vvvXfOr3PevHlOwLly5cpC9y9fvtwJOMeNG3fO19erV88ZGRnp3LNnT/59GzZscALOuLg4Z2ZmZv79CxYscALOhQsXFnmfrl27Ojt16nTOc4n4C62MiHjZzTffXOjzG2+8kZCQkPwl+S+//JKcnBwGDRpETk5O/i0iIoLu3bvnlyrOZ/369VxzzTVUq1aN4OBgQkNDGTRoELm5uWzZsqXcX8enn36Kw+HglltuKRRnrVq1aN26dZE4a9WqRceOHQvd16pVK3bu3Jn/+bJly2jRogXNmjUr9Ly///3vpY6vb9++BAcHFzoXUOh8xdm7dy8ANWvWLHT/559/DsDw4cPPe+42bdpQu3bt/M+bNm0KmPJShQoVitxfXEw1a9YkOTn5vOcS8QchVgcgEmhq1apV6POQkBCqVatGWloaQH55o0OHDsW+Pijo/H9D7Nq1i27dutG4cWNeeukl6tevT0REBKtWrWL48OFFygJlsW/fPpxOJ7GxscU+3rBhw0KfV6tWrchzwsPDC8WSlpZGgwYNijzvbOc4lzPPFx4eDnDer931eERERKH7Dxw4QHBwcJF/v+JUrVq10OdhYWHnvP/kyZNF3iMiIsIt/04idqBkRMTLUlNTC/3VnJOTQ1paWv4vz+rVqwPwwQcfUK9evTKdY8GCBWRmZjJ//vxC77Fhw4ayB36G6tWr43A4+Pbbb/N/0RdU3H3nU61atSK9JmC+Z97i+v4fOnQov/8GoEaNGuTm5pKamlrofk85dOhQfiwi/k5lGhEve+eddwp9/p///IecnBwuvfRSAHr16kVISAh//PEH7du3L/bmcra/9l1XlhRMCJxOJ2+88Ybbvo6rr74ap9NJcnJysTG2bNmy1O/ZvXt3fvnll/wmXZf333+/yHPPXFVxlyZNmgCmAbig3r17A+ZKG2/Ytm1bkXKViL/SyoiIl82fP5+QkBCuvPJKNm7cyGOPPUbr1q258cYbAXNp6MSJExk3bhzbtm3jqquuokqVKuzbt49Vq1ZRsWLF/EFnrl/4zz77LL179yY4OJhWrVpx5ZVXEhYWxt///nceeughTp48ycyZMzl8+LDbvo6uXbty1113cfvtt7NmzRouueQSKlasSEpKCt999x0tW7bknnvuKdV7jhw5kjlz5tC7d28mTpxIbGws7777Lr/++itQuETVsmVL5s+fz8yZM0lMTCQoKKhQolZWnTp1IjIykpUrV3LNNdfk39+tWzduvfVWnnrqKfbt28fVV19NeHg469evp0KFCowYMaLc53ZJS0tj69atbn1PEV+mlRERL5s/fz6//vorAwYMYPz48fTr14+vvvoqv38AYOzYsXzwwQds2bKF2267jV69evHQQw+xc+dOLrnkkvzn3XTTTQwZMoQZM2bQuXNnOnTowN69e2nSpAkffvghhw8fZsCAAYwYMYI2bdrw8ssvu/Vree2115g2bRrLly/nb3/7G3379mX8+PFkZmYWaVYtifj4eJYtW0ajRo0YOnQoN998M2FhYUycOBGg0NyP+++/n+uvv55HHnmEiy+++Kw9NqUVFhbG9ddfz8cff1zksblz5zJlyhS+//57rr/+em688UY+/vjjYvtcyuPjjz8mNDQ0P0EV8XcOp1Mj/kS8YcKECTzxxBMcOHBAvQCldNddd/Hee++RlpZWKGnzlDVr1tChQwdWrlxJp06dPH6+M3Xr1o26desWKemJ+CuVaUTEp0ycOJH4+HgaNmzIsWPH+PTTT5k1axaPPvqoVxIRgPbt23PjjTfy5JNP5k9O9Zbly5ezevVq7U0jAUXJiIj4lNDQUJ5//nn27NlDTk4OF110EVOmTOH+++/3ahwvvPACs2fPJiMjw6ub5aWlpfH2228XuTRaxJ+pTCMiIiKWUgOriIiIWErJiIiIiFhKyYiIiIhYyhYNrHl5eezdu5dKlSrlT5YUERER3+Z0OsnIyCA+Pv6c+2rZIhnZu3cvCQkJVochIiIiZbB7927q1Klz1sdtkYy4LqvbvXs30dHRFkcjIiIiJZGenk5CQsJ5L4+3RTLiKs1ER0crGREREbGZ87VYqIFVRERELKVkRERERCylZEREREQsZYueERERCVxOp5NTp06Rk5NjdShyhpCQEEJDQ8s9dkPJiIiI+KysrCx27NjBsWPHrA5FziIqKor69esTHh5e5vdQMiIiIj4pLy+PTZs2ERISQoMGDQgPD9fgSx/idDrJysoiOTmZjRs30rx58zInJEpGRETEJ508eZK8vDwaNGhAVFSU1eFIMSpWrEhYWBi//fYbixYt4oorrjjvTJHiqIFVRER82rnGiIv1XP8+e/bs4bPPPuPkyZOlfw93ByUiIiKBp0aNGuzZs4dDhw6V+rVKRkRERKTcQkJCyMnJ8c7KyPLly+nXrx/x8fE4HA4WLFhw3tcsW7aMxMREIiIiaNiwIa+++mqpAxURERH/VOpkJDMzk9atWzNt2rQSPX/79u306dOHbt26sX79eh555BHuu+8+Pvzww1IHKyIiYgeDBw/muuuuszoM2yj11TS9e/emd+/eJX7+q6++St26dZk6dSoATZs2Zc2aNUyePJm//vWvxb4mKyuLrKys/M/T09NLG2aJbN8Or70GZVhR8riQELjrLmjUyOpIpET27YOXXoLjx62OROwuKgruuw9q1rQ6EgDSjqcxdeVUMrIzvH7uqiFV6Vulr9fPK97n8Ut7V6xYQc+ePQvd16tXL2bPns2pU6cIDQ0t8ppJkybxxBNPeDo0nn4aZs3y+GnKbNEiWL8eyjFHRrxlwgRQ+VHcJSgIJk60OgoApq6cylPfPmXJuRtHN6bvJYWTEafTupy/QgVwx5iTZcuW8eCDD/Ljjz9StWpVbrvtNp566ilCQkL45JNPuPXWWzl06BBBQUFs2LCBtm3bMmbMGJ5//nkA7r77btLT03nvvffKH4yP8HgykpqaSmxsbKH7YmNjycnJ4eDBg8TFxRV5zdixYxk9enT+5+np6SQkJLg9tsxM8/GKK6BjR7e/fbnMmgWbN8M//+kzP5PkbHJzYf58c3zHHVCrlrXxiH2tXg2LF8Mff1gdSb7vdn8HQP8m/WlavalXz105uHKR+44fN4tHVjh2DCpWLN97JCcn06dPHwYPHszbb7/Nr7/+yp133klERAQTJkzgkksuISMjg/Xr15OYmMiyZcuoXr06y5Yty3+PpUuXMmrUqHJ+Nb7FK0PPzpyY53Q6i73fJTw8vFxjZUvr6qvh/vu9droSadsWbrgBJk2C66+HVq2sjkjO6n//g/37oXJlmDkTwsKsjkjs6v33TTKyZ4/VkQCQk5fDquRVADzZ40ma12zu1fMfP36czZs3e/WcnjZjxgwSEhKYNm0aDoeDJk2asHfvXh5++GHGjx9PTEwMbdq0YenSpSQmJuYnHk888QQZGRlkZmayZcsWLr30Uqu/FLfy+KW9tWrVIjU1tdB9+/fvJyQkhGrVqnn69Lb1179C//6QkwNJSeaj+ChXM/Y11ygRkfKpU8d89JFk5Jf9v3D81HGiw6NpWsO7qyJnU6GCWaGw4lahQvnj37x5M507dy70x3jXrl05duwYe/78d7/00ktZunQpTqeTb7/9lmuvvZYWLVrw3XffsWTJEmJjY2nSpEn5g/EhHl8Z6dy5M5988kmh+7766ivat29fbL+IGA4HTJ8O//0vrFkDU6fCmDFWRyVF5OWdLtGcpSFbpMRc5eg9e0xzhMX7sKzYvQKATrU7EeTwjbFUDkf5SyVWcjqd560WXHrppcyePZsff/yRoKAgmjVrRvfu3Vm2bBmHDx+me/fuXo/b00r9X9exY8fYsGEDGzZsAMyluxs2bGDXrl2A6fcYNGhQ/vOHDh3Kzp07GT16NJs3b2bOnDnMnj2bMfrNel5xcTBlijl+7DH4/Xdr45FirF5tfnFERcEZjdoipRYXZ37bZmfDgQNWR8PK5JUAXFznYosj8R/NmjXj+++/z09AAL7//nsqVapE7dq1AfL7RqZOnUr37t1xOBx0796dpUuXsnTpUiUjAGvWrKFt27a0bdsWgNGjR9O2bVvGjx8PQEpKSn5iAtCgQQMWLVrE0qVLadOmDU8++SQvv/zyWS/rlcJuvx0uv9xcfjxkiPlDXHyIq0TTty9ERFgbi9hfWBi4Gv59oFTjWhnpXKezxZHY09GjR/P/eHfd7rrrLnbv3s2IESP49ddf+fjjj3n88ccZPXp0/h4vrr6Rf//73/m9IZdccgnr1q3zy34RKEOZ5tJLLy2U0Z1p7ty5Re7r3r0769atK+2pBPNH0uuvQ8uWsGyZucrmrrusjkoAs4zuSkaUXIu71KkDqakmGWnXzrIw0o6nsfXQVgA61elkWRx2tnTp0vw/3F1uu+02Fi1axIMPPkjr1q2pWrUqSUlJPProo4We16NHD9atW5efeFSpUoVmzZqxd+9emjb1jf4dd/LK1TRSPg0bmkt8R42CBx+EPn1O97mJhX78EbZtMysipRgEKHJOCQmmUczilZEfkn8AoHG1xlSNrGppLHY0d+7cYv84d1m1atU5Xz958mQmT55c6D5Xe4Q/8o2OJDmvESOgUydIT4d77jF/lIvFXKsiV11l3eAD8T+uvzR277Y0DFeJRv0i4g1KRmwiOBhmz4bQUPj0U5g3z+qIRCUa8QgfubxXzaviTUpGbKR5c3CVFUeMgIMHrY0noG3ebG6hoWZqnoi7+EAykpuXyw97TJlGzaviDUpGbOYf/4AWLUwiMnKk1dEEMNeqyBVXmMmrIu7iA8nI5oObycjOoGJoRa9PXZXApGTEZsLCTLkmKAjeeQc++8zqiAKUSjTiKWcOPrOAq1+kY+2OhATpOgfxPCUjNtSxo7myBmDoUNPUKl60bRts2GAaea691upoxN/Ex5uPJ09CWpolIazco34R8S4lIzY1caK55HfPHlO6ES9yrYp07w7Vq1sbi/if8HCoWdMcW1SqWbFHw87Eu5SM2FSFCmYAGpiNYpcvtzaegKISjXiahX0jR04eYfNBs1Ouhp2JtygZsbEePcyIeDAfT5ywNp6AsGcP/PCDGY3bv7/V0Yi/cvWNWDBrxHUVzQVVLqBmxZpeP78EJiUjNvf882Zvra1b4YknrI4mALh26O3SxXzjRTzBwpUR9YvYw9KlS3E4HBw5cgQwE18r2/jKPiUjNle5sinTAEyeDNoCyMNUohFvsDAZUb+IewwePBiHw8HQoUOLPDZs2DAcDgeDBw922/kGDhzIli1b3PZ+3qZkxA9cey3ceCPk5kJSEpw6ZXVEfmrfPvj2W3M8YIC1sYh/sygZyXPm5e9Jo5WR8ktISOD999/nRIEa+smTJ3nvvfeoW7euW88VGRlJzZr2LaspGfETL78MVauaK07P2FtJ3GXBAjP3oX17qFfP6mjEn1nUM/Lbwd84cvIIkSGRtIpt5dVzl5jTCZmZ1txKOfelXbt21K1bl/mu8i4wf/58EhISCu3m63Q6ee6552jYsCGRkZG0bt2aDz74oNB7LVq0iEaNGhEZGUmPHj3YsWNHocfPLNMMHjyY6667rtBzRo4cmb8LMMCll17KiBEjGDlyJFWqVCE2NpbXX3+dzMxMbr/9dipVqsQFF1zA559/XqqvuyyUjPiJ2FiYOtUcP/EE/PqrpeH4J5VoxFsKrox4cfCZq1+kfXx7QoNDvXbeUjl+3GxMacXt+PFSh3v77bfz5ptv5n8+Z84c7rjjjkLPefTRR3nzzTeZOXMmGzduZNSoUdxyyy0sW7YMgN27dzNgwAD69OnDhg0bGDJkCP9w00yHt956i+rVq7Nq1SpGjBjBPffcww033ECXLl1Yt24dvXr14tZbb+V4Gb720lAy4kduucVsIJuVZa6uycuzOiI/cugQLFlijpWMiKfVrm0+njgBhw977bTqF3G/W2+9le+++44dO3awc+dO/ve//3HLLbfkP56ZmcmUKVOYM2cOvXr1omHDhgwePJhbbrmF1157DYCZM2fSsGFDXnzxRRo3bszNN9/stn6T1q1b8+ijj3LRRRcxduxYIiMjqV69OnfeeScXXXQR48ePJy0tjZ9++skt5zsbzfn1Iw4HvPqq2bvmf/8zja3Dh1sdlZ9YuBBycqBlS7joIqujEX8XEWEG6h08aFZHqlb1ymltcSVNhQpw7Jh15y6l6tWr07dvX9566y2cTid9+/aleoFhiZs2beLkyZNceeWVhV6XnZ2dX8rZvHkzF198MQ6HI//xzp3dkzC2anW6HBccHEy1atVo2bJl/n2xsbEA7N+/3y3nOxslI36mXj145hm4914zmfXqq9Xe4BYq0Yi3JSScTkZaeb5/Iz0rnV/2/wL4eDLicEDFilZHUSp33HEH9957LwDTp08v9Fjen0vYn332GbVdK2J/Cg8PB0xPSWkFBQUVed2pYq5uCA0tXI5zOByF7nMlQHkeXmpXmcYP3XMPdO1q/ngYOtSyvbb8R3o6fPWVOVYyIt7i6hvxUhPr6uTVOHFSL6YecZU0Q8edrrrqKrKzs8nOzqZXr16FHmvWrBnh4eHs2rWLCy+8sNAt4c9G5mbNmrFy5cpCrzvz8zPVqFGDlJSUQvdt2LCh/F+MhygZ8UNBQWZn3/Bw+OIL+Pe/rY7I5j77DLKzoVEjaK7t1MVLvHx5b36/SIL6RdwtODiYzZs3s3nzZoKDgws9VqlSJcaMGcOoUaN46623+OOPP1i/fj3Tp0/nrbfeAmDo0KH88ccfjB49mt9++413332XuXPnnvOcl112GWvWrOHtt99m69atPP744/zyyy+e+hLLTcmIn2rcGB5/3ByPHGlGZEgZFSzRFKjZiniUl5OR/H6R2j5corGx6OhooqOji33sySefZPz48UyaNImmTZvSq1cvPvnkExo0aABA3bp1+fDDD/nkk09o3bo1r776Kk8//fQ5z9erVy8ee+wxHnroITp06EBGRgaDBg1y+9flLg5nWYpRXpaenk5MTAxHjx496z9mWdx0E7z3nrkk9v773fa2PuPUKejY0cweufFGmDfP6ohs6PhxqFHDfFyzBhITrY5IAsW//gWDBsEVV8DixR49ldPppMbzNUg7kcYPQ36gY+2OHj1fSR0/fpzNmzfTtGlTKpSheVS8w/XvtH37dn7//XduvPFGGjZsCJT897dWRvxYaKgp1wQHw3/+Y2Z2SSl98YVJROrXh3btrI5GAokXe0Z+P/Q7aSfSCA8Op02tNh4/n8iZlIz4uXbt4MEHzfGwYfDnnkpSUq4SzYABKtGId3lx8JmrXyQxPpGw4DCPnkukOEpGAsD48ab3MiXldGIiJZCVBZ9+ao51FY14m+syz8xMOHrUo6dSv4hYTclIAIiMhFmzzPGsWfDNN9bGYxtff20u642Ph4v1Q1q8rEIFqFbNHHu4iVVX0ojVlIwEiG7dTJkG4K67zB9bch6uEk3//uZ6aRFv80LfSGZ2Jj/tM6O+fXrYmfg1/YQNIJMmmaGO27aZ0o2cw6lT8PHH5lglGrGKFy7vXbN3DXnOPOpE16FOdB2PnUfkXJSMBJDoaLN3DZjLmX/4wdJwfNuyZWZzvOrVzbKSiBW8kIy4SjRaFRErKRkJMH36mN198/IgKckMFpViuEo0110HIdrCSSzihWREzaviC5SMBKAXXzR/8G/caEo3cobcXPjoI3OsEo1Y6c+9STzVM+J0OtW8Kj5ByUgAql4dXnnFHP/znyYpkQK+/97Mz4+JgcsuszoaCWQeXhnZcWQH+zP3ExoUSrs4DfXztrlz51K5cuVSvWbw4MFcd911HonHSkpGAtTAgdCvn+nTTEoyiwHyJ1eJ5pprIEwDoMRCHk5GXKsibePaEhES4ZFzBKqzJQ1Lly7F4XBw5MgRBg4cyJYtW7wfnA9SMhKgHA6YMcM0tf7ww+mVkoDndML8+eZYJRqxmisZycgwM2/cTP0i1oqMjKRmzZpWh+ETlIwEsDp14PnnzfG4ceaS34C3Zo2pz1esCD17Wh2NBLqKFaFKFXPsgb4RO/aLOJ1OMrMzLbm5e1/Z4so0Tz31FDVr1qRSpUoMGTKEf/zjH7Rp06bIaydPnkxcXBzVqlVj+PDhnDp1yq2xeZsuEwhwQ4aYnYuXLjXD0BYvDvAtWFwlmj59zOhaEavVqQOHD5tSTfPmbnvbE6dOsCF1A2Cvy3qPnzpO1KQoS859bOwxKoZV9Nj7v/POO/zzn/9kxowZdO3alffff58XXniBBg0aFHrekiVLiIuLY8mSJfz+++8MHDiQNm3acOedd3osNk/TykiACwqCN96AiAgzJv7NN62OyEJO5+lkRCUa8RUe6htZm7KWnLwcakXVol5MPbe+txiffvopUVFRhW69e/c+6/NfeeUVkpKSuP3222nUqBHjx4+nZcuWRZ5XpUoVpk2bRpMmTbj66qvp27cv39h8nw+tjAgXXghPPmk20Rs9Gq66ymzHEnB+/hl+/x3Cw83KiIgv8FAykt8vUudiHDZaDq0QWoFjY49Zdu7S6NGjBzNnzix03w8//MAtt9xS7PN/++03hrn27fhTx44d+e9//1vovubNmxMcHJz/eVxcHD///HOpYvM1SkYEgJEjYd480zIxfLjp4bTRzyf3cK2K9OoFlSpZG4uIi4dmjeT3i9SxT78IgMPh8GipxJ0qVqzIhRdeWOi+PedJKs9MDIvrUwkNDS3ymry8vDJG6RtUphHADBmdPdt8XLDg9O/lgKISjfgiD6yMOJ1OVuzWGHhf07hxY1atWlXovjVr1lgUjXcpGZF8rVrB2LHmePhwszVLwPjtNzP9LSTEDGAR8RUeSEZ2p+8m5VgKwY5g2se3d9v7SvmMGDGC2bNn89Zbb7F161aeeuopfvrpJ1uV0cpKyYgUMm4cNG0K+/eb/pGA4VoVufzy05dSivgCDyQjrn6R1rVal7oPQjzn5ptvZuzYsYwZM4Z27dqxfft2Bg8eTESE/w+kU8+IFBIebso1XbvCW2/B3/9uWij8nko04qtcycjRo2b4mRv6mVwlGrv1i9jJ3Llzi73/0ksvze8DGTx4MIMHDy70+GOPPcZjjz2W//mVV15ZqO+kuPedOnVqecO1nFZGpIjOneG++8zxXXeZn39+bft2WLfOXOfsh3s+iM1VqmT2SQK3rY6sTD59JY34juPHjzNlyhQ2btzIr7/+yuOPP87XX3/NbbfdZnVoHqdkRIr11FNQvz7s2mVKN37NNf79kkugRg1rYxEpjhtLNVk5WaxLWQdoZcTXOBwOFi1aRLdu3UhMTOSTTz7hww8/5IorrrA6NI9TmUaKFRUFr79uJqJPm2Y21uva1eqoPEQlGvF1deqYBms3JCPrU9eTnZtN9QrVaViloRuCE3eJjIzk66+/tjoMS2hlRM7qyivh9tvNYNIhQ+DkSasj8oDkZFhh6uf0729tLCJn45o14oZkpGC/SCBcpSH2oGREzumFF6BWLfj1V1O68TsffWQ+du4MtWtbG4vI2bjKNG4YfGbHfhG7D/Tyd+7491EyIudUpQpMn26On30WNmywNBz3U4lG7MCNPSN2upImLCwMgGPHrBn/LiXj+vcpz87B6hmR8xowwPyu/vBDSEqCH34ws8Fs78ABWL7cHA8YYG0sIufipmQkOT2Z3em7CXIE0aF2BzcE5lkhISFUr16d5ORkAKKioggK0t/QviIvL49jx46RnJzMkSNHyM3NBYqOtC8Jf/iVIl4wbZrZ1XfdOpgyBR56yOqI3GDBAsjLg3bt4IwtukV8ipt6RlzDzlrWbElUWFR5o/KKunXrAuQnJOJ7jhw5wr59+zh+/DhhYWFERkaW+j2UjEiJ1KplkpA77oDHHzfjOBo1sjqqclKJRuzCtTJy+DBkZkLFsm0UV3CnXrtwOBzUq1ePqlWrsmTJEnbu3ElUVFShXWulfJbuWMq+zH10rtOZujF1S/w6p9NJdnY2ubm5nDp1imPHjtGmTRuqVatW6hiUjEiJDR4M774LX38Nd94JS5aYOWG2dPiwWeoBJSPi+6KjzfCzjAyzOtK4cZnexq479QJUqlSJyy+/nK+//pq9e/fmlwSk/FLSUtibvpe0qDQqOyqX6T3CwsJITEykR48eRXYVLgklI1JiDoeZPdKihWm1eOMNuPtuq6Mqo08+gZwcaN68zD/YRbyqTh3YvLnMyUh2bjZrU9YC9loZKahixYpce+21nDp1ipycHKvD8RsfvfcRG3dsZEyfMVzf7PoyvUdYWFi5VquUjEipNGgATz8NI0fCgw9C376nV5BtRSUasZuEhNPJSBn8tO8nTuacpEpEFRpVs3eNNTQ0tEx/fctZhEBucC6h4aFl6vdwB7susouF7r0XLr7YrBgPHWqGotlKRgZ8+aU5VjIidlHOWSOuS3ovrnOxhp2JzylTMjJjxgwaNGhAREQEiYmJfPvtt+d8/jvvvEPr1q2pUKECcXFx3H777aSlpZUpYLFecLDZ2TcsDD77DN5/3+qISmnRIsjKggsvhJYtrY5GpGTKeXmvHYedSeAodTIyb948Ro4cybhx41i/fj3dunWjd+/e7Nq1q9jnf/fddwwaNIikpCQ2btzI//3f/7F69WqGDBlS7uDFOs2awaOPmuP77jMjO2yjYIlGfyGKXZQzGbHTsDMJPKVORqZMmUJSUhJDhgyhadOmTJ06lYSEBGbOnFns81euXEn9+vW57777aNCgAX/5y1+4++67WbNmTbmDF2s9/LBZWDh40PSQ2MKJE2ZlBFSiEXspRzKy79g+th/ZjgMHHWt3dHNgIuVXqmQkOzubtWvX0rNnz0L39+zZk++//77Y13Tp0oU9e/awaNEinE4n+/bt44MPPqBv375nPU9WVhbp6emFbuJ7wsJMuSYoyFzy++mnVkdUAl9+aeY01K0L7dtbHY1IybkGn5WhZ8Q1X6RZjWbERMS4MyoRtyhVMnLw4EFyc3OJjY0tdH9sbCypqanFvqZLly688847DBw4kLCwMGrVqkXlypV55ZVXznqeSZMmERMTk39LcP1PKD6nQwcYPdocDx0KPp83uko0AwaoRCP24loZOXQIjh8v1UvtOOxMAkuZGljP7MR2Op1n7c7etGkT9913H+PHj2ft2rV88cUXbN++naFDh571/ceOHcvRo0fzb7vdsFOleM4TT8AFF0Bysind+KzsbDNfBFSiEfuJiTk9ebWUo9HtPOxMAkOpkpHq1asTHBxcZBVk//79RVZLXCZNmkTXrl158MEHadWqFb169WLGjBnMmTOHlJSUYl8THh5OdHR0oZv4rgoVzAA0gFdfhWXLrI3nrL75Bo4eNbPtu3SxOhqR0nE4ytQ3kpOXw+q9qwGtjIjvKlUy4hr3unjx4kL3L168mC5n+eF+/PjxIrssuqa0OW03oELOpkcPuOsuczxkiOkT9TmuEk3//jaeYy8BrQx9Iz/v+5njp44THR5N0xpNPRSYSPmU+ify6NGjmTVrFnPmzGHz5s2MGjWKXbt25Zddxo4dy6BBg/Kf369fP+bPn8/MmTPZtm0b//vf/7jvvvvo2LEj8fHx7vtKxHLPPQfx8fD77zBhgtXRnCEnx+zSCyrRiH2VYWXE1S/SqXYnghxKwsU3lXoc/MCBA0lLS2PixImkpKTQokULFi1aRL169QBISUkpNHNk8ODBZGRkMG3aNB544AEqV67MZZddxrPPPuu+r0J8QkyMKdNccw1Mngw33OBDF6wsXw5paVCtGnTvbnU0ImVThmRE/SJiB2Xam2bYsGEMGzas2Mfmzp1b5L4RI0YwYsSIspxKbKZfP/jb38xU1qQkWLMGfGILCVeJ5tprIURbMolNlWNlRP0i4su0Zidu99JLZgHip59M6cZyeXnw0UfmWCUasbNS9owcPH6QrYe2AtCpTidPRSVSbkpGxO1q1jQJCcDEiWajUUutWAEpKRAdDZdfbnEwIuVQypWRH/b8AEDjao2pGlnVU1GJlJuSEfGIm26CPn3MaI+kJMjNtTAYV4mmXz8ID7cwEJFyciUjBw/CyZPnfXp+v0iC+kXEtykZEY9wOEwza1SUWZiYMcOiQJxOmD/fHKtEI3ZXpQpERprjEgw+y+8Xqa1+EfFtSkbEYxISwHXR1NixsGOHBUGsXQs7d5rJbL16WRCAiBs5HKf7Rs5TqsnNy+WHZFOm0cqI+DolI+JRQ4fCX/5i9qa7+26zUOFVrhJNnz4mIRGxO1ep5jxNrJsObOJY9jGiwqJoXqO5FwITKTslI+JRQUEwa5Zp1fjqK3j7bS+e3Ok8nYyoRCP+ooRNrK5+kY61OxIcFOzpqETKRcmIeFzjxqcnso4aBfv2eenEGzfC1q0mE+rb10snFfGwEiYj6hcRO1EyIl7xwAPQti0cPgxem3/nWhXp2RMqVfLSSUU8rIQ9I7qSRuxEyYh4RWgozJ4NwcHwf/93egaZR6lEI/6oBD0jh08c5teDvwJmTxoRX6dkRLymbVt46CFzPGyYWSXxmK1b4eefzej3a67x4IlEvKwEZRrXVTQXVr2QGhVreCMqkXJRMiJeNX48NGoEqanw4IMePJFrVeSyy8xsBhF/4UpG9u+HrKxin6L9aMRulIyIV0VEmHINmI/ffOOhE6lEI/6qWjXzPxLA3r3FPsWVjGinXrELJSPidX/5Cwwfbo7vvNPMIHGrnTvNdsEOh9mlV8SfOBzn7BvJc+ZpZURsR8mIWGLSJHNRwPbt8Nhjbn5z1/j3bt0gNtbNby7iA87RN/Lbwd84mnWUyJBIWsW28nJgImWjZEQsUakSvPaaOZ46FVaudOObq0Qj/u4cyYjrkt4OtTsQEhTizahEykzJiFimd2+49VYzKDUp6ay9eKWTkgLff2+OBwxwwxuK+KBzzBrRsDOxIyUjYqkXX4QaNWDTJlO6KbePPjLZTadOp/96FPE35+gZ0bAzsSMlI2KpatVg2jRz/PTTZjRIuahEI4HgLGWa9Kx0Nu7fCKh5VexFyYhY7oYbzEUvp06Zck1ubhnf6OBBWLbMHCsZEX92lmRkVfIqnDipX7k+taJqWRCYSNkoGRHLORwwYwbExMDq1fDSS2V8o48/NplMmzbQsKE7QxTxLa5kZN8+yM7Ov1uX9IpdKRkRnxAfD5Mnm+NHH4U//ijDm6hEI4GiRg0ICzP9UQUGn+X3i2jYmdiMkhHxGUlJ0KMHnDhhhqE5naV48ZEj8PXX5ljJiPi7goPP/izVOJ1OrYyIbSkZEZ/hcMAbb0BkJCxZcnpsfIl8+qlpOmna1NxE/N0ZycjWQ1s5dOIQ4cHhtKnVxrq4RMpAyYj4lAsugKeeMscPPADJySV8oUo0EmjOSEZcqyKJ8YmEBYdZFZVImSgZEZ9z//3QoQOkp8OwYSUo1xw7Bl98YY6VjEigcA0++3PWyIrd6hcR+1IyIj4nONiUaEJCYOFC+L//O88LPv8cTp40V9C0bu2VGEUsd+bKSLL6RcS+lIyIT2rZEh55xByPGAFpaed4csESjcPh8dhEfEKBZORY9jF+2vcToJURsSclI+KzHnkEmjWD/fth9OizPOnkSfjsM3OsEo0EkgLJyJq9a8hz5lEnug61o2tbG5dIGSgZEZ8VHm7KNQ4HvP326baQQr76yvSM1KljGk1EAoWrZyQlhRU7vwO0KiL2pWREfNrFF5uGVoC774aMjDOe4CrRDBgAQfrPWQJIjRoQGgpOJyv/WA6oX0TsSz+9xec99RTUrw+7dp3uIwHMGOyFC82xSjQSaIKCoHZtnMCK1NWAVkbEvpSMiM+rWNEMQwOYPh2+++7PB5YsMZNXa9aErl2tCk/EOnXqsL0KHDh1hNCgUNrGtbU6IpEyUTIitnDFFXDHHWbmyJAhpm81v0TTv7+5Hlgk0CQksOLPPtZ2ce2ICImwNh6RMlIyIrYxeTLUqgW//QZPPZELCxaYB1SikUBVpw4r/0xG1C8idqZkRGyjShWYMcMcr3juWzhwwNx56aWWxiVimTp1WPHnRTXqFxE7UzIittK/P1x/PVyXZ0o0ef2uNVcUiASg4/E1+DHWHGtlROxMyYjYzisv5fFXx3wA5jtUopHAtbZSBjnBEJcZRN2YulaHI1JmSkbEdmrt/IF4517SqcQd713Jli1WRyRijZVOs0nexbvycOTmWhyNSNkpGRH7+fMqmrW1riYjO5whQyAvz+KYRCyw8uhGADrvBlJTrQ1GpByUjIi9OJ35yUjz8X+lYkX49lt47TWL4xLxMqfTyYo9f+7Uu4f83XtF7EjJiNjL+vWwYwdERlJz0FVMmmTufughM6FVJFDsTt9NyrEUQvIcJKagZERsTcmI2Itr0Fnv3lCxIsOGQZcuZq+8oUPNwolIIFixewUArbMqU+EUsHu3tQGJlIOSEbGPAiUa16Cz4GCYNQvCwuDzz+Hddy2MT8SLVrpKNMH1zB1aGREbUzIi9rFpkxm/GhYGV1+df3fTpjB+vDm+/37Yv9+i+ES8aMUeszLSOaaFuUPJiNiYkhGxD9eqyJVXQnR0oYceeghatYK0NJOQiPizrJws1qeuB+DiOp3MnUpGxMaUjIh9nFGiKSg0FGbPNruqv/8+LFzo5dhEvGhdyjqyc7OpUaEGDRu2N3eqZ0RsTMmI2MPvv8NPP5kmkWuuKfYp7dvDAw+Y43vugaNHvRifiBfl94vUuRhHwp+b0+zdCxp8JjalZETsYb4Z/06PHlCt2lmfNmECXHih+bn88MPeCU3E2/L7Rep0NltZBwebRGTfPosjEykbJSNiD+co0RRUoQK88YY5fu01WLrUs2GJWKHgygjBwRAXZx5Q34jYlJIR8X27d8OqVeBwwHXXnffpl14Kd99tju+8E44f92h0Il6VnJ7M7vTdBDmC6FC7g7nTVapR34jYlJIR8X2uEs1f/mKWpEvg2Wehdm3TajJhgudCE/E216pIy5otiQqLMnfWqWM+amVEbErJiPi+EpZoCoqJgZkzzfELL8CaNR6IS8QChfpFXJSMiM0pGRHflpoK331njgcMKNVL+/WDv//d7Oh7xx2Qne2B+ES8rFC/iIuSEbE5JSPi2xYsMGPgO3Y8XRcvhZdeMhff/PwzPPec+8MT8abs3GzW7DXLfJ0TCqyMuP7fUDIiNqVkRHxbGUo0BdWoAS+/bI6ffNJMlBexqx9TfyQrN4uqkVW5qOpFpx9wrYyogVVsqkzJyIwZM2jQoAEREREkJiby7bffnvP5WVlZjBs3jnr16hEeHs4FF1zAnDlzyhSwBJC0NFiyxByXMRkBU6rp29eUaYYM0VwosS9Xv8jFdS7G4XCcfsCVjCQnm7qkiM2UOhmZN28eI0eOZNy4caxfv55u3brRu3dvdu3addbX3HjjjXzzzTfMnj2b3377jffee48mTZqUK3AJAAsXmsyhdWu44IIyv43DYZpZK1WCFStg+nQ3xijiRfn9IrUvLvxAXJzZCyEnRztFii2VOhmZMmUKSUlJDBkyhKZNmzJ16lQSEhKY6bp04QxffPEFy5YtY9GiRVxxxRXUr1+fjh070qVLl3IHL37OVaIpZeNqcRISTveMjB0LO3aU+y1FvC7/SpqC/SIAISEafCa2VqpkJDs7m7Vr19KzZ89C9/fs2ZPvv/++2NcsXLiQ9u3b89xzz1G7dm0aNWrEmDFjOHHixFnPk5WVRXp6eqGbBJj0dFi82ByXo0RT0F13wSWXmCFod91l+mJF7CL1WCo7juzAgYOOtTsWfYL6RsTGSpWMHDx4kNzcXGJjYwvdHxsbS2pqarGv2bZtG9999x2//PILH330EVOnTuWDDz5g+PDhZz3PpEmTiImJyb8llOEqCrG5Tz81TR6NG0OzZm55y6AgMyo+IsLkOW+95Za3FfEKV4mmec3mRIdHF32CLu8VGytTA2uhxinA6XQWuc8lLy8Ph8PBO++8Q8eOHenTpw9Tpkxh7ty5Z10dGTt2LEePHs2/7VamH3gKXkVzlv+2yqJRI3jiCXM8apQZYyJiB2ftF3FRMiI2VqpkpHr16gQHBxdZBdm/f3+R1RKXuLg4ateuTUxMTP59TZs2xel0sucs/9OEh4cTHR1d6CYBJDMTPv/cHLupRFPQ6NHQrh0cOQL33uv2txfxiLP2i7ho1ojYWKmSkbCwMBITE1nsquX/afHixWdtSO3atSt79+7l2LFj+fdt2bKFoKAg6rgyeZGCvvgCTpyA+vWhbVu3v31ICMyZYz5++OHpRRgRX5WTl8Pq5NXAGZNXC1LPiNhYqcs0o0ePZtasWcyZM4fNmzczatQodu3axdChQwFTYhk0aFD+82+66SaqVavG7bffzqZNm1i+fDkPPvggd9xxB5GRke77SsR/eKhEU1Dr1vDww+Z4+HA4fNgjpxFxi5/2/cSJnBPEhMfQpPpZxiKoTCM2VupkZODAgUydOpWJEyfSpk0bli9fzqJFi6hXrx4AKSkphWaOREVFsXjxYo4cOUL79u25+eab6devHy+7xmKKFJSVZZpXwSMlmoIefRSaNIF9++CBBzx6KpFycfWLdKrTiSDHWX5sa/CZ2FhIWV40bNgwhg0bVuxjc+fOLXJfkyZNipR2RIq1eDFkZEB8PHTq5NFTRUTArFnQrRu8+aaZ1HrllR49pUiZuJKRQjv1nik+3qwkZmfDwYNQs6aXohMpP+1NI76l4KCzIM//59m1qynTgJk9UqC1ScRnFBwDf1ahoVCrljlW34jYjJIR8R2nTsHHH5tjD5doCnr6aahb10xlffRRr51WpEQOHj/I74d+B6BT7fOsFqpvRGxKyYj4jqVLTSdpjRqmduIllSrBa6+Z45dfhpUrvXZqkfNylWiaVG9Clcgq536ykhGxKSUj4jtcJZrrroPgYK+e+qqrYNAgMyI+Kcn00Yr4gvxhZ+cq0bho1ojYlJIR8Q25ufDRR+bYiyWagqZMMT1/mzaZ0o2IL8gfdnau5lUXzRoRm1IyIr7hf/8zW59Xrgw9elgSQrVqMG2aOX76afjpJ0vCEMmXm5fLquRVQAlXRlSmEZtSMiK+wVWiueYaCAuzLIzrrzdVopwcU67JybEsFBE2HtjIsexjRIVF0bxG8/O/QMmI2JSSEbFeXh7Mn2+OLSrRuDgcMH06xMTAmjXw0kuWhiMBztUv0rF2R4KDStBHVTAZcTo9GJmIeykZEeutXm1+eEZFQc+eVkdDfDy88II5fuwx+P13a+ORwFWqfhGA2rXNx6wsM/hMxCaUjIj1XCWavn3NWFQfcMcdcNllZr++O+/UH5lijVJdSQOmxOnaQV2lGrERJSNiLaez8MZ4PsLhgDfegMhIM/5k1iyrI5JAc+jEIX49+CtQimQE1DcitqRkRKz144+wbZtZEend2+poCmnYEP75T3M8ZozZf0zEW1xX0VxY9UKqV6he8hcqGREbUjIi1nKtilx1lekZ8TH33QcdO0J6Otxzj8o14j0rdpeyX8RFg8/EhpSMiLV8sERTUHAwzJ5t9iD75BP4z3+sjkgCxcrkUvaLuGjwmdiQkhGxzubN5hYaCldfbXU0Z9WiBYwbZ45HjNBFCuJ5ec48ftjzA1CGlRGVacSGlIyIdVyrIldcYSav+rCxY01ScuAAjBpldTTi7349+CtHs45SIbQCLWNblu7FSkbEhpSMiHV8vERTUFiYKdcEBcG//w2LFlkdkfgzV79Ih/gOhASFlO7FBXtG1OQkNqFkRKyxbRts2GCaMq691upoSqRjRxg50hwPHWqaWkU8odTzRQqKjzcfT5yAQ4fcGJWI5ygZEWu4VkW6d4fqpbhs0WITJ5pLfnfvNqUbEU8o9eTVgiIioEYNc6xSjdiEkhGxho1KNAVVrGiGoQHMmAHffmttPOJ/jp48yqYDm4AyroyA+kbEdpSMiPft2QM//GDGnPbvb3U0pXbZZTBkiDlOSjKr4SLusip5FU6cNKjcgNio2LK9iWaNiM0oGRHv++gj87FLF4iLszaWMnr+eRP61q2mdCPiLuXqF3HRrBGxGSUj4n02LdEUVLmyKdOASUzWr7c0HPEj5eoXcVGZRmxGyYh41/79pxstBgywNpZyuu46uOEGyM01u/yeOmV1RGJ3TqfTvSsjSkbEJpSMiHctWAB5edC+PdSrZ3U05fbKK1ClirlK+YUXrI5G7G7roa0cPnmYiJAIWtdqXfY3Us+I2IySEfEuPyjRFBQbC1OnmuMJE+C336yMRuzONewsMS6RsOCwsr9RwZ4RDT4TG1AyIt5z+DD897/m2E+SEYBbb4VevSAry1xlk5dndURiV64STbn6RQBq1zYfjx+HI0fK914iXqBkRLxn4ULIyYGWLeGii6yOxm0cDnjtNTOD5Lvv4NVXrY5I7MrVvFqufhGAyEioVs0cq1QjNqBkRLzHz0o0BdWrB888Y44ffhh27bI2HrGfY9nH+Hn/zwB0Tijnygiob0RsRcmIeEdGBnz1lTn2w2QEYNgw6NoVjh0ze9eoVC+lsTp5NXnOPBKiE4ivFF/+N9SsEbERJSPiHZ99ZpoqGjWC5s2tjsYjgoJg1iyzw+/nn8M771gdkdiJWy7pLUiX94qNKBkR7yhYonE4rI3Fg5o0gccfN8f332/GqoiUhFuGnRWkZERsRMmIeN7x47BokTn20xJNQQ8+CK1bm93b77vP6mjEDtw27KwgJSNiI0pGxPO+/NIkJPXrQ7t2VkfjcaGhMGcOBAfDvHnw8cdWRyS+btvhbRw4foCw4DDaxbnp/xFXA6t6RsQGlIyI57lKNAMG+HWJpqB27WDMGHM8bJhGPci5uVZF2tZqS3hIuHveVIPPxEaUjIhnZWXBJ5+Y4wAo0RT0+ONmnMrevfDQQ1ZHI77M7f0icHrwWWYmpKe7731FPEDJiHjWN9+YH4RxcXCxm2rhNhEZaa6uAXjjjdPDZ0XO5PZ+ETBT+KpUMcfqGxEfp2REPMtVounf31z7GmAuuQTuuccc33mnaZ0RKej4qeP8uO9HwE3DzgpS34jYROD9dhDvyck53b0ZYCWagp55xpTvt22D8eOtjkZ8zdq9a8nJyyEuKo6E6AT3vrmuqBGbUDIinrNsGaSlmT0yLrnE6mgsEx19er+aF1+EVausjUd8S36/SEJnHO5u8FYyIjahZEQ8x1Wiue46CAmxNBSr9e0LN99sdvRNSoLsbKsjEl+R3y9S2wM9VUpGxCaUjIhn5OXBRx+Z4wAu0RQ0dSpUrw6//HJ6Uz0JbE6ns9DKiNtpszyxCSUj4hnffw+pqRATA5dfbnU0PqF6dXj5ZXP81FOwcaO18Yj1dh3dReqxVEKCQkiMS3T/CbRZntiEkhHxDFeJpl8/s3OcAPC3v8HVV8OpUzBkCOTmWh2RWMm1KtKmVhsiQyPdfwKVacQmlIyI+zmdMH++OVaJphCHA2bOhEqVYOVKmDbN6ojESh7tF4HTyUh6ugafiU9TMiLut2YN7Nplhi716mV1ND6nTh14/nlz/MgjsH27tfGIdTzaLwIQFQWVK5vj5GTPnEPEDZSMiPu5SjR9+pgxpFLEnXdC9+5mCNpdd2nrkEB0Muck61PWA26evHom9Y2IDSgZEfdyOk8nIyrRnFVQkBkRHxEBX38Nc+daHZF427qUdZzKO0XNijVpULmB506kvhGxASUj4l4//wy//w7h4WZlRM7qootg4kRzPHo0pKRYG494V8H9aNw+7KwgJSNiA0pGxL1cqyK9epkuTTmnUaMgMRGOHIF777U6GvEmj+zUWxzNGhEbUDIi7qUSTamEhMDs2ebj/Pmnv33i/zyyU29x1DMiNqBkRNznt9/MJK+QEDNfREqkdWv4xz/M8fDhcOiQtfGI5+1J38Oe9D0EOYLoEN/BsydTmUZsQMmIuI/rz/rLL4cqVayNxWYefRSaNIF9++CBB6yORjzNtSrSKrYVFcMqevZkSkbEBpSMiPuoRFNm4eGmXONwmCtrvvrK6ojEk1zJiMf7ReB0z8iRI3DsmOfPJ1IGSkbEPbZvh3XrzDWr111ndTS21KULjBhhju+6S783/JmredXj/SJgGsmjo82xVkfERykZEfdwjX+/5BKoUcPaWGzsn/+EevVg504YN87qaMQTsnOzWbt3LeCllRFQqUZ8XpmSkRkzZtCgQQMiIiJITEzk22+/LdHr/ve//xESEkKbNm3KclrxZSrRuEVUFLz+ujl+5RWz+bH4lw2pG8jKzaJqZFUurHqhd06qZER8XKmTkXnz5jFy5EjGjRvH+vXr6datG71792bXrl3nfN3Ro0cZNGgQl2s7ef+TnAwrzLIz/ftbG4sf6NkTBg82w2yTkuDkSasjEnfy2rCzgjRrRHxcqZORKVOmkJSUxJAhQ2jatClTp04lISGBmTNnnvN1d999NzfddBOdO3tpWVK856OPzMfOnaF2bWtj8RMvvACxsfDrr6Z0I/7Da8POCtKsEfFxpUpGsrOzWbt2LT179ix0f8+ePfn+HOvJb775Jn/88QePP/54ic6TlZVFenp6oZv4MJVo3K5qVZg+3Rw/8wz8+KO18Yj7eG3YWUEq04iPK1UycvDgQXJzc4mNjS10f2xsLKmpqcW+ZuvWrfzjH//gnXfeISQkpETnmTRpEjExMfm3BNcSo/ieAwdg+XJzPGCAtbH4mb/+1XxLc3JMuSYnx+qIpLxSj6Wy48gOHDjoWLuj906sZER8XJkaWM+sczqdzmJrn7m5udx000088cQTNGrUqMTvP3bsWI4ePZp/262lRd/18ceQlwft2kEDD+48GqCmTYPKlWHtWnjxRaujkfJyrYo0r9mc6PBo751YyYj4uFIlI9WrVyc4OLjIKsj+/fuLrJYAZGRksGbNGu69915CQkIICQlh4sSJ/Pjjj4SEhPDf//632POEh4cTHR1d6CY+SiUaj4qLM/0jAOPHw9at1sYj5bNitwX9InC6gfXQITh+3LvnFimBUiUjYWFhJCYmsnjx4kL3L168mC5duhR5fnR0ND///DMbNmzIvw0dOpTGjRuzYcMGOnXqVL7oxVpHjsA335hjJSMec/vtZsL+yZNw551mIUrsaWWyBf0iYIaeRUWZY62OiA8qWRNHAaNHj+bWW2+lffv2dO7cmddff51du3YxdOhQwJRYkpOTefvttwkKCqJFixaFXl+zZk0iIiKK3C829MkncOoUNG8OjRtbHY3fcjjM7JGWLWHZMpg1y0xoFXs5lXuK1cmrAQtWRhwOU6r59VeTjJSibC7iDaXuGRk4cCBTp05l4sSJtGnThuXLl7No0SLq1asHQEpKynlnjoifUInGaxo2PH2J74MP6o9bO/p5/8+cyDlB5YjKNK5uQfKuvhHxYWVqYB02bBg7duwgKyuLtWvXcskll+Q/NnfuXJYuXXrW106YMIENGzaU5bTiS44dgy+/NMdKRrxixAjo1AnS0+Gee8xQNLEPV79Ip9qdCHJYsBOHBp+JD9PeNFI2ixaZJoYLLzT1A/G44GCzs29oKHz6KcybZ3VEUhqW9Yu4aPCZ+DAlI1I2BUs03hppLTRvDo8+ao5HjICDB62NR0rOsitpXFSmER+mZERK78QJ+Owzc6wSjdf94x/QooVJREaOtDoaKYkDmQf44/AfAN4ddlaQkhHxYUpGpPS++goyM6FuXWjf3upoAk5YmCnXBAXBO++czgvFd7mGnTWt3pQqkVWsCUI9I+LDlIxI6blKNAMGqERjkY4dYdQoczx0qGlqFd9lyX40Z3KtjBw8aFY3RXyIkhEpnexsWLjQHKtEY6mJE80lv3v2mNKN+C5Lduo9U+XKUKGCOU5Oti4OkWIoGZHS+e9/4ehRqFULipm6K95ToYIZgAYwc+bp/QrFt+Tm5bIqeRVg8cqIa/AZqFQjPkfJiJSOq0TTv79pWhBL9ehhRsQDDBmi1Xdf9Mv+X8g8lUmlsEo0q9HM2mDUNyI+Sr9NpORycmDBAnOsEo3PeO45iI83m+g98YTV0ciZXP0iHWt3JDgo2NpgNGtEfJSSESm5b781zW/VqkH37lZHI3+qXNmUaQAmT4a1ay0NR87gE/0iLirTiI9SMiIl5yrRXHsthJR6j0XxoGuugYEDITcXkpLM/oXiG3ziShoXJSPio5SMSMnk5cH8+eZYJRqf9PLLULUq/PgjPP+81dEIwKETh/gt7TfAR5IR9YyIj1IyIiWzciWkpEB0NFx+udXRSDFq1oSXXjLHTzxhdosXa/2w5wcALqp6EdUqVLM4GtQzIj5LyYiUjKtE068fhIdbG4uc1c03Q+/eZhxMUpJZ0BLruEo0nRN8oF8ETicjBw6YjS5FfISSETk/p7PwxnjisxwOePVViIqC77+HGTOsjiiwuZpXL67tAyUaMHW8iAhzvHevtbGIFKBkRM5v3TrYudNM2erVy+po5Dzq1oVnnzXH//iH+acT78tz5vFDsinT+MzKiMOhvhHxSUpG5PxcqyK9e58eJy0+behQ+MtfzH6Gd99tFrfEuzYf2Ex6VjoVQivQomYLq8M5TX0j4oOUjMi5qURjS0FBZlR8eDh8+SX8619WRxR4XP0iHeI7EBLkQ5fC6/Je8UFKRuTcNm6ELVvMvvV9+1odjZRC48bw+OPmeNQo2LfP2ngCjU8NOytIyYj4ICUjcm6uVZGePc1lvWIrY8ZAmzZw6BDcd5/V0QQWnxp2VpCSEfFBSkbk3FSisbXQUJg9G4KD4T//Ob21kHjW0ZNH2XRgE+CDyYirgVU9I+JDlIzI2W3dCj//bEa/X3ON1dFIGbVrBw8+aI6HDYMjRywNJyCsSl6FEycNKjcgNirW6nAK08qI+CAlI3J2rlWRHj3MfAKxrfHjoVEjM0TXlZiI5+T3i/jKJb0FuZKRffvMdDwRH6BkRM5OJRq/ERlprq4B8/Gbb6yNx9/l94v4yrCzgqpXPz1FWYPPxEcoGZHi7dwJa9aYIUnXXWd1NOIG3bqZMg3AXXeZGSTifnnOPN8bA1+Qw6FSjfgcJSNSPNcOvd26QayP1bylzCZNMv2L27aZ0o2439a0rRw+eZiIkAhaxbayOpziafCZ+BglI1I8lWj8UnS02bsGYOpU+OEHS8PxS65+kfbx7QkLDrM4mrPQyoj4GCUjUlRKitllDWDAAGtjEbfr0wduucXs6JuUpB5Gd/PpfhEXJSPiY5SMSFEffWTGwHfqdPqHlviVF1+EGjXMgN1Jk6yOxr/49JU0LtosT3yMkhEpSiUav1e9Orzyijn+5z/hl1+sjcdfZGRl8Mt+8830uWFnBalnRHyMkhEp7OBBWLbMHCsZ8Ws33mhm2Z06Zco1ublWR2R/q/euJs+ZR92YusRXirc6nLNTmUZ8jJIRKezjj81vpTZtoGFDq6MRD3I4YMYM09S6ahW8/LLVEdmfz+5HcyZXMpKaarJREYspGZHCVKIJKLVrw+TJ5njcOHPJr5Sdz+7Ue6YaNcxO3E6naVgXsZiSETntyBH4+mtzrGQkYAwZYib+nzgBd95pfj9J6TmdTvusjAQFmUwU1DciPkHJiJz22WdmybZpU3OTgOBwwOuvm5Hx//0vzJljdUT29MfhPzh4/CBhwWG0rdXW6nDOT30j4kOUjMhpKtEErAsvhCefNMcPPKAtS8rCtSrSLq4d4SHhFkdTAkpGxIcoGREjMxO++MIcKxkJSPffDx06wNGjZg8blWtKZ8Vum/SLuGjWiPgQJSNifP65aRpo2BBat7Y6GrFASIjZ0TckxFxU9cEHVkdkLyuTbdIv4qJZI+JDlIyIUbBE43BYG4tYplUrGDvWHN97Lxw6ZG08dnH81HF+TP0RsNHKiMo04kOUjAicPAmffmqOVaIJeOPGmf7l/fth9Giro7GHNXvXkOvMJb5SPHWibbKFgpIR8SFKRgQWL4Zjx8wPpw4drI5GLBYeDrNnmwWyt96CL7+0OiLf52pe7VynMw67rCy6ekZSUiAnx9pYJOApGZHTJZoBA8z8AQl4nTvDffeZ47vugowMa+Pxda5hZ7bpFwGoWdM0COXlafCZWE6/eQLdqVOwcKE5VolGCnjqKahfH3btMqUbKV7BYWe26ReBwoPPVKoRiykZCXRLlsDhw+avpK5drY5GfEhUlBmGBjBtGvzvf9bG46t2Ht1J6rFUQoJCaBfXzupwSkd9I+IjlIwEOleJpn9/CA62NhbxOVdeCbffbmaODBliep2lMNeqSJtabYgMjbQ4mlLSrBHxEUpGAlluLixYYI5VopGzeOEFqFULfv3VlG6kMNsNOytIs0bERygZCWTffWeu36xSBS691OpoxEdVqQLTp5vjZ5+FDRssDcfn2G7YWUEq04iPUDISyFwlmmuvhdBQa2MRnzZggFk8y8mBpCRdCepyMuck61PWAzZfGVEyIhZTMhKo8vJg/nxzrBKNlMC0aVC5MqxbB1OmWB2Nb1iXso5TeaeoWbEm9SvXtzqc0lMyIj5CyUigWrUKkpOhUiXTpShyHrVqwYsvmuPHH4ctW6yNxxcU7BexzbCzglwNrHv3mh4yEYsoGQlUrhLN1VebkZsiJXDbbSZ3PXkS7rzTLLAFMlv3iwDExpqr6HJzITXV6mgkgCkZCUROZ+GN8URKyOEws0cqVoTly0/PIQlUtr6SBkwiEh9vjlWqEQspGQlEGzbA9u0QGQlXXWV1NGIz9evD00+b44ceCtyrQvek7yE5I5lgRzDt49tbHU7ZqW9EfICSkUDkWhXp3dv8iStSSsOHm/1rMjLgnnvMYlugca2KtIptRcUwG/9/pMFn4gOUjAQilWiknIKDYdYsCAuDzz6D996zOiLvc01etW2/iIsGn4kPUDISaDZtMqM0w8JM86pIGTVrBo89Zo7vuw8OHLA2Hm9z7dRr234RF5VpxAeUKRmZMWMGDRo0ICIigsTERL799tuzPnf+/PlceeWV1KhRg+joaDp37syXX35Z5oClnFyrIldeCdHR1sYitvfQQ9CqFaSlwf33Wx2N92TlZLEuZR3gRysjSkbEQqVORubNm8fIkSMZN24c69evp1u3bvTu3Ztdu3YV+/zly5dz5ZVXsmjRItauXUuPHj3o168f69evL3fwUgYq0YgbhYXB7NlmN/r33oNPPrE6Iu/YkLqBrNwsqkVW48KqF1odTvmoZ0R8QKmTkSlTppCUlMSQIUNo2rQpU6dOJSEhgZkzZxb7/KlTp/LQQw/RoUMHLrroIp5++mkuuugiPgmUn1q+5I8/4McfTcH/mmusjkb8RPv2MHq0Ob7nHjh61Np4vKFgv4gth50V5FoZSU7W4DOxTKmSkezsbNauXUvPnj0L3d+zZ0++//77Er1HXl4eGRkZVK1a9azPycrKIj09vdBN3MC1KtKjB1SrZm0s4leeeAIuuMD8PvvHP6yOxvP8pl8EzGjdoCCz4dD+/VZHIwGqVMnIwYMHyc3NJTY2ttD9sbGxpJZwet8LL7xAZmYmN95441mfM2nSJGJiYvJvCa5lRCkflWjEQypUgDfeMMevvgrLllkbj6f5zZU0ACEhEBdnjlWqEYuUqYH1zGVJp9NZoqXK9957jwkTJjBv3jxq1qx51ueNHTuWo0eP5t9265Kz8tu92+xH43DAdddZHY34oR494K67zPGQIXDihLXxeEpKRgo7j+7EgYOOtTtaHY57qG9ELFaqZKR69eoEBwcXWQXZv39/kdWSM82bN4+kpCT+85//cMUVV5zzueHh4URHRxe6STm5dujt2tUsy4p4wHPPmeniv/8OEyZYHY1nuFZFWtRsQaXwShZH4yaaNSIWK1UyEhYWRmJiIosXLy50/+LFi+nSpctZX/fee+8xePBg3n33Xfr27Vu2SKV8VKIRL4iJMWUagMmTYc0aa+PxBFcy4hf9Ii66vFcsVuoyzejRo5k1axZz5sxh8+bNjBo1il27djF06FDAlFgGDRqU//z33nuPQYMG8cILL3DxxReTmppKamoqRwOh5d5XpKbCd9+Z4wEDrI1F/F6/fvC3v5kdfZOS4NQpqyNyL1fzql/0i7goGRGLlToZGThwIFOnTmXixIm0adOG5cuXs2jRIurVqwdASkpKoZkjr732Gjk5OQwfPpy4uLj82/2BNCHJagsWmM1DOnSAunWtjkYCwEsvmQu2fvrJlG78xancU6zZa5Z7Oif40cqIekbEYiFledGwYcMYNmxYsY/NnTu30OdLly4tyynEnVSiES+rWdMkJLfcAhMnmgW5pk2tjqr8ftr3EydyTlA5ojKNqjWyOhz3Uc+IWEx70/i7tDRYssQcKxkRL7rpJujTB7KzTbnGH+ZpFbykN8jhRz8+Cw4+y8uzNhYJSH70f5MUa+FC81ugVSu40OZjq8VWHA7TzBoVBStWwIwZVkdUfvn9IrX9qF8EzJwRh8M0+ATajofiE5SM+DuVaMRCCQmne0bGjoUdOywNp9zyr6Txp34RgNBQDT4TSykZ8Wfp6eC6DFvJiFjk7ruhWzfIzDTHTqfVEZXN/sz9/HH4DwD/GXZWkPpGxEJKRvzZp5+agn3jxtCsmdXRSIAKCoJZsyA8HL76Ct5+2+qIyuaHPT8A0LR6UypHVLY2GE/Q5b1iISUj/qxgicbuO4uKrTVqZDbTAxg1yoy+sRu/2hyvOEpGxEJKRvxVZiZ8/rk5VolGfMADD0C7dnD4MIwYYXU0pedXm+MVR8mIWEjJiL/68kuzU1n9+tC2rdXRiBASArNnQ3AwfPDB6e2S7CAnL4dVyasAP2xedXENPlPPiFhAyYi/UolGfFCbNvDww+Z4+HCzSmIHG/dvJPNUJpXCKtG0uh9MbyuOVkbEQkpG/FFWlmleBZVoxOc89pjpqU5NhTFjrI6mZFz9Ip3qdCI4KNjiaDykYDJi10uexLaUjPijr782l/XGx0OnTlZHI1JIRIQp1zgcMGeO+c/V1+X3i/jbsLOC4uPNP0p2Nhw8aHU0EmCUjPgjV4lmwABzXaWIj+na1ZRpAO680/Rb+7L8K2n8tV8EICwMYmPNsUo14mX6TeVvTp2Cjz82xyrRiA97+mnTM7ljBzz6qNXRnF3a8TS2pG0BoFNtP19p1OAzsYiSEX+zbBkcOgQ1apixlyI+qlIleO01c/zSS7BypbXxnM0PyWbYWaNqjahWoZrF0XiYmljFIkpG/I2rRHPddeYaShEf1rs33Hqr6ZdMSjK9177G7+eLFKRkRCyiZMSf5ObCRx+ZY5VoxCZefNEs5G3aBJMmWR1NUX4/ebUg16wRJSPiZUpG/Mn338O+fVC5MvToYXU0IiVSrRpMm2aOn34afv7Z2ngKys3Lzd+TJqBWRtQzIl6mZMSfuEo011xjOuNFbOKGG+Daa03/dVKSWeTzBZsPbiYjO4OKoRVpUbOF1eF4nso0YhElI/7C6Tw9X1slGrEZhwNmzICYGFi92jS0+gJXv0iH2h0ICQqxOBov0OAzsYiSEX+xerVZWo2Kgp49rY5GpNTi42HyZHP86KPwxx/WxgOwYncA9YsA1K5tPp48aa7KE/ESJSP+wlWi6dvXjLgUsaGkJNPudOKEGYZm9R/nK5MD6EoagPBwqFnTHKtvRLxIyYg/cDoLb4wnYlMOB7zxBkRGwpIlZmy8VY6cPMKmA5uAAEpGQH0jYgklI/7gp5/MmnZEhBncIGJjF1wATz1ljh94AJKTrYljVfIqABpWaUjNijWtCcIKSkbEAkpG/IFrVeSqq0zPiIjN3X8/dOxo9nscNsyaco2reTVg+kVcNGtELKBkxB+oRCN+JjjYlGhCQ2HhQvi///N+DK5hZwFVogHNGhFLKBmxu19/NaMrQ0Ph6qutjkbEbVq0gEceMcf33gtpad47d54zL3/YWcCtjKhMIxZQMmJ3rlWRK64wk1dF/MjYsdC8ORw4AKNGee+8W9K2cPjkYSJDImkV28p7J/YFSkbEAkpG7E4lGvFj4eGmXONwwL/+BZ9/7p3zuvpF2se3JzQ41Dsn9RUFe0asvrZaAoaSETvbtg3WrzcF9muvtToaEY/o1AlGjjTHd98NGRmeP6dr2FnA9YvA6cFnx4/D4cPWxiIBQ8mInbnGv3fvDtWrWxuLiAc9+SQ0aGB6KseO9fz5Am7YWUEREad/nqhUI16iZMTOVKKRAFGxohmGBjB9Onz7refOlZGVwS/7fwECNBkB9Y2I1ykZsas9e2DlSlNM79/f6mhEPO7yy824eIAhQ8z2KZ6weu9q8px51I2pS3yleM+cxNdp1oh4mZIRu/roI/OxSxeIi7M2FhEvmTzZ/Oe+ZQtMnOiZcwTc5njF0awR8TIlI3alEo0EoMqVTZkG4LnnTP+2uwV0v4iLyjTiZUpG7Gj//tNF8wEDrI1FxMv694frr4fcXFO2yclx33s7nc7AHQNfkJIR8TIlI3a0YAHk5UH79lCvntXRiHjdK69AlSpmZeSFF9z3vn8c/oODxw8SFhxGm1pt3PfGdqNkRLxMyYgdqUQjAa5WLXjxRXP8+OOmh8QdXP0iiXGJhIeEu+dN7cjVwLp7twafiVcoGbGbw4fhv/81x0pGJIANGgQ9e0JWlrm6Ji+v/O/pKtEEdL8InB58lpkJR49aG4sEBCUjdrNwoSmSt2wJF11kdTQilnE44LXXzAySb781x+Xl2qk3oPtFACpUgKpVzbFKNeIFSkbsRiUakXz168OkSeb4oYdg166yv1dmdiY/7fsJ0MoIoL4R8SolI3aSkQFffWWOdRWNCADDhplxO8eOwdChZW9xWLN3DbnOXGpXqk1CTIJ7g7QjDT4TL1IyYieffWYK5BddBC1aWB2NiE8IDoZZsyAszOzq++67ZXsf9YucQYPPxIuUjNhJwRKNw2FtLCI+pGlTGD/eHN9/vxnFU1rqFzmDyjTiRUpG7OL4cVi0yByrX0SkiIceglatIC3NJCSlUXDYmVZG/qRkRLxIyYhdfPmlSUjq1YPERKujEfE5oaEwZw4EBcH775sLz0pqx5Ed7MvcR2hQKO3i2nkuSDtRz4h4kZIRu3CVaAYMUIlG5CwSE2HMGHN8zz0lH5HhWhVpU6sNkaGRHorOZtQzIl6kZMQOsrLgk0/MsUo0Iuc0YQJceCHs3WtKNyWhfpFiuAafZWRAerq1sYjfUzJiB998Y34YxMVBZ/2wFDmXyEhzdQ3A66/DkiXnf436RYoRFWW2SQaVasTjlIzYwfz55mP//qYgLiLn1L27mTkCcOedpt3qbE6cOsH61PUAdE5Qsl+I+kbES/Sbzdfl5JhdekElGpFSePZZ0/bwxx9mM72zWZeyjpy8HGIrxlIvRrtgF6K+EfESJSO+bvlyc61itWpwySVWRyNiG9HR8Oqr5njKFFi9uvjnuUo0nRM641BzeGG6vFe8RMmIr3NdRXPddRASYmkoInbTty/cdJPZ0TcpCbKziz7H1bx6cW31ixShZES8RMmIL8vLg48+Mscq0YiUydSpUL06/PyzKd2cqeDKiJxBPSPiJUpGfNmKFZCSAjExcPnlVkcjYks1asBLL5njJ5+ETZtOP7b76G6SM5IJdgSTGKdhgkWoZ0S8RMmIL3OVaPr1M7uAiUiZ/P3vpmRz6hQMGQK5ueZ+16pI61qtqRhW0cIIfZTKNOIlSkZ8ldN5+pJelWhEysXhgJkzoVIls+A4fbq5X/0i5+FKRo4eNcPPRDxEyYivWrsWdu6EihWhVy+roxGxvYQEeO45czx2LOzYoWFn51WpkikTAyQnWxuL+LUyJSMzZsygQYMGREREkJiYyLfffnvO5y9btozExEQiIiJo2LAhr7qut5Ozc5Vo+vQxIyVFpNzuustcIX/8OAy5O4u1KWsBNa+ek/pGxAtKnYzMmzePkSNHMm7cONavX0+3bt3o3bs3u3btKvb527dvp0+fPnTr1o3169fzyCOPcN999/Gh65etFOV0nk5GVKIRcZugIHjjDYiIgG82biA7N5vqFapzQZULrA7Nd6lvRLyg1MnIlClTSEpKYsiQITRt2pSpU6eSkJDAzJkzi33+q6++St26dZk6dSpNmzZlyJAh3HHHHUyePPms58jKyiI9Pb3QLaD88gts3Qrh4WZlRETcplEjeOIJIMH0i7StfrGGnZ2LkhHxglIlI9nZ2axdu5aePXsWur9nz558//33xb5mxYoVRZ7fq1cv1qxZw6lTp4p9zaRJk4iJicm/JbiudQ8UrlWRXr1MzVZE3Gr0aKjS0vSLHNygfpFzUjIiXlCqkZ4HDx4kNzeX2NjYQvfHxsaSmppa7GtSU1OLfX5OTg4HDx4kLi6uyGvGjh3L6NGj8z9PT0/3SEJy7bXQoAF06OD2ty6f/v1NUfsvf7E6EhG/FBICE/86iFcW1WLSEDWIn9Oll8LJk/p55MduanETF9e+mGY1mlkWQ5nmi5+5pOl0Os+5zFnc84u73yU8PJzw8PCyhFYqAweam89p3drcRMRj7u3Vh3t7qQx6Xpdeam7it5LaJVkdQunKNNWrVyc4OLjIKsj+/fuLrH641KpVq9jnh4SEUK1atVKGKyIiIv6mVMlIWFgYiYmJLF68uND9ixcvpkuXLsW+pnPnzkWe/9VXX9G+fXtCQ0NLGa6IiIj4m1JfTTN69GhmzZrFnDlz2Lx5M6NGjWLXrl0MHToUMP0egwYNyn/+0KFD2blzJ6NHj2bz5s3MmTOH2bNnM2bMGPd9FSIiImJbpe4ZGThwIGlpaUycOJGUlBRatGjBokWLqFevHgApKSmFZo40aNCARYsWMWrUKKZPn058fDwvv/wyf9X8DBEREQEcTlc3qQ9LT08nJiaGo0ePEh0dbXU4IiIiUgIl/f2tvWlERETEUkpGRERExFJKRkRERMRSSkZERETEUkpGRERExFJKRkRERMRSSkZERETEUkpGRERExFJl2rXX21xz2dLT0y2ORERERErK9Xv7fPNVbZGMZGRkAJCQkGBxJCIiIlJaGRkZxMTEnPVxW4yDz8vLY+/evVSqVAmHw+G2901PTychIYHdu3drzHwJ6XtWOvp+lZ6+Z6Wj71fp6XtWOuX5fjmdTjIyMoiPjyco6OydIbZYGQkKCqJOnToee//o6Gj9B1lK+p6Vjr5fpafvWeno+1V6+p6VTlm/X+daEXFRA6uIiIhYSsmIiIiIWCqgk5Hw8HAef/xxwsPDrQ7FNvQ9Kx19v0pP37PS0fer9PQ9Kx1vfL9s0cAqIiIi/iugV0ZERETEekpGRERExFJKRkRERMRSSkZERETEUkpGRERExFIBm4wsX76cfv36ER8fj8PhYMGCBVaH5LMmTZpEhw4dqFSpEjVr1uS6667jt99+szosnzZz5kxatWqVP7Gwc+fOfP7551aHZRuTJk3C4XAwcuRIq0PxWRMmTMDhcBS61apVy+qwfFpycjK33HIL1apVo0KFCrRp04a1a9daHZbPql+/fpH/xhwOB8OHD3f7uQI2GcnMzKR169ZMmzbN6lB83rJlyxg+fDgrV65k8eLF5OTk0LNnTzIzM60OzWfVqVOHZ555hjVr1rBmzRouu+wyrr32WjZu3Gh1aD5v9erVvP7667Rq1crqUHxe8+bNSUlJyb/9/PPPVofksw4fPkzXrl0JDQ3l888/Z9OmTbzwwgtUrlzZ6tB81urVqwv997V48WIAbrjhBrefyxZ703hC79696d27t9Vh2MIXX3xR6PM333yTmjVrsnbtWi655BKLovJt/fr1K/T5P//5T2bOnMnKlStp3ry5RVH5vmPHjnHzzTfzxhtv8NRTT1kdjs8LCQnRakgJPfvssyQkJPDmm2/m31e/fn3rArKBGjVqFPr8mWee4YILLqB79+5uP1fAroxI2R09ehSAqlWrWhyJPeTm5vL++++TmZlJ586drQ7Hpw0fPpy+fftyxRVXWB2KLWzdupX4+HgaNGjA3/72N7Zt22Z1SD5r4cKFtG/fnhtuuIGaNWvStm1b3njjDavDso3s7Gz+/e9/c8cdd+BwONz+/kpGpFScTiejR4/mL3/5Cy1atLA6HJ/2888/ExUVRXh4OEOHDuWjjz6iWbNmVofls95//33WrVvHpEmTrA7FFjp16sTbb7/Nl19+yRtvvEFqaipdunQhLS3N6tB80rZt25g5cyYXXXQRX375JUOHDuW+++7j7bfftjo0W1iwYAFHjhxh8ODBHnn/gC3TSNnce++9/PTTT3z33XdWh+LzGjduzIYNGzhy5Agffvght912G8uWLVNCUozdu3dz//3389VXXxEREWF1OLZQsMzcsmVLOnfuzAUXXMBbb73F6NGjLYzMN+Xl5dG+fXuefvppANq2bcvGjRuZOXMmgwYNsjg63zd79mx69+5NfHy8R95fKyNSYiNGjGDhwoUsWbKEOnXqWB2OzwsLC+PCCy+kffv2TJo0idatW/PSSy9ZHZZPWrt2Lfv37ycxMZGQkBBCQkJYtmwZL7/8MiEhIeTm5lodos+rWLEiLVu2ZOvWrVaH4pPi4uKK/CHQtGlTdu3aZVFE9rFz506+/vprhgwZ4rFzaGVEzsvpdDJixAg++ugjli5dSoMGDawOyZacTidZWVlWh+GTLr/88iJXgtx+++00adKEhx9+mODgYIsis4+srCw2b95Mt27drA7FJ3Xt2rXISIItW7ZQr149iyKyD9dFC3379vXYOQI2GTl27Bi///57/ufbt29nw4YNVK1albp161oYme8ZPnw47777Lh9//DGVKlUiNTUVgJiYGCIjIy2Ozjc98sgj9O7dm4SEBDIyMnj//fdZunRpkSuTxKhUqVKRHqSKFStSrVo19SadxZgxY+jXrx9169Zl//79PPXUU6Snp3PbbbdZHZpPGjVqFF26dOHpp5/mxhtvZNWqVbz++uu8/vrrVofm0/Ly8njzzTe57bbbCAnxYMrgDFBLlixxAkVut912m9Wh+Zzivk+A880337Q6NJ91xx13OOvVq+cMCwtz1qhRw3n55Zc7v/rqK6vDspXu3bs777//fqvD8FkDBw50xsXFOUNDQ53x8fHOAQMGODdu3Gh1WD7tk08+cbZo0cIZHh7ubNKkifP111+3OiSf9+WXXzoB52+//ebR8zicTqfTc6mOiIiIyLmpgVVEREQspWRERERELKVkRERERCylZEREREQspWRERERELKVkRERERCylZEREREQspWRERERELKVkRERERCylZEREREQspWRERERELPX/J6fk+lhNoEEAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAGxCAYAAACwbLZkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABi30lEQVR4nO3dd3gUVdsG8HvTAyGhBEKAAKGlgBQDSJEOoSOiwisqoKAiCAKigiggFj4botIsIPq+qCBNSlSCEjoqGERJ6CUBEkJPg9T5/jjMZpcUssnunpnd+3dde2UymZ15dl3Dk3nOOY9BURQFRERERJK4yA6AiIiInBuTESIiIpKKyQgRERFJxWSEiIiIpGIyQkRERFIxGSEiIiKpmIwQERGRVExGiIiISComI0RERCQVkxEiBxEVFYXZs2eX6xyjRo1C/fr1rRJPUQwGQ6liXL58OQwGA86cOWPct2jRIixfvrzQsTExMTAYDFi9enW5YpszZw7Cw8ORn59frvNY6oknnsDgwYPtek0irWEyQuQgoqKi8MYbb8gOo0R79+7FmDFjyvTc4pIRa7hw4QLee+89zJkzBy4u9v21OHv2bGzevBm//fabXa9LpCVMRojIbtq1a4c6derIDqOQjz/+GJUrV8aQIUPsfu2GDRuiT58++L//+z+7X5tIK5iMEEkwe/ZsGAwGxMbGYsiQIfD19YWfnx8ef/xxXLp0qdDxK1euRPv27VGxYkX4+Pigd+/eiI2NNf581KhRWLhwIQBRClEfaplj4cKF6Ny5M2rUqIGKFSvinnvuwXvvvYecnByLY1+4cCFcXFyQkpJi3Pfhhx/CYDBg/Pjxxn35+fmoUqUKXnzxReO+oso0+/btQ8eOHeHl5YVatWph+vTpheKqX78+Dh8+jO3btxtf253lpJycHMyYMQO1atWCr68vevbsiaNHj9719WRnZ2Pp0qUYPnx4obsiWVlZmDNnDsLCwuDl5YVq1aqhW7du2LNnj9lrev755/HVV18hJCQE3t7eaN26Nfbt2wdFUfD+++8jODgYPj4+6N69O06cOFEohieeeAJbt27FyZMn7xovkSNiMkIk0YMPPohGjRph9erVmD17NtavX4/evXub/WP8zjvv4NFHH0V4eDhWrVqF//73v0hLS0OnTp0QFxcHAHj99dfx8MMPAxClEPURGBgIADh58iSGDx+O//73v9i0aRNGjx6N999/H88++6zFMffs2ROKouDXX3817tu6dSu8vb0RHR1t3Ld//35cv34dPXv2LPZccXFx6NGjB65fv47ly5djyZIliI2NxVtvvWV23Lp169CgQQO0atXK+NrWrVtndsyrr76Ks2fP4ssvv8Tnn3+O48ePY+DAgcjLyyvx9fz++++4cuUKunXrZrY/NzcXffv2xZtvvokBAwZg3bp1WL58OTp06ICEhASzYzdt2oQvv/wS//d//4fvvvsOaWlp6N+/P1588UXs3r0bCxYswOeff464uDg89NBDuLNZeteuXaEoCqKiokqMlchhKURkd7NmzVIAKJMnTzbbv2LFCgWA8r///U9RFEVJSEhQ3NzclAkTJpgdl5aWptSsWVMZOnSocd/48eOV0vwvnZeXp+Tk5CjffPON4urqqly9etX4s5EjRyr16tW76znq1KmjPPXUU4qiKEpWVpZSsWJF5ZVXXlEAKGfPnlUURVHefvttxd3dXUlPTzc+D4Aya9Ys4/fDhg1TvL29leTkZOO+3NxcJTQ0VAGgnD592ri/adOmSpcuXQrFsm3bNgWA0q9fP7P9q1atUgAoe/fuLfG1vPvuuwoAsxgURVG++eYbBYDyxRdflPh8AErNmjXNXuf69esVAErLli2V/Px84/758+crAJRDhw4VOk/t2rWVYcOGlXgtIkfFOyNEEj322GNm3w8dOhRubm7Ytm0bAOCXX35Bbm4uRowYgdzcXOPDy8sLXbp0QUxMTKmuExsbi0GDBqFatWpwdXWFu7s7RowYgby8PBw7dsziuHv06IGtW7cCAPbs2YPMzExMmTIF/v7+xrsjW7duNZaWirNt2zb06NEDAQEBxn2urq4YNmyYxTENGjTI7PvmzZsDAM6ePVvi8y5cuACDwQB/f3+z/T/99BO8vLzw1FNP3fXa3bp1M3udYWFhAIC+ffvCYDAU2l9UTDVq1MD58+fvei0iR8RkhEiimjVrmn3v5uaGatWq4cqVKwCAixcvAgDatGkDd3d3s8fKlStx+fLlu14jISEBnTp1wvnz5/Hxxx9j586d+PPPP41jTG7evGlx3D179kRCQgKOHz+OrVu3olWrVqhRowa6d++OrVu34ubNm9izZ0+JJRoAuHLlSqH3ACj8vpRGtWrVzL739PQEcPfXd/PmTbi7u8PV1dVs/6VLl1CrVq1Sza6pWrWq2fceHh4l7r9161ahc3h5eZXpvwWRI3CTHQCRM0tOTkbt2rWN3+fm5uLKlSvGf1jVv9ZXr16NevXqleka69evR0ZGBtauXWt2joMHD5Y57h49egAQdz+io6PRq1cv4/7XXnsNO3bsQFZW1l2TkWrVqiE5ObnQ/qL22Yq/vz+ys7ORkZFhdnejevXq2LVrF/Lz8+0y3ffq1as2XeOFSMt4Z4RIohUrVph9v2rVKuTm5qJr164AgN69e8PNzQ0nT55E69ati3yoirsToJYJ1J8DgKIo+OKLL8ocd2BgIMLDw7FmzRocOHDAmIz06tULly5dwrx58+Dr64s2bdqUeJ5u3brh119/Nd4BAoC8vDysXLmy0LGenp42uXMQGhoKAIVmsvTt2xe3bt2y2dompnJzc5GYmIjw8HCbX4tIi3hnhEiitWvXws3NDb169cLhw4fx+uuvo0WLFhg6dCgAMaV1zpw5mDFjBk6dOoU+ffqgSpUquHjxIv744w9UrFjRuNDZPffcAwB499130bdvX7i6uqJ58+bo1asXPDw88Oijj+Lll1/GrVu3sHjxYly7dq1csffo0QOffvopvL290bFjRwBAcHAwgoODsWXLFgwaNAhubiX/innttdewYcMGdO/eHTNnzkSFChWwcOFCZGRkFDr2nnvuwffff4+VK1eiQYMG8PLyMr7m8lATv3379hnHmQDAo48+iq+++gpjx47F0aNH0a1bN+Tn5+P3339HWFgY/vOf/5T72qpDhw4hMzOz0IweImfBOyNEEq1duxZHjhzBkCFDMHPmTAwcOBBbtmwxji0AgOnTp2P16tU4duwYRo4cid69e+Pll1/G2bNn0blzZ+Nxw4cPx5gxY7Bo0SK0b98ebdq0wYULFxAaGoo1a9bg2rVrGDJkCCZMmICWLVvik08+KVfsagnm/vvvh5eXV6H9dyvRAECzZs2wdetW+Pr6YuTIkXjmmWfQvHlzvP7664WOfeONN9ClSxc8/fTTaNu2LQYOHFiu+FVBQUHo1KkTfvzxR7P9bm5uiIqKwvTp07Fu3To88MADGDFiBHbt2lXmkllx1q9fD39/f0RGRlr1vER6YVCUOya8E5HNzZ49G2+88QYuXbpUaBYH2d+aNWswbNgwnD171mwMjz3k5eWhUaNGGD58ON5++227XptIK3hnhIic3pAhQ9CmTRvMnTvX7tf+3//+h/T0dLz00kt2vzaRVjAZISKnZzAY8MUXX6BWrVp279qbn5+PFStWoHLlyna9LpGWsExDREREUvHOCBEREUnFZISIiIikYjJCREREUuli0bP8/HxcuHABlSpVMms6RURERNqlKArS0tLu2udJF8nIhQsXEBQUJDsMIiIiKoPExETUqVOn2J/rIhmpVKkSAPFifH19JUdDREREpZGamoqgoCDjv+PF0UUyopZmfH19mYwQERHpzN2GWHAAKxEREUnFZISIiIikYjJCREREUulizAgRETkvRVGQk5OD3Nxc2aHQHdzc3ODu7l7uZTeYjBARkWZlZWXhzJkzSE9Plx0KFcPHxwf169eHp6dnmc/BZISIiDQpPz8fcXFxcHNzQ3BwMDw9PbnwpYYoioKsrCycP38ehw8fRtOmTcuckDAZISIiTbp16xby8/MRHBwMHx8f2eFQESpWrAgPDw8cPXoUUVFR6Nmz513XFCkKB7ASEZGmlbSMOMmn/vc5d+4cNm/ejFu3bll+DmsHRURERM6nevXqOHfuHK5evWrxc5mMEBERUbm5ubkhNzfXPndGduzYgYEDB6JWrVowGAxYv379XZ+zfft2REREwMvLCw0aNMCSJUssDpSIiIgck8XJSEZGBlq0aIEFCxaU6vjTp0+jX79+6NSpE2JjY/Hqq69i4sSJWLNmjcXBEhER6cGoUaMwePBg2WHohsWzafr27Yu+ffuW+vglS5agbt26mD9/PgAgLCwM+/fvxwcffICHHnqoyOdkZWUhKyvL+H1qaqqlYZbK6dPAZ58BZbijVKR69YCJEwFXV+ucj6wkJQX4+GMgI0N2JOSs6tUDJk0CHHBa6rWb1zBv7zykZadZ/dxV3aqif5X+Vj8vaY/Np/bu3bsXkZGRZvt69+6NpUuXIicnB+7u7oWeM3fuXLzxxhu2Dg3vvAN8+aV1z+npCYwbZ91zUjnNmQMsXCg7CnJ2LVsC3brJjsLq3t39Lt7d/a5Nzh3iG4L+nc2TEUUBMjNtcrm7qlDBOvnk9u3b8dJLL+Hvv/9G1apVMXLkSLz11ltwc3PDxo0b8cQTT+Dq1atwcXHBwYMH0apVK0ydOhXvv/8+AODZZ59Famoqvvvuu/IHoxE2T0aSk5MREBBgti8gIAC5ubm4fPkyAgMDCz1n+vTpmDJlivH71NRUBAUFWT029Q/lnj2Btm3Ld64zZ4BvvwVefRUYMgSoWbPc4ZE1KAqgjmsaNQqoVUtmNOSMNmwA/v0X+Ptvh0tGFEXBysMrAQCPN38cdX3rWvX8lV0rF9qXmQnIWnIkPR2oWLF85zh//jz69euHUaNG4ZtvvsGRI0fw9NNPw8vLC7Nnz0bnzp2RlpaG2NhYREREYPv27fD398f27duN54iJicHkyZPL+Wq0xS6Lnt25Yp6iKEXuV3l6epZrWVlLDRgAvPBC+c6RlwccOwbs3w+8+CKwYoV1YqNy+usv4Px58Rtk8WLAy0t2RORsXFxEMnL4sOxIrG7/hf04c/0MKrhXwGcDPkMF9wpWPX9mZibi4+Otek7ZFi1ahKCgICxYsAAGgwGhoaG4cOECXnnlFcycORN+fn5o2bIlYmJiEBERYUw83njjDaSlpSEjIwPHjh1D165dZb8Uq7L51N6aNWsiOTnZbF9KSgrc3NxQrVo1W1/eblxdgSVLxO+db78Ffv1VdkQEAPjxR/G1d28mIiRH06biqwMmI6sOrwIADGwy0OqJSHEqVBB3KGQ8KljhJcbHx6N9+/Zmf4x37NgR6enpOHfuHACga9euiImJgaIo2LlzJx544AE0a9YMu3btwrZt2xAQEIDQ0NDyB6MhNr8z0r59e2zcuNFs35YtW9C6desix4voWUQEMH488OmnYtzIoUNiDAlJpCYjDzwgNw5yXqbJiKI4zCBWRVGwKk4kI4+EP2K36xoM5S+VyKQoyl2rBV27dsXSpUvx999/w8XFBeHh4ejSpQu2b9+Oa9euoUuXLnaP29YsvjOSnp6OgwcP4uDBgwDE1N2DBw8iISEBgBjvMWLECOPxY8eOxdmzZzFlyhTEx8dj2bJlWLp0KaZOnWqdV6Axb74pxoscOwa8957saJzcmTMiI3RxAfpzRD5J0qSJuHWamipKhg7ij/N/IOFGAiq6V0TfxqWfYenswsPDsWfPHmMCAgB79uxBpUqVULt2bQAwjhuZP38+unTpAoPBgC5duiAmJgYxMTFMRgBg//79aNWqFVq1agUAmDJlClq1aoWZM2cCAJKSkoyJCQAEBwcjKioKMTExaNmyJd5880188sknxU7r1Ts/P+Cjj8T2228DJ07Ijcepbdggvt5/P+BAJUHSGU9PoHFjse1ApZof4n4AAAwMsV+JRm9u3Lhh/ONdfTzzzDNITEzEhAkTcOTIEfz444+YNWsWpkyZYuzxoo4b+d///mccG9K5c2f89ddfDjleBChDmaZr165mGd2dli9fXmhfly5d8Ndff1l6Kd0aNgxYtgyIjhZlm59/dpg7s/rCEg1pRdOmwJEjIhnp3Vt2NOWmKIpxvMjQ8KGSo9GumJgY4x/uqpEjRyIqKgovvfQSWrRogapVq2L06NF47bXXzI7r1q0b/vrrL2PiUaVKFYSHh+PChQsICwuz10uwG7vMpnE2BoNY1uKee4AtW4AffgCG8v9X+7p2DVCnwjEZIdmaNgXWrHGYOyO/n/8diamJ8PHwQZ9GfWSHo0nLly8v8o9z1R9//FHi8z/44AN88MEHZvvU4RGOiI3ybKRxY2D6dLE9aZIoF5Md/fSTmG8dHg40bCg7GnJ2DjajRr0rMihkELzdvSVHQ46AyYgNvfIK0KgRkJQEvP667GicDEs0pCVqMhIXJ2bU6Fi+km8cL8ISDVkLkxEb8vICFi0S2wsWiPW3yA6yssSdEYDJCGlD48aAmxuQlgYkJsqOplz2nduHc6nnUMmjEno30v/4F9IGJiM21qsX8J//APn5wNixonJANrZ9u/ilX7Mm0KaN7GiIAA8PMcUX0H2pRi3RPBD6ALzcuJAgWQeTETuYNw/w9QX+/BP4/HPZ0TgBtUQzcKBYY4RICxxg3IhpicaeC52R4+NvajsIDBRrjgBiUOvFi3LjcWiKUrC+CEs0pCXh4eKrjpORPYl7cCHtAnw9fRHZMPLuTyAqJSYjdvLcc2K5+Bs3RCM9spG//gLOnRPrRffoITsaogIOcGfkh8PirsgDISzRkHUxGbETtZGewSA6+v72m+yIHJR6V4SN8UhrdD6jxmwWTVPOoiHrYjJiR61bixVZAXGnJCtLbjwOSR0vMmiQ3DiI7tS4MeDuDmRkACYtM/Rid8JuJKUnwc/TD70a9JIdDjkYJiN29tZbBY303n9fdjQO5swZ4O+/2RiPtMndXdczatRZNINDB8PTje3IZYuJiYHBYMD169cBiBVfK1euLDWm8mAyYmd+fmJ2DSASk5Mn5cbjUEwb4/n7y42FqCg6HTeSl5+H1fGrAbBEU1qjRo2CwWDA2LFjC/1s3LhxMBgMGDVqlNWuN2zYMBw7dsxq57M3JiMS/Oc/QM+eokzz/PO6LB9rk5qMsERDWqXTZGRXwi4kpyejsldl9GzQU3Y4uhEUFITvv/8eN2/eNO67desWvvvuO9StW9eq1/L29kaNGjWsek57YjIigdpIz8NDdPRdvVp2RA7g+nU2xiPt02kyopZoHgx9EB6uHnKDURQx7kbGw8K/HO+9917UrVsXa9euNe5bu3YtgoKCzLr5KoqC9957Dw0aNIC3tzdatGiB1Xf8wxAVFYUmTZrA29sb3bp1w5kzZ8x+fmeZZtSoURg8eLDZMZMmTTJ2AQaArl27YsKECZg0aRKqVKmCgIAAfP7558jIyMCTTz6JSpUqoWHDhvhJXdHahpiMSNKkCRvpWVVUFJCbK9ZyaNRIdjRERTOdUZOfLzeWUsrLz8Oa+DUANLLQWWYm4OMj55GZaXG4Tz75JL766ivj98uWLcNTTz1ldsxrr72Gr776CosXL8bhw4cxefJkPP7449h++w+sxMREDBkyBP369cPBgwcxZswYTJs2rXzv421ff/01/P398ccff2DChAl47rnn8Mgjj6BDhw7466+/0Lt3bzzxxBPILMNrtwSTEYmmTRP/bl64AMycKTsanWNjPNKDRo3ELdHMTODsWdnRlMrOhJ24mHERVbyqoEcDrt1jqSeeeAK7du3CmTNncPbsWezevRuPP/648ecZGRmYN28eli1bht69e6NBgwYYNWoUHn/8cXz22WcAgMWLF6NBgwb46KOPEBISgscee8xq401atGiB1157DY0bN8b06dPh7e0Nf39/PP3002jcuDFmzpyJK1eu4NChQ1a5XnHcbHp2KpGXlyjX9O4NfPopMHIkYHLnjkorO7ugMR7Hi5CWubkBISHAP/+IUk1wsOyI7kpTJRoAqFABSE+Xd20L+fv7o3///vj666+hKAr69+8Pf5MB9nFxcbh16xZ69TKfLp2dnW0s5cTHx6Ndu3YwGAzGn7dv376ML8Jc8+bNjduurq6oVq0a7rnnHuO+gIAAAEBKSopVrlccJiOSRUYCw4YBK1eKRnp79ogF0sgCMTEFjfHatpUdDVHJmjYtSEYGDJAdTYly83ONJRrNzKIxGMQKyzry1FNP4fnnnwcALFy40Oxn+bfLdZs3b0bt2rXNfubpKaZQK2WY5eDi4lLoeTk5OYWOc3d3N/veYDCY7VMToHwblxVZptEAtZHeH38AX3whOxodYmM80hMdDWLdcXYHUjJSUNW7KroHd5cdjm716dMH2dnZyM7ORu/evc1+Fh4eDk9PTyQkJKBRo0Zmj6CgIOMx+/btM3vend/fqXr16khKSjLbd/DgwfK/GBvhb24NqFVLrDkCsJGexdgYj/RGR8mIWqIZEjoE7q7udzmaiuPq6or4+HjEx8fD9Y5b35UqVcLUqVMxefJkfP311zh58iRiY2OxcOFCfP311wCAsWPH4uTJk5gyZQqOHj2Kb7/9FsuXLy/xmt27d8f+/fvxzTff4Pjx45g1axb+/fdfW73EcmMyohHjxolGetevA1Onyo5GR2JjRWO8ChWA7vzLjXRATUbi4zU9o0aTJRod8/X1ha+vb5E/e/PNNzFz5kzMnTsXYWFh6N27NzZu3Ijg22OK6tatizVr1mDjxo1o0aIFlixZgnfeeafE6/Xu3Ruvv/46Xn75ZbRp0wZpaWkYMWKE1V+XtRiUshSj7Cw1NRV+fn64ceNGsf8xy2L4cOC774D584EXXrDaacts/34x5EFRRCO9bt1kR6QDs2YBc+YADz4ImMzlJ9KsvDwx5iErCzhxAmjYUHZERdp6ait6/bcXqnlXQ/LUZLi52H+IYWZmJuLj4xEWFoYKZRg8Svah/nc6ffo0Tpw4gaFDh6JBgwYASv/vN++MaEjr1qKBHsBGeqXGKb2kN66uQGio2NZwqUYt0TwU9pCURIScC5MRjXn7bSAgADh6FPjgA9nRaNzZs2yMR/qk8XEjOXk5WBsv7jQ+0lQDC52Rw2MyojGVK5s30jt1Smo42qYOXO3YkY3xSF/Cw8VXjSYjMWdicOXmFfhX8EfX+l1lh0NOgMmIBj36KNCjB3DrFjB+PBvpFYslGtIr02XhNYglGrI3JiMaZDAAixYVNNJbs0Z2RBpk2hiPq66S3pjOqMnLkxvLHXLycrD2iCjRcBYN2QuTEY1q0kT0rgHETJ+0NLnxaM5PP4nGeGFhQOPGsqMhskyDBqIfxK1bwOnTsqMx89vp33D15lXUqFgDnet1lh0OOQkmIxo2fbqY9cdGekVgiYb0TMMzaliiIRmYjGiY2kgPAD75RKzvRTBvjMdkhPRKgzNqsvOyse7IOgAs0ZB9MRnRuN69gaFDxUKNzz2n6QUb7Wf7diA1VcyBZmM80isNJiO/nvoV125dQ0DFAHSq20l2OOREmIzowEcfAZUqAb//zkZ6ANgYjxyDBpORVXEFJRpXF7YPt7Xly5ejcuXKFj1n1KhRGDx4sE3ikYm/yXXAtJHetGlASorceKRiYzxyFGoycuSIJmbUZOdlY/2R9QBYorGG4pKGmJgYGAwGXL9+HcOGDcOxY8fsH5wGMRnRiXHjgHvvZSM9xMYCiYmiMV6PHrKjISq74GDA21v0fTh5UnY02HpqK67fuo6aPjVxf937ZYfjFLy9vVGjRg3ZYWgCkxGdcHMDliwRa5D897/Atm2yI5JEvSvSu7f4RU6kVy4uYmo6oIlSjTqL5uGwhzVdolEUBRnZGVIe1u4rW1SZ5q233kKNGjVQqVIljBkzBtOmTUPLli0LPfeDDz5AYGAgqlWrhvHjxyMnJ8eqsdkb523pSJs2wNixwOLF4k7J33+LhdGcijpehAudkSNo2hT46y+RjDz4oLQwsnKzdFOiyczJhM9cHynXTp+ejooeFW12/hUrVuDtt9/GokWL0LFjR3z//ff48MMPERwcbHbctm3bEBgYiG3btuHEiRMYNmwYWrZsiaefftpmsdka74zozDvvADVqiDKz0zXSO3sWOHhQ/EU5YIDsaIjKTyODWKNPReNG1g0E+gSiY92OUmNxJJs2bYKPj4/Zo2/fvsUe/+mnn2L06NF48skn0aRJE8ycORP33HNPoeOqVKmCBQsWIDQ0FAMGDED//v3x66+/2vKl2BzvjOiM2kjv8ceBN98E/vMfsZijU2BjPHI0GklG1BLNI+GPwMWg7b9RK7hXQPr0dGnXtkS3bt2wePFis32///47Hn/88SKPP3r0KMaNG2e2r23btvjtt9/M9jVt2hSurgWltMDAQPzzzz8WxaY1TEZ0aPhwYNky4LffgOefBzZvFmNJHJ6ajLBEQ45CTUaOHhXtDdzs/yv5Vu4t/HhUlD+1XqIBAIPBYNNSiTVVrFgRjRo1Mtt37ty5Ep9juOOXeVHjVNzd3Qs9J1/ni1BpOwWmIpk20vvpJ2DtWtkR2cH160BMjNjmlF5yFPXqiZlh2dnAiRNSQthycgtSs1JRu1JttA9qLyUGEkJCQvDHH3+Y7du/f7+kaOyLyYhOhYQAr7witp2ikR4b45EjcnEBwsPFtqRSjXEWTfjDmi/ROLoJEyZg6dKl+Prrr3H8+HG89dZbOHToUKG7JY6Inzwdmz5djBc5fx6YNUt2NDbGxnjkqCSOG7mVewsbjorypx5KNI7usccew/Tp0zF16lTce++9OH36NEaNGgUvLy/Zodkcx4zomLe3aKTXt69opDdiBFDEdHT9M22Mx/Ei5Ggk3hn55cQvSMtOQx3fOmhXp53dr+/Ili9fXuT+rl27GseBjBo1CqNGjTL7+euvv47XX3/d+H2vXr3Mxp0Udd758+eXN1zpeGdE5/r0AR55RKwm7bCN9Ewb4913n+xoiKxLvTMSF2f3S6u9aPQwi8YZZGZmYt68eTh8+DCOHDmCWbNmYevWrRg5cqTs0GyOnz4HoDbS27cP+PJL2dHYABvjkSMznVFjx1U0b+bcZIlGYwwGA6KiotCpUydERERg48aNWLNmDXr27Ck7NJtjmcYB1K4t1hyZNEk00hs8WCyM5hDYGI8cXd26QMWKQEaGmFGjLhFvYz+f+Bnp2emo61cX99XmHUct8Pb2xtatW2WHIQX/zHQQ48cDrVoB164BL70kOxorOniQjfHIsUmaUWNaonGG2RqkbUxGHIRpI71vvilYkkP31BJNZCQb45HjsvOMmsycTGw8uhGAPko0el/Qy9FZ478PkxEH0rYt8OyzYnvcODEJRfc4pZecgZ2TkZ+O/4SMnAzU86uHNrXa2OWaZeFxuxNoerqc5d+pdNT/PuXpHMwxIw7mnXfEiqzx8cCHH4q1SHQrIaGgMV7//rKjIbIdOycjeinRuLm5wd/fH+fPnwcA+Pj4wIWD2DUjPz8f6enpOH/+PK5fv468vDwAhZe0Lw0mIw6mShWRhDzxBDBnjmikd0f3af1QB6526ABUry43FiJbUpORY8fELc3bdwRsITMnE5uObQKgjxJN3bp1AcCYkJD2XL9+HRcvXkRmZiY8PDzgXYaSOpMRB/TYY6KR3rZtopHepk06baTHEg05i6AgMT8/LQ04frwgObGBqONRyMzJRP3K9dG6VmubXcdaDAYD6tWrh6pVq2Lbtm04e/YsfHx8zLrWUvnEnInBxYyLaF+nPer61S318xRFQXZ2NvLy8pCTk4P09HS0bNkS1apVszgGJiMOSG2k17w5EBUFrFsHDBkiOyoLsTEeORODQcyo+f13UaqxYTKi9qIZGj5U0yWaO1WqVAk9evTA1q1bceHCBWNJgMov6UoSLqRewBWfK6hsqFymc3h4eCAiIgLdunUr1FW4NJiMOKjQUNFI7623RCO9Xr3EH1668fPPojFeaCgb45FzaNq0IBmxkYzsDF2VaO5UsWJFPPDAA8jJyUFubq7scBzGuu/W4fCZw5jabyoeDn+4TOfw8PAo190qJiMO7NVXgW+/BU6dAmbPFmNJdIMlGnI2dhjEuvn4ZtzMvYkGVRrg3sB7bXYdW3N3dy/TX99UDDcgzzUP7p7uZRrvYQ0cluzA1EZ6APDxx8Dff8uNp9Sys0V9CWAyQs7DDsmIXks05PjKlIwsWrQIwcHB8PLyQkREBHbu3Fni8StWrECLFi1QoUIFBAYG4sknn8SVK1fKFDBZpk8f4OGHddZIb8cO0RivRg02xiPnoSYjx48DWVlWP316djo2H98MQJ8lGnJsFicjK1euxKRJkzBjxgzExsaiU6dO6Nu3LxISEoo8fteuXRgxYgRGjx6Nw4cP44cffsCff/6JMWPGlDt4Kp358wEfH2DvXmDpUtnRlAIb45Ezql0b8PUVfzkcO2b10286tgm3cm+hUdVGaFmzpdXPT1QeFv+mnzdvHkaPHo0xY8YgLCwM8+fPR1BQEBYvXlzk8fv27UP9+vUxceJEBAcH4/7778ezzz6L/fv3lzt4Kh21kR4gBrVeuiQ3nhIpCseLkHMyGGxaqlFLNFpf6Iyck0XJSHZ2Ng4cOIDIyEiz/ZGRkdizZ0+Rz+nQoQPOnTuHqKgoKIqCixcvYvXq1ehfwoqaWVlZSE1NNXtQ+Tz/PNCypQ4a6Zk2xnOCttlEZmyUjKRlpSHquBiHxRINaZFFycjly5eRl5eHgIAAs/0BAQFITk4u8jkdOnTAihUrMGzYMHh4eKBmzZqoXLkyPv3002KvM3fuXPj5+RkfQUFBloRJRTBtpPf118D27bIjKoa66iob45EzUrv3xsVZ9bSbjm1CVl4WGldtjBYBLax6biJrKFNB/s5bfIqiFHvbLy4uDhMnTsTMmTNx4MAB/Pzzzzh9+jTGjh1b7PmnT5+OGzduGB+JiYllCZPucN99wDPPiO3nntNoIz21RDNokNw4iGSw0Z0RtRfN0KacRUPaZNE6I/7+/nB1dS10FyQlJaXQ3RLV3Llz0bFjR7x0uzbQvHlzVKxYEZ06dcJbb72FwMDAQs/x9PSEp6enJaFRKc2dW9BIb948YNo02RGZSEgAYmPFoNUBA2RHQ2R/ajJy4oSYUWOF34OpWan46fhPAFiiIe2y6M6IutxrdHS02f7o6Gh06NChyOdkZmYW6rKortKmKIollycrUBvpAaKR3unTcuMxw8Z45Oxq1QL8/MSMmqNHrXLKjUc3IisvCyHVQnBPjXusck4ia7O4TDNlyhR8+eWXWLZsGeLj4zF58mQkJCQYyy7Tp0/HiBEjjMcPHDgQa9euxeLFi3Hq1Cns3r0bEydORNu2bVGrVi3rvRIqtccfB7p2BW7eBCZMEBNYNEFNRliiIWdlgxk1LNGQHli8HPywYcNw5coVzJkzB0lJSWjWrBmioqJQr149AEBSUpLZmiOjRo1CWloaFixYgBdffBGVK1dG9+7d8e6771rvVZBFDAZg8WLRSG/zZmD9euDBByUHdeMGG+MRASIZ2bPHKsnIjVs38POJnwGwREPaVqbeNOPGjcO4ceOK/Nny5csL7ZswYQImTJhQlkuRjYSGAi+/DLz9NjBxomik5+MjMaCffgJyckRgTZpIDIRIMiveGdlwdAOy87IR5h+GptVt1wmYqLy4vKUTmzEDCA4Gzp0TjfSk4kJnRIIVkxG1RMOFzkjrmIw4MW9vYMECsT1/PnDokKRAsrPFnRGA40WI1GTk5Eng1q0yn+b6rev45cQvAFiiIe1jMuLk+vUDHnpIDN4fO1ZSI70dO8SYETbGIwJq1hTT3vLzgSNHynyaDUc3ICc/B+HVw9G0Bks0pG1MRsiskd6yZRICMG2Md3vaN5HTstKMGrUXzdBw3hUh7WMyQqhTR6w5AkhopKcoBVN6OV6ESChnMnLt5jVsObkFAPBI00esFRWRzTAZIQBivZEWLYCrV8UsG7v5+2+x8qq3N9Cjhx0vTKRh5UxGfjz6I3Lyc9CsRjOEVw+3YmBEtsFkhACYN9JbvlwM47ALtUQTGSk69RJRuZMRlmhIb5iMkFG7dsDTT4ttuzXS45ReosLUZOTUKSAz06KnXr15FdGnRMsOlmhIL5iMkJm5c0VbmLg44KOPbHyxxETRGM9gAPr3t/HFiHSkRg2gWjUxpsrCGTXrj6xHbn4umgc0R6h/qI0CJLIuJiNkpmpV4IMPxPYbbwBnztjwYqaN8WrUsOGFiHSmHDNq1BLNI+G8K0L6wWSECnniCaBLFzs00mOJhqh4ZUhGrmRewdZTWwEwGSF9YTJChaiN9NzdgU2bCnIGq2JjPKKShd+eBRMXV+qnrD+yHnlKHloEtECIf4iNAiOyPiYjVKSwMOCll8T2xIlAerqVL/Dzz6IxXkgIG+MRFaUMd0bUXjRc/p30hskIFWvGDKB+fTHO9I03rHxylmiISqYmI6dPl2pGzeXMy/j11K8AWKIh/WEyQsWqUAFYuFBsf/QR8M8/VjpxTg4QFSW2mYwQFa1GDcDfXwzaio+/6+Hr4tchT8lDq5qt0LhaYzsESGQ9TEaoRP36AUOGWLmRHhvjEZWOBaUalmhIz5iM0F19/LFopLdnD/DVV1Y4oVqiGTCAjfGISlLKZORSxiX8dvo3ACzRkD4xGaG7qlOnYMzIyy8Dly+X42SKwvEiRKVVymRkbfxa5Cv5iAiMQMOqDe0QGJF1MRmhUpk4EWje3AqN9Ewb4/XsabX4iBxSKZMRtUTDuyKkV0xGqFTURnqAKNXs3FnGE6mrrrIxHtHdqcnImTPFzq9PyUhBzJkYAOxFQ/rFZIRKrX1780Z6OTllOIlaohk0yGpxETksf/+CVgnFzKhRSzSta7VGgyoN7BgckfUwGSGL/N//id+Phw+XoZFeYiLw119iidcBA2wSH5HDuUupRu1FMzScs2hIv5iMkEXubKR39qwFT2ZjPCLLlZCMJKcnY/vZ7QBYoiF9YzJCFhsxQjTSy8wUA1tLTU1GWKIhKr0SkhG1RNO2dlvUr1zfvnERWRGTEbKYwQAsWiQGtW7YUMpGejduANu2iW1O6SUqvRKSEZZoyFEwGaEyCQ8vaKQ3YUIpGumZNsYLYTdRolJTk5GEBCAtzbg7KS0JO87uAAA8HP6wjMiIrIbJCJXZa68VNNKbM+cuB3OhM6KyqVoVqFlTbMfFGXeviV8DBQra1WmHepXrSQqOyDqYjFCZVagALFggtktspGfaGI/jRYgsV0SpRi3RcKEzcgRMRqhc+vcHHnwQyM0Va48U2UhPbYxXvTrQrp3dYyTSPTUZuX1n5ELaBexK2AWAJRpyDExGqNw+/hioWBHYvRtYvryIA9QSzcCBbIxHVBbh4eLr7Tsja+JEiaZ9nfao61dXYmBE1sFkhMotKKigkd5LL93RSE9RCqb0crwIUdncUaZRe9EMbcpZNOQYmIyQVUycCNxzj2ik98orJj84dEisjMbGeERlpyYjiYk4f+EISzTkcJiMkFW4uxc00lu2DNi16/YP1BJNr15sjEdUVlWqAIGBAIDVOz8DAHQM6og6vnVkRkVkNUxGyGo6dADGjBHbxkZ6nNJLZB23746sOrURAEs05FiYjJBVqY30/v0X+HL2uYLGeP37yw6NSN+aNkWiL7An+yQMMOChsIdkR0RkNUxGyKqqVQPef19sH33/9sDV9u2BgAB5QRE5gqZNsfr2pJqOdTuitm9tufEQWRGTEbK6kSOBzp2Bvjks0RBZTdOmWHV7HCt70ZCjYTJCVmcwAEvevYFuEI3xfvVhMkJUXgl1KmFfEGBQgIdqc2YaORYmI2QTYQm/wAM5OIomeOrdEGRkyI6ISN9Wn48GAHQ6C9RKuCY5GiLrYjJCtnF7Fs023weQkFCKRnpEVCK1F83QwzDrUUPkCJiMkPWZNMa7Z4Yo0cybJ2bYEJHlzlw/g9/P/y5KNPFgMkIOh8kIWd/OncD160D16uj4YjsMHnyXRnpEVKLVcasBAF28QlAzHUxGyOEwGSHrUxc6GzAAcHXFxx+LxVd37QK+/lpuaER6ZCzRNBgkdjAZIQfDZISsS1EKrbpat655I70rVyTFRqRDp6+dxp8X/oSLwQVDOj0jdiYlAdc4iJUcB5MRsi7Txni9ehl3v/AC0KyZSETMGukRUYl+iPsBANClXhcEBDYSbbIB3h0hh8JkhKxrw+1VV+9ojGfaSG/pUmD3bgmxEemQsUSj9qJRO/gyGSEHwmSErEst0QwaVOhHHTsCo0eL7bFjbzfSI6Jinbp2CgeSDogSTdgQsVNNRuLi5AVGZGVMRsh6zp0DDhwQS7AOGFDkIe++K/rX/Psv8PHHdo6PSGd+OCxKNN3qd0ONijXEzvDbDWp4Z4QcCJMRsp4Nd2+MZ9pIb9YsICHBTrER6dCquDtKNADLNOSQmIyQ9ajJSBElGlMjRwKdOgGZmWJgKxEVduLqCfyV9BdcDa54MPTBgh+od0aSk4GrV+UER2RlTEbIOlJTgd9+E9t36dLr4gIsXgy4uQHr1wMbN9o+PCK9UUs03YO7o3rF6gU/qFRJzJcHeHeEHAaTEbKOn38WI1KbNAFCQ+96eNOmwIsviu0JE8BGekR3KLJEo2KphhwMkxGyjjsWOiuN118H6tUTy5K8+aaN4iLSoWNXjuFg8sHCJRoVkxFyMExGqPxMGuPdbbyIqYoVgU8/Fdsffsjfq0QqtUTTo0EPVKtQrfABTEbIwTAZofIzaYyH9u0teurAgeJmitpIT1FsEyKRnhhLNOFFlGgAJiPkcJiMUPnd0RjPUp98IhZr3bmTjfSIjl4+ikMXD8HNxQ2DQwcXfVBYmPiakgJcvmy32IhspUzJyKJFixAcHAwvLy9ERERg586dJR6flZWFGTNmoF69evD09ETDhg2xbNmyMgVMGqMoBVN6LRgvYqpuXWD2bLE9dSob6ZFzU3vR9GzQs+gSDQD4+AD164tt3h0hB2BxMrJy5UpMmjQJM2bMQGxsLDp16oS+ffsioYTVq4YOHYpff/0VS5cuxdGjR/Hdd98htBQzLkgH/vkHOHMG8PICevYs82kmTSpopDdtmtWiI9IdYy+a4ko0KpZqyIFYnIzMmzcPo0ePxpgxYxAWFob58+cjKCgIixcvLvL4n3/+Gdu3b0dUVBR69uyJ+vXro23btujQoUO5gycNUEs0vXqJEall5O4u1h4BgC+/BPbssUJsRDoTfyke/6T8A3cX9+JLNComI+RALEpGsrOzceDAAURGRprtj4yMxJ5i/vXYsGEDWrdujffeew+1a9dGkyZNMHXqVNy8ebPY62RlZSE1NdXsQRpVhim9xbn/fuCpp8Q2G+mRM1JLNL0a9kIV7yolH8xkhByIRcnI5cuXkZeXh4A7+o4EBAQgOTm5yOecOnUKu3btwr///ot169Zh/vz5WL16NcaPH1/sdebOnQs/Pz/jIygoyJIwyV5K0RjPUmojvX/+EQNbiZxJqUs0AJMRcihlGsBqMBjMvlcUpdA+VX5+PgwGA1asWIG2bduiX79+mDdvHpYvX17s3ZHp06fjxo0bxkdiYmJZwiRbU9dxb9eu2MZ4lvL3B957T2zPmgXwPz05i8Mph3H40mG4u7jjgdBS3GkMCxN/CFy+LGbVEOmYRcmIv78/XF1dC90FSUlJKXS3RBUYGIjatWvDz8/PuC8sLAyKouDcuXNFPsfT0xO+vr5mD9IgK5ZoTI0aJUo2GRlspEfOQy3RRDaMRGWvynd/QoUKQHCw2ObdEdI5i5IRDw8PREREIDo62mx/dHR0sQNSO3bsiAsXLiA9Pd2479ixY3BxcUGdOnXKEDJpggWN8Sxl2khv3Tpg0yarnp5Ik4wlmqJ60RSHpRpyEBaXaaZMmYIvv/wSy5YtQ3x8PCZPnoyEhASMHTsWgCixjBgxwnj88OHDUa1aNTz55JOIi4vDjh078NJLL+Gpp56Ct7e39V4J2dcvv4gRpo0bAyEhVj99s2bAlCli+/nngcxMq1+CSDMOpxxG/OV4eLh6YFBI6VsqGJORuDjbBEZkJxYnI8OGDcP8+fMxZ84ctGzZEjt27EBUVBTq1asHAEhKSjJbc8THxwfR0dG4fv06WrdujcceewwDBw7EJxydqG+mJZpixguV18yZYkE0NtIjR6feFendsHfpSjSq8HDxlXdGSOfcyvKkcePGYdy4cUX+bPny5YX2hYaGFirtkI7l5ACbN4ttK5doTKmN9B54APjgA+Dxxwv+ECRyFIqiFPSisaREA5iXaRTFZn8YENkae9OQ5XbtEo3x/P0tboxnqUGDxCM3Fxg3jo30yPH8m/Ivjlw+Ak9XT8tKNAAQGioSkCtXOKOGdI3JCFmunI3xLKU20tuxA/jmG5tfjsiu1BJNn0Z94Otp4czBChWABg3ENks1pGNMRsgyimKzKb3FqVdPrDkCsJEeOZZylWhUnFFDDoDJCFnGtDFer152u+zkyeJ37uXLwPTpdrsskU0dungIx64cg6erJwY2GVi2kzAZIQfAZIQss2GD+NqzZ7ka41nKtJHeF1+wkR45BrVE07dxX1TyrFS2kzAZIQfAZIQsY+cSjalOnYAnnxTbzz0nBrUS6ZVZiaY0vWiKc+eMGiIdYjJCpXf+PLB/vxi9P7CMt5TL6b33gKpVgUOH2EiP9O3vi3/jxNUT8HLzwoAm5Wg0GRoqli2+dg0opmEpkdYxGaHSU0s0VmyMZynTRnozZ7KRHumXWqLp17hf2Us0gBi/1bCh2GaphnSKyQiVnpqMDLJwLQQre/JJoGNH0Uhv0iSpoRCViaIoBb1oylOiUXHcCOkckxEqnbQ0mzXGs5TaSM/VFVi7tmAxWCK9iE2OxclrJ+Ht5o3+TfqX/4RMRkjnmIxQ6fz8M5CdLRrjhYbKjgb33MNGeqRf6l2R/k36w8fDp/wnZDJCOsdkhErHDo3xLDVzJhAUJJY9eest2dEQlY7VSzQAZ9SQ7jEZobszbYwnebyIKR8f0UgPEI302EWd9OBA0gGcvn4aFdwroF/jftY5aUiIqFveuAFcuGCdcxLZEZMRujvTxngdOsiOxswDD4hZxjk5bKRH+mAs0TTuj4oeVlo40NMTaNRIbLNUQzrEZITuzs6N8Sz1ySeAtzewfTvw3//KjoaoeIqi4Ie4HwCUoxdNcdRSDW8Rkg4xGaGSKUrBlF7Js2iKU79+QSO9F18Erl6VGg5RsfZf2I8z189Yt0Sj4iBW0jEmI1Syf/8FTp+2e2M8S02eDISHs5EeaZtaohnYZCAquFew7snDw8VXJiOkQ0xGqGRqicbOjfEs5eFR0Ejv88+BvXvlxkN0J7NeNNYu0QCcUUO6xmSESiaxMZ6lOncGRo0S22ykR1rzx/k/kHAjARXdK6Jvo77Wv0CTJmJMV2qq6CNFpCNMRqh4po3xBpSjkZcdqY30/v67YNovkRaoJZpBIYPg7e5t/Qt4eopFCQGWakh3mIxQ8TZuFF/vuw+oWVNuLKVUvTrw7rtie+ZM4Nw5ufEQAUC+km+7WTSmOIiVdIrJCBVPRyUaU089JZZDSU9nIz3Sht/P/Y7E1ET4ePigT6M+trsQkxHSKSYjVDQNNcazlGkjvTVrgKgo2RGRszMt0Xi5ednuQkxGSKeYjFDRfvlFNMZr1EgTjfEs1by5mO4LsJEeyZWv5GN1/GoAVuxFUxzThc84o4Z0hMkIFU2DjfEsNWuWaKR3+jTw9tuyoyFnte/cPpxLPYdKHpXQu1Fv216scWPAzU3c2UxMtO21iKyIyQgVZtoYT2clGlM+PsDHH4vt998H4uPlxkPOSS3RPBD6gG1LNIBYcKdJE7HNUg3pCJMRKmz3buDaNaBaNc01xrPU4MFiVjIb6ZEMZrNobF2iUXHcCOkQkxEqTOON8SxhMIj1Rry9gZgY4H//kx0ROZM9iXtwIe0CfD19Edkw0j4XZTJCOsRkhMwpim6n9Banfn2x5gjARnpkX2qJZnDoYHi6edrnokxGSIeYjJA5tTGepycQaae/5OxgyhTRR+zSJeDVV2VHQ84gLz8Pq+PsNIvGlOmMmvx8+12XqByYjJC5DRvEV403xrPUnY309u2TGw85vt2Ju5GUngQ/Tz/0amjHjteNGgHu7kBGBpCQYL/rEpUDkxEy52AlGlOdOwMjR4pK1NixbKRHtmVaovFw9bDfhd3dgZAQsc1SDekEkxEqcOEC8OefYtTnwIGyo7GJ998HqlQRjfQWLJAdDTmqvPw8rIlfA8DGvWiKY1qqIdIBJiNUQC3R6KgxnqVMG+m9/job6ZFt7ErYheT0ZFT2qoyeDXraP4DwcPGVd0ZIJ5iMUAE1GRk0SG4cNjZ6NNC+vWikpy4ZT2RNaonmwdAH7VuiUXFGDekMkxES0tKAX38V2w44XsSUiwuwZIlYQmX1auCnn2RHRI4kLz+voBeNjBINwBk1pDtMRkgwbYwXFiY7Gptr3hyYNElsjx8P3LwpNRxyIDvO7kBKRgqqeFVBj+AecoJo1EhMIcvMBM6elRMDkQWYjJDgAI3xLDV7NlCnDhvpkXWpJZohYUPg7uouJwg3N86oIV1hMkJijqvaGM/Bx4uYMm2k9957wJEjcuMh/cvNz5U7i8YUx42QjjAZIWDXLodpjGepBx8E+vcXjfSee46N9Kh8tp/ZjkuZl1DNuxq61e8mNxgmI6QjTEbIvDGem5vcWOzszkZ6K1bIjoj0zHQWjbQSjYrJCOkIkxFn54CN8SwVHCzWHAFED5tr1+TGQ/qUm5+LtUfWAtBAiQYoSEbi4zmjhjSPyYizO3y4oDFeLzv2z9CYF18Uk4jYSI/KKuZMDC5nXhYlmmDJJRoAaNhQ/H9986b4f5xIw5iMODv1rkjPnmJEp5MybaT32WfA77/LjYf0Ry3RPBT2ENxcNFDudHUFQkPFNks1pHFMRpydk5doTHXpAowYwUZ6ZLmcvBysjddQiUbFcSOkE0xGnJnaGA8Qg1fJ2Ejv4EFg4ULZ0ZBebDuzDVduXkH1CtXRpX4X2eEUYDJCOsFkxJlt3Ci+3ncfEBgoNxaNqFED+L//E9uvvQacPy83HtIHzZVoVExGSCeYjDgzlmiKNGYM0K4dG+lR6Wi2RAMUJCNHjgB5eXJjISoBkxFn5USN8Sxl2kjvhx+An3+WHRFp2a+nf8W1W9dQo2INdK7XWXY45oKDAS8v4NYt4NQp2dEQFYvJiLPaskU0xmvY0Cka41mqRQvghRfENhvpUUlMSzSuLq6So7mDq2vB/99xcXJjISoBkxFn5YSN8Sw1ezZQu7b4g/Kdd2RHQ1qUnZeN9UfWA9BgiUbFcSOkA0xGnJFpYzyWaIpVqVJBI71332UjPSrs11OiRBNQMQCd6naSHU7RwsPFVyYjpGFMRpzR7t3A1atO2RjPUkOGAP36iUZ648axkR6ZWxUnSjQPhz+svRKNindGSAeYjDgjtUTTv7/TNcazlNpIz8sL2LYN+PZb2RGRVmTnZWNd/DoAGi7RAJxRQ7rAZMTZsDGexRo0YCM9Kiz6ZDRuZN1AoE8gOgZ1lB1O8YKDRVvqrCzg5EnZ0RAVicmIszl8WIzI9PQEIiNlR6MbU6eKNh8pKcCMGbKjIS3QRYkGEHPV1Rk1LNWQRpUpGVm0aBGCg4Ph5eWFiIgI7Ny5s1TP2717N9zc3NCyZcuyXJasYcMG8bVHD6dujGcp00Z6S5YAf/whNx6SKys3S/uzaExx3AhpnMXJyMqVKzFp0iTMmDEDsbGx6NSpE/r27YuEhIQSn3fjxg2MGDECPXr0KHOwZAUs0ZRZ167AE0+wkR4BW05uQWpWKmpVqoUOQToYBM5khDTO4mRk3rx5GD16NMaMGYOwsDDMnz8fQUFBWKz+2ViMZ599FsOHD0f79u3LHCyV04ULBX/SDxwoNxad+uADoHJlIDYWWLRIdjQki7FEE/YwXAw6qHYzGSGNs+j/ouzsbBw4cACRd4w1iIyMxJ49e4p93ldffYWTJ09i1qxZpbpOVlYWUlNTzR5kBWyMV253NtK7cEFuPGR/t3JvYcNRUe7URYkGKEhGjh7lLT3SJIuSkcuXLyMvLw8BAQFm+wMCApCcnFzkc44fP45p06ZhxYoVcCvlNNK5c+fCz8/P+AgKCrIkTCqOOl5k0CC5cejc00+LRnppaWyk54zUEk3tSrXRPkgnd3rr1QMqVBAtIE6ckB0NUSFlur9ouGP5cEVRCu0DgLy8PAwfPhxvvPEGmjRpUurzT58+HTdu3DA+EhMTyxImmUpPZ2M8K3FxEYNZXVyAVauAX36RHRHZk9qL5pHwR/RRogHEh5UrsZKGWfR/kr+/P1xdXQvdBUlJSSl0twQA0tLSsH//fjz//PNwc3ODm5sb5syZg7///htubm747bffiryOp6cnfH19zR5UTr/8ItYZaNiw4JcSlVnLlsDEiWKbjfScx82cm/jxqBgErpsSjYrjRkjDLEpGPDw8EBERgejoaLP90dHR6FDEsuK+vr74559/cPDgQeNj7NixCAkJwcGDB3HfffeVL3oqPTbGs7o5c0QjvZMngblzZUdD9vDLyV+Qnp2OIN8g3FdHZ7+/mIyQhlm8FviUKVPwxBNPoHXr1mjfvj0+//xzJCQkYOzYsQBEieX8+fP45ptv4OLigmbNmpk9v0aNGvDy8iq0n2zItDEex4tYTaVKwPz5wCOPiEZ6jz0GhITIjopsSZclGhWTEdIwi5ORYcOG4cqVK5gzZw6SkpLQrFkzREVFoV69egCApKSku645QnamNsarWhXoqOFlq3XooYeAvn2Bn34SjfS2buWNJ0d1M+em/mbRmFKTkWPHROdHd3e58RCZKFNqP27cOJw5cwZZWVk4cOAAOnfubPzZ8uXLERMTU+xzZ8+ejYMHD5blslRWaolmwAA2xrMygwFYsEA00vvtN+C772RHRLby04mfkJGTgbp+ddG2dlvZ4Viubl2x6nJODnD8uOxoiMzo7D4jWUxRCqb0chaNTTRoINYcAcRU3+vXpYZDNmJaoilq9qDmGQwFg9fj4uTGQnQHJiOOLi5OjLBkYzybmjpVjBdhIz3HlJmTiU3HNgHQaYlGxXEjpFFMRhydWqJhYzyb8vQsaKS3eDEb6Tman46LEk09v3poU6uN7HDKjmuNkEYxGXF0bIxnN926AY8/Lipjzz0H5OXJjoisRe1FM7TpUH2WaFS8M0IaxWTEkSUlFfyJPmCA3FichNpI76+/2EjPUWRkZzhGiQYwn1GTnS03FiITTEYcmdoYr21boFYtubE4iYCAggXQZsxgIz1HEHU8Cpk5mQiuHIyIwAjZ4ZRPUJBYICc3lzNqSFOYjDgylmikeOYZ0Rg5LQ2YMkV2NFReDlOiAcxn1LBUQxrCZMRRsTGeNKaN9FauBLZskR0RlVV6djo2HxOrF+u+RKPiuBHSICYjjmrLFtEYr0EDNsaToFUrYMIEsT1uHBvp6dXmY5txM/cmGlRpgFY1W8kOxzqYjJAGMRlxVGyMJ92cOWKozsmTwP/9n+xoqCyMJZpwByjRqJiMkAYxGXFEubnAJjH6nyUaeXx9RSM9QCQjx45JDYcslJ6djqjjUQAcqEQDFCQjx4+Lu6dEGsBkxBHt2cPGeBrx8MNAnz5iFuW4cWINEtKHTcc24VbuLTSq2ggta7aUHY711K4tMuW8PGbIpBlMRhyRWqLp35+N8SQzbaT366/A99/LjohKS+1F41AlGkB8KFmqIY1hMuJoFIVTejWmYcOCfjVspKcPaVlpjlmiUTEZIY1hMuJo1MZ4Hh5A796yo6HbXnpJNNK7eLGgwy9p18ZjG5GVl4Um1ZqgeUBz2eFYH5MR0hgmI45mwwbxlY3xNMXTs2B5+EWLgD//lBsPlcxhSzQqJiOkMUxGHA1LNJrVvTvw2GNspKd1qVmp+OnETwActEQDFCQjJ04At27JjYUITEYcS1IS8PvvYnvgQLmxUJE+/BDw8wMOHBCrtJL2bDi6Adl52QipFoJmNZrJDsc2AgNFR8f8fODoUdnREDEZcShsjKd5dzbSS0qSGw8V9kPcDwAcpBdNcUxn1MTFyY2FCExGHIs6XmTQILlxUImeeUbki6mpbKSnNTdu3cDPJ34G4MAlGhXHjZCGMBlxFOnpwNatYpvjRTTN1RVYskQ00vv+eyA6WnZEpFJLNGH+YWhavanscGyL3XtJQ5iMOArTxnhNHfyXqANo1Qp4/nmxPW4cxxBqhbEXjSOXaFS8M0IawmTEUbAxnu68+aYYR3jiBBvpacH1W9fxy4lfAACPhD8iORo7UJORkyeZDZN0TEYcQW4usHmz2OZ4Ed0wbaQ3d67oW0by/HjkR+Tk56Bp9aZoWsMJ7i7WrAlUqSJm1Bw5IjsacnJMRhzBnj3AlSuiMd7998uOhizwyCNioVw20pPPtETjFNijhjSEyYgjYGM83VIb6Xl6ivHHK1fKjsg5Xbt5DVtObgHgJCUaFZMR0ggmI3pn2hiPJRpdatTIvJHejRty43FG64+sR25+LprVaIaw6mGyw7EfJiOkEUxG9C4+no3xHMDLLwNNmgDJyWykJ4NxobNwJynRqJiMkEYwGdE79a5Ijx5ApUpyY6EyM22kt3AhsH+/3HicydWbVxF9Siz28khTJyrRAAXJyKlTQGam3FjIqTEZ0Ts2xnMYPXoAw4eLytvYsWykZy9qiaZ5QHOE+ofKDse+atQAqlUTHzrOqCGJmIzoWXIyG+M5GNNGekuWyI7GOaw6fHsWjbOVaADOqCHNYDKiZ2pjvDZt2BjPQdSsCbzzjth+9VU20rO1K5lXsPWUaKPgdCUaFZMR0gAmI3rGEo1DevZZkV+mpgIvvig7Gse27sg65Cl5aFmzJZpUayI7HDmYjJAGMBnRKzbGc1imjfS++46N9GzJqUs0KiYjpAFMRvQqOlo0xgsOZmM8B3TvvcD48WJ7/Hi2DrGFSxmX8Nvp3wA4cYkGKPj9cfo0kJEhNxZyWkxG9IqN8Rye2kjv+HHg3XdlR+N41BJNq5qt0KhqI9nhyFO9ungAnFFD0jAZ0aPcXGDTJrHNEo3D8vMDPvpIbLORnvUZFzpzll40JWGphiRjMqJHe/eKxnhVqrAxnoMbOhSIjBQVufHj2UjPWsxKNM7Ui6Y4TEZIMiYjesTGeE7DYBArsnp6imFCq1bJjsgxrI1fi3wlHxGBEWhYtaHscOQLDxdfmYyQJExG9Ma0MR5LNE6hUSOx5ggATJrERnrWsCru9iwalmgE3hkhyZiM6E18PHDiBBvjOZlXXgEaNxaL7r7+uuxo9O1i+kXEnIkBwBKNkZqMnDkjlg0gsjMmI3qzYYP42r07G+M5kTsb6R04IDcePVNLNG1qtUFwlWDZ4WiDv7/oUwOIP3iI7IzJiN6wROO0evYEHn0UyM9nI73yYImmGCzVkERMRvTEtDHeoEFyYyEp5s0TU3737wc++0x2NPqTnJ6M7We2A2CJphAmIyQRkxE92bhRDGBlYzynVbMm8PbbYnv6dJGfUumtiVsDBQra1m6LepXryQ5HW5iMkERMRvREHS/CuyJObexYoHVrNtIrC+NCZ87ci6Y4TEZIIiYjepGRwcZ4BMC8kd633xZ8LKhkSWlJ2HF2BwDg4fCHJUejQWoykpAApKXJjYWcDpMRvdiyRXRLCw4GmjWTHQ1JFhEBjBsntseNYyO90lgTL0o07eq0Y4mmKFWrijogAMTFyY2FnA6TEb1gYzy6w1tviX87jh8H3ntPdjTat+rw7Vk0LNEUj6UakoTJiB7k5RU0xuN4EbrNtJHeO++ItfCoaOdTz2NXwi4ALNGUiMkIScJkRA/27ClojNepk+xoSEOGDQN69WIjvbtRSzQdgjogyC9IdjjaxWSEJGEyogdsjEfFMG2kt2UL8MMPsiPSJpZoSonJCEnCZETrTBvjsURDRWjcWKw5AohGeqmpUsPRnHOp57A7cTcAlmjuSk1Gzp1jR0ayKyYjWnfkSEFjvD59ZEdDGvXKK6K7b1ISG+ndaXXcagBAx6COqO1bW3I0Gle5csGCiuxRQ3bEZETr1LsibIxHJfDyKmikt2AB8NdfcuPREuNCZ+xFUzos1ZAETEa0jo3xqJR69QL+8x820jOVeCMRexL3wAADHgp7SHY4+sBkhCQoUzKyaNEiBAcHw8vLCxEREdi5c2exx65duxa9evVC9erV4evri/bt2+OXX34pc8BOxbQx3sCBcmMhXZg3D/D1Bf78E/j8c9nRyKeWaO6vez9LNKUVHi6+MhkhO7I4GVm5ciUmTZqEGTNmIDY2Fp06dULfvn2RkJBQ5PE7duxAr169EBUVhQMHDqBbt24YOHAgYmNjyx28w9u0SQxgbd0aqM1fpHR3gYFspGdqVdztWTQs0ZQe74yQBBYnI/PmzcPo0aMxZswYhIWFYf78+QgKCsLixYuLPH7+/Pl4+eWX0aZNGzRu3BjvvPMOGjdujI0bN5Y7eIfHEg2VwXPPieXib9wApk6VHY08Z6+fxb5z+1iisZR6Z+T8eeD6damhkPOwKBnJzs7GgQMHEBkZabY/MjISe/bsKdU58vPzkZaWhqpVqxZ7TFZWFlJTU80eToeN8aiM1EZ6BgOwYgXw66+yI5JDLdF0rtcZgZUCJUejI5UrF9yJZY8ashOLkpHLly8jLy8PAQEBZvsDAgKQXMr7wR9++CEyMjIwdGjxt03nzp0LPz8/4yMoyAlXTIyOFt3P6tdnYzyyWOvW5o30srLkxiMDSzTlwFIN2VmZBrAa7mjUpihKoX1F+e677zB79mysXLkSNWrUKPa46dOn48aNG8ZHYmJiWcLUNzbGo3J6+23RSO/YMedrpHfm+hn8cf4PGGDAkLAhssPRHyYjZGcWJSP+/v5wdXUtdBckJSWl0N2SO61cuRKjR4/GqlWr0LNnzxKP9fT0hK+vr9nDqZg2xmOJhsrIz0/MrgFEYuJMjfR+OCzWFulSvwtq+tSUHI0OMRkhO7MoGfHw8EBERASio6PN9kdHR6NDhw7FPu+7777DqFGj8O2336J///5li9SZ7N0LXL4sGuPdf7/saEjH/vMfoGdPUaZ5/nnnaaRnXOiMvWjKhskI2ZnFZZopU6bgyy+/xLJlyxAfH4/JkycjISEBY8eOBSBKLCNGjDAe/91332HEiBH48MMP0a5dOyQnJyM5ORk32PegeGqJpl8/wN1dbiyka2ojPQ8P4JdfgNWrZUdke6evncafF/6Ei8GFJZqyUmfUJCUB167JjYWcgsXJyLBhwzB//nzMmTMHLVu2xI4dOxAVFYV69eoBAJKSkszWHPnss8+Qm5uL8ePHIzAw0Ph44YUXrPcqHIlpYzyWaMgKmjQpaKT3wguO30hPvSvStX5XBPiUXD6mYvj6AurEAd4dITsoUz/6cePGYZw6VP8Oy5cvN/s+JiamLJdwXkeOAMePszEeWdW0aWKa74kTwMyZwPz5siOynVWHb8+iYYmmfJo2BRITRTLCcjHZGHvTaM2GDeJrt25sjEdW4+UlyjUA8OmnjttI7+TVkziQdIAlGmvguBGyIyYjWsMSDdlIZCQwbJhjN9JTSzTdg7ujesXqkqPROSYjZEdMRrTk4kVg3z6xPWiQ3FjIITl6Iz2WaKyIyQjZEZMRLdm4kY3xyKZq1QLeektsT58u8l9HcfzKccQmx8LV4IoHwx6UHY7+qTNqLl4ErlyRGws5PCYjWqKOF+FdEbKhceOAe+91vEZ6piUa/wr+kqNxAD4+wO1ZkuxRQ7bGZEQrMjJEPxqA40XIpkwb6f3vf8Bvv8mOyDqMC52xF431sFRDdsJkRCtMG+Pdc4/saMjBtWkDPPec2HaERnrHrhzDweSDokQTyhKN1TAZITthMqIVbIxHdvb220BAAHD0KPD++7KjKR+1F03PBj1RrUI1ydE4EHXcCJMRsjEmI1pg2hiP40XITipXNm+kd/Kk1HDKZVXc7Vk0LNFYF++MkJ0wGdECtTFe5cpAp06yoyEn8uijQI8eokKo10Z6Ry4fwaGLh+Dm4obBoYNlh+NYwsLE15QU8TuKyEaYjGiBWqLp35+N8ciuDAZg0SLRfeDnn4E1a2RHZDm1RNOrQS9U9a4qORoH4+MjxrEBvDtCNsVkRAs4pZckatJE9K4B9NlIjyUaG2OphuyAyYhsR44Ax46JOyJsjEeSTJ8ONGwIXLgAzJolO5rSi7sUh39T/oW7izseCOGUeJtgMkJ2wGRENrVE0727WKebSALTRnqffALExsqNp7SMJZqGvVDFu4rkaBwUkxGyAyYjsrExHmlE797A0KH6aqRnXOiMvWhsh8kI2QGTEZlMG+MNHCg3FiIAH30EVKoE/PEH8MUXsqMp2eGUwzh86bAo0YQymbeZsDAx0vnyZTGrhsgGmIzItGmTmEsZEQHUqSM7GiJdNdJT74r0btQblb0qyw3GkVWoAAQHi23eHSEbYTIiE0s0pEHjxgGtWgHXrwMvvSQ7mqIpioJVh2/PomGJxvZYqiEbYzIiCxvjkUa5uRU00vvvf4Ft22RHVNjhS4cRfzkeHq4eGBTCKfE2x2SEbIzJiCxbt4plL+vVY2M80py2bcUgVkA01NNaIz31rkifRn3g5+UnORonwGSEbIzJiCxsjEca9847QI0aopHeBx/IjqYASzQSmCYjeuwZQJrHZEQG08Z4LNGQRpk20nvrLeDUKanhGP2T8g+OXjkKT1dPDAzhLDS7CA0FXFyAq1c5o4ZsgsmIDHv3ApcusTEead7w4WI9Pi010lMXOuvTqA98PblQoF14ewMNGohtlmrIBpiMyKD2ounXj43xSNNMG+n99BOwdq3ceBRFYS8aWThuhGyIyYgMnNJLOhISArzyith+4QUgLU1eLIcuHsKxK8dEiaYJSzR2xWSEbIjJiL2xMR7p0PTp4i79+fNyG+mpA1f7Ne6HSp6V5AXijMLDxVcmI2QDTEbsTS3RdOvGxnikG97eBY30Pv4YOHjQ/jGwRCMZZ9SQDTEZsTeWaEin+vQBHnmkoJFefr59r38w+SBOXD0BLzcvDGgywL4Xp4IZNdeuAcnJsqMhB8NkxJ4uXhQzaQBgEFeNJP356CPAxwf4/Xf7N9JTSzT9G/eHj4ePfS9OgJcX0LCh2GaphqyMyYg9sTEe6Vzt2gWN9KZNs9+SEyzRaAQHsZKNMBmxJ3W8CO+KkI6NHw+0bGnfRnp/Jf2FU9dOwdvNG/0b97fPRakwJiNkI0xG7CUzk43xyCGYNtL75hsgJsb21/whTix01r9Jf1T0qGj7C1LRmIyQjTAZsZfoaODmTdEYr3lz2dEQlct99wHPPiu2n3sOyM623bXYi0ZDOKOGbITJiL2wMR45GLWR3pEjtm2kdyDpAE5fP40K7hXQr3E/212I7i4kBHB1BW7cAC5ckB0NORAmI/Zg2hiP40XIQVSpAnz4odh+803bNdJT74oMaDKAJRrZPD2BRo3ENks1ZEVMRuxh376CxnidO8uOhshqHntMrN936xYwYYL179yzRKNBHDdCNsBkxB7UEg0b45GDURvpubsDUVHAunXWPf+fF/7E2RtnUdG9Ivo27mvdk1PZMBkhG2AyYg+c0ksOLDS0oJHexInWbaSn3hUZGDIQFdwrWO/EVHZMRsgGmIzY2tGj4uHuDvTlX3bkmF59taCR3uzZ1jknSzQapSYjcXGcUUNWw2TE1tQSDRvjkQO7s5He33+X/5y/n/8diamJ8PHwQZ9G7HCtGU2aiMVmUlNF9klkBUxGbI2N8chJ9OkDPPywmDxmjUZ6PxwWC50NbDIQ3u7eVoiQrMLDA2jcWGyzVENWwmTEllJSChrjDRwoNxYiO5g/XzTS27cP+PLLsp8nX8k3rrrKXjQaxHEjZGVMRmxJbYx3771AUJDsaIhsrnZtseYIUL5Ger+fY4lG05iMkJUxGbEllmjICT3/vGikd+0a8PLLZTuHOnD1gZAH4OXmZb3gyDrCw8VXJiNkJUxGbIWN8chJmTbS+/prYPt2y57PEo0OcEYNWRmTEVvZupWN8chp3Xcf8MwzYtvSRnp7E/fifNp5+Hr6IrJhpG0CpPJp3FhknWlpQGKi7GjIATAZsRW1RDNoEBvjkVOaOxeoXh2Ijy/oYVMaLNHogIeHmOILsFRDVsFkxBby8oCNG8U2SzTkpO5spHf69N2fwxKNjnAQK1kRkxFbUBvj+fmxMR45tccfB7p2FRXL0jTS252wG0npSfD19EWvBr3sEiOVEZMRsiImI7ag9qJhYzxycgYDsHix+N9g82Zg/fqSj1fvigwOHQxPN0/bB0hlx2SErIjJiC1wSi+RUWhowRTfiROB9PSij8vLz8PquNUA2ItGF0xn1JR3uV1yekxGrM20MV4fLtZEBAAzZgDBwcC5c8U30tudKEo0fp5+6NWQJRrNa9RI/J7LyAASEmRHQzrHZMTa1BJN165izAgRwdsbWLBAbM+fDxw6VPgYdRbNg2EPwsPVw37BUdm4uwMhIWKbpRoqJyYj1sYSDVGR+vUDHnqo6EZ6LNHoFMeNkJUwGbGmlBRgzx6xPWiQ3FiINEhtpLd3L7B0acH+nQk7cTHjIqp4VUGPBj2kxUcWYjJCVsJkxJrYGI+oRHXqAHPmiO1XXhEz4AGTEk0oSzS6wmSErITJiDWp40V4V4SoWBMmAC1aFDTSy83PxZr4NQC40JnuqMlIfDxn1FC5lCkZWbRoEYKDg+Hl5YWIiAjs3LmzxOO3b9+OiIgIeHl5oUGDBliyZEmZgtW0zExgyxaxzfEiRMUybaS3fDmwYOMOpGSkoKp3VXQP7i47PLJEw4ZiafjMTODsWdnRkI5ZnIysXLkSkyZNwowZMxAbG4tOnTqhb9++SChmatfp06fRr18/dOrUCbGxsXj11VcxceJErFmzptzBa4ppY7wWLWRHQ6Rp7doBTz8ttuesFgudPRj6INxduUigrri5iYVkAJZqqFwsTkbmzZuH0aNHY8yYMQgLC8P8+fMRFBSExYsXF3n8kiVLULduXcyfPx9hYWEYM2YMnnrqKXzwwQfFXiMrKwupqalmD81jYzwii8ydC/jXyMW1QJZodI3jRsgKLEpGsrOzceDAAURGmrf1joyMxB51Fskd9u7dW+j43r17Y//+/cjJySnyOXPnzoWfn5/xEaT1waCmjfE4XoSoVKpWBZ6asx2oeAnIrIZw726yQ6KyYDJCVuBmycGXL19GXl4eAgICzPYHBAQgOTm5yOckJycXeXxubi4uX76MwMDAQs+ZPn06pkyZYvw+NTXVJgnJAw+IVSHbtCnnifLzgXnzgF9+Abp0sUpsRM7ghUfDsfW193BP83zUqcUSjS517w5MncqmoDo2vNlwtKvdDuHVw6XFYFEyojLcUYZQFKXQvrsdX9R+laenJzw9bd8ka9gw8Sg3d3fRnvTxx61wMiLnUcs3EAc+eUl2GFQe7duLB+nW6HtHyw7BsjKNv78/XF1dC90FSUlJKXT3Q1WzZs0ij3dzc0O1atUsDJeIiIgcjUXJiIeHByIiIhAdHW22Pzo6Gh06dCjyOe3bty90/JYtW9C6dWu4u/O2LBERkbOzeDbNlClT8OWXX2LZsmWIj4/H5MmTkZCQgLFjxwIQ4z1GjBhhPH7s2LE4e/YspkyZgvj4eCxbtgxLly7F1KlTrfcqiIiISLcsHjMybNgwXLlyBXPmzEFSUhKaNWuGqKgo1KtXDwCQlJRktuZIcHAwoqKiMHnyZCxcuBC1atXCJ598goceesh6r4KIiIh0y6Coo0k1LDU1FX5+frhx4wZ8fX1lh0NERESlUNp/v9mbhoiIiKRiMkJERERSMRkhIiIiqZiMEBERkVRMRoiIiEgqJiNEREQkFZMRIiIikorJCBEREUlVpq699qauy5aamio5EiIiIiot9d/tu62vqotkJC0tDQAQFBQkORIiIiKyVFpaGvz8/Ir9uS6Wg8/Pz8eFCxdQqVIlGAwGpKamIigoCImJiVwe3o74vtsf33M5+L7LwfddDlu+74qiIC0tDbVq1YKLS/EjQ3RxZ8TFxQV16tQptN/X15cfWAn4vtsf33M5+L7LwfddDlu97yXdEVFxACsRERFJxWSEiIiIpNJlMuLp6YlZs2bB09NTdihOhe+7/fE9l4Pvuxx83+XQwvuuiwGsRERE5Lh0eWeEiIiIHAeTESIiIpKKyQgRERFJxWSEiIiIpGIyQkRERFJpMhlZtGgRgoOD4eXlhYiICOzcubPE47dv346IiAh4eXmhQYMGWLJkiZ0idSyWvO8xMTEwGAyFHkeOHLFjxPq3Y8cODBw4ELVq1YLBYMD69evv+hx+3svP0vedn/fymzt3Ltq0aYNKlSqhRo0aGDx4MI4ePXrX5/HzXj5led9lfN41l4ysXLkSkyZNwowZMxAbG4tOnTqhb9++SEhIKPL406dPo1+/fujUqRNiY2Px6quvYuLEiVizZo2dI9c3S9931dGjR5GUlGR8NG7c2E4RO4aMjAy0aNECCxYsKNXx/Lxbh6Xvu4qf97Lbvn07xo8fj3379iE6Ohq5ubmIjIxERkZGsc/h5738yvK+q+z6eVc0pm3btsrYsWPN9oWGhirTpk0r8viXX35ZCQ0NNdv37LPPKu3atbNZjI7I0vd927ZtCgDl2rVrdojOOQBQ1q1bV+Ix/LxbX2ned37erS8lJUUBoGzfvr3YY/h5t77SvO8yPu+aujOSnZ2NAwcOIDIy0mx/ZGQk9uzZU+Rz9u7dW+j43r17Y//+/cjJybFZrI6kLO+7qlWrVggMDESPHj2wbds2W4ZJ4OddNn7erefGjRsAgKpVqxZ7DD/v1lea911lz8+7ppKRy5cvIy8vDwEBAWb7AwICkJycXORzkpOTizw+NzcXly9ftlmsjqQs73tgYCA+//xzrFmzBmvXrkVISAh69OiBHTt22CNkp8XPuxz8vFuXoiiYMmUK7r//fjRr1qzY4/h5t67Svu8yPu9uNjtzORgMBrPvFUUptO9uxxe1n0pmyfseEhKCkJAQ4/ft27dHYmIiPvjgA3Tu3NmmcTo7ft7tj59363r++edx6NAh7Nq1667H8vNuPaV932V83jV1Z8Tf3x+urq6F/hpPSUkplB2ratasWeTxbm5uqFatms1idSRled+L0q5dOxw/ftza4ZEJft61g5/3spkwYQI2bNiAbdu2oU6dOiUey8+79VjyvhfF1p93TSUjHh4eiIiIQHR0tNn+6OhodOjQocjntG/fvtDxW7ZsQevWreHu7m6zWB1JWd73osTGxiIwMNDa4ZEJft61g593yyiKgueffx5r167Fb7/9huDg4Ls+h5/38ivL+14Um3/e7TZUtpS+//57xd3dXVm6dKkSFxenTJo0SalYsaJy5swZRVEUZdq0acoTTzxhPP7UqVNKhQoVlMmTJytxcXHK0qVLFXd3d2X16tWyXoIuWfq+f/TRR8q6deuUY8eOKf/++68ybdo0BYCyZs0aWS9Bl9LS0pTY2FglNjZWAaDMmzdPiY2NVc6ePasoCj/vtmLp+87Pe/k999xzip+fnxITE6MkJSUZH5mZmcZj+Hm3vrK87zI+75pLRhRFURYuXKjUq1dP8fDwUO69916zKUgjR45UunTpYnZ8TEyM0qpVK8XDw0OpX7++snjxYjtH7Bgsed/fffddpWHDhoqXl5dSpUoV5f7771c2b94sIWp9U6fQ3fkYOXKkoij8vNuKpe87P+/lV9T7DUD56quvjMfw8259ZXnfZXzeDbeDJSIiIpJCU2NGiIiIyPkwGSEiIiKpmIwQERGRVExGiIiISComI0RERCQVkxEiIiKSiskIERERScVkhIiIiKRiMkJERERSMRkhIiIiqZiMEBERkVT/DzgQFIVF5SIzAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Display the classifier performance and visualize the results\n", + "eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, \n", + " plot_rules=False, print_rules=False, plot_partitions=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Demos/iris_demo_persistence.py b/Demos/iris_demo_persistence.py new file mode 100644 index 0000000..8e5cd31 --- /dev/null +++ b/Demos/iris_demo_persistence.py @@ -0,0 +1,61 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" + + +import pandas as pd + +from sklearn import datasets +from sklearn.model_selection import train_test_split + +import sys + +# In case yo urun this without installing the package, you need to add the path to the package +sys.path.append('./ex_fuzzy/') +sys.path.append('../ex_fuzzy/') + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools +import ex_fuzzy.persistence as persistence +import ex_fuzzy.vis_rules as vis_rules + +fz_type_studied = fs.FUZZY_SETS.t1 + +# Import some data to play with +iris = datasets.load_iris() +X = pd.DataFrame(iris.data, columns=iris.feature_names) +y = iris.target + +# Compute the fuzzy partitions using 3 quartiles +precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +# Split the data into a training set and a test set +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +# Load rules from a plain text file +with open('iris_rules.txt', 'r') as f: + str_rules = f.read() + +# Persistence of the rules example +mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions) + +fl_classifier2 = GA.BaseFuzzyRulesClassifier(precomputed_rules=mrule_base) +# fl_classifier2.load_master_rule_base(mrule_base) # (Another possibility) + +str_rules = eval_tools.eval_fuzzy_model(fl_classifier2, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) + +print('Done') \ No newline at end of file diff --git a/Demos/occupancy_data/datatest.txt b/Demos/occupancy_data/datatest.txt new file mode 100644 index 0000000..fabde16 --- /dev/null +++ b/Demos/occupancy_data/datatest.txt @@ -0,0 +1,2666 @@ +"date","Temperature","Humidity","Light","CO2","HumidityRatio","Occupancy" +"140","2015-02-02 14:19:00",23.7,26.272,585.2,749.2,0.00476416302416414,1 +"141","2015-02-02 14:19:59",23.718,26.29,578.4,760.4,0.00477266099212519,1 +"142","2015-02-02 14:21:00",23.73,26.23,572.666666666667,769.666666666667,0.00476515255246541,1 +"143","2015-02-02 14:22:00",23.7225,26.125,493.75,774.75,0.00474377335599685,1 +"144","2015-02-02 14:23:00",23.754,26.2,488.6,779,0.00476659399998615,1 +"145","2015-02-02 14:23:59",23.76,26.26,568.666666666667,790,0.00477933243163454,1 +"146","2015-02-02 14:25:00",23.73,26.29,536.333333333333,798,0.00477613633274892,1 +"147","2015-02-02 14:25:59",23.754,26.29,509,797,0.00478309370839038,1 +"148","2015-02-02 14:26:59",23.754,26.35,476,803.2,0.00479409399662041,1 +"149","2015-02-02 14:28:00",23.736,26.39,510,809,0.00479618871038935,1 +"150","2015-02-02 14:29:00",23.745,26.445,481.5,815.25,0.00480888622067716,1 +"151","2015-02-02 14:30:00",23.7,26.56,481.8,824,0.0048167933677358,1 +"152","2015-02-02 14:31:00",23.7,26.6,475.25,832,0.00482410383674874,1 +"153","2015-02-02 14:31:59",23.7,26.7,469,845.333333333333,0.00484238075533563,1 +"154","2015-02-02 14:32:59",23.7,26.774,464,852.4,0.00485590636128976,1 +"155","2015-02-02 14:34:00",23.7,26.89,464,861,0.00487710983719076,1 +"156","2015-02-02 14:35:00",23.7,26.9725,455,880,0.004892190768364,1 +"157","2015-02-02 14:36:00",23.6,26.89,454,891,0.00484759441396992,1 +"158","2015-02-02 14:37:00",23.64,26.976,458,897.6,0.0048750447811301,1 +"159","2015-02-02 14:38:00",23.65,27.05,464,900.5,0.00489149158929623,1 +"160","2015-02-02 14:38:59",23.64,27.1,473,908.8,0.00489763024345823,1 +"161","2015-02-02 14:39:59",23.6,27.16,464,918,0.00489665184522539,1 +"162","2015-02-02 14:41:00",23.6,27.236,498.4,925.2,0.00491046198855591,1 +"163","2015-02-02 14:42:00",23.6,27.29,530.2,929.4,0.0049202748285747,1 +"164","2015-02-02 14:43:00",23.6,27.33,533.6,936.4,0.00492754379701558,1 +"165","2015-02-02 14:44:00",23.6,27.34,524.25,950,0.0049293610654639,1 +"166","2015-02-02 14:44:59",23.625,27.3925,498.666666666667,961,0.00494640574744149,1 +"167","2015-02-02 14:45:59",23.6,27.39,516.333333333333,963,0.00493844756573873,1 +"168","2015-02-02 14:47:00",23.6,27.412,501.2,958.6,0.00494244570930318,1 +"169","2015-02-02 14:48:00",23.6,27.5,522,965.333333333333,0.00495843879351724,1 +"170","2015-02-02 14:49:00",23.6,27.525,520.5,979.25,0.00496298243218165,1 +"171","2015-02-02 14:50:00",23.6,27.6,505.285714285714,978.428571428571,0.00497661374332263,1 +"172","2015-02-02 14:51:00",23.6,27.6,488.333333333333,983,0.00497661374332263,1 +"173","2015-02-02 14:51:59",23.6,27.54,512,992.6,0.00496570864699156,1 +"174","2015-02-02 14:53:00",23.6,27.6,511,997.2,0.00497661374332263,1 +"175","2015-02-02 14:54:00",23.6166666666667,27.6333333333333,501.5,999.5,0.00498771842139186,1 +"176","2015-02-02 14:55:00",23.6666666666667,27.7,503.666666666667,1001,0.00501505086095386,1 +"177","2015-02-02 14:55:59",23.6,27.7,483.166666666667,1009.5,0.00499478974690881,1 +"178","2015-02-02 14:57:00",23.6,27.7225,483.5,1019,0.00499887949294923,1 +"179","2015-02-02 14:57:59",23.6,27.79,473,1021,0.00501114905119468,1 +"180","2015-02-02 14:58:59",23.6,27.8566666666667,470.333333333333,1024.66666666667,0.00502326760476436,1 +"181","2015-02-02 15:00:00",23.6,27.8042857142857,480.142857142857,1030.42857142857,0.00501374584466786,1 +"182","2015-02-02 15:01:00",23.575,27.79,464,1026.25,0.00500354474845336,1 +"183","2015-02-02 15:02:00",23.54,27.81,474.4,1028,0.00499653801060323,1 +"184","2015-02-02 15:03:00",23.6,27.978,470,1034.8,0.00504532457442066,1 +"185","2015-02-02 15:04:00",23.525,28,454,1055.5,0.00502636675819462,1 +"186","2015-02-02 15:04:59",23.5,27.978,454,1055.25,0.0050147597241768,1 +"187","2015-02-02 15:06:00",23.5,28,454,1050,0.00501873480786954,1 +"188","2015-02-02 15:07:00",23.5,28,454,1051.25,0.00501873480786954,1 +"189","2015-02-02 15:08:00",23.5,28,445,1053.6,0.00501873480786954,1 +"190","2015-02-02 15:08:59",23.5,28,439,1055.5,0.00501873480786954,1 +"191","2015-02-02 15:10:00",23.5,28.025,444.25,1055,0.00502325200960961,1 +"192","2015-02-02 15:10:59",23.445,28.125,454.75,1059.5,0.00502449114747957,1 +"193","2015-02-02 15:11:59",23.39,28.18,455.8,1060,0.00501758227438523,1 +"194","2015-02-02 15:13:00",23.39,28.2,451.6,1073.6,0.00502117211635073,1 +"195","2015-02-02 15:14:00",23.39,28.2,451.6,1078.6,0.00502117211635073,1 +"196","2015-02-02 15:15:00",23.39,28.2,454.75,1081,0.00502117211635073,1 +"197","2015-02-02 15:16:00",23.39,28.2225,454.75,1082,0.00502521073769626,1 +"198","2015-02-02 15:16:59",23.39,28.3733333333333,457.5,1088.83333333333,0.00505228580200481,1 +"199","2015-02-02 15:17:59",23.37,28.39,464,1090.6,0.00504912954232637,1 +"200","2015-02-02 15:19:00",23.39,28.3233333333333,464,1086,0.00504331038348948,1 +"201","2015-02-02 15:20:00",23.3733333333333,28.445,464,1092.5,0.00506001703431877,1 +"202","2015-02-02 15:21:00",23.39,28.5,471.5,1103.75,0.00507502467892817,1 +"203","2015-02-02 15:22:00",23.3233333333333,28.5,475.666666666667,1104.5,0.0050544759894773,1 +"204","2015-02-02 15:23:00",23.365,28.5,471.5,1103.5,0.00506731029811295,1 +"205","2015-02-02 15:23:59",23.29,28.5,467.75,1112,0.00504422920396206,1 +"206","2015-02-02 15:24:59",23.3066666666667,28.5333333333333,466.5,1105.66666666667,0.00505530397430099,1 +"207","2015-02-02 15:26:00",23.29,28.7,464,1104,0.00507991640233217,1 +"208","2015-02-02 15:27:00",23.29,28.7,467,1117.2,0.00507991640233217,1 +"209","2015-02-02 15:28:00",23.29,28.675,467.75,1121.25,0.00507545528038826,1 +"210","2015-02-02 15:29:00",23.29,28.6166666666667,466.5,1115.66666666667,0.00506504624269139,1 +"211","2015-02-02 15:29:59",23.29,28.66,459,1120,0.00507277863768927,1 +"212","2015-02-02 15:30:59",23.29,28.55,464,1123.75,0.0050531506227436,1 +"213","2015-02-02 15:32:00",23.29,28.6,470,1116,0.00506207229539191,1 +"214","2015-02-02 15:33:00",23.272,28.6,464,1126.8,0.00505652695304372,1 +"215","2015-02-02 15:34:00",23.2,28.4175,464,1112.75,0.00500201570843155,1 +"216","2015-02-02 15:35:00",23.23,28.5,449,1104.5,0.0050258311747689,1 +"217","2015-02-02 15:36:00",23.29,28.5,464,1108,0.00504422920396206,1 +"218","2015-02-02 15:36:59",23.215,28.6333333333333,462.333333333333,1127.83333333333,0.00504492264821108,1 +"219","2015-02-02 15:38:00",23.2,28.6,469,1128.75,0.00503439915237488,1 +"220","2015-02-02 15:39:00",23.2,28.65,469,1124.25,0.00504327191257943,1 +"221","2015-02-02 15:40:00",23.2,28.62,469,1130.4,0.0050379482263243,1 +"222","2015-02-02 15:40:59",23.2,28.7,464,1138,0.00505214492389298,1 +"223","2015-02-02 15:42:00",23.2,28.7,456.5,1144,0.00505214492389298,1 +"224","2015-02-02 15:42:59",23.2,28.718,457,1140,0.0050553392694394,1 +"225","2015-02-02 15:43:59",23.2,28.79,450.25,1139.25,0.00506811697708606,1 +"226","2015-02-02 15:45:00",23.2,28.79,446,1167.33333333333,0.00506811697708606,1 +"227","2015-02-02 15:46:00",23.14,28.79,451.6,1159.6,0.00504961840975861,1 +"228","2015-02-02 15:47:00",23.15,28.89,454.75,1157.75,0.00507039060666789,1 +"229","2015-02-02 15:48:00",23.15,28.89,448,1159.5,0.00507039060666789,1 +"230","2015-02-02 15:49:00",23.18,28.83,444,1156.4,0.00506903438932986,1 +"231","2015-02-02 15:49:59",23.1166666666667,28.945,444,1160,0.00506980946716446,1 +"232","2015-02-02 15:51:00",23.14,28.956,444,1169.8,0.00507897170322202,1 +"233","2015-02-02 15:52:00",23.1,29,444,1176.16666666667,0.00507436212642666,1 +"234","2015-02-02 15:53:00",23.1,29.075,444,1175.25,0.00508759281801227,1 +"235","2015-02-02 15:53:59",23.1,28.918,444,1166.6,0.00505989720917094,1 +"236","2015-02-02 15:55:00",23.1,27.925,444,1140.25,0.0048847835460129,1 +"237","2015-02-02 15:55:59",23.06,27.772,444,1089.2,0.00484597890696344,1 +"238","2015-02-02 15:56:59",23.02,27.556,435,1042.6,0.00479628399598345,1 +"239","2015-02-02 15:58:00",23.01,27.8188333333333,432,1051.1,0.00483943509812856,1 +"240","2015-02-02 15:59:00",23,28.0816666666667,429,1059.6,0.00488253791514092,1 +"241","2015-02-02 16:00:00",23,27.956,429,1064.6,0.00486051760799699,1 +"242","2015-02-02 16:01:00",22.9816666666667,27.9083333333333,429,1061.66666666667,0.00484674149485762,1 +"243","2015-02-02 16:01:59",23,27.9266666666667,429,1058.33333333333,0.00485537781204804,1 +"244","2015-02-02 16:02:59",23,28.018,429,1061.6,0.00487138154496758,1 +"245","2015-02-02 16:04:00",22.9816666666667,28.0666666666667,429,1070.33333333333,0.00487445417299691,1 +"246","2015-02-02 16:05:00",22.945,28.1,429,1074,0.00486938124670424,1 +"247","2015-02-02 16:06:00",23,28.1,429,1086.25,0.0048857505561061,1 +"248","2015-02-02 16:07:00",22.956,28.2,429,1089.6,0.00489012795696835,1 +"249","2015-02-02 16:08:00",22.9725,28.1,429,1085,0.00487755984259212,1 +"250","2015-02-02 16:08:59",22.945,28.1333333333333,429,1085,0.00487520277362808,1 +"251","2015-02-02 16:09:59",23,28.2,429,1088,0.00490327463194147,1 +"252","2015-02-02 16:11:00",22.945,28.2,429,1091.75,0.00488684615185727,1 +"253","2015-02-02 16:12:00",23,28.1333333333333,429,1091.33333333333,0.00489159180585966,1 +"254","2015-02-02 16:13:00",22.912,28.1,429,1088.2,0.00485958290505565,1 +"255","2015-02-02 16:14:00",22.89,28.1,429,1087.5,0.00485306034574781,1 +"256","2015-02-02 16:14:59",22.89,27.956,432,1079.2,0.00482799752977294,1 +"257","2015-02-02 16:15:59",22.865,27.84,432.75,1077.25,0.00480047642649419,1 +"258","2015-02-02 16:17:00",22.8733333333333,27.6833333333333,439,1064.16666666667,0.00477568424252338,1 +"259","2015-02-02 16:18:00",22.8733333333333,27.6,429,1056.4,0.00476119826877342,1 +"260","2015-02-02 16:19:00",22.89,27.6,432.75,1043.6,0.00476604528011147,1 +"261","2015-02-02 16:20:00",22.815,27.445,432.75,1039.5,0.0047174223493656,1 +"262","2015-02-02 16:21:00",22.84,27.3733333333333,436.5,1028.66666666667,0.00471219953995305,1 +"263","2015-02-02 16:21:59",22.79,27.365,438,1020.4,0.00469639044961084,1 +"264","2015-02-02 16:23:00",22.79,27.2,444,1018,0.00466786058404679,1 +"265","2015-02-02 16:24:00",22.79,27.1714285714286,435.428571428571,1015.14285714286,0.00466292061142762,1 +"266","2015-02-02 16:25:00",22.79,27.0666666666667,434,1006.33333333333,0.00464480804480218,1 +"267","2015-02-02 16:25:59",22.79,27.02,432,1002.6,0.00463674005674535,1 +"268","2015-02-02 16:27:00",22.772,26.934,438,993.2,0.00461679349309269,1 +"269","2015-02-02 16:27:59",22.76,26.8233333333333,439,983.333333333333,0.00459431462064815,1 +"270","2015-02-02 16:28:59",22.7,26.754,432,976.2,0.00456558276701595,1 +"271","2015-02-02 16:30:00",22.7225,26.7,432.75,980.75,0.00456256926364279,1 +"272","2015-02-02 16:31:00",22.7,26.6833333333333,434,971.333333333333,0.00455343518515253,1 +"273","2015-02-02 16:32:00",22.7,26.5333333333333,444,966.666666666667,0.00452765178461813,1 +"274","2015-02-02 16:33:00",22.7,26.4633333333333,444,963,0.00451562025722854,1 +"275","2015-02-02 16:34:00",22.7,26.445,441.5,952.333333333333,0.00451246921927278,1 +"276","2015-02-02 16:34:59",22.7,26.34,444,948,0.00449442297611622,1 +"277","2015-02-02 16:36:00",22.7,26.26,444,945,0.00448067415529907,1 +"278","2015-02-02 16:37:00",22.7,26.2,441,941.6,0.00447036293569594,1 +"279","2015-02-02 16:38:00",22.7,26.16,438,929.8,0.00446348897786061,1 +"280","2015-02-02 16:38:59",22.7,26.02,441,923.8,0.00443943131332927,1 +"281","2015-02-02 16:40:00",22.7,26.1,440.25,919,0.00445317832394532,1 +"282","2015-02-02 16:40:59",22.7,26,439,918.25,0.0044359946549457,1 +"283","2015-02-02 16:41:59",22.7,25.934,438,919.4,0.00442465394980727,1 +"284","2015-02-02 16:43:00",22.7,25.9266666666667,439,927.333333333333,0.00442339389680503,1 +"285","2015-02-02 16:44:00",22.7,25.815,432.75,920.25,0.00440420735236127,1 +"286","2015-02-02 16:45:00",22.68,25.772,432,902.4,0.00439144943150097,1 +"287","2015-02-02 16:46:00",22.64,25.696,429,904.4,0.00436771760822153,1 +"288","2015-02-02 16:46:59",22.6,25.575,429,897,0.00433639010072962,1 +"289","2015-02-02 16:47:59",22.6666666666667,25.6,429,892,0.00435838319402606,1 +"290","2015-02-02 16:49:00",22.6,25.525,433.5,882.5,0.00432785332156062,1 +"291","2015-02-02 16:50:00",22.62,25.476,436.2,887.2,0.00432477212303797,1 +"292","2015-02-02 16:51:00",22.625,25.55,442.5,889.25,0.00433874780423475,1 +"293","2015-02-02 16:52:00",22.6,25.39,443.4,889.2,0.00430480518013568,1 +"294","2015-02-02 16:53:00",22.65,25.42,438,880.75,0.0043231196096785,1 +"295","2015-02-02 16:53:59",22.6,25.2675,442.5,868.75,0.0042838925937963,1 +"296","2015-02-02 16:54:59",22.6,25.218,439.8,861,0.00427544259793873,1 +"297","2015-02-02 16:56:00",22.6,25.2,439.8,860.6,0.0042723699287058,1 +"298","2015-02-02 16:57:00",22.6,25.2,435.5,864,0.0042723699287058,1 +"299","2015-02-02 16:58:00",22.6,25.15,430.75,859,0.00426383489458762,1 +"300","2015-02-02 16:59:00",22.6,25.14,440.6,854.4,0.00426212791568025,1 +"301","2015-02-02 16:59:59",22.6,25.15,428.2,847.4,0.00426383489458762,1 +"302","2015-02-02 17:00:59",22.6,25.04,432.2,837.2,0.00424505863838244,1 +"303","2015-02-02 17:02:00",22.6,25.05,431.75,834.75,0.00424676552424079,1 +"304","2015-02-02 17:03:00",22.6,25.06,429.2,832.4,0.0042484724194037,1 +"305","2015-02-02 17:04:00",22.6,25,433,832,0.00423823118799312,1 +"306","2015-02-02 17:05:00",22.6,25,433,836.25,0.00423823118799312,1 +"307","2015-02-02 17:06:00",22.6,25,428.2,832.6,0.00423823118799312,1 +"308","2015-02-02 17:06:59",22.6,25.025,428.25,821.5,0.0042424983270408,1 +"309","2015-02-02 17:08:00",22.6,25.1,425.4,832.4,0.00425530009310245,1 +"310","2015-02-02 17:09:00",22.6,25.08,429.2,832.4,0.0042518862376435,1 +"311","2015-02-02 17:10:00",22.56,25.02,433,830.75,0.0042312841785683,1 +"312","2015-02-02 17:10:59",22.58,25.08,433,821.5,0.00424669048857924,1 +"313","2015-02-02 17:12:00",22.575,25.075,433,818.25,0.00424454028030122,1 +"314","2015-02-02 17:12:59",22.56,24.912,433,819.8,0.00421289593420237,1 +"315","2015-02-02 17:13:59",22.55,25.2,433,822.5,0.00425932809708705,1 +"316","2015-02-02 17:15:00",22.6,24.9175,433,818,0.00422415004171152,1 +"317","2015-02-02 17:16:00",22.58,25.06,433,812.8,0.00424328087024612,1 +"318","2015-02-02 17:17:00",22.5666666666667,24.9083333333333,433,816.5,0.00421398909213464,1 +"319","2015-02-02 17:18:00",22.525,24.945,433,822.25,0.00420949461543371,1 +"320","2015-02-02 17:19:00",22.54,24.89,433,825,0.0042040055610701,1 +"321","2015-02-02 17:19:59",22.5,24.865,433,816.5,0.00418949204255268,1 +"322","2015-02-02 17:21:00",22.5,24.9175,433,811.5,0.00419839744963948,1 +"323","2015-02-02 17:22:00",22.5,24.9116666666667,433,811,0.00419740794745465,1 +"324","2015-02-02 17:23:00",22.56,24.81,433,812.2,0.00419553025049749,1 +"325","2015-02-02 17:23:59",22.525,24.89,426,814.25,0.00420015063495153,1 +"326","2015-02-02 17:25:00",22.52,24.976,430.2,824,0.00421347256504319,1 +"327","2015-02-02 17:25:59",22.575,25.075,433,834.5,0.00424454028030123,1 +"328","2015-02-02 17:26:59",22.6,25,433,837,0.00423823118799312,1 +"329","2015-02-02 17:28:00",22.6,25.0214285714286,433,841.166666666667,0.00424188873218796,1 +"330","2015-02-02 17:29:00",22.6,25.0428571428571,433,845.333333333333,0.00424554631910682,1 +"331","2015-02-02 17:30:00",22.6,25.1,433,854.75,0.00425530009310245,1 +"332","2015-02-02 17:31:00",22.6,25.1,428.333333333333,850.333333333333,0.00425530009310245,1 +"333","2015-02-02 17:31:59",22.6,25.08,424.6,845.4,0.0042518862376435,1 +"334","2015-02-02 17:32:59",22.6,25.1666666666667,433,854.333333333333,0.00426667988011176,1 +"335","2015-02-02 17:34:00",22.6,25.0666666666667,428.333333333333,849.333333333333,0.00424961035468154,0 +"336","2015-02-02 17:35:00",22.6,25.2,422.5,853,0.0042723699287058,0 +"337","2015-02-02 17:36:00",22.6,25.2,423.666666666667,853,0.0042723699287058,0 +"338","2015-02-02 17:37:00",22.54,25.16,424.6,852,0.0042499210749079,0 +"339","2015-02-02 17:38:00",22.54,25.16,427.4,853.6,0.0042499210749079,0 +"340","2015-02-02 17:38:59",22.54,25.14,421.8,845.6,0.0042465196948245,0 +"341","2015-02-02 17:39:59",22.525,25.1,426,834.25,0.00423582915169482,0 +"342","2015-02-02 17:41:00",22.5,25.04,421.8,826.4,0.00421917771792251,0 +"343","2015-02-02 17:42:00",22.5,25,419,819.6,0.00421239217255268,0 +"344","2015-02-02 17:43:00",22.5,25,419,829.6,0.00421239217255268,0 +"345","2015-02-02 17:44:00",22.5,25,419,824,0.00421239217255268,0 +"346","2015-02-02 17:44:59",22.5,24.912,419,814.2,0.0041974644903524,0 +"347","2015-02-02 17:45:59",22.5,24.89,419,813.5,0.0041937326810038,0 +"348","2015-02-02 17:47:00",22.5,24.89,419,813.8,0.0041937326810038,0 +"349","2015-02-02 17:48:00",22.5,24.89,419,811,0.0041937326810038,0 +"350","2015-02-02 17:49:00",22.478,24.87,419,804.6,0.00418470411108146,0 +"351","2015-02-02 17:50:00",22.456,24.83,419,807.8,0.00417230818064312,0 +"352","2015-02-02 17:51:00",22.5,24.8566666666667,419,802.333333333333,0.00418807850916583,0 +"353","2015-02-02 17:51:59",22.4175,24.7475,419,796.75,0.00414856636550583,0 +"354","2015-02-02 17:53:00",22.456,24.81,419,794.4,0.00416892495641864,0 +"355","2015-02-02 17:54:00",22.39,24.7,419,790.6,0.00413358648459168,0 +"356","2015-02-02 17:55:00",22.4175,24.7225,419,789.75,0.0041443475474366,0 +"357","2015-02-02 17:55:59",22.39,24.7,419,782.2,0.00413358648459168,0 +"358","2015-02-02 17:57:00",22.39,24.7225,419,772.25,0.00413737694389585,1 +"359","2015-02-02 17:57:59",22.39,24.7170833333333,419,772.925,0.00413646442172095,1 +"360","2015-02-02 17:58:59",22.39,24.7116666666667,419,773.6,0.00413555190220584,1 +"361","2015-02-02 18:00:00",22.39,24.625,419,773.75,0.00412095195168535,1 +"362","2015-02-02 18:01:00",22.39,24.754,416.2,771.8,0.00414268366402263,1 +"363","2015-02-02 18:02:00",22.39,24.912,418.6,782.8,0.00416930285551727,1 +"364","2015-02-02 18:03:00",22.39,25.245,415,796.5,0.00422541274126769,1 +"365","2015-02-02 18:04:00",22.39,25.0925,310.25,809,0.00419971552453032,1 +"366","2015-02-02 18:04:59",22.39,25,0,805.5,0.0041841297156888,0 +"367","2015-02-02 18:06:00",22.35,24.978,0,791.4,0.00417019632275524,0 +"368","2015-02-02 18:07:00",22.3233333333333,25,0,779.333333333333,0.00416708241580403,0 +"369","2015-02-02 18:08:00",22.365,24.9725,0,780.75,0.00417310345378263,0 +"370","2015-02-02 18:08:59",22.315,24.89,0,781.75,0.00414650784083818,0 +"371","2015-02-02 18:10:00",22.29,24.9175,0,781,0.00414476697940617,0 +"372","2015-02-02 18:10:59",22.29,24.912,0,778.4,0.00414384601663705,0 +"373","2015-02-02 18:11:59",22.26,24.8566666666667,0,769.333333333333,0.00412698756337495,0 +"374","2015-02-02 18:13:00",22.254,24.85,0,766.5,0.0041243566010876,0 +"375","2015-02-02 18:14:00",22.23,24.7933333333333,0,763.25,0.00410884135392114,0 +"376","2015-02-02 18:15:00",22.26,24.8233333333333,0,762.333333333333,0.00412141651164059,0 +"377","2015-02-02 18:16:00",22.2,24.79,0,761.5,0.00410073726963565,0 +"378","2015-02-02 18:16:59",22.2,24.79,0,761,0.00410073726963565,0 +"379","2015-02-02 18:17:59",22.2,24.736,0,757,0.00409174588095119,0 +"380","2015-02-02 18:19:00",22.2,24.79,0,752.333333333333,0.00410073726963565,0 +"381","2015-02-02 18:20:00",22.1333333333333,24.7,0,748.666666666667,0.00406908365757901,0 +"382","2015-02-02 18:21:00",22.1,24.7,0,746.25,0.00406077210033269,0 +"383","2015-02-02 18:22:00",22.15,24.7225,0,745.25,0.00407697982248635,0 +"384","2015-02-02 18:23:00",22.1,24.7,0,740.666666666667,0.00406077210033269,0 +"385","2015-02-02 18:23:59",22.1,24.7,0,738,0.00406077210033269,0 +"386","2015-02-02 18:24:59",22.1333333333333,24.7,0,732.666666666667,0.00406908365757901,0 +"387","2015-02-02 18:26:00",22.1,24.7,0,727,0.00406077210033269,0 +"388","2015-02-02 18:27:00",22.1,24.675,0,716,0.00405663520140821,0 +"389","2015-02-02 18:28:00",22.0666666666667,24.6666666666667,0,723.25,0.00404697099901821,0 +"390","2015-02-02 18:29:00",22.0666666666667,24.6666666666667,0,718.333333333333,0.00404697099901821,0 +"391","2015-02-02 18:29:59",22,24.58,0,716.6,0.00401619278733235,0 +"392","2015-02-02 18:30:59",21.978,24.6,0,714,0.0040140562223397,0 +"393","2015-02-02 18:32:00",21.978,24.56,0,714.2,0.00400748724931948,0 +"394","2015-02-02 18:33:00",21.945,24.6,0,715,0.00400593001937022,0 +"395","2015-02-02 18:34:00",21.9266666666667,24.5,0,706.666666666667,0.00398505157493118,0 +"396","2015-02-02 18:35:00",21.89,24.5,0,706,0.00397608547610517,0 +"397","2015-02-02 18:36:00",21.89,24.525,0,698.75,0.00398016866833722,0 +"398","2015-02-02 18:36:59",21.89,24.5,0,692.5,0.00397608547610517,0 +"399","2015-02-02 18:38:00",21.89,24.5,0,694.75,0.00397608547610517,0 +"400","2015-02-02 18:39:00",21.815,24.4175,0,697.25,0.00394438928261232,0 +"401","2015-02-02 18:40:00",21.8233333333333,24.4633333333333,0,692,0.00395386507281094,0 +"402","2015-02-02 18:40:59",21.79,24.39,0,691,0.00393386813796092,0 +"403","2015-02-02 18:42:00",21.79,24.39,0,689.75,0.00393386813796092,0 +"404","2015-02-02 18:42:59",21.79,24.39,0,689,0.00393386813796092,0 +"405","2015-02-02 18:43:59",21.7675,24.39,0,687,0.00392842953743671,0 +"406","2015-02-02 18:45:00",21.7675,24.365,0,679.75,0.00392437745140477,0 +"407","2015-02-02 18:46:00",21.754,24.35,0,668.4,0.00391869166016661,0 +"408","2015-02-02 18:47:00",21.7,24.29,0,665.666666666667,0.00389601301458523,0 +"409","2015-02-02 18:48:00",21.7,24.29,0,664.75,0.00389601301458523,0 +"410","2015-02-02 18:49:00",21.7,24.29,0,668,0.00389601301458523,0 +"411","2015-02-02 18:49:59",21.7,24.29,0,661.25,0.00389601301458523,0 +"412","2015-02-02 18:51:00",21.64,24.236,0,658.2,0.00387297199396133,0 +"413","2015-02-02 18:52:00",21.6,24.2,0,656,0.0038576731827532,0 +"414","2015-02-02 18:53:00",21.6,24.2,0,654.8,0.0038576731827532,0 +"415","2015-02-02 18:53:59",21.6,24.2225,0,653.75,0.003861282127931,0 +"416","2015-02-02 18:55:00",21.5,24.26,0,650.333333333333,0.00384355240302953,0 +"417","2015-02-02 18:55:59",21.5,24.2,0,650.75,0.0038339879085467,0 +"418","2015-02-02 18:56:59",21.55,24.2,0,648.25,0.00384581447627792,0 +"419","2015-02-02 18:58:00",21.5,24.2,0,640.333333333333,0.0038339879085467,0 +"420","2015-02-02 18:59:00",21.5,24.2,0,638,0.0038339879085467,0 +"421","2015-02-02 19:00:00",21.5,24.2,0,636.25,0.0038339879085467,0 +"422","2015-02-02 19:01:00",21.5,24.2,0,636.333333333333,0.0038339879085467,0 +"423","2015-02-02 19:01:59",21.5,24.15,0,635.75,0.00382601771979012,0 +"424","2015-02-02 19:02:59",21.5,24.175,0,635.5,0.00383000278879255,0 +"425","2015-02-02 19:04:00",21.5,24.125,0,627.5,0.00382203270153845,0 +"426","2015-02-02 19:05:00",21.5,24.15,0,626.25,0.00382601771979012,0 +"427","2015-02-02 19:06:00",21.5,24.125,0,621.5,0.00382203270153845,0 +"428","2015-02-02 19:07:00",21.5,24.1,0,621.75,0.00381804773403658,0 +"429","2015-02-02 19:08:00",21.5,24.1,0,620.666666666667,0.00381804773403658,0 +"430","2015-02-02 19:08:59",21.5,24.1,0,617,0.00381804773403658,0 +"431","2015-02-02 19:09:59",21.5,24.1,0,612.75,0.00381804773403658,0 +"432","2015-02-02 19:11:00",21.4725,24.075,0,614.5,0.00380760581536113,0 +"433","2015-02-02 19:12:00",21.39,24,0,617.333333333333,0.00377641938611092,0 +"434","2015-02-02 19:13:00",21.4266666666667,23.9266666666667,0,614.25,0.00377333000182496,0 +"435","2015-02-02 19:14:00",21.39,23.9725,0,610.75,0.00377206599728212,0 +"436","2015-02-02 19:14:59",21.39,23.9175,0,603,0.00376335940133541,0 +"437","2015-02-02 19:15:59",21.39,23.945,0,603.5,0.00376771266902404,0 +"438","2015-02-02 19:17:00",21.365,23.89,0,602,0.00375321614938758,0 +"439","2015-02-02 19:18:00",21.3233333333333,24,0,605.666666666667,0.00376092485713894,0 +"440","2015-02-02 19:19:00",21.34,23.9725,0,604.5,0.0037604533217008,0 +"441","2015-02-02 19:20:00",21.315,23.9725,0,599,0.00375465880754887,0 +"442","2015-02-02 19:21:00",21.3566666666667,24,0,600,0.00376866510404066,0 +"443","2015-02-02 19:21:59",21.39,23.9725,0,596.5,0.00377206599728212,0 +"444","2015-02-02 19:23:00",21.315,23.89,0,597.5,0.00374165963273266,0 +"445","2015-02-02 19:24:00",21.29,23.945,0,594,0.00374454576336437,0 +"446","2015-02-02 19:25:00",21.29,23.9725,0,590.5,0.00374887216352344,0 +"447","2015-02-02 19:25:59",21.29,23.89,0,586.666666666667,0.00373589314251898,0 +"448","2015-02-02 19:27:00",21.29,23.9266666666667,0,588,0.00374166152982765,0 +"449","2015-02-02 19:27:59",21.29,23.89,0,585.5,0.00373589314251898,0 +"450","2015-02-02 19:28:59",21.29,23.89,0,584.5,0.00373589314251898,0 +"451","2015-02-02 19:30:00",21.254,23.85,0,587.2,0.00372132453722628,0 +"452","2015-02-02 19:31:00",21.23,23.8233333333333,0,585,0.00371163679525134,0 +"453","2015-02-02 19:32:00",21.218,23.81,0,579.4,0.00370680031023175,0 +"454","2015-02-02 19:33:00",21.2,23.79,0,579.333333333333,0.00369955480346118,0 +"455","2015-02-02 19:34:00",21.2,23.79,0,581.6,0.00369955480346118,0 +"456","2015-02-02 19:34:59",21.2,23.79,0,581.666666666667,0.00369955480346118,0 +"457","2015-02-02 19:36:00",21.2,23.79,0,577.5,0.00369955480346118,0 +"458","2015-02-02 19:37:00",21.2,23.79,0,577.333333333333,0.00369955480346118,0 +"459","2015-02-02 19:38:00",21.2,23.7675,0,574.25,0.00369603506365788,0 +"460","2015-02-02 19:38:59",21.2,23.745,0,569,0.00369251536345345,0 +"461","2015-02-02 19:40:00",21.2,23.76,0,565.333333333333,0.00369486182585656,0 +"462","2015-02-02 19:40:59",21.2,23.7,0,561.4,0.00368547608183853,0 +"463","2015-02-02 19:41:59",21.2,23.79,0,567.333333333333,0.00369955480346118,0 +"464","2015-02-02 19:43:00",21.175,23.7,0,565.333333333333,0.00367979166359871,0 +"465","2015-02-02 19:44:00",21.1666666666667,23.7,0,563.5,0.00367789857519486,0 +"466","2015-02-02 19:45:00",21.125,23.675,0,559,0.00366455353347419,0 +"467","2015-02-02 19:46:00",21.1,23.65,0,559.5,0.00365501193599322,0 +"468","2015-02-02 19:46:59",21.125,23.65,0,550.5,0.00366066111472342,0 +"469","2015-02-02 19:47:59",21.1,23.6,0,553,0.00364723932725151,0 +"470","2015-02-02 19:49:00",21.1333333333333,23.6,0,552,0.00365475715962219,0 +"471","2015-02-02 19:50:00",21.1,23.6,0,553.25,0.00364723932725151,0 +"472","2015-02-02 19:51:00",21.1,23.6,0,545.75,0.00364723932725151,0 +"473","2015-02-02 19:52:00",21.1,23.6,0,548,0.00364723932725151,0 +"474","2015-02-02 19:53:00",21.1,23.6,0,547,0.00364723932725151,0 +"475","2015-02-02 19:53:59",21.1,23.575,0,545.75,0.00364335309530045,0 +"476","2015-02-02 19:54:59",21.1,23.5333333333333,0,544,0.00363687614933414,0 +"477","2015-02-02 19:56:00",21.1,23.4725,0,545.5,0.00362742004904475,0 +"478","2015-02-02 19:57:00",21.1,23.4725,0,547,0.00362742004904475,0 +"479","2015-02-02 19:58:00",21.1,23.5,0,545.25,0.00363169468911561,0 +"480","2015-02-02 19:59:00",21.1,23.5,0,541.25,0.00363169468911561,0 +"481","2015-02-02 19:59:59",21.125,23.5,0,540.75,0.00363730761924146,0 +"482","2015-02-02 20:00:59",21.1,23.5,0,533.333333333333,0.00363169468911561,0 +"483","2015-02-02 20:02:00",21.1333333333333,23.5,0,528,0.00363918029389709,0 +"484","2015-02-02 20:03:00",21.1,23.3925,0,537.75,0.00361498506460243,0 +"485","2015-02-02 20:04:00",21.1,23.4725,0,539.5,0.00362742004904475,0 +"486","2015-02-02 20:05:00",21.1,23.5,0,535.25,0.00363169468911561,0 +"487","2015-02-02 20:06:00",21.1,23.5,0,537.25,0.00363169468911561,0 +"488","2015-02-02 20:06:59",21.1,23.5,0,535.25,0.00363169468911561,0 +"489","2015-02-02 20:08:00",21.1,23.5,0,533.4,0.00363169468911561,0 +"490","2015-02-02 20:09:00",21.1,23.5,0,524.5,0.00363169468911561,0 +"491","2015-02-02 20:10:00",21.1,23.434,0,524.8,0.00362143565107863,0 +"492","2015-02-02 20:10:59",21.1,23.39,0,522.666666666667,0.00361459647930365,0 +"493","2015-02-02 20:12:00",21.1,23.39,0,521,0.00361459647930365,0 +"494","2015-02-02 20:12:59",21.125,23.39,0,519.75,0.00362018283054654,0 +"495","2015-02-02 20:13:59",21.1,23.39,0,523,0.00361459647930365,0 +"496","2015-02-02 20:15:00",21.1,23.39,0,523,0.00361459647930365,0 +"497","2015-02-02 20:16:00",21.1,23.39,0,519,0.00361459647930365,0 +"498","2015-02-02 20:17:00",21.1,23.365,0,519.5,0.00361071065286537,0 +"499","2015-02-02 20:18:00",21.1,23.39,0,519.75,0.00361459647930365,0 +"500","2015-02-02 20:19:00",21.1,23.365,0,520,0.00361071065286537,0 +"501","2015-02-02 20:19:59",21.1,23.33,0,524.6,0.00360527057694702,0 +"502","2015-02-02 20:21:00",21.075,23.315,0,520.25,0.00359737848607855,0 +"503","2015-02-02 20:22:00",21.075,23.34,0,519,0.00360125818434467,0 +"504","2015-02-02 20:23:00",21.1,23.29,0,523.2,0.00359905346317353,0 +"505","2015-02-02 20:23:59",21.0333333333333,23.29,0,517.666666666667,0.00358425790846352,0 +"506","2015-02-02 20:25:00",21.02,23.29,0,514.2,0.00358130523727,0 +"507","2015-02-02 20:25:59",21.025,23.29,0,516.5,0.00358241223770972,0 +"508","2015-02-02 20:26:59",21,23.29,0,521,0.00357688024903438,0 +"509","2015-02-02 20:28:00",21,23.29,0,520,0.00357688024903438,0 +"510","2015-02-02 20:29:00",21,23.254,0,517.8,0.00357131962083668,0 +"511","2015-02-02 20:30:00",21,23.26,0,514.333333333333,0.00357224638533805,0 +"512","2015-02-02 20:31:00",21,23.2675,0,516.75,0.00357340484482625,0 +"513","2015-02-02 20:31:59",21,23.29,0,520.75,0.00357688024903438,0 +"514","2015-02-02 20:32:59",21,23.29,0,519.333333333333,0.00357688024903438,0 +"515","2015-02-02 20:34:00",21,23.29,0,519,0.00357688024903438,0 +"516","2015-02-02 20:35:00",21,23.29,0,509.75,0.00357688024903438,0 +"517","2015-02-02 20:36:00",21,23.29,0,508.5,0.00357688024903438,0 +"518","2015-02-02 20:37:00",20.9725,23.29,0,504.5,0.00357080375658003,0 +"519","2015-02-02 20:38:00",21,23.29,0,506.5,0.00357688024903438,0 +"520","2015-02-02 20:38:59",20.9725,23.29,0,509,0.00357080375658003,0 +"521","2015-02-02 20:39:59",20.9633333333333,23.29,0,507.25,0.00356878028139735,0 +"522","2015-02-02 20:41:00",21,23.29,0,509.333333333333,0.00357688024903438,0 +"523","2015-02-02 20:42:00",20.89,23.2,0,509.666666666667,0.00353882221893409,0 +"524","2015-02-02 20:43:00",20.89,23.245,0,508.25,0.00354572544268721,0 +"525","2015-02-02 20:44:00",20.89,23.2225,0,510.25,0.00354227381176538,0 +"526","2015-02-02 20:44:59",20.89,23.254,0,504,0.00354710610572144,0 +"527","2015-02-02 20:45:59",20.89,23.26,0,499.333333333333,0.00354802655113016,0 +"528","2015-02-02 20:47:00",20.89,23.2225,0,495,0.00354227381176538,0 +"529","2015-02-02 20:48:00",20.89,23.2,0,496.25,0.00353882221893409,0 +"530","2015-02-02 20:49:00",20.89,23.2,0,494.75,0.00353882221893409,0 +"531","2015-02-02 20:50:00",20.89,23.2,0,492.5,0.00353882221893409,0 +"532","2015-02-02 20:51:00",20.89,23.2,0,494.25,0.00353882221893409,0 +"533","2015-02-02 20:51:59",20.89,23.2,0,492.333333333333,0.00353882221893409,0 +"534","2015-02-02 20:53:00",20.89,23.125,0,493.75,0.00352731718458679,0 +"535","2015-02-02 20:54:00",20.89,23.125,0,484.75,0.00352731718458679,0 +"536","2015-02-02 20:55:00",20.89,23.1,0,489.25,0.00352348226718284,0 +"537","2015-02-02 20:55:59",20.89,23.1,0,494.5,0.00352348226718284,0 +"538","2015-02-02 20:57:00",20.89,23.1,0,495.666666666667,0.00352348226718284,0 +"539","2015-02-02 20:57:59",20.89,23.1,0,501.5,0.00352348226718284,0 +"540","2015-02-02 20:58:59",20.89,23.1,0,499.666666666667,0.00352348226718284,0 +"541","2015-02-02 21:00:00",20.89,23.1,0,492.5,0.00352348226718284,0 +"542","2015-02-02 21:01:00",20.89,23.1,0,494.25,0.00352348226718284,0 +"543","2015-02-02 21:02:00",20.89,23.1,0,494,0.00352348226718284,0 +"544","2015-02-02 21:03:00",20.9725,23.1,0,489.25,0.00354150724957436,0 +"545","2015-02-02 21:04:00",20.9175,23.1,0,490,0.00352948159229704,0 +"546","2015-02-02 21:04:59",20.89,23.1,0,495.5,0.00352348226718284,0 +"547","2015-02-02 21:06:00",20.89,23.05,0,498,0.00351581257343747,0 +"548","2015-02-02 21:07:00",20.89,23.05,0,495,0.00351581257343747,0 +"549","2015-02-02 21:08:00",20.912,23,0,490.2,0.00351292080009673,0 +"550","2015-02-02 21:08:59",20.9266666666667,23,0,492.333333333333,0.00351610913906784,0 +"551","2015-02-02 21:10:00",20.89,23,0,491.666666666667,0.00350814306776971,0 +"552","2015-02-02 21:10:59",20.89,22.956,0,488,0.00350139405835438,0 +"553","2015-02-02 21:11:59",20.934,22.934,0,488,0.00350755305943681,0 +"554","2015-02-02 21:13:00",20.89,23,0,485,0.00350814306776971,0 +"555","2015-02-02 21:14:00",20.89,23,0,490,0.00350814306776971,0 +"556","2015-02-02 21:15:00",20.9175,22.9725,0,489.5,0.00350989075838834,0 +"557","2015-02-02 21:16:00",20.89,22.945,0,485.25,0.00349970682875656,0 +"558","2015-02-02 21:16:59",20.89,22.89,0,485.666666666667,0.00349127081729973,0 +"559","2015-02-02 21:17:59",20.9175,22.945,0,485,0.00350566544528695,0 +"560","2015-02-02 21:19:00",20.89,22.956,0,485.2,0.00350139405835438,0 +"561","2015-02-02 21:20:00",20.945,22.89,0,484,0.00350316807807591,0 +"562","2015-02-02 21:21:00",20.89,22.9175,0,483,0.00349548879458418,0 +"563","2015-02-02 21:22:00",20.89,22.89,0,481,0.00349127081729973,0 +"564","2015-02-02 21:23:00",20.89,22.89,0,476.5,0.00349127081729973,0 +"565","2015-02-02 21:23:59",20.89,22.89,0,475,0.00349127081729973,0 +"566","2015-02-02 21:24:59",20.89,22.89,0,476,0.00349127081729973,0 +"567","2015-02-02 21:26:00",20.89,22.89,0,478.5,0.00349127081729973,0 +"568","2015-02-02 21:27:00",20.89,22.89,0,481,0.00349127081729973,0 +"569","2015-02-02 21:28:00",20.89,22.89,0,483,0.00349127081729973,0 +"570","2015-02-02 21:29:00",20.8566666666667,22.8566666666667,0,480.25,0.00347897566308279,0 +"571","2015-02-02 21:29:59",20.89,22.89,0,480.25,0.00349127081729973,0 +"572","2015-02-02 21:30:59",20.89,22.865,0,470.75,0.00348743634186028,0 +"573","2015-02-02 21:32:00",20.89,22.89,0,474.75,0.00349127081729973,0 +"574","2015-02-02 21:33:00",20.89,22.865,0,482.25,0.00348743634186028,0 +"575","2015-02-02 21:34:00",20.89,22.89,0,480.333333333333,0.00349127081729973,0 +"576","2015-02-02 21:35:00",20.89,22.89,0,480,0.00349127081729973,0 +"577","2015-02-02 21:36:00",20.89,22.84,0,481.5,0.00348360191343384,0 +"578","2015-02-02 21:36:59",20.89,22.84,0,483.5,0.00348360191343384,0 +"579","2015-02-02 21:38:00",20.89,22.79,0,475.6,0.0034759331976165,0 +"580","2015-02-02 21:39:00",20.89,22.76,0,475.333333333333,0.00347133205838652,0 +"581","2015-02-02 21:40:00",20.89,22.815,0,477.666666666667,0.00347976753201953,0 +"582","2015-02-02 21:40:59",20.89,22.79,0,475.75,0.0034759331976165,0 +"583","2015-02-02 21:42:00",20.89,22.79,0,479.166666666667,0.0034759331976165,0 +"584","2015-02-02 21:42:59",20.865,22.7675,0,475,0.00346711546963321,0 +"585","2015-02-02 21:43:59",20.865,22.7675,0,474,0.00346711546963321,0 +"586","2015-02-02 21:45:00",20.89,22.79,0,477.333333333333,0.0034759331976165,0 +"587","2015-02-02 21:46:00",20.89,22.79,0,473,0.0034759331976165,0 +"588","2015-02-02 21:47:00",20.89,22.7675,0,470,0.00347248233684769,0 +"589","2015-02-02 21:48:00",20.865,22.675,0,468.75,0.00345295104445914,0 +"590","2015-02-02 21:49:00",20.87,22.718,0,471.4,0.00346060593833997,0 +"591","2015-02-02 21:49:59",20.89,22.7,0,471,0.00346212998300557,0 +"592","2015-02-02 21:51:00",20.89,22.7,0,468,0.00346212998300557,0 +"593","2015-02-02 21:52:00",20.85,22.678,0,468.6,0.00345020659473582,0 +"594","2015-02-02 21:53:00",20.81,22.62,0,467.4,0.00343282503619857,0 +"595","2015-02-02 21:53:59",20.79,22.6,0,469,0.00342552949876246,0 +"596","2015-02-02 21:55:00",20.79,22.65,0,471.25,0.00343314993421406,0 +"597","2015-02-02 21:55:59",20.8233333333333,22.73,0,470.666666666667,0.00345245938689913,0 +"598","2015-02-02 21:56:59",20.79,22.6,0,466.75,0.00342552949876246,0 +"599","2015-02-02 21:58:00",20.79,22.64,0,466.8,0.0034316258322677,0 +"600","2015-02-02 21:59:00",20.79,22.7,0,468.75,0.0034407705553688,0 +"601","2015-02-02 22:00:00",20.79,22.65,0,467.5,0.00343314993421406,0 +"602","2015-02-02 22:01:00",20.79,22.6333333333333,0,469.666666666667,0.00343060976843018,0 +"603","2015-02-02 22:01:59",20.79,22.7,0,469.75,0.0034407705553688,0 +"604","2015-02-02 22:02:59",20.79,22.6,0,469.75,0.00342552949876246,0 +"605","2015-02-02 22:04:00",20.79,22.6,0,467.25,0.00342552949876246,0 +"606","2015-02-02 22:05:00",20.772,22.6,0,461.4,0.00342171422452537,0 +"607","2015-02-02 22:06:00",20.79,22.6,0,469.25,0.00342552949876246,0 +"608","2015-02-02 22:07:00",20.79,22.625,0,468,0.00342933969327579,0 +"609","2015-02-02 22:08:00",20.73,22.6,0,469,0.00341282647306003,0 +"610","2015-02-02 22:08:59",20.79,22.6,0,467.25,0.00342552949876246,0 +"611","2015-02-02 22:09:59",20.79,22.6,0,467.4,0.00342552949876246,0 +"612","2015-02-02 22:11:00",20.79,22.6,0,467.666666666667,0.00342552949876246,0 +"613","2015-02-02 22:12:00",20.745,22.6,0,471.5,0.00341599833244845,0 +"614","2015-02-02 22:13:00",20.76,22.6,0,471.666666666667,0.00341917278864175,0 +"615","2015-02-02 22:14:00",20.7225,22.6,0,464.75,0.00341124151659625,0 +"616","2015-02-02 22:14:59",20.7225,22.6,0,461.75,0.00341124151659625,0 +"617","2015-02-02 22:15:59",20.7225,22.6,0,458.5,0.00341124151659625,0 +"618","2015-02-02 22:17:00",20.745,22.55,0,459.5,0.00340839940076414,0 +"619","2015-02-02 22:18:00",20.7225,22.55,0,460.5,0.00340365322409664,0 +"620","2015-02-02 22:19:00",20.76,22.5666666666667,0,465.333333333333,0.00341410208020416,0 +"621","2015-02-02 22:20:00",20.7225,22.5,0,465,0.00339606511573662,0 +"622","2015-02-02 22:21:00",20.7225,22.5,0,459,0.00339606511573662,0 +"623","2015-02-02 22:21:59",20.7675,22.5,0,463,0.00340554200808737,0 +"624","2015-02-02 22:23:00",20.745,22.5,0,460.75,0.00340080065373473,0 +"625","2015-02-02 22:24:00",20.7,22.5,0,461.5,0.00339133538795165,0 +"626","2015-02-02 22:25:00",20.7,22.5,0,466,0.00339133538795165,0 +"627","2015-02-02 22:25:59",20.7675,22.5,0,460.25,0.00340554200808737,0 +"628","2015-02-02 22:27:00",20.718,22.52,0,457.4,0.00339815307635992,0 +"629","2015-02-02 22:27:59",20.7,22.5,0,464.6,0.00339133538795165,0 +"630","2015-02-02 22:28:59",20.73,22.5,0,464.333333333333,0.00339764298252023,0 +"631","2015-02-02 22:30:00",20.7,22.5,0,459.333333333333,0.00339133538795165,0 +"632","2015-02-02 22:31:00",20.7,22.5,0,459.75,0.00339133538795165,0 +"633","2015-02-02 22:32:00",20.7225,22.5,0,459.25,0.00339606511573662,0 +"634","2015-02-02 22:33:00",20.7,22.5,0,463,0.00339133538795165,0 +"635","2015-02-02 22:34:00",20.7225,22.445,0,461.5,0.00338771840921383,0 +"636","2015-02-02 22:34:59",20.7,22.5,0,454.5,0.00339133538795165,0 +"637","2015-02-02 22:36:00",20.7,22.5,0,458.333333333333,0.00339133538795165,0 +"638","2015-02-02 22:37:00",20.718,22.5,0,463,0.00339511870555902,0 +"639","2015-02-02 22:38:00",20.7,22.5,0,463.75,0.00339133538795165,0 +"640","2015-02-02 22:38:59",20.7,22.456,0,460.6,0.00338466735488604,0 +"641","2015-02-02 22:40:00",20.7,22.5,0,455.25,0.00339133538795165,0 +"642","2015-02-02 22:40:59",20.7,22.5,0,455.666666666667,0.00339133538795165,0 +"643","2015-02-02 22:41:59",20.7,22.5,0,456.25,0.00339133538795165,0 +"644","2015-02-02 22:43:00",20.7,22.4266666666667,0,459.666666666667,0.00338022207850367,0 +"645","2015-02-02 22:44:00",20.7,22.5,0,462,0.00339133538795165,0 +"646","2015-02-02 22:45:00",20.7225,22.4725,0,460.25,0.00339189173462569,0 +"647","2015-02-02 22:46:00",20.718,22.434,0,462,0.00338510549082456,0 +"648","2015-02-02 22:46:59",20.73,22.39,0,461,0.00338094199441115,0 +"649","2015-02-02 22:47:59",20.7,22.39,0,461.666666666667,0.00337466557189241,0 +"650","2015-02-02 22:49:00",20.745,22.39,0,460.25,0.00338408406022206,0 +"651","2015-02-02 22:50:00",20.7225,22.365,0,456.25,0.00337557814288937,0 +"652","2015-02-02 22:51:00",20.745,22.39,0,457.5,0.00338408406022206,0 +"653","2015-02-02 22:52:00",20.772,22.37,0,455.8,0.00338670186417428,0 +"654","2015-02-02 22:53:00",20.76,22.39,0,455,0.00338722869814769,0 +"655","2015-02-02 22:53:59",20.7675,22.365,0,451.25,0.00338499755586482,0 +"656","2015-02-02 22:54:59",20.745,22.39,0,453.75,0.00338408406022206,0 +"657","2015-02-02 22:56:00",20.736,22.39,0,456.2,0.00338219851219764,0 +"658","2015-02-02 22:57:00",20.73,22.3566666666667,0,453.666666666667,0.0033758812650259,0 +"659","2015-02-02 22:58:00",20.7,22.34,0,452.75,0.0033670886765457,0 +"660","2015-02-02 22:59:00",20.76,22.3566666666667,0,454,0.00338215850768072,0 +"661","2015-02-02 22:59:59",20.745,22.39,0,452.5,0.00338408406022206,0 +"662","2015-02-02 23:00:59",20.73,22.39,0,456,0.00338094199441115,0 +"663","2015-02-02 23:02:00",20.745,22.34,0,451.5,0.00337648590404306,0 +"664","2015-02-02 23:03:00",20.7,22.37,0,449.8,0.00337163479172159,0 +"665","2015-02-02 23:04:00",20.7,22.365,0,449.25,0.00337087710126894,0 +"666","2015-02-02 23:05:00",20.7,22.365,0,452.25,0.00337087710126894,0 +"667","2015-02-02 23:06:00",20.7225,22.34,0,451.25,0.00337178440632454,0 +"668","2015-02-02 23:06:59",20.7,22.34,0,453,0.0033670886765457,0 +"669","2015-02-02 23:08:00",20.7,22.39,0,453.25,0.00337466557189241,0 +"670","2015-02-02 23:09:00",20.7,22.315,0,456.666666666667,0.00336330029772187,0 +"671","2015-02-02 23:10:00",20.7,22.29,0,455.75,0.0033595119647966,0 +"672","2015-02-02 23:10:59",20.7,22.365,0,458,0.00337087710126894,0 +"673","2015-02-02 23:12:00",20.7,22.34,0,458.75,0.0033670886765457,0 +"674","2015-02-02 23:12:59",20.7,22.29,0,455.5,0.0033595119647966,0 +"675","2015-02-02 23:13:59",20.7,22.29,0,455,0.0033595119647966,0 +"676","2015-02-02 23:15:00",20.7,22.29,0,453.333333333333,0.0033595119647966,0 +"677","2015-02-02 23:16:00",20.7,22.33,0,454.6,0.00336557331950829,0 +"678","2015-02-02 23:17:00",20.7,22.29,0,457.5,0.0033595119647966,0 +"679","2015-02-02 23:18:00",20.7,22.29,0,449.666666666667,0.0033595119647966,0 +"680","2015-02-02 23:19:00",20.7,22.29,0,452,0.0033595119647966,0 +"681","2015-02-02 23:19:59",20.7,22.29,0,453.5,0.0033595119647966,0 +"682","2015-02-02 23:21:00",20.7,22.29,0,452,0.0033595119647966,0 +"683","2015-02-02 23:22:00",20.7,22.29,0,450.6,0.0033595119647966,0 +"684","2015-02-02 23:23:00",20.7,22.29,0,450.666666666667,0.0033595119647966,0 +"685","2015-02-02 23:23:59",20.7,22.29,0,451,0.0033595119647966,0 +"686","2015-02-02 23:25:00",20.7,22.29,0,454.5,0.0033595119647966,0 +"687","2015-02-02 23:25:59",20.7,22.29,0,457.25,0.0033595119647966,0 +"688","2015-02-02 23:26:59",20.7,22.315,0,456,0.00336330029772187,0 +"689","2015-02-02 23:28:00",20.675,22.29,0,456.5,0.00335431303291648,0 +"690","2015-02-02 23:29:00",20.675,22.29,0,453.5,0.00335431303291648,0 +"691","2015-02-02 23:30:00",20.7,22.29,0,454.25,0.0033595119647966,0 +"692","2015-02-02 23:31:00",20.675,22.22,0,454,0.00334372244741046,0 +"693","2015-02-02 23:31:59",20.675,22.2675,0,451,0.00335090887702669,0 +"694","2015-02-02 23:32:59",20.6666666666667,22.26,0,450.25,0.00334804512041243,0 +"695","2015-02-02 23:34:00",20.625,22.2225,0,449.75,0.00333375583115171,0 +"696","2015-02-02 23:35:00",20.675,22.2675,0,452,0.00335090887702669,0 +"697","2015-02-02 23:36:00",20.65,22.245,0,452.5,0.00334232350934395,0 +"698","2015-02-02 23:37:00",20.64,22.236,0,454,0.00333889431704007,0 +"699","2015-02-02 23:38:00",20.6333333333333,22.26,0,453,0.00334113679495563,0 +"700","2015-02-02 23:38:59",20.7,22.29,0,454,0.0033595119647966,0 +"701","2015-02-02 23:39:59",20.675,22.2675,0,450,0.00335090887702669,0 +"702","2015-02-02 23:41:00",20.625,22.245,0,451.75,0.00333714932632965,0 +"703","2015-02-02 23:42:00",20.675,22.2675,0,450.25,0.00335090887702669,0 +"704","2015-02-02 23:43:00",20.625,22.2225,0,445,0.00333375583115171,0 +"705","2015-02-02 23:44:00",20.65,22.2675,0,446.25,0.00334572233110724,0 +"706","2015-02-02 23:44:59",20.6666666666667,22.26,0,450.666666666667,0.00334804512041243,0 +"707","2015-02-02 23:45:59",20.64,22.236,0,453.6,0.00333889431704007,0 +"708","2015-02-02 23:47:00",20.6333333333333,22.23,0,450.333333333333,0.00333660976027032,0 +"709","2015-02-02 23:48:00",20.65,22.245,0,445.5,0.00334232350934395,0 +"710","2015-02-02 23:49:00",20.65,22.245,0,443,0.00334232350934395,0 +"711","2015-02-02 23:50:00",20.65,22.245,0,449.25,0.00334232350934395,0 +"712","2015-02-02 23:51:00",20.6333333333333,22.23,0,454.666666666667,0.00333660976027032,0 +"713","2015-02-02 23:51:59",20.65,22.245,0,449,0.00334232350934395,0 +"714","2015-02-02 23:53:00",20.625,22.2225,0,448.5,0.00333375583115171,0 +"715","2015-02-02 23:54:00",20.6,22.2,0,449.6,0.00332520581189891,0 +"716","2015-02-02 23:55:00",20.6,22.2,0,454,0.00332520581189891,0 +"717","2015-02-02 23:55:59",20.6,22.2225,0,451.25,0.00332859398802281,0 +"718","2015-02-02 23:57:00",20.6,22.2,0,449.333333333333,0.00332520581189891,0 +"719","2015-02-02 23:57:59",20.6,22.2,0,446,0.00332520581189891,0 +"720","2015-02-02 23:58:59",20.6,22.2225,0,445.75,0.00332859398802281,0 +"721","2015-02-03 00:00:00",20.6,22.2,0,451.5,0.00332520581189891,0 +"722","2015-02-03 00:01:00",20.6,22.2,0,455.25,0.00332520581189891,0 +"723","2015-02-03 00:02:00",20.6,22.2,0,455.25,0.00332520581189891,0 +"724","2015-02-03 00:03:00",20.6333333333333,22.23,0,451.666666666667,0.00333660976027032,0 +"725","2015-02-03 00:04:00",20.6,22.2,0,451,0.00332520581189891,0 +"726","2015-02-03 00:04:59",20.6,22.2,0,448.75,0.00332520581189891,0 +"727","2015-02-03 00:06:00",20.6,22.2,0,445.75,0.00332520581189891,0 +"728","2015-02-03 00:07:00",20.6,22.2,0,444.75,0.00332520581189891,0 +"729","2015-02-03 00:08:00",20.6,22.2,0,446.333333333333,0.00332520581189891,0 +"730","2015-02-03 00:08:59",20.6,22.2,0,450,0.00332520581189891,0 +"731","2015-02-03 00:10:00",20.575,22.2225,0,446.5,0.00332343918686436,0 +"732","2015-02-03 00:10:59",20.6,22.2225,0,446.5,0.00332859398802281,0 +"733","2015-02-03 00:11:59",20.575,22.2675,0,447.75,0.00333020509905801,0 +"734","2015-02-03 00:13:00",20.58,22.254,0,449.6,0.00332920718350033,0 +"735","2015-02-03 00:14:00",20.6,22.23,0,451.666666666667,0.00332972338822324,0 +"736","2015-02-03 00:15:00",20.6,22.26,0,450,0.00333424102982127,0 +"737","2015-02-03 00:16:00",20.6,22.2,0,449.25,0.00332520581189891,0 +"738","2015-02-03 00:16:59",20.575,22.2,0,449.75,0.00332005628567131,0 +"739","2015-02-03 00:17:59",20.55,22.2675,0,453.75,0.0033250467959681,0 +"740","2015-02-03 00:19:00",20.6,22.2,0,453,0.00332520581189891,0 +"741","2015-02-03 00:20:00",20.6,22.2,0,450.5,0.00332520581189891,0 +"742","2015-02-03 00:21:00",20.5666666666667,22.23,0,447,0.00332284953955743,0 +"743","2015-02-03 00:22:00",20.575,22.2675,0,443.75,0.00333020509905801,0 +"744","2015-02-03 00:23:00",20.6,22.2,0,444.25,0.00332520581189891,0 +"745","2015-02-03 00:23:59",20.6,22.2675,0,451.5,0.00333537045041996,0 +"746","2015-02-03 00:24:59",20.6,22.218,0,448.4,0.00332791634986075,0 +"747","2015-02-03 00:26:00",20.6,22.2,0,449,0.00332520581189891,0 +"748","2015-02-03 00:27:00",20.6,22.26,0,449.333333333333,0.00333424102982127,0 +"749","2015-02-03 00:28:00",20.6,22.2,0,446.25,0.00332520581189891,0 +"750","2015-02-03 00:29:00",20.6,22.2,0,446.6,0.00332520581189891,0 +"751","2015-02-03 00:29:59",20.6,22.2,0,447.666666666667,0.00332520581189891,0 +"752","2015-02-03 00:30:59",20.6,22.2,0,447,0.00332520581189891,0 +"753","2015-02-03 00:32:00",20.6,22.2,0,446.75,0.00332520581189891,0 +"754","2015-02-03 00:33:00",20.6,22.2,0,449.333333333333,0.00332520581189891,0 +"755","2015-02-03 00:34:00",20.58,22.2,0,451.2,0.00332108562853912,0 +"756","2015-02-03 00:35:00",20.6,22.2,0,454,0.00332520581189891,0 +"757","2015-02-03 00:36:00",20.6,22.2,0,451,0.00332520581189891,0 +"758","2015-02-03 00:36:59",20.6,22.2,0,450.25,0.00332520581189891,0 +"759","2015-02-03 00:38:00",20.6,22.2225,0,450,0.00332859398802281,0 +"760","2015-02-03 00:39:00",20.6,22.2225,0,449,0.00332859398802281,0 +"761","2015-02-03 00:40:00",20.6,22.2,0,446,0.00332520581189891,0 +"762","2015-02-03 00:40:59",20.58,22.218,0,443.2,0.00332379279008611,0 +"763","2015-02-03 00:42:00",20.5666666666667,22.26,0,443.333333333333,0.0033273578053557,0 +"764","2015-02-03 00:42:59",20.6,22.2,0,448,0.00332520581189891,0 +"765","2015-02-03 00:43:59",20.6,22.2675,0,454,0.00333537045041996,0 +"766","2015-02-03 00:45:00",20.6,22.29,0,451.5,0.00333875873669441,0 +"767","2015-02-03 00:46:00",20.6,22.29,0,451.333333333333,0.00333875873669441,0 +"768","2015-02-03 00:47:00",20.55,22.29,0,447,0.00332842453898209,0 +"769","2015-02-03 00:48:00",20.55,22.29,0,448.5,0.00332842453898209,0 +"770","2015-02-03 00:49:00",20.525,22.2225,0,450.5,0.0033131506773984,0 +"771","2015-02-03 00:49:59",20.575,22.29,0,446.5,0.00333358811005981,0 +"772","2015-02-03 00:51:00",20.6,22.29,0,447.333333333333,0.00333875873669441,0 +"773","2015-02-03 00:52:00",20.575,22.29,0,453.5,0.00333358811005981,0 +"774","2015-02-03 00:53:00",20.5666666666667,22.29,0,451.333333333333,0.00333186613615914,0 +"775","2015-02-03 00:53:59",20.58,22.254,0,449.4,0.00332920718350033,0 +"776","2015-02-03 00:55:00",20.5333333333333,22.26,0,453.666666666667,0.00332048710193108,0 +"777","2015-02-03 00:55:59",20.575,22.2,0,448.25,0.00332005628567131,0 +"778","2015-02-03 00:56:59",20.575,22.29,0,452,0.00333358811005981,0 +"779","2015-02-03 00:58:00",20.525,22.2675,0,452.666666666667,0.00331989553287361,0 +"780","2015-02-03 00:59:00",20.6,22.2,0,454.666666666667,0.00332520581189891,0 +"781","2015-02-03 01:00:00",20.6,22.254,0,453.2,0.0033333374962797,0 +"782","2015-02-03 01:01:00",20.56,22.29,0,447.6,0.0033304891212768,0 +"783","2015-02-03 01:01:59",20.6,22.29,0,447.666666666667,0.00333875873669441,0 +"784","2015-02-03 01:02:59",20.55,22.29,0,448,0.00332842453898209,0 +"785","2015-02-03 01:04:00",20.55,22.29,0,451,0.00332842453898209,0 +"786","2015-02-03 01:05:00",20.6,22.29,0,451,0.00333875873669441,0 +"787","2015-02-03 01:06:00",20.525,22.2675,0,451,0.00331989553287361,0 +"788","2015-02-03 01:07:00",20.525,22.29,0,449.75,0.00332326801517587,0 +"789","2015-02-03 01:08:00",20.52,22.29,0,453,0.00332223755535867,0 +"790","2015-02-03 01:08:59",20.5,22.2675,0,453.5,0.00331475130150607,0 +"791","2015-02-03 01:09:59",20.5,22.29,0,452.333333333333,0.00331811853036384,0 +"792","2015-02-03 01:11:00",20.525,22.29,0,452,0.00332326801517587,0 +"793","2015-02-03 01:12:00",20.6,22.26,0,450.666666666667,0.00333424102982127,0 +"794","2015-02-03 01:13:00",20.5,22.2,0,449.5,0.00330464983251252,0 +"795","2015-02-03 01:14:00",20.6,22.2225,0,449.75,0.00332859398802281,0 +"796","2015-02-03 01:14:59",20.56,22.2,0,449,0.00331696994314427,0 +"797","2015-02-03 01:15:59",20.6,22.2,0,451.333333333333,0.00332520581189891,0 +"798","2015-02-03 01:17:00",20.5666666666667,22.2,0,449,0.00331834133876291,0 +"799","2015-02-03 01:18:00",20.5666666666667,22.2,0,448,0.00331834133876291,0 +"800","2015-02-03 01:19:00",20.575,22.2,0,443.25,0.00332005628567131,0 +"801","2015-02-03 01:20:00",20.55,22.245,0,446.5,0.003321669089444,0 +"802","2015-02-03 01:21:00",20.6,22.245,0,448.75,0.00333198220086296,0 +"803","2015-02-03 01:21:59",20.6,22.2225,0,451,0.00332859398802281,0 +"804","2015-02-03 01:23:00",20.6,22.2,0,451.5,0.00332520581189891,0 +"805","2015-02-03 01:24:00",20.5666666666667,22.2,0,455,0.00331834133876291,0 +"806","2015-02-03 01:25:00",20.6,22.2,0,451.6,0.00332520581189891,0 +"807","2015-02-03 01:25:59",20.6,22.2,0,452.666666666667,0.00332520581189891,0 +"808","2015-02-03 01:27:00",20.6,22.14,0,448.2,0.00331617085506567,0 +"809","2015-02-03 01:27:59",20.6,22.125,0,445.75,0.00331391215665121,0 +"810","2015-02-03 01:28:59",20.6,22.1,0,446.666666666667,0.0033101476955541,0 +"811","2015-02-03 01:30:00",20.6,22.1,0,446.333333333333,0.0033101476955541,0 +"812","2015-02-03 01:31:00",20.6,22.125,0,444.75,0.00331391215665121,0 +"813","2015-02-03 01:32:00",20.6,22.1,0,444.5,0.0033101476955541,0 +"814","2015-02-03 01:33:00",20.58,22.14,0,446,0.0033120619260006,0 +"815","2015-02-03 01:34:00",20.5666666666667,22.1333333333333,0,443.333333333333,0.00330832334749752,0 +"816","2015-02-03 01:34:59",20.6,22.1,0,447,0.0033101476955541,0 +"817","2015-02-03 01:36:00",20.5666666666667,22.1,0,446,0.00330331447223472,0 +"818","2015-02-03 01:37:00",20.6,22.15,0,445.25,0.00331767666307384,0 +"819","2015-02-03 01:38:00",20.575,22.125,0,442,0.0033087802127036,0 +"820","2015-02-03 01:38:59",20.575,22.1,0,443,0.00330502161208519,0 +"821","2015-02-03 01:40:00",20.6,22.1,0,443,0.0033101476955541,0 +"822","2015-02-03 01:40:59",20.6,22.1,0,446.333333333333,0.0033101476955541,0 +"823","2015-02-03 01:41:59",20.6,22.1333333333333,0,449,0.00331516698708921,0 +"824","2015-02-03 01:43:00",20.6,22.125,0,445.25,0.00331391215665121,0 +"825","2015-02-03 01:44:00",20.6,22.1,0,441.25,0.0033101476955541,0 +"826","2015-02-03 01:45:00",20.575,22.175,0,441.75,0.00331629754949584,0 +"827","2015-02-03 01:46:00",20.575,22.175,0,441.5,0.00331629754949584,0 +"828","2015-02-03 01:46:59",20.6,22.1333333333333,0,445,0.00331516698708921,0 +"829","2015-02-03 01:47:59",20.575,22.125,0,446,0.0033087802127036,0 +"830","2015-02-03 01:49:00",20.55,22.2,0,442.5,0.00331491378586315,0 +"831","2015-02-03 01:50:00",20.5666666666667,22.2,0,445,0.00331834133876291,0 +"832","2015-02-03 01:51:00",20.525,22.2,0,443.5,0.00330977830422425,0 +"833","2015-02-03 01:52:00",20.56,22.2,0,443,0.00331696994314427,0 +"834","2015-02-03 01:53:00",20.6,22.2,0,444.333333333333,0.00332520581189891,0 +"835","2015-02-03 01:53:59",20.5333333333333,22.2,0,443.666666666667,0.00331148935214956,0 +"836","2015-02-03 01:54:59",20.58,22.2,0,443.4,0.00332108562853912,0 +"837","2015-02-03 01:56:00",20.6,22.2,0,447,0.00332520581189891,0 +"838","2015-02-03 01:57:00",20.6,22.2,0,446.25,0.00332520581189891,0 +"839","2015-02-03 01:58:00",20.56,22.2,0,445.6,0.00331696994314427,0 +"840","2015-02-03 01:59:00",20.55,22.2,0,448.5,0.00331491378586315,0 +"841","2015-02-03 01:59:59",20.6,22.2,0,443.666666666667,0.00332520581189891,0 +"842","2015-02-03 02:00:59",20.58,22.2,0,444.4,0.00332108562853912,0 +"843","2015-02-03 02:02:00",20.6,22.2,0,444.333333333333,0.00332520581189891,0 +"844","2015-02-03 02:03:00",20.575,22.2,0,443.5,0.00332005628567131,0 +"845","2015-02-03 02:04:00",20.5666666666667,22.23,0,451,0.00332284953955743,0 +"846","2015-02-03 02:05:00",20.575,22.2675,0,444.5,0.00333020509905801,0 +"847","2015-02-03 02:06:00",20.6,22.2225,0,443,0.00332859398802281,0 +"848","2015-02-03 02:06:59",20.5333333333333,22.2,0,445.666666666667,0.00331148935214956,0 +"849","2015-02-03 02:08:00",20.56,22.2,0,447.8,0.00331696994314427,0 +"850","2015-02-03 02:09:00",20.6,22.2,0,445,0.00332520581189891,0 +"851","2015-02-03 02:10:00",20.575,22.2,0,442.5,0.00332005628567131,0 +"852","2015-02-03 02:10:59",20.525,22.245,0,446.75,0.00331652308694799,0 +"853","2015-02-03 02:12:00",20.525,22.2675,0,442.75,0.00331989553287361,0 +"854","2015-02-03 02:12:59",20.5,22.29,0,441.333333333333,0.00331811853036384,0 +"855","2015-02-03 02:13:59",20.525,22.29,0,443.75,0.00332326801517587,0 +"856","2015-02-03 02:15:00",20.5,22.29,0,441.25,0.00331811853036384,0 +"857","2015-02-03 02:16:00",20.5,22.29,0,440.25,0.00331811853036384,0 +"858","2015-02-03 02:17:00",20.5,22.29,0,441.5,0.00331811853036384,0 +"859","2015-02-03 02:18:00",20.5,22.29,0,439.333333333333,0.00331811853036384,0 +"860","2015-02-03 02:19:00",20.5,22.29,0,439,0.00331811853036384,0 +"861","2015-02-03 02:19:59",20.5,22.29,0,445.333333333333,0.00331811853036384,0 +"862","2015-02-03 02:21:00",20.5,22.29,0,443.5,0.00331811853036384,0 +"863","2015-02-03 02:22:00",20.5,22.29,0,439.8,0.00331811853036384,0 +"864","2015-02-03 02:23:00",20.5,22.29,0,438.25,0.00331811853036384,0 +"865","2015-02-03 02:23:59",20.5,22.29,0,443,0.00331811853036384,0 +"866","2015-02-03 02:25:00",20.5,22.29,0,440.75,0.00331811853036384,0 +"867","2015-02-03 02:25:59",20.5,22.29,0,438.2,0.00331811853036384,0 +"868","2015-02-03 02:26:59",20.5,22.29,0,441.333333333333,0.00331811853036384,0 +"869","2015-02-03 02:28:00",20.5,22.29,0,438.25,0.00331811853036384,0 +"870","2015-02-03 02:29:00",20.5,22.29,0,436.5,0.00331811853036384,0 +"871","2015-02-03 02:30:00",20.5,22.29,0,439.333333333333,0.00331811853036384,0 +"872","2015-02-03 02:31:00",20.5,22.29,0,439.75,0.00331811853036384,0 +"873","2015-02-03 02:31:59",20.5,22.29,0,439.75,0.00331811853036384,0 +"874","2015-02-03 02:32:59",20.5,22.29,0,441.166666666667,0.00331811853036384,0 +"875","2015-02-03 02:34:00",20.5,22.29,0,441.666666666667,0.00331811853036384,0 +"876","2015-02-03 02:35:00",20.5,22.29,0,438.5,0.00331811853036384,0 +"877","2015-02-03 02:36:00",20.5,22.29,0,439.75,0.00331811853036384,0 +"878","2015-02-03 02:37:00",20.5,22.29,0,438.2,0.00331811853036384,0 +"879","2015-02-03 02:38:00",20.5,22.29,0,438.666666666667,0.00331811853036384,0 +"880","2015-02-03 02:38:59",20.5,22.315,0,442,0.00332185993829356,0 +"881","2015-02-03 02:39:59",20.5,22.39,0,447.75,0.00333308443071495,0 +"882","2015-02-03 02:41:00",20.5,22.3566666666667,0,442.333333333333,0.00332809571766905,0 +"883","2015-02-03 02:42:00",20.5,22.365,0,442.25,0.00332934288846831,0 +"884","2015-02-03 02:43:00",20.5,22.39,0,445.75,0.00333308443071495,0 +"885","2015-02-03 02:44:00",20.5,22.365,0,441.5,0.00332934288846831,0 +"886","2015-02-03 02:44:59",20.5,22.39,0,437.25,0.00333308443071495,0 +"887","2015-02-03 02:45:59",20.5,22.39,0,439,0.00333308443071495,0 +"888","2015-02-03 02:47:00",20.5,22.29,0,436.5,0.00331811853036384,0 +"889","2015-02-03 02:48:00",20.5,22.3233333333333,0,432.5,0.00332310708421931,0 +"890","2015-02-03 02:49:00",20.5,22.315,0,427.5,0.00332185993829356,0 +"891","2015-02-03 02:50:00",20.5,22.315,0,437.5,0.00332185993829356,0 +"892","2015-02-03 02:51:00",20.5,22.3566666666667,0,436.666666666667,0.00332809571766905,0 +"893","2015-02-03 02:51:59",20.5,22.39,0,435,0.00333308443071495,0 +"894","2015-02-03 02:53:00",20.5,22.39,0,437,0.00333308443071495,0 +"895","2015-02-03 02:54:00",20.5,22.39,0,438.666666666667,0.00333308443071495,0 +"896","2015-02-03 02:55:00",20.5,22.39,0,440.5,0.00333308443071495,0 +"897","2015-02-03 02:55:59",20.5,22.34,0,442.75,0.00332560139099478,0 +"898","2015-02-03 02:57:00",20.5,22.37,0,438,0.00333009119333576,0 +"899","2015-02-03 02:57:59",20.5,22.39,0,436.25,0.00333308443071495,0 +"900","2015-02-03 02:58:59",20.4633333333333,22.3566666666667,0,441.333333333333,0.00332053306356377,0 +"901","2015-02-03 03:00:00",20.5,22.39,0,441,0.00333308443071495,0 +"902","2015-02-03 03:01:00",20.5,22.315,0,437,0.00332185993829356,0 +"903","2015-02-03 03:02:00",20.5,22.37,0,435.2,0.00333009119333576,0 +"904","2015-02-03 03:03:00",20.5,22.3566666666667,0,433.333333333333,0.00332809571766905,0 +"905","2015-02-03 03:04:00",20.5,22.39,0,435,0.00333308443071495,0 +"906","2015-02-03 03:04:59",20.5,22.34,0,433.8,0.00332560139099478,0 +"907","2015-02-03 03:06:00",20.5,22.39,0,435.333333333333,0.00333308443071495,0 +"908","2015-02-03 03:07:00",20.5,22.39,0,437.25,0.00333308443071495,0 +"909","2015-02-03 03:08:00",20.5,22.39,0,434.4,0.00333308443071495,0 +"910","2015-02-03 03:08:59",20.5,22.39,0,431.75,0.00333308443071495,0 +"911","2015-02-03 03:10:00",20.5,22.39,0,437.333333333333,0.00333308443071495,0 +"912","2015-02-03 03:10:59",20.5,22.39,0,439.666666666667,0.00333308443071495,0 +"913","2015-02-03 03:11:59",20.478,22.37,0,435.6,0.00332554904589295,0 +"914","2015-02-03 03:13:00",20.456,22.35,0,433,0.00331802735234761,0 +"915","2015-02-03 03:14:00",20.478,22.392,0,432.6,0.00332883709371958,0 +"916","2015-02-03 03:15:00",20.5,22.39,0,435.75,0.00333308443071495,0 +"917","2015-02-03 03:16:00",20.4266666666667,22.3233333333333,0,436,0.00330801968913549,0 +"918","2015-02-03 03:16:59",20.5,22.39,0,434.5,0.00333308443071495,0 +"919","2015-02-03 03:17:59",20.478,22.392,0,435.4,0.00332883709371958,0 +"920","2015-02-03 03:19:00",20.4266666666667,22.3233333333333,0,437.333333333333,0.00330801968913549,0 +"921","2015-02-03 03:20:00",20.4175,22.3925,0,430.75,0.00331643637851585,0 +"922","2015-02-03 03:21:00",20.456,22.414,0,439.2,0.00332757946876666,0 +"923","2015-02-03 03:22:00",20.4725,22.39,0,441.5,0.00332740246984485,0 +"924","2015-02-03 03:23:00",20.4633333333333,22.3933333333333,0,445.666666666667,0.00332600811615316,0 +"925","2015-02-03 03:23:59",20.5,22.39,0,443.25,0.00333308443071495,0 +"926","2015-02-03 03:24:59",20.4175,22.3425,0,438.25,0.00330899174401155,0 +"927","2015-02-03 03:26:00",20.4633333333333,22.4633333333333,0,437,0.00333646075551332,0 +"928","2015-02-03 03:27:00",20.478,22.478,0,429.8,0.00334169070337164,0 +"929","2015-02-03 03:28:00",20.5,22.456,0,431.2,0.00334296231737792,0 +"930","2015-02-03 03:29:00",20.5,22.412,0,435.8,0.00333637702492895,0 +"931","2015-02-03 03:29:59",20.4725,22.3925,0,435.75,0.00332777598530706,0 +"932","2015-02-03 03:30:59",20.445,22.34,0,434.25,0.00331427163328817,0 +"933","2015-02-03 03:32:00",20.5,22.434,0,434.6,0.00333966965381643,0 +"934","2015-02-03 03:33:00",20.5,22.39,0,434,0.00333308443071495,0 +"935","2015-02-03 03:34:00",20.5,22.39,0,433.5,0.00333308443071495,0 +"936","2015-02-03 03:35:00",20.5,22.39,0,434.666666666667,0.00333308443071495,0 +"937","2015-02-03 03:36:00",20.5,22.39,0,437.5,0.00333308443071495,0 +"938","2015-02-03 03:36:59",20.5,22.39,0,438.5,0.00333308443071495,0 +"939","2015-02-03 03:38:00",20.5,22.4266666666667,0,436.666666666667,0.0033385721070013,0 +"940","2015-02-03 03:39:00",20.5,22.445,0,431.166666666667,0.00334131598126289,0 +"941","2015-02-03 03:40:00",20.5,22.39,0,436,0.00333308443071495,0 +"942","2015-02-03 03:40:59",20.4725,22.3925,0,438.25,0.00332777598530706,0 +"943","2015-02-03 03:42:00",20.5,22.4633333333333,0,439,0.00334405987960385,0 +"944","2015-02-03 03:42:59",20.5,22.456,0,436.6,0.00334296231737792,0 +"945","2015-02-03 03:43:59",20.5,22.39,0,432.666666666667,0.00333308443071495,0 +"946","2015-02-03 03:45:00",20.5,22.39,0,433.25,0.00333308443071495,0 +"947","2015-02-03 03:46:00",20.4725,22.39,0,433.5,0.00332740246984485,0 +"948","2015-02-03 03:47:00",20.4725,22.4175,0,435.75,0.00333151116447087,0 +"949","2015-02-03 03:48:00",20.5,22.5,0,436,0.00334954774852514,0 +"950","2015-02-03 03:49:00",20.5,22.478,0,430.8,0.00334625501561398,0 +"951","2015-02-03 03:49:59",20.434,22.412,0,435.4,0.00332274112706532,0 +"952","2015-02-03 03:51:00",20.4175,22.34,0,433.5,0.00330861951693947,0 +"953","2015-02-03 03:52:00",20.39,22.39,0,429.75,0.00331040775412912,0 +"954","2015-02-03 03:53:00",20.39,22.39,0,430,0.00331040775412912,0 +"955","2015-02-03 03:53:59",20.39,22.39,0,433,0.00331040775412912,0 +"956","2015-02-03 03:55:00",20.39,22.39,0,436.25,0.00331040775412912,0 +"957","2015-02-03 03:55:59",20.39,22.39,0,433.5,0.00331040775412912,0 +"958","2015-02-03 03:56:59",20.39,22.5,0,434.25,0.00332675846769344,0 +"959","2015-02-03 03:58:00",20.39,22.4633333333333,0,430.333333333333,0.00332130813483038,0 +"960","2015-02-03 03:59:00",20.39,22.5,0,429.6,0.00332675846769344,0 +"961","2015-02-03 04:00:00",20.39,22.5,0,433.5,0.00332675846769344,0 +"962","2015-02-03 04:01:00",20.39,22.5,0,435.6,0.00332675846769344,0 +"963","2015-02-03 04:01:59",20.39,22.5,0,434.666666666667,0.00332675846769344,0 +"964","2015-02-03 04:02:59",20.39,22.5,0,432.333333333333,0.00332675846769344,0 +"965","2015-02-03 04:04:00",20.39,22.5,0,438,0.00332675846769344,0 +"966","2015-02-03 04:05:00",20.39,22.5,0,436.5,0.00332675846769344,0 +"967","2015-02-03 04:06:00",20.39,22.5,0,440.75,0.00332675846769344,0 +"968","2015-02-03 04:07:00",20.39,22.5,0,438,0.00332675846769344,0 +"969","2015-02-03 04:08:00",20.39,22.5,0,434.75,0.00332675846769344,0 +"970","2015-02-03 04:08:59",20.39,22.5,0,434.75,0.00332675846769344,0 +"971","2015-02-03 04:09:59",20.39,22.5,0,435.666666666667,0.00332675846769344,0 +"972","2015-02-03 04:11:00",20.39,22.5,0,434,0.00332675846769344,0 +"973","2015-02-03 04:12:00",20.35,22.5,0,429.2,0.00331850539059036,0 +"974","2015-02-03 04:13:00",20.39,22.5,0,431.5,0.00332675846769344,0 +"975","2015-02-03 04:14:00",20.39,22.5,0,430,0.00332675846769344,0 +"976","2015-02-03 04:14:59",20.39,22.5,0,434,0.00332675846769344,0 +"977","2015-02-03 04:15:59",20.39,22.5,0,434.25,0.00332675846769344,0 +"978","2015-02-03 04:17:00",20.39,22.5,0,432.4,0.00332675846769344,0 +"979","2015-02-03 04:18:00",20.39,22.4633333333333,0,434.333333333333,0.00332130813483038,0 +"980","2015-02-03 04:19:00",20.39,22.5,0,436.4,0.00332675846769344,0 +"981","2015-02-03 04:20:00",20.39,22.5,0,435.75,0.00332675846769344,0 +"982","2015-02-03 04:21:00",20.39,22.5,0,435.2,0.00332675846769344,0 +"983","2015-02-03 04:21:59",20.39,22.5,0,436.75,0.00332675846769344,0 +"984","2015-02-03 04:23:00",20.39,22.5,0,438.25,0.00332675846769344,0 +"985","2015-02-03 04:24:00",20.39,22.5,0,438.75,0.00332675846769344,0 +"986","2015-02-03 04:25:00",20.39,22.4725,0,437.5,0.00332267070913894,0 +"987","2015-02-03 04:25:59",20.39,22.4633333333333,0,439.333333333333,0.00332130813483038,0 +"988","2015-02-03 04:27:00",20.39,22.5,0,437.5,0.00332675846769344,0 +"989","2015-02-03 04:27:59",20.39,22.5,0,433.6,0.00332675846769344,0 +"990","2015-02-03 04:28:59",20.39,22.5,0,431.333333333333,0.00332675846769344,0 +"991","2015-02-03 04:30:00",20.39,22.5,0,434.8,0.00332675846769344,0 +"992","2015-02-03 04:31:00",20.39,22.4633333333333,0,433.333333333333,0.00332130813483038,0 +"993","2015-02-03 04:32:00",20.39,22.4725,0,433.8,0.00332267070913894,0 +"994","2015-02-03 04:33:00",20.39,22.5,0,436.5,0.00332675846769344,0 +"995","2015-02-03 04:34:00",20.39,22.5,0,434,0.00332675846769344,0 +"996","2015-02-03 04:34:59",20.39,22.4725,0,433.75,0.00332267070913894,0 +"997","2015-02-03 04:36:00",20.39,22.445,0,435.5,0.00331858300402743,0 +"998","2015-02-03 04:37:00",20.39,22.4266666666667,0,434.333333333333,0.00331585789697644,0 +"999","2015-02-03 04:38:00",20.39,22.5,0,431.75,0.00332675846769344,0 +"1000","2015-02-03 04:38:59",20.39,22.5,0,431.5,0.00332675846769344,0 +"1001","2015-02-03 04:40:00",20.39,22.5,0,432.5,0.00332675846769344,0 +"1002","2015-02-03 04:40:59",20.39,22.456,0,435.4,0.00332021807965894,0 +"1003","2015-02-03 04:41:59",20.39,22.5,0,436.666666666667,0.00332675846769344,0 +"1004","2015-02-03 04:43:00",20.39,22.5,0,432.6,0.00332675846769344,0 +"1005","2015-02-03 04:44:00",20.39,22.4633333333333,0,433,0.00332130813483038,0 +"1006","2015-02-03 04:45:00",20.39,22.445,0,431.5,0.00331858300402743,0 +"1007","2015-02-03 04:46:00",20.39,22.5,0,431.8,0.00332675846769344,0 +"1008","2015-02-03 04:46:59",20.39,22.5,0,439.666666666667,0.00332675846769344,0 +"1009","2015-02-03 04:47:59",20.39,22.5,0,436.666666666667,0.00332675846769344,0 +"1010","2015-02-03 04:49:00",20.39,22.5,0,439,0.00332675846769344,0 +"1011","2015-02-03 04:50:00",20.39,22.5,0,436.25,0.00332675846769344,0 +"1012","2015-02-03 04:51:00",20.39,22.5,0,435.8,0.00332675846769344,0 +"1013","2015-02-03 04:52:00",20.39,22.4266666666667,0,438.333333333333,0.00331585789697644,0 +"1014","2015-02-03 04:53:00",20.39,22.4725,0,436,0.00332267070913894,0 +"1015","2015-02-03 04:53:59",20.39,22.5,0,433.666666666667,0.00332675846769344,0 +"1016","2015-02-03 04:54:59",20.39,22.5,0,432.25,0.00332675846769344,0 +"1017","2015-02-03 04:56:00",20.39,22.5,0,433.5,0.00332675846769344,0 +"1018","2015-02-03 04:57:00",20.39,22.5,0,436.25,0.00332675846769344,0 +"1019","2015-02-03 04:58:00",20.39,22.5,0,435,0.00332675846769344,0 +"1020","2015-02-03 04:59:00",20.39,22.5,0,433.75,0.00332675846769344,0 +"1021","2015-02-03 04:59:59",20.39,22.5,0,440.666666666667,0.00332675846769344,0 +"1022","2015-02-03 05:00:59",20.39,22.5,0,441.2,0.00332675846769344,0 +"1023","2015-02-03 05:02:00",20.39,22.5,0,435.25,0.00332675846769344,0 +"1024","2015-02-03 05:03:00",20.39,22.5,0,437.25,0.00332675846769344,0 +"1025","2015-02-03 05:04:00",20.39,22.5,0,435.5,0.00332675846769344,0 +"1026","2015-02-03 05:05:00",20.39,22.5,0,439.75,0.00332675846769344,0 +"1027","2015-02-03 05:06:00",20.39,22.5,0,438,0.00332675846769344,0 +"1028","2015-02-03 05:06:59",20.39,22.5,0,435.25,0.00332675846769344,0 +"1029","2015-02-03 05:08:00",20.39,22.5,0,434.2,0.00332675846769344,0 +"1030","2015-02-03 05:09:00",20.39,22.5,0,435,0.00332675846769344,0 +"1031","2015-02-03 05:10:00",20.365,22.5,0,436.5,0.00332159817811205,0 +"1032","2015-02-03 05:10:59",20.39,22.5,0,434,0.00332675846769344,0 +"1033","2015-02-03 05:12:00",20.39,22.5,0,435.25,0.00332675846769344,0 +"1034","2015-02-03 05:12:59",20.39,22.5,0,432.75,0.00332675846769344,0 +"1035","2015-02-03 05:13:59",20.39,22.5,0,432,0.00332675846769344,0 +"1036","2015-02-03 05:15:00",20.39,22.5,0,432,0.00332675846769344,0 +"1037","2015-02-03 05:16:00",20.39,22.5,0,431.5,0.00332675846769344,0 +"1038","2015-02-03 05:17:00",20.39,22.5,0,435,0.00332675846769344,0 +"1039","2015-02-03 05:18:00",20.39,22.5,0,437.666666666667,0.00332675846769344,0 +"1040","2015-02-03 05:19:00",20.39,22.5,0,437.333333333333,0.00332675846769344,0 +"1041","2015-02-03 05:19:59",20.365,22.5,0,438,0.00332159817811205,0 +"1042","2015-02-03 05:21:00",20.365,22.5,0,434.25,0.00332159817811205,0 +"1043","2015-02-03 05:22:00",20.34,22.575,0,435.75,0.00332755889929759,0 +"1044","2015-02-03 05:23:00",20.315,22.6,0,433.25,0.00332609433192358,0 +"1045","2015-02-03 05:23:59",20.315,22.6,0,434.75,0.00332609433192358,0 +"1046","2015-02-03 05:25:00",20.3566666666667,22.6,0,439,0.0033347137758515,0 +"1047","2015-02-03 05:25:59",20.34,22.6,0,439.25,0.00333126363950143,0 +"1048","2015-02-03 05:26:59",20.365,22.575,0,438.5,0.00333272949673482,0 +"1049","2015-02-03 05:28:00",20.29,22.6,0,437.6,0.00332093209327951,0 +"1050","2015-02-03 05:29:00",20.29,22.6,0,434.5,0.00332093209327951,0 +"1051","2015-02-03 05:30:00",20.29,22.6,0,435.5,0.00332093209327951,0 +"1052","2015-02-03 05:31:00",20.3233333333333,22.6,0,436,0.00332781664860126,0 +"1053","2015-02-03 05:31:59",20.29,22.6,0,435.2,0.00332093209327951,0 +"1054","2015-02-03 05:32:59",20.3233333333333,22.6,0,433.666666666667,0.00332781664860126,0 +"1055","2015-02-03 05:34:00",20.29,22.6,0,434.25,0.00332093209327951,0 +"1056","2015-02-03 05:35:00",20.29,22.625,0,440.5,0.00332462532631483,0 +"1057","2015-02-03 05:36:00",20.29,22.6333333333333,0,440.666666666667,0.00332585641368785,0 +"1058","2015-02-03 05:37:00",20.29,22.675,0,438,0.00333201192326353,0 +"1059","2015-02-03 05:38:00",20.29,22.7,0,433.8,0.00333570528717845,0 +"1060","2015-02-03 05:38:59",20.29,22.7,0,435,0.00333570528717845,0 +"1061","2015-02-03 05:39:59",20.29,22.7,0,434.75,0.00333570528717845,0 +"1062","2015-02-03 05:41:00",20.29,22.7,0,437.333333333333,0.00333570528717845,0 +"1063","2015-02-03 05:42:00",20.29,22.7,0,439.5,0.00333570528717845,0 +"1064","2015-02-03 05:43:00",20.29,22.65,0,432.75,0.00332831860297592,0 +"1065","2015-02-03 05:44:00",20.29,22.6,0,435,0.00332093209327951,0 +"1066","2015-02-03 05:44:59",20.29,22.7,0,436.5,0.00333570528717845,0 +"1067","2015-02-03 05:45:59",20.29,22.675,0,434.666666666667,0.00333201192326353,0 +"1068","2015-02-03 05:47:00",20.29,22.7,0,436,0.00333570528717845,0 +"1069","2015-02-03 05:48:00",20.29,22.7,0,441.5,0.00333570528717845,0 +"1070","2015-02-03 05:49:00",20.29,22.7,0,436,0.00333570528717845,0 +"1071","2015-02-03 05:50:00",20.29,22.675,0,435.75,0.00333201192326353,0 +"1072","2015-02-03 05:51:00",20.29,22.65,0,431,0.00332831860297592,0 +"1073","2015-02-03 05:51:59",20.29,22.7,0,434,0.00333570528717845,0 +"1074","2015-02-03 05:53:00",20.29,22.7,0,436,0.00333570528717845,0 +"1075","2015-02-03 05:54:00",20.29,22.7,0,436.5,0.00333570528717845,0 +"1076","2015-02-03 05:55:00",20.29,22.7,0,436.5,0.00333570528717845,0 +"1077","2015-02-03 05:55:59",20.29,22.7,0,436.25,0.00333570528717845,0 +"1078","2015-02-03 05:57:00",20.29,22.7,0,437.666666666667,0.00333570528717845,0 +"1079","2015-02-03 05:57:59",20.29,22.7,0,432.25,0.00333570528717845,0 +"1080","2015-02-03 05:58:59",20.29,22.7,0,429.333333333333,0.00333570528717845,0 +"1081","2015-02-03 06:00:00",20.29,22.7,0,432.25,0.00333570528717845,0 +"1082","2015-02-03 06:01:00",20.272,22.68,0,437,0.00332902487101743,0 +"1083","2015-02-03 06:02:00",20.26,22.6666666666667,0,433.333333333333,0.00332457700340578,0 +"1084","2015-02-03 06:03:00",20.29,22.7,0,427.6,0.00333570528717845,0 +"1085","2015-02-03 06:04:00",20.29,22.7,0,436,0.00333570528717845,0 +"1086","2015-02-03 06:04:59",20.29,22.7,0,436.333333333333,0.00333570528717845,0 +"1087","2015-02-03 06:06:00",20.29,22.7,0,435.25,0.00333570528717845,0 +"1088","2015-02-03 06:07:00",20.29,22.7,0,436.25,0.00333570528717845,0 +"1089","2015-02-03 06:08:00",20.29,22.7,0,434.25,0.00333570528717845,0 +"1090","2015-02-03 06:08:59",20.29,22.7225,0,436,0.00333902935200387,0 +"1091","2015-02-03 06:10:00",20.2675,22.7,0,434.5,0.00333104455852738,0 +"1092","2015-02-03 06:10:59",20.26,22.76,0,435.666666666667,0.00333833991077244,0 +"1093","2015-02-03 06:11:59",20.29,22.7,0,433,0.00333570528717845,0 +"1094","2015-02-03 06:13:00",20.29,22.7,0,428.25,0.00333570528717845,0 +"1095","2015-02-03 06:14:00",20.29,22.7,0,434.2,0.00333570528717845,0 +"1096","2015-02-03 06:15:00",20.2675,22.675,0,437,0.0033273563825288,0 +"1097","2015-02-03 06:16:00",20.2675,22.72,0,433.666666666667,0.00333399513065048,0 +"1098","2015-02-03 06:16:59",20.29,22.76,0,434,0.00334456953857831,0 +"1099","2015-02-03 06:17:59",20.29,22.772,0,439.6,0.00334634241901495,0 +"1100","2015-02-03 06:19:00",20.29,22.79,0,435.666666666667,0.00334900175851823,0 +"1101","2015-02-03 06:20:00",20.29,22.7675,0,431,0.00334567758767319,0 +"1102","2015-02-03 06:21:00",20.29,22.76,0,433.333333333333,0.00334456953857831,0 +"1103","2015-02-03 06:22:00",20.29,22.7,0,434.5,0.00333570528717845,0 +"1104","2015-02-03 06:23:00",20.29,22.7,0,435,0.00333570528717845,0 +"1105","2015-02-03 06:23:59",20.29,22.7,0,437.75,0.00333570528717845,0 +"1106","2015-02-03 06:24:59",20.29,22.79,0,438.333333333333,0.00334900175851823,0 +"1107","2015-02-03 06:26:00",20.29,22.7225,0,438,0.00333902935200387,0 +"1108","2015-02-03 06:27:00",20.29,22.7,0,431.75,0.00333570528717845,0 +"1109","2015-02-03 06:28:00",20.29,22.7675,0,432.75,0.00334567758767319,0 +"1110","2015-02-03 06:29:00",20.29,22.7225,0,431.25,0.00333902935200387,0 +"1111","2015-02-03 06:29:59",20.29,22.7,0,437.25,0.00333570528717845,0 +"1112","2015-02-03 06:30:59",20.3233333333333,22.7,0,434.333333333333,0.00334262063221122,0 +"1113","2015-02-03 06:32:00",20.365,22.7,0,429.5,0.00335128257512357,0 +"1114","2015-02-03 06:33:00",20.39,22.7,0,430,0.00335648922862046,0 +"1115","2015-02-03 06:34:00",20.39,22.7,0,434,0.00335648922862046,0 +"1116","2015-02-03 06:35:00",20.39,22.7,0,437.75,0.00335648922862046,0 +"1117","2015-02-03 06:36:00",20.39,22.7,0,434.666666666667,0.00335648922862046,0 +"1118","2015-02-03 06:36:59",20.39,22.7,0,431.75,0.00335648922862046,0 +"1119","2015-02-03 06:38:00",20.39,22.65,0,437.5,0.00334905627335497,0 +"1120","2015-02-03 06:39:00",20.39,22.68,0,433.8,0.00335351602531066,0 +"1121","2015-02-03 06:40:00",20.39,22.7,0,435.8,0.00335648922862046,0 +"1122","2015-02-03 06:40:59",20.39,22.7,0,437.666666666667,0.00335648922862046,0 +"1123","2015-02-03 06:42:00",20.39,22.7,0,434.25,0.00335648922862046,0 +"1124","2015-02-03 06:42:59",20.39,22.675,0,433,0.00335277272890065,0 +"1125","2015-02-03 06:43:59",20.39,22.7,0,436.25,0.00335648922862046,0 +"1126","2015-02-03 06:45:00",20.37,22.7,0,436.8,0.00335232333614086,0 +"1127","2015-02-03 06:46:00",20.3233333333333,22.7,0,438,0.00334262063221122,0 +"1128","2015-02-03 06:47:00",20.29,22.7225,0,438.75,0.00333902935200387,0 +"1129","2015-02-03 06:48:00",20.29,22.745,0,439.5,0.0033423534521686,0 +"1130","2015-02-03 06:49:00",20.29,22.79,0,441.25,0.00334900175851823,0 +"1131","2015-02-03 06:49:59",20.29,22.79,0,432,0.00334900175851823,0 +"1132","2015-02-03 06:51:00",20.29,22.79,0,431.666666666667,0.00334900175851823,0 +"1133","2015-02-03 06:52:00",20.29,22.79,0,435,0.00334900175851823,0 +"1134","2015-02-03 06:53:00",20.29,22.79,0,435.75,0.00334900175851823,0 +"1135","2015-02-03 06:53:59",20.26,22.79,0,436.333333333333,0.00334276383108678,0 +"1136","2015-02-03 06:55:00",20.29,22.84,0,436,0.00335638893137085,0 +"1137","2015-02-03 06:55:59",20.2675,22.84,0,439.25,0.00335169914813076,0 +"1138","2015-02-03 06:56:59",20.245,22.815,0,435,0.00334333190248453,0 +"1139","2015-02-03 06:58:00",20.236,22.83,0,431.4,0.00334367068060774,0 +"1140","2015-02-03 06:59:00",20.29,22.89,0,435.333333333333,0.00336377627875311,0 +"1141","2015-02-03 07:00:00",20.2,22.79,0,439.666666666667,0.00333031868245807,0 +"1142","2015-02-03 07:01:00",20.218,22.81,0,431.4,0.00333698951696175,0 +"1143","2015-02-03 07:01:59",20.245,22.84,0,431,0.00334701513999229,0 +"1144","2015-02-03 07:02:59",20.2,22.79,0,431.75,0.00333031868245807,0 +"1145","2015-02-03 07:04:00",20.245,22.84,0,437.75,0.00334701513999229,0 +"1146","2015-02-03 07:05:00",20.2675,22.865,0,436.75,0.00335538761128267,0 +"1147","2015-02-03 07:06:00",20.2,22.79,0,432,0.00333031868245807,0 +"1148","2015-02-03 07:07:00",20.2225,22.815,0,433.25,0.0033386588389997,0 +"1149","2015-02-03 07:08:00",20.2,22.79,0,434.5,0.00333031868245807,0 +"1150","2015-02-03 07:08:59",20.2,22.79,0,436.5,0.00333031868245807,0 +"1151","2015-02-03 07:09:59",20.2225,22.815,0,438.25,0.0033386588389997,0 +"1152","2015-02-03 07:11:00",20.2,22.79,0,439,0.00333031868245807,0 +"1153","2015-02-03 07:12:00",20.2,22.815,0,441.2,0.0033339915319245,0 +"1154","2015-02-03 07:13:00",20.2225,22.8675,0,435.25,0.00334638281882292,0 +"1155","2015-02-03 07:14:00",20.2,22.89,0,433.75,0.00334501033919613,0 +"1156","2015-02-03 07:14:59",20.2,22.89,0,439.25,0.00334501033919613,0 +"1157","2015-02-03 07:15:59",20.2,22.89,0,442,0.00334501033919613,0 +"1158","2015-02-03 07:17:00",20.2,22.89,0,445.333333333333,0.00334501033919613,0 +"1159","2015-02-03 07:18:00",20.2,22.89,0,440.6,0.00334501033919613,0 +"1160","2015-02-03 07:19:00",20.2,22.89,0,440.666666666667,0.00334501033919613,0 +"1161","2015-02-03 07:20:00",20.236,22.83,0,440.2,0.00334367068060774,0 +"1162","2015-02-03 07:21:00",20.29,22.84,0,439.5,0.00335638893137085,0 +"1163","2015-02-03 07:21:59",20.29,22.79,0,441.666666666667,0.00334900175851823,0 +"1164","2015-02-03 07:23:00",20.29,22.79,0,440.5,0.00334900175851823,0 +"1165","2015-02-03 07:24:00",20.29,22.79,0,437,0.00334900175851823,0 +"1166","2015-02-03 07:25:00",20.29,22.79,0,439,0.00334900175851823,0 +"1167","2015-02-03 07:25:59",20.29,22.79,0,438.5,0.00334900175851823,0 +"1168","2015-02-03 07:27:00",20.29,22.79,0,438.5,0.00334900175851823,0 +"1169","2015-02-03 07:27:59",20.315,22.79,0,440.25,0.00335420786423315,0 +"1170","2015-02-03 07:28:59",20.3566666666667,22.7,0,445,0.003349548606077,0 +"1171","2015-02-03 07:30:00",20.34,22.745,0,442.75,0.0033527519983685,0 +"1172","2015-02-03 07:31:00",20.34,22.7225,0,439.75,0.00334941750105436,0 +"1173","2015-02-03 07:32:00",20.315,22.7675,0,434.5,0.00335087849819304,0 +"1174","2015-02-03 07:33:00",20.315,22.7675,0,437.5,0.00335087849819304,0 +"1175","2015-02-03 07:34:00",20.29,22.79,0,440,0.00334900175851823,0 +"1176","2015-02-03 07:34:59",20.29,22.79,0,438,0.00334900175851823,0 +"1177","2015-02-03 07:36:00",20.29,22.79,217.2,441.6,0.00334900175851823,1 +"1178","2015-02-03 07:37:00",20.29,22.8566666666667,413.666666666667,442.666666666667,0.00335885136110578,1 +"1179","2015-02-03 07:38:00",20.29,22.956,433,445.6,0.00337352784454795,1 +"1180","2015-02-03 07:38:59",20.29,23,419,453,0.00338002905736888,0 +"1181","2015-02-03 07:40:00",20.315,23.1,419,459.25,0.00340008273894569,0 +"1182","2015-02-03 07:40:59",20.29,23.2,419,470.4,0.003409581728402,0 +"1183","2015-02-03 07:41:59",20.31,23.2,416.2,466,0.00341382178221691,0 +"1184","2015-02-03 07:43:00",20.31,23.2,415,470.8,0.00341382178221691,1 +"1185","2015-02-03 07:44:00",20.33,23.2,412.2,476.6,0.00341806648197945,1 +"1186","2015-02-03 07:45:00",20.39,23.2,412.2,473,0.00343082850079598,1 +"1187","2015-02-03 07:46:00",20.365,23.245,413.5,473,0.00343218686244567,1 +"1188","2015-02-03 07:46:59",20.39,23.34,403.5,479.75,0.0034516466643212,1 +"1189","2015-02-03 07:47:59",20.39,23.434,397.4,494.2,0.00346562535180023,1 +"1190","2015-02-03 07:49:00",20.39,23.5,399.5,498.75,0.0034754405483064,1 +"1191","2015-02-03 07:50:00",20.39,23.66,397.4,501,0.00349923624272876,1 +"1192","2015-02-03 07:51:00",20.39,23.7,398.333333333333,507,0.00350518544923937,1 +"1193","2015-02-03 07:52:00",20.39,23.7,399.5,518,0.00350518544923937,1 +"1194","2015-02-03 07:53:00",20.445,23.8175,403,520,0.00353471318077689,1 +"1195","2015-02-03 07:53:59",20.5,23.89,407.666666666667,523.666666666667,0.00355765893071744,1 +"1196","2015-02-03 07:54:59",20.5,23.978,412.2,525.2,0.00357083897726138,1 +"1197","2015-02-03 07:56:00",20.5,24.0333333333333,413,531.333333333333,0.00357912671517753,1 +"1198","2015-02-03 07:57:00",20.5,24.1,414,538,0.00358911223325629,1 +"1199","2015-02-03 07:58:00",20.5,24.1,412.2,536.4,0.00358911223325629,1 +"1200","2015-02-03 07:59:00",20.5,24.1,413,538.333333333333,0.00358911223325629,1 +"1201","2015-02-03 07:59:59",20.5,24.18,412.2,541,0.00360109527574641,1 +"1202","2015-02-03 08:00:59",20.52,24.236,407.4,549.6,0.0036139664870275,1 +"1203","2015-02-03 08:02:00",20.5,24.3233333333333,407,555.166666666667,0.0036225660416438,1 +"1204","2015-02-03 08:03:00",20.5,24.39,405,561.5,0.00363255294654218,1 +"1205","2015-02-03 08:04:00",20.5,24.39,405,569,0.00363255294654218,1 +"1206","2015-02-03 08:05:00",20.56,24.39,405,568.2,0.00364610264536675,1 +"1207","2015-02-03 08:06:00",20.55,24.39,412,572,0.00364384127303786,1 +"1208","2015-02-03 08:06:59",20.55,24.39,416.666666666667,573.166666666667,0.00364384127303786,1 +"1209","2015-02-03 08:08:00",20.58,24.39,419,583,0.00365062910171658,1 +"1210","2015-02-03 08:09:00",20.6,24.39,419,585,0.00365516051087822,1 +"1211","2015-02-03 08:10:00",20.6666666666667,24.39,419,584.666666666667,0.00367030103838176,1 +"1212","2015-02-03 08:10:59",20.7,24.37,419,584.8,0.00367485829249482,1 +"1213","2015-02-03 08:12:00",20.7,24.39,419,591.4,0.00367789201244977,1 +"1214","2015-02-03 08:12:59",20.7,24.39,419,594.333333333333,0.00367789201244977,1 +"1215","2015-02-03 08:13:59",20.7,24.39,419,600.5,0.00367789201244977,1 +"1216","2015-02-03 08:15:00",20.736,24.39,419,601.4,0.0036861058054682,1 +"1217","2015-02-03 08:16:00",20.73,24.39,419,606,0.00368473571810374,1 +"1218","2015-02-03 08:17:00",20.7,24.5,419,608.75,0.00369457799808589,1 +"1219","2015-02-03 08:18:00",20.754,24.5,419,616.8,0.00370696100370173,1 +"1220","2015-02-03 08:19:00",20.79,24.5,419,624.2,0.00371523665252415,1 +"1221","2015-02-03 08:19:59",20.772,24.52,419,625.6,0.00371414435124831,1 +"1222","2015-02-03 08:21:00",20.7675,24.6,419,628.75,0.00372529627333651,1 +"1223","2015-02-03 08:22:00",20.754,24.66,419,635.2,0.00373131495431088,1 +"1224","2015-02-03 08:23:00",20.772,24.7,419,640.8,0.0037415736966499,1 +"1225","2015-02-03 08:23:59",20.79,24.7,421.8,642.4,0.00374574775610345,1 +"1226","2015-02-03 08:25:00",20.79,24.7,422.5,643.25,0.00374574775610345,1 +"1227","2015-02-03 08:25:59",20.79,24.736,427.4,643.6,0.00375124007075525,1 +"1228","2015-02-03 08:26:59",20.79,24.79,433,645.25,0.00375947872351275,1 +"1229","2015-02-03 08:28:00",20.775,24.79,433,652.666666666667,0.00375598722728803,1 +"1230","2015-02-03 08:29:00",20.79,24.79,433,658,0.00375947872351275,1 +"1231","2015-02-03 08:30:00",20.79,24.79,433,665.5,0.00375947872351275,1 +"1232","2015-02-03 08:31:00",20.79,24.79,433,666.333333333333,0.00375947872351275,1 +"1233","2015-02-03 08:31:59",20.79,24.79,433,666.5,0.00375947872351275,1 +"1234","2015-02-03 08:32:59",20.79,24.79,433,668.2,0.00375947872351275,1 +"1235","2015-02-03 08:34:00",20.79,24.79,433,668,0.00375947872351275,1 +"1236","2015-02-03 08:35:00",20.79,24.79,433,672.666666666667,0.00375947872351275,1 +"1237","2015-02-03 08:36:00",20.79,24.79,433,672.75,0.00375947872351275,1 +"1238","2015-02-03 08:37:00",20.79,24.79,433,679.2,0.00375947872351275,1 +"1239","2015-02-03 08:38:00",20.815,24.815,433,683.5,0.0037691244531884,1 +"1240","2015-02-03 08:38:59",20.79,24.79,440,688.5,0.00375947872351275,1 +"1241","2015-02-03 08:39:59",20.84,24.84,434.5,686,0.00377879009466567,1 +"1242","2015-02-03 08:41:00",20.79,24.79,435.5,689.75,0.00375947872351275,1 +"1243","2015-02-03 08:42:00",20.89,24.89,443.4,700,0.00379818125119672,1 +"1244","2015-02-03 08:43:00",20.83,24.83,439.8,697.6,0.00377492144644985,1 +"1245","2015-02-03 08:44:00",20.87,24.87,439.8,695.8,0.00379041519663829,1 +"1246","2015-02-03 08:44:59",20.89,24.8733333333333,441,697.333333333333,0.00379562241977668,1 +"1247","2015-02-03 08:45:59",20.89,24.89,442.5,701.25,0.00379818125119672,1 +"1248","2015-02-03 08:47:00",20.8733333333333,24.84,441,700.666666666667,0.00378659635900053,1 +"1249","2015-02-03 08:48:00",20.8733333333333,24.775,441,694.833333333333,0.00377662763133105,1 +"1250","2015-02-03 08:49:00",20.89,24.84,442.5,709.75,0.00379050481971304,1 +"1251","2015-02-03 08:50:00",20.89,24.8566666666667,435,715,0.0037930636092822,1 +"1252","2015-02-03 08:51:00",20.89,24.8233333333333,435,715.833333333333,0.00378794605106893,1 +"1253","2015-02-03 08:51:59",20.89,24.79,429,713.8,0.00378282857655485,1 +"1254","2015-02-03 08:53:00",20.9266666666667,24.79,429,709,0.00379142216717855,1 +"1255","2015-02-03 08:54:00",20.89,24.85,429,716.2,0.00379204009094351,1 +"1256","2015-02-03 08:55:00",20.89,24.89,429,716.166666666667,0.00379818125119672,1 +"1257","2015-02-03 08:55:59",20.89,24.945,432.75,725,0.003806625543353,1 +"1258","2015-02-03 08:57:00",20.89,24.9175,429,725,0.003802403368789,1 +"1259","2015-02-03 08:57:59",20.89,24.978,435,727.6,0.00381169222803407,1 +"1260","2015-02-03 08:58:59",20.89,25,435,729.4,0.00381507006340074,1 +"1261","2015-02-03 09:00:00",20.89,25,441,730.8,0.00381507006340074,1 +"1262","2015-02-03 09:01:00",20.89,25,438,731.2,0.00381507006340074,1 +"1263","2015-02-03 09:02:00",20.9175,25,444,736.25,0.003821568899283,1 +"1264","2015-02-03 09:03:00",20.978,25,441,741,0.00383590070431204,1 +"1265","2015-02-03 09:04:00",21,24.9633333333333,444,742.333333333333,0.00383545561825104,1 +"1266","2015-02-03 09:04:59",21,24.912,444,742.4,0.0038275200483029,1 +"1267","2015-02-03 09:06:00",21.025,24.89,444,746.75,0.00383003585980888,1 +"1268","2015-02-03 09:07:00",21.075,24.89,444,745,0.00384189349251253,1 +"1269","2015-02-03 09:08:00",21.1,24.89,444,742,0.00384783443575005,1 +"1270","2015-02-03 09:08:59",21.1,24.89,444,740.8,0.00384783443575005,1 +"1271","2015-02-03 09:10:00",21.1333333333333,24.8233333333333,444,747.333333333333,0.00384537695364168,0 +"1272","2015-02-03 09:10:59",21.1666666666667,24.8583333333333,444,745.5,0.00385877039769743,0 +"1273","2015-02-03 09:11:59",21.2,25.1633333333333,444,752.666666666667,0.00391446429048382,1 +"1274","2015-02-03 09:13:00",21.175,25.0404166666667,446.666666666667,751.5,0.00388921341469932,1 +"1275","2015-02-03 09:14:00",21.15,24.9175,449.333333333333,750.333333333333,0.00386403159400571,1 +"1276","2015-02-03 09:15:00",21.1833333333333,25.1983333333333,454.666666666667,754.333333333333,0.00391591015445099,1 +"1277","2015-02-03 09:16:00",21.2,25.34,448,765.75,0.00394212113144808,1 +"1278","2015-02-03 09:16:59",21.2,25.3925,454.75,782,0.0039503403807421,1 +"1279","2015-02-03 09:17:59",21.23,25.445,453,786.666666666667,0.00396590076609986,1 +"1280","2015-02-03 09:19:00",21.254,25.578,451.6,792,0.00399267575098837,1 +"1281","2015-02-03 09:20:00",21.2,25.7633333333333,453,800.333333333333,0.00400840313060352,1 +"1282","2015-02-03 09:21:00",21.2,25.89,454.75,804.333333333333,0.00402823826834312,1 +"1283","2015-02-03 09:22:00",21.2,26.05,449.5,815.2,0.00405329497589108,1 +"1284","2015-02-03 09:23:00",21.2,26.1,460,829.75,0.0040611256083473,1 +"1285","2015-02-03 09:23:59",21.2,26.1571428571429,442,837.166666666667,0.00407007514245178,1 +"1286","2015-02-03 09:24:59",21.2,26.245,439,849,0.00408383555026875,1 +"1287","2015-02-03 09:26:00",21.2,26.29,439,853.5,0.0040908837982831,1 +"1288","2015-02-03 09:27:00",21.218,26.31,439,863.4,0.00409857117204104,1 +"1289","2015-02-03 09:28:00",21.236,26.412,442,864.4,0.00411914298609529,1 +"1290","2015-02-03 09:29:00",21.23,26.4983333333333,449,871.833333333333,0.00413116548618656,1 +"1291","2015-02-03 09:29:59",21.2225,26.525,454,872.25,0.00413343520190689,1 +"1292","2015-02-03 09:30:59",21.245,26.5833333333333,454,876.666666666667,0.00414834708477706,1 +"1293","2015-02-03 09:32:00",21.26,26.5666666666667,454,890.333333333333,0.00414957116092305,1 +"1294","2015-02-03 09:33:00",21.29,26.6833333333333,454,895.166666666667,0.00417564415325051,1 +"1295","2015-02-03 09:34:00",21.29,26.76,454,901,0.00418772240686286,1 +"1296","2015-02-03 09:35:00",21.29,26.79,454,910.25,0.00419244880685435,1 +"1297","2015-02-03 09:36:00",21.315,26.7675,454,918.5,0.00419537441770921,1 +"1298","2015-02-03 09:36:59",21.3066666666667,26.79,454,923.166666666667,0.00419676511367559,1 +"1299","2015-02-03 09:38:00",21.31,26.79,454,926.75,0.00419762884525263,1 +"1300","2015-02-03 09:39:00",21.3566666666667,26.79,454,925.5,0.00420973756199024,1 +"1301","2015-02-03 09:40:00",21.31,26.83,463,927.6,0.00420393866166668,1 +"1302","2015-02-03 09:40:59",21.29,26.89,457.75,935,0.00420820398880216,1 +"1303","2015-02-03 09:42:00",21.35,26.934,463,932,0.00423077833121522,1 +"1304","2015-02-03 09:42:59",21.34,26.945,464,935.75,0.00422990636361969,1 +"1305","2015-02-03 09:43:59",21.315,27,469,946.75,0.00423206298786129,1 +"1306","2015-02-03 09:45:00",21.39,27,461,952,0.00425169853702332,1 +"1307","2015-02-03 09:46:00",21.39,27.1,462.333333333333,959.333333333333,0.00426755360931977,1 +"1308","2015-02-03 09:47:00",21.39,27.08,461,967,0.0042643825306353,1 +"1309","2015-02-03 09:48:00",21.39,27.1,464,969,0.00426755360931977,1 +"1310","2015-02-03 09:49:00",21.4175,27.22,464,982.5,0.00429386020632878,1 +"1311","2015-02-03 09:49:59",21.4266666666667,27.23,462.333333333333,983,0.00429787837564832,1 +"1312","2015-02-03 09:51:00",21.412,27.272,453,985.4,0.00430066017745165,1 +"1313","2015-02-03 09:52:00",21.456,27.33,453,996.2,0.00432158397988126,1 +"1314","2015-02-03 09:53:00",21.4816666666667,27.3566666666667,449,1004.5,0.00433268296819078,1 +"1315","2015-02-03 09:53:59",21.5,27.312,458,1004.4,0.0043304522996918,1 +"1316","2015-02-03 09:55:00",21.5,27.315,460.25,1009.25,0.00433093127649958,1 +"1317","2015-02-03 09:55:59",21.54,27.718,461,1019,0.00440613366564097,1 +"1318","2015-02-03 09:56:59",21.55,27.5,464,1034.25,0.00437393153272012,1 +"1319","2015-02-03 09:58:00",21.6,27.4633333333333,464,1035.33333333333,0.00438153900805544,1 +"1320","2015-02-03 09:59:00",21.6,27.4633333333333,464,1031,0.00438153900805544,1 +"1321","2015-02-03 10:00:00",21.6,27.4725,467.75,1028.25,0.00438301177646266,1 +"1322","2015-02-03 10:01:00",21.6,27.456,473,1030,0.0043803607983161,1 +"1323","2015-02-03 10:01:59",21.6,27.5,479,1032.25,0.00438743012323847,1 +"1324","2015-02-03 10:02:59",21.6,27.6,479,1033.5,0.0044034973642419,1 +"1325","2015-02-03 10:04:00",21.6,27.54,479,1045,0.00439385692072895,1 +"1326","2015-02-03 10:05:00",21.6,27.525,474,1040.25,0.00439144685621549,1 +"1327","2015-02-03 10:06:00",21.6,27.5666666666667,472.333333333333,1044,0.00439814152565597,1 +"1328","2015-02-03 10:07:00",21.625,27.625,477.75,1041.25,0.0044143085475918,1 +"1329","2015-02-03 10:08:00",21.64,27.716,476,1045.8,0.00443304795553122,1 +"1330","2015-02-03 10:08:59",21.66,27.83,479,1054.2,0.00445689970955439,1 +"1331","2015-02-03 10:09:59",21.6833333333333,27.84,474,1054.8,0.00446492460265262,1 +"1332","2015-02-03 10:11:00",21.65,27.84,474,1069.8,0.00445576717556508,1 +"1333","2015-02-03 10:12:00",21.7,27.84,474,1073.66666666667,0.00446950954012619,1 +"1334","2015-02-03 10:13:00",21.7,27.912,474,1073.4,0.00448115189301355,1 +"1335","2015-02-03 10:14:00",21.7,28.0725,474,1076.75,0.00450710619550781,1 +"1336","2015-02-03 10:14:59",21.7,27.9675,474,1086.75,0.00449012650204007,1 +"1337","2015-02-03 10:15:59",21.7,27.8933333333333,484,1086.66666666667,0.00447813346367708,1 +"1338","2015-02-03 10:17:00",21.7,27.945,479,1078.83333333333,0.00448648811603864,1 +"1339","2015-02-03 10:18:00",21.7,27.912,483,1077.6,0.00448115189301355,1 +"1340","2015-02-03 10:19:00",21.7,27.9725,489,1080.5,0.00449093503800171,1 +"1341","2015-02-03 10:20:00",21.7,27.9175,489,1088.75,0.00448204125720489,1 +"1342","2015-02-03 10:21:00",21.7,27.89,489,1083.66666666667,0.00447759446149913,1 +"1343","2015-02-03 10:21:59",21.7,27.8566666666667,482,1076.16666666667,0.00447220449073066,1 +"1344","2015-02-03 10:23:00",21.7,27.934,480.6,1079.4,0.0044847093649297,1 +"1345","2015-02-03 10:24:00",21.7,28.1,495.25,1088,0.00451155341017895,1 +"1346","2015-02-03 10:25:00",21.7,27.9083333333333,484.833333333333,1092.5,0.00448055898495549,1 +"1347","2015-02-03 10:25:59",21.7,27.9616666666667,484,1094.66666666667,0.0044891832127225,1 +"1348","2015-02-03 10:27:00",21.718,27.974,484,1091.4,0.00449615819804534,1 +"1349","2015-02-03 10:27:59",21.7,28.1,484,1101.66666666667,0.00451155341017895,1 +"1350","2015-02-03 10:28:59",21.79,28.0666666666667,484,1111,0.00453119847610958,1 +"1351","2015-02-03 10:30:00",21.718,28.1,484,1119.4,0.00451655676817307,1 +"1352","2015-02-03 10:31:00",21.76,28.0833333333333,484,1122.5,0.0045255449793802,1 +"1353","2015-02-03 10:32:00",21.7675,28.125,495.25,1127.5,0.00453440119348346,1 +"1354","2015-02-03 10:33:00",21.73,28.1333333333333,499,1131,0.00452529574660407,1 +"1355","2015-02-03 10:34:00",21.775,28.05,499,1127.83333333333,0.00452430956253871,1 +"1356","2015-02-03 10:34:59",21.7771428571429,28.0857142857143,499,1128.85714285714,0.00453070953719286,1 +"1357","2015-02-03 10:36:00",21.79,28.125,499,1123.5,0.00454068479971385,1 +"1358","2015-02-03 10:37:00",21.79,28.158,490.6,1127.8,0.00454605147571897,1 +"1359","2015-02-03 10:38:00",21.79,28.26,502,1148.66666666667,0.00456263996464264,1 +"1360","2015-02-03 10:38:59",21.84,28.1,493,1151.5,0.00455059766479871,1 +"1361","2015-02-03 10:40:00",21.8233333333333,28.1333333333333,493,1142.33333333333,0.0045513659847956,1 +"1362","2015-02-03 10:40:59",21.87,28.252,493,1142,0.00458384551297586,1 +"1363","2015-02-03 10:41:59",21.89,28.1833333333333,495.666666666667,1146,0.00457825057734741,1 +"1364","2015-02-03 10:43:00",21.89,28.254,499.4,1142.2,0.00458981475498553,1 +"1365","2015-02-03 10:44:00",21.89,28.29,509,1159.8,0.00459570610393958,1 +"1366","2015-02-03 10:45:00",21.89,28.31,500.6,1168,0.0045989791234505,1 +"1367","2015-02-03 10:46:00",21.89,28.3757142857143,506.428571428571,1181.14285714286,0.00460973357116715,1 +"1368","2015-02-03 10:46:59",21.89,28.39,510,1180,0.00461207154343336,1 +"1369","2015-02-03 10:47:59",21.89,28.3757142857143,503,1183.71428571429,0.00460973357116715,1 +"1370","2015-02-03 10:49:00",21.89,28.3066666666667,503,1189.66666666667,0.00459843361782416,1 +"1371","2015-02-03 10:50:00",21.89,28.315,503,1190,0.00459979738367093,1 +"1372","2015-02-03 10:51:00",21.89,28.31,512,1178.8,0.0045989791234505,1 +"1373","2015-02-03 10:52:00",21.89,28.365,518,1173,0.00460798010341677,1 +"1374","2015-02-03 10:53:00",21.912,28.37,518,1170.6,0.00461503794243694,1 +"1375","2015-02-03 10:53:59",21.89,28.39,518,1178.6,0.00461207154343336,1 +"1376","2015-02-03 10:54:59",21.89,28.445,513,1193.5,0.0046210728995467,1 +"1377","2015-02-03 10:56:00",21.89,28.445,513,1201.5,0.0046210728995467,1 +"1378","2015-02-03 10:57:00",21.89,28.5,511.333333333333,1189.66666666667,0.00463007451427484,1 +"1379","2015-02-03 10:58:00",21.89,28.33,518.2,1190.4,0.00460225217715481,1 +"1380","2015-02-03 10:59:00",21.9083333333333,28.3083333333333,513,1172.66666666667,0.00460389401426128,1 +"1381","2015-02-03 10:59:59",21.945,28.29,513,1177.75,0.00461127429127358,1 +"1382","2015-02-03 11:00:59",21.934,28.29,519,1184.8,0.00460815693611691,1 +"1383","2015-02-03 11:02:00",22,28.29,528,1188.25,0.00462688899775767,1 +"1384","2015-02-03 11:03:00",21.9816666666667,28.29,528,1189.5,0.00462167891938681,1 +"1385","2015-02-03 11:04:00",21.945,28.29,528,1191.5,0.00461127429127358,1 +"1386","2015-02-03 11:05:00",21.978,28.29,532.8,1193,0.00462063752517838,1 +"1387","2015-02-03 11:06:00",22,28.29,534.25,1190,0.00462688899775767,1 +"1388","2015-02-03 11:06:59",22,28.29,528,1198.5,0.00462688899775767,1 +"1389","2015-02-03 11:08:00",22,28.2,523,1198,0.00461206016363195,1 +"1390","2015-02-03 11:09:00",22,28.218,526,1194.2,0.00461502587431004,1 +"1391","2015-02-03 11:10:00",22,28.2225,534.25,1185,0.00461576730636597,1 +"1392","2015-02-03 11:10:59",22,28.2675,538,1194,0.00462318172342805,1 +"1393","2015-02-03 11:12:00",22.025,28.2575,538,1193.125,0.00462863877156492,1 +"1394","2015-02-03 11:12:59",22.06,28.274,538,1190.4,0.00464133032259261,1 +"1395","2015-02-03 11:13:59",22.05,28.34,532.25,1192.25,0.00464938873472607,1 +"1396","2015-02-03 11:15:00",22.1,28.39,547.5,1200.5,0.00467197853896129,1 +"1397","2015-02-03 11:16:00",22.08,28.37,544.2,1198.6,0.00466293178958891,1 +"1398","2015-02-03 11:17:00",22.1,28.39,536.333333333333,1197,0.00467197853896129,1 +"1399","2015-02-03 11:18:00",22.1,28.365,535,1197.5,0.0046678335586324,1 +"1400","2015-02-03 11:19:00",22.06,28.35,534.2,1203,0.00465389948039161,1 +"1401","2015-02-03 11:19:59",22.1,28.39,533.666666666667,1206.5,0.00467197853896129,1 +"1402","2015-02-03 11:21:00",22.0833333333333,28.3583333333333,533.666666666667,1207.16666666667,0.00466195416810129,1 +"1403","2015-02-03 11:22:00",22.1,28.39,535,1213,0.00467197853896129,1 +"1404","2015-02-03 11:23:00",22.1,28.3566666666667,547,1211.5,0.00466645191070765,1 +"1405","2015-02-03 11:23:59",22.1,28.372,553.4,1208.2,0.00466899414759741,1 +"1406","2015-02-03 11:25:00",22.1,28.2,550.5,1209.25,0.00464047806359011,1 +"1407","2015-02-03 11:25:59",22.1,28.2,543.666666666667,1201.66666666667,0.00464047806359011,1 +"1408","2015-02-03 11:26:59",22.15,28.1,550.75,1189.75,0.00463811559644083,1 +"1409","2015-02-03 11:28:00",22.1,28.2,555,1191,0.00464047806359011,1 +"1410","2015-02-03 11:29:00",22.1166666666667,28.0666666666667,555,1192.16666666667,0.00462310286697241,1 +"1411","2015-02-03 11:30:00",22.1666666666667,28,557.666666666667,1184.33333333333,0.00462621711188873,1 +"1412","2015-02-03 11:31:00",22.18,28.06,555,1176.4,0.00463999955869725,1 +"1413","2015-02-03 11:31:59",22.1333333333333,28,557.666666666667,1175.66666666667,0.00461676157258899,1 +"1414","2015-02-03 11:32:59",22.16,27.956,556.4,1173.8,0.00461700390215967,1 +"1415","2015-02-03 11:34:00",22.2,27.9175,555,1170.75,0.00462192951071389,1 +"1416","2015-02-03 11:35:00",22.175,27.945,555,1170.25,0.0046194242813307,1 +"1417","2015-02-03 11:36:00",22.1833333333333,27.8066666666667,555,1168,0.00459873925912057,1 +"1418","2015-02-03 11:37:00",22.2,27.8233333333333,555,1160.83333333333,0.00460622413573017,1 +"1419","2015-02-03 11:38:00",22.2,27.79,546.5,1161,0.00460066489961799,1 +"1420","2015-02-03 11:38:59",22.2,27.79,538,1166,0.00460066489961799,1 +"1421","2015-02-03 11:39:59",22.2,27.772,543,1164.4,0.0045976629531329,1 +"1422","2015-02-03 11:41:00",22.2,27.7225,550.5,1157.75,0.00458940774860989,1 +"1423","2015-02-03 11:42:00",22.2,27.772,543,1148.6,0.0045976629531329,1 +"1424","2015-02-03 11:43:00",22.2,27.7225,547,1153.75,0.00458940774860989,1 +"1425","2015-02-03 11:44:00",22.2,27.7,544.2,1152.4,0.00458565545482424,1 +"1426","2015-02-03 11:44:59",22.175,27.7,543,1147.25,0.00457862664380834,1 +"1427","2015-02-03 11:45:59",22.2,27.7,544.25,1147.5,0.00458565545482424,1 +"1428","2015-02-03 11:47:00",22.2,27.7,548,1144,0.00458565545482424,1 +"1429","2015-02-03 11:48:00",22.2,27.6428571428571,535.714285714286,1137.85714285714,0.00457612602181138,0 +"1430","2015-02-03 11:49:00",22.2,27.7,543,1133,0.00458565545482424,1 +"1431","2015-02-03 11:50:00",22.2,27.6,538,1121.2,0.00456897913726817,1 +"1432","2015-02-03 11:51:00",22.2,27.5166666666667,549.333333333333,1110.83333333333,0.00455508288403504,1 +"1433","2015-02-03 11:51:59",22.2,27.5,547,1093.25,0.00455230370735505,1 +"1434","2015-02-03 11:53:00",22.2,27.54,538.6,1093.2,0.00455897377280768,1 +"1435","2015-02-03 11:54:00",22.2,27.5666666666667,549.333333333333,1102.5,0.00456342056200697,1 +"1436","2015-02-03 11:55:00",22.2,27.52,548.6,1104.4,0.00455563872232964,1 +"1437","2015-02-03 11:55:59",22.2,27.58,543,1101.75,0.00456564398027638,1 +"1438","2015-02-03 11:57:00",22.2,27.6,548.5,1098.75,0.00456897913726817,1 +"1439","2015-02-03 11:57:59",22.2,27.56,555,1092.4,0.00456230885878974,1 +"1440","2015-02-03 11:58:59",22.2,27.5,555,1094,0.00455230370735505,1 +"1441","2015-02-03 12:00:00",22.254,27.56,556.4,1092.4,0.004577445560063,1 +"1442","2015-02-03 12:01:00",22.2225,27.575,556.666666666667,1081.66666666667,0.00457111526070442,1 +"1443","2015-02-03 12:02:00",22.245,27.5833333333333,562,1077,0.00457882151640635,1 +"1444","2015-02-03 12:03:00",22.254,27.54,555.6,1074.4,0.00457409932824721,1 +"1445","2015-02-03 12:04:00",22.29,27.55,558,1072.25,0.00458588444602437,1 +"1446","2015-02-03 12:04:59",22.29,27.5,563.4,1070.4,0.00457750035625741,1 +"1447","2015-02-03 12:06:00",22.272,27.5,570,1071,0.0045724512071483,1 +"1448","2015-02-03 12:07:00",22.29,27.4816666666667,565.833333333333,1078.16666666667,0.00457442624622594,1 +"1449","2015-02-03 12:08:00",22.29,27.5,553,1071.75,0.00457750035625741,1 +"1450","2015-02-03 12:08:59",22.29,27.445,561.833333333333,1066.83333333333,0.00456827811665517,1 +"1451","2015-02-03 12:10:00",22.29,27.456,562.4,1068.4,0.00457012254285764,1 +"1452","2015-02-03 12:10:59",22.29,27.37,560.6,1064.2,0.00455570277286978,1 +"1453","2015-02-03 12:11:59",22.29,27.3566666666667,559.666666666667,1060.33333333333,0.00455346720904263,1 +"1454","2015-02-03 12:13:00",22.3066666666667,27.39,569.833333333333,1061.5,0.00456371667886437,1 +"1455","2015-02-03 12:14:00",22.33,27.37,581,1057,0.00456688681371893,1 +"1456","2015-02-03 12:15:00",22.35,27.33,593,1057.8,0.00456575637736974,1 +"1457","2015-02-03 12:16:00",22.39,27.29,601,1065,0.00457021208799111,1 +"1458","2015-02-03 12:16:59",22.39,27.29,600.4,1064.2,0.00457021208799111,1 +"1459","2015-02-03 12:17:59",22.39,27.254,616,1061.8,0.00456413898746735,1 +"1460","2015-02-03 12:19:00",22.39,27.29,603.6,1064,0.00457021208799111,0 +"1461","2015-02-03 12:20:00",22.39,27.2675,587.5,1065.25,0.00456641638636741,0 +"1462","2015-02-03 12:21:00",22.39,27.2,575,1050.5,0.00455502955741922,0 +"1463","2015-02-03 12:22:00",22.39,27.14,579.2,1045.2,0.00454490827913193,1 +"1464","2015-02-03 12:23:00",22.434,27.04,584.8,1049.6,0.00454025934484615,1 +"1465","2015-02-03 12:23:59",22.4266666666667,27.0333333333333,609.666666666667,1041.33333333333,0.00453709375237434,1 +"1466","2015-02-03 12:24:59",22.4266666666667,27.0333333333333,625.666666666667,1038,0.00453709375237434,1 +"1467","2015-02-03 12:26:00",22.4266666666667,26.9816666666667,629.666666666667,1035.16666666667,0.00452835923432911,1 +"1468","2015-02-03 12:27:00",22.5,27,617,1040,0.0045518496783126,1 +"1469","2015-02-03 12:28:00",22.5,27,624.8,1036.25,0.0045518496783126,1 +"1470","2015-02-03 12:29:00",22.5,26.9633333333333,641.333333333333,1033.25,0.00454562297901196,1 +"1471","2015-02-03 12:29:59",22.5,26.89,659.4,1037,0.00453316995169055,1 +"1472","2015-02-03 12:30:59",22.58,26.81,644.6,1031.2,0.00454176304586707,1 +"1473","2015-02-03 12:32:00",22.575,26.79,653,1033,0.00453696235530401,1 +"1474","2015-02-03 12:33:00",22.6,26.79,659,1032.25,0.00454390539234429,1 +"1475","2015-02-03 12:34:00",22.6,26.79,660,1030.16666666667,0.00454390539234429,1 +"1476","2015-02-03 12:35:00",22.6,26.7225,668.5,1033,0.0045323731576807,1 +"1477","2015-02-03 12:36:00",22.6666666666667,26.7133333333333,652.5,1030.33333333333,0.00454931379169049,1 +"1478","2015-02-03 12:36:59",22.675,26.675,652.75,1028.5,0.0045450525434806,1 +"1479","2015-02-03 12:38:00",22.7,26.7,654.2,1020.4,0.00455630013842985,1 +"1480","2015-02-03 12:39:00",22.7,26.6833333333333,656.166666666667,1023.66666666667,0.00455343518515253,1 +"1481","2015-02-03 12:40:00",22.7225,26.6,650.75,1021.25,0.00454535611417879,1 +"1482","2015-02-03 12:40:59",22.745,26.6,663.75,1014.75,0.0045516089930389,1 +"1483","2015-02-03 12:42:00",22.745,26.55,651,1017,0.00454299084786184,1 +"1484","2015-02-03 12:42:59",22.79,26.5166666666667,648.333333333333,1014.16666666667,0.00454973424512434,1 +"1485","2015-02-03 12:43:59",22.79,26.6,651,1022.5,0.00456413751185785,1 +"1486","2015-02-03 12:45:00",22.79,26.525,651,1027.25,0.00455117454199881,1 +"1487","2015-02-03 12:46:00",22.84,26.5,651,1022,0.00456075667086994,1 +"1488","2015-02-03 12:47:00",22.87,26.456,657.8,1019,0.00456147435928116,1 +"1489","2015-02-03 12:48:00",22.89,26.445,668,1020.75,0.00456513280446388,1 +"1490","2015-02-03 12:49:00",22.89,26.39,668,1015.5,0.00455556875653445,1 +"1491","2015-02-03 12:49:59",22.9083333333333,26.39,663.666666666667,1016,0.00456066810185617,1 +"1492","2015-02-03 12:51:00",22.956,26.39,664.6,1011,0.00457394996276206,1 +"1493","2015-02-03 12:52:00",22.9633333333333,26.29,668,1018.66666666667,0.0045585293816626,1 +"1494","2015-02-03 12:53:00",23,26.29,662.333333333333,1006.33333333333,0.00456873404646213,1 +"1495","2015-02-03 12:53:59",22.956,26.236,647.8,1008.2,0.00454706335236863,1 +"1496","2015-02-03 12:55:00",23,26.2,651.666666666667,1009.33333333333,0.00455297916224937,1 +"1497","2015-02-03 12:55:59",23,26.2,651.666666666667,1006.16666666667,0.00455297916224937,1 +"1498","2015-02-03 12:56:59",23.02,26.16,650,1004.4,0.00455152394293641,1 +"1499","2015-02-03 12:58:00",23.025,26.125,653.75,999.75,0.00454677558763047,1 +"1500","2015-02-03 12:59:00",23.05,26.0833333333333,660,994.166666666667,0.00454639400910893,1 +"1501","2015-02-03 13:00:00",23.1,26,656,992.5,0.00454559188217678,1 +"1502","2015-02-03 13:01:00",23.1,26,660,995.666666666667,0.00454559188217678,1 +"1503","2015-02-03 13:01:59",23.1,26,655,994,0.00454559188217678,1 +"1504","2015-02-03 13:02:59",23.14,26,660,990.2,0.00455668179296498,1 +"1505","2015-02-03 13:04:00",23.18,26,655,993.4,0.00456779555054517,1 +"1506","2015-02-03 13:05:00",23.2,26,650,998.5,0.00457336138571879,1 +"1507","2015-02-03 13:06:00",23.2,26,651.666666666667,997.25,0.00457336138571879,1 +"1508","2015-02-03 13:07:00",23.2,25.945,653.166666666667,992.5,0.00456361598616477,1 +"1509","2015-02-03 13:08:00",23.2225,25.9175,653.75,996.5,0.00456499192799556,1 +"1510","2015-02-03 13:08:59",23.2225,25.815,659.75,993.75,0.00454680606529801,1 +"1511","2015-02-03 13:09:59",23.26,25.8566666666667,338.333333333333,997.333333333333,0.00456460471615985,0 +"1512","2015-02-03 13:11:00",23.29,25.9783333333333,197.166666666667,996.5,0.00459462133070974,0 +"1513","2015-02-03 13:12:00",23.272,25.87,184,998.6,0.00457031193495107,0 +"1514","2015-02-03 13:13:00",23.29,25.89,173.2,993.4,0.00457888337102673,0 +"1515","2015-02-03 13:14:00",23.2675,25.865,193,994.25,0.00456817106525555,0 +"1516","2015-02-03 13:14:59",23.29,25.89,193,990.166666666667,0.00457888337102673,0 +"1517","2015-02-03 13:15:59",23.245,25.825,178,984,0.00455481367184223,0 +"1518","2015-02-03 13:17:00",23.254,25.85,184,983.6,0.00456175322657994,0 +"1519","2015-02-03 13:18:00",23.26,25.7933333333333,186,983.333333333333,0.00455334232387095,0 +"1520","2015-02-03 13:19:00",23.272,25.772,178,974.6,0.00455287208154249,0 +"1521","2015-02-03 13:20:00",23.245,25.715,178,961,0.00453527126228133,0 +"1522","2015-02-03 13:21:00",23.29,25.7225,173.5,954.25,0.00454904280691813,0 +"1523","2015-02-03 13:21:59",23.245,25.7,174.5,951.5,0.00453260648270231,0 +"1524","2015-02-03 13:23:00",23.215,25.6833333333333,169.666666666667,952.5,0.00452138233147554,0 +"1525","2015-02-03 13:24:00",23.215,25.6833333333333,168.5,946.333333333333,0.00452138233147554,0 +"1526","2015-02-03 13:25:00",23.2,25.6,171,942,0.00450249266674727,0 +"1527","2015-02-03 13:25:59",23.2,25.6,176,933.2,0.00450249266674727,0 +"1528","2015-02-03 13:27:00",23.2,25.58,176,928.8,0.00449894965161647,0 +"1529","2015-02-03 13:27:59",23.2,25.55,177.25,924,0.00449363520405676,0 +"1530","2015-02-03 13:28:59",23.2,25.55,171,918,0.00449363520405676,0 +"1531","2015-02-03 13:30:00",23.2,25.5,171,912.75,0.00448477799181549,0 +"1532","2015-02-03 13:31:00",23.2,25.5,171,907,0.00448477799181549,0 +"1533","2015-02-03 13:32:00",23.1857142857143,25.5285714285714,268.714285714286,899.285714285714,0.00448593615538647,0 +"1534","2015-02-03 13:33:00",23.2,25.7,538.75,917.25,0.00452020834351849,1 +"1535","2015-02-03 13:34:00",23.2,25.792,627.6,919.8,0.00453650765104568,0 +"1536","2015-02-03 13:34:59",23.2,25.65,638,938.25,0.00451135037989764,0 +"1537","2015-02-03 13:36:00",23.2,25.5333333333333,634,922.166666666667,0.00449068277214917,0 +"1538","2015-02-03 13:37:00",23.2,25.5,629,899,0.00448477799181549,0 +"1539","2015-02-03 13:38:00",23.2,25.5166666666667,557.666666666667,895.333333333333,0.00448773036806887,0 +"1540","2015-02-03 13:38:59",23.2,25.7225,547,899.75,0.0045241945088667,1 +"1541","2015-02-03 13:40:00",23.2,25.54,543,894.4,0.00449186374157291,1 +"1542","2015-02-03 13:40:59",23.1833333333333,25.5166666666667,561.833333333333,880.333333333333,0.00448317923134458,1 +"1543","2015-02-03 13:41:59",23.15,25.5,597.75,879.75,0.00447114582351116,1 +"1544","2015-02-03 13:43:00",23.2,25.5,561.5,870.5,0.00448477799181549,1 +"1545","2015-02-03 13:44:00",23.2,25.5,598.4,866.2,0.00448477799181549,1 +"1546","2015-02-03 13:45:00",23.18,25.5,609.6,866.4,0.00447932073438887,1 +"1547","2015-02-03 13:46:00",23.2,25.525,587,869.75,0.00448920656663063,1 +"1548","2015-02-03 13:46:59",23.2,25.58,596.8,874.2,0.00449894965161647,1 +"1549","2015-02-03 13:47:59",23.175,25.6,595,877.5,0.00449564487529898,1 +"1550","2015-02-03 13:49:00",23.1833333333333,25.7,608.333333333333,879,0.00451562403253954,1 +"1551","2015-02-03 13:50:00",23.2,25.68,611.6,875.5,0.00451666512801301,1 +"1552","2015-02-03 13:51:00",23.2,25.7,610.2,881.333333333333,0.00452020834351849,1 +"1553","2015-02-03 13:52:00",23.218,25.7,616.6,882.4,0.00452516400707931,1 +"1554","2015-02-03 13:53:00",23.23,25.715,608.333333333333,883,0.00453113277335468,1 +"1555","2015-02-03 13:53:59",23.254,25.68,609,884.5,0.00453153473985364,1 +"1556","2015-02-03 13:54:59",23.2675,25.7225,599,888.25,0.00454281948050459,1 +"1557","2015-02-03 13:56:00",23.272,25.772,594.8,889.4,0.00455287208154249,1 +"1558","2015-02-03 13:57:00",23.29,25.79,585.75,895,0.00456106776695527,1 +"1559","2015-02-03 13:58:00",23.29,25.79,584.8,894.4,0.00456106776695527,1 +"1560","2015-02-03 13:59:00",23.29,25.79,592.75,898.25,0.00456106776695527,1 +"1561","2015-02-03 13:59:59",23.29,25.79,586.5,898,0.00456106776695527,1 +"1562","2015-02-03 14:00:59",23.29,25.79,585,898.8,0.00456106776695527,1 +"1563","2015-02-03 14:02:00",23.29,25.79,576.75,901,0.00456106776695527,1 +"1564","2015-02-03 14:03:00",23.29,25.79,566,900.142857142857,0.00456106776695527,1 +"1565","2015-02-03 14:04:00",23.29,25.7675,560,898.25,0.00455705939565711,1 +"1566","2015-02-03 14:05:00",23.29,25.754,566,895.6,0.00455465439749561,1 +"1567","2015-02-03 14:06:00",23.29,25.7933333333333,569.333333333333,892.333333333333,0.00456166160410202,1 +"1568","2015-02-03 14:06:59",23.29,26.16,561,911.166666666667,0.00462699056302192,1 +"1569","2015-02-03 14:08:00",23.29,25.89,561,912,0.00457888337102673,1 +"1570","2015-02-03 14:09:00",23.29,25.89,561,913,0.00457888337102673,1 +"1571","2015-02-03 14:10:00",23.29,26.0591666666667,558.3,921.4,0.00460902374129976,1 +"1572","2015-02-03 14:10:59",23.29,26.2283333333333,555.6,929.8,0.0046391670114012,1 +"1573","2015-02-03 14:12:00",23.29,26.456,558.8,951.8,0.00467973878852721,1 +"1574","2015-02-03 14:12:59",23.29,26.575,546,956.75,0.00470094750364723,1 +"1575","2015-02-03 14:13:59",23.29,26.62,546,968,0.00470896798007197,1 +"1576","2015-02-03 14:15:00",23.29,26.754,542.8,966,0.0047328523924129,1 +"1577","2015-02-03 14:16:00",23.29,26.79,544.8,971.8,0.00473926941045434,1 +"1578","2015-02-03 14:17:00",23.29,26.87,541.4,983,0.00475352992102182,1 +"1579","2015-02-03 14:18:00",23.33,26.956,538,993.6,0.00478048254400917,1 +"1580","2015-02-03 14:19:00",23.29,27,538.4,999.6,0.0047767046348402,1 +"1581","2015-02-03 14:19:59",23.35,27.08,538.4,1005.4,0.00480849045959722,1 +"1582","2015-02-03 14:21:00",23.315,27.1,534.5,1013.75,0.00480183262216262,1 +"1583","2015-02-03 14:22:00",23.29,27.14,538.8,1019.8,0.00480166393565326,1 +"1584","2015-02-03 14:23:00",23.29,27.26,531,1023,0.00482305920427885,1 +"1585","2015-02-03 14:23:59",23.29,27.4083333333333,526.833333333333,1027.5,0.00484950815226506,1 +"1586","2015-02-03 14:25:00",23.29,27.4175,526.75,1038.5,0.0048511427110445,1 +"1587","2015-02-03 14:25:59",23.29,27.5,519.666666666667,1049,0.00486585412367001,1 +"1588","2015-02-03 14:26:59",23.29,27.5,505.8,1051.8,0.00486585412367001,1 +"1589","2015-02-03 14:28:00",23.3185714285714,27.5857142857143,493,1056,0.00488963512707243,1 +"1590","2015-02-03 14:29:00",23.29,27.65,503.5,1054.5,0.0048926039157939,1 +"1591","2015-02-03 14:30:00",23.29,27.772,496.2,1066.6,0.00491436209694374,1 +"1592","2015-02-03 14:31:00",23.29,27.7,513,1074,0.00490152102049775,1 +"1593","2015-02-03 14:31:59",23.29,27.79,520.5,1068.25,0.00491757244825221,1 +"1594","2015-02-03 14:32:59",23.33,27.874,528,1075.6,0.00494457844645588,1 +"1595","2015-02-03 14:34:00",23.29,27.9175,516.75,1085.25,0.00494031337801483,1 +"1596","2015-02-03 14:35:00",23.29,27.9633333333333,513,1096.33333333333,0.00494848862518615,1 +"1597","2015-02-03 14:36:00",23.3042857142857,28.0142857142857,503.714285714286,1099.14285714286,0.00496189043810212,1 +"1598","2015-02-03 14:37:00",23.3233333333333,28.1,503,1108.83333333333,0.00498296766080685,1 +"1599","2015-02-03 14:38:00",23.29,28.1,498,1117,0.00497286699161319,1 +"1600","2015-02-03 14:38:59",23.29,28.236,481.6,1116,0.00499712832126751,1 +"1601","2015-02-03 14:39:59",23.29,28.35,484,1120.2,0.00501746647070968,1 +"1602","2015-02-03 14:41:00",23.29,28.39,483.4,1120.6,0.00502460297620029,1 +"1603","2015-02-03 14:42:00",23.29,28.5333333333333,485,1129.33333333333,0.0050501767882762,1 +"1604","2015-02-03 14:43:00",23.29,28.575,478,1132.25,0.00505761142733373,1 +"1605","2015-02-03 14:44:00",23.29,28.6,478.75,1132.5,0.00506207229539191,1 +"1606","2015-02-03 14:44:59",23.29,28.6833333333333,474,1142.83333333333,0.00507694231398356,1 +"1607","2015-02-03 14:45:59",23.29,28.772,473,1152,0.00509276478818188,1 +"1608","2015-02-03 14:47:00",23.29,28.79,474,1156.75,0.00509597696691146,1 +"1609","2015-02-03 14:48:00",23.29,28.89,479,1159.33333333333,0.00511382300356036,1 +"1610","2015-02-03 14:49:00",23.254,28.912,476,1160.8,0.00510654102587916,1 +"1611","2015-02-03 14:50:00",23.245,28.92,467.75,1160,0.0051051661578754,1 +"1612","2015-02-03 14:51:00",23.236,28.978,464,1167,0.00511268512907113,1 +"1613","2015-02-03 14:51:59",23.2,29.05,464,1171,0.00511426303503512,1 +"1614","2015-02-03 14:53:00",23.2225,29.15,464,1175.5,0.00513905406343719,1 +"1615","2015-02-03 14:54:00",23.2,29.2,453,1181,0.00514088885036853,1 +"1616","2015-02-03 14:55:00",23.2,29.2,464,1192,0.00514088885036853,1 +"1617","2015-02-03 14:55:59",23.2,29.2,464,1197.75,0.00514088885036853,1 +"1618","2015-02-03 14:57:00",23.2,29.254,461,1198.2,0.00515047469737527,1 +"1619","2015-02-03 14:57:59",23.2,29.33,464,1196.5,0.00516396638590783,1 +"1620","2015-02-03 14:58:59",23.2,29.3566666666667,464,1203.25,0.00516870044928234,1 +"1621","2015-02-03 15:00:00",23.14,29.456,469,1209,0.00516740184512806,1 +"1622","2015-02-03 15:01:00",23.125,29.4725,469,1212.25,0.00516559391429917,1 +"1623","2015-02-03 15:02:00",23.1,29.5,463,1219.6,0.00516257728412937,1 +"1624","2015-02-03 15:03:00",23.1,29.55,465.25,1218.75,0.00517140016500502,1 +"1625","2015-02-03 15:04:00",23.1,29.6,466,1221.6,0.00518022329412355,1 +"1626","2015-02-03 15:04:59",23.1,29.62,469,1219.8,0.00518375261528132,1 +"1627","2015-02-03 15:06:00",23.1,29.7,466.5,1224.66666666667,0.00519787029713117,1 +"1628","2015-02-03 15:07:00",23.1,29.745,469,1233.75,0.00520581177247756,1 +"1629","2015-02-03 15:08:00",23.1,29.84,469,1235.75,0.00522257776976399,1 +"1630","2015-02-03 15:08:59",23.1,29.84,469,1239.5,0.00522257776976399,1 +"1631","2015-02-03 15:10:00",23.0857142857143,29.89,465.666666666667,1245,0.0052268457571293,1 +"1632","2015-02-03 15:10:59",23.0666666666667,29.8566666666667,464,1247.25,0.00521490474145376,1 +"1633","2015-02-03 15:11:59",23.025,29.9175,469,1246,0.00521235062737091,1 +"1634","2015-02-03 15:13:00",23.0166666666667,29.9633333333333,462.333333333333,1245.16666666667,0.00521774860124666,1 +"1635","2015-02-03 15:14:00",23,30,465,1254.6,0.00521887561724853,1 +"1636","2015-02-03 15:15:00",23,30,461,1261.2,0.00521887561724853,1 +"1637","2015-02-03 15:16:00",23,30,464,1261,0.00521887561724853,1 +"1638","2015-02-03 15:16:59",23,30.0166666666667,462.333333333333,1263.66666666667,0.0052217993333571,1 +"1639","2015-02-03 15:17:59",23,30.06,461,1270.2,0.00522940112280461,1 +"1640","2015-02-03 15:19:00",23,30.075,464,1273.25,0.00523203255439104,1 +"1641","2015-02-03 15:20:00",23,30.12,461,1280.2,0.00523992698162853,1 +"1642","2015-02-03 15:21:00",23,30.15,469,1284.5,0.00524519004352148,1 +"1643","2015-02-03 15:22:00",23,30.23,462.333333333333,1285.16666666667,0.00525922530704646,1 +"1644","2015-02-03 15:23:00",23,30.29,462.333333333333,1290.66666666667,0.00526975216689249,1 +"1645","2015-02-03 15:23:59",22.9685714285714,30.3042857142857,460.428571428571,1294.57142857143,0.0052621521240719,1 +"1646","2015-02-03 15:24:59",22.9175,30.29,464,1294,0.0052432718125789,1 +"1647","2015-02-03 15:26:00",22.912,30.29,461,1301,0.00524151064064436,1 +"1648","2015-02-03 15:27:00",22.9083333333333,30.3066666666667,462.333333333333,1313.16666666667,0.00524324454762937,1 +"1649","2015-02-03 15:28:00",22.89,30.34,464,1312.75,0.00524318460448223,1 +"1650","2015-02-03 15:29:00",22.945,30.39,469,1311.5,0.00526957174907314,1 +"1651","2015-02-03 15:29:59",22.9266666666667,30.3733333333333,469,1317.6,0.00526076361340516,1 +"1652","2015-02-03 15:30:59",22.9633333333333,30.39,469,1327.5,0.0052754745659686,1 +"1653","2015-02-03 15:32:00",22.9371428571429,30.3914285714286,469,1330.28571428571,0.00526729344587457,1 +"1654","2015-02-03 15:33:00",22.934,30.456,466,1330,0.00527756649320545,1 +"1655","2015-02-03 15:34:00",22.9175,30.5,465.25,1328.75,0.00527993189209704,1 +"1656","2015-02-03 15:35:00",22.9371428571429,30.4057142857143,456.142857142857,1330,0.00526979035275781,1 +"1657","2015-02-03 15:36:00",22.956,30.412,454,1321.8,0.00527696244872235,1 +"1658","2015-02-03 15:36:59",22.89,30.445,454,1321.5,0.00526148359397035,1 +"1659","2015-02-03 15:38:00",22.934,30.6,454,1331.6,0.00530273225818885,1 +"1660","2015-02-03 15:39:00",22.9083333333333,30.6,454,1336.83333333333,0.00529442503322916,1 +"1661","2015-02-03 15:40:00",22.89,30.68,454,1340,0.00530244234434886,1 +"1662","2015-02-03 15:40:59",22.945,30.7,454,1350.75,0.00532378527896655,1 +"1663","2015-02-03 15:42:00",22.89,30.675,454,1356,0.00530157082588112,1 +"1664","2015-02-03 15:42:59",22.89,30.675,454,1351.75,0.00530157082588112,1 +"1665","2015-02-03 15:43:59",22.89,30.745,454,1360.16666666667,0.00531377230480128,1 +"1666","2015-02-03 15:45:00",22.89,30.79,454,1364.2,0.00532161636332885,1 +"1667","2015-02-03 15:46:00",22.89,30.754,454,1363.2,0.00531534110081356,1 +"1668","2015-02-03 15:47:00",22.89,30.79,454,1363.16666666667,0.00532161636332885,1 +"1669","2015-02-03 15:48:00",22.89,30.79,454,1367,0.00532161636332885,1 +"1670","2015-02-03 15:49:00",22.89,30.79,454,1368.5,0.00532161636332885,1 +"1671","2015-02-03 15:49:59",22.912,30.79,454,1365.8,0.00532877401973244,1 +"1672","2015-02-03 15:51:00",22.89,30.89,454,1361.6,0.00533904830684845,1 +"1673","2015-02-03 15:52:00",22.89,30.865,465.25,1372,0.00533469023014476,1 +"1674","2015-02-03 15:53:00",22.89,30.89,465.25,1385.25,0.00533904830684845,1 +"1675","2015-02-03 15:53:59",22.89,30.89,469,1386.4,0.00533904830684845,1 +"1676","2015-02-03 15:55:00",22.89,30.89,469,1393.16666666667,0.00533904830684845,1 +"1677","2015-02-03 15:55:59",22.89,30.85,469,1393,0.00533207541318664,1 +"1678","2015-02-03 15:56:59",22.89,30.79,460,1389,0.00532161636332885,1 +"1679","2015-02-03 15:58:00",22.89,30.79,454,1385.2,0.00532161636332885,1 +"1680","2015-02-03 15:59:00",22.89,30.8566666666667,454,1377.33333333333,0.00533323755136582,1 +"1681","2015-02-03 16:00:00",22.89,30.8566666666667,454,1383.83333333333,0.00533323755136582,1 +"1682","2015-02-03 16:01:00",22.89,30.83,442,1388.6,0.00532858902448337,1 +"1683","2015-02-03 16:01:59",22.89,30.865,449.5,1377.5,0.00533469023014476,1 +"1684","2015-02-03 16:02:59",22.89,30.89,451.6,1374,0.00533904830684845,1 +"1685","2015-02-03 16:04:00",22.89,30.89,451.6,1377.6,0.00533904830684845,1 +"1686","2015-02-03 16:05:00",22.89,30.89,456.8,1373,0.00533904830684845,1 +"1687","2015-02-03 16:06:00",22.865,30.84,444,1372.25,0.00532219540359315,1 +"1688","2015-02-03 16:07:00",22.89,30.89,444,1376,0.00533904830684845,1 +"1689","2015-02-03 16:08:00",22.84,30.84,444,1361.75,0.0053140695648421,1 +"1690","2015-02-03 16:08:59",22.79,30.81,444,1356.6,0.00529265334760105,1 +"1691","2015-02-03 16:09:59",22.79,30.84,444,1363,0.00529785075094191,1 +"1692","2015-02-03 16:11:00",22.79,30.83,444,1363.8,0.00529611827359213,1 +"1693","2015-02-03 16:12:00",22.79,30.89,444,1363.5,0.00530651328123638,1 +"1694","2015-02-03 16:13:00",22.79,30.89,444,1369.33333333333,0.00530651328123638,1 +"1695","2015-02-03 16:14:00",22.79,30.9175,444,1366.25,0.00531127777487795,1 +"1696","2015-02-03 16:14:59",22.79,30.89,444,1372.57142857143,0.00530651328123638,1 +"1697","2015-02-03 16:15:59",22.79,30.89,444,1361.66666666667,0.00530651328123638,1 +"1698","2015-02-03 16:17:00",22.79,30.89,444,1367.25,0.00530651328123638,1 +"1699","2015-02-03 16:18:00",22.79,30.89,444,1359,0.00530651328123638,1 +"1700","2015-02-03 16:19:00",22.79,30.934,444,1363.8,0.00531413650580267,1 +"1701","2015-02-03 16:20:00",22.79,30.89,444,1353.75,0.00530651328123638,1 +"1702","2015-02-03 16:21:00",22.79,31,444,1356.33333333333,0.00532557169005772,1 +"1703","2015-02-03 16:21:59",22.79,31,444,1363.8,0.00532557169005772,1 +"1704","2015-02-03 16:23:00",22.772,31.02,444,1364,0.00532317431933842,1 +"1705","2015-02-03 16:24:00",22.79,31.05,444,1373.33333333333,0.00533423498598668,1 +"1706","2015-02-03 16:25:00",22.7675,31.125,440.25,1374.25,0.00533987771455223,1 +"1707","2015-02-03 16:25:59",22.79,31.0833333333333,444,1369,0.0053400106495396,1 +"1708","2015-02-03 16:27:00",22.79,31.075,444.75,1360.75,0.00533856672368114,1 +"1709","2015-02-03 16:27:59",22.79,31.1142857142857,441.285714285714,1359.5,0.00534537386092276,1 +"1710","2015-02-03 16:28:59",22.745,31.15,447,1366.33333333333,0.00533685389183532,1 +"1711","2015-02-03 16:30:00",22.772,31.2,439.8,1377,0.00535432904378901,1 +"1712","2015-02-03 16:31:00",22.79,31.2,441,1379.5,0.00536022630950282,1 +"1713","2015-02-03 16:32:00",22.745,31.2,442.5,1379.25,0.00534549389028849,1 +"1714","2015-02-03 16:33:00",22.7225,31.2,442.5,1381.5,0.00533814110163399,1 +"1715","2015-02-03 16:34:00",22.745,31.29,438,1381,0.00536104648725084,1 +"1716","2015-02-03 16:34:59",22.73,31.1666666666667,441,1374,0.00533483634054531,1 +"1717","2015-02-03 16:36:00",22.73,31.2133333333333,441,1372.5,0.00534289294650604,1 +"1718","2015-02-03 16:37:00",22.7,31.1,442.5,1369.75,0.0053135653993026,1 +"1719","2015-02-03 16:38:00",22.7,31.12,443.4,1368.6,0.00531701169324883,1 +"1720","2015-02-03 16:38:59",22.715,31.2,441,1368.33333333333,0.00533569215804204,1 +"1721","2015-02-03 16:40:00",22.7,31.1666666666667,441,1365.33333333333,0.00532505319304875,1 +"1722","2015-02-03 16:40:59",22.715,31.2,441,1370.5,0.00533569215804204,1 +"1723","2015-02-03 16:41:59",22.715,31.2,441,1366.33333333333,0.00533569215804204,1 +"1724","2015-02-03 16:43:00",22.7,31.2,442.5,1373.5,0.0053307972477025,1 +"1725","2015-02-03 16:44:00",22.745,31.2225,438,1378.5,0.00534938196723674,1 +"1726","2015-02-03 16:45:00",22.7,31.272,441,1377.16666666667,0.00534320476475416,1 +"1727","2015-02-03 16:46:00",22.7,31.245,447,1401.16666666667,0.00533855188834477,1 +"1728","2015-02-03 16:46:59",22.7,31.2675,442.5,1395.33333333333,0.00534242928055959,1 +"1729","2015-02-03 16:47:59",22.7,31.29,447,1401,0.00534630672070471,1 +"1730","2015-02-03 16:49:00",22.7,31.29,444,1400.5,0.00534630672070471,1 +"1731","2015-02-03 16:50:00",22.7,31.29,447,1394,0.00534630672070471,1 +"1732","2015-02-03 16:51:00",22.7,31.29,447,1394.6,0.00534630672070471,1 +"1733","2015-02-03 16:52:00",22.7,31.29,447,1389.66666666667,0.00534630672070471,1 +"1734","2015-02-03 16:53:00",22.7,31.29,447,1377.2,0.00534630672070471,1 +"1735","2015-02-03 16:53:59",22.7,31.29,447,1387,0.00534630672070471,1 +"1736","2015-02-03 16:54:59",22.7,31.3757142857143,439,1393.42857142857,0.00536107836036269,1 +"1737","2015-02-03 16:56:00",22.7,31.39,447,1393.75,0.00536354036793693,1 +"1738","2015-02-03 16:57:00",22.7,31.39,441.4,1392.6,0.00536354036793693,1 +"1739","2015-02-03 16:58:00",22.7,31.37,438.6,1394.2,0.00536009356274362,1 +"1740","2015-02-03 16:59:00",22.7,31.4175,440,1396.25,0.0053682797869201,1 +"1741","2015-02-03 16:59:59",22.7,31.39,443.5,1390.5,0.00536354036793693,1 +"1742","2015-02-03 17:00:59",22.7225,31.365,436.5,1397.5,0.00536661522872093,1 +"1743","2015-02-03 17:02:00",22.7,31.4175,433,1398.25,0.0053682797869201,1 +"1744","2015-02-03 17:03:00",22.7,31.4725,433,1402.25,0.00537775883971339,1 +"1745","2015-02-03 17:04:00",22.7,31.3785714285714,433,1398,0.00536157076033165,1 +"1746","2015-02-03 17:05:00",22.7,31.29,433,1384.25,0.00534630672070471,1 +"1747","2015-02-03 17:06:00",22.7,31.29,433,1387.33333333333,0.00534630672070471,1 +"1748","2015-02-03 17:06:59",22.7,31.29,433,1392.5,0.00534630672070471,1 +"1749","2015-02-03 17:08:00",22.7,31.236,433,1384.8,0.00533700094487913,1 +"1750","2015-02-03 17:09:00",22.7225,31.315,433,1388,0.00535798643240495,1 +"1751","2015-02-03 17:10:00",22.7,31.27,433,1384.6,0.00534286010487543,1 +"1752","2015-02-03 17:10:59",22.7,31.275,433,1373.33333333333,0.00534372175528233,1 +"1753","2015-02-03 17:12:00",22.7,31.18,433,1368.8,0.00532735080228751,1 +"1754","2015-02-03 17:12:59",22.7,31.2,433,1364,0.0053307972477025,1 +"1755","2015-02-03 17:13:59",22.7,31.15,433,1357.5,0.00532218120516758,1 +"1756","2015-02-03 17:15:00",22.7,31.2,433,1352,0.0053307972477025,1 +"1757","2015-02-03 17:16:00",22.7,31.2,433,1357,0.0053307972477025,1 +"1758","2015-02-03 17:17:00",22.7,31.1,433,1361.75,0.0053135653993026,1 +"1759","2015-02-03 17:18:00",22.7,31.1,433,1356,0.0053135653993026,1 +"1760","2015-02-03 17:19:00",22.7,31.1,433,1344.25,0.0053135653993026,1 +"1761","2015-02-03 17:19:59",22.7,31.05,433,1357.75,0.00530494983009781,1 +"1762","2015-02-03 17:21:00",22.7,31.1,433,1355.75,0.0053135653993026,1 +"1763","2015-02-03 17:22:00",22.7,31.1,433,1354.66666666667,0.0053135653993026,1 +"1764","2015-02-03 17:23:00",22.7,31.0166666666667,433,1343.33333333333,0.00529920624876767,1 +"1765","2015-02-03 17:23:59",22.7,31.05,433,1334.16666666667,0.00530494983009781,1 +"1766","2015-02-03 17:25:00",22.7225,30.9725,433,1340.25,0.00529888555878151,1 +"1767","2015-02-03 17:25:59",22.736,30.934,433,1336.8,0.00529661515620911,1 +"1768","2015-02-03 17:26:59",22.7675,31,433,1335.75,0.0053182490601398,1 +"1769","2015-02-03 17:28:00",22.73,31,433,1342.33333333333,0.00530606443699799,1 +"1770","2015-02-03 17:29:00",22.718,31,433,1348.8,0.00530217056838159,1 +"1771","2015-02-03 17:30:00",22.7,31,433,1353.25,0.00529633449754344,1 +"1772","2015-02-03 17:31:00",22.7,30.912,433,1339,0.00528117208699465,1 +"1773","2015-02-03 17:31:59",22.7,30.945,433,1338.25,0.00528685790505325,1 +"1774","2015-02-03 17:32:59",22.7,30.956,433,1347.6,0.0052887532006451,1 +"1775","2015-02-03 17:34:00",22.7,30.9725,433,1338.75,0.00529159616550726,1 +"1776","2015-02-03 17:35:00",22.7,30.89,433,1318,0.00527738159888531,1 +"1777","2015-02-03 17:36:00",22.7,30.8733333333333,433,1311.16666666667,0.00527451004748194,1 +"1778","2015-02-03 17:37:00",22.66,30.83,433,1306.5,0.00525416760909382,1 +"1779","2015-02-03 17:38:00",22.68,30.87,433,1316.66666666667,0.0052674854976067,1 +"1780","2015-02-03 17:38:59",22.7,30.89,433,1306.33333333333,0.00527738159888531,1 +"1781","2015-02-03 17:39:59",22.7,30.79,429.5,1300.5,0.0052601526848178,1 +"1782","2015-02-03 17:41:00",22.675,30.7225,433,1298.66666666667,0.00524050115769863,1 +"1783","2015-02-03 17:42:00",22.675,30.745,424.6,1298.2,0.00524437146255304,1 +"1784","2015-02-03 17:43:00",22.7,30.7675,426,1292.5,0.00525627630958099,1 +"1785","2015-02-03 17:44:00",22.675,30.7225,426,1288.5,0.00524050115769863,1 +"1786","2015-02-03 17:44:59",22.7,30.7,433,1299.66666666667,0.00524464747133036,1 +"1787","2015-02-03 17:45:59",22.65,30.65,423.666666666667,1285.33333333333,0.00522003801051811,1 +"1788","2015-02-03 17:47:00",22.7,30.675,426,1286,0.00524034060362104,1 +"1789","2015-02-03 17:48:00",22.6,30.5833333333333,419,1284.33333333333,0.00519267151632743,1 +"1790","2015-02-03 17:49:00",22.6,30.575,422.5,1275.25,0.00519124481065258,1 +"1791","2015-02-03 17:50:00",22.6,30.6,419,1273.8,0.00519552494714966,1 +"1792","2015-02-03 17:51:00",22.6,30.6,419,1271.8,0.00519552494714966,1 +"1793","2015-02-03 17:51:59",22.6,30.55,419,1273.33333333333,0.00518696473257251,1 +"1794","2015-02-03 17:53:00",22.6,30.58,419,1261.75,0.00519210083327859,1 +"1795","2015-02-03 17:54:00",22.6,30.5666666666667,419,1258.5,0.0051898181114685,1 +"1796","2015-02-03 17:55:00",22.6,30.4725,419,1251.5,0.00517369686175147,1 +"1797","2015-02-03 17:55:59",22.6,30.445,419,1241.33333333333,0.00516898904252297,1 +"1798","2015-02-03 17:57:00",22.6,30.4725,419,1238.75,0.00517369686175147,1 +"1799","2015-02-03 17:57:59",22.6,30.37,419,1246.8,0.00515614989475787,1 +"1800","2015-02-03 17:58:59",22.6,30.315,419,1240.75,0.00514673485382115,1 +"1801","2015-02-03 18:00:00",22.6,30.365,419,1240.25,0.00515529397026419,1 +"1802","2015-02-03 18:01:00",22.6,30.275,426,1239,0.00513988772887235,1 +"1803","2015-02-03 18:02:00",22.6,30.245,422.5,1235.25,0.00513475248327749,1 +"1804","2015-02-03 18:03:00",22.6,30.254,424.6,1229.8,0.00513629304812559,1 +"1805","2015-02-03 18:04:00",22.6,30.18,419,1220.6,0.00512362640632125,1 +"1806","2015-02-03 18:04:59",22.6,30.1666666666667,419,1214.16666666667,0.00512134418292066,1 +"1807","2015-02-03 18:06:00",22.6,30.1,419,1214,0.00510993331507665,1 +"1808","2015-02-03 18:07:00",22.6,30.14,419,1217.8,0.00511677978595181,1 +"1809","2015-02-03 18:08:00",22.6,30.1,419,1211.8,0.00510993331507665,1 +"1810","2015-02-03 18:08:59",22.6,30.1,419,1217.2,0.00510993331507665,1 +"1811","2015-02-03 18:10:00",22.6,30.1,415.5,1211.5,0.00510993331507665,1 +"1812","2015-02-03 18:10:59",22.6,30.1816666666667,419,1207.33333333333,0.00512391168541428,1 +"1813","2015-02-03 18:11:59",22.6,30.1,419,1204.75,0.00510993331507665,1 +"1814","2015-02-03 18:13:00",22.6,30.1225,0,1205.25,0.00511378443654941,0 +"1815","2015-02-03 18:14:00",22.575,30.05,0,1204.75,0.00509357366672771,0 +"1816","2015-02-03 18:15:00",22.5,30.1,0,1196.66666666667,0.00507873673636185,0 +"1817","2015-02-03 18:16:00",22.5,30.1,0,1191.5,0.00507873673636185,0 +"1818","2015-02-03 18:16:59",22.5,30.1,0,1184,0.00507873673636185,0 +"1819","2015-02-03 18:17:59",22.445,30.1,0,1189.25,0.00506165039923841,0 +"1820","2015-02-03 18:19:00",22.39,30.075,0,1186.5,0.00504039100441317,0 +"1821","2015-02-03 18:20:00",22.39,30.1,0,1180.75,0.0050446148366279,0 +"1822","2015-02-03 18:21:00",22.39,30.05,0,1172.5,0.00503616722910233,0 +"1823","2015-02-03 18:22:00",22.365,30.075,0,1164,0.00503267083787181,0 +"1824","2015-02-03 18:23:00",22.3566666666667,30.1,0,1160.66666666667,0.0050343149090972,0 +"1825","2015-02-03 18:23:59",22.29,30,0,1143.25,0.00499697987960895,0 +"1826","2015-02-03 18:24:59",22.2675,29.945,0,1139.5,0.0049808645484254,0 +"1827","2015-02-03 18:26:00",22.245,29.9725,0,1138.25,0.00497859662034063,0 +"1828","2015-02-03 18:27:00",22.2,29.815,0,1135.5,0.00493856761746771,0 +"1829","2015-02-03 18:28:00",22.2,29.84,0,1124.75,0.0049427415333592,0 +"1830","2015-02-03 18:29:00",22.2,29.8566666666667,0,1119.33333333333,0.00494552417482958,0 +"1831","2015-02-03 18:29:59",22.125,29.79,0,1110.25,0.00491172182783557,0 +"1832","2015-02-03 18:30:59",22.1,29.79,0,1105.5,0.0049041849823736,0 +"1833","2015-02-03 18:32:00",22.1,29.745,0,1096.75,0.00489671852714075,0 +"1834","2015-02-03 18:33:00",22.1,29.7,0,1092.25,0.00488925224975737,0 +"1835","2015-02-03 18:34:00",22.1,29.6,0,1092.5,0.00487266115895176,0 +"1836","2015-02-03 18:35:00",22.025,29.525,0,1085.75,0.00483787282281954,0 +"1837","2015-02-03 18:36:00",22,29.4633333333333,0,1074.33333333333,0.00482027729718789,0 +"1838","2015-02-03 18:36:59",22,29.39,0,1066,0.0048081870314844,0 +"1839","2015-02-03 18:38:00",22,29.39,0,1058.5,0.0048081870314844,0 +"1840","2015-02-03 18:39:00",21.9175,29.29,0,1050.75,0.00476745642321002,0 +"1841","2015-02-03 18:40:00",21.89,29.2675,0,1044,0.00475571494671863,0 +"1842","2015-02-03 18:40:59",21.9633333333333,29.2,0,1039,0.00476610928505314,0 +"1843","2015-02-03 18:42:00",21.89,29.2,0,1030.5,0.00474466311607751,0 +"1844","2015-02-03 18:42:59",21.89,29.2,0,1030.8,0.00474466311607751,0 +"1845","2015-02-03 18:43:59",21.89,29.2,0,1032.33333333333,0.00474466311607751,0 +"1846","2015-02-03 18:45:00",21.89,29.16,0,1021.2,0.00473811406702397,0 +"1847","2015-02-03 18:46:00",21.89,29.2,0,1018.66666666667,0.00474466311607751,0 +"1848","2015-02-03 18:47:00",21.89,29.2,0,1008.75,0.00474466311607751,0 +"1849","2015-02-03 18:48:00",21.79,29,0,1003.25,0.00468301413344449,0 +"1850","2015-02-03 18:49:00",21.81,29,0,989.8,0.00468878260131167,0 +"1851","2015-02-03 18:49:59",21.815,29,0,992,0.0046902256978545,0 +"1852","2015-02-03 18:51:00",21.79,28.9725,0,985.75,0.00467853994159167,0 +"1853","2015-02-03 18:52:00",21.79,28.89,0,989,0.00466511774934596,0 +"1854","2015-02-03 18:53:00",21.7225,28.89,0,983,0.00464577016201608,0 +"1855","2015-02-03 18:53:59",21.7,28.89,0,976.75,0.00463933672315574,0 +"1856","2015-02-03 18:55:00",21.7,28.89,0,970.333333333333,0.00463933672315574,0 +"1857","2015-02-03 18:55:59",21.7,28.865,0,961.75,0.00463529214876545,0 +"1858","2015-02-03 18:56:59",21.7,28.865,0,958.75,0.00463529214876545,0 +"1859","2015-02-03 18:58:00",21.7,28.89,0,954.666666666667,0.00463933672315574,0 +"1860","2015-02-03 18:59:00",21.7,28.79,0,950.5,0.00462315873885162,0 +"1861","2015-02-03 19:00:00",21.7,28.815,0,942.75,0.0046272031566144,0 +"1862","2015-02-03 19:01:00",21.675,28.79,0,938.25,0.00461604477513936,0 +"1863","2015-02-03 19:01:59",21.675,28.7675,0,941,0.00461241048602348,0 +"1864","2015-02-03 19:02:59",21.6333333333333,28.73,0,944.333333333333,0.00459454332333087,0 +"1865","2015-02-03 19:04:00",21.6,28.65,0,938,0.00457225317349586,0 +"1866","2015-02-03 19:05:00",21.6,28.675,0,934.5,0.00457627227719972,0 +"1867","2015-02-03 19:06:00",21.6,28.6333333333333,0,936.666666666667,0.00456957379967104,0 +"1868","2015-02-03 19:07:00",21.6,28.6,0,926,0.00456421512076671,0 +"1869","2015-02-03 19:08:00",21.6,28.6,0,920.75,0.00456421512076671,0 +"1870","2015-02-03 19:08:59",21.6,28.56,0,920.2,0.00455778482707044,0 +"1871","2015-02-03 19:09:59",21.6,28.5,0,911.333333333333,0.00454813963399493,0 +"1872","2015-02-03 19:11:00",21.6,28.5,0,905.333333333333,0.00454813963399493,0 +"1873","2015-02-03 19:12:00",21.6,28.5,0,904.2,0.00454813963399493,0 +"1874","2015-02-03 19:13:00",21.6,28.5,0,899.666666666667,0.00454813963399493,0 +"1875","2015-02-03 19:14:00",21.6,28.478,0,898.2,0.00454460313760389,0 +"1876","2015-02-03 19:14:59",21.6,28.4725,0,898.25,0.00454371901974407,0 +"1877","2015-02-03 19:15:59",21.6,28.39,0,895,0.00453045755125964,0 +"1878","2015-02-03 19:17:00",21.6,28.39,0,891.666666666667,0.00453045755125964,0 +"1879","2015-02-03 19:18:00",21.58,28.35,0,887.4,0.00451845465409197,0 +"1880","2015-02-03 19:19:00",21.6,28.29,0,885.333333333333,0.00451438379662567,0 +"1881","2015-02-03 19:20:00",21.56,28.29,0,876.4,0.00450326718351884,0 +"1882","2015-02-03 19:21:00",21.5333333333333,28.29,0,871.333333333333,0.00449586953536044,0 +"1883","2015-02-03 19:21:59",21.5,28.29,0,863.5,0.00448663755713656,0 +"1884","2015-02-03 19:23:00",21.5,28.2675,0,865.25,0.00448304346261749,0 +"1885","2015-02-03 19:24:00",21.5,28.23,0,859.666666666667,0.00447705339672475,0 +"1886","2015-02-03 19:25:00",21.5,28.26,0,858.666666666667,0.00448184544027511,0 +"1887","2015-02-03 19:25:59",21.5,28.2,0,852.25,0.00447226142648379,0 +"1888","2015-02-03 19:27:00",21.5,28.175,0,849.25,0.00446826817394868,0 +"1889","2015-02-03 19:27:59",21.5,28.1,0,849,0.00445628872178248,0 +"1890","2015-02-03 19:28:59",21.5,28.1,0,845,0.00445628872178248,0 +"1891","2015-02-03 19:30:00",21.5,28.1,0,844.5,0.00445628872178248,0 +"1892","2015-02-03 19:31:00",21.5,28.05,0,843.75,0.0044483026748612,0 +"1893","2015-02-03 19:32:00",21.5,28.075,0,842,0.0044522956728702,0 +"1894","2015-02-03 19:33:00",21.5,28.1,0,833.2,0.00445628872178248,0 +"1895","2015-02-03 19:34:00",21.5,28.0333333333333,0,832.666666666667,0.00444564070446765,0 +"1896","2015-02-03 19:34:59",21.4175,27.945,0,825.25,0.00440903711468536,0 +"1897","2015-02-03 19:36:00",21.39,27.89,0,820.333333333333,0.00439283690920249,0 +"1898","2015-02-03 19:37:00",21.4175,27.9175,0,824.5,0.0044046675624544,0 +"1899","2015-02-03 19:38:00",21.39,27.89,0,819.25,0.00439283690920249,0 +"1900","2015-02-03 19:38:59",21.39,27.89,0,820.2,0.00439283690920249,0 +"1901","2015-02-03 19:40:00",21.39,27.89,0,817.666666666667,0.00439283690920249,0 +"1902","2015-02-03 19:40:59",21.365,27.89,0,808,0.00438606372384652,0 +"1903","2015-02-03 19:41:59",21.39,27.79,0,806.666666666667,0.00437697549281461,0 +"1904","2015-02-03 19:43:00",21.39,27.8566666666667,0,804.666666666667,0.00438754968115165,0 +"1905","2015-02-03 19:44:00",21.29,27.85,0,803.8,0.00435949408340988,0 +"1906","2015-02-03 19:45:00",21.29,27.79,0,806,0.00435003631085442,0 +"1907","2015-02-03 19:46:00",21.29,27.79,0,801.5,0.00435003631085442,0 +"1908","2015-02-03 19:46:59",21.34,27.79,0,802,0.00436348755838157,0 +"1909","2015-02-03 19:47:59",21.29,27.79,0,803.666666666667,0.00435003631085442,0 +"1910","2015-02-03 19:49:00",21.29,27.79,0,800,0.00435003631085442,0 +"1911","2015-02-03 19:50:00",21.29,27.79,0,795,0.00435003631085442,0 +"1912","2015-02-03 19:51:00",21.29,27.79,0,785,0.00435003631085442,0 +"1913","2015-02-03 19:52:00",21.29,27.79,0,781,0.00435003631085442,0 +"1914","2015-02-03 19:53:00",21.29,27.79,0,782,0.00435003631085442,0 +"1915","2015-02-03 19:53:59",21.29,27.7675,0,778,0.00434648971978134,0 +"1916","2015-02-03 19:54:59",21.29,27.79,0,772.5,0.00435003631085442,0 +"1917","2015-02-03 19:56:00",21.245,27.745,0,770.75,0.00433088816734843,0 +"1918","2015-02-03 19:57:00",21.218,27.718,0,769,0.00431943255623199,0 +"1919","2015-02-03 19:58:00",21.23,27.7,0,767,0.00431980984000691,0 +"1920","2015-02-03 19:59:00",21.2,27.7,0,764,0.00431180931830607,0 +"1921","2015-02-03 19:59:59",21.2,27.7,0,765.25,0.00431180931830607,0 +"1922","2015-02-03 20:00:59",21.2,27.65,0,765,0.00430397241364211,0 +"1923","2015-02-03 20:02:00",21.2,27.6,0,766,0.00429613570509869,0 +"1924","2015-02-03 20:03:00",21.2,27.6,0,758.5,0.00429613570509869,0 +"1925","2015-02-03 20:04:00",21.2,27.575,0,749.75,0.00429221742436988,0 +"1926","2015-02-03 20:05:00",21.2,27.6,0,749,0.00429613570509869,0 +"1927","2015-02-03 20:06:00",21.2,27.54,0,747.8,0.00428673191371534,0 +"1928","2015-02-03 20:06:59",21.2,27.5,0,744,0.00428046287634404,0 +"1929","2015-02-03 20:08:00",21.2,27.5,0,746.4,0.00428046287634404,0 +"1930","2015-02-03 20:09:00",21.2,27.4725,0,750.5,0.00427615298595305,0 +"1931","2015-02-03 20:10:00",21.2,27.5,0,747,0.00428046287634404,0 +"1932","2015-02-03 20:10:59",21.2,27.4725,0,750,0.00427615298595305,0 +"1933","2015-02-03 20:12:00",21.2,27.365,0,742.75,0.00425930580175908,0 +"1934","2015-02-03 20:12:59",21.2,27.34,0,737.75,0.00425538798185127,0 +"1935","2015-02-03 20:13:59",21.2,27.34,0,736.25,0.00425538798185127,0 +"1936","2015-02-03 20:15:00",21.2,27.29,0,738.25,0.00424755248909092,0 +"1937","2015-02-03 20:16:00",21.2,27.29,0,732.333333333333,0.00424755248909092,0 +"1938","2015-02-03 20:17:00",21.2,27.29,0,725.4,0.00424755248909092,0 +"1939","2015-02-03 20:18:00",21.2,27.2675,0,729.25,0.00424402658131624,0 +"1940","2015-02-03 20:19:00",21.2,27.245,0,727,0.00424050071324457,0 +"1941","2015-02-03 20:19:59",21.2,27.245,0,716.75,0.00424050071324457,0 +"1942","2015-02-03 20:21:00",21.2,27.2,0,715.666666666667,0.00423344909620756,0 +"1943","2015-02-03 20:22:00",21.2,27.2,0,712.25,0.00423344909620756,0 +"1944","2015-02-03 20:23:00",21.2,27.2,0,719,0.00423344909620756,0 +"1945","2015-02-03 20:23:59",21.2,27.15,0,714.25,0.0042256141524178,0 +"1946","2015-02-03 20:25:00",21.2,27.14,0,711.4,0.00422404718718571,0 +"1947","2015-02-03 20:25:59",21.2,27.1,0,702.75,0.00421777940467497,0 +"1948","2015-02-03 20:26:59",21.2,27.1,0,701,0.00421777940467497,0 +"1949","2015-02-03 20:28:00",21.2,27.1,0,703.666666666667,0.00421777940467497,0 +"1950","2015-02-03 20:29:00",21.2,27.025,0,707.25,0.00420602765063266,0 +"1951","2015-02-03 20:30:00",21.2,27,0,703.75,0.00420211049730072,0 +"1952","2015-02-03 20:31:00",21.2,27,0,699.5,0.00420211049730072,0 +"1953","2015-02-03 20:31:59",21.2,27,0,697.5,0.00420211049730072,0 +"1954","2015-02-03 20:32:59",21.2,27,0,696.666666666667,0.00420211049730072,0 +"1955","2015-02-03 20:34:00",21.2,27,0,692.75,0.00420211049730072,0 +"1956","2015-02-03 20:35:00",21.2,27,0,692.6,0.00420211049730072,0 +"1957","2015-02-03 20:36:00",21.2,26.8566666666667,0,695.333333333333,0.00417965309743181,0 +"1958","2015-02-03 20:37:00",21.2,26.89,0,690.5,0.00418487560482166,0 +"1959","2015-02-03 20:38:00",21.2,26.89,0,689.5,0.00418487560482166,0 +"1960","2015-02-03 20:38:59",21.2,26.89,0,692.333333333333,0.00418487560482166,0 +"1961","2015-02-03 20:39:59",21.2,26.815,0,691.5,0.00417312508569661,0 +"1962","2015-02-03 20:41:00",21.2,26.79,0,687.6,0.00416920834398832,0 +"1963","2015-02-03 20:42:00",21.1666666666667,26.79,0,682.333333333333,0.00416062964814346,0 +"1964","2015-02-03 20:43:00",21.2,26.79,0,677.666666666667,0.00416920834398832,0 +"1965","2015-02-03 20:44:00",21.16,26.79,0,677.8,0.00415891577864711,0 +"1966","2015-02-03 20:44:59",21.2,26.79,0,684.333333333333,0.00416920834398832,0 +"1967","2015-02-03 20:45:59",21.15,26.79,0,682.5,0.00415634614203119,0 +"1968","2015-02-03 20:47:00",21.175,26.79,0,675,0.00416277286107906,0 +"1969","2015-02-03 20:48:00",21.125,26.79,0,669.25,0.00414992817653432,0 +"1970","2015-02-03 20:49:00",21.2,26.745,0,668.5,0.00416215833238896,0 +"1971","2015-02-03 20:50:00",21.15,26.7,0,671.25,0.0041422900640776,0 +"1972","2015-02-03 20:51:00",21.1,26.7,0,674.333333333333,0.00412950654185839,0 +"1973","2015-02-03 20:51:59",21.125,26.675,0,673,0.00413199566084617,0 +"1974","2015-02-03 20:53:00",21.125,26.6,0,671.5,0.00412030109528856,0 +"1975","2015-02-03 20:54:00",21.125,26.625,0,670.5,0.00412419923526858,0 +"1976","2015-02-03 20:55:00",21.1,26.625,0,669.75,0.00411783001057564,0 +"1977","2015-02-03 20:55:59",21.1,26.6,0,663.5,0.00411393793025976,0 +"1978","2015-02-03 20:57:00",21.1,26.6,0,665,0.00411393793025976,0 +"1979","2015-02-03 20:57:59",21.1,26.6,0,661.5,0.00411393793025976,0 +"1980","2015-02-03 20:58:59",21.1,26.6,0,657.75,0.00411393793025976,0 +"1981","2015-02-03 21:00:00",21.1,26.6,0,652.75,0.00411393793025976,0 +"1982","2015-02-03 21:01:00",21.1,26.6,0,653.25,0.00411393793025976,0 +"1983","2015-02-03 21:02:00",21.1,26.6,0,656.75,0.00411393793025976,0 +"1984","2015-02-03 21:03:00",21.1,26.6,0,651,0.00411393793025976,0 +"1985","2015-02-03 21:04:00",21.1,26.575,0,648.5,0.00411004589833156,0 +"1986","2015-02-03 21:04:59",21.1,26.55,0,652.25,0.00410615391479014,0 +"1987","2015-02-03 21:06:00",21.1,26.5,0,642.25,0.00409837009286403,0 +"1988","2015-02-03 21:07:00",21.1,26.5,0,643.75,0.00409837009286403,0 +"1989","2015-02-03 21:08:00",21.075,26.4725,0,649.666666666667,0.0040877654367767,0 +"1990","2015-02-03 21:08:59",21.1,26.5,0,649.5,0.00409837009286403,0 +"1991","2015-02-03 21:10:00",21.06,26.412,0,646.6,0.00407458077132825,0 +"1992","2015-02-03 21:10:59",21.0666666666667,26.4633333333333,0,643,0.00408423543698301,0 +"1993","2015-02-03 21:11:59",21.08,26.478,0,640.4,0.00408988460864459,0 +"1994","2015-02-03 21:13:00",21.075,26.39,0,640.75,0.00407494269500011,0 +"1995","2015-02-03 21:14:00",21.075,26.4175,0,636.75,0.00407921688389874,0 +"1996","2015-02-03 21:15:00",21.05,26.39,0,634.75,0.00406864761293942,0 +"1997","2015-02-03 21:16:00",21.075,26.4175,0,633.75,0.00407921688389874,0 +"1998","2015-02-03 21:16:59",21,26.29,0,632,0.00404061355695366,0 +"1999","2015-02-03 21:17:59",21,26.29,0,626.5,0.00404061355695366,0 +"2000","2015-02-03 21:19:00",21.0333333333333,26.3233333333333,0,628.666666666667,0.00405412106853874,0 +"2001","2015-02-03 21:20:00",21.025,26.315,0,629.5,0.00405074075050262,0 +"2002","2015-02-03 21:21:00",21.05,26.34,0,630.5,0.00406088859278804,0 +"2003","2015-02-03 21:22:00",21.025,26.315,0,631.5,0.00405074075050262,0 +"2004","2015-02-03 21:23:00",21.025,26.315,0,629.5,0.00405074075050262,0 +"2005","2015-02-03 21:23:59",21.05,26.29,0,627,0.00405312976495311,0 +"2006","2015-02-03 21:24:59",21,26.2675,0,624.5,0.00403713299829174,0 +"2007","2015-02-03 21:26:00",21,26.26,0,625.666666666667,0.00403597282067138,0 +"2008","2015-02-03 21:27:00",21,26.29,0,624.5,0.00404061355695366,0 +"2009","2015-02-03 21:28:00",21,26.236,0,622,0.00403226028118273,0 +"2010","2015-02-03 21:29:00",21,26.2675,0,622.75,0.00403713299829174,0 +"2011","2015-02-03 21:29:59",21,26.2,0,619.25,0.00402669155450986,0 +"2012","2015-02-03 21:30:59",21,26.2,0,616,0.00402669155450986,0 +"2013","2015-02-03 21:32:00",21,26.2,0,617.25,0.00402669155450986,0 +"2014","2015-02-03 21:33:00",21,26.2,0,616.4,0.00402669155450986,0 +"2015","2015-02-03 21:34:00",21,26.1666666666667,0,616.666666666667,0.00402153541444294,0 +"2016","2015-02-03 21:35:00",21,26.125,0,614.75,0.00401509035879788,0 +"2017","2015-02-03 21:36:00",21,26.125,0,611.333333333333,0.00401509035879788,0 +"2018","2015-02-03 21:36:59",21,26.1,0,613.6,0.00401122338910984,0 +"2019","2015-02-03 21:38:00",21,26.15,0,608.75,0.00401895737625997,0 +"2020","2015-02-03 21:39:00",21,26.1,0,611,0.00401122338910984,0 +"2021","2015-02-03 21:40:00",21,26.1,0,612,0.00401122338910984,0 +"2022","2015-02-03 21:40:59",21,26.1,0,608.8,0.00401122338910984,0 +"2023","2015-02-03 21:42:00",21,26.1,0,612,0.00401122338910984,0 +"2024","2015-02-03 21:42:59",21,26.1,0,604.5,0.00401122338910984,0 +"2025","2015-02-03 21:43:59",21,26,0,607,0.00399575598808051,0 +"2026","2015-02-03 21:45:00",21,26,0,614.75,0.00399575598808051,0 +"2027","2015-02-03 21:46:00",21,26,0,612.25,0.00399575598808051,0 +"2028","2015-02-03 21:47:00",21,26,0,607.5,0.00399575598808051,0 +"2029","2015-02-03 21:48:00",21,26,0,602.666666666667,0.00399575598808051,0 +"2030","2015-02-03 21:49:00",21,26,0,605.25,0.00399575598808051,0 +"2031","2015-02-03 21:49:59",21,26,0,606,0.00399575598808051,0 +"2032","2015-02-03 21:51:00",21,26,0,602.25,0.00399575598808051,0 +"2033","2015-02-03 21:52:00",21,25.956,0,600.5,0.00398895057376564,0 +"2034","2015-02-03 21:53:00",21,26,0,600.5,0.00399575598808051,0 +"2035","2015-02-03 21:53:59",21,26,0,601,0.00399575598808051,0 +"2036","2015-02-03 21:55:00",21,25.934,0,600.4,0.0039855479220959,0 +"2037","2015-02-03 21:55:59",21,25.89,0,604.333333333333,0.00397874272972879,0 +"2038","2015-02-03 21:56:59",21,25.89,0,606,0.00397874272972879,0 +"2039","2015-02-03 21:58:00",20.9633333333333,25.89,0,602,0.00396972695597109,0 +"2040","2015-02-03 21:59:00",21,25.89,0,596,0.00397874272972879,0 +"2041","2015-02-03 22:00:00",21,25.89,0,596.333333333333,0.00397874272972879,0 +"2042","2015-02-03 22:01:00",21,25.89,0,594,0.00397874272972879,0 +"2043","2015-02-03 22:01:59",20.945,25.89,0,596.5,0.00396522582885432,0 +"2044","2015-02-03 22:02:59",20.9633333333333,25.89,0,596,0.00396972695597109,0 +"2045","2015-02-03 22:04:00",20.9725,25.815,0,597.5,0.00396039963283484,0 +"2046","2015-02-03 22:05:00",21,25.815,0,594.25,0.00396714331105683,0 +"2047","2015-02-03 22:06:00",21,25.815,0,591.5,0.00396714331105683,0 +"2048","2015-02-03 22:07:00",20.978,25.83,0,594.2,0.00396406423329848,0 +"2049","2015-02-03 22:08:00",20.9633333333333,25.79,0,588.666666666667,0.00395429642658738,0 +"2050","2015-02-03 22:08:59",20.9266666666667,25.79,0,585.333333333333,0.00394533386883401,0 +"2051","2015-02-03 22:09:59",20.945,25.79,0,585,0.00394981290597816,0 +"2052","2015-02-03 22:11:00",20.945,25.79,0,582.25,0.00394981290597816,0 +"2053","2015-02-03 22:12:00",20.89,25.79,0,580.75,0.00393638922946585,0 +"2054","2015-02-03 22:13:00",20.9175,25.745,0,585,0.00393617233116675,0 +"2055","2015-02-03 22:14:00",20.89,25.7225,0,584.5,0.00392602151357463,0 +"2056","2015-02-03 22:14:59",20.9633333333333,25.7,0,583.333333333333,0.00394040960056339,0 +"2057","2015-02-03 22:15:59",20.89,25.7,0,584,0.00392256568459979,0 +"2058","2015-02-03 22:17:00",20.912,25.7,0,581.8,0.00392791136236446,0 +"2059","2015-02-03 22:18:00",20.89,25.7,0,576.666666666667,0.00392256568459979,0 +"2060","2015-02-03 22:19:00",20.89,25.7,0,579.333333333333,0.00392256568459979,0 +"2061","2015-02-03 22:20:00",20.89,25.7,0,581.75,0.00392256568459979,0 +"2062","2015-02-03 22:21:00",20.89,25.7,0,582.75,0.00392256568459979,0 +"2063","2015-02-03 22:21:59",20.89,25.7,0,579.8,0.00392256568459979,0 +"2064","2015-02-03 22:23:00",20.9175,25.7,0,578.5,0.003929248785149,0 +"2065","2015-02-03 22:24:00",20.89,25.7,0,578.5,0.00392256568459979,0 +"2066","2015-02-03 22:25:00",20.89,25.7,0,580.5,0.00392256568459979,0 +"2067","2015-02-03 22:25:59",20.89,25.7,0,577.8,0.00392256568459979,0 +"2068","2015-02-03 22:27:00",20.89,25.7,0,582.75,0.00392256568459979,0 +"2069","2015-02-03 22:27:59",20.89,25.7,0,584.4,0.00392256568459979,0 +"2070","2015-02-03 22:28:59",20.89,25.6,0,582.666666666667,0.00390720690639245,0 +"2071","2015-02-03 22:30:00",20.865,25.575,0,578.25,0.00389733036200245,0 +"2072","2015-02-03 22:31:00",20.89,25.6,0,575.666666666667,0.00390720690639245,0 +"2073","2015-02-03 22:32:00",20.89,25.6,0,577.25,0.00390720690639245,0 +"2074","2015-02-03 22:33:00",20.87,25.58,0,577.2,0.00389930405186146,0 +"2075","2015-02-03 22:34:00",20.89,25.6,0,572.75,0.00390720690639245,0 +"2076","2015-02-03 22:34:59",20.89,25.6,0,576.5,0.00390720690639245,0 +"2077","2015-02-03 22:36:00",20.89,25.525,0,579.333333333333,0.00389568831737105,0 +"2078","2015-02-03 22:37:00",20.89,25.525,0,571.6,0.00389568831737105,0 +"2079","2015-02-03 22:38:00",20.89,25.5,0,573,0.00389184888190864,0 +"2080","2015-02-03 22:38:59",20.89,25.5,0,573.5,0.00389184888190864,0 +"2081","2015-02-03 22:40:00",20.89,25.5,0,572.75,0.00389184888190864,0 +"2082","2015-02-03 22:40:59",20.89,25.5,0,573.6,0.00389184888190864,0 +"2083","2015-02-03 22:41:59",20.89,25.5,0,571.5,0.00389184888190864,0 +"2084","2015-02-03 22:43:00",20.8566666666667,25.4633333333333,0,573.333333333333,0.00387820591111703,0 +"2085","2015-02-03 22:44:00",20.89,25.4725,0,570.75,0.00388762555730537,0 +"2086","2015-02-03 22:45:00",20.89,25.39,0,568,0.0038749559254609,0 +"2087","2015-02-03 22:46:00",20.89,25.4175,0,573,0.00387917907908266,0 +"2088","2015-02-03 22:46:59",20.89,25.39,0,569.666666666667,0.0038749559254609,0 +"2089","2015-02-03 22:47:59",20.89,25.39,0,575.2,0.0038749559254609,0 +"2090","2015-02-03 22:49:00",20.89,25.39,0,578,0.0038749559254609,0 +"2091","2015-02-03 22:50:00",20.89,25.39,0,572.75,0.0038749559254609,0 +"2092","2015-02-03 22:51:00",20.89,25.39,0,569.6,0.0038749559254609,0 +"2093","2015-02-03 22:52:00",20.8566666666667,25.3566666666667,0,566.333333333333,0.00386185912300041,0 +"2094","2015-02-03 22:53:00",20.8566666666667,25.3566666666667,0,567.333333333333,0.00386185912300041,0 +"2095","2015-02-03 22:53:59",20.865,25.365,0,570.25,0.00386512996367583,0 +"2096","2015-02-03 22:54:59",20.89,25.39,0,575,0.0038749559254609,0 +"2097","2015-02-03 22:56:00",20.89,25.37,0,570.2,0.00387188457680511,0 +"2098","2015-02-03 22:57:00",20.89,25.3566666666667,0,565.333333333333,0.00386983702778119,0 +"2099","2015-02-03 22:58:00",20.89,25.29,0,569.25,0.0038595994836159,0 +"2100","2015-02-03 22:59:00",20.89,25.315,0,567.25,0.00386343852342952,0 +"2101","2015-02-03 22:59:59",20.89,25.29,0,567.5,0.0038595994836159,0 +"2102","2015-02-03 23:00:59",20.865,25.2675,0,566,0.0038501809049505,0 +"2103","2015-02-03 23:02:00",20.89,25.29,0,565.75,0.0038595994836159,0 +"2104","2015-02-03 23:03:00",20.89,25.2675,0,564.5,0.00385614438805157,0 +"2105","2015-02-03 23:04:00",20.89,25.218,0,562.6,0.00384854331208982,0 +"2106","2015-02-03 23:05:00",20.89,25.29,0,561.333333333333,0.0038595994836159,0 +"2107","2015-02-03 23:06:00",20.89,25.29,0,561,0.0038595994836159,0 +"2108","2015-02-03 23:06:59",20.89,25.29,0,566.75,0.0038595994836159,0 +"2109","2015-02-03 23:08:00",20.9175,25.245,0,563.75,0.0038592526447835,0 +"2110","2015-02-03 23:09:00",20.89,25.2,0,566.75,0.00384577933024355,0 +"2111","2015-02-03 23:10:00",20.89,25.218,0,563.4,0.00384854331208982,0 +"2112","2015-02-03 23:10:59",20.89,25.2,0,564.25,0.00384577933024355,0 +"2113","2015-02-03 23:12:00",20.89,25.2225,0,562.75,0.00384923431136602,0 +"2114","2015-02-03 23:12:59",20.9175,25.2,0,560,0.00385233080028532,0 +"2115","2015-02-03 23:13:59",20.89,25.2,0,558.75,0.00384577933024355,0 +"2116","2015-02-03 23:15:00",20.89,25.2,0,558.5,0.00384577933024355,0 +"2117","2015-02-03 23:16:00",20.89,25.2,0,558.333333333333,0.00384577933024355,0 +"2118","2015-02-03 23:17:00",20.89,25.2,0,561.4,0.00384577933024355,0 +"2119","2015-02-03 23:18:00",20.89,25.2,0,558.25,0.00384577933024355,0 +"2120","2015-02-03 23:19:00",20.89,25.2,0,557.2,0.00384577933024355,0 +"2121","2015-02-03 23:19:59",20.89,25.2,0,559.666666666667,0.00384577933024355,0 +"2122","2015-02-03 23:21:00",20.89,25.1333333333333,0,561,0.00383554257309491,0 +"2123","2015-02-03 23:22:00",20.89,25.16,0,563.4,0.00383963723576866,0 +"2124","2015-02-03 23:23:00",20.9175,25.125,0,559.75,0.00384079473302138,0 +"2125","2015-02-03 23:23:59",20.9175,25.1,0,559,0.00383694947177254,0 +"2126","2015-02-03 23:25:00",20.9175,25.1,0,561,0.00383694947177254,0 +"2127","2015-02-03 23:25:59",20.89,25.1,0,563.25,0.00383042432009906,0 +"2128","2015-02-03 23:26:59",20.89,25.1,0,560.75,0.00383042432009906,0 +"2129","2015-02-03 23:28:00",20.89,25.1,0,558,0.00383042432009906,0 +"2130","2015-02-03 23:29:00",20.89,25.08,0,556.8,0.00382735340848547,0 +"2131","2015-02-03 23:30:00",20.89,25.125,0,556,0.00383426300199744,0 +"2132","2015-02-03 23:31:00",20.89,25.1,0,558,0.00383042432009906,0 +"2133","2015-02-03 23:31:59",20.89,25.08,0,556.8,0.00382735340848547,0 +"2134","2015-02-03 23:32:59",20.89,25.0666666666667,0,557,0.00382530615081945,0 +"2135","2015-02-03 23:34:00",20.89,25,0,556.8,0.00381507006340074,0 +"2136","2015-02-03 23:35:00",20.89,25.025,0,548.5,0.00381890855694277,0 +"2137","2015-02-03 23:36:00",20.89,25.05,0,550,0.00382274709757259,0 +"2138","2015-02-03 23:37:00",20.89,25,0,554,0.00381507006340074,0 +"2139","2015-02-03 23:38:00",20.89,25.025,0,555.25,0.00381890855694277,0 +"2140","2015-02-03 23:38:59",20.89,25,0,555.5,0.00381507006340074,0 +"2141","2015-02-03 23:39:59",20.89,25,0,556.75,0.00381507006340074,0 +"2142","2015-02-03 23:41:00",20.89,25,0,558,0.00381507006340074,0 +"2143","2015-02-03 23:42:00",20.89,25,0,558,0.00381507006340074,0 +"2144","2015-02-03 23:43:00",20.89,25,0,558.25,0.00381507006340074,0 +"2145","2015-02-03 23:44:00",20.89,25,0,556.25,0.00381507006340074,0 +"2146","2015-02-03 23:44:59",20.89,25,0,554.5,0.00381507006340074,0 +"2147","2015-02-03 23:45:59",20.89,25,0,555.25,0.00381507006340074,0 +"2148","2015-02-03 23:47:00",20.89,25,0,558,0.00381507006340074,0 +"2149","2015-02-03 23:48:00",20.89,25,0,554.333333333333,0.00381507006340074,0 +"2150","2015-02-03 23:49:00",20.89,25,0,549.75,0.00381507006340074,0 +"2151","2015-02-03 23:50:00",20.89,24.9725,0,558.5,0.00381084777488986,0 +"2152","2015-02-03 23:51:00",20.865,24.92,0,558.25,0.00379690673426888,0 +"2153","2015-02-03 23:51:59",20.89,24.9175,0,558.25,0.003802403368789,0 +"2154","2015-02-03 23:53:00",20.89,24.9725,0,547.25,0.00381084777488986,0 +"2155","2015-02-03 23:54:00",20.89,24.945,0,553.75,0.003806625543353,0 +"2156","2015-02-03 23:55:00",20.89,24.89,0,547.75,0.00379818125119672,0 +"2157","2015-02-03 23:55:59",20.89,24.89,0,547.25,0.00379818125119672,0 +"2158","2015-02-03 23:57:00",20.89,24.89,0,551.5,0.00379818125119672,0 +"2159","2015-02-03 23:57:59",20.89,24.89,0,554,0.00379818125119672,0 +"2160","2015-02-03 23:58:59",20.89,24.89,0,550,0.00379818125119672,0 +"2161","2015-02-04 00:00:00",20.89,24.9266666666667,0,553.666666666667,0.00380381075398009,0 +"2162","2015-02-04 00:01:00",20.89,24.934,0,552.4,0.00380493666669072,0 +"2163","2015-02-04 00:02:00",20.89,24.9266666666667,0,554,0.00380381075398009,0 +"2164","2015-02-04 00:03:00",20.83,24.87,0,547,0.00378103963992061,0 +"2165","2015-02-04 00:04:00",20.89,24.89,0,542.333333333333,0.00379818125119672,0 +"2166","2015-02-04 00:04:59",20.84,24.8925,0,544.75,0.00378682529133795,0 +"2167","2015-02-04 00:06:00",20.89,24.945,0,547,0.003806625543353,0 +"2168","2015-02-04 00:07:00",20.865,24.865,0,552.75,0.00378847568247451,0 +"2169","2015-02-04 00:08:00",20.89,25,0,556,0.00381507006340074,0 +"2170","2015-02-04 00:08:59",20.87,24.934,0,551.6,0.0038002289763746,0 +"2171","2015-02-04 00:10:00",20.84,24.92,0,553,0.00379103428623353,0 +"2172","2015-02-04 00:10:59",20.89,24.9725,0,551.25,0.00381084777488986,0 +"2173","2015-02-04 00:11:59",20.8566666666667,24.9266666666667,0,552.666666666667,0.00379596979195081,0 +"2174","2015-02-04 00:13:00",20.865,24.9725,0,553.75,0.00380495476836207,0 +"2175","2015-02-04 00:14:00",20.8566666666667,24.8566666666667,0,545.666666666667,0.00378524493481222,0 +"2176","2015-02-04 00:15:00",20.865,24.9175,0,547.75,0.00379652349971342,0 +"2177","2015-02-04 00:16:00",20.89,24.912,0,548.4,0.00380155894071285,0 +"2178","2015-02-04 00:16:59",20.89,24.9266666666667,0,549.333333333333,0.00380381075398009,0 +"2179","2015-02-04 00:17:59",20.89,25,0,549.333333333333,0.00381507006340074,0 +"2180","2015-02-04 00:19:00",20.865,24.8925,0,545.5,0.00379269117997465,0 +"2181","2015-02-04 00:20:00",20.89,24.9266666666667,0,543,0.00380381075398009,0 +"2182","2015-02-04 00:21:00",20.89,24.978,0,545.6,0.00381169222803407,0 +"2183","2015-02-04 00:22:00",20.85,24.956,0,547.6,0.00379889577981915,0 +"2184","2015-02-04 00:23:00",20.89,25,0,548.666666666667,0.00381507006340074,0 +"2185","2015-02-04 00:23:59",20.89,25,0,542.75,0.00381507006340074,0 +"2186","2015-02-04 00:24:59",20.87,24.978,0,537.2,0.00380697612849538,0 +"2187","2015-02-04 00:26:00",20.8566666666667,24.9266666666667,0,541.333333333333,0.00379596979195081,0 +"2188","2015-02-04 00:27:00",20.865,24.9725,0,545.25,0.00380495476836207,0 +"2189","2015-02-04 00:28:00",20.83,24.934,0,541.25,0.00379082899831852,0 +"2190","2015-02-04 00:29:00",20.8233333333333,24.9266666666667,0,535.5,0.0037881430827897,0 +"2191","2015-02-04 00:29:59",20.89,25,0,536.5,0.00381507006340074,0 +"2192","2015-02-04 00:30:59",20.87,24.978,0,543.8,0.00380697612849538,0 +"2193","2015-02-04 00:32:00",20.84,24.92,0,542,0.00379103428623353,0 +"2194","2015-02-04 00:33:00",20.84,24.945,0,537.25,0.00379486069436179,0 +"2195","2015-02-04 00:34:00",20.8233333333333,24.9266666666667,0,538,0.0037881430827897,0 +"2196","2015-02-04 00:35:00",20.8233333333333,24.9266666666667,0,542,0.0037881430827897,0 +"2197","2015-02-04 00:36:00",20.81,24.912,0,542,0.00378277576496328,0 +"2198","2015-02-04 00:36:59",20.79,24.89,0,545.333333333333,0.00377473606074636,0 +"2199","2015-02-04 00:38:00",20.865,24.9725,0,543.25,0.00380495476836207,0 +"2200","2015-02-04 00:39:00",20.8566666666667,24.93,0,539,0.00379648050860303,0 +"2201","2015-02-04 00:40:00",20.84,24.945,0,540.75,0.00379486069436179,0 +"2202","2015-02-04 00:40:59",20.79,24.9175,0,538,0.00377893195892112,0 +"2203","2015-02-04 00:42:00",20.79,24.89,0,538,0.00377473606074636,0 +"2204","2015-02-04 00:42:59",20.79,24.9266666666667,0,538.666666666667,0.00378033060415007,0 +"2205","2015-02-04 00:43:59",20.81,24.956,0,541.6,0.00378949767297425,0 +"2206","2015-02-04 00:45:00",20.79,24.89,0,537.5,0.00377473606074636,0 +"2207","2015-02-04 00:46:00",20.79,24.978,0,537.2,0.00378816313297203,0 +"2208","2015-02-04 00:47:00",20.79,24.9633333333333,0,541,0.00378592524758721,0 +"2209","2015-02-04 00:48:00",20.79,25,0,534,0.00379151999106046,0 +"2210","2015-02-04 00:49:00",20.79,25,0,532,0.00379151999106046,0 +"2211","2015-02-04 00:49:59",20.84,25,0,531.75,0.00380327895695843,0 +"2212","2015-02-04 00:51:00",20.79,25,0,532.8,0.00379151999106046,0 +"2213","2015-02-04 00:52:00",20.79,25,0,532,0.00379151999106046,0 +"2214","2015-02-04 00:53:00",20.8233333333333,24.9266666666667,0,533.666666666667,0.0037881430827897,0 +"2215","2015-02-04 00:53:59",20.79,25,0,531.75,0.00379151999106046,0 +"2216","2015-02-04 00:55:00",20.79,25,0,534.4,0.00379151999106046,0 +"2217","2015-02-04 00:55:59",20.79,25,0,535.666666666667,0.00379151999106046,0 +"2218","2015-02-04 00:56:59",20.79,25,0,529.75,0.00379151999106046,0 +"2219","2015-02-04 00:58:00",20.79,25,0,532,0.00379151999106046,0 +"2220","2015-02-04 00:59:00",20.79,25,0,531.333333333333,0.00379151999106046,0 +"2221","2015-02-04 01:00:00",20.79,25,0,529.75,0.00379151999106046,0 +"2222","2015-02-04 01:01:00",20.79,25,0,528.75,0.00379151999106046,0 +"2223","2015-02-04 01:01:59",20.79,25,0,528.25,0.00379151999106046,0 +"2224","2015-02-04 01:02:59",20.79,25,0,526,0.00379151999106046,0 +"2225","2015-02-04 01:04:00",20.79,25,0,526.5,0.00379151999106046,0 +"2226","2015-02-04 01:05:00",20.79,24.9633333333333,0,529.333333333333,0.00378592524758721,0 +"2227","2015-02-04 01:06:00",20.815,24.945,0,528.25,0.00378899030008008,0 +"2228","2015-02-04 01:07:00",20.81,24.934,0,526.8,0.00378613670091785,0 +"2229","2015-02-04 01:08:00",20.79,24.9725,0,525.5,0.00378732392407703,0 +"2230","2015-02-04 01:08:59",20.79,24.9633333333333,0,524.666666666667,0.00378592524758721,0 +"2231","2015-02-04 01:09:59",20.79,24.89,0,523,0.00377473606074636,0 +"2232","2015-02-04 01:11:00",20.79,24.89,0,526,0.00377473606074636,0 +"2233","2015-02-04 01:12:00",20.79,24.9725,0,523.25,0.00378732392407703,0 +"2234","2015-02-04 01:13:00",20.79,24.89,0,524.333333333333,0.00377473606074636,0 +"2235","2015-02-04 01:14:00",20.79,24.89,0,521.5,0.00377473606074636,0 +"2236","2015-02-04 01:14:59",20.79,24.912,0,518.6,0.00377809277478473,0 +"2237","2015-02-04 01:15:59",20.79,24.89,0,520.75,0.00377473606074636,0 +"2238","2015-02-04 01:17:00",20.79,24.89,0,527.666666666667,0.00377473606074636,0 +"2239","2015-02-04 01:18:00",20.79,24.945,0,526,0.0037831279133643,0 +"2240","2015-02-04 01:19:00",20.79,24.956,0,519.6,0.00378480631089698,0 +"2241","2015-02-04 01:20:00",20.79,24.9633333333333,0,518.333333333333,0.00378592524758721,0 +"2242","2015-02-04 01:21:00",20.79,24.9725,0,520.5,0.00378732392407703,0 +"2243","2015-02-04 01:21:59",20.79,24.945,0,521.75,0.0037831279133643,0 +"2244","2015-02-04 01:23:00",20.79,24.89,0,523,0.00377473606074636,0 +"2245","2015-02-04 01:24:00",20.79,24.89,0,520.333333333333,0.00377473606074636,0 +"2246","2015-02-04 01:25:00",20.79,24.89,0,519,0.00377473606074636,0 +"2247","2015-02-04 01:25:59",20.79,24.945,0,516.25,0.0037831279133643,0 +"2248","2015-02-04 01:27:00",20.79,25,0,518.6,0.00379151999106046,0 +"2249","2015-02-04 01:27:59",20.79,25,0,519.333333333333,0.00379151999106046,0 +"2250","2015-02-04 01:28:59",20.76,25,0,515.333333333333,0.00378448000753531,0 +"2251","2015-02-04 01:30:00",20.772,25,0,516.4,0.00378729461678286,0 +"2252","2015-02-04 01:31:00",20.745,25,0,519.5,0.00378096433944754,0 +"2253","2015-02-04 01:32:00",20.7675,25,0,522.25,0.003786238922116,0 +"2254","2015-02-04 01:33:00",20.7675,25,0,514.75,0.003786238922116,0 +"2255","2015-02-04 01:34:00",20.7675,25,0,513.75,0.003786238922116,0 +"2256","2015-02-04 01:34:59",20.79,25,0,515,0.00379151999106046,0 +"2257","2015-02-04 01:36:00",20.79,25,0,519,0.00379151999106046,0 +"2258","2015-02-04 01:37:00",20.772,25,0,518.8,0.00378729461678286,0 +"2259","2015-02-04 01:38:00",20.79,25,0,517.333333333333,0.00379151999106046,0 +"2260","2015-02-04 01:38:59",20.73,25.0666666666667,0,509.75,0.00378758609466528,0 +"2261","2015-02-04 01:40:00",20.718,25.04,0,513.6,0.00378071953151168,0 +"2262","2015-02-04 01:40:59",20.73,25.0666666666667,0,511,0.00378758609466528,0 +"2263","2015-02-04 01:41:59",20.718,25.1,0,512.4,0.00378983396134181,0 +"2264","2015-02-04 01:43:00",20.7,25.075,0,515.5,0.00378181468299795,0 +"2265","2015-02-04 01:44:00",20.736,25.1,0,511.8,0.00379406394707,0 +"2266","2015-02-04 01:45:00",20.73,25.1,0,511.666666666667,0.00379265348954902,0 +"2267","2015-02-04 01:46:00",20.7,25.05,0,509.75,0.00377802127782894,0 +"2268","2015-02-04 01:46:59",20.73,25.1,0,513,0.00379265348954902,0 +"2269","2015-02-04 01:47:59",20.7,25.1,0,508.5,0.00378560813415773,0 +"2270","2015-02-04 01:49:00",20.7,25.1,0,510,0.00378560813415773,0 +"2271","2015-02-04 01:50:00",20.7,25.1,0,509.666666666667,0.00378560813415773,0 +"2272","2015-02-04 01:51:00",20.7,25.1,0,508.5,0.00378560813415773,0 +"2273","2015-02-04 01:52:00",20.7,25.1,0,511.25,0.00378560813415773,0 +"2274","2015-02-04 01:53:00",20.7,25.1,0,513.333333333333,0.00378560813415773,0 +"2275","2015-02-04 01:53:59",20.7,25.1,0,509.5,0.00378560813415773,0 +"2276","2015-02-04 01:54:59",20.7,25.1,0,509,0.00378560813415773,0 +"2277","2015-02-04 01:56:00",20.7,25.1,0,509,0.00378560813415773,0 +"2278","2015-02-04 01:57:00",20.7,25.1,0,510.5,0.00378560813415773,0 +"2279","2015-02-04 01:58:00",20.7,25.1,0,512,0.00378560813415773,0 +"2280","2015-02-04 01:59:00",20.7,25.1,0,509,0.00378560813415773,0 +"2281","2015-02-04 01:59:59",20.68,25.12,0,508,0.00378394865473313,0 +"2282","2015-02-04 02:00:59",20.7,25.125,0,502.25,0.00378940163130914,0 +"2283","2015-02-04 02:02:00",20.675,25.1,0,502.5,0.00377974582194704,0 +"2284","2015-02-04 02:03:00",20.7,25.1,0,505.5,0.00378560813415773,0 +"2285","2015-02-04 02:04:00",20.7,25.1,0,505.5,0.00378560813415773,0 +"2286","2015-02-04 02:05:00",20.7,25.1,0,500.25,0.00378560813415773,0 +"2287","2015-02-04 02:06:00",20.68,25.1,0,500,0.00378091764363594,0 +"2288","2015-02-04 02:06:59",20.6666666666667,25.1,0,499,0.00377779349737419,0 +"2289","2015-02-04 02:08:00",20.7,25.1,0,501.25,0.00378560813415773,0 +"2290","2015-02-04 02:09:00",20.7,25.1,0,501,0.00378560813415773,0 +"2291","2015-02-04 02:10:00",20.7,25.1,0,502,0.00378560813415773,0 +"2292","2015-02-04 02:10:59",20.7,25.1,0,496.25,0.00378560813415773,0 +"2293","2015-02-04 02:12:00",20.7,25.1,0,495.8,0.00378560813415773,0 +"2294","2015-02-04 02:12:59",20.66,25.1,0,497.8,0.00377623227793241,0 +"2295","2015-02-04 02:13:59",20.6333333333333,25.1,0,497,0.00376999308725358,0 +"2296","2015-02-04 02:15:00",20.625,25.1,0,497.25,0.00376804520502069,0 +"2297","2015-02-04 02:16:00",20.675,25.175,0,503.25,0.00379110872081107,0 +"2298","2015-02-04 02:17:00",20.675,25.125,0,500,0.00378353340905175,0 +"2299","2015-02-04 02:18:00",20.7,25.1,0,494.75,0.00378560813415773,0 +"2300","2015-02-04 02:19:00",20.7,25.1,0,492.333333333333,0.00378560813415773,0 +"2301","2015-02-04 02:19:59",20.7,25.1,0,492.75,0.00378560813415773,0 +"2302","2015-02-04 02:21:00",20.7,25.1,0,497,0.00378560813415773,0 +"2303","2015-02-04 02:22:00",20.65,25.075,0,498.5,0.00377010987584578,0 +"2304","2015-02-04 02:23:00",20.7,25.1,0,498.75,0.00378560813415773,0 +"2305","2015-02-04 02:23:59",20.675,25.075,0,498.75,0.00377595828069119,0 +"2306","2015-02-04 02:25:00",20.7,25.1,0,495.333333333333,0.00378560813415773,0 +"2307","2015-02-04 02:25:59",20.675,25.075,0,490.75,0.00377595828069119,0 +"2308","2015-02-04 02:26:59",20.7,25.1,0,487.75,0.00378560813415773,0 +"2309","2015-02-04 02:28:00",20.65,25.05,0,491.75,0.00376632828201918,0 +"2310","2015-02-04 02:29:00",20.7,25.1,0,491.25,0.00378560813415773,0 +"2311","2015-02-04 02:30:00",20.7,25.1,0,493.5,0.00378560813415773,0 +"2312","2015-02-04 02:31:00",20.7,25.1,0,493.333333333333,0.00378560813415773,0 +"2313","2015-02-04 02:31:59",20.7,25,0,493.25,0.00377043460545993,0 +"2314","2015-02-04 02:32:59",20.7,25,0,491,0.00377043460545993,0 +"2315","2015-02-04 02:34:00",20.7,25,0,492,0.00377043460545993,0 +"2316","2015-02-04 02:35:00",20.7,25,0,496,0.00377043460545993,0 +"2317","2015-02-04 02:36:00",20.7,25,0,493,0.00377043460545993,0 +"2318","2015-02-04 02:37:00",20.7,25,0,491.25,0.00377043460545993,0 +"2319","2015-02-04 02:38:00",20.7,25,0,494,0.00377043460545993,0 +"2320","2015-02-04 02:38:59",20.7,25,0,494.2,0.00377043460545993,0 +"2321","2015-02-04 02:39:59",20.7,25,0,493.75,0.00377043460545993,0 +"2322","2015-02-04 02:41:00",20.7,25,0,495.75,0.00377043460545993,0 +"2323","2015-02-04 02:42:00",20.7,25,0,492.25,0.00377043460545993,0 +"2324","2015-02-04 02:43:00",20.7,25,0,486.5,0.00377043460545993,0 +"2325","2015-02-04 02:44:00",20.7,25,0,493.333333333333,0.00377043460545993,0 +"2326","2015-02-04 02:44:59",20.7,25,0,494.75,0.00377043460545993,0 +"2327","2015-02-04 02:45:59",20.7,25,0,490,0.00377043460545993,0 +"2328","2015-02-04 02:47:00",20.7,25,0,490.5,0.00377043460545993,0 +"2329","2015-02-04 02:48:00",20.7,25,0,490.25,0.00377043460545993,0 +"2330","2015-02-04 02:49:00",20.7,25,0,498.25,0.00377043460545993,0 +"2331","2015-02-04 02:50:00",20.7,25,0,499,0.00377043460545993,0 +"2332","2015-02-04 02:51:00",20.7,24.9633333333333,0,493,0.00376487116263545,0 +"2333","2015-02-04 02:51:59",20.7,24.9816666666667,0,484.833333333333,0.00376765287168212,0 +"2334","2015-02-04 02:53:00",20.7,24.9725,0,480,0.00376626201406741,0 +"2335","2015-02-04 02:54:00",20.7,24.9725,0,478.75,0.00376626201406741,0 +"2336","2015-02-04 02:55:00",20.7,25,0,483.333333333333,0.00377043460545993,0 +"2337","2015-02-04 02:55:59",20.7,25,0,480.2,0.00377043460545993,0 +"2338","2015-02-04 02:57:00",20.7,24.89,0,483.333333333333,0.00375374457375356,0 +"2339","2015-02-04 02:57:59",20.7,24.89,0,487,0.00375374457375356,0 +"2340","2015-02-04 02:58:59",20.7,24.85,0,485.2,0.00374767569204467,0 +"2341","2015-02-04 03:00:00",20.7,24.89,0,480.666666666667,0.00375374457375356,0 +"2342","2015-02-04 03:01:00",20.7,24.84,0,480.25,0.00374615849001089,0 +"2343","2015-02-04 03:02:00",20.7,24.79,0,486,0.00373857259019989,0 +"2344","2015-02-04 03:03:00",20.7,24.865,0,485.75,0.00374995150889035,0 +"2345","2015-02-04 03:04:00",20.7,24.815,0,483,0.00374236551711435,0 +"2346","2015-02-04 03:04:59",20.7,24.87,0,483.6,0.00375071011818426,0 +"2347","2015-02-04 03:06:00",20.7,24.79,0,489.333333333333,0.00373857259019989,0 +"2348","2015-02-04 03:07:00",20.7,24.79,0,486.75,0.00373857259019989,0 +"2349","2015-02-04 03:08:00",20.7,24.79,0,483.5,0.00373857259019989,0 +"2350","2015-02-04 03:08:59",20.7,24.79,0,482,0.00373857259019989,0 +"2351","2015-02-04 03:10:00",20.745,24.79,0,481.5,0.00374901280969807,0 +"2352","2015-02-04 03:10:59",20.7,24.79,0,488.25,0.00373857259019989,0 +"2353","2015-02-04 03:11:59",20.7,24.79,0,486.333333333333,0.00373857259019989,0 +"2354","2015-02-04 03:13:00",20.7,24.79,0,480.6,0.00373857259019989,0 +"2355","2015-02-04 03:14:00",20.7,24.79,0,485.666666666667,0.00373857259019989,0 +"2356","2015-02-04 03:15:00",20.7,24.79,0,484.8,0.00373857259019989,0 +"2357","2015-02-04 03:16:00",20.7,24.79,0,481,0.00373857259019989,0 +"2358","2015-02-04 03:16:59",20.7,24.79,0,486.5,0.00373857259019989,0 +"2359","2015-02-04 03:17:59",20.7,24.79,0,488,0.00373857259019989,0 +"2360","2015-02-04 03:19:00",20.7,24.79,0,481.666666666667,0.00373857259019989,0 +"2361","2015-02-04 03:20:00",20.7,24.79,0,481,0.00373857259019989,0 +"2362","2015-02-04 03:21:00",20.7,24.754,0,483,0.00373311085622271,0 +"2363","2015-02-04 03:22:00",20.7,24.7675,0,485,0.00373515899529087,0 +"2364","2015-02-04 03:23:00",20.7,24.76,0,475.666666666667,0.00373402113859771,0 +"2365","2015-02-04 03:23:59",20.7,24.7225,0,478.5,0.00372833191720482,0 +"2366","2015-02-04 03:24:59",20.7,24.7,0,482.8,0.00372491843402658,0 +"2367","2015-02-04 03:26:00",20.7,24.7,0,482.333333333333,0.00372491843402658,0 +"2368","2015-02-04 03:27:00",20.7,24.675,0,481.5,0.00372112571861894,0 +"2369","2015-02-04 03:28:00",20.7,24.675,0,479.25,0.00372112571861894,0 +"2370","2015-02-04 03:29:00",20.7,24.6,0,478.333333333333,0.00370974784825709,0 +"2371","2015-02-04 03:29:59",20.7,24.6,0,477.5,0.00370974784825709,0 +"2372","2015-02-04 03:30:59",20.7,24.6,0,480.25,0.00370974784825709,0 +"2373","2015-02-04 03:32:00",20.7,24.65,0,481.5,0.0037173330491887,0 +"2374","2015-02-04 03:33:00",20.7,24.65,0,481.25,0.0037173330491887,0 +"2375","2015-02-04 03:34:00",20.7,24.66,0,481.75,0.00371885011144356,0 +"2376","2015-02-04 03:35:00",20.7,24.7,0,479,0.00372491843402658,0 +"2377","2015-02-04 03:36:00",20.7,24.65,0,482.75,0.0037173330491887,0 +"2378","2015-02-04 03:36:59",20.7,24.6666666666667,0,485.666666666667,0.00371986149036697,0 +"2379","2015-02-04 03:38:00",20.7,24.6333333333333,0,484,0.00371480462844446,0 +"2380","2015-02-04 03:39:00",20.7,24.6,0,479.5,0.00370974784825709,0 +"2381","2015-02-04 03:40:00",20.7,24.6,0,479.75,0.00370974784825709,0 +"2382","2015-02-04 03:40:59",20.7,24.6,0,480.75,0.00370974784825709,0 +"2383","2015-02-04 03:42:00",20.7,24.6333333333333,0,475.333333333333,0.00371480462844446,0 +"2384","2015-02-04 03:42:59",20.7,24.7,0,475.666666666667,0.00372491843402658,0 +"2385","2015-02-04 03:43:59",20.7,24.6,0,477.25,0.00370974784825709,0 +"2386","2015-02-04 03:45:00",20.7,24.6,0,478.5,0.00370974784825709,0 +"2387","2015-02-04 03:46:00",20.7,24.64,0,479.6,0.00371581599429009,0 +"2388","2015-02-04 03:47:00",20.7,24.6,0,475.666666666667,0.00370974784825709,0 +"2389","2015-02-04 03:48:00",20.7,24.6,0,479.333333333333,0.00370974784825709,0 +"2390","2015-02-04 03:49:00",20.7,24.6,0,478.5,0.00370974784825709,0 +"2391","2015-02-04 03:49:59",20.7,24.6285714285714,0,476.857142857143,0.00371408222627069,0 +"2392","2015-02-04 03:51:00",20.7,24.6333333333333,0,477.333333333333,0.00371480462844446,0 +"2393","2015-02-04 03:52:00",20.7,24.625,0,475.25,0.00371354042573503,0 +"2394","2015-02-04 03:53:00",20.7,24.6,0,479.666666666667,0.00370974784825709,0 +"2395","2015-02-04 03:53:59",20.7,24.6,0,482,0.00370974784825709,0 +"2396","2015-02-04 03:55:00",20.7,24.6,0,475.8,0.00370974784825709,0 +"2397","2015-02-04 03:55:59",20.7,24.6,0,477.333333333333,0.00370974784825709,0 +"2398","2015-02-04 03:56:59",20.7,24.6,0,475.25,0.00370974784825709,0 +"2399","2015-02-04 03:58:00",20.7,24.6,0,477.25,0.00370974784825709,0 +"2400","2015-02-04 03:59:00",20.7,24.6,0,478.666666666667,0.00370974784825709,0 +"2401","2015-02-04 04:00:00",20.7,24.6,0,476.75,0.00370974784825709,0 +"2402","2015-02-04 04:01:00",20.7,24.6,0,472.5,0.00370974784825709,0 +"2403","2015-02-04 04:01:59",20.7,24.6,0,471.6,0.00370974784825709,0 +"2404","2015-02-04 04:02:59",20.7,24.6,0,474.75,0.00370974784825709,0 +"2405","2015-02-04 04:04:00",20.7,24.6,0,475.666666666667,0.00370974784825709,0 +"2406","2015-02-04 04:05:00",20.7,24.6,0,473.2,0.00370974784825709,0 +"2407","2015-02-04 04:06:00",20.7,24.6,0,467,0.00370974784825709,0 +"2408","2015-02-04 04:07:00",20.7,24.6,0,466,0.00370974784825709,0 +"2409","2015-02-04 04:08:00",20.7,24.6,0,465.25,0.00370974784825709,0 +"2410","2015-02-04 04:08:59",20.7,24.6,0,471,0.00370974784825709,0 +"2411","2015-02-04 04:09:59",20.7,24.6,0,471.5,0.00370974784825709,0 +"2412","2015-02-04 04:11:00",20.7,24.6,0,476.5,0.00370974784825709,0 +"2413","2015-02-04 04:12:00",20.7,24.6,0,472.75,0.00370974784825709,0 +"2414","2015-02-04 04:13:00",20.7,24.6,0,470.75,0.00370974784825709,0 +"2415","2015-02-04 04:14:00",20.7,24.575,0,466.75,0.00370595531675404,0 +"2416","2015-02-04 04:14:59",20.7,24.5,0,463.75,0.00369457799808589,0 +"2417","2015-02-04 04:15:59",20.7,24.5333333333333,0,469,0.00369963453307978,0 +"2418","2015-02-04 04:17:00",20.7,24.575,0,472.25,0.00370595531675404,0 +"2419","2015-02-04 04:18:00",20.7,24.6,0,475.4,0.00370974784825709,0 +"2420","2015-02-04 04:19:00",20.7,24.5,0,474.25,0.00369457799808589,0 +"2421","2015-02-04 04:20:00",20.7,24.5,0,470.25,0.00369457799808589,0 +"2422","2015-02-04 04:21:00",20.7,24.5333333333333,0,478,0.00369963453307978,0 +"2423","2015-02-04 04:21:59",20.7,24.56,0,469.4,0.00370367981991981,0 +"2424","2015-02-04 04:23:00",20.7,24.5333333333333,0,468.333333333333,0.00369963453307978,0 +"2425","2015-02-04 04:24:00",20.7,24.6,0,469.25,0.00370974784825709,0 +"2426","2015-02-04 04:25:00",20.7,24.6,0,468,0.00370974784825709,0 +"2427","2015-02-04 04:25:59",20.7,24.6,0,473,0.00370974784825709,0 +"2428","2015-02-04 04:27:00",20.7,24.5666666666667,0,474.333333333333,0.00370469114980285,0 +"2429","2015-02-04 04:27:59",20.7,24.5,0,475.75,0.00369457799808589,0 +"2430","2015-02-04 04:28:59",20.7,24.5,0,473.5,0.00369457799808589,0 +"2431","2015-02-04 04:30:00",20.7,24.5,0,474.75,0.00369457799808589,0 +"2432","2015-02-04 04:31:00",20.7,24.5,0,472,0.00369457799808589,0 +"2433","2015-02-04 04:32:00",20.7,24.5,0,468.25,0.00369457799808589,0 +"2434","2015-02-04 04:33:00",20.7,24.5,0,471.5,0.00369457799808589,0 +"2435","2015-02-04 04:34:00",20.7,24.5,0,469,0.00369457799808589,0 +"2436","2015-02-04 04:34:59",20.7,24.5,0,468,0.00369457799808589,0 +"2437","2015-02-04 04:36:00",20.7,24.5,0,471.5,0.00369457799808589,0 +"2438","2015-02-04 04:37:00",20.7,24.5,0,469.6,0.00369457799808589,0 +"2439","2015-02-04 04:38:00",20.7,24.5,0,466.6,0.00369457799808589,0 +"2440","2015-02-04 04:38:59",20.7,24.5,0,462.666666666667,0.00369457799808589,0 +"2441","2015-02-04 04:40:00",20.7,24.5,0,461.333333333333,0.00369457799808589,0 +"2442","2015-02-04 04:40:59",20.7,24.5,0,463.75,0.00369457799808589,0 +"2443","2015-02-04 04:41:59",20.7,24.5,0,466.25,0.00369457799808589,0 +"2444","2015-02-04 04:43:00",20.7,24.5,0,468.25,0.00369457799808589,0 +"2445","2015-02-04 04:44:00",20.7,24.5,0,470.6,0.00369457799808589,0 +"2446","2015-02-04 04:45:00",20.7,24.5,0,467.666666666667,0.00369457799808589,0 +"2447","2015-02-04 04:46:00",20.7,24.5,0,469,0.00369457799808589,0 +"2448","2015-02-04 04:46:59",20.7,24.5,0,464.25,0.00369457799808589,0 +"2449","2015-02-04 04:47:59",20.7,24.5,0,468,0.00369457799808589,0 +"2450","2015-02-04 04:49:00",20.7,24.5,0,468.75,0.00369457799808589,0 +"2451","2015-02-04 04:50:00",20.7,24.5,0,472.333333333333,0.00369457799808589,0 +"2452","2015-02-04 04:51:00",20.7,24.5,0,468.666666666667,0.00369457799808589,0 +"2453","2015-02-04 04:52:00",20.7,24.5,0,467.666666666667,0.00369457799808589,0 +"2454","2015-02-04 04:53:00",20.7,24.5,0,462.333333333333,0.00369457799808589,0 +"2455","2015-02-04 04:53:59",20.7,24.5,0,463.5,0.00369457799808589,0 +"2456","2015-02-04 04:54:59",20.7,24.5,0,467.4,0.00369457799808589,0 +"2457","2015-02-04 04:56:00",20.7,24.5,0,465.666666666667,0.00369457799808589,0 +"2458","2015-02-04 04:57:00",20.7,24.5,0,465.75,0.00369457799808589,0 +"2459","2015-02-04 04:58:00",20.7,24.5,0,469.75,0.00369457799808589,0 +"2460","2015-02-04 04:59:00",20.7,24.5,0,463.333333333333,0.00369457799808589,0 +"2461","2015-02-04 04:59:59",20.62,24.412,0,462.6,0.00366301739748915,0 +"2462","2015-02-04 05:00:59",20.7,24.5,0,468.25,0.00369457799808589,0 +"2463","2015-02-04 05:02:00",20.7,24.5,0,469.25,0.00369457799808589,0 +"2464","2015-02-04 05:03:00",20.675,24.4725,0,469,0.00368469240145023,0 +"2465","2015-02-04 05:04:00",20.6666666666667,24.4633333333333,0,471.333333333333,0.00368140183570895,0 +"2466","2015-02-04 05:05:00",20.625,24.4175,0,467.75,0.00366498369445519,0 +"2467","2015-02-04 05:06:00",20.7,24.5,0,459,0.00369457799808589,0 +"2468","2015-02-04 05:06:59",20.68,24.478,0,464.6,0.00368666785232636,0 +"2469","2015-02-04 05:08:00",20.6666666666667,24.4633333333333,0,467.666666666667,0.00368140183570895,0 +"2470","2015-02-04 05:09:00",20.7,24.5,0,473.25,0.00369457799808589,0 +"2471","2015-02-04 05:10:00",20.7,24.5,0,471,0.00369457799808589,0 +"2472","2015-02-04 05:10:59",20.675,24.4725,0,465.75,0.00368469240145023,0 +"2473","2015-02-04 05:12:00",20.7,24.5,0,461.5,0.00369457799808589,0 +"2474","2015-02-04 05:12:59",20.675,24.4725,0,464.5,0.00368469240145023,0 +"2475","2015-02-04 05:13:59",20.7,24.5,0,464.8,0.00369457799808589,0 +"2476","2015-02-04 05:15:00",20.6333333333333,24.4266666666667,0,468.333333333333,0.00366826270223185,0 +"2477","2015-02-04 05:16:00",20.6666666666667,24.4633333333333,0,464.333333333333,0.00368140183570895,0 +"2478","2015-02-04 05:17:00",20.6,24.39,0,463.2,0.00365516051087822,0 +"2479","2015-02-04 05:18:00",20.6666666666667,24.4633333333333,0,465.333333333333,0.00368140183570895,0 +"2480","2015-02-04 05:19:00",20.675,24.4725,0,464.25,0.00368469240145023,0 +"2481","2015-02-04 05:19:59",20.64,24.434,0,460,0.00367088757078308,0 +"2482","2015-02-04 05:21:00",20.7,24.5,0,461,0.00369457799808589,0 +"2483","2015-02-04 05:22:00",20.6666666666667,24.4633333333333,0,467,0.00368140183570895,0 +"2484","2015-02-04 05:23:00",20.64,24.434,0,462.2,0.00367088757078308,0 +"2485","2015-02-04 05:23:59",20.6,24.39,0,459.75,0.00365516051087822,0 +"2486","2015-02-04 05:25:00",20.65,24.445,0,455.25,0.00367482764578557,0 +"2487","2015-02-04 05:25:59",20.625,24.4175,0,455.25,0.00366498369445519,0 +"2488","2015-02-04 05:26:59",20.6,24.39,0,461.333333333333,0.00365516051087822,0 +"2489","2015-02-04 05:28:00",20.6,24.39,0,465.25,0.00365516051087822,0 +"2490","2015-02-04 05:29:00",20.6,24.39,0,464.75,0.00365516051087822,0 +"2491","2015-02-04 05:30:00",20.6,24.39,0,464.8,0.00365516051087822,0 +"2492","2015-02-04 05:31:00",20.6,24.39,0,463.5,0.00365516051087822,0 +"2493","2015-02-04 05:31:59",20.625,24.4175,0,463.5,0.00366498369445519,0 +"2494","2015-02-04 05:32:59",20.6,24.39,0,465.666666666667,0.00365516051087822,0 +"2495","2015-02-04 05:34:00",20.625,24.4175,0,464.5,0.00366498369445519,0 +"2496","2015-02-04 05:35:00",20.62,24.412,0,467.6,0.00366301739748915,0 +"2497","2015-02-04 05:36:00",20.625,24.4175,0,459.5,0.00366498369445519,0 +"2498","2015-02-04 05:37:00",20.625,24.4175,0,457.5,0.00366498369445519,0 +"2499","2015-02-04 05:38:00",20.6,24.39,0,463.333333333333,0.00365516051087822,0 +"2500","2015-02-04 05:38:59",20.6,24.39,0,465,0.00365516051087822,0 +"2501","2015-02-04 05:39:59",20.6,24.39,0,468.25,0.00365516051087822,0 +"2502","2015-02-04 05:41:00",20.6,24.39,0,465,0.00365516051087822,0 +"2503","2015-02-04 05:42:00",20.6,24.39,0,464.5,0.00365516051087822,0 +"2504","2015-02-04 05:43:00",20.6,24.34,0,465.5,0.00364762341444938,0 +"2505","2015-02-04 05:44:00",20.6,24.39,0,465.75,0.00365516051087822,0 +"2506","2015-02-04 05:44:59",20.6,24.39,0,469.75,0.00365516051087822,0 +"2507","2015-02-04 05:45:59",20.6,24.39,0,468.2,0.00365516051087822,0 +"2508","2015-02-04 05:47:00",20.6,24.365,0,463.5,0.00365139193996433,0 +"2509","2015-02-04 05:48:00",20.6,24.34,0,461.5,0.00364762341444938,0 +"2510","2015-02-04 05:49:00",20.6,24.39,0,464,0.00365516051087822,0 +"2511","2015-02-04 05:50:00",20.6,24.365,0,464,0.00365139193996433,0 +"2512","2015-02-04 05:51:00",20.6166666666667,24.3233333333333,0,466.5,0.00364888059723987,0 +"2513","2015-02-04 05:51:59",20.6333333333333,24.3233333333333,0,461,0.00365265354089946,0 +"2514","2015-02-04 05:53:00",20.625,24.315,0,459.25,0.00364950852408944,0 +"2515","2015-02-04 05:54:00",20.66,24.312,0,459.6,0.0036569826295124,0 +"2516","2015-02-04 05:55:00",20.6,24.2,0,460.333333333333,0.00362652051049971,0 +"2517","2015-02-04 05:55:59",20.6,24.2,0,458.5,0.00362652051049971,0 +"2518","2015-02-04 05:57:00",20.6,24.2,0,460,0.00362652051049971,0 +"2519","2015-02-04 05:57:59",20.625,24.2925,0,464.5,0.0036461116379366,0 +"2520","2015-02-04 05:58:59",20.62,24.236,0,467.2,0.00363645422458372,0 +"2521","2015-02-04 06:00:00",20.6,24.2,0,456,0.00362652051049971,0 +"2522","2015-02-04 06:01:00",20.6,24.2,0,459.5,0.00362652051049971,0 +"2523","2015-02-04 06:02:00",20.6,24.2,0,460.333333333333,0.00362652051049971,0 +"2524","2015-02-04 06:03:00",20.6,24.2,0,462.2,0.00362652051049971,0 +"2525","2015-02-04 06:04:00",20.6,24.2,0,460.5,0.00362652051049971,0 +"2526","2015-02-04 06:04:59",20.6,24.2,0,464.25,0.00362652051049971,0 +"2527","2015-02-04 06:06:00",20.6333333333333,24.23,0,464.333333333333,0.00363855561297649,0 +"2528","2015-02-04 06:07:00",20.6,24.2,0,465.75,0.00362652051049971,0 +"2529","2015-02-04 06:08:00",20.6,24.2,0,463.5,0.00362652051049971,0 +"2530","2015-02-04 06:08:59",20.6,24.2,0,466.2,0.00362652051049971,0 +"2531","2015-02-04 06:10:00",20.6,24.2,0,466.25,0.00362652051049971,0 +"2532","2015-02-04 06:10:59",20.6,24.2,0,466,0.00362652051049971,0 +"2533","2015-02-04 06:11:59",20.6,24.2,0,463.25,0.00362652051049971,0 +"2534","2015-02-04 06:13:00",20.575,24.2,0,466.75,0.00362090165616911,0 +"2535","2015-02-04 06:14:00",20.6,24.2,0,467.666666666667,0.00362652051049971,0 +"2536","2015-02-04 06:15:00",20.6,24.2,0,463.5,0.00362652051049971,0 +"2537","2015-02-04 06:16:00",20.6,24.2,0,459.25,0.00362652051049971,0 +"2538","2015-02-04 06:16:59",20.6,24.2,0,463.25,0.00362652051049971,0 +"2539","2015-02-04 06:17:59",20.575,24.2,0,463,0.00362090165616911,0 +"2540","2015-02-04 06:19:00",20.5333333333333,24.2,0,459.333333333333,0.00361155395043591,0 +"2541","2015-02-04 06:20:00",20.55,24.2,0,463,0.00361529047701477,0 +"2542","2015-02-04 06:21:00",20.575,24.2,0,460.75,0.00362090165616911,0 +"2543","2015-02-04 06:22:00",20.56,24.2,0,462.4,0.00361753402823388,0 +"2544","2015-02-04 06:23:00",20.52,24.2,0,464,0.00360856718053967,0 +"2545","2015-02-04 06:23:59",20.5333333333333,24.2,0,462.666666666667,0.00361155395043591,0 +"2546","2015-02-04 06:24:59",20.55,24.2,0,467,0.00361529047701477,0 +"2547","2015-02-04 06:26:00",20.6,24.2,0,468,0.00362652051049971,0 +"2548","2015-02-04 06:27:00",20.6,24.1,0,463.25,0.00361144787924265,0 +"2549","2015-02-04 06:28:00",20.6,24.175,0,462.5,0.0036227522845972,0 +"2550","2015-02-04 06:29:00",20.6,24.1,0,467.75,0.00361144787924265,0 +"2551","2015-02-04 06:29:59",20.6666666666667,24.1666666666667,0,467.666666666667,0.00363649649104029,0 +"2552","2015-02-04 06:30:59",20.6,24.1,0,466.25,0.00361144787924265,0 +"2553","2015-02-04 06:32:00",20.6,24.1,0,466.5,0.00361144787924265,0 +"2554","2015-02-04 06:33:00",20.6,24.1,0,467.5,0.00361144787924265,0 +"2555","2015-02-04 06:34:00",20.6,24.1,0,464.5,0.00361144787924265,0 +"2556","2015-02-04 06:35:00",20.6,24.1,0,460.5,0.00361144787924265,0 +"2557","2015-02-04 06:36:00",20.6,24.0333333333333,0,457,0.00360139986187671,0 +"2558","2015-02-04 06:36:59",20.6,24.08,0,459.4,0.00360843344014219,0 +"2559","2015-02-04 06:38:00",20.6333333333333,24.0666666666667,0,465,0.00361388576784168,0 +"2560","2015-02-04 06:39:00",20.6,24.05,0,465.75,0.00360391183595888,0 +"2561","2015-02-04 06:40:00",20.625,24.05,0,468.75,0.00360950309482678,0 +"2562","2015-02-04 06:40:59",20.6,24,0,463.5,0.00359637597422955,0 +"2563","2015-02-04 06:42:00",20.6,24.05,0,463.25,0.00360391183595888,0 +"2564","2015-02-04 06:42:59",20.6,24,0,466.333333333333,0.00359637597422955,0 +"2565","2015-02-04 06:43:59",20.6,24.02,0,467.8,0.00359939029713517,0 +"2566","2015-02-04 06:45:00",20.575,24.075,0,463.25,0.00360209033999183,0 +"2567","2015-02-04 06:46:00",20.525,24.1,0,468.75,0.00359468469872632,0 +"2568","2015-02-04 06:47:00",20.5666666666667,24.1,0,465,0.00360398908937207,0 +"2569","2015-02-04 06:48:00",20.525,24.1,0,464.75,0.00359468469872632,0 +"2570","2015-02-04 06:49:00",20.54,24.1,0,466.4,0.00359803183728493,0 +"2571","2015-02-04 06:49:59",20.5,24.1,0,467,0.00358911223325629,0 +"2572","2015-02-04 06:51:00",20.5,24.15,0,466.75,0.00359660158101622,0 +"2573","2015-02-04 06:52:00",20.525,24.1,0,468.75,0.00359468469872632,0 +"2574","2015-02-04 06:53:00",20.5,24.2,0,468.666666666667,0.00360409110809833,0 +"2575","2015-02-04 06:53:59",20.5,24.2,0,466.75,0.00360409110809833,0 +"2576","2015-02-04 06:55:00",20.5,24.2,0,462.5,0.00360409110809833,0 +"2577","2015-02-04 06:55:59",20.525,24.1,0,465.5,0.00359468469872632,0 +"2578","2015-02-04 06:56:59",20.54,24.1,0,463.8,0.00359803183728493,0 +"2579","2015-02-04 06:58:00",20.5,24.1,0,467.333333333333,0.00358911223325629,0 +"2580","2015-02-04 06:59:00",20.5666666666667,24.1,0,466.75,0.00360398908937207,0 +"2581","2015-02-04 07:00:00",20.5,24.1,0,466.8,0.00358911223325629,0 +"2582","2015-02-04 07:01:00",20.5,24.1,0,464,0.00358911223325629,0 +"2583","2015-02-04 07:01:59",20.52,24.1,0,461.4,0.00359356959594452,0 +"2584","2015-02-04 07:02:59",20.5,24.1,0,464.666666666667,0.00358911223325629,0 +"2585","2015-02-04 07:04:00",20.5,24.1,0,465.5,0.00358911223325629,0 +"2586","2015-02-04 07:05:00",20.5,24.1,0,467.666666666667,0.00358911223325629,0 +"2587","2015-02-04 07:06:00",20.5,24.1,0,473.5,0.00358911223325629,0 +"2588","2015-02-04 07:07:00",20.52,24.1,0,469.8,0.00359356959594452,0 +"2589","2015-02-04 07:08:00",20.5,24.1,0,469.666666666667,0.00358911223325629,0 +"2590","2015-02-04 07:08:59",20.5,24.1,0,470.6,0.00358911223325629,0 +"2591","2015-02-04 07:09:59",20.5,24.1,0,468,0.00358911223325629,0 +"2592","2015-02-04 07:11:00",20.5,24.1,0,468.5,0.00358911223325629,0 +"2593","2015-02-04 07:12:00",20.5,24.1,0,470,0.00358911223325629,0 +"2594","2015-02-04 07:13:00",20.4725,24.05,0,472.75,0.00357551499371526,0 +"2595","2015-02-04 07:14:00",20.5,24.075,0,466.75,0.00358536762662013,0 +"2596","2015-02-04 07:14:59",20.4725,24.0225,0,466,0.00357140309205584,0 +"2597","2015-02-04 07:15:59",20.4266666666667,23.96,0,467.333333333333,0.00355193680003749,0 +"2598","2015-02-04 07:17:00",20.4725,23.9975,0,468.5,0.00356766504654512,0 +"2599","2015-02-04 07:18:00",20.456,23.956,0,470.8,0.00355781402645853,0 +"2600","2015-02-04 07:19:00",20.5,24,0,472,0.00357413407567721,0 +"2601","2015-02-04 07:20:00",20.478,23.978,0,470,0.00356596658429162,0 +"2602","2015-02-04 07:21:00",20.445,23.945,0,466.666666666667,0.00355374334047454,0 +"2603","2015-02-04 07:21:59",20.5,24,0,461.4,0.00357413407567721,0 +"2604","2015-02-04 07:23:00",20.39,23.89,0,462.666666666667,0.00353344572567677,0 +"2605","2015-02-04 07:24:00",20.4725,23.89,0,464.75,0.00355159195988146,0 +"2606","2015-02-04 07:25:00",20.5,23.89,0,473.5,0.00355765893071744,0 +"2607","2015-02-04 07:25:59",20.456,23.85,0,472.5,0.00354198184055287,0 +"2608","2015-02-04 07:27:00",20.4266666666667,23.8233333333333,0,473,0.00353156169479861,0 +"2609","2015-02-04 07:27:59",20.4633333333333,23.8566666666667,0,473,0.00354459077966779,0 +"2610","2015-02-04 07:28:59",20.445,23.8233333333333,0,469.833333333333,0.00353558381640323,0 +"2611","2015-02-04 07:30:00",20.445,23.8175,0,469.25,0.00353471318077689,0 +"2612","2015-02-04 07:31:00",20.4175,23.7475,0,471.75,0.00351825348975941,0 +"2613","2015-02-04 07:32:00",20.4266666666667,23.76,0,472.666666666667,0.00352212002291503,0 +"2614","2015-02-04 07:33:00",20.4175,23.7225,0,471.5,0.00351452874724351,0 +"2615","2015-02-04 07:34:00",20.4725,23.7675,0,471,0.00353327712377474,0 +"2616","2015-02-04 07:34:59",20.39,23.7,0,472,0.00350518544923937,0 +"2617","2015-02-04 07:36:00",20.434,23.736,0,468.8,0.00352014460232289,0 +"2618","2015-02-04 07:37:00",20.4266666666667,23.73,56.3333333333333,471.666666666667,0.0035176477515035,0 +"2619","2015-02-04 07:38:00",20.39,23.7,311.75,474.75,0.00350518544923937,1 +"2620","2015-02-04 07:38:59",20.4175,23.7225,426,473.5,0.00351452874724351,1 +"2621","2015-02-04 07:40:00",20.4725,23.7675,433,473.75,0.00353327712377474,1 +"2622","2015-02-04 07:40:59",20.4816666666667,23.89,423.666666666667,484.5,0.00355361326947345,1 +"2623","2015-02-04 07:41:59",20.5,23.89,419,492.4,0.00355765893071744,1 +"2624","2015-02-04 07:43:00",20.5,23.89,419,491,0.00355765893071744,1 +"2625","2015-02-04 07:44:00",20.5,23.89,419,487.2,0.00355765893071744,1 +"2626","2015-02-04 07:45:00",20.55,23.945,415.5,493.25,0.00357697639860997,1 +"2627","2015-02-04 07:46:00",20.52,24,409.8,499.6,0.00357857273040011,1 +"2628","2015-02-04 07:46:59",20.525,24,414.6,506.2,0.00357968315295065,1 +"2629","2015-02-04 07:47:59",20.6,24.0833333333333,413,507.333333333333,0.00360893584464161,0 +"2630","2015-02-04 07:49:00",20.6,24.1,414.6,514.6,0.00361144787924265,0 +"2631","2015-02-04 07:50:00",20.6,24.175,407.5,522.25,0.0036227522845972,0 +"2632","2015-02-04 07:51:00",20.6,24.2,406.6,525.6,0.00362652051049971,0 +"2633","2015-02-04 07:52:00",20.6,24.2,399.5,528,0.00362652051049971,0 +"2634","2015-02-04 07:53:00",20.6333333333333,24.23,398.333333333333,537.333333333333,0.00363855561297649,1 +"2635","2015-02-04 07:53:59",20.66,24.2,406.2,538.8,0.00364003712975864,1 +"2636","2015-02-04 07:54:59",20.625,24.175,414,538.5,0.00362837294284862,1 +"2637","2015-02-04 07:56:00",20.66,24.216,412.2,535.8,0.00364245785923865,1 +"2638","2015-02-04 07:57:00",20.675,24.34,411,538.75,0.00366462505281217,1 +"2639","2015-02-04 07:58:00",20.7,24.5,408,546.25,0.00369457799808589,1 +"2640","2015-02-04 07:59:00",20.7,24.65,405,554.666666666667,0.0037173330491887,1 +"2641","2015-02-04 07:59:59",20.7,24.7,405,565.333333333333,0.00372491843402658,1 +"2642","2015-02-04 08:00:59",20.7,24.7675,405,573,0.00373515899529087,1 +"2643","2015-02-04 08:02:00",20.7128571428571,24.79,405,581.142857142857,0.00374155289136171,1 +"2644","2015-02-04 08:03:00",20.7,24.79,405,587.25,0.00373857259019989,1 +"2645","2015-02-04 08:04:00",20.754,24.87,413.4,588.2,0.00376328239169231,1 +"2646","2015-02-04 08:05:00",20.775,24.89,416.666666666667,589.5,0.00377123030935907,1 +"2647","2015-02-04 08:06:00",20.772,24.956,419,592,0.00378058846372981,1 +"2648","2015-02-04 08:06:59",20.79,24.978,419,599.8,0.00378816313297203,1 +"2649","2015-02-04 08:08:00",20.79,25,419,605.4,0.00379151999106046,1 +"2650","2015-02-04 08:09:00",20.79,24.9975,419,611.25,0.00379113852810034,1 +"2651","2015-02-04 08:10:00",20.81,25.02,419,616.4,0.00379927525150784,1 +"2652","2015-02-04 08:10:59",20.865,25.075,419,621,0.00382066819344459,1 +"2653","2015-02-04 08:12:00",20.8233333333333,25.0333333333333,419,622.666666666667,0.00380445252679579,1 +"2654","2015-02-04 08:12:59",20.8566666666667,25.0666666666667,419,624,0.00381742060909679,1 +"2655","2015-02-04 08:13:59",20.84,25.05,419,623.75,0.00381093211949594,1 +"2656","2015-02-04 08:15:00",20.87,25.16,433,632.4,0.00383488634878397,1 +"2657","2015-02-04 08:16:00",20.89,25.2,433,639,0.00384577933024355,1 +"2658","2015-02-04 08:17:00",20.8733333333333,25.275,433,646,0.00385331832782966,1 +"2659","2015-02-04 08:18:00",20.84,25.1975,433,649.5,0.00383351003961505,1 +"2660","2015-02-04 08:19:00",20.89,25.272,433,649.8,0.00385683540411258,1 +"2661","2015-02-04 08:19:59",20.865,25.365,433,656.75,0.00386512996367583,1 +"2662","2015-02-04 08:21:00",20.84,25.34,433,660.75,0.00385532415378895,1 +"2663","2015-02-04 08:22:00",20.8733333333333,25.3733333333333,437.666666666667,659.333333333333,0.00386840304345056,1 +"2664","2015-02-04 08:23:00",20.87,25.37,440.6,671.6,0.00386709354276614,1 +"2665","2015-02-04 08:23:59",20.84,25.34,442.5,673.5,0.00385532415378895,1 +"2666","2015-02-04 08:25:00",20.865,25.365,438,678.25,0.00386512996367583,1 +"2667","2015-02-04 08:25:59",20.89,25.39,441,681,0.0038749559254609,1 +"2668","2015-02-04 08:26:59",20.89,25.35,429,683,0.00386881325829316,1 +"2669","2015-02-04 08:28:00",20.89,25.33,429,689.4,0.00386574196992461,1 +"2670","2015-02-04 08:29:00",20.89,25.34,429,694.25,0.00386727761034099,1 +"2671","2015-02-04 08:30:00",20.912,25.39,435,690.4,0.00388023631835984,1 +"2672","2015-02-04 08:31:00",20.945,25.39,444,697.333333333333,0.00388816880386623,1 +"2673","2015-02-04 08:31:59",20.9725,25.39,444,710.25,0.00389479012739197,1 +"2674","2015-02-04 08:32:59",20.956,25.39,444,717.8,0.00389081614129734,0 +"2675","2015-02-04 08:34:00",21,25.39,444,720.75,0.00390142139093685,0 +"2676","2015-02-04 08:35:00",21,25.412,444,721.4,0.00390482312809722,0 +"2677","2015-02-04 08:36:00",21,25.39,444,718,0.00390142139093685,0 +"2678","2015-02-04 08:37:00",21,25.3566666666667,444,715.5,0.00389626731417885,0 +"2679","2015-02-04 08:38:00",21,25.29,447.2,713,0.00388595941531064,0 +"2680","2015-02-04 08:38:59",21,25.29,456.8,714.8,0.00388595941531064,0 +"2681","2015-02-04 08:39:59",21,25.245,460,714.5,0.0038790017755085,1 +"2682","2015-02-04 08:41:00",21,25.2,454.75,711,0.00387204429039337,1 +"2683","2015-02-04 08:42:00",21,25.2,453,705,0.00387204429039337,1 +"2684","2015-02-04 08:43:00",21,25.2,451.6,711,0.00387204429039337,1 +"2685","2015-02-04 08:44:00",21.025,25.2225,454.75,713.5,0.00388151974782212,1 +"2686","2015-02-04 08:44:59",21.0833333333333,25.2,453,719.5,0.00389204714712558,1 +"2687","2015-02-04 08:45:59",21.0666666666667,25.2,458,727.666666666667,0.00388803930328456,1 +"2688","2015-02-04 08:47:00",21.1166666666667,25.2,458,728.666666666667,0.00390007376350971,1 +"2689","2015-02-04 08:48:00",21.15,25.2225,459.25,731.25,0.00391162630292601,1 +"2690","2015-02-04 08:49:00",21.2,25.2283333333333,454,738.5,0.00392463963646193,1 +"2691","2015-02-04 08:50:00",21.2,25.18,454,740.2,0.00391707332201621,1 +"2692","2015-02-04 08:51:00",21.2,25.1,454,735.75,0.00390455016902337,1 +"2693","2015-02-04 08:51:59",21.2,25.14,454,735,0.00391081168287933,1 +"2694","2015-02-04 08:53:00",21.215,25.215,456.5,746.166666666667,0.00392618773758027,1 +"2695","2015-02-04 08:54:00",21.2,25.2,465.25,762.75,0.00392020418856616,1 +"2696","2015-02-04 08:55:00",21.2,25.2,469,766.2,0.00392020418856616,1 +"2697","2015-02-04 08:55:59",21.2,25.218,469,763.4,0.00392302199524111,1 +"2698","2015-02-04 08:57:00",21.215,25.2916666666667,462.333333333333,773.833333333333,0.00393820096624668,0 +"2699","2015-02-04 08:57:59",21.2,25.29,464,777.75,0.00393429347565304,0 +"2700","2015-02-04 08:58:59",21.2,25.3566666666667,462.333333333333,778,0.00394473039355291,1 +"2701","2015-02-04 09:00:00",21.2,25.37,470.2,778.4,0.00394681781889942,1 +"2702","2015-02-04 09:01:00",21.2225,25.34,475.75,774.75,0.00394760269427452,1 +"2703","2015-02-04 09:02:00",21.236,25.33,471,774,0.00394932580355015,1 +"2704","2015-02-04 09:03:00",21.29,25.4725,480.25,778,0.00398494828914425,1 +"2705","2015-02-04 09:04:00",21.29,25.4266666666667,487,779,0.00397773221374547,1 +"2706","2015-02-04 09:04:59",21.272,25.412,503.6,780.6,0.00397100850540684,1 +"2707","2015-02-04 09:06:00",21.29,25.575,509.5,786.25,0.00400108665984332,1 +"2708","2015-02-04 09:07:00",21.29,25.6725,527.25,800.75,0.00401643856518858,1 +"2709","2015-02-04 09:08:00",21.34,25.79,524.5,814,0.0040474111875209,1 +"2710","2015-02-04 09:08:59",21.412,25.872,529.8,832,0.0040784394636053,1 +"2711","2015-02-04 09:10:00",21.5,26,534,849.25,0.00412104996926551,1 +"2712","2015-02-04 09:10:59",21.5,26.08,544,860.6,0.00413381439536776,1 +"2713","2015-02-04 09:11:59",21.6,26.15,538,871,0.00417060301513912,1 +"2714","2015-02-04 09:13:00",21.66,26.216,553,879.5,0.00419667797928421,1 +"2715","2015-02-04 09:14:00",21.7,26.2675,542.5,894,0.0042153452030233,1 +"2716","2015-02-04 09:15:00",21.7225,26.2225,547,905.5,0.0042139062349477,1 +"2717","2015-02-04 09:16:00",21.79,26.39,559.2,911.2,0.00425865716745792,1 +"2718","2015-02-04 09:16:59",21.81,26.274,567.8,919.2,0.00424502903402628,1 +"2719","2015-02-04 09:17:59",21.865,26.315,554,923.5,0.0042661023632274,1 +"2720","2015-02-04 09:19:00",21.89,26.315,563,931.75,0.00427266374639605,1 +"2721","2015-02-04 09:20:00",21.89,26.315,564.5,934.75,0.00427266374639605,1 +"2722","2015-02-04 09:21:00",21.945,26.2225,577.5,934.75,0.00427195690933226,1 +"2723","2015-02-04 09:22:00",22,26.12,578.8,939,0.00426954476696138,1 +"2724","2015-02-04 09:23:00",22,26.0666666666667,581.666666666667,936.666666666667,0.00426076724453117,1 +"2725","2015-02-04 09:23:59",22.0857142857143,26.1285714285714,580,936.428571428571,0.00429349107080348,1 +"2726","2015-02-04 09:24:59",22.1,26.1,596,936.5,0.00429252572916348,1 +"2727","2015-02-04 09:26:00",22.1,26.1,594.8,937.6,0.00429252572916348,1 +"2728","2015-02-04 09:27:00",22.14,25.998,603.4,937.8,0.00428614213832739,1 +"2729","2015-02-04 09:28:00",22.2,26,608.25,946,0.00430227872763771,0 +"2730","2015-02-04 09:29:00",22.29,25.9633333333333,606.666666666667,950.333333333333,0.00431993869567135,0 +"2731","2015-02-04 09:29:59",22.29,25.89,612,937.333333333333,0.00430765254338066,1 +"2732","2015-02-04 09:30:59",22.29,25.8566666666667,611,943.666666666667,0.00430206808804728,1 +"2733","2015-02-04 09:32:00",22.3233333333333,25.8066666666667,617,946.166666666667,0.00430247034092601,1 +"2734","2015-02-04 09:33:00",22.39,25.7,624.75,944.5,0.00430209566080886,1 +"2735","2015-02-04 09:34:00",22.39,25.68,630.4,944.4,0.00429872458842353,1 +"2736","2015-02-04 09:35:00",22.445,25.65,632.5,948,0.00430815025504638,1 +"2737","2015-02-04 09:36:00",22.5,25.6666666666667,652,940.333333333333,0.0043255037974044,1 +"2738","2015-02-04 09:36:59",22.5,25.6,643.5,944.333333333333,0.00431419079614889,1 +"2739","2015-02-04 09:38:00",22.5666666666667,25.6,648.666666666667,942.166666666667,0.00433182012264332,1 +"2740","2015-02-04 09:39:00",22.6,25.6,767,948.666666666667,0.00434065857758123,1 +"2741","2015-02-04 09:40:00",22.6,25.4725,1419.5,945,0.00431888995388107,1 +"2742","2015-02-04 09:40:59",22.7,25.5,1697.25,951.75,0.00435009044849769,1 +"2743","2015-02-04 09:42:00",22.7,25.456,1209.8,958.6,0.00434253200619881,1 +"2744","2015-02-04 09:42:59",22.7225,25.4175,685.75,956.25,0.00434188231426183,1 +"2745","2015-02-04 09:43:59",22.7675,25.315,684.75,952.25,0.00433615170348689,1 +"2746","2015-02-04 09:45:00",22.79,25.456,679.4,954.6,0.00436646730195512,1 +"2747","2015-02-04 09:46:00",22.8233333333333,25.3933333333333,683,961.666666666667,0.00436451500523488,1 +"2748","2015-02-04 09:47:00",22.89,25.39,692,961.75,0.00438172787670815,1 +"2749","2015-02-04 09:48:00",22.89,25.39,693.8,953.8,0.00438172787670815,1 +"2750","2015-02-04 09:49:00",22.9083333333333,25.39,689,956.333333333333,0.00438663126822082,1 +"2751","2015-02-04 09:49:59",22.9725,25.39,693.75,970,0.00440383124996745,1 +"2752","2015-02-04 09:51:00",23,25.39,686.5,971.25,0.00441122084993632,1 +"2753","2015-02-04 09:52:00",23.025,25.4175,698.25,986.25,0.00442276727057166,1 +"2754","2015-02-04 09:53:00",23.1,25.5,694.833333333333,985,0.00445755019423801,1 +"2755","2015-02-04 09:53:59",23.1,25.5,690,997,0.00445755019423801,1 +"2756","2015-02-04 09:55:00",23.2,25.5,696.8,1003.8,0.00448477799181549,1 +"2757","2015-02-04 09:55:59",23.2,25.5,710,1004.83333333333,0.00448477799181549,1 +"2758","2015-02-04 09:56:59",23.2,25.5,722,1011.4,0.00448477799181549,1 +"2759","2015-02-04 09:58:00",23.29,25.6,732,1022.5,0.00452722091017869,1 +"2760","2015-02-04 09:59:00",23.29,25.6,735,1029.83333333333,0.00452722091017869,1 +"2761","2015-02-04 10:00:00",23.31,25.6,719.2,1031,0.00453273230505731,1 +"2762","2015-02-04 10:01:00",23.39,25.6,723.333333333333,1040,0.00455483707490689,1 +"2763","2015-02-04 10:01:59",23.365,25.6,729,1040.5,0.00454791914921006,1 +"2764","2015-02-04 10:02:59",23.39,25.6,738,1042,0.00455483707490689,1 +"2765","2015-02-04 10:04:00",23.456,25.66,738,1052.4,0.00458394228676715,1 +"2766","2015-02-04 10:05:00",23.5,25.718,734.4,1062.8,0.00460667857151887,1 +"2767","2015-02-04 10:06:00",23.58,25.736,738,1067.75,0.00463237796667757,1 +"2768","2015-02-04 10:07:00",23.6,25.89,747,1072.25,0.0046659670837691,1 +"2769","2015-02-04 10:08:00",23.64,25.954,745.2,1095.2,0.00468895881962261,1 +"2770","2015-02-04 10:08:59",23.6666666666667,26.0666666666667,746.333333333333,1109,0.00471709525928931,1 +"2771","2015-02-04 10:09:59",23.7,26.12,737.8,1119,0.00473638946145591,1 +"2772","2015-02-04 10:11:00",23.718,26.1,745,1123.4,0.00473790584115977,1 +"2773","2015-02-04 10:12:00",23.79,26.125,740.5,1122.5,0.0047632311174623,1 +"2774","2015-02-04 10:13:00",23.745,26.2,754,1123,0.00476399300976303,1 +"2775","2015-02-04 10:14:00",23.79,26.31,763,1158.2,0.0047972213207179,1 +"2776","2015-02-04 10:14:59",23.79,26.315,758.25,1160.25,0.00479814002602634,1 +"2777","2015-02-04 10:15:59",23.89,26.39,755.5,1166,0.00484117485260517,1 +"2778","2015-02-04 10:17:00",23.89,26.365,758.25,1164.75,0.00483655300824924,1 +"2779","2015-02-04 10:18:00",23.89,26.29,772.75,1163.25,0.00482268788410749,1 +"2780","2015-02-04 10:19:00",23.9842857142857,26.3757142857143,767,1172.71428571429,0.00486624432774014,1 +"2781","2015-02-04 10:20:00",24,26.365,774.5,1182,0.00486888220360127,1 +"2782","2015-02-04 10:21:00",24.05,26.34,774.5,1182,0.00487897304812946,1 +"2783","2015-02-04 10:21:59",24.08,26.37,769.8,1187.6,0.00489344901185261,1 +"2784","2015-02-04 10:23:00",24.1,26.5666666666667,758.333333333333,1191.33333333333,0.0049362032071249,1 +"2785","2015-02-04 10:24:00",24.1,26.4725,775.75,1213.75,0.00491856827026637,1 +"2786","2015-02-04 10:25:00",24.1,26.154,775,1194,0.00485892895958963,1 +"2787","2015-02-04 10:25:59",24.1,25.958,783.4,1173.4,0.00482223348496531,1 +"2788","2015-02-04 10:27:00",24.1,25.918,789.6,1160.2,0.0048147451404422,1 +"2789","2015-02-04 10:27:59",24.1,25.8925,797.5,1156.25,0.0048099714141955,1 +"2790","2015-02-04 10:28:59",24.1,25.832,799,1139,0.00479864580556749,1 +"2791","2015-02-04 10:30:00",24.175,25.84,782.5,1140.5,0.00482196327497705,1 +"2792","2015-02-04 10:31:00",24.2,25.8916666666667,786.166666666667,1145.33333333333,0.00483898711768363,1 +"2793","2015-02-04 10:32:00",24.2,25.89,794.25,1149.25,0.00483867320518602,1 +"2794","2015-02-04 10:33:00",24.2,25.89,797.5,1152.5,0.00483867320518602,1 +"2795","2015-02-04 10:34:00",24.2,25.89,787,1153.25,0.00483867320518602,1 +"2796","2015-02-04 10:34:59",24.218,25.912,805,1152.4,0.0048480885145136,1 +"2797","2015-02-04 10:36:00",24.26,25.8916666666667,798,1146.16666666667,0.00485656490522074,1 +"2798","2015-02-04 10:37:00",24.29,25.978,793,1145.4,0.00488172534996697,1 +"2799","2015-02-04 10:38:00",24.29,25.852,801.4,1140.8,0.00485786279907514,1 +"2800","2015-02-04 10:38:59",24.29,25.7,808,1150.25,0.00482907864729539,1 +"2801","2015-02-04 10:40:00",24.33,25.736,809.8,1129.2,0.00484759240740331,1 +"2802","2015-02-04 10:40:59",24.33,25.7,817,1125.8,0.00484075873127256,1 +"2803","2015-02-04 10:41:59",24.3566666666667,25.7,813,1123,0.00484855928127551,1 +"2804","2015-02-04 10:43:00",24.4083333333333,25.6816666666667,798,1124,0.00486020770362199,1 diff --git a/Demos/occupancy_data/datatest2.txt b/Demos/occupancy_data/datatest2.txt new file mode 100644 index 0000000..ba53ab4 --- /dev/null +++ b/Demos/occupancy_data/datatest2.txt @@ -0,0 +1,9753 @@ +"date","Temperature","Humidity","Light","CO2","HumidityRatio","Occupancy" +"1",2015-02-11 14:48:00,21.76,31.1333333333333,437.333333333333,1029.66666666667,0.00502101089021385,1 +"2",2015-02-11 14:49:00,21.79,31,437.333333333333,1000,0.00500858127480172,1 +"3",2015-02-11 14:50:00,21.7675,31.1225,434,1003.75,0.0050215691326541,1 +"4",2015-02-11 14:51:00,21.7675,31.1225,439,1009.5,0.0050215691326541,1 +"5",2015-02-11 14:51:59,21.79,31.1333333333333,437.333333333333,1005.66666666667,0.00503029777867882,1 +"6",2015-02-11 14:53:00,21.76,31.26,437.333333333333,1014.33333333333,0.00504160456530272,1 +"7",2015-02-11 14:54:00,21.79,31.1975,434,1018.5,0.00504074938235223,1 +"8",2015-02-11 14:55:00,21.79,31.3933333333333,437.333333333333,1018.66666666667,0.00507264928829298,1 +"9",2015-02-11 14:55:59,21.79,31.3175,434,1022,0.00506029617368585,1 +"10",2015-02-11 14:57:00,21.79,31.4633333333333,437.333333333333,1027.33333333333,0.00508405259531726,1 +"11",2015-02-11 14:57:59,21.79,31.525,437.75,1047.75,0.00509409870941305,1 +"12",2015-02-11 14:58:59,21.79,31.575,441.75,1049,0.00510224444363126,1 +"13",2015-02-11 15:00:00,21.79,31.395,442,1061.5,0.00507292079078337,1 +"14",2015-02-11 15:01:00,21.79,31.3925,441.75,1049,0.00507251353713595,1 +"15",2015-02-11 15:02:00,21.79,31.5,441.5,1048,0.00509002592166009,1 +"16",2015-02-11 15:03:00,21.815,31.5,438,1049.25,0.00509786935872823,1 +"17",2015-02-11 15:04:00,21.815,31.4725,449.5,1051.25,0.0050933823938006,1 +"18",2015-02-11 15:04:59,21.89,31.6,449.5,1060.5,0.0051378566839722,1 +"19",2015-02-11 15:06:00,21.79,31.55,449.5,1059.5,0.00509817155006976,1 +"20",2015-02-11 15:07:00,21.8233333333333,31.73,447.666666666667,1072,0.00513803548952273,1 +"21",2015-02-11 15:08:00,21.865,31.7225,449.5,1072.33333333333,0.00515000712298489,1 +"22",2015-02-11 15:08:59,21.89,31.745,449.5,1075.33333333333,0.00516162793287788,1 +"23",2015-02-11 15:10:00,21.89,31.7675,449.5,1087,0.00516531673646147,1 +"24",2015-02-11 15:10:59,21.89,31.7675,437.75,1083.25,0.00516531673646147,1 +"25",2015-02-11 15:11:59,21.89,31.79,442.666666666667,1086.33333333333,0.00516900558343851,1 +"26",2015-02-11 15:13:00,21.89,31.79,437.333333333333,1091,0.00516900558343851,1 +"27",2015-02-11 15:14:00,21.89,31.89,439,1100,0.00518540098391904,1 +"28",2015-02-11 15:15:00,21.89,31.89,444,1101,0.00518540098391904,1 +"29",2015-02-11 15:16:00,21.89,31.865,444,1107,0.00518130205343558,1 +"30",2015-02-11 15:16:59,21.89,31.79,444,1110,0.00516900558343851,1 +"31",2015-02-11 15:17:59,21.89,31.865,444,1101.75,0.00518130205343558,1 +"32",2015-02-11 15:19:00,21.89,31.73,444,1100,0.0051591687545959,1 +"33",2015-02-11 15:20:00,21.89,31.7225,444,1092.75,0.00515793917268696,1 +"34",2015-02-11 15:21:00,21.89,31.7,444,1092.5,0.00515425045588796,1 +"35",2015-02-11 15:22:00,21.89,31.695,436.5,1094,0.00515343074693639,1 +"36",2015-02-11 15:23:00,21.89,31.5666666666667,434,1085.66666666667,0.00513239228379069,1 +"37",2015-02-11 15:23:59,21.89,31.55,436.5,1047,0.00512966011940923,0 +"38",2015-02-11 15:24:59,21.89,31.36,434,1031,0.00509851512797734,0 +"39",2015-02-11 15:26:00,21.89,31.125,432.75,977.5,0.00505999797020354,0 +"40",2015-02-11 15:27:00,21.89,31.15,436.5,961.25,0.00506409531527447,1 +"41",2015-02-11 15:28:00,21.89,31.0633333333333,434,948,0.00504989141462838,1 +"42",2015-02-11 15:29:00,21.89,30.77,429,913.25,0.00500182144829266,1 +"43",2015-02-11 15:29:59,21.89,30.7675,432.75,882.5,0.00500141179275406,1 +"44",2015-02-11 15:30:59,21.89,30.945,429,884.5,0.00503049866628219,1 +"45",2015-02-11 15:32:00,21.89,30.7925,429,899,0.00500550837222886,1 +"46",2015-02-11 15:33:00,21.89,30.77,432.75,888.25,0.00500182144829266,1 +"47",2015-02-11 15:34:00,21.89,30.795,436.5,878.5,0.00500591803312054,1 +"48",2015-02-11 15:35:00,21.89,30.8175,429,891.25,0.00500960500523488,1 +"49",2015-02-11 15:36:00,21.89,30.65,436.5,896.5,0.0049821585862417,1 +"50",2015-02-11 15:36:59,21.89,30.7475,429,889.5,0.00499813456771599,1 +"51",2015-02-11 15:38:00,21.89,30.7633333333333,429,887.333333333333,0.00500072903471261,1 +"52",2015-02-11 15:39:00,21.89,30.77,429,893.5,0.00500182144829266,1 +"53",2015-02-11 15:40:00,21.89,30.445,429,832.5,0.00494857071640284,1 +"54",2015-02-11 15:40:59,21.89,30.5666666666667,429,829,0.00496850454649975,1 +"55",2015-02-11 15:42:00,21.89,30.5,429,829.25,0.00495758174288195,1 +"56",2015-02-11 15:42:59,21.89,30.575,429,850.5,0.00496986992371244,1 +"57",2015-02-11 15:43:59,21.89,30.6,429,844,0.00497396609103204,1 +"58",2015-02-11 15:45:00,21.89,30.55,429,840.25,0.00496577380991492,1 +"59",2015-02-11 15:46:00,21.865,30.55,429,823.75,0.00495813961475943,1 +"60",2015-02-11 15:47:00,21.89,30.6,429,824,0.00497396609103204,1 +"61",2015-02-11 15:48:00,21.89,30.34,429,813,0.00493136856692414,1 +"62",2015-02-11 15:49:00,21.89,30.3566666666667,429,802,0.00493409900381388,1 +"63",2015-02-11 15:49:59,21.865,30.3925,429,810.75,0.00493237531114486,1 +"64",2015-02-11 15:51:00,21.89,30.3566666666667,429,805.333333333333,0.00493409900381388,1 +"65",2015-02-11 15:52:00,21.89,30.315,429,796.5,0.00492727295618295,1 +"66",2015-02-11 15:53:00,21.89,30.2,429,795,0.00490843383598124,1 +"67",2015-02-11 15:53:59,21.89,30.34,429,793.5,0.00493136856692414,1 +"68",2015-02-11 15:55:00,21.89,30.295,429,790.5,0.0049239965061181,1 +"69",2015-02-11 15:55:59,21.89,30.29,429,786.5,0.00492317739895294,1 +"70",2015-02-11 15:56:59,21.89,30.39,429,794.333333333333,0.00493955994894424,1 +"71",2015-02-11 15:58:00,21.89,30.365,429,795.5,0.00493546423117755,1 +"72",2015-02-11 15:59:00,21.89,30.4266666666667,414,792.666666666667,0.00494556709847047,1 +"73",2015-02-11 16:00:00,21.89,30.73,424,798,0.00499526702391059,1 +"74",2015-02-11 16:01:00,21.89,30.4175,429,795.5,0.00494406530029668,1 +"75",2015-02-11 16:01:59,21.89,30.39,429,797.75,0.00493955994894424,1 +"76",2015-02-11 16:02:59,21.89,30.39,429,798,0.00493955994894424,1 +"77",2015-02-11 16:04:00,21.89,30.445,429,802,0.00494857071640284,1 +"78",2015-02-11 16:05:00,21.89,30.3566666666667,421.5,797.5,0.00493409900381388,1 +"79",2015-02-11 16:06:00,21.89,30.3233333333333,429,791.5,0.00492863815381761,1 +"80",2015-02-11 16:07:00,21.89,30.32,418.75,788.25,0.00492809207405026,1 +"81",2015-02-11 16:08:00,21.89,30.39,429,792.25,0.00493955994894424,1 +"82",2015-02-11 16:08:59,21.89,30.39,429,795.5,0.00493955994894424,1 +"83",2015-02-11 16:09:59,21.89,30.365,429,793.5,0.00493546423117755,1 +"84",2015-02-11 16:11:00,21.89,30.23,429,789.333333333333,0.00491334827992024,1 +"85",2015-02-11 16:12:00,21.89,30.2,429,786,0.00490843383598124,1 +"86",2015-02-11 16:13:00,21.89,30.0225,429,771.75,0.0048793582858461,1 +"87",2015-02-11 16:14:00,21.89,29.96,429,760,0.0048691210580864,1 +"88",2015-02-11 16:14:59,21.89,29.9175,429,756,0.00486215993419255,1 +"89",2015-02-11 16:15:59,21.89,30.1,429,754,0.00489205291264047,1 +"90",2015-02-11 16:17:00,21.89,30.15,416.5,759,0.00490024326730235,1 +"91",2015-02-11 16:18:00,21.89,30.1333333333333,421.666666666667,756.666666666667,0.00489751312530247,1 +"92",2015-02-11 16:19:00,21.89,30.47,438,764.25,0.00495266660541906,1 +"93",2015-02-11 16:20:00,21.89,30.1666666666667,441,768,0.00490297343308189,1 +"94",2015-02-11 16:21:00,21.89,30.075,438,770.25,0.0048879578155633,1 +"95",2015-02-11 16:21:59,21.89,30.125,438,766.25,0.00489614806321981,1 +"96",2015-02-11 16:23:00,21.89,30.175,438,767.75,0.00490433852488914,1 +"97",2015-02-11 16:24:00,21.89,30.295,438,777,0.0049239965061181,1 +"98",2015-02-11 16:25:00,21.89,30.2,441,775.333333333333,0.00490843383598124,1 +"99",2015-02-11 16:25:59,21.89,30.2,436.333333333333,768,0.00490843383598124,1 +"100",2015-02-11 16:27:00,21.865,30.15,438,766.75,0.00489271060254199,1 +"101",2015-02-11 16:27:59,21.89,30.075,438,772.5,0.0048879578155633,1 +"102",2015-02-11 16:28:59,21.89,30.0725,435.5,774.75,0.00488754830879816,1 +"103",2015-02-11 16:30:00,21.89,30.03,435,766.333333333333,0.00488058677564648,1 +"104",2015-02-11 16:31:00,21.89,29.9175,434.5,752,0.00486215993419255,1 +"105",2015-02-11 16:32:00,21.89,30.1,430.5,754,0.00489205291264047,1 +"106",2015-02-11 16:33:00,21.89,30.1,441,755,0.00489205291264047,1 +"107",2015-02-11 16:34:00,21.89,30.075,431,763.25,0.0048879578155633,1 +"108",2015-02-11 16:34:59,21.89,30.1975,425,769.5,0.00490802430246426,1 +"109",2015-02-11 16:36:00,21.89,30.23,419,769.333333333333,0.00491334827992024,1 +"110",2015-02-11 16:37:00,21.9175,30.5475,395.25,772.25,0.00497377310467557,1 +"111",2015-02-11 16:38:00,21.9633333333333,30.7933333333333,426.666666666667,784.666666666667,0.00502828021278913,1 +"112",2015-02-11 16:38:59,21.9725,30.2,424.75,784.25,0.00493340633293594,1 +"113",2015-02-11 16:40:00,22,30.175,423.5,794.25,0.00493763206073067,1 +"114",2015-02-11 16:40:59,21.945,30.245,423.5,791,0.00493246660701159,1 +"115",2015-02-11 16:41:59,21.9266666666667,30.29,426.666666666667,791.333333333333,0.00493429603105484,1 +"116",2015-02-11 16:43:00,21.9725,30.175,428.25,793.25,0.0049292900224207,1 +"117",2015-02-11 16:44:00,21.89,30.245,433,787.5,0.00491580553078374,1 +"118",2015-02-11 16:45:00,21.9266666666667,30.3566666666667,433,789,0.00494524249611813,1 +"119",2015-02-11 16:46:00,21.945,30.1725,428.25,782.75,0.00492054950402857,1 +"120",2015-02-11 16:46:59,21.9175,30.34,428.25,783.5,0.00493971944451338,1 +"121",2015-02-11 16:47:59,21.9266666666667,30.29,426.666666666667,791,0.00493429603105484,1 +"122",2015-02-11 16:49:00,21.9175,30.2925,428.25,786,0.00493192454865155,1 +"123",2015-02-11 16:50:00,21.9175,30.27,433,786.5,0.00492823229721187,1 +"124",2015-02-11 16:51:00,21.9266666666667,30.1966666666667,433,786.333333333333,0.00491897162213154,1 +"125",2015-02-11 16:52:00,21.89,30.34,428.25,786.333333333333,0.00493136856692414,1 +"126",2015-02-11 16:53:00,21.945,30.34,433,787.666666666667,0.00494808280707249,1 +"127",2015-02-11 16:53:59,21.945,30.39,433,786.5,0.00495630217221916,1 +"128",2015-02-11 16:54:59,21.89,30.365,433,791.75,0.00493546423117755,1 +"129",2015-02-11 16:56:00,21.89,30.39,433,788,0.00493955994894424,1 +"130",2015-02-11 16:57:00,21.9175,30.4725,433,797.75,0.00496146412590179,1 +"131",2015-02-11 16:58:00,21.9175,30.39,433,801.75,0.00494792480746019,1 +"132",2015-02-11 16:59:00,21.945,30.5,433,803.5,0.0049743855341721,1 +"133",2015-02-11 16:59:59,21.89,30.4725,433,811,0.00495307619726414,1 +"134",2015-02-11 17:00:59,21.89,30.4266666666667,433,803.666666666667,0.00494556709847047,1 +"135",2015-02-11 17:02:00,21.9725,30.5,433,801.5,0.00498280627566165,1 +"136",2015-02-11 17:03:00,21.945,30.5,433,804,0.0049743855341721,1 +"137",2015-02-11 17:04:00,21.9725,30.4175,433,807,0.0049692205153566,1 +"138",2015-02-11 17:05:00,21.945,30.3675,433,801.75,0.00495260343123349,1 +"139",2015-02-11 17:06:00,21.9725,30.4725,433,796.25,0.00497827762347398,1 +"140",2015-02-11 17:06:59,21.9266666666667,30.5333333333333,433,807,0.00497425247731314,1 +"141",2015-02-11 17:08:00,21.9725,30.55,433,823.75,0.00499104035633918,1 +"142",2015-02-11 17:09:00,21.89,30.4633333333333,433,818,0.00495157436311527,1 +"143",2015-02-11 17:10:00,21.956,30.458,433,807.5,0.00497084293173824,1 +"144",2015-02-11 17:10:59,21.9175,30.5,433,814,0.00496597736200092,1 +"145",2015-02-11 17:12:00,21.9633333333333,30.39,433,804.25,0.00496189403797198,1 +"146",2015-02-11 17:12:59,21.945,30.445,433,805,0.00496534372280247,1 +"147",2015-02-11 17:13:59,21.945,30.3975,433,805.75,0.00495753509557926,1 +"148",2015-02-11 17:15:00,21.945,30.3425,433,799.25,0.00494849377021143,1 +"149",2015-02-11 17:16:00,22,30.445,433,797,0.00498216691274296,1 +"150",2015-02-11 17:17:00,21.9725,30.4175,433,798.25,0.0049692205153566,1 +"151",2015-02-11 17:18:00,22,30.2,433,784.5,0.00494175539235679,1 +"152",2015-02-11 17:19:00,21.9266666666667,30.3266666666667,423.666666666667,780.666666666667,0.00494031653953569,1 +"153",2015-02-11 17:19:59,21.9725,30.365,433,782.75,0.00496057533806915,1 +"154",2015-02-11 17:21:00,21.89,30.39,426,787,0.00493955994894424,1 +"155",2015-02-11 17:22:00,21.89,30.245,426,790.5,0.00491580553078374,1 +"156",2015-02-11 17:23:00,21.89,30.3175,429.5,782.25,0.00492768251484905,1 +"157",2015-02-11 17:23:59,21.89,30.1966666666667,423.666666666667,778,0.00490788779141084,1 +"158",2015-02-11 17:25:00,21.89,30.2475,422.5,778,0.00491621507446711,1 +"159",2015-02-11 17:25:59,21.89,30.1333333333333,428.333333333333,773.333333333333,0.00489751312530247,1 +"160",2015-02-11 17:26:59,21.89,30.175,419,766.25,0.00490433852488914,1 +"161",2015-02-11 17:28:00,21.89,30.125,419,756.25,0.00489614806321981,1 +"162",2015-02-11 17:29:00,21.89,30.175,419,751.333333333333,0.00490433852488914,1 +"163",2015-02-11 17:30:00,21.89,30.0333333333333,419,746.5,0.00488113277265885,1 +"164",2015-02-11 17:31:00,21.89,29.8675,419,740.5,0.00485397057459965,1 +"165",2015-02-11 17:31:59,21.84,29.84,419,735,0.00483456861993528,1 +"166",2015-02-11 17:32:59,21.89,29.89,419,719,0.00485765575993721,1 +"167",2015-02-11 17:34:00,21.815,29.84,419,718,0.00482713483512968,1 +"168",2015-02-11 17:35:00,21.8233333333333,29.8566666666667,419,716,0.00483233010252681,1 +"169",2015-02-11 17:36:00,21.84,29.84,419,712.25,0.00483456861993528,1 +"170",2015-02-11 17:37:00,21.815,29.815,419,708.5,0.0048230592947544,1 +"171",2015-02-11 17:38:00,21.84,29.795,419,702,0.00482722130108145,1 +"172",2015-02-11 17:38:59,21.8233333333333,29.8233333333333,419,702,0.00482689320364354,1 +"173",2015-02-11 17:39:59,21.815,29.7475,419,695.75,0.00481205560045731,1 +"174",2015-02-11 17:41:00,21.79,29.73,419,686.666666666667,0.00480180695172817,1 +"175",2015-02-11 17:42:00,21.815,29.55,419,679.75,0.00477986182481734,1 +"176",2015-02-11 17:43:00,21.79,29.5,419,674,0.00476437421834314,1 +"177",2015-02-11 17:44:00,21.79,29.3675,419,669.25,0.00474281173856628,1 +"178",2015-02-11 17:44:59,21.79,29.745,419,667.5,0.00480424837225991,1 +"179",2015-02-11 17:45:59,21.815,29.6725,419,679,0.00479982972655858,1 +"180",2015-02-11 17:47:00,21.79,29.6,419,678,0.00478064877043622,1 +"181",2015-02-11 17:48:00,21.84,29.55,419,674,0.0047872222532215,1 +"182",2015-02-11 17:49:00,21.79,29.4725,419,666.5,0.00475989886468141,1 +"183",2015-02-11 17:50:00,21.79,29.34,419,665.666666666667,0.00473833669282797,1 +"184",2015-02-11 17:51:00,21.89,29.29,419,648.666666666667,0.00475939897688161,1 +"185",2015-02-11 17:51:59,21.84,29.315,419,643.25,0.00474886061580987,1 +"186",2015-02-11 17:53:00,21.89,29.29,419,635,0.00475939897688161,1 +"187",2015-02-11 17:54:00,21.865,29.29,419,636.25,0.00475208445945421,1 +"188",2015-02-11 17:55:00,21.89,29.34,419,636.25,0.00476758586563602,1 +"189",2015-02-11 17:55:59,21.89,29.29,419,639,0.00475939897688161,1 +"190",2015-02-11 17:57:00,21.8566666666667,29.4333333333333,419,640.333333333333,0.00477306969846789,1 +"191",2015-02-11 17:57:59,21.89,29.2675,419,639.75,0.00475571494671863,1 +"192",2015-02-11 17:58:59,21.89,29.245,419,638.5,0.00475203095986413,1 +"193",2015-02-11 18:00:00,21.89,29.42,415.5,643.5,0.00478068533251944,1 +"194",2015-02-11 18:01:00,21.89,29.7725,415,648,0.00483841138085258,1 +"195",2015-02-11 18:02:00,21.89,29.7475,419,656.75,0.00483431698455686,1 +"196",2015-02-11 18:03:00,21.89,29.4566666666667,419,655.666666666667,0.00478668943783764,1 +"197",2015-02-11 18:04:00,21.89,29.2675,419,646.75,0.00475571494671863,1 +"198",2015-02-11 18:04:59,21.89,29.29,419,643,0.00475939897688161,1 +"199",2015-02-11 18:06:00,21.89,29.23,419,639,0.00474957499268768,1 +"200",2015-02-11 18:07:00,21.89,29.2,419,633.5,0.00474466311607751,1 +"201",2015-02-11 18:08:00,21.865,29.125,419,631,0.00472511107548626,1 +"202",2015-02-11 18:08:59,21.89,29.125,419,626,0.00473238376137405,1 +"203",2015-02-11 18:10:00,21.815,28.9725,419,614.75,0.00468574456449438,1 +"204",2015-02-11 18:10:59,21.79,28.89,419,606,0.00466511774934596,1 +"205",2015-02-11 18:11:59,21.8233333333333,28.8566666666667,419,603,0.00466926415276969,1 +"206",2015-02-11 18:13:00,21.79,28.79,419,600.75,0.00464884919621899,1 +"207",2015-02-11 18:14:00,21.79,28.695,419,601,0.00463339485311415,1 +"208",2015-02-11 18:15:00,21.79,28.6333333333333,419,601.666666666667,0.00462336349452756,1 +"209",2015-02-11 18:16:00,21.79,28.7225,419,597.25,0.00463786840035822,1 +"210",2015-02-11 18:16:59,21.79,28.6475,419,596.5,0.00462566796740816,1 +"211",2015-02-11 18:17:59,21.79,28.5333333333333,419,596.666666666667,0.00460709710922468,1 +"212",2015-02-11 18:19:00,21.79,28.525,419,595.25,0.00460574161523633,1 +"213",2015-02-11 18:20:00,21.79,28.42,419,588.5,0.0045886628934385,1 +"214",2015-02-11 18:21:00,21.79,28.55,419,585,0.00460980811479494,1 +"215",2015-02-11 18:22:00,21.7675,28.5,419,585.75,0.0045953065419468,1 +"216",2015-02-11 18:23:00,21.7,28.445,412,584.5,0.00456735110467873,1 +"217",2015-02-11 18:23:59,21.7,28.5,279.333333333333,585,0.00457624730784069,1 +"218",2015-02-11 18:24:59,21.7,28.5666666666667,0,582,0.00458703092309197,0 +"219",2015-02-11 18:26:00,21.7,28.76,0,578,0.00461830550644963,0 +"220",2015-02-11 18:27:00,21.7,28.79,0,584,0.00462315873885162,0 +"221",2015-02-11 18:28:00,21.7,28.79,0,586.5,0.00462315873885162,0 +"222",2015-02-11 18:29:00,21.7,28.84,0,587.5,0.00463124762658534,0 +"223",2015-02-11 18:29:59,21.7,28.86,0,586,0.00463448324015265,0 +"224",2015-02-11 18:30:59,21.7,28.86,0,592.333333333333,0.00463448324015265,0 +"225",2015-02-11 18:32:00,21.7,28.79,0,590,0.00462315873885162,0 +"226",2015-02-11 18:33:00,21.6,28.895,0,590,0.00461164261320868,0 +"227",2015-02-11 18:34:00,21.6333333333333,28.79,0,590.5,0.00460420963733684,0 +"228",2015-02-11 18:35:00,21.6,28.73,0,593.5,0.00458511448684379,0 +"229",2015-02-11 18:36:00,21.6,28.79,0,595,0.00459476081835653,0 +"230",2015-02-11 18:36:59,21.6,28.79,0,594.666666666667,0.00459476081835653,0 +"231",2015-02-11 18:38:00,21.55,28.79,0,593,0.00458061967899108,0 +"232",2015-02-11 18:39:00,21.6,28.79,0,582.5,0.00459476081835653,0 +"233",2015-02-11 18:40:00,21.6,28.79,0,579.5,0.00459476081835653,0 +"234",2015-02-11 18:40:59,21.6,28.79,0,588,0.00459476081835653,0 +"235",2015-02-11 18:42:00,21.5,28.84,0,596.5,0.00457450602730472,0 +"236",2015-02-11 18:42:59,21.5,28.8233333333333,0,622.333333333333,0.00457184298425214,0 +"237",2015-02-11 18:43:59,21.5,28.79,0,606,0.00456651696605658,0 +"238",2015-02-11 18:45:00,21.5,29.6,0,605,0.00469596484633747,0 +"239",2015-02-11 18:46:00,21.5,28.995,0,642.5,0.00459927341192726,0 +"240",2015-02-11 18:47:00,21.39,29.015,0,604.25,0.00457133321177775,0 +"241",2015-02-11 18:48:00,21.39,29.445,0,596,0.00463958534047274,0 +"242",2015-02-11 18:49:00,21.39,29.2,0,612,0.00460069567733772,0 +"243",2015-02-11 18:49:59,21.39,29.1,0,720.5,0.00458482373260557,0 +"244",2015-02-11 18:51:00,21.3233333333333,29.33,0,1760,0.00460234373974201,0 +"245",2015-02-11 18:52:00,21.29,29,0,1665,0.00454082327365664,0 +"246",2015-02-11 18:53:00,21.29,29.03,0,1255.66666666667,0.00454555500550858,0 +"247",2015-02-11 18:53:59,21.29,29.2,0,724,0.00457236950270718,0 +"248",2015-02-11 18:55:00,21.29,29.1,0,619,0.00455659599110503,0 +"249",2015-02-11 18:55:59,21.29,29.9,0,562.5,0.00468280632526691,0 +"250",2015-02-11 18:56:59,21.29,29.9266666666667,0,582,0.00468701421209814,0 +"251",2015-02-11 18:58:00,21.29,29.8,0,616,0.00466702725290859,0 +"252",2015-02-11 18:59:00,21.245,29.55,0,648.5,0.00461473213121645,0 +"253",2015-02-11 19:00:00,21.2,29.5,0,673,0.00459406856462562,0 +"254",2015-02-11 19:01:00,21.2,30.1,0,608,0.00468821152431995,0 +"255",2015-02-11 19:01:59,21.2,29.6,0,752,0.00460975709363184,0 +"256",2015-02-11 19:02:59,21.2,30.45,0,621.5,0.00474314131602537,0 +"257",2015-02-11 19:04:00,21.2,30,0,589.333333333333,0.00467251906656465,0 +"258",2015-02-11 19:05:00,21.2,29.9,0,608.5,0.00465682739467722,0 +"259",2015-02-11 19:06:00,21.2,29.945,0,620,0.00466388854977919,0 +"260",2015-02-11 19:07:00,21.2,29.495,0,598.5,0.00459328415879708,0 +"261",2015-02-11 19:08:00,21.2,29.64,0,640.5,0.00461603272520792,0 +"262",2015-02-11 19:08:59,21.2,29.9633333333333,0,695,0.00466676536229439,0 +"263",2015-02-11 19:09:59,21.2,29.89,0,670,0.00465525827070893,0 +"264",2015-02-11 19:11:00,21.2,29.79,0,619,0.00463956746320798,0 +"265",2015-02-11 19:12:00,21.2,29.76,0,571.666666666667,0.00463486037418044,0 +"266",2015-02-11 19:13:00,21.2,29.995,0,533.5,0.00467173446430641,0 +"267",2015-02-11 19:14:00,21.1666666666667,29.9966666666667,0,618.666666666667,0.00466237504730255,0 +"268",2015-02-11 19:14:59,21.2,30.2,0,516,0.00470390476800215,0 +"269",2015-02-11 19:15:59,21.15,31.05,0,515,0.00482238981986243,0 +"270",2015-02-11 19:17:00,21.15,29.8,0,513.5,0.00462680762837323,0 +"271",2015-02-11 19:18:00,21.15,29.645,0,520,0.00460256394184382,0 +"272",2015-02-11 19:19:00,21.1,29.65,0,527.5,0.00458912915155477,0 +"273",2015-02-11 19:20:00,21.1,29.45,0,526,0.0045579469742819,0 +"274",2015-02-11 19:21:00,21.1,29.6633333333333,0,526.333333333333,0.00459120807372759,0 +"275",2015-02-11 19:21:59,21.1,29.795,0,528,0.00461173817093849,0 +"276",2015-02-11 19:23:00,21.1,29.89,0,524,0.00462655186142874,0 +"277",2015-02-11 19:24:00,21.1,29.695,0,524.5,0.00459614556917648,0 +"278",2015-02-11 19:25:00,21.1,29.8966666666667,0,521.333333333333,0.00462759144495691,0 +"279",2015-02-11 19:25:59,21.1,29.995,0,524,0.00464292570267342,0 +"280",2015-02-11 19:27:00,21.1,29.945,0,522.5,0.00463512852869522,0 +"281",2015-02-11 19:27:59,21.1,29.79,0,526,0.00461095852241966,0 +"282",2015-02-11 19:28:59,21.05,29.75,0,520,0.00459049484235374,0 +"283",2015-02-11 19:30:00,21.1,30.29,0,526,0.00468893297910483,0 +"284",2015-02-11 19:31:00,21.1,29.39,0,530,0.00454859292628501,0 +"285",2015-02-11 19:32:00,21.1,29.6,0,529,0.00458133331626704,0 +"286",2015-02-11 19:33:00,21.1,29.34,0,529,0.00454079809963765,0 +"287",2015-02-11 19:34:00,21.1,29.745,0,527,0.00460394177305473,0 +"288",2015-02-11 19:34:59,21.1,29.3933333333333,0,530,0.0045491125882909,0 +"289",2015-02-11 19:36:00,21.1,30.05,0,526,0.00465150281816791,0 +"290",2015-02-11 19:37:00,21.075,29.5,0,526,0.00455868478206748,0 +"291",2015-02-11 19:38:00,21.1,29.5,0,526,0.00456574222763784,0 +"292",2015-02-11 19:38:59,21.1,30.09,0,531.5,0.00465774086782293,0 +"293",2015-02-11 19:40:00,21.1,30.1,0,534,0.00465930039964209,0 +"294",2015-02-11 19:40:59,21,29.495,0,533,0.00453679550654645,0 +"295",2015-02-11 19:41:59,21.1,29.445,0,521.333333333333,0.00455716745961438,0 +"296",2015-02-11 19:43:00,21.1,29.645,0,523.5,0.00458834955929649,0 +"297",2015-02-11 19:44:00,21.1,30.1,0,521,0.00465930039964209,0 +"298",2015-02-11 19:45:00,21,29.945,0,522,0.00460652521443113,0 +"299",2015-02-11 19:46:00,21.1,29.6,0,520,0.00458133331626704,0 +"300",2015-02-11 19:46:59,21.025,30.1225,0,520.5,0.00464121308755847,0 +"301",2015-02-11 19:47:59,21,30,0,520,0.00461504879873074,0 +"302",2015-02-11 19:49:00,21,29.53,0,523.666666666667,0.00454221837168049,0 +"303",2015-02-11 19:50:00,21,29.55,0,520,0.00454531719390439,0 +"304",2015-02-11 19:51:00,21,29.195,0,524.5,0.0044903176557902,0 +"305",2015-02-11 19:52:00,21,29.53,0,519.333333333333,0.00454221837168049,0 +"306",2015-02-11 19:53:00,21,29.445,0,519,0.00452904871919258,0 +"307",2015-02-11 19:53:59,21,30.1,0,520,0.00463054681883977,0 +"308",2015-02-11 19:54:59,21,29.945,0,522.5,0.00460652521443113,0 +"309",2015-02-11 19:56:00,21,29.8,0,527.5,0.00458405505820984,0 +"310",2015-02-11 19:57:00,21,30.0666666666667,0,537,0.00462538072695717,0 +"311",2015-02-11 19:58:00,21,29.7666666666667,0,542.333333333333,0.004578889732874,0 +"312",2015-02-11 19:59:00,21,29.5,0,548,0.00453757019581831,0 +"313",2015-02-11 19:59:59,21,29.995,0,545.5,0.00461427391784861,0 +"314",2015-02-11 20:00:59,21,29.9266666666667,0,549.666666666667,0.00460368407119449,0 +"315",2015-02-11 20:02:00,21,29.495,0,562,0.00453679550654645,0 +"316",2015-02-11 20:03:00,21,29.5,0,583,0.00453757019581831,0 +"317",2015-02-11 20:04:00,21,29.4475,0,552,0.00452943605401049,0 +"318",2015-02-11 20:05:00,21,29.6966666666667,0,540,0.00456804282686637,0 +"319",2015-02-11 20:06:00,21,29.445,0,527.333333333333,0.00452904871919258,0 +"320",2015-02-11 20:06:59,21,29.4,0,523.333333333333,0.00452207677436432,0 +"321",2015-02-11 20:08:00,21,29.495,0,517,0.00453679550654645,0 +"322",2015-02-11 20:09:00,21,30.06,0,517.333333333333,0.00462434751880236,0 +"323",2015-02-11 20:10:00,21,30,0,513,0.00461504879873074,0 +"324",2015-02-11 20:10:59,21,29.995,0,511,0.00461427391784861,0 +"325",2015-02-11 20:12:00,21,29.56,0,513,0.00454686661651124,0 +"326",2015-02-11 20:12:59,21,29.35,0,513,0.00451433035098219,0 +"327",2015-02-11 20:13:59,21,29.9,0,512.333333333333,0.00459955154520639,0 +"328",2015-02-11 20:15:00,21,29.8,0,510.5,0.00458405505820984,0 +"329",2015-02-11 20:16:00,20.9266666666667,29.5933333333333,0,512,0.00453140356716867,0 +"330",2015-02-11 20:17:00,20.945,29.445,0,509,0.00451364879466593,0 +"331",2015-02-11 20:18:00,20.945,29.6,0,502.5,0.00453758220823091,0 +"332",2015-02-11 20:19:00,21,29.55,0,503,0.00454531719390439,0 +"333",2015-02-11 20:19:59,21,29.6,0,502,0.00455306438357266,0 +"334",2015-02-11 20:21:00,21,29.2,0,502,0.00449109223013001,0 +"335",2015-02-11 20:22:00,21,29.23,0,500,0.00449573971639093,0 +"336",2015-02-11 20:23:00,21,29.745,0,504,0.00457553231707361,0 +"337",2015-02-11 20:23:59,21,29.245,0,506.5,0.00449806348537876,0 +"338",2015-02-11 20:25:00,21,30.09,0,497,0.00462899698233093,0 +"339",2015-02-11 20:25:59,20.9725,30.0475,0,493.5,0.00461454449617954,0 +"340",2015-02-11 20:26:59,20.945,30.4,0,494.5,0.00466113858404688,0 +"341",2015-02-11 20:28:00,20.9266666666667,30.0933333333333,0,499.666666666667,0.00460853204846124,0 +"342",2015-02-11 20:29:00,20.9266666666667,29.83,0,498.333333333333,0.00456790868151425,0 +"343",2015-02-11 20:30:00,20.89,30.29,0,498,0.00462834583303539,0 +"344",2015-02-11 20:31:00,20.89,29.35,0,499,0.00448367740645792,0 +"345",2015-02-11 20:31:59,20.89,29.7633333333333,0,501.666666666667,0.0045472822441782,0 +"346",2015-02-11 20:32:59,20.945,30,0,499,0.00459935430525412,0 +"347",2015-02-11 20:34:00,20.89,29.6175,0,492.25,0.00452483954672639,0 +"348",2015-02-11 20:35:00,20.89,29.79,0,495,0.00455138622559595,0 +"349",2015-02-11 20:36:00,20.89,29.92,0,492,0.00457139390494109,0 +"350",2015-02-11 20:37:00,20.89,29.3,0,494.5,0.00447598414841847,0 +"351",2015-02-11 20:38:00,20.89,29.5,0,499,0.00450675831431613,0 +"352",2015-02-11 20:38:59,20.89,29.5933333333333,0,497.333333333333,0.00452112062643947,0 +"353",2015-02-11 20:39:59,20.89,29.7,0,493,0.00453753550378,0 +"354",2015-02-11 20:41:00,20.89,29.79,0,491.5,0.00455138622559595,0 +"355",2015-02-11 20:42:00,20.89,29.7675,0,492,0.00454792348773076,0 +"356",2015-02-11 20:43:00,20.89,29.495,0,492,0.00450598892332083,0 +"357",2015-02-11 20:44:00,20.89,30.42,0,486,0.0046483584278666,0 +"358",2015-02-11 20:44:59,20.89,29.6,0,488,0.00452214653107444,0 +"359",2015-02-11 20:45:59,20.8566666666667,29.6266666666667,0,491.333333333333,0.00451690927640663,0 +"360",2015-02-11 20:47:00,20.89,29.495,0,491,0.00450598892332083,0 +"361",2015-02-11 20:48:00,20.89,29.35,0,491,0.00448367740645792,0 +"362",2015-02-11 20:49:00,20.89,29.5,0,496,0.00450675831431613,0 +"363",2015-02-11 20:50:00,20.89,29.29,0,500,0.00447444551948421,0 +"364",2015-02-11 20:51:00,20.79,29.1666666666667,0,495.666666666667,0.0044279385473201,0 +"365",2015-02-11 20:51:59,20.89,29.65,0,489,0.00452984092293033,0 +"366",2015-02-11 20:53:00,20.89,29.65,0,489,0.00452984092293033,0 +"367",2015-02-11 20:54:00,20.79,29.5,0,489,0.00447890795670226,0 +"368",2015-02-11 20:55:00,20.8566666666667,29.5333333333333,0,495,0.00450257658237428,0 +"369",2015-02-11 20:55:59,20.8233333333333,30.1266666666667,0,494,0.00458421917265433,0 +"370",2015-02-11 20:57:00,20.79,29.2966666666667,0,495.5,0.00444781563042489,0 +"371",2015-02-11 20:57:59,20.84,30.045,0,495,0.00457642762145289,0 +"372",2015-02-11 20:58:59,20.79,29.545,0,493.5,0.00448578946242047,0 +"373",2015-02-11 21:00:00,20.79,29.495,0,494,0.0044781433542877,0 +"374",2015-02-11 21:01:00,20.79,29.29,0,496,0.00444679626214408,0 +"375",2015-02-11 21:02:00,20.79,29.395,0,486,0.00446285169792195,0 +"376",2015-02-11 21:03:00,20.79,30.25,0,485,0.0045936194592834,0 +"377",2015-02-11 21:04:00,20.79,29.34,0,490,0.00445444160511457,0 +"378",2015-02-11 21:04:59,20.79,29.3,0,488,0.00444832531580936,0 +"379",2015-02-11 21:06:00,20.76,29.5633333333333,0,484.666666666667,0.00448024952733589,0 +"380",2015-02-11 21:07:00,20.79,30.0966666666667,0,485.333333333333,0.00457016391371587,0 +"381",2015-02-11 21:08:00,20.79,29.89,0,487.5,0.00453855269584072,0 +"382",2015-02-11 21:08:59,20.79,29.89,0,493,0.00453855269584072,0 +"383",2015-02-11 21:10:00,20.79,29.795,0,496.5,0.00452402280285655,0 +"384",2015-02-11 21:10:59,20.79,30.05,0,490,0.00456302561796166,0 +"385",2015-02-11 21:11:59,20.79,29.85,0,493.5,0.00453243476402249,0 +"386",2015-02-11 21:13:00,20.79,29.45,0,489,0.00447126201654179,0 +"387",2015-02-11 21:14:00,20.79,29.83,0,486.333333333333,0.00452937584291777,0 +"388",2015-02-11 21:15:00,20.79,29.445,0,486.5,0.00447049743279047,0 +"389",2015-02-11 21:16:00,20.79,29.39,0,486,0.00446208713469941,0 +"390",2015-02-11 21:16:59,20.79,29.55,0,486,0.00448655408349896,0 +"391",2015-02-11 21:17:59,20.79,29.39,0,486,0.00446208713469941,0 +"392",2015-02-11 21:19:00,20.79,30.2,0,488,0.00458597071886192,0 +"393",2015-02-11 21:20:00,20.79,29.7933333333333,0,489.333333333333,0.00452376789846859,0 +"394",2015-02-11 21:21:00,20.79,29.39,0,488.5,0.00446208713469941,0 +"395",2015-02-11 21:22:00,20.79,29.245,0,488,0.00443991561302027,0 +"396",2015-02-11 21:23:00,20.79,29.05,0,493,0.00441010121334201,0 +"397",2015-02-11 21:23:59,20.79,29.2475,0,489,0.0044402978673396,0 +"398",2015-02-11 21:24:59,20.79,30.6,0,486,0.00464716587130211,0 +"399",2015-02-11 21:26:00,20.79,29.79,0,486.666666666667,0.00452325809031493,0 +"400",2015-02-11 21:27:00,20.745,29.545,0,490.5,0.00447328713715764,0 +"401",2015-02-11 21:28:00,20.79,29.945,0,487.5,0.00454696504718207,0 +"402",2015-02-11 21:29:00,20.79,30.045,0,488,0.00456226081020628,0 +"403",2015-02-11 21:29:59,20.79,29.59,0,494,0.00449267111931899,0 +"404",2015-02-11 21:30:59,20.79,29.495,0,492,0.0044781433542877,0 +"405",2015-02-11 21:32:00,20.79,29.95,0,487.5,0.0045477298175966,0 +"406",2015-02-11 21:33:00,20.79,29.795,0,489.5,0.00452402280285655,0 +"407",2015-02-11 21:34:00,20.7,29.79,0,488,0.00449807411610544,0 +"408",2015-02-11 21:35:00,20.7,29,0,488,0.00437795025812882,0 +"409",2015-02-11 21:36:00,20.79,29.495,0,492,0.0044781433542877,0 +"410",2015-02-11 21:36:59,20.79,29.33,0,488,0.00445291252159154,0 +"411",2015-02-11 21:38:00,20.79,29.2,0,486,0.00443303511504357,0 +"412",2015-02-11 21:39:00,20.79,29.84,0,489,0.00453090529973648,0 +"413",2015-02-11 21:40:00,20.76,29.4266666666667,0,488.333333333333,0.00445938954469104,0 +"414",2015-02-11 21:40:59,20.745,29.52,0,487.5,0.00446947479106151,0 +"415",2015-02-11 21:42:00,20.79,29.5,0,489,0.00447890795670226,0 +"416",2015-02-11 21:42:59,20.79,28.895,0,495,0.00438640461231233,0 +"417",2015-02-11 21:43:59,20.7,29.145,0,492,0.00439999485635369,0 +"418",2015-02-11 21:45:00,20.7225,29.67,0,488.75,0.00448608316563041,0 +"419",2015-02-11 21:46:00,20.7,29.3566666666667,0,491,0.00443217768796195,0 +"420",2015-02-11 21:47:00,20.745,29.39,0,492.5,0.0044496513392958,0 +"421",2015-02-11 21:48:00,20.745,29.29,0,486,0.00443440338391366,0 +"422",2015-02-11 21:49:00,20.7,29.39,0,495,0.0044372461518178,0 +"423",2015-02-11 21:49:59,20.7,29.34,0,494.5,0.00442964348679036,0 +"424",2015-02-11 21:51:00,20.7,28.65,0,495,0.00432474555120397,0 +"425",2015-02-11 21:52:00,20.7,28.9,0,496,0.00436274799094705,0 +"426",2015-02-11 21:53:00,20.7,29.6,0,490.5,0.00446917936020743,0 +"427",2015-02-11 21:53:59,20.7,29.695,0,492,0.00448362640498455,0 +"428",2015-02-11 21:55:00,20.7,28.645,0,485,0.00432398554944471,0 +"429",2015-02-11 21:55:59,20.7,29.2633333333333,0,490.333333333333,0.00441798642548738,0 +"430",2015-02-11 21:56:59,20.7,29.29,0,489,0.00442204100629797,0 +"431",2015-02-11 21:58:00,20.7,29.9966666666667,0,490,0.00452950652627233,0 +"432",2015-02-11 21:59:00,20.7,29.4966666666667,0,493.333333333333,0.00445346578733109,0 +"433",2015-02-11 22:00:00,20.7,29.2,0,488,0.00440835700641855,0 +"434",2015-02-11 22:01:00,20.7,29.13,0,490.666666666667,0.0043977143087196,0 +"435",2015-02-11 22:01:59,20.7,28.7225,0,489,0.00433576578398378,0 +"436",2015-02-11 22:02:59,20.7,29.0266666666667,0,487,0.00438200432067456,0 +"437",2015-02-11 22:04:00,20.7,29.545,0,490.5,0.0044608155861957,0 +"438",2015-02-11 22:05:00,20.7,28.895,0,494,0.00436198789695838,0 +"439",2015-02-11 22:06:00,20.7,28.895,0,494.5,0.00436198789695838,0 +"440",2015-02-11 22:07:00,20.7,29.195,0,486,0.00440759680173243,0 +"441",2015-02-11 22:08:00,20.7,29.4,0,488.5,0.00443876670696809,0 +"442",2015-02-11 22:08:59,20.7,29.945,0,489.5,0.00452164812804414,0 +"443",2015-02-11 22:09:59,20.7,29.445,0,491.5,0.00444560929649399,0 +"444",2015-02-11 22:11:00,20.7,29.195,0,489,0.00440759680173243,0 +"445",2015-02-11 22:12:00,20.7,29.09,0,491.5,0.00439163292954454,0 +"446",2015-02-11 22:13:00,20.7,29.3,0,489,0.00442356148763397,0 +"447",2015-02-11 22:14:00,20.7,28.995,0,492.5,0.00437719012724369,0 +"448",2015-02-11 22:14:59,20.7,29.045,0,491,0.00438479151911604,0 +"449",2015-02-11 22:15:59,20.7,29.35,0,485,0.00443116400503283,0 +"450",2015-02-11 22:17:00,20.7,28.745,0,488,0.0043391859350781,0 +"451",2015-02-11 22:18:00,20.7,28.495,0,489.5,0.00430118635429052,0 +"452",2015-02-11 22:19:00,20.7,28.56,0,486.333333333333,0.00431106580172756,0 +"453",2015-02-11 22:20:00,20.7,28.2,0,487,0.00425635277897133,0 +"454",2015-02-11 22:21:00,20.6,28,0,487,0.00419981916413007,0 +"455",2015-02-11 22:21:59,20.7,28.8,0,491.5,0.00434754646166901,0 +"456",2015-02-11 22:23:00,20.7,28.29,0,487,0.00427003013846627,0 +"457",2015-02-11 22:24:00,20.6333333333333,28.9966666666667,0,487,0.00435937022173279,0 +"458",2015-02-11 22:25:00,20.6,28.195,0,488,0.00422926678050432,0 +"459",2015-02-11 22:25:59,20.6,28.33,0,486.333333333333,0.00424965521432269,0 +"460",2015-02-11 22:27:00,20.6,28.4,0,486,0.00426022751748929,0 +"461",2015-02-11 22:27:59,20.6,28.1,0,487,0.00421492015989576,0 +"462",2015-02-11 22:28:59,20.6,28.495,0,497,0.00427457621418519,0 +"463",2015-02-11 22:30:00,20.6,29,0,498,0.00435086190375414,0 +"464",2015-02-11 22:31:00,20.6,28.945,0,497,0.00434255265953035,0 +"465",2015-02-11 22:32:00,20.6,28.79,0,496.5,0.00431913688461813,0 +"466",2015-02-11 22:33:00,20.6,28.0333333333333,0,487,0.00420485274846104,0 +"467",2015-02-11 22:34:00,20.5,27.995,0,486.5,0.0041730700279078,0 +"468",2015-02-11 22:34:59,20.5,27.895,0,491.5,0.00415806389481231,0 +"469",2015-02-11 22:36:00,20.5,28.59,0,489,0.00426237139346761,0 +"470",2015-02-11 22:37:00,20.5333333333333,28.0233333333333,0,488,0.00418597964610078,0 +"471",2015-02-11 22:38:00,20.5,27.79,0,487,0.00414230822912348,0 +"472",2015-02-11 22:38:59,20.5,27.79,0,488,0.00414230822912348,0 +"473",2015-02-11 22:40:00,20.55,28.195,0,488.5,0.00421615767952661,0 +"474",2015-02-11 22:40:59,20.5,28.0966666666667,0,495,0.00418832700057701,0 +"475",2015-02-11 22:41:59,20.5,27.9633333333333,0,499.333333333333,0.00416831800794196,0 +"476",2015-02-11 22:43:00,20.55,28.1,0,499,0.00420185582630295,0 +"477",2015-02-11 22:44:00,20.55,28.245,0,489,0.00422368523309845,0 +"478",2015-02-11 22:45:00,20.55,28.195,0,489.5,0.00421615767952661,0 +"479",2015-02-11 22:46:00,20.5,27.79,0,486,0.00414230822912348,0 +"480",2015-02-11 22:46:59,20.5,28.0966666666667,0,490.333333333333,0.00418832700057701,0 +"481",2015-02-11 22:47:59,20.5,27.7,0,488,0.00412880400389045,0 +"482",2015-02-11 22:49:00,20.5,28.16,0,484.666666666667,0.00419783172005139,0 +"483",2015-02-11 22:50:00,20.5,27.73,0,491.666666666667,0.00413330534757872,0 +"484",2015-02-11 22:51:00,20.5,28.7,0,492,0.00427888367947334,0 +"485",2015-02-11 22:52:00,20.5,28.445,0,488.5,0.00424060652859284,0 +"486",2015-02-11 22:53:00,20.5333333333333,28,0,489.333333333333,0.00418247079752938,0 +"487",2015-02-11 22:53:59,20.6,27.9,0,490,0.00418471889665931,0 +"488",2015-02-11 22:54:59,20.55,27.6,0,491.5,0.00412659368043955,0 +"489",2015-02-11 22:56:00,20.55,28.04,0,493.5,0.00419282341347972,0 +"490",2015-02-11 22:57:00,20.5,28.895,0,491,0.00430815759927824,0 +"491",2015-02-11 22:58:00,20.5,28.195,0,498.5,0.00420308445197078,0 +"492",2015-02-11 22:59:00,20.5,28.145,0,486,0.00419558057620488,0 +"493",2015-02-11 22:59:59,20.5666666666667,29.03,0,489.333333333333,0.00434638836093714,0 +"494",2015-02-11 23:00:59,20.6,28.1,0,488,0.00421492015989576,0 +"495",2015-02-11 23:02:00,20.6,27.95,0,489.5,0.00419226893936112,0 +"496",2015-02-11 23:03:00,20.6,27.84,0,488,0.0041756590857365,0 +"497",2015-02-11 23:04:00,20.6,28.4,0,493.5,0.00426022751748929,0 +"498",2015-02-11 23:05:00,20.6,27.995,0,497.5,0.00419906413345997,0 +"499",2015-02-11 23:06:00,20.65,28.495,0,496.5,0.00428786306497355,0 +"500",2015-02-11 23:06:59,20.6,28,0,493,0.00419981916413007,0 +"501",2015-02-11 23:08:00,20.6,28.29,0,492,0.00424361405849179,0 +"502",2015-02-11 23:09:00,20.6,27.84,0,491.5,0.0041756590857365,0 +"503",2015-02-11 23:10:00,20.6,27.7633333333333,0,494,0.00416408304216839,0 +"504",2015-02-11 23:10:59,20.6,27.745,0,493,0.00416131492124927,0 +"505",2015-02-11 23:12:00,20.6,27.945,0,492,0.00419151392689803,0 +"506",2015-02-11 23:12:59,20.6,27.945,0,493.5,0.00419151392689803,0 +"507",2015-02-11 23:13:59,20.6,28.1,0,497,0.00421492015989576,0 +"508",2015-02-11 23:15:00,20.6,28.29,0,499,0.00424361405849179,0 +"509",2015-02-11 23:16:00,20.6,27.695,0,501,0.00415376562495391,0 +"510",2015-02-11 23:17:00,20.6,28.1475,0,498.25,0.0042220933880305,0 +"511",2015-02-11 23:18:00,20.6,28.29,0,498,0.00424361405849179,0 +"512",2015-02-11 23:19:00,20.6,28.03,0,498,0.00420434938638641,0 +"513",2015-02-11 23:19:59,20.6,27.53,0,495,0.00412885423867154,0 +"514",2015-02-11 23:21:00,20.6,27.7,0,493,0.00415452054639183,0 +"515",2015-02-11 23:22:00,20.6,27.995,0,494.5,0.00419906413345997,0 +"516",2015-02-11 23:23:00,20.6,27.295,0,495,0.00409337780724628,0 +"517",2015-02-11 23:23:59,20.6,27.495,0,494.5,0.00412357026004226,0 +"518",2015-02-11 23:25:00,20.7,27.79,0,500,0.0041940523670117,0 +"519",2015-02-11 23:25:59,20.65,27.59,0,499.5,0.00415077193344933,0 +"520",2015-02-11 23:26:59,20.6,27.5633333333333,0,497.666666666667,0.00413388668218732,0 +"521",2015-02-11 23:28:00,20.65,27.95,0,489.5,0.00420529823296916,0 +"522",2015-02-11 23:29:00,20.6,27.4,0,490,0.00410922848188558,0 +"523",2015-02-11 23:30:00,20.6,27.79,0,493,0.00416810944355923,0 +"524",2015-02-11 23:31:00,20.6,27.445,0,497.5,0.00411602187384888,0 +"525",2015-02-11 23:31:59,20.6,27.79,0,503,0.00416810944355923,0 +"526",2015-02-11 23:32:59,20.6,28.5,0,502,0.00427533142696163,0 +"527",2015-02-11 23:34:00,20.6,27.3633333333333,0,497.666666666667,0.00410369323446587,0 +"528",2015-02-11 23:35:00,20.6,27,0,498,0.00404884925400269,0 +"529",2015-02-11 23:36:00,20.6,27.2,0,499,0.00407903741219696,0 +"530",2015-02-11 23:37:00,20.65,27.34,0,495.5,0.00411291203409566,0 +"531",2015-02-11 23:38:00,20.7,27.65,0,497.5,0.00417278189443148,0 +"532",2015-02-11 23:38:59,20.65,27.695,0,497,0.0041666744565622,0 +"533",2015-02-11 23:39:59,20.6,27.53,0,495.666666666667,0.00412885423867154,0 +"534",2015-02-11 23:41:00,20.6,27.2266666666667,0,495.666666666667,0.00408306271992658,0 +"535",2015-02-11 23:42:00,20.6,27.79,0,498,0.00416810944355923,0 +"536",2015-02-11 23:43:00,20.6333333333333,27.0966666666667,0,497,0.00407185352319128,0 +"537",2015-02-11 23:44:00,20.6,26.84,0,498,0.00402470082344019,0 +"538",2015-02-11 23:44:59,20.6,26.8966666666667,0,500,0.00403325317953688,0 +"539",2015-02-11 23:45:59,20.6,27.195,0,497,0.00407828267276002,0 +"540",2015-02-11 23:47:00,20.6,27.745,0,499,0.00416131492124927,0 +"541",2015-02-11 23:48:00,20.6,27.5666666666667,0,499.333333333333,0.00413438993098815,0 +"542",2015-02-11 23:49:00,20.55,27.495,0,498.5,0.00411079092824493,0 +"543",2015-02-11 23:50:00,20.55,27.445,0,502.5,0.00410326608851558,0 +"544",2015-02-11 23:51:00,20.6,26.895,0,501,0.00403300163631638,0 +"545",2015-02-11 23:51:59,20.55,27.55,0,499,0.00411906846086061,0 +"546",2015-02-11 23:53:00,20.6,27.245,0,504.5,0.00408583014901599,0 +"547",2015-02-11 23:54:00,20.6,27.4966666666667,0,508,0.00412382187604991,0 +"548",2015-02-11 23:55:00,20.5666666666667,27.0933333333333,0,501.333333333333,0.00405453939756185,0 +"549",2015-02-11 23:55:59,20.55,26.995,0,502.5,0.0040355506693481,0 +"550",2015-02-11 23:57:00,20.6,27.04,0,502,0.00405488665274221,0 +"551",2015-02-11 23:57:59,20.6,27.04,0,504.666666666667,0.00405488665274221,0 +"552",2015-02-11 23:58:59,20.6,27.245,0,506.5,0.00408583014901599,0 +"553",2015-02-12 00:00:00,20.6,26.65,0,508,0.00399602698167932,0 +"554",2015-02-12 00:01:00,20.55,26.85,0,505.5,0.00401373437664451,0 +"555",2015-02-12 00:02:00,20.6,26.8,0,502.333333333333,0.00401866400688162,0 +"556",2015-02-12 00:03:00,20.6,27.1666666666667,0,500,0.00407400585032218,0 +"557",2015-02-12 00:04:00,20.6,26.89,0,498,0.00403224700786772,0 +"558",2015-02-12 00:04:59,20.55,27.39,0,503,0.00409498897371864,0 +"559",2015-02-12 00:06:00,20.6,26.9966666666667,0,502.333333333333,0.00404834614269721,0 +"560",2015-02-12 00:07:00,20.6,27.3633333333333,0,500.333333333333,0.00410369323446587,0 +"561",2015-02-12 00:08:00,20.6,26.7,0,499,0.00400357247484196,0 +"562",2015-02-12 00:08:59,20.6,26.4966666666667,0,507.666666666667,0.00397288860350841,0 +"563",2015-02-12 00:10:00,20.6,27,0,504,0.00404884925400269,0 +"564",2015-02-12 00:10:59,20.6,26.89,0,505,0.00403224700786772,0 +"565",2015-02-12 00:11:59,20.6,26.5,0,505,0.00397339159354124,0 +"566",2015-02-12 00:13:00,20.55,26.795,0,506.5,0.0040054596288896,0 +"567",2015-02-12 00:14:00,20.6,26.7633333333333,0,506,0.00401313036064676,0 +"568",2015-02-12 00:15:00,20.6,26.5,0,505,0.00397339159354124,0 +"569",2015-02-12 00:16:00,20.6,27.15,0,504,0.00407149009971225,0 +"570",2015-02-12 00:16:59,20.6,26.85,0,509,0.0040262100457718,0 +"571",2015-02-12 00:17:59,20.6,26.7933333333333,0,505.666666666667,0.00401765788210782,0 +"572",2015-02-12 00:19:00,20.6,27.145,0,508,0.00407073537847179,0 +"573",2015-02-12 00:20:00,20.6,27.2,0,506,0.00407903741219696,0 +"574",2015-02-12 00:21:00,20.5666666666667,27.1566666666667,0,499,0.00406407920992429,0 +"575",2015-02-12 00:22:00,20.575,27.0425,0,504.666666666667,0.00404897655441915,0 +"576",2015-02-12 00:23:00,20.6,26.84,0,508.666666666667,0.00402470082344019,0 +"577",2015-02-12 00:23:59,20.6,26.6,0,510.5,0.0039884816704127,0 +"578",2015-02-12 00:24:59,20.6,26.65,0,506,0.00399602698167932,0 +"579",2015-02-12 00:26:00,20.55,26.79,0,504,0.00400470738994098,0 +"580",2015-02-12 00:27:00,20.6,26.545,0,506,0.00398018203810149,0 +"581",2015-02-12 00:28:00,20.6,26.395,0,507,0.00395754779580271,0 +"582",2015-02-12 00:29:00,20.6,26.8,0,508.5,0.00401866400688162,0 +"583",2015-02-12 00:29:59,20.6,26.73,0,510.333333333333,0.00400809985805237,0 +"584",2015-02-12 00:30:59,20.6,26.89,0,508,0.00403224700786772,0 +"585",2015-02-12 00:32:00,20.6,26.65,0,502,0.00399602698167932,0 +"586",2015-02-12 00:33:00,20.6,26.5675,0,511,0.00398357731562803,0 +"587",2015-02-12 00:34:00,20.6,27,0,514,0.00404884925400269,0 +"588",2015-02-12 00:35:00,20.6,27.245,0,508,0.00408583014901599,0 +"589",2015-02-12 00:36:00,20.6,26.59,0,506.5,0.00398697262998632,0 +"590",2015-02-12 00:36:59,20.6,26.89,0,508,0.00403224700786772,0 +"591",2015-02-12 00:38:00,20.6,26.6,0,510.333333333333,0.0039884816704127,0 +"592",2015-02-12 00:39:00,20.6,26.2,0,507,0.0039281257277475,0 +"593",2015-02-12 00:40:00,20.6,26.15,0,511.5,0.00392058205324917,0 +"594",2015-02-12 00:40:59,20.6,26.79,0,512,0.00401715482093368,0 +"595",2015-02-12 00:42:00,20.6,26.77,0,515.25,0.0040141364708675,0 +"596",2015-02-12 00:42:59,20.6,26.245,0,514,0.0039349151902663,0 +"597",2015-02-12 00:43:59,20.6,26.7,0,513,0.00400357247484196,0 +"598",2015-02-12 00:45:00,20.6666666666667,26.26,0,516,0.00395349447018001,0 +"599",2015-02-12 00:46:00,20.65,26.35,0,516,0.0039630317850545,0 +"600",2015-02-12 00:47:00,20.7,26.7,0,510,0.00402848470749634,0 +"601",2015-02-12 00:48:00,20.7,26.7,0,510,0.00402848470749634,0 +"602",2015-02-12 00:49:00,20.65,26.245,0,510.5,0.00394713960380338,0 +"603",2015-02-12 00:49:59,20.6,27,0,516,0.00404884925400269,0 +"604",2015-02-12 00:51:00,20.6,26.295,0,520,0.00394245921026025,0 +"605",2015-02-12 00:52:00,20.6,26.545,0,518.666666666667,0.00398018203810149,0 +"606",2015-02-12 00:53:00,20.6,26,0,516.5,0.0038979521207095,0 +"607",2015-02-12 00:53:59,20.6,26,0,518,0.0038979521207095,0 +"608",2015-02-12 00:55:00,20.65,26,0,516.5,0.00391006098551608,0 +"609",2015-02-12 00:55:59,20.6,26.2,0,511,0.0039281257277475,0 +"610",2015-02-12 00:56:59,20.65,26.445,0,509.5,0.0039774111206015,0 +"611",2015-02-12 00:58:00,20.6666666666667,26.3,0,521,0.00395955488419174,0 +"612",2015-02-12 00:59:00,20.65,26.245,0,513.333333333333,0.00394713960380338,0 +"613",2015-02-12 01:00:00,20.6,26.195,0,518,0.00392737135211512,0 +"614",2015-02-12 01:01:00,20.6,26.495,0,521,0.00397263710879512,0 +"615",2015-02-12 01:01:59,20.6,26.3,0,516.5,0.00394321362226125,0 +"616",2015-02-12 01:02:59,20.6,26.0966666666667,0,514,0.00391253566753483,0 +"617",2015-02-12 01:04:00,20.6,26.1,0,518,0.00391303856058111,0 +"618",2015-02-12 01:05:00,20.6,27,0,517,0.00404884925400269,0 +"619",2015-02-12 01:06:00,20.6,26.2933333333333,0,519,0.00394220773999736,0 +"620",2015-02-12 01:07:00,20.6,26.55,0,521.5,0.00398093654103554,0 +"621",2015-02-12 01:08:00,20.6,26.56,0,525.666666666667,0.00398244555236013,0 +"622",2015-02-12 01:08:59,20.6,26.1,0,524,0.00391303856058111,0 +"623",2015-02-12 01:09:59,20.6,25.7,0,522,0.00385269716433744,0 +"624",2015-02-12 01:11:00,20.6,25.79,0,523,0.00386627296408967,0 +"625",2015-02-12 01:12:00,20.6,26.245,0,521.5,0.0039349151902663,0 +"626",2015-02-12 01:13:00,20.6,26.145,0,524.5,0.00391982769580011,0 +"627",2015-02-12 01:14:00,20.6,26.39,0,526,0.00395679334924909,0 +"628",2015-02-12 01:14:59,20.6,26.2,0,526,0.0039281257277475,0 +"629",2015-02-12 01:15:59,20.6,26.15,0,524.5,0.00392058205324917,0 +"630",2015-02-12 01:17:00,20.6,26.3,0,527.75,0.00394321362226125,0 +"631",2015-02-12 01:18:00,20.6,25.945,0,528,0.00388965488877046,0 +"632",2015-02-12 01:19:00,20.7,26,0,522,0.00392220301282748,0 +"633",2015-02-12 01:20:00,20.6,25.945,0,526.5,0.00388965488877046,0 +"634",2015-02-12 01:21:00,20.6,25.8,0,532,0.00386778142264025,0 +"635",2015-02-12 01:21:59,20.6,26.295,0,534.5,0.00394245921026025,0 +"636",2015-02-12 01:23:00,20.6,26.09,0,531,0.00391152988386656,0 +"637",2015-02-12 01:24:00,20.6,25.85,0,535,0.00387532382446475,0 +"638",2015-02-12 01:25:00,20.55,25.6,0,533.5,0.00382572592266322,0 +"639",2015-02-12 01:25:59,20.6,26.1,0,533,0.00391303856058111,0 +"640",2015-02-12 01:27:00,20.6,26.045,0,530,0.00390474092865236,0 +"641",2015-02-12 01:27:59,20.6,25.6633333333333,0,532,0.00384716645180423,0 +"642",2015-02-12 01:28:59,20.6,25.7633333333333,0,532.666666666667,0.00386225044350331,0 +"643",2015-02-12 01:30:00,20.6,25.6,0,534.5,0.00383761363311907,0 +"644",2015-02-12 01:31:00,20.7,25.7,0,537,0.00387666476140182,0 +"645",2015-02-12 01:32:00,20.7,25.8666666666667,0,539,0.00390196297189333,0 +"646",2015-02-12 01:33:00,20.6666666666667,25.8333333333333,0,543,0.00388885735516638,0 +"647",2015-02-12 01:34:00,20.6,26.1666666666667,0,542.666666666667,0.00392309659121159,0 +"648",2015-02-12 01:34:59,20.7,26.5,0,542,0.0039981148262085,0 +"649",2015-02-12 01:36:00,20.6,25.995,0,535.5,0.00389719781780647,0 +"650",2015-02-12 01:37:00,20.6,26.0633333333333,0,539.333333333333,0.0039075067815173,0 +"651",2015-02-12 01:38:00,20.6,26.29,0,540,0.00394170480007774,0 +"652",2015-02-12 01:38:59,20.6,25.745,0,540,0.00385948499059386,0 +"653",2015-02-12 01:40:00,20.6,25.8633333333333,0,541.666666666667,0.00387733516232013,0 +"654",2015-02-12 01:40:59,20.6,25.495,0,543,0.00382177670780691,0 +"655",2015-02-12 01:41:59,20.6,25.75,0,545.5,0.0038602392026,0 +"656",2015-02-12 01:43:00,20.6,25.895,0,544.5,0.00388211214153777,0 +"657",2015-02-12 01:44:00,20.6,25.79,0,543,0.00386627296408967,0 +"658",2015-02-12 01:45:00,20.6,25.825,0,545,0.00387155260082905,0 +"659",2015-02-12 01:46:00,20.6,26.445,0,546,0.00396509236136438,0 +"660",2015-02-12 01:46:59,20.6,25.95,0,541.5,0.0038904091734928,0 +"661",2015-02-12 01:47:59,20.6,25.6,0,536,0.00383761363311907,0 +"662",2015-02-12 01:49:00,20.55,25.445,0,536.5,0.00380242074378942,0 +"663",2015-02-12 01:50:00,20.5,25.5,0,549,0.00379888177542341,0 +"664",2015-02-12 01:51:00,20.5,26.045,0,551.5,0.00388058010777968,0 +"665",2015-02-12 01:52:00,20.5,25.895,0,551.5,0.00385809220072338,0 +"666",2015-02-12 01:53:00,20.55,25.645,0,557,0.00383249226746207,0 +"667",2015-02-12 01:53:59,20.5,25.445,0,554.5,0.00379063817440314,0 +"668",2015-02-12 01:54:59,20.5,25.29,0,552,0.00376740737633744,0 +"669",2015-02-12 01:56:00,20.6,25.6,0,549,0.00383761363311907,0 +"670",2015-02-12 01:57:00,20.55,25.1,0,544,0.00375055415705833,0 +"671",2015-02-12 01:58:00,20.6,25.445,0,544.5,0.00381423559650832,0 +"672",2015-02-12 01:59:00,20.6,25.2,0,549,0.0037772867780388,0 +"673",2015-02-12 01:59:59,20.6,25.29,0,547.5,0.00379085930639592,0 +"674",2015-02-12 02:00:59,20.6,25.5966666666667,0,548.333333333333,0.00383711086126653,0 +"675",2015-02-12 02:02:00,20.6,25.89,0,549,0.00388135787681343,0 +"676",2015-02-12 02:03:00,20.6,25.245,0,549,0.00378407296862427,0 +"677",2015-02-12 02:04:00,20.6,25.1,0,558,0.00376220688145424,0 +"678",2015-02-12 02:05:00,20.6,25.3966666666667,0,555,0.0038069460283381,0 +"679",2015-02-12 02:06:00,20.6,25.85,0,555.5,0.00387532382446475,0 +"680",2015-02-12 02:06:59,20.6,25.445,0,546.5,0.00381423559650832,0 +"681",2015-02-12 02:08:00,20.7,26.1,0,544,0.00393738390259364,0 +"682",2015-02-12 02:09:00,20.6,25.84,0,546.5,0.00387381532955679,0 +"683",2015-02-12 02:10:00,20.5,25.79,0,548,0.00384235162726924,0 +"684",2015-02-12 02:10:59,20.6,25.56,0,550,0.0038315804242036,0 +"685",2015-02-12 02:12:00,20.6,25.495,0,552.333333333333,0.00382177670780691,0 +"686",2015-02-12 02:12:59,20.6,25.195,0,552,0.00377653276594799,0 +"687",2015-02-12 02:13:59,20.6,25.395,0,549.5,0.00380669466694733,0 +"688",2015-02-12 02:15:00,20.6,25.495,0,549.5,0.00382177670780691,0 +"689",2015-02-12 02:16:00,20.6,25.195,0,553,0.00377653276594799,0 +"690",2015-02-12 02:17:00,20.5666666666667,25.4633333333333,0,554,0.00380911474293669,0 +"691",2015-02-12 02:18:00,20.6,25.35,0,551.5,0.00379990798572266,0 +"692",2015-02-12 02:19:00,20.6,25.2725,0,553.5,0.00378822015755026,0 +"693",2015-02-12 02:19:59,20.6,25.3933333333333,0,552.333333333333,0.00380644330575848,0 +"694",2015-02-12 02:21:00,20.6,25.5666666666667,0,549,0.00383258595094486,0 +"695",2015-02-12 02:22:00,20.6,25,0,550,0.0037471277116388,0 +"696",2015-02-12 02:23:00,20.6,25.2966666666667,0,549.333333333333,0.00379186470228768,0 +"697",2015-02-12 02:23:59,20.6,25.245,0,547.5,0.00378407296862427,0 +"698",2015-02-12 02:25:00,20.6,25.245,0,545.5,0.00378407296862427,0 +"699",2015-02-12 02:25:59,20.6,25.5,0,543.666666666667,0.00382253082893259,0 +"700",2015-02-12 02:26:59,20.6,25.53,0,551,0.00382705559385332,0 +"701",2015-02-12 02:28:00,20.6,25.195,0,552.5,0.00377653276594799,0 +"702",2015-02-12 02:29:00,20.6,25.195,0,554.5,0.00377653276594799,0 +"703",2015-02-12 02:30:00,20.6,25.14,0,553,0.00376823875287283,0 +"704",2015-02-12 02:31:00,20.6,25.1,0,555,0.00376220688145424,0 +"705",2015-02-12 02:31:59,20.6,25.29,0,555,0.00379085930639592,0 +"706",2015-02-12 02:32:59,20.6,24.945,0,560,0.0037388344780066,0 +"707",2015-02-12 02:34:00,20.6,25.2666666666667,0,553,0.00378734044621507,0 +"708",2015-02-12 02:35:00,20.6,25.1,0,553.333333333333,0.00376220688145424,0 +"709",2015-02-12 02:36:00,20.6,25.395,0,554.5,0.00380669466694733,0 +"710",2015-02-12 02:37:00,20.575,25.1475,0,558,0.00376352822837397,0 +"711",2015-02-12 02:38:00,20.6,24.89,0,555,0.00373054146419743,0 +"712",2015-02-12 02:38:59,20.6,25.05,0,556,0.00375466720570366,0 +"713",2015-02-12 02:39:59,20.6,25.695,0,552,0.0038519429705087,0 +"714",2015-02-12 02:41:00,20.6,25.05,0,557,0.00375466720570366,0 +"715",2015-02-12 02:42:00,20.5,25.29,0,555,0.00376740737633744,0 +"716",2015-02-12 02:43:00,20.6,25.745,0,561.5,0.00385948499059386,0 +"717",2015-02-12 02:44:00,20.6,25.445,0,561.5,0.00381423559650832,0 +"718",2015-02-12 02:44:59,20.6,25.05,0,563,0.00375466720570366,0 +"719",2015-02-12 02:45:59,20.6,25.03,0,559.666666666667,0.0037516513862758,0 +"720",2015-02-12 02:47:00,20.6,25.6,0,555,0.00383761363311907,0 +"721",2015-02-12 02:48:00,20.6,25.2,0,555,0.0037772867780388,0 +"722",2015-02-12 02:49:00,20.6,25.4,0,557,0.00380744875172542,0 +"723",2015-02-12 02:50:00,20.6,25.195,0,551.5,0.00377653276594799,0 +"724",2015-02-12 02:51:00,20.6,25.39,0,546.5,0.00380594058398654,0 +"725",2015-02-12 02:51:59,20.6,25.55,0,553.5,0.00383007214015013,0 +"726",2015-02-12 02:53:00,20.55,25.395,0,550,0.00379490331441264,0 +"727",2015-02-12 02:54:00,20.6,24.79,0,546,0.00371546382042611,0 +"728",2015-02-12 02:55:00,20.6,25.05,0,553.5,0.00375466720570366,0 +"729",2015-02-12 02:55:59,20.6,24.745,0,554,0.00370867911778745,0 +"730",2015-02-12 02:57:00,20.6,25.395,0,550,0.00380669466694733,0 +"731",2015-02-12 02:57:59,20.6,26.1,0,552,0.00391303856058111,0 +"732",2015-02-12 02:58:59,20.6,25.09,0,546,0.00376069893176895,0 +"733",2015-02-12 03:00:00,20.6,24.65,0,554,0.00369435633983301,0 +"734",2015-02-12 03:01:00,20.6,24.6,0,561,0.00368681829901744,0 +"735",2015-02-12 03:02:00,20.6,24.745,0,559,0.00370867911778745,0 +"736",2015-02-12 03:03:00,20.6,24.545,0,559,0.00367852666389879,0 +"737",2015-02-12 03:04:00,20.7,25,0,552,0.00377043460545993,0 +"738",2015-02-12 03:04:59,20.6,24.995,0,552,0.00374637377222477,0 +"739",2015-02-12 03:06:00,20.6,24.63,0,555.666666666667,0.00369134110171117,0 +"740",2015-02-12 03:07:00,20.6,24.6,0,556,0.00368681829901744,0 +"741",2015-02-12 03:08:00,20.6,24.895,0,559,0.00373129536546035,0 +"742",2015-02-12 03:08:59,20.6,25.395,0,557.5,0.00380669466694733,0 +"743",2015-02-12 03:10:00,20.6,24.9266666666667,0,560.666666666667,0.00373607011564586,0 +"744",2015-02-12 03:10:59,20.6,25,0,561,0.0037471277116388,0 +"745",2015-02-12 03:11:59,20.6,24.84,0,564.5,0.0037230025514827,0 +"746",2015-02-12 03:13:00,20.625,24.6725,0,575.75,0.00370348622028537,0 +"747",2015-02-12 03:14:00,20.6,24.6,0,579,0.00368681829901744,0 +"748",2015-02-12 03:15:00,20.6,24.39,0,579,0.00365516051087822,0 +"749",2015-02-12 03:16:00,20.6333333333333,24.6633333333333,0,573.666666666667,0.00370401565174561,0 +"750",2015-02-12 03:16:59,20.6,25.29,0,579,0.00379085930639592,0 +"751",2015-02-12 03:17:59,20.6,25.33,0,579.666666666667,0.00379689173020495,0 +"752",2015-02-12 03:19:00,20.6,24.795,0,576,0.00371621768535734,0 +"753",2015-02-12 03:20:00,20.6,24.945,0,579,0.0037388344780066,0 +"754",2015-02-12 03:21:00,20.7,24.55,0,579,0.00370216283122505,0 +"755",2015-02-12 03:22:00,20.7,24.6,0,575,0.00370974784825709,0 +"756",2015-02-12 03:23:00,20.6,24.495,0,570,0.00367098900449153,0 +"757",2015-02-12 03:23:59,20.6,24.39,0,578,0.00365516051087822,0 +"758",2015-02-12 03:24:59,20.6,24.495,0,579,0.00367098900449153,0 +"759",2015-02-12 03:26:00,20.6,24.995,0,576.5,0.00374637377222477,0 +"760",2015-02-12 03:27:00,20.6,24.945,0,573.5,0.0037388344780066,0 +"761",2015-02-12 03:28:00,20.6,24.59,0,574.5,0.00368531071264973,0 +"762",2015-02-12 03:29:00,20.6,24.2,0,579,0.00362652051049971,0 +"763",2015-02-12 03:29:59,20.6,24.5566666666667,0,579.333333333333,0.00368028547722659,0 +"764",2015-02-12 03:30:59,20.6,25.29,0,582,0.00379085930639592,0 +"765",2015-02-12 03:32:00,20.6,24.6,0,587,0.00368681829901744,0 +"766",2015-02-12 03:33:00,20.6,25.15,0,598,0.0037697467388971,0 +"767",2015-02-12 03:34:00,20.6,24.6633333333333,0,604.666666666667,0.00369636651472605,0 +"768",2015-02-12 03:35:00,20.6,24.6,0,610,0.00368681829901744,0 +"769",2015-02-12 03:36:00,20.6,24.5233333333333,0,609.333333333333,0.00367526032252387,0 +"770",2015-02-12 03:36:59,20.6,24.2,0,610,0.00362652051049971,0 +"771",2015-02-12 03:38:00,20.6,24.34,0,610,0.00364762341444938,0 +"772",2015-02-12 03:39:00,20.6,24.445,0,613,0.00366345152669711,0 +"773",2015-02-12 03:40:00,20.6,24.245,0,616,0.00363330343151646,0 +"774",2015-02-12 03:40:59,20.625,24.595,0,662.25,0.00369178397099612,0 +"775",2015-02-12 03:42:00,20.65,24.245,0,700.5,0.0036445853863553,0 +"776",2015-02-12 03:42:59,20.6333333333333,24.2666666666667,0,955.666666666667,0.00364409400888887,0 +"777",2015-02-12 03:43:59,20.7,24.29,0,965,0.00366272370686086,0 +"778",2015-02-12 03:45:00,20.6,24.55,0,740,0.00367928043982848,0 +"779",2015-02-12 03:46:00,20.7,24.395,0,626.5,0.00367865044703527,0 +"780",2015-02-12 03:47:00,20.7,24.395,0,592.5,0.00367865044703527,0 +"781",2015-02-12 03:48:00,20.7,24.1,0,588,0.00363390595231418,0 +"782",2015-02-12 03:49:00,20.7,24.3966666666667,0,586.666666666667,0.00367890325897238,0 +"783",2015-02-12 03:49:59,20.7,24.495,0,594,0.00369381952488583,0 +"784",2015-02-12 03:51:00,20.7,24.6,0,591,0.00370974784825709,0 +"785",2015-02-12 03:52:00,20.6,24.445,0,596.5,0.00366345152669711,0 +"786",2015-02-12 03:53:00,20.6,24.34,0,607,0.00364762341444938,0 +"787",2015-02-12 03:53:59,20.6,24.195,0,609.5,0.00362576686168775,0 +"788",2015-02-12 03:55:00,20.6,24.5266666666667,0,599.333333333333,0.00367576283436178,0 +"789",2015-02-12 03:55:59,20.6333333333333,24.8633333333333,0,599,0.0037342325976096,0 +"790",2015-02-12 03:56:59,20.65,24.145,0,602,0.00362946535294305,0 +"791",2015-02-12 03:58:00,20.65,24.05,0,600.5,0.00361510199810381,0 +"792",2015-02-12 03:59:00,20.65,24.645,0,593,0.00370507282904349,0 +"793",2015-02-12 04:00:00,20.7,24.15,0,586.5,0.00364148931455096,0 +"794",2015-02-12 04:01:00,20.7,24.84,0,587.5,0.00374615849001089,0 +"795",2015-02-12 04:01:59,20.6,24.045,0,584,0.00360315824161611,0 +"796",2015-02-12 04:02:59,20.6,24.6,0,593,0.00368681829901744,0 +"797",2015-02-12 04:04:00,20.6,24.42,0,578.25,0.00365968285590265,0 +"798",2015-02-12 04:05:00,20.6,24.35,0,582.5,0.00364913081920754,0 +"799",2015-02-12 04:06:00,20.6,24.8,0,584,0.00371697155210509,0 +"800",2015-02-12 04:07:00,20.6,24.83,0,571.666666666667,0.00372149479073894,0 +"801",2015-02-12 04:08:00,20.6,24.6,0,570,0.00368681829901744,0 +"802",2015-02-12 04:08:59,20.6,24.34,0,577,0.00364762341444938,0 +"803",2015-02-12 04:09:59,20.6,24.9,0,573,0.00373204926853992,0 +"804",2015-02-12 04:11:00,20.6,24.6,0,572,0.00368681829901744,0 +"805",2015-02-12 04:12:00,20.6,24.245,0,568.5,0.00363330343151646,0 +"806",2015-02-12 04:13:00,20.6,24.45,0,568.5,0.00366420526630416,0 +"807",2015-02-12 04:14:00,20.6,24.795,0,564.5,0.00371621768535734,0 +"808",2015-02-12 04:14:59,20.6,24.195,0,567.5,0.00362576686168775,0 +"809",2015-02-12 04:15:59,20.6,24.2,0,569,0.00362652051049971,0 +"810",2015-02-12 04:17:00,20.6,24.1633333333333,0,564.666666666667,0.00362099379471047,0 +"811",2015-02-12 04:18:00,20.6,23.84,0,568.5,0.00357226243666501,0 +"812",2015-02-12 04:19:00,20.6,23.89,0,566,0.00357979771746426,0 +"813",2015-02-12 04:20:00,20.6,24.4966666666667,0,562,0.00367124025687909,0 +"814",2015-02-12 04:21:00,20.65,24.445,0,558.5,0.00367482764578557,0 +"815",2015-02-12 04:21:59,20.6,24.295,0,559,0.00364084018292519,0 +"816",2015-02-12 04:23:00,20.6,24.3,0,560.5,0.00364159386805321,0 +"817",2015-02-12 04:24:00,20.6,24.79,0,555,0.00371546382042611,0 +"818",2015-02-12 04:25:00,20.6,24.245,0,556,0.00363330343151646,0 +"819",2015-02-12 04:25:59,20.6,24.495,0,559,0.00367098900449153,0 +"820",2015-02-12 04:27:00,20.6,23.895,0,558,0.00358055125552842,0 +"821",2015-02-12 04:27:59,20.65,23.79,0,557,0.00357579513607266,0 +"822",2015-02-12 04:28:59,20.6,23.745,0,561,0.00355794590324754,0 +"823",2015-02-12 04:30:00,20.7,23.7,0,557,0.00357324567183612,0 +"824",2015-02-12 04:31:00,20.7,23.7,0,558,0.00357324567183612,0 +"825",2015-02-12 04:32:00,20.6,24.35,0,548,0.00364913081920754,0 +"826",2015-02-12 04:33:00,20.6,23.945,0,558,0.00358808673601481,0 +"827",2015-02-12 04:34:00,20.6,24.045,0,552.5,0.00360315824161611,0 +"828",2015-02-12 04:34:59,20.6,23.9975,0,554.25,0.00359599918590877,0 +"829",2015-02-12 04:36:00,20.6,23.6,0,556,0.00353609561556703,0 +"830",2015-02-12 04:37:00,20.6,24,0,556,0.00359637597422955,0 +"831",2015-02-12 04:38:00,20.65,24.25,0,550,0.00364534140721031,0 +"832",2015-02-12 04:38:59,20.6,24.39,0,547,0.00365516051087822,0 +"833",2015-02-12 04:40:00,20.6,24.245,0,551,0.00363330343151646,0 +"834",2015-02-12 04:40:59,20.6,24.16,0,553.333333333333,0.00362049137084425,0 +"835",2015-02-12 04:41:59,20.6,23.995,0,553.5,0.00359562239804185,0 +"836",2015-02-12 04:43:00,20.6,23.89,0,554,0.00357979771746426,0 +"837",2015-02-12 04:44:00,20.6,23.7,0,556.5,0.00355116461612913,0 +"838",2015-02-12 04:45:00,20.6,23.9333333333333,0,560.333333333333,0.00358632844099709,0 +"839",2015-02-12 04:46:00,20.6,23.7,0,556,0.00355116461612913,0 +"840",2015-02-12 04:46:59,20.6,23.8,0,560.5,0.00356623434272527,0 +"841",2015-02-12 04:47:59,20.6,23.9,0,558,0.00358130479540791,0 +"842",2015-02-12 04:49:00,20.6,23.745,0,556.5,0.00355794590324754,0 +"843",2015-02-12 04:50:00,20.6,23.89,0,560,0.00357979771746426,0 +"844",2015-02-12 04:51:00,20.6,24.39,0,557,0.00365516051087822,0 +"845",2015-02-12 04:52:00,20.6,23.7,0,555,0.00355116461612913,0 +"846",2015-02-12 04:53:00,20.6,23.55,0,565,0.00352856138753235,0 +"847",2015-02-12 04:53:59,20.6,23.995,0,559.5,0.00359562239804185,0 +"848",2015-02-12 04:54:59,20.6,24.79,0,556,0.00371546382042611,0 +"849",2015-02-12 04:56:00,20.6,23.65,0,556.5,0.0035436300250971,0 +"850",2015-02-12 04:57:00,20.6,24.1966666666667,0,558,0.00362601807775665,0 +"851",2015-02-12 04:58:00,20.6,24.2,0,560,0.00362652051049971,0 +"852",2015-02-12 04:59:00,20.6,24.35,0,566,0.00364913081920754,0 +"853",2015-02-12 04:59:59,20.6,23.995,0,559,0.00359562239804185,0 +"854",2015-02-12 05:00:59,20.6,24.045,0,560.333333333333,0.00360315824161611,0 +"855",2015-02-12 05:02:00,20.6,23.795,0,560,0.00356548083915134,0 +"856",2015-02-12 05:03:00,20.6,23.5,0,559,0.0035210273409865,0 +"857",2015-02-12 05:04:00,20.55,23.39,0,559.5,0.00349360315378382,0 +"858",2015-02-12 05:05:00,20.6,23.545,0,560,0.00352780797471087,0 +"859",2015-02-12 05:06:00,20.6,23.945,0,563.5,0.00358808673601481,0 +"860",2015-02-12 05:06:59,20.55,24.4,0,563.5,0.00364534401869875,0 +"861",2015-02-12 05:08:00,20.5333333333333,24.03,0,561,0.00358603726119597,0 +"862",2015-02-12 05:09:00,20.55,24.195,0,561.5,0.00361453917546626,0 +"863",2015-02-12 05:10:00,20.6,23.945,0,556.5,0.00358808673601481,0 +"864",2015-02-12 05:10:59,20.55,24.245,0,563.5,0.00362205227215379,0 +"865",2015-02-12 05:12:00,20.575,23.6225,0,560.25,0.00353400283410704,0 +"866",2015-02-12 05:12:59,20.6,23.6,0,556,0.00353609561556703,0 +"867",2015-02-12 05:13:59,20.5,23.39,0,557.5,0.00348278284376229,0 +"868",2015-02-12 05:15:00,20.5,23.65,0,561,0.00352171617185244,0 +"869",2015-02-12 05:16:00,20.55,24.045,0,566.5,0.00359200096806221,0 +"870",2015-02-12 05:17:00,20.55,23.85,0,566,0.00356270372606842,0 +"871",2015-02-12 05:18:00,20.5,23.795,0,565,0.00354343109476598,0 +"872",2015-02-12 05:19:00,20.5,24.6,0,569,0.00366401378112657,0 +"873",2015-02-12 05:19:59,20.5,23.995,0,569,0.00357338518662548,0 +"874",2015-02-12 05:21:00,20.5,23.55,0,567.5,0.0035067412413192,0 +"875",2015-02-12 05:22:00,20.6,23.945,0,571,0.00358808673601481,0 +"876",2015-02-12 05:23:00,20.5333333333333,23.6966666666667,0,568.333333333333,0.0035360105787096,0 +"877",2015-02-12 05:23:59,20.55,23.945,0,578.5,0.00357697639860997,0 +"878",2015-02-12 05:25:00,20.5333333333333,23.7966666666667,0,581.666666666667,0.00355101774332632,0 +"879",2015-02-12 05:25:59,20.5,24.1266666666667,0,580,0.00359310652974633,0 +"880",2015-02-12 05:26:59,20.5,23.5,0,581,0.00349925404492317,0 +"881",2015-02-12 05:28:00,20.5,23.8666666666667,0,582.666666666667,0.00355416431455843,0 +"882",2015-02-12 05:29:00,20.5,23.6,0,583.5,0.00351422861696014,0 +"883",2015-02-12 05:30:00,20.5,23.34,0,586,0.00347529622090674,0 +"884",2015-02-12 05:31:00,20.5,23.745,0,585,0.00353594302000835,0 +"885",2015-02-12 05:31:59,20.5,23.945,0,577,0.00356589639472338,0 +"886",2015-02-12 05:32:59,20.55,23.65,0,577.5,0.00353265812309873,0 +"887",2015-02-12 05:34:00,20.5,23.7666666666667,0,580.666666666667,0.00353918783039257,0 +"888",2015-02-12 05:35:00,20.5,24.6,0,585,0.00366401378112657,0 +"889",2015-02-12 05:36:00,20.55,23.795,0,577.5,0.00355444089752727,0 +"890",2015-02-12 05:37:00,20.5,23.29,0,583,0.00346780977726908,0 +"891",2015-02-12 05:38:00,20.5,23.65,0,583,0.00352171617185244,0 +"892",2015-02-12 05:38:59,20.5,24.0333333333333,0,587.25,0.00357912671517753,0 +"893",2015-02-12 05:39:59,20.5,23.95,0,587,0.00356664526584517,0 +"894",2015-02-12 05:41:00,20.5,23.5,0,586,0.00349925404492317,0 +"895",2015-02-12 05:42:00,20.5,23.59,0,584.5,0.00351273112749205,0 +"896",2015-02-12 05:43:00,20.5,23.79,0,587,0.00354268227922288,0 +"897",2015-02-12 05:44:00,20.5,23.64,0,581,0.00352021864653357,0 +"898",2015-02-12 05:44:59,20.5,23.6966666666667,0,580.333333333333,0.00352870471814882,0 +"899",2015-02-12 05:45:59,20.5,23.5933333333333,0,581.5,0.00351323028985141,0 +"900",2015-02-12 05:47:00,20.5,23.6,0,575.5,0.00351422861696014,0 +"901",2015-02-12 05:48:00,20.5,23.96,0,568.666666666667,0.00356814301346766,0 +"902",2015-02-12 05:49:00,20.5,23.945,0,574,0.00356589639472338,0 +"903",2015-02-12 05:50:00,20.5,23.545,0,579,0.00350599251361368,0 +"904",2015-02-12 05:51:00,20.55,23.64,0,578.5,0.00353115591871187,0 +"905",2015-02-12 05:51:59,20.5,23.44,0,581,0.00349026964584216,0 +"906",2015-02-12 05:53:00,20.5,23.7,0,581.5,0.00352920390600254,0 +"907",2015-02-12 05:54:00,20.5,23.39,0,587,0.00348278284376229,0 +"908",2015-02-12 05:55:00,20.5,23.59,0,584,0.00351273112749205,0 +"909",2015-02-12 05:55:59,20.5,23.1633333333333,0,588,0.00344884492210975,0 +"910",2015-02-12 05:57:00,20.5,23.7,0,588,0.00352920390600254,0 +"911",2015-02-12 05:57:59,20.5,23.9,0,587,0.00355915663530956,0 +"912",2015-02-12 05:58:59,20.5,23.35,0,588,0.00347679353114021,0 +"913",2015-02-12 06:00:00,20.5,23.2,0,588,0.00345433463032982,0 +"914",2015-02-12 06:01:00,20.5,23.05,0,587.5,0.00343187734231823,0 +"915",2015-02-12 06:02:00,20.5,23.0666666666667,0,586.5,0.00343437251690276,0 +"916",2015-02-12 06:03:00,20.5333333333333,23.1966666666667,0,576.5,0.0034609855551278,0 +"917",2015-02-12 06:04:00,20.5,23.34,0,576.5,0.00347529622090674,0 +"918",2015-02-12 06:04:59,20.5,23.09,0,580,0.00343786579476859,0 +"919",2015-02-12 06:06:00,20.5,23.14,0,584.5,0.00344535152159906,0 +"920",2015-02-12 06:07:00,20.5,23.0666666666667,0,585.333333333333,0.00343437251690276,0 +"921",2015-02-12 06:08:00,20.5,22.89,0,584,0.0034079246792395,0 +"922",2015-02-12 06:08:59,20.5,23.3,0,582.5,0.00346930705165949,0 +"923",2015-02-12 06:10:00,20.5,23.295,0,585,0.00346855841356822,0 +"924",2015-02-12 06:10:59,20.5,23.695,0,586.333333333333,0.00352845512452074,0 +"925",2015-02-12 06:11:59,20.5,23.35,0,587,0.00347679353114021,0 +"926",2015-02-12 06:13:00,20.5,22.945,0,594.5,0.00341615820023239,0 +"927",2015-02-12 06:14:00,20.445,22.945,0,594,0.00340451825123681,0 +"928",2015-02-12 06:15:00,20.5,23.445,0,596.5,0.00349101833590773,0 +"929",2015-02-12 06:16:00,20.5,23.1966666666667,0,599,0.00345383556196399,0 +"930",2015-02-12 06:16:59,20.5,23.5,0,604,0.00349925404492317,0 +"931",2015-02-12 06:17:59,20.5,22.79,0,598,0.00339295519646057,0 +"932",2015-02-12 06:19:00,20.5,22.8933333333333,0,600.333333333333,0.00340842367434065,0 +"933",2015-02-12 06:20:00,20.5,22.7,0,609,0.00337948327464413,0 +"934",2015-02-12 06:21:00,20.5,22.79,0,614.666666666667,0.00339295519646057,0 +"935",2015-02-12 06:22:00,20.5,22.7,0,616,0.00337948327464413,0 +"936",2015-02-12 06:23:00,20.5,22.7,0,610,0.00337948327464413,0 +"937",2015-02-12 06:23:59,20.5,22.7,0,607,0.00337948327464413,0 +"938",2015-02-12 06:24:59,20.5,22.6,0,607.5,0.00336451515333929,0 +"939",2015-02-12 06:26:00,20.5,22.6,0,608,0.00336451515333929,0 +"940",2015-02-12 06:27:00,20.5,22.6,0,603,0.00336451515333929,0 +"941",2015-02-12 06:28:00,20.6,22.7,0,602.5,0.00340050727338431,0 +"942",2015-02-12 06:29:00,20.5,22.7,0,596,0.00337948327464413,0 +"943",2015-02-12 06:29:59,20.5,22.55,0,602.5,0.00335703136137409,0 +"944",2015-02-12 06:30:59,20.55,22.65,0,612,0.00338247339031518,0 +"945",2015-02-12 06:32:00,20.5,22.6,0,609,0.00336451515333929,0 +"946",2015-02-12 06:33:00,20.6,22.6,0,604,0.0033854455302777,0 +"947",2015-02-12 06:34:00,20.6,22.5,0,606,0.00337038451262827,0 +"948",2015-02-12 06:35:00,20.5,22.55,0,608,0.00335703136137409,0 +"949",2015-02-12 06:36:00,20.6,22.5,0,611.5,0.00337038451262827,0 +"950",2015-02-12 06:36:59,20.6,22.6,0,612,0.0033854455302777,0 +"951",2015-02-12 06:38:00,20.6,22.5,0,615,0.00337038451262827,0 +"952",2015-02-12 06:39:00,20.6,22.55,0,621.5,0.00337791493077412,0 +"953",2015-02-12 06:40:00,20.6,22.6,0,626.5,0.0033854455302777,0 +"954",2015-02-12 06:40:59,20.6,22.55,0,626,0.00337791493077412,0 +"955",2015-02-12 06:42:00,20.6,22.445,0,630,0.00336210126212821,0 +"956",2015-02-12 06:42:59,20.6,22.5,0,630.5,0.00337038451262827,0 +"957",2015-02-12 06:43:59,20.6,22.5,0,628,0.00337038451262827,0 +"958",2015-02-12 06:45:00,20.6,22.495,0,627.666666666667,0.00336963148078811,0 +"959",2015-02-12 06:46:00,20.6,22.445,0,629.5,0.00336210126212821,0 +"960",2015-02-12 06:47:00,20.6,22.495,0,634,0.00336963148078811,0 +"961",2015-02-12 06:48:00,20.6,22.39,0,627.5,0.00335381823105437,0 +"962",2015-02-12 06:49:00,20.6,22.495,0,632,0.00336963148078811,0 +"963",2015-02-12 06:49:59,20.6,22.6,0,630,0.0033854455302777,0 +"964",2015-02-12 06:51:00,20.6,22.445,0,636,0.00336210126212821,0 +"965",2015-02-12 06:52:00,20.6,22.65,0,631.5,0.00339297631114558,0 +"966",2015-02-12 06:53:00,20.6,22.6,0,634,0.0033854455302777,0 +"967",2015-02-12 06:53:59,20.6,22.5333333333333,0,635,0.00337540477124163,0 +"968",2015-02-12 06:55:00,20.6,22.6,0,643,0.0033854455302777,0 +"969",2015-02-12 06:55:59,20.5666666666667,22.6333333333333,0,642.666666666667,0.00338346610703465,0 +"970",2015-02-12 06:56:59,20.5,22.7,0,638,0.00337948327464413,0 +"971",2015-02-12 06:58:00,20.55,22.55,0,635.5,0.00336745888332113,0 +"972",2015-02-12 06:59:00,20.6,22.85,0,634.5,0.00342310124839109,0 +"973",2015-02-12 07:00:00,20.55,22.745,0,646,0.00339673783977272,0 +"974",2015-02-12 07:01:00,20.5,22.9,0,648.5,0.00340942166693174,0 +"975",2015-02-12 07:01:59,20.5,22.895,0,651,0.00340867317218982,0 +"976",2015-02-12 07:02:59,20.5,22.7,0,657,0.00337948327464413,0 +"977",2015-02-12 07:04:00,20.5,22.5,0,655,0.00334954774852514,0 +"978",2015-02-12 07:05:00,20.5,22.5,0,660,0.00334954774852514,0 +"979",2015-02-12 07:06:00,20.55,22.85,0,662,0.00341250456731552,0 +"980",2015-02-12 07:07:00,20.5,22.945,0,667,0.00341615820023239,0 +"981",2015-02-12 07:08:00,20.5,22.7,0,664.666666666667,0.00337948327464413,0 +"982",2015-02-12 07:08:59,20.5,22.7,0,665,0.00337948327464413,0 +"983",2015-02-12 07:09:59,20.5,22.7666666666667,0,668.666666666667,0.0033894624202565,0 +"984",2015-02-12 07:11:00,20.5,22.7,0,667,0.00337948327464413,0 +"985",2015-02-12 07:12:00,20.5,22.7,0,668,0.00337948327464413,0 +"986",2015-02-12 07:13:00,20.525,22.7925,0,675.666666666667,0.00339859626596909,0 +"987",2015-02-12 07:14:00,20.5,22.79,0,699.5,0.00339295519646057,0 +"988",2015-02-12 07:14:59,20.5,23.195,0,715.5,0.00345358602807975,0 +"989",2015-02-12 07:15:59,20.5,22.945,0,725.5,0.00341615820023239,0 +"990",2015-02-12 07:17:00,20.5,22.9,0,734.5,0.00340942166693174,0 +"991",2015-02-12 07:18:00,20.5,23.1966666666667,0,741,0.00345383556196399,0 +"992",2015-02-12 07:19:00,20.5,23.15,0,735,0.003446848688468,0 +"993",2015-02-12 07:20:00,20.5,22.89,0,735,0.0034079246792395,0 +"994",2015-02-12 07:21:00,20.5,22.745,0,744.5,0.00338621916300012,0 +"995",2015-02-12 07:21:59,20.5,22.6,0,741.5,0.00336451515333929,0 +"996",2015-02-12 07:23:00,20.5,22.895,0,733,0.00340867317218982,0 +"997",2015-02-12 07:24:00,20.5,22.445,0,734.5,0.00334131598126289,0 +"998",2015-02-12 07:25:00,20.5,22.29,0,733,0.00331811853036384,0 +"999",2015-02-12 07:25:59,20.55,22.29,0,741,0.00332842453898209,0 +"1000",2015-02-12 07:27:00,20.55,22.29,0,745,0.00332842453898209,0 +"1001",2015-02-12 07:27:59,20.6,22.645,0,733,0.00339222322489722,0 +"1002",2015-02-12 07:28:59,20.55,22.34,0,714,0.00333593076521459,0 +"1003",2015-02-12 07:30:00,20.6,22.29,0,705.5,0.00333875873669441,0 +"1004",2015-02-12 07:31:00,20.6,22.545,0,701,0.00337716188079854,0 +"1005",2015-02-12 07:32:00,20.6,22.29,0,697,0.00333875873669441,0 +"1006",2015-02-12 07:33:00,20.55,22.29,0,693.5,0.00332842453898209,0 +"1007",2015-02-12 07:34:00,20.6,22.495,0,697.5,0.00336963148078811,0 +"1008",2015-02-12 07:34:59,20.5333333333333,22.6666666666667,0,701.333333333333,0.00338147867629852,0 +"1009",2015-02-12 07:36:00,20.6,22.7,0,703,0.00340050727338431,0 +"1010",2015-02-12 07:37:00,20.6,22.39,0,700,0.00335381823105437,0 +"1011",2015-02-12 07:38:00,20.55,22.7,0,696.5,0.00338998091417899,0 +"1012",2015-02-12 07:38:59,20.5,22.645,0,695,0.00337125071925767,0 +"1013",2015-02-12 07:40:00,20.55,22.895,0,702.5,0.00341926197962702,0 +"1014",2015-02-12 07:40:59,20.55,22.445,0,706,0.00335169442688258,0 +"1015",2015-02-12 07:41:59,20.5,23.03,0,714.333333333333,0.0034288831590966,0 +"1016",2015-02-12 07:43:00,20.5,22.795,0,720,0.00339370365358012,0 +"1017",2015-02-12 07:44:00,20.55,22.5,0,715.5,0.00335995190017792,0 +"1018",2015-02-12 07:45:00,20.5,22.39,0,719,0.00333308443071495,0 +"1019",2015-02-12 07:46:00,20.5,22.39,0,720,0.00333308443071495,0 +"1020",2015-02-12 07:46:59,20.5,22.745,0,724.5,0.00338621916300012,0 +"1021",2015-02-12 07:47:59,20.5,22.8,0,723,0.00339445211249114,0 +"1022",2015-02-12 07:49:00,20.5,22.5,0,766.5,0.00334954774852514,0 +"1023",2015-02-12 07:50:00,20.5,22.445,0,815,0.00334131598126289,0 +"1024",2015-02-12 07:51:00,20.5,22.79,0,843.5,0.00339295519646057,0 +"1025",2015-02-12 07:52:00,20.5,23.1,0,844,0.00343936292579962,0 +"1026",2015-02-12 07:53:00,20.5,22.545,0,820.5,0.00335628299202907,0 +"1027",2015-02-12 07:53:59,20.5,22.445,0,793.5,0.00334131598126289,0 +"1028",2015-02-12 07:54:59,20.5,22.29,0,762,0.00331811853036384,0 +"1029",2015-02-12 07:56:00,20.5,22.29,0,764,0.00331811853036384,0 +"1030",2015-02-12 07:57:00,20.5,22.29,0,787.5,0.00331811853036384,0 +"1031",2015-02-12 07:58:00,20.5,22.29,0,800.5,0.00331811853036384,0 +"1032",2015-02-12 07:59:00,20.5,22.3233333333333,0,796.333333333333,0.00332310708421931,0 +"1033",2015-02-12 07:59:59,20.5,22.29,0,805,0.00331811853036384,0 +"1034",2015-02-12 08:00:59,20.5,22.245,0,820,0.00331138410891199,0 +"1035",2015-02-12 08:02:00,20.5,22.2,0,832,0.00330464983251252,0 +"1036",2015-02-12 08:03:00,20.5,22.3966666666667,9.33333333333333,831,0.00333408218287584,0 +"1037",2015-02-12 08:04:00,20.5,22.35,14,819,0.00332709798461147,0 +"1038",2015-02-12 08:05:00,20.5,22.245,14,820,0.00331138410891199,0 +"1039",2015-02-12 08:06:00,20.5,22.1,14,816,0.0032896852931468,0 +"1040",2015-02-12 08:06:59,20.5,22.1,14,817,0.0032896852931468,0 +"1041",2015-02-12 08:08:00,20.5,22.15,14,831,0.00329716747329726,0 +"1042",2015-02-12 08:09:00,20.55,22,14,836,0.00328489198017216,0 +"1043",2015-02-12 08:10:00,20.55,22.1475,7,855.5,0.00330703278281957,0 +"1044",2015-02-12 08:10:59,20.5,22.0666666666667,14,858.666666666667,0.00328469727252378,0 +"1045",2015-02-12 08:12:00,20.6,22,14,849,0.00329509030440446,0 +"1046",2015-02-12 08:12:59,20.55,22.075,7,865.25,0.00329614981947961,0 +"1047",2015-02-12 08:13:59,20.5666666666667,22.1333333333333,6.66666666666667,865.333333333333,0.00330832334749752,0 +"1048",2015-02-12 08:15:00,20.6,21.945,6,909,0.00328680904836761,0 +"1049",2015-02-12 08:16:00,20.6,21.89,6,913,0.00327852801167774,0 +"1050",2015-02-12 08:17:00,20.6,21.97,6,926.75,0.00329057322846479,0 +"1051",2015-02-12 08:18:00,20.6,22,6,1099,0.00329509030440446,0 +"1052",2015-02-12 08:19:00,20.6,22.13,6,1422.33333333333,0.00331466505430967,0 +"1053",2015-02-12 08:19:59,20.6,22.5175,6,917,0.00337302013835028,0 +"1054",2015-02-12 08:21:00,20.6,22.05,9.6,1003.4,0.00330261890933316,0 +"1055",2015-02-12 08:22:00,20.6,21.9266666666667,24,1051.33333333333,0.00328404867843287,0 +"1056",2015-02-12 08:23:00,20.575,21.995,24,836.25,0.00328923598288829,0 +"1057",2015-02-12 08:23:59,20.6,21.945,14,819.5,0.00328680904836761,0 +"1058",2015-02-12 08:25:00,20.6,22.245,14,781.5,0.00333198220086296,0 +"1059",2015-02-12 08:25:59,20.5666666666667,22.0966666666667,10,914.333333333333,0.0033028135891219,0 +"1060",2015-02-12 08:26:59,20.6,22.1975,10,1018,0.00332482935015156,0 +"1061",2015-02-12 08:28:00,20.6,22.5,9,805.5,0.00337038451262827,0 +"1062",2015-02-12 08:29:00,20.6,22.145,9,673,0.00331692375816323,0 +"1063",2015-02-12 08:30:00,20.6,22.05,9,659.5,0.00330261890933316,0 +"1064",2015-02-12 08:31:00,20.6,22.195,358,647,0.00332445288885748,1 +"1065",2015-02-12 08:31:59,20.6,22.0225,437.5,649,0.00329847815418788,1 +"1066",2015-02-12 08:32:59,20.6,21.865,454,652.5,0.00327476397660048,0 +"1067",2015-02-12 08:34:00,20.6,22.2,442.75,681.75,0.00332520581189891,0 +"1068",2015-02-12 08:35:00,20.6,22.26,444,702.333333333333,0.00333424102982127,0 +"1069",2015-02-12 08:36:00,20.6333333333333,22.26,444,707,0.00334113679495563,0 +"1070",2015-02-12 08:37:00,20.625,22.1,440,698,0.00331528078129294,1 +"1071",2015-02-12 08:38:00,20.6666666666667,22.1666666666667,437,692,0.00333393195183134,1 +"1072",2015-02-12 08:38:59,20.7,22.1725,428.5,690.5,0.00334170741483424,1 +"1073",2015-02-12 08:39:59,20.6666666666667,22.23,418,700.333333333333,0.00334350867532442,1 +"1074",2015-02-12 08:41:00,20.7,22.2225,418,708.5,0.00334928369515521,1 +"1075",2015-02-12 08:42:00,20.7,22.3233333333333,418,717,0.00336456308556326,1 +"1076",2015-02-12 08:43:00,20.7,22.3566666666667,428.666666666667,723,0.00336961428792787,1 +"1077",2015-02-12 08:44:00,20.7,22.7225,434,727.25,0.00342505659647225,1 +"1078",2015-02-12 08:44:59,20.7,22.525,434,735.5,0.00339512410645082,1 +"1079",2015-02-12 08:45:59,20.7,22.695,423.5,734,0.00342088860970383,1 +"1080",2015-02-12 08:47:00,20.745,22.625,438.5,734,0.00341979786753829,1 +"1081",2015-02-12 08:48:00,20.745,22.65,428,732,0.00342359744879437,1 +"1082",2015-02-12 08:49:00,20.79,22.6,438,732,0.00342552949876246,1 +"1083",2015-02-12 08:50:00,20.8566666666667,22.7266666666667,443,736,0.00345907853643754,1 +"1084",2015-02-12 08:51:00,20.89,22.625,446.75,725.5,0.0034506277695371,1 +"1085",2015-02-12 08:51:59,20.9175,22.65,443.75,731.5,0.00346034294965435,1 +"1086",2015-02-12 08:53:00,21,22.6966666666667,447.333333333333,735.333333333333,0.00348524546839607,1 +"1087",2015-02-12 08:54:00,21,22.82,449.5,736,0.00350429093730489,1 +"1088",2015-02-12 08:55:00,21.05,23.2925,435.75,811.75,0.00358833912426706,1 +"1089",2015-02-12 08:55:59,21.1,23.23,449.666666666667,827.666666666667,0.00358972802420049,1 +"1090",2015-02-12 08:57:00,21.2,23.1,441.5,776,0.00359163412634295,1 +"1091",2015-02-12 08:57:59,21.15,23.245,454.75,786.75,0.00360316955539665,1 +"1092",2015-02-12 08:58:59,21.2,23.4725,444,818.5,0.00364989102690522,1 +"1093",2015-02-12 09:00:00,21.245,23.55,460,844,0.00367219876113733,1 +"1094",2015-02-12 09:01:00,21.2675,23.675,457.5,857.75,0.00369693561433924,1 +"1095",2015-02-12 09:02:00,21.34,23.745,459.5,892,0.00372455277288432,1 +"1096",2015-02-12 09:03:00,21.34,23.79,469.75,902,0.00373165365352031,1 +"1097",2015-02-12 09:04:00,21.39,23.89,475,877.5,0.00375900619421496,1 +"1098",2015-02-12 09:04:59,21.4175,23.9725,472.5,868.75,0.00377846642990952,1 +"1099",2015-02-12 09:06:00,21.445,24.05,466,868.5,0.00379718714692567,1 +"1100",2015-02-12 09:07:00,21.5,24.1,476.25,903,0.00381804773403658,1 +"1101",2015-02-12 09:08:00,21.55,24.2,474,928,0.00384581447627792,1 +"1102",2015-02-12 09:08:59,21.575,24.2,494,939.25,0.00385173980747275,1 +"1103",2015-02-12 09:10:00,21.625,24.2925,481,947.5,0.0038784746453341,1 +"1104",2015-02-12 09:10:59,21.7,24.39,497,965.666666666667,0.00391215347369415,1 +"1105",2015-02-12 09:11:59,21.7,24.39,494,965,0.00391215347369415,1 +"1106",2015-02-12 09:13:00,21.7225,24.39,502.25,970.5,0.00391757221226468,1 +"1107",2015-02-12 09:14:00,21.79,24.46,512.666666666667,980.333333333333,0.00394523006478022,1 +"1108",2015-02-12 09:15:00,21.815,24.55,508,991.5,0.00396592973218369,1 +"1109",2015-02-12 09:16:00,21.84,24.55,502,1000,0.00397202885752698,1 +"1110",2015-02-12 09:16:59,21.89,24.6,514,1001.33333333333,0.0039924185646517,1 +"1111",2015-02-12 09:17:59,21.89,24.6,508,1006.25,0.0039924185646517,1 +"1112",2015-02-12 09:19:00,22,24.65,526,1017.5,0.00402770433938488,1 +"1113",2015-02-12 09:20:00,22,24.7,529,1026.5,0.00403592713577008,1 +"1114",2015-02-12 09:21:00,22,24.7,524.333333333333,1032.66666666667,0.00403592713577008,1 +"1115",2015-02-12 09:22:00,22.1,24.79,515,1040,0.00407566538915702,1 +"1116",2015-02-12 09:23:00,22.1,24.83,545,1055,0.0040822848560854,1 +"1117",2015-02-12 09:23:59,22.1,24.79,525.333333333333,1070,0.00407566538915702,1 +"1118",2015-02-12 09:24:59,22.14,24.85,534.5,1090.25,0.0040956316866024,1 +"1119",2015-02-12 09:26:00,22.2,24.89,545.25,1095.5,0.00411738867138392,1 +"1120",2015-02-12 09:27:00,22.2225,24.945,537,1103.75,0.0041322430488045,1 +"1121",2015-02-12 09:28:00,22.26,25,552,1108,0.00415094421556813,1 +"1122",2015-02-12 09:29:00,22.29,25.025,549,1111.75,0.00416276815932944,1 +"1123",2015-02-12 09:29:59,22.315,25.075,538.5,1129,0.00417753460041575,1 +"1124",2015-02-12 09:30:59,22.34,25.075,552,1144.25,0.00418393668334608,1 +"1125",2015-02-12 09:32:00,22.39,25.125,552,1142,0.00420519180372051,1 +"1126",2015-02-12 09:33:00,22.3925,25.15,565.5,1141,0.00421004875391816,1 +"1127",2015-02-12 09:34:00,22.4175,25.125,566.25,1129,0.00421227742956203,1 +"1128",2015-02-12 09:35:00,22.5,25.2,570.333333333333,1125.33333333333,0.004246321370009,1 +"1129",2015-02-12 09:36:00,22.5,25.2,576,1131,0.004246321370009,1 +"1130",2015-02-12 09:36:59,22.5,25.2,577.75,1135.75,0.004246321370009,1 +"1131",2015-02-12 09:38:00,22.6,25.2,583,1144,0.0042723699287058,1 +"1132",2015-02-12 09:39:00,22.6,25.2,583,1143.5,0.0042723699287058,1 +"1133",2015-02-12 09:40:00,22.6,25.2,590.75,1149.25,0.0042723699287058,1 +"1134",2015-02-12 09:40:59,22.6,25.2,589,1152.5,0.0042723699287058,1 +"1135",2015-02-12 09:42:00,22.675,25.2675,592.5,1167.5,0.00430357464398119,1 +"1136",2015-02-12 09:42:59,22.7,25.29,592.5,1166,0.00431401770708798,1 +"1137",2015-02-12 09:43:59,22.7,25.29,589.25,1178.5,0.00431401770708798,1 +"1138",2015-02-12 09:45:00,22.7,25.29,756,1195,0.00431401770708798,1 +"1139",2015-02-12 09:46:00,22.772,25.29,1380,1202.5,0.00433303012057448,1 +"1140",2015-02-12 09:47:00,22.79,25.29,1581,1211.5,0.00433779474842324,1 +"1141",2015-02-12 09:48:00,22.79,25.1,1010.5,1215.5,0.00430497998704502,1 +"1142",2015-02-12 09:49:00,22.89,24.6,844,1192,0.00424446177297652,1 +"1143",2015-02-12 09:49:59,22.865,24.6475,621,1139.75,0.00424623273576192,1 +"1144",2015-02-12 09:51:00,22.8566666666667,24.4966666666667,615,1119.66666666667,0.0042179261985631,1 +"1145",2015-02-12 09:52:00,22.89,24.295,624,1105,0.00419148272738827,1 +"1146",2015-02-12 09:53:00,22.89,24.245,625.75,1040.25,0.00418279849312655,1 +"1147",2015-02-12 09:53:59,22.89,24.175,628.5,1035.5,0.00417064096981687,1 +"1148",2015-02-12 09:55:00,22.89,24.1666666666667,633,1023,0.00416919367705875,1 +"1149",2015-02-12 09:55:59,22.89,24.05,633,1016.5,0.00414893228091113,1 +"1150",2015-02-12 09:56:59,22.89,23.89,637.5,993.25,0.00412114735545412,1 +"1151",2015-02-12 09:58:00,22.89,23.7925,637.5,972.75,0.00410421712562811,1 +"1152",2015-02-12 09:59:00,22.945,23.55,651,932.5,0.00407575621461908,1 +"1153",2015-02-12 10:00:00,22.9266666666667,23.6333333333333,657,913.333333333333,0.0040857047277189,1 +"1154",2015-02-12 10:01:00,22.9175,23.4725,645.5,906.5,0.00405545173291771,1 +"1155",2015-02-12 10:01:59,22.9175,23.5,641,898.5,0.00406023404944669,1 +"1156",2015-02-12 10:02:59,22.9725,23.525,658.75,903.333333333333,0.00407823078020331,1 +"1157",2015-02-12 10:04:00,23,23.5,655.666666666667,899.75,0.00408070077940134,1 +"1158",2015-02-12 10:05:00,23,23.2925,670.5,889,0.00404443477046117,1 +"1159",2015-02-12 10:06:00,23,23.365,667.75,883,0.00405710554905269,1 +"1160",2015-02-12 10:07:00,23.05,23.295,664,891,0.00405720993850829,1 +"1161",2015-02-12 10:08:00,23.1,23.39,682,892,0.00408628663503333,1 +"1162",2015-02-12 10:08:59,23.1,23.2,673,845.5,0.00405287691492905,1 +"1163",2015-02-12 10:09:59,23.1,23.2,673,847.75,0.00405287691492905,1 +"1164",2015-02-12 10:11:00,23.2,23.15,684.5,846,0.00406877132764041,1 +"1165",2015-02-12 10:12:00,23.175,23.1,683.5,842,0.00405375578283534,1 +"1166",2015-02-12 10:13:00,23.26,23.0666666666667,700,832.666666666667,0.00406885034428994,1 +"1167",2015-02-12 10:14:00,23.315,23.0475,697,827.5,0.00407906357298038,1 +"1168",2015-02-12 10:14:59,23.4266666666667,22.9266666666667,708.333333333333,829.333333333333,0.00408515956998715,1 +"1169",2015-02-12 10:15:59,23.4633333333333,22.8566666666667,706.333333333333,832,0.00408168256254555,1 +"1170",2015-02-12 10:17:00,23.525,22.815,718.25,834.75,0.0040894717607988,1 +"1171",2015-02-12 10:18:00,23.525,22.6475,720,832.25,0.00405925230735139,1 +"1172",2015-02-12 10:19:00,23.575,22.6,730,823.666666666667,0.00406298964262971,1 +"1173",2015-02-12 10:20:00,23.5333333333333,22.4966666666667,723.5,816.5,0.00403408157289805,1 +"1174",2015-02-12 10:21:00,23.55,22.5225,728,803,0.00404283015779455,1 +"1175",2015-02-12 10:21:59,23.55,22.5,745.5,799,0.00403876514178216,1 +"1176",2015-02-12 10:23:00,23.5,22.575,733.75,794,0.00404003909850806,1 +"1177",2015-02-12 10:24:00,23.525,22.6,732.25,785.5,0.00405068314252282,1 +"1178",2015-02-12 10:25:00,23.5,22.7,725,790,0.00406255530210177,1 +"1179",2015-02-12 10:25:59,23.55,22.65,732.5,798.5,0.00406586624571628,1 +"1180",2015-02-12 10:27:00,23.5,22.6333333333333,743,795.333333333333,0.00405054645863392,1 +"1181",2015-02-12 10:27:59,23.6,22.7,729.5,789.75,0.00408727865537402,1 +"1182",2015-02-12 10:28:59,23.6,22.6333333333333,734.666666666667,796,0.00407519625439235,1 +"1183",2015-02-12 10:30:00,23.6,22.55,761,792,0.00406009390893845,1 +"1184",2015-02-12 10:31:00,23.6,22.65,761,794,0.00407821681091828,1 +"1185",2015-02-12 10:32:00,23.6,22.55,751,803.25,0.00406009390893845,1 +"1186",2015-02-12 10:33:00,23.65,22.55,761,806,0.00407242210729454,1 +"1187",2015-02-12 10:34:00,23.625,22.5725,746.5,812.25,0.00407033768259236,1 +"1188",2015-02-12 10:34:59,23.7,22.745,756.5,812.25,0.00412034020384398,1 +"1189",2015-02-12 10:36:00,23.6666666666667,22.8566666666667,749,806,0.00413234565600387,1 +"1190",2015-02-12 10:37:00,23.675,22.79,743,801.75,0.00412229483449003,1 +"1191",2015-02-12 10:38:00,23.675,22.745,289,795.75,0.00411410131786791,1 +"1192",2015-02-12 10:38:59,23.7,22.945,289,804.5,0.00415681306690622,0 +"1193",2015-02-12 10:40:00,23.7,23.0666666666667,271,814.333333333333,0.00417900280407989,0 +"1194",2015-02-12 10:40:59,23.7,22.89,284.5,829.5,0.00414678260597416,0 +"1195",2015-02-12 10:41:59,23.7225,22.79,288,838.75,0.00413417961704383,0 +"1196",2015-02-12 10:43:00,23.7,22.8233333333333,295,836,0.00413462490234033,0 +"1197",2015-02-12 10:44:00,23.7225,22.815,289,835,0.00413874487391261,0 +"1198",2015-02-12 10:45:00,23.7225,22.815,289,835,0.00413874487391261,0 +"1199",2015-02-12 10:46:00,23.79,22.79,289,836.5,0.00415112041786,0 +"1200",2015-02-12 10:46:59,23.79,22.79,292.5,834.75,0.00415112041786,0 +"1201",2015-02-12 10:47:59,23.79,22.79,293.666666666667,829,0.00415112041786,0 +"1202",2015-02-12 10:49:00,23.79,22.7225,307.5,830.25,0.00413874371477813,0 +"1203",2015-02-12 10:50:00,23.79,22.7,298.5,833.5,0.00413461825581317,0 +"1204",2015-02-12 10:51:00,23.79,22.7,302,829.5,0.00413461825581317,0 +"1205",2015-02-12 10:52:00,23.815,22.7225,312,824,0.00414501470219801,0 +"1206",2015-02-12 10:53:00,23.89,22.7,313,824.333333333333,0.00415972721303041,0 +"1207",2015-02-12 10:53:59,23.865,22.675,307.5,826.75,0.00414883263868941,0 +"1208",2015-02-12 10:54:59,23.89,22.7,306,830,0.00415972721303041,0 +"1209",2015-02-12 10:56:00,23.89,22.7,293.666666666667,827.333333333333,0.00415972721303041,0 +"1210",2015-02-12 10:57:00,23.89,22.7,307,828.5,0.00415972721303041,0 +"1211",2015-02-12 10:58:00,23.89,22.65,292,825.25,0.00415050367913518,0 +"1212",2015-02-12 10:59:00,23.9633333333333,22.6333333333333,293,819.333333333333,0.00416587264297216,0 +"1213",2015-02-12 10:59:59,23.9175,22.6,290.5,823.5,0.00414817794587088,0 +"1214",2015-02-12 11:00:59,23.9725,22.6,296.5,822,0.0041620033548918,0 +"1215",2015-02-12 11:02:00,23.9633333333333,22.5666666666667,291,824.333333333333,0.00415352009207855,0 +"1216",2015-02-12 11:03:00,23.945,22.575,298,827.5,0.00415045858373016,0 +"1217",2015-02-12 11:04:00,23.945,22.575,291.75,828.75,0.00415045858373016,0 +"1218",2015-02-12 11:05:00,23.945,22.6,294.5,826.5,0.00415508558758961,0 +"1219",2015-02-12 11:06:00,24,22.5,294.75,829,0.00415036157515842,0 +"1220",2015-02-12 11:06:59,24,22.5,293,827,0.00415036157515842,0 +"1221",2015-02-12 11:08:00,24,22.5,286,823.5,0.00415036157515842,0 +"1222",2015-02-12 11:09:00,24,22.5,294.75,813.25,0.00415036157515842,0 +"1223",2015-02-12 11:10:00,24,22.5,301,801,0.00415036157515842,0 +"1224",2015-02-12 11:10:59,24.05,22.5,301,802,0.00416292718640506,0 +"1225",2015-02-12 11:12:00,24.05,22.5,304,801.5,0.00416292718640506,0 +"1226",2015-02-12 11:12:59,24.0666666666667,22.4633333333333,295,799.666666666667,0.00416028687150909,0 +"1227",2015-02-12 11:13:59,24.075,22.4725,289,794.5,0.00416409271215082,0 +"1228",2015-02-12 11:15:00,24.075,22.4725,289,790,0.00416409271215082,0 +"1229",2015-02-12 11:16:00,24.1,22.5,298,786,0.00417552627916119,0 +"1230",2015-02-12 11:17:00,24.1,22.4266666666667,295,786.333333333333,0.00416182609730641,0 +"1231",2015-02-12 11:18:00,24.1,22.39,294,791.333333333333,0.00415497623118771,0 +"1232",2015-02-12 11:19:00,24.1,22.4725,277.75,969.5,0.0041703886407112,0 +"1233",2015-02-12 11:19:59,24.1,22.4266666666667,288,791,0.00416182609730641,0 +"1234",2015-02-12 11:21:00,24.1,22.4175,278,756.75,0.00416011361672654,0 +"1235",2015-02-12 11:22:00,24.1,22.4175,274.5,757.25,0.00416011361672654,0 +"1236",2015-02-12 11:23:00,24.1,22.39,252,760.5,0.00415497623118771,0 +"1237",2015-02-12 11:23:59,24.1,22.4266666666667,275,761.666666666667,0.00416182609730641,0 +"1238",2015-02-12 11:25:00,24.1,22.39,267.5,921.5,0.00415497623118771,0 +"1239",2015-02-12 11:25:59,24.1,22.4725,258.75,902.25,0.0041703886407112,0 +"1240",2015-02-12 11:26:59,24.1,22.39,257,877.5,0.00415497623118771,0 +"1241",2015-02-12 11:28:00,24.1,22.4175,261.75,880.25,0.00416011361672654,0 +"1242",2015-02-12 11:29:00,24.1,22.4633333333333,275,866,0.00416867611329593,0 +"1243",2015-02-12 11:30:00,24.1,22.5,258,861.5,0.00417552627916119,0 +"1244",2015-02-12 11:31:00,24.1,22.445,253.5,852,0.00416525108656701,0 +"1245",2015-02-12 11:31:59,24.1,22.4266666666667,250,845,0.00416182609730641,0 +"1246",2015-02-12 11:32:59,24.1,22.5,237,830.75,0.00417552627916119,0 +"1247",2015-02-12 11:34:00,24.1,22.5,250,830.666666666667,0.00417552627916119,0 +"1248",2015-02-12 11:35:00,24.1,22.5,241.5,814.25,0.00417552627916119,0 +"1249",2015-02-12 11:36:00,24.1,22.5,257.25,799.5,0.00417552627916119,0 +"1250",2015-02-12 11:37:00,24.0333333333333,22.5,225,796.333333333333,0.00415873493294387,0 +"1251",2015-02-12 11:38:00,24.05,22.445,245.5,797,0.004152683203445,0 +"1252",2015-02-12 11:38:59,24.0333333333333,22.5,240.666666666667,803,0.00415873493294387,0 +"1253",2015-02-12 11:39:59,24.1,22.55,209,810,0.00418486765597616,0 +"1254",2015-02-12 11:41:00,24.025,22.5,214.75,821,0.0041566402003878,0 +"1255",2015-02-12 11:42:00,24,22.5,190,815.25,0.00415036157515842,0 +"1256",2015-02-12 11:43:00,24,22.5,187.5,799.5,0.00415036157515842,0 +"1257",2015-02-12 11:44:00,24,22.55,192.75,808.75,0.00415964628018105,0 +"1258",2015-02-12 11:44:59,23.89,22.6,233,796,0.00414128041696718,0 +"1259",2015-02-12 11:45:59,23.9175,22.625,231,798,0.00415279727479911,0 +"1260",2015-02-12 11:47:00,23.9175,22.625,228.75,801,0.00415279727479911,0 +"1261",2015-02-12 11:48:00,23.9633333333333,22.6,227,797,0.00415969630660419,0 +"1262",2015-02-12 11:49:00,23.9633333333333,22.6,235,804.333333333333,0.00415969630660419,0 +"1263",2015-02-12 11:50:00,24,22.6,241.75,806,0.00416893126055936,0 +"1264",2015-02-12 11:51:00,23.9633333333333,22.6,239,800,0.00415969630660419,0 +"1265",2015-02-12 11:51:59,23.9633333333333,22.6,261,782,0.00415969630660419,0 +"1266",2015-02-12 11:53:00,23.9266666666667,22.6,222.333333333333,781.333333333333,0.00415047936883409,0 +"1267",2015-02-12 11:54:00,23.945,22.6,224.75,783,0.00415508558758961,0 +"1268",2015-02-12 11:55:00,24,22.7,217.5,779,0.00418750204743197,0 +"1269",2015-02-12 11:55:59,23.9725,22.7,244.25,778,0.00418054307490038,0 +"1270",2015-02-12 11:57:00,23.945,22.7,284.5,779,0.00417359428688215,0 +"1271",2015-02-12 11:57:59,23.945,22.7,264,777,0.00417359428688215,0 +"1272",2015-02-12 11:58:59,23.9725,22.65,274.5,773.25,0.00417127307766478,0 +"1273",2015-02-12 12:00:00,24,22.6,275,770,0.00416893126055936,0 +"1274",2015-02-12 12:01:00,24,22.6333333333333,273.666666666667,771,0.00417512140045965,0 +"1275",2015-02-12 12:02:00,24,22.6,283,770,0.00416893126055936,0 +"1276",2015-02-12 12:03:00,24,22.6666666666667,300,766.333333333333,0.00418131166274931,0 +"1277",2015-02-12 12:04:00,24,22.7,295.25,767,0.00418750204743197,0 +"1278",2015-02-12 12:04:59,24,22.7,288,767,0.00418750204743197,0 +"1279",2015-02-12 12:06:00,24,22.7,287.25,761.25,0.00418750204743197,0 +"1280",2015-02-12 12:07:00,24,22.7,293.666666666667,760.333333333333,0.00418750204743197,0 +"1281",2015-02-12 12:08:00,24.025,22.675,281,757,0.00418918736374027,0 +"1282",2015-02-12 12:08:59,24,22.7,287,756.333333333333,0.00418750204743197,0 +"1283",2015-02-12 12:10:00,24.05,22.675,260,756.5,0.00419552390772226,0 +"1284",2015-02-12 12:10:59,24.075,22.675,281,753.25,0.00420186888905812,0 +"1285",2015-02-12 12:11:59,24.0333333333333,22.6333333333333,271,750.666666666667,0.00418354504496686,0 +"1286",2015-02-12 12:13:00,24.075,22.675,264.25,746.5,0.00420186888905812,0 +"1287",2015-02-12 12:14:00,24.1,22.7,275,746.5,0.004212893458768,0 +"1288",2015-02-12 12:15:00,24.1,22.7,251.25,745.25,0.004212893458768,0 +"1289",2015-02-12 12:16:00,24.1,22.7,257.5,749,0.004212893458768,0 +"1290",2015-02-12 12:16:59,24.1,22.7,274,745,0.004212893458768,0 +"1291",2015-02-12 12:17:59,24.125,22.7,244.5,739.75,0.00421926245314457,0 +"1292",2015-02-12 12:19:00,24.1,22.7,261,738.5,0.004212893458768,0 +"1293",2015-02-12 12:20:00,24.1,22.7,260.25,735.5,0.004212893458768,0 +"1294",2015-02-12 12:21:00,24.1,22.7,262,735,0.004212893458768,0 +"1295",2015-02-12 12:22:00,24.15,22.7,257.5,729.25,0.00422563992353678,0 +"1296",2015-02-12 12:23:00,24.2,22.65,248.75,734.25,0.00422902112937993,0 +"1297",2015-02-12 12:23:59,24.2,22.6666666666667,209.666666666667,730.666666666667,0.00423215416531739,0 +"1298",2015-02-12 12:24:59,24.14,22.7,246.75,730,0.00422308791763644,0 +"1299",2015-02-12 12:26:00,24.175,22.7,234.6,728,0.00423202587966061,0 +"1300",2015-02-12 12:27:00,24.1333333333333,22.7,264,724.25,0.00422138733434953,0 +"1301",2015-02-12 12:28:00,24.1666666666667,22.7,271.666666666667,726,0.00422989628416011,0 +"1302",2015-02-12 12:29:00,24.2,22.7,285.666666666667,729,0.00423842033124109,0 +"1303",2015-02-12 12:29:59,24.2,22.7,282.5,729.75,0.00423842033124109,0 +"1304",2015-02-12 12:30:59,24.2,22.7,276.5,727.75,0.00423842033124109,0 +"1305",2015-02-12 12:32:00,24.2,22.7,261,724,0.00423842033124109,0 +"1306",2015-02-12 12:33:00,24.23,22.73,268.666666666667,718.666666666667,0.00425175485193373,0 +"1307",2015-02-12 12:34:00,24.2,22.7,238.5,723.5,0.00423842033124109,0 +"1308",2015-02-12 12:35:00,24.2,22.7,248.5,725,0.00423842033124109,0 +"1309",2015-02-12 12:36:00,24.2,22.7,236,722,0.00423842033124109,0 +"1310",2015-02-12 12:36:59,24.2,22.7,240.25,725.25,0.00423842033124109,0 +"1311",2015-02-12 12:38:00,24.2,22.7,242.25,722.25,0.00423842033124109,0 +"1312",2015-02-12 12:39:00,24.2,22.7,236,723,0.00423842033124109,0 +"1313",2015-02-12 12:40:00,24.175,22.7,238.5,726.5,0.00423202587966061,0 +"1314",2015-02-12 12:40:59,24.2,22.7,336.333333333333,726.333333333333,0.00423842033124109,0 +"1315",2015-02-12 12:42:00,24.2,23.0225,497,722,0.00429905196288809,0 +"1316",2015-02-12 12:42:59,24.29,23.6266666666667,522,728.666666666667,0.00443671649794104,1 +"1317",2015-02-12 12:43:59,24.315,23.4925,626.75,740.5,0.00441800488019686,1 +"1318",2015-02-12 12:45:00,24.3566666666667,23.23,638,739.333333333333,0.00437928846738519,1 +"1319",2015-02-12 12:46:00,24.39,23.2725,666,840.75,0.00439618779441628,1 +"1320",2015-02-12 12:47:00,24.39,22.9966666666667,670.333333333333,754.333333333333,0.00434371885486522,1 +"1321",2015-02-12 12:48:00,24.39,23.34,709.25,756.5,0.0044090289643799,1 +"1322",2015-02-12 12:49:00,24.3566666666667,23.46,700.666666666667,763.666666666667,0.0044229560810758,1 +"1323",2015-02-12 12:49:59,24.29,23.4725,688,812.75,0.00440756127857155,1 +"1324",2015-02-12 12:51:00,24.315,23.4725,688,823,0.00441421698309807,1 +"1325",2015-02-12 12:52:00,24.29,23.39,677.333333333333,817.666666666667,0.00439196041100586,1 +"1326",2015-02-12 12:53:00,24.34,23.39,681.75,817.5,0.00440523319039569,1 +"1327",2015-02-12 12:53:59,24.3233333333333,23.39,683.666666666667,818,0.0044008050110609,1 +"1328",2015-02-12 12:55:00,24.29,23.29,688,863.5,0.00437305131029723,1 +"1329",2015-02-12 12:55:59,24.39,23.3925,236.5,852.5,0.00441901690501712,1 +"1330",2015-02-12 12:56:59,24.34,23.5,223,805,0.00442609782695283,0 +"1331",2015-02-12 12:58:00,24.39,23.4175,223,795.25,0.00442377317917434,0 +"1332",2015-02-12 12:59:00,24.3566666666667,23.3566666666667,231.333333333333,780.333333333333,0.00440333654490515,0 +"1333",2015-02-12 13:00:00,24.3233333333333,23.3566666666667,239.666666666667,760.333333333333,0.00439448906818448,0 +"1334",2015-02-12 13:01:00,24.315,23.39,230,758.5,0.0043985923917815,0 +"1335",2015-02-12 13:01:59,24.34,23.39,241,759.5,0.00440523319039569,0 +"1336",2015-02-12 13:02:59,24.29,23.39,223,760.25,0.00439196041100586,0 +"1337",2015-02-12 13:04:00,24.29,23.39,226.5,751,0.00439196041100586,0 +"1338",2015-02-12 13:05:00,24.29,23.39,235,746,0.00439196041100586,0 +"1339",2015-02-12 13:06:00,24.29,23.445,237.5,750,0.00440236090303838,0 +"1340",2015-02-12 13:07:00,24.29,23.39,221.25,754.5,0.00439196041100586,0 +"1341",2015-02-12 13:08:00,24.29,23.4266666666667,216,749.666666666667,0.00439889403398603,0 +"1342",2015-02-12 13:08:59,24.29,23.5,216,749,0.0044127617404522,0 +"1343",2015-02-12 13:09:59,24.29,23.5,225,744,0.0044127617404522,0 +"1344",2015-02-12 13:11:00,24.29,23.5,214.666666666667,748,0.0044127617404522,0 +"1345",2015-02-12 13:12:00,24.236,23.434,216.4,738.5,0.004385958473379,0 +"1346",2015-02-12 13:13:00,24.29,23.5,210,740.666666666667,0.0044127617404522,0 +"1347",2015-02-12 13:14:00,24.2225,23.5,216.25,745,0.0043948141645946,0 +"1348",2015-02-12 13:14:59,24.2,23.5,205,740,0.00438884594252233,0 +"1349",2015-02-12 13:15:59,24.2,23.5,220.75,729.75,0.00438884594252233,0 +"1350",2015-02-12 13:17:00,24.2,23.5,229.75,735,0.00438884594252233,0 +"1351",2015-02-12 13:18:00,24.2,23.5,218.333333333333,742.333333333333,0.00438884594252233,0 +"1352",2015-02-12 13:19:00,24.2,23.5,217,745.25,0.00438884594252233,0 +"1353",2015-02-12 13:20:00,24.2,23.5,220.75,747.75,0.00438884594252233,0 +"1354",2015-02-12 13:21:00,24.2,23.5,210,736.5,0.00438884594252233,0 +"1355",2015-02-12 13:21:59,24.2,23.5,215.5,733.75,0.00438884594252233,0 +"1356",2015-02-12 13:23:00,24.2,23.5,211.333333333333,738,0.00438884594252233,0 +"1357",2015-02-12 13:24:00,24.2,23.55,450,733,0.00439824994271958,1 +"1358",2015-02-12 13:25:00,24.2,23.7,630,734,0.0044264636375791,0 +"1359",2015-02-12 13:25:59,24.2,23.745,690.5,729,0.00443492824164674,0 +"1360",2015-02-12 13:27:00,24.2,23.6966666666667,682.666666666667,724.666666666667,0.0044258366389703,1 +"1361",2015-02-12 13:27:59,24.2,23.675,653.75,718.5,0.00442176117860701,1 +"1362",2015-02-12 13:28:59,24.2,23.65,651,718.5,0.00441705879023525,1 +"1363",2015-02-12 13:30:00,24.2,23.7,652,717.5,0.0044264636375791,1 +"1364",2015-02-12 13:31:00,24.2,23.7,651.666666666667,712.333333333333,0.0044264636375791,1 +"1365",2015-02-12 13:32:00,24.2,23.675,648,701.5,0.00442176117860701,1 +"1366",2015-02-12 13:33:00,24.2,23.7,654.666666666667,697.666666666667,0.0044264636375791,1 +"1367",2015-02-12 13:34:00,24.2,23.7,655.5,698.75,0.0044264636375791,1 +"1368",2015-02-12 13:34:59,24.2,23.745,419.75,697.25,0.00443492824164674,1 +"1369",2015-02-12 13:36:00,24.2,23.8425,188.5,693.75,0.00445326900191104,0 +"1370",2015-02-12 13:37:00,24.2,23.815,182.5,688.75,0.00444809585822788,0 +"1371",2015-02-12 13:38:00,24.2,23.84,190,694,0.00445279871259114,0 +"1372",2015-02-12 13:38:59,24.2,23.89,187.5,694,0.00446220463315171,0 +"1373",2015-02-12 13:40:00,24.175,23.89,194.75,691.75,0.00445547015894865,0 +"1374",2015-02-12 13:40:59,24.1,23.89,193,689,0.0044353204219434,0 +"1375",2015-02-12 13:41:59,24.15,23.89,179.5,691.25,0.004448744639192,0 +"1376",2015-02-12 13:43:00,24.1,23.89,160,689,0.0044353204219434,0 +"1377",2015-02-12 13:44:00,24.1,23.9266666666667,169.666666666667,689,0.00444217642315851,0 +"1378",2015-02-12 13:45:00,24.1,24.2975,171,694.5,0.0045115239612022,0 +"1379",2015-02-12 13:46:00,24.1,24.1,171,691,0.0044745886423598,0 +"1380",2015-02-12 13:46:59,24.0666666666667,24.1,183,685,0.00446557937722871,0 +"1381",2015-02-12 13:47:59,24.1,24.1,181.75,681.25,0.0044745886423598,0 +"1382",2015-02-12 13:49:00,24.075,24.125,175.5,680.5,0.00447249819843423,0 +"1383",2015-02-12 13:50:00,24,24.1,183,679.333333333333,0.00444760877307786,0 +"1384",2015-02-12 13:51:00,24,24.1,189,679.333333333333,0.00444760877307786,0 +"1385",2015-02-12 13:52:00,24.025,24.1,181.75,681.5,0.00445434026978091,0 +"1386",2015-02-12 13:53:00,24,24.1,180,672.5,0.00444760877307786,0 +"1387",2015-02-12 13:53:59,24,24.1,171,669,0.00444760877307786,0 +"1388",2015-02-12 13:54:59,24,24.125,180,665,0.00445225549985181,0 +"1389",2015-02-12 13:56:00,24,24.1666666666667,177,663.666666666667,0.00446000019766575,0 +"1390",2015-02-12 13:57:00,24,24.15,164.25,660.25,0.00445690229556123,0 +"1391",2015-02-12 13:58:00,24,24.175,152,668,0.00446154916020766,0 +"1392",2015-02-12 13:59:00,23.945,24.2,134,665,0.00445135613947432,0 +"1393",2015-02-12 13:59:59,23.9633333333333,24.2,137.666666666667,662,0.00445629795687425,0 +"1394",2015-02-12 14:00:59,23.945,24.2,130,657.75,0.00445135613947432,0 +"1395",2015-02-12 14:02:00,23.89,24.2,135.75,660.75,0.00443655964263606,0 +"1396",2015-02-12 14:03:00,23.89,24.2,139,661,0.00443655964263606,0 +"1397",2015-02-12 14:04:00,23.89,24.2225,142.5,655.5,0.00444071399249253,0 +"1398",2015-02-12 14:05:00,23.89,24.2,142.5,654,0.00443655964263606,0 +"1399",2015-02-12 14:06:00,23.89,24.2675,149.75,649,0.0044490228575105,0 +"1400",2015-02-12 14:06:59,23.89,24.245,157,647.5,0.00444486839745031,0 +"1401",2015-02-12 14:08:00,23.89,24.2,142.5,641,0.00443655964263606,0 +"1402",2015-02-12 14:09:00,23.89,24.245,148,643.5,0.00444486839745031,0 +"1403",2015-02-12 14:10:00,23.89,24.26,139,637.333333333333,0.00444763803136788,0 +"1404",2015-02-12 14:10:59,23.8566666666667,24.26,139,639,0.00443866906295608,0 +"1405",2015-02-12 14:12:00,23.87,24.272,128.25,641.25,0.00444446776025605,0 +"1406",2015-02-12 14:12:59,23.815,24.2225,132.6,638.6,0.00442058782666326,0 +"1407",2015-02-12 14:13:59,23.79,24.2,121,637.666666666667,0.00440976790048444,0 +"1408",2015-02-12 14:15:00,23.84,24.245,126.75,636.5,0.00443142935643837,0 +"1409",2015-02-12 14:16:00,23.79,24.2,133,631.5,0.00440976790048444,0 +"1410",2015-02-12 14:17:00,23.79,24.2,113.25,626.5,0.00440976790048444,0 +"1411",2015-02-12 14:18:00,23.79,24.2,108,626.333333333333,0.00440976790048444,0 +"1412",2015-02-12 14:19:00,23.79,24.2,114,627.75,0.00440976790048444,0 +"1413",2015-02-12 14:19:59,23.79,24.2,118.75,627,0.00440976790048444,0 +"1414",2015-02-12 14:21:00,23.79,24.2,103,618.666666666667,0.00440976790048444,0 +"1415",2015-02-12 14:22:00,23.79,24.2,100.666666666667,615,0.00440976790048444,0 +"1416",2015-02-12 14:23:00,23.79,24.2,115.5,617.5,0.00440976790048444,0 +"1417",2015-02-12 14:23:59,23.79,24.2,107,618,0.00440976790048444,0 +"1418",2015-02-12 14:25:00,23.7675,24.2225,120,615.5,0.00440788285941707,0 +"1419",2015-02-12 14:25:59,23.745,24.2,120,615.5,0.00439775819209062,0 +"1420",2015-02-12 14:26:59,23.7675,24.2675,123,610,0.0044161298621988,0 +"1421",2015-02-12 14:28:00,23.7,24.29,105.666666666667,609.333333333333,0.00440220348975394,0 +"1422",2015-02-12 14:29:00,23.7225,24.29,111.5,610.5,0.00440821291270567,0 +"1423",2015-02-12 14:30:00,23.7,24.29,102,606.75,0.00440220348975394,0 +"1424",2015-02-12 14:31:00,23.7,24.29,103.333333333333,601,0.00440220348975394,0 +"1425",2015-02-12 14:31:59,23.7,24.29,90.3333333333333,600,0.00440220348975394,0 +"1426",2015-02-12 14:32:59,23.7,24.43,87,599.666666666667,0.0044277570397796,1 +"1427",2015-02-12 14:34:00,23.6,24.445,102.5,602.5,0.00440370144282091,0 +"1428",2015-02-12 14:35:00,23.6,24.5,97.3333333333333,603.666666666667,0.00441367985327035,0 +"1429",2015-02-12 14:36:00,23.6,24.6,88,600.5,0.00443182323221678,0 +"1430",2015-02-12 14:37:00,23.6,24.7,95,599,0.00444996766219944,0 +"1431",2015-02-12 14:38:00,23.525,24.7225,113,593.25,0.00443381859760201,0 +"1432",2015-02-12 14:38:59,23.5,24.89,95,590,0.00445730211719461,0 +"1433",2015-02-12 14:39:59,23.39,24.84,107,582,0.00441865474133687,0 +"1434",2015-02-12 14:41:00,23.39,24.89,98.6666666666667,583,0.0044276122861482,0 +"1435",2015-02-12 14:42:00,23.34,24.945,86.5,579,0.00442399809917624,0 +"1436",2015-02-12 14:43:00,23.29,25,92,576.5,0.0044203601025715,0 +"1437",2015-02-12 14:44:00,23.29,25.1,81,585,0.00443816770567925,0 +"1438",2015-02-12 14:44:59,23.29,25.3333333333333,83.3333333333333,584,0.00447972271717749,0 +"1439",2015-02-12 14:45:59,23.2,25.39,87,592,0.00446529300641367,0 +"1440",2015-02-12 14:47:00,23.2,25.29,94,592,0.00444758043506813,0 +"1441",2015-02-12 14:48:00,23.2,25.29,94,588,0.00444758043506813,0 +"1442",2015-02-12 14:49:00,23.2,25.29,78,587.333333333333,0.00444758043506813,0 +"1443",2015-02-12 14:50:00,23.2,25.29,76,587,0.00444758043506813,0 +"1444",2015-02-12 14:51:00,23.2,25.29,76,586.5,0.00444758043506813,0 +"1445",2015-02-12 14:51:59,23.2,25.29,81,583,0.00444758043506813,0 +"1446",2015-02-12 14:53:00,23.2,25.29,70,583,0.00444758043506813,0 +"1447",2015-02-12 14:54:00,23.2,25.29,90,591.333333333333,0.00444758043506813,0 +"1448",2015-02-12 14:55:00,23.1666666666667,25.29,86,588.666666666667,0.00443856420522413,0 +"1449",2015-02-12 14:55:59,23.1666666666667,25.29,76,584.333333333333,0.00443856420522413,0 +"1450",2015-02-12 14:57:00,23.15,25.29,59,580.5,0.00443406213468133,0 +"1451",2015-02-12 14:57:59,23.15,25.29,64.5,581.5,0.00443406213468133,0 +"1452",2015-02-12 14:58:59,23.1,25.34,70.5,583,0.00442938207960448,0 +"1453",2015-02-12 15:00:00,23.1,25.39,62,577,0.0044381843433123,0 +"1454",2015-02-12 15:01:00,23.1,25.39,62,576.666666666667,0.0044381843433123,0 +"1455",2015-02-12 15:02:00,23.1,25.39,62,580,0.0044381843433123,0 +"1456",2015-02-12 15:03:00,23.1,25.5,62,579.5,0.00445755019423801,0 +"1457",2015-02-12 15:04:00,23.05,25.445,62,577.5,0.0044343376071688,0 +"1458",2015-02-12 15:04:59,23.0333333333333,25.4266666666667,60,573.333333333333,0.00442662139006117,0 +"1459",2015-02-12 15:06:00,23,25.39,50,570,0.00441122084993632,0 +"1460",2015-02-12 15:07:00,23,25.39,68,569.5,0.00441122084993632,0 +"1461",2015-02-12 15:08:00,23,25.39,68,568.5,0.00441122084993632,0 +"1462",2015-02-12 15:08:59,23,25.39,68,569.5,0.00441122084993632,0 +"1463",2015-02-12 15:10:00,23,25.39,62.5,564,0.00441122084993632,0 +"1464",2015-02-12 15:10:59,23,25.39,74,569,0.00441122084993632,0 +"1465",2015-02-12 15:11:59,23,25.39,63,567.5,0.00441122084993632,0 +"1466",2015-02-12 15:13:00,22.945,25.39,74,569.5,0.00439645256371606,0 +"1467",2015-02-12 15:14:00,22.945,25.39,59,569,0.00439645256371606,0 +"1468",2015-02-12 15:15:00,22.89,25.5,50,569,0.00440084565133473,0 +"1469",2015-02-12 15:16:00,22.89,25.5,60.6666666666667,567,0.00440084565133473,0 +"1470",2015-02-12 15:16:59,22.89,25.5,63,568,0.00440084565133473,0 +"1471",2015-02-12 15:17:59,22.89,25.5,63,567.5,0.00440084565133473,0 +"1472",2015-02-12 15:19:00,22.89,25.5,62,568,0.00440084565133473,0 +"1473",2015-02-12 15:20:00,22.89,25.5,56,566,0.00440084565133473,0 +"1474",2015-02-12 15:21:00,22.89,25.6,62,563,0.00441822645915157,0 +"1475",2015-02-12 15:22:00,22.89,25.6,58,560,0.00441822645915157,0 +"1476",2015-02-12 15:23:00,22.89,25.6,72,562,0.00441822645915157,0 +"1477",2015-02-12 15:23:59,22.89,25.6,72,566,0.00441822645915157,0 +"1478",2015-02-12 15:24:59,22.79,25.55,58,561.5,0.00438270473138885,0 +"1479",2015-02-12 15:26:00,22.79,25.6,44,564,0.00439134200493453,0 +"1480",2015-02-12 15:27:00,22.79,25.55,47,566.5,0.00438270473138885,0 +"1481",2015-02-12 15:28:00,22.79,25.6,62,562,0.00439134200493453,0 +"1482",2015-02-12 15:29:00,22.745,25.65,64.5,561.5,0.00438790476586486,0 +"1483",2015-02-12 15:29:59,22.76,25.6666666666667,59.6666666666667,560.666666666667,0.00439480034979246,0 +"1484",2015-02-12 15:30:59,22.745,25.7,79,562.5,0.00439651864509956,0 +"1485",2015-02-12 15:32:00,22.7,25.7,62,564,0.00438444930367711,0 +"1486",2015-02-12 15:33:00,22.7,25.7,47,565.5,0.00438444930367711,0 +"1487",2015-02-12 15:34:00,22.7,25.7,62,555.333333333333,0.00438444930367711,0 +"1488",2015-02-12 15:35:00,22.7,25.7,62,556,0.00438444930367711,0 +"1489",2015-02-12 15:36:00,22.7,25.7,62,552.5,0.00438444930367711,0 +"1490",2015-02-12 15:36:59,22.7,25.7,62,551,0.00438444930367711,0 +"1491",2015-02-12 15:38:00,22.7,25.7225,44,553.25,0.00438831491077801,0 +"1492",2015-02-12 15:39:00,22.7,25.745,58,551,0.00439218056559085,0 +"1493",2015-02-12 15:40:00,22.6,25.7,72,553,0.00435773306679615,0 +"1494",2015-02-12 15:40:59,22.6,25.7,65,551,0.00435773306679615,0 +"1495",2015-02-12 15:42:00,22.6,25.7,44,548.5,0.00435773306679615,0 +"1496",2015-02-12 15:42:59,22.6,25.7,72,549,0.00435773306679615,0 +"1497",2015-02-12 15:43:59,22.6,25.7,58,540,0.00435773306679615,0 +"1498",2015-02-12 15:45:00,22.6,25.7,58,544.5,0.00435773306679615,0 +"1499",2015-02-12 15:46:00,22.6,25.7,63.5,552.5,0.00435773306679615,0 +"1500",2015-02-12 15:47:00,22.6,25.73,45.3333333333333,554,0.00436285559509254,0 +"1501",2015-02-12 15:48:00,22.6,25.73,55,546,0.00436285559509254,0 +"1502",2015-02-12 15:49:00,22.6,25.79,55,542.666666666667,0.00437310090305024,0 +"1503",2015-02-12 15:49:59,22.6,25.79,55,538,0.00437310090305024,0 +"1504",2015-02-12 15:51:00,22.6,25.79,55,542,0.00437310090305024,0 +"1505",2015-02-12 15:52:00,22.6,25.79,55,543,0.00437310090305024,0 +"1506",2015-02-12 15:53:00,22.6,25.84,37,549.5,0.00438163891571123,0 +"1507",2015-02-12 15:53:59,22.55,25.84,37,542,0.00436826120315825,0 +"1508",2015-02-12 15:55:00,22.5666666666667,25.89,37,538,0.00438123717108904,0 +"1509",2015-02-12 15:55:59,22.5,25.89,37,545,0.00436340532960398,0 +"1510",2015-02-12 15:56:59,22.5,25.89,37,538,0.00436340532960398,0 +"1511",2015-02-12 15:58:00,22.445,25.89,37,535,0.00434874226337612,0 +"1512",2015-02-12 15:59:00,22.5,25.89,37,539,0.00436340532960398,0 +"1513",2015-02-12 16:00:00,22.5,25.89,37,544,0.00436340532960398,0 +"1514",2015-02-12 16:01:00,22.5,25.89,37,544.5,0.00436340532960398,0 +"1515",2015-02-12 16:01:59,22.5,25.89,37,538.5,0.00436340532960398,0 +"1516",2015-02-12 16:02:59,22.39,25.89,37,540,0.00433412265851602,0 +"1517",2015-02-12 16:04:00,22.5,26,37,537,0.00438207493457723,0 +"1518",2015-02-12 16:05:00,22.39,25.89,37,536,0.00433412265851602,0 +"1519",2015-02-12 16:06:00,22.39,25.89,19,532.5,0.00433412265851602,0 +"1520",2015-02-12 16:07:00,22.39,25.89,28,532.5,0.00433412265851602,0 +"1521",2015-02-12 16:08:00,22.39,25.89,19,526.5,0.00433412265851602,0 +"1522",2015-02-12 16:08:59,22.39,25.9633333333333,28.6666666666667,531.666666666667,0.00434648483198383,0 +"1523",2015-02-12 16:09:59,22.39,26,191.5,534.5,0.00435266610171691,1 +"1524",2015-02-12 16:11:00,22.365,26.2675,407.25,535,0.00439103597707417,1 +"1525",2015-02-12 16:12:00,22.365,26.29,466.75,539.25,0.00439482379023074,1 +"1526",2015-02-12 16:13:00,22.34,26.315,459,536,0.00439230029328601,1 +"1527",2015-02-12 16:14:00,22.29,26.445,469,538,0.00440064835996778,1 +"1528",2015-02-12 16:14:59,22.29,26.6,464,541.333333333333,0.00442662509816911,1 +"1529",2015-02-12 16:15:59,22.315,26.55,461.5,548,0.00442502014952117,1 +"1530",2015-02-12 16:17:00,22.29,26.55,454,546.25,0.00441824526980057,1 +"1531",2015-02-12 16:18:00,22.3233333333333,26.6,454,542.666666666667,0.0044356775640082,1 +"1532",2015-02-12 16:19:00,22.29,26.6,454,543.333333333333,0.00442662509816911,1 +"1533",2015-02-12 16:20:00,22.315,26.6,450.25,551.75,0.00443341291835053,1 +"1534",2015-02-12 16:21:00,22.29,26.65,439,555,0.00443500515074077,1 +"1535",2015-02-12 16:21:59,22.29,26.65,439,552.75,0.00443500515074077,1 +"1536",2015-02-12 16:23:00,22.29,26.745,439,555,0.00445092786833875,1 +"1537",2015-02-12 16:24:00,22.29,26.79,439,554,0.00445847049077861,1 +"1538",2015-02-12 16:25:00,22.29,26.815,439,556.5,0.00446266091506117,1 +"1539",2015-02-12 16:25:59,22.29,26.79,439,565,0.00445847049077861,1 +"1540",2015-02-12 16:27:00,22.2675,26.865,439,561.75,0.00446487907572183,1 +"1541",2015-02-12 16:27:59,22.2675,26.945,439,570.25,0.0044782705524413,1 +"1542",2015-02-12 16:28:59,22.23,26.9266666666667,439,576,0.00446492296591114,1 +"1543",2015-02-12 16:30:00,22.26,26.9633333333333,439,577.333333333333,0.00447927927201729,1 +"1544",2015-02-12 16:31:00,22.29,27.025,439,577.75,0.00449786269241101,1 +"1545",2015-02-12 16:32:00,22.245,27.075,444.25,577.666666666667,0.00449382874928666,1 +"1546",2015-02-12 16:33:00,22.2,27.0333333333333,453,582.75,0.00447449676895718,1 +"1547",2015-02-12 16:34:00,22.2225,27.075,449.5,584.25,0.00448763212130289,1 +"1548",2015-02-12 16:34:59,22.2225,27.125,445.5,585,0.00449597943414763,1 +"1549",2015-02-12 16:36:00,22.2,27.1,441.5,591.75,0.00448561086271465,1 +"1550",2015-02-12 16:37:00,22.2,27.1,441.75,596.25,0.00448561086271465,1 +"1551",2015-02-12 16:38:00,22.2,27.1,434,602,0.00448561086271465,1 +"1552",2015-02-12 16:38:59,22.2,27.175,434,605.75,0.00449811468956496,1 +"1553",2015-02-12 16:40:00,22.2,27.1666666666667,444,605,0.00449672535082264,1 +"1554",2015-02-12 16:40:59,22.2,27.2225,439,596.5,0.0045060340380626,1 +"1555",2015-02-12 16:41:59,22.2,27.29,444,593.5,0.00451728819349999,1 +"1556",2015-02-12 16:43:00,22.2,27.245,444,595,0.00450978537828394,1 +"1557",2015-02-12 16:44:00,22.1666666666667,27.23,444,596,0.00449807612586088,1 +"1558",2015-02-12 16:45:00,22.175,27.29,444,594.25,0.00451036492893207,1 +"1559",2015-02-12 16:46:00,22.1333333333333,27.3233333333333,444,596.333333333333,0.00450438185755505,1 +"1560",2015-02-12 16:46:59,22.1,27.365,444,599.75,0.00450207929588443,1 +"1561",2015-02-12 16:47:59,22.15,27.39,444,602,0.00452007314978391,1 +"1562",2015-02-12 16:49:00,22.15,27.4425,444,603,0.00452880011789408,1 +"1563",2015-02-12 16:50:00,22.1,27.575,444,600,0.00453688041724203,1 +"1564",2015-02-12 16:51:00,22.1,27.5,444,599,0.00452445100150358,1 +"1565",2015-02-12 16:52:00,22.1,27.5,444,599.25,0.00452445100150358,1 +"1566",2015-02-12 16:53:00,22.1,27.5,444,596.5,0.00452445100150358,1 +"1567",2015-02-12 16:53:59,22.1,27.5,444,597.25,0.00452445100150358,1 +"1568",2015-02-12 16:54:59,22.075,27.4725,439,596.333333333333,0.00451296107108967,1 +"1569",2015-02-12 16:56:00,22.075,27.525,435,598.4,0.00452164804276817,1 +"1570",2015-02-12 16:57:00,22.1,27.55,429,601,0.00453273722386665,1 +"1571",2015-02-12 16:58:00,22.1,27.6,429,599.5,0.00454102366541475,1 +"1572",2015-02-12 16:59:00,22.075,27.575,429,606.75,0.00452992157309756,1 +"1573",2015-02-12 16:59:59,22,27.525,429,606.75,0.00450086627470793,1 +"1574",2015-02-12 17:00:59,22.0333333333333,27.5666666666667,429,606,0.00451696903605908,1 +"1575",2015-02-12 17:02:00,22.05,27.65,429,612.5,0.00453536367506768,1 +"1576",2015-02-12 17:03:00,22,27.6725,429,610.5,0.00452516082891782,1 +"1577",2015-02-12 17:04:00,22,27.7675,433.5,620.75,0.00454080916652179,1 +"1578",2015-02-12 17:05:00,22,27.7,438,626,0.00452969053046999,1 +"1579",2015-02-12 17:06:00,22,27.7,436,623,0.00452969053046999,1 +"1580",2015-02-12 17:06:59,22,27.79,438,626.5,0.00454451546623538,1 +"1581",2015-02-12 17:08:00,21.9633333333333,27.73,441,625,0.00452442628547242,1 +"1582",2015-02-12 17:09:00,22,27.7225,438,623,0.00453339669863987,1 +"1583",2015-02-12 17:10:00,22,27.7,438,623.5,0.00452969053046999,1 +"1584",2015-02-12 17:10:59,22,27.7,423.5,624,0.00452969053046999,1 +"1585",2015-02-12 17:12:00,22,27.7,423.5,621.5,0.00452969053046999,1 +"1586",2015-02-12 17:12:59,22,27.745,423.5,621,0.00453710291065687,1 +"1587",2015-02-12 17:13:59,21.9725,27.79,427.25,622,0.00453684239738818,1 +"1588",2015-02-12 17:15:00,21.9725,27.79,423.5,623.5,0.00453684239738818,1 +"1589",2015-02-12 17:16:00,21.89,27.79,433,622,0.00451389172744809,1 +"1590",2015-02-12 17:17:00,21.945,27.79,433,623.25,0.0045291807611277,1 +"1591",2015-02-12 17:18:00,21.9725,27.79,433,632,0.00453684239738818,1 +"1592",2015-02-12 17:19:00,21.945,27.79,433,634.5,0.0045291807611277,1 +"1593",2015-02-12 17:19:59,22,27.79,433,632.5,0.00454451546623538,1 +"1594",2015-02-12 17:21:00,22,27.79,433,623.333333333333,0.00454451546623538,1 +"1595",2015-02-12 17:22:00,22,27.79,433,619.333333333333,0.00454451546623538,1 +"1596",2015-02-12 17:23:00,22,27.79,433,616.75,0.00454451546623538,1 +"1597",2015-02-12 17:23:59,22,27.79,433,617.666666666667,0.00454451546623538,1 +"1598",2015-02-12 17:25:00,22,27.79,433,616,0.00454451546623538,1 +"1599",2015-02-12 17:25:59,22,27.79,433,616.333333333333,0.00454451546623538,1 +"1600",2015-02-12 17:26:59,22,27.79,433,614,0.00454451546623538,1 +"1601",2015-02-12 17:28:00,21.9725,27.815,433,615,0.00454095355601153,1 +"1602",2015-02-12 17:29:00,21.945,27.79,426,607.5,0.0045291807611277,1 +"1603",2015-02-12 17:30:00,22,27.9175,422.5,610,0.00456551865956959,1 +"1604",2015-02-12 17:31:00,22,28.025,418.5,614,0.004583228328517,1 +"1605",2015-02-12 17:31:59,22,28.05,433,629,0.00458734699966078,1 +"1606",2015-02-12 17:32:59,22,28.1,433,635,0.00459558450438815,1 +"1607",2015-02-12 17:34:00,22,28.025,422.5,645.5,0.004583228328517,1 +"1608",2015-02-12 17:35:00,22,27.9175,423.666666666667,630.666666666667,0.00456551865956959,1 +"1609",2015-02-12 17:36:00,22,27.89,421.8,631,0.0045609884399421,1 +"1610",2015-02-12 17:37:00,21.9633333333333,27.9266666666667,419,625.666666666667,0.00455674949163352,1 +"1611",2015-02-12 17:38:00,21.9175,27.9175,419,625.75,0.00454242673746094,1 +"1612",2015-02-12 17:38:59,21.9175,27.89,419,624.5,0.00453791959716756,1 +"1613",2015-02-12 17:39:59,21.945,27.89,419,611,0.00454559774627516,1 +"1614",2015-02-12 17:41:00,21.89,27.89,419,607.666666666667,0.00453025289350595,1 +"1615",2015-02-12 17:42:00,21.9175,27.89,419,607.25,0.00453791959716756,1 +"1616",2015-02-12 17:43:00,21.89,27.89,419,601.333333333333,0.00453025289350595,1 +"1617",2015-02-12 17:44:00,21.89,27.89,279.333333333333,603.666666666667,0.00453025289350595,1 +"1618",2015-02-12 17:44:59,21.89,27.945,0,603,0.00453925189908682,0 +"1619",2015-02-12 17:45:59,21.89,28.05,0,604.5,0.00455643253669716,0 +"1620",2015-02-12 17:47:00,21.89,28.1,0,614,0.00456461412387824,0 +"1621",2015-02-12 17:48:00,21.89,28.1633333333333,0,626.333333333333,0.00457497777438213,0 +"1622",2015-02-12 17:49:00,21.89,28.1,0,626.5,0.00456461412387824,0 +"1623",2015-02-12 17:50:00,21.89,28.1,0,623,0.00456461412387824,0 +"1624",2015-02-12 17:51:00,21.89,28.1,0,620,0.00456461412387824,0 +"1625",2015-02-12 17:51:59,21.89,28.05,0,619,0.00455643253669716,0 +"1626",2015-02-12 17:53:00,21.89,28.1,0,617.5,0.00456461412387824,0 +"1627",2015-02-12 17:54:00,21.89,28.1,0,613.5,0.00456461412387824,0 +"1628",2015-02-12 17:55:00,21.89,28.1,0,616,0.00456461412387824,0 +"1629",2015-02-12 17:55:59,21.89,28.05,0,622.5,0.00455643253669716,0 +"1630",2015-02-12 17:57:00,21.89,28,0,618.666666666667,0.00454825116318119,0 +"1631",2015-02-12 17:57:59,21.89,28,0,612,0.00454825116318119,0 +"1632",2015-02-12 17:58:59,21.89,28,0,610,0.00454825116318119,0 +"1633",2015-02-12 18:00:00,21.89,28,0,603.5,0.00454825116318119,0 +"1634",2015-02-12 18:01:00,21.89,28,0,611,0.00454825116318119,0 +"1635",2015-02-12 18:02:00,21.89,28,0,609.5,0.00454825116318119,0 +"1636",2015-02-12 18:03:00,21.89,28,0,606.5,0.00454825116318119,0 +"1637",2015-02-12 18:04:00,21.89,27.945,0,610,0.00453925189908682,0 +"1638",2015-02-12 18:04:59,21.89,28,0,607,0.00454825116318119,0 +"1639",2015-02-12 18:06:00,21.89,27.945,0,606,0.00453925189908682,0 +"1640",2015-02-12 18:07:00,21.89,27.945,0,612.5,0.00453925189908682,0 +"1641",2015-02-12 18:08:00,21.89,28,0,611.666666666667,0.00454825116318119,0 +"1642",2015-02-12 18:08:59,21.89,28,0,617,0.00454825116318119,0 +"1643",2015-02-12 18:10:00,21.89,28.05,0,608.5,0.00455643253669716,0 +"1644",2015-02-12 18:10:59,21.89,28,0,606,0.00454825116318119,0 +"1645",2015-02-12 18:11:59,21.89,28.0333333333333,0,612.5,0.00455370538845169,0 +"1646",2015-02-12 18:13:00,21.89,28.3,0,610.5,0.00459734260942091,0 +"1647",2015-02-12 18:14:00,21.89,28.1966666666667,0,612.666666666667,0.00458043246498535,0 +"1648",2015-02-12 18:15:00,21.89,28.54,0,610,0.00463662130561013,0 +"1649",2015-02-12 18:16:00,21.89,28.1,0,600,0.00456461412387824,0 +"1650",2015-02-12 18:16:59,21.89,28.4633333333333,0,603.666666666667,0.00462407340905389,0 +"1651",2015-02-12 18:17:59,21.89,28.2966666666667,0,601.666666666667,0.00459679710664399,0 +"1652",2015-02-12 18:19:00,21.89,28.1,0,599,0.00456461412387824,0 +"1653",2015-02-12 18:20:00,21.89,28.245,0,599,0.00458834193505678,0 +"1654",2015-02-12 18:21:00,21.89,28.15,0,597,0.00457279592473277,0 +"1655",2015-02-12 18:22:00,21.89,28.1,0,599.5,0.00456461412387824,0 +"1656",2015-02-12 18:23:00,21.89,28.1,0,597,0.00456461412387824,0 +"1657",2015-02-12 18:23:59,21.84,28.05,0,597.5,0.00454244138277123,0 +"1658",2015-02-12 18:24:59,21.84,28.05,0,597.5,0.00454244138277123,0 +"1659",2015-02-12 18:26:00,21.8233333333333,28.0666666666667,0,595.666666666667,0.00454050202688189,0 +"1660",2015-02-12 18:27:00,21.79,28.05,0,594.5,0.00452848815069892,0 +"1661",2015-02-12 18:28:00,21.79,28.05,0,592,0.00452848815069892,0 +"1662",2015-02-12 18:29:00,21.79,28.05,0,595,0.00452848815069892,0 +"1663",2015-02-12 18:29:59,21.79,28.1,0,597,0.00453661919727976,0 +"1664",2015-02-12 18:30:59,21.79,28,0,592,0.004520357315161,0 +"1665",2015-02-12 18:32:00,21.79,28.1,0,589.5,0.00453661919727976,0 +"1666",2015-02-12 18:33:00,21.745,28.05,0,591.5,0.0045159625915127,0 +"1667",2015-02-12 18:34:00,21.79,28.05,0,594.5,0.00452848815069892,0 +"1668",2015-02-12 18:35:00,21.79,28.1,0,594,0.00453661919727976,0 +"1669",2015-02-12 18:36:00,21.745,28.1,0,591,0.00452407098565056,0 +"1670",2015-02-12 18:36:59,21.7,28.1,0,594,0.00451155341017895,0 +"1671",2015-02-12 18:38:00,21.7,28.1,0,591.5,0.00451155341017895,0 +"1672",2015-02-12 18:39:00,21.7,28.1,0,587.5,0.00451155341017895,0 +"1673",2015-02-12 18:40:00,21.7,28.1,0,584.5,0.00451155341017895,0 +"1674",2015-02-12 18:40:59,21.7,28.1,0,582,0.00451155341017895,0 +"1675",2015-02-12 18:42:00,21.7,28.1,0,582,0.00451155341017895,0 +"1676",2015-02-12 18:42:59,21.7,28.1,0,592,0.00451155341017895,0 +"1677",2015-02-12 18:43:59,21.7,28.1,0,592,0.00451155341017895,0 +"1678",2015-02-12 18:45:00,21.7,28.1,0,585,0.00451155341017895,0 +"1679",2015-02-12 18:46:00,21.6666666666667,28.1,0,579,0.00450230084563674,0 +"1680",2015-02-12 18:47:00,21.7,28.1,0,581,0.00451155341017895,0 +"1681",2015-02-12 18:48:00,21.6,28.1,0,582,0.00448384593489741,0 +"1682",2015-02-12 18:49:00,21.7,28.1,0,581.5,0.00451155341017895,0 +"1683",2015-02-12 18:49:59,21.65,28.1,0,579.5,0.00449768084557703,0 +"1684",2015-02-12 18:51:00,21.6,28.1,0,579.666666666667,0.00448384593489741,0 +"1685",2015-02-12 18:52:00,21.6,28.1,0,582.5,0.00448384593489741,0 +"1686",2015-02-12 18:53:00,21.6,28.1,0,585,0.00448384593489741,0 +"1687",2015-02-12 18:53:59,21.6,28.1,0,584,0.00448384593489741,0 +"1688",2015-02-12 18:55:00,21.6,28,0,579.5,0.00446777457180305,0 +"1689",2015-02-12 18:55:59,21.6,28.0666666666667,0,583,0.00447848872224592,0 +"1690",2015-02-12 18:56:59,21.6,28,0,584,0.00446777457180305,0 +"1691",2015-02-12 18:58:00,21.5666666666667,28.1333333333333,0,577.666666666667,0.00447998976689538,0 +"1692",2015-02-12 18:59:00,21.5,28.1333333333333,0,576,0.0044616128661834,0 +"1693",2015-02-12 19:00:00,21.5,28.1,0,576.5,0.00445628872178248,0 +"1694",2015-02-12 19:01:00,21.5,28.1,0,573.5,0.00445628872178248,0 +"1695",2015-02-12 19:01:59,21.5,28.1,0,574,0.00445628872178248,0 +"1696",2015-02-12 19:02:59,21.5,28.1333333333333,0,575.333333333333,0.0044616128661834,0 +"1697",2015-02-12 19:04:00,21.5,28.2,0,576,0.00447226142648379,0 +"1698",2015-02-12 19:05:00,21.5,28.29,0,576,0.00448663755713656,0 +"1699",2015-02-12 19:06:00,21.5,28.245,0,570.5,0.00447944940933615,0 +"1700",2015-02-12 19:07:00,21.5,28.1333333333333,0,566,0.0044616128661834,0 +"1701",2015-02-12 19:08:00,21.5,28.2,0,567,0.00447226142648379,0 +"1702",2015-02-12 19:08:59,21.5,28.245,0,566,0.00447944940933615,0 +"1703",2015-02-12 19:09:59,21.5,28.29,0,563,0.00448663755713656,0 +"1704",2015-02-12 19:11:00,21.5,28.29,0,564,0.00448663755713656,0 +"1705",2015-02-12 19:12:00,21.5,28.1,0,566.333333333333,0.00445628872178248,0 +"1706",2015-02-12 19:13:00,21.39,28.15,0,567,0.00443408035150574,0 +"1707",2015-02-12 19:14:00,21.5,28.2,0,565,0.00447226142648379,0 +"1708",2015-02-12 19:14:59,21.445,28.05,0,567,0.00443323724000741,0 +"1709",2015-02-12 19:15:59,21.5,28.1,0,569,0.00445628872178248,0 +"1710",2015-02-12 19:17:00,21.445,28.05,0,568.5,0.00443323724000741,0 +"1711",2015-02-12 19:18:00,21.5,28.445,0,565.5,0.00451139799553777,0 +"1712",2015-02-12 19:19:00,21.5,28.4,0,565.666666666667,0.00450420927953948,0 +"1713",2015-02-12 19:20:00,21.5,28.1,0,566,0.00445628872178248,0 +"1714",2015-02-12 19:21:00,21.5,28.1,0,573.333333333333,0.00445628872178248,0 +"1715",2015-02-12 19:21:59,21.4633333333333,28.3633333333333,0,570.333333333333,0.0044881894252806,0 +"1716",2015-02-12 19:23:00,21.5,28.445,0,572.5,0.00451139799553777,0 +"1717",2015-02-12 19:24:00,21.445,28.54,0,572,0.00451124228127941,0 +"1718",2015-02-12 19:25:00,21.39,28.445,0,564.5,0.00448088237320175,0 +"1719",2015-02-12 19:25:59,21.5,28.45,0,566.5,0.00451219675194323,0 +"1720",2015-02-12 19:27:00,21.39,28.1,0,569,0.00442614849849983,0 +"1721",2015-02-12 19:27:59,21.5,28.39,0,565,0.00450261180949863,0 +"1722",2015-02-12 19:28:59,21.445,28.05,0,570.5,0.00443323724000741,0 +"1723",2015-02-12 19:30:00,21.4266666666667,28.1333333333333,0,566.333333333333,0.00444147513369604,0 +"1724",2015-02-12 19:31:00,21.39,27.89,0,567,0.00439283690920249,0 +"1725",2015-02-12 19:32:00,21.39,28.0966666666667,0,568.666666666667,0.0044256197154413,0 +"1726",2015-02-12 19:33:00,21.5,28.1,0,569,0.00445628872178248,0 +"1727",2015-02-12 19:34:00,21.39,27.945,0,563,0.00440156103062751,0 +"1728",2015-02-12 19:34:59,21.39,27.96,0,566.666666666667,0.00440394037864638,0 +"1729",2015-02-12 19:36:00,21.39,28.0233333333333,0,561.666666666667,0.00441398671400737,0 +"1730",2015-02-12 19:37:00,21.39,27.89,0,567,0.00439283690920249,0 +"1731",2015-02-12 19:38:00,21.39,27.89,0,563,0.00439283690920249,0 +"1732",2015-02-12 19:38:59,21.39,27.89,0,561,0.00439283690920249,0 +"1733",2015-02-12 19:40:00,21.39,27.79,0,563.5,0.00437697549281461,0 +"1734",2015-02-12 19:40:59,21.39,27.79,0,570.5,0.00437697549281461,0 +"1735",2015-02-12 19:41:59,21.34,28.14,0,565.5,0.00441883373969639,0 +"1736",2015-02-12 19:43:00,21.34,27.79,0,568,0.00436348755838157,0 +"1737",2015-02-12 19:44:00,21.39,27.79,0,566,0.00437697549281461,0 +"1738",2015-02-12 19:45:00,21.3233333333333,27.79,0,562.333333333333,0.0043589997371483,0 +"1739",2015-02-12 19:46:00,21.39,27.79,0,563,0.00437697549281461,0 +"1740",2015-02-12 19:46:59,21.29,27.79,0,562,0.00435003631085442,0 +"1741",2015-02-12 19:47:59,21.29,27.7,0,559,0.00433585018754098,0 +"1742",2015-02-12 19:49:00,21.3566666666667,27.79,0,558.333333333333,0.00436797945593634,0 +"1743",2015-02-12 19:50:00,21.29,27.745,0,565.5,0.00434294316887186,0 +"1744",2015-02-12 19:51:00,21.29,27.79,0,567,0.00435003631085442,0 +"1745",2015-02-12 19:52:00,21.29,27.7,0,570,0.00433585018754098,0 +"1746",2015-02-12 19:53:00,21.29,27.7,0,568,0.00433585018754098,0 +"1747",2015-02-12 19:53:59,21.29,27.7,0,567.5,0.00433585018754098,0 +"1748",2015-02-12 19:54:59,21.29,27.79,0,566,0.00435003631085442,0 +"1749",2015-02-12 19:56:00,21.29,27.895,0,567.5,0.00436658760026758,0 +"1750",2015-02-12 19:57:00,21.29,27.79,0,564,0.00435003631085442,0 +"1751",2015-02-12 19:58:00,21.29,27.745,0,559,0.00434294316887186,0 +"1752",2015-02-12 19:59:00,21.29,27.745,0,558,0.00434294316887186,0 +"1753",2015-02-12 19:59:59,21.29,28.33,0,560,0.00443516654746327,0 +"1754",2015-02-12 20:00:59,21.29,27.89,0,558,0.00436579942379362,0 +"1755",2015-02-12 20:02:00,21.29,27.84,0,563,0.0043579177681492,0 +"1756",2015-02-12 20:03:00,21.29,27.89,0,565,0.00436579942379362,0 +"1757",2015-02-12 20:04:00,21.245,28.05,0,559.5,0.00437883266450429,0 +"1758",2015-02-12 20:05:00,21.23,27.8933333333333,0,557.666666666667,0.00435017100380359,0 +"1759",2015-02-12 20:06:00,21.29,27.945,0,558,0.00437446947410525,0 +"1760",2015-02-12 20:06:59,21.29,28.145,0,556.5,0.00440599895318441,0 +"1761",2015-02-12 20:08:00,21.2,27.745,0,559,0.00431886270019278,0 +"1762",2015-02-12 20:09:00,21.26,27.93,0,557.666666666667,0.00436401057644065,0 +"1763",2015-02-12 20:10:00,21.245,27.795,0,556,0.00433874741799393,0 +"1764",2015-02-12 20:10:59,21.23,27.7,0,558,0.00431980984000691,0 +"1765",2015-02-12 20:12:00,21.2,27.6333333333333,0,561,0.00430136015567016,0 +"1766",2015-02-12 20:12:59,21.2,27.575,0,562,0.00429221742436988,0 +"1767",2015-02-12 20:13:59,21.2,27.5,0,558.5,0.00428046287634404,0 +"1768",2015-02-12 20:15:00,21.2,27.6,0,553.5,0.00429613570509869,0 +"1769",2015-02-12 20:16:00,21.2,27.695,0,558.5,0.00431102561901404,0 +"1770",2015-02-12 20:17:00,21.2,27.6,0,559.5,0.00429613570509869,0 +"1771",2015-02-12 20:18:00,21.2,27.5,0,562,0.00428046287634404,0 +"1772",2015-02-12 20:19:00,21.2,27.5,0,564.5,0.00428046287634404,0 +"1773",2015-02-12 20:19:59,21.2,27.89,0,566,0.0043415913447783,0 +"1774",2015-02-12 20:21:00,21.2,27.995,0,559,0.00435805104825176,0 +"1775",2015-02-12 20:22:00,21.2,28.26,0,559,0.0043995960517114,0 +"1776",2015-02-12 20:23:00,21.2,28.09,0,561,0.00437294390636749,0 +"1777",2015-02-12 20:23:59,21.2,27.55,0,562,0.00428829919266845,0 +"1778",2015-02-12 20:25:00,21.2,27.8,0,564,0.00432748371602507,0 +"1779",2015-02-12 20:25:59,21.2,27.5,0,564,0.00428046287634404,0 +"1780",2015-02-12 20:26:59,21.23,27.5,0,567,0.00428840483676946,0 +"1781",2015-02-12 20:28:00,21.2,27.39,0,563,0.00426322367068653,0 +"1782",2015-02-12 20:29:00,21.2,27.395,0,552.5,0.00426400725035446,0 +"1783",2015-02-12 20:30:00,21.23,27.9966666666667,0,559,0.00436639972949679,0 +"1784",2015-02-12 20:31:00,21.2,27.59,0,562.5,0.00429456838692382,0 +"1785",2015-02-12 20:31:59,21.2,27.7,0,558,0.00431180931830607,0 +"1786",2015-02-12 20:32:59,21.2,28.745,0,559,0.00447564552181432,0 +"1787",2015-02-12 20:34:00,21.2,28.5,0,561,0.00443722647133208,0 +"1788",2015-02-12 20:35:00,21.2,28.7,0,559.5,0.00446858860823996,0 +"1789",2015-02-12 20:36:00,21.2,27.5633333333333,0,567,0.00429038891014142,0 +"1790",2015-02-12 20:37:00,21.2,27.39,0,564,0.00426322367068653,0 +"1791",2015-02-12 20:38:00,21.245,28.1,0,562,0.00438669311842625,0 +"1792",2015-02-12 20:38:59,21.2,28.245,0,563,0.00439724430059451,0 +"1793",2015-02-12 20:39:59,21.2,27.53,0,563,0.0042851646426064,0 +"1794",2015-02-12 20:41:00,21.2,27.645,0,566,0.00430318873396246,0 +"1795",2015-02-12 20:42:00,21.2,27.995,0,566.5,0.00435805104825176,0 +"1796",2015-02-12 20:43:00,21.2,27.5,0,564,0.00428046287634404,0 +"1797",2015-02-12 20:44:00,21.2,27.4933333333333,0,561.333333333333,0.00427941804898394,0 +"1798",2015-02-12 20:44:59,21.2,27.29,0,559,0.00424755248909092,0 +"1799",2015-02-12 20:45:59,21.2,27.395,0,554.5,0.00426400725035446,0 +"1800",2015-02-12 20:47:00,21.2,27.29,0,553,0.00424755248909092,0 +"1801",2015-02-12 20:48:00,21.2,27.2,0,554.5,0.00423344909620756,0 +"1802",2015-02-12 20:49:00,21.23,27.36,0,563,0.00426642320834649,0 +"1803",2015-02-12 20:50:00,21.29,28,0,562,0.00438313976443897,0 +"1804",2015-02-12 20:51:00,21.2,27.99,0,561.666666666667,0.00435726723323166,0 +"1805",2015-02-12 20:51:59,21.2,27.5233333333333,0,562,0.00428411979955829,0 +"1806",2015-02-12 20:53:00,21.2,27.545,0,565,0.00428751555221137,0 +"1807",2015-02-12 20:54:00,21.2,27.5933333333333,0,567.333333333333,0.00429509082544384,0 +"1808",2015-02-12 20:55:00,21.2,27.29,0,566,0.00424755248909092,0 +"1809",2015-02-12 20:55:59,21.2,27.15,0,567,0.0042256141524178,0 +"1810",2015-02-12 20:57:00,21.2,27.34,0,561.5,0.00425538798185127,0 +"1811",2015-02-12 20:57:59,21.2,27.295,0,571,0.0042483360295438,0 +"1812",2015-02-12 20:58:59,21.2,27.6,0,574,0.00429613570509869,0 +"1813",2015-02-12 21:00:00,21.2,27.395,0,564.5,0.00426400725035446,0 +"1814",2015-02-12 21:01:00,21.2,27.245,0,570.5,0.00424050071324457,0 +"1815",2015-02-12 21:02:00,21.2,27.1,0,560,0.00421777940467497,0 +"1816",2015-02-12 21:03:00,21.2,27.195,0,564,0.00423266559300627,0 +"1817",2015-02-12 21:04:00,21.2,27,0,569,0.00420211049730072,0 +"1818",2015-02-12 21:04:59,21.2,27.05,0,569.5,0.00420994485297173,0 +"1819",2015-02-12 21:06:00,21.245,27.495,0,568.5,0.00429159487245356,0 +"1820",2015-02-12 21:07:00,21.2,27.36,0,568.666666666667,0.00425852223385598,0 +"1821",2015-02-12 21:08:00,21.2,27.3,0,566,0.00424911957195736,0 +"1822",2015-02-12 21:08:59,21.2,27.05,0,565,0.00420994485297173,0 +"1823",2015-02-12 21:10:00,21.2,27,0,563,0.00420211049730072,0 +"1824",2015-02-12 21:10:59,21.2,27.145,0,557.5,0.00422483066882152,0 +"1825",2015-02-12 21:11:59,21.15,27.84,0,560,0.00432038036026393,0 +"1826",2015-02-12 21:13:00,21.2,27.1,0,565,0.00421777940467497,0 +"1827",2015-02-12 21:14:00,21.2,26.9633333333333,0,566,0.00419636542772708,0 +"1828",2015-02-12 21:15:00,21.1333333333333,26.93,0,570.666666666667,0.00417391012609193,0 +"1829",2015-02-12 21:16:00,21.2,27.195,0,571,0.00423266559300627,0 +"1830",2015-02-12 21:16:59,21.2,27.745,0,572,0.00431886270019278,0 +"1831",2015-02-12 21:17:59,21.2,27.29,0,567,0.00424755248909092,0 +"1832",2015-02-12 21:19:00,21.1666666666667,27.1333333333333,0,569,0.0042143124185732,0 +"1833",2015-02-12 21:20:00,21.2,27,0,569,0.00420211049730072,0 +"1834",2015-02-12 21:21:00,21.2,26.79,0,570,0.00416920834398832,0 +"1835",2015-02-12 21:22:00,21.2,27.2266666666667,0,574.333333333333,0.00423762781305939,0 +"1836",2015-02-12 21:23:00,21.2,26.895,0,571,0.00418565898844375,0 +"1837",2015-02-12 21:23:59,21.15,27.09,0,565.5,0.00420320429335989,0 +"1838",2015-02-12 21:24:59,21.15,26.895,0,561.5,0.00417274569728117,0 +"1839",2015-02-12 21:26:00,21.15,26.945,0,564.5,0.00418055531123749,0 +"1840",2015-02-12 21:27:00,21.2,26.84,0,566.5,0.00417704187640432,0 +"1841",2015-02-12 21:28:00,21.2,27.26,0,570.333333333333,0.00424285128754761,0 +"1842",2015-02-12 21:29:00,21.1333333333333,27.13,0,564.666666666667,0.00420511791241738,0 +"1843",2015-02-12 21:29:59,21.15,27.09,0,563,0.00420320429335989,0 +"1844",2015-02-12 21:30:59,21.1333333333333,27.1,0,566,0.00420043654616163,0 +"1845",2015-02-12 21:32:00,21.1333333333333,27.1633333333333,0,562.666666666667,0.00421031951257194,0 +"1846",2015-02-12 21:33:00,21.1,27.145,0,563,0.00419879625315612,0 +"1847",2015-02-12 21:34:00,21.15,27.895,0,564.5,0.00432897499769287,0 +"1848",2015-02-12 21:35:00,21.1,27.15,0,564.5,0.00419957487636183,0 +"1849",2015-02-12 21:36:00,21.1,27.495,0,563,0.00425330455411939,0 +"1850",2015-02-12 21:36:59,21.15,27.4,0,561,0.00425163175141405,0 +"1851",2015-02-12 21:38:00,21.1,27.79,0,564,0.00429925463532297,0 +"1852",2015-02-12 21:39:00,21.1,27.3,0,562.333333333333,0.00422293447294578,0 +"1853",2015-02-12 21:40:00,21.1,26.995,0,567,0.00417543845732926,0 +"1854",2015-02-12 21:40:59,21.1,27.79,0,570,0.00429925463532297,0 +"1855",2015-02-12 21:42:00,21.1,27.65,0,572.5,0.00427744697645937,0 +"1856",2015-02-12 21:42:59,21.1,27,0,569,0.00417621702244928,0 +"1857",2015-02-12 21:43:59,21.1,27.2,0,565.5,0.0042073612149167,0 +"1858",2015-02-12 21:45:00,21.1,26.745,0,559.5,0.00413651266967687,0 +"1859",2015-02-12 21:46:00,21.1,27.445,0,563.5,0.00424551707299958,0 +"1860",2015-02-12 21:47:00,21.1,27.7,0,561,0.00428523525171311,0 +"1861",2015-02-12 21:48:00,21.1,27.09,0,567,0.00419023152568716,0 +"1862",2015-02-12 21:49:00,21.05,27.05,0,567.5,0.0041710847062305,0 +"1863",2015-02-12 21:49:59,21.1,26.9266666666667,0,562,0.0041647982613906,0 +"1864",2015-02-12 21:51:00,21.1,26.89,0,558,0.00415908903703165,0 +"1865",2015-02-12 21:52:00,21.1,26.96,0,563.666666666667,0.00416998855569889,0 +"1866",2015-02-12 21:53:00,21.1,27.9,0,573,0.00431639028989664,0 +"1867",2015-02-12 21:53:59,21.0666666666667,27.2966666666667,0,572,0.00421371975376013,0 +"1868",2015-02-12 21:55:00,21.1,27,0,567,0.00417621702244928,0 +"1869",2015-02-12 21:55:59,21.1,27.7,0,567,0.00428523525171311,0 +"1870",2015-02-12 21:56:59,21.1,27.35,0,567.5,0.00423072139243445,0 +"1871",2015-02-12 21:58:00,21.05,27.05,0,568,0.0041710847062305,0 +"1872",2015-02-12 21:59:00,21.1,27.695,0,565.5,0.00428445641547093,0 +"1873",2015-02-12 22:00:00,21.0333333333333,27.3933333333333,0,562.333333333333,0.00422003245018561,0 +"1874",2015-02-12 22:01:00,21,28.89,0,565,0.00444307224265842,0 +"1875",2015-02-12 22:01:59,21.05,27.39,0,563,0.00422386841343422,0 +"1876",2015-02-12 22:02:59,21.05,26.995,0,563.5,0.00416254700147465,0 +"1877",2015-02-12 22:04:00,21.05,26.645,0,564,0.00410822160745695,0 +"1878",2015-02-12 22:05:00,21.1,27.445,0,563.5,0.00424551707299958,0 +"1879",2015-02-12 22:06:00,21.1,27.195,0,569,0.00420658257234765,0 +"1880",2015-02-12 22:07:00,21,27.09,0,568,0.00416439190999257,0 +"1881",2015-02-12 22:08:00,21.05,27.745,0,567,0.00427899031090637,0 +"1882",2015-02-12 22:08:59,21,27.145,0,569,0.00417290346997903,0 +"1883",2015-02-12 22:09:59,21,27.545,0,566.5,0.00423481268618378,0 +"1884",2015-02-12 22:11:00,21,26.39,0,563,0.00405608317481411,0 +"1885",2015-02-12 22:12:00,21,26.29,0,563,0.00404061355695366,0 +"1886",2015-02-12 22:13:00,21,26.8933333333333,0,562,0.00413395852781716,0 +"1887",2015-02-12 22:14:00,21,27.1266666666667,0,563.666666666667,0.00417006625760609,0 +"1888",2015-02-12 22:14:59,21,26.7666666666667,0,564.333333333333,0.0041143589326253,0 +"1889",2015-02-12 22:15:59,21,27.39,0,562,0.0042108214121992,0 +"1890",2015-02-12 22:17:00,21,27.0675,0,559.75,0.00416090997487297,0 +"1891",2015-02-12 22:18:00,21.1,27,0,564,0.00417621702244928,0 +"1892",2015-02-12 22:19:00,21,26.5933333333333,0,559.666666666667,0.004087540422265,0 +"1893",2015-02-12 22:20:00,21,27.39,0,559,0.0042108214121992,0 +"1894",2015-02-12 22:21:00,21,26.55,0,559.5,0.00408083615364728,0 +"1895",2015-02-12 22:21:59,21,26.495,0,561.5,0.00407232709639943,0 +"1896",2015-02-12 22:23:00,21,26.445,0,559,0.00406459179051679,0 +"1897",2015-02-12 22:24:00,21,26.79,0,560,0.00411796929217306,0 +"1898",2015-02-12 22:25:00,21,26.65,0,563.5,0.00409630775941671,0 +"1899",2015-02-12 22:25:59,21,26.695,0,562,0.0041032702314872,0 +"1900",2015-02-12 22:27:00,21,26.95,0,560,0.00414272716504623,0 +"1901",2015-02-12 22:27:59,21,26.945,0,565,0.00414195345188212,0 +"1902",2015-02-12 22:28:59,21,27.1233333333333,0,562.333333333333,0.00416955040357335,0 +"1903",2015-02-12 22:30:00,21,26.55,0,566,0.00408083615364728,0 +"1904",2015-02-12 22:31:00,21,27,0,567,0.00415046440185575,0 +"1905",2015-02-12 22:32:00,21,26.34,0,568.5,0.00404834827032055,0 +"1906",2015-02-12 22:33:00,21,26.2425,0,561.25,0.00403326575627974,0 +"1907",2015-02-12 22:34:00,21,26.5,0,565,0.00407310063750076,0 +"1908",2015-02-12 22:34:59,21,26.89,0,565,0.00413344273327552,0 +"1909",2015-02-12 22:36:00,21,27.145,0,572,0.00417290346997903,0 +"1910",2015-02-12 22:37:00,21,27.1933333333333,0,564.333333333333,0.00418038351675268,0 +"1911",2015-02-12 22:38:00,21,26.745,0,568,0.00411100649318388,0 +"1912",2015-02-12 22:38:59,21,26.695,0,565.5,0.0041032702314872,0 +"1913",2015-02-12 22:40:00,21,26.39,0,565,0.00405608317481411,0 +"1914",2015-02-12 22:40:59,21,26.2,0,567,0.00402669155450986,0 +"1915",2015-02-12 22:41:59,21,26.29,0,563,0.00404061355695366,0 +"1916",2015-02-12 22:43:00,21,26.395,0,559,0.00405685667577571,0 +"1917",2015-02-12 22:44:00,21,26.745,0,564,0.00411100649318388,0 +"1918",2015-02-12 22:45:00,21,26.85,0,563,0.00412725326505949,0 +"1919",2015-02-12 22:46:00,21,26.245,0,561,0.0040336524783309,0 +"1920",2015-02-12 22:46:59,21,27.55,0,566.5,0.00423558662885426,0 +"1921",2015-02-12 22:47:59,21,27,0,573,0.00415046440185575,0 +"1922",2015-02-12 22:49:00,21,26.29,0,569.5,0.00404061355695366,0 +"1923",2015-02-12 22:50:00,21,26.65,0,567,0.00409630775941671,0 +"1924",2015-02-12 22:51:00,21,26.1,0,567,0.00401122338910984,0 +"1925",2015-02-12 22:52:00,21,26.9966666666667,0,564.666666666667,0.00414994858011945,0 +"1926",2015-02-12 22:53:00,21,26.1,0,563,0.00401122338910984,0 +"1927",2015-02-12 22:53:59,21,26.295,0,562,0.00404138701968985,0 +"1928",2015-02-12 22:54:59,21,26.6966666666667,0,560,0.00410352810379698,0 +"1929",2015-02-12 22:56:00,21,26.75,0,558,0.00411178012986855,0 +"1930",2015-02-12 22:57:00,21,26.695,0,563,0.0041032702314872,0 +"1931",2015-02-12 22:58:00,21,26.695,0,565,0.0041032702314872,0 +"1932",2015-02-12 22:59:00,20.9725,26.2975,0,569,0.00403490239281645,0 +"1933",2015-02-12 22:59:59,21,26.33,0,567,0.00404680131235726,0 +"1934",2015-02-12 23:00:59,20.9633333333333,26.3,0,569.333333333333,0.00403300008101889,0 +"1935",2015-02-12 23:02:00,21,26.29,0,571,0.00404061355695366,0 +"1936",2015-02-12 23:03:00,21,26.645,0,567,0.00409553416096751,0 +"1937",2015-02-12 23:04:00,21,26.3933333333333,0,566,0.00405659884190947,0 +"1938",2015-02-12 23:05:00,21,26,0,569,0.00399575598808051,0 +"1939",2015-02-12 23:06:00,21,25.995,0,567.5,0.00399498263809276,0 +"1940",2015-02-12 23:06:59,21,25.84,0,565.5,0.00397100973618322,0 +"1941",2015-02-12 23:08:00,21,26.05,0,568,0.00400348959305238,0 +"1942",2015-02-12 23:09:00,21,25.745,0,564,0.00395631757479967,0 +"1943",2015-02-12 23:10:00,21,26,0,568,0.00399575598808051,0 +"1944",2015-02-12 23:10:59,21,26.5,0,568,0.00407310063750076,0 +"1945",2015-02-12 23:12:00,21,26.3,0,570,0.00404216048433724,0 +"1946",2015-02-12 23:12:59,21,26.245,0,569.5,0.0040336524783309,0 +"1947",2015-02-12 23:13:59,21,25.8966666666667,0,567.333333333333,0.00397977380997057,0 +"1948",2015-02-12 23:15:00,21,25.7,0,570,0.00394935837065017,0 +"1949",2015-02-12 23:16:00,21,25.745,0,568,0.00395631757479967,0 +"1950",2015-02-12 23:17:00,21,25.89,0,566,0.00397874272972879,0 +"1951",2015-02-12 23:18:00,21,25.895,0,567,0.00397951603959169,0 +"1952",2015-02-12 23:19:00,21,26.14,0,567.5,0.00401741056354219,0 +"1953",2015-02-12 23:19:59,21,26.0633333333333,0,567,0.00400555191998348,0 +"1954",2015-02-12 23:21:00,21,26.445,0,566,0.00406459179051679,0 +"1955",2015-02-12 23:22:00,21,26.36,0,567.666666666667,0.00405144220918237,0 +"1956",2015-02-12 23:23:00,21,26.0333333333333,0,572,0.00400091170349704,0 +"1957",2015-02-12 23:23:59,21,26.2,0,574,0.00402669155450986,0 +"1958",2015-02-12 23:25:00,21,26.945,0,562,0.00414195345188212,0 +"1959",2015-02-12 23:25:59,21,26.35,0,564.5,0.0040498952359289,0 +"1960",2015-02-12 23:26:59,21,26.495,0,568.5,0.00407232709639943,0 +"1961",2015-02-12 23:28:00,21,26.39,0,571,0.00405608317481411,0 +"1962",2015-02-12 23:29:00,21,25.87,0,564.25,0.00397564950938341,0 +"1963",2015-02-12 23:30:00,21,25.795,0,569,0.00396405020534517,0 +"1964",2015-02-12 23:31:00,21,26.26,0,574,0.00403597282067138,0 +"1965",2015-02-12 23:31:59,21,25.995,0,571.5,0.00399498263809276,0 +"1966",2015-02-12 23:32:59,21,26.045,0,570,0.00400271622395646,0 +"1967",2015-02-12 23:34:00,21,26.245,0,570.5,0.00403365247833091,0 +"1968",2015-02-12 23:35:00,21,26.6,0,570,0.00408857186095024,0 +"1969",2015-02-12 23:36:00,21,26.39,0,570,0.00405608317481411,0 +"1970",2015-02-12 23:37:00,21,26.19,0,565.666666666667,0.00402514470357156,0 +"1971",2015-02-12 23:38:00,21,26.6633333333333,0,566,0.00409837069796074,0 +"1972",2015-02-12 23:38:59,21,25.7933333333333,0,565.333333333333,0.00396379244791568,0 +"1973",2015-02-12 23:39:59,21,25.64,0,568.5,0.00394007967248868,0 +"1974",2015-02-12 23:41:00,21,26.0475,0,566,0.00400310290826556,0 +"1975",2015-02-12 23:42:00,21,26.29,0,572,0.00404061355695366,0 +"1976",2015-02-12 23:43:00,21,25.89,0,571,0.00397874272972879,0 +"1977",2015-02-12 23:44:00,21,25.745,0,571,0.00395631757479967,0 +"1978",2015-02-12 23:44:59,21,25.65,0,570,0.00394162610307918,0 +"1979",2015-02-12 23:45:59,21,26.295,0,568,0.00404138701968985,0 +"1980",2015-02-12 23:47:00,21,26.06,0,574,0.0040050363369768,0 +"1981",2015-02-12 23:48:00,21,25.95,0,578.5,0.00398802257418715,0 +"1982",2015-02-12 23:49:00,21,25.85,0,579,0.00397255631960764,0 +"1983",2015-02-12 23:50:00,21,25.8,0,573.5,0.00396482347890733,0 +"1984",2015-02-12 23:51:00,21,25.59,0,573,0.00393234763415156,0 +"1985",2015-02-12 23:51:59,21,26.395,0,566.5,0.00405685667577571,0 +"1986",2015-02-12 23:53:00,21,25.995,0,565,0.00399498263809276,0 +"1987",2015-02-12 23:54:00,21,25.9966666666667,0,563.666666666667,0.0039952404212097,0 +"1988",2015-02-12 23:55:00,21,26.1,0,567,0.00401122338910984,0 +"1989",2015-02-12 23:55:59,21,25.55,0,567.5,0.00392616214101694,0 +"1990",2015-02-12 23:57:00,21,25.35,0,569,0.00389523650901331,0 +"1991",2015-02-12 23:57:59,21,25.2,0,566,0.00387204429039337,0 +"1992",2015-02-12 23:58:59,21,25.1966666666667,0,567,0.00387152892727897,0 +"1993",2015-02-13 00:00:00,21.05,25.59,0,568.5,0.00394452636448711,0 +"1994",2015-02-13 00:01:00,21,25.395,0,571,0.00390219450977186,0 +"1995",2015-02-13 00:02:00,21,25.945,0,566.5,0.00398724924330686,0 +"1996",2015-02-13 00:03:00,21,25.8333333333333,0,561.666666666667,0.00396997868481263,0 +"1997",2015-02-13 00:04:00,21,25.6475,0,566.25,0.0039412394947152,0 +"1998",2015-02-13 00:04:59,21,25.7,0,568.5,0.00394935837065017,0 +"1999",2015-02-13 00:06:00,21,25.745,0,568,0.00395631757479967,0 +"2000",2015-02-13 00:07:00,21,25.795,0,565,0.00396405020534517,0 +"2001",2015-02-13 00:08:00,21,25.6,0,564,0.00393389402653712,0 +"2002",2015-02-13 00:08:59,21,25.295,0,568,0.00388673249594857,0 +"2003",2015-02-13 00:10:00,21,25.3633333333333,0,569,0.00389729812273972,0 +"2004",2015-02-13 00:10:59,21,25.545,0,573,0.00392538896297085,0 +"2005",2015-02-13 00:11:59,21,26.6,0,573.666666666667,0.00408857186095024,0 +"2006",2015-02-13 00:13:00,21,25.7675,0,571.75,0.00395979723490323,0 +"2007",2015-02-13 00:14:00,21,25.64,0,571.5,0.00394007967248868,0 +"2008",2015-02-13 00:15:00,21,25.05,0,568.5,0.00384885379046066,0 +"2009",2015-02-13 00:16:00,21,25.2,0,562,0.00387204429039337,0 +"2010",2015-02-13 00:16:59,21,25.1,0,562,0.00385658376615144,0 +"2011",2015-02-13 00:17:59,21.05,24.995,0,565.5,0.0038522430952657,0 +"2012",2015-02-13 00:19:00,21,25.295,0,569.5,0.00388673249594857,0 +"2013",2015-02-13 00:20:00,21,25.3,0,567.5,0.00388750557849629,0 +"2014",2015-02-13 00:21:00,21,25.2,0,569,0.00387204429039337,0 +"2015",2015-02-13 00:22:00,21,25.545,0,574,0.00392538896297085,0 +"2016",2015-02-13 00:23:00,21,25.89,0,574,0.00397874272972879,0 +"2017",2015-02-13 00:23:59,21,25.295,0,574,0.00388673249594857,0 +"2018",2015-02-13 00:24:59,21,25.1,0,578.666666666667,0.00385658376615144,0 +"2019",2015-02-13 00:26:00,21,25.66,0,581.666666666667,0.00394317254131083,0 +"2020",2015-02-13 00:27:00,21,25.825,0,582,0.00396868987537577,0 +"2021",2015-02-13 00:28:00,21,25.89,0,577.5,0.00397874272972879,0 +"2022",2015-02-13 00:29:00,21,26.2,0,575,0.00402669155450986,0 +"2023",2015-02-13 00:29:59,21,25.1,0,572,0.00385658376615144,0 +"2024",2015-02-13 00:30:59,21,25.54,0,574.5,0.0039246157868349,0 +"2025",2015-02-13 00:32:00,21,25.55,0,573,0.00392616214101694,0 +"2026",2015-02-13 00:33:00,21,25.4966666666667,0,569.333333333333,0.00391791500700265,0 +"2027",2015-02-13 00:34:00,21,26.09,0,573,0.00400967661461116,0 +"2028",2015-02-13 00:35:00,21,25.76,0,573.666666666667,0.00395863734390355,0 +"2029",2015-02-13 00:36:00,21,25,0,573,0.0038411240057139,0 +"2030",2015-02-13 00:36:59,21,24.84,0,576.5,0.00381638997758567,0 +"2031",2015-02-13 00:38:00,21,25.29,0,574,0.00388595941531064,0 +"2032",2015-02-13 00:39:00,21,25.395,0,569,0.00390219450977186,0 +"2033",2015-02-13 00:40:00,21,25.7,0,573,0.00394935837065017,0 +"2034",2015-02-13 00:40:59,21,25.0266666666667,0,577.333333333333,0.00384524653381734,0 +"2035",2015-02-13 00:42:00,21,24.945,0,575.5,0.00383262146302436,0 +"2036",2015-02-13 00:42:59,21,25.6,0,571,0.00393389402653712,0 +"2037",2015-02-13 00:43:59,21,25.1,0,570,0.00385658376615144,0 +"2038",2015-02-13 00:45:00,21,25.29,0,573,0.00388595941531064,0 +"2039",2015-02-13 00:46:00,21,25.795,0,572,0.00396405020534517,0 +"2040",2015-02-13 00:47:00,21,25.745,0,578,0.00395631757479967,0 +"2041",2015-02-13 00:48:00,21,25.59,0,577.5,0.00393234763415156,0 +"2042",2015-02-13 00:49:00,21,25.195,0,577,0.00387127124604005,0 +"2043",2015-02-13 00:49:59,21,25.26,0,573,0.00388132097158818,0 +"2044",2015-02-13 00:51:00,21,25.1,0,576,0.00385658376615144,0 +"2045",2015-02-13 00:52:00,21,25.16,0,583.666666666667,0.00386585998903645,0 +"2046",2015-02-13 00:53:00,21,25.045,0,582,0.00384808080339362,0 +"2047",2015-02-13 00:53:59,21,24.85,0,575.5,0.00381793579706699,0 +"2048",2015-02-13 00:55:00,21,24.845,0,573,0.00381716288637175,0 +"2049",2015-02-13 00:55:59,21,24.995,0,575.5,0.00384035103774087,0 +"2050",2015-02-13 00:56:59,21,25.195,0,574,0.00387127124604005,0 +"2051",2015-02-13 00:58:00,21,24.89,0,574,0.00382411915135911,0 +"2052",2015-02-13 00:59:00,21,24.9633333333333,0,570,0.00383545561825104,0 +"2053",2015-02-13 01:00:00,21,24.7633333333333,0,579.333333333333,0.0038045389485953,0 +"2054",2015-02-13 01:01:00,21,24.7,0,578,0.00379474930666158,0 +"2055",2015-02-13 01:01:59,21,25.8966666666667,0,570.666666666667,0.00397977380997057,0 +"2056",2015-02-13 01:02:59,21,25.29,0,577,0.00388595941531064,0 +"2057",2015-02-13 01:04:00,21,24.9,0,580,0.00382566500902413,0 +"2058",2015-02-13 01:05:00,21,25.25,0,577.5,0.00387977483895867,0 +"2059",2015-02-13 01:06:00,21,24.745,0,577.5,0.00380170507337921,0 +"2060",2015-02-13 01:07:00,21,24.9266666666667,0,583,0.00382978733346704,0 +"2061",2015-02-13 01:08:00,21,24.65,0,583,0.00378702085832489,0 +"2062",2015-02-13 01:08:59,21,25.05,0,576,0.00384885379046066,0 +"2063",2015-02-13 01:09:59,21,25.1,0,578,0.00385658376615144,0 +"2064",2015-02-13 01:11:00,21,25.29,0,580,0.00388595941531064,0 +"2065",2015-02-13 01:12:00,21,24.83,0,581,0.00381484416574093,0 +"2066",2015-02-13 01:13:00,21,24.945,0,576.5,0.00383262146302436,0 +"2067",2015-02-13 01:14:00,21,25,0,579,0.0038411240057139,0 +"2068",2015-02-13 01:14:59,21,25.39,0,578,0.00390142139093685,0 +"2069",2015-02-13 01:15:59,21,25.09,0,580.5,0.00385503775573742,0 +"2070",2015-02-13 01:17:00,21,24.65,0,575,0.00378702085832489,0 +"2071",2015-02-13 01:18:00,21,24.7666666666667,0,578.666666666667,0.00380505420139207,0 +"2072",2015-02-13 01:19:00,21,24.6,0,578,0.00377929260087562,0 +"2073",2015-02-13 01:20:00,21,25.245,0,574,0.0038790017755085,0 +"2074",2015-02-13 01:21:00,21,24.7666666666667,0,571.666666666667,0.00380505420139207,0 +"2075",2015-02-13 01:21:59,21,24.6,0,571,0.00377929260087562,0 +"2076",2015-02-13 01:23:00,21,24.995,0,568,0.00384035103774087,0 +"2077",2015-02-13 01:24:00,21,25.0933333333333,0,572.666666666667,0.00385555309169343,0 +"2078",2015-02-13 01:25:00,21,24.84,0,569,0.00381638997758567,0 +"2079",2015-02-13 01:25:59,21,25.05,0,572.5,0.00384885379046066,0 +"2080",2015-02-13 01:27:00,21,24.7,0,574,0.00379474930666158,0 +"2081",2015-02-13 01:27:59,21,24.5,0,576,0.0037638366586111,0 +"2082",2015-02-13 01:28:59,21,24.495,0,574,0.00376306388153929,0 +"2083",2015-02-13 01:30:00,21.1,25.1,0,576,0.0038805016282998,0 +"2084",2015-02-13 01:31:00,21,24.6225,0,580.5,0.00378277029310593,0 +"2085",2015-02-13 01:32:00,21,24.6,0,579,0.00377929260087562,0 +"2086",2015-02-13 01:33:00,21,24.5,0,578.5,0.0037638366586111,0 +"2087",2015-02-13 01:34:00,21,24.4966666666667,0,576.333333333333,0.00376332147368449,0 +"2088",2015-02-13 01:34:59,21,24.83,0,580,0.00381484416574093,0 +"2089",2015-02-13 01:36:00,21,24.65,0,579.5,0.00378702085832489,0 +"2090",2015-02-13 01:37:00,21,25.125,0,580.25,0.00386044882560305,0 +"2091",2015-02-13 01:38:00,21,24.6,0,584,0.00377929260087562,0 +"2092",2015-02-13 01:38:59,21,24.545,0,582,0.00377079173814797,0 +"2093",2015-02-13 01:40:00,21.1,24.6,0,575,0.00380272820412541,0 +"2094",2015-02-13 01:40:59,21,24.395,0,570,0.00374760874091139,0 +"2095",2015-02-13 01:41:59,21,25.295,0,579,0.00388673249594857,0 +"2096",2015-02-13 01:43:00,21,24.8,0,575.5,0.00381020677602556,0 +"2097",2015-02-13 01:44:00,21,25.1725,0,585.5,0.00386779257008185,0 +"2098",2015-02-13 01:45:00,21,25.445,0,570.5,0.00390992580316924,0 +"2099",2015-02-13 01:46:00,21,24.79,0,572,0.00380866099472654,0 +"2100",2015-02-13 01:46:59,21,24.6,0,571.5,0.00377929260087562,0 +"2101",2015-02-13 01:47:59,21,25.29,0,573.333333333333,0.00388595941531064,0 +"2102",2015-02-13 01:49:00,21,24.6,0,582,0.00377929260087562,0 +"2103",2015-02-13 01:50:00,21,24.96,0,576,0.00383494031539143,0 +"2104",2015-02-13 01:51:00,21,24.65,0,578.5,0.00378702085832489,0 +"2105",2015-02-13 01:52:00,21,25.45,0,577,0.00391069894301386,0 +"2106",2015-02-13 01:53:00,21,25.09,0,577,0.00385503775573742,0 +"2107",2015-02-13 01:53:59,21,25.26,0,576,0.00388132097158818,0 +"2108",2015-02-13 01:54:59,21,24.7,0,580,0.00379474930666158,0 +"2109",2015-02-13 01:56:00,21,24.745,0,581.5,0.00380170507337921,0 +"2110",2015-02-13 01:57:00,21,24.46,0,584,0.00375765449547862,0 +"2111",2015-02-13 01:58:00,21,24.65,0,583.5,0.00378702085832489,0 +"2112",2015-02-13 01:59:00,21.0333333333333,24.3933333333333,0,585.333333333333,0.00375508254436653,0 +"2113",2015-02-13 01:59:59,21,25.05,0,578,0.00384885379046066,0 +"2114",2015-02-13 02:00:59,21,24.8225,0,579.5,0.00381368481186883,0 +"2115",2015-02-13 02:02:00,21,24.29,0,577.75,0.00373138166486622,0 +"2116",2015-02-13 02:03:00,21,24.8,0,576,0.00381020677602556,0 +"2117",2015-02-13 02:04:00,21,24.7,0,577,0.00379474930666158,0 +"2118",2015-02-13 02:05:00,21,24.495,0,578.5,0.00376306388153929,0 +"2119",2015-02-13 02:06:00,21,24.55,0,577,0.00377156453430672,0 +"2120",2015-02-13 02:06:59,21,25.25,0,575,0.00387977483895867,0 +"2121",2015-02-13 02:08:00,21,24.39,0,578,0.00374683600391986,0 +"2122",2015-02-13 02:09:00,21,24.8,0,576.333333333333,0.00381020677602556,0 +"2123",2015-02-13 02:10:00,21,24.7,0,580,0.00379474930666158,0 +"2124",2015-02-13 02:10:59,21,25.05,0,575.5,0.00384885379046066,0 +"2125",2015-02-13 02:12:00,21,25.1,0,582,0.00385658376615144,0 +"2126",2015-02-13 02:12:59,21,24.9333333333333,0,578.666666666667,0.00383081792306335,0 +"2127",2015-02-13 02:13:59,20.945,24.9,0,574.5,0.00381267132341687,0 +"2128",2015-02-13 02:15:00,21,24.945,0,575,0.00383262146302436,0 +"2129",2015-02-13 02:16:00,21,24.29,0,576,0.00373138166486622,0 +"2130",2015-02-13 02:17:00,21,24.495,0,574.5,0.00376306388153929,0 +"2131",2015-02-13 02:18:00,21,26,0,579,0.00399575598808051,0 +"2132",2015-02-13 02:19:00,21,25.445,0,579,0.00390992580316924,0 +"2133",2015-02-13 02:19:59,20.9633333333333,24.7333333333333,0,581.333333333333,0.00379129364345831,0 +"2134",2015-02-13 02:21:00,21,24.995,0,575,0.00384035103774087,0 +"2135",2015-02-13 02:22:00,20.9633333333333,24.6,0,573,0.00377073150067396,0 +"2136",2015-02-13 02:23:00,21,24.445,0,576,0.00375533621579613,0 +"2137",2015-02-13 02:23:59,20.9266666666667,24.5633333333333,0,577.333333333333,0.00375654603676923,0 +"2138",2015-02-13 02:25:00,21,24.8,0,577,0.00381020677602556,0 +"2139",2015-02-13 02:25:59,21,24.54,0,579.5,0.00377001894389796,0 +"2140",2015-02-13 02:26:59,21,25,0,581,0.0038411240057139,0 +"2141",2015-02-13 02:28:00,21,25.0633333333333,0,581.333333333333,0.00385091509864116,0 +"2142",2015-02-13 02:29:00,21,24.795,0,575,0.00380943388442151,0 +"2143",2015-02-13 02:30:00,20.9633333333333,24.5666666666667,0,574.333333333333,0.00376559117610969,0 +"2144",2015-02-13 02:31:00,20.945,24.9,0,579,0.00381267132341687,0 +"2145",2015-02-13 02:31:59,21,24.34,0,580,0.00373910873897124,0 +"2146",2015-02-13 02:32:59,21,24.745,0,576.5,0.00380170507337921,0 +"2147",2015-02-13 02:34:00,21,24.2,0,577,0.00371747341238045,0 +"2148",2015-02-13 02:35:00,20.9633333333333,24.7633333333333,0,576.333333333333,0.00379592031181207,0 +"2149",2015-02-13 02:36:00,21,24.445,0,579.5,0.00375533621579613,0 +"2150",2015-02-13 02:37:00,21,24.2666666666667,0,578.666666666667,0.00372777576225947,0 +"2151",2015-02-13 02:38:00,21,24.29,0,579,0.00373138166486622,0 +"2152",2015-02-13 02:38:59,20.89,25.1,0,579,0.00383042432009906,0 +"2153",2015-02-13 02:39:59,21,24.2,0,578,0.00371747341238045,0 +"2154",2015-02-13 02:41:00,20.945,25.495,0,578.5,0.00390434920537772,0 +"2155",2015-02-13 02:42:00,20.945,25.34,0,578.5,0.00388046414479331,0 +"2156",2015-02-13 02:43:00,20.89,24.6966666666667,0,586,0.00376850009317768,0 +"2157",2015-02-13 02:44:00,20.89,24.29,0,583,0.00370607650135101,0 +"2158",2015-02-13 02:44:59,20.89,24.245,0,577.5,0.00369916973804848,0 +"2159",2015-02-13 02:45:59,20.89,24.6566666666667,0,576.666666666667,0.00376235951544944,0 +"2160",2015-02-13 02:47:00,20.89,24.39,0,580,0.00372142541017581,0 +"2161",2015-02-13 02:48:00,20.89,24.15,0,577,0.00368458929401908,0 +"2162",2015-02-13 02:49:00,21,24.45,0,581,0.0037561089737817,0 +"2163",2015-02-13 02:50:00,21,25,0,578.666666666667,0.0038411240057139,0 +"2164",2015-02-13 02:51:00,20.89,24.945,0,577.5,0.003806625543353,0 +"2165",2015-02-13 02:51:59,20.89,24.6,0,578,0.00375366056996012,0 +"2166",2015-02-13 02:53:00,20.89,24.6,0,578,0.00375366056996012,0 +"2167",2015-02-13 02:54:00,20.945,24.4,0,583,0.00373565185080452,0 +"2168",2015-02-13 02:55:00,20.89,24.73,0,579.666666666667,0.00377361733334494,0 +"2169",2015-02-13 02:55:59,20.945,24.945,0,575.5,0.00381960400595424,0 +"2170",2015-02-13 02:57:00,20.89,24.65,0,577.5,0.00376133609754461,0 +"2171",2015-02-13 02:57:59,20.89,24.9633333333333,0,578,0.00380944035804718,0 +"2172",2015-02-13 02:58:59,20.89,24.945,0,581.5,0.003806625543353,0 +"2173",2015-02-13 03:00:00,20.89,24.745,0,579.5,0.00377592011872506,0 +"2174",2015-02-13 03:01:00,20.89,24.745,0,573.5,0.00377592011872506,0 +"2175",2015-02-13 03:02:00,20.9175,24.995,0,574,0.00382079989050314,0 +"2176",2015-02-13 03:03:00,20.89,24.87,0,575.25,0.00379511065600375,0 +"2177",2015-02-13 03:04:00,20.89,24.29,0,575,0.00370607650135101,0 +"2178",2015-02-13 03:04:59,20.89,24.245,0,577.5,0.00369916973804848,0 +"2179",2015-02-13 03:06:00,20.89,24.73,0,583.333333333333,0.00377361733334494,0 +"2180",2015-02-13 03:07:00,20.9633333333333,24.6333333333333,0,583.666666666667,0.00377587190968888,0 +"2181",2015-02-13 03:08:00,20.945,24.4,0,577.5,0.00373565185080452,0 +"2182",2015-02-13 03:08:59,20.945,24.045,0,580,0.00368097953254459,0 +"2183",2015-02-13 03:10:00,21,25.1,0,584,0.00385658376615144,0 +"2184",2015-02-13 03:10:59,21,24.745,0,586,0.00380170507337921,0 +"2185",2015-02-13 03:11:59,20.89,25.045,0,578,0.00382197938567956,0 +"2186",2015-02-13 03:13:00,20.89,24.4,0,580,0.00372296034247527,0 +"2187",2015-02-13 03:14:00,20.9266666666667,24.7233333333333,0,583,0.00378116407821393,0 +"2188",2015-02-13 03:15:00,20.89,24.45,0,578,0.00373063511693237,0 +"2189",2015-02-13 03:16:00,20.9266666666667,24.3966666666667,0,580.333333333333,0.0037309043031855,0 +"2190",2015-02-13 03:16:59,20.89,24.745,0,583.5,0.00377592011872506,0 +"2191",2015-02-13 03:17:59,20.89,24.4,0,583,0.00372296034247527,0 +"2192",2015-02-13 03:19:00,20.89,24.29,0,584,0.00370607650135101,0 +"2193",2015-02-13 03:20:00,20.89,24.27,0,578.5,0.00370300680994748,0 +"2194",2015-02-13 03:21:00,20.89,24.2,0,578,0.00369226312722283,0 +"2195",2015-02-13 03:22:00,20.84,24.445,0,579,0.00371834142142753,0 +"2196",2015-02-13 03:23:00,20.89,24.545,0,581,0.00374521770709445,0 +"2197",2015-02-13 03:23:59,20.89,24.6,0,577.5,0.00375366056996012,0 +"2198",2015-02-13 03:24:59,20.89,24.54,0,577,0.00374445018540388,0 +"2199",2015-02-13 03:26:00,20.89,24.295,0,577,0.00370684392890811,0 +"2200",2015-02-13 03:27:00,20.945,24.5,0,577,0.0037510542286699,0 +"2201",2015-02-13 03:28:00,20.89,23.995,0,577,0.00366080160725762,0 +"2202",2015-02-13 03:29:00,20.945,24.3,0,579.5,0.0037202502311557,0 +"2203",2015-02-13 03:29:59,21,24.55,0,578,0.00377156453430672,0 +"2204",2015-02-13 03:30:59,20.89,24,0,575,0.00366156892375949,0 +"2205",2015-02-13 03:32:00,20.89,24.8,0,582,0.00378436381012078,0 +"2206",2015-02-13 03:33:00,20.89,24.35,0,582,0.00371528575628269,0 +"2207",2015-02-13 03:34:00,20.89,24.05,0,582.5,0.00366924219229434,0 +"2208",2015-02-13 03:35:00,20.89,24.1,0,580,0.00367691564904522,0 +"2209",2015-02-13 03:36:00,20.89,24.245,0,580,0.00369916973804848,0 +"2210",2015-02-13 03:36:59,20.89,24.145,0,580,0.00368382192105146,0 +"2211",2015-02-13 03:38:00,20.89,24,0,573.5,0.00366156892375949,0 +"2212",2015-02-13 03:39:00,20.89,24.39,0,578,0.00372142541017581,0 +"2213",2015-02-13 03:40:00,20.89,24.29,0,579,0.00370607650135101,0 +"2214",2015-02-13 03:40:59,20.89,24.45,0,575,0.00373063511693237,0 +"2215",2015-02-13 03:42:00,20.89,24.545,0,581,0.00374521770709445,0 +"2216",2015-02-13 03:42:59,20.89,24.29,0,579,0.00370607650135101,0 +"2217",2015-02-13 03:43:59,20.89,24.15,0,580.5,0.00368458929401908,0 +"2218",2015-02-13 03:45:00,20.89,24.095,0,585.75,0.00367614829490022,0 +"2219",2015-02-13 03:46:00,20.89,24,0,587,0.00366156892375949,0 +"2220",2015-02-13 03:47:00,20.89,24.495,0,580,0.00373754257491566,0 +"2221",2015-02-13 03:48:00,20.9266666666667,24.2633333333333,0,578,0.00371039242931397,0 +"2222",2015-02-13 03:49:00,20.89,23.945,0,575.5,0.00365312854575242,0 +"2223",2015-02-13 03:49:59,20.945,24.145,0,581.5,0.00369637921899458,0 +"2224",2015-02-13 03:51:00,20.9266666666667,24.2633333333333,0,585.333333333333,0.00371039242931397,0 +"2225",2015-02-13 03:52:00,20.89,24.445,0,583.5,0.00372986763101456,0 +"2226",2015-02-13 03:53:00,20.89,24.695,0,581,0.00376824423336624,0 +"2227",2015-02-13 03:53:59,20.89,24.395,0,579,0.00372219287538422,0 +"2228",2015-02-13 03:55:00,20.89,24.15,0,581.5,0.00368458929401908,0 +"2229",2015-02-13 03:55:59,21,24.6,0,581,0.00377929260087562,0 +"2230",2015-02-13 03:56:59,20.89,23.995,0,574.5,0.00366080160725762,0 +"2231",2015-02-13 03:58:00,20.89,24.26,0,584,0.00370147197554053,0 +"2232",2015-02-13 03:59:00,20.89,24.245,0,581.5,0.00369916973804848,0 +"2233",2015-02-13 04:00:00,20.89,24.0966666666667,0,579.333333333333,0.00367640407940608,0 +"2234",2015-02-13 04:01:00,20.89,24.445,0,585,0.00372986763101456,0 +"2235",2015-02-13 04:01:59,20.89,24.0966666666667,0,580.333333333333,0.00367640407940608,0 +"2236",2015-02-13 04:02:59,20.89,24.05,0,581,0.00366924219229434,0 +"2237",2015-02-13 04:04:00,20.89,24.26,0,582.333333333333,0.00370147197554053,0 +"2238",2015-02-13 04:05:00,20.89,24.09,0,583.5,0.00367538094263743,0 +"2239",2015-02-13 04:06:00,20.89,24.1966666666667,0,579.333333333333,0.0036917515324864,0 +"2240",2015-02-13 04:07:00,20.89,24.29,0,573,0.00370607650135101,0 +"2241",2015-02-13 04:08:00,20.89,24.55,0,570.5,0.00374598523066787,0 +"2242",2015-02-13 04:08:59,20.89,24.3966666666667,0,577,0.00372244869753872,0 +"2243",2015-02-13 04:09:59,20.89,24.29,0,580,0.00370607650135101,0 +"2244",2015-02-13 04:11:00,20.89,24.395,0,577.5,0.00372219287538422,0 +"2245",2015-02-13 04:12:00,20.89,24.145,0,576.5,0.00368382192105146,0 +"2246",2015-02-13 04:13:00,20.89,24.295,0,576,0.00370684392890811,0 +"2247",2015-02-13 04:14:00,20.89,24.1,0,581,0.00367691564904522,0 +"2248",2015-02-13 04:14:59,20.89,24.64,0,582,0.003759800976964,0 +"2249",2015-02-13 04:15:59,20.89,24.7333333333333,0,580.666666666667,0.00377412906196477,0 +"2250",2015-02-13 04:17:00,20.89,24.7,0,578,0.00376901181342826,0 +"2251",2015-02-13 04:18:00,20.89,24.7666666666667,0,576,0.00377924639419492,0 +"2252",2015-02-13 04:19:00,20.89,24.29,0,580,0.00370607650135101,0 +"2253",2015-02-13 04:20:00,20.89,24.6,0,578,0.00375366056996012,0 +"2254",2015-02-13 04:21:00,20.89,24.35,0,579,0.00371528575628269,0 +"2255",2015-02-13 04:21:59,20.89,24.25,0,574.5,0.00369993714866339,0 +"2256",2015-02-13 04:23:00,20.89,24.6966666666667,0,579,0.00376850009317768,0 +"2257",2015-02-13 04:24:00,20.89,25,0,576,0.00381507006340074,0 +"2258",2015-02-13 04:25:00,20.89,24.89,0,573,0.00379818125119672,0 +"2259",2015-02-13 04:25:59,20.89,24.245,0,573.5,0.00369916973804848,0 +"2260",2015-02-13 04:27:00,20.89,24.4,0,575.5,0.00372296034247527,0 +"2261",2015-02-13 04:27:59,20.89,24.145,0,578,0.00368382192105146,0 +"2262",2015-02-13 04:28:59,20.89,24.6,0,579.5,0.00375366056996012,0 +"2263",2015-02-13 04:30:00,20.89,24.3633333333333,0,582,0.00371733229419301,0 +"2264",2015-02-13 04:31:00,20.89,24.0666666666667,0,578,0.00367179999029806,0 +"2265",2015-02-13 04:32:00,20.89,24.2266666666667,0,581.333333333333,0.00369635591523233,0 +"2266",2015-02-13 04:33:00,20.89,24.34,0,583.5,0.0037137508616353,0 +"2267",2015-02-13 04:34:00,20.89,25.5,0,585,0.00389184888190864,0 +"2268",2015-02-13 04:34:59,20.89,24.495,0,578.5,0.00373754257491566,0 +"2269",2015-02-13 04:36:00,20.89,24.445,0,567,0.00372986763101456,0 +"2270",2015-02-13 04:37:00,20.89,24.1,0,577,0.00367691564904522,0 +"2271",2015-02-13 04:38:00,20.89,23.89,0,580.5,0.00364468839546917,0 +"2272",2015-02-13 04:38:59,20.89,24.29,0,580.5,0.00370607650135101,0 +"2273",2015-02-13 04:40:00,20.89,24.445,0,577,0.00372986763101456,0 +"2274",2015-02-13 04:40:59,20.89,23.995,0,577,0.00366080160725762,0 +"2275",2015-02-13 04:41:59,20.89,24.245,0,574,0.00369916973804848,0 +"2276",2015-02-13 04:43:00,20.89,24.245,0,577,0.00369916973804848,0 +"2277",2015-02-13 04:44:00,20.84,24.4,0,572,0.00371145560471808,0 +"2278",2015-02-13 04:45:00,20.89,24.89,0,574,0.00379818125119672,0 +"2279",2015-02-13 04:46:00,20.89,24,0,575.5,0.00366156892375949,0 +"2280",2015-02-13 04:46:59,20.89,24.2,0,572.5,0.00369226312722283,0 +"2281",2015-02-13 04:47:59,20.89,24.55,0,573,0.00374598523066787,0 +"2282",2015-02-13 04:49:00,20.84,24.495,0,573.5,0.00372599250663291,0 +"2283",2015-02-13 04:50:00,20.89,24.2,0,572.5,0.00369226312722283,0 +"2284",2015-02-13 04:51:00,20.84,24.15,0,576,0.00367320382702012,0 +"2285",2015-02-13 04:52:00,20.84,24.445,0,572.5,0.00371834142142753,0 +"2286",2015-02-13 04:53:00,20.84,24.745,0,577,0.00376425073948269,0 +"2287",2015-02-13 04:53:59,20.79,24.3,0,579.5,0.00368472852421734,0 +"2288",2015-02-13 04:54:59,20.89,24.79,0,577,0.00378282857655485,0 +"2289",2015-02-13 04:56:00,20.84,24.4,0,574,0.00371145560471808,0 +"2290",2015-02-13 04:57:00,20.89,24.59,0,569.5,0.00375212548703851,0 +"2291",2015-02-13 04:58:00,20.89,24.89,0,568,0.00379818125119672,0 +"2292",2015-02-13 04:59:00,20.89,24.8966666666667,0,571.333333333333,0.00379920478962396,0 +"2293",2015-02-13 04:59:59,20.89,24.8,0,575,0.00378436381012078,0 +"2294",2015-02-13 05:00:59,20.89,24.29,0,578,0.00370607650135101,0 +"2295",2015-02-13 05:02:00,20.89,24.695,0,574,0.00376824423336624,0 +"2296",2015-02-13 05:03:00,20.89,24.4,0,571.666666666667,0.00372296034247527,0 +"2297",2015-02-13 05:04:00,20.89,24.79,0,568,0.00378282857655485,0 +"2298",2015-02-13 05:05:00,20.89,24.6,0,566.5,0.00375366056996012,0 +"2299",2015-02-13 05:06:00,20.8566666666667,24.6566666666667,0,571,0.00375460451131887,0 +"2300",2015-02-13 05:06:59,20.89,24.29,0,573,0.00370607650135101,0 +"2301",2015-02-13 05:08:00,20.89,24.695,0,571.5,0.00376824423336624,0 +"2302",2015-02-13 05:09:00,20.89,24.65,0,565.5,0.00376133609754461,0 +"2303",2015-02-13 05:10:00,20.89,24.445,0,567.5,0.00372986763101456,0 +"2304",2015-02-13 05:10:59,20.89,24.89,0,569,0.00379818125119672,0 +"2305",2015-02-13 05:12:00,20.84,24.745,0,570,0.00376425073948269,0 +"2306",2015-02-13 05:12:59,20.89,24.9266666666667,0,571,0.00380381075398009,0 +"2307",2015-02-13 05:13:59,20.89,24.6,0,572,0.00375366056996012,0 +"2308",2015-02-13 05:15:00,20.89,25.5,0,573,0.00389184888190864,0 +"2309",2015-02-13 05:16:00,20.84,25.2,0,572,0.0038338927302674,0 +"2310",2015-02-13 05:17:00,20.79,24.695,0,571.5,0.00374498494224934,0 +"2311",2015-02-13 05:18:00,20.89,25,0,573.5,0.00381507006340074,0 +"2312",2015-02-13 05:19:00,20.79,24.65,0,577,0.00373811970125303,0 +"2313",2015-02-13 05:19:59,20.79,25.09,0,572,0.003805252967359,0 +"2314",2015-02-13 05:21:00,20.79,24.745,0,567.5,0.00375261316448302,0 +"2315",2015-02-13 05:22:00,20.8233333333333,24.7633333333333,0,566.666666666667,0.00376317089407213,0 +"2316",2015-02-13 05:23:00,20.84,24.895,0,564.5,0.00378720792489794,0 +"2317",2015-02-13 05:23:59,20.79,24.79,0,565,0.00375947872351275,0 +"2318",2015-02-13 05:25:00,20.79,25.195,0,566.5,0.00382127553485591,0 +"2319",2015-02-13 05:25:59,20.79,24.6966666666667,0,569,0.0037452392133274,0 +"2320",2015-02-13 05:26:59,20.79,24.9,0,571.333333333333,0.00377626183539049,0 +"2321",2015-02-13 05:28:00,20.79,25.03,0,570.333333333333,0.00379609758285656,0 +"2322",2015-02-13 05:29:00,20.79,25.15,0,570,0.00381440861975154,0 +"2323",2015-02-13 05:30:00,20.79,25.6,0,571,0.00388308455287971,0 +"2324",2015-02-13 05:31:00,20.79,25.0966666666667,0,563.333333333333,0.00380627024883993,0 +"2325",2015-02-13 05:31:59,20.89,24.79,0,566,0.00378282857655485,0 +"2326",2015-02-13 05:32:59,20.79,25.05,0,564.5,0.00379914934792587,0 +"2327",2015-02-13 05:34:00,20.79,24.9666666666667,0,566,0.00378643385649647,0 +"2328",2015-02-13 05:35:00,20.84,24.995,0,564.5,0.00380251365099979,0 +"2329",2015-02-13 05:36:00,20.79,24.995,0,561.5,0.00379075706560527,0 +"2330",2015-02-13 05:37:00,20.79,24.7,0,561,0.00374574775610345,0 +"2331",2015-02-13 05:38:00,20.79,25.645,0,558.5,0.00388995297520493,0 +"2332",2015-02-13 05:38:59,20.79,25,0,559,0.00379151999106046,0 +"2333",2015-02-13 05:39:59,20.79,25.1,0,560,0.00380677889082063,0 +"2334",2015-02-13 05:41:00,20.79,24.945,0,551,0.0037831279133643,0 +"2335",2015-02-13 05:42:00,20.79,25.29,0,556,0.00383577285052839,0 +"2336",2015-02-13 05:43:00,20.79,24.83,0,557,0.00376558156912604,0 +"2337",2015-02-13 05:44:00,20.79,25.045,0,560.5,0.00379838640386812,0 +"2338",2015-02-13 05:44:59,20.79,25.49,0,559,0.00386629571069003,0 +"2339",2015-02-13 05:45:59,20.79,25.85,0,557.5,0.00392124436239198,0 +"2340",2015-02-13 05:47:00,20.79,25.645,0,555.5,0.00388995297520493,0 +"2341",2015-02-13 05:48:00,20.745,25.995,0,566,0.00393239809737234,0 +"2342",2015-02-13 05:49:00,20.745,24.995,0,560.5,0.00378020355081926,0 +"2343",2015-02-13 05:50:00,20.73,25.0666666666667,0,557.333333333333,0.00378758609466528,0 +"2344",2015-02-13 05:51:00,20.7,25.39,0,555,0.00382961552889464,0 +"2345",2015-02-13 05:51:59,20.7,25.1,0,552.666666666667,0.00378560813415773,0 +"2346",2015-02-13 05:53:00,20.7,25.05,0,546.5,0.00377802127782894,0 +"2347",2015-02-13 05:54:00,20.7,25.145,0,550.5,0.00379243646214478,0 +"2348",2015-02-13 05:55:00,20.7,25.1,0,555,0.00378560813415773,0 +"2349",2015-02-13 05:55:59,20.7,25.5,0,558,0.00384630960814308,0 +"2350",2015-02-13 05:57:00,20.7,25.5666666666667,0,553,0.00385642766539482,0 +"2351",2015-02-13 05:57:59,20.7,25.65,0,553,0.00386907569703369,0 +"2352",2015-02-13 05:58:59,20.7,25.795,0,552,0.0038910844907557,0 +"2353",2015-02-13 06:00:00,20.7,25.5333333333333,0,553.666666666667,0.00385136859587463,0 +"2354",2015-02-13 06:01:00,20.7,25.5,0,551,0.00384630960814308,0 +"2355",2015-02-13 06:02:00,20.7,25.445,0,549.5,0.00383796245719121,0 +"2356",2015-02-13 06:03:00,20.7,25.2933333333333,0,546.666666666667,0.00381494570960929,0 +"2357",2015-02-13 06:04:00,20.7,25.445,0,548,0.00383796245719121,0 +"2358",2015-02-13 06:04:59,20.76,25.1966666666667,0,553.333333333333,0.00381443382330823,0 +"2359",2015-02-13 06:06:00,20.79,25.295,0,553.5,0.00383653588574852,0 +"2360",2015-02-13 06:07:00,20.7,25.1333333333333,0,554.333333333333,0.00379066614058011,0 +"2361",2015-02-13 06:08:00,20.7,25.245,0,551.5,0.00380761105786558,0 +"2362",2015-02-13 06:08:59,20.7,25.7,0,551,0.00387666476140182,0 +"2363",2015-02-13 06:10:00,20.7,25.695,0,553,0.00387590584668301,0 +"2364",2015-02-13 06:10:59,20.7,25.29,0,544,0.0038144398660383,0 +"2365",2015-02-13 06:11:59,20.7,25.29,0,540,0.0038144398660383,0 +"2366",2015-02-13 06:13:00,20.7,25.475,0,542.25,0.00384251542101704,0 +"2367",2015-02-13 06:14:00,20.7,25.29,0,546,0.0038144398660383,0 +"2368",2015-02-13 06:15:00,20.65,25.4,0,550,0.0038192747551103,0 +"2369",2015-02-13 06:16:00,20.7,25.395,0,550.5,0.00383037433135756,0 +"2370",2015-02-13 06:16:59,20.7,25.5,0,547,0.00384630960814308,0 +"2371",2015-02-13 06:17:59,20.7,25.39,0,544,0.00382961552889464,0 +"2372",2015-02-13 06:19:00,20.7,25.5,0,541,0.00384630960814308,0 +"2373",2015-02-13 06:20:00,20.65,25.59,0,547,0.00384802087847844,0 +"2374",2015-02-13 06:21:00,20.6,25.445,0,541.5,0.00381423559650832,0 +"2375",2015-02-13 06:22:00,20.65,25.445,0,542.5,0.00382608280883351,0 +"2376",2015-02-13 06:23:00,20.65,25.395,0,548,0.00381851831383999,0 +"2377",2015-02-13 06:23:59,20.65,25.645,0,546,0.0038563426175918,0 +"2378",2015-02-13 06:24:59,20.65,25.42,0,543.25,0.00382230053847819,0 +"2379",2015-02-13 06:26:00,20.7,25.29,0,544,0.0038144398660383,0 +"2380",2015-02-13 06:27:00,20.7,25.29,0,542.5,0.0038144398660383,0 +"2381",2015-02-13 06:28:00,20.7,25.43,0,540.333333333333,0.00383568600012009,0 +"2382",2015-02-13 06:29:00,20.7,25.6,0,543,0.00386148681670566,0 +"2383",2015-02-13 06:29:59,20.7,25.53,0,546.333333333333,0.00385086269342101,0 +"2384",2015-02-13 06:30:59,20.7,25.6,0,545,0.00386148681670566,0 +"2385",2015-02-13 06:32:00,20.7,25.495,0,542.5,0.0038455507670375,0 +"2386",2015-02-13 06:33:00,20.79,25.295,0,535,0.00383653588574852,0 +"2387",2015-02-13 06:34:00,20.79,25.3925,0,538,0.00385141544444234,0 +"2388",2015-02-13 06:35:00,20.79,25.54,0,539.5,0.00387392689093653,0 +"2389",2015-02-13 06:36:00,20.84,25.445,0,541,0.00387139868471207,0 +"2390",2015-02-13 06:36:59,20.89,25.1966666666667,0,542,0.00384526748443262,0 +"2391",2015-02-13 06:38:00,20.89,25.1,0,535,0.00383042432009906,0 +"2392",2015-02-13 06:39:00,20.89,25.15,0,542,0.00383810173098707,0 +"2393",2015-02-13 06:40:00,20.9633333333333,25.0333333333333,0,534,0.00383756340577576,0 +"2394",2015-02-13 06:40:59,21,25,0,532,0.0038411240057139,0 +"2395",2015-02-13 06:42:00,21,25,0,534.5,0.0038411240057139,0 +"2396",2015-02-13 06:42:59,21,25.0333333333333,0,537.666666666667,0.00384627717432942,0 +"2397",2015-02-13 06:43:59,20.945,25,0,539,0.00382807749320501,0 +"2398",2015-02-13 06:45:00,20.9633333333333,25.0333333333333,0,540,0.00383756340577576,0 +"2399",2015-02-13 06:46:00,20.89,25.05,0,537,0.00382274709757259,0 +"2400",2015-02-13 06:47:00,20.89,25.05,0,540,0.00382274709757259,0 +"2401",2015-02-13 06:48:00,20.945,25.1,0,536,0.00384348442154574,0 +"2402",2015-02-13 06:49:00,20.945,25.1,0,532.5,0.00384348442154574,0 +"2403",2015-02-13 06:49:59,20.9633333333333,25.1,0,532,0.00384784650438096,0 +"2404",2015-02-13 06:51:00,20.945,25.1,0,540,0.00384348442154574,0 +"2405",2015-02-13 06:52:00,20.89,25.1,0,539,0.00383042432009906,0 +"2406",2015-02-13 06:53:00,20.9633333333333,25.1966666666667,0,539.333333333333,0.00386275759760662,0 +"2407",2015-02-13 06:53:59,21,25.1666666666667,0,531.333333333333,0.00386689069744208,0 +"2408",2015-02-13 06:55:00,21,25.1,0,525,0.00385658376615144,0 +"2409",2015-02-13 06:55:59,21,25.1,0,528,0.00385658376615144,0 +"2410",2015-02-13 06:56:59,20.89,25.39,0,533,0.0038749559254609,0 +"2411",2015-02-13 06:58:00,20.945,25.2,0,530.5,0.00385889210849508,0 +"2412",2015-02-13 06:59:00,20.9175,25.2,0,531.5,0.00385233080028532,0 +"2413",2015-02-13 07:00:00,20.89,25.2,0,532,0.00384577933024355,0 +"2414",2015-02-13 07:01:00,20.89,25.2,0,530.333333333333,0.00384577933024355,0 +"2415",2015-02-13 07:01:59,20.89,25.2,0,529,0.00384577933024355,0 +"2416",2015-02-13 07:02:59,20.89,25.3966666666667,0,527.333333333333,0.00387597971504487,0 +"2417",2015-02-13 07:04:00,20.89,25.39,0,529,0.0038749559254609,0 +"2418",2015-02-13 07:05:00,20.89,25.29,0,524,0.0038595994836159,0 +"2419",2015-02-13 07:06:00,20.89,25.39,0,529,0.0038749559254609,0 +"2420",2015-02-13 07:07:00,20.89,25.395,0,527.5,0.00387572376733487,0 +"2421",2015-02-13 07:08:00,20.89,25.34,0,529,0.00386727761034099,0 +"2422",2015-02-13 07:08:59,20.89,25.54,0,530,0.0038979920012589,0 +"2423",2015-02-13 07:09:59,20.89,25.39,0,527,0.0038749559254609,0 +"2424",2015-02-13 07:11:00,20.89,25.39,0,528,0.0038749559254609,0 +"2425",2015-02-13 07:12:00,20.89,25.3566666666667,0,526,0.00386983702778119,0 +"2426",2015-02-13 07:13:00,20.89,25.34,0,526.5,0.00386727761034099,0 +"2427",2015-02-13 07:14:00,20.89,25.495,0,523.5,0.0038910810004687,0 +"2428",2015-02-13 07:14:59,20.8566666666667,25.3566666666667,0,525,0.00386185912300041,0 +"2429",2015-02-13 07:15:59,20.89,25.39,0,526,0.0038749559254609,0 +"2430",2015-02-13 07:17:00,20.8566666666667,25.3566666666667,0,530.666666666667,0.00386185912300041,0 +"2431",2015-02-13 07:18:00,20.89,25.39,0,532,0.0038749559254609,0 +"2432",2015-02-13 07:19:00,20.84,25.495,0,528.5,0.00387905351346938,0 +"2433",2015-02-13 07:20:00,20.79,25.445,0,526,0.00385942780757468,0 +"2434",2015-02-13 07:21:00,20.79,25.5633333333333,0,525.666666666667,0.00387748817207068,0 +"2435",2015-02-13 07:21:59,20.79,25.39,0,518.5,0.00385103390845795,0 +"2436",2015-02-13 07:23:00,20.79,25.4633333333333,0,522,0.00386222582398216,0 +"2437",2015-02-13 07:24:00,20.89,25.5,0,524,0.00389184888190864,0 +"2438",2015-02-13 07:25:00,20.79,25.7725,0,527.333333333333,0.00390941432379575,0 +"2439",2015-02-13 07:25:59,20.79,25.55,0,523.666666666667,0.00387545314931714,0 +"2440",2015-02-13 07:27:00,20.79,25.6,0,523,0.00388308455287971,0 +"2441",2015-02-13 07:27:59,20.79,25.695,0,524.5,0.00389758473237134,0 +"2442",2015-02-13 07:28:59,20.79,25.8966666666667,0,524,0.00392836804220487,0 +"2443",2015-02-13 07:30:00,20.79,25.5,0,523,0.00386782193185198,0 +"2444",2015-02-13 07:31:00,20.79,25.5,0,519,0.00386782193185198,0 +"2445",2015-02-13 07:32:00,20.79,25.75,0,518,0.00390597988021995,0 +"2446",2015-02-13 07:33:00,20.84,25.7,0,514,0.00391044026914437,0 +"2447",2015-02-13 07:34:00,20.89,25.89,0,515.5,0.00395174943990074,0 +"2448",2015-02-13 07:34:59,20.89,25.745,0,518,0.00392947738071017,0 +"2449",2015-02-13 07:36:00,21,25.6,0,519,0.00393389402653712,0 +"2450",2015-02-13 07:37:00,21,25.7,0,524,0.00394935837065017,0 +"2451",2015-02-13 07:38:00,21,25.495,0,523,0.00391765728756655,0 +"2452",2015-02-13 07:38:59,21,25.495,0,520,0.00391765728756655,0 +"2453",2015-02-13 07:40:00,21,25.6,0,519,0.00393389402653712,0 +"2454",2015-02-13 07:40:59,21,25.495,0,519,0.00391765728756655,0 +"2455",2015-02-13 07:41:59,21,25.29,0,518,0.00388595941531064,0 +"2456",2015-02-13 07:43:00,21,25.5,0,523,0.00391843044651155,0 +"2457",2015-02-13 07:44:00,21,25.39,0,523,0.00390142139093685,0 +"2458",2015-02-13 07:45:00,21,25.53,0,527.666666666667,0.0039230694402934,0 +"2459",2015-02-13 07:46:00,20.945,25.6,0,524,0.00392053044349925,0 +"2460",2015-02-13 07:46:59,20.89,25.65,0,521.5,0.00391488620127721,0 +"2461",2015-02-13 07:47:59,20.9266666666667,25.7333333333333,0,522.666666666667,0.00393661018225297,0 +"2462",2015-02-13 07:49:00,20.89,25.6,0,524,0.00390720690639245,0 +"2463",2015-02-13 07:50:00,20.89,25.6,0,524,0.00390720690639245,0 +"2464",2015-02-13 07:51:00,20.89,25.695,0,524,0.00392179772778763,0 +"2465",2015-02-13 07:52:00,20.84,25.65,0,520.5,0.00390278467261957,0 +"2466",2015-02-13 07:53:00,20.79,25.6666666666667,0,518,0.00389326004712643,0 +"2467",2015-02-13 07:53:59,20.79,25.6666666666667,0,520,0.00389326004712643,0 +"2468",2015-02-13 07:54:59,20.79,25.745,0,520,0.00390521667565489,0 +"2469",2015-02-13 07:56:00,20.79,25.7,0,520.5,0.00389834791832431,0 +"2470",2015-02-13 07:57:00,20.79,25.7633333333333,0,521.666666666667,0.0039080151014929,0 +"2471",2015-02-13 07:58:00,20.79,25.745,0,526.5,0.00390521667565489,0 +"2472",2015-02-13 07:59:00,20.79,25.795,0,519.5,0.00391284880506241,0 +"2473",2015-02-13 07:59:59,20.79,25.895,0,520.5,0.00392811362227655,0 +"2474",2015-02-13 08:00:59,20.89,25.945,0,517,0.00396019787697963,0 +"2475",2015-02-13 08:02:00,20.79,25.6,0,515,0.00388308455287971,0 +"2476",2015-02-13 08:03:00,20.84,25.65,7,512.5,0.00390278467261957,0 +"2477",2015-02-13 08:04:00,20.945,25.6,14,512,0.00392053044349925,0 +"2478",2015-02-13 08:05:00,20.945,25.6,14,516.5,0.00392053044349925,0 +"2479",2015-02-13 08:06:00,21,25.5,14,522,0.00391843044651155,0 +"2480",2015-02-13 08:06:59,21,25.5,14,522,0.00391843044651155,0 +"2481",2015-02-13 08:08:00,21,25.6,14,520.5,0.00393389402653712,0 +"2482",2015-02-13 08:09:00,21,25.445,14,518,0.00390992580316924,0 +"2483",2015-02-13 08:10:00,21,25.39,14,522.666666666667,0.00390142139093685,0 +"2484",2015-02-13 08:10:59,21,25.39,14,522,0.00390142139093685,0 +"2485",2015-02-13 08:12:00,21,25.39,9.33333333333333,522,0.00390142139093685,0 +"2486",2015-02-13 08:12:59,21,25.39,9.33333333333333,515.333333333333,0.00390142139093685,0 +"2487",2015-02-13 08:13:59,21,25.39,14,515.5,0.00390142139093685,0 +"2488",2015-02-13 08:15:00,20.9633333333333,25.5333333333333,9.33333333333333,516.333333333333,0.00391469488304146,0 +"2489",2015-02-13 08:16:00,21,25.6,14,521,0.00393389402653712,0 +"2490",2015-02-13 08:17:00,20.9266666666667,25.5666666666667,13.3333333333333,518.333333333333,0.00391095368980967,0 +"2491",2015-02-13 08:18:00,20.89,25.6,6,516.5,0.00390720690639245,0 +"2492",2015-02-13 08:19:00,20.89,25.6,6,514.333333333333,0.00390720690639245,0 +"2493",2015-02-13 08:19:59,20.89,25.65,6,513.5,0.00391488620127721,0 +"2494",2015-02-13 08:21:00,20.89,25.89,6,515,0.00395174943990074,0 +"2495",2015-02-13 08:22:00,20.89,25.7,24,513,0.00392256568459979,0 +"2496",2015-02-13 08:23:00,20.89,25.6,24,512,0.00390720690639245,0 +"2497",2015-02-13 08:23:59,20.84,25.65,18.5,514,0.00390278467261957,0 +"2498",2015-02-13 08:25:00,20.84,25.65,7.5,516,0.00390278467261957,0 +"2499",2015-02-13 08:25:59,20.89,25.7,9,512,0.00392256568459979,0 +"2500",2015-02-13 08:26:59,20.89,25.6,13,514.5,0.00390720690639245,0 +"2501",2015-02-13 08:28:00,21,25.65,11,515.5,0.00394162610307918,0 +"2502",2015-02-13 08:29:00,21,25.76,15,510,0.00395863734390355,0 +"2503",2015-02-13 08:30:00,21.0333333333333,25.6,15,516,0.00394201270140705,0 +"2504",2015-02-13 08:31:00,21.05,25.5,17,518.5,0.00393056580376996,0 +"2505",2015-02-13 08:31:59,21.1,25.34,14,519,0.00391783973869481,0 +"2506",2015-02-13 08:32:59,21.1666666666667,25.2933333333333,23.6666666666667,520,0.00392672193648121,0 +"2507",2015-02-13 08:34:00,21.2,25.295,31,518,0.00393507623242262,0 +"2508",2015-02-13 08:35:00,21.23,25.23,23.6666666666667,515.333333333333,0.00393217865599575,0 +"2509",2015-02-13 08:36:00,21.23,25.2,23.6666666666667,513.666666666667,0.00392747353414259,0 +"2510",2015-02-13 08:37:00,21.29,25.2,31,519,0.00394204788657305,0 +"2511",2015-02-13 08:38:00,21.2,25.2,19,519,0.00392020418856616,0 +"2512",2015-02-13 08:38:59,21.2,25.29,19,513,0.00393429347565304,0 +"2513",2015-02-13 08:39:59,21.2,25.29,19,520.5,0.00393429347565304,0 +"2514",2015-02-13 08:41:00,21.2,25.23,19,518.333333333333,0.00392490054711932,0 +"2515",2015-02-13 08:42:00,21.1666666666667,25.2,19,516,0.00391214105268426,0 +"2516",2015-02-13 08:43:00,21.1,25.29,19,519,0.00391006059832138,0 +"2517",2015-02-13 08:44:00,21.15,25.34,37,514,0.00392996390106742,0 +"2518",2015-02-13 08:44:59,21.2,25.2,37,516,0.00392020418856616,0 +"2519",2015-02-13 08:45:59,21.2,25.2,37,513,0.00392020418856616,0 +"2520",2015-02-13 08:47:00,21.2,25.2,30.6666666666667,512,0.00392020418856616,0 +"2521",2015-02-13 08:48:00,21.2,25.15,33.5,511,0.00391237708091832,0 +"2522",2015-02-13 08:49:00,21.2,25.2,33,515,0.00392020418856616,0 +"2523",2015-02-13 08:50:00,21.2,25.245,42,516.5,0.00392724875282402,0 +"2524",2015-02-13 08:51:00,21.2,25.2,53,518,0.00392020418856616,0 +"2525",2015-02-13 08:51:59,21.23,25.2933333333333,49.6666666666667,515.333333333333,0.00394211192332018,0 +"2526",2015-02-13 08:53:00,21.245,25.245,58.5,514,0.00393817695145039,0 +"2527",2015-02-13 08:54:00,21.26,25.23,56.6666666666667,512,0.0039394686609083,0 +"2528",2015-02-13 08:55:00,21.29,25.295,58.5,509,0.0039570033225574,0 +"2529",2015-02-13 08:55:59,21.29,25.2633333333333,64.6666666666667,510,0.00395201809782425,0 +"2530",2015-02-13 08:57:00,21.29,25.345,328.5,519,0.00396487489170624,1 +"2531",2015-02-13 08:57:59,21.29,25.4966666666667,499.333333333333,525,0.0039887531958881,0 +"2532",2015-02-13 08:58:59,21.29,25.4633333333333,510.333333333333,528.666666666667,0.00398350506075498,0 +"2533",2015-02-13 09:00:00,21.29,25.4266666666667,506.666666666667,536,0.00397773221374547,1 +"2534",2015-02-13 09:01:00,21.29,25.7,511,532.666666666667,0.00402076872591321,1 +"2535",2015-02-13 09:02:00,21.3233333333333,25.6,502,536,0.00401327093125944,1 +"2536",2015-02-13 09:03:00,21.39,25.6,520,538.666666666667,0.00402981178884647,1 +"2537",2015-02-13 09:04:00,21.5,25.84,491,540,0.0040955226782985,1 +"2538",2015-02-13 09:04:59,21.5,25.65,508,549,0.00406521172368449,1 +"2539",2015-02-13 09:06:00,21.5,25.65,508,549.5,0.00406521172368449,1 +"2540",2015-02-13 09:07:00,21.575,25.625,511.5,547,0.004080034550054,1 +"2541",2015-02-13 09:08:00,21.5666666666667,25.6,497,549,0.00407393612769248,1 +"2542",2015-02-13 09:08:59,21.575,25.8975,496,560,0.00412370988441429,1 +"2543",2015-02-13 09:10:00,21.6333333333333,26.1333333333333,507.666666666667,577.333333333333,0.00417649228861361,1 +"2544",2015-02-13 09:10:59,21.6333333333333,25.8633333333333,509.666666666667,579,0.0041330555821899,1 +"2545",2015-02-13 09:11:59,21.6,25.7,530,570,0.00409836066671354,1 +"2546",2015-02-13 09:13:00,21.675,25.8675,528,573.75,0.00414434361465552,1 +"2547",2015-02-13 09:14:00,21.7,25.84,516,578.5,0.00414628371264067,1 +"2548",2015-02-13 09:15:00,21.7,25.865,534,585.5,0.00415032197693106,1 +"2549",2015-02-13 09:16:00,21.7,25.865,539.25,587.25,0.00415032197693106,1 +"2550",2015-02-13 09:16:59,21.79,25.79,541,585,0.00416118507305908,1 +"2551",2015-02-13 09:17:59,21.79,25.8933333333333,559,584.333333333333,0.00417796977093578,1 +"2552",2015-02-13 09:19:00,21.79,25.89,566.333333333333,589,0.00417742831502325,1 +"2553",2015-02-13 09:20:00,21.865,25.9475,556,588.25,0.00420612157548839,1 +"2554",2015-02-13 09:21:00,21.8233333333333,25.9266666666667,565,588,0.004191969015084,1 +"2555",2015-02-13 09:22:00,21.89,25.84,583,588,0.00419501969730454,1 +"2556",2015-02-13 09:23:00,21.89,25.6975,570.25,587,0.0041717302366383,1 +"2557",2015-02-13 09:23:59,21.89,25.7,572,585,0.00417213880873795,1 +"2558",2015-02-13 09:24:59,21.9175,25.7,589,579,0.00417919542097097,1 +"2559",2015-02-13 09:26:00,21.9633333333333,25.76,585.333333333333,582.666666666667,0.00420083029796589,1 +"2560",2015-02-13 09:27:00,21.945,25.89,592.5,585.5,0.00421742142433231,1 +"2561",2015-02-13 09:28:00,22.025,25.7225,591.5,590,0.00421058943457796,1 +"2562",2015-02-13 09:29:00,22.0666666666667,25.6333333333333,608,588.666666666667,0.00420664112017092,1 +"2563",2015-02-13 09:29:59,22.1,25.575,606.5,586.5,0.00420559801411491,1 +"2564",2015-02-13 09:30:59,22.1333333333333,25.4633333333333,602,586.666666666667,0.00419568362038902,1 +"2565",2015-02-13 09:32:00,22.175,25.445,602,587.75,0.00420337117951009,1 +"2566",2015-02-13 09:33:00,22.2225,25.4175,608.25,590,0.00421104455175592,1 +"2567",2015-02-13 09:34:00,22.2225,25.3175,620.75,587.25,0.00419436533031372,1 +"2568",2015-02-13 09:35:00,22.2,25.2,644,587,0.00416901364590065,1 +"2569",2015-02-13 09:36:00,22.2675,25.175,629.5,579,0.00418211786187487,1 +"2570",2015-02-13 09:36:59,22.29,25.2,660,578.5,0.00419207461976444,1 +"2571",2015-02-13 09:38:00,22.315,25.2,642.5,581.25,0.00419850036792043,1 +"2572",2015-02-13 09:39:00,22.3233333333333,25.2,635.333333333333,579,0.00420064421250195,1 +"2573",2015-02-13 09:40:00,22.34,25.175,652.75,586,0.00420073506137317,1 +"2574",2015-02-13 09:40:59,22.3566666666667,25.1333333333333,661.666666666667,582,0.00419801856017843,1 +"2575",2015-02-13 09:42:00,22.3566666666667,25.1666666666667,682,575.666666666667,0.00420362385164725,1 +"2576",2015-02-13 09:42:59,22.4175,25.1,667,584.25,0.00420805775291651,1 +"2577",2015-02-13 09:43:59,22.39,25.05,686,584.5,0.00419255438088021,1 +"2578",2015-02-13 09:45:00,22.39,24.9966666666667,671.333333333333,586.333333333333,0.0041835680794027,1 +"2579",2015-02-13 09:46:00,22.5,25.025,699,585.25,0.00421663312117596,1 +"2580",2015-02-13 09:47:00,22.5,25.1,714.5,578.5,0.00422935631170863,1 +"2581",2015-02-13 09:48:00,22.5,25.05,705.5,580.5,0.00422087412724227,1 +"2582",2015-02-13 09:49:00,22.5,24.9175,1021.25,577.5,0.00419839744963948,1 +"2583",2015-02-13 09:49:59,22.5,24.84,717,577,0.00418525146153713,1 +"2584",2015-02-13 09:51:00,22.5,24.815,726.5,572,0.00418101093795596,1 +"2585",2015-02-13 09:52:00,22.55,24.8675,734,574.25,0.00420274889883064,1 +"2586",2015-02-13 09:53:00,22.55,24.89,757,581.5,0.00420657724388686,1 +"2587",2015-02-13 09:53:59,22.6,24.7,738.25,568,0.00418703005486845,1 +"2588",2015-02-13 09:55:00,22.575,24.82,740,569,0.00420108392206466,1 +"2589",2015-02-13 09:55:59,22.6,24.93,734,577.333333333333,0.00422628350801979,1 +"2590",2015-02-13 09:56:59,22.6,24.9725,748.75,583.25,0.00423353740220517,1 +"2591",2015-02-13 09:58:00,22.6333333333333,24.89,732,587.666666666667,0.00422806191125925,1 +"2592",2015-02-13 09:59:00,22.65,24.8975,726.75,585,0.00423365443407076,0 +"2593",2015-02-13 10:00:00,22.6666666666667,24.9966666666667,737,594,0.00425496342528066,0 +"2594",2015-02-13 10:01:00,22.7,24.9725,723.5,598,0.00425948704673893,0 +"2595",2015-02-13 10:01:59,22.7,25,707,595.5,0.00426420979919174,0 +"2596",2015-02-13 10:02:59,22.7225,25.175,720.5,604.5,0.00430017145808828,0 +"2597",2015-02-13 10:04:00,22.7225,25.0475,714.5,613,0.00427824323616494,0 +"2598",2015-02-13 10:05:00,22.79,24.945,743,604.5,0.00427821259669705,1 +"2599",2015-02-13 10:06:00,22.73,24.9633333333333,725,610,0.00426572208558884,1 +"2600",2015-02-13 10:07:00,22.79,24.8925,717.75,608.25,0.00426914674126805,1 +"2601",2015-02-13 10:08:00,22.79,24.7225,723.5,593,0.00423979243887682,1 +"2602",2015-02-13 10:08:59,22.8233333333333,24.86,727,587,0.00427221796656857,1 +"2603",2015-02-13 10:09:59,22.84,24.945,720.5,595.75,0.00429128854142437,1 +"2604",2015-02-13 10:11:00,22.8566666666667,24.8566666666667,725,596.333333333333,0.00428033888521932,1 +"2605",2015-02-13 10:12:00,22.89,24.865,722.25,598.5,0.0042905000257166,1 +"2606",2015-02-13 10:13:00,22.9975,24.7225,738.5,600,0.00429379538595462,1 +"2607",2015-02-13 10:14:00,23.05,24.845,733,601.75,0.00432904697852664,1 +"2608",2015-02-13 10:14:59,23.1333333333333,24.53,741.666666666667,602.333333333333,0.0042955301816641,1 +"2609",2015-02-13 10:15:59,23.245,24.6,743.75,603.75,0.00433725107632868,1 +"2610",2015-02-13 10:17:00,23.29,24.5,746.5,607.5,0.00433133727124468,1 +"2611",2015-02-13 10:18:00,23.29,24.315,750,603.5,0.00429840523628692,1 +"2612",2015-02-13 10:19:00,23.29,24.39,750,603.5,0.00431175564386951,1 +"2613",2015-02-13 10:20:00,23.29,24.34,739.25,605,0.00430285530890819,1 +"2614",2015-02-13 10:21:00,23.29,24.23,750,610,0.00428327546238523,1 +"2615",2015-02-13 10:21:59,23.29,24.2675,750,606.5,0.00428995027252551,1 +"2616",2015-02-13 10:23:00,23.26,24.3933333333333,750,603.666666666667,0.00430448753306944,1 +"2617",2015-02-13 10:24:00,23.245,24.2425,752.5,604.5,0.00427378679709105,1 +"2618",2015-02-13 10:25:00,23.26,24.29,767,603.666666666667,0.0042861275130535,1 +"2619",2015-02-13 10:25:59,23.29,24.26,759.666666666667,600,0.00428861529911526,1 +"2620",2015-02-13 10:27:00,23.245,24.245,752.5,600.5,0.00427423055858488,1 +"2621",2015-02-13 10:27:59,23.26,24.26,763.333333333333,604.333333333333,0.00428079738628298,1 +"2622",2015-02-13 10:28:59,23.23,24.2933333333333,765.666666666667,607.333333333333,0.00427890352931815,1 +"2623",2015-02-13 10:30:00,23.245,24.4725,763.25,610.75,0.00431461548716782,1 +"2624",2015-02-13 10:31:00,23.2675,24.4725,778.5,615.25,0.00432052505294574,1 +"2625",2015-02-13 10:32:00,23.26,24.39,774,607.333333333333,0.00430389525755686,1 +"2626",2015-02-13 10:33:00,23.29,24.3675,783,608.5,0.00430775046183285,1 +"2627",2015-02-13 10:34:00,23.29,24.4633333333333,774,607.666666666667,0.00432480992607232,1 +"2628",2015-02-13 10:34:59,23.29,24.4266666666667,762,610,0.00431828271694868,1 +"2629",2015-02-13 10:36:00,23.29,24.5225,774,609,0.00433534275495906,1 +"2630",2015-02-13 10:37:00,23.29,24.575,783,617.5,0.00434468908286194,1 +"2631",2015-02-13 10:38:00,23.34,24.6,783,620,0.00436238319155896,1 +"2632",2015-02-13 10:38:59,23.315,24.4725,792,619,0.00433302422942955,1 +"2633",2015-02-13 10:40:00,23.39,24.34,774,607.5,0.00432909338084501,1 +"2634",2015-02-13 10:40:59,23.29,24.43,786,606,0.00431887609397454,1 +"2635",2015-02-13 10:41:59,23.29,24.525,796.5,614,0.00433578781186753,1 +"2636",2015-02-13 10:43:00,23.29,24.3925,792,616,0.00431220066725788,1 +"2637",2015-02-13 10:44:00,23.29,24.365,792,614,0.00430730544476861,1 +"2638",2015-02-13 10:45:00,23.29,24.4633333333333,798,610.666666666667,0.00432480992607232,1 +"2639",2015-02-13 10:46:00,23.29,24.575,796.5,610,0.00434468908286194,1 +"2640",2015-02-13 10:46:59,23.3233333333333,24.5666666666667,780,615.333333333333,0.00435201837103761,1 +"2641",2015-02-13 10:47:59,23.34,24.6,774,622.25,0.00436238319155896,1 +"2642",2015-02-13 10:49:00,23.39,24.745,774,633,0.00440163611193883,1 +"2643",2015-02-13 10:50:00,23.365,24.7925,790.25,645.25,0.00440344868891725,1 +"2644",2015-02-13 10:51:00,23.3566666666667,24.9266666666667,792,651.333333333333,0.00442520548141922,1 +"2645",2015-02-13 10:52:00,23.39,24.945,774,659.75,0.00443746588133191,1 +"2646",2015-02-13 10:53:00,23.39,24.8225,776.75,660.333333333333,0.00441551966117399,1 +"2647",2015-02-13 10:53:59,23.39,24.75,774,647.4,0.00440253180622135,1 +"2648",2015-02-13 10:54:59,23.39,24.5666666666667,774,638.666666666667,0.0043696913573866,1 +"2649",2015-02-13 10:56:00,23.4175,24.925,783,643.5,0.00444129935427993,1 +"2650",2015-02-13 10:57:00,23.445,24.9725,785.75,649,0.00445726568824427,1 +"2651",2015-02-13 10:58:00,23.39,25,774,660,0.0044473197865111,1 +"2652",2015-02-13 10:59:00,23.4725,25.175,783,674.25,0.00450118461734673,1 +"2653",2015-02-13 10:59:59,23.4633333333333,25.3333333333333,792,679,0.00452717816427743,1 +"2654",2015-02-13 11:00:59,23.4725,25.575,785.75,697.75,0.00457322877841906,1 +"2655",2015-02-13 11:02:00,23.5,25.495,774,701,0.00456644094759165,1 +"2656",2015-02-13 11:03:00,23.5,25.2,785.75,703.25,0.00451321974299581,1 +"2657",2015-02-13 11:04:00,23.5,25.345,788.5,696.5,0.00453937818824753,1 +"2658",2015-02-13 11:05:00,23.5,25.6,788.5,698.5,0.0045853862702246,1 +"2659",2015-02-13 11:06:00,23.525,25.3175,786.75,717,0.0045413070536852,1 +"2660",2015-02-13 11:06:59,23.575,25.2675,795.75,716,0.00454605324764156,1 +"2661",2015-02-13 11:08:00,23.6,25.245,803,707,0.00454887328286729,1 +"2662",2015-02-13 11:09:00,23.575,25.315,785,700.5,0.00455466188541899,1 +"2663",2015-02-13 11:10:00,23.6,25.3566666666667,785,701.333333333333,0.0045691422040598,1 +"2664",2015-02-13 11:10:59,23.6,25.39,785,702,0.00457519288245809,1 +"2665",2015-02-13 11:12:00,23.6,25.4725,785,706.666666666667,0.00459016881404416,1 +"2666",2015-02-13 11:12:59,23.6,25.4266666666667,795.25,709.25,0.00458184876367196,1 +"2667",2015-02-13 11:13:59,23.65,25.445,792.5,716.75,0.00459911104642408,1 +"2668",2015-02-13 11:15:00,23.625,25.4175,779,715.5,0.00458713963047718,1 +"2669",2015-02-13 11:16:00,23.65,25.39,779,705.5,0.00458909660850154,1 +"2670",2015-02-13 11:17:00,23.65,25.445,788,707.25,0.00459911104642408,1 +"2671",2015-02-13 11:18:00,23.7,25.6666666666667,785,709.333333333333,0.00465357064475575,1 +"2672",2015-02-13 11:19:00,23.675,25.575,797,715,0.00462980013701136,1 +"2673",2015-02-13 11:19:59,23.7,25.445,792.5,720,0.00461308264658749,1 +"2674",2015-02-13 11:21:00,23.7,25.5,797,720,0.00462312805284412,1 +"2675",2015-02-13 11:22:00,23.7225,25.5225,792.5,714.5,0.00463355651816525,1 +"2676",2015-02-13 11:23:00,23.745,25.39,779,710,0.00461561632184839,1 +"2677",2015-02-13 11:23:59,23.7,25.39,791,707.666666666667,0.00460303756240186,1 +"2678",2015-02-13 11:25:00,23.7,25.39,792.5,703.5,0.00460303756240186,1 +"2679",2015-02-13 11:25:59,23.7225,25.39,797,710.75,0.00460932316016662,1 +"2680",2015-02-13 11:26:59,23.7,25.2933333333333,797,705.666666666667,0.00458538334638981,1 +"2681",2015-02-13 11:28:00,23.79,25.34,797,704.5,0.00461904341665328,1 +"2682",2015-02-13 11:29:00,23.745,25.365,801.25,707.5,0.00461103791202866,1 +"2683",2015-02-13 11:30:00,23.79,25.315,801.25,706,0.00461445254168184,1 +"2684",2015-02-13 11:31:00,23.79,25.29,802.666666666667,699.333333333333,0.00460986173397927,1 +"2685",2015-02-13 11:31:59,23.79,25.315,797,700.25,0.00461445254168184,1 +"2686",2015-02-13 11:32:59,23.79,25.3566666666667,802.666666666667,701.666666666667,0.0046221040373399,1 +"2687",2015-02-13 11:34:00,23.79,25.34,797,701,0.00461904341665328,1 +"2688",2015-02-13 11:35:00,23.79,25.39,803.2,700.3,0.00462822536840869,1 +"2689",2015-02-13 11:36:00,23.84,25.34,809.4,699.6,0.00463306099565467,1 +"2690",2015-02-13 11:37:00,23.865,25.34,805.25,702,0.00464008383454557,1 +"2691",2015-02-13 11:38:00,23.89,25.34,793.5,702,0.00464711605410508,1 +"2692",2015-02-13 11:38:59,23.89,25.53,808,706.333333333333,0.00468222255129162,1 +"2693",2015-02-13 11:39:59,23.865,25.4725,812.5,706.75,0.00466452825937191,1 +"2694",2015-02-13 11:41:00,23.89,25.3925,808,700.5,0.00465681614032235,1 +"2695",2015-02-13 11:42:00,23.89,25.3566666666667,808,692,0.00465019541402075,1 +"2696",2015-02-13 11:43:00,23.89,25.29,808,690.333333333333,0.00463787815593914,1 +"2697",2015-02-13 11:44:00,23.9175,25.2675,797.2,693.4,0.00464144498641583,1 +"2698",2015-02-13 11:44:59,23.89,25.2,802,688.666666666667,0.0046212506255852,1 +"2699",2015-02-13 11:45:59,23.89,25.2225,799,681.25,0.0046254074254475,1 +"2700",2015-02-13 11:47:00,23.89,25.2,803.5,682,0.0046212506255852,1 +"2701",2015-02-13 11:48:00,23.89,25.2,804.5,676,0.0046212506255852,1 +"2702",2015-02-13 11:49:00,23.89,25.125,799,677,0.00460739502433609,1 +"2703",2015-02-13 11:50:00,23.89,25.2,820.666666666667,673.666666666667,0.0046212506255852,1 +"2704",2015-02-13 11:51:00,23.89,25.2,806.25,679,0.0046212506255852,1 +"2705",2015-02-13 11:51:59,23.89,25.1666666666667,809.333333333333,677.333333333333,0.00461509250493786,1 +"2706",2015-02-13 11:53:00,23.945,25.125,807.5,670.5,0.00462276548364534,1 +"2707",2015-02-13 11:54:00,23.9175,25.025,819,664.75,0.0045965704159444,1 +"2708",2015-02-13 11:55:00,24,25.1,804.5,662,0.00463353162886213,1 +"2709",2015-02-13 11:55:59,23.945,25.1,819,665,0.00461813156534292,1 +"2710",2015-02-13 11:57:00,23.89,25.075,806.25,661,0.00459815829724231,1 +"2711",2015-02-13 11:57:59,23.9266666666667,25.1,802,661,0.00461300824424327,1 +"2712",2015-02-13 11:58:59,23.945,25.1,802,660,0.00461813156534292,1 +"2713",2015-02-13 12:00:00,23.89,25.1,805,661.666666666667,0.00460277662674964,1 +"2714",2015-02-13 12:01:00,23.945,25.1,793,662.5,0.00461813156534292,1 +"2715",2015-02-13 12:02:00,23.9175,25.075,808.5,661,0.00460582237872633,1 +"2716",2015-02-13 12:03:00,23.9633333333333,25.0333333333333,802,662.666666666667,0.00461088929699993,1 +"2717",2015-02-13 12:04:00,23.945,25.1,803,663,0.00461813156534292,1 +"2718",2015-02-13 12:04:59,23.89,25.125,803,663.333333333333,0.00460739502433609,1 +"2719",2015-02-13 12:06:00,23.89,25.2,795,666.8,0.0046212506255852,1 +"2720",2015-02-13 12:07:00,23.9266666666667,25.1333333333333,792,667.333333333333,0.00461917991221861,1 +"2721",2015-02-13 12:08:00,23.9175,25.2,797.25,672.5,0.0046289534810552,1 +"2722",2015-02-13 12:08:59,23.9266666666667,25.2,793.333333333333,674.666666666667,0.00463152361289426,1 +"2723",2015-02-13 12:10:00,23.9725,25.15,788,672,0.00463510941018933,1 +"2724",2015-02-13 12:10:59,23.9633333333333,25.2,782.333333333333,666.333333333333,0.00464181672116077,1 +"2725",2015-02-13 12:11:59,24,25.2225,781.75,668,0.00465631476655091,1 +"2726",2015-02-13 12:13:00,24,25.15,771,667.5,0.0046428306686384,1 +"2727",2015-02-13 12:14:00,23.945,25.175,796.5,664.25,0.0046320335258636,1 +"2728",2015-02-13 12:15:00,23.9266666666667,25.1,785.666666666667,652.666666666667,0.00461300824424327,1 +"2729",2015-02-13 12:16:00,23.89,24.9966666666667,782.666666666667,646.666666666667,0.0045836879722861,1 +"2730",2015-02-13 12:16:59,23.9175,25.05,778.25,633.25,0.00460119636318333,1 +"2731",2015-02-13 12:17:59,23.89,25.15,772,637.5,0.00461201349000317,1 +"2732",2015-02-13 12:19:00,23.9725,25.175,782.75,646.5,0.00463975124376631,1 +"2733",2015-02-13 12:20:00,23.89,25.2,775,647.333333333333,0.0046212506255852,1 +"2734",2015-02-13 12:21:00,23.89,25.1,773,645.75,0.00460277662674964,1 +"2735",2015-02-13 12:22:00,23.9175,25.1,766.5,640.25,0.0046104484625749,1 +"2736",2015-02-13 12:23:00,23.89,25.4,781,637,0.00465820189143931,1 +"2737",2015-02-13 12:23:59,23.89,25.46,773,664,0.00466928812101333,1 +"2738",2015-02-13 12:24:59,23.89,25.1725,760.25,660,0.0046161701673137,1 +"2739",2015-02-13 12:26:00,23.89,25.1,773.333333333333,647,0.00460277662674964,1 +"2740",2015-02-13 12:27:00,23.89,25.1,768.4,643.5,0.00460277662674964,1 +"2741",2015-02-13 12:28:00,23.89,25.1333333333333,765,644.75,0.0046089345053272,1 +"2742",2015-02-13 12:29:00,23.89,24.9175,765.25,633.25,0.00456906438672965,1 +"2743",2015-02-13 12:29:59,23.89,24.9633333333333,759.666666666667,626.333333333333,0.00457753058990699,1 +"2744",2015-02-13 12:30:59,23.89,25.1,753,625.25,0.00460277662674964,1 +"2745",2015-02-13 12:32:00,23.89,25.1,759.666666666667,629.333333333333,0.00460277662674964,1 +"2746",2015-02-13 12:33:00,23.84,25,761.5,622.75,0.00457044001826734,1 +"2747",2015-02-13 12:34:00,23.84,24.995,758,619,0.00456951921492173,1 +"2748",2015-02-13 12:35:00,23.89,25.075,766,610.5,0.00459815829724231,1 +"2749",2015-02-13 12:36:00,23.8566666666667,24.9633333333333,763.333333333333,601.666666666667,0.00456829777405708,1 +"2750",2015-02-13 12:36:59,23.8566666666667,24.9633333333333,758,593.666666666667,0.00456829777405708,1 +"2751",2015-02-13 12:38:00,23.84,25,754.5,595.5,0.00457044001826734,1 +"2752",2015-02-13 12:39:00,23.84,25,742,601.5,0.00457044001826734,1 +"2753",2015-02-13 12:40:00,23.815,25.025,750.5,602.75,0.00456811907208034,1 +"2754",2015-02-13 12:40:59,23.8233333333333,25.0666666666667,767,604.333333333333,0.00457809215702162,1 +"2755",2015-02-13 12:42:00,23.79,25.025,751,610,0.0045612033076407,1 +"2756",2015-02-13 12:42:59,23.79,25.0666666666667,748.333333333333,616,0.00456885350290915,1 +"2757",2015-02-13 12:43:59,23.815,25.125,745,614.75,0.00458650789725538,1 +"2758",2015-02-13 12:45:00,23.79,25.1,737,614.666666666667,0.00457497379363197,1 +"2759",2015-02-13 12:46:00,23.815,25.125,743.25,603,0.00458650789725538,1 +"2760",2015-02-13 12:47:00,23.79,25.1,739.5,598.5,0.00457497379363197,1 +"2761",2015-02-13 12:48:00,23.79,25.0666666666667,739.5,591.25,0.00456885350290915,1 +"2762",2015-02-13 12:49:00,23.79,25.1,727,588,0.00457497379363197,1 +"2763",2015-02-13 12:49:59,23.79,25.15,744,594.25,0.00458415445390449,1 +"2764",2015-02-13 12:51:00,23.8233333333333,25.23,749.333333333333,598,0.00460814381382689,1 +"2765",2015-02-13 12:52:00,23.815,25.2225,735.5,598.5,0.0046044380410601,1 +"2766",2015-02-13 12:53:00,23.79,25.2,740,599,0.00459333538321347,1 +"2767",2015-02-13 12:53:59,23.79,25.2225,736,595.5,0.00459746688917881,1 +"2768",2015-02-13 12:55:00,23.79,25.2,736,595,0.00459333538321347,1 +"2769",2015-02-13 12:55:59,23.79,25.2225,731.5,593.5,0.00459746688917881,1 +"2770",2015-02-13 12:56:59,23.79,25.29,733.333333333333,596,0.00460986173397927,1 +"2771",2015-02-13 12:58:00,23.79,25.29,734,588,0.00460986173397927,1 +"2772",2015-02-13 12:59:00,23.79,25.29,734.25,591.75,0.00460986173397927,1 +"2773",2015-02-13 13:00:00,23.79,25.3233333333333,425.333333333333,596.666666666667,0.00461598282586459,1 +"2774",2015-02-13 13:01:00,23.79,25.445,283,600,0.00463832582614278,0 +"2775",2015-02-13 13:01:59,23.865,25.575,265,614.5,0.00468343940576684,0 +"2776",2015-02-13 13:02:59,23.865,25.575,265,607,0.00468343940576684,0 +"2777",2015-02-13 13:04:00,23.8566666666667,25.6,257,600.333333333333,0.00468568567356009,0 +"2778",2015-02-13 13:05:00,23.89,25.7,268,601,0.00471363696212356,0 +"2779",2015-02-13 13:06:00,23.89,25.6333333333333,261,599,0.00470131720996216,0 +"2780",2015-02-13 13:07:00,23.89,25.6,259,601,0.00469515751551323,0 +"2781",2015-02-13 13:08:00,23.89,25.55,259,595.5,0.00468591820086948,0 +"2782",2015-02-13 13:08:59,23.89,25.5,248.25,588.75,0.00467667915865061,0 +"2783",2015-02-13 13:09:59,23.89,25.5,242,585.5,0.00467667915865061,0 +"2784",2015-02-13 13:11:00,23.89,25.5,241,585.5,0.00467667915865061,0 +"2785",2015-02-13 13:12:00,23.89,25.5,252,578.5,0.00467667915865061,0 +"2786",2015-02-13 13:13:00,23.89,25.4633333333333,246,579.666666666667,0.0046699040341576,0 +"2787",2015-02-13 13:14:00,23.89,25.445,243,578,0.00466651652684621,0 +"2788",2015-02-13 13:14:59,23.89,25.4725,237.25,576,0.00467159780154697,0 +"2789",2015-02-13 13:15:59,23.89,25.5,252,574.333333333333,0.00467667915865061,0 +"2790",2015-02-13 13:17:00,23.89,25.39,246,564,0.0046563542246453,0 +"2791",2015-02-13 13:18:00,23.89,25.39,246,565.666666666667,0.0046563542246453,0 +"2792",2015-02-13 13:19:00,23.89,25.4266666666667,240,568,0.00466312905615742,0 +"2793",2015-02-13 13:20:00,23.89,25.4266666666667,228,566,0.00466312905615742,0 +"2794",2015-02-13 13:21:00,23.89,25.4633333333333,230.75,563,0.0046699040341576,0 +"2795",2015-02-13 13:21:59,23.89,25.445,229,562.75,0.00466651652684621,0 +"2796",2015-02-13 13:23:00,23.89,25.5,239,562,0.00467667915865061,0 +"2797",2015-02-13 13:24:00,23.89,25.5,225.5,556.75,0.00467667915865061,0 +"2798",2015-02-13 13:25:00,23.89,25.5,225.5,558.25,0.00467667915865061,0 +"2799",2015-02-13 13:25:59,23.89,25.5,227,560.5,0.00467667915865061,0 +"2800",2015-02-13 13:27:00,23.84,25.445,225.75,544.5,0.0046524023566395,0 +"2801",2015-02-13 13:27:59,23.84,25.445,227,547,0.0046524023566395,0 +"2802",2015-02-13 13:28:59,23.865,25.4725,237.5,546,0.00466452825937191,0 +"2803",2015-02-13 13:30:00,23.79,25.39,215,549,0.00462822536840869,0 +"2804",2015-02-13 13:31:00,23.865,25.4725,229.5,547.5,0.00466452825937191,0 +"2805",2015-02-13 13:32:00,23.815,25.4175,213.25,544.25,0.00464030140733581,0 +"2806",2015-02-13 13:33:00,23.84,25.445,209,544,0.0046524023566395,0 +"2807",2015-02-13 13:34:00,23.79,25.4266666666667,209,543.333333333333,0.00463495897071902,0 +"2808",2015-02-13 13:34:59,23.79,25.5,213,545.25,0.00464842660949544,0 +"2809",2015-02-13 13:36:00,23.79,25.5,204.5,545.25,0.00464842660949544,0 +"2810",2015-02-13 13:37:00,23.79,25.575,262.666666666667,545.333333333333,0.00466220092976197,0 +"2811",2015-02-13 13:38:00,23.79,25.6666666666667,438.5,542.5,0.00467903703245484,1 +"2812",2015-02-13 13:38:59,23.7675,25.675,654,547,0.00467418744385608,0 +"2813",2015-02-13 13:40:00,23.7675,25.7475,668.5,545,0.00468748568844322,0 +"2814",2015-02-13 13:40:59,23.7,25.89,680.333333333333,564,0.00469436835565054,0 +"2815",2015-02-13 13:41:59,23.7225,25.9725,664.75,567.75,0.00471587248344224,0 +"2816",2015-02-13 13:43:00,23.7,25.89,675.25,569.5,0.00469436835565054,0 +"2817",2015-02-13 13:44:00,23.745,26,669,571.5,0.0047273502577975,0 +"2818",2015-02-13 13:45:00,23.7,26.075,667.25,564.75,0.00472816749734838,0 +"2819",2015-02-13 13:46:00,23.7,26,655.666666666667,563.666666666667,0.00471446470320956,0 +"2820",2015-02-13 13:46:59,23.745,25.9725,659.25,567.5,0.00472231221446236,1 +"2821",2015-02-13 13:47:59,23.7,25.89,662,563,0.00469436835565054,1 +"2822",2015-02-13 13:49:00,23.7,25.89,651.5,551.5,0.00469436835565054,1 +"2823",2015-02-13 13:50:00,23.7,25.89,648.333333333333,545.333333333333,0.00469436835565054,1 +"2824",2015-02-13 13:51:00,23.7,25.89,643.75,540.75,0.00469436835565054,1 +"2825",2015-02-13 13:52:00,23.7,25.89,646,537.75,0.00469436835565054,1 +"2826",2015-02-13 13:53:00,23.6333333333333,25.89,629.666666666667,537.666666666667,0.0046754172967167,1 +"2827",2015-02-13 13:53:59,23.625,26.0225,634,543,0.00469714954751556,1 +"2828",2015-02-13 13:54:59,23.6,26.1,636.333333333333,547.666666666667,0.00470410009192513,1 +"2829",2015-02-13 13:56:00,23.6,26.1,633.25,554.5,0.00470410009192513,1 +"2830",2015-02-13 13:57:00,23.6,26.1,631.25,554.75,0.00470410009192513,1 +"2831",2015-02-13 13:58:00,23.6,26.1,622.5,558,0.00470410009192513,1 +"2832",2015-02-13 13:59:00,23.6,26.1,627,548.5,0.00470410009192513,1 +"2833",2015-02-13 13:59:59,23.55,26.075,627.5,541.25,0.00468531386717237,1 +"2834",2015-02-13 14:00:59,23.5,26.1,631.666666666667,543,0.00467561781205665,1 +"2835",2015-02-13 14:02:00,23.5,26.175,617.75,546,0.00468915478481201,1 +"2836",2015-02-13 14:03:00,23.5,26.23,626.666666666667,545,0.00469908226986435,1 +"2837",2015-02-13 14:04:00,23.5,26.2225,611.5,548,0.00469772850338208,1 +"2838",2015-02-13 14:05:00,23.5,26.2,610.333333333333,549.666666666667,0.00469366723902715,1 +"2839",2015-02-13 14:06:00,23.5,26.3975,607.5,545.25,0.00472931791195345,1 +"2840",2015-02-13 14:06:59,23.4175,26.5225,608,599.75,0.00472811612394435,1 +"2841",2015-02-13 14:08:00,23.445,26.39,616.5,586.5,0.00471218769219991,1 +"2842",2015-02-13 14:09:00,23.4725,27.525,610,570,0.00492468147512067,1 +"2843",2015-02-13 14:10:00,23.4266666666667,26.83,605.666666666667,564,0.00478602181679988,1 +"2844",2015-02-13 14:10:59,23.445,26.6475,596,561.5,0.00475851854395451,1 +"2845",2015-02-13 14:12:00,23.5,26.65,592,564,0.00477490252852723,1 +"2846",2015-02-13 14:12:59,23.5,26.72,598.25,555.25,0.00478754102197953,1 +"2847",2015-02-13 14:13:59,23.5,26.84,593,571,0.00480920819661319,1 +"2848",2015-02-13 14:15:00,23.5,26.745,589,570,0.00479205489316459,1 +"2849",2015-02-13 14:16:00,23.5,26.79,585,567,0.00480018002513551,1 +"2850",2015-02-13 14:17:00,23.5,26.92,585,571,0.00482365381194829,1 +"2851",2015-02-13 14:18:00,23.5,26.8675,587.5,573.5,0.00481417380178424,1 +"2852",2015-02-13 14:19:00,23.5,26.865,589.75,573.75,0.00481372237988128,1 +"2853",2015-02-13 14:19:59,23.55,26.84,566,575,0.00482383975051795,1 +"2854",2015-02-13 14:21:00,23.5,26.79,587.5,563.5,0.00480018002513551,1 +"2855",2015-02-13 14:22:00,23.5,26.79,585.5,561.5,0.00480018002513551,1 +"2856",2015-02-13 14:23:00,23.445,26.7675,583.5,558.5,0.00478011196058261,1 +"2857",2015-02-13 14:23:59,23.4725,26.92,582,558,0.00481559884421181,1 +"2858",2015-02-13 14:25:00,23.5,27.05,570,565.5,0.00484712935702254,1 +"2859",2015-02-13 14:25:59,23.5,27.1,567.333333333333,573.333333333333,0.00485615888103828,1 +"2860",2015-02-13 14:26:59,23.4725,27.05,574.25,579.25,0.00483903488509196,1 +"2861",2015-02-13 14:28:00,23.445,27.025,572.5,578.5,0.00482645285610581,1 +"2862",2015-02-13 14:29:00,23.4633333333333,27.0666666666667,579,576.333333333333,0.00483934243900072,1 +"2863",2015-02-13 14:30:00,23.5,27,574.75,575,0.00483810009313388,1 +"2864",2015-02-13 14:31:00,23.39,27,562,568,0.00480585433033931,1 +"2865",2015-02-13 14:31:59,23.39,27,560.25,562,0.00480585433033931,1 +"2866",2015-02-13 14:32:59,23.39,27.1,558.5,563,0.00482379183084145,1 +"2867",2015-02-13 14:34:00,23.39,27.1,573,556,0.00482379183084145,1 +"2868",2015-02-13 14:35:00,23.3566666666667,27.1333333333333,571,557.333333333333,0.00481998846299087,1 +"2869",2015-02-13 14:36:00,23.29,27.2425,563,560,0.00481993896996669,1 +"2870",2015-02-13 14:37:00,23.29,27.29,559,557.75,0.00482840824965807,1 +"2871",2015-02-13 14:38:00,23.29,27.39,552,560.666666666667,0.0048462390602794,1 +"2872",2015-02-13 14:38:59,23.29,27.4175,556.75,562,0.0048511427110445,1 +"2873",2015-02-13 14:39:59,23.29,27.4633333333333,552.333333333333,563.333333333333,0.00485931563281056,1 +"2874",2015-02-13 14:41:00,23.29,27.445,547,561.25,0.0048560464385301,1 +"2875",2015-02-13 14:42:00,23.29,27.5,547,556.5,0.00486585412367001,1 +"2876",2015-02-13 14:43:00,23.2675,27.625,540.25,557.5,0.00488145460781615,1 +"2877",2015-02-13 14:44:00,23.23,27.6333333333333,554.333333333333,557.333333333333,0.00487180182603679,1 +"2878",2015-02-13 14:44:59,23.2,27.6,547,552.25,0.00485699666476052,1 +"2879",2015-02-13 14:45:59,23.2,27.625,551.5,549.5,0.00486143050353041,1 +"2880",2015-02-13 14:47:00,23.2,27.7,553,549.5,0.00487473239618131,1 +"2881",2015-02-13 14:48:00,23.2,27.7225,538,557.25,0.0048787230740602,1 +"2882",2015-02-13 14:49:00,23.2,27.79,539.666666666667,565,0.00489069541255805,1 +"2883",2015-02-13 14:50:00,23.175,27.8675,531,563.5,0.00489697810473307,1 +"2884",2015-02-13 14:51:00,23.1,28.0333333333333,543,561.666666666667,0.00490388317028148,1 +"2885",2015-02-13 14:51:59,23.1,28.1,543,555.5,0.00491563736370171,1 +"2886",2015-02-13 14:53:00,23.1,28.1,543,555.25,0.00491563736370171,1 +"2887",2015-02-13 14:54:00,23.1,28.1,535.5,555,0.00491563736370171,1 +"2888",2015-02-13 14:55:00,23.1,28.1975,528,561,0.00493282866530136,1 +"2889",2015-02-13 14:55:59,23.1,28.2225,532.5,574,0.00493723684322477,1 +"2890",2015-02-13 14:57:00,23.1,28.2,517.5,562.2,0.00493326948030414,1 +"2891",2015-02-13 14:57:59,23.1,28.1333333333333,528.666666666667,557.666666666667,0.00492151462570314,1 +"2892",2015-02-13 14:58:59,23.075,28.1,534,558.75,0.00490815057976438,1 +"2893",2015-02-13 15:00:00,23.1,28.1666666666667,528.666666666667,561.666666666667,0.00492739199790292,1 +"2894",2015-02-13 15:01:00,23.1,28.2,518,566.5,0.00493326948030414,1 +"2895",2015-02-13 15:02:00,23.1,28.2,518,567.5,0.00493326948030414,1 +"2896",2015-02-13 15:03:00,23.1,28.3566666666667,513,571.333333333333,0.00496089512383092,1 +"2897",2015-02-13 15:04:00,23.1,28.29,513.5,572.5,0.00494913923326789,1 +"2898",2015-02-13 15:04:59,23,28.245,524,573.5,0.00491116078571232,1 +"2899",2015-02-13 15:06:00,23,28.2,519,561,0.00490327463194147,1 +"2900",2015-02-13 15:07:00,23,28.2225,516.5,555.5,0.00490721768402601,1 +"2901",2015-02-13 15:08:00,23,28.29,509,555,0.00491904713789402,1 +"2902",2015-02-13 15:08:59,23,28.29,509,562,0.00491904713789402,1 +"2903",2015-02-13 15:10:00,23,28.29,505,564.5,0.00491904713789402,1 +"2904",2015-02-13 15:10:59,23,28.29,505.333333333333,564,0.00491904713789402,1 +"2905",2015-02-13 15:11:59,23,28.34,514,564.5,0.00492780998414242,1 +"2906",2015-02-13 15:13:00,23,28.39,514,571.5,0.00493657307536199,1 +"2907",2015-02-13 15:14:00,23,28.39,506.5,580.5,0.00493657307536199,1 +"2908",2015-02-13 15:15:00,23,28.4266666666667,504,571,0.00494299949795509,1 +"2909",2015-02-13 15:16:00,23,28.4633333333333,499,569.333333333333,0.00494942605229781,1 +"2910",2015-02-13 15:16:59,23,28.4725,499,571.25,0.00495103271146985,1 +"2911",2015-02-13 15:17:59,22.9725,28.445,495.25,568,0.00493791988490374,1 +"2912",2015-02-13 15:19:00,22.9175,28.5,489,569.75,0.00493096211917668,1 +"2913",2015-02-13 15:20:00,22.89,28.5,497.333333333333,569,0.00492268979605045,1 +"2914",2015-02-13 15:21:00,22.89,28.6,494,571.25,0.00494009957565735,1 +"2915",2015-02-13 15:22:00,22.89,28.6,494,573,0.00494009957565735,1 +"2916",2015-02-13 15:23:00,22.89,28.6,500.25,570,0.00494009957565735,1 +"2917",2015-02-13 15:23:59,22.89,28.6,494,569.333333333333,0.00494009957565735,1 +"2918",2015-02-13 15:24:59,22.89,28.65,492.75,571.5,0.00494880482807087,1 +"2919",2015-02-13 15:26:00,22.84,28.65,489,573.75,0.00493371535968374,1 +"2920",2015-02-13 15:27:00,22.79,28.7,489,572,0.00492731856938336,1 +"2921",2015-02-13 15:28:00,22.79,28.772,483,570.2,0.00493977795658584,1 +"2922",2015-02-13 15:29:00,22.76,28.79,480.666666666667,577.666666666667,0.00493383830059903,1 +"2923",2015-02-13 15:29:59,22.7675,28.84,484,575,0.00494474131781277,1 +"2924",2015-02-13 15:30:59,22.7225,28.89,484,569.75,0.00493977454313347,1 +"2925",2015-02-13 15:32:00,22.7,28.9175,484,576.25,0.00493771596038109,1 +"2926",2015-02-13 15:33:00,22.73,29,484,580,0.00496100733665431,1 +"2927",2015-02-13 15:34:00,22.7,29,479,580,0.00495191513685054,1 +"2928",2015-02-13 15:35:00,22.7,29.05,479,577.75,0.00496052101137711,1 +"2929",2015-02-13 15:36:00,22.7,29.1,479,578,0.00496912712216452,1 +"2930",2015-02-13 15:36:59,22.7,29.1,479,574.5,0.00496912712216452,1 +"2931",2015-02-13 15:38:00,22.675,29.125,479,575,0.00496583153954914,1 +"2932",2015-02-13 15:39:00,22.6,29.1,479,572,0.00493882011452233,1 +"2933",2015-02-13 15:40:00,22.6,29.1,479,570,0.00493882011452233,1 +"2934",2015-02-13 15:40:59,22.6,29.125,479,580.75,0.00494309680646105,1 +"2935",2015-02-13 15:42:00,22.6,29.175,479,584.75,0.00495165036538278,1 +"2936",2015-02-13 15:42:59,22.6,29.2,479,586,0.00495592723236818,1 +"2937",2015-02-13 15:43:59,22.6,29.2225,471.5,585.25,0.00495977646254535,1 +"2938",2015-02-13 15:45:00,22.6,29.2,469,586,0.00495592723236818,1 +"2939",2015-02-13 15:46:00,22.6,29.2675,467.75,585.75,0.00496747506469679,1 +"2940",2015-02-13 15:47:00,22.6,29.29,464,586,0.00497132443667279,1 +"2941",2015-02-13 15:48:00,22.6,29.3233333333333,464,584.333333333333,0.00497702729685581,1 +"2942",2015-02-13 15:49:00,22.55,29.4175,464,584,0.00497787890038783,1 +"2943",2015-02-13 15:49:59,22.5,29.6,474.5,588.25,0.00499369502351873,1 +"2944",2015-02-13 15:51:00,22.5,29.65,474.5,593.5,0.00500219815681985,1 +"2945",2015-02-13 15:52:00,22.5,29.7,474.5,596.75,0.00501070152075887,1 +"2946",2015-02-13 15:53:00,22.4266666666667,29.73,478,596.333333333333,0.00499331756369339,1 +"2947",2015-02-13 15:53:59,22.445,29.79,459,595,0.00500910063115527,1 +"2948",2015-02-13 15:55:00,22.39,29.79,472.666666666667,601.333333333333,0.00499224333885032,1 +"2949",2015-02-13 15:55:59,22.39,29.84,464,595.75,0.00500068976289938,1 +"2950",2015-02-13 15:56:59,22.29,29.9266666666667,469,593.666666666667,0.00498466715098003,1 +"2951",2015-02-13 15:58:00,22.365,30.025,457.75,596.5,0.00502423638651601,1 +"2952",2015-02-13 15:59:00,22.39,30,454,586,0.0050277198491877,1 +"2953",2015-02-13 16:00:00,22.29,30,454.75,595.25,0.00499697987960895,1 +"2954",2015-02-13 16:01:00,22.29,30,460,595.5,0.00499697987960895,1 +"2955",2015-02-13 16:01:59,22.29,30,444,601.25,0.00499697987960895,1 +"2956",2015-02-13 16:02:59,22.29,30.1,449.666666666667,598,0.00501377074347092,1 +"2957",2015-02-13 16:04:00,22.2675,30.075,438,601.5,0.00500266185167665,1 +"2958",2015-02-13 16:05:00,22.26,30.0666666666667,441,599,0.00499896336554179,1 +"2959",2015-02-13 16:06:00,22.2,30.1,438,605.5,0.00498615355344287,1 +"2960",2015-02-13 16:07:00,22.2,30.1,441,608.333333333333,0.00498615355344287,1 +"2961",2015-02-13 16:08:00,22.2,30.1,447,605.75,0.00498615355344287,1 +"2962",2015-02-13 16:08:59,22.2,30.23,447,600.333333333333,0.00500786181807904,1 +"2963",2015-02-13 16:09:59,22.175,30.2,447,597.25,0.00499517870463988,1 +"2964",2015-02-13 16:11:00,22.1,30.34,447,592,0.00499545603055302,1 +"2965",2015-02-13 16:12:00,22.1,30.39,438,594,0.005003754716421,1 +"2966",2015-02-13 16:13:00,22.1,30.39,447,588,0.005003754716421,1 +"2967",2015-02-13 16:14:00,22.1,30.6,447,585,0.00503861159607086,1 +"2968",2015-02-13 16:14:59,22.1,30.6,447,588.25,0.00503861159607086,1 +"2969",2015-02-13 16:15:59,22.075,30.575,447,594,0.0050267335872278,1 +"2970",2015-02-13 16:17:00,22.1,30.6,447,585.5,0.00503861159607086,1 +"2971",2015-02-13 16:18:00,22.025,30.525,447,583.5,0.00500304762993183,1 +"2972",2015-02-13 16:19:00,22.0333333333333,30.5333333333333,447,588.333333333333,0.00500698881213204,1 +"2973",2015-02-13 16:20:00,22,30.6,443.5,591,0.00500773607549388,1 +"2974",2015-02-13 16:21:00,22,30.7,447,594.666666666667,0.00502423341631879,1 +"2975",2015-02-13 16:21:59,21.9175,30.7675,440,602.5,0.00500988223078186,1 +"2976",2015-02-13 16:23:00,21.89,30.865,443.5,605.5,0.00501738875542855,1 +"2977",2015-02-13 16:24:00,21.89,30.89,442.333333333333,606.666666666667,0.00502148554368102,1 +"2978",2015-02-13 16:25:00,21.89,31,447,610,0.00503951204800542,1 +"2979",2015-02-13 16:25:59,21.89,30.945,442.5,603,0.00503049866628219,1 +"2980",2015-02-13 16:27:00,21.89,31,441,610,0.00503951204800542,1 +"2981",2015-02-13 16:27:59,21.89,30.9725,438,610.5,0.00503500532475285,1 +"2982",2015-02-13 16:28:59,21.89,31,441,607,0.00503951204800542,1 +"2983",2015-02-13 16:30:00,21.89,31.075,438,607.5,0.00505180344069613,1 +"2984",2015-02-13 16:31:00,21.865,31.1,438,617,0.00504812681021909,1 +"2985",2015-02-13 16:32:00,21.79,31.1,433.5,614.75,0.00502486851168203,1 +"2986",2015-02-13 16:33:00,21.79,31.1,429,612.5,0.00502486851168203,1 +"2987",2015-02-13 16:34:00,21.79,31.175,432.75,612.75,0.00503708449464411,1 +"2988",2015-02-13 16:34:59,21.79,31.1333333333333,434,618.333333333333,0.00503029777867882,1 +"2989",2015-02-13 16:36:00,21.79,31.125,440.25,613.75,0.00502894045311512,1 +"2990",2015-02-13 16:37:00,21.79,31.2,444,611,0.00504115659474208,1 +"2991",2015-02-13 16:38:00,21.79,31.2,444,612,0.00504115659474208,1 +"2992",2015-02-13 16:38:59,21.79,31.2,444,617.5,0.00504115659474208,1 +"2993",2015-02-13 16:40:00,21.79,31.1333333333333,444,615,0.00503029777867882,1 +"2994",2015-02-13 16:40:59,21.79,31.2,444,606.75,0.00504115659474208,1 +"2995",2015-02-13 16:41:59,21.79,31.2,444,607,0.00504115659474208,1 +"2996",2015-02-13 16:43:00,21.76,31.29,444,608,0.00504648221280132,1 +"2997",2015-02-13 16:44:00,21.7,31.315,440.25,610.75,0.00503190875266905,1 +"2998",2015-02-13 16:45:00,21.7,31.29,444,612.5,0.00502785910908216,1 +"2999",2015-02-13 16:46:00,21.7,31.3566666666667,439,617.333333333333,0.00503865827489077,1 +"3000",2015-02-13 16:46:59,21.7,31.5,444,619,0.00506187774105478,1 +"3001",2015-02-13 16:47:59,21.7,31.575,432.75,624,0.00507402814706102,1 +"3002",2015-02-13 16:49:00,21.7,31.6,429,627,0.00507807838703493,1 +"3003",2015-02-13 16:50:00,21.675,31.625,436.5,628.5,0.00507430274876678,1 +"3004",2015-02-13 16:51:00,21.7,31.6,439,626,0.00507807838703493,1 +"3005",2015-02-13 16:52:00,21.65,31.575,440.25,626.5,0.00505841206597156,1 +"3006",2015-02-13 16:53:00,21.7,31.7,444,627.5,0.00509427987015004,1 +"3007",2015-02-13 16:53:59,21.7,31.7,444,625.25,0.00509427987015004,1 +"3008",2015-02-13 16:54:59,21.6666666666667,31.7,444,622.333333333333,0.00508382251765462,1 +"3009",2015-02-13 16:56:00,21.675,31.7,444,625.25,0.00508643507628818,1 +"3010",2015-02-13 16:57:00,21.65,31.7,444,630,0.00507860095656655,1 +"3011",2015-02-13 16:58:00,21.6,31.7,444,629,0.00506296468914706,1 +"3012",2015-02-13 16:59:00,21.6333333333333,31.73,444,633,0.00507822464341175,1 +"3013",2015-02-13 16:59:59,21.625,31.7675,444,631.5,0.00508166310866195,1 +"3014",2015-02-13 17:00:59,21.6,31.79,444,630.666666666667,0.0050774563762716,1 +"3015",2015-02-13 17:02:00,21.575,31.815,444,628,0.00507365102439193,1 +"3016",2015-02-13 17:03:00,21.6,31.79,444,629,0.0050774563762716,1 +"3017",2015-02-13 17:04:00,21.6,31.79,444,626,0.0050774563762716,1 +"3018",2015-02-13 17:05:00,21.6,31.84,444,626,0.00508550760299421,1 +"3019",2015-02-13 17:06:00,21.575,31.89,444,629.75,0.00508570933446053,1 +"3020",2015-02-13 17:06:59,21.5333333333333,31.9266666666667,444,626.666666666667,0.0050785303283783,1 +"3021",2015-02-13 17:08:00,21.5,32,444,629.333333333333,0.00507982834200202,1 +"3022",2015-02-13 17:09:00,21.525,32,444,633.25,0.00508767341952366,1 +"3023",2015-02-13 17:10:00,21.5333333333333,32,444,633,0.00509029082307654,1 +"3024",2015-02-13 17:10:59,21.525,32.0225,444,621.5,0.00509127997106236,1 +"3025",2015-02-13 17:12:00,21.5333333333333,32,444,619,0.00509029082307654,1 +"3026",2015-02-13 17:12:59,21.5,32.09,440.25,619,0.00509423237108781,1 +"3027",2015-02-13 17:13:59,21.5,32.09,440.25,624.75,0.00509423237108781,1 +"3028",2015-02-13 17:15:00,21.5,32.0675,436.5,620.25,0.00509063130178034,1 +"3029",2015-02-13 17:16:00,21.5,32,434,615,0.00507982834200202,1 +"3030",2015-02-13 17:17:00,21.5,32.06,429,615.666666666667,0.00508943095453518,1 +"3031",2015-02-13 17:18:00,21.5,32.09,429,615,0.00509423237108781,1 +"3032",2015-02-13 17:19:00,21.5,32.09,429,614,0.00509423237108781,1 +"3033",2015-02-13 17:19:59,21.5,32.09,429,606.75,0.00509423237108781,1 +"3034",2015-02-13 17:21:00,21.5,32.09,429,603,0.00509423237108781,1 +"3035",2015-02-13 17:22:00,21.5,32.1725,429,603,0.0051074366457325,1 +"3036",2015-02-13 17:23:00,21.4633333333333,32.1633333333333,429,602.333333333333,0.00509442310420516,1 +"3037",2015-02-13 17:23:59,21.5,32.1266666666667,429,605,0.00510010086894725,1 +"3038",2015-02-13 17:25:00,21.445,32.145,429,601,0.0050857342855617,1 +"3039",2015-02-13 17:25:59,21.4175,32.1175,429,599.25,0.0050727244222225,1 +"3040",2015-02-13 17:26:59,21.39,32.09,429,598.5,0.00505974255031613,1 +"3041",2015-02-13 17:28:00,21.39,32.145,429,594.75,0.00506848525849145,1 +"3042",2015-02-13 17:29:00,21.445,32.145,438,599.5,0.0050857342855617,0 +"3043",2015-02-13 17:30:00,21.39,32.09,441,600,0.00505974255031613,0 +"3044",2015-02-13 17:31:00,21.39,32.1725,423.5,587.5,0.0050728567040004,1 +"3045",2015-02-13 17:31:59,21.39,32.145,423.5,588.75,0.00506848525849145,1 +"3046",2015-02-13 17:32:59,21.315,32.2,428.25,580.75,0.00505374936473684,1 +"3047",2015-02-13 17:34:00,21.29,32.2,423.5,575.75,0.00504594442999233,1 +"3048",2015-02-13 17:35:00,21.3233333333333,32.26,426.666666666667,573,0.0050658518907916,1 +"3049",2015-02-13 17:36:00,21.3233333333333,32.29,433,585.333333333333,0.00507060125456876,1 +"3050",2015-02-13 17:37:00,21.29,32.29,433,586.25,0.005060162738304,1 +"3051",2015-02-13 17:38:00,21.29,32.3175,433,586.25,0.00506450735001229,1 +"3052",2015-02-13 17:38:59,21.3233333333333,32.3266666666667,433,583,0.00507640613021972,1 +"3053",2015-02-13 17:39:59,21.29,32.3725,433,583.75,0.00507319675404227,1 +"3054",2015-02-13 17:41:00,21.29,32.4,433,585,0.00507754154636647,1 +"3055",2015-02-13 17:42:00,21.29,32.4,433,582,0.00507754154636647,1 +"3056",2015-02-13 17:43:00,21.29,32.4,433,584,0.00507754154636647,1 +"3057",2015-02-13 17:44:00,21.29,32.4,426,585,0.00507754154636647,1 +"3058",2015-02-13 17:44:59,21.29,32.4666666666667,419,582,0.00508807462614412,1 +"3059",2015-02-13 17:45:59,21.29,32.475,419,575,0.00508939128599647,1 +"3060",2015-02-13 17:47:00,21.29,32.4666666666667,419,578.666666666667,0.00508807462614412,1 +"3061",2015-02-13 17:48:00,21.29,32.4666666666667,419,578,0.00508807462614412,1 +"3062",2015-02-13 17:49:00,21.29,32.5675,419,579,0.005104006581668,1 +"3063",2015-02-13 17:50:00,21.29,32.53,419,575,0.0050980813796919,1 +"3064",2015-02-13 17:51:00,21.29,32.5675,419,571,0.005104006581668,1 +"3065",2015-02-13 17:51:59,21.23,32.53,419,573,0.0050791983134978,1 +"3066",2015-02-13 17:53:00,21.2675,32.5675,419,573,0.00509690986919828,1 +"3067",2015-02-13 17:54:00,21.29,32.59,419,575.666666666667,0.00510756175659946,1 +"3068",2015-02-13 17:55:00,21.245,32.59,419,578.5,0.00509336709226649,1 +"3069",2015-02-13 17:55:59,21.2225,32.6175,419,577.5,0.00509060986038533,1 +"3070",2015-02-13 17:57:00,21.29,32.7,419,576,0.00512494319210037,1 +"3071",2015-02-13 17:57:59,21.245,32.7,419,573.5,0.00511069982853226,1 +"3072",2015-02-13 17:58:59,21.245,32.6725,419,573.75,0.00510636655464018,1 +"3073",2015-02-13 18:00:00,21.29,32.7,419,574.666666666667,0.00512494319210037,1 +"3074",2015-02-13 18:01:00,21.29,32.7,419,568.5,0.00512494319210037,1 +"3075",2015-02-13 18:02:00,21.245,32.7,419,571.5,0.00511069982853226,1 +"3076",2015-02-13 18:03:00,21.2,32.7,419,574.333333333333,0.00509649145910912,1 +"3077",2015-02-13 18:04:00,21.2675,32.7225,411.5,572,0.0051213675596474,1 +"3078",2015-02-13 18:04:59,21.29,32.79,0,577,0.00513916508328268,1 +"3079",2015-02-13 18:06:00,21.29,32.73,0,582.333333333333,0.00512968375082379,0 +"3080",2015-02-13 18:07:00,21.29,32.7,0,586,0.00512494319210037,0 +"3081",2015-02-13 18:08:00,21.29,32.645,0,586,0.005116252353912,0 +"3082",2015-02-13 18:08:59,21.39,32.59,0,586,0.00513923068232968,0 +"3083",2015-02-13 18:10:00,21.34,32.59,0,583,0.00512337459613129,0 +"3084",2015-02-13 18:10:59,21.39,32.59,0,582,0.00513923068232968,0 +"3085",2015-02-13 18:11:59,21.34,32.545,0,579.5,0.00511624209370366,0 +"3086",2015-02-13 18:13:00,21.29,32.5,0,578,0.0050933412987279,0 +"3087",2015-02-13 18:14:00,21.3566666666667,32.5,0,580,0.0051143754829636,0 +"3088",2015-02-13 18:15:00,21.39,32.5,0,578,0.00512492133135788,0 +"3089",2015-02-13 18:16:00,21.39,32.4,0,572,0.00510902281833226,0 +"3090",2015-02-13 18:16:59,21.34,32.45,0,573,0.00510118512135762,0 +"3091",2015-02-13 18:17:59,21.34,32.5,0,574.5,0.00510910975351528,0 +"3092",2015-02-13 18:19:00,21.39,32.4,0,569,0.00510902281833226,0 +"3093",2015-02-13 18:20:00,21.39,32.4,0,564,0.00510902281833226,0 +"3094",2015-02-13 18:21:00,21.315,32.5,0,561,0.00510122014212673,0 +"3095",2015-02-13 18:22:00,21.29,32.5,0,560,0.0050933412987279,0 +"3096",2015-02-13 18:23:00,21.29,32.5,0,553.5,0.0050933412987279,0 +"3097",2015-02-13 18:23:59,21.29,32.5,0,551.333333333333,0.0050933412987279,0 +"3098",2015-02-13 18:24:59,21.29,32.5,0,557,0.0050933412987279,0 +"3099",2015-02-13 18:26:00,21.29,32.5,0,556.5,0.0050933412987279,0 +"3100",2015-02-13 18:27:00,21.29,32.45,0,554.5,0.00508544132302639,0 +"3101",2015-02-13 18:28:00,21.29,32.45,0,549.75,0.00508544132302639,0 +"3102",2015-02-13 18:29:00,21.29,32.5,0,553.5,0.0050933412987279,0 +"3103",2015-02-13 18:29:59,21.29,32.5,0,556,0.0050933412987279,0 +"3104",2015-02-13 18:30:59,21.29,32.5,0,551,0.0050933412987279,0 +"3105",2015-02-13 18:32:00,21.29,32.5,0,543,0.0050933412987279,0 +"3106",2015-02-13 18:33:00,21.29,32.5,0,546.5,0.0050933412987279,0 +"3107",2015-02-13 18:34:00,21.29,32.59,0,545,0.00510756175659946,0 +"3108",2015-02-13 18:35:00,21.29,32.5,0,543,0.0050933412987279,0 +"3109",2015-02-13 18:36:00,21.29,32.5,0,537,0.0050933412987279,0 +"3110",2015-02-13 18:36:59,21.245,32.45,0,544,0.0050713086317725,0 +"3111",2015-02-13 18:38:00,21.29,32.5,0,547,0.0050933412987279,0 +"3112",2015-02-13 18:39:00,21.29,32.475,0,541.5,0.00508939128599647,0 +"3113",2015-02-13 18:40:00,21.29,32.4,0,542,0.00507754154636647,0 +"3114",2015-02-13 18:40:59,21.29,32.4666666666667,0,541,0.00508807462614412,0 +"3115",2015-02-13 18:42:00,21.245,32.4,0,539,0.00506343098624753,0 +"3116",2015-02-13 18:42:59,21.29,32.4,0,537,0.00507754154636647,0 +"3117",2015-02-13 18:43:59,21.245,32.4,0,535.5,0.00506343098624753,0 +"3118",2015-02-13 18:45:00,21.26,32.4,0,534.333333333333,0.00506813065130459,0 +"3119",2015-02-13 18:46:00,21.245,32.4,0,534,0.00506343098624753,0 +"3120",2015-02-13 18:47:00,21.23,32.4333333333333,0,534.75,0.00506398200442409,0 +"3121",2015-02-13 18:48:00,21.2,32.4,0,537,0.0050493550880857,0 +"3122",2015-02-13 18:49:00,21.2,32.4,0,535,0.0050493550880857,0 +"3123",2015-02-13 18:49:59,21.2,32.4,0,530.333333333333,0.0050493550880857,0 +"3124",2015-02-13 18:51:00,21.2,32.4,0,529,0.0050493550880857,0 +"3125",2015-02-13 18:52:00,21.2,32.4,0,528,0.0050493550880857,0 +"3126",2015-02-13 18:53:00,21.2,32.4,0,526,0.0050493550880857,0 +"3127",2015-02-13 18:53:59,21.2,32.4,0,532.333333333333,0.0050493550880857,0 +"3128",2015-02-13 18:55:00,21.2,32.4,0,534,0.0050493550880857,0 +"3129",2015-02-13 18:55:59,21.175,32.3725,0,531,0.00503723634736724,0 +"3130",2015-02-13 18:56:59,21.2,32.4,0,528,0.0050493550880857,0 +"3131",2015-02-13 18:58:00,21.1,32.4,0,525,0.00501819904052598,0 +"3132",2015-02-13 18:59:00,21.1666666666667,32.4,0,526.333333333333,0.00503895080052938,0 +"3133",2015-02-13 19:00:00,21.1,32.4,0,526,0.00501819904052598,0 +"3134",2015-02-13 19:01:00,21.2,32.345,0,524.5,0.00504071418870028,0 +"3135",2015-02-13 19:01:59,21.1333333333333,32.3266666666667,0,522.333333333333,0.00501709213043349,0 +"3136",2015-02-13 19:02:59,21.1,32.29,0,521.5,0.00500102496279949,0 +"3137",2015-02-13 19:04:00,21.15,32.29,0,521.5,0.00501652801988182,0 +"3138",2015-02-13 19:05:00,21.15,32.4,0,518.5,0.00503375576425692,0 +"3139",2015-02-13 19:06:00,21.1,32.345,0,519,0.00500961188406129,0 +"3140",2015-02-13 19:07:00,21.1,32.3633333333333,0,520.333333333333,0.00501247424341539,0 +"3141",2015-02-13 19:08:00,21.1,32.345,0,522,0.00500961188406129,0 +"3142",2015-02-13 19:08:59,21.1,32.3266666666667,0,518.666666666667,0.00500674955084085,0 +"3143",2015-02-13 19:09:59,21.1,32.29,0,518,0.00500102496279949,0 +"3144",2015-02-13 19:11:00,21.1,32.29,0,518.666666666667,0.00500102496279949,0 +"3145",2015-02-13 19:12:00,21.1,32.29,0,524,0.00500102496279949,0 +"3146",2015-02-13 19:13:00,21.1,32.29,0,523.5,0.00500102496279949,0 +"3147",2015-02-13 19:14:00,21.05,32.245,0,515,0.00497856065948955,0 +"3148",2015-02-13 19:14:59,21,32.2,0,515,0.00495618242297541,0 +"3149",2015-02-13 19:15:59,21,32.2,0,517,0.00495618242297541,0 +"3150",2015-02-13 19:17:00,21,32.2,0,520,0.00495618242297541,0 +"3151",2015-02-13 19:18:00,21,32.2,0,518,0.00495618242297541,0 +"3152",2015-02-13 19:19:00,21,32.2,0,519.5,0.00495618242297541,0 +"3153",2015-02-13 19:20:00,21,32.2,0,518,0.00495618242297541,0 +"3154",2015-02-13 19:21:00,20.9633333333333,32.2,0,519.333333333333,0.00494493428856739,0 +"3155",2015-02-13 19:21:59,21,32.2,0,521,0.00495618242297541,0 +"3156",2015-02-13 19:23:00,20.945,32.2,0,519.5,0.00493931868467299,0 +"3157",2015-02-13 19:24:00,20.9633333333333,32.2,0,517,0.00494493428856739,0 +"3158",2015-02-13 19:25:00,21,32.2,0,519.333333333333,0.00495618242297541,0 +"3159",2015-02-13 19:25:59,20.9266666666667,32.2,0,510.666666666667,0.00493370871643604,0 +"3160",2015-02-13 19:27:00,20.89,32.145,0,511,0.00491403123435799,0 +"3161",2015-02-13 19:27:59,20.89,32.09,0,514.5,0.00490555703050911,0 +"3162",2015-02-13 19:28:59,20.89,32.145,0,515.5,0.00491403123435799,0 +"3163",2015-02-13 19:30:00,20.89,32.09,0,513,0.00490555703050911,0 +"3164",2015-02-13 19:31:00,20.89,32.145,0,513,0.00491403123435799,0 +"3165",2015-02-13 19:32:00,20.89,32.09,0,511,0.00490555703050911,0 +"3166",2015-02-13 19:33:00,20.89,32.09,0,508.666666666667,0.00490555703050911,0 +"3167",2015-02-13 19:34:00,20.89,32.09,0,509,0.00490555703050911,0 +"3168",2015-02-13 19:34:59,20.89,32.09,0,510.75,0.00490555703050911,0 +"3169",2015-02-13 19:36:00,20.89,32.09,0,510,0.00490555703050911,0 +"3170",2015-02-13 19:37:00,20.84,32.045,0,510,0.00488345761995822,0 +"3171",2015-02-13 19:38:00,20.84,32.045,0,510,0.00488345761995822,0 +"3172",2015-02-13 19:38:59,20.79,32,0,511,0.00486144306830351,0 +"3173",2015-02-13 19:40:00,20.89,32.09,0,515.5,0.00490555703050911,0 +"3174",2015-02-13 19:40:59,20.8566666666667,31.9933333333333,0,518,0.00488056471865244,0 +"3175",2015-02-13 19:41:59,20.79,31.89,0,514,0.0048446016983366,0 +"3176",2015-02-13 19:43:00,20.84,31.945,0,511.5,0.00486809897390912,0 +"3177",2015-02-13 19:44:00,20.79,32,0,512.5,0.00486144306830351,0 +"3178",2015-02-13 19:45:00,20.79,31.9175,0,512.25,0.00484881195599091,0 +"3179",2015-02-13 19:46:00,20.79,31.89,0,514,0.0048446016983366,0 +"3180",2015-02-13 19:46:59,20.79,31.89,0,516,0.0048446016983366,0 +"3181",2015-02-13 19:47:59,20.79,31.89,0,512,0.0048446016983366,0 +"3182",2015-02-13 19:49:00,20.79,31.8566666666667,0,515,0.0048394984315492,0 +"3183",2015-02-13 19:50:00,20.79,31.79,0,509,0.00482929214725061,0 +"3184",2015-02-13 19:51:00,20.745,31.89,0,508.5,0.00483109161722008,0 +"3185",2015-02-13 19:52:00,20.745,31.89,0,516,0.00483109161722008,0 +"3186",2015-02-13 19:53:00,20.7,31.89,0,518,0.00481761483395393,0 +"3187",2015-02-13 19:53:59,20.745,31.79,0,511,0.00481582508769021,0 +"3188",2015-02-13 19:54:59,20.7,31.79,0,517,0.00480239121811869,0 +"3189",2015-02-13 19:56:00,20.73,31.79,0,518.25,0.00481134344689619,0 +"3190",2015-02-13 19:57:00,20.7,31.79,0,511,0.00480239121811869,0 +"3191",2015-02-13 19:58:00,20.7,31.79,0,510.5,0.00480239121811869,0 +"3192",2015-02-13 19:59:00,20.7,31.79,0,512,0.00480239121811869,0 +"3193",2015-02-13 19:59:59,20.7,31.79,0,513,0.00480239121811869,0 +"3194",2015-02-13 20:00:59,20.7,31.79,0,511,0.00480239121811869,0 +"3195",2015-02-13 20:02:00,20.7,31.79,0,513,0.00480239121811869,0 +"3196",2015-02-13 20:03:00,20.7,31.79,0,512.5,0.00480239121811869,0 +"3197",2015-02-13 20:04:00,20.7,31.79,0,508.5,0.00480239121811869,0 +"3198",2015-02-13 20:05:00,20.7,31.76,0,509,0.00479782427756501,0 +"3199",2015-02-13 20:06:00,20.7,31.79,0,515,0.00480239121811869,0 +"3200",2015-02-13 20:06:59,20.7,31.79,0,515,0.00480239121811869,0 +"3201",2015-02-13 20:08:00,20.7,31.79,0,515,0.00480239121811869,0 +"3202",2015-02-13 20:09:00,20.65,31.745,0,518,0.00478067454929088,0 +"3203",2015-02-13 20:10:00,20.6,31.7,0,515,0.00475904149675229,0 +"3204",2015-02-13 20:10:59,20.7,31.7,0,513.5,0.00478869059610566,0 +"3205",2015-02-13 20:12:00,20.6,31.7,0,511,0.00475904149675229,0 +"3206",2015-02-13 20:12:59,20.7,31.7,0,512.5,0.00478869059610566,0 +"3207",2015-02-13 20:13:59,20.6,31.7,0,512,0.00475904149675229,0 +"3208",2015-02-13 20:15:00,20.6,31.6333333333333,0,517.666666666667,0.00474895658260734,0 +"3209",2015-02-13 20:16:00,20.6,31.65,0,514.5,0.00475147778071744,0 +"3210",2015-02-13 20:17:00,20.6,31.6,0,512.5,0.00474391424723795,0 +"3211",2015-02-13 20:18:00,20.6,31.6,0,511.5,0.00474391424723795,0 +"3212",2015-02-13 20:19:00,20.6,31.6,0,512,0.00474391424723795,0 +"3213",2015-02-13 20:19:59,20.6,31.5666666666667,0,511,0.00473887199300134,0 +"3214",2015-02-13 20:21:00,20.6,31.6,0,511,0.00474391424723795,0 +"3215",2015-02-13 20:22:00,20.6,31.6,0,505.5,0.00474391424723795,0 +"3216",2015-02-13 20:23:00,20.6,31.55,0,507.5,0.00473635089630721,0 +"3217",2015-02-13 20:23:59,20.5,31.5,0,509,0.00469948978389975,0 +"3218",2015-02-13 20:25:00,20.6,31.5,0,513.333333333333,0.0047287877279186,0 +"3219",2015-02-13 20:25:59,20.55,31.5,0,514,0.00471411864861635,0 +"3220",2015-02-13 20:26:59,20.6,31.5,0,513,0.0047287877279186,0 +"3221",2015-02-13 20:28:00,20.5333333333333,31.5,0,512,0.00470923789681501,0 +"3222",2015-02-13 20:29:00,20.5,31.5,0,516,0.00469948978389975,0 +"3223",2015-02-13 20:30:00,20.5,31.5,0,514.333333333333,0.00469948978389975,0 +"3224",2015-02-13 20:31:00,20.55,31.5,0,513,0.00471411864861635,0 +"3225",2015-02-13 20:31:59,20.5,31.5,0,514.5,0.00469948978389975,0 +"3226",2015-02-13 20:32:59,20.5,31.5,0,513,0.00469948978389975,0 +"3227",2015-02-13 20:34:00,20.5,31.5,0,513.5,0.00469948978389975,0 +"3228",2015-02-13 20:35:00,20.5,31.5,0,507.5,0.00469948978389975,0 +"3229",2015-02-13 20:36:00,20.5,31.5,0,511.5,0.00469948978389975,0 +"3230",2015-02-13 20:37:00,20.5,31.5,0,512,0.00469948978389975,0 +"3231",2015-02-13 20:38:00,20.5,31.445,0,507,0.00469122243868141,0 +"3232",2015-02-13 20:38:59,20.5,31.5,0,511.5,0.00469948978389975,0 +"3233",2015-02-13 20:39:59,20.5,31.39,0,517,0.00468295531158386,0 +"3234",2015-02-13 20:41:00,20.5,31.445,0,510.5,0.00469122243868141,0 +"3235",2015-02-13 20:42:00,20.5,31.5,0,508.5,0.00469948978389975,0 +"3236",2015-02-13 20:43:00,20.5,31.4266666666667,0,511.666666666667,0.00468846670541367,0 +"3237",2015-02-13 20:44:00,20.5,31.445,0,514,0.00469122243868141,0 +"3238",2015-02-13 20:44:59,20.5,31.39,0,515,0.00468295531158386,0 +"3239",2015-02-13 20:45:59,20.5,31.39,0,515,0.00468295531158386,0 +"3240",2015-02-13 20:47:00,20.5,31.39,0,512,0.00468295531158386,0 +"3241",2015-02-13 20:48:00,20.5,31.39,0,507,0.00468295531158386,0 +"3242",2015-02-13 20:49:00,20.5,31.39,0,510.5,0.00468295531158386,0 +"3243",2015-02-13 20:50:00,20.445,31.34,0,514.5,0.00465947723699815,0 +"3244",2015-02-13 20:51:00,20.4725,31.34,0,511.5,0.00466745255559264,0 +"3245",2015-02-13 20:51:59,20.5,31.29,0,508,0.00466792473020021,0 +"3246",2015-02-13 20:53:00,20.39,31.29,0,512,0.00463609912371531,0 +"3247",2015-02-13 20:54:00,20.5,31.29,0,509.5,0.00466792473020021,0 +"3248",2015-02-13 20:55:00,20.5,31.29,0,512,0.00466792473020021,0 +"3249",2015-02-13 20:55:59,20.445,31.245,0,514.666666666667,0.00464524762123115,0 +"3250",2015-02-13 20:57:00,20.445,31.245,0,514.5,0.00464524762123115,0 +"3251",2015-02-13 20:57:59,20.5,31.29,0,516,0.00466792473020021,0 +"3252",2015-02-13 20:58:59,20.445,31.245,0,510.5,0.00464524762123115,0 +"3253",2015-02-13 21:00:00,20.39,31.2,0,507.5,0.00462266512278733,0 +"3254",2015-02-13 21:01:00,20.39,31.2,0,514,0.00462266512278733,0 +"3255",2015-02-13 21:02:00,20.39,31.2,0,516,0.00462266512278733,0 +"3256",2015-02-13 21:03:00,20.39,31.2,0,512.5,0.00462266512278733,0 +"3257",2015-02-13 21:04:00,20.39,31.2,0,513,0.00462266512278733,0 +"3258",2015-02-13 21:04:59,20.39,31.2,0,512.5,0.00462266512278733,0 +"3259",2015-02-13 21:06:00,20.39,31.2,0,509,0.00462266512278733,0 +"3260",2015-02-13 21:07:00,20.39,31.2,0,505,0.00462266512278733,0 +"3261",2015-02-13 21:08:00,20.39,31.1666666666667,0,515,0.00461768971306071,0 +"3262",2015-02-13 21:08:59,20.39,31.2,0,517,0.00462266512278733,0 +"3263",2015-02-13 21:10:00,20.39,31.2,0,516,0.00462266512278733,0 +"3264",2015-02-13 21:10:59,20.39,31.1,0,515,0.00460773913063346,0 +"3265",2015-02-13 21:11:59,20.39,31.2,0,516.333333333333,0.00462266512278733,0 +"3266",2015-02-13 21:13:00,20.39,31.15,0,511,0.004615202037826,0 +"3267",2015-02-13 21:14:00,20.39,31.15,0,513.5,0.004615202037826,0 +"3268",2015-02-13 21:15:00,20.39,31.2,0,507.666666666667,0.00462266512278733,0 +"3269",2015-02-13 21:16:00,20.39,31.2,0,509,0.00462266512278733,0 +"3270",2015-02-13 21:16:59,20.39,31.1,0,513,0.00460773913063346,0 +"3271",2015-02-13 21:17:59,20.39,31.15,0,512.5,0.004615202037826,0 +"3272",2015-02-13 21:19:00,20.39,31.2,0,510,0.00462266512278733,0 +"3273",2015-02-13 21:20:00,20.39,31.2,0,511,0.00462266512278733,0 +"3274",2015-02-13 21:21:00,20.39,31.15,0,514,0.004615202037826,0 +"3275",2015-02-13 21:22:00,20.39,31.1666666666667,0,507.666666666667,0.00461768971306071,0 +"3276",2015-02-13 21:23:00,20.39,31.2,0,514,0.00462266512278733,0 +"3277",2015-02-13 21:23:59,20.34,31.2,0,515,0.00460830445582707,0 +"3278",2015-02-13 21:24:59,20.39,31.2,0,514,0.00462266512278733,0 +"3279",2015-02-13 21:26:00,20.3566666666667,31.2,0,510.333333333333,0.00461308695981688,0 +"3280",2015-02-13 21:27:00,20.39,31.2,0,518.5,0.00462266512278733,0 +"3281",2015-02-13 21:28:00,20.39,31.2,0,513.5,0.00462266512278733,0 +"3282",2015-02-13 21:29:00,20.29,31.2,0,512,0.00459398321209564,0 +"3283",2015-02-13 21:29:59,20.29,31.2,0,511,0.00459398321209564,0 +"3284",2015-02-13 21:30:59,20.39,31.2,0,510,0.00462266512278733,0 +"3285",2015-02-13 21:32:00,20.39,31.2,0,509,0.00462266512278733,0 +"3286",2015-02-13 21:33:00,20.29,31.2,0,511,0.00459398321209564,0 +"3287",2015-02-13 21:34:00,20.34,31.2,0,510.5,0.00460830445582707,0 +"3288",2015-02-13 21:35:00,20.29,31.2,0,514,0.00459398321209564,0 +"3289",2015-02-13 21:36:00,20.34,31.2,0,512,0.00460830445582707,0 +"3290",2015-02-13 21:36:59,20.29,31.2,0,510.5,0.00459398321209564,0 +"3291",2015-02-13 21:38:00,20.29,31.2,0,515.5,0.00459398321209564,0 +"3292",2015-02-13 21:39:00,20.29,31.2,0,511.666666666667,0.00459398321209564,0 +"3293",2015-02-13 21:40:00,20.29,31.2,0,508,0.00459398321209564,0 +"3294",2015-02-13 21:40:59,20.29,31.2,0,510,0.00459398321209564,0 +"3295",2015-02-13 21:42:00,20.29,31.2,0,506.5,0.00459398321209564,0 +"3296",2015-02-13 21:42:59,20.29,31.2,0,508,0.00459398321209564,0 +"3297",2015-02-13 21:43:59,20.29,31.2,0,512,0.00459398321209564,0 +"3298",2015-02-13 21:45:00,20.29,31.2,0,507,0.00459398321209564,0 +"3299",2015-02-13 21:46:00,20.29,31.2,0,504,0.00459398321209564,0 +"3300",2015-02-13 21:47:00,20.29,31.29,0,501,0.00460733324720036,0 +"3301",2015-02-13 21:48:00,20.245,31.2,0,510,0.00458112772205937,0 +"3302",2015-02-13 21:49:00,20.29,31.29,0,504,0.00460733324720036,0 +"3303",2015-02-13 21:49:59,20.29,31.29,0,508.5,0.00460733324720036,0 +"3304",2015-02-13 21:51:00,20.29,31.29,0,511,0.00460733324720036,0 +"3305",2015-02-13 21:52:00,20.29,31.29,0,510.5,0.00460733324720036,0 +"3306",2015-02-13 21:53:00,20.26,31.26,0,507,0.00459429257816965,0 +"3307",2015-02-13 21:53:59,20.29,31.29,0,511,0.00460733324720036,0 +"3308",2015-02-13 21:55:00,20.29,31.29,0,508,0.00460733324720036,0 +"3309",2015-02-13 21:55:59,20.29,31.29,0,510,0.00460733324720036,0 +"3310",2015-02-13 21:56:59,20.245,31.29,0,512,0.00459444012541152,0 +"3311",2015-02-13 21:58:00,20.29,31.34,0,511.5,0.00461475017917807,0 +"3312",2015-02-13 21:59:00,20.2,31.29,0,511.5,0.00458157888677931,0 +"3313",2015-02-13 22:00:00,20.2,31.29,0,513,0.00458157888677931,0 +"3314",2015-02-13 22:01:00,20.2,31.29,0,510,0.00458157888677931,0 +"3315",2015-02-13 22:01:59,20.245,31.34,0,515,0.0046018361494812,0 +"3316",2015-02-13 22:02:59,20.245,31.34,0,517,0.0046018361494812,0 +"3317",2015-02-13 22:04:00,20.26,31.3566666666667,0,513.333333333333,0.00460860497563174,0 +"3318",2015-02-13 22:05:00,20.29,31.39,0,509,0.00462216728674112,0 +"3319",2015-02-13 22:06:00,20.2,31.39,0,511.5,0.00459632939783347,0 +"3320",2015-02-13 22:07:00,20.2,31.39,0,513,0.00459632939783347,0 +"3321",2015-02-13 22:08:00,20.2,31.39,0,512.666666666667,0.00459632939783347,0 +"3322",2015-02-13 22:08:59,20.2,31.39,0,510.333333333333,0.00459632939783347,0 +"3323",2015-02-13 22:09:59,20.2,31.39,0,512,0.00459632939783347,0 +"3324",2015-02-13 22:11:00,20.2,31.39,0,512,0.00459632939783347,0 +"3325",2015-02-13 22:12:00,20.2,31.39,0,507,0.00459632939783347,0 +"3326",2015-02-13 22:13:00,20.2,31.5,0,505,0.00461255576215071,0 +"3327",2015-02-13 22:14:00,20.2,31.5,0,509,0.00461255576215071,0 +"3328",2015-02-13 22:14:59,20.2,31.5,0,513.75,0.00461255576215071,0 +"3329",2015-02-13 22:15:59,20.2,31.5,0,510,0.00461255576215071,0 +"3330",2015-02-13 22:17:00,20.15,31.5,0,514,0.00459820573374122,0 +"3331",2015-02-13 22:18:00,20.15,31.5,0,508,0.00459820573374122,0 +"3332",2015-02-13 22:19:00,20.2,31.5,0,514.5,0.00461255576215071,0 +"3333",2015-02-13 22:20:00,20.2,31.6,0,513,0.00462730773172657,0 +"3334",2015-02-13 22:21:00,20.15,31.6,0,511,0.00461291147090429,0 +"3335",2015-02-13 22:21:59,20.2,31.6,0,513,0.00462730773172657,0 +"3336",2015-02-13 22:23:00,20.1333333333333,31.6,0,511.666666666667,0.00460812151851077,0 +"3337",2015-02-13 22:24:00,20.15,31.6,0,511,0.00461291147090429,0 +"3338",2015-02-13 22:25:00,20.1,31.6,0,508,0.00459855479455644,0 +"3339",2015-02-13 22:25:59,20.15,31.6,0,512.5,0.00461291147090429,0 +"3340",2015-02-13 22:27:00,20.2,31.6,0,510.5,0.00462730773172657,0 +"3341",2015-02-13 22:27:59,20.15,31.6,0,512,0.00461291147090429,0 +"3342",2015-02-13 22:28:59,20.1,31.6,0,511,0.00459855479455644,0 +"3343",2015-02-13 22:30:00,20.1,31.6,0,512.5,0.00459855479455644,0 +"3344",2015-02-13 22:31:00,20.1,31.6,0,515,0.00459855479455644,0 +"3345",2015-02-13 22:32:00,20.1666666666667,31.6,0,517.333333333333,0.00461770582157118,0 +"3346",2015-02-13 22:33:00,20.1,31.6,0,512,0.00459855479455644,0 +"3347",2015-02-13 22:34:00,20.1,31.6,0,511,0.00459855479455644,0 +"3348",2015-02-13 22:34:59,20.175,31.65,0,511.25,0.00462746932561189,0 +"3349",2015-02-13 22:36:00,20.2,31.7,0,511.5,0.00464206039591261,0 +"3350",2015-02-13 22:37:00,20.2,31.7,0,512,0.00464206039591261,0 +"3351",2015-02-13 22:38:00,20.15,31.7,0,510.5,0.00462761789834634,0 +"3352",2015-02-13 22:38:59,20.2,31.7,0,508.5,0.00464206039591261,0 +"3353",2015-02-13 22:40:00,20.2,31.7,0,511,0.00464206039591261,0 +"3354",2015-02-13 22:40:59,20.15,31.7,0,513.5,0.00462761789834634,0 +"3355",2015-02-13 22:41:59,20.1,31.7,0,512.5,0.00461321511449568,0 +"3356",2015-02-13 22:43:00,20.1666666666667,31.79,0,513.666666666667,0.00464567788112868,0 +"3357",2015-02-13 22:44:00,20.1,31.79,0,511,0.00462640998898792,0 +"3358",2015-02-13 22:45:00,20.15,31.79,0,513,0.00464085427327286,0 +"3359",2015-02-13 22:46:00,20.15,31.79,0,507.5,0.00464085427327286,0 +"3360",2015-02-13 22:46:59,20.15,31.79,0,513,0.00464085427327286,0 +"3361",2015-02-13 22:47:59,20.1,31.79,0,512.5,0.00462640998898792,0 +"3362",2015-02-13 22:49:00,20.1,31.79,0,507,0.00462640998898792,0 +"3363",2015-02-13 22:50:00,20.175,31.79,0,511,0.00464809134574222,0 +"3364",2015-02-13 22:51:00,20.1,31.79,0,506,0.00462640998898792,0 +"3365",2015-02-13 22:52:00,20.15,31.79,0,504,0.00464085427327286,0 +"3366",2015-02-13 22:53:00,20.15,31.79,0,506.5,0.00464085427327286,0 +"3367",2015-02-13 22:53:59,20.1,31.79,0,509,0.00462640998898792,0 +"3368",2015-02-13 22:54:59,20.2,31.79,0,511,0.0046553383876123,0 +"3369",2015-02-13 22:56:00,20.1333333333333,31.79,0,511.333333333333,0.00463603509097707,0 +"3370",2015-02-13 22:57:00,20.1,31.89,0,513,0.00464107161240899,0 +"3371",2015-02-13 22:58:00,20.1333333333333,31.89,0,508.333333333333,0.00465072744383843,0 +"3372",2015-02-13 22:59:00,20.1,31.89,0,506,0.00464107161240899,0 +"3373",2015-02-13 22:59:59,20.1,31.89,0,503,0.00464107161240899,0 +"3374",2015-02-13 23:00:59,20.1333333333333,31.9633333333333,0,506.333333333333,0.00466150227381999,0 +"3375",2015-02-13 23:02:00,20.1,32,0,508.5,0.00465720019063442,0 +"3376",2015-02-13 23:03:00,20.1,32,0,511.5,0.00465720019063442,0 +"3377",2015-02-13 23:04:00,20.1333333333333,32.09,0,506.666666666667,0.00468011421655387,0 +"3378",2015-02-13 23:05:00,20.1,32.09,0,502,0.00467039691763799,0 +"3379",2015-02-13 23:06:00,20.1,32.09,0,503,0.00467039691763799,0 +"3380",2015-02-13 23:06:59,20.15,32.09,0,506,0.00468497956189922,0 +"3381",2015-02-13 23:08:00,20.1333333333333,32.1633333333333,0,503,0.00469089005713866,0 +"3382",2015-02-13 23:09:00,20.1333333333333,32.2,0,502.666666666667,0.00469627811640117,0 +"3383",2015-02-13 23:10:00,20.15,32.245,0,502,0.0047077800625428,0 +"3384",2015-02-13 23:10:59,20.1,32.345,0,508.666666666667,0.0047077906627275,0 +"3385",2015-02-13 23:12:00,20.1,32.4,0,509.5,0.00471585656536653,0 +"3386",2015-02-13 23:12:59,20.1,32.4,0,505.666666666667,0.00471585656536653,0 +"3387",2015-02-13 23:13:59,20.1,32.45,0,509.5,0.00472318938429821,0 +"3388",2015-02-13 23:15:00,20.1,32.53,0,510,0.00473492225151038,0 +"3389",2015-02-13 23:16:00,20.1,32.59,0,510,0.00474372219021507,0 +"3390",2015-02-13 23:17:00,20.1,32.59,0,510.5,0.00474372219021507,0 +"3391",2015-02-13 23:18:00,20.1,32.645,0,509.5,0.00475178901778397,0 +"3392",2015-02-13 23:19:00,20.1,32.7,0,508,0.00475985605301206,0 +"3393",2015-02-13 23:19:59,20.1,32.745,0,499,0.00476645650902515,0 +"3394",2015-02-13 23:21:00,20.1,32.745,0,500.5,0.00476645650902515,0 +"3395",2015-02-13 23:22:00,20,32.79,0,505,0.0047433688137961,0 +"3396",2015-02-13 23:23:00,20,32.7,0,505,0.0047302504926255,0 +"3397",2015-02-13 23:23:59,20.1,32.845,0,508.5,0.00478112468679117,0 +"3398",2015-02-13 23:25:00,20.1,32.8633333333333,0,511,0.00478381392718762,0 +"3399",2015-02-13 23:25:59,20.1,32.95,0,507.5,0.00479652701237058,0 +"3400",2015-02-13 23:26:59,20,32.9,0,509.5,0.00475940306325293,0 +"3401",2015-02-13 23:28:00,20.1,33,0,512,0.00480386171918592,0 +"3402",2015-02-13 23:29:00,20.1,33.09,0,510.5,0.00481706462404567,0 +"3403",2015-02-13 23:30:00,20.05,33.09,0,509,0.00480206191343434,0 +"3404",2015-02-13 23:31:00,20,33.09,0,507,0.00478710051752731,0 +"3405",2015-02-13 23:31:59,20.05,33.2,0,506,0.00481814890562586,0 +"3406",2015-02-13 23:32:59,20.05,33.145,0,510.5,0.00481010530631251,0 +"3407",2015-02-13 23:34:00,20.1,33.2,0,505,0.00483320226312693,0 +"3408",2015-02-13 23:35:00,20,33.2,0,502,0.0048031370047054,0 +"3409",2015-02-13 23:36:00,20,33.245,0,505,0.00480969762234042,0 +"3410",2015-02-13 23:37:00,20,33.29,0,506.333333333333,0.0048162583773141,0 +"3411",2015-02-13 23:38:00,20,33.29,0,507.5,0.0048162583773141,0 +"3412",2015-02-13 23:38:59,20,33.345,0,508,0.00482427726435308,0 +"3413",2015-02-13 23:39:59,20.05,33.4,0,509,0.0048474000979977,0 +"3414",2015-02-13 23:41:00,20,33.4,0,505.5,0.00483229635656662,0 +"3415",2015-02-13 23:42:00,20,33.4,0,507,0.00483229635656662,0 +"3416",2015-02-13 23:43:00,20,33.4,0,503,0.00483229635656662,0 +"3417",2015-02-13 23:44:00,20,33.4,0,508,0.00483229635656662,0 +"3418",2015-02-13 23:44:59,20,33.5,0,509,0.00484687704990708,0 +"3419",2015-02-13 23:45:59,20,33.59,0,512,0.00486000025388971,0 +"3420",2015-02-13 23:47:00,20,33.56,0,513,0.00485562579150977,0 +"3421",2015-02-13 23:48:00,20,33.59,0,512,0.00486000025388971,0 +"3422",2015-02-13 23:49:00,20,33.545,0,506,0.00485343858321468,0 +"3423",2015-02-13 23:50:00,20,33.59,0,504,0.00486000025388971,0 +"3424",2015-02-13 23:51:00,20,33.5,0,506,0.00484687704990708,0 +"3425",2015-02-13 23:51:59,20,33.5,0,513,0.00484687704990708,0 +"3426",2015-02-13 23:53:00,20.05,33.545,0,508,0.004868608919679,0 +"3427",2015-02-13 23:54:00,20,33.5,0,508,0.00484687704990708,0 +"3428",2015-02-13 23:55:00,20.025,33.545,0,509,0.0048610185199955,0 +"3429",2015-02-13 23:55:59,20.1,33.59,0,505,0.00489042422515518,0 +"3430",2015-02-13 23:57:00,20,33.5,0,504.5,0.00484687704990708,0 +"3431",2015-02-13 23:57:59,20,33.5,0,500.5,0.00484687704990708,0 +"3432",2015-02-13 23:58:59,20,33.5,0,502,0.00484687704990708,0 +"3433",2015-02-14 00:00:00,20.1,33.59,0,505.5,0.00489042422515518,0 +"3434",2015-02-14 00:01:00,20.05,33.545,0,507,0.004868608919679,0 +"3435",2015-02-14 00:02:00,20.0333333333333,33.6266666666667,0,505.333333333333,0.00487548080474089,0 +"3436",2015-02-14 00:03:00,20,33.59,0,505.5,0.00486000025388971,0 +"3437",2015-02-14 00:04:00,20,33.645,0,504.5,0.00486802026015828,0 +"3438",2015-02-14 00:04:59,20,33.6266666666667,0,504.666666666667,0.00486534690193387,0 +"3439",2015-02-14 00:06:00,20,33.645,0,507.5,0.00486802026015828,0 +"3440",2015-02-14 00:07:00,20,33.7,0,509,0.00487604047164436,0 +"3441",2015-02-14 00:08:00,20,33.59,0,511,0.00486000025388971,0 +"3442",2015-02-14 00:08:59,20.0333333333333,33.6266666666667,0,506.666666666667,0.00487548080474089,0 +"3443",2015-02-14 00:10:00,20,33.59,0,509,0.00486000025388971,0 +"3444",2015-02-14 00:10:59,20,33.7,0,509,0.00487604047164436,0 +"3445",2015-02-14 00:11:59,20,33.7,0,506,0.00487604047164436,0 +"3446",2015-02-14 00:13:00,20,33.7,0,502.5,0.00487604047164436,0 +"3447",2015-02-14 00:14:00,20,33.79,0,499,0.00488916489675597,0 +"3448",2015-02-14 00:15:00,20,33.79,0,501.5,0.00488916489675597,0 +"3449",2015-02-14 00:16:00,20,33.79,0,505,0.00488916489675597,0 +"3450",2015-02-14 00:16:59,20,33.79,0,504.5,0.00488916489675597,0 +"3451",2015-02-14 00:17:59,20,33.79,0,501.5,0.00488916489675597,0 +"3452",2015-02-14 00:19:00,20,33.95,0,503.5,0.00491249856503486,0 +"3453",2015-02-14 00:20:00,20,34,0,505,0.00491979069260134,0 +"3454",2015-02-14 00:21:00,19.9633333333333,34,0,508,0.00490853943683116,0 +"3455",2015-02-14 00:22:00,20,34,0,508,0.00491979069260134,0 +"3456",2015-02-14 00:23:00,20,34,0,509.666666666667,0.00491979069260134,0 +"3457",2015-02-14 00:23:59,20,34.09,0,504.333333333333,0.00493291694972601,0 +"3458",2015-02-14 00:24:59,20,34.09,0,506.333333333333,0.00493291694972601,0 +"3459",2015-02-14 00:26:00,20,34.09,0,506.5,0.00493291694972601,0 +"3460",2015-02-14 00:27:00,20,34.145,0,506,0.004940938821898,0 +"3461",2015-02-14 00:28:00,20,34.045,0,502.5,0.00492635375245599,0 +"3462",2015-02-14 00:29:00,20,34.09,0,502.5,0.00493291694972601,0 +"3463",2015-02-14 00:29:59,20,34.09,0,506,0.00493291694972601,0 +"3464",2015-02-14 00:30:59,20,34.09,0,506,0.00493291694972601,0 +"3465",2015-02-14 00:32:00,20,34.2,0,503.666666666667,0.00494896089935913,0 +"3466",2015-02-14 00:33:00,19.945,34.2,0,505.5,0.00493199174948031,0 +"3467",2015-02-14 00:34:00,20,34.2,0,507,0.00494896089935913,0 +"3468",2015-02-14 00:35:00,20,34.245,0,508,0.00495552456998177,0 +"3469",2015-02-14 00:36:00,20,34.345,0,506,0.00497011099675465,0 +"3470",2015-02-14 00:36:59,19.89,34.3633333333333,0,502.333333333333,0.00493873399733769,0 +"3471",2015-02-14 00:38:00,19.89,34.4,0,505.5,0.00494404565624152,0 +"3472",2015-02-14 00:39:00,19.89,34.45,0,503,0.00495128897252461,0 +"3473",2015-02-14 00:40:00,19.89,34.5,0,500.5,0.00495853245617905,0 +"3474",2015-02-14 00:40:59,19.89,34.5,0,503,0.00495853245617905,0 +"3475",2015-02-14 00:42:00,19.89,34.5,0,506,0.00495853245617905,0 +"3476",2015-02-14 00:42:59,19.945,34.5,0,504.5,0.00497560091192775,0 +"3477",2015-02-14 00:43:59,19.9175,34.5675,0,505.5,0.00497685612105086,0 +"3478",2015-02-14 00:45:00,19.945,34.645,0,509,0.00499668084865667,0 +"3479",2015-02-14 00:46:00,19.89,34.7,0,502,0.00498750806462639,0 +"3480",2015-02-14 00:47:00,19.89,34.7,0,502.5,0.00498750806462639,0 +"3481",2015-02-14 00:48:00,19.89,34.7,0,500.25,0.00498750806462639,0 +"3482",2015-02-14 00:49:00,19.89,34.745,0,499,0.00499402794563162,0 +"3483",2015-02-14 00:49:59,19.89,34.8,0,497,0.00500199687322903,0 +"3484",2015-02-14 00:51:00,19.89,34.845,0,498.5,0.00500851705557006,0 +"3485",2015-02-14 00:52:00,19.89,34.9,0,503,0.00501648635147954,0 +"3486",2015-02-14 00:53:00,19.89,34.9,0,506.5,0.00501648635147954,0 +"3487",2015-02-14 00:53:59,19.89,34.9,0,507.5,0.00501648635147954,0 +"3488",2015-02-14 00:55:00,19.89,34.9333333333333,0,506.666666666667,0.00502131632638171,0 +"3489",2015-02-14 00:55:59,19.89,35,0,504,0.00503097649942435,0 +"3490",2015-02-14 00:56:59,19.89,35,0,501.666666666667,0.00503097649942435,0 +"3491",2015-02-14 00:58:00,19.89,35,0,500.5,0.00503097649942435,0 +"3492",2015-02-14 00:59:00,19.89,35.09,0,501.5,0.00504401820520169,0 +"3493",2015-02-14 01:00:00,19.89,35.09,0,500.5,0.00504401820520169,0 +"3494",2015-02-14 01:01:00,19.89,35.045,0,501,0.00503749728449966,0 +"3495",2015-02-14 01:01:59,19.89,35.145,0,507,0.00505198840358368,0 +"3496",2015-02-14 01:02:59,19.89,35.145,0,502,0.00505198840358368,0 +"3497",2015-02-14 01:04:00,19.89,35.2,0,502.5,0.00505995880458261,0 +"3498",2015-02-14 01:05:00,19.89,35.2,0,498,0.00505995880458261,0 +"3499",2015-02-14 01:06:00,19.89,35.2,0,502.5,0.00505995880458261,0 +"3500",2015-02-14 01:07:00,19.89,35.245,0,499.5,0.00506648019247576,0 +"3501",2015-02-14 01:08:00,19.89,35.2,0,501,0.00505995880458261,0 +"3502",2015-02-14 01:08:59,19.89,35.2,0,502.5,0.00505995880458261,0 +"3503",2015-02-14 01:09:59,19.89,35.29,0,502.5,0.00507300171601445,0 +"3504",2015-02-14 01:11:00,19.89,35.29,0,503.666666666667,0.00507300171601445,0 +"3505",2015-02-14 01:12:00,19.89,35.29,0,500,0.00507300171601445,0 +"3506",2015-02-14 01:13:00,19.89,35.4,0,501,0.00508894378907528,0 +"3507",2015-02-14 01:14:00,19.89,35.29,0,501,0.00507300171601445,0 +"3508",2015-02-14 01:14:59,19.89,35.4,0,499,0.00508894378907528,0 +"3509",2015-02-14 01:15:59,19.89,35.4,0,503,0.00508894378907528,0 +"3510",2015-02-14 01:17:00,19.89,35.4,0,507,0.00508894378907528,0 +"3511",2015-02-14 01:18:00,19.89,35.5,0,500.5,0.00510343728618814,0 +"3512",2015-02-14 01:19:00,19.89,35.45,0,498.5,0.00509619045388799,0 +"3513",2015-02-14 01:20:00,19.89,35.5,0,497,0.00510343728618814,0 +"3514",2015-02-14 01:21:00,19.89,35.5,0,503.5,0.00510343728618814,0 +"3515",2015-02-14 01:21:59,19.89,35.5,0,501,0.00510343728618814,0 +"3516",2015-02-14 01:23:00,19.89,35.59,0,503,0.00511648200641525,0 +"3517",2015-02-14 01:24:00,19.84,35.545,0,500.5,0.00509401142181076,0 +"3518",2015-02-14 01:25:00,19.89,35.59,0,504,0.00511648200641525,0 +"3519",2015-02-14 01:25:59,19.84,35.59,0,502.5,0.00510051332773175,0 +"3520",2015-02-14 01:27:00,19.84,35.545,0,503,0.00509401142181076,0 +"3521",2015-02-14 01:27:59,19.84,35.545,0,503.5,0.00509401142181076,0 +"3522",2015-02-14 01:28:59,19.8566666666667,35.5966666666667,0,508,0.00510679558473242,0 +"3523",2015-02-14 01:30:00,19.89,35.7,0,507.5,0.00513242629037914,0 +"3524",2015-02-14 01:31:00,19.89,35.59,0,506.5,0.00511648200641525,0 +"3525",2015-02-14 01:32:00,19.89,35.7,0,501.5,0.00513242629037914,0 +"3526",2015-02-14 01:33:00,19.8566666666667,35.6633333333333,0,503.666666666667,0.00511643844078383,0 +"3527",2015-02-14 01:34:00,19.89,35.7,0,503.333333333333,0.00513242629037914,0 +"3528",2015-02-14 01:34:59,19.89,35.7,0,504,0.00513242629037914,0 +"3529",2015-02-14 01:36:00,19.89,35.7,0,507,0.00513242629037914,0 +"3530",2015-02-14 01:37:00,19.89,35.7,0,505,0.00513242629037914,0 +"3531",2015-02-14 01:38:00,19.89,35.7,0,503,0.00513242629037914,0 +"3532",2015-02-14 01:38:59,19.89,35.7,0,507,0.00513242629037914,0 +"3533",2015-02-14 01:40:00,19.89,35.76,0,503.666666666667,0.0051411235142709,0 +"3534",2015-02-14 01:40:59,19.89,35.79,0,502,0.00514547221667881,0 +"3535",2015-02-14 01:41:59,19.89,35.79,0,500,0.00514547221667881,0 +"3536",2015-02-14 01:43:00,19.89,35.9,0,503,0.0051614179748336,0 +"3537",2015-02-14 01:44:00,19.89,35.79,0,502,0.00514547221667881,0 +"3538",2015-02-14 01:45:00,19.89,35.79,0,503,0.00514547221667881,0 +"3539",2015-02-14 01:46:00,19.89,35.79,0,501.5,0.00514547221667881,0 +"3540",2015-02-14 01:46:59,19.89,35.9,0,501.666666666667,0.0051614179748336,0 +"3541",2015-02-14 01:47:59,19.84,35.845,0,501,0.00513736000817665,0 +"3542",2015-02-14 01:49:00,19.84,35.9,0,500,0.00514530789909708,0 +"3543",2015-02-14 01:50:00,19.79,35.79,0,501.5,0.00511339677683678,0 +"3544",2015-02-14 01:51:00,19.84,35.845,0,500,0.00513736000817665,0 +"3545",2015-02-14 01:52:00,19.89,35.9,0,502.5,0.0051614179748336,0 +"3546",2015-02-14 01:53:00,19.79,35.9,0,507,0.0051292423206035,0 +"3547",2015-02-14 01:53:59,19.8233333333333,35.9,0,507,0.00513994776741067,0 +"3548",2015-02-14 01:54:59,19.84,35.95,0,508,0.00515253342929482,0 +"3549",2015-02-14 01:56:00,19.89,36,0,505,0.00517591482227579,0 +"3550",2015-02-14 01:57:00,19.79,35.9,0,504.5,0.0051292423206035,0 +"3551",2015-02-14 01:58:00,19.79,35.9,0,504,0.0051292423206035,0 +"3552",2015-02-14 01:59:00,19.89,36,0,503,0.00517591482227579,0 +"3553",2015-02-14 01:59:59,19.84,35.95,0,510.5,0.00515253342929482,0 +"3554",2015-02-14 02:00:59,19.8233333333333,36.03,0,505.333333333333,0.00515871476015788,0 +"3555",2015-02-14 02:02:00,19.79,36,0,504,0.00514364805527512,0 +"3556",2015-02-14 02:03:00,19.79,36,0,504,0.00514364805527512,0 +"3557",2015-02-14 02:04:00,19.79,36,0,505.5,0.00514364805527512,0 +"3558",2015-02-14 02:05:00,19.815,36.0225,0,509.75,0.00515494451520808,0 +"3559",2015-02-14 02:06:00,19.79,36,0,506,0.00514364805527512,0 +"3560",2015-02-14 02:06:59,19.79,36,0,505.5,0.00514364805527512,0 +"3561",2015-02-14 02:08:00,19.79,36,0,505,0.00514364805527512,0 +"3562",2015-02-14 02:09:00,19.79,36.09,0,500,0.00515661378235243,0 +"3563",2015-02-14 02:10:00,19.79,36.045,0,505,0.00515013085180028,0 +"3564",2015-02-14 02:10:59,19.79,36.09,0,503,0.00515661378235243,0 +"3565",2015-02-14 02:12:00,19.79,36.09,0,499.5,0.00515661378235243,0 +"3566",2015-02-14 02:12:59,19.79,36.09,0,498,0.00515661378235243,0 +"3567",2015-02-14 02:13:59,19.79,36.09,0,502.5,0.00515661378235243,0 +"3568",2015-02-14 02:15:00,19.79,36.09,0,509,0.00515661378235243,0 +"3569",2015-02-14 02:16:00,19.79,36.09,0,505,0.00515661378235243,0 +"3570",2015-02-14 02:17:00,19.79,36.2,0,505,0.00517246151018731,0 +"3571",2015-02-14 02:18:00,19.79,36.2,0,505.5,0.00517246151018731,0 +"3572",2015-02-14 02:19:00,19.79,36.2,0,507.666666666667,0.00517246151018731,0 +"3573",2015-02-14 02:19:59,19.79,36.2,0,507.5,0.00517246151018731,0 +"3574",2015-02-14 02:21:00,19.79,36.2,0,506,0.00517246151018731,0 +"3575",2015-02-14 02:22:00,19.79,36.2,0,505.5,0.00517246151018731,0 +"3576",2015-02-14 02:23:00,19.79,36.2,0,504,0.00517246151018731,0 +"3577",2015-02-14 02:23:59,19.79,36.245,0,502.5,0.00517894490241977,0 +"3578",2015-02-14 02:25:00,19.79,36.2,0,500,0.00517246151018731,0 +"3579",2015-02-14 02:25:59,19.79,36.2,0,501.5,0.00517246151018731,0 +"3580",2015-02-14 02:26:59,19.79,36.2,0,501,0.00517246151018731,0 +"3581",2015-02-14 02:28:00,19.79,36.2,0,502,0.00517246151018731,0 +"3582",2015-02-14 02:29:00,19.79,36.2675,0,506.333333333333,0.00518218664880278,0 +"3583",2015-02-14 02:30:00,19.79,36.29,0,510.333333333333,0.00518542842869768,0 +"3584",2015-02-14 02:31:00,19.79,36.29,0,510,0.00518542842869768,0 +"3585",2015-02-14 02:31:59,19.79,36.29,0,503.5,0.00518542842869768,0 +"3586",2015-02-14 02:32:59,19.79,36.29,0,507,0.00518542842869768,0 +"3587",2015-02-14 02:34:00,19.79,36.29,0,503,0.00518542842869768,0 +"3588",2015-02-14 02:35:00,19.79,36.29,0,501,0.00518542842869768,0 +"3589",2015-02-14 02:36:00,19.76,36.3633333333333,0,503.666666666667,0.00518625022500445,0 +"3590",2015-02-14 02:37:00,19.79,36.4,0,510,0.00520127761282888,0 +"3591",2015-02-14 02:38:00,19.73,36.4,0,506.333333333333,0.00518178534618073,0 +"3592",2015-02-14 02:38:59,19.79,36.4,0,506.75,0.00520127761282888,0 +"3593",2015-02-14 02:39:59,19.79,36.4,0,504,0.00520127761282888,0 +"3594",2015-02-14 02:41:00,19.745,36.4,0,508,0.00518665234394312,0 +"3595",2015-02-14 02:42:00,19.79,36.345,0,503.5,0.005193352920636,0 +"3596",2015-02-14 02:43:00,19.79,36.4,0,501,0.00520127761282888,0 +"3597",2015-02-14 02:44:00,19.79,36.4,0,501,0.00520127761282888,0 +"3598",2015-02-14 02:44:59,19.79,36.4,0,499.333333333333,0.00520127761282888,0 +"3599",2015-02-14 02:45:59,19.745,36.4,0,503.5,0.00518665234394312,0 +"3600",2015-02-14 02:47:00,19.79,36.4,0,503.5,0.00520127761282888,0 +"3601",2015-02-14 02:48:00,19.79,36.4,0,504,0.00520127761282888,0 +"3602",2015-02-14 02:49:00,19.79,36.345,0,506.5,0.005193352920636,0 +"3603",2015-02-14 02:50:00,19.79,36.4,0,509.5,0.00520127761282888,0 +"3604",2015-02-14 02:51:00,19.79,36.4,0,505,0.00520127761282888,0 +"3605",2015-02-14 02:51:59,19.79,36.45,0,499.5,0.00520848205223975,0 +"3606",2015-02-14 02:53:00,19.79,36.4,0,503.5,0.00520127761282888,0 +"3607",2015-02-14 02:54:00,19.79,36.4,0,505,0.00520127761282888,0 +"3608",2015-02-14 02:55:00,19.79,36.4333333333333,0,505.666666666667,0.00520608055404623,0 +"3609",2015-02-14 02:55:59,19.79,36.4,0,503,0.00520127761282888,0 +"3610",2015-02-14 02:57:00,19.76,36.4666666666667,0,504.666666666667,0.00520111117774783,0 +"3611",2015-02-14 02:57:59,19.79,36.5,0,506,0.00521568665716223,0 +"3612",2015-02-14 02:58:59,19.79,36.4,0,503.5,0.00520127761282888,0 +"3613",2015-02-14 03:00:00,19.79,36.4666666666667,0,502.333333333333,0.00521088356882345,0 +"3614",2015-02-14 03:01:00,19.79,36.5,0,502.5,0.00521568665716223,0 +"3615",2015-02-14 03:02:00,19.79,36.5,0,501,0.00521568665716223,0 +"3616",2015-02-14 03:03:00,19.7,36.45,0,498,0.00517922711084423,0 +"3617",2015-02-14 03:04:00,19.79,36.5,0,504.5,0.00521568665716223,0 +"3618",2015-02-14 03:04:59,19.76,36.4666666666667,0,505.666666666667,0.00520111117774783,0 +"3619",2015-02-14 03:06:00,19.79,36.45,0,509,0.00520848205223975,0 +"3620",2015-02-14 03:07:00,19.745,36.4,0,505,0.00518665234394312,0 +"3621",2015-02-14 03:08:00,19.79,36.4,0,503.5,0.00520127761282888,0 +"3622",2015-02-14 03:08:59,19.79,36.4,0,505.666666666667,0.00520127761282888,0 +"3623",2015-02-14 03:10:00,19.7675,36.45,0,502.25,0.00520115464408533,0 +"3624",2015-02-14 03:10:59,19.79,36.4,0,501,0.00520127761282888,0 +"3625",2015-02-14 03:11:59,19.79,36.4,0,504.5,0.00520127761282888,0 +"3626",2015-02-14 03:13:00,19.79,36.4,0,502,0.00520127761282888,0 +"3627",2015-02-14 03:14:00,19.79,36.4,0,503,0.00520127761282888,0 +"3628",2015-02-14 03:15:00,19.79,36.4,0,504.25,0.00520127761282888,0 +"3629",2015-02-14 03:16:00,19.79,36.4,0,504,0.00520127761282888,0 +"3630",2015-02-14 03:16:59,19.79,36.4,0,502.5,0.00520127761282888,0 +"3631",2015-02-14 03:17:59,19.7675,36.425,0,507.25,0.00519755751339821,0 +"3632",2015-02-14 03:19:00,19.7,36.4,0,506.5,0.00517206347093251,0 +"3633",2015-02-14 03:20:00,19.7,36.5,0,498.5,0.00518639091440586,0 +"3634",2015-02-14 03:21:00,19.7,36.5,0,503,0.00518639091440586,0 +"3635",2015-02-14 03:22:00,19.7,36.5,0,503,0.00518639091440586,0 +"3636",2015-02-14 03:23:00,19.7,36.5,0,501.5,0.00518639091440586,0 +"3637",2015-02-14 03:23:59,19.7,36.5,0,504.5,0.00518639091440586,0 +"3638",2015-02-14 03:24:59,19.7,36.5,0,505,0.00518639091440586,0 +"3639",2015-02-14 03:26:00,19.7,36.5,0,507.5,0.00518639091440586,0 +"3640",2015-02-14 03:27:00,19.7,36.5,0,507,0.00518639091440586,0 +"3641",2015-02-14 03:28:00,19.7,36.5,0,505.5,0.00518639091440586,0 +"3642",2015-02-14 03:29:00,19.7,36.56,0,501.666666666667,0.00519498769470557,0 +"3643",2015-02-14 03:29:59,19.65,36.545,0,505,0.00517660573306873,0 +"3644",2015-02-14 03:30:59,19.7,36.59,0,506.5,0.00519928617323243,0 +"3645",2015-02-14 03:32:00,19.7,36.59,0,501.333333333333,0.00519928617323243,0 +"3646",2015-02-14 03:33:00,19.7,36.5,0,504,0.00518639091440586,0 +"3647",2015-02-14 03:34:00,19.7,36.5,0,504.5,0.00518639091440586,0 +"3648",2015-02-14 03:35:00,19.7,36.5,0,503,0.00518639091440586,0 +"3649",2015-02-14 03:36:00,19.7,36.53,0,501.333333333333,0.00519068927509712,0 +"3650",2015-02-14 03:36:59,19.65,36.45,0,500.5,0.00516303726559079,0 +"3651",2015-02-14 03:38:00,19.7,36.5,0,500,0.00518639091440586,0 +"3652",2015-02-14 03:39:00,19.6666666666667,36.5,0,501.666666666667,0.00517557764293137,0 +"3653",2015-02-14 03:40:00,19.7,36.59,0,503,0.00519928617323243,0 +"3654",2015-02-14 03:40:59,19.65,36.5,0,498.5,0.00517017849108008,0 +"3655",2015-02-14 03:42:00,19.7,36.545,0,499,0.00519283847753662,0 +"3656",2015-02-14 03:42:59,19.7,36.59,0,499.333333333333,0.00519928617323243,0 +"3657",2015-02-14 03:43:59,19.65,36.545,0,504.5,0.00517660573306873,0 +"3658",2015-02-14 03:45:00,19.65,36.545,0,497,0.00517660573306873,0 +"3659",2015-02-14 03:46:00,19.65,36.545,0,496.5,0.00517660573306873,0 +"3660",2015-02-14 03:47:00,19.65,36.45,0,497,0.00516303726559079,0 +"3661",2015-02-14 03:48:00,19.7,36.5,0,499,0.00518639091440586,0 +"3662",2015-02-14 03:49:00,19.7,36.5225,0,503,0.00518961467940086,0 +"3663",2015-02-14 03:49:59,19.65,36.45,0,499.5,0.00516303726559079,0 +"3664",2015-02-14 03:51:00,19.7,36.59,0,502,0.00519928617323243,0 +"3665",2015-02-14 03:52:00,19.6,36.4,0,502,0.00513977366256214,0 +"3666",2015-02-14 03:53:00,19.65,36.5,0,499.5,0.00517017849108008,0 +"3667",2015-02-14 03:53:59,19.6333333333333,36.4666666666667,0,503.333333333333,0.00516002849604084,0 +"3668",2015-02-14 03:55:00,19.6,36.5,0,504.5,0.0051540109230287,0 +"3669",2015-02-14 03:55:59,19.6333333333333,36.6266666666667,0,506,0.00518285712397329,0 +"3670",2015-02-14 03:56:59,19.6,36.545,0,501,0.00516041790113714,0 +"3671",2015-02-14 03:58:00,19.6,36.5,0,503,0.0051540109230287,0 +"3672",2015-02-14 03:59:00,19.65,36.545,0,502,0.00517660573306873,0 +"3673",2015-02-14 04:00:00,19.65,36.545,0,502,0.00517660573306873,0 +"3674",2015-02-14 04:01:00,19.6,36.5,0,499,0.0051540109230287,0 +"3675",2015-02-14 04:01:59,19.675,36.5,0,502.666666666667,0.00517827908907724,0 +"3676",2015-02-14 04:02:59,19.7,36.5,0,504.5,0.00518639091440586,0 +"3677",2015-02-14 04:04:00,19.7,36.59,0,505,0.00519928617323243,0 +"3678",2015-02-14 04:05:00,19.7,36.5,0,500,0.00518639091440586,0 +"3679",2015-02-14 04:06:00,19.7,36.5,0,502.5,0.00518639091440586,0 +"3680",2015-02-14 04:07:00,19.7,36.5,0,502,0.00518639091440586,0 +"3681",2015-02-14 04:08:00,19.6666666666667,36.4666666666667,0,500,0.00517081179519932,0 +"3682",2015-02-14 04:08:59,19.65,36.545,0,497.5,0.00517660573306873,0 +"3683",2015-02-14 04:09:59,19.6,36.5,0,499,0.0051540109230287,0 +"3684",2015-02-14 04:11:00,19.65,36.545,0,502.5,0.00517660573306873,0 +"3685",2015-02-14 04:12:00,19.6666666666667,36.53,0,497.666666666667,0.00517986696781915,0 +"3686",2015-02-14 04:13:00,19.6,36.5,0,500.5,0.0051540109230287,0 +"3687",2015-02-14 04:14:00,19.7,36.545,0,501,0.00519283847753662,0 +"3688",2015-02-14 04:14:59,19.7,36.59,0,505,0.00519928617323243,0 +"3689",2015-02-14 04:15:59,19.6333333333333,36.53,0,503.666666666667,0.00516906462921111,0 +"3690",2015-02-14 04:17:00,19.6,36.5,0,503,0.0051540109230287,0 +"3691",2015-02-14 04:18:00,19.7,36.59,0,500,0.00519928617323243,0 +"3692",2015-02-14 04:19:00,19.7,36.59,0,500,0.00519928617323243,0 +"3693",2015-02-14 04:20:00,19.65,36.59,0,496.5,0.00518303310679151,0 +"3694",2015-02-14 04:21:00,19.6,36.5,0,498,0.0051540109230287,0 +"3695",2015-02-14 04:21:59,19.6666666666667,36.56,0,499,0.00518415635137769,0 +"3696",2015-02-14 04:23:00,19.6,36.53,0,504,0.00515828222722251,0 +"3697",2015-02-14 04:24:00,19.6,36.545,0,499.5,0.00516041790113714,0 +"3698",2015-02-14 04:25:00,19.6,36.545,0,497.5,0.00516041790113714,0 +"3699",2015-02-14 04:25:59,19.6,36.59,0,502,0.00516682501015374,0 +"3700",2015-02-14 04:27:00,19.6,36.59,0,501,0.00516682501015374,0 +"3701",2015-02-14 04:27:59,19.6,36.59,0,499.5,0.00516682501015374,0 +"3702",2015-02-14 04:28:59,19.6,36.59,0,499,0.00516682501015374,0 +"3703",2015-02-14 04:30:00,19.6,36.59,0,502,0.00516682501015374,0 +"3704",2015-02-14 04:31:00,19.6,36.59,0,505.5,0.00516682501015374,0 +"3705",2015-02-14 04:32:00,19.6,36.59,0,503,0.00516682501015374,0 +"3706",2015-02-14 04:33:00,19.6,36.59,0,501,0.00516682501015374,0 +"3707",2015-02-14 04:34:00,19.7,36.7,0,504.5,0.00521504776526353,0 +"3708",2015-02-14 04:34:59,19.6,36.59,0,503.5,0.00516682501015374,0 +"3709",2015-02-14 04:36:00,19.6,36.645,0,504.5,0.00517465609895639,0 +"3710",2015-02-14 04:37:00,19.6,36.7,0,504.666666666667,0.00518248738332651,0 +"3711",2015-02-14 04:38:00,19.6,36.79,0,504.5,0.00519530263415887,0 +"3712",2015-02-14 04:38:59,19.6,36.745,0,501.5,0.0051888949432797,0 +"3713",2015-02-14 04:40:00,19.6,36.79,0,501,0.00519530263415887,0 +"3714",2015-02-14 04:40:59,19.6,36.76,0,500,0.00519103082569189,0 +"3715",2015-02-14 04:41:59,19.65,36.79,0,497,0.00521160080615187,0 +"3716",2015-02-14 04:43:00,19.7,36.79,0,503,0.00522794420252687,0 +"3717",2015-02-14 04:44:00,19.65,36.79,0,500,0.00521160080615187,0 +"3718",2015-02-14 04:45:00,19.6,36.79,0,501.666666666667,0.00519530263415887,0 +"3719",2015-02-14 04:46:00,19.6,36.79,0,502,0.00519530263415887,0 +"3720",2015-02-14 04:46:59,19.6,36.9,0,499.5,0.00521096642973746,0 +"3721",2015-02-14 04:47:59,19.6,36.9,0,504,0.00521096642973746,0 +"3722",2015-02-14 04:49:00,19.6,36.845,0,504,0.0052031344341511,0 +"3723",2015-02-14 04:50:00,19.6,36.79,0,503.5,0.00519530263415887,0 +"3724",2015-02-14 04:51:00,19.65,36.95,0,499,0.00523445683948898,0 +"3725",2015-02-14 04:52:00,19.6,36.9,0,503,0.00521096642973746,0 +"3726",2015-02-14 04:53:00,19.6666666666667,36.9666666666667,0,503.333333333333,0.00524230711724436,0 +"3727",2015-02-14 04:53:59,19.6,37,0,503,0.00522520692284545,0 +"3728",2015-02-14 04:54:59,19.6,37.09,0,502,0.00523802391953603,0 +"3729",2015-02-14 04:56:00,19.65,37.3,0,500.5,0.00528446022033243,0 +"3730",2015-02-14 04:57:00,19.7,37.4,0,499,0.00531536736904229,0 +"3731",2015-02-14 04:58:00,19.6,37.4,0,499,0.00528217536232196,0 +"3732",2015-02-14 04:59:00,19.6333333333333,37.4333333333333,0,498.666666666667,0.00529797677227713,0 +"3733",2015-02-14 04:59:59,19.6333333333333,37.53,0,503.333333333333,0.00531177493767088,0 +"3734",2015-02-14 05:00:59,19.6,37.495,0,503,0.00529570688746691,0 +"3735",2015-02-14 05:02:00,19.6,37.59,0,503.5,0.0053092389964197,0 +"3736",2015-02-14 05:03:00,19.625,37.7225,0,507.25,0.00533646708969625,0 +"3737",2015-02-14 05:04:00,19.6,37.9,0,498,0.00535340046582217,0 +"3738",2015-02-14 05:05:00,19.6,37.745,0,499,0.00533131895392581,0 +"3739",2015-02-14 05:06:00,19.6,37.9,0,500,0.00535340046582217,0 +"3740",2015-02-14 05:06:59,19.6666666666667,37.9666666666667,0,505,0.00538534667381554,0 +"3741",2015-02-14 05:08:00,19.6,37.95,0,503.666666666667,0.00536052386578463,0 +"3742",2015-02-14 05:09:00,19.6,38,0,506,0.00536764742751685,0 +"3743",2015-02-14 05:10:00,19.6,38.045,0,503.5,0.00537405877139354,0 +"3744",2015-02-14 05:10:59,19.6,38.045,0,501.5,0.00537405877139354,0 +"3745",2015-02-14 05:12:00,19.6,38.09,0,502,0.00538047024631221,0 +"3746",2015-02-14 05:12:59,19.6333333333333,38.23,0,508,0.00541171080294355,0 +"3747",2015-02-14 05:13:59,19.6,38.1633333333333,0,509.666666666667,0.0053909188565983,0 +"3748",2015-02-14 05:15:00,19.6333333333333,38.1633333333333,0,508,0.00540219172966711,0 +"3749",2015-02-14 05:16:00,19.6,38.26,0,503.75,0.00540469255646605,0 +"3750",2015-02-14 05:17:00,19.6,38.245,0,504,0.00540255521856975,0 +"3751",2015-02-14 05:18:00,19.65,38.345,0,500.5,0.00543380347780258,0 +"3752",2015-02-14 05:19:00,19.65,38.345,0,498,0.00543380347780258,0 +"3753",2015-02-14 05:19:59,19.6,38.29,0,505.666666666667,0.00540896727594585,0 +"3754",2015-02-14 05:21:00,19.6,38.29,0,500,0.00540896727594585,0 +"3755",2015-02-14 05:22:00,19.6,38.29,0,498.5,0.00540896727594585,0 +"3756",2015-02-14 05:23:00,19.6,38.29,0,500,0.00540896727594585,0 +"3757",2015-02-14 05:23:59,19.6,38.29,0,500.666666666667,0.00540896727594585,0 +"3758",2015-02-14 05:25:00,19.6,38.29,0,503.5,0.00540896727594585,0 +"3759",2015-02-14 05:25:59,19.6,38.29,0,510,0.00540896727594585,0 +"3760",2015-02-14 05:26:59,19.6,38.29,0,508.5,0.00540896727594585,0 +"3761",2015-02-14 05:28:00,19.6,38.29,0,507,0.00540896727594585,0 +"3762",2015-02-14 05:29:00,19.65,38.345,0,507,0.00543380347780258,0 +"3763",2015-02-14 05:30:00,19.65,38.345,0,504,0.00543380347780258,0 +"3764",2015-02-14 05:31:00,19.6,38.29,0,506,0.00540896727594585,0 +"3765",2015-02-14 05:31:59,19.6,38.29,0,504,0.00540896727594585,0 +"3766",2015-02-14 05:32:59,19.7,38.4,0,506,0.00545873676975271,0 +"3767",2015-02-14 05:34:00,19.6,38.29,0,502.666666666667,0.00540896727594585,0 +"3768",2015-02-14 05:35:00,19.7,38.4,0,501,0.00545873676975271,0 +"3769",2015-02-14 05:36:00,19.6,38.29,0,502.5,0.00540896727594585,0 +"3770",2015-02-14 05:37:00,19.6,38.29,0,506,0.00540896727594585,0 +"3771",2015-02-14 05:38:00,19.6333333333333,38.3266666666667,0,500.666666666667,0.0054255139722766,0 +"3772",2015-02-14 05:38:59,19.6,38.29,0,504,0.00540896727594585,0 +"3773",2015-02-14 05:39:59,19.6,38.29,0,501,0.00540896727594585,0 +"3774",2015-02-14 05:41:00,19.6,38.29,0,501,0.00540896727594585,0 +"3775",2015-02-14 05:42:00,19.6,38.29,0,505,0.00540896727594585,0 +"3776",2015-02-14 05:43:00,19.65,38.345,0,507,0.00543380347780258,0 +"3777",2015-02-14 05:44:00,19.6,38.29,0,506,0.00540896727594585,0 +"3778",2015-02-14 05:44:59,19.6,38.29,0,506,0.00540896727594585,0 +"3779",2015-02-14 05:45:59,19.6,38.29,0,507.5,0.00540896727594585,0 +"3780",2015-02-14 05:47:00,19.6,38.29,0,501,0.00540896727594585,0 +"3781",2015-02-14 05:48:00,19.6,38.29,0,499,0.00540896727594585,0 +"3782",2015-02-14 05:49:00,19.6,38.29,0,498,0.00540896727594585,0 +"3783",2015-02-14 05:50:00,19.6,38.29,0,500,0.00540896727594585,0 +"3784",2015-02-14 05:51:00,19.6,38.29,0,504.5,0.00540896727594585,0 +"3785",2015-02-14 05:51:59,19.6,38.29,0,504.5,0.00540896727594585,0 +"3786",2015-02-14 05:53:00,19.5666666666667,38.29,0,505.333333333333,0.00539767723518669,0 +"3787",2015-02-14 05:54:00,19.6,38.29,0,505.5,0.00540896727594585,0 +"3788",2015-02-14 05:55:00,19.5,38.29,0,501.5,0.00537515971665821,0 +"3789",2015-02-14 05:55:59,19.6,38.29,0,496,0.00540896727594585,0 +"3790",2015-02-14 05:57:00,19.6,38.29,0,497.666666666667,0.00540896727594585,0 +"3791",2015-02-14 05:57:59,19.6,38.29,0,499.5,0.00540896727594585,0 +"3792",2015-02-14 05:58:59,19.55,38.29,0,510.5,0.00539204004147927,0 +"3793",2015-02-14 06:00:00,19.6,38.29,0,502.5,0.00540896727594585,0 +"3794",2015-02-14 06:01:00,19.6,38.345,0,504.5,0.00541680441294944,0 +"3795",2015-02-14 06:02:00,19.575,38.4,0,507.25,0.00541614750239586,0 +"3796",2015-02-14 06:03:00,19.6,38.4,0,506.5,0.00542464174574713,0 +"3797",2015-02-14 06:04:00,19.6,38.45,0,504,0.00543176676365516,0 +"3798",2015-02-14 06:04:59,19.5,38.5,0,504,0.00540489573529471,0 +"3799",2015-02-14 06:06:00,19.55,38.5,0,504,0.00542187025110523,0 +"3800",2015-02-14 06:07:00,19.6,38.59,0,503,0.00545171767472357,0 +"3801",2015-02-14 06:08:00,19.5,38.59,0,502.5,0.00541764060620533,0 +"3802",2015-02-14 06:08:59,19.6,38.645,0,499.5,0.00545955587978406,0 +"3803",2015-02-14 06:10:00,19.575,38.645,0,503.75,0.00545100649072366,0 +"3804",2015-02-14 06:10:59,19.6,38.59,0,505,0.00545171767472357,0 +"3805",2015-02-14 06:11:59,19.6,38.7,0,502,0.00546739428067868,0 +"3806",2015-02-14 06:13:00,19.6,38.7,0,501,0.00546739428067868,0 +"3807",2015-02-14 06:14:00,19.5666666666667,38.73,0,505.666666666667,0.00546024779687692,0 +"3808",2015-02-14 06:15:00,19.5,38.79,0,508,0.00544596439545907,0 +"3809",2015-02-14 06:16:00,19.5666666666667,38.76,0,503,0.00546451442601671,0 +"3810",2015-02-14 06:16:59,19.6,38.79,0,508,0.00548022117730809,0 +"3811",2015-02-14 06:17:59,19.5333333333333,38.9,0,497.666666666667,0.00547297426129975,0 +"3812",2015-02-14 06:19:00,19.5,38.9,0,495,0.00546154356961051,0 +"3813",2015-02-14 06:20:00,19.5,38.9,0,500.5,0.00546154356961051,0 +"3814",2015-02-14 06:21:00,19.55,38.9,0,501,0.00547869754610548,0 +"3815",2015-02-14 06:22:00,19.5,38.9,0,502,0.00546154356961051,0 +"3816",2015-02-14 06:23:00,19.55,38.95,0,503.5,0.00548580168178583,0 +"3817",2015-02-14 06:23:59,19.55,39,0,507.5,0.00549290597833001,0 +"3818",2015-02-14 06:24:59,19.55,39,0,510,0.00549290597833001,0 +"3819",2015-02-14 06:26:00,19.5,39.09,0,504.5,0.00548845487453896,0 +"3820",2015-02-14 06:27:00,19.5,39.09,0,503,0.00548845487453896,0 +"3821",2015-02-14 06:28:00,19.55,39.09,0,503,0.00550569411750385,0 +"3822",2015-02-14 06:29:00,19.5,39.2,0,505,0.00550403615882336,0 +"3823",2015-02-14 06:29:59,19.525,39.2,0,512,0.00551267446497156,0 +"3824",2015-02-14 06:30:59,19.5,39.29,0,505,0.00551678505789689,0 +"3825",2015-02-14 06:32:00,19.5,39.29,0,508,0.00551678505789689,0 +"3826",2015-02-14 06:33:00,19.5,39.4,0,506,0.00553236774917479,0 +"3827",2015-02-14 06:34:00,19.5,39.4,0,507,0.00553236774917479,0 +"3828",2015-02-14 06:35:00,19.5,39.4,0,504,0.00553236774917479,0 +"3829",2015-02-14 06:36:00,19.5,39.5,0,503,0.0055465345037433,0 +"3830",2015-02-14 06:36:59,19.5,39.5,0,506.5,0.0055465345037433,0 +"3831",2015-02-14 06:38:00,19.5,39.4666666666667,0,507.333333333333,0.00554181218115005,0 +"3832",2015-02-14 06:39:00,19.5,39.5,0,509,0.0055465345037433,0 +"3833",2015-02-14 06:40:00,19.5,39.5,0,502.5,0.0055465345037433,0 +"3834",2015-02-14 06:40:59,19.5,39.5,0,502,0.0055465345037433,0 +"3835",2015-02-14 06:42:00,19.5,39.45,0,508.5,0.00553945104650513,0 +"3836",2015-02-14 06:42:59,19.5,39.45,0,507.5,0.00553945104650513,0 +"3837",2015-02-14 06:43:59,19.5,39.4,0,503.5,0.00553236774917479,0 +"3838",2015-02-14 06:45:00,19.5,39.4,0,505.5,0.00553236774917479,0 +"3839",2015-02-14 06:46:00,19.5,39.4,0,506,0.00553236774917479,0 +"3840",2015-02-14 06:47:00,19.5,39.29,0,504.5,0.00551678505789689,0 +"3841",2015-02-14 06:48:00,19.5,39.29,0,501,0.00551678505789689,0 +"3842",2015-02-14 06:49:00,19.55,39.29,0,499.5,0.00553411407080127,0 +"3843",2015-02-14 06:49:59,19.6,39.245,0,503,0.00554507629405322,0 +"3844",2015-02-14 06:51:00,19.5,39.29,0,505,0.00551678505789689,0 +"3845",2015-02-14 06:52:00,19.525,39.2225,0,506,0.00551586668725606,0 +"3846",2015-02-14 06:53:00,19.5333333333333,39.2,0,505.333333333333,0.00551555656677824,0 +"3847",2015-02-14 06:53:59,19.55,39.2,0,505.5,0.00552132477325438,0 +"3848",2015-02-14 06:55:00,19.6,39.2,0,505,0.00553866145434827,0 +"3849",2015-02-14 06:55:59,19.5666666666667,39.09,0,507.666666666667,0.00551145117647699,0 +"3850",2015-02-14 06:56:59,19.55,39.045,0,511,0.00549929998276287,0 +"3851",2015-02-14 06:58:00,19.5,39.09,0,513,0.00548845487453896,0 +"3852",2015-02-14 06:59:00,19.6,39,0,511,0.00551015264229816,0 +"3853",2015-02-14 07:00:00,19.5,39.06,0,508.333333333333,0.00548420556766273,0 +"3854",2015-02-14 07:01:00,19.55,39,0,509.5,0.00549290597833001,0 +"3855",2015-02-14 07:01:59,19.5,39,0,507,0.00547570712656396,0 +"3856",2015-02-14 07:02:59,19.5,39,0,506,0.00547570712656396,0 +"3857",2015-02-14 07:04:00,19.6,38.9,0,507,0.00549589920760837,0 +"3858",2015-02-14 07:05:00,19.55,38.9,0,508,0.00547869754610548,0 +"3859",2015-02-14 07:06:00,19.6,38.79,0,505,0.00548022117730809,0 +"3860",2015-02-14 07:07:00,19.6,38.7,0,509,0.00546739428067868,0 +"3861",2015-02-14 07:08:00,19.575,38.7,0,512.25,0.00545883251029072,0 +"3862",2015-02-14 07:08:59,19.6,38.7,0,510,0.00546739428067868,0 +"3863",2015-02-14 07:09:59,19.6,38.59,0,508,0.00545171767472357,0 +"3864",2015-02-14 07:11:00,19.6,38.59,0,508,0.00545171767472357,0 +"3865",2015-02-14 07:12:00,19.6,38.59,0,508.5,0.00545171767472357,0 +"3866",2015-02-14 07:13:00,19.575,38.5225,0,502.666666666667,0.00543357651238537,0 +"3867",2015-02-14 07:14:00,19.5666666666667,38.56,0,504.666666666667,0.00543607132772552,0 +"3868",2015-02-14 07:14:59,19.6,38.5,0,506.333333333333,0.00543889194338806,0 +"3869",2015-02-14 07:15:59,19.55,38.45,0,505.5,0.00541476756295358,0 +"3870",2015-02-14 07:17:00,19.6,38.4,0,502,0.00542464174574713,0 +"3871",2015-02-14 07:18:00,19.6,38.4,0,504,0.00542464174574713,0 +"3872",2015-02-14 07:19:00,19.6,38.4,0,502,0.00542464174574713,0 +"3873",2015-02-14 07:20:00,19.6,38.345,0,509,0.00541680441294944,0 +"3874",2015-02-14 07:21:00,19.65,38.345,0,513,0.00543380347780258,0 +"3875",2015-02-14 07:21:59,19.6,38.29,0,504,0.00540896727594585,0 +"3876",2015-02-14 07:23:00,19.6,38.29,0,503.333333333333,0.00540896727594585,0 +"3877",2015-02-14 07:24:00,19.6,38.29,0,502,0.00540896727594585,0 +"3878",2015-02-14 07:25:00,19.6,38.29,0,503,0.00540896727594585,0 +"3879",2015-02-14 07:25:59,19.6,38.2,0,506.5,0.00539614329225349,0 +"3880",2015-02-14 07:27:00,19.6,38.09,0,500,0.00538047024631221,0 +"3881",2015-02-14 07:27:59,19.6,38.09,0,499.5,0.00538047024631221,0 +"3882",2015-02-14 07:28:59,19.6,38.09,0,499.5,0.00538047024631221,0 +"3883",2015-02-14 07:30:00,19.6333333333333,38.1266666666667,0,507.666666666667,0.00539695636248475,0 +"3884",2015-02-14 07:31:00,19.6,38.09,0,514.333333333333,0.00538047024631221,0 +"3885",2015-02-14 07:32:00,19.6,38.045,0,513,0.00537405877139354,0 +"3886",2015-02-14 07:33:00,19.6,38,0,505.5,0.00536764742751685,0 +"3887",2015-02-14 07:34:00,19.6,38.045,0,502,0.00537405877139354,0 +"3888",2015-02-14 07:34:59,19.6,38,0,502,0.00536764742751685,0 +"3889",2015-02-14 07:36:00,19.6,37.9,0,503,0.00535340046582217,0 +"3890",2015-02-14 07:37:00,19.6,37.9,0,506,0.00535340046582217,0 +"3891",2015-02-14 07:38:00,19.6,37.9,0,502,0.00535340046582217,0 +"3892",2015-02-14 07:38:59,19.6,37.9,0,508.5,0.00535340046582217,0 +"3893",2015-02-14 07:40:00,19.6,37.9,0,507,0.00535340046582217,0 +"3894",2015-02-14 07:40:59,19.6,37.9,0,508,0.00535340046582217,0 +"3895",2015-02-14 07:41:59,19.6,37.845,0,507,0.00534556491270095,0 +"3896",2015-02-14 07:43:00,19.65,37.845,0,506.5,0.00536233850237018,0 +"3897",2015-02-14 07:44:00,19.6,37.7,0,506.5,0.00532490848355968,0 +"3898",2015-02-14 07:45:00,19.6333333333333,37.73,0,504,0.00534032479330301,0 +"3899",2015-02-14 07:46:00,19.625,37.7225,0,506.5,0.00533646708969625,0 +"3900",2015-02-14 07:46:59,19.6,37.7,0,503.5,0.00532490848355968,0 +"3901",2015-02-14 07:47:59,19.6,37.7,0,503.5,0.00532490848355968,0 +"3902",2015-02-14 07:49:00,19.6,37.7,0,506,0.00532490848355968,0 +"3903",2015-02-14 07:50:00,19.6,37.645,0,503.5,0.00531707364213932,0 +"3904",2015-02-14 07:51:00,19.6,37.7,0,503,0.00532490848355968,0 +"3905",2015-02-14 07:52:00,19.6,37.7,0,509,0.00532490848355968,0 +"3906",2015-02-14 07:53:00,19.6,37.645,0,508,0.00531707364213932,0 +"3907",2015-02-14 07:53:59,19.6333333333333,37.6266666666667,0,502.666666666667,0.00532557371009212,0 +"3908",2015-02-14 07:54:59,19.65,37.645,0,508.5,0.00533375707032846,0 +"3909",2015-02-14 07:56:00,19.6333333333333,37.56,0,510,0.00531605725035565,0 +"3910",2015-02-14 07:57:00,19.7,37.59,0,504.333333333333,0.00534260251338157,0 +"3911",2015-02-14 07:58:00,19.65,37.45,0,503,0.00530589268136267,0 +"3912",2015-02-14 07:59:00,19.7,37.5,0,505,0.00532970136075543,0 +"3913",2015-02-14 07:59:59,19.7,37.45,0,507,0.00532253428301781,0 +"3914",2015-02-14 08:00:59,19.7,37.5,0,510.5,0.00532970136075543,0 +"3915",2015-02-14 08:02:00,19.65,37.45,0,513,0.00530589268136267,0 +"3916",2015-02-14 08:03:00,19.6333333333333,37.4333333333333,0,506.666666666667,0.00529797677227713,0 +"3917",2015-02-14 08:04:00,19.7,37.4,0,509.5,0.00531536736904229,0 +"3918",2015-02-14 08:05:00,19.7,37.4,0,510.5,0.00531536736904229,0 +"3919",2015-02-14 08:06:00,19.7,37.4,0,511,0.00531536736904229,0 +"3920",2015-02-14 08:06:59,19.7,37.29,0,515,0.00529960073471111,0 +"3921",2015-02-14 08:08:00,19.7,37.29,0,511.5,0.00529960073471111,0 +"3922",2015-02-14 08:09:00,19.745,37.245,0,506.5,0.00530808429242442,0 +"3923",2015-02-14 08:10:00,19.7,37.2,0,503,0.00528670135064903,0 +"3924",2015-02-14 08:10:59,19.745,37.245,0,505,0.00530808429242442,0 +"3925",2015-02-14 08:12:00,19.7,37.2,0,502,0.00528670135064903,0 +"3926",2015-02-14 08:12:59,19.79,37.2,0,501,0.00531656850798938,0 +"3927",2015-02-14 08:13:59,19.79,37.1266666666667,0,505,0.00530599841138912,0 +"3928",2015-02-14 08:15:00,19.79,37.09,0,507.5,0.00530071349666509,0 +"3929",2015-02-14 08:16:00,19.79,37.09,0,507.5,0.00530071349666509,0 +"3930",2015-02-14 08:17:00,19.79,37.09,0,505.333333333333,0.00530071349666509,0 +"3931",2015-02-14 08:18:00,19.79,37,0,508.5,0.00528774181077989,0 +"3932",2015-02-14 08:19:00,19.79,37,0,508,0.00528774181077989,0 +"3933",2015-02-14 08:19:59,19.79,37,0,506.5,0.00528774181077989,0 +"3934",2015-02-14 08:21:00,19.79,37,0,504.5,0.00528774181077989,0 +"3935",2015-02-14 08:22:00,19.79,36.9,0,504.5,0.00527332945564411,0 +"3936",2015-02-14 08:23:00,19.84,36.95,0,502.5,0.0052970790052633,0 +"3937",2015-02-14 08:23:59,19.84,36.895,0,502,0.00528912726707338,0 +"3938",2015-02-14 08:25:00,19.8233333333333,36.8266666666667,0,506.333333333333,0.00527374727815893,0 +"3939",2015-02-14 08:25:59,19.84,36.845,0,503.5,0.00528189858910969,0 +"3940",2015-02-14 08:26:59,19.79,36.79,0,504.5,0.00525747662989378,0 +"3941",2015-02-14 08:28:00,19.89,36.9,0,506.5,0.00530641661407087,0 +"3942",2015-02-14 08:29:00,19.79,36.79,0,505,0.00525747662989378,0 +"3943",2015-02-14 08:30:00,19.79,36.79,0,507.5,0.00525747662989378,0 +"3944",2015-02-14 08:31:00,19.89,36.79,0,508.5,0.00529046348189389,0 +"3945",2015-02-14 08:31:59,19.84,36.745,0,505,0.00526744173297655,0 +"3946",2015-02-14 08:32:59,19.89,36.79,0,508,0.00529046348189389,0 +"3947",2015-02-14 08:34:00,19.89,36.79,0,507.5,0.00529046348189389,0 +"3948",2015-02-14 08:35:00,19.89,36.79,0,503,0.00529046348189389,0 +"3949",2015-02-14 08:36:00,19.79,36.7,0,503,0.0052445067320822,0 +"3950",2015-02-14 08:37:00,19.8233333333333,36.73,9.33333333333333,499.333333333333,0.00525978710811843,0 +"3951",2015-02-14 08:38:00,19.89,36.79,14,500.5,0.00529046348189389,0 +"3952",2015-02-14 08:38:59,19.865,36.7675,14,501.75,0.00527894174606436,0 +"3953",2015-02-14 08:39:59,19.89,36.79,14,502,0.00529046348189389,0 +"3954",2015-02-14 08:41:00,19.89,36.7225,10.5,503.25,0.00528067446159502,0 +"3955",2015-02-14 08:42:00,19.89,36.7,7,507.75,0.00527741152272173,0 +"3956",2015-02-14 08:43:00,19.865,36.7,7,508.5,0.00526916824649786,0 +"3957",2015-02-14 08:44:00,19.84,36.7225,7,503.5,0.00526418903218013,0 +"3958",2015-02-14 08:44:59,19.79,36.7,9.33333333333333,503,0.0052445067320822,0 +"3959",2015-02-14 08:45:59,19.865,36.6725,7,507.5,0.0052651865376925,0 +"3960",2015-02-14 08:47:00,19.89,36.7,7,510.25,0.00527741152272173,0 +"3961",2015-02-14 08:48:00,19.89,36.645,7,509.5,0.00526943559282614,0 +"3962",2015-02-14 08:49:00,19.89,36.6633333333333,9.33333333333333,506,0.00527209421358787,0 +"3963",2015-02-14 08:50:00,19.89,36.645,8.5,506.5,0.00526943559282614,0 +"3964",2015-02-14 08:51:00,19.89,36.59,7,510,0.00526145986575835,0 +"3965",2015-02-14 08:51:59,19.945,36.545,7,508,0.00527303174512839,0 +"3966",2015-02-14 08:53:00,19.9266666666667,36.5,9.33333333333333,508.333333333333,0.00526045277880424,0 +"3967",2015-02-14 08:54:00,19.89,36.5,14,512.5,0.00524840911349541,0 +"3968",2015-02-14 08:55:00,20,36.5,10,508,0.0052846134894447,0 +"3969",2015-02-14 08:55:59,20,36.5,6,507,0.0052846134894447,0 +"3970",2015-02-14 08:57:00,20,36.4,17,502,0.00527001242540388,0 +"3971",2015-02-14 08:57:59,19.9725,36.4,17,501.25,0.00526096595301218,0 +"3972",2015-02-14 08:58:59,19.945,36.5,17,501,0.00526648377587266,0 +"3973",2015-02-14 09:00:00,19.945,36.5,6,503.5,0.00526648377587266,0 +"3974",2015-02-14 09:01:00,19.89,36.5,6,505.333333333333,0.00524840911349541,0 +"3975",2015-02-14 09:02:00,19.945,36.5,6,506,0.00526648377587266,0 +"3976",2015-02-14 09:03:00,19.9725,36.475,6,504.25,0.00527189773136336,0 +"3977",2015-02-14 09:04:00,19.945,36.5,6,501.5,0.00526648377587266,0 +"3978",2015-02-14 09:04:59,19.9266666666667,36.5,6,502.333333333333,0.00526045277880424,0 +"3979",2015-02-14 09:06:00,19.945,36.5,6,503.5,0.00526648377587266,0 +"3980",2015-02-14 09:07:00,19.9633333333333,36.5,6,505.333333333333,0.00527252088973779,0 +"3981",2015-02-14 09:08:00,19.945,36.45,17,506,0.0052592084148094,0 +"3982",2015-02-14 09:08:59,20,36.3175,13.5,508.25,0.00525796705926718,0 +"3983",2015-02-14 09:10:00,20,36.29,7,504,0.00525395204002329,0 +"3984",2015-02-14 09:10:59,20,36.29,7,507.75,0.00525395204002329,0 +"3985",2015-02-14 09:11:59,20.05,36.3175,10,510.75,0.00527441246472862,0 +"3986",2015-02-14 09:13:00,20,36.29,11.3333333333333,508,0.00525395204002329,0 +"3987",2015-02-14 09:14:00,20,36.29,10,508.5,0.00525395204002329,0 +"3988",2015-02-14 09:15:00,20,36.29,13.5,504.75,0.00525395204002329,0 +"3989",2015-02-14 09:16:00,20,36.345,17,505.5,0.00526198212991126,0 +"3990",2015-02-14 09:16:59,20,36.3725,13.5,503.75,0.00526599725195649,0 +"3991",2015-02-14 09:17:59,20,36.4,7,502,0.00527001242540388,0 +"3992",2015-02-14 09:19:00,20,36.4,7,500,0.00527001242540388,0 +"3993",2015-02-14 09:20:00,20,36.4,9.33333333333333,502,0.00527001242540388,0 +"3994",2015-02-14 09:21:00,20,36.425,7,500,0.00527366262768933,0 +"3995",2015-02-14 09:22:00,20,36.4,7,506,0.00527001242540388,0 +"3996",2015-02-14 09:23:00,20,36.4,9.33333333333333,503,0.00527001242540388,0 +"3997",2015-02-14 09:23:59,20,36.4,7,498.75,0.00527001242540388,0 +"3998",2015-02-14 09:24:59,20,36.475,7,502.75,0.005280963159709,0 +"3999",2015-02-14 09:26:00,19.9266666666667,36.5,9.33333333333333,504.333333333333,0.00526045277880424,0 +"4000",2015-02-14 09:27:00,19.89,36.5,7,506.5,0.00524840911349541,0 +"4001",2015-02-14 09:28:00,20,36.5,7,506.5,0.0052846134894447,0 +"4002",2015-02-14 09:29:00,20,36.425,10.5,503.75,0.00527366262768933,0 +"4003",2015-02-14 09:29:59,20,36.4,9.33333333333333,503,0.00527001242540388,0 +"4004",2015-02-14 09:30:59,20,36.4,7,505.5,0.00527001242540388,0 +"4005",2015-02-14 09:32:00,20,36.29,7,506,0.00525395204002329,0 +"4006",2015-02-14 09:33:00,20.0333333333333,36.3266666666667,11.3333333333333,508.666666666667,0.00527026677780789,0 +"4007",2015-02-14 09:34:00,20.025,36.2675,17,506,0.00525887258188773,0 +"4008",2015-02-14 09:35:00,20.0666666666667,36.26,20.6666666666667,504.666666666667,0.00527147406854245,0 +"4009",2015-02-14 09:36:00,20.1,36.245,6,508,0.00528025155753494,0 +"4010",2015-02-14 09:36:59,20.1,36.2,6,507.5,0.00527364027562742,0 +"4011",2015-02-14 09:38:00,20.15,36.2,6,501,0.00529012236088292,0 +"4012",2015-02-14 09:39:00,20.1,36.2,6,504,0.00527364027562742,0 +"4013",2015-02-14 09:40:00,20.15,36.2,6,504.5,0.00529012236088292,0 +"4014",2015-02-14 09:40:59,20.1333333333333,36.2,6,503.666666666667,0.0052846232760837,0 +"4015",2015-02-14 09:42:00,20.1,36.2,6,506,0.00527364027562742,0 +"4016",2015-02-14 09:42:59,20.15,36.2,6,504,0.00529012236088292,0 +"4017",2015-02-14 09:43:59,20.175,36.2,10.5,500.75,0.00529838048018309,0 +"4018",2015-02-14 09:45:00,20.1,36.2,15,501.5,0.00527364027562742,0 +"4019",2015-02-14 09:46:00,20.1666666666667,36.2,24,510.333333333333,0.00529562650746093,0 +"4020",2015-02-14 09:47:00,20.15,36.2,19.5,503.25,0.00529012236088292,0 +"4021",2015-02-14 09:48:00,20.1333333333333,36.26,6,507,0.00529345686298856,0 +"4022",2015-02-14 09:49:00,20.1,36.29,6,505.75,0.0052868629788059,0 +"4023",2015-02-14 09:49:59,20.1,36.29,6,506,0.0052868629788059,0 +"4024",2015-02-14 09:51:00,20.075,36.345,6,501.5,0.00528668629897345,0 +"4025",2015-02-14 09:52:00,20.0333333333333,36.3266666666667,6,503.333333333333,0.00527026677780789,0 +"4026",2015-02-14 09:53:00,20,36.29,6,509,0.00525395204002329,0 +"4027",2015-02-14 09:53:59,20.05,36.345,6,505,0.00527844019903312,0 +"4028",2015-02-14 09:55:00,20.1,36.29,6,502.5,0.0052868629788059,0 +"4029",2015-02-14 09:55:59,20.1,36.29,19.5,503.75,0.0052868629788059,0 +"4030",2015-02-14 09:56:59,20.1,36.3266666666667,24,508.333333333333,0.00529225016584854,0 +"4031",2015-02-14 09:58:00,20.0666666666667,36.3633333333333,24,509,0.00528662433797117,0 +"4032",2015-02-14 09:59:00,20.1,36.345,24,508,0.00529494379406918,0 +"4033",2015-02-14 10:00:00,20.1,36.345,24,505.25,0.00529494379406918,0 +"4034",2015-02-14 10:01:00,20.1,36.3266666666667,17.3333333333333,506.666666666667,0.00529225016584854,0 +"4035",2015-02-14 10:01:59,20.1,36.29,14,504,0.0052868629788059,0 +"4036",2015-02-14 10:02:59,20.1,36.29,17.3333333333333,504,0.0052868629788059,0 +"4037",2015-02-14 10:04:00,20.1333333333333,36.29,17.3333333333333,506,0.00529787374973931,0 +"4038",2015-02-14 10:05:00,20.1,36.2225,26.5,503.75,0.00527694589916103,0 +"4039",2015-02-14 10:06:00,20.1,36.23,31,507.666666666667,0.00527804778141449,0 +"4040",2015-02-14 10:07:00,20.1,36.29,31,511,0.0052868629788059,0 +"4041",2015-02-14 10:08:00,20.1,36.345,26.5,506,0.00529494379406918,0 +"4042",2015-02-14 10:08:59,20.1,36.4,18.5,505.5,0.005303024817532,0 +"4043",2015-02-14 10:09:59,20.05,36.3725,14,506,0.00528246798506219,0 +"4044",2015-02-14 10:11:00,20.1,36.4,25.6666666666667,508,0.005303024817532,0 +"4045",2015-02-14 10:12:00,20.1,36.5,19.75,506,0.00531771812089439,0 +"4046",2015-02-14 10:13:00,20.0666666666667,36.5,13,507.333333333333,0.00530666291515309,0 +"4047",2015-02-14 10:14:00,20.025,36.5225,22,508.25,0.00529616301739834,0 +"4048",2015-02-14 10:14:59,20.05,36.545,31,510.5,0.00530773436823116,0 +"4049",2015-02-14 10:15:59,20.025,36.5225,31,510.5,0.00529616301739834,0 +"4050",2015-02-14 10:17:00,20.025,36.55,25.5,506.25,0.00530018479981663,0 +"4051",2015-02-14 10:18:00,20.05,36.645,33.5,507,0.00532238247889174,0 +"4052",2015-02-14 10:19:00,20.025,36.59,37,507.75,0.00530603475721147,0 +"4053",2015-02-14 10:20:00,20,36.53,37,507.333333333333,0.00528899394120768,0 +"4054",2015-02-14 10:21:00,20.0333333333333,36.53,25,508.666666666667,0.00530001770780325,0 +"4055",2015-02-14 10:21:59,20.1,36.59,19,512.5,0.00533094268244806,0 +"4056",2015-02-14 10:23:00,20.1,36.59,19,512.5,0.00533094268244806,0 +"4057",2015-02-14 10:24:00,20.1,36.59,37,512,0.00533094268244806,0 +"4058",2015-02-14 10:25:00,20.1,36.59,55,512.5,0.00533094268244806,0 +"4059",2015-02-14 10:25:59,20.1,36.645,26,506.5,0.00533902463344293,0 +"4060",2015-02-14 10:27:00,20.075,36.6725,40.5,510.75,0.00533473250734825,0 +"4061",2015-02-14 10:27:59,20.05,36.7,40.5,509,0.00533043923135172,0 +"4062",2015-02-14 10:28:59,20.075,36.545,39.5,509.25,0.0053160266200308,0 +"4063",2015-02-14 10:30:00,20.15,36.545,44,511,0.00534097219141473,0 +"4064",2015-02-14 10:31:00,20.1,36.59,52,498.666666666667,0.00533094268244806,0 +"4065",2015-02-14 10:32:00,20.1,36.475,50,504.5,0.005314044730524,0 +"4066",2015-02-14 10:33:00,20.1666666666667,36.4333333333333,48,505.333333333333,0.0053300528805323,0 +"4067",2015-02-14 10:34:00,20.175,36.3725,45.5,506.75,0.00532384438964674,0 +"4068",2015-02-14 10:34:59,20.2,36.29,44,506.5,0.00531995617323106,0 +"4069",2015-02-14 10:36:00,20.23,36.3266666666667,44,505.666666666667,0.00533535123655249,0 +"4070",2015-02-14 10:37:00,20.2675,36.345,44,510.5,0.00535056397518831,0 +"4071",2015-02-14 10:38:00,20.2,36.2,62,515.5,0.00530665000216417,0 +"4072",2015-02-14 10:38:59,20.26,36.26,52,515.333333333333,0.0053354477150107,0 +"4073",2015-02-14 10:40:00,20.29,36.29,50,517,0.00534989660179553,0 +"4074",2015-02-14 10:40:59,20.29,36.29,68,517,0.00534989660179553,0 +"4075",2015-02-14 10:41:59,20.29,36.29,74,513,0.00534989660179553,0 +"4076",2015-02-14 10:43:00,20.26,36.3266666666667,63,511.666666666667,0.0053453416283563,0 +"4077",2015-02-14 10:44:00,20.245,36.345,72,516.5,0.00534306268111027,0 +"4078",2015-02-14 10:45:00,20.29,36.4,81,516,0.00536625278152589,0 +"4079",2015-02-14 10:46:00,20.29,36.4,66.5,511,0.00536625278152589,0 +"4080",2015-02-14 10:46:59,20.26,36.26,87,508.666666666667,0.0053354477150107,0 +"4081",2015-02-14 10:47:59,20.29,36.345,106,512.5,0.00535807458505308,0 +"4082",2015-02-14 10:49:00,20.29,36.29,128,510.666666666667,0.00534989660179553,0 +"4083",2015-02-14 10:50:00,20.34,36.29,121.5,510.25,0.00536659450596802,0 +"4084",2015-02-14 10:51:00,20.365,36.195,152.5,514.5,0.00536076888903939,0 +"4085",2015-02-14 10:52:00,20.39,36.09,215,514.75,0.00535341471193155,0 +"4086",2015-02-14 10:53:00,20.39,36,345,517,0.00533994993770402,0 +"4087",2015-02-14 10:53:59,20.5,36,362.5,518,0.00537664875300219,0 +"4088",2015-02-14 10:54:59,20.5666666666667,35.8633333333333,260.333333333333,515.333333333333,0.0053783254589279,0 +"4089",2015-02-14 10:56:00,20.625,35.79,210.75,518.5,0.00538674025671219,0 +"4090",2015-02-14 10:57:00,20.65,35.79,179.25,516,0.00539511970632085,0 +"4091",2015-02-14 10:58:00,20.7,35.79,205,515.666666666667,0.00541191320416554,0 +"4092",2015-02-14 10:59:00,20.6666666666667,35.6933333333333,235.666666666667,516,0.00538599909476305,0 +"4093",2015-02-14 10:59:59,20.73,35.6633333333333,213.333333333333,512,0.00540265541931924,0 +"4094",2015-02-14 11:00:59,20.745,35.59,135,511.5,0.00539647646985074,0 +"4095",2015-02-14 11:02:00,20.79,35.59,119,508,0.00541158129184712,0 +"4096",2015-02-14 11:03:00,20.79,35.59,128.25,507.75,0.00541158129184712,0 +"4097",2015-02-14 11:04:00,20.79,35.5225,134.6,512,0.00540122856032323,0 +"4098",2015-02-14 11:05:00,20.79,35.5,158,512.75,0.00539777772573811,0 +"4099",2015-02-14 11:06:00,20.79,35.5,173.5,513.5,0.00539777772573811,0 +"4100",2015-02-14 11:06:59,20.79,35.4,131,515,0.00538244114240259,0 +"4101",2015-02-14 11:08:00,20.79,35.4,141.333333333333,513.333333333333,0.00538244114240259,0 +"4102",2015-02-14 11:09:00,20.79,35.4,128,509.75,0.00538244114240259,0 +"4103",2015-02-14 11:10:00,20.815,35.425,136,510.25,0.00539464327950184,0 +"4104",2015-02-14 11:10:59,20.79,35.345,193,515,0.00537400634116513,0 +"4105",2015-02-14 11:12:00,20.79,35.4,78.5,513.5,0.00538244114240259,0 +"4106",2015-02-14 11:12:59,20.815,35.4,66.25,504,0.00539080319619999,0 +"4107",2015-02-14 11:13:59,20.79,35.4,68,505.5,0.00538244114240259,0 +"4108",2015-02-14 11:15:00,20.79,35.4,53,506.5,0.00538244114240259,0 +"4109",2015-02-14 11:16:00,20.84,35.45,47,505.5,0.00540686898439329,0 +"4110",2015-02-14 11:17:00,20.815,35.425,42.25,506.5,0.00539464327950184,0 +"4111",2015-02-14 11:18:00,20.79,35.4,43,505.333333333333,0.00538244114240259,0 +"4112",2015-02-14 11:19:00,20.736,35.4,47.8,503.5,0.00536441824856496,0 +"4113",2015-02-14 11:19:59,20.76,35.3633333333333,51.3333333333333,503.75,0.00536680915413518,0 +"4114",2015-02-14 11:21:00,20.7,35.3725,50,505,0.0053482389447083,0 +"4115",2015-02-14 11:22:00,20.7,35.4,57.75,503.25,0.00535243265999211,0 +"4116",2015-02-14 11:23:00,20.7,35.4,89.6666666666667,497.333333333333,0.00535243265999211,0 +"4117",2015-02-14 11:23:59,20.7,35.4333333333333,161.333333333333,497,0.00535751602641576,0 +"4118",2015-02-14 11:25:00,20.7,35.4,217.25,502,0.00535243265999211,0 +"4119",2015-02-14 11:25:59,20.76,35.4,127.666666666667,500,0.00537242182308207,0 +"4120",2015-02-14 11:26:59,20.7675,35.29,103.5,505.25,0.00535807948702842,0 +"4121",2015-02-14 11:28:00,20.745,35.09,84.5,507,0.00532001351754167,0 +"4122",2015-02-14 11:29:00,20.7,35.1633333333333,66.6666666666667,507.666666666667,0.00531634312706266,0 +"4123",2015-02-14 11:30:00,20.7,35.2225,64.25,508.5,0.00532536512101828,0 +"4124",2015-02-14 11:31:00,20.7,35.26,54,508.666666666667,0.00533108342056335,0 +"4125",2015-02-14 11:31:59,20.675,35.2675,44,508,0.00532394934327624,0 +"4126",2015-02-14 11:32:59,20.7,35.2675,54.5,504.75,0.00533222709298224,0 +"4127",2015-02-14 11:34:00,20.675,35.24,48.5,498.25,0.00531976246323524,0 +"4128",2015-02-14 11:35:00,20.6,35.2,44,503,0.00528895566376233,0 +"4129",2015-02-14 11:36:00,20.6,35.26,35.6666666666667,501.666666666667,0.00529804771897924,0 +"4130",2015-02-14 11:37:00,20.5666666666667,35.29,43,499,0.00529161275783124,0 +"4131",2015-02-14 11:38:00,20.6,35.345,47.75,504.25,0.00531092858171651,0 +"4132",2015-02-14 11:38:59,20.6,35.29,35.6666666666667,503.666666666667,0.005302593845425,0 +"4133",2015-02-14 11:39:59,20.5666666666667,35.3266666666667,44,500.666666666667,0.00529715762008637,0 +"4134",2015-02-14 11:41:00,20.6,35.3175,50,504.75,0.0053067611858858,0 +"4135",2015-02-14 11:42:00,20.525,35.29,50,507.5,0.00527791468502237,0 +"4136",2015-02-14 11:43:00,20.525,35.3175,65.5,505.75,0.00528206246666676,0 +"4137",2015-02-14 11:44:00,20.55,35.29,94,503,0.00528612976015596,0 +"4138",2015-02-14 11:44:59,20.5,35.345,98.5,509.25,0.0052779935187992,0 +"4139",2015-02-14 11:45:59,20.5333333333333,35.3266666666667,120.666666666667,508,0.00528618506780304,0 +"4140",2015-02-14 11:47:00,20.6,35.29,125.5,503,0.005302593845425,0 +"4141",2015-02-14 11:48:00,20.6,35.23,134,505,0.00529350165842549,0 +"4142",2015-02-14 11:49:00,20.65,35.2225,171,506,0.00530884245962455,0 +"4143",2015-02-14 11:50:00,20.7,35.145,166,506,0.00531354763230202,0 +"4144",2015-02-14 11:51:00,20.7,35.1175,185.25,508.5,0.00530935443687635,0 +"4145",2015-02-14 11:51:59,20.7,35.09,177.333333333333,515.333333333333,0.00530516129750804,0 +"4146",2015-02-14 11:53:00,20.7,35.03,387.333333333333,513.666666666667,0.00529601282436919,0 +"4147",2015-02-14 11:54:00,20.79,34.95,192.5,511.25,0.00531343579512197,0 +"4148",2015-02-14 11:55:00,20.79,34.8175,143,510,0.00529312044669456,0 +"4149",2015-02-14 11:55:59,20.79,34.79,143.5,509.5,0.00528890421851003,0 +"4150",2015-02-14 11:57:00,20.79,34.79,176,508.5,0.00528890421851003,0 +"4151",2015-02-14 11:57:59,20.8233333333333,34.79,305,504.333333333333,0.00529986073820405,0 +"4152",2015-02-14 11:58:59,20.89,34.79,201.25,509.5,0.00532183401023033,0 +"4153",2015-02-14 12:00:00,20.89,34.745,203.5,509.5,0.00531489153047263,0 +"4154",2015-02-14 12:01:00,20.9266666666667,34.73,108,504,0.00532467575167612,0 +"4155",2015-02-14 12:02:00,20.89,34.7,105,507.5,0.00530794920437607,0 +"4156",2015-02-14 12:03:00,20.9175,34.7,93,510.5,0.00531701271291745,0 +"4157",2015-02-14 12:04:00,20.89,34.7,68.5,508.75,0.00530794920437607,0 +"4158",2015-02-14 12:04:59,20.89,34.645,74,508.5,0.0052994643478151,0 +"4159",2015-02-14 12:06:00,20.89,34.7,115.75,506.75,0.00530794920437607,0 +"4160",2015-02-14 12:07:00,20.8566666666667,34.6633333333333,120.333333333333,504,0.00529133664204872,0 +"4161",2015-02-14 12:08:00,20.89,34.7,112,503,0.00530794920437607,0 +"4162",2015-02-14 12:08:59,20.8566666666667,34.56,87,510.666666666667,0.00527542908827695,0 +"4163",2015-02-14 12:10:00,20.84,34.545,74,511,0.00526766851354636,0 +"4164",2015-02-14 12:10:59,20.8233333333333,34.4333333333333,73.5,512,0.00524506845183653,0 +"4165",2015-02-14 12:11:59,20.8233333333333,34.4,53,509,0.00523994816648798,0 +"4166",2015-02-14 12:13:00,20.79,34.5,44,507.25,0.0052444456258698,0 +"4167",2015-02-14 12:14:00,20.79,34.4333333333333,67.6666666666667,510.333333333333,0.00523422615061083,0 +"4168",2015-02-14 12:15:00,20.79,34.5,62.5,513,0.0052444456258698,0 +"4169",2015-02-14 12:16:00,20.79,34.4666666666667,148.333333333333,511.666666666667,0.00523933584661439,0 +"4170",2015-02-14 12:16:59,20.79,34.5,220,501,0.0052444456258698,0 +"4171",2015-02-14 12:17:59,20.79,34.5,78.5,503.5,0.0052444456258698,0 +"4172",2015-02-14 12:19:00,20.79,34.5,47,514,0.0052444456258698,0 +"4173",2015-02-14 12:20:00,20.79,34.4,46,510,0.0052291165378571,0 +"4174",2015-02-14 12:21:00,20.79,34.3175,33.5,508.75,0.00521647060427879,0 +"4175",2015-02-14 12:22:00,20.745,34.4,31,509,0.00521452524487928,0 +"4176",2015-02-14 12:23:00,20.7,34.44,36.5,508.5,0.00520606704931818,0 +"4177",2015-02-14 12:23:59,20.7,34.56,35.25,506.25,0.00522435901559534,0 +"4178",2015-02-14 12:24:59,20.7,34.59,19,509.5,0.00522893217387542,0 +"4179",2015-02-14 12:26:00,20.7,34.53,19,512.333333333333,0.00521978592400103,0 +"4180",2015-02-14 12:27:00,20.7,34.5,26.5,513.5,0.00521521289909104,0 +"4181",2015-02-14 12:28:00,20.7,34.59,24,513.5,0.00522893217387542,0 +"4182",2015-02-14 12:29:00,20.6,34.59,24,513,0.00519653472756723,0 +"4183",2015-02-14 12:29:59,20.6,34.59,24,514,0.00519653472756723,0 +"4184",2015-02-14 12:30:59,20.6,34.59,24,514,0.00519653472756723,0 +"4185",2015-02-14 12:32:00,20.55,34.645,24,515,0.00518870850463634,0 +"4186",2015-02-14 12:33:00,20.5,34.79,13,504.5,0.0051944244324762,0 +"4187",2015-02-14 12:34:00,20.5,34.8975,31,510,0.0052106094986512,0 +"4188",2015-02-14 12:35:00,20.5,35,31,510.5,0.00522604254902212,0 +"4189",2015-02-14 12:36:00,20.445,34.95,29.25,504.75,0.00520068191438152,0 +"4190",2015-02-14 12:36:59,20.4633333333333,34.9666666666667,31,505,0.0052091236751825,0 +"4191",2015-02-14 12:38:00,20.39,34.925,38.75,506.5,0.00517916536080724,0 +"4192",2015-02-14 12:39:00,20.39,35,45.3333333333333,505,0.00519038021495672,0 +"4193",2015-02-14 12:40:00,20.39,35,26,508.75,0.00519038021495672,0 +"4194",2015-02-14 12:40:59,20.39,35,35,508,0.00519038021495672,0 +"4195",2015-02-14 12:42:00,20.39,35,33.25,505,0.00519038021495672,0 +"4196",2015-02-14 12:42:59,20.39,35,45.3333333333333,505.333333333333,0.00519038021495672,0 +"4197",2015-02-14 12:43:59,20.39,35.09,40.5,504.25,0.00520383856936651,0 +"4198",2015-02-14 12:45:00,20.3566666666667,35.09,47.6666666666667,500,0.00519304623534392,0 +"4199",2015-02-14 12:46:00,20.315,35.09,47,499,0.00517958365726395,0 +"4200",2015-02-14 12:47:00,20.3566666666667,35.1633333333333,70.6666666666667,501,0.00520398979664046,0 +"4201",2015-02-14 12:48:00,20.34,35.2,90,503.5,0.00520405580488273,0 +"4202",2015-02-14 12:49:00,20.39,35.2,116.333333333333,497.666666666667,0.00522028845359346,0 +"4203",2015-02-14 12:49:59,20.365,35.1725,88.75,498.25,0.00520806043993437,0 +"4204",2015-02-14 12:51:00,20.39,35.09,97.75,501,0.00520383856936651,0 +"4205",2015-02-14 12:52:00,20.39,35.09,90.5,499.75,0.00520383856936651,0 +"4206",2015-02-14 12:53:00,20.39,35.09,103.5,499,0.00520383856936651,0 +"4207",2015-02-14 12:53:59,20.39,35.09,89.5,496.75,0.00520383856936651,0 +"4208",2015-02-14 12:55:00,20.39,35.09,113,497,0.00520383856936651,0 +"4209",2015-02-14 12:55:59,20.4266666666667,35.09,104.666666666667,496.333333333333,0.00521573304304079,0 +"4210",2015-02-14 12:56:59,20.4175,35.0225,148.75,494.5,0.00520264590996228,0 +"4211",2015-02-14 12:58:00,20.5,35,98.5,499,0.00522604254902212,0 +"4212",2015-02-14 12:59:00,20.5,35,214,500,0.00522604254902212,0 +"4213",2015-02-14 13:00:00,20.5,35,189,495.5,0.00522604254902212,0 +"4214",2015-02-14 13:01:00,20.6,34.8725,183,492.75,0.00523933284081706,0 +"4215",2015-02-14 13:01:59,20.6,34.8266666666667,131,494,0.00523238879718685,0 +"4216",2015-02-14 13:02:59,20.625,34.79,156.25,497.25,0.00523496386952086,0 +"4217",2015-02-14 13:04:00,20.625,34.79,201.25,498.75,0.00523496386952086,0 +"4218",2015-02-14 13:05:00,20.7,34.845,287,498.5,0.0052678067119005,0 +"4219",2015-02-14 13:06:00,20.68,34.736,207.2,495,0.00524466755124264,0 +"4220",2015-02-14 13:07:00,20.73,34.6266666666667,159,495,0.00524428619125922,0 +"4221",2015-02-14 13:08:00,20.7675,34.59,222,497,0.0052509012909699,0 +"4222",2015-02-14 13:08:59,20.8233333333333,34.6266666666667,180.333333333333,502.333333333333,0.00527476775544592,0 +"4223",2015-02-14 13:09:59,20.79,34.5,114.5,498.25,0.0052444456258698,0 +"4224",2015-02-14 13:11:00,20.79,34.5,100,498,0.0052444456258698,0 +"4225",2015-02-14 13:12:00,20.79,34.5,84.5,497.5,0.0052444456258698,0 +"4226",2015-02-14 13:13:00,20.79,34.5,74,494.25,0.0052444456258698,0 +"4227",2015-02-14 13:14:00,20.79,34.545,57,500.5,0.00525134395992645,0 +"4228",2015-02-14 13:14:59,20.79,34.59,48.5,498.5,0.00525824244571833,0 +"4229",2015-02-14 13:15:59,20.79,34.59,44,498,0.00525824244571833,0 +"4230",2015-02-14 13:17:00,20.745,34.59,39.5,499,0.00524356920056396,0 +"4231",2015-02-14 13:18:00,20.73,34.6266666666667,56,504,0.00524428619125922,0 +"4232",2015-02-14 13:19:00,20.7225,34.6175,45.5,499.25,0.00524044419784885,0 +"4233",2015-02-14 13:20:00,20.7,34.7,40.5,495.75,0.00524570099145984,0 +"4234",2015-02-14 13:21:00,20.7,34.7,55,496.666666666667,0.00524570099145984,0 +"4235",2015-02-14 13:21:59,20.7,34.7,37,496,0.00524570099145984,0 +"4236",2015-02-14 13:23:00,20.675,34.7675,40.5,498.75,0.0052478329802459,0 +"4237",2015-02-14 13:24:00,20.7,34.79,50,496,0.00525942160004241,0 +"4238",2015-02-14 13:25:00,20.7,34.8175,53.5,498,0.00526361412794891,0 +"4239",2015-02-14 13:25:59,20.7,34.9,42.6666666666667,498,0.00527619204794348,0 +"4240",2015-02-14 13:27:00,20.65,34.975,47,500.25,0.00527122236858158,0 +"4241",2015-02-14 13:27:59,20.6,34.9666666666667,56,503.333333333333,0.00525360017656182,0 +"4242",2015-02-14 13:28:59,20.6,35,51,503,0.00525865071643927,0 +"4243",2015-02-14 13:30:00,20.6,35.0225,65.5,501.5,0.00526205987683489,0 +"4244",2015-02-14 13:31:00,20.6,35.09,64.25,503.5,0.00527228758037146,0 +"4245",2015-02-14 13:32:00,20.6,35.1266666666667,58.3333333333333,503.333333333333,0.00527784350974577,0 +"4246",2015-02-14 13:33:00,20.6,35.1725,60.75,507.5,0.00528478855986959,0 +"4247",2015-02-14 13:34:00,20.6,35.1725,68,505.5,0.00528478855986959,0 +"4248",2015-02-14 13:34:59,20.6,35.1633333333333,68,507,0.00528339953754186,0 +"4249",2015-02-14 13:36:00,20.6,35.145,77,512,0.00528062151134093,0 +"4250",2015-02-14 13:37:00,20.6,35.09,57,506,0.00527228758037146,0 +"4251",2015-02-14 13:38:00,20.6,35.2,74,506.5,0.00528895566376233,0 +"4252",2015-02-14 13:38:59,20.6,35.2,75.75,496.5,0.00528895566376233,0 +"4253",2015-02-14 13:40:00,20.6,35.2,59.5,497.5,0.00528895566376233,0 +"4254",2015-02-14 13:40:59,20.6,35.245,78.5,496,0.00529577468046595,0 +"4255",2015-02-14 13:41:59,20.5,35.29,81,503,0.00526971090353197,0 +"4256",2015-02-14 13:43:00,20.55,35.29,81,504,0.00528612976015596,0 +"4257",2015-02-14 13:44:00,20.5,35.29,61.25,505.5,0.00526971090353197,0 +"4258",2015-02-14 13:45:00,20.5333333333333,35.29,60.75,507.5,0.00528065178788388,0 +"4259",2015-02-14 13:46:00,20.525,35.29,50,501,0.00527791468502237,0 +"4260",2015-02-14 13:46:59,20.5666666666667,35.29,54,501.333333333333,0.00529161275783124,0 +"4261",2015-02-14 13:47:59,20.5,35.3266666666667,52,498,0.0052752326227401,0 +"4262",2015-02-14 13:49:00,20.5,35.29,54.5,502.75,0.00526971090353197,0 +"4263",2015-02-14 13:50:00,20.5,35.3266666666667,44,502,0.0052752326227401,0 +"4264",2015-02-14 13:51:00,20.5,35.3725,42.25,502,0.00528213490845755,0 +"4265",2015-02-14 13:52:00,20.5,35.4,47.75,502.5,0.00528627635280048,0 +"4266",2015-02-14 13:53:00,20.5,35.4,37,509,0.00528627635280048,0 +"4267",2015-02-14 13:53:59,20.5,35.4,37,509,0.00528627635280048,0 +"4268",2015-02-14 13:54:59,20.4175,35.3175,37,504,0.00524683827427915,0 +"4269",2015-02-14 13:56:00,20.5,35.4,23.5,509,0.00528627635280048,0 +"4270",2015-02-14 13:57:00,20.4266666666667,35.3633333333333,19,508,0.00525670432108865,0 +"4271",2015-02-14 13:58:00,20.39,35.3725,33.5,505,0.00524608660057825,0 +"4272",2015-02-14 13:59:00,20.39,35.4,38.3333333333333,502.666666666667,0.0052501995447784,0 +"4273",2015-02-14 13:59:59,20.39,35.4333333333333,31,502.333333333333,0.00525518500400229,0 +"4274",2015-02-14 14:00:59,20.365,35.425,31,503.25,0.00524576392644531,0 +"4275",2015-02-14 14:02:00,20.39,35.5,31,508.5,0.00526515616020398,0 +"4276",2015-02-14 14:03:00,20.3233333333333,35.5,31,510.666666666667,0.00524333506547663,0 +"4277",2015-02-14 14:04:00,20.29,35.59,28.6666666666667,509,0.00524583180043972,0 +"4278",2015-02-14 14:05:00,20.29,35.59,37,501.5,0.00524583180043972,0 +"4279",2015-02-14 14:06:00,20.29,35.59,37,504.25,0.00524583180043972,0 +"4280",2015-02-14 14:06:59,20.34,35.545,19,503,0.00525549242988049,0 +"4281",2015-02-14 14:08:00,20.29,35.59,28.6666666666667,502.666666666667,0.00524583180043972,0 +"4282",2015-02-14 14:09:00,20.29,35.59,32.6666666666667,506,0.00524583180043972,0 +"4283",2015-02-14 14:10:00,20.29,35.59,31,506.5,0.00524583180043972,0 +"4284",2015-02-14 14:10:59,20.29,35.59,31,505,0.00524583180043972,0 +"4285",2015-02-14 14:12:00,20.2675,35.5675,13,507.25,0.00523514019801416,0 +"4286",2015-02-14 14:12:59,20.29,35.7,13,506.75,0.00526218255422322,0 +"4287",2015-02-14 14:13:59,20.29,35.7,31,505,0.00526218255422322,0 +"4288",2015-02-14 14:15:00,20.2,35.59,31,505,0.00521647860798868,0 +"4289",2015-02-14 14:16:00,20.2,35.7,31,506.666666666667,0.00523273710743569,0 +"4290",2015-02-14 14:17:00,20.2,35.7,31,511.5,0.00523273710743569,0 +"4291",2015-02-14 14:18:00,20.2,35.7,31,511,0.00523273710743569,0 +"4292",2015-02-14 14:19:00,20.2,35.7,33.5,506.5,0.00523273710743569,0 +"4293",2015-02-14 14:19:59,20.2,35.7,19,506,0.00523273710743569,0 +"4294",2015-02-14 14:21:00,20.2,35.7,37,507.25,0.00523273710743569,0 +"4295",2015-02-14 14:22:00,20.1666666666667,35.7,37,504,0.00522186842995927,0 +"4296",2015-02-14 14:23:00,20.1666666666667,35.73,37,507,0.00522629342547398,0 +"4297",2015-02-14 14:23:59,20.15,35.7,47.75,510,0.00521644158325566,0 +"4298",2015-02-14 14:25:00,20.1,35.7,40.5,506.75,0.00520019096339399,0 +"4299",2015-02-14 14:25:59,20.1,35.745,40.5,506,0.00520680069711517,0 +"4300",2015-02-14 14:26:59,20.1333333333333,35.79,39.3333333333333,511.333333333333,0.00522426709018864,0 +"4301",2015-02-14 14:28:00,20.1333333333333,35.79,37,509.333333333333,0.00522426709018864,0 +"4302",2015-02-14 14:29:00,20.15,35.79,37,511,0.00522970284580333,0 +"4303",2015-02-14 14:30:00,20.1,35.79,19,508.333333333333,0.00521341057015086,0 +"4304",2015-02-14 14:31:00,20.1,35.79,19,516,0.00521341057015086,0 +"4305",2015-02-14 14:31:59,20.1333333333333,35.8633333333333,32.6666666666667,510,0.00523506165260853,0 +"4306",2015-02-14 14:32:59,20.15,35.79,31,510.5,0.00522970284580333,0 +"4307",2015-02-14 14:34:00,20.1,35.878,31,508.6,0.00522633694670579,0 +"4308",2015-02-14 14:35:00,20.1,35.9,31,513,0.00522956862409573,0 +"4309",2015-02-14 14:36:00,20.1,35.8633333333333,31,508.333333333333,0.00522418251361309,0 +"4310",2015-02-14 14:37:00,20.1,35.79,31,506.666666666667,0.00521341057015086,0 +"4311",2015-02-14 14:38:00,20.1,35.9,13,509.25,0.00522956862409573,0 +"4312",2015-02-14 14:38:59,20.1,35.9,13,510,0.00522956862409573,0 +"4313",2015-02-14 14:39:59,20.1,35.9,13,511,0.00522956862409573,0 +"4314",2015-02-14 14:41:00,20.1,35.9,22,511,0.00522956862409573,0 +"4315",2015-02-14 14:42:00,20.05,35.8725,32.25,505.5,0.00520924359025842,0 +"4316",2015-02-14 14:43:00,20.05,35.925,28,504.5,0.00521693134843441,0 +"4317",2015-02-14 14:44:00,20.05,35.95,37,505,0.0052205922518999,0 +"4318",2015-02-14 14:44:59,20.05,35.95,37,508,0.0052205922518999,0 +"4319",2015-02-14 14:45:59,20,35.9,37,506.333333333333,0.00519701729991479,0 +"4320",2015-02-14 14:47:00,20,35.9,37,513,0.00519701729991479,0 +"4321",2015-02-14 14:48:00,20,35.9,45.3333333333333,511,0.00519701729991479,0 +"4322",2015-02-14 14:49:00,20,35.9,26,511.333333333333,0.00519701729991479,0 +"4323",2015-02-14 14:50:00,20,35.9,35,511,0.00519701729991479,0 +"4324",2015-02-14 14:51:00,20,35.9,33.25,504.5,0.00519701729991479,0 +"4325",2015-02-14 14:51:59,20,35.9,55,505,0.00519701729991479,0 +"4326",2015-02-14 14:53:00,20,35.9,37,508.25,0.00519701729991479,0 +"4327",2015-02-14 14:54:00,20,35.9,37,506.333333333333,0.00519701729991479,0 +"4328",2015-02-14 14:55:00,20,35.925,37,508.75,0.00520066665270245,0 +"4329",2015-02-14 14:55:59,20,35.9,37,512.5,0.00519701729991479,0 +"4330",2015-02-14 14:57:00,20,35.9,37,514,0.00519701729991479,0 +"4331",2015-02-14 14:57:59,20,35.95,28,508,0.00520431604795795,0 +"4332",2015-02-14 14:58:59,20,36,19,513,0.00521161496587546,0 +"4333",2015-02-14 15:00:00,20,36,33.5,510.5,0.00521161496587546,0 +"4334",2015-02-14 15:01:00,19.9725,36,26.5,506.75,0.00520266956966452,0 +"4335",2015-02-14 15:02:00,19.9633333333333,36,13,508.666666666667,0.00519969079081404,0 +"4336",2015-02-14 15:03:00,19.945,36,26.5,510.5,0.00519373775895339,0 +"4337",2015-02-14 15:04:00,20,36,24,513,0.00521161496587546,0 +"4338",2015-02-14 15:04:59,19.945,36,24,513,0.00519373775895339,0 +"4339",2015-02-14 15:06:00,19.945,36,24,512,0.00519373775895339,0 +"4340",2015-02-14 15:07:00,19.89,36,24,514,0.00517591482227579,0 +"4341",2015-02-14 15:08:00,19.9266666666667,36,24,509,0.00518779075711723,0 +"4342",2015-02-14 15:08:59,19.9266666666667,36,24,506,0.00518779075711723,0 +"4343",2015-02-14 15:10:00,19.89,36,24,505.5,0.00517591482227579,0 +"4344",2015-02-14 15:10:59,19.89,36,24,506.5,0.00517591482227579,0 +"4345",2015-02-14 15:11:59,19.89,36,24,509.5,0.00517591482227579,0 +"4346",2015-02-14 15:13:00,19.89,36.09,24,513.5,0.00518896255799795,0 +"4347",2015-02-14 15:14:00,19.89,36.09,24,513,0.00518896255799795,0 +"4348",2015-02-14 15:15:00,19.89,36,24,512,0.00517591482227579,0 +"4349",2015-02-14 15:16:00,19.89,36,24,509,0.00517591482227579,0 +"4350",2015-02-14 15:16:59,19.89,36,14,502.75,0.00517591482227579,0 +"4351",2015-02-14 15:17:59,19.89,36,20.3333333333333,503.333333333333,0.00517591482227579,0 +"4352",2015-02-14 15:19:00,19.89,36.045,26.5,511,0.00518243862227647,0 +"4353",2015-02-14 15:20:00,19.89,36.1266666666667,25,517.666666666667,0.0051942784578254,0 +"4354",2015-02-14 15:21:00,19.89,36.2,25.25,518,0.00520491052782246,0 +"4355",2015-02-14 15:22:00,19.89,36.2,44,519,0.00520491052782246,0 +"4356",2015-02-14 15:23:00,19.89,36.29,47,509,0.00521795947003541,0 +"4357",2015-02-14 15:23:59,19.89,36.29,62.5,510,0.00521795947003541,0 +"4358",2015-02-14 15:24:59,19.89,36.29,63,510.5,0.00521795947003541,0 +"4359",2015-02-14 15:26:00,19.89,36.29,52.25,508,0.00521795947003541,0 +"4360",2015-02-14 15:27:00,19.89,36.29,57,509,0.00521795947003541,0 +"4361",2015-02-14 15:28:00,19.89,36.29,48.5,511,0.00521795947003541,0 +"4362",2015-02-14 15:29:00,19.89,36.23,37,511,0.00520926011489827,0 +"4363",2015-02-14 15:29:59,19.89,36.2,33.5,513.5,0.00520491052782246,0 +"4364",2015-02-14 15:30:59,19.89,36.2,31,518.5,0.00520491052782246,0 +"4365",2015-02-14 15:32:00,19.945,36.2,31,514,0.00522283414084831,0 +"4366",2015-02-14 15:33:00,19.89,36.2,31,512,0.00520491052782246,0 +"4367",2015-02-14 15:34:00,19.89,36.2,31,509,0.00520491052782246,0 +"4368",2015-02-14 15:35:00,19.89,36.2,31,510.5,0.00520491052782246,0 +"4369",2015-02-14 15:36:00,19.89,36.2,31,511,0.00520491052782246,0 +"4370",2015-02-14 15:36:59,19.84,36.245,13,512,0.00519516744669813,0 +"4371",2015-02-14 15:38:00,19.865,36.245,17.5,510.75,0.00520329556460965,0 +"4372",2015-02-14 15:39:00,19.8233333333333,36.2,13,513,0.00518325790703892,0 +"4373",2015-02-14 15:40:00,19.815,36.145,13,511.666666666667,0.00517262047235032,0 +"4374",2015-02-14 15:40:59,19.79,36.1725,26.5,509.8,0.00516849950314301,0 +"4375",2015-02-14 15:42:00,19.79,36.09,32,513,0.00515661378235243,0 +"4376",2015-02-14 15:42:59,19.79,36.145,14,508.5,0.0051645375461564,0 +"4377",2015-02-14 15:43:59,19.79,36.2,24,510.5,0.00517246151018731,0 +"4378",2015-02-14 15:45:00,19.79,36.2,24,509,0.00517246151018731,0 +"4379",2015-02-14 15:46:00,19.84,36.145,24,513,0.00518071458799747,0 +"4380",2015-02-14 15:47:00,19.8233333333333,36.1266666666667,24,515.333333333333,0.00517267043161833,0 +"4381",2015-02-14 15:48:00,19.79,36.2,24,516.5,0.00517246151018731,0 +"4382",2015-02-14 15:49:00,19.79,36.2,24,512.666666666667,0.00517246151018731,0 +"4383",2015-02-14 15:49:59,19.79,36.2,24,512,0.00517246151018731,0 +"4384",2015-02-14 15:51:00,19.79,36.2,24,512,0.00517246151018731,0 +"4385",2015-02-14 15:52:00,19.79,36.2,24,504,0.00517246151018731,0 +"4386",2015-02-14 15:53:00,19.79,36.2,24,507.5,0.00517246151018731,0 +"4387",2015-02-14 15:53:59,19.79,36.2,24,505.5,0.00517246151018731,0 +"4388",2015-02-14 15:55:00,19.79,36.1633333333333,24,509,0.00516717884525222,0 +"4389",2015-02-14 15:55:59,19.89,36.2,24,515.666666666667,0.00520491052782246,0 +"4390",2015-02-14 15:56:59,19.89,36.145,32,516,0.00519693644153147,0 +"4391",2015-02-14 15:58:00,19.89,36.09,13,515,0.00518896255799795,0 +"4392",2015-02-14 15:59:00,19.89,36.09,22,513,0.00518896255799795,0 +"4393",2015-02-14 16:00:00,19.89,36.0675,25.5,512.25,0.00518570057317184,0 +"4394",2015-02-14 16:01:00,19.89,36,33.5,515,0.00517591482227579,0 +"4395",2015-02-14 16:01:59,19.945,35.925,23.5,510.5,0.00518282731169999,0 +"4396",2015-02-14 16:02:59,20,35.9,37,500,0.00519701729991479,0 +"4397",2015-02-14 16:04:00,19.9266666666667,35.9,37,506.666666666667,0.00517326037285823,0 +"4398",2015-02-14 16:05:00,20,35.9,37,513,0.00519701729991479,0 +"4399",2015-02-14 16:06:00,20,35.9,37,517,0.00519701729991479,0 +"4400",2015-02-14 16:07:00,20,35.9,19,516.5,0.00519701729991479,0 +"4401",2015-02-14 16:08:00,20,35.79,48,516,0.00518096065214833,0 +"4402",2015-02-14 16:08:59,20,35.79,20,516,0.00518096065214833,0 +"4403",2015-02-14 16:09:59,20,35.79,31,512,0.00518096065214833,0 +"4404",2015-02-14 16:11:00,20,35.745,17.5,511.5,0.00517439226046843,0 +"4405",2015-02-14 16:12:00,20,35.7,13,515,0.00516782400636706,0 +"4406",2015-02-14 16:13:00,20.05,35.745,13,521.5,0.00519057410497444,0 +"4407",2015-02-14 16:14:00,20.0666666666667,35.76,22,517,0.00519817664966774,0 +"4408",2015-02-14 16:14:59,20.1,35.9,26.5,509,0.00522956862409573,0 +"4409",2015-02-14 16:15:59,20,35.79,40,512,0.00518096065214833,0 +"4410",2015-02-14 16:17:00,20,35.79,40,514.5,0.00518096065214833,0 +"4411",2015-02-14 16:18:00,20,35.79,26.5,515,0.00518096065214833,0 +"4412",2015-02-14 16:19:00,20,35.79,13,522,0.00518096065214833,0 +"4413",2015-02-14 16:20:00,20.0666666666667,35.8633333333333,13,519.333333333333,0.00521332337860652,0 +"4414",2015-02-14 16:21:00,20,35.745,22,524,0.00517439226046843,0 +"4415",2015-02-14 16:21:59,20.1,35.8266666666667,32.6666666666667,518.333333333333,0.00521879649563226,0 +"4416",2015-02-14 16:23:00,20,35.7,19,517,0.00516782400636706,0 +"4417",2015-02-14 16:24:00,20.05,35.745,19,513.5,0.00519057410497444,0 +"4418",2015-02-14 16:25:00,20.1,35.79,19,512.5,0.00521341057015086,0 +"4419",2015-02-14 16:25:59,20.1,35.73,19,510,0.00520459743706228,0 +"4420",2015-02-14 16:27:00,20.1,35.745,33.5,509,0.00520680069711517,0 +"4421",2015-02-14 16:27:59,20.1,35.745,25,509,0.00520680069711517,0 +"4422",2015-02-14 16:28:59,20.1,35.79,31,516,0.00521341057015086,0 +"4423",2015-02-14 16:30:00,20.1,35.79,25,516,0.00521341057015086,0 +"4424",2015-02-14 16:31:00,20.05,35.845,26.5,516,0.00520521674452036,0 +"4425",2015-02-14 16:32:00,20,35.79,40,516,0.00518096065214833,0 +"4426",2015-02-14 16:33:00,20.0333333333333,35.8266666666667,31,513.333333333333,0.00519712075344864,0 +"4427",2015-02-14 16:34:00,20.0333333333333,35.9,24,512.333333333333,0.00520784776948095,0 +"4428",2015-02-14 16:34:59,20,35.9,24,514.75,0.00519701729991479,0 +"4429",2015-02-14 16:36:00,20,35.9,24,518,0.00519701729991479,0 +"4430",2015-02-14 16:37:00,20,35.9,24,516.5,0.00519701729991479,0 +"4431",2015-02-14 16:38:00,20,35.9,24,518,0.00519701729991479,0 +"4432",2015-02-14 16:38:59,20,35.8633333333333,24,516.666666666667,0.00519166499264429,0 +"4433",2015-02-14 16:40:00,20.0333333333333,35.8633333333333,24,518,0.00520248421559887,0 +"4434",2015-02-14 16:40:59,20.05,35.845,24,514,0.00520521674452036,0 +"4435",2015-02-14 16:41:59,20,35.79,24,517,0.00518096065214833,0 +"4436",2015-02-14 16:43:00,20.0333333333333,35.8266666666667,24,518.333333333333,0.00519712075344864,0 +"4437",2015-02-14 16:44:00,20.0666666666667,35.8266666666667,24,520,0.00520794864911491,0 +"4438",2015-02-14 16:45:00,20.1,35.79,24,518,0.00521341057015086,0 +"4439",2015-02-14 16:46:00,20.1,35.79,14,510,0.00521341057015086,0 +"4440",2015-02-14 16:46:59,20.0666666666667,35.76,20.3333333333333,511.666666666667,0.00519817664966774,0 +"4441",2015-02-14 16:47:59,20.0333333333333,35.73,20.3333333333333,510.666666666667,0.00518298115655964,0 +"4442",2015-02-14 16:49:00,20.1,35.8266666666667,17.3333333333333,513.666666666667,0.00521879649563226,0 +"4443",2015-02-14 16:50:00,20.1,35.745,24,515,0.00520680069711517,0 +"4444",2015-02-14 16:51:00,20.1,35.79,24,509,0.00521341057015086,0 +"4445",2015-02-14 16:52:00,20.05,35.7,24,514,0.00518398514023021,0 +"4446",2015-02-14 16:53:00,20,35.7,12,517,0.00516782400636706,0 +"4447",2015-02-14 16:53:59,20.1,35.79,6,519,0.00521341057015086,0 +"4448",2015-02-14 16:54:59,20,35.7,6,518,0.00516782400636706,0 +"4449",2015-02-14 16:56:00,20.05,35.745,6,515.5,0.00519057410497444,0 +"4450",2015-02-14 16:57:00,20,35.7,6,515,0.00516782400636706,0 +"4451",2015-02-14 16:58:00,20,35.59,6,514,0.00515176885328093,0 +"4452",2015-02-14 16:59:00,20,35.7,6,513.5,0.00516782400636706,0 +"4453",2015-02-14 16:59:59,20,35.7,17,509,0.00516782400636706,0 +"4454",2015-02-14 17:00:59,20,35.7,10,510,0.00516782400636706,0 +"4455",2015-02-14 17:02:00,20,35.7,11.3333333333333,513.333333333333,0.00516782400636706,0 +"4456",2015-02-14 17:03:00,20,35.7,14,516,0.00516782400636706,0 +"4457",2015-02-14 17:04:00,20,35.7,7,515,0.00516782400636706,0 +"4458",2015-02-14 17:05:00,20,35.7,14,515,0.00516782400636706,0 +"4459",2015-02-14 17:06:00,20,35.7,7,519.5,0.00516782400636706,0 +"4460",2015-02-14 17:06:59,20,35.7,14,518,0.00516782400636706,0 +"4461",2015-02-14 17:08:00,20,35.7,14,514,0.00516782400636706,0 +"4462",2015-02-14 17:09:00,20,35.7,14,515.5,0.00516782400636706,0 +"4463",2015-02-14 17:10:00,20,35.7,14,516.5,0.00516782400636706,0 +"4464",2015-02-14 17:10:59,20,35.6633333333333,9.33333333333333,514.333333333333,0.00516247219733609,0 +"4465",2015-02-14 17:12:00,20,35.59,14,515,0.00515176885328093,0 +"4466",2015-02-14 17:12:59,20,35.7,7,514.5,0.00516782400636706,0 +"4467",2015-02-14 17:13:59,20,35.7,14,515,0.00516782400636706,0 +"4468",2015-02-14 17:15:00,20,35.7,14,514.5,0.00516782400636706,0 +"4469",2015-02-14 17:16:00,20,35.7,14,515,0.00516782400636706,0 +"4470",2015-02-14 17:17:00,20,35.7,14,519.5,0.00516782400636706,0 +"4471",2015-02-14 17:18:00,20,35.7,7,517,0.00516782400636706,0 +"4472",2015-02-14 17:19:00,20,35.7,14,518,0.00516782400636706,0 +"4473",2015-02-14 17:19:59,20,35.7,7,516,0.00516782400636706,0 +"4474",2015-02-14 17:21:00,20,35.7,14,520,0.00516782400636706,0 +"4475",2015-02-14 17:22:00,20,35.6633333333333,14,518.666666666667,0.00516247219733609,0 +"4476",2015-02-14 17:23:00,20,35.59,14,520,0.00515176885328093,0 +"4477",2015-02-14 17:23:59,20,35.59,14,520,0.00515176885328093,0 +"4478",2015-02-14 17:25:00,20,35.59,14,521.5,0.00515176885328093,0 +"4479",2015-02-14 17:25:59,20,35.59,14,521,0.00515176885328093,0 +"4480",2015-02-14 17:26:59,20,35.59,14,516,0.00515176885328093,0 +"4481",2015-02-14 17:28:00,20,35.59,14,516.5,0.00515176885328093,0 +"4482",2015-02-14 17:29:00,20,35.59,14,521,0.00515176885328093,0 +"4483",2015-02-14 17:30:00,20,35.59,14,522,0.00515176885328093,0 +"4484",2015-02-14 17:31:00,20,35.5,14,519.333333333333,0.00513863343033455,0 +"4485",2015-02-14 17:31:59,20,35.5,0,515,0.00513863343033455,0 +"4486",2015-02-14 17:32:59,20,35.5,0,512,0.00513863343033455,0 +"4487",2015-02-14 17:34:00,20,35.5,4.66666666666667,516.333333333333,0.00513863343033455,0 +"4488",2015-02-14 17:35:00,19.945,35.5,0,513,0.00512100861323466,0 +"4489",2015-02-14 17:36:00,20,35.5,0,516,0.00513863343033455,0 +"4490",2015-02-14 17:37:00,20,35.5,7,516.5,0.00513863343033455,0 +"4491",2015-02-14 17:38:00,20,35.5,0,515.333333333333,0.00513863343033455,0 +"4492",2015-02-14 17:38:59,20,35.5,0,516,0.00513863343033455,0 +"4493",2015-02-14 17:39:59,20,35.45,7,515,0.00513133621089371,0 +"4494",2015-02-14 17:41:00,20,35.4,4.66666666666667,523,0.00512403916126793,0 +"4495",2015-02-14 17:42:00,20,35.4,0,521,0.00512403916126793,0 +"4496",2015-02-14 17:43:00,20,35.5,0,519,0.00513863343033455,0 +"4497",2015-02-14 17:44:00,20,35.4,0,517,0.00512403916126793,0 +"4498",2015-02-14 17:44:59,20,35.4,4.66666666666667,514,0.00512403916126793,0 +"4499",2015-02-14 17:45:59,20,35.4,0,516,0.00512403916126793,0 +"4500",2015-02-14 17:47:00,19.89,35.45,0,518.5,0.00509619045388799,0 +"4501",2015-02-14 17:48:00,19.89,35.5,0,519,0.00510343728618814,0 +"4502",2015-02-14 17:49:00,19.89,35.5,0,516.666666666667,0.00510343728618814,0 +"4503",2015-02-14 17:50:00,19.89,35.5,0,516,0.00510343728618814,0 +"4504",2015-02-14 17:51:00,19.89,35.5,0,515,0.00510343728618814,0 +"4505",2015-02-14 17:51:59,19.89,35.5,0,516.5,0.00510343728618814,0 +"4506",2015-02-14 17:53:00,19.9266666666667,35.4,0,518.666666666667,0.00510061854938161,0 +"4507",2015-02-14 17:54:00,19.89,35.45,0,517,0.00509619045388799,0 +"4508",2015-02-14 17:55:00,19.89,35.5,0,518,0.00510343728618814,0 +"4509",2015-02-14 17:55:59,19.89,35.5,0,514.5,0.00510343728618814,0 +"4510",2015-02-14 17:57:00,19.89,35.5,0,516,0.00510343728618814,0 +"4511",2015-02-14 17:57:59,19.89,35.5,0,519,0.00510343728618814,0 +"4512",2015-02-14 17:58:59,19.89,35.5,0,515.5,0.00510343728618814,0 +"4513",2015-02-14 18:00:00,19.89,35.5,0,515.5,0.00510343728618814,0 +"4514",2015-02-14 18:01:00,19.89,35.5,0,511,0.00510343728618814,0 +"4515",2015-02-14 18:02:00,19.89,35.5,0,509,0.00510343728618814,0 +"4516",2015-02-14 18:03:00,19.84,35.5,0,513.5,0.00508750965071454,0 +"4517",2015-02-14 18:04:00,19.89,35.5,0,515,0.00510343728618814,0 +"4518",2015-02-14 18:04:59,19.79,35.5,0,515,0.0050716259994161,0 +"4519",2015-02-14 18:06:00,19.89,35.5,0,514,0.00510343728618814,0 +"4520",2015-02-14 18:07:00,19.84,35.45,0,520,0.00508028561873035,0 +"4521",2015-02-14 18:08:00,19.89,35.5,0,517.333333333333,0.00510343728618814,0 +"4522",2015-02-14 18:08:59,19.84,35.5,0,513.5,0.00508750965071454,0 +"4523",2015-02-14 18:10:00,19.89,35.5,0,514.5,0.00510343728618814,0 +"4524",2015-02-14 18:10:59,19.89,35.5,0,522,0.00510343728618814,0 +"4525",2015-02-14 18:11:59,19.79,35.5,0,523,0.0050716259994161,0 +"4526",2015-02-14 18:13:00,19.84,35.45,0,522.5,0.00508028561873035,0 +"4527",2015-02-14 18:14:00,19.79,35.5,0,515,0.0050716259994161,0 +"4528",2015-02-14 18:15:00,19.79,35.5,0,517,0.0050716259994161,0 +"4529",2015-02-14 18:16:00,19.79,35.5,0,515,0.0050716259994161,0 +"4530",2015-02-14 18:16:59,19.79,35.5,0,513.5,0.0050716259994161,0 +"4531",2015-02-14 18:17:59,19.79,35.5,0,520,0.0050716259994161,0 +"4532",2015-02-14 18:19:00,19.79,35.5,0,517,0.0050716259994161,0 +"4533",2015-02-14 18:20:00,19.79,35.5,0,513,0.0050716259994161,0 +"4534",2015-02-14 18:21:00,19.79,35.5,0,517.5,0.0050716259994161,0 +"4535",2015-02-14 18:22:00,19.79,35.5,0,520,0.0050716259994161,0 +"4536",2015-02-14 18:23:00,19.84,35.5,0,519.5,0.00508750965071454,0 +"4537",2015-02-14 18:23:59,19.89,35.5,0,522,0.00510343728618814,0 +"4538",2015-02-14 18:24:59,19.79,35.4,0,518.5,0.00505722357326604,0 +"4539",2015-02-14 18:26:00,19.79,35.4,0,519.5,0.00505722357326604,0 +"4540",2015-02-14 18:27:00,19.84,35.45,0,517,0.00508028561873035,0 +"4541",2015-02-14 18:28:00,19.8566666666667,35.4666666666667,0,522.75,0.00508799286834919,0 +"4542",2015-02-14 18:29:00,19.89,35.5,0,523,0.00510343728618814,0 +"4543",2015-02-14 18:29:59,19.79,35.4,0,523,0.00505722357326604,0 +"4544",2015-02-14 18:30:59,19.89,35.5,0,526,0.00510343728618814,0 +"4545",2015-02-14 18:32:00,19.89,35.5,0,526.666666666667,0.00510343728618814,0 +"4546",2015-02-14 18:33:00,19.89,35.45,0,524.5,0.00509619045388799,0 +"4547",2015-02-14 18:34:00,19.84,35.4,0,521,0.00507306175318557,0 +"4548",2015-02-14 18:35:00,19.8566666666667,35.4,0,524,0.00507835088705791,0 +"4549",2015-02-14 18:36:00,19.84,35.4,0,523,0.00507306175318557,0 +"4550",2015-02-14 18:36:59,19.89,35.45,0,522.5,0.00509619045388799,0 +"4551",2015-02-14 18:38:00,19.79,35.4,0,512,0.00505722357326604,0 +"4552",2015-02-14 18:39:00,19.89,35.5,0,521,0.00510343728618814,0 +"4553",2015-02-14 18:40:00,19.79,35.4,0,521,0.00505722357326604,0 +"4554",2015-02-14 18:40:59,19.84,35.45,0,518.5,0.00508028561873035,0 +"4555",2015-02-14 18:42:00,19.79,35.4,0,517,0.00505722357326604,0 +"4556",2015-02-14 18:42:59,19.89,35.4666666666667,0,519.666666666667,0.00509860604604471,0 +"4557",2015-02-14 18:43:59,19.89,35.5,0,519,0.00510343728618814,0 +"4558",2015-02-14 18:45:00,19.89,35.45,0,519,0.00509619045388799,0 +"4559",2015-02-14 18:46:00,19.8233333333333,35.4,0,516.333333333333,0.00506777749219691,0 +"4560",2015-02-14 18:47:00,19.84,35.45,0,519,0.00508028561873035,0 +"4561",2015-02-14 18:48:00,19.84,35.45,0,519,0.00508028561873035,0 +"4562",2015-02-14 18:49:00,19.89,35.4,0,522,0.00508894378907528,0 +"4563",2015-02-14 18:49:59,19.84,35.4,0,521.5,0.00507306175318557,0 +"4564",2015-02-14 18:51:00,19.865,35.4,0,515.25,0.00508099728254566,0 +"4565",2015-02-14 18:52:00,19.89,35.4,0,521,0.00508894378907528,0 +"4566",2015-02-14 18:53:00,19.84,35.4,0,520,0.00507306175318557,0 +"4567",2015-02-14 18:53:59,19.84,35.4,0,523.5,0.00507306175318557,0 +"4568",2015-02-14 18:55:00,19.89,35.4,0,523,0.00508894378907528,0 +"4569",2015-02-14 18:55:59,19.79,35.4,0,525,0.00505722357326604,0 +"4570",2015-02-14 18:56:59,19.84,35.4,0,524,0.00507306175318557,0 +"4571",2015-02-14 18:58:00,19.89,35.4,0,520.5,0.00508894378907528,0 +"4572",2015-02-14 18:59:00,19.89,35.45,0,522.5,0.00509619045388799,0 +"4573",2015-02-14 19:00:00,19.84,35.45,0,524.5,0.00508028561873035,0 +"4574",2015-02-14 19:01:00,19.89,35.4,0,522,0.00508894378907528,0 +"4575",2015-02-14 19:01:59,19.84,35.4,0,524.5,0.00507306175318557,0 +"4576",2015-02-14 19:02:59,19.89,35.4,0,520.5,0.00508894378907528,0 +"4577",2015-02-14 19:04:00,19.84,35.345,0,522.5,0.00506511569331696,0 +"4578",2015-02-14 19:05:00,19.8566666666667,35.4,0,521.666666666667,0.00507835088705791,0 +"4579",2015-02-14 19:06:00,19.79,35.4,0,522,0.00505722357326604,0 +"4580",2015-02-14 19:07:00,19.84,35.45,0,523,0.00508028561873035,0 +"4581",2015-02-14 19:08:00,19.89,35.45,0,523.5,0.00509619045388799,0 +"4582",2015-02-14 19:08:59,19.89,35.4,0,525,0.00508894378907528,0 +"4583",2015-02-14 19:09:59,19.84,35.4,0,523.5,0.00507306175318557,0 +"4584",2015-02-14 19:11:00,19.89,35.4,0,518,0.00508894378907528,0 +"4585",2015-02-14 19:12:00,19.8566666666667,35.4,0,520.666666666667,0.00507835088705791,0 +"4586",2015-02-14 19:13:00,19.79,35.4,0,523,0.00505722357326604,0 +"4587",2015-02-14 19:14:00,19.89,35.45,0,521.5,0.00509619045388799,0 +"4588",2015-02-14 19:14:59,19.79,35.4,0,520,0.00505722357326604,0 +"4589",2015-02-14 19:15:59,19.79,35.45,0,515,0.00506442470364228,0 +"4590",2015-02-14 19:17:00,19.79,35.45,0,519.5,0.00506442470364228,0 +"4591",2015-02-14 19:18:00,19.79,35.4,0,521.5,0.00505722357326604,0 +"4592",2015-02-14 19:19:00,19.79,35.4,0,524,0.00505722357326604,0 +"4593",2015-02-14 19:20:00,19.79,35.4,0,528,0.00505722357326604,0 +"4594",2015-02-14 19:21:00,19.79,35.5,0,527.5,0.0050716259994161,0 +"4595",2015-02-14 19:21:59,19.79,35.45,0,529,0.00506442470364228,0 +"4596",2015-02-14 19:23:00,19.79,35.4,0,532,0.00505722357326604,0 +"4597",2015-02-14 19:24:00,19.79,35.4,0,532,0.00505722357326604,0 +"4598",2015-02-14 19:25:00,19.84,35.45,0,525.333333333333,0.00508028561873035,0 +"4599",2015-02-14 19:25:59,19.79,35.4,0,524,0.00505722357326604,0 +"4600",2015-02-14 19:27:00,19.79,35.4,0,524,0.00505722357326604,0 +"4601",2015-02-14 19:27:59,19.84,35.45,0,521.5,0.00508028561873035,0 +"4602",2015-02-14 19:28:59,19.8233333333333,35.4333333333333,0,522.333333333333,0.00507258832710329,0 +"4603",2015-02-14 19:30:00,19.79,35.4,0,519,0.00505722357326604,0 +"4604",2015-02-14 19:31:00,19.84,35.45,0,526,0.00508028561873035,0 +"4605",2015-02-14 19:32:00,19.89,35.4,0,525.5,0.00508894378907528,0 +"4606",2015-02-14 19:33:00,19.89,35.5,0,522,0.00510343728618814,0 +"4607",2015-02-14 19:34:00,19.84,35.45,0,526,0.00508028561873035,0 +"4608",2015-02-14 19:34:59,19.84,35.45,0,521.5,0.00508028561873035,0 +"4609",2015-02-14 19:36:00,19.8566666666667,35.4666666666667,0,521.333333333333,0.00508799286834919,0 +"4610",2015-02-14 19:37:00,19.89,35.4,0,521,0.00508894378907528,0 +"4611",2015-02-14 19:38:00,19.8566666666667,35.4,0,519.333333333333,0.00507835088705791,0 +"4612",2015-02-14 19:38:59,19.84,35.345,0,524.5,0.00506511569331696,0 +"4613",2015-02-14 19:40:00,19.8566666666667,35.4,0,524.333333333333,0.00507835088705791,0 +"4614",2015-02-14 19:40:59,19.89,35.4,0,522,0.00508894378907528,0 +"4615",2015-02-14 19:41:59,19.84,35.345,0,520.5,0.00506511569331696,0 +"4616",2015-02-14 19:43:00,19.89,35.4,0,518,0.00508894378907528,0 +"4617",2015-02-14 19:44:00,19.8233333333333,35.4,0,519,0.00506777749219691,0 +"4618",2015-02-14 19:45:00,19.84,35.4,0,523,0.00507306175318557,0 +"4619",2015-02-14 19:46:00,19.8233333333333,35.4,0,521.666666666667,0.00506777749219691,0 +"4620",2015-02-14 19:46:59,19.79,35.4,0,523.333333333333,0.00505722357326604,0 +"4621",2015-02-14 19:47:59,19.8233333333333,35.4,0,521.333333333333,0.00506777749219691,0 +"4622",2015-02-14 19:49:00,19.89,35.4,0,526,0.00508894378907528,0 +"4623",2015-02-14 19:50:00,19.89,35.4,0,526,0.00508894378907528,0 +"4624",2015-02-14 19:51:00,19.89,35.4,0,519,0.00508894378907528,0 +"4625",2015-02-14 19:52:00,19.89,35.4,0,518.5,0.00508894378907528,0 +"4626",2015-02-14 19:53:00,19.89,35.4,0,518,0.00508894378907528,0 +"4627",2015-02-14 19:53:59,19.89,35.4,0,515,0.00508894378907528,0 +"4628",2015-02-14 19:54:59,19.89,35.4,0,515,0.00508894378907528,0 +"4629",2015-02-14 19:56:00,19.89,35.4,0,512.5,0.00508894378907528,0 +"4630",2015-02-14 19:57:00,19.89,35.4,0,512.5,0.00508894378907528,0 +"4631",2015-02-14 19:58:00,19.84,35.345,0,506,0.00506511569331696,0 +"4632",2015-02-14 19:59:00,19.79,35.345,0,508,0.00504930252087958,0 +"4633",2015-02-14 19:59:59,19.89,35.4,0,512,0.00508894378907528,0 +"4634",2015-02-14 20:00:59,19.79,35.4,0,518,0.00505722357326604,0 +"4635",2015-02-14 20:02:00,19.79,35.4,0,518.25,0.00505722357326604,0 +"4636",2015-02-14 20:03:00,19.79,35.4,0,512,0.00505722357326604,0 +"4637",2015-02-14 20:04:00,19.79,35.4,0,512,0.00505722357326604,0 +"4638",2015-02-14 20:05:00,19.84,35.345,0,510.5,0.00506511569331696,0 +"4639",2015-02-14 20:06:00,19.79,35.4,0,512,0.00505722357326604,0 +"4640",2015-02-14 20:06:59,19.79,35.345,0,512,0.00504930252087958,0 +"4641",2015-02-14 20:08:00,19.79,35.4,0,509,0.00505722357326604,0 +"4642",2015-02-14 20:09:00,19.79,35.425,0,517,0.00506082411777982,0 +"4643",2015-02-14 20:10:00,19.79,35.5,0,524,0.0050716259994161,0 +"4644",2015-02-14 20:10:59,19.79,35.5,0,524,0.0050716259994161,0 +"4645",2015-02-14 20:12:00,19.79,35.4,0,523.333333333333,0.00505722357326604,0 +"4646",2015-02-14 20:12:59,19.79,35.4,0,523,0.00505722357326604,0 +"4647",2015-02-14 20:13:59,19.84,35.4,0,519,0.00507306175318557,0 +"4648",2015-02-14 20:15:00,19.79,35.29,0,519,0.00504138166860972,0 +"4649",2015-02-14 20:16:00,19.79,35.29,0,521,0.00504138166860972,0 +"4650",2015-02-14 20:17:00,19.84,35.345,0,524,0.00506511569331696,0 +"4651",2015-02-14 20:18:00,19.79,35.345,0,519,0.00504930252087958,0 +"4652",2015-02-14 20:19:00,19.84,35.345,0,525,0.00506511569331696,0 +"4653",2015-02-14 20:19:59,19.84,35.3725,0,523.25,0.00506908869807865,0 +"4654",2015-02-14 20:21:00,19.79,35.4,0,527,0.00505722357326604,0 +"4655",2015-02-14 20:22:00,19.84,35.4,0,531,0.00507306175318557,0 +"4656",2015-02-14 20:23:00,19.84,35.4,0,527.5,0.00507306175318557,0 +"4657",2015-02-14 20:23:59,19.89,35.4,0,529,0.00508894378907528,0 +"4658",2015-02-14 20:25:00,19.89,35.4,0,528.5,0.00508894378907528,0 +"4659",2015-02-14 20:25:59,19.89,35.4,0,532,0.00508894378907528,0 +"4660",2015-02-14 20:26:59,19.89,35.4,0,527,0.00508894378907528,0 +"4661",2015-02-14 20:28:00,19.8566666666667,35.3633333333333,0,525.333333333333,0.00507304792373249,0 +"4662",2015-02-14 20:29:00,19.89,35.4,0,529,0.00508894378907528,0 +"4663",2015-02-14 20:30:00,19.89,35.4,0,529,0.00508894378907528,0 +"4664",2015-02-14 20:31:00,19.89,35.4,0,531,0.00508894378907528,0 +"4665",2015-02-14 20:31:59,19.89,35.4,0,530.5,0.00508894378907528,0 +"4666",2015-02-14 20:32:59,19.89,35.4,0,529,0.00508894378907528,0 +"4667",2015-02-14 20:34:00,19.89,35.4,0,529.333333333333,0.00508894378907528,0 +"4668",2015-02-14 20:35:00,19.89,35.4,0,525,0.00508894378907528,0 +"4669",2015-02-14 20:36:00,19.89,35.4,0,531.666666666667,0.00508894378907528,0 +"4670",2015-02-14 20:37:00,19.89,35.4,0,528,0.00508894378907528,0 +"4671",2015-02-14 20:38:00,19.89,35.4,0,528,0.00508894378907528,0 +"4672",2015-02-14 20:38:59,19.89,35.4,0,529,0.00508894378907528,0 +"4673",2015-02-14 20:39:59,19.89,35.4,0,530,0.00508894378907528,0 +"4674",2015-02-14 20:41:00,19.89,35.4,0,527,0.00508894378907528,0 +"4675",2015-02-14 20:42:00,19.89,35.4,0,526.666666666667,0.00508894378907528,0 +"4676",2015-02-14 20:43:00,19.89,35.4,0,533,0.00508894378907528,0 +"4677",2015-02-14 20:44:00,19.89,35.4,0,533,0.00508894378907528,0 +"4678",2015-02-14 20:44:59,19.89,35.4,0,535,0.00508894378907528,0 +"4679",2015-02-14 20:45:59,19.89,35.4,0,533,0.00508894378907528,0 +"4680",2015-02-14 20:47:00,19.89,35.4,0,533.5,0.00508894378907528,0 +"4681",2015-02-14 20:48:00,19.89,35.4,0,534.5,0.00508894378907528,0 +"4682",2015-02-14 20:49:00,19.89,35.4,0,532,0.00508894378907528,0 +"4683",2015-02-14 20:50:00,19.89,35.4,0,531.333333333333,0.00508894378907528,0 +"4684",2015-02-14 20:51:00,19.89,35.4,0,529,0.00508894378907528,0 +"4685",2015-02-14 20:51:59,19.89,35.4,0,533,0.00508894378907528,0 +"4686",2015-02-14 20:53:00,19.89,35.45,0,531,0.00509619045388799,0 +"4687",2015-02-14 20:54:00,19.84,35.45,0,525,0.00508028561873035,0 +"4688",2015-02-14 20:55:00,19.8566666666667,35.4666666666667,0,528.333333333333,0.00508799286834919,0 +"4689",2015-02-14 20:55:59,19.89,35.5,0,525,0.00510343728618814,0 +"4690",2015-02-14 20:57:00,19.84,35.45,0,525,0.00508028561873035,0 +"4691",2015-02-14 20:57:59,19.89,35.4333333333333,0,526.333333333333,0.00509377488034099,0 +"4692",2015-02-14 20:58:59,19.89,35.4,0,534,0.00508894378907528,0 +"4693",2015-02-14 21:00:00,19.89,35.4,0,534.25,0.00508894378907528,0 +"4694",2015-02-14 21:01:00,19.89,35.4,0,533,0.00508894378907528,0 +"4695",2015-02-14 21:02:00,19.89,35.4,0,532,0.00508894378907528,0 +"4696",2015-02-14 21:03:00,19.89,35.4,0,534.5,0.00508894378907528,0 +"4697",2015-02-14 21:04:00,19.89,35.345,0,540,0.00508097265122235,0 +"4698",2015-02-14 21:04:59,19.89,35.29,0,536,0.00507300171601445,0 +"4699",2015-02-14 21:06:00,19.945,35.29,0,533.5,0.00509046740161306,0 +"4700",2015-02-14 21:07:00,19.89,35.29,0,529.5,0.00507300171601445,0 +"4701",2015-02-14 21:08:00,19.945,35.29,0,530,0.00509046740161306,0 +"4702",2015-02-14 21:08:59,20,35.29,0,532,0.005107986249811,0 +"4703",2015-02-14 21:10:00,20,35.26,0,534.333333333333,0.0051036083256814,0 +"4704",2015-02-14 21:10:59,20,35.245,0,533.5,0.00510141938653867,0 +"4705",2015-02-14 21:11:59,19.945,35.29,0,536,0.00509046740161306,0 +"4706",2015-02-14 21:13:00,19.945,35.2,0,538,0.0050773792215383,0 +"4707",2015-02-14 21:14:00,20,35.2,0,534,0.00509485266079684,0 +"4708",2015-02-14 21:15:00,20,35.2,0,538,0.00509485266079684,0 +"4709",2015-02-14 21:16:00,20,35.2,0,533,0.00509485266079684,0 +"4710",2015-02-14 21:16:59,20,35.2,0,532.5,0.00509485266079684,0 +"4711",2015-02-14 21:17:59,20,35.2,0,532.666666666667,0.00509485266079684,0 +"4712",2015-02-14 21:19:00,20,35.2,0,529,0.00509485266079684,0 +"4713",2015-02-14 21:20:00,20,35.2,0,531,0.00509485266079684,0 +"4714",2015-02-14 21:21:00,20,35.145,0,534.5,0.00508682684943148,0 +"4715",2015-02-14 21:22:00,20,35.145,0,532.5,0.00508682684943148,0 +"4716",2015-02-14 21:23:00,20,35.09,0,532.5,0.00507880124349859,0 +"4717",2015-02-14 21:23:59,20,35.145,0,533.5,0.00508682684943148,0 +"4718",2015-02-14 21:24:59,20,35.09,0,539,0.00507880124349859,0 +"4719",2015-02-14 21:26:00,20,35.2,0,537.333333333333,0.00509485266079684,0 +"4720",2015-02-14 21:27:00,20,35.2,0,533,0.00509485266079684,0 +"4721",2015-02-14 21:28:00,20,35.145,0,533.5,0.00508682684943148,0 +"4722",2015-02-14 21:29:00,20,35.09,0,533,0.00507880124349859,0 +"4723",2015-02-14 21:29:59,20,35.09,0,535,0.00507880124349859,0 +"4724",2015-02-14 21:30:59,19.89,35.145,0,533,0.00505198840358368,0 +"4725",2015-02-14 21:32:00,19.89,35.2,0,534,0.00505995880458261,0 +"4726",2015-02-14 21:33:00,19.89,35.29,0,533.5,0.00507300171601445,0 +"4727",2015-02-14 21:34:00,19.89,35.2,0,532,0.00505995880458261,0 +"4728",2015-02-14 21:35:00,19.89,35.2,0,534,0.00505995880458261,0 +"4729",2015-02-14 21:36:00,19.89,35.2,0,531,0.00505995880458261,0 +"4730",2015-02-14 21:36:59,19.89,35.2,0,526.5,0.00505995880458261,0 +"4731",2015-02-14 21:38:00,19.89,35.2,0,532.25,0.00505995880458261,0 +"4732",2015-02-14 21:39:00,19.89,35.2,0,524,0.00505995880458261,0 +"4733",2015-02-14 21:40:00,19.79,35.2225,0,527.75,0.00503166089613747,0 +"4734",2015-02-14 21:40:59,19.79,35.26,0,528.666666666667,0.0050370612880792,0 +"4735",2015-02-14 21:42:00,19.89,35.2,0,529,0.00505995880458261,0 +"4736",2015-02-14 21:42:59,19.8233333333333,35.23,0,530.666666666667,0.00504324338234415,0 +"4737",2015-02-14 21:43:59,19.79,35.145,0,528,0.00502050038089684,0 +"4738",2015-02-14 21:45:00,19.84,35.145,0,531.5,0.00503622262766043,0 +"4739",2015-02-14 21:46:00,19.79,35.145,0,531.25,0.00502050038089684,0 +"4740",2015-02-14 21:47:00,19.79,35.2,0,530.75,0.00502842070562293,0 +"4741",2015-02-14 21:48:00,19.79,35.2,0,527,0.00502842070562293,0 +"4742",2015-02-14 21:49:00,19.79,35.2,0,524.5,0.00502842070562293,0 +"4743",2015-02-14 21:49:59,19.8566666666667,35.1633333333333,0,532.333333333333,0.00504412424800302,0 +"4744",2015-02-14 21:51:00,19.89,35.2,0,536.5,0.00505995880458261,0 +"4745",2015-02-14 21:52:00,19.89,35.2,0,535,0.00505995880458261,0 +"4746",2015-02-14 21:53:00,19.89,35.2,0,534,0.00505995880458261,0 +"4747",2015-02-14 21:53:59,19.84,35.2,0,532,0.00504416795528548,0 +"4748",2015-02-14 21:55:00,19.84,35.2,0,534,0.00504416795528548,0 +"4749",2015-02-14 21:55:59,19.84,35.345,0,537,0.00506511569331696,0 +"4750",2015-02-14 21:56:59,19.79,35.4,0,531,0.00505722357326604,0 +"4751",2015-02-14 21:58:00,19.79,35.29,0,534.5,0.00504138166860972,0 +"4752",2015-02-14 21:59:00,19.89,35.4,0,532,0.00508894378907528,0 +"4753",2015-02-14 22:00:00,19.865,35.4,0,535,0.00508099728254566,0 +"4754",2015-02-14 22:01:00,19.79,35.45,0,537,0.00506442470364228,0 +"4755",2015-02-14 22:01:59,19.79,35.5,0,535,0.0050716259994161,0 +"4756",2015-02-14 22:02:59,19.79,35.5,0,533,0.0050716259994161,0 +"4757",2015-02-14 22:04:00,19.79,35.53,0,534.666666666667,0.00507594685627361,0 +"4758",2015-02-14 22:05:00,19.79,35.69,0,535,0.00509899243188306,0 +"4759",2015-02-14 22:06:00,19.79,35.845,0,532,0.00512131944862736,0 +"4760",2015-02-14 22:07:00,19.79,35.645,0,534,0.00509251069253615,0 +"4761",2015-02-14 22:08:00,19.79,35.7,0,534,0.00510043283660119,0 +"4762",2015-02-14 22:08:59,19.89,35.745,0,530.5,0.00513894918568269,0 +"4763",2015-02-14 22:09:59,19.89,35.7,0,523,0.00513242629037914,0 +"4764",2015-02-14 22:11:00,19.89,35.6633333333333,0,528.666666666667,0.00512711143897427,0 +"4765",2015-02-14 22:12:00,19.89,35.745,0,532.5,0.00513894918568269,0 +"4766",2015-02-14 22:13:00,19.89,35.7,0,528,0.00513242629037914,0 +"4767",2015-02-14 22:14:00,19.89,35.7,0,530,0.00513242629037914,0 +"4768",2015-02-14 22:14:59,19.89,35.7,0,530,0.00513242629037914,0 +"4769",2015-02-14 22:15:59,19.89,35.73,0,532.666666666667,0.00513677487217143,0 +"4770",2015-02-14 22:17:00,19.89,35.745,0,532,0.00513894918568269,0 +"4771",2015-02-14 22:18:00,19.89,35.7,0,524,0.00513242629037914,0 +"4772",2015-02-14 22:19:00,19.89,35.79,0,528,0.00514547221667881,0 +"4773",2015-02-14 22:20:00,19.89,35.845,0,529,0.00515344499439856,0 +"4774",2015-02-14 22:21:00,19.89,35.9333333333333,0,529.333333333333,0.00516625018284995,0 +"4775",2015-02-14 22:21:59,19.89,35.925,0,532,0.00516504212386495,0 +"4776",2015-02-14 22:23:00,19.89,36,0,533,0.00517591482227579,0 +"4777",2015-02-14 22:24:00,19.89,35.95,0,535.5,0.00516866631478195,0 +"4778",2015-02-14 22:25:00,19.89,35.9,0,535,0.0051614179748336,0 +"4779",2015-02-14 22:25:59,19.89,35.95,0,529.5,0.00516866631478195,0 +"4780",2015-02-14 22:27:00,19.89,36,0,531.666666666667,0.00517591482227579,0 +"4781",2015-02-14 22:27:59,19.89,36,0,530,0.00517591482227579,0 +"4782",2015-02-14 22:28:59,19.89,36,0,529.5,0.00517591482227579,0 +"4783",2015-02-14 22:30:00,19.89,36,0,532.5,0.00517591482227579,0 +"4784",2015-02-14 22:31:00,19.89,36,0,530,0.00517591482227579,0 +"4785",2015-02-14 22:32:00,19.89,36,0,531.5,0.00517591482227579,0 +"4786",2015-02-14 22:33:00,19.89,36,0,527,0.00517591482227579,0 +"4787",2015-02-14 22:34:00,19.84,36,0,534,0.00515975912598951,0 +"4788",2015-02-14 22:34:59,19.84,36,0,534,0.00515975912598951,0 +"4789",2015-02-14 22:36:00,19.89,36.03,0,534.666666666667,0.00518026400719636,0 +"4790",2015-02-14 22:37:00,19.89,36,0,531.5,0.00517591482227579,0 +"4791",2015-02-14 22:38:00,19.89,36,0,535,0.00517591482227579,0 +"4792",2015-02-14 22:38:59,19.89,36,0,535,0.00517591482227579,0 +"4793",2015-02-14 22:40:00,19.89,36,0,535,0.00517591482227579,0 +"4794",2015-02-14 22:40:59,19.89,36,0,528.5,0.00517591482227579,0 +"4795",2015-02-14 22:41:59,19.89,35.9666666666667,0,528,0.00517108246533011,0 +"4796",2015-02-14 22:43:00,19.89,36,0,533,0.00517591482227579,0 +"4797",2015-02-14 22:44:00,19.89,36,0,535,0.00517591482227579,0 +"4798",2015-02-14 22:45:00,19.89,35.9,0,538,0.0051614179748336,0 +"4799",2015-02-14 22:46:00,19.89,35.9,0,537,0.0051614179748336,0 +"4800",2015-02-14 22:46:59,19.89,35.9,0,532,0.0051614179748336,0 +"4801",2015-02-14 22:47:59,19.89,35.9,0,534,0.0051614179748336,0 +"4802",2015-02-14 22:49:00,19.9266666666667,35.9,0,535.333333333333,0.00517326037285823,0 +"4803",2015-02-14 22:50:00,19.89,35.9,0,537,0.0051614179748336,0 +"4804",2015-02-14 22:51:00,19.945,35.845,0,541.5,0.00517118991967981,0 +"4805",2015-02-14 22:52:00,20,35.79,0,532.5,0.00518096065214833,0 +"4806",2015-02-14 22:53:00,20,35.79,0,532,0.00518096065214833,0 +"4807",2015-02-14 22:53:59,20,35.79,0,534.5,0.00518096065214833,0 +"4808",2015-02-14 22:54:59,20,35.79,0,538,0.00518096065214833,0 +"4809",2015-02-14 22:56:00,20,35.79,0,535,0.00518096065214833,0 +"4810",2015-02-14 22:57:00,20,35.79,0,537,0.00518096065214833,0 +"4811",2015-02-14 22:58:00,20,35.79,0,535,0.00518096065214833,0 +"4812",2015-02-14 22:59:00,20,35.79,0,533,0.00518096065214833,0 +"4813",2015-02-14 22:59:59,20,35.79,0,534,0.00518096065214833,0 +"4814",2015-02-14 23:00:59,20,35.79,0,531,0.00518096065214833,0 +"4815",2015-02-14 23:02:00,20,35.79,0,535.5,0.00518096065214833,0 +"4816",2015-02-14 23:03:00,20,35.79,0,535,0.00518096065214833,0 +"4817",2015-02-14 23:04:00,20,35.79,0,535,0.00518096065214833,0 +"4818",2015-02-14 23:05:00,20,35.79,0,533.5,0.00518096065214833,0 +"4819",2015-02-14 23:06:00,20,35.79,0,530,0.00518096065214833,0 +"4820",2015-02-14 23:06:59,20,35.79,0,529.5,0.00518096065214833,0 +"4821",2015-02-14 23:08:00,20,35.79,0,529,0.00518096065214833,0 +"4822",2015-02-14 23:09:00,20,35.79,0,527.666666666667,0.00518096065214833,0 +"4823",2015-02-14 23:10:00,20,35.79,0,530,0.00518096065214833,0 +"4824",2015-02-14 23:10:59,20,35.79,0,532,0.00518096065214833,0 +"4825",2015-02-14 23:12:00,20,35.79,0,532,0.00518096065214833,0 +"4826",2015-02-14 23:12:59,20.05,35.745,0,538.5,0.00519057410497444,0 +"4827",2015-02-14 23:13:59,20.05,35.745,0,542.5,0.00519057410497444,0 +"4828",2015-02-14 23:15:00,20,35.7,0,533.5,0.00516782400636706,0 +"4829",2015-02-14 23:16:00,20,35.7,0,535.5,0.00516782400636706,0 +"4830",2015-02-14 23:17:00,20.05,35.745,0,537,0.00519057410497444,0 +"4831",2015-02-14 23:18:00,20,35.7,0,543.333333333333,0.00516782400636706,0 +"4832",2015-02-14 23:19:00,20.1,35.79,0,544,0.00521341057015086,0 +"4833",2015-02-14 23:19:59,20,35.79,0,531.5,0.00518096065214833,0 +"4834",2015-02-14 23:21:00,20,35.79,0,531.5,0.00518096065214833,0 +"4835",2015-02-14 23:22:00,20,35.7,0,535,0.00516782400636706,0 +"4836",2015-02-14 23:23:00,20,35.79,0,539.5,0.00518096065214833,0 +"4837",2015-02-14 23:23:59,20,35.73,0,535.333333333333,0.00517220282714835,0 +"4838",2015-02-14 23:25:00,20,35.7,0,539,0.00516782400636706,0 +"4839",2015-02-14 23:25:59,20.05,35.79,0,537,0.0051971632081626,0 +"4840",2015-02-14 23:26:59,20,35.7,0,539,0.00516782400636706,0 +"4841",2015-02-14 23:28:00,20,35.7,0,538,0.00516782400636706,0 +"4842",2015-02-14 23:29:00,20,35.7,0,532.333333333333,0.00516782400636706,0 +"4843",2015-02-14 23:30:00,20,35.7,0,534.5,0.00516782400636706,0 +"4844",2015-02-14 23:31:00,20,35.7,0,534,0.00516782400636706,0 +"4845",2015-02-14 23:31:59,20,35.7,0,536.333333333333,0.00516782400636706,0 +"4846",2015-02-14 23:32:59,20,35.7,0,530.5,0.00516782400636706,0 +"4847",2015-02-14 23:34:00,20.0333333333333,35.73,0,537,0.00518298115655964,0 +"4848",2015-02-14 23:35:00,20,35.7,0,537,0.00516782400636706,0 +"4849",2015-02-14 23:36:00,20,35.7,0,537.5,0.00516782400636706,0 +"4850",2015-02-14 23:37:00,20,35.7,0,543.333333333333,0.00516782400636706,0 +"4851",2015-02-14 23:38:00,20,35.7,0,537,0.00516782400636706,0 +"4852",2015-02-14 23:38:59,20,35.79,0,535,0.00518096065214833,0 +"4853",2015-02-14 23:39:59,20,35.79,0,538.666666666667,0.00518096065214833,0 +"4854",2015-02-14 23:41:00,20,35.7,0,541,0.00516782400636706,0 +"4855",2015-02-14 23:42:00,20,35.7,0,539,0.00516782400636706,0 +"4856",2015-02-14 23:43:00,20,35.7,0,540,0.00516782400636706,0 +"4857",2015-02-14 23:44:00,20,35.7,0,541,0.00516782400636706,0 +"4858",2015-02-14 23:44:59,20,35.7,0,540,0.00516782400636706,0 +"4859",2015-02-14 23:45:59,20,35.7,0,536,0.00516782400636706,0 +"4860",2015-02-14 23:47:00,20.05,35.7,0,540,0.00518398514023021,0 +"4861",2015-02-14 23:48:00,20,35.7,0,540,0.00516782400636706,0 +"4862",2015-02-14 23:49:00,20,35.645,0,537.5,0.00515979632707189,0 +"4863",2015-02-14 23:50:00,20,35.645,0,541,0.00515979632707189,0 +"4864",2015-02-14 23:51:00,20,35.6266666666667,0,537.333333333333,0.0051571204796415,0 +"4865",2015-02-14 23:51:59,20,35.59,0,538,0.00515176885328093,0 +"4866",2015-02-14 23:53:00,20,35.7,0,543.5,0.00516782400636706,0 +"4867",2015-02-14 23:54:00,20,35.7,0,534,0.00516782400636706,0 +"4868",2015-02-14 23:55:00,20,35.59,0,533,0.00515176885328093,0 +"4869",2015-02-14 23:55:59,20,35.7,0,535,0.00516782400636706,0 +"4870",2015-02-14 23:57:00,20,35.7,0,540,0.00516782400636706,0 +"4871",2015-02-14 23:57:59,19.89,35.7,0,538.25,0.00513242629037914,0 +"4872",2015-02-14 23:58:59,19.89,35.79,0,535,0.00514547221667881,0 +"4873",2015-02-15 00:00:00,19.89,35.745,0,535.5,0.00513894918568269,0 +"4874",2015-02-15 00:01:00,19.89,35.7,0,541,0.00513242629037914,0 +"4875",2015-02-15 00:02:00,20,35.7,0,539.333333333333,0.00516782400636706,0 +"4876",2015-02-15 00:03:00,20,35.7,0,541,0.00516782400636706,0 +"4877",2015-02-15 00:04:00,20,35.7,0,542,0.00516782400636706,0 +"4878",2015-02-15 00:04:59,19.9266666666667,35.7,0,540,0.00514420162404428,0 +"4879",2015-02-15 00:06:00,20,35.7,0,532,0.00516782400636706,0 +"4880",2015-02-15 00:07:00,19.945,35.7,0,534,0.00515009824735373,0 +"4881",2015-02-15 00:08:00,20,35.7,0,537,0.00516782400636706,0 +"4882",2015-02-15 00:08:59,19.9266666666667,35.7,0,542,0.00514420162404428,0 +"4883",2015-02-15 00:10:00,20,35.7,0,538.5,0.00516782400636706,0 +"4884",2015-02-15 00:10:59,19.89,35.645,0,538,0.0051244540470536,0 +"4885",2015-02-15 00:11:59,19.9175,35.7,0,540.75,0.00514125555249509,0 +"4886",2015-02-15 00:13:00,20,35.7,0,539,0.00516782400636706,0 +"4887",2015-02-15 00:14:00,19.9633333333333,35.6633333333333,0,529.333333333333,0.00515066138427544,0 +"4888",2015-02-15 00:15:00,20,35.59,0,534.5,0.00515176885328093,0 +"4889",2015-02-15 00:16:00,20,35.59,0,536,0.00515176885328093,0 +"4890",2015-02-15 00:16:59,20,35.59,0,531,0.00515176885328093,0 +"4891",2015-02-15 00:17:59,20,35.59,0,531.5,0.00515176885328093,0 +"4892",2015-02-15 00:19:00,20,35.59,0,537.333333333333,0.00515176885328093,0 +"4893",2015-02-15 00:20:00,20,35.59,0,534,0.00515176885328093,0 +"4894",2015-02-15 00:21:00,20,35.5,0,534,0.00513863343033455,0 +"4895",2015-02-15 00:22:00,20,35.5,0,538,0.00513863343033455,0 +"4896",2015-02-15 00:23:00,20,35.5,0,534.5,0.00513863343033455,0 +"4897",2015-02-15 00:23:59,20,35.5,0,537,0.00513863343033455,0 +"4898",2015-02-15 00:24:59,20,35.5,0,538,0.00513863343033455,0 +"4899",2015-02-15 00:26:00,19.9633333333333,35.5,0,538,0.00512687760194885,0 +"4900",2015-02-15 00:27:00,19.945,35.545,0,544.5,0.0051275535456267,0 +"4901",2015-02-15 00:28:00,20,35.5,0,542,0.00513863343033455,0 +"4902",2015-02-15 00:29:00,20,35.5,0,542,0.00513863343033455,0 +"4903",2015-02-15 00:29:59,20,35.5,0,539,0.00513863343033455,0 +"4904",2015-02-15 00:30:59,20,35.5,0,540,0.00513863343033455,0 +"4905",2015-02-15 00:32:00,20,35.5,0,541,0.00513863343033455,0 +"4906",2015-02-15 00:33:00,20,35.4,0,546,0.00512403916126793,0 +"4907",2015-02-15 00:34:00,19.9633333333333,35.4666666666667,0,541.333333333333,0.00512202399046011,0 +"4908",2015-02-15 00:35:00,19.945,35.5,0,536.5,0.00512100861323466,0 +"4909",2015-02-15 00:36:00,20,35.5,0,541,0.00513863343033455,0 +"4910",2015-02-15 00:36:59,20,35.5,0,537.5,0.00513863343033455,0 +"4911",2015-02-15 00:38:00,20,35.5,0,532.5,0.00513863343033455,0 +"4912",2015-02-15 00:39:00,20,35.45,0,537,0.00513133621089371,0 +"4913",2015-02-15 00:40:00,20,35.5,0,542,0.00513863343033455,0 +"4914",2015-02-15 00:40:59,19.945,35.4,0,540.5,0.00510646480811851,0 +"4915",2015-02-15 00:42:00,19.945,35.4,0,542,0.00510646480811851,0 +"4916",2015-02-15 00:42:59,20,35.4,0,539,0.00512403916126793,0 +"4917",2015-02-15 00:43:59,20,35.4,0,530,0.00512403916126793,0 +"4918",2015-02-15 00:45:00,19.89,35.45,0,535,0.00509619045388799,0 +"4919",2015-02-15 00:46:00,19.89,35.4,0,537.5,0.00508894378907528,0 +"4920",2015-02-15 00:47:00,19.89,35.4,0,540.666666666667,0.00508894378907528,0 +"4921",2015-02-15 00:48:00,19.89,35.4,0,540,0.00508894378907528,0 +"4922",2015-02-15 00:49:00,19.9633333333333,35.4,0,544.5,0.00511231699286458,0 +"4923",2015-02-15 00:49:59,19.89,35.4,0,544,0.00508894378907528,0 +"4924",2015-02-15 00:51:00,19.945,35.4,0,542.5,0.00510646480811851,0 +"4925",2015-02-15 00:52:00,19.945,35.4,0,535,0.00510646480811851,0 +"4926",2015-02-15 00:53:00,20,35.4,0,540,0.00512403916126793,0 +"4927",2015-02-15 00:53:59,19.89,35.29,0,540,0.00507300171601445,0 +"4928",2015-02-15 00:55:00,19.89,35.29,0,545,0.00507300171601445,0 +"4929",2015-02-15 00:55:59,19.89,35.4,0,543.333333333333,0.00508894378907528,0 +"4930",2015-02-15 00:56:59,19.89,35.4,0,542,0.00508894378907528,0 +"4931",2015-02-15 00:58:00,19.89,35.4,0,544,0.00508894378907528,0 +"4932",2015-02-15 00:59:00,19.89,35.4,0,544,0.00508894378907528,0 +"4933",2015-02-15 01:00:00,19.89,35.4,0,542,0.00508894378907528,0 +"4934",2015-02-15 01:01:00,19.89,35.29,0,537.666666666667,0.00507300171601445,0 +"4935",2015-02-15 01:01:59,19.89,35.345,0,540,0.00508097265122235,0 +"4936",2015-02-15 01:02:59,19.89,35.4,0,543,0.00508894378907528,0 +"4937",2015-02-15 01:04:00,19.89,35.29,0,542,0.00507300171601445,0 +"4938",2015-02-15 01:05:00,19.8566666666667,35.26,0,544.666666666667,0.00505810369144341,0 +"4939",2015-02-15 01:06:00,19.89,35.29,0,531.5,0.00507300171601445,0 +"4940",2015-02-15 01:07:00,19.89,35.345,0,530.5,0.00508097265122235,0 +"4941",2015-02-15 01:08:00,19.89,35.29,0,538,0.00507300171601445,0 +"4942",2015-02-15 01:08:59,19.89,35.29,0,538,0.00507300171601445,0 +"4943",2015-02-15 01:09:59,19.89,35.245,0,536,0.00506648019247576,0 +"4944",2015-02-15 01:11:00,19.89,35.2,0,539.5,0.00505995880458261,0 +"4945",2015-02-15 01:12:00,19.89,35.2,0,540,0.00505995880458261,0 +"4946",2015-02-15 01:13:00,19.89,35.2,0,541,0.00505995880458261,0 +"4947",2015-02-15 01:14:00,19.89,35.2,0,539,0.00505995880458261,0 +"4948",2015-02-15 01:14:59,19.89,35.2,0,539,0.00505995880458261,0 +"4949",2015-02-15 01:15:59,19.945,35.2,0,540.5,0.0050773792215383,0 +"4950",2015-02-15 01:17:00,20,35.2,0,549.5,0.00509485266079684,0 +"4951",2015-02-15 01:18:00,20,35.09,0,547,0.00507880124349859,0 +"4952",2015-02-15 01:19:00,19.9266666666667,35.09,0,543,0.00505558906891854,0 +"4953",2015-02-15 01:20:00,20,35.045,0,542.5,0.00507223499143991,0 +"4954",2015-02-15 01:21:00,20,35,0,541,0.00506566887689254,0 +"4955",2015-02-15 01:21:59,20,35,0,541.5,0.00506566887689254,0 +"4956",2015-02-15 01:23:00,19.945,35,0,540,0.00504829633284803,0 +"4957",2015-02-15 01:24:00,20,35,0,538,0.00506566887689254,0 +"4958",2015-02-15 01:25:00,20,35,0,540,0.00506566887689254,0 +"4959",2015-02-15 01:25:59,20,35,0,544,0.00506566887689254,0 +"4960",2015-02-15 01:27:00,20,35,0,544,0.00506566887689254,0 +"4961",2015-02-15 01:27:59,20,35,0,538.5,0.00506566887689254,0 +"4962",2015-02-15 01:28:59,20,35,0,534,0.00506566887689254,0 +"4963",2015-02-15 01:30:00,20,35,0,538.5,0.00506566887689254,0 +"4964",2015-02-15 01:31:00,20,35,0,539,0.00506566887689254,0 +"4965",2015-02-15 01:32:00,20,35,0,542,0.00506566887689254,0 +"4966",2015-02-15 01:33:00,20,34.9,0,543,0.00505107800353441,0 +"4967",2015-02-15 01:34:00,20,34.9333333333333,0,543.666666666667,0.00505594155254039,0 +"4968",2015-02-15 01:34:59,19.9633333333333,34.9,0,535.666666666667,0.0050395240882968,0 +"4969",2015-02-15 01:36:00,20,34.9,0,538.75,0.00505107800353441,0 +"4970",2015-02-15 01:37:00,20,34.9,0,536.25,0.00505107800353441,0 +"4971",2015-02-15 01:38:00,20,34.9,0,536,0.00505107800353441,0 +"4972",2015-02-15 01:38:59,20,34.9,0,535.666666666667,0.00505107800353441,0 +"4973",2015-02-15 01:40:00,20,34.9,0,537,0.00505107800353441,0 +"4974",2015-02-15 01:40:59,20,34.79,0,537.5,0.00503502882708305,0 +"4975",2015-02-15 01:41:59,20,34.8633333333333,0,536,0.00504572818676603,0 +"4976",2015-02-15 01:43:00,20,34.79,0,544.333333333333,0.00503502882708305,0 +"4977",2015-02-15 01:44:00,20,34.79,0,545.5,0.00503502882708305,0 +"4978",2015-02-15 01:45:00,20,34.73,0,544,0.00502627507710402,0 +"4979",2015-02-15 01:46:00,20,34.7,0,542,0.0050218982937692,0 +"4980",2015-02-15 01:46:59,20,34.7,0,542,0.0050218982937692,0 +"4981",2015-02-15 01:47:59,20,34.7,0,541,0.0050218982937692,0 +"4982",2015-02-15 01:49:00,20,34.7,0,545,0.0050218982937692,0 +"4983",2015-02-15 01:50:00,20,34.7,0,539.5,0.0050218982937692,0 +"4984",2015-02-15 01:51:00,20,34.7,0,538,0.0050218982937692,0 +"4985",2015-02-15 01:52:00,20,34.7,0,538,0.0050218982937692,0 +"4986",2015-02-15 01:53:00,20,34.6266666666667,0,542.333333333333,0.00501119974728872,0 +"4987",2015-02-15 01:53:59,20,34.59,0,544.5,0.00500585061095508,0 +"4988",2015-02-15 01:54:59,20,34.59,0,552,0.00500585061095508,0 +"4989",2015-02-15 01:56:00,20,34.59,0,549,0.00500585061095508,0 +"4990",2015-02-15 01:57:00,20,34.53,0,542.333333333333,0.00499709767563894,0 +"4991",2015-02-15 01:58:00,20,34.545,0,538,0.00499928588655726,0 +"4992",2015-02-15 01:59:00,20,34.5,0,535,0.00499272129962277,0 +"4993",2015-02-15 01:59:59,20,34.5225,0,538.5,0.00499600357590737,0 +"4994",2015-02-15 02:00:59,20,34.545,0,536,0.00499928588655726,0 +"4995",2015-02-15 02:02:00,20,34.545,0,539.333333333333,0.00499928588655726,0 +"4996",2015-02-15 02:03:00,19.89,34.5,0,540,0.00495853245617905,0 +"4997",2015-02-15 02:04:00,19.945,34.5,0,538,0.00497560091192775,0 +"4998",2015-02-15 02:05:00,19.89,34.545,0,542,0.00496505173457535,0 +"4999",2015-02-15 02:06:00,19.9633333333333,34.4666666666667,0,546.666666666667,0.00497645057243167,0 +"5000",2015-02-15 02:06:59,19.89,34.5,0,546.5,0.00495853245617905,0 +"5001",2015-02-15 02:08:00,19.945,34.5,0,538,0.00497560091192775,0 +"5002",2015-02-15 02:09:00,19.9266666666667,34.3966666666667,0,537.333333333333,0.00495490137471378,0 +"5003",2015-02-15 02:10:00,19.89,34.4,0,539,0.00494404565624152,0 +"5004",2015-02-15 02:10:59,19.89,34.4,0,534,0.00494404565624152,0 +"5005",2015-02-15 02:12:00,19.89,34.3633333333333,0,539.333333333333,0.00493873399733769,0 +"5006",2015-02-15 02:12:59,19.89,34.45,0,544.5,0.00495128897252461,0 +"5007",2015-02-15 02:13:59,19.89,34.5,0,545,0.00495853245617905,0 +"5008",2015-02-15 02:15:00,19.945,34.45,0,544.5,0.00496833229688062,0 +"5009",2015-02-15 02:16:00,19.9266666666667,34.4,0,545.333333333333,0.00495538537281126,0 +"5010",2015-02-15 02:17:00,19.89,34.4,0,547,0.00494404565624152,0 +"5011",2015-02-15 02:18:00,19.89,34.4,0,544,0.00494404565624152,0 +"5012",2015-02-15 02:19:00,20,34.4,0,545.5,0.00497813382078813,0 +"5013",2015-02-15 02:19:59,20,34.345,0,547.5,0.00497011099675465,0 +"5014",2015-02-15 02:21:00,20,34.29,0,543.666666666667,0.00496208837803895,0 +"5015",2015-02-15 02:22:00,19.9633333333333,34.29,0,547.666666666667,0.00495073962620215,0 +"5016",2015-02-15 02:23:00,20,34.29,0,545.5,0.00496208837803895,0 +"5017",2015-02-15 02:23:59,20,34.2,0,538.666666666667,0.00494896089935913,0 +"5018",2015-02-15 02:25:00,20,34.2,0,543.5,0.00494896089935913,0 +"5019",2015-02-15 02:25:59,20,34.2,0,544,0.00494896089935913,0 +"5020",2015-02-15 02:26:59,20,34.2,0,541.333333333333,0.00494896089935913,0 +"5021",2015-02-15 02:28:00,20,34.2,0,542,0.00494896089935913,0 +"5022",2015-02-15 02:29:00,20,34.145,0,538,0.004940938821898,0 +"5023",2015-02-15 02:30:00,20,34.09,0,542,0.00493291694972601,0 +"5024",2015-02-15 02:31:00,20,34.145,0,545,0.004940938821898,0 +"5025",2015-02-15 02:31:59,20,34.09,0,547,0.00493291694972601,0 +"5026",2015-02-15 02:32:59,20,34.09,0,541.5,0.00493291694972601,0 +"5027",2015-02-15 02:34:00,20,34.09,0,547.5,0.00493291694972601,0 +"5028",2015-02-15 02:35:00,20,34.09,0,547.5,0.00493291694972601,0 +"5029",2015-02-15 02:36:00,20,34.03,0,542,0.00492416605056961,0 +"5030",2015-02-15 02:37:00,20,34,0,538,0.00491979069260134,0 +"5031",2015-02-15 02:38:00,20,34,0,535,0.00491979069260134,0 +"5032",2015-02-15 02:38:59,20,34,0,539.666666666667,0.00491979069260134,0 +"5033",2015-02-15 02:39:59,20,34.045,0,549.333333333333,0.00492635375245599,0 +"5034",2015-02-15 02:41:00,20,34,0,549,0.00491979069260134,0 +"5035",2015-02-15 02:42:00,20,34,0,539,0.00491979069260134,0 +"5036",2015-02-15 02:43:00,20,34,0,539,0.00491979069260134,0 +"5037",2015-02-15 02:44:00,20,34,0,543,0.00491979069260134,0 +"5038",2015-02-15 02:44:59,20,34,0,547.5,0.00491979069260134,0 +"5039",2015-02-15 02:45:59,20.05,33.975,0,545.666666666667,0.00493151248551332,0 +"5040",2015-02-15 02:47:00,20,33.9,0,541.5,0.00490520660710574,0 +"5041",2015-02-15 02:48:00,20.0333333333333,33.9333333333333,0,543.666666666667,0.00492029567564949,0 +"5042",2015-02-15 02:49:00,20,33.9,0,547,0.00490520660710574,0 +"5043",2015-02-15 02:50:00,20,33.9,0,548,0.00490520660710574,0 +"5044",2015-02-15 02:51:00,20.05,33.9,0,544,0.00492054002442662,0 +"5045",2015-02-15 02:51:59,20.05,33.845,0,548.5,0.004912493797062,0 +"5046",2015-02-15 02:53:00,20,33.79,0,548.5,0.00488916489675597,0 +"5047",2015-02-15 02:54:00,20.1,33.9,0,546,0.00493591580189434,0 +"5048",2015-02-15 02:55:00,20.1,33.9,0,543,0.00493591580189434,0 +"5049",2015-02-15 02:55:59,20.1,33.9,0,543,0.00493591580189434,0 +"5050",2015-02-15 02:57:00,20.05,33.845,0,546.5,0.004912493797062,0 +"5051",2015-02-15 02:57:59,20.05,33.845,0,547,0.004912493797062,0 +"5052",2015-02-15 02:58:59,20.0666666666667,33.8633333333333,0,542.333333333333,0.00492029077133738,0 +"5053",2015-02-15 03:00:00,20,33.79,0,542.5,0.00488916489675597,0 +"5054",2015-02-15 03:01:00,20,33.79,0,541.5,0.00488916489675597,0 +"5055",2015-02-15 03:02:00,20.0666666666667,33.8633333333333,0,547,0.00492029077133738,0 +"5056",2015-02-15 03:03:00,20.0666666666667,33.79,0,551,0.00490955144619401,0 +"5057",2015-02-15 03:04:00,20.0333333333333,33.7966666666667,0,545.666666666667,0.00490032303954802,0 +"5058",2015-02-15 03:04:59,20.1,33.9,0,545,0.00493591580189434,0 +"5059",2015-02-15 03:06:00,20,33.79,0,545,0.00488916489675597,0 +"5060",2015-02-15 03:07:00,20.1,33.9,0,547.5,0.00493591580189434,0 +"5061",2015-02-15 03:08:00,20.0666666666667,33.7966666666667,0,546.666666666667,0.0049105277332758,0 +"5062",2015-02-15 03:08:59,20,33.7,0,554,0.00487604047164436,0 +"5063",2015-02-15 03:10:00,20.1,33.7,0,550,0.0049065656418467,0 +"5064",2015-02-15 03:10:59,20.1,33.7,0,547,0.0049065656418467,0 +"5065",2015-02-15 03:11:59,20.05,33.7,0,546.5,0.00489128200581624,0 +"5066",2015-02-15 03:13:00,20,33.7,0,543,0.00487604047164436,0 +"5067",2015-02-15 03:14:00,20,33.7,0,546,0.00487604047164436,0 +"5068",2015-02-15 03:15:00,20,33.7,0,543,0.00487604047164436,0 +"5069",2015-02-15 03:16:00,20,33.59,0,543,0.00486000025388971,0 +"5070",2015-02-15 03:16:59,20.1,33.7,0,544,0.0049065656418467,0 +"5071",2015-02-15 03:17:59,20.1,33.7,0,547,0.0049065656418467,0 +"5072",2015-02-15 03:19:00,20.05,33.59,0,555,0.00487519125960086,0 +"5073",2015-02-15 03:20:00,20.1,33.6266666666667,0,549.333333333333,0.00489580460502829,0 +"5074",2015-02-15 03:21:00,20.1,33.59,0,551.5,0.00489042422515518,0 +"5075",2015-02-15 03:22:00,20.0666666666667,33.56,0,551.333333333333,0.0048758714038463,0 +"5076",2015-02-15 03:23:00,20.0666666666667,33.56,0,554.333333333333,0.0048758714038463,0 +"5077",2015-02-15 03:23:59,20.1,33.59,0,550,0.00489042422515518,0 +"5078",2015-02-15 03:24:59,20.1,33.59,0,547.333333333333,0.00489042422515518,0 +"5079",2015-02-15 03:26:00,20.1,33.59,0,547,0.00489042422515518,0 +"5080",2015-02-15 03:27:00,20.1,33.59,0,546,0.00489042422515518,0 +"5081",2015-02-15 03:28:00,20.075,33.475,0,550.75,0.00486595476502773,0 +"5082",2015-02-15 03:29:00,20.1,33.5,0,550.333333333333,0.00487721822974042,0 +"5083",2015-02-15 03:29:59,20.1,33.5,0,549,0.00487721822974042,0 +"5084",2015-02-15 03:30:59,20.1,33.5,0,550.5,0.00487721822974042,0 +"5085",2015-02-15 03:32:00,20.0666666666667,33.4666666666667,0,550.333333333333,0.00486220517248165,0 +"5086",2015-02-15 03:33:00,20.1,33.5,0,552,0.00487721822974042,0 +"5087",2015-02-15 03:34:00,20.1,33.5,0,551,0.00487721822974042,0 +"5088",2015-02-15 03:35:00,20.1,33.4333333333333,0,548.666666666667,0.00486743636962527,0 +"5089",2015-02-15 03:36:00,20.05,33.4,0,548,0.0048474000979977,0 +"5090",2015-02-15 03:36:59,20.1,33.4,0,547,0.0048625455540447,0 +"5091",2015-02-15 03:38:00,20.1,33.4,0,554,0.0048625455540447,0 +"5092",2015-02-15 03:39:00,20.05,33.345,0,551.5,0.00483935574794395,0 +"5093",2015-02-15 03:40:00,20.1,33.345,0,549.5,0.00485447587518096,0 +"5094",2015-02-15 03:40:59,20.1,33.345,0,554.5,0.00485447587518096,0 +"5095",2015-02-15 03:42:00,20.1,33.29,0,554.5,0.00484640640407848,0 +"5096",2015-02-15 03:42:59,20.1,33.29,0,550,0.00484640640407848,0 +"5097",2015-02-15 03:43:59,20.05,33.245,0,553,0.00482473018588917,0 +"5098",2015-02-15 03:45:00,20.1,33.2,0,551,0.00483320226312693,0 +"5099",2015-02-15 03:46:00,20.1,33.2,0,551.5,0.00483320226312693,0 +"5100",2015-02-15 03:47:00,20.1,33.2,0,551.5,0.00483320226312693,0 +"5101",2015-02-15 03:48:00,20.1,33.2,0,556.5,0.00483320226312693,0 +"5102",2015-02-15 03:49:00,20.1,33.1633333333333,0,555.333333333333,0.00482782295777407,0 +"5103",2015-02-15 03:49:59,20.1,33.09,0,558,0.00481706462404567,0 +"5104",2015-02-15 03:51:00,20.1,33.09,0,557,0.00481706462404567,0 +"5105",2015-02-15 03:52:00,20.1,33.09,0,553,0.00481706462404567,0 +"5106",2015-02-15 03:53:00,20.1,33.06,0,555.666666666667,0.00481266359395861,0 +"5107",2015-02-15 03:53:59,20.1,33,0,554,0.00480386171918592,0 +"5108",2015-02-15 03:55:00,20.1,33.045,0,552.5,0.00481046310209051,0 +"5109",2015-02-15 03:55:59,20.1,33,0,552,0.00480386171918592,0 +"5110",2015-02-15 03:56:59,20.1,33,0,554,0.00480386171918592,0 +"5111",2015-02-15 03:58:00,20.1,33,0,554,0.00480386171918592,0 +"5112",2015-02-15 03:59:00,20.1,32.95,0,553,0.00479652701237058,0 +"5113",2015-02-15 04:00:00,20.1,32.9,0,552.5,0.00478919247721115,0 +"5114",2015-02-15 04:01:00,20.1,32.9,0,554,0.00478919247721115,0 +"5115",2015-02-15 04:01:59,20.1,32.9,0,554,0.00478919247721115,0 +"5116",2015-02-15 04:02:59,20.1,32.79,0,555,0.00477305710405953,0 +"5117",2015-02-15 04:04:00,20.1,32.845,0,559,0.00478112468679117,0 +"5118",2015-02-15 04:05:00,20.1,32.9,0,555,0.00478919247721115,0 +"5119",2015-02-15 04:06:00,20.1,32.9,0,552.5,0.00478919247721115,0 +"5120",2015-02-15 04:07:00,20.1,32.79,0,554,0.00477305710405953,0 +"5121",2015-02-15 04:08:00,20.1,32.7,0,553,0.00475985605301206,0 +"5122",2015-02-15 04:08:59,20.1,32.7,0,556,0.00475985605301206,0 +"5123",2015-02-15 04:09:59,20.1,32.7,0,559,0.00475985605301206,0 +"5124",2015-02-15 04:11:00,20.1,32.7,0,555,0.00475985605301206,0 +"5125",2015-02-15 04:12:00,20.1,32.7,0,557,0.00475985605301206,0 +"5126",2015-02-15 04:13:00,20.1,32.7,0,553.666666666667,0.00475985605301206,0 +"5127",2015-02-15 04:14:00,20.1,32.7,0,554,0.00475985605301206,0 +"5128",2015-02-15 04:14:59,20.1,32.7,0,557,0.00475985605301206,0 +"5129",2015-02-15 04:15:59,20.1,32.7,0,559.5,0.00475985605301206,0 +"5130",2015-02-15 04:17:00,20.1,32.7,0,561,0.00475985605301206,0 +"5131",2015-02-15 04:18:00,20.1,32.7,0,555,0.00475985605301206,0 +"5132",2015-02-15 04:19:00,20.1,32.7,0,552,0.00475985605301206,0 +"5133",2015-02-15 04:20:00,20.1,32.7,0,551.5,0.00475985605301206,0 +"5134",2015-02-15 04:21:00,20.1,32.59,0,558.5,0.00474372219021507,0 +"5135",2015-02-15 04:21:59,20.125,32.59,0,558.25,0.00475112375337379,0 +"5136",2015-02-15 04:23:00,20.1,32.59,0,560,0.00474372219021507,0 +"5137",2015-02-15 04:24:00,20.1,32.59,0,563,0.00474372219021507,0 +"5138",2015-02-15 04:25:00,20.1,32.59,0,559.5,0.00474372219021507,0 +"5139",2015-02-15 04:25:59,20.1,32.59,0,561,0.00474372219021507,0 +"5140",2015-02-15 04:27:00,20.15,32.59,0,564,0.00475853552060159,0 +"5141",2015-02-15 04:27:59,20.1,32.56,0,560,0.00473932218997312,0 +"5142",2015-02-15 04:28:59,20.1,32.59,0,556.5,0.00474372219021507,0 +"5143",2015-02-15 04:30:00,20.15,32.5,0,558.5,0.00474529417375883,0 +"5144",2015-02-15 04:31:00,20.1,32.59,0,557,0.00474372219021507,0 +"5145",2015-02-15 04:32:00,20.1,32.56,0,554.666666666667,0.00473932218997312,0 +"5146",2015-02-15 04:33:00,20.1,32.545,0,558,0.00473712221301943,0 +"5147",2015-02-15 04:34:00,20.1,32.5,0,558,0.00473052237482555,0 +"5148",2015-02-15 04:34:59,20.1,32.59,0,558.5,0.00474372219021507,0 +"5149",2015-02-15 04:36:00,20.1,32.5,0,557,0.00473052237482555,0 +"5150",2015-02-15 04:37:00,20.1,32.5,0,560,0.00473052237482555,0 +"5151",2015-02-15 04:38:00,20.1,32.45,0,568,0.00472318938429821,0 +"5152",2015-02-15 04:38:59,20.1,32.4,0,565,0.00471585656536653,0 +"5153",2015-02-15 04:40:00,20.1,32.5,0,566,0.00473052237482555,0 +"5154",2015-02-15 04:40:59,20.1,32.5,0,567,0.00473052237482555,0 +"5155",2015-02-15 04:41:59,20.1,32.4666666666667,0,566.666666666667,0.00472563369540751,0 +"5156",2015-02-15 04:43:00,20.1,32.4333333333333,0,565,0.00472074509225509,0 +"5157",2015-02-15 04:44:00,20.1,32.4,0,563,0.00471585656536653,0 +"5158",2015-02-15 04:45:00,20.1,32.4,0,564,0.00471585656536653,0 +"5159",2015-02-15 04:46:00,20.1,32.4,0,566,0.00471585656536653,0 +"5160",2015-02-15 04:46:59,20.1,32.29,0,559.5,0.00469972496770391,0 +"5161",2015-02-15 04:47:59,20.1,32.4,0,566,0.00471585656536653,0 +"5162",2015-02-15 04:49:00,20.1,32.29,0,565.5,0.00469972496770391,0 +"5163",2015-02-15 04:50:00,20.1,32.29,0,568.5,0.00469972496770391,0 +"5164",2015-02-15 04:51:00,20.1,32.29,0,564,0.00469972496770391,0 +"5165",2015-02-15 04:52:00,20.1,32.29,0,564.5,0.00469972496770391,0 +"5166",2015-02-15 04:53:00,20.2,32.29,0,568,0.00472911525603049,0 +"5167",2015-02-15 04:53:59,20.1,32.29,0,568,0.00469972496770391,0 +"5168",2015-02-15 04:54:59,20.1,32.29,0,568.5,0.00469972496770391,0 +"5169",2015-02-15 04:56:00,20.125,32.29,0,570.5,0.00470705736704224,0 +"5170",2015-02-15 04:57:00,20.1,32.29,0,568,0.00469972496770391,0 +"5171",2015-02-15 04:58:00,20.125,32.3175,0,567,0.00471109652781334,0 +"5172",2015-02-15 04:59:00,20.1,32.4,0,570,0.00471585656536653,0 +"5173",2015-02-15 04:59:59,20.1,32.29,0,570,0.00469972496770391,0 +"5174",2015-02-15 05:00:59,20.1,32.29,0,570,0.00469972496770391,0 +"5175",2015-02-15 05:02:00,20.1,32.29,0,565,0.00469972496770391,0 +"5176",2015-02-15 05:03:00,20.1,32.29,0,564,0.00469972496770391,0 +"5177",2015-02-15 05:04:00,20.1,32.26,0,567.666666666667,0.00469532558519552,0 +"5178",2015-02-15 05:05:00,20.1,32.145,0,570,0.00467846185776386,0 +"5179",2015-02-15 05:06:00,20.1,32.2,0,562,0.00468652700547604,0 +"5180",2015-02-15 05:06:59,20.1,32.2,0,566,0.00468652700547604,0 +"5181",2015-02-15 05:08:00,20.1,32.29,0,564.75,0.00469972496770391,0 +"5182",2015-02-15 05:09:00,20.1,32.29,0,569.5,0.00469972496770391,0 +"5183",2015-02-15 05:10:00,20.1333333333333,32.29,0,569,0.00470950374558275,0 +"5184",2015-02-15 05:10:59,20.1,32.2675,0,566.25,0.00469642542503199,0 +"5185",2015-02-15 05:12:00,20.1,32.2,0,565,0.00468652700547604,0 +"5186",2015-02-15 05:12:59,20.1,32.2,0,565,0.00468652700547604,0 +"5187",2015-02-15 05:13:59,20.1,32.2,0,568,0.00468652700547604,0 +"5188",2015-02-15 05:15:00,20.1,32.29,0,568,0.00469972496770391,0 +"5189",2015-02-15 05:16:00,20.1,32.245,0,566,0.00469312591710373,0 +"5190",2015-02-15 05:17:00,20.1,32.2,0,562,0.00468652700547604,0 +"5191",2015-02-15 05:18:00,20.1,32.2,0,563,0.00468652700547604,0 +"5192",2015-02-15 05:19:00,20.15,32.2,0,566.5,0.00470116039144233,0 +"5193",2015-02-15 05:19:59,20.1,32.2,0,569.666666666667,0.00468652700547604,0 +"5194",2015-02-15 05:21:00,20.1,32.2,0,569,0.00468652700547604,0 +"5195",2015-02-15 05:22:00,20.1333333333333,32.2,0,570,0.00469627811640117,0 +"5196",2015-02-15 05:23:00,20.1,32.2,0,566.5,0.00468652700547604,0 +"5197",2015-02-15 05:23:59,20.1,32.2,0,566,0.00468652700547604,0 +"5198",2015-02-15 05:25:00,20.1,32.2,0,566,0.00468652700547604,0 +"5199",2015-02-15 05:25:59,20.15,32.245,0,566.5,0.0047077800625428,0 +"5200",2015-02-15 05:26:59,20.1,32.2,0,572.333333333333,0.00468652700547604,0 +"5201",2015-02-15 05:28:00,20.1,32.26,0,568.666666666667,0.00469532558519552,0 +"5202",2015-02-15 05:29:00,20.1,32.29,0,568,0.00469972496770391,0 +"5203",2015-02-15 05:30:00,20.1,32.29,0,565,0.00469972496770391,0 +"5204",2015-02-15 05:31:00,20.1,32.245,0,567,0.00469312591710373,0 +"5205",2015-02-15 05:31:59,20.1,32.29,0,568.666666666667,0.00469972496770391,0 +"5206",2015-02-15 05:32:59,20.1,32.29,0,569,0.00469972496770391,0 +"5207",2015-02-15 05:34:00,20.1,32.29,0,568.5,0.00469972496770391,0 +"5208",2015-02-15 05:35:00,20.1,32.29,0,568,0.00469972496770391,0 +"5209",2015-02-15 05:36:00,20.1333333333333,32.29,0,569,0.00470950374558275,0 +"5210",2015-02-15 05:37:00,20.1,32.29,0,568,0.00469972496770391,0 +"5211",2015-02-15 05:38:00,20.1,32.29,0,569.5,0.00469972496770391,0 +"5212",2015-02-15 05:38:59,20.1,32.29,0,566.5,0.00469972496770391,0 +"5213",2015-02-15 05:39:59,20.1,32.29,0,568,0.00469972496770391,0 +"5214",2015-02-15 05:41:00,20.1,32.29,0,573,0.00469972496770391,0 +"5215",2015-02-15 05:42:00,20.1,32.29,0,568.5,0.00469972496770391,0 +"5216",2015-02-15 05:43:00,20.15,32.29,0,566.5,0.00471439987348827,0 +"5217",2015-02-15 05:44:00,20.1,32.29,0,568,0.00469972496770391,0 +"5218",2015-02-15 05:44:59,20.1,32.29,0,563.5,0.00469972496770391,0 +"5219",2015-02-15 05:45:59,20.1,32.3175,0,561.5,0.00470375778926427,0 +"5220",2015-02-15 05:47:00,20.1,32.4,0,568.333333333333,0.00471585656536653,0 +"5221",2015-02-15 05:48:00,20.1,32.4,0,571,0.00471585656536653,0 +"5222",2015-02-15 05:49:00,20.1,32.4,0,571,0.00471585656536653,0 +"5223",2015-02-15 05:50:00,20.1,32.4,0,569,0.00471585656536653,0 +"5224",2015-02-15 05:51:00,20.1,32.29,0,569,0.00469972496770391,0 +"5225",2015-02-15 05:51:59,20.15,32.29,0,569.333333333333,0.00471439987348827,0 +"5226",2015-02-15 05:53:00,20.1,32.29,0,568,0.00469972496770391,0 +"5227",2015-02-15 05:54:00,20.1,32.29,0,568.333333333333,0.00469972496770391,0 +"5228",2015-02-15 05:55:00,20.1,32.345,0,568,0.0047077906627275,0 +"5229",2015-02-15 05:55:59,20.1,32.29,0,569.5,0.00469972496770391,0 +"5230",2015-02-15 05:57:00,20.1,32.29,0,572.666666666667,0.00469972496770391,0 +"5231",2015-02-15 05:57:59,20.1,32.29,0,572,0.00469972496770391,0 +"5232",2015-02-15 05:58:59,20.1,32.29,0,570.5,0.00469972496770391,0 +"5233",2015-02-15 06:00:00,20.1,32.29,0,567.5,0.00469972496770391,0 +"5234",2015-02-15 06:01:00,20.1,32.29,0,570.666666666667,0.00469972496770391,0 +"5235",2015-02-15 06:02:00,20.1,32.29,0,572,0.00469972496770391,0 +"5236",2015-02-15 06:03:00,20.1,32.345,0,570.5,0.0047077906627275,0 +"5237",2015-02-15 06:04:00,20.1,32.29,0,574.5,0.00469972496770391,0 +"5238",2015-02-15 06:04:59,20.1,32.29,0,571,0.00469972496770391,0 +"5239",2015-02-15 06:06:00,20.1,32.29,0,572.333333333333,0.00469972496770391,0 +"5240",2015-02-15 06:07:00,20.05,32.245,0,570.5,0.00467851209375787,0 +"5241",2015-02-15 06:08:00,20.1,32.26,0,569.333333333333,0.00469532558519552,0 +"5242",2015-02-15 06:08:59,20.1,32.2,0,572,0.00468652700547604,0 +"5243",2015-02-15 06:10:00,20.1,32.2,0,573,0.00468652700547604,0 +"5244",2015-02-15 06:10:59,20.1,32.245,0,576,0.00469312591710373,0 +"5245",2015-02-15 06:11:59,20.05,32.2,0,577,0.00467193388352327,0 +"5246",2015-02-15 06:13:00,20.05,32.245,0,571.5,0.00467851209375787,0 +"5247",2015-02-15 06:14:00,20.1,32.245,0,572,0.00469312591710373,0 +"5248",2015-02-15 06:15:00,20.05,32.245,0,574.5,0.00467851209375787,0 +"5249",2015-02-15 06:16:00,20.0666666666667,32.23,0,575,0.00468118384379015,0 +"5250",2015-02-15 06:16:59,20,32.2,0,573,0.00465738092949067,0 +"5251",2015-02-15 06:17:59,20,32.2,0,573.5,0.00465738092949067,0 +"5252",2015-02-15 06:19:00,20,32.2,0,574,0.00465738092949067,0 +"5253",2015-02-15 06:20:00,20,32.2,0,579,0.00465738092949067,0 +"5254",2015-02-15 06:21:00,20.05,32.245,0,581,0.00467851209375787,0 +"5255",2015-02-15 06:22:00,20,32.2,0,579.5,0.00465738092949067,0 +"5256",2015-02-15 06:23:00,20,32.2,0,578,0.00465738092949067,0 +"5257",2015-02-15 06:23:59,20,32.2,0,571,0.00465738092949067,0 +"5258",2015-02-15 06:24:59,20,32.2,0,565.5,0.00465738092949067,0 +"5259",2015-02-15 06:26:00,20,32.2,0,571.5,0.00465738092949067,0 +"5260",2015-02-15 06:27:00,20,32.2,0,579,0.00465738092949067,0 +"5261",2015-02-15 06:28:00,20,32.2,0,576.5,0.00465738092949067,0 +"5262",2015-02-15 06:29:00,20,32.2,0,575,0.00465738092949067,0 +"5263",2015-02-15 06:29:59,20,32.2,0,578,0.00465738092949067,0 +"5264",2015-02-15 06:30:59,20,32.2,0,574,0.00465738092949067,0 +"5265",2015-02-15 06:32:00,20,32.2,0,577,0.00465738092949067,0 +"5266",2015-02-15 06:33:00,20,32.2,0,577,0.00465738092949067,0 +"5267",2015-02-15 06:34:00,20,32.2,0,580.5,0.00465738092949067,0 +"5268",2015-02-15 06:35:00,20,32.2,0,579.5,0.00465738092949067,0 +"5269",2015-02-15 06:36:00,20,32.2,0,580.5,0.00465738092949067,0 +"5270",2015-02-15 06:36:59,20,32.2,0,578,0.00465738092949067,0 +"5271",2015-02-15 06:38:00,20,32.2,0,581,0.00465738092949067,0 +"5272",2015-02-15 06:39:00,20,32.145,0,578,0.00464936631202509,0 +"5273",2015-02-15 06:40:00,20,32.1266666666667,0,579.333333333333,0.00464669481842647,0 +"5274",2015-02-15 06:40:59,20,32.145,0,577.5,0.00464936631202509,0 +"5275",2015-02-15 06:42:00,20,32.145,0,580.5,0.00464936631202509,0 +"5276",2015-02-15 06:42:59,20,32.09,0,575.5,0.00464135189956235,0 +"5277",2015-02-15 06:43:59,20,32.09,0,581.5,0.00464135189956235,0 +"5278",2015-02-15 06:45:00,20,32.09,0,579.5,0.00464135189956235,0 +"5279",2015-02-15 06:46:00,20,32.09,0,579.333333333333,0.00464135189956235,0 +"5280",2015-02-15 06:47:00,20,32.09,0,582,0.00464135189956235,0 +"5281",2015-02-15 06:48:00,20,32.09,0,576.5,0.00464135189956235,0 +"5282",2015-02-15 06:49:00,20,32,0,579,0.00462823784861715,0 +"5283",2015-02-15 06:49:59,19.945,32.09,0,579,0.00462544527047246,0 +"5284",2015-02-15 06:51:00,20,32.09,0,579,0.00464135189956235,0 +"5285",2015-02-15 06:52:00,20,32.09,0,580.5,0.00464135189956235,0 +"5286",2015-02-15 06:53:00,20,32.09,0,580.333333333333,0.00464135189956235,0 +"5287",2015-02-15 06:53:59,20,32.09,0,580,0.00464135189956235,0 +"5288",2015-02-15 06:55:00,20,32.045,0,577.5,0.00463479480547788,0 +"5289",2015-02-15 06:55:59,20,32,0,580,0.00462823784861715,0 +"5290",2015-02-15 06:56:59,20,32,0,580.5,0.00462823784861715,0 +"5291",2015-02-15 06:58:00,20,32,0,580,0.00462823784861715,0 +"5292",2015-02-15 06:59:00,20,32,0,588.25,0.00462823784861715,0 +"5293",2015-02-15 07:00:00,20,31.89,0,581,0.00461221030951458,0 +"5294",2015-02-15 07:01:00,20,32,0,584.5,0.00462823784861715,0 +"5295",2015-02-15 07:01:59,20,32,0,585,0.00462823784861715,0 +"5296",2015-02-15 07:02:59,20,31.945,0,583.5,0.00462022397657874,0 +"5297",2015-02-15 07:04:00,20,31.945,0,585.5,0.00462022397657874,0 +"5298",2015-02-15 07:05:00,20,31.945,0,587,0.00462022397657874,0 +"5299",2015-02-15 07:06:00,20,31.89,0,585,0.00461221030951458,0 +"5300",2015-02-15 07:07:00,20,31.945,0,584,0.00462022397657874,0 +"5301",2015-02-15 07:08:00,20,31.89,0,583,0.00461221030951458,0 +"5302",2015-02-15 07:08:59,20,31.89,0,576,0.00461221030951458,0 +"5303",2015-02-15 07:09:59,20,31.89,0,577,0.00461221030951458,0 +"5304",2015-02-15 07:11:00,20,31.79,0,580.5,0.00459764053087652,0 +"5305",2015-02-15 07:12:00,20,31.79,0,588.5,0.00459764053087652,0 +"5306",2015-02-15 07:13:00,20,31.79,0,586.5,0.00459764053087652,0 +"5307",2015-02-15 07:14:00,20,31.79,0,586,0.00459764053087652,0 +"5308",2015-02-15 07:14:59,20,31.76,0,591.333333333333,0.00459326972940513,0 +"5309",2015-02-15 07:15:59,20,31.79,0,590,0.00459764053087652,0 +"5310",2015-02-15 07:17:00,20,31.79,0,593.25,0.00459764053087652,0 +"5311",2015-02-15 07:18:00,20,31.79,0,590.5,0.00459764053087652,0 +"5312",2015-02-15 07:19:00,20,31.745,0,588,0.00459108435153558,0 +"5313",2015-02-15 07:20:00,20.0333333333333,31.73,0,590.333333333333,0.00459845286174549,0 +"5314",2015-02-15 07:21:00,20.1,31.79,0,592,0.00462640998898792,0 +"5315",2015-02-15 07:21:59,20,31.6333333333333,0,592,0.00457481590653238,0 +"5316",2015-02-15 07:23:00,20,31.6,0,583,0.00456995981801353,0 +"5317",2015-02-15 07:24:00,20,31.6,0,585,0.00456995981801353,0 +"5318",2015-02-15 07:25:00,20,31.6,0,587.5,0.00456995981801353,0 +"5319",2015-02-15 07:25:59,20,31.6,0,590,0.00456995981801353,0 +"5320",2015-02-15 07:27:00,20,31.6,0,583.5,0.00456995981801353,0 +"5321",2015-02-15 07:27:59,20,31.6,0,581.5,0.00456995981801353,0 +"5322",2015-02-15 07:28:59,20.0333333333333,31.5666666666667,0,584.666666666667,0.00457460777545624,0 +"5323",2015-02-15 07:30:00,20,31.5,0,592.5,0.00455539200407514,0 +"5324",2015-02-15 07:31:00,20,31.39,0,592,0.00453936819112712,0 +"5325",2015-02-15 07:32:00,20.05,31.55,0,592,0.00457693069327637,0 +"5326",2015-02-15 07:33:00,20.05,31.445,0,589.5,0.00456158672639182,0 +"5327",2015-02-15 07:34:00,20.1,31.5,0,589,0.00458389516059045,0 +"5328",2015-02-15 07:34:59,20,31.39,0,589,0.00453936819112712,0 +"5329",2015-02-15 07:36:00,20,31.39,0,590.5,0.00453936819112712,0 +"5330",2015-02-15 07:37:00,20.05,31.39,0,593.5,0.00455354971032052,0 +"5331",2015-02-15 07:38:00,20,31.34,0,595,0.0045320849107263,0 +"5332",2015-02-15 07:38:59,20.1,31.39,0,593,0.00456777035546951,0 +"5333",2015-02-15 07:40:00,20.1,31.3566666666667,0,587,0.00456288421473758,0 +"5334",2015-02-15 07:40:59,20.1,31.29,0,592.5,0.00455311216189065,0 +"5335",2015-02-15 07:41:59,20.1,31.29,0,595,0.00455311216189065,0 +"5336",2015-02-15 07:43:00,20.1,31.34,0,591.666666666667,0.00456044117294907,0 +"5337",2015-02-15 07:44:00,20.05,31.29,0,596.5,0.00453893748205606,0 +"5338",2015-02-15 07:45:00,20.1,31.29,0,600.5,0.00455311216189065,0 +"5339",2015-02-15 07:46:00,20.1,31.29,0,602.5,0.00455311216189065,0 +"5340",2015-02-15 07:46:59,20.1,31.29,0,593,0.00455311216189065,0 +"5341",2015-02-15 07:47:59,20.1,31.29,0,593.5,0.00455311216189065,0 +"5342",2015-02-15 07:49:00,20.1,31.2,0,600,0.00453992037405057,0 +"5343",2015-02-15 07:50:00,20.1,31.23,0,602.666666666667,0.00454431757494194,0 +"5344",2015-02-15 07:51:00,20.1,31.29,0,604,0.00455311216189065,0 +"5345",2015-02-15 07:52:00,20.1,31.2675,0,604,0.00454981416285224,0 +"5346",2015-02-15 07:53:00,20,31.2,0,607,0.00451169262641398,0 +"5347",2015-02-15 07:53:59,20,31.2,0,604,0.00451169262641398,0 +"5348",2015-02-15 07:54:59,20,31.2,0,602.5,0.00451169262641398,0 +"5349",2015-02-15 07:56:00,20,31.15,0,602,0.00450440998943091,0 +"5350",2015-02-15 07:57:00,20.05,31.195,0,599,0.00452505649648667,0 +"5351",2015-02-15 07:58:00,20.0333333333333,31.1333333333333,14,596.666666666667,0.00451135409527119,0 +"5352",2015-02-15 07:59:00,20.1,31.2,14,601.5,0.00453992037405057,0 +"5353",2015-02-15 07:59:59,20.1,31.2,14,603.5,0.00453992037405057,0 +"5354",2015-02-15 08:00:59,20.0666666666667,31.1333333333333,14,601.666666666667,0.00452074293815743,0 +"5355",2015-02-15 08:02:00,20.1,31.1333333333333,14,606,0.0045301490374861,0 +"5356",2015-02-15 08:03:00,20.0666666666667,31.1333333333333,14,604,0.00452074293815743,0 +"5357",2015-02-15 08:04:00,20.05,31.1,14,605.5,0.0045111761259708,0 +"5358",2015-02-15 08:05:00,20.1,31.1,7,606.5,0.00452526348349619,0 +"5359",2015-02-15 08:06:00,20.1,31.1,7,607,0.00452526348349619,0 +"5360",2015-02-15 08:06:59,20.1,31.1,7,607.25,0.00452526348349619,0 +"5361",2015-02-15 08:08:00,20.1,31.1,9.33333333333333,610,0.00452526348349619,0 +"5362",2015-02-15 08:09:00,20.1,31.0666666666667,11.3333333333333,607.666666666667,0.00452037800569879,0 +"5363",2015-02-15 08:10:00,20.1,31.1,6,601.5,0.00452526348349619,0 +"5364",2015-02-15 08:10:59,20.1,31,6,606,0.00451060727867438,0 +"5365",2015-02-15 08:12:00,20.1,30.945,6,606,0.00450254665829845,0 +"5366",2015-02-15 08:12:59,20.1,30.89,6,604.5,0.00449448624533407,0 +"5367",2015-02-15 08:13:59,20.05,30.84,6,604,0.00447319088829765,0 +"5368",2015-02-15 08:15:00,20.1,30.89,6,605,0.00449448624533407,0 +"5369",2015-02-15 08:16:00,20.1,30.89,6,606.5,0.00449448624533407,0 +"5370",2015-02-15 08:17:00,20.15,30.79,6,607.5,0.00449381484461673,0 +"5371",2015-02-15 08:18:00,20.1,30.79,24,608.5,0.00447983148039402,0 +"5372",2015-02-15 08:19:00,20.1,30.79,14,604.5,0.00447983148039402,0 +"5373",2015-02-15 08:19:59,20.1,30.79,17.3333333333333,604.666666666667,0.00447983148039402,0 +"5374",2015-02-15 08:21:00,20.1,30.79,10,605.666666666667,0.00447983148039402,0 +"5375",2015-02-15 08:22:00,20.125,30.79,13,606,0.00448681835092572,0 +"5376",2015-02-15 08:23:00,20.1,30.79,20,609,0.00447983148039402,0 +"5377",2015-02-15 08:23:59,20.125,30.79,14,611,0.00448681835092572,0 +"5378",2015-02-15 08:25:00,20.1,30.79,24.6666666666667,607,0.00447983148039402,0 +"5379",2015-02-15 08:25:59,20.15,30.745,23,608.5,0.00448719969278394,0 +"5380",2015-02-15 08:26:59,20.1,30.7,35,603,0.00446664277812316,0 +"5381",2015-02-15 08:28:00,20.175,30.625,35,603.333333333333,0.00447652801416604,0 +"5382",2015-02-15 08:29:00,20.2,30.6,31,600,0.00447981928533327,0 +"5383",2015-02-15 08:30:00,20.2,30.6,31,604,0.00447981928533327,0 +"5384",2015-02-15 08:31:00,20.2,30.6,32.6666666666667,613,0.00447981928533327,0 +"5385",2015-02-15 08:31:59,20.2,30.6,30,614,0.00447981928533327,0 +"5386",2015-02-15 08:32:59,20.2,30.6,24.6666666666667,611.333333333333,0.00447981928533327,0 +"5387",2015-02-15 08:34:00,20.2,30.6,15,610.5,0.00447981928533327,0 +"5388",2015-02-15 08:35:00,20.2,30.5,28,609,0.00446507425916187,0 +"5389",2015-02-15 08:36:00,20.2,30.5,19,613.333333333333,0.00446507425916187,0 +"5390",2015-02-15 08:37:00,20.2,30.525,19,611.25,0.00446876045063367,0 +"5391",2015-02-15 08:38:00,20.2,30.5,19,615,0.00446507425916187,0 +"5392",2015-02-15 08:38:59,20.2,30.5,32.5,613.5,0.00446507425916187,0 +"5393",2015-02-15 08:39:59,20.2,30.4725,37,608,0.0044610194986461,0 +"5394",2015-02-15 08:41:00,20.2,30.39,26,609,0.00444885553202324,0 +"5395",2015-02-15 08:42:00,20.2,30.39,34.3333333333333,609.25,0.00444885553202324,0 +"5396",2015-02-15 08:43:00,20.2225,30.4175,48.75,608.5,0.00445915500355248,0 +"5397",2015-02-15 08:44:00,20.2225,30.4175,45.75,609,0.00445915500355248,0 +"5398",2015-02-15 08:44:59,20.2675,30.39,71.5,609.25,0.00446759614428172,0 +"5399",2015-02-15 08:45:59,20.2675,30.365,89.25,608.25,0.00446389454947321,0 +"5400",2015-02-15 08:47:00,20.26,30.3566666666667,104,610.333333333333,0.00446057728740867,0 +"5401",2015-02-15 08:48:00,20.29,30.29,97,610.25,0.00445903147096821,0 +"5402",2015-02-15 08:49:00,20.3233333333333,30.29,82.6666666666667,608.666666666667,0.00446829225557467,0 +"5403",2015-02-15 08:50:00,20.365,30.2225,71.25,616.75,0.00446983712489773,0 +"5404",2015-02-15 08:51:00,20.39,30.2,98,617,0.00447343719239004,0 +"5405",2015-02-15 08:51:59,20.365,30.245,114,616,0.00447318875386015,0 +"5406",2015-02-15 08:53:00,20.39,30.2,122,612,0.00447343719239004,0 +"5407",2015-02-15 08:54:00,20.39,30.2,120,614.75,0.00447343719239004,0 +"5408",2015-02-15 08:55:00,20.4633333333333,30.2,129.333333333333,610,0.00449388388231126,0 +"5409",2015-02-15 08:55:59,20.4266666666667,30.1333333333333,124.666666666667,611,0.00447368137379797,0 +"5410",2015-02-15 08:57:00,20.5,30.1,124,610,0.00448911613609654,0 +"5411",2015-02-15 08:57:59,20.5,30,124,610.5,0.00447409485137549,0 +"5412",2015-02-15 08:58:59,20.55,29.89,130,617,0.00447144270595693,0 +"5413",2015-02-15 09:00:00,20.5333333333333,29.89,134.333333333333,615.333333333333,0.00446681499890624,0 +"5414",2015-02-15 09:01:00,20.6,29.89,134,617.5,0.00448535123797554,0 +"5415",2015-02-15 09:02:00,20.6,29.8233333333333,132.666666666667,620,0.0044752751295047,0 +"5416",2015-02-15 09:03:00,20.675,29.815,139.5,618,0.00449489677916754,0 +"5417",2015-02-15 09:04:00,20.675,29.815,143.25,621.25,0.00449489677916754,0 +"5418",2015-02-15 09:04:59,20.675,29.745,138.5,621.75,0.00448426752642077,0 +"5419",2015-02-15 09:06:00,20.7,29.7,139.666666666667,621.333333333333,0.00448438679422016,0 +"5420",2015-02-15 09:07:00,20.7675,29.7,122,614.25,0.00450320527948579,0 +"5421",2015-02-15 09:08:00,20.79,29.7,101.333333333333,613,0.00450949358377471,0 +"5422",2015-02-15 09:08:59,20.7675,29.7,121,616.25,0.00450320527948579,0 +"5423",2015-02-15 09:10:00,20.79,29.675,149.5,614.25,0.00450567021706902,0 +"5424",2015-02-15 09:10:59,20.79,29.6,153,614,0.00449420039693871,0 +"5425",2015-02-15 09:11:59,20.79,29.5333333333333,153,618,0.00448400535382895,0 +"5426",2015-02-15 09:13:00,20.79,29.445,141,609.5,0.00447049743279047,0 +"5427",2015-02-15 09:14:00,20.84,29.5225,124,616.5,0.00449626557670715,0 +"5428",2015-02-15 09:15:00,20.8233333333333,29.5333333333333,116,622,0.00449328249727103,0 +"5429",2015-02-15 09:16:00,20.84,29.55,104,619.5,0.00450048412032789,0 +"5430",2015-02-15 09:16:59,20.8233333333333,29.5333333333333,112.333333333333,622.666666666667,0.00449328249727103,0 +"5431",2015-02-15 09:17:59,20.84,29.55,124,619.5,0.00450048412032789,0 +"5432",2015-02-15 09:19:00,20.89,29.5,178.5,618.5,0.00450675831431613,0 +"5433",2015-02-15 09:20:00,20.89,29.5,201.5,624,0.00450675831431613,0 +"5434",2015-02-15 09:21:00,21,29.5,202,621.5,0.00453757019581831,0 +"5435",2015-02-15 09:22:00,20.9725,29.5,203,621,0.00452984984181646,0 +"5436",2015-02-15 09:23:00,21,29.4633333333333,205.666666666667,621,0.00453188918564554,0 +"5437",2015-02-15 09:23:59,21.02,29.35,210.75,623,0.00451992344578916,0 +"5438",2015-02-15 09:24:59,21.0666666666667,29.3566666666667,214.75,628.25,0.00453403494459128,0 +"5439",2015-02-15 09:26:00,21.1,29.34,231.25,627.5,0.00454079809963765,0 +"5440",2015-02-15 09:27:00,21.1,29.23,238.666666666667,621,0.00452365016369621,0 +"5441",2015-02-15 09:28:00,21.2,29.2,240.666666666667,620,0.00454700769080755,0 +"5442",2015-02-15 09:29:00,21.2225,29.15,239,621.5,0.00454548268659784,0 +"5443",2015-02-15 09:29:59,21.23,29.1333333333333,242.666666666667,631,0.00454497123211036,0 +"5444",2015-02-15 09:30:59,21.29,29.125,245.75,626.75,0.00456053929455131,0 +"5445",2015-02-15 09:32:00,21.29,29.1,256.75,623,0.00455659599110503,0 +"5446",2015-02-15 09:33:00,21.39,29,246.5,622,0.00456895259193333,0 +"5447",2015-02-15 09:34:00,21.3566666666667,28.9966666666667,232.333333333333,624.333333333333,0.00455903118199243,0 +"5448",2015-02-15 09:35:00,21.39,28.89,200.5,626.5,0.00455149526581013,0 +"5449",2015-02-15 09:36:00,21.39,28.89,212.5,625.5,0.00455149526581013,0 +"5450",2015-02-15 09:36:59,21.445,28.945,221.5,631,0.00457573050144449,0 +"5451",2015-02-15 09:38:00,21.39,28.89,207,635,0.00455149526581013,0 +"5452",2015-02-15 09:39:00,21.5,29,210,635.75,0.00460007239241809,0 +"5453",2015-02-15 09:40:00,21.4633333333333,28.9633333333333,239.333333333333,640,0.00458383259479218,0 +"5454",2015-02-15 09:40:59,21.5,29,246,640.5,0.00460007239241809,0 +"5455",2015-02-15 09:42:00,21.5,28.9175,236,637.25,0.00458688947486807,0 +"5456",2015-02-15 09:42:59,21.5333333333333,28.89,256,637.666666666667,0.00459192595893239,0 +"5457",2015-02-15 09:43:59,21.5,28.89,228.5,638,0.00458249529228513,0 +"5458",2015-02-15 09:45:00,21.56,28.89,217.4,631.75,0.00459948282178766,0 +"5459",2015-02-15 09:46:00,21.5666666666667,28.8566666666667,218.333333333333,634,0.00459602544920207,0 +"5460",2015-02-15 09:47:00,21.6,28.89,209.25,631,0.00461083869758847,0 +"5461",2015-02-15 09:48:00,21.6,28.89,204.333333333333,633.666666666667,0.00461083869758847,0 +"5462",2015-02-15 09:49:00,21.6,28.89,252.75,638,0.00461083869758847,0 +"5463",2015-02-15 09:49:59,21.6,28.89,290,644,0.00461083869758847,0 +"5464",2015-02-15 09:51:00,21.6,28.89,319.75,639.25,0.00461083869758847,0 +"5465",2015-02-15 09:52:00,21.6333333333333,28.8566666666667,340,637,0.00461495033602545,0 +"5466",2015-02-15 09:53:00,21.675,28.865,357,638,0.00462815937666557,0 +"5467",2015-02-15 09:53:59,21.7,28.815,392,640.5,0.0046272031566144,0 +"5468",2015-02-15 09:55:00,21.745,28.79,384,641.75,0.00463598826135457,0 +"5469",2015-02-15 09:55:59,21.79,28.7,360,639,0.00463420822058945,0 +"5470",2015-02-15 09:56:59,21.79,28.7,345,639.333333333333,0.00463420822058945,0 +"5471",2015-02-15 09:58:00,21.815,28.7,337,650,0.00464134407014696,0 +"5472",2015-02-15 09:59:00,21.89,28.79,312.5,651,0.00467754185095932,0 +"5473",2015-02-15 10:00:00,21.89,28.7,286,642.75,0.00466280983897591,0 +"5474",2015-02-15 10:01:00,21.89,28.7,260.5,644,0.00466280983897591,0 +"5475",2015-02-15 10:01:59,21.89,28.7,287.666666666667,643,0.00466280983897591,0 +"5476",2015-02-15 10:02:59,21.89,28.7,284,647.25,0.00466280983897591,0 +"5477",2015-02-15 10:04:00,21.89,28.7,221.333333333333,645.666666666667,0.00466280983897591,0 +"5478",2015-02-15 10:05:00,21.89,28.7,152.75,641.5,0.00466280983897591,0 +"5479",2015-02-15 10:06:00,21.89,28.7225,140.5,639.75,0.00466649277703602,0 +"5480",2015-02-15 10:07:00,21.89,28.79,146.666666666667,642,0.00467754185095932,0 +"5481",2015-02-15 10:08:00,21.89,28.79,133,645.666666666667,0.00467754185095932,0 +"5482",2015-02-15 10:08:59,21.84,28.815,148,644,0.0046672557327713,0 +"5483",2015-02-15 10:09:59,21.865,28.89,151.5,643.5,0.00468669844553575,0 +"5484",2015-02-15 10:11:00,21.8233333333333,28.8233333333333,162.333333333333,645.666666666667,0.00466383008224698,0 +"5485",2015-02-15 10:12:00,21.89,29,148.5,647,0.0047119192394134,0 +"5486",2015-02-15 10:13:00,21.79,28.89,158.25,645.5,0.00466511774934596,0 +"5487",2015-02-15 10:14:00,21.79,28.9175,148.5,640.75,0.00466959174954378,0 +"5488",2015-02-15 10:14:59,21.79,28.89,139,639,0.00466511774934596,0 +"5489",2015-02-15 10:15:59,21.79,28.9725,139,636.5,0.00467853994159167,0 +"5490",2015-02-15 10:17:00,21.89,29,136.5,646.5,0.0047119192394134,0 +"5491",2015-02-15 10:18:00,21.79,29,160,651,0.00468301413344449,0 +"5492",2015-02-15 10:19:00,21.79,29,188,647.25,0.00468301413344449,0 +"5493",2015-02-15 10:20:00,21.84,28.9725,217,642,0.0046929589781733,0 +"5494",2015-02-15 10:21:00,21.8233333333333,28.9633333333333,245,639,0.00468665381176825,0 +"5495",2015-02-15 10:21:59,21.89,29,257,638,0.0047119192394134,0 +"5496",2015-02-15 10:23:00,21.89,29,289,639,0.0047119192394134,0 +"5497",2015-02-15 10:24:00,21.89,28.89,295.5,640.25,0.00469391156556352,0 +"5498",2015-02-15 10:25:00,21.9633333333333,28.89,347,634.333333333333,0.00471512660858726,0 +"5499",2015-02-15 10:25:59,22,28.815,345.666666666667,637,0.00471340452038018,0 +"5500",2015-02-15 10:27:00,22.075,28.84,357.8,642.75,0.00473931461263572,0 +"5501",2015-02-15 10:27:59,22.1,28.79,260.333333333333,646.75,0.00473830568222405,0 +"5502",2015-02-15 10:28:59,22.1,28.745,209.25,641.5,0.00473084317770382,0 +"5503",2015-02-15 10:30:00,22.1,28.79,176.666666666667,638,0.00473830568222405,0 +"5504",2015-02-15 10:31:00,22.1,28.84,163,637.5,0.00474659756234427,0 +"5505",2015-02-15 10:32:00,22.05,28.84,192,642.5,0.0047320415272287,0 +"5506",2015-02-15 10:33:00,22,28.79,179,641.5,0.00470928419187771,0 +"5507",2015-02-15 10:34:00,22.025,28.815,195.25,640,0.00472065152889471,0 +"5508",2015-02-15 10:34:59,22,28.865,180,639.5,0.00472164533992298,0 +"5509",2015-02-15 10:36:00,22,28.89,169.333333333333,636.666666666667,0.00472576583096545,0 +"5510",2015-02-15 10:37:00,22,28.89,205.25,636.25,0.00472576583096545,0 +"5511",2015-02-15 10:38:00,22,28.89,224,633.666666666667,0.00472576583096545,0 +"5512",2015-02-15 10:38:59,22,28.945,232.75,637.25,0.00473483110198148,0 +"5513",2015-02-15 10:40:00,22,29,219.333333333333,640,0.00474389663525043,0 +"5514",2015-02-15 10:40:59,22,28.945,191,636.75,0.00473483110198148,0 +"5515",2015-02-15 10:41:59,22,29,143,641.25,0.00474389663525043,0 +"5516",2015-02-15 10:43:00,22,29,138,643,0.00474389663525043,0 +"5517",2015-02-15 10:44:00,21.9175,29.025,116,637.75,0.00472399547747708,0 +"5518",2015-02-15 10:45:00,21.89,29.05,116,637.5,0.00472010488782217,0 +"5519",2015-02-15 10:46:00,21.89,29.1,98.6666666666667,635.666666666667,0.00472829075006353,0 +"5520",2015-02-15 10:46:59,21.89,29.15,113,635.666666666667,0.00473647682614585,0 +"5521",2015-02-15 10:47:59,21.89,29.2,107.6,634,0.00474466311607751,0 +"5522",2015-02-15 10:49:00,21.89,29.2,97.6666666666667,631.25,0.00474466311607751,0 +"5523",2015-02-15 10:50:00,21.815,29.2225,78.75,630.5,0.00472648449747438,0 +"5524",2015-02-15 10:51:00,21.79,29.2675,77.25,630.75,0.0047265391512887,0 +"5525",2015-02-15 10:52:00,21.79,29.29,87,632.666666666667,0.00473020040975277,0 +"5526",2015-02-15 10:53:00,21.73,29.29,85.6666666666667,631.666666666667,0.0047127572717759,0 +"5527",2015-02-15 10:53:59,21.7,29.365,89.5,636.25,0.00471619355785029,0 +"5528",2015-02-15 10:54:59,21.7,29.4266666666667,82,638.666666666667,0.00472617284538679,0 +"5529",2015-02-15 10:56:00,21.7,29.5,97.6666666666667,640.333333333333,0.00473804051992681,0 +"5530",2015-02-15 10:57:00,21.7,29.5,94,637.5,0.00473804051992681,0 +"5531",2015-02-15 10:58:00,21.6666666666667,29.5,109,634.333333333333,0.0047283199564659,0 +"5532",2015-02-15 10:59:00,21.7,29.525,131.5,633.25,0.00474208642079472,0 +"5533",2015-02-15 10:59:59,21.6,29.5,145,635.5,0.00470893163100116,0 +"5534",2015-02-15 11:00:59,21.625,29.525,178.25,630.5,0.00472022111776565,0 +"5535",2015-02-15 11:02:00,21.7,29.5,246,628.5,0.00473804051992681,0 +"5536",2015-02-15 11:03:00,21.7,29.5,267,629.333333333333,0.00473804051992681,0 +"5537",2015-02-15 11:04:00,21.7,29.5,288,623,0.00473804051992681,0 +"5538",2015-02-15 11:05:00,21.7,29.5,342,627,0.00473804051992681,0 +"5539",2015-02-15 11:06:00,21.79,29.365,415.5,632.5,0.00474240491358571,0 +"5540",2015-02-15 11:06:59,21.8566666666667,29.29,327,631,0.00474964849308119,0 +"5541",2015-02-15 11:08:00,21.89,29.2675,245,632.25,0.00475571494671863,0 +"5542",2015-02-15 11:09:00,21.89,29.2,278,634.666666666667,0.00474466311607751,0 +"5543",2015-02-15 11:10:00,21.9175,29.2,244.5,634.75,0.00475269542608944,0 +"5544",2015-02-15 11:10:59,21.9175,29.2,234.5,639,0.00475269542608944,0 +"5545",2015-02-15 11:12:00,21.9633333333333,29.2,268,628,0.00476610928505314,0 +"5546",2015-02-15 11:12:59,21.9725,29.175,314.666666666667,630.333333333333,0.00476468191414742,0 +"5547",2015-02-15 11:13:59,22,29.1666666666667,370.75,636.5,0.00477136954975572,0 +"5548",2015-02-15 11:15:00,22.025,29.1,270.75,634.5,0.00476769987934292,0 +"5549",2015-02-15 11:16:00,22.1,29.15,293.5,636.5,0.00479801211664778,0 +"5550",2015-02-15 11:17:00,22.075,29.1,210,634.5,0.00478236925822485,0 +"5551",2015-02-15 11:18:00,22.1,29.1,329,628,0.00478971887604794,0 +"5552",2015-02-15 11:19:00,22.1,29.1333333333333,385,626.333333333333,0.00479524767873009,0 +"5553",2015-02-15 11:19:59,22.125,29.1,390.5,632,0.00479707846171033,0 +"5554",2015-02-15 11:21:00,22.175,28.9975,351.75,624.5,0.00479474805406622,0 +"5555",2015-02-15 11:22:00,22.2,28.9266666666667,419,628.333333333333,0.00479029053746571,0 +"5556",2015-02-15 11:23:00,22.2675,28.89,420.5,629,0.00480402708891409,0 +"5557",2015-02-15 11:23:59,22.29,28.89,415.5,630,0.00481066166450848,0 +"5558",2015-02-15 11:25:00,22.315,28.79,372.75,625.5,0.00480123696735858,0 +"5559",2015-02-15 11:25:59,22.3566666666667,28.73,307.666666666667,630,0.00480340880447041,0 +"5560",2015-02-15 11:26:59,22.39,28.7,289,631.25,0.00480816783272686,0 +"5561",2015-02-15 11:28:00,22.39,28.7,315.666666666667,632.666666666667,0.00480816783272686,0 +"5562",2015-02-15 11:29:00,22.39,28.7,347.5,631.75,0.00480816783272686,0 +"5563",2015-02-15 11:30:00,22.39,28.7,332,626.25,0.00480816783272686,0 +"5564",2015-02-15 11:31:00,22.5,28.7,353.5,626.5,0.00484067805248605,0 +"5565",2015-02-15 11:31:59,22.4725,28.7,328.25,631.5,0.00483253236421013,0 +"5566",2015-02-15 11:32:59,22.5,28.7,330.75,631,0.00484067805248605,0 +"5567",2015-02-15 11:34:00,22.5,28.6666666666667,350,629.333333333333,0.00483501219157123,0 +"5568",2015-02-15 11:35:00,22.5,28.6,323,633.5,0.00482368077701009,0 +"5569",2015-02-15 11:36:00,22.5333333333333,28.6,340,636.666666666667,0.00483353558789282,0 +"5570",2015-02-15 11:37:00,22.575,28.6,356.75,637.25,0.00484587908422266,0 +"5571",2015-02-15 11:38:00,22.6,28.6,359.333333333333,628,0.00485329852692608,0 +"5572",2015-02-15 11:38:59,22.6,28.5,355,628.25,0.00483619700919864,0 +"5573",2015-02-15 11:39:59,22.625,28.525,300.25,631.5,0.00484788198051153,0 +"5574",2015-02-15 11:41:00,22.7,28.6,303.5,626,0.0048830766448609,0 +"5575",2015-02-15 11:42:00,22.6333333333333,28.5333333333333,247.333333333333,624,0.00485178213909679,0 +"5576",2015-02-15 11:43:00,22.65,28.55,185.75,626.5,0.00485959021724992,0 +"5577",2015-02-15 11:44:00,22.6,28.5,208,629.5,0.00483619700919864,0 +"5578",2015-02-15 11:44:59,22.6,28.5,197,626.333333333333,0.00483619700919864,0 +"5579",2015-02-15 11:45:59,22.6,28.6,214,626,0.00485329852692608,0 +"5580",2015-02-15 11:47:00,22.6,28.6,205,632,0.00485329852692608,0 +"5581",2015-02-15 11:48:00,22.6,28.7,242.5,633,0.0048704009778156,0 +"5582",2015-02-15 11:49:00,22.6,28.7,274.5,628,0.0048704009778156,0 +"5583",2015-02-15 11:50:00,22.6,28.7,257.5,626,0.0048704009778156,0 +"5584",2015-02-15 11:51:00,22.6,28.65,239.25,627.25,0.00486184963572081,0 +"5585",2015-02-15 11:51:59,22.6,28.7,222.666666666667,629.333333333333,0.0048704009778156,0 +"5586",2015-02-15 11:53:00,22.6,28.6666666666667,234,630,0.00486470005716304,0 +"5587",2015-02-15 11:54:00,22.6,28.7,214.25,630,0.0048704009778156,0 +"5588",2015-02-15 11:55:00,22.6,28.7,217,626.333333333333,0.0048704009778156,0 +"5589",2015-02-15 11:55:59,22.6,28.7,181.5,624.4,0.0048704009778156,0 +"5590",2015-02-15 11:57:00,22.6,28.7,170,630.5,0.0048704009778156,0 +"5591",2015-02-15 11:57:59,22.6,28.7,199,632.333333333333,0.0048704009778156,0 +"5592",2015-02-15 11:58:59,22.575,28.745,229.5,630.75,0.00487063973684526,0 +"5593",2015-02-15 12:00:00,22.6,28.7675,237.5,630,0.00488194565973272,0 +"5594",2015-02-15 12:01:00,22.5666666666667,28.7,237.666666666667,630,0.0048604754901345,0 +"5595",2015-02-15 12:02:00,22.6,28.7,211.5,630.75,0.0048704009778156,0 +"5596",2015-02-15 12:03:00,22.6,28.7225,183.5,626,0.00487424915787495,0 +"5597",2015-02-15 12:04:00,22.575,28.7225,195,629.25,0.00486679743839439,0 +"5598",2015-02-15 12:04:59,22.6,28.79,223.5,632.5,0.00488579398153289,0 +"5599",2015-02-15 12:06:00,22.6,28.79,233,631,0.00488579398153289,0 +"5600",2015-02-15 12:07:00,22.6,28.79,243,632,0.00488579398153289,0 +"5601",2015-02-15 12:08:00,22.6,28.7675,263.5,628,0.00488194565973272,0 +"5602",2015-02-15 12:08:59,22.6,28.79,285,630,0.00488579398153289,0 +"5603",2015-02-15 12:10:00,22.6,28.7,311.5,630.75,0.0048704009778156,0 +"5604",2015-02-15 12:10:59,22.6,28.7,309.333333333333,632,0.0048704009778156,0 +"5605",2015-02-15 12:11:59,22.675,28.7675,316.75,635.5,0.00490439694084286,0 +"5606",2015-02-15 12:13:00,22.6666666666667,28.73,337,634.666666666667,0.00489545768050048,0 +"5607",2015-02-15 12:14:00,22.7,28.7,326.5,635.25,0.004900284850624,0 +"5608",2015-02-15 12:15:00,22.7225,28.7,325,636.5,0.00490703097958978,0 +"5609",2015-02-15 12:16:00,22.7225,28.675,271,638,0.00490272287058668,0 +"5610",2015-02-15 12:16:59,22.7675,28.6,242.5,627,0.00490326791104326,0 +"5611",2015-02-15 12:17:59,22.79,28.7,264.5,632.666666666667,0.00492731856938336,0 +"5612",2015-02-15 12:19:00,22.76,28.7,300.333333333333,637,0.00491829274264654,0 +"5613",2015-02-15 12:20:00,22.7675,28.65,274,639,0.00491190775162162,0 +"5614",2015-02-15 12:21:00,22.76,28.6333333333333,294.666666666667,637,0.00490677801156435,0 +"5615",2015-02-15 12:22:00,22.79,28.6,319,632.5,0.00491001468645711,0 +"5616",2015-02-15 12:23:00,22.79,28.6,284,628,0.00491001468645711,0 +"5617",2015-02-15 12:23:59,22.8233333333333,28.6333333333333,286,628,0.00492580467443597,0 +"5618",2015-02-15 12:24:59,22.84,28.65,289.25,633.5,0.00493371535968374,0 +"5619",2015-02-15 12:26:00,22.8233333333333,28.6,310,635.333333333333,0.0049200249679997,0 +"5620",2015-02-15 12:27:00,22.89,28.6,310,632.5,0.00494009957565735,0 +"5621",2015-02-15 12:28:00,22.89,28.6,302.5,632,0.00494009957565735,0 +"5622",2015-02-15 12:29:00,22.89,28.6,313.333333333333,630.333333333333,0.00494009957565735,0 +"5623",2015-02-15 12:29:59,22.89,28.575,335,631,0.004935747040105,0 +"5624",2015-02-15 12:30:59,22.945,28.575,324.5,634.75,0.00495234821431599,0 +"5625",2015-02-15 12:32:00,23,28.5,322,637,0.00495585273839422,0 +"5626",2015-02-15 12:33:00,23,28.5,274.25,633.75,0.00495585273839422,0 +"5627",2015-02-15 12:34:00,23,28.5,283.666666666667,632,0.00495585273839422,0 +"5628",2015-02-15 12:35:00,23,28.5,304.5,632.5,0.00495585273839422,0 +"5629",2015-02-15 12:36:00,23,28.5,266,632.666666666667,0.00495585273839422,0 +"5630",2015-02-15 12:36:59,23.02,28.52,269.25,631,0.00496541333328369,0 +"5631",2015-02-15 12:38:00,23,28.5,316.25,632.25,0.00495585273839422,0 +"5632",2015-02-15 12:39:00,23,28.5,327.25,634.75,0.00495585273839422,0 +"5633",2015-02-15 12:40:00,23.0333333333333,28.5666666666667,341.333333333333,633,0.00497765015656018,0 +"5634",2015-02-15 12:40:59,23.1,28.55,357.75,630,0.00499498969970884,0 +"5635",2015-02-15 12:42:00,23.1,28.5,329,627,0.00498617178149149,0 +"5636",2015-02-15 12:42:59,23.1,28.5,333.25,629,0.00498617178149149,0 +"5637",2015-02-15 12:43:59,23.1333333333333,28.5,336.333333333333,630.666666666667,0.00499631443836367,0 +"5638",2015-02-15 12:45:00,23.175,28.5,316.5,629.75,0.00500901835879713,0 +"5639",2015-02-15 12:46:00,23.2,28.5,345,627,0.00501665438525009,0 +"5640",2015-02-15 12:47:00,23.2,28.39,273,630.5,0.00499713630138535,0 +"5641",2015-02-15 12:48:00,23.2,28.39,366.5,629.75,0.00499713630138535,0 +"5642",2015-02-15 12:49:00,23.2,28.39,303,631.666666666667,0.00499713630138535,0 +"5643",2015-02-15 12:49:59,23.245,28.445,243.5,633.5,0.00502063892456017,0 +"5644",2015-02-15 12:51:00,23.29,28.5,150,633.5,0.00504422920396206,0 +"5645",2015-02-15 12:52:00,23.2,28.4725,156.25,633,0.00501177475036214,0 +"5646",2015-02-15 12:53:00,23.1666666666667,28.5,140,627.666666666667,0.00500647529685735,0 +"5647",2015-02-15 12:53:59,23.125,28.525,132.75,633,0.00499819277539285,0 +"5648",2015-02-15 12:55:00,23.1,28.6,137.25,633.25,0.00500380786595964,0 +"5649",2015-02-15 12:55:59,23.1,28.65,144,635,0.00501262628025438,0 +"5650",2015-02-15 12:56:59,23.0666666666667,28.6666666666667,180.333333333333,632.666666666667,0.00500538116190697,0 +"5651",2015-02-15 12:58:00,23,28.65,173.5,630.25,0.00498214509903657,0 +"5652",2015-02-15 12:59:00,23,28.7,171.5,630.25,0.00499090970930674,0 +"5653",2015-02-15 13:00:00,23,28.7225,196.5,635.5,0.00499485386387368,0 +"5654",2015-02-15 13:01:00,22.9725,28.79,173.666666666667,635.666666666667,0.00499829155208688,0 +"5655",2015-02-15 13:01:59,22.9725,28.79,134.8,632.75,0.00499829155208688,0 +"5656",2015-02-15 13:02:59,22.89,28.79,103.5,637,0.00497318082098931,0 +"5657",2015-02-15 13:04:00,22.89,28.865,97,640,0.00498624016835599,0 +"5658",2015-02-15 13:05:00,22.89,29,97,640.5,0.00500974836462659,0 +"5659",2015-02-15 13:06:00,22.89,29,106,641.75,0.00500974836462659,0 +"5660",2015-02-15 13:07:00,22.8566666666667,29.0333333333333,94,642,0.00500535213884248,0 +"5661",2015-02-15 13:08:00,22.79,29,94,644.25,0.00497923595006916,0 +"5662",2015-02-15 13:08:59,22.79,29.05,94,641,0.00498788968285707,0 +"5663",2015-02-15 13:09:59,22.79,29.1,92.25,645,0.00499654365453048,0 +"5664",2015-02-15 13:11:00,22.76,29.1666666666667,93,639.333333333333,0.00499890770558842,0 +"5665",2015-02-15 13:12:00,22.73,29.2,87,636,0.00499549596350345,0 +"5666",2015-02-15 13:13:00,22.7,29.2,78.5,636,0.00498634005256076,0 +"5667",2015-02-15 13:14:00,22.7,29.29,70,636,0.00500183249802707,0 +"5668",2015-02-15 13:14:59,22.675,29.2675,78.5,643.75,0.00499032281292189,0 +"5669",2015-02-15 13:15:59,22.625,29.2675,87,649,0.00497508069986113,0 +"5670",2015-02-15 13:17:00,22.6,29.29,105,645,0.00497132443667279,0 +"5671",2015-02-15 13:18:00,22.6,29.365,92.25,641.75,0.00498415601797785,0 +"5672",2015-02-15 13:19:00,22.6,29.39,102,647,0.00498843332846294,0 +"5673",2015-02-15 13:20:00,22.6,29.39,95.6,646,0.00498843332846294,0 +"5674",2015-02-15 13:21:00,22.575,29.4175,97.75,644,0.00498550351528107,0 +"5675",2015-02-15 13:21:59,22.525,29.5,95.3333333333333,649.666666666667,0.0049843151520674,0 +"5676",2015-02-15 13:23:00,22.5,29.525,87.6,652.5,0.0049809407559926,0 +"5677",2015-02-15 13:24:00,22.5,29.6,94,642,0.00499369502351873,0 +"5678",2015-02-15 13:25:00,22.5,29.6,94,643,0.00499369502351873,0 +"5679",2015-02-15 13:25:59,22.5,29.625,95.5,654.5,0.00499794656134013,0 +"5680",2015-02-15 13:27:00,22.4725,29.675,100,653.75,0.00499802294378469,0 +"5681",2015-02-15 13:27:59,22.445,29.65,107,653.5,0.00498537136472974,0 +"5682",2015-02-15 13:28:59,22.4175,29.65,118,656.5,0.00497697672279156,0 +"5683",2015-02-15 13:30:00,22.4266666666667,29.73,131,652,0.00499331756369339,0 +"5684",2015-02-15 13:31:00,22.39,29.7,131.5,658.75,0.00497704034901491,0 +"5685",2015-02-15 13:32:00,22.39,29.7,107.5,656.75,0.00497704034901491,0 +"5686",2015-02-15 13:33:00,22.39,29.7,92,655,0.00497704034901491,0 +"5687",2015-02-15 13:34:00,22.39,29.7,95.5,652.5,0.00497704034901491,0 +"5688",2015-02-15 13:34:59,22.39,29.79,106.5,655.5,0.00499224333885032,0 +"5689",2015-02-15 13:36:00,22.39,29.79,90.5,656,0.00499224333885032,0 +"5690",2015-02-15 13:37:00,22.39,29.79,92.25,659.5,0.00499224333885032,0 +"5691",2015-02-15 13:38:00,22.39,29.79,91.3333333333333,656.666666666667,0.00499224333885032,0 +"5692",2015-02-15 13:38:59,22.34,29.89,78.5,656.75,0.00499380296381987,0 +"5693",2015-02-15 13:40:00,22.29,29.89,84.5,658,0.00497851096800831,0 +"5694",2015-02-15 13:40:59,22.31,29.956,81,659.5,0.00499571772652335,0 +"5695",2015-02-15 13:41:59,22.29,30,81,659.75,0.00499697987960895,0 +"5696",2015-02-15 13:43:00,22.29,30,81,659.5,0.00499697987960895,0 +"5697",2015-02-15 13:44:00,22.29,30,75.5,661.5,0.00499697987960895,0 +"5698",2015-02-15 13:45:00,22.29,30.1,87.5,662,0.00501377074347092,0 +"5699",2015-02-15 13:46:00,22.29,30.1,109.5,660,0.00501377074347092,0 +"5700",2015-02-15 13:46:59,22.29,30.1,77.25,654,0.00501377074347092,0 +"5701",2015-02-15 13:47:59,22.26,30.0666666666667,75.6666666666667,655,0.00499896336554179,0 +"5702",2015-02-15 13:49:00,22.2,30,79.5,658.5,0.00496945591117598,0 +"5703",2015-02-15 13:50:00,22.2,30,63,658.666666666667,0.00496945591117598,0 +"5704",2015-02-15 13:51:00,22.2,30,66.75,656.75,0.00496945591117598,0 +"5705",2015-02-15 13:52:00,22.2,30,69.75,661,0.00496945591117598,0 +"5706",2015-02-15 13:53:00,22.2,30,57,663,0.00496945591117598,0 +"5707",2015-02-15 13:53:59,22.2,30,57,661.75,0.00496945591117598,0 +"5708",2015-02-15 13:54:59,22.2,30,57,656,0.00496945591117598,0 +"5709",2015-02-15 13:56:00,22.2,30.075,57,655.5,0.00498197905949607,0 +"5710",2015-02-15 13:57:00,22.15,30.1,57,653,0.00497086878212499,0 +"5711",2015-02-15 13:58:00,22.15,30.125,74,654.25,0.00497503043327437,0 +"5712",2015-02-15 13:59:00,22.1,30.2,74,660,0.00497222087874464,0 +"5713",2015-02-15 13:59:59,22.1,30.2,74,661.666666666667,0.00497222087874464,0 +"5714",2015-02-15 14:00:59,22.1,30.29,72.6666666666667,662.666666666667,0.00498715756435606,0 +"5715",2015-02-15 14:02:00,22.1,30.29,67.5,661.5,0.00498715756435606,0 +"5716",2015-02-15 14:03:00,22.1,30.29,81,659.333333333333,0.00498715756435606,0 +"5717",2015-02-15 14:04:00,22.1,30.29,85.75,658,0.00498715756435606,0 +"5718",2015-02-15 14:05:00,22.1,30.29,87,660.666666666667,0.00498715756435606,0 +"5719",2015-02-15 14:06:00,22.1,30.34,91.75,660.75,0.00499545603055302,0 +"5720",2015-02-15 14:06:59,22.1,30.34,77.25,662.5,0.00499545603055302,0 +"5721",2015-02-15 14:08:00,22.05,30.34,99,662,0.00498013077578083,0 +"5722",2015-02-15 14:09:00,22.075,30.365,81,665.5,0.00499193110144288,0 +"5723",2015-02-15 14:10:00,22.0333333333333,30.3233333333333,83.3333333333333,663.666666666667,0.00497227681111104,0 +"5724",2015-02-15 14:10:59,22.05,30.34,77.25,662,0.00498013077578083,0 +"5725",2015-02-15 14:12:00,22,30.29,87,659.666666666667,0.00495659983531057,0 +"5726",2015-02-15 14:12:59,22.05,30.365,87,661.5,0.00498426726063167,0 +"5727",2015-02-15 14:13:59,22,30.34,96,658.25,0.00496484705181481,0 +"5728",2015-02-15 14:15:00,22,30.34,87,666,0.00496484705181481,0 +"5729",2015-02-15 14:16:00,22.0333333333333,30.39,87,667,0.00498329607757372,0 +"5730",2015-02-15 14:17:00,22,30.39,87,668.75,0.00497309448529571,0 +"5731",2015-02-15 14:18:00,22,30.39,87,667,0.00497309448529571,0 +"5732",2015-02-15 14:19:00,22,30.39,89.3333333333333,670.333333333333,0.00497309448529571,0 +"5733",2015-02-15 14:19:59,22,30.39,101.25,664.75,0.00497309448529571,0 +"5734",2015-02-15 14:21:00,22,30.39,110,663.666666666667,0.00497309448529571,0 +"5735",2015-02-15 14:22:00,22,30.4175,97.75,665,0.00497763066619961,0 +"5736",2015-02-15 14:23:00,22,30.4725,94,668,0.00498670322492719,0 +"5737",2015-02-15 14:23:59,22,30.5,91.4,666.25,0.00499123960275373,0 +"5738",2015-02-15 14:25:00,22,30.4633333333333,121.333333333333,675,0.00498519111357226,0 +"5739",2015-02-15 14:25:59,22,30.4725,131.25,678,0.00498670322492719,0 +"5740",2015-02-15 14:26:59,22,30.39,129.5,683,0.00497309448529571,0 +"5741",2015-02-15 14:28:00,22.025,30.445,103,680.5,0.00498983044203751,0 +"5742",2015-02-15 14:29:00,22,30.4266666666667,89.3333333333333,686.666666666667,0.00497914274108738,0 +"5743",2015-02-15 14:30:00,22,30.5,79.75,692,0.00499123960275373,0 +"5744",2015-02-15 14:31:00,22,30.5,81,690.666666666667,0.00499123960275373,0 +"5745",2015-02-15 14:31:59,22,30.5,75.25,682.25,0.00499123960275373,0 +"5746",2015-02-15 14:32:59,22,30.5,74,683.5,0.00499123960275373,0 +"5747",2015-02-15 14:34:00,22,30.5,80,688,0.00499123960275373,0 +"5748",2015-02-15 14:35:00,22,30.5,65.5,682.5,0.00499123960275373,0 +"5749",2015-02-15 14:36:00,21.9725,30.5,75.5,676.75,0.00498280627566165,0 +"5750",2015-02-15 14:37:00,21.9633333333333,30.5,59.6666666666667,670.333333333333,0.00497999796423606,0 +"5751",2015-02-15 14:38:00,21.9175,30.6,62,677.25,0.00498238967739553,0 +"5752",2015-02-15 14:38:59,21.89,30.6,62,674,0.00497396609103204,0 +"5753",2015-02-15 14:39:59,21.89,30.6,59,678.75,0.00497396609103204,0 +"5754",2015-02-15 14:41:00,21.89,30.6,65.6666666666667,678,0.00497396609103204,0 +"5755",2015-02-15 14:42:00,21.89,30.7,62,674,0.00499035129555229,0 +"5756",2015-02-15 14:43:00,21.89,30.6666666666667,64,680.666666666667,0.00498488946555583,0 +"5757",2015-02-15 14:44:00,21.89,30.7,45.5,681.25,0.00499035129555229,0 +"5758",2015-02-15 14:44:59,21.89,30.7,44,685.5,0.00499035129555229,0 +"5759",2015-02-15 14:45:59,21.89,30.7,42.25,685.25,0.00499035129555229,0 +"5760",2015-02-15 14:47:00,21.89,30.7,51.3333333333333,682.666666666667,0.00499035129555229,0 +"5761",2015-02-15 14:48:00,21.89,30.7,45.3333333333333,685,0.00499035129555229,0 +"5762",2015-02-15 14:49:00,21.79,30.7,55,686.5,0.00495972464057981,0 +"5763",2015-02-15 14:50:00,21.79,30.7,57.3333333333333,679.333333333333,0.00495972464057981,0 +"5764",2015-02-15 14:51:00,21.79,30.7675,56,678.25,0.00497071671943664,0 +"5765",2015-02-15 14:51:59,21.79,30.745,40.5,677,0.00496705265032528,0 +"5766",2015-02-15 14:53:00,21.79,30.79,62,663.5,0.00497438083137476,0 +"5767",2015-02-15 14:54:00,21.76,30.79,60.3333333333333,664,0.00496519799371504,0 +"5768",2015-02-15 14:55:00,21.79,30.865,82,660.25,0.00498659484714909,0 +"5769",2015-02-15 14:55:59,21.73,30.89,80.3333333333333,660,0.00497225503648385,0 +"5770",2015-02-15 14:57:00,21.7675,30.89,64.25,649.75,0.00498375502715568,0 +"5771",2015-02-15 14:57:59,21.79,30.89,85.75,651.5,0.00499066629149226,0 +"5772",2015-02-15 14:58:59,21.745,30.89,87,653,0.00497685221726227,0 +"5773",2015-02-15 15:00:00,21.745,30.89,74,648,0.00497685221726227,0 +"5774",2015-02-15 15:01:00,21.79,30.89,73,649.333333333333,0.00499066629149226,0 +"5775",2015-02-15 15:02:00,21.73,30.89,62,652.666666666667,0.00497225503648385,0 +"5776",2015-02-15 15:03:00,21.7,30.89,74,652.75,0.00496307192494053,0 +"5777",2015-02-15 15:04:00,21.7,30.89,57,659.25,0.00496307192494053,0 +"5778",2015-02-15 15:04:59,21.79,30.89,59.5,661,0.00499066629149226,0 +"5779",2015-02-15 15:06:00,21.7,30.89,73,656.8,0.00496307192494053,0 +"5780",2015-02-15 15:07:00,21.7,30.9266666666667,80,657,0.00496901019277249,0 +"5781",2015-02-15 15:08:00,21.7,30.945,77.5,660.25,0.00497197936887181,0 +"5782",2015-02-15 15:08:59,21.73,30.9266666666667,60.6666666666667,655.666666666667,0.00497820437906331,0 +"5783",2015-02-15 15:10:00,21.7,30.945,71.25,658,0.00497197936887181,0 +"5784",2015-02-15 15:10:59,21.7,30.9633333333333,82.3333333333333,654,0.00497494857309388,0 +"5785",2015-02-15 15:11:59,21.7,30.9725,77.5,654,0.00497643318575108,0 +"5786",2015-02-15 15:13:00,21.7,31,63,655.666666666667,0.0049808870659079,0 +"5787",2015-02-15 15:14:00,21.7,30.89,63,654,0.00496307192494053,0 +"5788",2015-02-15 15:15:00,21.7,31,77.5,651.25,0.0049808870659079,0 +"5789",2015-02-15 15:16:00,21.7,31,70,659,0.0049808870659079,0 +"5790",2015-02-15 15:16:59,21.7,31,68.5,655,0.0049808870659079,0 +"5791",2015-02-15 15:17:59,21.7,31,74,659,0.0049808870659079,0 +"5792",2015-02-15 15:19:00,21.7,31,64.25,656.75,0.0049808870659079,0 +"5793",2015-02-15 15:20:00,21.7,31,57,657,0.0049808870659079,0 +"5794",2015-02-15 15:21:00,21.7,31,71.5,656,0.0049808870659079,0 +"5795",2015-02-15 15:22:00,21.675,31,69.75,652,0.00497321827293066,0 +"5796",2015-02-15 15:23:00,21.7,31,68,653,0.0049808870659079,0 +"5797",2015-02-15 15:23:59,21.7,31.025,50,658.5,0.00498493610278005,0 +"5798",2015-02-15 15:24:59,21.7,31.025,50,657,0.00498493610278005,0 +"5799",2015-02-15 15:26:00,21.7,31.1,50,656,0.00499708352718631,0 +"5800",2015-02-15 15:27:00,21.7,31.075,50,660.25,0.00499303433341824,0 +"5801",2015-02-15 15:28:00,21.675,31.075,57.25,662.75,0.0049853466892633,0 +"5802",2015-02-15 15:29:00,21.7,31.1,50,659.25,0.00499708352718631,0 +"5803",2015-02-15 15:29:59,21.7,31.125,50,661.5,0.00500113277325503,0 +"5804",2015-02-15 15:30:59,21.675,31.15,50,659.75,0.00499747557483873,0 +"5805",2015-02-15 15:32:00,21.7,31.2,50,656,0.00501328082527534,0 +"5806",2015-02-15 15:33:00,21.7,31.2,50,659,0.00501328082527534,0 +"5807",2015-02-15 15:34:00,21.7,31.2,50,663.25,0.00501328082527534,0 +"5808",2015-02-15 15:35:00,21.7,31.2,50,658.75,0.00501328082527534,0 +"5809",2015-02-15 15:36:00,21.65,31.15,50,654,0.00498977956065082,0 +"5810",2015-02-15 15:36:59,21.6666666666667,31.1666666666667,50,660,0.0049976030490189,0 +"5811",2015-02-15 15:38:00,21.625,31.125,48.5,654.75,0.00497806354534901,0 +"5812",2015-02-15 15:39:00,21.625,31.15,47,649.5,0.00498209401669525,0 +"5813",2015-02-15 15:40:00,21.6,31.2,62,656.333333333333,0.00498246751168639,0 +"5814",2015-02-15 15:40:59,21.6,31.2,42.25,660,0.00498246751168639,0 +"5815",2015-02-15 15:42:00,21.65,31.2,55,662.5,0.00499785319324602,0 +"5816",2015-02-15 15:42:59,21.6,31.2,40.5,663,0.00498246751168639,0 +"5817",2015-02-15 15:43:59,21.6,31.2,45.3333333333333,666,0.00498246751168639,0 +"5818",2015-02-15 15:45:00,21.6,31.245,40.5,663,0.00498971141132914,0 +"5819",2015-02-15 15:46:00,21.6,31.29,46,660,0.00499695547835995,0 +"5820",2015-02-15 15:47:00,21.5666666666667,31.29,23,661.333333333333,0.00498669161966099,0 +"5821",2015-02-15 15:48:00,21.55,31.29,43.75,670,0.00498156667719604,0 +"5822",2015-02-15 15:49:00,21.525,31.29,19,669.75,0.00497388798679162,0 +"5823",2015-02-15 15:49:59,21.525,31.34,40.75,659.5,0.00498189969383573,0 +"5824",2015-02-15 15:51:00,21.5,31.39,39.5,660.5,0.00498221847230601,0 +"5825",2015-02-15 15:52:00,21.5,31.39,25,662.333333333333,0.00498221847230601,0 +"5826",2015-02-15 15:53:00,21.5,31.39,28.75,663.5,0.00498221847230601,0 +"5827",2015-02-15 15:53:59,21.5,31.5,31,663,0.00499981800624192,0 +"5828",2015-02-15 15:55:00,21.5,31.5,48,662,0.00499981800624192,0 +"5829",2015-02-15 15:55:59,21.5,31.5,48,658,0.00499981800624192,0 +"5830",2015-02-15 15:56:59,21.5,31.5,40.75,661.5,0.00499981800624192,0 +"5831",2015-02-15 15:58:00,21.445,31.445,48,658.5,0.00497410002712628,0 +"5832",2015-02-15 15:59:00,21.4175,31.4725,33.5,657.5,0.00497003737792687,0 +"5833",2015-02-15 16:00:00,21.4175,31.525,48,663,0.00497839436839377,0 +"5834",2015-02-15 16:01:00,21.445,31.55,48,661,0.00499084263198941,0 +"5835",2015-02-15 16:01:59,21.39,31.525,40.75,657.75,0.00496994520693772,0 +"5836",2015-02-15 16:02:59,21.39,31.55,33.5,661.5,0.00497391799689239,0 +"5837",2015-02-15 16:04:00,21.39,31.6,48,667,0.00498186372784494,0 +"5838",2015-02-15 16:05:00,21.39,31.6,31,669,0.00498186372784494,0 +"5839",2015-02-15 16:06:00,21.365,31.6,31,662.5,0.00497417512742665,0 +"5840",2015-02-15 16:07:00,21.365,31.6,22,657.25,0.00497417512742665,0 +"5841",2015-02-15 16:08:00,21.315,31.6,22,662.333333333333,0.00495882936756385,0 +"5842",2015-02-15 16:08:59,21.29,31.6666666666667,28.75,663.75,0.00496170101822181,0 +"5843",2015-02-15 16:09:59,21.29,31.7,31,664.25,0.0049669655682835,0 +"5844",2015-02-15 16:11:00,21.34,31.65,31,661.5,0.00497441823988091,0 +"5845",2015-02-15 16:12:00,21.29,31.745,31,664.5,0.00497407285111199,0 +"5846",2015-02-15 16:13:00,21.29,31.7,31,666.333333333333,0.0049669655682835,0 +"5847",2015-02-15 16:14:00,21.29,31.7,31,665.666666666667,0.0049669655682835,0 +"5848",2015-02-15 16:14:59,21.29,31.7675,31,659,0.00497762655295258,0 +"5849",2015-02-15 16:15:59,21.29,31.7675,31,662.75,0.00497762655295258,0 +"5850",2015-02-15 16:17:00,21.29,31.79,31,661.666666666667,0.0049811802950783,0 +"5851",2015-02-15 16:18:00,21.29,31.79,31,663.5,0.0049811802950783,0 +"5852",2015-02-15 16:19:00,21.2675,31.7675,31,663.75,0.00497070695463917,0 +"5853",2015-02-15 16:20:00,21.245,31.79,31,664,0.00496733964551547,0 +"5854",2015-02-15 16:21:00,21.245,31.815,19.75,669.25,0.00497127723646099,0 +"5855",2015-02-15 16:21:59,21.2,31.79,26.5,668.5,0.00495353298310899,0 +"5856",2015-02-15 16:23:00,21.2,31.79,40,670.333333333333,0.00495353298310899,0 +"5857",2015-02-15 16:24:00,21.2,31.79,40,672,0.00495353298310899,0 +"5858",2015-02-15 16:25:00,21.2,31.79,34.6666666666667,665,0.00495353298310899,0 +"5859",2015-02-15 16:25:59,21.175,31.79,26.5,662,0.00494587727425414,0 +"5860",2015-02-15 16:27:00,21.175,31.865,32,673.25,0.00495763875182179,0 +"5861",2015-02-15 16:27:59,21.1333333333333,31.89,24,670,0.00494878235295446,0 +"5862",2015-02-15 16:28:59,21.125,31.89,24,670.75,0.00494623044637376,0 +"5863",2015-02-15 16:30:00,21.1,31.89,32,669,0.00493858170097655,0 +"5864",2015-02-15 16:31:00,21.15,31.89,26.5,667,0.00495388965604618,0 +"5865",2015-02-15 16:32:00,21.125,31.89,13,665.5,0.00494623044637376,0 +"5866",2015-02-15 16:33:00,21.1,31.89,26.5,668.75,0.00493858170097655,0 +"5867",2015-02-15 16:34:00,21.1,31.89,31,670,0.00493858170097655,0 +"5868",2015-02-15 16:34:59,21.1,31.89,26.5,671.25,0.00493858170097655,0 +"5869",2015-02-15 16:36:00,21.1,31.89,36,662.25,0.00493858170097655,0 +"5870",2015-02-15 16:37:00,21.1,31.89,40,667,0.00493858170097655,0 +"5871",2015-02-15 16:38:00,21.1,31.89,26.5,662.5,0.00493858170097655,0 +"5872",2015-02-15 16:38:59,21.0666666666667,31.9266666666667,31,668.666666666667,0.00493411118484096,0 +"5873",2015-02-15 16:40:00,21.1,32,26.5,674.25,0.00495575235808115,0 +"5874",2015-02-15 16:40:59,21,31.89,31,673.666666666667,0.00490809111427274,0 +"5875",2015-02-15 16:41:59,21.05,31.945,26.5,668.5,0.00493187401701558,0 +"5876",2015-02-15 16:43:00,21.0333333333333,31.9266666666667,31,667.333333333333,0.00492393579463575,0 +"5877",2015-02-15 16:44:00,21,31.89,26.5,675.75,0.00490809111427274,0 +"5878",2015-02-15 16:45:00,21,31.89,31,674,0.00490809111427274,0 +"5879",2015-02-15 16:46:00,21,31.9175,26.5,670,0.00491235698054133,0 +"5880",2015-02-15 16:46:59,21,31.89,40,664.333333333333,0.00490809111427274,0 +"5881",2015-02-15 16:47:59,21,32,33.25,667.5,0.00492515492768499,0 +"5882",2015-02-15 16:49:00,21,32,26.5,673.5,0.00492515492768499,0 +"5883",2015-02-15 16:50:00,21,32,26,681.25,0.00492515492768499,0 +"5884",2015-02-15 16:51:00,21,32,24,677,0.00492515492768499,0 +"5885",2015-02-15 16:52:00,21,32.0225,24,672,0.00492864536759196,0 +"5886",2015-02-15 16:53:00,20.9266666666667,32.06,24,678,0.00491208840583205,0 +"5887",2015-02-15 16:53:59,20.9633333333333,32.06,24,692,0.00492326439938503,0 +"5888",2015-02-15 16:54:59,20.945,32.09,24,690,0.00492231170460047,0 +"5889",2015-02-15 16:56:00,20.9266666666667,32.09,24,685,0.00491672120399834,0 +"5890",2015-02-15 16:57:00,20.89,32.09,24,683,0.00490555703050911,0 +"5891",2015-02-15 16:58:00,20.89,32.09,24,684,0.00490555703050911,0 +"5892",2015-02-15 16:59:00,20.89,32.09,24,684.5,0.00490555703050911,0 +"5893",2015-02-15 16:59:59,20.89,32.1266666666667,24,687.666666666667,0.00491120647428622,0 +"5894",2015-02-15 17:00:59,20.89,32.09,24,685.5,0.00490555703050911,0 +"5895",2015-02-15 17:02:00,20.89,32.1633333333333,24,685,0.00491685601988569,0 +"5896",2015-02-15 17:03:00,20.89,32.1725,24,691,0.00491826842219563,0 +"5897",2015-02-15 17:04:00,20.84,32.145,6,690.75,0.00489881701861793,0 +"5898",2015-02-15 17:05:00,20.8233333333333,32.1266666666667,18,689.333333333333,0.00489094185709971,0 +"5899",2015-02-15 17:06:00,20.8566666666667,32.1633333333333,24,693.333333333333,0.00490670269948332,0 +"5900",2015-02-15 17:06:59,20.84,32.145,24,692,0.00489881701861793,0 +"5901",2015-02-15 17:08:00,20.815,32.095,24,689.25,0.00488355773071544,0 +"5902",2015-02-15 17:09:00,20.79,32.045,24,686,0.00486833298048422,0 +"5903",2015-02-15 17:10:00,20.79,32.045,24,685.5,0.00486833298048422,0 +"5904",2015-02-15 17:10:59,20.79,32.0225,24,684.5,0.004864888005462,0 +"5905",2015-02-15 17:12:00,20.79,32.09,10.5,681.5,0.00487522304412235,0 +"5906",2015-02-15 17:12:59,20.79,32.09,6,685.75,0.00487522304412235,0 +"5907",2015-02-15 17:13:59,20.79,32.09,6,682.333333333333,0.00487522304412235,0 +"5908",2015-02-15 17:15:00,20.79,32.1175,6,678.5,0.00487943371313009,0 +"5909",2015-02-15 17:16:00,20.79,32.145,6,683.333333333333,0.00488364443870363,0 +"5910",2015-02-15 17:17:00,20.79,32.2,13.3333333333333,687,0.0048920660595527,0 +"5911",2015-02-15 17:18:00,20.745,32.2,17,682,0.0048784225850382,0 +"5912",2015-02-15 17:19:00,20.73,32.2,20.6666666666667,680.333333333333,0.00487388223761316,0 +"5913",2015-02-15 17:19:59,20.7225,32.2225,17,679.75,0.00487504422225853,0 +"5914",2015-02-15 17:21:00,20.7,32.2,20.6666666666667,678.666666666667,0.00486481274288493,0 +"5915",2015-02-15 17:22:00,20.7,32.26,11.3333333333333,674,0.00487394864302735,0 +"5916",2015-02-15 17:23:00,20.7,32.2225,14,678.5,0.00486823867423248,0 +"5917",2015-02-15 17:23:59,20.7225,32.2675,14,675.75,0.00488190585060145,0 +"5918",2015-02-15 17:25:00,20.7,32.29,14,679.5,0.00487851669295895,0 +"5919",2015-02-15 17:25:59,20.7,32.29,14,682.666666666667,0.00487851669295895,0 +"5920",2015-02-15 17:26:59,20.7,32.29,14,686.25,0.00487851669295895,0 +"5921",2015-02-15 17:28:00,20.65,32.29,14,685,0.00486339118713754,0 +"5922",2015-02-15 17:29:00,20.7,32.3175,14,669.25,0.00488270413054762,0 +"5923",2015-02-15 17:30:00,20.7,32.4,14,670.5,0.00489526677897649,0 +"5924",2015-02-15 17:31:00,20.7,32.3725,14,675.5,0.00489107917355527,0 +"5925",2015-02-15 17:31:59,20.65,32.345,14,681,0.00487173995056737,0 +"5926",2015-02-15 17:32:59,20.65,32.3725,14,680,0.00487591441567643,0 +"5927",2015-02-15 17:34:00,20.6,32.3175,14,682.333333333333,0.00485246844156813,0 +"5928",2015-02-15 17:35:00,20.625,32.425,14,670,0.00487630475284171,0 +"5929",2015-02-15 17:36:00,20.6,32.4,14,671,0.0048649526932543,0 +"5930",2015-02-15 17:37:00,20.6,32.4,14,673,0.0048649526932543,0 +"5931",2015-02-15 17:38:00,20.6,32.45,14,677,0.00487251914841278,0 +"5932",2015-02-15 17:38:59,20.6,32.4333333333333,14,680,0.00486999697639793,0 +"5933",2015-02-15 17:39:59,20.6,32.4,14,681,0.0048649526932543,0 +"5934",2015-02-15 17:41:00,20.6,32.5,14,680.5,0.00488008578623241,0 +"5935",2015-02-15 17:42:00,20.6,32.45,14,673.5,0.00487251914841278,0 +"5936",2015-02-15 17:43:00,20.5666666666667,32.5,14,673,0.00486998645897921,0 +"5937",2015-02-15 17:44:00,20.6,32.5,14,672.25,0.00488008578623241,0 +"5938",2015-02-15 17:44:59,20.5,32.5,14,668,0.00484984319757536,0 +"5939",2015-02-15 17:45:59,20.525,32.5,14,674.75,0.00485738827573757,0 +"5940",2015-02-15 17:47:00,20.55,32.5,14,671,0.00486494372498943,0 +"5941",2015-02-15 17:48:00,20.55,32.5,14,669.25,0.00486494372498943,0 +"5942",2015-02-15 17:49:00,20.5,32.5,14,668.625,0.00484984319757536,0 +"5943",2015-02-15 17:50:00,20.55,32.59,14,668,0.00487852154273239,0 +"5944",2015-02-15 17:51:00,20.5,32.59,0,673.5,0.00486337854352151,0 +"5945",2015-02-15 17:51:59,20.5,32.545,7,675.5,0.00485661079748325,0 +"5946",2015-02-15 17:53:00,20.5,32.5,0,677,0.00484984319757536,0 +"5947",2015-02-15 17:54:00,20.5,32.59,0,676,0.00486337854352151,0 +"5948",2015-02-15 17:55:00,20.5,32.645,0,676,0.00487165043157941,0 +"5949",2015-02-15 17:55:59,20.5,32.645,0,676,0.00487165043157941,0 +"5950",2015-02-15 17:57:00,20.5,32.645,0,680.5,0.00487165043157941,0 +"5951",2015-02-15 17:57:59,20.5,32.7,0,679.333333333333,0.00487992253794654,0 +"5952",2015-02-15 17:58:59,20.5,32.7,0,680,0.00487992253794654,0 +"5953",2015-02-15 18:00:00,20.5,32.59,0,678.5,0.00486337854352151,0 +"5954",2015-02-15 18:01:00,20.5,32.7,0,670.5,0.00487992253794654,0 +"5955",2015-02-15 18:02:00,20.5,32.7,0,668,0.00487992253794654,0 +"5956",2015-02-15 18:03:00,20.5,32.645,0,669.5,0.00487165043157941,0 +"5957",2015-02-15 18:04:00,20.5,32.7,0,674,0.00487992253794654,0 +"5958",2015-02-15 18:04:59,20.5,32.7,0,676,0.00487992253794654,0 +"5959",2015-02-15 18:06:00,20.5,32.7,0,675.5,0.00487992253794654,0 +"5960",2015-02-15 18:07:00,20.5,32.7,0,674,0.00487992253794654,0 +"5961",2015-02-15 18:08:00,20.5,32.7,0,673,0.00487992253794654,0 +"5962",2015-02-15 18:08:59,20.5,32.7,0,668,0.00487992253794654,0 +"5963",2015-02-15 18:10:00,20.5,32.7,0,667.5,0.00487992253794654,0 +"5964",2015-02-15 18:10:59,20.5,32.7,0,679.666666666667,0.00487992253794654,0 +"5965",2015-02-15 18:11:59,20.5,32.7,0,674.5,0.00487992253794654,0 +"5966",2015-02-15 18:13:00,20.5,32.79,0,671.5,0.0048934591829229,0 +"5967",2015-02-15 18:14:00,20.5,32.79,0,669,0.0048934591829229,0 +"5968",2015-02-15 18:15:00,20.5,32.79,0,671,0.0048934591829229,0 +"5969",2015-02-15 18:16:00,20.5,32.79,0,679,0.0048934591829229,0 +"5970",2015-02-15 18:16:59,20.5,32.79,0,676,0.0048934591829229,0 +"5971",2015-02-15 18:17:59,20.5,32.79,0,678.5,0.0048934591829229,0 +"5972",2015-02-15 18:19:00,20.5,32.79,0,680.666666666667,0.0048934591829229,0 +"5973",2015-02-15 18:20:00,20.5,32.79,0,685,0.0048934591829229,0 +"5974",2015-02-15 18:21:00,20.5,32.79,0,680,0.0048934591829229,0 +"5975",2015-02-15 18:22:00,20.5,32.79,0,672,0.0048934591829229,0 +"5976",2015-02-15 18:23:00,20.5,32.79,0,671,0.0048934591829229,0 +"5977",2015-02-15 18:23:59,20.5,32.79,0,674,0.0048934591829229,0 +"5978",2015-02-15 18:24:59,20.5,32.79,0,675.5,0.0048934591829229,0 +"5979",2015-02-15 18:26:00,20.5,32.79,0,674.5,0.0048934591829229,0 +"5980",2015-02-15 18:27:00,20.5,32.79,0,678,0.0048934591829229,0 +"5981",2015-02-15 18:28:00,20.5,32.79,0,677,0.0048934591829229,0 +"5982",2015-02-15 18:29:00,20.5,32.79,0,671,0.0048934591829229,0 +"5983",2015-02-15 18:29:59,20.5,32.79,0,669,0.0048934591829229,0 +"5984",2015-02-15 18:30:59,20.5,32.79,0,666.5,0.0048934591829229,0 +"5985",2015-02-15 18:32:00,20.5,32.79,0,673.666666666667,0.0048934591829229,0 +"5986",2015-02-15 18:33:00,20.5,32.79,0,675,0.0048934591829229,0 +"5987",2015-02-15 18:34:00,20.5,32.79,0,674,0.0048934591829229,0 +"5988",2015-02-15 18:35:00,20.5,32.79,0,675,0.0048934591829229,0 +"5989",2015-02-15 18:36:00,20.5,32.79,0,675,0.0048934591829229,0 +"5990",2015-02-15 18:36:59,20.5,32.79,0,668,0.0048934591829229,0 +"5991",2015-02-15 18:38:00,20.5,32.79,0,657,0.0048934591829229,0 +"5992",2015-02-15 18:39:00,20.5,32.79,0,651.666666666667,0.0048934591829229,0 +"5993",2015-02-15 18:40:00,20.5,32.79,0,652,0.0048934591829229,0 +"5994",2015-02-15 18:40:59,20.5,32.79,0,653,0.0048934591829229,0 +"5995",2015-02-15 18:42:00,20.5,32.79,0,653.5,0.0048934591829229,0 +"5996",2015-02-15 18:42:59,20.5,32.79,0,648,0.0048934591829229,0 +"5997",2015-02-15 18:43:59,20.5,32.79,0,647,0.0048934591829229,0 +"5998",2015-02-15 18:45:00,20.5,32.79,0,653,0.0048934591829229,0 +"5999",2015-02-15 18:46:00,20.5,32.79,0,649.666666666667,0.0048934591829229,0 +"6000",2015-02-15 18:47:00,20.5,32.79,0,646,0.0048934591829229,0 +"6001",2015-02-15 18:48:00,20.5,32.79,0,646.666666666667,0.0048934591829229,0 +"6002",2015-02-15 18:49:00,20.5,32.79,0,646,0.0048934591829229,0 +"6003",2015-02-15 18:49:59,20.5,32.9,0,649,0.00491000476516581,0 +"6004",2015-02-15 18:51:00,20.5,32.845,0,646.5,0.00490173186487402,0 +"6005",2015-02-15 18:52:00,20.445,32.845,0,647,0.00488499055207879,0 +"6006",2015-02-15 18:53:00,20.5,32.9,0,650.5,0.00491000476516581,0 +"6007",2015-02-15 18:53:59,20.5,32.9,0,654,0.00491000476516581,0 +"6008",2015-02-15 18:55:00,20.4633333333333,32.8633333333333,0,653.333333333333,0.00489331664416065,0 +"6009",2015-02-15 18:55:59,20.5,32.9,0,651,0.00491000476516581,0 +"6010",2015-02-15 18:56:59,20.445,32.845,0,661,0.00488499055207879,0 +"6011",2015-02-15 18:58:00,20.39,32.79,0,661,0.00486008397186806,0 +"6012",2015-02-15 18:59:00,20.39,32.79,0,665.5,0.00486008397186806,0 +"6013",2015-02-15 19:00:00,20.445,32.845,0,659.5,0.00488499055207879,0 +"6014",2015-02-15 19:01:00,20.39,32.79,0,656.5,0.00486008397186806,0 +"6015",2015-02-15 19:01:59,20.39,32.79,0,643.5,0.00486008397186806,0 +"6016",2015-02-15 19:02:59,20.39,32.79,0,644.5,0.00486008397186806,0 +"6017",2015-02-15 19:04:00,20.39,32.79,0,650,0.00486008397186806,0 +"6018",2015-02-15 19:05:00,20.39,32.79,0,653,0.00486008397186806,0 +"6019",2015-02-15 19:06:00,20.39,32.79,0,648,0.00486008397186806,0 +"6020",2015-02-15 19:07:00,20.39,32.845,0,650.5,0.00486829979288715,0 +"6021",2015-02-15 19:08:00,20.39,32.79,0,653.333333333333,0.00486008397186806,0 +"6022",2015-02-15 19:08:59,20.39,32.79,0,651,0.00486008397186806,0 +"6023",2015-02-15 19:09:59,20.39,32.845,0,663,0.00486829979288715,0 +"6024",2015-02-15 19:11:00,20.39,32.8633333333333,0,661.666666666667,0.00487103844775109,0 +"6025",2015-02-15 19:12:00,20.39,32.79,0,661,0.00486008397186806,0 +"6026",2015-02-15 19:13:00,20.39,32.79,0,659.5,0.00486008397186806,0 +"6027",2015-02-15 19:14:00,20.39,32.79,0,661.5,0.00486008397186806,0 +"6028",2015-02-15 19:14:59,20.39,32.79,0,663,0.00486008397186806,0 +"6029",2015-02-15 19:15:59,20.39,32.79,0,661.666666666667,0.00486008397186806,0 +"6030",2015-02-15 19:17:00,20.39,32.79,0,653,0.00486008397186806,0 +"6031",2015-02-15 19:18:00,20.39,32.79,0,646,0.00486008397186806,0 +"6032",2015-02-15 19:19:00,20.39,32.79,0,646.5,0.00486008397186806,0 +"6033",2015-02-15 19:20:00,20.39,32.79,0,657,0.00486008397186806,0 +"6034",2015-02-15 19:21:00,20.39,32.79,0,659.5,0.00486008397186806,0 +"6035",2015-02-15 19:21:59,20.39,32.79,0,659,0.00486008397186806,0 +"6036",2015-02-15 19:23:00,20.39,32.79,0,655,0.00486008397186806,0 +"6037",2015-02-15 19:24:00,20.39,32.7,0,652,0.00484664036562639,0 +"6038",2015-02-15 19:25:00,20.39,32.79,0,656,0.00486008397186806,0 +"6039",2015-02-15 19:25:59,20.39,32.7,0,659,0.00484664036562639,0 +"6040",2015-02-15 19:27:00,20.39,32.7,0,660,0.00484664036562639,0 +"6041",2015-02-15 19:27:59,20.39,32.7,0,664.333333333333,0.00484664036562639,0 +"6042",2015-02-15 19:28:59,20.39,32.7,0,664,0.00484664036562639,0 +"6043",2015-02-15 19:30:00,20.39,32.7,0,665.5,0.00484664036562639,0 +"6044",2015-02-15 19:31:00,20.5,32.79,0,661,0.0048934591829229,0 +"6045",2015-02-15 19:32:00,20.39,32.7,0,661,0.00484664036562639,0 +"6046",2015-02-15 19:33:00,20.39,32.7,0,662,0.00484664036562639,0 +"6047",2015-02-15 19:34:00,20.39,32.7,0,663.333333333333,0.00484664036562639,0 +"6048",2015-02-15 19:34:59,20.445,32.745,0,665,0.0048700012447385,0 +"6049",2015-02-15 19:36:00,20.5,32.7,0,668.5,0.00487992253794654,0 +"6050",2015-02-15 19:37:00,20.5,32.7,0,668,0.00487992253794654,0 +"6051",2015-02-15 19:38:00,20.39,32.7,0,669,0.00484664036562639,0 +"6052",2015-02-15 19:38:59,20.39,32.7,0,668,0.00484664036562639,0 +"6053",2015-02-15 19:40:00,20.39,32.6633333333333,0,664,0.00484116350617384,0 +"6054",2015-02-15 19:40:59,20.445,32.645,0,665.25,0.00485501265419304,0 +"6055",2015-02-15 19:41:59,20.4266666666667,32.6266666666667,0,658,0.00484673322460761,0 +"6056",2015-02-15 19:43:00,20.39,32.59,0,663.5,0.00483021007437691,0 +"6057",2015-02-15 19:44:00,20.39,32.59,0,668.333333333333,0.00483021007437691,0 +"6058",2015-02-15 19:45:00,20.39,32.59,0,672,0.00483021007437691,0 +"6059",2015-02-15 19:46:00,20.445,32.645,0,675,0.00485501265419304,0 +"6060",2015-02-15 19:46:59,20.39,32.59,0,674.5,0.00483021007437691,0 +"6061",2015-02-15 19:47:59,20.39,32.545,0,671,0.0048234888398397,0 +"6062",2015-02-15 19:49:00,20.39,32.5,0,670,0.00481676774943883,0 +"6063",2015-02-15 19:50:00,20.39,32.545,0,672,0.0048234888398397,0 +"6064",2015-02-15 19:51:00,20.5,32.59,0,670,0.00486337854352151,0 +"6065",2015-02-15 19:52:00,20.39,32.5,0,678.5,0.00481676774943883,0 +"6066",2015-02-15 19:53:00,20.39,32.5,0,679,0.00481676774943883,0 +"6067",2015-02-15 19:53:59,20.445,32.545,0,675.5,0.00484002478039101,0 +"6068",2015-02-15 19:54:59,20.4266666666667,32.53,0,677,0.00483226170594854,0 +"6069",2015-02-15 19:56:00,20.39,32.5,0,675.5,0.00481676774943883,0 +"6070",2015-02-15 19:57:00,20.39,32.5,0,676,0.00481676774943883,0 +"6071",2015-02-15 19:58:00,20.4266666666667,32.5,0,673.666666666667,0.00482777068084609,0 +"6072",2015-02-15 19:59:00,20.39,32.5,0,674.5,0.00481676774943883,0 +"6073",2015-02-15 19:59:59,20.5,32.5,0,675.5,0.00484984319757536,0 +"6074",2015-02-15 20:00:59,20.5,32.5,0,675.5,0.00484984319757536,0 +"6075",2015-02-15 20:02:00,20.445,32.5,0,676,0.00483328047100393,0 +"6076",2015-02-15 20:03:00,20.5,32.5,0,675.5,0.00484984319757536,0 +"6077",2015-02-15 20:04:00,20.445,32.45,0,681,0.00482578696411584,0 +"6078",2015-02-15 20:05:00,20.5,32.5,0,675,0.00484984319757536,0 +"6079",2015-02-15 20:06:00,20.39,32.4,0,677,0.00480183250901282,0 +"6080",2015-02-15 20:06:59,20.39,32.4,0,678,0.00480183250901282,0 +"6081",2015-02-15 20:08:00,20.445,32.45,0,672,0.00482578696411584,0 +"6082",2015-02-15 20:09:00,20.445,32.45,0,672.5,0.00482578696411584,0 +"6083",2015-02-15 20:10:00,20.39,32.4,0,671,0.00480183250901282,0 +"6084",2015-02-15 20:10:59,20.39,32.29,0,675,0.00478540456656807,0 +"6085",2015-02-15 20:12:00,20.39,32.29,0,679,0.00478540456656807,0 +"6086",2015-02-15 20:12:59,20.39,32.29,0,673.5,0.00478540456656807,0 +"6087",2015-02-15 20:13:59,20.39,32.29,0,676,0.00478540456656807,0 +"6088",2015-02-15 20:15:00,20.4633333333333,32.3633333333333,0,679.333333333333,0.00481829043766849,0 +"6089",2015-02-15 20:16:00,20.4266666666667,32.3266666666667,0,684.666666666667,0.00480182379580752,0 +"6090",2015-02-15 20:17:00,20.39,32.29,0,685.333333333333,0.00478540456656807,0 +"6091",2015-02-15 20:18:00,20.39,32.29,0,686,0.00478540456656807,0 +"6092",2015-02-15 20:19:00,20.39,32.29,0,679,0.00478540456656807,0 +"6093",2015-02-15 20:19:59,20.39,32.29,0,677,0.00478540456656807,0 +"6094",2015-02-15 20:21:00,20.39,32.29,0,684,0.00478540456656807,0 +"6095",2015-02-15 20:22:00,20.39,32.245,0,678.5,0.00477868429285228,0 +"6096",2015-02-15 20:23:00,20.39,32.245,0,680,0.00477868429285228,0 +"6097",2015-02-15 20:23:59,20.39,32.245,0,675,0.00477868429285228,0 +"6098",2015-02-15 20:25:00,20.39,32.2,0,676,0.00477196416324194,0 +"6099",2015-02-15 20:25:59,20.5,32.29,0,682,0.0048182629967012,0 +"6100",2015-02-15 20:26:59,20.39,32.245,0,679.5,0.00477868429285228,0 +"6101",2015-02-15 20:28:00,20.39,32.2,0,681,0.00477196416324194,0 +"6102",2015-02-15 20:29:00,20.39,32.2,0,683.333333333333,0.00477196416324194,0 +"6103",2015-02-15 20:30:00,20.39,32.2,0,684,0.00477196416324194,0 +"6104",2015-02-15 20:31:00,20.39,32.2,0,683.5,0.00477196416324194,0 +"6105",2015-02-15 20:31:59,20.39,32.2,0,680,0.00477196416324194,0 +"6106",2015-02-15 20:32:59,20.39,32.2,0,680,0.00477196416324194,0 +"6107",2015-02-15 20:34:00,20.39,32.2,0,685.5,0.00477196416324194,0 +"6108",2015-02-15 20:35:00,20.39,32.2,0,682,0.00477196416324194,0 +"6109",2015-02-15 20:36:00,20.39,32.2,0,690.5,0.00477196416324194,0 +"6110",2015-02-15 20:37:00,20.39,32.145,0,689,0.00476375086718795,0 +"6111",2015-02-15 20:38:00,20.39,32.09,0,690,0.0047555377863872,0 +"6112",2015-02-15 20:38:59,20.39,32.2,0,684,0.00477196416324194,0 +"6113",2015-02-15 20:39:59,20.39,32.09,0,688,0.0047555377863872,0 +"6114",2015-02-15 20:41:00,20.39,32.09,0,691,0.0047555377863872,0 +"6115",2015-02-15 20:42:00,20.39,32.09,0,691,0.0047555377863872,0 +"6116",2015-02-15 20:43:00,20.39,32.09,0,698,0.0047555377863872,0 +"6117",2015-02-15 20:44:00,20.39,32.09,0,693.5,0.0047555377863872,0 +"6118",2015-02-15 20:44:59,20.39,32.09,0,695.333333333333,0.0047555377863872,0 +"6119",2015-02-15 20:45:59,20.39,32.09,0,688.5,0.0047555377863872,0 +"6120",2015-02-15 20:47:00,20.39,32.09,0,685.5,0.0047555377863872,0 +"6121",2015-02-15 20:48:00,20.39,32.09,0,686,0.0047555377863872,0 +"6122",2015-02-15 20:49:00,20.39,32,0,688.333333333333,0.0047420986639068,0 +"6123",2015-02-15 20:50:00,20.39,32,0,692,0.0047420986639068,0 +"6124",2015-02-15 20:51:00,20.39,32,0,684,0.0047420986639068,0 +"6125",2015-02-15 20:51:59,20.39,32,0,690,0.0047420986639068,0 +"6126",2015-02-15 20:53:00,20.39,32,0,690.666666666667,0.0047420986639068,0 +"6127",2015-02-15 20:54:00,20.39,32,0,692,0.0047420986639068,0 +"6128",2015-02-15 20:55:00,20.39,32,0,691,0.0047420986639068,0 +"6129",2015-02-15 20:55:59,20.39,32,0,696,0.0047420986639068,0 +"6130",2015-02-15 20:57:00,20.39,32,0,696,0.0047420986639068,0 +"6131",2015-02-15 20:57:59,20.39,32,0,699,0.0047420986639068,0 +"6132",2015-02-15 20:58:59,20.39,32,0,698.333333333333,0.0047420986639068,0 +"6133",2015-02-15 21:00:00,20.39,32,0,694.333333333333,0.0047420986639068,0 +"6134",2015-02-15 21:01:00,20.39,32,0,695,0.0047420986639068,0 +"6135",2015-02-15 21:02:00,20.39,32,0,696,0.0047420986639068,0 +"6136",2015-02-15 21:03:00,20.39,32,0,692,0.0047420986639068,0 +"6137",2015-02-15 21:04:00,20.39,32,0,694,0.0047420986639068,0 +"6138",2015-02-15 21:04:59,20.39,32,0,692.666666666667,0.0047420986639068,0 +"6139",2015-02-15 21:06:00,20.39,32,0,694.666666666667,0.0047420986639068,0 +"6140",2015-02-15 21:07:00,20.34,32,0,694,0.00472736416828834,0 +"6141",2015-02-15 21:08:00,20.39,31.89,0,700,0.00472567385241829,0 +"6142",2015-02-15 21:08:59,20.39,31.89,0,694,0.00472567385241829,0 +"6143",2015-02-15 21:10:00,20.3233333333333,31.89,0,701,0.00470610538139885,0 +"6144",2015-02-15 21:10:59,20.39,31.89,0,705,0.00472567385241829,0 +"6145",2015-02-15 21:11:59,20.39,31.89,0,704.5,0.00472567385241829,0 +"6146",2015-02-15 21:13:00,20.34,31.89,0,700,0.00471099077505166,0 +"6147",2015-02-15 21:14:00,20.39,31.89,0,700,0.00472567385241829,0 +"6148",2015-02-15 21:15:00,20.39,31.79,0,706.5,0.00471074295263618,0 +"6149",2015-02-15 21:16:00,20.39,31.8566666666667,0,703.333333333333,0.00472069680677662,0 +"6150",2015-02-15 21:16:59,20.29,31.79,0,697,0.00468151046906608,0 +"6151",2015-02-15 21:17:59,20.39,31.79,0,698.5,0.00471074295263618,0 +"6152",2015-02-15 21:19:00,20.39,31.79,0,699,0.00471074295263618,0 +"6153",2015-02-15 21:20:00,20.39,31.79,0,700,0.00471074295263618,0 +"6154",2015-02-15 21:21:00,20.39,31.79,0,695,0.00471074295263618,0 +"6155",2015-02-15 21:22:00,20.34,31.79,0,701,0.00469610661448251,0 +"6156",2015-02-15 21:23:00,20.34,31.79,0,698.5,0.00469610661448251,0 +"6157",2015-02-15 21:23:59,20.39,31.79,0,699,0.00471074295263618,0 +"6158",2015-02-15 21:24:59,20.39,31.79,0,699,0.00471074295263618,0 +"6159",2015-02-15 21:26:00,20.3566666666667,31.79,0,702,0.00470098092327496,0 +"6160",2015-02-15 21:27:00,20.39,31.7,0,703,0.00469730575108109,0 +"6161",2015-02-15 21:28:00,20.29,31.745,0,700,0.00467483379993915,0 +"6162",2015-02-15 21:29:00,20.3233333333333,31.7,0,701,0.00467785562588551,0 +"6163",2015-02-15 21:29:59,20.39,31.7,0,708.5,0.00469730575108109,0 +"6164",2015-02-15 21:30:59,20.39,31.7,0,706,0.00469730575108109,0 +"6165",2015-02-15 21:32:00,20.34,31.7,0,708.5,0.00468271147443117,0 +"6166",2015-02-15 21:33:00,20.39,31.7,0,707,0.00469730575108109,0 +"6167",2015-02-15 21:34:00,20.34,31.65,0,706.5,0.00467526997738424,0 +"6168",2015-02-15 21:35:00,20.29,31.6,0,700.5,0.00465332105603858,0 +"6169",2015-02-15 21:36:00,20.39,31.6,0,712,0.00468237620291633,0 +"6170",2015-02-15 21:36:59,20.3566666666667,31.6,0,710,0.00467267339599704,0 +"6171",2015-02-15 21:38:00,20.39,31.6,0,705,0.00468237620291633,0 +"6172",2015-02-15 21:39:00,20.39,31.6,0,709.5,0.00468237620291633,0 +"6173",2015-02-15 21:40:00,20.3566666666667,31.5666666666667,0,704,0.00466770742681395,0 +"6174",2015-02-15 21:40:59,20.29,31.6,0,708.5,0.00465332105603858,0 +"6175",2015-02-15 21:42:00,20.29,31.55,0,710.5,0.004645903210949,0 +"6176",2015-02-15 21:42:59,20.29,31.5,0,708.5,0.00463848554147096,0 +"6177",2015-02-15 21:43:59,20.34,31.5,0,707.5,0.00465294654656767,0 +"6178",2015-02-15 21:45:00,20.34,31.5,0,707.5,0.00465294654656767,0 +"6179",2015-02-15 21:46:00,20.29,31.5,0,706,0.00463848554147096,0 +"6180",2015-02-15 21:47:00,20.29,31.5,0,709,0.00463848554147096,0 +"6181",2015-02-15 21:48:00,20.29,31.5,0,706.5,0.00463848554147096,0 +"6182",2015-02-15 21:49:00,20.29,31.5,0,706.333333333333,0.00463848554147096,0 +"6183",2015-02-15 21:49:59,20.29,31.39,0,713,0.00462216728674112,0 +"6184",2015-02-15 21:51:00,20.29,31.445,0,707.5,0.00463032630786899,0 +"6185",2015-02-15 21:52:00,20.3233333333333,31.39,0,710.666666666667,0.00463176938663424,0 +"6186",2015-02-15 21:53:00,20.3233333333333,31.39,0,711.666666666667,0.00463176938663424,0 +"6187",2015-02-15 21:53:59,20.39,31.34,0,717,0.00464356270646302,0 +"6188",2015-02-15 21:55:00,20.34,31.29,0,713.5,0.00462169641518139,0 +"6189",2015-02-15 21:55:59,20.34,31.29,0,713,0.00462169641518139,0 +"6190",2015-02-15 21:56:59,20.29,31.2,0,713.5,0.00459398321209564,0 +"6191",2015-02-15 21:58:00,20.29,31.29,0,715.5,0.00460733324720036,0 +"6192",2015-02-15 21:59:00,20.29,31.29,0,713,0.00460733324720036,0 +"6193",2015-02-15 22:00:00,20.29,31.2225,0,714,0.00459732066754166,0 +"6194",2015-02-15 22:01:00,20.39,31.29,0,714,0.00463609912371531,0 +"6195",2015-02-15 22:01:59,20.29,31.29,0,718.5,0.00460733324720036,0 +"6196",2015-02-15 22:02:59,20.29,31.245,0,719.5,0.00460065815854074,0 +"6197",2015-02-15 22:04:00,20.29,31.29,0,720,0.00460733324720036,0 +"6198",2015-02-15 22:05:00,20.29,31.2,0,715.5,0.00459398321209564,0 +"6199",2015-02-15 22:06:00,20.29,31.2,0,715,0.00459398321209564,0 +"6200",2015-02-15 22:07:00,20.29,31.2,0,717,0.00459398321209564,0 +"6201",2015-02-15 22:08:00,20.29,31.1,0,720,0.00457915050691345,0 +"6202",2015-02-15 22:08:59,20.29,31.2,0,721,0.00459398321209564,0 +"6203",2015-02-15 22:09:59,20.29,31.2,0,722,0.00459398321209564,0 +"6204",2015-02-15 22:11:00,20.29,31.2,0,721,0.00459398321209564,0 +"6205",2015-02-15 22:12:00,20.29,31.2,0,715.5,0.00459398321209564,0 +"6206",2015-02-15 22:13:00,20.29,31.1333333333333,0,718,0.00458409466394709,0 +"6207",2015-02-15 22:14:00,20.29,31.1,0,717.666666666667,0.00457915050691345,0 +"6208",2015-02-15 22:14:59,20.29,31,0,722,0.00456431850395291,0 +"6209",2015-02-15 22:15:59,20.29,31.1,0,722.5,0.00457915050691345,0 +"6210",2015-02-15 22:17:00,20.245,31.1,0,723,0.00456633682619335,0 +"6211",2015-02-15 22:18:00,20.29,31.05,0,720.5,0.00457173441765859,0 +"6212",2015-02-15 22:19:00,20.245,31.05,0,721,0.00455894164011951,0 +"6213",2015-02-15 22:20:00,20.29,31,0,722,0.00456431850395291,0 +"6214",2015-02-15 22:21:00,20.29,31.0666666666667,0,720.666666666667,0.00457420642790444,0 +"6215",2015-02-15 22:21:59,20.29,31.0333333333333,0,723.666666666667,0.00456926242691821,0 +"6216",2015-02-15 22:23:00,20.29,31,0,715.333333333333,0.00456431850395291,0 +"6217",2015-02-15 22:24:00,20.29,31,0,718,0.00456431850395291,0 +"6218",2015-02-15 22:25:00,20.29,31,0,715,0.00456431850395291,0 +"6219",2015-02-15 22:25:59,20.29,31,0,712,0.00456431850395291,0 +"6220",2015-02-15 22:27:00,20.29,31,0,718,0.00456431850395291,0 +"6221",2015-02-15 22:27:59,20.29,31,0,718.5,0.00456431850395291,0 +"6222",2015-02-15 22:28:59,20.29,31,0,719.333333333333,0.00456431850395291,0 +"6223",2015-02-15 22:30:00,20.29,31,0,716,0.00456431850395291,0 +"6224",2015-02-15 22:31:00,20.29,30.89,0,717.5,0.00454800411170284,0 +"6225",2015-02-15 22:32:00,20.245,30.84,0,728,0.00452788376478214,0 +"6226",2015-02-15 22:33:00,20.245,30.84,0,728,0.00452788376478214,0 +"6227",2015-02-15 22:34:00,20.245,30.84,0,728,0.00452788376478214,0 +"6228",2015-02-15 22:34:59,20.29,30.89,0,727,0.00454800411170284,0 +"6229",2015-02-15 22:36:00,20.29,30.84,0,723,0.00454058875971266,0 +"6230",2015-02-15 22:37:00,20.26,30.8566666666667,0,724.666666666667,0.00453458238810971,0 +"6231",2015-02-15 22:38:00,20.29,30.89,0,717,0.00454800411170284,0 +"6232",2015-02-15 22:38:59,20.29,30.89,0,713,0.00454800411170284,0 +"6233",2015-02-15 22:40:00,20.29,30.79,0,709.5,0.00453317358324549,0 +"6234",2015-02-15 22:40:59,20.23,30.6633333333333,0,715.333333333333,0.00449755465119769,0 +"6235",2015-02-15 22:41:59,20.26,30.76,0,717.666666666667,0.00452027337191629,0 +"6236",2015-02-15 22:43:00,20.29,30.695,0,720.5,0.00451908523150143,0 +"6237",2015-02-15 22:44:00,20.245,30.65,0,714.5,0.00449978643533299,0 +"6238",2015-02-15 22:45:00,20.2,30.65,0,715.5,0.00448719205871083,0 +"6239",2015-02-15 22:46:00,20.245,30.65,0,715,0.00449978643533299,0 +"6240",2015-02-15 22:46:59,20.29,30.7,0,713,0.00451982670790267,0 +"6241",2015-02-15 22:47:59,20.29,30.7,0,713,0.00451982670790267,0 +"6242",2015-02-15 22:49:00,20.245,30.65,0,714.5,0.00449978643533299,0 +"6243",2015-02-15 22:50:00,20.2,30.6,0,715.5,0.00447981928533327,0 +"6244",2015-02-15 22:51:00,20.26,30.6666666666667,0,724.333333333333,0.0045064583902316,0 +"6245",2015-02-15 22:52:00,20.29,30.6,0,723,0.00450499751333018,0 +"6246",2015-02-15 22:53:00,20.29,30.6,0,721.333333333333,0.00450499751333018,0 +"6247",2015-02-15 22:53:59,20.29,30.55,0,721,0.00449758317928669,0 +"6248",2015-02-15 22:54:59,20.29,30.5,0,721,0.00449016902073007,0 +"6249",2015-02-15 22:56:00,20.29,30.55,0,717.5,0.00449758317928669,0 +"6250",2015-02-15 22:57:00,20.29,30.5,0,717,0.00449016902073007,0 +"6251",2015-02-15 22:58:00,20.29,30.5333333333333,0,725,0.00449511177360291,0 +"6252",2015-02-15 22:59:00,20.2,30.39,0,724.5,0.00444885553202324,0 +"6253",2015-02-15 22:59:59,20.2,30.39,0,727.5,0.00444885553202324,0 +"6254",2015-02-15 23:00:59,20.2,30.34,0,728,0.00444148366093455,0 +"6255",2015-02-15 23:02:00,20.29,30.5,0,734.5,0.00449016902073007,0 +"6256",2015-02-15 23:03:00,20.2,30.39,0,727,0.00444885553202324,0 +"6257",2015-02-15 23:04:00,20.26,30.43,0,730.333333333333,0.00447143027479798,0 +"6258",2015-02-15 23:05:00,20.245,30.445,0,730.5,0.00446947372192622,0 +"6259",2015-02-15 23:06:00,20.29,30.4266666666667,0,727.333333333333,0.0044792952389369,0 +"6260",2015-02-15 23:06:59,20.29,30.34,0,725.5,0.00446644489254803,0 +"6261",2015-02-15 23:08:00,20.29,30.34,0,731,0.00446644489254803,0 +"6262",2015-02-15 23:09:00,20.245,30.245,0,727.5,0.00443990316973038,0 +"6263",2015-02-15 23:10:00,20.29,30.245,0,728,0.00445235954156012,0 +"6264",2015-02-15 23:10:59,20.2,30.29,0,730,0.00443411196334396,0 +"6265",2015-02-15 23:12:00,20.2675,30.34,0,731,0.00446019299840749,0 +"6266",2015-02-15 23:12:59,20.29,30.3566666666667,0,729.666666666667,0.0044689160720656,0 +"6267",2015-02-15 23:13:59,20.245,30.245,0,730.5,0.00443990316973038,0 +"6268",2015-02-15 23:15:00,20.2,30.1,0,731,0.00440610109469442,0 +"6269",2015-02-15 23:16:00,20.245,30.1975,0,731,0.00443288057380961,0 +"6270",2015-02-15 23:17:00,20.245,30.05,0,734,0.00441107456897689,0 +"6271",2015-02-15 23:18:00,20.29,30.2,0,733.333333333333,0.00444568775426561,0 +"6272",2015-02-15 23:19:00,20.245,30.15,0,733.5,0.00442585813533826,0 +"6273",2015-02-15 23:19:59,20.29,30.2,0,732,0.00444568775426561,0 +"6274",2015-02-15 23:21:00,20.29,30.15,0,731,0.0044382748239426,0 +"6275",2015-02-15 23:22:00,20.29,30.1,0,728,0.00443086206905663,0 +"6276",2015-02-15 23:23:00,20.245,30,0,734.5,0.00440368304746076,0 +"6277",2015-02-15 23:23:59,20.2,30.0666666666667,0,731.5,0.0044011871654972,0 +"6278",2015-02-15 23:25:00,20.29,30.1,0,730.5,0.00443086206905663,0 +"6279",2015-02-15 23:25:59,20.29,30.05,0,725,0.00442344948960147,0 +"6280",2015-02-15 23:26:59,20.245,29.84,0,723.5,0.00438003135078056,0 +"6281",2015-02-15 23:28:00,20.245,30,0,732.5,0.00440368304746076,0 +"6282",2015-02-15 23:29:00,20.29,30.05,0,732,0.00442344948960147,0 +"6283",2015-02-15 23:30:00,20.2,30,0,721,0.0043913595383871,0 +"6284",2015-02-15 23:31:00,20.23,30,0,723.5,0.00439957182221627,0 +"6285",2015-02-15 23:31:59,20.245,30,0,730,0.00440368304746076,0 +"6286",2015-02-15 23:32:59,20.2,29.89,0,727.5,0.004375144627816,0 +"6287",2015-02-15 23:34:00,20.2675,29.89,0,727.5,0.00439357255835947,0 +"6288",2015-02-15 23:35:00,20.29,29.89,0,733,0.00439973041416739,0 +"6289",2015-02-15 23:36:00,20.29,29.89,0,729.5,0.00439973041416739,0 +"6290",2015-02-15 23:37:00,20.29,29.89,0,731,0.00439973041416739,0 +"6291",2015-02-15 23:38:00,20.29,29.89,0,733,0.00439973041416739,0 +"6292",2015-02-15 23:38:59,20.29,29.8233333333333,0,733.333333333333,0.00438984799619339,0 +"6293",2015-02-15 23:39:59,20.29,29.745,0,731,0.00437823655351488,0 +"6294",2015-02-15 23:41:00,20.29,29.745,0,733,0.00437823655351488,0 +"6295",2015-02-15 23:42:00,20.2,29.7,0,730.5,0.00434713903222423,0 +"6296",2015-02-15 23:43:00,20.245,29.745,0,733.5,0.00436598900093055,0 +"6297",2015-02-15 23:44:00,20.26,29.6666666666667,0,733,0.00435847895383564,0 +"6298",2015-02-15 23:44:59,20.29,29.7,0,733,0.00437156634495469,0 +"6299",2015-02-15 23:45:59,20.245,29.695,0,729,0.00435859854337066,0 +"6300",2015-02-15 23:47:00,20.26,29.6333333333333,0,727,0.0043535475098628,0 +"6301",2015-02-15 23:48:00,20.29,29.7,0,730,0.00437156634495469,0 +"6302",2015-02-15 23:49:00,20.26,29.6666666666667,0,723.333333333333,0.00435847895383564,0 +"6303",2015-02-15 23:50:00,20.29,29.7,0,723,0.00437156634495469,0 +"6304",2015-02-15 23:51:00,20.245,29.6,0,726.5,0.00434455715446589,0 +"6305",2015-02-15 23:51:59,20.245,29.55,0,727.5,0.0043371672026407,0 +"6306",2015-02-15 23:53:00,20.245,29.65,0,729.5,0.00435194728067649,0 +"6307",2015-02-15 23:54:00,20.29,29.6,0,733,0.00435674416786363,0 +"6308",2015-02-15 23:55:00,20.2,29.6,0,728,0.00433240025092638,0 +"6309",2015-02-15 23:55:59,20.29,29.6,0,730.5,0.00435674416786363,0 +"6310",2015-02-15 23:57:00,20.2,29.5,0,738,0.00431766216325846,0 +"6311",2015-02-15 23:57:59,20.2,29.4633333333333,0,739,0.00431225837156338,0 +"6312",2015-02-15 23:58:59,20.29,29.5,0,738,0.00434192269224674,0 +"6313",2015-02-16 00:00:00,20.26,29.4633333333333,0,735.333333333333,0.00432839835343693,0 +"6314",2015-02-16 00:01:00,20.2,29.39,0,732,0.00430145106790789,0 +"6315",2015-02-16 00:02:00,20.29,29.5,0,726.5,0.00434192269224674,0 +"6316",2015-02-16 00:03:00,20.245,29.445,0,734,0.00432164887140486,0 +"6317",2015-02-16 00:04:00,20.29,29.5,0,733,0.00434192269224674,0 +"6318",2015-02-16 00:04:59,20.29,29.5,0,733,0.00434192269224674,0 +"6319",2015-02-16 00:06:00,20.29,29.5,0,731,0.00434192269224674,0 +"6320",2015-02-16 00:07:00,20.29,29.5,0,739,0.00434192269224674,0 +"6321",2015-02-16 00:08:00,20.26,29.4266666666667,0,732.333333333333,0.00432297429034963,0 +"6322",2015-02-16 00:08:59,20.29,29.4633333333333,0,727.666666666667,0.00433648832693561,0 +"6323",2015-02-16 00:10:00,20.29,29.5,0,723,0.00434192269224674,0 +"6324",2015-02-16 00:10:59,20.29,29.39,0,725.5,0.00432561987921138,0 +"6325",2015-02-16 00:11:59,20.29,29.39,0,727,0.00432561987921138,0 +"6326",2015-02-16 00:13:00,20.245,29.34,0,735,0.00430613130912431,0 +"6327",2015-02-16 00:14:00,20.245,29.34,0,732.5,0.00430613130912431,0 +"6328",2015-02-16 00:15:00,20.29,29.29,0,731,0.00431079987652814,0 +"6329",2015-02-16 00:16:00,20.29,29.29,0,732.5,0.00431079987652814,0 +"6330",2015-02-16 00:16:59,20.29,29.29,0,729,0.00431079987652814,0 +"6331",2015-02-16 00:17:59,20.29,29.2,0,733,0.00429746247374309,0 +"6332",2015-02-16 00:19:00,20.29,29.2,0,729.5,0.00429746247374309,0 +"6333",2015-02-16 00:20:00,20.29,29.2,0,733,0.00429746247374309,0 +"6334",2015-02-16 00:21:00,20.29,29.2,0,734,0.00429746247374309,0 +"6335",2015-02-16 00:22:00,20.29,29.2,0,732,0.00429746247374309,0 +"6336",2015-02-16 00:23:00,20.29,29,0,730,0.00426782583453201,0 +"6337",2015-02-16 00:23:59,20.29,29.2,0,734,0.00429746247374309,0 +"6338",2015-02-16 00:24:59,20.245,29.15,0,731,0.00427805386517338,0 +"6339",2015-02-16 00:26:00,20.29,29.175,0,732,0.00429375774044597,0 +"6340",2015-02-16 00:27:00,20.29,29,0,730,0.00426782583453201,0 +"6341",2015-02-16 00:28:00,20.26,29.1333333333333,0,737.666666666667,0.00427958516746563,0 +"6342",2015-02-16 00:29:00,20.2,29.1,0,739,0.00425871674790693,0 +"6343",2015-02-16 00:29:59,20.2675,29.175,0,730,0.00428774921908152,0 +"6344",2015-02-16 00:30:59,20.26,29.1666666666667,0,727.5,0.00428451544685323,0 +"6345",2015-02-16 00:32:00,20.29,29.2,0,733.5,0.00429746247374309,0 +"6346",2015-02-16 00:33:00,20.29,29,0,729,0.00426782583453201,0 +"6347",2015-02-16 00:34:00,20.29,29.1,0,711,0.00428264380352494,0 +"6348",2015-02-16 00:35:00,20.29,29.1,0,712,0.00428264380352494,0 +"6349",2015-02-16 00:36:00,20.245,29.05,0,709,0.00426327727422867,0 +"6350",2015-02-16 00:36:59,20.29,29,0,698.333333333333,0.00426782583453201,0 +"6351",2015-02-16 00:38:00,20.29,29,0,697,0.00426782583453201,0 +"6352",2015-02-16 00:39:00,20.29,29,0,711,0.00426782583453201,0 +"6353",2015-02-16 00:40:00,20.29,29,0,749,0.00426782583453201,0 +"6354",2015-02-16 00:40:59,20.29,29,0,758,0.00426782583453201,0 +"6355",2015-02-16 00:42:00,20.29,28.93,0,774,0.00425745367343932,0 +"6356",2015-02-16 00:42:59,20.29,28.89,0,778,0.00425152687849553,0 +"6357",2015-02-16 00:43:59,20.29,28.89,0,781.333333333333,0.00425152687849553,0 +"6358",2015-02-16 00:45:00,20.29,28.84,0,775,0.00424411854256758,0 +"6359",2015-02-16 00:46:00,20.29,28.79,0,775.666666666667,0.00423671038191359,0 +"6360",2015-02-16 00:47:00,20.34,28.745,0,781.5,0.00424322220441099,0 +"6361",2015-02-16 00:48:00,20.29,28.745,0,783.5,0.00423004318717909,0 +"6362",2015-02-16 00:49:00,20.29,28.79,0,786,0.00423671038191359,0 +"6363",2015-02-16 00:49:59,20.29,28.79,0,790,0.00423671038191359,0 +"6364",2015-02-16 00:51:00,20.29,28.79,0,789,0.00423671038191359,0 +"6365",2015-02-16 00:52:00,20.29,28.73,0,801,0.00422782082048167,0 +"6366",2015-02-16 00:53:00,20.29,28.65,0,804,0.00421596846448693,0 +"6367",2015-02-16 00:53:59,20.29,28.6,0,798,0.00420856096981725,0 +"6368",2015-02-16 00:55:00,20.29,28.6,0,797,0.00420856096981725,0 +"6369",2015-02-16 00:55:59,20.29,28.6,0,793,0.00420856096981725,0 +"6370",2015-02-16 00:56:59,20.29,28.5333333333333,0,802.666666666667,0.00419868458285855,0 +"6371",2015-02-16 00:58:00,20.29,28.5,0,799,0.00419374650620399,0 +"6372",2015-02-16 00:59:00,20.29,28.6,0,803.333333333333,0.00420856096981725,0 +"6373",2015-02-16 01:00:00,20.29,28.6,0,806.5,0.00420856096981725,0 +"6374",2015-02-16 01:01:00,20.29,28.6,0,805,0.00420856096981725,0 +"6375",2015-02-16 01:01:59,20.29,28.5,0,801,0.00419374650620399,0 +"6376",2015-02-16 01:02:59,20.29,28.55,0,805,0.00420115365039168,0 +"6377",2015-02-16 01:04:00,20.29,28.6,0,807,0.00420856096981725,0 +"6378",2015-02-16 01:05:00,20.29,28.5666666666667,0,808.666666666667,0.00420362273739569,0 +"6379",2015-02-16 01:06:00,20.29,28.5,0,815,0.00419374650620399,0 +"6380",2015-02-16 01:07:00,20.29,28.5,0,818,0.00419374650620399,0 +"6381",2015-02-16 01:08:00,20.29,28.5,0,810.5,0.00419374650620399,0 +"6382",2015-02-16 01:08:59,20.29,28.5,0,809.5,0.00419374650620399,0 +"6383",2015-02-16 01:09:59,20.29,28.5,0,810,0.00419374650620399,0 +"6384",2015-02-16 01:11:00,20.29,28.5,0,816.5,0.00419374650620399,0 +"6385",2015-02-16 01:12:00,20.2,28.39,0,811,0.00415411595650792,0 +"6386",2015-02-16 01:13:00,20.245,28.4175,0,813.5,0.00416983148695459,0 +"6387",2015-02-16 01:14:00,20.26,28.29,0,820,0.00415487491925253,0 +"6388",2015-02-16 01:14:59,20.29,28.5,0,815.333333333333,0.00419374650620399,0 +"6389",2015-02-16 01:15:59,20.29,28.39,0,817,0.0041774514057978,0 +"6390",2015-02-16 01:17:00,20.29,28.39,0,815.5,0.0041774514057978,0 +"6391",2015-02-16 01:18:00,20.29,28.39,0,822,0.0041774514057978,0 +"6392",2015-02-16 01:19:00,20.29,28.34,0,826,0.00417004482232956,0 +"6393",2015-02-16 01:20:00,20.29,28.39,0,825.5,0.0041774514057978,0 +"6394",2015-02-16 01:21:00,20.245,28.245,0,824.5,0.00414435111183553,0 +"6395",2015-02-16 01:21:59,20.29,28.39,0,823,0.0041774514057978,0 +"6396",2015-02-16 01:23:00,20.29,28.29,0,821,0.00416263841407309,0 +"6397",2015-02-16 01:24:00,20.29,28.29,0,814.5,0.00416263841407309,0 +"6398",2015-02-16 01:25:00,20.29,28.26,0,822.333333333333,0.00415819465321827,0 +"6399",2015-02-16 01:25:59,20.29,28.2,0,828,0.00414930732072526,0 +"6400",2015-02-16 01:27:00,20.29,28.245,0,831.5,0.00415597279644319,0 +"6401",2015-02-16 01:27:59,20.245,28.245,0,831.5,0.00414435111183553,0 +"6402",2015-02-16 01:28:59,20.29,28.23,0,841.333333333333,0.00415375095543611,0 +"6403",2015-02-16 01:30:00,20.23,28.1,0,846.333333333333,0.00411908703143143,0 +"6404",2015-02-16 01:31:00,20.29,28.2,0,852,0.00414930732072526,0 +"6405",2015-02-16 01:32:00,20.29,28.1,0,866,0.00413449566052023,0 +"6406",2015-02-16 01:33:00,20.29,28.1,0,865.5,0.00413449566052023,0 +"6407",2015-02-16 01:34:00,20.29,28.1,0,1018.5,0.00413449566052023,0 +"6408",2015-02-16 01:34:59,20.29,28.05,0,953.5,0.00412709009319372,0 +"6409",2015-02-16 01:36:00,20.29,28.05,0,926,0.00412709009319372,0 +"6410",2015-02-16 01:37:00,20.29,28.1,0,921.333333333333,0.00413449566052023,0 +"6411",2015-02-16 01:38:00,20.29,28.1,0,905,0.00413449566052023,0 +"6412",2015-02-16 01:38:59,20.34,28.05,0,885,0.00413994623182864,0 +"6413",2015-02-16 01:40:00,20.29,28,0,874,0.00411968470104293,0 +"6414",2015-02-16 01:40:59,20.29,28.05,0,870,0.00412709009319372,0 +"6415",2015-02-16 01:41:59,20.29,27.89,0,858,0.00410339345489906,0 +"6416",2015-02-16 01:43:00,20.29,28.025,0,863.5,0.00412338737522175,0 +"6417",2015-02-16 01:44:00,20.29,28,0,862.333333333333,0.00411968470104293,0 +"6418",2015-02-16 01:45:00,20.34,27.89,0,858.5,0.00411617529178165,0 +"6419",2015-02-16 01:46:00,20.39,27.89,0,857,0.00412899225159303,0 +"6420",2015-02-16 01:46:59,20.39,27.89,0,858,0.00412899225159303,0 +"6421",2015-02-16 01:47:59,20.29,27.79,0,859,0.00408858396678811,0 +"6422",2015-02-16 01:49:00,20.39,27.84,0,869,0.00412154092123162,0 +"6423",2015-02-16 01:50:00,20.3566666666667,27.79,0,859.333333333333,0.00410557227766486,0 +"6424",2015-02-16 01:51:00,20.39,27.79,0,853,0.00411408976821918,0 +"6425",2015-02-16 01:52:00,20.39,27.79,0,853,0.00411408976821918,0 +"6426",2015-02-16 01:53:00,20.39,27.79,0,851.5,0.00411408976821918,0 +"6427",2015-02-16 01:53:59,20.39,27.79,0,859.5,0.00411408976821918,0 +"6428",2015-02-16 01:54:59,20.39,27.7,0,859,0.00410067813969595,0 +"6429",2015-02-16 01:56:00,20.39,27.6,0,852,0.00408577700408278,0 +"6430",2015-02-16 01:57:00,20.39,27.7,0,852.5,0.00410067813969595,0 +"6431",2015-02-16 01:58:00,20.39,27.65,0,845,0.00409322748322691,0 +"6432",2015-02-16 01:59:00,20.39,27.7,0,851.5,0.00410067813969595,0 +"6433",2015-02-16 01:59:59,20.39,27.6,0,863,0.00408577700408278,0 +"6434",2015-02-16 02:00:59,20.39,27.6,0,859,0.00408577700408278,0 +"6435",2015-02-16 02:02:00,20.39,27.7,0,860,0.00410067813969595,0 +"6436",2015-02-16 02:03:00,20.39,27.6,0,851.666666666667,0.00408577700408278,0 +"6437",2015-02-16 02:04:00,20.39,27.53,0,853.5,0.00407534663117478,0 +"6438",2015-02-16 02:05:00,20.39,27.5,0,851.333333333333,0.00407087657774391,0 +"6439",2015-02-16 02:06:00,20.39,27.55,0,854.25,0.00407832670225722,0 +"6440",2015-02-16 02:06:59,20.39,27.55,0,852,0.00407832670225722,0 +"6441",2015-02-16 02:08:00,20.39,27.5,0,854,0.00407087657774391,0 +"6442",2015-02-16 02:09:00,20.39,27.4633333333333,0,853,0.00406541326578892,0 +"6443",2015-02-16 02:10:00,20.39,27.5,0,853.5,0.00407087657774391,0 +"6444",2015-02-16 02:10:59,20.39,27.5,0,855,0.00407087657774391,0 +"6445",2015-02-16 02:12:00,20.39,27.5,0,856,0.00407087657774391,0 +"6446",2015-02-16 02:12:59,20.39,27.5,0,855.5,0.00407087657774391,0 +"6447",2015-02-16 02:13:59,20.39,27.39,0,853.666666666667,0.00405448692792252,0 +"6448",2015-02-16 02:15:00,20.39,27.39,0,855.5,0.00405448692792252,0 +"6449",2015-02-16 02:16:00,20.39,27.39,0,853,0.00405448692792252,0 +"6450",2015-02-16 02:17:00,20.39,27.34,0,851.5,0.00404703737076584,0 +"6451",2015-02-16 02:18:00,20.39,27.34,0,853,0.00404703737076584,0 +"6452",2015-02-16 02:19:00,20.39,27.39,0,855,0.00405448692792252,0 +"6453",2015-02-16 02:19:59,20.39,27.39,0,853.666666666667,0.00405448692792252,0 +"6454",2015-02-16 02:21:00,20.39,27.29,0,863,0.00403958799089483,0 +"6455",2015-02-16 02:22:00,20.39,27.29,0,856.5,0.00403958799089483,0 +"6456",2015-02-16 02:23:00,20.39,27.2,0,857,0.00402617955386667,0 +"6457",2015-02-16 02:23:59,20.39,27.2,0,861.5,0.00402617955386667,0 +"6458",2015-02-16 02:25:00,20.39,27.245,0,860,0.00403288370058493,0 +"6459",2015-02-16 02:25:59,20.39,27.29,0,865,0.00403958799089483,0 +"6460",2015-02-16 02:26:59,20.39,27.245,0,864.5,0.00403288370058493,0 +"6461",2015-02-16 02:28:00,20.39,27.2,0,868,0.00402617955386667,0 +"6462",2015-02-16 02:29:00,20.39,27.2,0,858,0.00402617955386667,0 +"6463",2015-02-16 02:30:00,20.39,27.2,0,853,0.00402617955386667,0 +"6464",2015-02-16 02:31:00,20.39,27.2,0,854.5,0.00402617955386667,0 +"6465",2015-02-16 02:31:59,20.39,27.1333333333333,0,859.333333333333,0.00401624774858535,0 +"6466",2015-02-16 02:32:59,20.39,27.1,0,860,0.00401128196411862,0 +"6467",2015-02-16 02:34:00,20.39,27.1,0,864,0.00401128196411862,0 +"6468",2015-02-16 02:35:00,20.39,27.1,0,865,0.00401128196411862,0 +"6469",2015-02-16 02:36:00,20.39,27.1,0,861.666666666667,0.00401128196411862,0 +"6470",2015-02-16 02:37:00,20.39,27.1,0,865.5,0.00401128196411862,0 +"6471",2015-02-16 02:38:00,20.39,27.05,0,852.5,0.00400383343513069,0 +"6472",2015-02-16 02:38:59,20.39,27.1,0,859.5,0.00401128196411862,0 +"6473",2015-02-16 02:39:59,20.39,27.1,0,852,0.00401128196411862,0 +"6474",2015-02-16 02:41:00,20.39,27.1,0,861.666666666667,0.00401128196411862,0 +"6475",2015-02-16 02:42:00,20.39,27.05,0,864.5,0.00400383343513069,0 +"6476",2015-02-16 02:43:00,20.39,27,0,865.333333333333,0.00399638508339172,0 +"6477",2015-02-16 02:44:00,20.34,27.1,0,867,0.00399883272681963,0 +"6478",2015-02-16 02:44:59,20.34,27.15,0,861,0.00400625816764364,0 +"6479",2015-02-16 02:45:59,20.3566666666667,27.1,0,853,0.0040029786796212,0 +"6480",2015-02-16 02:47:00,20.39,27.1,0,856.5,0.00401128196411862,0 +"6481",2015-02-16 02:48:00,20.39,27.1,0,861,0.00401128196411862,0 +"6482",2015-02-16 02:49:00,20.39,27.05,0,862,0.00400383343513069,0 +"6483",2015-02-16 02:50:00,20.39,27,0,857.333333333333,0.00399638508339172,0 +"6484",2015-02-16 02:51:00,20.29,27.1,0,857,0.00398641759029151,0 +"6485",2015-02-16 02:51:59,20.3566666666667,27.1,0,858,0.0040029786796212,0 +"6486",2015-02-16 02:53:00,20.34,27.05,0,864.5,0.00399140746214886,0 +"6487",2015-02-16 02:54:00,20.34,27.05,0,864.5,0.00399140746214886,0 +"6488",2015-02-16 02:55:00,20.39,27,0,864,0.00399638508339172,0 +"6489",2015-02-16 02:55:59,20.39,27,0,863,0.00399638508339172,0 +"6490",2015-02-16 02:57:00,20.39,27,0,863.5,0.00399638508339172,0 +"6491",2015-02-16 02:57:59,20.39,27.1,0,860.666666666667,0.00401128196411862,0 +"6492",2015-02-16 02:58:59,20.39,27,0,865,0.00399638508339172,0 +"6493",2015-02-16 03:00:00,20.39,26.89,0,865,0.00397999933345114,0 +"6494",2015-02-16 03:01:00,20.39,26.89,0,860.5,0.00397999933345114,0 +"6495",2015-02-16 03:02:00,20.39,26.89,0,863,0.00397999933345114,0 +"6496",2015-02-16 03:03:00,20.39,26.89,0,865,0.00397999933345114,0 +"6497",2015-02-16 03:04:00,20.39,26.89,0,863,0.00397999933345114,0 +"6498",2015-02-16 03:04:59,20.39,26.89,0,861,0.00397999933345114,0 +"6499",2015-02-16 03:06:00,20.39,26.89,0,862.5,0.00397999933345114,0 +"6500",2015-02-16 03:07:00,20.39,26.89,0,866,0.00397999933345114,0 +"6501",2015-02-16 03:08:00,20.39,26.89,0,867,0.00397999933345114,0 +"6502",2015-02-16 03:08:59,20.39,26.89,0,873,0.00397999933345114,0 +"6503",2015-02-16 03:10:00,20.39,26.89,0,872,0.00397999933345114,0 +"6504",2015-02-16 03:10:59,20.39,26.89,0,866,0.00397999933345114,0 +"6505",2015-02-16 03:11:59,20.39,26.89,0,863.333333333333,0.00397999933345114,0 +"6506",2015-02-16 03:13:00,20.39,26.79,0,868.5,0.00396510394150388,0 +"6507",2015-02-16 03:14:00,20.39,26.79,0,871,0.00396510394150388,0 +"6508",2015-02-16 03:15:00,20.39,26.76,0,864.666666666667,0.00396063546215054,0 +"6509",2015-02-16 03:16:00,20.39,26.7,0,869,0.00395169869483174,0 +"6510",2015-02-16 03:16:59,20.39,26.7,0,862,0.00395169869483174,0 +"6511",2015-02-16 03:17:59,20.5,26.7,0,868,0.00397879624040084,0 +"6512",2015-02-16 03:19:00,20.39,26.7,0,867.5,0.00395169869483174,0 +"6513",2015-02-16 03:20:00,20.39,26.7,0,864.25,0.00395169869483174,0 +"6514",2015-02-16 03:21:00,20.39,26.7,0,859,0.00395169869483174,0 +"6515",2015-02-16 03:22:00,20.39,26.7,0,860,0.00395169869483174,0 +"6516",2015-02-16 03:23:00,20.39,26.65,0,865.5,0.00394425158365834,0 +"6517",2015-02-16 03:23:59,20.39,26.7,0,866,0.00395169869483174,0 +"6518",2015-02-16 03:24:59,20.39,26.6,0,863,0.0039368046496833,0 +"6519",2015-02-16 03:26:00,20.445,26.65,0,871,0.0039577542811337,0 +"6520",2015-02-16 03:27:00,20.39,26.6,0,868,0.0039368046496833,0 +"6521",2015-02-16 03:28:00,20.39,26.55,0,869.666666666667,0.00392935789290029,0 +"6522",2015-02-16 03:29:00,20.39,26.6,0,866,0.0039368046496833,0 +"6523",2015-02-16 03:29:59,20.39,26.6,0,866.5,0.0039368046496833,0 +"6524",2015-02-16 03:30:59,20.39,26.5,0,868,0.00392191131330298,0 +"6525",2015-02-16 03:32:00,20.39,26.5,0,856,0.00392191131330298,0 +"6526",2015-02-16 03:33:00,20.4266666666667,26.5333333333333,0,860,0.00393583306905001,0 +"6527",2015-02-16 03:34:00,20.39,26.5,0,855,0.00392191131330298,0 +"6528",2015-02-16 03:35:00,20.39,26.5,0,859,0.00392191131330298,0 +"6529",2015-02-16 03:36:00,20.39,26.5,0,854.5,0.00392191131330298,0 +"6530",2015-02-16 03:36:59,20.39,26.445,0,852.5,0.00391372028038788,0 +"6531",2015-02-16 03:38:00,20.39,26.5,0,863.5,0.00392191131330298,0 +"6532",2015-02-16 03:39:00,20.5,26.5,0,869,0.00394880331260596,0 +"6533",2015-02-16 03:40:00,20.39,26.5,0,863,0.00392191131330298,0 +"6534",2015-02-16 03:40:59,20.39,26.5,0,857,0.00392191131330298,0 +"6535",2015-02-16 03:42:00,20.39,26.5,0,860,0.00392191131330298,0 +"6536",2015-02-16 03:42:59,20.39,26.5,0,857.5,0.00392191131330298,0 +"6537",2015-02-16 03:43:59,20.39,26.5,0,857.5,0.00392191131330298,0 +"6538",2015-02-16 03:45:00,20.39,26.39,0,853,0.00390552946185142,0 +"6539",2015-02-16 03:46:00,20.39,26.5,0,859.5,0.00392191131330298,0 +"6540",2015-02-16 03:47:00,20.39,26.445,0,862,0.00391372028038788,0 +"6541",2015-02-16 03:48:00,20.39,26.39,0,858.5,0.00390552946185142,0 +"6542",2015-02-16 03:49:00,20.39,26.39,0,861.333333333333,0.00390552946185142,0 +"6543",2015-02-16 03:49:59,20.39,26.39,0,848,0.00390552946185142,0 +"6544",2015-02-16 03:51:00,20.39,26.39,0,851,0.00390552946185142,0 +"6545",2015-02-16 03:52:00,20.39,26.39,0,858,0.00390552946185142,0 +"6546",2015-02-16 03:53:00,20.39,26.39,0,860,0.00390552946185142,0 +"6547",2015-02-16 03:53:59,20.39,26.39,0,859,0.00390552946185142,0 +"6548",2015-02-16 03:55:00,20.39,26.39,0,860,0.00390552946185142,0 +"6549",2015-02-16 03:55:59,20.39,26.39,0,860.666666666667,0.00390552946185142,0 +"6550",2015-02-16 03:56:59,20.39,26.39,0,868,0.00390552946185142,0 +"6551",2015-02-16 03:58:00,20.39,26.34,0,860,0.00389808344920587,0 +"6552",2015-02-16 03:59:00,20.39,26.39,0,848,0.00390552946185142,0 +"6553",2015-02-16 04:00:00,20.39,26.39,0,856,0.00390552946185142,0 +"6554",2015-02-16 04:01:00,20.39,26.39,0,857,0.00390552946185142,0 +"6555",2015-02-16 04:01:59,20.39,26.39,0,856,0.00390552946185142,0 +"6556",2015-02-16 04:02:59,20.39,26.39,0,851,0.00390552946185142,0 +"6557",2015-02-16 04:04:00,20.39,26.29,0,848,0.00389063761371947,0 +"6558",2015-02-16 04:05:00,20.39,26.365,0,846.5,0.00390180643338336,0 +"6559",2015-02-16 04:06:00,20.39,26.29,0,846,0.00389063761371947,0 +"6560",2015-02-16 04:07:00,20.39,26.29,0,847.5,0.00389063761371947,0 +"6561",2015-02-16 04:08:00,20.39,26.2675,0,842.5,0.00388728704554708,0 +"6562",2015-02-16 04:08:59,20.39,26.29,0,844,0.00389063761371947,0 +"6563",2015-02-16 04:09:59,20.39,26.245,0,846.5,0.00388393651324755,0 +"6564",2015-02-16 04:11:00,20.39,26.23,0,845,0.00388170284497696,0 +"6565",2015-02-16 04:12:00,20.39,26.2,0,844,0.00387723555626482,0 +"6566",2015-02-16 04:13:00,20.39,26.2,0,845,0.00387723555626482,0 +"6567",2015-02-16 04:14:00,20.39,26.2,0,845,0.00387723555626482,0 +"6568",2015-02-16 04:14:59,20.34,26.2,0,847,0.00386520490811982,0 +"6569",2015-02-16 04:15:59,20.39,26.2,0,848,0.00387723555626482,0 +"6570",2015-02-16 04:17:00,20.39,26.2,0,844,0.00387723555626482,0 +"6571",2015-02-16 04:18:00,20.39,26.2,0,845,0.00387723555626482,0 +"6572",2015-02-16 04:19:00,20.39,26.1,0,845,0.00386234505445109,0 +"6573",2015-02-16 04:20:00,20.39,26,0,842,0.00384745526115257,0 +"6574",2015-02-16 04:21:00,20.29,26.2,0,841.5,0.00385320719822783,0 +"6575",2015-02-16 04:21:59,20.29,26.2,0,833,0.00385320719822783,0 +"6576",2015-02-16 04:23:00,20.39,26.1,0,834,0.00386234505445109,0 +"6577",2015-02-16 04:24:00,20.3233333333333,26,0,820.666666666667,0.00383154562485193,0 +"6578",2015-02-16 04:25:00,20.29,26.1,0,816,0.00383840954313481,0 +"6579",2015-02-16 04:25:59,20.29,26.2,0,814.5,0.00385320719822783,0 +"6580",2015-02-16 04:27:00,20.29,26.1333333333333,0,815.333333333333,0.00384334201708179,0 +"6581",2015-02-16 04:27:59,20.29,26.1,0,806.5,0.00383840954313481,0 +"6582",2015-02-16 04:28:59,20.39,26.1,0,803,0.00386234505445109,0 +"6583",2015-02-16 04:30:00,20.29,26.2,0,802,0.00385320719822783,0 +"6584",2015-02-16 04:31:00,20.34,26.1,0,796,0.00385036089418621,0 +"6585",2015-02-16 04:32:00,20.39,26.0666666666667,0,794.333333333333,0.00385738171129683,0 +"6586",2015-02-16 04:33:00,20.39,26,0,798,0.00384745526115257,0 +"6587",2015-02-16 04:34:00,20.29,26,0,798,0.0038236125877759,0 +"6588",2015-02-16 04:34:59,20.39,26,0,800.5,0.00384745526115257,0 +"6589",2015-02-16 04:36:00,20.39,26,0,801,0.00384745526115257,0 +"6590",2015-02-16 04:37:00,20.39,25.9633333333333,0,804,0.00384199584778887,0 +"6591",2015-02-16 04:38:00,20.39,25.945,0,810.5,0.00383926617682466,0 +"6592",2015-02-16 04:38:59,20.39,25.89,0,807,0.0038310773067989,0 +"6593",2015-02-16 04:40:00,20.39,25.89,0,795.5,0.0038310773067989,0 +"6594",2015-02-16 04:40:59,20.39,25.89,0,799,0.0038310773067989,0 +"6595",2015-02-16 04:41:59,20.39,25.89,0,793,0.0038310773067989,0 +"6596",2015-02-16 04:43:00,20.39,25.89,0,796.5,0.0038310773067989,0 +"6597",2015-02-16 04:44:00,20.39,25.84,0,809,0.00382363306546034,0 +"6598",2015-02-16 04:45:00,20.39,25.89,0,802,0.0038310773067989,0 +"6599",2015-02-16 04:46:00,20.34,25.89,0,798,0.0038191907567496,0 +"6600",2015-02-16 04:46:59,20.39,25.84,0,799.5,0.00382363306546034,0 +"6601",2015-02-16 04:47:59,20.34,25.89,0,802,0.0038191907567496,0 +"6602",2015-02-16 04:49:00,20.39,25.79,0,808,0.00381618900121772,0 +"6603",2015-02-16 04:50:00,20.39,25.79,0,801,0.00381618900121772,0 +"6604",2015-02-16 04:51:00,20.39,25.79,0,800,0.00381618900121772,0 +"6605",2015-02-16 04:52:00,20.39,25.79,0,795,0.00381618900121772,0 +"6606",2015-02-16 04:53:00,20.3566666666667,25.79,0,791.333333333333,0.00380829201251369,0 +"6607",2015-02-16 04:53:59,20.39,25.79,0,791,0.00381618900121772,0 +"6608",2015-02-16 04:54:59,20.39,25.79,0,789.5,0.00381618900121772,0 +"6609",2015-02-16 04:56:00,20.39,25.79,0,789.5,0.00381618900121772,0 +"6610",2015-02-16 04:57:00,20.39,25.76,0,784.333333333333,0.00381172264767557,0 +"6611",2015-02-16 04:58:00,20.39,25.79,0,780,0.00381618900121772,0 +"6612",2015-02-16 04:59:00,20.39,25.745,0,781.5,0.00380948949481116,0 +"6613",2015-02-16 04:59:59,20.39,25.79,0,787,0.00381618900121772,0 +"6614",2015-02-16 05:00:59,20.39,25.79,0,786.5,0.00381618900121772,0 +"6615",2015-02-16 05:02:00,20.39,25.79,0,784.333333333333,0.00381618900121772,0 +"6616",2015-02-16 05:03:00,20.39,25.7,0,791,0.00380279013184258,0 +"6617",2015-02-16 05:04:00,20.39,25.745,0,788,0.00380948949481116,0 +"6618",2015-02-16 05:05:00,20.39,25.7,0,787,0.00380279013184258,0 +"6619",2015-02-16 05:06:00,20.39,25.7,0,781,0.00380279013184258,0 +"6620",2015-02-16 05:06:59,20.39,25.7,0,784,0.00380279013184258,0 +"6621",2015-02-16 05:08:00,20.39,25.6666666666667,0,781.666666666667,0.0037978277332292,0 +"6622",2015-02-16 05:09:00,20.445,25.7,0,781.5,0.00381580559990668,0 +"6623",2015-02-16 05:10:00,20.39,25.6,0,782.5,0.00378790317209926,0 +"6624",2015-02-16 05:10:59,20.39,25.6,0,781,0.00378790317209926,0 +"6625",2015-02-16 05:12:00,20.4633333333333,25.6666666666667,0,778,0.00381516761681429,0 +"6626",2015-02-16 05:12:59,20.5,25.7,0,786.5,0.00382886033733085,0 +"6627",2015-02-16 05:13:59,20.5,25.65,0,784.5,0.00382136542758715,0 +"6628",2015-02-16 05:15:00,20.4266666666667,25.6333333333333,0,786.333333333333,0.00380151526205359,0 +"6629",2015-02-16 05:16:00,20.4266666666667,25.6333333333333,0,792.666666666667,0.00380151526205359,0 +"6630",2015-02-16 05:17:00,20.39,25.55,0,791,0.00378045995782916,0 +"6631",2015-02-16 05:18:00,20.445,25.6,0,793,0.00380086737844103,0 +"6632",2015-02-16 05:19:00,20.4266666666667,25.6,0,796,0.00379654163550396,0 +"6633",2015-02-16 05:19:59,20.39,25.55,0,797.5,0.00378045995782916,0 +"6634",2015-02-16 05:21:00,20.445,25.65,0,797.5,0.00380833640002897,0 +"6635",2015-02-16 05:22:00,20.39,25.6,0,798.5,0.00378790317209926,0 +"6636",2015-02-16 05:23:00,20.39,25.6,0,795.5,0.00378790317209926,0 +"6637",2015-02-16 05:23:59,20.39,25.6,0,799,0.00378790317209926,0 +"6638",2015-02-16 05:25:00,20.39,25.6,0,795,0.00378790317209926,0 +"6639",2015-02-16 05:25:59,20.39,25.5,0,794,0.00377301692061835,0 +"6640",2015-02-16 05:26:59,20.39,25.5,0,788.666666666667,0.00377301692061835,0 +"6641",2015-02-16 05:28:00,20.39,25.5,0,791.5,0.00377301692061835,0 +"6642",2015-02-16 05:29:00,20.39,25.5,0,793,0.00377301692061835,0 +"6643",2015-02-16 05:30:00,20.39,25.5,0,798,0.00377301692061835,0 +"6644",2015-02-16 05:31:00,20.445,25.445,0,798,0.00377771454448103,0 +"6645",2015-02-16 05:31:59,20.39,25.39,0,792,0.00375664286197212,0 +"6646",2015-02-16 05:32:59,20.39,25.39,0,790.5,0.00375664286197212,0 +"6647",2015-02-16 05:34:00,20.5,25.39,0,792,0.00378239479056467,0 +"6648",2015-02-16 05:35:00,20.5,25.39,0,793,0.00378239479056467,0 +"6649",2015-02-16 05:36:00,20.5,25.39,0,789,0.00378239479056467,0 +"6650",2015-02-16 05:37:00,20.39,25.29,0,796,0.00374175809767778,0 +"6651",2015-02-16 05:38:00,20.445,25.29,0,794.5,0.0037545634236343,0 +"6652",2015-02-16 05:38:59,20.5,25.29,0,792.5,0.00376740737633744,0 +"6653",2015-02-16 05:39:59,20.445,25.29,0,795,0.0037545634236343,0 +"6654",2015-02-16 05:41:00,20.39,25.245,0,796,0.00373506018476785,0 +"6655",2015-02-16 05:42:00,20.445,25.245,0,800.5,0.00374784245133256,0 +"6656",2015-02-16 05:43:00,20.5,25.29,0,798.5,0.00376740737633744,0 +"6657",2015-02-16 05:44:00,20.5,25.29,0,798,0.00376740737633744,0 +"6658",2015-02-16 05:44:59,20.39,25.245,0,801,0.00373506018476785,0 +"6659",2015-02-16 05:45:59,20.4633333333333,25.29,0,796,0.00375884044438521,0 +"6660",2015-02-16 05:47:00,20.39,25.2,0,801.666666666667,0.00372836241524473,0 +"6661",2015-02-16 05:48:00,20.5,25.29,0,800,0.00376740737633744,0 +"6662",2015-02-16 05:49:00,20.445,25.29,0,799,0.0037545634236343,0 +"6663",2015-02-16 05:50:00,20.445,25.245,0,789.5,0.00374784245133256,0 +"6664",2015-02-16 05:51:00,20.5,25.29,0,800,0.00376740737633744,0 +"6665",2015-02-16 05:51:59,20.39,25.2,0,802,0.00372836241524473,0 +"6666",2015-02-16 05:53:00,20.4266666666667,25.3233333333333,0,801,0.00375526358614144,0 +"6667",2015-02-16 05:54:00,20.39,25.245,0,792.5,0.00373506018476785,0 +"6668",2015-02-16 05:55:00,20.39,25.245,0,794.5,0.00373506018476785,0 +"6669",2015-02-16 05:55:59,20.39,25.26,0,793.666666666667,0.0037372928064724,0 +"6670",2015-02-16 05:57:00,20.39,25.29,0,792.5,0.00374175809767778,0 +"6671",2015-02-16 05:57:59,20.39,25.2,0,793,0.00372836241524473,0 +"6672",2015-02-16 05:58:59,20.445,25.245,0,795,0.00374784245133256,0 +"6673",2015-02-16 06:00:00,20.39,25.245,0,796,0.00373506018476785,0 +"6674",2015-02-16 06:01:00,20.39,25.245,0,795.5,0.00373506018476785,0 +"6675",2015-02-16 06:02:00,20.39,25.2225,0,797,0.00373171128208323,0 +"6676",2015-02-16 06:03:00,20.39,25.2,0,796.5,0.00372836241524473,0 +"6677",2015-02-16 06:04:00,20.445,25.245,0,795.5,0.00374784245133256,0 +"6678",2015-02-16 06:04:59,20.39,25.245,0,799,0.00373506018476785,0 +"6679",2015-02-16 06:06:00,20.39,25.2,0,802.666666666667,0.00372836241524473,0 +"6680",2015-02-16 06:07:00,20.39,25.2,0,804,0.00372836241524473,0 +"6681",2015-02-16 06:08:00,20.5,25.29,0,805,0.00376740737633744,0 +"6682",2015-02-16 06:08:59,20.39,25.1666666666667,0,806.333333333333,0.00372340119692832,0 +"6683",2015-02-16 06:10:00,20.39,25.1666666666667,0,804,0.00372340119692832,0 +"6684",2015-02-16 06:10:59,20.39,25.15,0,801.5,0.00372092061727204,0 +"6685",2015-02-16 06:11:59,20.445,25.15,0,806,0.00373365420613652,0 +"6686",2015-02-16 06:13:00,20.445,25.15,0,795,0.00373365420613652,0 +"6687",2015-02-16 06:14:00,20.39,25.1,0,798,0.00371347899630811,0 +"6688",2015-02-16 06:15:00,20.39,25.1,0,797,0.00371347899630811,0 +"6689",2015-02-16 06:16:00,20.5,25.2,0,800,0.00375391931731873,0 +"6690",2015-02-16 06:16:59,20.39,25.1,0,801,0.00371347899630811,0 +"6691",2015-02-16 06:17:59,20.39,25.1,0,804.333333333333,0.00371347899630811,0 +"6692",2015-02-16 06:19:00,20.39,25.1,0,805,0.00371347899630811,0 +"6693",2015-02-16 06:20:00,20.39,25.1,0,805,0.00371347899630811,0 +"6694",2015-02-16 06:21:00,20.39,25.1,0,801,0.00371347899630811,0 +"6695",2015-02-16 06:22:00,20.39,25.1,0,799,0.00371347899630811,0 +"6696",2015-02-16 06:23:00,20.39,25.1,0,797,0.00371347899630811,0 +"6697",2015-02-16 06:23:59,20.39,25.1,0,801,0.00371347899630811,0 +"6698",2015-02-16 06:24:59,20.39,25.0333333333333,0,799.333333333333,0.00370355711035889,0 +"6699",2015-02-16 06:26:00,20.39,25,0,801,0.00369859628538123,0 +"6700",2015-02-16 06:27:00,20.39,25,0,803.5,0.00369859628538123,0 +"6701",2015-02-16 06:28:00,20.39,25,0,809,0.00369859628538123,0 +"6702",2015-02-16 06:29:00,20.39,25,0,808,0.00369859628538123,0 +"6703",2015-02-16 06:29:59,20.39,25,0,800,0.00369859628538123,0 +"6704",2015-02-16 06:30:59,20.39,25,0,804,0.00369859628538123,0 +"6705",2015-02-16 06:32:00,20.39,25,0,801,0.00369859628538123,0 +"6706",2015-02-16 06:33:00,20.39,25,0,797,0.00369859628538123,0 +"6707",2015-02-16 06:34:00,20.39,25,0,797,0.00369859628538123,0 +"6708",2015-02-16 06:35:00,20.39,25,0,802,0.00369859628538123,0 +"6709",2015-02-16 06:36:00,20.39,25,0,803.5,0.00369859628538123,0 +"6710",2015-02-16 06:36:59,20.39,25,0,805,0.00369859628538123,0 +"6711",2015-02-16 06:38:00,20.39,25,0,803,0.00369859628538123,0 +"6712",2015-02-16 06:39:00,20.39,25,0,807.5,0.00369859628538123,0 +"6713",2015-02-16 06:40:00,20.39,25,0,810,0.00369859628538123,0 +"6714",2015-02-16 06:40:59,20.39,24.945,0,809,0.00369041109614231,0 +"6715",2015-02-16 06:42:00,20.39,25,0,810.5,0.00369859628538123,0 +"6716",2015-02-16 06:42:59,20.39,24.945,0,807,0.00369041109614231,0 +"6717",2015-02-16 06:43:59,20.39,25,0,801,0.00369859628538123,0 +"6718",2015-02-16 06:45:00,20.39,25,0,801.5,0.00369859628538123,0 +"6719",2015-02-16 06:46:00,20.39,24.945,0,804,0.00369041109614231,0 +"6720",2015-02-16 06:47:00,20.39,24.89,0,810,0.00368222612105264,0 +"6721",2015-02-16 06:48:00,20.39,24.89,0,808.5,0.00368222612105264,0 +"6722",2015-02-16 06:49:00,20.39,24.89,0,809.333333333333,0.00368222612105264,0 +"6723",2015-02-16 06:49:59,20.39,24.89,0,804.5,0.00368222612105264,0 +"6724",2015-02-16 06:51:00,20.39,24.79,0,807,0.00366734489678181,0 +"6725",2015-02-16 06:52:00,20.39,24.89,0,809,0.00368222612105264,0 +"6726",2015-02-16 06:53:00,20.39,24.79,0,808.5,0.00366734489678181,0 +"6727",2015-02-16 06:53:59,20.39,24.84,0,814.5,0.00367478542043242,0 +"6728",2015-02-16 06:55:00,20.39,24.79,0,815,0.00366734489678181,0 +"6729",2015-02-16 06:55:59,20.39,24.79,0,815,0.00366734489678181,0 +"6730",2015-02-16 06:56:59,20.39,24.79,0,816,0.00366734489678181,0 +"6731",2015-02-16 06:58:00,20.39,24.79,0,807,0.00366734489678181,0 +"6732",2015-02-16 06:59:00,20.39,24.79,0,801.5,0.00366734489678181,0 +"6733",2015-02-16 07:00:00,20.39,24.79,0,807.5,0.00366734489678181,0 +"6734",2015-02-16 07:01:00,20.39,24.79,0,813.5,0.00366734489678181,0 +"6735",2015-02-16 07:01:59,20.39,24.79,0,820.5,0.00366734489678181,0 +"6736",2015-02-16 07:02:59,20.39,24.79,0,815,0.00366734489678181,0 +"6737",2015-02-16 07:04:00,20.39,24.79,0,811,0.00366734489678181,0 +"6738",2015-02-16 07:05:00,20.39,24.7,0,810,0.00365395240015394,0 +"6739",2015-02-16 07:06:00,20.39,24.79,0,811.5,0.00366734489678181,0 +"6740",2015-02-16 07:07:00,20.39,24.7,0,808,0.00365395240015394,0 +"6741",2015-02-16 07:08:00,20.39,24.745,0,812,0.00366064857680004,0 +"6742",2015-02-16 07:08:59,20.39,24.7225,0,811.25,0.00365730047056032,0 +"6743",2015-02-16 07:09:59,20.39,24.79,0,809.5,0.00366734489678181,0 +"6744",2015-02-16 07:11:00,20.39,24.7,0,806,0.00365395240015394,0 +"6745",2015-02-16 07:12:00,20.39,24.7,0,806,0.00365395240015394,0 +"6746",2015-02-16 07:13:00,20.39,24.7,0,809.333333333333,0.00365395240015394,0 +"6747",2015-02-16 07:14:00,20.39,24.7,0,813.5,0.00365395240015394,0 +"6748",2015-02-16 07:14:59,20.39,24.7,0,816.5,0.00365395240015394,0 +"6749",2015-02-16 07:15:59,20.39,24.7,0,817.333333333333,0.00365395240015394,0 +"6750",2015-02-16 07:17:00,20.39,24.7,0,813,0.00365395240015394,0 +"6751",2015-02-16 07:18:00,20.39,24.7,0,811,0.00365395240015394,0 +"6752",2015-02-16 07:19:00,20.39,24.7,0,811.5,0.00365395240015394,0 +"6753",2015-02-16 07:20:00,20.39,24.65,0,809.5,0.00364651237198463,0 +"6754",2015-02-16 07:21:00,20.39,24.6,0,806,0.00363907252076092,0 +"6755",2015-02-16 07:21:59,20.39,24.6,0,802.5,0.00363907252076092,0 +"6756",2015-02-16 07:23:00,20.39,24.65,0,802.5,0.00364651237198463,0 +"6757",2015-02-16 07:24:00,20.39,24.65,0,805,0.00364651237198463,0 +"6758",2015-02-16 07:25:00,20.39,24.6,0,806,0.00363907252076092,0 +"6759",2015-02-16 07:25:59,20.39,24.6,0,809,0.00363907252076092,0 +"6760",2015-02-16 07:27:00,20.39,24.6,0,809,0.00363907252076092,0 +"6761",2015-02-16 07:27:59,20.39,24.6,0,803.5,0.00363907252076092,0 +"6762",2015-02-16 07:28:59,20.39,24.6,0,805.333333333333,0.00363907252076092,0 +"6763",2015-02-16 07:30:00,20.39,24.6,0,805,0.00363907252076092,0 +"6764",2015-02-16 07:31:00,20.39,24.55,0,805.5,0.00363163284647652,0 +"6765",2015-02-16 07:32:00,20.39,24.6,0,806.5,0.00363907252076092,0 +"6766",2015-02-16 07:33:00,20.39,24.6,0,807,0.00363907252076092,0 +"6767",2015-02-16 07:34:00,20.39,24.5,0,808,0.0036241933491251,0 +"6768",2015-02-16 07:34:59,20.39,24.6,0,813,0.00363907252076092,0 +"6769",2015-02-16 07:36:00,20.39,24.6,0,806.333333333333,0.00363907252076092,0 +"6770",2015-02-16 07:37:00,20.39,24.55,0,803.666666666667,0.00363163284647652,0 +"6771",2015-02-16 07:38:00,20.39,24.5,0,814,0.0036241933491251,0 +"6772",2015-02-16 07:38:59,20.39,24.5,0,816.5,0.0036241933491251,0 +"6773",2015-02-16 07:40:00,20.39,24.5,0,816,0.0036241933491251,0 +"6774",2015-02-16 07:40:59,20.39,24.5,0,815,0.0036241933491251,0 +"6775",2015-02-16 07:41:59,20.39,24.5,0,813,0.0036241933491251,0 +"6776",2015-02-16 07:43:00,20.39,24.5,0,811,0.0036241933491251,0 +"6777",2015-02-16 07:44:00,20.39,24.5,0,806,0.0036241933491251,0 +"6778",2015-02-16 07:45:00,20.39,24.39,0,813.5,0.003607827077725,0 +"6779",2015-02-16 07:46:00,20.39,24.39,0,815.5,0.003607827077725,0 +"6780",2015-02-16 07:46:59,20.39,24.5,0,811.333333333333,0.0036241933491251,0 +"6781",2015-02-16 07:47:59,20.39,24.39,0,818,0.003607827077725,0 +"6782",2015-02-16 07:49:00,20.39,24.4633333333333,0,815,0.00361873783018115,0 +"6783",2015-02-16 07:50:00,20.39,24.39,0,815,0.003607827077725,0 +"6784",2015-02-16 07:51:00,20.39,24.4633333333333,0,820.666666666667,0.00361873783018115,0 +"6785",2015-02-16 07:52:00,20.39,24.5,0,820,0.0036241933491251,0 +"6786",2015-02-16 07:53:00,20.39,24.4725,0,813.75,0.00362010170099722,0 +"6787",2015-02-16 07:53:59,20.39,24.445,0,814.5,0.00361601010638861,0 +"6788",2015-02-16 07:54:59,20.39,24.39,0,823,0.003607827077725,0 +"6789",2015-02-16 07:56:00,20.39,24.39,0,822,0.003607827077725,0 +"6790",2015-02-16 07:57:00,20.39,24.39,0,821,0.003607827077725,0 +"6791",2015-02-16 07:58:00,20.39,24.39,0,820,0.003607827077725,0 +"6792",2015-02-16 07:59:00,20.39,24.39,0,817.666666666667,0.003607827077725,0 +"6793",2015-02-16 07:59:59,20.39,24.39,0,816.5,0.003607827077725,0 +"6794",2015-02-16 08:00:59,20.39,24.39,0,814,0.003607827077725,0 +"6795",2015-02-16 08:02:00,20.39,24.39,0,817.5,0.003607827077725,0 +"6796",2015-02-16 08:03:00,20.39,24.29,0,817.5,0.00359294939221495,0 +"6797",2015-02-16 08:04:00,20.39,24.29,0,825,0.00359294939221495,0 +"6798",2015-02-16 08:05:00,20.39,24.29,0,823.666666666667,0.00359294939221495,0 +"6799",2015-02-16 08:06:00,20.39,24.29,0,822,0.00359294939221495,0 +"6800",2015-02-16 08:06:59,20.39,24.29,0,816.5,0.00359294939221495,0 +"6801",2015-02-16 08:08:00,20.39,24.34,0,815,0.00360038814651673,0 +"6802",2015-02-16 08:09:00,20.39,24.29,0,821.666666666667,0.00359294939221495,0 +"6803",2015-02-16 08:10:00,20.39,24.29,0,821.5,0.00359294939221495,0 +"6804",2015-02-16 08:10:59,20.39,24.29,0,826.5,0.00359294939221495,0 +"6805",2015-02-16 08:12:00,20.39,24.29,0,826.333333333333,0.00359294939221495,0 +"6806",2015-02-16 08:12:59,20.39,24.29,0,825.666666666667,0.00359294939221495,0 +"6807",2015-02-16 08:13:59,20.39,24.29,0,813.5,0.00359294939221495,0 +"6808",2015-02-16 08:15:00,20.39,24.29,0,809,0.00359294939221495,0 +"6809",2015-02-16 08:16:00,20.39,24.29,0,818.333333333333,0.00359294939221495,0 +"6810",2015-02-16 08:17:00,20.39,24.29,0,818.666666666667,0.00359294939221495,0 +"6811",2015-02-16 08:18:00,20.39,24.29,0,824.5,0.00359294939221495,0 +"6812",2015-02-16 08:19:00,20.39,24.29,0,830,0.00359294939221495,0 +"6813",2015-02-16 08:19:59,20.39,24.29,7,826,0.00359294939221495,0 +"6814",2015-02-16 08:21:00,20.39,24.29,4.66666666666667,822.333333333333,0.00359294939221495,0 +"6815",2015-02-16 08:22:00,20.39,24.29,4.66666666666667,823.666666666667,0.00359294939221495,0 +"6816",2015-02-16 08:23:00,20.39,24.29,7,826.25,0.00359294939221495,0 +"6817",2015-02-16 08:23:59,20.39,24.29,14,828,0.00359294939221495,0 +"6818",2015-02-16 08:25:00,20.39,24.29,14,829,0.00359294939221495,0 +"6819",2015-02-16 08:25:59,20.39,24.29,14,828.333333333333,0.00359294939221495,0 +"6820",2015-02-16 08:26:59,20.39,24.29,14,826.5,0.00359294939221495,0 +"6821",2015-02-16 08:28:00,20.39,24.29,14,825.5,0.00359294939221495,0 +"6822",2015-02-16 08:29:00,20.39,24.29,14,819,0.00359294939221495,0 +"6823",2015-02-16 08:30:00,20.39,24.29,14,819,0.00359294939221495,0 +"6824",2015-02-16 08:31:00,20.445,24.34,14,823,0.003612706872346,0 +"6825",2015-02-16 08:31:59,20.39,24.29,14,828.666666666667,0.00359294939221495,0 +"6826",2015-02-16 08:32:59,20.39,24.29,14,822.5,0.00359294939221495,0 +"6827",2015-02-16 08:34:00,20.39,24.29,14,823.5,0.00359294939221495,0 +"6828",2015-02-16 08:35:00,20.39,24.29,14,826,0.00359294939221495,0 +"6829",2015-02-16 08:36:00,20.39,24.29,7,833.5,0.00359294939221495,0 +"6830",2015-02-16 08:37:00,20.39,24.29,14,829,0.00359294939221495,0 +"6831",2015-02-16 08:38:00,20.39,24.29,14,828,0.00359294939221495,0 +"6832",2015-02-16 08:38:59,20.39,24.29,7,830,0.00359294939221495,0 +"6833",2015-02-16 08:39:59,20.4266666666667,24.3233333333333,9.33333333333333,828,0.00360611121836855,0 +"6834",2015-02-16 08:41:00,20.39,24.29,14,827,0.00359294939221495,0 +"6835",2015-02-16 08:42:00,20.445,24.34,292.25,831,0.003612706872346,0 +"6836",2015-02-16 08:43:00,20.5,24.445,433,835.5,0.00364079238311689,1 +"6837",2015-02-16 08:44:00,20.4633333333333,24.6,414.333333333333,841,0.0036556833355373,1 +"6838",2015-02-16 08:44:59,20.5,24.6,397,851.75,0.00366401378112657,1 +"6839",2015-02-16 08:45:59,20.5,24.775,389,857,0.00369023356040756,1 +"6840",2015-02-16 08:47:00,20.5,25.05,389,856.5,0.00373144051102961,0 +"6841",2015-02-16 08:48:00,20.5,25.025,397,870.75,0.00372769420032785,0 +"6842",2015-02-16 08:49:00,20.6,25.05,405,869,0.00375466720570366,0 +"6843",2015-02-16 08:50:00,20.55,25.1,405,872.5,0.00375055415705833,0 +"6844",2015-02-16 08:51:00,20.6,25.2,405,871.5,0.0037772867780388,0 +"6845",2015-02-16 08:51:59,20.6,25.2,405,875.75,0.0037772867780388,1 +"6846",2015-02-16 08:53:00,20.6,25.29,405,881.666666666667,0.00379085930639592,1 +"6847",2015-02-16 08:54:00,20.6,25.29,405,883.5,0.00379085930639592,1 +"6848",2015-02-16 08:55:00,20.6333333333333,25.36,399.666666666667,879.333333333333,0.0038092839710094,1 +"6849",2015-02-16 08:55:59,20.65,25.445,389,874.25,0.00382608280883351,1 +"6850",2015-02-16 08:57:00,20.675,25.5475,393,882.333333333333,0.0038475505667833,1 +"6851",2015-02-16 08:57:59,20.675,25.575,393,885.8,0.00385171781803991,1 +"6852",2015-02-16 08:58:59,20.7,25.65,405,884.5,0.00386907569703369,1 +"6853",2015-02-16 09:00:00,20.7,25.7,401,889.25,0.00387666476140182,1 +"6854",2015-02-16 09:01:00,20.7,25.73,399.666666666667,891.666666666667,0.00388121828836473,1 +"6855",2015-02-16 09:02:00,20.7,25.79,405,899,0.00389032554106686,1 +"6856",2015-02-16 09:03:00,20.745,25.79,397,901.75,0.00390119218312941,1 +"6857",2015-02-16 09:04:00,20.76,25.79,405,905,0.00390482034069078,1 +"6858",2015-02-16 09:04:59,20.79,25.865,405,897.5,0.00392353409893415,1 +"6859",2015-02-16 09:06:00,20.79,25.79,394.5,905,0.00391208558374589,1 +"6860",2015-02-16 09:07:00,20.79,25.79,405.666666666667,899,0.00391208558374589,1 +"6861",2015-02-16 09:08:00,20.79,26.065,399,901.75,0.00395406552037525,1 +"6862",2015-02-16 09:08:59,20.79,26.46,399,933.333333333333,0.00401437382894296,1 +"6863",2015-02-16 09:10:00,20.79,26.52,402.75,956.75,0.0040235356013603,1 +"6864",2015-02-16 09:10:59,20.84,26.27,414,950.5,0.00399772730801216,1 +"6865",2015-02-16 09:11:59,20.89,27.15,414,943.5,0.00414535270259246,1 +"6866",2015-02-16 09:13:00,20.89,26.65,421.5,957.5,0.00406851168014064,1 +"6867",2015-02-16 09:14:00,20.89,26.7925,414,963.5,0.00409040944987653,1 +"6868",2015-02-16 09:15:00,20.89,26.9175,424,968.25,0.00410961928105323,1 +"6869",2015-02-16 09:16:00,20.945,26.89,426.5,975.5,0.00411939681469699,1 +"6870",2015-02-16 09:16:59,21,26.89,419,972.75,0.00413344273327552,1 +"6871",2015-02-16 09:17:59,20.9633333333333,26.9633333333333,422.333333333333,983.333333333333,0.00413539588839584,1 +"6872",2015-02-16 09:19:00,21,27.05,422.75,998,0.00415820182988547,1 +"6873",2015-02-16 09:20:00,21,27.075,419,991.75,0.00416207061561013,1 +"6874",2015-02-16 09:21:00,21,27.1,419,990.5,0.0041659394491425,1 +"6875",2015-02-16 09:22:00,21,27.1,424,995,0.0041659394491425,1 +"6876",2015-02-16 09:23:00,21.025,27.1975,424,999.5,0.00418750097298635,1 +"6877",2015-02-16 09:23:59,21,27.1966666666667,424,1001,0.00418089938863476,1 +"6878",2015-02-16 09:24:59,21.05,27.3225,429,1008.5,0.00421338858712705,1 +"6879",2015-02-16 09:26:00,21.1,27.6,434,1014.33333333333,0.00426965889490803,1 +"6880",2015-02-16 09:27:00,21.1,27.4725,439,1020,0.004249800163648,1 +"6881",2015-02-16 09:28:00,21.1,27.39,444,1014.5,0.00423695106745956,1 +"6882",2015-02-16 09:29:00,21.1,27.3233333333333,447.333333333333,1014,0.00422656834460783,1 +"6883",2015-02-16 09:29:59,21.1,27.1,444,1010.75,0.00419178873143713,1 +"6884",2015-02-16 09:30:59,21.15,27.2675,442.75,1009.5,0.00423093200201056,1 +"6885",2015-02-16 09:32:00,21.1,27.34,456.5,1017.5,0.00422916399304422,1 +"6886",2015-02-16 09:33:00,21.14,27.274,456.25,1019.5,0.00422933216334201,1 +"6887",2015-02-16 09:34:00,21.1666666666667,27.1633333333333,470.25,1018,0.00421900358338038,1 +"6888",2015-02-16 09:35:00,21.175,27.2,458.25,1018.75,0.00422691378354773,1 +"6889",2015-02-16 09:36:00,21.2,27.1,464.25,1012.75,0.00421777940467497,1 +"6890",2015-02-16 09:36:59,21.2,26.995,468,1009.25,0.0042013270725151,1 +"6891",2015-02-16 09:38:00,21.29,27.1,484,1008.5,0.00424129245162486,1 +"6892",2015-02-16 09:39:00,21.23,27.1633333333333,489,1007.33333333333,0.00423554686027928,1 +"6893",2015-02-16 09:40:00,21.29,27.025,478,1010.5,0.00422947474206899,1 +"6894",2015-02-16 09:40:59,21.29,27.05,488,1006,0.00423341392902945,1 +"6895",2015-02-16 09:42:00,21.29,27.125,489.25,1000.25,0.00424523178726166,1 +"6896",2015-02-16 09:42:59,21.29,27.1,502,995,0.00424129245162486,1 +"6897",2015-02-16 09:43:59,21.29,27.22,498.25,992.25,0.00426020171468262,1 +"6898",2015-02-16 09:45:00,21.29,27.2933333333333,509.333333333333,1001,0.00427175793760176,1 +"6899",2015-02-16 09:46:00,21.315,27.1975,515.5,1004.5,0.004263231924701,1 +"6900",2015-02-16 09:47:00,21.39,27.1333333333333,530.666666666667,997.333333333333,0.00427283881182427,1 +"6901",2015-02-16 09:48:00,21.445,27.1,537.25,1004.25,0.00428205829929974,1 +"6902",2015-02-16 09:49:00,21.4725,27.27,556.5,1006.75,0.00431642088070509,1 +"6903",2015-02-16 09:49:59,21.5,27.2,575,1010.5,0.00431257102305466,1 +"6904",2015-02-16 09:51:00,21.5,27.26,571.333333333333,1015.33333333333,0.00432215015142084,1 +"6905",2015-02-16 09:52:00,21.5,27.175,576,1018,0.0043085798060472,1 +"6906",2015-02-16 09:53:00,21.6,27.2,554,1021.5,0.00433923334534173,1 +"6907",2015-02-16 09:53:59,21.62,27.18,544.5,1018.75,0.00434136638128134,1 +"6908",2015-02-16 09:55:00,21.6,26.8966666666667,534.25,1019.5,0.00429050858808632,1 +"6909",2015-02-16 09:55:59,21.6,26.8566666666667,536.333333333333,1009,0.00428408391111665,1 +"6910",2015-02-16 09:56:59,21.7,27.15,536,1002,0.00435795893155244,1 +"6911",2015-02-16 09:58:00,21.675,26.87,549.75,1006,0.00430607038588876,1 +"6912",2015-02-16 09:59:00,21.7,26.8933333333333,541,999.666666666667,0.00431647439712608,1 +"6913",2015-02-16 10:00:00,21.65,27,543,1003,0.00432039209995011,1 +"6914",2015-02-16 10:01:00,21.7,27.125,528,997.75,0.00435391798857871,1 +"6915",2015-02-16 10:01:59,21.7,26.9966666666667,528.333333333333,995.333333333333,0.00433317530208927,1 +"6916",2015-02-16 10:02:59,21.7,26.9633333333333,529.333333333333,996,0.00432778781607679,1 +"6917",2015-02-16 10:04:00,21.675,26.7,493,979.75,0.00427863951511892,1 +"6918",2015-02-16 10:05:00,21.7,26.6266666666667,489,946,0.00427337940220683,1 +"6919",2015-02-16 10:06:00,21.7,27.03,470,943.333333333333,0.00433856288078566,1 +"6920",2015-02-16 10:07:00,21.675,26.9425,461.5,978.75,0.00431776957640475,1 +"6921",2015-02-16 10:08:00,21.7,26.8225,454,985.5,0.00430502671064695,1 +"6922",2015-02-16 10:08:59,21.7,26.8566666666667,464,973,0.0043105484836449,1 +"6923",2015-02-16 10:09:59,21.675,26.8925,465.25,956.5,0.00430970112237927,1 +"6924",2015-02-16 10:11:00,21.6,27.0333333333333,454,965,0.00431246056232172,1 +"6925",2015-02-16 10:12:00,21.6,26.8225,457.75,968,0.00427859627058436,1 +"6926",2015-02-16 10:13:00,21.6,27.125,460.25,963.5,0.00432718530973735,1 +"6927",2015-02-16 10:14:00,21.6,26.945,461.5,980,0.00429827191529313,1 +"6928",2015-02-16 10:14:59,21.5333333333333,27.1333333333333,462.333333333333,976.333333333333,0.00431077718391187,1 +"6929",2015-02-16 10:15:59,21.5,27.025,449,976.666666666667,0.0042846335722016,1 +"6930",2015-02-16 10:17:00,21.525,26.9175,457,969.5,0.00427405518985086,1 +"6931",2015-02-16 10:18:00,21.525,27.09,457.75,964.8,0.00430163477086233,1 +"6932",2015-02-16 10:19:00,21.5,27.1333333333333,454,978.666666666667,0.0043019278907415,1 +"6933",2015-02-16 10:20:00,21.5,27.1,454,968.5,0.00429660646023041,1 +"6934",2015-02-16 10:21:00,21.5,27.1725,450.25,964.5,0.00430818068714422,1 +"6935",2015-02-16 10:21:59,21.5,27.2225,439,972,0.00431616316185453,1 +"6936",2015-02-16 10:23:00,21.5,27.39,439,972,0.00434290593478743,1 +"6937",2015-02-16 10:24:00,21.4633333333333,27.26,446,974.666666666667,0.00431238845580599,1 +"6938",2015-02-16 10:25:00,21.4266666666667,27.1666666666667,453,960.666666666667,0.00428781317579773,1 +"6939",2015-02-16 10:25:59,21.445,27.27,439,969.75,0.00430910601218316,1 +"6940",2015-02-16 10:27:00,21.4175,27.1725,439,968.75,0.00428631561139447,1 +"6941",2015-02-16 10:27:59,21.445,27.34,454,964.5,0.00432024398478673,1 +"6942",2015-02-16 10:28:59,21.4175,27.34,446.5,972.75,0.00431292104533065,1 +"6943",2015-02-16 10:30:00,21.39,27.3566666666667,439,974.333333333333,0.00430825196979949,1 +"6944",2015-02-16 10:31:00,21.39,27.2675,449.5,975,0.00429411265405758,1 +"6945",2015-02-16 10:32:00,21.39,27.05,439,965,0.00425962597282046,1 +"6946",2015-02-16 10:33:00,21.365,27.2175,442.75,964.5,0.00427957672773023,1 +"6947",2015-02-16 10:34:00,21.3566666666667,27.3566666666667,449,965.666666666667,0.00429939815050746,1 +"6948",2015-02-16 10:34:59,21.365,27.365,454,976.5,0.00430292951183441,1 +"6949",2015-02-16 10:36:00,21.365,27.2675,454,979.25,0.00428749273061741,1 +"6950",2015-02-16 10:37:00,21.39,27.2933333333333,459,975,0.00429820902564163,1 +"6951",2015-02-16 10:38:00,21.39,27.2675,469,965.5,0.00429411265405758,1 +"6952",2015-02-16 10:38:59,21.39,27.29,459,972,0.00429768045855521,1 +"6953",2015-02-16 10:40:00,21.39,27.29,462.333333333333,969.666666666667,0.00429768045855521,1 +"6954",2015-02-16 10:40:59,21.39,27.315,459,962.25,0.00430164473345027,1 +"6955",2015-02-16 10:41:59,21.39,27.3933333333333,462.333333333333,963.333333333333,0.00431406645310576,1 +"6956",2015-02-16 10:43:00,21.39,27.39,459,972.75,0.00431353785925312,1 +"6957",2015-02-16 10:44:00,21.39,27.39,454,965,0.00431353785925312,1 +"6958",2015-02-16 10:45:00,21.39,27.39,449,962,0.00431353785925312,1 +"6959",2015-02-16 10:46:00,21.39,27.4633333333333,454,966.333333333333,0.00432516713012274,1 +"6960",2015-02-16 10:46:59,21.445,27.55,459,975,0.00435366027959088,1 +"6961",2015-02-16 10:47:59,21.39,27.525,460.25,980.5,0.00433494662399069,1 +"6962",2015-02-16 10:49:00,21.4725,27.575,454,982.5,0.00436503647611038,1 +"6963",2015-02-16 10:50:00,21.445,27.65,446.5,988,0.00436957405422399,1 +"6964",2015-02-16 10:51:00,21.5,27.745,450.25,989.25,0.00439959219751203,1 +"6965",2015-02-16 10:52:00,21.5,27.76,444,995.666666666667,0.00440198761764557,1 +"6966",2015-02-16 10:53:00,21.5,27.79,446.5,1005.75,0.00440677851287516,1 +"6967",2015-02-16 10:53:59,21.5,27.79,454,1013.33333333333,0.00440677851287516,1 +"6968",2015-02-16 10:54:59,21.5,27.84,454,1019.5,0.00441476350111362,1 +"6969",2015-02-16 10:56:00,21.5,27.7675,454,1019.5,0.00440318533458262,1 +"6970",2015-02-16 10:57:00,21.525,27.8725,450.25,1012.25,0.00442677265313571,1 +"6971",2015-02-16 10:58:00,21.5,27.8233333333333,454,1010,0.00441210181574824,1 +"6972",2015-02-16 10:59:00,21.5,27.8233333333333,439,1000,0.00441210181574824,1 +"6973",2015-02-16 10:59:59,21.5,28.0475,454,1014.5,0.00444790337785994,1 +"6974",2015-02-16 11:00:59,21.5,28.0333333333333,454,1017,0.00444564070446765,1 +"6975",2015-02-16 11:02:00,21.5,28.2675,457.75,1027.75,0.00448304346261749,1 +"6976",2015-02-16 11:03:00,21.5,28.2266666666667,462.333333333333,1044.66666666667,0.00447652095196668,1 +"6977",2015-02-16 11:04:00,21.5,28.1,460.25,1039.5,0.00445628872178248,1 +"6978",2015-02-16 11:05:00,21.4633333333333,28.1666666666667,454,1048.66666666667,0.004456846073202,1 +"6979",2015-02-16 11:06:00,21.4725,28.1975,464,1046.75,0.00446428353436765,1 +"6980",2015-02-16 11:06:59,21.5,28.29,469,1055,0.00448663755713656,1 +"6981",2015-02-16 11:08:00,21.445,28.245,459,1061,0.00446427773552187,1 +"6982",2015-02-16 11:09:00,21.4725,28.245,459,1060.5,0.00447185789459475,1 +"6983",2015-02-16 11:10:00,21.5,28.23,462.333333333333,1058,0.00447705339672475,1 +"6984",2015-02-16 11:10:59,21.5,28.29,454,1059.5,0.00448663755713656,1 +"6985",2015-02-16 11:12:00,21.4725,28.2925,454,1047,0.00447943243798194,1 +"6986",2015-02-16 11:12:59,21.5,28.39,454,1030,0.00450261180949863,1 +"6987",2015-02-16 11:13:59,21.4633333333333,28.3566666666667,454,1033.5,0.00448712688741244,1 +"6988",2015-02-16 11:15:00,21.5,28.365,454,1034.2,0.00449861817003724,1 +"6989",2015-02-16 11:16:00,21.5,28.3233333333333,454,1034.66666666667,0.00449196221741125,1 +"6990",2015-02-16 11:17:00,21.4725,28.315,454,1034.75,0.00448302044351677,1 +"6991",2015-02-16 11:18:00,21.5,28.29,454,1031,0.00448663755713656,1 +"6992",2015-02-16 11:19:00,21.5,28.34,454,1027.5,0.00449462458149041,1 +"6993",2015-02-16 11:19:59,21.5,28.365,454,1028.75,0.00449861817003724,1 +"6994",2015-02-16 11:21:00,21.4725,28.3175,454,1021,0.00448341911333538,1 +"6995",2015-02-16 11:22:00,21.5,28.175,454,1012.25,0.00446826817394868,1 +"6996",2015-02-16 11:23:00,21.5,28.15,454,1008.5,0.00446427497232075,1 +"6997",2015-02-16 11:23:59,21.5,28.2425,454,1010,0.00447905007262817,1 +"6998",2015-02-16 11:25:00,21.4725,28.2925,450.25,1006.25,0.00447943243798194,1 +"6999",2015-02-16 11:25:59,21.5,28.3566666666667,439,1009,0.00449728696819783,1 +"7000",2015-02-16 11:26:59,21.4725,28.39,446.5,1012,0.00449498075879667,1 +"7001",2015-02-16 11:28:00,21.5,28.4633333333333,454,1016,0.00451432677898177,1 +"7002",2015-02-16 11:29:00,21.445,28.3675,454,1016.25,0.00448377910726823,1 +"7003",2015-02-16 11:30:00,21.4266666666667,28.46,444,1011,0.00449341932542755,1 +"7004",2015-02-16 11:31:00,21.4175,28.42,450.25,1011.75,0.0044845208200134,1 +"7005",2015-02-16 11:31:59,21.445,28.495,454,1007,0.00450407774288568,1 +"7006",2015-02-16 11:32:59,21.4175,28.4975,454,1005.5,0.00449683830871173,1 +"7007",2015-02-16 11:34:00,21.39,28.39,439,1001,0.00447215604217809,1 +"7008",2015-02-16 11:35:00,21.39,28.4725,442.75,1003,0.00448524562987811,1 +"7009",2015-02-16 11:36:00,21.39,28.4266666666667,454,1000.66666666667,0.00447797356918246,1 +"7010",2015-02-16 11:37:00,21.39,28.445,450.25,999.75,0.00448088237320175,1 +"7011",2015-02-16 11:38:00,21.39,28.4725,446.5,999.75,0.00448524562987811,1 +"7012",2015-02-16 11:38:59,21.39,28.4725,439,998.25,0.00448524562987811,1 +"7013",2015-02-16 11:39:59,21.4266666666667,28.5,444,993,0.00449978043069803,1 +"7014",2015-02-16 11:41:00,21.4725,28.4725,446.5,994.5,0.00450813763307371,1 +"7015",2015-02-16 11:42:00,21.5,28.5,439,998,0.00452018442801849,1 +"7016",2015-02-16 11:43:00,21.5,28.34,439,989.75,0.00449462458149041,1 +"7017",2015-02-16 11:44:00,21.525,28.29,446.5,968.75,0.0044935599706281,1 +"7018",2015-02-16 11:44:59,21.5,28.3233333333333,454,972,0.00449196221741125,1 +"7019",2015-02-16 11:45:59,21.5,28.29,454,976,0.00448663755713656,1 +"7020",2015-02-16 11:47:00,21.6,28.245,454,992.75,0.00450715087611206,1 +"7021",2015-02-16 11:48:00,21.6,28.2,454,985.666666666667,0.00449991812260031,1 +"7022",2015-02-16 11:49:00,21.6,28.2,454,976.25,0.00449991812260031,1 +"7023",2015-02-16 11:50:00,21.575,28.2,454,974,0.00449298983751707,1 +"7024",2015-02-16 11:51:00,21.6,28.1,454,965,0.00448384593489741,1 +"7025",2015-02-16 11:51:59,21.6,28.1,454,963.666666666667,0.00448384593489741,1 +"7026",2015-02-16 11:53:00,21.575,28.1,454,966.25,0.00447694257213877,1 +"7027",2015-02-16 11:54:00,21.5333333333333,28.1,454,961,0.00446545780728482,1 +"7028",2015-02-16 11:55:00,21.5,28.175,454,967.5,0.00446826817394868,0 +"7029",2015-02-16 11:55:59,21.525,28.175,454,967,0.00447516204294433,0 +"7030",2015-02-16 11:57:00,21.5,28.15,454,958.5,0.00446427497232075,0 +"7031",2015-02-16 11:57:59,21.5,28.15,454,962.5,0.00446427497232075,1 +"7032",2015-02-16 11:58:59,21.5,28.245,454,964.5,0.00447944940933615,1 +"7033",2015-02-16 12:00:00,21.5,28.2,454,958.666666666667,0.00447226142648379,1 +"7034",2015-02-16 12:01:00,21.5,28.2,454,963,0.00447226142648379,1 +"7035",2015-02-16 12:02:00,21.5,28.1666666666667,454,956.666666666667,0.00446693710108307,1 +"7036",2015-02-16 12:03:00,21.5,28.1,457.75,946.75,0.00445628872178248,1 +"7037",2015-02-16 12:04:00,21.5,28.1,454,949.333333333333,0.00445628872178248,1 +"7038",2015-02-16 12:04:59,21.445,28.05,454,946.25,0.00443323724000741,1 +"7039",2015-02-16 12:06:00,21.39,27.9175,461.5,931.5,0.00439719893953879,1 +"7040",2015-02-16 12:07:00,21.39,28,469,914,0.00441028539506729,1 +"7041",2015-02-16 12:08:00,21.39,28.0666666666667,459,914.333333333333,0.00442086070808653,1 +"7042",2015-02-16 12:08:59,21.365,27.9975,465.25,916.75,0.00440308916575736,1 +"7043",2015-02-16 12:10:00,21.29,28.025,469,918.25,0.00438708088484858,1 +"7044",2015-02-16 12:10:59,21.315,28.075,454,919.75,0.00440175422017843,1 +"7045",2015-02-16 12:11:59,21.29,28.05,454,921.5,0.00439102205485254,1 +"7046",2015-02-16 12:13:00,21.29,27.9633333333333,454,919,0.00437735954421354,1 +"7047",2015-02-16 12:14:00,21.29,28.025,454,913.25,0.00438708088484858,1 +"7048",2015-02-16 12:15:00,21.29,27.9725,454,909.5,0.00437880458926872,1 +"7049",2015-02-16 12:16:00,21.29,27.8933333333333,454,909,0.00436632487455587,1 +"7050",2015-02-16 12:16:59,21.29,27.92,454,910,0.00437052851239121,1 +"7051",2015-02-16 12:17:59,21.29,27.89,454,903,0.00436579942379362,1 +"7052",2015-02-16 12:19:00,21.29,28.156,454,896.2,0.00440773316662449,1 +"7053",2015-02-16 12:20:00,21.29,28.0666666666667,454,905.666666666667,0.00439364952907471,1 +"7054",2015-02-16 12:21:00,21.34,28.15,454,905.5,0.00442041520288226,1 +"7055",2015-02-16 12:22:00,21.445,28.075,454,907.5,0.0044372166188114,1 +"7056",2015-02-16 12:23:00,21.5,28.175,454,914.5,0.00446826817394868,1 +"7057",2015-02-16 12:23:59,21.5,28.15,454,924.5,0.00446427497232075,1 +"7058",2015-02-16 12:24:59,21.5,28.3633333333333,454,936.333333333333,0.00449835192921679,1 +"7059",2015-02-16 12:26:00,21.5,28.2675,454,948,0.00448304346261749,1 +"7060",2015-02-16 12:27:00,21.5333333333333,28.2266666666667,454,952.333333333333,0.00448573196459932,1 +"7061",2015-02-16 12:28:00,21.5,28.15,454,941.25,0.00446427497232075,1 +"7062",2015-02-16 12:29:00,21.5333333333333,27.96,454,932,0.0044430510547679,1 +"7063",2015-02-16 12:29:59,21.5,27.89,469,905.75,0.00442274869292857,1 +"7064",2015-02-16 12:30:59,21.5666666666667,27.89,462.333333333333,908.666666666667,0.00444096438153294,1 +"7065",2015-02-16 12:32:00,21.575,28.0475,469,909,0.00446851808690097,1 +"7066",2015-02-16 12:33:00,21.6,28.05,469,915,0.00447581015027813,1 +"7067",2015-02-16 12:34:00,21.6,28,469,915.666666666667,0.00446777457180305,1 +"7068",2015-02-16 12:35:00,21.6,28.025,459,916.5,0.00447179233527306,1 +"7069",2015-02-16 12:36:00,21.6,27.85,449,913.5,0.00444366907316371,1 +"7070",2015-02-16 12:36:59,21.6,27.7925,459,906,0.00443442912386619,1 +"7071",2015-02-16 12:38:00,21.5,27.945,459,902,0.00443153263906517,1 +"7072",2015-02-16 12:39:00,21.55,28.1,469,909.75,0.00447004858971507,1 +"7073",2015-02-16 12:40:00,21.6,27.97,464,908.75,0.00446295332366392,1 +"7074",2015-02-16 12:40:59,21.575,28.02,459,900.75,0.00446410535172401,1 +"7075",2015-02-16 12:42:00,21.6,28.1,459,901,0.00448384593489741,1 +"7076",2015-02-16 12:42:59,21.6,27.96,462.333333333333,905.5,0.00446134625744149,1 +"7077",2015-02-16 12:43:59,21.6,28.15,459,907.75,0.00449188192566883,1 +"7078",2015-02-16 12:45:00,21.625,28.05,459,905.5,0.00448271042697731,1 +"7079",2015-02-16 12:46:00,21.6,28,459,907,0.00446777457180305,1 +"7080",2015-02-16 12:47:00,21.6,28.025,464,912.5,0.00447179233527306,1 +"7081",2015-02-16 12:48:00,21.6,28.1,464,910,0.00448384593489741,1 +"7082",2015-02-16 12:49:00,21.625,28.125,464,905.75,0.00449478289759883,1 +"7083",2015-02-16 12:49:59,21.65,28.1,479,906.5,0.00449768084557703,1 +"7084",2015-02-16 12:51:00,21.625,28.05,479,912.75,0.00448271042697731,1 +"7085",2015-02-16 12:52:00,21.55,28,464,894,0.00445402703177401,1 +"7086",2015-02-16 12:53:00,21.575,28.05,464,897.5,0.00446891924772692,1 +"7087",2015-02-16 12:53:59,21.5,28.0666666666667,464,898.333333333333,0.004450964667878,1 +"7088",2015-02-16 12:55:00,21.525,28.075,464,894.5,0.00445916472327869,0 +"7089",2015-02-16 12:55:59,21.5,28.1,456.5,892,0.00445628872178248,1 +"7090",2015-02-16 12:56:59,21.5,28.175,460.25,902.25,0.00446826817394868,1 +"7091",2015-02-16 12:58:00,21.5,28.1,456.5,901,0.00445628872178248,1 +"7092",2015-02-16 12:59:00,21.5,28.125,467.75,895.25,0.004460281821599,1 +"7093",2015-02-16 13:00:00,21.525,28.125,467.75,890.333333333333,0.00446716328098555,1 +"7094",2015-02-16 13:01:00,21.5,28.2675,467.75,894.4,0.00448304346261749,1 +"7095",2015-02-16 13:01:59,21.6,28.1333333333333,464,903.333333333333,0.00448920323917207,1 +"7096",2015-02-16 13:02:59,21.575,28.1,464,904.75,0.00447694257213877,1 +"7097",2015-02-16 13:04:00,21.6,28.1,464,904,0.00448384593489741,1 +"7098",2015-02-16 13:05:00,21.6,28.1333333333333,464,898,0.00448920323917207,1 +"7099",2015-02-16 13:06:00,21.6,28.1,464,893.5,0.00448384593489741,1 +"7100",2015-02-16 13:07:00,21.5666666666667,28.1,464,892.333333333333,0.00447464353628273,1 +"7101",2015-02-16 13:08:00,21.525,28.1,457.75,888,0.00446316397660112,1 +"7102",2015-02-16 13:08:59,21.525,28.1725,459,888.5,0.00447476209999529,1 +"7103",2015-02-16 13:09:59,21.55,28.2,459,895,0.00448607096717959,1 +"7104",2015-02-16 13:11:00,21.5,28.29,459,897.5,0.00448663755713656,1 +"7105",2015-02-16 13:12:00,21.55,28.2,459,900.25,0.00448607096717959,1 +"7106",2015-02-16 13:13:00,21.5,28.2675,459,906.75,0.00448304346261749,1 +"7107",2015-02-16 13:14:00,21.5,28.1,459,893.5,0.00445628872178248,1 +"7108",2015-02-16 13:14:59,21.5,28.2225,457.75,886,0.00447585539729182,1 +"7109",2015-02-16 13:15:59,21.5,28.29,469,886.5,0.00448663755713656,1 +"7110",2015-02-16 13:17:00,21.4633333333333,28.26,454,889.25,0.00447172049333341,1 +"7111",2015-02-16 13:18:00,21.445,28.245,454,880.25,0.00446427773552187,0 +"7112",2015-02-16 13:19:00,21.5,28.29,464,875.666666666667,0.00448663755713656,1 +"7113",2015-02-16 13:20:00,21.5,28.2675,457.75,873.75,0.00448304346261749,0 +"7114",2015-02-16 13:21:00,21.5,28.29,469,883,0.00448663755713656,1 +"7115",2015-02-16 13:21:59,21.5,28.34,461.5,884.5,0.00449462458149041,1 +"7116",2015-02-16 13:23:00,21.5,28.2675,464,882.5,0.00448304346261749,1 +"7117",2015-02-16 13:24:00,21.5,28.1,459,871,0.00445628872178248,1 +"7118",2015-02-16 13:25:00,21.5,28.0475,464,870.75,0.00444790337785994,1 +"7119",2015-02-16 13:25:59,21.5,27.9966666666667,464,858,0.00443978444923423,1 +"7120",2015-02-16 13:27:00,21.5,28.2675,459,860,0.00448304346261749,1 +"7121",2015-02-16 13:27:59,21.5333333333333,28.23,462.333333333333,872.333333333333,0.00448626551277588,1 +"7122",2015-02-16 13:28:59,21.6,28.1,459,871.75,0.00448384593489741,1 +"7123",2015-02-16 13:30:00,21.6,27.9975,459,869.75,0.00446737279829044,1 +"7124",2015-02-16 13:31:00,21.6,27.995,459,868,0.00446697102529317,1 +"7125",2015-02-16 13:32:00,21.6,28.05,459,865.25,0.00447581015027813,1 +"7126",2015-02-16 13:33:00,21.6,28,469,857,0.00446777457180305,1 +"7127",2015-02-16 13:34:00,21.6,28.025,459,856.25,0.00447179233527306,1 +"7128",2015-02-16 13:34:59,21.65,28.1,469,858.5,0.00449768084557703,1 +"7129",2015-02-16 13:36:00,21.7,28.2,454,865,0.00452772563213056,1 +"7130",2015-02-16 13:37:00,21.6,27.7933333333333,454,853,0.00443456303422829,1 +"7131",2015-02-16 13:38:00,21.6,28.0666666666667,454,853,0.00447848872224592,1 +"7132",2015-02-16 13:38:59,21.6,28.15,454,869.25,0.00449188192566883,1 +"7133",2015-02-16 13:40:00,21.65,28.2225,454,873,0.0045174305762271,1 +"7134",2015-02-16 13:40:59,21.6,28,446.5,863,0.00446777457180305,1 +"7135",2015-02-16 13:41:59,21.625,27.92,446.5,859.75,0.00446178591336897,1 +"7136",2015-02-16 13:43:00,21.5666666666667,27.8566666666667,446,856,0.00443561881696333,1 +"7137",2015-02-16 13:44:00,21.5,28.075,449.5,852,0.0044522956728702,1 +"7138",2015-02-16 13:45:00,21.5,28,454,857.25,0.00444031683154913,1 +"7139",2015-02-16 13:46:00,21.5,28.0666666666667,454,853.333333333333,0.004450964667878,1 +"7140",2015-02-16 13:46:59,21.525,28.1,454,844.5,0.00446316397660112,1 +"7141",2015-02-16 13:47:59,21.5,28,454,845,0.00444031683154913,1 +"7142",2015-02-16 13:49:00,21.5333333333333,28.0666666666667,454,840,0.00446012272082291,1 +"7143",2015-02-16 13:50:00,21.5,27.9175,454,833,0.0044271406352041,1 +"7144",2015-02-16 13:51:00,21.5,28.125,454,830,0.004460281821599,1 +"7145",2015-02-16 13:52:00,21.5,28.2,454,837.5,0.00447226142648379,1 +"7146",2015-02-16 13:53:00,21.5,28.1,454,841.75,0.00445628872178248,1 +"7147",2015-02-16 13:53:59,21.5,28.1,454,843.5,0.00445628872178248,1 +"7148",2015-02-16 13:54:59,21.4725,28.1,461.5,844.25,0.00444873673718102,1 +"7149",2015-02-16 13:56:00,21.5,28.125,469,834.5,0.004460281821599,1 +"7150",2015-02-16 13:57:00,21.4725,28.075,469,831,0.00444475050322189,1 +"7151",2015-02-16 13:58:00,21.445,28.1,459,832,0.00444119604817323,1 +"7152",2015-02-16 13:59:00,21.5,28.175,459,835.25,0.00446826817394868,1 +"7153",2015-02-16 13:59:59,21.5,28.2,469,844.333333333333,0.00447226142648379,1 +"7154",2015-02-16 14:00:59,21.5,28.2,461.5,846,0.00447226142648379,1 +"7155",2015-02-16 14:02:00,21.5,28.2,454,840.5,0.00447226142648379,1 +"7156",2015-02-16 14:03:00,21.5,28.2,454,837.333333333333,0.00447226142648379,1 +"7157",2015-02-16 14:04:00,21.5,28.2225,450.25,840.75,0.00447585539729182,1 +"7158",2015-02-16 14:05:00,21.5,28.2,446.5,838,0.00447226142648379,1 +"7159",2015-02-16 14:06:00,21.5,28.23,449,841,0.00447705339672475,1 +"7160",2015-02-16 14:06:59,21.5333333333333,28.3266666666667,454,847,0.004501738805232,1 +"7161",2015-02-16 14:08:00,21.575,28.7925,454,856.75,0.0045880867531723,1 +"7162",2015-02-16 14:09:00,21.6,28.5225,454,868.5,0.00455175654659862,1 +"7163",2015-02-16 14:10:00,21.6,28.5,446.5,864,0.00454813963399493,1 +"7164",2015-02-16 14:10:59,21.6,28.4175,439,866.5,0.00453487797837775,1 +"7165",2015-02-16 14:12:00,21.6666666666667,28.5,446,864.666666666667,0.00456686109803275,1 +"7166",2015-02-16 14:12:59,21.675,28.5225,450.25,867.5,0.00457283984421898,1 +"7167",2015-02-16 14:13:59,21.7,28.5666666666667,454,880.666666666667,0.00458703092309197,1 +"7168",2015-02-16 14:15:00,21.65,28.575,454,884,0.00457426838122053,1 +"7169",2015-02-16 14:16:00,21.7,28.6,454,890.666666666667,0.00459242286991139,1 +"7170",2015-02-16 14:17:00,21.6666666666667,28.5666666666667,454,893,0.0045776224337308,1 +"7171",2015-02-16 14:18:00,21.7,28.675,465.25,901.5,0.00460455508955526,1 +"7172",2015-02-16 14:19:00,21.7,28.7,469,906.333333333333,0.00460859926717353,1 +"7173",2015-02-16 14:19:59,21.7,28.7675,469,908.75,0.00461951880750225,1 +"7174",2015-02-16 14:21:00,21.7,28.745,469,908.5,0.00461587891843994,1 +"7175",2015-02-16 14:22:00,21.7,28.79,469,901.5,0.00462315873885162,1 +"7176",2015-02-16 14:23:00,21.7,28.79,459,901.5,0.00462315873885162,1 +"7177",2015-02-16 14:23:59,21.675,28.815,459,910.25,0.00462008292360074,1 +"7178",2015-02-16 14:25:00,21.6333333333333,28.79,469,907,0.00460420963733684,1 +"7179",2015-02-16 14:25:59,21.675,28.84,465.25,910.25,0.00462412112410914,1 +"7180",2015-02-16 14:26:59,21.6,28.8566666666667,469,909,0.00460547931283539,1 +"7181",2015-02-16 14:28:00,21.625,28.9175,459,914.25,0.00462237710973341,1 +"7182",2015-02-16 14:29:00,21.7,28.945,459,918.5,0.0046482349705992,1 +"7183",2015-02-16 14:30:00,21.6333333333333,28.8233333333333,455.666666666667,918,0.00460957994065464,1 +"7184",2015-02-16 14:31:00,21.7,29,452.75,918.5,0.00465713347075559,1 +"7185",2015-02-16 14:31:59,21.675,28.945,461.5,918.666666666667,0.00464108213462057,1 +"7186",2015-02-16 14:32:59,21.7,28.9175,454,920.4,0.00464378581528903,1 +"7187",2015-02-16 14:34:00,21.7,29,449,920.666666666667,0.00465713347075559,1 +"7188",2015-02-16 14:35:00,21.7,28.9633333333333,455.666666666667,925,0.00465120110923825,1 +"7189",2015-02-16 14:36:00,21.7225,28.815,459,917,0.00463361964525666,1 +"7190",2015-02-16 14:37:00,21.7,28.865,459,916.25,0.00463529214876545,1 +"7191",2015-02-16 14:38:00,21.7,28.79,469,911.5,0.00462315873885162,1 +"7192",2015-02-16 14:38:59,21.7,28.89,464,914.333333333333,0.00463933672315574,1 +"7193",2015-02-16 14:39:59,21.7,28.89,454,917,0.00463933672315574,1 +"7194",2015-02-16 14:41:00,21.73,28.89,459,906.666666666667,0.00464791639075764,1 +"7195",2015-02-16 14:42:00,21.73,28.8566666666667,464,912.333333333333,0.00464251358963475,1 +"7196",2015-02-16 14:43:00,21.745,28.84,459,898,0.00464409976256397,1 +"7197",2015-02-16 14:44:00,21.745,28.865,461.5,909.75,0.0046481555919188,1 +"7198",2015-02-16 14:44:59,21.79,28.79,469,913,0.00464884919621899,1 +"7199",2015-02-16 14:45:59,21.7675,28.79,469,911,0.00464241479808563,1 +"7200",2015-02-16 14:47:00,21.7,28.8233333333333,469,907.666666666667,0.00462855130747043,1 +"7201",2015-02-16 14:48:00,21.7,28.89,465.25,908.25,0.00463933672315574,1 +"7202",2015-02-16 14:49:00,21.7,28.89,469,906,0.00463933672315574,1 +"7203",2015-02-16 14:50:00,21.7,28.73,469,899.333333333333,0.00461345234922418,1 +"7204",2015-02-16 14:51:00,21.7,28.8925,469,901.75,0.00463974118346637,1 +"7205",2015-02-16 14:51:59,21.7,29,459,903.666666666667,0.00465713347075559,1 +"7206",2015-02-16 14:53:00,21.675,28.9725,465.25,909,0.0046455244557695,1 +"7207",2015-02-16 14:54:00,21.7,29,454,910,0.00465713347075559,1 +"7208",2015-02-16 14:55:00,21.7,29.075,454,910.75,0.00466926819643476,1 +"7209",2015-02-16 14:55:59,21.675,29,454,914.5,0.004649966839903,1 +"7210",2015-02-16 14:57:00,21.7,29,454,912,0.00465713347075559,1 +"7211",2015-02-16 14:57:59,21.7,29,469,906.75,0.00465713347075559,1 +"7212",2015-02-16 14:58:59,21.7,29,459,905.666666666667,0.00465713347075559,1 +"7213",2015-02-16 15:00:00,21.675,28.9725,454,912,0.0046455244557695,1 +"7214",2015-02-16 15:01:00,21.675,28.9725,454,910.25,0.0046455244557695,1 +"7215",2015-02-16 15:02:00,21.7,28.9266666666667,464,904,0.00464526886003937,1 +"7216",2015-02-16 15:03:00,21.7,28.89,462.333333333333,901.333333333333,0.00463933672315574,1 +"7217",2015-02-16 15:04:00,21.7,28.945,464,897.25,0.0046482349705992,1 +"7218",2015-02-16 15:04:59,21.73,28.8933333333333,454,896,0.00464845667599395,1 +"7219",2015-02-16 15:06:00,21.745,28.84,454,900,0.00464409976256397,1 +"7220",2015-02-16 15:07:00,21.7,28.79,454,895.5,0.00462315873885162,1 +"7221",2015-02-16 15:08:00,21.79,28.79,454,890,0.00464884919621899,1 +"7222",2015-02-16 15:08:59,21.772,28.754,454,886,0.00463785110965595,1 +"7223",2015-02-16 15:10:00,21.7,28.73,454,879.5,0.00461345234922418,1 +"7224",2015-02-16 15:10:59,21.7225,28.79,454,879.75,0.00462956957771205,1 +"7225",2015-02-16 15:11:59,21.76,28.6666666666667,454,877.666666666667,0.00462024565179145,1 +"7226",2015-02-16 15:13:00,21.7,28.6666666666667,454,871.666666666667,0.00460320704194977,1 +"7227",2015-02-16 15:14:00,21.7,28.7675,454,870.5,0.00461951880750225,1 +"7228",2015-02-16 15:15:00,21.745,28.7675,446.5,874.5,0.0046323381543212,1 +"7229",2015-02-16 15:16:00,21.745,28.7,439,874,0.00462138808835582,1 +"7230",2015-02-16 15:16:59,21.7675,28.7,444.25,861.25,0.0046277942364492,1 +"7231",2015-02-16 15:17:59,21.79,28.7,439,858,0.00463420822058945,1 +"7232",2015-02-16 15:19:00,21.7225,28.65,439,855.5,0.004606890166909,1 +"7233",2015-02-16 15:20:00,21.7,28.6666666666667,439,859,0.00460320704194977,1 +"7234",2015-02-16 15:21:00,21.7,28.7675,454,854.75,0.00461951880750225,1 +"7235",2015-02-16 15:22:00,21.7,28.745,446.5,858.25,0.00461587891843994,1 +"7236",2015-02-16 15:23:00,21.7,28.745,439,854.5,0.00461587891843994,1 +"7237",2015-02-16 15:23:59,21.6666666666667,28.76,446,857,0.00460883239775034,1 +"7238",2015-02-16 15:24:59,21.7,28.79,444.25,862.5,0.00462315873885162,1 +"7239",2015-02-16 15:26:00,21.7,28.79,439,862,0.00462315873885162,1 +"7240",2015-02-16 15:27:00,21.7,28.865,442.75,865.5,0.00463529214876545,1 +"7241",2015-02-16 15:28:00,21.7,28.865,454,870.5,0.00463529214876545,1 +"7242",2015-02-16 15:29:00,21.675,28.8675,454,874.75,0.00462856320478389,1 +"7243",2015-02-16 15:29:59,21.7,29,461.5,874,0.00465713347075559,1 +"7244",2015-02-16 15:30:59,21.7,29,454,872.75,0.00465713347075559,1 +"7245",2015-02-16 15:32:00,21.65,29.025,457.75,876,0.00464684226877608,1 +"7246",2015-02-16 15:33:00,21.7,29.1,459,885,0.00467331320943048,1 +"7247",2015-02-16 15:34:00,21.675,29.075,459,884.75,0.00466208275313324,1 +"7248",2015-02-16 15:35:00,21.7,29,459,880,0.00465713347075559,1 +"7249",2015-02-16 15:36:00,21.6666666666667,29.0333333333333,462.333333333333,882,0.00465296213516231,1 +"7250",2015-02-16 15:36:59,21.7,29,459,887,0.00465713347075559,1 +"7251",2015-02-16 15:38:00,21.7,29,462.333333333333,886.333333333333,0.00465713347075559,1 +"7252",2015-02-16 15:39:00,21.7225,29,456.5,887,0.00466359177230361,1 +"7253",2015-02-16 15:40:00,21.79,29,454,893.333333333333,0.00468301413344449,1 +"7254",2015-02-16 15:40:59,21.7675,29,454,897.5,0.00467653209527285,1 +"7255",2015-02-16 15:42:00,21.8233333333333,29,457.333333333333,893.333333333333,0.00469263172994848,1 +"7256",2015-02-16 15:42:59,21.865,28.9725,449,895,0.00470018319414353,1 +"7257",2015-02-16 15:43:59,21.89,29,459,893.5,0.0047119192394134,1 +"7258",2015-02-16 15:45:00,21.865,28.9725,459,892.5,0.00470018319414353,1 +"7259",2015-02-16 15:46:00,21.89,29,459,902,0.0047119192394134,1 +"7260",2015-02-16 15:47:00,21.89,29,462.333333333333,892,0.0047119192394134,1 +"7261",2015-02-16 15:48:00,21.89,29,459,883.5,0.0047119192394134,1 +"7262",2015-02-16 15:49:00,21.89,28.9266666666667,469,881,0.00469991400852908,1 +"7263",2015-02-16 15:49:59,21.865,29.025,454,892.75,0.00470876469995564,1 +"7264",2015-02-16 15:51:00,21.89,29.1,454,897,0.00472829075006353,1 +"7265",2015-02-16 15:52:00,21.89,29,454,900.5,0.0047119192394134,1 +"7266",2015-02-16 15:53:00,21.89,28.9175,442.75,896,0.00469841338700813,1 +"7267",2015-02-16 15:53:59,21.89,28.9266666666667,444,886,0.00469991400852908,1 +"7268",2015-02-16 15:55:00,21.89,28.9175,446.5,884.25,0.00469841338700813,1 +"7269",2015-02-16 15:55:59,21.89,28.89,454,885,0.00469391156556352,1 +"7270",2015-02-16 15:56:59,21.89,29,454,891.5,0.0047119192394134,1 +"7271",2015-02-16 15:58:00,21.89,29.1,454,892,0.00472829075006353,1 +"7272",2015-02-16 15:59:00,21.89,29.15,454,896.5,0.00473647682614585,1 +"7273",2015-02-16 16:00:00,21.89,29.2,439,896.333333333333,0.00474466311607751,1 +"7274",2015-02-16 16:01:00,21.865,29.2,454,900.5,0.0047373714167436,1 +"7275",2015-02-16 16:01:59,21.89,29.245,454,905.5,0.00475203095986413,1 +"7276",2015-02-16 16:02:59,21.89,29.175,457.75,918.5,0.00474056994437999,1 +"7277",2015-02-16 16:04:00,21.89,29.1666666666667,454,911.333333333333,0.00473920556569495,1 +"7278",2015-02-16 16:05:00,21.89,29.2,454,909,0.00474466311607751,1 +"7279",2015-02-16 16:06:00,21.89,29.2,446,906.666666666667,0.00474466311607751,1 +"7280",2015-02-16 16:07:00,21.89,29.2675,447,906,0.00475571494671863,1 +"7281",2015-02-16 16:08:00,21.89,29.29,441.5,904,0.00475939897688161,1 +"7282",2015-02-16 16:08:59,21.89,29.2675,456,906.25,0.00475571494671863,1 +"7283",2015-02-16 16:09:59,21.89,29.2,449.5,895.75,0.00474466311607751,1 +"7284",2015-02-16 16:11:00,21.89,29.23,439,892,0.00474957499268768,1 +"7285",2015-02-16 16:12:00,21.89,29.365,442.75,917,0.00477167939021815,1 +"7286",2015-02-16 16:13:00,21.89,29.4266666666667,444,926.333333333333,0.00478177697947595,1 +"7287",2015-02-16 16:14:00,21.89,29.5,454,930.5,0.00479378534697303,1 +"7288",2015-02-16 16:14:59,21.8233333333333,29.3566666666667,439,930.666666666667,0.00475078652115836,1 +"7289",2015-02-16 16:15:59,21.84,29.445,444.25,933.75,0.0047700813667996,1 +"7290",2015-02-16 16:17:00,21.79,29.39,449.5,933.5,0.00474647318715823,1 +"7291",2015-02-16 16:18:00,21.815,29.445,449.5,928,0.00476274749303211,1 +"7292",2015-02-16 16:19:00,21.8233333333333,29.4633333333333,453,924.666666666667,0.00476818070489796,1 +"7293",2015-02-16 16:20:00,21.79,29.39,449.5,917.25,0.00474647318715823,1 +"7294",2015-02-16 16:21:00,21.79,29.39,453,918,0.00474647318715823,1 +"7295",2015-02-16 16:21:59,21.7675,29.525,448,923.5,0.00476184159360194,1 +"7296",2015-02-16 16:23:00,21.7675,29.5,456,928.5,0.00475777870986701,1 +"7297",2015-02-16 16:24:00,21.79,29.55,449.5,923.5,0.00477251138874487,1 +"7298",2015-02-16 16:25:00,21.76,29.5333333333333,453,925,0.00476099666878251,1 +"7299",2015-02-16 16:25:59,21.79,29.6,446.75,921.5,0.00478064877043622,1 +"7300",2015-02-16 16:27:00,21.7675,29.55,444,920.5,0.00476590453001155,1 +"7301",2015-02-16 16:27:59,21.79,29.55,436.5,914,0.00477251138874487,1 +"7302",2015-02-16 16:28:59,21.79,29.55,429,920.5,0.00477251138874487,1 +"7303",2015-02-16 16:30:00,21.79,29.625,429,920,0.00478471754051807,1 +"7304",2015-02-16 16:31:00,21.745,29.7,429,930,0.00478365045972226,1 +"7305",2015-02-16 16:32:00,21.7675,29.7,429,933.75,0.00479028325469474,1 +"7306",2015-02-16 16:33:00,21.7675,29.7225,429,936.5,0.00479394022696895,1 +"7307",2015-02-16 16:34:00,21.79,29.79,429,934.5,0.00481157274796973,1 +"7308",2015-02-16 16:34:59,21.745,29.745,429,926,0.00479095424233068,1 +"7309",2015-02-16 16:36:00,21.7,29.745,433.5,925.25,0.00477769260099989,1 +"7310",2015-02-16 16:37:00,21.7,29.79,429,927.333333333333,0.00478497618171682,1 +"7311",2015-02-16 16:38:00,21.7,29.79,429,930,0.00478497618171682,1 +"7312",2015-02-16 16:38:59,21.745,29.79,429,924,0.00479825819516008,1 +"7313",2015-02-16 16:40:00,21.7,29.79,429,919,0.00478497618171682,1 +"7314",2015-02-16 16:40:59,21.7,29.79,429,923.666666666667,0.00478497618171682,1 +"7315",2015-02-16 16:41:59,21.7,29.79,433.5,929.25,0.00478497618171682,1 +"7316",2015-02-16 16:43:00,21.7,29.8233333333333,441,933.333333333333,0.00479037153583144,1 +"7317",2015-02-16 16:44:00,21.675,29.7675,438,927,0.00477397515673165,1 +"7318",2015-02-16 16:45:00,21.7,29.865,438,912.5,0.00479711585909737,1 +"7319",2015-02-16 16:46:00,21.6333333333333,29.79,441,910.666666666667,0.00476535878954602,1 +"7320",2015-02-16 16:46:59,21.6,29.745,438,907,0.00474833825770024,1 +"7321",2015-02-16 16:47:59,21.675,29.815,438,904,0.00478165155133954,1 +"7322",2015-02-16 16:49:00,21.6333333333333,29.76,441,902.333333333333,0.00476052310896566,1 +"7323",2015-02-16 16:50:00,21.7,29.8566666666667,441,899,0.00479576698283308,1 +"7324",2015-02-16 16:51:00,21.7,29.79,438,894.75,0.00478497618171682,1 +"7325",2015-02-16 16:52:00,21.675,29.7675,438,892,0.00477397515673165,1 +"7326",2015-02-16 16:53:00,21.675,29.7675,441,890.666666666667,0.00477397515673165,1 +"7327",2015-02-16 16:53:59,21.7,29.79,442.5,888.5,0.00478497618171682,1 +"7328",2015-02-16 16:54:59,21.7,29.79,429,889.333333333333,0.00478497618171682,1 +"7329",2015-02-16 16:56:00,21.7,30.07,440.25,910,0.00483030004336746,1 +"7330",2015-02-16 16:57:00,21.7,29.8425,432.75,928.75,0.00479347390650759,1 +"7331",2015-02-16 16:58:00,21.7,29.79,429,933.5,0.00478497618171682,1 +"7332",2015-02-16 16:59:00,21.79,29.79,429,921.5,0.00481157274796973,1 +"7333",2015-02-16 16:59:59,21.79,29.79,429,925.5,0.00481157274796973,1 +"7334",2015-02-16 17:00:59,21.79,29.79,429,919,0.00481157274796973,1 +"7335",2015-02-16 17:02:00,21.79,29.7675,429,913.25,0.00480791053871812,1 +"7336",2015-02-16 17:03:00,21.79,29.815,429,914,0.00481564191955111,1 +"7337",2015-02-16 17:04:00,21.79,29.84,429,921,0.00481971114396579,1 +"7338",2015-02-16 17:05:00,21.79,29.84,434.5,925.25,0.00481971114396579,1 +"7339",2015-02-16 17:06:00,21.79,29.84,438,931.5,0.00481971114396579,1 +"7340",2015-02-16 17:06:59,21.7675,29.89,423.5,938.25,0.00482116569525287,1 +"7341",2015-02-16 17:08:00,21.79,30,431.333333333333,938.666666666667,0.00484575543138078,1 +"7342",2015-02-16 17:09:00,21.79,30.0333333333333,430,948.666666666667,0.00485118159700759,1 +"7343",2015-02-16 17:10:00,21.84,30.245,427.25,971,0.00490070224134286,1 +"7344",2015-02-16 17:10:59,21.8566666666667,30.2933333333333,436.333333333333,981.333333333333,0.00491363369887749,1 +"7345",2015-02-16 17:12:00,21.89,30.2225,427.25,985.5,0.00491211966171204,1 +"7346",2015-02-16 17:12:59,21.89,30.15,431,990,0.00490024326730235,1 +"7347",2015-02-16 17:13:59,21.945,30.025,427,980.25,0.00489630576191266,1 +"7348",2015-02-16 17:15:00,21.89,29.96,426.666666666667,975,0.0048691210580864,1 +"7349",2015-02-16 17:16:00,21.9725,29.945,428.25,973.5,0.00489142250172348,1 +"7350",2015-02-16 17:17:00,22,29.9266666666667,433,982,0.00489667657826667,1 +"7351",2015-02-16 17:18:00,22,29.89,433,973,0.00489062991340907,1 +"7352",2015-02-16 17:19:00,21.945,29.9175,433,965.25,0.00487863777517267,1 +"7353",2015-02-16 17:19:59,21.9266666666667,30,433,967.333333333333,0.00488668335565526,1 +"7354",2015-02-16 17:21:00,21.945,30.05,433,969.5,0.0049004147387739,1 +"7355",2015-02-16 17:22:00,21.9175,30.125,433,979.5,0.00490443883112406,1 +"7356",2015-02-16 17:23:00,21.9633333333333,30.2,433,974,0.0049306260822856,1 +"7357",2015-02-16 17:23:59,21.9175,30.2,433,980,0.00491674557085079,1 +"7358",2015-02-16 17:25:00,21.9266666666667,30.2,433,976.666666666667,0.00491951890955012,1 +"7359",2015-02-16 17:25:59,22,30.175,433,978,0.00493763206073067,1 +"7360",2015-02-16 17:26:59,22,30.05,433,977.5,0.0049170162161352,1 +"7361",2015-02-16 17:28:00,22,30.1,433,966.5,0.00492526239127064,1 +"7362",2015-02-16 17:29:00,22,30.075,433,966.5,0.00492113927658651,1 +"7363",2015-02-16 17:30:00,21.9633333333333,30.2,433,973.333333333333,0.0049306260822856,1 +"7364",2015-02-16 17:31:00,22,30.175,422.5,979,0.00493763206073067,1 +"7365",2015-02-16 17:31:59,22,30.1,419,979.666666666667,0.00492526239127064,1 +"7366",2015-02-16 17:32:59,22,30.05,419,977.5,0.0049170162161352,1 +"7367",2015-02-16 17:34:00,22,30.1666666666667,419,972,0.00493625762890804,1 +"7368",2015-02-16 17:35:00,22,30.025,419,977.5,0.00491289320991564,1 +"7369",2015-02-16 17:36:00,22,30.075,419,976.75,0.00492113927658651,1 +"7370",2015-02-16 17:37:00,22,30.1333333333333,419,974.666666666667,0.00493075996188017,1 +"7371",2015-02-16 17:38:00,22,30.175,419,980.5,0.00493763206073067,1 +"7372",2015-02-16 17:38:59,22,30.2,419,982.5,0.00494175539235679,1 +"7373",2015-02-16 17:39:59,22,30.2,419,986.25,0.00494175539235679,1 +"7374",2015-02-16 17:41:00,22,30.2,419,982.5,0.00494175539235679,1 +"7375",2015-02-16 17:42:00,22,30.2,419,987,0.00494175539235679,1 +"7376",2015-02-16 17:43:00,21.9633333333333,30.26,419,989.666666666667,0.00494049983661537,1 +"7377",2015-02-16 17:44:00,21.9725,30.29,419,997,0.00494822549836836,1 +"7378",2015-02-16 17:44:59,21.9633333333333,30.29,419,994,0.00494543683041014,1 +"7379",2015-02-16 17:45:59,21.945,30.245,419,991.75,0.00493246660701159,1 +"7380",2015-02-16 17:47:00,21.9725,30.29,419,983,0.00494822549836836,1 +"7381",2015-02-16 17:48:00,21.89,30.2,419,980,0.00490843383598124,1 +"7382",2015-02-16 17:49:00,21.945,30.245,419,977.75,0.00493246660701159,1 +"7383",2015-02-16 17:50:00,22,30.245,419,983,0.00494917752596472,1 +"7384",2015-02-16 17:51:00,21.9633333333333,30.29,419,986,0.00494543683041014,1 +"7385",2015-02-16 17:51:59,22,30.2,419,990,0.00494175539235679,1 +"7386",2015-02-16 17:53:00,21.9266666666667,30.1666666666667,419,981.666666666667,0.00491404607836335,1 +"7387",2015-02-16 17:54:00,22,30.05,419,980,0.0049170162161352,1 +"7388",2015-02-16 17:55:00,21.9725,30.0725,419,975.25,0.00491241371442367,1 +"7389",2015-02-16 17:55:59,21.945,30.1975,419,976.25,0.00492465879870705,1 +"7390",2015-02-16 17:57:00,21.89,30.23,419,981.333333333333,0.00491334827992024,1 +"7391",2015-02-16 17:57:59,21.9175,30.2,419,981.25,0.00491674557085079,1 +"7392",2015-02-16 17:58:59,21.945,30.2,419,985.5,0.00492506973113778,1 +"7393",2015-02-16 18:00:00,21.89,30.245,419,982.25,0.00491580553078374,1 +"7394",2015-02-16 18:01:00,21.89,30.29,419,976,0.00492317739895294,1 +"7395",2015-02-16 18:02:00,21.89,30.34,419,973.75,0.00493136856692414,1 +"7396",2015-02-16 18:03:00,21.89,30.39,419,975.666666666667,0.00493955994894424,1 +"7397",2015-02-16 18:04:00,21.89,30.39,411.5,978,0.00493955994894424,1 +"7398",2015-02-16 18:04:59,21.89,30.39,0,974,0.00493955994894424,0 +"7399",2015-02-16 18:06:00,21.89,30.39,0,974,0.00493955994894424,0 +"7400",2015-02-16 18:07:00,21.89,30.39,0,969,0.00493955994894424,0 +"7401",2015-02-16 18:08:00,21.84,30.34,0,965.5,0.00491621708674368,0 +"7402",2015-02-16 18:08:59,21.79,30.29,0,964,0.0048929662190992,0 +"7403",2015-02-16 18:10:00,21.79,30.29,0,952,0.0048929662190992,0 +"7404",2015-02-16 18:10:59,21.79,30.29,0,949,0.0048929662190992,0 +"7405",2015-02-16 18:11:59,21.84,30.34,0,950.5,0.00491621708674368,0 +"7406",2015-02-16 18:13:00,21.84,30.295,0,941.5,0.00490886785372334,0 +"7407",2015-02-16 18:14:00,21.79,30.26,0,943.666666666667,0.00488808201473317,0 +"7408",2015-02-16 18:15:00,21.79,30.2,0,941,0.00487831383431837,0 +"7409",2015-02-16 18:16:00,21.79,30.245,0,933.5,0.00488563994109014,0 +"7410",2015-02-16 18:16:59,21.79,30.2,0,941,0.00487831383431837,0 +"7411",2015-02-16 18:17:59,21.79,30.29,0,943,0.0048929662190992,0 +"7412",2015-02-16 18:19:00,21.79,30.29,0,945,0.0048929662190992,0 +"7413",2015-02-16 18:20:00,21.79,30.29,0,944.333333333333,0.0048929662190992,0 +"7414",2015-02-16 18:21:00,21.7,30.29,0,939,0.00486591624766547,0 +"7415",2015-02-16 18:22:00,21.7,30.29,0,937.5,0.00486591624766547,0 +"7416",2015-02-16 18:23:00,21.7,30.39,0,932,0.00488210676945272,0 +"7417",2015-02-16 18:23:59,21.7,30.39,0,925.5,0.00488210676945272,0 +"7418",2015-02-16 18:24:59,21.7,30.39,0,922.5,0.00488210676945272,0 +"7419",2015-02-16 18:26:00,21.7,30.3233333333333,0,923,0.0048713129953374,0 +"7420",2015-02-16 18:27:00,21.7,30.29,0,926,0.00486591624766547,0 +"7421",2015-02-16 18:28:00,21.6,30.15,0,917,0.00481349069239354,0 +"7422",2015-02-16 18:29:00,21.7,30.29,0,904.5,0.00486591624766547,0 +"7423",2015-02-16 18:29:59,21.6,30.2,0,908.5,0.00482153514223757,0 +"7424",2015-02-16 18:30:59,21.6,30.2,0,905.5,0.00482153514223757,0 +"7425",2015-02-16 18:32:00,21.6,30.2,0,897,0.00482153514223757,0 +"7426",2015-02-16 18:33:00,21.5,30.1966666666667,0,891.666666666667,0.00479135367472258,0 +"7427",2015-02-16 18:34:00,21.5,30.2,0,886,0.00479188665477039,0 +"7428",2015-02-16 18:35:00,21.5,30.245,0,884,0.00479908197413252,0 +"7429",2015-02-16 18:36:00,21.5,30.2,0,883,0.00479188665477039,0 +"7430",2015-02-16 18:36:59,21.5,30.2,0,883,0.00479188665477039,0 +"7431",2015-02-16 18:38:00,21.5,30.2,0,884,0.00479188665477039,0 +"7432",2015-02-16 18:39:00,21.5,30.2,0,878,0.00479188665477039,0 +"7433",2015-02-16 18:40:00,21.5,30.245,0,876.5,0.00479908197413252,0 +"7434",2015-02-16 18:40:59,21.5,30.2,0,879,0.00479188665477039,0 +"7435",2015-02-16 18:42:00,21.39,30.1,0,862.5,0.00474357937270712,0 +"7436",2015-02-16 18:42:59,21.34,30.15,0,853,0.00473686842275773,0 +"7437",2015-02-16 18:43:59,21.34,30.2,0,855,0.00474478384984455,0 +"7438",2015-02-16 18:45:00,21.29,30.15,0,851,0.00472225748281681,0 +"7439",2015-02-16 18:46:00,21.29,30.15,0,846,0.00472225748281681,0 +"7440",2015-02-16 18:47:00,21.29,30.2,0,846,0.00473014831038467,0 +"7441",2015-02-16 18:48:00,21.29,30.29,0,844,0.0047443523007446,0 +"7442",2015-02-16 18:49:00,21.29,30.26,0,843,0.00473961756575534,0 +"7443",2015-02-16 18:49:59,21.29,30.2,0,842,0.00473014831038467,0 +"7444",2015-02-16 18:51:00,21.29,30.2,0,841,0.00473014831038467,0 +"7445",2015-02-16 18:52:00,21.29,30.245,0,839,0.00473725022508699,0 +"7446",2015-02-16 18:53:00,21.29,30.2,0,844.5,0.00473014831038467,0 +"7447",2015-02-16 18:53:59,21.2,30.2,0,844,0.00470390476800215,0 +"7448",2015-02-16 18:55:00,21.2,30.2,0,835,0.00470390476800215,0 +"7449",2015-02-16 18:55:59,21.2,30.2,0,831.5,0.00470390476800215,0 +"7450",2015-02-16 18:56:59,21.1,30.245,0,829.5,0.00468191448333509,0 +"7451",2015-02-16 18:58:00,21.1,30.2,0,821,0.00467489614476848,0 +"7452",2015-02-16 18:59:00,21.1,30.245,0,822,0.00468191448333509,0 +"7453",2015-02-16 19:00:00,21.1,30.29,0,822.666666666667,0.00468893297910483,0 +"7454",2015-02-16 19:01:00,21.0333333333333,30.29,0,825,0.00466962353320893,0 +"7455",2015-02-16 19:01:59,21.1,30.34,0,832,0.00469673149211834,0 +"7456",2015-02-16 19:02:59,21.1,30.3233333333333,0,815.666666666667,0.00469413196621512,0 +"7457",2015-02-16 19:04:00,21.1,30.29,0,817,0.00468893297910483,0 +"7458",2015-02-16 19:05:00,21.05,30.29,0,814.5,0.00467444429974908,0 +"7459",2015-02-16 19:06:00,21,30.29,0,813.5,0.00465999516919142,0 +"7460",2015-02-16 19:07:00,21,30.29,0,811,0.00465999516919142,0 +"7461",2015-02-16 19:08:00,21,30.29,0,809.75,0.00465999516919142,0 +"7462",2015-02-16 19:08:59,21,30.29,0,803,0.00465999516919142,0 +"7463",2015-02-16 19:09:59,20.89,30.29,0,803,0.00462834583303539,0 +"7464",2015-02-16 19:11:00,20.945,30.29,0,803.5,0.00464414669280217,0 +"7465",2015-02-16 19:12:00,20.89,30.39,0,800,0.00464374002329553,0 +"7466",2015-02-16 19:13:00,20.89,30.39,0,796.5,0.00464374002329553,0 +"7467",2015-02-16 19:14:00,20.84,30.39,0,796,0.00462936882933099,0 +"7468",2015-02-16 19:14:59,20.79,30.39,0,800.333333333333,0.0046150369259356,0 +"7469",2015-02-16 19:15:59,20.79,30.39,0,795.5,0.0046150369259356,0 +"7470",2015-02-16 19:17:00,20.79,30.39,0,790,0.0046150369259356,0 +"7471",2015-02-16 19:18:00,20.79,30.39,0,792,0.0046150369259356,0 +"7472",2015-02-16 19:19:00,20.745,30.39,0,785.5,0.00460217172938416,0 +"7473",2015-02-16 19:20:00,20.7,30.39,0,783,0.00458933821507646,0 +"7474",2015-02-16 19:21:00,20.7,30.5,0,782,0.00460607285085383,0 +"7475",2015-02-16 19:21:59,20.7,30.5,0,777.5,0.00460607285085383,0 +"7476",2015-02-16 19:23:00,20.7,30.5,0,776.5,0.00460607285085383,0 +"7477",2015-02-16 19:24:00,20.7,30.5,0,774,0.00460607285085383,0 +"7478",2015-02-16 19:25:00,20.7,30.5,0,771.5,0.00460607285085383,0 +"7479",2015-02-16 19:25:59,20.7,30.5,0,770,0.00460607285085383,0 +"7480",2015-02-16 19:27:00,20.6666666666667,30.5666666666667,0,769.333333333333,0.00460667360648062,0 +"7481",2015-02-16 19:27:59,20.6666666666667,30.5666666666667,0,766.333333333333,0.00460667360648062,0 +"7482",2015-02-16 19:28:59,20.6,30.5,0,763,0.00457756268382079,0 +"7483",2015-02-16 19:30:00,20.6,30.525,0,764.75,0.00458134242048655,0 +"7484",2015-02-16 19:31:00,20.6,30.5666666666667,0,765.333333333333,0.00458764208293362,0 +"7485",2015-02-16 19:32:00,20.6,30.5333333333333,0,766.333333333333,0.00458260234284213,0 +"7486",2015-02-16 19:33:00,20.65,30.55,0,766,0.00459938142619299,0 +"7487",2015-02-16 19:34:00,20.65,30.55,0,763,0.00459938142619299,0 +"7488",2015-02-16 19:34:59,20.6,30.5,0,764,0.00457756268382079,0 +"7489",2015-02-16 19:36:00,20.7,30.6,0,765,0.00462128693180636,0 +"7490",2015-02-16 19:37:00,20.7,30.55,0,762.5,0.00461367979898123,0 +"7491",2015-02-16 19:38:00,20.65,30.55,0,768,0.00459938142619299,0 +"7492",2015-02-16 19:38:59,20.65,30.5,0,769.5,0.0045917982257084,0 +"7493",2015-02-16 19:40:00,20.7,30.5,0,767,0.00460607285085383,0 +"7494",2015-02-16 19:40:59,20.65,30.5,0,765,0.0045917982257084,0 +"7495",2015-02-16 19:41:59,20.7,30.5,0,767.5,0.00460607285085383,0 +"7496",2015-02-16 19:43:00,20.7,30.5,0,765,0.00460607285085383,0 +"7497",2015-02-16 19:44:00,20.6,30.4266666666667,0,759.333333333333,0.00456647571933112,0 +"7498",2015-02-16 19:45:00,20.7,30.5,0,760,0.00460607285085383,0 +"7499",2015-02-16 19:46:00,20.6666666666667,30.4633333333333,0,759,0.00459098539054017,0 +"7500",2015-02-16 19:46:59,20.7,30.445,0,760.666666666667,0.00459770542123156,0 +"7501",2015-02-16 19:47:59,20.6666666666667,30.4266666666667,0,760,0.00458541879306692,0 +"7502",2015-02-16 19:49:00,20.7,30.39,0,764.5,0.00458933821507646,0 +"7503",2015-02-16 19:50:00,20.7,30.39,0,763,0.00458933821507646,0 +"7504",2015-02-16 19:51:00,20.7,30.39,0,753,0.00458933821507646,0 +"7505",2015-02-16 19:52:00,20.7,30.39,0,751,0.00458933821507646,0 +"7506",2015-02-16 19:53:00,20.675,30.39,0,756,0.00458222214987692,0 +"7507",2015-02-16 19:53:59,20.6,30.39,0,756,0.00456093238421853,0 +"7508",2015-02-16 19:54:59,20.7,30.39,0,752,0.00458933821507646,0 +"7509",2015-02-16 19:56:00,20.6666666666667,30.4266666666667,0,753,0.00458541879306692,0 +"7510",2015-02-16 19:57:00,20.6,30.39,0,752,0.00456093238421853,0 +"7511",2015-02-16 19:58:00,20.65,30.39,0,754.5,0.0045751158307073,0 +"7512",2015-02-16 19:59:00,20.65,30.39,0,759,0.0045751158307073,0 +"7513",2015-02-16 19:59:59,20.6,30.39,0,749.5,0.00456093238421853,0 +"7514",2015-02-16 20:00:59,20.6,30.39,0,748,0.00456093238421853,0 +"7515",2015-02-16 20:02:00,20.6,30.39,0,752,0.00456093238421853,0 +"7516",2015-02-16 20:03:00,20.6,30.39,0,748,0.00456093238421853,0 +"7517",2015-02-16 20:04:00,20.6,30.39,0,753,0.00456093238421853,0 +"7518",2015-02-16 20:05:00,20.6,30.39,0,748.5,0.00456093238421853,0 +"7519",2015-02-16 20:06:00,20.5666666666667,30.39,0,747.666666666667,0.00455149833976378,0 +"7520",2015-02-16 20:06:59,20.5,30.39,0,746.5,0.0045326819356264,0 +"7521",2015-02-16 20:08:00,20.55,30.445,0,744.5,0.00455507684819661,0 +"7522",2015-02-16 20:09:00,20.5,30.5,0,743,0.00454920847912978,0 +"7523",2015-02-16 20:10:00,20.5,30.445,0,747,0.00454094509839613,0 +"7524",2015-02-16 20:10:59,20.5,30.4633333333333,0,744.666666666667,0.00454369953442204,0 +"7525",2015-02-16 20:12:00,20.5,30.5,0,741,0.00454920847912978,0 +"7526",2015-02-16 20:12:59,20.5,30.5,0,744,0.00454920847912978,0 +"7527",2015-02-16 20:13:59,20.5,30.5,0,750,0.00454920847912978,0 +"7528",2015-02-16 20:15:00,20.5,30.39,0,745,0.0045326819356264,0 +"7529",2015-02-16 20:16:00,20.5,30.39,0,742,0.0045326819356264,0 +"7530",2015-02-16 20:17:00,20.5,30.39,0,741,0.0045326819356264,0 +"7531",2015-02-16 20:18:00,20.5,30.39,0,743,0.0045326819356264,0 +"7532",2015-02-16 20:19:00,20.5,30.39,0,738.5,0.0045326819356264,0 +"7533",2015-02-16 20:19:59,20.5,30.39,0,735.5,0.0045326819356264,0 +"7534",2015-02-16 20:21:00,20.55,30.39,0,739.5,0.00454678778324929,0 +"7535",2015-02-16 20:22:00,20.55,30.39,0,745.5,0.00454678778324929,0 +"7536",2015-02-16 20:23:00,20.55,30.39,0,739,0.00454678778324929,0 +"7537",2015-02-16 20:23:59,20.5,30.39,0,737,0.0045326819356264,0 +"7538",2015-02-16 20:25:00,20.6,30.39,0,741,0.00456093238421853,0 +"7539",2015-02-16 20:25:59,20.5,30.39,0,749,0.0045326819356264,0 +"7540",2015-02-16 20:26:59,20.6,30.29,0,738.5,0.00454581469606991,0 +"7541",2015-02-16 20:28:00,20.6,30.29,0,738.5,0.00454581469606991,0 +"7542",2015-02-16 20:29:00,20.6,30.29,0,731,0.00454581469606991,0 +"7543",2015-02-16 20:30:00,20.5,30.29,0,731.5,0.00451765856170965,0 +"7544",2015-02-16 20:31:00,20.5,30.29,0,728.5,0.00451765856170965,0 +"7545",2015-02-16 20:31:59,20.5,30.34,0,731.5,0.0045251701586071,0 +"7546",2015-02-16 20:32:59,20.5,30.34,0,734,0.0045251701586071,0 +"7547",2015-02-16 20:34:00,20.5,30.29,0,733,0.00451765856170965,0 +"7548",2015-02-16 20:35:00,20.5,30.39,0,733,0.0045326819356264,0 +"7549",2015-02-16 20:36:00,20.5,30.365,0,734.666666666667,0.00452892602460111,0 +"7550",2015-02-16 20:37:00,20.5,30.39,0,727.5,0.0045326819356264,0 +"7551",2015-02-16 20:38:00,20.39,30.29,0,725,0.00448686479549351,0 +"7552",2015-02-16 20:38:59,20.445,30.34,0,731.5,0.0045097242016922,0 +"7553",2015-02-16 20:39:59,20.39,30.29,0,730,0.00448686479549351,0 +"7554",2015-02-16 20:41:00,20.39,30.29,0,732,0.00448686479549351,0 +"7555",2015-02-16 20:42:00,20.39,30.29,0,726,0.00448686479549351,0 +"7556",2015-02-16 20:43:00,20.39,30.3233333333333,0,728.666666666667,0.00449183812790181,0 +"7557",2015-02-16 20:44:00,20.39,30.29,0,724.333333333333,0.00448686479549351,0 +"7558",2015-02-16 20:44:59,20.39,30.29,0,719,0.00448686479549351,0 +"7559",2015-02-16 20:45:59,20.39,30.29,0,721.5,0.00448686479549351,0 +"7560",2015-02-16 20:47:00,20.39,30.29,0,722.5,0.00448686479549351,0 +"7561",2015-02-16 20:48:00,20.39,30.29,0,726.666666666667,0.00448686479549351,0 +"7562",2015-02-16 20:49:00,20.39,30.29,0,724,0.00448686479549351,0 +"7563",2015-02-16 20:50:00,20.29,30.34,0,719.5,0.00446644489254803,0 +"7564",2015-02-16 20:51:00,20.3566666666667,30.3566666666667,0,725,0.00448749601241794,0 +"7565",2015-02-16 20:51:59,20.39,30.29,0,729,0.00448686479549351,0 +"7566",2015-02-16 20:53:00,20.39,30.29,0,728.666666666667,0.00448686479549351,0 +"7567",2015-02-16 20:54:00,20.39,30.29,0,732,0.00448686479549351,0 +"7568",2015-02-16 20:55:00,20.39,30.29,0,729.5,0.00448686479549351,0 +"7569",2015-02-16 20:55:59,20.39,30.23,0,724.666666666667,0.00447791299613603,0 +"7570",2015-02-16 20:57:00,20.39,30.2,0,726,0.00447343719239004,0 +"7571",2015-02-16 20:57:59,20.39,30.2,0,725.5,0.00447343719239004,0 +"7572",2015-02-16 20:58:59,20.39,30.2,0,718.666666666667,0.00447343719239004,0 +"7573",2015-02-16 21:00:00,20.39,30.2,0,717.5,0.00447343719239004,0 +"7574",2015-02-16 21:01:00,20.39,30.2,0,721,0.00447343719239004,0 +"7575",2015-02-16 21:02:00,20.39,30.2,0,727,0.00447343719239004,0 +"7576",2015-02-16 21:03:00,20.39,30.2,0,727,0.00447343719239004,0 +"7577",2015-02-16 21:04:00,20.39,30.2,0,722,0.00447343719239004,0 +"7578",2015-02-16 21:04:59,20.39,30.2,0,727,0.00447343719239004,0 +"7579",2015-02-16 21:06:00,20.4266666666667,30.1666666666667,0,724.666666666667,0.00447866576958472,0 +"7580",2015-02-16 21:07:00,20.39,30.15,0,726,0.00446597766159789,0 +"7581",2015-02-16 21:08:00,20.39,30.1666666666667,0,730.333333333333,0.00446846415212365,0 +"7582",2015-02-16 21:08:59,20.39,30.2,0,717,0.00447343719239004,0 +"7583",2015-02-16 21:10:00,20.39,30.2,0,723.75,0.00447343719239004,0 +"7584",2015-02-16 21:10:59,20.39,30.2,0,723.5,0.00447343719239004,0 +"7585",2015-02-16 21:11:59,20.39,30.2,0,723,0.00447343719239004,0 +"7586",2015-02-16 21:13:00,20.39,30.2,0,726,0.00447343719239004,0 +"7587",2015-02-16 21:14:00,20.39,30.2,0,726,0.00447343719239004,0 +"7588",2015-02-16 21:15:00,20.39,30.2,0,724,0.00447343719239004,0 +"7589",2015-02-16 21:16:00,20.39,30.2,0,720,0.00447343719239004,0 +"7590",2015-02-16 21:16:59,20.34,30.2,0,720,0.00445954341280494,0 +"7591",2015-02-16 21:17:59,20.39,30.2,0,726.5,0.00447343719239004,0 +"7592",2015-02-16 21:19:00,20.39,30.2,0,733,0.00447343719239004,0 +"7593",2015-02-16 21:20:00,20.39,30.2,0,720.5,0.00447343719239004,0 +"7594",2015-02-16 21:21:00,20.39,30.2,0,720.666666666667,0.00447343719239004,0 +"7595",2015-02-16 21:22:00,20.39,30.2,0,722.333333333333,0.00447343719239004,0 +"7596",2015-02-16 21:23:00,20.39,30.2,0,724.666666666667,0.00447343719239004,0 +"7597",2015-02-16 21:23:59,20.39,30.2,0,719,0.00447343719239004,0 +"7598",2015-02-16 21:24:59,20.39,30.2,0,715.5,0.00447343719239004,0 +"7599",2015-02-16 21:26:00,20.39,30.15,0,721,0.00446597766159789,0 +"7600",2015-02-16 21:27:00,20.39,30.1,0,725.5,0.00445851830844756,0 +"7601",2015-02-16 21:28:00,20.39,30.1,0,724,0.00445851830844756,0 +"7602",2015-02-16 21:29:00,20.39,30.1,0,721,0.00445851830844756,0 +"7603",2015-02-16 21:29:59,20.39,30.1,0,724,0.00445851830844756,0 +"7604",2015-02-16 21:30:59,20.34,30.2,0,718,0.00445954341280494,0 +"7605",2015-02-16 21:32:00,20.39,30.2,0,723,0.00447343719239004,0 +"7606",2015-02-16 21:33:00,20.39,30.15,0,721.5,0.00446597766159789,0 +"7607",2015-02-16 21:34:00,20.39,30.1,0,727,0.00445851830844756,0 +"7608",2015-02-16 21:35:00,20.39,30.1,0,727,0.00445851830844756,0 +"7609",2015-02-16 21:36:00,20.39,30.1333333333333,0,725.666666666667,0.00446349119081012,0 +"7610",2015-02-16 21:36:59,20.34,30.2,0,724,0.00445954341280494,0 +"7611",2015-02-16 21:38:00,20.29,30.2,0,723,0.00444568775426561,0 +"7612",2015-02-16 21:39:00,20.34,30.2,0,720,0.00445954341280494,0 +"7613",2015-02-16 21:40:00,20.34,30.2,0,714.5,0.00445954341280494,0 +"7614",2015-02-16 21:40:59,20.29,30.2,0,719.666666666667,0.00444568775426561,0 +"7615",2015-02-16 21:42:00,20.29,30.2,0,728,0.00444568775426561,0 +"7616",2015-02-16 21:42:59,20.3233333333333,30.2,0,721,0.00445492062876417,0 +"7617",2015-02-16 21:43:59,20.34,30.2,0,719.333333333333,0.00445954341280494,0 +"7618",2015-02-16 21:45:00,20.29,30.2,0,720,0.00444568775426561,0 +"7619",2015-02-16 21:46:00,20.34,30.2,0,719.5,0.00445954341280494,0 +"7620",2015-02-16 21:47:00,20.34,30.2,0,718.5,0.00445954341280494,0 +"7621",2015-02-16 21:48:00,20.3233333333333,30.2,0,726.666666666667,0.00445492062876417,0 +"7622",2015-02-16 21:49:00,20.29,30.2,0,728.5,0.00444568775426561,0 +"7623",2015-02-16 21:49:59,20.34,30.2,0,729.5,0.00445954341280494,0 +"7624",2015-02-16 21:51:00,20.39,30.2,0,728,0.00447343719239004,0 +"7625",2015-02-16 21:52:00,20.3566666666667,30.1333333333333,0,726,0.00445424518064493,0 +"7626",2015-02-16 21:53:00,20.39,30.1,0,718.5,0.00445851830844756,0 +"7627",2015-02-16 21:53:59,20.39,30.1,0,720.333333333333,0.00445851830844756,0 +"7628",2015-02-16 21:55:00,20.39,30.1,0,721.333333333333,0.00445851830844756,0 +"7629",2015-02-16 21:55:59,20.39,30.05,0,719.5,0.00445105913293269,0 +"7630",2015-02-16 21:56:59,20.4266666666667,30.0333333333333,0,713.333333333333,0.00445872866230918,0 +"7631",2015-02-16 21:58:00,20.5,30.1,0,713,0.00448911613609654,0 +"7632",2015-02-16 21:59:00,20.39,30,0,713,0.00444360013504694,0 +"7633",2015-02-16 22:00:00,20.39,30,0,716,0.00444360013504694,0 +"7634",2015-02-16 22:01:00,20.39,30,0,712.333333333333,0.00444360013504694,0 +"7635",2015-02-16 22:01:59,20.39,30,0,707,0.00444360013504694,0 +"7636",2015-02-16 22:02:59,20.39,30,0,709,0.00444360013504694,0 +"7637",2015-02-16 22:04:00,20.39,30,0,713.5,0.00444360013504694,0 +"7638",2015-02-16 22:05:00,20.39,30,0,716.5,0.00444360013504694,0 +"7639",2015-02-16 22:06:00,20.39,30,0,722.5,0.00444360013504694,0 +"7640",2015-02-16 22:07:00,20.39,30,0,714,0.00444360013504694,0 +"7641",2015-02-16 22:08:00,20.39,30,0,714.5,0.00444360013504694,0 +"7642",2015-02-16 22:08:59,20.39,30.05,0,710,0.00445105913293269,0 +"7643",2015-02-16 22:09:59,20.39,30.1,0,714.5,0.00445851830844756,0 +"7644",2015-02-16 22:11:00,20.34,30.1,0,713,0.00444467119326688,0 +"7645",2015-02-16 22:12:00,20.29,30.2,0,712,0.00444568775426561,0 +"7646",2015-02-16 22:13:00,20.39,30.15,0,711,0.00446597766159789,0 +"7647",2015-02-16 22:14:00,20.34,30.15,0,714.5,0.00445210721476783,0 +"7648",2015-02-16 22:14:59,20.29,30.2,0,715,0.00444568775426561,0 +"7649",2015-02-16 22:15:59,20.29,30.2,0,715.5,0.00444568775426561,0 +"7650",2015-02-16 22:17:00,20.29,30.245,0,712.5,0.00445235954156012,0 +"7651",2015-02-16 22:18:00,20.23,30.23,0,717.333333333333,0.00443354229665739,0 +"7652",2015-02-16 22:19:00,20.245,30.245,0,719.5,0.00443990316973038,0 +"7653",2015-02-16 22:20:00,20.29,30.29,0,722,0.00445903147096821,0 +"7654",2015-02-16 22:21:00,20.34,30.2,0,728,0.00445954341280494,0 +"7655",2015-02-16 22:21:59,20.29,30.2,0,720,0.00444568775426561,0 +"7656",2015-02-16 22:23:00,20.29,30.2,0,718.5,0.00444568775426561,0 +"7657",2015-02-16 22:24:00,20.29,30.2,0,718.666666666667,0.00444568775426561,0 +"7658",2015-02-16 22:25:00,20.29,30.2,0,721,0.00444568775426561,0 +"7659",2015-02-16 22:25:59,20.29,30.2,0,718.5,0.00444568775426561,0 +"7660",2015-02-16 22:27:00,20.29,30.23,0,717.666666666667,0.00445013559667177,0 +"7661",2015-02-16 22:27:59,20.29,30.29,0,709.666666666667,0.00445903147096821,0 +"7662",2015-02-16 22:28:59,20.245,30.245,0,712.5,0.00443990316973038,0 +"7663",2015-02-16 22:30:00,20.29,30.29,0,719,0.00445903147096821,0 +"7664",2015-02-16 22:31:00,20.245,30.29,0,714.5,0.00444655630058161,0 +"7665",2015-02-16 22:32:00,20.23,30.3233333333333,0,706.333333333333,0.00444732846769673,0 +"7666",2015-02-16 22:33:00,20.23,30.3233333333333,0,708.333333333333,0.00444732846769673,0 +"7667",2015-02-16 22:34:00,20.245,30.29,0,709.5,0.00444655630058161,0 +"7668",2015-02-16 22:34:59,20.2675,30.365,0,707,0.00446389454947321,0 +"7669",2015-02-16 22:36:00,20.29,30.39,0,715,0.00447385848958856,0 +"7670",2015-02-16 22:37:00,20.245,30.34,0,715.5,0.00445394883394137,0 +"7671",2015-02-16 22:38:00,20.29,30.29,0,716,0.00445903147096821,0 +"7672",2015-02-16 22:38:59,20.26,30.3566666666667,0,713.666666666667,0.00446057728740867,0 +"7673",2015-02-16 22:40:00,20.29,30.34,0,711.5,0.00446644489254803,0 +"7674",2015-02-16 22:40:59,20.29,30.29,0,712,0.00445903147096821,0 +"7675",2015-02-16 22:41:59,20.29,30.29,0,716,0.00445903147096821,0 +"7676",2015-02-16 22:43:00,20.29,30.29,0,714.5,0.00445903147096821,0 +"7677",2015-02-16 22:44:00,20.39,30.29,0,717,0.00448686479549351,0 +"7678",2015-02-16 22:45:00,20.39,30.2,0,714.5,0.00447343719239004,0 +"7679",2015-02-16 22:46:00,20.34,30.2,0,715,0.00445954341280494,0 +"7680",2015-02-16 22:46:59,20.34,30.245,0,722,0.00446623614198197,0 +"7681",2015-02-16 22:47:59,20.39,30.2,0,723,0.00447343719239004,0 +"7682",2015-02-16 22:49:00,20.39,30.2,0,716,0.00447343719239004,0 +"7683",2015-02-16 22:50:00,20.39,30.2,0,713,0.00447343719239004,0 +"7684",2015-02-16 22:51:00,20.39,30.2,0,712,0.00447343719239004,0 +"7685",2015-02-16 22:52:00,20.39,30.2,0,715.5,0.00447343719239004,0 +"7686",2015-02-16 22:53:00,20.39,30.1666666666667,0,718,0.00446846415212365,0 +"7687",2015-02-16 22:53:59,20.39,30.15,0,716,0.00446597766159789,0 +"7688",2015-02-16 22:54:59,20.445,30.15,0,721.5,0.00448127921595236,0 +"7689",2015-02-16 22:56:00,20.39,30.1,0,721.5,0.00445851830844756,0 +"7690",2015-02-16 22:57:00,20.39,30.1666666666667,0,721,0.00446846415212365,0 +"7691",2015-02-16 22:58:00,20.39,30.2,0,720,0.00447343719239004,0 +"7692",2015-02-16 22:59:00,20.39,30.2,0,715.333333333333,0.00447343719239004,0 +"7693",2015-02-16 22:59:59,20.34,30.2,0,710.5,0.00445954341280494,0 +"7694",2015-02-16 23:00:59,20.3233333333333,30.29,0,712,0.00446829225557467,0 +"7695",2015-02-16 23:02:00,20.29,30.29,0,712,0.00445903147096821,0 +"7696",2015-02-16 23:03:00,20.29,30.29,0,716,0.00445903147096821,0 +"7697",2015-02-16 23:04:00,20.29,30.39,0,716,0.00447385848958856,0 +"7698",2015-02-16 23:05:00,20.245,30.34,0,716.5,0.00445394883394137,0 +"7699",2015-02-16 23:06:00,20.2,30.39,0,718,0.00444885553202324,0 +"7700",2015-02-16 23:06:59,20.29,30.5,0,714,0.00449016902073007,0 +"7701",2015-02-16 23:08:00,20.2,30.39,0,716.333333333333,0.00444885553202324,0 +"7702",2015-02-16 23:09:00,20.2,30.39,0,713,0.00444885553202324,0 +"7703",2015-02-16 23:10:00,20.2,30.5,0,716.5,0.00446507425916187,0 +"7704",2015-02-16 23:10:59,20.2,30.5,0,713.333333333333,0.00446507425916187,0 +"7705",2015-02-16 23:12:00,20.2,30.5,0,711.25,0.00446507425916187,0 +"7706",2015-02-16 23:12:59,20.1666666666667,30.5,0,712,0.00445581138590463,0 +"7707",2015-02-16 23:13:59,20.2,30.6,0,719.666666666667,0.00447981928533327,0 +"7708",2015-02-16 23:15:00,20.2,30.6,0,718,0.00447981928533327,0 +"7709",2015-02-16 23:16:00,20.2,30.6,0,714.333333333333,0.00447981928533327,0 +"7710",2015-02-16 23:17:00,20.2,30.55,0,716.5,0.00447244668548565,0 +"7711",2015-02-16 23:18:00,20.2,30.6,0,712,0.00447981928533327,0 +"7712",2015-02-16 23:19:00,20.2,30.5,0,711,0.00446507425916187,0 +"7713",2015-02-16 23:19:59,20.2,30.5,0,712.5,0.00446507425916187,0 +"7714",2015-02-16 23:21:00,20.2,30.55,0,710,0.00447244668548565,0 +"7715",2015-02-16 23:22:00,20.2,30.6,0,705.5,0.00447981928533327,0 +"7716",2015-02-16 23:23:00,20.2,30.6,0,715,0.00447981928533327,0 +"7717",2015-02-16 23:23:59,20.1,30.6,0,715.5,0.00445198931575045,0 +"7718",2015-02-16 23:25:00,20.2,30.6,0,711.666666666667,0.00447981928533327,0 +"7719",2015-02-16 23:25:59,20.2,30.6,0,717,0.00447981928533327,0 +"7720",2015-02-16 23:26:59,20.2,30.6,0,717,0.00447981928533327,0 +"7721",2015-02-16 23:28:00,20.2,30.5,0,721.5,0.00446507425916187,0 +"7722",2015-02-16 23:29:00,20.15,30.55,0,708,0.00445853564906587,0 +"7723",2015-02-16 23:30:00,20.1,30.6,0,716,0.00445198931575045,0 +"7724",2015-02-16 23:31:00,20.1666666666667,30.6,0,710,0.00447052560498071,0 +"7725",2015-02-16 23:31:59,20.1333333333333,30.6,0,710,0.00446124895746667,0 +"7726",2015-02-16 23:32:59,20.15,30.6,0,711,0.00446588515380977,0 +"7727",2015-02-16 23:34:00,20.15,30.6,0,716,0.00446588515380977,0 +"7728",2015-02-16 23:35:00,20.2,30.6,0,711.25,0.00447981928533327,0 +"7729",2015-02-16 23:36:00,20.2,30.6,0,717,0.00447981928533327,0 +"7730",2015-02-16 23:37:00,20.2,30.6,0,714,0.00447981928533327,0 +"7731",2015-02-16 23:38:00,20.2,30.6,0,714.5,0.00447981928533327,0 +"7732",2015-02-16 23:38:59,20.2,30.6,0,708.5,0.00447981928533327,0 +"7733",2015-02-16 23:39:59,20.2,30.6,0,709.5,0.00447981928533327,0 +"7734",2015-02-16 23:41:00,20.2,30.55,0,714,0.00447244668548565,0 +"7735",2015-02-16 23:42:00,20.2,30.55,0,711.5,0.00447244668548565,0 +"7736",2015-02-16 23:43:00,20.2,30.6,0,714.5,0.00447981928533327,0 +"7737",2015-02-16 23:44:00,20.15,30.6,0,713,0.00446588515380977,0 +"7738",2015-02-16 23:44:59,20.1666666666667,30.6,0,717,0.00447052560498071,0 +"7739",2015-02-16 23:45:59,20.2,30.5,0,717,0.00446507425916187,0 +"7740",2015-02-16 23:47:00,20.2,30.6,0,713.5,0.00447981928533327,0 +"7741",2015-02-16 23:48:00,20.2,30.5,0,713,0.00446507425916187,0 +"7742",2015-02-16 23:49:00,20.1333333333333,30.5,0,717.333333333333,0.00444656548812262,0 +"7743",2015-02-16 23:50:00,20.2,30.5,0,716,0.00446507425916187,0 +"7744",2015-02-16 23:51:00,20.2,30.5,0,711.333333333333,0.00446507425916187,0 +"7745",2015-02-16 23:51:59,20.2,30.5,0,718,0.00446507425916187,0 +"7746",2015-02-16 23:53:00,20.245,30.55,0,714.5,0.00448499937941095,0 +"7747",2015-02-16 23:54:00,20.2,30.39,0,710.5,0.00444885553202324,0 +"7748",2015-02-16 23:55:00,20.245,30.445,0,717,0.00446947372192622,0 +"7749",2015-02-16 23:55:59,20.245,30.445,0,709,0.00446947372192622,0 +"7750",2015-02-16 23:57:00,20.2,30.39,0,714.5,0.00444885553202324,0 +"7751",2015-02-16 23:57:59,20.2,30.39,0,715.333333333333,0.00444885553202324,0 +"7752",2015-02-16 23:58:59,20.2,30.39,0,718,0.00444885553202324,0 +"7753",2015-02-17 00:00:00,20.2,30.39,0,714,0.00444885553202324,0 +"7754",2015-02-17 00:01:00,20.15,30.445,0,714,0.00444310225039588,0 +"7755",2015-02-17 00:02:00,20.1,30.5,0,708.5,0.00443733653886975,0 +"7756",2015-02-17 00:03:00,20.1,30.55,0,708,0.00444466284162661,0 +"7757",2015-02-17 00:04:00,20.1,30.6,0,710.333333333333,0.00445198931575045,0 +"7758",2015-02-17 00:04:59,20.1,30.6,0,720,0.00445198931575045,0 +"7759",2015-02-17 00:06:00,20.1,30.6,0,711.5,0.00445198931575045,0 +"7760",2015-02-17 00:07:00,20.1,30.6,0,712.5,0.00445198931575045,0 +"7761",2015-02-17 00:08:00,20.1,30.5333333333333,0,713.333333333333,0.00444222072166718,0 +"7762",2015-02-17 00:08:59,20.15,30.5,0,713,0.00445118631676419,0 +"7763",2015-02-17 00:10:00,20.1,30.5,0,713,0.00443733653886975,0 +"7764",2015-02-17 00:10:59,20.2,30.5,0,720,0.00446507425916187,0 +"7765",2015-02-17 00:11:59,20.2,30.5,0,714.5,0.00446507425916187,0 +"7766",2015-02-17 00:13:00,20.2,30.5,0,714.5,0.00446507425916187,0 +"7767",2015-02-17 00:14:00,20.2,30.445,0,713,0.00445696479061842,0 +"7768",2015-02-17 00:15:00,20.2,30.39,0,711,0.00444885553202324,0 +"7769",2015-02-17 00:16:00,20.2,30.39,0,715,0.00444885553202324,0 +"7770",2015-02-17 00:16:59,20.2,30.39,0,717,0.00444885553202324,0 +"7771",2015-02-17 00:17:59,20.2,30.39,0,715,0.00444885553202324,0 +"7772",2015-02-17 00:19:00,20.2,30.39,0,718.333333333333,0.00444885553202324,0 +"7773",2015-02-17 00:20:00,20.2,30.39,0,720,0.00444885553202324,0 +"7774",2015-02-17 00:21:00,20.2,30.39,0,717.5,0.00444885553202324,0 +"7775",2015-02-17 00:22:00,20.2,30.39,0,714,0.00444885553202324,0 +"7776",2015-02-17 00:23:00,20.2,30.39,0,720,0.00444885553202324,0 +"7777",2015-02-17 00:23:59,20.2,30.34,0,713.5,0.00444148366093455,0 +"7778",2015-02-17 00:24:59,20.2,30.39,0,714.666666666667,0.00444885553202324,0 +"7779",2015-02-17 00:26:00,20.2,30.39,0,719.5,0.00444885553202324,0 +"7780",2015-02-17 00:27:00,20.2,30.39,0,717.5,0.00444885553202324,0 +"7781",2015-02-17 00:28:00,20.2,30.39,0,722,0.00444885553202324,0 +"7782",2015-02-17 00:29:00,20.2,30.39,0,718.5,0.00444885553202324,0 +"7783",2015-02-17 00:29:59,20.2,30.34,0,717,0.00444148366093455,0 +"7784",2015-02-17 00:30:59,20.2,30.39,0,715.666666666667,0.00444885553202324,0 +"7785",2015-02-17 00:32:00,20.2,30.39,0,711,0.00444885553202324,0 +"7786",2015-02-17 00:33:00,20.1666666666667,30.39,0,711.666666666667,0.00443962654323641,0 +"7787",2015-02-17 00:34:00,20.2,30.39,0,714.5,0.00444885553202324,0 +"7788",2015-02-17 00:35:00,20.2,30.39,0,719.5,0.00444885553202324,0 +"7789",2015-02-17 00:36:00,20.2,30.39,0,711,0.00444885553202324,0 +"7790",2015-02-17 00:36:59,20.2,30.39,0,710,0.00444885553202324,0 +"7791",2015-02-17 00:38:00,20.2,30.39,0,711.5,0.00444885553202324,0 +"7792",2015-02-17 00:39:00,20.2,30.34,0,714,0.00444148366093455,0 +"7793",2015-02-17 00:40:00,20.1666666666667,30.3566666666667,0,712.666666666667,0.00443472221056449,0 +"7794",2015-02-17 00:40:59,20.2,30.39,0,715,0.00444885553202324,0 +"7795",2015-02-17 00:42:00,20.2,30.365,0,713.75,0.00444516957479125,0 +"7796",2015-02-17 00:42:59,20.2,30.29,0,718,0.00443411196334396,0 +"7797",2015-02-17 00:43:59,20.2,30.29,0,714,0.00443411196334396,0 +"7798",2015-02-17 00:45:00,20.29,30.39,0,710,0.00447385848958856,0 +"7799",2015-02-17 00:46:00,20.2,30.29,0,706,0.00443411196334396,0 +"7800",2015-02-17 00:47:00,20.2,30.29,0,713.333333333333,0.00443411196334396,0 +"7801",2015-02-17 00:48:00,20.2,30.29,0,715.5,0.00443411196334396,0 +"7802",2015-02-17 00:49:00,20.2,30.29,0,713,0.00443411196334396,0 +"7803",2015-02-17 00:49:59,20.2,30.29,0,714,0.00443411196334396,0 +"7804",2015-02-17 00:51:00,20.2,30.29,0,717,0.00443411196334396,0 +"7805",2015-02-17 00:52:00,20.1,30.29,0,727,0.00440656793848278,0 +"7806",2015-02-17 00:53:00,20.1,30.29,0,714,0.00440656793848278,0 +"7807",2015-02-17 00:53:59,20.1,30.34,0,711.5,0.00441389352156393,0 +"7808",2015-02-17 00:55:00,20.1,30.29,0,717.333333333333,0.00440656793848278,0 +"7809",2015-02-17 00:55:59,20.1,30.29,0,715,0.00440656793848278,0 +"7810",2015-02-17 00:56:59,20.125,30.365,0,710.5,0.00442444543595398,0 +"7811",2015-02-17 00:58:00,20.1333333333333,30.3566666666667,0,715.666666666667,0.0044255203823837,0 +"7812",2015-02-17 00:59:00,20.1,30.29,0,714,0.00440656793848278,0 +"7813",2015-02-17 01:00:00,20.1,30.29,0,713,0.00440656793848278,0 +"7814",2015-02-17 01:01:00,20.1,30.29,0,713,0.00440656793848278,0 +"7815",2015-02-17 01:01:59,20.1,30.29,0,716,0.00440656793848278,0 +"7816",2015-02-17 01:02:59,20.1,30.29,0,709.5,0.00440656793848278,0 +"7817",2015-02-17 01:04:00,20.05,30.29,0,706.5,0.00439285267652326,0 +"7818",2015-02-17 01:05:00,20,30.29,0,708,0.0043791751281533,0 +"7819",2015-02-17 01:06:00,20,30.29,0,709,0.0043791751281533,0 +"7820",2015-02-17 01:07:00,20,30.29,0,706,0.0043791751281533,0 +"7821",2015-02-17 01:08:00,20,30.39,0,714.5,0.00439373474883846,0 +"7822",2015-02-17 01:08:59,20,30.39,0,715,0.00439373474883846,0 +"7823",2015-02-17 01:09:59,20,30.3566666666667,0,711.333333333333,0.00438888146673837,0 +"7824",2015-02-17 01:11:00,20.05,30.34,0,710,0.00440015529886628,0 +"7825",2015-02-17 01:12:00,20.0333333333333,30.3233333333333,0,721,0.00439315261090937,0 +"7826",2015-02-17 01:13:00,20,30.29,0,723,0.0043791751281533,0 +"7827",2015-02-17 01:14:00,20,30.29,0,711,0.0043791751281533,0 +"7828",2015-02-17 01:14:59,20,30.29,0,713,0.0043791751281533,0 +"7829",2015-02-17 01:15:59,20,30.29,0,712,0.0043791751281533,0 +"7830",2015-02-17 01:17:00,20,30.29,0,712.75,0.0043791751281533,0 +"7831",2015-02-17 01:18:00,20,30.34,0,710.5,0.00438645485389054,0 +"7832",2015-02-17 01:19:00,20,30.29,0,709,0.0043791751281533,0 +"7833",2015-02-17 01:20:00,20,30.29,0,711,0.0043791751281533,0 +"7834",2015-02-17 01:21:00,20,30.29,0,707.5,0.0043791751281533,0 +"7835",2015-02-17 01:21:59,20,30.29,0,708,0.0043791751281533,0 +"7836",2015-02-17 01:23:00,20,30.29,0,714,0.0043791751281533,0 +"7837",2015-02-17 01:24:00,20,30.34,0,715,0.00438645485389054,0 +"7838",2015-02-17 01:25:00,20,30.39,0,719.666666666667,0.00439373474883846,0 +"7839",2015-02-17 01:25:59,20,30.29,0,719,0.0043791751281533,0 +"7840",2015-02-17 01:27:00,20,30.39,0,718,0.00439373474883846,0 +"7841",2015-02-17 01:27:59,20,30.29,0,713.5,0.0043791751281533,0 +"7842",2015-02-17 01:28:59,20,30.29,0,709,0.0043791751281533,0 +"7843",2015-02-17 01:30:00,20,30.29,0,711,0.0043791751281533,0 +"7844",2015-02-17 01:31:00,20,30.29,0,710,0.0043791751281533,0 +"7845",2015-02-17 01:32:00,20,30.29,0,713.333333333333,0.0043791751281533,0 +"7846",2015-02-17 01:33:00,20,30.29,0,714,0.0043791751281533,0 +"7847",2015-02-17 01:34:00,20.05,30.34,0,714.5,0.00440015529886628,0 +"7848",2015-02-17 01:34:59,20,30.2,0,711,0.00436607204821834,0 +"7849",2015-02-17 01:36:00,20,30.29,0,711,0.0043791751281533,0 +"7850",2015-02-17 01:37:00,20,30.2,0,712,0.00436607204821834,0 +"7851",2015-02-17 01:38:00,20,30.23,0,715.5,0.0043704396806184,0 +"7852",2015-02-17 01:38:59,20,30.29,0,715.333333333333,0.0043791751281533,0 +"7853",2015-02-17 01:40:00,20,30.29,0,714,0.0043791751281533,0 +"7854",2015-02-17 01:40:59,20,30.29,0,713.5,0.0043791751281533,0 +"7855",2015-02-17 01:41:59,20.1,30.29,0,725,0.00440656793848278,0 +"7856",2015-02-17 01:43:00,20.1,30.29,0,728,0.00440656793848278,0 +"7857",2015-02-17 01:44:00,20,30.2,0,725,0.00436607204821834,0 +"7858",2015-02-17 01:45:00,20,30.2,0,722.333333333333,0.00436607204821834,0 +"7859",2015-02-17 01:46:00,20.1,30.29,0,718,0.00440656793848278,0 +"7860",2015-02-17 01:46:59,20.05,30.245,0,722,0.00438628046199309,0 +"7861",2015-02-17 01:47:59,20,30.2,0,721,0.00436607204821834,0 +"7862",2015-02-17 01:49:00,20,30.2,0,723.5,0.00436607204821834,0 +"7863",2015-02-17 01:50:00,20,30.2,0,724,0.00436607204821834,0 +"7864",2015-02-17 01:51:00,20,30.2,0,711.333333333333,0.00436607204821834,0 +"7865",2015-02-17 01:52:00,20,30.245,0,710,0.00437262351966004,0 +"7866",2015-02-17 01:53:00,20,30.26,0,711.333333333333,0.00437480737392963,0 +"7867",2015-02-17 01:53:59,20,30.245,0,715,0.00437262351966004,0 +"7868",2015-02-17 01:54:59,20,30.29,0,716.5,0.0043791751281533,0 +"7869",2015-02-17 01:56:00,20,30.245,0,716.5,0.00437262351966004,0 +"7870",2015-02-17 01:57:00,20,30.29,0,718,0.0043791751281533,0 +"7871",2015-02-17 01:58:00,20,30.29,0,715,0.0043791751281533,0 +"7872",2015-02-17 01:59:00,20,30.29,0,715,0.0043791751281533,0 +"7873",2015-02-17 01:59:59,20,30.29,0,711.5,0.0043791751281533,0 +"7874",2015-02-17 02:00:59,20,30.29,0,715.666666666667,0.0043791751281533,0 +"7875",2015-02-17 02:02:00,20,30.29,0,720,0.0043791751281533,0 +"7876",2015-02-17 02:03:00,20,30.29,0,719,0.0043791751281533,0 +"7877",2015-02-17 02:04:00,20,30.29,0,720.5,0.0043791751281533,0 +"7878",2015-02-17 02:05:00,20,30.29,0,725,0.0043791751281533,0 +"7879",2015-02-17 02:06:00,20,30.29,0,722.5,0.0043791751281533,0 +"7880",2015-02-17 02:06:59,20,30.29,0,716.5,0.0043791751281533,0 +"7881",2015-02-17 02:08:00,20,30.26,0,716,0.00437480737392963,0 +"7882",2015-02-17 02:09:00,19.945,30.29,0,718.5,0.00436417327695448,0 +"7883",2015-02-17 02:10:00,20,30.29,0,718,0.0043791751281533,0 +"7884",2015-02-17 02:10:59,20,30.29,0,715,0.0043791751281533,0 +"7885",2015-02-17 02:12:00,20,30.29,0,715.25,0.0043791751281533,0 +"7886",2015-02-17 02:12:59,19.89,30.29,0,718,0.00434921683124043,0 +"7887",2015-02-17 02:13:59,19.89,30.34,0,718,0.00435644640940998,0 +"7888",2015-02-17 02:15:00,19.89,30.39,0,716,0.00436367615447494,0 +"7889",2015-02-17 02:16:00,19.89,30.39,0,715.333333333333,0.00436367615447494,0 +"7890",2015-02-17 02:17:00,19.89,30.39,0,712.5,0.00436367615447494,0 +"7891",2015-02-17 02:18:00,19.89,30.39,0,722,0.00436367615447494,0 +"7892",2015-02-17 02:19:00,19.89,30.39,0,723,0.00436367615447494,0 +"7893",2015-02-17 02:19:59,20,30.39,0,719,0.00439373474883846,0 +"7894",2015-02-17 02:21:00,19.89,30.39,0,731.5,0.00436367615447494,0 +"7895",2015-02-17 02:22:00,19.9633333333333,30.39,0,721.333333333333,0.00438369496263895,0 +"7896",2015-02-17 02:23:00,19.89,30.39,0,719,0.00436367615447494,0 +"7897",2015-02-17 02:23:59,19.945,30.39,0,714.5,0.00437868267171281,0 +"7898",2015-02-17 02:25:00,19.945,30.39,0,717,0.00437868267171281,0 +"7899",2015-02-17 02:25:59,19.89,30.39,0,714,0.00436367615447494,0 +"7900",2015-02-17 02:26:59,19.945,30.39,0,712,0.00437868267171281,0 +"7901",2015-02-17 02:28:00,20,30.39,0,711,0.00439373474883846,0 +"7902",2015-02-17 02:29:00,19.9266666666667,30.3566666666667,0,713.333333333333,0.0043688444727716,0 +"7903",2015-02-17 02:30:00,19.89,30.39,0,718.5,0.00436367615447494,0 +"7904",2015-02-17 02:31:00,19.89,30.39,0,714.666666666667,0.00436367615447494,0 +"7905",2015-02-17 02:31:59,19.945,30.39,0,715,0.00437868267171281,0 +"7906",2015-02-17 02:32:59,19.945,30.39,0,718.5,0.00437868267171281,0 +"7907",2015-02-17 02:34:00,20,30.29,0,719,0.0043791751281533,0 +"7908",2015-02-17 02:35:00,20,30.29,0,717.5,0.0043791751281533,0 +"7909",2015-02-17 02:36:00,20,30.29,0,714.5,0.0043791751281533,0 +"7910",2015-02-17 02:37:00,20,30.29,0,712,0.0043791751281533,0 +"7911",2015-02-17 02:38:00,20,30.29,0,710.666666666667,0.0043791751281533,0 +"7912",2015-02-17 02:38:59,20,30.29,0,721,0.0043791751281533,0 +"7913",2015-02-17 02:39:59,20,30.39,0,722.666666666667,0.00439373474883846,0 +"7914",2015-02-17 02:41:00,19.89,30.39,0,717,0.00436367615447494,0 +"7915",2015-02-17 02:42:00,20,30.39,0,716,0.00439373474883846,0 +"7916",2015-02-17 02:43:00,20,30.34,0,714,0.00438645485389054,0 +"7917",2015-02-17 02:44:00,20,30.39,0,721.5,0.00439373474883846,0 +"7918",2015-02-17 02:44:59,20,30.39,0,715.5,0.00439373474883846,0 +"7919",2015-02-17 02:45:59,19.945,30.39,0,713,0.00437868267171281,0 +"7920",2015-02-17 02:47:00,19.945,30.39,0,707,0.00437868267171281,0 +"7921",2015-02-17 02:48:00,20,30.39,0,716,0.00439373474883846,0 +"7922",2015-02-17 02:49:00,20,30.39,0,712,0.00439373474883846,0 +"7923",2015-02-17 02:50:00,20,30.39,0,713,0.00439373474883846,0 +"7924",2015-02-17 02:51:00,19.89,30.445,0,715,0.00437162906681748,0 +"7925",2015-02-17 02:51:59,19.945,30.445,0,719,0.00438666312536088,0 +"7926",2015-02-17 02:53:00,19.89,30.5,0,722,0.00437958218111815,0 +"7927",2015-02-17 02:54:00,19.89,30.5,0,722,0.00437958218111815,0 +"7928",2015-02-17 02:55:00,19.89,30.5,0,721.333333333333,0.00437958218111815,0 +"7929",2015-02-17 02:55:59,19.89,30.5333333333333,0,716.666666666667,0.00438440234868454,0 +"7930",2015-02-17 02:57:00,19.89,30.6,0,715,0.00439404290637603,0 +"7931",2015-02-17 02:57:59,19.89,30.6,0,713,0.00439404290637603,0 +"7932",2015-02-17 02:58:59,19.89,30.5333333333333,0,722.333333333333,0.00438440234868454,0 +"7933",2015-02-17 03:00:00,19.945,30.6,0,721.5,0.00440915458883873,0 +"7934",2015-02-17 03:01:00,19.89,30.55,0,720.5,0.00438681246028725,0 +"7935",2015-02-17 03:02:00,19.945,30.55,0,719,0.00440189910156418,0 +"7936",2015-02-17 03:03:00,20,30.5,0,718,0.00440975111337455,0 +"7937",2015-02-17 03:04:00,20,30.5,0,722,0.00440975111337455,0 +"7938",2015-02-17 03:04:59,20,30.445,0,718.5,0.00440174282872655,0 +"7939",2015-02-17 03:06:00,20,30.39,0,724,0.00439373474883846,0 +"7940",2015-02-17 03:07:00,20.05,30.39,0,727,0.00440745809148236,0 +"7941",2015-02-17 03:08:00,20.1,30.39,0,725.5,0.00442121927598683,0 +"7942",2015-02-17 03:08:59,20,30.29,0,724,0.0043791751281533,0 +"7943",2015-02-17 03:10:00,20.1,30.39,0,719.5,0.00442121927598683,0 +"7944",2015-02-17 03:10:59,20.1,30.39,0,719,0.00442121927598683,0 +"7945",2015-02-17 03:11:59,20.1,30.39,0,722,0.00442121927598683,0 +"7946",2015-02-17 03:13:00,20.075,30.34,0,723.666666666667,0.00440701968236935,0 +"7947",2015-02-17 03:14:00,20,30.39,0,723,0.00439373474883846,0 +"7948",2015-02-17 03:15:00,20.05,30.39,0,724.5,0.00440745809148236,0 +"7949",2015-02-17 03:16:00,20,30.39,0,727,0.00439373474883846,0 +"7950",2015-02-17 03:16:59,20,30.4633333333333,0,724.333333333333,0.00440441223419106,0 +"7951",2015-02-17 03:17:59,20,30.5,0,718,0.00440975111337455,0 +"7952",2015-02-17 03:19:00,20,30.5,0,716.5,0.00440975111337455,0 +"7953",2015-02-17 03:20:00,20,30.5,0,718,0.00440975111337455,0 +"7954",2015-02-17 03:21:00,20,30.55,0,721.666666666667,0.00441703154983629,0 +"7955",2015-02-17 03:22:00,19.945,30.6,0,721,0.00440915458883873,0 +"7956",2015-02-17 03:23:00,20,30.5,0,721.5,0.00440975111337455,0 +"7957",2015-02-17 03:23:59,20.05,30.445,0,724,0.00441549136003255,0 +"7958",2015-02-17 03:24:59,20.1,30.5,0,719,0.00443733653886975,0 +"7959",2015-02-17 03:26:00,20.1,30.5,0,720,0.00443733653886975,0 +"7960",2015-02-17 03:27:00,20.1,30.5,0,725,0.00443733653886975,0 +"7961",2015-02-17 03:28:00,20.1,30.55,0,719.5,0.00444466284162661,0 +"7962",2015-02-17 03:29:00,20.0666666666667,30.5333333333333,0,716.333333333333,0.00443299848258801,0 +"7963",2015-02-17 03:29:59,20,30.5,0,725.5,0.00440975111337455,0 +"7964",2015-02-17 03:30:59,20,30.5,0,727.5,0.00440975111337455,0 +"7965",2015-02-17 03:32:00,20,30.5,0,728,0.00440975111337455,0 +"7966",2015-02-17 03:33:00,20,30.55,0,724,0.00441703154983629,0 +"7967",2015-02-17 03:34:00,20,30.5666666666667,0,725.666666666667,0.00441945839959779,0 +"7968",2015-02-17 03:35:00,20,30.55,0,722.5,0.00441703154983629,0 +"7969",2015-02-17 03:36:00,20.0333333333333,30.5666666666667,0,726.666666666667,0.00442865701174136,0 +"7970",2015-02-17 03:36:59,20.05,30.6,0,722,0.00443813167998615,0 +"7971",2015-02-17 03:38:00,20,30.5,0,724,0.00440975111337455,0 +"7972",2015-02-17 03:39:00,20.1,30.6,0,724,0.00445198931575045,0 +"7973",2015-02-17 03:40:00,20.1,30.5,0,723.5,0.00443733653886975,0 +"7974",2015-02-17 03:40:59,20.1,30.5,0,725.5,0.00443733653886975,0 +"7975",2015-02-17 03:42:00,20.1,30.55,0,724.5,0.00444466284162661,0 +"7976",2015-02-17 03:42:59,20.1,30.6,0,727.5,0.00445198931575045,0 +"7977",2015-02-17 03:43:59,20.2,30.6,0,726,0.00447981928533327,0 +"7978",2015-02-17 03:45:00,20.1,30.5,0,728,0.00443733653886975,0 +"7979",2015-02-17 03:46:00,20.1333333333333,30.5,0,721.666666666667,0.00444656548812262,0 +"7980",2015-02-17 03:47:00,20.2,30.39,0,726,0.00444885553202324,0 +"7981",2015-02-17 03:48:00,20.2,30.39,0,730.5,0.00444885553202324,0 +"7982",2015-02-17 03:49:00,20.2,30.39,0,728.5,0.00444885553202324,0 +"7983",2015-02-17 03:49:59,20.2,30.39,0,723.5,0.00444885553202324,0 +"7984",2015-02-17 03:51:00,20.245,30.34,0,727.25,0.00445394883394137,0 +"7985",2015-02-17 03:52:00,20.2,30.29,0,733.5,0.00443411196334396,0 +"7986",2015-02-17 03:53:00,20.26,30.3566666666667,0,728.333333333333,0.00446057728740867,0 +"7987",2015-02-17 03:53:59,20.245,30.395,0,727.5,0.00446208082215805,0 +"7988",2015-02-17 03:55:00,20.29,30.39,0,726,0.00447385848958856,0 +"7989",2015-02-17 03:55:59,20.245,30.445,0,730,0.00446947372192622,0 +"7990",2015-02-17 03:56:59,20.23,30.4266666666667,0,737,0.00446259243630656,0 +"7991",2015-02-17 03:58:00,20.245,30.445,0,733.5,0.00446947372192622,0 +"7992",2015-02-17 03:59:00,20.26,30.4633333333333,0,736.666666666667,0.00447636357519598,0 +"7993",2015-02-17 04:00:00,20.2,30.39,0,731.5,0.00444885553202324,0 +"7994",2015-02-17 04:01:00,20.2,30.39,0,731,0.00444885553202324,0 +"7995",2015-02-17 04:01:59,20.29,30.445,0,726.5,0.00448201364899767,0 +"7996",2015-02-17 04:02:59,20.29,30.39,0,732,0.00447385848958856,0 +"7997",2015-02-17 04:04:00,20.29,30.39,0,733.333333333333,0.00447385848958856,0 +"7998",2015-02-17 04:05:00,20.34,30.39,0,733.5,0.00448780257546672,0 +"7999",2015-02-17 04:06:00,20.39,30.34,0,730,0.00449432482371647,0 +"8000",2015-02-17 04:07:00,20.39,30.39,0,725,0.00450178502960536,0 +"8001",2015-02-17 04:08:00,20.39,30.29,0,734,0.00448686479549351,0 +"8002",2015-02-17 04:08:59,20.39,30.29,0,735,0.00448686479549351,0 +"8003",2015-02-17 04:09:59,20.34,30.39,0,732,0.00448780257546672,0 +"8004",2015-02-17 04:11:00,20.245,30.445,0,727.5,0.00446947372192622,0 +"8005",2015-02-17 04:12:00,20.2,30.39,0,728.5,0.00444885553202324,0 +"8006",2015-02-17 04:13:00,20.29,30.5,0,726.333333333333,0.00449016902073007,0 +"8007",2015-02-17 04:14:00,20.29,30.5,0,728,0.00449016902073007,0 +"8008",2015-02-17 04:14:59,20.34,30.39,0,731.5,0.00448780257546672,0 +"8009",2015-02-17 04:15:59,20.39,30.4266666666667,0,735,0.00450725596017745,0 +"8010",2015-02-17 04:17:00,20.39,30.39,0,732.5,0.00450178502960536,0 +"8011",2015-02-17 04:18:00,20.39,30.39,0,733,0.00450178502960536,0 +"8012",2015-02-17 04:19:00,20.39,30.39,0,733,0.00450178502960536,0 +"8013",2015-02-17 04:20:00,20.4266666666667,30.39,0,730.666666666667,0.00451206326738066,0 +"8014",2015-02-17 04:21:00,20.39,30.29,0,733,0.00448686479549351,0 +"8015",2015-02-17 04:21:59,20.39,30.39,0,734,0.00450178502960536,0 +"8016",2015-02-17 04:23:00,20.39,30.315,0,735.5,0.00449059478739715,0 +"8017",2015-02-17 04:24:00,20.39,30.29,0,733,0.00448686479549351,0 +"8018",2015-02-17 04:25:00,20.445,30.34,0,728.5,0.0045097242016922,0 +"8019",2015-02-17 04:25:59,20.39,30.29,0,729,0.00448686479549351,0 +"8020",2015-02-17 04:27:00,20.39,30.29,0,732,0.00448686479549351,0 +"8021",2015-02-17 04:27:59,20.4633333333333,30.3233333333333,0,738.666666666667,0.0045123695285676,0 +"8022",2015-02-17 04:28:59,20.5,30.29,0,738,0.00451765856170965,0 +"8023",2015-02-17 04:30:00,20.5,30.34,0,736.5,0.0045251701586071,0 +"8024",2015-02-17 04:31:00,20.5,30.29,0,741,0.00451765856170965,0 +"8025",2015-02-17 04:32:00,20.5,30.34,0,741,0.0045251701586071,0 +"8026",2015-02-17 04:33:00,20.5,30.39,0,736,0.0045326819356264,0 +"8027",2015-02-17 04:34:00,20.4266666666667,30.3233333333333,0,734.333333333333,0.00450209349223891,0 +"8028",2015-02-17 04:34:59,20.39,30.39,0,731,0.00450178502960536,0 +"8029",2015-02-17 04:36:00,20.39,30.39,0,737.5,0.00450178502960536,0 +"8030",2015-02-17 04:37:00,20.39,30.445,0,726.5,0.00450999146129486,0 +"8031",2015-02-17 04:38:00,20.34,30.5,0,733,0.00450416430863932,0 +"8032",2015-02-17 04:38:59,20.39,30.5,0,729,0.00451819810797625,0 +"8033",2015-02-17 04:40:00,20.39,30.5,0,735.5,0.00451819810797625,0 +"8034",2015-02-17 04:40:59,20.3566666666667,30.5,0,734.333333333333,0.00450883795817739,0 +"8035",2015-02-17 04:41:59,20.39,30.5,0,735,0.00451819810797625,0 +"8036",2015-02-17 04:43:00,20.39,30.445,0,741,0.00450999146129486,0 +"8037",2015-02-17 04:44:00,20.39,30.39,0,742.5,0.00450178502960536,0 +"8038",2015-02-17 04:45:00,20.39,30.4266666666667,0,741.333333333333,0.00450725596017745,0 +"8039",2015-02-17 04:46:00,20.39,30.445,0,735.5,0.00450999146129486,0 +"8040",2015-02-17 04:46:59,20.39,30.39,0,730.5,0.00450178502960536,0 +"8041",2015-02-17 04:47:59,20.39,30.39,0,732,0.00450178502960536,0 +"8042",2015-02-17 04:49:00,20.39,30.39,0,733,0.00450178502960536,0 +"8043",2015-02-17 04:50:00,20.39,30.39,0,736.25,0.00450178502960536,0 +"8044",2015-02-17 04:51:00,20.5,30.39,0,738.333333333333,0.0045326819356264,0 +"8045",2015-02-17 04:52:00,20.4725,30.365,0,741.75,0.00452119075500089,0 +"8046",2015-02-17 04:53:00,20.5,30.39,0,735.5,0.0045326819356264,0 +"8047",2015-02-17 04:53:59,20.5,30.39,0,738.5,0.0045326819356264,0 +"8048",2015-02-17 04:54:59,20.5,30.39,0,738,0.0045326819356264,0 +"8049",2015-02-17 04:56:00,20.5,30.39,0,738,0.0045326819356264,0 +"8050",2015-02-17 04:57:00,20.5,30.39,0,737.5,0.0045326819356264,0 +"8051",2015-02-17 04:58:00,20.5,30.29,0,735,0.00451765856170965,0 +"8052",2015-02-17 04:59:00,20.5,30.29,0,735.5,0.00451765856170965,0 +"8053",2015-02-17 04:59:59,20.5,30.29,0,741.5,0.00451765856170965,0 +"8054",2015-02-17 05:00:59,20.5,30.29,0,737.5,0.00451765856170965,0 +"8055",2015-02-17 05:02:00,20.5,30.29,0,735.666666666667,0.00451765856170965,0 +"8056",2015-02-17 05:03:00,20.5,30.29,0,737.5,0.00451765856170965,0 +"8057",2015-02-17 05:04:00,20.5,30.29,0,738,0.00451765856170965,0 +"8058",2015-02-17 05:05:00,20.5,30.29,0,740.5,0.00451765856170965,0 +"8059",2015-02-17 05:06:00,20.5,30.29,0,738.5,0.00451765856170965,0 +"8060",2015-02-17 05:06:59,20.5,30.29,0,739.5,0.00451765856170965,0 +"8061",2015-02-17 05:08:00,20.5,30.29,0,739.5,0.00451765856170965,0 +"8062",2015-02-17 05:09:00,20.5,30.245,0,739.5,0.00451089827850079,0 +"8063",2015-02-17 05:10:00,20.5,30.2,0,741,0.00450413814118067,0 +"8064",2015-02-17 05:10:59,20.5,30.2,0,734,0.00450413814118067,0 +"8065",2015-02-17 05:12:00,20.5333333333333,30.29,0,739.333333333333,0.00452702677908709,0 +"8066",2015-02-17 05:12:59,20.55,30.29,0,736,0.00453171731795767,0 +"8067",2015-02-17 05:13:59,20.6,30.245,0,743.5,0.00453901197440648,0 +"8068",2015-02-17 05:15:00,20.5666666666667,30.23,0,744.666666666667,0.00452736078188615,0 +"8069",2015-02-17 05:16:00,20.6,30.29,0,745,0.00454581469606991,0 +"8070",2015-02-17 05:17:00,20.6,30.2,0,746,0.00453220940046256,0 +"8071",2015-02-17 05:18:00,20.55,30.2,0,744,0.0045181545190451,0 +"8072",2015-02-17 05:19:00,20.5,30.23,0,732.666666666667,0.00450864488318446,0 +"8073",2015-02-17 05:19:59,20.5,30.29,0,734,0.00451765856170965,0 +"8074",2015-02-17 05:21:00,20.55,30.245,0,742,0.00452493584510067,0 +"8075",2015-02-17 05:22:00,20.5,30.26,0,739.666666666667,0.00451315169002698,0 +"8076",2015-02-17 05:23:00,20.5,30.29,0,739.333333333333,0.00451765856170965,0 +"8077",2015-02-17 05:23:59,20.5,30.29,0,733.5,0.00451765856170965,0 +"8078",2015-02-17 05:25:00,20.5,30.29,0,735,0.00451765856170965,0 +"8079",2015-02-17 05:25:59,20.5,30.29,0,740.5,0.00451765856170965,0 +"8080",2015-02-17 05:26:59,20.5,30.39,0,738.75,0.0045326819356264,0 +"8081",2015-02-17 05:28:00,20.5,30.39,0,744,0.0045326819356264,0 +"8082",2015-02-17 05:29:00,20.5,30.39,0,742,0.0045326819356264,0 +"8083",2015-02-17 05:30:00,20.5,30.39,0,741.666666666667,0.0045326819356264,0 +"8084",2015-02-17 05:31:00,20.39,30.34,0,739.5,0.00449432482371647,0 +"8085",2015-02-17 05:31:59,20.39,30.39,0,735.666666666667,0.00450178502960536,0 +"8086",2015-02-17 05:32:59,20.39,30.39,0,730,0.00450178502960536,0 +"8087",2015-02-17 05:34:00,20.39,30.39,0,731,0.00450178502960536,0 +"8088",2015-02-17 05:35:00,20.39,30.445,0,729.5,0.00450999146129486,0 +"8089",2015-02-17 05:36:00,20.39,30.5,0,733,0.00451819810797625,0 +"8090",2015-02-17 05:37:00,20.39,30.5,0,732,0.00451819810797625,0 +"8091",2015-02-17 05:38:00,20.39,30.5,0,734.75,0.00451819810797625,0 +"8092",2015-02-17 05:38:59,20.39,30.5,0,738,0.00451819810797625,0 +"8093",2015-02-17 05:39:59,20.29,30.5,0,738,0.00449016902073007,0 +"8094",2015-02-17 05:41:00,20.34,30.5,0,738.5,0.00450416430863932,0 +"8095",2015-02-17 05:42:00,20.39,30.5,0,737.333333333333,0.00451819810797625,0 +"8096",2015-02-17 05:43:00,20.39,30.5,0,739,0.00451819810797625,0 +"8097",2015-02-17 05:44:00,20.39,30.5,0,739,0.00451819810797625,0 +"8098",2015-02-17 05:44:59,20.34,30.5,0,735.5,0.00450416430863932,0 +"8099",2015-02-17 05:45:59,20.29,30.5,0,736.5,0.00449016902073007,0 +"8100",2015-02-17 05:47:00,20.29,30.6,0,732.666666666667,0.00450499751333018,0 +"8101",2015-02-17 05:48:00,20.29,30.6,0,732.333333333333,0.00450499751333018,0 +"8102",2015-02-17 05:49:00,20.29,30.6333333333333,0,726,0.00450994050018828,0 +"8103",2015-02-17 05:50:00,20.2,30.55,0,736.5,0.00447244668548565,0 +"8104",2015-02-17 05:51:00,20.2,30.6,0,746.5,0.00447981928533327,0 +"8105",2015-02-17 05:51:59,20.2,30.6,0,750,0.00447981928533327,0 +"8106",2015-02-17 05:53:00,20.2,30.6,0,749.5,0.00447981928533327,0 +"8107",2015-02-17 05:54:00,20.26,30.6666666666667,0,743.666666666667,0.0045064583902316,0 +"8108",2015-02-17 05:55:00,20.26,30.6666666666667,0,742,0.0045064583902316,0 +"8109",2015-02-17 05:55:59,20.2,30.6,0,736.333333333333,0.00447981928533327,0 +"8110",2015-02-17 05:57:00,20.23,30.6333333333333,0,736,0.00449312260515927,0 +"8111",2015-02-17 05:57:59,20.2,30.6,0,740,0.00447981928533327,0 +"8112",2015-02-17 05:58:59,20.2675,30.675,0,744.75,0.00450979741708465,0 +"8113",2015-02-17 06:00:00,20.245,30.65,0,743,0.00449978643533299,0 +"8114",2015-02-17 06:01:00,20.29,30.6,0,748.5,0.00450499751333018,0 +"8115",2015-02-17 06:02:00,20.29,30.5,0,749,0.00449016902073007,0 +"8116",2015-02-17 06:03:00,20.29,30.5,0,744,0.00449016902073007,0 +"8117",2015-02-17 06:04:00,20.34,30.5,0,740.75,0.00450416430863932,0 +"8118",2015-02-17 06:04:59,20.3566666666667,30.5,0,745.333333333333,0.00450883795817739,0 +"8119",2015-02-17 06:06:00,20.39,30.5,0,748.5,0.00451819810797625,0 +"8120",2015-02-17 06:07:00,20.39,30.5,0,735.5,0.00451819810797625,0 +"8121",2015-02-17 06:08:00,20.39,30.5,0,734,0.00451819810797625,0 +"8122",2015-02-17 06:08:59,20.39,30.5,0,734,0.00451819810797625,0 +"8123",2015-02-17 06:10:00,20.39,30.5,0,734,0.00451819810797625,0 +"8124",2015-02-17 06:10:59,20.3566666666667,30.5,0,746.5,0.00450883795817739,0 +"8125",2015-02-17 06:11:59,20.39,30.5,0,749.666666666667,0.00451819810797625,0 +"8126",2015-02-17 06:13:00,20.39,30.5,0,745.5,0.00451819810797625,0 +"8127",2015-02-17 06:14:00,20.39,30.5,0,744,0.00451819810797625,0 +"8128",2015-02-17 06:15:00,20.39,30.445,0,746,0.00450999146129486,0 +"8129",2015-02-17 06:16:00,20.39,30.39,0,743,0.00450178502960536,0 +"8130",2015-02-17 06:16:59,20.39,30.39,0,747,0.00450178502960536,0 +"8131",2015-02-17 06:17:59,20.39,30.39,0,743.666666666667,0.00450178502960536,0 +"8132",2015-02-17 06:19:00,20.39,30.39,0,744.333333333333,0.00450178502960536,0 +"8133",2015-02-17 06:20:00,20.39,30.39,0,750.5,0.00450178502960536,0 +"8134",2015-02-17 06:21:00,20.39,30.39,0,748,0.00450178502960536,0 +"8135",2015-02-17 06:22:00,20.39,30.3566666666667,0,755,0.0044968115392718,0 +"8136",2015-02-17 06:23:00,20.39,30.29,0,749,0.00448686479549351,0 +"8137",2015-02-17 06:23:59,20.39,30.39,0,749,0.00450178502960536,0 +"8138",2015-02-17 06:24:59,20.5,30.39,0,749,0.0045326819356264,0 +"8139",2015-02-17 06:26:00,20.445,30.34,0,751,0.0045097242016922,0 +"8140",2015-02-17 06:27:00,20.5,30.39,0,751,0.0045326819356264,0 +"8141",2015-02-17 06:28:00,20.39,30.39,0,752.5,0.00450178502960536,0 +"8142",2015-02-17 06:29:00,20.39,30.39,0,752,0.00450178502960536,0 +"8143",2015-02-17 06:29:59,20.5,30.39,0,751,0.0045326819356264,0 +"8144",2015-02-17 06:30:59,20.5,30.39,0,748.5,0.0045326819356264,0 +"8145",2015-02-17 06:32:00,20.5,30.39,0,751.5,0.0045326819356264,0 +"8146",2015-02-17 06:33:00,20.5,30.39,0,748.5,0.0045326819356264,0 +"8147",2015-02-17 06:34:00,20.5,30.39,0,752,0.0045326819356264,0 +"8148",2015-02-17 06:35:00,20.5,30.39,0,754.5,0.0045326819356264,0 +"8149",2015-02-17 06:36:00,20.5,30.39,0,749.666666666667,0.0045326819356264,0 +"8150",2015-02-17 06:36:59,20.5,30.39,0,750.5,0.0045326819356264,0 +"8151",2015-02-17 06:38:00,20.5,30.39,0,754,0.0045326819356264,0 +"8152",2015-02-17 06:39:00,20.5,30.39,0,752.666666666667,0.0045326819356264,0 +"8153",2015-02-17 06:40:00,20.5,30.39,0,749.5,0.0045326819356264,0 +"8154",2015-02-17 06:40:59,20.5,30.39,0,747.333333333333,0.0045326819356264,0 +"8155",2015-02-17 06:42:00,20.5,30.39,0,748,0.0045326819356264,0 +"8156",2015-02-17 06:42:59,20.5,30.39,0,751.5,0.0045326819356264,0 +"8157",2015-02-17 06:43:59,20.5,30.39,0,762,0.0045326819356264,0 +"8158",2015-02-17 06:45:00,20.5,30.39,0,761.666666666667,0.0045326819356264,0 +"8159",2015-02-17 06:46:00,20.5,30.39,0,753,0.0045326819356264,0 +"8160",2015-02-17 06:47:00,20.5,30.39,0,765,0.0045326819356264,0 +"8161",2015-02-17 06:48:00,20.5,30.34,0,765.5,0.0045251701586071,0 +"8162",2015-02-17 06:49:00,20.5333333333333,30.3566666666667,0,762,0.00453706320108142,0 +"8163",2015-02-17 06:49:59,20.5,30.39,0,754,0.0045326819356264,0 +"8164",2015-02-17 06:51:00,20.6,30.39,0,755,0.00456093238421853,0 +"8165",2015-02-17 06:52:00,20.5333333333333,30.3566666666667,0,753.333333333333,0.00453706320108142,0 +"8166",2015-02-17 06:53:00,20.5,30.39,0,753,0.0045326819356264,0 +"8167",2015-02-17 06:53:59,20.6,30.39,0,752,0.00456093238421853,0 +"8168",2015-02-17 06:55:00,20.6,30.34,0,753.5,0.00455337344895307,0 +"8169",2015-02-17 06:55:59,20.6,30.29,0,759.5,0.00454581469606991,0 +"8170",2015-02-17 06:56:59,20.55,30.29,0,762,0.00453171731795767,0 +"8171",2015-02-17 06:58:00,20.55,30.29,0,758,0.00453171731795767,0 +"8172",2015-02-17 06:59:00,20.6,30.29,0,758.5,0.00454581469606991,0 +"8173",2015-02-17 07:00:00,20.6,30.29,0,763,0.00454581469606991,0 +"8174",2015-02-17 07:01:00,20.6,30.29,0,765,0.00454581469606991,0 +"8175",2015-02-17 07:01:59,20.6,30.29,0,758.5,0.00454581469606991,0 +"8176",2015-02-17 07:02:59,20.6,30.29,0,756.5,0.00454581469606991,0 +"8177",2015-02-17 07:04:00,20.6,30.245,0,760,0.00453901197440648,0 +"8178",2015-02-17 07:05:00,20.6,30.2,0,758,0.00453220940046256,0 +"8179",2015-02-17 07:06:00,20.65,30.245,0,759.5,0.00455312675812004,0 +"8180",2015-02-17 07:07:00,20.6666666666667,30.26,0,758.666666666667,0.00456011732377978,0 +"8181",2015-02-17 07:08:00,20.7,30.2,0,766,0.00456043504036532,0 +"8182",2015-02-17 07:08:59,20.6666666666667,30.26,0,762.333333333333,0.00456011732377978,0 +"8183",2015-02-17 07:09:59,20.6,30.2,0,761.5,0.00453220940046256,0 +"8184",2015-02-17 07:11:00,20.65,30.2,0,762,0.00454630287698865,0 +"8185",2015-02-17 07:12:00,20.7,30.2,0,763.5,0.00456043504036532,0 +"8186",2015-02-17 07:13:00,20.7,30.2,0,760,0.00456043504036532,0 +"8187",2015-02-17 07:14:00,20.6,30.2,0,761,0.00453220940046256,0 +"8188",2015-02-17 07:14:59,20.7,30.2,0,768,0.00456043504036532,0 +"8189",2015-02-17 07:15:59,20.7,30.2,0,768,0.00456043504036532,0 +"8190",2015-02-17 07:17:00,20.6666666666667,30.2,0,768,0.00455100929503942,0 +"8191",2015-02-17 07:18:00,20.7,30.2,0,768.666666666667,0.00456043504036532,0 +"8192",2015-02-17 07:19:00,20.7,30.2,0,771,0.00456043504036532,0 +"8193",2015-02-17 07:20:00,20.7,30.2,0,768.5,0.00456043504036532,0 +"8194",2015-02-17 07:21:00,20.7,30.2,0,761.666666666667,0.00456043504036532,0 +"8195",2015-02-17 07:21:59,20.7,30.2,0,762.5,0.00456043504036532,0 +"8196",2015-02-17 07:23:00,20.7,30.2,0,763,0.00456043504036532,0 +"8197",2015-02-17 07:24:00,20.7,30.2,0,765.5,0.00456043504036532,0 +"8198",2015-02-17 07:25:00,20.6666666666667,30.2,0,769,0.00455100929503942,0 +"8199",2015-02-17 07:25:59,20.7,30.2,0,769.5,0.00456043504036532,0 +"8200",2015-02-17 07:27:00,20.7,30.23,0,768.333333333333,0.00456499852225614,0 +"8201",2015-02-17 07:27:59,20.7,30.2,0,768.5,0.00456043504036532,0 +"8202",2015-02-17 07:28:59,20.7,30.2,0,771,0.00456043504036532,0 +"8203",2015-02-17 07:30:00,20.7,30.2,0,770.5,0.00456043504036532,0 +"8204",2015-02-17 07:31:00,20.7,30.29,0,774,0.00457412568546629,0 +"8205",2015-02-17 07:32:00,20.7,30.29,0,775,0.00457412568546629,0 +"8206",2015-02-17 07:33:00,20.7,30.26,0,776.666666666667,0.00456956207062264,0 +"8207",2015-02-17 07:34:00,20.7,30.245,0,773.5,0.00456728028812984,0 +"8208",2015-02-17 07:34:59,20.7,30.29,0,771,0.00457412568546629,0 +"8209",2015-02-17 07:36:00,20.6,30.2,0,771,0.00453220940046256,0 +"8210",2015-02-17 07:37:00,20.7,30.29,0,776,0.00457412568546629,0 +"8211",2015-02-17 07:38:00,20.7,30.29,0,774.5,0.00457412568546629,0 +"8212",2015-02-17 07:38:59,20.6666666666667,30.26,0,770.666666666667,0.00456011732377978,0 +"8213",2015-02-17 07:40:00,20.7,30.29,0,772,0.00457412568546629,0 +"8214",2015-02-17 07:40:59,20.7,30.29,0,773,0.00457412568546629,0 +"8215",2015-02-17 07:41:59,20.6,30.2,0,773,0.00453220940046256,0 +"8216",2015-02-17 07:43:00,20.7,30.29,0,770.5,0.00457412568546629,0 +"8217",2015-02-17 07:44:00,20.7,30.29,0,770.5,0.00457412568546629,0 +"8218",2015-02-17 07:45:00,20.675,30.2675,0,773,0.00456361600850634,0 +"8219",2015-02-17 07:46:00,20.7,30.245,0,782.5,0.00456728028812984,0 +"8220",2015-02-17 07:46:59,20.65,30.245,0,778.5,0.00455312675812004,0 +"8221",2015-02-17 07:47:59,20.65,30.245,0,770,0.00455312675812004,0 +"8222",2015-02-17 07:49:00,20.7,30.29,0,774.5,0.00457412568546629,0 +"8223",2015-02-17 07:50:00,20.65,30.29,0,774.5,0.00455995078789443,0 +"8224",2015-02-17 07:51:00,20.65,30.34,0,775.5,0.0045675332175396,0 +"8225",2015-02-17 07:52:00,20.6,30.29,0,778,0.00454581469606991,0 +"8226",2015-02-17 07:53:00,20.7,30.39,0,772.333333333333,0.00458933821507646,0 +"8227",2015-02-17 07:53:59,20.6,30.29,0,773,0.00454581469606991,0 +"8228",2015-02-17 07:54:59,20.6,30.29,0,775,0.00454581469606991,0 +"8229",2015-02-17 07:56:00,20.7,30.39,0,780,0.00458933821507646,0 +"8230",2015-02-17 07:57:00,20.6,30.29,0,780,0.00454581469606991,0 +"8231",2015-02-17 07:58:00,20.6,30.29,0,782.5,0.00454581469606991,0 +"8232",2015-02-17 07:59:00,20.6333333333333,30.3233333333333,0,781.666666666667,0.00456028411644251,0 +"8233",2015-02-17 07:59:59,20.6,30.39,0,776.5,0.00456093238421853,0 +"8234",2015-02-17 08:00:59,20.6,30.39,0,774.5,0.00456093238421853,0 +"8235",2015-02-17 08:02:00,20.6,30.39,0,773,0.00456093238421853,0 +"8236",2015-02-17 08:03:00,20.6,30.39,0,773,0.00456093238421853,0 +"8237",2015-02-17 08:04:00,20.6,30.39,0,782,0.00456093238421853,0 +"8238",2015-02-17 08:05:00,20.6,30.39,0,784.5,0.00456093238421853,0 +"8239",2015-02-17 08:06:00,20.6,30.39,0,782,0.00456093238421853,0 +"8240",2015-02-17 08:06:59,20.6,30.39,0,781.333333333333,0.00456093238421853,0 +"8241",2015-02-17 08:08:00,20.7,30.5,0,783,0.00460607285085383,0 +"8242",2015-02-17 08:09:00,20.6,30.39,0,790.666666666667,0.00456093238421853,0 +"8243",2015-02-17 08:10:00,20.6,30.39,0,789.666666666667,0.00456093238421853,0 +"8244",2015-02-17 08:10:59,20.6,30.39,0,787,0.00456093238421853,0 +"8245",2015-02-17 08:12:00,20.6,30.39,0,783.333333333333,0.00456093238421853,0 +"8246",2015-02-17 08:12:59,20.6,30.39,0,781.5,0.00456093238421853,0 +"8247",2015-02-17 08:13:59,20.6,30.39,0,779.5,0.00456093238421853,0 +"8248",2015-02-17 08:15:00,20.6,30.39,0,779,0.00456093238421853,0 +"8249",2015-02-17 08:16:00,20.6,30.39,0,788,0.00456093238421853,0 +"8250",2015-02-17 08:17:00,20.6,30.39,0,789,0.00456093238421853,0 +"8251",2015-02-17 08:18:00,20.6,30.39,0,785,0.00456093238421853,0 +"8252",2015-02-17 08:19:00,20.6,30.39,0,783,0.00456093238421853,0 +"8253",2015-02-17 08:19:59,20.6,30.39,0,784.5,0.00456093238421853,0 +"8254",2015-02-17 08:21:00,20.6,30.39,0,792,0.00456093238421853,0 +"8255",2015-02-17 08:22:00,20.6,30.39,0,790.666666666667,0.00456093238421853,0 +"8256",2015-02-17 08:23:00,20.6,30.39,0,784,0.00456093238421853,0 +"8257",2015-02-17 08:23:59,20.6,30.39,0,786,0.00456093238421853,0 +"8258",2015-02-17 08:25:00,20.6,30.39,0,787,0.00456093238421853,0 +"8259",2015-02-17 08:25:59,20.6,30.39,0,787,0.00456093238421853,0 +"8260",2015-02-17 08:26:59,20.6,30.39,0,794,0.00456093238421853,0 +"8261",2015-02-17 08:28:00,20.6,30.39,0,787,0.00456093238421853,0 +"8262",2015-02-17 08:29:00,20.6,30.4266666666667,0,785.333333333333,0.00456647571933112,0 +"8263",2015-02-17 08:30:00,20.6,30.39,0,790,0.00456093238421853,0 +"8264",2015-02-17 08:31:00,20.6,30.39,0,796.5,0.00456093238421853,0 +"8265",2015-02-17 08:31:59,20.6,30.39,0,796,0.00456093238421853,0 +"8266",2015-02-17 08:32:59,20.6,30.39,0,796,0.00456093238421853,0 +"8267",2015-02-17 08:34:00,20.6,30.39,0,791,0.00456093238421853,0 +"8268",2015-02-17 08:35:00,20.6,30.445,0,797.5,0.00456924742366998,0 +"8269",2015-02-17 08:36:00,20.6,30.4266666666667,0,798.333333333333,0.00456647571933112,0 +"8270",2015-02-17 08:37:00,20.6,30.5,0,787,0.00457756268382079,0 +"8271",2015-02-17 08:38:00,20.6,30.5,101.333333333333,787.666666666667,0.00457756268382079,0 +"8272",2015-02-17 08:38:59,20.5666666666667,30.5,301,785.666666666667,0.00456809398968827,1 +"8273",2015-02-17 08:39:59,20.6,30.5,419,794.75,0.00457756268382079,1 +"8274",2015-02-17 08:41:00,20.6,30.5,419,801,0.00457756268382079,1 +"8275",2015-02-17 08:42:00,20.6,30.6333333333333,419,804.666666666667,0.00459772180633486,0 +"8276",2015-02-17 08:43:00,20.625,30.7225,419,814.25,0.00461836949378085,0 +"8277",2015-02-17 08:44:00,20.6,30.745,419,818.5,0.00461460606958226,1 +"8278",2015-02-17 08:44:59,20.7,30.89,419,825,0.00466541194477645,1 +"8279",2015-02-17 08:45:59,20.6333333333333,30.89,405,823.666666666667,0.00464614089960618,1 +"8280",2015-02-17 08:47:00,20.675,30.9175,405,827.25,0.00466235509894657,1 +"8281",2015-02-17 08:48:00,20.675,30.9175,405,834,0.00466235509894657,1 +"8282",2015-02-17 08:49:00,20.7,30.945,405,840.5,0.00467378118278058,1 +"8283",2015-02-17 08:50:00,20.7,30.9175,405,832,0.0046695965358355,1 +"8284",2015-02-17 08:51:00,20.7225,30.89,405,828,0.00467193183825474,1 +"8285",2015-02-17 08:51:59,20.76,30.89,405,830,0.00468281621263778,1 +"8286",2015-02-17 08:53:00,20.745,30.89,405,831.75,0.00467845977818504,1 +"8287",2015-02-17 08:54:00,20.79,30.8566666666667,405,834,0.00468643905693435,1 +"8288",2015-02-17 08:55:00,20.79,30.89,405,839.5,0.00469153983182186,1 +"8289",2015-02-17 08:55:59,20.79,30.89,405,840.25,0.00469153983182186,1 +"8290",2015-02-17 08:57:00,20.79,30.89,405,835,0.00469153983182186,1 +"8291",2015-02-17 08:57:59,20.79,30.89,405,839.5,0.00469153983182186,1 +"8292",2015-02-17 08:58:59,20.79,30.89,405,840,0.00469153983182186,1 +"8293",2015-02-17 09:00:00,20.79,30.89,405,832.75,0.00469153983182186,1 +"8294",2015-02-17 09:01:00,20.8233333333333,30.8566666666667,405,840.666666666667,0.00469613816331599,1 +"8295",2015-02-17 09:02:00,20.84,30.84,405,838.5,0.00469843602504216,1 +"8296",2015-02-17 09:03:00,20.89,30.89,405,843,0.00472072232152342,1 +"8297",2015-02-17 09:04:00,20.89,30.89,405,846.5,0.00472072232152342,1 +"8298",2015-02-17 09:04:59,20.89,30.89,412,850.25,0.00472072232152342,1 +"8299",2015-02-17 09:06:00,20.89,30.89,419,857,0.00472072232152342,1 +"8300",2015-02-17 09:07:00,20.89,30.89,419,862,0.00472072232152342,1 +"8301",2015-02-17 09:08:00,20.89,30.89,419,851.666666666667,0.00472072232152342,1 +"8302",2015-02-17 09:08:59,20.89,30.89,419,850.333333333333,0.00472072232152342,1 +"8303",2015-02-17 09:10:00,20.945,30.89,419,856.75,0.0047368409323156,1 +"8304",2015-02-17 09:10:59,20.9175,30.89,419,855.25,0.0047287755610291,1 +"8305",2015-02-17 09:11:59,20.9266666666667,30.89,419,858,0.00473146266936738,1 +"8306",2015-02-17 09:13:00,20.9725,30.89,419,861.75,0.00474491845121701,1 +"8307",2015-02-17 09:14:00,20.9725,31.1475,423.666666666667,864.333333333333,0.0047847765090403,1 +"8308",2015-02-17 09:15:00,20.945,31.15,428.333333333333,873.333333333333,0.00477701695300657,1 +"8309",2015-02-17 09:16:00,20.9266666666667,31.26,433,875,0.00478857237462572,1 +"8310",2015-02-17 09:16:59,21,31.29,433,880,0.00481503211757805,1 +"8311",2015-02-17 09:17:59,21,31.345,429.5,894.75,0.00482356137540285,1 +"8312",2015-02-17 09:19:00,21,31.4966666666667,428.333333333333,920.333333333333,0.00484708265264768,1 +"8313",2015-02-17 09:20:00,21,31.4175,433,920.25,0.00483480484265129,1 +"8314",2015-02-17 09:21:00,21,31.55,433,920.5,0.00485535429054128,1 +"8315",2015-02-17 09:22:00,21,31.4175,429.5,934.5,0.00483480484265129,1 +"8316",2015-02-17 09:23:00,21,31.4266666666667,433,928.666666666667,0.00483622645918775,1 +"8317",2015-02-17 09:23:59,21.025,31.4175,433,924.75,0.00484229739168019,1 +"8318",2015-02-17 09:24:59,21.0333333333333,31.5333333333333,433,924.666666666667,0.0048627991402564,1 +"8319",2015-02-17 09:26:00,21.075,31.4725,433,926.25,0.00486588308247985,1 +"8320",2015-02-17 09:27:00,21.1,31.445,433,932,0.00486912818560733,1 +"8321",2015-02-17 09:28:00,21.1,31.445,433,923.5,0.00486912818560733,1 +"8322",2015-02-17 09:29:00,21.1,31.445,433,925.75,0.00486912818560733,1 +"8323",2015-02-17 09:29:59,21.1,31.55,433,928.5,0.00488551470657948,1 +"8324",2015-02-17 09:30:59,21.1,31.5,433,934.25,0.00487771149451183,1 +"8325",2015-02-17 09:32:00,21.1,31.575,433,937.666666666667,0.00488941638546303,1 +"8326",2015-02-17 09:33:00,21.1,31.39,433,946.75,0.00486054511174767,1 +"8327",2015-02-17 09:34:00,21.1,31.39,433,940,0.00486054511174767,1 +"8328",2015-02-17 09:35:00,21.1,31.39,433,936.5,0.00486054511174767,1 +"8329",2015-02-17 09:36:00,21.1,31.39,433,940.333333333333,0.00486054511174767,1 +"8330",2015-02-17 09:36:59,21.1,31.365,433,938,0.00485664379223689,1 +"8331",2015-02-17 09:38:00,21.1,31.39,433,937,0.00486054511174767,1 +"8332",2015-02-17 09:39:00,21.1,31.4175,433,937,0.0048648366192975,1 +"8333",2015-02-17 09:40:00,21.1,31.39,433,939.5,0.00486054511174767,1 +"8334",2015-02-17 09:40:59,21.1,31.39,433,941,0.00486054511174767,1 +"8335",2015-02-17 09:42:00,21.1,31.575,433,953.75,0.00488941638546303,1 +"8336",2015-02-17 09:42:59,21.1,31.4266666666667,433,953.666666666667,0.00486626713487183,1 +"8337",2015-02-17 09:43:59,21.1,31.4725,433,948.25,0.00487341981067837,1 +"8338",2015-02-17 09:45:00,21.1,31.445,433,951.25,0.00486912818560733,1 +"8339",2015-02-17 09:46:00,21.15,31.39,433,950.5,0.00487560929831198,1 +"8340",2015-02-17 09:47:00,21.15,31.34,433,941.75,0.00486778233765936,1 +"8341",2015-02-17 09:48:00,21.2,31.39,433,942.5,0.00489071471264367,1 +"8342",2015-02-17 09:49:00,21.175,31.34,433,939.75,0.00487531767471348,1 +"8343",2015-02-17 09:49:59,21.175,31.39,433,939.25,0.00488315684589931,1 +"8344",2015-02-17 09:51:00,21.2,31.29,433,939,0.00487501211189772,1 +"8345",2015-02-17 09:52:00,21.2,31.29,433,938,0.00487501211189772,1 +"8346",2015-02-17 09:53:00,21.175,31.315,433,945.2,0.00487139816264171,1 +"8347",2015-02-17 09:53:59,21.2,31.34,433,950,0.00488286331393826,1 +"8348",2015-02-17 09:55:00,21.2,31.315,433,949.5,0.00487893768833534,1 +"8349",2015-02-17 09:55:59,21.2,31.3233333333333,433,948.333333333333,0.00488024622474013,1 +"8350",2015-02-17 09:56:59,21.2,31.39,433,946,0.00489071471264367,1 +"8351",2015-02-17 09:58:00,21.2,31.39,433,947.333333333333,0.00489071471264367,1 +"8352",2015-02-17 09:59:00,21.2,31.34,433,952.5,0.00488286331393826,1 +"8353",2015-02-17 10:00:00,21.2,31.39,433,952.666666666667,0.00489071471264367,1 +"8354",2015-02-17 10:01:00,21.2,31.365,433,958.75,0.0048867889887074,1 +"8355",2015-02-17 10:01:59,21.2,31.34,433,961,0.00488286331393826,1 +"8356",2015-02-17 10:02:59,21.2,31.3566666666667,433,957,0.00488548042498805,1 +"8357",2015-02-17 10:04:00,21.2,31.34,433,956.75,0.00488286331393826,1 +"8358",2015-02-17 10:05:00,21.2225,31.3925,433,958.25,0.00489791875177898,1 +"8359",2015-02-17 10:06:00,21.245,31.34,433,957.5,0.00489647146499429,1 +"8360",2015-02-17 10:07:00,21.23,31.3233333333333,433,957,0.00488930970953872,1 +"8361",2015-02-17 10:08:00,21.2675,31.365,433,970.75,0.00490723031899548,1 +"8362",2015-02-17 10:08:59,21.23,31.3233333333333,433,974,0.00488930970953872,1 +"8363",2015-02-17 10:09:59,21.245,31.365,433,974.75,0.00490040816582962,1 +"8364",2015-02-17 10:11:00,21.2675,31.39,433,965.5,0.0049111725927957,1 +"8365",2015-02-17 10:12:00,21.26,31.29,433,960.666666666667,0.00489313433797612,1 +"8366",2015-02-17 10:13:00,21.29,31.29,433,955.666666666667,0.00490221774608623,1 +"8367",2015-02-17 10:14:00,21.29,31.29,433,965,0.00490221774608623,1 +"8368",2015-02-17 10:14:59,21.29,31.245,433,960.5,0.00489511209223225,1 +"8369",2015-02-17 10:15:59,21.29,31.23,433,953.333333333333,0.00489274357674274,1 +"8370",2015-02-17 10:17:00,21.29,31.29,433,953.666666666667,0.00490221774608623,1 +"8371",2015-02-17 10:18:00,21.2675,31.2675,433,964,0.00489185592491196,1 +"8372",2015-02-17 10:19:00,21.29,31.29,433,966.5,0.00490221774608623,1 +"8373",2015-02-17 10:20:00,21.29,31.29,433,959,0.00490221774608623,1 +"8374",2015-02-17 10:21:00,21.245,31.245,433,960,0.00488151245272057,1 +"8375",2015-02-17 10:21:59,21.29,31.29,429.5,957.75,0.00490221774608623,1 +"8376",2015-02-17 10:23:00,21.29,31.29,433,960,0.00490221774608623,1 +"8377",2015-02-17 10:24:00,21.29,31.39,429.5,960.5,0.00491800866470675,1 +"8378",2015-02-17 10:25:00,21.2675,31.365,422.5,971.25,0.00490723031899548,1 +"8379",2015-02-17 10:25:59,21.29,31.39,433,973,0.00491800866470675,1 +"8380",2015-02-17 10:27:00,21.2675,31.365,419,977,0.00490723031899548,1 +"8381",2015-02-17 10:27:59,21.29,31.29,423.666666666667,976.666666666667,0.00490221774608623,1 +"8382",2015-02-17 10:28:59,21.29,31.29,428.333333333333,978.666666666667,0.00490221774608623,1 +"8383",2015-02-17 10:30:00,21.29,31.29,433,977,0.00490221774608623,1 +"8384",2015-02-17 10:31:00,21.29,31.29,426,977.25,0.00490221774608623,1 +"8385",2015-02-17 10:32:00,21.29,31.315,426,979,0.00490616540116382,1 +"8386",2015-02-17 10:33:00,21.26,31.29,428.333333333333,982,0.00489313433797612,1 +"8387",2015-02-17 10:34:00,21.29,31.29,433,981,0.00490221774608623,1 +"8388",2015-02-17 10:34:59,21.29,31.39,433,982,0.00491800866470675,1 +"8389",2015-02-17 10:36:00,21.29,31.315,433,978.5,0.00490616540116382,1 +"8390",2015-02-17 10:37:00,21.29,31.34,433,983,0.00491011310595914,1 +"8391",2015-02-17 10:38:00,21.29,31.29,433,985,0.00490221774608623,1 +"8392",2015-02-17 10:38:59,21.29,31.34,433,981.666666666667,0.00491011310595914,1 +"8393",2015-02-17 10:40:00,21.29,31.315,433,991.5,0.00490616540116382,1 +"8394",2015-02-17 10:40:59,21.29,31.3233333333333,433,991.333333333333,0.00490748129723802,1 +"8395",2015-02-17 10:41:59,21.29,31.39,433,990,0.00491800866470675,1 +"8396",2015-02-17 10:43:00,21.29,31.315,433,993.25,0.00490616540116382,1 +"8397",2015-02-17 10:44:00,21.29,31.29,433,986.75,0.00490221774608623,1 +"8398",2015-02-17 10:45:00,21.29,31.29,433,984,0.00490221774608623,1 +"8399",2015-02-17 10:46:00,21.29,31.29,433,983,0.00490221774608623,1 +"8400",2015-02-17 10:46:59,21.31,31.29,433,989,0.00490828162327326,1 +"8401",2015-02-17 10:47:59,21.3233333333333,31.3566666666667,442.5,986,0.0049228769601335,1 +"8402",2015-02-17 10:49:00,21.365,31.39,433.5,989.75,0.00494085631821017,1 +"8403",2015-02-17 10:50:00,21.39,31.4266666666667,429,993,0.0049543193882462,1 +"8404",2015-02-17 10:51:00,21.315,31.5,433.5,999,0.00494301216183459,1 +"8405",2015-02-17 10:52:00,21.29,31.5666666666667,435,1002.66666666667,0.00494590789849128,1 +"8406",2015-02-17 10:53:00,21.365,31.6,438,1005.25,0.00497417512742665,1 +"8407",2015-02-17 10:53:59,21.39,31.6,438,1002.5,0.00498186372784494,1 +"8408",2015-02-17 10:54:59,21.3233333333333,31.6333333333333,441,1003,0.00496665940321308,1 +"8409",2015-02-17 10:56:00,21.39,31.7,438,1007,0.00499775579394974,1 +"8410",2015-02-17 10:57:00,21.39,31.7225,438,1008,0.00500133161984987,1 +"8411",2015-02-17 10:58:00,21.39,31.79,437.666666666667,1015.33333333333,0.0050120593422736,1 +"8412",2015-02-17 10:59:00,21.39,31.79,433,1015.5,0.0050120593422736,1 +"8413",2015-02-17 10:59:59,21.34,31.945,433,1014,0.00502115756202247,1 +"8414",2015-02-17 11:00:59,21.39,31.945,440,1040.25,0.00503669476091262,1 +"8415",2015-02-17 11:02:00,21.3566666666667,31.9633333333333,437.666666666667,1039.33333333333,0.00502923986775897,1 +"8416",2015-02-17 11:03:00,21.39,32,433,1030.5,0.00504543682641298,1 +"8417",2015-02-17 11:04:00,21.39,32.03,433,1031.33333333333,0.00505020532852006,1 +"8418",2015-02-17 11:05:00,21.39,32.045,433,1043.5,0.00505258960677102,1 +"8419",2015-02-17 11:06:00,21.3566666666667,32.09,441,1046.66666666667,0.00504933190397887,1 +"8420",2015-02-17 11:06:59,21.39,32.1175,438,1048.75,0.00506411387393045,1 +"8421",2015-02-17 11:08:00,21.39,32.3333333333333,441,1046,0.00509842425747431,1 +"8422",2015-02-17 11:09:00,21.39,32.2966666666667,441,1052,0.00509259520170316,1 +"8423",2015-02-17 11:10:00,21.39,32.2675,429,1059.25,0.0050879585301776,1 +"8424",2015-02-17 11:10:59,21.39,32.44,425.25,1069.75,0.00511538212680952,1 +"8425",2015-02-17 11:12:00,21.39,32.345,433.5,1079.5,0.00510027897976353,1 +"8426",2015-02-17 11:12:59,21.39,32.29,441,1076,0.00509153538502368,1 +"8427",2015-02-17 11:13:59,21.39,32.29,433,1075,0.00509153538502368,1 +"8428",2015-02-17 11:15:00,21.39,32.475,430.75,1078.5,0.00512094662752816,1 +"8429",2015-02-17 11:16:00,21.39,32.4,437.666666666667,1074,0.00510902281833226,1 +"8430",2015-02-17 11:17:00,21.39,32.4,433,1079.5,0.00510902281833226,1 +"8431",2015-02-17 11:18:00,21.39,32.45,433,1068,0.00511697197408129,1 +"8432",2015-02-17 11:19:00,21.39,32.4333333333333,433,1072.66666666667,0.00511432223310671,1 +"8433",2015-02-17 11:19:59,21.39,32.45,433,1084.25,0.00511697197408129,1 +"8434",2015-02-17 11:21:00,21.39,32.45,433,1092,0.00511697197408129,1 +"8435",2015-02-17 11:22:00,21.39,32.545,433,1090,0.00513207592521922,1 +"8436",2015-02-17 11:23:00,21.4175,32.6725,433,1097,0.0051611099695114,1 +"8437",2015-02-17 11:23:59,21.4266666666667,32.56,433,1103.33333333333,0.00514610526134464,1 +"8438",2015-02-17 11:25:00,21.39,32.65,435.5,1105,0.00514877061242971,1 +"8439",2015-02-17 11:25:59,21.39,32.7,441,1109,0.00515672077589322,1 +"8440",2015-02-17 11:26:59,21.39,32.59,438,1103.25,0.00513923068232968,1 +"8441",2015-02-17 11:28:00,21.4175,32.545,438,1098.75,0.00514080297721831,1 +"8442",2015-02-17 11:29:00,21.4266666666667,32.5,441,1095,0.00513654395478294,1 +"8443",2015-02-17 11:30:00,21.4266666666667,32.4966666666667,441,1089.66666666667,0.00513601277963326,1 +"8444",2015-02-17 11:31:00,21.412,32.498,433.5,1083.25,0.00513157369914483,1 +"8445",2015-02-17 11:31:59,21.39,32.5,429,1084.33333333333,0.00512492133135788,1 +"8446",2015-02-17 11:32:59,21.4175,32.475,444,1083.75,0.00512965459944987,1 +"8447",2015-02-17 11:34:00,21.39,32.56,444,1082.66666666667,0.00513446082611697,1 +"8448",2015-02-17 11:35:00,21.39,32.475,429,1080.5,0.00512094662752816,1 +"8449",2015-02-17 11:36:00,21.39,32.475,432.75,1081,0.00512094662752816,1 +"8450",2015-02-17 11:37:00,21.39,32.5,434,1076,0.00512492133135788,1 +"8451",2015-02-17 11:38:00,21.39,32.5225,444,1076.25,0.00512849860788276,1 +"8452",2015-02-17 11:38:59,21.4175,32.6175,444,1077.75,0.00515234992919562,1 +"8453",2015-02-17 11:39:59,21.4266666666667,32.56,444,1086,0.00514610526134464,1 +"8454",2015-02-17 11:41:00,21.445,32.645,444,1088.5,0.00516549738356079,1 +"8455",2015-02-17 11:42:00,21.445,32.645,444,1092.5,0.00516549738356079,1 +"8456",2015-02-17 11:43:00,21.4266666666667,32.6266666666667,439,1099.66666666667,0.00515672927724083,1 +"8457",2015-02-17 11:44:00,21.5,32.7,429,1103.5,0.0051918771237193,1 +"8458",2015-02-17 11:44:59,21.5,32.6725,429,1108,0.00518747445165058,1 +"8459",2015-02-17 11:45:59,21.4725,32.6725,429,1115,0.00517867309763639,1 +"8460",2015-02-17 11:47:00,21.5,32.6725,432.75,1119,0.00518747445165058,1 +"8461",2015-02-17 11:48:00,21.5,32.6633333333333,444,1128.33333333333,0.00518600690802998,1 +"8462",2015-02-17 11:49:00,21.5,32.7,444,1135.75,0.0051918771237193,1 +"8463",2015-02-17 11:50:00,21.5,32.6725,444,1134.25,0.00518747445165058,1 +"8464",2015-02-17 11:51:00,21.5,32.645,460,1133,0.00518307184139193,1 +"8465",2015-02-17 11:51:59,21.5,32.6266666666667,454.666666666667,1131.66666666667,0.00518013680222444,1 +"8466",2015-02-17 11:53:00,21.525,32.7,444,1141.25,0.0051998966796797,1 +"8467",2015-02-17 11:54:00,21.525,32.6725,444,1153.66666666667,0.00519548715075522,1 +"8468",2015-02-17 11:55:00,21.5,32.6633333333333,444,1158,0.00518600690802998,1 +"8469",2015-02-17 11:55:59,21.55,32.7,440.25,1173,0.00520792718062367,1 +"8470",2015-02-17 11:57:00,21.6,32.6725,429,1172.25,0.00521959091260962,1 +"8471",2015-02-17 11:57:59,21.6,32.7,429,1177.33333333333,0.00522402106934216,1 +"8472",2015-02-17 11:58:59,21.575,32.6725,429,1178.25,0.00521154536827335,1 +"8473",2015-02-17 12:00:00,21.6,32.7,441,1181.66666666667,0.00522402106934216,1 +"8474",2015-02-17 12:01:00,21.6,32.7,438,1194,0.00522402106934216,1 +"8475",2015-02-17 12:02:00,21.6,32.7,438,1207,0.00522402106934216,1 +"8476",2015-02-17 12:03:00,21.6,32.7,441,1208.33333333333,0.00522402106934216,1 +"8477",2015-02-17 12:04:00,21.6,32.7,438,1211.25,0.00522402106934216,1 +"8478",2015-02-17 12:04:59,21.6,32.7225,438,1223.25,0.00522764578958119,1 +"8479",2015-02-17 12:06:00,21.6,32.7,438,1243,0.00522402106934216,1 +"8480",2015-02-17 12:07:00,21.6,32.7,441,1243,0.00522402106934216,1 +"8481",2015-02-17 12:08:00,21.6,32.7,429,1253.25,0.00522402106934216,1 +"8482",2015-02-17 12:08:59,21.6,32.7,429,1263.5,0.00522402106934216,1 +"8483",2015-02-17 12:10:00,21.6333333333333,32.73,429,1266.66666666667,0.00523961773220921,1 +"8484",2015-02-17 12:10:59,21.6,32.7,433.5,1271.5,0.00522402106934216,1 +"8485",2015-02-17 12:11:59,21.6,32.745,438,1275.5,0.0052312705517149,1 +"8486",2015-02-17 12:13:00,21.625,32.7675,438,1302,0.00524297569454225,1 +"8487",2015-02-17 12:14:00,21.6,32.73,441,1318.33333333333,0.00522885403897076,1 +"8488",2015-02-17 12:15:00,21.62,32.772,433.5,1342.75,0.0052420846139749,1 +"8489",2015-02-17 12:16:00,21.6666666666667,32.76,440.25,1377.75,0.00525525412873784,1 +"8490",2015-02-17 12:16:59,21.675,32.7675,452,1445,0.00525916944652414,1 +"8491",2015-02-17 12:17:59,21.6666666666667,32.76,446,1506,0.00525525412873784,1 +"8492",2015-02-17 12:19:00,21.675,32.7225,450.25,1382.25,0.00525188598281784,1 +"8493",2015-02-17 12:20:00,21.6333333333333,32.73,454,1303.33333333333,0.00523961773220921,1 +"8494",2015-02-17 12:21:00,21.7,32.79,454,1283,0.00527093034659311,1 +"8495",2015-02-17 12:22:00,21.675,32.745,454,1279.5,0.00525552769352775,1 +"8496",2015-02-17 12:23:00,21.6666666666667,32.76,454,1279.66666666667,0.00525525412873784,1 +"8497",2015-02-17 12:23:59,21.7,32.73,464,1286.33333333333,0.0052612038787908,1 +"8498",2015-02-17 12:24:59,21.7,33.07,454,1254,0.00531632451833733,1 +"8499",2015-02-17 12:26:00,21.7,33.145,454,1249.5,0.00532848478713063,1 +"8500",2015-02-17 12:27:00,21.7,33.0675,454,1254.5,0.00531591918416337,1 +"8501",2015-02-17 12:28:00,21.7,32.9333333333333,454,1235.66666666667,0.005294167018498,1 +"8502",2015-02-17 12:29:00,21.7,33.03,454,1214.66666666667,0.0053098392344099,1 +"8503",2015-02-17 12:29:59,21.675,33.0675,442.75,1205.5,0.00530773019420943,1 +"8504",2015-02-17 12:30:59,21.6666666666667,32.9666666666667,446,1209.33333333333,0.00528868882140902,1 +"8505",2015-02-17 12:32:00,21.7,32.95,444.25,1209,0.00529686906882136,1 +"8506",2015-02-17 12:33:00,21.7,32.9,449.5,1207.5,0.00528876298768437,1 +"8507",2015-02-17 12:34:00,21.7,32.95,444.25,1199.25,0.00529686906882136,1 +"8508",2015-02-17 12:35:00,21.7,32.8266666666667,439,1197.5,0.00527687444763391,1 +"8509",2015-02-17 12:36:00,21.7,32.925,442,1189.2,0.00529281600206551,1 +"8510",2015-02-17 12:36:59,21.6666666666667,32.9333333333333,454,1190.66666666667,0.0052832958879597,1 +"8511",2015-02-17 12:38:00,21.7,32.925,454,1187.5,0.00529281600206551,1 +"8512",2015-02-17 12:39:00,21.7,32.95,454,1177.25,0.00529686906882136,1 +"8513",2015-02-17 12:40:00,21.675,32.8175,464,1164.25,0.00526726238236026,1 +"8514",2015-02-17 12:40:59,21.7,32.95,459,1157,0.00529686906882136,1 +"8515",2015-02-17 12:42:00,21.7,33,455.666666666667,1160.33333333333,0.00530497535946122,1 +"8516",2015-02-17 12:42:59,21.675,32.845,464,1164.5,0.00527171358608501,1 +"8517",2015-02-17 12:43:59,21.7,32.925,460.25,1170,0.00529281600206551,1 +"8518",2015-02-17 12:45:00,21.7,32.79,464,1159.5,0.00527093034659311,1 +"8519",2015-02-17 12:46:00,21.7,32.9666666666667,464,1153.66666666667,0.00529957114242281,1 +"8520",2015-02-17 12:47:00,21.7,32.845,454,1150.25,0.00527984654039982,1 +"8521",2015-02-17 12:48:00,21.7,32.9666666666667,469,1150,0.00529957114242281,1 +"8522",2015-02-17 12:49:00,21.7,32.845,459,1149.75,0.00527984654039982,1 +"8523",2015-02-17 12:49:59,21.7,32.845,454,1154.25,0.00527984654039982,1 +"8524",2015-02-17 12:51:00,21.7,32.79,464,1155,0.00527093034659311,1 +"8525",2015-02-17 12:52:00,21.7,32.8633333333333,464,1156.66666666667,0.00528281866132993,1 +"8526",2015-02-17 12:53:00,21.7,32.975,471.5,1152,0.00530092218795292,1 +"8527",2015-02-17 12:53:59,21.7,32.975,479,1155,0.00530092218795292,1 +"8528",2015-02-17 12:55:00,21.7,32.95,469,1147,0.00529686906882136,1 +"8529",2015-02-17 12:55:59,21.7,33,474,1142,0.00530497535946122,1 +"8530",2015-02-17 12:56:59,21.7,32.79,474,1144.2,0.00527093034659311,1 +"8531",2015-02-17 12:58:00,21.73,32.8266666666667,464,1153.33333333333,0.00528664308007719,1 +"8532",2015-02-17 12:59:00,21.73,32.76,464,1151.33333333333,0.00527581553238284,1 +"8533",2015-02-17 13:00:00,21.7225,32.795,456.5,1140.75,0.00527905869044829,1 +"8534",2015-02-17 13:01:00,21.7,32.895,37,1143,0.00528795239109302,1 +"8535",2015-02-17 13:01:59,21.7,33.095,33.5,1164.5,0.00532037788888648,0 +"8536",2015-02-17 13:02:59,21.7,33.1175,19,1165.5,0.00532402596716697,0 +"8537",2015-02-17 13:04:00,21.7,33.09,37,1165.5,0.00531956721058616,0 +"8538",2015-02-17 13:05:00,21.7,33.09,37,1166.5,0.00531956721058616,0 +"8539",2015-02-17 13:06:00,21.7,33.09,37,1156,0.00531956721058616,0 +"8540",2015-02-17 13:07:00,21.7,33.09,28,1153.5,0.00531956721058616,0 +"8541",2015-02-17 13:08:00,21.7,33.09,33.5,1152,0.00531956721058616,0 +"8542",2015-02-17 13:08:59,21.7,33.09,33.5,1142.25,0.00531956721058616,0 +"8543",2015-02-17 13:09:59,21.7,33.09,38.3333333333333,1142,0.00531956721058616,0 +"8544",2015-02-17 13:11:00,21.7,33.09,38.3333333333333,1138,0.00531956721058616,0 +"8545",2015-02-17 13:12:00,21.7,33.09,33.5,1136.5,0.00531956721058616,0 +"8546",2015-02-17 13:13:00,21.7,33.09,26.25,1136.5,0.00531956721058616,0 +"8547",2015-02-17 13:14:00,21.7,33.09,31,1134.33333333333,0.00531956721058616,0 +"8548",2015-02-17 13:14:59,21.7,33.09,43.25,1134.33333333333,0.00531956721058616,0 +"8549",2015-02-17 13:15:59,21.7,33.09,42.25,1136.8,0.00531956721058616,0 +"8550",2015-02-17 13:17:00,21.65,33.045,44,1126.5,0.00529591569798562,0 +"8551",2015-02-17 13:18:00,21.7,33.09,44,1119.5,0.00531956721058616,0 +"8552",2015-02-17 13:19:00,21.6333333333333,33.03,44,1115,0.00528805186001503,0 +"8553",2015-02-17 13:20:00,21.7,33.09,40.5,1116.25,0.00531956721058616,0 +"8554",2015-02-17 13:21:00,21.7,33,40.5,1106,0.00530497535946122,0 +"8555",2015-02-17 13:21:59,21.65,33.0225,55,1105.25,0.00529227908250948,0 +"8556",2015-02-17 13:23:00,21.7,33.06,37,1114.33333333333,0.0053147031847843,0 +"8557",2015-02-17 13:24:00,21.675,33.0675,37,1112,0.00530773019420943,0 +"8558",2015-02-17 13:25:00,21.65,33.045,37,1113.5,0.00529591569798562,0 +"8559",2015-02-17 13:25:59,21.675,33.0675,101,1117.5,0.00530773019420943,0 +"8560",2015-02-17 13:27:00,21.6333333333333,33.1633333333333,332.666666666667,1129.33333333333,0.00530958054009819,0 +"8561",2015-02-17 13:27:59,21.675,33.19,431,1139.5,0.00532756132819109,0 +"8562",2015-02-17 13:28:59,21.65,33.2,454,1139,0.00532096908372805,0 +"8563",2015-02-17 13:30:00,21.7,33.145,454,1132.75,0.00532848478713063,1 +"8564",2015-02-17 13:31:00,21.7,33.2225,454,1130,0.00534105089350466,1 +"8565",2015-02-17 13:32:00,21.6666666666667,33.23,459,1128.33333333333,0.00533129625577424,1 +"8566",2015-02-17 13:33:00,21.675,33.2975,459,1125,0.0053449651930295,1 +"8567",2015-02-17 13:34:00,21.7,33.545,464,1130.75,0.00539334751701023,1 +"8568",2015-02-17 13:34:59,21.65,33.6175,470.5,1146.25,0.00538846154627499,1 +"8569",2015-02-17 13:36:00,21.7,33.645,462.75,1152.5,0.00540956529531318,1 +"8570",2015-02-17 13:37:00,21.7,33.69,464,1158,0.00541686356909426,1 +"8571",2015-02-17 13:38:00,21.7,33.79,469,1153,0.00543308256319014,1 +"8572",2015-02-17 13:38:59,21.7,33.79,457.75,1156.75,0.00543308256319014,1 +"8573",2015-02-17 13:40:00,21.7,33.745,454,1154.5,0.00542578391207939,1 +"8574",2015-02-17 13:40:59,21.7,33.8266666666667,454,1153.66666666667,0.00543902973779377,1 +"8575",2015-02-17 13:41:59,21.7,33.8175,457.75,1154.5,0.00543754293357337,1 +"8576",2015-02-17 13:43:00,21.7,33.9,454,1167,0.00545092442523207,1 +"8577",2015-02-17 13:44:00,21.73,33.86,449,1170,0.00545451788096643,1 +"8578",2015-02-17 13:45:00,21.7225,33.8725,449.5,1168,0.00545402630051425,1 +"8579",2015-02-17 13:46:00,21.7675,33.8975,448,1169.25,0.00547325113910275,1 +"8580",2015-02-17 13:46:59,21.736,33.98,444,1170,0.0054760444050842,1 +"8581",2015-02-17 13:47:59,21.79,33.95,444,1170.5,0.00548941072986437,1 +"8582",2015-02-17 13:49:00,21.7675,33.925,444,1173,0.00547773052350054,1 +"8583",2015-02-17 13:50:00,21.7675,33.95,444,1176,0.005481802746633,1 +"8584",2015-02-17 13:51:00,21.79,33.95,444,1178,0.00548941072986437,1 +"8585",2015-02-17 13:52:00,21.7675,33.95,444,1175,0.005481802746633,1 +"8586",2015-02-17 13:53:00,21.76,34,444,1174.66666666667,0.00548740963172261,1 +"8587",2015-02-17 13:53:59,21.7675,33.975,444,1174,0.00548587502262187,1 +"8588",2015-02-17 13:54:59,21.79,33.9333333333333,444,1174,0.00548669210782822,1 +"8589",2015-02-17 13:56:00,21.79,33.9,444,1183.75,0.00548125493442653,1 +"8590",2015-02-17 13:57:00,21.79,33.845,440.25,1185.5,0.0054722838043129,1 +"8591",2015-02-17 13:58:00,21.79,33.9333333333333,434,1187.66666666667,0.00548669210782822,1 +"8592",2015-02-17 13:59:00,21.79,34,429,1188,0.00549756673731766,1 +"8593",2015-02-17 13:59:59,21.79,33.925,429,1191.75,0.00548533280564403,1 +"8594",2015-02-17 14:00:59,21.79,34,441,1201,0.00549756673731766,1 +"8595",2015-02-17 14:02:00,21.79,33.925,436.2,1200.6,0.00548533280564403,1 +"8596",2015-02-17 14:03:00,21.79,34,435,1203,0.00549756673731766,1 +"8597",2015-02-17 14:04:00,21.79,33.925,433.5,1205.5,0.00548533280564403,1 +"8598",2015-02-17 14:05:00,21.79,33.9666666666667,429,1203,0.00549212937545778,1 +"8599",2015-02-17 14:06:00,21.79,33.95,429,1212.5,0.00548941072986437,1 +"8600",2015-02-17 14:06:59,21.79,34,444,1222,0.00549756673731766,1 +"8601",2015-02-17 14:08:00,21.79,34,444,1226,0.00549756673731766,1 +"8602",2015-02-17 14:09:00,21.79,34,444,1234,0.00549756673731766,1 +"8603",2015-02-17 14:10:00,21.79,34,444,1223.25,0.00549756673731766,1 +"8604",2015-02-17 14:10:59,21.79,34,447.666666666667,1229,0.00549756673731766,1 +"8605",2015-02-17 14:12:00,21.84,34.3175,446.5,1233.5,0.00556648904163571,1 +"8606",2015-02-17 14:12:59,21.84,34.475,452.75,1257.25,0.00559226610698814,1 +"8607",2015-02-17 14:13:59,21.89,34.4,449,1263.5,0.00559720650521025,1 +"8608",2015-02-17 14:15:00,21.89,34.2675,464,1252.75,0.00557545424798062,1 +"8609",2015-02-17 14:16:00,21.89,34.29,469,1255.5,0.00557914792122477,1 +"8610",2015-02-17 14:17:00,21.89,34.52,469,1265,0.00561690796397064,1 +"8611",2015-02-17 14:18:00,21.89,34.59,472.333333333333,1269,0.00562840105281332,1 +"8612",2015-02-17 14:19:00,21.89,34.5675,479,1277,0.0056247067997807,1 +"8613",2015-02-17 14:19:59,21.89,34.3966666666667,479,1285.5,0.00559665926012316,1 +"8614",2015-02-17 14:21:00,21.89,34.53,479,1283,0.00561854980803455,1 +"8615",2015-02-17 14:22:00,21.945,34.5675,469,1285.75,0.00564379217589783,1 +"8616",2015-02-17 14:23:00,21.89,34.59,472.333333333333,1297,0.00562840105281332,1 +"8617",2015-02-17 14:23:59,21.945,34.5,464,1294.25,0.00563267173586029,1 +"8618",2015-02-17 14:25:00,21.945,34.545,474,1286,0.00564008531876718,1 +"8619",2015-02-17 14:25:59,22,34.545,469,1296,0.00565921525072799,1 +"8620",2015-02-17 14:26:59,22,34.59,479,1306.33333333333,0.00566665438164527,1 +"8621",2015-02-17 14:28:00,22.025,34.595,464,1317.25,0.00567620817992093,1 +"8622",2015-02-17 14:29:00,22,34.4975,449,1318.75,0.00565136302606207,1 +"8623",2015-02-17 14:30:00,22,34.59,459,1316.5,0.00566665438164527,1 +"8624",2015-02-17 14:31:00,22,34.59,454,1320,0.00566665438164527,1 +"8625",2015-02-17 14:31:59,22.025,34.52,454,1317.25,0.00566379042929294,1 +"8626",2015-02-17 14:32:59,22.025,34.5,454,1322.5,0.00566047911210653,1 +"8627",2015-02-17 14:34:00,22,34.4966666666667,449,1320.33333333333,0.00565122526948824,1 +"8628",2015-02-17 14:35:00,22.05,34.545,454,1322.5,0.0056766558628319,1 +"8629",2015-02-17 14:36:00,22.0666666666667,34.53,454,1319.33333333333,0.00567998999553439,1 +"8630",2015-02-17 14:37:00,22.1,34.545,454,1321.75,0.00569414398611036,1 +"8631",2015-02-17 14:38:00,22.1,34.4,454,1321,0.0056700253772434,1 +"8632",2015-02-17 14:38:59,22.1,34.5266666666667,459,1329,0.00569109440446632,1 +"8633",2015-02-17 14:39:59,22.1,34.5225,459,1334.5,0.00569040132186161,1 +"8634",2015-02-17 14:41:00,22.1,34.545,449,1340.25,0.00569414398611036,1 +"8635",2015-02-17 14:42:00,22.1,34.5225,459,1345.25,0.00569040132186161,1 +"8636",2015-02-17 14:43:00,22.1,34.45,459,1357,0.00567834192954909,1 +"8637",2015-02-17 14:44:00,22.1,34.45,459,1348.25,0.00567834192954909,1 +"8638",2015-02-17 14:44:59,22.1,34.5,459,1344,0.00568665870224433,1 +"8639",2015-02-17 14:45:59,22.1,34.5,456.5,1354,0.00568665870224433,1 +"8640",2015-02-17 14:47:00,22.1,34.545,444,1353.5,0.00569414398611036,1 +"8641",2015-02-17 14:48:00,22.1,34.45,454,1338,0.00567834192954909,1 +"8642",2015-02-17 14:49:00,22.1,34.4666666666667,457.333333333333,1336,0.00568111416262601,1 +"8643",2015-02-17 14:50:00,22.1,34.3975,454,1337.5,0.00566960955541319,1 +"8644",2015-02-17 14:51:00,22.1,34.4333333333333,459,1342.33333333333,0.0056755697209599,1 +"8645",2015-02-17 14:51:59,22.1,34.3225,449,1340.5,0.00565713515669396,1 +"8646",2015-02-17 14:53:00,22.125,34.425,459,1339.5,0.00568291454708994,1 +"8647",2015-02-17 14:54:00,22.1,34.4,459,1342,0.0056700253772434,1 +"8648",2015-02-17 14:55:00,22.125,34.475,456.5,1361,0.00569124412255061,1 +"8649",2015-02-17 14:55:59,22.1666666666667,34.4,454,1364.66666666667,0.00569331699764442,1 +"8650",2015-02-17 14:57:00,22.1666666666667,34.4333333333333,444,1366.33333333333,0.0056988843234868,1 +"8651",2015-02-17 14:57:59,22.18,34.48,444.25,1366.5,0.00571135826470084,1 +"8652",2015-02-17 14:58:59,22.1666666666667,34.4666666666667,449.5,1368.75,0.00570445174808884,1 +"8653",2015-02-17 15:00:00,22.2,34.4333333333333,447.666666666667,1381.33333333333,0.00571057335054633,1 +"8654",2015-02-17 15:01:00,22.175,34.45,449.5,1379.75,0.0057045897344117,1 +"8655",2015-02-17 15:02:00,22.1666666666667,34.5,453,1386.66666666667,0.00571001927145317,1 +"8656",2015-02-17 15:03:00,22.175,34.425,444,1389.25,0.0057004120346292,1 +"8657",2015-02-17 15:04:00,22.175,34.45,444,1388.25,0.0057045897344117,1 +"8658",2015-02-17 15:04:59,22.2,34.4666666666667,439,1391,0.00571615229852824,1 +"8659",2015-02-17 15:06:00,22.2,34.5,429,1393.5,0.00572173134567986,1 +"8660",2015-02-17 15:07:00,22.2,34.5,436.5,1396.25,0.00572173134567986,1 +"8661",2015-02-17 15:08:00,22.2,34.5,444,1397,0.00572173134567986,1 +"8662",2015-02-17 15:08:59,22.2,34.5,444,1408.5,0.00572173134567986,1 +"8663",2015-02-17 15:10:00,22.2,34.47,441.75,1417.25,0.00571671019878072,1 +"8664",2015-02-17 15:10:59,22.2,34.245,449.5,1425.5,0.00567905415734882,1 +"8665",2015-02-17 15:11:59,22.2,34.1566666666667,453,1431.66666666667,0.00566427190940104,1 +"8666",2015-02-17 15:13:00,22.2,34.2725,449.5,1409.5,0.00568365632006241,1 +"8667",2015-02-17 15:14:00,22.2,34.2175,449.5,1409.75,0.00567445206212065,1 +"8668",2015-02-17 15:15:00,22.2,34.29,444,1401.5,0.00568658500419968,1 +"8669",2015-02-17 15:16:00,22.2,34.4,444,1410,0.00570499450173149,1 +"8670",2015-02-17 15:16:59,22.2,34.4,444,1405.75,0.00570499450173149,1 +"8671",2015-02-17 15:17:59,22.125,34.1725,444,1401.25,0.00564085356790667,1 +"8672",2015-02-17 15:19:00,22.175,34.0225,452,1393,0.00563315872223923,1 +"8673",2015-02-17 15:20:00,22.125,34.1175,442.75,1386.5,0.00563169251810878,1 +"8674",2015-02-17 15:21:00,22.1333333333333,34.26,444,1391.66666666667,0.00565832724643069,1 +"8675",2015-02-17 15:22:00,22.1333333333333,34.1566666666667,444,1399,0.00564110609697091,1 +"8676",2015-02-17 15:23:00,22.15,34.2,448,1405.25,0.00565411881081779,1 +"8677",2015-02-17 15:23:59,22.125,34.1675,441.5,1407.25,0.00564002073414682,1 +"8678",2015-02-17 15:24:59,22.1666666666667,33.9966666666667,453,1415.66666666667,0.00562596018117051,1 +"8679",2015-02-17 15:26:00,22.2,34.125,449.5,1419,0.00565897278250764,1 +"8680",2015-02-17 15:27:00,22.15,34.2,439,1426,0.00565411881081779,1 +"8681",2015-02-17 15:28:00,22.175,34.145,454,1446.25,0.00565362559602441,1 +"8682",2015-02-17 15:29:00,22.2,34.0966666666667,454,1433.66666666667,0.0056542315342893,1 +"8683",2015-02-17 15:29:59,22.15,34.095,454,1433.75,0.00563660236455044,1 +"8684",2015-02-17 15:30:59,22.15,34.045,454,1434.5,0.00562826154328955,1 +"8685",2015-02-17 15:32:00,22.15,34.35,465.25,1476,0.00567914400159498,1 +"8686",2015-02-17 15:33:00,22.1666666666667,34.0966666666667,469,1479.33333333333,0.00564265887053263,1 +"8687",2015-02-17 15:34:00,22.2,34.1175,465.25,1487.25,0.00565771773924365,1 +"8688",2015-02-17 15:35:00,22.175,33.9475,471.5,1481.75,0.00562062864195205,1 +"8689",2015-02-17 15:36:00,22.2,34.0333333333333,470.666666666667,1474,0.00564363370903831,1 +"8690",2015-02-17 15:36:59,22.175,34.095,467.75,1468.5,0.00564527160876657,1 +"8691",2015-02-17 15:38:00,22.2,34.045,466.5,1456,0.0056455859131146,1 +"8692",2015-02-17 15:39:00,22.2,33.9725,470.25,1440.25,0.00563345455596204,1 +"8693",2015-02-17 15:40:00,22.175,33.975,484,1430.5,0.00562522294663303,1 +"8694",2015-02-17 15:40:59,22.2,34.145,476.5,1426.25,0.00566231958908283,1 +"8695",2015-02-17 15:42:00,22.2,34.0333333333333,472.333333333333,1400.33333333333,0.00564363370903831,1 +"8696",2015-02-17 15:42:59,22.2,33.95,471.5,1379.75,0.00562968974737058,1 +"8697",2015-02-17 15:43:59,22.2,34.06,471,1369.33333333333,0.00564809590762865,1 +"8698",2015-02-17 15:45:00,22.2,34.0225,464,1352.75,0.00564182095898423,1 +"8699",2015-02-17 15:46:00,22.2,34.2,474,1347.33333333333,0.00567152349120271,1 +"8700",2015-02-17 15:47:00,22.2,34.2725,474,1368.75,0.00568365632006241,1 +"8701",2015-02-17 15:48:00,22.2,34.1633333333333,480.666666666667,1376.66666666667,0.00566538752646442,1 +"8702",2015-02-17 15:49:00,22.2,34.25,471.5,1381,0.00567989090918622,1 +"8703",2015-02-17 15:49:59,22.2,34.3725,464,1393.25,0.00570039202611158,1 +"8704",2015-02-17 15:51:00,22.2,34.345,479,1402,0.00569578961798396,1 +"8705",2015-02-17 15:52:00,22.2,34.3225,474,1418.75,0.00569202406153394,1 +"8706",2015-02-17 15:53:00,22.2,34.26,465.666666666667,1421.33333333333,0.00568156441955382,1 +"8707",2015-02-17 15:53:59,22.2,34.23,477,1411.33333333333,0.00567654391522214,1 +"8708",2015-02-17 15:55:00,22.2,34.245,471.5,1397,0.00567905415734882,1 +"8709",2015-02-17 15:55:59,22.2,34.2,464,1397.5,0.00567152349120271,1 +"8710",2015-02-17 15:56:59,22.2225,34.2725,452.75,1395.75,0.00569152080861507,1 +"8711",2015-02-17 15:58:00,22.2,34.1633333333333,449,1398,0.00566538752646442,1 +"8712",2015-02-17 15:59:00,22.23,34.4,449,1397.33333333333,0.00571552235797479,1 +"8713",2015-02-17 16:00:00,22.2,34.245,449,1414.5,0.00567905415734882,1 +"8714",2015-02-17 16:01:00,22.245,34.4,449,1405.25,0.00572079272521389,1 +"8715",2015-02-17 16:01:59,22.26,34.3633333333333,455.666666666667,1400.33333333333,0.00571990789633727,1 +"8716",2015-02-17 16:02:59,22.2225,34.29,449,1398.75,0.00569445358194375,1 +"8717",2015-02-17 16:04:00,22.2675,34.345,449,1400,0.00571946284266422,1 +"8718",2015-02-17 16:05:00,22.245,34.145,459,1404,0.00567799856858127,1 +"8719",2015-02-17 16:06:00,22.2225,34.5225,454,1430.75,0.00573342017135878,1 +"8720",2015-02-17 16:07:00,22.2,34.4333333333333,454,1438.66666666667,0.00571057335054633,1 +"8721",2015-02-17 16:08:00,22.2225,34.275,454,1440,0.00569193977455556,1 +"8722",2015-02-17 16:08:59,22.2,34.4,449,1441.33333333333,0.00570499450173149,1 +"8723",2015-02-17 16:09:59,22.2675,34.375,442.75,1454,0.00572450471302751,1 +"8724",2015-02-17 16:11:00,22.245,34.545,439,1461.5,0.00574512925995133,1 +"8725",2015-02-17 16:12:00,22.245,34.595,439,1487.25,0.00575352160602916,1 +"8726",2015-02-17 16:13:00,22.29,34.59,439,1480.66666666667,0.00576860834754997,1 +"8727",2015-02-17 16:14:00,22.2225,34.4975,439,1488.5,0.00572922998336993,1 +"8728",2015-02-17 16:14:59,22.29,34.5,439,1494.5,0.00575346012307919,1 +"8729",2015-02-17 16:15:59,22.245,34.1225,439,1489.75,0.00567422289371772,1 +"8730",2015-02-17 16:17:00,22.23,34.3333333333333,439,1487.33333333333,0.00570434418113413,1 +"8731",2015-02-17 16:18:00,22.245,34.3975,439,1501.5,0.00572037314633479,1 +"8732",2015-02-17 16:19:00,22.23,34.4633333333333,439,1511,0.00572614199474071,1 +"8733",2015-02-17 16:20:00,22.2225,34.425,439,1519,0.00571707875453636,1 +"8734",2015-02-17 16:21:00,22.2,34.4,439,1509.75,0.00570499450173149,1 +"8735",2015-02-17 16:21:59,22.23,34.4,449.5,1501,0.00571552235797479,1 +"8736",2015-02-17 16:23:00,22.23,34.3266666666667,449.5,1505,0.00570322638534638,1 +"8737",2015-02-17 16:24:00,22.2,34.37,449.5,1507.5,0.00569997362258378,1 +"8738",2015-02-17 16:25:00,22.2225,34.595,445.5,1516.75,0.00574557203287484,1 +"8739",2015-02-17 16:25:59,22.2,34.45,441.5,1528,0.00571336281214124,1 +"8740",2015-02-17 16:27:00,22.2,34.5,444,1531,0.00572173134567986,1 +"8741",2015-02-17 16:27:59,22.2,34.5225,444,1530,0.00572549725857041,1 +"8742",2015-02-17 16:28:59,22.2,34.4633333333333,444,1526,0.00571559439926746,1 +"8743",2015-02-17 16:30:00,22.2,34.4475,444,1506,0.00571294439132152,1 +"8744",2015-02-17 16:31:00,22.2,34.3633333333333,439,1469.33333333333,0.00569885788256996,1 +"8745",2015-02-17 16:32:00,22.2,34.295,429,1453.5,0.00568742177611579,1 +"8746",2015-02-17 16:33:00,22.175,34.245,429,1456,0.00567033423770956,1 +"8747",2015-02-17 16:34:00,22.2,34.3633333333333,429,1457.33333333333,0.00569885788256996,1 +"8748",2015-02-17 16:34:59,22.15,34.345,429,1454.5,0.00567830979641845,1 +"8749",2015-02-17 16:36:00,22.2,34.2225,429,1440,0.00567528880168808,1 +"8750",2015-02-17 16:37:00,22.1666666666667,34.3333333333333,429,1449.66666666667,0.00568218264222818,1 +"8751",2015-02-17 16:38:00,22.15,34.25,429,1450.5,0.00566246031935406,1 +"8752",2015-02-17 16:38:59,22.15,34.29,429,1453.5,0.00566913368582093,1 +"8753",2015-02-17 16:40:00,22.125,34.2975,429,1453,0.00566167513024912,1 +"8754",2015-02-17 16:40:59,22.125,34.37,429,1458.75,0.00567375226941524,1 +"8755",2015-02-17 16:41:59,22.1,34.395,429,1456.75,0.00566919373413392,1 +"8756",2015-02-17 16:43:00,22.1666666666667,34.2966666666667,429,1458,0.00567605891512238,1 +"8757",2015-02-17 16:44:00,22.15,34.425,429,1466,0.00569165734533283,1 +"8758",2015-02-17 16:45:00,22.1666666666667,34.4666666666667,429,1471.66666666667,0.00570445174808884,1 +"8759",2015-02-17 16:46:00,22.175,34.45,429,1478.25,0.0057045897344117,1 +"8760",2015-02-17 16:46:59,22.15,34.395,429,1484.5,0.00568665194796664,1 +"8761",2015-02-17 16:47:59,22.15,34.595,429,1487,0.00572002277170273,1 +"8762",2015-02-17 16:49:00,22.15,34.645,429,1507.5,0.0057283660320668,1 +"8763",2015-02-17 16:50:00,22.15,34.495,429,1500.5,0.00570333691630834,1 +"8764",2015-02-17 16:51:00,22.125,34.5675,429,1497.5,0.00570665441997048,1 +"8765",2015-02-17 16:52:00,22.1333333333333,34.3966666666667,429,1501,0.00568110505690894,1 +"8766",2015-02-17 16:53:00,22.1,34.4475,429,1498,0.00567792609669962,1 +"8767",2015-02-17 16:53:59,22.1,34.545,429,1495,0.00569414398611036,1 +"8768",2015-02-17 16:54:59,22.125,34.35,429,1481,0.0056704205983968,1 +"8769",2015-02-17 16:56:00,22.1333333333333,34.3333333333333,434,1481,0.00567054928065687,1 +"8770",2015-02-17 16:57:00,22.1,34.3,429,1488.25,0.00565339293376565,1 +"8771",2015-02-17 16:58:00,22.1333333333333,34.4666666666667,429,1495.33333333333,0.00569277238057818,1 +"8772",2015-02-17 16:59:00,22.1,34.425,429,1503.75,0.0056741836258481,1 +"8773",2015-02-17 16:59:59,22.1,34.3266666666667,435,1499.66666666667,0.00565782816583696,1 +"8774",2015-02-17 17:00:59,22.15,34.245,438,1485.5,0.00566162615852318,1 +"8775",2015-02-17 17:02:00,22.15,34.3725,438,1477,0.00568289795232948,1 +"8776",2015-02-17 17:03:00,22.1666666666667,34.4,441,1483,0.00569331699764442,1 +"8777",2015-02-17 17:04:00,22.15,34.35,438,1480.66666666667,0.00567914400159498,1 +"8778",2015-02-17 17:05:00,22.15,34.245,438,1475,0.00566162615852318,1 +"8779",2015-02-17 17:06:00,22.125,34.245,447,1482.25,0.00565292990580306,1 +"8780",2015-02-17 17:06:59,22.125,34.37,447,1484.25,0.00567375226941524,1 +"8781",2015-02-17 17:08:00,22.1,34.36,447,1488.66666666667,0.00566337229407344,1 +"8782",2015-02-17 17:09:00,22.1,34.3633333333333,447,1495,0.00566392671228396,1 +"8783",2015-02-17 17:10:00,22.1,34.425,443.5,1501.75,0.0056741836258481,1 +"8784",2015-02-17 17:10:59,22.125,34.45,439,1504.5,0.00568707930718636,1 +"8785",2015-02-17 17:12:00,22.125,34.4,443.5,1507.25,0.00567874984226028,1 +"8786",2015-02-17 17:12:59,22.1,34.4725,440,1508,0.00568208444998821,1 +"8787",2015-02-17 17:13:59,22.1,34.4975,443.5,1512.75,0.00568624285837518,1 +"8788",2015-02-17 17:15:00,22.1,34.4,447,1512.5,0.0056700253772434,1 +"8789",2015-02-17 17:16:00,22.125,34.4,447,1520,0.00567874984226028,1 +"8790",2015-02-17 17:17:00,22.1,34.425,443.5,1515,0.0056741836258481,1 +"8791",2015-02-17 17:18:00,22.1333333333333,34.4333333333333,447,1519.66666666667,0.00568721645806968,1 +"8792",2015-02-17 17:19:00,22.125,34.3,442.5,1518.75,0.0056620915755871,1 +"8793",2015-02-17 17:19:59,22.125,34.3725,438,1528.5,0.00567416873077943,1 +"8794",2015-02-17 17:21:00,22.125,34.4,439,1537.5,0.00567874984226028,1 +"8795",2015-02-17 17:22:00,22.2,34.345,438,1522,0.00569578961798396,1 +"8796",2015-02-17 17:23:00,22.15,34.345,438,1517.5,0.00567830979641845,1 +"8797",2015-02-17 17:23:59,22.15,34.3225,438,1523.5,0.00567455590056388,1 +"8798",2015-02-17 17:25:00,22.15,34.3175,442.5,1526.5,0.00567372170758276,1 +"8799",2015-02-17 17:25:59,22.15,34.3725,435.5,1534.5,0.00568289795232948,1 +"8800",2015-02-17 17:26:59,22.15,34.645,434.5,1588.75,0.0057283660320668,1 +"8801",2015-02-17 17:28:00,22.1,34.6,435.5,1594,0.00570329290883852,1 +"8802",2015-02-17 17:29:00,22.1,34.7333333333333,428.333333333333,1585.33333333333,0.00572547322245255,1 +"8803",2015-02-17 17:30:00,22.1333333333333,34.6633333333333,433,1649,0.00572555432551101,1 +"8804",2015-02-17 17:31:00,22.1,34.53,433,1653,0.00569164887165211,1 +"8805",2015-02-17 17:31:59,22.15,34.5675,433,1690.5,0.00571543407303715,1 +"8806",2015-02-17 17:32:59,22.1666666666667,34.6633333333333,433,1739.66666666667,0.00573730156363479,1 +"8807",2015-02-17 17:34:00,22.15,34.545,433,1757.75,0.00571167973311953,1 +"8808",2015-02-17 17:35:00,22.1666666666667,34.4966666666667,433,1779,0.00570946251467236,1 +"8809",2015-02-17 17:36:00,22.2,34.45,433,1778,0.00571336281214124,1 +"8810",2015-02-17 17:37:00,22.175,34.3725,433,1774.5,0.0056916390460924,1 +"8811",2015-02-17 17:38:00,22.2,34.3633333333333,433,1776,0.00569885788256996,1 +"8812",2015-02-17 17:38:59,22.175,34.475,433,1842.75,0.00570876748980446,1 +"8813",2015-02-17 17:39:59,22.175,34.425,433,1809.25,0.0057004120346292,1 +"8814",2015-02-17 17:41:00,22.2,34.4,433,1750,0.00570499450173149,1 +"8815",2015-02-17 17:42:00,22.1666666666667,34.4333333333333,433,1740,0.0056988843234868,1 +"8816",2015-02-17 17:43:00,22.175,34.35,433,1705.25,0.00568787926893215,1 +"8817",2015-02-17 17:44:00,22.2,34.29,433,1682,0.00568658500419968,1 +"8818",2015-02-17 17:44:59,22.2,34.345,433,1669.5,0.00569578961798396,1 +"8819",2015-02-17 17:45:59,22.2,34.23,433,1683.33333333333,0.00567654391522214,1 +"8820",2015-02-17 17:47:00,22.2,34.2,433,1699.75,0.00567152349120271,1 +"8821",2015-02-17 17:48:00,22.2,34.2175,433,1696,0.00567445206212065,1 +"8822",2015-02-17 17:49:00,22.2,34.1725,433,1682.75,0.00566692150640202,1 +"8823",2015-02-17 17:50:00,22.2,34.45,433,1684,0.00571336281214124,1 +"8824",2015-02-17 17:51:00,22.2,34.26,433,1699.66666666667,0.00568156441955382,1 +"8825",2015-02-17 17:51:59,22.2,34.245,433,1698,0.00567905415734882,1 +"8826",2015-02-17 17:53:00,22.2,34.2675,429.5,1695,0.00568281955818575,1 +"8827",2015-02-17 17:54:00,22.2,34.1933333333333,423.666666666667,1675.33333333333,0.00567040785232703,1 +"8828",2015-02-17 17:55:00,22.2,34.0966666666667,419,1658.66666666667,0.0056542315342893,1 +"8829",2015-02-17 17:55:59,22.2,34.2675,426,1645.5,0.00568281955818575,1 +"8830",2015-02-17 17:57:00,22.2,34.345,429.5,1652,0.00569578961798396,1 +"8831",2015-02-17 17:57:59,22.2,34.29,426,1641,0.00568658500419968,1 +"8832",2015-02-17 17:58:59,22.2,34.3175,419,1637.5,0.00569118727734716,1 +"8833",2015-02-17 18:00:00,22.2,34.3333333333333,419,1628.33333333333,0.00569383710159242,1 +"8834",2015-02-17 18:01:00,22.2,34.345,419,1619.5,0.00569578961798396,1 +"8835",2015-02-17 18:02:00,22.2,34.345,419,1600.5,0.00569578961798396,1 +"8836",2015-02-17 18:03:00,22.2,34.245,419,1602,0.00567905415734882,1 +"8837",2015-02-17 18:04:00,22.2,34.245,419,1603,0.00567905415734882,1 +"8838",2015-02-17 18:04:59,22.2,34.2175,415.5,1606.75,0.00567445206212065,1 +"8839",2015-02-17 18:06:00,22.1666666666667,34.26,279.333333333333,1595.66666666667,0.00566993530750274,0 +"8840",2015-02-17 18:07:00,22.1,34.3266666666667,0,1591.33333333333,0.00565782816583696,0 +"8841",2015-02-17 18:08:00,22.1,34.345,0,1594.5,0.00566087742424663,0 +"8842",2015-02-17 18:08:59,22.1,34.29,0,1585.66666666667,0.00565172973789895,0 +"8843",2015-02-17 18:10:00,22.1,34.29,0,1576,0.00565172973789895,0 +"8844",2015-02-17 18:10:59,22.1,34.345,0,1572,0.00566087742424663,0 +"8845",2015-02-17 18:11:59,22.1,34.29,0,1568.5,0.00565172973789895,0 +"8846",2015-02-17 18:13:00,22.1,34.4,0,1569,0.0056700253772434,0 +"8847",2015-02-17 18:14:00,22.1,34.3266666666667,0,1564.66666666667,0.00565782816583696,0 +"8848",2015-02-17 18:15:00,22.05,34.245,0,1550.5,0.00562691196678847,0 +"8849",2015-02-17 18:16:00,22.1,34.29,0,1549,0.00565172973789895,0 +"8850",2015-02-17 18:16:59,22.0333333333333,34.26,0,1551.33333333333,0.00562362903779214,0 +"8851",2015-02-17 18:17:59,22.025,34.2225,0,1538.25,0.00561453819137265,0 +"8852",2015-02-17 18:19:00,22,34.29,0,1536,0.00561706350613092,0 +"8853",2015-02-17 18:20:00,22,34.245,0,1541,0.00560962555066642,0 +"8854",2015-02-17 18:21:00,22,34.29,0,1544,0.00561706350613092,0 +"8855",2015-02-17 18:22:00,22,34.29,0,1533,0.00561706350613092,0 +"8856",2015-02-17 18:23:00,21.89,34.29,0,1536,0.00557914792122477,0 +"8857",2015-02-17 18:23:59,21.89,34.29,0,1538,0.00557914792122477,0 +"8858",2015-02-17 18:24:59,21.89,34.29,0,1531,0.00557914792122477,0 +"8859",2015-02-17 18:26:00,21.89,34.29,0,1530.33333333333,0.00557914792122477,0 +"8860",2015-02-17 18:27:00,21.89,34.29,0,1529,0.00557914792122477,0 +"8861",2015-02-17 18:28:00,21.89,34.29,0,1523,0.00557914792122477,0 +"8862",2015-02-17 18:29:00,21.89,34.29,0,1530.66666666667,0.00557914792122477,0 +"8863",2015-02-17 18:29:59,21.89,34.29,0,1525,0.00557914792122477,0 +"8864",2015-02-17 18:30:59,21.89,34.29,0,1519,0.00557914792122477,0 +"8865",2015-02-17 18:32:00,21.89,34.245,0,1508,0.0055717606182151,0 +"8866",2015-02-17 18:33:00,21.89,34.2,0,1491.5,0.0055643734891169,0 +"8867",2015-02-17 18:34:00,21.84,34.145,0,1499,0.00553825944714946,0 +"8868",2015-02-17 18:35:00,21.79,34.2,0,1499,0.00553019288745083,0 +"8869",2015-02-17 18:36:00,21.79,34.09,0,1495.5,0.00551224808503896,0 +"8870",2015-02-17 18:36:59,21.79,34.1266666666667,0,1491,0.00551822957180891,0 +"8871",2015-02-17 18:38:00,21.79,34.09,0,1492,0.00551224808503896,0 +"8872",2015-02-17 18:39:00,21.76,34.1266666666667,0,1487.33333333333,0.0055080339552081,0 +"8873",2015-02-17 18:40:00,21.7,34.145,0,1489.5,0.00549066676507729,0 +"8874",2015-02-17 18:40:59,21.7,34.2,0,1488,0.00549958920680493,0 +"8875",2015-02-17 18:42:00,21.7,34.2,0,1475,0.00549958920680493,0 +"8876",2015-02-17 18:42:59,21.7,34.2,0,1470.5,0.00549958920680493,0 +"8877",2015-02-17 18:43:59,21.7,34.2,0,1477,0.00549958920680493,0 +"8878",2015-02-17 18:45:00,21.7,34.29,0,1476,0.00551419011333338,0 +"8879",2015-02-17 18:46:00,21.7,34.2,0,1477,0.00549958920680493,0 +"8880",2015-02-17 18:47:00,21.7,34.245,0,1484.75,0.00550688957513524,0 +"8881",2015-02-17 18:48:00,21.7,34.245,0,1471.5,0.00550688957513524,0 +"8882",2015-02-17 18:49:00,21.7,34.29,0,1476,0.00551419011333338,0 +"8883",2015-02-17 18:49:59,21.7,34.245,0,1477.5,0.00550688957513524,0 +"8884",2015-02-17 18:51:00,21.65,34.145,0,1475.5,0.00547375722330738,0 +"8885",2015-02-17 18:52:00,21.6,34.1175,0,1478,0.00545246029355172,0 +"8886",2015-02-17 18:53:00,21.6,34.09,0,1487,0.00544802690925694,0 +"8887",2015-02-17 18:53:59,21.6,34.09,0,1483.5,0.00544802690925694,0 +"8888",2015-02-17 18:55:00,21.6,34.09,0,1488,0.00544802690925694,0 +"8889",2015-02-17 18:55:59,21.6,34.09,0,1490,0.00544802690925694,0 +"8890",2015-02-17 18:56:59,21.6,34.09,0,1483,0.00544802690925694,0 +"8891",2015-02-17 18:58:00,21.6,34.09,0,1481,0.00544802690925694,0 +"8892",2015-02-17 18:59:00,21.5333333333333,34.1266666666667,0,1479.33333333333,0.00543153716204901,0 +"8893",2015-02-17 19:00:00,21.5,34.1725,0,1472.25,0.00542771049918892,0 +"8894",2015-02-17 19:01:00,21.5,34.09,0,1473,0.00541449273397144,0 +"8895",2015-02-17 19:01:59,21.5,34.1725,0,1475.75,0.00542771049918892,0 +"8896",2015-02-17 19:02:59,21.5,34.09,0,1468,0.00541449273397144,0 +"8897",2015-02-17 19:04:00,21.5,34.1633333333333,0,1469.33333333333,0.00542624183110713,0 +"8898",2015-02-17 19:05:00,21.5,34.145,0,1474,0.00542330451557038,0 +"8899",2015-02-17 19:06:00,21.5,34.09,0,1475,0.00541449273397144,0 +"8900",2015-02-17 19:07:00,21.445,34.09,0,1474,0.00539612683640535,0 +"8901",2015-02-17 19:08:00,21.5,34.2,0,1477.5,0.00543211654468858,0 +"8902",2015-02-17 19:08:59,21.445,34.145,0,1480.5,0.00540490847105668,0 +"8903",2015-02-17 19:09:59,21.39,34.09,0,1465,0.00537781603845932,0 +"8904",2015-02-17 19:11:00,21.39,34.2,0,1469.5,0.00539531944240748,0 +"8905",2015-02-17 19:12:00,21.39,34.09,0,1468,0.00537781603845932,0 +"8906",2015-02-17 19:13:00,21.39,34.2,0,1468,0.00539531944240748,0 +"8907",2015-02-17 19:14:00,21.34,34.145,0,1466,0.00536994188844854,0 +"8908",2015-02-17 19:14:59,21.3566666666667,34.2,0,1465.33333333333,0.00538421240298986,0 +"8909",2015-02-17 19:15:59,21.29,34.2,0,1468,0.0053620589560631,0 +"8910",2015-02-17 19:17:00,21.29,34.2,0,1471,0.0053620589560631,0 +"8911",2015-02-17 19:18:00,21.29,34.245,0,1471.5,0.00536917519930357,0 +"8912",2015-02-17 19:19:00,21.29,34.2,0,1466.5,0.0053620589560631,0 +"8913",2015-02-17 19:20:00,21.29,34.2,0,1472,0.0053620589560631,0 +"8914",2015-02-17 19:21:00,21.29,34.29,0,1472.66666666667,0.00537629160398667,0 +"8915",2015-02-17 19:21:59,21.2675,34.295,0,1470.75,0.00536960267204758,0 +"8916",2015-02-17 19:23:00,21.29,34.29,0,1469,0.00537629160398667,0 +"8917",2015-02-17 19:24:00,21.29,34.345,0,1467.5,0.00538498965118379,0 +"8918",2015-02-17 19:25:00,21.2,34.2,0,1466,0.00533227965384048,0 +"8919",2015-02-17 19:25:59,21.2,34.29,0,1467,0.00534643258419408,0 +"8920",2015-02-17 19:27:00,21.2,34.29,0,1468,0.00534643258419408,0 +"8921",2015-02-17 19:27:59,21.2,34.29,0,1468,0.00534643258419408,0 +"8922",2015-02-17 19:28:59,21.2,34.245,0,1464.5,0.00533935603919388,0 +"8923",2015-02-17 19:30:00,21.2,34.29,0,1460.33333333333,0.00534643258419408,0 +"8924",2015-02-17 19:31:00,21.2,34.29,0,1458,0.00534643258419408,0 +"8925",2015-02-17 19:32:00,21.1666666666667,34.29,0,1468.66666666667,0.00533541095458364,0 +"8926",2015-02-17 19:33:00,21.2,34.29,0,1475,0.00534643258419408,0 +"8927",2015-02-17 19:34:00,21.2,34.29,0,1474,0.00534643258419408,0 +"8928",2015-02-17 19:34:59,21.2,34.29,0,1475,0.00534643258419408,0 +"8929",2015-02-17 19:36:00,21.15,34.29,0,1472.5,0.00532990767706535,0 +"8930",2015-02-17 19:37:00,21.1,34.29,0,1473.5,0.00531342794587954,0 +"8931",2015-02-17 19:38:00,21.1,34.29,0,1483,0.00531342794587954,0 +"8932",2015-02-17 19:38:59,21.1333333333333,34.29,0,1486,0.0053244094190945,0 +"8933",2015-02-17 19:40:00,21.1,34.29,0,1485.5,0.00531342794587954,0 +"8934",2015-02-17 19:40:59,21.1,34.29,0,1488,0.00531342794587954,0 +"8935",2015-02-17 19:41:59,21.1,34.29,0,1494.5,0.00531342794587954,0 +"8936",2015-02-17 19:43:00,21.1,34.245,0,1487,0.0053063954553692,0 +"8937",2015-02-17 19:44:00,21.1,34.29,0,1484,0.00531342794587954,0 +"8938",2015-02-17 19:45:00,21.1,34.29,0,1488.5,0.00531342794587954,0 +"8939",2015-02-17 19:46:00,21.1333333333333,34.29,0,1490.5,0.0053244094190945,0 +"8940",2015-02-17 19:46:59,21.1,34.29,0,1493.5,0.00531342794587954,0 +"8941",2015-02-17 19:47:59,21.1,34.29,0,1495,0.00531342794587954,0 +"8942",2015-02-17 19:49:00,21.1,34.29,0,1486.5,0.00531342794587954,0 +"8943",2015-02-17 19:50:00,21.1,34.29,0,1486.5,0.00531342794587954,0 +"8944",2015-02-17 19:51:00,21.1,34.29,0,1489,0.00531342794587954,0 +"8945",2015-02-17 19:52:00,21.1,34.29,0,1493.5,0.00531342794587954,0 +"8946",2015-02-17 19:53:00,21.1,34.29,0,1491,0.00531342794587954,0 +"8947",2015-02-17 19:53:59,21.1,34.245,0,1488.5,0.0053063954553692,0 +"8948",2015-02-17 19:54:59,21.1,34.245,0,1504,0.0053063954553692,0 +"8949",2015-02-17 19:56:00,21.1,34.2,0,1500.5,0.00529936312253242,0 +"8950",2015-02-17 19:57:00,21.1,34.245,0,1510.5,0.0053063954553692,0 +"8951",2015-02-17 19:58:00,21,34.2,0,1511,0.00526662637537907,0 +"8952",2015-02-17 19:59:00,21.1,34.2,0,1520,0.00529936312253242,0 +"8953",2015-02-17 19:59:59,21.05,34.145,0,1516,0.00527440427723406,0 +"8954",2015-02-17 20:00:59,21.1,34.2,0,1515.5,0.00529936312253242,0 +"8955",2015-02-17 20:02:00,21.05,34.145,0,1515.5,0.00527440427723406,0 +"8956",2015-02-17 20:03:00,21,34.145,0,1526,0.00525808505570565,0 +"8957",2015-02-17 20:04:00,21.05,34.145,0,1530.5,0.00527440427723406,0 +"8958",2015-02-17 20:05:00,21.1,34.2,0,1520.5,0.00529936312253242,0 +"8959",2015-02-17 20:06:00,21,34.09,0,1518.5,0.00524954396863874,0 +"8960",2015-02-17 20:06:59,21,34.09,0,1520,0.00524954396863874,0 +"8961",2015-02-17 20:08:00,21,34.09,0,1517,0.00524954396863874,0 +"8962",2015-02-17 20:09:00,21,34.09,0,1518,0.00524954396863874,0 +"8963",2015-02-17 20:10:00,21,34.09,0,1512.5,0.00524954396863874,0 +"8964",2015-02-17 20:10:59,21,34.09,0,1514.5,0.00524954396863874,0 +"8965",2015-02-17 20:12:00,21,34.09,0,1506,0.00524954396863874,0 +"8966",2015-02-17 20:12:59,21,34.09,0,1493,0.00524954396863874,0 +"8967",2015-02-17 20:13:59,21,34.09,0,1492,0.00524954396863874,0 +"8968",2015-02-17 20:15:00,21,34.09,0,1472,0.00524954396863874,0 +"8969",2015-02-17 20:16:00,21,34.09,0,1477,0.00524954396863874,0 +"8970",2015-02-17 20:17:00,21,34.09,0,1483,0.00524954396863874,0 +"8971",2015-02-17 20:18:00,21,34.09,0,1486.5,0.00524954396863874,0 +"8972",2015-02-17 20:19:00,21,34.09,0,1474,0.00524954396863874,0 +"8973",2015-02-17 20:19:59,20.9175,34.09,0,1477,0.00522275877965484,0 +"8974",2015-02-17 20:21:00,21,34,0,1481,0.00523556814606058,0 +"8975",2015-02-17 20:22:00,20.9266666666667,34.06,0,1492,0.00522109156628242,0 +"8976",2015-02-17 20:23:00,21,34,0,1507.5,0.00523556814606058,0 +"8977",2015-02-17 20:23:59,21,34,0,1501.33333333333,0.00523556814606058,0 +"8978",2015-02-17 20:25:00,21,34,0,1506,0.00523556814606058,0 +"8979",2015-02-17 20:25:59,21,34,0,1507,0.00523556814606058,0 +"8980",2015-02-17 20:26:59,20.945,34,0,1514.5,0.00521774586790994,0 +"8981",2015-02-17 20:28:00,20.945,33.95,0,1519.5,0.00521000844018663,0 +"8982",2015-02-17 20:29:00,20.9725,33.95,0,1523.5,0.00521889954896303,0 +"8983",2015-02-17 20:30:00,21,33.9,0,1527.5,0.00522004018472635,0 +"8984",2015-02-17 20:31:00,20.9633333333333,33.9,0,1510,0.00520818824641829,0 +"8985",2015-02-17 20:31:59,21,33.9,0,1511,0.00522004018472635,0 +"8986",2015-02-17 20:32:59,20.945,33.9,0,1510.5,0.0052022712033605,0 +"8987",2015-02-17 20:34:00,21,33.9,0,1503.33333333333,0.00522004018472635,0 +"8988",2015-02-17 20:35:00,21,33.8633333333333,0,1507.33333333333,0.00521434679153574,0 +"8989",2015-02-17 20:36:00,20.945,33.79,0,1518.5,0.00518524995426627,0 +"8990",2015-02-17 20:37:00,21,33.79,0,1532.5,0.00520296031522883,0 +"8991",2015-02-17 20:38:00,21,33.9,0,1530.5,0.00522004018472635,0 +"8992",2015-02-17 20:38:59,21,33.79,0,1538,0.00520296031522883,0 +"8993",2015-02-17 20:39:59,21,33.79,0,1538,0.00520296031522883,0 +"8994",2015-02-17 20:41:00,21,33.79,0,1528.33333333333,0.00520296031522883,0 +"8995",2015-02-17 20:42:00,21,33.79,0,1533,0.00520296031522883,0 +"8996",2015-02-17 20:43:00,21,33.79,0,1528,0.00520296031522883,0 +"8997",2015-02-17 20:44:00,21,33.79,0,1522,0.00520296031522883,0 +"8998",2015-02-17 20:44:59,20.945,33.79,0,1517,0.00518524995426627,0 +"8999",2015-02-17 20:45:59,21,33.73,0,1511,0.00519364441484014,0 +"9000",2015-02-17 20:47:00,21,33.7,0,1510.33333333333,0.00518898656842244,0 +"9001",2015-02-17 20:48:00,21,33.7,0,1508.5,0.00518898656842244,0 +"9002",2015-02-17 20:49:00,21,33.7,0,1510,0.00518898656842244,0 +"9003",2015-02-17 20:50:00,21,33.7,0,1513.66666666667,0.00518898656842244,0 +"9004",2015-02-17 20:51:00,21,33.7,0,1516,0.00518898656842244,0 +"9005",2015-02-17 20:51:59,21,33.7,0,1512,0.00518898656842244,0 +"9006",2015-02-17 20:53:00,21,33.645,0,1512,0.0051804473630042,0 +"9007",2015-02-17 20:54:00,21,33.6633333333333,0,1501.33333333333,0.00518329373897424,0 +"9008",2015-02-17 20:55:00,21,33.7,0,1500,0.00518898656842244,0 +"9009",2015-02-17 20:55:59,21,33.7,0,1501.33333333333,0.00518898656842244,0 +"9010",2015-02-17 20:57:00,21,33.7,0,1496,0.00518898656842244,0 +"9011",2015-02-17 20:57:59,21,33.59,0,1498,0.0051719083901061,0 +"9012",2015-02-17 20:58:59,21,33.59,0,1503.5,0.0051719083901061,0 +"9013",2015-02-17 21:00:00,21,33.59,0,1505,0.0051719083901061,0 +"9014",2015-02-17 21:01:00,21,33.59,0,1507,0.0051719083901061,0 +"9015",2015-02-17 21:02:00,20.945,33.59,0,1506,0.00515430459543257,0 +"9016",2015-02-17 21:03:00,21,33.59,0,1510,0.0051719083901061,0 +"9017",2015-02-17 21:04:00,21,33.59,0,1515,0.0051719083901061,0 +"9018",2015-02-17 21:04:59,21,33.545,0,1520,0.00516492213067716,0 +"9019",2015-02-17 21:06:00,20.9633333333333,33.5,0,1517.66666666667,0.0051462262510594,0 +"9020",2015-02-17 21:07:00,21,33.5,0,1518.5,0.00515793602689064,0 +"9021",2015-02-17 21:08:00,20.9633333333333,33.5,0,1525,0.0051462262510594,0 +"9022",2015-02-17 21:08:59,21,33.45,0,1528,0.00515017387188732,0 +"9023",2015-02-17 21:10:00,20.945,33.4,0,1533,0.00512490933289002,0 +"9024",2015-02-17 21:10:59,20.89,33.4,0,1542,0.00510745943434578,0 +"9025",2015-02-17 21:11:59,21,33.4,0,1543.5,0.00514241190902158,0 +"9026",2015-02-17 21:13:00,20.945,33.4,0,1557.5,0.00512490933289002,0 +"9027",2015-02-17 21:14:00,20.89,33.245,0,1565.5,0.00508356343541247,0 +"9028",2015-02-17 21:15:00,20.89,33.29,0,1564,0.0050905007958803,0 +"9029",2015-02-17 21:16:00,20.89,33.29,0,1542.5,0.0050905007958803,0 +"9030",2015-02-17 21:16:59,20.89,33.245,0,1537,0.00508356343541247,0 +"9031",2015-02-17 21:17:59,20.89,33.29,0,1537.5,0.0050905007958803,0 +"9032",2015-02-17 21:19:00,20.89,33.2,0,1546,0.00507662622843585,0 +"9033",2015-02-17 21:20:00,20.89,33.2,0,1545,0.00507662622843585,0 +"9034",2015-02-17 21:21:00,20.89,33.2,0,1567.33333333333,0.00507662622843585,0 +"9035",2015-02-17 21:22:00,20.89,33.2,0,1684.33333333333,0.00507662622843585,0 +"9036",2015-02-17 21:23:00,20.89,33.2,0,1744,0.00507662622843585,0 +"9037",2015-02-17 21:23:59,20.89,33.2,0,1735.5,0.00507662622843585,0 +"9038",2015-02-17 21:24:59,20.945,33.145,0,1741.5,0.00508546212689862,0 +"9039",2015-02-17 21:26:00,20.89,33.145,0,1739.5,0.00506814762834628,0 +"9040",2015-02-17 21:27:00,20.89,33.09,0,1741.5,0.00505966925752913,0 +"9041",2015-02-17 21:28:00,20.89,33.09,0,1737,0.00505966925752913,0 +"9042",2015-02-17 21:29:00,20.89,33.09,0,1757,0.00505966925752913,0 +"9043",2015-02-17 21:29:59,20.89,33.09,0,1759.5,0.00505966925752913,0 +"9044",2015-02-17 21:30:59,20.89,33.045,0,1759,0.00505273257920544,0 +"9045",2015-02-17 21:32:00,20.89,33,0,1769.5,0.00504579605435031,0 +"9046",2015-02-17 21:33:00,20.89,33,0,1752,0.00504579605435031,0 +"9047",2015-02-17 21:34:00,20.89,33,0,1709,0.00504579605435031,0 +"9048",2015-02-17 21:35:00,20.89,32.9,0,1688,0.00503038210410195,0 +"9049",2015-02-17 21:36:00,20.89,32.9,0,1666.5,0.00503038210410195,0 +"9050",2015-02-17 21:36:59,20.89,32.9,0,1649,0.00503038210410195,0 +"9051",2015-02-17 21:38:00,20.89,32.9,0,1594.5,0.00503038210410195,0 +"9052",2015-02-17 21:39:00,20.89,32.9,0,1588.5,0.00503038210410195,0 +"9053",2015-02-17 21:40:00,20.89,32.9,0,1581.5,0.00503038210410195,0 +"9054",2015-02-17 21:40:59,20.89,32.8725,0,1551,0.0050261434006358,0 +"9055",2015-02-17 21:42:00,20.89,32.79,0,1541,0.00501342763407223,0 +"9056",2015-02-17 21:42:59,20.89,32.79,0,1539.5,0.00501342763407223,0 +"9057",2015-02-17 21:43:59,20.89,32.79,0,1536,0.00501342763407223,0 +"9058",2015-02-17 21:45:00,20.89,32.745,0,1529,0.00500649197877611,0 +"9059",2015-02-17 21:46:00,20.89,32.7,0,1528,0.00499955647691461,0 +"9060",2015-02-17 21:47:00,20.89,32.7,0,1525.5,0.00499955647691461,0 +"9061",2015-02-17 21:48:00,20.89,32.7,0,1524.5,0.00499955647691461,0 +"9062",2015-02-17 21:49:00,20.89,32.7,0,1523,0.00499955647691461,0 +"9063",2015-02-17 21:49:59,20.89,32.59,0,1516,0.00498260367382887,0 +"9064",2015-02-17 21:51:00,20.89,32.59,0,1518.33333333333,0.00498260367382887,0 +"9065",2015-02-17 21:52:00,20.89,32.59,0,1521.5,0.00498260367382887,0 +"9066",2015-02-17 21:53:00,20.89,32.59,0,1522,0.00498260367382887,0 +"9067",2015-02-17 21:53:59,20.89,32.59,0,1511,0.00498260367382887,0 +"9068",2015-02-17 21:55:00,20.79,32.4,0,1507,0.00492269204289342,0 +"9069",2015-02-17 21:55:59,20.84,32.45,0,1506,0.00494566783341643,0 +"9070",2015-02-17 21:56:59,20.8233333333333,32.3633333333333,0,1513,0.00492725724558259,0 +"9071",2015-02-17 21:58:00,20.79,32.2,0,1512,0.0048920660595527,0 +"9072",2015-02-17 21:59:00,20.79,32.245,0,1512.5,0.00489895664491577,0 +"9073",2015-02-17 22:00:00,20.84,32.345,0,1514,0.00492953807399043,0 +"9074",2015-02-17 22:01:00,20.79,32.29,0,1511,0.00490584738175847,0 +"9075",2015-02-17 22:01:59,20.84,32.29,0,1507.5,0.00492108948361208,0 +"9076",2015-02-17 22:02:59,20.89,32.29,0,1524,0.00493637341543825,0 +"9077",2015-02-17 22:04:00,20.79,32.2,0,1545,0.0048920660595527,0 +"9078",2015-02-17 22:05:00,20.84,32.245,0,1533.5,0.00491417716994355,0 +"9079",2015-02-17 22:06:00,20.89,32.2,0,1554,0.00492250566731028,0 +"9080",2015-02-17 22:07:00,20.79,32.09,0,1599,0.00487522304412235,0 +"9081",2015-02-17 22:08:00,20.79,32.09,0,1628.5,0.00487522304412235,0 +"9082",2015-02-17 22:08:59,20.8233333333333,32.1266666666667,0,1619.33333333333,0.00489094185709971,0 +"9083",2015-02-17 22:09:59,20.89,32.145,0,1586.5,0.00491403123435799,0 +"9084",2015-02-17 22:11:00,20.89,32.09,0,1586,0.00490555703050911,0 +"9085",2015-02-17 22:12:00,20.89,32.09,0,1585,0.00490555703050911,0 +"9086",2015-02-17 22:13:00,20.89,32.09,0,1570,0.00490555703050911,0 +"9087",2015-02-17 22:14:00,20.89,32.06,0,1534.66666666667,0.00490093483406156,0 +"9088",2015-02-17 22:14:59,20.89,32,0,1514,0.00489169064564112,0 +"9089",2015-02-17 22:15:59,20.89,32,0,1483,0.00489169064564112,0 +"9090",2015-02-17 22:17:00,20.84,31.89,0,1455,0.00485965203936234,0 +"9091",2015-02-17 22:18:00,20.89,31.89,0,1430,0.00487474367492375,0 +"9092",2015-02-17 22:19:00,20.89,31.89,0,1412,0.00487474367492375,0 +"9093",2015-02-17 22:20:00,20.89,31.89,0,1405,0.00487474367492375,0 +"9094",2015-02-17 22:21:00,20.8566666666667,31.8566666666667,0,1408.33333333333,0.00485955341246906,0 +"9095",2015-02-17 22:21:59,20.8566666666667,31.8566666666667,0,1419.66666666667,0.00485955341246906,0 +"9096",2015-02-17 22:23:00,20.89,31.89,0,1455,0.00487474367492375,0 +"9097",2015-02-17 22:24:00,20.84,31.795,0,1597.5,0.00484506241585934,0 +"9098",2015-02-17 22:25:00,20.79,31.745,0,1494,0.00482240309323435,0 +"9099",2015-02-17 22:25:59,20.79,31.7,0,1303.5,0.00481551419064223,0 +"9100",2015-02-17 22:27:00,20.79,31.7,0,1295,0.00481551419064223,0 +"9101",2015-02-17 22:27:59,20.84,31.745,0,1295,0.00483738393942145,0 +"9102",2015-02-17 22:28:59,20.8566666666667,31.63,0,1575.66666666667,0.00482470849748081,0 +"9103",2015-02-17 22:30:00,20.79,31.6,0,1661,0.00480020606032595,0 +"9104",2015-02-17 22:31:00,20.89,31.65,0,1466,0.00483777164632622,0 +"9105",2015-02-17 22:32:00,20.84,31.6,0,1454.5,0.00481511742149549,0 +"9106",2015-02-17 22:33:00,20.84,31.55,0,1451.5,0.00480743967865207,0 +"9107",2015-02-17 22:34:00,20.79,31.5,0,1445,0.00478489867770378,0 +"9108",2015-02-17 22:34:59,20.79,31.395,0,1434.5,0.00476882673059633,0 +"9109",2015-02-17 22:36:00,20.79,31.445,0,1482.5,0.00477647993594635,0 +"9110",2015-02-17 22:37:00,20.79,31.445,0,1525,0.00477647993594635,0 +"9111",2015-02-17 22:38:00,20.8233333333333,31.4266666666667,0,1469.66666666667,0.00478355476529234,0 +"9112",2015-02-17 22:38:59,20.8233333333333,31.4266666666667,0,1474.66666666667,0.00478355476529234,0 +"9113",2015-02-17 22:40:00,20.84,31.445,0,1539.5,0.00479131703088674,0 +"9114",2015-02-17 22:40:59,20.79,31.29,0,1542,0.00475275560769784,0 +"9115",2015-02-17 22:41:59,20.84,31.395,0,1597,0.00478363987108188,0 +"9116",2015-02-17 22:43:00,20.79,31.29,0,1662.66666666667,0.00475275560769784,0 +"9117",2015-02-17 22:44:00,20.79,31.29,0,1645.5,0.00475275560769784,0 +"9118",2015-02-17 22:45:00,20.79,31.2,0,1627,0.0047389810154541,0 +"9119",2015-02-17 22:46:00,20.79,31.2,0,1582,0.0047389810154541,0 +"9120",2015-02-17 22:46:59,20.79,31.29,0,1558.5,0.00475275560769784,0 +"9121",2015-02-17 22:47:59,20.79,31,0,1542.5,0.00470837297808737,0 +"9122",2015-02-17 22:49:00,20.79,31.1,0,1526,0.0047236766230606,0 +"9123",2015-02-17 22:50:00,20.79,31.2,0,1513,0.0047389810154541,0 +"9124",2015-02-17 22:51:00,20.79,31.1,0,1502,0.0047236766230606,0 +"9125",2015-02-17 22:52:00,20.79,31.1,0,1501.5,0.0047236766230606,0 +"9126",2015-02-17 22:53:00,20.79,31,0,1727,0.00470837297808737,0 +"9127",2015-02-17 22:53:59,20.79,31,0,1721,0.00470837297808737,0 +"9128",2015-02-17 22:54:59,20.79,30.89,0,1655,0.00469153983182186,0 +"9129",2015-02-17 22:56:00,20.79,30.9266666666667,0,2072,0.00469715078010239,0 +"9130",2015-02-17 22:57:00,20.79,30.89,0,1690.66666666667,0.00469153983182186,0 +"9131",2015-02-17 22:58:00,20.79,30.89,0,1412,0.00469153983182186,0 +"9132",2015-02-17 22:59:00,20.8233333333333,30.89,0,1254.66666666667,0.00470124957401714,0 +"9133",2015-02-17 22:59:59,20.79,30.79,0,1247.5,0.00467623775625297,0 +"9134",2015-02-17 23:00:59,20.79,30.79,0,1231,0.00467623775625297,0 +"9135",2015-02-17 23:02:00,20.79,30.89,0,1231,0.00469153983182186,0 +"9136",2015-02-17 23:03:00,20.84,30.84,0,1159.5,0.00469843602504216,0 +"9137",2015-02-17 23:04:00,20.84,30.745,0,1157,0.00468385390481723,0 +"9138",2015-02-17 23:05:00,20.8566666666667,30.7933333333333,0,1135.33333333333,0.00469612329966554,0 +"9139",2015-02-17 23:06:00,20.79,30.7,0,1128,0.00466246652714175,0 +"9140",2015-02-17 23:06:59,20.84,30.745,0,1119.5,0.00468385390481723,0 +"9141",2015-02-17 23:08:00,20.89,30.79,0,1116,0.00470532434876837,0 +"9142",2015-02-17 23:09:00,20.89,30.79,0,1113,0.00470532434876837,0 +"9143",2015-02-17 23:10:00,20.89,30.7,0,1133,0.00469146682019239,0 +"9144",2015-02-17 23:10:59,20.84,30.695,0,1149,0.00467617937726267,0 +"9145",2015-02-17 23:12:00,20.84,30.6,0,1146.5,0.00466159829274983,0 +"9146",2015-02-17 23:12:59,20.89,30.6333333333333,0,1145.66666666667,0.00468120237930505,0 +"9147",2015-02-17 23:13:59,20.84,30.55,0,1136.5,0.00465392431027786,0 +"9148",2015-02-17 23:15:00,20.89,30.6,0,1132,0.0046760702849496,0 +"9149",2015-02-17 23:16:00,20.89,30.6,0,1135.5,0.0046760702849496,0 +"9150",2015-02-17 23:17:00,20.84,30.495,0,1164.5,0.00464548314663612,0 +"9151",2015-02-17 23:18:00,20.8566666666667,30.4966666666667,0,1180,0.00465054201357758,0 +"9152",2015-02-17 23:19:00,20.84,30.5,0,1173,0.00464625051575194,0 +"9153",2015-02-17 23:19:59,20.89,30.5,0,1184.5,0.00466067450621137,0 +"9154",2015-02-17 23:21:00,20.89,30.445,0,1189.5,0.00465220715034521,0 +"9155",2015-02-17 23:22:00,20.89,30.39,0,1190,0.00464374002329553,0 +"9156",2015-02-17 23:23:00,20.89,30.39,0,1198,0.00464374002329553,0 +"9157",2015-02-17 23:23:59,20.89,30.39,0,1191,0.00464374002329553,0 +"9158",2015-02-17 23:25:00,20.89,30.29,0,1196,0.00462834583303539,0 +"9159",2015-02-17 23:25:59,20.89,30.29,0,1195,0.00462834583303539,0 +"9160",2015-02-17 23:26:59,20.89,30.29,0,1193,0.00462834583303539,0 +"9161",2015-02-17 23:28:00,20.89,30.245,0,1193.5,0.00462141869417488,0 +"9162",2015-02-17 23:29:00,20.89,30.2,0,1186,0.00461449170846647,0 +"9163",2015-02-17 23:30:00,20.84,30.195,0,1198.5,0.00459944443871186,0 +"9164",2015-02-17 23:31:00,20.89,30.2,0,1202,0.00461449170846647,0 +"9165",2015-02-17 23:31:59,20.89,30.1,0,1199.33333333333,0.00459909895518896,0 +"9166",2015-02-17 23:32:59,20.89,30.1,0,1197,0.00459909895518896,0 +"9167",2015-02-17 23:34:00,20.89,30.1,0,1198,0.00459909895518896,0 +"9168",2015-02-17 23:35:00,20.89,30,0,1202,0.00458370695813728,0 +"9169",2015-02-17 23:36:00,20.89,30,0,1212.5,0.00458370695813728,0 +"9170",2015-02-17 23:37:00,20.89,30,0,1221.5,0.00458370695813728,0 +"9171",2015-02-17 23:38:00,20.89,30,0,1219,0.00458370695813728,0 +"9172",2015-02-17 23:38:59,20.89,30,0,1217.33333333333,0.00458370695813728,0 +"9173",2015-02-17 23:39:59,20.89,30,0,1217.66666666667,0.00458370695813728,0 +"9174",2015-02-17 23:41:00,20.89,30,0,1221,0.00458370695813728,0 +"9175",2015-02-17 23:42:00,20.89,30,0,1220.5,0.00458370695813728,0 +"9176",2015-02-17 23:43:00,20.89,29.89,0,1235,0.00456677663475476,0 +"9177",2015-02-17 23:44:00,20.89,29.89,0,1252.5,0.00456677663475476,0 +"9178",2015-02-17 23:44:59,20.89,29.89,0,1250,0.00456677663475476,0 +"9179",2015-02-17 23:45:59,20.89,29.79,0,1216,0.00455138622559595,0 +"9180",2015-02-17 23:47:00,20.89,29.79,0,1231.5,0.00455138622559595,0 +"9181",2015-02-17 23:48:00,20.89,29.7,0,1252.5,0.00453753550378,0 +"9182",2015-02-17 23:49:00,20.89,29.6,0,1270.5,0.00452214653107444,0 +"9183",2015-02-17 23:50:00,20.89,29.65,0,1269.5,0.00452984092293033,0 +"9184",2015-02-17 23:51:00,20.89,29.7,0,1267,0.00453753550378,0 +"9185",2015-02-17 23:51:59,20.89,29.7,0,1255.5,0.00453753550378,0 +"9186",2015-02-17 23:53:00,20.89,29.7,0,1245.5,0.00453753550378,0 +"9187",2015-02-17 23:54:00,20.89,29.6,0,1221.5,0.00452214653107444,0 +"9188",2015-02-17 23:55:00,20.89,29.6,0,1201,0.00452214653107444,0 +"9189",2015-02-17 23:55:59,20.89,29.55,0,1196,0.00451445232820536,0 +"9190",2015-02-17 23:57:00,20.89,29.525,0,1194,0.0045106052976387,0 +"9191",2015-02-17 23:57:59,20.89,29.5,0,1203,0.00450675831431613,0 +"9192",2015-02-17 23:58:59,20.89,29.5,0,1202.5,0.00450675831431613,0 +"9193",2015-02-18 00:00:00,20.89,29.445,0,1201.5,0.00449829511730139,0 +"9194",2015-02-18 00:01:00,20.89,29.5,0,1201.5,0.00450675831431613,0 +"9195",2015-02-18 00:02:00,20.89,29.5,0,1205,0.00450675831431613,0 +"9196",2015-02-18 00:03:00,20.89,29.4633333333333,0,1212.66666666667,0.00450111615756719,0 +"9197",2015-02-18 00:04:00,20.89,29.5,0,1213.5,0.00450675831431613,0 +"9198",2015-02-18 00:04:59,20.89,29.4266666666667,0,1213.66666666667,0.00449547410244092,0 +"9199",2015-02-18 00:06:00,20.89,29.29,0,1215,0.00447444551948421,0 +"9200",2015-02-18 00:07:00,20.89,29.39,0,1233,0.00448983214893459,0 +"9201",2015-02-18 00:08:00,20.89,29.39,0,1234.5,0.00448983214893459,0 +"9202",2015-02-18 00:08:59,20.89,29.29,0,1239,0.00447444551948421,0 +"9203",2015-02-18 00:10:00,20.89,29.29,0,1246.5,0.00447444551948421,0 +"9204",2015-02-18 00:10:59,20.89,29.29,0,1238.5,0.00447444551948421,0 +"9205",2015-02-18 00:11:59,20.89,29.2,0,1244,0.00446059819916775,0 +"9206",2015-02-18 00:13:00,20.84,29.2,0,1255.5,0.00444679780452915,0 +"9207",2015-02-18 00:14:00,20.89,29.2,0,1327,0.00446059819916775,0 +"9208",2015-02-18 00:15:00,20.89,29.2,0,1355,0.00446059819916775,0 +"9209",2015-02-18 00:16:00,20.89,29.1,0,1367.5,0.0044452130056415,0 +"9210",2015-02-18 00:16:59,20.89,29.15,0,1302.5,0.00445290550794254,0 +"9211",2015-02-18 00:17:59,20.89,29,0,1255,0.00442982856778407,0 +"9212",2015-02-18 00:19:00,20.89,29.1,0,1239,0.0044452130056415,0 +"9213",2015-02-18 00:20:00,20.89,29,0,1052.66666666667,0.00442982856778407,0 +"9214",2015-02-18 00:21:00,20.89,29,0,1030.5,0.00442982856778407,0 +"9215",2015-02-18 00:22:00,20.89,29,0,1043,0.00442982856778407,0 +"9216",2015-02-18 00:23:00,20.89,29,0,1045,0.00442982856778407,0 +"9217",2015-02-18 00:23:59,20.89,29,0,1058.5,0.00442982856778407,0 +"9218",2015-02-18 00:24:59,20.89,28.89,0,1050,0.00441290655887192,0 +"9219",2015-02-18 00:26:00,20.89,28.89,0,1058.5,0.00441290655887192,0 +"9220",2015-02-18 00:27:00,20.89,28.89,0,1072,0.00441290655887192,0 +"9221",2015-02-18 00:28:00,20.89,28.89,0,1086,0.00441290655887192,0 +"9222",2015-02-18 00:29:00,20.89,28.89,0,1118.5,0.00441290655887192,0 +"9223",2015-02-18 00:29:59,20.89,28.89,0,1141.5,0.00441290655887192,0 +"9224",2015-02-18 00:30:59,20.89,28.89,0,1145.33333333333,0.00441290655887192,0 +"9225",2015-02-18 00:32:00,20.89,28.89,0,1141,0.00441290655887192,0 +"9226",2015-02-18 00:33:00,20.89,28.84,0,1154,0.00440521503886434,0 +"9227",2015-02-18 00:34:00,20.84,28.84,0,1159.5,0.00439158719224813,0 +"9228",2015-02-18 00:35:00,20.89,28.89,0,1164.5,0.00441290655887192,0 +"9229",2015-02-18 00:36:00,20.8233333333333,28.8233333333333,0,1158,0.00438449969976528,0 +"9230",2015-02-18 00:36:59,20.84,28.745,0,1185.5,0.00437701934797759,0 +"9231",2015-02-18 00:38:00,20.8233333333333,28.73,0,1206.33333333333,0.00437020242308493,0 +"9232",2015-02-18 00:39:00,20.89,28.7,0,1656.5,0.00438367978766792,0 +"9233",2015-02-18 00:40:00,20.89,28.7,0,1489.66666666667,0.00438367978766792,0 +"9234",2015-02-18 00:40:59,20.89,28.7,0,1879.5,0.00438367978766792,0 +"9235",2015-02-18 00:42:00,20.89,28.65,0,1774,0.00437598898537119,0 +"9236",2015-02-18 00:42:59,20.89,28.6,0,1684,0.00436829837192905,0 +"9237",2015-02-18 00:43:59,20.8566666666667,28.4633333333333,0,1631.66666666667,0.0043383093236317,0 +"9238",2015-02-18 00:45:00,20.79,28.5,0,1542,0.00432602460528833,0 +"9239",2015-02-18 00:46:00,20.89,28.55,0,1512.5,0.00436060794733453,0 +"9240",2015-02-18 00:47:00,20.8566666666667,28.5666666666667,0,1431.66666666667,0.00435416938204361,0 +"9241",2015-02-18 00:48:00,20.89,28.5,0,1399,0.00435291771158068,0 +"9242",2015-02-18 00:49:00,20.89,28.445,0,1366,0.00434445867035411,0 +"9243",2015-02-18 00:49:59,20.89,28.445,0,1328.5,0.00434445867035411,0 +"9244",2015-02-18 00:51:00,20.89,28.39,0,1306,0.00433599985760708,0 +"9245",2015-02-18 00:52:00,20.89,28.39,0,1308,0.00433599985760708,0 +"9246",2015-02-18 00:53:00,20.89,28.39,0,1321,0.00433599985760708,0 +"9247",2015-02-18 00:53:59,20.89,28.295,0,1344.5,0.00432138971917123,0 +"9248",2015-02-18 00:55:00,20.89,28.29,0,1359,0.00432062078339764,0 +"9249",2015-02-18 00:55:59,20.89,28.29,0,1359,0.00432062078339764,0 +"9250",2015-02-18 00:56:59,20.89,28.29,0,1357,0.00432062078339764,0 +"9251",2015-02-18 00:58:00,20.89,28.29,0,1350,0.00432062078339764,0 +"9252",2015-02-18 00:59:00,20.8566666666667,28.1666666666667,0,1337.5,0.00429278007033011,0 +"9253",2015-02-18 01:00:00,20.89,28.2,0,1340.33333333333,0.00430678026232214,0 +"9254",2015-02-18 01:01:00,20.89,28.245,0,1342,0.0043137004463966,0 +"9255",2015-02-18 01:01:59,20.89,28.2,0,1356,0.00430678026232214,0 +"9256",2015-02-18 01:02:59,20.89,28.1,0,1357,0.00429140262297937,0 +"9257",2015-02-18 01:04:00,20.8233333333333,28.1333333333333,0,1394.33333333333,0.00427881739663079,0 +"9258",2015-02-18 01:05:00,20.89,28.2,0,1427,0.00430678026232214,0 +"9259",2015-02-18 01:06:00,20.89,28.2,0,1427,0.00430678026232214,0 +"9260",2015-02-18 01:07:00,20.89,28.15,0,1420,0.00429909134825824,0 +"9261",2015-02-18 01:08:00,20.79,28,0,1419,0.00424961090793852,0 +"9262",2015-02-18 01:08:59,20.89,28.1,0,1422,0.00429140262297937,0 +"9263",2015-02-18 01:09:59,20.84,27.995,0,1366.5,0.00426203383788697,0 +"9264",2015-02-18 01:11:00,20.89,28.1,0,1322,0.00429140262297937,0 +"9265",2015-02-18 01:12:00,20.89,27.995,0,1307.5,0.00427525691435811,0 +"9266",2015-02-18 01:13:00,20.8233333333333,27.89,0,1311.5,0.00424155629721384,0 +"9267",2015-02-18 01:14:00,20.79,27.89,0,1341.33333333333,0.00423280239666859,0 +"9268",2015-02-18 01:14:59,20.79,27.89,0,1327.66666666667,0.00423280239666859,0 +"9269",2015-02-18 01:15:59,20.79,27.89,0,1323.5,0.00423280239666859,0 +"9270",2015-02-18 01:17:00,20.79,27.89,0,1297.5,0.00423280239666859,0 +"9271",2015-02-18 01:18:00,20.79,27.89,0,1291.25,0.00423280239666859,0 +"9272",2015-02-18 01:19:00,20.89,28,0,1299,0.00427602573874893,0 +"9273",2015-02-18 01:20:00,20.79,27.89,0,1302,0.00423280239666859,0 +"9274",2015-02-18 01:21:00,20.79,27.89,0,1317,0.00423280239666859,0 +"9275",2015-02-18 01:21:59,20.79,27.79,0,1321,0.00421752271482834,0 +"9276",2015-02-18 01:23:00,20.84,27.84,0,1321.5,0.00423827542950838,0 +"9277",2015-02-18 01:24:00,20.79,27.79,0,1321,0.00421752271482834,0 +"9278",2015-02-18 01:25:00,20.79,27.79,0,1317.5,0.00421752271482834,0 +"9279",2015-02-18 01:25:59,20.79,27.6666666666667,0,1318.66666666667,0.00419867880075799,0 +"9280",2015-02-18 01:27:00,20.89,27.7,0,1329,0.00422989961617544,0 +"9281",2015-02-18 01:27:59,20.8566666666667,27.76,0,1330.66666666667,0.00423037993830305,0 +"9282",2015-02-18 01:28:59,20.89,27.7,0,1329,0.00422989961617544,0 +"9283",2015-02-18 01:30:00,20.84,27.7225,0,1330.5,0.0042202662243341,0 +"9284",2015-02-18 01:31:00,20.89,27.79,0,1342,0.00424373673950824,0 +"9285",2015-02-18 01:32:00,20.89,27.6,0,1342,0.0042145257518382,0 +"9286",2015-02-18 01:33:00,20.79,27.445,0,1333.5,0.00416481353563252,0 +"9287",2015-02-18 01:34:00,20.79,27.6,0,1336,0.0041884933734446,0 +"9288",2015-02-18 01:34:59,20.79,27.6,0,1335.66666666667,0.0041884933734446,0 +"9289",2015-02-18 01:36:00,20.79,27.6,0,1322,0.0041884933734446,0 +"9290",2015-02-18 01:37:00,20.79,27.65,0,1348.5,0.00419613241286596,0 +"9291",2015-02-18 01:38:00,20.79,27.55,0,1358.5,0.00418085452040003,0 +"9292",2015-02-18 01:38:59,20.79,27.6,0,1386.5,0.0041884933734446,0 +"9293",2015-02-18 01:40:00,20.79,27.5,0,1404,0.00417321585372542,0 +"9294",2015-02-18 01:40:59,20.79,27.5,0,1431.5,0.00417321585372542,0 +"9295",2015-02-18 01:41:59,20.79,27.445,0,1483,0.00416481353563252,0 +"9296",2015-02-18 01:43:00,20.79,27.445,0,1472,0.00416481353563252,0 +"9297",2015-02-18 01:44:00,20.79,27.39,0,1484,0.00415641144302994,0 +"9298",2015-02-18 01:45:00,20.79,27.5,0,1496.33333333333,0.00417321585372542,0 +"9299",2015-02-18 01:46:00,20.79,27.5,0,1497,0.00417321585372542,0 +"9300",2015-02-18 01:46:59,20.79,27.39,0,1515.5,0.00415641144302994,0 +"9301",2015-02-18 01:47:59,20.79,27.5,0,1748,0.00417321585372542,0 +"9302",2015-02-18 01:49:00,20.79,27.39,0,2065.75,0.00415641144302994,0 +"9303",2015-02-18 01:50:00,20.79,27.39,0,1739,0.00415641144302994,0 +"9304",2015-02-18 01:51:00,20.79,27.245,0,2076.5,0.00413426155241865,0 +"9305",2015-02-18 01:52:00,20.79,27.26,0,1978.66666666667,0.00413655284774203,0 +"9306",2015-02-18 01:53:00,20.79,27.1,0,1588,0.00411211322882893,0 +"9307",2015-02-18 01:53:59,20.79,27.195,0,1544.5,0.00412662402245315,0 +"9308",2015-02-18 01:54:59,20.79,27.1,0,1538.5,0.00411211322882893,0 +"9309",2015-02-18 01:56:00,20.73,27.1,0,1398.33333333333,0.00409684743956725,0 +"9310",2015-02-18 01:57:00,20.7,27.1,0,1415,0.00408923331117716,0 +"9311",2015-02-18 01:58:00,20.7,27.15,0,1409,0.00409682771562157,0 +"9312",2015-02-18 01:59:00,20.7,27.15,0,1603.5,0.00409682771562157,0 +"9313",2015-02-18 01:59:59,20.7,27.2,0,1537,0.00410442230430706,0 +"9314",2015-02-18 02:00:59,20.7,27.1666666666667,0,1288.66666666667,0.00409935922471184,0 +"9315",2015-02-18 02:02:00,20.7,27.2,0,1283,0.00410442230430706,0 +"9316",2015-02-18 02:03:00,20.7,27.2,0,1282,0.00410442230430706,0 +"9317",2015-02-18 02:04:00,20.745,27.2,0,1282.5,0.00411589090426523,0 +"9318",2015-02-18 02:05:00,20.79,27.0666666666667,0,1285,0.00410702188169386,0 +"9319",2015-02-18 02:06:00,20.7,27,0,1282,0.00407404505498477,0 +"9320",2015-02-18 02:06:59,20.745,27.05,0,1236.5,0.00409304361376997,0 +"9321",2015-02-18 02:08:00,20.7,27.0666666666667,0,1241.33333333333,0.00408417047723373,0 +"9322",2015-02-18 02:09:00,20.7,27.1,0,1241,0.00408923331117716,0 +"9323",2015-02-18 02:10:00,20.7,26.945,0,1219.5,0.00406569182817913,0 +"9324",2015-02-18 02:10:59,20.7,27,0,1214,0.00407404505498477,0 +"9325",2015-02-18 02:12:00,20.7,26.945,0,1216.5,0.00406569182817913,0 +"9326",2015-02-18 02:12:59,20.7,27.1,0,1211,0.00408923331117716,0 +"9327",2015-02-18 02:13:59,20.7,27.1,0,1207.5,0.00408923331117716,0 +"9328",2015-02-18 02:15:00,20.7,27,0,1209,0.00407404505498477,0 +"9329",2015-02-18 02:16:00,20.7,26.995,0,1206.5,0.0040732856615188,0 +"9330",2015-02-18 02:17:00,20.7,27.1,0,1210,0.00408923331117716,0 +"9331",2015-02-18 02:18:00,20.7,27,0,1215,0.00407404505498477,0 +"9332",2015-02-18 02:19:00,20.745,27,0,1222.5,0.00408542822080454,0 +"9333",2015-02-18 02:19:59,20.745,26.89,0,1221,0.00406867500836947,0 +"9334",2015-02-18 02:21:00,20.73,26.8233333333333,0,1213.66666666667,0.00405474965235427,0 +"9335",2015-02-18 02:22:00,20.7,26.84,0,1212,0.00404974537777309,0 +"9336",2015-02-18 02:23:00,20.7,26.89,0,1220.5,0.00405733882427195,0 +"9337",2015-02-18 02:23:59,20.6666666666667,26.7933333333333,0,1220.33333333333,0.00403430964047579,0 +"9338",2015-02-18 02:25:00,20.7,26.89,0,1224,0.00405733882427195,0 +"9339",2015-02-18 02:25:59,20.6,26.84,0,1234,0.00402470082344019,0 +"9340",2015-02-18 02:26:59,20.7,26.89,0,1231.5,0.00405733882427195,0 +"9341",2015-02-18 02:28:00,20.6,26.84,0,1233.5,0.00402470082344019,0 +"9342",2015-02-18 02:29:00,20.6,26.84,0,1238,0.00402470082344019,0 +"9343",2015-02-18 02:30:00,20.6,26.89,0,1233,0.00403224700786772,0 +"9344",2015-02-18 02:31:00,20.7,27,0,1234,0.00407404505498477,0 +"9345",2015-02-18 02:31:59,20.7,26.945,0,1239,0.00406569182817913,0 +"9346",2015-02-18 02:32:59,20.7,26.89,0,1246,0.00405733882427195,0 +"9347",2015-02-18 02:34:00,20.6666666666667,26.89,0,1253.66666666667,0.00404895962404328,0 +"9348",2015-02-18 02:35:00,20.65,26.79,0,1257.5,0.00402963636920306,0 +"9349",2015-02-18 02:36:00,20.7,26.89,0,1257,0.00405733882427195,0 +"9350",2015-02-18 02:37:00,20.7,26.89,0,1254.5,0.00405733882427195,0 +"9351",2015-02-18 02:38:00,20.7,26.89,0,1262,0.00405733882427195,0 +"9352",2015-02-18 02:38:59,20.7,26.89,0,1276,0.00405733882427195,0 +"9353",2015-02-18 02:39:59,20.7,26.89,0,1276,0.00405733882427195,0 +"9354",2015-02-18 02:41:00,20.7,26.79,0,1272.5,0.00404215211547375,0 +"9355",2015-02-18 02:42:00,20.7,26.8233333333333,0,1272,0.0040472142698737,0 +"9356",2015-02-18 02:43:00,20.7,26.79,0,1277,0.00404215211547375,0 +"9357",2015-02-18 02:44:00,20.7,26.79,0,1274,0.00404215211547375,0 +"9358",2015-02-18 02:44:59,20.79,26.745,0,1272.5,0.0040578946364152,0 +"9359",2015-02-18 02:45:59,20.79,26.79,0,1271,0.00406476689601859,0 +"9360",2015-02-18 02:47:00,20.745,26.7,0,1264.5,0.00403973975313514,0 +"9361",2015-02-18 02:48:00,20.79,26.745,0,1262,0.0040578946364152,0 +"9362",2015-02-18 02:49:00,20.79,26.7,0,1255.33333333333,0.00405102252768257,0 +"9363",2015-02-18 02:50:00,20.79,26.7,0,1262,0.00405102252768257,0 +"9364",2015-02-18 02:51:00,20.79,26.7,0,1261.5,0.00405102252768257,0 +"9365",2015-02-18 02:51:59,20.79,26.6,0,1253.33333333333,0.00403575171507294,0 +"9366",2015-02-18 02:53:00,20.79,26.6,0,1268,0.00403575171507294,0 +"9367",2015-02-18 02:54:00,20.79,26.6,0,1264.5,0.00403575171507294,0 +"9368",2015-02-18 02:55:00,20.79,26.6,0,1264,0.00403575171507294,0 +"9369",2015-02-18 02:55:59,20.79,26.6,0,1264.33333333333,0.00403575171507294,0 +"9370",2015-02-18 02:57:00,20.79,26.6,0,1264.5,0.00403575171507294,0 +"9371",2015-02-18 02:57:59,20.79,26.625,0,1260.75,0.00403956934838305,0 +"9372",2015-02-18 02:58:59,20.79,26.65,0,1257,0.00404338702825413,0 +"9373",2015-02-18 03:00:00,20.79,26.6,0,1261,0.00403575171507294,0 +"9374",2015-02-18 03:01:00,20.79,26.6,0,1259,0.00403575171507294,0 +"9375",2015-02-18 03:02:00,20.79,26.6,0,1253,0.00403575171507294,0 +"9376",2015-02-18 03:03:00,20.79,26.6,0,1247,0.00403575171507294,0 +"9377",2015-02-18 03:04:00,20.79,26.5666666666667,0,1239.66666666667,0.00403066160975281,0 +"9378",2015-02-18 03:04:59,20.79,26.5,0,1236,0.00402048164742504,0 +"9379",2015-02-18 03:06:00,20.79,26.55,0,1236,0.00402811658813218,0 +"9380",2015-02-18 03:07:00,20.79,26.5,0,1244.66666666667,0.00402048164742504,0 +"9381",2015-02-18 03:08:00,20.79,26.5,0,1259,0.00402048164742504,0 +"9382",2015-02-18 03:08:59,20.79,26.5,0,1251.5,0.00402048164742504,0 +"9383",2015-02-18 03:10:00,20.79,26.5,0,1252,0.00402048164742504,0 +"9384",2015-02-18 03:10:59,20.79,26.5,0,1255,0.00402048164742504,0 +"9385",2015-02-18 03:11:59,20.79,26.5,0,1261,0.00402048164742504,0 +"9386",2015-02-18 03:13:00,20.79,26.5,0,1256.5,0.00402048164742504,0 +"9387",2015-02-18 03:14:00,20.79,26.5,0,1257.5,0.00402048164742504,0 +"9388",2015-02-18 03:15:00,20.79,26.5,0,1261,0.00402048164742504,0 +"9389",2015-02-18 03:16:00,20.79,26.445,0,1264,0.00401208342773889,0 +"9390",2015-02-18 03:16:59,20.79,26.5,0,1263,0.00402048164742504,0 +"9391",2015-02-18 03:17:59,20.79,26.39,0,1270,0.00400368543337811,0 +"9392",2015-02-18 03:19:00,20.79,26.39,0,1287.5,0.00400368543337811,0 +"9393",2015-02-18 03:20:00,20.79,26.39,0,1316,0.00400368543337811,0 +"9394",2015-02-18 03:21:00,20.79,26.39,0,1363,0.00400368543337811,0 +"9395",2015-02-18 03:22:00,20.79,26.39,0,1365,0.00400368543337811,0 +"9396",2015-02-18 03:23:00,20.79,26.445,0,1366.5,0.00401208342773889,0 +"9397",2015-02-18 03:23:59,20.79,26.39,0,1359.33333333333,0.00400368543337811,0 +"9398",2015-02-18 03:24:59,20.79,26.39,0,1356,0.00400368543337811,0 +"9399",2015-02-18 03:26:00,20.79,26.39,0,1365.5,0.00400368543337811,0 +"9400",2015-02-18 03:27:00,20.79,26.39,0,1369,0.00400368543337811,0 +"9401",2015-02-18 03:28:00,20.8566666666667,26.4633333333333,0,1371.33333333333,0.00403149858833552,0 +"9402",2015-02-18 03:29:00,20.79,26.39,0,1378,0.00400368543337811,0 +"9403",2015-02-18 03:29:59,20.79,26.3233333333333,0,1346,0.00399350634835022,0 +"9404",2015-02-18 03:30:59,20.79,26.3566666666667,0,1339.33333333333,0.00399859584948477,0 +"9405",2015-02-18 03:32:00,20.79,26.29,0,1343,0.00398841692997244,0 +"9406",2015-02-18 03:33:00,20.79,26.29,0,1354,0.00398841692997244,0 +"9407",2015-02-18 03:34:00,20.79,26.39,0,1354,0.00400368543337811,0 +"9408",2015-02-18 03:35:00,20.79,26.3566666666667,0,1367,0.00399859584948477,0 +"9409",2015-02-18 03:36:00,20.79,26.3566666666667,0,1373.75,0.00399859584948477,0 +"9410",2015-02-18 03:36:59,20.79,26.39,0,1366.5,0.00400368543337811,0 +"9411",2015-02-18 03:38:00,20.79,26.29,0,1374.5,0.00398841692997244,0 +"9412",2015-02-18 03:39:00,20.79,26.29,0,1383.75,0.00398841692997244,0 +"9413",2015-02-18 03:40:00,20.79,26.29,0,1388,0.00398841692997244,0 +"9414",2015-02-18 03:40:59,20.79,26.29,0,1391.33333333333,0.00398841692997244,0 +"9415",2015-02-18 03:42:00,20.79,26.29,0,1391,0.00398841692997244,0 +"9416",2015-02-18 03:42:59,20.79,26.245,0,1385,0.0039815463464318,0 +"9417",2015-02-18 03:43:59,20.79,26.29,0,1365,0.00398841692997244,0 +"9418",2015-02-18 03:45:00,20.79,26.26,0,1349,0.00398383652418782,0 +"9419",2015-02-18 03:46:00,20.79,26.245,0,1347.5,0.0039815463464318,0 +"9420",2015-02-18 03:47:00,20.79,26.2,0,1354,0.00397467591370672,0 +"9421",2015-02-18 03:48:00,20.79,26.2,0,1366,0.00397467591370672,0 +"9422",2015-02-18 03:49:00,20.79,26.2,0,1366,0.00397467591370672,0 +"9423",2015-02-18 03:49:59,20.79,26.2,0,1354.5,0.00397467591370672,0 +"9424",2015-02-18 03:51:00,20.79,26.2,0,1350.5,0.00397467591370672,0 +"9425",2015-02-18 03:52:00,20.79,26.2,0,1362,0.00397467591370672,0 +"9426",2015-02-18 03:53:00,20.79,26.2,0,1369,0.00397467591370672,0 +"9427",2015-02-18 03:53:59,20.79,26.2,0,1391,0.00397467591370672,0 +"9428",2015-02-18 03:55:00,20.79,26.1,0,1406,0.00395940882536073,0 +"9429",2015-02-18 03:55:59,20.79,26.2,0,1409.25,0.00397467591370672,0 +"9430",2015-02-18 03:56:59,20.79,26.1,0,1415,0.00395940882536073,0 +"9431",2015-02-18 03:58:00,20.79,26.2,0,1432.33333333333,0.00397467591370672,0 +"9432",2015-02-18 03:59:00,20.79,26.2,0,1432.5,0.00397467591370672,0 +"9433",2015-02-18 04:00:00,20.79,26.2,0,1428,0.00397467591370672,0 +"9434",2015-02-18 04:01:00,20.79,26.1,0,1434,0.00395940882536073,0 +"9435",2015-02-18 04:01:59,20.79,26.1,0,1434,0.00395940882536073,0 +"9436",2015-02-18 04:02:59,20.79,26.1,0,1431.5,0.00395940882536073,0 +"9437",2015-02-18 04:04:00,20.79,26.1,0,1421,0.00395940882536073,0 +"9438",2015-02-18 04:05:00,20.79,26.1,0,1418.75,0.00395940882536073,0 +"9439",2015-02-18 04:06:00,20.79,26.1,0,1415,0.00395940882536073,0 +"9440",2015-02-18 04:07:00,20.79,26.1,0,1409.5,0.00395940882536073,0 +"9441",2015-02-18 04:08:00,20.79,26.1,0,1399.5,0.00395940882536073,0 +"9442",2015-02-18 04:08:59,20.79,26.1,0,1403.5,0.00395940882536073,0 +"9443",2015-02-18 04:09:59,20.79,26.1333333333333,0,1408.33333333333,0.00396449777206345,0 +"9444",2015-02-18 04:11:00,20.79,26.1,0,1414,0.00395940882536073,0 +"9445",2015-02-18 04:12:00,20.79,26.1,0,1413,0.00395940882536073,0 +"9446",2015-02-18 04:13:00,20.79,26.1,0,1411,0.00395940882536073,0 +"9447",2015-02-18 04:14:00,20.79,26.1,0,1401,0.00395940882536073,0 +"9448",2015-02-18 04:14:59,20.79,26.1,0,1394,0.00395940882536073,0 +"9449",2015-02-18 04:15:59,20.79,26.1,0,1399.5,0.00395940882536073,0 +"9450",2015-02-18 04:17:00,20.79,26,0,1416,0.00394414248170397,0 +"9451",2015-02-18 04:18:00,20.89,26.1,0,1426,0.00398400833577413,0 +"9452",2015-02-18 04:19:00,20.8233333333333,26.1333333333333,0,1424,0.00397269326909056,0 +"9453",2015-02-18 04:20:00,20.79,26.1,0,1441,0.00395940882536073,0 +"9454",2015-02-18 04:21:00,20.79,26.1,0,1449,0.00395940882536073,0 +"9455",2015-02-18 04:21:59,20.8233333333333,26.0666666666667,0,1456.5,0.00396249428544764,0 +"9456",2015-02-18 04:23:00,20.79,26.05,0,1463,0.0039517755604496,0 +"9457",2015-02-18 04:24:00,20.79,26,0,1467.5,0.00394414248170397,0 +"9458",2015-02-18 04:25:00,20.79,26.05,0,1468.5,0.0039517755604496,0 +"9459",2015-02-18 04:25:59,20.79,26.075,0,1464.75,0.00395559216963405,0 +"9460",2015-02-18 04:27:00,20.79,26.1,0,1452,0.00395940882536073,0 +"9461",2015-02-18 04:27:59,20.79,26,0,1453,0.00394414248170397,0 +"9462",2015-02-18 04:28:59,20.79,26,0,1463,0.00394414248170397,0 +"9463",2015-02-18 04:30:00,20.79,26,0,1466,0.00394414248170397,0 +"9464",2015-02-18 04:31:00,20.79,26.1,0,1465,0.00395940882536073,0 +"9465",2015-02-18 04:32:00,20.79,26.025,0,1481.25,0.00394795899780652,0 +"9466",2015-02-18 04:33:00,20.79,26,0,1482.75,0.00394414248170397,0 +"9467",2015-02-18 04:34:00,20.79,26,0,1482.5,0.00394414248170397,0 +"9468",2015-02-18 04:34:59,20.79,26,0,1482.5,0.00394414248170397,0 +"9469",2015-02-18 04:36:00,20.8566666666667,26.1,0,1501,0.00397579356470849,0 +"9470",2015-02-18 04:37:00,20.79,26.05,0,1500.5,0.0039517755604496,0 +"9471",2015-02-18 04:38:00,20.79,26.1,0,1514,0.00395940882536073,0 +"9472",2015-02-18 04:38:59,20.79,26.0333333333333,0,1511.66666666667,0.003949231180183,0 +"9473",2015-02-18 04:40:00,20.79,26.0333333333333,0,1505,0.003949231180183,0 +"9474",2015-02-18 04:40:59,20.84,26.1,0,1503,0.00397169178392402,0 +"9475",2015-02-18 04:41:59,20.79,26,0,1511,0.00394414248170397,0 +"9476",2015-02-18 04:43:00,20.79,26.1,0,1510,0.00395940882536073,0 +"9477",2015-02-18 04:44:00,20.79,26.1,0,1484,0.00395940882536073,0 +"9478",2015-02-18 04:45:00,20.79,26.1,0,1456.5,0.00395940882536073,0 +"9479",2015-02-18 04:46:00,20.79,26.1,0,1504.5,0.00395940882536073,0 +"9480",2015-02-18 04:46:59,20.79,26.1,0,1521.5,0.00395940882536073,0 +"9481",2015-02-18 04:47:59,20.79,26.1,0,1513,0.00395940882536073,0 +"9482",2015-02-18 04:49:00,20.79,26.1,0,1510,0.00395940882536073,0 +"9483",2015-02-18 04:50:00,20.79,26.1,0,1513.75,0.00395940882536073,0 +"9484",2015-02-18 04:51:00,20.79,26.1,0,1517.5,0.00395940882536073,0 +"9485",2015-02-18 04:52:00,20.79,26.175,0,1519,0.00397085907180262,0 +"9486",2015-02-18 04:53:00,20.79,26.1,0,1539.5,0.00395940882536073,0 +"9487",2015-02-18 04:53:59,20.79,26.1,0,1547,0.00395940882536073,0 +"9488",2015-02-18 04:54:59,20.79,26.2,0,1565,0.00397467591370672,0 +"9489",2015-02-18 04:56:00,20.79,26.2,0,1570,0.00397467591370672,0 +"9490",2015-02-18 04:57:00,20.79,26.2,0,1562,0.00397467591370672,0 +"9491",2015-02-18 04:58:00,20.79,26.2,0,1573.5,0.00397467591370672,0 +"9492",2015-02-18 04:59:00,20.745,26.2,0,1555,0.00396360712347269,0 +"9493",2015-02-18 04:59:59,20.745,26.2,0,1510,0.00396360712347269,0 +"9494",2015-02-18 05:00:59,20.76,26.26,0,1495.66666666667,0.0039764371839183,0 +"9495",2015-02-18 05:02:00,20.7,26.2,0,1493.5,0.00395256552876124,0 +"9496",2015-02-18 05:03:00,20.7,26.2,0,1493,0.00395256552876124,0 +"9497",2015-02-18 05:04:00,20.745,26.2,0,1481,0.00396360712347269,0 +"9498",2015-02-18 05:05:00,20.7675,26.2675,0,1472.5,0.00397942937126781,0 +"9499",2015-02-18 05:06:00,20.79,26.2,0,1492,0.00397467591370672,0 +"9500",2015-02-18 05:06:59,20.73,26.29,0,1494,0.00397361326462039,0 +"9501",2015-02-18 05:08:00,20.7,26.2,0,1506,0.00395256552876124,0 +"9502",2015-02-18 05:09:00,20.745,26.2,0,1527,0.00396360712347269,0 +"9503",2015-02-18 05:10:00,20.79,26.2,0,1541,0.00397467591370672,0 +"9504",2015-02-18 05:10:59,20.7,26.29,0,1535.5,0.00396622962197959,0 +"9505",2015-02-18 05:12:00,20.745,26.29,0,1528,0.00397730963023016,0 +"9506",2015-02-18 05:12:59,20.79,26.2,0,1520.5,0.00397467591370672,0 +"9507",2015-02-18 05:13:59,20.79,26.2,0,1503,0.00397467591370672,0 +"9508",2015-02-18 05:15:00,20.79,26.2,0,1496,0.00397467591370672,0 +"9509",2015-02-18 05:16:00,20.79,26.2,0,1498,0.00397467591370672,0 +"9510",2015-02-18 05:17:00,20.79,26.2,0,1484.5,0.00397467591370672,0 +"9511",2015-02-18 05:18:00,20.79,26.29,0,1476,0.00398841692997244,0 +"9512",2015-02-18 05:19:00,20.79,26.29,0,1477,0.00398841692997244,0 +"9513",2015-02-18 05:19:59,20.745,26.29,0,1487,0.00397730963023016,0 +"9514",2015-02-18 05:21:00,20.73,26.26,0,1494,0.00396904996755869,0 +"9515",2015-02-18 05:22:00,20.79,26.245,0,1506.5,0.0039815463464318,0 +"9516",2015-02-18 05:23:00,20.745,26.29,0,1510.5,0.00397730963023016,0 +"9517",2015-02-18 05:23:59,20.745,26.245,0,1523.5,0.00397045830186438,0 +"9518",2015-02-18 05:25:00,20.79,26.245,0,1514,0.0039815463464318,0 +"9519",2015-02-18 05:25:59,20.79,26.29,0,1527.5,0.00398841692997244,0 +"9520",2015-02-18 05:26:59,20.79,26.29,0,1532,0.00398841692997244,0 +"9521",2015-02-18 05:28:00,20.79,26.29,0,1532.5,0.00398841692997244,0 +"9522",2015-02-18 05:29:00,20.76,26.29,0,1538.66666666667,0.003981009028227,0 +"9523",2015-02-18 05:30:00,20.79,26.29,0,1542,0.00398841692997244,0 +"9524",2015-02-18 05:31:00,20.79,26.2,0,1551.5,0.00397467591370672,0 +"9525",2015-02-18 05:31:59,20.79,26.2,0,1555.5,0.00397467591370672,0 +"9526",2015-02-18 05:32:59,20.79,26.2,0,1555,0.00397467591370672,0 +"9527",2015-02-18 05:34:00,20.79,26.29,0,1550.5,0.00398841692997244,0 +"9528",2015-02-18 05:35:00,20.79,26.29,0,1546,0.00398841692997244,0 +"9529",2015-02-18 05:36:00,20.79,26.29,0,1531,0.00398841692997244,0 +"9530",2015-02-18 05:37:00,20.79,26.29,0,1518,0.00398841692997244,0 +"9531",2015-02-18 05:38:00,20.79,26.29,0,1508.5,0.00398841692997244,0 +"9532",2015-02-18 05:38:59,20.79,26.29,0,1513.5,0.00398841692997244,0 +"9533",2015-02-18 05:39:59,20.79,26.29,0,1516,0.00398841692997244,0 +"9534",2015-02-18 05:41:00,20.79,26.29,0,1521,0.00398841692997244,0 +"9535",2015-02-18 05:42:00,20.79,26.29,0,1536.5,0.00398841692997244,0 +"9536",2015-02-18 05:43:00,20.79,26.39,0,1534,0.00400368543337811,0 +"9537",2015-02-18 05:44:00,20.79,26.39,0,1533.5,0.00400368543337811,0 +"9538",2015-02-18 05:44:59,20.745,26.39,0,1582,0.00399253534134539,0 +"9539",2015-02-18 05:45:59,20.76,26.39,0,1571.33333333333,0.00399624899157711,0 +"9540",2015-02-18 05:47:00,20.79,26.39,0,1571,0.00400368543337811,0 +"9541",2015-02-18 05:48:00,20.79,26.39,0,1568,0.00400368543337811,0 +"9542",2015-02-18 05:49:00,20.79,26.39,0,1563.66666666667,0.00400368543337811,0 +"9543",2015-02-18 05:50:00,20.79,26.39,0,1556.5,0.00400368543337811,0 +"9544",2015-02-18 05:51:00,20.79,26.39,0,1572,0.00400368543337811,0 +"9545",2015-02-18 05:51:59,20.79,26.39,0,1597,0.00400368543337811,0 +"9546",2015-02-18 05:53:00,20.79,26.39,0,1597,0.00400368543337811,0 +"9547",2015-02-18 05:54:00,20.79,26.39,0,1601.5,0.00400368543337811,0 +"9548",2015-02-18 05:55:00,20.79,26.39,0,1577,0.00400368543337811,0 +"9549",2015-02-18 05:55:59,20.79,26.39,0,1567,0.00400368543337811,0 +"9550",2015-02-18 05:57:00,20.79,26.39,0,1531,0.00400368543337811,0 +"9551",2015-02-18 05:57:59,20.79,26.445,0,1495,0.00401208342773889,0 +"9552",2015-02-18 05:58:59,20.79,26.4266666666667,0,1487,0.0040092840712496,0 +"9553",2015-02-18 06:00:00,20.79,26.39,0,1486,0.00400368543337811,0 +"9554",2015-02-18 06:01:00,20.79,26.445,0,1489,0.00401208342773889,0 +"9555",2015-02-18 06:02:00,20.79,26.5,0,1492,0.00402048164742504,0 +"9556",2015-02-18 06:03:00,20.79,26.5,0,1516,0.00402048164742504,0 +"9557",2015-02-18 06:04:00,20.79,26.5,0,1533,0.00402048164742504,0 +"9558",2015-02-18 06:04:59,20.79,26.5,0,1552.66666666667,0.00402048164742504,0 +"9559",2015-02-18 06:06:00,20.745,26.5,0,1561.5,0.00400928447907247,0 +"9560",2015-02-18 06:07:00,20.79,26.5,0,1569.5,0.00402048164742504,0 +"9561",2015-02-18 06:08:00,20.79,26.5,0,1563.5,0.00402048164742504,0 +"9562",2015-02-18 06:08:59,20.79,26.5,0,1555.5,0.00402048164742504,0 +"9563",2015-02-18 06:10:00,20.79,26.5,0,1561,0.00402048164742504,0 +"9564",2015-02-18 06:10:59,20.79,26.5,0,1566,0.00402048164742504,0 +"9565",2015-02-18 06:11:59,20.79,26.5,0,1564,0.00402048164742504,0 +"9566",2015-02-18 06:13:00,20.79,26.5,0,1563,0.00402048164742504,0 +"9567",2015-02-18 06:14:00,20.7,26.5,0,1543,0.0039981148262085,0 +"9568",2015-02-18 06:15:00,20.7,26.5,0,1538,0.0039981148262085,0 +"9569",2015-02-18 06:16:00,20.79,26.5,0,1533.5,0.00402048164742504,0 +"9570",2015-02-18 06:16:59,20.79,26.6,0,1535,0.00403575171507294,0 +"9571",2015-02-18 06:17:59,20.76,26.6,0,1543.5,0.00402825533012815,0 +"9572",2015-02-18 06:19:00,20.79,26.6,0,1556.5,0.00403575171507294,0 +"9573",2015-02-18 06:20:00,20.745,26.6,0,1554,0.00402451174570149,0 +"9574",2015-02-18 06:21:00,20.7,26.6,0,1559.5,0.00401329939851772,0 +"9575",2015-02-18 06:22:00,20.7,26.6,0,1549,0.00401329939851772,0 +"9576",2015-02-18 06:23:00,20.7,26.6333333333333,0,1538,0.00401836108632246,0 +"9577",2015-02-18 06:23:59,20.7,26.6,0,1533,0.00401329939851772,0 +"9578",2015-02-18 06:24:59,20.7,26.65,0,1536,0.00402089196092,0 +"9579",2015-02-18 06:26:00,20.7,26.7,0,1529.33333333333,0.00402848470749634,0 +"9580",2015-02-18 06:27:00,20.76,26.7,0,1504.66666666667,0.00404349759408431,0 +"9581",2015-02-18 06:28:00,20.79,26.6,0,1498.5,0.00403575171507294,0 +"9582",2015-02-18 06:29:00,20.79,26.6,0,1489,0.00403575171507294,0 +"9583",2015-02-18 06:29:59,20.79,26.6,0,1484,0.00403575171507294,0 +"9584",2015-02-18 06:30:59,20.79,26.65,0,1481,0.00404338702825413,0 +"9585",2015-02-18 06:32:00,20.79,26.6,0,1484.5,0.00403575171507294,0 +"9586",2015-02-18 06:33:00,20.79,26.6,0,1486,0.00403575171507294,0 +"9587",2015-02-18 06:34:00,20.79,26.6,0,1480.33333333333,0.00403575171507294,0 +"9588",2015-02-18 06:35:00,20.79,26.6,0,1475,0.00403575171507294,0 +"9589",2015-02-18 06:36:00,20.79,26.6333333333333,0,1466.66666666667,0.0040408419031666,0 +"9590",2015-02-18 06:36:59,20.79,26.65,0,1475.5,0.00404338702825413,0 +"9591",2015-02-18 06:38:00,20.79,26.65,0,1477,0.00404338702825413,0 +"9592",2015-02-18 06:39:00,20.79,26.6,0,1477,0.00403575171507294,0 +"9593",2015-02-18 06:40:00,20.79,26.7,0,1473,0.00405102252768257,0 +"9594",2015-02-18 06:40:59,20.79,26.7,0,1473,0.00405102252768257,0 +"9595",2015-02-18 06:42:00,20.79,26.7,0,1473,0.00405102252768257,0 +"9596",2015-02-18 06:42:59,20.79,26.7,0,1480,0.00405102252768257,0 +"9597",2015-02-18 06:43:59,20.79,26.7,0,1480,0.00405102252768257,0 +"9598",2015-02-18 06:45:00,20.79,26.7,0,1473.5,0.00405102252768257,0 +"9599",2015-02-18 06:46:00,20.79,26.7,0,1479.5,0.00405102252768257,0 +"9600",2015-02-18 06:47:00,20.79,26.7,0,1483,0.00405102252768257,0 +"9601",2015-02-18 06:48:00,20.79,26.745,0,1499,0.0040578946364152,0 +"9602",2015-02-18 06:49:00,20.79,26.79,0,1501,0.00406476689601859,0 +"9603",2015-02-18 06:49:59,20.79,26.79,0,1502.66666666667,0.00406476689601859,0 +"9604",2015-02-18 06:51:00,20.79,26.79,0,1507,0.00406476689601859,0 +"9605",2015-02-18 06:52:00,20.745,26.84,0,1513,0.00406106020819697,0 +"9606",2015-02-18 06:53:00,20.79,26.89,0,1508,0.00408003912420573,0 +"9607",2015-02-18 06:53:59,20.7,26.89,0,1501,0.00405733882427195,0 +"9608",2015-02-18 06:55:00,20.76,26.89,0,1497.66666666667,0.00407245994052285,0 +"9609",2015-02-18 06:55:59,20.745,26.89,0,1494,0.00406867500836947,0 +"9610",2015-02-18 06:56:59,20.79,26.89,0,1504,0.00408003912420573,0 +"9611",2015-02-18 06:58:00,20.79,26.89,0,1505.5,0.00408003912420573,0 +"9612",2015-02-18 06:59:00,20.79,26.89,0,1497.66666666667,0.00408003912420573,0 +"9613",2015-02-18 07:00:00,20.79,26.89,0,1506,0.00408003912420573,0 +"9614",2015-02-18 07:01:00,20.79,26.89,0,1505,0.00408003912420573,0 +"9615",2015-02-18 07:01:59,20.79,26.89,0,1510,0.00408003912420573,0 +"9616",2015-02-18 07:02:59,20.79,26.89,0,1516.33333333333,0.00408003912420573,0 +"9617",2015-02-18 07:04:00,20.79,26.89,0,1515,0.00408003912420573,0 +"9618",2015-02-18 07:05:00,20.79,26.89,0,1519.66666666667,0.00408003912420573,0 +"9619",2015-02-18 07:06:00,20.745,26.89,0,1520,0.00406867500836947,0 +"9620",2015-02-18 07:07:00,20.745,26.89,0,1525,0.00406867500836947,0 +"9621",2015-02-18 07:08:00,20.7,26.89,0,1509.5,0.00405733882427195,0 +"9622",2015-02-18 07:08:59,20.745,26.89,0,1496,0.00406867500836947,0 +"9623",2015-02-18 07:09:59,20.73,27,0,1495.33333333333,0.00408163071856388,0 +"9624",2015-02-18 07:11:00,20.7675,27,0,1496.75,0.00409113031843797,0 +"9625",2015-02-18 07:12:00,20.7,27,0,1489,0.00407404505498477,0 +"9626",2015-02-18 07:13:00,20.79,27,0,1486.66666666667,0.00409683943582711,0 +"9627",2015-02-18 07:14:00,20.76,27,0,1494.33333333333,0.00408922883962236,0 +"9628",2015-02-18 07:14:59,20.79,27,0,1496,0.00409683943582711,0 +"9629",2015-02-18 07:15:59,20.79,27,0,1491,0.00409683943582711,0 +"9630",2015-02-18 07:17:00,20.79,27,0,1520,0.00409683943582711,0 +"9631",2015-02-18 07:18:00,20.79,27,0,1519,0.00409683943582711,0 +"9632",2015-02-18 07:19:00,20.745,27,0,1512,0.00408542822080454,0 +"9633",2015-02-18 07:20:00,20.76,27,0,1498,0.00408922883962236,0 +"9634",2015-02-18 07:21:00,20.79,27,0,1483,0.00409683943582711,0 +"9635",2015-02-18 07:21:59,20.79,27.05,0,1486,0.00410447623917713,0 +"9636",2015-02-18 07:23:00,20.745,27.1,0,1471,0.00410065919199739,0 +"9637",2015-02-18 07:24:00,20.745,27.1,0,1456,0.00410065919199739,0 +"9638",2015-02-18 07:25:00,20.745,27.05,0,1446,0.00409304361376997,0 +"9639",2015-02-18 07:25:59,20.79,27.1,0,1443,0.00411211322882893,0 +"9640",2015-02-18 07:27:00,20.7,27.1,0,1447.66666666667,0.00408923331117716,0 +"9641",2015-02-18 07:27:59,20.79,27.1,0,1451,0.00411211322882893,0 +"9642",2015-02-18 07:28:59,20.79,27.1,0,1452,0.00411211322882893,0 +"9643",2015-02-18 07:30:00,20.76,27.1,0,1446.75,0.0041044740728723,0 +"9644",2015-02-18 07:31:00,20.79,27.1,0,1455.5,0.00411211322882893,0 +"9645",2015-02-18 07:32:00,20.745,27.1,0,1456,0.00410065919199739,0 +"9646",2015-02-18 07:33:00,20.7,27.1,0,1464.66666666667,0.00408923331117716,0 +"9647",2015-02-18 07:34:00,20.79,27.1,0,1434,0.00411211322882893,0 +"9648",2015-02-18 07:34:59,20.79,27.1,0,1418,0.00411211322882893,0 +"9649",2015-02-18 07:36:00,20.745,27.1,0,1417,0.00410065919199739,0 +"9650",2015-02-18 07:37:00,20.7,27.1,0,1422,0.00408923331117716,0 +"9651",2015-02-18 07:38:00,20.745,27.1,0,1420,0.00410065919199739,0 +"9652",2015-02-18 07:38:59,20.76,27.1333333333333,0,1426.33333333333,0.00410955598227716,0 +"9653",2015-02-18 07:40:00,20.7,27.2,0,1427,0.00410442230430706,0 +"9654",2015-02-18 07:40:59,20.7,27.15,0,1430,0.00409682771562157,0 +"9655",2015-02-18 07:41:59,20.7,27.1,0,1414.5,0.00408923331117716,0 +"9656",2015-02-18 07:43:00,20.745,27.15,0,1414,0.00410827495549355,0 +"9657",2015-02-18 07:44:00,20.7,27.2,0,1413.5,0.00410442230430706,0 +"9658",2015-02-18 07:45:00,20.7,27.2,0,1411,0.00410442230430706,0 +"9659",2015-02-18 07:46:00,20.73,27.2,0,1412.33333333333,0.00411206490026402,0 +"9660",2015-02-18 07:46:59,20.745,27.2,0,1412.5,0.00411589090426523,0 +"9661",2015-02-18 07:47:59,20.745,27.2,0,1410.5,0.00411589090426523,0 +"9662",2015-02-18 07:49:00,20.7,27.2,0,1412,0.00410442230430706,0 +"9663",2015-02-18 07:50:00,20.7,27.15,0,1405,0.00409682771562157,0 +"9664",2015-02-18 07:51:00,20.7,27.2,0,1407,0.00410442230430706,0 +"9665",2015-02-18 07:52:00,20.7,27.2,0,1420.33333333333,0.00410442230430706,0 +"9666",2015-02-18 07:53:00,20.7,27.2,0,1437,0.00410442230430706,0 +"9667",2015-02-18 07:53:59,20.745,27.2,0,1439.66666666667,0.00411589090426523,0 +"9668",2015-02-18 07:54:59,20.79,27.2,0,1443,0.00412738776706512,0 +"9669",2015-02-18 07:56:00,20.7,27.2,0,1437,0.00410442230430706,0 +"9670",2015-02-18 07:57:00,20.7,27.2,0,1421.5,0.00410442230430706,0 +"9671",2015-02-18 07:58:00,20.7,27.2,0,1404,0.00410442230430706,0 +"9672",2015-02-18 07:59:00,20.7,27.2,0,1404.5,0.00410442230430706,0 +"9673",2015-02-18 07:59:59,20.7,27.1666666666667,0,1408.66666666667,0.00409935922471184,0 +"9674",2015-02-18 08:00:59,20.7,27.2,0,1400,0.00410442230430706,0 +"9675",2015-02-18 08:02:00,20.7,27.2,0,1401,0.00410442230430706,0 +"9676",2015-02-18 08:03:00,20.7,27.15,0,1404,0.00409682771562157,0 +"9677",2015-02-18 08:04:00,20.7,27.2,0,1406.5,0.00410442230430706,0 +"9678",2015-02-18 08:05:00,20.7,27.2,0,1406,0.00410442230430706,0 +"9679",2015-02-18 08:06:00,20.7,27.15,0,1413.5,0.00409682771562157,0 +"9680",2015-02-18 08:06:59,20.7,27.15,0,1428,0.00409682771562157,0 +"9681",2015-02-18 08:08:00,20.7,27.2,0,1443,0.00410442230430706,0 +"9682",2015-02-18 08:09:00,20.7,27.2,0,1451.5,0.00410442230430706,0 +"9683",2015-02-18 08:10:00,20.7,27.2,0,1434.5,0.00410442230430706,0 +"9684",2015-02-18 08:10:59,20.7,27.2,0,1429.5,0.00410442230430706,0 +"9685",2015-02-18 08:12:00,20.7,27.2,0,1423,0.00410442230430706,0 +"9686",2015-02-18 08:12:59,20.7,27.2,0,1432.33333333333,0.00410442230430706,0 +"9687",2015-02-18 08:13:59,20.7,27.2,9.33333333333333,1427.66666666667,0.00410442230430706,0 +"9688",2015-02-18 08:15:00,20.7,27.2,14,1430,0.00410442230430706,0 +"9689",2015-02-18 08:16:00,20.7,27.2,14,1430,0.00410442230430706,0 +"9690",2015-02-18 08:17:00,20.7,27.1333333333333,14,1433,0.00409429622700254,0 +"9691",2015-02-18 08:18:00,20.745,27.1,14,1432.25,0.00410065919199739,0 +"9692",2015-02-18 08:19:00,20.7,27.1,14,1434,0.00408923331117716,0 +"9693",2015-02-18 08:19:59,20.79,27.1,14,1426.75,0.00411211322882893,0 +"9694",2015-02-18 08:21:00,20.79,27.1,14,1415.5,0.00411211322882893,0 +"9695",2015-02-18 08:22:00,20.79,27.1,14,1405,0.00411211322882893,0 +"9696",2015-02-18 08:23:00,20.79,27.1,14,1404,0.00411211322882893,0 +"9697",2015-02-18 08:23:59,20.79,27.1,14,1421,0.00411211322882893,0 +"9698",2015-02-18 08:25:00,20.79,27.1,14,1437.75,0.00411211322882893,0 +"9699",2015-02-18 08:25:59,20.79,27,14,1482,0.00409683943582711,0 +"9700",2015-02-18 08:26:59,20.79,27.025,14,1477.25,0.00410065781421483,0 +"9701",2015-02-18 08:28:00,20.79,27,14,1477.66666666667,0.00409683943582711,0 +"9702",2015-02-18 08:29:00,20.79,27,14,1475.25,0.00409683943582711,0 +"9703",2015-02-18 08:30:00,20.79,27,14,1471.25,0.00409683943582711,0 +"9704",2015-02-18 08:31:00,20.8233333333333,27.0333333333333,14,1468,0.00411041208416711,0 +"9705",2015-02-18 08:31:59,20.84,27.025,14,1472.5,0.00411338183772193,0 +"9706",2015-02-18 08:32:59,20.815,26.9725,14,1461.25,0.00409898442475371,0 +"9707",2015-02-18 08:34:00,20.84,27,14,1438,0.00410955153343404,0 +"9708",2015-02-18 08:35:00,20.8233333333333,27.0333333333333,14,1444,0.00411041208416711,0 +"9709",2015-02-18 08:36:00,20.89,27.05,14,1433.25,0.00412998298915598,0 +"9710",2015-02-18 08:37:00,20.8566666666667,27.0666666666667,14,1430,0.00412402149464584,0 +"9711",2015-02-18 08:38:00,20.84,27.0225,14,1427.5,0.00411299880518423,0 +"9712",2015-02-18 08:38:59,20.84,27,14,1416.25,0.00410955153343404,0 +"9713",2015-02-18 08:39:59,20.89,27.0333333333333,14,1422,0.00412742144360835,0 +"9714",2015-02-18 08:41:00,20.89,27,14,1427,0.00412229841538944,0 +"9715",2015-02-18 08:42:00,20.89,27,14,1402,0.00412229841538944,0 +"9716",2015-02-18 08:43:00,20.865,26.9725,14,1404,0.00411170076791517,0 +"9717",2015-02-18 08:44:00,20.89,26.945,14,1406.5,0.00411384560210811,0 +"9718",2015-02-18 08:44:59,20.89,27,14,1410,0.00412229841538944,0 +"9719",2015-02-18 08:45:59,20.8233333333333,26.9266666666667,14,1414,0.00409408668890024,0 +"9720",2015-02-18 08:47:00,20.79,26.89,14,1412.5,0.00408003912420573,0 +"9721",2015-02-18 08:48:00,20.815,26.9175,14,1418.5,0.00409057116041118,0 +"9722",2015-02-18 08:49:00,20.84,26.945,10.5,1428,0.00410112502896133,0 +"9723",2015-02-18 08:50:00,20.79,26.89,7,1472.4,0.00408003912420573,0 +"9724",2015-02-18 08:51:00,20.8233333333333,26.9266666666667,9.33333333333333,1482.33333333333,0.00409408668890024,0 +"9725",2015-02-18 08:51:59,20.89,27,4.66666666666667,1492,0.00412229841538944,0 +"9726",2015-02-18 08:53:00,20.865,26.945,7,1469,0.00410748097147587,0 +"9727",2015-02-18 08:54:00,20.84,26.895,7,1463.5,0.00409346476717158,0 +"9728",2015-02-18 08:55:00,20.815,26.815,7,1471.75,0.0040748924983746,0 +"9729",2015-02-18 08:55:59,20.865,26.865,7,1500.25,0.0040952055234278,0 +"9730",2015-02-18 08:57:00,20.8233333333333,26.8933333333333,9.33333333333333,1514,0.00408898517747052,0 +"9731",2015-02-18 08:57:59,20.815,26.8925,13.5,1499.25,0.0040867470240924,0 +"9732",2015-02-18 08:58:59,20.8566666666667,26.89,20.6666666666667,1485.66666666667,0.00409692632044227,0 +"9733",2015-02-18 09:00:00,20.865,26.865,17,1476.25,0.0040952055234278,0 +"9734",2015-02-18 09:01:00,20.865,26.865,12,1462.5,0.0040952055234278,0 +"9735",2015-02-18 09:02:00,20.84,26.84,7,1452.5,0.00408503869569835,0 +"9736",2015-02-18 09:03:00,20.815,26.815,7,1448,0.0040748924983746,0 +"9737",2015-02-18 09:04:00,20.8233333333333,26.8233333333333,13.3333333333333,1448.66666666667,0.00407827227407053,0 +"9738",2015-02-18 09:04:59,20.815,26.815,11.5,1443.25,0.0040748924983746,0 +"9739",2015-02-18 09:06:00,20.79,26.79,10,1450.5,0.00406476689601859,0 +"9740",2015-02-18 09:07:00,20.84,26.84,12,1446.5,0.00408503869569835,0 +"9741",2015-02-18 09:08:00,20.79,26.79,14,1444.66666666667,0.00406476689601859,0 +"9742",2015-02-18 09:08:59,20.79,26.7675,10,1455,0.00406133074735774,0 +"9743",2015-02-18 09:10:00,20.79,26.745,50.75,1463.75,0.0040578946364152,0 +"9744",2015-02-18 09:10:59,20.79,27.1225,296,1467,0.00411554993495501,1 +"9745",2015-02-18 09:11:59,20.79,27.03,419,1488,0.00410142149548129,1 +"9746",2015-02-18 09:13:00,20.79,27.2966666666667,429,1486,0.00414215386246472,1 +"9747",2015-02-18 09:14:00,20.815,27.4175,430.75,1511.75,0.00416706369826767,1 +"9748",2015-02-18 09:15:00,20.815,27.7175,429.75,1505.25,0.00421296819328694,1 +"9749",2015-02-18 09:16:00,20.865,27.745,423.5,1514.5,0.00423026193160229,1 +"9750",2015-02-18 09:16:59,20.89,27.745,423.5,1521.5,0.00423681810140671,1 +"9751",2015-02-18 09:17:59,20.89,28.0225,418.75,1632,0.0042794854718673,1 +"9752",2015-02-18 09:19:00,21,28.1,409,1864,0.00432073200293677,1 diff --git a/Demos/occupancy_data/datatraining.txt b/Demos/occupancy_data/datatraining.txt new file mode 100644 index 0000000..2ec954a --- /dev/null +++ b/Demos/occupancy_data/datatraining.txt @@ -0,0 +1,8144 @@ +"date","Temperature","Humidity","Light","CO2","HumidityRatio","Occupancy" +"1","2015-02-04 17:51:00",23.18,27.272,426,721.25,0.00479298817650529,1 +"2","2015-02-04 17:51:59",23.15,27.2675,429.5,714,0.00478344094931065,1 +"3","2015-02-04 17:53:00",23.15,27.245,426,713.5,0.00477946352442199,1 +"4","2015-02-04 17:54:00",23.15,27.2,426,708.25,0.00477150882608175,1 +"5","2015-02-04 17:55:00",23.1,27.2,426,704.5,0.00475699293331518,1 +"6","2015-02-04 17:55:59",23.1,27.2,419,701,0.00475699293331518,1 +"7","2015-02-04 17:57:00",23.1,27.2,419,701.666666666667,0.00475699293331518,1 +"8","2015-02-04 17:57:59",23.1,27.2,419,699,0.00475699293331518,1 +"9","2015-02-04 17:58:59",23.1,27.2,419,689.333333333333,0.00475699293331518,1 +"10","2015-02-04 18:00:00",23.075,27.175,419,688,0.00474535071966655,1 +"11","2015-02-04 18:01:00",23.075,27.15,419,690.25,0.00474095189694268,1 +"12","2015-02-04 18:02:00",23.1,27.1,419,691,0.00473937073052061,1 +"13","2015-02-04 18:03:00",23.1,27.1666666666667,419,683.5,0.00475111875560951,1 +"14","2015-02-04 18:04:00",23.05,27.15,419,687.5,0.0047337317970825,1 +"15","2015-02-04 18:04:59",23,27.125,419,686,0.00471494214590473,1 +"16","2015-02-04 18:06:00",23,27.125,418.5,680.5,0.00471494214590473,1 +"17","2015-02-04 18:07:00",23,27.2,0,681.5,0.00472807794966877,0 +"18","2015-02-04 18:08:00",22.945,27.29,0,685,0.00472795137178073,0 +"19","2015-02-04 18:08:59",22.945,27.39,0,685,0.0047454083970941,0 +"20","2015-02-04 18:10:00",22.89,27.39,0,689,0.00472950615591001,0 +"21","2015-02-04 18:10:59",22.89,27.39,0,689.5,0.00472950615591001,0 +"22","2015-02-04 18:11:59",22.89,27.39,0,689,0.00472950615591001,0 +"23","2015-02-04 18:13:00",22.89,27.445,0,691,0.00473907551474663,0 +"24","2015-02-04 18:14:00",22.89,27.5,0,688,0.00474864516581148,0 +"25","2015-02-04 18:15:00",22.89,27.5,0,689.5,0.00474864516581148,0 +"26","2015-02-04 18:16:00",22.79,27.445,0,689,0.00471022404680625,0 +"27","2015-02-04 18:16:59",22.79,27.5,0,685.666666666667,0.00471973499914952,0 +"28","2015-02-04 18:17:59",22.79,27.5,0,687,0.00471973499914952,0 +"29","2015-02-04 18:19:00",22.79,27.5,0,688,0.00471973499914952,0 +"30","2015-02-04 18:20:00",22.745,27.5,0,670,0.0047067761580489,0 +"31","2015-02-04 18:21:00",22.7,27.4633333333333,0,668.666666666667,0.00468754308384392,0 +"32","2015-02-04 18:22:00",22.7,27.5,0,670,0.00469384871410812,0 +"33","2015-02-04 18:23:00",22.7,27.5,0,667,0.00469384871410812,0 +"34","2015-02-04 18:23:59",22.6666666666667,27.4266666666667,0,664.5,0.00467170776461751,0 +"35","2015-02-04 18:24:59",22.7,27.6,0,670,0.00471104653252311,0 +"36","2015-02-04 18:26:00",22.6,27.4266666666667,0,670.333333333333,0.00465269945869772,0 +"37","2015-02-04 18:27:00",22.6,27.39,0,672,0.0046464328065348,0 +"38","2015-02-04 18:28:00",22.6,27.3566666666667,0,658,0.00464073595878431,0 +"39","2015-02-04 18:29:00",22.6,27.445,0,660.5,0.00465583283178072,0 +"40","2015-02-04 18:29:59",22.6,27.4266666666667,0,658,0.00465269945869772,0 +"41","2015-02-04 18:30:59",22.6,27.445,0,655,0.00465583283178072,0 +"42","2015-02-04 18:32:00",22.6,27.445,0,654.25,0.00465583283178072,0 +"43","2015-02-04 18:33:00",22.6,27.39,0,648,0.0046464328065348,0 +"44","2015-02-04 18:34:00",22.5,27.3233333333333,0,648.666666666667,0.00460676320297832,0 +"45","2015-02-04 18:35:00",22.5,27.445,0,646,0.00462742903214501,0 +"46","2015-02-04 18:36:00",22.5,27.5,0,646,0.00463677156669758,0 +"47","2015-02-04 18:36:59",22.5,27.445,0,641.5,0.00462742903214501,0 +"48","2015-02-04 18:38:00",22.39,27.29,0,639,0.00457021208799111,0 +"49","2015-02-04 18:39:00",22.5,27.5,0,640,0.00463677156669758,0 +"50","2015-02-04 18:40:00",22.39,27.34,0,630.5,0.00457864714513976,0 +"51","2015-02-04 18:40:59",22.39,27.3566666666667,0,629.333333333333,0.0045814588813251,0 +"52","2015-02-04 18:42:00",22.39,27.5,0,632,0.00460564085426059,0 +"53","2015-02-04 18:42:59",22.39,27.5,0,636.5,0.00460564085426059,0 +"54","2015-02-04 18:43:59",22.39,27.5,0,627.5,0.00460564085426059,0 +"55","2015-02-04 18:45:00",22.39,27.39,0,626,0.0045870824294015,0 +"56","2015-02-04 18:46:00",22.39,27.5,0,625.5,0.00460564085426059,0 +"57","2015-02-04 18:47:00",22.34,27.39,0,623.5,0.00457305034947982,0 +"58","2015-02-04 18:48:00",22.39,27.4633333333333,0,624.666666666667,0.00459945459049356,0 +"59","2015-02-04 18:49:00",22.39,27.39,0,622,0.0045870824294015,0 +"60","2015-02-04 18:49:59",22.29,27.39,0,621,0.00455905614852278,0 +"61","2015-02-04 18:51:00",22.34,27.39,0,626.5,0.00457305034947982,0 +"62","2015-02-04 18:52:00",22.29,27.39,0,622,0.00455905614852278,0 +"63","2015-02-04 18:53:00",22.39,27.39,0,620,0.0045870824294015,0 +"64","2015-02-04 18:53:59",22.29,27.39,0,621.5,0.00455905614852278,0 +"65","2015-02-04 18:55:00",22.29,27.3566666666667,0,616.333333333333,0.00455346720904263,0 +"66","2015-02-04 18:55:59",22.29,27.34,0,609,0.00455067277669262,0 +"67","2015-02-04 18:56:59",22.29,27.39,0,614,0.00455905614852278,0 +"68","2015-02-04 18:58:00",22.29,27.34,0,613.5,0.00455067277669262,0 +"69","2015-02-04 18:59:00",22.29,27.34,0,611,0.00455067277669262,0 +"70","2015-02-04 19:00:00",22.29,27.39,0,612,0.00455905614852278,0 +"71","2015-02-04 19:01:00",22.29,27.29,0,608,0.00454228962919881,0 +"72","2015-02-04 19:01:59",22.29,27.29,0,605.5,0.00454228962919881,0 +"73","2015-02-04 19:02:59",22.2675,27.315,0,608.5,0.00454021358023024,0 +"74","2015-02-04 19:04:00",22.2,27.29,0,608.5,0.00451728819349999,0 +"75","2015-02-04 19:05:00",22.245,27.29,0,602.5,0.00452977369585959,0 +"76","2015-02-04 19:06:00",22.2,27.29,0,598,0.00451728819349999,0 +"77","2015-02-04 19:07:00",22.2,27.29,0,595,0.00451728819349999,0 +"78","2015-02-04 19:08:00",22.2,27.29,0,591,0.00451728819349999,0 +"79","2015-02-04 19:08:59",22.245,27.245,0,591,0.00452224999364749,0 +"80","2015-02-04 19:09:59",22.2,27.2,0,595,0.00450228274276464,0 +"81","2015-02-04 19:11:00",22.2,27.29,0,594.333333333333,0.00451728819349999,0 +"82","2015-02-04 19:12:00",22.2,27.29,0,593.5,0.00451728819349999,0 +"83","2015-02-04 19:13:00",22.2,27.29,0,592,0.00451728819349999,0 +"84","2015-02-04 19:14:00",22.15,27.245,0,586.5,0.0044959713579516,0 +"85","2015-02-04 19:14:59",22.2,27.2,0,586,0.00450228274276464,0 +"86","2015-02-04 19:15:59",22.15,27.245,0,586,0.0044959713579516,0 +"87","2015-02-04 19:17:00",22.2,27.245,0,584.5,0.00450978537828394,0 +"88","2015-02-04 19:18:00",22.1,27.245,0,584.5,0.00448219467655486,0 +"89","2015-02-04 19:19:00",22.1,27.2,0,585.5,0.00447473826972372,0 +"90","2015-02-04 19:20:00",22.1333333333333,27.2,0,584.666666666667,0.00448390319821458,0 +"91","2015-02-04 19:21:00",22.2,27.2,0,577,0.00450228274276464,0 +"92","2015-02-04 19:21:59",22.1,27.2,0,580,0.00447473826972372,0 +"93","2015-02-04 19:23:00",22.125,27.2,0,582,0.00448161041517148,0 +"94","2015-02-04 19:24:00",22.2,27.2,0,580,0.00450228274276464,0 +"95","2015-02-04 19:25:00",22.1,27.15,0,578,0.00446645358141236,0 +"96","2015-02-04 19:25:59",22.1,27.2,0,576.5,0.00447473826972372,0 +"97","2015-02-04 19:27:00",22.1,27.2,0,580,0.00447473826972372,0 +"98","2015-02-04 19:27:59",22.1,27.2,0,572.5,0.00447473826972372,0 +"99","2015-02-04 19:28:59",22.1,27.2,0,567,0.00447473826972372,0 +"100","2015-02-04 19:30:00",22.1,27.2,0,568,0.00447473826972372,0 +"101","2015-02-04 19:31:00",22.1,27.2,0,574.5,0.00447473826972372,0 +"102","2015-02-04 19:32:00",22.1,27.2,0,564.333333333333,0.00447473826972372,0 +"103","2015-02-04 19:33:00",22.1,27.2,0,563,0.00447473826972372,0 +"104","2015-02-04 19:34:00",22.1,27.15,0,564.5,0.00446645358141236,0 +"105","2015-02-04 19:34:59",22.0666666666667,27.1666666666667,0,566.333333333333,0.00446007809167045,0 +"106","2015-02-04 19:36:00",22.1,27.1,0,562,0.00445816911221647,0 +"107","2015-02-04 19:37:00",22,27.1,0,565.5,0.00443087555124918,0 +"108","2015-02-04 19:38:00",22,27.1,0,570,0.00443087555124918,0 +"109","2015-02-04 19:38:59",22.05,27.15,0,562,0.00445276274636235,0 +"110","2015-02-04 19:40:00",22,27.1,0,560,0.00443087555124918,0 +"111","2015-02-04 19:40:59",22,27.1,0,558,0.00443087555124918,0 +"112","2015-02-04 19:41:59",22,27.1,0,556,0.00443087555124918,0 +"113","2015-02-04 19:43:00",22,27.1,0,557,0.00443087555124918,0 +"114","2015-02-04 19:44:00",21.9175,27.1,0,556.5,0.00440846943162748,0 +"115","2015-02-04 19:45:00",21.945,27.1,0,557.5,0.00441592700761485,0 +"116","2015-02-04 19:46:00",21.9266666666667,27.1,0,555,0.00441095405497767,0 +"117","2015-02-04 19:46:59",21.89,27.1,0,555,0.00440102296708593,0 +"118","2015-02-04 19:47:59",21.89,27.1,0,553,0.00440102296708593,0 +"119","2015-02-04 19:49:00",21.89,27.1,0,549.5,0.00440102296708593,0 +"120","2015-02-04 19:50:00",21.89,27.1,0,548.5,0.00440102296708593,0 +"121","2015-02-04 19:51:00",21.89,27.1,0,551.5,0.00440102296708593,0 +"122","2015-02-04 19:52:00",21.89,27.1,0,548.5,0.00440102296708593,0 +"123","2015-02-04 19:53:00",21.89,27.1,0,548,0.00440102296708593,0 +"124","2015-02-04 19:53:59",21.89,27.1,0,547.5,0.00440102296708593,0 +"125","2015-02-04 19:54:59",21.89,27.1,0,553,0.00440102296708593,0 +"126","2015-02-04 19:56:00",21.84,27.1,0,547.5,0.00438751236133436,0 +"127","2015-02-04 19:57:00",21.8566666666667,27.1,0,548.666666666667,0.00439201182580606,0 +"128","2015-02-04 19:58:00",21.79,27.1,0,540,0.00437403835445405,0 +"129","2015-02-04 19:59:00",21.79,27.1,0,538,0.00437403835445405,0 +"130","2015-02-04 19:59:59",21.79,27.1,0,542,0.00437403835445405,0 +"131","2015-02-04 20:00:59",21.79,27.1,0,542,0.00437403835445405,0 +"132","2015-02-04 20:02:00",21.79,27.1,0,538,0.00437403835445405,0 +"133","2015-02-04 20:03:00",21.79,27.1,0,537.666666666667,0.00437403835445405,0 +"134","2015-02-04 20:04:00",21.79,27.1,0,537.5,0.00437403835445405,0 +"135","2015-02-04 20:05:00",21.79,27.1,0,536,0.00437403835445405,0 +"136","2015-02-04 20:06:00",21.745,27.1,0,534.5,0.00436194296945302,0 +"137","2015-02-04 20:06:59",21.7,27.1,0,532.5,0.00434987709774486,0 +"138","2015-02-04 20:08:00",21.76,27.1,0,530,0.0043659714821212,0 +"139","2015-02-04 20:09:00",21.745,27.05,0,529.5,0.00435383877122501,0 +"140","2015-02-04 20:10:00",21.79,27.05,0,531,0.00436591152717108,0 +"141","2015-02-04 20:10:59",21.73,27,0,533.333333333333,0.00434172461000499,0 +"142","2015-02-04 20:12:00",21.745,27,0,531,0.004345734782707,0 +"143","2015-02-04 20:12:59",21.745,27,0,529,0.004345734782707,0 +"144","2015-02-04 20:13:59",21.745,27,0,528.5,0.004345734782707,0 +"145","2015-02-04 20:15:00",21.7,27,0,525,0.00433371405578809,0 +"146","2015-02-04 20:16:00",21.7,27,0,528.5,0.00433371405578809,0 +"147","2015-02-04 20:17:00",21.7,27,0,530.5,0.00433371405578809,0 +"148","2015-02-04 20:18:00",21.7,26.89,0,528,0.00431593567308493,0 +"149","2015-02-04 20:19:00",21.7,26.89,0,526,0.00431593567308493,0 +"150","2015-02-04 20:19:59",21.7,26.89,0,530,0.00431593567308493,0 +"151","2015-02-04 20:21:00",21.7,26.89,0,533.333333333333,0.00431593567308493,0 +"152","2015-02-04 20:22:00",21.7,26.89,0,529,0.00431593567308493,0 +"153","2015-02-04 20:23:00",21.7,26.89,0,528,0.00431593567308493,0 +"154","2015-02-04 20:23:59",21.7,26.89,0,526,0.00431593567308493,0 +"155","2015-02-04 20:25:00",21.7,26.89,0,526,0.00431593567308493,0 +"156","2015-02-04 20:25:59",21.7,26.79,0,521,0.00429977438278406,0 +"157","2015-02-04 20:26:59",21.7,26.79,0,518,0.00429977438278406,0 +"158","2015-02-04 20:28:00",21.7,26.79,0,515.5,0.00429977438278406,0 +"159","2015-02-04 20:29:00",21.7,26.79,0,520,0.00429977438278406,0 +"160","2015-02-04 20:30:00",21.7,26.7675,0,523.5,0.00429613820740729,0 +"161","2015-02-04 20:31:00",21.7,26.79,0,525.5,0.00429977438278406,0 +"162","2015-02-04 20:31:59",21.7,26.79,0,525.5,0.00429977438278406,0 +"163","2015-02-04 20:32:59",21.7,26.79,0,514,0.00429977438278406,0 +"164","2015-02-04 20:34:00",21.7,26.7,0,518,0.00428522993460374,0 +"165","2015-02-04 20:35:00",21.7,26.7,0,518,0.00428522993460374,0 +"166","2015-02-04 20:36:00",21.7,26.7,0,520,0.00428522993460374,0 +"167","2015-02-04 20:37:00",21.6,26.7,0,521,0.00425892186208795,0 +"168","2015-02-04 20:38:00",21.6,26.6,0,518,0.00424286203685278,0 +"169","2015-02-04 20:38:59",21.6,26.65,0,517,0.00425089184650924,0 +"170","2015-02-04 20:39:59",21.6,26.6,0,511.5,0.00424286203685278,0 +"171","2015-02-04 20:41:00",21.65,26.65,0,514,0.00426400308494511,0 +"172","2015-02-04 20:42:00",21.6,26.55,0,515.5,0.00423483243311065,0 +"173","2015-02-04 20:43:00",21.6,26.5,0,517,0.00422680303527493,0 +"174","2015-02-04 20:44:00",21.6,26.5,0,515,0.00422680303527493,0 +"175","2015-02-04 20:44:59",21.6,26.5,0,512,0.00422680303527493,0 +"176","2015-02-04 20:45:59",21.6,26.5,0,515,0.00422680303527493,0 +"177","2015-02-04 20:47:00",21.65,26.55,0,511,0.00424789380271014,0 +"178","2015-02-04 20:48:00",21.6,26.5,0,514,0.00422680303527493,0 +"179","2015-02-04 20:49:00",21.6,26.445,0,508,0.00421797093546809,0 +"180","2015-02-04 20:50:00",21.6,26.4725,0,509.75,0.00422238695423002,0 +"181","2015-02-04 20:51:00",21.6,26.445,0,508.75,0.00421797093546809,0 +"182","2015-02-04 20:51:59",21.6,26.445,0,508.5,0.00421797093546809,0 +"183","2015-02-04 20:53:00",21.6,26.39,0,507,0.00420913908478788,0 +"184","2015-02-04 20:54:00",21.6,26.39,0,507,0.00420913908478788,0 +"185","2015-02-04 20:55:00",21.6,26.39,0,503.5,0.00420913908478788,0 +"186","2015-02-04 20:55:59",21.6,26.39,0,504,0.00420913908478788,0 +"187","2015-02-04 20:57:00",21.6,26.39,0,504,0.00420913908478788,0 +"188","2015-02-04 20:57:59",21.575,26.315,0,500.5,0.0041906371261489,0 +"189","2015-02-04 20:58:59",21.6,26.29,0,500,0.00419308181268417,0 +"190","2015-02-04 21:00:00",21.6,26.29,0,503.5,0.00419308181268417,0 +"191","2015-02-04 21:01:00",21.55,26.245,0,503,0.00417298202219627,0 +"192","2015-02-04 21:02:00",21.55,26.245,0,502.5,0.00417298202219627,0 +"193","2015-02-04 21:03:00",21.5,26.2,0,502,0.00415296201038409,0 +"194","2015-02-04 21:04:00",21.5666666666667,26.2,0,502,0.00417005914917235,0 +"195","2015-02-04 21:04:59",21.5,26.2,0,502.5,0.00415296201038409,0 +"196","2015-02-04 21:06:00",21.5,26.2,0,497,0.00415296201038409,0 +"197","2015-02-04 21:07:00",21.5,26.15,0,501.5,0.00414498369514183,0 +"198","2015-02-04 21:08:00",21.5,26.15,0,504,0.00414498369514183,0 +"199","2015-02-04 21:08:59",21.5,26.1,0,501,0.00413700558321316,0 +"200","2015-02-04 21:10:00",21.5,26.1,0,493.75,0.00413700558321316,0 +"201","2015-02-04 21:10:59",21.5,26.1,0,500,0.00413700558321316,0 +"202","2015-02-04 21:11:59",21.5,26.1,0,504.5,0.00413700558321316,0 +"203","2015-02-04 21:13:00",21.5,26.05,0,504,0.00412902767459031,0 +"204","2015-02-04 21:14:00",21.5,26.1,0,501,0.00413700558321316,0 +"205","2015-02-04 21:15:00",21.5,26,0,499,0.00412104996926551,0 +"206","2015-02-04 21:16:00",21.5,26,0,502,0.00412104996926551,0 +"207","2015-02-04 21:16:59",21.5,26,0,503.5,0.00412104996926551,0 +"208","2015-02-04 21:17:59",21.5,26,0,500.666666666667,0.00412104996926551,0 +"209","2015-02-04 21:19:00",21.5,26,0,493,0.00412104996926551,0 +"210","2015-02-04 21:20:00",21.5,26,0,492.5,0.00412104996926551,0 +"211","2015-02-04 21:21:00",21.5,26,0,493,0.00412104996926551,0 +"212","2015-02-04 21:22:00",21.5,25.89,0,495.5,0.00410349973312177,0 +"213","2015-02-04 21:23:00",21.5,26,0,492.666666666667,0.00412104996926551,0 +"214","2015-02-04 21:23:59",21.5,26,0,490,0.00412104996926551,0 +"215","2015-02-04 21:24:59",21.5,25.9266666666667,0,493,0.00410934970251646,0 +"216","2015-02-04 21:26:00",21.5,25.89,0,494.666666666667,0.00410349973312177,0 +"217","2015-02-04 21:27:00",21.5,25.89,0,496,0.00410349973312177,0 +"218","2015-02-04 21:28:00",21.5,25.89,0,491,0.00410349973312177,0 +"219","2015-02-04 21:29:00",21.5,25.84,0,490.5,0.0040955226782985,0 +"220","2015-02-04 21:29:59",21.5,25.84,0,490,0.0040955226782985,0 +"221","2015-02-04 21:30:59",21.5,25.89,0,491,0.00410349973312177,0 +"222","2015-02-04 21:32:00",21.5,25.89,0,491.666666666667,0.00410349973312177,0 +"223","2015-02-04 21:33:00",21.5,25.89,0,493.5,0.00410349973312177,0 +"224","2015-02-04 21:34:00",21.4725,25.865,0,493.75,0.00409256776950153,0 +"225","2015-02-04 21:35:00",21.5,25.84,0,490,0.0040955226782985,0 +"226","2015-02-04 21:36:00",21.5,25.79,0,488,0.00408754582674064,0 +"227","2015-02-04 21:36:59",21.5,25.79,0,490,0.00408754582674064,0 +"228","2015-02-04 21:38:00",21.5,25.79,0,487,0.00408754582674064,0 +"229","2015-02-04 21:39:00",21.445,25.745,0,492.5,0.00406655560714929,0 +"230","2015-02-04 21:40:00",21.445,25.745,0,493.5,0.00406655560714929,0 +"231","2015-02-04 21:40:59",21.4633333333333,25.76,0,493.333333333333,0.00407354230391887,0 +"232","2015-02-04 21:42:00",21.445,25.745,0,488,0.00406655560714929,0 +"233","2015-02-04 21:42:59",21.5,25.79,0,487.5,0.00408754582674064,0 +"234","2015-02-04 21:43:59",21.4266666666667,25.73,0,485.333333333333,0.00405957893706384,0 +"235","2015-02-04 21:45:00",21.39,25.7,0,484,0.00404565562779471,0 +"236","2015-02-04 21:46:00",21.39,25.7,0,489,0.00404565562779471,0 +"237","2015-02-04 21:47:00",21.445,25.745,0,488,0.00406655560714929,0 +"238","2015-02-04 21:48:00",21.5,25.79,0,493,0.00408754582674064,0 +"239","2015-02-04 21:49:00",21.39,25.7,0,491,0.00404565562779471,0 +"240","2015-02-04 21:49:59",21.445,25.745,0,488,0.00406655560714929,0 +"241","2015-02-04 21:51:00",21.445,25.745,0,487.25,0.00406655560714929,0 +"242","2015-02-04 21:52:00",21.39,25.7,0,489,0.00404565562779471,0 +"243","2015-02-04 21:53:00",21.5,25.79,0,489,0.00408754582674064,0 +"244","2015-02-04 21:53:59",21.39,25.7,0,486,0.00404565562779471,0 +"245","2015-02-04 21:55:00",21.4266666666667,25.73,0,484.666666666667,0.00405957893706384,0 +"246","2015-02-04 21:55:59",21.39,25.7,0,485,0.00404565562779471,0 +"247","2015-02-04 21:56:59",21.39,25.7,0,487,0.00404565562779471,0 +"248","2015-02-04 21:58:00",21.39,25.7,0,492,0.00404565562779471,0 +"249","2015-02-04 21:59:00",21.39,25.7,0,490.666666666667,0.00404565562779471,0 +"250","2015-02-04 22:00:00",21.39,25.7,0,488,0.00404565562779471,0 +"251","2015-02-04 22:01:00",21.39,25.7,0,485.5,0.00404565562779471,0 +"252","2015-02-04 22:01:59",21.39,25.7,0,486,0.00404565562779471,0 +"253","2015-02-04 22:02:59",21.39,25.7,0,485.5,0.00404565562779471,0 +"254","2015-02-04 22:04:00",21.39,25.7,0,486,0.00404565562779471,0 +"255","2015-02-04 22:05:00",21.39,25.7,0,480,0.00404565562779471,0 +"256","2015-02-04 22:06:00",21.39,25.7,0,481,0.00404565562779471,0 +"257","2015-02-04 22:07:00",21.39,25.7,0,481.666666666667,0.00404565562779471,0 +"258","2015-02-04 22:08:00",21.39,25.7,0,485.5,0.00404565562779471,0 +"259","2015-02-04 22:08:59",21.39,25.7,0,485,0.00404565562779471,0 +"260","2015-02-04 22:09:59",21.39,25.7,0,473,0.00404565562779471,0 +"261","2015-02-04 22:11:00",21.39,25.7,0,475,0.00404565562779471,0 +"262","2015-02-04 22:12:00",21.39,25.7,0,486,0.00404565562779471,0 +"263","2015-02-04 22:13:00",21.39,25.7,0,481.5,0.00404565562779471,0 +"264","2015-02-04 22:14:00",21.39,25.7,0,483,0.00404565562779471,0 +"265","2015-02-04 22:14:59",21.39,25.7,0,479,0.00404565562779471,0 +"266","2015-02-04 22:15:59",21.39,25.7,0,479,0.00404565562779471,0 +"267","2015-02-04 22:17:00",21.39,25.7,0,479,0.00404565562779471,0 +"268","2015-02-04 22:18:00",21.34,25.7,0,479,0.0040331952510965,0 +"269","2015-02-04 22:19:00",21.39,25.7,0,479,0.00404565562779471,0 +"270","2015-02-04 22:20:00",21.39,25.7,0,477,0.00404565562779471,0 +"271","2015-02-04 22:21:00",21.39,25.7,0,477.5,0.00404565562779471,0 +"272","2015-02-04 22:21:59",21.29,25.7,0,477.5,0.00402076872591321,0 +"273","2015-02-04 22:23:00",21.34,25.7,0,480,0.0040331952510965,0 +"274","2015-02-04 22:24:00",21.29,25.7,0,480,0.00402076872591321,0 +"275","2015-02-04 22:25:00",21.34,25.7,0,482,0.0040331952510965,0 +"276","2015-02-04 22:25:59",21.3233333333333,25.7,0,480.333333333333,0.00402904931868002,0 +"277","2015-02-04 22:27:00",21.34,25.7,0,477.5,0.0040331952510965,0 +"278","2015-02-04 22:27:59",21.29,25.7,0,476,0.00402076872591321,0 +"279","2015-02-04 22:28:59",21.39,25.7,0,479,0.00404565562779471,0 +"280","2015-02-04 22:30:00",21.39,25.7,0,471,0.00404565562779471,0 +"281","2015-02-04 22:31:00",21.29,25.7,0,474,0.00402076872591321,0 +"282","2015-02-04 22:32:00",21.29,25.7,0,477.5,0.00402076872591321,0 +"283","2015-02-04 22:33:00",21.34,25.7,0,476,0.0040331952510965,0 +"284","2015-02-04 22:34:00",21.29,25.7,0,474.25,0.00402076872591321,0 +"285","2015-02-04 22:34:59",21.39,25.7,0,475,0.00404565562779471,0 +"286","2015-02-04 22:36:00",21.29,25.7,0,476.5,0.00402076872591321,0 +"287","2015-02-04 22:37:00",21.34,25.7,0,474.5,0.0040331952510965,0 +"288","2015-02-04 22:38:00",21.29,25.7,0,478,0.00402076872591321,0 +"289","2015-02-04 22:38:59",21.29,25.7,0,475.333333333333,0.00402076872591321,0 +"290","2015-02-04 22:40:00",21.29,25.7,0,477,0.00402076872591321,0 +"291","2015-02-04 22:40:59",21.29,25.7,0,475.5,0.00402076872591321,0 +"292","2015-02-04 22:41:59",21.29,25.7,0,477.5,0.00402076872591321,0 +"293","2015-02-04 22:43:00",21.29,25.7,0,477.5,0.00402076872591321,0 +"294","2015-02-04 22:44:00",21.29,25.7,0,478,0.00402076872591321,0 +"295","2015-02-04 22:45:00",21.29,25.7,0,473.5,0.00402076872591321,0 +"296","2015-02-04 22:46:00",21.29,25.7,0,472.5,0.00402076872591321,0 +"297","2015-02-04 22:46:59",21.29,25.7,0,472,0.00402076872591321,0 +"298","2015-02-04 22:47:59",21.29,25.7,0,469.5,0.00402076872591321,0 +"299","2015-02-04 22:49:00",21.29,25.7,0,466.666666666667,0.00402076872591321,0 +"300","2015-02-04 22:50:00",21.29,25.7,0,467,0.00402076872591321,0 +"301","2015-02-04 22:51:00",21.29,25.7,0,469.5,0.00402076872591321,0 +"302","2015-02-04 22:52:00",21.2,25.6,0,469,0.00398282809773472,0 +"303","2015-02-04 22:53:00",21.29,25.7,0,471,0.00402076872591321,0 +"304","2015-02-04 22:53:59",21.29,25.7,0,469,0.00402076872591321,0 +"305","2015-02-04 22:54:59",21.26,25.6666666666667,0,467.333333333333,0.00400809012841946,0 +"306","2015-02-04 22:56:00",21.245,25.65,0,471.5,0.00400176273769059,0 +"307","2015-02-04 22:57:00",21.23,25.6333333333333,0,471.666666666667,0.00399544327454182,0 +"308","2015-02-04 22:58:00",21.29,25.7,0,475,0.00402076872591321,0 +"309","2015-02-04 22:59:00",21.2,25.6,0,471,0.00398282809773472,0 +"310","2015-02-04 22:59:59",21.2,25.6,0,471,0.00398282809773472,0 +"311","2015-02-04 23:00:59",21.245,25.65,0,471,0.00400176273769059,0 +"312","2015-02-04 23:02:00",21.245,25.65,0,474.5,0.00400176273769059,0 +"313","2015-02-04 23:03:00",21.2,25.6,0,475.5,0.00398282809773472,0 +"314","2015-02-04 23:04:00",21.2,25.6,0,474,0.00398282809773472,0 +"315","2015-02-04 23:05:00",21.2,25.6,0,469,0.00398282809773472,0 +"316","2015-02-04 23:06:00",21.2,25.6,0,474,0.00398282809773472,0 +"317","2015-02-04 23:06:59",21.2,25.6,0,474,0.00398282809773472,0 +"318","2015-02-04 23:08:00",21.2,25.6,0,468.5,0.00398282809773472,0 +"319","2015-02-04 23:09:00",21.2,25.6,0,469.5,0.00398282809773472,0 +"320","2015-02-04 23:10:00",21.2,25.6,0,472.5,0.00398282809773472,0 +"321","2015-02-04 23:10:59",21.2,25.6,0,467.5,0.00398282809773472,0 +"322","2015-02-04 23:12:00",21.2,25.6,0,469,0.00398282809773472,0 +"323","2015-02-04 23:12:59",21.2,25.55,0,466.5,0.00397499942379926,0 +"324","2015-02-04 23:13:59",21.2,25.5,0,469.5,0.00396717094567545,0 +"325","2015-02-04 23:15:00",21.2,25.5,0,469,0.00396717094567545,0 +"326","2015-02-04 23:16:00",21.2,25.5,0,467,0.00396717094567545,0 +"327","2015-02-04 23:17:00",21.2,25.5,0,467.333333333333,0.00396717094567545,0 +"328","2015-02-04 23:18:00",21.2,25.5,0,467,0.00396717094567545,0 +"329","2015-02-04 23:19:00",21.2,25.5,0,464.5,0.00396717094567545,0 +"330","2015-02-04 23:19:59",21.2,25.445,0,466,0.00395855984589297,0 +"331","2015-02-04 23:21:00",21.2,25.5,0,473,0.00396717094567545,0 +"332","2015-02-04 23:22:00",21.2,25.39,0,475,0.00394994898302393,0 +"333","2015-02-04 23:23:00",21.2,25.39,0,471,0.00394994898302393,0 +"334","2015-02-04 23:23:59",21.2,25.39,0,470,0.00394994898302393,0 +"335","2015-02-04 23:25:00",21.2,25.39,0,466.25,0.00394994898302393,0 +"336","2015-02-04 23:25:59",21.2,25.39,0,467,0.00394994898302393,0 +"337","2015-02-04 23:26:59",21.2,25.39,0,473,0.00394994898302393,0 +"338","2015-02-04 23:28:00",21.2,25.39,0,468,0.00394994898302393,0 +"339","2015-02-04 23:29:00",21.2,25.39,0,463,0.00394994898302393,0 +"340","2015-02-04 23:30:00",21.2,25.39,0,466,0.00394994898302393,0 +"341","2015-02-04 23:31:00",21.2,25.39,0,467,0.00394994898302393,0 +"342","2015-02-04 23:31:59",21.2,25.29,0,468,0.00393429347565304,0 +"343","2015-02-04 23:32:59",21.2,25.39,0,468,0.00394994898302393,0 +"344","2015-02-04 23:34:00",21.2,25.29,0,468,0.00393429347565304,0 +"345","2015-02-04 23:35:00",21.2,25.34,0,465.5,0.00394212113144808,0 +"346","2015-02-04 23:36:00",21.2,25.39,0,464,0.00394994898302393,0 +"347","2015-02-04 23:37:00",21.2,25.34,0,464.5,0.00394212113144808,0 +"348","2015-02-04 23:38:00",21.2,25.29,0,465.666666666667,0.00393429347565304,0 +"349","2015-02-04 23:38:59",21.2,25.365,0,465.75,0.00394603503276295,0 +"350","2015-02-04 23:39:59",21.2,25.39,0,464,0.00394994898302393,0 +"351","2015-02-04 23:41:00",21.2,25.39,0,467,0.00394994898302393,0 +"352","2015-02-04 23:42:00",21.15,25.39,0,466.5,0.0039377674602206,0 +"353","2015-02-04 23:43:00",21.2,25.39,0,465,0.00394994898302393,0 +"354","2015-02-04 23:44:00",21.2,25.39,0,462,0.00394994898302393,0 +"355","2015-02-04 23:44:59",21.2,25.39,0,459.666666666667,0.00394994898302393,0 +"356","2015-02-04 23:45:59",21.2,25.29,0,458,0.00393429347565304,0 +"357","2015-02-04 23:47:00",21.2,25.34,0,462.5,0.00394212113144808,0 +"358","2015-02-04 23:48:00",21.2,25.29,0,467,0.00393429347565304,0 +"359","2015-02-04 23:49:00",21.2,25.29,0,466.5,0.00393429347565304,0 +"360","2015-02-04 23:50:00",21.2,25.29,0,463,0.00393429347565304,0 +"361","2015-02-04 23:51:00",21.2,25.29,0,465,0.00393429347565304,0 +"362","2015-02-04 23:51:59",21.2,25.29,0,463.25,0.00393429347565304,0 +"363","2015-02-04 23:53:00",21.2,25.29,0,460,0.00393429347565304,0 +"364","2015-02-04 23:54:00",21.2,25.29,0,457,0.00393429347565304,0 +"365","2015-02-04 23:55:00",21.2,25.29,0,456,0.00393429347565304,0 +"366","2015-02-04 23:55:59",21.245,25.245,0,454,0.00393817695145039,0 +"367","2015-02-04 23:57:00",21.23,25.23,0,454,0.00393217865599575,0 +"368","2015-02-04 23:57:59",21.29,25.29,0,458,0.00395621617653094,0 +"369","2015-02-04 23:58:59",21.2,25.2,0,456,0.00392020418856616,0 +"370","2015-02-05 00:00:00",21.245,25.245,0,456.5,0.00393817695145039,0 +"371","2015-02-05 00:01:00",21.245,25.245,0,458.5,0.00393817695145039,0 +"372","2015-02-05 00:02:00",21.26,25.26,0,459.666666666667,0.00394418263158888,0 +"373","2015-02-05 00:03:00",21.245,25.245,0,464,0.00393817695145039,0 +"374","2015-02-05 00:04:00",21.245,25.2,0,465,0.00393111266145068,0 +"375","2015-02-05 00:04:59",21.29,25.2,0,461,0.00394204788657305,0 +"376","2015-02-05 00:06:00",21.245,25.2,0,458.5,0.00393111266145068,0 +"377","2015-02-05 00:07:00",21.29,25.2,0,459,0.00394204788657305,0 +"378","2015-02-05 00:08:00",21.29,25.2,0,451,0.00394204788657305,0 +"379","2015-02-05 00:08:59",21.29,25.2,0,456,0.00394204788657305,0 +"380","2015-02-05 00:10:00",21.29,25.2,0,463,0.00394204788657305,0 +"381","2015-02-05 00:10:59",21.29,25.2,0,461.666666666667,0.00394204788657305,0 +"382","2015-02-05 00:11:59",21.29,25.2,0,458,0.00394204788657305,0 +"383","2015-02-05 00:13:00",21.29,25.2,0,450,0.00394204788657305,0 +"384","2015-02-05 00:14:00",21.29,25.2,0,457,0.00394204788657305,0 +"385","2015-02-05 00:15:00",21.29,25.2,0,456,0.00394204788657305,0 +"386","2015-02-05 00:16:00",21.29,25.2,0,456,0.00394204788657305,0 +"387","2015-02-05 00:16:59",21.29,25.2,0,461,0.00394204788657305,0 +"388","2015-02-05 00:17:59",21.29,25.2,0,463,0.00394204788657305,0 +"389","2015-02-05 00:19:00",21.29,25.2,0,460,0.00394204788657305,0 +"390","2015-02-05 00:20:00",21.29,25.2,0,456,0.00394204788657305,0 +"391","2015-02-05 00:21:00",21.29,25.2,0,454.5,0.00394204788657305,0 +"392","2015-02-05 00:22:00",21.29,25.2,0,448.5,0.00394204788657305,0 +"393","2015-02-05 00:23:00",21.29,25.2,0,453.5,0.00394204788657305,0 +"394","2015-02-05 00:23:59",21.29,25.2,0,454,0.00394204788657305,0 +"395","2015-02-05 00:24:59",21.29,25.2,0,454,0.00394204788657305,0 +"396","2015-02-05 00:26:00",21.29,25.245,0,450.5,0.00394913195137757,0 +"397","2015-02-05 00:27:00",21.29,25.245,0,453,0.00394913195137757,0 +"398","2015-02-05 00:28:00",21.2,25.2,0,457,0.00392020418856616,0 +"399","2015-02-05 00:29:00",21.2,25.2,0,452.5,0.00392020418856616,0 +"400","2015-02-05 00:29:59",21.2,25.2,0,449,0.00392020418856616,0 +"401","2015-02-05 00:30:59",21.2,25.2,0,458.666666666667,0.00392020418856616,0 +"402","2015-02-05 00:32:00",21.2,25.2,0,454.5,0.00392020418856616,0 +"403","2015-02-05 00:33:00",21.2,25.245,0,455.5,0.00392724875282402,0 +"404","2015-02-05 00:34:00",21.2,25.245,0,453.5,0.00392724875282402,0 +"405","2015-02-05 00:35:00",21.2,25.29,0,452,0.00393429347565304,0 +"406","2015-02-05 00:36:00",21.2,25.29,0,451.5,0.00393429347565304,0 +"407","2015-02-05 00:36:59",21.2,25.29,0,451,0.00393429347565304,0 +"408","2015-02-05 00:38:00",21.1666666666667,25.3566666666667,0,450.333333333333,0.00393661649452723,0 +"409","2015-02-05 00:39:00",21.1666666666667,25.39,0,450,0.00394182428230707,0 +"410","2015-02-05 00:40:00",21.15,25.39,0,453.5,0.0039377674602206,0 +"411","2015-02-05 00:40:59",21.1,25.39,0,454,0.00392561907243717,0 +"412","2015-02-05 00:42:00",21.15,25.39,0,452.5,0.0039377674602206,0 +"413","2015-02-05 00:42:59",21.1,25.39,0,454,0.00392561907243717,0 +"414","2015-02-05 00:43:59",21.1,25.39,0,457,0.00392561907243717,0 +"415","2015-02-05 00:45:00",21.1,25.4633333333333,0,450.333333333333,0.00393702911172392,0 +"416","2015-02-05 00:46:00",21.1,25.5,0,451,0.00394273428736449,0 +"417","2015-02-05 00:47:00",21.1,25.5,0,451,0.00394273428736449,0 +"418","2015-02-05 00:48:00",21.05,25.445,0,449,0.00392203465655424,0 +"419","2015-02-05 00:49:00",21.1,25.5,0,449,0.00394273428736449,0 +"420","2015-02-05 00:49:59",21.05,25.445,0,450,0.00392203465655424,0 +"421","2015-02-05 00:51:00",21.05,25.445,0,449,0.00392203465655424,0 +"422","2015-02-05 00:52:00",21.1,25.5,0,445,0.00394273428736449,0 +"423","2015-02-05 00:53:00",21,25.39,0,443,0.00390142139093685,0 +"424","2015-02-05 00:53:59",21.1,25.5,0,446.5,0.00394273428736449,0 +"425","2015-02-05 00:55:00",21.1,25.5,0,446,0.00394273428736449,0 +"426","2015-02-05 00:55:59",21.1,25.5,0,451.5,0.00394273428736449,0 +"427","2015-02-05 00:56:59",21.1,25.39,0,445,0.00392561907243717,0 +"428","2015-02-05 00:58:00",21.1,25.39,0,449,0.00392561907243717,0 +"429","2015-02-05 00:59:00",21.1,25.39,0,451.666666666667,0.00392561907243717,0 +"430","2015-02-05 01:00:00",21.1,25.39,0,452,0.00392561907243717,0 +"431","2015-02-05 01:01:00",21.1,25.39,0,451,0.00392561907243717,0 +"432","2015-02-05 01:01:59",21.05,25.34,0,450,0.00390574856670598,0 +"433","2015-02-05 01:02:59",21.1,25.39,0,450,0.00392561907243717,0 +"434","2015-02-05 01:04:00",21.1,25.39,0,448,0.00392561907243717,0 +"435","2015-02-05 01:05:00",21.1,25.39,0,450.666666666667,0.00392561907243717,0 +"436","2015-02-05 01:06:00",21.1,25.39,0,450,0.00392561907243717,0 +"437","2015-02-05 01:07:00",21.15,25.39,0,446,0.0039377674602206,0 +"438","2015-02-05 01:08:00",21.1,25.39,0,444,0.00392561907243717,0 +"439","2015-02-05 01:08:59",21.125,25.39,0,447.5,0.00393168912931672,0 +"440","2015-02-05 01:09:59",21.1333333333333,25.39,0,443.333333333333,0.00393371431980177,0 +"441","2015-02-05 01:11:00",21.1,25.34,0,443.5,0.00391783973869481,0 +"442","2015-02-05 01:12:00",21.1,25.34,0,444,0.00391783973869481,0 +"443","2015-02-05 01:13:00",21.15,25.34,0,449,0.00392996390106742,0 +"444","2015-02-05 01:14:00",21.2,25.29,0,449.333333333333,0.00393429347565304,0 +"445","2015-02-05 01:14:59",21.15,25.29,0,448,0.00392216053648559,0 +"446","2015-02-05 01:15:59",21.15,25.245,0,449.5,0.00391513767471442,0 +"447","2015-02-05 01:17:00",21.2,25.245,0,450,0.00392724875282402,0 +"448","2015-02-05 01:18:00",21.2,25.2,0,447,0.00392020418856616,0 +"449","2015-02-05 01:19:00",21.2,25.2,0,446,0.00392020418856616,0 +"450","2015-02-05 01:20:00",21.1333333333333,25.2,0,443,0.00390409254176333,0 +"451","2015-02-05 01:21:00",21.1666666666667,25.2,0,444,0.00391214105268426,0 +"452","2015-02-05 01:21:59",21.2,25.2,0,444.5,0.00392020418856616,0 +"453","2015-02-05 01:23:00",21.2,25.2,0,445,0.00392020418856616,0 +"454","2015-02-05 01:24:00",21.2,25.2,0,451,0.00392020418856616,0 +"455","2015-02-05 01:25:00",21.2,25.2,0,450,0.00392020418856616,0 +"456","2015-02-05 01:25:59",21.2,25.2,0,444,0.00392020418856616,0 +"457","2015-02-05 01:27:00",21.2,25.2,0,443,0.00392020418856616,0 +"458","2015-02-05 01:27:59",21.2,25.1,0,438.5,0.00390455016902337,0 +"459","2015-02-05 01:28:59",21.2,25.1,0,441,0.00390455016902337,0 +"460","2015-02-05 01:30:00",21.2,25.1,0,444,0.00390455016902337,0 +"461","2015-02-05 01:31:00",21.2,25.15,0,441.5,0.00391237708091832,0 +"462","2015-02-05 01:32:00",21.2,25.1,0,441,0.00390455016902337,0 +"463","2015-02-05 01:33:00",21.2,25.1,0,439.5,0.00390455016902337,0 +"464","2015-02-05 01:34:00",21.2,25.1,0,441,0.00390455016902337,0 +"465","2015-02-05 01:34:59",21.2,25.1,0,442,0.00390455016902337,0 +"466","2015-02-05 01:36:00",21.2,25.1,0,441,0.00390455016902337,0 +"467","2015-02-05 01:37:00",21.2,25.1,0,436,0.00390455016902337,0 +"468","2015-02-05 01:38:00",21.2,25.1,0,442.5,0.00390455016902337,0 +"469","2015-02-05 01:38:59",21.2,25.1,0,446,0.00390455016902337,0 +"470","2015-02-05 01:40:00",21.2,25.1,0,443,0.00390455016902337,0 +"471","2015-02-05 01:40:59",21.2,25.1,0,437.5,0.00390455016902337,0 +"472","2015-02-05 01:41:59",21.2,25.1,0,440.5,0.00390455016902337,0 +"473","2015-02-05 01:43:00",21.2,25.05,0,439.5,0.00389672345287398,0 +"474","2015-02-05 01:44:00",21.2,25,0,443,0.00388889693246281,0 +"475","2015-02-05 01:45:00",21.2,25,0,443,0.00388889693246281,0 +"476","2015-02-05 01:46:00",21.2,25,0,438.5,0.00388889693246281,0 +"477","2015-02-05 01:46:59",21.2,25,0,438,0.00388889693246281,0 +"478","2015-02-05 01:47:59",21.2,25,0,442.333333333333,0.00388889693246281,0 +"479","2015-02-05 01:49:00",21.2,25,0,448,0.00388889693246281,0 +"480","2015-02-05 01:50:00",21.2,25.1,0,447.5,0.00390455016902337,0 +"481","2015-02-05 01:51:00",21.125,25.1,0,445.75,0.00388650148836853,0 +"482","2015-02-05 01:52:00",21.1,25,0,439,0.00386494539702099,0 +"483","2015-02-05 01:53:00",21.1,25.1,0,440,0.0038805016282998,0 +"484","2015-02-05 01:53:59",21.1,25.1,0,441.5,0.0038805016282998,0 +"485","2015-02-05 01:54:59",21.1,25.0666666666667,0,439,0.00387531613195001,0 +"486","2015-02-05 01:56:00",21.1,25,0,439,0.00386494539702099,0 +"487","2015-02-05 01:57:00",21.1,25.1,0,437.5,0.0038805016282998,0 +"488","2015-02-05 01:58:00",21.05,25.05,0,437.5,0.0038607723400945,0 +"489","2015-02-05 01:59:00",21.1,25.1,0,439.333333333333,0.0038805016282998,0 +"490","2015-02-05 01:59:59",21.1,25.1,0,443,0.0038805016282998,0 +"491","2015-02-05 02:00:59",21,25,0,440.5,0.0038411240057139,0 +"492","2015-02-05 02:02:00",21,25,0,442.333333333333,0.0038411240057139,0 +"493","2015-02-05 02:03:00",21,25,0,440.666666666667,0.0038411240057139,0 +"494","2015-02-05 02:04:00",21,25,0,440,0.0038411240057139,0 +"495","2015-02-05 02:05:00",21,25,0,439,0.0038411240057139,0 +"496","2015-02-05 02:06:00",21,25,0,442,0.0038411240057139,0 +"497","2015-02-05 02:06:59",21,25,0,443.5,0.0038411240057139,0 +"498","2015-02-05 02:08:00",21,25,0,445,0.0038411240057139,0 +"499","2015-02-05 02:09:00",21,25,0,445,0.0038411240057139,0 +"500","2015-02-05 02:10:00",21,25.05,0,442.5,0.00384885379046066,0 +"501","2015-02-05 02:10:59",21,25.1,0,440,0.00385658376615144,0 +"502","2015-02-05 02:12:00",21,25,0,439.5,0.0038411240057139,0 +"503","2015-02-05 02:12:59",21,25,0,438.5,0.0038411240057139,0 +"504","2015-02-05 02:13:59",21,25,0,435,0.0038411240057139,0 +"505","2015-02-05 02:15:00",21,25,0,439.5,0.0038411240057139,0 +"506","2015-02-05 02:16:00",21,25,0,440.5,0.0038411240057139,0 +"507","2015-02-05 02:17:00",21,25,0,439.5,0.0038411240057139,0 +"508","2015-02-05 02:18:00",21,25,0,441,0.0038411240057139,0 +"509","2015-02-05 02:19:00",21,25,0,442,0.0038411240057139,0 +"510","2015-02-05 02:19:59",21,25,0,445,0.0038411240057139,0 +"511","2015-02-05 02:21:00",21,25,0,444,0.0038411240057139,0 +"512","2015-02-05 02:22:00",21,25,0,445,0.0038411240057139,0 +"513","2015-02-05 02:23:00",21,24.89,0,444,0.00382411915135911,0 +"514","2015-02-05 02:23:59",21,24.89,0,443,0.00382411915135911,0 +"515","2015-02-05 02:25:00",21,24.89,0,448,0.00382411915135911,0 +"516","2015-02-05 02:25:59",21.05,24.945,0,443,0.00384448943806112,0 +"517","2015-02-05 02:26:59",21.05,24.945,0,440,0.00384448943806112,0 +"518","2015-02-05 02:28:00",21,24.89,0,440,0.00382411915135911,0 +"519","2015-02-05 02:29:00",21.0333333333333,24.9266666666667,0,441,0.00383768983818085,0 +"520","2015-02-05 02:30:00",21.05,24.945,0,440.5,0.00384448943806112,0 +"521","2015-02-05 02:31:00",21.05,24.945,0,444.5,0.00384448943806112,0 +"522","2015-02-05 02:31:59",21.1,25,0,446,0.00386494539702099,0 +"523","2015-02-05 02:32:59",21.05,24.945,0,442.5,0.00384448943806112,0 +"524","2015-02-05 02:34:00",21,24.89,0,439,0.00382411915135911,0 +"525","2015-02-05 02:35:00",21.1,24.89,0,441,0.00384783443575005,0 +"526","2015-02-05 02:36:00",21.1,24.89,0,438.333333333333,0.00384783443575005,0 +"527","2015-02-05 02:37:00",21.0333333333333,24.89,0,439.5,0.00383200988855104,0 +"528","2015-02-05 02:38:00",21.075,24.9725,0,440.75,0.00385470668973164,0 +"529","2015-02-05 02:38:59",21.0333333333333,24.9266666666667,0,437,0.00383768983818085,0 +"530","2015-02-05 02:39:59",21.1,24.945,0,440.5,0.00385638979943178,0 +"531","2015-02-05 02:41:00",21.1,24.9175,0,442.25,0.00385211208835308,0 +"532","2015-02-05 02:42:00",21.1,24.89,0,435,0.00384783443575005,0 +"533","2015-02-05 02:43:00",21.1,24.89,0,435.5,0.00384783443575005,0 +"534","2015-02-05 02:44:00",21.1,24.89,0,432,0.00384783443575005,0 +"535","2015-02-05 02:44:59",21.1,24.89,0,439.5,0.00384783443575005,0 +"536","2015-02-05 02:45:59",21.05,24.84,0,442.5,0.00382820738326409,0 +"537","2015-02-05 02:47:00",21.1,24.89,0,438.5,0.00384783443575005,0 +"538","2015-02-05 02:48:00",21.05,24.84,0,435.5,0.00382820738326409,0 +"539","2015-02-05 02:49:00",21.0666666666667,24.8566666666667,0,437.333333333333,0.00383474075764093,0 +"540","2015-02-05 02:50:00",21.1,24.89,0,437,0.00384783443575005,0 +"541","2015-02-05 02:51:00",21.0333333333333,24.8233333333333,0,438,0.00382168297154121,0 +"542","2015-02-05 02:51:59",21.025,24.84,0,435,0.00382229465435571,0 +"543","2015-02-05 02:53:00",21,24.79,0,440,0.00380866099472654,0 +"544","2015-02-05 02:54:00",21,24.8233333333333,0,441.333333333333,0.00381381362875361,0 +"545","2015-02-05 02:55:00",21,24.8566666666667,0,435,0.00381896634763043,0 +"546","2015-02-05 02:55:59",21,24.89,0,432,0.00382411915135911,0 +"547","2015-02-05 02:57:00",21,24.89,0,435.5,0.00382411915135911,0 +"548","2015-02-05 02:57:59",21,24.89,0,444,0.00382411915135911,0 +"549","2015-02-05 02:58:59",21,24.84,0,444.5,0.00381638997758567,0 +"550","2015-02-05 03:00:00",21,24.89,0,446,0.00382411915135911,0 +"551","2015-02-05 03:01:00",21,24.89,0,445,0.00382411915135911,0 +"552","2015-02-05 03:02:00",21,24.89,0,438.333333333333,0.00382411915135911,0 +"553","2015-02-05 03:03:00",21,24.89,0,445.5,0.00382411915135911,0 +"554","2015-02-05 03:04:00",21,24.89,0,439,0.00382411915135911,0 +"555","2015-02-05 03:04:59",21,24.89,0,439,0.00382411915135911,0 +"556","2015-02-05 03:06:00",20.945,24.89,0,439.5,0.00381113074815629,0 +"557","2015-02-05 03:07:00",20.9633333333333,24.89,0,443.333333333333,0.00381545588800348,0 +"558","2015-02-05 03:08:00",20.89,24.89,0,443.5,0.00379818125119672,0 +"559","2015-02-05 03:08:59",20.9266666666667,24.89,0,444,0.00380680993122318,0 +"560","2015-02-05 03:10:00",21,24.89,0,447.5,0.00382411915135911,0 +"561","2015-02-05 03:10:59",20.89,24.89,0,445.5,0.00379818125119672,0 +"562","2015-02-05 03:11:59",20.89,24.89,0,443,0.00379818125119672,0 +"563","2015-02-05 03:13:00",20.89,24.89,0,438,0.00379818125119672,0 +"564","2015-02-05 03:14:00",20.89,24.89,0,428,0.00379818125119672,0 +"565","2015-02-05 03:15:00",20.89,24.89,0,431,0.00379818125119672,0 +"566","2015-02-05 03:16:00",20.89,24.89,0,441,0.00379818125119672,0 +"567","2015-02-05 03:16:59",20.89,24.89,0,446,0.00379818125119672,0 +"568","2015-02-05 03:17:59",20.89,24.89,0,447,0.00379818125119672,0 +"569","2015-02-05 03:19:00",20.89,24.89,0,439,0.00379818125119672,0 +"570","2015-02-05 03:20:00",20.89,24.89,0,438.333333333333,0.00379818125119672,0 +"571","2015-02-05 03:21:00",20.89,24.89,0,442,0.00379818125119672,0 +"572","2015-02-05 03:22:00",20.9266666666667,24.79,0,443.333333333333,0.00379142216717855,0 +"573","2015-02-05 03:23:00",20.89,24.79,0,448,0.00378282857655485,0 +"574","2015-02-05 03:23:59",20.89,24.79,0,444.5,0.00378282857655485,0 +"575","2015-02-05 03:24:59",20.9266666666667,24.79,0,443.333333333333,0.00379142216717855,0 +"576","2015-02-05 03:26:00",20.945,24.79,0,445,0.0037957254127113,0 +"577","2015-02-05 03:27:00",21,24.7,0,445,0.00379474930666158,0 +"578","2015-02-05 03:28:00",21,24.7,0,443.5,0.00379474930666158,0 +"579","2015-02-05 03:29:00",21,24.7,0,439,0.00379474930666158,0 +"580","2015-02-05 03:29:59",21,24.7,0,441.5,0.00379474930666158,0 +"581","2015-02-05 03:30:59",21,24.6333333333333,0,441.333333333333,0.0037844447512991,0 +"582","2015-02-05 03:32:00",21,24.6,0,441,0.00377929260087562,0 +"583","2015-02-05 03:33:00",21,24.6,0,441,0.00377929260087562,0 +"584","2015-02-05 03:34:00",21,24.6,0,440,0.00377929260087562,0 +"585","2015-02-05 03:35:00",21,24.6,0,436,0.00377929260087562,0 +"586","2015-02-05 03:36:00",21,24.6,0,444,0.00377929260087562,0 +"587","2015-02-05 03:36:59",21,24.6,0,442,0.00377929260087562,0 +"588","2015-02-05 03:38:00",21,24.6,0,443.666666666667,0.00377929260087562,0 +"589","2015-02-05 03:39:00",21,24.6,0,439.5,0.00377929260087562,0 +"590","2015-02-05 03:40:00",21,24.5666666666667,0,439.333333333333,0.00377414053528786,0 +"591","2015-02-05 03:40:59",21,24.55,0,443.5,0.00377156453430672,0 +"592","2015-02-05 03:42:00",21,24.5,0,445,0.0037638366586111,0 +"593","2015-02-05 03:42:59",21,24.5,0,441.5,0.0037638366586111,0 +"594","2015-02-05 03:43:59",21,24.5,0,445,0.0037638366586111,0 +"595","2015-02-05 03:45:00",21,24.5,0,444.5,0.0037638366586111,0 +"596","2015-02-05 03:46:00",21,24.5,0,443.666666666667,0.0037638366586111,0 +"597","2015-02-05 03:47:00",21,24.5,0,445.5,0.0037638366586111,0 +"598","2015-02-05 03:48:00",21,24.445,0,445,0.00375533621579613,0 +"599","2015-02-05 03:49:00",21,24.445,0,443.5,0.00375533621579613,0 +"600","2015-02-05 03:49:59",21,24.39,0,447,0.00374683600391986,0 +"601","2015-02-05 03:51:00",21,24.39,0,444,0.00374683600391986,0 +"602","2015-02-05 03:52:00",21,24.5,0,442.5,0.0037638366586111,0 +"603","2015-02-05 03:53:00",21,24.4266666666667,0,445,0.00375250278617798,0 +"604","2015-02-05 03:53:59",21,24.5,0,444,0.0037638366586111,0 +"605","2015-02-05 03:55:00",21,24.39,0,440,0.00374683600391986,0 +"606","2015-02-05 03:55:59",21,24.39,0,445.5,0.00374683600391986,0 +"607","2015-02-05 03:56:59",21,24.39,0,444.5,0.00374683600391986,0 +"608","2015-02-05 03:58:00",21,24.39,0,442.5,0.00374683600391986,0 +"609","2015-02-05 03:59:00",21,24.39,0,444,0.00374683600391986,0 +"610","2015-02-05 04:00:00",21,24.39,0,442,0.00374683600391986,0 +"611","2015-02-05 04:01:00",21,24.3566666666667,0,442.666666666667,0.00374168447274892,0 +"612","2015-02-05 04:01:59",21,24.29,0,439,0.00373138166486622,0 +"613","2015-02-05 04:02:59",20.89,24.39,0,440,0.00372142541017581,0 +"614","2015-02-05 04:04:00",20.945,24.39,0,440,0.00373411165472082,0 +"615","2015-02-05 04:05:00",21,24.39,0,444,0.00374683600391986,0 +"616","2015-02-05 04:06:00",20.89,24.39,0,439.5,0.00372142541017581,0 +"617","2015-02-05 04:07:00",20.89,24.39,0,440,0.00372142541017581,0 +"618","2015-02-05 04:08:00",20.89,24.39,0,440,0.00372142541017581,0 +"619","2015-02-05 04:08:59",20.89,24.29,0,442,0.00370607650135101,0 +"620","2015-02-05 04:09:59",20.89,24.34,0,445,0.0037137508616353,0 +"621","2015-02-05 04:11:00",20.8566666666667,24.3566666666667,0,447,0.00370864950161061,0 +"622","2015-02-05 04:12:00",20.89,24.39,0,446,0.00372142541017581,0 +"623","2015-02-05 04:13:00",20.89,24.34,0,445,0.0037137508616353,0 +"624","2015-02-05 04:14:00",20.89,24.39,0,445,0.00372142541017581,0 +"625","2015-02-05 04:14:59",20.89,24.29,0,443,0.00370607650135101,0 +"626","2015-02-05 04:15:59",20.89,24.29,0,442,0.00370607650135101,0 +"627","2015-02-05 04:17:00",20.84,24.245,0,444,0.00368773895159239,0 +"628","2015-02-05 04:18:00",20.89,24.39,0,443.5,0.00372142541017581,0 +"629","2015-02-05 04:19:00",20.89,24.29,0,441,0.00370607650135101,0 +"630","2015-02-05 04:20:00",20.8566666666667,24.26,0,441,0.00369384321410272,0 +"631","2015-02-05 04:21:00",20.89,24.29,0,444,0.00370607650135101,0 +"632","2015-02-05 04:21:59",20.89,24.29,0,445.5,0.00370607650135101,0 +"633","2015-02-05 04:23:00",20.89,24.29,0,441,0.00370607650135101,0 +"634","2015-02-05 04:24:00",20.89,24.29,0,445.333333333333,0.00370607650135101,0 +"635","2015-02-05 04:25:00",20.89,24.2,0,442,0.00369226312722283,0 +"636","2015-02-05 04:25:59",20.89,24.29,0,442,0.00370607650135101,0 +"637","2015-02-05 04:27:00",20.89,24.2,0,446.5,0.00369226312722283,0 +"638","2015-02-05 04:27:59",20.8566666666667,24.1666666666667,0,444.333333333333,0.00367954815311901,0 +"639","2015-02-05 04:28:59",20.89,24.2,0,445.5,0.00369226312722283,0 +"640","2015-02-05 04:30:00",20.89,24.2,0,441.5,0.00369226312722283,0 +"641","2015-02-05 04:31:00",20.865,24.175,0,447.25,0.00368272360450164,0 +"642","2015-02-05 04:32:00",20.89,24.2,0,448,0.00369226312722283,0 +"643","2015-02-05 04:33:00",20.89,24.175,0,447.25,0.00368842618709178,0 +"644","2015-02-05 04:34:00",20.89,24.2,0,439,0.00369226312722283,0 +"645","2015-02-05 04:34:59",20.89,24.15,0,440,0.00368458929401908,0 +"646","2015-02-05 04:36:00",20.89,24.2,0,440,0.00369226312722283,0 +"647","2015-02-05 04:37:00",20.89,24.1,0,445,0.00367691564904522,0 +"648","2015-02-05 04:38:00",20.89,24,0,438,0.00366156892375949,0 +"649","2015-02-05 04:38:59",20.945,24,0,438.5,0.00367404992094876,0 +"650","2015-02-05 04:40:00",21,24,0,440,0.00368656839813018,0 +"651","2015-02-05 04:40:59",20.945,24,0,446,0.00367404992094876,0 +"652","2015-02-05 04:41:59",20.945,24,0,447,0.00367404992094876,0 +"653","2015-02-05 04:43:00",20.9266666666667,24,0,447,0.00366988542889002,0 +"654","2015-02-05 04:44:00",20.89,24,0,445,0.00366156892375949,0 +"655","2015-02-05 04:45:00",20.89,24,0,446.5,0.00366156892375949,0 +"656","2015-02-05 04:46:00",20.945,24,0,446,0.00367404992094876,0 +"657","2015-02-05 04:46:59",20.89,23.89,0,453,0.00364468839546917,0 +"658","2015-02-05 04:47:59",21,23.89,0,451,0.00366957194154691,0 +"659","2015-02-05 04:49:00",21,23.84,0,448.5,0.00366184658471608,0 +"660","2015-02-05 04:50:00",21,23.8233333333333,0,444.666666666667,0.0036592715081668,0 +"661","2015-02-05 04:51:00",21,23.79,0,447,0.00365412141865817,0 +"662","2015-02-05 04:52:00",21,23.79,0,447,0.00365412141865817,0 +"663","2015-02-05 04:53:00",21,23.79,0,445,0.00365412141865817,0 +"664","2015-02-05 04:53:59",21,23.79,0,446.5,0.00365412141865817,0 +"665","2015-02-05 04:54:59",21,23.79,0,446.5,0.00365412141865817,0 +"666","2015-02-05 04:56:00",21,23.7675,0,442.25,0.00365064515616988,0 +"667","2015-02-05 04:57:00",21,23.79,0,443,0.00365412141865817,0 +"668","2015-02-05 04:58:00",21,23.79,0,443,0.00365412141865817,0 +"669","2015-02-05 04:59:00",20.9633333333333,23.79,0,442.333333333333,0.00364584551634966,0 +"670","2015-02-05 04:59:59",20.89,23.79,0,444.5,0.00362934325107605,0 +"671","2015-02-05 05:00:59",20.89,23.73,0,443.333333333333,0.00362013652574939,0 +"672","2015-02-05 05:02:00",20.9175,23.7225,0,446.5,0.00362514858241312,0 +"673","2015-02-05 05:03:00",20.89,23.7,0,449,0.00361553326469954,0 +"674","2015-02-05 05:04:00",20.89,23.7,0,449.5,0.00361553326469954,0 +"675","2015-02-05 05:05:00",20.89,23.6,0,448.5,0.00360018955042734,0 +"676","2015-02-05 05:06:00",20.89,23.7,0,446,0.00361553326469954,0 +"677","2015-02-05 05:06:59",20.89,23.6,0,446,0.00360018955042734,0 +"678","2015-02-05 05:08:00",20.89,23.6,0,444,0.00360018955042734,0 +"679","2015-02-05 05:09:00",20.89,23.6,0,443.333333333333,0.00360018955042734,0 +"680","2015-02-05 05:10:00",20.89,23.6333333333333,0,441.666666666667,0.00360530403822479,0 +"681","2015-02-05 05:10:59",20.89,23.6,0,449.5,0.00360018955042734,0 +"682","2015-02-05 05:12:00",20.89,23.6,0,448.5,0.00360018955042734,0 +"683","2015-02-05 05:12:59",20.89,23.6,0,450,0.00360018955042734,0 +"684","2015-02-05 05:13:59",20.89,23.6,0,448.5,0.00360018955042734,0 +"685","2015-02-05 05:15:00",20.945,23.6,0,446.5,0.00361246011897543,0 +"686","2015-02-05 05:16:00",20.89,23.6,0,452.5,0.00360018955042734,0 +"687","2015-02-05 05:17:00",20.89,23.6,0,451,0.00360018955042734,0 +"688","2015-02-05 05:18:00",20.945,23.5,0,450.666666666667,0.00359706456304402,0 +"689","2015-02-05 05:19:00",20.89,23.5,0,449,0.00358484658877007,0 +"690","2015-02-05 05:19:59",20.945,23.5,0,449,0.00359706456304402,0 +"691","2015-02-05 05:21:00",20.945,23.5,0,448.5,0.00359706456304402,0 +"692","2015-02-05 05:22:00",20.89,23.5,0,452,0.00358484658877007,0 +"693","2015-02-05 05:23:00",20.89,23.5,0,444,0.00358484658877007,0 +"694","2015-02-05 05:23:59",20.89,23.5,0,443.5,0.00358484658877007,0 +"695","2015-02-05 05:25:00",20.89,23.5,0,446,0.00358484658877007,0 +"696","2015-02-05 05:25:59",20.89,23.5,0,449,0.00358484658877007,0 +"697","2015-02-05 05:26:59",20.9266666666667,23.5,0,448,0.00359298783408602,0 +"698","2015-02-05 05:28:00",20.89,23.5,0,448,0.00358484658877007,0 +"699","2015-02-05 05:29:00",20.89,23.5,0,449,0.00358484658877007,0 +"700","2015-02-05 05:30:00",20.945,23.5,0,443,0.00359706456304402,0 +"701","2015-02-05 05:31:00",20.89,23.5,0,444.25,0.00358484658877007,0 +"702","2015-02-05 05:31:59",20.89,23.5,0,445.333333333333,0.00358484658877007,0 +"703","2015-02-05 05:32:59",20.89,23.5,0,444.5,0.00358484658877007,0 +"704","2015-02-05 05:34:00",20.89,23.5,0,446.5,0.00358484658877007,0 +"705","2015-02-05 05:35:00",20.89,23.445,0,446,0.00357640828064061,0 +"706","2015-02-05 05:36:00",20.89,23.445,0,448.5,0.00357640828064061,0 +"707","2015-02-05 05:37:00",20.89,23.39,0,450,0.00356797020015121,0 +"708","2015-02-05 05:38:00",20.89,23.445,0,450.5,0.00357640828064061,0 +"709","2015-02-05 05:38:59",20.89,23.5,0,448,0.00358484658877007,0 +"710","2015-02-05 05:39:59",20.89,23.5,0,448.333333333333,0.00358484658877007,0 +"711","2015-02-05 05:41:00",20.89,23.445,0,446.5,0.00357640828064061,0 +"712","2015-02-05 05:42:00",20.89,23.5,0,442.5,0.00358484658877007,0 +"713","2015-02-05 05:43:00",20.89,23.5,0,440.5,0.00358484658877007,0 +"714","2015-02-05 05:44:00",20.89,23.5,0,443,0.00358484658877007,0 +"715","2015-02-05 05:44:59",20.89,23.5,0,453,0.00358484658877007,0 +"716","2015-02-05 05:45:59",20.89,23.4266666666667,0,450,0.00357359556185126,0 +"717","2015-02-05 05:47:00",20.89,23.445,0,451,0.00357640828064061,0 +"718","2015-02-05 05:48:00",20.89,23.39,0,452.333333333333,0.00356797020015121,0 +"719","2015-02-05 05:49:00",20.89,23.445,0,448,0.00357640828064061,0 +"720","2015-02-05 05:50:00",20.89,23.39,0,448,0.00356797020015121,0 +"721","2015-02-05 05:51:00",20.84,23.395,0,446.5,0.00355771184291898,0 +"722","2015-02-05 05:51:59",20.89,23.39,0,449,0.00356797020015121,0 +"723","2015-02-05 05:53:00",20.84,23.34,0,446.5,0.00354930018568549,0 +"724","2015-02-05 05:54:00",20.89,23.39,0,448,0.00356797020015121,0 +"725","2015-02-05 05:55:00",20.89,23.39,0,450.5,0.00356797020015121,0 +"726","2015-02-05 05:55:59",20.89,23.39,0,450.5,0.00356797020015121,0 +"727","2015-02-05 05:57:00",20.84,23.34,0,448,0.00354930018568549,0 +"728","2015-02-05 05:57:59",20.89,23.39,0,448,0.00356797020015121,0 +"729","2015-02-05 05:58:59",20.89,23.34,0,451,0.00356029941541926,0 +"730","2015-02-05 06:00:00",20.865,23.2925,0,450,0.00354752030852732,0 +"731","2015-02-05 06:01:00",20.89,23.34,0,448.5,0.00356029941541926,0 +"732","2015-02-05 06:02:00",20.8566666666667,23.26,0,449.5,0.00354071583146613,0 +"733","2015-02-05 06:03:00",20.89,23.29,0,446,0.00355262881880505,0 +"734","2015-02-05 06:04:00",20.89,23.29,0,443,0.00355262881880505,0 +"735","2015-02-05 06:04:59",20.89,23.29,0,443,0.00355262881880505,0 +"736","2015-02-05 06:06:00",20.89,23.29,0,448,0.00355262881880505,0 +"737","2015-02-05 06:07:00",20.84,23.245,0,448.5,0.00353477149236833,0 +"738","2015-02-05 06:08:00",20.89,23.29,0,448.5,0.00355262881880505,0 +"739","2015-02-05 06:08:59",20.89,23.29,0,448,0.00355262881880505,0 +"740","2015-02-05 06:10:00",20.89,23.29,0,450.5,0.00355262881880505,0 +"741","2015-02-05 06:10:59",20.89,23.2,0,451,0.00353882221893409,0 +"742","2015-02-05 06:11:59",20.89,23.2,0,453,0.00353882221893409,0 +"743","2015-02-05 06:13:00",20.89,23.2,0,449,0.00353882221893409,0 +"744","2015-02-05 06:14:00",20.89,23.2,0,448.5,0.00353882221893409,0 +"745","2015-02-05 06:15:00",20.89,23.2,0,448.5,0.00353882221893409,0 +"746","2015-02-05 06:16:00",20.89,23.15,0,448.5,0.00353115214901274,0 +"747","2015-02-05 06:16:59",20.89,23.15,0,453.5,0.00353115214901274,0 +"748","2015-02-05 06:17:59",20.84,23.075,0,451,0.00350877446231773,0 +"749","2015-02-05 06:19:00",20.89,23.1,0,451.333333333333,0.00352348226718284,0 +"750","2015-02-05 06:20:00",20.89,23.1,0,452,0.00352348226718284,0 +"751","2015-02-05 06:21:00",20.89,23.1,0,452.5,0.00352348226718284,0 +"752","2015-02-05 06:22:00",20.8566666666667,23.0666666666667,0,450.5,0.00351111984968993,0 +"753","2015-02-05 06:23:00",20.89,23.1,0,445.666666666667,0.00352348226718284,0 +"754","2015-02-05 06:23:59",20.89,23.1,0,449.5,0.00352348226718284,0 +"755","2015-02-05 06:24:59",20.89,23.1,0,450,0.00352348226718284,0 +"756","2015-02-05 06:26:00",20.89,23.1,0,454,0.00352348226718284,0 +"757","2015-02-05 06:27:00",20.89,23.1,0,452,0.00352348226718284,0 +"758","2015-02-05 06:28:00",20.89,23.1,0,453.75,0.00352348226718284,0 +"759","2015-02-05 06:29:00",20.89,23.1,0,448.5,0.00352348226718284,0 +"760","2015-02-05 06:29:59",20.89,23.1,0,447,0.00352348226718284,0 +"761","2015-02-05 06:30:59",20.89,23.1,0,447.75,0.00352348226718284,0 +"762","2015-02-05 06:32:00",20.89,23.1,0,452,0.00352348226718284,0 +"763","2015-02-05 06:33:00",20.89,23,0,454,0.00350814306776971,0 +"764","2015-02-05 06:34:00",20.84,23.05,0,455,0.00350495155191433,0 +"765","2015-02-05 06:35:00",20.89,23.1,0,455,0.00352348226718284,0 +"766","2015-02-05 06:36:00",20.8566666666667,23.0666666666667,0,449,0.00351111984968993,0 +"767","2015-02-05 06:36:59",20.89,23,0,449,0.00350814306776971,0 +"768","2015-02-05 06:38:00",20.89,23,0,452,0.00350814306776971,0 +"769","2015-02-05 06:39:00",20.89,23,0,449,0.00350814306776971,0 +"770","2015-02-05 06:40:00",20.79,22.89,0,450,0.0034697306094892,0 +"771","2015-02-05 06:40:59",20.79,22.89,0,452,0.0034697306094892,0 +"772","2015-02-05 06:42:00",20.84,22.945,0,449,0.00348889583848565,0 +"773","2015-02-05 06:42:59",20.79,22.89,0,448.333333333333,0.0034697306094892,0 +"774","2015-02-05 06:43:59",20.79,22.84,0,448,0.00346210928260059,0 +"775","2015-02-05 06:45:00",20.79,22.84,0,449.5,0.00346210928260059,0 +"776","2015-02-05 06:46:00",20.79,22.89,0,454,0.0034697306094892,0 +"777","2015-02-05 06:47:00",20.79,22.89,0,452,0.0034697306094892,0 +"778","2015-02-05 06:48:00",20.79,22.89,0,454.5,0.0034697306094892,0 +"779","2015-02-05 06:49:00",20.7,22.89,0,454.5,0.00345044462469646,0 +"780","2015-02-05 06:49:59",20.745,22.84,0,454,0.00345247577514156,0 +"781","2015-02-05 06:51:00",20.7,22.89,0,454.5,0.00345044462469646,0 +"782","2015-02-05 06:52:00",20.745,22.84,0,454,0.00345247577514156,0 +"783","2015-02-05 06:53:00",20.79,22.79,0,458,0.00345448814144093,0 +"784","2015-02-05 06:53:59",20.7,22.79,0,455.5,0.00343528734498098,0 +"785","2015-02-05 06:55:00",20.7,22.79,0,452,0.00343528734498098,0 +"786","2015-02-05 06:55:59",20.76,22.79,0,458.333333333333,0.00344807739687947,0 +"787","2015-02-05 06:56:59",20.7,22.79,0,460,0.00343528734498098,0 +"788","2015-02-05 06:58:00",20.7,22.79,0,455,0.00343528734498098,0 +"789","2015-02-05 06:59:00",20.7,22.79,0,455,0.00343528734498098,0 +"790","2015-02-05 07:00:00",20.73,22.79,0,449,0.00344167713631347,0 +"791","2015-02-05 07:01:00",20.7,22.79,0,459,0.00343528734498098,0 +"792","2015-02-05 07:01:59",20.7,22.7,0,457,0.00342164642134786,0 +"793","2015-02-05 07:02:59",20.73,22.7,0,454,0.00342801070087149,0 +"794","2015-02-05 07:04:00",20.7,22.7,0,452.5,0.00342164642134786,0 +"795","2015-02-05 07:05:00",20.7,22.7675,0,456.75,0.0034318770582882,0 +"796","2015-02-05 07:06:00",20.7,22.79,0,454.5,0.00343528734498098,0 +"797","2015-02-05 07:07:00",20.7,22.7,0,453.5,0.00342164642134786,0 +"798","2015-02-05 07:08:00",20.7,22.7,0,458,0.00342164642134786,0 +"799","2015-02-05 07:08:59",20.7,22.7,0,451.5,0.00342164642134786,0 +"800","2015-02-05 07:09:59",20.7,22.7,0,451,0.00342164642134786,0 +"801","2015-02-05 07:11:00",20.7,22.7,0,455.666666666667,0.00342164642134786,0 +"802","2015-02-05 07:12:00",20.7,22.7,0,457.5,0.00342164642134786,0 +"803","2015-02-05 07:13:00",20.7,22.7,0,452,0.00342164642134786,0 +"804","2015-02-05 07:14:00",20.7,22.65,0,451,0.00341406838754699,0 +"805","2015-02-05 07:14:59",20.7,22.6333333333333,0,454.666666666667,0.00341154241708903,0 +"806","2015-02-05 07:15:59",20.7,22.6,0,454.666666666667,0.00340649053738512,0 +"807","2015-02-05 07:17:00",20.7,22.6,0,454.5,0.00340649053738512,0 +"808","2015-02-05 07:18:00",20.7,22.6,0,456,0.00340649053738512,0 +"809","2015-02-05 07:19:00",20.7,22.5,0,455,0.00339133538795165,0 +"810","2015-02-05 07:20:00",20.7,22.5,0,451.5,0.00339133538795165,0 +"811","2015-02-05 07:21:00",20.7,22.5,0,455,0.00339133538795165,0 +"812","2015-02-05 07:21:59",20.7,22.5,0,454.5,0.00339133538795165,0 +"813","2015-02-05 07:23:00",20.7,22.5,0,451.666666666667,0.00339133538795165,0 +"814","2015-02-05 07:24:00",20.7,22.5,0,453.5,0.00339133538795165,0 +"815","2015-02-05 07:25:00",20.7,22.5,0,456.5,0.00339133538795165,0 +"816","2015-02-05 07:25:59",20.7,22.5,0,457,0.00339133538795165,0 +"817","2015-02-05 07:27:00",20.7,22.5,0,454,0.00339133538795165,0 +"818","2015-02-05 07:27:59",20.7,22.5,0,453.5,0.00339133538795165,0 +"819","2015-02-05 07:28:59",20.7,22.5,0,457,0.00339133538795165,0 +"820","2015-02-05 07:30:00",20.7,22.445,0,459,0.00338300036883699,0 +"821","2015-02-05 07:31:00",20.7,22.5,0,459,0.00339133538795165,0 +"822","2015-02-05 07:32:00",20.7,22.39,0,454.75,0.00337466557189241,0 +"823","2015-02-05 07:33:00",20.7,22.39,0,457,0.00337466557189241,0 +"824","2015-02-05 07:34:00",20.7,22.39,0,458,0.00337466557189241,0 +"825","2015-02-05 07:34:59",20.7,22.39,0,449,0.00337466557189241,0 +"826","2015-02-05 07:36:00",20.7,22.39,0,451,0.00337466557189241,0 +"827","2015-02-05 07:37:00",20.7,22.39,0,457.5,0.00337466557189241,0 +"828","2015-02-05 07:38:00",20.7,22.39,356,457,0.00337466557189241,1 +"829","2015-02-05 07:38:59",20.7,22.4175,426,460.25,0.003378832942594,0 +"830","2015-02-05 07:40:00",20.7,22.5,423.666666666667,465.333333333333,0.00339133538795165,0 +"831","2015-02-05 07:40:59",20.7,22.4633333333333,423.666666666667,472.666666666667,0.00338577868385588,0 +"832","2015-02-05 07:41:59",20.7225,22.5,419,470.75,0.00339606511573662,1 +"833","2015-02-05 07:43:00",20.73,22.5,419,472,0.00339764298252023,1 +"834","2015-02-05 07:44:00",20.7225,22.525,419,470.5,0.0033998591468996,1 +"835","2015-02-05 07:45:00",20.7675,22.65,411,478,0.00342837076038827,1 +"836","2015-02-05 07:46:00",20.79,22.79,411,492,0.00345448814144093,1 +"837","2015-02-05 07:46:59",20.815,22.8675,411,497.75,0.00347166969308452,1 +"838","2015-02-05 07:47:59",20.8233333333333,23.0333333333333,408.333333333333,499,0.00349879184810959,1 +"839","2015-02-05 07:49:00",20.815,23.025,400,507,0.00349571521582248,1 +"840","2015-02-05 07:50:00",20.89,23.175,396,514.75,0.00353498716046155,1 +"841","2015-02-05 07:51:00",20.89,23.29,396,515,0.00355262881880505,1 +"842","2015-02-05 07:52:00",20.89,23.29,396,520.75,0.00355262881880505,1 +"843","2015-02-05 07:53:00",20.89,23.29,396,526,0.00355262881880505,1 +"844","2015-02-05 07:53:59",20.89,23.3233333333333,398.333333333333,527,0.00355774252897956,1 +"845","2015-02-05 07:54:59",20.945,23.39,399.5,531.25,0.00358013032667571,1 +"846","2015-02-05 07:56:00",20.9633333333333,23.4633333333333,413,536,0.00359549407943774,1 +"847","2015-02-05 07:57:00",21,23.5,411,542.75,0.00360931921720166,1 +"848","2015-02-05 07:58:00",21,23.5,411,541,0.00360931921720166,1 +"849","2015-02-05 07:59:00",21,23.5666666666667,411,548.5,0.00361961800587205,1 +"850","2015-02-05 07:59:59",21,23.6,412.2,553.25,0.00362476752736239,1 +"851","2015-02-05 08:00:59",21,23.6,405,559.25,0.00362476752736239,1 +"852","2015-02-05 08:02:00",21,23.6,405,567.333333333333,0.00362476752736239,1 +"853","2015-02-05 08:03:00",21,23.7,405,569,0.00364021660047908,1 +"854","2015-02-05 08:04:00",21,23.7,405,576,0.00364021660047908,1 +"855","2015-02-05 08:05:00",21.025,23.7225,405,578.75,0.00364932867048953,1 +"856","2015-02-05 08:06:00",21.025,23.7225,412,585.75,0.00364932867048953,1 +"857","2015-02-05 08:06:59",21.05,23.745,419,590,0.00365845928385946,1 +"858","2015-02-05 08:08:00",21.025,23.7225,419,590,0.00364932867048953,1 +"859","2015-02-05 08:09:00",21.1,23.76,419,587.666666666667,0.00367211235503663,1 +"860","2015-02-05 08:10:00",21.075,23.72,419,594,0.00366023552315573,1 +"861","2015-02-05 08:10:59",21.0333333333333,23.6666666666667,419,602.333333333333,0.0036425651983171,1 +"862","2015-02-05 08:12:00",21.075,23.7675,419,611,0.00366760847238762,1 +"863","2015-02-05 08:12:59",21.1,23.79,419,611.333333333333,0.00367677626792028,1 +"864","2015-02-05 08:13:59",21.1,23.79,419,613,0.00367677626792028,1 +"865","2015-02-05 08:15:00",21.1,23.73,419,615,0.00366744851168384,1 +"866","2015-02-05 08:16:00",21.15,23.7225,419,615.75,0.00367762368029252,1 +"867","2015-02-05 08:17:00",21.2,23.745,419,620.5,0.00369251536345345,1 +"868","2015-02-05 08:18:00",21.2,23.79,419,630.666666666667,0.00369955480346118,1 +"869","2015-02-05 08:19:00",21.2,23.79,419,640.5,0.00369955480346118,1 +"870","2015-02-05 08:19:59",21.26,23.8566666666667,423.666666666667,641,0.00372374955324299,1 +"871","2015-02-05 08:21:00",21.29,23.865,422.5,650.75,0.00373196021214811,1 +"872","2015-02-05 08:22:00",21.29,23.89,422.5,650.5,0.00373589314251898,0 +"873","2015-02-05 08:23:00",21.29,23.89,419,651,0.00373589314251898,1 +"874","2015-02-05 08:23:59",21.3233333333333,23.9266666666667,428.333333333333,654.666666666667,0.00374936387120372,1 +"875","2015-02-05 08:25:00",21.29,24,424.6,664.25,0.00375319862350842,1 +"876","2015-02-05 08:25:59",21.34,24,426,675.4,0.00376479322756297,1 +"877","2015-02-05 08:26:59",21.29,24.05,429.5,675,0.00376106506766724,1 +"878","2015-02-05 08:28:00",21.29,24.1,419,679,0.00376893170960922,1 +"879","2015-02-05 08:29:00",21.315,24.175,426,685.5,0.00378656816292857,1 +"880","2015-02-05 08:30:00",21.29,24.2,419,689.333333333333,0.00378466558687248,1 +"881","2015-02-05 08:31:00",21.29,24.2,433,692.75,0.00378466558687248,1 +"882","2015-02-05 08:31:59",21.34,24.15,433,695.5,0.00378846650108156,1 +"883","2015-02-05 08:32:59",21.3233333333333,24.1,433,693.333333333333,0.00377669052642096,1 +"884","2015-02-05 08:34:00",21.29,24.1,433,694.25,0.00376893170960922,1 +"885","2015-02-05 08:35:00",21.34,24.2225,433,703,0.00379990922537672,1 +"886","2015-02-05 08:36:00",21.29,24.29,433,704.5,0.00379882675290265,1 +"887","2015-02-05 08:37:00",21.34,24.29,433,709,0.00381056317245117,1 +"888","2015-02-05 08:38:00",21.34,24.29,433,721.5,0.00381056317245117,1 +"889","2015-02-05 08:38:59",21.3233333333333,24.29,426.666666666667,727,0.00380664748676956,1 +"890","2015-02-05 08:39:59",21.3566666666667,24.29,436.333333333333,733,0.00381448240765945,1 +"891","2015-02-05 08:41:00",21.365,24.29,429,736.25,0.00381644335720262,1 +"892","2015-02-05 08:42:00",21.39,24.29,429,742,0.00382233153775034,1 +"893","2015-02-05 08:43:00",21.3566666666667,24.29,429,742.666666666667,0.00381448240765945,1 +"894","2015-02-05 08:44:00",21.3233333333333,24.29,434,737,0.00380664748676956,1 +"895","2015-02-05 08:44:59",21.39,24.2675,444,739.25,0.00381876914698375,1 +"896","2015-02-05 08:45:59",21.3233333333333,24.29,444,752,0.00380664748676956,1 +"897","2015-02-05 08:47:00",21.39,24.29,444,753.75,0.00382233153775034,1 +"898","2015-02-05 08:48:00",21.365,24.2225,441.75,746.25,0.00380577286974984,1 +"899","2015-02-05 08:49:00",21.39,24.26,446,754.666666666667,0.00381758169240746,1 +"900","2015-02-05 08:50:00",21.39,24.26,439,755.333333333333,0.00381758169240746,1 +"901","2015-02-05 08:51:00",21.39,24.29,446.5,758.25,0.00382233153775034,1 +"902","2015-02-05 08:51:59",21.39,24.29,446,766.6,0.00382233153775034,1 +"903","2015-02-05 08:53:00",21.39,24.29,451.5,781,0.00382233153775034,1 +"904","2015-02-05 08:54:00",21.4175,24.315,455.25,785.5,0.003832782800254,1 +"905","2015-02-05 08:55:00",21.39,24.29,447.333333333333,789.666666666667,0.00382233153775034,1 +"906","2015-02-05 08:55:59",21.445,24.34,444,787.5,0.00384325734848259,1 +"907","2015-02-05 08:57:00",21.4633333333333,24.3566666666667,455.666666666667,787.666666666667,0.00385025333877057,1 +"908","2015-02-05 08:57:59",21.5,24.39,454,782.5,0.00386427647734617,1 +"909","2015-02-05 08:58:59",21.5,24.39,457.333333333333,782.333333333333,0.00386427647734617,1 +"910","2015-02-05 09:00:00",21.5,24.39,454,786,0.00386427647734617,1 +"911","2015-02-05 09:01:00",21.5,24.3566666666667,465.666666666667,786.666666666667,0.00385896248129404,1 +"912","2015-02-05 09:02:00",21.5,24.365,465.5,785.25,0.00386029097184719,1 +"913","2015-02-05 09:03:00",21.5,24.29,469.666666666667,788,0.00384833475990096,1 +"914","2015-02-05 09:04:00",21.525,24.5425,478.5,791.25,0.00389458311119627,1 +"915","2015-02-05 09:04:59",21.55,24.5175,471.25,808.75,0.00389658701648499,1 +"916","2015-02-05 09:06:00",21.6,24.39,473,812,0.00388815002810914,1 +"917","2015-02-05 09:07:00",21.6,24.55,484.5,811,0.00391381704229398,1 +"918","2015-02-05 09:08:00",21.7,24.7,482.5,817.75,0.00396219418759181,1 +"919","2015-02-05 09:08:59",21.7,24.6966666666667,487.5,833.25,0.00396165607284392,1 +"920","2015-02-05 09:10:00",21.7675,24.865,490,847.75,0.00400542914152283,1 +"921","2015-02-05 09:10:59",21.79,24.89,492,854,0.0040150338084687,1 +"922","2015-02-05 09:11:59",21.815,24.9175,497.25,863.5,0.00402568175706654,1 +"923","2015-02-05 09:13:00",21.84,25.0225,495.5,869.75,0.00404897389842617,1 +"924","2015-02-05 09:14:00",21.89,25.15,495.5,880,0.00408226578928212,1 +"925","2015-02-05 09:15:00",21.89,25.2,497,895.75,0.00409043499770933,1 +"926","2015-02-05 09:16:00",21.89,25.2,497,895.5,0.00409043499770933,1 +"927","2015-02-05 09:16:59",21.89,25.2925,495.5,910.75,0.00410554859532466,1 +"928","2015-02-05 09:17:59",21.9175,25.39,494,919.25,0.00412845029871863,1 +"929","2015-02-05 09:19:00",21.9633333333333,25.3933333333333,498.666666666667,925.333333333333,0.00414063782090081,1 +"930","2015-02-05 09:20:00",22,25.4725,504.25,933.75,0.00416299679533861,1 +"931","2015-02-05 09:21:00",22,25.5,506,936,0.00416752126158064,1 +"932","2015-02-05 09:22:00",22,25.519,505.75,939.375,0.00417064729463238,1 +"933","2015-02-05 09:23:00",22,25.538,505.5,942.75,0.00417377335889663,1 +"934","2015-02-05 09:23:59",22.025,25.5975,518.5,948.25,0.00418998999194358,1 +"935","2015-02-05 09:24:59",22.05,25.7475,508.5,961.5,0.00422118332665464,1 +"936","2015-02-05 09:26:00",22.0666666666667,25.7933333333333,503.666666666667,969.333333333333,0.004233077134502,1 +"937","2015-02-05 09:27:00",22.0666666666667,25.8933333333333,496.333333333333,973.666666666667,0.00424960077695266,1 +"938","2015-02-05 09:28:00",22.1,25.9266666666667,503,986.333333333333,0.00426382311660346,1 +"939","2015-02-05 09:29:00",22.1,25.945,506,994.5,0.00426685884543887,1 +"940","2015-02-05 09:29:59",22.1,26.075,489.5,1003.25,0.00428838576690821,1 +"941","2015-02-05 09:30:59",22.1,25.83,478,1006.66666666667,0.00424781703306446,1 +"942","2015-02-05 09:32:00",22.1,25.8233333333333,478,1009,0.00424671319539255,1 +"943","2015-02-05 09:33:00",22.1,25.8,483.25,998.75,0.00424284979418462,1 +"944","2015-02-05 09:34:00",22.1,25.8225,484,998,0.00424657521595717,1 +"945","2015-02-05 09:35:00",22.1,26.05,476,1008,0.00428424585938511,1 +"946","2015-02-05 09:36:00",22.1,26.1,486.5,1021,0.00429252572916348,1 +"947","2015-02-05 09:36:59",22.1,26.0725,476.25,1029.5,0.00428797177369297,1 +"948","2015-02-05 09:38:00",22.1,25.745,469,1025,0.00423374339422388,1 +"949","2015-02-05 09:39:00",22.1,25.7933333333333,459,1015,0.00424174597402334,1 +"950","2015-02-05 09:40:00",22.1,25.945,459,1011,0.00426685884543887,1 +"951","2015-02-05 09:40:59",22.1,26.03,459,1011.66666666667,0.00428093397277306,1 +"952","2015-02-05 09:42:00",22.125,26.025,460.25,1025,0.00428667719736674,1 +"953","2015-02-05 09:42:59",22.1,26.1,446.5,1026.75,0.00429252572916348,1 +"954","2015-02-05 09:43:59",22.1,26.1,466.5,1035,0.00429252572916348,1 +"955","2015-02-05 09:45:00",22.1,26.175,450.25,1032,0.00430494594433316,1 +"956","2015-02-05 09:46:00",22.1,26.2,439,1025.66666666667,0.00430908612552796,1 +"957","2015-02-05 09:47:00",22.1,26.1975,450.25,1026.5,0.00430867210494531,1 +"958","2015-02-05 09:48:00",22.1,26.2,454,1024,0.00430908612552796,1 +"959","2015-02-05 09:49:00",22.075,26.2,450.25,1023.5,0.00430247908050949,1 +"960","2015-02-05 09:49:59",22.075,26.2225,454,1026.5,0.00430619953777207,1 +"961","2015-02-05 09:51:00",22.1,26.29,454,1031.33333333333,0.00432399123106433,1 +"962","2015-02-05 09:52:00",22.1,26.29,454,1027,0.00432399123106433,1 +"963","2015-02-05 09:53:00",22.1,26.29,457.75,1031,0.00432399123106433,1 +"964","2015-02-05 09:53:59",22.1,26.3566666666667,462.333333333333,1033,0.00433503250737302,1 +"965","2015-02-05 09:55:00",22.1,26.315,454,1037,0.00432813166406107,1 +"966","2015-02-05 09:55:59",22.1,26.39,456.5,1038,0.00434055329151115,1 +"967","2015-02-05 09:56:59",22.1,26.39,454,1034.5,0.00434055329151115,1 +"968","2015-02-05 09:58:00",22.1,26.39,461.5,1038.5,0.00434055329151115,1 +"969","2015-02-05 09:59:00",22.1,26.39,444,1037,0.00434055329151115,1 +"970","2015-02-05 10:00:00",22.1,26.5225,449.5,1037.5,0.00436249937082617,1 +"971","2015-02-05 10:01:00",22.125,26.4425,449.5,1032.75,0.00435592680689732,1 +"972","2015-02-05 10:01:59",22.1,26.47,449.5,1031.5,0.00435380357053742,1 +"973","2015-02-05 10:02:59",22.1,26.445,460,1039.25,0.00434966279811913,1 +"974","2015-02-05 10:04:00",22.1,26.5,453,1038,0.00435877256970857,1 +"975","2015-02-05 10:05:00",22.1,26.445,449.5,1040.25,0.00434966279811913,1 +"976","2015-02-05 10:06:00",22.1,26.5,449.5,1036.75,0.00435877256970857,1 +"977","2015-02-05 10:07:00",22.1,26.55,460,1045.5,0.00436705441019675,1 +"978","2015-02-05 10:08:00",22.1,26.5,453,1038,0.00435877256970857,1 +"979","2015-02-05 10:08:59",22.1,26.5,454.75,1041.75,0.00435877256970857,1 +"980","2015-02-05 10:09:59",22.1,26.6,449.5,1047.5,0.00437533646969611,1 +"981","2015-02-05 10:11:00",22.1,26.6,449.5,1045.5,0.00437533646969611,1 +"982","2015-02-05 10:12:00",22.1,26.575,449.5,1041.5,0.00437119541256949,1 +"983","2015-02-05 10:13:00",22.15,26.6,449.5,1043,0.00438878240585666,1 +"984","2015-02-05 10:14:00",22.1,26.7,455.5,1049,0.00439190124576314,1 +"985","2015-02-05 10:14:59",22.1,26.6666666666667,454,1048,0.00438637955639434,1 +"986","2015-02-05 10:15:59",22.1,26.675,454,1047,0.00438775996961013,1 +"987","2015-02-05 10:17:00",22.1,26.625,469,1047.4,0.0043794775815777,1 +"988","2015-02-05 10:18:00",22.1,26.65,469,1050,0.00438361874821534,1 +"989","2015-02-05 10:19:00",22.1,26.625,464,1047.75,0.0043794775815777,1 +"990","2015-02-05 10:20:00",22.1,26.65,469,1047,0.00438361874821534,1 +"991","2015-02-05 10:21:00",22.1,26.64,469,1048.25,0.00438196227498949,1 +"992","2015-02-05 10:21:59",22.1,26.6333333333333,459,1044,0.00438085796437285,0 +"993","2015-02-05 10:23:00",22.1,26.6,459,1036.5,0.00437533646969611,0 +"994","2015-02-05 10:24:00",22.05,26.575,469,1039,0.00435779859957091,0 +"995","2015-02-05 10:25:00",22.05,26.55,469,1039,0.00435367037672952,0 +"996","2015-02-05 10:25:59",22.025,26.4425,469,1034.25,0.00432926861517939,1 +"997","2015-02-05 10:27:00",22.05,26.34,469,1024.5,0.00431899545312204,1 +"998","2015-02-05 10:27:59",22,26.29,469,1024.75,0.00429752476185875,1 +"999","2015-02-05 10:28:59",22,26.29,469,1024,0.00429752476185875,1 +"1000","2015-02-05 10:30:00",22,26.23,469,1021.66666666667,0.00428764918406366,1 +"1001","2015-02-05 10:31:00",22.0666666666667,26.26,464,1016,0.00431019492691724,1 +"1002","2015-02-05 10:32:00",22.05,26.245,454,1009,0.00430331043936086,1 +"1003","2015-02-05 10:33:00",22.075,26.2925,454,1006.25,0.00431777457637761,1 +"1004","2015-02-05 10:34:00",22.1,26.29,454,1007.5,0.00432399123106433,1 +"1005","2015-02-05 10:34:59",22.1,26.245,461.5,1008,0.00431653858961807,1 +"1006","2015-02-05 10:36:00",22.1,26.245,461.5,1002.5,0.00431653858961807,1 +"1007","2015-02-05 10:37:00",22.1,26.245,464,999,0.00431653858961807,1 +"1008","2015-02-05 10:38:00",22.1,26.245,459,1006,0.00431653858961807,1 +"1009","2015-02-05 10:38:59",22.1,26.2,469,1003,0.00430908612552796,1 +"1010","2015-02-05 10:40:00",22.08,26.216,461.5,1006.5,0.00430644624605718,1 +"1011","2015-02-05 10:40:59",22.1,26.2,454,1014,0.00430908612552796,1 +"1012","2015-02-05 10:41:59",22,26.1,454,1009,0.00426625316721653,1 +"1013","2015-02-05 10:43:00",22.08,26.18,454,1009.6,0.00430049171628544,1 +"1014","2015-02-05 10:44:00",22.025,26.125,454,1010.5,0.00427692884900219,1 +"1015","2015-02-05 10:45:00",22,26.175,454,1012.5,0.00427859684467222,1 +"1016","2015-02-05 10:46:00",22.0333333333333,26.23,454,1013.66666666667,0.00429643504783087,1 +"1017","2015-02-05 10:46:59",22.075,26.2675,454,1023.25,0.00431364058490376,1 +"1018","2015-02-05 10:47:59",22,26.2,439,1025,0.00428271151195518,1 +"1019","2015-02-05 10:49:00",22.075,26.29,444.25,1022,0.00431736117477444,1 +"1020","2015-02-05 10:50:00",22.0666666666667,26.3566666666667,453,1024,0.00432617170149728,1 +"1021","2015-02-05 10:51:00",22.05,26.34,450.25,1030.5,0.00431899545312204,1 +"1022","2015-02-05 10:52:00",22.0666666666667,26.3566666666667,454,1032,0.00432617170149728,1 +"1023","2015-02-05 10:53:00",22.075,26.3425,454,1033,0.00432604272304626,1 +"1024","2015-02-05 10:53:59",22.025,26.34,469,1031,0.00431237056908573,1 +"1025","2015-02-05 10:54:59",22.025,26.315,463,1039,0.00430824923274392,1 +"1026","2015-02-05 10:56:00",22.0333333333333,26.39,471,1044.33333333333,0.00432282495101358,1 +"1027","2015-02-05 10:57:00",22.075,26.365,464,1039.5,0.0043297634602676,1 +"1028","2015-02-05 10:58:00",22.075,26.365,464,1044,0.0043297634602676,1 +"1029","2015-02-05 10:59:00",22.0666666666667,26.4266666666667,464,1044.66666666667,0.0043377415988366,1 +"1030","2015-02-05 10:59:59",22.0666666666667,26.4633333333333,474,1051,0.0043438021918476,1 +"1031","2015-02-05 11:00:59",22.1,26.5,479,1047,0.00435877256970857,1 +"1032","2015-02-05 11:02:00",22.1,26.5,465.25,1054,0.00435877256970857,1 +"1033","2015-02-05 11:03:00",22.1,26.5,469,1063.75,0.00435877256970857,1 +"1034","2015-02-05 11:04:00",22.1,26.5,464,1063.5,0.00435877256970857,1 +"1035","2015-02-05 11:05:00",22.1,26.525,466.75,1061.25,0.0043629134625768,1 +"1036","2015-02-05 11:06:00",22.1,26.6,465.666666666667,1065.66666666667,0.00437533646969611,1 +"1037","2015-02-05 11:06:59",22.1,26.6,464,1073.25,0.00437533646969611,1 +"1038","2015-02-05 11:08:00",22.1,26.6,459,1083.66666666667,0.00437533646969611,1 +"1039","2015-02-05 11:09:00",22.1,26.6,454,1082,0.00437533646969611,1 +"1040","2015-02-05 11:10:00",22.1333333333333,26.6,454,1077,0.00438429638374513,1 +"1041","2015-02-05 11:10:59",22.1,26.6,454,1077.33333333333,0.00437533646969611,1 +"1042","2015-02-05 11:12:00",22.175,26.6,454,1079.5,0.00439551902924901,1 +"1043","2015-02-05 11:12:59",22.175,26.6,450.25,1077.75,0.00439551902924901,1 +"1044","2015-02-05 11:13:59",22.175,26.6,442.75,1067.75,0.00439551902924901,1 +"1045","2015-02-05 11:15:00",22.175,26.6,439,1070.25,0.00439551902924901,1 +"1046","2015-02-05 11:16:00",22.2,26.6,439,1070.33333333333,0.00440226477037821,1 +"1047","2015-02-05 11:17:00",22.2,26.6,449.5,1075.5,0.00440226477037821,1 +"1048","2015-02-05 11:18:00",22.2,26.6,454.75,1076.5,0.00440226477037821,1 +"1049","2015-02-05 11:19:00",22.2,26.6,448,1068,0.00440226477037821,1 +"1050","2015-02-05 11:19:59",22.2,26.6,444,1071.5,0.00440226477037821,1 +"1051","2015-02-05 11:21:00",22.15,26.6,444,1075.75,0.00438878240585666,1 +"1052","2015-02-05 11:22:00",22.15,26.6,444,1073.25,0.00438878240585666,1 +"1053","2015-02-05 11:23:00",22.2,26.6,454.666666666667,1069,0.00440226477037821,1 +"1054","2015-02-05 11:23:59",22.175,26.675,460,1062.5,0.00440800023959307,1 +"1055","2015-02-05 11:25:00",22.2,26.7,460,1066.25,0.0044189322146931,1 +"1056","2015-02-05 11:25:59",22.2,26.7633333333333,449.333333333333,1060,0.00442948872153361,1 +"1057","2015-02-05 11:26:59",22.1666666666667,26.8566666666667,444,1077,0.0044359660260218,1 +"1058","2015-02-05 11:28:00",22.2,26.79,444,1091.75,0.00443393367296408,1 +"1059","2015-02-05 11:29:00",22.2,26.8566666666667,444,1097.33333333333,0.00444504632752026,1 +"1060","2015-02-05 11:30:00",22.175,26.9175,440.25,1096.75,0.00444835955732212,1 +"1061","2015-02-05 11:31:00",22.2,26.9175,444,1104,0.00445518696883703,1 +"1062","2015-02-05 11:31:59",22.2,26.89,454.666666666667,1105,0.00445060280264975,1 +"1063","2015-02-05 11:32:59",22.2,26.9725,449.5,1104.75,0.00446435550248734,1 +"1064","2015-02-05 11:34:00",22.2,27,454,1108.66666666667,0.00446893986995333,1 +"1065","2015-02-05 11:35:00",22.2,27,454,1116.25,0.00446893986995333,1 +"1066","2015-02-05 11:36:00",22.2,27,454,1120.66666666667,0.00446893986995333,1 +"1067","2015-02-05 11:37:00",22.2,27.025,457.75,1127.25,0.00447310753496422,1 +"1068","2015-02-05 11:38:00",22.2,27,454,1134.25,0.00446893986995333,1 +"1069","2015-02-05 11:38:59",22.2,27,454,1131.25,0.00446893986995333,1 +"1070","2015-02-05 11:39:59",22.2,27.05,454,1131,0.00447727525542733,1 +"1071","2015-02-05 11:41:00",22.2,27,454,1129.75,0.00446893986995333,1 +"1072","2015-02-05 11:42:00",22.2,27.0666666666667,454,1137.33333333333,0.00448005376654341,1 +"1073","2015-02-05 11:43:00",22.2,27,449.5,1136.5,0.00446893986995333,1 +"1074","2015-02-05 11:44:00",22.2,27.075,460,1129,0.00448144303134378,1 +"1075","2015-02-05 11:44:59",22.2,27.1,444,1126.5,0.00448561086271465,1 +"1076","2015-02-05 11:45:59",22.2,27.075,444,1133.25,0.00448144303134378,1 +"1077","2015-02-05 11:47:00",22.2,27.0666666666667,444,1139,0.00448005376654341,1 +"1078","2015-02-05 11:48:00",22.2,27.1,444,1137,0.00448561086271465,1 +"1079","2015-02-05 11:49:00",22.175,27.1,444,1136.75,0.0044787364943652,1 +"1080","2015-02-05 11:50:00",22.2,27.1,444,1131.25,0.00448561086271465,1 +"1081","2015-02-05 11:51:00",22.2,27.0333333333333,444,1132.33333333333,0.00447449676895718,1 +"1082","2015-02-05 11:51:59",22.2,27,444,1127.5,0.00446893986995333,1 +"1083","2015-02-05 11:53:00",22.2,27.025,444,1114.5,0.00447310753496422,1 +"1084","2015-02-05 11:54:00",22.2,27.1,460,1121.25,0.00448561086271465,1 +"1085","2015-02-05 11:55:00",22.2,27.1,460,1124,0.00448561086271465,1 +"1086","2015-02-05 11:55:59",22.175,27.175,454.75,1127.25,0.00449122102125288,1 +"1087","2015-02-05 11:57:00",22.175,27.125,460,1136,0.0044828979480412,1 +"1088","2015-02-05 11:57:59",22.175,27.125,458.5,1127.75,0.0044828979480412,1 +"1089","2015-02-05 11:58:59",22.2,27.1,461.5,1122.5,0.00448561086271465,1 +"1090","2015-02-05 12:00:00",22.2,27.1,464,1118,0.00448561086271465,1 +"1091","2015-02-05 12:01:00",22.2,27.1,465.666666666667,1110,0.00448561086271465,1 +"1092","2015-02-05 12:02:00",22.2,27.075,481.5,1115,0.00448144303134378,1 +"1093","2015-02-05 12:03:00",22.2,27.1,474,1119.75,0.00448561086271465,1 +"1094","2015-02-05 12:04:00",22.2,27,486.5,1114,0.00446893986995333,1 +"1095","2015-02-05 12:04:59",22.175,27,471.5,1104.75,0.00446209123250109,1 +"1096","2015-02-05 12:06:00",22.2,27.0666666666667,474,1099.33333333333,0.00448005376654341,1 +"1097","2015-02-05 12:07:00",22.2,27,481.5,1097.75,0.00446893986995333,1 +"1098","2015-02-05 12:08:00",22.2,26.945,489,1093.5,0.00445977120211573,1 +"1099","2015-02-05 12:08:59",22.2,27,504,1088,0.00446893986995333,1 +"1100","2015-02-05 12:10:00",22.2,27,502.333333333333,1083.66666666667,0.00446893986995333,1 +"1101","2015-02-05 12:10:59",22.2,27,524,1085.5,0.00446893986995333,1 +"1102","2015-02-05 12:11:59",22.2,26.9633333333333,550,1086.5,0.00446282739490862,1 +"1103","2015-02-05 12:13:00",22.2,26.84,554.2,1081.8,0.00444226812691885,1 +"1104","2015-02-05 12:14:00",22.26,26.8566666666667,562.333333333333,1081,0.00446143218925086,1 +"1105","2015-02-05 12:15:00",22.29,26.865,568.5,1063.25,0.00447104193180879,1 +"1106","2015-02-05 12:16:00",22.315,26.865,606.5,1063,0.00447789834796233,1 +"1107","2015-02-05 12:16:59",22.39,26.79,696.5,1078,0.00448587400570661,1 +"1108","2015-02-05 12:17:59",22.39,26.9725,657.25,1086,0.00451665477446917,1 +"1109","2015-02-05 12:19:00",22.4266666666667,27,744,1098.33333333333,0.0045314585515658,1 +"1110","2015-02-05 12:20:00",22.4725,26.89,708.75,1099,0.004525545460911,1 +"1111","2015-02-05 12:21:00",22.5333333333333,26.8233333333333,607,1092.33333333333,0.00453108315736118,1 +"1112","2015-02-05 12:22:00",22.575,26.84,660,1093.5,0.00454549187725733,1 +"1113","2015-02-05 12:23:00",22.6,26.79,688.5,1100.5,0.00454390539234429,1 +"1114","2015-02-05 12:23:59",22.6,26.815,558,1102,0.00454817669810378,1 +"1115","2015-02-05 12:24:59",22.6,26.8566666666667,661.333333333333,1105,0.00455529567045353,1 +"1116","2015-02-05 12:26:00",22.675,26.89,665.5,1111.25,0.0045819554386193,1 +"1117","2015-02-05 12:27:00",22.6666666666667,26.9633333333333,647.666666666667,1108.33333333333,0.0045922034336642,1 +"1118","2015-02-05 12:28:00",22.7,27.075,638,1124.25,0.00462076851459784,1 +"1119","2015-02-05 12:29:00",22.7225,26.7475,558,1125.25,0.0045707458409672,1 +"1120","2015-02-05 12:29:59",22.7,26.89,534,1106,0.00458896245772806,1 +"1121","2015-02-05 12:30:59",22.7,26.89,520,1110.33333333333,0.00458896245772806,1 +"1122","2015-02-05 12:32:00",22.7,26.9175,513.5,1117.5,0.00459369018079138,1 +"1123","2015-02-05 12:33:00",22.7,26.89,531.25,1120,0.00458896245772806,0 +"1124","2015-02-05 12:34:00",22.7,26.89,539,1113.66666666667,0.00458896245772806,0 +"1125","2015-02-05 12:35:00",22.7,26.89,545.75,1104.75,0.00458896245772806,0 +"1126","2015-02-05 12:36:00",22.675,26.865,604.75,1103.25,0.00457766418095273,0 +"1127","2015-02-05 12:36:59",22.7,26.815,597.25,1102.75,0.00457606903015623,0 +"1128","2015-02-05 12:38:00",22.7,26.7,528,1090,0.00455630013842985,0 +"1129","2015-02-05 12:39:00",22.7,26.7,521,1086.25,0.00455630013842985,0 +"1130","2015-02-05 12:40:00",22.7,26.6666666666667,535.666666666667,1083.66666666667,0.00455057025807531,0 +"1131","2015-02-05 12:40:59",22.675,26.575,533.25,1078.5,0.00452788988723977,0 +"1132","2015-02-05 12:42:00",22.65,26.55,523.75,1064.75,0.00451669155295424,0 +"1133","2015-02-05 12:42:59",22.6666666666667,26.5666666666667,524,1053,0.00452415460102103,0 +"1134","2015-02-05 12:43:59",22.65,26.55,521,1051,0.00451669155295424,1 +"1135","2015-02-05 12:45:00",22.625,26.4975,536.25,1041,0.00450081084146563,1 +"1136","2015-02-05 12:46:00",22.6,26.39,548.333333333333,1039,0.00447557241952152,1 +"1137","2015-02-05 12:47:00",22.625,26.4975,565.75,1037.5,0.00450081084146563,1 +"1138","2015-02-05 12:48:00",22.625,26.525,584.5,1043,0.00450551577040144,1 +"1139","2015-02-05 12:49:00",22.6,26.5,535,1046.33333333333,0.00449436250113661,1 +"1140","2015-02-05 12:49:59",22.6,26.5,546.333333333333,1045.33333333333,0.00449436250113661,1 +"1141","2015-02-05 12:51:00",22.6,26.5,630.5,1035.75,0.00449436250113661,1 +"1142","2015-02-05 12:52:00",22.6333333333333,26.46,570.666666666667,1029.66666666667,0.00449668571036632,1 +"1143","2015-02-05 12:53:00",22.65,26.495,630,1034,0.00450726713960598,1 +"1144","2015-02-05 12:53:59",22.675,26.525,732.75,1038.5,0.004519308911711,1 +"1145","2015-02-05 12:55:00",22.7225,26.4725,686.25,1027,0.00452341072022839,1 +"1146","2015-02-05 12:55:59",22.76,26.39,635.5,1022,0.00451955375372939,0 +"1147","2015-02-05 12:56:59",22.8566666666667,26.3233333333333,676,1024.75,0.00453474143569447,0 +"1148","2015-02-05 12:58:00",22.89,26.245,567.25,1020,0.00453035584785524,0 +"1149","2015-02-05 12:59:00",22.89,26.2,582.5,1015.5,0.00452253156464092,0 +"1150","2015-02-05 13:00:00",22.89,26.1,618.75,1007,0.00450514496825443,0 +"1151","2015-02-05 13:01:00",22.89,26.175,579.25,997.5,0.00451818482507468,0 +"1152","2015-02-05 13:01:59",22.89,26.1333333333333,590.333333333333,1002,0.00451094039316125,0 +"1153","2015-02-05 13:02:59",22.89,26.1,584.5,1000,0.00450514496825443,0 +"1154","2015-02-05 13:04:00",22.89,26,564,997.75,0.00448775933683034,0 +"1155","2015-02-05 13:05:00",22.89,25.945,534,987,0.00447819765083321,1 +"1156","2015-02-05 13:06:00",22.84,25.9175,496.5,983,0.00445978727174012,1 +"1157","2015-02-05 13:07:00",22.8233333333333,25.8566666666667,340.666666666667,983,0.00444472014342114,1 +"1158","2015-02-05 13:08:00",22.79,25.865,38.75,979,0.00443712353178304,0 +"1159","2015-02-05 13:08:59",22.79,25.8233333333333,31,977,0.00442992473512061,0 +"1160","2015-02-05 13:09:59",22.79,25.9725,26.75,961.5,0.00445569719129448,0 +"1161","2015-02-05 13:11:00",22.745,26,22,963.25,0.00444820689603743,0 +"1162","2015-02-05 13:12:00",22.7,26,13,974,0.0044359946549457,0 +"1163","2015-02-05 13:13:00",22.7,26.075,31,965.25,0.00444888231831554,0 +"1164","2015-02-05 13:14:00",22.6666666666667,26.0666666666667,32.6666666666667,962.333333333333,0.00443839981613283,0 +"1165","2015-02-05 13:14:59",22.6,26.05,33.5,957,0.00441750111078464,0 +"1166","2015-02-05 13:15:59",22.6,26.1,28,949.5,0.00442604033392404,0 +"1167","2015-02-05 13:17:00",22.5666666666667,26.1,31,950.333333333333,0.00441702679849529,0 +"1168","2015-02-05 13:18:00",22.525,26.1,33.5,949.5,0.00440578264158756,0 +"1169","2015-02-05 13:19:00",22.5,26.1,31,948.75,0.00439904826854001,0 +"1170","2015-02-05 13:20:00",22.5,26.1,31,944,0.00439904826854001,0 +"1171","2015-02-05 13:21:00",22.4175,26.05,33.5,934.5,0.00436844545377996,0 +"1172","2015-02-05 13:21:59",22.39,26.1,33.5,931.75,0.00436952473019479,0 +"1173","2015-02-05 13:23:00",22.39,26.1,28.6666666666667,928.666666666667,0.00436952473019479,0 +"1174","2015-02-05 13:24:00",22.39,26.1,46,930.5,0.00436952473019479,0 +"1175","2015-02-05 13:25:00",22.39,26.1,53,923.25,0.00436952473019479,0 +"1176","2015-02-05 13:25:59",22.39,26.1,71.5,921,0.00436952473019479,0 +"1177","2015-02-05 13:27:00",22.34,26.1,103,916.5,0.00435616279533284,0 +"1178","2015-02-05 13:27:59",22.3233333333333,26.1,91.6666666666667,912.333333333333,0.00435171683045639,0 +"1179","2015-02-05 13:28:59",22.29,26.1,90,902.25,0.00434283690213977,0 +"1180","2015-02-05 13:30:00",22.29,26.1,81.6666666666667,903,0.00434283690213977,0 +"1181","2015-02-05 13:31:00",22.29,26.1,112.75,898.5,0.00434283690213977,0 +"1182","2015-02-05 13:32:00",22.29,26.1666666666667,334.333333333333,900.333333333333,0.00435400736653795,1 +"1183","2015-02-05 13:33:00",22.29,26.15,472.25,893.75,0.00435121471308504,1 +"1184","2015-02-05 13:34:00",22.29,26.1,503.5,892.5,0.00434283690213977,0 +"1185","2015-02-05 13:34:59",22.2675,26.1725,567.5,883.5,0.0043489830279959,0 +"1186","2015-02-05 13:36:00",22.29,26.29,569.25,879.25,0.00437467377609042,0 +"1187","2015-02-05 13:37:00",22.29,26.26,490.666666666667,887.333333333333,0.00436964668608732,0 +"1188","2015-02-05 13:38:00",22.29,26.2,487.333333333333,890,0.00435959274815248,0 +"1189","2015-02-05 13:38:59",22.29,26.2,500,891.25,0.00435959274815248,0 +"1190","2015-02-05 13:40:00",22.29,26.2,524,891,0.00435959274815248,0 +"1191","2015-02-05 13:40:59",22.29,26.175,545.333333333333,881,0.00435540370260293,0 +"1192","2015-02-05 13:41:59",22.315,26.1,520.6,866.25,0.00434949534878106,0 +"1193","2015-02-05 13:43:00",22.29,26.1,509,864.666666666667,0.00434283690213977,0 +"1194","2015-02-05 13:44:00",22.34,26.1,476.5,870,0.00435616279533284,0 +"1195","2015-02-05 13:45:00",22.315,26.1,471.5,862,0.00434949534878106,0 +"1196","2015-02-05 13:46:00",22.29,26.1,464,857.5,0.00434283690213977,0 +"1197","2015-02-05 13:46:59",22.29,26.1,464,851.333333333333,0.00434283690213977,0 +"1198","2015-02-05 13:47:59",22.29,26.1,459,846.75,0.00434283690213977,0 +"1199","2015-02-05 13:49:00",22.29,26.1,459,844.666666666667,0.00434283690213977,0 +"1200","2015-02-05 13:50:00",22.29,26.1,454.75,843,0.00434283690213977,0 +"1201","2015-02-05 13:51:00",22.29,26.1,444,840.5,0.00434283690213977,0 +"1202","2015-02-05 13:52:00",22.29,26.025,456,831.25,0.00433027060593123,0 +"1203","2015-02-05 13:53:00",22.29,26,461,829,0.00432608195257972,0 +"1204","2015-02-05 13:53:59",22.29,26,461.5,825.5,0.00432608195257972,0 +"1205","2015-02-05 13:54:59",22.29,26,464,813.666666666667,0.00432608195257972,0 +"1206","2015-02-05 13:56:00",22.29,26,476.5,819,0.00432608195257972,0 +"1207","2015-02-05 13:57:00",22.29,26,489,819.5,0.00432608195257972,0 +"1208","2015-02-05 13:58:00",22.29,25.945,489,810,0.00431686711240859,0 +"1209","2015-02-05 13:59:00",22.29,25.945,484,809.5,0.00431686711240859,1 +"1210","2015-02-05 13:59:59",22.29,25.9633333333333,454,801,0.00431993869567135,1 +"1211","2015-02-05 14:00:59",22.2675,25.89,451,795,0.0043017164486566,0 +"1212","2015-02-05 14:02:00",22.2675,25.89,449.5,785,0.0043017164486566,0 +"1213","2015-02-05 14:03:00",22.2675,25.9175,449.5,795,0.00430631730667352,0 +"1214","2015-02-05 14:04:00",22.29,25.9266666666667,453,795.25,0.00431379555927285,0 +"1215","2015-02-05 14:05:00",22.245,25.89,451.75,797.5,0.00429578756746545,0 +"1216","2015-02-05 14:06:00",22.29,25.89,459,797,0.00430765254338066,0 +"1217","2015-02-05 14:06:59",22.2675,25.89,459,795.5,0.0043017164486566,0 +"1218","2015-02-05 14:08:00",22.2675,25.865,464,784.5,0.00429753390911668,0 +"1219","2015-02-05 14:09:00",22.29,25.89,454,775.5,0.00430765254338066,0 +"1220","2015-02-05 14:10:00",22.23,25.8233333333333,454,777.333333333333,0.00428071145407884,0 +"1221","2015-02-05 14:10:59",22.2225,25.8925,448,775.5,0.00429028298913779,0 +"1222","2015-02-05 14:12:00",22.2,25.96,453,780,0.0042956141263568,1 +"1223","2015-02-05 14:12:59",22.2225,25.99,444,781.5,0.00430655020161292,1 +"1224","2015-02-05 14:13:59",22.2,26.1225,444,776.75,0.00432268995143426,1 +"1225","2015-02-05 14:15:00",22.2,26.05,444,782,0.0043106096787041,1 +"1226","2015-02-05 14:16:00",22.2,26.213,441.9,788.6,0.00433777011822515,1 +"1227","2015-02-05 14:17:00",22.2,26.376,439.8,795.2,0.00436493291351491,1 +"1228","2015-02-05 14:18:00",22.2,26.6,442.5,818.5,0.00440226477037821,1 +"1229","2015-02-05 14:19:00",22.2,26.6666666666667,447,828.333333333333,0.00441337630136881,1 +"1230","2015-02-05 14:19:59",22.2,26.745,443.5,837,0.00442643285401607,1 +"1231","2015-02-05 14:21:00",22.2,26.8233333333333,441,832.666666666667,0.00443948995095924,1 +"1232","2015-02-05 14:22:00",22.2,26.945,438,847.5,0.00445977120211573,1 +"1233","2015-02-05 14:23:00",22.2,27,438,849,0.00446893986995333,1 +"1234","2015-02-05 14:23:59",22.2,26.9175,438,850,0.00445518696883703,1 +"1235","2015-02-05 14:25:00",22.2,26.9175,447,842.5,0.00445518696883703,1 +"1236","2015-02-05 14:25:59",22.2,27.1,441,839,0.00448561086271465,1 +"1237","2015-02-05 14:26:59",22.245,27.125,438,847.75,0.00450218767112889,1 +"1238","2015-02-05 14:28:00",22.2,27.1966666666667,441,860,0.00450172699913369,1 +"1239","2015-02-05 14:29:00",22.2,27.4175,438,885.75,0.00453854714585518,1 +"1240","2015-02-05 14:30:00",22.2,27.5,429,910,0.00455230370735505,1 +"1241","2015-02-05 14:31:00",22.2675,27.4225,429,917.25,0.00455821283752403,1 +"1242","2015-02-05 14:31:59",22.2,26.8975,438,919.75,0.00445185302313812,1 +"1243","2015-02-05 14:32:59",22.23,27.73,441,932,0.00459911494453659,1 +"1244","2015-02-05 14:34:00",22.2,27.745,438,942,0.00459316008733686,1 +"1245","2015-02-05 14:35:00",22.2675,28.025,429,959.75,0.00465911153966592,1 +"1246","2015-02-05 14:36:00",22.2,28,444,966.5,0.00463568973405886,1 +"1247","2015-02-05 14:37:00",22.2,28.1,451,970.666666666667,0.00465236960289551,1 +"1248","2015-02-05 14:38:00",22.245,28.2225,454,988.75,0.0046857222045098,1 +"1249","2015-02-05 14:38:59",22.2225,28.2225,465.25,996.75,0.00467925899457382,1 +"1250","2015-02-05 14:39:59",22.2225,28.3675,474.5,1012,0.00470348162634113,1 +"1251","2015-02-05 14:41:00",22.29,28.39,479,1021,0.00472677070962879,1 +"1252","2015-02-05 14:42:00",22.245,28.245,525.5,1019.5,0.00468948599636347,1 +"1253","2015-02-05 14:43:00",22.29,28.39,515,1020,0.00472677070962879,1 +"1254","2015-02-05 14:44:00",22.29,28.5,494,1037,0.00474522479295852,1 +"1255","2015-02-05 14:44:59",22.29,28.4266666666667,487.333333333333,1047,0.00473292194998911,1 +"1256","2015-02-05 14:45:59",22.315,28.39,474.5,1051,0.00473402225350664,1 +"1257","2015-02-05 14:47:00",22.3233333333333,28.39,486,1052.33333333333,0.00473644161539406,1 +"1258","2015-02-05 14:48:00",22.29,28.3566666666667,502.333333333333,1048.33333333333,0.00472117877771628,1 +"1259","2015-02-05 14:49:00",22.29,28.34,540.5,1050.5,0.00471838284918011,1 +"1260","2015-02-05 14:50:00",22.34,28.39,504,1052.25,0.00474128361261468,1 +"1261","2015-02-05 14:51:00",22.39,28.2,489,1053,0.00472376568359107,1 +"1262","2015-02-05 14:51:59",22.39,28.2,490.25,1051,0.00472376568359107,1 +"1263","2015-02-05 14:53:00",22.39,28.2933333333333,536.333333333333,1049.66666666667,0.00473951902591521,1 +"1264","2015-02-05 14:54:00",22.39,28.39,532,1054,0.00475583582251364,1 +"1265","2015-02-05 14:55:00",22.39,28.2925,543,1067.75,0.0047393783675691,1 +"1266","2015-02-05 14:55:59",22.4266666666667,28.2,543,1066.33333333333,0.0047343896633629,1 +"1267","2015-02-05 14:57:00",22.445,28.245,543,1066.5,0.00474733064778224,1 +"1268","2015-02-05 14:57:59",22.5,28.365,533.25,1081,0.00478374080780174,1 +"1269","2015-02-05 14:58:59",22.4633333333333,28.3266666666667,527,1081.33333333333,0.00476651144434147,1 +"1270","2015-02-05 15:00:00",22.5,28.3175,534,1084.5,0.00477566845366135,1 +"1271","2015-02-05 15:01:00",22.55,28.3175,530,1082.5,0.0047903090040007,1 +"1272","2015-02-05 15:02:00",22.5,28.34,524,1087.5,0.00477949217444028,1 +"1273","2015-02-05 15:03:00",22.525,28.39,526.25,1094,0.0047953238486071,1 +"1274","2015-02-05 15:04:00",22.5,28.39,522,1103.33333333333,0.00478798949876243,1 +"1275","2015-02-05 15:04:59",22.5,28.0333333333333,517,1099.33333333333,0.00472738029153847,1 +"1276","2015-02-05 15:06:00",22.525,28.025,513.5,1085,0.00473320294951395,1 +"1277","2015-02-05 15:07:00",22.575,28.22,524,1086.25,0.00478099837718911,1 +"1278","2015-02-05 15:08:00",22.6,28.2,513.5,1103,0.0047848980542252,1 +"1279","2015-02-05 15:08:59",22.6,28.245,513.5,1106.75,0.00479259236219434,1 +"1280","2015-02-05 15:10:00",22.5,28.29,513.5,1104,0.00477099508051037,1 +"1281","2015-02-05 15:10:59",22.6,28.315,518,1102.25,0.00480456166119307,1 +"1282","2015-02-05 15:11:59",22.55,28.2675,520.75,1097.5,0.00478178576617497,1 +"1283","2015-02-05 15:13:00",22.6,28.29,525,1100,0.0048002868590739,1 +"1284","2015-02-05 15:14:00",22.6,28.245,524.833333333333,1101,0.00479259236219434,1 +"1285","2015-02-05 15:15:00",22.6,28.2,524.666666666667,1102,0.0047848980542252,1 +"1286","2015-02-05 15:16:00",22.6,28.39,489,1102.5,0.00481738641740953,1 +"1287","2015-02-05 15:16:59",22.6,28.39,474,1114,0.00481738641740953,1 +"1288","2015-02-05 15:17:59",22.6,28.34,474,1112,0.00480883652162128,1 +"1289","2015-02-05 15:19:00",22.6,28.1725,472.75,1113.5,0.00478019607012754,1 +"1290","2015-02-05 15:20:00",22.6,28.1475,471.5,1105.25,0.00477592160034705,1 +"1291","2015-02-05 15:21:00",22.6,28.23,464,1104.33333333333,0.00479002757188159,1 +"1292","2015-02-05 15:22:00",22.6,28.1333333333333,469,1107.33333333333,0.00477349942668403,1 +"1293","2015-02-05 15:23:00",22.575,28,465.25,1108.25,0.00474344200093282,1 +"1294","2015-02-05 15:23:59",22.6,28,454,1101.66666666667,0.00475070341532009,1 +"1295","2015-02-05 15:24:59",22.55,27.82,450.25,1097,0.00470551310764671,1 +"1296","2015-02-05 15:26:00",22.525,27.815,449.5,1092.25,0.00469746773815421,1 +"1297","2015-02-05 15:27:00",22.5,27.815,454.75,1102.75,0.00469028417719752,1 +"1298","2015-02-05 15:28:00",22.5,27.745,449.5,1097,0.00467839169614977,1 +"1299","2015-02-05 15:29:00",22.525,27.7,454.75,1086.33333333333,0.00467790018253108,1 +"1300","2015-02-05 15:29:59",22.55,27.7,454.75,1092,0.00468506326046972,1 +"1301","2015-02-05 15:30:59",22.5,27.6,460,1085,0.00465375870689364,1 +"1302","2015-02-05 15:32:00",22.5,27.7,460,1084,0.00467074676810413,1 +"1303","2015-02-05 15:33:00",22.5,27.6,436.5,1076.25,0.00465375870689364,1 +"1304","2015-02-05 15:34:00",22.5,27.33,460,1060.66666666667,0.0046078955418804,1 +"1305","2015-02-05 15:35:00",22.55,27.445,449.5,1051.5,0.00464161176615444,1 +"1306","2015-02-05 15:36:00",22.5,27.4725,460.75,1062,0.00463210026459905,1 +"1307","2015-02-05 15:36:59",22.5,27.39,461,1068.33333333333,0.00461808677616419,1 +"1308","2015-02-05 15:38:00",22.5,27.34,454,1074,0.00460959405790695,1 +"1309","2015-02-05 15:39:00",22.5,27.29,469,1072,0.00460110156985465,1 +"1310","2015-02-05 15:40:00",22.5,27.315,469,1068,0.00460534778510577,1 +"1311","2015-02-05 15:40:59",22.5,27.29,479.666666666667,1072,0.00460110156985465,1 +"1312","2015-02-05 15:42:00",22.5,27.2225,476.75,1072.75,0.00458963707613002,1 +"1313","2015-02-05 15:42:59",22.5,27.2225,476.5,1074,0.00458963707613002,1 +"1314","2015-02-05 15:43:59",22.5,27.2,474,1069,0.00458581567144704,1 +"1315","2015-02-05 15:45:00",22.5,27.15,481.5,1068.25,0.00457732382791874,1 +"1316","2015-02-05 15:46:00",22.5,27.2225,474,1079.75,0.00458963707613002,1 +"1317","2015-02-05 15:47:00",22.4725,27.1975,479,1085,0.00457767810882964,1 +"1318","2015-02-05 15:48:00",22.5,27.1666666666667,469,1066,0.00458015441685334,1 +"1319","2015-02-05 15:49:00",22.5,27.125,474,1063.5,0.00457307799246869,1 +"1320","2015-02-05 15:49:59",22.5,27.15,469,1065.5,0.00457732382791874,1 +"1321","2015-02-05 15:51:00",22.5,27.125,474,1071.25,0.00457307799246869,1 +"1322","2015-02-05 15:52:00",22.5,27.0666666666667,479,1068,0.00456317126685443,1 +"1323","2015-02-05 15:53:00",22.5,27.1,478.5,1064.75,0.00456883221455981,1 +"1324","2015-02-05 15:53:59",22.5,27.1,478.5,1070.75,0.00456883221455981,1 +"1325","2015-02-05 15:55:00",22.5,27.1,477,1072.33333333333,0.00456883221455981,1 +"1326","2015-02-05 15:55:59",22.5,27.025,470.25,1079.25,0.00455609522606849,1 +"1327","2015-02-05 15:56:59",22.5,27,469,1063.5,0.0045518496783126,1 +"1328","2015-02-05 15:58:00",22.5,27,460.666666666667,1074.33333333333,0.0045518496783126,1 +"1329","2015-02-05 15:59:00",22.5,26.9725,465.25,1068.75,0.00454717964223436,1 +"1330","2015-02-05 16:00:00",22.5,26.7333333333333,452.333333333333,1064,0.00450656741532423,1 +"1331","2015-02-05 16:01:00",22.5,26.925,446.5,1048.5,0.00453911338025217,1 +"1332","2015-02-05 16:01:59",22.5,26.9725,449.5,1054.5,0.00454717964223436,1 +"1333","2015-02-05 16:02:59",22.5,27.05,460,1055.5,0.00456034083136088,1 +"1334","2015-02-05 16:04:00",22.445,26.9,456,1064,0.00451962464445108,1 +"1335","2015-02-05 16:05:00",22.4175,26.82,456,1063.25,0.00449850420165594,1 +"1336","2015-02-05 16:06:00",22.39,26.6966666666667,444,1078,0.00447013341157524,1 +"1337","2015-02-05 16:07:00",22.39,26.9633333333333,444,1067.33333333333,0.00451510863631191,1 +"1338","2015-02-05 16:08:00",22.39,27.0225,454.75,1074.75,0.00452508838966376,1 +"1339","2015-02-05 16:08:59",22.39,26.8233333333333,453,1077.33333333333,0.00449149583816393,1 +"1340","2015-02-05 16:09:59",22.39,26.84,449.5,1072.75,0.0044943067922288,1 +"1341","2015-02-05 16:11:00",22.39,26.745,449.5,1074.25,0.00447828469193235,1 +"1342","2015-02-05 16:12:00",22.39,26.79,456,1074,0.00448587400570661,1 +"1343","2015-02-05 16:13:00",22.3566666666667,26.73,449.333333333333,1068.33333333333,0.00446662478682213,1 +"1344","2015-02-05 16:14:00",22.39,26.5725,444,1062.75,0.00444919402578691,1 +"1345","2015-02-05 16:14:59",22.39,26.675,444,1056.5,0.00446647945820187,1 +"1346","2015-02-05 16:15:59",22.39,26.695,444,1054,0.00446985233672554,1 +"1347","2015-02-05 16:17:00",22.39,26.745,444,1068,0.00447828469193235,1 +"1348","2015-02-05 16:18:00",22.39,26.79,444,1074,0.00448587400570661,1 +"1349","2015-02-05 16:19:00",22.4175,26.65,444,1078.75,0.00446978528697734,1 +"1350","2015-02-05 16:20:00",22.4725,26.745,429,1077.5,0.00450096559598787,1 +"1351","2015-02-05 16:21:00",22.445,26.695,429,1077.5,0.00448493305524509,1 +"1352","2015-02-05 16:21:59",22.445,26.745,429,1083.25,0.00449339406421304,1 +"1353","2015-02-05 16:23:00",22.4266666666667,26.6966666666667,429,1088,0.00448018288220535,1 +"1354","2015-02-05 16:24:00",22.39,26.79,438,1086,0.00448587400570661,1 +"1355","2015-02-05 16:25:00",22.4266666666667,26.73,441,1087.66666666667,0.00448581716067179,1 +"1356","2015-02-05 16:25:59",22.39,26.5475,438,1075,0.0044449782113592,1 +"1357","2015-02-05 16:27:00",22.39,26.4175,438,1067.75,0.00442305689098935,1 +"1358","2015-02-05 16:27:59",22.39,26.5333333333333,441,1064,0.00444258927503736,1 +"1359","2015-02-05 16:28:59",22.39,26.456,438,1063.25,0.00442954881442905,1 +"1360","2015-02-05 16:30:00",22.39,26.26,432.75,1065.5,0.00439650042347941,1 +"1361","2015-02-05 16:31:00",22.39,26.4266666666667,444,1068.66666666667,0.00442460257484173,1 +"1362","2015-02-05 16:32:00",22.39,26.4175,444,1073.25,0.00442305689098935,1 +"1363","2015-02-05 16:33:00",22.39,26.34,444,1061.5,0.00440998914145686,1 +"1364","2015-02-05 16:34:00",22.39,26.3233333333333,444,1060.33333333333,0.00440717894397208,1 +"1365","2015-02-05 16:34:59",22.39,26.4633333333333,444,1057.33333333333,0.00443078538653073,1 +"1366","2015-02-05 16:36:00",22.39,26.015,444,1056.25,0.0043551948381356,1 +"1367","2015-02-05 16:37:00",22.39,26.045,429,1046,0.00436025237222819,1 +"1368","2015-02-05 16:38:00",22.39,26.29,435,1049.66666666667,0.00440155862464441,1 +"1369","2015-02-05 16:38:59",22.39,26.2675,438,1052.75,0.0043977649661122,1 +"1370","2015-02-05 16:40:00",22.39,26.29,438,1044.5,0.00440155862464441,1 +"1371","2015-02-05 16:40:59",22.39,26.3233333333333,441,1053.66666666667,0.00440717894397208,1 +"1372","2015-02-05 16:41:59",22.3566666666667,26.3233333333333,441,1059,0.00439818964083385,1 +"1373","2015-02-05 16:43:00",22.39,26.34,438,1067.25,0.00440998914145686,1 +"1374","2015-02-05 16:44:00",22.365,26.29,438,1067.25,0.00439482379023074,1 +"1375","2015-02-05 16:45:00",22.3233333333333,26.39,441,1065.33333333333,0.00440041131442427,1 +"1376","2015-02-05 16:46:00",22.34,26.39,438,1068.75,0.0044049073782613,1 +"1377","2015-02-05 16:46:59",22.34,26.39,447,1074.75,0.0044049073782613,1 +"1378","2015-02-05 16:47:59",22.3233333333333,26.4633333333333,447,1076.33333333333,0.00441272606148445,1 +"1379","2015-02-05 16:49:00",22.365,26.4725,447,1077.5,0.00442554885640755,1 +"1380","2015-02-05 16:50:00",22.315,26.3425,438,1073,0.00439019256195137,1 +"1381","2015-02-05 16:51:00",22.34,26.145,438,1068,0.00436372611266303,1 +"1382","2015-02-05 16:52:00",22.29,26.1425,438,1061.75,0.00434995802715568,1 +"1383","2015-02-05 16:53:00",22.29,25.7,441,1045.66666666667,0.00427582248189627,1 +"1384","2015-02-05 16:53:59",22.29,26.22,438,1041.5,0.00436294402493567,1 +"1385","2015-02-05 16:54:59",22.29,26.2425,442.5,1051,0.00436671425418257,1 +"1386","2015-02-05 16:56:00",22.29,26.125,438,1059.25,0.0043470257795977,1 +"1387","2015-02-05 16:57:00",22.315,26.2,438,1065,0.00436627706397936,1 +"1388","2015-02-05 16:58:00",22.29,26.175,442.5,1064.75,0.00435540370260293,1 +"1389","2015-02-05 16:59:00",22.29,26.1,441,1054.66666666667,0.00434283690213977,1 +"1390","2015-02-05 16:59:59",22.29,25.995,447,1042.5,0.00432524422863232,1 +"1391","2015-02-05 17:00:59",22.2675,25.8925,438,1039,0.0043021347056831,1 +"1392","2015-02-05 17:02:00",22.29,25.89,447,1036.33333333333,0.00430765254338066,1 +"1393","2015-02-05 17:03:00",22.29,25.89,447,1036.5,0.00430765254338066,1 +"1394","2015-02-05 17:04:00",22.29,25.8566666666667,433,1038.66666666667,0.00430206808804728,1 +"1395","2015-02-05 17:05:00",22.245,25.7225,433,1030.5,0.00426780450390924,1 +"1396","2015-02-05 17:06:00",22.23,25.6666666666667,433,1023.66666666667,0.00425456331564984,1 +"1397","2015-02-05 17:06:59",22.29,25.6,433,1019.5,0.0042590711174276,1 +"1398","2015-02-05 17:08:00",22.245,25.55,433,1010,0.00423898873856473,1 +"1399","2015-02-05 17:09:00",22.2675,25.575,433,1002.75,0.00424902053262658,1 +"1400","2015-02-05 17:10:00",22.29,25.5666666666667,433,1002.33333333333,0.00425348752840671,1 +"1401","2015-02-05 17:10:59",22.2675,25.4975,433,998.75,0.00423605702359138,1 +"1402","2015-02-05 17:12:00",22.245,25.55,433,1002,0.00423898873856473,1 +"1403","2015-02-05 17:12:59",22.29,25.5,433,1002.25,0.00424232064905198,1 +"1404","2015-02-05 17:13:59",22.29,25.5,433,1001.5,0.00424232064905198,1 +"1405","2015-02-05 17:15:00",22.29,25.445,433,998.5,0.00423310827337899,1 +"1406","2015-02-05 17:16:00",22.29,25.2,433,990.75,0.00419207461976444,1 +"1407","2015-02-05 17:17:00",22.29,25.23,433,991,0.00419709885985995,1 +"1408","2015-02-05 17:18:00",22.245,25.15,433,986,0.00417217977515601,1 +"1409","2015-02-05 17:19:00",22.29,25.2675,433,976.25,0.00420337927335767,1 +"1410","2015-02-05 17:19:59",22.29,25.2,433,966,0.00419207461976444,1 +"1411","2015-02-05 17:21:00",22.29,25.2,433,966.333333333333,0.00419207461976444,1 +"1412","2015-02-05 17:22:00",22.29,25.15,433,967.5,0.00418370106543207,1 +"1413","2015-02-05 17:23:00",22.29,25.03,433,970,0.00416360544870222,1 +"1414","2015-02-05 17:23:59",22.2225,24.865,433,954.75,0.00411890295856365,1 +"1415","2015-02-05 17:25:00",22.26,24.8266666666667,433,951.666666666667,0.0041219736123528,1 +"1416","2015-02-05 17:25:59",22.245,24.89,433,940.75,0.00412876159251567,1 +"1417","2015-02-05 17:26:59",22.245,24.89,433,935.5,0.00412876159251567,1 +"1418","2015-02-05 17:28:00",22.2225,24.84,433,933.25,0.00411473429693637,1 +"1419","2015-02-05 17:29:00",22.2,24.7,433,937.666666666667,0.00408575176529873,1 +"1420","2015-02-05 17:30:00",22.2,24.7,433,938,0.00408575176529873,1 +"1421","2015-02-05 17:31:00",22.2,24.7,433,933.5,0.00408575176529873,1 +"1422","2015-02-05 17:31:59",22.2,24.7,433,925.5,0.00408575176529873,1 +"1423","2015-02-05 17:32:59",22.2,24.65,433,921,0.00407742679507162,1 +"1424","2015-02-05 17:34:00",22.2,24.5666666666667,433,920.333333333333,0.00406355233666402,1 +"1425","2015-02-05 17:35:00",22.2,24.55,433,912.25,0.00406077751877519,1 +"1426","2015-02-05 17:36:00",22.2,24.334,429.5,913,0.00402481810386428,1 +"1427","2015-02-05 17:37:00",22.2,24.34,433,903,0.00402581692072147,1 +"1428","2015-02-05 17:38:00",22.2,24.395,433,905.5,0.0040349728904295,1 +"1429","2015-02-05 17:38:59",22.2,24.34,433,907,0.00402581692072147,1 +"1430","2015-02-05 17:39:59",22.2,24.3566666666667,433,903,0.00402859142871451,1 +"1431","2015-02-05 17:41:00",22.175,24.39,433,900.5,0.00402796249402516,1 +"1432","2015-02-05 17:42:00",22.175,24.365,433,900.25,0.00402380708201175,1 +"1433","2015-02-05 17:43:00",22.2,24.365,433,900.5,0.00402997869193338,1 +"1434","2015-02-05 17:44:00",22.1333333333333,24.29,433,898.666666666667,0.00400110568029615,1 +"1435","2015-02-05 17:44:59",22.15,24.2225,433,892,0.00399399551699376,1 +"1436","2015-02-05 17:45:59",22.1333333333333,24.2,433,886,0.00398618566110871,1 +"1437","2015-02-05 17:47:00",22.1,24.2675,433,884.25,0.00398921145655858,1 +"1438","2015-02-05 17:48:00",22.1,24.245,433,887,0.00398548909616386,1 +"1439","2015-02-05 17:49:00",22.1,24.29,433,884,0.00399293386122286,1 +"1440","2015-02-05 17:50:00",22.125,24.2675,433,878.5,0.00399533319162209,1 +"1441","2015-02-05 17:51:00",22.1333333333333,24.26,433,887,0.00399613226154318,1 +"1442","2015-02-05 17:51:59",22.125,24.15,433,882.25,0.0039758646672312,1 +"1443","2015-02-05 17:53:00",22.1,24.0725,433,879.25,0.00395695247045276,1 +"1444","2015-02-05 17:54:00",22.1,23.9966666666667,433,866,0.00394440820707065,1 +"1445","2015-02-05 17:55:00",22.1,24.12,433,866,0.00396481012230008,1 +"1446","2015-02-05 17:55:59",22.0666666666667,23.9266666666667,433,863,0.00392479578216467,1 +"1447","2015-02-05 17:57:00",22.025,23.945,433,853.25,0.00391779269090952,1 +"1448","2015-02-05 17:57:59",22,23.9266666666667,433,858,0.00390877204643491,1 +"1449","2015-02-05 17:58:59",22,23.89,433,852.5,0.00390274442392475,1 +"1450","2015-02-05 18:00:00",22,23.89,433,850.666666666667,0.00390274442392475,1 +"1451","2015-02-05 18:01:00",22.025,23.9175,433,847,0.00391326493428083,1 +"1452","2015-02-05 18:02:00",22,23.89,433,840.666666666667,0.00390274442392475,1 +"1453","2015-02-05 18:03:00",22.075,23.9725,426,839,0.00393437247979718,1 +"1454","2015-02-05 18:04:00",22.025,24.0475,213,845.5,0.00393466945182658,1 +"1455","2015-02-05 18:04:59",22,24.1,0,844,0.00393726783361537,0 +"1456","2015-02-05 18:06:00",22,24.1,0,846.666666666667,0.00393726783361537,0 +"1457","2015-02-05 18:07:00",22,24.1,0,852,0.00393726783361537,0 +"1458","2015-02-05 18:08:00",21.945,23.795,0,851,0.00387402519658295,0 +"1459","2015-02-05 18:08:59",21.89,23.8566666666667,0,824.666666666667,0.00387102964890651,0 +"1460","2015-02-05 18:10:00",21.89,23.84,0,817,0.00386830846395102,0 +"1461","2015-02-05 18:10:59",21.84,23.745,0,813.666666666667,0.0038409808590766,0 +"1462","2015-02-05 18:11:59",21.84,23.745,0,805,0.0038409808590766,0 +"1463","2015-02-05 18:13:00",21.79,23.7,0,807,0.00382189406984404,0 +"1464","2015-02-05 18:14:00",21.79,23.745,0,800,0.00382919550526379,0 +"1465","2015-02-05 18:15:00",21.79,23.7,0,781,0.00382189406984404,0 +"1466","2015-02-05 18:16:00",21.745,23.55,0,776.5,0.00378706555977436,0 +"1467","2015-02-05 18:16:59",21.7,23.7,0,771,0.00380080124740326,0 +"1468","2015-02-05 18:17:59",21.7,23.6666666666667,0,775,0.00379542291602805,0 +"1469","2015-02-05 18:19:00",21.7,23.6666666666667,0,771,0.00379542291602805,0 +"1470","2015-02-05 18:20:00",21.7,23.39,0,763,0.00375078633331977,0 +"1471","2015-02-05 18:21:00",21.7,23.55,0,755,0.0037765994842066,0 +"1472","2015-02-05 18:22:00",21.6,23.6,0,754,0.00376144999584149,0 +"1473","2015-02-05 18:23:00",21.7,23.6,0,755,0.0037846665306114,0 +"1474","2015-02-05 18:23:59",21.6,23.3933333333333,0,754.666666666667,0.00372831330419356,0 +"1475","2015-02-05 18:24:59",21.6,23.55,0,751.5,0.00375343273247922,0 +"1476","2015-02-05 18:26:00",21.6,23.5,0,748.5,0.00374541567454887,0 +"1477","2015-02-05 18:27:00",21.55,23.5,0,745.5,0.00373390411283325,0 +"1478","2015-02-05 18:28:00",21.55,23.445,0,749,0.00372511285152923,0 +"1479","2015-02-05 18:29:00",21.5666666666667,23.5,0,746.666666666667,0.00373773783144013,0 +"1480","2015-02-05 18:29:59",21.55,23.5,0,738.5,0.00373390411283325,0 +"1481","2015-02-05 18:30:59",21.5,23.35,0,732.5,0.00369852230282477,0 +"1482","2015-02-05 18:32:00",21.5,23.26,0,725.5,0.00368418231912537,0 +"1483","2015-02-05 18:33:00",21.5,23.245,0,711.666666666667,0.00368179238574585,0 +"1484","2015-02-05 18:34:00",21.5,23.23,0,705.666666666667,0.00367940247062397,0 +"1485","2015-02-05 18:35:00",21.5,23.05,0,702.5,0.00365072491318157,0 +"1486","2015-02-05 18:36:00",21.39,23.05,0,702.5,0.00362606467823633,0 +"1487","2015-02-05 18:36:59",21.39,22.945,0,698.5,0.00360945096033576,0 +"1488","2015-02-05 18:38:00",21.39,22.79,0,698,0.00358492756080275,0 +"1489","2015-02-05 18:39:00",21.39,22.695,0,677.5,0.00356989804039301,0 +"1490","2015-02-05 18:40:00",21.34,22.55,0,672,0.00353604389078825,0 +"1491","2015-02-05 18:40:59",21.29,22.6,0,666.5,0.00353301845675043,0 +"1492","2015-02-05 18:42:00",21.3233333333333,22.5333333333333,0,664.333333333333,0.00352978627422652,0 +"1493","2015-02-05 18:42:59",21.34,22.395,0,660.5,0.00351160126925951,0 +"1494","2015-02-05 18:43:59",21.34,22.395,0,654,0.00351160126925951,0 +"1495","2015-02-05 18:45:00",21.29,21.945,0,650,0.00343005878900538,0 +"1496","2015-02-05 18:46:00",21.29,21.85,0,635.5,0.00341512852175991,0 +"1497","2015-02-05 18:47:00",21.245,21.745,0,634,0.00338920785984853,0 +"1498","2015-02-05 18:48:00",21.2,21.745,0,631.5,0.00337981124215862,0 +"1499","2015-02-05 18:49:00",21.2,21.995,0,631,0.00341888216301548,0 +"1500","2015-02-05 18:49:59",21.245,22.1,0,637.5,0.00344484512558914,0 +"1501","2015-02-05 18:51:00",21.29,22.1,0,640,0.00345442022913307,0 +"1502","2015-02-05 18:52:00",21.29,21.8633333333333,0,638.666666666667,0.00341722395486199,0 +"1503","2015-02-05 18:53:00",21.29,21.5,0,628,0.00336012842435259,0 +"1504","2015-02-05 18:53:59",21.29,21.34,0,617,0.00333498874445521,0 +"1505","2015-02-05 18:55:00",21.2,21.1666666666667,0,612.333333333333,0.00328944588440249,0 +"1506","2015-02-05 18:55:59",21.2,21.5666666666667,0,609,0.00335194363493422,0 +"1507","2015-02-05 18:56:59",21.2,21.6,0,616,0.00335715234475089,0 +"1508","2015-02-05 18:58:00",21.2,21.55,0,614,0.00334933931256394,0 +"1509","2015-02-05 18:59:00",21.2,21.445,0,613.5,0.00333293258042035,0 +"1510","2015-02-05 19:00:00",21.2,21.195,0,611.5,0.00329387239730685,0 +"1511","2015-02-05 19:01:00",21.2,21.2,0,600,0.00329465355314865,0 +"1512","2015-02-05 19:01:59",21.2,21.3566666666667,0,599,0.00331913075822666,0 +"1513","2015-02-05 19:02:59",21.2,21.0666666666667,0,592.666666666667,0.00327382339860608,0 +"1514","2015-02-05 19:04:00",21.2,21.23,0,593,0.00329934052918621,0 +"1515","2015-02-05 19:05:00",21.2,21.2,0,586,0.00329465355314865,0 +"1516","2015-02-05 19:06:00",21.2,21.2,0,585,0.00329465355314865,0 +"1517","2015-02-05 19:07:00",21.29,21.1,0,592.5,0.00329728301421794,0 +"1518","2015-02-05 19:08:00",21.29,21.1,0,593,0.00329728301421794,0 +"1519","2015-02-05 19:08:59",21.29,20.89,0,583,0.00326429423008482,0 +"1520","2015-02-05 19:09:59",21.29,20.65,0,579.333333333333,0.00322659702442179,0 +"1521","2015-02-05 19:11:00",21.29,20.89,0,578,0.00326429423008482,0 +"1522","2015-02-05 19:12:00",21.29,20.7475,0,570.5,0.00324191096599299,0 +"1523","2015-02-05 19:13:00",21.29,20.795,0,571,0.0032493718759597,0 +"1524","2015-02-05 19:14:00",21.29,20.65,0,571,0.00322659702442179,0 +"1525","2015-02-05 19:14:59",21.245,20.79,0,563.5,0.00323958489857107,0 +"1526","2015-02-05 19:15:59",21.2,20.495,0,560.5,0.00318452983970222,0 +"1527","2015-02-05 19:17:00",21.2,20.3933333333333,0,556,0.00316865231514498,0 +"1528","2015-02-05 19:18:00",21.2,20.3225,0,550.25,0.00315759058208409,0 +"1529","2015-02-05 19:19:00",21.2,20.1225,0,544.5,0.0031263595663672,0 +"1530","2015-02-05 19:20:00",21.2,20.2266666666667,0,547.666666666667,0.00314262533100127,0 +"1531","2015-02-05 19:21:00",21.2,20,0,545,0.00310723211014337,0 +"1532","2015-02-05 19:21:59",21.1,20.2,0,536,0.00311915461141429,0 +"1533","2015-02-05 19:23:00",21.1,20.1,0,538,0.00310363620313794,0 +"1534","2015-02-05 19:24:00",21.1,20.195,0,539.5,0.00311837867270114,0 +"1535","2015-02-05 19:25:00",21.1,20.245,0,542.5,0.0031261381465169,0 +"1536","2015-02-05 19:25:59",21.15,20.245,0,539,0.00313580003168149,0 +"1537","2015-02-05 19:27:00",21.1,20.0333333333333,0,532.333333333333,0.00309329102565789,0 +"1538","2015-02-05 19:27:59",21.15,20,0,534,0.00309766236194505,0 +"1539","2015-02-05 19:28:59",21.15,20,0,538.5,0.00309766236194505,0 +"1540","2015-02-05 19:30:00",21.2,19.9633333333333,0,538,0.00310150711276261,0 +"1541","2015-02-05 19:31:00",21.2,19.995,0,539.5,0.00310645142250747,0 +"1542","2015-02-05 19:32:00",21.2,19.895,0,531,0.00309083807927498,0 +"1543","2015-02-05 19:33:00",21.2,20,0,526.5,0.00310723211014337,0 +"1544","2015-02-05 19:34:00",21.2,19.9633333333333,0,522,0.00310150711276261,0 +"1545","2015-02-05 19:34:59",21.2,19.895,0,526,0.00309083807927498,0 +"1546","2015-02-05 19:36:00",21.2,19.945,0,522.666666666667,0.00309864465339602,0 +"1547","2015-02-05 19:37:00",21.2,19.84,0,525.333333333333,0.00308225107294704,0 +"1548","2015-02-05 19:38:00",21.2,19.79,0,516.333333333333,0.0030744449082821,0 +"1549","2015-02-05 19:38:59",21.15,19.65,0,520,0.00304318804800837,0 +"1550","2015-02-05 19:40:00",21.1,19.795,0,515.5,0.00305630981621369,0 +"1551","2015-02-05 19:40:59",21.1,19.79,0,513.5,0.00305553403350672,0 +"1552","2015-02-05 19:41:59",21.1,19.79,0,517,0.00305553403350672,0 +"1553","2015-02-05 19:43:00",21.1,19.79,0,517,0.00305553403350672,0 +"1554","2015-02-05 19:44:00",21.175,19.79,0,514.75,0.00306970755834064,0 +"1555","2015-02-05 19:45:00",21.2,19.63,0,510,0.00304946649150167,0 +"1556","2015-02-05 19:46:00",21.1,19.29,0,503.5,0.00297796548644197,0 +"1557","2015-02-05 19:46:59",21.1,19.39,0,502,0.0029934776556324,0 +"1558","2015-02-05 19:47:59",21.1,19.65,0,498.5,0.00303381289952296,0 +"1559","2015-02-05 19:49:00",21.075,19.65,0,498.5,0.00302913486470159,0 +"1560","2015-02-05 19:50:00",21.05,19.6,0,502.5,0.00301673001937995,0 +"1561","2015-02-05 19:51:00",21.1,19.7,0,505,0.00304157027407045,0 +"1562","2015-02-05 19:52:00",21.15,19.55,0,506.5,0.00302762570213065,0 +"1563","2015-02-05 19:53:00",21.15,19.445,0,500,0.0030112860729703,0 +"1564","2015-02-05 19:53:59",21.2,19.6,0,496,0.00304478326059916,0 +"1565","2015-02-05 19:54:59",21.175,19.4425,0,499.25,0.00301554409181566,0 +"1566","2015-02-05 19:56:00",21.1666666666667,19.4966666666667,0,497.666666666667,0.00302243214481241,0 +"1567","2015-02-05 19:57:00",21.15,19.55,0,497,0.00302762570213065,0 +"1568","2015-02-05 19:58:00",21.1,19.5,0,498,0.00301054193115634,0 +"1569","2015-02-05 19:59:00",21.2,19.39,0,495,0.00301200260918866,0 +"1570","2015-02-05 19:59:59",21.2,19.34,0,491.5,0.0030041981989707,0 +"1571","2015-02-05 20:00:59",21.15,19.395,0,491,0.00300350559744339,0 +"1572","2015-02-05 20:02:00",21.1666666666667,19.5,0,493,0.00302295139961112,0 +"1573","2015-02-05 20:03:00",21.1,19.5,0,489,0.00301054193115634,0 +"1574","2015-02-05 20:04:00",21.2,19.445,0,485.5,0.00302058768554898,0 +"1575","2015-02-05 20:05:00",21.2,19.39,0,488.5,0.00301200260918866,0 +"1576","2015-02-05 20:06:00",21.2,19.39,0,486,0.00301200260918866,0 +"1577","2015-02-05 20:06:59",21.2,19.445,0,488.5,0.00302058768554898,0 +"1578","2015-02-05 20:08:00",21.2,19.29,0,490,0.00299639398365479,0 +"1579","2015-02-05 20:09:00",21.2,19.39,0,491,0.00301200260918866,0 +"1580","2015-02-05 20:10:00",21.2,19.245,0,487,0.00298937035650568,0 +"1581","2015-02-05 20:10:59",21.2,19.34,0,485.5,0.0030041981989707,0 +"1582","2015-02-05 20:12:00",21.2,19.29,0,484.5,0.00299639398365479,0 +"1583","2015-02-05 20:12:59",21.2,19.29,0,491,0.00299639398365479,0 +"1584","2015-02-05 20:13:59",21.2,19.29,0,485,0.00299639398365479,0 +"1585","2015-02-05 20:15:00",21.2,19.29,0,484.5,0.00299639398365479,0 +"1586","2015-02-05 20:16:00",21.2,19.29,0,482,0.00299639398365479,0 +"1587","2015-02-05 20:17:00",21.2,19.315,0,491.25,0.00300029606695045,0 +"1588","2015-02-05 20:18:00",21.2,19.34,0,486.5,0.0030041981989707,0 +"1589","2015-02-05 20:19:00",21.2,19.39,0,481,0.00301200260918866,0 +"1590","2015-02-05 20:19:59",21.2,19.39,0,480,0.00301200260918866,0 +"1591","2015-02-05 20:21:00",21.2,19.34,0,483.5,0.0030041981989707,0 +"1592","2015-02-05 20:22:00",21.2,19.39,0,481.333333333333,0.00301200260918866,0 +"1593","2015-02-05 20:23:00",21.2,19.39,0,484.333333333333,0.00301200260918866,0 +"1594","2015-02-05 20:23:59",21.2,19.39,0,479.666666666667,0.00301200260918866,0 +"1595","2015-02-05 20:25:00",21.2,19.39,0,479,0.00301200260918866,0 +"1596","2015-02-05 20:25:59",21.2,19.39,0,477.5,0.00301200260918866,0 +"1597","2015-02-05 20:26:59",21.2,19.39,0,483,0.00301200260918866,0 +"1598","2015-02-05 20:28:00",21.15,19.39,0,482,0.00300272756054479,0 +"1599","2015-02-05 20:29:00",21.2,19.39,0,483.25,0.00301200260918866,0 +"1600","2015-02-05 20:30:00",21.2,19.39,0,477,0.00301200260918866,0 +"1601","2015-02-05 20:31:00",21.2,19.3566666666667,0,479,0.00300679964738721,0 +"1602","2015-02-05 20:31:59",21.2,19.39,0,482.5,0.00301200260918866,0 +"1603","2015-02-05 20:32:59",21.2,19.39,0,474,0.00301200260918866,0 +"1604","2015-02-05 20:34:00",21.2,19.39,0,473,0.00301200260918866,0 +"1605","2015-02-05 20:35:00",21.2,19.39,0,472,0.00301200260918866,0 +"1606","2015-02-05 20:36:00",21.2,19.39,0,472.5,0.00301200260918866,0 +"1607","2015-02-05 20:37:00",21.2,19.445,0,475,0.00302058768554898,0 +"1608","2015-02-05 20:38:00",21.2,19.39,0,475,0.00301200260918866,0 +"1609","2015-02-05 20:38:59",21.2,19.445,0,477.5,0.00302058768554898,0 +"1610","2015-02-05 20:39:59",21.15,19.5,0,474,0.00301984481979203,0 +"1611","2015-02-05 20:41:00",21.1666666666667,19.5,0,474.666666666667,0.00302295139961112,0 +"1612","2015-02-05 20:42:00",21.1,19.5,0,470.5,0.00301054193115634,0 +"1613","2015-02-05 20:43:00",21.1,19.5,0,474.333333333333,0.00301054193115634,0 +"1614","2015-02-05 20:44:00",21.1,19.5,0,483,0.00301054193115634,0 +"1615","2015-02-05 20:44:59",21.1,19.6,0,484,0.00302605571752623,0 +"1616","2015-02-05 20:45:59",21.0333333333333,19.5333333333333,0,479.333333333333,0.00300332715277666,0 +"1617","2015-02-05 20:47:00",21,19.6,0,479.5,0.00300742962468002,0 +"1618","2015-02-05 20:48:00",21,19.6,0,473,0.00300742962468002,0 +"1619","2015-02-05 20:49:00",21,19.6,0,470,0.00300742962468002,0 +"1620","2015-02-05 20:50:00",21,19.6,0,464,0.00300742962468002,0 +"1621","2015-02-05 20:51:00",21,19.7,0,463.5,0.00302284822358619,0 +"1622","2015-02-05 20:51:59",21,19.7,0,467.5,0.00302284822358619,0 +"1623","2015-02-05 20:53:00",21,19.7,0,476,0.00302284822358619,0 +"1624","2015-02-05 20:54:00",21,19.76,0,474,0.00303209974808914,0 +"1625","2015-02-05 20:55:00",21,19.79,0,471,0.00303672561304647,0 +"1626","2015-02-05 20:55:59",21,19.79,0,472,0.00303672561304647,0 +"1627","2015-02-05 20:57:00",21,19.79,0,472,0.00303672561304647,0 +"1628","2015-02-05 20:57:59",21,19.79,0,474.25,0.00303672561304647,0 +"1629","2015-02-05 20:58:59",20.9725,19.79,0,473,0.00303157119548328,0 +"1630","2015-02-05 21:00:00",21,19.79,0,469,0.00303672561304647,0 +"1631","2015-02-05 21:01:00",20.9633333333333,19.79,0,472.666666666667,0.00302985476836808,0 +"1632","2015-02-05 21:02:00",21,19.79,0,473,0.00303672561304647,0 +"1633","2015-02-05 21:03:00",20.89,19.79,0,471.5,0.00301615411603875,0 +"1634","2015-02-05 21:04:00",20.9633333333333,19.79,0,471.333333333333,0.00302985476836808,0 +"1635","2015-02-05 21:04:59",21,19.79,0,469,0.00303672561304647,0 +"1636","2015-02-05 21:06:00",20.89,19.89,0,471,0.00303146919477111,0 +"1637","2015-02-05 21:07:00",20.89,19.84,0,470,0.00302381156158785,0 +"1638","2015-02-05 21:08:00",20.89,19.89,0,469.5,0.00303146919477111,0 +"1639","2015-02-05 21:08:59",20.89,19.89,0,464,0.00303146919477111,0 +"1640","2015-02-05 21:10:00",20.89,19.89,0,467,0.00303146919477111,0 +"1641","2015-02-05 21:10:59",20.89,19.9266666666667,0,472,0.00303708491169476,0 +"1642","2015-02-05 21:11:59",20.89,19.945,0,469.5,0.00303989280799839,0 +"1643","2015-02-05 21:13:00",20.89,20,0,470.5,0.00304831664828052,0 +"1644","2015-02-05 21:14:00",20.89,20,0,470,0.00304831664828052,0 +"1645","2015-02-05 21:15:00",20.89,20,0,469,0.00304831664828052,0 +"1646","2015-02-05 21:16:00",20.89,20,0,468.5,0.00304831664828052,0 +"1647","2015-02-05 21:16:59",20.89,20,0,467.333333333333,0.00304831664828052,0 +"1648","2015-02-05 21:17:59",20.89,20,0,467,0.00304831664828052,0 +"1649","2015-02-05 21:19:00",20.89,20,0,464,0.00304831664828052,0 +"1650","2015-02-05 21:20:00",20.89,20,0,462,0.00304831664828052,0 +"1651","2015-02-05 21:21:00",20.89,20,0,466,0.00304831664828052,0 +"1652","2015-02-05 21:22:00",20.89,20,0,465.5,0.00304831664828052,0 +"1653","2015-02-05 21:23:00",20.79,20,0,464,0.0030295225859519,0 +"1654","2015-02-05 21:23:59",20.89,20,0,469.666666666667,0.00304831664828052,0 +"1655","2015-02-05 21:24:59",20.89,20.1,0,469.5,0.00306363330326149,0 +"1656","2015-02-05 21:26:00",20.89,20.1,0,472,0.00306363330326149,0 +"1657","2015-02-05 21:27:00",20.89,20.1,0,464.5,0.00306363330326149,0 +"1658","2015-02-05 21:28:00",20.89,20.1,0,467,0.00306363330326149,0 +"1659","2015-02-05 21:29:00",20.89,20.1,0,467,0.00306363330326149,0 +"1660","2015-02-05 21:29:59",20.89,20.1,0,462,0.00306363330326149,0 +"1661","2015-02-05 21:30:59",20.89,20.15,0,464.5,0.00307129191225357,0 +"1662","2015-02-05 21:32:00",20.79,20.05,0,460,0.00303713337418589,0 +"1663","2015-02-05 21:33:00",20.89,20.2,0,457,0.00307895070892257,0 +"1664","2015-02-05 21:34:00",20.79,20.1,0,461,0.00304474434777049,0 +"1665","2015-02-05 21:35:00",20.79,20.1,0,462,0.00304474434777049,0 +"1666","2015-02-05 21:36:00",20.79,20.15,0,463.5,0.00305235550671248,0 +"1667","2015-02-05 21:36:59",20.79,20.2,0,461.5,0.00305996685101862,0 +"1668","2015-02-05 21:38:00",20.79,20.2,0,461.5,0.00305996685101862,0 +"1669","2015-02-05 21:39:00",20.79,20.2,0,458,0.00305996685101862,0 +"1670","2015-02-05 21:40:00",20.79,20.2,0,460,0.00305996685101862,0 +"1671","2015-02-05 21:40:59",20.79,20.245,0,460,0.00306681721938609,0 +"1672","2015-02-05 21:42:00",20.79,20.29,0,460.5,0.00307366773790896,0 +"1673","2015-02-05 21:42:59",20.745,20.29,0,460,0.0030651203870119,0 +"1674","2015-02-05 21:43:59",20.79,20.29,0,457,0.00307366773790896,0 +"1675","2015-02-05 21:45:00",20.745,20.34,0,460.5,0.00307271097901383,0 +"1676","2015-02-05 21:46:00",20.7,20.39,0,461,0.00307173289826042,0 +"1677","2015-02-05 21:47:00",20.745,20.39,0,458.5,0.00308030175537347,0 +"1678","2015-02-05 21:48:00",20.7,20.39,0,461.333333333333,0.00307173289826042,0 +"1679","2015-02-05 21:49:00",20.7,20.39,0,457.5,0.00307173289826042,0 +"1680","2015-02-05 21:49:59",20.7,20.39,0,455,0.00307173289826042,0 +"1681","2015-02-05 21:51:00",20.7,20.445,0,461.5,0.00308005962232409,0 +"1682","2015-02-05 21:52:00",20.7,20.445,0,461,0.00308005962232409,0 +"1683","2015-02-05 21:53:00",20.7,20.5,0,460.5,0.00308838656823511,0 +"1684","2015-02-05 21:53:59",20.7,20.5,0,461,0.00308838656823511,0 +"1685","2015-02-05 21:55:00",20.7,20.55,0,459.5,0.00309595671158295,0 +"1686","2015-02-05 21:55:59",20.7,20.6,0,463,0.00310352703828971,0 +"1687","2015-02-05 21:56:59",20.7,20.6,0,463.5,0.00310352703828971,0 +"1688","2015-02-05 21:58:00",20.7,20.6,0,463,0.00310352703828971,0 +"1689","2015-02-05 21:59:00",20.7,20.6,0,464,0.00310352703828971,0 +"1690","2015-02-05 22:00:00",20.7,20.6,0,462.5,0.00310352703828971,0 +"1691","2015-02-05 22:01:00",20.7,20.6,0,457.666666666667,0.00310352703828971,0 +"1692","2015-02-05 22:01:59",20.6333333333333,20.6333333333333,0,460,0.00309576545382003,0 +"1693","2015-02-05 22:02:59",20.7,20.7,0,460,0.00311866824180661,0 +"1694","2015-02-05 22:04:00",20.65,20.65,0,458.5,0.00310147891526391,0 +"1695","2015-02-05 22:05:00",20.6,20.6,0,461,0.00308436294447443,0 +"1696","2015-02-05 22:06:00",20.65,20.65,0,460,0.00310147891526391,0 +"1697","2015-02-05 22:07:00",20.6,20.6,0,454,0.00308436294447443,0 +"1698","2015-02-05 22:08:00",20.6,20.7,0,451.333333333333,0.00309941018839007,0 +"1699","2015-02-05 22:08:59",20.6,20.7,0,457,0.00309941018839007,0 +"1700","2015-02-05 22:09:59",20.6,20.7,0,454.5,0.00309941018839007,0 +"1701","2015-02-05 22:11:00",20.6,20.7,0,460,0.00309941018839007,0 +"1702","2015-02-05 22:12:00",20.6,20.745,0,458.5,0.00310618168450477,0 +"1703","2015-02-05 22:13:00",20.6,20.745,0,453.5,0.00310618168450477,0 +"1704","2015-02-05 22:14:00",20.6,20.79,0,457,0.00311295332732784,0 +"1705","2015-02-05 22:14:59",20.55,20.79,0,450.5,0.00310332151583221,0 +"1706","2015-02-05 22:15:59",20.6,20.79,0,454.5,0.00311295332732784,0 +"1707","2015-02-05 22:17:00",20.6,20.79,0,463,0.00311295332732784,0 +"1708","2015-02-05 22:18:00",20.6,20.79,0,459,0.00311295332732784,0 +"1709","2015-02-05 22:19:00",20.6,20.84,0,452.5,0.00312047754698019,0 +"1710","2015-02-05 22:20:00",20.6,20.89,0,451,0.00312800194776641,0 +"1711","2015-02-05 22:21:00",20.55,20.89,0,446,0.00311832334195416,0 +"1712","2015-02-05 22:21:59",20.6,20.84,0,449.5,0.00312047754698019,0 +"1713","2015-02-05 22:23:00",20.55,20.89,0,449.5,0.00311832334195416,0 +"1714","2015-02-05 22:24:00",20.6,20.89,0,450,0.00312800194776641,0 +"1715","2015-02-05 22:25:00",20.6,20.89,0,453.5,0.00312800194776641,0 +"1716","2015-02-05 22:25:59",20.6,20.89,0,458.5,0.00312800194776641,0 +"1717","2015-02-05 22:27:00",20.575,20.9175,0,459.5,0.00312729140199668,0 +"1718","2015-02-05 22:27:59",20.6,20.89,0,457,0.00312800194776641,0 +"1719","2015-02-05 22:28:59",20.5,20.945,0,458,0.00311689676029087,0 +"1720","2015-02-05 22:30:00",20.5,21,0,453,0.00312512262022728,0 +"1721","2015-02-05 22:31:00",20.55,21,0,450.5,0.00313482618237526,0 +"1722","2015-02-05 22:32:00",20.6,21,0,455,0.00314455626711953,0 +"1723","2015-02-05 22:33:00",20.55,21,0,453,0.00313482618237526,0 +"1724","2015-02-05 22:34:00",20.55,21,0,454.5,0.00313482618237526,0 +"1725","2015-02-05 22:34:59",20.5,21,0,455,0.00312512262022728,0 +"1726","2015-02-05 22:36:00",20.6,21,0,452,0.00314455626711953,0 +"1727","2015-02-05 22:37:00",20.5666666666667,21.0333333333333,0,456,0.00314307282215576,0 +"1728","2015-02-05 22:38:00",20.55,21.05,0,454,0.00314232776152385,0 +"1729","2015-02-05 22:38:59",20.5,21.1,0,453,0.00314007928385138,0 +"1730","2015-02-05 22:40:00",20.55,21.1,0,460.5,0.00314982952071157,0 +"1731","2015-02-05 22:40:59",20.6,21.1,0,455,0.00315960640919795,0 +"1732","2015-02-05 22:41:59",20.5,21.1,0,452,0.00314007928385138,0 +"1733","2015-02-05 22:43:00",20.55,21.1,0,453,0.00314982952071157,0 +"1734","2015-02-05 22:44:00",20.55,21.1,0,454,0.00314982952071157,0 +"1735","2015-02-05 22:45:00",20.5,21.1,0,454.5,0.00314007928385138,0 +"1736","2015-02-05 22:46:00",20.5,21.1,0,455,0.00314007928385138,0 +"1737","2015-02-05 22:46:59",20.5,21.1,0,454,0.00314007928385138,0 +"1738","2015-02-05 22:47:59",20.55,21.1,0,454,0.00314982952071157,0 +"1739","2015-02-05 22:49:00",20.5,21.1,0,447,0.00314007928385138,0 +"1740","2015-02-05 22:50:00",20.5,21.1,0,454,0.00314007928385138,0 +"1741","2015-02-05 22:51:00",20.5333333333333,21.2,0,455.666666666667,0.00316156496802361,0 +"1742","2015-02-05 22:52:00",20.5,21.2,0,456,0.00315503666319505,0 +"1743","2015-02-05 22:53:00",20.5,21.2,0,453,0.00315503666319505,0 +"1744","2015-02-05 22:53:59",20.5,21.2,0,452,0.00315503666319505,0 +"1745","2015-02-05 22:54:59",20.5,21.2,0,446,0.00315503666319505,0 +"1746","2015-02-05 22:56:00",20.5,21.2,0,452.333333333333,0.00315503666319505,0 +"1747","2015-02-05 22:57:00",20.5,21.245,0,451,0.00316176771741689,0 +"1748","2015-02-05 22:58:00",20.5,21.2,0,449,0.00315503666319505,0 +"1749","2015-02-05 22:59:00",20.5,21.2,0,447,0.00315503666319505,0 +"1750","2015-02-05 22:59:59",20.5,21.245,0,450,0.00316176771741689,0 +"1751","2015-02-05 23:00:59",20.5,21.29,0,449,0.00316849891658704,0 +"1752","2015-02-05 23:02:00",20.5,21.26,0,448.333333333333,0.00316401143436801,0 +"1753","2015-02-05 23:03:00",20.5,21.2675,0,443.75,0.00316513329888314,0 +"1754","2015-02-05 23:04:00",20.5,21.29,0,442.5,0.00316849891658704,0 +"1755","2015-02-05 23:05:00",20.5,21.29,0,444.5,0.00316849891658704,0 +"1756","2015-02-05 23:06:00",20.5,21.29,0,446.25,0.00316849891658704,0 +"1757","2015-02-05 23:06:59",20.5,21.29,0,448,0.00316849891658704,0 +"1758","2015-02-05 23:08:00",20.5,21.29,0,451,0.00316849891658704,0 +"1759","2015-02-05 23:09:00",20.5,21.29,0,452.333333333333,0.00316849891658704,0 +"1760","2015-02-05 23:10:00",20.5,21.29,0,447,0.00316849891658704,0 +"1761","2015-02-05 23:10:59",20.445,21.29,0,446.5,0.00315770708296947,0 +"1762","2015-02-05 23:12:00",20.5,21.29,0,442,0.00316849891658704,0 +"1763","2015-02-05 23:12:59",20.5,21.29,0,452,0.00316849891658704,0 +"1764","2015-02-05 23:13:59",20.39,21.29,0,450,0.00314694763447223,0 +"1765","2015-02-05 23:15:00",20.445,21.29,0,443.5,0.00315770708296947,0 +"1766","2015-02-05 23:16:00",20.39,21.29,0,443,0.00314694763447223,0 +"1767","2015-02-05 23:17:00",20.4266666666667,21.29,0,450,0.00315411700592178,0 +"1768","2015-02-05 23:18:00",20.39,21.29,0,445.666666666667,0.00314694763447223,0 +"1769","2015-02-05 23:19:00",20.39,21.29,0,443.666666666667,0.00314694763447223,0 +"1770","2015-02-05 23:19:59",20.39,21.29,0,445.333333333333,0.00314694763447223,0 +"1771","2015-02-05 23:21:00",20.39,21.29,0,449,0.00314694763447223,0 +"1772","2015-02-05 23:22:00",20.39,21.29,0,444.5,0.00314694763447223,0 +"1773","2015-02-05 23:23:00",20.39,21.29,0,445.5,0.00314694763447223,0 +"1774","2015-02-05 23:23:59",20.39,21.29,0,447,0.00314694763447223,0 +"1775","2015-02-05 23:25:00",20.39,21.29,0,446.5,0.00314694763447223,0 +"1776","2015-02-05 23:25:59",20.39,21.29,0,451,0.00314694763447223,0 +"1777","2015-02-05 23:26:59",20.39,21.29,0,448,0.00314694763447223,0 +"1778","2015-02-05 23:28:00",20.39,21.29,0,450,0.00314694763447223,0 +"1779","2015-02-05 23:29:00",20.39,21.29,0,442.666666666667,0.00314694763447223,0 +"1780","2015-02-05 23:30:00",20.39,21.29,0,445,0.00314694763447223,0 +"1781","2015-02-05 23:31:00",20.39,21.29,0,444.5,0.00314694763447223,0 +"1782","2015-02-05 23:31:59",20.3566666666667,21.29,0,441.666666666667,0.00314044248260255,0 +"1783","2015-02-05 23:32:59",20.3566666666667,21.29,0,442.333333333333,0.00314044248260255,0 +"1784","2015-02-05 23:34:00",20.39,21.29,0,441,0.00314694763447223,0 +"1785","2015-02-05 23:35:00",20.29,21.29,0,440.5,0.00312746769855435,0 +"1786","2015-02-05 23:36:00",20.39,21.29,0,447,0.00314694763447223,0 +"1787","2015-02-05 23:37:00",20.34,21.29,0,439.5,0.00313719435010793,0 +"1788","2015-02-05 23:38:00",20.29,21.29,0,444,0.00312746769855435,0 +"1789","2015-02-05 23:38:59",20.29,21.29,0,445.5,0.00312746769855435,0 +"1790","2015-02-05 23:39:59",20.29,21.29,0,446.666666666667,0.00312746769855435,0 +"1791","2015-02-05 23:41:00",20.3233333333333,21.29,0,444.333333333333,0.00313394917681341,0 +"1792","2015-02-05 23:42:00",20.29,21.29,0,446.5,0.00312746769855435,0 +"1793","2015-02-05 23:43:00",20.3233333333333,21.29,0,449.333333333333,0.00313394917681341,0 +"1794","2015-02-05 23:44:00",20.29,21.29,0,445,0.00312746769855435,0 +"1795","2015-02-05 23:44:59",20.29,21.29,0,447,0.00312746769855435,0 +"1796","2015-02-05 23:45:59",20.29,21.29,0,443.5,0.00312746769855435,0 +"1797","2015-02-05 23:47:00",20.29,21.29,0,447,0.00312746769855435,0 +"1798","2015-02-05 23:48:00",20.29,21.29,0,445,0.00312746769855435,0 +"1799","2015-02-05 23:49:00",20.29,21.29,0,443,0.00312746769855435,0 +"1800","2015-02-05 23:50:00",20.29,21.29,0,446,0.00312746769855435,0 +"1801","2015-02-05 23:51:00",20.245,21.245,0,438,0.00311211147465291,0 +"1802","2015-02-05 23:51:59",20.29,21.29,0,435.333333333333,0.00312746769855435,0 +"1803","2015-02-05 23:53:00",20.29,21.29,0,443,0.00312746769855435,0 +"1804","2015-02-05 23:54:00",20.29,21.29,0,441,0.00312746769855435,0 +"1805","2015-02-05 23:55:00",20.29,21.29,0,439.5,0.00312746769855435,0 +"1806","2015-02-05 23:55:59",20.2225,21.2225,0,445,0.00310445542556718,0 +"1807","2015-02-05 23:57:00",20.2,21.2,0,442.5,0.0030968140539317,0 +"1808","2015-02-05 23:57:59",20.2,21.2,0,443.5,0.0030968140539317,0 +"1809","2015-02-05 23:58:59",20.2,21.2,0,444,0.0030968140539317,0 +"1810","2015-02-06 00:00:00",20.2,21.29,0,438,0.00311002664087112,0 +"1811","2015-02-06 00:01:00",20.2,21.2,0,439,0.0030968140539317,0 +"1812","2015-02-06 00:02:00",20.2,21.29,0,441.5,0.00311002664087112,0 +"1813","2015-02-06 00:03:00",20.2,21.29,0,444,0.00311002664087112,0 +"1814","2015-02-06 00:04:00",20.2,21.29,0,446.5,0.00311002664087112,0 +"1815","2015-02-06 00:04:59",20.2,21.29,0,446,0.00311002664087112,0 +"1816","2015-02-06 00:06:00",20.2,21.29,0,447,0.00311002664087112,0 +"1817","2015-02-06 00:07:00",20.2,21.29,0,447,0.00311002664087112,0 +"1818","2015-02-06 00:08:00",20.2,21.29,0,446.333333333333,0.00311002664087112,0 +"1819","2015-02-06 00:08:59",20.2,21.29,0,445.75,0.00311002664087112,0 +"1820","2015-02-06 00:10:00",20.2,21.29,0,445,0.00311002664087112,0 +"1821","2015-02-06 00:10:59",20.2,21.29,0,444.5,0.00311002664087112,0 +"1822","2015-02-06 00:11:59",20.1666666666667,21.23,0,446.333333333333,0.00309479863434179,0 +"1823","2015-02-06 00:13:00",20.15,21.245,0,446.5,0.00309378847081544,0 +"1824","2015-02-06 00:14:00",20.2,21.29,0,448,0.00311002664087112,0 +"1825","2015-02-06 00:15:00",20.15,21.245,0,450,0.00309378847081544,0 +"1826","2015-02-06 00:16:00",20.15,21.29,0,452,0.00310037422883303,0 +"1827","2015-02-06 00:16:59",20.2,21.2,0,449,0.0030968140539317,0 +"1828","2015-02-06 00:17:59",20.15,21.2,0,446.5,0.00308720285156516,0 +"1829","2015-02-06 00:19:00",20.2,21.2,0,446.5,0.0030968140539317,0 +"1830","2015-02-06 00:20:00",20.15,21.2,0,448.5,0.00308720285156516,0 +"1831","2015-02-06 00:21:00",20.1,21.2,0,446,0.0030776179310379,0 +"1832","2015-02-06 00:22:00",20.2,21.2,0,446,0.0030968140539317,0 +"1833","2015-02-06 00:23:00",20.1,21.2,0,441,0.0030776179310379,0 +"1834","2015-02-06 00:23:59",20.1,21.2,0,443,0.0030776179310379,0 +"1835","2015-02-06 00:24:59",20.1,21.2,0,444.333333333333,0.0030776179310379,0 +"1836","2015-02-06 00:26:00",20.1,21,0,444,0.00304844150242455,0 +"1837","2015-02-06 00:27:00",20.1,21.1,0,443,0.00306302937625997,0 +"1838","2015-02-06 00:28:00",20.1,21.1,0,444,0.00306302937625997,0 +"1839","2015-02-06 00:29:00",20.1,21.1,0,447.5,0.00306302937625997,0 +"1840","2015-02-06 00:29:59",20.1,21.1,0,443,0.00306302937625997,0 +"1841","2015-02-06 00:30:59",20.1,21.0666666666667,0,442.333333333333,0.00305816667599024,0 +"1842","2015-02-06 00:32:00",20.1,21.0666666666667,0,444.666666666667,0.00305816667599024,0 +"1843","2015-02-06 00:33:00",20.1,21,0,444.5,0.00304844150242455,0 +"1844","2015-02-06 00:34:00",20.1,21,0,445.333333333333,0.00304844150242455,0 +"1845","2015-02-06 00:35:00",20.1,21,0,446.5,0.00304844150242455,0 +"1846","2015-02-06 00:36:00",20.1,21,0,445,0.00304844150242455,0 +"1847","2015-02-06 00:36:59",20.1,21,0,442,0.00304844150242455,0 +"1848","2015-02-06 00:38:00",20.1666666666667,21,0,439,0.00306110542895263,0 +"1849","2015-02-06 00:39:00",20.2,21,0,441,0.00306745474921589,0 +"1850","2015-02-06 00:40:00",20.2,20.9633333333333,0,445.666666666667,0.00306207250916801,0 +"1851","2015-02-06 00:40:59",20.2,20.89,0,446,0.00305130830713514,0 +"1852","2015-02-06 00:42:00",20.2,20.8566666666667,0,443.666666666667,0.00304641561058731,0 +"1853","2015-02-06 00:42:59",20.2,20.89,0,439,0.00305130830713514,0 +"1854","2015-02-06 00:43:59",20.2,20.79,0,441,0.0030366304472786,0 +"1855","2015-02-06 00:45:00",20.2,20.79,0,442,0.0030366304472786,0 +"1856","2015-02-06 00:46:00",20.2,20.745,0,443.5,0.00303002563524123,0 +"1857","2015-02-06 00:47:00",20.245,20.84,0,443,0.00305249318128504,0 +"1858","2015-02-06 00:48:00",20.245,20.84,0,442,0.00305249318128504,0 +"1859","2015-02-06 00:49:00",20.29,20.89,0,443,0.00306841845549967,0 +"1860","2015-02-06 00:49:59",20.29,20.89,0,444,0.00306841845549967,0 +"1861","2015-02-06 00:51:00",20.29,20.79,0,443,0.0030536578877459,0 +"1862","2015-02-06 00:52:00",20.29,20.79,0,442,0.0030536578877459,0 +"1863","2015-02-06 00:53:00",20.29,20.79,0,443,0.0030536578877459,0 +"1864","2015-02-06 00:53:59",20.29,20.79,0,441,0.0030536578877459,0 +"1865","2015-02-06 00:55:00",20.29,20.79,0,446.333333333333,0.0030536578877459,0 +"1866","2015-02-06 00:55:59",20.29,20.7,0,446,0.00304037397279384,0 +"1867","2015-02-06 00:56:59",20.29,20.7,0,439,0.00304037397279384,0 +"1868","2015-02-06 00:58:00",20.3566666666667,20.7,0,444.333333333333,0.00305298567041732,0 +"1869","2015-02-06 00:59:00",20.29,20.65,0,446,0.00303299426401626,0 +"1870","2015-02-06 01:00:00",20.29,20.7,0,442,0.00304037397279384,0 +"1871","2015-02-06 01:01:00",20.29,20.7,0,441.5,0.00304037397279384,0 +"1872","2015-02-06 01:01:59",20.29,20.7,0,440.5,0.00304037397279384,0 +"1873","2015-02-06 01:02:59",20.29,20.7,0,443.5,0.00304037397279384,0 +"1874","2015-02-06 01:04:00",20.29,20.7,0,440.5,0.00304037397279384,0 +"1875","2015-02-06 01:05:00",20.29,20.7,0,437.5,0.00304037397279384,0 +"1876","2015-02-06 01:06:00",20.29,20.7,0,438,0.00304037397279384,0 +"1877","2015-02-06 01:07:00",20.29,20.7,0,443,0.00304037397279384,0 +"1878","2015-02-06 01:08:00",20.26,20.7,0,443,0.00303471369223494,0 +"1879","2015-02-06 01:08:59",20.29,20.7,0,436.333333333333,0.00304037397279384,0 +"1880","2015-02-06 01:09:59",20.29,20.76,0,438.333333333333,0.00304922985335753,0 +"1881","2015-02-06 01:11:00",20.29,20.7,0,437,0.00304037397279384,0 +"1882","2015-02-06 01:12:00",20.29,20.7,0,439,0.00304037397279384,0 +"1883","2015-02-06 01:13:00",20.245,20.7,0,436,0.00303188703336769,0 +"1884","2015-02-06 01:14:00",20.29,20.7,0,432.5,0.00304037397279384,0 +"1885","2015-02-06 01:14:59",20.23,20.6333333333333,0,435,0.00301925990384447,0 +"1886","2015-02-06 01:15:59",20.245,20.65,0,442,0.00302452802408622,0 +"1887","2015-02-06 01:17:00",20.2,20.6,0,444.5,0.00300874441262578,0 +"1888","2015-02-06 01:18:00",20.29,20.7,0,447,0.00304037397279384,0 +"1889","2015-02-06 01:19:00",20.2,20.6,0,446,0.00300874441262578,0 +"1890","2015-02-06 01:20:00",20.23,20.5666666666667,0,442.333333333333,0.0030094574219121,0 +"1891","2015-02-06 01:21:00",20.245,20.55,0,440,0.00300981052537268,0 +"1892","2015-02-06 01:21:59",20.29,20.6,0,440,0.00302561472949769,0 +"1893","2015-02-06 01:23:00",20.26,20.4966666666667,0,439.666666666667,0.00300476010096927,0 +"1894","2015-02-06 01:24:00",20.29,20.5,0,442,0.00301085618321289,0 +"1895","2015-02-06 01:25:00",20.29,20.55,0,441,0.00301823536923195,0 +"1896","2015-02-06 01:25:59",20.29,20.6,0,441,0.00302561472949769,0 +"1897","2015-02-06 01:27:00",20.29,20.5,0,441.75,0.00301085618321289,0 +"1898","2015-02-06 01:27:59",20.3233333333333,20.5,0,442,0.00301709482512142,0 +"1899","2015-02-06 01:28:59",20.39,20.445,0,443,0.00302143856976684,0 +"1900","2015-02-06 01:30:00",20.39,20.39,0,443,0.0030132710875474,0 +"1901","2015-02-06 01:31:00",20.39,20.29,0,440,0.00299842166673735,0 +"1902","2015-02-06 01:32:00",20.39,20.2,0,441,0.00298505779128509,0 +"1903","2015-02-06 01:33:00",20.39,20.2,0,439,0.00298505779128509,0 +"1904","2015-02-06 01:34:00",20.39,20.2,0,436,0.00298505779128509,0 +"1905","2015-02-06 01:34:59",20.39,20.1,0,433.5,0.00297020971104394,0 +"1906","2015-02-06 01:36:00",20.39,20.1,0,435,0.00297020971104394,0 +"1907","2015-02-06 01:37:00",20.39,20.05,0,434,0.00296278593548514,0 +"1908","2015-02-06 01:38:00",20.34,20.05,0,438.5,0.00295360611721352,0 +"1909","2015-02-06 01:38:59",20.39,20.05,0,440,0.00296278593548514,0 +"1910","2015-02-06 01:40:00",20.39,20,0,439,0.00295536233629246,0 +"1911","2015-02-06 01:40:59",20.39,20,0,440.5,0.00295536233629246,0 +"1912","2015-02-06 01:41:59",20.39,20,0,433,0.00295536233629246,0 +"1913","2015-02-06 01:43:00",20.39,19.945,0,436.5,0.00294719658087589,0 +"1914","2015-02-06 01:44:00",20.5,19.89,0,438,0.00295915170308649,0 +"1915","2015-02-06 01:45:00",20.4266666666667,19.9266666666667,0,438,0.00295118063018497,0 +"1916","2015-02-06 01:46:00",20.5,19.89,0,441,0.00295915170308649,0 +"1917","2015-02-06 01:46:59",20.5,19.89,0,434,0.00295915170308649,0 +"1918","2015-02-06 01:47:59",20.5,19.89,0,439.5,0.00295915170308649,0 +"1919","2015-02-06 01:49:00",20.5,19.89,0,438,0.00295915170308649,0 +"1920","2015-02-06 01:50:00",20.5,19.89,0,435.5,0.00295915170308649,0 +"1921","2015-02-06 01:51:00",20.5,19.89,0,436,0.00295915170308649,0 +"1922","2015-02-06 01:52:00",20.5,19.89,0,439.5,0.00295915170308649,0 +"1923","2015-02-06 01:53:00",20.5,19.89,0,439.5,0.00295915170308649,0 +"1924","2015-02-06 01:53:59",20.5,19.89,0,438.5,0.00295915170308649,0 +"1925","2015-02-06 01:54:59",20.5,19.89,0,435,0.00295915170308649,0 +"1926","2015-02-06 01:56:00",20.5,19.745,0,435,0.00293747732551703,0 +"1927","2015-02-06 01:57:00",20.5,19.79,0,436,0.00294420369559917,0 +"1928","2015-02-06 01:58:00",20.55,19.84,0,433,0.00296084007143347,0 +"1929","2015-02-06 01:59:00",20.5,19.79,0,433.666666666667,0.00294420369559917,0 +"1930","2015-02-06 01:59:59",20.5,19.745,0,431.5,0.00293747732551703,0 +"1931","2015-02-06 02:00:59",20.5,19.65,0,436.5,0.00292327768638439,0 +"1932","2015-02-06 02:02:00",20.5,19.7,0,437,0.00293075110022723,0 +"1933","2015-02-06 02:03:00",20.6,19.6,0,435,0.00293393033923272,0 +"1934","2015-02-06 02:04:00",20.5,19.745,0,437,0.00293747732551703,0 +"1935","2015-02-06 02:05:00",20.6,19.6,0,433,0.00293393033923272,0 +"1936","2015-02-06 02:06:00",20.5,19.65,0,431.5,0.00292327768638439,0 +"1937","2015-02-06 02:06:59",20.5,19.65,0,432,0.00292327768638439,0 +"1938","2015-02-06 02:08:00",20.55,19.65,0,429,0.00293235157647933,0 +"1939","2015-02-06 02:09:00",20.55,19.6,0,430,0.00292485503579613,0 +"1940","2015-02-06 02:10:00",20.5,19.6,0,430.5,0.00291580445128535,0 +"1941","2015-02-06 02:10:59",20.55,19.6,0,433,0.00292485503579613,0 +"1942","2015-02-06 02:12:00",20.6,19.6,0,436,0.00293393033923272,0 +"1943","2015-02-06 02:12:59",20.6,19.53,0,435,0.00292340276842956,0 +"1944","2015-02-06 02:13:59",20.6,19.445,0,434,0.0029106197664319,0 +"1945","2015-02-06 02:15:00",20.5,19.55,0,434,0.00290833139492368,0 +"1946","2015-02-06 02:16:00",20.5,19.6,0,435,0.00291580445128535,0 +"1947","2015-02-06 02:17:00",20.6,19.6,0,438,0.00293393033923272,0 +"1948","2015-02-06 02:18:00",20.6,19.5,0,440,0.00291889106094967,0 +"1949","2015-02-06 02:19:00",20.5666666666667,19.5333333333333,0,436.666666666667,0.00291787190321775,0 +"1950","2015-02-06 02:19:59",20.5666666666667,19.5,0,437.666666666667,0.00291286928120345,0 +"1951","2015-02-06 02:21:00",20.5666666666667,19.5,0,437,0.00291286928120345,0 +"1952","2015-02-06 02:22:00",20.6,19.5,0,433,0.00291889106094967,0 +"1953","2015-02-06 02:23:00",20.6,19.445,0,435.5,0.0029106197664319,0 +"1954","2015-02-06 02:23:59",20.6,19.5,0,435,0.00291889106094967,0 +"1955","2015-02-06 02:25:00",20.6,19.5,0,437,0.00291889106094967,0 +"1956","2015-02-06 02:25:59",20.6,19.34,0,436,0.00289482972125133,0 +"1957","2015-02-06 02:26:59",20.5,19.34,0,438,0.00287694650987218,0 +"1958","2015-02-06 02:28:00",20.6,19.5,0,440,0.00291889106094967,0 +"1959","2015-02-06 02:29:00",20.55,19.445,0,438.5,0.00290161690260444,0 +"1960","2015-02-06 02:30:00",20.55,19.39,0,436,0.00289337152882751,0 +"1961","2015-02-06 02:31:00",20.6,19.34,0,433,0.00289482972125133,0 +"1962","2015-02-06 02:31:59",20.5,19.39,0,432.5,0.00288441881560686,0 +"1963","2015-02-06 02:32:59",20.5,19.39,0,434.5,0.00288441881560686,0 +"1964","2015-02-06 02:34:00",20.55,19.29,0,433.5,0.00287838049759094,0 +"1965","2015-02-06 02:35:00",20.6,19.39,0,433.5,0.00290234869086544,0 +"1966","2015-02-06 02:36:00",20.6,19.295,0,434.5,0.00288806280330063,0 +"1967","2015-02-06 02:37:00",20.6,19.29,0,434,0.00288731093257501,0 +"1968","2015-02-06 02:38:00",20.6,19.29,0,435,0.00288731093257501,0 +"1969","2015-02-06 02:38:59",20.5,19.34,0,431,0.00287694650987218,0 +"1970","2015-02-06 02:39:59",20.5,19.29,0,431.5,0.00286947438284154,0 +"1971","2015-02-06 02:41:00",20.4633333333333,19.2266666666667,0,432.666666666667,0.00285351580731716,0 +"1972","2015-02-06 02:42:00",20.5,19.39,0,436,0.00288441881560686,0 +"1973","2015-02-06 02:43:00",20.5,19.39,0,436,0.00288441881560686,0 +"1974","2015-02-06 02:44:00",20.5,19.245,0,441.5,0.00286274962130062,0 +"1975","2015-02-06 02:44:59",20.5,19.2,0,434,0.0028560250045001,0 +"1976","2015-02-06 02:45:59",20.39,19.29,0,433.5,0.00284996625752727,0 +"1977","2015-02-06 02:47:00",20.4266666666667,19.29,0,429.333333333333,0.00285645595496454,0 +"1978","2015-02-06 02:48:00",20.5,19.29,0,434.5,0.00286947438284154,0 +"1979","2015-02-06 02:49:00",20.5,19.2,0,433.5,0.0028560250045001,0 +"1980","2015-02-06 02:50:00",20.5,19.15,0,435.5,0.00284855337780667,0 +"1981","2015-02-06 02:51:00",20.445,19.05,0,435,0.00282396460077754,0 +"1982","2015-02-06 02:51:59",20.39,19.1666666666667,0,434,0.00283166164233876,0 +"1983","2015-02-06 02:53:00",20.39,19.245,0,430.5,0.00284328742231428,0 +"1984","2015-02-06 02:54:00",20.39,19.2,0,426,0.00283660872987593,0 +"1985","2015-02-06 02:55:00",20.5,19.2,0,429,0.0028560250045001,0 +"1986","2015-02-06 02:55:59",20.5,19.2,0,435.5,0.0028560250045001,0 +"1987","2015-02-06 02:57:00",20.5,19.2,0,433.5,0.0028560250045001,0 +"1988","2015-02-06 02:57:59",20.5,19.2,0,427.5,0.0028560250045001,0 +"1989","2015-02-06 02:58:59",20.5333333333333,19.1666666666667,0,429.666666666667,0.00285694031796831,0 +"1990","2015-02-06 03:00:00",20.525,19.175,0,433,0.00285671241681019,0 +"1991","2015-02-06 03:01:00",20.5,19.1,0,432.5,0.00284108192979292,0 +"1992","2015-02-06 03:02:00",20.5,19.1,0,431,0.00284108192979292,0 +"1993","2015-02-06 03:03:00",20.5333333333333,19.1,0,433.333333333333,0.00284695765074688,0 +"1994","2015-02-06 03:04:00",20.5,19.1,0,433,0.00284108192979292,0 +"1995","2015-02-06 03:04:59",20.5,19.1,0,434,0.00284108192979292,0 +"1996","2015-02-06 03:06:00",20.5,19.1,0,437,0.00284108192979292,0 +"1997","2015-02-06 03:07:00",20.5,19.1,0,437,0.00284108192979292,0 +"1998","2015-02-06 03:08:00",20.5,19.1,0,439,0.00284108192979292,0 +"1999","2015-02-06 03:08:59",20.5333333333333,18.9633333333333,0,432.333333333333,0.0028264941800736,0 +"2000","2015-02-06 03:10:00",20.525,19.075,0,432,0.00284174624237996,0 +"2001","2015-02-06 03:10:59",20.5,19.05,0,429.5,0.00283361066045245,0 +"2002","2015-02-06 03:11:59",20.5,19.1,0,436.5,0.00284108192979292,0 +"2003","2015-02-06 03:13:00",20.5333333333333,19,0,432.666666666667,0.00283198424795916,0 +"2004","2015-02-06 03:14:00",20.55,19,0,430,0.00283491057414835,0 +"2005","2015-02-06 03:15:00",20.5,18.945,0,425,0.00281792157639044,0 +"2006","2015-02-06 03:16:00",20.55,19,0,425.5,0.00283491057414835,0 +"2007","2015-02-06 03:16:59",20.55,19,0,434,0.00283491057414835,0 +"2008","2015-02-06 03:17:59",20.5,19,0,433,0.00282613956977883,0 +"2009","2015-02-06 03:19:00",20.5,19,0,433,0.00282613956977883,0 +"2010","2015-02-06 03:20:00",20.6,18.9633333333333,0,433.5,0.00283819263211046,0 +"2011","2015-02-06 03:21:00",20.5,19,0,426,0.00282613956977883,0 +"2012","2015-02-06 03:22:00",20.5333333333333,18.9633333333333,0,426.333333333333,0.0028264941800736,0 +"2013","2015-02-06 03:23:00",20.5333333333333,18.9266666666667,0,430,0.00282100420866383,0 +"2014","2015-02-06 03:23:59",20.6,18.945,0,436,0.00283543622163973,0 +"2015","2015-02-06 03:24:59",20.6,19,0,437.5,0.00284370552601066,0 +"2016","2015-02-06 03:26:00",20.5,19,0,433.5,0.00282613956977883,0 +"2017","2015-02-06 03:27:00",20.55,18.945,0,432.5,0.00282666696060251,0 +"2018","2015-02-06 03:28:00",20.55,18.945,0,430,0.00282666696060251,0 +"2019","2015-02-06 03:29:00",20.5,19,0,433,0.00282613956977883,0 +"2020","2015-02-06 03:29:59",20.6,19,0,439,0.00284370552601066,0 +"2021","2015-02-06 03:30:59",20.5,18.89,0,429.5,0.00280970379917266,0 +"2022","2015-02-06 03:32:00",20.55,19,0,431,0.00283491057414835,0 +"2023","2015-02-06 03:33:00",20.6,19,0,433,0.00284370552601066,0 +"2024","2015-02-06 03:34:00",20.55,19,0,434,0.00283491057414835,0 +"2025","2015-02-06 03:35:00",20.55,18.89,0,434.5,0.00281842356457419,0 +"2026","2015-02-06 03:36:00",20.5,18.945,0,435.5,0.00281792157639044,0 +"2027","2015-02-06 03:36:59",20.5,18.84,0,434.5,0.00280223328018994,0 +"2028","2015-02-06 03:38:00",20.5,18.89,0,433.5,0.00280970379917266,0 +"2029","2015-02-06 03:39:00",20.5,19,0,433,0.00282613956977883,0 +"2030","2015-02-06 03:40:00",20.5,19,0,433.5,0.00282613956977883,0 +"2031","2015-02-06 03:40:59",20.5,19,0,434.5,0.00282613956977883,0 +"2032","2015-02-06 03:42:00",20.5,19,0,438,0.00282613956977883,0 +"2033","2015-02-06 03:42:59",20.5,18.945,0,437,0.00281792157639044,0 +"2034","2015-02-06 03:43:59",20.445,18.945,0,435,0.00280832916488769,0 +"2035","2015-02-06 03:45:00",20.5,19,0,434,0.00282613956977883,0 +"2036","2015-02-06 03:46:00",20.5,18.895,0,434.5,0.00281045086089638,0 +"2037","2015-02-06 03:47:00",20.5,18.89,0,431,0.00280970379917266,0 +"2038","2015-02-06 03:48:00",20.5,19,0,433.5,0.00282613956977883,0 +"2039","2015-02-06 03:49:00",20.4266666666667,18.89,0,431.666666666667,0.0027969577563535,0 +"2040","2015-02-06 03:49:59",20.39,18.8233333333333,0,428.666666666667,0.00278071119911161,0 +"2041","2015-02-06 03:51:00",20.39,18.79,0,429.5,0.00277576499665867,0 +"2042","2015-02-06 03:52:00",20.39,18.9266666666667,0,434.333333333333,0.0027960449244251,0 +"2043","2015-02-06 03:53:00",20.39,18.84,0,430,0.00278318432970664,0 +"2044","2015-02-06 03:53:59",20.39,18.7,0,430,0.00276241064121188,0 +"2045","2015-02-06 03:55:00",20.39,18.89,0,424,0.00279060383896873,0 +"2046","2015-02-06 03:55:59",20.39,18.9266666666667,0,427.333333333333,0.0027960449244251,0 +"2047","2015-02-06 03:56:59",20.39,18.8233333333333,0,430,0.00278071119911161,0 +"2048","2015-02-06 03:58:00",20.39,18.79,0,431,0.00277576499665867,0 +"2049","2015-02-06 03:59:00",20.39,18.79,0,433.5,0.00277576499665867,0 +"2050","2015-02-06 04:00:00",20.445,18.79,0,430,0.00278524971345677,0 +"2051","2015-02-06 04:01:00",20.445,18.79,0,434,0.00278524971345677,0 +"2052","2015-02-06 04:01:59",20.5,18.79,0,434,0.00279476293984717,0 +"2053","2015-02-06 04:02:59",20.5,18.79,0,435.5,0.00279476293984717,0 +"2054","2015-02-06 04:04:00",20.5,18.79,0,436.333333333333,0.00279476293984717,0 +"2055","2015-02-06 04:05:00",20.5,18.745,0,434.5,0.00278803978627054,0 +"2056","2015-02-06 04:06:00",20.5,18.745,0,434,0.00278803978627054,0 +"2057","2015-02-06 04:07:00",20.5,18.7,0,434,0.00278131677738241,0 +"2058","2015-02-06 04:08:00",20.5,18.79,0,435,0.00279476293984717,0 +"2059","2015-02-06 04:08:59",20.5,18.79,0,430.5,0.00279476293984717,0 +"2060","2015-02-06 04:09:59",20.5,18.7,0,436,0.00278131677738241,0 +"2061","2015-02-06 04:11:00",20.39,18.6666666666667,0,431.666666666667,0.00275746472851366,0 +"2062","2015-02-06 04:12:00",20.39,18.76,0,428.666666666667,0.00277131348141006,0 +"2063","2015-02-06 04:13:00",20.39,18.7675,0,431,0.00277242635427527,0 +"2064","2015-02-06 04:14:00",20.39,18.7225,0,434.5,0.00276574917655245,0 +"2065","2015-02-06 04:14:59",20.39,18.7,0,434.5,0.00276241064121188,0 +"2066","2015-02-06 04:15:59",20.39,18.7,0,429.5,0.00276241064121188,0 +"2067","2015-02-06 04:17:00",20.39,18.745,0,432,0.00276908774757338,0 +"2068","2015-02-06 04:18:00",20.39,18.7,0,435.5,0.00276241064121188,0 +"2069","2015-02-06 04:19:00",20.39,18.6,0,436,0.0027475731380385,0 +"2070","2015-02-06 04:20:00",20.39,18.745,0,430,0.00276908774757338,0 +"2071","2015-02-06 04:21:00",20.39,18.76,0,434,0.00277131348141006,0 +"2072","2015-02-06 04:21:59",20.39,18.745,0,435,0.00276908774757338,0 +"2073","2015-02-06 04:23:00",20.39,18.7,0,434.5,0.00276241064121188,0 +"2074","2015-02-06 04:24:00",20.39,18.7,0,427.5,0.00276241064121188,0 +"2075","2015-02-06 04:25:00",20.39,18.7,0,433.333333333333,0.00276241064121188,0 +"2076","2015-02-06 04:25:59",20.5,18.745,0,433,0.00278803978627054,0 +"2077","2015-02-06 04:27:00",20.39,18.7,0,438,0.00276241064121188,0 +"2078","2015-02-06 04:27:59",20.445,18.7,0,434,0.00277184952407835,0 +"2079","2015-02-06 04:28:59",20.4633333333333,18.73,0,432.666666666667,0.00277947388804106,0 +"2080","2015-02-06 04:30:00",20.5,18.7,0,435,0.00278131677738241,0 +"2081","2015-02-06 04:31:00",20.445,18.7,0,433.5,0.00277184952407835,0 +"2082","2015-02-06 04:32:00",20.39,18.6,0,432,0.0027475731380385,0 +"2083","2015-02-06 04:33:00",20.39,18.7,0,434,0.00276241064121188,0 +"2084","2015-02-06 04:34:00",20.39,18.7,0,439,0.00276241064121188,0 +"2085","2015-02-06 04:34:59",20.39,18.7,0,434,0.00276241064121188,0 +"2086","2015-02-06 04:36:00",20.445,18.7,0,430,0.00277184952407835,0 +"2087","2015-02-06 04:37:00",20.445,18.7,0,435,0.00277184952407835,0 +"2088","2015-02-06 04:38:00",20.5,18.7,0,437.5,0.00278131677738241,0 +"2089","2015-02-06 04:38:59",20.5,18.7,0,434,0.00278131677738241,0 +"2090","2015-02-06 04:40:00",20.445,18.7,0,436,0.00277184952407835,0 +"2091","2015-02-06 04:40:59",20.445,18.7,0,432.5,0.00277184952407835,0 +"2092","2015-02-06 04:41:59",20.4633333333333,18.7,0,429.5,0.00277500211930092,0 +"2093","2015-02-06 04:43:00",20.39,18.7,0,430,0.00276241064121188,0 +"2094","2015-02-06 04:44:00",20.5,18.7,0,436,0.00278131677738241,0 +"2095","2015-02-06 04:45:00",20.5,18.745,0,436.5,0.00278803978627054,0 +"2096","2015-02-06 04:46:00",20.4633333333333,18.6666666666667,0,439.333333333333,0.00277003356244273,0 +"2097","2015-02-06 04:46:59",20.39,18.6,0,435,0.0027475731380385,0 +"2098","2015-02-06 04:47:59",20.39,18.6,0,432,0.0027475731380385,0 +"2099","2015-02-06 04:49:00",20.39,18.65,0,431,0.00275499180153006,0 +"2100","2015-02-06 04:50:00",20.39,18.7,0,425.5,0.00276241064121188,0 +"2101","2015-02-06 04:51:00",20.39,18.7,0,429,0.00276241064121188,0 +"2102","2015-02-06 04:52:00",20.39,18.7,0,431.5,0.00276241064121188,0 +"2103","2015-02-06 04:53:00",20.39,18.6,0,435,0.0027475731380385,0 +"2104","2015-02-06 04:53:59",20.39,18.7,0,428,0.00276241064121188,0 +"2105","2015-02-06 04:54:59",20.39,18.7,0,431.5,0.00276241064121188,0 +"2106","2015-02-06 04:56:00",20.39,18.7,0,432.5,0.00276241064121188,0 +"2107","2015-02-06 04:57:00",20.445,18.7,0,434.5,0.00277184952407835,0 +"2108","2015-02-06 04:58:00",20.39,18.7,0,429,0.00276241064121188,0 +"2109","2015-02-06 04:59:00",20.39,18.6666666666667,0,428.666666666667,0.00275746472851366,0 +"2110","2015-02-06 04:59:59",20.39,18.7,0,432,0.00276241064121188,0 +"2111","2015-02-06 05:00:59",20.39,18.7,0,430,0.00276241064121188,0 +"2112","2015-02-06 05:02:00",20.39,18.7,0,431,0.00276241064121188,0 +"2113","2015-02-06 05:03:00",20.445,18.6,0,431.5,0.0027569610989078,0 +"2114","2015-02-06 05:04:00",20.39,18.7,0,433,0.00276241064121188,0 +"2115","2015-02-06 05:05:00",20.39,18.7,0,437.5,0.00276241064121188,0 +"2116","2015-02-06 05:06:00",20.39,18.7,0,434,0.00276241064121188,0 +"2117","2015-02-06 05:06:59",20.39,18.7,0,432,0.00276241064121188,0 +"2118","2015-02-06 05:08:00",20.39,18.65,0,433,0.00275499180153006,0 +"2119","2015-02-06 05:09:00",20.39,18.7,0,425.5,0.00276241064121188,0 +"2120","2015-02-06 05:10:00",20.39,18.7,0,423,0.00276241064121188,0 +"2121","2015-02-06 05:10:59",20.39,18.6666666666667,0,430,0.00275746472851366,0 +"2122","2015-02-06 05:12:00",20.39,18.6,0,434,0.0027475731380385,0 +"2123","2015-02-06 05:12:59",20.3566666666667,18.6,0,428.666666666667,0.00274189716633263,0 +"2124","2015-02-06 05:13:59",20.29,18.65,0,427,0.00273794873953609,0 +"2125","2015-02-06 05:15:00",20.34,18.7,0,425.5,0.00275385439617598,0 +"2126","2015-02-06 05:16:00",20.34,18.7,0,433.5,0.00275385439617598,0 +"2127","2015-02-06 05:17:00",20.34,18.7,0,434.5,0.00275385439617598,0 +"2128","2015-02-06 05:18:00",20.39,18.7,0,427,0.00276241064121188,0 +"2129","2015-02-06 05:19:00",20.39,18.65,0,433,0.00275499180153006,0 +"2130","2015-02-06 05:19:59",20.34,18.65,0,433.5,0.00274645863650126,0 +"2131","2015-02-06 05:21:00",20.3566666666667,18.6666666666667,0,432.666666666667,0.00275176823262922,0 +"2132","2015-02-06 05:22:00",20.39,18.7,0,430,0.00276241064121188,0 +"2133","2015-02-06 05:23:00",20.34,18.7,0,430.5,0.00275385439617598,0 +"2134","2015-02-06 05:23:59",20.39,18.7,0,431,0.00276241064121188,0 +"2135","2015-02-06 05:25:00",20.39,18.65,0,431.333333333333,0.00275499180153006,0 +"2136","2015-02-06 05:25:59",20.39,18.7,0,433,0.00276241064121188,0 +"2137","2015-02-06 05:26:59",20.39,18.7,0,432,0.00276241064121188,0 +"2138","2015-02-06 05:28:00",20.39,18.7,0,430,0.00276241064121188,0 +"2139","2015-02-06 05:29:00",20.34,18.7,0,431.5,0.00275385439617598,0 +"2140","2015-02-06 05:30:00",20.39,18.7,0,430.333333333333,0.00276241064121188,0 +"2141","2015-02-06 05:31:00",20.39,18.7,0,429,0.00276241064121188,0 +"2142","2015-02-06 05:31:59",20.3566666666667,18.6666666666667,0,432.666666666667,0.00275176823262922,0 +"2143","2015-02-06 05:32:59",20.34,18.6,0,431.5,0.00273906305192466,0 +"2144","2015-02-06 05:34:00",20.29,18.745,0,428,0.00275195710045601,0 +"2145","2015-02-06 05:35:00",20.29,18.745,0,425.5,0.00275195710045601,0 +"2146","2015-02-06 05:36:00",20.29,18.745,0,430.5,0.00275195710045601,0 +"2147","2015-02-06 05:37:00",20.29,18.79,0,432,0.00275859285910685,0 +"2148","2015-02-06 05:38:00",20.29,18.7,0,433,0.00274532148276465,0 +"2149","2015-02-06 05:38:59",20.29,18.745,0,435.5,0.00275195710045601,0 +"2150","2015-02-06 05:39:59",20.29,18.79,0,431.5,0.00275859285910685,0 +"2151","2015-02-06 05:41:00",20.29,18.7675,0,432.75,0.00275527496216121,0 +"2152","2015-02-06 05:42:00",20.29,18.7,0,437,0.00274532148276465,0 +"2153","2015-02-06 05:43:00",20.29,18.7,0,433.5,0.00274532148276465,0 +"2154","2015-02-06 05:44:00",20.29,18.7,0,434,0.00274532148276465,0 +"2155","2015-02-06 05:44:59",20.245,18.695,0,438.5,0.0027369265480493,0 +"2156","2015-02-06 05:45:59",20.29,18.79,0,436.5,0.00275859285910685,0 +"2157","2015-02-06 05:47:00",20.29,18.79,0,437,0.00275859285910685,0 +"2158","2015-02-06 05:48:00",20.29,18.79,0,436,0.00275859285910685,0 +"2159","2015-02-06 05:49:00",20.29,18.79,0,441,0.00275859285910685,0 +"2160","2015-02-06 05:50:00",20.29,18.79,0,440,0.00275859285910685,0 +"2161","2015-02-06 05:51:00",20.29,18.745,0,437,0.00275195710045601,0 +"2162","2015-02-06 05:51:59",20.29,18.79,0,438.5,0.00275859285910685,0 +"2163","2015-02-06 05:53:00",20.29,18.84,0,433,0.00276596608960277,0 +"2164","2015-02-06 05:54:00",20.245,18.795,0,434,0.00275163119787626,0 +"2165","2015-02-06 05:55:00",20.29,18.76,0,437,0.0027541690043439,0 +"2166","2015-02-06 05:55:59",20.29,18.79,0,435,0.00275859285910685,0 +"2167","2015-02-06 05:57:00",20.29,18.79,0,434,0.00275859285910685,0 +"2168","2015-02-06 05:57:59",20.29,18.79,0,437,0.00275859285910685,0 +"2169","2015-02-06 05:58:59",20.29,18.745,0,434.5,0.00275195710045601,0 +"2170","2015-02-06 06:00:00",20.29,18.745,0,439,0.00275195710045601,0 +"2171","2015-02-06 06:01:00",20.29,18.79,0,433,0.00275859285910685,0 +"2172","2015-02-06 06:02:00",20.29,18.7,0,434,0.00274532148276465,0 +"2173","2015-02-06 06:03:00",20.245,18.745,0,433,0.00274427878643669,0 +"2174","2015-02-06 06:04:00",20.245,18.745,0,432.5,0.00274427878643669,0 +"2175","2015-02-06 06:04:59",20.245,18.745,0,433,0.00274427878643669,0 +"2176","2015-02-06 06:06:00",20.2,18.745,0,433,0.00273661933319912,0 +"2177","2015-02-06 06:07:00",20.245,18.84,0,432,0.00275824851613654,0 +"2178","2015-02-06 06:08:00",20.2,18.79,0,434,0.00274321794569799,0 +"2179","2015-02-06 06:08:59",20.29,18.79,0,433,0.00275859285910685,0 +"2180","2015-02-06 06:10:00",20.245,18.745,0,430.5,0.00274427878643669,0 +"2181","2015-02-06 06:10:59",20.29,18.79,0,433,0.00275859285910685,0 +"2182","2015-02-06 06:11:59",20.29,18.745,0,434,0.00275195710045601,0 +"2183","2015-02-06 06:13:00",20.29,18.84,0,430,0.00276596608960277,0 +"2184","2015-02-06 06:14:00",20.29,18.79,0,431.333333333333,0.00275859285910685,0 +"2185","2015-02-06 06:15:00",20.29,18.7,0,439,0.00274532148276465,0 +"2186","2015-02-06 06:16:00",20.29,18.79,0,439,0.00275859285910685,0 +"2187","2015-02-06 06:16:59",20.29,18.73,0,442,0.00274974521223028,0 +"2188","2015-02-06 06:17:59",20.2,18.7,0,432,0.00273002086008945,0 +"2189","2015-02-06 06:19:00",20.23,18.73,0,427.5,0.00273951991475475,0 +"2190","2015-02-06 06:20:00",20.29,18.745,0,433,0.00275195710045601,0 +"2191","2015-02-06 06:21:00",20.29,18.6,0,437,0.00273057617031989,0 +"2192","2015-02-06 06:22:00",20.29,18.7,0,432,0.00274532148276465,0 +"2193","2015-02-06 06:23:00",20.2,18.7,0,426,0.00273002086008945,0 +"2194","2015-02-06 06:23:59",20.29,18.7,0,431,0.00274532148276465,0 +"2195","2015-02-06 06:24:59",20.29,18.7,0,433.333333333333,0.00274532148276465,0 +"2196","2015-02-06 06:26:00",20.29,18.675,0,429.25,0.00274163508939844,0 +"2197","2015-02-06 06:27:00",20.26,18.6333333333333,0,433.333333333333,0.0027304009979612,0 +"2198","2015-02-06 06:28:00",20.245,18.65,0,430.5,0.00273030968145523,0 +"2199","2015-02-06 06:29:00",20.29,18.7,0,430,0.00274532148276465,0 +"2200","2015-02-06 06:29:59",20.29,18.7,0,433.5,0.00274532148276465,0 +"2201","2015-02-06 06:30:59",20.29,18.6,0,432.5,0.00273057617031989,0 +"2202","2015-02-06 06:32:00",20.29,18.7,0,432,0.00274532148276465,0 +"2203","2015-02-06 06:33:00",20.29,18.7,0,434,0.00274532148276465,0 +"2204","2015-02-06 06:34:00",20.29,18.6,0,429,0.00273057617031989,0 +"2205","2015-02-06 06:35:00",20.29,18.65,0,438,0.00273794873953609,0 +"2206","2015-02-06 06:36:00",20.29,18.7,0,439,0.00274532148276465,0 +"2207","2015-02-06 06:36:59",20.29,18.7,0,433,0.00274532148276465,0 +"2208","2015-02-06 06:38:00",20.29,18.65,0,433.5,0.00273794873953609,0 +"2209","2015-02-06 06:39:00",20.29,18.6,0,431,0.00273057617031989,0 +"2210","2015-02-06 06:40:00",20.3233333333333,18.5666666666667,0,432.666666666667,0.00273130634237627,0 +"2211","2015-02-06 06:40:59",20.39,18.6,0,434,0.0027475731380385,0 +"2212","2015-02-06 06:42:00",20.39,18.6,0,434,0.0027475731380385,0 +"2213","2015-02-06 06:42:59",20.39,18.6,0,436.5,0.0027475731380385,0 +"2214","2015-02-06 06:43:59",20.39,18.6,0,432.666666666667,0.0027475731380385,0 +"2215","2015-02-06 06:45:00",20.39,18.6,0,429.75,0.0027475731380385,0 +"2216","2015-02-06 06:46:00",20.39,18.5,0,428.5,0.0027327363396011,0 +"2217","2015-02-06 06:47:00",20.39,18.6,0,434,0.0027475731380385,0 +"2218","2015-02-06 06:48:00",20.29,18.6,0,435.5,0.00273057617031989,0 +"2219","2015-02-06 06:49:00",20.29,18.39,0,432,0.00269961327968767,0 +"2220","2015-02-06 06:49:59",20.245,18.6,0,433,0.00272295777185017,0 +"2221","2015-02-06 06:51:00",20.29,18.7,0,434,0.00274532148276465,0 +"2222","2015-02-06 06:52:00",20.29,18.65,0,433.5,0.00273794873953609,0 +"2223","2015-02-06 06:53:00",20.2,18.6,0,432,0.00271535808553788,0 +"2224","2015-02-06 06:53:59",20.2,18.6,0,431,0.00271535808553788,0 +"2225","2015-02-06 06:55:00",20.2,18.6,0,435,0.00271535808553788,0 +"2226","2015-02-06 06:55:59",20.2,18.6,0,438,0.00271535808553788,0 +"2227","2015-02-06 06:56:59",20.2,18.6,0,432,0.00271535808553788,0 +"2228","2015-02-06 06:58:00",20.1,18.6,0,430,0.00269853668924176,0 +"2229","2015-02-06 06:59:00",20.2,18.6,0,428.5,0.00271535808553788,0 +"2230","2015-02-06 07:00:00",20.2,18.6,0,432.666666666667,0.00271535808553788,0 +"2231","2015-02-06 07:01:00",20.2,18.6,0,432,0.00271535808553788,0 +"2232","2015-02-06 07:01:59",20.2,18.6,0,430,0.00271535808553788,0 +"2233","2015-02-06 07:02:59",20.2,18.6,0,431.333333333333,0.00271535808553788,0 +"2234","2015-02-06 07:04:00",20.2,18.6,0,432.666666666667,0.00271535808553788,0 +"2235","2015-02-06 07:05:00",20.2,18.6,0,434,0.00271535808553788,0 +"2236","2015-02-06 07:06:00",20.2,18.6,0,429,0.00271535808553788,0 +"2237","2015-02-06 07:07:00",20.2,18.6,0,429,0.00271535808553788,0 +"2238","2015-02-06 07:08:00",20.2,18.6,0,433,0.00271535808553788,0 +"2239","2015-02-06 07:08:59",20.2,18.6,0,436,0.00271535808553788,0 +"2240","2015-02-06 07:09:59",20.2,18.6,0,440,0.00271535808553788,0 +"2241","2015-02-06 07:11:00",20.2,18.6,0,436,0.00271535808553788,0 +"2242","2015-02-06 07:12:00",20.2,18.6,0,435,0.00271535808553788,0 +"2243","2015-02-06 07:13:00",20.2,18.5666666666667,0,430,0.00271047064697228,0 +"2244","2015-02-06 07:14:00",20.2,18.6,0,425.5,0.00271535808553788,0 +"2245","2015-02-06 07:14:59",20.2,18.6,0,432,0.00271535808553788,0 +"2246","2015-02-06 07:15:59",20.245,18.6,0,439.5,0.00272295777185017,0 +"2247","2015-02-06 07:17:00",20.29,18.6,0,434,0.00273057617031989,0 +"2248","2015-02-06 07:18:00",20.29,18.5,0,442,0.00271583155389989,0 +"2249","2015-02-06 07:19:00",20.29,18.5,0,439,0.00271583155389989,0 +"2250","2015-02-06 07:20:00",20.29,18.5666666666667,0,436.666666666667,0.00272566122084624,0 +"2251","2015-02-06 07:21:00",20.29,18.5,0,439,0.00271583155389989,0 +"2252","2015-02-06 07:21:59",20.29,18.5,0,436,0.00271583155389989,0 +"2253","2015-02-06 07:23:00",20.29,18.5,0,435,0.00271583155389989,0 +"2254","2015-02-06 07:24:00",20.29,18.55,0,439,0.00272320377510987,0 +"2255","2015-02-06 07:25:00",20.29,18.5,0,433,0.00271583155389989,0 +"2256","2015-02-06 07:25:59",20.29,18.5,0,435,0.00271583155389989,0 +"2257","2015-02-06 07:27:00",20.29,18.5,0,436,0.00271583155389989,0 +"2258","2015-02-06 07:27:59",20.245,18.5,0,438,0.00270825447173734,0 +"2259","2015-02-06 07:28:59",20.245,18.55,0,439,0.00271560603527957,0 +"2260","2015-02-06 07:30:00",20.2,18.5,0,436.5,0.00270069599925773,0 +"2261","2015-02-06 07:31:00",20.2,18.5,0,432.666666666667,0.00270069599925773,0 +"2262","2015-02-06 07:32:00",20.2,18.5,0,427.5,0.00270069599925773,0 +"2263","2015-02-06 07:33:00",20.2,18.5,0,427,0.00270069599925773,0 +"2264","2015-02-06 07:34:00",20.245,18.55,0,432,0.00271560603527957,0 +"2265","2015-02-06 07:34:59",20.245,18.55,0,438,0.00271560603527957,0 +"2266","2015-02-06 07:36:00",20.2,18.5,0,436,0.00270069599925773,0 +"2267","2015-02-06 07:37:00",20.2,18.5,0,434,0.00270069599925773,0 +"2268","2015-02-06 07:38:00",20.2,18.6,0,435,0.00271535808553788,0 +"2269","2015-02-06 07:38:59",20.2,18.6,0,435,0.00271535808553788,0 +"2270","2015-02-06 07:40:00",20.2,18.6,260.333333333333,434,0.00271535808553788,0 +"2271","2015-02-06 07:40:59",20.2,18.6,401.333333333333,439,0.00271535808553788,1 +"2272","2015-02-06 07:41:59",20.175,18.6,433,437.5,0.002711144108566,0 +"2273","2015-02-06 07:43:00",20.175,18.675,422.5,440.75,0.00272212398426569,0 +"2274","2015-02-06 07:44:00",20.2,18.7,419,442,0.00273002086008945,0 +"2275","2015-02-06 07:45:00",20.175,18.7,419,448.5,0.00272578402860229,0 +"2276","2015-02-06 07:46:00",20.1,18.745,419,451,0.00271966565200899,0 +"2277","2015-02-06 07:46:59",20.15,18.7,419,457.25,0.00272155298507209,1 +"2278","2015-02-06 07:47:59",20.1333333333333,18.7,409,458.666666666667,0.00271873550156601,0 +"2279","2015-02-06 07:49:00",20.175,18.7225,411,456,0.00272907810517298,0 +"2280","2015-02-06 07:50:00",20.125,18.865,411,458,0.00274140981774534,1 +"2281","2015-02-06 07:51:00",20.15,18.89,411,460,0.00274932735405506,1 +"2282","2015-02-06 07:52:00",20.2,18.89,411,459.75,0.0027578820280988,1 +"2283","2015-02-06 07:53:00",20.2,19.05,411,464,0.0027813459918572,1 +"2284","2015-02-06 07:53:59",20.2225,19.05,407.5,463.5,0.00278523619589936,1 +"2285","2015-02-06 07:54:59",20.2675,19.2175,400,470.25,0.00281770037038195,1 +"2286","2015-02-06 07:56:00",20.29,19.2225,400,483.5,0.0028223770615393,1 +"2287","2015-02-06 07:57:00",20.315,19.245,413,488.666666666667,0.00283008460321223,1 +"2288","2015-02-06 07:58:00",20.39,19.22,412.2,496.25,0.00283957702000011,1 +"2289","2015-02-06 07:59:00",20.39,19.26,409,496.25,0.00284551368485454,1 +"2290","2015-02-06 07:59:59",20.4175,19.29,411,497,0.00285483231239523,1 +"2291","2015-02-06 08:00:59",20.4266666666667,19.1633333333333,413,504,0.00283761363273738,1 +"2292","2015-02-06 08:02:00",20.4725,19.0975,411,503.25,0.00283586956883607,1 +"2293","2015-02-06 08:03:00",20.525,19.315,411,509.25,0.00287766626550865,1 +"2294","2015-02-06 08:04:00",20.5,19.2425,405,515,0.00286237602768121,1 +"2295","2015-02-06 08:05:00",20.5666666666667,19.2,409,515.333333333333,0.00286784928706544,1 +"2296","2015-02-06 08:06:00",20.625,19.4175,405,524.5,0.00291098840715561,1 +"2297","2015-02-06 08:06:59",20.65,19.4725,408.5,531,0.00292379571401485,1 +"2298","2015-02-06 08:08:00",20.7,19.5,418.333333333333,530.333333333333,0.00293702219639414,1 +"2299","2015-02-06 08:09:00",20.7,19.5,419,533.666666666667,0.00293702219639414,1 +"2300","2015-02-06 08:10:00",20.7,19.575,419,535.75,0.00294837198145542,1 +"2301","2015-02-06 08:10:59",20.7225,19.6,419,546.25,0.00295626966449128,1 +"2302","2015-02-06 08:12:00",20.7,19.5333333333333,419,547,0.00294206649441474,1 +"2303","2015-02-06 08:12:59",20.79,19.4725,419,546.25,0.00294924006107571,1 +"2304","2015-02-06 08:13:59",20.79,19.5,419,551.25,0.00295342489640642,1 +"2305","2015-02-06 08:15:00",20.79,19.5333333333333,419,560,0.00295849749921988,1 +"2306","2015-02-06 08:16:00",20.79,19.525,419,564,0.00295722934079657,1 +"2307","2015-02-06 08:17:00",20.815,19.625,419,568.75,0.00297704775062286,1 +"2308","2015-02-06 08:18:00",20.79,19.6333333333333,419,572,0.00297371580175007,1 +"2309","2015-02-06 08:19:00",20.84,19.65,419,573,0.00298547070121526,1 +"2310","2015-02-06 08:19:59",20.89,19.72,419,575.25,0.00300543400748227,1 +"2311","2015-02-06 08:21:00",20.865,19.65,419,579.5,0.00299008934004269,1 +"2312","2015-02-06 08:22:00",20.89,19.6,426,583.5,0.00298705753405412,1 +"2313","2015-02-06 08:23:00",20.89,19.6333333333333,423.666666666667,585.333333333333,0.00299216200161059,1 +"2314","2015-02-06 08:23:59",20.89,19.7,426,587.5,0.00300237118686644,1 +"2315","2015-02-06 08:25:00",20.89,19.65,422.5,591.5,0.0029947142666563,1 +"2316","2015-02-06 08:25:59",20.89,19.7,426,594,0.00300237118686644,1 +"2317","2015-02-06 08:26:59",20.89,19.625,419,597.5,0.00299088587690465,1 +"2318","2015-02-06 08:28:00",20.89,19.6333333333333,428.333333333333,595.333333333333,0.00299216200161059,1 +"2319","2015-02-06 08:29:00",20.865,19.675,429.5,590.75,0.00299391183587688,1 +"2320","2015-02-06 08:30:00",20.865,19.7425,429.5,589.75,0.00300423280818658,1 +"2321","2015-02-06 08:31:00",20.8233333333333,19.6666666666667,433,591,0.00298493683482187,1 +"2322","2015-02-06 08:31:59",20.84,19.695,433,589.5,0.0029923405484988,1 +"2323","2015-02-06 08:32:59",20.89,19.7225,433,595.75,0.00300581686216994,1 +"2324","2015-02-06 08:34:00",20.865,19.7225,433,596.75,0.00300117470678015,1 +"2325","2015-02-06 08:35:00",20.8566666666667,19.76,433,598.666666666667,0.00300535972133214,1 +"2326","2015-02-06 08:36:00",20.865,19.7675,433,605.5,0.00300805547702872,1 +"2327","2015-02-06 08:37:00",20.84,19.745,433,609,0.00299997388927963,1 +"2328","2015-02-06 08:38:00",20.84,19.745,433,614,0.00299997388927963,1 +"2329","2015-02-06 08:38:59",20.84,19.745,433,614.75,0.00299997388927963,1 +"2330","2015-02-06 08:39:59",20.89,19.79,433,621,0.00301615411603875,1 +"2331","2015-02-06 08:41:00",20.865,19.7675,433,620.25,0.00300805547702872,1 +"2332","2015-02-06 08:42:00",20.865,19.7675,433,617.5,0.00300805547702872,1 +"2333","2015-02-06 08:43:00",20.865,19.7675,433,621.25,0.00300805547702872,1 +"2334","2015-02-06 08:44:00",20.89,19.79,433,616.666666666667,0.00301615411603875,1 +"2335","2015-02-06 08:44:59",20.865,19.7675,433,620,0.00300805547702872,1 +"2336","2015-02-06 08:45:59",20.8566666666667,19.76,433,628.333333333333,0.00300535972133214,1 +"2337","2015-02-06 08:47:00",20.84,19.7675,433,635.25,0.00300340895346376,1 +"2338","2015-02-06 08:48:00",20.865,19.7675,433,636.5,0.00300805547702872,1 +"2339","2015-02-06 08:49:00",20.89,19.79,433,635.5,0.00301615411603875,1 +"2340","2015-02-06 08:50:00",20.89,19.79,433,635.75,0.00301615411603875,1 +"2341","2015-02-06 08:51:00",20.865,19.7675,433,637.5,0.00300805547702872,1 +"2342","2015-02-06 08:51:59",20.84,19.745,433,629.75,0.00299997388927963,1 +"2343","2015-02-06 08:53:00",20.865,19.7675,433,637.25,0.00300805547702872,1 +"2344","2015-02-06 08:54:00",20.89,19.79,433,647.333333333333,0.00301615411603875,1 +"2345","2015-02-06 08:55:00",20.865,19.7675,433,646,0.00300805547702872,1 +"2346","2015-02-06 08:55:59",20.8233333333333,19.73,433,642.666666666667,0.00299459562233365,1 +"2347","2015-02-06 08:57:00",20.8566666666667,19.7933333333333,433,648,0.003010454028918,1 +"2348","2015-02-06 08:57:59",20.89,19.79,433,655,0.00301615411603875,1 +"2349","2015-02-06 08:58:59",20.9175,19.79,433,650.5,0.0030212854568588,1 +"2350","2015-02-06 09:00:00",20.9266666666667,19.79,433,643.666666666667,0.00302299761050479,1 +"2351","2015-02-06 09:01:00",20.9175,19.79,433,642,0.0030212854568588,1 +"2352","2015-02-06 09:02:00",20.9633333333333,19.79,433,639.333333333333,0.00302985476836808,1 +"2353","2015-02-06 09:03:00",20.89,19.79,436.5,648,0.00301615411603875,1 +"2354","2015-02-06 09:04:00",20.89,19.815,426,649,0.00301998281535946,1 +"2355","2015-02-06 09:04:59",20.89,19.79,433,654,0.00301615411603875,1 +"2356","2015-02-06 09:06:00",20.89,19.9266666666667,433,660,0.00303708491169476,1 +"2357","2015-02-06 09:07:00",20.89,20.1333333333333,442.333333333333,677.333333333333,0.00306873902173689,1 +"2358","2015-02-06 09:08:00",20.89,20.354,435.8,698.2,0.00310254098194816,1 +"2359","2015-02-06 09:08:59",20.89,20.4725,447,709.25,0.00312069444972632,1 +"2360","2015-02-06 09:10:00",20.9266666666667,20.39,442.333333333333,712,0.00311510890191837,1 +"2361","2015-02-06 09:10:59",20.945,20.5,443.5,710,0.00313554997033061,1 +"2362","2015-02-06 09:11:59",20.945,20.445,447,708,0.00312709522572479,1 +"2363","2015-02-06 09:13:00",20.945,20.55,447,707.5,0.00314323630024997,1 +"2364","2015-02-06 09:14:00",20.945,20.6975,447,725.75,0.00316591207479449,1 +"2365","2015-02-06 09:15:00",20.9725,20.7675,438,733.25,0.00318207756450964,1 +"2366","2015-02-06 09:16:00",21,20.79,441,735.333333333333,0.00319096030254309,1 +"2367","2015-02-06 09:16:59",21,20.815,438,740.75,0.00319481714505113,1 +"2368","2015-02-06 09:17:59",21,20.865,438,744.25,0.0032025309728276,1 +"2369","2015-02-06 09:19:00",21,20.79,438,757,0.00319096030254309,1 +"2370","2015-02-06 09:20:00",21,20.79,440,759,0.00319096030254309,1 +"2371","2015-02-06 09:21:00",21,20.815,437.25,752.25,0.00319481714505113,1 +"2372","2015-02-06 09:22:00",21,20.865,438,754.5,0.0032025309728276,1 +"2373","2015-02-06 09:23:00",21.025,20.945,440.25,758.5,0.00321984272199134,1 +"2374","2015-02-06 09:23:59",21.05,21,436.5,764,0.00323333086438862,1 +"2375","2015-02-06 09:24:59",21.05,21.05,441,765.25,0.00324106938547011,1 +"2376","2015-02-06 09:26:00",21.1,21.15,436.5,769.75,0.0032666179277636,1 +"2377","2015-02-06 09:27:00",21.1,21.245,444,780.25,0.00328136808595491,1 +"2378","2015-02-06 09:28:00",21.1,21.29,444,786,0.00328835524589222,1 +"2379","2015-02-06 09:29:00",21.1,21.2225,444,783.25,0.00327787456454339,1 +"2380","2015-02-06 09:29:59",21.1,21.2675,444,787,0.0032848616464043,1 +"2381","2015-02-06 09:30:59",21.1,21.2,444,787.666666666667,0.0032743810821691,1 +"2382","2015-02-06 09:32:00",21.1,21.2,448,786.75,0.0032743810821691,1 +"2383","2015-02-06 09:33:00",21.1,21.2,444,782.5,0.0032743810821691,1 +"2384","2015-02-06 09:34:00",21.1,21.1,454.75,779.75,0.00325885496612408,1 +"2385","2015-02-06 09:35:00",21.1,21.05,454.75,777.5,0.00325109219724338,1 +"2386","2015-02-06 09:36:00",21.1,21.1,460,779.333333333333,0.00325885496612408,1 +"2387","2015-02-06 09:36:59",21.175,21.075,449.5,782.75,0.00327007705069215,1 +"2388","2015-02-06 09:38:00",21.15,21.05,449.5,787.5,0.00326114228977468,1 +"2389","2015-02-06 09:39:00",21.2,21.075,454.75,777,0.00327512524260638,1 +"2390","2015-02-06 09:40:00",21.2,21.0666666666667,449.333333333333,789.666666666667,0.00327382339860608,1 +"2391","2015-02-06 09:40:59",21.175,21.075,460,805.25,0.00327007705069215,1 +"2392","2015-02-06 09:42:00",21.2,20.9975,456,801.25,0.00326301830262213,1 +"2393","2015-02-06 09:42:59",21.2,21,460,796,0.00326340884175517,1 +"2394","2015-02-06 09:43:59",21.2225,21.025,449.5,793.25,0.00327185259165016,1 +"2395","2015-02-06 09:45:00",21.29,20.9633333333333,453,788.333333333333,0.00327581372742662,1 +"2396","2015-02-06 09:46:00",21.2675,21,460,794.5,0.00327702411140154,1 +"2397","2015-02-06 09:47:00",21.29,21,460,797.5,0.00328157363527027,1 +"2398","2015-02-06 09:48:00",21.3233333333333,21.0333333333333,460,810,0.00329357109246129,1 +"2399","2015-02-06 09:49:00",21.29,21,450.75,812.5,0.00328157363527027,1 +"2400","2015-02-06 09:49:59",21.29,21.0333333333333,454.666666666667,813.666666666667,0.00328681000721484,1 +"2401","2015-02-06 09:51:00",21.315,20.9725,444,809.25,0.00328230854413818,1 +"2402","2015-02-06 09:52:00",21.29,21,444,812.333333333333,0.00328157363527027,1 +"2403","2015-02-06 09:53:00",21.29,21.0333333333333,454.666666666667,807.666666666667,0.00328681000721484,1 +"2404","2015-02-06 09:53:59",21.315,21,460,810.5,0.0032866351830872,1 +"2405","2015-02-06 09:55:00",21.34,21,452,811.5,0.00329170360317058,1 +"2406","2015-02-06 09:55:59",21.325,20.978,456,808,0.00328519826458598,1 +"2407","2015-02-06 09:56:59",21.31,20.956,460,804.5,0.0032787018749781,1 +"2408","2015-02-06 09:58:00",21.3233333333333,20.86,460,797.333333333333,0.00326628661412406,1 +"2409","2015-02-06 09:59:00",21.3566666666667,20.9266666666667,460,796.333333333333,0.00328351897769845,1 +"2410","2015-02-06 10:00:00",21.39,20.865,449.5,798.5,0.00328052289186158,1 +"2411","2015-02-06 10:01:00",21.39,20.79,460,796,0.00326866896536751,1 +"2412","2015-02-06 10:01:59",21.34,20.995,449.5,801.25,0.00329091571756336,1 +"2413","2015-02-06 10:02:59",21.34,21.1,449.5,811,0.0033074617322846,1 +"2414","2015-02-06 10:04:00",21.29,21.245,460,821.5,0.00332006301583508,1 +"2415","2015-02-06 10:05:00",21.34,21.2675,455.5,830.25,0.00333385837799151,1 +"2416","2015-02-06 10:06:00",21.29,21.29,457,835,0.00332713300899553,1 +"2417","2015-02-06 10:07:00",21.34,21.2,449.5,831,0.00332322065566757,1 +"2418","2015-02-06 10:08:00",21.315,21.29,454.75,834.75,0.00333226520275809,1 +"2419","2015-02-06 10:08:59",21.29,21.29,460,837,0.00332713300899553,1 +"2420","2015-02-06 10:09:59",21.315,21.29,460,841,0.00333226520275809,1 +"2421","2015-02-06 10:11:00",21.315,21.2675,460,844.5,0.00332872470430793,1 +"2422","2015-02-06 10:12:00",21.39,21.34,460,847,0.00335560819829238,1 +"2423","2015-02-06 10:13:00",21.39,21.2675,454.75,842.5,0.0033441466432948,1 +"2424","2015-02-06 10:14:00",21.39,21.2,453,841,0.00333347591803249,1 +"2425","2015-02-06 10:14:59",21.39,21.2475,449.5,839.5,0.0033409849089552,1 +"2426","2015-02-06 10:15:59",21.365,21.3175,454.75,844.5,0.00334689126491045,1 +"2427","2015-02-06 10:17:00",21.39,21.2,457,847,0.00333347591803249,1 +"2428","2015-02-06 10:18:00",21.39,21.2675,454,847.75,0.0033441466432948,1 +"2429","2015-02-06 10:19:00",21.3233333333333,21.23,464,843.333333333333,0.00332453136508391,1 +"2430","2015-02-06 10:20:00",21.365,21.315,461.5,847.25,0.0033464966480141,1 +"2431","2015-02-06 10:21:00",21.39,21.34,449.5,848.5,0.00335560819829238,1 +"2432","2015-02-06 10:21:59",21.34,21.445,449.5,848.5,0.00336183337511146,1 +"2433","2015-02-06 10:23:00",21.39,21.39,454,854.25,0.00336351296377594,1 +"2434","2015-02-06 10:24:00",21.34,21.1475,455.5,848.25,0.00331494712185242,1 +"2435","2015-02-06 10:25:00",21.3566666666667,21.2,468,844.333333333333,0.00332663598556098,1 +"2436","2015-02-06 10:25:59",21.29,21.2,454,836.5,0.00331299318254051,1 +"2437","2015-02-06 10:27:00",21.3233333333333,21.2,454,838,0.00331980841346625,1 +"2438","2015-02-06 10:27:59",21.315,21.125,469,841.5,0.003306302478428,1 +"2439","2015-02-06 10:28:59",21.34,21,469,832,0.00329170360317058,1 +"2440","2015-02-06 10:30:00",21.315,20.865,469,825,0.00326539589365197,1 +"2441","2015-02-06 10:31:00",21.315,20.9175,465.25,824,0.00327365544586539,1 +"2442","2015-02-06 10:32:00",21.29,21.175,475.25,826.75,0.00330906556645272,1 +"2443","2015-02-06 10:33:00",21.29,21.1,464,824,0.00329728301421794,1 +"2444","2015-02-06 10:34:00",21.29,21.2,459,827.5,0.00331299318254051,1 +"2445","2015-02-06 10:34:59",21.29,21.236,468.2,843.5,0.00331864903638707,1 +"2446","2015-02-06 10:36:00",21.365,21.17,474,845.6,0.0033236097201333,1 +"2447","2015-02-06 10:37:00",21.39,20.79,492.333333333333,837.333333333333,0.00326866896536751,1 +"2448","2015-02-06 10:38:00",21.3233333333333,21.0666666666667,474,825.666666666667,0.00329881838052129,1 +"2449","2015-02-06 10:38:59",21.39,20.97,480.25,831.75,0.00329711914406046,1 +"2450","2015-02-06 10:40:00",21.4725,21.0475,504,832.25,0.00332622797144664,1 +"2451","2015-02-06 10:40:59",21.5,21.1,539.5,843,0.00334021979127877,1 +"2452","2015-02-06 10:41:59",21.5,20.725,509,839,0.00328054259828353,1 +"2453","2015-02-06 10:43:00",21.5,20.84,528.5,832.5,0.00329884239319777,1 +"2454","2015-02-06 10:44:00",21.6,21.0225,499,840,0.00334842756234686,1 +"2455","2015-02-06 10:45:00",21.65,20.9175,497.75,850,0.00334187449611367,1 +"2456","2015-02-06 10:46:00",21.675,21.1,500.25,853.75,0.0033763756804593,1 +"2457","2015-02-06 10:46:59",21.7,21,489,852,0.00336545572585474,1 +"2458","2015-02-06 10:47:59",21.7,20.9725,490.25,856.25,0.0033610247671086,1 +"2459","2015-02-06 10:49:00",21.7,20.945,494,854.5,0.00335659387115217,1 +"2460","2015-02-06 10:50:00",21.7,20.89,485.666666666667,854,0.00334773226760308,1 +"2461","2015-02-06 10:51:00",21.7,20.815,481.5,850.75,0.0033356486674956,1 +"2462","2015-02-06 10:52:00",21.7,20.8925,484,844.5,0.00334813506231597,1 +"2463","2015-02-06 10:53:00",21.7,21.075,482.75,850.75,0.00337754047794719,1 +"2464","2015-02-06 10:53:59",21.73,20.89,477.333333333333,861,0.00335391054716794,1 +"2465","2015-02-06 10:54:59",21.73,20.93,477.333333333333,865,0.00336036728266843,1 +"2466","2015-02-06 10:56:00",21.7675,20.795,485.25,860.75,0.00334627773474081,1 +"2467","2015-02-06 10:57:00",21.754,20.896,485.25,853.25,0.00335983033431899,1 +"2468","2015-02-06 10:58:00",21.73,20.7,482.75,849.75,0.00332324287422974,1 +"2469","2015-02-06 10:59:00",21.79,20.945,464,844.5,0.00337520823685561,1 +"2470","2015-02-06 10:59:59",21.7225,20.87,479,846.75,0.00334913821487917,1 +"2471","2015-02-06 11:00:59",21.745,20.7225,476.75,852.5,0.0033299422525362,1 +"2472","2015-02-06 11:02:00",21.7,20.79,476,851,0.00333162090456645,1 +"2473","2015-02-06 11:03:00",21.7,20.7675,480,854.75,0.00332799596229192,1 +"2474","2015-02-06 11:04:00",21.73,20.73,479,852.666666666667,0.00332808493840404,1 +"2475","2015-02-06 11:05:00",21.7225,20.7,479,848.25,0.00332171157107602,1 +"2476","2015-02-06 11:06:00",21.7225,20.7,485.25,848,0.00332171157107602,1 +"2477","2015-02-06 11:06:59",21.7,20.6,489,846,0.00330101160183458,1 +"2478","2015-02-06 11:08:00",21.7,20.745,489,844.5,0.0033243710620435,1 +"2479","2015-02-06 11:09:00",21.7675,20.7925,471.5,846.75,0.00334587327716802,1 +"2480","2015-02-06 11:10:00",21.76,20.73,471,849,0.00333422534811644,1 +"2481","2015-02-06 11:10:59",21.79,20.55,487.75,837,0.00331121661205061,1 +"2482","2015-02-06 11:12:00",21.79,20.5,467.666666666667,830.333333333333,0.00330311734014026,1 +"2483","2015-02-06 11:12:59",21.79,20.65,469.25,829.5,0.0033274157853251,1 +"2484","2015-02-06 11:13:59",21.73,20.5666666666667,462.333333333333,830.666666666667,0.0033017234962236,1 +"2485","2015-02-06 11:15:00",21.79,20.6,462.75,834.25,0.00331931609377617,1 +"2486","2015-02-06 11:16:00",21.79,20.6225,462.75,833.5,0.00332296092900706,1 +"2487","2015-02-06 11:17:00",21.79,20.5,472.333333333333,827.666666666667,0.00330311734014026,1 +"2488","2015-02-06 11:18:00",21.79,20.678,485,821.25,0.00333195170424639,1 +"2489","2015-02-06 11:19:00",21.745,20.5,479,822.333333333333,0.00329399891137401,1 +"2490","2015-02-06 11:19:59",21.745,20.6,471.5,821.75,0.00331015271078034,1 +"2491","2015-02-06 11:21:00",21.7,20.6666666666667,464,826,0.00331175136679585,1 +"2492","2015-02-06 11:22:00",21.7225,20.65,475.25,829.5,0.00331364536897211,1 +"2493","2015-02-06 11:23:00",21.7,20.6,479,832,0.00330101160183458,1 +"2494","2015-02-06 11:23:59",21.7,20.6,464,823,0.00330101160183458,1 +"2495","2015-02-06 11:25:00",21.7,20.6,469,824,0.00330101160183458,1 +"2496","2015-02-06 11:25:59",21.7,20.6,467.75,825.25,0.00330101160183458,1 +"2497","2015-02-06 11:26:59",21.7,20.625,481.5,830.75,0.00330503897046288,1 +"2498","2015-02-06 11:28:00",21.7,20.5,479,831,0.00328490264608514,1 +"2499","2015-02-06 11:29:00",21.7225,20.6,479,826,0.00330557937496198,1 +"2500","2015-02-06 11:30:00",21.76,20.5333333333333,490.666666666667,818.333333333333,0.00330242542044239,1 +"2501","2015-02-06 11:31:00",21.7225,20.525,502.75,815.75,0.00329348077410498,1 +"2502","2015-02-06 11:31:59",21.7225,20.5,490.25,816,0.00328944801119081,0 +"2503","2015-02-06 11:32:59",21.7,20.5,479,813.25,0.00328490264608514,0 +"2504","2015-02-06 11:34:00",21.7,20.39,474,806,0.00326718375337819,0 +"2505","2015-02-06 11:35:00",21.7,20.525,492.75,804.5,0.00328892980720994,0 +"2506","2015-02-06 11:36:00",21.7,20.46,507,801,0.00327845929618166,1 +"2507","2015-02-06 11:37:00",21.7,20.575,484,796,0.00329698428508366,1 +"2508","2015-02-06 11:38:00",21.7,20.4425,467.75,801,0.00327564037235591,1 +"2509","2015-02-06 11:38:59",21.7,20.39,464,803,0.00326718375337819,1 +"2510","2015-02-06 11:39:59",21.7,20.39,469,795.666666666667,0.00326718375337819,1 +"2511","2015-02-06 11:41:00",21.7,20.4175,464,794,0.00327161338240943,1 +"2512","2015-02-06 11:42:00",21.7,20.5,471,787,0.00328490264608514,1 +"2513","2015-02-06 11:43:00",21.7,20.39,462.75,787,0.00326718375337819,1 +"2514","2015-02-06 11:44:00",21.7,20.39,481.5,788,0.00326718375337819,1 +"2515","2015-02-06 11:44:59",21.7,20.39,479,786.5,0.00326718375337819,1 +"2516","2015-02-06 11:45:59",21.7,20.39,469.25,788.25,0.00326718375337819,1 +"2517","2015-02-06 11:47:00",21.7,20.39,469,788.333333333333,0.00326718375337819,1 +"2518","2015-02-06 11:48:00",21.7,20.39,469,781,0.00326718375337819,1 +"2519","2015-02-06 11:49:00",21.65,20.365,457.75,788.75,0.0032531429315252,1 +"2520","2015-02-06 11:50:00",21.6333333333333,20.3233333333333,460.666666666667,790.666666666667,0.00324312720518315,1 +"2521","2015-02-06 11:51:00",21.65,20.34,465.5,789.5,0.00324912852407748,1 +"2522","2015-02-06 11:51:59",21.7,20.39,474.333333333333,794.333333333333,0.00326718375337819,1 +"2523","2015-02-06 11:53:00",21.675,20.4175,477.75,792.5,0.00326658997353317,1 +"2524","2015-02-06 11:54:00",21.65,20.2475,487.75,789.5,0.00323427566472548,1 +"2525","2015-02-06 11:55:00",21.7,20.5333333333333,492.333333333333,785.5,0.00329027220577913,1 +"2526","2015-02-06 11:55:59",21.7,20.4725,490.25,792.6,0.00328047282876157,1 +"2527","2015-02-06 11:57:00",21.7,20.4266666666667,484,800,0.00327308993936706,1 +"2528","2015-02-06 11:57:59",21.7,20.4633333333333,480.666666666667,795,0.00327899623693499,1 +"2529","2015-02-06 11:58:59",21.7,20.32,491.5,795.75,0.00325590861722737,1 +"2530","2015-02-06 12:00:00",21.675,20.4175,501.5,802,0.00326658997353317,1 +"2531","2015-02-06 12:01:00",21.7,20.39,494,803,0.00326718375337819,1 +"2532","2015-02-06 12:02:00",21.7,20.39,494,796.25,0.00326718375337819,1 +"2533","2015-02-06 12:03:00",21.7,20.39,479,806.666666666667,0.00326718375337819,1 +"2534","2015-02-06 12:04:00",21.7,20.3933333333333,506,805.666666666667,0.00326772067476656,1 +"2535","2015-02-06 12:04:59",21.7,20.29,514,803,0.00325107654049993,1 +"2536","2015-02-06 12:06:00",21.7,20.4175,513.75,800.25,0.00327161338240943,1 +"2537","2015-02-06 12:07:00",21.7,20.39,514,793,0.00326718375337819,1 +"2538","2015-02-06 12:08:00",21.7,20.39,494,791,0.00326718375337819,1 +"2539","2015-02-06 12:08:59",21.7,20.5,514,800.5,0.00328490264608514,1 +"2540","2015-02-06 12:10:00",21.7,20.4266666666667,507.333333333333,808,0.00327308993936706,1 +"2541","2015-02-06 12:10:59",21.7,20.39,567.5,805.5,0.00326718375337819,1 +"2542","2015-02-06 12:11:59",21.7,20.39,512.75,804,0.00326718375337819,1 +"2543","2015-02-06 12:13:00",21.7,20.34,528.5,798.5,0.00325913004320515,1 +"2544","2015-02-06 12:14:00",21.7225,20.315,541.5,806.25,0.00325960718226015,1 +"2545","2015-02-06 12:15:00",21.7,20.2475,533.75,802.5,0.00324423122631609,1 +"2546","2015-02-06 12:16:00",21.73,20.2933333333333,504,794.333333333333,0.00325761340127826,1 +"2547","2015-02-06 12:16:59",21.79,20.3425,494,800.25,0.00327760600493593,1 +"2548","2015-02-06 12:17:59",21.7675,20.3175,496.5,806,0.00326903583036557,1 +"2549","2015-02-06 12:19:00",21.79,20.245,496.5,804.5,0.00326181431677313,1 +"2550","2015-02-06 12:20:00",21.79,20.295,504,801,0.00326991251875266,1 +"2551","2015-02-06 12:21:00",21.79,20.295,489,801.5,0.00326991251875266,1 +"2552","2015-02-06 12:22:00",21.79,20.2675,489,805,0.00326545848170495,1 +"2553","2015-02-06 12:23:00",21.79,20.23,518.666666666667,802.333333333333,0.00325938489708391,1 +"2554","2015-02-06 12:23:59",21.76,20.26,489,800.666666666667,0.00325823428158547,1 +"2555","2015-02-06 12:24:59",21.79,20.2925,486.5,799.5,0.00326950760367163,1 +"2556","2015-02-06 12:26:00",21.79,20.245,471.5,806,0.00326181431677313,1 +"2557","2015-02-06 12:27:00",21.73,20.3566666666667,474,812.666666666667,0.00326783347909749,1 +"2558","2015-02-06 12:28:00",21.745,20.34,484,816.5,0.00326815456824215,1 +"2559","2015-02-06 12:29:00",21.76,20.39,479,820.333333333333,0.00327925123942565,1 +"2560","2015-02-06 12:29:59",21.7675,20.545,479,817.5,0.00330583456706247,1 +"2561","2015-02-06 12:30:59",21.79,20.39,479,811.333333333333,0.0032852996804469,1 +"2562","2015-02-06 12:32:00",21.745,20.39,484,820.75,0.00327623069597488,1 +"2563","2015-02-06 12:33:00",21.745,20.4725,486.5,815.5,0.0032895567628539,1 +"2564","2015-02-06 12:34:00",21.745,20.445,499,821,0.00328511467744824,1 +"2565","2015-02-06 12:35:00",21.745,20.4425,511.5,821.5,0.00328471085463187,1 +"2566","2015-02-06 12:36:00",21.7,20.495,521.5,813,0.00328409722008502,1 +"2567","2015-02-06 12:36:59",21.73,20.3566666666667,504,801.666666666667,0.00326783347909749,1 +"2568","2015-02-06 12:38:00",21.73,20.29,489,799,0.00325707551170042,1 +"2569","2015-02-06 12:39:00",21.7,20.3566666666667,500.666666666667,799.666666666667,0.00326181459021045,1 +"2570","2015-02-06 12:40:00",21.7,20.2675,511,797.25,0.00324745253196683,1 +"2571","2015-02-06 12:40:59",21.7,20.2225,500.25,789.75,0.00324020464092953,1 +"2572","2015-02-06 12:42:00",21.7,20.2,494,780.25,0.00323658075842388,1 +"2573","2015-02-06 12:42:59",21.7,20.1666666666667,497.333333333333,782.333333333333,0.00323121212081626,1 +"2574","2015-02-06 12:43:59",21.7,20.1,495.666666666667,779.333333333333,0.00322047512218536,1 +"2575","2015-02-06 12:45:00",21.7,20.14,492,773.5,0.00322691727711109,1 +"2576","2015-02-06 12:46:00",21.7,20.15,509,771.666666666667,0.00322852783658594,1 +"2577","2015-02-06 12:47:00",21.7,20,509,769,0.00320437031566424,1 +"2578","2015-02-06 12:48:00",21.7,20,495.25,763,0.00320437031566424,1 +"2579","2015-02-06 12:49:00",21.7,20,499,760,0.00320437031566424,1 +"2580","2015-02-06 12:49:59",21.7,20.1,489,752,0.00322047512218536,1 +"2581","2015-02-06 12:51:00",21.7,20.125,481.25,757.5,0.00322450145345648,1 +"2582","2015-02-06 12:52:00",21.7,20.025,489,759,0.00320839643951202,1 +"2583","2015-02-06 12:53:00",21.7,20,377.75,757.75,0.00320437031566424,1 +"2584","2015-02-06 12:53:59",21.7,20.075,44,754.75,0.00321644884277157,0 +"2585","2015-02-06 12:55:00",21.7,20.075,60.25,755,0.00321644884277158,0 +"2586","2015-02-06 12:55:59",21.65,20.05,60.75,753.5,0.00320256516457624,0 +"2587","2015-02-06 12:56:59",21.65,20.05,57,760,0.00320256516457624,0 +"2588","2015-02-06 12:58:00",21.6,20,67,758,0.00318473164725866,0 +"2589","2015-02-06 12:59:00",21.6,20,66.5,751.75,0.00318473164725866,0 +"2590","2015-02-06 13:00:00",21.6,20,53,739.25,0.00318473164725866,0 +"2591","2015-02-06 13:01:00",21.5333333333333,19.9633333333333,58.3333333333333,732,0.00316585374749298,0 +"2592","2015-02-06 13:01:59",21.55,20,61.5,733,0.00317495209552161,0 +"2593","2015-02-06 13:02:59",21.525,20,48.5,723.5,0.00317007223832875,0 +"2594","2015-02-06 13:04:00",21.5,19.9725,62.5,720.25,0.00316082471837625,0 +"2595","2015-02-06 13:05:00",21.5,20,68.75,719.25,0.00316519898334311,0 +"2596","2015-02-06 13:06:00",21.5,19.9725,47,714.333333333333,0.00316082471837625,0 +"2597","2015-02-06 13:07:00",21.4725,19.945,54.5,713.4,0.00315111242045884,0 +"2598","2015-02-06 13:08:00",21.445,19.89,50,708,0.00313706376502723,0 +"2599","2015-02-06 13:08:59",21.39,19.89,50,708.5,0.00312645689641751,0 +"2600","2015-02-06 13:09:59",21.39,19.89,52.3333333333333,701,0.00312645689641751,0 +"2601","2015-02-06 13:11:00",21.39,19.89,57,692.5,0.00312645689641751,0 +"2602","2015-02-06 13:12:00",21.39,19.89,81.25,688.75,0.00312645689641751,0 +"2603","2015-02-06 13:13:00",21.39,19.6966666666667,50,689.666666666667,0.00309591607748975,0 +"2604","2015-02-06 13:14:00",21.34,19.7675,51.75,676.25,0.00309754985994537,0 +"2605","2015-02-06 13:14:59",21.29,19.7266666666667,58.3333333333333,671.333333333333,0.00308160987056291,0 +"2606","2015-02-06 13:15:59",21.29,19.6666666666667,131.333333333333,665.333333333333,0.00307219064941045,0 +"2607","2015-02-06 13:17:00",21.29,19.745,293.5,662.25,0.00308448802253734,1 +"2608","2015-02-06 13:18:00",21.29,19.7,440,660,0.00307742351500443,1 +"2609","2015-02-06 13:19:00",21.29,19.625,483.75,662.5,0.00306564969062438,1 +"2610","2015-02-06 13:20:00",21.29,19.575,492.75,658.75,0.00305780072077818,1 +"2611","2015-02-06 13:21:00",21.29,19.6,499,659.25,0.00306172518106119,1 +"2612","2015-02-06 13:21:59",21.29,19.55,489,652,0.00305387630977445,1 +"2613","2015-02-06 13:23:00",21.29,19.6,479,653.5,0.00306172518106119,1 +"2614","2015-02-06 13:24:00",21.29,19.55,486.5,658.5,0.00305387630977445,1 +"2615","2015-02-06 13:25:00",21.29,19.4175,489,656,0.00303307775413431,1 +"2616","2015-02-06 13:25:59",21.29,19.525,490.25,652.5,0.00304995194804905,1 +"2617","2015-02-06 13:27:00",21.29,19.6,486.5,658.5,0.00306172518106119,1 +"2618","2015-02-06 13:27:59",21.39,19.5,495,665.25,0.00306485175435598,1 +"2619","2015-02-06 13:28:59",21.39,19.5,480.666666666667,660,0.00306485175435598,1 +"2620","2015-02-06 13:30:00",21.39,19.5,485.25,663.25,0.00306485175435598,1 +"2621","2015-02-06 13:31:00",21.445,19.5,494,665,0.00307524859218901,1 +"2622","2015-02-06 13:32:00",21.5,19.5,500.666666666667,668.666666666667,0.00308567645329438,1 +"2623","2015-02-06 13:33:00",21.5,19.4725,508.5,667,0.00308130330108709,1 +"2624","2015-02-06 13:34:00",21.5,19.445,508.5,664,0.00307693021006926,1 +"2625","2015-02-06 13:34:59",21.5,19.4175,500.25,655.25,0.00307255718023959,1 +"2626","2015-02-06 13:36:00",21.5,19.4725,507.5,655.5,0.00308130330108709,1 +"2627","2015-02-06 13:37:00",21.5,19.445,516.5,659,0.00307693021006926,1 +"2628","2015-02-06 13:38:00",21.5,19.365,536.5,656.25,0.00306420883865291,1 +"2629","2015-02-06 13:38:59",21.5,19.39,514,659.5,0.00306818421159682,1 +"2630","2015-02-06 13:40:00",21.5,19.29,516.25,654,0.00305228302321123,1 +"2631","2015-02-06 13:40:59",21.5,19.315,546,647,0.00305625824446108,0 +"2632","2015-02-06 13:41:59",21.5,19.39,573,652.666666666667,0.00306818421159682,0 +"2633","2015-02-06 13:43:00",21.55,19.34,560.75,663.75,0.00306966160411553,0 +"2634","2015-02-06 13:44:00",21.6,19.3566666666667,524,652,0.0030817818824015,0 +"2635","2015-02-06 13:45:00",21.6,19.29,537,653,0.00307111545177247,0 +"2636","2015-02-06 13:46:00",21.625,19.2225,548.75,649.5,0.0030650234197501,0 +"2637","2015-02-06 13:46:59",21.7,19.34,541.5,640,0.00309809939732844,1 +"2638","2015-02-06 13:47:59",21.64,19.31,549.4,645.5,0.0030818848103959,1 +"2639","2015-02-06 13:49:00",21.7,19.1666666666667,509,646,0.00307019585285627,1 +"2640","2015-02-06 13:50:00",21.675,19.125,523.75,637.25,0.00305878636163381,1 +"2641","2015-02-06 13:51:00",21.7,19.12,559.5,632.25,0.0030626837857422,1 +"2642","2015-02-06 13:52:00",21.6333333333333,19.03,549.25,623.25,0.00303573426118885,1 +"2643","2015-02-06 13:53:00",21.6666666666667,19.2,525.333333333333,624,0.00306926860661904,1 +"2644","2015-02-06 13:53:59",21.7,19.2,535.5,633.5,0.00307556172562946,1 +"2645","2015-02-06 13:54:59",21.7,19.075,545.5,634.25,0.0030554401777391,1 +"2646","2015-02-06 13:56:00",21.7,19.1,551,626,0.0030594643836806,1 +"2647","2015-02-06 13:57:00",21.7225,19.1,586,629,0.00306369627833641,1 +"2648","2015-02-06 13:58:00",21.745,19.05,581.75,626.75,0.00305986257422779,1 +"2649","2015-02-06 13:59:00",21.76,19.0666666666667,557.666666666667,626.666666666667,0.00306537537622089,1 +"2650","2015-02-06 13:59:59",21.79,18.9933333333333,571,631,0.00305915765815247,1 +"2651","2015-02-06 14:00:59",21.79,19.05,555.5,629.75,0.00306832968772729,1 +"2652","2015-02-06 14:02:00",21.7675,19,525.25,625,0.00305601180447185,1 +"2653","2015-02-06 14:03:00",21.7675,19,543.75,626,0.00305601180447185,1 +"2654","2015-02-06 14:04:00",21.79,19,563.5,627,0.00306023670648439,1 +"2655","2015-02-06 14:05:00",21.79,19,551.666666666667,630.666666666667,0.00306023670648439,1 +"2656","2015-02-06 14:06:00",21.79,19.15,531,639.25,0.00308451627893368,1 +"2657","2015-02-06 14:06:59",21.76,19.0333333333333,553.333333333333,642.333333333333,0.00305998996399916,1 +"2658","2015-02-06 14:08:00",21.79,19.05,531.5,637,0.00306832968772729,1 +"2659","2015-02-06 14:09:00",21.79,19.1,546.5,654.5,0.003076422878541,1 +"2660","2015-02-06 14:10:00",21.79,19.2,524,658.5,0.00309260988891347,1 +"2661","2015-02-06 14:10:59",21.79,19.2,509,669,0.00309260988891347,1 +"2662","2015-02-06 14:12:00",21.8233333333333,19.23,537.666666666667,673,0.00310381135399823,1 +"2663","2015-02-06 14:12:59",21.89,19.3233333333333,524,680,0.0031317384210383,1 +"2664","2015-02-06 14:13:59",21.815,19.3675,543.25,683.5,0.00312451719861933,1 +"2665","2015-02-06 14:15:00",21.89,19.5,534.666666666667,688.333333333333,0.00316051632812739,1 +"2666","2015-02-06 14:16:00",21.89,19.55,526,709.75,0.00316866149987487,1 +"2667","2015-02-06 14:17:00",21.89,19.675,522,717.75,0.00318902535784885,1 +"2668","2015-02-06 14:18:00",21.89,19.5,549.5,717,0.00316051632812739,1 +"2669","2015-02-06 14:19:00",21.89,19.6,547.75,720.5,0.00317680688387084,1 +"2670","2015-02-06 14:19:59",21.89,19.76,552.333333333333,731,0.00320287353906441,1 +"2671","2015-02-06 14:21:00",21.945,19.79,551,735.5,0.00321860358164257,1 +"2672","2015-02-06 14:22:00",22,19.79,538.333333333333,735.666666666667,0.0032294781187166,1 +"2673","2015-02-06 14:23:00",22,19.7175,555.25,733.25,0.00321758583233142,1 +"2674","2015-02-06 14:23:59",22,19.7675,570,724.75,0.0032257873607345,1 +"2675","2015-02-06 14:25:00",22,19.84,570,729,0.00323767995912783,1 +"2676","2015-02-06 14:25:59",22,19.87,535.5,738,0.00324260116666447,1 +"2677","2015-02-06 14:26:59",22,20,559.333333333333,756.333333333333,0.00326392729455164,1 +"2678","2015-02-06 14:28:00",22,20,566,763.75,0.00326392729455164,1 +"2679","2015-02-06 14:29:00",22.05,20.05,557.25,773.75,0.00328217564472419,1 +"2680","2015-02-06 14:30:00",22.0666666666667,20.0666666666667,562,766,0.00328827575810693,1 +"2681","2015-02-06 14:31:00",22.1,20.075,566.25,760,0.0032963751832523,1 +"2682","2015-02-06 14:31:59",22.1,20.1333333333333,567.666666666667,767,0.00330600460238431,1 +"2683","2015-02-06 14:32:59",22.1,20.1975,562,768.5,0.00331659730598712,1 +"2684","2015-02-06 14:34:00",22.1,20.1,562,767.5,0.00330050204085022,1 +"2685","2015-02-06 14:35:00",22.1,20.1333333333333,554.333333333333,767.666666666667,0.00330600460238431,1 +"2686","2015-02-06 14:36:00",22.125,20.3175,556.75,769.25,0.00334152261381293,1 +"2687","2015-02-06 14:37:00",22.15,20.5,555,790,0.00337686823874045,1 +"2688","2015-02-06 14:38:00",22.1666666666667,20.4633333333333,543.666666666667,799.666666666667,0.00337423855854933,1 +"2689","2015-02-06 14:38:59",22.2,20.5,547,803.75,0.00338722518725759,1 +"2690","2015-02-06 14:39:59",22.2,20.445,539,804.5,0.00337808815466041,1 +"2691","2015-02-06 14:41:00",22.2,20.65,539,802.25,0.00341214572414583,1 +"2692","2015-02-06 14:42:00",22.2,20.7225,539,816.75,0.00342419136227514,1 +"2693","2015-02-06 14:43:00",22.2,20.55,538,812,0.0033955318122178,1 +"2694","2015-02-06 14:44:00",22.2,20.55,541.75,810.333333333333,0.0033955318122178,1 +"2695","2015-02-06 14:44:59",22.2,20.7225,530.5,827,0.00342419136227514,1 +"2696","2015-02-06 14:45:59",22.175,20.745,534.25,830.25,0.00342268518174602,1 +"2697","2015-02-06 14:47:00",22.2,20.65,519,826,0.00341214572414583,1 +"2698","2015-02-06 14:48:00",22.2,20.625,526.75,822.5,0.00340799216341012,1 +"2699","2015-02-06 14:49:00",22.2,20.6633333333333,512,832,0.00341436097909694,1 +"2700","2015-02-06 14:50:00",22.2,20.745,513.5,840,0.00342792975811009,1 +"2701","2015-02-06 14:51:00",22.1333333333333,20.8233333333333,498.666666666667,846,0.00342692208616013,1 +"2702","2015-02-06 14:51:59",22.1666666666667,20.8566666666667,528,853.333333333333,0.0034394546921402,1 +"2703","2015-02-06 14:53:00",22.175,20.8975,528,857.5,0.00344798539445085,1 +"2704","2015-02-06 14:54:00",22.2,20.7,513,860,0.00342045301113125,1 +"2705","2015-02-06 14:55:00",22.2,20.945,523.5,863.5,0.00346116190763739,1 +"2706","2015-02-06 14:55:59",22.2,20.92,523.5,865,0.00345700769581424,1 +"2707","2015-02-06 14:57:00",22.2,21.1475,526,875,0.00349481305730489,1 +"2708","2015-02-06 14:57:59",22.2,21.245,523.5,882.5,0.00351101675417691,1 +"2709","2015-02-06 14:58:59",22.2,21.34,528.75,888.25,0.00352680577917552,1 +"2710","2015-02-06 15:00:00",22.2,21.3175,528.75,894,0.00352306620121933,1 +"2711","2015-02-06 15:01:00",22.2,21.29,528.666666666667,895.333333333333,0.00351849566665982,1 +"2712","2015-02-06 15:02:00",22.2,21.4175,518,893,0.00353968688994445,1 +"2713","2015-02-06 15:03:00",22.175,21.445,518,890,0.00353883417428477,1 +"2714","2015-02-06 15:04:00",22.1666666666667,21.4633333333333,518,898,0.00354006896081683,1 +"2715","2015-02-06 15:04:59",22.175,21.39,513.5,899.25,0.00352970662038708,1 +"2716","2015-02-06 15:06:00",22.2,21.5,513.5,896,0.0035533996230805,1 +"2717","2015-02-06 15:07:00",22.2,21.2925,518.75,902.5,0.00351891116704162,1 +"2718","2015-02-06 15:08:00",22.2,21.4,519,903.333333333333,0.00353677820565809,1 +"2719","2015-02-06 15:08:59",22.2,21.445,509,904.5,0.00354425773419013,1 +"2720","2015-02-06 15:10:00",22.2,21.5,509,905,0.0035533996230805,1 +"2721","2015-02-06 15:10:59",22.2,21.575,512.75,910.75,0.00356586626583119,1 +"2722","2015-02-06 15:11:59",22.2,21.7675,509,915.25,0.00359786625673988,1 +"2723","2015-02-06 15:13:00",22.2,21.6666666666667,509,923.666666666667,0.00358110394844973,1 +"2724","2015-02-06 15:14:00",22.2,21.7675,508.75,930,0.00359786625673988,1 +"2725","2015-02-06 15:15:00",22.15,21.745,514,930.5,0.00358313262624067,1 +"2726","2015-02-06 15:16:00",22.2,21.7,514,925.25,0.00358664510799683,1 +"2727","2015-02-06 15:16:59",22.1666666666667,21.76,509,920.333333333333,0.00358928223034293,1 +"2728","2015-02-06 15:17:59",22.125,21.7475,499,922,0.0035780608196993,1 +"2729","2015-02-06 15:19:00",22.1,21.77,499,924,0.0035762995384961,1 +"2730","2015-02-06 15:20:00",22.1,21.4966666666667,499,919.333333333333,0.00353114237994918,1 +"2731","2015-02-06 15:21:00",22.1,21.1475,499,893.5,0.00347346634582456,1 +"2732","2015-02-06 15:22:00",22.1,21.67,496.5,884.5,0.00355977787054026,1 +"2733","2015-02-06 15:23:00",22.1,21.84,499,914,0.00358786522533605,1 +"2734","2015-02-06 15:23:59",22.1,21.6333333333333,490.666666666667,925,0.00355372014427706,1 +"2735","2015-02-06 15:24:59",22.1,21.1175,504,887,0.00346851138320822,1 +"2736","2015-02-06 15:26:00",22.1,21.575,500.25,884.25,0.00354408309428636,1 +"2737","2015-02-06 15:27:00",22.1,21.6,499,893.333333333333,0.00354821322220911,1 +"2738","2015-02-06 15:28:00",22.1,21.625,496.5,895,0.00355234340467021,1 +"2739","2015-02-06 15:29:00",22.1,21.2925,489,889.75,0.00349741643856871,1 +"2740","2015-02-06 15:29:59",22.1,21.15,489,880.5,0.00347387926291962,1 +"2741","2015-02-06 15:30:59",22.075,21.2225,489,864.75,0.00348051631237202,1 +"2742","2015-02-06 15:32:00",22.1,21.2,481.5,863,0.00348213771931191,1 +"2743","2015-02-06 15:33:00",22.05,21.3975,484,868.5,0.00350400342035632,1 +"2744","2015-02-06 15:34:00",22.0666666666667,21.4933333333333,487.333333333333,876.333333333333,0.00352338444382542,1 +"2745","2015-02-06 15:35:00",22.075,21.3925,484,880.5,0.00350855378876938,1 +"2746","2015-02-06 15:36:00",22.0333333333333,21.5666666666667,487.333333333333,883.666666666667,0.00352825509945877,1 +"2747","2015-02-06 15:36:59",22.1,21.595,484,892,0.00354738719226153,1 +"2748","2015-02-06 15:38:00",22.1,21.225,494,884.5,0.00348626702928911,1 +"2749","2015-02-06 15:39:00",22.1,21.145,494,883.5,0.00347305342927469,1 +"2750","2015-02-06 15:40:00",22.1,21.32,490.25,876,0.00350195890445361,1 +"2751","2015-02-06 15:40:59",22.1,21.5333333333333,479,882.333333333333,0.00353719966894183,1 +"2752","2015-02-06 15:42:00",22.1,21.3925,486.5,908.5,0.00351393481258797,1 +"2753","2015-02-06 15:42:59",22.1,21.1633333333333,479,892.333333333333,0.00347608149663426,1 +"2754","2015-02-06 15:43:59",22.1,21.365,479,878.25,0.00350939217276125,1 +"2755","2015-02-06 15:45:00",22.1,21.0666666666667,479,870,0.00346011565354069,1 +"2756","2015-02-06 15:46:00",22.1,20.9633333333333,479,866.666666666667,0.0034430496191381,1 +"2757","2015-02-06 15:47:00",22.1,21.26,479,863.333333333333,0.00349204815485463,1 +"2758","2015-02-06 15:48:00",22.1,21.445,479,883.5,0.00352260730820437,1 +"2759","2015-02-06 15:49:00",22.1,21.4633333333333,479,896,0.0035256358553889,1 +"2760","2015-02-06 15:49:59",22.1,21.445,475.25,901.75,0.00352260730820437,1 +"2761","2015-02-06 15:51:00",22.1,21.2475,471.5,896.5,0.00348998345488499,1 +"2762","2015-02-06 15:52:00",22.0666666666667,21.0666666666667,464,876.333333333333,0.00345305303685636,1 +"2763","2015-02-06 15:53:00",22.075,21.1725,467.75,865,0.00347227047412126,1 +"2764","2015-02-06 15:53:59",22.05,21.2425,474.5,872,0.00347847904214117,1 +"2765","2015-02-06 15:55:00",22,20.795,474.5,873.5,0.00339437642728385,1 +"2766","2015-02-06 15:55:59",22,20.9633333333333,478,854,0.00342200471525666,1 +"2767","2015-02-06 15:56:59",22,21.2425,474.5,865.25,0.00346782928719183,1 +"2768","2015-02-06 15:58:00",22,20.94,474.5,870.5,0.00341817490584495,1 +"2769","2015-02-06 15:59:00",22,21.1566666666667,478,858.666666666667,0.00345373922628695,1 +"2770","2015-02-06 16:00:00",22.0083333333333,21.0841666666667,478.3,861.633333333333,0.00344359800926237,1 +"2771","2015-02-06 16:01:00",22.0166666666667,21.0116666666667,478.6,864.6,0.00343344579955854,1 +"2772","2015-02-06 16:01:59",22,20.92,477,858.25,0.00341489224939515,1 +"2773","2015-02-06 16:02:59",21.9725,21.315,473,869.75,0.00347386580187436,1 +"2774","2015-02-06 16:04:00",22,21.15,469,877.75,0.00345264487919242,1 +"2775","2015-02-06 16:05:00",22,20.8675,469,867.75,0.00340627544016454,1 +"2776","2015-02-06 16:06:00",22,20.945,469,861,0.00341899557534175,1 +"2777","2015-02-06 16:07:00",22,21.32,469,866.5,0.00348055192640452,1 +"2778","2015-02-06 16:08:00",22,21.3925,469,880.75,0.00349245421876394,1 +"2779","2015-02-06 16:08:59",22,21.05,469,880,0.0034362301323054,1 +"2780","2015-02-06 16:09:59",22,21.2725,469,874,0.00347275411839211,1 +"2781","2015-02-06 16:11:00",21.9633333333333,21.4633333333333,469,885.666666666667,0.00349620985466609,1 +"2782","2015-02-06 16:12:00",21.9725,21.3925,469,901.25,0.00348656736016295,1 +"2783","2015-02-06 16:13:00",21.9633333333333,21.29,469,893.666666666667,0.00346781778870521,1 +"2784","2015-02-06 16:14:00",21.89,21.1725,469,886.5,0.00343308756312797,1 +"2785","2015-02-06 16:14:59",21.89,21.3233333333333,469,879,0.00345768090875961,1 +"2786","2015-02-06 16:15:59",21.9175,21.315,469,879,0.00346216132025755,1 +"2787","2015-02-06 16:17:00",21.89,21.39,469,884.25,0.00346855151214028,1 +"2788","2015-02-06 16:18:00",21.89,21.245,469,877,0.00344490843261269,1 +"2789","2015-02-06 16:19:00",21.89,21.22,469,875.75,0.00344083222024682,1 +"2790","2015-02-06 16:20:00",21.89,21.34,469,877,0.00346039852418017,1 +"2791","2015-02-06 16:21:00",21.89,21.29,461.5,879,0.00345224574876583,1 +"2792","2015-02-06 16:21:59",21.89,21.1725,454,871.75,0.00343308756312797,1 +"2793","2015-02-06 16:23:00",21.89,21.5225,454,880.5,0.00349015795822132,1 +"2794","2015-02-06 16:24:00",21.89,21.39,454,895.666666666667,0.00346855151214028,1 +"2795","2015-02-06 16:25:00",21.89,21.2675,454,896,0.00344857706917022,1 +"2796","2015-02-06 16:25:59",21.865,21.32,459.25,883,0.00345183528393358,1 +"2797","2015-02-06 16:27:00",21.89,21.4966666666667,468,889,0.00348594526353529,1 +"2798","2015-02-06 16:27:59",21.865,21.3175,464.5,890.5,0.00345142827299996,1 +"2799","2015-02-06 16:28:59",21.79,21.53,468,897,0.00347000470919691,1 +"2800","2015-02-06 16:30:00",21.84,21.4425,464.5,913.75,0.0034664537615766,1 +"2801","2015-02-06 16:31:00",21.79,21.1975,464.5,902.5,0.00341612113804534,1 +"2802","2015-02-06 16:32:00",21.76,21.2,468,890.333333333333,0.00341023488811576,1 +"2803","2015-02-06 16:33:00",21.745,21.1725,457,876,0.00340264928168776,1 +"2804","2015-02-06 16:34:00",21.79,21.445,464.5,890,0.00345622907830983,1 +"2805","2015-02-06 16:34:59",21.745,21.34,453.25,893,0.00342971677171415,1 +"2806","2015-02-06 16:36:00",21.73,21.2933333333333,453,891.666666666667,0.00341902206993455,1 +"2807","2015-02-06 16:37:00",21.7225,21.5225,454.75,897.5,0.00345443046971391,1 +"2808","2015-02-06 16:38:00",21.7225,21.5225,460,903.75,0.00345443046971391,1 +"2809","2015-02-06 16:38:59",21.7,21.34,460,908.5,0.00342024367621835,1 +"2810","2015-02-06 16:40:00",21.73,21.5666666666667,460,907,0.0034631549424416,1 +"2811","2015-02-06 16:40:59",21.7225,21.525,460,910.5,0.00345483395650013,1 +"2812","2015-02-06 16:41:59",21.745,21.675,460,917.25,0.00348385878127766,1 +"2813","2015-02-06 16:43:00",21.79,21.6,460,926.5,0.00348134980204223,1 +"2814","2015-02-06 16:44:00",21.79,21.55,460,925,0.00347324612229958,1 +"2815","2015-02-06 16:45:00",21.79,21.6333333333333,460,921.666666666667,0.00348675237186268,1 +"2816","2015-02-06 16:46:00",21.7675,21.7675,460,934,0.00350365142677427,1 +"2817","2015-02-06 16:46:59",21.7675,21.865,460,947.25,0.00351943362075633,1 +"2818","2015-02-06 16:47:59",21.79,21.8233333333333,460,953,0.00351754880204338,1 +"2819","2015-02-06 16:49:00",21.79,21.8175,460,959,0.00351660325248453,1 +"2820","2015-02-06 16:50:00",21.79,21.945,460,959.5,0.00353727091588678,1 +"2821","2015-02-06 16:51:00",21.7675,21.6975,444,962,0.00349232111196078,1 +"2822","2015-02-06 16:52:00",21.76,21.8266666666667,449.333333333333,944,0.0035116096895995,1 +"2823","2015-02-06 16:53:00",21.7225,21.8925,444,953.5,0.00351415217755142,1 +"2824","2015-02-06 16:53:59",21.745,21.815,444,949,0.0035064880701341,1 +"2825","2015-02-06 16:54:59",21.7,21.8233333333333,444,948.666666666667,0.00349814503312957,1 +"2826","2015-02-06 16:56:00",21.745,21.815,444,952.75,0.0035064880701341,1 +"2827","2015-02-06 16:57:00",21.7225,21.97,444,951.25,0.00352666289886336,1 +"2828","2015-02-06 16:58:00",21.79,22.05,444,961.5,0.00355429237009922,1 +"2829","2015-02-06 16:59:00",21.79,21.775,444,964.25,0.00350971433483896,1 +"2830","2015-02-06 16:59:59",21.7675,21.745,444,951,0.00350000949510484,1 +"2831","2015-02-06 17:00:59",21.79,21.7933333333333,444,945.666666666667,0.00351268600619375,1 +"2832","2015-02-06 17:02:00",21.79,21.7225,444,936,0.00350120470488396,1 +"2833","2015-02-06 17:03:00",21.7675,21.79,444,935,0.00350729340085375,1 +"2834","2015-02-06 17:04:00",21.79,21.745,444,938,0.00350485166079896,1 +"2835","2015-02-06 17:05:00",21.7675,21.8175,444,926.75,0.00351174476010142,1 +"2836","2015-02-06 17:06:00",21.7675,21.89,444,932,0.00352348046544661,1 +"2837","2015-02-06 17:06:59",21.79,21.79,447.4,942,0.00351214570021089,1 +"2838","2015-02-06 17:08:00",21.79,21.79,450.666666666667,935,0.00351214570021089,1 +"2839","2015-02-06 17:09:00",21.79,21.79,449,937.5,0.00351214570021089,1 +"2840","2015-02-06 17:10:00",21.79,21.65,438,927.25,0.00348945369177141,1 +"2841","2015-02-06 17:10:59",21.79,21.6,438,916.5,0.00348134980204223,1 +"2842","2015-02-06 17:12:00",21.79,21.745,438,914,0.00350485166079896,1 +"2843","2015-02-06 17:12:59",21.79,21.7,441,910,0.00349755779149528,1 +"2844","2015-02-06 17:13:59",21.79,21.65,437.25,923,0.00348945369177141,1 +"2845","2015-02-06 17:15:00",21.84,21.65,436.5,918.75,0.00350018755285245,1 +"2846","2015-02-06 17:16:00",21.84,21.6,429,904,0.00349205859568566,1 +"2847","2015-02-06 17:17:00",21.79,21.395,432.75,901,0.00344812604947353,1 +"2848","2015-02-06 17:18:00",21.79,21.6,438,893,0.00348134980204223,1 +"2849","2015-02-06 17:19:00",21.79,21.6225,438,885.5,0.00348499652643404,1 +"2850","2015-02-06 17:19:59",21.745,21.575,438,890,0.00346769600595279,1 +"2851","2015-02-06 17:21:00",21.7225,21.5475,438,886.5,0.00345846536100259,1 +"2852","2015-02-06 17:22:00",21.7,21.4266666666667,441,887,0.00343421076761939,1 +"2853","2015-02-06 17:23:00",21.7,21.525,438,883.25,0.003450058799875,1 +"2854","2015-02-06 17:23:59",21.7,21.445,438,874,0.00343716542458736,1 +"2855","2015-02-06 17:25:00",21.7,21.575,447,874,0.00345811742938302,1 +"2856","2015-02-06 17:25:59",21.7,21.5333333333333,447,871.666666666667,0.0034514018903721,1 +"2857","2015-02-06 17:26:59",21.7,21.6,447,879.25,0.00346214682201126,1 +"2858","2015-02-06 17:28:00",21.7,21.516,441.4,872.75,0.00344860826861707,1 +"2859","2015-02-06 17:29:00",21.7,21.36,447,868.5,0.00342346679578799,1 +"2860","2015-02-06 17:30:00",21.7,21.5,443.5,859.75,0.00344602956299322,1 +"2861","2015-02-06 17:31:00",21.7,21.2675,433,848.25,0.00340856014625599,1 +"2862","2015-02-06 17:31:59",21.6666666666667,21.39,433,843,0.00342128270265622,1 +"2863","2015-02-06 17:32:59",21.625,21.315,433,849,0.00340049615612859,1 +"2864","2015-02-06 17:34:00",21.6,21.39,433,841.666666666667,0.00340728297921016,1 +"2865","2015-02-06 17:35:00",21.6,21.39,433,847.5,0.00340728297921016,1 +"2866","2015-02-06 17:36:00",21.6,21.34,433,844.25,0.00339927478840595,1 +"2867","2015-02-06 17:37:00",21.6,21.3233333333333,433,844.333333333333,0.00339660543704568,1 +"2868","2015-02-06 17:38:00",21.6,21.29,433,838.75,0.00339126680268506,1 +"2869","2015-02-06 17:38:59",21.6,21.29,433,831.666666666667,0.00339126680268506,1 +"2870","2015-02-06 17:39:59",21.6,21.2675,433,822.25,0.00338766327601699,1 +"2871","2015-02-06 17:41:00",21.6,21.2,433,817.5,0.00337685294517225,1 +"2872","2015-02-06 17:42:00",21.6,21.1333333333333,433,819,0.00336617644203402,1 +"2873","2015-02-06 17:43:00",21.6,21.1333333333333,433,817.666666666667,0.00336617644203402,1 +"2874","2015-02-06 17:44:00",21.6,21.2,433,818,0.00337685294517225,1 +"2875","2015-02-06 17:44:59",21.625,21.2225,433,819.75,0.00338565881037238,1 +"2876","2015-02-06 17:45:59",21.65,21.2,433,819.5,0.00338725376047017,1 +"2877","2015-02-06 17:47:00",21.6666666666667,21.2266666666667,433,813,0.00339501530594985,1 +"2878","2015-02-06 17:48:00",21.65,21.125,433,811.75,0.00337520552602053,1 +"2879","2015-02-06 17:49:00",21.675,21.175,433,813.75,0.00338844239496995,1 +"2880","2015-02-06 17:50:00",21.7,21.125,433,812,0.00338559723882264,1 +"2881","2015-02-06 17:51:00",21.7,21.05,433,801,0.00337351217535461,1 +"2882","2015-02-06 17:51:59",21.6333333333333,20.9633333333333,433,801,0.00334580555339045,1 +"2883","2015-02-06 17:53:00",21.675,21.175,433,798.75,0.00338844239496995,1 +"2884","2015-02-06 17:54:00",21.7,21.08,433,805.75,0.00337834614469325,1 +"2885","2015-02-06 17:55:00",21.7,20.89,433,802.25,0.00334773226760308,1 +"2886","2015-02-06 17:55:59",21.625,20.9975,433,791.5,0.00334957090815663,1 +"2887","2015-02-06 17:57:00",21.65,20.9175,433,790.5,0.00334187449611367,1 +"2888","2015-02-06 17:57:59",21.65,20.89,433,780.5,0.00333745739733991,1 +"2889","2015-02-06 17:58:59",21.7,20.9175,433,781,0.0033521630379841,1 +"2890","2015-02-06 18:00:00",21.7,20.9633333333333,433,780.333333333333,0.00335954779481322,1 +"2891","2015-02-06 18:01:00",21.7,20.8566666666667,433,778,0.00334236172101358,1 +"2892","2015-02-06 18:02:00",21.7,20.865,433,778.5,0.00334370434901292,1 +"2893","2015-02-06 18:03:00",21.7,20.945,433,780.75,0.00335659387115217,1 +"2894","2015-02-06 18:04:00",21.7,20.84,433,772,0.00333967648231076,1 +"2895","2015-02-06 18:04:59",21.7,20.89,433,777,0.00334773226760308,1 +"2896","2015-02-06 18:06:00",21.7,20.89,426,780.5,0.00334773226760308,1 +"2897","2015-02-06 18:07:00",21.7,20.84,0,778.5,0.00333967648231076,0 +"2898","2015-02-06 18:08:00",21.675,20.9725,0,781.25,0.00335586333441947,0 +"2899","2015-02-06 18:08:59",21.65,20.795,0,780.5,0.00332219880895834,0 +"2900","2015-02-06 18:10:00",21.6,20.6,0,775.5,0.00328077753860833,0 +"2901","2015-02-06 18:10:59",21.5333333333333,20.7,0,763.333333333333,0.00328329353292887,0 +"2902","2015-02-06 18:11:59",21.5,20.6,0,758,0.003260652731688,0 +"2903","2015-02-06 18:13:00",21.5,20.7,0,750.5,0.00327656452373195,0 +"2904","2015-02-06 18:14:00",21.5,20.7,0,746,0.00327656452373195,0 +"2905","2015-02-06 18:15:00",21.5,20.65,0,750,0.00326860852647943,0 +"2906","2015-02-06 18:16:00",21.5,20.7,0,740,0.00327656452373195,0 +"2907","2015-02-06 18:16:59",21.445,20.6,0,738.5,0.00324963047449355,0 +"2908","2015-02-06 18:17:59",21.39,20.5,0,730.666666666667,0.00322283801142109,0 +"2909","2015-02-06 18:19:00",21.39,20.5,0,725.5,0.00322283801142109,0 +"2910","2015-02-06 18:20:00",21.39,20.5,0,724,0.00322283801142109,0 +"2911","2015-02-06 18:21:00",21.39,20.5,0,722.5,0.00322283801142109,0 +"2912","2015-02-06 18:22:00",21.39,20.5,0,719,0.00322283801142109,0 +"2913","2015-02-06 18:23:00",21.3233333333333,20.5,0,711,0.00320962645897761,0 +"2914","2015-02-06 18:23:59",21.3233333333333,20.5,0,703.666666666667,0.00320962645897761,0 +"2915","2015-02-06 18:24:59",21.29,20.5,0,703,0.00320303857907321,0 +"2916","2015-02-06 18:26:00",21.29,20.3933333333333,0,704.333333333333,0.00318628698691509,0 +"2917","2015-02-06 18:27:00",21.29,20.29,0,689,0.00317005973802837,0 +"2918","2015-02-06 18:28:00",21.2,20.29,0,686.5,0.00315251532968655,0 +"2919","2015-02-06 18:29:00",21.2,20.245,0,674.5,0.00314548819317666,0 +"2920","2015-02-06 18:29:59",21.2,20.15,0,672,0.00313065364599599,0 +"2921","2015-02-06 18:30:59",21.2,20.2,0,666.5,0.00313846121464453,0 +"2922","2015-02-06 18:32:00",21.175,20.2,0,664.75,0.00313362472876263,0 +"2923","2015-02-06 18:33:00",21.1,20.15,0,664.5,0.00311139531096488,0 +"2924","2015-02-06 18:34:00",21.1,20.2,0,661,0.00311915461141429,0 +"2925","2015-02-06 18:35:00",21.1,20.2,0,649.5,0.00311915461141429,0 +"2926","2015-02-06 18:36:00",21.1,20.1,0,647,0.00310363620313794,0 +"2927","2015-02-06 18:36:59",21.1,20.1,0,645.5,0.00310363620313794,0 +"2928","2015-02-06 18:38:00",21.05,20.05,0,644,0.00308633535114804,0 +"2929","2015-02-06 18:39:00",21,20,0,636.5,0.00306910858506558,0 +"2930","2015-02-06 18:40:00",21,20,0,630.5,0.00306910858506558,0 +"2931","2015-02-06 18:40:59",21,20,0,626,0.00306910858506558,0 +"2932","2015-02-06 18:42:00",21,20,0,625,0.00306910858506558,0 +"2933","2015-02-06 18:42:59",21,20,0,625.5,0.00306910858506558,0 +"2934","2015-02-06 18:43:59",21,19.945,0,624,0.00306062700616612,0 +"2935","2015-02-06 18:45:00",21,19.89,0,614,0.00305214565743707,0 +"2936","2015-02-06 18:46:00",20.89,20,0,616.5,0.00304831664828052,0 +"2937","2015-02-06 18:47:00",20.9266666666667,20,0,609.666666666667,0.00305523347455462,0 +"2938","2015-02-06 18:48:00",21,19.8933333333333,0,607.5,0.00305265967202019,0 +"2939","2015-02-06 18:49:00",21,19.89,0,602,0.00305214565743707,0 +"2940","2015-02-06 18:49:59",21,19.89,0,598,0.00305214565743707,0 +"2941","2015-02-06 18:51:00",20.89,19.79,0,595.5,0.00301615411603875,0 +"2942","2015-02-06 18:52:00",21,19.79,0,593,0.00303672561304647,0 +"2943","2015-02-06 18:53:00",20.89,19.79,0,592,0.00301615411603875,0 +"2944","2015-02-06 18:53:59",20.89,19.79,0,582,0.00301615411603875,0 +"2945","2015-02-06 18:55:00",20.89,19.79,0,581.666666666667,0.00301615411603875,0 +"2946","2015-02-06 18:55:59",20.89,19.79,0,576.5,0.00301615411603875,0 +"2947","2015-02-06 18:56:59",20.945,19.79,0,572.5,0.00302642448004896,0 +"2948","2015-02-06 18:58:00",20.89,19.79,0,575.5,0.00301615411603875,0 +"2949","2015-02-06 18:59:00",20.89,19.745,0,578.5,0.00300926257546607,0 +"2950","2015-02-06 19:00:00",21,19.79,0,578,0.00303672561304647,0 +"2951","2015-02-06 19:01:00",20.945,19.7,0,572.5,0.00301259439214521,0 +"2952","2015-02-06 19:01:59",20.9633333333333,19.6333333333333,0,574.333333333333,0.00300575314746671,0 +"2953","2015-02-06 19:02:59",20.945,19.695,0,570,0.003011826071874,0 +"2954","2015-02-06 19:04:00",21,19.5,0,569,0.00299201178647348,0 +"2955","2015-02-06 19:05:00",20.89,19.65,0,562,0.0029947142666563,0 +"2956","2015-02-06 19:06:00",20.89,19.5,0,562,0.00297174463164605,0 +"2957","2015-02-06 19:07:00",20.79,19.6,0,550,0.0029686429518897,0 +"2958","2015-02-06 19:08:00",20.84,19.65,0,551,0.00298547070121526,0 +"2959","2015-02-06 19:08:59",20.79,19.6,0,551.666666666667,0.0029686429518897,0 +"2960","2015-02-06 19:09:59",20.79,19.6,0,547,0.0029686429518897,0 +"2961","2015-02-06 19:11:00",20.79,19.5,0,537,0.00295342489640642,0 +"2962","2015-02-06 19:12:00",20.7,19.39,0,532.5,0.00292037659066632,0 +"2963","2015-02-06 19:13:00",20.79,19.5,0,533,0.00295342489640642,0 +"2964","2015-02-06 19:14:00",20.745,19.445,0,536,0.00293686726080581,0 +"2965","2015-02-06 19:14:59",20.7,19.4266666666667,0,530,0.00292592502738214,0 +"2966","2015-02-06 19:15:59",20.7,19.4725,0,531.4,0.00293286071182929,0 +"2967","2015-02-06 19:17:00",20.7,19.445,0,520,0.00292869928268711,0 +"2968","2015-02-06 19:18:00",20.7,19.39,0,521.5,0.00292037659066632,0 +"2969","2015-02-06 19:19:00",20.7,19.5,0,528.5,0.00293702219639414,0 +"2970","2015-02-06 19:20:00",20.7,19.5,0,530,0.00293702219639414,0 +"2971","2015-02-06 19:21:00",20.6333333333333,19.3233333333333,0,523.666666666667,0.00289830100827254,0 +"2972","2015-02-06 19:21:59",20.6,19.29,0,525,0.00288731093257501,0 +"2973","2015-02-06 19:23:00",20.6,19.34,0,523,0.00289482972125133,0 +"2974","2015-02-06 19:24:00",20.6,19.3566666666667,0,525,0.00289733602435152,0 +"2975","2015-02-06 19:25:00",20.6,19.29,0,517.5,0.00288731093257501,0 +"2976","2015-02-06 19:25:59",20.6,19.39,0,519.5,0.00290234869086544,0 +"2977","2015-02-06 19:27:00",20.6333333333333,19.39,0,519.333333333333,0.00290834707652056,0 +"2978","2015-02-06 19:27:59",20.6,19.29,0,516,0.00288731093257501,0 +"2979","2015-02-06 19:28:59",20.6,19.29,0,516,0.00288731093257501,0 +"2980","2015-02-06 19:30:00",20.65,19.29,0,513.5,0.00289626574477497,0 +"2981","2015-02-06 19:31:00",20.6,19.29,0,509.5,0.00288731093257501,0 +"2982","2015-02-06 19:32:00",20.5,19.29,0,502,0.00286947438284154,0 +"2983","2015-02-06 19:33:00",20.5,19.29,0,503,0.00286947438284154,0 +"2984","2015-02-06 19:34:00",20.5,19.29,0,501,0.00286947438284154,0 +"2985","2015-02-06 19:34:59",20.39,19.245,0,500.5,0.00284328742231428,0 +"2986","2015-02-06 19:36:00",20.34,19.29,0,498,0.00284113758590851,0 +"2987","2015-02-06 19:37:00",20.39,19.445,0,499,0.0028729722272785,0 +"2988","2015-02-06 19:38:00",20.39,19.29,0,497,0.00284996625752727,0 +"2989","2015-02-06 19:38:59",20.39,19.34,0,498,0.00285738735299901,0 +"2990","2015-02-06 19:40:00",20.39,19.29,0,492,0.00284996625752727,0 +"2991","2015-02-06 19:40:59",20.5,19.29,0,492.5,0.00286947438284154,0 +"2992","2015-02-06 19:41:59",20.5,19.29,0,491.5,0.00286947438284154,0 +"2993","2015-02-06 19:43:00",20.445,19.245,0,492,0.00285300391506558,0 +"2994","2015-02-06 19:44:00",20.39,19.29,0,490.5,0.00284996625752727,0 +"2995","2015-02-06 19:45:00",20.39,19.34,0,492,0.00285738735299901,0 +"2996","2015-02-06 19:46:00",20.5,19.34,0,489.5,0.00287694650987218,0 +"2997","2015-02-06 19:46:59",20.445,19.29,0,488,0.00285970567861715,0 +"2998","2015-02-06 19:47:59",20.39,19.29,0,484.5,0.00284996625752727,0 +"2999","2015-02-06 19:49:00",20.39,19.245,0,485.5,0.00284328742231428,0 +"3000","2015-02-06 19:50:00",20.445,19.29,0,481.5,0.00285970567861715,0 +"3001","2015-02-06 19:51:00",20.5,19.29,0,484,0.00286947438284154,0 +"3002","2015-02-06 19:52:00",20.5,19.29,0,483,0.00286947438284154,0 +"3003","2015-02-06 19:53:00",20.5,19.29,0,479,0.00286947438284154,0 +"3004","2015-02-06 19:53:59",20.5,19.245,0,483,0.00286274962130062,0 +"3005","2015-02-06 19:54:59",20.5,19.26,0,479,0.00286499119239843,0 +"3006","2015-02-06 19:56:00",20.5,19.2,0,481,0.0028560250045001,0 +"3007","2015-02-06 19:57:00",20.39,19.2,0,477,0.00283660872987593,0 +"3008","2015-02-06 19:58:00",20.39,19.2,0,475,0.00283660872987593,0 +"3009","2015-02-06 19:59:00",20.39,19.29,0,474,0.00284996625752727,0 +"3010","2015-02-06 19:59:59",20.39,19.245,0,476,0.00284328742231428,0 +"3011","2015-02-06 20:00:59",20.39,19.2,0,472,0.00283660872987593,0 +"3012","2015-02-06 20:02:00",20.39,19.2,0,474,0.00283660872987593,0 +"3013","2015-02-06 20:03:00",20.39,19.2,0,479,0.00283660872987593,0 +"3014","2015-02-06 20:04:00",20.39,19.2,0,476,0.00283660872987593,0 +"3015","2015-02-06 20:05:00",20.39,19.245,0,476.5,0.00284328742231428,0 +"3016","2015-02-06 20:06:00",20.39,19.2,0,472.333333333333,0.00283660872987593,0 +"3017","2015-02-06 20:06:59",20.39,19.245,0,473,0.00284328742231428,0 +"3018","2015-02-06 20:08:00",20.39,19.2,0,471,0.00283660872987593,0 +"3019","2015-02-06 20:09:00",20.445,19.2,0,471.5,0.00284630229526837,0 +"3020","2015-02-06 20:10:00",20.5,19.2,0,467,0.0028560250045001,0 +"3021","2015-02-06 20:10:59",20.5,19.2,0,455,0.0028560250045001,0 +"3022","2015-02-06 20:12:00",20.445,19.15,0,458.5,0.00283885621964441,0 +"3023","2015-02-06 20:12:59",20.39,19.1,0,462,0.00282176770226941,0 +"3024","2015-02-06 20:13:59",20.39,19.1,0,465,0.00282176770226941,0 +"3025","2015-02-06 20:15:00",20.39,19.2,0,468.5,0.00283660872987593,0 +"3026","2015-02-06 20:16:00",20.39,19.1,0,463,0.00282176770226941,0 +"3027","2015-02-06 20:17:00",20.39,19.1,0,458.5,0.00282176770226941,0 +"3028","2015-02-06 20:18:00",20.39,19.2,0,454,0.00283660872987593,0 +"3029","2015-02-06 20:19:00",20.39,19.15,0,462,0.00282918812794615,0 +"3030","2015-02-06 20:19:59",20.39,19.1,0,463.333333333333,0.00282176770226941,0 +"3031","2015-02-06 20:21:00",20.39,19.1,0,458,0.00282176770226941,0 +"3032","2015-02-06 20:22:00",20.29,19.1666666666667,0,460,0.00281414214528258,0 +"3033","2015-02-06 20:23:00",20.29,19.2,0,457,0.00281905848708509,0 +"3034","2015-02-06 20:23:59",20.29,19.1,0,466,0.00280430969377713,0 +"3035","2015-02-06 20:25:00",20.29,19.2,0,465.5,0.00281905848708509,0 +"3036","2015-02-06 20:25:59",20.29,19.2,0,461.5,0.00281905848708509,0 +"3037","2015-02-06 20:26:59",20.2675,19.175,0,458,0.00281144078687036,0 +"3038","2015-02-06 20:28:00",20.245,19.245,0,464,0.00281781068918898,0 +"3039","2015-02-06 20:29:00",20.245,19.245,0,465.5,0.00281781068918898,0 +"3040","2015-02-06 20:30:00",20.29,19.245,0,464,0.00282569567124529,0 +"3041","2015-02-06 20:31:00",20.245,19.245,0,459.5,0.00281781068918898,0 +"3042","2015-02-06 20:31:59",20.29,19.245,0,455.5,0.00282569567124529,0 +"3043","2015-02-06 20:32:59",20.29,19.2,0,454,0.00281905848708509,0 +"3044","2015-02-06 20:34:00",20.29,19.2,0,457.666666666667,0.00281905848708509,0 +"3045","2015-02-06 20:35:00",20.29,19.2,0,462,0.00281905848708509,0 +"3046","2015-02-06 20:36:00",20.29,19.2,0,457,0.00281905848708509,0 +"3047","2015-02-06 20:37:00",20.26,19.1966666666667,0,458.666666666667,0.00281332136702797,0 +"3048","2015-02-06 20:38:00",20.29,19.29,0,459,0.00283233299641491,0 +"3049","2015-02-06 20:38:59",20.29,19.2,0,452,0.00281905848708509,0 +"3050","2015-02-06 20:39:59",20.29,19.2,0,455,0.00281905848708509,0 +"3051","2015-02-06 20:41:00",20.29,19.1,0,458,0.00280430969377713,0 +"3052","2015-02-06 20:42:00",20.29,19.2,0,459.5,0.00281905848708509,0 +"3053","2015-02-06 20:43:00",20.29,19.2,0,452.5,0.00281905848708509,0 +"3054","2015-02-06 20:44:00",20.29,19.2,0,451,0.00281905848708509,0 +"3055","2015-02-06 20:44:59",20.29,19.2,0,455,0.00281905848708509,0 +"3056","2015-02-06 20:45:59",20.245,19.2,0,452.5,0.00281119210913326,0 +"3057","2015-02-06 20:47:00",20.2,19.15,0,449,0.00279601186423001,0 +"3058","2015-02-06 20:48:00",20.2,19.2,0,452,0.00280334505861515,0 +"3059","2015-02-06 20:49:00",20.29,19.2,0,454,0.00281905848708509,0 +"3060","2015-02-06 20:50:00",20.2,19.1,0,453,0.00278867884197938,0 +"3061","2015-02-06 20:51:00",20.2,19.1,0,449,0.00278867884197938,0 +"3062","2015-02-06 20:51:59",20.2,19.1,0,450,0.00278867884197938,0 +"3063","2015-02-06 20:53:00",20.15,19.1,0,450,0.00278002821422076,0 +"3064","2015-02-06 20:54:00",20.2,19.2,0,452,0.00280334505861515,0 +"3065","2015-02-06 20:55:00",20.2,19.2,0,448.5,0.00280334505861515,0 +"3066","2015-02-06 20:55:59",20.2,19.1333333333333,0,448.666666666667,0.00279356750435404,0 +"3067","2015-02-06 20:57:00",20.15,19.15,0,452,0.00278733838757056,0 +"3068","2015-02-06 20:57:59",20.2,19.1,0,461.5,0.00278867884197938,0 +"3069","2015-02-06 20:58:59",20.2,19.1,0,455,0.00278867884197938,0 +"3070","2015-02-06 21:00:00",20.2,19,0,455,0.0027740133138574,0 +"3071","2015-02-06 21:01:00",20.2,19.1,0,450,0.00278867884197938,0 +"3072","2015-02-06 21:02:00",20.2,19.1,0,449,0.00278867884197938,0 +"3073","2015-02-06 21:03:00",20.2,19.0666666666667,0,449.333333333333,0.00278379025610625,0 +"3074","2015-02-06 21:04:00",20.2,19.1,0,450,0.00278867884197938,0 +"3075","2015-02-06 21:04:59",20.2,19,0,447,0.0027740133138574,0 +"3076","2015-02-06 21:06:00",20.2,19.1,0,445,0.00278867884197938,0 +"3077","2015-02-06 21:07:00",20.2,19.1,0,446,0.00278867884197938,0 +"3078","2015-02-06 21:08:00",20.2,19,0,450,0.0027740133138574,0 +"3079","2015-02-06 21:08:59",20.2,19.0333333333333,0,452.333333333333,0.00277890174673286,0 +"3080","2015-02-06 21:10:00",20.2,19.05,0,448,0.0027813459918572,0 +"3081","2015-02-06 21:10:59",20.15,19.1,0,447.5,0.00278002821422076,0 +"3082","2015-02-06 21:11:59",20.2,19.1,0,448.5,0.00278867884197938,0 +"3083","2015-02-06 21:13:00",20.2,19.1,0,447,0.00278867884197938,0 +"3084","2015-02-06 21:14:00",20.2,19.1,0,443.666666666667,0.00278867884197938,0 +"3085","2015-02-06 21:15:00",20.2,19.05,0,442,0.0027813459918572,0 +"3086","2015-02-06 21:16:00",20.15,19,0,443,0.00276540838069467,0 +"3087","2015-02-06 21:16:59",20.1333333333333,19.0666666666667,0,444.333333333333,0.00277228163934065,0 +"3088","2015-02-06 21:17:59",20.15,19.05,0,442,0.0027727182119308,0 +"3089","2015-02-06 21:19:00",20.1666666666667,19.1,0,446.333333333333,0.0027829091286467,0 +"3090","2015-02-06 21:20:00",20.2,19,0,447.5,0.0027740133138574,0 +"3091","2015-02-06 21:21:00",20.2,19,0,448.5,0.0027740133138574,0 +"3092","2015-02-06 21:22:00",20.1,19.1,0,450,0.0027714012152491,0 +"3093","2015-02-06 21:23:00",20.2,19.1,0,453,0.00278867884197938,0 +"3094","2015-02-06 21:23:59",20.2,19,0,453,0.0027740133138574,0 +"3095","2015-02-06 21:24:59",20.2,19.0333333333333,0,450.333333333333,0.00277890174673286,0 +"3096","2015-02-06 21:26:00",20.15,18.945,0,440.5,0.00275736776389493,0 +"3097","2015-02-06 21:27:00",20.2,19.05,0,444.5,0.0027813459918572,0 +"3098","2015-02-06 21:28:00",20.2,18.89,0,450,0.0027578820280988,0 +"3099","2015-02-06 21:29:00",20.2,19,0,447,0.0027740133138574,0 +"3100","2015-02-06 21:29:59",20.2,19,0,446,0.0027740133138574,0 +"3101","2015-02-06 21:30:59",20.2,19,0,441.5,0.0027740133138574,0 +"3102","2015-02-06 21:32:00",20.2,18.9266666666667,0,441.333333333333,0.00276325903079532,0 +"3103","2015-02-06 21:33:00",20.2,18.89,0,443,0.0027578820280988,0 +"3104","2015-02-06 21:34:00",20.2,19,0,438.5,0.0027740133138574,0 +"3105","2015-02-06 21:35:00",20.2,18.945,0,440.5,0.00276594756685176,0 +"3106","2015-02-06 21:36:00",20.2,18.89,0,442.666666666667,0.0027578820280988,0 +"3107","2015-02-06 21:36:59",20.2,18.89,0,444,0.0027578820280988,0 +"3108","2015-02-06 21:38:00",20.15,18.945,0,444.5,0.00275736776389493,0 +"3109","2015-02-06 21:39:00",20.1666666666667,18.9266666666667,0,444.5,0.00275754214259837,0 +"3110","2015-02-06 21:40:00",20.2,18.9266666666667,0,444,0.00276325903079532,0 +"3111","2015-02-06 21:40:59",20.2,18.89,0,446,0.0027578820280988,0 +"3112","2015-02-06 21:42:00",20.2,18.89,0,446,0.0027578820280988,0 +"3113","2015-02-06 21:42:59",20.2,18.89,0,443.5,0.0027578820280988,0 +"3114","2015-02-06 21:43:59",20.2,18.89,0,440.5,0.0027578820280988,0 +"3115","2015-02-06 21:45:00",20.2,18.9633333333333,0,445.666666666667,0.00276863612604739,0 +"3116","2015-02-06 21:46:00",20.2,19,0,445,0.0027740133138574,0 +"3117","2015-02-06 21:47:00",20.2,19,0,445.5,0.0027740133138574,0 +"3118","2015-02-06 21:48:00",20.2,18.89,0,445,0.0027578820280988,0 +"3119","2015-02-06 21:49:00",20.1,18.89,0,443.5,0.00274079604409978,0 +"3120","2015-02-06 21:49:59",20.2,18.89,0,439.5,0.0027578820280988,0 +"3121","2015-02-06 21:51:00",20.2,18.89,0,443.5,0.0027578820280988,0 +"3122","2015-02-06 21:52:00",20.2,18.89,0,441,0.0027578820280988,0 +"3123","2015-02-06 21:53:00",20.15,18.89,0,442,0.00274932735405506,0 +"3124","2015-02-06 21:53:59",20.15,18.89,0,444,0.00274932735405506,0 +"3125","2015-02-06 21:55:00",20.1333333333333,18.89,0,441.666666666667,0.00274648099076732,0 +"3126","2015-02-06 21:55:59",20.05,18.89,0,436,0.00273228804345741,0 +"3127","2015-02-06 21:56:59",20.05,18.89,0,444,0.00273228804345741,0 +"3128","2015-02-06 21:58:00",20,18.89,0,443,0.00272380329745947,0 +"3129","2015-02-06 21:59:00",20.1,18.89,0,444,0.00274079604409978,0 +"3130","2015-02-06 22:00:00",20.1,18.89,0,444,0.00274079604409978,0 +"3131","2015-02-06 22:01:00",20.1,18.79,0,447,0.00272622320693274,0 +"3132","2015-02-06 22:01:59",20.05,18.89,0,444,0.00273228804345741,0 +"3133","2015-02-06 22:02:59",20.05,18.89,0,443.5,0.00273228804345741,0 +"3134","2015-02-06 22:04:00",20.05,18.89,0,438.5,0.00273228804345741,0 +"3135","2015-02-06 22:05:00",20,18.89,0,440,0.00272380329745947,0 +"3136","2015-02-06 22:06:00",20,18.89,0,441,0.00272380329745947,0 +"3137","2015-02-06 22:07:00",20,18.89,0,440.666666666667,0.00272380329745947,0 +"3138","2015-02-06 22:08:00",20.1,19,0,441,0.00275682695025823,0 +"3139","2015-02-06 22:08:59",20,18.89,0,443,0.00272380329745947,0 +"3140","2015-02-06 22:09:59",20,18.79,0,442,0.00270932120270335,0 +"3141","2015-02-06 22:11:00",20.1,18.89,0,439,0.00274079604409978,0 +"3142","2015-02-06 22:12:00",19.945,18.84,0,436.5,0.00270728058756142,0 +"3143","2015-02-06 22:13:00",20,18.89,0,443,0.00272380329745947,0 +"3144","2015-02-06 22:14:00",20,18.89,0,439.666666666667,0.00272380329745947,0 +"3145","2015-02-06 22:14:59",20,18.89,0,437,0.00272380329745947,0 +"3146","2015-02-06 22:15:59",20,18.89,0,436,0.00272380329745947,0 +"3147","2015-02-06 22:17:00",20,18.89,0,434,0.00272380329745947,0 +"3148","2015-02-06 22:18:00",20.0666666666667,18.89,0,439.666666666667,0.00273512145712466,0 +"3149","2015-02-06 22:19:00",20.05,18.79,0,442,0.00271776064019761,0 +"3150","2015-02-06 22:20:00",20.1,18.89,0,439.5,0.00274079604409978,0 +"3151","2015-02-06 22:21:00",20.1,18.89,0,446,0.00274079604409978,0 +"3152","2015-02-06 22:21:59",20.05,18.84,0,444.5,0.00272502425737218,0 +"3153","2015-02-06 22:23:00",20.1,18.89,0,439,0.00274079604409978,0 +"3154","2015-02-06 22:24:00",20.1,18.89,0,439.5,0.00274079604409978,0 +"3155","2015-02-06 22:25:00",20.05,18.84,0,436.5,0.00272502425737218,0 +"3156","2015-02-06 22:25:59",20,18.79,0,436,0.00270932120270335,0 +"3157","2015-02-06 22:27:00",20,18.84,0,436,0.00271656216615092,0 +"3158","2015-02-06 22:27:59",20,18.89,0,437,0.00272380329745947,0 +"3159","2015-02-06 22:28:59",20,18.84,0,442,0.00271656216615092,0 +"3160","2015-02-06 22:30:00",20,18.89,0,441,0.00272380329745947,0 +"3161","2015-02-06 22:31:00",20,18.89,0,439,0.00272380329745947,0 +"3162","2015-02-06 22:32:00",20,18.89,0,444,0.00272380329745947,0 +"3163","2015-02-06 22:33:00",20,18.89,0,442.666666666667,0.00272380329745947,0 +"3164","2015-02-06 22:34:00",20.1,18.89,0,437,0.00274079604409978,0 +"3165","2015-02-06 22:34:59",20,18.89,0,438,0.00272380329745947,0 +"3166","2015-02-06 22:36:00",20.05,18.84,0,442.5,0.00272502425737218,0 +"3167","2015-02-06 22:37:00",20.05,18.84,0,438.5,0.00272502425737218,0 +"3168","2015-02-06 22:38:00",20.05,18.89,0,441.5,0.00273228804345741,0 +"3169","2015-02-06 22:38:59",20,18.89,0,437,0.00272380329745947,0 +"3170","2015-02-06 22:40:00",20,18.745,0,437,0.00270280447911685,0 +"3171","2015-02-06 22:40:59",20,18.84,0,442,0.00271656216615092,0 +"3172","2015-02-06 22:41:59",20,18.89,0,440.5,0.00272380329745947,0 +"3173","2015-02-06 22:43:00",20,18.84,0,441,0.00271656216615092,0 +"3174","2015-02-06 22:44:00",20,18.84,0,444,0.00271656216615092,0 +"3175","2015-02-06 22:45:00",20,18.89,0,442.5,0.00272380329745947,0 +"3176","2015-02-06 22:46:00",20,18.84,0,440.5,0.00271656216615092,0 +"3177","2015-02-06 22:46:59",20,18.84,0,439.5,0.00271656216615092,0 +"3178","2015-02-06 22:47:59",20,18.79,0,441,0.00270932120270335,0 +"3179","2015-02-06 22:49:00",20,18.84,0,436.5,0.00271656216615092,0 +"3180","2015-02-06 22:50:00",19.945,18.89,0,434.5,0.00271449687085988,0 +"3181","2015-02-06 22:51:00",20,18.8233333333333,0,434.5,0.00271414849301746,0 +"3182","2015-02-06 22:52:00",20,18.84,0,435.666666666667,0.00271656216615092,0 +"3183","2015-02-06 22:53:00",20,18.79,0,440.5,0.00270932120270335,0 +"3184","2015-02-06 22:53:59",20,18.84,0,439,0.00271656216615092,0 +"3185","2015-02-06 22:54:59",20,18.89,0,444.5,0.00272380329745947,0 +"3186","2015-02-06 22:56:00",20,18.84,0,441.5,0.00271656216615092,0 +"3187","2015-02-06 22:57:00",20,18.84,0,434.5,0.00271656216615092,0 +"3188","2015-02-06 22:58:00",20,18.84,0,438,0.00271656216615092,0 +"3189","2015-02-06 22:59:00",20,18.79,0,433,0.00270932120270335,0 +"3190","2015-02-06 22:59:59",20.0333333333333,18.79,0,434,0.00271494492713225,0 +"3191","2015-02-06 23:00:59",20,18.79,0,436.5,0.00270932120270335,0 +"3192","2015-02-06 23:02:00",20,18.745,0,438,0.00270280447911685,0 +"3193","2015-02-06 23:03:00",20,18.79,0,440,0.00270932120270335,0 +"3194","2015-02-06 23:04:00",20,18.745,0,440.5,0.00270280447911685,0 +"3195","2015-02-06 23:05:00",20,18.79,0,440,0.00270932120270335,0 +"3196","2015-02-06 23:06:00",19.945,18.84,0,440,0.00270728058756142,0 +"3197","2015-02-06 23:06:59",20,18.89,0,440.333333333333,0.00272380329745947,0 +"3198","2015-02-06 23:08:00",20,18.79,0,439,0.00270932120270335,0 +"3199","2015-02-06 23:09:00",20,18.79,0,436,0.00270932120270335,0 +"3200","2015-02-06 23:10:00",20,18.79,0,434,0.00270932120270335,0 +"3201","2015-02-06 23:10:59",20,18.79,0,433,0.00270932120270335,0 +"3202","2015-02-06 23:12:00",20,18.7,0,438,0.00269628789148877,0 +"3203","2015-02-06 23:12:59",19.9266666666667,18.79,0,439.666666666667,0.00269698508587903,0 +"3204","2015-02-06 23:13:59",19.89,18.79,0,441,0.00269083558790582,0 +"3205","2015-02-06 23:15:00",19.79,18.79,0,432,0.00267412691390407,0 +"3206","2015-02-06 23:16:00",19.89,18.89,0,435,0.00270521844389013,0 +"3207","2015-02-06 23:17:00",19.89,18.89,0,436,0.00270521844389013,0 +"3208","2015-02-06 23:18:00",19.89,18.84,0,431,0.00269802693311136,0 +"3209","2015-02-06 23:19:00",19.89,18.79,0,434.5,0.00269083558790582,0 +"3210","2015-02-06 23:19:59",19.89,18.89,0,436,0.00270521844389013,0 +"3211","2015-02-06 23:21:00",19.89,18.89,0,437,0.00270521844389013,0 +"3212","2015-02-06 23:22:00",19.89,18.89,0,444,0.00270521844389013,0 +"3213","2015-02-06 23:23:00",19.89,18.89,0,443,0.00270521844389013,0 +"3214","2015-02-06 23:23:59",19.89,18.79,0,439,0.00269083558790582,0 +"3215","2015-02-06 23:25:00",20,18.79,0,433.666666666667,0.00270932120270335,0 +"3216","2015-02-06 23:25:59",20,18.79,0,434.5,0.00270932120270335,0 +"3217","2015-02-06 23:26:59",20,18.79,0,441,0.00270932120270335,0 +"3218","2015-02-06 23:28:00",20,18.79,0,436,0.00270932120270335,0 +"3219","2015-02-06 23:29:00",20,18.79,0,438,0.00270932120270335,0 +"3220","2015-02-06 23:30:00",20,18.79,0,437,0.00270932120270335,0 +"3221","2015-02-06 23:31:00",20,18.79,0,436.5,0.00270932120270335,0 +"3222","2015-02-06 23:31:59",20,18.7,0,437.5,0.00269628789148877,0 +"3223","2015-02-06 23:32:59",20,18.79,0,436,0.00270932120270335,0 +"3224","2015-02-06 23:34:00",20,18.79,0,433,0.00270932120270335,0 +"3225","2015-02-06 23:35:00",20,18.79,0,434,0.00270932120270335,0 +"3226","2015-02-06 23:36:00",20,18.7,0,438,0.00269628789148877,0 +"3227","2015-02-06 23:37:00",19.945,18.79,0,435.5,0.00270006447097638,0 +"3228","2015-02-06 23:38:00",19.945,18.79,0,430,0.00270006447097638,0 +"3229","2015-02-06 23:38:59",20,18.79,0,432,0.00270932120270335,0 +"3230","2015-02-06 23:39:59",20,18.79,0,439.5,0.00270932120270335,0 +"3231","2015-02-06 23:41:00",20,18.76,0,439,0.00270497670520565,0 +"3232","2015-02-06 23:42:00",20,18.7,0,438,0.00269628789148877,0 +"3233","2015-02-06 23:43:00",20,18.7,0,439.5,0.00269628789148877,0 +"3234","2015-02-06 23:44:00",20,18.7675,0,435,0.00270606282391503,0 +"3235","2015-02-06 23:44:59",20,18.7675,0,434.75,0.00270606282391503,0 +"3236","2015-02-06 23:45:59",20,18.745,0,431,0.00270280447911685,0 +"3237","2015-02-06 23:47:00",20.0666666666667,18.79,0,438,0.00272057892317774,0 +"3238","2015-02-06 23:48:00",20.1,18.79,0,439,0.00272622320693274,0 +"3239","2015-02-06 23:49:00",20,18.6,0,441,0.00268180707239182,0 +"3240","2015-02-06 23:50:00",20,18.65,0,442,0.00268904739802089,0 +"3241","2015-02-06 23:51:00",19.945,18.7,0,441,0.00268707588122265,0 +"3242","2015-02-06 23:51:59",19.89,18.745,0,438,0.00268436351878123,0 +"3243","2015-02-06 23:53:00",19.89,18.79,0,438.5,0.00269083558790582,0 +"3244","2015-02-06 23:54:00",19.89,18.79,0,437.666666666667,0.00269083558790582,0 +"3245","2015-02-06 23:55:00",19.89,18.79,0,441.5,0.00269083558790582,0 +"3246","2015-02-06 23:55:59",20,18.745,0,435,0.00270280447911685,0 +"3247","2015-02-06 23:57:00",20,18.7,0,441,0.00269628789148877,0 +"3248","2015-02-06 23:57:59",20,18.7,0,441,0.00269628789148877,0 +"3249","2015-02-06 23:58:59",20,18.7,0,440,0.00269628789148877,0 +"3250","2015-02-07 00:00:00",20,18.7,0,438,0.00269628789148877,0 +"3251","2015-02-07 00:01:00",19.9725,18.745,0,433.666666666667,0.0026981838167703,0 +"3252","2015-02-07 00:02:00",20,18.79,0,434.5,0.00270932120270335,0 +"3253","2015-02-07 00:03:00",20,18.7,0,434,0.00269628789148877,0 +"3254","2015-02-07 00:04:00",20,18.745,0,438.5,0.00270280447911685,0 +"3255","2015-02-07 00:04:59",20,18.745,0,443,0.00270280447911685,0 +"3256","2015-02-07 00:06:00",20,18.745,0,437,0.00270280447911685,0 +"3257","2015-02-07 00:07:00",20,18.79,0,436.5,0.00270932120270335,0 +"3258","2015-02-07 00:08:00",20,18.73,0,436.333333333333,0.00270063226813454,0 +"3259","2015-02-07 00:08:59",20,18.73,0,433.666666666667,0.00270063226813454,0 +"3260","2015-02-07 00:10:00",20,18.79,0,435.5,0.00270932120270335,0 +"3261","2015-02-07 00:10:59",20,18.79,0,438,0.00270932120270335,0 +"3262","2015-02-07 00:11:59",20,18.79,0,438,0.00270932120270335,0 +"3263","2015-02-07 00:13:00",20,18.79,0,441,0.00270932120270335,0 +"3264","2015-02-07 00:14:00",20,18.7,0,434,0.00269628789148877,0 +"3265","2015-02-07 00:15:00",20,18.745,0,435,0.00270280447911685,0 +"3266","2015-02-07 00:16:00",20,18.79,0,435,0.00270932120270335,0 +"3267","2015-02-07 00:16:59",20,18.79,0,435,0.00270932120270335,0 +"3268","2015-02-07 00:17:59",20,18.7,0,436,0.00269628789148877,0 +"3269","2015-02-07 00:19:00",20,18.7,0,443.5,0.00269628789148877,0 +"3270","2015-02-07 00:20:00",20,18.7,0,451,0.00269628789148877,0 +"3271","2015-02-07 00:21:00",20,18.7,0,448,0.00269628789148877,0 +"3272","2015-02-07 00:22:00",20,18.7,0,443.5,0.00269628789148877,0 +"3273","2015-02-07 00:23:00",20,18.65,0,442,0.00268904739802089,0 +"3274","2015-02-07 00:23:59",20,18.7,0,442,0.00269628789148877,0 +"3275","2015-02-07 00:24:59",20,18.7,0,437.666666666667,0.00269628789148877,0 +"3276","2015-02-07 00:26:00",20,18.745,0,442,0.00270280447911685,0 +"3277","2015-02-07 00:27:00",20,18.79,0,444,0.00270932120270335,0 +"3278","2015-02-07 00:28:00",20,18.7,0,443.333333333333,0.00269628789148877,0 +"3279","2015-02-07 00:29:00",20,18.65,0,440,0.00268904739802089,0 +"3280","2015-02-07 00:29:59",20,18.6,0,438,0.00268180707239182,0 +"3281","2015-02-07 00:30:59",20,18.7,0,439,0.00269628789148877,0 +"3282","2015-02-07 00:32:00",20,18.7,0,440,0.00269628789148877,0 +"3283","2015-02-07 00:33:00",20,18.7,0,439,0.00269628789148877,0 +"3284","2015-02-07 00:34:00",20,18.7,0,439,0.00269628789148877,0 +"3285","2015-02-07 00:35:00",20.05,18.7,0,436,0.00270468655491948,0 +"3286","2015-02-07 00:36:00",20,18.65,0,432,0.00268904739802089,0 +"3287","2015-02-07 00:36:59",20,18.6,0,438,0.00268180707239182,0 +"3288","2015-02-07 00:38:00",20,18.7,0,437.5,0.00269628789148877,0 +"3289","2015-02-07 00:39:00",20.05,18.7,0,433.5,0.00270468655491948,0 +"3290","2015-02-07 00:40:00",20,18.7,0,434.25,0.00269628789148877,0 +"3291","2015-02-07 00:40:59",20,18.7,0,435,0.00269628789148877,0 +"3292","2015-02-07 00:42:00",20,18.7,0,439,0.00269628789148877,0 +"3293","2015-02-07 00:42:59",20,18.7,0,434,0.00269628789148877,0 +"3294","2015-02-07 00:43:59",20,18.7,0,436,0.00269628789148877,0 +"3295","2015-02-07 00:45:00",20,18.7,0,434,0.00269628789148877,0 +"3296","2015-02-07 00:46:00",20,18.7,0,437,0.00269628789148877,0 +"3297","2015-02-07 00:47:00",20,18.7,0,433.666666666667,0.00269628789148877,0 +"3298","2015-02-07 00:48:00",20,18.7,0,433.5,0.00269628789148877,0 +"3299","2015-02-07 00:49:00",20,18.6,0,432,0.00268180707239182,0 +"3300","2015-02-07 00:49:59",20,18.6666666666667,0,433.333333333333,0.00269146087719447,0 +"3301","2015-02-07 00:51:00",20,18.7,0,432,0.00269628789148877,0 +"3302","2015-02-07 00:52:00",20,18.7,0,437,0.00269628789148877,0 +"3303","2015-02-07 00:53:00",20,18.7,0,439.5,0.00269628789148877,0 +"3304","2015-02-07 00:53:59",20,18.7,0,436,0.00269628789148877,0 +"3305","2015-02-07 00:55:00",20,18.7,0,435,0.00269628789148877,0 +"3306","2015-02-07 00:55:59",20.05,18.7,0,433.5,0.00270468655491948,0 +"3307","2015-02-07 00:56:59",20.0333333333333,18.6333333333333,0,438,0.00269221036713816,0 +"3308","2015-02-07 00:58:00",20,18.7,0,436.5,0.00269628789148877,0 +"3309","2015-02-07 00:59:00",20,18.65,0,435,0.00268904739802089,0 +"3310","2015-02-07 01:00:00",20,18.65,0,434.5,0.00268904739802089,0 +"3311","2015-02-07 01:01:00",19.945,18.7,0,435.5,0.00268707588122265,0 +"3312","2015-02-07 01:01:59",19.89,18.7,0,436,0.00267789158376215,0 +"3313","2015-02-07 01:02:59",20,18.65,0,435,0.00268904739802089,0 +"3314","2015-02-07 01:04:00",19.945,18.7,0,434,0.00268707588122265,0 +"3315","2015-02-07 01:05:00",20,18.7,0,436,0.00269628789148877,0 +"3316","2015-02-07 01:06:00",20,18.7,0,433,0.00269628789148877,0 +"3317","2015-02-07 01:07:00",20,18.7,0,434.5,0.00269628789148877,0 +"3318","2015-02-07 01:08:00",20,18.7,0,435,0.00269628789148877,0 +"3319","2015-02-07 01:08:59",20,18.6,0,436,0.00268180707239182,0 +"3320","2015-02-07 01:09:59",19.945,18.7,0,433.5,0.00268707588122265,0 +"3321","2015-02-07 01:11:00",19.945,18.7,0,434,0.00268707588122265,0 +"3322","2015-02-07 01:12:00",19.945,18.7,0,438,0.00268707588122265,0 +"3323","2015-02-07 01:13:00",19.945,18.7,0,436,0.00268707588122265,0 +"3324","2015-02-07 01:14:00",20,18.7,0,439,0.00269628789148877,0 +"3325","2015-02-07 01:14:59",20,18.7,0,437,0.00269628789148877,0 +"3326","2015-02-07 01:15:59",20,18.7,0,441.5,0.00269628789148877,0 +"3327","2015-02-07 01:17:00",20,18.7,0,441,0.00269628789148877,0 +"3328","2015-02-07 01:18:00",19.9266666666667,18.7,0,435.333333333333,0.0026840113730721,0 +"3329","2015-02-07 01:19:00",19.945,18.7,0,437,0.00268707588122265,0 +"3330","2015-02-07 01:20:00",20,18.7,0,435.5,0.00269628789148877,0 +"3331","2015-02-07 01:21:00",20,18.7,0,439,0.00269628789148877,0 +"3332","2015-02-07 01:21:59",19.945,18.7,0,438.5,0.00268707588122265,0 +"3333","2015-02-07 01:23:00",19.945,18.7,0,440,0.00268707588122265,0 +"3334","2015-02-07 01:24:00",19.945,18.7,0,441,0.00268707588122265,0 +"3335","2015-02-07 01:25:00",19.9266666666667,18.7,0,441.666666666667,0.0026840113730721,0 +"3336","2015-02-07 01:25:59",20,18.7,0,440,0.00269628789148877,0 +"3337","2015-02-07 01:27:00",20,18.7,0,439,0.00269628789148877,0 +"3338","2015-02-07 01:27:59",19.9633333333333,18.7,0,440,0.00269014346857257,0 +"3339","2015-02-07 01:28:59",19.945,18.745,0,441.5,0.00269357010858503,0 +"3340","2015-02-07 01:30:00",19.89,18.745,0,433,0.00268436351878123,0 +"3341","2015-02-07 01:31:00",20,18.79,0,435,0.00270932120270335,0 +"3342","2015-02-07 01:32:00",19.945,18.79,0,434.5,0.00270006447097638,0 +"3343","2015-02-07 01:33:00",19.9266666666667,18.79,0,435,0.00269698508587903,0 +"3344","2015-02-07 01:34:00",19.89,18.745,0,435.5,0.00268436351878123,0 +"3345","2015-02-07 01:34:59",19.89,18.79,0,441.333333333333,0.00269083558790582,0 +"3346","2015-02-07 01:36:00",19.89,18.7,0,445,0.00267789158376215,0 +"3347","2015-02-07 01:37:00",19.89,18.79,0,444,0.00269083558790582,0 +"3348","2015-02-07 01:38:00",19.89,18.79,0,439,0.00269083558790582,0 +"3349","2015-02-07 01:38:59",19.89,18.79,0,438.5,0.00269083558790582,0 +"3350","2015-02-07 01:40:00",19.89,18.79,0,443.666666666667,0.00269083558790582,0 +"3351","2015-02-07 01:40:59",19.89,18.76,0,437.666666666667,0.00268652086025527,0 +"3352","2015-02-07 01:41:59",19.89,18.815,0,435,0.00269443123981229,0 +"3353","2015-02-07 01:43:00",19.89,18.79,0,437.5,0.00269083558790582,0 +"3354","2015-02-07 01:44:00",19.89,18.79,0,438.5,0.00269083558790582,0 +"3355","2015-02-07 01:45:00",19.89,18.79,0,439,0.00269083558790582,0 +"3356","2015-02-07 01:46:00",19.89,18.84,0,436.5,0.00269802693311136,0 +"3357","2015-02-07 01:46:59",19.89,18.79,0,439,0.00269083558790582,0 +"3358","2015-02-07 01:47:59",19.89,18.84,0,436,0.00269802693311136,0 +"3359","2015-02-07 01:49:00",19.89,18.89,0,437,0.00270521844389013,0 +"3360","2015-02-07 01:50:00",19.89,18.84,0,437.5,0.00269802693311136,0 +"3361","2015-02-07 01:51:00",19.89,18.84,0,438,0.00269802693311136,0 +"3362","2015-02-07 01:52:00",19.89,18.89,0,435,0.00270521844389013,0 +"3363","2015-02-07 01:53:00",19.89,18.79,0,438,0.00269083558790582,0 +"3364","2015-02-07 01:53:59",19.89,18.8566666666667,0,436.666666666667,0.00270042408497364,0 +"3365","2015-02-07 01:54:59",19.89,18.89,0,436.333333333333,0.00270521844389013,0 +"3366","2015-02-07 01:56:00",19.89,18.89,0,434.333333333333,0.00270521844389013,0 +"3367","2015-02-07 01:57:00",19.89,18.89,0,440,0.00270521844389013,0 +"3368","2015-02-07 01:58:00",19.89,18.89,0,436.333333333333,0.00270521844389013,0 +"3369","2015-02-07 01:59:00",19.89,18.89,0,433,0.00270521844389013,0 +"3370","2015-02-07 01:59:59",19.89,18.89,0,436.5,0.00270521844389013,0 +"3371","2015-02-07 02:00:59",19.89,18.89,0,436.5,0.00270521844389013,0 +"3372","2015-02-07 02:02:00",19.89,18.89,0,437.666666666667,0.00270521844389013,0 +"3373","2015-02-07 02:03:00",19.89,18.8566666666667,0,435,0.00270042408497364,0 +"3374","2015-02-07 02:04:00",19.89,18.89,0,440,0.00270521844389013,0 +"3375","2015-02-07 02:05:00",19.89,18.89,0,438.5,0.00270521844389013,0 +"3376","2015-02-07 02:06:00",19.89,18.89,0,439,0.00270521844389013,0 +"3377","2015-02-07 02:06:59",19.84,18.89,0,439,0.00269680774662527,0 +"3378","2015-02-07 02:08:00",19.79,18.89,0,439,0.00268842007556158,0 +"3379","2015-02-07 02:09:00",19.89,18.89,0,438,0.00270521844389013,0 +"3380","2015-02-07 02:10:00",19.89,18.89,0,444,0.00270521844389013,0 +"3381","2015-02-07 02:10:59",19.84,18.945,0,438,0.00270469389789044,0 +"3382","2015-02-07 02:12:00",19.89,18.89,0,439,0.00270521844389013,0 +"3383","2015-02-07 02:12:59",19.89,18.89,0,437.666666666667,0.00270521844389013,0 +"3384","2015-02-07 02:13:59",19.89,18.89,0,437,0.00270521844389013,0 +"3385","2015-02-07 02:15:00",19.89,18.89,0,433,0.00270521844389013,0 +"3386","2015-02-07 02:16:00",19.89,18.89,0,439,0.00270521844389013,0 +"3387","2015-02-07 02:17:00",19.89,18.945,0,442.5,0.0027131292969907,0 +"3388","2015-02-07 02:18:00",19.89,18.89,0,440.5,0.00270521844389013,0 +"3389","2015-02-07 02:19:00",19.89,18.89,0,439,0.00270521844389013,0 +"3390","2015-02-07 02:19:59",19.89,18.89,0,433,0.00270521844389013,0 +"3391","2015-02-07 02:21:00",19.89,18.9633333333333,0,431.666666666667,0.00271576629254787,0 +"3392","2015-02-07 02:22:00",19.89,19,0,433,0.0027210403504494,0 +"3393","2015-02-07 02:23:00",19.89,19,0,434,0.0027210403504494,0 +"3394","2015-02-07 02:23:59",19.89,18.89,0,437,0.00270521844389013,0 +"3395","2015-02-07 02:25:00",19.89,18.945,0,439.5,0.0027131292969907,0 +"3396","2015-02-07 02:25:59",19.89,19,0,438,0.0027210403504494,0 +"3397","2015-02-07 02:26:59",19.89,18.89,0,439,0.00270521844389013,0 +"3398","2015-02-07 02:28:00",19.89,19,0,440.666666666667,0.0027210403504494,0 +"3399","2015-02-07 02:29:00",19.89,18.945,0,438,0.0027131292969907,0 +"3400","2015-02-07 02:30:00",19.89,18.89,0,438,0.00270521844389013,0 +"3401","2015-02-07 02:31:00",19.89,18.89,0,437,0.00270521844389013,0 +"3402","2015-02-07 02:31:59",19.89,18.945,0,441,0.0027131292969907,0 +"3403","2015-02-07 02:32:59",19.89,18.89,0,437,0.00270521844389013,0 +"3404","2015-02-07 02:34:00",19.89,18.89,0,439,0.00270521844389013,0 +"3405","2015-02-07 02:35:00",19.89,18.89,0,437,0.00270521844389013,0 +"3406","2015-02-07 02:36:00",19.89,18.89,0,437,0.00270521844389013,0 +"3407","2015-02-07 02:37:00",19.89,18.89,0,436,0.00270521844389013,0 +"3408","2015-02-07 02:38:00",19.89,18.945,0,436,0.0027131292969907,0 +"3409","2015-02-07 02:38:59",19.89,18.89,0,431,0.00270521844389013,0 +"3410","2015-02-07 02:39:59",19.89,18.89,0,437,0.00270521844389013,0 +"3411","2015-02-07 02:41:00",19.89,19,0,442.5,0.0027210403504494,0 +"3412","2015-02-07 02:42:00",19.89,18.89,0,443,0.00270521844389013,0 +"3413","2015-02-07 02:43:00",19.89,19,0,443,0.0027210403504494,0 +"3414","2015-02-07 02:44:00",19.89,19,0,441,0.0027210403504494,0 +"3415","2015-02-07 02:44:59",19.89,19,0,440.5,0.0027210403504494,0 +"3416","2015-02-07 02:45:59",19.89,19,0,441.5,0.0027210403504494,0 +"3417","2015-02-07 02:47:00",19.89,19,0,442.5,0.0027210403504494,0 +"3418","2015-02-07 02:48:00",19.89,19.05,0,445,0.00272823239110096,0 +"3419","2015-02-07 02:49:00",19.89,19.05,0,442.5,0.00272823239110096,0 +"3420","2015-02-07 02:50:00",19.79,19,0,443,0.00270414330887012,0 +"3421","2015-02-07 02:51:00",19.89,19.05,0,442.5,0.00272823239110096,0 +"3422","2015-02-07 02:51:59",19.89,19.05,0,441,0.00272823239110096,0 +"3423","2015-02-07 02:53:00",19.89,19.1,0,433,0.00273542459734976,0 +"3424","2015-02-07 02:54:00",19.79,19,0,435,0.00270414330887012,0 +"3425","2015-02-07 02:55:00",19.89,19,0,434,0.0027210403504494,0 +"3426","2015-02-07 02:55:59",19.89,19,0,438.5,0.0027210403504494,0 +"3427","2015-02-07 02:57:00",19.89,19,0,437.333333333333,0.0027210403504494,0 +"3428","2015-02-07 02:57:59",19.89,19,0,435,0.0027210403504494,0 +"3429","2015-02-07 02:58:59",19.84,19,0,437,0.00271258024826712,0 +"3430","2015-02-07 03:00:00",19.79,19,0,437,0.00270414330887012,0 +"3431","2015-02-07 03:01:00",19.79,19,0,434.5,0.00270414330887012,0 +"3432","2015-02-07 03:02:00",19.79,19,0,436,0.00270414330887012,0 +"3433","2015-02-07 03:03:00",19.79,19,0,441.333333333333,0.00270414330887012,0 +"3434","2015-02-07 03:04:00",19.79,19,0,435,0.00270414330887012,0 +"3435","2015-02-07 03:04:59",19.79,19,0,430.5,0.00270414330887012,0 +"3436","2015-02-07 03:06:00",19.89,19.05,0,436.5,0.00272823239110096,0 +"3437","2015-02-07 03:07:00",19.84,19,0,442.5,0.00271258024826712,0 +"3438","2015-02-07 03:08:00",19.8566666666667,19.0666666666667,0,442.333333333333,0.00272496715791814,0 +"3439","2015-02-07 03:08:59",19.79,19,0,443,0.00270414330887012,0 +"3440","2015-02-07 03:10:00",19.79,19,0,441.5,0.00270414330887012,0 +"3441","2015-02-07 03:10:59",19.79,19,0,443,0.00270414330887012,0 +"3442","2015-02-07 03:11:59",19.84,19.1,0,436,0.00272691957727885,0 +"3443","2015-02-07 03:13:00",19.79,19.1,0,435,0.00271843784418595,0 +"3444","2015-02-07 03:14:00",19.84,19.1,0,437,0.00272691957727885,0 +"3445","2015-02-07 03:15:00",19.79,19.05,0,441,0.00271129049475677,0 +"3446","2015-02-07 03:16:00",19.79,19.1,0,442,0.00271843784418595,0 +"3447","2015-02-07 03:16:59",19.79,19.1,0,438.5,0.00271843784418595,0 +"3448","2015-02-07 03:17:59",19.79,19.1,0,436.5,0.00271843784418595,0 +"3449","2015-02-07 03:19:00",19.79,19.1,0,440,0.00271843784418595,0 +"3450","2015-02-07 03:20:00",19.89,19.1,0,439,0.00273542459734976,0 +"3451","2015-02-07 03:21:00",19.79,19.1,0,439,0.00271843784418595,0 +"3452","2015-02-07 03:22:00",19.79,19.1,0,436,0.00271843784418595,0 +"3453","2015-02-07 03:23:00",19.79,19.1,0,436,0.00271843784418595,0 +"3454","2015-02-07 03:23:59",19.79,19.1,0,438.25,0.00271843784418595,0 +"3455","2015-02-07 03:24:59",19.79,19.1,0,440.5,0.00271843784418595,0 +"3456","2015-02-07 03:26:00",19.79,19.1666666666667,0,440.25,0.00272796789783406,0 +"3457","2015-02-07 03:27:00",19.79,19.1,0,443,0.00271843784418595,0 +"3458","2015-02-07 03:28:00",19.84,19.2,0,439.5,0.00274125956458075,0 +"3459","2015-02-07 03:29:00",19.79,19.15,0,440,0.00272558535716328,0 +"3460","2015-02-07 03:29:59",19.79,19.15,0,438.5,0.00272558535716328,0 +"3461","2015-02-07 03:30:59",19.79,19.1,0,438,0.00271843784418595,0 +"3462","2015-02-07 03:32:00",19.79,19.2,0,434,0.00273273303369438,0 +"3463","2015-02-07 03:33:00",19.745,19.2,0,438.666666666667,0.00272507912697409,0 +"3464","2015-02-07 03:34:00",19.79,19.2,0,436,0.00273273303369438,0 +"3465","2015-02-07 03:35:00",19.79,19.2,0,440.5,0.00273273303369438,0 +"3466","2015-02-07 03:36:00",19.79,19.2,0,442.333333333333,0.00273273303369438,0 +"3467","2015-02-07 03:36:59",19.79,19.2,0,441.5,0.00273273303369438,0 +"3468","2015-02-07 03:38:00",19.79,19.2,0,440,0.00273273303369438,0 +"3469","2015-02-07 03:39:00",19.79,19.2,0,438,0.00273273303369438,0 +"3470","2015-02-07 03:40:00",19.79,19.2,0,437.333333333333,0.00273273303369438,0 +"3471","2015-02-07 03:40:59",19.79,19.2,0,443,0.00273273303369438,0 +"3472","2015-02-07 03:42:00",19.79,19.2,0,437,0.00273273303369438,0 +"3473","2015-02-07 03:42:59",19.79,19.2,0,435,0.00273273303369438,0 +"3474","2015-02-07 03:43:59",19.79,19.245,0,436,0.00273916608241548,0 +"3475","2015-02-07 03:45:00",19.79,19.2,0,440,0.00273273303369438,0 +"3476","2015-02-07 03:46:00",19.79,19.2,0,441.75,0.00273273303369438,0 +"3477","2015-02-07 03:47:00",19.79,19.245,0,445,0.00273916608241548,0 +"3478","2015-02-07 03:48:00",19.79,19.245,0,440,0.00273916608241548,0 +"3479","2015-02-07 03:49:00",19.79,19.245,0,437.5,0.00273916608241548,0 +"3480","2015-02-07 03:49:59",19.79,19.29,0,440,0.00274559926362376,0 +"3481","2015-02-07 03:51:00",19.79,19.29,0,438.5,0.00274559926362376,0 +"3482","2015-02-07 03:52:00",19.79,19.2,0,438,0.00273273303369438,0 +"3483","2015-02-07 03:53:00",19.79,19.29,0,439.5,0.00274559926362376,0 +"3484","2015-02-07 03:53:59",19.79,19.29,0,440,0.00274559926362376,0 +"3485","2015-02-07 03:55:00",19.79,19.29,0,441,0.00274559926362376,0 +"3486","2015-02-07 03:55:59",19.79,19.29,0,441,0.00274559926362376,0 +"3487","2015-02-07 03:56:59",19.79,19.29,0,437.5,0.00274559926362376,0 +"3488","2015-02-07 03:58:00",19.79,19.29,0,439,0.00274559926362376,0 +"3489","2015-02-07 03:59:00",19.79,19.29,0,438,0.00274559926362376,0 +"3490","2015-02-07 04:00:00",19.79,19.29,0,448,0.00274559926362376,0 +"3491","2015-02-07 04:01:00",19.79,19.29,0,441,0.00274559926362376,0 +"3492","2015-02-07 04:01:59",19.79,19.29,0,443,0.00274559926362376,0 +"3493","2015-02-07 04:02:59",19.79,19.29,0,442,0.00274559926362376,0 +"3494","2015-02-07 04:04:00",19.79,19.29,0,439,0.00274559926362376,0 +"3495","2015-02-07 04:05:00",19.79,19.29,0,439.5,0.00274559926362376,0 +"3496","2015-02-07 04:06:00",19.79,19.29,0,438.5,0.00274559926362376,0 +"3497","2015-02-07 04:07:00",19.79,19.3566666666667,0,438.666666666667,0.00275513014598885,0 +"3498","2015-02-07 04:08:00",19.79,19.29,0,443,0.00274559926362376,0 +"3499","2015-02-07 04:08:59",19.79,19.29,0,436,0.00274559926362376,0 +"3500","2015-02-07 04:09:59",19.79,19.29,0,442,0.00274559926362376,0 +"3501","2015-02-07 04:11:00",19.79,19.29,0,440,0.00274559926362376,0 +"3502","2015-02-07 04:12:00",19.79,19.29,0,439,0.00274559926362376,0 +"3503","2015-02-07 04:13:00",19.79,19.29,0,442.333333333333,0.00274559926362376,0 +"3504","2015-02-07 04:14:00",19.79,19.39,0,441.5,0.00275989569622187,0 +"3505","2015-02-07 04:14:59",19.79,19.29,0,446.5,0.00274559926362376,0 +"3506","2015-02-07 04:15:59",19.79,19.29,0,450,0.00274559926362376,0 +"3507","2015-02-07 04:17:00",19.84,19.29,0,444,0.00275416611602803,0 +"3508","2015-02-07 04:18:00",19.79,19.29,0,442,0.00274559926362376,0 +"3509","2015-02-07 04:19:00",19.79,19.29,0,440,0.00274559926362376,0 +"3510","2015-02-07 04:20:00",19.79,19.29,0,441,0.00274559926362376,0 +"3511","2015-02-07 04:21:00",19.79,19.29,0,442,0.00274559926362376,0 +"3512","2015-02-07 04:21:59",19.79,19.29,0,441,0.00274559926362376,0 +"3513","2015-02-07 04:23:00",19.79,19.29,0,441,0.00274559926362376,0 +"3514","2015-02-07 04:24:00",19.79,19.3233333333333,0,441.333333333333,0.0027503646684567,0 +"3515","2015-02-07 04:25:00",19.79,19.39,0,439,0.00275989569622187,0 +"3516","2015-02-07 04:25:59",19.79,19.34,0,439.5,0.00275274739813527,0 +"3517","2015-02-07 04:27:00",19.79,19.39,0,442,0.00275989569622187,0 +"3518","2015-02-07 04:27:59",19.79,19.29,0,443,0.00274559926362376,0 +"3519","2015-02-07 04:28:59",19.79,19.29,0,439.5,0.00274559926362376,0 +"3520","2015-02-07 04:30:00",19.79,19.29,0,441,0.00274559926362376,0 +"3521","2015-02-07 04:31:00",19.79,19.29,0,441,0.00274559926362376,0 +"3522","2015-02-07 04:32:00",19.79,19.29,0,443.333333333333,0.00274559926362376,0 +"3523","2015-02-07 04:33:00",19.79,19.29,0,443,0.00274559926362376,0 +"3524","2015-02-07 04:34:00",19.79,19.29,0,445.5,0.00274559926362376,0 +"3525","2015-02-07 04:34:59",19.79,19.29,0,446,0.00274559926362376,0 +"3526","2015-02-07 04:36:00",19.79,19.29,0,442,0.00274559926362376,0 +"3527","2015-02-07 04:37:00",19.79,19.29,0,442.5,0.00274559926362376,0 +"3528","2015-02-07 04:38:00",19.79,19.29,0,440,0.00274559926362376,0 +"3529","2015-02-07 04:38:59",19.79,19.29,0,441.5,0.00274559926362376,0 +"3530","2015-02-07 04:40:00",19.79,19.29,0,443,0.00274559926362376,0 +"3531","2015-02-07 04:40:59",19.79,19.29,0,443,0.00274559926362376,0 +"3532","2015-02-07 04:41:59",19.79,19.3566666666667,0,441.666666666667,0.00275513014598885,0 +"3533","2015-02-07 04:43:00",19.79,19.29,0,442,0.00274559926362376,0 +"3534","2015-02-07 04:44:00",19.79,19.3233333333333,0,446.333333333333,0.0027503646684567,0 +"3535","2015-02-07 04:45:00",19.79,19.29,0,440.5,0.00274559926362376,0 +"3536","2015-02-07 04:46:00",19.745,19.34,0,437.5,0.00274503718837492,0 +"3537","2015-02-07 04:46:59",19.79,19.34,0,442.5,0.00275274739813527,0 +"3538","2015-02-07 04:47:59",19.79,19.39,0,442,0.00275989569622187,0 +"3539","2015-02-07 04:49:00",19.7,19.39,0,439,0.00274445412554034,0 +"3540","2015-02-07 04:50:00",19.7,19.39,0,437,0.00274445412554034,0 +"3541","2015-02-07 04:51:00",19.745,19.39,0,439,0.0027521653764906,0 +"3542","2015-02-07 04:52:00",19.79,19.39,0,441,0.00275989569622187,0 +"3543","2015-02-07 04:53:00",19.79,19.39,0,446,0.00275989569622187,0 +"3544","2015-02-07 04:53:59",19.745,19.39,0,443,0.0027521653764906,0 +"3545","2015-02-07 04:54:59",19.745,19.39,0,441,0.0027521653764906,0 +"3546","2015-02-07 04:56:00",19.79,19.39,0,443,0.00275989569622187,0 +"3547","2015-02-07 04:57:00",19.79,19.39,0,439,0.00275989569622187,0 +"3548","2015-02-07 04:58:00",19.7,19.39,0,441.5,0.00274445412554034,0 +"3549","2015-02-07 04:59:00",19.76,19.39,0,440.666666666667,0.00275474002898411,0 +"3550","2015-02-07 04:59:59",19.73,19.39,0,444,0.00274959284274992,0 +"3551","2015-02-07 05:00:59",19.745,19.39,0,442,0.0027521653764906,0 +"3552","2015-02-07 05:02:00",19.7,19.39,0,441,0.00274445412554034,0 +"3553","2015-02-07 05:03:00",19.7225,19.39,0,448.5,0.00274830736994408,0 +"3554","2015-02-07 05:04:00",19.7,19.39,0,445,0.00274445412554034,0 +"3555","2015-02-07 05:05:00",19.745,19.39,0,442,0.0027521653764906,0 +"3556","2015-02-07 05:06:00",19.79,19.39,0,444.5,0.00275989569622187,0 +"3557","2015-02-07 05:06:59",19.73,19.39,0,444.666666666667,0.00274959284274992,0 +"3558","2015-02-07 05:08:00",19.79,19.39,0,445,0.00275989569622187,0 +"3559","2015-02-07 05:09:00",19.79,19.39,0,445,0.00275989569622187,0 +"3560","2015-02-07 05:10:00",19.79,19.34,0,445.5,0.00275274739813527,0 +"3561","2015-02-07 05:10:59",19.79,19.39,0,444,0.00275989569622187,0 +"3562","2015-02-07 05:12:00",19.79,19.29,0,443.5,0.00274559926362376,0 +"3563","2015-02-07 05:12:59",19.79,19.315,0,446,0.00274917331043298,0 +"3564","2015-02-07 05:13:59",19.745,19.34,0,446,0.00274503718837492,0 +"3565","2015-02-07 05:15:00",19.7,19.29,0,447,0.00273023803079935,0 +"3566","2015-02-07 05:16:00",19.745,19.29,0,444.5,0.00273790916291729,0 +"3567","2015-02-07 05:17:00",19.79,19.29,0,437.5,0.00274559926362376,0 +"3568","2015-02-07 05:18:00",19.79,19.29,0,435.5,0.00274559926362376,0 +"3569","2015-02-07 05:19:00",19.745,19.29,0,443,0.00273790916291729,0 +"3570","2015-02-07 05:19:59",19.79,19.29,0,446,0.00274559926362376,0 +"3571","2015-02-07 05:21:00",19.745,19.29,0,440.5,0.00273790916291729,0 +"3572","2015-02-07 05:22:00",19.79,19.29,0,439.5,0.00274559926362376,0 +"3573","2015-02-07 05:23:00",19.7,19.29,0,444.5,0.00273023803079935,0 +"3574","2015-02-07 05:23:59",19.7675,19.29,0,444.25,0.00274175183968322,0 +"3575","2015-02-07 05:25:00",19.79,19.29,0,446,0.00274559926362376,0 +"3576","2015-02-07 05:25:59",19.79,19.29,0,442,0.00274559926362376,0 +"3577","2015-02-07 05:26:59",19.745,19.29,0,443,0.00273790916291729,0 +"3578","2015-02-07 05:28:00",19.7,19.34,0,443,0.00273734599729692,0 +"3579","2015-02-07 05:29:00",19.745,19.34,0,443.5,0.00274503718837492,0 +"3580","2015-02-07 05:30:00",19.745,19.29,0,441.5,0.00273790916291729,0 +"3581","2015-02-07 05:31:00",19.79,19.29,0,439,0.00274559926362376,0 +"3582","2015-02-07 05:31:59",19.79,19.29,0,437,0.00274559926362376,0 +"3583","2015-02-07 05:32:59",19.79,19.29,0,442.666666666667,0.00274559926362376,0 +"3584","2015-02-07 05:34:00",19.79,19.29,0,442,0.00274559926362376,0 +"3585","2015-02-07 05:35:00",19.79,19.29,0,438.5,0.00274559926362376,0 +"3586","2015-02-07 05:36:00",19.79,19.29,0,437,0.00274559926362376,0 +"3587","2015-02-07 05:37:00",19.79,19.29,0,440,0.00274559926362376,0 +"3588","2015-02-07 05:38:00",19.79,19.26,0,444.5,0.00274131046143057,0 +"3589","2015-02-07 05:38:59",19.79,19.29,0,438.666666666667,0.00274559926362376,0 +"3590","2015-02-07 05:39:59",19.79,19.2,0,438,0.00273273303369438,0 +"3591","2015-02-07 05:41:00",19.79,19.2,0,437,0.00273273303369438,0 +"3592","2015-02-07 05:42:00",19.79,19.2,0,444,0.00273273303369438,0 +"3593","2015-02-07 05:43:00",19.79,19.2,0,444,0.00273273303369438,0 +"3594","2015-02-07 05:44:00",19.79,19.2,0,443,0.00273273303369438,0 +"3595","2015-02-07 05:44:59",19.79,19.245,0,444,0.00273916608241548,0 +"3596","2015-02-07 05:45:59",19.76,19.26,0,442.333333333333,0.00273618966468993,0 +"3597","2015-02-07 05:47:00",19.79,19.29,0,442,0.00274559926362376,0 +"3598","2015-02-07 05:48:00",19.76,19.29,0,444.666666666667,0.00274047042021246,0 +"3599","2015-02-07 05:49:00",19.79,19.29,0,443,0.00274559926362376,0 +"3600","2015-02-07 05:50:00",19.745,19.29,0,443.5,0.00273790916291729,0 +"3601","2015-02-07 05:51:00",19.79,19.29,0,444,0.00274559926362376,0 +"3602","2015-02-07 05:51:59",19.745,19.29,0,441,0.00273790916291729,0 +"3603","2015-02-07 05:53:00",19.73,19.3233333333333,0,441.75,0.00274009755092147,0 +"3604","2015-02-07 05:54:00",19.745,19.34,0,445.5,0.00274503718837492,0 +"3605","2015-02-07 05:55:00",19.7,19.34,0,442,0.00273734599729692,0 +"3606","2015-02-07 05:55:59",19.7,19.39,0,441,0.00274445412554034,0 +"3607","2015-02-07 05:57:00",19.7,19.39,0,448,0.00274445412554034,0 +"3608","2015-02-07 05:57:59",19.7,19.39,0,443,0.00274445412554034,0 +"3609","2015-02-07 05:58:59",19.7,19.39,0,442,0.00274445412554034,0 +"3610","2015-02-07 06:00:00",19.745,19.39,0,443,0.0027521653764906,0 +"3611","2015-02-07 06:01:00",19.7,19.39,0,446,0.00274445412554034,0 +"3612","2015-02-07 06:02:00",19.7,19.39,0,439,0.00274445412554034,0 +"3613","2015-02-07 06:03:00",19.7,19.39,0,444,0.00274445412554034,0 +"3614","2015-02-07 06:04:00",19.7,19.39,0,445,0.00274445412554034,0 +"3615","2015-02-07 06:04:59",19.7,19.39,0,440,0.00274445412554034,0 +"3616","2015-02-07 06:06:00",19.7,19.39,0,442.333333333333,0.00274445412554034,0 +"3617","2015-02-07 06:07:00",19.7,19.39,0,444,0.00274445412554034,0 +"3618","2015-02-07 06:08:00",19.7,19.39,0,441.5,0.00274445412554034,0 +"3619","2015-02-07 06:08:59",19.7,19.39,0,444,0.00274445412554034,0 +"3620","2015-02-07 06:10:00",19.7,19.39,0,439.5,0.00274445412554034,0 +"3621","2015-02-07 06:10:59",19.7,19.39,0,441,0.00274445412554034,0 +"3622","2015-02-07 06:11:59",19.7,19.39,0,442,0.00274445412554034,0 +"3623","2015-02-07 06:13:00",19.745,19.39,0,447,0.0027521653764906,0 +"3624","2015-02-07 06:14:00",19.7225,19.39,0,450.5,0.00274830736994408,0 +"3625","2015-02-07 06:15:00",19.7,19.39,0,452,0.00274445412554034,0 +"3626","2015-02-07 06:16:00",19.7,19.39,0,450,0.00274445412554034,0 +"3627","2015-02-07 06:16:59",19.7,19.39,0,447,0.00274445412554034,0 +"3628","2015-02-07 06:17:59",19.79,19.39,0,442,0.00275989569622187,0 +"3629","2015-02-07 06:19:00",19.7,19.39,0,442,0.00274445412554034,0 +"3630","2015-02-07 06:20:00",19.7,19.39,0,449.666666666667,0.00274445412554034,0 +"3631","2015-02-07 06:21:00",19.7,19.39,0,445,0.00274445412554034,0 +"3632","2015-02-07 06:22:00",19.7,19.39,0,445,0.00274445412554034,0 +"3633","2015-02-07 06:23:00",19.7,19.39,0,446,0.00274445412554034,0 +"3634","2015-02-07 06:23:59",19.7,19.39,0,447,0.00274445412554034,0 +"3635","2015-02-07 06:24:59",19.7,19.39,0,444,0.00274445412554034,0 +"3636","2015-02-07 06:26:00",19.7,19.39,0,443,0.00274445412554034,0 +"3637","2015-02-07 06:27:00",19.7,19.39,0,442,0.00274445412554034,0 +"3638","2015-02-07 06:28:00",19.7,19.39,0,442.5,0.00274445412554034,0 +"3639","2015-02-07 06:29:00",19.7,19.39,0,441,0.00274445412554034,0 +"3640","2015-02-07 06:29:59",19.7,19.39,0,444,0.00274445412554034,0 +"3641","2015-02-07 06:30:59",19.7,19.39,0,447,0.00274445412554034,0 +"3642","2015-02-07 06:32:00",19.7,19.3566666666667,0,445,0.00273971535540603,0 +"3643","2015-02-07 06:33:00",19.7,19.39,0,445,0.00274445412554034,0 +"3644","2015-02-07 06:34:00",19.65,19.34,0,442.5,0.00272882248629992,0 +"3645","2015-02-07 06:35:00",19.7,19.39,0,445,0.00274445412554034,0 +"3646","2015-02-07 06:36:00",19.7,19.29,0,448.5,0.00273023803079935,0 +"3647","2015-02-07 06:36:59",19.7,19.29,0,448,0.00273023803079935,0 +"3648","2015-02-07 06:38:00",19.7,19.29,0,449.5,0.00273023803079935,0 +"3649","2015-02-07 06:39:00",19.7,19.29,0,450,0.00273023803079935,0 +"3650","2015-02-07 06:40:00",19.7,19.245,0,449,0.00272384099923968,0 +"3651","2015-02-07 06:40:59",19.7,19.245,0,442,0.00272384099923968,0 +"3652","2015-02-07 06:42:00",19.7,19.2,0,446,0.00271744409868565,0 +"3653","2015-02-07 06:42:59",19.7,19.2,0,445,0.00271744409868565,0 +"3654","2015-02-07 06:43:59",19.7,19.29,0,444.5,0.00273023803079935,0 +"3655","2015-02-07 06:45:00",19.7,19.2,0,445,0.00271744409868565,0 +"3656","2015-02-07 06:46:00",19.745,19.2675,0,451.75,0.00273470160452707,0 +"3657","2015-02-07 06:47:00",19.76,19.23,0,450.333333333333,0.00273190896783094,0 +"3658","2015-02-07 06:48:00",19.745,19.2,0,451,0.00272507912697409,0 +"3659","2015-02-07 06:49:00",19.79,19.2,0,452,0.00273273303369438,0 +"3660","2015-02-07 06:49:59",19.79,19.2,0,450,0.00273273303369438,0 +"3661","2015-02-07 06:51:00",19.79,19.2,0,444,0.00273273303369438,0 +"3662","2015-02-07 06:52:00",19.7675,19.2,0,446.5,0.00272890371802876,0 +"3663","2015-02-07 06:53:00",19.79,19.2,0,447.666666666667,0.00273273303369438,0 +"3664","2015-02-07 06:53:59",19.79,19.2,0,440.333333333333,0.00273273303369438,0 +"3665","2015-02-07 06:55:00",19.79,19.2,0,448,0.00273273303369438,0 +"3666","2015-02-07 06:55:59",19.73,19.2,0,448.333333333333,0.00272253202191685,0 +"3667","2015-02-07 06:56:59",19.745,19.245,0,445,0.00273149407907346,0 +"3668","2015-02-07 06:58:00",19.7,19.2,0,442,0.00271744409868565,0 +"3669","2015-02-07 06:59:00",19.745,19.245,0,448,0.00273149407907346,0 +"3670","2015-02-07 07:00:00",19.745,19.29,0,449,0.00273790916291729,0 +"3671","2015-02-07 07:01:00",19.7,19.29,0,451,0.00273023803079935,0 +"3672","2015-02-07 07:01:59",19.79,19.29,0,448,0.00274559926362376,0 +"3673","2015-02-07 07:02:59",19.7,19.29,0,447.5,0.00273023803079935,0 +"3674","2015-02-07 07:04:00",19.7,19.29,0,446.5,0.00273023803079935,0 +"3675","2015-02-07 07:05:00",19.7,19.29,0,449,0.00273023803079935,0 +"3676","2015-02-07 07:06:00",19.7,19.29,0,453,0.00273023803079935,0 +"3677","2015-02-07 07:07:00",19.7,19.29,0,448,0.00273023803079935,0 +"3678","2015-02-07 07:08:00",19.7,19.34,0,449.5,0.00273734599729692,0 +"3679","2015-02-07 07:08:59",19.7,19.39,0,449,0.00274445412554034,0 +"3680","2015-02-07 07:09:59",19.7,19.39,0,447,0.00274445412554034,0 +"3681","2015-02-07 07:11:00",19.6666666666667,19.3566666666667,0,449.333333333333,0.00273402547256641,0 +"3682","2015-02-07 07:12:00",19.7,19.39,0,448,0.00274445412554034,0 +"3683","2015-02-07 07:13:00",19.7,19.39,0,446.5,0.00274445412554034,0 +"3684","2015-02-07 07:14:00",19.65,19.34,0,444,0.00272882248629992,0 +"3685","2015-02-07 07:14:59",19.7,19.39,0,443.333333333333,0.00274445412554034,0 +"3686","2015-02-07 07:15:59",19.6666666666667,19.3566666666667,0,450,0.00273402547256641,0 +"3687","2015-02-07 07:17:00",19.6666666666667,19.3566666666667,0,453.333333333333,0.00273402547256641,0 +"3688","2015-02-07 07:18:00",19.7,19.39,0,448,0.00274445412554034,0 +"3689","2015-02-07 07:19:00",19.65,19.34,0,449,0.00272882248629992,0 +"3690","2015-02-07 07:20:00",19.6,19.29,0,450,0.0027132587804371,0 +"3691","2015-02-07 07:21:00",19.7,19.39,0,451,0.00274445412554034,0 +"3692","2015-02-07 07:21:59",19.65,19.34,0,443,0.00272882248629992,0 +"3693","2015-02-07 07:23:00",19.6666666666667,19.3566666666667,0,448.333333333333,0.00273402547256641,0 +"3694","2015-02-07 07:24:00",19.65,19.34,0,453,0.00272882248629992,0 +"3695","2015-02-07 07:25:00",19.6,19.29,0,451,0.0027132587804371,0 +"3696","2015-02-07 07:25:59",19.7,19.39,0,451.5,0.00274445412554034,0 +"3697","2015-02-07 07:27:00",19.7,19.39,0,451,0.00274445412554034,0 +"3698","2015-02-07 07:27:59",19.7,19.39,0,448,0.00274445412554034,0 +"3699","2015-02-07 07:28:59",19.7,19.39,0,450,0.00274445412554034,0 +"3700","2015-02-07 07:30:00",19.65,19.34,0,446,0.00272882248629992,0 +"3701","2015-02-07 07:31:00",19.7,19.39,0,445,0.00274445412554034,0 +"3702","2015-02-07 07:32:00",19.65,19.34,0,446,0.00272882248629992,0 +"3703","2015-02-07 07:33:00",19.7,19.4175,0,448.75,0.0027483636650204,0 +"3704","2015-02-07 07:34:00",19.7,19.445,0,449,0.00275227325343116,0 +"3705","2015-02-07 07:34:59",19.7,19.39,0,454,0.00274445412554034,0 +"3706","2015-02-07 07:36:00",19.7,19.39,0,452.666666666667,0.00274445412554034,0 +"3707","2015-02-07 07:37:00",19.7,19.39,0,450,0.00274445412554034,0 +"3708","2015-02-07 07:38:00",19.65,19.34,0,444.5,0.00272882248629992,0 +"3709","2015-02-07 07:38:59",19.7,19.39,0,448.5,0.00274445412554034,0 +"3710","2015-02-07 07:40:00",19.7,19.39,0,448,0.00274445412554034,0 +"3711","2015-02-07 07:40:59",19.7,19.39,0,447,0.00274445412554034,0 +"3712","2015-02-07 07:41:59",19.7,19.39,0,449.5,0.00274445412554034,0 +"3713","2015-02-07 07:43:00",19.6,19.29,0,450,0.0027132587804371,0 +"3714","2015-02-07 07:44:00",19.7,19.39,0,450,0.00274445412554034,0 +"3715","2015-02-07 07:45:00",19.7,19.39,0,445,0.00274445412554034,0 +"3716","2015-02-07 07:46:00",19.7,19.39,0,447.5,0.00274445412554034,0 +"3717","2015-02-07 07:46:59",19.7,19.39,0,454,0.00274445412554034,0 +"3718","2015-02-07 07:47:59",19.7,19.5,0,450,0.00276009257704848,0 +"3719","2015-02-07 07:49:00",19.7,19.5,0,452,0.00276009257704848,0 +"3720","2015-02-07 07:50:00",19.7,19.5,0,447,0.00276009257704848,0 +"3721","2015-02-07 07:51:00",19.7,19.5,0,456,0.00276009257704848,0 +"3722","2015-02-07 07:52:00",19.65,19.445,0,452,0.00274370305801485,0 +"3723","2015-02-07 07:53:00",19.7,19.5,0,452,0.00276009257704848,0 +"3724","2015-02-07 07:53:59",19.7,19.445,0,450,0.00275227325343116,0 +"3725","2015-02-07 07:54:59",19.65,19.445,0,450.5,0.00274370305801485,0 +"3726","2015-02-07 07:56:00",19.6,19.39,0,450.5,0.00272738607983636,0 +"3727","2015-02-07 07:57:00",19.7,19.5,0,452,0.00276009257704848,0 +"3728","2015-02-07 07:58:00",19.7,19.5,0,455,0.00276009257704848,0 +"3729","2015-02-07 07:59:00",19.7,19.5,0,454,0.00276009257704848,0 +"3730","2015-02-07 07:59:59",19.6,19.4266666666667,0,453,0.00273256624971014,0 +"3731","2015-02-07 08:00:59",19.6,19.39,0,449,0.00272738607983636,0 +"3732","2015-02-07 08:02:00",19.6,19.5,0,451,0.00274292684718233,0 +"3733","2015-02-07 08:03:00",19.6,19.5,0,449,0.00274292684718233,0 +"3734","2015-02-07 08:04:00",19.575,19.5,0,451,0.00273865012986127,0 +"3735","2015-02-07 08:05:00",19.6,19.5,0,455.5,0.00274292684718233,0 +"3736","2015-02-07 08:06:00",19.6,19.5,0,453.5,0.00274292684718233,0 +"3737","2015-02-07 08:06:59",19.6,19.5,0,445.5,0.00274292684718233,0 +"3738","2015-02-07 08:08:00",19.6,19.5,0,448,0.00274292684718233,0 +"3739","2015-02-07 08:09:00",19.6,19.5,14,453.5,0.00274292684718233,0 +"3740","2015-02-07 08:10:00",19.6,19.5,14,450,0.00274292684718233,0 +"3741","2015-02-07 08:10:59",19.6,19.5,14,451,0.00274292684718233,0 +"3742","2015-02-07 08:12:00",19.6,19.5,14,451.333333333333,0.00274292684718233,0 +"3743","2015-02-07 08:12:59",19.6,19.5,14,453.6,0.00274292684718233,0 +"3744","2015-02-07 08:13:59",19.6,19.5,14,456,0.00274292684718233,0 +"3745","2015-02-07 08:15:00",19.6,19.5,9.33333333333333,451,0.00274292684718233,0 +"3746","2015-02-07 08:16:00",19.6,19.5,10.5,446,0.00274292684718233,0 +"3747","2015-02-07 08:17:00",19.6,19.5,7,447,0.00274292684718233,0 +"3748","2015-02-07 08:18:00",19.6,19.5,9.33333333333333,449.333333333333,0.00274292684718233,0 +"3749","2015-02-07 08:19:00",19.6,19.5,7,450.75,0.00274292684718233,0 +"3750","2015-02-07 08:19:59",19.6333333333333,19.5333333333333,9.33333333333333,451.333333333333,0.00275335760901027,0 +"3751","2015-02-07 08:21:00",19.6,19.5,7,450.5,0.00274292684718233,0 +"3752","2015-02-07 08:22:00",19.625,19.5,10,458,0.00274720944362111,0 +"3753","2015-02-07 08:23:00",19.6,19.5,13.5,454.5,0.00274292684718233,0 +"3754","2015-02-07 08:23:59",19.6,19.5,11.5,459.75,0.00274292684718233,0 +"3755","2015-02-07 08:25:00",19.65,19.55,6,457,0.00275858433863477,0 +"3756","2015-02-07 08:25:59",19.7,19.55,6,459,0.00276720122291574,0 +"3757","2015-02-07 08:26:59",19.675,19.5,6,456.25,0.00275579230160686,0 +"3758","2015-02-07 08:28:00",19.675,19.5,6,453,0.00275579230160686,0 +"3759","2015-02-07 08:29:00",19.7,19.5,12,452.666666666667,0.00276009257704848,0 +"3760","2015-02-07 08:30:00",19.675,19.5,24,453.25,0.00275579230160686,0 +"3761","2015-02-07 08:31:00",19.7,19.5,24,454,0.00276009257704848,0 +"3762","2015-02-07 08:31:59",19.7,19.5,24,458,0.00276009257704848,0 +"3763","2015-02-07 08:32:59",19.68,19.478,24,458,0.00275352804773916,0 +"3764","2015-02-07 08:34:00",19.7,19.5,14,454.75,0.00276009257704848,0 +"3765","2015-02-07 08:35:00",19.675,19.4725,14,453.5,0.00275188873352638,0 +"3766","2015-02-07 08:36:00",19.6666666666667,19.4633333333333,17.3333333333333,456.333333333333,0.00274915815797597,0 +"3767","2015-02-07 08:37:00",19.7,19.5,18.5,457.75,0.00276009257704848,0 +"3768","2015-02-07 08:38:00",19.7,19.5,20.3333333333333,461,0.00276009257704848,0 +"3769","2015-02-07 08:38:59",19.7,19.5,26.5,460.25,0.00276009257704848,0 +"3770","2015-02-07 08:39:59",19.7,19.5,26.5,458,0.00276009257704848,0 +"3771","2015-02-07 08:41:00",19.7,19.5,26.5,459,0.00276009257704848,0 +"3772","2015-02-07 08:42:00",19.6333333333333,19.4266666666667,22,457,0.00273825601814212,0 +"3773","2015-02-07 08:43:00",19.7,19.5,13,451.5,0.00276009257704848,0 +"3774","2015-02-07 08:44:00",19.7,19.5,22,451.5,0.00276009257704848,0 +"3775","2015-02-07 08:44:59",19.6666666666667,19.4633333333333,31,455,0.00274915815797597,0 +"3776","2015-02-07 08:45:59",19.675,19.4725,31,458,0.00275188873352638,0 +"3777","2015-02-07 08:47:00",19.7,19.5,31,457.5,0.00276009257704848,0 +"3778","2015-02-07 08:48:00",19.675,19.4725,31,456.5,0.00275188873352638,0 +"3779","2015-02-07 08:49:00",19.6333333333333,19.4266666666667,31,454.333333333333,0.00273825601814212,0 +"3780","2015-02-07 08:50:00",19.675,19.4725,31,455,0.00275188873352638,0 +"3781","2015-02-07 08:51:00",19.6666666666667,19.4633333333333,42.3333333333333,456.333333333333,0.00274915815797597,0 +"3782","2015-02-07 08:51:59",19.65,19.445,48,456,0.00274370305801485,0 +"3783","2015-02-07 08:53:00",19.65,19.4725,48,452.5,0.00274760046775094,0 +"3784","2015-02-07 08:54:00",19.6333333333333,19.5,38.3333333333333,451.333333333333,0.00274863828343676,0 +"3785","2015-02-07 08:55:00",19.625,19.5,33.5,453,0.00274720944362111,0 +"3786","2015-02-07 08:55:59",19.6,19.5,38.3333333333333,453,0.00274292684718233,0 +"3787","2015-02-07 08:57:00",19.6,19.5,33.5,454.5,0.00274292684718233,0 +"3788","2015-02-07 08:57:59",19.6,19.5,40.75,456.75,0.00274292684718233,0 +"3789","2015-02-07 08:58:59",19.6,19.5,41.5,453.5,0.00274292684718233,0 +"3790","2015-02-07 09:00:00",19.575,19.55,38.75,450.25,0.00274570330778812,0 +"3791","2015-02-07 09:01:00",19.575,19.6,55,454.75,0.00275275664497478,0 +"3792","2015-02-07 09:02:00",19.575,19.6,67.75,455,0.00275275664497478,0 +"3793","2015-02-07 09:03:00",19.6,19.6,81.6666666666667,455.333333333333,0.00275705548845916,0 +"3794","2015-02-07 09:04:00",19.6333333333333,19.6,82.6666666666667,457,0.00276279647405805,0 +"3795","2015-02-07 09:04:59",19.65,19.5,89.75,461.5,0.00275149792611465,0 +"3796","2015-02-07 09:06:00",19.7,19.5333333333333,96,458,0.00276483165631926,0 +"3797","2015-02-07 09:07:00",19.7675,19.5,93.5,461,0.00277173284545745,0 +"3798","2015-02-07 09:08:00",19.79,19.39,93.5,458,0.00275989569622187,0 +"3799","2015-02-07 09:08:59",19.79,19.39,91.5,460,0.00275989569622187,0 +"3800","2015-02-07 09:10:00",19.89,19.4175,103,453.25,0.0027810989718201,0 +"3801","2015-02-07 09:10:59",19.89,19.39,107.25,452.5,0.00277714265946394,0 +"3802","2015-02-07 09:11:59",19.9266666666667,19.4266666666667,110,455.333333333333,0.00278877748326468,0 +"3803","2015-02-07 09:13:00",19.945,19.365,112,451,0.00278305987813143,0 +"3804","2015-02-07 09:14:00",20,19.34,116,453,0.0027889810339437,0 +"3805","2015-02-07 09:15:00",20,19.29,119.5,450.75,0.00278173839162363,0 +"3806","2015-02-07 09:16:00",20,19.29,126.333333333333,450.666666666667,0.00278173839162363,0 +"3807","2015-02-07 09:16:59",20,19.2675,133,458.25,0.00277847925736174,0 +"3808","2015-02-07 09:17:59",20.0666666666667,19.26,133,460.666666666667,0.00278893472023407,0 +"3809","2015-02-07 09:19:00",20.1,19.29,130.5,460,0.00279909419214316,0 +"3810","2015-02-07 09:20:00",20.1333333333333,19.23,137.666666666667,457,0.00279613696506725,0 +"3811","2015-02-07 09:21:00",20.15,19.2225,137.75,455,0.00279793844278506,0 +"3812","2015-02-07 09:22:00",20.1333333333333,19.2,143.333333333333,456.333333333333,0.00279175523805738,0 +"3813","2015-02-07 09:23:00",20.2,19.2,141.6,461.75,0.00280334505861515,0 +"3814","2015-02-07 09:23:59",20.2675,19.2,151.75,459.6,0.00281512287962897,0 +"3815","2015-02-07 09:24:59",20.2675,19.175,152,455,0.00281144078687036,0 +"3816","2015-02-07 09:26:00",20.29,19.175,157,454.4,0.00281537122347997,0 +"3817","2015-02-07 09:27:00",20.29,19.15,153,458.5,0.00281168400339412,0 +"3818","2015-02-07 09:28:00",20.365,19.1,165.5,455.75,0.00281739425652493,0 +"3819","2015-02-07 09:29:00",20.39,19.075,168,455,0.00281805755552398,0 +"3820","2015-02-07 09:29:59",20.39,19.0333333333333,173.333333333333,456,0.00281187407552766,0 +"3821","2015-02-07 09:30:59",20.39,19,166.25,455.5,0.00280692737964998,0 +"3822","2015-02-07 09:32:00",20.445,19.05,170.5,453.5,0.00282396460077754,0 +"3823","2015-02-07 09:33:00",20.5,19.025,172.5,460.5,0.00282987509278268,0 +"3824","2015-02-07 09:34:00",20.5,19,175.333333333333,454.666666666667,0.00282613956977883,0 +"3825","2015-02-07 09:35:00",20.525,19,181.5,455,0.00283052208202809,0 +"3826","2015-02-07 09:36:00",20.55,19,188.5,458.25,0.00283491057414835,0 +"3827","2015-02-07 09:36:59",20.6,18.9725,190,457,0.00283957084646561,0 +"3828","2015-02-07 09:38:00",20.6,18.9266666666667,196.666666666667,456.333333333333,0.00283267983548813,0 +"3829","2015-02-07 09:39:00",20.65,18.945,199,457.5,0.00284422941541807,0 +"3830","2015-02-07 09:40:00",20.7,18.9175,215,454.5,0.00284888623171376,0 +"3831","2015-02-07 09:40:59",20.7,18.89,611.5,452.25,0.00284472592086517,0 +"3832","2015-02-07 09:42:00",20.7,18.89,1546.33333333333,455.333333333333,0.00284472592086517,0 +"3833","2015-02-07 09:42:59",20.745,18.89,1451.75,453,0.00285265863292873,0 +"3834","2015-02-07 09:43:59",20.76,18.8566666666667,829,452.666666666667,0.00285024562332216,0 +"3835","2015-02-07 09:45:00",20.79,18.84,251.25,458.75,0.00285300431458645,0 +"3836","2015-02-07 09:46:00",20.79,18.815,205.5,461.666666666667,0.00284920113903208,0 +"3837","2015-02-07 09:47:00",20.79,18.84,220.75,458.4,0.00285300431458645,0 +"3838","2015-02-07 09:48:00",20.8233333333333,18.8566666666667,224.666666666667,454.333333333333,0.00286143234597377,0 +"3839","2015-02-07 09:49:00",20.815,18.815,205,458.5,0.00285360970061655,0 +"3840","2015-02-07 09:49:59",20.84,18.84,219,457.5,0.00286183927031488,0 +"3841","2015-02-07 09:51:00",20.89,18.84,212,460,0.00287069829192633,0 +"3842","2015-02-07 09:52:00",20.89,18.815,230.25,459.25,0.00286687142133289,0 +"3843","2015-02-07 09:53:00",20.89,18.8233333333333,241.333333333333,459.333333333333,0.00286814703965586,0 +"3844","2015-02-07 09:53:59",20.9633333333333,18.79,204.333333333333,460.333333333333,0.00287604656118685,0 +"3845","2015-02-07 09:55:00",20.9725,18.79,183.25,464,0.00287767545405624,0 +"3846","2015-02-07 09:55:59",20.9633333333333,18.79,229,459,0.00287604656118685,0 +"3847","2015-02-07 09:56:59",21,18.7675,206.5,456.75,0.00287909931024598,0 +"3848","2015-02-07 09:58:00",21,18.7675,204,459.75,0.00287909931024598,0 +"3849","2015-02-07 09:59:00",21,18.7675,257.25,459,0.00287909931024598,0 +"3850","2015-02-07 10:00:00",21,18.7,257,456.5,0.00286869645925413,0 +"3851","2015-02-07 10:01:00",21.075,18.7,257,458.25,0.00288200958652276,0 +"3852","2015-02-07 10:01:59",21.125,18.7,253,461.5,0.00289091517637112,0 +"3853","2015-02-07 10:02:59",21.1,18.6666666666667,270.333333333333,463,0.00288129032161803,0 +"3854","2015-02-07 10:04:00",21.1333333333333,18.6,269,460.666666666667,0.00287686286414458,0 +"3855","2015-02-07 10:05:00",21.15,18.6,265.5,461,0.00287982205746459,0 +"3856","2015-02-07 10:06:00",21.2,18.6,270,461.666666666667,0.00288871571176587,0 +"3857","2015-02-07 10:07:00",21.2,18.6,271,463.333333333333,0.00288871571176587,0 +"3858","2015-02-07 10:08:00",21.2675,18.6,258,461.25,0.002900760471659,0 +"3859","2015-02-07 10:08:59",21.29,18.6,267,463,0.00290478519840094,0 +"3860","2015-02-07 10:09:59",21.29,18.5666666666667,270.333333333333,460.333333333333,0.00289955522289558,0 +"3861","2015-02-07 10:11:00",21.29,18.525,258.75,461.5,0.00289301787661824,0 +"3862","2015-02-07 10:12:00",21.315,18.525,269,461.75,0.00289747733312601,0 +"3863","2015-02-07 10:13:00",21.365,18.5,262.5,455.5,0.00290247380240607,0 +"3864","2015-02-07 10:14:00",21.3566666666667,18.5,275.333333333333,457.333333333333,0.00290098464191221,0 +"3865","2015-02-07 10:14:59",21.39,18.5,271.25,459.25,0.00290694531955741,0 +"3866","2015-02-07 10:15:59",21.4175,18.5,288.25,461.5,0.00291187098681264,0 +"3867","2015-02-07 10:17:00",21.39,18.445,291,460.5,0.00289826278028476,0 +"3868","2015-02-07 10:18:00",21.5,18.5,287.25,462,0.00292669207051286,0 +"3869","2015-02-07 10:19:00",21.5,18.5,283.333333333333,464,0.00292669207051286,0 +"3870","2015-02-07 10:20:00",21.5,18.5,290.5,462.5,0.00292669207051286,0 +"3871","2015-02-07 10:21:00",21.5,18.4725,290.25,461.5,0.00292232114255124,0 +"3872","2015-02-07 10:21:59",21.5,18.4266666666667,303,459,0.00291503639848743,0 +"3873","2015-02-07 10:23:00",21.55,18.39,300.5,459.25,0.0029181693580099,0 +"3874","2015-02-07 10:24:00",21.6,18.39,297,462.5,0.00292715425903567,0 +"3875","2015-02-07 10:25:00",21.6,18.39,300.5,458.5,0.00292715425903567,0 +"3876","2015-02-07 10:25:59",21.6,18.39,307.666666666667,457,0.00292715425903567,0 +"3877","2015-02-07 10:27:00",21.7,18.39,306.75,454,0.00294519709219547,0 +"3878","2015-02-07 10:27:59",21.7,18.365,305,454.5,0.00294117435744712,0 +"3879","2015-02-07 10:28:59",21.7,18.29,304,456,0.0029291064639253,0 +"3880","2015-02-07 10:30:00",21.7,18.29,305,460.75,0.0029291064639253,0 +"3881","2015-02-07 10:31:00",21.7,18.29,317.333333333333,454.666666666667,0.0029291064639253,0 +"3882","2015-02-07 10:32:00",21.745,18.245,300.5,459,0.00292995221675734,0 +"3883","2015-02-07 10:33:00",21.745,18.2,324.75,458.25,0.00292269174076307,0 +"3884","2015-02-07 10:34:00",21.79,18.2,314,454.75,0.00293077750158866,0 +"3885","2015-02-07 10:34:59",21.79,18.2,316.75,453.5,0.00293077750158866,0 +"3886","2015-02-07 10:36:00",21.84,18.2225,327.5,463,0.00294343629714788,0 +"3887","2015-02-07 10:37:00",21.8566666666667,18.1666666666667,311.333333333333,462,0.00293737738802671,0 +"3888","2015-02-07 10:38:00",21.89,18.2,328.5,461.25,0.0029488163347437,0 +"3889","2015-02-07 10:38:59",21.89,18.2,327,459.666666666667,0.0029488163347437,0 +"3890","2015-02-07 10:40:00",21.89,18.1,324,457.25,0.00293253765841459,0 +"3891","2015-02-07 10:40:59",21.89,18.1,329.333333333333,460,0.00293253765841459,0 +"3892","2015-02-07 10:41:59",21.89,18.1,330.25,458.5,0.00293253765841459,0 +"3893","2015-02-07 10:43:00",21.945,18.1,321.25,458,0.00294244532120338,0 +"3894","2015-02-07 10:44:00",22,18.1,334.75,460,0.00295238241001692,0 +"3895","2015-02-07 10:45:00",22,18.05,333,452.5,0.00294418805289033,0 +"3896","2015-02-07 10:46:00",22,18.025,334.75,464.5,0.00294009095490964,0 +"3897","2015-02-07 10:46:59",22.0333333333333,18.0333333333333,345,464.333333333333,0.00294747103358407,0 +"3898","2015-02-07 10:47:59",22.0666666666667,18,335.333333333333,459,0.00294801102833698,0 +"3899","2015-02-07 10:49:00",22.1,18,336.5,458.5,0.0029540357910551,0 +"3900","2015-02-07 10:50:00",22.1,17.9725,342,461.25,0.00294950127981488,0 +"3901","2015-02-07 10:51:00",22.1,17.9633333333333,335.333333333333,464.666666666667,0.0029479897906909,0 +"3902","2015-02-07 10:52:00",22.1,17.945,288.75,461,0.00294496683437676,0 +"3903","2015-02-07 10:53:00",22.1,17.89,351.333333333333,459.333333333333,0.00293589814090107,0 +"3904","2015-02-07 10:53:59",22.1,17.945,348,459.25,0.00294496683437676,0 +"3905","2015-02-07 10:54:59",22.1,17.9725,351,457.5,0.00294950127981488,0 +"3906","2015-02-07 10:56:00",22.1,18,351,463,0.0029540357910551,0 +"3907","2015-02-07 10:57:00",22.15,17.945,351,458.5,0.00295399634211629,0 +"3908","2015-02-07 10:58:00",22.2,17.89,355.5,456.75,0.00295392554344823,0 +"3909","2015-02-07 10:59:00",22.2,17.89,333,459.75,0.00295392554344823,0 +"3910","2015-02-07 10:59:59",22.2,17.89,337.5,459.5,0.00295392554344823,0 +"3911","2015-02-07 11:00:59",22.2,17.89,350.25,458.5,0.00295392554344823,0 +"3912","2015-02-07 11:02:00",22.245,17.89,347.5,456.75,0.00296206957996746,0 +"3913","2015-02-07 11:03:00",22.29,17.89,352.333333333333,452,0.00297023335324217,0 +"3914","2015-02-07 11:04:00",22.272,17.83,350.4,452.5,0.00295696747291495,0 +"3915","2015-02-07 11:05:00",22.29,17.815,357.5,455.4,0.00295772207313588,0 +"3916","2015-02-07 11:06:00",22.29,17.84,353,453.5,0.00296189244417909,0 +"3917","2015-02-07 11:06:59",22.34,17.79,344,456.75,0.00296259449816788,0 +"3918","2015-02-07 11:08:00",22.3566666666667,17.79,350,459,0.00296561414969772,0 +"3919","2015-02-07 11:09:00",22.34,17.79,337.75,457.5,0.00296259449816788,0 +"3920","2015-02-07 11:10:00",22.365,17.7675,333.5,453.5,0.00296335442373616,0 +"3921","2015-02-07 11:10:59",22.39,17.7,338,453.666666666667,0.00295655641147791,0 +"3922","2015-02-07 11:12:00",22.365,17.745,353,452,0.00295958390295335,0 +"3923","2015-02-07 11:12:59",22.3566666666667,17.7,342,452.666666666667,0.00295053987346393,0 +"3924","2015-02-07 11:13:59",22.39,17.7,351.5,453.5,0.00295655641147791,0 +"3925","2015-02-07 11:15:00",22.39,17.7,350,455.25,0.00295655641147791,0 +"3926","2015-02-07 11:16:00",22.39,17.7,362,452,0.00295655641147791,0 +"3927","2015-02-07 11:17:00",22.4175,17.7,355.75,452.25,0.00296152817291631,0 +"3928","2015-02-07 11:18:00",22.4175,17.7,342.5,459.5,0.00296152817291631,0 +"3929","2015-02-07 11:19:00",22.445,17.65,353,458,0.00295808746625037,0 +"3930","2015-02-07 11:19:59",22.5,17.7,344,456.5,0.00297648758928842,0 +"3931","2015-02-07 11:21:00",22.5,17.7,357.5,456,0.00297648758928842,0 +"3932","2015-02-07 11:22:00",22.5,17.7,353,453.75,0.00297648758928842,0 +"3933","2015-02-07 11:23:00",22.5,17.7,334,459,0.00297648758928842,0 +"3934","2015-02-07 11:23:59",22.5333333333333,17.6333333333333,331,459,0.00297126324079146,0 +"3935","2015-02-07 11:25:00",22.55,17.6,346,458.75,0.00296863797533426,0 +"3936","2015-02-07 11:25:59",22.525,17.65,341,451.5,0.0029725725982904,0 +"3937","2015-02-07 11:26:59",22.5,17.6,331,451,0.00295959126008617,0 +"3938","2015-02-07 11:28:00",22.55,17.6,354.25,450.5,0.00296863797533426,0 +"3939","2015-02-07 11:29:00",22.575,17.6,349.75,455.5,0.00297317044283677,0 +"3940","2015-02-07 11:30:00",22.6,17.6,364.5,453,0.00297770899290623,0 +"3941","2015-02-07 11:31:00",22.6,17.6,356,455.5,0.00297770899290623,0 +"3942","2015-02-07 11:31:59",22.6,17.55,349.75,456,0.00296920921015559,0 +"3943","2015-02-07 11:32:59",22.6,17.6,357.333333333333,458.666666666667,0.00297770899290623,0 +"3944","2015-02-07 11:34:00",22.6,17.525,354.25,458.5,0.00296495940547835,0 +"3945","2015-02-07 11:35:00",22.6,17.5666666666667,357.333333333333,456,0.00297204244538386,0 +"3946","2015-02-07 11:36:00",22.6,17.5,336.333333333333,455,0.00296070965859824,0 +"3947","2015-02-07 11:37:00",22.6,17.6,359.75,455,0.00297770899290623,0 +"3948","2015-02-07 11:38:00",22.65,17.6,358,458.75,0.00298680436872979,0 +"3949","2015-02-07 11:38:59",22.6666666666667,17.5666666666667,355,455.333333333333,0.00298415183734728,0 +"3950","2015-02-07 11:39:59",22.7,17.6,349,451,0.00299592415883982,0 +"3951","2015-02-07 11:41:00",22.7,17.6,358,455.5,0.00299592415883982,0 +"3952","2015-02-07 11:42:00",22.7,17.6,349,458,0.00299592415883982,0 +"3953","2015-02-07 11:43:00",22.7,17.6,352.666666666667,456.666666666667,0.00299592415883982,0 +"3954","2015-02-07 11:44:00",22.7,17.6,345.5,453.75,0.00299592415883982,0 +"3955","2015-02-07 11:44:59",22.7225,17.6,347.25,454.5,0.0030000360445047,0 +"3956","2015-02-07 11:45:59",22.7225,17.6,360,453.5,0.0030000360445047,0 +"3957","2015-02-07 11:47:00",22.7,17.6,360,453,0.00299592415883982,0 +"3958","2015-02-07 11:48:00",22.79,17.6,343,450.5,0.00301240148431402,0 +"3959","2015-02-07 11:49:00",22.76,17.6,343,452.333333333333,0.00300690021288565,0 +"3960","2015-02-07 11:50:00",22.79,17.6,343,453.5,0.00301240148431402,0 +"3961","2015-02-07 11:51:00",22.76,17.6,344.333333333333,450,0.00300690021288565,0 +"3962","2015-02-07 11:51:59",22.79,17.6,339.5,450.5,0.00301240148431402,0 +"3963","2015-02-07 11:53:00",22.79,17.6,339.5,452,0.00301240148431402,0 +"3964","2015-02-07 11:54:00",22.79,17.6,357.5,455.75,0.00301240148431402,0 +"3965","2015-02-07 11:55:00",22.79,17.6,354,458,0.00301240148431402,0 +"3966","2015-02-07 11:55:59",22.79,17.6,334,457,0.00301240148431402,0 +"3967","2015-02-07 11:57:00",22.815,17.6,334.5,461.75,0.00301699263388512,0 +"3968","2015-02-07 11:57:59",22.815,17.6,336,458,0.00301699263388512,0 +"3969","2015-02-07 11:58:59",22.8566666666667,17.6,334,455.666666666667,0.00302465821996528,0 +"3970","2015-02-07 12:00:00",22.89,17.6,352.25,453,0.00303080301077589,0 +"3971","2015-02-07 12:01:00",22.89,17.6,338.333333333333,451.666666666667,0.00303080301077589,0 +"3972","2015-02-07 12:02:00",22.865,17.6,340.5,452.5,0.00302619339005387,0 +"3973","2015-02-07 12:03:00",22.89,17.6,333,454,0.00303080301077589,0 +"3974","2015-02-07 12:04:00",22.89,17.6,337.2,457,0.00303080301077589,0 +"3975","2015-02-07 12:04:59",22.89,17.6,336,448.666666666667,0.00303080301077589,0 +"3976","2015-02-07 12:06:00",22.89,17.6,334.5,451.25,0.00303080301077589,0 +"3977","2015-02-07 12:07:00",22.9175,17.625,342.75,453,0.00304021412995959,0 +"3978","2015-02-07 12:08:00",22.89,17.65,342.75,455.25,0.00303945532124359,0 +"3979","2015-02-07 12:08:59",22.89,17.625,341,457,0.00303512913606643,0 +"3980","2015-02-07 12:10:00",22.89,17.65,341,457,0.00303945532124359,0 +"3981","2015-02-07 12:10:59",22.89,17.675,318.5,452.5,0.00304378156630861,0 +"3982","2015-02-07 12:11:59",22.89,17.6333333333333,337,453.666666666667,0.00303657119113802,0 +"3983","2015-02-07 12:13:00",22.89,17.6,314.666666666667,457.333333333333,0.00303080301077589,0 +"3984","2015-02-07 12:14:00",22.9175,17.6,298.75,453,0.00303588072156228,0 +"3985","2015-02-07 12:15:00",22.945,17.55,312.25,459,0.00303228468507896,0 +"3986","2015-02-07 12:16:00",22.945,17.6,321.5,458.25,0.00304096590890648,0 +"3987","2015-02-07 12:16:59",22.9266666666667,17.5333333333333,317,452,0.00302601301087672,0 +"3988","2015-02-07 12:17:59",22.9725,17.525,319.75,451.5,0.00303301492373049,0 +"3989","2015-02-07 12:19:00",22.9725,17.55,310.75,445,0.00303736274941155,0 +"3990","2015-02-07 12:20:00",23,17.6,313.5,444.5,0.00305115875100853,0 +"3991","2015-02-07 12:21:00",22.9725,17.5,313.5,445.75,0.00302866715853687,0 +"3992","2015-02-07 12:22:00",23,17.5,310,449,0.00303373806663648,0 +"3993","2015-02-07 12:23:00",23,17.5,310,449.5,0.00303373806663648,0 +"3994","2015-02-07 12:23:59",23,17.4633333333333,310,446,0.00302735072566804,0 +"3995","2015-02-07 12:24:59",23,17.4175,308.75,449.5,0.0030193667330368,0 +"3996","2015-02-07 12:26:00",23,17.39,308.75,455,0.00301457643536401,0 +"3997","2015-02-07 12:27:00",23.0333333333333,17.4266666666667,318.333333333333,457,0.00302709402492384,0 +"3998","2015-02-07 12:28:00",23.0333333333333,17.3566666666667,312.333333333333,455,0.00301487575835715,0 +"3999","2015-02-07 12:29:00",23,17.315,308.5,452,0.00300151236036599,0 +"4000","2015-02-07 12:29:59",23.02,17.352,317.5,456,0.00301161832364564,0 +"4001","2015-02-07 12:30:59",23.0333333333333,17.3566666666667,308.5,454,0.00301487575835715,0 +"4002","2015-02-07 12:32:00",23.025,17.365,306.75,447.25,0.0030148021168416,0 +"4003","2015-02-07 12:33:00",23.04,17.35,321.25,445.5,0.00301493409990867,0 +"4004","2015-02-07 12:34:00",23.0666666666667,17.3566666666667,305,450.25,0.00302099229179882,0 +"4005","2015-02-07 12:35:00",23.05,17.315,315,446.75,0.00301065270272719,0 +"4006","2015-02-07 12:36:00",23.1,17.29,310.5,446.5,0.00301543624514715,0 +"4007","2015-02-07 12:36:59",23.0666666666667,17.26,297,448.666666666667,0.00300408583850099,0 +"4008","2015-02-07 12:38:00",23.0666666666667,17.26,297,451.333333333333,0.00300408583850099,0 +"4009","2015-02-07 12:39:00",23.1,17.29,310.5,453.5,0.00301543624514715,0 +"4010","2015-02-07 12:40:00",23.075,17.2675,310.5,455,0.00300692040942567,0 +"4011","2015-02-07 12:40:59",23.1,17.29,303,454.666666666667,0.00301543624514715,0 +"4012","2015-02-07 12:42:00",23.1,17.29,312.666666666667,448.666666666667,0.00301543624514715,0 +"4013","2015-02-07 12:42:59",23.075,17.2675,291,450.5,0.00300692040942567,0 +"4014","2015-02-07 12:43:59",23.1,17.245,288,447.5,0.00300755014023843,0 +"4015","2015-02-07 12:45:00",23.1,17.2,291,444,0.00299966423433237,0 +"4016","2015-02-07 12:46:00",23.1,17.2,301,444.25,0.00299966423433237,0 +"4017","2015-02-07 12:47:00",23.1,17.2,292,448.5,0.00299966423433237,0 +"4018","2015-02-07 12:48:00",23.1,17.1666666666667,302,446,0.00299382295084641,0 +"4019","2015-02-07 12:49:00",23.1,17.1,293.5,449.75,0.00298214071142625,0 +"4020","2015-02-07 12:49:59",23.1,17.0333333333333,302,453,0.00297045890872133,0 +"4021","2015-02-07 12:51:00",23.1,17.05,285,448.75,0.00297337931845684,0 +"4022","2015-02-07 12:52:00",23.1,17,285,448.5,0.00296461817112944,0 +"4023","2015-02-07 12:53:00",23.1,17,285,448.25,0.00296461817112944,0 +"4024","2015-02-07 12:53:59",23.1,17,283.25,451,0.00296461817112944,0 +"4025","2015-02-07 12:55:00",23.1,17,288.666666666667,449.666666666667,0.00296461817112944,0 +"4026","2015-02-07 12:55:59",23.1,17,278.75,448.5,0.00296461817112944,0 +"4027","2015-02-07 12:56:59",23.1,17,279.75,446,0.00296461817112944,0 +"4028","2015-02-07 12:58:00",23.1,17,283.25,447,0.00296461817112944,0 +"4029","2015-02-07 12:59:00",23.1,17,271,441.666666666667,0.00296461817112944,0 +"4030","2015-02-07 13:00:00",23.1,17.06,268,445.25,0.00297513157739903,0 +"4031","2015-02-07 13:01:00",23.1,17.0333333333333,268.25,447.5,0.00297045890872133,0 +"4032","2015-02-07 13:01:59",23.1,17.0666666666667,266,446.333333333333,0.00297629975548591,0 +"4033","2015-02-07 13:02:59",23.1,17,270.25,453.5,0.00296461817112944,0 +"4034","2015-02-07 13:04:00",23.1,16.9725,268.5,449.25,0.00295979964480052,0 +"4035","2015-02-07 13:05:00",23.1,16.89,272,445.25,0.00294534451161807,0 +"4036","2015-02-07 13:06:00",23.1,16.89,274,445,0.00294534451161807,0 +"4037","2015-02-07 13:07:00",23.1,16.84,265,446,0.00293658415027564,0 +"4038","2015-02-07 13:08:00",23.1,16.89,265,449,0.00294534451161807,0 +"4039","2015-02-07 13:08:59",23.1,16.9633333333333,267.333333333333,448.666666666667,0.00295819348586916,0 +"4040","2015-02-07 13:09:59",23.075,16.9725,243.75,442.75,0.00295530575084192,0 +"4041","2015-02-07 13:11:00",23.0666666666667,17,265,449.333333333333,0.00295861784690694,0 +"4042","2015-02-07 13:12:00",23.075,17,263.5,449.5,0.00296011692650095,0 +"4043","2015-02-07 13:13:00",23.1,17,262,452,0.00296461817112944,0 +"4044","2015-02-07 13:14:00",23.075,17,260.5,449.75,0.00296011692650095,0 +"4045","2015-02-07 13:14:59",23.1,17,252,447.666666666667,0.00296461817112944,0 +"4046","2015-02-07 13:15:59",23.075,16.945,259,443.5,0.00295049464925875,0 +"4047","2015-02-07 13:17:00",23.075,16.865,250,443.25,0.00293649913855628,0 +"4048","2015-02-07 13:18:00",23.1,16.945,241,447,0.00295498119277347,0 +"4049","2015-02-07 13:19:00",23.075,16.865,248.25,452.5,0.00293649913855628,0 +"4050","2015-02-07 13:20:00",23.075,16.865,261,448,0.00293649913855628,0 +"4051","2015-02-07 13:21:00",23.075,16.865,252,448.5,0.00293649913855628,0 +"4052","2015-02-07 13:21:59",23.05,16.865,243,451.75,0.00293203993544146,0 +"4053","2015-02-07 13:23:00",23.025,16.89,239.75,446,0.00293194687764162,0 +"4054","2015-02-07 13:24:00",23,16.89,241.333333333333,444,0.00292749291663824,0 +"4055","2015-02-07 13:25:00",23,16.865,232.5,441.25,0.00292313937769995,0 +"4056","2015-02-07 13:25:59",23.025,16.84,224.75,438.75,0.00292322655138237,0 +"4057","2015-02-07 13:27:00",23,16.79,221.666666666667,440,0.00291007912482309,0 +"4058","2015-02-07 13:27:59",23,16.79,199,441,0.00291007912482309,0 +"4059","2015-02-07 13:28:59",23,16.79,206.25,438,0.00291007912482309,0 +"4060","2015-02-07 13:30:00",23,16.84,186,439.75,0.00291878589941884,0 +"4061","2015-02-07 13:31:00",23,16.8233333333333,189,443,0.00291588361426258,0 +"4062","2015-02-07 13:32:00",23,16.745,189,442.75,0.00290224323512175,0 +"4063","2015-02-07 13:33:00",22.9633333333333,16.79,189,440,0.00290359637829719,0 +"4064","2015-02-07 13:34:00",22.9725,16.79,181.5,444,0.00290521587399794,0 +"4065","2015-02-07 13:34:59",22.9725,16.865,198,445.5,0.00291825419898503,0 +"4066","2015-02-07 13:36:00",22.945,16.84,180,444.5,0.002909037326274,0 +"4067","2015-02-07 13:37:00",22.9175,16.89,193.5,441.5,0.00291283700330503,0 +"4068","2015-02-07 13:38:00",22.9175,16.865,188.5,442.5,0.00290850536093475,0 +"4069","2015-02-07 13:38:59",22.9266666666667,16.89,202,446.333333333333,0.0029144622474755,0 +"4070","2015-02-07 13:40:00",22.89,16.9175,187.5,447.25,0.00291272291955338,0 +"4071","2015-02-07 13:40:59",22.89,16.89,205,445,0.00290796604872893,0 +"4072","2015-02-07 13:41:59",22.89,17,201.5,437,0.00292699396655477,0 +"4073","2015-02-07 13:43:00",22.89,17,193.75,440.25,0.00292699396655477,0 +"4074","2015-02-07 13:44:00",22.89,17,171.75,438.5,0.00292699396655477,0 +"4075","2015-02-07 13:45:00",22.79,17,157,440.25,0.00290922565055317,0 +"4076","2015-02-07 13:46:00",22.8233333333333,17.0666666666667,139.333333333333,446,0.00292662356242996,0 +"4077","2015-02-07 13:46:59",22.79,17.0666666666667,164.666666666667,444.333333333333,0.00292068794987191,0 +"4078","2015-02-07 13:47:59",22.79,17.1,150,443.5,0.00292641925721679,0 +"4079","2015-02-07 13:49:00",22.76,17.1,149.666666666667,441.666666666667,0.00292107574107174,0 +"4080","2015-02-07 13:50:00",22.7225,17.075,154,439.5,0.00291012764085475,0 +"4081","2015-02-07 13:51:00",22.73,17.0333333333333,160.666666666667,441,0.00290432031391607,0 +"4082","2015-02-07 13:52:00",22.7,17.075,143.25,446.5,0.00290613955773023,0 +"4083","2015-02-07 13:53:00",22.7,17.1,151,441.5,0.00291041442997302,0 +"4084","2015-02-07 13:53:59",22.7,17.0333333333333,153.333333333333,441.666666666667,0.00289901490062831,0 +"4085","2015-02-07 13:54:59",22.7,17.025,157,439.5,0.00289758998870293,0 +"4086","2015-02-07 13:56:00",22.7,17.05,144.75,442.5,0.00290186474397394,0 +"4087","2015-02-07 13:57:00",22.7,17.1,115,443.75,0.00291041442997302,0 +"4088","2015-02-07 13:58:00",22.65,17.1,131,445,0.00290155614553475,0 +"4089","2015-02-07 13:59:00",22.6,17.1,140,443.25,0.00289272156796585,0 +"4090","2015-02-07 13:59:59",22.6,17.1,167.666666666667,444,0.00289272156796585,0 +"4091","2015-02-07 14:00:59",22.6,17.125,168.75,436.5,0.00289697039025201,0 +"4092","2015-02-07 14:02:00",22.6,17.1333333333333,176,437,0.00289838667718696,0 +"4093","2015-02-07 14:03:00",22.6,17.175,163,445.75,0.00290546820816037,0 +"4094","2015-02-07 14:04:00",22.6,17.2,170,446,0.00290971720378491,0 +"4095","2015-02-07 14:05:00",22.6,17.175,163.25,443.75,0.00290546820816037,0 +"4096","2015-02-07 14:06:00",22.6,17.1,151,442.25,0.00289272156796585,0 +"4097","2015-02-07 14:06:59",22.6,17.1666666666667,140.666666666667,446,0.00290405188912572,0 +"4098","2015-02-07 14:08:00",22.6,17.15,138.5,446.25,0.00290121927031646,0 +"4099","2015-02-07 14:09:00",22.6,17.175,142.5,443,0.00290546820816037,0 +"4100","2015-02-07 14:10:00",22.6,17.1666666666667,139,439.333333333333,0.00290405188912572,0 +"4101","2015-02-07 14:10:59",22.6,17.2225,158.5,441.5,0.00291354134925042,0 +"4102","2015-02-07 14:12:00",22.55,17.2225,157,440.5,0.00290466671455287,0 +"4103","2015-02-07 14:12:59",22.6,17.2,148,442.5,0.00290971720378491,0 +"4104","2015-02-07 14:13:59",22.55,17.245,139,444,0.00290847920413449,0 +"4105","2015-02-07 14:15:00",22.5,17.245,139,444,0.00289961666908634,0 +"4106","2015-02-07 14:16:00",22.5,17.34,151.75,443.75,0.0029156650794581,0 +"4107","2015-02-07 14:17:00",22.5,17.39,142,445,0.00292411194232605,0 +"4108","2015-02-07 14:18:00",22.5,17.365,126.5,447.5,0.00291988848234862,0 +"4109","2015-02-07 14:19:00",22.5,17.39,120,444.333333333333,0.00292411194232605,0 +"4110","2015-02-07 14:19:59",22.4725,17.365,123,443,0.00291499004828762,0 +"4111","2015-02-07 14:21:00",22.445,17.365,121.5,441.5,0.00291009883974994,0 +"4112","2015-02-07 14:22:00",22.5,17.39,117,437,0.00292411194232605,0 +"4113","2015-02-07 14:23:00",22.4725,17.39,126,440,0.00291920638984859,0 +"4114","2015-02-07 14:23:59",22.39,17.3233333333333,124,439.666666666667,0.00289334643800711,0 +"4115","2015-02-07 14:25:00",22.39,17.315,123,437,0.00289194813183905,0 +"4116","2015-02-07 14:25:59",22.39,17.34,138,436,0.00289614306911706,0 +"4117","2015-02-07 14:26:59",22.39,17.39,116,442.75,0.00290453311264054,0 +"4118","2015-02-07 14:28:00",22.39,17.39,122.75,441.5,0.00290453311264054,0 +"4119","2015-02-07 14:29:00",22.39,17.4175,128.25,442,0.00290914773261095,0 +"4120","2015-02-07 14:30:00",22.365,17.39,126.5,441,0.00290009948519122,0 +"4121","2015-02-07 14:31:00",22.3566666666667,17.5,119,442.333333333333,0.00291704408520697,0 +"4122","2015-02-07 14:31:59",22.39,17.525,110,442.25,0.00292718735554075,0 +"4123","2015-02-07 14:32:59",22.39,17.6,125,442.666666666667,0.00293977375579381,0 +"4124","2015-02-07 14:34:00",22.365,17.6,116,442,0.00293528608255412,0 +"4125","2015-02-07 14:35:00",22.29,17.6,119,438,0.00292185917958549,0 +"4126","2015-02-07 14:36:00",22.29,17.6,116,440.5,0.00292185917958549,0 +"4127","2015-02-07 14:37:00",22.34,17.6,107,445,0.00293080443339284,0 +"4128","2015-02-07 14:38:00",22.29,17.6,107,439.5,0.00292185917958549,0 +"4129","2015-02-07 14:38:59",22.29,17.6,118,440.666666666667,0.00292185917958549,0 +"4130","2015-02-07 14:39:59",22.29,17.675,100,440.5,0.00293436902381121,0 +"4131","2015-02-07 14:41:00",22.29,17.7,100,440,0.0029385390831873,0 +"4132","2015-02-07 14:42:00",22.29,17.7,100,442.75,0.0029385390831873,0 +"4133","2015-02-07 14:43:00",22.29,17.7,100,443,0.0029385390831873,0 +"4134","2015-02-07 14:44:00",22.2225,17.675,99.5,443.5,0.00292227923054319,0 +"4135","2015-02-07 14:44:59",22.2,17.7,87,445.5,0.00292240610175194,0 +"4136","2015-02-07 14:45:59",22.2,17.7,87,444.5,0.00292240610175194,0 +"4137","2015-02-07 14:47:00",22.2,17.7,105,441.25,0.00292240610175194,0 +"4138","2015-02-07 14:48:00",22.2,17.7,105,442,0.00292240610175194,0 +"4139","2015-02-07 14:49:00",22.175,17.745,90.5,440.25,0.00292539194050672,0 +"4140","2015-02-07 14:50:00",22.15,17.745,97.75,441.25,0.00292091895741881,0 +"4141","2015-02-07 14:51:00",22.175,17.79,93.25,441.5,0.00293284549682129,0 +"4142","2015-02-07 14:51:59",22.15,17.79,87,438.5,0.002928361063692,0 +"4143","2015-02-07 14:53:00",22.1,17.79,87,445.333333333333,0.00291941028159241,0 +"4144","2015-02-07 14:54:00",22.1333333333333,17.79,87,443.666666666667,0.00292537479224092,0 +"4145","2015-02-07 14:55:00",22.125,17.815,70,438.75,0.00292801088828591,0 +"4146","2015-02-07 14:55:59",22.1,17.8233333333333,89.3333333333333,441,0.00292490613802693,0 +"4147","2015-02-07 14:57:00",22.1,17.865,91.75,438,0.00293177609450907,0 +"4148","2015-02-07 14:57:59",22.1,17.89,81,437,0.00293589814090107,0 +"4149","2015-02-07 14:58:59",22.1,17.89,81,446.25,0.00293589814090107,0 +"4150","2015-02-07 15:00:00",22.1,17.945,76.5,445.25,0.00294496683437676,0 +"4151","2015-02-07 15:01:00",22.05,17.945,63,443.5,0.00293596160645754,0 +"4152","2015-02-07 15:02:00",22.0666666666667,17.9633333333333,82.3333333333333,441.666666666667,0.00294197741685179,0 +"4153","2015-02-07 15:03:00",22.025,17.9175,77.5,445.5,0.00292695458173188,0 +"4154","2015-02-07 15:04:00",22,17.9725,77.5,446.5,0.00293148722400857,0 +"4155","2015-02-07 15:04:59",22,18,78.5,445.25,0.00293599391064927,0 +"4156","2015-02-07 15:06:00",22,18,74,446,0.00293599391064927,0 +"4157","2015-02-07 15:07:00",21.9633333333333,18,74,443,0.00292940287560619,0 +"4158","2015-02-07 15:08:00",21.9725,18.05,74,440.5,0.00293922969090823,0 +"4159","2015-02-07 15:08:59",21.9725,18.025,69.75,441,0.00293513952533345,0 +"4160","2015-02-07 15:10:00",21.89,18.1,57,439.333333333333,0.00293253765841459,0 +"4161","2015-02-07 15:10:59",21.89,18.1,69.75,437,0.00293253765841459,0 +"4162","2015-02-07 15:11:59",21.89,18.1,68,438,0.00293253765841459,0 +"4163","2015-02-07 15:13:00",21.89,18.1,68,446,0.00293253765841459,0 +"4164","2015-02-07 15:14:00",21.89,18.1,64.4,442,0.00293253765841459,0 +"4165","2015-02-07 15:15:00",21.8566666666667,18.1666666666667,62,442,0.00293737738802671,0 +"4166","2015-02-07 15:16:00",21.865,18.175,68,437.5,0.00294023401366207,0 +"4167","2015-02-07 15:16:59",21.865,18.2,68,441,0.00294429749632691,0 +"4168","2015-02-07 15:17:59",21.8233333333333,18.23,50,441.333333333333,0.00294164337153825,0 +"4169","2015-02-07 15:19:00",21.84,18.245,57.25,440.5,0.00294708788761225,0 +"4170","2015-02-07 15:20:00",21.79,18.2,64.5,442.5,0.00293077750158866,0 +"4171","2015-02-07 15:21:00",21.79,18.2,64.5,436.5,0.00293077750158866,0 +"4172","2015-02-07 15:22:00",21.79,18.29,52,442,0.00294533898497527,0 +"4173","2015-02-07 15:23:00",21.745,18.29,54.5,440,0.00293721286146087,0 +"4174","2015-02-07 15:23:59",21.745,18.315,62,438.5,0.00294124662586406,0 +"4175","2015-02-07 15:24:59",21.745,18.34,62,442,0.00294528044234083,0 +"4176","2015-02-07 15:26:00",21.7,18.39,44,442,0.00294519709219547,0 +"4177","2015-02-07 15:27:00",21.7,18.39,51,441.5,0.00294519709219547,0 +"4178","2015-02-07 15:28:00",21.7,18.39,62.6666666666667,442,0.00294519709219547,0 +"4179","2015-02-07 15:29:00",21.7,18.39,58,441.75,0.00294519709219547,0 +"4180","2015-02-07 15:29:59",21.6666666666667,18.4266666666667,44,440.666666666667,0.00294505995319839,0 +"4181","2015-02-07 15:30:59",21.7,18.4725,44,442.5,0.00295847248431251,0 +"4182","2015-02-07 15:32:00",21.65,18.445,44,443,0.00294498641014222,0 +"4183","2015-02-07 15:33:00",21.6,18.5,51,442.5,0.00294474595872457,0 +"4184","2015-02-07 15:34:00",21.6,18.5,53.75,446.5,0.00294474595872457,0 +"4185","2015-02-07 15:35:00",21.6,18.5,45.3333333333333,442,0.00294474595872457,0 +"4186","2015-02-07 15:36:00",21.6,18.525,47.75,442.5,0.00294874421041685,0 +"4187","2015-02-07 15:36:59",21.6,18.575,55,440.5,0.00295674086728271,0 +"4188","2015-02-07 15:38:00",21.5666666666667,18.6,55,440,0.00295467755695997,0 +"4189","2015-02-07 15:39:00",21.55,18.65,50.5,439.25,0.00295962309490279,0 +"4190","2015-02-07 15:40:00",21.5,18.6,37,442,0.00294258686944843,0 +"4191","2015-02-07 15:40:59",21.5,18.7,37,442,0.00295848247696224,0 +"4192","2015-02-07 15:42:00",21.5,18.7,37,438.75,0.00295848247696224,0 +"4193","2015-02-07 15:42:59",21.5,18.7,37,439,0.00295848247696224,0 +"4194","2015-02-07 15:43:59",21.5,18.7675,37,440.75,0.00296921246916454,0 +"4195","2015-02-07 15:45:00",21.5,18.79,37,440,0.00297278921511004,0 +"4196","2015-02-07 15:46:00",21.5,18.79,37,439.5,0.00297278921511004,0 +"4197","2015-02-07 15:47:00",21.445,18.815,37,440,0.0029667053761862,0 +"4198","2015-02-07 15:48:00",21.39,18.79,37,439,0.00295272997149686,0 +"4199","2015-02-07 15:49:00",21.39,18.815,43.75,439,0.00295667723836028,0 +"4200","2015-02-07 15:49:59",21.39,18.89,33.5,436.75,0.00296851933813242,0 +"4201","2015-02-07 15:51:00",21.39,18.89,38.3333333333333,440.333333333333,0.00296851933813242,0 +"4202","2015-02-07 15:52:00",21.365,18.89,33.5,440.75,0.00296395265745206,0 +"4203","2015-02-07 15:53:00",21.365,18.89,33.5,443.25,0.00296395265745206,0 +"4204","2015-02-07 15:53:59",21.29,18.89,48,444,0.00295028967942359,0 +"4205","2015-02-07 15:55:00",21.29,18.945,33.5,435.75,0.00295892058724676,0 +"4206","2015-02-07 15:55:59",21.29,19,40.75,436.5,0.0029675517334684,0 +"4207","2015-02-07 15:56:59",21.3233333333333,19.0333333333333,48,440.333333333333,0.00297889488999471,0 +"4208","2015-02-07 15:58:00",21.29,19.1,48,439,0.00298324533740384,0 +"4209","2015-02-07 15:59:00",21.29,19.1,48,438,0.00298324533740384,0 +"4210","2015-02-07 16:00:00",21.29,19.1,42.3333333333333,437.666666666667,0.00298324533740384,0 +"4211","2015-02-07 16:01:00",21.272,19.16,39.5,439.75,0.00298934382002562,0 +"4212","2015-02-07 16:01:59",21.26,19.1666666666667,40.75,437.75,0.00298817793786851,0 +"4213","2015-02-07 16:02:59",21.2225,19.2,32.25,439.75,0.00298648750587502,0 +"4214","2015-02-07 16:04:00",21.2,19.2,36.5,437.5,0.002982346887216,0 +"4215","2015-02-07 16:05:00",21.2,19.2,31,435.666666666667,0.002982346887216,0 +"4216","2015-02-07 16:06:00",21.2,19.2675,37,435.75,0.00299288215034748,0 +"4217","2015-02-07 16:07:00",21.2,19.29,19,443,0.00299639398365479,0 +"4218","2015-02-07 16:08:00",21.2,19.29,31,440.25,0.00299639398365479,0 +"4219","2015-02-07 16:08:59",21.15,19.34,31,439.5,0.00299494729809699,0 +"4220","2015-02-07 16:09:59",21.2,19.39,22,433.5,0.00301200260918866,0 +"4221","2015-02-07 16:11:00",21.1,19.39,19.75,433.5,0.0029934776556324,0 +"4222","2015-02-07 16:12:00",21.1,19.445,26.5,439.5,0.00300200967691895,0 +"4223","2015-02-07 16:13:00",21.125,19.5,19,439,0.00301519021799044,0 +"4224","2015-02-07 16:14:00",21.1,19.5,24,435,0.00301054193115634,0 +"4225","2015-02-07 16:14:59",21.1,19.55,24,437,0.00301829872807308,0 +"4226","2015-02-07 16:15:59",21.075,19.575,24,436,0.00301751719237901,0 +"4227","2015-02-07 16:17:00",21.0333333333333,19.5,24,438,0.00299817731685058,0 +"4228","2015-02-07 16:18:00",21.075,19.575,24,441.25,0.00301751719237901,0 +"4229","2015-02-07 16:19:00",21.0333333333333,19.6,24,440.333333333333,0.00301362707923355,0 +"4230","2015-02-07 16:20:00",21,19.6,24,438,0.00300742962468002,0 +"4231","2015-02-07 16:21:00",21,19.675,24,436,0.00301899350254098,0 +"4232","2015-02-07 16:21:59",21,19.66,24,440.25,0.00301668069273616,0 +"4233","2015-02-07 16:23:00",21,19.79,24,444,0.00303672561304647,0 +"4234","2015-02-07 16:24:00",21,19.79,12,444,0.00303672561304647,0 +"4235","2015-02-07 16:25:00",20.945,19.79,6,437.2,0.00302642448004896,0 +"4236","2015-02-07 16:25:59",20.89,19.79,6,439.5,0.00301615411603875,0 +"4237","2015-02-07 16:27:00",20.9175,19.84,6,433.5,0.00302895599304688,0 +"4238","2015-02-07 16:27:59",20.89,19.84,6,439.25,0.00302381156158785,0 +"4239","2015-02-07 16:28:59",20.89,19.865,6,443.75,0.00302764035472478,0 +"4240","2015-02-07 16:30:00",20.8566666666667,19.8233333333333,6,446,0.00301503897674977,0 +"4241","2015-02-07 16:31:00",20.89,19.945,11.5,437,0.00303989280799839,0 +"4242","2015-02-07 16:32:00",20.865,19.945,13.5,435.75,0.00303519777046834,0 +"4243","2015-02-07 16:33:00",20.89,20,10,438,0.00304831664828052,0 +"4244","2015-02-07 16:34:00",20.8566666666667,20,9.33333333333333,441.333333333333,0.00304204058962159,0 +"4245","2015-02-07 16:34:59",20.8566666666667,20,9.33333333333333,444.333333333333,0.00304204058962159,0 +"4246","2015-02-07 16:36:00",20.815,19.9725,7,438.5,0.00303001914873219,0 +"4247","2015-02-07 16:37:00",20.815,20,7,438.75,0.00303421151329867,0 +"4248","2015-02-07 16:38:00",20.79,20,7,441.5,0.0030295225859519,0 +"4249","2015-02-07 16:38:59",20.79,20,10.5,438.75,0.0030295225859519,0 +"4250","2015-02-07 16:40:00",20.79,20,14,437.333333333333,0.0030295225859519,0 +"4251","2015-02-07 16:40:59",20.79,20,14,438.75,0.0030295225859519,0 +"4252","2015-02-07 16:41:59",20.79,20.075,10.5,440,0.00304093883780894,0 +"4253","2015-02-07 16:43:00",20.79,20.15,14,440.5,0.00305235550671248,0 +"4254","2015-02-07 16:44:00",20.79,20.15,14,441,0.00305235550671248,0 +"4255","2015-02-07 16:45:00",20.79,20.2,14,439.333333333333,0.00305996685101862,0 +"4256","2015-02-07 16:46:00",20.7225,20.245,14,436.75,0.00305403274259712,0 +"4257","2015-02-07 16:46:59",20.7225,20.29,14,435.75,0.00306085456388902,0 +"4258","2015-02-07 16:47:59",20.7225,20.245,14,436.75,0.00305403274259712,0 +"4259","2015-02-07 16:49:00",20.7,20.365,14,437.5,0.0030679480970216,0 +"4260","2015-02-07 16:50:00",20.7,20.39,14,440.75,0.00307173289826042,0 +"4261","2015-02-07 16:51:00",20.7,20.39,14,441,0.00307173289826042,0 +"4262","2015-02-07 16:52:00",20.7,20.5,14,433.75,0.00308838656823511,0 +"4263","2015-02-07 16:53:00",20.7,20.5,14,438,0.00308838656823511,0 +"4264","2015-02-07 16:53:59",20.7,20.525,14,442.75,0.00309217161698958,0 +"4265","2015-02-07 16:54:59",20.6666666666667,20.4966666666667,14,441,0.00308151467156501,0 +"4266","2015-02-07 16:56:00",20.7,20.575,14,436.5,0.00309974185201605,0 +"4267","2015-02-07 16:57:00",20.7,20.6,14,435,0.00310352703828971,0 +"4268","2015-02-07 16:58:00",20.7,20.6,4.66666666666667,441,0.00310352703828971,0 +"4269","2015-02-07 16:59:00",20.7,20.6,0,443,0.00310352703828971,0 +"4270","2015-02-07 16:59:59",20.7,20.65,0,439,0.00311109754836204,0 +"4271","2015-02-07 17:00:59",20.6333333333333,20.6333333333333,0,438,0.00309576545382003,0 +"4272","2015-02-07 17:02:00",20.7,20.7,0,436.5,0.00311866824180661,0 +"4273","2015-02-07 17:03:00",20.6,20.6333333333333,0,437.666666666667,0.00308937861195374,0 +"4274","2015-02-07 17:04:00",20.6,20.7,0,438,0.00309941018839007,0 +"4275","2015-02-07 17:05:00",20.7,20.7,0,443,0.00311866824180661,0 +"4276","2015-02-07 17:06:00",20.6,20.7,0,439,0.00309941018839007,0 +"4277","2015-02-07 17:06:59",20.6,20.7,0,439,0.00309941018839007,0 +"4278","2015-02-07 17:08:00",20.6,20.7,0,440,0.00309941018839007,0 +"4279","2015-02-07 17:09:00",20.6,20.745,0,439.5,0.00310618168450477,0 +"4280","2015-02-07 17:10:00",20.6,20.79,0,431.666666666667,0.00311295332732784,0 +"4281","2015-02-07 17:10:59",20.6,20.79,0,434.5,0.00311295332732784,0 +"4282","2015-02-07 17:12:00",20.6,20.89,0,437,0.00312800194776641,0 +"4283","2015-02-07 17:12:59",20.6,20.89,0,441.5,0.00312800194776641,0 +"4284","2015-02-07 17:13:59",20.55,20.89,0,431,0.00311832334195416,0 +"4285","2015-02-07 17:15:00",20.6,20.89,0,437,0.00312800194776641,0 +"4286","2015-02-07 17:16:00",20.6,20.9633333333333,0,433.666666666667,0.0031390380632509,0 +"4287","2015-02-07 17:17:00",20.6,21.0333333333333,0,439.666666666667,0.00314957290062984,0 +"4288","2015-02-07 17:18:00",20.6,21.05,0,439.5,0.00315208124757807,0 +"4289","2015-02-07 17:19:00",20.5,21,0,440,0.00312512262022728,0 +"4290","2015-02-07 17:19:59",20.5,21,0,436,0.00312512262022728,0 +"4291","2015-02-07 17:21:00",20.6,21,0,435,0.00314455626711953,0 +"4292","2015-02-07 17:22:00",20.5,21.15,0,440,0.00314755788405506,0 +"4293","2015-02-07 17:23:00",20.5,21.1,0,438,0.00314007928385138,0 +"4294","2015-02-07 17:23:59",20.5,21.1,0,435,0.00314007928385138,0 +"4295","2015-02-07 17:25:00",20.55,21.1,0,435,0.00314982952071157,0 +"4296","2015-02-07 17:25:59",20.5,21.1,0,434,0.00314007928385138,0 +"4297","2015-02-07 17:26:59",20.5,21.2,0,436,0.00315503666319505,0 +"4298","2015-02-07 17:28:00",20.5,21.245,0,439.5,0.00316176771741689,0 +"4299","2015-02-07 17:29:00",20.5,21.26,0,441.333333333333,0.00316401143436801,0 +"4300","2015-02-07 17:30:00",20.5,21.245,0,442,0.00316176771741689,0 +"4301","2015-02-07 17:31:00",20.5,21.29,0,435.5,0.00316849891658704,0 +"4302","2015-02-07 17:31:59",20.5,21.29,0,436.5,0.00316849891658704,0 +"4303","2015-02-07 17:32:59",20.5,21.29,0,441.666666666667,0.00316849891658704,0 +"4304","2015-02-07 17:34:00",20.5,21.29,0,442,0.00316849891658704,0 +"4305","2015-02-07 17:35:00",20.5,21.39,0,440,0.00318345765593941,0 +"4306","2015-02-07 17:36:00",20.5,21.39,0,437.25,0.00318345765593941,0 +"4307","2015-02-07 17:37:00",20.5,21.39,0,437,0.00318345765593941,0 +"4308","2015-02-07 17:38:00",20.5,21.445,0,435.5,0.00319168526771891,0 +"4309","2015-02-07 17:38:59",20.5,21.39,0,433.5,0.00318345765593941,0 +"4310","2015-02-07 17:39:59",20.5,21.39,0,436,0.00318345765593941,0 +"4311","2015-02-07 17:41:00",20.5,21.39,0,439,0.00318345765593941,0 +"4312","2015-02-07 17:42:00",20.5,21.495,0,438.5,0.00319916510271387,0 +"4313","2015-02-07 17:43:00",20.5,21.55,0,435.5,0.0032073931279312,0 +"4314","2015-02-07 17:44:00",20.4633333333333,21.5666666666667,0,438.666666666667,0.00320259384792963,0 +"4315","2015-02-07 17:44:59",20.4725,21.625,0,442.5,0.00321312769351576,0 +"4316","2015-02-07 17:45:59",20.5,21.6,0,437.5,0.0032148733387929,0 +"4317","2015-02-07 17:47:00",20.5,21.6,0,435,0.0032148733387929,0 +"4318","2015-02-07 17:48:00",20.39,21.6,0,434,0.00319300501924389,0 +"4319","2015-02-07 17:49:00",20.39,21.6,0,438,0.00319300501924389,0 +"4320","2015-02-07 17:50:00",20.39,21.6333333333333,0,431,0.00319795783031077,0 +"4321","2015-02-07 17:51:00",20.39,21.7,0,430,0.00320786368786681,0 +"4322","2015-02-07 17:51:59",20.39,21.76,0,436.666666666667,0.00321677922805883,0 +"4323","2015-02-07 17:53:00",20.39,21.76,0,439.333333333333,0.00321677922805883,0 +"4324","2015-02-07 17:54:00",20.5,21.89,0,437,0.00325826209175758,0 +"4325","2015-02-07 17:55:00",20.39,21.79,0,443.5,0.00322123709350804,0 +"4326","2015-02-07 17:55:59",20.39,21.89,0,435,0.00323609710413411,0 +"4327","2015-02-07 17:57:00",20.39,21.89,0,434,0.00323609710413411,0 +"4328","2015-02-07 17:57:59",20.39,21.89,0,437.666666666667,0.00323609710413411,0 +"4329","2015-02-07 17:58:59",20.39,22,0,441.5,0.00325244393170573,0 +"4330","2015-02-07 18:00:00",20.39,22,0,433,0.00325244393170573,0 +"4331","2015-02-07 18:01:00",20.39,22,0,433.333333333333,0.00325244393170573,0 +"4332","2015-02-07 18:02:00",20.39,22,0,433,0.00325244393170573,0 +"4333","2015-02-07 18:03:00",20.39,22,0,432,0.00325244393170573,0 +"4334","2015-02-07 18:04:00",20.39,22.1,0,439,0.00326730542580999,0 +"4335","2015-02-07 18:04:59",20.39,22.05,0,441,0.00325987459044898,0 +"4336","2015-02-07 18:06:00",20.39,22.1,0,442.5,0.00326730542580999,0 +"4337","2015-02-07 18:07:00",20.39,22.1,0,444.5,0.00326730542580999,0 +"4338","2015-02-07 18:08:00",20.39,22.1,0,440,0.00326730542580999,0 +"4339","2015-02-07 18:08:59",20.39,22.2,0,433,0.0032821676264105,0 +"4340","2015-02-07 18:10:00",20.39,22.2,0,436,0.0032821676264105,0 +"4341","2015-02-07 18:10:59",20.39,22.2,0,441,0.0032821676264105,0 +"4342","2015-02-07 18:11:59",20.39,22.245,0,433,0.00328885584718856,0 +"4343","2015-02-07 18:13:00",20.3566666666667,22.29,0,434.333333333333,0.00328873027470996,0 +"4344","2015-02-07 18:14:00",20.34,22.29,0,434,0.00328532796340797,0 +"4345","2015-02-07 18:15:00",20.34,22.34,0,437,0.00329273648694994,0 +"4346","2015-02-07 18:16:00",20.29,22.34,0,438.5,0.00328252505565792,0 +"4347","2015-02-07 18:16:59",20.29,22.29,0,439,0.00327513962776155,0 +"4348","2015-02-07 18:17:59",20.39,22.39,0,432,0.00331040775412912,0 +"4349","2015-02-07 18:19:00",20.34,22.445,0,442,0.0033082949578363,0 +"4350","2015-02-07 18:20:00",20.29,22.5,0,439.333333333333,0.00330615959738039,0 +"4351","2015-02-07 18:21:00",20.29,22.5,0,432,0.00330615959738039,0 +"4352","2015-02-07 18:22:00",20.29,22.6,0,434,0.00332093209327951,0 +"4353","2015-02-07 18:23:00",20.29,22.6,0,434,0.00332093209327951,0 +"4354","2015-02-07 18:23:59",20.29,22.65,0,435,0.00332831860297592,0 +"4355","2015-02-07 18:24:59",20.29,22.7,0,437,0.00333570528717845,0 +"4356","2015-02-07 18:26:00",20.29,22.7,0,437,0.00333570528717845,0 +"4357","2015-02-07 18:27:00",20.29,22.7,0,437,0.00333570528717845,0 +"4358","2015-02-07 18:28:00",20.29,22.7,0,436,0.00333570528717845,0 +"4359","2015-02-07 18:29:00",20.29,22.745,0,438,0.0033423534521686,0 +"4360","2015-02-07 18:29:59",20.29,22.79,0,428,0.00334900175851823,0 +"4361","2015-02-07 18:30:59",20.29,22.79,0,433,0.00334900175851823,0 +"4362","2015-02-07 18:32:00",20.29,22.79,0,435,0.00334900175851823,0 +"4363","2015-02-07 18:33:00",20.29,22.89,0,439.5,0.00336377627875311,0 +"4364","2015-02-07 18:34:00",20.29,22.89,0,438.5,0.00336377627875311,0 +"4365","2015-02-07 18:35:00",20.29,22.89,0,440,0.00336377627875311,0 +"4366","2015-02-07 18:36:00",20.29,23,0,438,0.00338002905736888,0 +"4367","2015-02-07 18:36:59",20.2,22.89,0,437,0.00334501033919613,0 +"4368","2015-02-07 18:38:00",20.29,23,0,435.5,0.00338002905736888,0 +"4369","2015-02-07 18:39:00",20.245,22.9725,0,436,0.00336653702317086,0 +"4370","2015-02-07 18:40:00",20.26,22.9966666666667,0,435.25,0.00337324142751268,0 +"4371","2015-02-07 18:40:59",20.2,23,0,432,0.00336117195896949,0 +"4372","2015-02-07 18:42:00",20.245,23.05,0,436,0.00337795604810557,0 +"4373","2015-02-07 18:42:59",20.245,23.05,0,441,0.00337795604810557,0 +"4374","2015-02-07 18:43:59",20.2,23,0,437,0.00336117195896949,0 +"4375","2015-02-07 18:45:00",20.2,23.1,0,438,0.00337586506550852,0 +"4376","2015-02-07 18:46:00",20.2,23.1,0,436,0.00337586506550852,0 +"4377","2015-02-07 18:47:00",20.2,23.23,0,438,0.00339496713624954,0 +"4378","2015-02-07 18:48:00",20.2,23.2,0,435,0.00339055886250441,0 +"4379","2015-02-07 18:49:00",20.2,23.29,0,441,0.00340378387018154,0 +"4380","2015-02-07 18:49:59",20.2,23.29,0,436,0.00340378387018154,0 +"4381","2015-02-07 18:51:00",20.1,23.29,0,434.5,0.00338267464632764,0 +"4382","2015-02-07 18:52:00",20.15,23.29,0,438,0.00339321479163625,0 +"4383","2015-02-07 18:53:00",20.15,23.29,0,439,0.00339321479163625,0 +"4384","2015-02-07 18:53:59",20.2,23.3566666666667,0,440,0.00341358053278282,0 +"4385","2015-02-07 18:55:00",20.15,23.29,0,441.5,0.00339321479163625,0 +"4386","2015-02-07 18:55:59",20.15,23.34,0,439.5,0.00340053932116234,0 +"4387","2015-02-07 18:56:59",20.2,23.39,0,439,0.00341847897917952,0 +"4388","2015-02-07 18:58:00",20.1,23.34,0,436.5,0.00338997630076753,0 +"4389","2015-02-07 18:59:00",20.2,23.34,0,433,0.00341113133835882,0 +"4390","2015-02-07 19:00:00",20.1,23.39,0,439,0.00339727812571033,0 +"4391","2015-02-07 19:01:00",20.2,23.4633333333333,0,439.333333333333,0.00342925583135537,0 +"4392","2015-02-07 19:01:59",20.2,23.445,0,435,0.00342656158349271,0 +"4393","2015-02-07 19:02:59",20.15,23.55,0,438.5,0.00343130421878666,0 +"4394","2015-02-07 19:04:00",20.15,23.5,0,441,0.00342397896862601,0 +"4395","2015-02-07 19:05:00",20.15,23.6,0,441,0.00343862964054265,0 +"4396","2015-02-07 19:06:00",20.15,23.65,0,442,0.0034459552339,0 +"4397","2015-02-07 19:07:00",20.15,23.65,0,440,0.0034459552339,0 +"4398","2015-02-07 19:08:00",20.15,23.6,0,440,0.00343862964054265,0 +"4399","2015-02-07 19:08:59",20.2,23.745,0,444,0.00347065219389873,0 +"4400","2015-02-07 19:09:59",20.2,23.7,0,443,0.00346403820604018,0 +"4401","2015-02-07 19:11:00",20.15,23.7,0,441.5,0.00345328099886475,0 +"4402","2015-02-07 19:12:00",20.2,23.7,0,440.5,0.00346403820604018,0 +"4403","2015-02-07 19:13:00",20.15,23.895,0,440,0.00348185312204922,0 +"4404","2015-02-07 19:14:00",20.15,24,0,442,0.0034972391927462,0 +"4405","2015-02-07 19:14:59",20.1,24.05,0,434.5,0.0034936781973234,0 +"4406","2015-02-07 19:15:59",20.1333333333333,24.0333333333333,0,437.666666666667,0.00349849372433744,0 +"4407","2015-02-07 19:17:00",20.1,24.0666666666667,0,441.666666666667,0.00349611292727846,0 +"4408","2015-02-07 19:18:00",20.1,24,0,436,0.00348637412118249,0 +"4409","2015-02-07 19:19:00",20.1,24.15,0,440,0.0035082868613744,0 +"4410","2015-02-07 19:20:00",20.1,24.1,0,445,0.00350098244405205,0 +"4411","2015-02-07 19:21:00",20.1,24.1,0,441,0.00350098244405205,0 +"4412","2015-02-07 19:21:59",20.1,24.2,0,443,0.00351559144929644,0 +"4413","2015-02-07 19:23:00",20.1,24.1,0,438.5,0.00350098244405205,0 +"4414","2015-02-07 19:24:00",20.2,24.1,0,439,0.00352283411405765,0 +"4415","2015-02-07 19:25:00",20.1,24,0,444,0.00348637412118249,0 +"4416","2015-02-07 19:25:59",20.1,24.05,0,438.5,0.0034936781973234,0 +"4417","2015-02-07 19:27:00",20.1,24.2,0,439,0.00351559144929644,0 +"4418","2015-02-07 19:27:59",20.1,24.15,0,437,0.0035082868613744,0 +"4419","2015-02-07 19:28:59",20.1,24.2,0,435.333333333333,0.00351559144929644,0 +"4420","2015-02-07 19:30:00",20.1,24.2,0,440,0.00351559144929644,0 +"4421","2015-02-07 19:31:00",20.1,24.2,0,435,0.00351559144929644,0 +"4422","2015-02-07 19:32:00",20.05,24.2,0,440,0.00350466483040947,0 +"4423","2015-02-07 19:33:00",20.1,24.245,0,439.5,0.00352216572429394,0 +"4424","2015-02-07 19:34:00",20.1,24.245,0,445,0.00352216572429394,0 +"4425","2015-02-07 19:34:59",20.05,24.245,0,442,0.00351121855756207,0 +"4426","2015-02-07 19:36:00",20.0666666666667,24.29,0,441,0.00352142498332395,0 +"4427","2015-02-07 19:37:00",20,24.3233333333333,0,441.5,0.00351167439325981,0 +"4428","2015-02-07 19:38:00",20.1,24.39,0,440,0.0035433504393747,0 +"4429","2015-02-07 19:38:59",20.0666666666667,24.4633333333333,0,439.333333333333,0.00354669714352311,0 +"4430","2015-02-07 19:40:00",20.1,24.5,0,446,0.00355942255975679,0 +"4431","2015-02-07 19:40:59",20,24.445,0,445,0.00352933965427684,0 +"4432","2015-02-07 19:41:59",20,24.5,0,444,0.00353732564769569,0 +"4433","2015-02-07 19:43:00",20.1,24.6,0,445,0.0035740342949787,0 +"4434","2015-02-07 19:44:00",20,24.5,0,443.5,0.00353732564769569,0 +"4435","2015-02-07 19:45:00",20,24.5,0,444,0.00353732564769569,0 +"4436","2015-02-07 19:46:00",20.1,24.7,0,443,0.00358864671281456,0 +"4437","2015-02-07 19:46:59",20,24.6,0,443,0.00355184615815818,0 +"4438","2015-02-07 19:47:59",20,24.7,0,443,0.00356636734276148,0 +"4439","2015-02-07 19:49:00",20,24.7,0,442,0.00356636734276148,0 +"4440","2015-02-07 19:50:00",20,24.7,0,447,0.00356636734276148,0 +"4441","2015-02-07 19:51:00",20,24.745,0,441.5,0.00357290209578391,0 +"4442","2015-02-07 19:52:00",20,24.79,0,441.666666666667,0.00357943698533364,0 +"4443","2015-02-07 19:53:00",20,24.89,0,434,0.00359395945093381,0 +"4444","2015-02-07 19:53:59",20,24.89,0,439,0.00359395945093381,0 +"4445","2015-02-07 19:54:59",20,24.89,0,440,0.00359395945093381,0 +"4446","2015-02-07 19:56:00",20,24.945,0,439,0.00360194709442146,0 +"4447","2015-02-07 19:57:00",20,25,0,437,0.00360993494188571,0 +"4448","2015-02-07 19:58:00",20,25,0,442,0.00360993494188571,0 +"4449","2015-02-07 19:59:00",20,25.0666666666667,0,446.333333333333,0.00361961745471477,0 +"4450","2015-02-07 19:59:59",20,25.025,0,442,0.00361356584907457,0 +"4451","2015-02-07 20:00:59",20,25.1,0,440.5,0.00362445882352175,0 +"4452","2015-02-07 20:02:00",20,25.05,0,441,0.00361719679840972,0 +"4453","2015-02-07 20:03:00",20,25,0,443,0.00360993494188571,0 +"4454","2015-02-07 20:04:00",20,25,0,441.666666666667,0.00360993494188571,0 +"4455","2015-02-07 20:05:00",20,25,0,438.5,0.00360993494188571,0 +"4456","2015-02-07 20:06:00",20,25,0,443,0.00360993494188571,0 +"4457","2015-02-07 20:06:59",20.025,25.025,0,440.5,0.00361919821447153,0 +"4458","2015-02-07 20:08:00",20.025,25.05,0,441.25,0.00362283485604032,0 +"4459","2015-02-07 20:09:00",20.05,25.1,0,443.5,0.00363576547200194,0 +"4460","2015-02-07 20:10:00",20,25,0,445.5,0.00360993494188571,0 +"4461","2015-02-07 20:10:59",20,25.1,0,447,0.00362445882352175,0 +"4462","2015-02-07 20:12:00",20,25.1,0,445,0.00362445882352175,0 +"4463","2015-02-07 20:12:59",20,25.0666666666667,0,443,0.00361961745471477,0 +"4464","2015-02-07 20:13:59",20.1,25.2,0,444,0.00366171904287748,0 +"4465","2015-02-07 20:15:00",20,25.1333333333333,0,445.333333333333,0.00362930026725936,0 +"4466","2015-02-07 20:16:00",20.05,25.15,0,443,0.00364305045233985,0 +"4467","2015-02-07 20:17:00",20,25.2,0,440.5,0.00363898337953339,0 +"4468","2015-02-07 20:18:00",20,25.2,0,440.5,0.00363898337953339,0 +"4469","2015-02-07 20:19:00",20,25.2,0,439,0.00363898337953339,0 +"4470","2015-02-07 20:19:59",20.0333333333333,25.23,0,447,0.00365091467257836,0 +"4471","2015-02-07 20:21:00",20,25.2,0,447,0.00363898337953339,0 +"4472","2015-02-07 20:22:00",20,25.29,0,442,0.00365205605657382,0 +"4473","2015-02-07 20:23:00",20,25.2675,0,439,0.00364878783609788,0 +"4474","2015-02-07 20:23:59",20,25.29,0,440,0.00365205605657382,0 +"4475","2015-02-07 20:25:00",20,25.34,0,440,0.00365931889099011,0 +"4476","2015-02-07 20:25:59",20.0333333333333,25.3566666666667,0,442,0.00366935214024042,0 +"4477","2015-02-07 20:26:59",20,25.34,0,440,0.00365931889099011,0 +"4478","2015-02-07 20:28:00",20,25.39,0,439.5,0.00366658189402849,0 +"4479","2015-02-07 20:29:00",20,25.445,0,439.5,0.00367457139213622,0 +"4480","2015-02-07 20:30:00",20,25.5,0,440,0.00368256109429158,0 +"4481","2015-02-07 20:31:00",20,25.55,0,441,0.00368982463696009,0 +"4482","2015-02-07 20:31:59",20,25.6,0,443,0.00369708834827534,0 +"4483","2015-02-07 20:32:59",20,25.65,0,442,0.00370435222824321,0 +"4484","2015-02-07 20:34:00",20,25.7,0,445,0.00371161627686957,0 +"4485","2015-02-07 20:35:00",20,25.65,0,441,0.00370435222824321,0 +"4486","2015-02-07 20:36:00",20,25.7,0,439.5,0.00371161627686957,0 +"4487","2015-02-07 20:37:00",19.945,25.745,0,440,0.00370543008606362,0 +"4488","2015-02-07 20:38:00",20,25.84,0,434,0.0037319565103366,0 +"4489","2015-02-07 20:38:59",20,25.89,0,440,0.00373922119991882,0 +"4490","2015-02-07 20:39:59",20,25.89,0,443,0.00373922119991882,0 +"4491","2015-02-07 20:41:00",19.945,25.89,0,442.5,0.00372642469747065,0 +"4492","2015-02-07 20:42:00",19.89,25.89,0,441,0.00371366683650005,0 +"4493","2015-02-07 20:43:00",19.945,25.89,0,443,0.00372642469747065,0 +"4494","2015-02-07 20:44:00",19.9266666666667,25.9633333333333,0,444.333333333333,0.00373277408699372,0 +"4495","2015-02-07 20:44:59",19.9266666666667,26,0,446.333333333333,0.00373807737101431,0 +"4496","2015-02-07 20:45:59",19.89,26.1,0,436,0.00374397059334565,0 +"4497","2015-02-07 20:47:00",19.89,26.1,0,438.5,0.00374397059334565,0 +"4498","2015-02-07 20:48:00",20,26.1,0,436,0.0037697347382913,0 +"4499","2015-02-07 20:49:00",19.89,26.1,0,443,0.00374397059334565,0 +"4500","2015-02-07 20:50:00",19.89,26.1,0,445.5,0.00374397059334565,0 +"4501","2015-02-07 20:51:00",19.89,26.1,0,445.5,0.00374397059334565,0 +"4502","2015-02-07 20:51:59",19.89,26.2,0,441.333333333333,0.00375840198544118,0 +"4503","2015-02-07 20:53:00",19.89,26.2,0,440,0.00375840198544118,0 +"4504","2015-02-07 20:54:00",19.89,26.245,0,438.5,0.00376489632905666,0 +"4505","2015-02-07 20:55:00",19.89,26.245,0,443.5,0.00376489632905666,0 +"4506","2015-02-07 20:55:59",19.89,26.2,0,441,0.00375840198544118,0 +"4507","2015-02-07 20:57:00",19.89,26.29,0,439,0.00377139080747475,0 +"4508","2015-02-07 20:57:59",19.89,26.29,0,440.5,0.00377139080747475,0 +"4509","2015-02-07 20:58:59",19.89,26.29,0,444,0.00377139080747475,0 +"4510","2015-02-07 21:00:00",19.89,26.29,0,439,0.00377139080747475,0 +"4511","2015-02-07 21:01:00",19.89,26.29,0,438,0.00377139080747475,0 +"4512","2015-02-07 21:02:00",19.89,26.29,0,438,0.00377139080747475,0 +"4513","2015-02-07 21:03:00",19.89,26.39,0,440,0.00378582346438501,0 +"4514","2015-02-07 21:04:00",19.89,26.39,0,443,0.00378582346438501,0 +"4515","2015-02-07 21:04:59",19.79,26.39,0,435,0.00376227454189624,0 +"4516","2015-02-07 21:06:00",19.89,26.6,0,439,0.00381613421099627,0 +"4517","2015-02-07 21:07:00",19.89,26.6,0,438,0.00381613421099627,0 +"4518","2015-02-07 21:08:00",19.8233333333333,26.6,0,440.333333333333,0.00380029395676112,0 +"4519","2015-02-07 21:08:59",19.79,26.5,0,438,0.00377805187958511,0 +"4520","2015-02-07 21:10:00",19.8233333333333,26.6,0,440.666666666667,0.00380029395676112,0 +"4521","2015-02-07 21:10:59",19.89,26.6,0,435.333333333333,0.00381613421099627,0 +"4522","2015-02-07 21:11:59",19.84,26.6,0,437,0.00380424857235653,0 +"4523","2015-02-07 21:13:00",19.89,26.6,0,438,0.00381613421099627,0 +"4524","2015-02-07 21:14:00",19.89,26.6,0,441,0.00381613421099627,0 +"4525","2015-02-07 21:15:00",19.89,26.55,0,442,0.00380891710023879,0 +"4526","2015-02-07 21:16:00",19.89,26.6,0,441.5,0.00381613421099627,0 +"4527","2015-02-07 21:16:59",19.89,26.6,0,440.5,0.00381613421099627,0 +"4528","2015-02-07 21:17:59",19.89,26.6,0,443.666666666667,0.00381613421099627,0 +"4529","2015-02-07 21:19:00",19.89,26.7,0,441,0.00383056893190861,0 +"4530","2015-02-07 21:20:00",19.89,26.79,0,440,0.00384356075007424,0 +"4531","2015-02-07 21:21:00",19.89,26.84,0,429.5,0.00385077865991085,0 +"4532","2015-02-07 21:22:00",19.89,26.7,0,433,0.00383056893190861,0 +"4533","2015-02-07 21:23:00",19.89,26.675,0,443,0.00382696018925405,0 +"4534","2015-02-07 21:23:59",19.89,26.7,0,438.75,0.00383056893190861,0 +"4535","2015-02-07 21:24:59",19.89,26.7,0,441,0.00383056893190861,0 +"4536","2015-02-07 21:26:00",19.89,26.79,0,443,0.00384356075007424,0 +"4537","2015-02-07 21:27:00",19.89,26.7,0,438.666666666667,0.00383056893190861,0 +"4538","2015-02-07 21:28:00",19.89,26.79,0,437,0.00384356075007424,0 +"4539","2015-02-07 21:29:00",19.89,26.79,0,438,0.00384356075007424,0 +"4540","2015-02-07 21:29:59",19.89,26.79,0,437.5,0.00384356075007424,0 +"4541","2015-02-07 21:30:59",19.89,26.84,0,445,0.00385077865991085,0 +"4542","2015-02-07 21:32:00",19.89,26.89,0,443,0.00385799673623897,0 +"4543","2015-02-07 21:33:00",19.89,26.8933333333333,0,440.666666666667,0.00385847794724735,0 +"4544","2015-02-07 21:34:00",19.89,26.945,0,441.5,0.00386593681250449,0 +"4545","2015-02-07 21:35:00",19.89,27,0,442.5,0.00387387709023938,0 +"4546","2015-02-07 21:36:00",19.89,27,0,440.5,0.00387387709023938,0 +"4547","2015-02-07 21:36:59",19.89,27.1,0,438,0.00388831447503451,0 +"4548","2015-02-07 21:38:00",19.89,27.1,0,438,0.00388831447503451,0 +"4549","2015-02-07 21:39:00",19.89,27.1,0,438.5,0.00388831447503451,0 +"4550","2015-02-07 21:40:00",19.79,27.1,0,441,0.00386412409206066,0 +"4551","2015-02-07 21:40:59",19.89,27.2,0,444,0.00390275252591555,0 +"4552","2015-02-07 21:42:00",19.89,27.245,0,441.5,0.00390924986613483,0 +"4553","2015-02-07 21:42:59",19.89,27.29,0,438,0.00391574734125005,0 +"4554","2015-02-07 21:43:59",19.89,27.29,0,441,0.00391574734125005,0 +"4555","2015-02-07 21:45:00",19.79,27.2,0,440.5,0.00387847176283724,0 +"4556","2015-02-07 21:46:00",19.79,27.23,0,443,0.00388277619234767,0 +"4557","2015-02-07 21:47:00",19.79,27.29,0,442,0.0038913852289912,0 +"4558","2015-02-07 21:48:00",19.79,27.29,0,446,0.0038913852289912,0 +"4559","2015-02-07 21:49:00",19.79,27.29,0,444,0.0038913852289912,0 +"4560","2015-02-07 21:49:59",19.79,27.29,0,438,0.0038913852289912,0 +"4561","2015-02-07 21:51:00",19.79,27.29,0,438,0.0038913852289912,0 +"4562","2015-02-07 21:52:00",19.79,27.29,0,437,0.0038913852289912,0 +"4563","2015-02-07 21:53:00",19.79,27.3566666666667,0,437,0.00390095110303563,0 +"4564","2015-02-07 21:53:59",19.79,27.39,0,443.5,0.00390573414970943,0 +"4565","2015-02-07 21:55:00",19.79,27.5,0,444,0.00392151872240996,0 +"4566","2015-02-07 21:55:59",19.79,27.39,0,442,0.00390573414970943,0 +"4567","2015-02-07 21:56:59",19.79,27.5,0,440,0.00392151872240996,0 +"4568","2015-02-07 21:58:00",19.79,27.5,0,441,0.00392151872240996,0 +"4569","2015-02-07 21:59:00",19.79,27.5,0,443.666666666667,0.00392151872240996,0 +"4570","2015-02-07 22:00:00",19.79,27.5,0,438.333333333333,0.00392151872240996,0 +"4571","2015-02-07 22:01:00",19.79,27.5,0,444,0.00392151872240996,0 +"4572","2015-02-07 22:01:59",19.79,27.5,0,444.5,0.00392151872240996,0 +"4573","2015-02-07 22:02:59",19.79,27.6,0,440,0.00393586902483269,0 +"4574","2015-02-07 22:04:00",19.79,27.65,0,441,0.00394304442280048,0 +"4575","2015-02-07 22:05:00",19.79,27.7,0,436.5,0.0039502199852801,0 +"4576","2015-02-07 22:06:00",19.745,27.7,0,435,0.00393913460988321,0 +"4577","2015-02-07 22:07:00",19.79,27.7,0,442,0.0039502199852801,0 +"4578","2015-02-07 22:08:00",19.79,27.7,0,443,0.0039502199852801,0 +"4579","2015-02-07 22:08:59",19.79,27.79,0,441,0.00396313641233127,0 +"4580","2015-02-07 22:09:59",19.7,27.79,0,439,0.00394092026432448,0 +"4581","2015-02-07 22:11:00",19.7,27.84,0,437,0.0039480558071287,0 +"4582","2015-02-07 22:12:00",19.7,27.89,0,440,0.00395519151262096,0 +"4583","2015-02-07 22:13:00",19.73,27.9633333333333,0,439,0.00397309734895495,0 +"4584","2015-02-07 22:14:00",19.79,28,0,438,0.00399327681522299,0 +"4585","2015-02-07 22:14:59",19.7,27.945,0,438,0.00396304097657378,0 +"4586","2015-02-07 22:15:59",19.745,27.945,0,443,0.00397419794197032,0 +"4587","2015-02-07 22:17:00",19.79,27.79,0,439,0.00396313641233127,0 +"4588","2015-02-07 22:18:00",19.745,27.79,0,441,0.00395201456113058,0 +"4589","2015-02-07 22:19:00",19.79,27.79,0,437.5,0.00396313641233127,0 +"4590","2015-02-07 22:20:00",19.79,27.79,0,439.5,0.00396313641233127,0 +"4591","2015-02-07 22:21:00",19.79,27.79,0,435.5,0.00396313641233127,0 +"4592","2015-02-07 22:21:59",19.79,27.79,0,438,0.00396313641233127,0 +"4593","2015-02-07 22:23:00",19.79,27.79,0,437,0.00396313641233127,0 +"4594","2015-02-07 22:24:00",19.79,27.79,0,434.666666666667,0.00396313641233127,0 +"4595","2015-02-07 22:25:00",19.79,27.79,0,439,0.00396313641233127,0 +"4596","2015-02-07 22:25:59",19.79,27.79,0,438,0.00396313641233127,0 +"4597","2015-02-07 22:27:00",19.79,27.84,0,441.5,0.0039703124354741,0 +"4598","2015-02-07 22:27:59",19.79,27.79,0,439.5,0.00396313641233127,0 +"4599","2015-02-07 22:28:59",19.79,27.945,0,436,0.00398538261963677,0 +"4600","2015-02-07 22:30:00",19.79,28.05,0,433.5,0.00400045352944381,0 +"4601","2015-02-07 22:31:00",19.79,28.05,0,433,0.00400045352944381,0 +"4602","2015-02-07 22:32:00",19.79,28.15,0,433.5,0.00401480745156241,0 +"4603","2015-02-07 22:33:00",19.79,28.0333333333333,0,431.666666666667,0.00399806127308636,0 +"4604","2015-02-07 22:34:00",19.79,28.1,0,431.5,0.00400763040822173,0 +"4605","2015-02-07 22:34:59",19.79,28.2,0,430.5,0.0040219846594715,0 +"4606","2015-02-07 22:36:00",19.76,28.23,0,435,0.00401875446850276,0 +"4607","2015-02-07 22:37:00",19.7,28.29,0,438,0.00401228301399633,0 +"4608","2015-02-07 22:38:00",19.745,28.34,0,439.5,0.00403073689314494,0 +"4609","2015-02-07 22:38:59",19.7,28.39,0,440.5,0.00402655751661013,0 +"4610","2015-02-07 22:40:00",19.7,28.39,0,435.5,0.00402655751661013,0 +"4611","2015-02-07 22:40:59",19.7,28.39,0,435.5,0.00402655751661013,0 +"4612","2015-02-07 22:41:59",19.7,28.445,0,438.5,0.00403440877053237,0 +"4613","2015-02-07 22:43:00",19.7,28.5,0,437,0.00404226022138861,0 +"4614","2015-02-07 22:44:00",19.7,28.5,0,430.5,0.00404226022138861,0 +"4615","2015-02-07 22:45:00",19.7,28.5,0,433.5,0.00404226022138861,0 +"4616","2015-02-07 22:46:00",19.7,28.445,0,437.5,0.00403440877053237,0 +"4617","2015-02-07 22:46:59",19.7,28.5,0,436.5,0.00404226022138861,0 +"4618","2015-02-07 22:47:59",19.7,28.5,0,439,0.00404226022138861,0 +"4619","2015-02-07 22:49:00",19.7,28.5,0,437,0.00404226022138861,0 +"4620","2015-02-07 22:50:00",19.7,28.5,0,440.5,0.00404226022138861,0 +"4621","2015-02-07 22:51:00",19.7,28.5333333333333,0,441.333333333333,0.00404701877230097,0 +"4622","2015-02-07 22:52:00",19.7,28.5666666666667,0,439.666666666667,0.00405177739555343,0 +"4623","2015-02-07 22:53:00",19.7,28.6,0,440,0.00405653609114763,0 +"4624","2015-02-07 22:53:59",19.65,28.6,0,439.5,0.00404387831517003,0 +"4625","2015-02-07 22:54:59",19.7,28.65,0,436,0.00406367427018332,0 +"4626","2015-02-07 22:56:00",19.65,28.65,0,438.5,0.00405099407652843,0 +"4627","2015-02-07 22:57:00",19.65,28.65,0,440.5,0.00405099407652843,0 +"4628","2015-02-07 22:58:00",19.7,28.7,0,437.5,0.00407081261199722,0 +"4629","2015-02-07 22:59:00",19.6,28.6,0,435,0.00403125541777448,0 +"4630","2015-02-07 22:59:59",19.7,28.7,0,435.5,0.00407081261199722,0 +"4631","2015-02-07 23:00:59",19.7,28.7,0,440,0.00407081261199722,0 +"4632","2015-02-07 23:02:00",19.6,28.6,0,438,0.00403125541777448,0 +"4633","2015-02-07 23:03:00",19.6666666666667,28.73,0,439.666666666667,0.00406661442155126,0 +"4634","2015-02-07 23:04:00",19.65,28.745,0,441,0.00406451446876457,0 +"4635","2015-02-07 23:05:00",19.65,28.79,0,438,0.00407091906891627,0 +"4636","2015-02-07 23:06:00",19.7,28.945,0,440,0.00410579284002946,0 +"4637","2015-02-07 23:06:59",19.7,28.945,0,441.5,0.00410579284002946,0 +"4638","2015-02-07 23:08:00",19.6,28.89,0,439,0.00407239941233829,0 +"4639","2015-02-07 23:09:00",19.6,28.84,0,435,0.00406530523434103,0 +"4640","2015-02-07 23:10:00",19.65,28.945,0,437,0.0040929803613646,0 +"4641","2015-02-07 23:10:59",19.65,28.945,0,438.5,0.0040929803613646,0 +"4642","2015-02-07 23:12:00",19.6,28.89,0,439,0.00407239941233829,0 +"4643","2015-02-07 23:12:59",19.7,29,0,441,0.00411364608153483,0 +"4644","2015-02-07 23:13:59",19.65,28.945,0,441,0.0040929803613646,0 +"4645","2015-02-07 23:15:00",19.6,28.89,0,444.5,0.00407239941233829,0 +"4646","2015-02-07 23:16:00",19.65,28.945,0,443.5,0.0040929803613646,0 +"4647","2015-02-07 23:17:00",19.7,29.05,0,437.5,0.00412078556295211,0 +"4648","2015-02-07 23:18:00",19.7,29,0,438.5,0.00411364608153483,0 +"4649","2015-02-07 23:19:00",19.6,28.89,0,433.5,0.00407239941233829,0 +"4650","2015-02-07 23:19:59",19.7,29,0,432,0.00411364608153483,0 +"4651","2015-02-07 23:21:00",19.7,28.89,0,433,0.00409793979552548,0 +"4652","2015-02-07 23:22:00",19.6666666666667,28.8566666666667,0,433,0.00408466131240046,0 +"4653","2015-02-07 23:23:00",19.7,28.89,0,439,0.00409793979552548,0 +"4654","2015-02-07 23:23:59",19.7,29,0,440,0.00411364608153483,0 +"4655","2015-02-07 23:25:00",19.65,28.89,0,439,0.00408515198285439,0 +"4656","2015-02-07 23:25:59",19.7,28.945,0,437.5,0.00410579284002946,0 +"4657","2015-02-07 23:26:59",19.7,29.05,0,438,0.00412078556295211,0 +"4658","2015-02-07 23:28:00",19.65,28.945,0,441,0.0040929803613646,0 +"4659","2015-02-07 23:29:00",19.7,29.05,0,438.5,0.00412078556295211,0 +"4660","2015-02-07 23:30:00",19.7,29.05,0,437.5,0.00412078556295211,0 +"4661","2015-02-07 23:31:00",19.7,29.05,0,444,0.00412078556295211,0 +"4662","2015-02-07 23:31:59",19.7,29.1,0,439,0.00412792520719215,0 +"4663","2015-02-07 23:32:59",19.7,29.1,0,438,0.00412792520719215,0 +"4664","2015-02-07 23:34:00",19.6666666666667,29.1,0,439.666666666667,0.0041193332589133,0 +"4665","2015-02-07 23:35:00",19.7,29,0,438,0.00411364608153483,0 +"4666","2015-02-07 23:36:00",19.7,29,0,438,0.00411364608153483,0 +"4667","2015-02-07 23:37:00",19.7,29.05,0,438.5,0.00412078556295211,0 +"4668","2015-02-07 23:38:00",19.7,29,0,438,0.00411364608153483,0 +"4669","2015-02-07 23:38:59",19.7,29.1666666666667,0,439.666666666667,0.00413744498613502,0 +"4670","2015-02-07 23:39:59",19.7,29.1,0,436,0.00412792520719215,0 +"4671","2015-02-07 23:41:00",19.6,29.1,0,438,0.0041021967156572,0 +"4672","2015-02-07 23:42:00",19.6666666666667,29.1,0,440.666666666667,0.0041193332589133,0 +"4673","2015-02-07 23:43:00",19.7,29.1,0,440,0.00412792520719215,0 +"4674","2015-02-07 23:44:00",19.65,29.2,0,435,0.00412927812888797,0 +"4675","2015-02-07 23:44:59",19.65,29.245,0,438,0.00413568405417123,0 +"4676","2015-02-07 23:45:59",19.65,29.245,0,439.5,0.00413568405417123,0 +"4677","2015-02-07 23:47:00",19.65,29.29,0,432.5,0.0041420901105338,0 +"4678","2015-02-07 23:48:00",19.65,29.34,0,433,0.00414920810467655,0 +"4679","2015-02-07 23:49:00",19.6,29.29,0,432,0.00412915862468785,0 +"4680","2015-02-07 23:50:00",19.6,29.29,0,437,0.00412915862468785,0 +"4681","2015-02-07 23:51:00",19.65,29.34,0,435,0.00414920810467655,0 +"4682","2015-02-07 23:51:59",19.6,29.29,0,438,0.00412915862468785,0 +"4683","2015-02-07 23:53:00",19.7,29.39,0,438,0.00416933835493484,0 +"4684","2015-02-07 23:54:00",19.6,29.29,0,439.333333333333,0.00412915862468785,0 +"4685","2015-02-07 23:55:00",19.6333333333333,29.3566666666667,0,436.666666666667,0.00414725639160758,0 +"4686","2015-02-07 23:55:59",19.6,29.39,0,432,0.00414335003585663,0 +"4687","2015-02-07 23:57:00",19.6,29.39,0,438,0.00414335003585663,0 +"4688","2015-02-07 23:57:59",19.6,29.39,0,440.666666666667,0.00414335003585663,0 +"4689","2015-02-07 23:58:59",19.6,29.39,0,438,0.00414335003585663,0 +"4690","2015-02-08 00:00:00",19.6,29.39,0,438.5,0.00414335003585663,0 +"4691","2015-02-08 00:01:00",19.6,29.4633333333333,0,438.666666666667,0.00415375747957689,0 +"4692","2015-02-08 00:02:00",19.6,29.5,0,437.5,0.00415896133117862,0 +"4693","2015-02-08 00:03:00",19.6,29.445,0,437,0.00415115558621183,0 +"4694","2015-02-08 00:04:00",19.6,29.5,0,440,0.00415896133117862,0 +"4695","2015-02-08 00:04:59",19.55,29.5,0,441,0.00414597181052063,0 +"4696","2015-02-08 00:06:00",19.6,29.5,0,438,0.00415896133117862,0 +"4697","2015-02-08 00:07:00",19.6,29.5,0,439,0.00415896133117862,0 +"4698","2015-02-08 00:08:00",19.6,29.5,0,440.5,0.00415896133117862,0 +"4699","2015-02-08 00:08:59",19.6,29.6,0,439.5,0.00417315409337,0 +"4700","2015-02-08 00:10:00",19.5,29.65,0,440,0.00415417382815466,0 +"4701","2015-02-08 00:10:59",19.55,29.65,0,442,0.00416719426026783,0 +"4702","2015-02-08 00:11:59",19.55,29.7,0,441.5,0.00417426872988002,0 +"4703","2015-02-08 00:13:00",19.5,29.7,0,441.666666666667,0.00416122604663459,0 +"4704","2015-02-08 00:14:00",19.55,29.7,0,440,0.00417426872988002,0 +"4705","2015-02-08 00:15:00",19.525,29.675,0,437.25,0.00416421119487459,0 +"4706","2015-02-08 00:16:00",19.6,29.7,0,435,0.00418734749897328,0 +"4707","2015-02-08 00:16:59",19.6,29.6,0,443,0.00417315409337,0 +"4708","2015-02-08 00:17:59",19.6,29.55,0,437,0.00416605763185056,0 +"4709","2015-02-08 00:19:00",19.6,29.6333333333333,0,436.666666666667,0.00417788515707872,0 +"4710","2015-02-08 00:20:00",19.6,29.5,0,436,0.00415896133117862,0 +"4711","2015-02-08 00:21:00",19.6,29.5,0,437,0.00415896133117862,0 +"4712","2015-02-08 00:22:00",19.6,29.5,0,438,0.00415896133117862,0 +"4713","2015-02-08 00:23:00",19.6,29.5,0,439.5,0.00415896133117862,0 +"4714","2015-02-08 00:23:59",19.6,29.5,0,440,0.00415896133117862,0 +"4715","2015-02-08 00:24:59",19.6,29.5,0,440,0.00415896133117862,0 +"4716","2015-02-08 00:26:00",19.6,29.55,0,442,0.00416605763185056,0 +"4717","2015-02-08 00:27:00",19.6,29.5,0,439.5,0.00415896133117862,0 +"4718","2015-02-08 00:28:00",19.6,29.6,0,434.333333333333,0.00417315409337,0 +"4719","2015-02-08 00:29:00",19.6,29.55,0,435.5,0.00416605763185056,0 +"4720","2015-02-08 00:29:59",19.6,29.7,0,437,0.00418734749897328,0 +"4721","2015-02-08 00:30:59",19.6,29.6666666666667,0,437.666666666667,0.00418261629227928,0 +"4722","2015-02-08 00:32:00",19.6,29.65,0,440.5,0.00418025071574242,0 +"4723","2015-02-08 00:33:00",19.6,29.7,0,439.5,0.00418734749897328,0 +"4724","2015-02-08 00:34:00",19.6,29.79,0,440,0.00420012211416958,0 +"4725","2015-02-08 00:35:00",19.6,29.79,0,436.5,0.00420012211416958,0 +"4726","2015-02-08 00:36:00",19.6,29.79,0,435.5,0.00420012211416958,0 +"4727","2015-02-08 00:36:59",19.6,29.79,0,434,0.00420012211416958,0 +"4728","2015-02-08 00:38:00",19.6,29.79,0,430,0.00420012211416958,0 +"4729","2015-02-08 00:39:00",19.6,29.84,0,433.5,0.00420721934783319,0 +"4730","2015-02-08 00:40:00",19.6,29.89,0,435.5,0.00421431674237602,0 +"4731","2015-02-08 00:40:59",19.6,29.89,0,439,0.00421431674237602,0 +"4732","2015-02-08 00:42:00",19.6,29.89,0,435,0.00421431674237602,0 +"4733","2015-02-08 00:42:59",19.6,29.89,0,440,0.00421431674237602,0 +"4734","2015-02-08 00:43:59",19.6,29.89,0,443,0.00421431674237602,0 +"4735","2015-02-08 00:45:00",19.55,29.89,0,439,0.00420115317235068,0 +"4736","2015-02-08 00:46:00",19.6,29.9266666666667,0,437.5,0.00421952160062496,0 +"4737","2015-02-08 00:47:00",19.55,29.945,0,439.666666666667,0.00420893594181827,0 +"4738","2015-02-08 00:48:00",19.6,29.89,0,446,0.00421431674237602,0 +"4739","2015-02-08 00:49:00",19.55,29.89,0,441,0.00420115317235068,0 +"4740","2015-02-08 00:49:59",19.55,29.89,0,442,0.00420115317235068,0 +"4741","2015-02-08 00:51:00",19.55,29.945,0,442,0.00420893594181827,0 +"4742","2015-02-08 00:52:00",19.5,30,0,439.5,0.00420354269368957,0 +"4743","2015-02-08 00:53:00",19.6,30,0,437,0.00422993157669211,0 +"4744","2015-02-08 00:53:59",19.5,30.0333333333333,0,436.666666666667,0.00420824489642727,0 +"4745","2015-02-08 00:55:00",19.5,30,0,435,0.00420354269368957,0 +"4746","2015-02-08 00:55:59",19.5,30,0,434,0.00420354269368957,0 +"4747","2015-02-08 00:56:59",19.55,30,0,436,0.00421671890474527,0 +"4748","2015-02-08 00:58:00",19.55,30,0,438.5,0.00421671890474527,0 +"4749","2015-02-08 00:59:00",19.5,30,0,437,0.00420354269368957,0 +"4750","2015-02-08 01:00:00",19.5,30.1,0,435.5,0.0042176495137607,0 +"4751","2015-02-08 01:01:00",19.5,30.0666666666667,0,437,0.00421294716978378,0 +"4752","2015-02-08 01:01:59",19.5,30.1,0,438.5,0.0042176495137607,0 +"4753","2015-02-08 01:02:59",19.5,30.1,0,436.666666666667,0.0042176495137607,0 +"4754","2015-02-08 01:04:00",19.5,30.1,0,436.5,0.0042176495137607,0 +"4755","2015-02-08 01:05:00",19.5,30.1,0,438,0.0042176495137607,0 +"4756","2015-02-08 01:06:00",19.5,30.1,0,436,0.0042176495137607,0 +"4757","2015-02-08 01:07:00",19.5,30.1,0,431,0.0042176495137607,0 +"4758","2015-02-08 01:08:00",19.5,30.1333333333333,0,433,0.00422235192835962,0 +"4759","2015-02-08 01:08:59",19.5,30.1,0,436,0.0042176495137607,0 +"4760","2015-02-08 01:09:59",19.6,30.2,0,438,0.00425832417969976,0 +"4761","2015-02-08 01:11:00",19.5,30.2,0,436.5,0.00423175696942982,0 +"4762","2015-02-08 01:12:00",19.5,30.2,0,439,0.00423175696942982,0 +"4763","2015-02-08 01:13:00",19.5,30.2,0,438,0.00423175696942982,0 +"4764","2015-02-08 01:14:00",19.5,30.2,0,436.5,0.00423175696942982,0 +"4765","2015-02-08 01:14:59",19.5,30.2675,0,436.5,0.00424127986133962,0 +"4766","2015-02-08 01:15:59",19.5,30.29,0,441.5,0.00424445422300381,0 +"4767","2015-02-08 01:17:00",19.5,30.29,0,442.5,0.00424445422300381,0 +"4768","2015-02-08 01:18:00",19.5,30.29,0,440.5,0.00424445422300381,0 +"4769","2015-02-08 01:19:00",19.5,30.29,0,444.666666666667,0.00424445422300381,0 +"4770","2015-02-08 01:20:00",19.5,30.29,0,439,0.00424445422300381,0 +"4771","2015-02-08 01:21:00",19.5,30.245,0,437,0.00423810553185621,0 +"4772","2015-02-08 01:21:59",19.5,30.2,0,438,0.00423175696942982,0 +"4773","2015-02-08 01:23:00",19.55,30.15,0,438.5,0.00423794615061667,0 +"4774","2015-02-08 01:24:00",19.5,30.1,0,434,0.0042176495137607,0 +"4775","2015-02-08 01:25:00",19.5,30.1,0,433.5,0.0042176495137607,0 +"4776","2015-02-08 01:25:59",19.5,30.1,0,437.333333333333,0.0042176495137607,0 +"4777","2015-02-08 01:27:00",19.5,30.1,0,442,0.0042176495137607,0 +"4778","2015-02-08 01:27:59",19.5,30.15,0,443.5,0.00422470316214283,0 +"4779","2015-02-08 01:28:59",19.5,30.15,0,445.5,0.00422470316214283,0 +"4780","2015-02-08 01:30:00",19.5,30.1,0,439,0.0042176495137607,0 +"4781","2015-02-08 01:31:00",19.6,30.1,0,442,0.00424412755638058,0 +"4782","2015-02-08 01:32:00",19.5333333333333,30.1,0,439.666666666667,0.00422645927186397,0 +"4783","2015-02-08 01:33:00",19.5,30.1,0,440,0.0042176495137607,0 +"4784","2015-02-08 01:34:00",19.5,30.15,0,438.5,0.00422470316214283,0 +"4785","2015-02-08 01:34:59",19.5666666666667,30.1666666666667,0,442.666666666667,0.00424472976965014,0 +"4786","2015-02-08 01:36:00",19.5666666666667,30.2,0,436.333333333333,0.00424945212258871,0 +"4787","2015-02-08 01:37:00",19.5666666666667,30.2,0,438,0.00424945212258871,0 +"4788","2015-02-08 01:38:00",19.5,30.2,0,437,0.00423175696942982,0 +"4789","2015-02-08 01:38:59",19.6,30.2,0,441.5,0.00425832417969976,0 +"4790","2015-02-08 01:40:00",19.6,30.2,0,441,0.00425832417969976,0 +"4791","2015-02-08 01:40:59",19.5,30.2,0,439,0.00423175696942982,0 +"4792","2015-02-08 01:41:59",19.55,30.2,0,441.5,0.00424502221904531,0 +"4793","2015-02-08 01:43:00",19.5333333333333,30.3233333333333,0,437,0.00425803305819191,0 +"4794","2015-02-08 01:44:00",19.55,30.34,0,437.5,0.00426483606139173,0 +"4795","2015-02-08 01:45:00",19.5,30.39,0,443,0.00425856288642746,0 +"4796","2015-02-08 01:46:00",19.5,30.29,0,437,0.00424445422300381,0 +"4797","2015-02-08 01:46:59",19.5,30.39,0,433,0.00425856288642746,0 +"4798","2015-02-08 01:47:59",19.5,30.39,0,434.5,0.00425856288642746,0 +"4799","2015-02-08 01:49:00",19.5,30.39,0,436,0.00425856288642746,0 +"4800","2015-02-08 01:50:00",19.5666666666667,30.39,0,439.666666666667,0.00427637089434552,0 +"4801","2015-02-08 01:51:00",19.5,30.5,0,439,0.00427408315045469,0 +"4802","2015-02-08 01:52:00",19.5,30.5,0,441,0.00427408315045469,0 +"4803","2015-02-08 01:53:00",19.5,30.5,0,439,0.00427408315045469,0 +"4804","2015-02-08 01:53:59",19.5,30.5,0,440,0.00427408315045469,0 +"4805","2015-02-08 01:54:59",19.5,30.6,0,436,0.00428819314894537,0 +"4806","2015-02-08 01:56:00",19.5,30.6,0,436,0.00428819314894537,0 +"4807","2015-02-08 01:57:00",19.5,30.6,0,437.75,0.00428819314894537,0 +"4808","2015-02-08 01:58:00",19.445,30.55,0,435,0.00426641765515782,0 +"4809","2015-02-08 01:59:00",19.5,30.6,0,438.5,0.00428819314894537,0 +"4810","2015-02-08 01:59:59",19.5,30.6,0,439,0.00428819314894537,0 +"4811","2015-02-08 02:00:59",19.39,30.55,0,436.5,0.00425174196501045,0 +"4812","2015-02-08 02:02:00",19.445,30.65,0,440,0.00428047912253884,0 +"4813","2015-02-08 02:03:00",19.39,30.55,0,441.5,0.00425174196501045,0 +"4814","2015-02-08 02:04:00",19.4266666666667,30.5333333333333,0,441,0.00425917998642283,0 +"4815","2015-02-08 02:05:00",19.39,30.55,0,440,0.00425174196501045,0 +"4816","2015-02-08 02:06:00",19.445,30.55,0,433,0.00426641765515782,0 +"4817","2015-02-08 02:06:59",19.39,30.6,0,440,0.00425874827115814,0 +"4818","2015-02-08 02:08:00",19.5,30.7,0,435,0.00430230378324886,0 +"4819","2015-02-08 02:09:00",19.39,30.6,0,436,0.00425874827115814,0 +"4820","2015-02-08 02:10:00",19.39,30.7,0,436,0.00427276135377004,0 +"4821","2015-02-08 02:10:59",19.445,30.7,0,431.5,0.00428751009302205,0 +"4822","2015-02-08 02:12:00",19.39,30.7,0,439,0.00427276135377004,0 +"4823","2015-02-08 02:12:59",19.39,30.7,0,440.5,0.00427276135377004,0 +"4824","2015-02-08 02:13:59",19.39,30.7,0,438,0.00427276135377004,0 +"4825","2015-02-08 02:15:00",19.39,30.745,0,438,0.00427906744554202,0 +"4826","2015-02-08 02:16:00",19.39,30.79,0,438,0.00428537366431039,0 +"4827","2015-02-08 02:17:00",19.39,30.79,0,433.666666666667,0.00428537366431039,0 +"4828","2015-02-08 02:18:00",19.39,30.79,0,439,0.00428537366431039,0 +"4829","2015-02-08 02:19:00",19.39,30.745,0,438,0.00427906744554202,0 +"4830","2015-02-08 02:19:59",19.39,30.745,0,439.5,0.00427906744554202,0 +"4831","2015-02-08 02:21:00",19.39,30.745,0,436,0.00427906744554202,0 +"4832","2015-02-08 02:22:00",19.39,30.7,0,437,0.00427276135377004,0 +"4833","2015-02-08 02:23:00",19.39,30.79,0,437,0.00428537366431039,0 +"4834","2015-02-08 02:23:59",19.39,30.73,0,446.333333333333,0.00427696540084084,0 +"4835","2015-02-08 02:25:00",19.5,30.79,0,447,0.00431500389777748,0 +"4836","2015-02-08 02:25:59",19.39,30.79,0,440,0.00428537366431039,0 +"4837","2015-02-08 02:26:59",19.39,30.79,0,441,0.00428537366431039,0 +"4838","2015-02-08 02:28:00",19.39,30.84,0,438,0.0042923807230041,0 +"4839","2015-02-08 02:29:00",19.39,30.89,0,434,0.00429938793849348,0 +"4840","2015-02-08 02:30:00",19.39,30.89,0,435.333333333333,0.00429938793849348,0 +"4841","2015-02-08 02:31:00",19.39,30.9266666666667,0,439.333333333333,0.00430452666284111,0 +"4842","2015-02-08 02:31:59",19.39,30.945,0,438.5,0.0043070960566371,0 +"4843","2015-02-08 02:32:59",19.39,30.89,0,434.5,0.00429938793849348,0 +"4844","2015-02-08 02:34:00",19.39,30.8233333333333,0,441.333333333333,0.00429004501935138,0 +"4845","2015-02-08 02:35:00",19.4266666666667,30.86,0,441,0.00430506302097151,0 +"4846","2015-02-08 02:36:00",19.39,30.89,0,437,0.00429938793849348,0 +"4847","2015-02-08 02:37:00",19.39,30.89,0,433.5,0.00429938793849348,0 +"4848","2015-02-08 02:38:00",19.39,30.89,0,434,0.00429938793849348,0 +"4849","2015-02-08 02:38:59",19.39,30.84,0,439,0.0042923807230041,0 +"4850","2015-02-08 02:39:59",19.39,30.84,0,441.5,0.0042923807230041,0 +"4851","2015-02-08 02:41:00",19.39,30.84,0,440,0.0042923807230041,0 +"4852","2015-02-08 02:42:00",19.39,30.89,0,443,0.00429938793849348,0 +"4853","2015-02-08 02:43:00",19.39,31,0,441.666666666667,0.00431480436451686,0 +"4854","2015-02-08 02:44:00",19.39,31,0,437,0.00431480436451686,0 +"4855","2015-02-08 02:44:59",19.39,31.05,0,434.5,0.0043218120817878,0 +"4856","2015-02-08 02:45:59",19.39,31.1,0,436.666666666667,0.00432881995587652,0 +"4857","2015-02-08 02:47:00",19.29,31.1,0,442,0.00430176611972061,0 +"4858","2015-02-08 02:48:00",19.34,31.05,0,434.5,0.00430828851395676,0 +"4859","2015-02-08 02:49:00",19.39,31.1,0,437,0.00432881995587652,0 +"4860","2015-02-08 02:50:00",19.39,31,0,439,0.00431480436451686,0 +"4861","2015-02-08 02:51:00",19.39,31.05,0,435.5,0.0043218120817878,0 +"4862","2015-02-08 02:51:59",19.39,31.1,0,434,0.00432881995587652,0 +"4863","2015-02-08 02:53:00",19.39,31.0666666666667,0,433,0.00432414802239291,0 +"4864","2015-02-08 02:54:00",19.39,31.1,0,440,0.00432881995587652,0 +"4865","2015-02-08 02:55:00",19.39,31.1,0,436,0.00432881995587652,0 +"4866","2015-02-08 02:55:59",19.39,31.1,0,434,0.00432881995587652,0 +"4867","2015-02-08 02:57:00",19.39,31.05,0,431.5,0.0043218120817878,0 +"4868","2015-02-08 02:57:59",19.3566666666667,31.1,0,437,0.00431978535762908,0 +"4869","2015-02-08 02:58:59",19.39,31.1,0,437,0.00432881995587652,0 +"4870","2015-02-08 03:00:00",19.39,31.1,0,440.5,0.00432881995587652,0 +"4871","2015-02-08 03:01:00",19.39,31.1,0,440,0.00432881995587652,0 +"4872","2015-02-08 03:02:00",19.39,31.1,0,440.666666666667,0.00432881995587652,0 +"4873","2015-02-08 03:03:00",19.39,31.1,0,440,0.00432881995587652,0 +"4874","2015-02-08 03:04:00",19.34,31.15,0,440,0.00432226025852344,0 +"4875","2015-02-08 03:04:59",19.39,31.1,0,441,0.00432881995587652,0 +"4876","2015-02-08 03:06:00",19.39,31.1,0,435,0.00432881995587652,0 +"4877","2015-02-08 03:07:00",19.39,31.1,0,439,0.00432881995587652,0 +"4878","2015-02-08 03:08:00",19.39,31.1,0,438,0.00432881995587652,0 +"4879","2015-02-08 03:08:59",19.39,31.1,0,437,0.00432881995587652,0 +"4880","2015-02-08 03:10:00",19.39,31.1,0,436.666666666667,0.00432881995587652,0 +"4881","2015-02-08 03:10:59",19.34,31.1,0,436.5,0.00431527430832022,0 +"4882","2015-02-08 03:11:59",19.39,31.1,0,436,0.00432881995587652,0 +"4883","2015-02-08 03:13:00",19.39,31.15,0,436.5,0.00433582798678829,0 +"4884","2015-02-08 03:14:00",19.29,31.2,0,435.5,0.0043156941375931,0 +"4885","2015-02-08 03:15:00",19.39,31.2,0,437,0.00434283617452838,0 +"4886","2015-02-08 03:16:00",19.34,31.2,0,437.5,0.00432924636457163,0 +"4887","2015-02-08 03:16:59",19.29,31.2,0,437,0.0043156941375931,0 +"4888","2015-02-08 03:17:59",19.34,31.2,0,431,0.00432924636457163,0 +"4889","2015-02-08 03:19:00",19.39,31.2,0,433,0.00434283617452838,0 +"4890","2015-02-08 03:20:00",19.3566666666667,31.2,0,439,0.00433377212088523,0 +"4891","2015-02-08 03:21:00",19.34,31.15,0,438,0.00432226025852344,0 +"4892","2015-02-08 03:22:00",19.29,31.15,0,438,0.00430873005122313,0 +"4893","2015-02-08 03:23:00",19.39,31.1666666666667,0,441,0.00433816403194269,0 +"4894","2015-02-08 03:23:59",19.39,31,0,438,0.00431480436451686,0 +"4895","2015-02-08 03:24:59",19.39,31.1,0,437,0.00432881995587652,0 +"4896","2015-02-08 03:26:00",19.39,31.05,0,437,0.0043218120817878,0 +"4897","2015-02-08 03:27:00",19.39,31.1,0,437,0.00432881995587652,0 +"4898","2015-02-08 03:28:00",19.39,31.05,0,437,0.0043218120817878,0 +"4899","2015-02-08 03:29:00",19.39,31,0,434,0.00431480436451686,0 +"4900","2015-02-08 03:29:59",19.39,31.0666666666667,0,437.666666666667,0.00432414802239291,0 +"4901","2015-02-08 03:30:59",19.39,31,0,443,0.00431480436451686,0 +"4902","2015-02-08 03:32:00",19.4266666666667,31,0,439,0.00432472923684185,0 +"4903","2015-02-08 03:33:00",19.39,31,0,440,0.00431480436451686,0 +"4904","2015-02-08 03:34:00",19.445,31,0,434,0.00432969923135401,0 +"4905","2015-02-08 03:35:00",19.39,31,0,435,0.00431480436451686,0 +"4906","2015-02-08 03:36:00",19.39,30.945,0,432,0.0043070960566371,0 +"4907","2015-02-08 03:36:59",19.39,31,0,437,0.00431480436451686,0 +"4908","2015-02-08 03:38:00",19.39,31,0,433.5,0.00431480436451686,0 +"4909","2015-02-08 03:39:00",19.39,31,0,435,0.00431480436451686,0 +"4910","2015-02-08 03:40:00",19.445,31,0,436.5,0.00432969923135401,0 +"4911","2015-02-08 03:40:59",19.445,31,0,434.5,0.00432969923135401,0 +"4912","2015-02-08 03:42:00",19.39,31,0,438.333333333333,0.00431480436451686,0 +"4913","2015-02-08 03:42:59",19.39,31,0,440.5,0.00431480436451686,0 +"4914","2015-02-08 03:43:59",19.39,31,0,438.666666666667,0.00431480436451686,0 +"4915","2015-02-08 03:45:00",19.39,31,0,436.5,0.00431480436451686,0 +"4916","2015-02-08 03:46:00",19.39,31,0,437,0.00431480436451686,0 +"4917","2015-02-08 03:47:00",19.39,31,0,443.5,0.00431480436451686,0 +"4918","2015-02-08 03:48:00",19.39,31.1,0,436.5,0.00432881995587652,0 +"4919","2015-02-08 03:49:00",19.39,31.1,0,435,0.00432881995587652,0 +"4920","2015-02-08 03:49:59",19.5,31.2,0,438.5,0.00437286649346282,0 +"4921","2015-02-08 03:51:00",19.39,31.1,0,437.5,0.00432881995587652,0 +"4922","2015-02-08 03:52:00",19.39,31.15,0,433.5,0.00433582798678829,0 +"4923","2015-02-08 03:53:00",19.39,31.2,0,434,0.00434283617452838,0 +"4924","2015-02-08 03:53:59",19.39,31.2,0,436,0.00434283617452838,0 +"4925","2015-02-08 03:55:00",19.39,31.2,0,434,0.00434283617452838,0 +"4926","2015-02-08 03:55:59",19.39,31.2,0,434.5,0.00434283617452838,0 +"4927","2015-02-08 03:56:59",19.39,31.2,0,433.666666666667,0.00434283617452838,0 +"4928","2015-02-08 03:58:00",19.39,31.2,0,431.5,0.00434283617452838,0 +"4929","2015-02-08 03:59:00",19.39,31.2,0,432,0.00434283617452838,0 +"4930","2015-02-08 04:00:00",19.39,31.2,0,438,0.00434283617452838,0 +"4931","2015-02-08 04:01:00",19.39,31.2,0,437.5,0.00434283617452838,0 +"4932","2015-02-08 04:01:59",19.39,31.2,0,433,0.00434283617452838,0 +"4933","2015-02-08 04:02:59",19.39,31.2,0,437,0.00434283617452838,0 +"4934","2015-02-08 04:04:00",19.39,31.2,0,433.5,0.00434283617452838,0 +"4935","2015-02-08 04:05:00",19.39,31.245,0,434.5,0.00434914367758701,0 +"4936","2015-02-08 04:06:00",19.34,31.2,0,433.5,0.00432924636457163,0 +"4937","2015-02-08 04:07:00",19.29,31.245,0,433.5,0.00432196194774202,0 +"4938","2015-02-08 04:08:00",19.34,31.2,0,433.5,0.00432924636457163,0 +"4939","2015-02-08 04:08:59",19.39,31.245,0,436.5,0.00434914367758701,0 +"4940","2015-02-08 04:09:59",19.29,31.29,0,436,0.00432822988334154,0 +"4941","2015-02-08 04:11:00",19.34,31.29,0,433,0.00434182174820438,0 +"4942","2015-02-08 04:12:00",19.29,31.29,0,434,0.00432822988334154,0 +"4943","2015-02-08 04:13:00",19.3233333333333,31.29,0,431,0.00433728694275697,0 +"4944","2015-02-08 04:14:00",19.39,31.29,0,436,0.00435545130768469,0 +"4945","2015-02-08 04:14:59",19.29,31.29,0,439.5,0.00432822988334154,0 +"4946","2015-02-08 04:15:59",19.29,31.29,0,439,0.00432822988334154,0 +"4947","2015-02-08 04:17:00",19.39,31.29,0,435.5,0.00435545130768469,0 +"4948","2015-02-08 04:18:00",19.29,31.34,0,437,0.00433519440336788,0 +"4949","2015-02-08 04:19:00",19.29,31.39,0,436.5,0.00434215907828131,0 +"4950","2015-02-08 04:20:00",19.39,31.39,0,438,0.00436946871830776,0 +"4951","2015-02-08 04:21:00",19.29,31.39,0,433,0.00434215907828131,0 +"4952","2015-02-08 04:21:59",19.29,31.4633333333333,0,435,0.00435237421500535,0 +"4953","2015-02-08 04:23:00",19.29,31.5,0,434.333333333333,0.00435748190831888,0 +"4954","2015-02-08 04:24:00",19.39,31.39,0,438,0.00436946871830776,0 +"4955","2015-02-08 04:25:00",19.3233333333333,31.3566666666667,0,435,0.00434659257032357,0 +"4956","2015-02-08 04:25:59",19.29,31.29,0,434.5,0.00432822988334154,0 +"4957","2015-02-08 04:27:00",19.29,31.39,0,434.333333333333,0.00434215907828131,0 +"4958","2015-02-08 04:27:59",19.29,31.29,0,434,0.00432822988334154,0 +"4959","2015-02-08 04:28:59",19.39,31.29,0,439,0.00435545130768469,0 +"4960","2015-02-08 04:30:00",19.3233333333333,31.29,0,441.666666666667,0.00433728694275697,0 +"4961","2015-02-08 04:31:00",19.29,31.29,0,439,0.00432822988334154,0 +"4962","2015-02-08 04:32:00",19.29,31.29,0,439,0.00432822988334154,0 +"4963","2015-02-08 04:33:00",19.3233333333333,31.29,0,436.333333333333,0.00433728694275697,0 +"4964","2015-02-08 04:34:00",19.39,31.29,0,436.5,0.00435545130768469,0 +"4965","2015-02-08 04:34:59",19.39,31.29,0,436,0.00435545130768469,0 +"4966","2015-02-08 04:36:00",19.39,31.29,0,438,0.00435545130768469,0 +"4967","2015-02-08 04:37:00",19.39,31.29,0,435,0.00435545130768469,0 +"4968","2015-02-08 04:38:00",19.39,31.2,0,434,0.00434283617452838,0 +"4969","2015-02-08 04:38:59",19.39,31.29,0,434,0.00435545130768469,0 +"4970","2015-02-08 04:40:00",19.39,31.29,0,436.333333333333,0.00435545130768469,0 +"4971","2015-02-08 04:40:59",19.39,31.29,0,430.666666666667,0.00435545130768469,0 +"4972","2015-02-08 04:41:59",19.39,31.29,0,436,0.00435545130768469,0 +"4973","2015-02-08 04:43:00",19.39,31.29,0,433,0.00435545130768469,0 +"4974","2015-02-08 04:44:00",19.34,31.29,0,432,0.00434182174820438,0 +"4975","2015-02-08 04:45:00",19.39,31.29,0,431,0.00435545130768469,0 +"4976","2015-02-08 04:46:00",19.39,31.29,0,437,0.00435545130768469,0 +"4977","2015-02-08 04:46:59",19.34,31.445,0,437,0.00436348053712032,0 +"4978","2015-02-08 04:47:59",19.3233333333333,31.4266666666667,0,439.333333333333,0.00435636377686856,0 +"4979","2015-02-08 04:49:00",19.29,31.39,0,438,0.00434215907828131,0 +"4980","2015-02-08 04:50:00",19.29,31.29,0,438,0.00432822988334154,0 +"4981","2015-02-08 04:51:00",19.29,31.39,0,436,0.00434215907828131,0 +"4982","2015-02-08 04:52:00",19.39,31.39,0,436,0.00436946871830776,0 +"4983","2015-02-08 04:53:00",19.29,31.445,0,438.5,0.00434982039958684,0 +"4984","2015-02-08 04:53:59",19.39,31.39,0,437.25,0.00436946871830776,0 +"4985","2015-02-08 04:54:59",19.29,31.445,0,436,0.00434982039958684,0 +"4986","2015-02-08 04:56:00",19.34,31.5,0,433.5,0.00437116627389738,0 +"4987","2015-02-08 04:57:00",19.3566666666667,31.5,0,434,0.00437573615907725,0 +"4988","2015-02-08 04:58:00",19.29,31.5,0,433,0.00435748190831888,0 +"4989","2015-02-08 04:59:00",19.29,31.5,0,433,0.00435748190831888,0 +"4990","2015-02-08 04:59:59",19.29,31.55,0,438.5,0.00436444707890572,0 +"4991","2015-02-08 05:00:59",19.29,31.6,0,440.333333333333,0.00437141240440136,0 +"4992","2015-02-08 05:02:00",19.29,31.6,0,437.333333333333,0.00437141240440136,0 +"4993","2015-02-08 05:03:00",19.29,31.6,0,436,0.00437141240440136,0 +"4994","2015-02-08 05:04:00",19.29,31.6,0,430,0.00437141240440136,0 +"4995","2015-02-08 05:05:00",19.29,31.6,0,431,0.00437141240440136,0 +"4996","2015-02-08 05:06:00",19.29,31.6,0,431.5,0.00437141240440136,0 +"4997","2015-02-08 05:06:59",19.2,31.5,0,434,0.00433294540706503,0 +"4998","2015-02-08 05:08:00",19.29,31.6333333333333,0,429.666666666667,0.00437605604079478,0 +"4999","2015-02-08 05:09:00",19.245,31.55,0,429.5,0.00435214375543047,0 +"5000","2015-02-08 05:10:00",19.245,31.65,0,430,0.004366035016828,0 +"5001","2015-02-08 05:10:59",19.2,31.6,0,430,0.00434679691769094,0 +"5002","2015-02-08 05:12:00",19.245,31.6,0,429,0.00435908930910986,0 +"5003","2015-02-08 05:12:59",19.2,31.6,0,435,0.00434679691769094,0 +"5004","2015-02-08 05:13:59",19.23,31.6333333333333,0,432,0.00435961450525212,0 +"5005","2015-02-08 05:15:00",19.245,31.65,0,435.5,0.004366035016828,0 +"5006","2015-02-08 05:16:00",19.245,31.7,0,434.5,0.00437298087859001,0 +"5007","2015-02-08 05:17:00",19.26,31.7,0,434,0.00437709833315715,0 +"5008","2015-02-08 05:18:00",19.29,31.7,0,435,0.00438534352013969,0 +"5009","2015-02-08 05:19:00",19.2,31.6,0,435,0.00434679691769094,0 +"5010","2015-02-08 05:19:59",19.29,31.7,0,436.5,0.00438534352013969,0 +"5011","2015-02-08 05:21:00",19.2,31.6,0,434.5,0.00434679691769094,0 +"5012","2015-02-08 05:22:00",19.29,31.7,0,432,0.00438534352013969,0 +"5013","2015-02-08 05:23:00",19.2,31.5333333333333,0,432.666666666667,0.00433756250920142,0 +"5014","2015-02-08 05:23:59",19.26,31.5666666666667,0,437,0.0043585588164274,0 +"5015","2015-02-08 05:25:00",19.245,31.6,0,435.5,0.00435908930910986,0 +"5016","2015-02-08 05:25:59",19.29,31.7,0,429.5,0.00438534352013969,0 +"5017","2015-02-08 05:26:59",19.29,31.7,0,430,0.00438534352013969,0 +"5018","2015-02-08 05:28:00",19.29,31.7,0,437,0.00438534352013969,0 +"5019","2015-02-08 05:29:00",19.29,31.7,0,438,0.00438534352013969,0 +"5020","2015-02-08 05:30:00",19.29,31.7,0,436.333333333333,0.00438534352013969,0 +"5021","2015-02-08 05:31:00",19.2,31.6,0,435,0.00434679691769094,0 +"5022","2015-02-08 05:31:59",19.29,31.6,0,433,0.00437141240440136,0 +"5023","2015-02-08 05:32:59",19.29,31.6,0,436.5,0.00437141240440136,0 +"5024","2015-02-08 05:34:00",19.245,31.55,0,439,0.00435214375543047,0 +"5025","2015-02-08 05:35:00",19.29,31.6,0,432,0.00437141240440136,0 +"5026","2015-02-08 05:36:00",19.29,31.5,0,434.5,0.00435748190831888,0 +"5027","2015-02-08 05:37:00",19.29,31.6,0,433.5,0.00437141240440136,0 +"5028","2015-02-08 05:38:00",19.29,31.55,0,434,0.00436444707890572,0 +"5029","2015-02-08 05:38:59",19.29,31.55,0,434,0.00436444707890572,0 +"5030","2015-02-08 05:39:59",19.29,31.5,0,435,0.00435748190831888,0 +"5031","2015-02-08 05:41:00",19.29,31.55,0,433.5,0.00436444707890572,0 +"5032","2015-02-08 05:42:00",19.29,31.5,0,428.5,0.00435748190831888,0 +"5033","2015-02-08 05:43:00",19.29,31.5,0,428.333333333333,0.00435748190831888,0 +"5034","2015-02-08 05:44:00",19.29,31.5,0,431,0.00435748190831888,0 +"5035","2015-02-08 05:44:59",19.29,31.5,0,435.5,0.00435748190831888,0 +"5036","2015-02-08 05:45:59",19.29,31.5,0,436.666666666667,0.00435748190831888,0 +"5037","2015-02-08 05:47:00",19.29,31.55,0,434,0.00436444707890572,0 +"5038","2015-02-08 05:48:00",19.34,31.6,0,432.5,0.00438514082400221,0 +"5039","2015-02-08 05:49:00",19.29,31.5,0,431.5,0.00435748190831888,0 +"5040","2015-02-08 05:50:00",19.29,31.5,0,437,0.00435748190831888,0 +"5041","2015-02-08 05:51:00",19.34,31.55,0,439.5,0.00437815347100645,0 +"5042","2015-02-08 05:51:59",19.29,31.5,0,436,0.00435748190831888,0 +"5043","2015-02-08 05:53:00",19.29,31.5,0,431.666666666667,0.00435748190831888,0 +"5044","2015-02-08 05:54:00",19.29,31.55,0,434.5,0.00436444707890572,0 +"5045","2015-02-08 05:55:00",19.29,31.55,0,435,0.00436444707890572,0 +"5046","2015-02-08 05:55:59",19.29,31.6,0,433.5,0.00437141240440136,0 +"5047","2015-02-08 05:57:00",19.29,31.6,0,435,0.00437141240440136,0 +"5048","2015-02-08 05:57:59",19.29,31.6,0,436,0.00437141240440136,0 +"5049","2015-02-08 05:58:59",19.29,31.6,0,433.333333333333,0.00437141240440136,0 +"5050","2015-02-08 06:00:00",19.29,31.55,0,436.5,0.00436444707890572,0 +"5051","2015-02-08 06:01:00",19.29,31.6,0,441,0.00437141240440136,0 +"5052","2015-02-08 06:02:00",19.29,31.6,0,436,0.00437141240440136,0 +"5053","2015-02-08 06:03:00",19.29,31.6,0,433,0.00437141240440136,0 +"5054","2015-02-08 06:04:00",19.2,31.6,0,432,0.00434679691769094,0 +"5055","2015-02-08 06:04:59",19.245,31.65,0,429,0.004366035016828,0 +"5056","2015-02-08 06:06:00",19.2,31.6,0,433,0.00434679691769094,0 +"5057","2015-02-08 06:07:00",19.23,31.6333333333333,0,434.333333333333,0.00435961450525212,0 +"5058","2015-02-08 06:08:00",19.29,31.7,0,432,0.00438534352013969,0 +"5059","2015-02-08 06:08:59",19.245,31.65,0,437.5,0.004366035016828,0 +"5060","2015-02-08 06:10:00",19.2,31.6,0,437.5,0.00434679691769094,0 +"5061","2015-02-08 06:10:59",19.245,31.65,0,437.5,0.004366035016828,0 +"5062","2015-02-08 06:11:59",19.29,31.7,0,438,0.00438534352013969,0 +"5063","2015-02-08 06:13:00",19.2,31.6,0,439.333333333333,0.00434679691769094,0 +"5064","2015-02-08 06:14:00",19.2,31.6,0,437.5,0.00434679691769094,0 +"5065","2015-02-08 06:15:00",19.29,31.7,0,433,0.00438534352013969,0 +"5066","2015-02-08 06:16:00",19.2,31.6,0,433,0.00434679691769094,0 +"5067","2015-02-08 06:16:59",19.245,31.7,0,431,0.00437298087859001,0 +"5068","2015-02-08 06:17:59",19.2,31.6,0,431,0.00434679691769094,0 +"5069","2015-02-08 06:19:00",19.2,31.7,0,433,0.00436064904098968,0 +"5070","2015-02-08 06:20:00",19.2,31.7,0,435,0.00436064904098968,0 +"5071","2015-02-08 06:21:00",19.2,31.7,0,431,0.00436064904098968,0 +"5072","2015-02-08 06:22:00",19.2,31.7,0,431.5,0.00436064904098968,0 +"5073","2015-02-08 06:23:00",19.2,31.7,0,427,0.00436064904098968,0 +"5074","2015-02-08 06:23:59",19.2,31.7,0,426,0.00436064904098968,0 +"5075","2015-02-08 06:24:59",19.2,31.7,0,435,0.00436064904098968,0 +"5076","2015-02-08 06:26:00",19.2225,31.7,0,434.25,0.00436681111345645,0 +"5077","2015-02-08 06:27:00",19.2,31.6,0,434,0.00434679691769094,0 +"5078","2015-02-08 06:28:00",19.245,31.65,0,435,0.004366035016828,0 +"5079","2015-02-08 06:29:00",19.2,31.55,0,434.5,0.00433987108579642,0 +"5080","2015-02-08 06:29:59",19.23,31.5666666666667,0,432,0.00435036243715725,0 +"5081","2015-02-08 06:30:59",19.2,31.5,0,432,0.00433294540706503,0 +"5082","2015-02-08 06:32:00",19.29,31.7,0,433,0.00438534352013969,0 +"5083","2015-02-08 06:33:00",19.26,31.6666666666667,0,437.333333333333,0.00437246335108502,0 +"5084","2015-02-08 06:34:00",19.2,31.5,0,437,0.00433294540706503,0 +"5085","2015-02-08 06:35:00",19.2,31.5,0,435,0.00433294540706503,0 +"5086","2015-02-08 06:36:00",19.245,31.5,0,431,0.00434519835578471,0 +"5087","2015-02-08 06:36:59",19.2,31.5,0,435,0.00433294540706503,0 +"5088","2015-02-08 06:38:00",19.2,31.5,0,431.5,0.00433294540706503,0 +"5089","2015-02-08 06:39:00",19.2,31.6,0,429.5,0.00434679691769094,0 +"5090","2015-02-08 06:40:00",19.2,31.5,0,435,0.00433294540706503,0 +"5091","2015-02-08 06:40:59",19.2,31.55,0,432,0.00433987108579642,0 +"5092","2015-02-08 06:42:00",19.2,31.6,0,428.666666666667,0.00434679691769094,0 +"5093","2015-02-08 06:42:59",19.2,31.55,0,432.5,0.00433987108579642,0 +"5094","2015-02-08 06:43:59",19.2,31.5,0,435,0.00433294540706503,0 +"5095","2015-02-08 06:45:00",19.29,31.6,0,441,0.00437141240440136,0 +"5096","2015-02-08 06:46:00",19.2,31.5,0,430.5,0.00433294540706503,0 +"5097","2015-02-08 06:47:00",19.2,31.5,0,430,0.00433294540706503,0 +"5098","2015-02-08 06:48:00",19.2,31.445,0,434,0.00432532733735785,0 +"5099","2015-02-08 06:49:00",19.2,31.39,0,436,0.00431770945296514,0 +"5100","2015-02-08 06:49:59",19.245,31.445,0,436.5,0.00433755859407709,0 +"5101","2015-02-08 06:51:00",19.2,31.5,0,433.5,0.00433294540706503,0 +"5102","2015-02-08 06:52:00",19.245,31.445,0,431,0.00433755859407709,0 +"5103","2015-02-08 06:53:00",19.26,31.4633333333333,0,428.333333333333,0.00434419144579513,0 +"5104","2015-02-08 06:53:59",19.26,31.4633333333333,0,431.666666666667,0.00434419144579513,0 +"5105","2015-02-08 06:55:00",19.2,31.39,0,435,0.00431770945296514,0 +"5106","2015-02-08 06:55:59",19.2,31.39,0,435,0.00431770945296514,0 +"5107","2015-02-08 06:56:59",19.2,31.39,0,434,0.00431770945296514,0 +"5108","2015-02-08 06:58:00",19.2,31.39,0,433.5,0.00431770945296514,0 +"5109","2015-02-08 06:59:00",19.2,31.39,0,432.5,0.00431770945296514,0 +"5110","2015-02-08 07:00:00",19.2,31.39,0,429,0.00431770945296514,0 +"5111","2015-02-08 07:01:00",19.2,31.39,0,436.333333333333,0.00431770945296514,0 +"5112","2015-02-08 07:01:59",19.2,31.39,0,432.333333333333,0.00431770945296514,0 +"5113","2015-02-08 07:02:59",19.2,31.39,0,429.333333333333,0.00431770945296514,0 +"5114","2015-02-08 07:04:00",19.2,31.39,0,423.5,0.00431770945296514,0 +"5115","2015-02-08 07:05:00",19.2,31.39,0,429,0.00431770945296514,0 +"5116","2015-02-08 07:06:00",19.1666666666667,31.39,0,428.666666666667,0.00430868495130474,0 +"5117","2015-02-08 07:07:00",19.2,31.39,0,432,0.00431770945296514,0 +"5118","2015-02-08 07:08:00",19.1666666666667,31.39,0,426.666666666667,0.00430868495130474,0 +"5119","2015-02-08 07:08:59",19.2,31.39,0,431,0.00431770945296514,0 +"5120","2015-02-08 07:09:59",19.1333333333333,31.39,0,433.333333333333,0.00429967711865158,0 +"5121","2015-02-08 07:11:00",19.2,31.39,0,437.5,0.00431770945296514,0 +"5122","2015-02-08 07:12:00",19.2,31.39,0,428,0.00431770945296514,0 +"5123","2015-02-08 07:13:00",19.15,31.39,0,432.5,0.00430417895302023,0 +"5124","2015-02-08 07:14:00",19.1,31.39,0,432,0.00429068592833222,0 +"5125","2015-02-08 07:14:59",19.1,31.39,0,436,0.00429068592833222,0 +"5126","2015-02-08 07:15:59",19.1,31.39,0,433,0.00429068592833222,0 +"5127","2015-02-08 07:17:00",19.1,31.445,0,435.5,0.00429825580697863,0 +"5128","2015-02-08 07:18:00",19.1,31.445,0,433,0.00429825580697863,0 +"5129","2015-02-08 07:19:00",19.1,31.445,0,430,0.00429825580697863,0 +"5130","2015-02-08 07:20:00",19.1,31.5,0,432,0.00430582586861916,0 +"5131","2015-02-08 07:21:00",19.1,31.39,0,439,0.00429068592833222,0 +"5132","2015-02-08 07:21:59",19.1,31.39,0,441,0.00429068592833222,0 +"5133","2015-02-08 07:23:00",19.1,31.39,0,442,0.00429068592833222,0 +"5134","2015-02-08 07:24:00",19.1,31.4633333333333,0,440.666666666667,0.0043007791405258,0 +"5135","2015-02-08 07:25:00",19.1,31.5,0,439,0.00430582586861916,0 +"5136","2015-02-08 07:25:59",19.1,31.5,0,435,0.00430582586861916,0 +"5137","2015-02-08 07:27:00",19.05,31.445,0,436,0.00428477626597972,0 +"5138","2015-02-08 07:27:59",19,31.39,0,437.5,0.00426381194518774,0 +"5139","2015-02-08 07:28:59",19,31.39,0,439,0.00426381194518774,0 +"5140","2015-02-08 07:30:00",19,31.39,0,440.5,0.00426381194518774,0 +"5141","2015-02-08 07:31:00",19,31.3566666666667,0,435.333333333333,0.00425925315880258,0 +"5142","2015-02-08 07:32:00",19,31.39,0,432,0.00426381194518774,0 +"5143","2015-02-08 07:33:00",19.1,31.39,0,434,0.00429068592833222,0 +"5144","2015-02-08 07:34:00",19.1,31.29,0,431,0.00427692298141774,0 +"5145","2015-02-08 07:34:59",19.1,31.29,0,436,0.00427692298141774,0 +"5146","2015-02-08 07:36:00",19.1,31.245,0,435.5,0.00427072985264986,0 +"5147","2015-02-08 07:37:00",19.1333333333333,31.2,0,433.666666666667,0.00427347286703399,0 +"5148","2015-02-08 07:38:00",19.15,31.2,0,428.5,0.00427794707770588,0 +"5149","2015-02-08 07:38:59",19.1333333333333,31.2,0,430,0.00427347286703399,0 +"5150","2015-02-08 07:40:00",19.1666666666667,31.2,0,429.666666666667,0.0042824254263509,0 +"5151","2015-02-08 07:40:59",19.2,31.2,0,431.666666666667,0.00429139455081785,0 +"5152","2015-02-08 07:41:59",19.2,31.2,0,431,0.00429139455081785,0 +"5153","2015-02-08 07:43:00",19.2,31.2,0,431.5,0.00429139455081785,0 +"5154","2015-02-08 07:44:00",19.2,31.2,0,435.5,0.00429139455081785,0 +"5155","2015-02-08 07:45:00",19.2,31.1333333333333,0,433,0.00428216177586966,0 +"5156","2015-02-08 07:46:00",19.2,31.1,0,430,0.00427754549047685,0 +"5157","2015-02-08 07:46:59",19.2,31.1,0,432,0.00427754549047685,0 +"5158","2015-02-08 07:47:59",19.2,31.1,0,431,0.00427754549047685,0 +"5159","2015-02-08 07:49:00",19.29,31.2,0,434,0.0043156941375931,0 +"5160","2015-02-08 07:50:00",19.245,31.15,0,431,0.00429658487077552,0 +"5161","2015-02-08 07:51:00",19.2,31.1,0,430.5,0.00427754549047685,0 +"5162","2015-02-08 07:52:00",19.2,31.1,0,429,0.00427754549047685,0 +"5163","2015-02-08 07:53:00",19.245,31.15,0,427.5,0.00429658487077552,0 +"5164","2015-02-08 07:53:59",19.2,31.1,0,429.5,0.00427754549047685,0 +"5165","2015-02-08 07:54:59",19.2,31.1,0,436,0.00427754549047685,0 +"5166","2015-02-08 07:56:00",19.2,31.1,0,435.5,0.00427754549047685,0 +"5167","2015-02-08 07:57:00",19.26,31.1666666666667,0,436.666666666667,0.00430294685044752,0 +"5168","2015-02-08 07:58:00",19.29,31.2,0,437,0.0043156941375931,0 +"5169","2015-02-08 07:59:00",19.23,31.1333333333333,0,432,0.0042902306562674,0 +"5170","2015-02-08 07:59:59",19.2,31,0,432,0.00426369704260547,0 +"5171","2015-02-08 08:00:59",19.245,31.1,0,431,0.00428964070321433,0 +"5172","2015-02-08 08:02:00",19.245,31.05,0,432,0.00428269668964065,0 +"5173","2015-02-08 08:03:00",19.26,31.1,0,442,0.00429367914952019,0 +"5174","2015-02-08 08:04:00",19.29,31.1,0,441,0.00430176611972061,0 +"5175","2015-02-08 08:05:00",19.2,31.05,0,438,0.00427062118998499,0 +"5176","2015-02-08 08:06:00",19.23,31.1,0,437.666666666667,0.00428560561288179,0 +"5177","2015-02-08 08:06:59",19.2,31.05,0,436,0.00427062118998499,0 +"5178","2015-02-08 08:08:00",19.2,31.05,0,436.5,0.00427062118998499,0 +"5179","2015-02-08 08:09:00",19.2,31.1,0,437,0.00427754549047685,0 +"5180","2015-02-08 08:10:00",19.29,31.2,0,433,0.0043156941375931,0 +"5181","2015-02-08 08:10:59",19.23,31.1,0,433.333333333333,0.00428560561288179,0 +"5182","2015-02-08 08:12:00",19.245,31.05,0,432,0.00428269668964065,0 +"5183","2015-02-08 08:12:59",19.245,31.1,0,437,0.00428964070321433,0 +"5184","2015-02-08 08:13:59",19.245,31.1,7,438.5,0.00428964070321433,0 +"5185","2015-02-08 08:15:00",19.26,31.1666666666667,14,436.666666666667,0.00430294685044752,0 +"5186","2015-02-08 08:16:00",19.2675,31.175,14,435.5,0.00430613075474336,0 +"5187","2015-02-08 08:17:00",19.26,31.1,14,434,0.00429367914952019,0 +"5188","2015-02-08 08:18:00",19.245,31.15,14,436.75,0.00429658487077552,0 +"5189","2015-02-08 08:19:00",19.2225,31.125,14,430.5,0.00428705645842815,0 +"5190","2015-02-08 08:19:59",19.2675,31.175,14,427,0.00430613075474336,0 +"5191","2015-02-08 08:21:00",19.23,31.1333333333333,14,430.666666666667,0.0042902306562674,0 +"5192","2015-02-08 08:22:00",19.245,31.15,14,437.25,0.00429658487077552,0 +"5193","2015-02-08 08:23:00",19.29,31.2,14,438,0.0043156941375931,0 +"5194","2015-02-08 08:23:59",19.2225,31.1,14,432.5,0.00428358932545068,0 +"5195","2015-02-08 08:25:00",19.23,31.1333333333333,14,428,0.0042902306562674,0 +"5196","2015-02-08 08:25:59",19.2675,31.175,7,429,0.00430613075474336,0 +"5197","2015-02-08 08:26:59",19.23,31.1333333333333,9.33333333333333,434,0.0042902306562674,0 +"5198","2015-02-08 08:28:00",19.245,31.175,8.5,434,0.00430005701230304,0 +"5199","2015-02-08 08:29:00",19.2225,31.15,10,435.5,0.00429052362979423,0 +"5200","2015-02-08 08:30:00",19.245,31.15,17,439,0.00429658487077552,0 +"5201","2015-02-08 08:31:00",19.23,31.1333333333333,20.6666666666667,439,0.0042902306562674,0 +"5202","2015-02-08 08:31:59",19.2225,31.125,11.5,430.5,0.00428705645842815,0 +"5203","2015-02-08 08:32:59",19.245,31.15,6,424.5,0.00429658487077552,0 +"5204","2015-02-08 08:34:00",19.2,31.1,6,428.666666666667,0.00427754549047685,0 +"5205","2015-02-08 08:35:00",19.2225,31.125,9.6,432,0.00428705645842815,0 +"5206","2015-02-08 08:36:00",19.245,31.15,10.5,429.2,0.00429658487077552,0 +"5207","2015-02-08 08:37:00",19.245,31.15,6,430.333333333333,0.00429658487077552,0 +"5208","2015-02-08 08:38:00",19.2,31.1,6,431.8,0.00427754549047685,0 +"5209","2015-02-08 08:38:59",19.2,31.1,6,431.333333333333,0.00427754549047685,0 +"5210","2015-02-08 08:39:59",19.2,31.1,6,431.5,0.00427754549047685,0 +"5211","2015-02-08 08:41:00",19.2,31.125,6.5,433.5,0.00428100769814148,0 +"5212","2015-02-08 08:42:00",19.23,31.1666666666667,9.33333333333333,433,0.00429485576796428,0 +"5213","2015-02-08 08:43:00",19.2,31.1333333333333,9.33333333333333,430,0.00428216177586966,0 +"5214","2015-02-08 08:44:00",19.2,31.125,7,432.5,0.00428100769814148,0 +"5215","2015-02-08 08:44:59",19.2,31.175,14,434.5,0.00428793222831135,0 +"5216","2015-02-08 08:45:59",19.2,31.1,14,439.5,0.00427754549047685,0 +"5217","2015-02-08 08:47:00",19.2,31.1,14,438.666666666667,0.00427754549047685,0 +"5218","2015-02-08 08:48:00",19.2,31.1,14,432,0.00427754549047685,0 +"5219","2015-02-08 08:49:00",19.2,31.125,14,439,0.00428100769814148,0 +"5220","2015-02-08 08:50:00",19.2,31.1333333333333,14,438.333333333333,0.00428216177586966,0 +"5221","2015-02-08 08:51:00",19.2,31.1666666666667,14,437,0.00428677812931616,0 +"5222","2015-02-08 08:51:59",19.2,31.2,14,435.75,0.00429139455081785,0 +"5223","2015-02-08 08:53:00",19.2,31.1333333333333,14,437.333333333333,0.00428216177586966,0 +"5224","2015-02-08 08:54:00",19.2225,31.175,14,439.5,0.00429399083954956,0 +"5225","2015-02-08 08:55:00",19.2,31.2,14,431,0.00429139455081785,0 +"5226","2015-02-08 08:55:59",19.23,31.2,9.33333333333333,433.333333333333,0.00429948094797394,0 +"5227","2015-02-08 08:57:00",19.2225,31.15,12,442.25,0.00429052362979423,0 +"5228","2015-02-08 08:57:59",19.23,31.1333333333333,12,435.666666666667,0.0042902306562674,0 +"5229","2015-02-08 08:58:59",19.2225,31.2,18.5,431.5,0.00429745808769477,0 +"5230","2015-02-08 09:00:00",19.26,31.2,29,430.666666666667,0.00430758080376737,0 +"5231","2015-02-08 09:01:00",19.245,31.15,36,428.75,0.00429658487077552,0 +"5232","2015-02-08 09:02:00",19.2675,31.175,30.5,430.75,0.00430613075474336,0 +"5233","2015-02-08 09:03:00",19.2675,31.15,40,437.25,0.00430265367519454,0 +"5234","2015-02-08 09:04:00",19.26,31.1666666666667,46,438,0.00430294685044752,0 +"5235","2015-02-08 09:04:59",19.29,31.1,35,434.5,0.00430176611972061,0 +"5236","2015-02-08 09:06:00",19.26,31.0666666666667,25,435,0.00428904540190969,0 +"5237","2015-02-08 09:07:00",19.29,31.05,32.25,435.25,0.00429480234308039,0 +"5238","2015-02-08 09:08:00",19.29,31.1,28.75,437.75,0.00430176611972061,0 +"5239","2015-02-08 09:08:59",19.29,31.1,19.5,435,0.00430176611972061,0 +"5240","2015-02-08 09:10:00",19.29,31.0666666666667,6,438.333333333333,0.00429712358475386,0 +"5241","2015-02-08 09:10:59",19.29,31.075,6,437.5,0.00429828421204303,0 +"5242","2015-02-08 09:11:59",19.29,31,6,436.5,0.00428783872129729,0 +"5243","2015-02-08 09:13:00",19.29,31,11.5,439,0.00428783872129729,0 +"5244","2015-02-08 09:14:00",19.29,31.1,10,440,0.00430176611972061,0 +"5245","2015-02-08 09:15:00",19.29,31.0666666666667,9.33333333333333,437.666666666667,0.00429712358475386,0 +"5246","2015-02-08 09:16:00",19.29,31,7,432.75,0.00428783872129729,0 +"5247","2015-02-08 09:16:59",19.29,31,7,435,0.00428783872129729,0 +"5248","2015-02-08 09:17:59",19.2675,31,13.5,436.5,0.00428179200863381,0 +"5249","2015-02-08 09:19:00",19.29,31,20.6666666666667,436.333333333333,0.00428783872129729,0 +"5250","2015-02-08 09:20:00",19.29,31,17,433,0.00428783872129729,0 +"5251","2015-02-08 09:21:00",19.2675,31,17,428.75,0.00428179200863381,0 +"5252","2015-02-08 09:22:00",19.29,31,6,430,0.00428783872129729,0 +"5253","2015-02-08 09:23:00",19.29,31,6,430.333333333333,0.00428783872129729,0 +"5254","2015-02-08 09:23:59",19.272,30.978,24,436.5,0.00427994028432957,0 +"5255","2015-02-08 09:24:59",19.29,30.9725,22.8,434.6,0.00428400879532256,0 +"5256","2015-02-08 09:26:00",19.29,30.945,13,430,0.0042801789161897,0 +"5257","2015-02-08 09:27:00",19.245,30.945,28,427.75,0.00426811476234251,0 +"5258","2015-02-08 09:28:00",19.29,31,29.3333333333333,431,0.00428783872129729,0 +"5259","2015-02-08 09:29:00",19.29,30.9175,30.75,434,0.00427634908389783,0 +"5260","2015-02-08 09:29:59",19.29,30.89,36,435.25,0.0042725192984461,0 +"5261","2015-02-08 09:30:59",19.29,30.89,75.5,435,0.0042725192984461,0 +"5262","2015-02-08 09:32:00",19.29,30.89,97,432,0.0042725192984461,0 +"5263","2015-02-08 09:33:00",19.29,30.89,147.5,439.75,0.0042725192984461,0 +"5264","2015-02-08 09:34:00",19.29,30.865,166,437.75,0.00426903771595385,0 +"5265","2015-02-08 09:35:00",19.34,30.79,149,433.5,0.004271964895202,0 +"5266","2015-02-08 09:36:00",19.39,30.7,146,428.75,0.00427276135377004,0 +"5267","2015-02-08 09:36:59",19.39,30.65,167.5,428.5,0.00426575473407625,0 +"5268","2015-02-08 09:38:00",19.445,30.625,118.25,430.5,0.00427696369649641,0 +"5269","2015-02-08 09:39:00",19.5,30.6,42.25,430.75,0.00428819314894537,0 +"5270","2015-02-08 09:40:00",19.4266666666667,30.5333333333333,37,426.666666666667,0.00425917998642283,0 +"5271","2015-02-08 09:40:59",19.4725,30.575,34.25,424.75,0.00427729367356571,0 +"5272","2015-02-08 09:42:00",19.4633333333333,30.5666666666667,26,428.666666666667,0.0042736657299121,0 +"5273","2015-02-08 09:42:59",19.4633333333333,30.5666666666667,43,429.333333333333,0.0042736657299121,0 +"5274","2015-02-08 09:43:59",19.434,30.56,28,429,0.00426488408609693,0 +"5275","2015-02-08 09:45:00",19.39,30.5333333333333,29.25,429,0.00424940656446485,0 +"5276","2015-02-08 09:46:00",19.39,30.525,25.5,427,0.00424823887072387,0 +"5277","2015-02-08 09:47:00",19.412,30.6,16.6,428.25,0.00426462291818162,0 +"5278","2015-02-08 09:48:00",19.39,30.6,31,428.75,0.00425874827115814,0 +"5279","2015-02-08 09:49:00",19.39,30.6,20.3333333333333,438,0.00425874827115814,0 +"5280","2015-02-08 09:49:59",19.39,30.575,14,426.5,0.00425524509848832,0 +"5281","2015-02-08 09:51:00",19.4175,30.6,14,430.25,0.00426609269787983,0 +"5282","2015-02-08 09:52:00",19.39,30.6,24,435,0.00425874827115814,0 +"5283","2015-02-08 09:53:00",19.39,30.5666666666667,24,433,0.0042540773829744,0 +"5284","2015-02-08 09:53:59",19.39,30.55,24,430,0.00425174196501045,0 +"5285","2015-02-08 09:55:00",19.39,30.6,24,431,0.00425874827115814,0 +"5286","2015-02-08 09:55:59",19.39,30.6,24,431,0.00425874827115814,0 +"5287","2015-02-08 09:56:59",19.365,30.6,24,427,0.00425208121346694,0 +"5288","2015-02-08 09:58:00",19.39,30.6,24,430,0.00425874827115814,0 +"5289","2015-02-08 09:59:00",19.39,30.6,19,428,0.00425874827115814,0 +"5290","2015-02-08 10:00:00",19.3566666666667,30.6,31,432,0.00424986091052405,0 +"5291","2015-02-08 10:01:00",19.39,30.575,13,431.5,0.00425524509848832,0 +"5292","2015-02-08 10:01:59",19.34,30.55,13,432,0.00423843914036198,0 +"5293","2015-02-08 10:02:59",19.39,30.5,26.5,434,0.00424473581562793,0 +"5294","2015-02-08 10:04:00",19.39,30.5,26.5,433.75,0.00424473581562793,0 +"5295","2015-02-08 10:05:00",19.39,30.5,26.5,429,0.00424473581562793,0 +"5296","2015-02-08 10:06:00",19.365,30.6,26.5,431.75,0.00425208121346694,0 +"5297","2015-02-08 10:07:00",19.3233333333333,30.6,17.3333333333333,431.666666666667,0.00424098993594787,0 +"5298","2015-02-08 10:08:00",19.29,30.6,24,428.75,0.00423213532126926,0 +"5299","2015-02-08 10:08:59",19.35,30.58,24,426.25,0.00424528992873563,0 +"5300","2015-02-08 10:09:59",19.3233333333333,30.6,24,425,0.00424098993594787,0 +"5301","2015-02-08 10:11:00",19.315,30.55,24,426.5,0.00423180152501532,0 +"5302","2015-02-08 10:12:00",19.315,30.575,24,428,0.00423528811787515,0 +"5303","2015-02-08 10:13:00",19.29,30.6,24,429,0.00423213532126926,0 +"5304","2015-02-08 10:14:00",19.29,30.6,17.3333333333333,430,0.00423213532126926,0 +"5305","2015-02-08 10:14:59",19.315,30.6,14,441,0.00423877474955894,0 +"5306","2015-02-08 10:15:59",19.29,30.6333333333333,17.3333333333333,441,0.0042367768928091,0 +"5307","2015-02-08 10:17:00",19.315,30.6,18.5,432.25,0.00423877474955894,0 +"5308","2015-02-08 10:18:00",19.29,30.6,17.3333333333333,435,0.00423213532126926,0 +"5309","2015-02-08 10:19:00",19.29,30.6,19,429.5,0.00423213532126926,0 +"5310","2015-02-08 10:20:00",19.34,30.6,24,430,0.00424542337661458,0 +"5311","2015-02-08 10:21:00",19.29,30.6,24,431.5,0.00423213532126926,0 +"5312","2015-02-08 10:21:59",19.315,30.6,24,430,0.00423877474955894,0 +"5313","2015-02-08 10:23:00",19.29,30.6,24,427.333333333333,0.00423213532126926,0 +"5314","2015-02-08 10:24:00",19.29,30.6,24,425,0.00423213532126926,0 +"5315","2015-02-08 10:25:00",19.29,30.5,24,431,0.00421821101947199,0 +"5316","2015-02-08 10:25:59",19.29,30.5,24,432.75,0.00421821101947199,0 +"5317","2015-02-08 10:27:00",19.3566666666667,30.6,24,426.666666666667,0.00424986091052405,0 +"5318","2015-02-08 10:27:59",19.29,30.5,24,429.333333333333,0.00421821101947199,0 +"5319","2015-02-08 10:28:59",19.29,30.56,24,429.5,0.00422656552624355,0 +"5320","2015-02-08 10:30:00",19.29,30.525,24,428.4,0.00422169203686957,0 +"5321","2015-02-08 10:31:00",19.29,30.5333333333333,24,427.666666666667,0.00422285238460223,0 +"5322","2015-02-08 10:32:00",19.29,30.5,24,428,0.00421821101947199,0 +"5323","2015-02-08 10:33:00",19.29,30.5,12,430.666666666667,0.00421821101947199,0 +"5324","2015-02-08 10:34:00",19.29,30.5666666666667,6,428.666666666667,0.00422749381853414,0 +"5325","2015-02-08 10:34:59",19.29,30.55,6,435.5,0.00422517309296788,0 +"5326","2015-02-08 10:36:00",19.29,30.575,6,435.75,0.00422865418776756,0 +"5327","2015-02-08 10:37:00",19.29,30.6,6,437,0.00423213532126926,0 +"5328","2015-02-08 10:38:00",19.29,30.6,6,437.5,0.00423213532126926,0 +"5329","2015-02-08 10:38:59",19.2675,30.55,6,438.75,0.00421921534675402,0 +"5330","2015-02-08 10:40:00",19.29,30.5333333333333,6,435,0.00422285238460223,0 +"5331","2015-02-08 10:40:59",19.245,30.55,24,437.5,0.00421326502209067,0 +"5332","2015-02-08 10:41:59",19.23,30.5333333333333,24,435,0.0042069903254854,0 +"5333","2015-02-08 10:43:00",19.245,30.55,24,435,0.00421326502209067,0 +"5334","2015-02-08 10:44:00",19.2675,30.575,14,436.5,0.00422269149990349,0 +"5335","2015-02-08 10:45:00",19.23,30.5333333333333,17.3333333333333,433,0.0042069903254854,0 +"5336","2015-02-08 10:46:00",19.245,30.55,22.5,433,0.00421326502209067,0 +"5337","2015-02-08 10:46:59",19.2675,30.525,26.5,430,0.00421573923219649,0 +"5338","2015-02-08 10:47:59",19.245,30.525,19.75,428.25,0.0042097938428251,0 +"5339","2015-02-08 10:49:00",19.26,30.5666666666667,13,433.333333333333,0.00421954741490875,0 +"5340","2015-02-08 10:50:00",19.245,30.525,19.75,435.25,0.0042097938428251,0 +"5341","2015-02-08 10:51:00",19.26,30.5666666666667,31,433.333333333333,0.00421954741490875,0 +"5342","2015-02-08 10:52:00",19.2675,30.575,26.5,428.25,0.00422269149990349,0 +"5343","2015-02-08 10:53:00",19.23,30.5,31,430.666666666667,0.00420236651144401,0 +"5344","2015-02-08 10:53:59",19.2225,30.5,26.5,428,0.00420038964891632,0 +"5345","2015-02-08 10:54:59",19.26,30.5666666666667,22,423,0.00421954741490875,0 +"5346","2015-02-08 10:56:00",19.2225,30.525,26.5,433.5,0.00420385586075843,0 +"5347","2015-02-08 10:57:00",19.23,30.5333333333333,31,437.666666666667,0.0042069903254854,0 +"5348","2015-02-08 10:58:00",19.23,30.5333333333333,31,433.666666666667,0.0042069903254854,0 +"5349","2015-02-08 10:59:00",19.245,30.55,19.75,432.75,0.00421326502209067,0 +"5350","2015-02-08 10:59:59",19.245,30.55,19.75,433,0.00421326502209067,0 +"5351","2015-02-08 11:00:59",19.23,30.5333333333333,31,433,0.0042069903254854,0 +"5352","2015-02-08 11:02:00",19.23,30.5333333333333,31,432.666666666667,0.0042069903254854,0 +"5353","2015-02-08 11:03:00",19.2225,30.525,26.5,427,0.00420385586075843,0 +"5354","2015-02-08 11:04:00",19.245,30.6,20.25,427.75,0.00422020749607083,0 +"5355","2015-02-08 11:05:00",19.245,30.55,14,429.5,0.00421326502209067,0 +"5356","2015-02-08 11:06:00",19.245,30.55,19,430.25,0.00421326502209067,0 +"5357","2015-02-08 11:06:59",19.23,30.5333333333333,24,432,0.0042069903254854,0 +"5358","2015-02-08 11:08:00",19.2225,30.575,15,434.25,0.00421078839956323,0 +"5359","2015-02-08 11:09:00",19.23,30.6333333333333,6,430,0.00422086217731987,0 +"5360","2015-02-08 11:10:00",19.245,30.575,6,430.25,0.00421673623983903,0 +"5361","2015-02-08 11:10:59",19.245,30.55,6,437,0.00421326502209067,0 +"5362","2015-02-08 11:12:00",19.245,30.6,17,435,0.00422020749607083,0 +"5363","2015-02-08 11:12:59",19.2,30.6,17,430.75,0.00420830937500383,0 +"5364","2015-02-08 11:13:59",19.2,30.6,13.5,431,0.00420830937500383,0 +"5365","2015-02-08 11:15:00",19.2,30.625,7,435.5,0.00421177081720203,0 +"5366","2015-02-08 11:16:00",19.2,30.6666666666667,16,428.666666666667,0.00421753997257109,0 +"5367","2015-02-08 11:17:00",19.2,30.7,10.5,427,0.00422215537340291,0 +"5368","2015-02-08 11:18:00",19.2,30.7,25.25,429,0.00422215537340291,0 +"5369","2015-02-08 11:19:00",19.1333333333333,30.73,25,431.333333333333,0.00420866124356053,0 +"5370","2015-02-08 11:19:59",19.15,30.7675,22,429.5,0.0042182432388776,0 +"5371","2015-02-08 11:21:00",19.1,30.79,22,430,0.00420811731920908,0 +"5372","2015-02-08 11:22:00",19.1333333333333,30.89,31,425,0.00423072326889308,0 +"5373","2015-02-08 11:23:00",19.1,30.89,18.5,424,0.00422187724213521,0 +"5374","2015-02-08 11:23:59",19.1,30.89,18.5,425.5,0.00422187724213521,0 +"5375","2015-02-08 11:25:00",19.1,30.89,17.3333333333333,426,0.00422187724213521,0 +"5376","2015-02-08 11:25:59",19.1,30.89,14,426.5,0.00422187724213521,0 +"5377","2015-02-08 11:26:59",19.1,30.89,14,429.25,0.00422187724213521,0 +"5378","2015-02-08 11:28:00",19.1,30.89,17.3333333333333,431.666666666667,0.00422187724213521,0 +"5379","2015-02-08 11:29:00",19.1,30.89,19.75,433.5,0.00422187724213521,0 +"5380","2015-02-08 11:30:00",19.1,30.89,13,435.5,0.00422187724213521,0 +"5381","2015-02-08 11:31:00",19.1,30.89,13,436.333333333333,0.00422187724213521,0 +"5382","2015-02-08 11:31:59",19.1,30.89,22.5,432.5,0.00422187724213521,0 +"5383","2015-02-08 11:32:59",19.1,30.89,24,433,0.00422187724213521,0 +"5384","2015-02-08 11:34:00",19.1,30.89,24,432.75,0.00422187724213521,0 +"5385","2015-02-08 11:35:00",19.1,30.89,6,434,0.00422187724213521,0 +"5386","2015-02-08 11:36:00",19.1,30.89,6,434.333333333333,0.00422187724213521,0 +"5387","2015-02-08 11:37:00",19.1,30.89,13.5,433,0.00422187724213521,0 +"5388","2015-02-08 11:38:00",19.1,30.89,9.33333333333333,430.333333333333,0.00422187724213521,0 +"5389","2015-02-08 11:38:59",19.1,30.9175,12,433,0.00422566132695282,0 +"5390","2015-02-08 11:39:59",19.1,31,15,437,0.00423701385580471,0 +"5391","2015-02-08 11:41:00",19.1,31,18.5,435,0.00423701385580471,0 +"5392","2015-02-08 11:42:00",19.05,31.05,26.5,431,0.00423058646733672,0 +"5393","2015-02-08 11:43:00",19.1,31.0333333333333,31,432,0.00424160085290026,0 +"5394","2015-02-08 11:44:00",19.1,31,26.5,434.25,0.00423701385580471,0 +"5395","2015-02-08 11:44:59",19.1,31,31,435,0.00423701385580471,0 +"5396","2015-02-08 11:45:59",19.1,31,16.25,436,0.00423701385580471,0 +"5397","2015-02-08 11:47:00",19.1,31,24,435.5,0.00423701385580471,0 +"5398","2015-02-08 11:48:00",19.1,31,24,432.25,0.00423701385580471,0 +"5399","2015-02-08 11:49:00",19.1,31,24,435.5,0.00423701385580471,0 +"5400","2015-02-08 11:50:00",19.1,31,17.3333333333333,434.333333333333,0.00423701385580471,0 +"5401","2015-02-08 11:51:00",19.1,31,18.5,432,0.00423701385580471,0 +"5402","2015-02-08 11:51:59",19.1,31,22.5,432,0.00423701385580471,0 +"5403","2015-02-08 11:53:00",19.1,30.9266666666667,31,433,0.00422692269872146,0 +"5404","2015-02-08 11:54:00",19.15,30.89,13,432.5,0.00423515241921811,0 +"5405","2015-02-08 11:55:00",19.175,30.89,13,429.5,0.00424180382510226,0 +"5406","2015-02-08 11:55:59",19.2,30.84,31,427.5,0.00424154079984671,0 +"5407","2015-02-08 11:57:00",19.2,30.865,31,428.75,0.00424500260943712,0 +"5408","2015-02-08 11:57:59",19.2,30.79,25,428.333333333333,0.00423461729548353,0 +"5409","2015-02-08 11:58:59",19.2,30.79,39.3333333333333,425.666666666667,0.00423461729548353,0 +"5410","2015-02-08 12:00:00",19.2,30.79,53,421.5,0.00423461729548353,0 +"5411","2015-02-08 12:01:00",19.2,30.79,65.6666666666667,423.333333333333,0.00423461729548353,0 +"5412","2015-02-08 12:02:00",19.245,30.7675,67.25,426.75,0.00424346590555203,0 +"5413","2015-02-08 12:03:00",19.245,30.745,116.75,424.25,0.00424034154114147,0 +"5414","2015-02-08 12:04:00",19.29,30.745,112.5,425,0.00425232665881594,0 +"5415","2015-02-08 12:04:59",19.29,30.7675,201.5,431,0.00425545991409741,0 +"5416","2015-02-08 12:06:00",19.29,30.7,102.666666666667,435,0.00424606024230911,0 +"5417","2015-02-08 12:07:00",19.315,30.7,85.75,431.25,0.00425272166454662,0 +"5418","2015-02-08 12:08:00",19.29,30.7,81,431.333333333333,0.00424606024230911,0 +"5419","2015-02-08 12:08:59",19.365,30.675,81.5,435.75,0.00426257440166169,0 +"5420","2015-02-08 12:10:00",19.39,30.6333333333333,93.6666666666667,434.333333333333,0.00426341922901762,0 +"5421","2015-02-08 12:10:59",19.39,30.6,106,431,0.00425874827115814,0 +"5422","2015-02-08 12:11:59",19.39,30.5333333333333,74,432.666666666667,0.00424940656446485,0 +"5423","2015-02-08 12:13:00",19.39,30.5,79.5,428.75,0.00424473581562793,0 +"5424","2015-02-08 12:14:00",19.39,30.5,110,430,0.00424473581562793,0 +"5425","2015-02-08 12:15:00",19.39,30.5,150.25,427,0.00424473581562793,0 +"5426","2015-02-08 12:16:00",19.39,30.5,66.6666666666667,428,0.00424473581562793,0 +"5427","2015-02-08 12:16:59",19.39,30.5,62.5,427.25,0.00424473581562793,0 +"5428","2015-02-08 12:17:59",19.4266666666667,30.5,54,428,0.0042544984221175,0 +"5429","2015-02-08 12:19:00",19.4175,30.4725,47,429,0.00424819590758226,0 +"5430","2015-02-08 12:20:00",19.4725,30.5,62,423.5,0.00426672956580133,0 +"5431","2015-02-08 12:21:00",19.4175,30.4175,255,425.666666666667,0.00424047603931713,0 +"5432","2015-02-08 12:22:00",19.5,30.4266666666667,317.25,428.75,0.00426373622229767,0 +"5433","2015-02-08 12:23:00",19.525,30.34,233,429.5,0.00425816766306139,0 +"5434","2015-02-08 12:23:59",19.6,30.245,277.5,432.75,0.00426471287018958,0 +"5435","2015-02-08 12:24:59",19.675,30.2,88.5,428.75,0.00427834614621145,0 +"5436","2015-02-08 12:26:00",19.7,30.2,72.75,425.5,0.004285038585908,0 +"5437","2015-02-08 12:27:00",19.65,30.15,68,424,0.00426454216078906,0 +"5438","2015-02-08 12:28:00",19.625,30.125,57.25,426.75,0.00425432464846632,0 +"5439","2015-02-08 12:29:00",19.6666666666667,30.1666666666667,63.6666666666667,427,0.00427136519749302,0 +"5440","2015-02-08 12:29:59",19.65,30.15,50,427,0.00426454216078906,0 +"5441","2015-02-08 12:30:59",19.625,30.125,54.5,426.25,0.00425432464846632,0 +"5442","2015-02-08 12:32:00",19.65,30.15,68,427.5,0.00426454216078906,0 +"5443","2015-02-08 12:33:00",19.7,30.2,71.5,434,0.004285038585908,0 +"5444","2015-02-08 12:34:00",19.625,30.125,69.75,428.25,0.00425432464846632,0 +"5445","2015-02-08 12:35:00",19.6333333333333,30.1333333333333,84.6666666666667,428.666666666667,0.00425772821526826,0 +"5446","2015-02-08 12:36:00",19.65,30.15,81.5,427.5,0.00426454216078906,0 +"5447","2015-02-08 12:36:59",19.7,30.15,90.5,422,0.00427789535815756,0 +"5448","2015-02-08 12:38:00",19.6,30.1,99.75,422.5,0.00424412755638058,0 +"5449","2015-02-08 12:39:00",19.6333333333333,30.1,226,423,0.00425298613468152,0 +"5450","2015-02-08 12:40:00",19.7,30.1,161.25,422.25,0.00427075229335247,0 +"5451","2015-02-08 12:40:59",19.7,30.1,178.666666666667,425,0.00427075229335247,0 +"5452","2015-02-08 12:42:00",19.7225,30,241,428.25,0.0042624572633588,0 +"5453","2015-02-08 12:42:59",19.79,30,214.75,425,0.00428047379453288,0 +"5454","2015-02-08 12:43:59",19.79,29.9175,293.5,425.5,0.00426862170825508,0 +"5455","2015-02-08 12:45:00",19.89,29.84,290.5,426,0.00428415813705438,0 +"5456","2015-02-08 12:46:00",19.9266666666667,29.79,290.666666666667,424.333333333333,0.00428672937885196,0 +"5457","2015-02-08 12:47:00",20,29.7225,288.5,425.75,0.0042965620985378,0 +"5458","2015-02-08 12:48:00",20.025,29.65,295.5,425.5,0.00429269725747901,0 +"5459","2015-02-08 12:49:00",20.0333333333333,29.6,194,429.333333333333,0.00428763589091257,0 +"5460","2015-02-08 12:49:59",20.125,29.575,261.75,426,0.00430853818727102,0 +"5461","2015-02-08 12:51:00",20.1333333333333,29.5,243.333333333333,430,0.00429976864365105,0 +"5462","2015-02-08 12:52:00",20.125,29.445,247.5,427,0.00428946895230924,0 +"5463","2015-02-08 12:53:00",20.2,29.39,256,430.5,0.00430145106790789,0 +"5464","2015-02-08 12:53:59",20.2,29.365,192.75,426.75,0.00429776684509052,0 +"5465","2015-02-08 12:55:00",20.245,29.365,252.5,425,0.00430982589706669,0 +"5466","2015-02-08 12:55:59",20.23,29.3233333333333,287.666666666667,428.666666666667,0.00429965106296165,0 +"5467","2015-02-08 12:56:59",20.29,29.315,279.75,429,0.00431450481144828,0 +"5468","2015-02-08 12:58:00",20.29,29.23,253.333333333333,427.666666666667,0.0043019082115549,0 +"5469","2015-02-08 12:59:00",20.34,29.2,273,427.5,0.00431085298677028,0 +"5470","2015-02-08 13:00:00",20.39,29.2,272,427.333333333333,0.00432428032125835,0 +"5471","2015-02-08 13:01:00",20.39,29.2,273.333333333333,429,0.00432428032125835,0 +"5472","2015-02-08 13:01:59",20.445,29.125,265,424.75,0.004327870545459,0 +"5473","2015-02-08 13:02:59",20.4725,28.9725,265,426.75,0.00431241724796904,0 +"5474","2015-02-08 13:04:00",20.5,28.8233333333333,265,429.333333333333,0.00429739849017449,0 +"5475","2015-02-08 13:05:00",20.5,28.8233333333333,265,423.666666666667,0.00429739849017449,0 +"5476","2015-02-08 13:06:00",20.525,28.7225,265,426.75,0.00428891732851142,0 +"5477","2015-02-08 13:07:00",20.55,28.7,262,434.25,0.00429219428811953,0 +"5478","2015-02-08 13:08:00",20.6,28.6,259,427,0.0042904360649924,0 +"5479","2015-02-08 13:08:59",20.6,28.6,257.25,425.5,0.0042904360649924,0 +"5480","2015-02-08 13:09:59",20.65,28.525,256.75,429,0.00429240855033793,0 +"5481","2015-02-08 13:11:00",20.625,28.5,247.25,431.5,0.00428197148387816,0 +"5482","2015-02-08 13:12:00",20.7,28.5,175.666666666667,431,0.00430194630072019,0 +"5483","2015-02-08 13:13:00",20.7,28.5,250.75,432,0.00430194630072019,0 +"5484","2015-02-08 13:14:00",20.7,28.4175,255.5,432,0.00428940742045544,0 +"5485","2015-02-08 13:14:59",20.7,28.245,252,425,0.00426319138404167,0 +"5486","2015-02-08 13:15:59",20.7,28.1666666666667,260.333333333333,422,0.00425128724187452,0 +"5487","2015-02-08 13:17:00",20.745,28.1,174.5,427,0.00425300967197671,0 +"5488","2015-02-08 13:18:00",20.7225,28.1,97.75,431.5,0.00424707939347129,0 +"5489","2015-02-08 13:19:00",20.7,28.1,252,429,0.00424115641351555,0 +"5490","2015-02-08 13:20:00",20.7,28.1,215.5,426.5,0.00424115641351555,0 +"5491","2015-02-08 13:21:00",20.745,28.025,164.5,424.75,0.00424158081417014,0 +"5492","2015-02-08 13:21:59",20.73,28,97.6666666666667,422,0.00423383122127418,0 +"5493","2015-02-08 13:23:00",20.7,27.945,237,420,0.00421760350447281,0 +"5494","2015-02-08 13:24:00",20.745,27.815,153,418,0.00420958223140355,0 +"5495","2015-02-08 13:25:00",20.7225,27.84,231.5,420.5,0.00420751675026369,0 +"5496","2015-02-08 13:25:59",20.7,27.815,82,423.5,0.00419785081775221,0 +"5497","2015-02-08 13:27:00",20.7,27.79,90,422,0.0041940523670117,0 +"5498","2015-02-08 13:27:59",20.7,27.76,89,423.666666666667,0.0041894942869509,0 +"5499","2015-02-08 13:28:59",20.7,27.79,115.25,428.75,0.0041940523670117,0 +"5500","2015-02-08 13:30:00",20.68,27.79,96.4,428.75,0.00418885241337428,0 +"5501","2015-02-08 13:31:00",20.6,27.7,127,428,0.00415452054639183,0 +"5502","2015-02-08 13:32:00",20.6,27.65,169.25,429,0.00414697141392697,0 +"5503","2015-02-08 13:33:00",20.625,27.65,205.5,429.5,0.00415341079159456,0 +"5504","2015-02-08 13:34:00",20.65,27.65,202,427,0.00415985899060534,0 +"5505","2015-02-08 13:34:59",20.7,27.625,156.75,422.75,0.0041689837478149,0 +"5506","2015-02-08 13:36:00",20.7,27.6,209,425,0.00416518564727451,0 +"5507","2015-02-08 13:37:00",20.7,27.525,211,426,0.00415379162210216,0 +"5508","2015-02-08 13:38:00",20.7,27.4633333333333,133.333333333333,425,0.00414442351203924,0 +"5509","2015-02-08 13:38:59",20.7,27.39,197.25,424,0.0041332834217088,0 +"5510","2015-02-08 13:40:00",20.7,27.39,147.5,420.5,0.0041332834217088,0 +"5511","2015-02-08 13:40:59",20.7,27.3233333333333,171,423,0.00412315641084026,0 +"5512","2015-02-08 13:41:59",20.7,27.2675,152,425.25,0.00411467529129676,0 +"5513","2015-02-08 13:43:00",20.7,27.175,77.5,424.75,0.00410062498693376,0 +"5514","2015-02-08 13:44:00",20.7,27.1,74,427.5,0.00408923331117716,0 +"5515","2015-02-08 13:45:00",20.6666666666667,27.1666666666667,123,425,0.00409089267706161,0 +"5516","2015-02-08 13:46:00",20.6,27.0475,151.5,423.75,0.00405601867796952,0 +"5517","2015-02-08 13:46:59",20.625,26.9975,182,425.5,0.00405475735858457,0 +"5518","2015-02-08 13:47:59",20.65,27.05,199.75,424.5,0.00406900028621316,0 +"5519","2015-02-08 13:49:00",20.65,27,201.5,422,0.00406142991772346,0 +"5520","2015-02-08 13:50:00",20.675,26.89,179.5,418.5,0.00405105299165078,0 +"5521","2015-02-08 13:51:00",20.675,26.8925,195.25,417,0.00405143207678965,0 +"5522","2015-02-08 13:52:00",20.7,26.8233333333333,157.333333333333,418.333333333333,0.0040472142698737,0 +"5523","2015-02-08 13:53:00",20.7,26.79,141,427.75,0.00404215211547375,0 +"5524","2015-02-08 13:53:59",20.7,26.79,183,424.75,0.00404215211547375,0 +"5525","2015-02-08 13:54:59",20.7,26.79,186,428,0.00404215211547375,0 +"5526","2015-02-08 13:56:00",20.7,26.745,186,428,0.0040353183368894,0 +"5527","2015-02-08 13:57:00",20.7,26.675,136,423,0.004024688311186,0 +"5528","2015-02-08 13:58:00",20.7,26.65,85.5,420.5,0.00402089196092,0 +"5529","2015-02-08 13:59:00",20.7,26.55,77.5,416,0.00400570702028278,0 +"5530","2015-02-08 13:59:59",20.7,26.65,128.75,412.75,0.00402089196092,0 +"5531","2015-02-08 14:00:59",20.6666666666667,26.6,178.333333333333,414,0.00400501173016373,0 +"5532","2015-02-08 14:02:00",20.7,26.6,154.25,421,0.00401329939851772,0 +"5533","2015-02-08 14:03:00",20.7,26.5,140.5,415,0.0039981148262085,0 +"5534","2015-02-08 14:04:00",20.7,26.5,130,416.333333333333,0.0039981148262085,0 +"5535","2015-02-08 14:05:00",20.7,26.4725,64.25,420.5,0.00399393919796369,0 +"5536","2015-02-08 14:06:00",20.675,26.4725,113,415.75,0.00398775221285737,0 +"5537","2015-02-08 14:06:59",20.6666666666667,26.5,152.333333333333,417.333333333333,0.00398985871462378,0 +"5538","2015-02-08 14:08:00",20.625,26.39,145,418.666666666667,0.00396293555121107,0 +"5539","2015-02-08 14:09:00",20.675,26.4175,151,426.6,0.00397941414233845,0 +"5540","2015-02-08 14:10:00",20.625,26.4175,152.5,427,0.003967091511895,0 +"5541","2015-02-08 14:10:59",20.675,26.39,142.25,424.5,0.00397524519037489,0 +"5542","2015-02-08 14:12:00",20.675,26.365,134.5,420.75,0.00397145528223085,0 +"5543","2015-02-08 14:12:59",20.7,26.39,149.25,418.25,0.00398141264745754,0 +"5544","2015-02-08 14:13:59",20.7,26.315,115.75,423,0.0039700253092998,0 +"5545","2015-02-08 14:15:00",20.6666666666667,26.3566666666667,142.333333333333,421,0.00396814067159585,0 +"5546","2015-02-08 14:16:00",20.7,26.3566666666667,130,423,0.00397635155712788,0 +"5547","2015-02-08 14:17:00",20.675,26.29,145.25,429.25,0.00396008583314141,0 +"5548","2015-02-08 14:18:00",20.7,26.3233333333333,157,422.333333333333,0.0039712905486359,0 +"5549","2015-02-08 14:19:00",20.7,26.245,106.25,419.25,0.0039593975008019,0 +"5550","2015-02-08 14:19:59",20.7,26.23,82.3333333333333,423.666666666667,0.00395712016021781,0 +"5551","2015-02-08 14:21:00",20.7,26.2225,72,421.5,0.00395598149613975,0 +"5552","2015-02-08 14:22:00",20.6,26.15,95.75,422,0.00392058205324917,0 +"5553","2015-02-08 14:23:00",20.6,26.1333333333333,112,426,0.00391806753549011,0 +"5554","2015-02-08 14:23:59",20.6,26.15,110.25,424.75,0.00392058205324917,0 +"5555","2015-02-08 14:25:00",20.6,26.125,85.75,421,0.00391681028418677,0 +"5556","2015-02-08 14:25:59",20.6,26.1,59.5,419.5,0.00391303856058111,0 +"5557","2015-02-08 14:26:59",20.6,26.125,115.25,426,0.00391681028418677,0 +"5558","2015-02-08 14:28:00",20.6,26.2,74,418,0.0039281257277475,0 +"5559","2015-02-08 14:29:00",20.5,26.2,74,417,0.00390381930954106,0 +"5560","2015-02-08 14:30:00",20.5,26.2,81.6666666666667,417.666666666667,0.00390381930954106,0 +"5561","2015-02-08 14:31:00",20.5,26.2,63.5,419,0.00390381930954106,0 +"5562","2015-02-08 14:31:59",20.5,26.245,86.25,420,0.00391056649781573,0 +"5563","2015-02-08 14:32:59",20.5,26.26,63.3333333333333,425.666666666667,0.00391281559290033,0 +"5564","2015-02-08 14:34:00",20.5,26.254,59.5,424.5,0.00391191595292689,0 +"5565","2015-02-08 14:35:00",20.5,26.29,65.8,422,0.00391731383156016,0 +"5566","2015-02-08 14:36:00",20.5,26.29,81,421.666666666667,0.00391731383156016,0 +"5567","2015-02-08 14:37:00",20.4633333333333,26.23,69,421.666666666667,0.00389942806650711,0 +"5568","2015-02-08 14:38:00",20.39,26.2,108,428.25,0.00387723555626482,0 +"5569","2015-02-08 14:38:59",20.445,26.245,57,429,0.00389723144333791,0 +"5570","2015-02-08 14:39:59",20.39,26.2,68,425.75,0.00387723555626482,0 +"5571","2015-02-08 14:41:00",20.39,26.2,73.25,421.5,0.00387723555626482,0 +"5572","2015-02-08 14:42:00",20.39,26.2,98.6666666666667,424,0.00387723555626482,0 +"5573","2015-02-08 14:43:00",20.39,26.2,59,424,0.00387723555626482,0 +"5574","2015-02-08 14:44:00",20.39,26.23,54.3333333333333,426,0.00388170284497696,0 +"5575","2015-02-08 14:44:59",20.39,26.245,100.25,419.75,0.00388393651324755,0 +"5576","2015-02-08 14:45:59",20.39,26.23,100,417.666666666667,0.00388170284497696,0 +"5577","2015-02-08 14:47:00",20.39,26.2225,67.5,419,0.00388058601682033,0 +"5578","2015-02-08 14:48:00",20.365,26.2,59,424.75,0.00387121611003819,0 +"5579","2015-02-08 14:49:00",20.39,26.2,72.3333333333333,421.666666666667,0.00387723555626482,0 +"5580","2015-02-08 14:50:00",20.3566666666667,26.2,70.3333333333333,424.333333333333,0.00386921146051269,0 +"5581","2015-02-08 14:51:00",20.34,26.2225,69.75,422.5,0.0038685449082954,0 +"5582","2015-02-08 14:51:59",20.3566666666667,26.2,85.3333333333333,424.333333333333,0.00386921146051269,0 +"5583","2015-02-08 14:53:00",20.29,26.2,79.75,426.25,0.00385320719822783,0 +"5584","2015-02-08 14:54:00",20.29,26.2225,76.75,421.5,0.00385653676706094,0 +"5585","2015-02-08 14:55:00",20.29,26.2,85.6666666666667,418.666666666667,0.00385320719822783,0 +"5586","2015-02-08 14:55:59",20.315,26.2,59.25,422.5,0.00385920194076222,0 +"5587","2015-02-08 14:57:00",20.29,26.23,62,422.333333333333,0.00385764663121131,0 +"5588","2015-02-08 14:57:59",20.29,26.2,48.5,418.5,0.00385320719822783,0 +"5589","2015-02-08 14:58:59",20.29,26.2,48.5,421.5,0.00385320719822783,0 +"5590","2015-02-08 15:00:00",20.29,26.2,59,421.5,0.00385320719822783,0 +"5591","2015-02-08 15:01:00",20.29,26.175,60.75,417.75,0.00384950771885178,0 +"5592","2015-02-08 15:02:00",20.29,26.2,44.3333333333333,422,0.00385320719822783,0 +"5593","2015-02-08 15:03:00",20.29,26.2,64,419,0.00385320719822783,0 +"5594","2015-02-08 15:04:00",20.2225,26.2225,44,423.75,0.00384037793273924,0 +"5595","2015-02-08 15:04:59",20.245,26.245,54.5,425.25,0.0038490778031903,0 +"5596","2015-02-08 15:06:00",20.2,26.1666666666667,46,420.666666666667,0.00382678915504942,0 +"5597","2015-02-08 15:07:00",20.2,26.2,49,417.5,0.00383169407638348,0 +"5598","2015-02-08 15:08:00",20.2,26.2,63,418.5,0.00383169407638348,0 +"5599","2015-02-08 15:08:59",20.2,26.2,52.75,424.25,0.00383169407638348,0 +"5600","2015-02-08 15:10:00",20.2,26.2,55,423.666666666667,0.00383169407638348,0 +"5601","2015-02-08 15:10:59",20.2,26.175,56.5,419,0.00382801537817504,0 +"5602","2015-02-08 15:11:59",20.2,26.2,62.5,420.5,0.00383169407638348,0 +"5603","2015-02-08 15:13:00",20.2,26.2225,57.75,426.5,0.00383500494174807,0 +"5604","2015-02-08 15:14:00",20.1333333333333,26.2,58.3333333333333,422.666666666667,0.00381582680556521,0 +"5605","2015-02-08 15:15:00",20.125,26.2225,69.25,420.25,0.00381714282818553,0 +"5606","2015-02-08 15:16:00",20.15,26.2675,58.75,420.25,0.00382968982916166,0 +"5607","2015-02-08 15:16:59",20.15,26.29,60.75,424.25,0.00383299044855343,0 +"5608","2015-02-08 15:17:59",20.15,26.29,53.5,423.5,0.00383299044855343,0 +"5609","2015-02-08 15:19:00",20.175,26.2675,60.75,420.25,0.0038356542073287,0 +"5610","2015-02-08 15:20:00",20.15,26.2675,62,424.75,0.00382968982916166,0 +"5611","2015-02-08 15:21:00",20.15,26.2675,52.25,423.75,0.00382968982916166,0 +"5612","2015-02-08 15:22:00",20.1,26.29,46,425.666666666667,0.00382107590736235,0 +"5613","2015-02-08 15:23:00",20.1,26.26,53.6666666666667,426.5,0.00381668885225685,0 +"5614","2015-02-08 15:23:59",20.1,26.2675,47,421.5,0.00381778561026692,0 +"5615","2015-02-08 15:24:59",20.1,26.29,50,423,0.00382107590736235,0 +"5616","2015-02-08 15:26:00",20.1,26.29,40.5,424,0.00382107590736235,0 +"5617","2015-02-08 15:27:00",20.1,26.29,34.6666666666667,422.333333333333,0.00382107590736235,0 +"5618","2015-02-08 15:28:00",20.1,26.29,35.25,422,0.00382107590736235,0 +"5619","2015-02-08 15:29:00",20.075,26.2675,33.5,420.5,0.00381184575016873,0 +"5620","2015-02-08 15:29:59",20.0666666666667,26.26,44,422.666666666667,0.00380877313961726,0 +"5621","2015-02-08 15:30:59",20.075,26.29,44,418.5,0.00381513089688364,0 +"5622","2015-02-08 15:32:00",20.05,26.29,55,418.5,0.00380919404690712,0 +"5623","2015-02-08 15:33:00",20,26.2675,46,423.75,0.00379407505125258,0 +"5624","2015-02-08 15:34:00",20,26.29,44,423.666666666667,0.00379734478979116,0 +"5625","2015-02-08 15:35:00",20,26.29,44,422.5,0.00379734478979116,0 +"5626","2015-02-08 15:36:00",20,26.29,47.6666666666667,423,0.00379734478979116,0 +"5627","2015-02-08 15:36:59",20,26.29,40.5,421.5,0.00379734478979116,0 +"5628","2015-02-08 15:38:00",20,26.29,51.5,426,0.00379734478979116,0 +"5629","2015-02-08 15:39:00",20,26.29,36.6666666666667,421,0.00379734478979116,0 +"5630","2015-02-08 15:40:00",20,26.34,37,420.5,0.00380461099776517,0 +"5631","2015-02-08 15:40:59",20,26.365,37,421,0.00380824416502914,0 +"5632","2015-02-08 15:42:00",20,26.39,37,421.5,0.00381187737447875,0 +"5633","2015-02-08 15:42:59",19.9633333333333,26.39,37,419.666666666667,0.00380317521839064,0 +"5634","2015-02-08 15:43:59",19.9266666666667,26.39,37,421.333333333333,0.00379449059185483,0 +"5635","2015-02-08 15:45:00",19.89,26.39,37,418.75,0.00378582346438501,0 +"5636","2015-02-08 15:46:00",19.89,26.445,37,418,0.00379376170946238,0 +"5637","2015-02-08 15:47:00",19.89,26.4725,37,422.25,0.00379773090752546,0 +"5638","2015-02-08 15:48:00",19.89,26.5,28.6666666666667,422.666666666667,0.00380170015593943,0 +"5639","2015-02-08 15:49:00",19.89,26.4725,28,421.5,0.00379773090752546,0 +"5640","2015-02-08 15:49:59",19.89,26.5,30.75,422.5,0.00380170015593943,0 +"5641","2015-02-08 15:51:00",19.89,26.5,19,421,0.00380170015593943,0 +"5642","2015-02-08 15:52:00",19.89,26.525,23.5,424.75,0.0038053086072822,0 +"5643","2015-02-08 15:53:00",19.89,26.5,33.5,422.5,0.00380170015593943,0 +"5644","2015-02-08 15:53:59",19.865,26.525,26.25,420.25,0.00379937867189251,0 +"5645","2015-02-08 15:55:00",19.8233333333333,26.5333333333333,38.3333333333333,420.666666666667,0.00379071136419209,0 +"5646","2015-02-08 15:55:59",19.84,26.55,33.5,421.75,0.00379705407622002,0 +"5647","2015-02-08 15:56:59",19.84,26.55,33.5,420.5,0.00379705407622002,0 +"5648","2015-02-08 15:58:00",19.84,26.55,33.5,421,0.00379705407622002,0 +"5649","2015-02-08 15:59:00",19.815,26.575,33.5,420,0.00379472638249145,0 +"5650","2015-02-08 16:00:00",19.79,26.6,38.3333333333333,421.333333333333,0.00379239560424957,0 +"5651","2015-02-08 16:01:00",19.79,26.6,33.5,424.25,0.00379239560424957,0 +"5652","2015-02-08 16:01:59",19.79,26.6,38.3333333333333,421.333333333333,0.00379239560424957,0 +"5653","2015-02-08 16:02:59",19.79,26.6,40.75,422,0.00379239560424957,0 +"5654","2015-02-08 16:04:00",19.79,26.6,36.6666666666667,418.666666666667,0.00379239560424957,0 +"5655","2015-02-08 16:05:00",19.79,26.6,34.4,422.75,0.00379239560424957,0 +"5656","2015-02-08 16:06:00",19.79,26.6,36.6666666666667,421,0.00379239560424957,0 +"5657","2015-02-08 16:07:00",19.79,26.6,39.5,418,0.00379239560424957,0 +"5658","2015-02-08 16:08:00",19.79,26.6,39.5,421.75,0.00379239560424957,0 +"5659","2015-02-08 16:08:59",19.745,26.7,39.5,423,0.00379605969621947,0 +"5660","2015-02-08 16:09:59",19.7225,26.7,31,422.5,0.00379072947168724,0 +"5661","2015-02-08 16:11:00",19.7,26.7,31,423,0.00378540585145811,0 +"5662","2015-02-08 16:12:00",19.7225,26.7,31,422,0.00379072947168724,0 +"5663","2015-02-08 16:13:00",19.7,26.7,31,424,0.00378540585145811,0 +"5664","2015-02-08 16:14:00",19.7,26.7,31,427.75,0.00378540585145811,0 +"5665","2015-02-08 16:14:59",19.7,26.73,31,423.333333333333,0.00378968503050269,0 +"5666","2015-02-08 16:15:59",19.7,26.79,31,423.5,0.0037982435641628,0 +"5667","2015-02-08 16:17:00",19.7,26.79,31,421.5,0.0037982435641628,0 +"5668","2015-02-08 16:18:00",19.7,26.79,31,419.333333333333,0.0037982435641628,0 +"5669","2015-02-08 16:19:00",19.6333333333333,26.73,31,426,0.00377393215183181,0 +"5670","2015-02-08 16:20:00",19.675,26.7675,31,418.75,0.0037891115736851,0 +"5671","2015-02-08 16:21:00",19.65,26.745,31,417.75,0.00377999784314178,0 +"5672","2015-02-08 16:21:59",19.7,26.79,31,418,0.0037982435641628,0 +"5673","2015-02-08 16:23:00",19.6,26.7,31,417,0.00376182503753838,0 +"5674","2015-02-08 16:24:00",19.6666666666667,26.8566666666667,31,415.666666666667,0.00379983182894117,0 +"5675","2015-02-08 16:25:00",19.6333333333333,26.8233333333333,31,413,0.00378718985190981,0 +"5676","2015-02-08 16:25:59",19.625,26.79,22,416.75,0.0037804853881162,0 +"5677","2015-02-08 16:27:00",19.65,26.745,17.5,423,0.00377999784314178,0 +"5678","2015-02-08 16:27:59",19.6,26.73,13,425.333333333333,0.00376607739943296,0 +"5679","2015-02-08 16:28:59",19.6,26.79,13,425.25,0.00377458229660593,0 +"5680","2015-02-08 16:30:00",19.6,26.76,13,429,0.00377032981912175,0 +"5681","2015-02-08 16:31:00",19.6,26.7,26.5,428,0.00376182503753838,0 +"5682","2015-02-08 16:32:00",19.6,26.7675,33.25,422,0.00377139293307443,0 +"5683","2015-02-08 16:33:00",19.6,26.84,26.5,416.5,0.00378166988751695,0 +"5684","2015-02-08 16:34:00",19.6,26.79,31,423.666666666667,0.00377458229660593,0 +"5685","2015-02-08 16:34:59",19.58,26.79,23.8,421.75,0.00376986568041323,0 +"5686","2015-02-08 16:36:00",19.5,26.8233333333333,31,417,0.00375574658440957,0 +"5687","2015-02-08 16:37:00",19.55,26.865,26.5,423.5,0.00377339856821446,0 +"5688","2015-02-08 16:38:00",19.5333333333333,26.89,31,430,0.00377299647867788,0 +"5689","2015-02-08 16:38:59",19.5,26.89,22.5,423,0.00376513761499172,0 +"5690","2015-02-08 16:40:00",19.525,26.89,18.5,424.5,0.00377103040709353,0 +"5691","2015-02-08 16:40:59",19.5,26.89,29.3333333333333,426,0.00376513761499172,0 +"5692","2015-02-08 16:41:59",19.5,26.89,24,421.75,0.00376513761499172,0 +"5693","2015-02-08 16:43:00",19.5,26.89,24,425.5,0.00376513761499172,0 +"5694","2015-02-08 16:44:00",19.5,26.89,24,424.5,0.00376513761499172,0 +"5695","2015-02-08 16:45:00",19.525,26.945,24,422,0.00377879041879854,0 +"5696","2015-02-08 16:46:00",19.5,26.9175,24,425.75,0.00376901149722455,0 +"5697","2015-02-08 16:46:59",19.5,26.945,24,422,0.00377288542742124,0 +"5698","2015-02-08 16:47:59",19.5,27,24,423.333333333333,0.00378063343170978,0 +"5699","2015-02-08 16:49:00",19.5,27,24,426.75,0.00378063343170978,0 +"5700","2015-02-08 16:50:00",19.5,27,24,421.75,0.00378063343170978,0 +"5701","2015-02-08 16:51:00",19.5,27.05,24,414.5,0.00378767723846731,0 +"5702","2015-02-08 16:52:00",19.5,27,24,416,0.00378063343170978,0 +"5703","2015-02-08 16:53:00",19.4725,27,24,423.25,0.00377413394638856,0 +"5704","2015-02-08 16:53:59",19.5,27.1,10.5,424.5,0.00379472120379726,0 +"5705","2015-02-08 16:54:59",19.5,27.1,6,424.5,0.00379472120379726,0 +"5706","2015-02-08 16:56:00",19.4725,27.075,6,424.75,0.00378468144196448,0 +"5707","2015-02-08 16:57:00",19.4175,27.075,6,423,0.00377167557861276,0 +"5708","2015-02-08 16:58:00",19.39,27.1,6,425,0.00376868514089311,0 +"5709","2015-02-08 16:59:00",19.4175,27.075,6,421,0.00377167557861276,0 +"5710","2015-02-08 16:59:59",19.4175,27.125,6,420.25,0.00377868312932124,0 +"5711","2015-02-08 17:00:59",19.39,27.1,6,423,0.00376868514089311,0 +"5712","2015-02-08 17:02:00",19.39,27.1,6,418.75,0.00376868514089311,0 +"5713","2015-02-08 17:03:00",19.4266666666667,27.1333333333333,6,423,0.0037820206919294,0 +"5714","2015-02-08 17:04:00",19.4175,27.125,6,428,0.00377868312932124,0 +"5715","2015-02-08 17:05:00",19.39,27.1,6,423.75,0.00376868514089311,0 +"5716","2015-02-08 17:06:00",19.4266666666667,27.1333333333333,6,428,0.0037820206919294,0 +"5717","2015-02-08 17:06:59",19.4266666666667,27.1333333333333,6,426.333333333333,0.0037820206919294,0 +"5718","2015-02-08 17:08:00",19.39,27.1,11.5,429.5,0.00376868514089311,0 +"5719","2015-02-08 17:09:00",19.4266666666667,27.1666666666667,20.6666666666667,427,0.00378669519486035,0 +"5720","2015-02-08 17:10:00",19.39,27.125,17,424.25,0.00377218287218364,0 +"5721","2015-02-08 17:10:59",19.39,27.2,17,423,0.00378267630066579,0 +"5722","2015-02-08 17:12:00",19.39,27.1333333333333,20.6666666666667,424,0.00377334879130296,0 +"5723","2015-02-08 17:12:59",19.39,27.15,17,423.5,0.00377568064257549,0 +"5724","2015-02-08 17:13:59",19.39,27.1,17,425.75,0.00376868514089311,0 +"5725","2015-02-08 17:15:00",19.39,27.15,17,426.75,0.00377568064257549,0 +"5726","2015-02-08 17:16:00",19.445,27.2,17,434.5,0.00379572310890555,0 +"5727","2015-02-08 17:17:00",19.39,27.2,20.6666666666667,426,0.00378267630066579,0 +"5728","2015-02-08 17:18:00",19.39,27.125,17,420.5,0.00377218287218364,0 +"5729","2015-02-08 17:19:00",19.39,27.1,10,425.5,0.00376868514089311,0 +"5730","2015-02-08 17:19:59",19.39,27.1666666666667,11.3333333333333,423.666666666667,0.00377801251122667,0 +"5731","2015-02-08 17:21:00",19.39,27.15,8.5,424.5,0.00377568064257549,0 +"5732","2015-02-08 17:22:00",19.39,27.175,7,421,0.00377917845206932,0 +"5733","2015-02-08 17:23:00",19.39,27.2,7,425.5,0.00378267630066579,0 +"5734","2015-02-08 17:23:59",19.39,27.2,7,426.5,0.00378267630066579,0 +"5735","2015-02-08 17:25:00",19.39,27.2,9.33333333333333,420.666666666667,0.00378267630066579,0 +"5736","2015-02-08 17:25:59",19.39,27.2,14,423.75,0.00378267630066579,0 +"5737","2015-02-08 17:26:59",19.39,27.2,14,422.666666666667,0.00378267630066579,0 +"5738","2015-02-08 17:28:00",19.39,27.2,14,420.75,0.00378267630066579,0 +"5739","2015-02-08 17:29:00",19.39,27.15,14,419.5,0.00377568064257549,0 +"5740","2015-02-08 17:30:00",19.39,27.175,14,426,0.00377917845206932,0 +"5741","2015-02-08 17:31:00",19.39,27.15,14,422,0.00377568064257549,0 +"5742","2015-02-08 17:31:59",19.39,27.2,14,419,0.00378267630066579,0 +"5743","2015-02-08 17:32:59",19.39,27.2,14,421.666666666667,0.00378267630066579,0 +"5744","2015-02-08 17:34:00",19.4175,27.2,14,425,0.00378919474966018,0 +"5745","2015-02-08 17:35:00",19.39,27.2,14,422.5,0.00378267630066579,0 +"5746","2015-02-08 17:36:00",19.39,27.2,14,419.5,0.00378267630066579,0 +"5747","2015-02-08 17:37:00",19.39,27.2,14,422,0.00378267630066579,0 +"5748","2015-02-08 17:38:00",19.39,27.2,9.33333333333333,425.333333333333,0.00378267630066579,0 +"5749","2015-02-08 17:38:59",19.4266666666667,27.23,4.66666666666667,427.666666666667,0.00379557694282936,0 +"5750","2015-02-08 17:39:59",19.39,27.2,0,427,0.00378267630066579,0 +"5751","2015-02-08 17:41:00",19.39,27.2,0,426,0.00378267630066579,0 +"5752","2015-02-08 17:42:00",19.39,27.2,0,423,0.00378267630066579,0 +"5753","2015-02-08 17:43:00",19.445,27.2,0,427,0.00379572310890555,0 +"5754","2015-02-08 17:44:00",19.39,27.2,0,422,0.00378267630066579,0 +"5755","2015-02-08 17:44:59",19.39,27.2,0,423,0.00378267630066579,0 +"5756","2015-02-08 17:45:59",19.39,27.2,0,421,0.00378267630066579,0 +"5757","2015-02-08 17:47:00",19.39,27.2,0,422.333333333333,0.00378267630066579,0 +"5758","2015-02-08 17:48:00",19.39,27.2,0,424,0.00378267630066579,0 +"5759","2015-02-08 17:49:00",19.39,27.2,0,426,0.00378267630066579,0 +"5760","2015-02-08 17:50:00",19.39,27.2,0,428,0.00378267630066579,0 +"5761","2015-02-08 17:51:00",19.39,27.2,0,427.5,0.00378267630066579,0 +"5762","2015-02-08 17:51:59",19.4633333333333,27.26,0,428,0.00380851471818723,0 +"5763","2015-02-08 17:53:00",19.39,27.2,0,425,0.00378267630066579,0 +"5764","2015-02-08 17:54:00",19.39,27.2,0,426.5,0.00378267630066579,0 +"5765","2015-02-08 17:55:00",19.39,27.2,0,426,0.00378267630066579,0 +"5766","2015-02-08 17:55:59",19.39,27.2,0,422,0.00378267630066579,0 +"5767","2015-02-08 17:57:00",19.39,27.2,0,426,0.00378267630066579,0 +"5768","2015-02-08 17:57:59",19.39,27.2,0,423.5,0.00378267630066579,0 +"5769","2015-02-08 17:58:59",19.39,27.2,0,424,0.00378267630066579,0 +"5770","2015-02-08 18:00:00",19.39,27.2,0,429,0.00378267630066579,0 +"5771","2015-02-08 18:01:00",19.34,27.29,0,422.5,0.0037834028932961,0 +"5772","2015-02-08 18:02:00",19.34,27.29,0,424.5,0.0037834028932961,0 +"5773","2015-02-08 18:03:00",19.29,27.29,0,428,0.00377156965824258,0 +"5774","2015-02-08 18:04:00",19.29,27.29,0,426.5,0.00377156965824258,0 +"5775","2015-02-08 18:04:59",19.34,27.34,0,424.5,0.00379037698343334,0 +"5776","2015-02-08 18:06:00",19.29,27.29,0,425,0.00377156965824258,0 +"5777","2015-02-08 18:07:00",19.29,27.3566666666667,0,423.333333333333,0.00378083922027632,0 +"5778","2015-02-08 18:08:00",19.29,27.29,0,426,0.00377156965824258,0 +"5779","2015-02-08 18:08:59",19.34,27.39,0,424.5,0.00379735122901886,0 +"5780","2015-02-08 18:10:00",19.34,27.39,0,424.5,0.00379735122901886,0 +"5781","2015-02-08 18:10:59",19.3233333333333,27.39,0,420.333333333333,0.00379338853862594,0 +"5782","2015-02-08 18:11:59",19.29,27.39,0,425,0.00378547410427655,0 +"5783","2015-02-08 18:13:00",19.29,27.445,0,427.5,0.00379312181298036,0 +"5784","2015-02-08 18:14:00",19.29,27.5,0,426,0.00380076970861137,0 +"5785","2015-02-08 18:15:00",19.29,27.445,0,425,0.00379312181298036,0 +"5786","2015-02-08 18:16:00",19.29,27.5,0,427,0.00380076970861137,0 +"5787","2015-02-08 18:16:59",19.29,27.5,0,424,0.00380076970861137,0 +"5788","2015-02-08 18:17:59",19.29,27.5,0,424,0.00380076970861137,0 +"5789","2015-02-08 18:19:00",19.29,27.5,0,425,0.00380076970861137,0 +"5790","2015-02-08 18:20:00",19.29,27.5,0,425,0.00380076970861137,0 +"5791","2015-02-08 18:21:00",19.29,27.5,0,426,0.00380076970861137,0 +"5792","2015-02-08 18:22:00",19.29,27.5,0,432,0.00380076970861137,0 +"5793","2015-02-08 18:23:00",19.29,27.5,0,428.5,0.00380076970861137,0 +"5794","2015-02-08 18:23:59",19.29,27.5,0,426,0.00380076970861137,0 +"5795","2015-02-08 18:24:59",19.34,27.4725,0,428,0.00380885907409757,0 +"5796","2015-02-08 18:26:00",19.29,27.5,0,426.666666666667,0.00380076970861137,0 +"5797","2015-02-08 18:27:00",19.34,27.5,0,427.5,0.00381269511651053,0 +"5798","2015-02-08 18:28:00",19.29,27.39,0,428,0.00378547410427655,0 +"5799","2015-02-08 18:29:00",19.34,27.39,0,427,0.00379735122901886,0 +"5800","2015-02-08 18:29:59",19.39,27.39,0,425,0.00380926122794171,0 +"5801","2015-02-08 18:30:59",19.34,27.445,0,425,0.00380502307871189,0 +"5802","2015-02-08 18:32:00",19.34,27.39,0,430,0.00379735122901886,0 +"5803","2015-02-08 18:33:00",19.39,27.39,0,437,0.00380926122794171,0 +"5804","2015-02-08 18:34:00",19.39,27.39,0,430.5,0.00380926122794171,0 +"5805","2015-02-08 18:35:00",19.39,27.39,0,430.666666666667,0.00380926122794171,0 +"5806","2015-02-08 18:36:00",19.39,27.39,0,422.5,0.00380926122794171,0 +"5807","2015-02-08 18:36:59",19.39,27.39,0,422,0.00380926122794171,0 +"5808","2015-02-08 18:38:00",19.39,27.39,0,424,0.00380926122794171,0 +"5809","2015-02-08 18:39:00",19.39,27.39,0,427.666666666667,0.00380926122794171,0 +"5810","2015-02-08 18:40:00",19.3233333333333,27.39,0,430,0.00379338853862594,0 +"5811","2015-02-08 18:40:59",19.39,27.39,0,432,0.00380926122794171,0 +"5812","2015-02-08 18:42:00",19.39,27.5,0,429,0.00382465353406781,0 +"5813","2015-02-08 18:42:59",19.29,27.5,0,428,0.00380076970861137,0 +"5814","2015-02-08 18:43:59",19.29,27.5,0,428,0.00380076970861137,0 +"5815","2015-02-08 18:45:00",19.29,27.55,0,426,0.00380772250321852,0 +"5816","2015-02-08 18:46:00",19.29,27.6,0,427.5,0.00381467545232177,0 +"5817","2015-02-08 18:47:00",19.29,27.6,0,429,0.00381467545232177,0 +"5818","2015-02-08 18:48:00",19.29,27.6,0,426.333333333333,0.00381467545232177,0 +"5819","2015-02-08 18:49:00",19.29,27.6,0,428.5,0.00381467545232177,0 +"5820","2015-02-08 18:49:59",19.29,27.6,0,426,0.00381467545232177,0 +"5821","2015-02-08 18:51:00",19.29,27.6,0,429,0.00381467545232177,0 +"5822","2015-02-08 18:52:00",19.29,27.6,0,432,0.00381467545232177,0 +"5823","2015-02-08 18:53:00",19.29,27.6,0,427,0.00381467545232177,0 +"5824","2015-02-08 18:53:59",19.245,27.6,0,429,0.00380393134038813,0 +"5825","2015-02-08 18:55:00",19.26,27.6666666666667,0,426.333333333333,0.00381676305777689,0 +"5826","2015-02-08 18:55:59",19.2,27.6,0,436,0.00379321394453656,0 +"5827","2015-02-08 18:56:59",19.2,27.6,0,429,0.00379321394453656,0 +"5828","2015-02-08 18:58:00",19.2,27.6,0,429.5,0.00379321394453656,0 +"5829","2015-02-08 18:59:00",19.2,27.6,0,434,0.00379321394453656,0 +"5830","2015-02-08 19:00:00",19.2,27.65,0,423.5,0.0038001276921799,0 +"5831","2015-02-08 19:01:00",19.29,27.7,0,432,0.00382858181403718,0 +"5832","2015-02-08 19:01:59",19.245,27.745,0,427,0.00382403862595271,0 +"5833","2015-02-08 19:02:59",19.245,27.745,0,430,0.00382403862595271,0 +"5834","2015-02-08 19:04:00",19.23,27.73,0,432.666666666667,0.00381836602344458,0 +"5835","2015-02-08 19:05:00",19.2,27.7,0,434,0.00380704159259074,0 +"5836","2015-02-08 19:06:00",19.2,27.7,0,436,0.00380704159259074,0 +"5837","2015-02-08 19:07:00",19.2,27.7,0,440.333333333333,0.00380704159259074,0 +"5838","2015-02-08 19:08:00",19.2,27.7,0,439,0.00380704159259074,0 +"5839","2015-02-08 19:08:59",19.23,27.73,0,440.333333333333,0.00381836602344458,0 +"5840","2015-02-08 19:09:59",19.2,27.7,0,443,0.00380704159259074,0 +"5841","2015-02-08 19:11:00",19.2,27.7,0,439.5,0.00380704159259074,0 +"5842","2015-02-08 19:12:00",19.2,27.6,0,437,0.00379321394453656,0 +"5843","2015-02-08 19:13:00",19.245,27.65,0,431.5,0.00381086474118018,0 +"5844","2015-02-08 19:14:00",19.29,27.7,0,430.333333333333,0.00382858181403718,0 +"5845","2015-02-08 19:14:59",19.29,27.7,0,436.5,0.00382858181403718,0 +"5846","2015-02-08 19:15:59",19.29,27.7,0,437.5,0.00382858181403718,0 +"5847","2015-02-08 19:17:00",19.29,27.6333333333333,0,434,0.00381931083755765,0 +"5848","2015-02-08 19:18:00",19.29,27.6,0,432.5,0.00381467545232177,0 +"5849","2015-02-08 19:19:00",19.29,27.6,0,427.666666666667,0.00381467545232177,0 +"5850","2015-02-08 19:20:00",19.29,27.6,0,428.5,0.00381467545232177,0 +"5851","2015-02-08 19:21:00",19.315,27.6,0,434.5,0.00382065596854389,0 +"5852","2015-02-08 19:21:59",19.29,27.6,0,438,0.00381467545232177,0 +"5853","2015-02-08 19:23:00",19.29,27.6,0,438,0.00381467545232177,0 +"5854","2015-02-08 19:24:00",19.34,27.6,0,435,0.00382664475809049,0 +"5855","2015-02-08 19:25:00",19.39,27.6,0,437,0.00383864719670305,0 +"5856","2015-02-08 19:25:59",19.39,27.6,0,437.5,0.00383864719670305,0 +"5857","2015-02-08 19:27:00",19.39,27.5,0,437,0.00382465353406781,0 +"5858","2015-02-08 19:27:59",19.39,27.55,0,431.5,0.00383165028716048,0 +"5859","2015-02-08 19:28:59",19.39,27.6,0,432,0.00383864719670305,0 +"5860","2015-02-08 19:30:00",19.39,27.6,0,434,0.00383864719670305,0 +"5861","2015-02-08 19:31:00",19.39,27.6,0,434,0.00383864719670305,0 +"5862","2015-02-08 19:32:00",19.39,27.6,0,438,0.00383864719670305,0 +"5863","2015-02-08 19:33:00",19.29,27.6,0,437,0.00381467545232177,0 +"5864","2015-02-08 19:34:00",19.29,27.6,0,435.5,0.00381467545232177,0 +"5865","2015-02-08 19:34:59",19.29,27.65,0,435,0.00382162855592627,0 +"5866","2015-02-08 19:36:00",19.29,27.6,0,435,0.00381467545232177,0 +"5867","2015-02-08 19:37:00",19.39,27.65,0,435,0.00384564426270076,0 +"5868","2015-02-08 19:38:00",19.29,27.7,0,435,0.00382858181403718,0 +"5869","2015-02-08 19:38:59",19.29,27.7,0,432,0.00382858181403718,0 +"5870","2015-02-08 19:40:00",19.29,27.7,0,432,0.00382858181403718,0 +"5871","2015-02-08 19:40:59",19.29,27.7,0,435,0.00382858181403718,0 +"5872","2015-02-08 19:41:59",19.29,27.7,0,433,0.00382858181403718,0 +"5873","2015-02-08 19:43:00",19.29,27.7,0,435,0.00382858181403718,0 +"5874","2015-02-08 19:44:00",19.29,27.745,0,438,0.00383483987844422,0 +"5875","2015-02-08 19:45:00",19.29,27.7,0,437,0.00382858181403718,0 +"5876","2015-02-08 19:46:00",19.29,27.7,0,439,0.00382858181403718,0 +"5877","2015-02-08 19:46:59",19.29,27.7,0,436,0.00382858181403718,0 +"5878","2015-02-08 19:47:59",19.39,27.7,0,434,0.00385264148515886,0 +"5879","2015-02-08 19:49:00",19.34,27.7,0,440.5,0.00384059502157166,0 +"5880","2015-02-08 19:50:00",19.315,27.675,0,437.75,0.00383110213333343,0 +"5881","2015-02-08 19:51:00",19.34,27.65,0,436,0.00383361981209082,0 +"5882","2015-02-08 19:52:00",19.39,27.6,0,437,0.00383864719670305,0 +"5883","2015-02-08 19:53:00",19.39,27.6,0,432,0.00383864719670305,0 +"5884","2015-02-08 19:53:59",19.39,27.6,0,437.666666666667,0.00383864719670305,0 +"5885","2015-02-08 19:54:59",19.39,27.6,0,443,0.00383864719670305,0 +"5886","2015-02-08 19:56:00",19.39,27.6,0,440.25,0.00383864719670305,0 +"5887","2015-02-08 19:57:00",19.39,27.6,0,437.5,0.00383864719670305,0 +"5888","2015-02-08 19:58:00",19.39,27.6,0,434.666666666667,0.00383864719670305,0 +"5889","2015-02-08 19:59:00",19.39,27.6,0,441,0.00383864719670305,0 +"5890","2015-02-08 19:59:59",19.39,27.6,0,440.5,0.00383864719670305,0 +"5891","2015-02-08 20:00:59",19.39,27.6,0,441.5,0.00383864719670305,0 +"5892","2015-02-08 20:02:00",19.39,27.6,0,434.333333333333,0.00383864719670305,0 +"5893","2015-02-08 20:03:00",19.39,27.6,0,431,0.00383864719670305,0 +"5894","2015-02-08 20:04:00",19.39,27.6,0,434,0.00383864719670305,0 +"5895","2015-02-08 20:05:00",19.39,27.6,0,435,0.00383864719670305,0 +"5896","2015-02-08 20:06:00",19.39,27.6,0,441,0.00383864719670305,0 +"5897","2015-02-08 20:06:59",19.39,27.6,0,434.5,0.00383864719670305,0 +"5898","2015-02-08 20:08:00",19.39,27.6,0,440.333333333333,0.00383864719670305,0 +"5899","2015-02-08 20:09:00",19.39,27.6,0,434.5,0.00383864719670305,0 +"5900","2015-02-08 20:10:00",19.39,27.6,0,440,0.00383864719670305,0 +"5901","2015-02-08 20:10:59",19.39,27.5,0,444,0.00382465353406781,0 +"5902","2015-02-08 20:12:00",19.39,27.5666666666667,0,441,0.00383398257295775,0 +"5903","2015-02-08 20:12:59",19.4266666666667,27.5666666666667,0,441.666666666667,0.00384279467770833,0 +"5904","2015-02-08 20:13:59",19.39,27.6,0,444,0.00383864719670305,0 +"5905","2015-02-08 20:15:00",19.39,27.55,0,444.5,0.00383165028716048,0 +"5906","2015-02-08 20:16:00",19.39,27.5,0,443,0.00382465353406781,0 +"5907","2015-02-08 20:17:00",19.39,27.5,0,437,0.00382465353406781,0 +"5908","2015-02-08 20:18:00",19.39,27.5,0,436.5,0.00382465353406781,0 +"5909","2015-02-08 20:19:00",19.39,27.5,0,437,0.00382465353406781,0 +"5910","2015-02-08 20:19:59",19.39,27.5,0,437.5,0.00382465353406781,0 +"5911","2015-02-08 20:21:00",19.39,27.5,0,439.333333333333,0.00382465353406781,0 +"5912","2015-02-08 20:22:00",19.39,27.5,0,440.666666666667,0.00382465353406781,0 +"5913","2015-02-08 20:23:00",19.39,27.5,0,442,0.00382465353406781,0 +"5914","2015-02-08 20:23:59",19.39,27.5,0,441,0.00382465353406781,0 +"5915","2015-02-08 20:25:00",19.39,27.5,0,439,0.00382465353406781,0 +"5916","2015-02-08 20:25:59",19.39,27.5,0,436.5,0.00382465353406781,0 +"5917","2015-02-08 20:26:59",19.39,27.5,0,437,0.00382465353406781,0 +"5918","2015-02-08 20:28:00",19.39,27.5,0,445,0.00382465353406781,0 +"5919","2015-02-08 20:29:00",19.39,27.5,0,449,0.00382465353406781,0 +"5920","2015-02-08 20:30:00",19.39,27.5,0,443.5,0.00382465353406781,0 +"5921","2015-02-08 20:31:00",19.39,27.5,0,442,0.00382465353406781,0 +"5922","2015-02-08 20:31:59",19.39,27.5,0,445,0.00382465353406781,0 +"5923","2015-02-08 20:32:59",19.39,27.445,0,443.5,0.00381695728635924,0 +"5924","2015-02-08 20:34:00",19.39,27.39,0,444.5,0.00380926122794171,0 +"5925","2015-02-08 20:35:00",19.39,27.39,0,442,0.00380926122794171,0 +"5926","2015-02-08 20:36:00",19.39,27.39,0,442,0.00380926122794171,0 +"5927","2015-02-08 20:37:00",19.39,27.39,0,444,0.00380926122794171,0 +"5928","2015-02-08 20:38:00",19.39,27.39,0,435,0.00380926122794171,0 +"5929","2015-02-08 20:38:59",19.39,27.39,0,434,0.00380926122794171,0 +"5930","2015-02-08 20:39:59",19.39,27.39,0,441.5,0.00380926122794171,0 +"5931","2015-02-08 20:41:00",19.39,27.39,0,443.5,0.00380926122794171,0 +"5932","2015-02-08 20:42:00",19.39,27.39,0,441,0.00380926122794171,0 +"5933","2015-02-08 20:43:00",19.39,27.39,0,444,0.00380926122794171,0 +"5934","2015-02-08 20:44:00",19.39,27.39,0,444.5,0.00380926122794171,0 +"5935","2015-02-08 20:44:59",19.39,27.39,0,445.5,0.00380926122794171,0 +"5936","2015-02-08 20:45:59",19.39,27.445,0,447,0.00381695728635924,0 +"5937","2015-02-08 20:47:00",19.39,27.445,0,445,0.00381695728635924,0 +"5938","2015-02-08 20:48:00",19.39,27.39,0,447,0.00380926122794171,0 +"5939","2015-02-08 20:49:00",19.39,27.39,0,449,0.00380926122794171,0 +"5940","2015-02-08 20:50:00",19.39,27.39,0,449,0.00380926122794171,0 +"5941","2015-02-08 20:51:00",19.39,27.39,0,453,0.00380926122794171,0 +"5942","2015-02-08 20:51:59",19.39,27.39,0,452.5,0.00380926122794171,0 +"5943","2015-02-08 20:53:00",19.39,27.4633333333333,0,446,0.00381952268122941,0 +"5944","2015-02-08 20:54:00",19.39,27.39,0,447,0.00380926122794171,0 +"5945","2015-02-08 20:55:00",19.39,27.39,0,449,0.00380926122794171,0 +"5946","2015-02-08 20:55:59",19.445,27.445,0,441.5,0.00383012305664187,0 +"5947","2015-02-08 20:57:00",19.39,27.39,0,444,0.00380926122794171,0 +"5948","2015-02-08 20:57:59",19.445,27.445,0,446,0.00383012305664187,0 +"5949","2015-02-08 20:58:59",19.39,27.39,0,441.333333333333,0.00380926122794171,0 +"5950","2015-02-08 21:00:00",19.39,27.39,0,442.666666666667,0.00380926122794171,0 +"5951","2015-02-08 21:01:00",19.39,27.39,0,446,0.00380926122794171,0 +"5952","2015-02-08 21:02:00",19.39,27.445,0,446,0.00381695728635924,0 +"5953","2015-02-08 21:03:00",19.39,27.39,0,443,0.00380926122794171,0 +"5954","2015-02-08 21:04:00",19.4266666666667,27.4633333333333,0,444.666666666667,0.00382830134776418,0 +"5955","2015-02-08 21:04:59",19.4266666666667,27.4266666666667,0,437,0.00382315871462424,0 +"5956","2015-02-08 21:06:00",19.39,27.39,0,450,0.00380926122794171,0 +"5957","2015-02-08 21:07:00",19.39,27.39,0,454.5,0.00380926122794171,0 +"5958","2015-02-08 21:08:00",19.4633333333333,27.4633333333333,0,451,0.00383709781535469,0 +"5959","2015-02-08 21:08:59",19.39,27.39,0,450.5,0.00380926122794171,0 +"5960","2015-02-08 21:10:00",19.39,27.39,0,449,0.00380926122794171,0 +"5961","2015-02-08 21:10:59",19.5,27.5,0,443.5,0.00385107863568625,0 +"5962","2015-02-08 21:11:59",19.39,27.39,0,447.5,0.00380926122794171,0 +"5963","2015-02-08 21:13:00",19.5,27.5,0,445,0.00385107863568625,0 +"5964","2015-02-08 21:14:00",19.445,27.445,0,447.5,0.00383012305664187,0 +"5965","2015-02-08 21:15:00",19.4266666666667,27.46,0,449.666666666667,0.00382783383216807,0 +"5966","2015-02-08 21:16:00",19.4633333333333,27.5666666666667,0,450,0.00385162465225822,0 +"5967","2015-02-08 21:16:59",19.5,27.6,0,451,0.00386516957975751,0 +"5968","2015-02-08 21:17:59",19.5,27.6,0,454.5,0.00386516957975751,0 +"5969","2015-02-08 21:19:00",19.39,27.5,0,455,0.00382465353406781,0 +"5970","2015-02-08 21:20:00",19.39,27.39,0,454,0.00380926122794171,0 +"5971","2015-02-08 21:21:00",19.5,27.5,0,452,0.00385107863568625,0 +"5972","2015-02-08 21:22:00",19.5,27.525,0,451,0.00385460131221966,0 +"5973","2015-02-08 21:23:00",19.5,27.55,0,447,0.0038581240284089,0 +"5974","2015-02-08 21:23:59",19.4633333333333,27.5666666666667,0,450,0.00385162465225822,0 +"5975","2015-02-08 21:24:59",19.5,27.6,0,446,0.00386516957975751,0 +"5976","2015-02-08 21:26:00",19.5,27.6,0,447,0.00386516957975751,0 +"5977","2015-02-08 21:27:00",19.445,27.55,0,449,0.00384486704914558,0 +"5978","2015-02-08 21:28:00",19.5,27.6,0,449,0.00386516957975751,0 +"5979","2015-02-08 21:29:00",19.5,27.6,0,447.666666666667,0.00386516957975751,0 +"5980","2015-02-08 21:29:59",19.445,27.55,0,446.5,0.00384486704914558,0 +"5981","2015-02-08 21:30:59",19.445,27.55,0,447,0.00384486704914558,0 +"5982","2015-02-08 21:32:00",19.5,27.6,0,453.5,0.00386516957975751,0 +"5983","2015-02-08 21:33:00",19.5,27.6,0,458,0.00386516957975751,0 +"5984","2015-02-08 21:34:00",19.5,27.6,0,450,0.00386516957975751,0 +"5985","2015-02-08 21:35:00",19.5,27.6,0,446,0.00386516957975751,0 +"5986","2015-02-08 21:36:00",19.5,27.6,0,447,0.00386516957975751,0 +"5987","2015-02-08 21:36:59",19.5,27.6,0,448,0.00386516957975751,0 +"5988","2015-02-08 21:38:00",19.5,27.6,0,450,0.00386516957975751,0 +"5989","2015-02-08 21:39:00",19.5,27.6,0,447,0.00386516957975751,0 +"5990","2015-02-08 21:40:00",19.5,27.6,0,446.5,0.00386516957975751,0 +"5991","2015-02-08 21:40:59",19.5,27.6,0,449.5,0.00386516957975751,0 +"5992","2015-02-08 21:42:00",19.5,27.6,0,447.5,0.00386516957975751,0 +"5993","2015-02-08 21:42:59",19.5,27.6,0,447,0.00386516957975751,0 +"5994","2015-02-08 21:43:59",19.5,27.6,0,447,0.00386516957975751,0 +"5995","2015-02-08 21:45:00",19.5,27.6,0,450,0.00386516957975751,0 +"5996","2015-02-08 21:46:00",19.5,27.6,0,454,0.00386516957975751,0 +"5997","2015-02-08 21:47:00",19.5,27.6,0,447,0.00386516957975751,0 +"5998","2015-02-08 21:48:00",19.5,27.6,0,447.5,0.00386516957975751,0 +"5999","2015-02-08 21:49:00",19.5,27.6,0,448.5,0.00386516957975751,0 +"6000","2015-02-08 21:49:59",19.5,27.6,0,445.5,0.00386516957975751,0 +"6001","2015-02-08 21:51:00",19.5,27.6,0,444,0.00386516957975751,0 +"6002","2015-02-08 21:52:00",19.5,27.6,0,444.5,0.00386516957975751,0 +"6003","2015-02-08 21:53:00",19.5,27.6,0,449.5,0.00386516957975751,0 +"6004","2015-02-08 21:53:59",19.5,27.6,0,456,0.00386516957975751,0 +"6005","2015-02-08 21:55:00",19.5,27.6,0,451.5,0.00386516957975751,0 +"6006","2015-02-08 21:55:59",19.5,27.6,0,447.666666666667,0.00386516957975751,0 +"6007","2015-02-08 21:56:59",19.5,27.6,0,447.5,0.00386516957975751,0 +"6008","2015-02-08 21:58:00",19.5,27.6,0,450,0.00386516957975751,0 +"6009","2015-02-08 21:59:00",19.5,27.6,0,449,0.00386516957975751,0 +"6010","2015-02-08 22:00:00",19.5,27.6,0,442,0.00386516957975751,0 +"6011","2015-02-08 22:01:00",19.5,27.6,0,444,0.00386516957975751,0 +"6012","2015-02-08 22:01:59",19.5,27.6,0,447.5,0.00386516957975751,0 +"6013","2015-02-08 22:02:59",19.6,27.6,0,451,0.00388942103964091,0 +"6014","2015-02-08 22:04:00",19.5,27.6,0,444,0.00386516957975751,0 +"6015","2015-02-08 22:05:00",19.5,27.6,0,445.666666666667,0.00386516957975751,0 +"6016","2015-02-08 22:06:00",19.5,27.7,0,450,0.00387926115835408,0 +"6017","2015-02-08 22:07:00",19.5,27.7,0,446.666666666667,0.00387926115835408,0 +"6018","2015-02-08 22:08:00",19.5,27.6,0,452,0.00386516957975751,0 +"6019","2015-02-08 22:08:59",19.5,27.7,0,455,0.00387926115835408,0 +"6020","2015-02-08 22:09:59",19.5,27.7,0,453,0.00387926115835408,0 +"6021","2015-02-08 22:11:00",19.5,27.7,0,446,0.00387926115835408,0 +"6022","2015-02-08 22:12:00",19.5,27.65,0,449,0.00387221528973745,0 +"6023","2015-02-08 22:13:00",19.5,27.7,0,451,0.00387926115835408,0 +"6024","2015-02-08 22:14:00",19.5,27.6,0,451,0.00386516957975751,0 +"6025","2015-02-08 22:14:59",19.5,27.7,0,445.5,0.00387926115835408,0 +"6026","2015-02-08 22:15:59",19.5,27.65,0,443,0.00387221528973745,0 +"6027","2015-02-08 22:17:00",19.5,27.7,0,450,0.00387926115835408,0 +"6028","2015-02-08 22:18:00",19.5,27.7,0,455.5,0.00387926115835408,0 +"6029","2015-02-08 22:19:00",19.5,27.7,0,456,0.00387926115835408,0 +"6030","2015-02-08 22:20:00",19.5,27.65,0,454,0.00387221528973745,0 +"6031","2015-02-08 22:21:00",19.5,27.7,0,450.5,0.00387926115835408,0 +"6032","2015-02-08 22:21:59",19.5,27.7,0,450.75,0.00387926115835408,0 +"6033","2015-02-08 22:23:00",19.5,27.7,0,452,0.00387926115835408,0 +"6034","2015-02-08 22:24:00",19.5,27.7,0,452,0.00387926115835408,0 +"6035","2015-02-08 22:25:00",19.5,27.7,0,454,0.00387926115835408,0 +"6036","2015-02-08 22:25:59",19.5,27.7,0,453,0.00387926115835408,0 +"6037","2015-02-08 22:27:00",19.5,27.7,0,452,0.00387926115835408,0 +"6038","2015-02-08 22:27:59",19.5,27.7,0,447.333333333333,0.00387926115835408,0 +"6039","2015-02-08 22:28:59",19.5,27.7,0,444,0.00387926115835408,0 +"6040","2015-02-08 22:30:00",19.5,27.7,0,446,0.00387926115835408,0 +"6041","2015-02-08 22:31:00",19.5,27.7,0,447.666666666667,0.00387926115835408,0 +"6042","2015-02-08 22:32:00",19.5,27.7,0,448,0.00387926115835408,0 +"6043","2015-02-08 22:33:00",19.5,27.7,0,447,0.00387926115835408,0 +"6044","2015-02-08 22:34:00",19.5,27.7,0,443,0.00387926115835408,0 +"6045","2015-02-08 22:34:59",19.5,27.7,0,442.5,0.00387926115835408,0 +"6046","2015-02-08 22:36:00",19.5,27.7,0,445.666666666667,0.00387926115835408,0 +"6047","2015-02-08 22:37:00",19.5,27.7,0,453,0.00387926115835408,0 +"6048","2015-02-08 22:38:00",19.5,27.7,0,452,0.00387926115835408,0 +"6049","2015-02-08 22:38:59",19.5,27.745,0,450,0.00388560257574784,0 +"6050","2015-02-08 22:40:00",19.5,27.79,0,451,0.00389194412164556,0 +"6051","2015-02-08 22:40:59",19.5,27.7,0,447,0.00387926115835408,0 +"6052","2015-02-08 22:41:59",19.5,27.745,0,451,0.00388560257574784,0 +"6053","2015-02-08 22:43:00",19.5,27.745,0,450,0.00388560257574784,0 +"6054","2015-02-08 22:44:00",19.5,27.7,0,448,0.00387926115835408,0 +"6055","2015-02-08 22:45:00",19.5,27.7,0,452,0.00387926115835408,0 +"6056","2015-02-08 22:46:00",19.5,27.745,0,454,0.00388560257574784,0 +"6057","2015-02-08 22:46:59",19.5,27.79,0,454.5,0.00389194412164556,0 +"6058","2015-02-08 22:47:59",19.5,27.745,0,451.5,0.00388560257574784,0 +"6059","2015-02-08 22:49:00",19.5,27.79,0,452,0.00389194412164556,0 +"6060","2015-02-08 22:50:00",19.5,27.79,0,454,0.00389194412164556,0 +"6061","2015-02-08 22:51:00",19.5,27.79,0,453.5,0.00389194412164556,0 +"6062","2015-02-08 22:52:00",19.5,27.79,0,454,0.00389194412164556,0 +"6063","2015-02-08 22:53:00",19.5,27.79,0,450,0.00389194412164556,0 +"6064","2015-02-08 22:53:59",19.5,27.79,0,448,0.00389194412164556,0 +"6065","2015-02-08 22:54:59",19.5,27.79,0,444,0.00389194412164556,0 +"6066","2015-02-08 22:56:00",19.5,27.79,0,447.5,0.00389194412164556,0 +"6067","2015-02-08 22:57:00",19.5,27.7,0,451,0.00387926115835408,0 +"6068","2015-02-08 22:58:00",19.5,27.79,0,449,0.00389194412164556,0 +"6069","2015-02-08 22:59:00",19.5,27.79,0,448.333333333333,0.00389194412164556,0 +"6070","2015-02-08 22:59:59",19.5,27.79,0,456.5,0.00389194412164556,0 +"6071","2015-02-08 23:00:59",19.5,27.79,0,452,0.00389194412164556,0 +"6072","2015-02-08 23:02:00",19.5,27.79,0,447,0.00389194412164556,0 +"6073","2015-02-08 23:03:00",19.5,27.79,0,449.5,0.00389194412164556,0 +"6074","2015-02-08 23:04:00",19.5,27.79,0,452,0.00389194412164556,0 +"6075","2015-02-08 23:05:00",19.5,27.79,0,451,0.00389194412164556,0 +"6076","2015-02-08 23:06:00",19.5,27.745,0,450.5,0.00388560257574784,0 +"6077","2015-02-08 23:06:59",19.5,27.7,0,449,0.00387926115835408,0 +"6078","2015-02-08 23:08:00",19.5,27.7,0,449,0.00387926115835408,0 +"6079","2015-02-08 23:09:00",19.5,27.7,0,453,0.00387926115835408,0 +"6080","2015-02-08 23:10:00",19.5,27.7,0,447.5,0.00387926115835408,0 +"6081","2015-02-08 23:10:59",19.5,27.7,0,450.5,0.00387926115835408,0 +"6082","2015-02-08 23:12:00",19.5,27.7,0,453,0.00387926115835408,0 +"6083","2015-02-08 23:12:59",19.5,27.7,0,447,0.00387926115835408,0 +"6084","2015-02-08 23:13:59",19.5,27.7,0,447.666666666667,0.00387926115835408,0 +"6085","2015-02-08 23:15:00",19.5,27.6666666666667,0,452.666666666667,0.0038745638949831,0 +"6086","2015-02-08 23:16:00",19.5,27.6,0,452,0.00386516957975751,0 +"6087","2015-02-08 23:17:00",19.5,27.6,0,454,0.00386516957975751,0 +"6088","2015-02-08 23:18:00",19.5,27.6,0,448,0.00386516957975751,0 +"6089","2015-02-08 23:19:00",19.5,27.6,0,453.5,0.00386516957975751,0 +"6090","2015-02-08 23:19:59",19.5,27.6,0,451,0.00386516957975751,0 +"6091","2015-02-08 23:21:00",19.4633333333333,27.5666666666667,0,447,0.00385162465225822,0 +"6092","2015-02-08 23:22:00",19.5,27.6,0,452.333333333333,0.00386516957975751,0 +"6093","2015-02-08 23:23:00",19.5,27.6,0,455.666666666667,0.00386516957975751,0 +"6094","2015-02-08 23:23:59",19.5,27.55,0,446,0.0038581240284089,0 +"6095","2015-02-08 23:25:00",19.4633333333333,27.4966666666667,0,448.333333333333,0.00384178381809175,0 +"6096","2015-02-08 23:25:59",19.5,27.5,0,452.5,0.00385107863568625,0 +"6097","2015-02-08 23:26:59",19.5,27.5,0,455,0.00385107863568625,0 +"6098","2015-02-08 23:28:00",19.5,27.4266666666667,0,451.333333333333,0.00384074567995193,0 +"6099","2015-02-08 23:29:00",19.5,27.39,0,450.333333333333,0.00383557933003345,0 +"6100","2015-02-08 23:30:00",19.5,27.39,0,451,0.00383557933003345,0 +"6101","2015-02-08 23:31:00",19.5,27.39,0,449.5,0.00383557933003345,0 +"6102","2015-02-08 23:31:59",19.5,27.39,0,448.5,0.00383557933003345,0 +"6103","2015-02-08 23:32:59",19.5,27.34,0,447.5,0.00382853444487792,0 +"6104","2015-02-08 23:34:00",19.5,27.29,0,447,0.00382148971832586,0 +"6105","2015-02-08 23:35:00",19.5,27.29,0,450,0.00382148971832586,0 +"6106","2015-02-08 23:36:00",19.5,27.2,0,459,0.0038088096101958,0 +"6107","2015-02-08 23:37:00",19.5,27.2,0,453,0.0038088096101958,0 +"6108","2015-02-08 23:38:00",19.5,27.2,0,454.333333333333,0.0038088096101958,0 +"6109","2015-02-08 23:38:59",19.5,27.2,0,455.5,0.0038088096101958,0 +"6110","2015-02-08 23:39:59",19.5,27.2,0,457.666666666667,0.0038088096101958,0 +"6111","2015-02-08 23:41:00",19.5,27.2,0,452,0.0038088096101958,0 +"6112","2015-02-08 23:42:00",19.5,27.2,0,452.666666666667,0.0038088096101958,0 +"6113","2015-02-08 23:43:00",19.5,27.2,0,453,0.0038088096101958,0 +"6114","2015-02-08 23:44:00",19.5,27.2,0,460,0.0038088096101958,0 +"6115","2015-02-08 23:44:59",19.5,27.2,0,455,0.0038088096101958,0 +"6116","2015-02-08 23:45:59",19.5,27.2,0,453,0.0038088096101958,0 +"6117","2015-02-08 23:47:00",19.5,27.2,0,454.5,0.0038088096101958,0 +"6118","2015-02-08 23:48:00",19.5,27.2,0,450.5,0.0038088096101958,0 +"6119","2015-02-08 23:49:00",19.5,27.1666666666667,0,452.666666666667,0.00380411340424797,0 +"6120","2015-02-08 23:50:00",19.5,27.1,0,454,0.00379472120379726,0 +"6121","2015-02-08 23:51:00",19.5,27.1,0,448,0.00379472120379726,0 +"6122","2015-02-08 23:51:59",19.5,27.1,0,454,0.00379472120379726,0 +"6123","2015-02-08 23:53:00",19.5,27.1,0,459.5,0.00379472120379726,0 +"6124","2015-02-08 23:54:00",19.5,27.1,0,462,0.00379472120379726,0 +"6125","2015-02-08 23:55:00",19.5,27.1,0,461,0.00379472120379726,0 +"6126","2015-02-08 23:55:59",19.5,27,0,456,0.00378063343170978,0 +"6127","2015-02-08 23:57:00",19.5,27.1,0,456,0.00379472120379726,0 +"6128","2015-02-08 23:57:59",19.5,27.1,0,459,0.00379472120379726,0 +"6129","2015-02-08 23:58:59",19.5,27.1,0,458,0.00379472120379726,0 +"6130","2015-02-09 00:00:00",19.5,27.1,0,459,0.00379472120379726,0 +"6131","2015-02-09 00:01:00",19.5,27.1,0,459,0.00379472120379726,0 +"6132","2015-02-09 00:02:00",19.5,27.1,0,458,0.00379472120379726,0 +"6133","2015-02-09 00:03:00",19.5,27.1,0,457,0.00379472120379726,0 +"6134","2015-02-09 00:04:00",19.5,27,0,458,0.00378063343170978,0 +"6135","2015-02-09 00:04:59",19.5,27,0,456.5,0.00378063343170978,0 +"6136","2015-02-09 00:06:00",19.5,27,0,455,0.00378063343170978,0 +"6137","2015-02-09 00:07:00",19.5,27.1,0,460,0.00379472120379726,0 +"6138","2015-02-09 00:08:00",19.5,27.05,0,456.5,0.00378767723846731,0 +"6139","2015-02-09 00:08:59",19.5,27,0,456.5,0.00378063343170978,0 +"6140","2015-02-09 00:10:00",19.5,27,0,456,0.00378063343170978,0 +"6141","2015-02-09 00:10:59",19.5,27,0,461,0.00378063343170978,0 +"6142","2015-02-09 00:11:59",19.5,27.0333333333333,0,459,0.00378532928526258,0 +"6143","2015-02-09 00:13:00",19.5,27.05,0,456.5,0.00378767723846731,0 +"6144","2015-02-09 00:14:00",19.5,27.0333333333333,0,454.666666666667,0.00378532928526258,0 +"6145","2015-02-09 00:15:00",19.5,27,0,456,0.00378063343170978,0 +"6146","2015-02-09 00:16:00",19.5,27,0,461,0.00378063343170978,0 +"6147","2015-02-09 00:16:59",19.5,27,0,458,0.00378063343170978,0 +"6148","2015-02-09 00:17:59",19.5,27,0,460,0.00378063343170978,0 +"6149","2015-02-09 00:19:00",19.5,27,0,462,0.00378063343170978,0 +"6150","2015-02-09 00:20:00",19.5,27,0,462,0.00378063343170978,0 +"6151","2015-02-09 00:21:00",19.5,27,0,451.5,0.00378063343170978,0 +"6152","2015-02-09 00:22:00",19.5,26.945,0,456.5,0.00377288542742124,0 +"6153","2015-02-09 00:23:00",19.5,26.89,0,459,0.00376513761499172,0 +"6154","2015-02-09 00:23:59",19.5,26.89,0,452,0.00376513761499172,0 +"6155","2015-02-09 00:24:59",19.5,26.89,0,455.333333333333,0.00376513761499172,0 +"6156","2015-02-09 00:26:00",19.5,26.89,0,467.5,0.00376513761499172,0 +"6157","2015-02-09 00:27:00",19.5,26.89,0,464.5,0.00376513761499172,0 +"6158","2015-02-09 00:28:00",19.5,26.89,0,459.333333333333,0.00376513761499172,0 +"6159","2015-02-09 00:29:00",19.5,26.89,0,457,0.00376513761499172,0 +"6160","2015-02-09 00:29:59",19.5,26.89,0,458,0.00376513761499172,0 +"6161","2015-02-09 00:30:59",19.5,26.89,0,457,0.00376513761499172,0 +"6162","2015-02-09 00:32:00",19.4266666666667,26.89,0,460,0.00374789893607631,0 +"6163","2015-02-09 00:33:00",19.39,26.89,0,466,0.00373930574168329,0 +"6164","2015-02-09 00:34:00",19.445,26.89,0,463,0.00375220206382535,0 +"6165","2015-02-09 00:35:00",19.445,26.89,0,459.5,0.00375220206382535,0 +"6166","2015-02-09 00:36:00",19.39,26.79,0,463,0.00372531652116727,0 +"6167","2015-02-09 00:36:59",19.445,26.89,0,462.5,0.00375220206382535,0 +"6168","2015-02-09 00:38:00",19.39,26.84,0,461,0.00373231105323758,0 +"6169","2015-02-09 00:39:00",19.39,26.84,0,463.5,0.00373231105323758,0 +"6170","2015-02-09 00:40:00",19.39,26.79,0,462.5,0.00372531652116727,0 +"6171","2015-02-09 00:40:59",19.39,26.79,0,462.5,0.00372531652116727,0 +"6172","2015-02-09 00:42:00",19.39,26.84,0,459,0.00373231105323758,0 +"6173","2015-02-09 00:42:59",19.39,26.79,0,464,0.00372531652116727,0 +"6174","2015-02-09 00:43:59",19.39,26.84,0,461,0.00373231105323758,0 +"6175","2015-02-09 00:45:00",19.39,26.79,0,464,0.00372531652116727,0 +"6176","2015-02-09 00:46:00",19.39,26.79,0,468.333333333333,0.00372531652116727,0 +"6177","2015-02-09 00:47:00",19.39,26.79,0,467,0.00372531652116727,0 +"6178","2015-02-09 00:48:00",19.39,26.79,0,459,0.00372531652116727,0 +"6179","2015-02-09 00:49:00",19.39,26.79,0,462,0.00372531652116727,0 +"6180","2015-02-09 00:49:59",19.39,26.79,0,458,0.00372531652116727,0 +"6181","2015-02-09 00:51:00",19.39,26.79,0,458,0.00372531652116727,0 +"6182","2015-02-09 00:52:00",19.39,26.8233333333333,0,459.666666666667,0.00372997952517269,0 +"6183","2015-02-09 00:53:00",19.39,26.79,0,462,0.00372531652116727,0 +"6184","2015-02-09 00:53:59",19.39,26.79,0,462,0.00372531652116727,0 +"6185","2015-02-09 00:55:00",19.39,26.8233333333333,0,461.333333333333,0.00372997952517269,0 +"6186","2015-02-09 00:55:59",19.39,26.89,0,461,0.00373930574168329,0 +"6187","2015-02-09 00:56:59",19.39,26.89,0,461,0.00373930574168329,0 +"6188","2015-02-09 00:58:00",19.39,26.89,0,460,0.00373930574168329,0 +"6189","2015-02-09 00:59:00",19.39,26.89,0,459.666666666667,0.00373930574168329,0 +"6190","2015-02-09 01:00:00",19.39,26.89,0,462.5,0.00373930574168329,0 +"6191","2015-02-09 01:01:00",19.39,27,0,462.5,0.00375469460673115,0 +"6192","2015-02-09 01:01:59",19.5,27,0,463,0.00378063343170978,0 +"6193","2015-02-09 01:02:59",19.39,26.89,0,464,0.00373930574168329,0 +"6194","2015-02-09 01:04:00",19.39,27,0,466,0.00375469460673115,0 +"6195","2015-02-09 01:05:00",19.39,27,0,463,0.00375469460673115,0 +"6196","2015-02-09 01:06:00",19.39,27,0,461,0.00375469460673115,0 +"6197","2015-02-09 01:07:00",19.39,27.0666666666667,0,465.333333333333,0.00376402155999556,0 +"6198","2015-02-09 01:08:00",19.39,27.1,0,462,0.00376868514089311,0 +"6199","2015-02-09 01:08:59",19.39,27.1,0,458,0.00376868514089311,0 +"6200","2015-02-09 01:09:59",19.39,27.1,0,457,0.00376868514089311,0 +"6201","2015-02-09 01:11:00",19.39,27.1,0,460.5,0.00376868514089311,0 +"6202","2015-02-09 01:12:00",19.39,27.1,0,457,0.00376868514089311,0 +"6203","2015-02-09 01:13:00",19.39,27.1,0,459,0.00376868514089311,0 +"6204","2015-02-09 01:14:00",19.39,27.1,0,467.5,0.00376868514089311,0 +"6205","2015-02-09 01:14:59",19.39,27.1,0,468.5,0.00376868514089311,0 +"6206","2015-02-09 01:15:59",19.5,27.2,0,464.5,0.0038088096101958,0 +"6207","2015-02-09 01:17:00",19.4633333333333,27.2,0,462.666666666667,0.00380008086052056,0 +"6208","2015-02-09 01:18:00",19.39,27.2,0,458,0.00378267630066579,0 +"6209","2015-02-09 01:19:00",19.445,27.2,0,458.5,0.00379572310890555,0 +"6210","2015-02-09 01:20:00",19.39,27.2,0,458.5,0.00378267630066579,0 +"6211","2015-02-09 01:21:00",19.4633333333333,27.23,0,462.333333333333,0.00380429776093848,0 +"6212","2015-02-09 01:21:59",19.5,27.29,0,464,0.00382148971832586,0 +"6213","2015-02-09 01:23:00",19.39,27.2,0,464,0.00378267630066579,0 +"6214","2015-02-09 01:24:00",19.4633333333333,27.26,0,459,0.00380851471818723,0 +"6215","2015-02-09 01:25:00",19.39,27.2,0,460,0.00378267630066579,0 +"6216","2015-02-09 01:25:59",19.5,27.29,0,465,0.00382148971832586,0 +"6217","2015-02-09 01:27:00",19.39,27.2,0,466.5,0.00378267630066579,0 +"6218","2015-02-09 01:27:59",19.445,27.2,0,467,0.00379572310890555,0 +"6219","2015-02-09 01:28:59",19.5,27.29,0,459,0.00382148971832586,0 +"6220","2015-02-09 01:30:00",19.4633333333333,27.26,0,456.666666666667,0.00380851471818723,0 +"6221","2015-02-09 01:31:00",19.445,27.245,0,459.5,0.00380204118313949,0 +"6222","2015-02-09 01:32:00",19.445,27.245,0,464,0.00380204118313949,0 +"6223","2015-02-09 01:33:00",19.445,27.2,0,465,0.00379572310890555,0 +"6224","2015-02-09 01:34:00",19.5,27.29,0,464,0.00382148971832586,0 +"6225","2015-02-09 01:34:59",19.445,27.245,0,463,0.00380204118313949,0 +"6226","2015-02-09 01:36:00",19.39,27.2,0,462,0.00378267630066579,0 +"6227","2015-02-09 01:37:00",19.39,27.2,0,461,0.00378267630066579,0 +"6228","2015-02-09 01:38:00",19.39,27.2,0,460,0.00378267630066579,0 +"6229","2015-02-09 01:38:59",19.39,27.2,0,459,0.00378267630066579,0 +"6230","2015-02-09 01:40:00",19.39,27.2,0,464.5,0.00378267630066579,0 +"6231","2015-02-09 01:40:59",19.39,27.2,0,465.5,0.00378267630066579,0 +"6232","2015-02-09 01:41:59",19.39,27.2,0,463,0.00378267630066579,0 +"6233","2015-02-09 01:43:00",19.39,27.2,0,462.333333333333,0.00378267630066579,0 +"6234","2015-02-09 01:44:00",19.39,27.2,0,463,0.00378267630066579,0 +"6235","2015-02-09 01:45:00",19.39,27.2,0,466,0.00378267630066579,0 +"6236","2015-02-09 01:46:00",19.39,27.2,0,466,0.00378267630066579,0 +"6237","2015-02-09 01:46:59",19.34,27.2,0,462.5,0.00377084992276213,0 +"6238","2015-02-09 01:47:59",19.34,27.2,0,457,0.00377084992276213,0 +"6239","2015-02-09 01:49:00",19.39,27.2,0,458.666666666667,0.00378267630066579,0 +"6240","2015-02-09 01:50:00",19.29,27.2,0,464,0.00375905618509829,0 +"6241","2015-02-09 01:51:00",19.34,27.2,0,467,0.00377084992276213,0 +"6242","2015-02-09 01:52:00",19.3566666666667,27.2,0,464.333333333333,0.0037747884181893,0 +"6243","2015-02-09 01:53:00",19.39,27.2,0,457,0.00378267630066579,0 +"6244","2015-02-09 01:53:59",19.39,27.2,0,456,0.00378267630066579,0 +"6245","2015-02-09 01:54:59",19.39,27.2,0,464,0.00378267630066579,0 +"6246","2015-02-09 01:56:00",19.39,27.1666666666667,0,468,0.00377801251122667,0 +"6247","2015-02-09 01:57:00",19.39,27.1,0,468.5,0.00376868514089311,0 +"6248","2015-02-09 01:58:00",19.39,27.1,0,466,0.00376868514089311,0 +"6249","2015-02-09 01:59:00",19.39,27.1,0,465,0.00376868514089311,0 +"6250","2015-02-09 01:59:59",19.39,27.1,0,470,0.00376868514089311,0 +"6251","2015-02-09 02:00:59",19.39,27.1,0,466.5,0.00376868514089311,0 +"6252","2015-02-09 02:02:00",19.39,27.1,0,467.5,0.00376868514089311,0 +"6253","2015-02-09 02:03:00",19.39,27.1,0,465,0.00376868514089311,0 +"6254","2015-02-09 02:04:00",19.39,27.1,0,464.5,0.00376868514089311,0 +"6255","2015-02-09 02:05:00",19.39,27.05,0,466,0.00376168979561341,0 +"6256","2015-02-09 02:06:00",19.39,27.0333333333333,0,464.666666666667,0.00375935804860876,0 +"6257","2015-02-09 02:06:59",19.39,27.05,0,464.5,0.00376168979561341,0 +"6258","2015-02-09 02:08:00",19.39,27,0,467.5,0.00375469460673115,0 +"6259","2015-02-09 02:09:00",19.445,26.995,0,470,0.00376694238501795,0 +"6260","2015-02-09 02:10:00",19.39,26.89,0,472,0.00373930574168329,0 +"6261","2015-02-09 02:10:59",19.39,26.89,0,472,0.00373930574168329,0 +"6262","2015-02-09 02:12:00",19.39,26.89,0,471,0.00373930574168329,0 +"6263","2015-02-09 02:12:59",19.39,26.89,0,463.5,0.00373930574168329,0 +"6264","2015-02-09 02:13:59",19.39,26.89,0,467,0.00373930574168329,0 +"6265","2015-02-09 02:15:00",19.39,26.89,0,466,0.00373930574168329,0 +"6266","2015-02-09 02:16:00",19.39,26.89,0,470.5,0.00373930574168329,0 +"6267","2015-02-09 02:17:00",19.39,26.89,0,469,0.00373930574168329,0 +"6268","2015-02-09 02:18:00",19.39,26.89,0,467,0.00373930574168329,0 +"6269","2015-02-09 02:19:00",19.39,26.89,0,471,0.00373930574168329,0 +"6270","2015-02-09 02:19:59",19.39,26.89,0,473,0.00373930574168329,0 +"6271","2015-02-09 02:21:00",19.39,26.84,0,473,0.00373231105323758,0 +"6272","2015-02-09 02:22:00",19.39,26.89,0,474,0.00373930574168329,0 +"6273","2015-02-09 02:23:00",19.39,26.8233333333333,0,466,0.00372997952517269,0 +"6274","2015-02-09 02:23:59",19.39,26.815,0,467,0.00372881376765582,0 +"6275","2015-02-09 02:25:00",19.39,26.79,0,469,0.00372531652116727,0 +"6276","2015-02-09 02:25:59",19.39,26.79,0,471,0.00372531652116727,0 +"6277","2015-02-09 02:26:59",19.39,26.79,0,471,0.00372531652116727,0 +"6278","2015-02-09 02:28:00",19.39,26.745,0,472.5,0.00371902157600063,0 +"6279","2015-02-09 02:29:00",19.39,26.745,0,472,0.00371902157600063,0 +"6280","2015-02-09 02:30:00",19.39,26.7,0,472,0.00371272675749,0 +"6281","2015-02-09 02:31:00",19.39,26.7,0,472,0.00371272675749,0 +"6282","2015-02-09 02:31:59",19.39,26.7,0,471,0.00371272675749,0 +"6283","2015-02-09 02:32:59",19.39,26.7,0,468,0.00371272675749,0 +"6284","2015-02-09 02:34:00",19.39,26.7,0,470,0.00371272675749,0 +"6285","2015-02-09 02:35:00",19.39,26.7,0,469,0.00371272675749,0 +"6286","2015-02-09 02:36:00",19.39,26.7,0,470.333333333333,0.00371272675749,0 +"6287","2015-02-09 02:37:00",19.39,26.7,0,471,0.00371272675749,0 +"6288","2015-02-09 02:38:00",19.39,26.7,0,471.5,0.00371272675749,0 +"6289","2015-02-09 02:38:59",19.39,26.7,0,470,0.00371272675749,0 +"6290","2015-02-09 02:39:59",19.39,26.7,0,468,0.00371272675749,0 +"6291","2015-02-09 02:41:00",19.39,26.7,0,469,0.00371272675749,0 +"6292","2015-02-09 02:42:00",19.39,26.65,0,472,0.00370573266324294,0 +"6293","2015-02-09 02:43:00",19.39,26.7,0,474,0.00371272675749,0 +"6294","2015-02-09 02:44:00",19.39,26.7,0,468,0.00371272675749,0 +"6295","2015-02-09 02:44:59",19.39,26.65,0,470.5,0.00370573266324294,0 +"6296","2015-02-09 02:45:59",19.39,26.7,0,470.5,0.00371272675749,0 +"6297","2015-02-09 02:47:00",19.39,26.65,0,468,0.00370573266324294,0 +"6298","2015-02-09 02:48:00",19.445,26.65,0,468.5,0.00371851250863133,0 +"6299","2015-02-09 02:49:00",19.39,26.65,0,469,0.00370573266324294,0 +"6300","2015-02-09 02:50:00",19.39,26.6666666666667,0,471.333333333333,0.00370806401061887,0 +"6301","2015-02-09 02:51:00",19.39,26.6,0,470.5,0.00369873872535136,0 +"6302","2015-02-09 02:51:59",19.39,26.6,0,472,0.00369873872535136,0 +"6303","2015-02-09 02:53:00",19.4633333333333,26.6666666666667,0,467.666666666667,0.00372512322655296,0 +"6304","2015-02-09 02:54:00",19.445,26.65,0,464,0.00371851250863133,0 +"6305","2015-02-09 02:55:00",19.39,26.6,0,467.5,0.00369873872535136,0 +"6306","2015-02-09 02:55:59",19.5,26.7,0,472,0.0037383739208854,0 +"6307","2015-02-09 02:57:00",19.5,26.7,0,473,0.0037383739208854,0 +"6308","2015-02-09 02:57:59",19.4266666666667,26.6333333333333,0,475.666666666667,0.00371191152725347,0 +"6309","2015-02-09 02:58:59",19.39,26.6666666666667,0,470.666666666667,0.00370806401061887,0 +"6310","2015-02-09 03:00:00",19.445,26.7,0,468.5,0.00372553086680987,0 +"6311","2015-02-09 03:01:00",19.39,26.7,0,470,0.00371272675749,0 +"6312","2015-02-09 03:02:00",19.39,26.7,0,469,0.00371272675749,0 +"6313","2015-02-09 03:03:00",19.39,26.7,0,468,0.00371272675749,0 +"6314","2015-02-09 03:04:00",19.39,26.7,0,465.333333333333,0.00371272675749,0 +"6315","2015-02-09 03:04:59",19.39,26.7,0,464,0.00371272675749,0 +"6316","2015-02-09 03:06:00",19.39,26.7,0,469.666666666667,0.00371272675749,0 +"6317","2015-02-09 03:07:00",19.39,26.7,0,471,0.00371272675749,0 +"6318","2015-02-09 03:08:00",19.39,26.7,0,473.333333333333,0.00371272675749,0 +"6319","2015-02-09 03:08:59",19.39,26.7,0,472,0.00371272675749,0 +"6320","2015-02-09 03:10:00",19.39,26.7,0,472,0.00371272675749,0 +"6321","2015-02-09 03:10:59",19.39,26.73,0,469.333333333333,0.00371692328909105,0 +"6322","2015-02-09 03:11:59",19.39,26.7,0,467,0.00371272675749,0 +"6323","2015-02-09 03:13:00",19.3566666666667,26.73,0,472.333333333333,0.00370917333176834,0 +"6324","2015-02-09 03:14:00",19.3566666666667,26.79,0,464.666666666667,0.00371754895959292,0 +"6325","2015-02-09 03:15:00",19.29,26.79,0,464.5,0.00370205669540882,0 +"6326","2015-02-09 03:16:00",19.29,26.79,0,464,0.00370205669540882,0 +"6327","2015-02-09 03:16:59",19.34,26.84,0,472,0.00372064307637585,0 +"6328","2015-02-09 03:17:59",19.29,26.79,0,471,0.00370205669540882,0 +"6329","2015-02-09 03:19:00",19.29,26.79,0,466,0.00370205669540882,0 +"6330","2015-02-09 03:20:00",19.29,26.79,0,467.666666666667,0.00370205669540882,0 +"6331","2015-02-09 03:21:00",19.29,26.79,0,470,0.00370205669540882,0 +"6332","2015-02-09 03:22:00",19.29,26.79,0,469,0.00370205669540882,0 +"6333","2015-02-09 03:23:00",19.29,26.8566666666667,0,467.666666666667,0.00371132419814892,0 +"6334","2015-02-09 03:23:59",19.29,26.84,0,472,0.00370900729672692,0 +"6335","2015-02-09 03:24:59",19.29,26.79,0,473,0.00370205669540882,0 +"6336","2015-02-09 03:26:00",19.34,26.79,0,472,0.00371367054043556,0 +"6337","2015-02-09 03:27:00",19.34,26.79,0,472,0.00371367054043556,0 +"6338","2015-02-09 03:28:00",19.34,26.79,0,471,0.00371367054043556,0 +"6339","2015-02-09 03:29:00",19.39,26.79,0,467,0.00372531652116727,0 +"6340","2015-02-09 03:29:59",19.34,26.79,0,471,0.00371367054043556,0 +"6341","2015-02-09 03:30:59",19.29,26.79,0,474,0.00370205669540882,0 +"6342","2015-02-09 03:32:00",19.39,26.7,0,478,0.00371272675749,0 +"6343","2015-02-09 03:33:00",19.39,26.7,0,472,0.00371272675749,0 +"6344","2015-02-09 03:34:00",19.39,26.7,0,475,0.00371272675749,0 +"6345","2015-02-09 03:35:00",19.39,26.7,0,476,0.00371272675749,0 +"6346","2015-02-09 03:36:00",19.39,26.7,0,472,0.00371272675749,0 +"6347","2015-02-09 03:36:59",19.39,26.7,0,479,0.00371272675749,0 +"6348","2015-02-09 03:38:00",19.39,26.7,0,479,0.00371272675749,0 +"6349","2015-02-09 03:39:00",19.39,26.6666666666667,0,471,0.00370806401061887,0 +"6350","2015-02-09 03:40:00",19.39,26.7,0,466,0.00371272675749,0 +"6351","2015-02-09 03:40:59",19.39,26.65,0,466.5,0.00370573266324294,0 +"6352","2015-02-09 03:42:00",19.39,26.7,0,469,0.00371272675749,0 +"6353","2015-02-09 03:42:59",19.34,26.7,0,471,0.00370112036732517,0 +"6354","2015-02-09 03:43:59",19.34,26.7,0,469,0.00370112036732517,0 +"6355","2015-02-09 03:45:00",19.34,26.7,0,468.5,0.00370112036732517,0 +"6356","2015-02-09 03:46:00",19.39,26.7,0,468,0.00371272675749,0 +"6357","2015-02-09 03:47:00",19.29,26.7,0,470.5,0.00368954600216578,0 +"6358","2015-02-09 03:48:00",19.39,26.7,0,472,0.00371272675749,0 +"6359","2015-02-09 03:49:00",19.39,26.7,0,474,0.00371272675749,0 +"6360","2015-02-09 03:49:59",19.39,26.6,0,466,0.00369873872535136,0 +"6361","2015-02-09 03:51:00",19.39,26.65,0,466,0.00370573266324294,0 +"6362","2015-02-09 03:52:00",19.39,26.7,0,466,0.00371272675749,0 +"6363","2015-02-09 03:53:00",19.3566666666667,26.6,0,468,0.00369102690734661,0 +"6364","2015-02-09 03:53:59",19.39,26.6,0,471.333333333333,0.00369873872535136,0 +"6365","2015-02-09 03:55:00",19.39,26.6666666666667,0,471.666666666667,0.00370806401061887,0 +"6366","2015-02-09 03:55:59",19.34,26.65,0,469.5,0.00369414826646692,0 +"6367","2015-02-09 03:56:59",19.39,26.7,0,473,0.00371272675749,0 +"6368","2015-02-09 03:58:00",19.39,26.7,0,472,0.00371272675749,0 +"6369","2015-02-09 03:59:00",19.29,26.7,0,468,0.00368954600216578,0 +"6370","2015-02-09 04:00:00",19.34,26.7,0,465,0.00370112036732517,0 +"6371","2015-02-09 04:01:00",19.39,26.7,0,467,0.00371272675749,0 +"6372","2015-02-09 04:01:59",19.34,26.7,0,471.5,0.00370112036732517,0 +"6373","2015-02-09 04:02:59",19.39,26.7,0,467,0.00371272675749,0 +"6374","2015-02-09 04:04:00",19.3566666666667,26.7,0,472,0.00370498560194032,0 +"6375","2015-02-09 04:05:00",19.39,26.7,0,468,0.00371272675749,0 +"6376","2015-02-09 04:06:00",19.39,26.7,0,468,0.00371272675749,0 +"6377","2015-02-09 04:07:00",19.39,26.7,0,466,0.00371272675749,0 +"6378","2015-02-09 04:08:00",19.39,26.7,0,469.666666666667,0.00371272675749,0 +"6379","2015-02-09 04:08:59",19.39,26.7,0,467,0.00371272675749,0 +"6380","2015-02-09 04:09:59",19.39,26.7,0,464,0.00371272675749,0 +"6381","2015-02-09 04:11:00",19.39,26.7,0,469.5,0.00371272675749,0 +"6382","2015-02-09 04:12:00",19.39,26.7,0,473,0.00371272675749,0 +"6383","2015-02-09 04:13:00",19.39,26.7,0,468,0.00371272675749,0 +"6384","2015-02-09 04:14:00",19.29,26.7,0,466.5,0.00368954600216578,0 +"6385","2015-02-09 04:14:59",19.39,26.7,0,462.5,0.00371272675749,0 +"6386","2015-02-09 04:15:59",19.39,26.7,0,473,0.00371272675749,0 +"6387","2015-02-09 04:17:00",19.29,26.7,0,472.5,0.00368954600216578,0 +"6388","2015-02-09 04:18:00",19.29,26.7,0,471,0.00368954600216578,0 +"6389","2015-02-09 04:19:00",19.29,26.7,0,473.5,0.00368954600216578,0 +"6390","2015-02-09 04:20:00",19.29,26.7,0,470,0.00368954600216578,0 +"6391","2015-02-09 04:21:00",19.29,26.7,0,471,0.00368954600216578,0 +"6392","2015-02-09 04:21:59",19.29,26.79,0,470,0.00370205669540882,0 +"6393","2015-02-09 04:23:00",19.29,26.79,0,470,0.00370205669540882,0 +"6394","2015-02-09 04:24:00",19.29,26.79,0,470.5,0.00370205669540882,0 +"6395","2015-02-09 04:25:00",19.29,26.79,0,469,0.00370205669540882,0 +"6396","2015-02-09 04:25:59",19.29,26.79,0,470.5,0.00370205669540882,0 +"6397","2015-02-09 04:27:00",19.29,26.79,0,467,0.00370205669540882,0 +"6398","2015-02-09 04:27:59",19.29,26.79,0,469,0.00370205669540882,0 +"6399","2015-02-09 04:28:59",19.29,26.79,0,470.5,0.00370205669540882,0 +"6400","2015-02-09 04:30:00",19.29,26.79,0,466,0.00370205669540882,0 +"6401","2015-02-09 04:31:00",19.29,26.79,0,466,0.00370205669540882,0 +"6402","2015-02-09 04:32:00",19.29,26.79,0,466,0.00370205669540882,0 +"6403","2015-02-09 04:33:00",19.29,26.79,0,469.5,0.00370205669540882,0 +"6404","2015-02-09 04:34:00",19.29,26.89,0,469,0.00371595805246803,0 +"6405","2015-02-09 04:34:59",19.29,26.79,0,461,0.00370205669540882,0 +"6406","2015-02-09 04:36:00",19.29,26.89,0,465,0.00371595805246803,0 +"6407","2015-02-09 04:37:00",19.29,26.89,0,470.5,0.00371595805246803,0 +"6408","2015-02-09 04:38:00",19.29,26.89,0,471.5,0.00371595805246803,0 +"6409","2015-02-09 04:38:59",19.29,26.89,0,469,0.00371595805246803,0 +"6410","2015-02-09 04:40:00",19.29,26.89,0,473,0.00371595805246803,0 +"6411","2015-02-09 04:40:59",19.29,26.89,0,467,0.00371595805246803,0 +"6412","2015-02-09 04:41:59",19.29,26.89,0,468,0.00371595805246803,0 +"6413","2015-02-09 04:43:00",19.29,26.89,0,463,0.00371595805246803,0 +"6414","2015-02-09 04:44:00",19.29,26.89,0,463.666666666667,0.00371595805246803,0 +"6415","2015-02-09 04:45:00",19.29,26.89,0,458,0.00371595805246803,0 +"6416","2015-02-09 04:46:00",19.29,26.89,0,459,0.00371595805246803,0 +"6417","2015-02-09 04:46:59",19.34,26.89,0,462.5,0.00372761576771246,0 +"6418","2015-02-09 04:47:59",19.3233333333333,26.89,0,459.666666666667,0.00372372628212772,0 +"6419","2015-02-09 04:49:00",19.29,26.89,0,466,0.00371595805246803,0 +"6420","2015-02-09 04:50:00",19.29,26.89,0,466,0.00371595805246803,0 +"6421","2015-02-09 04:51:00",19.29,26.89,0,465.5,0.00371595805246803,0 +"6422","2015-02-09 04:52:00",19.29,26.89,0,466.5,0.00371595805246803,0 +"6423","2015-02-09 04:53:00",19.29,26.89,0,467.5,0.00371595805246803,0 +"6424","2015-02-09 04:53:59",19.29,26.89,0,466,0.00371595805246803,0 +"6425","2015-02-09 04:54:59",19.29,26.89,0,463,0.00371595805246803,0 +"6426","2015-02-09 04:56:00",19.29,26.89,0,465.333333333333,0.00371595805246803,0 +"6427","2015-02-09 04:57:00",19.29,26.89,0,465,0.00371595805246803,0 +"6428","2015-02-09 04:58:00",19.29,26.89,0,466,0.00371595805246803,0 +"6429","2015-02-09 04:59:00",19.29,26.79,0,465,0.00370205669540882,0 +"6430","2015-02-09 04:59:59",19.39,26.79,0,468,0.00372531652116727,0 +"6431","2015-02-09 05:00:59",19.34,26.79,0,461.5,0.00371367054043556,0 +"6432","2015-02-09 05:02:00",19.39,26.79,0,460,0.00372531652116727,0 +"6433","2015-02-09 05:03:00",19.39,26.79,0,462.5,0.00372531652116727,0 +"6434","2015-02-09 05:04:00",19.39,26.79,0,468,0.00372531652116727,0 +"6435","2015-02-09 05:05:00",19.39,26.79,0,467.5,0.00372531652116727,0 +"6436","2015-02-09 05:06:00",19.39,26.745,0,461,0.00371902157600063,0 +"6437","2015-02-09 05:06:59",19.39,26.7,0,464,0.00371272675749,0 +"6438","2015-02-09 05:08:00",19.39,26.745,0,467,0.00371902157600063,0 +"6439","2015-02-09 05:09:00",19.39,26.745,0,468,0.00371902157600063,0 +"6440","2015-02-09 05:10:00",19.39,26.7,0,465,0.00371272675749,0 +"6441","2015-02-09 05:10:59",19.39,26.7,0,465,0.00371272675749,0 +"6442","2015-02-09 05:12:00",19.39,26.7,0,458,0.00371272675749,0 +"6443","2015-02-09 05:12:59",19.39,26.7,0,461,0.00371272675749,0 +"6444","2015-02-09 05:13:59",19.39,26.7,0,466,0.00371272675749,0 +"6445","2015-02-09 05:15:00",19.445,26.745,0,464.5,0.00373184752378527,0 +"6446","2015-02-09 05:16:00",19.445,26.7,0,459.5,0.00372553086680987,0 +"6447","2015-02-09 05:17:00",19.39,26.7,0,457.333333333333,0.00371272675749,0 +"6448","2015-02-09 05:18:00",19.5,26.7,0,461,0.0037383739208854,0 +"6449","2015-02-09 05:19:00",19.5,26.7,0,460,0.0037383739208854,0 +"6450","2015-02-09 05:19:59",19.445,26.745,0,460.5,0.00373184752378527,0 +"6451","2015-02-09 05:21:00",19.5,26.7,0,461,0.0037383739208854,0 +"6452","2015-02-09 05:22:00",19.5,26.7,0,459,0.0037383739208854,0 +"6453","2015-02-09 05:23:00",19.5,26.7,0,460.5,0.0037383739208854,0 +"6454","2015-02-09 05:23:59",19.5,26.7,0,460.333333333333,0.0037383739208854,0 +"6455","2015-02-09 05:25:00",19.5,26.7,0,463,0.0037383739208854,0 +"6456","2015-02-09 05:25:59",19.5,26.7,0,466,0.0037383739208854,0 +"6457","2015-02-09 05:26:59",19.5,26.7,0,466.5,0.0037383739208854,0 +"6458","2015-02-09 05:28:00",19.5,26.7,0,463.5,0.0037383739208854,0 +"6459","2015-02-09 05:29:00",19.5,26.7,0,461.5,0.0037383739208854,0 +"6460","2015-02-09 05:30:00",19.6,26.7,0,461,0.00376182503753838,0 +"6461","2015-02-09 05:31:00",19.5,26.7,0,456,0.0037383739208854,0 +"6462","2015-02-09 05:31:59",19.5,26.7,0,460,0.0037383739208854,0 +"6463","2015-02-09 05:32:59",19.5,26.7,0,461,0.0037383739208854,0 +"6464","2015-02-09 05:34:00",19.5,26.7,0,461,0.0037383739208854,0 +"6465","2015-02-09 05:35:00",19.5,26.745,0,465,0.00374471248364312,0 +"6466","2015-02-09 05:36:00",19.5,26.7,0,466,0.0037383739208854,0 +"6467","2015-02-09 05:37:00",19.5,26.7,0,460,0.0037383739208854,0 +"6468","2015-02-09 05:38:00",19.5,26.79,0,459,0.00375105117481805,0 +"6469","2015-02-09 05:38:59",19.5,26.79,0,457.333333333333,0.00375105117481805,0 +"6470","2015-02-09 05:39:59",19.5,26.89,0,456,0.00376513761499172,0 +"6471","2015-02-09 05:41:00",19.4633333333333,26.8566666666667,0,462.333333333333,0.00375182482450967,0 +"6472","2015-02-09 05:42:00",19.39,26.79,0,462,0.00372531652116727,0 +"6473","2015-02-09 05:43:00",19.4266666666667,26.8566666666667,0,464.333333333333,0.00374322501272601,0 +"6474","2015-02-09 05:44:00",19.39,26.84,0,458.5,0.00373231105323758,0 +"6475","2015-02-09 05:44:59",19.39,26.84,0,461,0.00373231105323758,0 +"6476","2015-02-09 05:45:59",19.39,26.84,0,461.5,0.00373231105323758,0 +"6477","2015-02-09 05:47:00",19.39,26.84,0,465,0.00373231105323758,0 +"6478","2015-02-09 05:48:00",19.39,26.79,0,465,0.00372531652116727,0 +"6479","2015-02-09 05:49:00",19.39,26.79,0,461,0.00372531652116727,0 +"6480","2015-02-09 05:50:00",19.39,26.76,0,461,0.0037211198769831,0 +"6481","2015-02-09 05:51:00",19.39,26.7,0,460,0.00371272675749,0 +"6482","2015-02-09 05:51:59",19.39,26.79,0,462,0.00372531652116727,0 +"6483","2015-02-09 05:53:00",19.39,26.79,0,465.333333333333,0.00372531652116727,0 +"6484","2015-02-09 05:54:00",19.39,26.79,0,465,0.00372531652116727,0 +"6485","2015-02-09 05:55:00",19.39,26.79,0,466.5,0.00372531652116727,0 +"6486","2015-02-09 05:55:59",19.39,26.79,0,462.666666666667,0.00372531652116727,0 +"6487","2015-02-09 05:57:00",19.39,26.79,0,460,0.00372531652116727,0 +"6488","2015-02-09 05:57:59",19.39,26.79,0,457,0.00372531652116727,0 +"6489","2015-02-09 05:58:59",19.39,26.7,0,463.5,0.00371272675749,0 +"6490","2015-02-09 06:00:00",19.39,26.7,0,466,0.00371272675749,0 +"6491","2015-02-09 06:01:00",19.445,26.795,0,466.5,0.00373886618111249,0 +"6492","2015-02-09 06:02:00",19.39,26.7,0,467.333333333333,0.00371272675749,0 +"6493","2015-02-09 06:03:00",19.39,26.7,0,469.5,0.00371272675749,0 +"6494","2015-02-09 06:04:00",19.445,26.7,0,462,0.00372553086680987,0 +"6495","2015-02-09 06:04:59",19.4266666666667,26.6666666666667,0,460,0.00371658498282815,0 +"6496","2015-02-09 06:06:00",19.5,26.6,0,463,0.00372428868561385,0 +"6497","2015-02-09 06:07:00",19.5,26.65,0,459,0.00373133122398483,0 +"6498","2015-02-09 06:08:00",19.5,26.5,0,460,0.00371020408443922,0 +"6499","2015-02-09 06:08:59",19.5,26.5666666666667,0,453,0.00371959374810254,0 +"6500","2015-02-09 06:10:00",19.5,26.55,0,461.666666666667,0.0037172463057671,0 +"6501","2015-02-09 06:10:59",19.5,26.5,0,463,0.00371020408443922,0 +"6502","2015-02-09 06:11:59",19.5,26.5,0,467,0.00371020408443922,0 +"6503","2015-02-09 06:13:00",19.5,26.5,0,464.5,0.00371020408443922,0 +"6504","2015-02-09 06:14:00",19.5,26.5,0,470,0.00371020408443922,0 +"6505","2015-02-09 06:15:00",19.5,26.5,0,466.5,0.00371020408443922,0 +"6506","2015-02-09 06:16:00",19.445,26.445,0,465,0.00368973888606677,0 +"6507","2015-02-09 06:16:59",19.39,26.4633333333333,0,460.333333333333,0.00367962275949924,0 +"6508","2015-02-09 06:17:59",19.39,26.445,0,461.5,0.0036770585114699,0 +"6509","2015-02-09 06:19:00",19.39,26.39,0,461,0.00366936589349026,0 +"6510","2015-02-09 06:20:00",19.39,26.39,0,463,0.00366936589349026,0 +"6511","2015-02-09 06:21:00",19.39,26.39,0,467.5,0.00366936589349026,0 +"6512","2015-02-09 06:22:00",19.39,26.39,0,471,0.00366936589349026,0 +"6513","2015-02-09 06:23:00",19.39,26.39,0,461,0.00366936589349026,0 +"6514","2015-02-09 06:23:59",19.39,26.39,0,456.333333333333,0.00366936589349026,0 +"6515","2015-02-09 06:24:59",19.39,26.39,0,459.5,0.00366936589349026,0 +"6516","2015-02-09 06:26:00",19.39,26.34,0,464.5,0.00366237276856267,0 +"6517","2015-02-09 06:27:00",19.39,26.29,0,467,0.00365537979995807,0 +"6518","2015-02-09 06:28:00",19.39,26.29,0,469,0.00365537979995807,0 +"6519","2015-02-09 06:29:00",19.39,26.29,0,465.5,0.00365537979995807,0 +"6520","2015-02-09 06:29:59",19.39,26.29,0,464,0.00365537979995807,0 +"6521","2015-02-09 06:30:59",19.39,26.29,0,464,0.00365537979995807,0 +"6522","2015-02-09 06:32:00",19.39,26.29,0,465.5,0.00365537979995807,0 +"6523","2015-02-09 06:33:00",19.34,26.29,0,466.5,0.0036439537266872,0 +"6524","2015-02-09 06:34:00",19.39,26.29,0,463,0.00365537979995807,0 +"6525","2015-02-09 06:35:00",19.39,26.29,0,461.75,0.00365537979995807,0 +"6526","2015-02-09 06:36:00",19.39,26.29,0,460.5,0.00365537979995807,0 +"6527","2015-02-09 06:36:59",19.29,26.39,0,459.5,0.00364645744347464,0 +"6528","2015-02-09 06:38:00",19.29,26.29,0,467,0.00363255917436095,0 +"6529","2015-02-09 06:39:00",19.29,26.29,0,468,0.00363255917436095,0 +"6530","2015-02-09 06:40:00",19.29,26.39,0,469,0.00364645744347464,0 +"6531","2015-02-09 06:40:59",19.29,26.34,0,465.5,0.00363950823173202,0 +"6532","2015-02-09 06:42:00",19.29,26.29,0,458,0.00363255917436095,0 +"6533","2015-02-09 06:42:59",19.39,26.29,0,458,0.00365537979995807,0 +"6534","2015-02-09 06:43:59",19.39,26.29,0,466,0.00365537979995807,0 +"6535","2015-02-09 06:45:00",19.29,26.26,0,465,0.00362838981403452,0 +"6536","2015-02-09 06:46:00",19.29,26.2,0,465,0.00362005126009293,0 +"6537","2015-02-09 06:47:00",19.29,26.2,0,465,0.00362005126009293,0 +"6538","2015-02-09 06:48:00",19.29,26.2,0,461.5,0.00362005126009293,0 +"6539","2015-02-09 06:49:00",19.29,26.2,0,461.5,0.00362005126009293,0 +"6540","2015-02-09 06:49:59",19.29,26.2,0,463,0.00362005126009293,0 +"6541","2015-02-09 06:51:00",19.34,26.2,0,465.5,0.00363140635006537,0 +"6542","2015-02-09 06:52:00",19.29,26.2,0,466,0.00362005126009293,0 +"6543","2015-02-09 06:53:00",19.29,26.2,0,466.5,0.00362005126009293,0 +"6544","2015-02-09 06:53:59",19.3233333333333,26.2,0,466.333333333333,0.00362761783373232,0 +"6545","2015-02-09 06:55:00",19.34,26.15,0,469,0.00362443580273919,0 +"6546","2015-02-09 06:55:59",19.29,26.1,0,469,0.00360615416412876,0 +"6547","2015-02-09 06:56:59",19.29,26.1,0,463,0.00360615416412876,0 +"6548","2015-02-09 06:58:00",19.29,26.1,0,468,0.00360615416412876,0 +"6549","2015-02-09 06:59:00",19.29,26.1,0,468.5,0.00360615416412876,0 +"6550","2015-02-09 07:00:00",19.34,26.1,0,470.5,0.00361746541073764,0 +"6551","2015-02-09 07:01:00",19.29,26.1,0,471,0.00360615416412876,0 +"6552","2015-02-09 07:01:59",19.29,26.1,0,470,0.00360615416412876,0 +"6553","2015-02-09 07:02:59",19.29,26.1,0,469,0.00360615416412876,0 +"6554","2015-02-09 07:04:00",19.34,26.05,0,468.5,0.00361049517405556,0 +"6555","2015-02-09 07:05:00",19.29,26.1,0,463.5,0.00360615416412876,0 +"6556","2015-02-09 07:06:00",19.29,26.1,0,466,0.00360615416412876,0 +"6557","2015-02-09 07:07:00",19.29,26.1,0,467.5,0.00360615416412876,0 +"6558","2015-02-09 07:08:00",19.29,26.1,0,467,0.00360615416412876,0 +"6559","2015-02-09 07:08:59",19.29,26.1,0,467,0.00360615416412876,0 +"6560","2015-02-09 07:09:59",19.3233333333333,26.0333333333333,0,469,0.00360440765943935,0 +"6561","2015-02-09 07:11:00",19.34,26,0,468.5,0.00360352509268773,0 +"6562","2015-02-09 07:12:00",19.39,26,0,466,0.00361482366447177,0 +"6563","2015-02-09 07:13:00",19.39,25.945,0,464.5,0.00360713257674529,0 +"6564","2015-02-09 07:14:00",19.39,26,0,469,0.00361482366447177,0 +"6565","2015-02-09 07:14:59",19.39,25.89,0,469,0.00359944167811953,0 +"6566","2015-02-09 07:15:59",19.39,25.89,0,471,0.00359944167811953,0 +"6567","2015-02-09 07:17:00",19.39,25.89,0,472,0.00359944167811953,0 +"6568","2015-02-09 07:18:00",19.445,25.945,0,473.5,0.00361957041601978,0 +"6569","2015-02-09 07:19:00",19.39,25.89,0,473.5,0.00359944167811953,0 +"6570","2015-02-09 07:20:00",19.39,25.89,0,473.666666666667,0.00359944167811953,0 +"6571","2015-02-09 07:21:00",19.39,25.89,0,473,0.00359944167811953,0 +"6572","2015-02-09 07:21:59",19.445,25.945,0,471.5,0.00361957041601978,0 +"6573","2015-02-09 07:23:00",19.39,26,0,463,0.00361482366447177,0 +"6574","2015-02-09 07:24:00",19.39,25.945,0,468,0.00360713257674529,0 +"6575","2015-02-09 07:25:00",19.445,26,0,470.5,0.00362728817733071,0 +"6576","2015-02-09 07:25:59",19.39,26,0,471,0.00361482366447177,0 +"6577","2015-02-09 07:27:00",19.5,26.15,0,471,0.00366091297322309,0 +"6578","2015-02-09 07:27:59",19.445,26.1,0,467,0.00364132095847566,0 +"6579","2015-02-09 07:28:59",19.5,26.15,0,468,0.00366091297322309,0 +"6580","2015-02-09 07:30:00",19.4266666666667,26.0333333333333,0,467,0.00362780126311498,0 +"6581","2015-02-09 07:31:00",19.5,26.1,0,467,0.00365387201985357,0 +"6582","2015-02-09 07:32:00",19.39,26.1,0,466,0.00362880794483372,0 +"6583","2015-02-09 07:33:00",19.4266666666667,26.1333333333333,0,468.333333333333,0.00364181807010568,0 +"6584","2015-02-09 07:34:00",19.39,26.1,0,465.5,0.00362880794483372,0 +"6585","2015-02-09 07:34:59",19.39,26.1,0,465.5,0.00362880794483372,0 +"6586","2015-02-09 07:36:00",19.39,26.1,0,468,0.00362880794483372,0 +"6587","2015-02-09 07:37:00",19.5,26.2,0,466,0.00366795408506867,0 +"6588","2015-02-09 07:38:00",19.4266666666667,26.2,0,471,0.00365116295703576,0 +"6589","2015-02-09 07:38:59",19.5,26.2,0,471,0.00366795408506867,0 +"6590","2015-02-09 07:40:00",19.39,26.2,0,471,0.00364279285038695,0 +"6591","2015-02-09 07:40:59",19.5,26.2,0,473,0.00366795408506867,0 +"6592","2015-02-09 07:41:59",19.5,26.245,0,467.5,0.00367429122123116,0 +"6593","2015-02-09 07:43:00",19.5,26.29,0,466.666666666667,0.00368062848576749,0 +"6594","2015-02-09 07:44:00",19.5,26.29,0,467.5,0.00368062848576749,0 +"6595","2015-02-09 07:45:00",19.445,26.29,0,468,0.00366798497702178,0 +"6596","2015-02-09 07:46:00",19.4633333333333,26.3566666666667,0,465.333333333333,0.0036815623532426,0 +"6597","2015-02-09 07:46:59",19.5,26.39,0,467,0.00369471175547797,0 +"6598","2015-02-09 07:47:59",19.5,26.39,0,467,0.00369471175547797,0 +"6599","2015-02-09 07:49:00",19.445,26.34,0,470,0.00367500220175779,0 +"6600","2015-02-09 07:50:00",19.445,26.39,0,471.5,0.00368201958389996,0 +"6601","2015-02-09 07:51:00",19.5,26.39,0,470.333333333333,0.00369471175547797,0 +"6602","2015-02-09 07:52:00",19.445,26.445,0,468.5,0.00368973888606677,0 +"6603","2015-02-09 07:53:00",19.39,26.39,0,469,0.00366936589349026,0 +"6604","2015-02-09 07:53:59",19.39,26.39,0,470,0.00366936589349026,0 +"6605","2015-02-09 07:54:59",19.445,26.445,0,470.5,0.00368973888606677,0 +"6606","2015-02-09 07:56:00",19.5,26.5,0,472,0.00371020408443922,0 +"6607","2015-02-09 07:57:00",19.445,26.5,0,468.5,0.00369745837870849,0 +"6608","2015-02-09 07:58:00",19.445,26.5,0,470.5,0.00369745837870849,0 +"6609","2015-02-09 07:59:00",19.5,26.5,0,473,0.00371020408443922,0 +"6610","2015-02-09 07:59:59",19.5,26.5,0,467,0.00371020408443922,0 +"6611","2015-02-09 08:00:59",19.5,26.5,0,471.333333333333,0.00371020408443922,0 +"6612","2015-02-09 08:02:00",19.5,26.5,0,471,0.00371020408443922,0 +"6613","2015-02-09 08:03:00",19.5,26.5,0,472.5,0.00371020408443922,0 +"6614","2015-02-09 08:04:00",19.5,26.5,0,472,0.00371020408443922,0 +"6615","2015-02-09 08:05:00",19.5,26.5,0,470,0.00371020408443922,0 +"6616","2015-02-09 08:06:00",19.5,26.5,0,472,0.00371020408443922,0 +"6617","2015-02-09 08:06:59",19.5,26.55,0,462.5,0.0037172463057671,0 +"6618","2015-02-09 08:08:00",19.5,26.6,0,463,0.00372428868561385,0 +"6619","2015-02-09 08:09:00",19.5,26.6,0,469.5,0.00372428868561385,0 +"6620","2015-02-09 08:10:00",19.5,26.625,0,470.666666666667,0.00372780993498348,0 +"6621","2015-02-09 08:10:59",19.5,26.6,0,471,0.00372428868561385,0 +"6622","2015-02-09 08:12:00",19.5,26.6,0,470,0.00372428868561385,0 +"6623","2015-02-09 08:12:59",19.5,26.6,0,471.5,0.00372428868561385,0 +"6624","2015-02-09 08:13:59",19.5,26.65,0,470.5,0.00373133122398483,0 +"6625","2015-02-09 08:15:00",19.5,26.6,0,469,0.00372428868561385,0 +"6626","2015-02-09 08:16:00",19.5,26.6,0,472,0.00372428868561385,0 +"6627","2015-02-09 08:17:00",19.5,26.7,0,473,0.0037383739208854,0 +"6628","2015-02-09 08:18:00",19.5,26.7,0,474,0.0037383739208854,0 +"6629","2015-02-09 08:19:00",19.5,26.7,0,473,0.0037383739208854,0 +"6630","2015-02-09 08:19:59",19.5,26.7,0,477.5,0.0037383739208854,0 +"6631","2015-02-09 08:21:00",19.5,26.7,0,477.5,0.0037383739208854,0 +"6632","2015-02-09 08:22:00",19.5,26.7,0,474,0.0037383739208854,0 +"6633","2015-02-09 08:23:00",19.5,26.79,0,473.666666666667,0.00375105117481805,0 +"6634","2015-02-09 08:23:59",19.5,26.79,0,467.5,0.00375105117481805,0 +"6635","2015-02-09 08:25:00",19.5,26.79,0,473,0.00375105117481805,0 +"6636","2015-02-09 08:25:59",19.5,26.79,0,480.333333333333,0.00375105117481805,0 +"6637","2015-02-09 08:26:59",19.5,26.79,0,474.333333333333,0.00375105117481805,0 +"6638","2015-02-09 08:28:00",19.5,26.79,0,469,0.00375105117481805,0 +"6639","2015-02-09 08:29:00",19.5,26.79,0,469.5,0.00375105117481805,0 +"6640","2015-02-09 08:30:00",19.5,26.79,0,470,0.00375105117481805,0 +"6641","2015-02-09 08:31:00",19.5,26.79,0,471.5,0.00375105117481805,0 +"6642","2015-02-09 08:31:59",19.5,26.79,0,470,0.00375105117481805,0 +"6643","2015-02-09 08:32:59",19.6,26.79,0,476,0.00377458229660593,0 +"6644","2015-02-09 08:34:00",19.5,26.79,0,470,0.00375105117481805,0 +"6645","2015-02-09 08:35:00",19.6,26.89,0,470,0.00378875763897944,0 +"6646","2015-02-09 08:36:00",19.5,26.89,0,471,0.00376513761499172,0 +"6647","2015-02-09 08:37:00",19.5,26.89,0,471,0.00376513761499172,0 +"6648","2015-02-09 08:38:00",19.5333333333333,26.89,0,470.666666666667,0.00377299647867788,0 +"6649","2015-02-09 08:38:59",19.5,26.89,0,475.333333333333,0.00376513761499172,0 +"6650","2015-02-09 08:39:59",19.5,27,0,471,0.00378063343170978,0 +"6651","2015-02-09 08:41:00",19.5,27,0,469,0.00378063343170978,0 +"6652","2015-02-09 08:42:00",19.5,27,0,474.5,0.00378063343170978,0 +"6653","2015-02-09 08:43:00",19.5333333333333,27,0,474,0.00378852483518725,0 +"6654","2015-02-09 08:44:00",19.5,27,0,471,0.00378063343170978,0 +"6655","2015-02-09 08:44:59",19.525,27.025,289.75,473.75,0.0037900780521215,1 +"6656","2015-02-09 08:45:59",19.5,27.1,440,481.5,0.00379472120379726,1 +"6657","2015-02-09 08:47:00",19.525,27.125,412,479,0.00380418816642257,1 +"6658","2015-02-09 08:48:00",19.525,27.2925,397,484.75,0.00382782403344306,0 +"6659","2015-02-09 08:49:00",19.525,27.365,392.5,486.75,0.0038380550369924,0 +"6660","2015-02-09 08:50:00",19.5666666666667,27.5666666666667,393.666666666667,492.333333333333,0.00387660553903883,0 +"6661","2015-02-09 08:51:00",19.575,27.675,397,496.5,0.00389396425258134,1 +"6662","2015-02-09 08:51:59",19.575,27.6,405,501.5,0.00388334561973281,1 +"6663","2015-02-09 08:53:00",19.6333333333333,27.6333333333333,405,506.666666666667,0.00390227134609569,1 +"6664","2015-02-09 08:54:00",19.6666666666667,27.73,405,510.666666666667,0.00392417548856283,1 +"6665","2015-02-09 08:55:00",19.6333333333333,27.73,399.666666666667,512,0.00391600817872044,1 +"6666","2015-02-09 08:55:59",19.625,27.745,393,517,0.0039160992111958,1 +"6667","2015-02-09 08:57:00",19.6333333333333,27.79,393.666666666667,515,0.00392453479190768,1 +"6668","2015-02-09 08:57:59",19.7,27.9175,389,528.75,0.0039591162199895,1 +"6669","2015-02-09 08:58:59",19.7,27.9633333333333,393.666666666667,534.333333333333,0.00396565750830584,1 +"6670","2015-02-09 09:00:00",19.745,28.05,389,541,0.00398922628686199,1 +"6671","2015-02-09 09:01:00",19.7675,28.175,392.5,546,0.00401275357766118,1 +"6672","2015-02-09 09:02:00",19.79,28.1,393.666666666667,553,0.00400763040822173,1 +"6673","2015-02-09 09:03:00",19.79,28.2675,392.5,559.75,0.00403167415120545,1 +"6674","2015-02-09 09:04:00",19.79,28.3233333333333,389,572.333333333333,0.00403968914263802,1 +"6675","2015-02-09 09:04:59",19.84,28.6975,389,578.75,0.00410620678330711,1 +"6676","2015-02-09 09:06:00",19.89,28.625,389,595,0.00410856715250739,1 +"6677","2015-02-09 09:07:00",19.89,28.65,389,599,0.00411217914359546,1 +"6678","2015-02-09 09:08:00",19.9175,28.8175,393,606.5,0.00414348501236772,1 +"6679","2015-02-09 09:08:59",19.9633333333333,28.96,399.666666666667,622,0.00417603550199632,1 +"6680","2015-02-09 09:10:00",19.945,29.05,397,636,0.00418431261140537,1 +"6681","2015-02-09 09:10:59",20,29.1975,405,655.5,0.00422015535020849,1 +"6682","2015-02-09 09:11:59",20,29.39,405,661.333333333333,0.00424816899318491,1 +"6683","2015-02-09 09:13:00",20,29.445,405,680.8,0.00425617335153449,1 +"6684","2015-02-09 09:14:00",20.05,29.575,405,689.75,0.00428844380050077,1 +"6685","2015-02-09 09:15:00",20.1,29.745,405,695.5,0.00432673019359038,1 +"6686","2015-02-09 09:16:00",20.1,29.79,405,701,0.00433332153014446,1 +"6687","2015-02-09 09:16:59",20.1,29.823,406.75,710.125,0.00433815526512323,1 +"6688","2015-02-09 09:17:59",20.1,29.856,408.5,719.25,0.00434298907471139,1 +"6689","2015-02-09 09:19:00",20.2,29.945,419,736,0.00438325197816447,1 +"6690","2015-02-09 09:20:00",20.125,29.9725,419,743.75,0.00436685324484237,1 +"6691","2015-02-09 09:21:00",20.15,30.15,419,759,0.00439974581852508,1 +"6692","2015-02-09 09:22:00",20.175,30.15,419,765.75,0.00440660425600342,1 +"6693","2015-02-09 09:23:00",20.2,30.195,419,769.5,0.00442010621588718,1 +"6694","2015-02-09 09:23:59",20.215,30.2275,419,774.916666666667,0.00442903360207528,1 +"6695","2015-02-09 09:24:59",20.23,30.26,419,780.333333333333,0.00443797349974626,1 +"6696","2015-02-09 09:26:00",20.29,30.4175,422.5,802.75,0.00447793604275322,1 +"6697","2015-02-09 09:27:00",20.29,30.445,422.5,814.75,0.00448201364899767,1 +"6698","2015-02-09 09:28:00",20.29,30.34,433,816,0.00446644489254803,1 +"6699","2015-02-09 09:29:00",20.29,30.4725,433,822.75,0.00448609130832294,1 +"6700","2015-02-09 09:29:59",20.29,30.5333333333333,433,843.666666666667,0.00449511177360291,1 +"6701","2015-02-09 09:30:59",20.29,30.495,433,850.5,0.00448942761452594,1 +"6702","2015-02-09 09:32:00",20.39,30.7,433,850,0.00454804227200713,1 +"6703","2015-02-09 09:33:00",20.3816666666667,30.7058333333333,433,856.7,0.00454655509061854,1 +"6704","2015-02-09 09:34:00",20.3733333333333,30.7116666666667,433,863.4,0.00454506808230366,1 +"6705","2015-02-09 09:35:00",20.39,30.84,433,886,0.00456893487861928,1 +"6706","2015-02-09 09:36:00",20.39,30.695,433,889,0.00454729613325429,1 +"6707","2015-02-09 09:36:59",20.39,30.795,433,898,0.00456221924597057,1 +"6708","2015-02-09 09:38:00",20.39,30.77,433,902.5,0.0045584884011471,1 +"6709","2015-02-09 09:39:00",20.39,30.8925,433,909.25,0.00457676996532691,1 +"6710","2015-02-09 09:40:00",20.445,30.795,433,922,0.00457785295762528,1 +"6711","2015-02-09 09:40:59",20.4725,30.9175,433,921.5,0.00460406405837682,1 +"6712","2015-02-09 09:42:00",20.5,31.1225,433,929.25,0.00464275012157711,1 +"6713","2015-02-09 09:42:59",20.5,31.1,447,953,0.00463936861182849,1 +"6714","2015-02-09 09:43:59",20.5,31.1,437.666666666667,954,0.00463936861182849,1 +"6715","2015-02-09 09:45:00",20.5,30.9725,442.5,950.75,0.00462020741257856,1 +"6716","2015-02-09 09:46:00",20.5,31.1475,447,959.75,0.00464650739743419,1 +"6717","2015-02-09 09:47:00",20.5,31.245,440,967.75,0.00466116120380042,1 +"6718","2015-02-09 09:48:00",20.5,31.26,442.333333333333,974.333333333333,0.00466341569637859,1 +"6719","2015-02-09 09:49:00",20.5,31.1,447,977,0.00463936861182849,1 +"6720","2015-02-09 09:49:59",20.5,31.1633333333333,441,970.333333333333,0.00464888702878125,1 +"6721","2015-02-09 09:51:00",20.5,31.2225,442.5,968,0.00465777949534847,1 +"6722","2015-02-09 09:52:00",20.55,31.245,438,975.5,0.00467566986676579,1 +"6723","2015-02-09 09:53:00",20.55,31.245,447,981.5,0.00467566986676579,1 +"6724","2015-02-09 09:53:59",20.6,31.245,438,1007,0.0046902184083364,1 +"6725","2015-02-09 09:55:00",20.6,31.3233333333333,447,1013,0.00470206599480761,1 +"6726","2015-02-09 09:55:59",20.6,31.2675,438,1016,0.00469362139263832,1 +"6727","2015-02-09 09:56:59",20.6333333333333,31.26,447,1018,0.00470221302723743,1 +"6728","2015-02-09 09:58:00",20.6,31.295,438,1019.5,0.00469778064586289,1 +"6729","2015-02-09 09:59:00",20.675,31.4725,438,1041.5,0.00474668772497995,1 +"6730","2015-02-09 10:00:00",20.6,31.445,438,1050.5,0.00472046845351942,1 +"6731","2015-02-09 10:01:00",20.7,31.5225,438,1056.75,0.00476167168028189,1 +"6732","2015-02-09 10:01:59",20.65,31.5225,438,1066.5,0.00474691118761033,1 +"6733","2015-02-09 10:02:59",20.7,31.4633333333333,441,1074,0.00475266589264503,1 +"6734","2015-02-09 10:04:00",20.7,31.6,438,1071.75,0.00477346838519578,1 +"6735","2015-02-09 10:05:00",20.7,31.575,442.5,1075.25,0.00476966294799483,1 +"6736","2015-02-09 10:06:00",20.7,31.745,438,1080.75,0.00479554083224444,1 +"6737","2015-02-09 10:07:00",20.7,31.7225,438,1102.5,0.00479211569545842,1 +"6738","2015-02-09 10:08:00",20.7,31.79,438,1106.75,0.00480239121811869,1 +"6739","2015-02-09 10:08:59",20.7,31.795,438,1105.5,0.00480315238134786,1 +"6740","2015-02-09 10:09:59",20.7225,31.865,438,1111,0.00482053773348256,1 +"6741","2015-02-09 10:11:00",20.7,31.7925,441.75,1111,0.0048027717995022,1 +"6742","2015-02-09 10:12:00",20.7,31.84,432.75,1119.25,0.00481000293360061,1 +"6743","2015-02-09 10:13:00",20.7,31.79,429,1127.66666666667,0.00480239121811869,1 +"6744","2015-02-09 10:14:00",20.745,31.895,433.5,1136,0.00483185496321751,1 +"6745","2015-02-09 10:14:59",20.79,31.895,429,1142.5,0.00484536719552159,1 +"6746","2015-02-09 10:15:59",20.79,31.8225,438,1143.75,0.00483426766932679,1 +"6747","2015-02-09 10:17:00",20.79,31.8933333333333,441,1145.33333333333,0.00484511202958552,1 +"6748","2015-02-09 10:18:00",20.79,31.84,438,1144,0.00483694682931541,1 +"6749","2015-02-09 10:19:00",20.79,31.945,438,1147,0.00485302227020273,1 +"6750","2015-02-09 10:20:00",20.79,31.8925,429,1157.5,0.00484498444669539,1 +"6751","2015-02-09 10:21:00",20.79,31.99,435,1150.66666666667,0.00485991199727559,1 +"6752","2015-02-09 10:21:59",20.79,31.9933333333333,441,1159.33333333333,0.00486042235345388,1 +"6753","2015-02-09 10:23:00",20.79,31.9633333333333,441,1167,0.00485582917776536,1 +"6754","2015-02-09 10:24:00",20.79,32.0666666666667,434,1177.66666666667,0.00487165039962569,1 +"6755","2015-02-09 10:25:00",20.79,31.995,444,1178,0.00486067753185466,1 +"6756","2015-02-09 10:25:59",20.815,31.9925,440.25,1175.25,0.00486783932782812,1 +"6757","2015-02-09 10:27:00",20.8233333333333,32.06,439,1184.33333333333,0.00488071292967525,1 +"6758","2015-02-09 10:27:59",20.865,32.1675,444,1198.25,0.0049098802891586,1 +"6759","2015-02-09 10:28:59",20.84,32.245,432.75,1204,0.00491417716994355,1 +"6760","2015-02-09 10:30:00",20.89,32.2,444,1199,0.00492250566731028,1 +"6761","2015-02-09 10:31:00",20.89,32.26,439,1204.33333333333,0.00493175076456065,1 +"6762","2015-02-09 10:32:00",20.89,32.3725,437.25,1224.75,0.00494908605685923,1 +"6763","2015-02-09 10:33:00",20.89,32.1675,432.75,1218.75,0.00491749802014673,1 +"6764","2015-02-09 10:34:00",20.89,32.3333333333333,439,1212,0.00494305069816742,1 +"6765","2015-02-09 10:34:59",20.89,32.25,444,1222.5,0.00493020989608348,1 +"6766","2015-02-09 10:36:00",20.89,32.29,429,1218.5,0.00493637341543825,1 +"6767","2015-02-09 10:37:00",20.89,32.2725,441,1228,0.0049336768608085,1 +"6768","2015-02-09 10:38:00",20.89,32.475,436.5,1237.75,0.00496488126894816,1 +"6769","2015-02-09 10:38:59",20.89,32.4725,440.25,1240.75,0.00496449601040367,1 +"6770","2015-02-09 10:40:00",20.945,32.4975,444,1253,0.00498531945808804,1 +"6771","2015-02-09 10:40:59",21,32.4,444,1262,0.00498721298961528,1 +"6772","2015-02-09 10:41:59",21,32.4,446.75,1261,0.00498721298961528,1 +"6773","2015-02-09 10:43:00",21,32.425,454,1263.8,0.00499109202642223,1 +"6774","2015-02-09 10:44:00",20.9266666666667,32.5266666666667,469,1276.66666666667,0.00498416190757425,1 +"6775","2015-02-09 10:45:00",21,32.5675,469,1294,0.0050132034527675,1 +"6776","2015-02-09 10:46:00",21,32.52,465.25,1294.5,0.00500583280403665,1 +"6777","2015-02-09 10:46:59",21,32.5266666666667,454,1287.66666666667,0.00500686727059776,1 +"6778","2015-02-09 10:47:59",21,32.4725,454,1289.25,0.00499846232859026,1 +"6779","2015-02-09 10:49:00",21,32.545,454,1300.75,0.00500971207124142,1 +"6780","2015-02-09 10:50:00",21,32.59,454,1312,0.00501669487317596,1 +"6781","2015-02-09 10:51:00",21,32.56,454,1315,0.00501203965460524,1 +"6782","2015-02-09 10:52:00",21.025,32.7,454,1315,0.00504156795832232,1 +"6783","2015-02-09 10:53:00",21,32.645,454,1323,0.00502522962009067,1 +"6784","2015-02-09 10:53:59",21.0666666666667,32.8633333333333,454,1325.66666666667,0.0050800507402687,1 +"6785","2015-02-09 10:54:59",21.075,32.8725,454,1330,0.00508410273974399,1 +"6786","2015-02-09 10:56:00",21.1,32.845,454,1338,0.00508768559405042,1 +"6787","2015-02-09 10:57:00",21.05,32.775,454,1334,0.00506105739001047,1 +"6788","2015-02-09 10:58:00",21.1,32.9666666666667,454,1339.66666666667,0.00510668647143731,1 +"6789","2015-02-09 10:59:00",21.1,33.0225,454,1349.25,0.00511540643761103,1 +"6790","2015-02-09 10:59:59",21.1,33.09,454,1354,0.00512594881008055,1 +"6791","2015-02-09 11:00:59",21.1,33.045,454,1361.75,0.00511892052238426,1 +"6792","2015-02-09 11:02:00",21.1,33.0675,454,1369.75,0.00512243464654054,1 +"6793","2015-02-09 11:03:00",21.1,32.925,464.5,1370,0.00510017919200398,1 +"6794","2015-02-09 11:04:00",21.1333333333333,33.0966666666667,458,1371,0.00513758305018677,1 +"6795","2015-02-09 11:05:00",21.1,33.1266666666667,458,1379.33333333333,0.00513167567949639,1 +"6796","2015-02-09 11:06:00",21.1,33.0725,449.5,1384.5,0.0051232155683681,1 +"6797","2015-02-09 11:06:59",21.1,33.025,464.5,1382,0.0051157968895299,1 +"6798","2015-02-09 11:08:00",21.1,32.7675,465.25,1371.2,0.0050755828957469,1 +"6799","2015-02-09 11:09:00",21.125,33.0675,471.75,1352,0.00513037046868385,1 +"6800","2015-02-09 11:10:00",21.1,32.975,474.5,1349.75,0.00510798794352991,1 +"6801","2015-02-09 11:10:59",21.125,33.0425,474.5,1357,0.00512645979018345,1 +"6802","2015-02-09 11:12:00",21.125,33.1175,464,1364.75,0.00513819197200534,1 +"6803","2015-02-09 11:12:59",21.1333333333333,33.0333333333333,464,1369.66666666667,0.00512767079385108,1 +"6804","2015-02-09 11:13:59",21.1666666666667,32.9966666666667,469,1377.33333333333,0.00513251200746536,1 +"6805","2015-02-09 11:15:00",21.15,33.0425,479,1384.5,0.00513440036953829,1 +"6806","2015-02-09 11:16:00",21.1333333333333,33.09,479,1379.33333333333,0.0051365396400273,1 +"6807","2015-02-09 11:17:00",21.175,33.09,479,1387.25,0.00514980537157095,1 +"6808","2015-02-09 11:18:00",21.2,33.1266666666667,480.666666666667,1390.33333333333,0.00516354206128261,1 +"6809","2015-02-09 11:19:00",21.2,33.1725,496.5,1390.25,0.00517074561555594,1 +"6810","2015-02-09 11:19:59",21.2,33.145,496.5,1398.25,0.0051664234631346,1 +"6811","2015-02-09 11:21:00",21.2,33.1633333333333,504,1402.66666666667,0.00516930489146299,1 +"6812","2015-02-09 11:22:00",21.2225,33.145,495.25,1404.75,0.00517362150278515,1 +"6813","2015-02-09 11:23:00",21.245,33.1725,489,1408.5,0.00518516270779162,1 +"6814","2015-02-09 11:23:59",21.29,33.2,489,1414,0.00520396186213006,1 +"6815","2015-02-09 11:25:00",21.29,33.2,489,1415,0.00520396186213006,1 +"6816","2015-02-09 11:25:59",21.29,33.2,500.25,1417.25,0.00520396186213006,1 +"6817","2015-02-09 11:26:59",21.29,33.1266666666667,492.333333333333,1416,0.00519237121110796,1 +"6818","2015-02-09 11:28:00",21.29,33.1725,485.25,1417.75,0.00519961531779453,1 +"6819","2015-02-09 11:29:00",21.29,33.1725,481.5,1414.5,0.00519961531779453,1 +"6820","2015-02-09 11:30:00",21.29,33.145,471.5,1419.25,0.00519526883370197,1 +"6821","2015-02-09 11:31:00",21.29,33.1633333333333,464,1413.33333333333,0.00519816648307007,1 +"6822","2015-02-09 11:31:59",21.29,33.145,464,1421.75,0.00519526883370197,1 +"6823","2015-02-09 11:32:59",21.29,33.23,464,1427.33333333333,0.00520870361556808,1 +"6824","2015-02-09 11:34:00",21.29,33.145,464,1430.25,0.00519526883370197,1 +"6825","2015-02-09 11:35:00",21.29,33.145,475.25,1433.25,0.00519526883370197,1 +"6826","2015-02-09 11:36:00",21.3233333333333,33.1633333333333,479,1441,0.00520889204954885,1 +"6827","2015-02-09 11:37:00",21.29,33.195,479,1432.75,0.00520317157686084,1 +"6828","2015-02-09 11:38:00",21.365,33.24,479,1435.5,0.0052345010349088,1 +"6829","2015-02-09 11:38:59",21.3233333333333,33.23,479,1437.66666666667,0.00521945110462744,1 +"6830","2015-02-09 11:39:59",21.39,33.3,479,1436,0.00525213846178747,1 +"6831","2015-02-09 11:41:00",21.39,33.35,479,1438.5,0.0052600912462056,1 +"6832","2015-02-09 11:42:00",21.39,33.2725,479,1444.75,0.00524776451631467,1 +"6833","2015-02-09 11:43:00",21.39,33.29,474,1453,0.00525054792910304,1 +"6834","2015-02-09 11:44:00",21.39,33.2675,475.25,1449.25,0.00524696926005522,1 +"6835","2015-02-09 11:44:59",21.39,33.2225,479,1439.25,0.00523981204446303,1 +"6836","2015-02-09 11:45:59",21.39,33.2966666666667,469,1441,0.00525160828332974,1 +"6837","2015-02-09 11:47:00",21.39,33.3,471.5,1442.5,0.00525213846178747,1 +"6838","2015-02-09 11:48:00",21.4175,33.2725,464,1441.75,0.00525668994478241,1 +"6839","2015-02-09 11:49:00",21.39,33.2675,464,1449.75,0.00524696926005522,1 +"6840","2015-02-09 11:50:00",21.39,33.3633333333333,464,1453.33333333333,0.00526221202277586,1 +"6841","2015-02-09 11:51:00",21.39,33.3725,464,1458,0.00526367006498669,1 +"6842","2015-02-09 11:51:59",21.39,33.4,478,1456.66666666667,0.0052680442322893,1 +"6843","2015-02-09 11:53:00",21.39,33.3725,474.5,1454,0.00526367006498669,1 +"6844","2015-02-09 11:54:00",21.39,33.4666666666667,478,1458,0.00527864852744951,1 +"6845","2015-02-09 11:55:00",21.4175,33.5425,469.25,1465.5,0.00529971043893642,1 +"6846","2015-02-09 11:55:59",21.39,33.4975,464,1462.75,0.00528355313522219,1 +"6847","2015-02-09 11:57:00",21.4175,33.5675,464,1470.5,0.00530369411652366,1 +"6848","2015-02-09 11:57:59",21.4266666666667,33.5,464,1476,0.00529593713577501,1 +"6849","2015-02-09 11:58:59",21.445,33.3725,464,1460.25,0.00528158893814204,1 +"6850","2015-02-09 12:00:00",21.39,33.4666666666667,464,1455,0.00527864852744951,1 +"6851","2015-02-09 12:01:00",21.4725,33.5675,464,1458.75,0.00532174657216372,1 +"6852","2015-02-09 12:02:00",21.5,33.59,464,1462,0.00533439697991446,1 +"6853","2015-02-09 12:03:00",21.5,33.595,464,1464.25,0.00533519783622714,1 +"6854","2015-02-09 12:04:00",21.5,33.5675,467.75,1472.5,0.00533079315181101,1 +"6855","2015-02-09 12:04:59",21.5,33.84,456.5,1455.5,0.00537444230052315,1 +"6856","2015-02-09 12:06:00",21.5,33.7933333333333,464,1460.33333333333,0.00536696678591759,1 +"6857","2015-02-09 12:07:00",21.5,33.4475,464,1445.75,0.00531157343453232,1 +"6858","2015-02-09 12:08:00",21.525,33.52,464,1445,0.00533140930935942,1 +"6859","2015-02-09 12:08:59",21.5,33.6333333333333,464,1431.66666666667,0.00534133780255613,1 +"6860","2015-02-09 12:10:00",21.5,33.7975,475.25,1435.25,0.00536763423533578,1 +"6861","2015-02-09 12:10:59",21.5,33.6933333333333,479,1429,0.00535094842592544,1 +"6862","2015-02-09 12:11:59",21.5333333333333,34.1,479,1430,0.00542725591180863,1 +"6863","2015-02-09 12:13:00",21.55,33.895,479,1399,0.00539989972278862,1 +"6864","2015-02-09 12:14:00",21.5666666666667,33.79,474,1399,0.00538856864054833,1 +"6865","2015-02-09 12:15:00",21.575,33.595,479,1375.5,0.00535996007684243,1 +"6866","2015-02-09 12:16:00",21.575,33.79,479,1385.25,0.00539134128479374,1 +"6867","2015-02-09 12:16:59",21.6,33.8,471.5,1378.5,0.00540127867028301,1 +"6868","2015-02-09 12:17:59",21.5666666666667,34.43,464,1366.5,0.00549153199576074,1 +"6869","2015-02-09 12:19:00",21.525,34.45,474.5,1396.75,0.00548063063858146,1 +"6870","2015-02-09 12:20:00",21.6,34.475,462.75,1419.75,0.0055100999910828,1 +"6871","2015-02-09 12:21:00",21.5666666666667,34.5,469,1422.66666666667,0.00550279566311072,1 +"6872","2015-02-09 12:22:00",21.575,34.5,461.5,1428,0.00550562759771765,1 +"6873","2015-02-09 12:23:00",21.5,34.5,454,1430,0.00548018651567403,1 +"6874","2015-02-09 12:23:59",21.525,34.475,454,1424.75,0.00548464294445296,1 +"6875","2015-02-09 12:24:59",21.5,34.4475,460.75,1423,0.00547177373905098,1 +"6876","2015-02-09 12:26:00",21.5,34.45,464.5,1401,0.00547217434234631,1 +"6877","2015-02-09 12:27:00",21.5,34.3966666666667,463,1407,0.00546362824965466,1 +"6878","2015-02-09 12:28:00",21.5,34.4,460.75,1401.25,0.00546416237362776,1 +"6879","2015-02-09 12:29:00",21.5,34.4,468,1395,0.00546416237362776,1 +"6880","2015-02-09 12:29:59",21.5,34.4225,464.5,1396.5,0.00546776773423122,1 +"6881","2015-02-09 12:30:59",21.5,34.4225,464.5,1391.5,0.00546776773423122,1 +"6882","2015-02-09 12:32:00",21.5,34.345,454,1399,0.0054553494443516,1 +"6883","2015-02-09 12:33:00",21.5,34.29,454,1402.25,0.00544653676263263,1 +"6884","2015-02-09 12:34:00",21.5,34.29,454,1401,0.00544653676263263,1 +"6885","2015-02-09 12:35:00",21.5,34.245,454,1390.75,0.00543932657080691,1 +"6886","2015-02-09 12:36:00",21.445,34.195,454,1386.5,0.0054128919886134,1 +"6887","2015-02-09 12:36:59",21.5,34.2,454,1380,0.00543211654468858,1 +"6888","2015-02-09 12:38:00",21.5,34.2,454,1370,0.00543211654468858,1 +"6889","2015-02-09 12:39:00",21.4266666666667,34.06,469,1367.66666666667,0.0053852327129369,1 +"6890","2015-02-09 12:40:00",21.39,34.0675,471.75,1362,0.00537423591705614,1 +"6891","2015-02-09 12:40:59",21.4175,34.0225,467.75,1365.25,0.0053762058899107,1 +"6892","2015-02-09 12:42:00",21.445,34.045,481.5,1361.5,0.00538894204544552,1 +"6893","2015-02-09 12:42:59",21.39,33.95,482.75,1355.5,0.0053555403913322,1 +"6894","2015-02-09 12:43:59",21.39,33.9,489,1340,0.0053475851864208,1 +"6895","2015-02-09 12:45:00",21.4725,33.925,496.5,1347,0.00537891427893576,1 +"6896","2015-02-09 12:46:00",21.4725,33.8975,499,1337.25,0.00537451639311458,1 +"6897","2015-02-09 12:47:00",21.5,33.9,499,1339.33333333333,0.00538405393822286,1 +"6898","2015-02-09 12:48:00",21.5,33.845,514,1330.5,0.00537524325908302,1 +"6899","2015-02-09 12:49:00",21.39,33.7,514,1326.5,0.00531576638419822,1 +"6900","2015-02-09 12:49:59",21.4266666666667,33.6933333333333,510.666666666667,1324.33333333333,0.00532676249765869,1 +"6901","2015-02-09 12:51:00",21.5,33.7,514,1315.66666666667,0.00535201629114317,1 +"6902","2015-02-09 12:52:00",21.5,33.7,510.25,1314,0.00535201629114317,1 +"6903","2015-02-09 12:53:00",21.5,33.6266666666667,499,1312.66666666667,0.00534026997369145,1 +"6904","2015-02-09 12:53:59",21.5,33.59,496.5,1316.25,0.00533439697991446,1 +"6905","2015-02-09 12:55:00",21.5,33.59,504,1312,0.00533439697991446,1 +"6906","2015-02-09 12:55:59",21.5,33.59,489,1307,0.00533439697991446,1 +"6907","2015-02-09 12:56:59",21.5,33.56,480.666666666667,1312.33333333333,0.00532959188497775,1 +"6908","2015-02-09 12:58:00",21.5,33.5,486.5,1305.75,0.00531998191592993,1 +"6909","2015-02-09 12:59:00",21.5,33.5,479,1290.75,0.00531998191592993,1 +"6910","2015-02-09 13:00:00",21.5,33.5,475.25,1281.5,0.00531998191592993,1 +"6911","2015-02-09 13:01:00",21.5,33.4666666666667,464,1283.33333333333,0.00531464317145733,1 +"6912","2015-02-09 13:01:59",21.5,33.425,464,1279.25,0.00530796986865074,1 +"6913","2015-02-09 13:02:59",21.5,33.4,464,1274.33333333333,0.00530396595511661,1 +"6914","2015-02-09 13:04:00",21.5,33.3725,469.25,1267.5,0.00529956170926242,1 +"6915","2015-02-09 13:05:00",21.5,33.3175,474.5,1257,0.00529075340308238,1 +"6916","2015-02-09 13:06:00",21.5,33.3175,474.5,1254.75,0.00529075340308238,1 +"6917","2015-02-09 13:07:00",21.5,33.29,471,1255.33333333333,0.00528634934275391,1 +"6918","2015-02-09 13:08:00",21.5,33.29,466.75,1262.5,0.00528634934275391,1 +"6919","2015-02-09 13:08:59",21.5,33.29,469,1262,0.00528634934275391,1 +"6920","2015-02-09 13:09:59",21.5,33.245,469,1254,0.00527914283196837,1 +"6921","2015-02-09 13:11:00",21.5,33.2225,31,1246,0.00527553963866866,1 +"6922","2015-02-09 13:12:00",21.5,33.1633333333333,31,1243.33333333333,0.00526606477235079,0 +"6923","2015-02-09 13:13:00",21.5,33.23,31,1236.66666666667,0.00527674069850248,0 +"6924","2015-02-09 13:14:00",21.5,33.2675,26.5,1229.25,0.00528274606666322,0 +"6925","2015-02-09 13:14:59",21.4175,33.09,13,1229.75,0.00522761461946103,0 +"6926","2015-02-09 13:15:59",21.39,33.09,13,1222,0.00521873896924632,0 +"6927","2015-02-09 13:17:00",21.39,33.09,13,1213.75,0.00521873896924632,0 +"6928","2015-02-09 13:18:00",21.39,33.09,13,1209.33333333333,0.00521873896924632,0 +"6929","2015-02-09 13:19:00",21.39,33.0675,26.5,1201.25,0.00521516066314925,0 +"6930","2015-02-09 13:20:00",21.365,33.09,26.5,1197.5,0.00521068175679435,0 +"6931","2015-02-09 13:21:00",21.29,33.06,22,1197.66666666667,0.00518183462736836,0 +"6932","2015-02-09 13:21:59",21.315,33.045,13,1196.25,0.00518747711260258,0 +"6933","2015-02-09 13:23:00",21.29,33.03,13,1189.66666666667,0.00517709328018398,0 +"6934","2015-02-09 13:24:00",21.29,33,13,1175.75,0.00517235200468599,0 +"6935","2015-02-09 13:25:00",21.29,33,13,1169,0.00517235200468599,0 +"6936","2015-02-09 13:25:59",21.29,33,13,1161.33333333333,0.00517235200468599,0 +"6937","2015-02-09 13:27:00",21.29,33,13,1159,0.00517235200468599,0 +"6938","2015-02-09 13:27:59",21.2675,32.95,13,1159.75,0.00515726859274351,0 +"6939","2015-02-09 13:28:59",21.2,32.9,13,1151.66666666667,0.0051279196436793,0 +"6940","2015-02-09 13:30:00",21.2,32.9,13,1138.4,0.0051279196436793,0 +"6941","2015-02-09 13:31:00",21.2,32.9,13,1128.25,0.0051279196436793,0 +"6942","2015-02-09 13:32:00",21.2,32.8725,13,1132.25,0.00512359808150685,0 +"6943","2015-02-09 13:33:00",21.2,32.79,13,1115.5,0.00511063375234271,0 +"6944","2015-02-09 13:34:00",21.1666666666667,32.79,167,1117.33333333333,0.00510010217200739,0 +"6945","2015-02-09 13:34:59",21.15,32.845,365.75,1121,0.00510345948364146,1 +"6946","2015-02-09 13:36:00",21.2,32.745,454,1108,0.00510356252599249,1 +"6947","2015-02-09 13:37:00",21.1333333333333,32.79,454,1094,0.00508958977608224,1 +"6948","2015-02-09 13:38:00",21.15,32.9,454,1106,0.00511207562615001,1 +"6949","2015-02-09 13:38:59",21.2,32.845,454,1104.25,0.00511927657889409,1 +"6950","2015-02-09 13:40:00",21.2,32.845,454,1102,0.00511927657889409,1 +"6951","2015-02-09 13:40:59",21.2,32.9,454,1113.75,0.0051279196436793,1 +"6952","2015-02-09 13:41:59",21.2,32.9,454,1113,0.0051279196436793,1 +"6953","2015-02-09 13:43:00",21.2,32.9,454,1117.33333333333,0.0051279196436793,1 +"6954","2015-02-09 13:44:00",21.2,32.9,454,1110.75,0.0051279196436793,1 +"6955","2015-02-09 13:45:00",21.2,32.9,461.5,1113.25,0.0051279196436793,1 +"6956","2015-02-09 13:46:00",21.2,32.9,469,1116,0.0051279196436793,1 +"6957","2015-02-09 13:46:59",21.245,32.925,469,1123.25,0.00514615613719146,1 +"6958","2015-02-09 13:47:59",21.2675,32.9725,469,1122.66666666667,0.00516081946773821,1 +"6959","2015-02-09 13:49:00",21.245,32.95,469,1122.2,0.00515009597453412,1 +"6960","2015-02-09 13:50:00",21.29,32.9666666666667,467.333333333333,1123.33333333333,0.00516708400487401,1 +"6961","2015-02-09 13:51:00",21.245,32.925,474.5,1126.5,0.00514615613719146,1 +"6962","2015-02-09 13:52:00",21.26,32.9666666666667,478,1125.33333333333,0.00515750578367724,1 +"6963","2015-02-09 13:53:00",21.29,33,474.5,1119.5,0.00517235200468599,1 +"6964","2015-02-09 13:53:59",21.29,33,478,1125,0.00517235200468599,1 +"6965","2015-02-09 13:54:59",21.29,32.975,464,1124.75,0.00516840099653028,1 +"6966","2015-02-09 13:56:00",21.29,32.975,469.25,1130.5,0.00516840099653028,1 +"6967","2015-02-09 13:57:00",21.29,32.95,474.5,1131.5,0.00516445003815471,1 +"6968","2015-02-09 13:58:00",21.29,32.95,474.5,1129.5,0.00516445003815471,1 +"6969","2015-02-09 13:59:00",21.29,32.9333333333333,472.666666666667,1127.66666666667,0.00516181609355951,1 +"6970","2015-02-09 13:59:59",21.34,32.975,474.5,1131,0.00518440374947686,1 +"6971","2015-02-09 14:00:59",21.29,33.05,451.5,1129,0.00518025417034164,1 +"6972","2015-02-09 14:02:00",21.29,33.2225,459,1147.25,0.00520751817048702,1 +"6973","2015-02-09 14:03:00",21.29,33.045,459,1143.5,0.00517946394481527,1 +"6974","2015-02-09 14:04:00",21.365,33.1725,466.5,1149.5,0.00522378213587924,1 +"6975","2015-02-09 14:05:00",21.39,33.3725,469.25,1164,0.00526367006498669,1 +"6976","2015-02-09 14:06:00",21.39,33.5,464,1171.66666666667,0.00528395080948412,1 +"6977","2015-02-09 14:06:59",21.39,33.545,475.25,1176.5,0.00529110903242173,1 +"6978","2015-02-09 14:08:00",21.39,33.6633333333333,484,1184.66666666667,0.0053099332872336,1 +"6979","2015-02-09 14:09:00",21.39,33.7,482.75,1187.75,0.00531576638419822,1 +"6980","2015-02-09 14:10:00",21.39,33.7225,484,1198.25,0.00531934583831589,1 +"6981","2015-02-09 14:10:59",21.4175,33.87,484,1202.75,0.00535190062568885,1 +"6982","2015-02-09 14:12:00",21.4725,33.95,474,1218,0.00538291241046043,1 +"6983","2015-02-09 14:12:59",21.4633333333333,33.9666666666667,479,1221.33333333333,0.00538252890716354,1 +"6984","2015-02-09 14:13:59",21.5,34.045,489,1226,0.00540728327857935,1 +"6985","2015-02-09 14:15:00",21.5,34.045,489,1230.25,0.00540728327857935,1 +"6986","2015-02-09 14:16:00",21.5,34.0675,489,1235.5,0.00541088798556478,1 +"6987","2015-02-09 14:17:00",21.5,34.045,489,1240,0.00540728327857935,1 +"6988","2015-02-09 14:18:00",21.5,34.09,489,1242,0.00541449273397144,1 +"6989","2015-02-09 14:19:00",21.5,34.2,479,1242,0.00543211654468858,1 +"6990","2015-02-09 14:19:59",21.525,34.2,477.75,1249,0.0054405104018201,1 +"6991","2015-02-09 14:21:00",21.5,34.26,487.333333333333,1260.33333333333,0.00544172994966993,1 +"6992","2015-02-09 14:22:00",21.5,34.245,484,1259.25,0.00543932657080691,1 +"6993","2015-02-09 14:23:00",21.525,34.295,479,1261,0.00545575548740607,1 +"6994","2015-02-09 14:23:59",21.6,34.29,489,1272.5,0.00548027113323906,1 +"6995","2015-02-09 14:25:00",21.5666666666667,34.29,484,1271,0.00546900587411334,1 +"6996","2015-02-09 14:25:59",21.6,34.345,474,1276.25,0.00548913887583278,1 +"6997","2015-02-09 14:26:59",21.6333333333333,35.2566666666667,465.666666666667,1457.66666666667,0.00564777464606213,1 +"6998","2015-02-09 14:28:00",21.625,34.77,476.5,1423.75,0.00556625377486167,1 +"6999","2015-02-09 14:29:00",21.6666666666667,34.6566666666667,479,1342.66666666667,0.00556223213067862,1 +"7000","2015-02-09 14:30:00",21.65,34.7675,474,1341.75,0.00557444404577417,1 +"7001","2015-02-09 14:31:00",21.6333333333333,34.6933333333333,480.666666666667,1345,0.00555672795536732,1 +"7002","2015-02-09 14:31:59",21.7,34.8175,477.75,1353.75,0.00559978131288192,1 +"7003","2015-02-09 14:32:59",21.6666666666667,34.83,489,1355.33333333333,0.00559030134444052,1 +"7004","2015-02-09 14:34:00",21.7,35.0225,474,1369.5,0.00563305054400117,1 +"7005","2015-02-09 14:35:00",21.7,35.0225,489,1383.25,0.00563305054400117,1 +"7006","2015-02-09 14:36:00",21.7,35,472.75,1399.75,0.0056293988707038,1 +"7007","2015-02-09 14:37:00",21.7,35.09,472.333333333333,1398.33333333333,0.00564400581885173,1 +"7008","2015-02-09 14:38:00",21.745,35.24,479,1418.5,0.00568410854617175,1 +"7009","2015-02-09 14:38:59",21.7,35.26,474,1428.66666666667,0.00567159857602907,1 +"7010","2015-02-09 14:39:59",21.7,35.345,464,1441,0.00568539586442128,1 +"7011","2015-02-09 14:41:00",21.73,35.4,464,1440,0.00570487229439401,1 +"7012","2015-02-09 14:42:00",21.745,35.475,474.5,1453,0.00572236207822592,1 +"7013","2015-02-09 14:43:00",21.7675,35.5675,464,1464.25,0.00574538797050582,1 +"7014","2015-02-09 14:44:00",21.76,35.59,464,1469,0.00574639750709881,1 +"7015","2015-02-09 14:44:59",21.79,35.645,464,1471,0.00576601766766884,1 +"7016","2015-02-09 14:45:59",21.79,35.6725,464,1477,0.00577050740121563,1 +"7017","2015-02-09 14:47:00",21.79,35.6725,464,1483.5,0.00577050740121563,1 +"7018","2015-02-09 14:48:00",21.79,35.845,474.5,1496.5,0.00579867174021067,1 +"7019","2015-02-09 14:49:00",21.815,35.845,470.75,1498,0.0058076172727972,1 +"7020","2015-02-09 14:50:00",21.79,35.8633333333333,467.333333333333,1503.66666666667,0.00580166520016687,1 +"7021","2015-02-09 14:51:00",21.84,35.95,466.75,1513,0.00583377318526353,1 +"7022","2015-02-09 14:51:59",21.84,35.9,466.5,1520.5,0.00582558346111598,1 +"7023","2015-02-09 14:53:00",21.84,36.0225,469,1540,0.00584564866480374,1 +"7024","2015-02-09 14:54:00",21.84,36.145,465.25,1541,0.0058657151510938,1 +"7025","2015-02-09 14:55:00",21.865,36.24,454,1565,0.0058903484748188,1 +"7026","2015-02-09 14:55:59",21.89,36.29,457,1579.2,0.00590764822460584,1 +"7027","2015-02-09 14:57:00",21.89,36.3266666666667,464,1580,0.005913673940416,1 +"7028","2015-02-09 14:57:59",21.89,36.425,457.75,1581,0.0059298343856187,1 +"7029","2015-02-09 14:58:59",21.89,36.53,454,1592.66666666667,0.00594709137258928,1 +"7030","2015-02-09 15:00:00",21.89,36.53,454,1600.66666666667,0.00594709137258928,1 +"7031","2015-02-09 15:01:00",21.89,36.5725,455.5,1605.25,0.00595407661317183,1 +"7032","2015-02-09 15:02:00",21.89,36.595,453.25,1616.5,0.00595777474463141,1 +"7033","2015-02-09 15:03:00",21.89,36.59,449.5,1625,0.00595695293387614,1 +"7034","2015-02-09 15:04:00",21.89,36.6633333333333,453,1630,0.00596900637387035,1 +"7035","2015-02-09 15:04:59",21.89,36.645,449.5,1636.5,0.00596599297049162,1 +"7036","2015-02-09 15:06:00",21.89,36.7,449.5,1649.25,0.00597503326739067,1 +"7037","2015-02-09 15:07:00",21.89,36.76,453,1661.66666666667,0.0059848957063279,1 +"7038","2015-02-09 15:08:00",21.89,36.8333333333333,460,1665,0.00599695021906207,1 +"7039","2015-02-09 15:08:59",21.89,36.8725,456,1662.25,0.00600338861431929,1 +"7040","2015-02-09 15:10:00",21.89,36.845,456,1667.5,0.00599886802512078,1 +"7041","2015-02-09 15:10:59",21.9175,36.845,444,1682.75,0.0060090439542928,1 +"7042","2015-02-09 15:11:59",21.89,36.95,444,1684,0.00601612880676526,1 +"7043","2015-02-09 15:13:00",21.9175,37.09,444,1689.5,0.00604938956720005,1 +"7044","2015-02-09 15:14:00",21.945,37.045,444,1695,0.00605222635635452,1 +"7045","2015-02-09 15:15:00",21.89,37.0675,444,1707.5,0.00603544556839896,1 +"7046","2015-02-09 15:16:00",21.89,37,444,1714.33333333333,0.00602434856009213,1 +"7047","2015-02-09 15:16:59",21.945,36.95,444,1715.2,0.00603655510390638,1 +"7048","2015-02-09 15:17:59",21.89,37.1633333333333,444,1718.33333333333,0.00605120125383608,1 +"7049","2015-02-09 15:19:00",21.9175,37.15,440.25,1727.5,0.0060592709156912,1 +"7050","2015-02-09 15:20:00",21.89,37.06,444,1722.66666666667,0.00603421254811,1 +"7051","2015-02-09 15:21:00",21.9175,37.145,444,1716.25,0.00605844745810765,1 +"7052","2015-02-09 15:22:00",21.945,37.2,444,1723.5,0.00607779692098183,1 +"7053","2015-02-09 15:23:00",21.9175,37.24,444,1735,0.00607409352144347,1 +"7054","2015-02-09 15:23:59",21.89,37.3975,444,1744.75,0.00608970325469176,1 +"7055","2015-02-09 15:24:59",21.945,37.425,444,1748,0.00611491918775131,1 +"7056","2015-02-09 15:26:00",21.9266666666667,37.4,439,1752.33333333333,0.00610389406579333,1 +"7057","2015-02-09 15:27:00",21.945,37.45,444,1757.75,0.0061190441549368,1 +"7058","2015-02-09 15:28:00",21.9175,37.2725,444,1762,0.00607944630102008,1 +"7059","2015-02-09 15:29:00",21.945,37.4,444,1762.5,0.00611079427474422,1 +"7060","2015-02-09 15:29:59",21.945,37.475,444,1763.25,0.00612316917630176,1 +"7061","2015-02-09 15:30:59",21.9266666666667,37.4633333333333,444,1767,0.0061143320359338,1 +"7062","2015-02-09 15:32:00",21.89,37.4725,444,1774.5,0.00610203585451183,1 +"7063","2015-02-09 15:33:00",21.945,37.425,444,1780,0.00611491918775131,1 +"7064","2015-02-09 15:34:00",21.89,37.495,444,1785,0.00610573572889759,1 +"7065","2015-02-09 15:35:00",22,37.545,432.75,1792,0.00615554360088436,1 +"7066","2015-02-09 15:36:00",21.9633333333333,37.56,434,1798.33333333333,0.0061441318990109,1 +"7067","2015-02-09 15:36:59",22,37.6725,440.25,1802,0.0061766549455363,1 +"7068","2015-02-09 15:38:00",22,37.59,444,1813.25,0.00616299450167052,1 +"7069","2015-02-09 15:39:00",22,37.6633333333333,439,1815.5,0.00617513708910003,1 +"7070","2015-02-09 15:40:00",22,37.6725,440.25,1814.75,0.0061766549455363,1 +"7071","2015-02-09 15:40:59",21.9725,37.6725,440.25,1828,0.00616619901235127,1 +"7072","2015-02-09 15:42:00",21.9725,37.745,444,1837.5,0.00617818361300241,1 +"7073","2015-02-09 15:42:59",21.9633333333333,37.56,439,1828.33333333333,0.0061441318990109,1 +"7074","2015-02-09 15:43:59",22,37.6266666666667,439,1817,0.00616906573670584,1 +"7075","2015-02-09 15:45:00",21.9725,37.9,444,1819,0.00620380739667747,1 +"7076","2015-02-09 15:46:00",21.9725,37.795,444,1826.5,0.00618644912127627,1 +"7077","2015-02-09 15:47:00",21.89,37.7,444,1823.5,0.00613944770340126,1 +"7078","2015-02-09 15:48:00",22,37.95,444,1832.75,0.00622260807187049,1 +"7079","2015-02-09 15:49:00",22,37.79,444,1847,0.00619611175494833,1 +"7080","2015-02-09 15:49:59",21.9725,37.9475,444,1845.5,0.00621166026498338,1 +"7081","2015-02-09 15:51:00",21.9633333333333,37.8966666666667,444,1846.66666666667,0.00619975336647141,1 +"7082","2015-02-09 15:52:00",22,37.945,444,1848.25,0.00622178002813395,1 +"7083","2015-02-09 15:53:00",22,38.03,444,1850,0.00623585706852875,1 +"7084","2015-02-09 15:53:59",22,38.09,444,1860.5,0.00624579418276272,1 +"7085","2015-02-09 15:55:00",21.9633333333333,38.09,444,1866.66666666667,0.00623169885995895,1 +"7086","2015-02-09 15:55:59",22,38.1633333333333,444,1868.33333333333,0.00625793997152168,1 +"7087","2015-02-09 15:56:59",22,38.1175,444,1875.5,0.00625034879851373,1 +"7088","2015-02-09 15:58:00",22,38.145,444,1879.25,0.00625490348030474,1 +"7089","2015-02-09 15:59:00",22,38.23,439,1888.66666666667,0.00626898200519979,1 +"7090","2015-02-09 16:00:00",22,38.4,444,1896.33333333333,0.00629714094798342,1 +"7091","2015-02-09 16:01:00",22,38.2725,432.75,1895,0.00627602150426355,1 +"7092","2015-02-09 16:01:59",22,38.2966666666667,429,1895.66666666667,0.00628002442702627,1 +"7093","2015-02-09 16:02:59",22,38.37,441,1904,0.00629217153937121,1 +"7094","2015-02-09 16:04:00",22,38.3975,438,1909.75,0.00629672682759661,1 +"7095","2015-02-09 16:05:00",22,38.345,438,1911,0.00628803042557613,1 +"7096","2015-02-09 16:06:00",22,38.4666666666667,441,1915.66666666667,0.00630818435968092,1 +"7097","2015-02-09 16:07:00",22,38.47,438,1932.25,0.00630873654045642,1 +"7098","2015-02-09 16:08:00",22,38.5675,438,1933.75,0.00632488825753033,1 +"7099","2015-02-09 16:08:59",22,38.59,438,1940,0.00632861569478429,1 +"7100","2015-02-09 16:09:59",22,38.5675,438,1938.25,0.00632488825753033,1 +"7101","2015-02-09 16:11:00",22,38.56,441,1935.33333333333,0.00632364578827334,1 +"7102","2015-02-09 16:12:00",22.025,38.7,438,1943.5,0.00635662329742464,1 +"7103","2015-02-09 16:13:00",22,38.645,438,1940,0.00633772739425564,1 +"7104","2015-02-09 16:14:00",22,38.6175,438,1949.25,0.00633317151148691,1 +"7105","2015-02-09 16:14:59",22.05,38.7675,438,1950.75,0.00637763866819206,1 +"7106","2015-02-09 16:15:59",22.0666666666667,38.79,441,1955.33333333333,0.00638793259011949,1 +"7107","2015-02-09 16:17:00",22.05,38.69,438,1962.75,0.00636475868629979,1 +"7108","2015-02-09 16:18:00",22.025,38.8,438,1959.25,0.00637321698051136,1 +"7109","2015-02-09 16:19:00",22.0333333333333,38.6566666666667,441,1968.33333333333,0.00635269352352418,1 +"7110","2015-02-09 16:20:00",22.075,38.745,438,1974.5,0.00638372156712843,1 +"7111","2015-02-09 16:21:00",22.075,38.895,438,1981.25,0.00640869057740842,1 +"7112","2015-02-09 16:21:59",22.1,38.845,438,1972.5,0.00641022896600429,1 +"7113","2015-02-09 16:23:00",22.1,39,438,1984.5,0.00643607184150235,1 +"7114","2015-02-09 16:24:00",22.075,38.8975,438,1991.75,0.00640910674439121,1 +"7115","2015-02-09 16:25:00",22.05,38.9975,438,1994.25,0.00641586623953859,1 +"7116","2015-02-09 16:25:59",22.1,39.045,438,2008.25,0.00644357500993623,1 +"7117","2015-02-09 16:27:00",22.0666666666667,39.0266666666667,441,2014.33333333333,0.00642730956096891,1 +"7118","2015-02-09 16:27:59",22.1,39.0425,442.5,2014,0.00644315816254509,1 +"7119","2015-02-09 16:28:59",22.1,39,447,2016.33333333333,0.00643607184150235,1 +"7120","2015-02-09 16:30:00",22.1,38.97,443.5,2011.25,0.00643106982874839,1 +"7121","2015-02-09 16:31:00",22.1,38.76,447,2003.33333333333,0.00639605796889285,1 +"7122","2015-02-09 16:32:00",22.1,38.69,447,1995,0.00638438821586721,1 +"7123","2015-02-09 16:33:00",22.1,38.845,447,2005,0.00641022896600429,1 +"7124","2015-02-09 16:34:00",22.1,38.8,447,2012.75,0.00640272659380053,1 +"7125","2015-02-09 16:34:59",22.1,38.79,447,2011.5,0.00640105942430457,1 +"7126","2015-02-09 16:36:00",22.1,38.745,447,1993.75,0.00639355727104188,1 +"7127","2015-02-09 16:37:00",22.1,38.79,447,1989,0.00640105942430457,1 +"7128","2015-02-09 16:38:00",22.1,38.8225,447,1993.5,0.00640647775751022,1 +"7129","2015-02-09 16:38:59",22.1,38.845,447,1995.5,0.00641022896600429,1 +"7130","2015-02-09 16:40:00",22.1,38.73,447,1981.66666666667,0.00639105659309384,1 +"7131","2015-02-09 16:40:59",22.1,38.834,447,1982,0.0064083950362563,1 +"7132","2015-02-09 16:41:59",22.1,38.79,447,1990.8,0.00640105942430457,1 +"7133","2015-02-09 16:43:00",22.1,38.8633333333333,442.333333333333,1995.33333333333,0.00641328553937146,1 +"7134","2015-02-09 16:44:00",22.1,38.6225,436.5,1989.25,0.00637313565021581,1 +"7135","2015-02-09 16:45:00",22.1,38.6175,436.5,1950.75,0.00637230214286585,1 +"7136","2015-02-09 16:46:00",22.1,38.7675,436.5,1962.25,0.00639730832528201,1 +"7137","2015-02-09 16:46:59",22.1,38.7,433,1974.5,0.00638605529690565,1 +"7138","2015-02-09 16:47:59",22.1,38.745,433,1988,0.00639355727104188,1 +"7139","2015-02-09 16:49:00",22.1,38.845,433,1987,0.00641022896600429,1 +"7140","2015-02-09 16:50:00",22.1,38.845,433,2000.25,0.00641022896600429,1 +"7141","2015-02-09 16:51:00",22.1,38.79,433,2000,0.00640105942430457,1 +"7142","2015-02-09 16:52:00",22.1,38.8266666666667,433,2001,0.00640717242237104,1 +"7143","2015-02-09 16:53:00",22.1,38.79,433,1997.5,0.00640105942430457,1 +"7144","2015-02-09 16:53:59",22.1,38.845,433,1997.5,0.00641022896600429,1 +"7145","2015-02-09 16:54:59",22.1,38.845,433,2007.5,0.00641022896600429,1 +"7146","2015-02-09 16:56:00",22.1,38.79,433,2007,0.00640105942430457,1 +"7147","2015-02-09 16:57:00",22.1,38.8725,433,1997.5,0.0064148138372054,1 +"7148","2015-02-09 16:58:00",22.1,38.95,433,2001,0.00642773519781588,1 +"7149","2015-02-09 16:59:00",22.1,38.9475,433,2010.5,0.0064273183714376,1 +"7150","2015-02-09 16:59:59",22.1,39,433,2005,0.00643607184150235,1 +"7151","2015-02-09 17:00:59",22.1,39,433,2007.66666666667,0.00643607184150235,1 +"7152","2015-02-09 17:02:00",22.1,38.9725,433,2008.25,0.00643148666010325,1 +"7153","2015-02-09 17:03:00",22.1,39.0225,433,2012.25,0.00643982340332354,1 +"7154","2015-02-09 17:04:00",22.1,39,433,2027.5,0.00643607184150235,1 +"7155","2015-02-09 17:05:00",22.1,39,433,2028.5,0.00643607184150235,1 +"7156","2015-02-09 17:06:00",22.1,38.975,433,2021.75,0.00643190349201108,1 +"7157","2015-02-09 17:06:59",22.1,39,433,2012.5,0.00643607184150235,1 +"7158","2015-02-09 17:08:00",22.1,38.975,433,2007,0.00643190349201108,1 +"7159","2015-02-09 17:09:00",22.1,39.0225,433,2008.25,0.00643982340332354,1 +"7160","2015-02-09 17:10:00",22.1,39.045,433,2019.25,0.00644357500993623,1 +"7161","2015-02-09 17:10:59",22.1,39.03,433,2028,0.00644107393388423,1 +"7162","2015-02-09 17:12:00",22.1,39.0675,433,2015.5,0.00644732666134124,1 +"7163","2015-02-09 17:12:59",22.1,39,433,2010.33333333333,0.00643607184150235,1 +"7164","2015-02-09 17:13:59",22.1,39.0225,433,2019,0.00643982340332354,1 +"7165","2015-02-09 17:15:00",22.1,39.0675,433,2022.5,0.00644732666134124,1 +"7166","2015-02-09 17:16:00",22.1,39.03,433,2016,0.00644107393388423,1 +"7167","2015-02-09 17:17:00",22.1,39.09,433,2013,0.00645107835753937,1 +"7168","2015-02-09 17:18:00",22.1,39.09,433,2017.25,0.00645107835753937,1 +"7169","2015-02-09 17:19:00",22.1,39.1175,433,2012.5,0.00645566382483507,1 +"7170","2015-02-09 17:19:59",22.1,39.09,433,2026,0.00645107835753937,1 +"7171","2015-02-09 17:21:00",22.1333333333333,39.09,433,2023,0.00646433289198431,1 +"7172","2015-02-09 17:22:00",22.1,39.09,433,2027.5,0.00645107835753937,1 +"7173","2015-02-09 17:23:00",22.1,39.0675,433,2025.25,0.00644732666134124,1 +"7174","2015-02-09 17:23:59",22.1,39.0675,433,2028.25,0.00644732666134124,1 +"7175","2015-02-09 17:25:00",22.1,38.7966666666667,433,2012.33333333333,0.00640217086965231,1 +"7176","2015-02-09 17:25:59",22.1,38.86,433,1998.33333333333,0.00641272979654761,1 +"7177","2015-02-09 17:26:59",22.1,38.7225,426,1984.25,0.00638980626158335,1 +"7178","2015-02-09 17:28:00",22.1,38.9,413.666666666667,1973.33333333333,0.00641939877530929,1 +"7179","2015-02-09 17:29:00",22.175,38.9725,328,1986.5,0.0064612516694346,1 +"7180","2015-02-09 17:30:00",22.175,38.895,397,1984.75,0.00644826973999343,1 +"7181","2015-02-09 17:31:00",22.23,38.93,403.666666666667,1995,0.00647601323671025,1 +"7182","2015-02-09 17:31:59",22.245,38.87,419,1995.75,0.00647189793037149,1 +"7183","2015-02-09 17:32:59",22.245,38.695,419,1994.5,0.00644245843905562,1 +"7184","2015-02-09 17:34:00",22.29,38.59,419,1992.5,0.00644260186073005,1 +"7185","2015-02-09 17:35:00",22.2675,38.62,433,1978.75,0.00643874686034003,1 +"7186","2015-02-09 17:36:00",22.2,38.4,433,1959,0.00637516515570553,1 +"7187","2015-02-09 17:37:00",22.2,38.45,433,1954,0.00638355134466451,1 +"7188","2015-02-09 17:38:00",22.2,38.4333333333333,429.5,1943.5,0.0063807559234737,1 +"7189","2015-02-09 17:38:59",22.2,38.4,433,1923.75,0.00637516515570553,1 +"7190","2015-02-09 17:39:59",22.15,38.425,433,1917.5,0.0063597593406323,1 +"7191","2015-02-09 17:41:00",22.125,38.45,433,1926,0.00635415352427576,1 +"7192","2015-02-09 17:42:00",22.1,38.4,433,1927.5,0.0063360467132003,1 +"7193","2015-02-09 17:43:00",22.125,38.3175,433,1921.75,0.00633203398611987,1 +"7194","2015-02-09 17:44:00",22.1,38.29,433,1917.5,0.00631771222677822,1 +"7195","2015-02-09 17:44:59",22.1,38.29,433,1901.75,0.00631771222677822,1 +"7196","2015-02-09 17:45:59",22.1,38.29,433,1893.33333333333,0.00631771222677822,1 +"7197","2015-02-09 17:47:00",22.1,38.27875,430.666666666667,1893.83333333333,0.00631583716915922,1 +"7198","2015-02-09 17:48:00",22.1,38.2675,428.333333333333,1894.33333333333,0.00631396212273147,1 +"7199","2015-02-09 17:49:00",22.1,38.2,433,1880,0.00630271207917561,1 +"7200","2015-02-09 17:50:00",22.1,38.1175,429.5,1871.25,0.00628896257303204,1 +"7201","2015-02-09 17:51:00",22.1,38.145,433,1863.75,0.00629354567488201,1 +"7202","2015-02-09 17:51:59",22.1,38.09,433,1859.33333333333,0.00628437953804466,1 +"7203","2015-02-09 17:53:00",22.1,38.09,423.666666666667,1855,0.00628437953804466,1 +"7204","2015-02-09 17:54:00",22.1,38.09,429.5,1851.25,0.00628437953804466,1 +"7205","2015-02-09 17:55:00",22.1,38.0675,429.5,1845,0.00628062983187738,1 +"7206","2015-02-09 17:55:59",22.1,37.975,433,1839.25,0.00626521484341078,1 +"7207","2015-02-09 17:57:00",22.1,37.95,426,1831,0.0062610487601564,1 +"7208","2015-02-09 17:57:59",22.1,37.9333333333333,428.333333333333,1830,0.00625827140201521,1 +"7209","2015-02-09 17:58:59",22.1,37.925,429.5,1826,0.00625688273215301,1 +"7210","2015-02-09 18:00:00",22.075,37.8975,433,1819.25,0.00624268392678853,1 +"7211","2015-02-09 18:01:00",22.1,37.9,426,1803.25,0.0062527167593995,1 +"7212","2015-02-09 18:02:00",22.1,37.8175,426,1801.75,0.00623896944129705,1 +"7213","2015-02-09 18:03:00",22.0666666666667,37.76,423.666666666667,1796.66666666667,0.00621661703229087,1 +"7214","2015-02-09 18:04:00",22.1,37.79,209.5,1788.5,0.0062343871356248,1 +"7215","2015-02-09 18:04:59",22.1,37.69,0,1784.5,0.00621772476938492,0 +"7216","2015-02-09 18:06:00",22.0333333333333,37.5966666666667,0,1774,0.00617676718976279,0 +"7217","2015-02-09 18:07:00",22,37.59,0,1755.5,0.00616299450167052,0 +"7218","2015-02-09 18:08:00",22.05,37.645,0,1742,0.0061911382176895,0 +"7219","2015-02-09 18:08:59",22,37.59,0,1742,0.00616299450167052,0 +"7220","2015-02-09 18:10:00",22,37.56,0,1737,0.00615802721484007,0 +"7221","2015-02-09 18:10:59",21.89,37.5,0,1729.5,0.006106557929125,0 +"7222","2015-02-09 18:11:59",21.89,37.5,0,1722,0.006106557929125,0 +"7223","2015-02-09 18:13:00",21.89,37.45,0,1706.75,0.00609833602371425,0 +"7224","2015-02-09 18:14:00",21.89,37.4,0,1697,0.00609011433354991,0 +"7225","2015-02-09 18:15:00",21.89,37.4,0,1694,0.00609011433354991,0 +"7226","2015-02-09 18:16:00",21.84,37.345,0,1682,0.00606235265969029,0 +"7227","2015-02-09 18:16:59",21.79,37.29,0,1678,0.00603469838933611,0 +"7228","2015-02-09 18:17:59",21.79,37.29,0,1661.5,0.00603469838933611,0 +"7229","2015-02-09 18:19:00",21.79,37.2,0,1660.5,0.00601999258511133,0 +"7230","2015-02-09 18:20:00",21.79,37.2,0,1640.5,0.00601999258511133,0 +"7231","2015-02-09 18:21:00",21.73,37.1266666666667,0,1629,0.00598581037832928,0 +"7232","2015-02-09 18:22:00",21.745,37.145,0,1627,0.00599434068599531,0 +"7233","2015-02-09 18:23:00",21.7,37.145,0,1623.5,0.00597771623243678,0 +"7234","2015-02-09 18:23:59",21.7,37.045,0,1585,0.00596146906918631,0 +"7235","2015-02-09 18:24:59",21.7,37,0,1573,0.00595415811999865,0 +"7236","2015-02-09 18:26:00",21.7,37,0,1545.66666666667,0.00595415811999865,0 +"7237","2015-02-09 18:27:00",21.6333333333333,36.9333333333333,0,1544.33333333333,0.00591891616329108,0 +"7238","2015-02-09 18:28:00",21.6,36.9,0,1536,0.0059013622776979,0 +"7239","2015-02-09 18:29:00",21.6,36.925,0,1534.25,0.00590539845049522,0 +"7240","2015-02-09 18:29:59",21.6,36.9,0,1530,0.0059013622776979,0 +"7241","2015-02-09 18:30:59",21.55,36.79,0,1517,0.00586545883536125,0 +"7242","2015-02-09 18:32:00",21.55,36.845,0,1512,0.00587431034246642,0 +"7243","2015-02-09 18:33:00",21.5333333333333,36.79,0,1508.33333333333,0.00585942154944413,0 +"7244","2015-02-09 18:34:00",21.55,36.745,0,1495,0.00585821687881246,0 +"7245","2015-02-09 18:35:00",21.5,36.79,0,1491,0.00584736347174871,0 +"7246","2015-02-09 18:36:00",21.5,36.7,0,1474.5,0.00583292482422426,0 +"7247","2015-02-09 18:36:59",21.5,36.7,0,1461.5,0.00583292482422426,0 +"7248","2015-02-09 18:38:00",21.5,36.7,0,1462.5,0.00583292482422426,0 +"7249","2015-02-09 18:39:00",21.39,36.59,0,1466,0.00577586195943773,0 +"7250","2015-02-09 18:40:00",21.445,36.6,0,1453.5,0.00579713925045352,0 +"7251","2015-02-09 18:40:59",21.39,36.59,0,1449,0.00577586195943773,0 +"7252","2015-02-09 18:42:00",21.39,36.5,0,1429,0.00576152354219283,0 +"7253","2015-02-09 18:42:59",21.39,36.5,0,1421,0.00576152354219283,0 +"7254","2015-02-09 18:43:59",21.39,36.5,0,1419,0.00576152354219283,0 +"7255","2015-02-09 18:45:00",21.34,36.5,0,1408,0.00574372990947641,0 +"7256","2015-02-09 18:46:00",21.29,36.4,0,1399.5,0.00571015326926369,0 +"7257","2015-02-09 18:47:00",21.29,36.4,0,1391,0.00571015326926369,0 +"7258","2015-02-09 18:48:00",21.29,36.5,0,1390,0.00572598491648893,0 +"7259","2015-02-09 18:49:00",21.29,36.4333333333333,0,1392.33333333333,0.00571543039627487,0 +"7260","2015-02-09 18:49:59",21.29,36.4,0,1381,0.00571015326926369,0 +"7261","2015-02-09 18:51:00",21.29,36.45,0,1381.5,0.005718068993054,0 +"7262","2015-02-09 18:52:00",21.2,36.29,0,1372,0.00566110700337774,0 +"7263","2015-02-09 18:53:00",21.2,36.245,0,1355,0.00565402335750479,0 +"7264","2015-02-09 18:53:59",21.2,36.2,0,1356,0.00564693987151898,0 +"7265","2015-02-09 18:55:00",21.2,36.2,0,1341,0.00564693987151898,0 +"7266","2015-02-09 18:55:59",21.2,36.2,0,1335.5,0.00564693987151898,0 +"7267","2015-02-09 18:56:59",21.2,36.2,0,1320.5,0.00564693987151898,0 +"7268","2015-02-09 18:58:00",21.2,36.2,0,1313,0.00564693987151898,0 +"7269","2015-02-09 18:59:00",21.1,36.2,0,1298,0.00561206354418701,0 +"7270","2015-02-09 19:00:00",21.1,36.2,0,1303,0.00561206354418701,0 +"7271","2015-02-09 19:01:00",21.1,36.2,0,1295,0.00561206354418701,0 +"7272","2015-02-09 19:01:59",21.1,36.145,0,1287,0.00560346011391267,0 +"7273","2015-02-09 19:02:59",21,36.09,0,1280,0.00556027858312086,0 +"7274","2015-02-09 19:04:00",21.05,36.145,0,1275.5,0.00558612038088222,0 +"7275","2015-02-09 19:05:00",21,36.09,0,1268,0.00556027858312086,0 +"7276","2015-02-09 19:06:00",21,36.145,0,1267.5,0.00556882813471963,0 +"7277","2015-02-09 19:07:00",21,36.09,0,1267,0.00556027858312086,0 +"7278","2015-02-09 19:08:00",21,36.1266666666667,0,1267.66666666667,0.00556597825830358,0 +"7279","2015-02-09 19:08:59",21,36.09,0,1265,0.00556027858312086,0 +"7280","2015-02-09 19:09:59",21,36.09,0,1256,0.00556027858312086,0 +"7281","2015-02-09 19:11:00",21,36.09,0,1250,0.00556027858312086,0 +"7282","2015-02-09 19:12:00",20.945,36.09,0,1249.5,0.00554134120040385,0 +"7283","2015-02-09 19:13:00",20.89,36.09,0,1243,0.00552246089912342,0 +"7284","2015-02-09 19:14:00",20.89,36.045,0,1237,0.00551551397806286,0 +"7285","2015-02-09 19:14:59",20.89,36,0,1227,0.0055085672108109,0 +"7286","2015-02-09 19:15:59",20.945,36,0,1206.5,0.00552739959367409,0 +"7287","2015-02-09 19:17:00",20.89,36,0,1211.66666666667,0.0055085672108109,0 +"7288","2015-02-09 19:18:00",20.89,36,0,1204,0.0055085672108109,0 +"7289","2015-02-09 19:19:00",20.89,35.95,0,1204,0.00550084876091754,0 +"7290","2015-02-09 19:20:00",20.89,35.9,0,1200,0.00549313050089804,0 +"7291","2015-02-09 19:21:00",20.89,35.9,0,1194,0.00549313050089804,0 +"7292","2015-02-09 19:21:59",20.8233333333333,35.8266666666667,0,1182.66666666667,0.00545917118307227,0 +"7293","2015-02-09 19:23:00",20.79,35.79,0,1169,0.0054422580579229,0 +"7294","2015-02-09 19:24:00",20.79,35.79,0,1161,0.0054422580579229,0 +"7295","2015-02-09 19:25:00",20.79,35.79,0,1158,0.0054422580579229,0 +"7296","2015-02-09 19:25:59",20.79,35.7,0,1165,0.00542845314196803,0 +"7297","2015-02-09 19:27:00",20.79,35.7,0,1152.5,0.00542845314196803,0 +"7298","2015-02-09 19:27:59",20.79,35.73,0,1145.66666666667,0.00543305471312266,0 +"7299","2015-02-09 19:28:59",20.7,35.7,0,1136.5,0.00539818592367348,0 +"7300","2015-02-09 19:30:00",20.7,35.7,0,1136,0.00539818592367348,0 +"7301","2015-02-09 19:31:00",20.7,35.7,0,1131,0.00539818592367348,0 +"7302","2015-02-09 19:32:00",20.7,35.7,0,1133.5,0.00539818592367348,0 +"7303","2015-02-09 19:33:00",20.7,35.7,0,1134,0.00539818592367348,0 +"7304","2015-02-09 19:34:00",20.7,35.59,0,1120,0.00538140895212765,0 +"7305","2015-02-09 19:34:59",20.7,35.59,0,1116,0.00538140895212765,0 +"7306","2015-02-09 19:36:00",20.7,35.59,0,1098,0.00538140895212765,0 +"7307","2015-02-09 19:37:00",20.7,35.59,0,1101.5,0.00538140895212765,0 +"7308","2015-02-09 19:38:00",20.7,35.59,0,1108,0.00538140895212765,0 +"7309","2015-02-09 19:38:59",20.7,35.5,0,1099,0.00536768300640675,0 +"7310","2015-02-09 19:40:00",20.7,35.4,0,1082,0.00535243265999211,0 +"7311","2015-02-09 19:40:59",20.7,35.5,0,1081,0.00536768300640675,0 +"7312","2015-02-09 19:41:59",20.7675,35.4,0,1078.25,0.00537492510513876,0 +"7313","2015-02-09 19:43:00",20.73,35.4,0,1065.66666666667,0.00536241900348995,0 +"7314","2015-02-09 19:44:00",20.7,35.345,0,1060,0.00534404528549227,0 +"7315","2015-02-09 19:45:00",20.7,35.29,0,1060.5,0.00533565813525907,0 +"7316","2015-02-09 19:46:00",20.7,35.29,0,1060,0.00533565813525907,0 +"7317","2015-02-09 19:46:59",20.7,35.29,0,1059,0.00533565813525907,0 +"7318","2015-02-09 19:47:59",20.7,35.29,0,1054,0.00533565813525907,0 +"7319","2015-02-09 19:49:00",20.7,35.29,0,1044,0.00533565813525907,0 +"7320","2015-02-09 19:50:00",20.7,35.29,0,1048,0.00533565813525907,0 +"7321","2015-02-09 19:51:00",20.6666666666667,35.26,0,1039.66666666667,0.00532005133449848,0 +"7322","2015-02-09 19:52:00",20.7,35.29,0,1029,0.00533565813525907,0 +"7323","2015-02-09 19:53:00",20.7,35.29,0,1031.5,0.00533565813525907,0 +"7324","2015-02-09 19:53:59",20.7,35.29,0,1020,0.00533565813525907,0 +"7325","2015-02-09 19:54:59",20.6666666666667,35.26,0,1019.33333333333,0.00532005133449848,0 +"7326","2015-02-09 19:56:00",20.6333333333333,35.23,0,1018,0.0053044838727835,0 +"7327","2015-02-09 19:57:00",20.6333333333333,35.23,0,1015.66666666667,0.0053044838727835,0 +"7328","2015-02-09 19:58:00",20.6,35.2,0,1008,0.00528895566376233,0 +"7329","2015-02-09 19:59:00",20.6,35.145,0,1004,0.00528062151134093,0 +"7330","2015-02-09 19:59:59",20.6,35.145,0,999,0.00528062151134093,0 +"7331","2015-02-09 20:00:59",20.6,35.09,0,1001,0.00527228758037146,0 +"7332","2015-02-09 20:02:00",20.6,35.09,0,1000,0.00527228758037146,0 +"7333","2015-02-09 20:03:00",20.6,35.09,0,1001,0.00527228758037146,0 +"7334","2015-02-09 20:04:00",20.6,35.09,0,985.5,0.00527228758037146,0 +"7335","2015-02-09 20:05:00",20.6,35.09,0,977,0.00527228758037146,0 +"7336","2015-02-09 20:06:00",20.6,35.09,0,974.5,0.00527228758037146,0 +"7337","2015-02-09 20:06:59",20.5,35,0,972,0.00522604254902212,0 +"7338","2015-02-09 20:08:00",20.6,35,0,964,0.00525865071643927,0 +"7339","2015-02-09 20:09:00",20.6,35,0,970.5,0.00525865071643927,0 +"7340","2015-02-09 20:10:00",20.5666666666667,35,0,964.666666666667,0.00524776139150477,0 +"7341","2015-02-09 20:10:59",20.55,35,0,956,0.00524232421091791,0 +"7342","2015-02-09 20:12:00",20.55,35,0,947.5,0.00524232421091791,0 +"7343","2015-02-09 20:12:59",20.5,34.95,0,943.5,0.0052185141368898,0 +"7344","2015-02-09 20:13:59",20.5,34.9,0,947,0.00521098590547799,0 +"7345","2015-02-09 20:15:00",20.5,34.9,0,921.5,0.00521098590547799,0 +"7346","2015-02-09 20:16:00",20.5,34.9,0,928,0.00521098590547799,0 +"7347","2015-02-09 20:17:00",20.5,34.9,0,926.5,0.00521098590547799,0 +"7348","2015-02-09 20:18:00",20.5,34.8633333333333,0,921.333333333333,0.00520546531729683,0 +"7349","2015-02-09 20:19:00",20.5,34.79,0,917,0.0051944244324762,0 +"7350","2015-02-09 20:19:59",20.5,34.9,0,916,0.00521098590547799,0 +"7351","2015-02-09 20:21:00",20.5,34.79,0,911,0.0051944244324762,0 +"7352","2015-02-09 20:22:00",20.5,34.79,0,912.5,0.0051944244324762,0 +"7353","2015-02-09 20:23:00",20.5,34.79,0,902,0.0051944244324762,0 +"7354","2015-02-09 20:23:59",20.5,34.79,0,893,0.0051944244324762,0 +"7355","2015-02-09 20:25:00",20.5,34.79,0,886,0.0051944244324762,0 +"7356","2015-02-09 20:25:59",20.5,34.745,0,890.5,0.00518764953651003,0 +"7357","2015-02-09 20:26:59",20.525,34.7,0,891.25,0.00518893912605085,0 +"7358","2015-02-09 20:28:00",20.5,34.59,0,882,0.00516431490400991,0 +"7359","2015-02-09 20:29:00",20.5,34.59,0,874.5,0.00516431490400991,0 +"7360","2015-02-09 20:30:00",20.5,34.59,0,872.5,0.00516431490400991,0 +"7361","2015-02-09 20:31:00",20.5,34.59,0,869,0.00516431490400991,0 +"7362","2015-02-09 20:31:59",20.5,34.59,0,868.5,0.00516431490400991,0 +"7363","2015-02-09 20:32:59",20.5,34.545,0,869.5,0.00515754065850527,0 +"7364","2015-02-09 20:34:00",20.5,34.5,0,865,0.00515076655934157,0 +"7365","2015-02-09 20:35:00",20.5,34.5,0,856.5,0.00515076655934157,0 +"7366","2015-02-09 20:36:00",20.5,34.5,0,853,0.00515076655934157,0 +"7367","2015-02-09 20:37:00",20.5,34.4,0,843,0.00513571352955725,0 +"7368","2015-02-09 20:38:00",20.55,34.4,0,839,0.00515171146123729,0 +"7369","2015-02-09 20:38:59",20.5,34.4,0,828,0.00513571352955725,0 +"7370","2015-02-09 20:39:59",20.5,34.4,0,833,0.00513571352955725,0 +"7371","2015-02-09 20:41:00",20.55,34.345,0,822,0.00514340660241916,0 +"7372","2015-02-09 20:42:00",20.5,34.29,0,816,0.0051191560313907,0 +"7373","2015-02-09 20:43:00",20.5,34.29,0,814.5,0.0051191560313907,0 +"7374","2015-02-09 20:44:00",20.5,34.245,0,807,0.00511238276140274,0 +"7375","2015-02-09 20:44:59",20.5,34.26,0,807,0.00511464050180856,0 +"7376","2015-02-09 20:45:59",20.5,34.2,0,796,0.00510560963772411,0 +"7377","2015-02-09 20:47:00",20.5,34.2,0,796.333333333333,0.00510560963772411,0 +"7378","2015-02-09 20:48:00",20.5,34.2,0,796.25,0.00510560963772411,0 +"7379","2015-02-09 20:49:00",20.5,34.09,0,795.5,0.00508905372909098,0 +"7380","2015-02-09 20:50:00",20.55,34.09,0,794.5,0.00510490513069162,0 +"7381","2015-02-09 20:51:00",20.5,34,0,793,0.0050755086358581,0 +"7382","2015-02-09 20:51:59",20.5,34.09,0,788.5,0.00508905372909098,0 +"7383","2015-02-09 20:53:00",20.5,34.09,0,788,0.00508905372909098,0 +"7384","2015-02-09 20:54:00",20.5,34.045,0,782,0.00508228110933041,0 +"7385","2015-02-09 20:55:00",20.5,34,0,771,0.0050755086358581,0 +"7386","2015-02-09 20:55:59",20.5,34.09,0,772.666666666667,0.00508905372909098,0 +"7387","2015-02-09 20:57:00",20.5,34.09,0,774,0.00508905372909098,0 +"7388","2015-02-09 20:57:59",20.5,34.09,0,767,0.00508905372909098,0 +"7389","2015-02-09 20:58:59",20.5,34,0,771,0.0050755086358581,0 +"7390","2015-02-09 21:00:00",20.5,34.0675,0,762.5,0.00508566740092436,0 +"7391","2015-02-09 21:01:00",20.5,34.09,0,756,0.00508905372909098,0 +"7392","2015-02-09 21:02:00",20.5,34.045,0,748.5,0.00508228110933041,0 +"7393","2015-02-09 21:03:00",20.5,34.045,0,751.5,0.00508228110933041,0 +"7394","2015-02-09 21:04:00",20.5,34,0,754,0.0050755086358581,0 +"7395","2015-02-09 21:04:59",20.5,34,0,752,0.0050755086358581,0 +"7396","2015-02-09 21:06:00",20.5,34,0,750.5,0.0050755086358581,0 +"7397","2015-02-09 21:07:00",20.5,34,0,757,0.0050755086358581,0 +"7398","2015-02-09 21:08:00",20.5,34,0,755,0.0050755086358581,0 +"7399","2015-02-09 21:08:59",20.5,33.9,0,744.5,0.00506045921853273,0 +"7400","2015-02-09 21:10:00",20.5,33.9,0,740,0.00506045921853273,0 +"7401","2015-02-09 21:10:59",20.5,33.9,0,726,0.00506045921853273,0 +"7402","2015-02-09 21:11:59",20.5,33.9,0,723,0.00506045921853273,0 +"7403","2015-02-09 21:13:00",20.5,33.8266666666667,0,722.666666666667,0.00504942343824823,0 +"7404","2015-02-09 21:14:00",20.5,33.79,0,726,0.00504390569377061,0 +"7405","2015-02-09 21:15:00",20.5,33.8725,0,723.75,0.00505632075540494,0 +"7406","2015-02-09 21:16:00",20.5,33.79,0,721.5,0.00504390569377061,0 +"7407","2015-02-09 21:16:59",20.5,33.79,0,716.5,0.00504390569377061,0 +"7408","2015-02-09 21:17:59",20.5,33.79,0,714,0.00504390569377061,0 +"7409","2015-02-09 21:19:00",20.5,33.79,0,719.5,0.00504390569377061,0 +"7410","2015-02-09 21:20:00",20.5,33.79,0,723,0.00504390569377061,0 +"7411","2015-02-09 21:21:00",20.5,33.76,0,704,0.00503939124778962,0 +"7412","2015-02-09 21:22:00",20.5,33.79,0,695,0.00504390569377061,0 +"7413","2015-02-09 21:23:00",20.5,33.7,0,694.333333333333,0.00503036255083722,0 +"7414","2015-02-09 21:23:59",20.5,33.7,0,692.5,0.00503036255083722,0 +"7415","2015-02-09 21:24:59",20.5,33.745,0,690.5,0.00503713404917558,0 +"7416","2015-02-09 21:26:00",20.5,33.745,0,687.5,0.00503713404917558,0 +"7417","2015-02-09 21:27:00",20.5,33.6266666666667,0,681.666666666667,0.00501932782987423,0 +"7418","2015-02-09 21:28:00",20.5,33.59,0,683,0.0050138106150364,0 +"7419","2015-02-09 21:29:00",20.5,33.59,0,684,0.0050138106150364,0 +"7420","2015-02-09 21:29:59",20.5,33.6266666666667,0,675.666666666667,0.00501932782987423,0 +"7421","2015-02-09 21:30:59",20.5,33.59,0,676,0.0050138106150364,0 +"7422","2015-02-09 21:32:00",20.5,33.59,0,678.5,0.0050138106150364,0 +"7423","2015-02-09 21:33:00",20.5,33.59,0,677,0.0050138106150364,0 +"7424","2015-02-09 21:34:00",20.5,33.59,0,678,0.0050138106150364,0 +"7425","2015-02-09 21:35:00",20.5,33.59,0,671,0.0050138106150364,0 +"7426","2015-02-09 21:36:00",20.5,33.59,0,675.333333333333,0.0050138106150364,0 +"7427","2015-02-09 21:36:59",20.5,33.59,0,673,0.0050138106150364,0 +"7428","2015-02-09 21:38:00",20.5,33.59,0,667,0.0050138106150364,0 +"7429","2015-02-09 21:39:00",20.5,33.59,0,663,0.0050138106150364,0 +"7430","2015-02-09 21:40:00",20.5,33.59,0,657,0.0050138106150364,0 +"7431","2015-02-09 21:40:59",20.5,33.59,0,650,0.0050138106150364,0 +"7432","2015-02-09 21:42:00",20.5,33.545,0,652,0.00500703962043473,0 +"7433","2015-02-09 21:42:59",20.5,33.59,0,653.5,0.0050138106150364,0 +"7434","2015-02-09 21:43:59",20.5,33.5,0,652,0.00500026877206866,0 +"7435","2015-02-09 21:45:00",20.5,33.5,0,647.5,0.00500026877206866,0 +"7436","2015-02-09 21:46:00",20.5,33.5,0,646,0.00500026877206866,0 +"7437","2015-02-09 21:47:00",20.5,33.5,0,645,0.00500026877206866,0 +"7438","2015-02-09 21:48:00",20.5,33.5,0,712.5,0.00500026877206866,0 +"7439","2015-02-09 21:49:00",20.5,33.5,0,759,0.00500026877206866,0 +"7440","2015-02-09 21:49:59",20.4633333333333,33.4666666666667,0,655.666666666667,0.00498387218170032,0 +"7441","2015-02-09 21:51:00",20.5,33.5,0,660.5,0.00500026877206866,0 +"7442","2015-02-09 21:52:00",20.5,33.5,0,657.5,0.00500026877206866,0 +"7443","2015-02-09 21:53:00",20.5,33.5,0,640,0.00500026877206866,0 +"7444","2015-02-09 21:53:59",20.5,33.5,0,641,0.00500026877206866,0 +"7445","2015-02-09 21:55:00",20.5,33.5,0,639,0.00500026877206866,0 +"7446","2015-02-09 21:55:59",20.5,33.5,0,634,0.00500026877206866,0 +"7447","2015-02-09 21:56:59",20.5,33.5,0,632,0.00500026877206866,0 +"7448","2015-02-09 21:58:00",20.5,33.45,0,637.5,0.00499274577872262,0 +"7449","2015-02-09 21:59:00",20.5,33.4,0,662,0.00498522296590201,0 +"7450","2015-02-09 22:00:00",20.5,33.4,0,646.5,0.00498522296590201,0 +"7451","2015-02-09 22:01:00",20.5,33.4,0,629,0.00498522296590201,0 +"7452","2015-02-09 22:01:59",20.5,33.4,0,622,0.00498522296590201,0 +"7453","2015-02-09 22:02:59",20.4633333333333,33.3633333333333,0,621.666666666667,0.00496836081313276,0 +"7454","2015-02-09 22:04:00",20.5,33.4,0,627,0.00498522296590201,0 +"7455","2015-02-09 22:05:00",20.5,33.29,0,630,0.00496867341311421,0 +"7456","2015-02-09 22:06:00",20.5,33.345,0,625.5,0.00497694808029848,0 +"7457","2015-02-09 22:07:00",20.5,33.4,0,617,0.00498522296590201,0 +"7458","2015-02-09 22:08:00",20.5,33.29,0,614.5,0.00496867341311421,0 +"7459","2015-02-09 22:08:59",20.5,33.29,0,613,0.00496867341311421,0 +"7460","2015-02-09 22:09:59",20.445,33.29,0,619,0.0049517016631172,0 +"7461","2015-02-09 22:11:00",20.5,33.29,0,1365,0.00496867341311421,0 +"7462","2015-02-09 22:12:00",20.5,33.29,0,894,0.00496867341311421,0 +"7463","2015-02-09 22:13:00",20.5,33.29,0,1101.33333333333,0.00496867341311421,0 +"7464","2015-02-09 22:14:00",20.5,33.29,0,1165,0.00496867341311421,0 +"7465","2015-02-09 22:14:59",20.5,33.29,0,622,0.00496867341311421,0 +"7466","2015-02-09 22:15:59",20.445,33.245,0,617.5,0.00494495495041682,0 +"7467","2015-02-09 22:17:00",20.5,33.29,0,610.5,0.00496867341311421,0 +"7468","2015-02-09 22:18:00",20.5,33.2675,0,602.75,0.00496528838494487,0 +"7469","2015-02-09 22:19:00",20.5,33.29,0,596.5,0.00496867341311421,0 +"7470","2015-02-09 22:20:00",20.5,33.29,0,598,0.00496867341311421,0 +"7471","2015-02-09 22:21:00",20.445,33.245,0,594,0.00494495495041682,0 +"7472","2015-02-09 22:21:59",20.445,33.245,0,593.5,0.00494495495041682,0 +"7473","2015-02-09 22:23:00",20.445,33.245,0,590,0.00494495495041682,0 +"7474","2015-02-09 22:24:00",20.445,33.19,0,582,0.00493670916541628,0 +"7475","2015-02-09 22:25:00",20.445,33.19,0,588.5,0.00493670916541628,0 +"7476","2015-02-09 22:25:59",20.5,33.1633333333333,0,593.666666666667,0.00494961743454958,0 +"7477","2015-02-09 22:27:00",20.5,33.2,0,594.5,0.00495513351974405,0 +"7478","2015-02-09 22:27:59",20.5,33.09,0,588,0.0049385855553457,0 +"7479","2015-02-09 22:28:59",20.5,33.09,0,584,0.0049385855553457,0 +"7480","2015-02-09 22:30:00",20.5,33.09,0,583,0.0049385855553457,0 +"7481","2015-02-09 22:31:00",20.5,33.2,0,583.333333333333,0.00495513351974405,0 +"7482","2015-02-09 22:32:00",20.5,33.2,0,579.5,0.00495513351974405,0 +"7483","2015-02-09 22:33:00",20.5,33.2,0,583.5,0.00495513351974405,0 +"7484","2015-02-09 22:34:00",20.5,33.2,0,585,0.00495513351974405,0 +"7485","2015-02-09 22:34:59",20.445,33.145,0,581,0.00492996277538293,0 +"7486","2015-02-09 22:36:00",20.39,33.09,0,579,0.00490490015755043,0 +"7487","2015-02-09 22:37:00",20.5,33.09,0,578.5,0.0049385855553457,0 +"7488","2015-02-09 22:38:00",20.5,33.145,0,577.5,0.00494685942835096,0 +"7489","2015-02-09 22:38:59",20.5,33.09,0,571,0.0049385855553457,0 +"7490","2015-02-09 22:40:00",20.5,33.09,0,576,0.0049385855553457,0 +"7491","2015-02-09 22:40:59",20.5,33.09,0,581,0.0049385855553457,0 +"7492","2015-02-09 22:41:59",20.5,33.09,0,572,0.0049385855553457,0 +"7493","2015-02-09 22:43:00",20.5,33.09,0,561,0.0049385855553457,0 +"7494","2015-02-09 22:44:00",20.5,33.09,0,562,0.0049385855553457,0 +"7495","2015-02-09 22:45:00",20.4266666666667,33.03,0,564,0.00490712159973179,0 +"7496","2015-02-09 22:46:00",20.39,33,0,567,0.00489145462900984,0 +"7497","2015-02-09 22:46:59",20.5,33.09,0,562,0.0049385855553457,0 +"7498","2015-02-09 22:47:59",20.445,33.045,0,559,0.00491497131734958,0 +"7499","2015-02-09 22:49:00",20.5,33.09,0,570,0.0049385855553457,0 +"7500","2015-02-09 22:50:00",20.5,33.09,0,563,0.0049385855553457,0 +"7501","2015-02-09 22:51:00",20.5,33.09,0,557,0.0049385855553457,0 +"7502","2015-02-09 22:52:00",20.39,33,0,558,0.00489145462900984,0 +"7503","2015-02-09 22:53:00",20.5,33.09,0,554,0.0049385855553457,0 +"7504","2015-02-09 22:53:59",20.445,33.045,0,552.5,0.00491497131734958,0 +"7505","2015-02-09 22:54:59",20.445,33.045,0,550.5,0.00491497131734958,0 +"7506","2015-02-09 22:56:00",20.4266666666667,33.03,0,549,0.00490712159973179,0 +"7507","2015-02-09 22:57:00",20.5,33.09,0,554,0.0049385855553457,0 +"7508","2015-02-09 22:58:00",20.5,33.09,0,550,0.0049385855553457,0 +"7509","2015-02-09 22:59:00",20.39,33,0,549,0.00489145462900984,0 +"7510","2015-02-09 22:59:59",20.39,33,0,545.5,0.00489145462900984,0 +"7511","2015-02-09 23:00:59",20.5,33,0,546,0.00492504696147335,0 +"7512","2015-02-09 23:02:00",20.445,33.045,0,545.5,0.00491497131734958,0 +"7513","2015-02-09 23:03:00",20.445,33,0,546,0.0049082253951423,0 +"7514","2015-02-09 23:04:00",20.445,33,0,543,0.0049082253951423,0 +"7515","2015-02-09 23:05:00",20.39,33,0,544.5,0.00489145462900984,0 +"7516","2015-02-09 23:06:00",20.39,33,0,545,0.00489145462900984,0 +"7517","2015-02-09 23:06:59",20.5,33,0,543,0.00492504696147335,0 +"7518","2015-02-09 23:08:00",20.39,33,0,540.5,0.00489145462900984,0 +"7519","2015-02-09 23:09:00",20.39,33,0,542,0.00489145462900984,0 +"7520","2015-02-09 23:10:00",20.445,33.0225,0,539.5,0.00491159833809846,0 +"7521","2015-02-09 23:10:59",20.39,33,0,541,0.00489145462900984,0 +"7522","2015-02-09 23:12:00",20.39,33,0,540,0.00489145462900984,0 +"7523","2015-02-09 23:12:59",20.39,33,0,538,0.00489145462900984,0 +"7524","2015-02-09 23:13:59",20.39,33,0,541.5,0.00489145462900984,0 +"7525","2015-02-09 23:15:00",20.39,33,0,543,0.00489145462900984,0 +"7526","2015-02-09 23:16:00",20.39,33,0,540.5,0.00489145462900984,0 +"7527","2015-02-09 23:17:00",20.39,33,0,538,0.00489145462900984,0 +"7528","2015-02-09 23:18:00",20.39,32.9,0,527,0.00487651582926721,0 +"7529","2015-02-09 23:19:00",20.39,33,0,526.5,0.00489145462900984,0 +"7530","2015-02-09 23:19:59",20.39,33,0,530,0.00489145462900984,0 +"7531","2015-02-09 23:21:00",20.39,32.9,0,527,0.00487651582926721,0 +"7532","2015-02-09 23:22:00",20.39,33,0,531.25,0.00489145462900984,0 +"7533","2015-02-09 23:23:00",20.39,33,0,533,0.00489145462900984,0 +"7534","2015-02-09 23:23:59",20.39,33,0,535.333333333333,0.00489145462900984,0 +"7535","2015-02-09 23:25:00",20.39,33,0,529,0.00489145462900984,0 +"7536","2015-02-09 23:25:59",20.39,32.9,0,527,0.00487651582926721,0 +"7537","2015-02-09 23:26:59",20.39,33,0,531,0.00489145462900984,0 +"7538","2015-02-09 23:28:00",20.39,33,0,532,0.00489145462900984,0 +"7539","2015-02-09 23:29:00",20.39,33,0,530,0.00489145462900984,0 +"7540","2015-02-09 23:30:00",20.39,33,0,521,0.00489145462900984,0 +"7541","2015-02-09 23:31:00",20.39,33,0,521.5,0.00489145462900984,0 +"7542","2015-02-09 23:31:59",20.39,32.9,0,524,0.00487651582926721,0 +"7543","2015-02-09 23:32:59",20.39,32.9,0,523,0.00487651582926721,0 +"7544","2015-02-09 23:34:00",20.39,33,0,520.5,0.00489145462900984,0 +"7545","2015-02-09 23:35:00",20.39,33,0,520,0.00489145462900984,0 +"7546","2015-02-09 23:36:00",20.39,33,0,521.333333333333,0.00489145462900984,0 +"7547","2015-02-09 23:37:00",20.39,33,0,523,0.00489145462900984,0 +"7548","2015-02-09 23:38:00",20.39,32.9,0,515,0.00487651582926721,0 +"7549","2015-02-09 23:38:59",20.39,32.95,0,514.5,0.00488398514013971,0 +"7550","2015-02-09 23:39:59",20.39,32.95,0,511,0.00488398514013971,0 +"7551","2015-02-09 23:41:00",20.39,33,0,513,0.00489145462900984,0 +"7552","2015-02-09 23:42:00",20.39,32.95,0,513,0.00488398514013971,0 +"7553","2015-02-09 23:43:00",20.39,32.9,0,514,0.00487651582926721,0 +"7554","2015-02-09 23:44:00",20.39,32.9,0,511,0.00487651582926721,0 +"7555","2015-02-09 23:44:59",20.39,32.9,0,502,0.00487651582926721,0 +"7556","2015-02-09 23:45:59",20.39,32.9,0,506.333333333333,0.00487651582926721,0 +"7557","2015-02-09 23:47:00",20.39,32.9,0,505.5,0.00487651582926721,0 +"7558","2015-02-09 23:48:00",20.39,32.9,0,510,0.00487651582926721,0 +"7559","2015-02-09 23:49:00",20.39,32.9,0,508,0.00487651582926721,0 +"7560","2015-02-09 23:50:00",20.39,32.9,0,506.5,0.00487651582926721,0 +"7561","2015-02-09 23:51:00",20.39,32.9,0,501,0.00487651582926721,0 +"7562","2015-02-09 23:51:59",20.39,32.9,0,512,0.00487651582926721,0 +"7563","2015-02-09 23:53:00",20.39,32.9,0,511,0.00487651582926721,0 +"7564","2015-02-09 23:54:00",20.39,32.9,0,504,0.00487651582926721,0 +"7565","2015-02-09 23:55:00",20.39,32.9,0,502.5,0.00487651582926721,0 +"7566","2015-02-09 23:55:59",20.39,32.9,0,501,0.00487651582926721,0 +"7567","2015-02-09 23:57:00",20.39,32.9,0,502,0.00487651582926721,0 +"7568","2015-02-09 23:57:59",20.39,32.9,0,505,0.00487651582926721,0 +"7569","2015-02-09 23:58:59",20.39,33,0,506.5,0.00489145462900984,0 +"7570","2015-02-10 00:00:00",20.39,32.95,0,498.5,0.00488398514013971,0 +"7571","2015-02-10 00:01:00",20.3566666666667,33,0,500.333333333333,0.00488131519570132,0 +"7572","2015-02-10 00:02:00",20.39,33,0,500.5,0.00489145462900984,0 +"7573","2015-02-10 00:03:00",20.39,32.9666666666667,0,500.333333333333,0.00488647494998525,0 +"7574","2015-02-10 00:04:00",20.365,32.95,0,500.5,0.00487639052761436,0 +"7575","2015-02-10 00:04:59",20.39,32.9,0,498,0.00487651582926721,0 +"7576","2015-02-10 00:06:00",20.39,32.9,0,499,0.00487651582926721,0 +"7577","2015-02-10 00:07:00",20.39,32.9,0,500.5,0.00487651582926721,0 +"7578","2015-02-10 00:08:00",20.39,32.95,0,503,0.00488398514013971,0 +"7579","2015-02-10 00:08:59",20.39,33,0,503,0.00489145462900984,0 +"7580","2015-02-10 00:10:00",20.39,33,0,508,0.00489145462900984,0 +"7581","2015-02-10 00:10:59",20.39,33,0,499,0.00489145462900984,0 +"7582","2015-02-10 00:11:59",20.34,33,0,499.5,0.00487625244872327,0 +"7583","2015-02-10 00:13:00",20.29,33,0,499.333333333333,0.00486109204215602,0 +"7584","2015-02-10 00:14:00",20.29,33,0,492,0.00486109204215602,0 +"7585","2015-02-10 00:15:00",20.29,33,0,488.5,0.00486109204215602,0 +"7586","2015-02-10 00:16:00",20.29,33,0,490,0.00486109204215602,0 +"7587","2015-02-10 00:16:59",20.39,33,0,487,0.00489145462900984,0 +"7588","2015-02-10 00:17:59",20.3233333333333,33,0,489.666666666667,0.0048711943432678,0 +"7589","2015-02-10 00:19:00",20.29,33,0,488,0.00486109204215602,0 +"7590","2015-02-10 00:20:00",20.34,32.95,0,481,0.0048688063546182,0 +"7591","2015-02-10 00:21:00",20.29,33,0,487,0.00486109204215602,0 +"7592","2015-02-10 00:22:00",20.34,33,0,490.5,0.00487625244872327,0 +"7593","2015-02-10 00:23:00",20.3233333333333,32.9666666666667,0,488.333333333333,0.00486623545005901,0 +"7594","2015-02-10 00:23:59",20.29,33,0,489,0.00486109204215602,0 +"7595","2015-02-10 00:24:59",20.34,33,0,489.5,0.00487625244872327,0 +"7596","2015-02-10 00:26:00",20.315,33,0,487,0.00486866702995703,0 +"7597","2015-02-10 00:27:00",20.34,33,0,483.666666666667,0.00487625244872327,0 +"7598","2015-02-10 00:28:00",20.34,32.95,0,488,0.0048688063546182,0 +"7599","2015-02-10 00:29:00",20.29,33,0,488,0.00486109204215602,0 +"7600","2015-02-10 00:29:59",20.29,33,0,490,0.00486109204215602,0 +"7601","2015-02-10 00:30:59",20.29,33,0,488,0.00486109204215602,0 +"7602","2015-02-10 00:32:00",20.29,33,0,487,0.00486109204215602,0 +"7603","2015-02-10 00:33:00",20.3233333333333,33,0,483.5,0.0048711943432678,0 +"7604","2015-02-10 00:34:00",20.29,33,0,482,0.00486109204215602,0 +"7605","2015-02-10 00:35:00",20.29,33,0,482,0.00486109204215602,0 +"7606","2015-02-10 00:36:00",20.29,33,0,484,0.00486109204215602,0 +"7607","2015-02-10 00:36:59",20.29,32.95,0,483.5,0.00485366927741052,0 +"7608","2015-02-10 00:38:00",20.29,33,0,482.5,0.00486109204215602,0 +"7609","2015-02-10 00:39:00",20.29,33,0,485,0.00486109204215602,0 +"7610","2015-02-10 00:40:00",20.34,33,0,478.5,0.00487625244872327,0 +"7611","2015-02-10 00:40:59",20.29,32.975,0,474.75,0.0048573806378096,0 +"7612","2015-02-10 00:42:00",20.3233333333333,32.9666666666667,0,476.333333333333,0.00486623545005901,0 +"7613","2015-02-10 00:42:59",20.29,32.9,0,481,0.00484624668845129,0 +"7614","2015-02-10 00:43:59",20.39,32.9,0,479,0.00487651582926721,0 +"7615","2015-02-10 00:45:00",20.29,32.925,0,480,0.00484995796095802,0 +"7616","2015-02-10 00:46:00",20.29,33,0,478,0.00486109204215602,0 +"7617","2015-02-10 00:47:00",20.29,32.9,0,480.5,0.00484624668845129,0 +"7618","2015-02-10 00:48:00",20.29,33,0,477.5,0.00486109204215602,0 +"7619","2015-02-10 00:49:00",20.29,32.9333333333333,0,477.333333333333,0.00485119506155928,0 +"7620","2015-02-10 00:49:59",20.29,33,0,477,0.00486109204215602,0 +"7621","2015-02-10 00:51:00",20.29,33,0,477.5,0.00486109204215602,0 +"7622","2015-02-10 00:52:00",20.29,33,0,480,0.00486109204215602,0 +"7623","2015-02-10 00:53:00",20.29,33,0,482,0.00486109204215602,0 +"7624","2015-02-10 00:53:59",20.34,33,0,479.5,0.00487625244872327,0 +"7625","2015-02-10 00:55:00",20.29,33,0,482,0.00486109204215602,0 +"7626","2015-02-10 00:55:59",20.29,33,0,478,0.00486109204215602,0 +"7627","2015-02-10 00:56:59",20.29,32.9,0,479,0.00484624668845129,0 +"7628","2015-02-10 00:58:00",20.29,33,0,477,0.00486109204215602,0 +"7629","2015-02-10 00:59:00",20.29,32.9,0,477,0.00484624668845129,0 +"7630","2015-02-10 01:00:00",20.3233333333333,33,0,480.333333333333,0.0048711943432678,0 +"7631","2015-02-10 01:01:00",20.29,32.9,0,482,0.00484624668845129,0 +"7632","2015-02-10 01:01:59",20.29,32.9666666666667,0,482,0.00485614351279357,0 +"7633","2015-02-10 01:02:59",20.29,33,0,476,0.00486109204215602,0 +"7634","2015-02-10 01:04:00",20.29,33,0,471.5,0.00486109204215602,0 +"7635","2015-02-10 01:05:00",20.29,33,0,470,0.00486109204215602,0 +"7636","2015-02-10 01:06:00",20.29,32.9666666666667,0,482,0.00485614351279357,0 +"7637","2015-02-10 01:07:00",20.29,33,0,478.5,0.00486109204215602,0 +"7638","2015-02-10 01:08:00",20.29,33,0,472,0.00486109204215602,0 +"7639","2015-02-10 01:08:59",20.29,32.95,0,475,0.00485366927741052,0 +"7640","2015-02-10 01:09:59",20.29,32.95,0,474,0.00485366927741052,0 +"7641","2015-02-10 01:11:00",20.29,32.9666666666667,0,469,0.00485614351279357,0 +"7642","2015-02-10 01:12:00",20.29,32.9,0,469,0.00484624668845129,0 +"7643","2015-02-10 01:13:00",20.29,32.9,0,467,0.00484624668845129,0 +"7644","2015-02-10 01:14:00",20.29,32.9,0,469,0.00484624668845129,0 +"7645","2015-02-10 01:14:59",20.29,32.9,0,473,0.00484624668845129,0 +"7646","2015-02-10 01:15:59",20.29,32.9,0,474,0.00484624668845129,0 +"7647","2015-02-10 01:17:00",20.29,32.9,0,474,0.00484624668845129,0 +"7648","2015-02-10 01:18:00",20.29,32.9,0,471,0.00484624668845129,0 +"7649","2015-02-10 01:19:00",20.29,32.9,0,472,0.00484624668845129,0 +"7650","2015-02-10 01:20:00",20.29,32.95,0,468,0.00485366927741052,0 +"7651","2015-02-10 01:21:00",20.29,32.9,0,465.5,0.00484624668845129,0 +"7652","2015-02-10 01:21:59",20.29,32.9,0,471,0.00484624668845129,0 +"7653","2015-02-10 01:23:00",20.29,32.95,0,473,0.00485366927741052,0 +"7654","2015-02-10 01:24:00",20.29,32.95,0,473,0.00485366927741052,0 +"7655","2015-02-10 01:25:00",20.245,32.9,0,469,0.0048326798369998,0 +"7656","2015-02-10 01:25:59",20.245,32.95,0,465.5,0.00484008148630936,0 +"7657","2015-02-10 01:27:00",20.29,33,0,461,0.00486109204215602,0 +"7658","2015-02-10 01:27:59",20.29,33,0,467,0.00486109204215602,0 +"7659","2015-02-10 01:28:59",20.29,33,0,468.666666666667,0.00486109204215602,0 +"7660","2015-02-10 01:30:00",20.29,33,0,471,0.00486109204215602,0 +"7661","2015-02-10 01:31:00",20.29,33,0,470,0.00486109204215602,0 +"7662","2015-02-10 01:32:00",20.29,32.95,0,468,0.00485366927741052,0 +"7663","2015-02-10 01:33:00",20.29,32.9,0,466,0.00484624668845129,0 +"7664","2015-02-10 01:34:00",20.29,32.95,0,463,0.00485366927741052,0 +"7665","2015-02-10 01:34:59",20.29,32.95,0,463,0.00485366927741052,0 +"7666","2015-02-10 01:36:00",20.29,32.9,0,463.333333333333,0.00484624668845129,0 +"7667","2015-02-10 01:37:00",20.29,33,0,465,0.00486109204215602,0 +"7668","2015-02-10 01:38:00",20.29,33,0,465,0.00486109204215602,0 +"7669","2015-02-10 01:38:59",20.29,32.9,0,468,0.00484624668845129,0 +"7670","2015-02-10 01:40:00",20.29,32.9,0,470,0.00484624668845129,0 +"7671","2015-02-10 01:40:59",20.29,32.9,0,464,0.00484624668845129,0 +"7672","2015-02-10 01:41:59",20.29,32.9,0,461,0.00484624668845129,0 +"7673","2015-02-10 01:43:00",20.245,32.845,0,454,0.00482453822464545,0 +"7674","2015-02-10 01:44:00",20.29,33,0,456,0.00486109204215602,0 +"7675","2015-02-10 01:45:00",20.29,32.9,0,464.5,0.00484624668845129,0 +"7676","2015-02-10 01:46:00",20.29,32.9666666666667,0,466.333333333333,0.00485614351279357,0 +"7677","2015-02-10 01:46:59",20.29,32.95,0,465,0.00485366927741052,0 +"7678","2015-02-10 01:47:59",20.29,32.9,0,466,0.00484624668845129,0 +"7679","2015-02-10 01:49:00",20.29,32.9333333333333,0,460,0.00485119506155928,0 +"7680","2015-02-10 01:50:00",20.29,33,0,457,0.00486109204215602,0 +"7681","2015-02-10 01:51:00",20.29,32.9,0,463,0.00484624668845129,0 +"7682","2015-02-10 01:52:00",20.29,32.9,0,461,0.00484624668845129,0 +"7683","2015-02-10 01:53:00",20.29,32.9,0,462,0.00484624668845129,0 +"7684","2015-02-10 01:53:59",20.29,32.9,0,462,0.00484624668845129,0 +"7685","2015-02-10 01:54:59",20.29,32.9,0,457.333333333333,0.00484624668845129,0 +"7686","2015-02-10 01:56:00",20.29,32.9,0,456,0.00484624668845129,0 +"7687","2015-02-10 01:57:00",20.29,32.95,0,461.5,0.00485366927741052,0 +"7688","2015-02-10 01:58:00",20.29,33,0,461.5,0.00486109204215602,0 +"7689","2015-02-10 01:59:00",20.29,32.9,0,461,0.00484624668845129,0 +"7690","2015-02-10 01:59:59",20.29,32.9,0,460,0.00484624668845129,0 +"7691","2015-02-10 02:00:59",20.29,32.9,0,459,0.00484624668845129,0 +"7692","2015-02-10 02:02:00",20.29,32.9,0,463,0.00484624668845129,0 +"7693","2015-02-10 02:03:00",20.29,32.9,0,462,0.00484624668845129,0 +"7694","2015-02-10 02:04:00",20.29,32.9,0,464,0.00484624668845129,0 +"7695","2015-02-10 02:05:00",20.29,32.9,0,461,0.00484624668845129,0 +"7696","2015-02-10 02:06:00",20.245,32.845,0,461.5,0.00482453822464545,0 +"7697","2015-02-10 02:06:59",20.29,32.9,0,460,0.00484624668845129,0 +"7698","2015-02-10 02:08:00",20.29,32.9666666666667,0,460,0.00485614351279357,0 +"7699","2015-02-10 02:09:00",20.29,32.9333333333333,0,459,0.00485119506155928,0 +"7700","2015-02-10 02:10:00",20.245,32.895,0,456.5,0.00483193968168258,0 +"7701","2015-02-10 02:10:59",20.245,32.845,0,452,0.00482453822464545,0 +"7702","2015-02-10 02:12:00",20.29,32.9,0,456.5,0.00484624668845129,0 +"7703","2015-02-10 02:12:59",20.29,32.9,0,458.5,0.00484624668845129,0 +"7704","2015-02-10 02:13:59",20.29,32.9,0,460.5,0.00484624668845129,0 +"7705","2015-02-10 02:15:00",20.29,32.9,0,459.5,0.00484624668845129,0 +"7706","2015-02-10 02:16:00",20.29,32.9,0,461.333333333333,0.00484624668845129,0 +"7707","2015-02-10 02:17:00",20.29,32.9,0,460,0.00484624668845129,0 +"7708","2015-02-10 02:18:00",20.29,32.9,0,457,0.00484624668845129,0 +"7709","2015-02-10 02:19:00",20.29,32.9,0,462,0.00484624668845129,0 +"7710","2015-02-10 02:19:59",20.29,32.9,0,460,0.00484624668845129,0 +"7711","2015-02-10 02:21:00",20.29,32.9,0,463,0.00484624668845129,0 +"7712","2015-02-10 02:22:00",20.245,32.845,0,461,0.00482453822464545,0 +"7713","2015-02-10 02:23:00",20.245,32.845,0,459,0.00482453822464545,0 +"7714","2015-02-10 02:23:59",20.29,32.9,0,459,0.00484624668845129,0 +"7715","2015-02-10 02:25:00",20.29,32.9,0,463,0.00484624668845129,0 +"7716","2015-02-10 02:25:59",20.29,32.9,0,460,0.00484624668845129,0 +"7717","2015-02-10 02:26:59",20.29,32.9,0,458.5,0.00484624668845129,0 +"7718","2015-02-10 02:28:00",20.29,32.9,0,458,0.00484624668845129,0 +"7719","2015-02-10 02:29:00",20.29,32.9,0,459.5,0.00484624668845129,0 +"7720","2015-02-10 02:30:00",20.29,32.9,0,459.5,0.00484624668845129,0 +"7721","2015-02-10 02:31:00",20.29,32.9,0,457.5,0.00484624668845129,0 +"7722","2015-02-10 02:31:59",20.245,32.845,0,455,0.00482453822464545,0 +"7723","2015-02-10 02:32:59",20.29,32.9,0,460,0.00484624668845129,0 +"7724","2015-02-10 02:34:00",20.245,32.845,0,455.5,0.00482453822464545,0 +"7725","2015-02-10 02:35:00",20.29,32.9,0,457,0.00484624668845129,0 +"7726","2015-02-10 02:36:00",20.29,32.9,0,455,0.00484624668845129,0 +"7727","2015-02-10 02:37:00",20.245,32.845,0,452.5,0.00482453822464545,0 +"7728","2015-02-10 02:38:00",20.26,32.8633333333333,0,455.333333333333,0.00483176550721526,0 +"7729","2015-02-10 02:38:59",20.245,32.845,0,458.5,0.00482453822464545,0 +"7730","2015-02-10 02:39:59",20.29,32.9,0,460,0.00484624668845129,0 +"7731","2015-02-10 02:41:00",20.29,32.9,0,458,0.00484624668845129,0 +"7732","2015-02-10 02:42:00",20.29,32.9,0,455.5,0.00484624668845129,0 +"7733","2015-02-10 02:43:00",20.29,32.9,0,453.333333333333,0.00484624668845129,0 +"7734","2015-02-10 02:44:00",20.29,32.9,0,454,0.00484624668845129,0 +"7735","2015-02-10 02:44:59",20.29,32.9,0,457,0.00484624668845129,0 +"7736","2015-02-10 02:45:59",20.29,32.9,0,454.333333333333,0.00484624668845129,0 +"7737","2015-02-10 02:47:00",20.245,32.845,0,451,0.00482453822464545,0 +"7738","2015-02-10 02:48:00",20.2,32.79,0,451,0.00480290949816871,0 +"7739","2015-02-10 02:49:00",20.29,32.9,0,449,0.00484624668845129,0 +"7740","2015-02-10 02:50:00",20.29,32.9,0,454,0.00484624668845129,0 +"7741","2015-02-10 02:51:00",20.29,32.9,0,454.5,0.00484624668845129,0 +"7742","2015-02-10 02:51:59",20.245,32.845,0,453,0.00482453822464545,0 +"7743","2015-02-10 02:53:00",20.245,32.845,0,451.5,0.00482453822464545,0 +"7744","2015-02-10 02:54:00",20.2,32.79,0,455,0.00480290949816871,0 +"7745","2015-02-10 02:55:00",20.29,32.9,0,453,0.00484624668845129,0 +"7746","2015-02-10 02:55:59",20.29,32.9,0,457,0.00484624668845129,0 +"7747","2015-02-10 02:57:00",20.29,32.9,0,453.5,0.00484624668845129,0 +"7748","2015-02-10 02:57:59",20.23,32.8266666666667,0,455.666666666667,0.0048173198017732,0 +"7749","2015-02-10 02:58:59",20.29,32.9,0,454,0.00484624668845129,0 +"7750","2015-02-10 03:00:00",20.29,32.9,0,452,0.00484624668845129,0 +"7751","2015-02-10 03:01:00",20.2,32.79,0,454,0.00480290949816871,0 +"7752","2015-02-10 03:02:00",20.29,32.9,0,452,0.00484624668845129,0 +"7753","2015-02-10 03:03:00",20.29,32.9,0,460,0.00484624668845129,0 +"7754","2015-02-10 03:04:00",20.29,32.9,0,456.5,0.00484624668845129,0 +"7755","2015-02-10 03:04:59",20.29,32.9,0,451,0.00484624668845129,0 +"7756","2015-02-10 03:06:00",20.245,32.845,0,453,0.00482453822464545,0 +"7757","2015-02-10 03:07:00",20.29,32.9,0,456,0.00484624668845129,0 +"7758","2015-02-10 03:08:00",20.245,32.895,0,454.5,0.00483193968168258,0 +"7759","2015-02-10 03:08:59",20.29,32.9,0,455.5,0.00484624668845129,0 +"7760","2015-02-10 03:10:00",20.29,32.95,0,454,0.00485366927741052,0 +"7761","2015-02-10 03:10:59",20.23,32.8266666666667,0,455,0.0048173198017732,0 +"7762","2015-02-10 03:11:59",20.29,32.9,0,453,0.00484624668845129,0 +"7763","2015-02-10 03:13:00",20.29,32.9,0,452,0.00484624668845129,0 +"7764","2015-02-10 03:14:00",20.29,32.9,0,455,0.00484624668845129,0 +"7765","2015-02-10 03:15:00",20.29,32.95,0,450,0.00485366927741052,0 +"7766","2015-02-10 03:16:00",20.29,32.9,0,450.5,0.00484624668845129,0 +"7767","2015-02-10 03:16:59",20.29,32.9,0,452.5,0.00484624668845129,0 +"7768","2015-02-10 03:17:59",20.26,32.8633333333333,0,453.333333333333,0.00483176550721526,0 +"7769","2015-02-10 03:19:00",20.2,32.9,0,454.5,0.00481914656360182,0 +"7770","2015-02-10 03:20:00",20.2,32.9,0,453,0.00481914656360182,0 +"7771","2015-02-10 03:21:00",20.2,32.9,0,450.666666666667,0.00481914656360182,0 +"7772","2015-02-10 03:22:00",20.245,32.9,0,455,0.0048326798369998,0 +"7773","2015-02-10 03:23:00",20.2,32.9,0,457.5,0.00481914656360182,0 +"7774","2015-02-10 03:23:59",20.2,32.9,0,458,0.00481914656360182,0 +"7775","2015-02-10 03:24:59",20.2,32.79,0,452,0.00480290949816871,0 +"7776","2015-02-10 03:26:00",20.26,32.8633333333333,0,448.333333333333,0.00483176550721526,0 +"7777","2015-02-10 03:27:00",20.29,32.9,0,448,0.00484624668845129,0 +"7778","2015-02-10 03:28:00",20.29,32.9,0,453,0.00484624668845129,0 +"7779","2015-02-10 03:29:00",20.2,32.79,0,447,0.00480290949816871,0 +"7780","2015-02-10 03:29:59",20.2225,32.8725,0,449,0.00482184392225699,0 +"7781","2015-02-10 03:30:59",20.2,32.9,0,450.5,0.00481914656360182,0 +"7782","2015-02-10 03:32:00",20.2,32.9,0,448.333333333333,0.00481914656360182,0 +"7783","2015-02-10 03:33:00",20.2,32.9,0,452,0.00481914656360182,0 +"7784","2015-02-10 03:34:00",20.2,32.9,0,452.333333333333,0.00481914656360182,0 +"7785","2015-02-10 03:35:00",20.2,32.9,0,452,0.00481914656360182,0 +"7786","2015-02-10 03:36:00",20.29,32.9,0,452,0.00484624668845129,0 +"7787","2015-02-10 03:36:59",20.29,33,0,449,0.00486109204215602,0 +"7788","2015-02-10 03:38:00",20.2,32.9,0,448,0.00481914656360182,0 +"7789","2015-02-10 03:39:00",20.2,32.9,0,451.5,0.00481914656360182,0 +"7790","2015-02-10 03:40:00",20.2,32.9,0,451,0.00481914656360182,0 +"7791","2015-02-10 03:40:59",20.2,32.9,0,445,0.00481914656360182,0 +"7792","2015-02-10 03:42:00",20.29,33,0,448,0.00486109204215602,0 +"7793","2015-02-10 03:42:59",20.2,32.9,0,448,0.00481914656360182,0 +"7794","2015-02-10 03:43:59",20.2,32.9,0,447,0.00481914656360182,0 +"7795","2015-02-10 03:45:00",20.2,32.9,0,450.5,0.00481914656360182,0 +"7796","2015-02-10 03:46:00",20.2,32.9,0,446.333333333333,0.00481914656360182,0 +"7797","2015-02-10 03:47:00",20.2,32.9,0,447,0.00481914656360182,0 +"7798","2015-02-10 03:48:00",20.2,32.9,0,450.5,0.00481914656360182,0 +"7799","2015-02-10 03:49:00",20.2,32.9,0,450,0.00481914656360182,0 +"7800","2015-02-10 03:49:59",20.2,32.9,0,451,0.00481914656360182,0 +"7801","2015-02-10 03:51:00",20.2,32.9,0,450,0.00481914656360182,0 +"7802","2015-02-10 03:52:00",20.2,32.9,0,449,0.00481914656360182,0 +"7803","2015-02-10 03:53:00",20.2,32.9,0,447,0.00481914656360182,0 +"7804","2015-02-10 03:53:59",20.2,32.9,0,452.5,0.00481914656360182,0 +"7805","2015-02-10 03:55:00",20.2,32.9,0,452,0.00481914656360182,0 +"7806","2015-02-10 03:55:59",20.2,32.9,0,453,0.00481914656360182,0 +"7807","2015-02-10 03:56:59",20.2,32.9,0,453,0.00481914656360182,0 +"7808","2015-02-10 03:58:00",20.2,32.9,0,447.5,0.00481914656360182,0 +"7809","2015-02-10 03:59:00",20.2,32.9,0,445.5,0.00481914656360182,0 +"7810","2015-02-10 04:00:00",20.2,32.9,0,448.5,0.00481914656360182,0 +"7811","2015-02-10 04:01:00",20.2,32.9,0,444,0.00481914656360182,0 +"7812","2015-02-10 04:01:59",20.2,32.9,0,445,0.00481914656360182,0 +"7813","2015-02-10 04:02:59",20.2,32.9,0,448,0.00481914656360182,0 +"7814","2015-02-10 04:04:00",20.2,32.9,0,446,0.00481914656360182,0 +"7815","2015-02-10 04:05:00",20.2,32.9,0,449,0.00481914656360182,0 +"7816","2015-02-10 04:06:00",20.2,32.9,0,449.5,0.00481914656360182,0 +"7817","2015-02-10 04:07:00",20.2,32.9,0,451,0.00481914656360182,0 +"7818","2015-02-10 04:08:00",20.2,32.9,0,444,0.00481914656360182,0 +"7819","2015-02-10 04:08:59",20.2,32.9,0,449,0.00481914656360182,0 +"7820","2015-02-10 04:09:59",20.2,32.9,0,451,0.00481914656360182,0 +"7821","2015-02-10 04:11:00",20.2,32.9,0,450,0.00481914656360182,0 +"7822","2015-02-10 04:12:00",20.2,32.9,0,444,0.00481914656360182,0 +"7823","2015-02-10 04:13:00",20.2,32.9,0,447.333333333333,0.00481914656360182,0 +"7824","2015-02-10 04:14:00",20.2,32.9,0,453,0.00481914656360182,0 +"7825","2015-02-10 04:14:59",20.2,32.9,0,448,0.00481914656360182,0 +"7826","2015-02-10 04:15:59",20.2,32.9,0,443,0.00481914656360182,0 +"7827","2015-02-10 04:17:00",20.2,32.9,0,444,0.00481914656360182,0 +"7828","2015-02-10 04:18:00",20.2,32.9,0,445,0.00481914656360182,0 +"7829","2015-02-10 04:19:00",20.1333333333333,33,0,441.666666666667,0.00481385884010662,0 +"7830","2015-02-10 04:20:00",20.15,33,0,446.5,0.00481886429259954,0 +"7831","2015-02-10 04:21:00",20.1,33,0,449.5,0.00480386171918592,0 +"7832","2015-02-10 04:21:59",20.1,33,0,443.5,0.00480386171918592,0 +"7833","2015-02-10 04:23:00",20.1,33,0,447.25,0.00480386171918592,0 +"7834","2015-02-10 04:24:00",20.1,32.95,0,449.5,0.00479652701237058,0 +"7835","2015-02-10 04:25:00",20.2,33,0,449,0.0048339082621864,0 +"7836","2015-02-10 04:25:59",20.1,33,0,446,0.00480386171918592,0 +"7837","2015-02-10 04:27:00",20.1666666666667,33,0,448,0.00482387434466561,0 +"7838","2015-02-10 04:27:59",20.2,33,0,448,0.0048339082621864,0 +"7839","2015-02-10 04:28:59",20.15,33,0,447,0.00481886429259954,0 +"7840","2015-02-10 04:30:00",20.2,33,0,444,0.0048339082621864,0 +"7841","2015-02-10 04:31:00",20.2,33,0,445.5,0.0048339082621864,0 +"7842","2015-02-10 04:32:00",20.1,33,0,445,0.00480386171918592,0 +"7843","2015-02-10 04:33:00",20.15,33,0,447.5,0.00481886429259954,0 +"7844","2015-02-10 04:34:00",20.15,33,0,448,0.00481886429259954,0 +"7845","2015-02-10 04:34:59",20.2,33,0,450.5,0.0048339082621864,0 +"7846","2015-02-10 04:36:00",20.2,33,0,443,0.0048339082621864,0 +"7847","2015-02-10 04:37:00",20.1,33,0,444,0.00480386171918592,0 +"7848","2015-02-10 04:38:00",20.1,33,0,443.5,0.00480386171918592,0 +"7849","2015-02-10 04:38:59",20.2,32.9,0,445.5,0.00481914656360182,0 +"7850","2015-02-10 04:40:00",20.2,32.9,0,445,0.00481914656360182,0 +"7851","2015-02-10 04:40:59",20.1,32.95,0,444,0.00479652701237058,0 +"7852","2015-02-10 04:41:59",20.1,33,0,442.666666666667,0.00480386171918592,0 +"7853","2015-02-10 04:43:00",20.15,33,0,444.5,0.00481886429259954,0 +"7854","2015-02-10 04:44:00",20.1,33,0,448,0.00480386171918592,0 +"7855","2015-02-10 04:45:00",20.1,33,0,443.5,0.00480386171918592,0 +"7856","2015-02-10 04:46:00",20.1666666666667,33,0,446.666666666667,0.00482387434466561,0 +"7857","2015-02-10 04:46:59",20.2,33,0,444,0.0048339082621864,0 +"7858","2015-02-10 04:47:59",20.1666666666667,33,0,445.666666666667,0.00482387434466561,0 +"7859","2015-02-10 04:49:00",20.1333333333333,33,0,445,0.00481385884010662,0 +"7860","2015-02-10 04:50:00",20.1,33,0,444,0.00480386171918592,0 +"7861","2015-02-10 04:51:00",20.1333333333333,33,0,446.666666666667,0.00481385884010662,0 +"7862","2015-02-10 04:52:00",20.1,33,0,449.666666666667,0.00480386171918592,0 +"7863","2015-02-10 04:53:00",20.1,33,0,451,0.00480386171918592,0 +"7864","2015-02-10 04:53:59",20.15,33,0,448.5,0.00481886429259954,0 +"7865","2015-02-10 04:54:59",20.1,33,0,446,0.00480386171918592,0 +"7866","2015-02-10 04:56:00",20.2,33,0,446,0.0048339082621864,0 +"7867","2015-02-10 04:57:00",20.1,33,0,447.333333333333,0.00480386171918592,0 +"7868","2015-02-10 04:58:00",20.1,33,0,446,0.00480386171918592,0 +"7869","2015-02-10 04:59:00",20.1,33,0,447,0.00480386171918592,0 +"7870","2015-02-10 04:59:59",20.1333333333333,33,0,446.666666666667,0.00481385884010662,0 +"7871","2015-02-10 05:00:59",20.2,33,0,450,0.0048339082621864,0 +"7872","2015-02-10 05:02:00",20.15,33,0,446,0.00481886429259954,0 +"7873","2015-02-10 05:03:00",20.1,33,0,442,0.00480386171918592,0 +"7874","2015-02-10 05:04:00",20.175,33,0,449.333333333333,0.00482638109668428,0 +"7875","2015-02-10 05:05:00",20.1,33,0,446.333333333333,0.00480386171918592,0 +"7876","2015-02-10 05:06:00",20.1,33,0,444,0.00480386171918592,0 +"7877","2015-02-10 05:06:59",20.2,33,0,445,0.0048339082621864,0 +"7878","2015-02-10 05:08:00",20.15,33,0,444,0.00481886429259954,0 +"7879","2015-02-10 05:09:00",20.1333333333333,33,0,447.666666666667,0.00481385884010662,0 +"7880","2015-02-10 05:10:00",20.2,33,0,446,0.0048339082621864,0 +"7881","2015-02-10 05:10:59",20.15,33,0,446.5,0.00481886429259954,0 +"7882","2015-02-10 05:12:00",20.1,33,0,448,0.00480386171918592,0 +"7883","2015-02-10 05:12:59",20.1,33,0,449,0.00480386171918592,0 +"7884","2015-02-10 05:13:59",20.1,33,0,445,0.00480386171918592,0 +"7885","2015-02-10 05:15:00",20.2,33,0,447.5,0.0048339082621864,0 +"7886","2015-02-10 05:16:00",20.15,33,0,450,0.00481886429259954,0 +"7887","2015-02-10 05:17:00",20.15,33,0,449.5,0.00481886429259954,0 +"7888","2015-02-10 05:18:00",20.15,33,0,451.5,0.00481886429259954,0 +"7889","2015-02-10 05:19:00",20.15,33,0,445.5,0.00481886429259954,0 +"7890","2015-02-10 05:19:59",20.2,33,0,441,0.0048339082621864,0 +"7891","2015-02-10 05:21:00",20.2,33,0,446,0.0048339082621864,0 +"7892","2015-02-10 05:22:00",20.2,33,0,449,0.0048339082621864,0 +"7893","2015-02-10 05:23:00",20.1,33,0,453,0.00480386171918592,0 +"7894","2015-02-10 05:23:59",20.2,33,0,447,0.0048339082621864,0 +"7895","2015-02-10 05:25:00",20.15,33,0,443.5,0.00481886429259954,0 +"7896","2015-02-10 05:25:59",20.1,33,0,442,0.00480386171918592,0 +"7897","2015-02-10 05:26:59",20.2,33,0,449,0.0048339082621864,0 +"7898","2015-02-10 05:28:00",20.2,33,0,448,0.0048339082621864,0 +"7899","2015-02-10 05:29:00",20.1333333333333,33,0,448.333333333333,0.00481385884010662,0 +"7900","2015-02-10 05:30:00",20.1,33.03,0,451.333333333333,0.00480826262567247,0 +"7901","2015-02-10 05:31:00",20.1,33,0,452.5,0.00480386171918592,0 +"7902","2015-02-10 05:31:59",20.2,33,0,443,0.0048339082621864,0 +"7903","2015-02-10 05:32:59",20.2,33,0,444,0.0048339082621864,0 +"7904","2015-02-10 05:34:00",20.1,33.045,0,449,0.00481046310209051,0 +"7905","2015-02-10 05:35:00",20.15,33.045,0,449.5,0.00482548645049419,0 +"7906","2015-02-10 05:36:00",20.1,33,0,451.5,0.00480386171918592,0 +"7907","2015-02-10 05:37:00",20.1,33,0,455.5,0.00480386171918592,0 +"7908","2015-02-10 05:38:00",20.2,33.09,0,451,0.00484719438539044,0 +"7909","2015-02-10 05:38:59",20.15,33.09,0,446,0.00483210874831264,0 +"7910","2015-02-10 05:39:59",20.1,33.09,0,447.5,0.00481706462404567,0 +"7911","2015-02-10 05:41:00",20.1,33.09,0,449.5,0.00481706462404567,0 +"7912","2015-02-10 05:42:00",20.1333333333333,33.09,0,445.333333333333,0.00482708943258988,0 +"7913","2015-02-10 05:43:00",20.15,33.09,0,446,0.00483210874831264,0 +"7914","2015-02-10 05:44:00",20.125,33.09,0,444.75,0.00482458150327979,0 +"7915","2015-02-10 05:44:59",20.1,33.09,0,447,0.00481706462404567,0 +"7916","2015-02-10 05:45:59",20.2,33.09,0,448,0.00484719438539044,0 +"7917","2015-02-10 05:47:00",20.1,33,0,443.5,0.00480386171918592,0 +"7918","2015-02-10 05:48:00",20.1,33,0,444,0.00480386171918592,0 +"7919","2015-02-10 05:49:00",20.15,33.045,0,444.5,0.00482548645049419,0 +"7920","2015-02-10 05:50:00",20.1333333333333,33.06,0,443.5,0.00482267917303651,0 +"7921","2015-02-10 05:51:00",20.1,33.09,0,441,0.00481706462404567,0 +"7922","2015-02-10 05:51:59",20.1,33.09,0,446,0.00481706462404567,0 +"7923","2015-02-10 05:53:00",20.2,33.09,0,450,0.00484719438539044,0 +"7924","2015-02-10 05:54:00",20.15,33.09,0,451.5,0.00483210874831264,0 +"7925","2015-02-10 05:55:00",20.1,33.09,0,448,0.00481706462404567,0 +"7926","2015-02-10 05:55:59",20.1,33.09,0,447,0.00481706462404567,0 +"7927","2015-02-10 05:57:00",20.1,33.09,0,449,0.00481706462404567,0 +"7928","2015-02-10 05:57:59",20.1,33.09,0,447.5,0.00481706462404567,0 +"7929","2015-02-10 05:58:59",20.1333333333333,33.09,0,448,0.00482708943258988,0 +"7930","2015-02-10 06:00:00",20.2,33.09,0,446,0.00484719438539044,0 +"7931","2015-02-10 06:01:00",20.1,33.09,0,445,0.00481706462404567,0 +"7932","2015-02-10 06:02:00",20.1,33.09,0,445,0.00481706462404567,0 +"7933","2015-02-10 06:03:00",20.15,33.09,0,446.5,0.00483210874831264,0 +"7934","2015-02-10 06:04:00",20.1,33.09,0,447.5,0.00481706462404567,0 +"7935","2015-02-10 06:04:59",20.1,33.09,0,445.5,0.00481706462404567,0 +"7936","2015-02-10 06:06:00",20.1,33.09,0,449,0.00481706462404567,0 +"7937","2015-02-10 06:07:00",20.1,33.09,0,449,0.00481706462404567,0 +"7938","2015-02-10 06:08:00",20.1,33.09,0,449.5,0.00481706462404567,0 +"7939","2015-02-10 06:08:59",20.1,33.09,0,448,0.00481706462404567,0 +"7940","2015-02-10 06:10:00",20.1,33.09,0,447.333333333333,0.00481706462404567,0 +"7941","2015-02-10 06:10:59",20.1,33.09,0,442.5,0.00481706462404567,0 +"7942","2015-02-10 06:11:59",20.1,33.145,0,451,0.00482513333972025,0 +"7943","2015-02-10 06:13:00",20.1,33.09,0,451,0.00481706462404567,0 +"7944","2015-02-10 06:14:00",20.1,33.09,0,447,0.00481706462404567,0 +"7945","2015-02-10 06:15:00",20.1,33.09,0,443.5,0.00481706462404567,0 +"7946","2015-02-10 06:16:00",20.1,33.09,0,444,0.00481706462404567,0 +"7947","2015-02-10 06:16:59",20.1,33.09,0,444,0.00481706462404567,0 +"7948","2015-02-10 06:17:59",20.1,33.09,0,447.5,0.00481706462404567,0 +"7949","2015-02-10 06:19:00",20.1,33.145,0,449,0.00482513333972025,0 +"7950","2015-02-10 06:20:00",20.1,33.09,0,451,0.00481706462404567,0 +"7951","2015-02-10 06:21:00",20.1,33.1633333333333,0,448.333333333333,0.00482782295777407,0 +"7952","2015-02-10 06:22:00",20.1,33.2,0,441,0.00483320226312693,0 +"7953","2015-02-10 06:23:00",20.1,33.09,0,445,0.00481706462404567,0 +"7954","2015-02-10 06:23:59",20.1,33.09,0,444,0.00481706462404567,0 +"7955","2015-02-10 06:24:59",20.1,33.09,0,450,0.00481706462404567,0 +"7956","2015-02-10 06:26:00",20.1,33.09,0,454,0.00481706462404567,0 +"7957","2015-02-10 06:27:00",20.2,33.09,0,456,0.00484719438539044,0 +"7958","2015-02-10 06:28:00",20.1,33.09,0,448,0.00481706462404567,0 +"7959","2015-02-10 06:29:00",20.1,33.1266666666667,0,448.333333333333,0.00482244374474778,0 +"7960","2015-02-10 06:29:59",20.1,33.09,0,449,0.00481706462404567,0 +"7961","2015-02-10 06:30:59",20.2,33.09,0,455,0.00484719438539044,0 +"7962","2015-02-10 06:32:00",20.2,33.09,0,451.666666666667,0.00484719438539044,0 +"7963","2015-02-10 06:33:00",20.15,33.145,0,454.666666666667,0.00484020285789497,0 +"7964","2015-02-10 06:34:00",20.1,33.09,0,454,0.00481706462404567,0 +"7965","2015-02-10 06:35:00",20.2,33.09,0,454,0.00484719438539044,0 +"7966","2015-02-10 06:36:00",20.15,33.09,0,446,0.00483210874831264,0 +"7967","2015-02-10 06:36:59",20.15,33.2,0,449,0.00484829717651399,0 +"7968","2015-02-10 06:38:00",20.1333333333333,33.09,0,451,0.00482708943258988,0 +"7969","2015-02-10 06:39:00",20.15,33.09,0,451,0.00483210874831264,0 +"7970","2015-02-10 06:40:00",20.1,33.09,0,447.666666666667,0.00481706462404567,0 +"7971","2015-02-10 06:40:59",20.1,33.09,0,451,0.00481706462404567,0 +"7972","2015-02-10 06:42:00",20.1,33.09,0,452,0.00481706462404567,0 +"7973","2015-02-10 06:42:59",20.2,33.09,0,452.5,0.00484719438539044,0 +"7974","2015-02-10 06:43:59",20.1,33.09,0,454,0.00481706462404567,0 +"7975","2015-02-10 06:45:00",20.2,33.09,0,453.5,0.00484719438539044,0 +"7976","2015-02-10 06:46:00",20.2,33.045,0,451,0.00484055125338731,0 +"7977","2015-02-10 06:47:00",20.2,33.09,0,454,0.00484719438539044,0 +"7978","2015-02-10 06:48:00",20.2,33.09,0,453.5,0.00484719438539044,0 +"7979","2015-02-10 06:49:00",20.245,33.09,0,453,0.00486080703432993,0 +"7980","2015-02-10 06:49:59",20.2,33.09,0,449,0.00484719438539044,0 +"7981","2015-02-10 06:51:00",20.29,33.09,0,445,0.00487445346169922,0 +"7982","2015-02-10 06:52:00",20.2,33.06,0,447.333333333333,0.00484276561507678,0 +"7983","2015-02-10 06:53:00",20.2,33.06,0,443.333333333333,0.00484276561507678,0 +"7984","2015-02-10 06:53:59",20.23,33.03,0,450.666666666667,0.00484739155242702,0 +"7985","2015-02-10 06:55:00",20.29,33.09,0,450,0.00487445346169922,0 +"7986","2015-02-10 06:55:59",20.2675,33.0675,0,451,0.0048642903279587,0 +"7987","2015-02-10 06:56:59",20.29,33.09,0,450.333333333333,0.00487445346169922,0 +"7988","2015-02-10 06:58:00",20.29,33.09,0,447,0.00487445346169922,0 +"7989","2015-02-10 06:59:00",20.29,33.09,0,449,0.00487445346169922,0 +"7990","2015-02-10 07:00:00",20.29,33.09,0,452.5,0.00487445346169922,0 +"7991","2015-02-10 07:01:00",20.26,33.06,0,452.333333333333,0.0048609065974677,0 +"7992","2015-02-10 07:01:59",20.29,33.09,0,446,0.00487445346169922,0 +"7993","2015-02-10 07:02:59",20.29,33.09,0,442,0.00487445346169922,0 +"7994","2015-02-10 07:04:00",20.29,33.09,0,450,0.00487445346169922,0 +"7995","2015-02-10 07:05:00",20.29,33.09,0,456.666666666667,0.00487445346169922,0 +"7996","2015-02-10 07:06:00",20.29,33.045,0,453,0.00486777268072938,0 +"7997","2015-02-10 07:07:00",20.29,33.09,0,451,0.00487445346169922,0 +"7998","2015-02-10 07:08:00",20.29,33.09,0,449,0.00487445346169922,0 +"7999","2015-02-10 07:08:59",20.245,33.045,0,446,0.00485414510157563,0 +"8000","2015-02-10 07:09:59",20.29,33.09,0,447.666666666667,0.00487445346169922,0 +"8001","2015-02-10 07:11:00",20.29,33.09,0,445.666666666667,0.00487445346169922,0 +"8002","2015-02-10 07:12:00",20.29,33.09,0,452,0.00487445346169922,0 +"8003","2015-02-10 07:13:00",20.29,33.045,0,447.5,0.00486777268072938,0 +"8004","2015-02-10 07:14:00",20.245,33,0,448,0.00484748331041856,0 +"8005","2015-02-10 07:14:59",20.29,33.09,0,447.666666666667,0.00487445346169922,0 +"8006","2015-02-10 07:15:59",20.29,33.03,0,448.666666666667,0.00486554578538332,0 +"8007","2015-02-10 07:17:00",20.29,33,0,446,0.00486109204215602,0 +"8008","2015-02-10 07:18:00",20.29,33,0,450,0.00486109204215602,0 +"8009","2015-02-10 07:19:00",20.29,33,0,456.5,0.00486109204215602,0 +"8010","2015-02-10 07:20:00",20.29,33,0,452,0.00486109204215602,0 +"8011","2015-02-10 07:21:00",20.29,33.045,0,450.5,0.00486777268072938,0 +"8012","2015-02-10 07:21:59",20.29,33.03,0,453.333333333333,0.00486554578538332,0 +"8013","2015-02-10 07:23:00",20.29,33,0,457,0.00486109204215602,0 +"8014","2015-02-10 07:24:00",20.29,33,0,452.5,0.00486109204215602,0 +"8015","2015-02-10 07:25:00",20.29,33,0,447.5,0.00486109204215602,0 +"8016","2015-02-10 07:25:59",20.29,33,0,450,0.00486109204215602,0 +"8017","2015-02-10 07:27:00",20.29,33,0,452.5,0.00486109204215602,0 +"8018","2015-02-10 07:27:59",20.29,33,0,452,0.00486109204215602,0 +"8019","2015-02-10 07:28:59",20.29,33,0,452.5,0.00486109204215602,0 +"8020","2015-02-10 07:30:00",20.315,33.0225,0,455.5,0.00487201257705543,0 +"8021","2015-02-10 07:31:00",20.29,33,0,455,0.00486109204215602,0 +"8022","2015-02-10 07:32:00",20.29,33,0,452.5,0.00486109204215602,0 +"8023","2015-02-10 07:33:00",20.29,33,0,453.5,0.00486109204215602,0 +"8024","2015-02-10 07:34:00",20.29,33,0,454.666666666667,0.00486109204215602,0 +"8025","2015-02-10 07:34:59",20.29,33,0,452.5,0.00486109204215602,0 +"8026","2015-02-10 07:36:00",20.34,33,0,450.5,0.00487625244872327,0 +"8027","2015-02-10 07:37:00",20.29,33,0,444,0.00486109204215602,0 +"8028","2015-02-10 07:38:00",20.29,33.045,0,447.5,0.00486777268072938,0 +"8029","2015-02-10 07:38:59",20.29,33,0,449,0.00486109204215602,0 +"8030","2015-02-10 07:40:00",20.3233333333333,33,0,451,0.0048711943432678,0 +"8031","2015-02-10 07:40:59",20.29,33,0,448.666666666667,0.00486109204215602,0 +"8032","2015-02-10 07:41:59",20.29,33,0,445,0.00486109204215602,0 +"8033","2015-02-10 07:43:00",20.29,33,0,448,0.00486109204215602,0 +"8034","2015-02-10 07:44:00",20.29,33,0,451,0.00486109204215602,0 +"8035","2015-02-10 07:45:00",20.34,33,0,452,0.00487625244872327,0 +"8036","2015-02-10 07:46:00",20.39,33,0,454,0.00489145462900984,0 +"8037","2015-02-10 07:46:59",20.34,33,0,453,0.00487625244872327,0 +"8038","2015-02-10 07:47:59",20.29,33,0,453,0.00486109204215602,0 +"8039","2015-02-10 07:49:00",20.29,33.09,0,453,0.00487445346169922,0 +"8040","2015-02-10 07:50:00",20.39,33.045,0,453,0.00489817732118619,0 +"8041","2015-02-10 07:51:00",20.29,33.045,0,449,0.00486777268072938,0 +"8042","2015-02-10 07:52:00",20.29,33.045,0,449.5,0.00486777268072938,0 +"8043","2015-02-10 07:53:00",20.29,33.09,0,451,0.00487445346169922,0 +"8044","2015-02-10 07:53:59",20.29,33.09,0,454.333333333333,0.00487445346169922,0 +"8045","2015-02-10 07:54:59",20.29,33.045,0,454,0.00486777268072938,0 +"8046","2015-02-10 07:56:00",20.29,33,0,458,0.00486109204215602,0 +"8047","2015-02-10 07:57:00",20.29,33.09,0,454,0.00487445346169922,0 +"8048","2015-02-10 07:58:00",20.29,33.09,0,458.5,0.00487445346169922,0 +"8049","2015-02-10 07:59:00",20.29,33.09,0,457.333333333333,0.00487445346169922,0 +"8050","2015-02-10 07:59:59",20.29,33.09,0,455.5,0.00487445346169922,0 +"8051","2015-02-10 08:00:59",20.29,33.09,0,451.5,0.00487445346169922,0 +"8052","2015-02-10 08:02:00",20.29,33.09,0,453,0.00487445346169922,0 +"8053","2015-02-10 08:03:00",20.29,33.09,0,453,0.00487445346169922,0 +"8054","2015-02-10 08:04:00",20.29,33.09,0,452.666666666667,0.00487445346169922,0 +"8055","2015-02-10 08:05:00",20.29,33.09,0,456,0.00487445346169922,0 +"8056","2015-02-10 08:06:00",20.29,33.09,0,455.666666666667,0.00487445346169922,0 +"8057","2015-02-10 08:06:59",20.34,33.09,0,453,0.00488965586389202,0 +"8058","2015-02-10 08:08:00",20.29,33.09,0,453,0.00487445346169922,0 +"8059","2015-02-10 08:09:00",20.29,33.09,0,452.5,0.00487445346169922,0 +"8060","2015-02-10 08:10:00",20.29,33.09,0,449.5,0.00487445346169922,0 +"8061","2015-02-10 08:10:59",20.29,33.09,0,453,0.00487445346169922,0 +"8062","2015-02-10 08:12:00",20.29,33.09,0,456,0.00487445346169922,0 +"8063","2015-02-10 08:12:59",20.29,33.09,0,452.333333333333,0.00487445346169922,0 +"8064","2015-02-10 08:13:59",20.29,33.09,0,455.5,0.00487445346169922,0 +"8065","2015-02-10 08:15:00",20.29,33.09,0,456.333333333333,0.00487445346169922,0 +"8066","2015-02-10 08:16:00",20.39,33.09,0,448,0.00490490015755043,0 +"8067","2015-02-10 08:17:00",20.29,33.09,0,450,0.00487445346169922,0 +"8068","2015-02-10 08:18:00",20.29,33.09,0,449,0.00487445346169922,0 +"8069","2015-02-10 08:19:00",20.29,33.09,0,449.5,0.00487445346169922,0 +"8070","2015-02-10 08:19:59",20.29,33.2,0,454,0.00489078485912552,0 +"8071","2015-02-10 08:21:00",20.29,33.1266666666667,0,450,0.00487989716629469,0 +"8072","2015-02-10 08:22:00",20.29,33.2,0,449.666666666667,0.00489078485912552,0 +"8073","2015-02-10 08:23:00",20.29,33.145,0,451.5,0.00488261905404695,0 +"8074","2015-02-10 08:23:59",20.29,33.2,0,460,0.00489078485912552,0 +"8075","2015-02-10 08:25:00",20.29,33.2,0,456.5,0.00489078485912552,0 +"8076","2015-02-10 08:25:59",20.29,33.2,0,455.5,0.00489078485912552,0 +"8077","2015-02-10 08:26:59",20.29,33.2,0,450,0.00489078485912552,0 +"8078","2015-02-10 08:28:00",20.29,33.2,0,448,0.00489078485912552,0 +"8079","2015-02-10 08:29:00",20.29,33.2,0,451.5,0.00489078485912552,0 +"8080","2015-02-10 08:30:00",20.29,33.2,0,451.5,0.00489078485912552,0 +"8081","2015-02-10 08:31:00",20.29,33.2,0,454.5,0.00489078485912552,0 +"8082","2015-02-10 08:31:59",20.29,33.2,0,454.666666666667,0.00489078485912552,0 +"8083","2015-02-10 08:32:59",20.29,33.2,0,451,0.00489078485912552,0 +"8084","2015-02-10 08:34:00",20.29,33.2,0,451,0.00489078485912552,0 +"8085","2015-02-10 08:35:00",20.29,33.2,0,455,0.00489078485912552,0 +"8086","2015-02-10 08:36:00",20.29,33.2,0,458,0.00489078485912552,0 +"8087","2015-02-10 08:37:00",20.315,33.2,232,460,0.0048984064784882,0 +"8088","2015-02-10 08:38:00",20.3233333333333,33.23,419,456.666666666667,0.00490541284483592,1 +"8089","2015-02-10 08:38:59",20.3233333333333,33.26,433,463,0.00490987640306294,1 +"8090","2015-02-10 08:39:59",20.315,33.345,426,474.25,0.00491996934321247,0 +"8091","2015-02-10 08:41:00",20.3566666666667,33.4,419,482.333333333333,0.0049409526584124,0 +"8092","2015-02-10 08:42:00",20.365,33.4975,419,482.5,0.0049580629225364,1 +"8093","2015-02-10 08:43:00",20.39,33.5,419,484.5,0.0049661593089812,1 +"8094","2015-02-10 08:44:00",20.39,33.5,419,490.333333333333,0.0049661593089812,1 +"8095","2015-02-10 08:44:59",20.39,33.5,409.666666666667,489.666666666667,0.0049661593089812,1 +"8096","2015-02-10 08:45:59",20.4175,33.5225,405,487.25,0.00497803526961612,1 +"8097","2015-02-10 08:47:00",20.4266666666667,33.56,405,494.333333333333,0.00498649261142709,1 +"8098","2015-02-10 08:48:00",20.4175,33.5675,408,499,0.00498477124810134,1 +"8099","2015-02-10 08:49:00",20.4633333333333,33.6633333333333,413,499,0.00501339593919012,1 +"8100","2015-02-10 08:50:00",20.5,33.6725,404.5,494.5,0.00502622448496155,1 +"8101","2015-02-10 08:51:00",20.5,33.7225,407.5,495.5,0.00503374828172461,1 +"8102","2015-02-10 08:51:59",20.5,33.79,405,495.5,0.00504390569377061,1 +"8103","2015-02-10 08:53:00",20.5,33.79,408,502.5,0.00504390569377061,1 +"8104","2015-02-10 08:54:00",20.5,33.79,405,506.666666666667,0.00504390569377061,1 +"8105","2015-02-10 08:55:00",20.55,33.79,405,508,0.00505961533348046,1 +"8106","2015-02-10 08:55:59",20.6,33.8633333333333,405,509.5,0.00508647319424473,1 +"8107","2015-02-10 08:57:00",20.575,33.925,405,516,0.00508789792183084,1 +"8108","2015-02-10 08:57:59",20.6,33.8725,412,521.25,0.00508786134458237,1 +"8109","2015-02-10 08:58:59",20.6,33.895,419,525.75,0.00509126864873998,1 +"8110","2015-02-10 09:00:00",20.65,33.975,419,524.5,0.00511926793567655,1 +"8111","2015-02-10 09:01:00",20.675,33.975,419,527.75,0.0051272263778175,1 +"8112","2015-02-10 09:02:00",20.65,33.975,419,534.5,0.00511926793567655,1 +"8113","2015-02-10 09:03:00",20.65,34.145,419,532,0.00514509499509892,1 +"8114","2015-02-10 09:04:00",20.7,34.4175,419,568.75,0.00520263742441767,1 +"8115","2015-02-10 09:04:59",20.7,34.09,419,556.666666666667,0.00515272157447504,1 +"8116","2015-02-10 09:06:00",20.7,34.2966666666667,419,548,0.0051842197100333,1 +"8117","2015-02-10 09:07:00",20.73,34.4666666666667,419,563.333333333333,0.00521985047405851,1 +"8118","2015-02-10 09:08:00",20.745,34.5675,426,593.75,0.005240129644354,1 +"8119","2015-02-10 09:08:59",20.7675,34.7175,422.5,600.75,0.00527042030609893,1 +"8120","2015-02-10 09:10:00",20.79,35.09,426,623,0.00533490249866746,1 +"8121","2015-02-10 09:10:59",20.79,34.9725,433,631,0.00531688570196619,1 +"8122","2015-02-10 09:11:59",20.79,34.8266666666667,433,636,0.00529452586868443,1 +"8123","2015-02-10 09:13:00",20.84,35.195,433,636.75,0.00536764050115774,1 +"8124","2015-02-10 09:14:00",20.89,35.3,433,663,0.00540052618827497,1 +"8125","2015-02-10 09:15:00",20.8566666666667,35.0966666666667,433,665.333333333333,0.00535805452550947,1 +"8126","2015-02-10 09:16:00",20.89,35.32,433,669.5,0.00540361255833249,1 +"8127","2015-02-10 09:16:59",20.9175,35.475,433,679.25,0.00543680242759036,1 +"8128","2015-02-10 09:17:59",20.89,35.4,433,684.666666666667,0.00541595834222399,1 +"8129","2015-02-10 09:19:00",20.9175,35.7175,433,706.25,0.005474294413411,1 +"8130","2015-02-10 09:20:00",20.95875,35.68375,433,712.625,0.00548309006716284,1 +"8131","2015-02-10 09:21:00",21,35.65,433,719,0.0054918905554738,1 +"8132","2015-02-10 09:22:00",21,35.7,433,730.25,0.00549966117159867,1 +"8133","2015-02-10 09:23:00",21,35.76,433,739,0.00550898616499498,1 +"8134","2015-02-10 09:23:59",21,35.85,433,756.25,0.0055229741747557,1 +"8135","2015-02-10 09:24:59",21,35.7,433,761,0.00549966117159867,1 +"8136","2015-02-10 09:26:00",21.025,35.95,433,763,0.00554710988950315,1 +"8137","2015-02-10 09:27:00",21,35.86,433,771.333333333333,0.00552452843655777,1 +"8138","2015-02-10 09:28:00",21.05,36.05,433,780.25,0.00557130685771428,1 +"8139","2015-02-10 09:29:00",21.05,36.0975,433,787.25,0.00557871353188273,1 +"8140","2015-02-10 09:29:59",21.05,35.995,433,789.5,0.0055627309270867,1 +"8141","2015-02-10 09:30:59",21.1,36.095,433,798.5,0.00559563901834568,1 +"8142","2015-02-10 09:32:00",21.1,36.26,433,820.333333333333,0.00562144937350851,1 +"8143","2015-02-10 09:33:00",21.1,36.2,447,821,0.00561206354418701,1 diff --git a/Demos/occupancy_demo.py b/Demos/occupancy_demo.py new file mode 100644 index 0000000..7c58aa8 --- /dev/null +++ b/Demos/occupancy_demo.py @@ -0,0 +1,66 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" +import pandas as pd +import numpy as np + +import sys + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools + + +def load_occupancy(path='./Demos/occupancy_data/'): + train_data = pd.read_csv(path + 'datatraining.txt', index_col=0) + X_train = train_data[['Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_train = np.squeeze(train_data[['Occupancy']].values) + + test_data = pd.read_csv(path + 'datatest2.txt', index_col=0) + X_test = test_data[['Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_test = np.squeeze(test_data[['Occupancy']].values) + + return X_train, y_train, X_test, y_test + +X_train, y_train, X_test, y_test = load_occupancy() + +try: + n_gen = int(sys.argv[1]) + pop_size = int(sys.argv[2]) + nRules = int(sys.argv[2]) + nAnts = int(sys.argv[3]) +except: + n_gen = 50 + pop_size = 30 + nRules = 10 + nAnts = 3 + +fz_type_studied = fs.FUZZY_SETS.t1 +X = pd.concat([X_train, X_test]) +precomputed_partitions = utils.construct_partitions(pd.concat([X_train, X_test]), fz_type_studied) +min_bounds = np.min(X, axis=0).values +max_bounds = np.max(X, axis=0).values +domain = [min_bounds, max_bounds] + +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, + linguistic_variables=precomputed_partitions, n_linguist_variables=3, + fuzzy_type=fz_type_studied, verbose=True, tolerance=0.01, domain=domain) + +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size) + +eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +print('Done') \ No newline at end of file diff --git a/Demos/occupancy_demo_temporal.py b/Demos/occupancy_demo_temporal.py new file mode 100644 index 0000000..11995dc --- /dev/null +++ b/Demos/occupancy_demo_temporal.py @@ -0,0 +1,104 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +TODO: finish the example. + +""" +import sys +sys.path.append('./ex_fuzzy/ex_fuzzy/') + +import numpy as np + +import utils +import fuzzy_sets as t2 +import evolutionary_fit as GA +import pandas as pd +import eval_tools +import temporal +from sklearn.metrics import matthews_corrcoef +from sklearn.model_selection import train_test_split + + +def load_occupancy(path='./Demos/occupancy_data/', random_mixing=True): + train_data = pd.read_csv(path + 'datatraining.txt', index_col=0) + X_train = train_data[['date', 'Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_train = np.squeeze(train_data[['Occupancy']].values) + + test_data = pd.read_csv(path + 'datatest.txt', index_col=0) + X_test = test_data[['date', 'Temperature', 'Humidity', 'Light', 'CO2', 'HumidityRatio']] + y_test = np.squeeze(test_data[['Occupancy']].values) + + if random_mixing: + + X_total = pd.concat([X_train, X_test]) + y_total = np.concatenate([y_train, y_test]) + + X_train, X_test, y_train, y_test = train_test_split(X_total, y_total, test_size=0.33, random_state=0) + + return X_train, y_train, X_test, y_test, X_total, y_total + + +_, _, _, _, X_total, y_total = load_occupancy() +X_total_array = np.array(X_total.drop(columns=['date'])) + + +try: + n_gen = int(sys.argv[1]) + pop_size = int(sys.argv[2]) + nRules = int(sys.argv[2]) + nAnts = int(sys.argv[3]) +except: + n_gen = 50 + pop_size = 30 + nRules = 10 + nAnts = 3 + +fz_type_studied = t2.FUZZY_SETS.temporal +fz_type_inside = t2.FUZZY_SETS.t1 +precomputed_partitions = utils.construct_partitions(X_total.drop(columns=['date']), fz_type_inside) + +cut_point_morning0 = '00:00:00' +cut_point_morning1 = '10:00:00' +cut_points_morning = [cut_point_morning0, cut_point_morning1] +cut_point_daytime0 = '11:00:00' +cut_point_daytime1 = '19:00:00' +cut_points_daytime = [cut_point_daytime0, cut_point_daytime1] +cut_point_evening0 = '20:00:00' +cut_point_evening1 = '23:00:00' +cutpoints_evening = [cut_point_evening0, cut_point_evening1] + + +temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour') +time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])]) +partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers) +X_train, X_test, y_train, y_test = partitions +train_markers, test_markers = partition_markers + +train_time_moments = np.array([utils.assign_time(a, train_markers) for a in range(X_train.shape[0])]) +test_time_moments = np.array([utils.assign_time(a, test_markers) for a in range(X_test.shape[0])]) + +temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions) + +X_train = X_train.drop(columns=['date']) +X_test = X_test.drop(columns=['date']) +fl_classifier = temporal.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, + linguistic_variables=temp_partitions, n_linguist_variables=3, + fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_class=2) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments, checkpoints=0) + +temporal.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + time_moments=train_time_moments, test_time_moments=test_time_moments, + plot_rules=False, print_rules=True, plot_partitions=False) + + +print('Done') \ No newline at end of file diff --git a/Demos/precandidate_rules_demo.py b/Demos/precandidate_rules_demo.py new file mode 100644 index 0000000..1dfa08f --- /dev/null +++ b/Demos/precandidate_rules_demo.py @@ -0,0 +1,78 @@ +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of T1-FS are used to compute +a t1 reasoning approach. + +We also show the GA to optimize the rules obtained in classification. + +""" + + +import pandas as pd + +from sklearn import datasets +from sklearn.model_selection import train_test_split + +import sys + +# In case yo urun this without installing the package, you need to add the path to the package +sys.path.append('./ex_fuzzy/') +sys.path.append('./ex_fuzzy/ex_fuzzy/') +sys.path.append('../ex_fuzzy/') + +import ex_fuzzy.fuzzy_sets as fs +import ex_fuzzy.evolutionary_fit as GA +import ex_fuzzy.utils as utils +import ex_fuzzy.eval_tools as eval_tools +import ex_fuzzy.persistence as persistence +import ex_fuzzy.vis_rules as vis_rules + + +runner = 1 # 1: single thread, 2+: corresponding multi-thread + +n_gen = 50 +n_pop = 30 + +nRules = 15 +nAnts = 4 +vl = 3 +tolerance = 0.01 +fz_type_studied = fs.FUZZY_SETS.t1 + +# Import some data to play with +iris = datasets.load_iris() +X = pd.DataFrame(iris.data, columns=iris.feature_names) +y = iris.target + +# Compute the fuzzy partitions using 3 quartiles +precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +# Split the data into a training set and a test set +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +# We create a FRBC with the precomputed partitions and the specified fuzzy set type, +fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied, verbose=True, tolerance=tolerance, runner=runner) +fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1) + +# Evaluate the performance of the rule base +eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False) + +# Use the rule base as a candidate to further optimize the rules +frbc = fl_classifier.rule_base + +refined_classifier = GA.BaseFuzzyRulesClassifier(verbose=True, tolerance=tolerance, runner=runner, linguistic_variables=None) +refined_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=0, initial_rules=frbc) + +# Evaluate the performance of the rule base +eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=False, print_rules=True, plot_partitions=False) + +print('Done') \ No newline at end of file diff --git a/Demos/regression_demo.py b/Demos/regression_demo.py new file mode 100644 index 0000000..81bf359 --- /dev/null +++ b/Demos/regression_demo.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jan 7 09:35:55 2021 +All rights reserved + +@author: Javier Fumanal Idocin - University of Essex +@author: Javier Andreu-Perez - University of Essex + + +This is a the source file that contains a demo for a tip computation example, where a diferent set of IVFS are used to compute +a t2 reasoning approach. + +""" +import numpy as np + +import ex_fuzzy.fuzzy_sets as t2 +import ex_fuzzy.rules as rules + +# Define the fuzzy sets +food_rancid_lower = [0, 0, 0.5, 4.5] +food_rancid_upper = [0, 0, 1, 5] +food_delicious_lower = [4.5, 8.5, 9, 9] +food_delicious_upper = [4, 8, 9, 9] + +food_rancid = t2.IVFS('Rancid', food_rancid_lower, food_rancid_upper, [0,9]) +food_delicious = t2.IVFS('Delicious', food_delicious_lower, food_delicious_upper, [0,9]) + +#Use the fuzzy sets to define a fuzzy variable with its linguistic partitions. +food = t2.fuzzyVariable('Food', [food_rancid, food_delicious]) + +service_poor_lower = [0, 0, 0.5, 2.5] +service_poor_upper = [0, 0, 1, 3] +service_good_lower = [1.5, 3.5, 4.5, 6.5] +service_good_upper = [1, 3, 5, 7] +service_excellent_lower = [5.5, 7.5, 9, 9] +service_excellent_upper = [5, 7, 9, 9] + +service_poor = t2.IVFS('Poor', service_poor_lower, service_poor_upper, [0,9]) +service_good = t2.IVFS('Good', service_good_lower, service_good_upper, [0,9]) +service_excellent = t2.IVFS('Excellent', service_excellent_lower, service_excellent_upper, [0,9]) + +service = t2.fuzzyVariable('Service', [service_poor, service_good, service_excellent]) + +tip_cheap_lower = [2, 6, 6, 10] +tip_cheap_upper = [0, 6, 6, 12] +tip_average_lower = [12, 15, 15, 18] +tip_average_upper = [10, 15, 15, 20] +tip_genereous_lower = [20, 24, 24, 28] +tip_generous_upper = [18, 24, 24, 30] + +tip_cheap = t2.IVFS('Cheap', tip_cheap_lower, tip_cheap_upper, [0,30]) +tip_average = t2.IVFS('Average', tip_average_lower, tip_average_upper, [0,30]) +tip_genereous = t2.IVFS('Generous', tip_genereous_lower, tip_generous_upper, [0,30]) + +tip = t2.fuzzyVariable('Tip', [tip_cheap, tip_average, tip_genereous]) + +rule_list =[ + rules.RuleSimple([0, 0], 0), + rules.RuleSimple([0, 1], 0), + rules.RuleSimple([0, 2], 1), + rules.RuleSimple([1, 0], 1), + rules.RuleSimple([1, 1], 1), + rules.RuleSimple([1, 2], 2) +] + +inference_module = rules.RuleBaseT2([food, service], rule_list, tip) +input = np.array([4,8.5]).reshape((1,2)) +print(inference_module.inference(input)) \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..5e3244c --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# Ex-Fuzzy +ex-Fuzzy is a fuzzy toolbox library for Python with special focus in its accesibility to use and visualization of results. In this way, we focus on the ex(-Fuzzy)plainable capacities of approximate reasoning. + +Some of the tools available in this library include: + +- Support for approximate reasoning using fuzzy association rules, for both classification and regression problems. This includes rule base optimization using genetic algorithms and rule visualization. +- Precomputed and optimized fuzzy variables and their correspondent linguistic variables (i.e low, medium, high). +- Support for various kinds of fuzzy sets, including classic fuzzy sets, IV-fuzzy sets and General Type 2 fuzzy sets. + +## Main Characteristics + +### Easy to use + +ex-Fuzzy is designed to be easy to use. Linguistic variables can be precomputed and optimized without any understading of its implementation. Choosing one kind of fuzzy set only requires to set one flag. + +### Reusable code + +Code is designed so that some parts can be easily extendable, so that some use cases, like research, can be also supported. The rule base optimization is done using a Genetic Algorithm, but almost any other pymoo search algorithm will do. Fuzzy sets can be extended with ease, just as the kind of partitions, membership functions, etc. + +### Sci-py like interface + +ex-Fuzzy is built taking into account the actual machine-learing frameworks used in Python. Training amd sing a rule base classifier works exactly as sci-kit learn classifier. Parameters such as the number of rules or antecedents are also built + +### Visualization + +Use plots to visualize any kind of fuzzy sets, and use graphs to visualize rules or print them on screen. + + +

+ + + + + +

+ +## Dependencies + +- Numpy +- Pandas +- Matplotlib +- Networkx +- Pymoo + +## Installation + +You can install ex-Fuzzy using pip, from the PyPi repository, with the following command: + +`pip install ex-fuzzy` + + +## Contributors +Javier Fumanal Idocin, Javier Andreu-Perez + +All rights reserved, 2021-2024 + + diff --git a/dist/ex_fuzzy-1.0.0.tar.gz b/dist/ex_fuzzy-1.0.0.tar.gz new file mode 100644 index 0000000..1bed0fa Binary files /dev/null and b/dist/ex_fuzzy-1.0.0.tar.gz differ diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/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 = build + +# 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/build/.buildinfo b/docs/build/.buildinfo new file mode 100644 index 0000000..f32269a --- /dev/null +++ b/docs/build/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 7cc6f7cade9883ab9fe45ed6939a69af +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/.doctrees/api.doctree b/docs/build/.doctrees/api.doctree new file mode 100644 index 0000000..97aa16e Binary files /dev/null and b/docs/build/.doctrees/api.doctree differ diff --git a/docs/build/.doctrees/environment.pickle b/docs/build/.doctrees/environment.pickle new file mode 100644 index 0000000..b12c903 Binary files /dev/null and b/docs/build/.doctrees/environment.pickle differ diff --git a/docs/build/.doctrees/extending.doctree b/docs/build/.doctrees/extending.doctree new file mode 100644 index 0000000..851f051 Binary files /dev/null and b/docs/build/.doctrees/extending.doctree differ diff --git a/docs/build/.doctrees/function_resume/centroid.doctree b/docs/build/.doctrees/function_resume/centroid.doctree new file mode 100644 index 0000000..810c671 Binary files /dev/null and b/docs/build/.doctrees/function_resume/centroid.doctree differ diff --git a/docs/build/.doctrees/function_resume/eval_rules.doctree b/docs/build/.doctrees/function_resume/eval_rules.doctree new file mode 100644 index 0000000..cb8ae72 Binary files /dev/null and b/docs/build/.doctrees/function_resume/eval_rules.doctree differ diff --git a/docs/build/.doctrees/function_resume/eval_tools.doctree b/docs/build/.doctrees/function_resume/eval_tools.doctree new file mode 100644 index 0000000..48a223d Binary files /dev/null and b/docs/build/.doctrees/function_resume/eval_tools.doctree differ diff --git a/docs/build/.doctrees/function_resume/evolutionary_fit.doctree b/docs/build/.doctrees/function_resume/evolutionary_fit.doctree new file mode 100644 index 0000000..c25b1aa Binary files /dev/null and b/docs/build/.doctrees/function_resume/evolutionary_fit.doctree differ diff --git a/docs/build/.doctrees/function_resume/fuzzy_sets.doctree b/docs/build/.doctrees/function_resume/fuzzy_sets.doctree new file mode 100644 index 0000000..4ec8ce8 Binary files /dev/null and b/docs/build/.doctrees/function_resume/fuzzy_sets.doctree differ diff --git a/docs/build/.doctrees/function_resume/persistence.doctree b/docs/build/.doctrees/function_resume/persistence.doctree new file mode 100644 index 0000000..86fb97b Binary files /dev/null and b/docs/build/.doctrees/function_resume/persistence.doctree differ diff --git a/docs/build/.doctrees/function_resume/rules.doctree b/docs/build/.doctrees/function_resume/rules.doctree new file mode 100644 index 0000000..043d06c Binary files /dev/null and b/docs/build/.doctrees/function_resume/rules.doctree differ diff --git a/docs/build/.doctrees/function_resume/utils.doctree b/docs/build/.doctrees/function_resume/utils.doctree new file mode 100644 index 0000000..698e895 Binary files /dev/null and b/docs/build/.doctrees/function_resume/utils.doctree differ diff --git a/docs/build/.doctrees/gt2.doctree b/docs/build/.doctrees/gt2.doctree new file mode 100644 index 0000000..19797c2 Binary files /dev/null and b/docs/build/.doctrees/gt2.doctree differ diff --git a/docs/build/.doctrees/index.doctree b/docs/build/.doctrees/index.doctree new file mode 100644 index 0000000..8da6d46 Binary files /dev/null and b/docs/build/.doctrees/index.doctree differ diff --git a/docs/build/.doctrees/optimize.doctree b/docs/build/.doctrees/optimize.doctree new file mode 100644 index 0000000..fa61296 Binary files /dev/null and b/docs/build/.doctrees/optimize.doctree differ diff --git a/docs/build/.doctrees/persistence.doctree b/docs/build/.doctrees/persistence.doctree new file mode 100644 index 0000000..87d56a2 Binary files /dev/null and b/docs/build/.doctrees/persistence.doctree differ diff --git a/docs/build/.doctrees/precom.doctree b/docs/build/.doctrees/precom.doctree new file mode 100644 index 0000000..bdd966b Binary files /dev/null and b/docs/build/.doctrees/precom.doctree differ diff --git a/docs/build/.doctrees/step1.doctree b/docs/build/.doctrees/step1.doctree new file mode 100644 index 0000000..4e963cb Binary files /dev/null and b/docs/build/.doctrees/step1.doctree differ diff --git a/docs/build/.doctrees/step2.doctree b/docs/build/.doctrees/step2.doctree new file mode 100644 index 0000000..4c9f177 Binary files /dev/null and b/docs/build/.doctrees/step2.doctree differ diff --git a/docs/build/.doctrees/step3.doctree b/docs/build/.doctrees/step3.doctree new file mode 100644 index 0000000..f9f61c0 Binary files /dev/null and b/docs/build/.doctrees/step3.doctree differ diff --git a/docs/build/.doctrees/step4.doctree b/docs/build/.doctrees/step4.doctree new file mode 100644 index 0000000..066327f Binary files /dev/null and b/docs/build/.doctrees/step4.doctree differ diff --git a/docs/build/.doctrees/tmpfs.doctree b/docs/build/.doctrees/tmpfs.doctree new file mode 100644 index 0000000..fe8876d Binary files /dev/null and b/docs/build/.doctrees/tmpfs.doctree differ diff --git a/docs/build/.doctrees/usage.doctree b/docs/build/.doctrees/usage.doctree new file mode 100644 index 0000000..1e5f607 Binary files /dev/null and b/docs/build/.doctrees/usage.doctree differ diff --git a/docs/build/_images/ejemplo_t1.png b/docs/build/_images/ejemplo_t1.png new file mode 100644 index 0000000..50e1962 Binary files /dev/null and b/docs/build/_images/ejemplo_t1.png differ diff --git a/docs/build/_images/ejemplo_t2.png b/docs/build/_images/ejemplo_t2.png new file mode 100644 index 0000000..e2b2f98 Binary files /dev/null and b/docs/build/_images/ejemplo_t2.png differ diff --git a/docs/build/_images/example_gt2.png b/docs/build/_images/example_gt2.png new file mode 100644 index 0000000..3ac968d Binary files /dev/null and b/docs/build/_images/example_gt2.png differ diff --git a/docs/build/_images/red_fuzzy.png b/docs/build/_images/red_fuzzy.png new file mode 100644 index 0000000..f69b9e2 Binary files /dev/null and b/docs/build/_images/red_fuzzy.png differ diff --git a/docs/build/_modules/ex_fuzzy/centroid.html b/docs/build/_modules/ex_fuzzy/centroid.html new file mode 100644 index 0000000..86777ef --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/centroid.html @@ -0,0 +1,297 @@ + + + + + + ex_fuzzy.centroid — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.centroid

+# -*- coding: utf-8 -*-
+"""
+This is the source file that contains functions to compute centroids for the case of IV fuzzy sets,
+which are commonly used when using the IV-T2 fuzzy sets.
+"""
+import numpy as np
+
+
+
[docs]def y_compute(z: np.array, w: np.array) -> np.array: + ''' + Computes the ponderated centroid with normalized weighting. + + :param z: Vector of the referencial values. + :param w: Vector of the fuzzy memberships. + :return: The ponderated sum. + ''' + return z @ w / np.sum(w)
+ + +
[docs]def compute_centroid_t2_l(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = y_compute(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + # k_vector = np.argwhere((z - yhat) > 0) + # k = k_vector[0][0] + 1 + w[0:k] = memberships[:, 1][:k] + w[k:] = memberships[:, 0][k:] + + yhat_2 = yhat + yhat = y_compute(z, w) + + return yhat
+ + +
[docs]def compute_centroid_t2_r(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The lowest membership of the centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = y_compute(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + w[0:k+1] = memberships[:, 0][:k+1] + w[k+1:] = memberships[:, 1][k+1:] + + yhat_2 = yhat + yhat = y_compute(z, w) + + return yhat
+ + +
[docs]def consequent_centroid_r(antecedent_memberships: np.array, centroids_r: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + yhat = y_compute(centroids_r, initial_f) + yhat2 = None + + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_r) >= 0)[-1][0] + r_R = min(len(centroids_r)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_left[0:r_R+1] + new_memberships[r_R+1:] = memberships_right[r_R+1:] + + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = y_compute(centroids_r, new_memberships) + + return yhat2
+ + +
[docs]def consequent_centroid_l(antecedent_memberships, centroids_l): + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + # (memberships_right * centroids_r) / np.sum(memberships_right) + yhat = y_compute(centroids_l, initial_f) + yhat2 = -100 + + #R = np.where(yhat - centroids_r)[0] + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_l) >= 0)[-1][0] + r_R = min(len(centroids_l)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_right[0:r_R+1] + new_memberships[r_R+1:] = memberships_left[r_R+1:] + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = y_compute(centroids_l, new_memberships) + + return yhat2
+ + +
[docs]def compute_centroid_iv(z: np.array, memberships: np.array) -> np.array: + ''' + Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set. + ''' + res = np.zeros((2,)) + res[0] = compute_centroid_t2_l(z, memberships) + res[1] = compute_centroid_t2_r(z, memberships) + return res
+ + +
[docs]def consequent_centroid(antecedent_memberships, centroids): + ''' + Computes Karnik and Mendel algorithm? to find the centroid of a consequent iv fuzzy set given the centroids of the antecedents. + ''' + centroids_l = centroids[:, 0] + centroids_r = centroids[:, 1] + res = np.zeros((2,)) + + res[0] = consequent_centroid_l(antecedent_memberships, centroids_l) + res[1] = consequent_centroid_r(antecedent_memberships, centroids_r) + + return res
+ + +
[docs]def center_of_masses(z: np.array, memberships: np.array) -> np.array: + ''' + Computes the center of masses of a t1 membership function. + ''' + return z @ memberships / np.sum(memberships)
+ + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/eval_rules.html b/docs/build/_modules/ex_fuzzy/eval_rules.html new file mode 100644 index 0000000..2637fbf --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/eval_rules.html @@ -0,0 +1,356 @@ + + + + + + ex_fuzzy.eval_rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.eval_rules

+# -*- coding: utf-8 -*-
+"""
+This file contains the classes to perform rule classification evaluation.
+
+"""
+import numpy as np
+from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix
+
+try:
+    from . import rules
+    from . import fuzzy_sets as fs
+except ImportError:
+    import rules
+    import fuzzy_sets as fs
+
+
[docs]class evalRuleBase(): + ''' + Class to evaluate a set of rules given a evaluation dataset. + ''' + + def __init__(self, mrule_base: rules.MasterRuleBase, X: np.array, y: np.array, time_moments: np.array=None) -> None: + ''' + Creates the object with the rulebase to evaluate and the data to use in the evaluation. + + :param mrule_base: The rule base to evaluate. + :param X: array shape samples x features. The data to evaluate the rule base. + :param y: array shape samples x 1. The labels of the data. + :param time_moments: array shape samples x 1. The time moments of the samples. (Only for temporal rule bases) + :return: None + ''' + self.mrule_base = mrule_base + self.X = X + self.y = y + self.time_moments = time_moments + + self.consequents = mrule_base.get_consequents() + + +
[docs] def compute_pattern_support(self) -> np.array: + ''' + Computes the pattern support for each of the rules for the given X. + Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, + dvided by their number. + + :return: array of shape rules x 2 + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + + # / pattern_firing_strength.shape[0] + res[ix] = np.mean(pattern_firing_strength[consequent_match]) + + return res
+ + + def _get_all_rules(self) -> list[rules.RuleSimple]: + ''' + Returns a list of all the rules in the master rule base. + + :return: list of rules. + ''' + res = [] + for jx in self.mrule_base.get_rules(): + res.append(jx) + + return res + + +
[docs] def compute_pattern_confidence(self) -> np.array: + ''' + Computes the pattern confidence for each of the rules for the given X. + Each pattern confidence is the normalized firing strength. + + :returns: array of shape 1 x rules + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + antecedent_consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + dem = np.sum(pattern_firing_strength) + if dem == 0: + res[ix] = 0 + else: + res[ix] = np.sum( + pattern_firing_strength[antecedent_consequent_match]) / dem + + return res
+ + +
[docs] def dominance_scores(self) -> np.array: + ''' + Returns the dominance score of each pattern for each rule. + + :return: array of shape rules x 2 + ''' + return self.compute_pattern_confidence() * self.compute_pattern_support()
+ + +
[docs] def association_degree(self) -> np.array: + ''' + Returns the association degree of each rule for each sample. + + :return: vector of shape rules + ''' + firing_strengths = self.mrule_base.compute_firing_strenghts(self.X) + res = self.dominance_scores() * firing_strengths + + if (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + res = np.mean(res, axis=2) + + return res
+ + +
[docs] def add_rule_weights(self) -> None: + ''' + Add dominance score field to each of the rules present in the master Rule Base. + ''' + supports = self.compute_pattern_support() + confidences = self.compute_pattern_confidence() + scores = self.dominance_scores() + + aux_counter = 0 + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + rules[jx].score = scores[aux_counter] + rules[jx].support = supports[aux_counter] + rules[jx].confidence = confidences[aux_counter] + + aux_counter += 1
+ + +
[docs] def add_classification_metrics(self, X: np.array=None, y: np.array=None) -> None: + ''' + Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores. + If X and y are None uses the train set. + + :param X: array of shape samples x features + :param y: array of shape samples + + ''' + if X is not None: + actual_X = X + actual_y = y + else: + actual_X = self.X + actual_y = self.y + + self.add_rule_weights() + winning_rules = self.mrule_base._winning_rules(actual_X) + preds = self.mrule_base.winning_rule_predict(actual_X) + + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + relevant_samples = winning_rules == jx + if np.sum(relevant_samples) > 0: + relevant_labels = actual_y[relevant_samples] + relevant_preds = preds[relevant_samples] + + rules[jx].accuracy = accuracy_score(relevant_labels, relevant_preds) + else: + rules[jx].accuracy = 0.0
+ + +
[docs] def classification_eval(self) -> float: + ''' + Returns the matthews correlation coefficient for a classification task using + the rules evaluated. + + :return: mattews correlation coefficient. (float in [-1, 1]) + ''' + from sklearn.metrics import matthews_corrcoef + self.add_rule_weights() + preds = self.mrule_base.winning_rule_predict(self.X) + + return matthews_corrcoef(self.y, preds)
+ + +
[docs] def size_eval(self, tolerance=0.1) -> float: + ''' + Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents. + + 0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. + The more rules and antecedent per rules the lower this score is. + + :param tolerance: float in [0, 1]. The tolerance for the dominance score. Default 0.1 + :return: float in [0, 1] with the score. + ''' + self.add_rule_weights() + + possible_rule_size = 0 + effective_rule_size = 0 + + for rule_base in self.mrule_base.get_rulebases(): + if len(rule_base) > 0: + for rule in rule_base: + rscore = np.mean(rule.score) + if rscore > tolerance: + possible_rule_size += len(rule.antecedents) + # No antecedents for this rule + if sum(np.array(rule.antecedents) != -1) == 0: + effective_rule_size += len(rule.antecedents) + else: + effective_rule_size += sum( + np.array(rule.antecedents) != -1) + + else: + return 0.0 # If one consequent does not have rules, then we return 0.0 + + try: + rule_density = 1 - effective_rule_size / possible_rule_size # Antecedents used + except ZeroDivisionError: + rule_density = 0.0 + + return rule_density
+
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/eval_tools.html b/docs/build/_modules/ex_fuzzy/eval_tools.html new file mode 100644 index 0000000..1b61276 --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/eval_tools.html @@ -0,0 +1,244 @@ + + + + + + ex_fuzzy.eval_tools — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.eval_tools

+# -*- coding: utf-8 -*-
+"""
+Functions that contain some general functions to eval already fitted fuzzy rule based models.
+It can also be used to visualize rules and fuzzy partitions.
+"""
+import numpy as np
+import pandas as pd
+from sklearn.metrics import matthews_corrcoef
+
+try:
+      from . import evolutionary_fit as evf
+      from . import vis_rules
+except ImportError:
+      import evolutionary_fit as evf
+      import vis_rules
+
+
+
[docs]def eval_temporal_fuzzy_model(fl_classifier: evf.FuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, time_moments: list[int] = None, test_time_moments: list[int] = None, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + + if print_accuracy: + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.forward(X_train, time_moments))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.forward(X_test, test_time_moments))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.forward(X_train, time_moments)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.forward(X_test, test_time_moments)))) + print('------------') + + for ix in np.unique(time_moments): + try: + X_aux = X_train[time_moments == ix, :] + X_aux_test = X_test[time_moments == ix, :] + except pd.core.indexing.InvalidIndexError: + X_aux = X_train.iloc[time_moments == ix, :] + X_aux_test = X_test.iloc[test_time_moments == ix, :] + + y_aux = y_train[time_moments == ix] + y_aux_test = y_test[test_time_moments == ix] + + if print_matthew: + print('MOMENT ' + str(ix)) + print('------------') + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_aux, fl_classifier.forward(X_aux, np.array([ix] * X_aux.shape[0]))))) + print('Test performance: ' + + str(matthews_corrcoef(y_aux_test, fl_classifier.forward(X_aux_test, np.array([ix] * X_aux_test.shape[0]))))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier) + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res + else: + print(res)
+ + +
[docs]def eval_fuzzy_model(fl_classifier: evf.FuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + # Get the unique classes from the classifier + unique_classes = fl_classifier.classes_ + # Convert the names from the labels to the corresponding class + y_train = np.array([list(unique_classes).index(str(y)) for y in y_train]) + y_test = np.array([list(unique_classes).index(str(y)) for y in y_test]) + + if print_accuracy: + print('------------') + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.forward(X_train))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.forward(X_test))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.forward(X_train)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.forward(X_test)))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier, export_path='Demos') + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + + if print_rules: + print(res) + + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/evolutionary_fit.html b/docs/build/_modules/ex_fuzzy/evolutionary_fit.html new file mode 100644 index 0000000..ec1ba7b --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/evolutionary_fit.html @@ -0,0 +1,942 @@ + + + + + + ex_fuzzy.evolutionary_fit — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.evolutionary_fit

+# -*- coding: utf-8 -*-
+"""
+
+This is a the source file that contains the class to train/fit the rulebase using a genetic algorithm.
+
+"""
+import numpy as np
+import pandas as pd
+
+from sklearn.model_selection import StratifiedKFold
+from sklearn.metrics import matthews_corrcoef
+
+from pymoo.algorithms.soo.nonconvex.ga import GA
+from pymoo.core.problem import Problem
+from pymoo.optimize import minimize
+from pymoo.operators.sampling.rnd import IntegerRandomSampling
+from pymoo.operators.crossover.sbx import SBX
+from pymoo.operators.mutation.pm import PolynomialMutation
+from pymoo.core.variable import Integer
+from multiprocessing.pool import ThreadPool
+from pymoo.core.problem import StarmapParallelization
+
+try:
+    from . import fuzzy_sets as fs
+    from . import rules
+    from . import eval_rules as evr
+    from . import vis_rules
+except ImportError:
+    import fuzzy_sets as fs
+    import rules
+    import eval_rules as evr
+    import vis_rules
+
+
+
[docs]class FuzzyRulesClassifier(): + ''' + Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_class: int=None, precomputed_rules: rules.MasterRuleBase =None, runner: int=1) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param precomputed_rules: MasterRuleBase object. If not None, the classifier will use the rules in the object and ignore the conflicting parameters. + :param runner: number of threads to use. If None (default) the classifier will use 1 thread. + ''' + if precomputed_rules is not None: + self.nRules = len(precomputed_rules.get_rules()) + self.nAnts = len(precomputed_rules.get_rules()[0].antecedents) + self.n_class = len(precomputed_rules) + self.classes_ = precomputed_rules.consequent_names + self.rule_base = precomputed_rules + else: + self.nRules = nRules + self.nAnts = nAnts + + + self.custom_loss = None + self.verbose = verbose + self.tolerance = tolerance + + if runner > 1: + pool = ThreadPool(runner) + self.thread_runner = StarmapParallelization(pool.starmap) + else: + self.thread_runner = None + + if linguistic_variables is not None: + # If the linguistic variables are precomputed then we act accordingly + self.lvs = linguistic_variables + self.n_linguist_variables = len( + self.lvs[0].linguistic_variable_names()) + self.domain = None + self.fuzzy_type = self.lvs[0].fuzzy_type() + else: + # If not, then we need the parameters sumistered by the user. + self.lvs = None + self.fuzzy_type = fuzzy_type + self.n_linguist_variables = n_linguist_variables + self.domain = domain + + +
[docs] def customized_loss(self, loss_function): + ''' + Function to customize the loss function used for the optimization. + + :param loss_function: function that takes as input the true labels and the predicted labels and returns a float. + :return: None + ''' + self.custom_loss = loss_function
+ + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=70, pop_size:int=30, checkpoints:int=10): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :param checkpoints: integer. Number of checkpoints to save the best rulebase found so far. + :return: None. The classifier is fitted to the data. + ''' + if isinstance(y, pd.Series): + self.classes_ = [str(aux) for aux in y.unique()] + # Convert the names in the label vector to integer classes + y = np.array(y.replace(self.classes_, np.arange(len(self.classes_)))) + else: + self.classes_ = [str(aux) for aux in np.unique(y)] + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, n_classes=len(np.unique(y)), + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, thread_runner=self.thread_runner) + else: + # If Fuzzy variables are already precomputed. + + + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, n_classes=len(np.unique(y)), + linguist_variables=self.lvs, domain=self.domain, tolerance=self.tolerance, thread_runner=self.thread_runner) + + if self.custom_loss is not None: + problem.fitness_func = self.custom_loss + + + + algorithm = GA( + pop_size=pop_size, + sampling=IntegerRandomSampling(), + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + eliminate_duplicates=True) + + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, res.pop.get('F').mean(), res.pop.get('F').min())) + if k % checkpoints == 0: + with open("checkpoint_" + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_rule_weights() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + rule_base.rename_cons(self.classes_) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + + + self.performance = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + self.rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + self.rule_base.rename_cons(self.classes_) + + self.eval_performance = evr.evalRuleBase( + self.rule_base, np.array(X), y) + + self.eval_performance.add_rule_weights() + self.rename_fuzzy_variables() + self.rule_base.purge_rules(self.tolerance) + self.eval_performance.add_classification_metrics()
+ + +
[docs] def load_master_rule_base(self, rule_base: rules.MasterRuleBase) -> None: + ''' + Loads a master rule base to be used in the prediction process. + + :param rule_base: ruleBase object. + :return: None + ''' + self.rule_base = rule_base + self.nRules = len(rule_base.get_rules()) + self.nAnts = len(rule_base.get_rules()[0].antecedents) + self.n_class = len(rule_base)
+ + +
[docs] def forward(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a pandas dataframe + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X)
+ + +
[docs] def predict(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + return self.forward(X)
+ + +
[docs] def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules contained in the fitted rulebase. + ''' + return self.rule_base.print_rules(return_rules)
+ + +
[docs] def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv)
+ + +
[docs] def rename_fuzzy_variables(self) -> None: + ''' + Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process. + + :return: None. Names are sorted accorded to the central point of the fuzzy memberships. + ''' + + for ix in range(len(self.rule_base)): + fuzzy_variables = self.rule_base.rule_bases[ix].antecedents + + for jx, fv in enumerate(fuzzy_variables): + # I feel so extraordinary, lifes got a hold on me... + new_order_values = [] + possible_names = FitRuleBase.vl_names[self.n_linguist_variables] + + for zx, fuzzy_set in enumerate(fv.linguistic_variables): + if fuzzy_set.type() == fs.FUZZY_SETS.temporal: + studied_fz = fuzzy_set.inside_type() + else: + studied_fz = fuzzy_set.type() + + if studied_fz == fs.FUZZY_SETS.t1: + f1 = np.mean( + fuzzy_set.membership_parameters[0] + fuzzy_set.membership_parameters[1]) + elif (studied_fz == fs.FUZZY_SETS.t2): + f1 = np.mean( + fuzzy_set.secondMF_upper[0] + fuzzy_set.secondMF_upper[1]) + elif studied_fz == fs.FUZZY_SETS.gt2: + sec_memberships = fuzzy_set.secondary_memberships.values() + f1 = float(list(fuzzy_set.secondary_memberships.keys())[np.argmax( + [fzm.membership_parameters[2] for ix, fzm in enumerate(sec_memberships)])]) + + new_order_values.append(f1) + + new_order = np.argsort(np.array(new_order_values)) + fuzzy_sets_vl = fv.linguistic_variables + + for jx, x in enumerate(new_order): + fuzzy_sets_vl[x].name = possible_names[jx]
+ + +
[docs] def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix()
+ + +
[docs]class TemporalFuzzyRulesClassifier(FuzzyRulesClassifier): + ''' + Class that is used as a classifier for a fuzzy rule based system with time dependencies. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int, nAnts: int, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_classes: int = None, **kwargs) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + + kwargs: + - n_classes: number of classes to predict. Default deduces from data. + ''' + super().__init__(nRules, nAnts, fuzzy_type, tolerance, n_linguist_variables, verbose, linguistic_variables, domain, n_classes) + + + def _contruct_tempRuleBase(self, problems, best_individuals): + ruleBase_temp = [] + + for problem, subject in zip(problems, best_individuals): + ruleBase_time_moment = problem._construct_ruleBase(subject, + self.fuzzy_type) + ruleBase_temp.append(ruleBase_time_moment) + + return ruleBase_temp + + + def _fix_time(self, lvs: list[fs.temporalFuzzyVariable], time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variables. + + :param lvs: list of temporal fuzzy variables. + :param time: integer. Time moment to fix. + :return: None. The time is fixed. + ''' + for lv in lvs: + lv.fix_time(time) + + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=50, pop_size:int=10, time_moments: np.array=None, checkpoints:int=10): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: None. The classifier is fitted to the data. + ''' + problems = [] + for ix in range(len(np.unique(time_moments))): + X_problem = X[time_moments == ix] + y_problem = y[time_moments == ix] + time_moments_problem = time_moments[time_moments == ix] + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, time_moments=time_moments_problem, + n_classes=self.n_class, thread_runner=self.thread_runner) + else: + import copy + time_lvs = [copy.deepcopy(aux) for aux in self.lvs] + self._fix_time(time_lvs, ix) + # If Fuzzy variables are already precomputed. + problem = FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, + linguist_variables=time_lvs, domain=self.domain, tolerance=self.tolerance, time_moments=time_moments_problem, + n_classes=self.n_class, thread_runner=self.thread_runner) + + problems.append(problem) + + + + best_individuals = [] + for time, problem in enumerate(problems): + algorithm = GA( + pop_size=pop_size, + sampling=IntegerRandomSampling(), + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + eliminate_duplicates=True) + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, res.pop.get('F').mean(), res.pop.get('F').min())) + if k % checkpoints == 0: + with open("checkpoint_" + time + '_' + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_rule_weights() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + best_individuals.append(best_individual) + + if self.verbose: + print('Rule based fit for time ' + str(time) + ' completed.') + + + self.performance = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + + ruleBase_temp = self._contruct_tempRuleBase(problems, best_individuals) + + self.rule_base = rules.temporalMasterRuleBase(ruleBase_temp) + + self.eval_performance = evr.evalRuleBase(self.rule_base, np.array(X), y, time_moments) + + self.eval_performance.add_rule_weights() + self.rename_fuzzy_variables() + self.rule_base.purge_rules(self.tolerance) + self.eval_performance.add_classification_metrics()
+ + +
[docs] def forward(self, X: np.array, time_moments: list[int] = None) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :param time_moments: list of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a numpy array + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X, time_moments)
+ + + +
[docs] def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv)
+ + +
[docs] def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix()
+ + +
[docs]class FitRuleBase(Problem): + ''' + Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies. + Supports type 1 and iv fs (iv-type 2) + ''' + + def _init_optimize_vl(self, fuzzy_type: fs.FUZZY_SETS, n_linguist_variables: int, domain: list[(float, float)] = None): + ''' + Inits the corresponding fields if no linguistic partitions were given. + + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + ''' + self.lvs = None + try: + self.vl_names = FitRuleBase.vl_names[n_linguist_variables] + except IndexError: + self.vl_names = [str(ix) for ix in range(n_linguist_variables)] + + self.fuzzy_type = fuzzy_type + self.n_lv_possible = n_linguist_variables + self.domain = domain + + + def _init_precomputed_vl(self, linguist_variables: list[fs.fuzzyVariable]): + ''' + Inits the corresponding fields if linguistic partitions for each variable are given. + + :param linguistic_variables: list of fuzzyVariables type. + ''' + self.lvs = linguist_variables + self.vl_names = self.lvs[0].linguistic_variable_names() + self.n_lv_possible = len(self.vl_names) + self.fuzzy_type = self.lvs[0].fs_type + self.domain = None + + vl_names = [ # Linguistic variable names preestated for some specific cases. + [], + [], + ['Low', 'High'], + ['Low', 'Medium', 'High'], + ['Low', 'Medium', 'High', 'Very High'], + ['Very Low', 'Low', 'Medium', 'High', 'Very High'] + ] + + def __init__(self, X: np.array, y: np.array, nRules: int, nAnts: int, n_classes: int, thread_runner: StarmapParallelization=None, **kwargs) -> None: + ''' + Cosntructor method. Initializes the classifier with the number of antecedents, linguist variables and the kind of fuzzy set desired. + + :param X: np array or pandas dataframe samples x features. + :param y: np vector containing the target classes. vector sample + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param n_class: number of classes in the problem. If None (as default) it will be computed from the data. + + kwargs: + :param linguistic_variables: list of linguistic variables precomputed. If given, the rest of kwargs is ignored. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param fuzzy_type: Define the fuzzy set or fuzzy set extension used as linguistic variable. + :param domain: list with the upper and lower domains of each input variable. If None (as default) it will stablish the empirical min/max as the limits. + ''' + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + try: + self.tolerance = kwargs['tolerance'] + except KeyError: + self.tolerance = 0.001 + + self.y = y + self.nRules = nRules + self.nAnts = nAnts + self.nCons = 1 # This is fixed to MISO rules. + + if n_classes is not None: + self.n_classes = n_classes + else: + self.n_classes = len(np.unique(y)) + + if 'linguist_variables' in kwargs.keys(): + self._init_precomputed_vl(kwargs['linguist_variables']) + else: + self._init_optimize_vl( + kwargs['fuzzy_type'], kwargs['n_linguist_variables']) + + if self.domain is None: + self.min_bounds = np.min(self.X, axis=0) + self.max_bounds = np.max(self.X, axis=0) + else: + self.min_bounds, self.max_bounds = self.domain + + self.antecedents_referencial = [np.linspace( + self.min_bounds[ix], self.max_bounds[ix], 100) for ix in range(self.X.shape[1])] + + possible_antecedent_bounds = np.array( + [[0, self.X.shape[1] - 1]] * self.nAnts * self.nRules) # -1 means not caring + vl_antecedent_bounds = np.array( + [[-1, self.n_lv_possible - 1]] * self.nAnts * self.nRules) + antecedent_bounds = np.concatenate( + (possible_antecedent_bounds, vl_antecedent_bounds)) + vars_antecedent = {ix: Integer( + bounds=antecedent_bounds[ix]) for ix in range(len(antecedent_bounds))} + aux_counter = len(vars_antecedent) + + if self.lvs is None: + self.feature_domain_bounds = np.array( + [[0, 99] for ix in range(self.X.shape[1])]) + size_multiplier = 4 if self.fuzzy_type == fs.FUZZY_SETS.t1 else 8 + membership_bounds = np.concatenate( + [self.feature_domain_bounds] * self.n_lv_possible * size_multiplier) + vars_memeberships = { + aux_counter + ix: Integer(bounds=membership_bounds[ix]) for ix in range(len(membership_bounds))} + aux_counter += len(vars_memeberships) + + final_consequent_bounds = np.array( + [[0, self.n_classes - 1]] * self.nRules) + vars_consequent = {aux_counter + ix: Integer( + bounds=final_consequent_bounds[ix]) for ix in range(len(final_consequent_bounds))} + + if self.lvs is None: + vars = {key: val for d in [ + vars_antecedent, vars_memeberships, vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, membership_bounds, final_consequent_bounds), axis=0) + else: + vars = {key: val for d in [vars_antecedent, + vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, final_consequent_bounds), axis=0) + + nVar = len(varbound) + self.single_gen_size = nVar + + if thread_runner is not None: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1], + elementwise_runner=thread_runner) + else: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1]) + + + def _construct_ruleBase(self, x: np.array, fz_type: fs.FUZZY_SETS, **kwargs) -> rules.MasterRuleBase: + ''' + Given a subject, it creates a rulebase according to its specification. + + :param x: gen of a rulebase. type: dict. + :param fz_type: a enum type. Check fuzzy_sets for complete specification (two fields, t1 and t2, to mark which fs you want to use) + :return: a rulebase object. + + kwargs: + - time_moment: if temporal fuzzy sets are used with different partitions for each time interval, + then this parameter is used to specify which time moment is being used. + ''' + + rule_list = [[] for _ in range(self.n_classes)] + + mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8 + ''' + GEN STRUCTURE + + First: antecedents chosen by each rule. Size: nAnts * nRules + Second: Variable linguistics used. Size: nAnts * nRules + Third: Parameters for the fuzzy partitions of the chosen variables. Size: X.shape[1] * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) + Four: Consequent classes. Size: nRules * self.n_linguistic_variables (fixed to 4 right now) + ''' + if self.lvs is None: + # If memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + \ + self.X.shape[1] * self.n_lv_possible * mf_size + else: + # If no memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + + aux_pointer = 0 + min_domain = np.min(self.X, axis=0) + max_domain = np.max(self.X, axis=0) + + # Integer sampling doesnt work fine in pymoo, so we do this (which is btw what pymoo is really doing if you just set integer optimization) + try: + # subject might come as a dict. + x = np.array(list(x.values())).astype(int) + except AttributeError: + x = x.astype(int) + + for i0 in range(self.nRules): # Reconstruct the rules + first_pointer = i0 * self.nAnts + chosen_ants = x[first_pointer:first_pointer + self.nAnts] + + second_pointer = (i0 * self.nAnts) + (self.nAnts * self.nRules) + # Shape: self.nAnts + self.n_lv_possible + 1 + antecedent_parameters = x[second_pointer:second_pointer+self.nAnts] + + init_rule_antecedents = np.zeros( + (self.X.shape[1],)) - 1 # -1 is dont care + for jx, ant in enumerate(chosen_ants): + init_rule_antecedents[ant] = antecedent_parameters[jx] + + consequent_idx = x[fourth_pointer + aux_pointer] + assert consequent_idx < self.n_classes, "Consequent class is not valid. Something in the gene is wrong." + aux_pointer += 1 + + # TODO: check that the casting is correct + rule_list[consequent_idx].append( + rules.RuleSimple(init_rule_antecedents, 0)) + + # If we optimize the membership functions + if self.lvs is None: + third_pointer = 2 * self.nAnts * self.nRules + aux_pointer = 0 + antecedents = [] + for fuzzy_variable in range(self.X.shape[1]): + linguistic_variables = [] + + for linguistic_variable in range(self.n_lv_possible): + parameter_pointer = third_pointer + aux_pointer + fz_parameters_idx = x[parameter_pointer:parameter_pointer + mf_size] + fz_parameters = self.antecedents_referencial[fuzzy_variable][fz_parameters_idx] + aux_pointer += mf_size + + if fz_type == fs.FUZZY_SETS.t2: + fz_parameters[0:6] = np.sort(fz_parameters[0:6]) + mu = [np.min(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.max(fz_parameters[4:6])] + ml = [np.max(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.min(fz_parameters[4:6])] + height = fz_parameters[6] / np.max(fz_parameters) + + ivfs = fs.IVFS(self.vl_names[linguistic_variable], ml, mu, + (min_domain[fuzzy_variable], max_domain[fuzzy_variable]), lower_height=height) + else: + ivfs = fs.FS(self.vl_names[linguistic_variable], np.sort(fz_parameters[0:4]), + (min_domain[fuzzy_variable], max_domain[fuzzy_variable])) + linguistic_variables.append(ivfs) + + antecedents.append(fs.fuzzyVariable( + self.var_names[fuzzy_variable], linguistic_variables)) + else: + try: + antecedents = self.lvs[kwargs['time_moment']] + except: + antecedents = self.lvs + + for i in range(self.n_classes): + if fz_type == fs.FUZZY_SETS.temporal: + fz_type = self.lvs[0][0].inside_type() + + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(antecedents, rule_list[i]) + + + if i == 0: + res = rules.MasterRuleBase([rule_base]) + else: + res.add_rule_base(rule_base) + + return res + + + def _evaluate(self, x: np.array, out: dict, *args, **kwargs): + ''' + :param x: array of train samples. x shape = features + those features are the parameters to optimize. + + :param out: dict where the F field is the fitness. It is used from the outside. + ''' + ruleBase = self._construct_ruleBase(x, self.fuzzy_type) + + score = self.fitness_func(ruleBase, self.X, self.y, self.tolerance) + + + out["F"] = 1 - score + + +
[docs] def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float): + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_rule_weights() + + score_acc = ev_object.classification_eval() + score_size = ev_object.size_eval(tolerance) + alpha = 0.99 + beta = 1 - alpha + + score = score_acc * alpha + score_size * beta + + return score
+
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/fuzzy_sets.html b/docs/build/_modules/ex_fuzzy/fuzzy_sets.html new file mode 100644 index 0000000..c7c2d1f --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/fuzzy_sets.html @@ -0,0 +1,657 @@ + + + + + + ex_fuzzy.fuzzy_sets — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.fuzzy_sets

+# -*- coding: utf-8 -*-
+"""
+This is a the source file that contains the class of GT2 fuzzy set and its most direct applications, 
+like computing the FM function, etc.
+
+"""
+import enum
+
+import numpy as np
+
+''' Enum that defines the fuzzy set types.'''
+FUZZY_SETS = enum.Enum(
+    'fuzzy_type', ['t1', 't2', 'gt2', 'temporal', 'temporal_t2'])
+
+
+
[docs]def trapezoidal_membership(x: np.array, params: list[float], epsilon=10E-5) -> np.array: + ''' + Trapezoidal membership functions. + + :param x: input values in the fuzzy set referencial domain. + :param params: four numbers that comprises the start and end of the trapezoid. + :param epsilon: small float number for numerical stability. Adjust accordingly only if there are NaN issues. + ''' + a, b, c, d = params + + # Special case: a singleton trapezoid + if a == d: + return np.equal(a, x).astype(float) + + if b == a: + b += epsilon + if c == d: + d += epsilon + + aux1 = (x - a) / (b - a) + aux2 = (d - x) / (d - c) + + return np.maximum(np.minimum(np.minimum(aux1, aux2), 1), 0)
+ + +def __gaussian2(x, params: list[float]) -> np.array: + ''' + Gaussian membership functions. + + :param mean: real number, mean of the gaussian function. + :param amplitude: real number. + :param standard_deviation: std of the gaussian function. + ''' + mean, amplitude, standard_deviation = params + return amplitude * np.exp(- ((x - mean) / standard_deviation) ** 2) + + +
[docs]class FS(): + ''' + Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets). + ''' + + def __init__(self, name: str, membership_parameters: list[float], domain: list[float]) -> None: + ''' + Creates a fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + ''' + self.name = name + self.domain = domain + self.membership_parameters = membership_parameters + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + ''' + return trapezoidal_membership(x, self.membership_parameters)
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum. + + :return: FUZZY_SETS enum. + ''' + return FUZZY_SETS.t1
+ + + def __call__(self, x: np.array) -> np.array: + ''' + Calling the Fuzzy set returns its membership. + + :param x: input values in the fuzzy set referencial domain. + :return: membership of the fuzzy set. + ''' + return self.membership(x)
+ + +
[docs]class IVFS(FS): + ''' + Class to define a iv fuzzy set. + ''' + + def __init__(self, name: str, secondMF_lower: list[float], secondMF_upper: list[float], + domain: list[float], lower_height=1.0) -> None: + ''' + Creates a IV fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + ''' + self.name = name + self.domain = domain + + assert secondMF_lower[0] >= secondMF_upper[0], 'First term membership incoherent' + assert secondMF_lower[0] <= secondMF_lower[1] and secondMF_lower[ + 1] <= secondMF_lower[2] and secondMF_lower[2] <= secondMF_lower[3], 'Lower memberships incoherent. ' + assert secondMF_upper[0] <= secondMF_upper[1] and secondMF_upper[ + 1] <= secondMF_upper[2] and secondMF_upper[2] <= secondMF_upper[3], 'Upper memberships incoherent.' + assert secondMF_lower[3] <= secondMF_upper[3], 'Final term memberships incoherent.' + + self.secondMF_lower = secondMF_lower + self.secondMF_upper = secondMF_upper + self.lower_height = lower_height + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the iv-membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + :return: iv-membership of the fuzzy set. + ''' + lower = trapezoidal_membership( + x, self.secondMF_lower) * self.lower_height + upper = trapezoidal_membership(x, self.secondMF_upper) + + try: + assert np.all(lower <= upper) + except AssertionError: + np.argwhere(lower > upper) + + return np.stack([lower, upper], axis=-1)
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2) + ''' + return FUZZY_SETS.t2
+ + +
[docs]class GT2(FS): + ''' + Class to define a gt2 fuzzy set. + ''' + + MAX_RES_SUPPORT = 4 # Number of decimals supported in the secondary + + def __init__(self, name: str, secondary_memberships: dict[float, FS], + domain: list[float], significant_decimals: int, + alpha_cuts: list[float] = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0], + unit_resolution: float = 0.2) -> None: + ''' + Creates a GT2 fuzzy set. + + :param name: string. + :param secondary_memberships: list of fuzzy sets. Secondary membership that maps original domain to [0, 1] + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + :param alpha_cuts: list of real numbers. Alpha cuts of the fuzzy set. + :param unit_resolution: real number. Resolution of the primary membership function. + ''' + self.name = name + self.domain = domain + self.secondary_memberships = secondary_memberships + self.alpha_cuts = alpha_cuts + self.iv_secondary_memberships = {} + self.unit_resolution = unit_resolution + og_keys = list(self.secondary_memberships.keys()) + self.significant_decimals = significant_decimals + self.domain_init = int( + float(og_keys[0]) * 10**self.significant_decimals) + + formatted_keys = [('%.' + str(self.significant_decimals) + 'f') % + xz for xz in np.array(list(self.secondary_memberships.keys()))] + for og_key, formatted_key in zip(og_keys, formatted_keys): + secondary_memberships[formatted_key] = self.secondary_memberships.pop( + og_key) + + self.sample_unit_domain = np.arange( + 0, 1 + self.unit_resolution, self.unit_resolution) + + for ix, alpha_cut in enumerate(alpha_cuts): + level_memberships = {} + array_level_memberships = np.zeros( + (len(secondary_memberships.items()), 2)) + + for jx, (x, fs) in enumerate(secondary_memberships.items()): + alpha_primary_memberships = fs.membership( + self.sample_unit_domain) + alpha_membership = alpha_primary_memberships >= alpha_cut + + try: + b = self.sample_unit_domain[np.argwhere( + alpha_membership)[0]][0] + c = self.sample_unit_domain[np.argwhere( + alpha_membership)[-1]][0] + except IndexError: # If no numbers are bigger than alpha, then it is because of rounding errors near 0. So, we fix this manually. + b = 0 + c = 0 + + alpha_cut_interval = [b, c] + + level_memberships[x] = alpha_cut_interval + array_level_memberships[jx, :] = np.array(alpha_cut_interval) + + self.iv_secondary_memberships[alpha_cut] = array_level_memberships + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the alpha cut memberships of a point. + + :param x: input values in the fuzzy set referencial domain. + :return: np array samples x alpha_cuts x 2 + ''' + x = np.array(x) + # locate the x in the secondary membership + formatted_x = ( + x * 10**self.significant_decimals).astype(int) - self.domain_init + + # Once the x is located we compute the function for each alpha cut + alpha_cut_memberships = [] + for ix, alpha in enumerate(self.alpha_cuts): + ivfs = np.squeeze( + np.array(self.iv_secondary_memberships[alpha][formatted_x])) + alpha_cut_memberships.append(np.squeeze(ivfs)) + + alpha_cut_memberships = np.array(alpha_cut_memberships) + + # So that the result is samples x alpha_cuts x 2 + return np.swapaxes(alpha_cut_memberships, 0, 1)
+ + +
[docs] def type(self) -> FUZZY_SETS: + return FUZZY_SETS.gt2
+ + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + if len(x.shape) == 3: + formatted = np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0) + else: + formatted = self.alpha_cuts + return np.sum(formatted * x, axis=-1) / np.sum(self.alpha_cuts) + + +
[docs] def alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + return self._alpha_reduction(x)
+ + +
[docs]class gaussianIVFS(IVFS): + ''' + Class to define a iv fuzzy set with gaussian membership. + ''' + +
[docs] def membership(self, input: np.array) -> np.array: + ''' + Computes the gaussian iv-membership of a point or a vector. + + :param input: input values in the fuzzy set referencial domain. + :return: np array samples x 2 + ''' + lower = __gaussian2(input, self.secondMF_lower) + upper = __gaussian2(input, self.secondMF_upper) + + return np.array(np.concatenate([lower, upper])).T
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (t1) + ''' + return FUZZY_SETS.t1
+ + +
[docs]class temporalFS(FS): + ''' + Class to implement temporal fuzzy sets. + ''' + + def __init__(self, std_fuzzy_set: FS, conditional_variable: np.array) -> None: + ''' + Creates a temporal fuzzy set. + + :param std_fuzzy_set: FS. Standard fuzzy set that contains the non-temporal aware memberhsip function. + :param conditional_variable: np.array. The variable that expresses the different temporal moments. Shape (time discrete moments, ). + ''' + self.std_set = std_fuzzy_set + self.tmp_function = conditional_variable + self.time = None + self.name = std_fuzzy_set.name + + if std_fuzzy_set.type() == FUZZY_SETS.t1: + self.membership_parameters = std_fuzzy_set.membership_parameters + elif std_fuzzy_set.type() == FUZZY_SETS.t2: + self.secondMF_upper = std_fuzzy_set.secondMF_upper + self.secondMF_lower = std_fuzzy_set.secondMF_lower + elif std_fuzzy_set.type() == FUZZY_SETS.gt2: + self.secondary_memberships = std_fuzzy_set.secondary_memberships + self.alpha_cuts = std_fuzzy_set.alpha_cuts + + +
[docs] def membership(self, input: np.array, time: int=None) -> np.array: + ''' + Computes the membership of each sample and in each time for the fs. + + :param input: array temporal_time x samples. + :time: int. Time moment to compute the membership. If none, looks for a fixed time + :return: array temporal_time x samples. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy set has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + return self.std_set.membership(input) * self.tmp_function[time]
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (temporal) + ''' + return FUZZY_SETS.temporal
+ + +
[docs] def inside_type(self) -> FUZZY_SETS: + ''' + Returns the type of the og fuzzy set computed before the time dependency. + ''' + return self.std_set.type()
+ + +
[docs] def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy set. + + :param time: int. Time moment to fix. + :return: FS. Fuzzy set with the fixed time. + ''' + self.time = time
+ + +
[docs]class fuzzyVariable(): + ''' + Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them. + ''' + + def __init__(self, name: str, fuzzy_sets: list[FS]) -> None: + ''' + Creates a fuzzy variable. + + :param name: string. Name of the fuzzy variable. + :param fuzzy_sets: list of IVFS. Each of the fuzzy sets that comprises the linguist variables of the fuzzy variable. + ''' + self.linguistic_variables = [] + self.name = name + + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + +
[docs] def linguistic_variable_names(self) -> list: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return [fs.name for fs in self.linguistic_variables]
+ + +
[docs] def get_linguistic_variables(self) -> list[FS]: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return self.linguistic_variables
+ + +
[docs] def compute_memberships(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the FS in the fuzzy variables. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x)) + + return res
+ + +
[docs] def domain(self) -> list[float]: + ''' + Returns the domain of the fuzzy variable. + + :return: list of floats. + ''' + return self.linguistic_variables[0].domain
+ + +
[docs] def fuzzy_type(self) -> FUZZY_SETS: + ''' + Returns the fuzzy type of the domain + + :return: the type of the fuzzy set present in the fuzzy variable. + ''' + return self.fs_type
+ + + def __getitem__(self, item) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + return self.linguistic_variables[item] + + + def __setitem__(self, item: int, elem: FS) -> None: + ''' + Sets the corresponding fs. + + :param item: int. Index of the FS. + :param elem: FS. The FS to set. + ''' + self.linguistic_variables[item] = elem + + + def __iter__(self) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + for fs in self.linguistic_variables: + yield fs + + + def __len__(self) -> int: + ''' + Returns the number of linguistic variables. + + :return: int. Number of linguistic variables. + ''' + return len(self.linguistic_variables) + + + def __call__(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + return self.compute_memberships(x)
+ + +
[docs]class temporalFuzzyVariable(fuzzyVariable): + ''' + Class to implement a temporal fuzzy variable. + ''' + + def __init__(self, name: str, fuzzy_sets: list[temporalFS]) -> None: + ''' + Creates a temporal fuzzy variable. + + :param str: name of the variable. + :param fuzzy_sets: list of the fuzzy sets pre-time dependencies. + ''' + self.linguistic_variables = [] + self.name = name + self.time = None + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + +
[docs] def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variable. + + :param time: int. Time moment to fix. + ''' + self.time = time
+ + +
[docs] def compute_memberships(self, x: np.array, time: int=None) -> dict: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables. + :param time: int. Time moment to compute the membership. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy variable has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x, time)) + + return res
+ + +
[docs] def n_time_moments(self) -> int: + ''' + Returns the number of time moments of the temporal fuzzy variable. + + :return: int. Number of time moments of the temporal fuzzy variable. + ''' + return self.linguistic_variables[0].tmp_function.shape[0]
+
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/persistence.html b/docs/build/_modules/ex_fuzzy/persistence.html new file mode 100644 index 0000000..d54f70a --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/persistence.html @@ -0,0 +1,192 @@ + + + + + + ex_fuzzy.persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.persistence

+'''
+Load the rules of a fuzzy rules system using plain text format.
+
+'''
+import numpy as np
+
+try:
+    from . import fuzzy_sets as fs
+    from . import rules
+except ImportError:
+    import fuzzy_sets as fs
+    import rules
+
+
+
[docs]def load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) -> rules.MasterRuleBase: + ''' + Load the rules from a string. Only for non-temporal fuzzy sets. + + :param rules_printed: string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase + :param fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class. + + ''' + consequent = 0 + linguistic_variables_names = [linguistic_variable.name for linguistic_variable in fuzzy_variables] + value_names = [x.name for x in fuzzy_variables[0]] + fz_type = fuzzy_variables[0].fuzzy_type() + consequent_names = [] + for line in rules_printed.splitlines(): + if line.startswith('IF'): + #Is a rule + antecedents , consequent_ds = line.split('WITH') + consequent_ds = consequent_ds.split(',')[0].strip() + init_rule_antecedents = np.zeros( + (len(fuzzy_variables),)) - 1 # -1 is dont care + + for antecedent in antecedents.split('AND'): + antecedent = antecedent.replace('IF', '').strip() + antecedent_name, antecedent_value = antecedent.split('IS') + antecedent_name = antecedent_name.strip() + antecedent_value = antecedent_value.strip() + antecedent_index = linguistic_variables_names.index(antecedent_name) + antecedent_value_index = value_names.index(antecedent_value) + + init_rule_antecedents[antecedent_index] = antecedent_value_index + + rule_simple = rules.RuleSimple(init_rule_antecedents, 0) + rule_simple.score = float(consequent_ds[3:].strip()) # We remove the 'DS ' and the last space + reconstructed_rules.append(rule_simple) + + elif line.startswith('Rules'): + #New consequent + consequent_name = line.split(':')[-1].strip() + consequent_names.append(consequent_name) + if consequent > 0: + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + if consequent == 1: + mrule_base = rules.MasterRuleBase([rule_base]) + elif consequent > 1: + mrule_base.add_rule_base(rule_base) + + reconstructed_rules = [] + consequent += 1 + + # We add the last rule base + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + mrule_base.add_rule_base(rule_base) + mrule_base.rename_cons(consequent_names) + + return mrule_base
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/rules.html b/docs/build/_modules/ex_fuzzy/rules.html new file mode 100644 index 0000000..3cfab21 --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/rules.html @@ -0,0 +1,1318 @@ + + + + + + ex_fuzzy.rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.rules

+# -*- coding: utf-8 -*-
+"""
+This is a the source file that contains the Rule, RuleBase and MasterRuleBase classes to perform fuzzy inference.
+
+"""
+import abc
+
+import numpy as np
+try:
+    from . import fuzzy_sets as fs
+    from . import centroid
+except ImportError:
+    import fuzzy_sets as fs
+    import centroid
+
+
+def _myprod(x: np.array, y: np.array) -> np.array:
+    '''
+    Proxy function to change the product operation interface
+    '''
+    return x*y
+
+
+
[docs]class Rule(): + ''' + Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself. + ''' + + def __init__(self, antecedents: list[fs.FS], consequent: fs.FS) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of fuzzy sets. + :param consequent: fuzzy set. + ''' + self.antecedents = antecedents + self.consequent = consequent + +
[docs] def membership(self, x: np.array, tnorm=_myprod) -> np.array: + ''' + Computes the membership of one input to the antecedents of the rule. + + :param x: input to compute the membership. + :param tnorm: t-norm to use in the inference process. + ''' + for ix, antecedent in enumerate(self.antecedents): + if ix == 0: + res = antecedent.membership(x) + else: + res = tnorm(res, antecedent.membership(x)) + + return res
+ +
[docs] def consequent_centroid(self) -> np.array: + ''' + Returns the centroid of the consequent using a Karnik and Mendel algorithm. + ''' + try: + return self.centroid_consequent + except AttributeError: + consequent_domain = self.consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = self.consequent.membership( + domain_linspace) + + self.centroid_consequent = centroid.compute_centroid_fs( + domain_linspace, consequent_memberships) + + return self.centroid_consequent
+ + +
[docs]class RuleSimple(): + ''' + Class designed to represent rules in its simplest form to optimize the computation in a rulebase. + + It indicates the antecedent values using a vector coded in this way: + ith entry: -1 means this variable is not used. 0-N indicates that the variable linguistic used for the ith input is that one. + ''' + + def __init__(self, antecedents: list[int], consequent: int) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of integers indicating the linguistic variable used for each input. + :param consequent: integer indicating the linguistic variable used for the consequent. + ''' + self.antecedents = list(map(int, antecedents)) + self.consequent = int(consequent) + + + def __getitem__(self, ix): + ''' + Returns the antecedent value for the given index. + + :param ix: index of the antecedent to return. + ''' + return self.antecedents[ix] + + + def __setitem__(self, ix, value): + ''' + Sets the antecedent value for the given index. + + :param ix: index of the antecedent to set. + :param value: value to set. + ''' + self.antecedents[ix] = value + + + def __str__(self): + ''' + Returns a string representation of the rule. + ''' + return 'Rule: antecedents: ' + str(self.antecedents) + ' consequent: ' + str(self.consequent) + + + def __len__(self): + ''' + Returns the number of antecedents in the rule. + ''' + return len(self.antecedents) + + + def __eq__(self, other): + ''' + Returns True if the two rules are equal. + ''' + return self.antecedents == other.antecedents and self.consequent == other.consequent + + + def __hash__(self): + ''' + Returns the hash of the rule. + ''' + return hash(str(self))
+ + +
[docs]class RuleBase(): + ''' + Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study) + Default class supports iv fs fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=np.prod) -> None: + ''' + Creates a rulebase with the given antecedents, rules and consequent. + + :param antecedents: list of fuzzy sets. + :param rules: list of rules. + :param consequent: fuzzy set. + :param tnorm: t-norm to use in the inference process. + ''' + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership(domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + +
[docs] def get_rules(self) -> list[RuleSimple]: + ''' + Returns the list of rules in the rulebase. + ''' + return self.rules
+ + +
[docs] def add_rule(self, new_rule: RuleSimple): + ''' + Adds a new rule to the rulebase. + :param new_rule: rule to add. + ''' + self.rules.append(new_rule)
+ + +
[docs] def add_rules(self, new_rules: list[RuleSimple]): + ''' + Adds a list of new rules to the rulebase. + + :param new_rules: list of rules to add. + ''' + self.rules += new_rules
+ + +
[docs] def remove_rule(self, ix: int) -> None: + ''' + Removes the rule in the given index. + :param ix: index of the rule to remove. + ''' + del self.rules[ix]
+ + +
[docs] def remove_rules(self, delete_list: list[int]) -> None: + ''' + Removes the rules in the given list of indexes. + + :param delete_list: list of indexes of the rules to remove. + ''' + self.rules = [rule for ix, rule in enumerate( + self.rules) if ix not in delete_list]
+ + +
[docs] def get_rulebase_matrix(self): + ''' + Returns a matrix with the antecedents values for each rule. + ''' + res = np.zeros((len(self.rules), len(self.rules[0]))) + + for ix, rule in enumerate(self.rules): + res[ix] = rule + + return res
+ + +
[docs] def get_scores(self): + ''' + Returns an array with the dominance score for each rule. + (Must been already computed by an evalRule object) + + ''' + res = np.zeros((len(self.rules, ))) + for ix, rule in enumerate(self.rules): + res[ix] = rule.score + + return res
+ + +
[docs] def compute_antecedents_memberships(self, x: np.array) -> list[dict]: + ''' + Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable. + x must be a vector (only one sample) + + :param x: vector with the values of the inputs. + ''' + if len(self.rules) > 0: + cache_antecedent_memberships = [] + + for ix, antecedent in enumerate(self.antecedents): + cache_antecedent_memberships.append( + antecedent.compute_memberships(x[:, ix])) + + return cache_antecedent_memberships + + else: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + return [np.zeros((x.shape[0], 1))] + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + return [np.zeros((x.shape[0], 1, 2))] + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + return [np.zeros((x.shape[0], len(self.alpha_cuts), 2))]
+ + +
[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the antecedent truth value of an input array. + + Return an array in shape samples x rules (x 2) (last is iv dimension) + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled according to their sums for each sample. + :return: array with the memberships of the antecedents for each rule. + ''' + if self.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((x.shape[0], len(self.rules), 2)) + elif self.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((x.shape[0], len(self.rules), )) + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros( + (x.shape[0], len(self.rules), len(self.alpha_cuts), 2)) + + antecedents_memberships = self.compute_antecedents_memberships(x) + + for jx, rule in enumerate(self.rules): + rule_antecedents = rule.antecedents + initiated = False + for ix, vl in enumerate(rule_antecedents): + if vl >= 0: + if not initiated: + membership = list(antecedents_memberships[ix])[vl] + initiated = True + else: + membership = self.tnorm(membership, list( + antecedents_memberships[ix])[vl]) + + try: + res[:, jx] = membership + except UnboundLocalError: + pass # All the antecedents are dont care. + + if scaled: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + non_zero_rows = np.sum(res, axis=1) > 0 + res[non_zero_rows] = res[non_zero_rows] / \ + np.sum(res[non_zero_rows], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + non_zero_rows = np.sum(res[:, :, 0], axis=1) > 0 + res[non_zero_rows, :, 0] = res[non_zero_rows, :, 0] / \ + np.sum(res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(res[:, :, 1], axis=1) > 0 + res[non_zero_rows, :, 1] = res[non_zero_rows, :, 1] / \ + np.sum(res[non_zero_rows, :, 1], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + + for ix, alpha in enumerate(self.alpha_cuts): + relevant_res = res[:, :, ix, :] + + non_zero_rows = np.sum(relevant_res[:, :, 0], axis=1) > 0 + relevant_res[non_zero_rows, :, 0] = relevant_res[non_zero_rows, :, 0] / \ + np.sum(relevant_res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(relevant_res[:, :, 1], axis=1) > 0 + relevant_res[non_zero_rows, :, 1] = relevant_res[non_zero_rows, :, 1] / \ + np.sum(relevant_res[non_zero_rows, :, 1], axis=1, keepdims=True) + + res[:, :, ix, :] = relevant_res + + return res
+ + +
[docs] def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules from the rule base. + ''' + all_rules = '' + for ix, rule in enumerate(self.rules): + initiated = False + str_rule = 'IF ' + for jx, vl_ix in enumerate(rule.antecedents): + antecedent = self.antecedents[jx] + keys = antecedent.linguistic_variable_names() + + if rule[jx] != -1: + if not initiated: + str_rule += antecedent.name + ' IS ' + str(keys[vl_ix]) + initiated = True + else: + str_rule += ' AND ' + antecedent.name + \ + ' IS ' + str(keys[vl_ix]) + + try: + score = rule.score if self.fuzzy_type() == fs.FUZZY_SETS.t1 else np.mean(rule.score) + str_rule += ' WITH DS ' + str(score) + + # If the classification scores have been computed, print them. + try: + str_rule += ', ACC ' + str(rule.accuracy) + + except AttributeError: + pass + except AttributeError: + str_rule += ' THEN consequent vl is ' + str(rule.consequent) + + all_rules += str_rule + '\n' + + if not return_rules: + print(all_rules) + else: + return all_rules
+ + +
[docs] @abc.abstractmethod + def inference(self, x: np.array) -> np.array: + ''' + Computes the fuzzy output of the fl inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each rule. + ''' + raise NotImplementedError
+ + +
[docs] @abc.abstractmethod + def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the fl inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output. + ''' + raise NotImplementedError
+ + +
[docs] @abc.abstractmethod + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the type of fuzzy set used in the RuleBase. + ''' + raise NotImplementedError
+ + + def __len__(self): + ''' + Returns the number of rules in the rule base. + ''' + return len(self.rules) + + +
[docs] def prune_bad_rules(self, tolerance=0.01) -> None: + ''' + Delete the rules from the rule base that do not have a dominance score superior to the threshold. + + :param tolerance: threshold for the dominance score. + ''' + delete_list = [] + try: + for ix, rule in enumerate(self.rules): + score = rule.score + if (self.fuzzy_type() == fs.FUZZY_SETS.t2) or (self.fuzzy_type() == fs.FUZZY_SETS.gt2): + score = np.mean(score) + + if score < tolerance: + delete_list.append(ix) + except AttributeError: + assert False, 'Dominance scores not computed for this rulebase' + + self.remove_rules(delete_list)
+ + +
[docs] def scores(self) -> np.array: + ''' + Returns the dominance score for each rule. + + :return: array with the dominance score for each rule. + ''' + scores = [] + for rule in self.rules: + scores.append(rule.score) + + return np.array(scores)
+ + + def __getitem__(self, item: int) -> RuleSimple: + ''' + Returns the corresponding rulebase. + + :param item: index of the rule. + :return: the corresponding rule. + ''' + return self.rules[item] + + + def __setitem__(self, key: int, value: RuleSimple) -> None: + ''' + Set the corresponding rule. + + :param key: index of the rule. + :param value: new rule. + ''' + self.rules[key] = value + + + def __iter__(self): + ''' + Returns an iterator for the rule base. + ''' + return iter(self.rules) + + + def __str__(self): + ''' + Returns a string with the rules in the rule base. + ''' + str_res = '' + for rule in self.rules: + str_res += str(rule) + '\n' + return str_res
+ + +
[docs]class RuleBaseT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports iv approximation for t2 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + + for ix, vl_consequent in enumerate(consequent.linguistic_variables): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + # If 0, we are classifying and we do not need the consequent centroids. + if len(self.consequent_centroids) > 0: + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the iv output of the t2 inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res
+ +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.mean(self.inference(x))
+ +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t2
+ + +
[docs]class RuleBaseGT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports gt2 fs. (ONLY FOR CLASSIFICATION PROBLEMS) + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseGT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.alpha_cuts = antecedents[0][0].alpha_cuts + + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the gt2 inference system. + + Return an array in shape samples x alpha_cuts + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res
+ + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + formtatted = np.expand_dims(np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0), axis=0) + return np.sum(formtatted * x, axis=2) / np.sum(self.alpha_cuts) + + +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.sum(np.array(self.alpha_cuts) * (self.inference(x)), axis=1) / np.sum(self.alpha_cuts)
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.gt2
+ + +
[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents performing the alpha_cut reduction. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + ''' + antecedent_membership = super().compute_rule_antecedent_memberships(x, scaled) + return self._alpha_reduction(antecedent_membership)
+ + +
[docs] def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents for all the alpha cuts. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + :return: array with the memberships of the antecedents for each sample. + ''' + return super().compute_rule_antecedent_memberships(x, scaled)
+ + +
[docs]class RuleBaseT1(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports t1 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT1 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), )) + + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix] = centroid.center_of_masses( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), )) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the t1 inference system. + + Return an array in shape samples. + + :param x: array with the values of the inputs. + :return: array with the output of the inference system for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.center_of_masses( + self.consequent_centroids_rules, antecedent_memberships[sample]) + + return res
+ +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Same as inference() in the t1 case. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return self.inference(x)
+ +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t1
+ + +
[docs]class MasterRuleBase(): + ''' + This Class encompasses a list of rule bases where each one corresponds to a different class. + ''' + + def __init__(self, rule_base: list[RuleBase], consequent_names: list[str]=None) -> None: + ''' + Constructor of the MasterRuleBase class. + + :param rule_base: list of rule bases. + ''' + self.rule_bases = rule_base + self.antecedents = rule_base[0].antecedents + + if consequent_names is None: + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))] + else: + self.consequent_names = consequent_names + + +
[docs] def rename_cons(self, consequent_names: list[str]) -> None: + ''' + Renames the consequents of the rule base. + ''' + self.consequent_names = consequent_names
+ + +
[docs] def add_rule(self, rule: RuleSimple, consequent: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + ''' + self.rule_bases[consequent].add_rule(rule)
+ + +
[docs] def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([[ix]*len(x) for ix, x in enumerate(self.rule_bases)], [])
+ + +
[docs] def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [x.get_rulebase_matrix() for x in self.rule_bases]
+ + +
[docs] def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rb in self.rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0)
+ + +
[docs] def compute_firing_strenghts(self, X) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + for ix in range(len(self.rule_bases)): + aux.append(self[ix].compute_rule_antecedent_memberships(X)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1)
+ + + def _winning_rules(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + + firing_strengths = self.compute_firing_strenghts(X) + association_degrees = self.get_scores() * firing_strengths + + if (self[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + association_degrees = np.mean(association_degrees, axis=2) + elif self[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(association_degrees, axis=3) + + winning_rules = np.argmax(association_degrees, axis=1) + + return winning_rules + + +
[docs] def winning_rule_predict(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = sum([[ix]*len(self[ix].rules) + for ix in range(len(self.rule_bases))], []) # The sum is for flatenning the list + winning_rules = self._winning_rules(X) + + return np.array([consequents[ix] for ix in winning_rules])
+ + +
[docs] def add_rule_base(self, rule_base: RuleBase) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.rule_bases.append(rule_base) + + if len(self.rule_bases) != len(self.consequent_names): + # We did not give proper names to the consequents + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))]
+ + +
[docs] def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + + :param autoprint: if True, the rules are printed. If False, the rules are returned as a string. + ''' + res = '' + for ix, ruleBase in enumerate(self.rule_bases): + res += 'Rules for consequent: ' + str(self.consequent_names[ix]) + '\n' + + res += '----------------\n' + res += ruleBase.print_rules(return_rules=True) + '\n' + + + if return_rules: + return res + else: + print(res)
+ + +
[docs] def get_rules(self) -> list[RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for ruleBase in self.rule_bases for rule in ruleBase.rules]
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.rule_bases[0].fuzzy_type()
+ + +
[docs] def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for ruleBase in self.rule_bases: + ruleBase.prune_bad_rules(tolerance)
+ + + def __getitem__(self, item) -> RuleBase: + ''' + Returns the corresponding rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.rule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.rule_bases) + + + def __str__(self) -> str: + ''' + Returns a string with the rules for each consequent. + ''' + return self.print_rules(return_rules=True) + + + def __eq__(self, __value: object) -> bool: + ''' + Returns True if the two rule bases are equal. + + :param __value: object to compare. + :return: True if the two rule bases are equal. + ''' + if not isinstance(__value, MasterRuleBase): + return False + else: + return self.rule_bases == __value.rule_bases + + +
[docs] def get_rulebases(self) -> list[RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + return self.rule_bases
+ + +
[docs]def list_rules_to_matrix(rule_list: list[RuleSimple]) -> np.array: + ''' + Returns a matrix out of the rule list. + + :param rule_list: list of rules. + :return: matrix with the antecedents of the rules. + ''' + assert len(rule_list) > 0, 'No rules to list!' + + res = np.zeros((len(rule_list), len(rule_list[0].antecedents))) + for ix, rule in enumerate(rule_list): + res[ix, :] = rule.antecedents + + return res
+ + +
[docs]class temporalMasterRuleBase(MasterRuleBase): + ''' + This class is a temporal extension of the MasterRuleBase class. It includes a list of + rule bases for each time step. + ''' + def __init__(self, rule_base: list[MasterRuleBase], time_step_names: list[str]=None): + ''' + Constructor of the temporalMasterRuleBase class. + + :param rule_base: list of rule bases. + :param time_steps: number of time steps. + ''' + super().__init__(rule_base) + self.time_steps = np.arange(len(rule_base)) + self.time_mrule_bases = rule_base + + if time_step_names is None: + self.time_step_names = [str(x) for x in self.time_steps] + else: + self.time_step_names = time_step_names + + for ix, mrb in enumerate(rule_base): + for jx, rb in enumerate(mrb): + for antecedent in rb.antecedents: + antecedent.fix_time(ix) + + self.antecedents = rule_base[0].antecedents + + +
[docs] def add_rule(self, rule: RuleSimple, consequent: int, time_step: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + :param time_step: time step of the rule base to add the rule. + ''' + self.time_mrule_bases[time_step][consequent].add_rule(rule)
+ + +
[docs] def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [a.get_rulebase_matrix() for x in self.time_mrule_bases for a in x]
+ + +
[docs] def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rule_bases in self.time_mrule_bases: + for rb in rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0)
+ + +
[docs] def compute_firing_strenghts(self, X: np.array, time_moments: list[int]) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + time_moments = np.array(time_moments) + + for time_moment, rule_bases in enumerate(self.time_mrule_bases): + actual_moment = np.equal(time_moments, time_moment) + for ix in range(len(rule_bases)): + if rule_bases.fuzzy_type() == fs.FUZZY_SETS.t2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + elif rule_bases.fuzzy_type() == fs.FUZZY_SETS.gt2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + else: + aux.append(rule_bases[ix].compute_rule_antecedent_memberships(X) * np.expand_dims(actual_moment, axis=1)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1)
+ + +
[docs] def winning_rule_predict(self, X: np.array, time_moments: int) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = [] + for ix, mrb in enumerate(self.time_mrule_bases): + for jx, rb in enumerate(mrb): + for rule in rb: + consequents.append(jx) + + # consequents = sum([[ix]*len(self[ix].get_rules()) + # for ix in range(len(self.rule_bases))], []) # The sum is for flatenning + firing_strengths = self.compute_firing_strenghts(X, time_moments) + + if self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.t2 or self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(self.get_scores(), axis=1) * firing_strengths + else: + association_degrees = self.get_scores() * firing_strengths + + + winning_rules = np.argmax(association_degrees, axis=1) + + return np.array([consequents[ix] for ix in winning_rules])
+ + +
[docs] def add_rule_base(self, rule_base: RuleBase, time: int) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.time_mrule_bases[time].add_rule_base(rule_base)
+ + +
[docs] def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + ''' + res = '' + for zx, time in enumerate(self.time_mrule_bases): + res += 'Rules for time step: ' + self.time_step_names[zx] + '\n' + res += '----------------\n' + for ix, ruleBase in enumerate(time): + res += 'Consequent: ' + time.consequent_names[ix] + '\n' + res += ruleBase.print_rules(True) + res += '\n' + res += '----------------\n' + + if return_rules: + return res + else: + print(res)
+ + +
[docs] def get_rules(self) -> list[RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for mruleBase in self.rule_bases for rule in mruleBase.get_rules()]
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.time_mrule_bases[0].rule_bases[0].fuzzy_type()
+ + +
[docs] def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for mruleBase in self.time_mrule_bases: + mruleBase.purge_rules(tolerance)
+ + + def __getitem__(self, item: int) -> RuleBase: + ''' + Returns the corresponding time rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.time_mrule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.time_mrule_bases) + + +
[docs] def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([x.get_consequents() for ix, x in enumerate(self.time_mrule_bases)], [])
+ + +
[docs] def get_rulebases(self) -> list[RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + rule_bases = [] + + for ruleBase in self.time_mrule_bases: + for rule in ruleBase: + rule_bases.append(rule) + + return rule_bases
+ + + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/ex_fuzzy/utils.html b/docs/build/_modules/ex_fuzzy/utils.html new file mode 100644 index 0000000..777862f --- /dev/null +++ b/docs/build/_modules/ex_fuzzy/utils.html @@ -0,0 +1,597 @@ + + + + + + ex_fuzzy.utils — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.utils

+# -*- coding: utf-8 -*-
+"""
+Functions that are not fuzzy-specific, but util for some computations. 
+Dedicated mostly to compute quantiles for fuzzy partitions.
+
+"""
+import numpy as np
+import pandas as pd
+
+try:
+    from . import fuzzy_sets as fs
+except ImportError:
+    import fuzzy_sets as fs
+
+from sklearn.model_selection import train_test_split
+
+
+
[docs]def quartile_compute(x: np.array) -> list[float]: + ''' + Computes the quartiles for each feature. + + :param x: array samples x features + :return: list of quartiles for each feature + ''' + return np.quantile(x, [0, 0.25, 0.5, 1], axis=0)
+ + +
[docs]def fixed_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles for each feature in numpy array. + Quantiles: [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1], axis=0)
+ + +
[docs]def partition3_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles partitioning the variable in 3 cases. + + Quantiles: [0.00, 0.20, 0.50, 0.80, 1.00] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.50, 0.80, 1.00], axis=0)
+ + +
[docs]def t1_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 4, 4). + ''' + n_partitions = 4 + trap_memberships_size = 4 + quantile_numbers = fixed_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == n_partitions - 1: + partition_parameters[:, partition, 0] = quantile_numbers[-3] + partition_parameters[:, partition, 1] = quantile_numbers[-2] + partition_parameters[:, partition, 2] = quantile_numbers[-1] + partition_parameters[:, partition, 3] = quantile_numbers[-1] + else: + pointer = 1 if partition == 1 else 4 + partition_parameters[:, partition, 0] = quantile_numbers[pointer] + partition_parameters[:, partition, + 1] = quantile_numbers[pointer + 1] + partition_parameters[:, partition, + 2] = quantile_numbers[pointer + 2] + partition_parameters[:, partition, + 3] = quantile_numbers[pointer + 3] + + return partition_parameters
+ + +
[docs]def t1_three_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == 1: + partition_parameters[:, partition, 0] = quantile_numbers[1] + partition_parameters[:, partition, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3] = quantile_numbers[3] + else: + partition_parameters[:, partition, 0] = quantile_numbers[2] + partition_parameters[:, partition, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2] = quantile_numbers[4] + partition_parameters[:, partition, 3] = quantile_numbers[4] + + return partition_parameters
+ + +
[docs]def t2_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in three trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4, 2). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size, 2)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0, 1] = quantile_numbers[0] + partition_parameters[:, partition, 1, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2, 1] = quantile_numbers[1] + partition_parameters[:, partition, 3, 1] = quantile_numbers[2] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1, 0] = quantile_numbers[0] + partition_parameters[:, partition, 2, 0] = quantile_numbers[1] + partition_parameters[:, partition, 3, 0] = quantile_numbers[1] + \ + 0.9 * (quantile_numbers[2] - quantile_numbers[1]) + + elif partition == 1: + partition_parameters[:, partition, 0, 1] = quantile_numbers[1] + partition_parameters[:, partition, 1, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 1] = ( + quantile_numbers[2] + quantile_numbers[3]) / 2 + partition_parameters[:, partition, 3, 1] = quantile_numbers[3] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[1] + \ + 0.1 * (quantile_numbers[2] - quantile_numbers[1]) + partition_parameters[:, partition, 1, 0] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 0] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3, 0] = quantile_numbers[2] + \ + 0.9 * (quantile_numbers[3] - quantile_numbers[2]) + + else: + partition_parameters[:, partition, 0, 1] = quantile_numbers[2] + partition_parameters[:, partition, 1, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2, 1] = quantile_numbers[4] + partition_parameters[:, partition, 3, 1] = quantile_numbers[4] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[2] + \ + 0.1 * (quantile_numbers[3] - quantile_numbers[2]) + partition_parameters[:, partition, 1, 0] = quantile_numbers[3] + partition_parameters[:, partition, 2, 0] = quantile_numbers[4] + partition_parameters[:, partition, 3, 0] = quantile_numbers[4] + + return partition_parameters
+ + +
[docs]def t1_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + tripartition_names = ['Low', 'Medium', 'High'] + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t1_three_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.FS(tripartition_names[ix], fz_memberships[fz_parameter, ix, :], [ + mins[fz_parameter], maxs[fz_parameter]]) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res
+ + +
[docs]def t2_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using iv fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t2_simple_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.IVFS(str(ix), fz_memberships[fz_parameter, ix, :, 0], fz_memberships[fz_parameter, ix, :, 1], [ + mins[fz_parameter], maxs[fz_parameter]], lower_height=0.8) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res
+ + +
[docs]def gt2_fuzzy_partitions_dataset(x0: np.array, resolution_exp:int=1) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using gt2 fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :param resolution_exp: exponent of the resolution of the partition. Default is -2, which means 0.01. (Number of significant decimals) + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + iv_simple_partition = t2_fuzzy_partitions_dataset(x) + resolution = 10.0**-np.abs(resolution_exp) + res = [] + # We iterate through all possible variables + for ix_var, fz_var in enumerate(iv_simple_partition): + domain_resolution = np.arange( + mins[ix_var], maxs[ix_var] + resolution, resolution) + fzs = [] + for ix_lv, fz_lv in enumerate(fz_var.get_linguistic_variables()): + memberships = fz_lv.membership(domain_resolution) + fs_domain = {} + for ix_z, x in enumerate(domain_resolution): + membership_z = memberships[ix_z] + fs_domain[x] = fs.FS(str(x), [membership_z[0], np.mean( + membership_z), np.mean(membership_z), membership_z[1]], [0.0, 1.0]) + + fzs.append(fs.GT2(fz_lv.name, fs_domain, [ + mins[ix_var], maxs[ix_var]], significant_decimals=np.abs(resolution_exp), unit_resolution=0.01)) + + res.append(fs.fuzzyVariable(fv_names[ix_var], fzs)) + + return res
+ + +
[docs]def construct_partitions(X, fz_type_studied) -> list[fs.fuzzyVariable]: + ''' + Returns a list of linguistic variables according to the kind of fuzzy specified. + + :param X: numpy array|pandas dataframe, shape samples x features. + :param fz_type_studied: fuzzy set type studied. + ''' + if fz_type_studied == fs.FUZZY_SETS.t1: + precomputed_partitions = t1_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.t2: + precomputed_partitions = t2_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.gt2: + precomputed_partitions = gt2_fuzzy_partitions_dataset(X) + + return precomputed_partitions
+ + +
[docs]def construct_conditional_frequencies(X: np.array, discrete_time_labels: list[int], initial_ffss: list[fs.FS]): + ''' + Computes the conditional temporal function for a set of fuzzy sets according to their variation in time. + + :param X: numpy array, shape samples x features. + :param discrete_time_labels: discrete time labels. + :param initial_fs: initial fuzzy set list. + :return: conditional frequencies. Array shape (time steps, initial fuzzy sets) + ''' + obs = X.shape[0] + discrete_time_labels = np.array(discrete_time_labels) + memberships = np.zeros((obs, len(initial_ffss))) + for ix, fset in enumerate(initial_ffss): + if fset.type() == fs.FUZZY_SETS.t2: + memberships[:, ix] = np.mean(fset.membership(X), axis=1) + elif fset.type() == fs.FUZZY_SETS.gt2: + memberships[:, ix] = np.mean(np.squeeze(fset._alpha_reduction(fset.membership(X))), axis=1) + else: + memberships[:, ix] = fset.membership(X) + + max_memberships = np.argmax(memberships, axis=1) + res = np.zeros((len(np.unique(discrete_time_labels)), len(initial_ffss))) + + for time in range(len(np.unique(discrete_time_labels))): + + relevant_memberships = max_memberships[time == discrete_time_labels] + fs_winner_counter = np.zeros(len(initial_ffss)) + for ix, fset in enumerate(initial_ffss): + fs_winner_counter[ix] = np.sum(relevant_memberships == ix) + + res[time, :] = fs_winner_counter + + return res / (np.max(res, axis=0) + 1e-6)
+ + +
[docs]def classify_temp(dates: pd.DataFrame, cutpoints: tuple[str, str], time: str) -> np.array: + ''' + Classifies a set of dates according to the temporal cutpoints. Uses {time} as a the time resolution. + Returns an array where true values are those values contained between those two date points. + + :param dates: data observations to cut. The temporal + :param cutpoints: points to check. + :param time: time field to use as the criteria. + :return: boolean array. True values are those contained between the cutpoints. + ''' + + def extract_hour(row): + return row.__getattribute__(time) + + hours = pd.to_datetime(dates['date']).apply(extract_hour) + + cutpoint_series_0 = pd.to_datetime(pd.Series([cutpoints[0]] * len(dates))) + cutpoint_series_0.index = dates.index + hours0 = cutpoint_series_0.apply(extract_hour) + + cutpoint_series_1 = pd.to_datetime(pd.Series([cutpoints[1]] * len(dates))) + cutpoint_series_1.index = dates.index + hours1 = cutpoint_series_1.apply(extract_hour) + + condicion1 = hours >= hours0 + condicion2 = hours <= hours1 + + return np.array(np.logical_and(condicion1, condicion2))
+ + +
[docs]def assign_time(a: np.array, observations: list[np.array]) -> int: + ''' + Assigns a temporal moment to a set of observations. + + :param a: array of boolean values. + :param observations: list of boolean arrays with the corresponding timestamps. + :return: the index of the correspondent time moment for the a-th observation. + :raises: ValueError if a is not timestamped in any of the observation arrays.''' + for ix, obs in enumerate(observations): + if obs[a]: + return ix + + raise ValueError('No temporal moment assigned')
+ + +
[docs]def create_tempVariables(X_train: np.array, time_moments: np.array, precomputed_partitions: list[fs.fuzzyVariable]) -> list[fs.temporalFS]: + ''' + Creates a list of temporal fuzzy variables. + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of temporal fuzzy variables. + ''' + temp_partitions = [] + for ix in range(X_train.shape[1]): + feat_conditional = construct_conditional_frequencies(X_train[:, ix], time_moments, initial_ffss=precomputed_partitions[ix]) + temp_fs_list = [] + for vl in range(feat_conditional.shape[1]): + vl_temp_fs = fs.temporalFS(precomputed_partitions[ix][vl], feat_conditional[:, vl]) + temp_fs_list.append(vl_temp_fs) + + temp_fs_variable = fs.temporalFuzzyVariable(precomputed_partitions[ix].name, temp_fs_list) + temp_partitions.append(temp_fs_variable) + + return temp_partitions
+ + +
[docs]def create_multi_tempVariables(X_train: np.array, time_moments: np.array, fuzzy_type: fs.FUZZY_SETS) -> list[list[fs.temporalFS]]: + ''' + Creates a of list of lists of temporal fuzzy variables. Each corresponds to a fuzzy partition in a different moment in time. + (So, instead of having one vl for all time moments, you have one different for each time moment that represents the same idea) + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of lists of temporal fuzzy variables. + ''' + temp_partitions = [] + + unique_time_moments = np.unique(time_moments) + for time in unique_time_moments: + X_obs = X_train[time_moments == time, :] + precomputed_partitions = construct_partitions(X_obs, fuzzy_type) + + temp_partitions.append(create_tempVariables(X_obs, time_moments[time_moments == time], precomputed_partitions)) + + return temp_partitions
+ + +
[docs]def temporal_cuts(X: pd.DataFrame, cutpoints: list[tuple[str, str]], time_resolution: str='hour') -> list[np.array]: + ''' + Returns a list of boolean indexes for each temporal moment. Performs the cuts between time steps using the cutpoints list. + + :param X: data observations to cut in temrporal moments. + :param temporal_moments: list of temporal moments to cut. + :param cutpoints: list of tuples with the cutpoints for each temporal moment. + :param time_resolution: time field to use as the criteria. + :return: list of boolean arrays. True values are those contained between the cutpoints in each moment. + ''' + + res = [] + for ix, cutpoint in enumerate(cutpoints): + observations = classify_temp(X, cutpoint, time=time_resolution) + res.append(observations) + + return res
+ + +
[docs]def temporal_assemble(X: np.array, y:np.array, temporal_moments: list[np.array]): + ''' + Assembles the data in the temporal moments in order to have partitions with balanced time moments in each one. + + :param X: data observations. + :param y: labels. + :param temporal_moments: list of boolean arrays. True values are those contained between the cutpoints in each moment. + :return: tuple of lists of data and labels for each temporal moment. + First tuple is: X_train, X_test, y_train, y_test + Second tuple is: train temporal moments, test temporal moments. + ''' + moments_partitions = [] + train_temporal_boolean_markers = [] + test_temporal_boolean_markers = [] + train_counter = 0 + test_counter = 0 + + for ix, temporal_moment in enumerate(temporal_moments): + X_train, X_test, y_train, y_test = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + moments_partitions.append((X_train, X_test, y_train, y_test)) + + if isinstance(X_train,(pd.core.series.Series,pd.DataFrame)): + X_train = pd.concat([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = pd.concat([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + else: + X_train = np.concatenate([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = np.concatenate([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + + for ix, temporal_moment in enumerate(temporal_moments): + # Believe, this makes sense to avoid rounding errrors in the size of the final vector + _, _, y_train0, y_test0 = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + + train_moment_observations = np.zeros((X_train.shape[0])) + train_moment_observations[train_counter:train_counter+len(y_train0)] = 1 + train_counter += len(y_train0) + train_temporal_boolean_markers.append(train_moment_observations) + + test_moment_observations = np.zeros((X_test.shape[0])) + test_moment_observations[test_counter:test_counter+len(y_test0)] = 1 + test_counter += len(y_test0) + test_temporal_boolean_markers.append(test_moment_observations) + + + return [X_train, X_test, y_train, y_test], [train_temporal_boolean_markers, test_temporal_boolean_markers]
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/_modules/index.html b/docs/build/_modules/index.html new file mode 100644 index 0000000..02f2f43 --- /dev/null +++ b/docs/build/_modules/index.html @@ -0,0 +1,117 @@ + + + + + + Overview: module code — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/build/_sources/api.rst.txt b/docs/build/_sources/api.rst.txt new file mode 100644 index 0000000..d932152 --- /dev/null +++ b/docs/build/_sources/api.rst.txt @@ -0,0 +1,16 @@ +API +=== + + +.. toctree:: + function_resume/fuzzy_sets + function_resume/rules + function_resume/eval_rules + function_resume/eval_tools + function_resume/evolutionary_fit + function_resume/centroid + function_resume/utils + function_resume/persistence + + + \ No newline at end of file diff --git a/docs/build/_sources/extending.rst.txt b/docs/build/_sources/extending.rst.txt new file mode 100644 index 0000000..cd25a76 --- /dev/null +++ b/docs/build/_sources/extending.rst.txt @@ -0,0 +1,15 @@ +.. _extending: + +Extending Ex-Fuzzy +======================================= + +Some of the default behaviour/components can be easily extended to support more fuzzy/explainability tools. +The whole library is programmed using object orientation, so that the simplest thing to suplant some methods is +to create classes that inherit from the correspondent classes. This is an easy way to implement additional to additional kinds of fuzzy sets. + +In the same way, other search algorithms could be used insead of the genetic search as long as they follow ``pymoo:problem`` interface. + +In order to change the behaviour of the precomputed partition, this functions can be easily replaced by others, becaouse the format +of their outputs is just list of objects from this library, like ``fs.FS()`` or ``fs.fuzzyVariable()``. + +As long as their membership values are numerical or IV/2-tuple, new fuzzy sets can be easily supported using the ``fs.FUZZY_SET`` enum. So that the rest of the methods will expect a numeric value as the mmebership value (``fs.FUZZY_SET.t1``) or a IV/tuple (``fs.FUZZY_SET.t2``) \ No newline at end of file diff --git a/docs/build/_sources/function_resume/centroid.rst.txt b/docs/build/_sources/function_resume/centroid.rst.txt new file mode 100644 index 0000000..478cc81 --- /dev/null +++ b/docs/build/_sources/function_resume/centroid.rst.txt @@ -0,0 +1,5 @@ +T2 Centroid compute +==================== + +.. automodule:: ex_fuzzy.centroid + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/eval_rules.rst.txt b/docs/build/_sources/function_resume/eval_rules.rst.txt new file mode 100644 index 0000000..f8852d0 --- /dev/null +++ b/docs/build/_sources/function_resume/eval_rules.rst.txt @@ -0,0 +1,5 @@ +Rule Evaluation Functions +========================= + +.. automodule:: ex_fuzzy.eval_rules + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/eval_tools.rst.txt b/docs/build/_sources/function_resume/eval_tools.rst.txt new file mode 100644 index 0000000..8ca931f --- /dev/null +++ b/docs/build/_sources/function_resume/eval_tools.rst.txt @@ -0,0 +1,5 @@ +Classification evaluation tools +=============================== + +.. automodule:: ex_fuzzy.eval_tools + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/evolutionary_fit.rst.txt b/docs/build/_sources/function_resume/evolutionary_fit.rst.txt new file mode 100644 index 0000000..9a28064 --- /dev/null +++ b/docs/build/_sources/function_resume/evolutionary_fit.rst.txt @@ -0,0 +1,5 @@ +Evolutionary Algorithms to Fit the rules +======================================== + +.. automodule:: ex_fuzzy.evolutionary_fit + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/fuzzy_sets.rst.txt b/docs/build/_sources/function_resume/fuzzy_sets.rst.txt new file mode 100644 index 0000000..d1d6855 --- /dev/null +++ b/docs/build/_sources/function_resume/fuzzy_sets.rst.txt @@ -0,0 +1,5 @@ +Fuzzy Sets Functions +==================== + +.. automodule:: ex_fuzzy.fuzzy_sets + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/persistence.rst.txt b/docs/build/_sources/function_resume/persistence.rst.txt new file mode 100644 index 0000000..3a2d3f4 --- /dev/null +++ b/docs/build/_sources/function_resume/persistence.rst.txt @@ -0,0 +1,5 @@ +Classification persistence +=============================== + +.. automodule:: ex_fuzzy.persistence + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/rules.rst.txt b/docs/build/_sources/function_resume/rules.rst.txt new file mode 100644 index 0000000..edd97d2 --- /dev/null +++ b/docs/build/_sources/function_resume/rules.rst.txt @@ -0,0 +1,5 @@ +Fuzzy Rules Functions +===================== + +.. automodule:: ex_fuzzy.rules + :members: \ No newline at end of file diff --git a/docs/build/_sources/function_resume/utils.rst.txt b/docs/build/_sources/function_resume/utils.rst.txt new file mode 100644 index 0000000..f995a05 --- /dev/null +++ b/docs/build/_sources/function_resume/utils.rst.txt @@ -0,0 +1,5 @@ +Partition utils +==================== + +.. automodule:: ex_fuzzy.utils + :members: \ No newline at end of file diff --git a/docs/build/_sources/gt2.rst.txt b/docs/build/_sources/gt2.rst.txt new file mode 100644 index 0000000..62a05d4 --- /dev/null +++ b/docs/build/_sources/gt2.rst.txt @@ -0,0 +1,21 @@ +.. _gt2: + +General Type 2 +======================================= + +Although General Type 2 Fuzzy sets are fully supported, they present a series of additional considerations when used by default: + +- The resolution of the primary domain function is always capped at 4 significant decimals. +- When the domain of the secondary function are real numbers, precision is capped at 4 significant decimals. + +We believe that this precision can be enough for most applications, but in case it needs to be changed, it is enough to change the ``fs.gt2.MAX_RES_SUPPORT`` constant to the desired number before instantiating the GT2 fuzzy set. + +Computing with the GT2 is more costly than the rest of the sets. Specially, computing the GT2 fuzzy partitions, which are also notably more complex than in the rest of the fuzzy sets. +Essentially, a GT2 fuzzy partition is a dictionary where each value in the dictionary maps a value in the secondary domain to a fuzzy set. +When a new value needs to be computed, the closest known value in the secondary membership to the new one is used. + +As an example, the function ``utils.gt2_fuzzy_partitions_dataset()`` returns a fuzzy partition using GT2 in the following manner: + +1. Computes a IV partition for all the variables. +2. Discretizes the domain of the secondary membership to an arbitrary precision. +3. In each of the discretized points, computes a FS using as parameters of the trapezoid function the lower and upper memberships and the central point of them. This results in a triangle for each FS. \ No newline at end of file diff --git a/docs/build/_sources/index.rst.txt b/docs/build/_sources/index.rst.txt new file mode 100644 index 0000000..7676564 --- /dev/null +++ b/docs/build/_sources/index.rst.txt @@ -0,0 +1,37 @@ +.. Ex-Fuzzy documentation master file, created by + sphinx-quickstart on Mon Jan 2 21:36:30 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Ex-Fuzzy's documentation! +==================================== + +**Ex-Fuzzy** is a library to perform fuzzy logic inference using fuzzy rules, with a special focus +on the explainable features of approximate reasoning. Different fuzzy sets are supported, and rules +are fitted to a dataset using genetic optimization. + +Check out the :doc:`usage` section for a few examples. + +.. toctree:: + + usage + step1 + step2 + step3 + step4 + precom + optimize + gt2 + tmpfs + extending + persistence + api + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/build/_sources/optimize.rst.txt b/docs/build/_sources/optimize.rst.txt new file mode 100644 index 0000000..b28c4ca --- /dev/null +++ b/docs/build/_sources/optimize.rst.txt @@ -0,0 +1,36 @@ +.. _ga: + +Genetic algorithm details +======================================= + +The genetic algorithm searchs for the optimal rule base for a problem. The criteria used to determine optimal is the one mentioned in :ref:`step3`: + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Dominance scores: are related to the support and confidence of each rule. So, rules that do not significantly fire or that are not discriminative are penalized. Thos that have a value less than the `tolerance` parmeter are dleted fro mthe rule base. +3. Small preference: rule bases with less rules and less antecedents are prefered. + +In order to understand dominance scores, we recommend reading the following paper: +Antonelli, M., Bernardo, D., Hagras, H. & Marcelloni, F. Multiobjective evolutionary optimization of type-2 fuzzy rule-based systems for financial data classification. IEEE Trans. Fuzzy Syst. 25, 249–264 (2017) + +--------------------------------------- +Limitations of the optimization process +--------------------------------------- + +- General Type 2 requires precomputed fuzzy partitions. +- When optimizing IV fuzzy partitions: Not all possible shapes of trapezoids all supported. Optimized trapezoids will always have max memberships for the lower and upper bounds in the same points. Height of the lower membership is optimized by scaling. Upper membership always reaches 1 at some point. + +----------------- +Fitness functions +----------------- + +The fitness function is a convex combination of two different scores. The Matthew Correlation Coefficient and a small size preference. +The small size preference is computed as: + +.. math:: + 1 - \frac{\text{antecedents used}}{\text{total antecedents possible}} + +In this way, if the rule base uses 0 antecedents it would perfect according to this criteria, and a rule base that used the max number of antecedents in each rule would be considered the worst. +Of course, extreme cases such as using 0 antecedents are not desirable, but they are not problematic since the first fitness criteria would discard empty or useless rule base. + +The convex combination is set to put 99% of importance to the Matthew Correlation Coefficient and 1% to the size preference, so that this loss is only used in draws. For more information about +changing this fitness function check :ref:`extending`. diff --git a/docs/build/_sources/persistence.rst.txt b/docs/build/_sources/persistence.rst.txt new file mode 100644 index 0000000..7dfd6ba --- /dev/null +++ b/docs/build/_sources/persistence.rst.txt @@ -0,0 +1,64 @@ +.. _persistence: + +Persistence +==================================== +Rules can be saved and loaded using plain text. The specification for this format is the same the print format of the rules. +We can extract the rules from a model using the ``ex_fuzzy.eval_tools.eval_fuzzy_model`` method, which can can return the rules in string format if the ``return_rules`` parameter is set to ``True``:: + + + + import pandas as pd + + from sklearn import datasets + from sklearn.model_selection import train_test_split + + import sys + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + import ex_fuzzy.persistence as persistence + import ex_fuzzy.vis_rules as vis_rules + + n_gen = 5 + n_pop = 30 + nRules = 15 + nAnts = 4 + vl = 3 + fz_type_studied = fs.FUZZY_SETS.t1 + + # Import some data to play with + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + # Split the data into a training set and a test set + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + + # We create a FRBC with the precomputed partitions and the specified fuzzy set type, + fl_classifier = GA.FuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1) + + str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) + + # Save the rules as a plain text file + with open('rules_iris_t1.txt', 'w') as f: + f.write(str_rules) + + + +The rules can be loaded from a file using the ``load_rules`` method of the ``FuzzyModel`` class:: + + # Load the rules from a file + mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions) + + fl_classifier = GA.FuzzyRulesClassifier(precomputed_rules=mrule_base) + +If we already created the ``FuzzyRulesClassifier`` object, we can load the rules using the ``load_master_rule_base`` method:: + + fl_classifier.load_master_rule_base(mrule_base) + + \ No newline at end of file diff --git a/docs/build/_sources/precom.rst.txt b/docs/build/_sources/precom.rst.txt new file mode 100644 index 0000000..760769f --- /dev/null +++ b/docs/build/_sources/precom.rst.txt @@ -0,0 +1,20 @@ +.. _precom: + +Computing fuzzy partitions +======================================= + +One of the most typical ways to compute fuzzy partitions is to use quantiles of the data. The module ``utils`` contains a series of functions +to generate fuzzy partitions for all the supported kinds of fuzzy sets. +The easiest way to compute these partitions is with the ``utils.construct_partitions`` function, specifying the fuzzy set desired:: + + import utils + + fz_type_studied = fs.FUZZY_SETS.t2 + precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +-------------------------------- +About the precomputed partitions +-------------------------------- +Partitions computed using these method use three linguistic variables per fuzzy variable. We chose that number as it creates easily understandable +low, medium and high partitions. For the case of IV-fuzzy sets, the trapezoids constructed, both the lower and upper memberships +present 1 values in the same points. For the case of General Type 2 Fuzzy sets check :ref:`gt2`. diff --git a/docs/build/_sources/step1.rst.txt b/docs/build/_sources/step1.rst.txt new file mode 100644 index 0000000..2391a06 --- /dev/null +++ b/docs/build/_sources/step1.rst.txt @@ -0,0 +1,52 @@ +.. _step1: + +Creating fuzzy sets and fuzzy variables +======================================= + +----------------- +Fuzzy Sets +----------------- +Ex-Fuzzy supports different kinds of fuzzy sets, but the procedure to use them all is the same. +Fuzzy sets have a name, a domain range and a membership function:: + + import ex_fuzzy.fuzzy_sets as fs + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + +This code creates a fuzzy set named "Cold", with a trapezoidal membership function and a domain that ranges from 0 to 40 degrees. +A fuzzy membership can be computed easily using the newly-created fuzzy set:: + + cold(8.2) + +This would be the code to do the same thing using interval-valued fuzzy sets:: + + cold2 = fs.IVFS('Cold', [0, 0, 5, 10], [0, 0, 5, 15], [0,40], 0.8) + +This code would create an interval-valued fuzzy set defined using a lower and upper membership function, +the same domain and name as before, and a maximum certainty of 0.8 for the lower membership. +The membership is computed just as an ordinary fuzzy set:: + + cold2(8.2) + +We could use any of these kinds of fuzzy sets (or even general-type 2 fuzzy sets) to construct all the linguistic variables +for our temperature domain:: + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + warm = fs.FS('Warm', [15, 20, 25, 30] , [0,40]) + hot = fs.FS('Hot', [25, 30, 40, 40] , [0,40]) + +----------------- +Fuzzy Variables +----------------- +Once we have the linguistic variables, we can construct a fuzzy variable. A fuzzy variable consists of a list of fuzzy sets +of the same kind and a proper name:: + + temperature = fs.fuzzyVariable('Temperature', [cold, warm, hot]) + +We do not need to specify domain or fuzzy set type, because the ``fuzzyVariable`` class deduces it from the fuzzy sets given in the list. +We can use a ``fuzzyVariable`` object to compute the memberships for a value to all the linguistic variables in the fuzzy variable:: + + temperature(8.2) + +Once we have defined the fuzzy variables, we can use them to construct a fuzzy rule base. This step is described :ref:`step2`. + diff --git a/docs/build/_sources/step2.rst.txt b/docs/build/_sources/step2.rst.txt new file mode 100644 index 0000000..585719b --- /dev/null +++ b/docs/build/_sources/step2.rst.txt @@ -0,0 +1,69 @@ +.. _step2: + +Using Fuzzy Rules +================= + +----------------- +Fuzzy Rules +----------------- +Fuzzy rules can be used to solve both regression and classification problems. + +The most straightforward way to construct a rule is to give a series of antecedents and a consequent. +For the case of classification, the consequent will be a class, and for regression, a fuzzy set. +Following the temperature example. Suppose we have these fuzzy sets as consequents to module +the use of air conditioner:: + + activate_small = fs.FS('Small', [0.0, 0.0, 0.1, 0.2], [0,1]) + activate_medium = fs.FS('Small', [0.1, 0.4, 0.4, 0.5], [0,1]) + activate_large = fs.FS('Small', [0.5, 0.8, 1.0, 1.0], [0,1]) + + activate = fs.fuzzyVariable('Activate', [activate_small, activate_medium, activate_large]) + +We can construct a rule for regression using the ``ex_fuzzy.rules.Rule`` class. +For example, the rule IF temperature IS hot THEN conditioner IS large can be implemented as:: + + import ex_fuzzy.rules as frule + frule.Rule([hot], activate_large) + +Then, we can use the ``membership`` method to obtain the degree of truth for a value in a rule, and the ``centroid`` method to +compute the centroid of the consequent. + +This implementation, however, can be problematic when there is a considerable number of rules with repeated antecedents, +because we do not want to compute the degree of truth for a value for the same antecedents over and over. So, instead +of using the ``Rule`` class, it is more practical to use ``RuleBase`` and ``RuleSimple`` classes. + +----------------- +Rule Bases +----------------- + +``RuleSimple`` is a class that simplifies the way in which rules are expressed. Its antecedents are expressed as a list, denoting the +linguistic variable relevant to the rule. The previous rule would be expressed as a ``RuleSimple`` as this:: + + my_rule = frule.RuleSimple([2], 2) + +The length of the first list is the number of antecedents, and the second argument denotes the fuzzy set "activates_large". +``RuleSimple`` is used by ``RuleBase`` class to efficiently compute the degrees of truth for all the antecedents for all the data, +and then use them when necessary. In order to create one rule base, we need the list of all the fuzzy variables to use, the consequent +and the rules expressed as ``RuleSimple`` objects:: + + my_rulebase = frule.RuleBaseT1([temperature], [my_rule], activate) + +This is quite a simple case because we are using only one fuzzy variable and one rule, but the process is the same for more rules and variables. +Then, we can use "my_rule" using the ``inference`` method:: + + my_rulebase.inference(8.2) + +Which will return the defuzzified result of the fuzzy inference process. The process is the same for the rest of the fuzzy sets, but other +classes are required: ``RuleBaseT2``, ``RuleBaseGT2``. + +----------------- +Master Rule Bases +----------------- +Master Rules bases are required in a classification problem. The way in which Ex-Fuzzy handles classification problems is by using one Rule Base +per consequent. So, the ``rules.MasterRuleBase`` class is used to handle the rule bases created for each class. An object of this class is created using +a list of rule bases, and its main method is ``rules.MasterRuleBase.winning_rule_predict()`` which returns the class obtained from the rule with highest association degree. + + + + +The next step is :ref:`step3`. diff --git a/docs/build/_sources/step3.rst.txt b/docs/build/_sources/step3.rst.txt new file mode 100644 index 0000000..f122dbb --- /dev/null +++ b/docs/build/_sources/step3.rst.txt @@ -0,0 +1,53 @@ +.. _step3: + +Optimizing a Fuzzy rule base for a classification problem +========================================================= + +-------------------------------------- +Training a fuzzy rule based classifier +-------------------------------------- +In order to train a fuzzy rule based classifier, Ex-Fuzzy uses a Genetic algorithm to tune the rules to the +desired classification task. The interface to use this kind of classifiers is analogous to the standard used +in scikit-learn, so it requires no previous knowledge about fuzzy logic in order to work. + +For example, we load the iris dataset and split it in train and test:: + + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +Once the data has been loaded, we just need to create a classifier with the proper parameters, number of rules, +maximum number of antecedents per rule, number of linguist variables per fuzzy variable and tolerance, which will explained +in the evaluation part of this section:: + + + import ex_fuzzy.evolutionary_fit as GA + + fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + +These instructions will optimize the linguistic variables in each fuzzy variable, using IV fuzzy sets, using three linguistic variables and ten rules with up to four antecedents. +It is also possible to give a precomputed set of linguistic variables as a list of fuzzy variables. A convenient way to compute +these with easy can be found on the ``utils`` module. + +Once the classifier has been created, the next thing is tranining it. Since we are using a Genetic algorithm, we can specify the number +of generations and the population size:: + + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + +And then we can use forward or predict just as with a scikit-learn classifier. + +----------------- +Evaluation +----------------- +The genetic algorithm needs a fitness measure to evaluate the quality of each solution. In order to obtain the best possible set of rules, +Ex-Fuzzy uses three different criteria. + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Dominance scores: are related to the support and confidence of each rule. So, rules that do not significantly fire or that are not discriminative are penalized. Thos that have a value less than the ``tolerance`` parmeter are dleted fro mthe rule base. +3. Small preference: rule bases with less rules and less antecedents are prefered. + diff --git a/docs/build/_sources/step4.rst.txt b/docs/build/_sources/step4.rst.txt new file mode 100644 index 0000000..fb88650 --- /dev/null +++ b/docs/build/_sources/step4.rst.txt @@ -0,0 +1,38 @@ +.. _step4: + +Visualize rules and results +=========================== +Ex-Fuzzy can also visualize the fuzzy sets and the rules obtained after the training process. +The easiest way to do this is using the ``eval_tools.eval_fuzzy_model`` function:: + + import eval_tools + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This function prints the performance of the model, prints the rules on screen and plot the rules as graphs. + +------------------- +Visualize Rules +------------------- + +You can visualize each consequent rules as a network, so that the interactions between the antecedents can be seen. + +.. image:: images/red_fuzzy.png + :width: 200 + +If the number of linguistic variables is three, they also get automatically colored. It is also possible to export them to the gephi software. + +-------------------- +Visualize Fuzzy Sets +-------------------- + +Each fuzzy set is also visualized according to its own kind. The same linguistic variable can be visualized using T1, IV and GT2 fuzzy sets: + +.. image:: images/ejemplo_t1.png + :width: 200 + +.. image:: images/ejemplo_t2.png + :width: 200 + +.. image:: images/example_gt2.png + :width: 200 \ No newline at end of file diff --git a/docs/build/_sources/tmpfs.rst.txt b/docs/build/_sources/tmpfs.rst.txt new file mode 100644 index 0000000..705f3f0 --- /dev/null +++ b/docs/build/_sources/tmpfs.rst.txt @@ -0,0 +1,56 @@ +.. _tempfs: + +Temporal Fuzzy Sets +======================================= + +Temporal Fuzzy Sets (TFS) are a generalization of fuzzy sets to include a temporal variable that influences the membership values. +A comprehensive explanation of such fuzzy sets can be found in [1]. + +Temporal fuzzy sets thus require the additional temporal variable, which can be spceified in the dedicated functions that work with this kind of fuzzy sets. +The way in which is the temporal variable is used is by first discretizing the the temporal variable from a continuos into a discrete time space. For example, +our time variable is the seconds of the day, we can do the following to define the different stages of the day:: + + + cut_point_morning0 = '00:00:00' + cut_point_morning1 = '10:00:00' + cut_points_morning = [cut_point_morning0, cut_point_morning1] + cut_point_daytime0 = '11:00:00' + cut_point_daytime1 = '19:00:00' + cut_points_daytime = [cut_point_daytime0, cut_point_daytime1] + cut_point_evening0 = '20:00:00' + cut_point_evening1 = '23:00:00' + cutpoints_evening = [cut_point_evening0, cut_point_evening1] + +Once we have defined this cut points, there are various functions in the ``ex_fuzzy.utils`` module to assign each of the observatio to one of the temporal moments:: + + temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour') + time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])]) + +We can also partition the dataset equally in order to have balanced partitions in each of the temporal moments:: + + partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers) + X_train, X_test, y_train, y_test = partitions + train_markers, test_markers = partition_markers + + +Given the time moments and the original fuzzy partitions, we can convert them into temporal fuzzy partitions:: + + temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions) + +The temporal fuzzy partitions are then used to train the temporal fuzzy classifier:: + + X_train = X_train.drop(columns=['date']) + X_test = X_test.drop(columns=['date']) + fl_classifier = GA.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, + linguistic_variables=temp_partitions, n_linguist_variables=3, + fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_classes=2) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments) + +The temporal fuzzy classifier can be evaluated using the ``eval_temporal_fuzzy_model`` function in the ``ex_fuzzy.eval_tools`` module:: + + eval_tools.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + time_moments=train_time_moments, test_time_moments=test_time_moments, + plot_rules=False, print_rules=True, plot_partitions=False) + + +[1] Kiani, M., Andreu-Perez, J., & Hagras, H. (2022). A Temporal Type-2 Fuzzy System for Time-dependent Explainable Artificial Intelligence. IEEE Transactions on Artificial Intelligence. \ No newline at end of file diff --git a/docs/build/_sources/usage.rst.txt b/docs/build/_sources/usage.rst.txt new file mode 100644 index 0000000..0d559b3 --- /dev/null +++ b/docs/build/_sources/usage.rst.txt @@ -0,0 +1,34 @@ +.. _usage: + +Getting Started +==================================== + + +The most straightforward way to use Ex-Fuzzy is to fit a fuzzy rule based classifier to a dataset, and then explore the results and the rules obtained. +A couple of examples of this can be found in the "demos" folder. + +A brief piece of code that does this case of use is the following:: + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This code trains the classifier and also plots the rules, prints them on screen and show the linguistic variables optimized in the process. + +In the following, we will explain how the different processes to perform fuzzy inference are automated in this code, and how they can be perfomed manually. + +The next step is :ref:`step1`. diff --git a/docs/build/_static/basic.css b/docs/build/_static/basic.css new file mode 100644 index 0000000..bf18350 --- /dev/null +++ b/docs/build/_static/basic.css @@ -0,0 +1,906 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 450px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a.brackets:before, +span.brackets > a:before{ + content: "["; +} + +a.brackets:after, +span.brackets > a:after { + content: "]"; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +table.footnote td, table.footnote th { + border: 0 !important; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/_static/css/badge_only.css b/docs/build/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/docs/build/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/docs/build/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/docs/build/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/build/_static/css/fonts/fontawesome-webfont.eot b/docs/build/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/docs/build/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/build/_static/css/fonts/fontawesome-webfont.svg b/docs/build/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/docs/build/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/build/_static/css/fonts/fontawesome-webfont.ttf b/docs/build/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/docs/build/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/build/_static/css/fonts/fontawesome-webfont.woff b/docs/build/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/docs/build/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/build/_static/css/fonts/fontawesome-webfont.woff2 b/docs/build/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/docs/build/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/build/_static/css/fonts/lato-bold-italic.woff b/docs/build/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/docs/build/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/build/_static/css/fonts/lato-bold-italic.woff2 b/docs/build/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/docs/build/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/build/_static/css/fonts/lato-bold.woff b/docs/build/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/docs/build/_static/css/fonts/lato-bold.woff differ diff --git a/docs/build/_static/css/fonts/lato-bold.woff2 b/docs/build/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/docs/build/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/build/_static/css/fonts/lato-normal-italic.woff b/docs/build/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/docs/build/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/build/_static/css/fonts/lato-normal-italic.woff2 b/docs/build/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/docs/build/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/build/_static/css/fonts/lato-normal.woff b/docs/build/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/docs/build/_static/css/fonts/lato-normal.woff differ diff --git a/docs/build/_static/css/fonts/lato-normal.woff2 b/docs/build/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/docs/build/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/build/_static/css/theme.css b/docs/build/_static/css/theme.css new file mode 100644 index 0000000..c03c88f --- /dev/null +++ b/docs/build/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/build/_static/doctools.js b/docs/build/_static/doctools.js new file mode 100644 index 0000000..e509e48 --- /dev/null +++ b/docs/build/_static/doctools.js @@ -0,0 +1,326 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Sphinx JavaScript utilities for all documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + +/** + * make the code below compatible with browsers without + * an installed firebug like debugger +if (!window.console || !console.firebug) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", + "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", + "profile", "profileEnd"]; + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +} + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} + +/** + * Small JavaScript module for the documentation. + */ +var Documentation = { + + init : function() { + this.fixFirefoxAnchorBug(); + this.highlightSearchWords(); + this.initIndexTable(); + if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) { + this.initOnKeyListeners(); + } + }, + + /** + * i18n support + */ + TRANSLATIONS : {}, + PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; }, + LOCALE : 'unknown', + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext : function(string) { + var translated = Documentation.TRANSLATIONS[string]; + if (typeof translated === 'undefined') + return string; + return (typeof translated === 'string') ? translated : translated[0]; + }, + + ngettext : function(singular, plural, n) { + var translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated === 'undefined') + return (n == 1) ? singular : plural; + return translated[Documentation.PLURALEXPR(n)]; + }, + + addTranslations : function(catalog) { + for (var key in catalog.messages) + this.TRANSLATIONS[key] = catalog.messages[key]; + this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); + this.LOCALE = catalog.locale; + }, + + /** + * add context elements like header anchor links + */ + addContextElements : function() { + $('div[id] > :header:first').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this headline')). + appendTo(this); + }); + $('dt[id]').each(function() { + $('\u00B6'). + attr('href', '#' + this.id). + attr('title', _('Permalink to this definition')). + appendTo(this); + }); + }, + + /** + * workaround a firefox stupidity + * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 + */ + fixFirefoxAnchorBug : function() { + if (document.location.hash && $.browser.mozilla) + window.setTimeout(function() { + document.location.href += ''; + }, 10); + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords : function() { + var params = $.getQueryParameters(); + var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; + if (terms.length) { + var body = $('div.body'); + if (!body.length) { + body = $('body'); + } + window.setTimeout(function() { + $.each(terms, function() { + body.highlightText(this.toLowerCase(), 'highlighted'); + }); + }, 10); + $('') + .appendTo($('#searchbox')); + } + }, + + /** + * init the domain index toggle buttons + */ + initIndexTable : function() { + var togglers = $('img.toggler').click(function() { + var src = $(this).attr('src'); + var idnum = $(this).attr('id').substr(7); + $('tr.cg-' + idnum).toggle(); + if (src.substr(-9) === 'minus.png') + $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); + else + $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); + }).css('display', ''); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { + togglers.click(); + } + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords : function() { + $('#searchbox .highlight-link').fadeOut(300); + $('span.highlighted').removeClass('highlighted'); + var url = new URL(window.location); + url.searchParams.delete('highlight'); + window.history.replaceState({}, '', url); + }, + + /** + * make the url absolute + */ + makeURL : function(relativeURL) { + return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; + }, + + /** + * get the current relative url + */ + getCurrentURL : function() { + var path = document.location.pathname; + var parts = path.split(/\//); + $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { + if (this === '..') + parts.pop(); + }); + var url = parts.join('/'); + return path.substring(url.lastIndexOf('/') + 1, path.length - 1); + }, + + initOnKeyListeners: function() { + $(document).keydown(function(event) { + var activeElementType = document.activeElement.tagName; + // don't navigate when in search box, textarea, dropdown or button + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey + && !event.shiftKey) { + switch (event.keyCode) { + case 37: // left + var prevHref = $('link[rel="prev"]').prop('href'); + if (prevHref) { + window.location.href = prevHref; + return false; + } + break; + case 39: // right + var nextHref = $('link[rel="next"]').prop('href'); + if (nextHref) { + window.location.href = nextHref; + return false; + } + break; + } + } + }); + } +}; + +// quick alias for translations +_ = Documentation.gettext; + +$(document).ready(function() { + Documentation.init(); +}); diff --git a/docs/build/_static/documentation_options.js b/docs/build/_static/documentation_options.js new file mode 100644 index 0000000..2fa8c97 --- /dev/null +++ b/docs/build/_static/documentation_options.js @@ -0,0 +1,12 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'None', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false +}; \ No newline at end of file diff --git a/docs/build/_static/file.png b/docs/build/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/build/_static/file.png differ diff --git a/docs/build/_static/jquery-3.5.1.js b/docs/build/_static/jquery-3.5.1.js new file mode 100644 index 0000000..5093733 --- /dev/null +++ b/docs/build/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/build/doctrees/api.doctree b/docs/build/doctrees/api.doctree new file mode 100644 index 0000000..d9621ed Binary files /dev/null and b/docs/build/doctrees/api.doctree differ diff --git a/docs/build/doctrees/classifiers.doctree b/docs/build/doctrees/classifiers.doctree new file mode 100644 index 0000000..c0c33cd Binary files /dev/null and b/docs/build/doctrees/classifiers.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle new file mode 100644 index 0000000..50e0d49 Binary files /dev/null and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/extending.doctree b/docs/build/doctrees/extending.doctree new file mode 100644 index 0000000..34ab7d9 Binary files /dev/null and b/docs/build/doctrees/extending.doctree differ diff --git a/docs/build/doctrees/function_resume/centroid.doctree b/docs/build/doctrees/function_resume/centroid.doctree new file mode 100644 index 0000000..714a3d2 Binary files /dev/null and b/docs/build/doctrees/function_resume/centroid.doctree differ diff --git a/docs/build/doctrees/function_resume/classifiers.doctree b/docs/build/doctrees/function_resume/classifiers.doctree new file mode 100644 index 0000000..e00179b Binary files /dev/null and b/docs/build/doctrees/function_resume/classifiers.doctree differ diff --git a/docs/build/doctrees/function_resume/cognitive_maps.doctree b/docs/build/doctrees/function_resume/cognitive_maps.doctree new file mode 100644 index 0000000..bde40ab Binary files /dev/null and b/docs/build/doctrees/function_resume/cognitive_maps.doctree differ diff --git a/docs/build/doctrees/function_resume/eval_rules.doctree b/docs/build/doctrees/function_resume/eval_rules.doctree new file mode 100644 index 0000000..f04238b Binary files /dev/null and b/docs/build/doctrees/function_resume/eval_rules.doctree differ diff --git a/docs/build/doctrees/function_resume/eval_tools.doctree b/docs/build/doctrees/function_resume/eval_tools.doctree new file mode 100644 index 0000000..dfea017 Binary files /dev/null and b/docs/build/doctrees/function_resume/eval_tools.doctree differ diff --git a/docs/build/doctrees/function_resume/evolutionary_fit.doctree b/docs/build/doctrees/function_resume/evolutionary_fit.doctree new file mode 100644 index 0000000..c8d4f9a Binary files /dev/null and b/docs/build/doctrees/function_resume/evolutionary_fit.doctree differ diff --git a/docs/build/doctrees/function_resume/fuzzy_sets.doctree b/docs/build/doctrees/function_resume/fuzzy_sets.doctree new file mode 100644 index 0000000..11e2ec6 Binary files /dev/null and b/docs/build/doctrees/function_resume/fuzzy_sets.doctree differ diff --git a/docs/build/doctrees/function_resume/persistence.doctree b/docs/build/doctrees/function_resume/persistence.doctree new file mode 100644 index 0000000..2297a53 Binary files /dev/null and b/docs/build/doctrees/function_resume/persistence.doctree differ diff --git a/docs/build/doctrees/function_resume/rule_mining.doctree b/docs/build/doctrees/function_resume/rule_mining.doctree new file mode 100644 index 0000000..883385d Binary files /dev/null and b/docs/build/doctrees/function_resume/rule_mining.doctree differ diff --git a/docs/build/doctrees/function_resume/rules.doctree b/docs/build/doctrees/function_resume/rules.doctree new file mode 100644 index 0000000..a256173 Binary files /dev/null and b/docs/build/doctrees/function_resume/rules.doctree differ diff --git a/docs/build/doctrees/function_resume/temporal.doctree b/docs/build/doctrees/function_resume/temporal.doctree new file mode 100644 index 0000000..346d706 Binary files /dev/null and b/docs/build/doctrees/function_resume/temporal.doctree differ diff --git a/docs/build/doctrees/function_resume/utils.doctree b/docs/build/doctrees/function_resume/utils.doctree new file mode 100644 index 0000000..73c2f60 Binary files /dev/null and b/docs/build/doctrees/function_resume/utils.doctree differ diff --git a/docs/build/doctrees/function_resume/vis_rules.doctree b/docs/build/doctrees/function_resume/vis_rules.doctree new file mode 100644 index 0000000..6b22ce5 Binary files /dev/null and b/docs/build/doctrees/function_resume/vis_rules.doctree differ diff --git a/docs/build/doctrees/gt2.doctree b/docs/build/doctrees/gt2.doctree new file mode 100644 index 0000000..28e7c43 Binary files /dev/null and b/docs/build/doctrees/gt2.doctree differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree new file mode 100644 index 0000000..af398fa Binary files /dev/null and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/optimize.doctree b/docs/build/doctrees/optimize.doctree new file mode 100644 index 0000000..1ab2df9 Binary files /dev/null and b/docs/build/doctrees/optimize.doctree differ diff --git a/docs/build/doctrees/persistence.doctree b/docs/build/doctrees/persistence.doctree new file mode 100644 index 0000000..c47bd6b Binary files /dev/null and b/docs/build/doctrees/persistence.doctree differ diff --git a/docs/build/doctrees/precom.doctree b/docs/build/doctrees/precom.doctree new file mode 100644 index 0000000..b71549c Binary files /dev/null and b/docs/build/doctrees/precom.doctree differ diff --git a/docs/build/doctrees/step1.doctree b/docs/build/doctrees/step1.doctree new file mode 100644 index 0000000..7514bf1 Binary files /dev/null and b/docs/build/doctrees/step1.doctree differ diff --git a/docs/build/doctrees/step2.doctree b/docs/build/doctrees/step2.doctree new file mode 100644 index 0000000..7d2911d Binary files /dev/null and b/docs/build/doctrees/step2.doctree differ diff --git a/docs/build/doctrees/step3.doctree b/docs/build/doctrees/step3.doctree new file mode 100644 index 0000000..87d194f Binary files /dev/null and b/docs/build/doctrees/step3.doctree differ diff --git a/docs/build/doctrees/step4.doctree b/docs/build/doctrees/step4.doctree new file mode 100644 index 0000000..251f379 Binary files /dev/null and b/docs/build/doctrees/step4.doctree differ diff --git a/docs/build/doctrees/tmpfs.doctree b/docs/build/doctrees/tmpfs.doctree new file mode 100644 index 0000000..a59f83b Binary files /dev/null and b/docs/build/doctrees/tmpfs.doctree differ diff --git a/docs/build/doctrees/usage.doctree b/docs/build/doctrees/usage.doctree new file mode 100644 index 0000000..0a74fe0 Binary files /dev/null and b/docs/build/doctrees/usage.doctree differ diff --git a/docs/build/extending.html b/docs/build/extending.html new file mode 100644 index 0000000..1c41892 --- /dev/null +++ b/docs/build/extending.html @@ -0,0 +1,124 @@ + + + + + + + Extending Ex-Fuzzy — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Extending Ex-Fuzzy

+

Some of the default behaviour/components can be easily extended to support more fuzzy/explainability tools. +The whole library is programmed using object orientation, so that the simplest thing to suplant some methods is +to create classes that inherit from the correspondent classes. This is an easy way to implement additional to additional kinds of fuzzy sets.

+

In the same way, other search algorithms could be used insead of the genetic search as long as they follow pymoo:problem interface.

+

In order to change the behaviour of the precomputed partition, this functions can be easily replaced by others, becaouse the format +of their outputs is just list of objects from this library, like fs.FS() or fs.fuzzyVariable().

+

As long as their membership values are numerical or IV/2-tuple, new fuzzy sets can be easily supported using the fs.FUZZY_SET enum. So that the rest of the methods will expect a numeric value as the mmebership value (fs.FUZZY_SET.t1) or a IV/tuple (fs.FUZZY_SET.t2)

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/centroid.html b/docs/build/function_resume/centroid.html new file mode 100644 index 0000000..163eb90 --- /dev/null +++ b/docs/build/function_resume/centroid.html @@ -0,0 +1,234 @@ + + + + + + + T2 Centroid compute — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

T2 Centroid compute

+

This is the source file that contains functions to compute centroids for the case of IV fuzzy sets, +which are commonly used when using the IV-T2 fuzzy sets.

+
+
+ex_fuzzy.centroid.center_of_masses(z: numpy.array, memberships: numpy.array) numpy.array[source]
+

Computes the center of masses of a t1 membership function.

+
+ +
+
+ex_fuzzy.centroid.compute_centroid_iv(z: numpy.array, memberships: numpy.array) numpy.array[source]
+

Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set.

+
+ +
+
+ex_fuzzy.centroid.compute_centroid_t2_l(z: numpy.array, memberships: numpy.array) float[source]
+

Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set.

+
+
Parameters
+
    +
  • z – Vector of the referencial values.

  • +
  • memberships – vector of the fuzzy memberships.

  • +
+
+
Returns
+

The centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.compute_centroid_t2_r(z: numpy.array, memberships: numpy.array) float[source]
+

Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set.

+
+
Parameters
+
    +
  • z – Vector of the referencial values.

  • +
  • memberships – vector of the fuzzy memberships.

  • +
+
+
Returns
+

The lowest membership of the centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.consequent_centroid(antecedent_memberships, centroids)[source]
+

Computes Karnik and Mendel algorithm? to find the centroid of a consequent iv fuzzy set given the centroids of the antecedents.

+
+ +
+
+ex_fuzzy.centroid.consequent_centroid_l(antecedent_memberships, centroids_l)[source]
+

Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set.

+
+
Parameters
+
    +
  • antecedent_memberships – M x 2 matrix. M rules and iv dimension (2). Vector of memberships.

  • +
  • centroids_r – M sized vector. Contains the referencial values.

  • +
+
+
Returns
+

the IV centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.consequent_centroid_r(antecedent_memberships: numpy.array, centroids_r: numpy.array) float[source]
+

Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set.

+
+
Parameters
+
    +
  • antecedent_memberships – M x 2 matrix. M rules and iv dimension (2). Vector of memberships.

  • +
  • centroids_r – M sized vector. Contains the referencial values.

  • +
+
+
Returns
+

the IV centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.y_compute(z: numpy.array, w: numpy.array) numpy.array[source]
+

Computes the ponderated centroid with normalized weighting.

+
+
Parameters
+
    +
  • z – Vector of the referencial values.

  • +
  • w – Vector of the fuzzy memberships.

  • +
+
+
Returns
+

The ponderated sum.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/eval_rules.html b/docs/build/function_resume/eval_rules.html new file mode 100644 index 0000000..7df6737 --- /dev/null +++ b/docs/build/function_resume/eval_rules.html @@ -0,0 +1,233 @@ + + + + + + + Rule Evaluation Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Rule Evaluation Functions

+

This file contains the classes to perform rule classification evaluation.

+
+
+class ex_fuzzy.eval_rules.evalRuleBase(mrule_base: ex_fuzzy.rules.MasterRuleBase, X: numpy.array, y: numpy.array, time_moments: Optional[numpy.array] = None)[source]
+

Bases: object

+

Class to evaluate a set of rules given a evaluation dataset.

+
+
+add_classification_metrics(X: Optional[numpy.array] = None, y: Optional[numpy.array] = None) None[source]
+

Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores. +If X and y are None uses the train set.

+
+
Parameters
+
    +
  • X – array of shape samples x features

  • +
  • y – array of shape samples

  • +
+
+
+
+ +
+
+add_rule_weights() None[source]
+

Add dominance score field to each of the rules present in the master Rule Base.

+
+ +
+
+association_degree() numpy.array[source]
+

Returns the association degree of each rule for each sample.

+
+
Returns
+

vector of shape rules

+
+
+
+ +
+
+classification_eval() float[source]
+

Returns the matthews correlation coefficient for a classification task using +the rules evaluated.

+
+
Returns
+

mattews correlation coefficient. (float in [-1, 1])

+
+
+
+ +
+
+compute_pattern_confidence() numpy.array[source]
+

Computes the pattern confidence for each of the rules for the given X. +Each pattern confidence is the normalized firing strength.

+
+
Returns
+

array of shape 1 x rules

+
+
+
+ +
+
+compute_pattern_support() numpy.array[source]
+

Computes the pattern support for each of the rules for the given X. +Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, +dvided by their number.

+
+
Returns
+

array of shape rules x 2

+
+
+
+ +
+
+dominance_scores() numpy.array[source]
+

Returns the dominance score of each pattern for each rule.

+
+
Returns
+

array of shape rules x 2

+
+
+
+ +
+
+size_eval(tolerance=0.1) float[source]
+

Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents.

+

0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. +The more rules and antecedent per rules the lower this score is.

+
+
Parameters
+

tolerance – float in [0, 1]. The tolerance for the dominance score. Default 0.1

+
+
Returns
+

float in [0, 1] with the score.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/eval_tools.html b/docs/build/function_resume/eval_tools.html new file mode 100644 index 0000000..96c00c1 --- /dev/null +++ b/docs/build/function_resume/eval_tools.html @@ -0,0 +1,177 @@ + + + + + + + Classification evaluation tools — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Classification evaluation tools

+

Functions that contain some general functions to eval already fitted fuzzy rule based models. +It can also be used to visualize rules and fuzzy partitions.

+
+
+ex_fuzzy.eval_tools.eval_fuzzy_model(fl_classifier: ex_fuzzy.evolutionary_fit.FuzzyRulesClassifier, X_train: numpy.array, y_train: numpy.array, X_test: numpy.array, y_test: numpy.array, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) None[source]
+

Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.

+
+
Parameters
+
    +
  • fl_classifier – Fuzzy rule based model.

  • +
  • X_train – Training data.

  • +
  • y_train – Training labels.

  • +
  • X_test – Test data.

  • +
  • y_test – Test labels.

  • +
  • plot_rules – If True, it plots the rules.

  • +
  • print_rules – If True, it prints the rules.

  • +
  • plot_partitions – If True, it plots the fuzzy partitions.

  • +
+
+
Returns
+

None

+
+
+
+ +
+
+ex_fuzzy.eval_tools.eval_temporal_fuzzy_model(fl_classifier: ex_fuzzy.evolutionary_fit.FuzzyRulesClassifier, X_train: numpy.array, y_train: numpy.array, X_test: numpy.array, y_test: numpy.array, time_moments: Optional[list[int]] = None, test_time_moments: Optional[list[int]] = None, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) None[source]
+

Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.

+
+
Parameters
+
    +
  • fl_classifier – Fuzzy rule based model.

  • +
  • X_train – Training data.

  • +
  • y_train – Training labels.

  • +
  • X_test – Test data.

  • +
  • y_test – Test labels.

  • +
  • plot_rules – If True, it plots the rules.

  • +
  • print_rules – If True, it prints the rules.

  • +
  • plot_partitions – If True, it plots the fuzzy partitions.

  • +
+
+
Returns
+

None

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/evolutionary_fit.html b/docs/build/function_resume/evolutionary_fit.html new file mode 100644 index 0000000..2db8c8b --- /dev/null +++ b/docs/build/function_resume/evolutionary_fit.html @@ -0,0 +1,328 @@ + + + + + + + Evolutionary Algorithms to Fit the rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Evolutionary Algorithms to Fit the rules

+

This is a the source file that contains the class to train/fit the rulebase using a genetic algorithm.

+
+
+class ex_fuzzy.evolutionary_fit.FitRuleBase(X: numpy.array, y: numpy.array, nRules: int, nAnts: int, n_classes: int, thread_runner: Optional[pymoo.core.problem.StarmapParallelization] = None, **kwargs)[source]
+

Bases: pymoo.core.problem.Problem

+

Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies. +Supports type 1 and iv fs (iv-type 2)

+
+
+fitness_func(ruleBase: ex_fuzzy.rules.RuleBase, X: numpy.array, y: numpy.array, tolerance: float)[source]
+

Fitness function for the optimization problem. +:param ruleBase: RuleBase object +:param X: array of train samples. X shape = (n_samples, n_features) +:param y: array of train labels. y shape = (n_samples,) +:param tolerance: float. Tolerance for the size evaluation. +:return: float. Fitness value.

+
+ +
+ +
+
+class ex_fuzzy.evolutionary_fit.FuzzyRulesClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: Optional[ex_fuzzy.fuzzy_sets.fuzzy_type] = None, tolerance: float = 0.0, n_linguist_variables: int = 0, verbose=False, linguistic_variables: Optional[list[ex_fuzzy.fuzzy_sets.fuzzyVariable]] = None, domain: Optional[list[float]] = None, n_class: Optional[int] = None, precomputed_rules: Optional[ex_fuzzy.rules.MasterRuleBase] = None, runner: int = 1)[source]
+

Bases: object

+

Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables.

+
+
+customized_loss(loss_function)[source]
+

Function to customize the loss function used for the optimization.

+
+
Parameters
+

loss_function – function that takes as input the true labels and the predicted labels and returns a float.

+
+
Returns
+

None

+
+
+
+ +
+
+fit(X: numpy.array, y: numpy.array, n_gen: int = 70, pop_size: int = 30, checkpoints: int = 10)[source]
+

Fits a fuzzy rule based classifier using a genetic algorithm to the given data.

+
+
Parameters
+
    +
  • X – numpy array samples x features

  • +
  • y – labels. integer array samples (x 1)

  • +
  • n_gen – integer. Number of generations to run the genetic algorithm.

  • +
  • pop_size – integer. Population size for each gneration.

  • +
  • time_moments – array of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
  • checkpoints – integer. Number of checkpoints to save the best rulebase found so far.

  • +
+
+
Returns
+

None. The classifier is fitted to the data.

+
+
+
+ +
+
+forward(X: numpy.array) numpy.array[source]
+

Returns the predicted class for each sample.

+
+
Parameters
+

X – np array samples x features.

+
+
Returns
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+get_rulebase() list[numpy.array][source]
+

Get the rulebase obtained after fitting the classifier to the data.

+
+
Returns
+

a matrix format for the rulebase.

+
+
+
+ +
+
+load_master_rule_base(rule_base: ex_fuzzy.rules.MasterRuleBase) None[source]
+

Loads a master rule base to be used in the prediction process.

+
+
Parameters
+

rule_base – ruleBase object.

+
+
Returns
+

None

+
+
+
+ +
+
+plot_fuzzy_variables() None[source]
+

Plot the fuzzy partitions in each fuzzy variable.

+
+ +
+
+predict(X: numpy.array) numpy.array[source]
+

Returns the predicted class for each sample.

+
+
Parameters
+

X – np array samples x features.

+
+
Returns
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+print_rules(return_rules: bool = False) None[source]
+

Print the rules contained in the fitted rulebase.

+
+ +
+
+rename_fuzzy_variables() None[source]
+

Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process.

+
+
Returns
+

None. Names are sorted accorded to the central point of the fuzzy memberships.

+
+
+
+ +
+ +
+
+class ex_fuzzy.evolutionary_fit.TemporalFuzzyRulesClassifier(nRules: int, nAnts: int, fuzzy_type: Optional[ex_fuzzy.fuzzy_sets.fuzzy_type] = None, tolerance: float = 0.0, n_linguist_variables: int = 0, verbose=False, linguistic_variables: Optional[list[ex_fuzzy.fuzzy_sets.fuzzyVariable]] = None, domain: Optional[list[float]] = None, n_classes: Optional[int] = None, **kwargs)[source]
+

Bases: ex_fuzzy.evolutionary_fit.FuzzyRulesClassifier

+

Class that is used as a classifier for a fuzzy rule based system with time dependencies. Supports precomputed and optimization of the linguistic variables.

+
+
+fit(X: numpy.array, y: numpy.array, n_gen: int = 50, pop_size: int = 10, time_moments: Optional[numpy.array] = None, checkpoints: int = 10)[source]
+

Fits a fuzzy rule based classifier using a genetic algorithm to the given data.

+
+
Parameters
+
    +
  • X – numpy array samples x features

  • +
  • y – labels. integer array samples (x 1)

  • +
  • n_gen – integer. Number of generations to run the genetic algorithm.

  • +
  • pop_size – integer. Population size for each gneration.

  • +
  • time_moments – array of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
+
+
Returns
+

None. The classifier is fitted to the data.

+
+
+
+ +
+
+forward(X: numpy.array, time_moments: Optional[list[int]] = None) numpy.array[source]
+

Returns the predicted class for each sample.

+
+
Parameters
+
    +
  • X – np array samples x features.

  • +
  • time_moments – list of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
+
+
Returns
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+get_rulebase() list[numpy.array][source]
+

Get the rulebase obtained after fitting the classifier to the data.

+
+
Returns
+

a matrix format for the rulebase.

+
+
+
+ +
+
+plot_fuzzy_variables() None[source]
+

Plot the fuzzy partitions in each fuzzy variable.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/fuzzy_sets.html b/docs/build/function_resume/fuzzy_sets.html new file mode 100644 index 0000000..a56a94e --- /dev/null +++ b/docs/build/function_resume/fuzzy_sets.html @@ -0,0 +1,442 @@ + + + + + + + Fuzzy Sets Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fuzzy Sets Functions

+

This is a the source file that contains the class of GT2 fuzzy set and its most direct applications, +like computing the FM function, etc.

+
+
+class ex_fuzzy.fuzzy_sets.FS(name: str, membership_parameters: list[float], domain: list[float])[source]
+

Bases: object

+

Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets).

+
+
+membership(x: numpy.array) numpy.array[source]
+

Computes the membership of a point or a vector.

+
+
Parameters
+

x – input values in the fuzzy set referencial domain.

+
+
+
+ +
+
+type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum.

+
+
Returns
+

FUZZY_SETS enum.

+
+
+
+ +
+ +
+
+ex_fuzzy.fuzzy_sets.FUZZY_SETS
+

alias of ex_fuzzy.fuzzy_sets.fuzzy_type

+
+ +
+
+class ex_fuzzy.fuzzy_sets.GT2(name: str, secondary_memberships: dict[float, ex_fuzzy.fuzzy_sets.FS], domain: list[float], significant_decimals: int, alpha_cuts: list[float] = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0], unit_resolution: float = 0.2)[source]
+

Bases: ex_fuzzy.fuzzy_sets.FS

+

Class to define a gt2 fuzzy set.

+
+
+alpha_reduction(x) numpy.array[source]
+

Computes the type reduction to reduce the alpha cuts to one value.

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+
+membership(x: numpy.array) numpy.array[source]
+

Computes the alpha cut memberships of a point.

+
+
Parameters
+

x – input values in the fuzzy set referencial domain.

+
+
Returns
+

np array samples x alpha_cuts x 2

+
+
+
+ +
+
+type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum.

+
+
Returns
+

FUZZY_SETS enum.

+
+
+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.IVFS(name: str, secondMF_lower: list[float], secondMF_upper: list[float], domain: list[float], lower_height=1.0)[source]
+

Bases: ex_fuzzy.fuzzy_sets.FS

+

Class to define a iv fuzzy set.

+
+
+membership(x: numpy.array) numpy.array[source]
+

Computes the iv-membership of a point or a vector.

+
+
Parameters
+

x – input values in the fuzzy set referencial domain.

+
+
Returns
+

iv-membership of the fuzzy set.

+
+
+
+ +
+
+type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2)

+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.fuzzyVariable(name: str, fuzzy_sets: list[ex_fuzzy.fuzzy_sets.FS])[source]
+

Bases: object

+

Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them.

+
+
+compute_memberships(x: numpy.array) list[source]
+

Computes the membership to each of the FS in the fuzzy variables.

+
+
Parameters
+

x – numeric value or array. Computes the membership to each of the FS in the fuzzy variables.

+
+
Returns
+

list of floats. Membership to each of the FS in the fuzzy variables.

+
+
+
+ +
+
+domain() list[float][source]
+

Returns the domain of the fuzzy variable.

+
+
Returns
+

list of floats.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the fuzzy type of the domain

+
+
Returns
+

the type of the fuzzy set present in the fuzzy variable.

+
+
+
+ +
+
+get_linguistic_variables() list[ex_fuzzy.fuzzy_sets.FS][source]
+

Returns the name of the linguistic variables.

+
+
Returns
+

list of strings.

+
+
+
+ +
+
+linguistic_variable_names() list[source]
+

Returns the name of the linguistic variables.

+
+
Returns
+

list of strings.

+
+
+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.gaussianIVFS(name: str, secondMF_lower: list[float], secondMF_upper: list[float], domain: list[float], lower_height=1.0)[source]
+

Bases: ex_fuzzy.fuzzy_sets.IVFS

+

Class to define a iv fuzzy set with gaussian membership.

+
+
+membership(input: numpy.array) numpy.array[source]
+

Computes the gaussian iv-membership of a point or a vector.

+
+
Parameters
+

input – input values in the fuzzy set referencial domain.

+
+
Returns
+

np array samples x 2

+
+
+
+ +
+
+type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the type of the fuzzy set. (t1)

+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.temporalFS(std_fuzzy_set: ex_fuzzy.fuzzy_sets.FS, conditional_variable: numpy.array)[source]
+

Bases: ex_fuzzy.fuzzy_sets.FS

+

Class to implement temporal fuzzy sets.

+
+
+fix_time(time: int) None[source]
+

Fixes the time of the temporal fuzzy set.

+
+
Parameters
+

time – int. Time moment to fix.

+
+
Returns
+

FS. Fuzzy set with the fixed time.

+
+
+
+ +
+
+inside_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the type of the og fuzzy set computed before the time dependency.

+
+ +
+
+membership(input: numpy.array, time: Optional[int] = None) numpy.array[source]
+

Computes the membership of each sample and in each time for the fs.

+
+
Parameters
+

input – array temporal_time x samples.

+
+
Time
+

int. Time moment to compute the membership. If none, looks for a fixed time

+
+
Returns
+

array temporal_time x samples.

+
+
+
+ +
+
+type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the type of the fuzzy set. (temporal)

+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.temporalFuzzyVariable(name: str, fuzzy_sets: list[ex_fuzzy.fuzzy_sets.temporalFS])[source]
+

Bases: ex_fuzzy.fuzzy_sets.fuzzyVariable

+

Class to implement a temporal fuzzy variable.

+
+
+compute_memberships(x: numpy.array, time: Optional[int] = None) dict[source]
+

Computes the membership to each of the FS in the fuzzy variables.

+
+
Parameters
+
    +
  • x – numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables.

  • +
  • time – int. Time moment to compute the membership.

  • +
+
+
Returns
+

list of floats. Membership to each of the FS in the fuzzy variables.

+
+
+
+ +
+
+fix_time(time: int) None[source]
+

Fixes the time of the temporal fuzzy variable.

+
+
Parameters
+

time – int. Time moment to fix.

+
+
+
+ +
+
+n_time_moments() int[source]
+

Returns the number of time moments of the temporal fuzzy variable.

+
+
Returns
+

int. Number of time moments of the temporal fuzzy variable.

+
+
+
+ +
+ +
+
+ex_fuzzy.fuzzy_sets.trapezoidal_membership(x: numpy.array, params: list[float], epsilon=0.0001) numpy.array[source]
+

Trapezoidal membership functions.

+
+
Parameters
+
    +
  • x – input values in the fuzzy set referencial domain.

  • +
  • params – four numbers that comprises the start and end of the trapezoid.

  • +
  • epsilon – small float number for numerical stability. Adjust accordingly only if there are NaN issues.

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/persistence.html b/docs/build/function_resume/persistence.html new file mode 100644 index 0000000..1f22b92 --- /dev/null +++ b/docs/build/function_resume/persistence.html @@ -0,0 +1,142 @@ + + + + + + + Classification persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Classification persistence

+

Load the rules of a fuzzy rules system using plain text format.

+
+
+ex_fuzzy.persistence.load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) ex_fuzzy.rules.MasterRuleBase[source]
+

Load the rules from a string. Only for non-temporal fuzzy sets.

+
+
Parameters
+
    +
  • rules_printed – string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase

  • +
  • fuzzy_variables – list with the linguistic variables. Objects of FuzzyVariable class.

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/rules.html b/docs/build/function_resume/rules.html new file mode 100644 index 0000000..76edf86 --- /dev/null +++ b/docs/build/function_resume/rules.html @@ -0,0 +1,824 @@ + + + + + + + Fuzzy Rules Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fuzzy Rules Functions

+

This is a the source file that contains the Rule, RuleBase and MasterRuleBase classes to perform fuzzy inference.

+
+
+class ex_fuzzy.rules.MasterRuleBase(rule_base: list[ex_fuzzy.rules.RuleBase], consequent_names: Optional[list[str]] = None)[source]
+

Bases: object

+

This Class encompasses a list of rule bases where each one corresponds to a different class.

+
+
+add_rule(rule: ex_fuzzy.rules.RuleSimple, consequent: int) None[source]
+

Adds a rule to the rule base of the given consequent.

+
+
Parameters
+
    +
  • rule – rule to add.

  • +
  • consequent – index of the rule base to add the rule.

  • +
+
+
+
+ +
+
+add_rule_base(rule_base: ex_fuzzy.rules.RuleBase) None[source]
+

Adds a rule base to the list of rule bases.

+
+
Parameters
+

rule_base – rule base to add.

+
+
+
+ +
+
+compute_firing_strenghts(X) numpy.array[source]
+

Computes the firing strength of each rule for each sample.

+
+
Parameters
+

X – array with the values of the inputs.

+
+
Returns
+

array with the firing strength of each rule for each sample.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+get_consequents() list[int][source]
+

Returns a list with the consequents of each rule base.

+
+
Returns
+

list with the consequents of each rule base.

+
+
+
+ +
+
+get_rulebase_matrix() list[numpy.array][source]
+

Returns a list with the rulebases for each antecedent in matrix format.

+
+
Returns
+

list with the rulebases for each antecedent in matrix format.

+
+
+
+ +
+
+get_rulebases() list[ex_fuzzy.rules.RuleBase][source]
+

Returns a list with all the rules.

+
+
Returns
+

list

+
+
+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns a list with all the rules.

+
+
Returns
+

list with all the rules.

+
+
+
+ +
+
+get_scores() numpy.array[source]
+

Returns the dominance score for each rule in all the rulebases.

+
+
Returns
+

array with the dominance score for each rule in all the rulebases.

+
+
+
+ +
+
+print_rules(return_rules=False) None[source]
+

Print all the rules for all the consequents.

+
+
Parameters
+

autoprint – if True, the rules are printed. If False, the rules are returned as a string.

+
+
+
+ +
+
+purge_rules(tolerance=0.001) None[source]
+

Delete the roles with a dominance score lower than the tolerance.

+
+
Parameters
+

tolerance – tolerance to delete the rules.

+
+
+
+ +
+
+rename_cons(consequent_names: list[str]) None[source]
+

Renames the consequents of the rule base.

+
+ +
+
+winning_rule_predict(X: numpy.array) numpy.array[source]
+

Returns the winning rule for each sample. Takes into account dominance scores if already computed.

+
+
Parameters
+

X – array with the values of the inputs.

+
+
Returns
+

array with the winning rule for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.Rule(antecedents: list[ex_fuzzy.fuzzy_sets.FS], consequent: ex_fuzzy.fuzzy_sets.FS)[source]
+

Bases: object

+

Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself.

+
+
+consequent_centroid() numpy.array[source]
+

Returns the centroid of the consequent using a Karnik and Mendel algorithm.

+
+ +
+
+membership(x: numpy.array, tnorm=<function _myprod>) numpy.array[source]
+

Computes the membership of one input to the antecedents of the rule.

+
+
Parameters
+
    +
  • x – input to compute the membership.

  • +
  • tnorm – t-norm to use in the inference process.

  • +
+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBase(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: typing.Optional[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, tnorm=<function prod>)[source]
+

Bases: object

+

Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study) +Default class supports iv fs fs.

+
+
+add_rule(new_rule: ex_fuzzy.rules.RuleSimple)[source]
+

Adds a new rule to the rulebase. +:param new_rule: rule to add.

+
+ +
+
+add_rules(new_rules: list[ex_fuzzy.rules.RuleSimple])[source]
+

Adds a list of new rules to the rulebase.

+
+
Parameters
+

new_rules – list of rules to add.

+
+
+
+ +
+
+compute_antecedents_memberships(x: numpy.array) list[dict][source]
+

Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable. +x must be a vector (only one sample)

+
+
Parameters
+

x – vector with the values of the inputs.

+
+
+
+ +
+
+compute_rule_antecedent_memberships(x: numpy.array, scaled=True) numpy.array[source]
+

Computes the antecedent truth value of an input array.

+

Return an array in shape samples x rules (x 2) (last is iv dimension)

+
+
Parameters
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled according to their sums for each sample.

  • +
+
+
Returns
+

array with the memberships of the antecedents for each rule.

+
+
+
+ +
+
+abstract forward(x: numpy.array) numpy.array[source]
+

Computes the deffuzified output of the fl inference system.

+

Return a vector of size (samples, )

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the deffuzified output.

+
+
+
+ +
+
+abstract fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the type of fuzzy set used in the RuleBase.

+
+
+
+ +
+
+get_rulebase_matrix()[source]
+

Returns a matrix with the antecedents values for each rule.

+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns the list of rules in the rulebase.

+
+ +
+
+get_scores()[source]
+

Returns an array with the dominance score for each rule. +(Must been already computed by an evalRule object)

+
+ +
+
+abstract inference(x: numpy.array) numpy.array[source]
+

Computes the fuzzy output of the fl inference system.

+

Return an array in shape samples x 2 (last is iv dimension)

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the memberships of the consequents for each rule.

+
+
+
+ +
+
+print_rules(return_rules: bool = False) None[source]
+

Print the rules from the rule base.

+
+ +
+
+prune_bad_rules(tolerance=0.01) None[source]
+

Delete the rules from the rule base that do not have a dominance score superior to the threshold.

+
+
Parameters
+

tolerance – threshold for the dominance score.

+
+
+
+ +
+
+remove_rule(ix: int) None[source]
+

Removes the rule in the given index. +:param ix: index of the rule to remove.

+
+ +
+
+remove_rules(delete_list: list[int]) None[source]
+

Removes the rules in the given list of indexes.

+
+
Parameters
+

delete_list – list of indexes of the rules to remove.

+
+
+
+ +
+
+scores() numpy.array[source]
+

Returns the dominance score for each rule.

+
+
Returns
+

array with the dominance score for each rule.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseGT2(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: typing.Optional[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, tnorm=<function _myprod>)[source]
+

Bases: ex_fuzzy.rules.RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports gt2 fs. (ONLY FOR CLASSIFICATION PROBLEMS)

+
+
+alpha_compute_rule_antecedent_memberships(x: numpy.array, scaled=True) numpy.array[source]
+

Computes the membership for the antecedents for all the alpha cuts.

+
+
Parameters
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled to sum 1 in each sample.

  • +
+
+
Returns
+

array with the memberships of the antecedents for each sample.

+
+
+
+ +
+
+compute_rule_antecedent_memberships(x: numpy.array, scaled=True) numpy.array[source]
+

Computes the membership for the antecedents performing the alpha_cut reduction.

+
+
Parameters
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled to sum 1 in each sample.

  • +
+
+
+
+ +
+
+forward(x: numpy.array) numpy.array[source]
+

Computes the deffuzified output of the t2 inference system.

+

Return a vector of size (samples, )

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: numpy.array) numpy.array[source]
+

Computes the output of the gt2 inference system.

+

Return an array in shape samples x alpha_cuts

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseT1(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: typing.Optional[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, tnorm=<function _myprod>)[source]
+

Bases: ex_fuzzy.rules.RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports t1 fs.

+
+
+forward(x: numpy.array) numpy.array[source]
+

Same as inference() in the t1 case.

+

Return a vector of size (samples, )

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: numpy.array) numpy.array[source]
+

Computes the output of the t1 inference system.

+

Return an array in shape samples.

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the output of the inference system for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseT2(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: typing.Optional[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, tnorm=<function _myprod>)[source]
+

Bases: ex_fuzzy.rules.RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports iv approximation for t2 fs.

+
+
+forward(x: numpy.array) numpy.array[source]
+

Computes the deffuzified output of the t2 inference system.

+

Return a vector of size (samples, )

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: numpy.array) numpy.array[source]
+

Computes the iv output of the t2 inference system.

+

Return an array in shape samples x 2 (last is iv dimension)

+
+
Parameters
+

x – array with the values of the inputs.

+
+
Returns
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleSimple(antecedents: list[int], consequent: int)[source]
+

Bases: object

+

Class designed to represent rules in its simplest form to optimize the computation in a rulebase.

+
+
It indicates the antecedent values using a vector coded in this way:

ith entry: -1 means this variable is not used. 0-N indicates that the variable linguistic used for the ith input is that one.

+
+
+
+ +
+
+ex_fuzzy.rules.list_rules_to_matrix(rule_list: list[ex_fuzzy.rules.RuleSimple]) numpy.array[source]
+

Returns a matrix out of the rule list.

+
+
Parameters
+

rule_list – list of rules.

+
+
Returns
+

matrix with the antecedents of the rules.

+
+
+
+ +
+
+class ex_fuzzy.rules.temporalMasterRuleBase(rule_base: list[ex_fuzzy.rules.MasterRuleBase], time_step_names: Optional[list[str]] = None)[source]
+

Bases: ex_fuzzy.rules.MasterRuleBase

+

This class is a temporal extension of the MasterRuleBase class. It includes a list of +rule bases for each time step.

+
+
+add_rule(rule: ex_fuzzy.rules.RuleSimple, consequent: int, time_step: int) None[source]
+

Adds a rule to the rule base of the given consequent.

+
+
Parameters
+
    +
  • rule – rule to add.

  • +
  • consequent – index of the rule base to add the rule.

  • +
  • time_step – time step of the rule base to add the rule.

  • +
+
+
+
+ +
+
+add_rule_base(rule_base: ex_fuzzy.rules.RuleBase, time: int) None[source]
+

Adds a rule base to the list of rule bases.

+
+
Parameters
+

rule_base – rule base to add.

+
+
+
+ +
+
+compute_firing_strenghts(X: numpy.array, time_moments: list[int]) numpy.array[source]
+

Computes the firing strength of each rule for each sample.

+
+
Parameters
+

X – array with the values of the inputs.

+
+
Returns
+

array with the firing strength of each rule for each sample.

+
+
+
+ +
+
+fuzzy_type() ex_fuzzy.fuzzy_sets.fuzzy_type[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+get_consequents() list[int][source]
+

Returns a list with the consequents of each rule base.

+
+
Returns
+

list with the consequents of each rule base.

+
+
+
+ +
+
+get_rulebase_matrix() list[numpy.array][source]
+

Returns a list with the rulebases for each antecedent in matrix format.

+
+
Returns
+

list with the rulebases for each antecedent in matrix format.

+
+
+
+ +
+
+get_rulebases() list[ex_fuzzy.rules.RuleBase][source]
+

Returns a list with all the rules.

+
+
Returns
+

list

+
+
+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns a list with all the rules.

+
+
Returns
+

list with all the rules.

+
+
+
+ +
+
+get_scores() numpy.array[source]
+

Returns the dominance score for each rule in all the rulebases.

+
+
Returns
+

array with the dominance score for each rule in all the rulebases.

+
+
+
+ +
+
+print_rules(return_rules=False) None[source]
+

Print all the rules for all the consequents.

+
+ +
+
+purge_rules(tolerance=0.001) None[source]
+

Delete the roles with a dominance score lower than the tolerance.

+
+
Parameters
+

tolerance – tolerance to delete the rules.

+
+
+
+ +
+
+winning_rule_predict(X: numpy.array, time_moments: int) numpy.array[source]
+

Returns the winning rule for each sample. Takes into account dominance scores if already computed.

+
+
Parameters
+

X – array with the values of the inputs.

+
+
Returns
+

array with the winning rule for each sample.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/function_resume/utils.html b/docs/build/function_resume/utils.html new file mode 100644 index 0000000..c0771cf --- /dev/null +++ b/docs/build/function_resume/utils.html @@ -0,0 +1,412 @@ + + + + + + + Partition utils — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Partition utils

+

Functions that are not fuzzy-specific, but util for some computations. +Dedicated mostly to compute quantiles for fuzzy partitions.

+
+
+ex_fuzzy.utils.assign_time(a: numpy.array, observations: list[numpy.array]) int[source]
+

Assigns a temporal moment to a set of observations.

+
+
Parameters
+
    +
  • a – array of boolean values.

  • +
  • observations – list of boolean arrays with the corresponding timestamps.

  • +
+
+
Returns
+

the index of the correspondent time moment for the a-th observation.

+
+
Raises
+

ValueError if a is not timestamped in any of the observation arrays.

+
+
+
+ +
+
+ex_fuzzy.utils.classify_temp(dates: pandas.core.frame.DataFrame, cutpoints: tuple[str, str], time: str) numpy.array[source]
+

Classifies a set of dates according to the temporal cutpoints. Uses {time} as a the time resolution. +Returns an array where true values are those values contained between those two date points.

+
+
Parameters
+
    +
  • dates – data observations to cut. The temporal

  • +
  • cutpoints – points to check.

  • +
  • time – time field to use as the criteria.

  • +
+
+
Returns
+

boolean array. True values are those contained between the cutpoints.

+
+
+
+ +
+
+ex_fuzzy.utils.construct_conditional_frequencies(X: numpy.array, discrete_time_labels: list[int], initial_ffss: list[ex_fuzzy.fuzzy_sets.FS])[source]
+

Computes the conditional temporal function for a set of fuzzy sets according to their variation in time.

+
+
Parameters
+
    +
  • X – numpy array, shape samples x features.

  • +
  • discrete_time_labels – discrete time labels.

  • +
  • initial_fs – initial fuzzy set list.

  • +
+
+
Returns
+

conditional frequencies. Array shape (time steps, initial fuzzy sets)

+
+
+
+ +
+
+ex_fuzzy.utils.construct_partitions(X, fz_type_studied) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Returns a list of linguistic variables according to the kind of fuzzy specified.

+
+
Parameters
+
    +
  • X – numpy array|pandas dataframe, shape samples x features.

  • +
  • fz_type_studied – fuzzy set type studied.

  • +
+
+
+
+ +
+
+ex_fuzzy.utils.create_multi_tempVariables(X_train: numpy.array, time_moments: numpy.array, fuzzy_type: ex_fuzzy.fuzzy_sets.fuzzy_type) list[list[ex_fuzzy.fuzzy_sets.temporalFS]][source]
+

Creates a of list of lists of temporal fuzzy variables. Each corresponds to a fuzzy partition in a different moment in time. +(So, instead of having one vl for all time moments, you have one different for each time moment that represents the same idea)

+
+
Parameters
+
    +
  • X_train – numpy array, shape samples x features.

  • +
  • time_moments – time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation.

  • +
  • precomputed_partitions – precomputed partitions for each feature.

  • +
+
+
Returns
+

list of lists of temporal fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.create_tempVariables(X_train: numpy.array, time_moments: numpy.array, precomputed_partitions: list[ex_fuzzy.fuzzy_sets.fuzzyVariable]) list[ex_fuzzy.fuzzy_sets.temporalFS][source]
+

Creates a list of temporal fuzzy variables.

+
+
Parameters
+
    +
  • X_train – numpy array, shape samples x features.

  • +
  • time_moments – time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation.

  • +
  • precomputed_partitions – precomputed partitions for each feature.

  • +
+
+
Returns
+

list of temporal fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.fixed_quantile_compute(x: numpy.array) list[float][source]
+

Computes a series of quantiles for each feature in numpy array. +Quantiles: [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1]

+
+
Parameters
+

x – array samples x features

+
+
Returns
+

list of quantiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.gt2_fuzzy_partitions_dataset(x0: numpy.array, resolution_exp: int = 1) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables using gt2 fuzzy sets. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters
+
    +
  • x – numpy array|pandas dataframe, shape samples x features.

  • +
  • resolution_exp – exponent of the resolution of the partition. Default is -2, which means 0.01. (Number of significant decimals)

  • +
+
+
Returns
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.partition3_quantile_compute(x: numpy.array) list[float][source]
+

Computes a series of quantiles partitioning the variable in 3 cases.

+

Quantiles: [0.00, 0.20, 0.50, 0.80, 1.00]

+
+
Parameters
+

x – array samples x features

+
+
Returns
+

list of quantiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.quartile_compute(x: numpy.array) list[float][source]
+

Computes the quartiles for each feature.

+
+
Parameters
+

x – array samples x features

+
+
Returns
+

list of quartiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.t1_fuzzy_partitions_dataset(x0: numpy.array) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters
+

x – numpy array|pandas dataframe, shape samples x features.

+
+
Returns
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.t1_simple_partition(x: numpy.array) numpy.array[source]
+

Partitions the fuzzy variable in four trapezoidal memberships.

+
+
Parameters
+

x – numpy array, vector of shape (samples, ).

+
+
Returns
+

numpy array, vector of shape (variables, 4, 4).

+
+
+
+ +
+
+ex_fuzzy.utils.t1_three_partition(x: numpy.array) numpy.array[source]
+

Partitions the fuzzy variable in four trapezoidal memberships.

+
+
Parameters
+

x – numpy array, vector of shape (samples, ).

+
+
Returns
+

numpy array, vector of shape (variables, 3, 4).

+
+
+
+ +
+
+ex_fuzzy.utils.t2_fuzzy_partitions_dataset(x0: numpy.array) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables using iv fuzzy sets. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters
+

x – numpy array|pandas dataframe, shape samples x features.

+
+
Returns
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.t2_simple_partition(x: numpy.array) numpy.array[source]
+

Partitions the fuzzy variable in three trapezoidal memberships.

+
+
Parameters
+

x – numpy array, vector of shape (samples, ).

+
+
Returns
+

numpy array, vector of shape (variables, 3, 4, 2).

+
+
+
+ +
+
+ex_fuzzy.utils.temporal_assemble(X: numpy.array, y: numpy.array, temporal_moments: list[numpy.array])[source]
+

Assembles the data in the temporal moments in order to have partitions with balanced time moments in each one.

+
+
Parameters
+
    +
  • X – data observations.

  • +
  • y – labels.

  • +
  • temporal_moments – list of boolean arrays. True values are those contained between the cutpoints in each moment.

  • +
+
+
Returns
+

tuple of lists of data and labels for each temporal moment. +First tuple is: X_train, X_test, y_train, y_test +Second tuple is: train temporal moments, test temporal moments.

+
+
+
+ +
+
+ex_fuzzy.utils.temporal_cuts(X: pandas.core.frame.DataFrame, cutpoints: list[tuple[str, str]], time_resolution: str = 'hour') list[numpy.array][source]
+

Returns a list of boolean indexes for each temporal moment. Performs the cuts between time steps using the cutpoints list.

+
+
Parameters
+
    +
  • X – data observations to cut in temrporal moments.

  • +
  • temporal_moments – list of temporal moments to cut.

  • +
  • cutpoints – list of tuples with the cutpoints for each temporal moment.

  • +
  • time_resolution – time field to use as the criteria.

  • +
+
+
Returns
+

list of boolean arrays. True values are those contained between the cutpoints in each moment.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/genindex.html b/docs/build/genindex.html new file mode 100644 index 0000000..cbce1cd --- /dev/null +++ b/docs/build/genindex.html @@ -0,0 +1,672 @@ + + + + + + Index — Ex-Fuzzy documentation + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ A + | C + | D + | E + | F + | G + | I + | L + | M + | N + | P + | Q + | R + | S + | T + | W + | Y + +
+

A

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
    +
  • + ex_fuzzy.evolutionary_fit + +
  • +
  • + ex_fuzzy.fuzzy_sets + +
  • +
  • + ex_fuzzy.persistence + +
  • +
  • + ex_fuzzy.rules + +
  • +
  • + ex_fuzzy.utils + +
  • +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

I

+ + + +
+ +

L

+ + + +
+ +

M

+ + +
+ +

N

+ + +
+ +

P

+ + + +
+ +

Q

+ + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

W

+ + +
+ +

Y

+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/gt2.html b/docs/build/gt2.html new file mode 100644 index 0000000..a979ed3 --- /dev/null +++ b/docs/build/gt2.html @@ -0,0 +1,132 @@ + + + + + + + General Type 2 — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

General Type 2

+

Although General Type 2 Fuzzy sets are fully supported, they present a series of additional considerations when used by default:

+
    +
  • The resolution of the primary domain function is always capped at 4 significant decimals.

  • +
  • When the domain of the secondary function are real numbers, precision is capped at 4 significant decimals.

  • +
+

We believe that this precision can be enough for most applications, but in case it needs to be changed, it is enough to change the fs.gt2.MAX_RES_SUPPORT constant to the desired number before instantiating the GT2 fuzzy set.

+

Computing with the GT2 is more costly than the rest of the sets. Specially, computing the GT2 fuzzy partitions, which are also notably more complex than in the rest of the fuzzy sets. +Essentially, a GT2 fuzzy partition is a dictionary where each value in the dictionary maps a value in the secondary domain to a fuzzy set. +When a new value needs to be computed, the closest known value in the secondary membership to the new one is used.

+

As an example, the function utils.gt2_fuzzy_partitions_dataset() returns a fuzzy partition using GT2 in the following manner:

+
    +
  1. Computes a IV partition for all the variables.

  2. +
  3. Discretizes the domain of the secondary membership to an arbitrary precision.

  4. +
  5. In each of the discretized points, computes a FS using as parameters of the trapezoid function the lower and upper memberships and the central point of them. This results in a triangle for each FS.

  6. +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/.buildinfo b/docs/build/html/.buildinfo new file mode 100644 index 0000000..1ea0ddd --- /dev/null +++ b/docs/build/html/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. +config: 7184ad333879fb5e4f199b3de50a2caf +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/build/html/_images/ejemplo_t1.png b/docs/build/html/_images/ejemplo_t1.png new file mode 100644 index 0000000..50e1962 Binary files /dev/null and b/docs/build/html/_images/ejemplo_t1.png differ diff --git a/docs/build/html/_images/ejemplo_t2.png b/docs/build/html/_images/ejemplo_t2.png new file mode 100644 index 0000000..e2b2f98 Binary files /dev/null and b/docs/build/html/_images/ejemplo_t2.png differ diff --git a/docs/build/html/_images/example_gt2.png b/docs/build/html/_images/example_gt2.png new file mode 100644 index 0000000..fcd427d Binary files /dev/null and b/docs/build/html/_images/example_gt2.png differ diff --git a/docs/build/html/_images/red_fuzzy.png b/docs/build/html/_images/red_fuzzy.png new file mode 100644 index 0000000..f69b9e2 Binary files /dev/null and b/docs/build/html/_images/red_fuzzy.png differ diff --git a/docs/build/html/_modules/ex_fuzzy/centroid.html b/docs/build/html/_modules/ex_fuzzy/centroid.html new file mode 100644 index 0000000..02b7bf0 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/centroid.html @@ -0,0 +1,306 @@ + + + + + + ex_fuzzy.centroid — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.centroid

+# -*- coding: utf-8 -*-
+"""
+This is the source file that contains functions to compute centroids for the case of IV fuzzy sets,
+which are commonly used when using the IV-T2 fuzzy sets.
+"""
+import numpy as np
+
+
+
[docs]def center_of_masses(z: np.array, w: np.array) -> np.array: + ''' + Computes the ponderated centroid with normalized weighting. + + :param z: Vector of the referencial values. + :param w: Vector of the fuzzy memberships. + :return: The ponderated sum. + ''' + return z @ w / np.sum(w)
+ + +
[docs]def compute_centroid_t2_l(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = center_of_masses(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + # k_vector = np.argwhere((z - yhat) > 0) + # k = k_vector[0][0] + 1 + w[0:k] = memberships[:, 1][:k] + w[k:] = memberships[:, 0][k:] + + yhat_2 = yhat + yhat = center_of_masses(z, w) + + return yhat
+ + +
[docs]def compute_centroid_t2_r(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The lowest membership of the centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = center_of_masses(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + w[0:k+1] = memberships[:, 0][:k+1] + w[k+1:] = memberships[:, 1][k+1:] + + yhat_2 = yhat + yhat = center_of_masses(z, w) + + return yhat
+ + +
[docs]def consequent_centroid_r(antecedent_memberships: np.array, centroids_r: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set + using the centroids of the consequents and the antecedents memeberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + yhat = center_of_masses(centroids_r, initial_f) + yhat2 = None + + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_r) >= 0)[-1][0] + r_R = min(len(centroids_r)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_left[0:r_R+1] + new_memberships[r_R+1:] = memberships_right[r_R+1:] + + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = center_of_masses(centroids_r, new_memberships) + + return yhat2
+ + +
[docs]def consequent_centroid_l(antecedent_memberships: np.array, centroids_l: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the left component of a centroid of an IV fuzzy set + using the centroids of the consequents and the antecedents memeberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + # (memberships_right * centroids_r) / np.sum(memberships_right) + yhat = center_of_masses(centroids_l, initial_f) + yhat2 = -100 + + #R = np.where(yhat - centroids_r)[0] + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_l) >= 0)[-1][0] + r_R = min(len(centroids_l)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_right[0:r_R+1] + new_memberships[r_R+1:] = memberships_left[r_R+1:] + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = center_of_masses(centroids_l, new_memberships) + + return yhat2
+ + +
[docs]def compute_centroid_iv(z: np.array, memberships: np.array) -> np.array: + ''' + Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The centroid. + ''' + res = np.zeros((2,)) + res[0] = compute_centroid_t2_l(z, memberships) + res[1] = compute_centroid_t2_r(z, memberships) + return res
+ + +
[docs]def consequent_centroid(antecedent_memberships: np.array, centroids: np.array) -> np.array: + ''' + Computes Karnik and Mendel algorithm to find the centroid of a consequent iv fuzzy set given the centroids of the consequents + and the antecedents memberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids: M x 2 matrix. M rules and iv dimension (2). Vector of centroids. + :return: The centroid. + ''' + centroids_l = centroids[:, 0] + centroids_r = centroids[:, 1] + res = np.zeros((2,)) + + res[0] = consequent_centroid_l(antecedent_memberships, centroids_l) + res[1] = consequent_centroid_r(antecedent_memberships, centroids_r) + + return res
+ + + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/classifiers.html b/docs/build/html/_modules/ex_fuzzy/classifiers.html new file mode 100644 index 0000000..06c3412 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/classifiers.html @@ -0,0 +1,323 @@ + + + + + + ex_fuzzy.classifiers — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.classifiers

+'''
+Module that contains classifiers that uses two step genetic optimization and rule mining based on the support of the candidate rules. 
+
+'''
+
+import numpy as np
+from sklearn.base import ClassifierMixin
+
+try:
+    from . import fuzzy_sets as fs
+    from . import evolutionary_fit as evf
+    from . import rule_mining as rm
+    from . import utils
+    from . import maintenance as mnt
+except:
+    import fuzzy_sets as fs
+    import evolutionary_fit as evf
+    import rule_mining as rm
+    import utils
+    import maintenance as mnt
+
+
+
[docs]class RuleMineClassifier(ClassifierMixin): + """A classifier that works by mining a set of candidate rules with a minimum support, confidence and lift, and then using a genetic algorithm that chooses + the optimal combination of those rules.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the support/dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param runner: number of threads to use. + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['plot_graph'] += 1 + + self.nAnts = nAnts + self.fl_classifier = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + ''' + fuzzy_vars = utils.construct_partitions(X, self.fuzzy_type) + candidate_rules = rm.multiclass_mine_rulebase(X, y, fuzzy_vars, self.tolerance, max_depth=self.nAnts) + self.fl_classifier.fit(X, y, checkpoints=0, candidate_rules=candidate_rules, n_gen=n_gen, pop_size=pop_size)
+ + +
[docs] def predict(self, X: np.array) -> np.array: + ''' + Predict for each sample the corresponding class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier.predict(X) + + return y_pred
+ + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier
+ + + +
[docs]class FuzzyRulesClassifier(ClassifierMixin): + """A classifier that works by performing a double optimization process. First, it creates a candidate rule base using genetic optimization + and then uses it as a basis to obtain a better one that satisfies the constrain of antecedents and number of rules.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param runner: number of threads to use. + :param expansion_factor: if > 1, it will compute inthe first optimization process n times the nRules parameters. (So that the search space for the second step is bigger) + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1 + + + self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* 1, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + :param n_gen: number of generations to compute in the genetic optimization. + :param pop_size: number of subjects per generation. + :param checkpoints: if bigger than 0, will save the best subject per x generations in a text file. + :param n_runner: number of threds to use. + ''' + self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints) + self.phase1_rules = self.fl_classifier1.rule_base + self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner)
+ + +
[docs] def predict(self, X: np.array) -> np.array: + ''' + Predcit for each sample the correspondent class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier2.predict(X) + + return y_pred
+ + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier2
+ + +
[docs]class RuleFineTuneClassifier(ClassifierMixin): + """A classifier that works by mining a set of candidate rules with a minimum support and then uses a two step genetic optimization that chooses + the optimal combination of those rules and fine tunes them.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['double_go'] += 1 + mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1 + + self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* expansion_factor, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + :param n_gen: number of generations to compute in the genetic optimization. + :param pop_size: number of subjects per generation. + :param checkpoints: if bigger than 0, will save the best subject per x generations in a text file. + :param n_runner: number of threds to use. + ''' + candidate_rules = rm.multiclass_mine_rulebase(X, y, self.fl_classifier1.lvs, self.tolerance) + + self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints, candidate_rules=candidate_rules) + self.phase1_rules = self.fl_classifier1.rule_base + self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner)
+ + +
[docs] def predict(self, X: np.array) -> np.array: + ''' + Predcit for each sample the correspondent class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier.predict(X) + + return y_pred
+ + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier2
+
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/cognitive_maps.html b/docs/build/html/_modules/ex_fuzzy/cognitive_maps.html new file mode 100644 index 0000000..e152fb3 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/cognitive_maps.html @@ -0,0 +1,331 @@ + + + + + + ex_fuzzy.cognitive_maps — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.cognitive_maps

+from __future__ import annotations
+'''
+Module to use fuzzy cognitive maps.
+
+The module contains the class FuzzyCognitiveMap, which is used to create and
+use fuzzy cognitive maps. You can also plot them, or simulate the dynamics of
+the FCM.
+
+For the original papers about FCM, see the works by Bart Kosko.
+
+'''
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+try:
+    from . import maintenance as mnt
+except ImportError:
+
+    import maintenance as mnt
+
+
+def _threshold_modules(connections: np.array | pd.DataFrame, threshold) -> np.array | pd.DataFrame:
+    '''Thresholds the connections matrix to the {-1, 0, 1} values.'''
+    return np.abs(connections) > threshold * np.sign(connections)
+
+
+def __look_periods(states: list[np.array], min_period_len=2) -> list[np.array]:
+    '''Looks for periods in the states list. Returns the period if found, None otherwise.'''
+    max_period_len = int(len(states) / 2)
+
+    for period_len in np.arange(max_period_len, min_period_len, -1):
+
+        for i in range(len(states)):
+            candidate = states[i:i+period_len]
+            next_candidate = states[i+period_len:i+period_len*2]
+            if len(next_candidate) < min_period_len:
+                break
+            if candidate != next_candidate:
+                break
+        
+        return candidate
+
+
+    return None
+
+
+def __look_attractors(states: list[np.array]) -> [bool, np.array]:
+    '''Checks if all the states in the list are the same'''
+    attractors = []
+    for state in states:
+        if not state in attractors:
+            attractors.append(state)
+        else:
+            return False, []
+    
+    return True, attractors[0]
+    
+
+
[docs]def look_pattern_states(fcm: FuzzyCognitiveMap, sim_steps: int, pattern_len: 50, max_period_size: 50) -> [np.array]: + '''Looks for the pattern states of the FCM when simulation is prolongued. + + + :param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. + :param max_steps: int. The maximum number of steps to look for the attractor states. + :param random_inits : int + :returns: list of np.array. The attractor states found. None if none were found + ''' + for _ in range(sim_steps): + state = fcm.step() + + steps = [] + for _ in range(pattern_len): + state = fcm.step() + steps.append(state) + + satisfactory, period = __look_attractors(steps) + if not satisfactory: + period = __look_periods(steps, min_period_len=2) + + return period
+ + +
[docs]def study_attractors_FCM(fcm: FuzzyCognitiveMap, max_steps: int, random_inits: int=10) -> [np.array]: + '''Looks for the attractor states of the FCM when simulation is prolongued. + + + :param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. + :param max_steps: int. The maximum number of steps to look for the attractor states. + :param random_inits : int + :returns: list of np.array. The attractor states found. None if none were found + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_report'] += 1 + + attractors = {} + gen_random_state = lambda : np.random.randint(0, 2, fcm.connections.shape[0]) + for _ in range(random_inits): + init_state = gen_random_state() + fcm.set_state(init_state) + attractors[init_state] = look_pattern_states(fcm, max_steps) + + return attractors
+ + +
[docs]def attractors_report(attractors: dict[np.array, np.array]) -> None: + ''' + Prints a report of the attractors found. + + :param attractors: dict[np.array, np.array]. The attractors found. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_report'] += 1 + pattern_dict = {} + + for _, attractor in attractors.items(): + if attractor is None: + pattern_dict['Chaotic'] = pattern_dict.get('Chaotic', 0) + 1 / len(attractors) + else: + pattern_dict[str(attractor)] = pattern_dict.get(str(attractor), 0) + 1 / len(attractors) + + state_dict = {} + list_states = [] + for _, attractor in attractors.items(): + if attractor is not None: + for state in attractor: + list_states += [str(state)] + + for state in list_states: + state_dict[state] = state_dict.get(state, 0) + 1 / len(list_states) + + return pattern_dict, state_dict
+ + +class FuzzyCognitiveMap: + + def __init__(self, connections: np.array | pd.DataFrame, threshold:int=0.5) -> None: + ''' + Creates a fuzzy cognitive map. + + + :param connections: np.array | pd.DataFrame. A square matrix with the connections between the concepts. + :param threshold: int, optional. When simulating steps the state + will be trimmed using these threhold into the {0, 1, -1} values. + The default is 0.5. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_create'] += 1 + + self.connections = connections + self.state = np.zeros(connections.shape[0]) + self.threshold = threshold + + + def var_names(self) -> list[str]: + '''Returns the names of the variables.''' + try: + return list(self.connections.columns) + except AttributeError: + return None + + + def step(self) -> np.array | pd.DataFrame: + '''Performs a step in the FCM given the actual state.''' + self.state = _threshold_modules(self.state @ self.connections, self.threshold) + + if isinstance(self.state, pd.DataFrame): + return pd.DataFrame(self.state, columns=self.var_names()) + else: + return self.state + + + def simulate(self, steps: int) -> np.array | pd.DataFrame: + ''' + Simulates the FCM for a number of steps. + + :param steps: int. The number of steps to simulate. + ''' + for _ in range(steps): + fstep = self.step() + + return fstep + + + def add(self, other: FuzzyCognitiveMap) -> None: + '''Adds the connections of other FCM to the actual FCM.''' + self.connections = self.connections + other.connections + + + def set_state(self, state: np.array | pd.DataFrame) -> None: + '''Sets the state of the FCM.''' + try: + self.state = state.values + except AttributeError: + self.state = state + + + def set_and_step(self, state: np.array | pd.DataFrame) -> np.array | pd.DataFrame: + '''Sets the state of the FCM and performs a step.''' + self.set_state(state) + return self.step() + + + def set_and_simulate(self, state: np.array | pd.DataFrame, steps: int) -> np.array | pd.DataFrame: + '''Sets the state of the FCM and performs a simulation.''' + self.set_state(state) + return self.simulate(steps) + + + def clear_state(self) -> None: + '''Clears the state of the FCM.''' + self.state = np.zeros(self.connections.shape[0]) + + + def __add__(self, other: FuzzyCognitiveMap) -> FuzzyCognitiveMap: + '''Creates a new FCM that is the addition of the two different connection matrix.''' + return FuzzyCognitiveMap(self.connections + other.connections) +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/eval_rules.html b/docs/build/html/_modules/ex_fuzzy/eval_rules.html new file mode 100644 index 0000000..50dddfd --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/eval_rules.html @@ -0,0 +1,511 @@ + + + + + + ex_fuzzy.eval_rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.eval_rules

+"""
+This file contains the classes to perform rule classification evaluation.
+
+"""
+import numpy as np
+from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix
+
+try:
+    from . import rules
+    from . import fuzzy_sets as fs
+except ImportError:
+    import rules
+    import fuzzy_sets as fs
+
+
+
[docs]class evalRuleBase(): + ''' + Class to evaluate a set of rules given a evaluation dataset. + ''' + + def __init__(self, mrule_base: rules.MasterRuleBase, X: np.array, y: np.array, time_moments: np.array=None) -> None: + ''' + Creates the object with the rulebase to evaluate and the data to use in the evaluation. + + :param mrule_base: The rule base to evaluate. + :param X: array shape samples x features. The data to evaluate the rule base. + :param y: array shape samples x 1. The labels of the data. + :param time_moments: array shape samples x 1. The time moments of the samples. (Only for temporal rule bases) + :return: None + ''' + self.mrule_base = mrule_base + self.X = X + self.y = y + self.time_moments = time_moments + + self.consequents = mrule_base.get_consequents() + + +
[docs] def compute_pattern_support(self) -> np.array: + ''' + Computes the pattern support for each of the rules for the given X. + Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, + dvided by their number. + + :return: array of shape rules x 2 + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + + if pattern_firing_strength[consequent_match].shape[0] > 0: + res[ix] = np.mean(pattern_firing_strength[consequent_match]) + + + return res
+ + +
[docs] def compute_aux_pattern_support(self) -> np.array: + ''' + Computes the pattern support for each of the rules for each of the classes for the given X. + Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, + dvided by their number. + + :return: array of shape rules x 2 + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + n_classes = len(np.unique(self.y)) + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), n_classes, )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), n_classes, 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), n_classes, 2)) + + for con_ix in range(n_classes): + for ix, pattern in enumerate(patterns): + consequent_match = self.y == con_ix + pattern_firing_strength = antecedent_memberships[:, ix] + + # / pattern_firing_strength.shape[0] + if pattern_firing_strength[consequent_match].shape[0] > 0: + res[ix, con_ix] = np.mean(pattern_firing_strength[consequent_match]) + else: + res[ix, con_ix] = pattern_firing_strength[consequent_match] + + return res
+ + + def _get_all_rules(self) -> list[rules.RuleSimple]: + ''' + Returns a list of all the rules in the master rule base. + + :return: list of rules. + ''' + res = [] + for jx in self.mrule_base.get_rules(): + res.append(jx) + + return res + + +
[docs] def compute_pattern_confidence(self) -> np.array: + ''' + Computes the pattern confidence for each of the rules for the given X. + Each pattern confidence is the normalized firing strength. + + :returns: array of shape 1 x rules + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + antecedent_consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + dem = np.sum(pattern_firing_strength) + if dem == 0: + res[ix] = 0 + else: + res[ix] = np.sum( + pattern_firing_strength[antecedent_consequent_match]) / dem + + return res
+ + +
[docs] def compute_aux_pattern_confidence(self) -> np.array: + ''' + Computes the pattern confidence for each of the rules for the given X. + Each pattern confidence is the normalized firing strength. + + :returns: array of shape rules x classes + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + n_classes = len(np.unique(self.y)) + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), n_classes, )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), n_classes, 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), n_classes, 2)) + + for consequent in range(n_classes): + for ix, pattern in enumerate(patterns): + antecedent_consequent_match = self.y == consequent + pattern_firing_strength = antecedent_memberships[:, ix] + dem = np.sum(pattern_firing_strength) + if dem == 0: + res[ix, consequent] = 0 + else: + res[ix, consequent] = np.sum( + pattern_firing_strength[antecedent_consequent_match]) / dem + + return res
+ + +
[docs] def dominance_scores(self) -> np.array: + ''' + Returns the dominance score of each pattern for each rule. + + :return: array of shape rules x 2 + ''' + return self.compute_pattern_confidence() * self.compute_pattern_support()
+ + +
[docs] def association_degree(self) -> np.array: + ''' + Returns the association degree of each rule for each sample. + + :return: vector of shape rules + ''' + firing_strengths = self.mrule_base.compute_firing_strenghts(self.X) + res = self.dominance_scores() * firing_strengths + + if (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + res = np.mean(res, axis=2) + + return res
+ + +
[docs] def aux_dominance_scores(self) -> np.array: + ''' + Returns the dominance score of each pattern for each rule. + + :return: array of shape rules x 2 + ''' + return self.compute_aux_pattern_confidence() * self.compute_aux_pattern_support()
+ + +
[docs] def add_rule_weights(self) -> None: + ''' + Add dominance score field to each of the rules present in the master Rule Base. + ''' + supports = self.compute_pattern_support() + confidences = self.compute_pattern_confidence() + scores = self.dominance_scores() + + aux_counter = 0 + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + rules[jx].score = scores[aux_counter] + rules[jx].support = supports[aux_counter] + rules[jx].confidence = confidences[aux_counter] + + aux_counter += 1
+ + +
[docs] def add_auxiliary_rule_weights(self) -> None: + ''' + Add dominance score field to each of the rules present in the master Rule Base for each consequent. + They are labeled as aux_score, aux_support and aux_confidence. (Because they are not the main rule weights) + ''' + supports = self.compute_aux_pattern_support() + confidences = self.compute_aux_pattern_confidence() + scores = self.aux_dominance_scores() + + aux_counter = 0 + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + rules[jx].aux_score = scores[aux_counter] + rules[jx].aux_support = supports[aux_counter] + rules[jx].aux_confidence = confidences[aux_counter] + + aux_counter += 1
+ + +
[docs] def add_classification_metrics(self, X: np.array=None, y: np.array=None) -> None: + ''' + Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores. + If X and y are None uses the train set. + + :param X: array of shape samples x features + :param y: array of shape samples + + ''' + if X is not None: + actual_X = X + actual_y = y + else: + actual_X = self.X + actual_y = self.y + + if not hasattr(self.mrule_base.get_rules()[0], 'score'): + self.add_rule_weights() + + if self.time_moments is None: + winning_rules = self.mrule_base._winning_rules(actual_X) + preds = self.mrule_base.winning_rule_predict(actual_X) + else: + winning_rules = self.mrule_base._winning_rules(actual_X, self.time_moments) + preds = self.mrule_base.winning_rule_predict(actual_X, self.time_moments) + + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + relevant_samples = winning_rules == jx + if np.sum(relevant_samples) > 0: + relevant_labels = actual_y[relevant_samples] + relevant_preds = preds[relevant_samples] + + rules[jx].accuracy = accuracy_score(relevant_labels, relevant_preds) + else: + rules[jx].accuracy = 0.0
+ + +
[docs] def classification_eval(self) -> float: + ''' + Returns the matthews correlation coefficient for a classification task using + the rules evaluated. + + :return: mattews correlation coefficient. (float in [-1, 1]) + ''' + from sklearn.metrics import matthews_corrcoef + self.add_rule_weights() + preds = self.mrule_base.winning_rule_predict(self.X) + + return matthews_corrcoef(self.y, preds)
+ + +
[docs] def size_antecedents_eval(self, tolerance=0.1) -> float: + ''' + Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents. + + 0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. + The more rules and antecedent per rules the lower this score is. + + :param tolerance: float in [0, 1]. The tolerance for the dominance score. Default 0.1 + :return: float in [0, 1] with the score. + ''' + possible_rule_size = 0 + effective_rule_size = 0 + + for rule_base in self.mrule_base.get_rulebases(): + if len(rule_base) > 0: + for rule in rule_base: + rscore = np.mean(rule.score) + if rscore > tolerance: + possible_rule_size += len(rule.antecedents) + # No antecedents for this rule + if sum(np.array(rule.antecedents) != -1) == 0: + effective_rule_size += len(rule.antecedents) + else: + effective_rule_size += sum( + np.array(rule.antecedents) != -1) + + else: + return 0.0 # If one consequent does not have rules, then we return 0.0 + + try: + rule_density = 1 - effective_rule_size / possible_rule_size # Antecedents used + except ZeroDivisionError: + rule_density = 0.0 + + return rule_density
+ + +
[docs] def effective_rulesize_eval(self, tolerance=0.1) -> float: + ''' + Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents. + + 0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. + The more rules and antecedent per rules the lower this score is. + + :param tolerance: float in [0, 1]. The tolerance for the dominance score. Default 0.1 + :return: float in [0, 1] with the score. + ''' + possible_rules = len(self.mrule_base.get_rules()) + effective_rules = 0 + + for rule_base in self.mrule_base.get_rulebases(): + if len(rule_base) > 0: + for rule in rule_base: + rscore = np.mean(rule.score) + if rscore > tolerance: + # No antecedents for this rule + if not np.all(np.equal(np.array(rule.antecedents), -1)): + effective_rules += 1 + + else: + return 0.0 # If one consequent does not have rules, then we return 0.0 + + try: + rule_density = effective_rules / possible_rules + except ZeroDivisionError: + rule_density = 0.0 + + return rule_density
+ + +
[docs] def add_full_evaluation(self): + ''' + Adds classification scores, both Dominance Scores and accuracy metrics, for each individual rule. + ''' + self.add_rule_weights() + self.add_classification_metrics()
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/eval_tools.html b/docs/build/html/_modules/ex_fuzzy/eval_tools.html new file mode 100644 index 0000000..b370c64 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/eval_tools.html @@ -0,0 +1,181 @@ + + + + + + ex_fuzzy.eval_tools — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.eval_tools

+"""
+Functions that contain some general functions to eval already fitted fuzzy rule based models.
+It can also be used to visualize rules and fuzzy partitions.
+"""
+import numpy as np
+import pandas as pd
+from sklearn.metrics import matthews_corrcoef
+
+try:
+      from . import evolutionary_fit as evf
+      from . import vis_rules
+except ImportError:
+      import evolutionary_fit as evf
+      import vis_rules
+
+
+
[docs]def eval_fuzzy_model(fl_classifier: evf.BaseFuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + # Get the unique classes from the classifier + unique_classes = fl_classifier.classes_ + # Convert the names from the labels to the corresponding class + y_train = np.array([list(unique_classes).index(str(y)) for y in y_train]) + y_test = np.array([list(unique_classes).index(str(y)) for y in y_test]) + + if print_accuracy: + print('------------') + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.predict(X_train))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.predict(X_test))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.predict(X_train)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.predict(X_test)))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier.rule_base, export_path='Demos') + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + + if print_rules: + print(res) + + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html b/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html new file mode 100644 index 0000000..ad88abe --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/evolutionary_fit.html @@ -0,0 +1,1001 @@ + + + + + + ex_fuzzy.evolutionary_fit — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.evolutionary_fit

+"""
+This is a the source file that contains the class to train/fit the rulebase using a genetic algorithm.
+
+"""
+import numpy as np
+import pandas as pd
+
+from sklearn.model_selection import StratifiedKFold
+from sklearn.metrics import matthews_corrcoef
+from sklearn.base import ClassifierMixin
+from pymoo.algorithms.soo.nonconvex.ga import GA
+from pymoo.core.problem import Problem
+from pymoo.optimize import minimize
+from pymoo.operators.sampling.rnd import IntegerRandomSampling
+from pymoo.operators.crossover.sbx import SBX
+from pymoo.operators.mutation.pm import PolynomialMutation
+from pymoo.core.variable import Integer
+from multiprocessing.pool import ThreadPool
+from pymoo.core.problem import StarmapParallelization
+
+try:
+    from . import fuzzy_sets as fs
+    from . import rules
+    from . import eval_rules as evr
+    from . import vis_rules
+    from . import maintenance as mnt
+except ImportError:
+    import fuzzy_sets as fs
+    import rules
+    import eval_rules as evr
+    import vis_rules
+    import maintenance as mnt
+
+
+
+
[docs]class BaseFuzzyRulesClassifier(ClassifierMixin): + ''' + Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_class: int=None, precomputed_rules: rules.MasterRuleBase =None, runner: int=1) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param precomputed_rules: MasterRuleBase object. If not None, the classifier will use the rules in the object and ignore the conflicting parameters. + :param runner: number of threads to use. If None (default) the classifier will use 1 thread. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['fit'] += 1 + + if precomputed_rules is not None: + self.nRules = len(precomputed_rules.get_rules()) + self.nAnts = len(precomputed_rules.get_rules()[0].antecedents) + self.n_class = len(precomputed_rules) + self.classes_ = precomputed_rules.consequent_names + self.rule_base = precomputed_rules + else: + self.nRules = nRules + self.nAnts = nAnts + + + self.custom_loss = None + self.verbose = verbose + self.tolerance = tolerance + self.classes_ = n_class + + if runner > 1: + pool = ThreadPool(runner) + self.thread_runner = StarmapParallelization(pool.starmap) + else: + self.thread_runner = None + + if linguistic_variables is not None: + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['precompute_labels'] += 1 + # If the linguistic variables are precomputed then we act accordingly + self.lvs = linguistic_variables + self.n_linguist_variables = len( + self.lvs[0].linguistic_variable_names()) + self.domain = None + self.fuzzy_type = self.lvs[0].fuzzy_type() + else: + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['opt_labels'] += 1 + + # If not, then we need the parameters sumistered by the user. + self.lvs = None + self.fuzzy_type = fuzzy_type + self.n_linguist_variables = n_linguist_variables + self.domain = domain + + +
[docs] def customized_loss(self, loss_function): + ''' + Function to customize the loss function used for the optimization. + + :param loss_function: function that takes as input the true labels and the predicted labels and returns a float. + :return: None + ''' + self.custom_loss = loss_function
+ + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=70, pop_size:int=30, checkpoints:int=10, candidate_rules:rules.MasterRuleBase=None, initial_rules:rules.MasterRuleBase=None, **kwargs): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :param checkpoints: integer. Number of checkpoints to save the best rulebase found so far. + :param candidate_rules: if these rules exist, the optimization process will choose the best rules from this set. If None (default) the rules will be generated from scratch. + :return: None. The classifier is fitted to the data. + ''' + if self.classes_ is None: + if isinstance(y, pd.Series): + self.classes_ = [str(aux) for aux in y.unique()] + # Convert the names in the label vector to integer classes + y = np.array(y.replace(self.classes_, np.arange(len(self.classes_)))) + else: + self.classes_ = [str(aux) for aux in np.unique(y)] + + if candidate_rules is None: + if initial_rules is not None: + self.fuzzy_type = initial_rules.fuzzy_type() + self.n_linguist_variables = initial_rules.n_linguist_variables() + self.domain = [fv.domain for fv in initial_rules[0].antecedents] + self.nRules = len(initial_rules.get_rules()) + self.nAnts = len(initial_rules.get_rules()[0].antecedents) + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, n_classes=len(np.unique(y)), + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, thread_runner=self.thread_runner) + else: + # If Fuzzy variables are already precomputed. + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, n_classes=len(np.unique(y)), + linguist_variables=self.lvs, domain=self.domain, tolerance=self.tolerance, thread_runner=self.thread_runner) + else: + self.fuzzy_type = candidate_rules.fuzzy_type() + self.n_linguist_variables = candidate_rules.n_linguist_variables() + problem = ExploreRuleBases(X, y, n_classes=len(np.unique(y)), cancidate_rules=candidate_rules, thread_runner=self.thread_runner, nRules=self.nRules) + + if self.custom_loss is not None: + problem.fitness_func = self.custom_loss + + if initial_rules is not None: + rules_gene = problem.encode_rulebase(initial_rules, self.lvs is None) + rules_gene = (np.ones((pop_size, len(rules_gene))) * rules_gene).astype(int) + else: + rules_gene = IntegerRandomSampling() + + algorithm = GA( + pop_size=pop_size, + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + sampling=rules_gene, + eliminate_duplicates=False) + + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, res.pop.get('F').mean(), res.pop.get('F').min())) + if k % checkpoints == 0: + with open("checkpoint_" + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_full_evaluation() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + rule_base.rename_cons(self.classes_) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + + + self.performance = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + self.rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + self.rule_base.rename_cons(self.classes_) + + self.eval_performance = evr.evalRuleBase( + self.rule_base, np.array(X), y) + + self.eval_performance.add_full_evaluation() + self.rename_fuzzy_variables() + self.eval_performance.add_classification_metrics() + self.rule_base.purge_rules(self.tolerance)
+ + +
[docs] def load_master_rule_base(self, rule_base: rules.MasterRuleBase) -> None: + ''' + Loads a master rule base to be used in the prediction process. + + :param rule_base: ruleBase object. + :return: None + ''' + self.rule_base = rule_base + self.nRules = len(rule_base.get_rules()) + self.nAnts = len(rule_base.get_rules()[0].antecedents) + self.n_class = len(rule_base)
+ + +
[docs] def forward(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a pandas dataframe + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X)
+ + +
[docs] def predict(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + return self.forward(X)
+ + +
[docs] def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules contained in the fitted rulebase. + ''' + return self.rule_base.print_rules(return_rules)
+ + +
[docs] def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv)
+ + +
[docs] def rename_fuzzy_variables(self) -> None: + ''' + Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process. + + :return: None. Names are sorted accorded to the central point of the fuzzy memberships. + ''' + + for ix in range(len(self.rule_base)): + fuzzy_variables = self.rule_base.rule_bases[ix].antecedents + + for jx, fv in enumerate(fuzzy_variables): + # I feel so extraordinary, lifes got a hold on me... + new_order_values = [] + possible_names = FitRuleBase.vl_names[self.n_linguist_variables] + + for zx, fuzzy_set in enumerate(fv.linguistic_variables): + studied_fz = fuzzy_set.type() + + if studied_fz == fs.FUZZY_SETS.temporal: + studied_fz = fuzzy_set.inside_type() + + if studied_fz == fs.FUZZY_SETS.t1: + f1 = np.mean( + fuzzy_set.membership_parameters[0] + fuzzy_set.membership_parameters[1]) + elif (studied_fz == fs.FUZZY_SETS.t2): + f1 = np.mean( + fuzzy_set.secondMF_upper[0] + fuzzy_set.secondMF_upper[1]) + elif studied_fz == fs.FUZZY_SETS.gt2: + sec_memberships = fuzzy_set.secondary_memberships.values() + f1 = float(list(fuzzy_set.secondary_memberships.keys())[np.argmax( + [fzm.membership_parameters[2] for ix, fzm in enumerate(sec_memberships)])]) + + new_order_values.append(f1) + + new_order = np.argsort(np.array(new_order_values)) + fuzzy_sets_vl = fv.linguistic_variables + + for jx, x in enumerate(new_order): + fuzzy_sets_vl[x].name = possible_names[jx]
+ + +
[docs] def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix()
+ + +
[docs]class ExploreRuleBases(Problem): + ''' + Class to model as pymoo problem the fitting of a rulebase to a set of data given a series of candidate rules for a classification problem using Evolutionary strategies + Supports type 1 and t2. + ''' + + def __init__(self, X: np.array, y: np.array, nRules: int, n_classes: int, cancidate_rules: rules.MasterRuleBase, thread_runner: StarmapParallelization=None, tolerance:float = 0.01) -> None: + ''' + Cosntructor method. Initializes the classifier with the number of antecedents, linguist variables and the kind of fuzzy set desired. + + :param X: np array or pandas dataframe samples x features. + :param y: np vector containing the target classes. vector sample + :param n_class: number of classes in the problem. If None (as default) it will be computed from the data. + :param cancidate_rules: MasterRuleBase object. If not None, the classifier will use the rules in the object and ignore the conflicting parameters. + ''' + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + self.tolerance = tolerance + self.fuzzy_type = cancidate_rules.fuzzy_type() + self.y = y + self.nCons = 1 # This is fixed to MISO rules. + self.n_classes = n_classes + self.candidate_rules = cancidate_rules + self.nRules = nRules + + self.vl_names = self.candidate_rules[0].antecedents[0].linguistic_variable_names() + self.fuzzy_type = self.candidate_rules[0].antecedents[0].fuzzy_type() + + self.min_bounds = np.min(self.X, axis=0) + self.max_bounds = np.max(self.X, axis=0) + + nTotalRules = len(self.candidate_rules.get_rules()) + # Each var is using or not a rule. + vars = {ix: Integer(bounds=[0, nTotalRules - 1]) for ix in range(self.nRules)} + varbound = np.array([[0, nTotalRules- 1]] * self.nRules) + + nVar = len(vars.keys()) + if thread_runner is not None: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1], + elementwise_runner=thread_runner) + else: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1]) + + + def _construct_ruleBase(self, x: np.array, fuzzy_type: fs.FUZZY_SETS) -> rules.MasterRuleBase: + ''' + Creates a valid rulebase from the given subject and the candidate rules. + + :param x: gen of a rulebase. type: dict. + + :return: a Master rulebase object. + ''' + x = x.astype(int) + # Get all rules and their consequents + diff_consequents = np.arange(len(self.candidate_rules)) + + # Choose the selected ones in the gen + total_rules = self.candidate_rules.get_rules() + chosen_rules = [total_rules[ix] for ix, val in enumerate(x)] + rule_consequents = sum([[ix] * len(rule) for ix, rule in enumerate(self.candidate_rules)], []) + chosen_rules_consequents = [rule_consequents[val] for ix, val in enumerate(x)] + # Create a rule base for each consequent with the selected rules + rule_list = [[] for _ in range(self.n_classes)] + rule_bases = [] + for ix, consequent in enumerate(diff_consequents): + for rx, rule in enumerate(chosen_rules): + if chosen_rules_consequents[rx] == consequent: + rule_list[ix].append(rule) + + if len(rule_list[ix]) > 0: + if fuzzy_type == fs.FUZZY_SETS.t1: + rule_base_cons = rules.RuleBaseT1( + self.candidate_rules[0].antecedents, rule_list[ix]) + elif fuzzy_type == fs.FUZZY_SETS.t2: + rule_base_cons = rules.RuleBaseT2( + self.candidate_rules[0].antecedents, rule_list[ix]) + elif fuzzy_type == fs.FUZZY_SETS.gt2: + rule_base_cons = rules.RuleBaseGT2( + self.candidate_rules[0].antecedents, rule_list[ix]) + + rule_bases.append(rule_base_cons) + + # Create the Master Rule Base object with the individual rule bases + newMasterRuleBase = rules.MasterRuleBase(rule_bases, diff_consequents) + + return newMasterRuleBase + + + def _evaluate(self, x: np.array, out: dict, *args, **kwargs): + ''' + :param x: array of train samples. x shape = features + those features are the parameters to optimize. + + :param out: dict where the F field is the fitness. It is used from the outside. + ''' + try: + ruleBase = self._construct_ruleBase(x, self.fuzzy_type) + + score = self.fitness_func(ruleBase, self.X, self.y, self.tolerance) + + + out["F"] = 1 - score + except rules.RuleError: + out["F"] = 1 + + +
[docs] def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.95, beta:float=0.025, gamma:float=0.025) -> float: + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_rule_weights() + + score_acc = ev_object.classification_eval() + score_rules_size = ev_object.size_antecedents_eval(tolerance) + score_nrules = ev_object.effective_rulesize_eval(tolerance) + + score = score_acc * alpha + score_rules_size * beta + score_nrules * gamma + + return score
+ + + +
[docs]class FitRuleBase(Problem): + ''' + Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies. + Supports type 1 and iv fs (iv-type 2) + ''' + + def _init_optimize_vl(self, fuzzy_type: fs.FUZZY_SETS, n_linguist_variables: int, domain: list[(float, float)] = None): + ''' + Inits the corresponding fields if no linguistic partitions were given. + + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + ''' + self.lvs = None + try: + self.vl_names = FitRuleBase.vl_names[n_linguist_variables] + except IndexError: + self.vl_names = [str(ix) for ix in range(n_linguist_variables)] + + self.fuzzy_type = fuzzy_type + self.n_lv_possible = n_linguist_variables + self.domain = domain + + + def _init_precomputed_vl(self, linguist_variables: list[fs.fuzzyVariable]): + ''' + Inits the corresponding fields if linguistic partitions for each variable are given. + + :param linguistic_variables: list of fuzzyVariables type. + ''' + self.lvs = linguist_variables + self.vl_names = self.lvs[0].linguistic_variable_names() + self.n_lv_possible = len(self.lvs[0]) + self.fuzzy_type = self.lvs[0].fs_type + self.domain = None + + vl_names = [ # Linguistic variable names preestated for some specific cases. + [], + [], + ['Low', 'High'], + ['Low', 'Medium', 'High'], + ['Low', 'Medium', 'High', 'Very High'], + ['Very Low', 'Low', 'Medium', 'High', 'Very High'] + ] + + def __init__(self, X: np.array, y: np.array, nRules: int, nAnts: int, n_classes: int, thread_runner: StarmapParallelization=None, **kwargs) -> None: + ''' + Cosntructor method. Initializes the classifier with the number of antecedents, linguist variables and the kind of fuzzy set desired. + + :param X: np array or pandas dataframe samples x features. + :param y: np vector containing the target classes. vector sample + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param n_class: number of classes in the problem. If None (as default) it will be computed from the data. + + kwargs: + :param linguistic_variables: list of linguistic variables precomputed. If given, the rest of kwargs is ignored. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param fuzzy_type: Define the fuzzy set or fuzzy set extension used as linguistic variable. + :param domain: list with the upper and lower domains of each input variable. If None (as default) it will stablish the empirical min/max as the limits. + ''' + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + try: + self.tolerance = kwargs['tolerance'] + except KeyError: + self.tolerance = 0.001 + + self.y = y + self.nRules = nRules + self.nAnts = nAnts + self.nCons = 1 # This is fixed to MISO rules. + + if n_classes is not None: + self.n_classes = n_classes + else: + self.n_classes = len(np.unique(y)) + + if 'linguist_variables' in kwargs.keys(): + self._init_precomputed_vl(kwargs['linguist_variables']) + else: + self._init_optimize_vl( + kwargs['fuzzy_type'], kwargs['n_linguist_variables']) + + if self.domain is None: + self.min_bounds = np.min(self.X, axis=0) + self.max_bounds = np.max(self.X, axis=0) + else: + self.min_bounds, self.max_bounds = self.domain + + self.antecedents_referencial = [np.linspace( + self.min_bounds[ix], self.max_bounds[ix], 100) for ix in range(self.X.shape[1])] + + possible_antecedent_bounds = np.array( + [[0, self.X.shape[1] - 1]] * self.nAnts * self.nRules) + vl_antecedent_bounds = np.array( + [[-1, self.n_lv_possible - 1]] * self.nAnts * self.nRules) # -1 means not caring + antecedent_bounds = np.concatenate( + (possible_antecedent_bounds, vl_antecedent_bounds)) + vars_antecedent = {ix: Integer( + bounds=antecedent_bounds[ix]) for ix in range(len(antecedent_bounds))} + aux_counter = len(vars_antecedent) + + if self.lvs is None: + self.feature_domain_bounds = np.array( + [[0, 99] for ix in range(self.X.shape[1])]) + size_multiplier = 4 if self.fuzzy_type == fs.FUZZY_SETS.t1 else 8 + membership_bounds = np.concatenate( + [self.feature_domain_bounds] * self.n_lv_possible * size_multiplier) + vars_memeberships = { + aux_counter + ix: Integer(bounds=membership_bounds[ix]) for ix in range(len(membership_bounds))} + aux_counter += len(vars_memeberships) + + final_consequent_bounds = np.array( + [[-1, self.n_classes - 1]] * self.nRules) + vars_consequent = {aux_counter + ix: Integer( + bounds=final_consequent_bounds[ix]) for ix in range(len(final_consequent_bounds))} + + if self.lvs is None: + vars = {key: val for d in [ + vars_antecedent, vars_memeberships, vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, membership_bounds, final_consequent_bounds), axis=0) + else: + vars = {key: val for d in [vars_antecedent, + vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, final_consequent_bounds), axis=0) + + nVar = len(varbound) + self.single_gen_size = nVar + + if thread_runner is not None: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1], + elementwise_runner=thread_runner) + else: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1]) + + +
[docs] def encode_rulebase(self, rule_base: rules.MasterRuleBase, optimize_lv: bool) -> np.array: + ''' + Given a rule base, constructs the corresponding gene associated with that rule base. + + GENE STRUCTURE + + First: antecedents chosen by each rule. Size: nAnts * nRules (index of the antecedent) + Second: Variable linguistics used. Size: nAnts * nRules + Third: Parameters for the fuzzy partitions of the chosen variables. Size: nAnts * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) + Four: Consequent classes. Size: nRules + + :param rule_base: rule base object. + :param optimize_lv: if True, the gene is prepared to optimize the membership functions. + :param antecedents_referencial: list of lists. Each list contains the referencial for each variable. Required only if optimize_lv is True. + :return: np array of size self.single_gen_size. + ''' + gene = np.zeros((self.single_gen_size,)) + + n_lv_possible = len(rule_base.rule_bases[0].antecedents[0].linguistic_variables) + fz_type = rule_base.fuzzy_type() + rule_consequents = rule_base.get_consequents() + nreal_rules = len(rule_consequents) + mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8 + + # Pointer to the fourth section of the gene: consequents + if optimize_lv: + # If lv memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + \ + len(rule_base.antecedents) * n_lv_possible * mf_size + else: + # If no memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + + # First and second sections of the gene: antecedents and linguistic variables + for i0, rule in enumerate(rule_base.get_rules()): # Reconstruct the rules + first_pointer = i0 * self.nAnts + second_pointer = (self.nRules * self.nAnts) + i0 * self.nAnts + + for ax, linguistic_variable in enumerate(rule.antecedents): + gene[first_pointer + ax] = ax + gene[second_pointer + ax] = linguistic_variable + + # Update the fourth section of the gene: consequents using the fourth pointer + gene[fourth_pointer + i0] = rule_consequents[i0] + + # Fill the rest of the rules with don't care values + nvoid_rules = self.nRules - nreal_rules + for vx in range(nvoid_rules): + first_pointer = nreal_rules * self.nAnts + vx * self.nAnts + second_pointer = (self.nRules * self.nAnts) + nreal_rules * self.nAnts + vx * self.nAnts + + for ax, linguistic_variable in enumerate(rule.antecedents): + gene[first_pointer + ax] = ax + gene[second_pointer + ax] = -1 + + # Update the fourth section of the gene: consequents using the fourth pointer + gene[fourth_pointer + nreal_rules + vx] = -1 + + if optimize_lv: + # If lv memberships are optimized. + third_pointer = 2 * self.nAnts * self.nRules + aux_pointer = 0 + for ix, fuzzy_variable in enumerate(rule_base.get_antecedents()): + for linguistic_variable in range(n_lv_possible): + fz_parameters = fuzzy_variable[linguistic_variable].membership_parameters + for jx, fz_parameter in enumerate(fz_parameters): + closest_idx = (np.abs(np.asarray(self.antecedents_referencial[ix]) - fz_parameter)).argmin() + gene[third_pointer + aux_pointer] = closest_idx + aux_pointer += 1 + + return np.array(list(map(int, gene)))
+ + + + def _construct_ruleBase(self, x: np.array, fz_type: fs.FUZZY_SETS, **kwargs) -> rules.MasterRuleBase: + ''' + Given a subject, it creates a rulebase according to its specification. + + :param x: gen of a rulebase. type: dict. + :param fz_type: a enum type. Check fuzzy_sets for complete specification (two fields, t1 and t2, to mark which fs you want to use) + :return: a rulebase object. + + kwargs: + - time_moment: if temporal fuzzy sets are used with different partitions for each time interval, + then this parameter is used to specify which time moment is being used. + ''' + + rule_list = [[] for _ in range(self.n_classes)] + + mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8 + ''' + GEN STRUCTURE + + First: antecedents chosen by each rule. Size: nAnts * nRules + Second: Variable linguistics used. Size: nAnts * nRules + Third: Parameters for the fuzzy partitions of the chosen variables. Size: X.shape[1] * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) + Four: Consequent classes. Size: nRules (fixed to 4 right now) + ''' + if self.lvs is None: + # If memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + \ + self.X.shape[1] * self.n_lv_possible * mf_size + else: + # If no memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + + aux_pointer = 0 + min_domain = np.min(self.X, axis=0) + max_domain = np.max(self.X, axis=0) + + # Integer sampling doesnt work fine in pymoo, so we do this (which is btw what pymoo is really doing if you just set integer optimization) + try: + # subject might come as a dict. + x = np.array(list(x.values())).astype(int) + except AttributeError: + x = x.astype(int) + + for i0 in range(self.nRules): # Reconstruct the rules + first_pointer = i0 * self.nAnts + chosen_ants = x[first_pointer:first_pointer + self.nAnts] + + second_pointer = (i0 * self.nAnts) + (self.nAnts * self.nRules) + # Shape: self.nAnts + self.n_lv_possible + 1 + antecedent_parameters = x[second_pointer:second_pointer+self.nAnts] + + init_rule_antecedents = np.zeros( + (self.X.shape[1],)) - 1 # -1 is dont care + for jx, ant in enumerate(chosen_ants): + init_rule_antecedents[ant] = antecedent_parameters[jx] + + consequent_idx = x[fourth_pointer + aux_pointer] + assert consequent_idx < self.n_classes, "Consequent class is not valid. Something in the gene is wrong." + aux_pointer += 1 + + if consequent_idx != -1: + rule_list[consequent_idx].append( + rules.RuleSimple(init_rule_antecedents, 0)) + + # If we optimize the membership functions + if self.lvs is None: + third_pointer = 2 * self.nAnts * self.nRules + aux_pointer = 0 + antecedents = [] + for fuzzy_variable in range(self.X.shape[1]): + linguistic_variables = [] + + for linguistic_variable in range(self.n_lv_possible): + parameter_pointer = third_pointer + aux_pointer + fz_parameters_idx = x[parameter_pointer:parameter_pointer + mf_size] + fz_parameters = self.antecedents_referencial[fuzzy_variable][fz_parameters_idx] + aux_pointer += mf_size + + if fz_type == fs.FUZZY_SETS.t2: + fz_parameters[0:6] = np.sort(fz_parameters[0:6]) + mu = [np.min(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.max(fz_parameters[4:6])] + ml = [np.max(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.min(fz_parameters[4:6])] + height = fz_parameters[6] / np.max(fz_parameters) + + ivfs = fs.IVFS(self.vl_names[linguistic_variable], ml, mu, + (min_domain[fuzzy_variable], max_domain[fuzzy_variable]), lower_height=height) + else: + ivfs = fs.FS(self.vl_names[linguistic_variable], np.sort(fz_parameters[0:4]), + (min_domain[fuzzy_variable], max_domain[fuzzy_variable])) + linguistic_variables.append(ivfs) + + antecedents.append(fs.fuzzyVariable( + self.var_names[fuzzy_variable], linguistic_variables)) + else: + try: + antecedents = self.lvs[kwargs['time_moment']] + except: + antecedents = self.lvs + + for i in range(self.n_classes): + if fz_type == fs.FUZZY_SETS.temporal: + fz_type = self.lvs[0][0].inside_type() + + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(antecedents, rule_list[i]) + + + if i == 0: + res = rules.MasterRuleBase([rule_base]) + else: + res.add_rule_base(rule_base) + + return res + + + def _evaluate(self, x: np.array, out: dict, *args, **kwargs): + ''' + :param x: array of train samples. x shape = features + those features are the parameters to optimize. + + :param out: dict where the F field is the fitness. It is used from the outside. + ''' + ruleBase = self._construct_ruleBase(x, self.fuzzy_type) + + if len(ruleBase.get_rules()) > 0: + score = self.fitness_func(ruleBase, self.X, self.y, self.tolerance) + else: + score = 0.0 + + out["F"] = 1 - score + + +
[docs] def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.975, beta:float=0.0125, gamma:float=0.0125) -> float: + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_full_evaluation() + ruleBase.purge_rules(tolerance) + + if len(ruleBase.get_rules()) > 0: + score_acc = ev_object.classification_eval() + score_rules_size = ev_object.size_antecedents_eval(tolerance) + score_nrules = ev_object.effective_rulesize_eval(tolerance) + + score = score_acc * alpha + score_rules_size * beta + score_nrules * gamma + else: + score = 0.0 + + return score
+ + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html b/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html new file mode 100644 index 0000000..b5cc218 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/fuzzy_sets.html @@ -0,0 +1,552 @@ + + + + + + ex_fuzzy.fuzzy_sets — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.fuzzy_sets

+"""
+This is a the source file that contains the class of GT2 fuzzy set and its most direct applications, 
+like computing the FM function, etc.
+
+"""
+import enum
+
+import numpy as np
+
+try:
+    from . import maintenance as mnt
+except:
+    import maintenance as mnt
+
+
+''' Enum that defines the fuzzy set types.'''
+class FUZZY_SETS(enum.Enum):
+    t1 = 'Type 1'
+    t2 = 'Type 2'
+    gt2 = 'General Type 2'
+
+
[docs]def trapezoidal_membership(x: np.array, params: list[float], epsilon=10E-5) -> np.array: + ''' + Trapezoidal membership functions. + + :param x: input values in the fuzzy set referencial domain. + :param params: four numbers that comprises the start and end of the trapezoid. + :param epsilon: small float number for numerical stability. Adjust accordingly only if there are NaN issues. + ''' + a, b, c, d = params + + # Special case: a singleton trapezoid + if a == d: + return np.equal(a, x).astype(float) + + if b == a: + b += epsilon + if c == d: + d += epsilon + + aux1 = (x - a) / (b - a) + aux2 = (d - x) / (d - c) + + return np.maximum(np.minimum(np.minimum(aux1, aux2), 1), 0)
+ + +def __gaussian2(x, params: list[float]) -> np.array: + ''' + Gaussian membership functions. + + :param mean: real number, mean of the gaussian function. + :param amplitude: real number. + :param standard_deviation: std of the gaussian function. + ''' + mean, amplitude, standard_deviation = params + return amplitude * np.exp(- ((x - mean) / standard_deviation) ** 2) + + +
[docs]class FS(): + ''' + Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets). + ''' + + def __init__(self, name: str, membership_parameters: list[float], domain: list[float]) -> None: + ''' + Creates a fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain of the fuzzy set. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + self.name = name + self.domain = domain + self.membership_parameters = membership_parameters + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + ''' + return trapezoidal_membership(x, self.membership_parameters)
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum. + + :return: FUZZY_SETS enum. + ''' + return FUZZY_SETS.t1
+ + + def __call__(self, x: np.array) -> np.array: + ''' + Calling the Fuzzy set returns its membership. + + :param x: input values in the fuzzy set referencial domain. + :return: membership of the fuzzy set. + ''' + return self.membership(x)
+ + +
[docs]class IVFS(FS): + ''' + Class to define a iv fuzzy set. + ''' + + def __init__(self, name: str, secondMF_lower: list[float], secondMF_upper: list[float], + domain: list[float], lower_height=1.0) -> None: + ''' + Creates a IV fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + ''' + self.name = name + self.domain = domain + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + assert secondMF_lower[0] >= secondMF_upper[0], 'First term membership incoherent' + assert secondMF_lower[0] <= secondMF_lower[1] and secondMF_lower[ + 1] <= secondMF_lower[2] and secondMF_lower[2] <= secondMF_lower[3], 'Lower memberships incoherent. ' + assert secondMF_upper[0] <= secondMF_upper[1] and secondMF_upper[ + 1] <= secondMF_upper[2] and secondMF_upper[2] <= secondMF_upper[3], 'Upper memberships incoherent.' + assert secondMF_lower[3] <= secondMF_upper[3], 'Final term memberships incoherent.' + + self.secondMF_lower = secondMF_lower + self.secondMF_upper = secondMF_upper + self.lower_height = lower_height + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the iv-membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + :return: iv-membership of the fuzzy set. + ''' + lower = trapezoidal_membership( + x, self.secondMF_lower) * self.lower_height + upper = trapezoidal_membership(x, self.secondMF_upper) + + try: + assert np.all(lower <= upper) + except AssertionError: + np.argwhere(lower > upper) + + return np.stack([lower, upper], axis=-1)
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2) + ''' + return FUZZY_SETS.t2
+ + +
[docs]class GT2(FS): + ''' + Class to define a gt2 fuzzy set. + ''' + + MAX_RES_SUPPORT = 4 # Number of decimals supported in the secondary + + def __init__(self, name: str, secondary_memberships: dict[float, FS], + domain: list[float], significant_decimals: int, + alpha_cuts: list[float] = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0], + unit_resolution: float = 0.2) -> None: + ''' + Creates a GT2 fuzzy set. + + :param name: string. + :param secondary_memberships: list of fuzzy sets. Secondary membership that maps original domain to [0, 1] + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + :param alpha_cuts: list of real numbers. Alpha cuts of the fuzzy set. + :param unit_resolution: real number. Resolution of the primary membership function. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + self.name = name + self.domain = domain + self.secondary_memberships = secondary_memberships + self.alpha_cuts = alpha_cuts + self.iv_secondary_memberships = {} + self.unit_resolution = unit_resolution + og_keys = list(self.secondary_memberships.keys()) + self.significant_decimals = significant_decimals + self.domain_init = int( + float(og_keys[0]) * 10**self.significant_decimals) + + formatted_keys = [('%.' + str(self.significant_decimals) + 'f') % + xz for xz in np.array(list(self.secondary_memberships.keys()))] + for og_key, formatted_key in zip(og_keys, formatted_keys): + secondary_memberships[formatted_key] = self.secondary_memberships.pop( + og_key) + + self.sample_unit_domain = np.arange( + 0, 1 + self.unit_resolution, self.unit_resolution) + + for ix, alpha_cut in enumerate(alpha_cuts): + level_memberships = {} + array_level_memberships = np.zeros( + (len(secondary_memberships.items()), 2)) + + for jx, (x, fs) in enumerate(secondary_memberships.items()): + alpha_primary_memberships = fs.membership( + self.sample_unit_domain) + alpha_membership = alpha_primary_memberships >= alpha_cut + + try: + b = self.sample_unit_domain[np.argwhere( + alpha_membership)[0]][0] + c = self.sample_unit_domain[np.argwhere( + alpha_membership)[-1]][0] + except IndexError: # If no numbers are bigger than alpha, then it is because of rounding errors near 0. So, we fix this manually. + b = 0 + c = 0 + + alpha_cut_interval = [b, c] + + level_memberships[x] = alpha_cut_interval + array_level_memberships[jx, :] = np.array(alpha_cut_interval) + + self.iv_secondary_memberships[alpha_cut] = array_level_memberships + + +
[docs] def membership(self, x: np.array) -> np.array: + ''' + Computes the alpha cut memberships of a point. + + :param x: input values in the fuzzy set referencial domain. + :return: np array samples x alpha_cuts x 2 + ''' + x = np.array(x) + # locate the x in the secondary membership + formatted_x = ( + x * 10**self.significant_decimals).astype(int) - self.domain_init + + # Once the x is located we compute the function for each alpha cut + alpha_cut_memberships = [] + for ix, alpha in enumerate(self.alpha_cuts): + ivfs = np.squeeze( + np.array(self.iv_secondary_memberships[alpha][formatted_x])) + alpha_cut_memberships.append(np.squeeze(ivfs)) + + alpha_cut_memberships = np.array(alpha_cut_memberships) + + # So that the result is samples x alpha_cuts x 2 + return np.swapaxes(alpha_cut_memberships, 0, 1)
+ + +
[docs] def type(self) -> FUZZY_SETS: + return FUZZY_SETS.gt2
+ + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + if len(x.shape) == 3: + formatted = np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0) + else: + formatted = self.alpha_cuts + return np.sum(formatted * x, axis=-1) / np.sum(self.alpha_cuts) + + +
[docs] def alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + return self._alpha_reduction(x)
+ + +
[docs]class gaussianIVFS(IVFS): + ''' + Class to define a iv fuzzy set with gaussian membership. + ''' + +
[docs] def membership(self, input: np.array) -> np.array: + ''' + Computes the gaussian iv-membership of a point or a vector. + + :param input: input values in the fuzzy set referencial domain. + :return: np array samples x 2 + ''' + lower = __gaussian2(input, self.secondMF_lower) + upper = __gaussian2(input, self.secondMF_upper) + + return np.array(np.concatenate([lower, upper])).T
+ + +
[docs] def type(self) -> FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (t1) + ''' + return FUZZY_SETS.t1
+ + +
[docs]class fuzzyVariable(): + ''' + Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them. + ''' + + def __init__(self, name: str, fuzzy_sets: list[FS]) -> None: + ''' + Creates a fuzzy variable. + + :param name: string. Name of the fuzzy variable. + :param fuzzy_sets: list of IVFS. Each of the fuzzy sets that comprises the linguist variables of the fuzzy variable. + ''' + self.linguistic_variables = [] + self.name = name + + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + +
[docs] def linguistic_variable_names(self) -> list: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return [fs.name for fs in self.linguistic_variables]
+ + +
[docs] def get_linguistic_variables(self) -> list[FS]: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return self.linguistic_variables
+ + +
[docs] def compute_memberships(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the FS in the fuzzy variables. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x)) + + return res
+ + +
[docs] def domain(self) -> list[float]: + ''' + Returns the domain of the fuzzy variable. + + :return: list of floats. + ''' + return self.linguistic_variables[0].domain
+ + +
[docs] def fuzzy_type(self) -> FUZZY_SETS: + ''' + Returns the fuzzy type of the domain + + :return: the type of the fuzzy set present in the fuzzy variable. + ''' + return self.fs_type
+ + + def __getitem__(self, item) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + return self.linguistic_variables[item] + + + def __setitem__(self, item: int, elem: FS) -> None: + ''' + Sets the corresponding fs. + + :param item: int. Index of the FS. + :param elem: FS. The FS to set. + ''' + self.linguistic_variables[item] = elem + + + def __iter__(self) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + for fs in self.linguistic_variables: + yield fs + + + def __len__(self) -> int: + ''' + Returns the number of linguistic variables. + + :return: int. Number of linguistic variables. + ''' + return len(self.linguistic_variables) + + + def __call__(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + return self.compute_memberships(x)
+ + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/persistence.html b/docs/build/html/_modules/ex_fuzzy/persistence.html new file mode 100644 index 0000000..33b7145 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/persistence.html @@ -0,0 +1,202 @@ + + + + + + ex_fuzzy.persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.persistence

+'''
+Load the rules of a fuzzy rules system using plain text format.
+
+'''
+import numpy as np
+
+try:
+    from . import fuzzy_sets as fs
+    from . import rules
+    from . import maintenance as mnt
+
+except ImportError:
+    import fuzzy_sets as fs
+    import rules
+    import maintenance as mnt
+
+
+
[docs]def load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) -> rules.MasterRuleBase: + ''' + Load the rules from a string. + + :param rules_printed: string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase + :param fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class. + + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Persistence]['persistence_read'] += 1 + + consequent = 0 + linguistic_variables_names = [linguistic_variable.name for linguistic_variable in fuzzy_variables] + value_names = [x.name for x in fuzzy_variables[0]] + fz_type = fuzzy_variables[0].fuzzy_type() + consequent_names = [] + for line in rules_printed.splitlines(): + if line.startswith('IF'): + #Is a rule + antecedents , consequent_ds = line.split('WITH') + consequent_ds = consequent_ds.split(',')[0].strip() + init_rule_antecedents = np.zeros( + (len(fuzzy_variables),)) - 1 # -1 is dont care + + for antecedent in antecedents.split('AND'): + antecedent = antecedent.replace('IF', '').strip() + antecedent_name, antecedent_value = antecedent.split('IS') + antecedent_name = antecedent_name.strip() + antecedent_value = antecedent_value.strip() + antecedent_index = linguistic_variables_names.index(antecedent_name) + antecedent_value_index = value_names.index(antecedent_value) + + init_rule_antecedents[antecedent_index] = antecedent_value_index + + rule_simple = rules.RuleSimple(init_rule_antecedents, 0) + rule_simple.score = float(consequent_ds[3:].strip()) # We remove the 'DS ' and the last space + reconstructed_rules.append(rule_simple) + + elif line.startswith('Rules'): + #New consequent + consequent_name = line.split(':')[-1].strip() + consequent_names.append(consequent_name) + if consequent > 0: + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + if consequent == 1: + mrule_base = rules.MasterRuleBase([rule_base]) + elif consequent > 1: + mrule_base.add_rule_base(rule_base) + + reconstructed_rules = [] + consequent += 1 + + # We add the last rule base + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + mrule_base.add_rule_base(rule_base) + mrule_base.rename_cons(consequent_names) + + return mrule_base
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/rule_mining.html b/docs/build/html/_modules/ex_fuzzy/rule_mining.html new file mode 100644 index 0000000..59b1bd4 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/rule_mining.html @@ -0,0 +1,361 @@ + + + + + + ex_fuzzy.rule_mining — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.rule_mining

+"""
+Module to perform rule mining in a pandas dataframe or numpy array. The methods use the support of the different itemsets to look for good 
+rule candidates. It can be used then by a Genetic optimizator from evolutionary_fit module to search the optimal combination of them.
+
+"""
+import typing
+from itertools import product, combinations
+
+import pandas as pd
+import numpy as np
+
+try:
+    from . import rules as rl
+    from . import fuzzy_sets as fs
+    from . import maintenance as mnt
+    from . import utils
+except ImportError:
+    import utils
+    import rules as rl
+    import fuzzy_sets as fs
+    import maintenance as mnt
+
+
+def _generate_combinations(lists: list, k: int) -> typing.Iterator:
+    '''
+    Generate all the combinations between elements of different lists of length k without repeting elements of the same list.
+
+    :param lists: list of lists.
+    :param k: integer with the length of the combinations.
+    :return: a list with all the combinations.
+    '''
+    # Get all combinations of elements for k
+    all_combs = combinations(np.arange(len(lists)), k)
+    
+    # For those elements, get the cartesian product between them
+    for comb in all_combs:
+        selected_lists = [lists[x] for x in comb]
+        all_combinations = product(*selected_lists)
+
+        # Add them to the global combination list
+        yield all_combinations
+
+
+
+
+
+
[docs]def generate_rules_from_itemsets(itemsets:list, nAnts:int) -> list[rl.RuleSimple]: + ''' + Given a list of itemsets, it creates the rules for each one and returns a list of rules containing them. + + :param itemsets: list of tuple (antecedent, linguistic variable value) + :param nAnts: number of possible antecedents. + :return: the rules for ech itemset. + ''' + rules = [] + for itemset in itemsets: + template = np.ones((nAnts, )) * -1 + for ant, vl in itemset: + template[ant] = vl + + rule = rl.RuleSimple(list(template)) + rules.append(rule) + + return rules
+ + +
[docs]def mine_rulebase_support(x: pd.DataFrame, fuzzy_variables:list[fs.fuzzyVariable], support_threshold:float=0.05, max_depth:int=3) -> rl.RuleBase: + ''' + Search the data for associations that are frequent given a list of fuzzy variables for each antecedent. + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_variables: list of the fuzzy variables for each of the input variables. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.RuleMining]['mine_rulebase'] += 1 + + freq_itemsets = rule_search(x, fuzzy_variables, support_threshold, max_depth) + rule_list = generate_rules_from_itemsets(freq_itemsets, len(fuzzy_variables)) + + fuzzy_type = fuzzy_variables[0].fs_type + + if fuzzy_type == fs.FUZZY_SETS.t1: + rule_base = rl.RuleBaseT1(fuzzy_variables, rule_list) + elif fuzzy_type == fs.FUZZY_SETS.t2: + rule_base = rl.RuleBaseT2(fuzzy_variables, rule_list) + elif fuzzy_type == fs.FUZZY_SETS.gt2: + rule_base = rl.RuleBaseGT2(fuzzy_variables, rule_list) + + return rule_base
+ + +
[docs]def prune_rules_confidence_lift(x: pd.DataFrame, y:np.array, rules: rl.MasterRuleBase, fuzzy_variables: list[fs.fuzzyVariable], confidence_threshold:float=0.5, + lift_threshold:float=1.05): + ''' + Removes the rules from the rule base that do not meet a minimum value for confidence and lift measures. + + Confidence is the ratio of rules that have a particular antecedent and consequent, and those that only have the antecedent. + Lift is ratio between confidence and expected confidence, which is the percentage of class samples in the original data. + + :param x: data to mine. samples x features. + :param y: class vector. + :param rules: MasterRuleBase object with the rules to prune. + :param fuzzy_variables: a list of the fuzzy variables per antecedent. + :param confidence_threshold: minimum confidence required to the rules. + :param lift_threshold: minimum lift required to the rules. + ''' + for ix, rule_base in enumerate(rules): + delete_list = [] + relevant_class = ix + relevant_class_samples = x.loc[np.equal(y, relevant_class), :] + + for jx, rule in enumerate(rule_base): + real_nAnts = sum([ant != -1 for ant in rule]) + global_membership_array = np.zeros((x.shape[0], real_nAnts)) + class_samples_membership_array = np.zeros((relevant_class_samples.shape[0], real_nAnts)) + ant_counter = 0 + for zx, antecedent in enumerate(rule): + if antecedent != -1: + global_membership_array[:, ant_counter] = fuzzy_variables[zx](x[fuzzy_variables[zx].name])[antecedent] + class_samples_membership_array[:, ant_counter] = fuzzy_variables[zx](relevant_class_samples[fuzzy_variables[zx].name])[antecedent] + ant_counter += 1 + + # Compute rule confidence + global_support = np.mean(np.min(global_membership_array, axis=1), axis=0) + class_support = np.mean(np.min(class_samples_membership_array, axis=1), axis=0) + if fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.t2 or fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.gt2: + global_support = np.mean(global_support, axis=1) + class_support = np.mean(class_support, axis=1) + + rule_confidence = class_support / global_support + rule_lift = rule_confidence / np.mean(np.equal(relevant_class, y)) + + if rule_confidence < confidence_threshold or rule_lift < lift_threshold: + delete_list.append(jx) + + rule_base.remove_rules(delete_list)
+ + +
[docs]def simple_mine_rulebase(x: pd.DataFrame, fuzzy_type:fs.FUZZY_SETS=fs.FUZZY_SETS.t1, support_threshold:float=0.05, max_depth:int=3) -> rl.RuleBase: + ''' + Search the data for associations that are frequent. Computes the fuzzy variables using a 3 label partition (low, medium, high). + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_type: fuzzy type to use. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + + precomputed_partitions = utils.construct_partitions(x, fuzzy_type) + return mine_rulebase_support(x, precomputed_partitions, support_threshold, max_depth)
+ + +
[docs]def multiclass_mine_rulebase(x: pd.DataFrame, y: np.array, fuzzy_variables:list[fs.fuzzyVariable], support_threshold:float=0.05, max_depth:int=3, + confidence_threshold:float=0.05, lift_threshold:float=1.05) -> rl.MasterRuleBase: + ''' + Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. Computes a different ruleBase for each + class and then uses them to form a MasterRuleBase. + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_variables: list of the fuzzy variables for each of the input variables. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :param confidence_threshold: minimum confidence value. + :param lift_threshold: + :return: a rulebase object with the rules denoted as good. + ''' + unique_classes = np.unique(y) + rulebases = [] + for yclass in unique_classes: + selected_samples = np.equal(yclass, y) + selected_x = x.loc[selected_samples, :] + + rulebase = mine_rulebase_support(selected_x, fuzzy_variables, support_threshold, max_depth) + rulebases.append(rulebase) + + master_rulebase = rl.MasterRuleBase(rulebases, list(map(str, unique_classes))) + prune_rules_confidence_lift(x, y, master_rulebase, fuzzy_variables, confidence_threshold, lift_threshold) + return master_rulebase
+ + +
[docs]def simple_multiclass_mine_rulebase(x: pd.DataFrame, y: np.array, fuzzy_type:fs.FUZZY_SETS, support_threshold:float=0.05, max_depth:int=3, + confidence_threshold:float=0.5, lift_threshold:float=1.1) -> rl.MasterRuleBase: + ''' + Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. + Computes a different ruleBase for each class and then uses them to form a MasterRuleBase. + + Computes the fuzzy variables using a 3 label partition (low, medium, high). + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_type: fuzzy type to use. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + precomputed_partitions = utils.construct_partitions(x, fuzzy_type) + return multiclass_mine_rulebase(x, y, precomputed_partitions, support_threshold, max_depth, + confidence_threshold=confidence_threshold, lift_threshold=lift_threshold)
+ + + + + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/rules.html b/docs/build/html/_modules/ex_fuzzy/rules.html new file mode 100644 index 0000000..d3ddcf6 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/rules.html @@ -0,0 +1,1197 @@ + + + + + + ex_fuzzy.rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.rules

+# -*- coding: utf-8 -*-
+"""
+This is a the source file that contains the Rule, RuleBase and MasterRuleBase classes to perform fuzzy inference.
+
+"""
+import abc
+
+import numpy as np
+try:
+    from . import fuzzy_sets as fs
+    from . import centroid
+except ImportError:
+    import fuzzy_sets as fs
+    import centroid
+
+
+
[docs]class RuleError(Exception): + ''' + Exception raised when a rule is not well defined. + ''' + + def __init__(self, message: str) -> None: + ''' + Constructor of the RuleError class. + + :param message: message of the error. + ''' + super().__init__(message)
+ +def _myprod(x: np.array, y: np.array) -> np.array: + ''' + Proxy function to change the product operation interface + ''' + return x*y + + +
[docs]class Rule(): + ''' + Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself. + ''' + + def __init__(self, antecedents: list[fs.FS], consequent: fs.FS) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of fuzzy sets. + :param consequent: fuzzy set. + ''' + self.antecedents = antecedents + self.consequent = consequent + +
[docs] def membership(self, x: np.array, tnorm=_myprod) -> np.array: + ''' + Computes the membership of one input to the antecedents of the rule. + + :param x: input to compute the membership. + :param tnorm: t-norm to use in the inference process. + ''' + for ix, antecedent in enumerate(self.antecedents): + if ix == 0: + res = antecedent.membership(x) + else: + res = tnorm(res, antecedent.membership(x)) + + return res
+ +
[docs] def consequent_centroid(self) -> np.array: + ''' + Returns the centroid of the consequent using a Karnik and Mendel algorithm. + ''' + try: + return self.centroid_consequent + except AttributeError: + consequent_domain = self.consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = self.consequent.membership( + domain_linspace) + + self.centroid_consequent = centroid.compute_centroid_fs( + domain_linspace, consequent_memberships) + + return self.centroid_consequent
+ + +
[docs]class RuleSimple(): + ''' + Class designed to represent rules in its simplest form to optimize the computation in a rulebase. + + It indicates the antecedent values using a vector coded in this way: + ith entry: -1 means this variable is not used. 0-N indicates that the variable linguistic used for the ith input is that one. + ''' + + def __init__(self, antecedents: list[int], consequent: int=0) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of integers indicating the linguistic variable used for each input. + :param consequent: integer indicating the linguistic variable used for the consequent. + ''' + self.antecedents = list(map(int, antecedents)) + self.consequent = int(consequent) + + + def __getitem__(self, ix): + ''' + Returns the antecedent value for the given index. + + :param ix: index of the antecedent to return. + ''' + return self.antecedents[ix] + + + def __setitem__(self, ix, value): + ''' + Sets the antecedent value for the given index. + + :param ix: index of the antecedent to set. + :param value: value to set. + ''' + self.antecedents[ix] = value + + + def __str__(self): + ''' + Returns a string representation of the rule. + ''' + return 'Rule: antecedents: ' + str(self.antecedents) + ' consequent: ' + str(self.consequent) + + + def __len__(self): + ''' + Returns the number of antecedents in the rule. + ''' + return len(self.antecedents) + + + def __eq__(self, other): + ''' + Returns True if the two rules are equal. + ''' + return self.antecedents == other.antecedents and self.consequent == other.consequent + + + def __hash__(self): + ''' + Returns the hash of the rule. + ''' + return hash(str(self))
+ + +
[docs]class RuleBase(): + ''' + Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study) + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=np.prod) -> None: + ''' + Creates a rulebase with the given antecedents, rules and consequent. + + :param antecedents: list of fuzzy sets. + :param rules: list of rules. + :param consequent: fuzzy set. + :param tnorm: t-norm to use in the inference process. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership(domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + self.delete_duplicates() + + +
[docs] def get_rules(self) -> list[RuleSimple]: + ''' + Returns the list of rules in the rulebase. + ''' + return self.rules
+ + +
[docs] def add_rule(self, new_rule: RuleSimple): + ''' + Adds a new rule to the rulebase. + :param new_rule: rule to add. + ''' + self.rules.append(new_rule)
+ + +
[docs] def add_rules(self, new_rules: list[RuleSimple]): + ''' + Adds a list of new rules to the rulebase. + + :param new_rules: list of rules to add. + ''' + self.rules += new_rules
+ + +
[docs] def remove_rule(self, ix: int) -> None: + ''' + Removes the rule in the given index. + :param ix: index of the rule to remove. + ''' + del self.rules[ix]
+ + +
[docs] def remove_rules(self, delete_list: list[int]) -> None: + ''' + Removes the rules in the given list of indexes. + + :param delete_list: list of indexes of the rules to remove. + ''' + self.rules = [rule for ix, rule in enumerate( + self.rules) if ix not in delete_list]
+ + +
[docs] def get_rulebase_matrix(self): + ''' + Returns a matrix with the antecedents values for each rule. + ''' + res = np.zeros((len(self.rules), len(self.rules[0]))) + + for ix, rule in enumerate(self.rules): + res[ix] = rule + + return res
+ + +
[docs] def get_scores(self): + ''' + Returns an array with the dominance score for each rule. + (Must been already computed by an evalRule object) + + ''' + res = np.zeros((len(self.rules, ))) + for ix, rule in enumerate(self.rules): + res[ix] = rule.score + + return res
+ + + def delete_rule_duplicates(self, list_rules:list[RuleSimple]): + # Delete the rules that are duplicated in the rule list + unique = {} + for ix, rule in enumerate(list_rules): + try: + unique[rule] + except KeyError: + unique[rule] = ix + + new_list = [list_rules[x] for x in unique.values()] + + return new_list + + + +
[docs] def compute_antecedents_memberships(self, x: np.array) -> list[dict]: + ''' + Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable. + x must be a vector (only one sample) + + :param x: vector with the values of the inputs. + ''' + if len(self.rules) > 0: + cache_antecedent_memberships = [] + + for ix, antecedent in enumerate(self.antecedents): + cache_antecedent_memberships.append( + antecedent.compute_memberships(x[:, ix])) + + return cache_antecedent_memberships + + else: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + return [np.zeros((x.shape[0], 1))] + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + return [np.zeros((x.shape[0], 1, 2))] + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + return [np.zeros((x.shape[0], len(self.alpha_cuts), 2))]
+ + +
[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the antecedent truth value of an input array. + + Return an array in shape samples x rules (x 2) (last is iv dimension) + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled according to their sums for each sample. + :return: array with the memberships of the antecedents for each rule. + ''' + if self.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((x.shape[0], len(self.rules), 2)) + elif self.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((x.shape[0], len(self.rules), )) + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros( + (x.shape[0], len(self.rules), len(self.alpha_cuts), 2)) + + antecedents_memberships = self.compute_antecedents_memberships(x) + + for jx, rule in enumerate(self.rules): + rule_antecedents = rule.antecedents + initiated = False + for ix, vl in enumerate(rule_antecedents): + if vl >= 0: + if not initiated: + membership = list(antecedents_memberships[ix])[vl] + initiated = True + else: + membership = self.tnorm(membership, list( + antecedents_memberships[ix])[vl]) + + try: + res[:, jx] = membership + except UnboundLocalError: + pass # All the antecedents are dont care. + + if scaled: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + non_zero_rows = np.sum(res, axis=1) > 0 + res[non_zero_rows] = res[non_zero_rows] / \ + np.sum(res[non_zero_rows], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + non_zero_rows = np.sum(res[:, :, 0], axis=1) > 0 + res[non_zero_rows, :, 0] = res[non_zero_rows, :, 0] / \ + np.sum(res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(res[:, :, 1], axis=1) > 0 + res[non_zero_rows, :, 1] = res[non_zero_rows, :, 1] / \ + np.sum(res[non_zero_rows, :, 1], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + + for ix, alpha in enumerate(self.alpha_cuts): + relevant_res = res[:, :, ix, :] + + non_zero_rows = np.sum(relevant_res[:, :, 0], axis=1) > 0 + relevant_res[non_zero_rows, :, 0] = relevant_res[non_zero_rows, :, 0] / \ + np.sum(relevant_res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(relevant_res[:, :, 1], axis=1) > 0 + relevant_res[non_zero_rows, :, 1] = relevant_res[non_zero_rows, :, 1] / \ + np.sum(relevant_res[non_zero_rows, :, 1], axis=1, keepdims=True) + + res[:, :, ix, :] = relevant_res + + return res
+ + +
[docs] def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules from the rule base. + ''' + all_rules = '' + for ix, rule in enumerate(self.rules): + initiated = False + str_rule = 'IF ' + for jx, vl_ix in enumerate(rule.antecedents): + antecedent = self.antecedents[jx] + keys = antecedent.linguistic_variable_names() + + if rule[jx] != -1: + if not initiated: + str_rule += str(antecedent.name) + ' IS ' + str(keys[vl_ix]) + initiated = True + else: + str_rule += ' AND ' + str(antecedent.name) + \ + ' IS ' + str(keys[vl_ix]) + + try: + score = rule.score if self.fuzzy_type() == fs.FUZZY_SETS.t1 else np.mean(rule.score) + str_rule += ' WITH DS ' + str(score) + + # If the classification scores have been computed, print them. + try: + str_rule += ', ACC ' + str(rule.accuracy) + + except AttributeError: + pass + except AttributeError: + str_rule += ' THEN consequent vl is ' + str(rule.consequent) + + all_rules += str_rule + '\n' + + if not return_rules: + print(all_rules) + else: + return all_rules
+ + +
[docs] @abc.abstractmethod + def inference(self, x: np.array) -> np.array: + ''' + Computes the fuzzy output of the fl inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each rule. + ''' + raise NotImplementedError
+ + +
[docs] @abc.abstractmethod + def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the fl inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output. + ''' + raise NotImplementedError
+ + +
[docs] @abc.abstractmethod + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the type of fuzzy set used in the RuleBase. + ''' + raise NotImplementedError
+ + + def __len__(self): + ''' + Returns the number of rules in the rule base. + ''' + return len(self.rules) + + +
[docs] def prune_bad_rules(self, tolerance=0.01) -> None: + ''' + Delete the rules from the rule base that do not have a dominance score superior to the threshold or have 0 accuracy in the training set. + + :param tolerance: threshold for the dominance score. + ''' + delete_list = [] + try: + for ix, rule in enumerate(self.rules): + score = rule.score + if (self.fuzzy_type() == fs.FUZZY_SETS.t2) or (self.fuzzy_type() == fs.FUZZY_SETS.gt2): + score = np.mean(score) + + if score < tolerance or rule.accuracy == 0.0: + delete_list.append(ix) + except AttributeError: + assert False, 'Dominance scores not computed for this rulebase' + + self.remove_rules(delete_list)
+ + +
[docs] def scores(self) -> np.array: + ''' + Returns the dominance score for each rule. + + :return: array with the dominance score for each rule. + ''' + scores = [] + for rule in self.rules: + scores.append(rule.score) + + return np.array(scores)
+ + + def __getitem__(self, item: int) -> RuleSimple: + ''' + Returns the corresponding rulebase. + + :param item: index of the rule. + :return: the corresponding rule. + ''' + return self.rules[item] + + + def __setitem__(self, key: int, value: RuleSimple) -> None: + ''' + Set the corresponding rule. + + :param key: index of the rule. + :param value: new rule. + ''' + self.rules[key] = value + + + def __iter__(self): + ''' + Returns an iterator for the rule base. + ''' + return iter(self.rules) + + + def __str__(self): + ''' + Returns a string with the rules in the rule base. + ''' + str_res = '' + for rule in self.rules: + str_res += str(rule) + '\n' + return str_res + + + def __eq__(self, other): + ''' + Returns True if the two rule bases are equal. + ''' + return self.rules == other.rules + + + def __hash__(self): + ''' + Returns the hash of the rule base. + ''' + return hash(str(self)) + + + def __add__(self, other): + ''' + Adds two rule bases. + ''' + return RuleBase(self.antecedents, self.rules + other.rules, self.consequent, self.tnorm) + + +
[docs] def n_linguist_variables(self) -> int: + ''' + Returns the number of linguistic variables in the rule base. + ''' + return len(self.antecedents)
+ + +
[docs]class RuleBaseT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports iv approximation for t2 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + + for ix, vl_consequent in enumerate(consequent.linguistic_variables): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + # If 0, we are classifying and we do not need the consequent centroids. + if len(self.consequent_centroids) > 0: + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the iv output of the t2 inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res
+ + +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.mean(self.inference(x))
+ +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t2
+ + +
[docs]class RuleBaseGT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports gt2 fs. (ONLY FOR CLASSIFICATION PROBLEMS) + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseGT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.alpha_cuts = antecedents[0][0].alpha_cuts + + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the gt2 inference system. + + Return an array in shape samples x alpha_cuts + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res
+ + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + formtatted = np.expand_dims(np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0), axis=0) + return np.sum(formtatted * x, axis=2) / np.sum(self.alpha_cuts) + + +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.sum(np.array(self.alpha_cuts) * (self.inference(x)), axis=1) / np.sum(self.alpha_cuts)
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.gt2
+ + +
[docs] def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents performing the alpha_cut reduction. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + ''' + antecedent_membership = super().compute_rule_antecedent_memberships(x, scaled) + return self._alpha_reduction(antecedent_membership)
+ + +
[docs] def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents for all the alpha cuts. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + :return: array with the memberships of the antecedents for each sample. + ''' + return super().compute_rule_antecedent_memberships(x, scaled)
+ + +
[docs]class RuleBaseT1(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports t1 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT1 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. ONLY on regression problems. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), )) + + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix] = centroid.center_of_masses( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), )) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + +
[docs] def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the t1 inference system. + + Return an array in shape samples. + + :param x: array with the values of the inputs. + :return: array with the output of the inference system for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.center_of_masses( + self.consequent_centroids_rules, antecedent_memberships[sample]) + + return res
+ +
[docs] def forward(self, x: np.array) -> np.array: + ''' + Same as inference() in the t1 case. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return self.inference(x)
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t1
+ + +
[docs]class MasterRuleBase(): + ''' + This Class encompasses a list of rule bases where each one corresponds to a different class. + ''' + + def __init__(self, rule_base: list[RuleBase], consequent_names: list[str]=None) -> None: + ''' + Constructor of the MasterRuleBase class. + + :param rule_base: list of rule bases. + ''' + if len(rule_base) == 0: + raise RuleError('No rule bases given!') + + self.rule_bases = rule_base + self.antecedents = rule_base[0].antecedents + + if consequent_names is None: + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))] + else: + self.consequent_names = consequent_names + + +
[docs] def rename_cons(self, consequent_names: list[str]) -> None: + ''' + Renames the consequents of the rule base. + ''' + self.consequent_names = consequent_names
+ + +
[docs] def add_rule(self, rule: RuleSimple, consequent: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + ''' + self.rule_bases[consequent].add_rule(rule)
+ + +
[docs] def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([[ix]*len(x) for ix, x in enumerate(self.rule_bases)], [])
+ + +
[docs] def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [x.get_rulebase_matrix() for x in self.rule_bases]
+ + +
[docs] def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rb in self.rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0)
+ + +
[docs] def compute_firing_strenghts(self, X) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + for ix in range(len(self.rule_bases)): + aux.append(self[ix].compute_rule_antecedent_memberships(X)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1)
+ + + def _winning_rules(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + + firing_strengths = self.compute_firing_strenghts(X) + + association_degrees = self.get_scores() * firing_strengths + + if (self[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + association_degrees = np.mean(association_degrees, axis=2) + elif self[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(association_degrees, axis=3) + + winning_rules = np.argmax(association_degrees, axis=1) + + return winning_rules + + +
[docs] def winning_rule_predict(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = sum([[ix]*len(self[ix].rules) + for ix in range(len(self.rule_bases))], []) # The sum is for flatenning the list + winning_rules = self._winning_rules(X) + + return np.array([consequents[ix] for ix in winning_rules])
+ + +
[docs] def add_rule_base(self, rule_base: RuleBase) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.rule_bases.append(rule_base) + + if len(self.rule_bases) != len(self.consequent_names): + # We did not give proper names to the consequents + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))]
+ + +
[docs] def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + + :param autoprint: if True, the rules are printed. If False, the rules are returned as a string. + ''' + res = '' + for ix, ruleBase in enumerate(self.rule_bases): + res += 'Rules for consequent: ' + str(self.consequent_names[ix]) + '\n' + + res += '----------------\n' + res += ruleBase.print_rules(return_rules=True) + '\n' + + + if return_rules: + return res + else: + print(res)
+ + +
[docs] def get_rules(self) -> list[RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for ruleBase in self.rule_bases for rule in ruleBase.rules]
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.rule_bases[0].fuzzy_type()
+ + +
[docs] def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for ruleBase in self.rule_bases: + ruleBase.prune_bad_rules(tolerance)
+ + + def __getitem__(self, item) -> RuleBase: + ''' + Returns the corresponding rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.rule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.rule_bases) + + + def __str__(self) -> str: + ''' + Returns a string with the rules for each consequent. + ''' + return self.print_rules(return_rules=True) + + + def __eq__(self, __value: object) -> bool: + ''' + Returns True if the two rule bases are equal. + + :param __value: object to compare. + :return: True if the two rule bases are equal. + ''' + if not isinstance(__value, MasterRuleBase): + return False + else: + return self.rule_bases == __value.rule_bases + + + def __call__(self, X: np.array) -> np.array: + ''' + Gives the prediction for each sample (same as winning_rule_predict) + + :param X: array of dims: samples x features. + :return: vector of predictions, size: samples, + ''' + return self.winning_rule_predict(X) + + +
[docs] def get_rulebases(self) -> list[RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + return self.rule_bases
+ + +
[docs] def n_linguist_variables(self) -> int: + ''' + Returns the number of linguistic variables in the rule base. + ''' + return len(self.antecedents[0])
+ + +
[docs] def get_antecedents(self) -> list[fs.fuzzyVariable]: + ''' + Returns the antecedents of the rule base. + ''' + return self.antecedents
+ + +
[docs]def list_rules_to_matrix(rule_list: list[RuleSimple]) -> np.array: + ''' + Returns a matrix out of the rule list. + + :param rule_list: list of rules. + :return: matrix with the antecedents of the rules. + ''' + assert len(rule_list) > 0, 'No rules to list!' + + res = np.zeros((len(rule_list), len(rule_list[0].antecedents))) + for ix, rule in enumerate(rule_list): + res[ix, :] = rule.antecedents + + return res
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/temporal.html b/docs/build/html/_modules/ex_fuzzy/temporal.html new file mode 100644 index 0000000..8307497 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/temporal.html @@ -0,0 +1,796 @@ + + + + + + ex_fuzzy.temporal — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.temporal

+'''
+Expansion of the base fuzzy sets, adding temporal fuzzy sets.
+
+Contains functions to model the temporal fuzzy sets, temporal fuzzy variables and temporal rule bases.
+It also contains functions to evaluate the fuzzy rulebases obtained.
+
+'''
+import enum
+
+import numpy as np
+import pandas as pd
+
+from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix, matthews_corrcoef
+from pymoo.algorithms.soo.nonconvex.ga import GA
+from pymoo.core.problem import Problem
+from pymoo.optimize import minimize
+from pymoo.operators.sampling.rnd import IntegerRandomSampling
+from pymoo.operators.crossover.sbx import SBX
+from pymoo.operators.mutation.pm import PolynomialMutation
+from pymoo.core.variable import Integer
+from multiprocessing.pool import ThreadPool
+from pymoo.core.problem import StarmapParallelization
+
+try:
+    from . import fuzzy_sets as fs
+    from . import maintenance as mnt
+    from . import rules as rl
+    from . import evolutionary_fit as evf
+    from . import vis_rules
+    from . import eval_rules as evr
+except:
+    import fuzzy_sets as fs
+    import maintenance as mnt
+    import rules as rl
+    import evolutionary_fit as evf
+    import vis_rules
+    import eval_rules as evr
+
+
+TMP_FUZZY_SETS = enum.Enum(
+    "NEW_FUZZY_SETS",
+    ['temporal', 'temporal_t2', 'temporal_gt2']
+)
+NEW_FUZZY_SETS = enum.Enum(
+    "FUZZY_SETS",
+    [(es.name, es.value) for es in fs.FUZZY_SETS] + [(es.name, es.name) for es in TMP_FUZZY_SETS]
+)
+
+fs.FUZZY_SETS = NEW_FUZZY_SETS
+### DEFINE THE FUZZY SET ####
+
[docs]class temporalFS(fs.FS): + ''' + Class to implement temporal fuzzy sets. + ''' + + def __init__(self, std_fuzzy_set: fs.FS, conditional_variable: np.array) -> None: + ''' + Creates a temporal fuzzy set. + + :param std_fuzzy_set: FS. Standard fuzzy set that contains the non-temporal aware memberhsip function. + :param conditional_variable: np.array. The variable that expresses the different temporal moments. Shape (time discrete moments, ). + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + self.std_set = std_fuzzy_set + self.tmp_function = conditional_variable + self.time = None + self.name = std_fuzzy_set.name + + if std_fuzzy_set.type() == fs.FUZZY_SETS.t1: + self.membership_parameters = std_fuzzy_set.membership_parameters + elif std_fuzzy_set.type() == fs.FUZZY_SETS.t2: + self.secondMF_upper = std_fuzzy_set.secondMF_upper + self.secondMF_lower = std_fuzzy_set.secondMF_lower + elif std_fuzzy_set.type() == fs.FUZZY_SETS.gt2: + self.secondary_memberships = std_fuzzy_set.secondary_memberships + self.alpha_cuts = std_fuzzy_set.alpha_cuts + + +
[docs] def membership(self, input: np.array, time: int=None) -> np.array: + ''' + Computes the membership of each sample and in each time for the fs. + + :param input: array temporal_time x samples. + :time: int. Time moment to compute the membership. If none, looks for a fixed time + :return: array temporal_time x samples. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy set has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + return self.std_set.membership(input) * self.tmp_function[time]
+ + +
[docs] def type(self) -> fs.FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (temporal) + ''' + return fs.FUZZY_SETS.temporal
+ + +
[docs] def inside_type(self) -> fs.FUZZY_SETS: + ''' + Returns the type of the og fuzzy set computed before the time dependency. + ''' + return self.std_set.type()
+ + +
[docs] def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy set. + + :param time: int. Time moment to fix. + :return: FS. Fuzzy set with the fixed time. + ''' + self.time = time
+ + + +#### DEFINE THE FUZZY VARIABLE #### +
[docs]class temporalFuzzyVariable(fs.fuzzyVariable): + ''' + Class to implement a temporal fuzzy variable. + ''' + + def __init__(self, name: str, fuzzy_sets: list[temporalFS]) -> None: + ''' + Creates a temporal fuzzy variable. + + :param str: name of the variable. + :param fuzzy_sets: list of the fuzzy sets pre-time dependencies. + ''' + self.linguistic_variables = [] + self.name = name + self.time = None + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + +
[docs] def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variable. + + :param time: int. Time moment to fix. + ''' + self.time = time
+ + +
[docs] def compute_memberships(self, x: np.array, time: int=None) -> dict: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables. + :param time: int. Time moment to compute the membership. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy variable has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x, time)) + + return res
+ + +
[docs] def n_time_moments(self) -> int: + ''' + Returns the number of time moments of the temporal fuzzy variable. + + :return: int. Number of time moments of the temporal fuzzy variable. + ''' + return self.linguistic_variables[0].tmp_function.shape[0]
+ + +#### DEFINE THE RULE BASE WITH TEMPORAL DEPENDENCIES #### +
[docs]class temporalMasterRuleBase(rl.MasterRuleBase): + ''' + This class is a temporal extension of the MasterRuleBase class. It includes a list of + rule bases for each time step. + ''' + def __init__(self, rule_base: list[rl.MasterRuleBase], time_step_names: list[str]=None): + ''' + Constructor of the temporalMasterRuleBase class. + + :param rule_base: list of rule bases. + :param time_steps: number of time steps. + ''' + super().__init__(rule_base) + self.time_steps = np.arange(len(rule_base)) + self.time_mrule_bases = rule_base + + if time_step_names is None: + self.time_step_names = [str(x) for x in self.time_steps] + else: + self.time_step_names = time_step_names + + for ix, mrb in enumerate(rule_base): + for jx, rb in enumerate(mrb): + for antecedent in rb.antecedents: + antecedent.fix_time(ix) + + self.antecedents = rule_base[0].antecedents + + +
[docs] def add_rule(self, rule: rl.RuleSimple, consequent: int, time_step: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + :param time_step: time step of the rule base to add the rule. + ''' + self.time_mrule_bases[time_step][consequent].add_rule(rule)
+ + +
[docs] def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [a.get_rulebase_matrix() for x in self.time_mrule_bases for a in x]
+ + +
[docs] def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rule_bases in self.time_mrule_bases: + for rb in rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0)
+ + +
[docs] def compute_firing_strenghts(self, X: np.array, time_moments: list[int]) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + time_moments = np.array(time_moments) + + for time_moment, rule_bases in enumerate(self.time_mrule_bases): + actual_moment = np.equal(time_moments, time_moment) + for ix in range(len(rule_bases)): + if rule_bases.fuzzy_type() == fs.FUZZY_SETS.t2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + elif rule_bases.fuzzy_type() == fs.FUZZY_SETS.gt2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + else: + aux.append(rule_bases[ix].compute_rule_antecedent_memberships(X) * np.expand_dims(actual_moment, axis=1)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1)
+ + +
[docs] def winning_rule_predict(self, X: np.array, time_moments: int) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = [] + for ix, mrb in enumerate(self.time_mrule_bases): + for jx, rb in enumerate(mrb): + for rule in rb: + consequents.append(jx) + + # consequents = sum([[ix]*len(self[ix].get_rules()) + # for ix in range(len(self.rule_bases))], []) # The sum is for flatenning + firing_strengths = self.compute_firing_strenghts(X, time_moments) + + if self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.t2 or self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(self.get_scores(), axis=1) * firing_strengths + else: + association_degrees = self.get_scores() * firing_strengths + + + winning_rules = np.argmax(association_degrees, axis=1) + + return np.array([consequents[ix] for ix in winning_rules])
+ + +
[docs] def add_rule_base(self, rule_base: rl.RuleBase, time: int) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.time_mrule_bases[time].add_rule_base(rule_base)
+ + +
[docs] def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + ''' + res = '' + for zx, time in enumerate(self.time_mrule_bases): + res += 'Rules for time step: ' + self.time_step_names[zx] + '\n' + res += '----------------\n' + for ix, ruleBase in enumerate(time): + res += 'Consequent: ' + time.consequent_names[ix] + '\n' + res += ruleBase.print_rules(True) + res += '\n' + res += '----------------\n' + + if return_rules: + return res + else: + print(res)
+ + +
[docs] def get_rules(self) -> list[rl.RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for mruleBase in self.rule_bases for rule in mruleBase.get_rules()]
+ + +
[docs] def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.time_mrule_bases[0].rule_bases[0].fuzzy_type()
+ + +
[docs] def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for mruleBase in self.time_mrule_bases: + mruleBase.purge_rules(tolerance)
+ + + def __getitem__(self, item: int) -> rl.RuleBase: + ''' + Returns the corresponding time rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.time_mrule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.time_mrule_bases) + + +
[docs] def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([x.get_consequents() for ix, x in enumerate(self.time_mrule_bases)], [])
+ + +
[docs] def get_rulebases(self) -> list[rl.RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + rule_bases = [] + + for ruleBase in self.time_mrule_bases: + for rule in ruleBase: + rule_bases.append(rule) + + return rule_bases
+ + + def _winning_rules(self, X: np.array, temporal_moments: list[int]) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + + firing_strengths = self.compute_firing_strenghts(X, temporal_moments) + + association_degrees = self.get_scores() * firing_strengths + + if (self[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + association_degrees = np.mean(association_degrees, axis=2) + elif self[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(association_degrees, axis=3) + + winning_rules = np.argmax(association_degrees, axis=1) + + return winning_rules
+ + +#### DEFINE THE FUZZY CLASSIFIER USING TEMPORAL FUZZY SETS #### +
[docs]class TemporalFuzzyRulesClassifier(evf.BaseFuzzyRulesClassifier): + ''' + Class that is used as a classifier for a fuzzy rule based system with time dependencies. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_class: int=None, precomputed_rules: rl.MasterRuleBase =None, runner: int=1) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + + kwargs: + - n_classes: number of classes to predict. Default deduces from data. + ''' + super().__init__(nRules, nAnts, fuzzy_type, tolerance, n_linguist_variables, verbose, linguistic_variables, domain, n_class) + + + def _contruct_tempRuleBase(self, problems, best_individuals): + ruleBase_temp = [] + + for problem, subject in zip(problems, best_individuals): + ruleBase_time_moment = problem._construct_ruleBase(subject, + self.fuzzy_type) + ruleBase_temp.append(ruleBase_time_moment) + + return ruleBase_temp + + + def _fix_time(self, lvs: list[temporalFuzzyVariable], time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variables. + + :param lvs: list of temporal fuzzy variables. + :param time: integer. Time moment to fix. + :return: None. The time is fixed. + ''' + for lv in lvs: + lv.fix_time(time) + + +
[docs] def fit(self, X: np.array, y: np.array, n_gen:int=50, pop_size:int=10, time_moments: np.array=None, checkpoints:int=10): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: None. The classifier is fitted to the data. + ''' + problems = [] + for ix in range(len(np.unique(time_moments))): + X_problem = X[time_moments == ix] + y_problem = y[time_moments == ix] + time_moments_problem = time_moments[time_moments == ix] + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = evf.FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, time_moments=time_moments_problem, + n_classes=self.n_class, thread_runner=self.thread_runner) + else: + import copy + time_lvs = [copy.deepcopy(aux) for aux in self.lvs] + self._fix_time(time_lvs, ix) + # If Fuzzy variables are already precomputed. + problem = evf.FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, + linguist_variables=time_lvs, domain=self.domain, tolerance=self.tolerance, time_moments=time_moments_problem, + n_classes=self.classes_, thread_runner=self.thread_runner) + + problems.append(problem) + + + + best_individuals = [] + self.performance = {} + for time, problem in enumerate(problems): + algorithm = GA( + pop_size=pop_size, + sampling=IntegerRandomSampling(), + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + eliminate_duplicates=True) + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, round(res.pop.get('F').mean(), 8), round(res.pop.get('F').min(), 8))) + if k % checkpoints == 0: + with open("checkpoint_" + str(time) + '_' + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_full_evaluation() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + best_individuals.append(best_individual) + + if self.verbose: + print('Rule based fit for time ' + str(time) + ' completed.') + + + self.performance[time] = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + + ruleBase_temp = self._contruct_tempRuleBase(problems, best_individuals) + + self.rule_base = temporalMasterRuleBase(ruleBase_temp) + + self.eval_performance = evr.evalRuleBase(self.rule_base, np.array(X), y, time_moments) + + self.eval_performance.add_full_evaluation() + self.rename_fuzzy_variables() + self.rule_base.purge_rules(self.tolerance)
+ + +
[docs] def forward(self, X: np.array, time_moments: list[int] = None) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :param time_moments: list of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a numpy array + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X, time_moments)
+ + + +
[docs] def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv)
+ + +
[docs] def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix()
+ +
[docs]def eval_temporal_fuzzy_model(fl_classifier: evf.BaseFuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, time_moments: list[int] = None, test_time_moments: list[int] = None, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + + if print_accuracy: + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.forward(X_train, time_moments))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.forward(X_test, test_time_moments))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.forward(X_train, time_moments)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.forward(X_test, test_time_moments)))) + print('------------') + + for ix in np.unique(time_moments): + try: + X_aux = X_train[time_moments == ix, :] + X_aux_test = X_test[time_moments == ix, :] + except pd.core.indexing.InvalidIndexError: + X_aux = X_train.iloc[time_moments == ix, :] + X_aux_test = X_test.iloc[test_time_moments == ix, :] + + y_aux = y_train[time_moments == ix] + y_aux_test = y_test[test_time_moments == ix] + + if print_matthew: + print('MOMENT ' + str(ix)) + print('------------') + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_aux, fl_classifier.forward(X_aux, np.array([ix] * X_aux.shape[0]))))) + print('Test performance: ' + + str(matthews_corrcoef(y_aux_test, fl_classifier.forward(X_aux_test, np.array([ix] * X_aux_test.shape[0]))))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier) + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res + else: + print(res)
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/utils.html b/docs/build/html/_modules/ex_fuzzy/utils.html new file mode 100644 index 0000000..80a7773 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/utils.html @@ -0,0 +1,626 @@ + + + + + + ex_fuzzy.utils — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.utils

+# -*- coding: utf-8 -*-
+"""
+Functions that are not fuzzy-specific, but util for some computations. 
+Dedicated mostly to compute quantiles for fuzzy partitions.
+
+"""
+import numpy as np
+import pandas as pd
+
+try:
+    from . import fuzzy_sets as fs
+    from . import maintenance as mnt
+    from . import temporal
+except ImportError:
+    import fuzzy_sets as fs
+    import maintenance as mnt
+    import temporal
+
+
+from sklearn.model_selection import train_test_split
+
+
+
[docs]def quartile_compute(x: np.array) -> list[float]: + ''' + Computes the quartiles for each feature. + + :param x: array samples x features + :return: list of quartiles for each feature + ''' + return np.quantile(x, [0, 0.25, 0.5, 1], axis=0)
+ + +
[docs]def fixed_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles for each feature in numpy array. + Quantiles: [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1], axis=0)
+ + +
[docs]def partition3_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles partitioning the variable in 3 cases. + + Quantiles: [0.00, 0.20, 0.50, 0.80, 1.00] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.50, 0.80, 1.00], axis=0)
+ + +
[docs]def t1_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 4, 4). + ''' + + + n_partitions = 4 + trap_memberships_size = 4 + quantile_numbers = fixed_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == n_partitions - 1: + partition_parameters[:, partition, 0] = quantile_numbers[-3] + partition_parameters[:, partition, 1] = quantile_numbers[-2] + partition_parameters[:, partition, 2] = quantile_numbers[-1] + partition_parameters[:, partition, 3] = quantile_numbers[-1] + else: + pointer = 1 if partition == 1 else 4 + partition_parameters[:, partition, 0] = quantile_numbers[pointer] + partition_parameters[:, partition, + 1] = quantile_numbers[pointer + 1] + partition_parameters[:, partition, + 2] = quantile_numbers[pointer + 2] + partition_parameters[:, partition, + 3] = quantile_numbers[pointer + 3] + + return partition_parameters
+ + +
[docs]def t1_three_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == 1: + partition_parameters[:, partition, 0] = quantile_numbers[1] + partition_parameters[:, partition, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3] = quantile_numbers[3] + else: + partition_parameters[:, partition, 0] = quantile_numbers[2] + partition_parameters[:, partition, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2] = quantile_numbers[4] + partition_parameters[:, partition, 3] = quantile_numbers[4] + + return partition_parameters
+ + +
[docs]def t2_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in three trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4, 2). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size, 2)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0, 1] = quantile_numbers[0] + partition_parameters[:, partition, 1, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2, 1] = quantile_numbers[1] + partition_parameters[:, partition, 3, 1] = quantile_numbers[2] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1, 0] = quantile_numbers[0] + partition_parameters[:, partition, 2, 0] = quantile_numbers[1] + partition_parameters[:, partition, 3, 0] = quantile_numbers[1] + \ + 0.9 * (quantile_numbers[2] - quantile_numbers[1]) + + elif partition == 1: + partition_parameters[:, partition, 0, 1] = quantile_numbers[1] + partition_parameters[:, partition, 1, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 1] = ( + quantile_numbers[2] + quantile_numbers[3]) / 2 + partition_parameters[:, partition, 3, 1] = quantile_numbers[3] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[1] + \ + 0.1 * (quantile_numbers[2] - quantile_numbers[1]) + partition_parameters[:, partition, 1, 0] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 0] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3, 0] = quantile_numbers[2] + \ + 0.9 * (quantile_numbers[3] - quantile_numbers[2]) + + else: + partition_parameters[:, partition, 0, 1] = quantile_numbers[2] + partition_parameters[:, partition, 1, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2, 1] = quantile_numbers[4] + partition_parameters[:, partition, 3, 1] = quantile_numbers[4] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[2] + \ + 0.1 * (quantile_numbers[3] - quantile_numbers[2]) + partition_parameters[:, partition, 1, 0] = quantile_numbers[3] + partition_parameters[:, partition, 2, 0] = quantile_numbers[4] + partition_parameters[:, partition, 3, 0] = quantile_numbers[4] + + return partition_parameters
+ + +
[docs]def t1_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + tripartition_names = ['Low', 'Medium', 'High'] + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t1_three_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.FS(tripartition_names[ix], fz_memberships[fz_parameter, ix, :], [ + mins[fz_parameter], maxs[fz_parameter]]) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res
+ + +
[docs]def t2_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using iv fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t2_simple_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.IVFS(str(ix), fz_memberships[fz_parameter, ix, :, 0], fz_memberships[fz_parameter, ix, :, 1], [ + mins[fz_parameter], maxs[fz_parameter]], lower_height=0.8) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res
+ + +
[docs]def gt2_fuzzy_partitions_dataset(x0: np.array, resolution_exp:int=1) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using gt2 fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :param resolution_exp: exponent of the resolution of the partition. Default is -2, which means 0.01. (Number of significant decimals) + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + iv_simple_partition = t2_fuzzy_partitions_dataset(x) + resolution = 10.0**-np.abs(resolution_exp) + res = [] + # We iterate through all possible variables + for ix_var, fz_var in enumerate(iv_simple_partition): + domain_resolution = np.arange( + mins[ix_var], maxs[ix_var] + resolution, resolution) + fzs = [] + for ix_lv, fz_lv in enumerate(fz_var.get_linguistic_variables()): + memberships = fz_lv.membership(domain_resolution) + fs_domain = {} + for ix_z, x in enumerate(domain_resolution): + membership_z = memberships[ix_z] + fs_domain[x] = fs.FS(str(x), [membership_z[0], np.mean( + membership_z), np.mean(membership_z), membership_z[1]], [0.0, 1.0]) + + fzs.append(fs.GT2(fz_lv.name, fs_domain, [ + mins[ix_var], maxs[ix_var]], significant_decimals=np.abs(resolution_exp), unit_resolution=0.01)) + + res.append(fs.fuzzyVariable(fv_names[ix_var], fzs)) + + return res
+ + +
[docs]def construct_partitions(X : np.array, fz_type_studied:fs.FUZZY_SETS) -> list[fs.fuzzyVariable]: + ''' + Returns a list of linguistic variables according to the kind of fuzzy specified. + + :param X: numpy array|pandas dataframe, shape samples x features. + :param fz_type_studied: fuzzy set type studied. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['precompute_labels'] += 1 + mnt.usage_data[mnt.usage_categories.FuzzySets][fz_type_studied.name] += 1 + + if fz_type_studied == fs.FUZZY_SETS.t1: + precomputed_partitions = t1_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.t2: + precomputed_partitions = t2_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.gt2: + precomputed_partitions = gt2_fuzzy_partitions_dataset(X) + + return precomputed_partitions
+ + +
[docs]def construct_conditional_frequencies(X: np.array, discrete_time_labels: list[int], initial_ffss: list[fs.FS]): + ''' + Computes the conditional temporal function for a set of fuzzy sets according to their variation in time. + + :param X: numpy array, shape samples x features. + :param discrete_time_labels: discrete time labels. + :param initial_fs: initial fuzzy set list. + :return: conditional frequencies. Array shape (time steps, initial fuzzy sets) + ''' + obs = X.shape[0] + discrete_time_labels = np.array(discrete_time_labels) + memberships = np.zeros((obs, len(initial_ffss))) + for ix, fset in enumerate(initial_ffss): + if fset.type() == fs.FUZZY_SETS.t2: + memberships[:, ix] = np.mean(fset.membership(X), axis=1) + elif fset.type() == fs.FUZZY_SETS.gt2: + memberships[:, ix] = np.mean(np.squeeze(fset._alpha_reduction(fset.membership(X))), axis=1) + else: + memberships[:, ix] = fset.membership(X) + + max_memberships = np.argmax(memberships, axis=1) + res = np.zeros((len(np.unique(discrete_time_labels)), len(initial_ffss))) + + for time in range(len(np.unique(discrete_time_labels))): + + relevant_memberships = max_memberships[time == discrete_time_labels] + fs_winner_counter = np.zeros(len(initial_ffss)) + for ix, fset in enumerate(initial_ffss): + fs_winner_counter[ix] = np.sum(relevant_memberships == ix) + + res[time, :] = fs_winner_counter + + return res / (np.max(res, axis=0) + 1e-6)
+ + +
[docs]def classify_temp(dates: pd.DataFrame, cutpoints: tuple[str, str], time: str) -> np.array: + ''' + Classifies a set of dates according to the temporal cutpoints. Uses {time} as a the time resolution. + Returns an array where true values are those values contained between those two date points. + + :param dates: data observations to cut. + :param cutpoints: points to check. + :param time: time field to use as the criteria. + :return: boolean array. True values are those contained between the cutpoints. + ''' + + def extract_hour(row): + return row.__getattribute__(time) + + hours = pd.to_datetime(dates['date']).apply(extract_hour) + + cutpoint_series_0 = pd.to_datetime(pd.Series([cutpoints[0]] * len(dates))) + cutpoint_series_0.index = dates.index + hours0 = cutpoint_series_0.apply(extract_hour) + + cutpoint_series_1 = pd.to_datetime(pd.Series([cutpoints[1]] * len(dates))) + cutpoint_series_1.index = dates.index + hours1 = cutpoint_series_1.apply(extract_hour) + + condicion1 = hours >= hours0 + condicion2 = hours <= hours1 + + return np.array(np.logical_and(condicion1, condicion2))
+ + +
[docs]def assign_time(a: np.array, observations: list[np.array]) -> int: + ''' + Assigns a temporal moment to a set of observations. + + :param a: array of boolean values. + :param observations: list of boolean arrays with the corresponding timestamps. + :return: the index of the correspondent time moment for the a-th observation. + :raises: ValueError if a is not timestamped in any of the observation arrays.''' + for ix, obs in enumerate(observations): + if obs[a]: + return ix + + raise ValueError('No temporal moment assigned')
+ + +
[docs]def create_tempVariables(X_train: np.array, time_moments: np.array, precomputed_partitions: list[fs.fuzzyVariable]) -> list[temporal.temporalFS]: + ''' + Creates a list of temporal fuzzy variables. + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of temporal fuzzy variables. + ''' + temp_partitions = [] + for ix in range(X_train.shape[1]): + feat_conditional = construct_conditional_frequencies(X_train[:, ix], time_moments, initial_ffss=precomputed_partitions[ix]) + temp_fs_list = [] + for vl in range(feat_conditional.shape[1]): + vl_temp_fs = temporal.temporalFS(precomputed_partitions[ix][vl], feat_conditional[:, vl]) + temp_fs_list.append(vl_temp_fs) + + temp_fs_variable = temporal.temporalFuzzyVariable(precomputed_partitions[ix].name, temp_fs_list) + temp_partitions.append(temp_fs_variable) + + return temp_partitions
+ + +
[docs]def create_multi_tempVariables(X_train: np.array, time_moments: np.array, fuzzy_type: fs.FUZZY_SETS) -> list[list[temporal.temporalFS]]: + ''' + Creates a of list of lists of temporal fuzzy variables. Each corresponds to a fuzzy partition in a different moment in time. + (So, instead of having one vl for all time moments, you have one different for each time moment that represents the same idea) + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of lists of temporal fuzzy variables. + ''' + temp_partitions = [] + + unique_time_moments = np.unique(time_moments) + for time in unique_time_moments: + X_obs = X_train[time_moments == time, :] + precomputed_partitions = construct_partitions(X_obs, fuzzy_type) + + temp_partitions.append(create_tempVariables(X_obs, time_moments[time_moments == time], precomputed_partitions)) + + return temp_partitions
+ + +
[docs]def temporal_cuts(X: pd.DataFrame, cutpoints: list[tuple[str, str]], time_resolution: str='hour') -> list[np.array]: + ''' + Returns a list of boolean indexes for each temporal moment. Performs the cuts between time steps using the cutpoints list. + + :param X: data observations to cut in temrporal moments. + :param temporal_moments: list of temporal moments to cut. + :param cutpoints: list of tuples with the cutpoints for each temporal moment. + :param time_resolution: time field to use as the criteria. + :return: list of boolean arrays. True values are those contained between the cutpoints in each moment. + ''' + + res = [] + for ix, cutpoint in enumerate(cutpoints): + observations = classify_temp(X, cutpoint, time=time_resolution) + res.append(observations) + + return res
+ + +
[docs]def temporal_assemble(X: np.array, y:np.array, temporal_moments: list[np.array]): + ''' + Assembles the data in the temporal moments in order to have partitions with balanced time moments in each one. + + :param X: data observations. + :param y: labels. + :param temporal_moments: list of boolean arrays. True values are those contained between the cutpoints in each moment. + :return: tuple of lists of data and labels for each temporal moment. + First tuple is: X_train, X_test, y_train, y_test + Second tuple is: train temporal moments, test temporal moments. + ''' + moments_partitions = [] + train_temporal_boolean_markers = [] + test_temporal_boolean_markers = [] + train_counter = 0 + test_counter = 0 + + for ix, temporal_moment in enumerate(temporal_moments): + X_train, X_test, y_train, y_test = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + moments_partitions.append((X_train, X_test, y_train, y_test)) + + if isinstance(X_train,(pd.core.series.Series,pd.DataFrame)): + X_train = pd.concat([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = pd.concat([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + else: + X_train = np.concatenate([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = np.concatenate([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + + for ix, temporal_moment in enumerate(temporal_moments): + # Believe, this makes sense to avoid rounding errrors in the size of the final vector + _, _, y_train0, y_test0 = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + + train_moment_observations = np.zeros((X_train.shape[0])) + train_moment_observations[train_counter:train_counter+len(y_train0)] = 1 + train_counter += len(y_train0) + train_temporal_boolean_markers.append(train_moment_observations) + + test_moment_observations = np.zeros((X_test.shape[0])) + test_moment_observations[test_counter:test_counter+len(y_test0)] = 1 + test_counter += len(y_test0) + test_temporal_boolean_markers.append(test_moment_observations) + + + return [X_train, X_test, y_train, y_test], [train_temporal_boolean_markers, test_temporal_boolean_markers]
+ + +
[docs]def extend_fuzzy_sets_enum(new_fuzzy_sets_enum: fs.FUZZY_SETS) -> list[fs.FUZZY_SETS]: + ''' + Extends the fuzzy sets enum with additional types. + + :param fuzzy_sets_enum: fuzzy sets enum. + :return: extended fuzzy sets enum. + ''' + import enum + NEW_FUZZY_SETS = enum.Enum( + "FUZZY_SETS", + [(es.name, es.value) for es in fs.FUZZY_SETS] + [(es.name, es.value) for es in new_fuzzy_sets_enum] + ) + fs.FUZZY_SETS = NEW_FUZZY_SETS
+
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/ex_fuzzy/vis_rules.html b/docs/build/html/_modules/ex_fuzzy/vis_rules.html new file mode 100644 index 0000000..8278d74 --- /dev/null +++ b/docs/build/html/_modules/ex_fuzzy/vis_rules.html @@ -0,0 +1,419 @@ + + + + + + ex_fuzzy.vis_rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +

Source code for ex_fuzzy.vis_rules

+# -*- coding: utf-8 -*-
+"""
+This is a the source file that contains the functions necessary to visualize the set of rules.
+"""
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import networkx as nx
+
+try:
+    from . import rules
+    from . import evolutionary_fit as evf
+    from . import fuzzy_sets as fs
+    from . import maintenance as mnt
+except ImportError:
+    import rules
+    import evolutionary_fit as evf
+    import fuzzy_sets as fs
+    import maintenance as mnt
+
+
+def _column_histogram(rule_matrix: np.array) -> dict:
+    '''
+    Computes the histogram for all the unique values in a column.
+
+    :param rule_matrix: vector with the numerical values.
+    :return: dictionary with the histogram.
+    '''
+    res = {}
+    for x in np.unique(rule_matrix):
+        if x != -1:
+            res[x] = np.sum(rule_matrix == x)
+
+    return res
+
+
+def _histogram(rule_matrix: np.array) -> list[dict]:
+    '''
+    Returns a list with the histogram for each antecedent according to linguist variables.
+
+    :param rule_matrix: matrix with the rules.
+    :return: list with the histogram in dictionary format for each antecedent.
+    '''
+    res = []
+
+    for column_ix in range(rule_matrix.shape[1]):
+        res.append(_column_histogram(rule_matrix[:, column_ix]))
+
+    return res
+
+
+def _max_values(appearances: list) -> tuple[int, int]:
+    '''
+    Returns the antecedent and its linguistic value most repeated.
+
+    :param appearances: list with the histogram for each antecedent.
+    :return: tuple with the antecedent and its linguistic value most repeated.
+    '''
+    res = 0
+    antecedent = None
+    vl = None
+
+    for ix, apperances_an in enumerate(appearances):
+        for key, value in apperances_an.items():
+            if value > res:
+                res = value
+                antecedent = ix
+                vl = key
+
+    return antecedent, vl
+
+
+
[docs]def create_graph_connection(rules, possible_vl): + ''' + Returns a square matrix where each number indicates if two nodes are connected. + Connectes by checking if both are in the same rule. + + :param rules: list with the rules. + :param possible_vl: number of linguistic variables. + :return: square matrix where each number indicates if two nodes are connected. + ''' + def generate_index(ant, vl0): return int(possible_vl * ant + vl0) + res = np.zeros( + (possible_vl * rules.shape[1], possible_vl * rules.shape[1])) + + for rule in rules: + for antecedent, vl in enumerate(rule): + if vl > -1: + for antecedent2, vl2 in enumerate(rule): + if vl2 > -1: + res_index1 = generate_index(antecedent, vl) + res_index2 = generate_index(antecedent2, vl2) + + res[res_index1, res_index2] += 1 + + return res / 2
+ + + + + +
[docs]def connect_rulebase(rulebase: rules.RuleBase) -> list[np.array]: + ''' + Connects antecedents connected by checking if both are in the same rule. + + :param rulebase: Rule base to connect. + :return: List of pandas dataframes with the connections in adjacency matrix format. + ''' + + # We choose those rules to explain, as those who have the most common antecedent. + rule_matrix = rules.list_rules_to_matrix(rulebase.rules) + res = [] + antecedents_names = [ + x.name + ' ' + y for x in rulebase.antecedents for y in rulebase.antecedents[0].linguistic_variable_names()] + + while rule_matrix.shape[0] > 0: + rules_to_viz = rule_matrix[choose_popular_rules(rule_matrix), :] + rule_matrix = rule_matrix[( + 1 - choose_popular_rules(rule_matrix)).astype(bool), :] + + graph_rule = create_graph_connection(rules_to_viz, len( + rulebase.antecedents[0].linguistic_variable_names())) + res.append(pd.DataFrame( + graph_rule, columns=antecedents_names, index=antecedents_names)) + + return res
+ + +
[docs]def connect_master_rulebase(mrule_base: rules.MasterRuleBase) -> list[list[np.array]]: + ''' + Connects antecedents connected by checking if both are in the same rule. + + :param mrule_base: Master rule base to connect. + :return: List of list of pandas dataframes with the connections in adjacency matrix format. + ''' + res = [] + for rule_base in mrule_base.rule_bases: + res.append(connect_rulebase(rule_base)) + + return res
+ + +
[docs]def visualize_rulebase(mrule_base: rules.MasterRuleBase, export_path: str = None) -> None: + ''' + Visualize a rule base using low, medium and high partitions with 1 rule in common -> 1 edge connections. + + :param mrule_base: Master rule base to visualize. + :param export_path: Path to export the graph. + ''' + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Visualization]['plot_graph'] += 1 + + def color_func(a): + ''' + Returns the color of the node according to the linguistic variable. + + :param a: Node name. + :return: Color of the node. + ''' + node_colors = ['blue', 'yellow', 'red'] + + if ' L' in a: + return node_colors[0] + elif ' M' in a: + return node_colors[1] + else: + return node_colors[2] + + def vl_prune(a): return a.replace('High', 'H').replace( + 'Medium', 'M').replace('Low', 'L').strip() + + if isinstance(mrule_base, evf.BaseFuzzyRulesClassifier): + mrule_base = mrule_base.rule_base + + connected_mrule_base = connect_master_rulebase(mrule_base) + + for ix, connected_rule_base in enumerate(connected_mrule_base): + for jx, rule in enumerate(connected_rule_base): + G = nx.from_pandas_adjacency(rule) + isolated_nodes = [ + node for node in G.nodes() if G.degree(node) == 0] + G.remove_nodes_from(isolated_nodes) + auto_edges = nx.selfloop_edges(G) + G.remove_edges_from(auto_edges) + + new_node_names = [vl_prune(node) for node in G.nodes()] + mapping = dict(zip(G, new_node_names)) + G = nx.relabel_nodes(G, mapping) + + if jx == 0: + G_final = G + else: + G_final = nx.compose(G_final, G) + + fig, ax = plt.subplots() + try: + os = nx.nx_agraph.graphviz_layout(G_final, prog='sfdp') + except ImportError: + os = nx.kamada_kawai_layout(G_final) + + node_colors = [color_func(node) for node in G_final.nodes()] + nx.draw(G_final, with_labels=True, ax=ax, + pos=os, node_color=node_colors) + plt.title('Consequent: ' + str(ix)) + fig.show() + + if export_path is not None: + nx.write_gexf(G_final, export_path + + '/consequent_' + str(ix) + '.gexf')
+ + +
[docs]def plot_fuzzy_variable(fuzzy_variable: fs.fuzzyVariable) -> None: + ''' + Plots a fuzzy variable using trapezoidal membership functions. + + :param fuzzy_variable: a fuzzy variable from the fuzzyVariable class in fuzzy_set module. + :return: None + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Visualization]['plot_fuzzy_variable'] += 1 + + if fuzzy_variable.linguistic_variables[0].type() != fs.FUZZY_SETS.gt2: + fig, ax = plt.subplots() + else: + fig = plt.figure() + ax = plt.axes(projection='3d') + + memberships = [0, 1, 1, 0] + + colors = ['b', 'r', 'g', 'orange', 'y'] + for ix, fuzzy_set in enumerate(fuzzy_variable.linguistic_variables): + name = fuzzy_set.name + initiated = False + fz_studied = fuzzy_set.type() + + if fz_studied == fs.FUZZY_SETS.t1: + ax.plot(fuzzy_set.membership_parameters, + memberships, colors[ix], label=name) + elif fz_studied == fs.FUZZY_SETS.t2: + ax.plot(fuzzy_set.secondMF_lower, np.array(memberships) * fuzzy_set.lower_height, colors[ix], label=name) + ax.plot(fuzzy_set.secondMF_upper, np.array(memberships), colors[ix]) + elif fz_studied == fs.FUZZY_SETS.gt2: + for key, value in fuzzy_set.secondary_memberships.items(): + + gt2_memberships = value(fuzzy_set.sample_unit_domain) + key_plot = [float(key)]*sum(gt2_memberships > 0) + if initiated: + ax.plot(key_plot, fuzzy_set.sample_unit_domain[gt2_memberships > 0], gt2_memberships[gt2_memberships > 0], color=colors[ix]) + else: + ax.plot(key_plot, fuzzy_set.sample_unit_domain[gt2_memberships > 0], gt2_memberships[gt2_memberships > 0], color=colors[ix], label=name) + initiated = True + + ax.legend(loc='upper right', shadow=True) + plt.title(fuzzy_variable.name) + fig.show()
+ + +
[docs]def matrix_rule_base_form(rule_base: rules.Rule) -> pd.DataFrame: + ''' + Returns a matrix with the rule base in the form of a matrix to visualize. + + :param mrule_base: Rule base to transform. + :return: Matrix with the rule base in the form of a matrix. + ''' + + n_rules = len(rule_base.rules) + antecedents = len(rule_base.antecedents) + + res = pd.DataFrame(np.zeros((n_rules, antecedents)), columns=[jx.name for jx in rule_base.antecedents]) + + for ix, rule in enumerate(rule_base): + for jx, antecedent in enumerate(rule_base.antecedents): + res.loc[ix, antecedent.name] = rule.antecedents[jx] + + return res
+ + +
[docs]def filter_useless_columns(df: pd.DataFrame) -> pd.DataFrame: + ''' + Filter columns with only one value. + + :param df: Dataframe to filter. + :return: Filtered dataframe. + ''' + for column in df.columns: + if df[column].unique()[0] == -1: + df.drop(column, axis=1, inplace=True) + + return df
+ + + +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/_modules/index.html b/docs/build/html/_modules/index.html new file mode 100644 index 0000000..6c09fd1 --- /dev/null +++ b/docs/build/html/_modules/index.html @@ -0,0 +1,126 @@ + + + + + + Overview: module code — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/build/html/_sources/api.rst.txt b/docs/build/html/_sources/api.rst.txt new file mode 100644 index 0000000..c9b6191 --- /dev/null +++ b/docs/build/html/_sources/api.rst.txt @@ -0,0 +1,21 @@ +API +=== + + +.. toctree:: + function_resume/fuzzy_sets + function_resume/rules + function_resume/eval_rules + function_resume/eval_tools + function_resume/vis_rules + function_resume/evolutionary_fit + function_resume/rule_mining + function_resume/classifiers + function_resume/persistence + function_resume/cognitive_maps + function_resume/utils + function_resume/centroid + function_resume/temporal + + + \ No newline at end of file diff --git a/docs/build/html/_sources/classifiers.rst.txt b/docs/build/html/_sources/classifiers.rst.txt new file mode 100644 index 0000000..f8c6029 --- /dev/null +++ b/docs/build/html/_sources/classifiers.rst.txt @@ -0,0 +1,23 @@ +.. _classifiers: + +Advanced classifiers +======================================= + +Besides ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``, it is possible to use the classifiers in the ``ex_fuzzy.classifiers`` module, +which contains classifiers that take the base classifier and combine it with other techniques. There are two main additions to the base classification +class: rule mining using support, confidence and lift measures; and using a double genetic tuning, so that first a large number of rules can be +considered as potential good rules, and then the second optimization step choose the best combination of them. + +The three kind of classifiers are: + +1. ``ex_fuzzy.classifiers.RuleMineClassifier``: first mines the rules by checking all the possible combinations of antecedents. It looks for rules that present a minumum of the quality measures, (support, confidence and lift) and then uses them as candidate rules to find an optimal subset of them. +2. ``ex_fuzzy.classifiers.FuzzyRulesClassifier``: performs a double genetic optimization. First, it finds a good rule base and then it uses it as the initial population for another round of genetic optimization. +3. ``ex_fuzzy.classifiers.RuleFineTuneClassifier``: combines both previous approaches. First, searchs for all rules that hold the quality metrics. Then, uses them as candidate rules and finds a good subset of them. Finally, uses that rulebase as initial population for another round of genetic optimization, which gives the final result. + +---------------------------- +Support, Confidence and lift +---------------------------- +1. Support: The definition of support is the percentage of appearance of the antecedent of a rule in the whole dataset. We compute it as the average of the membership values of that antecedent in each sample for the dataset. The membership for each sample to that antecedent is computed using the minimum t-norm in this case. +2. Confidence: is the ratio between the support of an antecedent for a particular class and for the whole dataset. +3. Lift: is the ratio between the confidence and the expected confidence. It is computed as the ratio between the confidence of the rule and the percentage of samples of the rule class in the dataset. + diff --git a/docs/build/html/_sources/extending.rst.txt b/docs/build/html/_sources/extending.rst.txt new file mode 100644 index 0000000..1c52d4b --- /dev/null +++ b/docs/build/html/_sources/extending.rst.txt @@ -0,0 +1,12 @@ +.. _extending: + +Extending Ex-Fuzzy +======================================= + +Some of the default behaviour/components can be easily extended to support more fuzzy/explainability tools. + +- Using other fuzzy sets: the whole library is programmed using object orientation, so that to extend some methods is to create classes that inherit from the correspondent classes. This is an easy way to implement additional to additional kinds of fuzzy sets. Nevertheless, as long as their membership values are numerical or 2-sized tuples, new fuzzy sets can be easily supported using the existing ``fs.FUZZY_SET`` enum. For example, ``fs.FUZZY_SET.t1`` expects a numerical membership value and ``fs.FUZZY_SET.t2`` expects a tuple. You can take a look at the ``ex_fuzzy.temporal`` for an example on how to do this. +- In order to use other partitions than those given by the ``ex_fuzzzy.utils`` module, you can directly create the necessary objects through ``fs.FS()`` objects and ``fs.fuzzyVariable()``. +- You can change the loss function used in the genetic optimization using the ``new_loss`` method of ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``. + + diff --git a/docs/build/html/_sources/function_resume/centroid.rst.txt b/docs/build/html/_sources/function_resume/centroid.rst.txt new file mode 100644 index 0000000..478cc81 --- /dev/null +++ b/docs/build/html/_sources/function_resume/centroid.rst.txt @@ -0,0 +1,5 @@ +T2 Centroid compute +==================== + +.. automodule:: ex_fuzzy.centroid + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/classifiers.rst.txt b/docs/build/html/_sources/function_resume/classifiers.rst.txt new file mode 100644 index 0000000..34e55f7 --- /dev/null +++ b/docs/build/html/_sources/function_resume/classifiers.rst.txt @@ -0,0 +1,5 @@ +Advanced Classifiers +==================== + +.. automodule:: ex_fuzzy.classifiers + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/cognitive_maps.rst.txt b/docs/build/html/_sources/function_resume/cognitive_maps.rst.txt new file mode 100644 index 0000000..6d9feb3 --- /dev/null +++ b/docs/build/html/_sources/function_resume/cognitive_maps.rst.txt @@ -0,0 +1,5 @@ +Fuzzy Cognitive Maps +==================== + +.. automodule:: ex_fuzzy.cognitive_maps + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/eval_rules.rst.txt b/docs/build/html/_sources/function_resume/eval_rules.rst.txt new file mode 100644 index 0000000..f8852d0 --- /dev/null +++ b/docs/build/html/_sources/function_resume/eval_rules.rst.txt @@ -0,0 +1,5 @@ +Rule Evaluation Functions +========================= + +.. automodule:: ex_fuzzy.eval_rules + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/eval_tools.rst.txt b/docs/build/html/_sources/function_resume/eval_tools.rst.txt new file mode 100644 index 0000000..8ca931f --- /dev/null +++ b/docs/build/html/_sources/function_resume/eval_tools.rst.txt @@ -0,0 +1,5 @@ +Classification evaluation tools +=============================== + +.. automodule:: ex_fuzzy.eval_tools + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/evolutionary_fit.rst.txt b/docs/build/html/_sources/function_resume/evolutionary_fit.rst.txt new file mode 100644 index 0000000..9a28064 --- /dev/null +++ b/docs/build/html/_sources/function_resume/evolutionary_fit.rst.txt @@ -0,0 +1,5 @@ +Evolutionary Algorithms to Fit the rules +======================================== + +.. automodule:: ex_fuzzy.evolutionary_fit + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/fuzzy_sets.rst.txt b/docs/build/html/_sources/function_resume/fuzzy_sets.rst.txt new file mode 100644 index 0000000..d1d6855 --- /dev/null +++ b/docs/build/html/_sources/function_resume/fuzzy_sets.rst.txt @@ -0,0 +1,5 @@ +Fuzzy Sets Functions +==================== + +.. automodule:: ex_fuzzy.fuzzy_sets + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/persistence.rst.txt b/docs/build/html/_sources/function_resume/persistence.rst.txt new file mode 100644 index 0000000..3a2d3f4 --- /dev/null +++ b/docs/build/html/_sources/function_resume/persistence.rst.txt @@ -0,0 +1,5 @@ +Classification persistence +=============================== + +.. automodule:: ex_fuzzy.persistence + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/rule_mining.rst.txt b/docs/build/html/_sources/function_resume/rule_mining.rst.txt new file mode 100644 index 0000000..788eab5 --- /dev/null +++ b/docs/build/html/_sources/function_resume/rule_mining.rst.txt @@ -0,0 +1,5 @@ +Rule Mining methods +==================== + +.. automodule:: ex_fuzzy.rule_mining + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/rules.rst.txt b/docs/build/html/_sources/function_resume/rules.rst.txt new file mode 100644 index 0000000..edd97d2 --- /dev/null +++ b/docs/build/html/_sources/function_resume/rules.rst.txt @@ -0,0 +1,5 @@ +Fuzzy Rules Functions +===================== + +.. automodule:: ex_fuzzy.rules + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/temporal.rst.txt b/docs/build/html/_sources/function_resume/temporal.rst.txt new file mode 100644 index 0000000..f96d95b --- /dev/null +++ b/docs/build/html/_sources/function_resume/temporal.rst.txt @@ -0,0 +1,5 @@ +Temporal fuzzy sets +==================== + +.. automodule:: ex_fuzzy.temporal + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/utils.rst.txt b/docs/build/html/_sources/function_resume/utils.rst.txt new file mode 100644 index 0000000..f995a05 --- /dev/null +++ b/docs/build/html/_sources/function_resume/utils.rst.txt @@ -0,0 +1,5 @@ +Partition utils +==================== + +.. automodule:: ex_fuzzy.utils + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/function_resume/vis_rules.rst.txt b/docs/build/html/_sources/function_resume/vis_rules.rst.txt new file mode 100644 index 0000000..d290d63 --- /dev/null +++ b/docs/build/html/_sources/function_resume/vis_rules.rst.txt @@ -0,0 +1,5 @@ +Rule Visualization +==================== + +.. automodule:: ex_fuzzy.vis_rules + :members: \ No newline at end of file diff --git a/docs/build/html/_sources/gt2.rst.txt b/docs/build/html/_sources/gt2.rst.txt new file mode 100644 index 0000000..ed9cefc --- /dev/null +++ b/docs/build/html/_sources/gt2.rst.txt @@ -0,0 +1,21 @@ +.. _gt2: + +General Type 2 +======================================= + +General Type 2 Fuzzy sets are fully supported, however, they present a series of additional considerations when used in real domains: + +- The resolution of the primary domain function is always capped at 4 significant decimals. +- When the domain of the secondary function are real numbers, precision is capped at 4 significant decimals. + +We believe that this precision can be enough for most applications, but in case it needs to be changed, it is enough to modify the ``fs.gt2.MAX_RES_SUPPORT`` constant to the desired number before instantiating the GT2 fuzzy set. + +Computing with the GT2 is more costly than the rest of the sets. Specially, computing the GT2 fuzzy partitions, which are also notably more complex than in the rest of the fuzzy sets. +Essentially, a GT2 fuzzy partition is a dictionary where each value in the dictionary maps a value in the secondary domain to a fuzzy set. +When a new value needs to be computed, the closest known value in the secondary membership to the new one is used. + +As an example, the function ``utils.gt2_fuzzy_partitions_dataset()`` returns a fuzzy partition using GT2 in the following manner: + +1. Computes a IV partition for all the variables. +2. Discretizes the domain of the secondary membership to an arbitrary precision. +3. In each of the discretized points, computes a FS using as parameters of the trapezoid function the lower and upper memberships and the central point of them. This results in a triangle for each FS. \ No newline at end of file diff --git a/docs/build/html/_sources/index.rst.txt b/docs/build/html/_sources/index.rst.txt new file mode 100644 index 0000000..0a27f9e --- /dev/null +++ b/docs/build/html/_sources/index.rst.txt @@ -0,0 +1,38 @@ +.. Ex-Fuzzy documentation master file, created by + sphinx-quickstart on Mon Jan 2 21:36:30 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Ex-Fuzzy's documentation! +==================================== + +**Ex-Fuzzy** is a library to perform fuzzy logic inference using fuzzy logic, with a special focus +on the explainable features of approximate reasoning. Different fuzzy sets are supported, and rules +are fitted to a dataset using genetic optimization. We also support fuzzy cognitive_maps. + +Check out the :doc:`usage` section for a few examples. + +.. toctree:: + + usage + step1 + step2 + step3 + step4 + precom + optimize + gt2 + tmpfs + extending + persistence + classifiers + api + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/build/html/_sources/optimize.rst.txt b/docs/build/html/_sources/optimize.rst.txt new file mode 100644 index 0000000..6c552f8 --- /dev/null +++ b/docs/build/html/_sources/optimize.rst.txt @@ -0,0 +1,29 @@ +.. _ga: + +Genetic algorithm details +======================================= + +The genetic algorithm searchs for the optimal rule base for a problem. The criteria used to determine optimal is the one mentioned in :ref:`step3`: + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Less antecedents: the less antecedents per rule, the better. We compute this using the average number of antecedents per rule. We to normalize this by dividing the number of antecedents per rule by the maximum allowed in the optimization) +3. Less rules: rule bases with less rules are prefered. We normalize this by dividing the number of rules present in the database with dominance score bigger than the minimum threshold by the possible number of rules allowed in the optimization. + +It is possible to use previously computed rulesin order to fine tune them. There are two ways to do this using the ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``: + +1. Use the previously computed rules as the initial population for a new optimization problem. In that case, you can pass that rules to the ``initial_rules`` parameter the ``ex_fuzzy.rules.MasterRuleBase`` object. +2. Look for more efficient subsets of rules in the previously computed rules. In this case the genetic optimization will use those rules as the search space itself, and will try to optimize the best subset of them. In that case, you can pass that rules to the ``candidate_rules`` parameter the ``ex_fuzzy.rules.MasterRuleBase`` object. + +--------------------------------------- +Limitations of the optimization process +--------------------------------------- + +- General Type 2 requires precomputed fuzzy partitions. +- When optimizing IV fuzzy partitions: Not all possible shapes of trapezoids all supported. Optimized trapezoids will always have max memberships for the lower and upper bounds in the same points. Height of the lower membership is optimized by scaling. Upper membership always reaches 1 at some point. + +---------------- +Fitness function +---------------- + +By default, the fitness function is the convex combination of the Matthew Correlation Coefficient (95%), to the rule size preference (2.5%) and to the rule antecedent size preference (2.5%). +For more information about changing this fitness function check :ref:`extending`. diff --git a/docs/build/html/_sources/persistence.rst.txt b/docs/build/html/_sources/persistence.rst.txt new file mode 100644 index 0000000..0da9564 --- /dev/null +++ b/docs/build/html/_sources/persistence.rst.txt @@ -0,0 +1,66 @@ +.. _persistence: + +Persistence +==================================== +Rules can be saved and loaded using plain text. The specification for this format is the same the print format of the rules. +We can extract the rules from a model using the ``ex_fuzzy.eval_tools.eval_fuzzy_model`` method, which can can return the rules in string format if the ``return_rules`` parameter is set to ``True``:: + + + + import pandas as pd + + from sklearn import datasets + from sklearn.model_selection import train_test_split + + import sys + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + import ex_fuzzy.persistence as persistence + import ex_fuzzy.vis_rules as vis_rules + + n_gen = 5 + n_pop = 30 + nRules = 15 + nAnts = 4 + vl = 3 + fz_type_studied = fs.FUZZY_SETS.t1 + + # Import some data to play with + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + # Split the data into a training set and a test set + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + + # We create a FRBC with the precomputed partitions and the specified fuzzy set type, + fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1) + + str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) + + # Save the rules as a plain text file + with open('rules_iris_t1.txt', 'w') as f: + f.write(str_rules) + + + +The rules can be loaded from a file using the ``load_rules`` method of the ``FuzzyModel`` class:: + + # Load the rules from a file + mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions) + + fl_classifier = GA.FuzzyRulesClassifier(precomputed_rules=mrule_base) + +If we already created the ``FuzzyRulesClassifier`` object, we can load the rules using the ``load_master_rule_base`` method:: + + fl_classifier.load_master_rule_base(mrule_base) + +You can also save the best rulebase found each x steps of the genetic tuning if you set the ``checkpoint`` parameter to that x number of steps. + + \ No newline at end of file diff --git a/docs/build/html/_sources/precom.rst.txt b/docs/build/html/_sources/precom.rst.txt new file mode 100644 index 0000000..760769f --- /dev/null +++ b/docs/build/html/_sources/precom.rst.txt @@ -0,0 +1,20 @@ +.. _precom: + +Computing fuzzy partitions +======================================= + +One of the most typical ways to compute fuzzy partitions is to use quantiles of the data. The module ``utils`` contains a series of functions +to generate fuzzy partitions for all the supported kinds of fuzzy sets. +The easiest way to compute these partitions is with the ``utils.construct_partitions`` function, specifying the fuzzy set desired:: + + import utils + + fz_type_studied = fs.FUZZY_SETS.t2 + precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +-------------------------------- +About the precomputed partitions +-------------------------------- +Partitions computed using these method use three linguistic variables per fuzzy variable. We chose that number as it creates easily understandable +low, medium and high partitions. For the case of IV-fuzzy sets, the trapezoids constructed, both the lower and upper memberships +present 1 values in the same points. For the case of General Type 2 Fuzzy sets check :ref:`gt2`. diff --git a/docs/build/html/_sources/step1.rst.txt b/docs/build/html/_sources/step1.rst.txt new file mode 100644 index 0000000..349b6a6 --- /dev/null +++ b/docs/build/html/_sources/step1.rst.txt @@ -0,0 +1,52 @@ +.. _step1: + +Creating fuzzy sets and fuzzy variables +======================================= + +----------------- +Fuzzy Sets +----------------- +Ex-Fuzzy supports different kinds of fuzzy sets, but the procedure to use them all is the same. +Fuzzy sets have a name, a domain range and a membership function:: + + import ex_fuzzy.fuzzy_sets as fs + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + +This code creates a fuzzy set named "Cold", with a trapezoidal membership function and a domain that ranges from 0 to 40 degrees. +A fuzzy membership can be computed easily using the newly-created fuzzy set:: + + cold(8.2) + +This would be the code to do the same thing using interval-valued fuzzy sets:: + + cold2 = fs.IVFS('Cold', [0, 0, 5, 10], [0, 0, 5, 15], [0,40], 0.8) + +This code would create an interval-valued fuzzy set defined using a lower and upper membership function, +the same domain and name as before, and a maximum certainty of 0.8 for the lower membership. +The membership is computed just as an ordinary fuzzy set:: + + cold2(8.2) + +We could use any of these kinds of fuzzy sets (or even general-type 2 fuzzy sets) to construct all the linguistic variables +for our temperature domain:: + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + warm = fs.FS('Warm', [15, 20, 25, 30] , [0,40]) + hot = fs.FS('Hot', [25, 30, 40, 40] , [0,40]) + +----------------- +Fuzzy Variables +----------------- +Once we have the linguistic variables, we can construct a fuzzy variable. A fuzzy variable consists of a list of fuzzy sets +of the same kind and a proper name:: + + temperature = fs.fuzzyVariable('Temperature', [cold, warm, hot]) + +We do not need to specify domain or fuzzy set type, because the ``fuzzyVariable`` class deduces it from the fuzzy sets given in the list. +We can use a ``fuzzyVariable`` object to compute the memberships for a value to all the linguistic variables in the fuzzy variable:: + + temperature(8.2) + +Once we have defined the fuzzy variables, we can use them to construct a fuzzy rule base. This step is described in :ref:`step2`. + diff --git a/docs/build/html/_sources/step2.rst.txt b/docs/build/html/_sources/step2.rst.txt new file mode 100644 index 0000000..6151d65 --- /dev/null +++ b/docs/build/html/_sources/step2.rst.txt @@ -0,0 +1,69 @@ +.. _step2: + +Using Fuzzy Rules +================= + +----------------- +Fuzzy Rules +----------------- +Fuzzy rules can be used to solve both regression and classification problems. + +The most straightforward way to construct a rule is to give a series of antecedents and a consequent. +For the case of classification, the consequent will be a class, and for regression, a fuzzy set. +Following the temperature example. Suppose we have these fuzzy sets as consequents to module +the use of air conditioner:: + + activate_small = fs.FS('Small', [0.0, 0.0, 0.1, 0.2], [0,1]) + activate_medium = fs.FS('Small', [0.1, 0.4, 0.4, 0.5], [0,1]) + activate_large = fs.FS('Small', [0.5, 0.8, 1.0, 1.0], [0,1]) + + activate = fs.fuzzyVariable('Activate', [activate_small, activate_medium, activate_large]) + +We can construct a rule for regression using the ``ex_fuzzy.rules.Rule`` class. +For example, the rule IF temperature IS hot THEN conditioner IS large can be implemented as:: + + import ex_fuzzy.rules as frule + frule.Rule([hot], activate_large) + +Then, we can use the ``membership`` method to obtain the degree of truth for a value in a rule, and the ``centroid`` method to +compute the centroid of the consequent. + +This implementation, however, can be problematic when there is a considerable number of rules with repeated antecedents, +because we do not want to compute the degree of truth for a value for the same antecedents over and over. So, instead +of using the ``Rule`` class, it is more practical to use ``RuleBase`` and ``RuleSimple`` classes. + +----------------- +Rule Bases +----------------- + +``RuleSimple`` is a class that simplifies the way in which rules are expressed. Its antecedents are expressed as a list, denoting the +linguistic variable relevant to the rule. The previous rule would be expressed as a ``RuleSimple`` as this:: + + my_rule = frule.RuleSimple([2], 2) + +The length of the first list is the number of antecedents, and the second argument denotes that the consequent fuzzy set is "activates_large". +``RuleSimple`` is used by ``RuleBase`` class to efficiently compute the degrees of truth for all the antecedents for all the data, +and then use them when necessary. In order to create one rule base, we need the list of all the fuzzy variables to use, the consequent +and the rules expressed as ``RuleSimple`` objects:: + + my_rulebase = frule.RuleBaseT1([temperature], [my_rule], activate) + +This is quite a simple case because we are using only one fuzzy variable and one rule, but the process is the same for more rules and variables. +Then, we can use "my_rule" using the ``inference`` method:: + + my_rulebase.inference(np.array([8.2])) + +Which will return the defuzzified result of the fuzzy inference process. The process is the same for the rest of the fuzzy sets, but other +classes are required: ``RuleBaseT2``, ``RuleBaseGT2``. + +--------------------------------------------- +Classification problems and Master Rule Bases +--------------------------------------------- +Up to now, we have discussed how to model a regression problem. Classification problems perform the inference in a different way, which require another kind of object: the ``ex_fuzzy.rules.MasterRuleBase``. +This is because the way in which Ex-Fuzzy handles classification problems is by using one Rule Base per consequent. +So, the ``rules.MasterRuleBase`` class is used to handle the rule bases created for each class. An object of this class is created using +a list of rule bases, and its main method is ``rules.MasterRuleBase.winning_rule_predict()`` which returns the class obtained from the rule with highest association degree. +You can find more the specifics of the classification inference in the next steps. + + +The next step is :ref:`step3`. diff --git a/docs/build/html/_sources/step3.rst.txt b/docs/build/html/_sources/step3.rst.txt new file mode 100644 index 0000000..7d5b4d0 --- /dev/null +++ b/docs/build/html/_sources/step3.rst.txt @@ -0,0 +1,68 @@ +.. _step3: + +Optimizing a Fuzzy rule base for a classification problem +========================================================= + +-------------------------------------- +Fuzzy rule based classifier +-------------------------------------- +Usually, in classification inference we compute the matching degree of a sample for each rule in the rule base +(we refer as "rule base" to both ``ex_fuzzy.rules.RuleBase`` and ``ex_fuzzy.rules.MasterRuleBase`` objects as they are conceptually equivalent). +Then, the predicted class is the consequent class of that rule. In this library, besides the matching degree, we also use a prior, the Dominance Scores, +that are multiplied by the matching degree. + +The Dominance Score is the product of the support and confidence of a rule, so that we rely more on those rules that are more general, and that +cover different patterns than those covered by other rules. + +For more info about the dominance scores, you can see [Fach23]. + +-------------------------------------- +Training a fuzzy rule based classifier +-------------------------------------- +In order to train a fuzzy rule based classifier, Ex-Fuzzy uses a Genetic algorithm to tune the rules to the +desired classification task. The interface to use this kind of classifiers is analogous to the standard used +in scikit-learn, so it requires no previous knowledge about fuzzy logic in order to work. + +For example, we load the iris dataset and split it in train and test:: + + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +Once the data has been loaded, we just need to create a classifier with the proper parameters, number of rules, +maximum number of antecedents per rule, number of linguist variables per fuzzy variable and tolerance, which will explained +in the evaluation part of this section:: + + + import ex_fuzzy.evolutionary_fit as GA + + fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + +These instructions will optimize the linguistic variables in each fuzzy variable, using IV fuzzy sets, using three linguistic variables and ten rules with up to four antecedents. +It is also possible to give a precomputed set of linguistic variables as a list of fuzzy variables. A convenient way to compute +these with easy can be found on the ``utils`` module, by means of the ``ex_fuzzy.utils.construct_partitions`` function. + +Once the classifier has been created, the next thing is tranining it. Since we are using a Genetic algorithm, we can specify the number +of generations and the population size:: + + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + +And then we can use forward or predict just as with a scikit-learn classifier. + +----------------- +Evaluation +----------------- +The genetic algorithm needs a fitness measure to evaluate the quality of each solution. In order to obtain the best possible set of rules, +Ex-Fuzzy uses three different criteria. + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Less antecedents: the less antecedents per rule, the better. +3. Less rules: rule bases with less rules are prefered. + +.. _references:: + [Fach23] Fumanal-Idocin, J., Andreu-Perez, J., Cord, O., Hagras, H., & Bustince, H. (2023). Artxai: Explainable artificial intelligence curates deep representation learning for artistic images using fuzzy techniques. IEEE Transactions on Fuzzy Systems. \ No newline at end of file diff --git a/docs/build/html/_sources/step4.rst.txt b/docs/build/html/_sources/step4.rst.txt new file mode 100644 index 0000000..fb88650 --- /dev/null +++ b/docs/build/html/_sources/step4.rst.txt @@ -0,0 +1,38 @@ +.. _step4: + +Visualize rules and results +=========================== +Ex-Fuzzy can also visualize the fuzzy sets and the rules obtained after the training process. +The easiest way to do this is using the ``eval_tools.eval_fuzzy_model`` function:: + + import eval_tools + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This function prints the performance of the model, prints the rules on screen and plot the rules as graphs. + +------------------- +Visualize Rules +------------------- + +You can visualize each consequent rules as a network, so that the interactions between the antecedents can be seen. + +.. image:: images/red_fuzzy.png + :width: 200 + +If the number of linguistic variables is three, they also get automatically colored. It is also possible to export them to the gephi software. + +-------------------- +Visualize Fuzzy Sets +-------------------- + +Each fuzzy set is also visualized according to its own kind. The same linguistic variable can be visualized using T1, IV and GT2 fuzzy sets: + +.. image:: images/ejemplo_t1.png + :width: 200 + +.. image:: images/ejemplo_t2.png + :width: 200 + +.. image:: images/example_gt2.png + :width: 200 \ No newline at end of file diff --git a/docs/build/html/_sources/tmpfs.rst.txt b/docs/build/html/_sources/tmpfs.rst.txt new file mode 100644 index 0000000..21aeb2c --- /dev/null +++ b/docs/build/html/_sources/tmpfs.rst.txt @@ -0,0 +1,57 @@ +.. _tempfs: + +Temporal Fuzzy Sets +======================================= + +Temporal Fuzzy Sets (TFS) are a generalization of fuzzy sets to include a temporal variable that influences the membership values. +A comprehensive explanation of such fuzzy sets can be found in [Kiah]. + +Temporal fuzzy sets thus require the additional temporal variable, which can be spceified in the dedicated functions that work with this kind of fuzzy sets. +The way in which is the temporal variable is used is by first discretizing the the temporal variable from a continuous into a discrete time space. For example, +our time variable is the seconds of the day, we can do the following to define the different stages of the day:: + + + cut_point_morning0 = '00:00:00' + cut_point_morning1 = '10:00:00' + cut_points_morning = [cut_point_morning0, cut_point_morning1] + cut_point_daytime0 = '11:00:00' + cut_point_daytime1 = '19:00:00' + cut_points_daytime = [cut_point_daytime0, cut_point_daytime1] + cut_point_evening0 = '20:00:00' + cut_point_evening1 = '23:00:00' + cutpoints_evening = [cut_point_evening0, cut_point_evening1] + +Once we have defined this cut points, there are various functions in the ``ex_fuzzy.utils`` module to assign each of the observatio to one of the temporal moments:: + + temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour') + time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])]) + +We can also partition the dataset equally in order to have balanced partitions in each of the temporal moments:: + + partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers) + X_train, X_test, y_train, y_test = partitions + train_markers, test_markers = partition_markers + + +Given the time moments and the original fuzzy partitions, we can convert them into temporal fuzzy partitions:: + + temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions) + +The temporal fuzzy partitions are then used to train the temporal fuzzy classifier:: + + X_train = X_train.drop(columns=['date']) + X_test = X_test.drop(columns=['date']) + fl_classifier = temporal.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, + linguistic_variables=temp_partitions, n_linguist_variables=3, + fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_classes=2) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments) + +The temporal fuzzy classifier can be evaluated using the ``eval_temporal_fuzzy_model`` function in the ``ex_fuzzy.eval_tools`` module:: + + eval_tools.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + time_moments=train_time_moments, test_time_moments=test_time_moments, + plot_rules=False, print_rules=True, plot_partitions=False) + + +.. _references:: + [Kiah] Kiani, M., Andreu-Perez, J., & Hagras, H. (2022). A Temporal Type-2 Fuzzy System for Time-dependent Explainable Artificial Intelligence. IEEE Transactions on Artificial Intelligence. \ No newline at end of file diff --git a/docs/build/html/_sources/usage.rst.txt b/docs/build/html/_sources/usage.rst.txt new file mode 100644 index 0000000..7e61702 --- /dev/null +++ b/docs/build/html/_sources/usage.rst.txt @@ -0,0 +1,34 @@ +.. _usage: + +Getting Started +==================================== + + +The most straightforward way to use Ex-Fuzzy is to fit a fuzzy rule based classifier to a dataset, and then explore the results and the rules obtained. +A couple of examples of this can be found in the "demos" folder. + +A brief piece of code that does this case of use is the following:: + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This code trains the classifier and also plots the rules, prints them on screen and show the linguistic variables optimized in the process. + +In the following, we will explain how the different processes to perform fuzzy inference are automated in this code, and how they can be perfomed manually. + +The next step is :ref:`step1`. diff --git a/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 0000000..8549469 --- /dev/null +++ b/docs/build/html/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,134 @@ +/* + * _sphinx_javascript_frameworks_compat.js + * ~~~~~~~~~~ + * + * Compatability shim for jQuery and underscores.js. + * + * WILL BE REMOVED IN Sphinx 6.0 + * xref RemovedInSphinx60Warning + * + */ + +/** + * select a different prefix for underscore + */ +$u = _.noConflict(); + + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/docs/build/html/_static/basic.css b/docs/build/html/_static/basic.css new file mode 100644 index 0000000..0889677 --- /dev/null +++ b/docs/build/html/_static/basic.css @@ -0,0 +1,930 @@ +/* + * basic.css + * ~~~~~~~~~ + * + * Sphinx stylesheet -- basic theme. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin: 10px 0 0 20px; + padding: 0; +} + +ul.search li { + padding: 5px 0 5px 20px; + background-image: url(file.png); + background-repeat: no-repeat; + background-position: 0 7px; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} +nav.contents, +aside.topic, + +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ +nav.contents, +aside.topic, + +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, + +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, + +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +/* Docutils 0.17 and older (footnotes & citations) */ +dl.footnote > dt, +dl.citation > dt { + float: left; + margin-right: 0.5em; +} + +dl.footnote > dd, +dl.citation > dd { + margin-bottom: 0em; +} + +dl.footnote > dd:after, +dl.citation > dd:after { + content: ""; + clear: both; +} + +/* Docutils 0.18+ (footnotes & citations) */ +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +/* Footnotes & citations ends */ + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dt:after { + content: ":"; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/docs/build/html/_static/css/badge_only.css b/docs/build/html/_static/css/badge_only.css new file mode 100644 index 0000000..c718cee --- /dev/null +++ b/docs/build/html/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/docs/build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.eot b/docs/build/html/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.svg b/docs/build/html/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/docs/build/html/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf b/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.woff b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/docs/build/html/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-bold-italic.woff b/docs/build/html/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold-italic.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 b/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-bold.woff b/docs/build/html/_static/css/fonts/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-bold.woff2 b/docs/build/html/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-bold.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-normal-italic.woff b/docs/build/html/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal-italic.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 b/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/docs/build/html/_static/css/fonts/lato-normal.woff b/docs/build/html/_static/css/fonts/lato-normal.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal.woff differ diff --git a/docs/build/html/_static/css/fonts/lato-normal.woff2 b/docs/build/html/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/docs/build/html/_static/css/fonts/lato-normal.woff2 differ diff --git a/docs/build/html/_static/css/theme.css b/docs/build/html/_static/css/theme.css new file mode 100644 index 0000000..19a446a --- /dev/null +++ b/docs/build/html/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/docs/build/html/_static/doctools.js b/docs/build/html/_static/doctools.js new file mode 100644 index 0000000..c3db08d --- /dev/null +++ b/docs/build/html/_static/doctools.js @@ -0,0 +1,264 @@ +/* + * doctools.js + * ~~~~~~~~~~~ + * + * Base JavaScript utilities for all Sphinx HTML documentation. + * + * :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ +"use strict"; + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + parent.insertBefore( + span, + parent.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.highlightSearchWords(); + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * highlight the search words provided in the url in the text + */ + highlightSearchWords: () => { + const highlight = + new URLSearchParams(window.location.search).get("highlight") || ""; + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + const url = new URL(window.location); + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + const blacklistedElements = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", + ]); + document.addEventListener("keydown", (event) => { + if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements + if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + case "Escape": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.hideSearchWords(); + event.preventDefault(); + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/docs/build/html/_static/documentation_options.js b/docs/build/html/_static/documentation_options.js new file mode 100644 index 0000000..a750e4d --- /dev/null +++ b/docs/build/html/_static/documentation_options.js @@ -0,0 +1,14 @@ +var DOCUMENTATION_OPTIONS = { + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: false, +}; \ No newline at end of file diff --git a/docs/build/html/_static/file.png b/docs/build/html/_static/file.png new file mode 100644 index 0000000..a858a41 Binary files /dev/null and b/docs/build/html/_static/file.png differ diff --git a/docs/build/html/_static/jquery-3.6.0.js b/docs/build/html/_static/jquery-3.6.0.js new file mode 100644 index 0000000..fc6c299 --- /dev/null +++ b/docs/build/html/_static/jquery-3.6.0.js @@ -0,0 +1,10881 @@ +/*! + * jQuery JavaScript Library v3.6.0 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2021-03-02T17:08Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + // Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5 + // Plus for old WebKit, typeof returns "function" for HTML collections + // (e.g., `typeof document.getElementsByTagName("div") === "function"`). (gh-4756) + return typeof obj === "function" && typeof obj.nodeType !== "number" && + typeof obj.item !== "function"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.6.0", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.6 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2021-02-16 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem && elem.namespaceURI, + docElem = elem && ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +} +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the primary Deferred + primary = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + primary.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( primary.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return primary.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), primary.reject ); + } + + return primary.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + + // Support: Chrome 86+ + // In Chrome, if an element having a focusout handler is blurred by + // clicking outside of it, it invokes the handler synchronously. If + // that handler calls `.remove()` on the element, the data is cleared, + // leaving `result` undefined. We need to guard against this. + return result && result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + which: true +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + // Suppress native focus or blur as it's already being fired + // in leverageNative. + _default: function() { + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + // + // Support: Firefox 70+ + // Only Firefox includes border widths + // in computed dimensions. (gh-4529) + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px;border-collapse:separate"; + tr.style.cssText = "border:1px solid"; + + // Support: Chrome 86+ + // Height set through cssText does not get applied. + // Computed height then comes back as 0. + tr.style.height = "1px"; + trChild.style.height = "9px"; + + // Support: Android 8 Chrome 86+ + // In our bodyBackground.html iframe, + // display for all div elements is set to "inline", + // which causes a problem only in Android 8 Chrome 86. + // Ensuring the div is display: block + // gets around this issue. + trChild.style.display = "block"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) + + parseInt( trStyle.borderTopWidth, 10 ) + + parseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, parserErrorElem; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) {} + + parserErrorElem = xml && xml.getElementsByTagName( "parsererror" )[ 0 ]; + if ( !xml || parserErrorElem ) { + jQuery.error( "Invalid XML: " + ( + parserErrorElem ? + jQuery.map( parserErrorElem.childNodes, function( el ) { + return el.textContent; + } ).join( "\n" ) : + data + ) ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ).filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ).map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + +originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script but not if jsonp + if ( !isSuccess && + jQuery.inArray( "script", s.dataTypes ) > -1 && + jQuery.inArray( "json", s.dataTypes ) < 0 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/build/html/classifiers.html b/docs/build/html/classifiers.html new file mode 100644 index 0000000..cab8c42 --- /dev/null +++ b/docs/build/html/classifiers.html @@ -0,0 +1,143 @@ + + + + + + + Advanced classifiers — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Advanced classifiers

+

Besides ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier, it is possible to use the classifiers in the ex_fuzzy.classifiers module, +which contains classifiers that take the base classifier and combine it with other techniques. There are two main additions to the base classification +class: rule mining using support, confidence and lift measures; and using a double genetic tuning, so that first a large number of rules can be +considered as potential good rules, and then the second optimization step choose the best combination of them.

+

The three kind of classifiers are:

+
    +
  1. ex_fuzzy.classifiers.RuleMineClassifier: first mines the rules by checking all the possible combinations of antecedents. It looks for rules that present a minumum of the quality measures, (support, confidence and lift) and then uses them as candidate rules to find an optimal subset of them.

  2. +
  3. ex_fuzzy.classifiers.FuzzyRulesClassifier: performs a double genetic optimization. First, it finds a good rule base and then it uses it as the initial population for another round of genetic optimization.

  4. +
  5. ex_fuzzy.classifiers.RuleFineTuneClassifier: combines both previous approaches. First, searchs for all rules that hold the quality metrics. Then, uses them as candidate rules and finds a good subset of them. Finally, uses that rulebase as initial population for another round of genetic optimization, which gives the final result.

  6. +
+
+

Support, Confidence and lift

+
    +
  1. Support: The definition of support is the percentage of appearance of the antecedent of a rule in the whole dataset. We compute it as the average of the membership values of that antecedent in each sample for the dataset. The membership for each sample to that antecedent is computed using the minimum t-norm in this case.

  2. +
  3. Confidence: is the ratio between the support of an antecedent for a particular class and for the whole dataset.

  4. +
  5. Lift: is the ratio between the confidence and the expected confidence. It is computed as the ratio between the confidence of the rule and the percentage of samples of the rule class in the dataset.

  6. +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/extending.html b/docs/build/html/extending.html new file mode 100644 index 0000000..be83132 --- /dev/null +++ b/docs/build/html/extending.html @@ -0,0 +1,128 @@ + + + + + + + Extending Ex-Fuzzy — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Extending Ex-Fuzzy

+

Some of the default behaviour/components can be easily extended to support more fuzzy/explainability tools.

+
    +
  • Using other fuzzy sets: the whole library is programmed using object orientation, so that to extend some methods is to create classes that inherit from the correspondent classes. This is an easy way to implement additional to additional kinds of fuzzy sets. Nevertheless, as long as their membership values are numerical or 2-sized tuples, new fuzzy sets can be easily supported using the existing fs.FUZZY_SET enum. For example, fs.FUZZY_SET.t1 expects a numerical membership value and fs.FUZZY_SET.t2 expects a tuple. You can take a look at the ex_fuzzy.temporal for an example on how to do this.

  • +
  • In order to use other partitions than those given by the ex_fuzzzy.utils module, you can directly create the necessary objects through fs.FS() objects and fs.fuzzyVariable().

  • +
  • You can change the loss function used in the genetic optimization using the new_loss method of ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier.

  • +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/centroid.html b/docs/build/html/function_resume/centroid.html new file mode 100644 index 0000000..a06a52c --- /dev/null +++ b/docs/build/html/function_resume/centroid.html @@ -0,0 +1,262 @@ + + + + + + + T2 Centroid compute — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

T2 Centroid compute

+

This is the source file that contains functions to compute centroids for the case of IV fuzzy sets, +which are commonly used when using the IV-T2 fuzzy sets.

+
+
+ex_fuzzy.centroid.center_of_masses(z: array, w: array) array[source]
+

Computes the ponderated centroid with normalized weighting.

+
+
Parameters:
+
    +
  • z – Vector of the referencial values.

  • +
  • w – Vector of the fuzzy memberships.

  • +
+
+
Returns:
+

The ponderated sum.

+
+
+
+ +
+
+ex_fuzzy.centroid.compute_centroid_iv(z: array, memberships: array) array[source]
+

Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set.

+
+
Parameters:
+
    +
  • z – Vector of the referencial values.

  • +
  • memberships – vector of the fuzzy memberships.

  • +
+
+
Returns:
+

The centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.compute_centroid_t2_l(z: array, memberships: array) float[source]
+

Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set.

+
+
Parameters:
+
    +
  • z – Vector of the referencial values.

  • +
  • memberships – vector of the fuzzy memberships.

  • +
+
+
Returns:
+

The centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.compute_centroid_t2_r(z: array, memberships: array) float[source]
+

Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set.

+
+
Parameters:
+
    +
  • z – Vector of the referencial values.

  • +
  • memberships – vector of the fuzzy memberships.

  • +
+
+
Returns:
+

The lowest membership of the centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.consequent_centroid(antecedent_memberships: array, centroids: array) array[source]
+

Computes Karnik and Mendel algorithm to find the centroid of a consequent iv fuzzy set given the centroids of the consequents +and the antecedents memberships.

+
+
Parameters:
+
    +
  • antecedent_memberships – M x 2 matrix. M rules and iv dimension (2). Vector of memberships.

  • +
  • centroids – M x 2 matrix. M rules and iv dimension (2). Vector of centroids.

  • +
+
+
Returns:
+

The centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.consequent_centroid_l(antecedent_memberships: array, centroids_l: array) float[source]
+

Computes the Karnik and Mendel algorithm to find the left component of a centroid of an IV fuzzy set +using the centroids of the consequents and the antecedents memeberships.

+
+
Parameters:
+
    +
  • antecedent_memberships – M x 2 matrix. M rules and iv dimension (2). Vector of memberships.

  • +
  • centroids_r – M sized vector. Contains the referencial values.

  • +
+
+
Returns:
+

the IV centroid.

+
+
+
+ +
+
+ex_fuzzy.centroid.consequent_centroid_r(antecedent_memberships: array, centroids_r: array) float[source]
+

Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set +using the centroids of the consequents and the antecedents memeberships.

+
+
Parameters:
+
    +
  • antecedent_memberships – M x 2 matrix. M rules and iv dimension (2). Vector of memberships.

  • +
  • centroids_r – M sized vector. Contains the referencial values.

  • +
+
+
Returns:
+

the IV centroid.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/classifiers.html b/docs/build/html/function_resume/classifiers.html new file mode 100644 index 0000000..03eb5e0 --- /dev/null +++ b/docs/build/html/function_resume/classifiers.html @@ -0,0 +1,255 @@ + + + + + + + Advanced Classifiers — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Advanced Classifiers

+

Module that contains classifiers that uses two step genetic optimization and rule mining based on the support of the candidate rules.

+
+
+class ex_fuzzy.classifiers.FuzzyRulesClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: FUZZY_SETS = None, tolerance: float = 0.0, verbose=False, n_class: int = None, runner: int = 1, expansion_factor: int = 1, linguistic_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None)[source]
+

Bases: ClassifierMixin

+

A classifier that works by performing a double optimization process. First, it creates a candidate rule base using genetic optimization +and then uses it as a basis to obtain a better one that satisfies the constrain of antecedents and number of rules.

+
+
+fit(X: array, y: array, n_gen: int = 30, pop_size: int = 50, checkpoints: int = 0, n_runner: int = 1)[source]
+

Trains the model with the given data.

+
+
Parameters:
+
    +
  • X – samples to train.

  • +
  • y – labels for each sample.

  • +
  • n_gen – number of generations to compute in the genetic optimization.

  • +
  • pop_size – number of subjects per generation.

  • +
  • checkpoints – if bigger than 0, will save the best subject per x generations in a text file.

  • +
  • n_runner – number of threds to use.

  • +
+
+
+
+ +
+
+predict(X: array) array[source]
+

Predcit for each sample the correspondent class.

+
+
Parameters:
+

X – samples to predict.

+
+
Returns:
+

a class for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.classifiers.RuleFineTuneClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: FUZZY_SETS = None, tolerance: float = 0.0, verbose=False, n_class: int = None, runner: int = 1, expansion_factor: int = 1, linguistic_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None)[source]
+

Bases: ClassifierMixin

+

A classifier that works by mining a set of candidate rules with a minimum support and then uses a two step genetic optimization that chooses +the optimal combination of those rules and fine tunes them.

+
+
+fit(X: array, y: array, n_gen: int = 30, pop_size: int = 50, checkpoints: int = 0, n_runner: int = 1)[source]
+

Trains the model with the given data.

+
+
Parameters:
+
    +
  • X – samples to train.

  • +
  • y – labels for each sample.

  • +
  • n_gen – number of generations to compute in the genetic optimization.

  • +
  • pop_size – number of subjects per generation.

  • +
  • checkpoints – if bigger than 0, will save the best subject per x generations in a text file.

  • +
  • n_runner – number of threds to use.

  • +
+
+
+
+ +
+
+predict(X: array) array[source]
+

Predcit for each sample the correspondent class.

+
+
Parameters:
+

X – samples to predict.

+
+
Returns:
+

a class for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.classifiers.RuleMineClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: FUZZY_SETS = None, tolerance: float = 0.0, verbose=False, n_class: int = None, runner: int = 1, linguistic_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None)[source]
+

Bases: ClassifierMixin

+

A classifier that works by mining a set of candidate rules with a minimum support, confidence and lift, and then using a genetic algorithm that chooses +the optimal combination of those rules.

+
+
+fit(X: array, y: array, n_gen: int = 30, pop_size: int = 50)[source]
+

Trains the model with the given data.

+
+
Parameters:
+
    +
  • X – samples to train.

  • +
  • y – labels for each sample.

  • +
+
+
+
+ +
+
+predict(X: array) array[source]
+

Predict for each sample the corresponding class.

+
+
Parameters:
+

X – samples to predict.

+
+
Returns:
+

a class for each sample.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/cognitive_maps.html b/docs/build/html/function_resume/cognitive_maps.html new file mode 100644 index 0000000..873c85c --- /dev/null +++ b/docs/build/html/function_resume/cognitive_maps.html @@ -0,0 +1,169 @@ + + + + + + + Fuzzy Cognitive Maps — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fuzzy Cognitive Maps

+
+
+ex_fuzzy.cognitive_maps.attractors_report(attractors: dict[numpy.array, numpy.array]) None[source]
+

Prints a report of the attractors found.

+
+
Parameters:
+

attractors – dict[np.array, np.array]. The attractors found.

+
+
+
+ +
+
+ex_fuzzy.cognitive_maps.look_pattern_states(fcm: FuzzyCognitiveMap, sim_steps: int, pattern_len: 50, max_period_size: 50) [<built-in function array>][source]
+

Looks for the pattern states of the FCM when simulation is prolongued.

+

:param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. +:param max_steps: int. The maximum number of steps to look for the attractor states. +:param random_inits : int +:returns: list of np.array. The attractor states found. None if none were found

+
+ +
+
+ex_fuzzy.cognitive_maps.study_attractors_FCM(fcm: FuzzyCognitiveMap, max_steps: int, random_inits: int = 10) [<built-in function array>][source]
+

Looks for the attractor states of the FCM when simulation is prolongued.

+

:param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. +:param max_steps: int. The maximum number of steps to look for the attractor states. +:param random_inits : int +:returns: list of np.array. The attractor states found. None if none were found

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/eval_rules.html b/docs/build/html/function_resume/eval_rules.html new file mode 100644 index 0000000..6bdf06d --- /dev/null +++ b/docs/build/html/function_resume/eval_rules.html @@ -0,0 +1,307 @@ + + + + + + + Rule Evaluation Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Rule Evaluation Functions

+

This file contains the classes to perform rule classification evaluation.

+
+
+class ex_fuzzy.eval_rules.evalRuleBase(mrule_base: MasterRuleBase, X: array, y: array, time_moments: array = None)[source]
+

Bases: object

+

Class to evaluate a set of rules given a evaluation dataset.

+
+
+add_auxiliary_rule_weights() None[source]
+

Add dominance score field to each of the rules present in the master Rule Base for each consequent. +They are labeled as aux_score, aux_support and aux_confidence. (Because they are not the main rule weights)

+
+ +
+
+add_classification_metrics(X: array = None, y: array = None) None[source]
+

Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores. +If X and y are None uses the train set.

+
+
Parameters:
+
    +
  • X – array of shape samples x features

  • +
  • y – array of shape samples

  • +
+
+
+
+ +
+
+add_full_evaluation()[source]
+

Adds classification scores, both Dominance Scores and accuracy metrics, for each individual rule.

+
+ +
+
+add_rule_weights() None[source]
+

Add dominance score field to each of the rules present in the master Rule Base.

+
+ +
+
+association_degree() array[source]
+

Returns the association degree of each rule for each sample.

+
+
Returns:
+

vector of shape rules

+
+
+
+ +
+
+aux_dominance_scores() array[source]
+

Returns the dominance score of each pattern for each rule.

+
+
Returns:
+

array of shape rules x 2

+
+
+
+ +
+
+classification_eval() float[source]
+

Returns the matthews correlation coefficient for a classification task using +the rules evaluated.

+
+
Returns:
+

mattews correlation coefficient. (float in [-1, 1])

+
+
+
+ +
+
+compute_aux_pattern_confidence() array[source]
+

Computes the pattern confidence for each of the rules for the given X. +Each pattern confidence is the normalized firing strength.

+
+
Returns:
+

array of shape rules x classes

+
+
+
+ +
+
+compute_aux_pattern_support() array[source]
+

Computes the pattern support for each of the rules for each of the classes for the given X. +Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, +dvided by their number.

+
+
Returns:
+

array of shape rules x 2

+
+
+
+ +
+
+compute_pattern_confidence() array[source]
+

Computes the pattern confidence for each of the rules for the given X. +Each pattern confidence is the normalized firing strength.

+
+
Returns:
+

array of shape 1 x rules

+
+
+
+ +
+
+compute_pattern_support() array[source]
+

Computes the pattern support for each of the rules for the given X. +Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, +dvided by their number.

+
+
Returns:
+

array of shape rules x 2

+
+
+
+ +
+
+dominance_scores() array[source]
+

Returns the dominance score of each pattern for each rule.

+
+
Returns:
+

array of shape rules x 2

+
+
+
+ +
+
+effective_rulesize_eval(tolerance=0.1) float[source]
+

Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents.

+

0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. +The more rules and antecedent per rules the lower this score is.

+
+
Parameters:
+

tolerance – float in [0, 1]. The tolerance for the dominance score. Default 0.1

+
+
Returns:
+

float in [0, 1] with the score.

+
+
+
+ +
+
+size_antecedents_eval(tolerance=0.1) float[source]
+

Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents.

+

0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. +The more rules and antecedent per rules the lower this score is.

+
+
Parameters:
+

tolerance – float in [0, 1]. The tolerance for the dominance score. Default 0.1

+
+
Returns:
+

float in [0, 1] with the score.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/eval_tools.html b/docs/build/html/function_resume/eval_tools.html new file mode 100644 index 0000000..e90ff30 --- /dev/null +++ b/docs/build/html/function_resume/eval_tools.html @@ -0,0 +1,163 @@ + + + + + + + Classification evaluation tools — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Classification evaluation tools

+

Functions that contain some general functions to eval already fitted fuzzy rule based models. +It can also be used to visualize rules and fuzzy partitions.

+
+
+ex_fuzzy.eval_tools.eval_fuzzy_model(fl_classifier: BaseFuzzyRulesClassifier, X_train: array, y_train: array, X_test: array, y_test: array, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) None[source]
+

Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.

+
+
Parameters:
+
    +
  • fl_classifier – Fuzzy rule based model.

  • +
  • X_train – Training data.

  • +
  • y_train – Training labels.

  • +
  • X_test – Test data.

  • +
  • y_test – Test labels.

  • +
  • plot_rules – If True, it plots the rules.

  • +
  • print_rules – If True, it prints the rules.

  • +
  • plot_partitions – If True, it plots the fuzzy partitions.

  • +
+
+
Returns:
+

None

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/evolutionary_fit.html b/docs/build/html/function_resume/evolutionary_fit.html new file mode 100644 index 0000000..a3268cc --- /dev/null +++ b/docs/build/html/function_resume/evolutionary_fit.html @@ -0,0 +1,319 @@ + + + + + + + Evolutionary Algorithms to Fit the rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Evolutionary Algorithms to Fit the rules

+

This is a the source file that contains the class to train/fit the rulebase using a genetic algorithm.

+
+
+class ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: FUZZY_SETS = None, tolerance: float = 0.0, n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, domain: list[float] = None, n_class: int = None, precomputed_rules: MasterRuleBase = None, runner: int = 1)[source]
+

Bases: ClassifierMixin

+

Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables.

+
+
+customized_loss(loss_function)[source]
+

Function to customize the loss function used for the optimization.

+
+
Parameters:
+

loss_function – function that takes as input the true labels and the predicted labels and returns a float.

+
+
Returns:
+

None

+
+
+
+ +
+
+fit(X: array, y: array, n_gen: int = 70, pop_size: int = 30, checkpoints: int = 10, candidate_rules: MasterRuleBase = None, initial_rules: MasterRuleBase = None, **kwargs)[source]
+

Fits a fuzzy rule based classifier using a genetic algorithm to the given data.

+
+
Parameters:
+
    +
  • X – numpy array samples x features

  • +
  • y – labels. integer array samples (x 1)

  • +
  • n_gen – integer. Number of generations to run the genetic algorithm.

  • +
  • pop_size – integer. Population size for each gneration.

  • +
  • time_moments – array of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
  • checkpoints – integer. Number of checkpoints to save the best rulebase found so far.

  • +
  • candidate_rules – if these rules exist, the optimization process will choose the best rules from this set. If None (default) the rules will be generated from scratch.

  • +
+
+
Returns:
+

None. The classifier is fitted to the data.

+
+
+
+ +
+
+forward(X: array) array[source]
+

Returns the predicted class for each sample.

+
+
Parameters:
+

X – np array samples x features.

+
+
Returns:
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+get_rulebase() list[numpy.array][source]
+

Get the rulebase obtained after fitting the classifier to the data.

+
+
Returns:
+

a matrix format for the rulebase.

+
+
+
+ +
+
+load_master_rule_base(rule_base: MasterRuleBase) None[source]
+

Loads a master rule base to be used in the prediction process.

+
+
Parameters:
+

rule_base – ruleBase object.

+
+
Returns:
+

None

+
+
+
+ +
+
+plot_fuzzy_variables() None[source]
+

Plot the fuzzy partitions in each fuzzy variable.

+
+ +
+
+predict(X: array) array[source]
+

Returns the predicted class for each sample.

+
+
Parameters:
+

X – np array samples x features.

+
+
Returns:
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+print_rules(return_rules: bool = False) None[source]
+

Print the rules contained in the fitted rulebase.

+
+ +
+
+rename_fuzzy_variables() None[source]
+

Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process.

+
+
Returns:
+

None. Names are sorted accorded to the central point of the fuzzy memberships.

+
+
+
+ +
+ +
+
+class ex_fuzzy.evolutionary_fit.ExploreRuleBases(X: array, y: array, nRules: int, n_classes: int, cancidate_rules: MasterRuleBase, thread_runner: StarmapParallelization = None, tolerance: float = 0.01)[source]
+

Bases: Problem

+

Class to model as pymoo problem the fitting of a rulebase to a set of data given a series of candidate rules for a classification problem using Evolutionary strategies +Supports type 1 and t2.

+
+
+fitness_func(ruleBase: RuleBase, X: array, y: array, tolerance: float, alpha: float = 0.95, beta: float = 0.025, gamma: float = 0.025) float[source]
+

Fitness function for the optimization problem. +:param ruleBase: RuleBase object +:param X: array of train samples. X shape = (n_samples, n_features) +:param y: array of train labels. y shape = (n_samples,) +:param tolerance: float. Tolerance for the size evaluation. +:return: float. Fitness value.

+
+ +
+ +
+
+class ex_fuzzy.evolutionary_fit.FitRuleBase(X: array, y: array, nRules: int, nAnts: int, n_classes: int, thread_runner: StarmapParallelization = None, **kwargs)[source]
+

Bases: Problem

+

Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies. +Supports type 1 and iv fs (iv-type 2)

+
+
+encode_rulebase(rule_base: MasterRuleBase, optimize_lv: bool) array[source]
+

Given a rule base, constructs the corresponding gene associated with that rule base.

+

GENE STRUCTURE

+

First: antecedents chosen by each rule. Size: nAnts * nRules (index of the antecedent) +Second: Variable linguistics used. Size: nAnts * nRules +Third: Parameters for the fuzzy partitions of the chosen variables. Size: nAnts * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) +Four: Consequent classes. Size: nRules

+
+
Parameters:
+
    +
  • rule_base – rule base object.

  • +
  • optimize_lv – if True, the gene is prepared to optimize the membership functions.

  • +
  • antecedents_referencial – list of lists. Each list contains the referencial for each variable. Required only if optimize_lv is True.

  • +
+
+
Returns:
+

np array of size self.single_gen_size.

+
+
+
+ +
+
+fitness_func(ruleBase: RuleBase, X: array, y: array, tolerance: float, alpha: float = 0.975, beta: float = 0.0125, gamma: float = 0.0125) float[source]
+

Fitness function for the optimization problem. +:param ruleBase: RuleBase object +:param X: array of train samples. X shape = (n_samples, n_features) +:param y: array of train labels. y shape = (n_samples,) +:param tolerance: float. Tolerance for the size evaluation. +:return: float. Fitness value.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/fuzzy_sets.html b/docs/build/html/function_resume/fuzzy_sets.html new file mode 100644 index 0000000..6cf4183 --- /dev/null +++ b/docs/build/html/function_resume/fuzzy_sets.html @@ -0,0 +1,349 @@ + + + + + + + Fuzzy Sets Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fuzzy Sets Functions

+

This is a the source file that contains the class of GT2 fuzzy set and its most direct applications, +like computing the FM function, etc.

+
+
+class ex_fuzzy.fuzzy_sets.FS(name: str, membership_parameters: list[float], domain: list[float])[source]
+

Bases: object

+

Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets).

+
+
+membership(x: array) array[source]
+

Computes the membership of a point or a vector.

+
+
Parameters:
+

x – input values in the fuzzy set referencial domain.

+
+
+
+ +
+
+type() FUZZY_SETS[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum.

+
+
Returns:
+

FUZZY_SETS enum.

+
+
+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.GT2(name: str, secondary_memberships: dict[float, ex_fuzzy.fuzzy_sets.FS], domain: list[float], significant_decimals: int, alpha_cuts: list[float] = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0], unit_resolution: float = 0.2)[source]
+

Bases: FS

+

Class to define a gt2 fuzzy set.

+
+
+alpha_reduction(x) array[source]
+

Computes the type reduction to reduce the alpha cuts to one value.

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+
+membership(x: array) array[source]
+

Computes the alpha cut memberships of a point.

+
+
Parameters:
+

x – input values in the fuzzy set referencial domain.

+
+
Returns:
+

np array samples x alpha_cuts x 2

+
+
+
+ +
+
+type() FUZZY_SETS[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum.

+
+
Returns:
+

FUZZY_SETS enum.

+
+
+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.IVFS(name: str, secondMF_lower: list[float], secondMF_upper: list[float], domain: list[float], lower_height=1.0)[source]
+

Bases: FS

+

Class to define a iv fuzzy set.

+
+
+membership(x: array) array[source]
+

Computes the iv-membership of a point or a vector.

+
+
Parameters:
+

x – input values in the fuzzy set referencial domain.

+
+
Returns:
+

iv-membership of the fuzzy set.

+
+
+
+ +
+
+type() FUZZY_SETS[source]
+

Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2)

+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.fuzzyVariable(name: str, fuzzy_sets: list[ex_fuzzy.fuzzy_sets.FS])[source]
+

Bases: object

+

Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them.

+
+
+compute_memberships(x: array) list[source]
+

Computes the membership to each of the FS in the fuzzy variables.

+
+
Parameters:
+

x – numeric value or array. Computes the membership to each of the FS in the fuzzy variables.

+
+
Returns:
+

list of floats. Membership to each of the FS in the fuzzy variables.

+
+
+
+ +
+
+domain() list[float][source]
+

Returns the domain of the fuzzy variable.

+
+
Returns:
+

list of floats.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the fuzzy type of the domain

+
+
Returns:
+

the type of the fuzzy set present in the fuzzy variable.

+
+
+
+ +
+
+get_linguistic_variables() list[ex_fuzzy.fuzzy_sets.FS][source]
+

Returns the name of the linguistic variables.

+
+
Returns:
+

list of strings.

+
+
+
+ +
+
+linguistic_variable_names() list[source]
+

Returns the name of the linguistic variables.

+
+
Returns:
+

list of strings.

+
+
+
+ +
+ +
+
+class ex_fuzzy.fuzzy_sets.gaussianIVFS(name: str, secondMF_lower: list[float], secondMF_upper: list[float], domain: list[float], lower_height=1.0)[source]
+

Bases: IVFS

+

Class to define a iv fuzzy set with gaussian membership.

+
+
+membership(input: array) array[source]
+

Computes the gaussian iv-membership of a point or a vector.

+
+
Parameters:
+

input – input values in the fuzzy set referencial domain.

+
+
Returns:
+

np array samples x 2

+
+
+
+ +
+
+type() FUZZY_SETS[source]
+

Returns the type of the fuzzy set. (t1)

+
+ +
+ +
+
+ex_fuzzy.fuzzy_sets.trapezoidal_membership(x: array, params: list[float], epsilon=0.0001) array[source]
+

Trapezoidal membership functions.

+
+
Parameters:
+
    +
  • x – input values in the fuzzy set referencial domain.

  • +
  • params – four numbers that comprises the start and end of the trapezoid.

  • +
  • epsilon – small float number for numerical stability. Adjust accordingly only if there are NaN issues.

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/persistence.html b/docs/build/html/function_resume/persistence.html new file mode 100644 index 0000000..f48c240 --- /dev/null +++ b/docs/build/html/function_resume/persistence.html @@ -0,0 +1,153 @@ + + + + + + + Classification persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Classification persistence

+

Load the rules of a fuzzy rules system using plain text format.

+
+
+ex_fuzzy.persistence.load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) MasterRuleBase[source]
+

Load the rules from a string.

+
+
Parameters:
+
    +
  • rules_printed – string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase

  • +
  • fuzzy_variables – list with the linguistic variables. Objects of FuzzyVariable class.

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/rule_mining.html b/docs/build/html/function_resume/rule_mining.html new file mode 100644 index 0000000..49515fe --- /dev/null +++ b/docs/build/html/function_resume/rule_mining.html @@ -0,0 +1,276 @@ + + + + + + + Rule Mining methods — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Rule Mining methods

+

Module to perform rule mining in a pandas dataframe or numpy array. The methods use the support of the different itemsets to look for good +rule candidates. It can be used then by a Genetic optimizator from evolutionary_fit module to search the optimal combination of them.

+
+
+ex_fuzzy.rule_mining.generate_rules_from_itemsets(itemsets: list, nAnts: int) list[ex_fuzzy.rules.RuleSimple][source]
+

Given a list of itemsets, it creates the rules for each one and returns a list of rules containing them.

+
+
Parameters:
+
    +
  • itemsets – list of tuple (antecedent, linguistic variable value)

  • +
  • nAnts – number of possible antecedents.

  • +
+
+
Returns:
+

the rules for ech itemset.

+
+
+
+ +
+
+ex_fuzzy.rule_mining.mine_rulebase_support(x: DataFrame, fuzzy_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], support_threshold: float = 0.05, max_depth: int = 3) RuleBase[source]
+

Search the data for associations that are frequent given a list of fuzzy variables for each antecedent.

+
+
Parameters:
+
    +
  • x – the data to mine. Dims: samples x features.

  • +
  • fuzzy_variables – list of the fuzzy variables for each of the input variables.

  • +
  • support_threshold – minimum threshold to decide if prune or not the rule.

  • +
  • max_depth – maximum number of antecedents per rule.

  • +
+
+
Returns:
+

a rulebase object with the rules denoted as good.

+
+
+
+ +
+
+ex_fuzzy.rule_mining.multiclass_mine_rulebase(x: DataFrame, y: array, fuzzy_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], support_threshold: float = 0.05, max_depth: int = 3, confidence_threshold: float = 0.05, lift_threshold: float = 1.05) MasterRuleBase[source]
+

Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. Computes a different ruleBase for each +class and then uses them to form a MasterRuleBase.

+
+
Parameters:
+
    +
  • x – the data to mine. Dims: samples x features.

  • +
  • fuzzy_variables – list of the fuzzy variables for each of the input variables.

  • +
  • support_threshold – minimum threshold to decide if prune or not the rule.

  • +
  • max_depth – maximum number of antecedents per rule.

  • +
  • confidence_threshold – minimum confidence value.

  • +
  • lift_threshold

  • +
+
+
Returns:
+

a rulebase object with the rules denoted as good.

+
+
+
+ +
+
+ex_fuzzy.rule_mining.prune_rules_confidence_lift(x: DataFrame, y: array, rules: MasterRuleBase, fuzzy_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], confidence_threshold: float = 0.5, lift_threshold: float = 1.05)[source]
+

Removes the rules from the rule base that do not meet a minimum value for confidence and lift measures.

+

Confidence is the ratio of rules that have a particular antecedent and consequent, and those that only have the antecedent. +Lift is ratio between confidence and expected confidence, which is the percentage of class samples in the original data.

+
+
Parameters:
+
    +
  • x – data to mine. samples x features.

  • +
  • y – class vector.

  • +
  • rules – MasterRuleBase object with the rules to prune.

  • +
  • fuzzy_variables – a list of the fuzzy variables per antecedent.

  • +
  • confidence_threshold – minimum confidence required to the rules.

  • +
  • lift_threshold – minimum lift required to the rules.

  • +
+
+
+
+ +
+ +

Computes the apriori algorithm for the given dataframe and threshold the support.

+
+
Parameters:
+
    +
  • data – Dataframe of shape: samples x features

  • +
  • variables (fuzzy) – dict that maps each feature name with a fuzzy variable.

  • +
  • support_threshold – minimum support to consider frequent an itemset.

  • +
+
+
Returns:
+

all the frequent itemsets as a list.

+
+
+
+ +
+
+ex_fuzzy.rule_mining.simple_mine_rulebase(x: DataFrame, fuzzy_type: FUZZY_SETS = FUZZY_SETS.t1, support_threshold: float = 0.05, max_depth: int = 3) RuleBase[source]
+

Search the data for associations that are frequent. Computes the fuzzy variables using a 3 label partition (low, medium, high).

+
+
Parameters:
+
    +
  • x – the data to mine. Dims: samples x features.

  • +
  • fuzzy_type – fuzzy type to use.

  • +
  • support_threshold – minimum threshold to decide if prune or not the rule.

  • +
  • max_depth – maximum number of antecedents per rule.

  • +
+
+
Returns:
+

a rulebase object with the rules denoted as good.

+
+
+
+ +
+
+ex_fuzzy.rule_mining.simple_multiclass_mine_rulebase(x: DataFrame, y: array, fuzzy_type: FUZZY_SETS, support_threshold: float = 0.05, max_depth: int = 3, confidence_threshold: float = 0.5, lift_threshold: float = 1.1) MasterRuleBase[source]
+

Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. +Computes a different ruleBase for each class and then uses them to form a MasterRuleBase.

+

Computes the fuzzy variables using a 3 label partition (low, medium, high).

+
+
Parameters:
+
    +
  • x – the data to mine. Dims: samples x features.

  • +
  • fuzzy_type – fuzzy type to use.

  • +
  • support_threshold – minimum threshold to decide if prune or not the rule.

  • +
  • max_depth – maximum number of antecedents per rule.

  • +
+
+
Returns:
+

a rulebase object with the rules denoted as good.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/rules.html b/docs/build/html/function_resume/rules.html new file mode 100644 index 0000000..f1145d3 --- /dev/null +++ b/docs/build/html/function_resume/rules.html @@ -0,0 +1,712 @@ + + + + + + + Fuzzy Rules Functions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Fuzzy Rules Functions

+

This is a the source file that contains the Rule, RuleBase and MasterRuleBase classes to perform fuzzy inference.

+
+
+class ex_fuzzy.rules.MasterRuleBase(rule_base: list[ex_fuzzy.rules.RuleBase], consequent_names: list[str] = None)[source]
+

Bases: object

+

This Class encompasses a list of rule bases where each one corresponds to a different class.

+
+
+add_rule(rule: RuleSimple, consequent: int) None[source]
+

Adds a rule to the rule base of the given consequent.

+
+
Parameters:
+
    +
  • rule – rule to add.

  • +
  • consequent – index of the rule base to add the rule.

  • +
+
+
+
+ +
+
+add_rule_base(rule_base: RuleBase) None[source]
+

Adds a rule base to the list of rule bases.

+
+
Parameters:
+

rule_base – rule base to add.

+
+
+
+ +
+
+compute_firing_strenghts(X) array[source]
+

Computes the firing strength of each rule for each sample.

+
+
Parameters:
+

X – array with the values of the inputs.

+
+
Returns:
+

array with the firing strength of each rule for each sample.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+get_antecedents() list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Returns the antecedents of the rule base.

+
+ +
+
+get_consequents() list[int][source]
+

Returns a list with the consequents of each rule base.

+
+
Returns:
+

list with the consequents of each rule base.

+
+
+
+ +
+
+get_rulebase_matrix() list[numpy.array][source]
+

Returns a list with the rulebases for each antecedent in matrix format.

+
+
Returns:
+

list with the rulebases for each antecedent in matrix format.

+
+
+
+ +
+
+get_rulebases() list[ex_fuzzy.rules.RuleBase][source]
+

Returns a list with all the rules.

+
+
Returns:
+

list

+
+
+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns a list with all the rules.

+
+
Returns:
+

list with all the rules.

+
+
+
+ +
+
+get_scores() array[source]
+

Returns the dominance score for each rule in all the rulebases.

+
+
Returns:
+

array with the dominance score for each rule in all the rulebases.

+
+
+
+ +
+
+n_linguist_variables() int[source]
+

Returns the number of linguistic variables in the rule base.

+
+ +
+
+print_rules(return_rules=False) None[source]
+

Print all the rules for all the consequents.

+
+
Parameters:
+

autoprint – if True, the rules are printed. If False, the rules are returned as a string.

+
+
+
+ +
+
+purge_rules(tolerance=0.001) None[source]
+

Delete the roles with a dominance score lower than the tolerance.

+
+
Parameters:
+

tolerance – tolerance to delete the rules.

+
+
+
+ +
+
+rename_cons(consequent_names: list[str]) None[source]
+

Renames the consequents of the rule base.

+
+ +
+
+winning_rule_predict(X: array) array[source]
+

Returns the winning rule for each sample. Takes into account dominance scores if already computed.

+
+
Parameters:
+

X – array with the values of the inputs.

+
+
Returns:
+

array with the winning rule for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.Rule(antecedents: list[ex_fuzzy.fuzzy_sets.FS], consequent: FS)[source]
+

Bases: object

+

Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself.

+
+
+consequent_centroid() array[source]
+

Returns the centroid of the consequent using a Karnik and Mendel algorithm.

+
+ +
+
+membership(x: ~numpy.array, tnorm=<function _myprod>) array[source]
+

Computes the membership of one input to the antecedents of the rule.

+
+
Parameters:
+
    +
  • x – input to compute the membership.

  • +
  • tnorm – t-norm to use in the inference process.

  • +
+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBase(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: ~ex_fuzzy.fuzzy_sets.fuzzyVariable = None, tnorm=<function prod>)[source]
+

Bases: object

+

Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study)

+
+
+add_rule(new_rule: RuleSimple)[source]
+

Adds a new rule to the rulebase. +:param new_rule: rule to add.

+
+ +
+
+add_rules(new_rules: list[ex_fuzzy.rules.RuleSimple])[source]
+

Adds a list of new rules to the rulebase.

+
+
Parameters:
+

new_rules – list of rules to add.

+
+
+
+ +
+
+compute_antecedents_memberships(x: array) list[dict][source]
+

Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable. +x must be a vector (only one sample)

+
+
Parameters:
+

x – vector with the values of the inputs.

+
+
+
+ +
+
+compute_rule_antecedent_memberships(x: array, scaled=True) array[source]
+

Computes the antecedent truth value of an input array.

+

Return an array in shape samples x rules (x 2) (last is iv dimension)

+
+
Parameters:
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled according to their sums for each sample.

  • +
+
+
Returns:
+

array with the memberships of the antecedents for each rule.

+
+
+
+ +
+
+abstract forward(x: array) array[source]
+

Computes the deffuzified output of the fl inference system.

+

Return a vector of size (samples, )

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the deffuzified output.

+
+
+
+ +
+
+abstract fuzzy_type() FUZZY_SETS[source]
+

Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the type of fuzzy set used in the RuleBase.

+
+
+
+ +
+
+get_rulebase_matrix()[source]
+

Returns a matrix with the antecedents values for each rule.

+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns the list of rules in the rulebase.

+
+ +
+
+get_scores()[source]
+

Returns an array with the dominance score for each rule. +(Must been already computed by an evalRule object)

+
+ +
+
+abstract inference(x: array) array[source]
+

Computes the fuzzy output of the fl inference system.

+

Return an array in shape samples x 2 (last is iv dimension)

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the memberships of the consequents for each rule.

+
+
+
+ +
+
+n_linguist_variables() int[source]
+

Returns the number of linguistic variables in the rule base.

+
+ +
+
+print_rules(return_rules: bool = False) None[source]
+

Print the rules from the rule base.

+
+ +
+
+prune_bad_rules(tolerance=0.01) None[source]
+

Delete the rules from the rule base that do not have a dominance score superior to the threshold or have 0 accuracy in the training set.

+
+
Parameters:
+

tolerance – threshold for the dominance score.

+
+
+
+ +
+
+remove_rule(ix: int) None[source]
+

Removes the rule in the given index. +:param ix: index of the rule to remove.

+
+ +
+
+remove_rules(delete_list: list[int]) None[source]
+

Removes the rules in the given list of indexes.

+
+
Parameters:
+

delete_list – list of indexes of the rules to remove.

+
+
+
+ +
+
+scores() array[source]
+

Returns the dominance score for each rule.

+
+
Returns:
+

array with the dominance score for each rule.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseGT2(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: ~ex_fuzzy.fuzzy_sets.fuzzyVariable = None, tnorm=<function _myprod>)[source]
+

Bases: RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports gt2 fs. (ONLY FOR CLASSIFICATION PROBLEMS)

+
+
+alpha_compute_rule_antecedent_memberships(x: array, scaled=True) array[source]
+

Computes the membership for the antecedents for all the alpha cuts.

+
+
Parameters:
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled to sum 1 in each sample.

  • +
+
+
Returns:
+

array with the memberships of the antecedents for each sample.

+
+
+
+ +
+
+compute_rule_antecedent_memberships(x: array, scaled=True) array[source]
+

Computes the membership for the antecedents performing the alpha_cut reduction.

+
+
Parameters:
+
    +
  • x – array with the values of the inputs.

  • +
  • scaled – if True, the memberships are scaled to sum 1 in each sample.

  • +
+
+
+
+ +
+
+forward(x: array) array[source]
+

Computes the deffuzified output of the t2 inference system.

+

Return a vector of size (samples, )

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: array) array[source]
+

Computes the output of the gt2 inference system.

+

Return an array in shape samples x alpha_cuts

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseT1(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: ~ex_fuzzy.fuzzy_sets.fuzzyVariable = None, tnorm=<function _myprod>)[source]
+

Bases: RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports t1 fs.

+
+
+forward(x: array) array[source]
+

Same as inference() in the t1 case.

+

Return a vector of size (samples, )

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: array) array[source]
+

Computes the output of the t1 inference system.

+

Return an array in shape samples.

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the output of the inference system for each sample.

+
+
+
+ +
+ +
+
+class ex_fuzzy.rules.RuleBaseT2(antecedents: list[ex_fuzzy.fuzzy_sets.fuzzyVariable], rules: list[ex_fuzzy.rules.RuleSimple], consequent: ~ex_fuzzy.fuzzy_sets.fuzzyVariable = None, tnorm=<function _myprod>)[source]
+

Bases: RuleBase

+

Class optimized to work with multiple rules at the same time. Supports only one consequent. +(Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation)

+

This class supports iv approximation for t2 fs.

+
+
+forward(x: array) array[source]
+

Computes the deffuzified output of the t2 inference system.

+

Return a vector of size (samples, )

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the deffuzified output for each sample.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+inference(x: array) array[source]
+

Computes the iv output of the t2 inference system.

+

Return an array in shape samples x 2 (last is iv dimension)

+
+
Parameters:
+

x – array with the values of the inputs.

+
+
Returns:
+

array with the memberships of the consequents for each sample.

+
+
+
+ +
+ +
+
+exception ex_fuzzy.rules.RuleError(message: str)[source]
+

Bases: Exception

+

Exception raised when a rule is not well defined.

+
+ +
+
+class ex_fuzzy.rules.RuleSimple(antecedents: list[int], consequent: int = 0)[source]
+

Bases: object

+

Class designed to represent rules in its simplest form to optimize the computation in a rulebase.

+
+
It indicates the antecedent values using a vector coded in this way:

ith entry: -1 means this variable is not used. 0-N indicates that the variable linguistic used for the ith input is that one.

+
+
+
+ +
+
+ex_fuzzy.rules.list_rules_to_matrix(rule_list: list[ex_fuzzy.rules.RuleSimple]) array[source]
+

Returns a matrix out of the rule list.

+
+
Parameters:
+

rule_list – list of rules.

+
+
Returns:
+

matrix with the antecedents of the rules.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/temporal.html b/docs/build/html/function_resume/temporal.html new file mode 100644 index 0000000..8e860e1 --- /dev/null +++ b/docs/build/html/function_resume/temporal.html @@ -0,0 +1,476 @@ + + + + + + + Temporal fuzzy sets — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Temporal fuzzy sets

+

Expansion of the base fuzzy sets, adding temporal fuzzy sets.

+

Contains functions to model the temporal fuzzy sets, temporal fuzzy variables and temporal rule bases. +It also contains functions to evaluate the fuzzy rulebases obtained.

+
+
+ex_fuzzy.temporal.NEW_FUZZY_SETS
+

alias of FUZZY_SETS

+
+ +
+
+ex_fuzzy.temporal.TMP_FUZZY_SETS
+

alias of NEW_FUZZY_SETS

+
+ +
+
+class ex_fuzzy.temporal.TemporalFuzzyRulesClassifier(nRules: int = 30, nAnts: int = 4, fuzzy_type: FUZZY_SETS = None, tolerance: float = 0.0, n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[ex_fuzzy.fuzzy_sets.fuzzyVariable] = None, domain: list[float] = None, n_class: int = None, precomputed_rules: MasterRuleBase = None, runner: int = 1)[source]
+

Bases: BaseFuzzyRulesClassifier

+

Class that is used as a classifier for a fuzzy rule based system with time dependencies. Supports precomputed and optimization of the linguistic variables.

+
+
+fit(X: array, y: array, n_gen: int = 50, pop_size: int = 10, time_moments: array = None, checkpoints: int = 10)[source]
+

Fits a fuzzy rule based classifier using a genetic algorithm to the given data.

+
+
Parameters:
+
    +
  • X – numpy array samples x features

  • +
  • y – labels. integer array samples (x 1)

  • +
  • n_gen – integer. Number of generations to run the genetic algorithm.

  • +
  • pop_size – integer. Population size for each gneration.

  • +
  • time_moments – array of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
+
+
Returns:
+

None. The classifier is fitted to the data.

+
+
+
+ +
+
+forward(X: array, time_moments: list[int] = None) array[source]
+

Returns the predicted class for each sample.

+
+
Parameters:
+
    +
  • X – np array samples x features.

  • +
  • time_moments – list of integers. Time moments associated to each sample (when temporal dependencies are present)

  • +
+
+
Returns:
+

np array samples (x 1) with the predicted class.

+
+
+
+ +
+
+get_rulebase() list[numpy.array][source]
+

Get the rulebase obtained after fitting the classifier to the data.

+
+
Returns:
+

a matrix format for the rulebase.

+
+
+
+ +
+
+plot_fuzzy_variables() None[source]
+

Plot the fuzzy partitions in each fuzzy variable.

+
+ +
+ +
+
+ex_fuzzy.temporal.eval_temporal_fuzzy_model(fl_classifier: BaseFuzzyRulesClassifier, X_train: array, y_train: array, X_test: array, y_test: array, time_moments: list[int] = None, test_time_moments: list[int] = None, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) None[source]
+

Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions.

+
+
Parameters:
+
    +
  • fl_classifier – Fuzzy rule based model.

  • +
  • X_train – Training data.

  • +
  • y_train – Training labels.

  • +
  • X_test – Test data.

  • +
  • y_test – Test labels.

  • +
  • plot_rules – If True, it plots the rules.

  • +
  • print_rules – If True, it prints the rules.

  • +
  • plot_partitions – If True, it plots the fuzzy partitions.

  • +
+
+
Returns:
+

None

+
+
+
+ +
+
+class ex_fuzzy.temporal.temporalFS(std_fuzzy_set: FS, conditional_variable: array)[source]
+

Bases: FS

+

Class to implement temporal fuzzy sets.

+
+
+fix_time(time: int) None[source]
+

Fixes the time of the temporal fuzzy set.

+
+
Parameters:
+

time – int. Time moment to fix.

+
+
Returns:
+

FS. Fuzzy set with the fixed time.

+
+
+
+ +
+
+inside_type() FUZZY_SETS[source]
+

Returns the type of the og fuzzy set computed before the time dependency.

+
+ +
+
+membership(input: array, time: int = None) array[source]
+

Computes the membership of each sample and in each time for the fs.

+
+
Parameters:
+

input – array temporal_time x samples.

+
+
Time:
+

int. Time moment to compute the membership. If none, looks for a fixed time

+
+
Returns:
+

array temporal_time x samples.

+
+
+
+ +
+
+type() FUZZY_SETS[source]
+

Returns the type of the fuzzy set. (temporal)

+
+ +
+ +
+
+class ex_fuzzy.temporal.temporalFuzzyVariable(name: str, fuzzy_sets: list[ex_fuzzy.temporal.temporalFS])[source]
+

Bases: fuzzyVariable

+

Class to implement a temporal fuzzy variable.

+
+
+compute_memberships(x: array, time: int = None) dict[source]
+

Computes the membership to each of the FS in the fuzzy variables.

+
+
Parameters:
+
    +
  • x – numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables.

  • +
  • time – int. Time moment to compute the membership.

  • +
+
+
Returns:
+

list of floats. Membership to each of the FS in the fuzzy variables.

+
+
+
+ +
+
+fix_time(time: int) None[source]
+

Fixes the time of the temporal fuzzy variable.

+
+
Parameters:
+

time – int. Time moment to fix.

+
+
+
+ +
+
+n_time_moments() int[source]
+

Returns the number of time moments of the temporal fuzzy variable.

+
+
Returns:
+

int. Number of time moments of the temporal fuzzy variable.

+
+
+
+ +
+ +
+
+class ex_fuzzy.temporal.temporalMasterRuleBase(rule_base: list[ex_fuzzy.rules.MasterRuleBase], time_step_names: list[str] = None)[source]
+

Bases: MasterRuleBase

+

This class is a temporal extension of the MasterRuleBase class. It includes a list of +rule bases for each time step.

+
+
+add_rule(rule: RuleSimple, consequent: int, time_step: int) None[source]
+

Adds a rule to the rule base of the given consequent.

+
+
Parameters:
+
    +
  • rule – rule to add.

  • +
  • consequent – index of the rule base to add the rule.

  • +
  • time_step – time step of the rule base to add the rule.

  • +
+
+
+
+ +
+
+add_rule_base(rule_base: RuleBase, time: int) None[source]
+

Adds a rule base to the list of rule bases.

+
+
Parameters:
+

rule_base – rule base to add.

+
+
+
+ +
+
+compute_firing_strenghts(X: array, time_moments: list[int]) array[source]
+

Computes the firing strength of each rule for each sample.

+
+
Parameters:
+

X – array with the values of the inputs.

+
+
Returns:
+

array with the firing strength of each rule for each sample.

+
+
+
+ +
+
+fuzzy_type() FUZZY_SETS[source]
+

Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module.

+
+
Returns:
+

the corresponding fuzzy set type of the RuleBase.

+
+
+
+ +
+
+get_consequents() list[int][source]
+

Returns a list with the consequents of each rule base.

+
+
Returns:
+

list with the consequents of each rule base.

+
+
+
+ +
+
+get_rulebase_matrix() list[numpy.array][source]
+

Returns a list with the rulebases for each antecedent in matrix format.

+
+
Returns:
+

list with the rulebases for each antecedent in matrix format.

+
+
+
+ +
+
+get_rulebases() list[ex_fuzzy.rules.RuleBase][source]
+

Returns a list with all the rules.

+
+
Returns:
+

list

+
+
+
+ +
+
+get_rules() list[ex_fuzzy.rules.RuleSimple][source]
+

Returns a list with all the rules.

+
+
Returns:
+

list with all the rules.

+
+
+
+ +
+
+get_scores() array[source]
+

Returns the dominance score for each rule in all the rulebases.

+
+
Returns:
+

array with the dominance score for each rule in all the rulebases.

+
+
+
+ +
+
+print_rules(return_rules=False) None[source]
+

Print all the rules for all the consequents.

+
+ +
+
+purge_rules(tolerance=0.001) None[source]
+

Delete the roles with a dominance score lower than the tolerance.

+
+
Parameters:
+

tolerance – tolerance to delete the rules.

+
+
+
+ +
+
+winning_rule_predict(X: array, time_moments: int) array[source]
+

Returns the winning rule for each sample. Takes into account dominance scores if already computed.

+
+
Parameters:
+

X – array with the values of the inputs.

+
+
Returns:
+

array with the winning rule for each sample.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/utils.html b/docs/build/html/function_resume/utils.html new file mode 100644 index 0000000..709d10d --- /dev/null +++ b/docs/build/html/function_resume/utils.html @@ -0,0 +1,435 @@ + + + + + + + Partition utils — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Partition utils

+

Functions that are not fuzzy-specific, but util for some computations. +Dedicated mostly to compute quantiles for fuzzy partitions.

+
+
+ex_fuzzy.utils.assign_time(a: array, observations: list[numpy.array]) int[source]
+

Assigns a temporal moment to a set of observations.

+
+
Parameters:
+
    +
  • a – array of boolean values.

  • +
  • observations – list of boolean arrays with the corresponding timestamps.

  • +
+
+
Returns:
+

the index of the correspondent time moment for the a-th observation.

+
+
Raises:
+

ValueError if a is not timestamped in any of the observation arrays.

+
+
+
+ +
+
+ex_fuzzy.utils.classify_temp(dates: DataFrame, cutpoints: tuple[str, str], time: str) array[source]
+

Classifies a set of dates according to the temporal cutpoints. Uses {time} as a the time resolution. +Returns an array where true values are those values contained between those two date points.

+
+
Parameters:
+
    +
  • dates – data observations to cut.

  • +
  • cutpoints – points to check.

  • +
  • time – time field to use as the criteria.

  • +
+
+
Returns:
+

boolean array. True values are those contained between the cutpoints.

+
+
+
+ +
+
+ex_fuzzy.utils.construct_conditional_frequencies(X: array, discrete_time_labels: list[int], initial_ffss: list[ex_fuzzy.fuzzy_sets.FS])[source]
+

Computes the conditional temporal function for a set of fuzzy sets according to their variation in time.

+
+
Parameters:
+
    +
  • X – numpy array, shape samples x features.

  • +
  • discrete_time_labels – discrete time labels.

  • +
  • initial_fs – initial fuzzy set list.

  • +
+
+
Returns:
+

conditional frequencies. Array shape (time steps, initial fuzzy sets)

+
+
+
+ +
+
+ex_fuzzy.utils.construct_partitions(X: array, fz_type_studied: FUZZY_SETS) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Returns a list of linguistic variables according to the kind of fuzzy specified.

+
+
Parameters:
+
    +
  • X – numpy array|pandas dataframe, shape samples x features.

  • +
  • fz_type_studied – fuzzy set type studied.

  • +
+
+
+
+ +
+
+ex_fuzzy.utils.create_multi_tempVariables(X_train: array, time_moments: array, fuzzy_type: FUZZY_SETS) list[list[ex_fuzzy.temporal.temporalFS]][source]
+

Creates a of list of lists of temporal fuzzy variables. Each corresponds to a fuzzy partition in a different moment in time. +(So, instead of having one vl for all time moments, you have one different for each time moment that represents the same idea)

+
+
Parameters:
+
    +
  • X_train – numpy array, shape samples x features.

  • +
  • time_moments – time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation.

  • +
  • precomputed_partitions – precomputed partitions for each feature.

  • +
+
+
Returns:
+

list of lists of temporal fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.create_tempVariables(X_train: array, time_moments: array, precomputed_partitions: list[ex_fuzzy.fuzzy_sets.fuzzyVariable]) list[ex_fuzzy.temporal.temporalFS][source]
+

Creates a list of temporal fuzzy variables.

+
+
Parameters:
+
    +
  • X_train – numpy array, shape samples x features.

  • +
  • time_moments – time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation.

  • +
  • precomputed_partitions – precomputed partitions for each feature.

  • +
+
+
Returns:
+

list of temporal fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.extend_fuzzy_sets_enum(new_fuzzy_sets_enum: FUZZY_SETS) list[ex_fuzzy.temporal.FUZZY_SETS][source]
+

Extends the fuzzy sets enum with additional types.

+
+
Parameters:
+

fuzzy_sets_enum – fuzzy sets enum.

+
+
Returns:
+

extended fuzzy sets enum.

+
+
+
+ +
+
+ex_fuzzy.utils.fixed_quantile_compute(x: array) list[float][source]
+

Computes a series of quantiles for each feature in numpy array. +Quantiles: [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1]

+
+
Parameters:
+

x – array samples x features

+
+
Returns:
+

list of quantiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.gt2_fuzzy_partitions_dataset(x0: array, resolution_exp: int = 1) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables using gt2 fuzzy sets. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters:
+
    +
  • x – numpy array|pandas dataframe, shape samples x features.

  • +
  • resolution_exp – exponent of the resolution of the partition. Default is -2, which means 0.01. (Number of significant decimals)

  • +
+
+
Returns:
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.partition3_quantile_compute(x: array) list[float][source]
+

Computes a series of quantiles partitioning the variable in 3 cases.

+

Quantiles: [0.00, 0.20, 0.50, 0.80, 1.00]

+
+
Parameters:
+

x – array samples x features

+
+
Returns:
+

list of quantiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.quartile_compute(x: array) list[float][source]
+

Computes the quartiles for each feature.

+
+
Parameters:
+

x – array samples x features

+
+
Returns:
+

list of quartiles for each feature

+
+
+
+ +
+
+ex_fuzzy.utils.t1_fuzzy_partitions_dataset(x0: array) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters:
+

x – numpy array|pandas dataframe, shape samples x features.

+
+
Returns:
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.t1_simple_partition(x: array) array[source]
+

Partitions the fuzzy variable in four trapezoidal memberships.

+
+
Parameters:
+

x – numpy array, vector of shape (samples, ).

+
+
Returns:
+

numpy array, vector of shape (variables, 4, 4).

+
+
+
+ +
+
+ex_fuzzy.utils.t1_three_partition(x: array) array[source]
+

Partitions the fuzzy variable in four trapezoidal memberships.

+
+
Parameters:
+

x – numpy array, vector of shape (samples, ).

+
+
Returns:
+

numpy array, vector of shape (variables, 3, 4).

+
+
+
+ +
+
+ex_fuzzy.utils.t2_fuzzy_partitions_dataset(x0: array) list[ex_fuzzy.fuzzy_sets.fuzzyVariable][source]
+

Partitions the dataset features into different fuzzy variables using iv fuzzy sets. Parameters are prefixed. +Use it for simple testing and initial solution.

+
+
Parameters:
+

x – numpy array|pandas dataframe, shape samples x features.

+
+
Returns:
+

list of fuzzy variables.

+
+
+
+ +
+
+ex_fuzzy.utils.t2_simple_partition(x: array) array[source]
+

Partitions the fuzzy variable in three trapezoidal memberships.

+
+
Parameters:
+

x – numpy array, vector of shape (samples, ).

+
+
Returns:
+

numpy array, vector of shape (variables, 3, 4, 2).

+
+
+
+ +
+
+ex_fuzzy.utils.temporal_assemble(X: array, y: array, temporal_moments: list[numpy.array])[source]
+

Assembles the data in the temporal moments in order to have partitions with balanced time moments in each one.

+
+
Parameters:
+
    +
  • X – data observations.

  • +
  • y – labels.

  • +
  • temporal_moments – list of boolean arrays. True values are those contained between the cutpoints in each moment.

  • +
+
+
Returns:
+

tuple of lists of data and labels for each temporal moment. +First tuple is: X_train, X_test, y_train, y_test +Second tuple is: train temporal moments, test temporal moments.

+
+
+
+ +
+
+ex_fuzzy.utils.temporal_cuts(X: DataFrame, cutpoints: list[tuple[str, str]], time_resolution: str = 'hour') list[numpy.array][source]
+

Returns a list of boolean indexes for each temporal moment. Performs the cuts between time steps using the cutpoints list.

+
+
Parameters:
+
    +
  • X – data observations to cut in temrporal moments.

  • +
  • temporal_moments – list of temporal moments to cut.

  • +
  • cutpoints – list of tuples with the cutpoints for each temporal moment.

  • +
  • time_resolution – time field to use as the criteria.

  • +
+
+
Returns:
+

list of boolean arrays. True values are those contained between the cutpoints in each moment.

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/function_resume/vis_rules.html b/docs/build/html/function_resume/vis_rules.html new file mode 100644 index 0000000..21cb392 --- /dev/null +++ b/docs/build/html/function_resume/vis_rules.html @@ -0,0 +1,255 @@ + + + + + + + Rule Visualization — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Rule Visualization

+

This is a the source file that contains the functions necessary to visualize the set of rules.

+
+ +

Returns the index of the rules that contain the most popular antecedent in the dataset.

+
+
Parameters:
+

rule_matrix – matrix with the rules.

+
+
Returns:
+

numpy array with the rules that contain the most popular antecedent in the dataset.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.connect_master_rulebase(mrule_base: MasterRuleBase) list[list[numpy.array]][source]
+

Connects antecedents connected by checking if both are in the same rule.

+
+
Parameters:
+

mrule_base – Master rule base to connect.

+
+
Returns:
+

List of list of pandas dataframes with the connections in adjacency matrix format.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.connect_rulebase(rulebase: RuleBase) list[numpy.array][source]
+

Connects antecedents connected by checking if both are in the same rule.

+
+
Parameters:
+

rulebase – Rule base to connect.

+
+
Returns:
+

List of pandas dataframes with the connections in adjacency matrix format.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.create_graph_connection(rules, possible_vl)[source]
+

Returns a square matrix where each number indicates if two nodes are connected. +Connectes by checking if both are in the same rule.

+
+
Parameters:
+
    +
  • rules – list with the rules.

  • +
  • possible_vl – number of linguistic variables.

  • +
+
+
Returns:
+

square matrix where each number indicates if two nodes are connected.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.filter_useless_columns(df: DataFrame) DataFrame[source]
+

Filter columns with only one value.

+
+
Parameters:
+

df – Dataframe to filter.

+
+
Returns:
+

Filtered dataframe.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.matrix_rule_base_form(rule_base: Rule) DataFrame[source]
+

Returns a matrix with the rule base in the form of a matrix to visualize.

+
+
Parameters:
+

mrule_base – Rule base to transform.

+
+
Returns:
+

Matrix with the rule base in the form of a matrix.

+
+
+
+ +
+
+ex_fuzzy.vis_rules.plot_fuzzy_variable(fuzzy_variable: fuzzyVariable) None[source]
+

Plots a fuzzy variable using trapezoidal membership functions.

+
+
Parameters:
+

fuzzy_variable – a fuzzy variable from the fuzzyVariable class in fuzzy_set module.

+
+
Returns:
+

None

+
+
+
+ +
+
+ex_fuzzy.vis_rules.visualize_rulebase(mrule_base: MasterRuleBase, export_path: str = None) None[source]
+

Visualize a rule base using low, medium and high partitions with 1 rule in common -> 1 edge connections.

+
+
Parameters:
+
    +
  • mrule_base – Master rule base to visualize.

  • +
  • export_path – Path to export the graph.

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html new file mode 100644 index 0000000..9ec2904 --- /dev/null +++ b/docs/build/html/genindex.html @@ -0,0 +1,820 @@ + + + + + + Index — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ A + | B + | C + | D + | E + | F + | G + | I + | L + | M + | N + | P + | Q + | R + | S + | T + | V + | W + +
+

A

+ + + +
+ +

B

+ + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

I

+ + + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

Q

+ + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

V

+ + +
+ +

W

+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/gt2.html b/docs/build/html/gt2.html new file mode 100644 index 0000000..d5a30bf --- /dev/null +++ b/docs/build/html/gt2.html @@ -0,0 +1,137 @@ + + + + + + + General Type 2 — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

General Type 2

+

General Type 2 Fuzzy sets are fully supported, however, they present a series of additional considerations when used in real domains:

+
    +
  • The resolution of the primary domain function is always capped at 4 significant decimals.

  • +
  • When the domain of the secondary function are real numbers, precision is capped at 4 significant decimals.

  • +
+

We believe that this precision can be enough for most applications, but in case it needs to be changed, it is enough to modify the fs.gt2.MAX_RES_SUPPORT constant to the desired number before instantiating the GT2 fuzzy set.

+

Computing with the GT2 is more costly than the rest of the sets. Specially, computing the GT2 fuzzy partitions, which are also notably more complex than in the rest of the fuzzy sets. +Essentially, a GT2 fuzzy partition is a dictionary where each value in the dictionary maps a value in the secondary domain to a fuzzy set. +When a new value needs to be computed, the closest known value in the secondary membership to the new one is used.

+

As an example, the function utils.gt2_fuzzy_partitions_dataset() returns a fuzzy partition using GT2 in the following manner:

+
    +
  1. Computes a IV partition for all the variables.

  2. +
  3. Discretizes the domain of the secondary membership to an arbitrary precision.

  4. +
  5. In each of the discretized points, computes a FS using as parameters of the trapezoid function the lower and upper memberships and the central point of them. This results in a triangle for each FS.

  6. +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/index.html b/docs/build/html/index.html new file mode 100644 index 0000000..03953d4 --- /dev/null +++ b/docs/build/html/index.html @@ -0,0 +1,192 @@ + + + + + + + Welcome to Ex-Fuzzy’s documentation! — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv new file mode 100644 index 0000000..78242fa Binary files /dev/null and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/optimize.html b/docs/build/html/optimize.html new file mode 100644 index 0000000..0ac0bc4 --- /dev/null +++ b/docs/build/html/optimize.html @@ -0,0 +1,149 @@ + + + + + + + Genetic algorithm details — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Genetic algorithm details

+

The genetic algorithm searchs for the optimal rule base for a problem. The criteria used to determine optimal is the one mentioned in Optimizing a Fuzzy rule base for a classification problem:

+
    +
  1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy.

  2. +
  3. Less antecedents: the less antecedents per rule, the better. We compute this using the average number of antecedents per rule. We to normalize this by dividing the number of antecedents per rule by the maximum allowed in the optimization)

  4. +
  5. Less rules: rule bases with less rules are prefered. We normalize this by dividing the number of rules present in the database with dominance score bigger than the minimum threshold by the possible number of rules allowed in the optimization.

  6. +
+

It is possible to use previously computed rulesin order to fine tune them. There are two ways to do this using the ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier:

+
    +
  1. Use the previously computed rules as the initial population for a new optimization problem. In that case, you can pass that rules to the initial_rules parameter the ex_fuzzy.rules.MasterRuleBase object.

  2. +
  3. Look for more efficient subsets of rules in the previously computed rules. In this case the genetic optimization will use those rules as the search space itself, and will try to optimize the best subset of them. In that case, you can pass that rules to the candidate_rules parameter the ex_fuzzy.rules.MasterRuleBase object.

  4. +
+
+

Limitations of the optimization process

+
    +
  • General Type 2 requires precomputed fuzzy partitions.

  • +
  • When optimizing IV fuzzy partitions: Not all possible shapes of trapezoids all supported. Optimized trapezoids will always have max memberships for the lower and upper bounds in the same points. Height of the lower membership is optimized by scaling. Upper membership always reaches 1 at some point.

  • +
+
+
+

Fitness function

+

By default, the fitness function is the convex combination of the Matthew Correlation Coefficient (95%), to the rule size preference (2.5%) and to the rule antecedent size preference (2.5%). +For more information about changing this fitness function check Extending Ex-Fuzzy.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/persistence.html b/docs/build/html/persistence.html new file mode 100644 index 0000000..5e836f3 --- /dev/null +++ b/docs/build/html/persistence.html @@ -0,0 +1,178 @@ + + + + + + + Persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Persistence

+

Rules can be saved and loaded using plain text. The specification for this format is the same the print format of the rules. +We can extract the rules from a model using the ex_fuzzy.eval_tools.eval_fuzzy_model method, which can can return the rules in string format if the return_rules parameter is set to True:

+
import pandas as pd
+
+from sklearn import datasets
+from sklearn.model_selection import train_test_split
+
+import sys
+
+import ex_fuzzy.fuzzy_sets as fs
+import ex_fuzzy.evolutionary_fit as GA
+import ex_fuzzy.utils as  utils
+import ex_fuzzy.eval_tools as eval_tools
+import ex_fuzzy.persistence as persistence
+import ex_fuzzy.vis_rules as vis_rules
+
+n_gen = 5
+n_pop = 30
+nRules = 15
+nAnts = 4
+vl = 3
+fz_type_studied = fs.FUZZY_SETS.t1
+
+# Import some data to play with
+iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+# Split the data into a training set and a test set
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+
+# We create a FRBC with the precomputed partitions and the specified fuzzy set type,
+fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts,
+                                            n_linguist_variables=vl, fuzzy_type=fz_type_studied)
+fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1)
+
+str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True)
+
+# Save the rules as a plain text file
+with open('rules_iris_t1.txt', 'w') as f:
+    f.write(str_rules)
+
+
+

The rules can be loaded from a file using the load_rules method of the FuzzyModel class:

+
# Load the rules from a file
+mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions)
+
+fl_classifier = GA.FuzzyRulesClassifier(precomputed_rules=mrule_base)
+
+
+

If we already created the FuzzyRulesClassifier object, we can load the rules using the load_master_rule_base method:

+
fl_classifier.load_master_rule_base(mrule_base)
+
+
+

You can also save the best rulebase found each x steps of the genetic tuning if you set the checkpoint parameter to that x number of steps.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/precom.html b/docs/build/html/precom.html new file mode 100644 index 0000000..2b6e0d5 --- /dev/null +++ b/docs/build/html/precom.html @@ -0,0 +1,140 @@ + + + + + + + Computing fuzzy partitions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computing fuzzy partitions

+

One of the most typical ways to compute fuzzy partitions is to use quantiles of the data. The module utils contains a series of functions +to generate fuzzy partitions for all the supported kinds of fuzzy sets. +The easiest way to compute these partitions is with the utils.construct_partitions function, specifying the fuzzy set desired:

+
import utils
+
+fz_type_studied = fs.FUZZY_SETS.t2
+precomputed_partitions = utils.construct_partitions(X, fz_type_studied)
+
+
+
+

About the precomputed partitions

+

Partitions computed using these method use three linguistic variables per fuzzy variable. We chose that number as it creates easily understandable +low, medium and high partitions. For the case of IV-fuzzy sets, the trapezoids constructed, both the lower and upper memberships +present 1 values in the same points. For the case of General Type 2 Fuzzy sets check General Type 2.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/py-modindex.html b/docs/build/html/py-modindex.html new file mode 100644 index 0000000..31993a5 --- /dev/null +++ b/docs/build/html/py-modindex.html @@ -0,0 +1,198 @@ + + + + + + Python Module Index — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ e +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ e
+ ex_fuzzy +
    + ex_fuzzy.centroid +
    + ex_fuzzy.classifiers +
    + ex_fuzzy.cognitive_maps +
    + ex_fuzzy.eval_rules +
    + ex_fuzzy.eval_tools +
    + ex_fuzzy.evolutionary_fit +
    + ex_fuzzy.fuzzy_sets +
    + ex_fuzzy.persistence +
    + ex_fuzzy.rule_mining +
    + ex_fuzzy.rules +
    + ex_fuzzy.temporal +
    + ex_fuzzy.utils +
    + ex_fuzzy.vis_rules +
+ + +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/search.html b/docs/build/html/search.html new file mode 100644 index 0000000..ece9b34 --- /dev/null +++ b/docs/build/html/search.html @@ -0,0 +1,133 @@ + + + + + + Search — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js new file mode 100644 index 0000000..55e5198 --- /dev/null +++ b/docs/build/html/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"docnames": ["api", "classifiers", "extending", "function_resume/centroid", "function_resume/classifiers", "function_resume/cognitive_maps", "function_resume/eval_rules", "function_resume/eval_tools", "function_resume/evolutionary_fit", "function_resume/fuzzy_sets", "function_resume/persistence", "function_resume/rule_mining", "function_resume/rules", "function_resume/temporal", "function_resume/utils", "function_resume/vis_rules", "gt2", "index", "optimize", "persistence", "precom", "step1", "step2", "step3", "step4", "tmpfs", "usage"], "filenames": ["api.rst", "classifiers.rst", "extending.rst", "function_resume\\centroid.rst", "function_resume\\classifiers.rst", "function_resume\\cognitive_maps.rst", "function_resume\\eval_rules.rst", "function_resume\\eval_tools.rst", "function_resume\\evolutionary_fit.rst", "function_resume\\fuzzy_sets.rst", "function_resume\\persistence.rst", "function_resume\\rule_mining.rst", "function_resume\\rules.rst", "function_resume\\temporal.rst", "function_resume\\utils.rst", "function_resume\\vis_rules.rst", "gt2.rst", "index.rst", "optimize.rst", "persistence.rst", "precom.rst", "step1.rst", "step2.rst", "step3.rst", "step4.rst", "tmpfs.rst", "usage.rst"], "titles": ["API", "Advanced classifiers", "Extending Ex-Fuzzy", "T2 Centroid compute", "Advanced Classifiers", "Fuzzy Cognitive Maps", "Rule Evaluation Functions", "Classification evaluation tools", "Evolutionary Algorithms to Fit the rules", "Fuzzy Sets Functions", "Classification persistence", "Rule Mining methods", "Fuzzy Rules Functions", "Temporal fuzzy sets", "Partition utils", "Rule Visualization", "General Type 2", "Welcome to Ex-Fuzzy\u2019s documentation!", "Genetic algorithm details", "Persistence", "Computing fuzzy partitions", "Creating fuzzy sets and fuzzy variables", "Using Fuzzy Rules", "Optimizing a Fuzzy rule base for a classification problem", "Visualize rules and results", "Temporal Fuzzy Sets", "Getting Started"], "terms": {"fuzzi": [0, 3, 7, 8, 10, 11, 14, 15, 16, 18, 19, 26], "set": [0, 2, 3, 4, 6, 8, 12, 14, 15, 16, 17, 19, 20, 22, 23, 26], "function": [0, 2, 3, 5, 7, 8, 13, 14, 15, 16, 17, 20, 21, 23, 24, 25], "rule": [0, 1, 3, 4, 7, 10, 13, 17, 18, 19, 21, 26], "evalu": [0, 8, 13, 17, 25], "classif": [0, 1, 6, 8, 12, 17, 18], "tool": [0, 2, 17], "visual": [0, 7, 17], "evolutionari": [0, 17], "algorithm": [0, 3, 4, 11, 12, 13, 17, 23], "fit": [0, 4, 7, 13, 17, 19, 23, 25, 26], "mine": [0, 1, 4, 17], "method": [0, 2, 10, 17, 19, 20, 22], "advanc": [0, 17], "classifi": [0, 8, 13, 14, 17, 25, 26], "persist": [0, 17], "cognit": [0, 17], "map": [0, 11, 16, 17], "partit": [0, 2, 7, 8, 11, 13, 15, 16, 17, 18, 19, 25], "util": [0, 2, 16, 17, 19, 20, 23, 25, 26], "t2": [0, 2, 8, 9, 12, 17, 20, 23, 26], "centroid": [0, 12, 17, 22], "comput": [0, 1, 4, 6, 9, 11, 12, 13, 14, 16, 17, 18, 21, 22, 23], "tempor": [0, 2, 8, 14, 17], "besid": [1, 23], "ex_fuzzi": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19, 21, 22, 23, 25, 26], "evolutionary_fit": [1, 2, 8, 11, 18, 19, 23, 26], "basefuzzyrulesclassifi": [1, 2, 7, 8, 13, 18, 19, 26], "possibl": [1, 6, 11, 18, 23, 24], "us": [1, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26], "modul": [1, 2, 4, 11, 12, 13, 15, 17, 20, 22, 23, 25], "which": [1, 3, 11, 14, 16, 19, 22, 23, 25], "contain": [1, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 20], "take": [1, 2, 8, 12, 13], "base": [1, 4, 6, 7, 8, 9, 11, 12, 13, 15, 17, 18, 21, 26], "combin": [1, 4, 11, 18], "other": [1, 2, 22, 23], "techniqu": 1, "There": [1, 18], "ar": [1, 2, 3, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 22, 23, 25, 26], "two": [1, 4, 14, 15, 18], "main": [1, 6, 22], "addit": [1, 2, 14, 16, 25], "class": [1, 2, 4, 6, 8, 9, 10, 11, 12, 13, 15, 19, 21, 22, 23], "measur": [1, 11, 18, 23], "doubl": [1, 4], "genet": [1, 2, 4, 8, 11, 13, 17, 19, 23], "tune": [1, 4, 18, 19, 23], "so": [1, 2, 8, 14, 22, 23, 24], "first": [1, 4, 8, 14, 22, 25], "larg": [1, 22], "number": [1, 4, 5, 6, 8, 9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 24], "can": [1, 2, 7, 11, 16, 18, 19, 21, 22, 23, 24, 25, 26], "consid": [1, 11], "potenti": 1, "good": [1, 11], "second": [1, 8, 14, 22, 25], "optim": [1, 2, 4, 8, 11, 12, 13, 17, 22, 26], "step": [1, 4, 5, 13, 14, 19, 21, 22, 26], "choos": [1, 4, 8], "best": [1, 4, 8, 18, 19, 23], "them": [1, 4, 6, 9, 11, 16, 18, 21, 22, 24, 25, 26], "The": [1, 3, 5, 6, 8, 11, 13, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26], "three": [1, 14, 20, 23, 24], "kind": [1, 2, 14, 20, 21, 22, 23, 24, 25], "rulemineclassifi": [1, 4], "check": [1, 12, 14, 15, 17, 18, 20], "all": [1, 6, 9, 11, 12, 13, 14, 16, 18, 20, 21, 22], "anteced": [1, 3, 4, 6, 8, 11, 12, 13, 15, 18, 22, 23, 24], "It": [1, 6, 7, 8, 11, 12, 13, 18, 23, 24], "look": [1, 2, 5, 11, 13, 18], "present": [1, 6, 8, 9, 13, 16, 18, 20], "minumum": 1, "qualiti": [1, 18, 23], "candid": [1, 4, 8, 11], "find": [1, 3, 22], "an": [1, 2, 3, 8, 11, 12, 14, 16, 21, 22], "subset": [1, 18], "fuzzyrulesclassifi": [1, 4, 19, 23], "perform": [1, 4, 6, 11, 12, 14, 17, 18, 22, 23, 24, 26], "initi": [1, 14, 18], "popul": [1, 8, 13, 18, 23], "anoth": [1, 22], "round": 1, "rulefinetuneclassifi": [1, 4], "both": [1, 6, 15, 20, 22, 23], "previou": [1, 22, 23], "approach": 1, "search": [1, 11, 17, 18], "hold": 1, "metric": [1, 6, 18, 23], "Then": [1, 22, 23], "final": 1, "rulebas": [1, 8, 11, 12, 13, 15, 19, 22, 23], "give": [1, 22, 23], "result": [1, 6, 16, 17, 22, 26], "definit": 1, "percentag": [1, 11], "appear": 1, "whole": [1, 2, 12], "dataset": [1, 6, 14, 15, 17, 19, 23, 25, 26], "we": [1, 16, 17, 18, 19, 20, 21, 22, 23, 25, 26], "averag": [1, 18], "membership": [1, 2, 3, 8, 9, 12, 13, 14, 15, 16, 18, 20, 21, 22, 25], "valu": [1, 2, 3, 8, 9, 11, 12, 13, 14, 15, 16, 20, 21, 22, 25], "each": [1, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 19, 22, 23, 24, 25], "sampl": [1, 4, 6, 8, 9, 11, 12, 13, 14, 23], "minimum": [1, 4, 11, 18], "t": [1, 12], "norm": [1, 12], "thi": [1, 2, 3, 6, 8, 9, 12, 13, 15, 16, 18, 19, 21, 22, 23, 24, 25, 26], "case": [1, 3, 12, 14, 16, 18, 20, 22, 26], "ratio": [1, 11], "between": [1, 6, 11, 14, 24], "particular": [1, 11], "expect": [1, 2, 11], "some": [2, 7, 14, 18, 19], "default": [2, 6, 8, 14, 18], "behaviour": 2, "compon": [2, 3], "easili": [2, 20, 21], "support": [2, 4, 6, 8, 11, 12, 13, 16, 17, 18, 20, 21, 23], "more": [2, 6, 12, 16, 18, 22, 23], "explain": [2, 17, 23, 26], "librari": [2, 17, 23], "program": 2, "object": [2, 6, 8, 9, 10, 11, 12, 18, 19, 21, 22, 23], "orient": 2, "creat": [2, 4, 11, 14, 17, 19, 20, 22, 23, 26], "inherit": 2, "from": [2, 8, 10, 11, 12, 15, 18, 19, 21, 22, 23, 25], "correspond": [2, 4, 8, 9, 12, 13, 14], "easi": [2, 23], "wai": [2, 12, 18, 20, 22, 23, 24, 25, 26], "implement": [2, 9, 13, 22], "nevertheless": 2, "long": 2, "numer": [2, 9, 13], "2": [2, 3, 6, 8, 9, 12, 14, 17, 18, 20, 21, 22, 25], "size": [2, 3, 8, 12, 13, 18, 23], "tupl": [2, 11, 14], "new": [2, 12, 16, 18], "exist": [2, 8], "fs": [2, 8, 9, 12, 13, 14, 16, 19, 20, 21, 22, 23, 26], "fuzzy_set": [2, 4, 8, 9, 11, 12, 13, 14, 15, 19, 20, 21, 23, 26], "enum": [2, 9, 12, 13, 14], "For": [2, 18, 20, 22, 23, 25], "exampl": [2, 16, 17, 22, 23, 25, 26], "t1": [2, 9, 11, 12, 19, 24], "you": [2, 14, 18, 19, 22, 23, 24], "how": [2, 22, 26], "do": [2, 11, 12, 18, 21, 22, 24, 25], "In": [2, 16, 18, 22, 23, 26], "order": [2, 14, 18, 22, 23, 25], "than": [2, 4, 6, 12, 13, 16, 18, 23], "those": [2, 4, 11, 14, 18, 23], "given": [2, 3, 4, 6, 8, 10, 11, 12, 13, 21, 25], "ex_fuzzzi": 2, "directli": 2, "necessari": [2, 15, 22], "through": 2, "fuzzyvari": [2, 4, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22], "chang": [2, 16, 18], "loss": [2, 8], "new_loss": 2, "sourc": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], "file": [3, 4, 6, 8, 9, 12, 15, 19], "iv": [3, 8, 9, 12, 14, 16, 18, 20, 23, 24], "commonli": 3, "when": [3, 5, 8, 12, 13, 16, 18, 22], "center_of_mass": 3, "z": 3, "arrai": [3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 22, 25], "w": [3, 19], "ponder": 3, "normal": [3, 6, 18], "weight": [3, 6], "paramet": [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 23], "vector": [3, 6, 9, 11, 12, 14], "referenci": [3, 8, 9], "return": [3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 19, 22], "sum": [3, 12], "compute_centroid_iv": 3, "karnik": [3, 12], "mendel": [3, 12], "compute_centroid_t2_l": 3, "float": [3, 4, 6, 8, 9, 11, 13, 14], "compute_centroid_t2_r": 3, "right": [3, 12], "lowest": 3, "consequent_centroid": [3, 12], "antecedent_membership": 3, "consequ": [3, 6, 8, 9, 11, 12, 13, 22, 23, 24], "m": 3, "x": [3, 4, 6, 8, 9, 11, 12, 13, 14, 19, 20, 23, 26], "matrix": [3, 8, 12, 13, 15], "dimens": [3, 12], "consequent_centroid_l": 3, "centroids_l": 3, "left": 3, "memebership": [3, 6], "centroids_r": 3, "consequent_centroid_r": 3, "nrule": [4, 8, 13, 19, 23, 25, 26], "int": [4, 5, 8, 9, 11, 12, 13, 14], "30": [4, 8, 13, 14, 19, 21, 23, 26], "nant": [4, 8, 11, 13, 19, 23, 25, 26], "4": [4, 8, 9, 13, 14, 16, 19, 22, 23, 26], "fuzzy_typ": [4, 8, 9, 11, 12, 13, 14, 19, 23, 25, 26], "none": [4, 5, 6, 7, 8, 11, 12, 13, 15], "toler": [4, 6, 8, 12, 13, 23, 25, 26], "0": [4, 6, 8, 9, 11, 12, 13, 14, 19, 21, 22, 23, 25, 26], "verbos": [4, 8, 13, 25], "fals": [4, 7, 8, 12, 13, 25], "n_class": [4, 8, 13, 25], "runner": [4, 8, 13], "1": [4, 6, 8, 9, 11, 12, 13, 14, 15, 18, 19, 20, 22, 23], "expansion_factor": 4, "linguistic_vari": [4, 8, 13, 19, 25], "list": [4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, 23], "classifiermixin": [4, 8], "A": [4, 21, 23, 25, 26], "work": [4, 12, 23, 25], "process": [4, 8, 12, 17, 22, 24, 26], "basi": 4, "obtain": [4, 8, 13, 22, 23, 24, 26], "better": [4, 18, 23], "one": [4, 9, 11, 12, 14, 15, 16, 18, 22, 25], "satisfi": 4, "constrain": 4, "y": [4, 6, 8, 11, 13, 14, 19, 23, 26], "n_gen": [4, 8, 13, 19, 23, 25, 26], "pop_siz": [4, 8, 13, 19, 23, 25, 26], "50": [4, 5, 13, 14, 23, 26], "checkpoint": [4, 8, 13, 19], "n_runner": 4, "train": [4, 6, 7, 8, 12, 13, 14, 17, 19, 24, 25, 26], "model": [4, 7, 8, 13, 19, 22, 24], "data": [4, 7, 8, 11, 13, 14, 19, 20, 22, 23, 26], "label": [4, 6, 7, 8, 11, 13, 14], "gener": [4, 7, 8, 13, 17, 18, 20, 21, 23, 25], "subject": 4, "per": [4, 6, 11, 12, 18, 20, 22, 23], "bigger": [4, 18], "save": [4, 8, 19], "text": [4, 10, 19], "thred": 4, "predict": [4, 8, 13, 23], "predcit": 4, "fine": [4, 18], "confid": [4, 6, 11, 17, 23], "lift": [4, 11, 17], "cognitive_map": [5, 17], "attractors_report": 5, "attractor": 5, "dict": [5, 9, 11, 12, 13], "numpi": [5, 8, 11, 12, 13, 14, 15], "print": [5, 7, 8, 10, 12, 13, 19, 24, 26], "report": 5, "found": [5, 8, 19, 23, 25, 26], "np": [5, 8, 9, 13, 22, 25], "look_pattern_st": 5, "fcm": 5, "fuzzycognitivemap": 5, "sim_step": 5, "pattern_len": 5, "max_period_s": 5, "built": 5, "pattern": [5, 6, 23], "state": 5, "simul": 5, "prolongu": 5, "param": [5, 8, 9, 12], "max_step": 5, "maximum": [5, 11, 18, 21, 23], "random_init": 5, "were": 5, "study_attractors_fcm": 5, "10": [5, 8, 13, 21, 23, 25, 26], "eval_rul": 6, "evalrulebas": 6, "mrule_bas": [6, 15, 19], "masterrulebas": [6, 8, 10, 11, 12, 13, 15, 18, 22, 23], "time_mo": [6, 8, 13, 14, 25], "add_auxiliary_rule_weight": 6, "add": [6, 12, 13], "domin": [6, 12, 13, 18, 23], "score": [6, 12, 13, 18, 23], "field": [6, 14], "master": [6, 8, 15, 17], "thei": [6, 16, 23, 24, 26], "aux_scor": 6, "aux_support": 6, "aux_confid": 6, "becaus": [6, 21, 22], "add_classification_metr": 6, "accuraci": [6, 12, 18, 23], "also": [6, 7, 9, 13, 16, 17, 19, 23, 24, 25, 26], "f1": 6, "precis": [6, 16], "recal": 6, "If": [6, 7, 8, 12, 13, 19, 24], "shape": [6, 8, 11, 12, 14, 18, 25], "featur": [6, 8, 11, 13, 14, 17], "add_full_evalu": 6, "individu": 6, "add_rule_weight": 6, "association_degre": 6, "associ": [6, 8, 11, 13, 22], "degre": [6, 21, 22, 23], "aux_dominance_scor": 6, "classification_ev": 6, "matthew": [6, 18, 23], "correl": [6, 18, 23], "coeffici": [6, 18, 23], "task": [6, 23], "mattew": 6, "compute_aux_pattern_confid": 6, "fire": [6, 12, 13], "strength": [6, 12, 13], "compute_aux_pattern_support": 6, "tnorm": [6, 12], "dvide": 6, "compute_pattern_confid": 6, "compute_pattern_support": 6, "dominance_scor": 6, "effective_rulesize_ev": 6, "where": [6, 12, 14, 15, 16], "mean": [6, 12, 14, 23], "onli": [6, 8, 9, 11, 12, 15, 22], "almost": 6, "ds": 6, "mani": 6, "have": [6, 11, 12, 14, 18, 21, 22, 25], "lower": [6, 12, 13, 16, 18, 20, 21], "size_antecedents_ev": 6, "eval": 7, "alreadi": [7, 12, 13, 19], "eval_tool": [7, 19, 24, 25, 26], "eval_fuzzy_model": [7, 19, 24, 26], "fl_classifi": [7, 13, 19, 23, 24, 25, 26], "x_train": [7, 13, 14, 19, 23, 24, 25, 26], "y_train": [7, 13, 14, 19, 23, 24, 25, 26], "x_test": [7, 13, 14, 19, 23, 24, 25, 26], "y_test": [7, 13, 14, 19, 23, 24, 25, 26], "plot_rul": [7, 13, 19, 24, 25, 26], "true": [7, 8, 12, 13, 14, 19, 24, 25, 26], "print_rul": [7, 8, 12, 13, 19, 24, 25, 26], "plot_partit": [7, 13, 19, 24, 25, 26], "return_rul": [7, 8, 12, 13, 19], "print_accuraci": [7, 13], "print_matthew": [7, 13], "plot": [7, 8, 13, 15, 24, 26], "test": [7, 13, 14, 19, 23], "n_linguist_vari": [8, 12, 13, 19, 23, 25, 26], "domain": [8, 9, 13, 16, 21], "precomputed_rul": [8, 13, 19], "system": [8, 10, 12, 13], "precomput": [8, 13, 14, 17, 18, 19, 23], "linguist": [8, 9, 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 26], "variabl": [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 20, 22, 23, 24, 25, 26], "customized_loss": 8, "loss_funct": 8, "custom": 8, "input": [8, 9, 11, 12, 13], "70": 8, "candidate_rul": [8, 18], "initial_rul": [8, 18], "kwarg": 8, "integ": [8, 13, 14], "run": [8, 13], "gnerat": [8, 13], "time": [8, 12, 13, 14, 25], "moment": [8, 13, 14, 25], "depend": [8, 13], "far": 8, "scratch": 8, "forward": [8, 12, 13, 23], "get_rulebas": [8, 12, 13], "get": [8, 13, 17, 24], "after": [8, 13, 24], "format": [8, 10, 12, 13, 15, 19], "load_master_rule_bas": [8, 19], "rule_bas": [8, 12, 13, 15], "load": [8, 10, 19, 23], "plot_fuzzy_vari": [8, 13, 15], "bool": [8, 12], "rename_fuzzy_vari": 8, "renam": [8, 12], "high": [8, 11, 15, 20], "low": [8, 11, 15, 20], "consist": [8, 21], "doe": [8, 26], "usual": [8, 23], "name": [8, 9, 11, 13, 21], "sort": 8, "accord": [8, 9, 12, 14, 24], "central": [8, 16], "point": [8, 9, 14, 16, 18, 20, 25], "explorerulebas": 8, "cancidate_rul": 8, "thread_runn": 8, "starmapparallel": 8, "01": [8, 12, 14], "problem": [8, 12, 17, 18], "pymoo": 8, "seri": [8, 9, 14, 16, 20, 22], "strategi": 8, "type": [8, 9, 11, 12, 13, 14, 17, 18, 19, 20, 21], "fitness_func": 8, "alpha": [8, 9, 12], "95": [8, 18], "beta": 8, "025": 8, "gamma": 8, "n_sampl": 8, "n_featur": 8, "fitrulebas": 8, "encode_rulebas": 8, "optimize_lv": 8, "construct": [8, 20, 21, 22], "gene": 8, "structur": 8, "chosen": 8, "index": [8, 12, 13, 14, 15, 17], "third": 8, "self": 8, "n_linguistic_vari": 8, "8": [8, 14, 21, 22], "trapezoid": [8, 9, 14, 15, 16, 18, 20, 21], "four": [8, 9, 14, 23], "prepar": 8, "antecedents_referenci": 8, "requir": [8, 11, 18, 22, 23, 25], "single_gen_s": 8, "975": 8, "0125": 8, "gt2": [9, 12, 14, 16, 24], "its": [9, 12, 22, 24], "most": [9, 15, 16, 20, 22, 26], "direct": 9, "applic": [9, 16], "like": 9, "fm": 9, "etc": 9, "str": [9, 10, 12, 13, 14, 15], "membership_paramet": 9, "defin": [9, 12, 21, 25], "basic": 9, "known": [9, 16], "zadeh": 9, "secondary_membership": 9, "significant_decim": 9, "alpha_cut": [9, 12], "5": [9, 11, 18, 19, 21, 22], "7": [9, 14], "9": 9, "unit_resolut": 9, "alpha_reduct": 9, "reduct": [9, 12], "reduc": 9, "cut": [9, 12, 14, 25], "ivf": [9, 13, 21], "secondmf_low": 9, "secondmf_upp": 9, "lower_height": 9, "compute_membership": [9, 13], "get_linguistic_vari": 9, "string": [9, 10, 12, 19], "linguistic_variable_nam": 9, "gaussianivf": 9, "gaussian": 9, "trapezoidal_membership": 9, "epsilon": 9, "0001": 9, "compris": 9, "start": [9, 17], "end": 9, "small": [9, 22], "stabil": 9, "adjust": 9, "accordingli": 9, "nan": 9, "issu": 9, "plain": [10, 19], "load_fuzzy_rul": [10, 19], "rules_print": 10, "fuzzy_vari": [10, 11, 15], "follow": [10, 16, 22, 25, 26], "specif": [10, 14, 19, 22], "same": [10, 12, 14, 15, 18, 19, 20, 21, 22, 24], "panda": [11, 14, 15, 19], "datafram": [11, 14, 15, 19, 23, 26], "differ": [11, 12, 14, 17, 21, 22, 23, 25, 26], "itemset": 11, "optimiz": 11, "rule_min": 11, "generate_rules_from_itemset": 11, "rulesimpl": [11, 12, 13, 22], "mine_rulebase_support": 11, "support_threshold": 11, "05": 11, "max_depth": 11, "3": [11, 14, 19, 23, 25, 26], "frequent": 11, "dim": 11, "threshold": [11, 12, 18], "decid": 11, "prune": 11, "denot": [11, 14, 22], "multiclass_mine_rulebas": 11, "confidence_threshold": 11, "lift_threshold": 11, "form": [11, 12, 15], "prune_rules_confidence_lift": 11, "remov": [11, 12], "meet": 11, "origin": [11, 25], "rule_search": 11, "apriori": 11, "simple_mine_rulebas": 11, "medium": [11, 15, 20], "simple_multiclass_mine_rulebas": 11, "infer": [12, 17, 22, 23, 26], "consequent_nam": 12, "encompass": 12, "add_rul": [12, 13], "add_rule_bas": [12, 13], "compute_firing_strenght": [12, 13], "correspo": [12, 13], "get_anteced": 12, "get_consequ": [12, 13], "get_rulebase_matrix": [12, 13], "get_rul": [12, 13], "get_scor": [12, 13], "autoprint": 12, "purge_rul": [12, 13], "001": [12, 13, 23, 25, 26], "delet": [12, 13], "role": [12, 13], "rename_con": 12, "winning_rule_predict": [12, 13, 22], "win": [12, 13], "account": [12, 13], "design": 12, "singl": 12, "itself": [12, 18], "_myprod": 12, "prod": 12, "multipl": 12, "now": [12, 22], "solut": [12, 14, 23], "studi": [12, 14], "new_rul": 12, "compute_antecedents_membership": 12, "dictionari": [12, 16], "ith": 12, "nth": 12, "must": 12, "compute_rule_antecedent_membership": 12, "scale": [12, 18], "truth": [12, 22], "last": 12, "abstract": 12, "deffuzifi": 12, "output": 12, "fl": 12, "been": [12, 23], "evalrul": 12, "prune_bad_rul": 12, "superior": 12, "remove_rul": 12, "ix": 12, "delete_list": 12, "rulebasegt2": [12, 22], "document": 12, "FOR": 12, "alpha_compute_rule_antecedent_membership": 12, "rulebaset1": [12, 22], "rulebaset2": [12, 22], "approxim": [12, 17], "except": 12, "ruleerror": 12, "messag": 12, "rais": [12, 14], "well": 12, "repres": [12, 14], "simplest": 12, "indic": [12, 15], "code": [12, 21, 26], "entri": 12, "n": [12, 14], "list_rules_to_matrix": 12, "rule_list": 12, "out": [12, 17], "expans": 13, "ad": 13, "new_fuzzy_set": 13, "alia": 13, "tmp_fuzzy_set": 13, "temporalfuzzyrulesclassifi": [13, 25], "eval_temporal_fuzzy_model": [13, 25], "test_time_mo": [13, 25], "temporalf": [13, 14], "std_fuzzy_set": 13, "conditional_vari": 13, "fix_tim": 13, "fix": 13, "inside_typ": 13, "og": 13, "befor": [13, 16, 21], "temporal_tim": 13, "temporalfuzzyvari": 13, "n_time_mo": 13, "temporalmasterrulebas": 13, "time_step_nam": 13, "extens": 13, "includ": [13, 25], "time_step": 13, "dedic": [14, 25], "mostli": 14, "quantil": [14, 20], "assign_tim": [14, 25], "observ": 14, "assign": [14, 25], "boolean": 14, "timestamp": 14, "th": 14, "valueerror": 14, "ani": [14, 21], "classify_temp": 14, "date": [14, 25], "cutpoint": [14, 25], "resolut": [14, 16], "criteria": [14, 18, 23], "construct_conditional_frequ": 14, "discrete_time_label": 14, "initial_ffss": 14, "condit": 14, "variat": 14, "discret": [14, 16, 25], "initial_f": 14, "frequenc": 14, "construct_partit": [14, 20, 23], "fz_type_studi": [14, 19, 20, 25], "specifi": [14, 19, 20, 21, 23], "create_multi_tempvari": 14, "instead": [14, 22], "vl": [14, 19], "idea": 14, "precomputed_partit": [14, 19, 20, 25], "create_tempvari": [14, 25], "extend_fuzzy_sets_enum": 14, "new_fuzzy_sets_enum": 14, "extend": [14, 17, 18], "fuzzy_sets_enum": 14, "fixed_quantile_comput": 14, "20": [14, 21, 25], "45": 14, "55": 14, "gt2_fuzzy_partitions_dataset": [14, 16], "x0": 14, "resolution_exp": 14, "prefix": 14, "simpl": [14, 22], "expon": 14, "signific": [14, 16], "decim": [14, 16], "partition3_quantile_comput": 14, "00": [14, 25], "80": 14, "quartile_comput": 14, "quartil": 14, "t1_fuzzy_partitions_dataset": 14, "t1_simple_partit": 14, "t1_three_partit": 14, "t2_fuzzy_partitions_dataset": 14, "t2_simple_partit": 14, "temporal_assembl": [14, 25], "temporal_mo": [14, 25], "assembl": 14, "balanc": [14, 25], "temporal_cut": [14, 25], "time_resolut": [14, 25], "hour": [14, 25], "temrpor": 14, "vis_rul": [15, 19], "choose_popular_rul": 15, "rule_matrix": 15, "popular": 15, "connect_master_rulebas": 15, "connect": 15, "adjac": 15, "connect_rulebas": 15, "create_graph_connect": 15, "possible_vl": 15, "squar": 15, "node": 15, "filter_useless_column": 15, "df": 15, "filter": 15, "column": [15, 19, 23, 25, 26], "matrix_rule_base_form": 15, "transform": 15, "visualize_rulebas": 15, "export_path": 15, "common": 15, "edg": 15, "path": 15, "export": [15, 24], "graph": [15, 24], "fulli": 16, "howev": [16, 22], "consider": [16, 22], "real": 16, "primari": 16, "alwai": [16, 18], "cap": 16, "secondari": 16, "believ": 16, "enough": 16, "need": [16, 21, 22, 23], "modifi": 16, "max_res_support": 16, "constant": 16, "desir": [16, 20, 23], "instanti": 16, "costli": 16, "rest": [16, 22], "special": [16, 17], "notabl": 16, "complex": 16, "essenti": 16, "closest": 16, "As": 16, "manner": 16, "arbitrari": 16, "upper": [16, 18, 20, 21], "triangl": 16, "logic": [17, 23], "focu": 17, "reason": 17, "section": [17, 23], "few": 17, "about": [17, 18, 23], "detail": 17, "limit": 17, "api": 17, "page": 17, "determin": 18, "mention": 18, "rang": [18, 21, 23, 25], "less": [18, 23], "sensibl": [18, 23], "imbal": [18, 23], "standard": [18, 23], "divid": 18, "allow": 18, "prefer": [18, 23], "databas": 18, "previous": 18, "rulesin": 18, "pass": 18, "effici": [18, 22], "space": [18, 25], "try": 18, "Not": 18, "max": 18, "bound": 18, "height": 18, "reach": 18, "By": 18, "convex": 18, "inform": 18, "ex": [18, 21, 22, 23, 24, 26], "extract": 19, "import": [19, 20, 21, 22, 23, 24, 26], "pd": [19, 23, 26], "sklearn": 19, "model_select": 19, "train_test_split": [19, 23, 26], "sy": 19, "ga": [19, 23, 26], "n_pop": 19, "15": [19, 21], "plai": 19, "iri": [19, 23, 26], "load_iri": [19, 23, 26], "feature_nam": [19, 23, 26], "target": [19, 23, 26], "split": [19, 23], "test_siz": [19, 23, 26], "33": [19, 23, 26], "random_st": [19, 23, 26], "frbc": 19, "str_rule": 19, "open": 19, "rules_iris_t1": 19, "txt": 19, "f": 19, "write": 19, "load_rul": 19, "fuzzymodel": 19, "One": 20, "typic": 20, "easiest": [20, 24], "chose": 20, "understand": 20, "procedur": 21, "cold": 21, "40": 21, "newli": 21, "would": [21, 22], "thing": [21, 23], "interv": 21, "cold2": 21, "certainti": 21, "just": [21, 23], "ordinari": 21, "could": 21, "even": 21, "our": [21, 25], "temperatur": [21, 22], "warm": 21, "25": 21, "hot": [21, 22], "onc": [21, 23, 25], "proper": [21, 23], "deduc": 21, "describ": 21, "solv": 22, "regress": 22, "straightforward": [22, 26], "suppos": 22, "air": 22, "condition": 22, "activate_smal": 22, "activate_medium": 22, "activate_larg": 22, "activ": 22, "IF": 22, "IS": 22, "THEN": 22, "frule": 22, "problemat": 22, "repeat": 22, "want": 22, "over": 22, "practic": 22, "simplifi": 22, "express": 22, "Its": 22, "relev": 22, "my_rul": 22, "length": 22, "argument": 22, "activates_larg": 22, "my_rulebas": 22, "quit": 22, "defuzzifi": 22, "up": [22, 23], "discuss": 22, "handl": 22, "highest": 22, "next": [22, 23, 26], "match": 23, "refer": 23, "conceptu": 23, "equival": 23, "prior": 23, "multipli": 23, "product": 23, "reli": 23, "cover": 23, "info": 23, "see": 23, "fach23": 23, "interfac": 23, "analog": 23, "scikit": 23, "learn": 23, "knowledg": 23, "ha": 23, "part": 23, "These": 23, "instruct": 23, "ten": 23, "conveni": 23, "tranin": 23, "sinc": 23, "And": 23, "screen": [24, 26], "network": 24, "interact": 24, "seen": 24, "automat": 24, "color": 24, "gephi": 24, "softwar": 24, "own": 24, "tf": 25, "influenc": 25, "comprehens": 25, "explan": 25, "kiah": 25, "thu": 25, "spceifi": 25, "continu": 25, "dai": 25, "stage": 25, "cut_point_morning0": 25, "cut_point_morning1": 25, "cut_points_morn": 25, "cut_point_daytime0": 25, "11": 25, "cut_point_daytime1": 25, "19": 25, "cut_points_daytim": 25, "cut_point_evening0": 25, "cut_point_evening1": 25, "23": 25, "cutpoints_even": 25, "variou": 25, "observatio": 25, "temporal_boolean_mark": 25, "x_total": 25, "equal": 25, "partition_mark": 25, "y_total": 25, "train_mark": 25, "test_mark": 25, "convert": 25, "temp_partit": 25, "x_total_arrai": 25, "drop": 25, "train_time_mo": 25, "explor": 26, "coupl": 26, "demo": 26, "folder": 26, "brief": 26, "piec": 26, "show": 26, "autom": 26, "perfom": 26, "manual": 26, "ech": 11}, "objects": {"ex_fuzzy": [[3, 0, 0, "-", "centroid"], [4, 0, 0, "-", "classifiers"], [5, 0, 0, "-", "cognitive_maps"], [6, 0, 0, "-", "eval_rules"], [7, 0, 0, "-", "eval_tools"], [8, 0, 0, "-", "evolutionary_fit"], [9, 0, 0, "-", "fuzzy_sets"], [10, 0, 0, "-", "persistence"], [11, 0, 0, "-", "rule_mining"], [12, 0, 0, "-", "rules"], [13, 0, 0, "-", "temporal"], [14, 0, 0, "-", "utils"], [15, 0, 0, "-", "vis_rules"]], "ex_fuzzy.centroid": [[3, 1, 1, "", "center_of_masses"], [3, 1, 1, "", "compute_centroid_iv"], [3, 1, 1, "", "compute_centroid_t2_l"], [3, 1, 1, "", "compute_centroid_t2_r"], [3, 1, 1, "", "consequent_centroid"], [3, 1, 1, "", "consequent_centroid_l"], [3, 1, 1, "", "consequent_centroid_r"]], "ex_fuzzy.classifiers": [[4, 2, 1, "", "FuzzyRulesClassifier"], [4, 2, 1, "", "RuleFineTuneClassifier"], [4, 2, 1, "", "RuleMineClassifier"]], "ex_fuzzy.classifiers.FuzzyRulesClassifier": [[4, 3, 1, "", "fit"], [4, 3, 1, "", "predict"]], "ex_fuzzy.classifiers.RuleFineTuneClassifier": [[4, 3, 1, "", "fit"], [4, 3, 1, "", "predict"]], "ex_fuzzy.classifiers.RuleMineClassifier": [[4, 3, 1, "", "fit"], [4, 3, 1, "", "predict"]], "ex_fuzzy.cognitive_maps": [[5, 1, 1, "", "attractors_report"], [5, 1, 1, "", "look_pattern_states"], [5, 1, 1, "", "study_attractors_FCM"]], "ex_fuzzy.eval_rules": [[6, 2, 1, "", "evalRuleBase"]], "ex_fuzzy.eval_rules.evalRuleBase": [[6, 3, 1, "", "add_auxiliary_rule_weights"], [6, 3, 1, "", "add_classification_metrics"], [6, 3, 1, "", "add_full_evaluation"], [6, 3, 1, "", "add_rule_weights"], [6, 3, 1, "", "association_degree"], [6, 3, 1, "", "aux_dominance_scores"], [6, 3, 1, "", "classification_eval"], [6, 3, 1, "", "compute_aux_pattern_confidence"], [6, 3, 1, "", "compute_aux_pattern_support"], [6, 3, 1, "", "compute_pattern_confidence"], [6, 3, 1, "", "compute_pattern_support"], [6, 3, 1, "", "dominance_scores"], [6, 3, 1, "", "effective_rulesize_eval"], [6, 3, 1, "", "size_antecedents_eval"]], "ex_fuzzy.eval_tools": [[7, 1, 1, "", "eval_fuzzy_model"]], "ex_fuzzy.evolutionary_fit": [[8, 2, 1, "", "BaseFuzzyRulesClassifier"], [8, 2, 1, "", "ExploreRuleBases"], [8, 2, 1, "", "FitRuleBase"]], "ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier": [[8, 3, 1, "", "customized_loss"], [8, 3, 1, "", "fit"], [8, 3, 1, "", "forward"], [8, 3, 1, "", "get_rulebase"], [8, 3, 1, "", "load_master_rule_base"], [8, 3, 1, "", "plot_fuzzy_variables"], [8, 3, 1, "", "predict"], [8, 3, 1, "", "print_rules"], [8, 3, 1, "", "rename_fuzzy_variables"]], "ex_fuzzy.evolutionary_fit.ExploreRuleBases": [[8, 3, 1, "", "fitness_func"]], "ex_fuzzy.evolutionary_fit.FitRuleBase": [[8, 3, 1, "", "encode_rulebase"], [8, 3, 1, "", "fitness_func"]], "ex_fuzzy.fuzzy_sets": [[9, 2, 1, "", "FS"], [9, 2, 1, "", "GT2"], [9, 2, 1, "", "IVFS"], [9, 2, 1, "", "fuzzyVariable"], [9, 2, 1, "", "gaussianIVFS"], [9, 1, 1, "", "trapezoidal_membership"]], "ex_fuzzy.fuzzy_sets.FS": [[9, 3, 1, "", "membership"], [9, 3, 1, "", "type"]], "ex_fuzzy.fuzzy_sets.GT2": [[9, 3, 1, "", "alpha_reduction"], [9, 3, 1, "", "membership"], [9, 3, 1, "", "type"]], "ex_fuzzy.fuzzy_sets.IVFS": [[9, 3, 1, "", "membership"], [9, 3, 1, "", "type"]], "ex_fuzzy.fuzzy_sets.fuzzyVariable": [[9, 3, 1, "", "compute_memberships"], [9, 3, 1, "", "domain"], [9, 3, 1, "", "fuzzy_type"], [9, 3, 1, "", "get_linguistic_variables"], [9, 3, 1, "", "linguistic_variable_names"]], "ex_fuzzy.fuzzy_sets.gaussianIVFS": [[9, 3, 1, "", "membership"], [9, 3, 1, "", "type"]], "ex_fuzzy.persistence": [[10, 1, 1, "", "load_fuzzy_rules"]], "ex_fuzzy.rule_mining": [[11, 1, 1, "", "generate_rules_from_itemsets"], [11, 1, 1, "", "mine_rulebase_support"], [11, 1, 1, "", "multiclass_mine_rulebase"], [11, 1, 1, "", "prune_rules_confidence_lift"], [11, 1, 1, "", "rule_search"], [11, 1, 1, "", "simple_mine_rulebase"], [11, 1, 1, "", "simple_multiclass_mine_rulebase"]], "ex_fuzzy.rules": [[12, 2, 1, "", "MasterRuleBase"], [12, 2, 1, "", "Rule"], [12, 2, 1, "", "RuleBase"], [12, 2, 1, "", "RuleBaseGT2"], [12, 2, 1, "", "RuleBaseT1"], [12, 2, 1, "", "RuleBaseT2"], [12, 4, 1, "", "RuleError"], [12, 2, 1, "", "RuleSimple"], [12, 1, 1, "", "list_rules_to_matrix"]], "ex_fuzzy.rules.MasterRuleBase": [[12, 3, 1, "", "add_rule"], [12, 3, 1, "", "add_rule_base"], [12, 3, 1, "", "compute_firing_strenghts"], [12, 3, 1, "", "fuzzy_type"], [12, 3, 1, "", "get_antecedents"], [12, 3, 1, "", "get_consequents"], [12, 3, 1, "", "get_rulebase_matrix"], [12, 3, 1, "", "get_rulebases"], [12, 3, 1, "", "get_rules"], [12, 3, 1, "", "get_scores"], [12, 3, 1, "", "n_linguist_variables"], [12, 3, 1, "", "print_rules"], [12, 3, 1, "", "purge_rules"], [12, 3, 1, "", "rename_cons"], [12, 3, 1, "", "winning_rule_predict"]], "ex_fuzzy.rules.Rule": [[12, 3, 1, "", "consequent_centroid"], [12, 3, 1, "", "membership"]], "ex_fuzzy.rules.RuleBase": [[12, 3, 1, "", "add_rule"], [12, 3, 1, "", "add_rules"], [12, 3, 1, "", "compute_antecedents_memberships"], [12, 3, 1, "", "compute_rule_antecedent_memberships"], [12, 3, 1, "", "forward"], [12, 3, 1, "", "fuzzy_type"], [12, 3, 1, "", "get_rulebase_matrix"], [12, 3, 1, "", "get_rules"], [12, 3, 1, "", "get_scores"], [12, 3, 1, "", "inference"], [12, 3, 1, "", "n_linguist_variables"], [12, 3, 1, "", "print_rules"], [12, 3, 1, "", "prune_bad_rules"], [12, 3, 1, "", "remove_rule"], [12, 3, 1, "", "remove_rules"], [12, 3, 1, "", "scores"]], "ex_fuzzy.rules.RuleBaseGT2": [[12, 3, 1, "", "alpha_compute_rule_antecedent_memberships"], [12, 3, 1, "", "compute_rule_antecedent_memberships"], [12, 3, 1, "", "forward"], [12, 3, 1, "", "fuzzy_type"], [12, 3, 1, "", "inference"]], "ex_fuzzy.rules.RuleBaseT1": [[12, 3, 1, "", "forward"], [12, 3, 1, "", "fuzzy_type"], [12, 3, 1, "", "inference"]], "ex_fuzzy.rules.RuleBaseT2": [[12, 3, 1, "", "forward"], [12, 3, 1, "", "fuzzy_type"], [12, 3, 1, "", "inference"]], "ex_fuzzy.temporal": [[13, 5, 1, "", "NEW_FUZZY_SETS"], [13, 5, 1, "", "TMP_FUZZY_SETS"], [13, 2, 1, "", "TemporalFuzzyRulesClassifier"], [13, 1, 1, "", "eval_temporal_fuzzy_model"], [13, 2, 1, "", "temporalFS"], [13, 2, 1, "", "temporalFuzzyVariable"], [13, 2, 1, "", "temporalMasterRuleBase"]], "ex_fuzzy.temporal.TemporalFuzzyRulesClassifier": [[13, 3, 1, "", "fit"], [13, 3, 1, "", "forward"], [13, 3, 1, "", "get_rulebase"], [13, 3, 1, "", "plot_fuzzy_variables"]], "ex_fuzzy.temporal.temporalFS": [[13, 3, 1, "", "fix_time"], [13, 3, 1, "", "inside_type"], [13, 3, 1, "", "membership"], [13, 3, 1, "", "type"]], "ex_fuzzy.temporal.temporalFuzzyVariable": [[13, 3, 1, "", "compute_memberships"], [13, 3, 1, "", "fix_time"], [13, 3, 1, "", "n_time_moments"]], "ex_fuzzy.temporal.temporalMasterRuleBase": [[13, 3, 1, "", "add_rule"], [13, 3, 1, "", "add_rule_base"], [13, 3, 1, "", "compute_firing_strenghts"], [13, 3, 1, "", "fuzzy_type"], [13, 3, 1, "", "get_consequents"], [13, 3, 1, "", "get_rulebase_matrix"], [13, 3, 1, "", "get_rulebases"], [13, 3, 1, "", "get_rules"], [13, 3, 1, "", "get_scores"], [13, 3, 1, "", "print_rules"], [13, 3, 1, "", "purge_rules"], [13, 3, 1, "", "winning_rule_predict"]], "ex_fuzzy.utils": [[14, 1, 1, "", "assign_time"], [14, 1, 1, "", "classify_temp"], [14, 1, 1, "", "construct_conditional_frequencies"], [14, 1, 1, "", "construct_partitions"], [14, 1, 1, "", "create_multi_tempVariables"], [14, 1, 1, "", "create_tempVariables"], [14, 1, 1, "", "extend_fuzzy_sets_enum"], [14, 1, 1, "", "fixed_quantile_compute"], [14, 1, 1, "", "gt2_fuzzy_partitions_dataset"], [14, 1, 1, "", "partition3_quantile_compute"], [14, 1, 1, "", "quartile_compute"], [14, 1, 1, "", "t1_fuzzy_partitions_dataset"], [14, 1, 1, "", "t1_simple_partition"], [14, 1, 1, "", "t1_three_partition"], [14, 1, 1, "", "t2_fuzzy_partitions_dataset"], [14, 1, 1, "", "t2_simple_partition"], [14, 1, 1, "", "temporal_assemble"], [14, 1, 1, "", "temporal_cuts"]], "ex_fuzzy.vis_rules": [[15, 1, 1, "", "choose_popular_rules"], [15, 1, 1, "", "connect_master_rulebase"], [15, 1, 1, "", "connect_rulebase"], [15, 1, 1, "", "create_graph_connection"], [15, 1, 1, "", "filter_useless_columns"], [15, 1, 1, "", "matrix_rule_base_form"], [15, 1, 1, "", "plot_fuzzy_variable"], [15, 1, 1, "", "visualize_rulebase"]]}, "objtypes": {"0": "py:module", "1": "py:function", "2": "py:class", "3": "py:method", "4": "py:exception", "5": "py:attribute"}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "function", "Python function"], "2": ["py", "class", "Python class"], "3": ["py", "method", "Python method"], "4": ["py", "exception", "Python exception"], "5": ["py", "attribute", "Python attribute"]}, "titleterms": {"api": 0, "advanc": [1, 4], "classifi": [1, 4, 23], "support": 1, "confid": 1, "lift": 1, "extend": 2, "ex": [2, 17], "fuzzi": [2, 5, 9, 12, 13, 17, 20, 21, 22, 23, 24, 25], "t2": 3, "centroid": 3, "comput": [3, 20], "cognit": 5, "map": 5, "rule": [6, 8, 11, 12, 15, 22, 23, 24], "evalu": [6, 7, 23], "function": [6, 9, 12, 18], "classif": [7, 10, 22, 23], "tool": 7, "evolutionari": 8, "algorithm": [8, 18], "fit": [8, 18], "set": [9, 13, 21, 24, 25], "persist": [10, 19], "mine": 11, "method": 11, "tempor": [13, 25], "partit": [14, 20], "util": 14, "visual": [15, 24], "gener": 16, "type": 16, "2": 16, "welcom": 17, "s": 17, "document": 17, "indic": 17, "tabl": 17, "genet": 18, "detail": 18, "limit": 18, "optim": [18, 23], "process": 18, "about": 20, "precomput": 20, "creat": 21, "variabl": 21, "us": 22, "base": [22, 23], "problem": [22, 23], "master": 22, "train": 23, "result": 24, "get": 26, "start": 26}, "envversion": {"sphinx.domains.c": 2, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 6, "sphinx.domains.index": 1, "sphinx.domains.javascript": 2, "sphinx.domains.math": 2, "sphinx.domains.python": 3, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.viewcode": 1, "sphinx": 56}}) \ No newline at end of file diff --git a/docs/build/html/step1.html b/docs/build/html/step1.html new file mode 100644 index 0000000..6ac46c2 --- /dev/null +++ b/docs/build/html/step1.html @@ -0,0 +1,172 @@ + + + + + + + Creating fuzzy sets and fuzzy variables — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Creating fuzzy sets and fuzzy variables

+
+

Fuzzy Sets

+

Ex-Fuzzy supports different kinds of fuzzy sets, but the procedure to use them all is the same. +Fuzzy sets have a name, a domain range and a membership function:

+
import ex_fuzzy.fuzzy_sets as fs
+
+cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40])
+
+
+

This code creates a fuzzy set named “Cold”, with a trapezoidal membership function and a domain that ranges from 0 to 40 degrees. +A fuzzy membership can be computed easily using the newly-created fuzzy set:

+
cold(8.2)
+
+
+

This would be the code to do the same thing using interval-valued fuzzy sets:

+
cold2 = fs.IVFS('Cold', [0, 0, 5, 10], [0, 0, 5, 15], [0,40], 0.8)
+
+
+

This code would create an interval-valued fuzzy set defined using a lower and upper membership function, +the same domain and name as before, and a maximum certainty of 0.8 for the lower membership. +The membership is computed just as an ordinary fuzzy set:

+
cold2(8.2)
+
+
+

We could use any of these kinds of fuzzy sets (or even general-type 2 fuzzy sets) to construct all the linguistic variables +for our temperature domain:

+
cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40])
+warm = fs.FS('Warm', [15, 20, 25, 30] , [0,40])
+hot = fs.FS('Hot', [25, 30, 40, 40] , [0,40])
+
+
+
+
+

Fuzzy Variables

+

Once we have the linguistic variables, we can construct a fuzzy variable. A fuzzy variable consists of a list of fuzzy sets +of the same kind and a proper name:

+
temperature = fs.fuzzyVariable('Temperature', [cold, warm, hot])
+
+
+

We do not need to specify domain or fuzzy set type, because the fuzzyVariable class deduces it from the fuzzy sets given in the list. +We can use a fuzzyVariable object to compute the memberships for a value to all the linguistic variables in the fuzzy variable:

+
temperature(8.2)
+
+
+

Once we have defined the fuzzy variables, we can use them to construct a fuzzy rule base. This step is described in Using Fuzzy Rules.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/step2.html b/docs/build/html/step2.html new file mode 100644 index 0000000..bce6a59 --- /dev/null +++ b/docs/build/html/step2.html @@ -0,0 +1,184 @@ + + + + + + + Using Fuzzy Rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Using Fuzzy Rules

+
+

Fuzzy Rules

+

Fuzzy rules can be used to solve both regression and classification problems.

+

The most straightforward way to construct a rule is to give a series of antecedents and a consequent. +For the case of classification, the consequent will be a class, and for regression, a fuzzy set. +Following the temperature example. Suppose we have these fuzzy sets as consequents to module +the use of air conditioner:

+
activate_small = fs.FS('Small', [0.0, 0.0, 0.1, 0.2],  [0,1])
+activate_medium = fs.FS('Small', [0.1, 0.4, 0.4, 0.5],  [0,1])
+activate_large = fs.FS('Small', [0.5, 0.8, 1.0, 1.0],  [0,1])
+
+activate = fs.fuzzyVariable('Activate', [activate_small, activate_medium, activate_large])
+
+
+

We can construct a rule for regression using the ex_fuzzy.rules.Rule class. +For example, the rule IF temperature IS hot THEN conditioner IS large can be implemented as:

+
import ex_fuzzy.rules as frule
+frule.Rule([hot], activate_large)
+
+
+

Then, we can use the membership method to obtain the degree of truth for a value in a rule, and the centroid method to +compute the centroid of the consequent.

+

This implementation, however, can be problematic when there is a considerable number of rules with repeated antecedents, +because we do not want to compute the degree of truth for a value for the same antecedents over and over. So, instead +of using the Rule class, it is more practical to use RuleBase and RuleSimple classes.

+
+
+

Rule Bases

+

RuleSimple is a class that simplifies the way in which rules are expressed. Its antecedents are expressed as a list, denoting the +linguistic variable relevant to the rule. The previous rule would be expressed as a RuleSimple as this:

+
my_rule = frule.RuleSimple([2], 2)
+
+
+

The length of the first list is the number of antecedents, and the second argument denotes that the consequent fuzzy set is “activates_large”. +RuleSimple is used by RuleBase class to efficiently compute the degrees of truth for all the antecedents for all the data, +and then use them when necessary. In order to create one rule base, we need the list of all the fuzzy variables to use, the consequent +and the rules expressed as RuleSimple objects:

+
my_rulebase = frule.RuleBaseT1([temperature], [my_rule], activate)
+
+
+

This is quite a simple case because we are using only one fuzzy variable and one rule, but the process is the same for more rules and variables. +Then, we can use “my_rule” using the inference method:

+
my_rulebase.inference(np.array([8.2]))
+
+
+

Which will return the defuzzified result of the fuzzy inference process. The process is the same for the rest of the fuzzy sets, but other +classes are required: RuleBaseT2, RuleBaseGT2.

+
+
+

Classification problems and Master Rule Bases

+

Up to now, we have discussed how to model a regression problem. Classification problems perform the inference in a different way, which require another kind of object: the ex_fuzzy.rules.MasterRuleBase. +This is because the way in which Ex-Fuzzy handles classification problems is by using one Rule Base per consequent. +So, the rules.MasterRuleBase class is used to handle the rule bases created for each class. An object of this class is created using +a list of rule bases, and its main method is rules.MasterRuleBase.winning_rule_predict() which returns the class obtained from the rule with highest association degree. +You can find more the specifics of the classification inference in the next steps.

+

The next step is Optimizing a Fuzzy rule base for a classification problem.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/step3.html b/docs/build/html/step3.html new file mode 100644 index 0000000..a61dc98 --- /dev/null +++ b/docs/build/html/step3.html @@ -0,0 +1,180 @@ + + + + + + + Optimizing a Fuzzy rule base for a classification problem — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + View page source +
  • +
+
+
+
+
+ +
+

Optimizing a Fuzzy rule base for a classification problem

+
+

Fuzzy rule based classifier

+

Usually, in classification inference we compute the matching degree of a sample for each rule in the rule base +(we refer as “rule base” to both ex_fuzzy.rules.RuleBase and ex_fuzzy.rules.MasterRuleBase objects as they are conceptually equivalent). +Then, the predicted class is the consequent class of that rule. In this library, besides the matching degree, we also use a prior, the Dominance Scores, +that are multiplied by the matching degree.

+

The Dominance Score is the product of the support and confidence of a rule, so that we rely more on those rules that are more general, and that +cover different patterns than those covered by other rules.

+

For more info about the dominance scores, you can see [Fach23].

+
+
+

Training a fuzzy rule based classifier

+

In order to train a fuzzy rule based classifier, Ex-Fuzzy uses a Genetic algorithm to tune the rules to the +desired classification task. The interface to use this kind of classifiers is analogous to the standard used +in scikit-learn, so it requires no previous knowledge about fuzzy logic in order to work.

+

For example, we load the iris dataset and split it in train and test:

+
iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+
+
+

Once the data has been loaded, we just need to create a classifier with the proper parameters, number of rules, +maximum number of antecedents per rule, number of linguist variables per fuzzy variable and tolerance, which will explained +in the evaluation part of this section:

+
import ex_fuzzy.evolutionary_fit as GA
+
+fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3,
+                                             fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001)
+
+
+

These instructions will optimize the linguistic variables in each fuzzy variable, using IV fuzzy sets, using three linguistic variables and ten rules with up to four antecedents. +It is also possible to give a precomputed set of linguistic variables as a list of fuzzy variables. A convenient way to compute +these with easy can be found on the utils module, by means of the ex_fuzzy.utils.construct_partitions function.

+

Once the classifier has been created, the next thing is tranining it. Since we are using a Genetic algorithm, we can specify the number +of generations and the population size:

+
fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30)
+
+
+

And then we can use forward or predict just as with a scikit-learn classifier.

+
+
+

Evaluation

+

The genetic algorithm needs a fitness measure to evaluate the quality of each solution. In order to obtain the best possible set of rules, +Ex-Fuzzy uses three different criteria.

+
    +
  1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy.

  2. +
  3. Less antecedents: the less antecedents per rule, the better.

  4. +
  5. Less rules: rule bases with less rules are prefered.

  6. +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/step4.html b/docs/build/html/step4.html new file mode 100644 index 0000000..2c1e15a --- /dev/null +++ b/docs/build/html/step4.html @@ -0,0 +1,147 @@ + + + + + + + Visualize rules and results — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Visualize rules and results

+

Ex-Fuzzy can also visualize the fuzzy sets and the rules obtained after the training process. +The easiest way to do this is using the eval_tools.eval_fuzzy_model function:

+
import eval_tools
+eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True)
+
+
+

This function prints the performance of the model, prints the rules on screen and plot the rules as graphs.

+
+

Visualize Rules

+

You can visualize each consequent rules as a network, so that the interactions between the antecedents can be seen.

+_images/red_fuzzy.png +

If the number of linguistic variables is three, they also get automatically colored. It is also possible to export them to the gephi software.

+
+
+

Visualize Fuzzy Sets

+

Each fuzzy set is also visualized according to its own kind. The same linguistic variable can be visualized using T1, IV and GT2 fuzzy sets:

+_images/ejemplo_t1.png +_images/ejemplo_t2.png +_images/example_gt2.png +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/tmpfs.html b/docs/build/html/tmpfs.html new file mode 100644 index 0000000..995072f --- /dev/null +++ b/docs/build/html/tmpfs.html @@ -0,0 +1,168 @@ + + + + + + + Temporal Fuzzy Sets — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Temporal Fuzzy Sets

+

Temporal Fuzzy Sets (TFS) are a generalization of fuzzy sets to include a temporal variable that influences the membership values. +A comprehensive explanation of such fuzzy sets can be found in [Kiah].

+

Temporal fuzzy sets thus require the additional temporal variable, which can be spceified in the dedicated functions that work with this kind of fuzzy sets. +The way in which is the temporal variable is used is by first discretizing the the temporal variable from a continuous into a discrete time space. For example, +our time variable is the seconds of the day, we can do the following to define the different stages of the day:

+
cut_point_morning0 = '00:00:00'
+cut_point_morning1 = '10:00:00'
+cut_points_morning = [cut_point_morning0, cut_point_morning1]
+cut_point_daytime0 = '11:00:00'
+cut_point_daytime1 = '19:00:00'
+cut_points_daytime = [cut_point_daytime0, cut_point_daytime1]
+cut_point_evening0 = '20:00:00'
+cut_point_evening1 = '23:00:00'
+cutpoints_evening = [cut_point_evening0, cut_point_evening1]
+
+
+

Once we have defined this cut points, there are various functions in the ex_fuzzy.utils module to assign each of the observatio to one of the temporal moments:

+
temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour')
+time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])])
+
+
+

We can also partition the dataset equally in order to have balanced partitions in each of the temporal moments:

+
partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers)
+X_train, X_test, y_train, y_test = partitions
+train_markers, test_markers = partition_markers
+
+
+

Given the time moments and the original fuzzy partitions, we can convert them into temporal fuzzy partitions:

+
temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions)
+
+
+

The temporal fuzzy partitions are then used to train the temporal fuzzy classifier:

+
X_train = X_train.drop(columns=['date'])
+X_test = X_test.drop(columns=['date'])
+fl_classifier = temporal.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts,
+    linguistic_variables=temp_partitions, n_linguist_variables=3,
+    fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_classes=2)
+fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments)
+
+
+

The temporal fuzzy classifier can be evaluated using the eval_temporal_fuzzy_model function in the ex_fuzzy.eval_tools module:

+
eval_tools.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                            time_moments=train_time_moments, test_time_moments=test_time_moments,
+                            plot_rules=False, print_rules=True, plot_partitions=False)
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/html/usage.html b/docs/build/html/usage.html new file mode 100644 index 0000000..885e99e --- /dev/null +++ b/docs/build/html/usage.html @@ -0,0 +1,147 @@ + + + + + + + Getting Started — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Getting Started

+

The most straightforward way to use Ex-Fuzzy is to fit a fuzzy rule based classifier to a dataset, and then explore the results and the rules obtained. +A couple of examples of this can be found in the “demos” folder.

+

A brief piece of code that does this case of use is the following:

+
import ex_fuzzy.fuzzy_sets as fs
+import ex_fuzzy.evolutionary_fit as GA
+import ex_fuzzy.utils as  utils
+import ex_fuzzy.eval_tools as eval_tools
+
+iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3,
+                                             fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001)
+fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30)
+
+eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True)
+
+
+

This code trains the classifier and also plots the rules, prints them on screen and show the linguistic variables optimized in the process.

+

In the following, we will explain how the different processes to perform fuzzy inference are automated in this code, and how they can be perfomed manually.

+

The next step is Creating fuzzy sets and fuzzy variables.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/index.html b/docs/build/index.html new file mode 100644 index 0000000..7599e51 --- /dev/null +++ b/docs/build/index.html @@ -0,0 +1,178 @@ + + + + + + + Welcome to Ex-Fuzzy’s documentation! — Ex-Fuzzy documentation + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/objects.inv b/docs/build/objects.inv new file mode 100644 index 0000000..bf04e44 Binary files /dev/null and b/docs/build/objects.inv differ diff --git a/docs/build/optimize.html b/docs/build/optimize.html new file mode 100644 index 0000000..e5a716a --- /dev/null +++ b/docs/build/optimize.html @@ -0,0 +1,148 @@ + + + + + + + Genetic algorithm details — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Genetic algorithm details

+

The genetic algorithm searchs for the optimal rule base for a problem. The criteria used to determine optimal is the one mentioned in Optimizing a Fuzzy rule base for a classification problem:

+
    +
  1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy.

  2. +
  3. Dominance scores: are related to the support and confidence of each rule. So, rules that do not significantly fire or that are not discriminative are penalized. Thos that have a value less than the tolerance parmeter are dleted fro mthe rule base.

  4. +
  5. Small preference: rule bases with less rules and less antecedents are prefered.

  6. +
+

In order to understand dominance scores, we recommend reading the following paper: +Antonelli, M., Bernardo, D., Hagras, H. & Marcelloni, F. Multiobjective evolutionary optimization of type-2 fuzzy rule-based systems for financial data classification. IEEE Trans. Fuzzy Syst. 25, 249–264 (2017)

+
+

Limitations of the optimization process

+
    +
  • General Type 2 requires precomputed fuzzy partitions.

  • +
  • When optimizing IV fuzzy partitions: Not all possible shapes of trapezoids all supported. Optimized trapezoids will always have max memberships for the lower and upper bounds in the same points. Height of the lower membership is optimized by scaling. Upper membership always reaches 1 at some point.

  • +
+
+
+

Fitness functions

+

The fitness function is a convex combination of two different scores. The Matthew Correlation Coefficient and a small size preference. +The small size preference is computed as:

+
+\[1 - \frac{\text{antecedents used}}{\text{total antecedents possible}}\]
+

In this way, if the rule base uses 0 antecedents it would perfect according to this criteria, and a rule base that used the max number of antecedents in each rule would be considered the worst. +Of course, extreme cases such as using 0 antecedents are not desirable, but they are not problematic since the first fitness criteria would discard empty or useless rule base.

+

The convex combination is set to put 99% of importance to the Matthew Correlation Coefficient and 1% to the size preference, so that this loss is only used in draws. For more information about +changing this fitness function check Extending Ex-Fuzzy.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/persistence.html b/docs/build/persistence.html new file mode 100644 index 0000000..f2985d3 --- /dev/null +++ b/docs/build/persistence.html @@ -0,0 +1,173 @@ + + + + + + + Persistence — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Persistence

+

Rules can be saved and loaded using plain text. The specification for this format is the same the print format of the rules. +We can extract the rules from a model using the ex_fuzzy.eval_tools.eval_fuzzy_model method, which can can return the rules in string format if the return_rules parameter is set to True:

+
import pandas as pd
+
+from sklearn import datasets
+from sklearn.model_selection import train_test_split
+
+import sys
+
+import ex_fuzzy.fuzzy_sets as fs
+import ex_fuzzy.evolutionary_fit as GA
+import ex_fuzzy.utils as  utils
+import ex_fuzzy.eval_tools as eval_tools
+import ex_fuzzy.persistence as persistence
+import ex_fuzzy.vis_rules as vis_rules
+
+n_gen = 5
+n_pop = 30
+nRules = 15
+nAnts = 4
+vl = 3
+fz_type_studied = fs.FUZZY_SETS.t1
+
+# Import some data to play with
+iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+# Split the data into a training set and a test set
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+
+# We create a FRBC with the precomputed partitions and the specified fuzzy set type,
+fl_classifier = GA.FuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts,
+                                            n_linguist_variables=vl, fuzzy_type=fz_type_studied)
+fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1)
+
+str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True)
+
+# Save the rules as a plain text file
+with open('rules_iris_t1.txt', 'w') as f:
+    f.write(str_rules)
+
+
+

The rules can be loaded from a file using the load_rules method of the FuzzyModel class:

+
# Load the rules from a file
+mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions)
+
+fl_classifier = GA.FuzzyRulesClassifier(precomputed_rules=mrule_base)
+
+
+

If we already created the FuzzyRulesClassifier object, we can load the rules using the load_master_rule_base method:

+
fl_classifier.load_master_rule_base(mrule_base)
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/precom.html b/docs/build/precom.html new file mode 100644 index 0000000..c7fe9b4 --- /dev/null +++ b/docs/build/precom.html @@ -0,0 +1,135 @@ + + + + + + + Computing fuzzy partitions — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Computing fuzzy partitions

+

One of the most typical ways to compute fuzzy partitions is to use quantiles of the data. The module utils contains a series of functions +to generate fuzzy partitions for all the supported kinds of fuzzy sets. +The easiest way to compute these partitions is with the utils.construct_partitions function, specifying the fuzzy set desired:

+
import utils
+
+fz_type_studied = fs.FUZZY_SETS.t2
+precomputed_partitions = utils.construct_partitions(X, fz_type_studied)
+
+
+
+

About the precomputed partitions

+

Partitions computed using these method use three linguistic variables per fuzzy variable. We chose that number as it creates easily understandable +low, medium and high partitions. For the case of IV-fuzzy sets, the trapezoids constructed, both the lower and upper memberships +present 1 values in the same points. For the case of General Type 2 Fuzzy sets check General Type 2.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/py-modindex.html b/docs/build/py-modindex.html new file mode 100644 index 0000000..ad90094 --- /dev/null +++ b/docs/build/py-modindex.html @@ -0,0 +1,169 @@ + + + + + + Python Module Index — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ e +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ e
+ ex_fuzzy +
    + ex_fuzzy.centroid +
    + ex_fuzzy.eval_rules +
    + ex_fuzzy.eval_tools +
    + ex_fuzzy.evolutionary_fit +
    + ex_fuzzy.fuzzy_sets +
    + ex_fuzzy.persistence +
    + ex_fuzzy.rules +
    + ex_fuzzy.utils +
+ + +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/search.html b/docs/build/search.html new file mode 100644 index 0000000..71aeb69 --- /dev/null +++ b/docs/build/search.html @@ -0,0 +1,129 @@ + + + + + + Search — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2023, Javier Fumanal Idocin.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/docs/build/searchindex.js b/docs/build/searchindex.js new file mode 100644 index 0000000..4a48e46 --- /dev/null +++ b/docs/build/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({docnames:["api","extending","function_resume/centroid","function_resume/eval_rules","function_resume/eval_tools","function_resume/evolutionary_fit","function_resume/fuzzy_sets","function_resume/persistence","function_resume/rules","function_resume/utils","gt2","index","optimize","persistence","precom","step1","step2","step3","step4","tmpfs","usage"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":4,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":3,"sphinx.domains.rst":2,"sphinx.domains.std":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["api.rst","extending.rst","function_resume/centroid.rst","function_resume/eval_rules.rst","function_resume/eval_tools.rst","function_resume/evolutionary_fit.rst","function_resume/fuzzy_sets.rst","function_resume/persistence.rst","function_resume/rules.rst","function_resume/utils.rst","gt2.rst","index.rst","optimize.rst","persistence.rst","precom.rst","step1.rst","step2.rst","step3.rst","step4.rst","tmpfs.rst","usage.rst"],objects:{"ex_fuzzy.centroid":[[2,1,1,"","center_of_masses"],[2,1,1,"","compute_centroid_iv"],[2,1,1,"","compute_centroid_t2_l"],[2,1,1,"","compute_centroid_t2_r"],[2,1,1,"","consequent_centroid"],[2,1,1,"","consequent_centroid_l"],[2,1,1,"","consequent_centroid_r"],[2,1,1,"","y_compute"]],"ex_fuzzy.eval_rules":[[3,2,1,"","evalRuleBase"]],"ex_fuzzy.eval_rules.evalRuleBase":[[3,3,1,"","add_classification_metrics"],[3,3,1,"","add_rule_weights"],[3,3,1,"","association_degree"],[3,3,1,"","classification_eval"],[3,3,1,"","compute_pattern_confidence"],[3,3,1,"","compute_pattern_support"],[3,3,1,"","dominance_scores"],[3,3,1,"","size_eval"]],"ex_fuzzy.eval_tools":[[4,1,1,"","eval_fuzzy_model"],[4,1,1,"","eval_temporal_fuzzy_model"]],"ex_fuzzy.evolutionary_fit":[[5,2,1,"","FitRuleBase"],[5,2,1,"","FuzzyRulesClassifier"],[5,2,1,"","TemporalFuzzyRulesClassifier"]],"ex_fuzzy.evolutionary_fit.FitRuleBase":[[5,3,1,"","fitness_func"]],"ex_fuzzy.evolutionary_fit.FuzzyRulesClassifier":[[5,3,1,"","customized_loss"],[5,3,1,"","fit"],[5,3,1,"","forward"],[5,3,1,"","get_rulebase"],[5,3,1,"","load_master_rule_base"],[5,3,1,"","plot_fuzzy_variables"],[5,3,1,"","predict"],[5,3,1,"","print_rules"],[5,3,1,"","rename_fuzzy_variables"]],"ex_fuzzy.evolutionary_fit.TemporalFuzzyRulesClassifier":[[5,3,1,"","fit"],[5,3,1,"","forward"],[5,3,1,"","get_rulebase"],[5,3,1,"","plot_fuzzy_variables"]],"ex_fuzzy.fuzzy_sets":[[6,2,1,"","FS"],[6,4,1,"","FUZZY_SETS"],[6,2,1,"","GT2"],[6,2,1,"","IVFS"],[6,2,1,"","fuzzyVariable"],[6,2,1,"","gaussianIVFS"],[6,2,1,"","temporalFS"],[6,2,1,"","temporalFuzzyVariable"],[6,1,1,"","trapezoidal_membership"]],"ex_fuzzy.fuzzy_sets.FS":[[6,3,1,"","membership"],[6,3,1,"","type"]],"ex_fuzzy.fuzzy_sets.GT2":[[6,3,1,"","alpha_reduction"],[6,3,1,"","membership"],[6,3,1,"","type"]],"ex_fuzzy.fuzzy_sets.IVFS":[[6,3,1,"","membership"],[6,3,1,"","type"]],"ex_fuzzy.fuzzy_sets.fuzzyVariable":[[6,3,1,"","compute_memberships"],[6,3,1,"","domain"],[6,3,1,"","fuzzy_type"],[6,3,1,"","get_linguistic_variables"],[6,3,1,"","linguistic_variable_names"]],"ex_fuzzy.fuzzy_sets.gaussianIVFS":[[6,3,1,"","membership"],[6,3,1,"","type"]],"ex_fuzzy.fuzzy_sets.temporalFS":[[6,3,1,"","fix_time"],[6,3,1,"","inside_type"],[6,3,1,"","membership"],[6,3,1,"","type"]],"ex_fuzzy.fuzzy_sets.temporalFuzzyVariable":[[6,3,1,"","compute_memberships"],[6,3,1,"","fix_time"],[6,3,1,"","n_time_moments"]],"ex_fuzzy.persistence":[[7,1,1,"","load_fuzzy_rules"]],"ex_fuzzy.rules":[[8,2,1,"","MasterRuleBase"],[8,2,1,"","Rule"],[8,2,1,"","RuleBase"],[8,2,1,"","RuleBaseGT2"],[8,2,1,"","RuleBaseT1"],[8,2,1,"","RuleBaseT2"],[8,2,1,"","RuleSimple"],[8,1,1,"","list_rules_to_matrix"],[8,2,1,"","temporalMasterRuleBase"]],"ex_fuzzy.rules.MasterRuleBase":[[8,3,1,"","add_rule"],[8,3,1,"","add_rule_base"],[8,3,1,"","compute_firing_strenghts"],[8,3,1,"","fuzzy_type"],[8,3,1,"","get_consequents"],[8,3,1,"","get_rulebase_matrix"],[8,3,1,"","get_rulebases"],[8,3,1,"","get_rules"],[8,3,1,"","get_scores"],[8,3,1,"","print_rules"],[8,3,1,"","purge_rules"],[8,3,1,"","rename_cons"],[8,3,1,"","winning_rule_predict"]],"ex_fuzzy.rules.Rule":[[8,3,1,"","consequent_centroid"],[8,3,1,"","membership"]],"ex_fuzzy.rules.RuleBase":[[8,3,1,"","add_rule"],[8,3,1,"","add_rules"],[8,3,1,"","compute_antecedents_memberships"],[8,3,1,"","compute_rule_antecedent_memberships"],[8,3,1,"","forward"],[8,3,1,"","fuzzy_type"],[8,3,1,"","get_rulebase_matrix"],[8,3,1,"","get_rules"],[8,3,1,"","get_scores"],[8,3,1,"","inference"],[8,3,1,"","print_rules"],[8,3,1,"","prune_bad_rules"],[8,3,1,"","remove_rule"],[8,3,1,"","remove_rules"],[8,3,1,"","scores"]],"ex_fuzzy.rules.RuleBaseGT2":[[8,3,1,"","alpha_compute_rule_antecedent_memberships"],[8,3,1,"","compute_rule_antecedent_memberships"],[8,3,1,"","forward"],[8,3,1,"","fuzzy_type"],[8,3,1,"","inference"]],"ex_fuzzy.rules.RuleBaseT1":[[8,3,1,"","forward"],[8,3,1,"","fuzzy_type"],[8,3,1,"","inference"]],"ex_fuzzy.rules.RuleBaseT2":[[8,3,1,"","forward"],[8,3,1,"","fuzzy_type"],[8,3,1,"","inference"]],"ex_fuzzy.rules.temporalMasterRuleBase":[[8,3,1,"","add_rule"],[8,3,1,"","add_rule_base"],[8,3,1,"","compute_firing_strenghts"],[8,3,1,"","fuzzy_type"],[8,3,1,"","get_consequents"],[8,3,1,"","get_rulebase_matrix"],[8,3,1,"","get_rulebases"],[8,3,1,"","get_rules"],[8,3,1,"","get_scores"],[8,3,1,"","print_rules"],[8,3,1,"","purge_rules"],[8,3,1,"","winning_rule_predict"]],"ex_fuzzy.utils":[[9,1,1,"","assign_time"],[9,1,1,"","classify_temp"],[9,1,1,"","construct_conditional_frequencies"],[9,1,1,"","construct_partitions"],[9,1,1,"","create_multi_tempVariables"],[9,1,1,"","create_tempVariables"],[9,1,1,"","fixed_quantile_compute"],[9,1,1,"","gt2_fuzzy_partitions_dataset"],[9,1,1,"","partition3_quantile_compute"],[9,1,1,"","quartile_compute"],[9,1,1,"","t1_fuzzy_partitions_dataset"],[9,1,1,"","t1_simple_partition"],[9,1,1,"","t1_three_partition"],[9,1,1,"","t2_fuzzy_partitions_dataset"],[9,1,1,"","t2_simple_partition"],[9,1,1,"","temporal_assemble"],[9,1,1,"","temporal_cuts"]],ex_fuzzy:[[2,0,0,"-","centroid"],[3,0,0,"-","eval_rules"],[4,0,0,"-","eval_tools"],[5,0,0,"-","evolutionary_fit"],[6,0,0,"-","fuzzy_sets"],[7,0,0,"-","persistence"],[8,0,0,"-","rules"],[9,0,0,"-","utils"]]},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","method","Python method"],"4":["py","attribute","Python attribute"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:method","4":"py:attribute"},terms:{"0":[3,5,6,8,9,12,13,15,16,17,19,20],"00":[9,19],"0001":6,"001":[8,17,19,20],"01":[8,9],"1":[3,5,6,8,9,12,13,14,16,17,19],"10":[5,15,17,19,20],"11":19,"15":[13,15],"19":19,"2":[1,2,3,5,6,8,9,11,12,14,15,16,19],"20":[9,15,19],"2017":12,"2022":19,"23":19,"249":12,"25":[12,15],"264":12,"3":[9,13,17,19,20],"30":[5,9,13,15,17,20],"33":[13,17,20],"4":[5,6,9,10,13,16,17,20],"40":15,"45":9,"5":[6,13,15,16],"50":[5,9,17,20],"55":9,"7":[6,9],"70":5,"8":[9,15,16],"80":9,"9":6,"99":12,"abstract":8,"boolean":9,"case":[2,8,9,10,12,14,16,20],"class":[1,3,5,6,7,8,13,15,16],"default":[1,3,8,9,10],"do":[8,12,15,16,17,18,19],"enum":[1,6,8],"export":18,"float":[2,3,5,6,9],"function":[0,1,2,4,5,9,10,11,14,15,18,19],"import":[12,13,14,15,16,17,18,20],"int":[4,5,6,8,9],"long":1,"new":[1,8,10],"return":[2,3,4,5,6,8,9,10,13,16],"true":[4,5,8,9,13,18,19,20],A:[15,17,19,20],And:17,As:[1,10],FOR:8,For:[12,14,16,17,19],IF:16,IS:16,If:[3,4,6,8,13,18],In:[1,10,12,16,17,20],It:[3,4,5,8,12,17,18],Its:16,Not:12,Of:12,One:14,THEN:16,The:[1,2,3,5,9,10,12,13,14,15,16,17,18,19,20],Then:16,These:17,_myprod:8,about:[11,12,17],accord:[5,6,8,9,12,18],accordingli:6,account:8,accuraci:[3,12,17],activ:16,activate_larg:16,activate_medium:16,activate_smal:16,activates_larg:16,add:[3,8],add_classification_metr:3,add_rul:8,add_rule_bas:8,add_rule_weight:3,addit:[1,10,19],adjust:6,after:[5,18],air:16,algorithm:[0,1,2,8,11,17],alia:6,all:[3,6,8,9,10,12,14,15,16],almost:3,alpha:[6,8],alpha_compute_rule_antecedent_membership:8,alpha_cut:[6,8],alpha_reduct:6,alreadi:[4,8,13],also:[3,4,6,10,17,18,19,20],although:10,alwai:[10,12],an:[1,2,5,8,9,10,15,16],analog:17,andreu:19,ani:[9,15],anteced:[2,3,8,12,16,17,18],antecedent_membership:2,antonelli:12,api:11,applic:[6,10],approxim:[8,11],ar:[1,2,3,5,6,8,9,10,11,12,16,17,19,20],arbitrari:10,argument:16,arrai:[2,3,4,5,6,8,9,19],artifici:19,assembl:9,assign:[9,19],assign_tim:[9,19],associ:[3,5,16],association_degre:3,author:[],autom:20,automat:18,autoprint:8,balanc:[9,19],base:[3,4,5,6,8,11,12,15,20],basic:6,becaous:1,becaus:[15,16],been:[8,17],befor:[6,10,15],behaviour:1,believ:10,bernardo:12,best:[5,17],between:[3,9,18],bool:[5,8],both:[14,16],bound:12,brief:20,can:[1,4,10,13,15,16,17,18,19,20],cap:10,center:2,center_of_mass:2,central:[5,10],centroid:[0,8,11,16],centroids_l:2,centroids_r:2,certainti:15,chang:[1,10,12],check:[8,9,11,12,14],checkpoint:[5,13],chose:14,classif:[0,3,5,8,11,12,16],classifi:[5,9,11,19,20],classification_ev:3,classify_temp:9,closest:10,code:[8,15,20],coeffici:[3,12,17],cold2:15,cold:15,color:18,column:[13,17,19,20],combin:12,commonli:2,complex:10,compon:[1,2],comprehens:19,compris:6,comput:[0,3,6,8,9,10,11,12,15,16,17],compute_antecedents_membership:8,compute_centroid_iv:2,compute_centroid_t2_l:2,compute_centroid_t2_r:2,compute_firing_strenght:8,compute_membership:6,compute_pattern_confid:3,compute_pattern_support:3,compute_rule_antecedent_membership:8,condit:9,condition:16,conditional_vari:6,confid:[3,12,17],consequ:[2,6,8,16,18],consequent_centroid:[2,8],consequent_centroid_l:2,consequent_centroid_r:2,consequent_nam:8,consid:12,consider:[10,16],consist:[5,15],constant:10,construct:[14,15,16],construct_conditional_frequ:9,construct_partit:[9,14],contain:[2,3,4,5,6,8,9,14],continuo:19,conveni:17,convert:19,convex:12,core:[5,9],correl:[3,12,17],correspo:8,correspond:[1,6,8,9],costli:10,could:[1,15],coupl:20,cours:12,creat:[1,9,11,13,14,16,17,20],create_multi_tempvari:9,create_tempvari:[9,19],criteria:[9,12,17],custom:5,customized_loss:5,cut:[6,8,9,19],cut_point_daytime0:19,cut_point_daytime1:19,cut_point_evening0:19,cut_point_evening1:19,cut_point_morning0:19,cut_point_morning1:19,cut_points_daytim:19,cut_points_morn:19,cutpoint:[9,19],cutpoints_even:19,d:12,dai:19,data:[4,5,9,12,13,14,16,17,20],datafram:[9,13,17,20],dataset:[3,9,11,13,17,19,20],date:[9,19],decim:[9,10],dedic:[9,19],deduc:15,deffuzifi:8,defin:[6,15,19],defuzzifi:16,degre:[3,15,16],delet:8,delete_list:8,demo:20,denot:[9,16],depend:[5,6,19],describ:15,design:8,desir:[10,12,14,17],detail:11,determin:12,dict:[6,8],dictionari:[8,10],differ:[8,9,11,12,15,17,19,20],dimens:[2,8],direct:6,discard:12,discret:[9,10,19],discrete_time_label:9,discrimin:[12,17],dlete:[12,17],document:8,doe:[5,20],domain:[5,6,10,15],domin:[3,8,12,17],dominance_scor:3,draw:12,drop:19,ds:3,dvide:3,each:[3,5,6,8,9,10,12,16,17,18,19],easi:[1,17],easiest:[14,18],easili:[1,14,15],effici:16,empti:12,encompass:8,end:6,enough:10,entri:8,epsilon:6,equal:19,essenti:10,etc:6,eval:4,eval_fuzzy_model:[4,13,18,20],eval_rul:3,eval_temporal_fuzzy_model:[4,19],eval_tool:[4,13,18,19,20],evalrul:8,evalrulebas:3,evalu:[0,5,11,19],even:15,evolutionari:[0,11,12],evolutionary_fit:[4,5,13,17,20],ex:[12,15,16,17,18,20],ex_fuzzi:[2,3,4,5,6,7,8,9,13,15,16,17,19,20],exampl:[10,11,16,17,19,20],expect:1,explain:[1,11,17,19,20],explan:19,explor:20,expon:9,express:16,extend:[11,12],extens:8,extract:13,extrem:12,f1:3,f:[12,13],fals:[4,5,8,19],far:5,featur:[3,5,9,11],feature_nam:[13,17,20],few:11,field:[3,9],file:[2,3,5,6,8,13],financi:12,find:2,fire:[3,8,12,17],first:[9,12,16,19],fit:[0,4,11,13,17,19,20],fitness_func:5,fitrulebas:5,fix:6,fix_tim:6,fixed_quantile_comput:9,fl:8,fl_classifi:[4,13,17,18,19,20],fm:6,focu:11,folder:20,follow:[1,7,10,12,16,19,20],form:8,format:[1,5,7,8,13],forward:[5,8,17],found:[5,17,19,20],four:[6,9,17],frac:12,frame:9,frbc:13,frequenc:9,fro:[12,17],from:[1,7,8,12,13,15,16,17,19],frule:16,fs:[1,5,6,8,9,10,13,14,15,16,17,20],fulli:10,fuman:[],fuminid:[],fuzzi:[0,2,4,5,7,9,10,12,13,20],fuzzy_set:[1,5,6,8,9,13,14,15,17,20],fuzzy_typ:[5,6,8,9,13,17,19,20],fuzzy_vari:7,fuzzymodel:13,fuzzyrulesclassifi:[4,5,13,17,20],fuzzyvari:[1,5,6,7,8,9,15,16],fz_type_studi:[9,13,14,19],ga:[13,17,19,20],gaussian:6,gaussianivf:6,gener:[4,5,11,12,14,15,17,19],genet:[1,5,11,17],gephi:18,get:[5,11,18],get_consequ:8,get_linguistic_vari:6,get_rul:8,get_rulebas:[5,8],get_rulebase_matrix:8,get_scor:8,give:[16,17],given:[2,3,5,7,8,15,19],gnerat:5,graph:18,gt2:[6,8,9,10,18],gt2_fuzzy_partitions_dataset:[9,10],h:[12,19],ha:17,hagra:[12,19],handl:16,have:[3,8,9,12,15,16,17,19],height:12,high:[5,14],highest:16,hot:[15,16],hour:[9,19],how:20,howev:16,idea:9,idocin:[],ieee:[12,19],imbal:[12,17],implement:[1,6,16],includ:[8,19],index:[8,9,11],indic:8,infer:[8,11,16,20],influenc:19,inform:12,inherit:1,initi:9,initial_f:9,initial_ffss:9,input:[5,6,8],insead:1,inside_typ:6,instanti:10,instead:[9,16],instruct:17,integ:[5,9],intellig:19,interact:18,interfac:[1,17],interv:15,iri:[13,17,20],issu:6,ith:8,its:[6,8,16,18],itself:8,iv:[1,2,5,6,8,9,10,12,14,17,18],ivf:[6,15],ix:8,j:19,javier:[],just:[1,15,17],karnik:[2,8],kiani:19,kind:[1,9,14,15,17,18,19],knowledg:17,known:[6,10],kwarg:5,label:[4,5,9],larg:16,last:8,learn:17,length:16,less:[12,17],librari:[1,11],like:[1,6],limit:11,linguist:[5,6,7,8,9,14,15,16,17,18,20],linguistic_vari:[5,13,19],linguistic_variable_nam:6,list:[1,4,5,6,7,8,9,15,16,17],list_rules_to_matrix:8,load:[5,7,13,17],load_fuzzy_rul:[7,13],load_iri:[13,17,20],load_master_rule_bas:[5,13],load_rul:13,logic:[11,17],look:6,loss:[5,12],loss_funct:5,low:[5,14],lower:[3,8,10,12,14,15],lower_height:6,lowest:2,m:[2,12,19],main:16,mani:3,manner:10,manual:20,map:10,marcelloni:12,mass:2,master:[3,5,11],masterrulebas:[3,5,7,8,16],matrix:[2,5,8],mattew:3,matthew:[3,12,17],max:12,max_res_support:10,maximum:[15,17],mean:[3,8,9],measur:[12,17],medium:14,membership:[1,2,5,6,8,9,10,12,14,15,16,19],membership_paramet:6,memebership:3,mendel:[2,8],mention:12,method:[1,7,13,14,16],metric:[12,17],mmebership:1,model:[4,5,13,18],model_select:13,modul:[8,11,14,16,17,19],moment:[5,6,9,19],more:[1,3,8,10,12,16],most:[6,10,14,16,20],mostli:9,mrule_bas:[3,13],mthe:[12,17],multiobject:12,multipl:8,must:8,my_rul:16,my_rulebas:16,n:[8,9],n_class:[5,19],n_featur:5,n_gen:[5,13,17,19,20],n_linguist_vari:[5,13,17,19,20],n_pop:13,n_sampl:5,n_time_mo:6,name:[5,6,15],nan:6,nant:[5,13,17,19,20],necessari:16,need:[10,15,16,17],network:18,new_rul:8,newli:15,next:[16,17,20],non:7,none:[3,4,5,6,8],norm:8,normal:[2,3],notabl:10,now:8,np:[5,6,19],nrule:[5,13,17,19,20],nth:8,number:[3,5,6,9,10,12,14,16,17,18],numer:[1,6],numpi:[2,3,4,5,6,8,9],object:[1,3,5,6,7,8,13,15,16],observ:9,observatio:19,obtain:[5,16,17,18,20],og:6,onc:[15,17,19],one:[6,8,9,10,12,16,19],onli:[3,6,7,8,12,16],open:13,optim:[5,8,11,16,20],option:[3,4,5,6,8],order:[1,9,12,16,17,19],ordinari:15,orient:1,origin:19,other:[1,16],our:[15,19],out:[8,11],output:[1,8],over:16,own:18,page:11,panda:[9,13],paper:12,param:[5,6,8],paramet:[2,3,4,5,6,7,8,9,10,13,17],parmet:[12,17],part:17,partit:[0,1,4,5,10,11,12,13,19],partition3_quantile_comput:9,partition_mark:19,pattern:3,pd:[13,17,20],penal:[12,17],per:[3,8,14,16,17],perez:19,perfect:12,perfom:20,perform:[3,8,9,11,12,17,18,20],persist:[0,11],piec:20,plai:13,plain:[7,13],plot:[4,5,18,20],plot_fuzzy_vari:5,plot_partit:[4,13,18,19,20],plot_rul:[4,13,18,19,20],point:[5,6,9,10,12,14,19],ponder:2,pop_siz:[5,13,17,19,20],popul:[5,17],possibl:[3,12,17,18],practic:16,precis:[3,10],precomput:[1,5,9,11,12,13,17],precomputed_partit:[9,13,14,19],precomputed_rul:[5,13],predict:[5,17],prefer:[12,17],prefix:9,present:[3,5,6,10,14],previou:[16,17],primari:10,print:[4,5,7,8,13,18,20],print_accuraci:4,print_matthew:4,print_rul:[4,5,8,13,18,19,20],problem:[1,5,8,11,12,16],problemat:[12,16],procedur:15,process:[5,8,11,16,18,20],prod:8,program:1,proper:[15,17],prune_bad_rul:8,purge_rul:8,put:12,pymoo:[1,5],qualiti:[12,17],quantil:[9,14],quartil:9,quartile_comput:9,quit:16,rais:9,random_st:[13,17,20],rang:[12,15,17,19],reach:12,read:12,real:10,reason:11,recal:3,recommend:12,reduc:6,reduct:[6,8],referenci:[2,6],regress:16,relat:[12,17],relev:16,remov:8,remove_rul:8,renam:[5,8],rename_con:8,rename_fuzzy_vari:5,repeat:16,replac:1,repres:[8,9],requir:[12,16,17,19],resolut:[9,10],resolution_exp:9,rest:[1,10,16],result:[3,10,11,16,20],return_rul:[4,5,8,13],right:[2,8],role:8,rule:[0,2,4,7,11,12,13,15,20],rule_bas:[5,8],rule_list:8,rulebas:[5,8,16],rulebasegt2:[8,16],rulebaset1:[8,16],rulebaset2:[8,16],rules_iris_t1:13,rules_print:7,rulesimpl:[8,16],run:5,runner:5,same:[1,7,8,9,12,13,14,15,16,18],sampl:[3,5,6,8,9],save:[5,13],scale:[8,12],scikit:17,score:[3,8,12,17],screen:[18,20],search:[1,11,12],second:[9,16,19],secondari:10,secondary_membership:6,secondmf_low:6,secondmf_upp:6,section:[11,17],seen:18,sensibl:[12,17],seri:[6,9,10,14,16],set:[0,1,2,3,7,8,9,10,11,12,13,14,16,17,20],shape:[3,5,8,9,12,19],show:20,signific:[9,10],significant_decim:6,significantli:[12,17],simpl:[9,16],simplest:[1,8],simplifi:16,sinc:[12,17],singl:8,size:[2,5,8,12,17],size_ev:3,sklearn:13,small:[6,12,16,17],so:[1,5,9,12,16,17,18],softwar:18,solut:[8,9,17],solv:16,some:[1,4,9,12,13],sort:5,sourc:[2,3,4,5,6,7,8,9],space:19,spceifi:19,special:[10,11],specif:[7,9,13],specifi:[9,13,14,15,17],split:[13,17],stabil:6,stage:19,standard:[12,17],starmapparallel:5,start:[6,11],std_fuzzy_set:6,step:[8,9,15,16,20],str:[6,7,8,9],str_rule:13,straightforward:[16,20],strategi:5,strength:[3,8],string:[6,7,8,13],studi:[8,9],sum:[2,8],superior:8,suplant:1,support:[1,3,5,8,10,11,12,14,15,17],suppos:16,sy:13,syst:12,system:[5,7,8,12,19],t1:[1,2,6,8,13,18],t1_fuzzy_partitions_dataset:9,t1_simple_partit:9,t1_three_partit:9,t2:[0,1,6,8,11,14,17,20],t2_fuzzy_partitions_dataset:9,t2_simple_partit:9,t:8,take:[5,8],target:[13,17,20],task:[3,17],temp_partit:19,temperatur:[15,16],tempor:[5,6,7,8,9,11],temporal_assembl:[9,19],temporal_boolean_mark:19,temporal_cut:[9,19],temporal_mo:[9,19],temporal_tim:6,temporalf:[6,9],temporalfuzzyrulesclassifi:[5,19],temporalfuzzyvari:6,temporalmasterrulebas:8,temrpor:9,ten:17,test:[4,9,13,17],test_mark:19,test_siz:[13,17,20],test_time_mo:[4,19],text:[7,12,13],tf:19,th:9,than:[3,8,10,12,17],thei:[1,3,10,12,18,20],them:[3,6,10,15,16,18,19,20],thi:[1,2,3,5,6,8,10,12,13,15,16,17,18,19,20],thing:[1,15,17],tho:[12,17],those:9,thread_runn:5,three:[9,14,17,18],threshold:8,thu:19,time:[5,6,8,9,19],time_mo:[3,4,5,8,9,19],time_resolut:[9,19],time_step:8,time_step_nam:8,timestamp:9,tnorm:[3,8],toler:[3,5,8,12,17,19,20],tool:[0,1,11],total:12,train:[3,4,5,9,11,13,18,19,20],train_mark:19,train_test_split:[13,17,20],train_time_mo:19,tran:12,tranin:17,transact:19,trapezoid:[6,9,10,12,14,15],trapezoidal_membership:6,triangl:10,truth:[8,16],tune:17,tupl:[1,9],two:[9,12],txt:13,type:[5,6,8,9,11,12,13,14,15,19],typic:14,understand:[12,14],unit_resolut:6,up:17,upper:[10,12,14,15],us:[1,2,3,4,5,7,8,9,10,11,12,13,14,15,17,18,19,20],useless:12,usual:5,util:[0,10,11,13,14,17,19,20],valu:[1,2,5,6,8,9,10,12,14,15,16,17,19],valueerror:9,variabl:[5,6,7,8,9,10,11,14,16,17,18,19,20],variat:9,variou:19,vector:[2,3,6,8,9],verbos:[5,19],vis_rul:13,visual:[4,11],vl:[9,13],w:[2,13],wai:[1,8,12,14,16,17,18,19,20],want:16,warm:15,we:[10,12,13,14,15,16,17,19,20],weight:2,when:[2,5,10,12,16],where:[3,8,9,10],which:[2,9,10,13,16,17,19],whole:[1,8],win:8,winning_rule_predict:[8,16],work:[8,17,19],worst:12,would:[12,15,16],write:13,x0:9,x:[2,3,5,6,8,9,13,14,17,20],x_test:[4,9,13,17,18,19,20],x_total:19,x_total_arrai:19,x_train:[4,9,13,17,18,19,20],y:[3,5,9,13,17,20],y_comput:2,y_test:[4,9,13,17,18,19,20],y_total:19,y_train:[4,9,13,17,18,19,20],you:[9,18],z:2,zadeh:6},titles:["API","Extending Ex-Fuzzy","T2 Centroid compute","Rule Evaluation Functions","Classification evaluation tools","Evolutionary Algorithms to Fit the rules","Fuzzy Sets Functions","Classification persistence","Fuzzy Rules Functions","Partition utils","General Type 2","Welcome to Ex-Fuzzy\u2019s documentation!","Genetic algorithm details","Persistence","Computing fuzzy partitions","Creating fuzzy sets and fuzzy variables","Using Fuzzy Rules","Optimizing a Fuzzy rule base for a classification problem","Visualize rules and results","Temporal Fuzzy Sets","Getting Started"],titleterms:{"2":10,"function":[3,6,8,12],about:14,algorithm:[5,12],api:0,base:[16,17],centroid:2,classif:[4,7,17],classifi:17,comput:[2,14],creat:15,detail:12,document:11,evalu:[3,4,17],evolutionari:5,ex:[1,11],extend:1,fit:[5,12],fuzzi:[1,6,8,11,14,15,16,17,18,19],gener:10,genet:12,get:20,indic:11,limit:12,master:16,optim:[12,17],partit:[9,14],persist:[7,13],precomput:14,problem:17,process:12,result:18,rule:[3,5,8,16,17,18],s:11,set:[6,15,18,19],start:20,t2:2,tabl:11,tempor:19,tool:4,train:17,type:10,us:16,util:9,variabl:15,visual:18,welcom:11}}) \ No newline at end of file diff --git a/docs/build/step1.html b/docs/build/step1.html new file mode 100644 index 0000000..3ab6d21 --- /dev/null +++ b/docs/build/step1.html @@ -0,0 +1,167 @@ + + + + + + + Creating fuzzy sets and fuzzy variables — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Creating fuzzy sets and fuzzy variables

+
+

Fuzzy Sets

+

Ex-Fuzzy supports different kinds of fuzzy sets, but the procedure to use them all is the same. +Fuzzy sets have a name, a domain range and a membership function:

+
import ex_fuzzy.fuzzy_sets as fs
+
+cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40])
+
+
+

This code creates a fuzzy set named “Cold”, with a trapezoidal membership function and a domain that ranges from 0 to 40 degrees. +A fuzzy membership can be computed easily using the newly-created fuzzy set:

+
cold(8.2)
+
+
+

This would be the code to do the same thing using interval-valued fuzzy sets:

+
cold2 = fs.IVFS('Cold', [0, 0, 5, 10], [0, 0, 5, 15], [0,40], 0.8)
+
+
+

This code would create an interval-valued fuzzy set defined using a lower and upper membership function, +the same domain and name as before, and a maximum certainty of 0.8 for the lower membership. +The membership is computed just as an ordinary fuzzy set:

+
cold2(8.2)
+
+
+

We could use any of these kinds of fuzzy sets (or even general-type 2 fuzzy sets) to construct all the linguistic variables +for our temperature domain:

+
cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40])
+warm = fs.FS('Warm', [15, 20, 25, 30] , [0,40])
+hot = fs.FS('Hot', [25, 30, 40, 40] , [0,40])
+
+
+
+
+

Fuzzy Variables

+

Once we have the linguistic variables, we can construct a fuzzy variable. A fuzzy variable consists of a list of fuzzy sets +of the same kind and a proper name:

+
temperature = fs.fuzzyVariable('Temperature', [cold, warm, hot])
+
+
+

We do not need to specify domain or fuzzy set type, because the fuzzyVariable class deduces it from the fuzzy sets given in the list. +We can use a fuzzyVariable object to compute the memberships for a value to all the linguistic variables in the fuzzy variable:

+
temperature(8.2)
+
+
+

Once we have defined the fuzzy variables, we can use them to construct a fuzzy rule base. This step is described Using Fuzzy Rules.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/step2.html b/docs/build/step2.html new file mode 100644 index 0000000..408ac41 --- /dev/null +++ b/docs/build/step2.html @@ -0,0 +1,177 @@ + + + + + + + Using Fuzzy Rules — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Using Fuzzy Rules

+
+

Fuzzy Rules

+

Fuzzy rules can be used to solve both regression and classification problems.

+

The most straightforward way to construct a rule is to give a series of antecedents and a consequent. +For the case of classification, the consequent will be a class, and for regression, a fuzzy set. +Following the temperature example. Suppose we have these fuzzy sets as consequents to module +the use of air conditioner:

+
activate_small = fs.FS('Small', [0.0, 0.0, 0.1, 0.2],  [0,1])
+activate_medium = fs.FS('Small', [0.1, 0.4, 0.4, 0.5],  [0,1])
+activate_large = fs.FS('Small', [0.5, 0.8, 1.0, 1.0],  [0,1])
+
+activate = fs.fuzzyVariable('Activate', [activate_small, activate_medium, activate_large])
+
+
+

We can construct a rule for regression using the ex_fuzzy.rules.Rule class. +For example, the rule IF temperature IS hot THEN conditioner IS large can be implemented as:

+
import ex_fuzzy.rules as frule
+frule.Rule([hot], activate_large)
+
+
+

Then, we can use the membership method to obtain the degree of truth for a value in a rule, and the centroid method to +compute the centroid of the consequent.

+

This implementation, however, can be problematic when there is a considerable number of rules with repeated antecedents, +because we do not want to compute the degree of truth for a value for the same antecedents over and over. So, instead +of using the Rule class, it is more practical to use RuleBase and RuleSimple classes.

+
+
+

Rule Bases

+

RuleSimple is a class that simplifies the way in which rules are expressed. Its antecedents are expressed as a list, denoting the +linguistic variable relevant to the rule. The previous rule would be expressed as a RuleSimple as this:

+
my_rule = frule.RuleSimple([2], 2)
+
+
+

The length of the first list is the number of antecedents, and the second argument denotes the fuzzy set “activates_large”. +RuleSimple is used by RuleBase class to efficiently compute the degrees of truth for all the antecedents for all the data, +and then use them when necessary. In order to create one rule base, we need the list of all the fuzzy variables to use, the consequent +and the rules expressed as RuleSimple objects:

+
my_rulebase = frule.RuleBaseT1([temperature], [my_rule], activate)
+
+
+

This is quite a simple case because we are using only one fuzzy variable and one rule, but the process is the same for more rules and variables. +Then, we can use “my_rule” using the inference method:

+
my_rulebase.inference(8.2)
+
+
+

Which will return the defuzzified result of the fuzzy inference process. The process is the same for the rest of the fuzzy sets, but other +classes are required: RuleBaseT2, RuleBaseGT2.

+
+
+

Master Rule Bases

+

Master Rules bases are required in a classification problem. The way in which Ex-Fuzzy handles classification problems is by using one Rule Base +per consequent. So, the rules.MasterRuleBase class is used to handle the rule bases created for each class. An object of this class is created using +a list of rule bases, and its main method is rules.MasterRuleBase.winning_rule_predict() which returns the class obtained from the rule with highest association degree.

+

The next step is Optimizing a Fuzzy rule base for a classification problem.

+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/step3.html b/docs/build/step3.html new file mode 100644 index 0000000..e84bc7e --- /dev/null +++ b/docs/build/step3.html @@ -0,0 +1,164 @@ + + + + + + + Optimizing a Fuzzy rule base for a classification problem — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + View page source +
  • +
+
+
+
+
+ +
+

Optimizing a Fuzzy rule base for a classification problem

+
+

Training a fuzzy rule based classifier

+

In order to train a fuzzy rule based classifier, Ex-Fuzzy uses a Genetic algorithm to tune the rules to the +desired classification task. The interface to use this kind of classifiers is analogous to the standard used +in scikit-learn, so it requires no previous knowledge about fuzzy logic in order to work.

+

For example, we load the iris dataset and split it in train and test:

+
iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+
+
+

Once the data has been loaded, we just need to create a classifier with the proper parameters, number of rules, +maximum number of antecedents per rule, number of linguist variables per fuzzy variable and tolerance, which will explained +in the evaluation part of this section:

+
import ex_fuzzy.evolutionary_fit as GA
+
+fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3,
+                                             fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001)
+
+
+

These instructions will optimize the linguistic variables in each fuzzy variable, using IV fuzzy sets, using three linguistic variables and ten rules with up to four antecedents. +It is also possible to give a precomputed set of linguistic variables as a list of fuzzy variables. A convenient way to compute +these with easy can be found on the utils module.

+

Once the classifier has been created, the next thing is tranining it. Since we are using a Genetic algorithm, we can specify the number +of generations and the population size:

+
fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30)
+
+
+

And then we can use forward or predict just as with a scikit-learn classifier.

+
+
+

Evaluation

+

The genetic algorithm needs a fitness measure to evaluate the quality of each solution. In order to obtain the best possible set of rules, +Ex-Fuzzy uses three different criteria.

+
    +
  1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy.

  2. +
  3. Dominance scores: are related to the support and confidence of each rule. So, rules that do not significantly fire or that are not discriminative are penalized. Thos that have a value less than the tolerance parmeter are dleted fro mthe rule base.

  4. +
  5. Small preference: rule bases with less rules and less antecedents are prefered.

  6. +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/step4.html b/docs/build/step4.html new file mode 100644 index 0000000..9442929 --- /dev/null +++ b/docs/build/step4.html @@ -0,0 +1,142 @@ + + + + + + + Visualize rules and results — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Visualize rules and results

+

Ex-Fuzzy can also visualize the fuzzy sets and the rules obtained after the training process. +The easiest way to do this is using the eval_tools.eval_fuzzy_model function:

+
import eval_tools
+eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True)
+
+
+

This function prints the performance of the model, prints the rules on screen and plot the rules as graphs.

+
+

Visualize Rules

+

You can visualize each consequent rules as a network, so that the interactions between the antecedents can be seen.

+_images/red_fuzzy.png +

If the number of linguistic variables is three, they also get automatically colored. It is also possible to export them to the gephi software.

+
+
+

Visualize Fuzzy Sets

+

Each fuzzy set is also visualized according to its own kind. The same linguistic variable can be visualized using T1, IV and GT2 fuzzy sets:

+_images/ejemplo_t1.png +_images/ejemplo_t2.png +_images/example_gt2.png +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/tmpfs.html b/docs/build/tmpfs.html new file mode 100644 index 0000000..a2d596c --- /dev/null +++ b/docs/build/tmpfs.html @@ -0,0 +1,164 @@ + + + + + + + Temporal Fuzzy Sets — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Temporal Fuzzy Sets

+

Temporal Fuzzy Sets (TFS) are a generalization of fuzzy sets to include a temporal variable that influences the membership values. +A comprehensive explanation of such fuzzy sets can be found in [1].

+

Temporal fuzzy sets thus require the additional temporal variable, which can be spceified in the dedicated functions that work with this kind of fuzzy sets. +The way in which is the temporal variable is used is by first discretizing the the temporal variable from a continuos into a discrete time space. For example, +our time variable is the seconds of the day, we can do the following to define the different stages of the day:

+
cut_point_morning0 = '00:00:00'
+cut_point_morning1 = '10:00:00'
+cut_points_morning = [cut_point_morning0, cut_point_morning1]
+cut_point_daytime0 = '11:00:00'
+cut_point_daytime1 = '19:00:00'
+cut_points_daytime = [cut_point_daytime0, cut_point_daytime1]
+cut_point_evening0 = '20:00:00'
+cut_point_evening1 = '23:00:00'
+cutpoints_evening = [cut_point_evening0, cut_point_evening1]
+
+
+

Once we have defined this cut points, there are various functions in the ex_fuzzy.utils module to assign each of the observatio to one of the temporal moments:

+
temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour')
+time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])])
+
+
+

We can also partition the dataset equally in order to have balanced partitions in each of the temporal moments:

+
partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers)
+X_train, X_test, y_train, y_test = partitions
+train_markers, test_markers = partition_markers
+
+
+

Given the time moments and the original fuzzy partitions, we can convert them into temporal fuzzy partitions:

+
temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions)
+
+
+

The temporal fuzzy partitions are then used to train the temporal fuzzy classifier:

+
X_train = X_train.drop(columns=['date'])
+X_test = X_test.drop(columns=['date'])
+fl_classifier = GA.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts,
+    linguistic_variables=temp_partitions, n_linguist_variables=3,
+    fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_classes=2)
+fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments)
+
+
+

The temporal fuzzy classifier can be evaluated using the eval_temporal_fuzzy_model function in the ex_fuzzy.eval_tools module:

+
eval_tools.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                            time_moments=train_time_moments, test_time_moments=test_time_moments,
+                            plot_rules=False, print_rules=True, plot_partitions=False)
+
+
+

[1] Kiani, M., Andreu-Perez, J., & Hagras, H. (2022). A Temporal Type-2 Fuzzy System for Time-dependent Explainable Artificial Intelligence. IEEE Transactions on Artificial Intelligence.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/build/usage.html b/docs/build/usage.html new file mode 100644 index 0000000..43e41d4 --- /dev/null +++ b/docs/build/usage.html @@ -0,0 +1,142 @@ + + + + + + + Getting Started — Ex-Fuzzy documentation + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Getting Started

+

The most straightforward way to use Ex-Fuzzy is to fit a fuzzy rule based classifier to a dataset, and then explore the results and the rules obtained. +A couple of examples of this can be found in the “demos” folder.

+

A brief piece of code that does this case of use is the following:

+
import ex_fuzzy.fuzzy_sets as fs
+import ex_fuzzy.evolutionary_fit as GA
+import ex_fuzzy.utils as  utils
+import ex_fuzzy.eval_tools as eval_tools
+
+iris = datasets.load_iris()
+X = pd.DataFrame(iris.data, columns=iris.feature_names)
+y = iris.target
+
+
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0)
+fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3,
+                                             fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001)
+fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30)
+
+eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test,
+                        plot_rules=True, print_rules=True, plot_partitions=True)
+
+
+

This code trains the classifier and also plots the rules, prints them on screen and show the linguistic variables optimized in the process.

+

In the following, we will explain how the different processes to perform fuzzy inference are automated in this code, and how they can be perfomed manually.

+

The next step is Creating fuzzy sets and fuzzy variables.

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..dc1312a --- /dev/null +++ b/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 + +%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.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 0000000..c9b6191 --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,21 @@ +API +=== + + +.. toctree:: + function_resume/fuzzy_sets + function_resume/rules + function_resume/eval_rules + function_resume/eval_tools + function_resume/vis_rules + function_resume/evolutionary_fit + function_resume/rule_mining + function_resume/classifiers + function_resume/persistence + function_resume/cognitive_maps + function_resume/utils + function_resume/centroid + function_resume/temporal + + + \ No newline at end of file diff --git a/docs/source/classifiers.rst b/docs/source/classifiers.rst new file mode 100644 index 0000000..f8c6029 --- /dev/null +++ b/docs/source/classifiers.rst @@ -0,0 +1,23 @@ +.. _classifiers: + +Advanced classifiers +======================================= + +Besides ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``, it is possible to use the classifiers in the ``ex_fuzzy.classifiers`` module, +which contains classifiers that take the base classifier and combine it with other techniques. There are two main additions to the base classification +class: rule mining using support, confidence and lift measures; and using a double genetic tuning, so that first a large number of rules can be +considered as potential good rules, and then the second optimization step choose the best combination of them. + +The three kind of classifiers are: + +1. ``ex_fuzzy.classifiers.RuleMineClassifier``: first mines the rules by checking all the possible combinations of antecedents. It looks for rules that present a minumum of the quality measures, (support, confidence and lift) and then uses them as candidate rules to find an optimal subset of them. +2. ``ex_fuzzy.classifiers.FuzzyRulesClassifier``: performs a double genetic optimization. First, it finds a good rule base and then it uses it as the initial population for another round of genetic optimization. +3. ``ex_fuzzy.classifiers.RuleFineTuneClassifier``: combines both previous approaches. First, searchs for all rules that hold the quality metrics. Then, uses them as candidate rules and finds a good subset of them. Finally, uses that rulebase as initial population for another round of genetic optimization, which gives the final result. + +---------------------------- +Support, Confidence and lift +---------------------------- +1. Support: The definition of support is the percentage of appearance of the antecedent of a rule in the whole dataset. We compute it as the average of the membership values of that antecedent in each sample for the dataset. The membership for each sample to that antecedent is computed using the minimum t-norm in this case. +2. Confidence: is the ratio between the support of an antecedent for a particular class and for the whole dataset. +3. Lift: is the ratio between the confidence and the expected confidence. It is computed as the ratio between the confidence of the rule and the percentage of samples of the rule class in the dataset. + diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..ec6864d --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,47 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'Ex-Fuzzy' +copyright = '2023, Javier Fumanal Idocin' +author = 'Javier Fumanal Idocin' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.duration', + 'sphinx.ext.doctest', + 'sphinx.ext.autodoc', + 'sphinx.ext.viewcode', + 'sphinx.ext.autosummary', +] + +templates_path = ['_templates'] +exclude_patterns = [] + +autodoc_default_options = { + "members": True, + "show-inheritance": True, +} +autosummary_generate = True + +import sys +import os +print(os.getcwd()) +sys.path.insert(0, os.path.abspath('../../ex_fuzzy/')) + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "sphinx_rtd_theme" +html_static_path = ['_static'] + +html_show_sourcelink = True + + diff --git a/docs/source/extending.rst b/docs/source/extending.rst new file mode 100644 index 0000000..1c52d4b --- /dev/null +++ b/docs/source/extending.rst @@ -0,0 +1,12 @@ +.. _extending: + +Extending Ex-Fuzzy +======================================= + +Some of the default behaviour/components can be easily extended to support more fuzzy/explainability tools. + +- Using other fuzzy sets: the whole library is programmed using object orientation, so that to extend some methods is to create classes that inherit from the correspondent classes. This is an easy way to implement additional to additional kinds of fuzzy sets. Nevertheless, as long as their membership values are numerical or 2-sized tuples, new fuzzy sets can be easily supported using the existing ``fs.FUZZY_SET`` enum. For example, ``fs.FUZZY_SET.t1`` expects a numerical membership value and ``fs.FUZZY_SET.t2`` expects a tuple. You can take a look at the ``ex_fuzzy.temporal`` for an example on how to do this. +- In order to use other partitions than those given by the ``ex_fuzzzy.utils`` module, you can directly create the necessary objects through ``fs.FS()`` objects and ``fs.fuzzyVariable()``. +- You can change the loss function used in the genetic optimization using the ``new_loss`` method of ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``. + + diff --git a/docs/source/function_resume/centroid.rst b/docs/source/function_resume/centroid.rst new file mode 100644 index 0000000..478cc81 --- /dev/null +++ b/docs/source/function_resume/centroid.rst @@ -0,0 +1,5 @@ +T2 Centroid compute +==================== + +.. automodule:: ex_fuzzy.centroid + :members: \ No newline at end of file diff --git a/docs/source/function_resume/classifiers.rst b/docs/source/function_resume/classifiers.rst new file mode 100644 index 0000000..34e55f7 --- /dev/null +++ b/docs/source/function_resume/classifiers.rst @@ -0,0 +1,5 @@ +Advanced Classifiers +==================== + +.. automodule:: ex_fuzzy.classifiers + :members: \ No newline at end of file diff --git a/docs/source/function_resume/cognitive_maps.rst b/docs/source/function_resume/cognitive_maps.rst new file mode 100644 index 0000000..6d9feb3 --- /dev/null +++ b/docs/source/function_resume/cognitive_maps.rst @@ -0,0 +1,5 @@ +Fuzzy Cognitive Maps +==================== + +.. automodule:: ex_fuzzy.cognitive_maps + :members: \ No newline at end of file diff --git a/docs/source/function_resume/eval_rules.rst b/docs/source/function_resume/eval_rules.rst new file mode 100644 index 0000000..f8852d0 --- /dev/null +++ b/docs/source/function_resume/eval_rules.rst @@ -0,0 +1,5 @@ +Rule Evaluation Functions +========================= + +.. automodule:: ex_fuzzy.eval_rules + :members: \ No newline at end of file diff --git a/docs/source/function_resume/eval_tools.rst b/docs/source/function_resume/eval_tools.rst new file mode 100644 index 0000000..8ca931f --- /dev/null +++ b/docs/source/function_resume/eval_tools.rst @@ -0,0 +1,5 @@ +Classification evaluation tools +=============================== + +.. automodule:: ex_fuzzy.eval_tools + :members: \ No newline at end of file diff --git a/docs/source/function_resume/evolutionary_fit.rst b/docs/source/function_resume/evolutionary_fit.rst new file mode 100644 index 0000000..9a28064 --- /dev/null +++ b/docs/source/function_resume/evolutionary_fit.rst @@ -0,0 +1,5 @@ +Evolutionary Algorithms to Fit the rules +======================================== + +.. automodule:: ex_fuzzy.evolutionary_fit + :members: \ No newline at end of file diff --git a/docs/source/function_resume/fuzzy_sets.rst b/docs/source/function_resume/fuzzy_sets.rst new file mode 100644 index 0000000..d1d6855 --- /dev/null +++ b/docs/source/function_resume/fuzzy_sets.rst @@ -0,0 +1,5 @@ +Fuzzy Sets Functions +==================== + +.. automodule:: ex_fuzzy.fuzzy_sets + :members: \ No newline at end of file diff --git a/docs/source/function_resume/persistence.rst b/docs/source/function_resume/persistence.rst new file mode 100644 index 0000000..3a2d3f4 --- /dev/null +++ b/docs/source/function_resume/persistence.rst @@ -0,0 +1,5 @@ +Classification persistence +=============================== + +.. automodule:: ex_fuzzy.persistence + :members: \ No newline at end of file diff --git a/docs/source/function_resume/rule_mining.rst b/docs/source/function_resume/rule_mining.rst new file mode 100644 index 0000000..788eab5 --- /dev/null +++ b/docs/source/function_resume/rule_mining.rst @@ -0,0 +1,5 @@ +Rule Mining methods +==================== + +.. automodule:: ex_fuzzy.rule_mining + :members: \ No newline at end of file diff --git a/docs/source/function_resume/rules.rst b/docs/source/function_resume/rules.rst new file mode 100644 index 0000000..edd97d2 --- /dev/null +++ b/docs/source/function_resume/rules.rst @@ -0,0 +1,5 @@ +Fuzzy Rules Functions +===================== + +.. automodule:: ex_fuzzy.rules + :members: \ No newline at end of file diff --git a/docs/source/function_resume/temporal.rst b/docs/source/function_resume/temporal.rst new file mode 100644 index 0000000..f96d95b --- /dev/null +++ b/docs/source/function_resume/temporal.rst @@ -0,0 +1,5 @@ +Temporal fuzzy sets +==================== + +.. automodule:: ex_fuzzy.temporal + :members: \ No newline at end of file diff --git a/docs/source/function_resume/utils.rst b/docs/source/function_resume/utils.rst new file mode 100644 index 0000000..f995a05 --- /dev/null +++ b/docs/source/function_resume/utils.rst @@ -0,0 +1,5 @@ +Partition utils +==================== + +.. automodule:: ex_fuzzy.utils + :members: \ No newline at end of file diff --git a/docs/source/function_resume/vis_rules.rst b/docs/source/function_resume/vis_rules.rst new file mode 100644 index 0000000..d290d63 --- /dev/null +++ b/docs/source/function_resume/vis_rules.rst @@ -0,0 +1,5 @@ +Rule Visualization +==================== + +.. automodule:: ex_fuzzy.vis_rules + :members: \ No newline at end of file diff --git a/docs/source/gt2.rst b/docs/source/gt2.rst new file mode 100644 index 0000000..ed9cefc --- /dev/null +++ b/docs/source/gt2.rst @@ -0,0 +1,21 @@ +.. _gt2: + +General Type 2 +======================================= + +General Type 2 Fuzzy sets are fully supported, however, they present a series of additional considerations when used in real domains: + +- The resolution of the primary domain function is always capped at 4 significant decimals. +- When the domain of the secondary function are real numbers, precision is capped at 4 significant decimals. + +We believe that this precision can be enough for most applications, but in case it needs to be changed, it is enough to modify the ``fs.gt2.MAX_RES_SUPPORT`` constant to the desired number before instantiating the GT2 fuzzy set. + +Computing with the GT2 is more costly than the rest of the sets. Specially, computing the GT2 fuzzy partitions, which are also notably more complex than in the rest of the fuzzy sets. +Essentially, a GT2 fuzzy partition is a dictionary where each value in the dictionary maps a value in the secondary domain to a fuzzy set. +When a new value needs to be computed, the closest known value in the secondary membership to the new one is used. + +As an example, the function ``utils.gt2_fuzzy_partitions_dataset()`` returns a fuzzy partition using GT2 in the following manner: + +1. Computes a IV partition for all the variables. +2. Discretizes the domain of the secondary membership to an arbitrary precision. +3. In each of the discretized points, computes a FS using as parameters of the trapezoid function the lower and upper memberships and the central point of them. This results in a triangle for each FS. \ No newline at end of file diff --git a/docs/source/images/ejemplo_t1.png b/docs/source/images/ejemplo_t1.png new file mode 100644 index 0000000..50e1962 Binary files /dev/null and b/docs/source/images/ejemplo_t1.png differ diff --git a/docs/source/images/ejemplo_t2.png b/docs/source/images/ejemplo_t2.png new file mode 100644 index 0000000..e2b2f98 Binary files /dev/null and b/docs/source/images/ejemplo_t2.png differ diff --git a/docs/source/images/example_gt2.png b/docs/source/images/example_gt2.png new file mode 100644 index 0000000..fcd427d Binary files /dev/null and b/docs/source/images/example_gt2.png differ diff --git a/docs/source/images/red_fuzzy.png b/docs/source/images/red_fuzzy.png new file mode 100644 index 0000000..f69b9e2 Binary files /dev/null and b/docs/source/images/red_fuzzy.png differ diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..0a27f9e --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,38 @@ +.. Ex-Fuzzy documentation master file, created by + sphinx-quickstart on Mon Jan 2 21:36:30 2023. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to Ex-Fuzzy's documentation! +==================================== + +**Ex-Fuzzy** is a library to perform fuzzy logic inference using fuzzy logic, with a special focus +on the explainable features of approximate reasoning. Different fuzzy sets are supported, and rules +are fitted to a dataset using genetic optimization. We also support fuzzy cognitive_maps. + +Check out the :doc:`usage` section for a few examples. + +.. toctree:: + + usage + step1 + step2 + step3 + step4 + precom + optimize + gt2 + tmpfs + extending + persistence + classifiers + api + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/optimize.rst b/docs/source/optimize.rst new file mode 100644 index 0000000..6c552f8 --- /dev/null +++ b/docs/source/optimize.rst @@ -0,0 +1,29 @@ +.. _ga: + +Genetic algorithm details +======================================= + +The genetic algorithm searchs for the optimal rule base for a problem. The criteria used to determine optimal is the one mentioned in :ref:`step3`: + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Less antecedents: the less antecedents per rule, the better. We compute this using the average number of antecedents per rule. We to normalize this by dividing the number of antecedents per rule by the maximum allowed in the optimization) +3. Less rules: rule bases with less rules are prefered. We normalize this by dividing the number of rules present in the database with dominance score bigger than the minimum threshold by the possible number of rules allowed in the optimization. + +It is possible to use previously computed rulesin order to fine tune them. There are two ways to do this using the ``ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier``: + +1. Use the previously computed rules as the initial population for a new optimization problem. In that case, you can pass that rules to the ``initial_rules`` parameter the ``ex_fuzzy.rules.MasterRuleBase`` object. +2. Look for more efficient subsets of rules in the previously computed rules. In this case the genetic optimization will use those rules as the search space itself, and will try to optimize the best subset of them. In that case, you can pass that rules to the ``candidate_rules`` parameter the ``ex_fuzzy.rules.MasterRuleBase`` object. + +--------------------------------------- +Limitations of the optimization process +--------------------------------------- + +- General Type 2 requires precomputed fuzzy partitions. +- When optimizing IV fuzzy partitions: Not all possible shapes of trapezoids all supported. Optimized trapezoids will always have max memberships for the lower and upper bounds in the same points. Height of the lower membership is optimized by scaling. Upper membership always reaches 1 at some point. + +---------------- +Fitness function +---------------- + +By default, the fitness function is the convex combination of the Matthew Correlation Coefficient (95%), to the rule size preference (2.5%) and to the rule antecedent size preference (2.5%). +For more information about changing this fitness function check :ref:`extending`. diff --git a/docs/source/persistence.rst b/docs/source/persistence.rst new file mode 100644 index 0000000..0da9564 --- /dev/null +++ b/docs/source/persistence.rst @@ -0,0 +1,66 @@ +.. _persistence: + +Persistence +==================================== +Rules can be saved and loaded using plain text. The specification for this format is the same the print format of the rules. +We can extract the rules from a model using the ``ex_fuzzy.eval_tools.eval_fuzzy_model`` method, which can can return the rules in string format if the ``return_rules`` parameter is set to ``True``:: + + + + import pandas as pd + + from sklearn import datasets + from sklearn.model_selection import train_test_split + + import sys + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + import ex_fuzzy.persistence as persistence + import ex_fuzzy.vis_rules as vis_rules + + n_gen = 5 + n_pop = 30 + nRules = 15 + nAnts = 4 + vl = 3 + fz_type_studied = fs.FUZZY_SETS.t1 + + # Import some data to play with + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + # Split the data into a training set and a test set + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + + # We create a FRBC with the precomputed partitions and the specified fuzzy set type, + fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=precomputed_partitions, nAnts=nAnts, + n_linguist_variables=vl, fuzzy_type=fz_type_studied) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=n_pop, checkpoints=1) + + str_rules = eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=True) + + # Save the rules as a plain text file + with open('rules_iris_t1.txt', 'w') as f: + f.write(str_rules) + + + +The rules can be loaded from a file using the ``load_rules`` method of the ``FuzzyModel`` class:: + + # Load the rules from a file + mrule_base = persistence.load_fuzzy_rules(str_rules, precomputed_partitions) + + fl_classifier = GA.FuzzyRulesClassifier(precomputed_rules=mrule_base) + +If we already created the ``FuzzyRulesClassifier`` object, we can load the rules using the ``load_master_rule_base`` method:: + + fl_classifier.load_master_rule_base(mrule_base) + +You can also save the best rulebase found each x steps of the genetic tuning if you set the ``checkpoint`` parameter to that x number of steps. + + \ No newline at end of file diff --git a/docs/source/precom.rst b/docs/source/precom.rst new file mode 100644 index 0000000..760769f --- /dev/null +++ b/docs/source/precom.rst @@ -0,0 +1,20 @@ +.. _precom: + +Computing fuzzy partitions +======================================= + +One of the most typical ways to compute fuzzy partitions is to use quantiles of the data. The module ``utils`` contains a series of functions +to generate fuzzy partitions for all the supported kinds of fuzzy sets. +The easiest way to compute these partitions is with the ``utils.construct_partitions`` function, specifying the fuzzy set desired:: + + import utils + + fz_type_studied = fs.FUZZY_SETS.t2 + precomputed_partitions = utils.construct_partitions(X, fz_type_studied) + +-------------------------------- +About the precomputed partitions +-------------------------------- +Partitions computed using these method use three linguistic variables per fuzzy variable. We chose that number as it creates easily understandable +low, medium and high partitions. For the case of IV-fuzzy sets, the trapezoids constructed, both the lower and upper memberships +present 1 values in the same points. For the case of General Type 2 Fuzzy sets check :ref:`gt2`. diff --git a/docs/source/step1.rst b/docs/source/step1.rst new file mode 100644 index 0000000..349b6a6 --- /dev/null +++ b/docs/source/step1.rst @@ -0,0 +1,52 @@ +.. _step1: + +Creating fuzzy sets and fuzzy variables +======================================= + +----------------- +Fuzzy Sets +----------------- +Ex-Fuzzy supports different kinds of fuzzy sets, but the procedure to use them all is the same. +Fuzzy sets have a name, a domain range and a membership function:: + + import ex_fuzzy.fuzzy_sets as fs + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + +This code creates a fuzzy set named "Cold", with a trapezoidal membership function and a domain that ranges from 0 to 40 degrees. +A fuzzy membership can be computed easily using the newly-created fuzzy set:: + + cold(8.2) + +This would be the code to do the same thing using interval-valued fuzzy sets:: + + cold2 = fs.IVFS('Cold', [0, 0, 5, 10], [0, 0, 5, 15], [0,40], 0.8) + +This code would create an interval-valued fuzzy set defined using a lower and upper membership function, +the same domain and name as before, and a maximum certainty of 0.8 for the lower membership. +The membership is computed just as an ordinary fuzzy set:: + + cold2(8.2) + +We could use any of these kinds of fuzzy sets (or even general-type 2 fuzzy sets) to construct all the linguistic variables +for our temperature domain:: + + cold = fs.FS('Cold', [0, 0, 5, 15] , [0,40]) + warm = fs.FS('Warm', [15, 20, 25, 30] , [0,40]) + hot = fs.FS('Hot', [25, 30, 40, 40] , [0,40]) + +----------------- +Fuzzy Variables +----------------- +Once we have the linguistic variables, we can construct a fuzzy variable. A fuzzy variable consists of a list of fuzzy sets +of the same kind and a proper name:: + + temperature = fs.fuzzyVariable('Temperature', [cold, warm, hot]) + +We do not need to specify domain or fuzzy set type, because the ``fuzzyVariable`` class deduces it from the fuzzy sets given in the list. +We can use a ``fuzzyVariable`` object to compute the memberships for a value to all the linguistic variables in the fuzzy variable:: + + temperature(8.2) + +Once we have defined the fuzzy variables, we can use them to construct a fuzzy rule base. This step is described in :ref:`step2`. + diff --git a/docs/source/step2.rst b/docs/source/step2.rst new file mode 100644 index 0000000..6151d65 --- /dev/null +++ b/docs/source/step2.rst @@ -0,0 +1,69 @@ +.. _step2: + +Using Fuzzy Rules +================= + +----------------- +Fuzzy Rules +----------------- +Fuzzy rules can be used to solve both regression and classification problems. + +The most straightforward way to construct a rule is to give a series of antecedents and a consequent. +For the case of classification, the consequent will be a class, and for regression, a fuzzy set. +Following the temperature example. Suppose we have these fuzzy sets as consequents to module +the use of air conditioner:: + + activate_small = fs.FS('Small', [0.0, 0.0, 0.1, 0.2], [0,1]) + activate_medium = fs.FS('Small', [0.1, 0.4, 0.4, 0.5], [0,1]) + activate_large = fs.FS('Small', [0.5, 0.8, 1.0, 1.0], [0,1]) + + activate = fs.fuzzyVariable('Activate', [activate_small, activate_medium, activate_large]) + +We can construct a rule for regression using the ``ex_fuzzy.rules.Rule`` class. +For example, the rule IF temperature IS hot THEN conditioner IS large can be implemented as:: + + import ex_fuzzy.rules as frule + frule.Rule([hot], activate_large) + +Then, we can use the ``membership`` method to obtain the degree of truth for a value in a rule, and the ``centroid`` method to +compute the centroid of the consequent. + +This implementation, however, can be problematic when there is a considerable number of rules with repeated antecedents, +because we do not want to compute the degree of truth for a value for the same antecedents over and over. So, instead +of using the ``Rule`` class, it is more practical to use ``RuleBase`` and ``RuleSimple`` classes. + +----------------- +Rule Bases +----------------- + +``RuleSimple`` is a class that simplifies the way in which rules are expressed. Its antecedents are expressed as a list, denoting the +linguistic variable relevant to the rule. The previous rule would be expressed as a ``RuleSimple`` as this:: + + my_rule = frule.RuleSimple([2], 2) + +The length of the first list is the number of antecedents, and the second argument denotes that the consequent fuzzy set is "activates_large". +``RuleSimple`` is used by ``RuleBase`` class to efficiently compute the degrees of truth for all the antecedents for all the data, +and then use them when necessary. In order to create one rule base, we need the list of all the fuzzy variables to use, the consequent +and the rules expressed as ``RuleSimple`` objects:: + + my_rulebase = frule.RuleBaseT1([temperature], [my_rule], activate) + +This is quite a simple case because we are using only one fuzzy variable and one rule, but the process is the same for more rules and variables. +Then, we can use "my_rule" using the ``inference`` method:: + + my_rulebase.inference(np.array([8.2])) + +Which will return the defuzzified result of the fuzzy inference process. The process is the same for the rest of the fuzzy sets, but other +classes are required: ``RuleBaseT2``, ``RuleBaseGT2``. + +--------------------------------------------- +Classification problems and Master Rule Bases +--------------------------------------------- +Up to now, we have discussed how to model a regression problem. Classification problems perform the inference in a different way, which require another kind of object: the ``ex_fuzzy.rules.MasterRuleBase``. +This is because the way in which Ex-Fuzzy handles classification problems is by using one Rule Base per consequent. +So, the ``rules.MasterRuleBase`` class is used to handle the rule bases created for each class. An object of this class is created using +a list of rule bases, and its main method is ``rules.MasterRuleBase.winning_rule_predict()`` which returns the class obtained from the rule with highest association degree. +You can find more the specifics of the classification inference in the next steps. + + +The next step is :ref:`step3`. diff --git a/docs/source/step3.rst b/docs/source/step3.rst new file mode 100644 index 0000000..7d5b4d0 --- /dev/null +++ b/docs/source/step3.rst @@ -0,0 +1,68 @@ +.. _step3: + +Optimizing a Fuzzy rule base for a classification problem +========================================================= + +-------------------------------------- +Fuzzy rule based classifier +-------------------------------------- +Usually, in classification inference we compute the matching degree of a sample for each rule in the rule base +(we refer as "rule base" to both ``ex_fuzzy.rules.RuleBase`` and ``ex_fuzzy.rules.MasterRuleBase`` objects as they are conceptually equivalent). +Then, the predicted class is the consequent class of that rule. In this library, besides the matching degree, we also use a prior, the Dominance Scores, +that are multiplied by the matching degree. + +The Dominance Score is the product of the support and confidence of a rule, so that we rely more on those rules that are more general, and that +cover different patterns than those covered by other rules. + +For more info about the dominance scores, you can see [Fach23]. + +-------------------------------------- +Training a fuzzy rule based classifier +-------------------------------------- +In order to train a fuzzy rule based classifier, Ex-Fuzzy uses a Genetic algorithm to tune the rules to the +desired classification task. The interface to use this kind of classifiers is analogous to the standard used +in scikit-learn, so it requires no previous knowledge about fuzzy logic in order to work. + +For example, we load the iris dataset and split it in train and test:: + + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + +Once the data has been loaded, we just need to create a classifier with the proper parameters, number of rules, +maximum number of antecedents per rule, number of linguist variables per fuzzy variable and tolerance, which will explained +in the evaluation part of this section:: + + + import ex_fuzzy.evolutionary_fit as GA + + fl_classifier = GA.FuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + +These instructions will optimize the linguistic variables in each fuzzy variable, using IV fuzzy sets, using three linguistic variables and ten rules with up to four antecedents. +It is also possible to give a precomputed set of linguistic variables as a list of fuzzy variables. A convenient way to compute +these with easy can be found on the ``utils`` module, by means of the ``ex_fuzzy.utils.construct_partitions`` function. + +Once the classifier has been created, the next thing is tranining it. Since we are using a Genetic algorithm, we can specify the number +of generations and the population size:: + + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + +And then we can use forward or predict just as with a scikit-learn classifier. + +----------------- +Evaluation +----------------- +The genetic algorithm needs a fitness measure to evaluate the quality of each solution. In order to obtain the best possible set of rules, +Ex-Fuzzy uses three different criteria. + +1. Matthew Correlation Coefficient: it is a metric that ranges from [-1, 1] that measures the quality of a classification performance. It less sensible to imbalance classification than the standard accuracy. +2. Less antecedents: the less antecedents per rule, the better. +3. Less rules: rule bases with less rules are prefered. + +.. _references:: + [Fach23] Fumanal-Idocin, J., Andreu-Perez, J., Cord, O., Hagras, H., & Bustince, H. (2023). Artxai: Explainable artificial intelligence curates deep representation learning for artistic images using fuzzy techniques. IEEE Transactions on Fuzzy Systems. \ No newline at end of file diff --git a/docs/source/step4.rst b/docs/source/step4.rst new file mode 100644 index 0000000..fb88650 --- /dev/null +++ b/docs/source/step4.rst @@ -0,0 +1,38 @@ +.. _step4: + +Visualize rules and results +=========================== +Ex-Fuzzy can also visualize the fuzzy sets and the rules obtained after the training process. +The easiest way to do this is using the ``eval_tools.eval_fuzzy_model`` function:: + + import eval_tools + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This function prints the performance of the model, prints the rules on screen and plot the rules as graphs. + +------------------- +Visualize Rules +------------------- + +You can visualize each consequent rules as a network, so that the interactions between the antecedents can be seen. + +.. image:: images/red_fuzzy.png + :width: 200 + +If the number of linguistic variables is three, they also get automatically colored. It is also possible to export them to the gephi software. + +-------------------- +Visualize Fuzzy Sets +-------------------- + +Each fuzzy set is also visualized according to its own kind. The same linguistic variable can be visualized using T1, IV and GT2 fuzzy sets: + +.. image:: images/ejemplo_t1.png + :width: 200 + +.. image:: images/ejemplo_t2.png + :width: 200 + +.. image:: images/example_gt2.png + :width: 200 \ No newline at end of file diff --git a/docs/source/tmpfs.rst b/docs/source/tmpfs.rst new file mode 100644 index 0000000..21aeb2c --- /dev/null +++ b/docs/source/tmpfs.rst @@ -0,0 +1,57 @@ +.. _tempfs: + +Temporal Fuzzy Sets +======================================= + +Temporal Fuzzy Sets (TFS) are a generalization of fuzzy sets to include a temporal variable that influences the membership values. +A comprehensive explanation of such fuzzy sets can be found in [Kiah]. + +Temporal fuzzy sets thus require the additional temporal variable, which can be spceified in the dedicated functions that work with this kind of fuzzy sets. +The way in which is the temporal variable is used is by first discretizing the the temporal variable from a continuous into a discrete time space. For example, +our time variable is the seconds of the day, we can do the following to define the different stages of the day:: + + + cut_point_morning0 = '00:00:00' + cut_point_morning1 = '10:00:00' + cut_points_morning = [cut_point_morning0, cut_point_morning1] + cut_point_daytime0 = '11:00:00' + cut_point_daytime1 = '19:00:00' + cut_points_daytime = [cut_point_daytime0, cut_point_daytime1] + cut_point_evening0 = '20:00:00' + cut_point_evening1 = '23:00:00' + cutpoints_evening = [cut_point_evening0, cut_point_evening1] + +Once we have defined this cut points, there are various functions in the ``ex_fuzzy.utils`` module to assign each of the observatio to one of the temporal moments:: + + temporal_boolean_markers = utils.temporal_cuts(X_total, cutpoints=[cut_points_morning, cut_points_daytime, cutpoints_evening], time_resolution='hour') + time_moments = np.array([utils.assign_time(a, temporal_boolean_markers) for a in range(X_total.shape[0])]) + +We can also partition the dataset equally in order to have balanced partitions in each of the temporal moments:: + + partitions, partition_markers = utils.temporal_assemble(X_total, y_total, temporal_moments=temporal_boolean_markers) + X_train, X_test, y_train, y_test = partitions + train_markers, test_markers = partition_markers + + +Given the time moments and the original fuzzy partitions, we can convert them into temporal fuzzy partitions:: + + temp_partitions = utils.create_tempVariables(X_total_array, time_moments, precomputed_partitions) + +The temporal fuzzy partitions are then used to train the temporal fuzzy classifier:: + + X_train = X_train.drop(columns=['date']) + X_test = X_test.drop(columns=['date']) + fl_classifier = temporal.TemporalFuzzyRulesClassifier(nRules=nRules, nAnts=nAnts, + linguistic_variables=temp_partitions, n_linguist_variables=3, + fuzzy_type=fz_type_studied, verbose=True, tolerance=0.001, n_classes=2) + fl_classifier.fit(X_train, y_train, n_gen=n_gen, pop_size=pop_size, time_moments=train_time_moments) + +The temporal fuzzy classifier can be evaluated using the ``eval_temporal_fuzzy_model`` function in the ``ex_fuzzy.eval_tools`` module:: + + eval_tools.eval_temporal_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + time_moments=train_time_moments, test_time_moments=test_time_moments, + plot_rules=False, print_rules=True, plot_partitions=False) + + +.. _references:: + [Kiah] Kiani, M., Andreu-Perez, J., & Hagras, H. (2022). A Temporal Type-2 Fuzzy System for Time-dependent Explainable Artificial Intelligence. IEEE Transactions on Artificial Intelligence. \ No newline at end of file diff --git a/docs/source/usage.rst b/docs/source/usage.rst new file mode 100644 index 0000000..7e61702 --- /dev/null +++ b/docs/source/usage.rst @@ -0,0 +1,34 @@ +.. _usage: + +Getting Started +==================================== + + +The most straightforward way to use Ex-Fuzzy is to fit a fuzzy rule based classifier to a dataset, and then explore the results and the rules obtained. +A couple of examples of this can be found in the "demos" folder. + +A brief piece of code that does this case of use is the following:: + + import ex_fuzzy.fuzzy_sets as fs + import ex_fuzzy.evolutionary_fit as GA + import ex_fuzzy.utils as utils + import ex_fuzzy.eval_tools as eval_tools + + iris = datasets.load_iris() + X = pd.DataFrame(iris.data, columns=iris.feature_names) + y = iris.target + + + X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=0) + fl_classifier = GA.BaseFuzzyRulesClassifier(nRules=10, nAnts=4, n_linguist_variables=3, + fuzzy_type=fs.FUZZY_SETS.t2, tolerance=0.001) + fl_classifier.fit(X_train, y_train, n_gen=50, pop_size=30) + + eval_tools.eval_fuzzy_model(fl_classifier, X_train, y_train, X_test, y_test, + plot_rules=True, print_rules=True, plot_partitions=True) + +This code trains the classifier and also plots the rules, prints them on screen and show the linguistic variables optimized in the process. + +In the following, we will explain how the different processes to perform fuzzy inference are automated in this code, and how they can be perfomed manually. + +The next step is :ref:`step1`. diff --git a/docs/source_docs_exFuzzy.zip b/docs/source_docs_exFuzzy.zip new file mode 100644 index 0000000..2320d87 Binary files /dev/null and b/docs/source_docs_exFuzzy.zip differ diff --git a/ex_fuzzy/ex_fuzzy/__init__.py b/ex_fuzzy/ex_fuzzy/__init__.py new file mode 100644 index 0000000..85d227f --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/__init__.py @@ -0,0 +1,10 @@ +from . import centroid +from . import eval_rules +from . import eval_tools +from . import evolutionary_fit +from . import fuzzy_sets +from . import rules +from . import vis_rules +from . import utils +from . import persistence +from . import maintenance diff --git a/ex_fuzzy/ex_fuzzy/centroid.py b/ex_fuzzy/ex_fuzzy/centroid.py new file mode 100644 index 0000000..438ef2d --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/centroid.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +""" +This is the source file that contains functions to compute centroids for the case of IV fuzzy sets, +which are commonly used when using the IV-T2 fuzzy sets. +""" +import numpy as np + + +def center_of_masses(z: np.array, w: np.array) -> np.array: + ''' + Computes the ponderated centroid with normalized weighting. + + :param z: Vector of the referencial values. + :param w: Vector of the fuzzy memberships. + :return: The ponderated sum. + ''' + return z @ w / np.sum(w) + + +def compute_centroid_t2_l(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = center_of_masses(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + # k_vector = np.argwhere((z - yhat) > 0) + # k = k_vector[0][0] + 1 + w[0:k] = memberships[:, 1][:k] + w[k:] = memberships[:, 0][k:] + + yhat_2 = yhat + yhat = center_of_masses(z, w) + + return yhat + + +def compute_centroid_t2_r(z: np.array, memberships: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The lowest membership of the centroid. + ''' + centros = np.mean(memberships, axis=1) + w = centros + + yhat = center_of_masses(z, w) + + yhat_2 = None + + while(yhat != yhat_2): + try: + k = np.argwhere((z - yhat) >= 0)[-1][0] + k = min(len(centros)-1, k) + except IndexError: + k = 0 + + w[0:k+1] = memberships[:, 0][:k+1] + w[k+1:] = memberships[:, 1][k+1:] + + yhat_2 = yhat + yhat = center_of_masses(z, w) + + return yhat + + +def consequent_centroid_r(antecedent_memberships: np.array, centroids_r: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the right component of a centroid of an IV fuzzy set + using the centroids of the consequents and the antecedents memeberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + yhat = center_of_masses(centroids_r, initial_f) + yhat2 = None + + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_r) >= 0)[-1][0] + r_R = min(len(centroids_r)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_left[0:r_R+1] + new_memberships[r_R+1:] = memberships_right[r_R+1:] + + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = center_of_masses(centroids_r, new_memberships) + + return yhat2 + + +def consequent_centroid_l(antecedent_memberships: np.array, centroids_l: np.array) -> float: + ''' + Computes the Karnik and Mendel algorithm to find the left component of a centroid of an IV fuzzy set + using the centroids of the consequents and the antecedents memeberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids_r: M sized vector. Contains the referencial values. + :return: the IV centroid. + ''' + + memberships_left = antecedent_memberships[:, 0] + memberships_right = antecedent_memberships[:, 1] + initial_f = (memberships_left + memberships_right) / 2 + + # (memberships_right * centroids_r) / np.sum(memberships_right) + yhat = center_of_masses(centroids_l, initial_f) + yhat2 = -100 + + #R = np.where(yhat - centroids_r)[0] + while(yhat != yhat2): + try: + r_R = np.argwhere((yhat - centroids_l) >= 0)[-1][0] + r_R = min(len(centroids_l)-1, r_R) + except IndexError: + r_R = 0 + + new_memberships = initial_f + new_memberships[0:r_R+1] = memberships_right[0:r_R+1] + new_memberships[r_R+1:] = memberships_left[r_R+1:] + yhat2 = yhat + if np.sum(new_memberships) == 0: + yhat = 0 + else: + yhat = center_of_masses(centroids_l, new_memberships) + + return yhat2 + + +def compute_centroid_iv(z: np.array, memberships: np.array) -> np.array: + ''' + Computes Karnik and Mendel algorithm to find the centroid of a iv fuzzy set. + + :param z: Vector of the referencial values. + :param memberships: vector of the fuzzy memberships. + :return: The centroid. + ''' + res = np.zeros((2,)) + res[0] = compute_centroid_t2_l(z, memberships) + res[1] = compute_centroid_t2_r(z, memberships) + return res + + +def consequent_centroid(antecedent_memberships: np.array, centroids: np.array) -> np.array: + ''' + Computes Karnik and Mendel algorithm to find the centroid of a consequent iv fuzzy set given the centroids of the consequents + and the antecedents memberships. + + :param antecedent_memberships: M x 2 matrix. M rules and iv dimension (2). Vector of memberships. + :param centroids: M x 2 matrix. M rules and iv dimension (2). Vector of centroids. + :return: The centroid. + ''' + centroids_l = centroids[:, 0] + centroids_r = centroids[:, 1] + res = np.zeros((2,)) + + res[0] = consequent_centroid_l(antecedent_memberships, centroids_l) + res[1] = consequent_centroid_r(antecedent_memberships, centroids_r) + + return res + + + diff --git a/ex_fuzzy/ex_fuzzy/classifiers.py b/ex_fuzzy/ex_fuzzy/classifiers.py new file mode 100644 index 0000000..1a2be69 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/classifiers.py @@ -0,0 +1,209 @@ +''' +Module that contains classifiers that uses two step genetic optimization and rule mining based on the support of the candidate rules. + +''' + +import numpy as np +from sklearn.base import ClassifierMixin + +try: + from . import fuzzy_sets as fs + from . import evolutionary_fit as evf + from . import rule_mining as rm + from . import utils + from . import maintenance as mnt +except: + import fuzzy_sets as fs + import evolutionary_fit as evf + import rule_mining as rm + import utils + import maintenance as mnt + + +class RuleMineClassifier(ClassifierMixin): + """A classifier that works by mining a set of candidate rules with a minimum support, confidence and lift, and then using a genetic algorithm that chooses + the optimal combination of those rules.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the support/dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param runner: number of threads to use. + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1 + + self.nAnts = nAnts + self.fl_classifier = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + + def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + ''' + fuzzy_vars = utils.construct_partitions(X, self.fuzzy_type) + candidate_rules = rm.multiclass_mine_rulebase(X, y, fuzzy_vars, self.tolerance, max_depth=self.nAnts) + self.fl_classifier.fit(X, y, checkpoints=0, candidate_rules=candidate_rules, n_gen=n_gen, pop_size=pop_size) + + + def predict(self, X: np.array) -> np.array: + ''' + Predict for each sample the corresponding class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier.predict(X) + + return y_pred + + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier + + + +class FuzzyRulesClassifier(ClassifierMixin): + """A classifier that works by performing a double optimization process. First, it creates a candidate rule base using genetic optimization + and then uses it as a basis to obtain a better one that satisfies the constrain of antecedents and number of rules.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param runner: number of threads to use. + :param expansion_factor: if > 1, it will compute inthe first optimization process n times the nRules parameters. (So that the search space for the second step is bigger) + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['double_go'] += 1 + + + self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* 1, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + + def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + :param n_gen: number of generations to compute in the genetic optimization. + :param pop_size: number of subjects per generation. + :param checkpoints: if bigger than 0, will save the best subject per x generations in a text file. + :param n_runner: number of threds to use. + ''' + self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints) + self.phase1_rules = self.fl_classifier1.rule_base + self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner) + + + def predict(self, X: np.array) -> np.array: + ''' + Predcit for each sample the correspondent class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier2.predict(X) + + return y_pred + + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier2 + + +class RuleFineTuneClassifier(ClassifierMixin): + """A classifier that works by mining a set of candidate rules with a minimum support and then uses a two step genetic optimization that chooses + the optimal combination of those rules and fine tunes them.""" + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + verbose=False, n_class: int=None, runner: int=1, expansion_factor:int=1, linguistic_variables: list[fs.fuzzyVariable]=None) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param verbose: if True, prints the progress of the optimization. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param linguistic_variables: linguistic variables per antecedent. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Classification]['double_go'] += 1 + mnt.usage_data[mnt.usage_categories.Classification]['data_mining'] += 1 + + self.fl_classifier1 = evf.BaseFuzzyRulesClassifier(nRules=nRules* expansion_factor, linguistic_variables=linguistic_variables, nAnts=nAnts, # We give this one more number rules so that then the second optimization has a bigger search space + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fl_classifier2 = evf.BaseFuzzyRulesClassifier(nRules=nRules, linguistic_variables=linguistic_variables, nAnts=nAnts, + fuzzy_type=fuzzy_type, verbose=verbose, tolerance=tolerance, runner=runner, n_class=n_class) + self.fuzzy_type = fuzzy_type + self.tolerance = tolerance + + + def fit(self, X: np.array, y: np.array, n_gen:int=30, pop_size:int=50, checkpoints:int=0, n_runner:int=1): + ''' + Trains the model with the given data. + + :param X: samples to train. + :param y: labels for each sample. + :param n_gen: number of generations to compute in the genetic optimization. + :param pop_size: number of subjects per generation. + :param checkpoints: if bigger than 0, will save the best subject per x generations in a text file. + :param n_runner: number of threds to use. + ''' + candidate_rules = rm.multiclass_mine_rulebase(X, y, self.fl_classifier1.lvs, self.tolerance) + + self.fl_classifier1.fit(X, y, n_gen, pop_size, checkpoints, candidate_rules=candidate_rules) + self.phase1_rules = self.fl_classifier1.rule_base + self.fl_classifier2.fit(X, y, n_gen, pop_size, checkpoints, initial_rules=self.phase1_rules, n_runner=n_runner) + + + def predict(self, X: np.array) -> np.array: + ''' + Predcit for each sample the correspondent class. + + :param X: samples to predict. + :return: a class for each sample. + ''' + # Make predictions using the fitted model + y_pred = self.fl_classifier.predict(X) + + return y_pred + + + def internal_classifier(self) -> evf.BaseFuzzyRulesClassifier: + # Returns the classifier that performs the final predictions + return self.fl_classifier2 \ No newline at end of file diff --git a/ex_fuzzy/ex_fuzzy/cognitive_maps.py b/ex_fuzzy/ex_fuzzy/cognitive_maps.py new file mode 100644 index 0000000..655ede6 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/cognitive_maps.py @@ -0,0 +1,217 @@ +from __future__ import annotations +''' +Module to use fuzzy cognitive maps. + +The module contains the class FuzzyCognitiveMap, which is used to create and +use fuzzy cognitive maps. You can also plot them, or simulate the dynamics of +the FCM. + +For the original papers about FCM, see the works by Bart Kosko. + +''' +import pandas as pd +import numpy as np +import matplotlib.pyplot as plt + +try: + from . import maintenance as mnt +except ImportError: + + import maintenance as mnt + + +def _threshold_modules(connections: np.array | pd.DataFrame, threshold) -> np.array | pd.DataFrame: + '''Thresholds the connections matrix to the {-1, 0, 1} values.''' + return np.abs(connections) > threshold * np.sign(connections) + + +def __look_periods(states: list[np.array], min_period_len=2) -> list[np.array]: + '''Looks for periods in the states list. Returns the period if found, None otherwise.''' + max_period_len = int(len(states) / 2) + + for period_len in np.arange(max_period_len, min_period_len, -1): + + for i in range(len(states)): + candidate = states[i:i+period_len] + next_candidate = states[i+period_len:i+period_len*2] + if len(next_candidate) < min_period_len: + break + if candidate != next_candidate: + break + + return candidate + + + return None + + +def __look_attractors(states: list[np.array]) -> [bool, np.array]: + '''Checks if all the states in the list are the same''' + attractors = [] + for state in states: + if not state in attractors: + attractors.append(state) + else: + return False, [] + + return True, attractors[0] + + +def look_pattern_states(fcm: FuzzyCognitiveMap, sim_steps: int, pattern_len: 50, max_period_size: 50) -> [np.array]: + '''Looks for the pattern states of the FCM when simulation is prolongued. + + + :param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. + :param max_steps: int. The maximum number of steps to look for the attractor states. + :param random_inits : int + :returns: list of np.array. The attractor states found. None if none were found + ''' + for _ in range(sim_steps): + state = fcm.step() + + steps = [] + for _ in range(pattern_len): + state = fcm.step() + steps.append(state) + + satisfactory, period = __look_attractors(steps) + if not satisfactory: + period = __look_periods(steps, min_period_len=2) + + return period + + +def study_attractors_FCM(fcm: FuzzyCognitiveMap, max_steps: int, random_inits: int=10) -> [np.array]: + '''Looks for the attractor states of the FCM when simulation is prolongued. + + + :param fcm : FuzzyCognitiveMap. The FCM to look for the attractor states. + :param max_steps: int. The maximum number of steps to look for the attractor states. + :param random_inits : int + :returns: list of np.array. The attractor states found. None if none were found + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_report'] += 1 + + attractors = {} + gen_random_state = lambda : np.random.randint(0, 2, fcm.connections.shape[0]) + for _ in range(random_inits): + init_state = gen_random_state() + fcm.set_state(init_state) + attractors[init_state] = look_pattern_states(fcm, max_steps) + + return attractors + + +def attractors_report(attractors: dict[np.array, np.array]) -> None: + ''' + Prints a report of the attractors found. + + :param attractors: dict[np.array, np.array]. The attractors found. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_report'] += 1 + pattern_dict = {} + + for _, attractor in attractors.items(): + if attractor is None: + pattern_dict['Chaotic'] = pattern_dict.get('Chaotic', 0) + 1 / len(attractors) + else: + pattern_dict[str(attractor)] = pattern_dict.get(str(attractor), 0) + 1 / len(attractors) + + state_dict = {} + list_states = [] + for _, attractor in attractors.items(): + if attractor is not None: + for state in attractor: + list_states += [str(state)] + + for state in list_states: + state_dict[state] = state_dict.get(state, 0) + 1 / len(list_states) + + return pattern_dict, state_dict + + +class FuzzyCognitiveMap: + + def __init__(self, connections: np.array | pd.DataFrame, threshold:int=0.5) -> None: + ''' + Creates a fuzzy cognitive map. + + + :param connections: np.array | pd.DataFrame. A square matrix with the connections between the concepts. + :param threshold: int, optional. When simulating steps the state + will be trimmed using these threhold into the {0, 1, -1} values. + The default is 0.5. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzyCognitiveMaps]['fcm_create'] += 1 + + self.connections = connections + self.state = np.zeros(connections.shape[0]) + self.threshold = threshold + + + def var_names(self) -> list[str]: + '''Returns the names of the variables.''' + try: + return list(self.connections.columns) + except AttributeError: + return None + + + def step(self) -> np.array | pd.DataFrame: + '''Performs a step in the FCM given the actual state.''' + self.state = _threshold_modules(self.state @ self.connections, self.threshold) + + if isinstance(self.state, pd.DataFrame): + return pd.DataFrame(self.state, columns=self.var_names()) + else: + return self.state + + + def simulate(self, steps: int) -> np.array | pd.DataFrame: + ''' + Simulates the FCM for a number of steps. + + :param steps: int. The number of steps to simulate. + ''' + for _ in range(steps): + fstep = self.step() + + return fstep + + + def add(self, other: FuzzyCognitiveMap) -> None: + '''Adds the connections of other FCM to the actual FCM.''' + self.connections = self.connections + other.connections + + + def set_state(self, state: np.array | pd.DataFrame) -> None: + '''Sets the state of the FCM.''' + try: + self.state = state.values + except AttributeError: + self.state = state + + + def set_and_step(self, state: np.array | pd.DataFrame) -> np.array | pd.DataFrame: + '''Sets the state of the FCM and performs a step.''' + self.set_state(state) + return self.step() + + + def set_and_simulate(self, state: np.array | pd.DataFrame, steps: int) -> np.array | pd.DataFrame: + '''Sets the state of the FCM and performs a simulation.''' + self.set_state(state) + return self.simulate(steps) + + + def clear_state(self) -> None: + '''Clears the state of the FCM.''' + self.state = np.zeros(self.connections.shape[0]) + + + def __add__(self, other: FuzzyCognitiveMap) -> FuzzyCognitiveMap: + '''Creates a new FCM that is the addition of the two different connection matrix.''' + return FuzzyCognitiveMap(self.connections + other.connections) diff --git a/ex_fuzzy/ex_fuzzy/eval_rules.py b/ex_fuzzy/ex_fuzzy/eval_rules.py new file mode 100644 index 0000000..9a41db6 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/eval_rules.py @@ -0,0 +1,397 @@ +""" +This file contains the classes to perform rule classification evaluation. + +""" +import numpy as np +from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix + +try: + from . import rules + from . import fuzzy_sets as fs +except ImportError: + import rules + import fuzzy_sets as fs + + +class evalRuleBase(): + ''' + Class to evaluate a set of rules given a evaluation dataset. + ''' + + def __init__(self, mrule_base: rules.MasterRuleBase, X: np.array, y: np.array, time_moments: np.array=None) -> None: + ''' + Creates the object with the rulebase to evaluate and the data to use in the evaluation. + + :param mrule_base: The rule base to evaluate. + :param X: array shape samples x features. The data to evaluate the rule base. + :param y: array shape samples x 1. The labels of the data. + :param time_moments: array shape samples x 1. The time moments of the samples. (Only for temporal rule bases) + :return: None + ''' + self.mrule_base = mrule_base + self.X = X + self.y = y + self.time_moments = time_moments + + self.consequents = mrule_base.get_consequents() + + + def compute_pattern_support(self) -> np.array: + ''' + Computes the pattern support for each of the rules for the given X. + Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, + dvided by their number. + + :return: array of shape rules x 2 + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + + if pattern_firing_strength[consequent_match].shape[0] > 0: + res[ix] = np.mean(pattern_firing_strength[consequent_match]) + + + return res + + + def compute_aux_pattern_support(self) -> np.array: + ''' + Computes the pattern support for each of the rules for each of the classes for the given X. + Each pattern support firing strength is the result of the tnorm for all the antecedent memeberships, + dvided by their number. + + :return: array of shape rules x 2 + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + n_classes = len(np.unique(self.y)) + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), n_classes, )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), n_classes, 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), n_classes, 2)) + + for con_ix in range(n_classes): + for ix, pattern in enumerate(patterns): + consequent_match = self.y == con_ix + pattern_firing_strength = antecedent_memberships[:, ix] + + # / pattern_firing_strength.shape[0] + if pattern_firing_strength[consequent_match].shape[0] > 0: + res[ix, con_ix] = np.mean(pattern_firing_strength[consequent_match]) + else: + res[ix, con_ix] = pattern_firing_strength[consequent_match] + + return res + + + def _get_all_rules(self) -> list[rules.RuleSimple]: + ''' + Returns a list of all the rules in the master rule base. + + :return: list of rules. + ''' + res = [] + for jx in self.mrule_base.get_rules(): + res.append(jx) + + return res + + + def compute_pattern_confidence(self) -> np.array: + ''' + Computes the pattern confidence for each of the rules for the given X. + Each pattern confidence is the normalized firing strength. + + :returns: array of shape 1 x rules + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), 2)) + + for ix, pattern in enumerate(patterns): + antecedent_consequent_match = self.y == self.consequents[ix] + pattern_firing_strength = antecedent_memberships[:, ix] + dem = np.sum(pattern_firing_strength) + if dem == 0: + res[ix] = 0 + else: + res[ix] = np.sum( + pattern_firing_strength[antecedent_consequent_match]) / dem + + return res + + + def compute_aux_pattern_confidence(self) -> np.array: + ''' + Computes the pattern confidence for each of the rules for the given X. + Each pattern confidence is the normalized firing strength. + + :returns: array of shape rules x classes + ''' + if self.time_moments is None: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X) + else: + antecedent_memberships = self.mrule_base.compute_firing_strenghts( + self.X, self.time_moments) + + patterns = self._get_all_rules() + n_classes = len(np.unique(self.y)) + if self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((len(patterns), n_classes, )) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((len(patterns), n_classes, 2)) + elif self.mrule_base.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros((len(patterns), n_classes, 2)) + + for consequent in range(n_classes): + for ix, pattern in enumerate(patterns): + antecedent_consequent_match = self.y == consequent + pattern_firing_strength = antecedent_memberships[:, ix] + dem = np.sum(pattern_firing_strength) + if dem == 0: + res[ix, consequent] = 0 + else: + res[ix, consequent] = np.sum( + pattern_firing_strength[antecedent_consequent_match]) / dem + + return res + + + def dominance_scores(self) -> np.array: + ''' + Returns the dominance score of each pattern for each rule. + + :return: array of shape rules x 2 + ''' + return self.compute_pattern_confidence() * self.compute_pattern_support() + + + def association_degree(self) -> np.array: + ''' + Returns the association degree of each rule for each sample. + + :return: vector of shape rules + ''' + firing_strengths = self.mrule_base.compute_firing_strenghts(self.X) + res = self.dominance_scores() * firing_strengths + + if (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self.mrule_base[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + res = np.mean(res, axis=2) + + return res + + + def aux_dominance_scores(self) -> np.array: + ''' + Returns the dominance score of each pattern for each rule. + + :return: array of shape rules x 2 + ''' + return self.compute_aux_pattern_confidence() * self.compute_aux_pattern_support() + + + def add_rule_weights(self) -> None: + ''' + Add dominance score field to each of the rules present in the master Rule Base. + ''' + supports = self.compute_pattern_support() + confidences = self.compute_pattern_confidence() + scores = self.dominance_scores() + + aux_counter = 0 + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + rules[jx].score = scores[aux_counter] + rules[jx].support = supports[aux_counter] + rules[jx].confidence = confidences[aux_counter] + + aux_counter += 1 + + + def add_auxiliary_rule_weights(self) -> None: + ''' + Add dominance score field to each of the rules present in the master Rule Base for each consequent. + They are labeled as aux_score, aux_support and aux_confidence. (Because they are not the main rule weights) + ''' + supports = self.compute_aux_pattern_support() + confidences = self.compute_aux_pattern_confidence() + scores = self.aux_dominance_scores() + + aux_counter = 0 + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + rules[jx].aux_score = scores[aux_counter] + rules[jx].aux_support = supports[aux_counter] + rules[jx].aux_confidence = confidences[aux_counter] + + aux_counter += 1 + + + def add_classification_metrics(self, X: np.array=None, y: np.array=None) -> None: + ''' + Adds the accuracy of each rule in the master rule base. It also adds the f1, precision and recall scores. + If X and y are None uses the train set. + + :param X: array of shape samples x features + :param y: array of shape samples + + ''' + if X is not None: + actual_X = X + actual_y = y + else: + actual_X = self.X + actual_y = self.y + + if not hasattr(self.mrule_base.get_rules()[0], 'score'): + self.add_rule_weights() + + if self.time_moments is None: + winning_rules = self.mrule_base._winning_rules(actual_X) + preds = self.mrule_base.winning_rule_predict(actual_X) + else: + winning_rules = self.mrule_base._winning_rules(actual_X, self.time_moments) + preds = self.mrule_base.winning_rule_predict(actual_X, self.time_moments) + + rules = self.mrule_base.get_rules() + for jx in range(len(rules)): + relevant_samples = winning_rules == jx + if np.sum(relevant_samples) > 0: + relevant_labels = actual_y[relevant_samples] + relevant_preds = preds[relevant_samples] + + rules[jx].accuracy = accuracy_score(relevant_labels, relevant_preds) + else: + rules[jx].accuracy = 0.0 + + + def classification_eval(self) -> float: + ''' + Returns the matthews correlation coefficient for a classification task using + the rules evaluated. + + :return: mattews correlation coefficient. (float in [-1, 1]) + ''' + from sklearn.metrics import matthews_corrcoef + self.add_rule_weights() + preds = self.mrule_base.winning_rule_predict(self.X) + + return matthews_corrcoef(self.y, preds) + + + def size_antecedents_eval(self, tolerance=0.1) -> float: + ''' + Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents. + + 0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. + The more rules and antecedent per rules the lower this score is. + + :param tolerance: float in [0, 1]. The tolerance for the dominance score. Default 0.1 + :return: float in [0, 1] with the score. + ''' + possible_rule_size = 0 + effective_rule_size = 0 + + for rule_base in self.mrule_base.get_rulebases(): + if len(rule_base) > 0: + for rule in rule_base: + rscore = np.mean(rule.score) + if rscore > tolerance: + possible_rule_size += len(rule.antecedents) + # No antecedents for this rule + if sum(np.array(rule.antecedents) != -1) == 0: + effective_rule_size += len(rule.antecedents) + else: + effective_rule_size += sum( + np.array(rule.antecedents) != -1) + + else: + return 0.0 # If one consequent does not have rules, then we return 0.0 + + try: + rule_density = 1 - effective_rule_size / possible_rule_size # Antecedents used + except ZeroDivisionError: + rule_density = 0.0 + + return rule_density + + + def effective_rulesize_eval(self, tolerance=0.1) -> float: + ''' + Returns a score between 0 and 1, where 1 means that the rule base only contains almost no antecedents. + + 0 means that the rule base contains all rules with more than {tolerance} DS, there are many of them and they have all possible antecedents. + The more rules and antecedent per rules the lower this score is. + + :param tolerance: float in [0, 1]. The tolerance for the dominance score. Default 0.1 + :return: float in [0, 1] with the score. + ''' + possible_rules = len(self.mrule_base.get_rules()) + effective_rules = 0 + + for rule_base in self.mrule_base.get_rulebases(): + if len(rule_base) > 0: + for rule in rule_base: + rscore = np.mean(rule.score) + if rscore > tolerance: + # No antecedents for this rule + if not np.all(np.equal(np.array(rule.antecedents), -1)): + effective_rules += 1 + + else: + return 0.0 # If one consequent does not have rules, then we return 0.0 + + try: + rule_density = effective_rules / possible_rules + except ZeroDivisionError: + rule_density = 0.0 + + return rule_density + + + def add_full_evaluation(self): + ''' + Adds classification scores, both Dominance Scores and accuracy metrics, for each individual rule. + ''' + self.add_rule_weights() + self.add_classification_metrics() + diff --git a/ex_fuzzy/ex_fuzzy/eval_tools.py b/ex_fuzzy/ex_fuzzy/eval_tools.py new file mode 100644 index 0000000..7b63a43 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/eval_tools.py @@ -0,0 +1,67 @@ +""" +Functions that contain some general functions to eval already fitted fuzzy rule based models. +It can also be used to visualize rules and fuzzy partitions. +""" +import numpy as np +import pandas as pd +from sklearn.metrics import matthews_corrcoef + +try: + from . import evolutionary_fit as evf + from . import vis_rules +except ImportError: + import evolutionary_fit as evf + import vis_rules + + +def eval_fuzzy_model(fl_classifier: evf.BaseFuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + # Get the unique classes from the classifier + unique_classes = fl_classifier.classes_ + # Convert the names from the labels to the corresponding class + y_train = np.array([list(unique_classes).index(str(y)) for y in y_train]) + y_test = np.array([list(unique_classes).index(str(y)) for y in y_test]) + + if print_accuracy: + print('------------') + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.predict(X_train))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.predict(X_test))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.predict(X_train)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.predict(X_test)))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier.rule_base, export_path='Demos') + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + + if print_rules: + print(res) + + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res + \ No newline at end of file diff --git a/ex_fuzzy/ex_fuzzy/evolutionary_fit.py b/ex_fuzzy/ex_fuzzy/evolutionary_fit.py new file mode 100644 index 0000000..4f2fd6d --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/evolutionary_fit.py @@ -0,0 +1,913 @@ +""" +This is a the source file that contains the class to train/fit the rulebase using a genetic algorithm. + +""" +import numpy as np +import pandas as pd + +from sklearn.model_selection import StratifiedKFold +from sklearn.metrics import matthews_corrcoef +from sklearn.base import ClassifierMixin +from pymoo.algorithms.soo.nonconvex.ga import GA +from pymoo.core.problem import Problem +from pymoo.optimize import minimize +from pymoo.operators.sampling.rnd import IntegerRandomSampling +from pymoo.operators.crossover.sbx import SBX +from pymoo.operators.mutation.pm import PolynomialMutation +from pymoo.core.variable import Integer +from multiprocessing.pool import ThreadPool +from pymoo.core.problem import StarmapParallelization + +try: + from . import fuzzy_sets as fs + from . import rules + from . import eval_rules as evr + from . import vis_rules + from . import maintenance as mnt +except ImportError: + import fuzzy_sets as fs + import rules + import eval_rules as evr + import vis_rules + import maintenance as mnt + + + +class BaseFuzzyRulesClassifier(ClassifierMixin): + ''' + Class that is used as a classifier for a fuzzy rule based system. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = fs.FUZZY_SETS.t1, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_class: int=None, precomputed_rules: rules.MasterRuleBase =None, runner: int=1) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + :param n_class: number of classes in the problem. If None (default) the classifier will compute it empirically. + :param precomputed_rules: MasterRuleBase object. If not None, the classifier will use the rules in the object and ignore the conflicting parameters. + :param runner: number of threads to use. If None (default) the classifier will use 1 thread. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['fit'] += 1 + + if precomputed_rules is not None: + self.nRules = len(precomputed_rules.get_rules()) + self.nAnts = len(precomputed_rules.get_rules()[0].antecedents) + self.n_class = len(precomputed_rules) + self.classes_ = precomputed_rules.consequent_names + self.rule_base = precomputed_rules + else: + self.nRules = nRules + self.nAnts = nAnts + + + self.custom_loss = None + self.verbose = verbose + self.tolerance = tolerance + self.classes_ = n_class + + if runner > 1: + pool = ThreadPool(runner) + self.thread_runner = StarmapParallelization(pool.starmap) + else: + self.thread_runner = None + + if linguistic_variables is not None: + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['precompute_labels'] += 1 + # If the linguistic variables are precomputed then we act accordingly + self.lvs = linguistic_variables + self.n_linguist_variables = len( + self.lvs[0].linguistic_variable_names()) + self.domain = None + self.fuzzy_type = self.lvs[0].fuzzy_type() + else: + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['opt_labels'] += 1 + + # If not, then we need the parameters sumistered by the user. + self.lvs = None + self.fuzzy_type = fuzzy_type + self.n_linguist_variables = n_linguist_variables + self.domain = domain + + self.alpha_ = 0.950 + self.beta_ = 0.025 + self.gamma_ = 0.025 + + def customized_loss(self, loss_function): + ''' + Function to customize the loss function used for the optimization. + + :param loss_function: function that takes as input the true labels and the predicted labels and returns a float. + :return: None + ''' + self.custom_loss = loss_function + + + def fit(self, X: np.array, y: np.array, n_gen:int=70, pop_size:int=30, checkpoints:int=10, candidate_rules:rules.MasterRuleBase=None, initial_rules:rules.MasterRuleBase=None): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :param checkpoints: integer. Number of checkpoints to save the best rulebase found so far. + :param candidate_rules: if these rules exist, the optimization process will choose the best rules from this set. If None (default) the rules will be generated from scratch. + :return: None. The classifier is fitted to the data. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['fit'] += 1 + + if self.classes_ is None: + if isinstance(y, pd.Series): + self.classes_ = [str(aux) for aux in y.unique()] + # Convert the names in the label vector to integer classes + y = np.array(y.replace(self.classes_, np.arange(len(self.classes_)))) + else: + self.classes_ = [str(aux) for aux in np.unique(y)] + + if candidate_rules is None: + if initial_rules is not None: + self.fuzzy_type = initial_rules.fuzzy_type() + self.n_linguist_variables = initial_rules.n_linguist_variables() + self.domain = [fv.domain for fv in initial_rules[0].antecedents] + self.nRules = len(initial_rules.get_rules()) + self.nAnts = len(initial_rules.get_rules()[0].antecedents) + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, n_classes=len(np.unique(y)), + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, thread_runner=self.thread_runner, + alpha=self.alpha_, beta=self.beta_, gamma=self.gamma_) + else: + # If Fuzzy variables are already precomputed. + problem = FitRuleBase(X, y, nRules=self.nRules, nAnts=self.nAnts, n_classes=len(np.unique(y)), + linguistic_variables=self.lvs, domain=self.domain, tolerance=self.tolerance, thread_runner=self.thread_runner, + alpha=self.alpha_, beta=self.beta_, gamma=self.gamma_) + else: + self.fuzzy_type = candidate_rules.fuzzy_type() + self.n_linguist_variables = candidate_rules.n_linguist_variables() + problem = ExploreRuleBases(X, y, n_classes=len(np.unique(y)), cancidate_rules=candidate_rules, thread_runner=self.thread_runner, nRules=self.nRules) + + if self.custom_loss is not None: + problem.fitness_func = self.custom_loss + + if initial_rules is not None: + rules_gene = problem.encode_rulebase(initial_rules, self.lvs is None) + rules_gene = (np.ones((pop_size, len(rules_gene))) * rules_gene).astype(int) + else: + rules_gene = IntegerRandomSampling() + + algorithm = GA( + pop_size=pop_size, + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + sampling=rules_gene, + eliminate_duplicates=False) + + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, res.pop.get('F').mean(), res.pop.get('F').min())) + if k % checkpoints == 0: + with open("checkpoint_" + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_full_evaluation() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + rule_base.rename_cons(self.classes_) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + + + self.performance = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + self.rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + self.rule_base.rename_cons(self.classes_) + + self.eval_performance = evr.evalRuleBase( + self.rule_base, np.array(X), y) + + self.eval_performance.add_full_evaluation() + self.rename_fuzzy_variables() + self.eval_performance.add_classification_metrics() + self.rule_base.purge_rules(self.tolerance) + + + def load_master_rule_base(self, rule_base: rules.MasterRuleBase) -> None: + ''' + Loads a master rule base to be used in the prediction process. + + :param rule_base: ruleBase object. + :return: None + ''' + self.rule_base = rule_base + self.nRules = len(rule_base.get_rules()) + self.nAnts = len(rule_base.get_rules()[0].antecedents) + self.n_class = len(rule_base) + + + def forward(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a pandas dataframe + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X) + + + def predict(self, X: np.array) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :return: np array samples (x 1) with the predicted class. + ''' + return self.forward(X) + + + def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules contained in the fitted rulebase. + ''' + return self.rule_base.print_rules(return_rules) + + + def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv) + + + def rename_fuzzy_variables(self) -> None: + ''' + Renames the linguist labels so that high, low and so on are consistent. It does so usually after an optimization process. + + :return: None. Names are sorted accorded to the central point of the fuzzy memberships. + ''' + + for ix in range(len(self.rule_base)): + fuzzy_variables = self.rule_base.rule_bases[ix].antecedents + + for jx, fv in enumerate(fuzzy_variables): + # I feel so extraordinary, lifes got a hold on me... + new_order_values = [] + possible_names = FitRuleBase.vl_names[self.n_linguist_variables] + + for zx, fuzzy_set in enumerate(fv.linguistic_variables): + studied_fz = fuzzy_set.type() + + if studied_fz == fs.FUZZY_SETS.temporal: + studied_fz = fuzzy_set.inside_type() + + if studied_fz == fs.FUZZY_SETS.t1: + f1 = np.mean( + fuzzy_set.membership_parameters[0] + fuzzy_set.membership_parameters[1]) + elif (studied_fz == fs.FUZZY_SETS.t2): + f1 = np.mean( + fuzzy_set.secondMF_upper[0] + fuzzy_set.secondMF_upper[1]) + elif studied_fz == fs.FUZZY_SETS.gt2: + sec_memberships = fuzzy_set.secondary_memberships.values() + f1 = float(list(fuzzy_set.secondary_memberships.keys())[np.argmax( + [fzm.membership_parameters[2] for ix, fzm in enumerate(sec_memberships)])]) + + new_order_values.append(f1) + + new_order = np.argsort(np.array(new_order_values)) + fuzzy_sets_vl = fv.linguistic_variables + + for jx, x in enumerate(new_order): + fuzzy_sets_vl[x].name = possible_names[jx] + + + def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix() + + + def reparametrice_loss(self, alpha:float, beta:float, gamma:float) -> None: + ''' + Changes the parameters in the loss function. + + :note: Does not check for convexity preservation. The user can play with these parameters as it wills. + :param alpha: controls the MCC term. + :param beta: controls the average rule size loss. + :param gamma: controls the number of rules loss. + ''' + self.alpha_ = alpha + self.beta_ = beta + self.gamma_ = gamma + +class ExploreRuleBases(Problem): + ''' + Class to model as pymoo problem the fitting of a rulebase to a set of data given a series of candidate rules for a classification problem using Evolutionary strategies + Supports type 1 and t2. + ''' + + def __init__(self, X: np.array, y: np.array, nRules: int, n_classes: int, cancidate_rules: rules.MasterRuleBase, thread_runner: StarmapParallelization=None, tolerance:float = 0.01) -> None: + ''' + Cosntructor method. Initializes the classifier with the number of antecedents, linguist variables and the kind of fuzzy set desired. + + :param X: np array or pandas dataframe samples x features. + :param y: np vector containing the target classes. vector sample + :param n_class: number of classes in the problem. If None (as default) it will be computed from the data. + :param cancidate_rules: MasterRuleBase object. If not None, the classifier will use the rules in the object and ignore the conflicting parameters. + ''' + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + self.tolerance = tolerance + self.fuzzy_type = cancidate_rules.fuzzy_type() + self.y = y + self.nCons = 1 # This is fixed to MISO rules. + self.n_classes = n_classes + self.candidate_rules = cancidate_rules + self.nRules = nRules + + self.vl_names = self.candidate_rules[0].antecedents[0].linguistic_variable_names() + self.fuzzy_type = self.candidate_rules[0].antecedents[0].fuzzy_type() + + self.min_bounds = np.min(self.X, axis=0) + self.max_bounds = np.max(self.X, axis=0) + + nTotalRules = len(self.candidate_rules.get_rules()) + # Each var is using or not a rule. + vars = {ix: Integer(bounds=[0, nTotalRules - 1]) for ix in range(self.nRules)} + varbound = np.array([[0, nTotalRules- 1]] * self.nRules) + + nVar = len(vars.keys()) + if thread_runner is not None: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1], + elementwise_runner=thread_runner) + else: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1]) + + + def _construct_ruleBase(self, x: np.array, fuzzy_type: fs.FUZZY_SETS) -> rules.MasterRuleBase: + ''' + Creates a valid rulebase from the given subject and the candidate rules. + + :param x: gen of a rulebase. type: dict. + + :return: a Master rulebase object. + ''' + x = x.astype(int) + # Get all rules and their consequents + diff_consequents = np.arange(len(self.candidate_rules)) + + # Choose the selected ones in the gen + total_rules = self.candidate_rules.get_rules() + chosen_rules = [total_rules[ix] for ix, val in enumerate(x)] + rule_consequents = sum([[ix] * len(rule) for ix, rule in enumerate(self.candidate_rules)], []) + chosen_rules_consequents = [rule_consequents[val] for ix, val in enumerate(x)] + # Create a rule base for each consequent with the selected rules + rule_list = [[] for _ in range(self.n_classes)] + rule_bases = [] + for ix, consequent in enumerate(diff_consequents): + for rx, rule in enumerate(chosen_rules): + if chosen_rules_consequents[rx] == consequent: + rule_list[ix].append(rule) + + if len(rule_list[ix]) > 0: + if fuzzy_type == fs.FUZZY_SETS.t1: + rule_base_cons = rules.RuleBaseT1( + self.candidate_rules[0].antecedents, rule_list[ix]) + elif fuzzy_type == fs.FUZZY_SETS.t2: + rule_base_cons = rules.RuleBaseT2( + self.candidate_rules[0].antecedents, rule_list[ix]) + elif fuzzy_type == fs.FUZZY_SETS.gt2: + rule_base_cons = rules.RuleBaseGT2( + self.candidate_rules[0].antecedents, rule_list[ix]) + + rule_bases.append(rule_base_cons) + + # Create the Master Rule Base object with the individual rule bases + newMasterRuleBase = rules.MasterRuleBase(rule_bases, diff_consequents) + + return newMasterRuleBase + + + def _evaluate(self, x: np.array, out: dict, *args, **kwargs): + ''' + :param x: array of train samples. x shape = features + those features are the parameters to optimize. + + :param out: dict where the F field is the fitness. It is used from the outside. + ''' + try: + ruleBase = self._construct_ruleBase(x, self.fuzzy_type) + + score = self.fitness_func(ruleBase, self.X, self.y, self.tolerance) + + + out["F"] = 1 - score + except rules.RuleError: + out["F"] = 1 + + + def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.95, beta:float=0.025, gamma:float=0.025) -> float: + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_rule_weights() + + score_acc = ev_object.classification_eval() + score_rules_size = ev_object.size_antecedents_eval(tolerance) + score_nrules = ev_object.effective_rulesize_eval(tolerance) + + score = score_acc * alpha + (1 - alpha) * (score_rules_size * beta + score_nrules * gamma) + + return score + + + +class FitRuleBase(Problem): + ''' + Class to model as pymoo problem the fitting of a rulebase for a classification problem using Evolutionary strategies. + Supports type 1 and iv fs (iv-type 2) + ''' + + def _init_optimize_vl(self, fuzzy_type: fs.FUZZY_SETS, n_linguist_variables: int, domain: list[(float, float)] = None): + ''' + Inits the corresponding fields if no linguistic partitions were given. + + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + ''' + self.lvs = None + try: + self.vl_names = FitRuleBase.vl_names[n_linguist_variables] + except IndexError: + self.vl_names = [str(ix) for ix in range(n_linguist_variables)] + + self.fuzzy_type = fuzzy_type + self.n_lv_possible = n_linguist_variables + self.domain = domain + + + def _init_precomputed_vl(self, linguist_variables: list[fs.fuzzyVariable]): + ''' + Inits the corresponding fields if linguistic partitions for each variable are given. + + :param linguistic_variables: list of fuzzyVariables type. + ''' + self.lvs = linguist_variables + self.vl_names = self.lvs[0].linguistic_variable_names() + self.n_lv_possible = len(self.lvs[0]) + self.fuzzy_type = self.lvs[0].fs_type + self.domain = None + + vl_names = [ # Linguistic variable names preestated for some specific cases. + [], + [], + ['Low', 'High'], + ['Low', 'Medium', 'High'], + ['Low', 'Medium', 'High', 'Very High'], + ['Very Low', 'Low', 'Medium', 'High', 'Very High'] + ] + + def __init__(self, X: np.array, y: np.array, nRules: int, nAnts: int, n_classes: int, thread_runner: StarmapParallelization=None, + linguistic_variables:list[fs.fuzzyVariable]=None, n_linguist_variables:int=3, fuzzy_type=fs.FUZZY_SETS.t1, domain:list=None, + tolerance:float=0.01, alpha:float=0.950, beta:float=0.025, gamma:float=0.025) -> None: + ''' + Cosntructor method. Initializes the classifier with the number of antecedents, linguist variables and the kind of fuzzy set desired. + + :param X: np array or pandas dataframe samples x features. + :param y: np vector containing the target classes. vector sample + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param n_class: number of classes in the problem. If None (as default) it will be computed from the data. + :param linguistic_variables: list of linguistic variables precomputed. If given, the rest of conflicting arguments are ignored. + :param n_linguistic_variables: number of linguistic variables per antecedent. + :param fuzzy_type: Define the fuzzy set or fuzzy set extension used as linguistic variable. + :param domain: list with the upper and lower domains of each input variable. If None (as default) it will stablish the empirical min/max as the limits. + ''' + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + try: + self.tolerance = tolerance + except KeyError: + self.tolerance = 0.001 + + self.y = y + self.nRules = nRules + self.nAnts = nAnts + self.nCons = 1 # This is fixed to MISO rules. + + if n_classes is not None: + self.n_classes = n_classes + else: + self.n_classes = len(np.unique(y)) + + if linguistic_variables is not None: + self._init_precomputed_vl(linguistic_variables) + else: + self._init_optimize_vl( + fuzzy_type, n_linguist_variables) + + if self.domain is None: + self.min_bounds = np.min(self.X, axis=0) + self.max_bounds = np.max(self.X, axis=0) + else: + self.min_bounds, self.max_bounds = self.domain + + self.antecedents_referencial = [np.linspace( + self.min_bounds[ix], self.max_bounds[ix], 100) for ix in range(self.X.shape[1])] + + possible_antecedent_bounds = np.array( + [[0, self.X.shape[1] - 1]] * self.nAnts * self.nRules) + vl_antecedent_bounds = np.array( + [[-1, self.n_lv_possible - 1]] * self.nAnts * self.nRules) # -1 means not caring + antecedent_bounds = np.concatenate( + (possible_antecedent_bounds, vl_antecedent_bounds)) + vars_antecedent = {ix: Integer( + bounds=antecedent_bounds[ix]) for ix in range(len(antecedent_bounds))} + aux_counter = len(vars_antecedent) + + if self.lvs is None: + assert self.n_lv_possible >= 1, 'At least 1 possible value for a linguistic variable is required.' + + self.feature_domain_bounds = np.array( + [[0, 99] for ix in range(self.X.shape[1])]) + size_multiplier = 4 if self.fuzzy_type == fs.FUZZY_SETS.t1 else 8 + membership_bounds = np.concatenate( + [self.feature_domain_bounds] * self.n_lv_possible * size_multiplier) + vars_memeberships = { + aux_counter + ix: Integer(bounds=membership_bounds[ix]) for ix in range(len(membership_bounds))} + aux_counter += len(vars_memeberships) + + final_consequent_bounds = np.array( + [[-1, self.n_classes - 1]] * self.nRules) + vars_consequent = {aux_counter + ix: Integer( + bounds=final_consequent_bounds[ix]) for ix in range(len(final_consequent_bounds))} + + if self.lvs is None: + vars = {key: val for d in [ + vars_antecedent, vars_memeberships, vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, membership_bounds, final_consequent_bounds), axis=0) + else: + vars = {key: val for d in [vars_antecedent, + vars_consequent] for key, val in d.items()} + varbound = np.concatenate( + (antecedent_bounds, final_consequent_bounds), axis=0) + + nVar = len(varbound) + self.single_gen_size = nVar + self.alpha_ = alpha + self.beta_ = beta + self.gamma_ = gamma + + if thread_runner is not None: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1], + elementwise_runner=thread_runner) + else: + super().__init__( + vars=vars, + n_var=nVar, + n_obj=1, + elementwise=True, + vtype=int, + xl=varbound[:, 0], + xu=varbound[:, 1]) + + + def encode_rulebase(self, rule_base: rules.MasterRuleBase, optimize_lv: bool) -> np.array: + ''' + Given a rule base, constructs the corresponding gene associated with that rule base. + + GENE STRUCTURE + + First: antecedents chosen by each rule. Size: nAnts * nRules (index of the antecedent) + Second: Variable linguistics used. Size: nAnts * nRules + Third: Parameters for the fuzzy partitions of the chosen variables. Size: nAnts * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) + Four: Consequent classes. Size: nRules + + :param rule_base: rule base object. + :param optimize_lv: if True, the gene is prepared to optimize the membership functions. + :param antecedents_referencial: list of lists. Each list contains the referencial for each variable. Required only if optimize_lv is True. + :return: np array of size self.single_gen_size. + ''' + gene = np.zeros((self.single_gen_size,)) + + n_lv_possible = len(rule_base.rule_bases[0].antecedents[0].linguistic_variables) + fz_type = rule_base.fuzzy_type() + rule_consequents = rule_base.get_consequents() + nreal_rules = len(rule_consequents) + mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8 + + # Pointer to the fourth section of the gene: consequents + if optimize_lv: + # If lv memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + \ + len(rule_base.antecedents) * n_lv_possible * mf_size + else: + # If no memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + + # First and second sections of the gene: antecedents and linguistic variables + for i0, rule in enumerate(rule_base.get_rules()): # Reconstruct the rules + first_pointer = i0 * self.nAnts + second_pointer = (self.nRules * self.nAnts) + i0 * self.nAnts + + for ax, linguistic_variable in enumerate(rule.antecedents): + gene[first_pointer + ax] = ax + gene[second_pointer + ax] = linguistic_variable + + # Update the fourth section of the gene: consequents using the fourth pointer + gene[fourth_pointer + i0] = rule_consequents[i0] + + # Fill the rest of the rules with don't care values + nvoid_rules = self.nRules - nreal_rules + for vx in range(nvoid_rules): + first_pointer = nreal_rules * self.nAnts + vx * self.nAnts + second_pointer = (self.nRules * self.nAnts) + nreal_rules * self.nAnts + vx * self.nAnts + + for ax, linguistic_variable in enumerate(rule.antecedents): + gene[first_pointer + ax] = ax + gene[second_pointer + ax] = -1 + + # Update the fourth section of the gene: consequents using the fourth pointer + gene[fourth_pointer + nreal_rules + vx] = -1 + + if optimize_lv: + # If lv memberships are optimized. + third_pointer = 2 * self.nAnts * self.nRules + aux_pointer = 0 + for ix, fuzzy_variable in enumerate(rule_base.get_antecedents()): + for linguistic_variable in range(n_lv_possible): + fz_parameters = fuzzy_variable[linguistic_variable].membership_parameters + for jx, fz_parameter in enumerate(fz_parameters): + closest_idx = (np.abs(np.asarray(self.antecedents_referencial[ix]) - fz_parameter)).argmin() + gene[third_pointer + aux_pointer] = closest_idx + aux_pointer += 1 + + return np.array(list(map(int, gene))) + + + + def _construct_ruleBase(self, x: np.array, fz_type: fs.FUZZY_SETS, **kwargs) -> rules.MasterRuleBase: + ''' + Given a subject, it creates a rulebase according to its specification. + + :param x: gen of a rulebase. type: dict. + :param fz_type: a enum type. Check fuzzy_sets for complete specification (two fields, t1 and t2, to mark which fs you want to use) + :return: a rulebase object. + + kwargs: + - time_moment: if temporal fuzzy sets are used with different partitions for each time interval, + then this parameter is used to specify which time moment is being used. + ''' + + rule_list = [[] for _ in range(self.n_classes)] + + mf_size = 4 if fz_type == fs.FUZZY_SETS.t1 else 8 + ''' + GEN STRUCTURE + + First: antecedents chosen by each rule. Size: nAnts * nRules + Second: Variable linguistics used. Size: nAnts * nRules + Third: Parameters for the fuzzy partitions of the chosen variables. Size: X.shape[1] * self.n_linguistic_variables * 8|4 (2 trapezoidal memberships if t2) + Four: Consequent classes. Size: nRules (fixed to 4 right now) + ''' + if self.lvs is None: + # If memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + \ + self.X.shape[1] * self.n_lv_possible * mf_size + else: + # If no memberships are optimized. + fourth_pointer = 2 * self.nAnts * self.nRules + + aux_pointer = 0 + min_domain = np.min(self.X, axis=0) + max_domain = np.max(self.X, axis=0) + + # Integer sampling doesnt work fine in pymoo, so we do this (which is btw what pymoo is really doing if you just set integer optimization) + try: + # subject might come as a dict. + x = np.array(list(x.values())).astype(int) + except AttributeError: + x = x.astype(int) + + for i0 in range(self.nRules): # Reconstruct the rules + first_pointer = i0 * self.nAnts + chosen_ants = x[first_pointer:first_pointer + self.nAnts] + + second_pointer = (i0 * self.nAnts) + (self.nAnts * self.nRules) + # Shape: self.nAnts + self.n_lv_possible + 1 + antecedent_parameters = x[second_pointer:second_pointer+self.nAnts] + + init_rule_antecedents = np.zeros( + (self.X.shape[1],)) - 1 # -1 is dont care + for jx, ant in enumerate(chosen_ants): + init_rule_antecedents[ant] = antecedent_parameters[jx] + + consequent_idx = x[fourth_pointer + aux_pointer] + assert consequent_idx < self.n_classes, "Consequent class is not valid. Something in the gene is wrong." + aux_pointer += 1 + + if consequent_idx != -1: + rule_list[consequent_idx].append( + rules.RuleSimple(init_rule_antecedents, 0)) + + # If we optimize the membership functions + if self.lvs is None: + third_pointer = 2 * self.nAnts * self.nRules + aux_pointer = 0 + antecedents = [] + for fuzzy_variable in range(self.X.shape[1]): + linguistic_variables = [] + + for linguistic_variable in range(self.n_lv_possible): + parameter_pointer = third_pointer + aux_pointer + fz_parameters_idx = x[parameter_pointer:parameter_pointer + mf_size] + fz_parameters = self.antecedents_referencial[fuzzy_variable][fz_parameters_idx] + aux_pointer += mf_size + + if fz_type == fs.FUZZY_SETS.t2: + fz_parameters[0:6] = np.sort(fz_parameters[0:6]) + mu = [np.min(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.max(fz_parameters[4:6])] + ml = [np.max(fz_parameters[0:2]), fz_parameters[2], + fz_parameters[3], np.min(fz_parameters[4:6])] + height = fz_parameters[6] / np.max(fz_parameters) + + ivfs = fs.IVFS(self.vl_names[linguistic_variable], ml, mu, + (min_domain[fuzzy_variable], max_domain[fuzzy_variable]), lower_height=height) + else: + ivfs = fs.FS(self.vl_names[linguistic_variable], np.sort(fz_parameters[0:4]), + (min_domain[fuzzy_variable], max_domain[fuzzy_variable])) + linguistic_variables.append(ivfs) + + antecedents.append(fs.fuzzyVariable( + self.var_names[fuzzy_variable], linguistic_variables)) + else: + try: + antecedents = self.lvs[kwargs['time_moment']] + except: + antecedents = self.lvs + + for i in range(self.n_classes): + if fz_type == fs.FUZZY_SETS.temporal: + fz_type = self.lvs[0][0].inside_type() + + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(antecedents, rule_list[i]) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(antecedents, rule_list[i]) + + + if i == 0: + res = rules.MasterRuleBase([rule_base]) + else: + res.add_rule_base(rule_base) + + return res + + + def _evaluate(self, x: np.array, out: dict, *args, **kwargs): + ''' + :param x: array of train samples. x shape = features + those features are the parameters to optimize. + + :param out: dict where the F field is the fitness. It is used from the outside. + ''' + ruleBase = self._construct_ruleBase(x, self.fuzzy_type) + + if len(ruleBase.get_rules()) > 0: + score = self.fitness_func(ruleBase, self.X, self.y, self.tolerance, self.alpha_, self.beta_, self.gamma_) + else: + score = 0.0 + + out["F"] = 1 - score + + + def fitness_func(self, ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.975, beta:float=0.0125, gamma:float=0.0125) -> float: + ''' + Fitness function for the optimization problem. + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_full_evaluation() + ruleBase.purge_rules(tolerance) + + if len(ruleBase.get_rules()) > 0: + score_acc = ev_object.classification_eval() + score_rules_size = ev_object.size_antecedents_eval(tolerance) + score_nrules = ev_object.effective_rulesize_eval(tolerance) + + score = score_acc * alpha + score_rules_size * beta + score_nrules * gamma + else: + score = 0.0 + + return score + + diff --git a/ex_fuzzy/ex_fuzzy/fuzzy_sets.py b/ex_fuzzy/ex_fuzzy/fuzzy_sets.py new file mode 100644 index 0000000..4d7c009 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/fuzzy_sets.py @@ -0,0 +1,442 @@ +""" +This is a the source file that contains the class of GT2 fuzzy set and its most direct applications, +like computing the FM function, etc. + +""" +import enum + +import numpy as np + +try: + from . import maintenance as mnt +except: + import maintenance as mnt + + +''' Enum that defines the fuzzy set types.''' +class FUZZY_SETS(enum.Enum): + t1 = 'Type 1' + t2 = 'Type 2' + gt2 = 'General Type 2' + + + def __eq__(self, __value: object) -> bool: + return self.value == __value.value + +def trapezoidal_membership(x: np.array, params: list[float], epsilon=10E-5) -> np.array: + ''' + Trapezoidal membership functions. + + :param x: input values in the fuzzy set referencial domain. + :param params: four numbers that comprises the start and end of the trapezoid. + :param epsilon: small float number for numerical stability. Adjust accordingly only if there are NaN issues. + ''' + a, b, c, d = params + + # Special case: a singleton trapezoid + if a == d: + return np.equal(a, x).astype(float) + + if b == a: + b += epsilon + if c == d: + d += epsilon + + aux1 = (x - a) / (b - a) + aux2 = (d - x) / (d - c) + + return np.maximum(np.minimum(np.minimum(aux1, aux2), 1), 0) + + +def __gaussian2(x, params: list[float]) -> np.array: + ''' + Gaussian membership functions. + + :param mean: real number, mean of the gaussian function. + :param amplitude: real number. + :param standard_deviation: std of the gaussian function. + ''' + mean, amplitude, standard_deviation = params + return amplitude * np.exp(- ((x - mean) / standard_deviation) ** 2) + + +class FS(): + ''' + Class that defines the most basic fuzzy sets (also known as Type 1 fuzzy sets or Zadeh sets). + ''' + + def __init__(self, name: str, membership_parameters: list[float], domain: list[float]) -> None: + ''' + Creates a fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain of the fuzzy set. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + self.name = name + self.domain = domain + self.membership_parameters = membership_parameters + + + def membership(self, x: np.array) -> np.array: + ''' + Computes the membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + ''' + return trapezoidal_membership(x, self.membership_parameters) + + + def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum. + + :return: FUZZY_SETS enum. + ''' + return FUZZY_SETS.t1 + + + def __call__(self, x: np.array) -> np.array: + ''' + Calling the Fuzzy set returns its membership. + + :param x: input values in the fuzzy set referencial domain. + :return: membership of the fuzzy set. + ''' + return self.membership(x) + + +class IVFS(FS): + ''' + Class to define a iv fuzzy set. + ''' + + def __init__(self, name: str, secondMF_lower: list[float], secondMF_upper: list[float], + domain: list[float], lower_height=1.0) -> None: + ''' + Creates a IV fuzzy set. + + :param name: string. + :param secondMF_lower: four real numbers. Parameters of the lower trapezoid/gaussian function. + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + ''' + self.name = name + self.domain = domain + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + assert secondMF_lower[0] >= secondMF_upper[0], 'First term membership incoherent' + assert secondMF_lower[0] <= secondMF_lower[1] and secondMF_lower[ + 1] <= secondMF_lower[2] and secondMF_lower[2] <= secondMF_lower[3], 'Lower memberships incoherent. ' + assert secondMF_upper[0] <= secondMF_upper[1] and secondMF_upper[ + 1] <= secondMF_upper[2] and secondMF_upper[2] <= secondMF_upper[3], 'Upper memberships incoherent.' + assert secondMF_lower[3] <= secondMF_upper[3], 'Final term memberships incoherent.' + + self.secondMF_lower = secondMF_lower + self.secondMF_upper = secondMF_upper + self.lower_height = lower_height + + + def membership(self, x: np.array) -> np.array: + ''' + Computes the iv-membership of a point or a vector. + + :param x: input values in the fuzzy set referencial domain. + :return: iv-membership of the fuzzy set. + ''' + lower = trapezoidal_membership( + x, self.secondMF_lower) * self.lower_height + upper = trapezoidal_membership(x, self.secondMF_upper) + + try: + assert np.all(lower <= upper) + except AssertionError: + np.argwhere(lower > upper) + + return np.stack([lower, upper], axis=-1) + + + def type(self) -> FUZZY_SETS: + ''' + Returns the corresponding fuzzy set type according to FUZZY_SETS enum: (t2) + ''' + return FUZZY_SETS.t2 + + +class GT2(FS): + ''' + Class to define a gt2 fuzzy set. + ''' + + MAX_RES_SUPPORT = 4 # Number of decimals supported in the secondary + + def __init__(self, name: str, secondary_memberships: dict[float, FS], + domain: list[float], significant_decimals: int, + alpha_cuts: list[float] = [0.2, 0.4, 0.5, 0.7, 0.9, 1.0], + unit_resolution: float = 0.2) -> None: + ''' + Creates a GT2 fuzzy set. + + :param name: string. + :param secondary_memberships: list of fuzzy sets. Secondary membership that maps original domain to [0, 1] + :param secondMF_upper: four real numbers. Parameters of the upper trapezoid/gaussian function. + :param domain: list of two numbers. Limits of the domain if the fuzzy set. + :param alpha_cuts: list of real numbers. Alpha cuts of the fuzzy set. + :param unit_resolution: real number. Resolution of the primary membership function. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + self.name = name + self.domain = domain + self.secondary_memberships = secondary_memberships + self.alpha_cuts = alpha_cuts + self.iv_secondary_memberships = {} + self.unit_resolution = unit_resolution + og_keys = list(self.secondary_memberships.keys()) + self.significant_decimals = significant_decimals + self.domain_init = int( + float(og_keys[0]) * 10**self.significant_decimals) + + formatted_keys = [('%.' + str(self.significant_decimals) + 'f') % + xz for xz in np.array(list(self.secondary_memberships.keys()))] + for og_key, formatted_key in zip(og_keys, formatted_keys): + secondary_memberships[formatted_key] = self.secondary_memberships.pop( + og_key) + + self.sample_unit_domain = np.arange( + 0, 1 + self.unit_resolution, self.unit_resolution) + + for ix, alpha_cut in enumerate(alpha_cuts): + level_memberships = {} + array_level_memberships = np.zeros( + (len(secondary_memberships.items()), 2)) + + for jx, (x, fs) in enumerate(secondary_memberships.items()): + alpha_primary_memberships = fs.membership( + self.sample_unit_domain) + alpha_membership = alpha_primary_memberships >= alpha_cut + + try: + b = self.sample_unit_domain[np.argwhere( + alpha_membership)[0]][0] + c = self.sample_unit_domain[np.argwhere( + alpha_membership)[-1]][0] + except IndexError: # If no numbers are bigger than alpha, then it is because of rounding errors near 0. So, we fix this manually. + b = 0 + c = 0 + + alpha_cut_interval = [b, c] + + level_memberships[x] = alpha_cut_interval + array_level_memberships[jx, :] = np.array(alpha_cut_interval) + + self.iv_secondary_memberships[alpha_cut] = array_level_memberships + + + def membership(self, x: np.array) -> np.array: + ''' + Computes the alpha cut memberships of a point. + + :param x: input values in the fuzzy set referencial domain. + :return: np array samples x alpha_cuts x 2 + ''' + x = np.array(x) + # locate the x in the secondary membership + formatted_x = ( + x * 10**self.significant_decimals).astype(int) - self.domain_init + + # Once the x is located we compute the function for each alpha cut + alpha_cut_memberships = [] + for ix, alpha in enumerate(self.alpha_cuts): + ivfs = np.squeeze( + np.array(self.iv_secondary_memberships[alpha][formatted_x])) + alpha_cut_memberships.append(np.squeeze(ivfs)) + + alpha_cut_memberships = np.array(alpha_cut_memberships) + + # So that the result is samples x alpha_cuts x 2 + return np.swapaxes(alpha_cut_memberships, 0, 1) + + + def type(self) -> FUZZY_SETS: + return FUZZY_SETS.gt2 + + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + if len(x.shape) == 3: + formatted = np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0) + else: + formatted = self.alpha_cuts + return np.sum(formatted * x, axis=-1) / np.sum(self.alpha_cuts) + + + def alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + return self._alpha_reduction(x) + + +class gaussianIVFS(IVFS): + ''' + Class to define a iv fuzzy set with gaussian membership. + ''' + + def membership(self, input: np.array) -> np.array: + ''' + Computes the gaussian iv-membership of a point or a vector. + + :param input: input values in the fuzzy set referencial domain. + :return: np array samples x 2 + ''' + lower = __gaussian2(input, self.secondMF_lower) + upper = __gaussian2(input, self.secondMF_upper) + + return np.array(np.concatenate([lower, upper])).T + + + def type(self) -> FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (t1) + ''' + return FUZZY_SETS.t1 + + +class fuzzyVariable(): + ''' + Class to implement a fuzzy Variable. Contains a series of fuzzy sets and computes the memberships to all of them. + ''' + + def __init__(self, name: str, fuzzy_sets: list[FS]) -> None: + ''' + Creates a fuzzy variable. + + :param name: string. Name of the fuzzy variable. + :param fuzzy_sets: list of IVFS. Each of the fuzzy sets that comprises the linguist variables of the fuzzy variable. + ''' + self.linguistic_variables = [] + self.name = name + + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + + def linguistic_variable_names(self) -> list: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return [fs.name for fs in self.linguistic_variables] + + + def get_linguistic_variables(self) -> list[FS]: + ''' + Returns the name of the linguistic variables. + + :return: list of strings. + ''' + return self.linguistic_variables + + + def compute_memberships(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the FS in the fuzzy variables. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x)) + + return res + + + def domain(self) -> list[float]: + ''' + Returns the domain of the fuzzy variable. + + :return: list of floats. + ''' + return self.linguistic_variables[0].domain + + + def fuzzy_type(self) -> FUZZY_SETS: + ''' + Returns the fuzzy type of the domain + + :return: the type of the fuzzy set present in the fuzzy variable. + ''' + return self.fs_type + + + def __getitem__(self, item) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + return self.linguistic_variables[item] + + + def __setitem__(self, item: int, elem: FS) -> None: + ''' + Sets the corresponding fs. + + :param item: int. Index of the FS. + :param elem: FS. The FS to set. + ''' + self.linguistic_variables[item] = elem + + + def __iter__(self) -> FS: + ''' + Returns the corresponding fs. + + :param item: int. Index of the FS. + :return: FS. The corresponding FS. + ''' + for fs in self.linguistic_variables: + yield fs + + + def __len__(self) -> int: + ''' + Returns the number of linguistic variables. + + :return: int. Number of linguistic variables. + ''' + return len(self.linguistic_variables) + + + def __call__(self, x: np.array) -> list: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + return self.compute_memberships(x) + + diff --git a/ex_fuzzy/ex_fuzzy/maintenance.py b/ex_fuzzy/ex_fuzzy/maintenance.py new file mode 100644 index 0000000..ff81556 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/maintenance.py @@ -0,0 +1,161 @@ + +''' +Module to keep track of the usage of the different features of the library. +Asks nicely for permission before saving anything. + +''' +import os as _os +import atexit + +from enum import Enum + +usage_categories = Enum('uses', ['FuzzySets', 'Funcs', 'Persistence', 'Visualization', 'FuzzyCognitiveMaps', 'RuleMining', 'Classification']) + +def instance_dict_usage(): + # Inits the categories to track + return {usage_categories.FuzzySets: {'t1':0 , 't2': 0, 'gt2': 0, 'temporal': 0, 'temporal_t2': 0}, + usage_categories.Funcs: {'fit': 0, 'precompute_labels': 0, 'opt_labels':0}, + usage_categories.Persistence : {'persistence_write': 0, + 'persistence_read': 0}, + usage_categories.FuzzyCognitiveMaps : {'fcm_create': 0, 'fcm_report': 0}, + usage_categories.Visualization : {'plot_rules': 0, 'plot_graph': 0, 'print_rules': 0, 'plot_fuzzy_variable': 0}, + usage_categories.RuleMining : {'mine_rulebase' : 0}, + usage_categories.Classification : {'double_go': 0, 'data_mining': 0} + } + + +def rename_dict_usage_categories(): + global usage_data + str_names = ['Fuzzy sets', 'Utils and training', 'Persistence', 'Fuzzy Cognitive Maps', 'Visualization', 'Rule Mining', 'Classification'] + new_usage = {} + + for ix, (key, value) in enumerate(usage_data.items()): + new_usage[str_names[ix]] = value + + usage_data = new_usage + + +@atexit.register +def save_usage(): + # Saves the usage in the corresponding file + path_usage_data = _os.path.join(path_usage_data_folder, 'usage_data_' + str(number_files) + '.txt') + rename_dict_usage_categories() + import json + # Save the usage as a json + with open(_os.path.join(directory, path_usage_data), 'w') as f: + json.dump(usage_data, f) + + # Send the data to the developers + # send_data() + + +def send_data(): + # Send the data to the developers using a sfpt server (TODO) + import paramiko + + host = "sftp.upv.es" + port = 22 + + files_to_send = _os.listdir(path_usage_data_folder) + + # create ssh client + ssh_client = paramiko.SSHClient() + + # remote server credentials + host = "hostname" + # username = "username" + # password = "password" + port = port + + ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + ssh_client.connect(hostname=host,port=port) + + # create an SFTP client object + ftp = ssh_client.open_sftp() + + for file in files_to_send: + # send a file from the remote server + ftp.put(path_usage_data_folder + '/' + file, '/home/' + file) + + # Send also the logger file + ftp.put('ex_fuzzy.log', '/home/ex_fuzzy.log') + + # close the connection + ftp.close() + ssh_client.close() + + # Clear the logger file + with open('ex_fuzzy.log', 'w') as f: + f.write('') + + +# Open the usage file from user +file_name = 'usage_data_permission.txt' +directory = _os.path.dirname(_os.path.realpath(__file__)) + +if file_name not in _os.listdir(directory): + # Get input from user + print('exFuzzy:') + print('Do you want to share your usage data with the developers?') + print('This data will be used to improve the library. It will also help us to acquire funding for the project.') + print('If you agree, we will store the number of times you use each functionality in a file called "usage_data.txt".') + print('This file will be stored in the same folder as the library.') + print('If you do not agree, we will not store any data.') + print('If you agree, type "[y]es". If you do not agree, type "no".') + user_input = None + + while user_input not in ['no', 'yes', 'y']: + user_input = input() + + if user_input not in ['no', 'yes', 'y']: + print('Answer not understood, please repeat: If you agree, type "[y]es". If you do not agree, type "no".') + + with open(_os.path.join(directory, file_name), 'w') as f: + f.write(user_input) + +# Read the usage file +with open(_os.path.join(directory, file_name), 'r') as f: + user_input = f.read() + +save_usage_flag = user_input == 'yes' or user_input == 'y' + +if save_usage_flag: + import logging + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + # Create handlers + c_handler = logging.StreamHandler() + f_handler = logging.FileHandler(_os.path.join(directory, 'ex_fuzzy.log')) + c_handler.setLevel(logging.WARNING) + f_handler.setLevel(logging.DEBUG) + # Create formatters and add it to handlers + c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s') + f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + c_handler.setFormatter(c_format) + f_handler.setFormatter(f_format) + # Add handlers to the logger + logger.addHandler(c_handler) + logger.addHandler(f_handler) + + # Create usage reports + + # Create usage data dictionary + usage_data = instance_dict_usage() + + path_usage_data_folder = 'usage_data' + if path_usage_data_folder not in _os.listdir(directory): + _os.mkdir(_os.path.join(directory, path_usage_data_folder)) + + number_files = len(_os.listdir(_os.path.join(directory, path_usage_data_folder))) + + if number_files > 100: + # Avoid a large number of files + while number_files > 100: + _os.remove(_os.path.join(directory, path_usage_data_folder, 'usage_data_' + str(number_files-1) + '.txt')) + number_files = len(_os.listdir(path_usage_data_folder)) + + + atexit.register(save_usage) + + + diff --git a/ex_fuzzy/ex_fuzzy/persistence.py b/ex_fuzzy/ex_fuzzy/persistence.py new file mode 100644 index 0000000..4edfbbb --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/persistence.py @@ -0,0 +1,88 @@ +''' +Load the rules of a fuzzy rules system using plain text format. + +''' +import numpy as np + +try: + from . import fuzzy_sets as fs + from . import rules + from . import maintenance as mnt + +except ImportError: + import fuzzy_sets as fs + import rules + import maintenance as mnt + + +def load_fuzzy_rules(rules_printed: str, fuzzy_variables: list) -> rules.MasterRuleBase: + ''' + Load the rules from a string. + + :param rules_printed: string with the rules. Follows the specification given by the same printing method of rules.MasterRuleBase + :param fuzzy_variables: list with the linguistic variables. Objects of FuzzyVariable class. + + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Persistence]['persistence_read'] += 1 + + consequent = 0 + linguistic_variables_names = [linguistic_variable.name for linguistic_variable in fuzzy_variables] + value_names = [x.name for x in fuzzy_variables[0]] + fz_type = fuzzy_variables[0].fuzzy_type() + consequent_names = [] + for line in rules_printed.splitlines(): + if line.startswith('IF'): + #Is a rule + antecedents , consequent_ds = line.split('WITH') + consequent_ds = consequent_ds.split(',')[0].strip() + init_rule_antecedents = np.zeros( + (len(fuzzy_variables),)) - 1 # -1 is dont care + + for antecedent in antecedents.split('AND'): + antecedent = antecedent.replace('IF', '').strip() + antecedent_name, antecedent_value = antecedent.split('IS') + antecedent_name = antecedent_name.strip() + antecedent_value = antecedent_value.strip() + antecedent_index = linguistic_variables_names.index(antecedent_name) + antecedent_value_index = value_names.index(antecedent_value) + + init_rule_antecedents[antecedent_index] = antecedent_value_index + + rule_simple = rules.RuleSimple(init_rule_antecedents, 0) + rule_simple.score = float(consequent_ds[3:].strip()) # We remove the 'DS ' and the last space + reconstructed_rules.append(rule_simple) + + elif line.startswith('Rules'): + #New consequent + consequent_name = line.split(':')[-1].strip() + consequent_names.append(consequent_name) + if consequent > 0: + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + if consequent == 1: + mrule_base = rules.MasterRuleBase([rule_base]) + elif consequent > 1: + mrule_base.add_rule_base(rule_base) + + reconstructed_rules = [] + consequent += 1 + + # We add the last rule base + if fz_type == fs.FUZZY_SETS.t1: + rule_base = rules.RuleBaseT1(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.t2: + rule_base = rules.RuleBaseT2(fuzzy_variables, reconstructed_rules) + elif fz_type == fs.FUZZY_SETS.gt2: + rule_base = rules.RuleBaseGT2(fuzzy_variables, reconstructed_rules) + + mrule_base.add_rule_base(rule_base) + mrule_base.rename_cons(consequent_names) + + return mrule_base + diff --git a/ex_fuzzy/ex_fuzzy/rule_mining.py b/ex_fuzzy/ex_fuzzy/rule_mining.py new file mode 100644 index 0000000..2ac77e7 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/rule_mining.py @@ -0,0 +1,247 @@ +""" +Module to perform rule mining in a pandas dataframe or numpy array. The methods use the support of the different itemsets to look for good +rule candidates. It can be used then by a Genetic optimizator from evolutionary_fit module to search the optimal combination of them. + +""" +import typing +from itertools import product, combinations + +import pandas as pd +import numpy as np + +try: + from . import rules as rl + from . import fuzzy_sets as fs + from . import maintenance as mnt + from . import utils +except ImportError: + import utils + import rules as rl + import fuzzy_sets as fs + import maintenance as mnt + + +def _generate_combinations(lists: list, k: int) -> typing.Iterator: + ''' + Generate all the combinations between elements of different lists of length k without repeting elements of the same list. + + :param lists: list of lists. + :param k: integer with the length of the combinations. + :return: a list with all the combinations. + ''' + # Get all combinations of elements for k + all_combs = combinations(np.arange(len(lists)), k) + + # For those elements, get the cartesian product between them + for comb in all_combs: + selected_lists = [lists[x] for x in comb] + all_combinations = product(*selected_lists) + + # Add them to the global combination list + yield all_combinations + + +def rule_search(data: pd.DataFrame, fuzzy_variables: dict[fs.fuzzyVariable], support_threshold:float=0.05, max_depth:int=None) -> list: + ''' + Computes the apriori algorithm for the given dataframe and threshold the support. + + :param data: Dataframe of shape: samples x features + :param fuzzy variables: dict that maps each feature name with a fuzzy variable. + :param support_threshold: minimum support to consider frequent an itemset. + :return: all the frequent itemsets as a list. + ''' + n_linguist_variables = len(fuzzy_variables[0]) + list_possible_vars = [] + for ix in range(len(fuzzy_variables)): + list_possible_vars.append([(ix, ax) for ax in range(n_linguist_variables)]) + + memberships = [fuzzy_variables[ix](data.iloc[:, ix].values) for ix in range(data.shape[1])] + freq_itemsets = [] + + if max_depth is None: + max_depth = data.shape[1] + + # For all possible lengths + for r in range(max_depth): + all_r_combs = _generate_combinations(list_possible_vars, r+1) + + # Iterate through the possible itemsets + for itemsets in all_r_combs: + for ix, itemset in enumerate(itemsets): + relevant_memberships = [] + for item in itemset: + item_var, item_vl = item + relevant_memberships.append([memberships[item_var][item_vl]]) + + array_membership = np.array(relevant_memberships).T[:,0,:] + support = np.mean(np.min(array_membership, axis=1)) + if fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.t2 or fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.gt2: + support = np.mean(support, axis=1) + + if support > support_threshold: + freq_itemsets.append(itemset) + + return freq_itemsets + + +def generate_rules_from_itemsets(itemsets:list, nAnts:int) -> list[rl.RuleSimple]: + ''' + Given a list of itemsets, it creates the rules for each one and returns a list of rules containing them. + + :param itemsets: list of tuple (antecedent, linguistic variable value) + :param nAnts: number of possible antecedents. + :return: the rules for ech itemset. + ''' + rules = [] + for itemset in itemsets: + template = np.ones((nAnts, )) * -1 + for ant, vl in itemset: + template[ant] = vl + + rule = rl.RuleSimple(list(template)) + rules.append(rule) + + return rules + + +def mine_rulebase_support(x: pd.DataFrame, fuzzy_variables:list[fs.fuzzyVariable], support_threshold:float=0.05, max_depth:int=3) -> rl.RuleBase: + ''' + Search the data for associations that are frequent given a list of fuzzy variables for each antecedent. + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_variables: list of the fuzzy variables for each of the input variables. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.RuleMining]['mine_rulebase'] += 1 + + freq_itemsets = rule_search(x, fuzzy_variables, support_threshold, max_depth) + rule_list = generate_rules_from_itemsets(freq_itemsets, len(fuzzy_variables)) + + fuzzy_type = fuzzy_variables[0].fs_type + + if fuzzy_type == fs.FUZZY_SETS.t1: + rule_base = rl.RuleBaseT1(fuzzy_variables, rule_list) + elif fuzzy_type == fs.FUZZY_SETS.t2: + rule_base = rl.RuleBaseT2(fuzzy_variables, rule_list) + elif fuzzy_type == fs.FUZZY_SETS.gt2: + rule_base = rl.RuleBaseGT2(fuzzy_variables, rule_list) + + return rule_base + + +def prune_rules_confidence_lift(x: pd.DataFrame, y:np.array, rules: rl.MasterRuleBase, fuzzy_variables: list[fs.fuzzyVariable], confidence_threshold:float=0.5, + lift_threshold:float=1.05): + ''' + Removes the rules from the rule base that do not meet a minimum value for confidence and lift measures. + + Confidence is the ratio of rules that have a particular antecedent and consequent, and those that only have the antecedent. + Lift is ratio between confidence and expected confidence, which is the percentage of class samples in the original data. + + :param x: data to mine. samples x features. + :param y: class vector. + :param rules: MasterRuleBase object with the rules to prune. + :param fuzzy_variables: a list of the fuzzy variables per antecedent. + :param confidence_threshold: minimum confidence required to the rules. + :param lift_threshold: minimum lift required to the rules. + ''' + for ix, rule_base in enumerate(rules): + delete_list = [] + relevant_class = ix + relevant_class_samples = x.loc[np.equal(y, relevant_class), :] + + for jx, rule in enumerate(rule_base): + real_nAnts = sum([ant != -1 for ant in rule]) + global_membership_array = np.zeros((x.shape[0], real_nAnts)) + class_samples_membership_array = np.zeros((relevant_class_samples.shape[0], real_nAnts)) + ant_counter = 0 + for zx, antecedent in enumerate(rule): + if antecedent != -1: + global_membership_array[:, ant_counter] = fuzzy_variables[zx](x[fuzzy_variables[zx].name])[antecedent] + class_samples_membership_array[:, ant_counter] = fuzzy_variables[zx](relevant_class_samples[fuzzy_variables[zx].name])[antecedent] + ant_counter += 1 + + # Compute rule confidence + global_support = np.mean(np.min(global_membership_array, axis=1), axis=0) + class_support = np.mean(np.min(class_samples_membership_array, axis=1), axis=0) + if fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.t2 or fuzzy_variables[0].fuzzy_type == fs.FUZZY_SETS.gt2: + global_support = np.mean(global_support, axis=1) + class_support = np.mean(class_support, axis=1) + + rule_confidence = class_support / global_support + rule_lift = rule_confidence / np.mean(np.equal(relevant_class, y)) + + if rule_confidence < confidence_threshold or rule_lift < lift_threshold: + delete_list.append(jx) + + rule_base.remove_rules(delete_list) + + +def simple_mine_rulebase(x: pd.DataFrame, fuzzy_type:fs.FUZZY_SETS=fs.FUZZY_SETS.t1, support_threshold:float=0.05, max_depth:int=3) -> rl.RuleBase: + ''' + Search the data for associations that are frequent. Computes the fuzzy variables using a 3 label partition (low, medium, high). + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_type: fuzzy type to use. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + + precomputed_partitions = utils.construct_partitions(x, fuzzy_type) + return mine_rulebase_support(x, precomputed_partitions, support_threshold, max_depth) + + +def multiclass_mine_rulebase(x: pd.DataFrame, y: np.array, fuzzy_variables:list[fs.fuzzyVariable], support_threshold:float=0.05, max_depth:int=3, + confidence_threshold:float=0.05, lift_threshold:float=1.05) -> rl.MasterRuleBase: + ''' + Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. Computes a different ruleBase for each + class and then uses them to form a MasterRuleBase. + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_variables: list of the fuzzy variables for each of the input variables. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :param confidence_threshold: minimum confidence value. + :param lift_threshold: + :return: a rulebase object with the rules denoted as good. + ''' + unique_classes = np.unique(y) + rulebases = [] + for yclass in unique_classes: + selected_samples = np.equal(yclass, y) + selected_x = x.loc[selected_samples, :] + + rulebase = mine_rulebase_support(selected_x, fuzzy_variables, support_threshold, max_depth) + rulebases.append(rulebase) + + master_rulebase = rl.MasterRuleBase(rulebases, list(map(str, unique_classes))) + prune_rules_confidence_lift(x, y, master_rulebase, fuzzy_variables, confidence_threshold, lift_threshold) + return master_rulebase + + +def simple_multiclass_mine_rulebase(x: pd.DataFrame, y: np.array, fuzzy_type:fs.FUZZY_SETS, support_threshold:float=0.05, max_depth:int=3, + confidence_threshold:float=0.5, lift_threshold:float=1.1) -> rl.MasterRuleBase: + ''' + Search the data for associations that are frequent and have good confidence/lift values given a list of fuzzy variables for each antecedent. + Computes a different ruleBase for each class and then uses them to form a MasterRuleBase. + + Computes the fuzzy variables using a 3 label partition (low, medium, high). + + :param x: the data to mine. Dims: samples x features. + :param fuzzy_type: fuzzy type to use. + :param support_threshold: minimum threshold to decide if prune or not the rule. + :param max_depth: maximum number of antecedents per rule. + :return: a rulebase object with the rules denoted as good. + ''' + precomputed_partitions = utils.construct_partitions(x, fuzzy_type) + return multiclass_mine_rulebase(x, y, precomputed_partitions, support_threshold, max_depth, + confidence_threshold=confidence_threshold, lift_threshold=lift_threshold) + + + + + diff --git a/ex_fuzzy/ex_fuzzy/rules.py b/ex_fuzzy/ex_fuzzy/rules.py new file mode 100644 index 0000000..b8813ce --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/rules.py @@ -0,0 +1,1083 @@ +# -*- coding: utf-8 -*- +""" +This is a the source file that contains the Rule, RuleBase and MasterRuleBase classes to perform fuzzy inference. + +""" +import abc + +import numpy as np +try: + from . import fuzzy_sets as fs + from . import centroid +except ImportError: + import fuzzy_sets as fs + import centroid + + +class RuleError(Exception): + ''' + Exception raised when a rule is not well defined. + ''' + + def __init__(self, message: str) -> None: + ''' + Constructor of the RuleError class. + + :param message: message of the error. + ''' + super().__init__(message) + +def _myprod(x: np.array, y: np.array) -> np.array: + ''' + Proxy function to change the product operation interface + ''' + return x*y + + +class Rule(): + ''' + Class of Rule designed to work with one single rule. It contains the whole inference functionally in itself. + ''' + + def __init__(self, antecedents: list[fs.FS], consequent: fs.FS) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of fuzzy sets. + :param consequent: fuzzy set. + ''' + self.antecedents = antecedents + self.consequent = consequent + + def membership(self, x: np.array, tnorm=_myprod) -> np.array: + ''' + Computes the membership of one input to the antecedents of the rule. + + :param x: input to compute the membership. + :param tnorm: t-norm to use in the inference process. + ''' + for ix, antecedent in enumerate(self.antecedents): + if ix == 0: + res = antecedent.membership(x) + else: + res = tnorm(res, antecedent.membership(x)) + + return res + + def consequent_centroid(self) -> np.array: + ''' + Returns the centroid of the consequent using a Karnik and Mendel algorithm. + ''' + try: + return self.centroid_consequent + except AttributeError: + consequent_domain = self.consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = self.consequent.membership( + domain_linspace) + + self.centroid_consequent = centroid.compute_centroid_fs( + domain_linspace, consequent_memberships) + + return self.centroid_consequent + + +class RuleSimple(): + ''' + Class designed to represent rules in its simplest form to optimize the computation in a rulebase. + + It indicates the antecedent values using a vector coded in this way: + ith entry: -1 means this variable is not used. 0-N indicates that the variable linguistic used for the ith input is that one. + ''' + + def __init__(self, antecedents: list[int], consequent: int=0) -> None: + ''' + Creates a rule with the given antecedents and consequent. + + :param antecedents: list of integers indicating the linguistic variable used for each input. + :param consequent: integer indicating the linguistic variable used for the consequent. + ''' + self.antecedents = list(map(int, antecedents)) + self.consequent = int(consequent) + + + def __getitem__(self, ix): + ''' + Returns the antecedent value for the given index. + + :param ix: index of the antecedent to return. + ''' + return self.antecedents[ix] + + + def __setitem__(self, ix, value): + ''' + Sets the antecedent value for the given index. + + :param ix: index of the antecedent to set. + :param value: value to set. + ''' + self.antecedents[ix] = value + + + def __str__(self): + ''' + Returns a string representation of the rule. + ''' + return 'Rule: antecedents: ' + str(self.antecedents) + ' consequent: ' + str(self.consequent) + + + def __len__(self): + ''' + Returns the number of antecedents in the rule. + ''' + return len(self.antecedents) + + + def __eq__(self, other): + ''' + Returns True if the two rules are equal. + ''' + return self.antecedents == other.antecedents and self.consequent == other.consequent + + + def __hash__(self): + ''' + Returns the hash of the rule. + ''' + return hash(str(self)) + + +class RuleBase(): + ''' + Class optimized to work with multiple rules at the same time. Right now supports only one consequent. (Solution: use one rulebase per consequent to study) + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=np.prod) -> None: + ''' + Creates a rulebase with the given antecedents, rules and consequent. + + :param antecedents: list of fuzzy sets. + :param rules: list of rules. + :param consequent: fuzzy set. + :param tnorm: t-norm to use in the inference process. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership(domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + self.delete_duplicates() + + + def get_rules(self) -> list[RuleSimple]: + ''' + Returns the list of rules in the rulebase. + ''' + return self.rules + + + def add_rule(self, new_rule: RuleSimple): + ''' + Adds a new rule to the rulebase. + :param new_rule: rule to add. + ''' + self.rules.append(new_rule) + + + def add_rules(self, new_rules: list[RuleSimple]): + ''' + Adds a list of new rules to the rulebase. + + :param new_rules: list of rules to add. + ''' + self.rules += new_rules + + + def remove_rule(self, ix: int) -> None: + ''' + Removes the rule in the given index. + :param ix: index of the rule to remove. + ''' + del self.rules[ix] + + + def remove_rules(self, delete_list: list[int]) -> None: + ''' + Removes the rules in the given list of indexes. + + :param delete_list: list of indexes of the rules to remove. + ''' + self.rules = [rule for ix, rule in enumerate( + self.rules) if ix not in delete_list] + + + def get_rulebase_matrix(self): + ''' + Returns a matrix with the antecedents values for each rule. + ''' + res = np.zeros((len(self.rules), len(self.antecedents))) + + for ix, rule in enumerate(self.rules): + res[ix] = rule + + return res + + + def get_scores(self): + ''' + Returns an array with the dominance score for each rule. + (Must been already computed by an evalRule object) + + ''' + res = np.zeros((len(self.rules, ))) + for ix, rule in enumerate(self.rules): + res[ix] = rule.score + + return res + + + def delete_rule_duplicates(self, list_rules:list[RuleSimple]): + # Delete the rules that are duplicated in the rule list + unique = {} + for ix, rule in enumerate(list_rules): + try: + unique[rule] + except KeyError: + unique[rule] = ix + + new_list = [list_rules[x] for x in unique.values()] + + return new_list + + + + def compute_antecedents_memberships(self, x: np.array) -> list[dict]: + ''' + Returns a list of of dictionaries that contains the memberships for each x value to the ith antecedents, nth linguistic variable. + x must be a vector (only one sample) + + :param x: vector with the values of the inputs. + ''' + if len(self.rules) > 0: + cache_antecedent_memberships = [] + + for ix, antecedent in enumerate(self.antecedents): + cache_antecedent_memberships.append( + antecedent.compute_memberships(x[:, ix])) + + return cache_antecedent_memberships + + else: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + return [np.zeros((x.shape[0], 1))] + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + return [np.zeros((x.shape[0], 1, 2))] + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + return [np.zeros((x.shape[0], len(self.alpha_cuts), 2))] + + + def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the antecedent truth value of an input array. + + Return an array in shape samples x rules (x 2) (last is iv dimension) + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled according to their sums for each sample. + :return: array with the memberships of the antecedents for each rule. + ''' + if self.fuzzy_type() == fs.FUZZY_SETS.t2: + res = np.zeros((x.shape[0], len(self.rules), 2)) + elif self.fuzzy_type() == fs.FUZZY_SETS.t1: + res = np.zeros((x.shape[0], len(self.rules), )) + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + res = np.zeros( + (x.shape[0], len(self.rules), len(self.alpha_cuts), 2)) + + antecedents_memberships = self.compute_antecedents_memberships(x) + + for jx, rule in enumerate(self.rules): + rule_antecedents = rule.antecedents + initiated = False + for ix, vl in enumerate(rule_antecedents): + if vl >= 0: + if not initiated: + membership = list(antecedents_memberships[ix])[vl] + initiated = True + else: + membership = self.tnorm(membership, list( + antecedents_memberships[ix])[vl]) + + try: + res[:, jx] = membership + except UnboundLocalError: + pass # All the antecedents are dont care. + + if scaled: + if self.fuzzy_type() == fs.FUZZY_SETS.t1: + non_zero_rows = np.sum(res, axis=1) > 0 + res[non_zero_rows] = res[non_zero_rows] / \ + np.sum(res[non_zero_rows], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.t2: + non_zero_rows = np.sum(res[:, :, 0], axis=1) > 0 + res[non_zero_rows, :, 0] = res[non_zero_rows, :, 0] / \ + np.sum(res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(res[:, :, 1], axis=1) > 0 + res[non_zero_rows, :, 1] = res[non_zero_rows, :, 1] / \ + np.sum(res[non_zero_rows, :, 1], axis=1, keepdims=True) + + elif self.fuzzy_type() == fs.FUZZY_SETS.gt2: + + for ix, alpha in enumerate(self.alpha_cuts): + relevant_res = res[:, :, ix, :] + + non_zero_rows = np.sum(relevant_res[:, :, 0], axis=1) > 0 + relevant_res[non_zero_rows, :, 0] = relevant_res[non_zero_rows, :, 0] / \ + np.sum(relevant_res[non_zero_rows, :, 0], axis=1, keepdims=True) + non_zero_rows = np.sum(relevant_res[:, :, 1], axis=1) > 0 + relevant_res[non_zero_rows, :, 1] = relevant_res[non_zero_rows, :, 1] / \ + np.sum(relevant_res[non_zero_rows, :, 1], axis=1, keepdims=True) + + res[:, :, ix, :] = relevant_res + + return res + + + def print_rules(self, return_rules:bool=False) -> None: + ''' + Print the rules from the rule base. + ''' + all_rules = '' + for ix, rule in enumerate(self.rules): + initiated = False + str_rule = 'IF ' + for jx, vl_ix in enumerate(rule.antecedents): + antecedent = self.antecedents[jx] + keys = antecedent.linguistic_variable_names() + + if rule[jx] != -1: + if not initiated: + str_rule += str(antecedent.name) + ' IS ' + str(keys[vl_ix]) + initiated = True + else: + str_rule += ' AND ' + str(antecedent.name) + \ + ' IS ' + str(keys[vl_ix]) + + try: + score = rule.score if self.fuzzy_type() == fs.FUZZY_SETS.t1 else np.mean(rule.score) + str_rule += ' WITH DS ' + str(score) + + # If the classification scores have been computed, print them. + try: + str_rule += ', ACC ' + str(rule.accuracy) + + except AttributeError: + pass + except AttributeError: + str_rule += ' THEN consequent vl is ' + str(rule.consequent) + + all_rules += str_rule + '\n' + + if not return_rules: + print(all_rules) + else: + return all_rules + + + @abc.abstractmethod + def inference(self, x: np.array) -> np.array: + ''' + Computes the fuzzy output of the fl inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each rule. + ''' + raise NotImplementedError + + + @abc.abstractmethod + def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the fl inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output. + ''' + raise NotImplementedError + + + @abc.abstractmethod + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the corresponding type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the type of fuzzy set used in the RuleBase. + ''' + raise NotImplementedError + + + def __len__(self): + ''' + Returns the number of rules in the rule base. + ''' + return len(self.rules) + + + def prune_bad_rules(self, tolerance=0.01) -> None: + ''' + Delete the rules from the rule base that do not have a dominance score superior to the threshold or have 0 accuracy in the training set. + + :param tolerance: threshold for the dominance score. + ''' + delete_list = [] + try: + for ix, rule in enumerate(self.rules): + score = rule.score + if (self.fuzzy_type() == fs.FUZZY_SETS.t2) or (self.fuzzy_type() == fs.FUZZY_SETS.gt2): + score = np.mean(score) + + if score < tolerance or rule.accuracy == 0.0: + delete_list.append(ix) + except AttributeError: + assert False, 'Dominance scores not computed for this rulebase' + + self.remove_rules(delete_list) + + + def scores(self) -> np.array: + ''' + Returns the dominance score for each rule. + + :return: array with the dominance score for each rule. + ''' + scores = [] + for rule in self.rules: + scores.append(rule.score) + + return np.array(scores) + + + def __getitem__(self, item: int) -> RuleSimple: + ''' + Returns the corresponding rulebase. + + :param item: index of the rule. + :return: the corresponding rule. + ''' + return self.rules[item] + + + def __setitem__(self, key: int, value: RuleSimple) -> None: + ''' + Set the corresponding rule. + + :param key: index of the rule. + :param value: new rule. + ''' + self.rules[key] = value + + + def __iter__(self): + ''' + Returns an iterator for the rule base. + ''' + return iter(self.rules) + + + def __str__(self): + ''' + Returns a string with the rules in the rule base. + ''' + str_res = '' + for rule in self.rules: + str_res += str(rule) + '\n' + return str_res + + + def __eq__(self, other): + ''' + Returns True if the two rule bases are equal. + ''' + return self.rules == other.rules + + + def __hash__(self): + ''' + Returns the hash of the rule base. + ''' + return hash(str(self)) + + + def __add__(self, other): + ''' + Adds two rule bases. + ''' + return RuleBase(self.antecedents, self.rules + other.rules, self.consequent, self.tnorm) + + + def n_linguist_variables(self) -> int: + ''' + Returns the number of linguistic variables in the rule base. + ''' + return len(self.antecedents) + + +class RuleBaseT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports iv approximation for t2 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), 2)) + + for ix, vl_consequent in enumerate(consequent.linguistic_variables): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix, :] = centroid.compute_centroid_iv( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), 2)) + # If 0, we are classifying and we do not need the consequent centroids. + if len(self.consequent_centroids) > 0: + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + + def inference(self, x: np.array) -> np.array: + ''' + Computes the iv output of the t2 inference system. + + Return an array in shape samples x 2 (last is iv dimension) + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res + + + def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.mean(self.inference(x)) + + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t2 + + +class RuleBaseGT2(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports gt2 fs. (ONLY FOR CLASSIFICATION PROBLEMS) + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseGT2 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + self.alpha_cuts = antecedents[0][0].alpha_cuts + + + def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the gt2 inference system. + + Return an array in shape samples x alpha_cuts + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.consequent_centroid( + antecedent_memberships[sample], self.consequent_centroids_rules) + + return res + + + def _alpha_reduction(self, x) -> np.array: + ''' + Computes the type reduction to reduce the alpha cuts to one value. + + :param x: array with the values of the inputs. + :return: array with the memberships of the consequents for each sample. + ''' + formtatted = np.expand_dims(np.expand_dims(np.expand_dims( + np.array(self.alpha_cuts), axis=1), axis=0), axis=0) + return np.sum(formtatted * x, axis=2) / np.sum(self.alpha_cuts) + + + def forward(self, x: np.array) -> np.array: + ''' + Computes the deffuzified output of the t2 inference system. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return np.sum(np.array(self.alpha_cuts) * (self.inference(x)), axis=1) / np.sum(self.alpha_cuts) + + + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.gt2 + + + def compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents performing the alpha_cut reduction. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + ''' + antecedent_membership = super().compute_rule_antecedent_memberships(x, scaled) + return self._alpha_reduction(antecedent_membership) + + + def alpha_compute_rule_antecedent_memberships(self, x: np.array, scaled=True) -> np.array: + ''' + Computes the membership for the antecedents for all the alpha cuts. + + :param x: array with the values of the inputs. + :param scaled: if True, the memberships are scaled to sum 1 in each sample. + :return: array with the memberships of the antecedents for each sample. + ''' + return super().compute_rule_antecedent_memberships(x, scaled) + + +class RuleBaseT1(RuleBase): + ''' + Class optimized to work with multiple rules at the same time. Supports only one consequent. + (Use one rulebase per consequent to study classification problems. Check MasterRuleBase class for more documentation) + + This class supports t1 fs. + ''' + + def __init__(self, antecedents: list[fs.fuzzyVariable], rules: list[RuleSimple], consequent: fs.fuzzyVariable = None, tnorm=_myprod) -> None: + ''' + Constructor of the RuleBaseT1 class. + + :param antecedents: list of fuzzy variables that are the antecedents of the rules. + :param rules: list of rules. + :param consequent: fuzzy variable that is the consequent of the rules. ONLY on regression problems. + :param tnorm: t-norm used to compute the fuzzy output. + ''' + rules = self.delete_rule_duplicates(rules) + self.rules = rules + self.antecedents = antecedents + self.consequent = consequent + self.tnorm = tnorm + + if consequent is not None: + self.consequent_centroids = np.zeros( + (len(consequent.linguistic_variable_names()), )) + + for ix, (name, vl_consequent) in enumerate(consequent.linguistic_variables.items()): + consequent_domain = vl_consequent.domain + domain_linspace = np.arange( + consequent_domain[0], consequent_domain[1], 0.05) + consequent_memberships = vl_consequent.membership( + domain_linspace) + + self.consequent_centroids[ix] = centroid.center_of_masses( + domain_linspace, consequent_memberships) + + self.consequent_centroids_rules = np.zeros((len(self.rules), )) + for ix, rule in enumerate(self.rules): + consequent_ix = rule.consequent + self.consequent_centroids_rules[ix] = self.consequent_centroids[consequent_ix] + + + def inference(self, x: np.array) -> np.array: + ''' + Computes the output of the t1 inference system. + + Return an array in shape samples. + + :param x: array with the values of the inputs. + :return: array with the output of the inference system for each sample. + ''' + res = np.zeros((x.shape[0], 2)) + + antecedent_memberships = self.compute_rule_antecedent_memberships(x) + + for sample in range(antecedent_memberships.shape[0]): + res[sample, :] = centroid.center_of_masses( + self.consequent_centroids_rules, antecedent_memberships[sample]) + + return res + + def forward(self, x: np.array) -> np.array: + ''' + Same as inference() in the t1 case. + + Return a vector of size (samples, ) + + :param x: array with the values of the inputs. + :return: array with the deffuzified output for each sample. + ''' + return self.inference(x) + + + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return fs.FUZZY_SETS.t1 + + +class MasterRuleBase(): + ''' + This Class encompasses a list of rule bases where each one corresponds to a different class. + ''' + + def __init__(self, rule_base: list[RuleBase], consequent_names: list[str]=None) -> None: + ''' + Constructor of the MasterRuleBase class. + + :param rule_base: list of rule bases. + ''' + if len(rule_base) == 0: + raise RuleError('No rule bases given!') + + self.rule_bases = rule_base + self.antecedents = rule_base[0].antecedents + + if consequent_names is None: + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))] + else: + self.consequent_names = consequent_names + + + def rename_cons(self, consequent_names: list[str]) -> None: + ''' + Renames the consequents of the rule base. + ''' + self.consequent_names = consequent_names + + + def add_rule(self, rule: RuleSimple, consequent: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + ''' + self.rule_bases[consequent].add_rule(rule) + + + def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([[ix]*len(x) for ix, x in enumerate(self.rule_bases)], []) + + + def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [x.get_rulebase_matrix() for x in self.rule_bases] + + + def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rb in self.rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0) + + + def compute_firing_strenghts(self, X) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + for ix in range(len(self.rule_bases)): + aux.append(self[ix].compute_rule_antecedent_memberships(X)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1) + + + def _winning_rules(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + + firing_strengths = self.compute_firing_strenghts(X) + + association_degrees = self.get_scores() * firing_strengths + + if (self[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + association_degrees = np.mean(association_degrees, axis=2) + elif self[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(association_degrees, axis=3) + + winning_rules = np.argmax(association_degrees, axis=1) + + return winning_rules + + + def winning_rule_predict(self, X: np.array) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = sum([[ix]*len(self[ix].rules) + for ix in range(len(self.rule_bases))], []) # The sum is for flatenning the list + winning_rules = self._winning_rules(X) + + return np.array([consequents[ix] for ix in winning_rules]) + + + def add_rule_base(self, rule_base: RuleBase) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.rule_bases.append(rule_base) + + if len(self.rule_bases) != len(self.consequent_names): + # We did not give proper names to the consequents + self.consequent_names = [str(ix) for ix in range(len(self.rule_bases))] + + + def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + + :param autoprint: if True, the rules are printed. If False, the rules are returned as a string. + ''' + res = '' + for ix, ruleBase in enumerate(self.rule_bases): + res += 'Rules for consequent: ' + str(self.consequent_names[ix]) + '\n' + + res += '----------------\n' + res += ruleBase.print_rules(return_rules=True) + '\n' + + + if return_rules: + return res + else: + print(res) + + + def get_rules(self) -> list[RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for ruleBase in self.rule_bases for rule in ruleBase.rules] + + + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.rule_bases[0].fuzzy_type() + + + def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for ruleBase in self.rule_bases: + ruleBase.prune_bad_rules(tolerance) + + + def __getitem__(self, item) -> RuleBase: + ''' + Returns the corresponding rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.rule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.rule_bases) + + + def __str__(self) -> str: + ''' + Returns a string with the rules for each consequent. + ''' + return self.print_rules(return_rules=True) + + + def __eq__(self, __value: object) -> bool: + ''' + Returns True if the two rule bases are equal. + + :param __value: object to compare. + :return: True if the two rule bases are equal. + ''' + if not isinstance(__value, MasterRuleBase): + return False + else: + return self.rule_bases == __value.rule_bases + + + def __call__(self, X: np.array) -> np.array: + ''' + Gives the prediction for each sample (same as winning_rule_predict) + + :param X: array of dims: samples x features. + :return: vector of predictions, size: samples, + ''' + return self.winning_rule_predict(X) + + + def get_rulebases(self) -> list[RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + return self.rule_bases + + + def n_linguist_variables(self) -> int: + ''' + Returns the number of linguistic variables in the rule base. + ''' + return len(self.antecedents[0]) + + + def get_antecedents(self) -> list[fs.fuzzyVariable]: + ''' + Returns the antecedents of the rule base. + ''' + return self.antecedents + + +def list_rules_to_matrix(rule_list: list[RuleSimple]) -> np.array: + ''' + Returns a matrix out of the rule list. + + :param rule_list: list of rules. + :return: matrix with the antecedents of the rules. + ''' + assert len(rule_list) > 0, 'No rules to list!' + + res = np.zeros((len(rule_list), len(rule_list[0].antecedents))) + for ix, rule in enumerate(rule_list): + res[ix, :] = rule.antecedents + + return res + diff --git a/ex_fuzzy/ex_fuzzy/temporal.py b/ex_fuzzy/ex_fuzzy/temporal.py new file mode 100644 index 0000000..f68f24c --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/temporal.py @@ -0,0 +1,682 @@ +''' +Expansion of the base fuzzy sets, adding temporal fuzzy sets. + +Contains functions to model the temporal fuzzy sets, temporal fuzzy variables and temporal rule bases. +It also contains functions to evaluate the fuzzy rulebases obtained. + +''' +import enum + +import numpy as np +import pandas as pd + +from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, confusion_matrix, matthews_corrcoef +from pymoo.algorithms.soo.nonconvex.ga import GA +from pymoo.core.problem import Problem +from pymoo.optimize import minimize +from pymoo.operators.sampling.rnd import IntegerRandomSampling +from pymoo.operators.crossover.sbx import SBX +from pymoo.operators.mutation.pm import PolynomialMutation +from pymoo.core.variable import Integer +from multiprocessing.pool import ThreadPool +from pymoo.core.problem import StarmapParallelization + +try: + from . import fuzzy_sets as fs + from . import maintenance as mnt + from . import rules as rl + from . import evolutionary_fit as evf + from . import vis_rules + from . import eval_rules as evr +except: + import fuzzy_sets as fs + import maintenance as mnt + import rules as rl + import evolutionary_fit as evf + import vis_rules + import eval_rules as evr + + +TMP_FUZZY_SETS = enum.Enum( + "NEW_FUZZY_SETS", + ['temporal', 'temporal_t2', 'temporal_gt2'] +) +NEW_FUZZY_SETS = enum.Enum( + "FUZZY_SETS", + [(es.name, es.value) for es in fs.FUZZY_SETS] + [(es.name, es.name) for es in TMP_FUZZY_SETS] +) + +fs.FUZZY_SETS = NEW_FUZZY_SETS +### DEFINE THE FUZZY SET #### +class temporalFS(fs.FS): + ''' + Class to implement temporal fuzzy sets. + ''' + + def __init__(self, std_fuzzy_set: fs.FS, conditional_variable: np.array) -> None: + ''' + Creates a temporal fuzzy set. + + :param std_fuzzy_set: FS. Standard fuzzy set that contains the non-temporal aware memberhsip function. + :param conditional_variable: np.array. The variable that expresses the different temporal moments. Shape (time discrete moments, ). + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.FuzzySets][self.type().name] += 1 + + self.std_set = std_fuzzy_set + self.tmp_function = conditional_variable + self.time = None + self.name = std_fuzzy_set.name + + if std_fuzzy_set.type() == fs.FUZZY_SETS.t1: + self.membership_parameters = std_fuzzy_set.membership_parameters + elif std_fuzzy_set.type() == fs.FUZZY_SETS.t2: + self.secondMF_upper = std_fuzzy_set.secondMF_upper + self.secondMF_lower = std_fuzzy_set.secondMF_lower + elif std_fuzzy_set.type() == fs.FUZZY_SETS.gt2: + self.secondary_memberships = std_fuzzy_set.secondary_memberships + self.alpha_cuts = std_fuzzy_set.alpha_cuts + + + def membership(self, input: np.array, time: int=None) -> np.array: + ''' + Computes the membership of each sample and in each time for the fs. + + :param input: array temporal_time x samples. + :time: int. Time moment to compute the membership. If none, looks for a fixed time + :return: array temporal_time x samples. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy set has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + return self.std_set.membership(input) * self.tmp_function[time] + + + def type(self) -> fs.FUZZY_SETS: + ''' + Returns the type of the fuzzy set. (temporal) + ''' + return fs.FUZZY_SETS.temporal + + + def inside_type(self) -> fs.FUZZY_SETS: + ''' + Returns the type of the og fuzzy set computed before the time dependency. + ''' + return self.std_set.type() + + + def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy set. + + :param time: int. Time moment to fix. + :return: FS. Fuzzy set with the fixed time. + ''' + self.time = time + + + +#### DEFINE THE FUZZY VARIABLE #### +class temporalFuzzyVariable(fs.fuzzyVariable): + ''' + Class to implement a temporal fuzzy variable. + ''' + + def __init__(self, name: str, fuzzy_sets: list[temporalFS]) -> None: + ''' + Creates a temporal fuzzy variable. + + :param str: name of the variable. + :param fuzzy_sets: list of the fuzzy sets pre-time dependencies. + ''' + self.linguistic_variables = [] + self.name = name + self.time = None + for ix, fs in enumerate(fuzzy_sets): + self.linguistic_variables.append(fs) + + self.fs_type = self.linguistic_variables[0].type() + + + def fix_time(self, time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variable. + + :param time: int. Time moment to fix. + ''' + self.time = time + + + def compute_memberships(self, x: np.array, time: int=None) -> dict: + ''' + Computes the membership to each of the FS in the fuzzy variables. + + :param x: numeric value or array. Computes the membership to each of the IVFS in the fuzzy variables. + :param time: int. Time moment to compute the membership. + :return: list of floats. Membership to each of the FS in the fuzzy variables. + ''' + if time is None: + assert self.time is not None, 'Temporal fuzzy variable has no fixed time. Please, fix a time or provide a time to compute the membership.' + time = self.time + + res = [] + + for fuzzy_set in self.linguistic_variables: + res.append(fuzzy_set.membership(x, time)) + + return res + + + def n_time_moments(self) -> int: + ''' + Returns the number of time moments of the temporal fuzzy variable. + + :return: int. Number of time moments of the temporal fuzzy variable. + ''' + return self.linguistic_variables[0].tmp_function.shape[0] + + +#### DEFINE THE RULE BASE WITH TEMPORAL DEPENDENCIES #### +class temporalMasterRuleBase(rl.MasterRuleBase): + ''' + This class is a temporal extension of the MasterRuleBase class. It includes a list of + rule bases for each time step. + ''' + def __init__(self, rule_base: list[rl.MasterRuleBase], time_step_names: list[str]=None): + ''' + Constructor of the temporalMasterRuleBase class. + + :param rule_base: list of rule bases. + :param time_steps: number of time steps. + ''' + super().__init__(rule_base) + self.time_steps = np.arange(len(rule_base)) + self.time_mrule_bases = rule_base + + if time_step_names is None: + self.time_step_names = [str(x) for x in self.time_steps] + else: + self.time_step_names = time_step_names + + for ix, mrb in enumerate(rule_base): + for jx, rb in enumerate(mrb): + for antecedent in rb.antecedents: + antecedent.fix_time(ix) + + self.antecedents = rule_base[0].antecedents + + + def add_rule(self, rule: rl.RuleSimple, consequent: int, time_step: int) -> None: + ''' + Adds a rule to the rule base of the given consequent. + + :param rule: rule to add. + :param consequent: index of the rule base to add the rule. + :param time_step: time step of the rule base to add the rule. + ''' + self.time_mrule_bases[time_step][consequent].add_rule(rule) + + + def get_rulebase_matrix(self) -> list[np.array]: + ''' + Returns a list with the rulebases for each antecedent in matrix format. + + :return: list with the rulebases for each antecedent in matrix format. + ''' + return [a.get_rulebase_matrix() for x in self.time_mrule_bases for a in x] + + + def get_scores(self) -> np.array: + ''' + Returns the dominance score for each rule in all the rulebases. + + :return: array with the dominance score for each rule in all the rulebases. + ''' + res = [] + for rule_bases in self.time_mrule_bases: + for rb in rule_bases: + res.append(rb.scores()) + + res = [x for x in res if len(x) > 0] + + return np.concatenate(res, axis=0) + + + def compute_firing_strenghts(self, X: np.array, time_moments: list[int]) -> np.array: + ''' + Computes the firing strength of each rule for each sample. + + :param X: array with the values of the inputs. + :return: array with the firing strength of each rule for each sample. + ''' + aux = [] + time_moments = np.array(time_moments) + + for time_moment, rule_bases in enumerate(self.time_mrule_bases): + actual_moment = np.equal(time_moments, time_moment) + for ix in range(len(rule_bases)): + if rule_bases.fuzzy_type() == fs.FUZZY_SETS.t2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + elif rule_bases.fuzzy_type() == fs.FUZZY_SETS.gt2: + aux.append(np.mean(rule_bases[ix].compute_rule_antecedent_memberships(X), axis=2) * np.expand_dims(actual_moment, axis=1)) + else: + aux.append(rule_bases[ix].compute_rule_antecedent_memberships(X) * np.expand_dims(actual_moment, axis=1)) + + # Firing strengths shape: samples x rules + return np.concatenate(aux, axis=1) + + + def winning_rule_predict(self, X: np.array, time_moments: int) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + consequents = [] + for ix, mrb in enumerate(self.time_mrule_bases): + for jx, rb in enumerate(mrb): + for rule in rb: + consequents.append(jx) + + # consequents = sum([[ix]*len(self[ix].get_rules()) + # for ix in range(len(self.rule_bases))], []) # The sum is for flatenning + firing_strengths = self.compute_firing_strenghts(X, time_moments) + + if self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.t2 or self.time_mrule_bases[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(self.get_scores(), axis=1) * firing_strengths + else: + association_degrees = self.get_scores() * firing_strengths + + + winning_rules = np.argmax(association_degrees, axis=1) + + return np.array([consequents[ix] for ix in winning_rules]) + + + def add_rule_base(self, rule_base: rl.RuleBase, time: int) -> None: + ''' + Adds a rule base to the list of rule bases. + + :param rule_base: rule base to add. + ''' + self.time_mrule_bases[time].add_rule_base(rule_base) + + + def print_rules(self, return_rules=False) -> None: + ''' + Print all the rules for all the consequents. + ''' + res = '' + for zx, time in enumerate(self.time_mrule_bases): + res += 'Rules for time step: ' + self.time_step_names[zx] + '\n' + res += '----------------\n' + for ix, ruleBase in enumerate(time): + res += 'Consequent: ' + time.consequent_names[ix] + '\n' + res += ruleBase.print_rules(True) + res += '\n' + res += '----------------\n' + + if return_rules: + return res + else: + print(res) + + + def get_rules(self) -> list[rl.RuleSimple]: + ''' + Returns a list with all the rules. + + :return: list with all the rules. + ''' + return [rule for mruleBase in self.rule_bases for rule in mruleBase.get_rules()] + + + def fuzzy_type(self) -> fs.FUZZY_SETS: + ''' + Returns the correspoing type of the RuleBase using the enum type in the fuzzy_sets module. + + :return: the corresponding fuzzy set type of the RuleBase. + ''' + return self.time_mrule_bases[0].rule_bases[0].fuzzy_type() + + + def purge_rules(self, tolerance=0.001) -> None: + ''' + Delete the roles with a dominance score lower than the tolerance. + + :param tolerance: tolerance to delete the rules. + ''' + for mruleBase in self.time_mrule_bases: + mruleBase.purge_rules(tolerance) + + + def __getitem__(self, item: int) -> rl.RuleBase: + ''' + Returns the corresponding time rulebase. + + :param item: index of the rulebase. + :return: the corresponding rulebase. + ''' + return self.time_mrule_bases[item] + + + def __len__(self) -> int: + ''' + Returns the number of rule bases. + ''' + return len(self.time_mrule_bases) + + + def get_consequents(self) -> list[int]: + ''' + Returns a list with the consequents of each rule base. + + :return: list with the consequents of each rule base. + ''' + return sum([x.get_consequents() for ix, x in enumerate(self.time_mrule_bases)], []) + + + def get_rulebases(self) -> list[rl.RuleBase]: + ''' + Returns a list with all the rules. + + :return: list + ''' + rule_bases = [] + + for ruleBase in self.time_mrule_bases: + for rule in ruleBase: + rule_bases.append(rule) + + return rule_bases + + + def _winning_rules(self, X: np.array, temporal_moments: list[int]) -> np.array: + ''' + Returns the winning rule for each sample. Takes into account dominance scores if already computed. + + :param X: array with the values of the inputs. + :return: array with the winning rule for each sample. + ''' + + firing_strengths = self.compute_firing_strenghts(X, temporal_moments) + + association_degrees = self.get_scores() * firing_strengths + + if (self[0].fuzzy_type() == fs.FUZZY_SETS.t2) or (self[0].fuzzy_type() == fs.FUZZY_SETS.gt2): + association_degrees = np.mean(association_degrees, axis=2) + elif self[0].fuzzy_type() == fs.FUZZY_SETS.gt2: + association_degrees = np.mean(association_degrees, axis=3) + + winning_rules = np.argmax(association_degrees, axis=1) + + return winning_rules + + +#### DEFINE THE FUZZY CLASSIFIER USING TEMPORAL FUZZY SETS #### +class TemporalFuzzyRulesClassifier(evf.BaseFuzzyRulesClassifier): + ''' + Class that is used as a classifier for a fuzzy rule based system with time dependencies. Supports precomputed and optimization of the linguistic variables. + ''' + + def __init__(self, nRules: int = 30, nAnts: int = 4, fuzzy_type: fs.FUZZY_SETS = None, tolerance: float = 0.0, + n_linguist_variables: int = 0, verbose=False, linguistic_variables: list[fs.fuzzyVariable] = None, + domain: list[float] = None, n_class: int=None, precomputed_rules: rl.MasterRuleBase =None, runner: int=1) -> None: + ''' + Inits the optimizer with the corresponding parameters. + + :param nRules: number of rules to optimize. + :param nAnts: max number of antecedents to use. + :param fuzzy type: FUZZY_SET enum type in fuzzy_sets module. The kind of fuzzy set used. + :param tolerance: tolerance for the dominance score of the rules. + :param n_linguist_variables: number of linguistic variables per antecedent. + :param verbose: if True, prints the progress of the optimization. + :param linguistic_variables: list of fuzzyVariables type. If None (default) the optimization process will init+optimize them. + :param domain: list of the limits for each variable. If None (default) the classifier will compute them empirically. + + kwargs: + - n_classes: number of classes to predict. Default deduces from data. + ''' + super().__init__(nRules, nAnts, fuzzy_type, tolerance, n_linguist_variables, verbose, linguistic_variables, domain, n_class) + + + def _contruct_tempRuleBase(self, problems, best_individuals): + ruleBase_temp = [] + + for problem, subject in zip(problems, best_individuals): + ruleBase_time_moment = problem._construct_ruleBase(subject, + self.fuzzy_type) + ruleBase_temp.append(ruleBase_time_moment) + + return ruleBase_temp + + + def _fix_time(self, lvs: list[temporalFuzzyVariable], time: int) -> None: + ''' + Fixes the time of the temporal fuzzy variables. + + :param lvs: list of temporal fuzzy variables. + :param time: integer. Time moment to fix. + :return: None. The time is fixed. + ''' + for lv in lvs: + lv.fix_time(time) + + + def fit(self, X: np.array, y: np.array, n_gen:int=50, pop_size:int=10, time_moments: np.array=None, checkpoints:int=10): + ''' + Fits a fuzzy rule based classifier using a genetic algorithm to the given data. + + :param X: numpy array samples x features + :param y: labels. integer array samples (x 1) + :param n_gen: integer. Number of generations to run the genetic algorithm. + :param pop_size: integer. Population size for each gneration. + :param time_moments: array of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: None. The classifier is fitted to the data. + ''' + problems = [] + for ix in range(len(np.unique(time_moments))): + X_problem = X[time_moments == ix] + y_problem = y[time_moments == ix] + time_moments_problem = time_moments[time_moments == ix] + + if self.lvs is None: + # If Fuzzy variables need to be optimized. + problem = evf.FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, tolerance=self.tolerance, + n_linguist_variables=self.n_linguist_variables, fuzzy_type=self.fuzzy_type, domain=self.domain, time_moments=time_moments_problem, + n_classes=self.n_class, thread_runner=self.thread_runner) + else: + import copy + time_lvs = [copy.deepcopy(aux) for aux in self.lvs] + self._fix_time(time_lvs, ix) + # If Fuzzy variables are already precomputed. + problem = evf.FitRuleBase(X_problem, y_problem, nRules=self.nRules, nAnts=self.nAnts, + linguist_variables=time_lvs, domain=self.domain, tolerance=self.tolerance, time_moments=time_moments_problem, + n_classes=self.classes_, thread_runner=self.thread_runner) + + problems.append(problem) + + + + best_individuals = [] + self.performance = {} + for time, problem in enumerate(problems): + algorithm = GA( + pop_size=pop_size, + sampling=IntegerRandomSampling(), + crossover=SBX(prob=.3, eta=3.0), + mutation=PolynomialMutation(eta=7.0), + eliminate_duplicates=True) + + if checkpoints > 0: + if self.verbose: + print('=================================================') + print('n_gen | n_eval | f_avg | f_min ') + print('=================================================') + algorithm.setup(problem, seed=33, termination=('n_gen', n_gen)) # 33? Soon... + for k in range(n_gen): + algorithm.next() + res = algorithm + if self.verbose: + print('%-6s | %-8s | %-8s | %-8s' % (res.n_gen, res.evaluator.n_eval, round(res.pop.get('F').mean(), 8), round(res.pop.get('F').min(), 8))) + if k % checkpoints == 0: + with open("checkpoint_" + str(time) + '_' + str(algorithm.n_gen), "w") as f: + pop = algorithm.pop + fitness_last_gen = pop.get('F') + best_solution_arg = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution_arg, :] + + rule_base = problem._construct_ruleBase( + best_individual, self.fuzzy_type) + eval_performance = evr.evalRuleBase( + rule_base, np.array(X), y) + + eval_performance.add_full_evaluation() + # self.rename_fuzzy_variables() This wont work on checkpoints! + rule_base.purge_rules(self.tolerance) + checkpoint_rules = rule_base.print_rules(True) + f.write(checkpoint_rules) + + else: + res = minimize(problem, + algorithm, + # termination, + ("n_gen", n_gen), + copy_algorithm=False, + save_history=False, + verbose=self.verbose) + + pop = res.pop + fitness_last_gen = pop.get('F') + best_solution = np.argmin(fitness_last_gen) + best_individual = pop.get('X')[best_solution, :] + best_individuals.append(best_individual) + + if self.verbose: + print('Rule based fit for time ' + str(time) + ' completed.') + + + self.performance[time] = 1 - fitness_last_gen[best_solution] + + try: + self.var_names = list(X.columns) + self.X = X.values + except AttributeError: + self.X = X + self.var_names = [str(ix) for ix in range(X.shape[1])] + + + ruleBase_temp = self._contruct_tempRuleBase(problems, best_individuals) + + self.rule_base = temporalMasterRuleBase(ruleBase_temp) + + self.eval_performance = evr.evalRuleBase(self.rule_base, np.array(X), y, time_moments) + + self.eval_performance.add_full_evaluation() + self.rename_fuzzy_variables() + self.rule_base.purge_rules(self.tolerance) + + + def forward(self, X: np.array, time_moments: list[int] = None) -> np.array: + ''' + Returns the predicted class for each sample. + + :param X: np array samples x features. + :param time_moments: list of integers. Time moments associated to each sample (when temporal dependencies are present) + :return: np array samples (x 1) with the predicted class. + ''' + try: + X = X.values # If X was a numpy array + except AttributeError: + pass + + return self.rule_base.winning_rule_predict(X, time_moments) + + + + def plot_fuzzy_variables(self) -> None: + ''' + Plot the fuzzy partitions in each fuzzy variable. + ''' + fuzzy_variables = self.rule_base.rule_bases[0].antecedents + + for ix, fv in enumerate(fuzzy_variables): + vis_rules.plot_fuzzy_variable(fv) + + + def get_rulebase(self) -> list[np.array]: + ''' + Get the rulebase obtained after fitting the classifier to the data. + + :return: a matrix format for the rulebase. + ''' + return self.rule_base.get_rulebase_matrix() + +def eval_temporal_fuzzy_model(fl_classifier: evf.BaseFuzzyRulesClassifier, X_train: np.array, y_train: np.array, + X_test: np.array, y_test: np.array, time_moments: list[int] = None, test_time_moments: list[int] = None, + plot_rules=True, print_rules=True, plot_partitions=True, return_rules=False, print_accuracy=True, print_matthew=True) -> None: + ''' + Function that evaluates a fuzzy rule based model. It also plots the rules and the fuzzy partitions. + + :param fl_classifier: Fuzzy rule based model. + :param X_train: Training data. + :param y_train: Training labels. + :param X_test: Test data. + :param y_test: Test labels. + :param plot_rules: If True, it plots the rules. + :param print_rules: If True, it prints the rules. + :param plot_partitions: If True, it plots the fuzzy partitions. + :return: None + ''' + + if print_accuracy: + print('ACCURACY') + print('Train performance: ' + + str(np.mean(np.equal(y_train, fl_classifier.forward(X_train, time_moments))))) + print('Test performance: ' + + str(np.mean(np.equal(y_test, fl_classifier.forward(X_test, test_time_moments))))) + print('------------') + if print_matthew: + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_train, fl_classifier.forward(X_train, time_moments)))) + print('Test performance: ' + + str(matthews_corrcoef(y_test, fl_classifier.forward(X_test, test_time_moments)))) + print('------------') + + for ix in np.unique(time_moments): + try: + X_aux = X_train[time_moments == ix, :] + X_aux_test = X_test[time_moments == ix, :] + except pd.core.indexing.InvalidIndexError: + X_aux = X_train.iloc[time_moments == ix, :] + X_aux_test = X_test.iloc[test_time_moments == ix, :] + + y_aux = y_train[time_moments == ix] + y_aux_test = y_test[test_time_moments == ix] + + if print_matthew: + print('MOMENT ' + str(ix)) + print('------------') + print('MATTHEW CORRCOEF') + print('Train performance: ' + + str(matthews_corrcoef(y_aux, fl_classifier.forward(X_aux, np.array([ix] * X_aux.shape[0]))))) + print('Test performance: ' + + str(matthews_corrcoef(y_aux_test, fl_classifier.forward(X_aux_test, np.array([ix] * X_aux_test.shape[0]))))) + print('------------') + + if plot_rules: + vis_rules.visualize_rulebase(fl_classifier) + if print_rules or return_rules: + res = fl_classifier.print_rules(return_rules) + if plot_partitions: + fl_classifier.plot_fuzzy_variables() + + if return_rules: + return res + else: + print(res) + diff --git a/ex_fuzzy/ex_fuzzy/usage_data_permission.txt b/ex_fuzzy/ex_fuzzy/usage_data_permission.txt new file mode 100644 index 0000000..e25f181 --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/usage_data_permission.txt @@ -0,0 +1 @@ +y \ No newline at end of file diff --git a/ex_fuzzy/ex_fuzzy/utils.py b/ex_fuzzy/ex_fuzzy/utils.py new file mode 100644 index 0000000..b048ecb --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/utils.py @@ -0,0 +1,539 @@ +# -*- coding: utf-8 -*- +""" +Functions that are not fuzzy-specific, but util for some computations. +Dedicated mostly to compute quantiles for fuzzy partitions. + +""" +import numpy as np +import pandas as pd + +try: + from . import fuzzy_sets as fs + from . import maintenance as mnt + from . import temporal + from . import rules + from . import eval_rules as evr +except ImportError: + import fuzzy_sets as fs + import maintenance as mnt + import temporal + import rules + import eval_rules as evr + + +from sklearn.model_selection import train_test_split + + +def quartile_compute(x: np.array) -> list[float]: + ''' + Computes the quartiles for each feature. + + :param x: array samples x features + :return: list of quartiles for each feature + ''' + return np.quantile(x, [0, 0.25, 0.5, 1], axis=0) + + +def fixed_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles for each feature in numpy array. + Quantiles: [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1], axis=0) + + +def partition3_quantile_compute(x: np.array) -> list[float]: + ''' + Computes a series of quantiles partitioning the variable in 3 cases. + + Quantiles: [0.00, 0.20, 0.50, 0.80, 1.00] + + :param x: array samples x features + :return: list of quantiles for each feature + ''' + return np.quantile(x, [0, 0.20, 0.50, 0.80, 1.00], axis=0) + + +def t1_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 4, 4). + ''' + + + n_partitions = 4 + trap_memberships_size = 4 + quantile_numbers = fixed_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == n_partitions - 1: + partition_parameters[:, partition, 0] = quantile_numbers[-3] + partition_parameters[:, partition, 1] = quantile_numbers[-2] + partition_parameters[:, partition, 2] = quantile_numbers[-1] + partition_parameters[:, partition, 3] = quantile_numbers[-1] + else: + pointer = 1 if partition == 1 else 4 + partition_parameters[:, partition, 0] = quantile_numbers[pointer] + partition_parameters[:, partition, + 1] = quantile_numbers[pointer + 1] + partition_parameters[:, partition, + 2] = quantile_numbers[pointer + 2] + partition_parameters[:, partition, + 3] = quantile_numbers[pointer + 3] + + return partition_parameters + + +def t1_three_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in four trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2] = quantile_numbers[1] + partition_parameters[:, partition, 3] = quantile_numbers[2] + elif partition == 1: + partition_parameters[:, partition, 0] = quantile_numbers[1] + partition_parameters[:, partition, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3] = quantile_numbers[3] + else: + partition_parameters[:, partition, 0] = quantile_numbers[2] + partition_parameters[:, partition, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2] = quantile_numbers[4] + partition_parameters[:, partition, 3] = quantile_numbers[4] + + return partition_parameters + + +def t2_simple_partition(x: np.array) -> np.array: + ''' + Partitions the fuzzy variable in three trapezoidal memberships. + + :param x: numpy array, vector of shape (samples, ). + :return: numpy array, vector of shape (variables, 3, 4, 2). + ''' + n_partitions = 3 + trap_memberships_size = 4 + quantile_numbers = partition3_quantile_compute(x) + + partition_parameters = np.zeros( + (x.shape[1], n_partitions, trap_memberships_size, 2)) + for partition in range(n_partitions): + if partition == 0: + partition_parameters[:, partition, 0, 1] = quantile_numbers[0] + partition_parameters[:, partition, 1, 1] = quantile_numbers[0] + partition_parameters[:, partition, 2, 1] = quantile_numbers[1] + partition_parameters[:, partition, 3, 1] = quantile_numbers[2] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[0] + partition_parameters[:, partition, 1, 0] = quantile_numbers[0] + partition_parameters[:, partition, 2, 0] = quantile_numbers[1] + partition_parameters[:, partition, 3, 0] = quantile_numbers[1] + \ + 0.9 * (quantile_numbers[2] - quantile_numbers[1]) + + elif partition == 1: + partition_parameters[:, partition, 0, 1] = quantile_numbers[1] + partition_parameters[:, partition, 1, 1] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 1] = ( + quantile_numbers[2] + quantile_numbers[3]) / 2 + partition_parameters[:, partition, 3, 1] = quantile_numbers[3] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[1] + \ + 0.1 * (quantile_numbers[2] - quantile_numbers[1]) + partition_parameters[:, partition, 1, 0] = ( + quantile_numbers[1] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 2, 0] = ( + quantile_numbers[3] + quantile_numbers[2]) / 2 + partition_parameters[:, partition, 3, 0] = quantile_numbers[2] + \ + 0.9 * (quantile_numbers[3] - quantile_numbers[2]) + + else: + partition_parameters[:, partition, 0, 1] = quantile_numbers[2] + partition_parameters[:, partition, 1, 1] = quantile_numbers[3] + partition_parameters[:, partition, 2, 1] = quantile_numbers[4] + partition_parameters[:, partition, 3, 1] = quantile_numbers[4] + + partition_parameters[:, partition, 0, 0] = quantile_numbers[2] + \ + 0.1 * (quantile_numbers[3] - quantile_numbers[2]) + partition_parameters[:, partition, 1, 0] = quantile_numbers[3] + partition_parameters[:, partition, 2, 0] = quantile_numbers[4] + partition_parameters[:, partition, 3, 0] = quantile_numbers[4] + + return partition_parameters + + +def t1_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + tripartition_names = ['Low', 'Medium', 'High'] + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t1_three_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.FS(tripartition_names[ix], fz_memberships[fz_parameter, ix, :], [ + mins[fz_parameter], maxs[fz_parameter]]) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res + + +def t2_fuzzy_partitions_dataset(x0: np.array) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using iv fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + fz_memberships = t2_simple_partition(x) + res = [] + for fz_parameter in range(fz_memberships.shape[0]): + fzs = [fs.IVFS(str(ix), fz_memberships[fz_parameter, ix, :, 0], fz_memberships[fz_parameter, ix, :, 1], [ + mins[fz_parameter], maxs[fz_parameter]], lower_height=0.8) for ix in range(fz_memberships.shape[1])] + res.append(fs.fuzzyVariable(fv_names[fz_parameter], fzs)) + + return res + + +def gt2_fuzzy_partitions_dataset(x0: np.array, resolution_exp:int=1) -> list[fs.fuzzyVariable]: + ''' + Partitions the dataset features into different fuzzy variables using gt2 fuzzy sets. Parameters are prefixed. + Use it for simple testing and initial solution. + + :param x: numpy array|pandas dataframe, shape samples x features. + :param resolution_exp: exponent of the resolution of the partition. Default is -2, which means 0.01. (Number of significant decimals) + :return: list of fuzzy variables. + ''' + try: + fv_names = x0.columns + x = x0.values + except AttributeError: + fv_names = [str(ix) for ix in range(x0.shape[1])] + x = x0 + + mins = np.min(x, axis=0) + maxs = np.max(x, axis=0) + iv_simple_partition = t2_fuzzy_partitions_dataset(x) + resolution = 10.0**-np.abs(resolution_exp) + res = [] + # We iterate through all possible variables + for ix_var, fz_var in enumerate(iv_simple_partition): + domain_resolution = np.arange( + mins[ix_var], maxs[ix_var] + resolution, resolution) + fzs = [] + for ix_lv, fz_lv in enumerate(fz_var.get_linguistic_variables()): + memberships = fz_lv.membership(domain_resolution) + fs_domain = {} + for ix_z, x in enumerate(domain_resolution): + membership_z = memberships[ix_z] + fs_domain[x] = fs.FS(str(x), [membership_z[0], np.mean( + membership_z), np.mean(membership_z), membership_z[1]], [0.0, 1.0]) + + fzs.append(fs.GT2(fz_lv.name, fs_domain, [ + mins[ix_var], maxs[ix_var]], significant_decimals=np.abs(resolution_exp), unit_resolution=0.01)) + + res.append(fs.fuzzyVariable(fv_names[ix_var], fzs)) + + return res + + +def construct_partitions(X : np.array, fz_type_studied:fs.FUZZY_SETS) -> list[fs.fuzzyVariable]: + ''' + Returns a list of linguistic variables according to the kind of fuzzy specified. + + :param X: numpy array|pandas dataframe, shape samples x features. + :param fz_type_studied: fuzzy set type studied. + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Funcs]['precompute_labels'] += 1 + mnt.usage_data[mnt.usage_categories.FuzzySets][fz_type_studied.name] += 1 + + if fz_type_studied == fs.FUZZY_SETS.t1: + precomputed_partitions = t1_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.t2: + precomputed_partitions = t2_fuzzy_partitions_dataset(X) + elif fz_type_studied == fs.FUZZY_SETS.gt2: + precomputed_partitions = gt2_fuzzy_partitions_dataset(X) + + return precomputed_partitions + + +def construct_conditional_frequencies(X: np.array, discrete_time_labels: list[int], initial_ffss: list[fs.FS]): + ''' + Computes the conditional temporal function for a set of fuzzy sets according to their variation in time. + + :param X: numpy array, shape samples x features. + :param discrete_time_labels: discrete time labels. + :param initial_fs: initial fuzzy set list. + :return: conditional frequencies. Array shape (time steps, initial fuzzy sets) + ''' + obs = X.shape[0] + discrete_time_labels = np.array(discrete_time_labels) + memberships = np.zeros((obs, len(initial_ffss))) + for ix, fset in enumerate(initial_ffss): + if fset.type() == fs.FUZZY_SETS.t2: + memberships[:, ix] = np.mean(fset.membership(X), axis=1) + elif fset.type() == fs.FUZZY_SETS.gt2: + memberships[:, ix] = np.mean(np.squeeze(fset._alpha_reduction(fset.membership(X))), axis=1) + else: + memberships[:, ix] = fset.membership(X) + + max_memberships = np.argmax(memberships, axis=1) + res = np.zeros((len(np.unique(discrete_time_labels)), len(initial_ffss))) + + for time in range(len(np.unique(discrete_time_labels))): + + relevant_memberships = max_memberships[time == discrete_time_labels] + fs_winner_counter = np.zeros(len(initial_ffss)) + for ix, fset in enumerate(initial_ffss): + fs_winner_counter[ix] = np.sum(relevant_memberships == ix) + + res[time, :] = fs_winner_counter + + return res / (np.max(res, axis=0) + 1e-6) + + +def classify_temp(dates: pd.DataFrame, cutpoints: tuple[str, str], time: str) -> np.array: + ''' + Classifies a set of dates according to the temporal cutpoints. Uses {time} as a the time resolution. + Returns an array where true values are those values contained between those two date points. + + :param dates: data observations to cut. + :param cutpoints: points to check. + :param time: time field to use as the criteria. + :return: boolean array. True values are those contained between the cutpoints. + ''' + + def extract_hour(row): + return row.__getattribute__(time) + + hours = pd.to_datetime(dates['date']).apply(extract_hour) + + cutpoint_series_0 = pd.to_datetime(pd.Series([cutpoints[0]] * len(dates))) + cutpoint_series_0.index = dates.index + hours0 = cutpoint_series_0.apply(extract_hour) + + cutpoint_series_1 = pd.to_datetime(pd.Series([cutpoints[1]] * len(dates))) + cutpoint_series_1.index = dates.index + hours1 = cutpoint_series_1.apply(extract_hour) + + condicion1 = hours >= hours0 + condicion2 = hours <= hours1 + + return np.array(np.logical_and(condicion1, condicion2)) + + +def assign_time(a: np.array, observations: list[np.array]) -> int: + ''' + Assigns a temporal moment to a set of observations. + + :param a: array of boolean values. + :param observations: list of boolean arrays with the corresponding timestamps. + :return: the index of the correspondent time moment for the a-th observation. + :raises: ValueError if a is not timestamped in any of the observation arrays.''' + for ix, obs in enumerate(observations): + if obs[a]: + return ix + + raise ValueError('No temporal moment assigned') + + +def create_tempVariables(X_train: np.array, time_moments: np.array, precomputed_partitions: list[fs.fuzzyVariable]) -> list[temporal.temporalFS]: + ''' + Creates a list of temporal fuzzy variables. + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of temporal fuzzy variables. + ''' + temp_partitions = [] + for ix in range(X_train.shape[1]): + feat_conditional = construct_conditional_frequencies(X_train[:, ix], time_moments, initial_ffss=precomputed_partitions[ix]) + temp_fs_list = [] + for vl in range(feat_conditional.shape[1]): + vl_temp_fs = temporal.temporalFS(precomputed_partitions[ix][vl], feat_conditional[:, vl]) + temp_fs_list.append(vl_temp_fs) + + temp_fs_variable = temporal.temporalFuzzyVariable(precomputed_partitions[ix].name, temp_fs_list) + temp_partitions.append(temp_fs_variable) + + return temp_partitions + + +def create_multi_tempVariables(X_train: np.array, time_moments: np.array, fuzzy_type: fs.FUZZY_SETS) -> list[list[temporal.temporalFS]]: + ''' + Creates a of list of lists of temporal fuzzy variables. Each corresponds to a fuzzy partition in a different moment in time. + (So, instead of having one vl for all time moments, you have one different for each time moment that represents the same idea) + + :param X_train: numpy array, shape samples x features. + :param time_moments: time moments. Array shape (samples,). Each value is an integer denoting the n-th time moment of that observation. + :param precomputed_partitions: precomputed partitions for each feature. + :return: list of lists of temporal fuzzy variables. + ''' + temp_partitions = [] + + unique_time_moments = np.unique(time_moments) + for time in unique_time_moments: + X_obs = X_train[time_moments == time, :] + precomputed_partitions = construct_partitions(X_obs, fuzzy_type) + + temp_partitions.append(create_tempVariables(X_obs, time_moments[time_moments == time], precomputed_partitions)) + + return temp_partitions + + +def temporal_cuts(X: pd.DataFrame, cutpoints: list[tuple[str, str]], time_resolution: str='hour') -> list[np.array]: + ''' + Returns a list of boolean indexes for each temporal moment. Performs the cuts between time steps using the cutpoints list. + + :param X: data observations to cut in temrporal moments. + :param temporal_moments: list of temporal moments to cut. + :param cutpoints: list of tuples with the cutpoints for each temporal moment. + :param time_resolution: time field to use as the criteria. + :return: list of boolean arrays. True values are those contained between the cutpoints in each moment. + ''' + + res = [] + for ix, cutpoint in enumerate(cutpoints): + observations = classify_temp(X, cutpoint, time=time_resolution) + res.append(observations) + + return res + + +def temporal_assemble(X: np.array, y:np.array, temporal_moments: list[np.array]): + ''' + Assembles the data in the temporal moments in order to have partitions with balanced time moments in each one. + + :param X: data observations. + :param y: labels. + :param temporal_moments: list of boolean arrays. True values are those contained between the cutpoints in each moment. + :return: tuple of lists of data and labels for each temporal moment. + First tuple is: X_train, X_test, y_train, y_test + Second tuple is: train temporal moments, test temporal moments. + ''' + moments_partitions = [] + train_temporal_boolean_markers = [] + test_temporal_boolean_markers = [] + train_counter = 0 + test_counter = 0 + + for ix, temporal_moment in enumerate(temporal_moments): + X_train, X_test, y_train, y_test = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + moments_partitions.append((X_train, X_test, y_train, y_test)) + + if isinstance(X_train,(pd.core.series.Series,pd.DataFrame)): + X_train = pd.concat([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = pd.concat([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + else: + X_train = np.concatenate([moments_partitions[ix][0] for ix in range(len(moments_partitions))]) + X_test = np.concatenate([moments_partitions[ix][1] for ix in range(len(moments_partitions))]) + y_train = np.concatenate([moments_partitions[ix][2] for ix in range(len(moments_partitions))]) + y_test = np.concatenate([moments_partitions[ix][3] for ix in range(len(moments_partitions))]) + + for ix, temporal_moment in enumerate(temporal_moments): + # Believe, this makes sense to avoid rounding errrors in the size of the final vector + _, _, y_train0, y_test0 = train_test_split(X[temporal_moment], y[temporal_moment], test_size=0.33, random_state=0) + + train_moment_observations = np.zeros((X_train.shape[0])) + train_moment_observations[train_counter:train_counter+len(y_train0)] = 1 + train_counter += len(y_train0) + train_temporal_boolean_markers.append(train_moment_observations) + + test_moment_observations = np.zeros((X_test.shape[0])) + test_moment_observations[test_counter:test_counter+len(y_test0)] = 1 + test_counter += len(y_test0) + test_temporal_boolean_markers.append(test_moment_observations) + + + return [X_train, X_test, y_train, y_test], [train_temporal_boolean_markers, test_temporal_boolean_markers] + + +def extend_fuzzy_sets_enum(new_fuzzy_sets_enum: fs.FUZZY_SETS) -> list[fs.FUZZY_SETS]: + ''' + Extends the fuzzy sets enum with additional types. + + :param fuzzy_sets_enum: fuzzy sets enum. + :return: extended fuzzy sets enum. + ''' + import enum + NEW_FUZZY_SETS = enum.Enum( + "FUZZY_SETS", + [(es.name, es.value) for es in fs.FUZZY_SETS] + [(es.name, es.value) for es in new_fuzzy_sets_enum] + ) + fs.FUZZY_SETS = NEW_FUZZY_SETS + + +def mcc_loss(ruleBase: rules.RuleBase, X:np.array, y:np.array, tolerance:float, alpha:float=0.99, beta:float=0.0125, gamma:float=0.0125) -> float: + + ''' + Fitness function for the optimization problem. Uses only the MCC, ignores the size penalization terms. + + + :param ruleBase: RuleBase object + :param X: array of train samples. X shape = (n_samples, n_features) + :param y: array of train labels. y shape = (n_samples,) + :param tolerance: float. Tolerance for the size evaluation. + :param alpha: ignored. + :param beta: ignored. + :param gamma: ignored. + :return: float. Fitness value. + ''' + ev_object = evr.evalRuleBase(ruleBase, X, y) + ev_object.add_rule_weights() + + score_acc = ev_object.classification_eval() + + return score_acc \ No newline at end of file diff --git a/ex_fuzzy/ex_fuzzy/vis_rules.py b/ex_fuzzy/ex_fuzzy/vis_rules.py new file mode 100644 index 0000000..d38a9ff --- /dev/null +++ b/ex_fuzzy/ex_fuzzy/vis_rules.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +""" +This is a the source file that contains the functions necessary to visualize the set of rules. +""" +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import networkx as nx + +try: + from . import rules + from . import evolutionary_fit as evf + from . import fuzzy_sets as fs + from . import maintenance as mnt +except ImportError: + import rules + import evolutionary_fit as evf + import fuzzy_sets as fs + import maintenance as mnt + + +def _column_histogram(rule_matrix: np.array) -> dict: + ''' + Computes the histogram for all the unique values in a column. + + :param rule_matrix: vector with the numerical values. + :return: dictionary with the histogram. + ''' + res = {} + for x in np.unique(rule_matrix): + if x != -1: + res[x] = np.sum(rule_matrix == x) + + return res + + +def _histogram(rule_matrix: np.array) -> list[dict]: + ''' + Returns a list with the histogram for each antecedent according to linguist variables. + + :param rule_matrix: matrix with the rules. + :return: list with the histogram in dictionary format for each antecedent. + ''' + res = [] + + for column_ix in range(rule_matrix.shape[1]): + res.append(_column_histogram(rule_matrix[:, column_ix])) + + return res + + +def _max_values(appearances: list) -> tuple[int, int]: + ''' + Returns the antecedent and its linguistic value most repeated. + + :param appearances: list with the histogram for each antecedent. + :return: tuple with the antecedent and its linguistic value most repeated. + ''' + res = 0 + antecedent = None + vl = None + + for ix, apperances_an in enumerate(appearances): + for key, value in apperances_an.items(): + if value > res: + res = value + antecedent = ix + vl = key + + return antecedent, vl + + +def create_graph_connection(rules, possible_vl): + ''' + Returns a square matrix where each number indicates if two nodes are connected. + Connectes by checking if both are in the same rule. + + :param rules: list with the rules. + :param possible_vl: number of linguistic variables. + :return: square matrix where each number indicates if two nodes are connected. + ''' + def generate_index(ant, vl0): return int(possible_vl * ant + vl0) + res = np.zeros( + (possible_vl * rules.shape[1], possible_vl * rules.shape[1])) + + for rule in rules: + for antecedent, vl in enumerate(rule): + if vl > -1: + for antecedent2, vl2 in enumerate(rule): + if vl2 > -1: + res_index1 = generate_index(antecedent, vl) + res_index2 = generate_index(antecedent2, vl2) + + res[res_index1, res_index2] += 1 + + return res / 2 + + +def choose_popular_rules(rule_matrix: np.array) -> np.array: + ''' + Returns the index of the rules that contain the most popular antecedent in the dataset. + + :param rule_matrix: matrix with the rules. + :return: numpy array with the rules that contain the most popular antecedent in the dataset. + ''' + appearances = _histogram(rule_matrix) + antecedent, vl = _max_values(appearances) + + chosen_rules = rule_matrix[:, antecedent] == vl + + return chosen_rules + + +def connect_rulebase(rulebase: rules.RuleBase) -> list[np.array]: + ''' + Connects antecedents connected by checking if both are in the same rule. + + :param rulebase: Rule base to connect. + :return: List of pandas dataframes with the connections in adjacency matrix format. + ''' + + # We choose those rules to explain, as those who have the most common antecedent. + rule_matrix = rules.list_rules_to_matrix(rulebase.rules) + res = [] + antecedents_names = [ + x.name + ' ' + y for x in rulebase.antecedents for y in rulebase.antecedents[0].linguistic_variable_names()] + + while rule_matrix.shape[0] > 0: + rules_to_viz = rule_matrix[choose_popular_rules(rule_matrix), :] + rule_matrix = rule_matrix[( + 1 - choose_popular_rules(rule_matrix)).astype(bool), :] + + graph_rule = create_graph_connection(rules_to_viz, len( + rulebase.antecedents[0].linguistic_variable_names())) + res.append(pd.DataFrame( + graph_rule, columns=antecedents_names, index=antecedents_names)) + + return res + + +def connect_master_rulebase(mrule_base: rules.MasterRuleBase) -> list[list[np.array]]: + ''' + Connects antecedents connected by checking if both are in the same rule. + + :param mrule_base: Master rule base to connect. + :return: List of list of pandas dataframes with the connections in adjacency matrix format. + ''' + res = [] + for rule_base in mrule_base.rule_bases: + res.append(connect_rulebase(rule_base)) + + return res + + +def visualize_rulebase(mrule_base: rules.MasterRuleBase, export_path: str = None) -> None: + ''' + Visualize a rule base using low, medium and high partitions with 1 rule in common -> 1 edge connections. + + :param mrule_base: Master rule base to visualize. + :param export_path: Path to export the graph. + ''' + + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Visualization]['plot_graph'] += 1 + + def color_func(a): + ''' + Returns the color of the node according to the linguistic variable. + + :param a: Node name. + :return: Color of the node. + ''' + node_colors = ['blue', 'yellow', 'red'] + + if ' L' in a: + return node_colors[0] + elif ' M' in a: + return node_colors[1] + else: + return node_colors[2] + + def vl_prune(a): return a.replace('High', 'H').replace( + 'Medium', 'M').replace('Low', 'L').strip() + + if isinstance(mrule_base, evf.BaseFuzzyRulesClassifier): + mrule_base = mrule_base.rule_base + + connected_mrule_base = connect_master_rulebase(mrule_base) + + for ix, connected_rule_base in enumerate(connected_mrule_base): + for jx, rule in enumerate(connected_rule_base): + G = nx.from_pandas_adjacency(rule) + isolated_nodes = [ + node for node in G.nodes() if G.degree(node) == 0] + G.remove_nodes_from(isolated_nodes) + auto_edges = nx.selfloop_edges(G) + G.remove_edges_from(auto_edges) + + new_node_names = [vl_prune(node) for node in G.nodes()] + mapping = dict(zip(G, new_node_names)) + G = nx.relabel_nodes(G, mapping) + + if jx == 0: + G_final = G + else: + G_final = nx.compose(G_final, G) + + fig, ax = plt.subplots() + try: + os = nx.nx_agraph.graphviz_layout(G_final, prog='sfdp') + except ImportError: + os = nx.kamada_kawai_layout(G_final) + + node_colors = [color_func(node) for node in G_final.nodes()] + nx.draw(G_final, with_labels=True, ax=ax, + pos=os, node_color=node_colors) + plt.title('Consequent: ' + str(ix)) + fig.show() + + if export_path is not None: + nx.write_gexf(G_final, export_path + + '/consequent_' + str(ix) + '.gexf') + + +def plot_fuzzy_variable(fuzzy_variable: fs.fuzzyVariable) -> None: + ''' + Plots a fuzzy variable using trapezoidal membership functions. + + :param fuzzy_variable: a fuzzy variable from the fuzzyVariable class in fuzzy_set module. + :return: None + ''' + if mnt.save_usage_flag: + mnt.usage_data[mnt.usage_categories.Visualization]['plot_fuzzy_variable'] += 1 + + if fuzzy_variable.linguistic_variables[0].type() != fs.FUZZY_SETS.gt2: + fig, ax = plt.subplots() + else: + fig = plt.figure() + ax = plt.axes(projection='3d') + + memberships = [0, 1, 1, 0] + + colors = ['b', 'r', 'g', 'orange', 'y'] + for ix, fuzzy_set in enumerate(fuzzy_variable.linguistic_variables): + name = fuzzy_set.name + initiated = False + fz_studied = fuzzy_set.type() + + if fz_studied == fs.FUZZY_SETS.t1: + ax.plot(fuzzy_set.membership_parameters, + memberships, colors[ix], label=name) + elif fz_studied == fs.FUZZY_SETS.t2: + ax.plot(fuzzy_set.secondMF_lower, np.array(memberships) * fuzzy_set.lower_height, 'black') + ax.plot(fuzzy_set.secondMF_upper, np.array(memberships), 'black') + + # Compute the memberships for the lower/upper membership points. We do it in this way because non-exact 0/1s give problems. + x_lower = fuzzy_set.secondMF_lower + x_lower_lmemberships = [0.0 ,fuzzy_set.lower_height ,fuzzy_set.lower_height, 0.0] + x_lower_umemberships = [fuzzy_set(x_lower[0])[1] , 1.0, 1.0 , fuzzy_set(x_lower[3])[1]] + + x_upper = fuzzy_set.secondMF_upper + x_upper_lmemberships = [0.0 , fuzzy_set(x_upper[1])[0], fuzzy_set(x_upper[2])[0], 0.0] + x_upper_umemberships = [0.0 ,1.0 ,1.0, 0.0] + + x_values = list(x_lower) + list(x_upper) + lmembership_values = list(x_lower_lmemberships) + list(x_upper_lmemberships) + umembership_values = list(x_lower_umemberships) + list(x_upper_umemberships) + aux_df = pd.DataFrame(zip(x_values, lmembership_values, umembership_values), columns=['x', 'l', 'u']) + + + if len(aux_df['x']) != len(set(aux_df['x'])): # There are repeated elements, so we use an order that should work in this case + # u0 l0 u1 l1 l2 u2 l3 u3 + x = list((x_upper[0], x_lower[0], x_upper[1], x_lower[1], x_lower[2], x_upper[2], x_lower[3], x_upper[3])) + l_memberships = list((x_upper_lmemberships[0], x_lower_lmemberships[0], x_upper_lmemberships[1], x_lower_lmemberships[1], x_lower_lmemberships[2], x_upper_lmemberships[2], x_lower_lmemberships[3], x_upper_lmemberships[3])) + u_memberships = list((x_upper_umemberships[0], x_lower_umemberships[0], x_upper_umemberships[1], x_lower_umemberships[1], x_lower_umemberships[2], x_upper_umemberships[2], x_lower_umemberships[3], x_upper_umemberships[3])) + + ax.fill_between(x, l_memberships, u_memberships, color=colors[ix], alpha=0.5, label=name) + else: + aux_df.sort_values('x', inplace=True) + ax.fill_between(aux_df['x'], aux_df['l'], aux_df['u'], color=colors[ix], alpha=0.5, label=name) + + elif fz_studied == fs.FUZZY_SETS.gt2: + for key, value in fuzzy_set.secondary_memberships.items(): + + gt2_memberships = value(fuzzy_set.sample_unit_domain) + key_plot = [float(key)]*sum(gt2_memberships > 0) + if initiated: + ax.plot(key_plot, fuzzy_set.sample_unit_domain[gt2_memberships > 0], gt2_memberships[gt2_memberships > 0], color=colors[ix]) + else: + ax.plot(key_plot, fuzzy_set.sample_unit_domain[gt2_memberships > 0], gt2_memberships[gt2_memberships > 0], color=colors[ix], label=name) + initiated = True + + ax.legend(loc='upper right', shadow=True) + plt.title(fuzzy_variable.name) + fig.show() + + +def matrix_rule_base_form(rule_base: rules.Rule) -> pd.DataFrame: + ''' + Returns a matrix with the rule base in the form of a matrix to visualize. + + :param mrule_base: Rule base to transform. + :return: Matrix with the rule base in the form of a matrix. + ''' + + n_rules = len(rule_base.rules) + antecedents = len(rule_base.antecedents) + + res = pd.DataFrame(np.zeros((n_rules, antecedents)), columns=[jx.name for jx in rule_base.antecedents]) + + for ix, rule in enumerate(rule_base): + for jx, antecedent in enumerate(rule_base.antecedents): + res.loc[ix, antecedent.name] = rule.antecedents[jx] + + return res + + +def filter_useless_columns(df: pd.DataFrame) -> pd.DataFrame: + ''' + Filter columns with only one value. + + :param df: Dataframe to filter. + :return: Filtered dataframe. + ''' + for column in df.columns: + if df[column].unique()[0] == -1: + df.drop(column, axis=1, inplace=True) + + return df + + +def rules_to_latex(rule_base:rules.MasterRuleBase) -> str: + ''' + Prints the rule base in a latex format. It prints + + :note: if the rule base has three different linguistic labels, it will use custom commands for the partitions. You can define these commands (\low, \mid, \hig, \dc) to show colors, figures, etc. Be sure to recheck the DS, ACC values in this case, because 1.0 values of them are also converted to these commands. + + :param rule_base: the master rule base to print. + :returns: the String as a latex tabular. + ''' + class proxy_dict(): + + def __init__(self) -> None: + self.cell_colors = { + -1: '\\dc', + 0: '\\low', + 1: '\\med', + 2: '\\hig' + } + + def __getitem__(self, value) -> str: + if value in self.cell_colors.keys(): + return self.cell_colors[value] + else: + return "{:.2f}".format(value) + + + # Define the mapping for cell colors + rules_matrix = rule_base.get_rulebase_matrix() + + # Add the consequent to the rules + cons_rules_matrix = [] + for ix_cons, ruls in enumerate(rules_matrix): + for rule_list in ruls: + if len(rule_list.shape) == 2: + cons_rules_matrix.append(np.append(np.ones((rule_list.shape[0])) * ix_cons, rule_list, axis=1)) + else: + cons_rules_matrix.append(np.append(np.ones((1, )) * ix_cons, rule_list)) + + dominance_scores = np.array([x.score for x in rule_base.get_rules()]) + if len(dominance_scores.shape) == 2: + dominance_scores = np.mean(dominance_scores, axis=1, keepdims=True) + else: + dominance_scores = np.expand_dims(dominance_scores, axis=1) + + accs = np.array([x.accuracy for x in rule_base.get_rules()]) + accs = np.expand_dims(accs, axis=1) + cons_rules_matrix = np.append(np.append(np.array(cons_rules_matrix), dominance_scores, axis=1), accs, axis=1) + column_order = ['Consequent'] + [a.name for a in rule_base.antecedents] + ['DS', 'Acc'] + df = pd.DataFrame(cons_rules_matrix, columns=column_order) + cell_colors = proxy_dict() + + # Create the LaTeX table + latex_table = "\\begin{tabular}{" + "c" * (len(column_order)-2) + "|cc}\n" + latex_table += "\t\\toprule\n" + latex_table += "\t" + " & ".join(column_order) + " \\\\\n" + latex_table += "\t\\midrule\n" + + i = 0 + for cluster, group in df.groupby('Consequent'): + latex_table += f"\t\\multirow{{{len(group)}}}{{*}}{{{cluster}}}" + for _, row in group.iterrows(): + if i % 2 == 0: # Add a shade of grey + latex_table += " & \cellcolor{gray!25}" + " & \cellcolor{gray!25}".join([cell_colors[val] for val in row[column_order[1:]]]) + " \\\\\n" + else: + latex_table += " & " + " & ".join([cell_colors[val] for val in row[column_order[1:]]]) + " \\\\\n" + i += 1 + if cluster != len(rules_matrix) - 1: + latex_table += "\t\\midrule\n" + + latex_table += "\t\\bottomrule\n" + latex_table += "\\end{tabular}" + + print(latex_table) \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ff92683 --- /dev/null +++ b/setup.py @@ -0,0 +1,51 @@ +#! /usr/bin/env python +"""Toolbox for explainable AI using fuzzy logic.""" +from __future__ import absolute_import + +import os +# read the contents of your README file +from os import path + +from setuptools import find_packages, setup + +this_directory = path.abspath(path.dirname(__file__)) +with open(path.join(this_directory, "README.md"), encoding="utf-8") as f: + long_description = f.read() + +DISTNAME = "ex_fuzzy" +DESCRIPTION = "Library to perform explainable AI using fuzzy logic." +MAINTAINER = "Javier Fumanal Idocin" +MAINTAINER_EMAIL = "javierfumanalidocin@gmail.com" +URL = "" +LICENSE = "GPL-3.0" +DOWNLOAD_URL = "" +VERSION = "1.0.0" +INSTALL_REQUIRES = ["numpy", "networkx", "matplotlib", "pymoo", "pandas", "scikit-learn"] +CLASSIFIERS = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Programming Language :: Python", + "Programming Language :: Python :: 3.7", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Artificial Intelligence", + "Topic :: Software Development :: Libraries", + "Topic :: Software Development :: Libraries :: Python Modules", +] + +setup( + name=DISTNAME, + maintainer=MAINTAINER, + maintainer_email=MAINTAINER_EMAIL, + description=DESCRIPTION, + license=LICENSE, + url=URL, + version=VERSION, + download_url=DOWNLOAD_URL, + packages=['ex_fuzzy'], + package_dir={'ex_fuzzy': 'ex_fuzzy/ex_fuzzy'}, + install_requires=INSTALL_REQUIRES, + long_description=long_description, + long_description_content_type="text/markdown", + classifiers=CLASSIFIERS, +) diff --git a/tests/.coverage b/tests/.coverage new file mode 100644 index 0000000..ce72de1 Binary files /dev/null and b/tests/.coverage differ diff --git a/tests/__init__.py.txt b/tests/__init__.py.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_centroids.py b/tests/test_centroids.py new file mode 100644 index 0000000..7852fe0 --- /dev/null +++ b/tests/test_centroids.py @@ -0,0 +1,28 @@ +import numpy as np +import math + +import sys +sys.path.append('../ex_fuzzy/') + +import ex_fuzzy as ex_fuzzy + +def test_t2_centroid(): + ''' + Tests that fuzzy t2 (iv) centroids compute correctly. + ''' + trial_fs = ex_fuzzy.fuzzy_sets.IVFS('trial', [0.35, 0.4, 0.6, 0.65], [0.25 ,0.4, 0.6, 0.75], [0,1], lower_height=0.8) + z = np.arange(0, 1, 0.001) + assert math.isclose(ex_fuzzy.centroid.compute_centroid_iv(z, trial_fs(z))[0], 0.5, abs_tol=0.01), 'T2 centroid right not correctly computed' + assert math.isclose(ex_fuzzy.centroid.compute_centroid_iv(z, trial_fs(z))[1], 0.5, abs_tol=0.01), 'T2 centroid left not correctly computed' + + +def test_t2_centroid_centroids(): + ''' + Tests that fuzzy t2 (iv) centroid computed from previous centroids is computed correctly. + ''' + trial_fs = ex_fuzzy.fuzzy_sets.IVFS('trial', [0.35, 0.4, 0.6, 0.65], [0.25 ,0.4, 0.6, 0.75], [0,1], lower_height=0.8) + z = np.arange(0, 1, 0.001) + assert math.isclose(ex_fuzzy.centroid.compute_centroid_t2_r(z, trial_fs(z)), 0.5, abs_tol=0.01), 'T2 centroid right not correctly computed' + assert math.isclose(ex_fuzzy.centroid.compute_centroid_t2_l(z, trial_fs(z)), 0.5, abs_tol=0.01), 'T2 centroid left not correctly computed' + + diff --git a/tests/test_classification.py b/tests/test_classification.py new file mode 100644 index 0000000..f50ed7b --- /dev/null +++ b/tests/test_classification.py @@ -0,0 +1,56 @@ + +import numpy as np +import pandas as pd +import math +import sys +sys.path.append('../ex_fuzzy/') +sys.path.append('./ex_fuzzy/') + +import ex_fuzzy + +sample_size = 1000 + +def test_random_classification(fs_type=ex_fuzzy.fuzzy_sets.FUZZY_SETS.t1): + global sample_size + + sample = np.random.random_sample((sample_size, 5)) + targets = np.random.randint(0, 2, sample_size) + + model = ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier(10, 3, fs_type, verbose=False, tolerance=0.0, n_linguist_variables=3) + model.fit(sample, targets) + predictions = model.predict(sample) + assert math.isclose(np.mean(np.equal(predictions, targets)), 0.5, abs_tol=0.1) + + +def test_random_classification_precomputed(fs_type=ex_fuzzy.fuzzy_sets.FUZZY_SETS.t1): + global sample_size + + sample = np.random.random_sample((sample_size, 5)) + targets = np.random.randint(0, 2, sample_size) + vl_partitions = ex_fuzzy.utils.construct_partitions(sample, fs_type) + model = ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier(10, 3, verbose=False, tolerance=0.0, linguistic_variables=vl_partitions) + model.fit(sample, targets) + predictions = model.predict(sample) + assert math.isclose(np.mean(np.equal(predictions, targets)), 0.5, abs_tol=0.1) + + +def test_random_classification_t2(): + test_random_classification(ex_fuzzy.fuzzy_sets.FUZZY_SETS.t2) + + +def test_random_classification_t2_precomputed(): + test_random_classification_precomputed(ex_fuzzy.fuzzy_sets.FUZZY_SETS.t2) + + +def test_random_classification_gt2(): + test_random_classification(ex_fuzzy.fuzzy_sets.FUZZY_SETS.t2) + + +def test_random_classification_gt2_precomputed(): + test_random_classification_precomputed(ex_fuzzy.fuzzy_sets.FUZZY_SETS.t2) + +if __name__ == '__main__': + test_random_classification_t2() + test_random_classification_t2_precomputed() + test_random_classification_gt2() + test_random_classification_gt2_precomputed() diff --git a/tests/test_eval_tools.py b/tests/test_eval_tools.py new file mode 100644 index 0000000..143f889 --- /dev/null +++ b/tests/test_eval_tools.py @@ -0,0 +1,23 @@ +import numpy as np +import ex_fuzzy +import sys +sys.path.append('../ex_fuzzy/') + +def test_eval_fuzzy_model(): + ''' + Test the eval_fuzzy_model function. + + If it works, it should print the following: + Accuracy: 0.5 aprox + Matthews correlation coefficient: 0.0 aprox + ''' + sample_size = 1000 + sample = np.random.random_sample((sample_size, 5)) + targets = np.random.randint(0, 2, sample_size) + + model = ex_fuzzy.evolutionary_fit.BaseFuzzyRulesClassifier(10, 3, ex_fuzzy.fuzzy_sets.FUZZY_SETS.t1, verbose=False, tolerance=0.0, n_linguist_variables=3) + model.fit(sample, targets) + + ex_fuzzy.eval_tools.eval_fuzzy_model(model, sample, targets, sample, targets, + plot_rules=False, print_rules=False, plot_partitions=False) + diff --git a/tests/test_fuzzy_sets.py b/tests/test_fuzzy_sets.py new file mode 100644 index 0000000..259fcf7 --- /dev/null +++ b/tests/test_fuzzy_sets.py @@ -0,0 +1,52 @@ +import numpy as np +import math + +import sys +sys.path.append('./ex_fuzzy/') +sys.path.append('../ex_fuzzy/') +import ex_fuzzy as ex_fuzzy + + +def test_fuzzy_t1_memberships(): + ''' + Tests that fuzzy t1 memberships compute correctly. + ''' + trial_fs = ex_fuzzy.fuzzy_sets.FS('trial', [0,0.1, 0.25, 0.5], [0,1]) + + assert trial_fs.name == 'trial', 'Name not correctly set' + assert trial_fs(0.1) == 1, 'Trapezoidal membership fails in first term' + assert trial_fs(1) == 0, 'Trapezoidal membership fails in last term' + assert trial_fs(0.51) == 0, 'Trapezoidal memberships does not stop where it shoud' + assert trial_fs(0.05) == 0.5, 'Trapeziodal membership increasining in non linear way' + + +def test_fuzzy_t2_memberships(): + ''' + Tests that fuzzy t2 (iv) memberships compute correctly. + ''' + trial_fs = ex_fuzzy.fuzzy_sets.IVFS('trial', [0,0.1, 0.25, 0.4], [0, 0.15, 0.25, 0.5], [0,1], lower_height=0.8) + + assert trial_fs.name == 'trial', 'Name not correctly set' + trial_mfs = trial_fs(0.2) + assert trial_mfs[0] <= trial_mfs[1], 'Incoherent lower and upper membership behaviour' + + +def test_fuzzy_gt2_memberships(): + ''' + Tests that fuzzy gt2 memberships compute correctly. + ''' + trial_fs = {} + for x in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 1]: + trial_fs[x] = ex_fuzzy.fuzzy_sets.FS('trial', [0.25,0.5, 0.5, 0.75], [0,1]) + + trial_fs = ex_fuzzy.fuzzy_sets.GT2('trial', trial_fs, [0, 1], significant_decimals=1, unit_resolution=0.001) + res = trial_fs(0.3) + assert math.isclose(np.mean(trial_fs.alpha_reduction(res)), 0.5, abs_tol=0.1), 'GT2 memberships not correctly reduced' + + + + +if __name__ == '__main__': + test_fuzzy_t1_memberships() + test_fuzzy_t2_memberships() + test_fuzzy_gt2_memberships() \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..6a9ff2e --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,102 @@ +import numpy as np +import math +import sys + +sys.path.append('./ex_fuzzy/') +sys.path.append('../ex_fuzzy/') +import ex_fuzzy as ex_fuzzy + +sample_size = 10000 +tolerate = 0.05 +def test_quartiles(): + sample = np.random.random_sample(sample_size) + targets = [0, 0.25, 0.5, 1] + quartiles = ex_fuzzy.utils.quartile_compute(sample) + for ix, target in enumerate(targets): + assert math.isclose(quartiles[ix], target, abs_tol=tolerate), 'Not the correct ' +str(target) + ' quartile.' + +def test_quantiles(): + sample = np.random.random_sample(sample_size) + targets = [0, 0.20, 0.30, 0.45, 0.55, 0.7, 0.8, 1] + quartiles = ex_fuzzy.utils.fixed_quantile_compute(sample) + for ix, target in enumerate(targets): + assert math.isclose(quartiles[ix], target, abs_tol=tolerate), 'Not the correct ' +str(target) + ' quartile.' + +def test_3_partitions(): + sample = np.random.random_sample(sample_size) + targets = [0, 0.20, 0.50, 0.80, 1.00] + quartiles = ex_fuzzy.utils.partition3_quantile_compute(sample) + for ix, target in enumerate(targets): + assert math.isclose(quartiles[ix], target, abs_tol=tolerate), 'Not the correct ' +str(target) + ' quartile.' + + +def test_construct_partitions_t1(): + sample = np.random.random_sample((sample_size, 1)) + partitions = ex_fuzzy.utils.construct_partitions(sample, ex_fuzzy.fuzzy_sets.FUZZY_SETS.t1) + assert len(partitions[0]) == 3, 'Not the correct number of partitions' + assert math.isclose(partitions[0](0.01)[0], 1, abs_tol=tolerate), 'Not the correct partition' + + +def test_construct_partitions_t2(): + sample = np.random.random_sample((sample_size, 1)) + partitions = ex_fuzzy.utils.construct_partitions(sample, ex_fuzzy.fuzzy_sets.FUZZY_SETS.t2) + assert len(partitions[0]) == 3, 'Not the correct number of partitions' + assert math.isclose(partitions[0](0.01)[0][0], 0.8, abs_tol=tolerate), 'Not the correct partition' + assert math.isclose(partitions[0](0.01)[0][1], 1, abs_tol=tolerate), 'Not the correct partition' + + +def test_construct_partitions_gt2(): + sample = np.random.random_sample((sample_size, 1)) + partitions = ex_fuzzy.utils.construct_partitions(sample, ex_fuzzy.fuzzy_sets.FUZZY_SETS.gt2) + assert len(partitions[0]) == 3, 'Not the correct number of partitions' + assert math.isclose(np.mean(partitions[0][0].alpha_reduction(partitions[0](0.1)[0])), 0.9, abs_tol=tolerate), 'Not the correct partition' + + +def test_temporal_conditional(): + sample_size = 10 + sample = np.random.random_sample((sample_size, )) + + first_temp = int(sample_size / 2) + + sample[:first_temp] = sample[:first_temp] * 0.5 + time_labels = [0] * sample_size + time_labels[first_temp:] = [1] * first_temp + + vl1 = ex_fuzzy.fuzzy_sets.FS('',[0, 0.20, 0.30, 0.5], [0, 1]) + vl2 = ex_fuzzy.fuzzy_sets.FS('',[0.5, 0.70, 0.80, 1], [0, 1]) + + conditional_frequencies = ex_fuzzy.utils.construct_conditional_frequencies(sample, time_labels, [vl1, vl2]) + + assert conditional_frequencies[0, 0] > conditional_frequencies[0, 1] + assert conditional_frequencies[1, 0] < conditional_frequencies[1, 1] + + +def test_temporal_assemble(): + sample_size = 1000 + sample = np.random.random_sample((sample_size, 5)) + y = np.random.randint(0, 2, sample_size) + + temp_moments1 = np.random.randint(0, 2, sample_size) + temp_moments2 = 1 - temp_moments1 + temp_moments = [temp_moments1, temp_moments2] + + [X_train, X_test, y_train, y_test], [train_temporal_boolean_markers, test_temporal_boolean_markers] = ex_fuzzy.utils.temporal_assemble(sample, y, temp_moments) + + t1test = [y_test[jx] for jx, aux in enumerate(test_temporal_boolean_markers[0]) if aux] + t2test = [y_test[jx] for jx, aux in enumerate(test_temporal_boolean_markers[1]) if aux] + + assert len(t1test) == len(t2test) + + + + +if __name__ == '__main__': + test_quartiles() + test_quantiles() + test_3_partitions() + test_construct_partitions_t1() + test_construct_partitions_t2() + test_construct_partitions_gt2() + test_temporal_conditional() + test_temporal_assemble() + print('All tests passed.') \ No newline at end of file