1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
// < begin copyright > // Copyright Ryan Marcus 2019 // // This file is part of plr. // // plr is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // plr is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with plr. If not, see <http://www.gnu.org/licenses/>. // // < end copyright > #![allow(clippy::needless_return)] //! This crate provides code for performing error-bounded piecewise linear regression (PLR) in an //! online fashion using either a [greedy](struct.GreedyPLR.html) (constant time per point, constant //! space) or [optimal](struct.OptimalPLR.html) (linear time per point, linear space) algorithm. Both //! algorithms were implemented as described in: //! //! > Qing Xie, Chaoyi Pang, Xiaofang Zhou, Xiangliang Zhang, and Ke Deng. 2014. Maximum error-bounded Piecewise Linear Representation for online stream approximation. The VLDB Journal 23, 6 (December 2014), 915–937. DOI: https://doi.org/10.1007/s00778-014-0355-0 //! //! Error-bounded piecewise linear regression is the task of taking a set of datapoints and finding a //! piecewise linear function that approximates each datapoint within a fixed bound. In other words, //! given a dataset `(x, y) ∈ D`, we seek a piecewise linear function `f` such that //! `∀(x, y)∈D(|f(x) - y| < δ)`, for some given δ. This can also be thought of as minimizing the //! "L-infinity" loss. //! Since `f` could be trivially realized by a piecewise linear function with `|D|` pieces, we also seek //! the `f` with a minimal number of pieces. //! //! <div> //! <img src="data:image/png;base64, //! iVBORw0KGgoAAAANSUhEUgAABaAAAAFoCAYAAAChVFwCAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz //! AAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0 //! dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nOzdeVhU1f8H8PewCyqIiAsqCH5TQwUV //! FUXFJdMUFff1Ky7h10pzrVxQ1NwqNZcyy7XUCkXCLTPLfaG0cMk9glTSXHBJRBb5/P7wN8QwKzAL //! y/v1PPM8es+5935mmDn33s899xyFiAiIiIiIiIiIiIiIiIzMytIBEBEREREREREREVHJxAQ0ERER //! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER //! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER //! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER //! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0ERER //! EREREREREZkEE9BEREREREREREREZBJMQBMRERERERERERGRSTABTUREREREREREREQmwQQ0USmk //! UCjQtm3bQm+nbdu2UCgUhQ8on5KSkqBQKDBs2DCjbM9Yn4e53bt3D66urnj99dctHUqJIiLw8/ND //! 69atLR0KFROWagt1OXjwIBQKBWbNmmXpUKiUOHDgABQKBbZs2WLpUMjEYmJioFAo8OOPP1o6FItg //! m09UMOvXr4dCocDPP/9s6VCoCOrevTt8fHyQkZFh6VDIRJiAJirCTp06heHDh8Pb2xtlypRB+fLl //! 0aBBA7z11ltITk62dHiUi7GT4oaIjIxEWloaIiIizLZPXaKjozF27Fi0bt0a5cuXh0KhwJAhQ/Su //! d/z4cXTp0gWurq4oU6YMGjZsiKVLl+LZs2da19m1axfatm0LZ2dnlC1bFs2bN8fnn3+ucz+ff/45 //! mjVrhrJly8LZ2Rlt27bFrl271OopFArMmTMHR48eRXR0tP43ThZjrjZy2LBhUCgUSEpKMto2ixpl //! 8iL3y87ODtWrV0ffvn1x4sQJjfUNuXmnbB9zv2xsbODu7o7OnTtj+/btRn0vx44dQ2hoKKpWrQpb //! W1uUK1cOtWvXxqhRo3D9+nWj7qsw0tLSEBkZiTp16sDBwQHu7u7o168fLl68mO9tPXv2DB9++CEa //! NmyIMmXKwNXVFV26dMHx48c11ld+p7W9Ll26lK/9Z2dnY8KECfDz80Pfvn1zlmv622t6HTlyJN/v //! mfJv1qxZUCgUOHjwYKG207NnTzRu3BgTJ05Edna2cYIzANt842Gbb36WbPMLsn/ljRZtr6dPn+Yr //! 5sePH2PatGno1q0bmjVrlrM8NTUVmzdvxqBBg1C3bl04OTmhXLlyCAgIwOLFizUmI5OTk7FixQq8 //! 8sor8PLygr29PSpWrIiOHTsiJiYmX3FR4Xl5ecHLy6vQ25kzZw4SExOxfPnywgdFRZKNpQMgInUi //! gilTpuD999+HjY0NOnbsiL59+yIjIwPHjx/HokWLsHLlSnz++efo06dPvrd/8eJFODo6FjrOL774 //! Ak+ePCn0dij/rl27hk8//RTDhw9HtWrVLB0OAGDu3Lk4c+YMypYti+rVqxuUwNi+fTt69+4NBwcH //! 9O/fH66urti5cycmTJiAY8eOYevWrWrrfPTRRxg7diwqVqyIIUOGwM7ODtHR0Rg2bBjOnTuHRYsW //! qa0zefJkLF68GNWrV0d4eDgyMjLw9ddfo1u3blixYgXGjBmjUr9Hjx6oV68epk+fjt69exe5nk6l //! nanbyPwqSW2hp6dnzo201NRUxMXFITo6GjExMYiOjkbPnj0LvG1nZ2eMHz8eAJCeno7z589j165d //! 2Lt3Lz744ANMnjy50PFfvnwZ7du3R3Z2NkJDQ1G7dm1YWVnh3r17OHnyJH799VfUqFGj0PsprPT0 //! dHTs2BHHjh1DQEAAxo0bh+vXr2Pr1q3YvXs39u/fj+bNmxu0LRHBgAEDEB0djTp16mDMmDFISUlB //! VFQU2rRpg23btqFHjx4a1x03bhxcXFzUlru5ueXr/Xz99dc4c+YMNm/erNJeuri4IDIyUuM6169f //! x7p161CxYkWVZAQVfQqFAu+88w769++Pr7/+GoMGDTLp/tjmmw7bfPOwdJtfmP1ra8NtbPKXSlq+ //! fDlu3bqFKVOmqCw/cuQIhgwZAldXV7Rr1w6hoaG4f/8+duzYgcmTJyMmJgY//vgjHBwcctZZsWIF //! 3nvvPdSqVQvt2rVDlSpV8OeffyImJgY//PADJkyYgCVLluQrPrI8f39/dO7cGfPmzcPrr79ulHwF //! FTFCREXO7NmzBYB4eXnJb7/9plYeHR0tDg4OYm1tLfv377dAhJaVmJgoACQsLMwo2wMgwcHBRSom //! faZNmyYA5NixY2bZnyH2798vV65ckezsbDlw4IAAkMGDB2ut//DhQ6lUqZLY2dnJyZMnc5anpaVJ //! ixYtBIB89dVXKuskJiaKvb29uLq6SmJiYs7ylJQU8fHxEQBy/PhxlXWOHTsmAMTHx0dSUlJUtuXq //! 6ir29vYq21JauHChAJB9+/bl85MgUzN3GxkWFiYANH5PiirlbzAyMjJf9TW1hTNnzhQAUqtWLYPq //! 56VsHz09PdXKvvrqKwEgjo6OkpqaalCsumzatEkAyKhRozSWZ2ZmFnofxjB//nwBIH369JFnz57l //! LI+NjRUA8uKLL6os1+XLL78UANKyZUtJS0vLWf7zzz+LnZ2dVKpUSR49eqSyjrG/0y1btpTy5cvL //! kydPDF5nypQpAkAmTJhglBhIv8jISAEgBw4cKPS20tLSxMXFRYKCggofmB5s8/Vjm882X1ebX5D9 //! BwcHi7HSRVlZWVKjRg154YUX1Mri4+Nl06ZNkp6errL80aNH0rhxYwEgixYtUinbtm2bHDx4UG1b //! Fy5ckPLlywsAOXXqlFFiJ/08PT01/t4L4uuvvxYAsnr1aqNsj4oWJqCJipjExESxsbERW1tbOXv2 //! rNZ6n3zyiQCQOnXqqJwwrF+/XgDI+vXrZc+ePRIcHJxzIFbSdgL5119/ybBhw6RSpUri4OAgfn5+ //! smHDBq0ntZpOTHLXjY+Ply5duoizs7OUKVNG2rRpozFhmpycLLNnz5aWLVtK5cqVxdbWVqpWrSoD //! Bw6U8+fPa/yM8pvsTU9Plzlz5oi3t7fY2dmJl5eXTJ8+XZ4+farx88hPTMoLOk2v9evX5+x/xYoV //! 8sorr0jNmjXFzs5OKlSoIB06dJBvv/3W4PchIpKdnS1Vq1aVGjVqaCzPfeG0atUqqV+/vtjb24u7 //! u7uEh4fLgwcP8rW/gjAkAb127VoBIEOHDlUr+/HHHwWAtGnTRmX5jBkzBIDMnDnT4O3997//FQCy //! bt06tXV0bS8pKUkAyIABA7S+BzI/Y7aRu3btkhYtWoijo6O4uLhI79695cqVKyrb0fbbzn2ira8t //! PHnypHTq1EnKly8vLi4u0qtXL7l27ZqIiCQkJEj//v3Fzc1NHBwcpG3btnL69Gm193P58mV55513 //! pEmTJuLm5iZ2dnZSs2ZNCQ8Pl+vXr6vVN2Yy4u+//85537dv39ZbPy9dyYjs7GxxcnISACo3ogrq //! xo0b4urqKra2tjJy5EiJjo6WW7duFXq7xpSdnS01a9YUAPLHH3+olbdu3VoAGJxI01VfW/tnzATb //! xYsXBYAMGTLE4HUyMjKkSpUqAkAuXrxo8HoJCQkSHh4uPj4+4uDgIBUqVJD69evL//73P7l7965a //! /S+//FLatm0rzs7OYm9vL3Xr1pV3331Xnj59qnH7mzZtkkaNGomDg4NUqlRJhgwZIsnJyWb5jYuI //! pKamyvz588XPz08cHR3FyclJAgMD5csvv1Srm9/zLU9PT63tmdKtW7dk0qRJ8sILL4ijo6M4OzvL //! Cy+8IGFhYZKQkKAWw7Bhw/L9N8wvtvls83Vhm69KU5tf0P0bMwG9Z88eASARERH5Wm/z5s0CQEJC //! QgxeJzw8XGPSWpft27dL+/btpUqVKmJnZydVq1aVNm3ayMcff6xW9969ezJlyhSpW7euODg4SPny //! 5aV9+/ayd+9ejdt+8OCBjBs3Tjw8PMTe3l7q1KkjixcvloSEBI3Xs8rj8x9//CErVqyQevXqib29 //! vXh6esq8efMkOztbRES2bNkiTZs2FUdHR6lUqZK88cYbWm8CX7x4UcLCwqR69epia2sr7u7uMnDg //! QLl06ZJa3fxcRyrbBU2v3O/r8OHDEhISIh4eHmJnZyeVK1eW5s2by6xZs9T2n5aWJg4ODhIYGKjx //! vVDxxjGgiYqY9evXIysrCz179kSDBg201nv11VdRtWpVXL58GYcOHVIrj46ORkhICMqVK4fRo0ej //! f//+Ovd7+/ZttGjRAhs2bEC9evUwfvx4NGrUCK+//jqWLVuW7/dx6tQptGzZEk+fPsWrr76KkJAQ //! HD16FB06dMDly5dV6h4+fBgLFy6Ei4sLevfujQkTJiAwMBDR0dFo1qwZzpw5k+/95yYi6NevH2bO //! nAmFQoExY8YgJCQE69atQ79+/TSuk5+Y2rZti3HjxgEA/Pz8EBkZmfPy9/cHAKSkpGDcuHH4559/ //! 0LFjR0ycOBHdu3dHfHw8unTpgjVr1hj8fs6fP4+bN28iKChIZ723334bb7/9Nvz8/PDGG2/Aw8MD //! q1evLtTjlMa0f/9+AEDnzp3Vytq0aQNHR0ccP34c6enpBq3zyiuvqNQpzDrA88dSPTw88MMPP0BE //! DHpPZHrGaiNjYmIQGhqK6tWrY9y4cWjRogW2bduGwMBAlTYqMjISfn5+AJ4PV6D8bSsfK9bn5MmT //! ORNahoeHo1mzZoiJicFLL72ES5cuoVmzZrhx4waGDh2Krl274tChQ+jYsSMeP36sFu+qVatQo0YN //! DBw4EGPHjsWLL76INWvWoGnTpiadFyD399+Uw9HY2toWehseHh7Ytm0bnJ2dUbduXZw9exZ9+vRB //! kyZNsG3bNiNEWXgJCQm4du0aXnjhBdSqVUutXFe7lNfTp09x/PhxODo6apw4Vd+29uzZg/feew+L //! Fi1CbGwsHj16lJ+3AgD44YcfAACtWrUyeJ0dO3bg1q1baNOmDerWrWvQOjdv3kTTpk2xfv16+Pr6 //! 4s0338R///tf1KpVCxs3bsTNmzdV6o8YMQKDBg3C77//jt69e+ONN96Aq6srZsyYgc6dOyMrK0ul //! /vvvv48hQ4YgKSkJYWFhGD58OM6fP4+goCA8ePBAa1zG+o0/ePAArVq1wrRp02BtbY0RI0YgLCwM //! d+7cwaBBg7TO92Do+db48eMRHBwMAAgLC1M5VwGAJ0+eICgoCIsXL4anpydee+01jBw5Eg0aNMD2 //! 7dtx4cIFtX0rz0OU3wFTYJvPNl8Xtvn6t1XY/UdFRWHhwoVYsmQJ9uzZo3JebqiCHCeAf78j+Rnu //! I7/rfPbZZ+jRowcuXLiAbt26YdKkSejSpQvS0tKwfv16lbp//vknmjRpgoULF6JSpUo519gXL15E //! 586dsXr1apX6T58+Rfv27bFs2TK4u7tj3LhxaNu2LebNm4dJkybpjGvy5MmIjIxEs2bNMHr0aFhZ //! WWH69OmYPXs2li9fjrCwMNSuXRujR49GlSpV8PHHH2PixIlq2/nuu+/QuHFjbN68GU2bNsX48ePR //! oUMHxMTEoFmzZvj111817t+Q60gvLy9ERkbC2dkZzs7OKseV0NDQnP23bds257g0adIkhIaGwt7e //! HitXrlTbr4ODA5o0aYKTJ0/i4cOHOj8jKoYsm/8morzat28vAOSzzz7TW3fQoEECQN59992cZcqe //! HgqFQvbs2aNxPWjowTBixAgBIG+//bbK8tOnT4udnV2+e0AjV+9fpVWrVgkAee2111SW//3332qP //! iin37eTkJJ07d1ZZnt8e0Mq754GBgSqPqt27d0+8vb01fh7Gjunp06cae6w8ePBAfH19pUKFCgY/ //! uqzs5aPtzr7yznWNGjXkzz//zFmemZmZ08vhp59+Ulnnm2++kcjISINfH374oc4YDekBHRAQoPMR //! OV9fXwEgFy5cyFnm5uYmADT2dBORnF41ysc6Hz9+LACkbNmyGuvfuXNHAIi7u7vG8tDQUAGgsSc+ //! WYax2kgAsnPnTpX6S5cuFQDSvn17leX6eovqaws3bdqkUqZsbytUqCBz585VKZszZ44AkKVLl6os //! v3HjhsZem3v37hUrKysZPXq0xv0bozec8kkBb29vg+rnpas33MaNGwWAVKpUSaV9LqgLFy6Iq6ur //! 7N69W2X5F198IQqFQsaNG2fwttavX5+vdjHvMU+bXbt26ezRtXXrVgEg/fr107ut3377TQBI/fr1 //! NZafPHlSAEizZs1Uliu/03lf5cqVk48++sig96HUv39/nW25Ji+//LIAkM2bNxu8zvLlyzX+NkSe //! t/W5j6HK33nPnj3Vjq3Kp5ZybychIUFsbGzEzc0tp6eqyPOegwMGDFDrKSxi/N+48m/y3nvvqSxP //! S0uTTp06iUKhkPj4eI37N/R8S9cQHDt27BAAMn78eLWy9PR0redEAKRv375qZcbCNl8V23xVbPNV //! aWrzC7p/5fc878vd3V22bt2qN9bcmjdvrvP8XZvOnTsLAFm1apVB9R8+fCiVK1cWhUKhcv2gS+PG //! jcXOzk7+/vtvtbI7d+6o/D84OFgUCoXaEIH3798XPz8/cXBwUOmBr/x9DxgwIKfnsojItWvXcq5p //! tPWA9vT0lBs3bqjso2LFiuLo6Chubm4q7+/p06dSr149tfeRkpIiLi4uUrFiRbVrmXPnzomTk5M0 //! atRI4/7zcx2pawiOXr16CQCNT3rk/XyVxo8fLwDUftdU/DEBTVTE1KtXTwBoTR7n9s4776hdYChP //! tENDQ7Wul/cEMj09XcqUKSPOzs4aLzBeffXVfCegNY0JmJGRITY2NtKkSRO9702pW7duYm9vLxkZ //! GTnL8puAfumllwTQ/Kia8vPKzxjQxogpt8WLFwsAOXTokEH1p06dqvPCXXnioGnsrHXr1gkAWbFi //! hcZ1DH3pG+fLkAT0f/7zHwEgV69e1VjesmVLAVTHdLa1tRUAWsf0q1atmgCQv/76S0SeD6UCQDw8 //! PDTWz8jIEABiZ2ensXz06NEG/x7JPIzVRuZNOIg8H6NQOZZ4UlJSzvLCJCNatWqlVv/QoUMCPB/P //! NCsrS6VMOfTLsGHD9L4/pQYNGqiM1Zl7//lNRnh6euZcXE+ePDnnYsPKykpiYmLU6ucnGeHs7Jyz //! 7SlTpkhISIgoFAqxs7NT2XZhNG3aVPz9/TWWDRw4UADIL7/8YtC2tF18a3sZehxR3hTV1j5+//33 //! AkBefvllvdtSjnGvbRzeK1euCAC1cTfXrl0rUVFR8ueff0paWpokJCTIokWLpFy5cgJAPv30U4Pe //! i4jkjNmfnJxsUP3ExERRKBRSsWJFrUNhaKJMQBsSm7+/v9jY2Mj9+/fVyrKysqRixYrStGnTnGXv //! vvuuAJDZs2er1U9KShJra2uT/sbv3r0r1tbWEhAQoPH9KBO9b731ltr+83O+ZUgCeurUqRpj0OTW //! rVsCQJo3b27wOvnFNl8d2/x/sc1XpanNL+j+lyxZIjt37pQbN25IWlqaXLp0SaZOnSp2dnZiZWWV //! r3PjqlWriq2trcH1RURWrFghAMTf31/lmkub7Oxs6du3rwCQ119/3eD9NG7cWBwdHVXmidFE2Q73 //! 6dNHY7lyPO3cw3b4+PiIlZWVxrZk7ty5OhPQa9asUVtn+PDhAkBmzJihVjZr1iwBoDI2tvImm7Yb //! y8pEb+7kdEGuIw1JQF++fFljuSbKeXg++eQTg9eh4iF/U5cSUbGRnxnlL1++jLS0NAQEBKBcuXJq //! 5a1atcrXEBEAEBAQoLbM1tYWlStXxv3799XKdu/ejVWrVuHUqVO4e/eu2qOxd+/eRdWqVfMVg9Kv //! v/4KKysrjY99tW3bVut6xo7p/Pnz+OCDD3D48GHcvHkTT58+VSk39HHKe/fuAQAqVKigs56mv4Fy //! JvC8f4MNGzZgw4YNBu2/NHF1dQXw/G9NJYvyUfTcrK2t0apVKyQkJCA+Ph6enp6F3o+m32G1atUA //! PJ/t29raWqXMw8MDAHDjxg2V5SKCzZs3Y8OGDThz5gzu37+PZ8+e5ZTb2dkVOlbg+eOls2fPBvD8 //! 8dVKlSqhV69emDRpElq2bFmobT98+DBn20r29vbYvn07OnXqVKhtA0B8fDxOnjyJ4cOHayzv2LEj //! vvrqK+zcuRONGzfWu72DBw8WOqaiasSIESr/9/b2xqRJk1CnTh1069YN06dPx8iRI9W+n5oYekxS //! Wr16NUQEYWFhsLe3Nzjm7t27Y9q0aXjjjTewd+9edOrUCUFBQXjxxRdVhgl48uQJzpw5Azc3Nyxd //! ulTjtuzt7XHx4sWc/8fHxwPQ/Hi4p6cnatSogaSkJI3bMsZv/OTJk3j27BkUCgVmzZqltr3MzEwA //! UIlZ1/51nW9pExwcDA8PDyxcuBC//vorunTpgqCgII3vQak4HSPZ5mvGNv9fJbnNL4gJEyao/L9O //! nTqYP38+qlWrhrFjx2Lq1Kkah7fT5N69ewYfI4DnQ9CMHz8eVapUwbZt2wwarmXSpEnYunUrWrdu //! jSVLlhi8r8GDB2PSpEl48cUXMWDAAAQHByMoKAiVKlVSqXfixAkAz7/XmtrpO3fuAPi3nX706BES //! EhJQo0YNeHl5qdXXNxyJrrakSZMmamWa2hJlzGfOnNEY85UrV3JifvHFF/XuX9t1pC6DBw9GTEwM //! mjdvjv79+6Ndu3YICgpC9erVta5TnI4tlD9MQBMVMVWqVMHFixdx/fp1vXWVdZQHo7zbMZRyfKXK //! lStrLNe2XBcXFxeNy21sbFROoAFg2bJlGD9+PCpUqICOHTuiZs2acHR0hEKhQGxsLM6cOVOg8caU //! Hj58CFdXV40nL9o+J2PHFBcXh/bt2yMrKwsdOnRA9+7dUb58eVhZWeH06dPYvn27wdsrU6YMAKgl //! sPPS9DdQjoeW929gCc7OzgCgdXwv5fLc78PZ2Rl3797Fw4cPUbFiRa3rKLddkH3klpaWBuDfz5ws //! z1htpLZ2TdkmGGvcOeV3MDfl71BXmTLhpDRx4kQsXboUVatWRadOneDh4ZHzvdywYQP+/PNPo8Qb //! HBxssotwT0/PnCTeo0ePsG/fPrz66qvo168fTpw4oXbxk1+XLl0C8O+FS17KG4aGfHdMqbDtkqm2 //! BQAhISHw8PBAcnIyLly4oHPMXaXcxyR9bWVWVlbOmJqjRo0yKCYlT09P/Pzzz5g1axa+++47xMTE //! AHh+QTx58mS8+eabAJ5fGIsI7ty5o5b80saQ8yBtCWhj/MaVSfyTJ0/i5MmTWuPMO04wkL/zLV3K //! ly+PuLg4REZGYseOHdi7dy8AwM3NDa+//joiIiLUzqPMcYxkm882Xxu2+YZty9jHiVdffRUTJkzA //! 6dOn8c8//2jsvJRXmTJl9F63KMXGxmLAgAFwd3fHgQMH4O3trXedt99+Gx9++CHatGmD3bt35+vm //! 5sSJE+Hm5oaVK1di+fLlWLp0KRQKBYKDg/HBBx/kJGKV7fS+ffuwb98+rdtTttPKORUKen1tzGNL //! 3rGptcWcm7GuI3v16oVdu3Zh8eLFWLduHT799FMAz5PoCxYsQMeOHdXW4fVXycUENFER06pVKxw4 //! cAA//PADwsPDtdZ79uxZzgmjpsno8jNpSPny5QEAf//9t8ZybcuNISsrC7NmzUKVKlXw66+/qvUo //! Vt65LQxnZ2ekpKQgMzNT7eLp1q1bZolp7ty5SEtLw4EDB9R6XS9YsADbt283eFvu7u4A/j2pMIbY //! 2FicPn3a4PouLi4GT8ijTZ06dXDq1ClcuXJF7U5+VlYWEhMTYWNjo3LiWadOHdy9exdXrlxBixYt //! VNa5efMmUlNTUb16dTg6OgIAnJyccpIpN2/eVPtbXr16FQDwwgsvaIxR+RkrP3OyPGO1kdraNWWb //! oOnk3lJu376N5cuXo379+jh+/Ljaxd5XX31locgKrnz58ujduzccHBwQEhKCoUOH4uTJk4Wa8MrB //! wQEA8Ndff2ksVy43tOfghg0btCYdNfHy8sKwYcP01qtTpw6Af3se5aWvXcrNx8cH1tbW+OOPP5CV //! laU26VJ+tqVUqVIlJCcnIzU11aD6uY9J+nq47dy5Ezdv3kRwcHDO55Af9erVQ1RUFLKysnDmzBn8 //! 8MMPWLFiBcaNGwcnJyeMHDky57fbqFEjrZMr5ZX7PMjX11et3JTnQcC/7c2ECRPy1XPP2KpXr461 //! a9dCRHDhwgXs378fH3/8MebMmYPs7Gy8++67KvXNcYxkm882Xxu2+Ya1+cbcP/D8cy9Xrhzu37+P //! 1NRUgxLQ7u7uuHr1qsZrsdy2bt2KQYMGoUqVKti/fz/+85//6N32hAkTsHTpUrRr1w67du3KuQbI //! j6FDh2Lo0KF48OABjh8/jm+++Qbr1q1Dp06dcOnSJVSqVCmnjVi2bFnODU9dLHl9raSM+cyZM2jY //! sKHJ96dN165d0bVrV6SmpuKnn37Crl278MknnyAkJATx8fFqN6N4/VVyMQFNVMQMGzYM8+fPxzff //! fIPz589rvBACgHXr1uGvv/5CnTp1ND5WmB9169ZFmTJlcPbsWY13so8ePVqo7ety9+5dPHjwAL16 //! 9VJLDj5+/Njgi0ddGjdujB9++AFHjx5Fu3btVMo09fooSEzKRyq13RH+/fff4erqqnHID02zteui //! PIFQ9vwwhtjYWHz++ecG1/f09Cx0Arp9+/bYvHkzvvvuOwwcOFCl7PDhw3jy5AnatGmj0ouhffv2 //! OHbsGL777ju1BPSePXty6uTdz8aNG/Hdd9+pPaapbR2lS5cuwcrKyqBegGQexmojNf3unj17ltPe //! NWrUKGe5vt+3qf3xxx/Izm97bc0AACAASURBVM7Gyy+/rNY+37hxA3/88YdF4jKGrl27onPnzvju //! u+/w5ZdfYvDgwQXelvJ3evjwYWRkZKglHb7//nsA0PqdyWvDhg35ap+Dg4MNSkb4+PigZs2auHLl //! ChITE1GrVi2Vcn3tUm4ODg5o2bIljhw5giNHjqgd4/KzLeB5T7hLly5BoVCoxaVNw4YNsW/fPly6 //! dAm1a9fWWfezzz4DkP/ez3nZ2NigSZMmaNKkCVq2bIk2bdogNjYWI0eORNmyZeHr64vz588jJSVF //! a+/I3Bo1aoRvvvkGR48eVfus/vzzT5P3oGzWrBmsrKxw5MgRk+7H0LZMoVDA19cXvr6+CA0NRc2a //! NREbG6uWgFaeh/j7+5smYLDNZ5uvHdt8w9p8Y+4feD504/3791GuXDm4ubkZtE7Dhg1x9epVXL58 //! GfXr19dYZ/PmzQgLC4OHh4dBPZ9FBGPGjMHKlSvRsWNHbN++vdA9Zl1cXNClSxd06dIF2dnZWLdu //! HQ4fPozevXsjMDAQAHDkyBGDE9De3t5ISkpCUlKS2jAcpry+VgoMDMS2bdtw5MgRkyagra2tkZGR //! obeek5MT2rdvj/bt26NChQqYOXMm9uzZo5aANsexhSzDytIBEJEqb29vTJs2DZmZmejevTsuXLig //! Vic2Nhbjxo2DtbU1PvnkE1hZFe6nbGdnh/79++Phw4eYO3euStmZM2fwxRdfFGr7uri7u8PR0RG/ //! /PKLyuM/mZmZGDdunFHGflImHadPn67y+FdKSora+y1oTBUqVIBCocC1a9c0xuDl5YWUlBScPXtW //! ZfnatWtzHnM1VOvWrWFtbY24uLh8rafLhg0bIM8npjXolZ8eItr06dMHbm5u+Prrr3Hq1Kmc5U+f //! PkVERAQA4LXXXlNZZ/jw4bC3t8dHH32kEsP9+/cxf/58AMDo0aNV1lH+f968eSpjliUlJeHjjz+G //! vb29xvED09PTcfr0aTRq1MjgxxLJ9IzVRu7fvx+7du1SWfbRRx8hISEB7dq1UxkLVDnci7bft6kp //! L1qOHj2qkhB5/PgxwsPD1canL26USa3IyEi19+Ll5QWFQmFQm1O7dm20atUKycnJeP/991XKDh8+ //! jK1bt8LR0RH9+vUzKK6DBw/mq1009DF2hUKR0y69/fbbyM7Ozinbvn07jhw5ghdffFEtiXbt2jVc //! unQJT548UVmubCcjIiJUjnEnT55EVFQUKlWqhN69e+csv3Xrltp4s8Dz79OwYcPw9OlTvPTSSwYP //! v6W8sarvmPTnn3/i+++/R8WKFVXiMdQvv/yi8RFyZS+y3L3eJk6ciIyMDIwYMQIPHjxQW+f+/fsq //! N5MHDRoEGxsbrFixQiXZLCKYOnWqyROR7u7uGDx4ME6dOoV3331X4/4SEhKQmJhYqP3oasvOnz+v //! sUeeps9XSfk3z5sEMya2+WzztWGbb1ibX5D9JyYmIiUlRe293LlzJ+ececCAAWo9sLXRd5z4/PPP //! MXToUNSsWROHDx82KPk8atQorFy5Eq+88gp27NhR4OTzgQMHICJqy2/fvg3g37YvICAArVu3RkxM //! DNatW6dxW+fOnctZD3jeszo7OxtTp05V2cf169e1zlFgTMOHD4eLiwtmz56Nn3/+Wa08OzvbKEPw //! VKxYEXfu3MkZOiO3w4cPa2yz9B1b3NzctN6soOKLPaCJiqBZs2YhNTUVS5YsgZ+fHzp16gRfX19k //! Zmbi+PHj+Omnn1CmTBl89dVXRjvpX7hwIfbv34/3338fP/30E1q2bImbN29iy5Yt6NKlC2JjYwud //! 6NbEysoKb775JhYuXIgGDRqgR48eyMjIwIEDB5CSkoJ27drhwIEDhdrHwIEDERUVhR07dqB+/fro //! 0aMHMjMzER0djaZNmyIhIaHQMZUtWxbNmzfHkSNHMHjwYLzwwguwtrZG9+7d0bBhQ4wfPx579+5F //! q1at0K9fPzg7O+PUqVM4evQo+vTpg+joaIPfj7OzMzp06ICDBw/i/v37+ZrUw5RiY2MRGxsL4N9H //! Wk+cOJHTO8TNzQ2LFi3KqV++fHmsXr0affr0Qdu2bTFgwAC4urpix44duHz5Mvr06YP+/fur7KNW //! rVr44IMP8OabbyIgIAD9+/eHnZ0doqOjcePGDUyaNEmtZ3TLli0xceJELFmyBA0bNkSfPn2QkZGB //! qKgopKSkYMWKFRonBzl48CAyMjIKlCgh0zJGG9mtWzf07NkTPXv2RO3atXH69Gns2bMHrq6uWLly //! pUrdDh064IMPPkB4eDh69+6NcuXKwcXFBWPGjDHH20WVKlUwYMAAfP311/D398fLL7+Mhw8fYt++ //! fXBwcIC/v3++htAxpkuXLmntAVazZk3MmTNH7zYCAgLQo0cPbN++HWvXrsX//ve/nDLlhbKhF7nr //! 1q1D69atMWPGDBw4cADNmzfHtWvXsGXLFigUCqxZs0ZtYiFLmDhxInbt2oXo6Gg0b94cHTp0wLVr //! 13ISJuvWrVM75g4dOhSHDh1SG8ppwIABiImJQXR0NBo1aoRu3brh3r17iIqKwrNnz7B69eqcR4GB //! 53+zl156CS1atMALL7wAd3d3JCcnY9++fbh16xa8vb3zNfFw+/bt4eLigr1792q8qau0Zs0aZGdn //! 53vyQaWNGzfi008/RatWreDj44MKFSogISEBO3fuhL29vcpTOSNGjMAvv/yClStXwsfHB506dULN //! mjWRkpKCxMREHD58GMOHD8eqVasAPO8hOGfOHEybNg1+fn7o378/nJ2dsW/fPqSkpMDPz0/tBrKx //! ffTRR7h69SpmzpyJjRs3olWrVqhcuTL++usvXLx4ESdPnsRXX31lcM90Tdq1awcrKytMnToVv/32 //! W875Q0REBPbt24e33npL5Xtx48YNbN++HVZWVnjrrbfUtvf999/DxcXF4J6TBcU2n22+Nmzz9bf5 //! Bdn/oUOHMHr0aLRq1Qre3t5wdXXFtWvX8O233+Lhw4cICAhQS/rr0qNHj5xroVdffVWl7MCBAxgx //! YgSys7PRrl27nHkCcss79N+cOXOwZs0alClTBv7+/li4cKHaOv7+/ggNDdUbW8+ePVG2bFkEBgbC //! y8sLIoIjR47g5MmTaNKkCV566aWcul9++SXat2+PkSNHYvny5WjevDlcXFxw48YNnD17Fr/99htO //! nDiRM3TE22+/jdjYWHz99de4fPlyzm95y5YtOU/umOL6WqlixYqIjo5Gz549ERgYiA4dOsDX1xcK //! hQLXr1/HiRMncO/ePYPH59amQ4cOOHnyJDp37pzz9Kqfnx+6deuGN998E8nJyQgKCoKXlxfs7Ozw //! yy+/YP/+/fD09MSAAQNUtnX58mVcu3YNo0aNKtQQPVRECREVWT/99JMMHTpUvLy8xMHBQZycnMTX //! 11cmTZok169f17jO+vXrBYCsX79e63YBSHBwsNryGzduyNChQ8XNzU0cHBzEz89PNmzYIFu3bhUA //! 8uGHH6rUDw4OlrzNyIEDBwSAREZGaty3p6eneHp6qizLzMyUxYsXS7169cTBwUEqV64sQ4YMkaSk //! JAkLCxMAkpiYmFM/MTFRAEhYWJjW95hXenq6zJ49W2rVqiV2dnbi6ekp06ZNk6dPn2r8PPIbk4jI //! 1atXJSQkRFxdXUWhUKj9HXbu3CnNmzeXsmXLirOzs3Ts2FEOHTpk0N8sr9jYWAEgK1euVCvTFp+I //! /r9PYURGRgoAra+8f3elo0ePyiuvvCIuLi7i4OAg9evXlyVLlkhWVpbWfe3YsUPatGkjZcuWFUdH //! RwkICJANGzbojG/9+vUSEBAgjo6OUrZsWWnTpo3s3LlTa/2BAweKnZ2d/P333wa9fzK/wraRO3fu //! lMDAQHF0dBRnZ2fp1auXXL58WeN6ixcvlrp164qdnZ3a9zm/baG+NkxTm5SamirTpk0THx8fsbe3 //! l+rVq8vrr78ud+/eLVBbnJeyvqZjg676ul5+fn4q71dbGyAicvr0aVEoFOLh4SFpaWkiIpKSkiJW //! VlYSFBRkUExKN27ckNGjR0uNGjXE1tZWXF1dpVu3bnLs2LF8bcfUUlNTZcaMGVK7dm2xs7MTNzc3 //! 6dOnj5w/f15jfeXf+cCBA2plmZmZsmTJEqlfv744ODiIi4uLvPLKKxrf87Vr12TUqFHSqFEjcXNz //! ExsbGylfvrw0bdpU5s6dK48ePcr3exk/frwAkAsXLmgsz8rKkmrVqgkAuXTpUr63LyISFxcno0eP //! loYNG0qFChXEwcFBfHx8ZNiwYXLu3DmN6+zcuVO6du0qlSpVEltbW6lcubI0bdpUpk+fLhcvXlSr //! /8UXX4i/v7/Y29uLm5ubDB48WJKTk8XX11ecnZ1V6hr7Ny7y/FxlxYoV0qJFCylfvrzY2dlJjRo1 //! pH379vLhhx/K3bt3Ddq/iObzLRGRjRs3ip+fnzg4OOT8VkVELly4IBMmTJAmTZqIm5tbzrlS7969 //! NX6PLl++LABk3LhxGvdvCmzz2eZrwjZfd5tfkP2fPXtWwsLCpH79+uLq6io2NjZSoUIFadWqlSxf //! vlzS09Pz/f5DQ0PF3t5eUlJSVJYrf6P5uYZQXuvoehl6nfjJJ59IaGio1KpVS8qUKSMVKlQQf39/ //! ee+99zQeDx89eiTz5s2Txo0bi5OTkzg4OIiXl5d06dJFPv30U3n8+LFK/fv378vYsWOlatWqYmdn //! J3Xq1JFFixbJTz/9pLEN1XUdp7zW0vSd0HU9mZiYKG+88YbUrl1b7O3tpVy5clKnTh0ZMmSIfPPN //! NwbvX1s78/jxYxk9erR4eHiItbW1yucfFRUlAwYMkNq1a4uTk5OUK1dOfH19Zdq0aXL79m21fUyd //! OlUASHx8vFoZFX8KEQ3PGxAR5TJ9+nTMnz8f3333HTp16mTpcAjPxyVs0KAB7OzsEB8fzzvERnb7 //! 9m14eXlh0KBB+eoJSEXfhg0bMHz4cKxfv96gsRvJcnbs2IEePXpg9+7d6NKli6XDIR0SExNRt25d //! jB49GsuWLbN0OEb16NEjVK5cGf7+/kaZGLmkmDRpEj766CNcvHhR7+PylsQ2v/hgm1+yHT9+HEFB //! QViyZAkmTJhg6XAsbvXq1Rg1ahRWrVql8hRAaZaeng5vb2/Uq1cPP/zwg6XDIRPgGNBElEPTLNLn //! zp3D8uXL4erqWujJDsl4rK2tsWjRIpw5cwYxMTGWDqfEmT9/PqytrdUmXCIi8zl06BD8/f2ZiCgG //! atWqhXHjxuGzzz5DcnKypcMpkDt37iAzM1NlWVZWFiZNmoSnT5+iZ8+eFoqs6Ll58yY++eQTjB07 //! tkgnn6l4YZtfsrVs2RJ9+/bFe++9pzaudUmm6fr62rVrePfdd2FjY4Nu3bpZIKqi6ZNPPsGtW7ew //! ePFiS4dCJsIxoIkoR0BAAGrXro369evDyckJV69exe7du5GdnY1PP/0UDg4Olg6RcunSpQuWLVtW //! 6HG7SJWIoGrVqti4cSOqVq1q6XCISi1egBQvERERcHJyQlJSEjw8PCwdTr5t27YNM2fOxEsvvYQa //! NWogJSUFhw8fxpUrV+Dv74+xY8daOsQiIykpCe+88w7GjRtn6VCoBGGbX/ItWrQI69atQ2JiInx9 //! fS0djln07t0bmZmZaNKkCVxcXJCUlIRdu3bhyZMnWLBgAapVq2bpEIsMe3t7rF27Fn5+fpYOhUyE //! Q3AQUY7Zs2cjNjYWSUlJ+Oeff+Di4oLAwEBMnjxZZfILIqLiio9jE5Em8fHxePfdd/Hzzz/j3r17 //! AJ737O7VqxfeeecdlCtXzsIRUkGwzSciS1q5ciU2btyIq1ev4uHDhyhbtiwaNWqEMWPGoFevXpYO //! j8ismIAmIiIiIiIiIiIiIpPgGNBEREREREREREREZBIcA5pKFDc3N3h5eVk6DCKiIicpKQl37961 //! dBgWx+MEEZFmPE48x+MEEZFmPE5QYTABTSWKl5cXTp06ZekwiIiKnICAAEuHUCTwOEFEpBmPE8/x //! OEFEpBmPE1QYHIKDiIiIiIiIiIiIiEyCCWgiIiIiIiIiIiIiMgkmoImIiIiIiIiIiIjIJJiAJiIi //! IiIiIiIiIiKTYAKaiIiIiIiIiIiIiEyCCWgiIiIyqxs3bmDs2LFo0aIFHB0doVAokJSUZNC62dnZ //! WLBgAby8vODg4AA/Pz9s27bNtAETERERERFRgTEBTUbHxAIREeny+++/Y8uWLahQoQJat26dr3Vn //! zJiBWbNmYcyYMdizZw8CAwPRt29ffPvttyaKloiIzI3XE0RERCULE9BkdEwsEBGRLm3atMHff/+N //! b7/9Fn379jV4vdu3b2PRokWYMmUKJk+ejHbt2uHTTz9Fu3btMGXKFBNGTERE5sTrCSIiopLFxtIB //! UMmjTCwAwJo1a/D9998btF7exAIAtGvXDr///jumTJmCLl26mCxmIiIyHyurgt3/3rt3LzIyMjBk //! yBCV5UOGDMGIESOQmJiIWrVqGSNEIiKyIF5PEBERlSxMQJPRMbFQfETEnsOmuGsG1w/yccXm8BYm //! jIiISLvz58/D3t4etWvXVlnu6+sLALhw4QKPE0XB2S3Y/f0kLHMpi1s21qiS9QzjbKuga9gBS0dG //! RMUEryeKn/VvH0HK9S+B7OsqyxVW1pj41XYLRUVEREUFE9BUZDCxYB6x8cl4a+tpZGbnf91jCSnw //! mrIbADAksCbmhjYwcnRERNqlpKTAxcUFCoVCZbmrq2tOOVnI2S1A7BtAdgZ2Ozlilpsrnv5/Aumm //! rQ2myB3Efh6A1WGnLBwoEZVkvJ4wry9nncD9W2kAgKcPt6olnwFAsp9hcf8QAExGExGVZkxAU5HB //! xIJpxcYnY2LUaRQg76zRprhr+PKna1jSzx+hjTyMtFUiIuP77LPP8NlnnwEA7ty5Y+FoSpjPuwOJ //! h1QWLavgkpN8zqFQIE6eInxvOFZ3Wm3GAImoNOH1hOld+ekW9q2/oF6gIfmcF5PRRESlFxPQVOwx //! saDf4NUncCzB+Cfc2QKMjzqNjw9cxb6JbY2+fSKi3CpUqIAHDx5ARFSSC8qEgjLBkNeoUaMwatQo //! AEBAQIDpAy3pcvV21uSWjbXm9RQKxN2Kw+4/dqOrd1cTBkhElD+8ntDv49f2A2K87TEZTURUujAB //! TUUGEwvGFxufjPFRp02+n6u3U1Frym582J+9oYnIdHx9fZGeno6EhASVx6svXHjeE+vFF1+0VGgl //! n56kc25Vsp7hpq32U8wZR2cwAU1EJsHrCeP7PSQEe6uNBxSK5y8j6e05EdaKf48VSW/vh9f77Y22 //! fSIiKloKNrsDkQnkTizkxsRCwUTEnjNL8llJ8Lw39ODVJ8y2TyIqXTp37gxbW1ts3rxZZfmmTZtQ //! v359jutpCp93B2Y5AzHhBiWfAWDc/QeAaO8mlymZ2P3HbmNFSESUg9cTxnXRzx/73MMNSz5b1TB4 //! u8rks0KhyHlZK2xwbcoh/SsTEVGxxAQ0FRlMLBhPROw5bIq7ZpF9H0tIQcclBy2ybyIqPqKjoxEd //! HY1ffvkFALBnzx5ER0fj0KF/Lz5tbGwwcuTInP+7u7tj4sSJWLBgAZYsWYKDBw/itddew/79+7Fg //! wQKzv4cSa9fE50nnWc5q4zsbomvqEwSmpelMQs84OqMwERIRacTrCeO52LQZkJ6ObNuyBvV8dnDu //! C8DJoG0rk8+5KRQKKESBG1OOFCRcIiIq4jgEB5lEdHQ0AKgkFipVqoRKlSohODgYwPPEQlhYGNau //! XQtANbFQrlw5NG7cGFFRUdi/fz927NhhmTdSDBVmvOchgTUxN7SByrKOSw7i6u3UfG3n6u1UdFxy //! kONCE5FWffv2Vfn/66+/DgAIDg7GwYMHAQDPnj3Ds2fPVOrNmzcPZcuWxbJly3Dr1i3UqVMHW7Zs //! QUhIiFniLrF2TQROrTXa5lb/fRcNvLT3hsuUTMyNm4uIwAij7ZOIShZeT1jO5TbBwD//5Hs9hwr/ //! Q/rjHyCZZwu0X2VS+saUI6i+sHWBtkFEREUTE9BkEkwsWEZBks9BPq7YHN5Ca7kyiZzfXtVXb6ei //! +bx9+Gl6x3zFQ0Slg+joHaurjrW1NSIiIhARwcRloeVjXOd8CxiJ/m6uiLocpbVK1OUoNHJvxPGg //! iUgjXk9Yxu8hIci+fbtA69o6WOGNVfNz/n/xyAF8+9HiAm2LSWgiopJFIYZcARIVEwEBATh16pSl //! w7CI/CaI/+PuVKAeyvlNclcuZ8ckNFERUJrbx9z4OeD5uM4FGFpDL2t7oMdHQMN+OYsafN5AxwqA //! s50zjg48avxYiCjf2D4+V5o/h6Thw5F2Ik5l2cGWCzUPwyGSs+yNVfonD/xhzUqc2fctAKCf19tq //! Q3BowyQ0UdFRmttHKjyOAU1UAuQn+awAsLS/f4GHx9gc3gJL+/sbXP/vfzI4JjQRkaUpJxMs4LjO //! OgWMBGY9BGbcVkk+A0D/Ov11rvow46FxYyEiogK5OXu2WvIZANoenwKrzMfPE865XvWDPfDGqvYG //! JZ8B4KVXX8ekqF2YFLULf1W+btCTUAA4JjQRUQnBITiIirnY+GSDk8/G6o0c2sgDoY08DB4f+urt //! VAxefULnUB9ERGRkZ7cAMaMBPNNbNd8CRgIhS/RWiwiMwDdXv0GGjmE+OBY0EZFl3Zw9Gw+++lpr //! edvjU1T+X+/SxULtr/nEwUiJvYoncbcMqs/hOIiIij/2gCYq5iZEnTao3n/cnYw+FMa+iW0R5ONq //! UN1jCSmIjU826v6JiEizv1d0gsSEw6jJ51rBz3s6z3poUPJZaU7QHJ3lusaJJiIi03q4c6fO5HNe //! hU0+K7mG/ge2PuUNrs+e0ERExRsT0ETFWPN5+2DIw2sFHe/ZEJvDW2BIYE2D6o43MFlOREQFd2L5 //! MLjfjYNho2vqYW0P9Fr9POkctqNAm+jq3RWONo4664TvDS/QtomIqHD+euttg+saK/msVDncD1bu //! DgbXZxKaiKj4YgKaqJjquOQg/v5H+yPNSqZMPivNDW1gcBK6+bx9Jo2FiKg0i41PRtN729XmisqX //! 3ElnDeM6F8TMFjN1lsfdisPuP3YXej9ERGS4i3XrGVzX2MlnpWoTmzIJTURUCjABTVQMRcSeM2js //! ZXMkn5UMTUL//U8GBq8+YYaIiIhKn9k7z8Ma2QVbWcdkgoXV1bsr7KzsdNaZcXSGUfdJRETana9b //! z6AnKQHTJZ+Vqk1sCpTTPD3Vt7a/YI39jyqvqFlrTBoPEREZHxPQRMWQIZMOVi5nZ7bks5KhSWiO //! B01EZBr3n2TiWX5O7wo4rnNB6BsLOlMyMTdurkljICIiYGtnXygAg4ZqMnXyWan69BaAvWpE39r+ //! gr+sHiAn2P9/XZQb2LVrl1niIiIi42ACmqiYMWQIi/L21kafcNBQc0Mb4D/uTnrrTeR40ERERqW8 //! sbf5WXuIhm5tOYtyJ50LOK5zQXT17orAKoE660RdjuJQHEREJjQ3bi58k7KLVPJZqfrsVipJ6Jzk //! c14K4NSpU+YLjIiICo0JaKJiJCL2nEHjPp+d3dkM0Wi3b2JblLe31lknG+BQHERERjT9m3MAgMis //! Efji2UvIFkD+/5UtgEI5xIYZk855re60Wm+d2cdnmyESIqLSKepylEH1zJ18Vqo+uxWg+zIix+ef //! f27aYIiIyGiYgCYqRgwZemNpf38zRKKfIUlwDsVBRGQcsfHJSM14lvP/yKwR8E7/ErX+/9XYaqvJ //! h9gwVP86/XWWpz1LYy9oIiITCN8bblC9ah+8b+JIdKs+r7VB44MkJiaaPhgiIjIKJqCJiglDegsH //! +bgitJGHGaIxjCHjQY/nUBxERIWm7P2szazuvmaKRL+IwAi9ExKyFzQRkfHF3YoDAJzxhMYJCAWA //! y8ABcO7WzaxxaVJ9QWtUg4vmQHNZsGCBeQIiIqJCYQKaqBiIjU/GsYQUnXUql7PD5vAWZorIMIaO //! B82hOIiICi5v7+e8ythaFambk4D+CQnZC5qIyLgCvgjI+ff8QTY5SWjlK8Ma+Pa/L6BqZKSlQlQz //! avZ4vT2h09PTcfbsWfMEREREBcYENFExMHGL/l7Clpp0UJ99E9vCxkr3mSOH4iAiKjh9vZ8X9Gpo //! pkgM19W7KxxtHHXWmXF0hpmiISIq2ebGzUW6pKssmz/IBv2n/vsa8rYNJk/fbqEItQsICNBbJyYm //! xgyREBFRYTABTVTEdVxyENl6Hj0zZKgLS1rU109vnYkcioOIKN+KY+9npZktZuosz5RMzI2ba6Zo //! iIhKLkMmHtQ3Pr+lhISEwNpa/6yEnJCQiKhoYwKaqAiLjU/G1dupOutY4flQF0VZaCMPvUNxZAOI //! iNXdi4+IiFQVx97PSob0gjYkaUJERNqFfhOqt469wh4RgRFmiKZgZszQ/0QMJyQkIiramIAmKsL0 //! JRYAYEl/fzNEUnj7JraFnpE4sCnumnmCISIqAYpz72clfb2gAbAXNBFRISQ8StBb59TQU2aIpHDc //! 3Nz01uGEhERERRcT0ERFlL7EAgAE+bgW+eRCbkv66U+Wc0JCIiLDzN55Xmd5Ue79rNTVu6vex77Z //! C5qIqGBabm6pt45PeR8zRFJ4Y8aM0VuHExISERVdTEATFVGTt57RW2dzeAszRGI8oY08EOTjqrMO //! JyQkIjLM/SeZWsuKQ+9npYjACNhZ2emsw17QRET5s/uP3fgn6x+99WJ7xpohGuPghIRERMUXE9BE //! RVBE7Dlk6Zl5cGkxGXojL0OS5lNj2HOBiKgwikPv59zmBM3RWR51OQq7/9htpmiIiIq/KUem6K2z //! sPVCM0RiPCEhIQbV44SERERFDxPQREWQvrGQi1PPNk2GBNbUWZ6Wmc1e0EREOuhrI4vbMaKrd1e9 //! vaBnH59tpmiIiIq38L3heuuUsymHrt5dzRCNcfXq1UtvHU5ISERU9DABTVTEGDIGcnHr2ZbX3NAG //! sNEzI+FbW0+bKRoiSJH7IwAAIABJREFUouLHkElqixt9vaDTnqWxFzQRkQHibsXprXN88HEzRGJ8 //! DRs2RNmyZfXWW7RokRmiISIiQzEBTVSExMYn41hCis46xW3iQW0W9fXTWZ6Zrb+HHxFRaaRvkloP //! lzJmjMZ4unp3haONo8467AVNRKRbh6gOeusUl4kHtZk8ebLeOo8fP+aEhERERQgT0ERFiCE92orb //! xIPahDbygJOdtc467AVNRKRO37HirU51zBSJ8c1sMVNnOXtBExFpt/uP3bj99LbeesVp4kFtOCEh //! EVHxwgQ0URGhr0cboH/s5OJmXs8GOsvZC5qISJW+Y0VxnyPAkF7QM47OMFM0RETFiyETD/av098M //! kZieoRMS7tq1y8SREBGRIZiAJioi9PVos8LzsZNLktBGHrC30d0MTYxiL2giIiV9x4riPkcAoL8X //! dKZkYm7cXDNFQ0RUPBjaLkYERpg4EvPRNCGht08cglptQqvWGxHUahNS7n9kgciIiCgvJqCJigh9 //! vZ+X9Pc3UyTm9V5v3cmSbAARsSVvsi0iovwq6b2flQzpBR11OcpM0RARFQ+GtIsLWy80QyTmk3dC //! Qm+fOFSrdhVWVgKFArCyElSrdhV79w61YJRERAQwAU1UJAxefUJneUlJKmgS2sgDQT6uOutsirtm //! pmiIiIqu0tD7WUlfL2gACN8bboZIiIiKgV0TARGdVdwd3NHVu6uZAjKf3BMSVq16FQqFarlCAVhZ //! HzNzVERElBcT0EQWFhufjGMJKTrrlKSkgiaGTKzIsaCJqDQrLb2flbp6d9U7TmncrThOSEhEBACn //! 1uqt8mP/H80QiGXUqlULANSSz0oKBXDxkv4bm0REZDpMQBNZmL4ebbZWKFFJBW30TbD41laOBU1E //! pdfsned1lpfEG5URgRGws7LTWYcTEhJRqXd2i+5yEQRWCTRPLBYSFhams1yhAP76a7OZoiEiIk2Y //! gCayIH092gDgg74lc+znvPRNsJiZzV7QRFR63X+SqbWspPV+zm1O0Byd5ZmSyV7QRFS6bR8DAHDP //! ylIfhkME1iJY3Wm1BQIzr4CAAL11bt7aboZIiIhIEyagiSyIvZ9VVXC01Vk+NeasmSIhIio69N18 //! K4m9n5W6enfV23OPvaCpNEuNv42bC3/GjSlHcHPhz0iNv23pkMjcnqUDAH68cfPfJPT/v9yzsnC6 //! SaSFAzSPkJAQADY661y48I55giEiIjVMQBNZEHs/q4rs5quzPC0z20yREBEVHR/svayzvKTfqNTX //! cy9TMjE3bq6ZoiEqOlLjb+NBzFU8e/A8AfnsQToexFxlEro0+ai5yn9/vHET55Ku57x+vHETaNjP //! QsGZn6/v+3pqaH+aiIiITIsJaCILiYjV3fu5JD9SrU1oIw8E+bjqrDN49QkzRUNUdETEnoPP1G/h //! NWU3fKZ+q7f9oJIl+UGa1jKXMrqfHCkp9E1IGHU5ikNxUKnzcGcCJM/NecnMxqO9SZYJiMzv7iXd //! 5QEjzRNHEVG1Sg+9dX759b9miISoiPioOTDL+d9XnptWRObEBDSRhWyKu6azvCQ/Uq3L5vAWOsuP //! JaRwLGgqVQavPoFNcdfw7P/HdXwmgk1x15iELiX0tXezuut+cqSkiAiM0FtnwU8LzBAJUdGQGn8b //! 2U+yNJYpe0RTCbdrov46IUtMH0cR4+LSUmf5gwfHzRQJkYUtqqt+k+ruJSahyWKYgCayAH2Jo9I2 //! 9nNeTnbWOss5FjSVFrHxyTiWkKKx7Kufrps5GrIEfXMFlKZjhb5e0A8zHpopEiLLe7gzQWuZtYu9 //! GSMhizm1Vnd5rWDzxFHENGm8UW+di5dmmiESIgs6uwV4fFNzmb4nJ4hMhAloIgvYrKf3c2kb+zmv //! eT0b6CxPy8xmL2gqFd7Zpv1my7O8M91TiRMbn6xzrgAPlzJmjMbyIgIjYGdlp7MOx4Km0kJb72cA //! KN/Jy3yBkGUY0vs5bIfp4yii9PWC/uuvzWaKhMhCYkZZOgIiNUxAE5lZbHwydKWNSnvvZ+D5+7e3 //! 0d08zdpx3kzREFlGbHwy0rO0T7xprVCYMRqyBH29n9/qVMdMkRQdc4Lm6CyPuhxlpkiILEffJINO //! jdzNFAlZjL7ez3pu1pV0hvSCvnlruxkiIbIUdlShoocJaCIz05dQKO29n5Xe6617DOwHaZzFmko2 //! fW3FwOY1zBQJWYK+3s+lcaJaAOjq3RWONo4664TvDTdTNESW8eCbq1rLFGV0D2NGpUTox5aOwOIU //! Chud5RcuGNCLnKg44hjPVEQxAU1kRvoSCgB7PyuFNvLQOxY0h+GgkkxfWzE3VPdQNVS8zd6p+ymP //! 0jpRLQDMbKF77M64W3HY/cduM0VDZF6p8bchGdqfjnHpXtuM0ZBFfN5df52G/UwfRxFXr977euuw //! FzSVSPrGeC5b1TxxEOXBBDSRGenr0ehSxtZMkRQP+saCfmvraTNFQmRe+iYqHRJY00yRkKXcf6L9 //! KY/S2vtZqat3V71jQc84OsNM0RCZl67JBwEOv1EqJB7SXR4w0jxxFHFVq/TQW+fChXfMEAmRGRly //! g2oyJyEky2ACmshMDOn9PKu7r5miKR5CG3lA1yi3mdnsBU0lk76JStn7uWTT166V5t7PSvrGgs6U //! TPaCphInNf62zskHOfxGKWBIcilkienjKCaqVRuspwaH9KMSRt8NKiILYgKayEz0PU5d2nu0aTNY //! T09P9oKmkkbfRKVlbHnoLun0PS3DY8XzXtCBVQJ11mEvaCpp9PV+5vAbpYC+5FKtYPPEUUzUq6v7 //! ZiUA/PLrf80QCVERwSckyIJ4FUtkJroepwbYo00bfT092QuaSpp3tp3VWc62omTT97QMh2r61+pO //! q3WWZ0om5sbNNVM0RKanq/ezY2AVDr9R0u0yYNK8sP9j797DoyrP9Y/fkwOYgJCwFTmoBVEBERRN //! f41Si2CpVgxEVFDB07Zqre5WqYiUVEBBt/VEWw8VdCsqVqBIQOqWraJWrbib3QgKQamAIAfRhniA //! EJLM/P6gnDPvO0nWYdZa38915bp03pXwOMFZM8961v0ucL+OgLFNQVdV/dWjSgCX3Z1CRB93SMBH //! NKABD9gapEw/m9nybicuME+XA0FRWr5BNXXJN5fKzmD6Nexs089ENe1vRPcRxvVZH80iigOhsK18 //! i3G9XfFxHlUC35Q9YV63ZONHVSpT0BUrzZvbAoFQ85V5nTsk4DMa0IAHbA0FJhrNbFPQVdXktyEc //! bK8V9150skeVwA+26WcuVh6spLDEesykv07yoBLAXab4DbKfI2DZbPsxxQ+7X0dA5eSYL9Bs3DjT //! o0oAl9zXw34Md0jAZzSgAZelsvkgDQU72xQ0MRwIA14ros22VwAXKxtmm4Kurq9mChqBZ4rfIPs5 //! AubfaDkgU+oz3JNSguj00162HrNp83wPKgFc8u0m83rrjt7UARjQgAZcZptotDVWsYttCprNCBF0 //! JaW8VkSdaa8App+TKyksUQvLredsSIggs8VvkP0cAfU15vVhf/CmjgCLxVoa11esGOtRJYDDZgyx //! H3PLSvfrACxoQAMuSmX62dZYxV4ZseRrbEaIoJu5ZJ1xPWyvFevXr9eFF16otm3bqk2bNho2bJjW //! rTM/B7vFYrEGv95/P7gXomyvX0w/m93Rz5zxyYaECDLiNyIuleYS089WPXvebTmCSD8E1Jo3/a4A //! SAkNaLiCxsIuttup83KyPaokHC79nnkCdNwLyzyqBHBWafkGJQzrOdnhOl1v375dAwcO1MqVKzVj //! xgw988wzWrVqlQYMGKBt27al9DOuvPJKvfvuu/t9HX/88S5X7h7T3TJMP9sNPmawcrNyjcfM+miW //! R9UAzopi/AafJfZhay6xsVhKOnYYaj3mr++e40ElgINSyYcfNt39OoAUZPldAMJnd2OhZcuWmjFj //! hmKxmEpKSjRgwAAtW7ZMrVq1sv6MK6+8Utddd91+jwWxsWC6nVqSJg7p5VEl4TC5uLeeNUyJVtfG //! VVq+gUYNAmfsXPPFk7BNv06fPl2rV6/WRx99pGOP3dU86dOnj4477jg99thjGj16tPVndO7cWYWF //! hW6X6gnb3TJh+/275fbTbtdtb91mPGbykskpbVwIpIsoxm/wWWIfC+3nQzYWS12nTiONGw5WV6/y //! sBrAAS9caz+GOySQJmhAw3E0Fnax3U7NRFvTjCo82tiEnrhgOc8rAqW0fINq6uJJ17Mzwrf54IIF //! C1RYWLjnHCFJXbt2Vb9+/TR//vyUzhNhYrtbJmy/f7cMPmawyreUGyedZ300iwY0AiWK8Rt8lthH //! 2RPmdaafG6VnjzuMDWhJqlh5u3r2MMc6AekioYQMKZW8RiCthOueXqQFW2MhKmwNBSbamsaWg1tV //! TX4bgsX2WnHvRSd7VIl3li9frhNPPPGgx3v16qUVK1ak9DMeffRRtWzZUrm5uRo4cKDeeustp8v0 //! jOluGaKaGieVDQnJgkaQRDF+g88S/5LKrfVMPzdaXt7pxnVbgxpIFyWlH8iY4SfxGoG0QgMajqOx //! sIstfoOJtqbLzzU3ZNiMEEESxdeKyspK5efnH/R4u3bttHXrVuv3jxo1So888oheffVVTZs2Tf/8 //! 5z81cOBAvfHGGy5U6y7b6xVRTY1n25Bw1kez9OfVf/aoGqDpohi/IfFZYo/S6y0HhHMC3m2nnvKM //! 9ZiKlbd7UAnQPKa7ghMJSa07elcMkAIa0HAcjYV/XY00YKKteSYUmRsyExeYJ0qBdGFrPo4qNG+8 //! GVXPPPOMRowYoTPOOEOjRo3S22+/rU6dOqmkpOFohWnTpqmgoEAFBQX64osvPK7WzLT5oBTOCxBu //! G3zMYOsU9KS/TvKoGqDpohi/IfFZYo948ul3SdKwP3hTRwjFYi2N60xBI92lNHB1y0r3CwEagQY0 //! 0k4YGgszDVcjJSbamsvWkCGGA0Fhaz7aImeCKj8/v8EmQrKmg82hhx6qwYMH629/+1uD69dee63K //! yspUVlamww8/vNE/3y22zQe5WNl0tino6vpqpqCR9qIYv+GExn6WkNLw88SMIfZj2FisyXr2vHu/ //! f39H39cv9KhGao5+oUf1jr7vU2VAanZ/hngr3mvXtPM+EglpVesCH6oCzGhAw3FRbyyUlm8wRjGx //! +aAzbDEctil0wG+25qNxQ5GA69Wrl5YvP/hOhRUrVuiEE05o8s+NxYL1rNkuQHCxsukGHzNYuVm5 //! xmOYgkY6qyxdZVwPa/yG5P1nCSn9Pk8k1rxpPqDgam8KCamOHYbu+ed39H09phv0Zay9FMvQl7H2 //! ekw36L4lU3ysEDDb/Rni8trxe5rQu7/eivfS8WNe87lC4GA0oOG4qDcWbA0FNh90hi2Gw5SJBaQD //! 2+aDI0McvzFkyBAtWbJEq1ev3vPY2rVr9c4772jIkBSmvg7w9ddfa+HChfp//+//OVmmq2wXILhY //! 2Xy3n2bO8GQKGulqW/kWbV+yOel6mOM3JD5LzP6v++0bi533gCe1hFmnTiMlSU/r31Uf2z+2qT7W //! Qr/fPsCPsgCrAwetLq8dr641z+35urp+vE+VAWY0oOG4qDcWTA2F7AzyPJ1S3LezWrUwfwBjM0Kk //! M9vmg2GN35Cka665Rl26dNHQoUM1f/58LViwQEOHDtVRRx2l6667bs9xn376qbKysnTHHXvjFO67 //! 7z5dc801eu655/TGG29oxowZ6tevnzZv3qwpU4IzrcTFSvelMgX967d/7VE1QOq+XrTWuB72+I2o //! f5Y4fe0jMvbKu/b3rJYw69lj13uLb9WmwfUa5Wju5kovSwJSYov7vPeikz2qBGgcGtBwXJQbC7aG //! JycDZ00539ygG/fCMo8qARon6huVtmrVSosXL9bxxx+vyy67TCNHjlTXrl21ePFitW7des9xiURC //! 9fX1isfjex7r3r27VqxYoZ///OcaNGiQRo8era5du+rtt9/WGWec4cd/TqMx/ewd2xR0baJWk5dM //! 9qgaIDX1VTVJ12I5maGO35Ci/VlCkjrFvjQfcMUCbwqJgLy805MvxmIq+fgz74oBUmS7QYL3kEhX //! WX4XgPDZ3Vi4+eabddlllymRSOiss87S1KlTU2oszJs3T/PmzdNXX32lNm3aqF+/fnriiScCMbUw //! dq654cnJwFnFfTtr7NxlqqmLN7heXdvw44DfnnuPjUqPPvpozZ0713hMly5dlDhgZ5WioiIVFRW5 //! WZrrbPErTD87Z/Axg3XHu3doe932pMfM+XiOSgqTb04GeGlb+Rbjetinn6Vof5YoKf1AP00cpiOT //! NaEzWjT8OJrk1FOekRaXJ13fWs9nCaQX2xDLqBBH+CH4aEDDFVFsLJSWb0jaCJV2TbTBefdc0Ec3 //! zXo/6Xpp+QYa/0g7ccPoAtOv4WeKX+H377zbT7tdt711W9L1eIIGA9KHLX4j7NPPu0Xxs4S0aw+T //! rzOG697sx9Qytv+dMvGElFH8sE+VhVdeVlxV9clj/cZ+tE73dKeph/Rgi98Ic4Qfgo+OGOAQ8jz9 //! YWvUjJmTvDkN+ME2ucBrRbjZopr4/Ttv8DGDNaL7CElSv+X1evjhOj1/d50efrhO/ZbXKyPG22Gk //! D1P8RmZeSw8rgdd2nx8WxL+vMbXX6Z/x1kokpERCqky01q2JG6U+w32uMnymHN9VplCDpzeSA430 //! YYvfANIZE9CAA2x5nhLxG25q1SIz6fNfG2cKGunFNrnA39VwM8VvMP3snpLCEh3y2t901ksf65C6 //! XY8d/rV03UsJFXYo8Lc44F9s8Rttzu7iTSHwxb7nhwXx72vBzu/vtz51BHvJuOGCDu10Y8W6pI09 //! Gn5IFyOnv2tcJ34D6Y6RD8ABtjxPTgbusm1GOHGB+fcDeKW0fIPxg0zYNx+EOX6D6Wd3DX3t2z3N //! 590OqZMKZ6/wpyDgAF+9+IlxPSrxG1FlOj9IXKB20+Wd2hnXx35kHh4AvPDOJ+ZpfOI3kO5oQAMO //! sL1h5GTgruK+nRUzrFdVm38/gFdsF6uisPlglNniN2guuKtu06YGH09UVemrF1/0uBrgYPHtdUnX //! iN8IN9v5gb1k3GXLeJ5BDAd8ZovwA4KAMxngMiYavTHSMmVue2MPeMF0sSo7gwZk2Nn2CoC7sjp2 //! TLq2acpdHlYCHIz4jWhjLxn/2RojczfThIZ/bBF+3HGNIKABDTST7WokE43esE2ZE8MBv9kugtx7 //! EdmOYWbbK4CLle5rf/NNSdcSVVUeVgIczBi/kR0jfiPk2EvGf5dZYjjGrCSGA/6xZZFzxzWCgAY0 //! 0ExsKBYMxHDAb7b4DV4rws023cbFSve1LSoyrhPDAT+Z4jfyhx3vYSXwGvEb6cEWw7Gd3QjhE9vA //! G9PPCArOZkAzsKFYesnPNT/fZGfBT6b4DVOGOYLPNv2ck53BBQiPZOblJV0jhgN+qSxdZVxn+jnc //! iN9IH/lZmcZ1YjjgB9vAG9PPCAoa0EAzsKFYeplQZH6+n7WcvAG32C5+2DLMEWw0F9LHEeN/lXSN //! GA74YVv5Fm1fsjnpeizH3BBD8BG/kT4mH2d+rks+/syjSoC9GL5HWNCABpqBDcXSS3HfzmrVwvxB //! jc0I4QcmF6KL6ef0QgwH0s3Xi9Ya1/OGHOtNIfCF7X0pd1N664IO5hzorfVxjyoBdiF+A2FCAxpo //! IjYUS09TzmczQqQXonqizXanDNPP3iOGA+mkvqom6VosJ5P4jZAbO3eZcZ27Kb1ni+EY+xF3VMI7 //! tjt4GWJBkNCABpqIDcXSU3HfzmqZlfyljc0I4TWieqLNdKcM08/+IIYD6WJb+RbjOtPP4VZavkE1 //! deaJWs4R3rPFcDy9kRxoeIP9ixA2NKCBJmJDsfR1zwXmiUJiOOAlonqiy/Zaw/SzP2wxHJsmTfKo //! EkSdLX6D6edws+0PwK31/rigQzvjZznyeOEVW4QfrxEIGhrQQBOwoVh6szX0iOGAV4jqiTbulElf //! phiOqudnkQUNT5jiNzLzWnpYCfxg23yQW+v9c3kncxY0MRzwgu1iB68RCBoa0EATsKFY+sswjC4Q //! wwGv0ICMNtP0O9nf/jLFcCiR0JYHp3pXDCLJFr/R5uwu3hQCX9guUOdk8zHdT/d0Nw8TzSCGAy6z //! Dbz162a+SAKkI85sQCOxoVgwXPo98xtHYjjgBaJ6osv2GkP2t7/aFhUZp6DrNm70sBpEEfEb0WaL //! 3yCiyX+2RsnczTSh4R7bwNvMa07zqBLAOTSggUZiQ7FgsE2hj5nzvkeVIKqI6ok2U3OBzQfTg3EK //! WiKGA64ifiPabPEbnCP8d5klhmPMSmI44B6yxhFGNKCBRmJDseDIz00+jV4bZwoa7iKqJ7pKyzcY //! mwtMtqUH22aExHDALcRvRJvt/Sd3U6YHWwzHdjqEcIltiIXNBxFUNKCBRmBDsWCZUGSeRmczQriF //! qJ5os91azYXK9JHVqVPSNWI44BbiN6LNdo7gbsr0kZ+VaVwnhgNuYIgFYUUDGmgENhQLluK+nY05 //! u2xGCLcQ1RNdtulnLj6kl/Y332RcJ4YDbiB+I9qI3wiOyceZfxclH3/mUSWIEobrEVY0oIFGYEOx //! 4LHl7BLDATcQ1RNdTLYFiy2GY9OUuzyqBFFB/Ea0cWt9sFzQwZwDvbU+7lEliIqR0981rvMagSCj //! AQ2kyNaoZEOx9GS7RYkYDjiNqJ7osk0/s/lgejLFcCSqqpiChqOI34i2597j1vqgscVwjP2IzQjh //! nHc+Mce68BqBIKMBDaRo7NxlxnVOBsFEDAecRlRPdNl+92w+mJ5sMRxMQcNJxG9EW5x76wPHFsPx //! 9EZyoOEM2x0SQNDRgAZSUFq+QTV1yW+xItMzveXnmn8/xHDASab4DYSb6XfP9HP6altUpLxLLk66 //! nqiq8rAahFll6SrjOvEb4Ub8RjBd0KGdMWqRawpwim3zQV4jEHQ0oIEUsKFYsE0oMv9+xr1gnm4H //! UmW7mMHFqvCy/e6Zfk5vHSdMMK4Tw4Hm2la+RduXbDYeQ/xGuNmaS9xNmb4u72TOgiaGA06wXczg //! NQJBRwMaSIFtopGptvRW3LezWrVInt9WXRtnChqOYAO66LL97jlPpL/MvLyka8RwoLls2c/Eb4Sf //! qbnEZubp7Z7u5snTGcRwoJm4QwJRQAMaaCZOBsEw5Xw2I4S72IAuumy/eybfg+GI8b9KukYMB5rL //! lP0sEb8RdrbmEpuZpz9b42TuZprQaDrukEAU0IAGLGxvGDkZBIOt8cdmhGguNqCLLmKawqFtUZFx //! nRgONNW28i3G9dzCDsRvhNyzNJcC7zJLDMeYlcRwoOnIEkcU0IAGLGxXIxEcts0IgeYgqie62Hww //! PIjhgBts8Rvtio/zphD4whbzlpPNR/IgsMVwbKeDiCYifgNRwdkOMCgt32C8Gslt1cFi24yQHGi4 //! hdeK8GLzwXAhhgNuMMVvkP0cftwhFR75Wcn3lJGI4UDTcIcEooIGNGDAbdXhYptCHPfCMo8qQdjY //! mpC8VoSXafNBpp+DhxgOOM0Wv0H2c/hxh1R4TD7O/Lsq+fgzjypBWNimn4EwoQENGJjeMGZn8IYx //! iEwxHNW1caag0SRj55ovXvBaEU62zQeZagsmYjjgJFv8BtnP4WZrLhG/ESwXdDDnQG+tj3tUCcLC //! FvdJ/AbChDMekITtDeO9F53sUSVwki2GY+IC89Q7cKDS8g2qqUv+gYP4jfCy3SXDhYdgssVwMAWN //! xiB+I9pst9ZzoTJ4iOGAk2zR4cRvIExoQANJPPee+Q0jjYVgsv3eqqrNt0kCByKqJ7pMd8lw4SG4 //! 2hYVMQUNRxC/EW2p3FXH54ngIYYDTrENvPXrZp64B4KGBjSQRNxwOZLGQrCZYjgkNiNE45DtGE3k //! focbmxHCCcRvRJvtAjW31gcTMRxwii1+Y+Y1p3lUCeANGtBAA2gshBsxHHCK7bWCD5fhZdp8UOLC //! Q9CxGSGcQPxGtNkuUHNrfXC1yjS3UcZ+ZG4sApI9fgMIGxrQQAPI9Qy34r6d1apF8vw2YjiQKlsT //! kg+X4WTbfJC7ZMKBGA40B/Eb0Wa7QM3mg8H2m+OPNK4/vZEcaJj96o2PjA1ohlgQRpz5gAaQ6xl+ //! U843NwaJ4UAqaEJGk+3CA3fJhAMxHGiOr178xLhO/Ea42c4TbD4YbBd0aKeYYZ3JVtj88c01xr9D //! DLEgjGhAAwewbQZAYyEcbFPsxHDAhqieaLJNP+dkZ3CXTEjYYjg2TZrkUSUImm3lWxTfXpd0nfiN //! 8DOdJyTupgyDyzuZs6CJ4YBJvNr8GgGEEQ1o4AC2zQB4wxgeGYbLzsRwwIaonmhiqi1aTDEcVc/P //! IgsaDbJNPxO/EW7Eb0TDPd3NEQkziOFAEnM3VypxSMNxkAkRv4Hw4uwH7KO0fIPxliluqQ+XS79n //! PrkTwwETU1QPHy7Dienn6DHFcCiR0JYHp3pXDALDNP2cW9iB+I2Q40JldNje7c3dTBMaB7v1489U //! d9yhShwwDZWQFM/PJn4DocUnZGAftolGbqkPF9vJnRgOJGO7OMGHy3CiqRA9bYuKjFPQdRs3elgN //! gsC2+WC74uM8qgR+IX4jOi6zxHCUfPyZR5UgSLbVxxXv1Eq1vdoqfkjmrsbzIZmq7Z2nuv/HBUqE //! Fw1oYB+micbsDN4whlF+bvKpdmI4kIytEclrRfgw/RxdxiloiRgO7McUvxHLafiWa4SH7QI1d1OG //! iy2GY2t93KNKEBT7TsXHO7XSzv4dVHN2Z+3s30HxTq2s2eJAkNGABlJ070Un+10CXDChyDzVTgwH //! GmJqRPLhMpzuXfSRcZ3p5/CybUZIDAf2ZYrfyBtyrIeVwA+2C9TcTRk++VnmC0vEcGBft1qm4m0X //! NYAgowEN/EtJKRONUWT7vRLDgQPZLkrw4TKcNlRVJ11j+jn8sjp1SrpGDAd2s8VvkP0cfsRvRM/k //! 48y/U2I4sK8W0uWFAAAgAElEQVRthqn43FjSJSAUaEAD/zJzyTq/S4BPMgwne2I4cCBbVjwfLsPJ //! 9JmA6efwa3/zTcZ1YjggSVXzViVdI34j/GzDLKMKmWwMows6mCMTiOHAbmM/Mvcb7u3BawTCjQY0 //! oF0TjQnDOrfUh9ul3zOf7InhwL5MWfE52ZxWU7V+/XpdeOGFatu2rdq0aaNhw4Zp3brULgTu2LFD //! Y8aMUceOHZWTk6PTTjtNf/nLX1yr1XaO4KJD+BHDAZtt5VuU2Jm80UT8Rvg99575HGbb/BrB1SrT //! /P7P1nhENDyz0RzHYruYAQQdn5QB2ScauaU+3GwfCMa9sMyjSpDubBcjmIRNzfbt2zVw4ECtXLlS //! M2bM0DPPPKNVq1ZpwIAB2rZtm/X7r776ak2fPl133HGHFi5cqI4dO+rss8/W+++/70q9tkxPRAMx //! HDD5etFa4zrxG40TpIuUu8VNVyoRar85/kjj+tOWxiOiwTQLT/wGooAGNFwRtDeNponG7Aym26Ig //! Pzf5lHt1bZwpaEiSxs41X4zgtSI106dP1+rVq1VaWqri4mINHTpUCxYs0KeffqrHHnvM+L1Lly7V //! c889pwcffFDXXHONzjrrLM2ePVtHH320br/9dsdrLS3fwKaTkEQMB8zqq2qSrhG/0ThBu0gpEb8R //! dRd0aGeM6uLaBIjfAGhAwwVBfNNocu9FJ/vy58JbE4rMU+5sRojS8g2qqTPcXk0jMmULFixQYWGh //! jj127y3pXbt2Vb9+/TR//nzr92ZnZ2vEiBF7HsvKytLFF1+sRYsWqaYmeROoKe5d9JFxnTtkosMW //! w7Fpyl0eVYJ0Y9t8kPiNxgnSRcrdnrXsJUP8Rvhd3skcn0AMR7TZpuCJ30AU0ICG44L2ptE2scBE //! YzTYfs9sRgiiepyzfPlynXjiiQc93qtXL61YscL6vV27dlVubu5B37tz50794x//cLTWjVXVSddy //! sjM4R0SMKYYjUVXFFHREEb/hrCBdpJTs8VzcWR8N93Q3T7DOIIYjsuZurjROwedbMsSBsOBvOhwX //! tDeNMy0TC4gOUwwHYIrqkbhY1RiVlZXKz88/6PF27dpp69atTf7e3etO6pSXk3SNzO/oscVwMAUd //! Tab4jcy8lh5WEg5Bukgp2fcJGEn8RmTYmitzN9OEjqKSVeaLVJMtGeJAWNCAhuOC9KaxtHyD8Wok //! t9RHiy2GgxxoJEO2Y3qbNm2aCgoKVFBQoC+++KJR3zvm7O7Kyd4/vzWmXb9zLjpET9uiIuVdcnHS //! 9URVlYfVIB3Y4jfanN3Fm0JCJEgXKSUZ9wmQiN+IksssMRwlH3/mUSVIJ1vrzK8RxG8gKmhAw3FB //! etNItif2ZWsmjXvBvAEdwst28YEPl42Tn5/f4Pkg2Tkg1e+V9p4v9nXttdeqrKxMZWVlOvzwwxtV //! a3Hfzrp7WG91zstRTFLnvBw9OOJkfucR1nHCBOM6MRzR8tWLnxjXid8IhuZcqDThAnW02GI4ttYn //! 30sE4WSbeid+A1HC33YEXnPeMJqyPbMzuKU+ikwxHNW1caagI2rsXC4+OKlXr15avvzgTO0VK1bo //! hBNOsH7vmjVrtH379oO+t0WLFvvFPzmluG9nvXPbQK35z8F657aBnBugzLy8pGvEcETHtvItim+v //! S7pO/EbTeH2RUmrehUpTxjMXK6MnPyvTuE4MR7Tcapl6J34DUUIDGo4L0mSbKdvz3otObtTPQjjY //! YjgmLjBvRIfwKS3foJq65BMrRPU03pAhQ7RkyRKtXr16z2Nr167VO++8oyFDhhi/t6ioSLW1tZoz //! Z86ex+rq6jRr1iz96Ec/UsuWNHzgviPG/yrpGjEc0WGbfiZ+o2mCdpEyWcYz08/RNPm4vReps5ZX //! quWiDXu+spZXEsMRIXM3V2qbZeqd+A1ECQ1oOC5IbxrJ9sSBbL/3qmrzRnQIn0kvmi86ENXTeNdc //! c426dOmioUOHav78+VqwYIGGDh2qo446Stddd92e4z799FNlZWXpjjvu2PNY3759NWLECN100016 //! /PHH9dprr+niiy/WmjVrNGnSJD/+cxBBbYuKjOub+LsYCabp59zCDsRvNFHQLlJOLu6tUYVHKzO2 //! axY6MxbTqMKjmX6OqN0Nxazllcr8rFoxac9X5mfV+mbZl36WBw/ZNh+8wpIZDoQNDWg4LkhvGsn2 //! RENMMRwSmxFGzdbt5osOXKxqvFatWmnx4sU6/vjjddlll2nkyJHq2rWrFi9erNatW+85LpFIqL6+ //! XvH4/tMjTz75pK666iqVlJRo8ODBWr9+vV5++WWdcsopXv+nIMJMMRxVz88iCzrkbJsPtis+zqNK //! wieIFyknF/fWJ3efq7X/OVif3H0unyUirlVmxp7m8752N6ERDbbNB22Z4UDY0ICG44L2ppFsTxyI //! GA7sZrvYwO21TXf00Udr7ty5+vrrr/XNN9+otLRUXbp02e+YLl26KJFIaOLEifs9npOTowceeECb //! N2/Wjh079N577+nMM8/0rHZAMsdwKJHQlgenelcMPGeK34jlmDNgYcZFSgTdbwy5vjFJJaUfeFcM //! fMHmg8DB+FsPx/GmEUFX3LezWrVI/uGRGI7osMVvMOEERFfboiLjFHTdxo0eVgOvmeI38oY4nzMc //! NVykRJBd0KGdcXPKZ5es86wW+MMWv8Hmg4giGtBwBW8aEXRTzjc3FonhiAZT/AabDwIwTkFLxHCE //! lC1+g+xnAKYGtMRnibCzxW+w+SCiiAY0ADTAFsVCDEf42T4YsPkgANtmhMRwhBPxGwBsRlpi2sa9 //! sMyjSuA1W/wGmw8iqmhAA0ATEMMRfrb4DfLiAUhSVqdOSdeI4Qgn4jcA2Nhi2qpr48Z1BNetH39m //! XGfzQUQVDWgASCI/1xyxwK1z4WaK37DdVgkgOtrffJNxnRiOcCF+A0CqTHvKSHyWCKtt9ckvLvAZ //! AlFGAxoAkphQZI5Y4Na58LJ9ILDdVgkgOojhiBbiNwCkyranDJ8lwscWv3E58RuIMBrQAJBEcd/O //! xsmF6to4kwshNX7eB8Z1222VAKKFGI7oIH4DQKpscW3EcIQP8RtAcjSgAcDANrnAZoThU1q+Qdt2 //! Jt+5Oi/HHM0CIHqI4YiGytJVxnXiNwAcyBbpV1JqHnpAsJjiN3LJ30DE0YAGAAPb5AKbEYaPbfPB //! iUPM0SwAoscWw7Fpyl0eVQK3bCvfou1LNiddJ34DQENskX7PLlnnUSVw29iPzL/Le3sw/YxoowEN //! ABa2yQWEi2nzQcl+UQJANJliOBJVVUxBB9zXi9Ya14nfANAQ3jdGx9MbzfnPF3Qg/xnRRgMaACxs //! kwvkQEcH8RsAkrHFcDAFHWz1VTVJ12I5mcRvAEhqlGXzamI4gm/u5kolDOvEbwA0oAHAyja5wA7W //! 4WG7mED8BoBk2hYVKe+Si5OuJ6qqPKwGTtpWvsW4zvQzABPb5tXEcARfySrzZwjiNwAa0ACQElMM //! R3VtnCnokBg713wxgdsoAZh0nDDBuE4MRzB99eInxnWmnwHYtGphzonns0Swba1LvoG5RPwGINGA //! BoCU2GI4Ji4wb1yH9FdavkE1dcl3riZ+A0AqMvPykq4RwxFM8e11Sdcy81p6WAmAoJpyvnkKmjsq //! g2vuZnP2c34mbTdAogENACmxTb5WVZs3rkP6m/Si+SIC8RsAUnHE+F8lXSOGI3hs8Rttzu7iTSEA //! As32WaK6NvkQBNKbLX5j8vFHelQJkN5oQANAikwxHBK3zgXd1u3miwjEbwBIRduiIuP6pkmTPKoE //! TjDGb2THiN8AkDJbDAebEQYT8RtAamhAA0CKiOEIL9vFA9vu5QCwL1MMR9Xzs8iCDhBT/Eb+sOM9 //! rARA0NliOGayGWHgEL8BpI7/GwAgRcV9OxsnF4jhCC5b/IZt93IA2JcphkOJhLY8ONW7YtBktvgN //! pp8BNIbtbrqER3XAOcRvAKmjAQ0AjWCbXCCGI5hM8RtsPgigsdoWFRmnoOs2bvSwGjSVKX4jlmO+ //! lR4AGmK7q44YjmAhfgNIHQ1oAGgE2+QCMRzBY7towOaDAJrCOAUtEcMRAKb4jbwhx3pYCYCwsN1V //! 9ywxHIFhi9+4ohPNZ2BfNKABoJEyYsnXiOEIHlv8BpsPAmgK22aExHCkN+I3ALjF9FlC4o7KoLj1 //! 48+M6/d0Zw8ZYF80oAGgkS79nvnNBG8ag8UUv2H5fAAARlmdOiVdI4YjvRG/AcAtts8S415Y5lEl //! aI5t9fGka3yGAA5GAxoAGsl26xxvGoPDdrFgpCWnDwBM2t98k3GdGI70RfwGALfYPktU1yZvbCI9 //! jP3IHJVyOfEbwEFoQANAE+TnJt+YjjeNwTF+nnmjF9sHBAAwIYYjmCpLVxnXid8A0FytWpjvpOCO //! yvT2zEZz/jPxG8DBaEADQBNMKDJvTMebxmDYtjP5ztV5OckvMgBAqojhCJZt5Vu0fcnmpOvEbwBw //! wpTzuaMyyEzjRrnkbwANogENAE1g25hu4gLzxnbwn+0iwcQh5osMAJAKYjiC5etFa43rxG8AcILt //! swR3VKYvW/zGvT2YfgYaQgMaAJrIdOtcVXXyje2QHmzxG7YPBgCQClsMx6Ypd3lUCVJRX1WTdC2W //! k0n8BgDHmCL9JKmk1PxeFf542hK/cUEH8p+BhtCABoAmst06x5vG9FVavsEYv5GTzekRgHNMMRyJ //! qiqmoNPEtvItxnWmnwE4yRbp9+wS86QtvDd3c6UShvX8TD5DAMnwfwcANJFtQpY3jelr0ovmiJS7 //! h/XxqBIAUWCL4WAKOj3Y4jeYfgbgJO62C56SVeYIv8nHH+lRJUDw0IAGgGaw3TrHZoTpaet2c0QK //! HwgAOKltUZHyLrk46XqiqsrDapCMKX4jM6+lh5UAiIpRhea8YD5LpJetdcnvoJSI3wBMaEADQDPY //! bp1jM8L0Y3sjn5djvqgAAE3RccIE4zoxHP6yxW+0ObuLN4UAiJTJxeZIv3EvLPOoEtjM3WzOfiZ+ //! AzDj/xAAaIbivp3VMiv5SymbEaYfW/zGxCHmiwoA0FSZeXlJ17Y8ONXDSnAg4jcA+CVmWKuujXtW //! B8yI3wCahwY0ADTTPReY84K5dS69mOI3crIziN8A4Jojxv8q6Vrdxo0eVoIDEb8BwC8jLTEcbGye //! HojfAJqHBjQANJOtYUkMR/qwXQxg80EAbmpbVCTFks+6EcPhD+I3APjJFsPBxub+I34DaD7+LwEA //! lxHDkT5s8RtMPwNwXSKRdGnTlLs8LAS7ffXiJ8Z14jcAuM0UwyFxR6XfiN8Amo8GNAA4ID/XvHEd //! bxrTgyl+w/bGHwCckNWpU9K1RFUVU9A+iG+vS7pG/AYAL9hiOLij0l/EbwDNRwMaABwwoci8cd2Y //! Oe97VAmSseXn2d74A4AT2t98k3GdKWhvVZauMq4TvwHAC7YYDu6o9I8tfuOKTjSfgVTQgAYABxT3 //! 7axWLTKTrtfGmYL220xLfp7tjT8AOKFtUZHyLrk46XqiqsrDaqJtW/kWbV+yOfkB2THiNwB4xvRZ //! QuKzhF9u/fgz4/o93RliAVJBAxoAHDLlfHMDk1vn/FNavkHJU1elvBxzhAoAOKnjhAnGdWI4vPH1 //! orXG9fxhx3tTCADI/lli3AvLPKoE+9pWH0+6RoQfkDoa0ADgkOK+nY1vQrh1zj+2zQcnDjFHqACA //! 0zLz8pKuEcPhjfqqmqRrsZxMpp8BeMq2GXZ1bfJGKNwx9iPzHZSXE78BpIwGNAA4yJYjzK1z/jBt //! PpidYX/DDwBOO2L8r5KuEcPhvm3lW4zreUOO9agSANjLFsNh29MEznpmozn/mfgNIHU0oAHAQbYc //! YWI4vGdr+t970ckeVQIAe7UtKjKuE8PhLlv8BtPPAPxgi+F41rKnCZxlmjnPJX8DaBQa0ADgIWI4 //! vGeL32D6GYBfiOHwjyl+IzOvpYeVAMBevC9NH7b4jXt7MP0MNAYNaABwWH6ueUM7bp3zlil+g8EF //! AH4ihsMftviNNmd38aYQAGjAKEukH58lvPG0JX7jgg7kPwONQQMaABw2oci8oR23znnH9gbdltkN //! AG6yxXBsmjTJo0qihfgNAOnMFunHZwn3zd1cqYRhPT+TVhrQWPxfAwAOK+7b2bqBCJsRemOm5Q26 //! 7Q0+ALjNFMNR9fwssqBdQPwGgHTHZwl/lawyP7+Tjz/So0qA8KABDQAusG0gwmaE7ist32CcXMjL //! MUelAIAXTDEcSiS05cGp3hUTAcRvAAgC22eJcS8s86iSaNpaV2dcJ34DaDwa0ADgguK+ndUyK/lL //! LJsRum/8PHP8xsQh5qgUuCcej+vuu+9Wly5ddMghh+ikk07S3LlzU/reK6+8UrFY7KCvm266yeWq //! AXe0LSoyTkHXbdzoYTXhR/wGgCCwbUZYXRv3qJLo+Y/yv8g0xUL8BtA0/J8DAC6554I+xnVunXPX //! tp31SdeyM9hl3E+//vWvNXHiRN1444367//+bxUWFuqiiy7SSy+9lNL3H3744Xr33Xf3+7r55ptd //! rhpwj3EKWiKGw0HEbwAICmI4/DF3aysplnyrcuI3gKahAQ0ALrE1OLl1zj22N+T3XnSyR5XgQFu2 //! bNF9992n2267TbfccosGDBigxx57TAMGDNBtt92W0s9o0aKFCgsL9/v6zne+43LlgHtsmxESw+EM //! 4jeCgztlgP1jOIZkvK3/a3Gt1rS8VGtaXqq/t7xWb897xMfqwqli5e2KG9pkuTHiN4CmogENx/GG //! EdgrI/nFc1XXxplccMnYuebmPtPP/lm0aJF27typUaNG7ff4qFGj9MEHH2jNmjU+VQb4K6tTp6Rr //! xHA4g/iN4OBOGWDv+9UhGW/r3uzH9G8Z3yoW2zWc2y72rX4Te0haNtvnKsNl48aZylCSeJNEQvf2 //! ONrbgoAQoQENx/GGEdjr0u+Z36SwGaHzSss3qKYueS5eTjanPj8tX75cLVu21LHHHrvf47167crk //! XrFihfVnbNmyRYcddpiysrJ0/PHH65577lF9ffLIFSAI2t9svthODEfzEb8RDNwpA+w1qvBo3Zo1 //! Wy1jB7/PyYhJKr3B+6JCatPm+ZKkgVokJQ4IgU4k1EvvM/0MNEOW3wUgXA58wyhJAwYM0D/+8Q/d //! dtttOvfcc60/Y/cbRiAMJhf31rNL1iVdZzNC59k2H7x7mDmbG+6qrKxUXl6eYgdk67Vr127PusnJ //! J5+sU089Vb169dKOHTs0b948jRs3TqtWrdLjjz/uWt2A29oWFWnjmFuTrm+acpc1qgPJEb8RHKY7 //! Zf793/9da9asUdeuXX2qDvDW5OLeipd/mfyA+E7vigm5iopxkqSr9IQkaXHibMWVoQzFNVCLdJWe //! lHSVjxUCwcYYGBzFrdXAwfJzs43rJaXmhilSV1q+wbj5oET8htNeffXVBqOTDvw688wzHfnzbrrp //! Jv3Hf/yHBg4cqHPPPVfTp0/XL37xCz3xxBNatWpVg98zbdo0FRQUqKCgQF988YUjdQBuMMVwJKqq //! mIJuhq9e/MS4TvxG+uBOGWB/GxOHmQ+YMcSbQkIukdh7l8xVekLPaLhm6kI9o+G6Sk/ohBPu87E6 //! IPhoQMNRvGEEDjahqJdxfaZhQhqNM+lFc6TJqEJy25x2+umnq6Kiwvr19NNPS5Ly8/NVVVWlxAG3 //! Nu6efN49Cd0Yl1xyiSSprKyswfVrr71WZWVlKisr0+GHH97onw94xRbDsWnKXR5VEi7byrcovr0u //! 6TrxG+nFiTtl7r//fs2ePVsLFixQ//79NW7cOF133XWu1Qy46a9dfnZQIsR+1rzpWS1h9X9/v8x6 //! TMcOQz2oBAgvIjjgKG6tBg5W3Lezxs/7IOlkrun9JBpn63ZzpMnk4t7GdTRebm6uevTokfLxvXr1 //! Uk1NjT755JP9LlbuvkB5wgknNLmWA889QNC0LSrS9r//XVV/fL7B9URVlccVhUPVvIbvjtiN+A13 //! vfrqqxo0aJD1uP79++uNN95o9p934Obl5557rlq3bq2pU6dq7NixOu644w76nmnTpmnatGmSxJ0y //! SDvD//2XSky8w3zQwtHSeQ94U1AIVVX91bjeqdNIjyoBwosJaBhxazXgjCnnmxufxHA0X2n5BuN6 //! Xo45CgXeOOecc5Sdna2ZM2fu9/izzz6rE088sUm5njNnzlQsFtN3v/tdp8oEfNNxwgTjOjEcjbOt //! fIsSO5NvTJtb2IH4DZdxpwzQfLFMy50aZU94U0gIVay83XpMzx6WCwAArJiAhtHuN4w2ubm5kvZ/ //! w7jvJFpz3zBOnTpVZWVlDU4sXHvttbr22mslSQUFBY3++YAXivt21k2z3k+6/uySdUznNpMtfmPi //! EHMUCrzRvn17jR49WnfffbcOPfRQnXLKKZo1a5YWL16sBQsW7HfsWWedpU8//VT/+Mc/JEmffvqp //! LrvsMl188cU69thjVVNTo3nz5umpp57Sddddp27duvnxnwQ4LjMvT/VJpp3ZjLBxvl601rjervjg //! 95ZwFnfKAA4Y+pD0wjXmY5bNlvoM96aeENm4caZxPS/vdI8qAcKNBjSMeMMIOCc/N9sYEVFavoEN //! 8prBFr/Bc5s+pkyZotatW+u3v/2tNm/erO7du2v27Nk677zz9juuvr5edXV7c1sPPfRQtWvXTvfc //! c48+//xzZWRkqEePHvrd736nn/3sZ17/ZwCuOWL8r7RxzK0NrhHD0Tj1VTVJ12I5mR5WglTte6fM //! hH3uCOBOGURan+FS6fVSPHmevUpvoAHdSJs2z7cec+opz3hQCRB+NKDhKN4wAslNKOplnIIeM+d9 //! mqRNZIswIX4jvWRmZqqkpEQlJSXG4w7MAm3Xrp1KS0tdrAxID22LipI2oKVdMRxMQacmM69l0iZ0 //! 3pBjG3wc/uJOGSCJ4kfNU9Dxnd7VEhIVFeMsR5BaCziFBjQcxRtGILnivp01du4y1dQ1nEVZG2cK //! uqlmLllnXCd+A0DQEMPhjIrt/6tj4icoK2PvhchEIqGtbf6pI/ue4WNlMOFOGaABfYbbYzge+p50 //! 43ve1BMCiUTyu2Qk6YQT7vOoEiD8aEDDcbxhBJK754I+xinocS8sowHdSKXlG5QwrOdkZ/CcAggc //! Yjiar+Kt11X+0cv6Z6tP1Se/v3Kz2mh73ddatvVNrft0pfrofL9LRBLcKQMk0bW/tObN5OtfrvSu //! loD767vnWI/p2GGoB5UA0UADGo7jDSOQXHHfzrp51vtJG6bVtQ1PRyM52+aDdw/r41ElAOAcWwzH //! pkmT1HGfuDMcbNFjv5MkrdtWoXXb7JtqA0Dau2KBNLGt+ZiFo6XzHvCmngCrrl5lXO/UaaRHlQDR //! QKANAHhsZOHRxvXS8g0eVRIObD4IIKwy8/KSrlU9P0tfvfiih9UEy6uPP6L6WvP5AQACqWt/83rZ //! E97UEWAVK2+3HtOzxx0eVAJEBw1oAPDY5OLexvUxc5JHdGB/bD4IIMyOGP+r5IuJhLY8ONW7YgKk //! 4q3XtfSVl4zHZLZs6VE1AOCwKxbYj1k42v06AmzjxpnG9by80z2qBIgOGtAA4INWLTKTru3ejBB2 //! z7L5IIAQa1tUZJyCrtu40cNqguPlR+2N+bOvudGDSgDAJZmWi2hMQSe1afN86zGnnvKMB5UA0UID //! GgB8MOV88xT0uBeWeVRJcNmmn9l8EEAYGKegJWI4DjD7zvGK19cbjznqxJPU84wBHlUEAC4Y+pDf //! FQRWRUXy/RV24Q5KwA00oAHAB8V9OytmWGczQruZlulnNh8EEAZti4qM68Rw7FXx1uta/+FS4zGx //! zEwN//UUjyoCAJf0GW4/ZsYQ9+sImE2b5yuRqDMec8IJ93hUDRAtNKABwCe2zQhtE75RVlq+QQnD //! enYGmw8CCI+sTp2SrhHDsdeix35nPebH19/kQSUA4IGCq83ra970po4AqagYZz2mY4ehHlQCRA8N //! aADwiW0zQlu+cZSNn2duzt970ckeVQIA7mt/s7lpSgyH9Orjj6i+ttZ4DNEbAELlvAfsxzAFvZ9E //! osa43qnTSI8qAaKHBjQA+Mi0GaHEFHRDSss3aNtOc74n088AwsQWw7Fpyl0eVZKeKt56XUtfecl8 //! UCxG9AaA8Ona37zOFPQe//f3y6zH9OxxhweVANFEAxoAfGTbjJAp6IPZpp/zctg4BED4mGI4ElVV //! kZ6CfvlRew72uTeM9qASAPDYFQvsxyzk9U+Sqqr+alzPyzvdo0qAaKIBDQA+Ku7bWS2zzC/FTEHv //! lcr088QhvTyqBgC8Y4vhiOoU9Ow7xytebz4vEL0BINQO62FeL3vCmzrS2KbN863HnHrKMx5UAkQX //! DWgA8Nk9F/QxrjMFvdekF5cb13OyM4jfABBKbYuKlHfJxUnXE1VVHlaTHireel3rP1xqPCaWmUn0 //! BoBwu/E9+zHLZrtfRxqrqLjVuM70M+A+GtAA4LNUpqBLyzd4VE1627rdvMHU3cPMzXwACLKOEyYY //! 16MWw7Hosd9Zj/nx9ebJcQAIhcyW5vUXfupNHWlo0+b5SiTqjMcw/Qy4jwY0AKQB2xT0uBeWeVRJ //! +rI14Zl+BhAFmXl5SdeiFMPx6uOPqL7WfFGS6A0AkTH0IcsB9ZGdgq6oGOd3CQBEAxoA0oKtcVpd //! G4/8FPQtc8y3WTP9DCAKjhj/q6RrUYnhqHjrdS195SXzQbEY0RsAoqPPcPsxpTe4X0caSiRqjOud //! Oo30qBIg2mhAA0CayM/NNq6PmfO+R5Wkn5LSD1QXTxiPYfoZQBS0LSoyrkchhuPlR6dajzn3htEe //! VAIAaaTgavN6fKc3daSR//v7ZdZjeva4w4NKANCABoA0MaGol3G9Nh7dLGjbRoyjCo/2qBIA8F+U //! Yzhm3zle8fp64zFEbwCIpPMesB+zMFoX57Zu/atxnc0HAe/QgAaANFHct7Natcg0HhPFKeiS0g+s //! x0wu7k0SELIAABmRSURBVO1BJQCQHqIaw1Hx1uta/6E5jimWmUn0BoDo6tp/v3+d3C5PJ3U5Sr27 //! HKWTuhylyavn+lSY92bMmGE9hs0HAe/QgAaANDLlfHMjNYpT0Ew/A8D+bDEcmyZN8qgSb6USvfHj //! 62/yoBIASFNXLNjzj5Pb5WlWm0MVj8WkWEzxWEyz2hyqyX/8sY8FemfNmjVJ1xIJpp8Br9GABoA0 //! Uty3s/p1a2c8ZtwLyzyqxn+2ZnuGmH4GEE2mGI6q52eFLgua6A0ASFFmS0nSrDaHSrHY/muxmGbV //! rPehKG/dfffd1mOYfga8RQMaANLMzGtOM65X18YjMwV9yxzzrdYPjDjZo0oAIL2YYjiUSGjLg/Zp //! 4aBIJXpDsRjRGwAgSUMfsh5y1qyzPCjEH8uWLVNNTY0kKR6PNXhMsscBuIcGNACkIbKgd2U/18UT //! xmOK+3b2qBoASC9ti4qMU9B1Gzd6WI27UoneOPeGaG2sBQBJ9RkuxQytnlhMW3Zs0Z9X/9m7mjz0 //! wgsv7PnnVR+frnh8//V4XKqvG+VxVQBoQANAGiILmuxnALAxTkFLoYjhIHoDAJrg/Mesh9z21m0e //! FOKthQsX7vfvX3xxjD7+qJ927GilRELasaOV/rHqDP34xxP9KRCIMBrQAJCGivt2jvQUdEnpB9Zj //! yH4GEHW2zQiDHsORSvRGuyOPInoDAA7UZ7gyTFPQ/zJ5yWQPivFOWVnZQY998cUx+tv/DtPbb12m //! v/3vMF1//VPeFwaABjQApKsoT0Ez/QwAqcnq1CnpWtBjOFKJ3rjq/kc9qAQAgueuM+wb8c36aJYH //! lXjjoYfs2deHHXaYB5UAaAgNaABIU8V9O6tft3bGY0bPCt8U9Mjp7xrXM8T0MwDs1v7mm4zrQY3h //! ePXxR6zRGycNOtejagAgeAYfM1jtD2lvPS4sGxJ++eWX1mNuvPFGDyoB0BAa0ACQxmZec5pxPS57 //! wzZISss36J1PKo3HPDDiZI+qAYD0Z4vh2DTlLo8qcdbSV14yHxCL6Yc/+Zk3xQBAQL024jXrMWHY //! kPDOO++0HtO1a1cPKgGQDA1oAEhztizodz6pDE0Ux/h59uzn4r6dPagEAILDFMORqKoK3BT0k7+8 //! 3nrMuTeM9qASAAi+wg6F1mOCvCHhwoULVW+5Y0aSrrjiCg+qAZAMDWgASHO2LGhJmrhguQeVuG/b //! TvObR7KfAeBgthiOIG1GOPvO8ar8bL3xmKNOPEk9zxjgUUUAEGzTz56e0nFB3ZCwoY0HDzRs2DAP //! KgFgQgMaANJcKlnQVdW1HlXjHrKfAaBp2hYVKe+Si/f8+99736DF/R/a8/VKtzH6+L3NPlaYmoq3 //! Xtf6D5eaD4rFNPzXU7wpCABC4j/P+E/rMUHckHDGjBnWY1q2bKk+ffp4UA0AExrQABAAM685TVkZ //! MeMxQc6CJvsZAJqn44QJUiymv/e+QVXtekqx2J6vRGYLvfLkcj03Mb3PEy8/ap/UJnoDABpv8DGD //! dWjWodbjiucVe1CNc9asWWM9Zty4cR5UAsCGBjQABMR9F51kXA9yFvQtc8wTb9kZZD8DgFUisbf5 //! fJCYtm6u1sM/XZyW09CvPv6I4pYMT6I3AKDp/jryr9ZjPvn6Ew8qccZ9991nPYaNB4H0QQMaAAKi //! uG9nmWegpZtmve9JLU4aOf1d1cUTxmPuvYjpZwCwMW1GuK9XnlyRdtPQS195yXwA0RsA0GypbEhY //! 8HSBB5U0z7Jly/Ttt99aj2PjQSB90IAGgAAZmcImfEGK4kgleoPpZwBIjW0zwn2l0zT0k7+83noM //! 0RsA0HypbEhYk6hJ+w0JX3jhBesxBQXp30gHooQGNAAEyOTi3tYs6CBFcdiiNySmnwEgVW2LinRY //! i61SwnxXyb78noaefed4VX623ngM0RsA4Jygb0i4cOHClI4777zzXK4EQGPQgAaAgLFlQUvS6ABE //! caQSvdGvWzumnwGgEUb8/kId0jLRqCa0X9PQFW+9rvUfWi5EEr0BAI4K+oaEZWVl1mOGDRvmQSUA //! GoMGNAAETHHfzjqufSvjMXGldxRHKtEbkjTzmtM8qAYAwuXq3/1QJ/Zv/MU7r6ehX350qvUYojcA //! wHlB3ZBw6sTfSJbrq61bt1afPn28KQhAymhAA0AAvTL6TFmSONI6imP0bPuE9qgU8q4BAA3rf2kP //! 3fCHgcptk92o7/NqGvrVxx9RvL7eeAzRGwDgngM3JPzVc3Wadff+X/97Uk+fqjvYZ+PfUlViu2y7 //! st9yyy3eFASgUWhAA0BAPTDcno18UxpGcQx64A1Zkjd0XPtWmlzc25uCACDErvrNGTrxB50a/X1u //! T0MvfeUl8wFEbwCAq/bdkPBXz9XppE939Xb3/WpdI1X08L8J/dmEtyXzNUtJUteuXd0vBkCT0IAG //! gIAq7ttZ/bq1sx73vSmveFBNakZOf1ertmwzHpOhXRPeAABnpNs09JO/vN56DNEbAOC+Ed1HSNKe //! 5vOBdj/mZxP6synvSjWp7WtwxRVXuFwNgKaiAQ0AAZZKRvLn3+xMizzoVHOfHxhhn+wGADReOkxD //! z75zvCo/W288hugNAPBGSWGJWsZapnSsH03oz6cvlb6p2/PveYmchjOgE2w8CKQ7GtAAEHCpZCW/ //! 80mlSko/8KCa5G5OIQ7kuPatVNy38RtnAQBS4+c0dMVbr2v9h0vNBxG9AQCeKru8LOVjvWxCV5au //! Uu0nX+/32IU7T9/bhP7XVywR05mZvdl4EEhzNKABIOAmF/fWce1bWY97dsk63zYl/N6UV2wbVksi //! egMAvOLHNPTLj061HkP0BgB4r/rkY1N6ry5504SuLF2l7UsavuB54c7T9ZOas/Z8XV0zUGfefoHr //! NQFoHhrQABACr4w+U0cc2sJ6nB+bEg564A19/s1O63FTid4AAE95OQ396uOPKF5v3kGK6A0A8Mep //! z7+oeIvMtGhCbyvfkrT53JAj//MM12oB4Bwa0AAQEu+NH5TScT3Gv+RyJXsNeuAN66aD0q4YEaI3 //! AMAfXkxDL33Fcu4hegMAfHXisg8Va5laHrQkVfQ8wZU6ts76KOVjaT4DwUEDGgBCJJU86B31CfWZ //! 8LLrtaTafD6ufStNLu7tej0AgOTcnIZ+8pfXW38O0RsA4L+eS9+XDj00tYMTCVX0OtHRP/+z295K //! +Viaz0Cw0IAGgBBJNQ/665p6VyehU20+t2mZSe5zBD3wwAMqKipSx44dFYvFNHHixEZ9/9tvv63T //! Tz9dOTk56tChg0aPHq3q6mp3igUixulp6Nl3jlflZ+uN30v0BgCkj55/+18p1Uno+nrHJqFpPgPh //! RgMaAELmldFnptSE3lGfUJfb/uz4xoTfm/JKSs1nSVo26RxH/2wEw/Tp07VlyxYVFxc3+nuXLVum //! QYMGqX379lq4cKEmT56sJ598UldeeaXzhQIR5dQ0dMVbr2v9h0vN30T0BhrAhUrAXz2Xvi9lZiZd //! X/z9+7S4/0O7vn7wez38k6YPttw/4jx9euvrSiRSS6Cm+QwEU5bfBQAAnPfK6DPVZ8LL+rrGvOGT //! tGtjwrJPKx2Jwegx/iXtqE/tzSObDkbX8uXLlZGRobq6Ov3hD39o1PdOmDBBRx55pObMmaPs7F3N //! sRYtWuiKK67Q2LFjdcopp7hRMhBJV/3mDL353Ep9+JeNjfq+V55cobL/XqPPP55qPZboDTRk+vTp //! atOmjYqLixt9nth9ofLss8/WwoULtWbNGo0ZM0YbNmzQrFmzXKoYCJ+eyz/cFbFxwAayi79/n5R5 //! iBSL7X0ws6Uevu61PY/d8IeBxp89ddQw1dfu2qT86FY9lRHLVGzfn5cEzWcguJiAhuOYWADSw7JJ //! 5+iQTPsbOUl6dsk6DXrgjSb/WSWlH6jLbX9Oufncr1s7Nh2MsIyMpr39qK2t1csvv6zhw4fvaT5L //! 0vDhw9WiRQvNnz/fqRIB/EtTp6E3/+NFxevNF0GJ3kAyy5cv13vvvaff//73jf7efS9UnnXWWfrJ //! T36i3/72t5o9e7b+/ve/u1AtEF49l3+4f6NZOrj5LO36930ee/ini/d87b4r5slfXq/7R5yn+0ec //! t6f5LEl98vvTfAYigAY0HMet1UD6WDnlXLVpmfz2uX2t2rJNXW77s0ZOPzjDM5nS8g3qctuf9eyS //! dSl/T79u7TTzmtNSPh7Y7ZNPPtGOHTt04on7b3hzyCGHqFu3blqxYoVPlQHh19hs6ETtMvMBRG/A //! gAuVQProWdH091d1NRV68YGf6P4R5yXdDyA3q43159B8BoKPCA44jlurgfSybNI5jYrGeOeTSnW5 //! 7c/KyojpvotOanBSOdVNBg9E8xnNUVlZKUnKz88/aK1du3Z71gG4o/+lPdT/0h568ta3tP3r2qTH //! 1Xz7qvVnEb0BN3ChEnBHz5UVqujRs1HfU1dTobrt/209bnvd12qV3Tbpev6I7o36cwGkJyag4Tgm //! FoD0s3LKuSnHcexWF0/oplnvq8ttfz7oi+Yzdnv11VcVi8WsX2eeeaZvNU6bNk0FBQUqKCjQF198 //! 4VsdQFjYpqFt089Eb8AtXKgE3NNzZcWuf6jfIaWwYWDd9v9J6ecu2/qm6uN1Bz2eSCSUW9hBrfq2 //! b1SdANITE9BIG0wsAO5aOeXclDcmdNrUESeT+RxSp59+uioqKqzH5ebmNvvP2t1Q2Lp160FrlZWV //! 6tWrV4Pfd+211+raa6+VJBUUFDS7DgCpT0MfhOiNyHn11Vc1aNAg63H9+/fXG2+84X5BDZg2bZqm //! TZsmSVyoBAx6rqxQxg/669Uev971gDG7ObXPHOu27Xof2bfdD9UyM0eSVBOvVsdL+9J8BkKEBjTS //! BhMLgPuWTTpH35vyij7/Zqf9YAcckhnTyinnevJnwR+5ubnq0aOHJ39Wt27d1LJlSy1fvny/x3fs //! 2KHVq1froosu8qQOAHtd9Zsz9OZzK/XhXzamdDzRG9HDhUogXLr/5U11166NBp2yblvFvxrRMf1y //! 1ouO/VwA6YMGNIyYWADC573xg1RS+kGjNg5siuPat9Iro8909c9AtLRo0ULnnHOOZs+erYkTJyor //! a9fbmD/96U+qqanRkCFDfK4QiKaDp6Ez1fDkW4zojQjiQiUQTjf8YeCef25uM/qkQefqhz/5WXNL //! ApDGaEDDiIkFIJwmF/fW5OLeTd5M0CQm6UEiN2BQVlamtWvXKh6PS5JWrFihP/3pT5Kkc889d885 //! 5eqrr9aMGTNUV7c3F3DixIkqLCzU8OHDdcMNN2jt2rUaM2aMLrzwQp166qne/8cA2GP3NPT7r/yo //! wY2n+v74ah+qQpRwoRLwR4PN6IyjpPj6pN/TIreV/uPJWW6XBiBN0ICGERMLQLjtnlAeOf1dvfNJ //! 82NuRhUercnFvZv9cxBuDz30kGbMmLHn3+fMmaM5c+ZIktasWaMuXbpIkurr61Vfv/8U5cknn6z/ //! +Z//0dixYzV48GC1bdtWl19+ue666y7P6geQ3O5p6MVPddbSV2YrXve1MrLa6KRBwzXwymK/y0NA //! cKESCK69zeiBemDU9UrU7m1Cx7KP0uhnH/WnMAC+iiUSKWxfCjRBXV2dsrOzNWHCBE2cODGl7yku //! LtaKFSu0YsWKPRMLzz77rC677DKVlZVZ3zQWFBSorKysuaUDkdWUaI5+3dpp5jWnuVQRnMLr4y48 //! DwDQsHR6fbzyyiv3u1C5r30vVO4+7sCPtH/5y180duxYlZeXq23btrrkkkt01113pXTXZjo9DwCQ //! Tnh9RHMwAQ3HMbEABNfuaA4AAAC/PPXUU3rqqaeafNwPfvADvfvuu84XBgAAmoQGNBzHrdUAAAAA //! AAAAJCnD7wIQPk899ZQSiUSDX7ubz/sed6DdEws7duzQ559/rqlTpzqyySEAAAAAAAAAb9GABgAA //! AAAAAAC4ggY0AAAAAAAAAMAVNKABAAAAAAAAAK6gAQ0AAAAAAAAAcAUNaAAAAAAAAACAK2hAAwAA //! AAAAAABcQQMaAAAAAAAAAOCKWCKRSPhdBOCUww47TF26dGnS937xxRc6/PDDnS0o4nhOncdz6ryo //! PKdr167Vl19+6XcZvuM8kV54Tp3F8+m8KD2nnCd24TyRPng+ncdz6qyoPZ+cJ9AcNKCBfykoKFBZ //! WZnfZYQKz6nzeE6dx3OKVPF3xXk8p87i+XQezykag78vzuL5dB7PqbN4PoHUEcEBAAAAAAAAAHAF //! DWgAAAAAAAAAgCsyJ06cONHvIoB0ceqpp/pdQujwnDqP59R5PKdIFX9XnMdz6iyeT+fxnKIx+Pvi //! LJ5P5/GcOovnE0gNGdAAAAAAAAAAAFcQwQEAAAAAAAAAcAUNaETa+vXrdeGFF6pt27Zq06aNhg0b //! pnXr1vldVmD96U9/0gUXXKDvfOc7ysnJUffu3TVu3Dh98803fpcWKuecc45isZhKSkr8LiXQXnrp //! Jf3gBz9Q69at1aZNGxUUFGjx4sV+l4U0w3nCWZwn3Mc5whmcI5AqzhPO4RzhPs4RzuAcATQeDWhE //! 1vbt2zVw4ECtXLlSM2bM0DPPPKNVq1ZpwIAB2rZtm9/lBdJ9992nzMxM3XXXXXr55Zd1/fXX69FH //! H9WgQYMUj8f9Li8U/vjHP2rp0qV+lxF4jz32mIYOHapTTz1V8+bN05w5c3TRRRdp+/btfpeGNMJ5 //! wnmcJ9zFOcIZnCOQKs4TzuIc4S7OEc7gHAE0UQKIqKlTpyYyMjISq1at2vPY6tWrE5mZmYn777/f //! x8qCa8uWLQc9NmPGjISkxGuvveZDReFSWVmZOOKIIxLPPfdcQlJi/PjxfpcUSGvWrEkccsghiQcf //! fNDvUpDmOE84j/OEezhHOINzBBqD84SzOEe4h3OEMzhHAE3HBDQia8GCBSosLNSxxx6757GuXbuq //! X79+mj9/vo+VBdfhhx9+0GPf/e53JUkbNmzwupzQGTt2rE488URdcsklfpcSaP/1X/+ljIwM/fSn //! P/W7FKQ5zhPO4zzhHs4RzuAcgcbgPOEszhHu4RzhDM4RQNPRgEZkLV++XCeeeOJBj/fq1UsrVqzw //! oaJwevPNNyVJPXv29LmSYHv77bf19NNP6+GHH/a7lMB7++231aNHDz3//PPq1q2bsrKydOyxx/Lc //! 4iCcJ7zBeaL5OEc4h3MEGoPzhPs4RzQf5wjncI4Ami7L7wIAv1RWVio/P/+gx9u1a6etW7f6UFH4 //! bNiwQbfffrt++MMfqqCgwO9yAmvnzp267rrrdMstt6h79+5+lxN4Gzdu1MaNGzVmzBjddddd6tat //! m+bMmaMbb7xRdXV1+sUvfuF3iUgTnCfcx3mi+ThHOItzBBqD84S7OEc0H+cIZ3GOAJqOBjQAV3z7 //! 7bcaOnSosrKy9OSTT/pdTqD95je/UXV1tcaPH+93KaEQj8f1zTff6KmnntKwYcMkSQMHDtTatWt1 //! 99136+c//7lisZjPVQLhx3nCGZwjnMU5AkgPnCOcwTnCWZwjgKYjggORlZ+f3+BkQrJJBqSuurpa //! RUVFWr16tRYtWqQjjzzS75ICa926dZoyZYruvPNO1dTUqKqqSlVVVZK059/r6+t9rjJY/u3f/k2S //! NGjQoP0e/9GPfqTPP/9cmzZt8qMspCHOE+7hPOEMzhHO4xyBxuA84Q7OEc7gHOE8zhFA09GARmT1 //! 6tVLy5cvP+jxFStW6IQTTvChonCora3VhRdeqLKyMr300kvq3bu33yUF2urVq7Vjxw6NGjVK+fn5 //! e74k6b777lN+fr4++OADn6sMll69ehnXMzI4NWIXzhPu4DzhHM4RzuMcgcbgPOE8zhHO4RzhPM4R //! QNPxfwcia8iQIVqyZIlWr16957G1a9fqnXfe0ZAhQ3ysLLji8bhGjhypxYsXq7S0VIWFhX6XFHgn //! n3yyXn/99YO+JGnUqFF6/fXX99t5HXbnn3++JGnRokX7Pf7yyy/ryCOPVIcOHfwoC2mI84TzOE84 //! i3OE8zhHoDE4TziLc4SzOEc4j3ME0HSxRCKR8LsIwA/btm3TSSedpJycHE2ePFmxWEy//vWv9c03 //! 32jZsmVq3bq13yUGzvXXX68//OEPGj9+vM4777z91o488khun3NQLBbT+PHjNXnyZL9LCZxEIqGz //! zjpLS5cu1ZQpU3TMMcdozpw5evzxx/Xkk0/qyiuv9LtEpAnOE87jPOENzhFNxzkCjcF5wlmcI7zB //! OaLpOEcAzZAAIuzTTz9NDBs2LHHooYcmWrdunRg6dGhizZo1fpcVWN/5zncSkhr8mjBhgt/lhYqk //! xPjx4/0uI7C++uqrxM9+9rNE+/btE9nZ2YnevXsnZs6c6XdZSEOcJ5zFecIbnCOah3MEGoPzhHM4 //! R3iDc0TzcI4AmoYJaAAAAAAAAACAK8iABgAAAAAAAAC4ggY0AAAAAAAAAMAVNKABAAAAAAAAAK6g //! AQ0AAAAAAAAAcAUNaAAAAAAAAACAK2hAAwAAAAAAAABcQQMaAAAAAAAAAOAKGtAAAAAAAAAAAFfQ //! gAYAAAAAAAAAuIIGNAAAAAAAAADAFTSgAQAAAAAAAACuoAENAAAAAAAAAHAFDWgAAAAAAAAAgCto //! QAMAAAAAAAAAXEEDGgAAAAAAAPj/7dixAAAAAMAgf+tR7CuMgIWABgAAAABgIaABAAAAAFgIaAAA //! AAAAFgIaAAAAAICFgAYAAAAAYCGgAQAAAABYCGgAAAAAABYCGgAAAACAhYAGAAAAAGAhoAEAAAAA //! WASuc53nV8F7nQAAAABJRU5ErkJggg== //! "> //! </div> //! //! In the example above, we show the original 1000 data points (left), a PLR with //! a maximum error of 0.05 (center), and a PLR with a maximum error of 0.005. All //! of the displayed PLRs are optimal, meaning that they contain the fewest number //! segments possible to achieve their error bound. //! //! This package can perform PLR using one of two online algorithms: //! * [Greedy PLR](struct.GreedyPLR.html), which uses a constant time per point and a //! constant amount of space. Greedy PLR always finds a PLR with the specified error //! bound (e.g., none of the original points will be more than δ from their predictions), //! but the greedy approach may not find the PLR with the minimal number of segments. //! * [Optimal PLR](struct.OptimalPLR.html), which uses a linear time per point and //! potentially linear space. In practice, the amount of space used by the optimal algorithm //! should be small, but in the worst case linear space may be required (see //! [the paper](https://dl.acm.org/citation.cfm?id=2691542) for more details). The optimal //! algorithm will find the solution with a minimal number of segments. //! //! Written by [Ryan Marcus](https://rmarcus.info), licensed under the GPL v3. mod util; mod greedy; mod optimal; #[cfg(test)] mod test_util; pub use greedy::GreedyPLR; pub use optimal::OptimalPLR; pub use util::Segment;