Advertisement
Tuurlijk

Trim Explode Text

Jan 17th, 2014
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.98 KB | None | 0 0
  1. <?php
  2. error_reporting(E_ALL & ~E_NOTICE);
  3. /*****************************************************************************
  4.  *  Copyright notice
  5.  *
  6.  *  ⓒ 2013 Michiel Roos <michiel@maxserv.nl>
  7.  *  All rights reserved
  8.  *
  9.  *  This script is part of the TYPO3 project. The TYPO3 project is free
  10.  *  software; you can redistribute it and/or modify it under the terms of the
  11.  *  GNU General Public License as published by the Free Software Foundation;
  12.  *  either version 2 of the License, or (at your option) any later version.
  13.  *
  14.  *  The GNU General Public License can be found at
  15.  *  http://www.gnu.org/copyleft/gpl.html.
  16.  *
  17.  *  This script is distributed in the hope that it will be useful, but
  18.  *  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  19.  *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  20.  *  more details.
  21.  *
  22.  *  This copyright notice MUST APPEAR in all copies of the script!
  23.  ****************************************************************************/
  24.  
  25. // Setup
  26. $testName = '\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode';
  27. $reverseExecutionOrder = 0;
  28. $runs = 100;
  29.  
  30. // Parameter Sets
  31. $parameterSets = array(
  32.     'set1' => array (
  33.         'description' => 'CSV, no removeEmpty, no limit',
  34.         'delim' => ',',
  35.         'string' => 'a, b, c, ,d, e, f',
  36.         'removeEmptyValues' => FALSE,
  37.         'limit' => 0,
  38.     ),
  39.     'set2' => array (
  40.         'description' => 'CSV, removeEmpty, no limit',
  41.         'delim' => ',',
  42.         'string' => 'a, b, c, ,d, e, f',
  43.         'removeEmptyValues' => TRUE,
  44.         'limit' => 0,
  45.     ),
  46.     'set3' => array (
  47.         'description' => 'CSV, no removeEmpty, limit 3',
  48.         'delim' => ',',
  49.         'string' => 'a, b, c, ,d, e, f',
  50.         'removeEmptyValues' => FALSE,
  51.         'limit' => 3,
  52.     ),
  53.     'set4' => array (
  54.         'description' => 'CSV, removeEmpty, limit -3',
  55.         'delim' => ',',
  56.         'string' => 'a, b, c, ,d, e, f',
  57.         'removeEmptyValues' => TRUE,
  58.         'limit' => -3,
  59.     ),
  60.     'set5' => array (
  61.         'description' => 'LF, removeEmpty, limit -3',
  62.         'delim' => ',',
  63.         'string' => ' a , b , ' . PHP_EOL . ' ,d ,,  e,f,',
  64.         'removeEmptyValues' => TRUE,
  65.         'limit' => -3,
  66.     ),
  67.     'set6' => array (
  68.         'description' => 'Keep 0, removeEmpty, no limit',
  69.         'delim' => ',',
  70.         'string' => 'a , b , c , ,d ,, ,e,f, 0 ,',
  71.         'removeEmptyValues' => TRUE,
  72.         'limit' => 0,
  73.     ),
  74.  
  75. );
  76.  
  77. /*****************************************************************************
  78.  * Tests:
  79.  ****************************************************************************/
  80.  
  81. /**
  82.  * Baseline
  83.  *
  84.  * @return array|string
  85.  */
  86. $descriptions['version1'] = 'Baseline trimExplode';
  87. /**
  88.  * Explodes a string and trims all values for whitespace in the ends.
  89.  * If $onlyNonEmptyValues is set, then all blank ('') values are removed.
  90.  *
  91.  * @param string $delim Delimiter string to explode with
  92.  * @param string $string The string to explode
  93.  * @param boolean $removeEmptyValues If set, all empty values will be removed in output
  94.  * @param integer $limit If positive, the result will contain a maximum of
  95.  * @return array Exploded values
  96.  */
  97. function version1($delim, $string, $removeEmptyValues = FALSE, $limit = 0) {
  98.     $explodedValues = explode($delim, $string);
  99.     $result = array_map('trim', $explodedValues);
  100.     if ($removeEmptyValues) {
  101.         $temp = array();
  102.         foreach ($result as $value) {
  103.             if ($value !== '') {
  104.                 $temp[] = $value;
  105.             }
  106.         }
  107.         $result = $temp;
  108.     }
  109.     if ($limit != 0) {
  110.         if ($limit < 0) {
  111.             $result = array_slice($result, 0, $limit);
  112.         } elseif (count($result) > $limit) {
  113.             $lastElements = array_slice($result, $limit - 1);
  114.             $result = array_slice($result, 0, $limit - 1);
  115.             $result[] = implode($delim, $lastElements);
  116.         }
  117.     }
  118.     return $result;
  119. }
  120.  
  121. $descriptions['version2'] = 'Optimized version';
  122. function version2($delim, $string, $removeEmptyValues = FALSE, $limit = 0) {
  123.     if ($delim !== ' ') {
  124.         $string = str_replace(
  125.             array(
  126.                 ' ',
  127.                 "\t",
  128.                 "\n",
  129.                 "\r",
  130.                 "\0",
  131.                 "\x0B"
  132.             ),
  133.             '',
  134.             $string
  135.         );
  136.         $result = explode($delim, $string);
  137.     } else {
  138.         $explodedValues = explode($delim, $string);
  139.         $result = array_map('trim', $explodedValues);
  140.     }
  141.     if ($removeEmptyValues) {
  142.         $result = array_filter($result);
  143.     }
  144.     if ($limit != 0) {
  145.         if ($limit < 0) {
  146.             $result = array_slice($result, 0, $limit);
  147.         } elseif (count($result) > $limit) {
  148.             $lastElements = array_slice($result, $limit - 1);
  149.             $result = array_slice($result, 0, $limit - 1);
  150.             $result[] = implode($delim, $lastElements);
  151.         }
  152.     }
  153.     return $result;
  154. }
  155.  
  156.  
  157. /*****************************************************************************
  158.  * Helper functions needed for test:
  159.  ****************************************************************************/
  160.  
  161.  
  162. /*****************************************************************************
  163.  * System (look, but don't touch ;-) . . . only touch if you must.
  164.  ****************************************************************************/
  165.  
  166. // Show source?
  167. if (isset($_GET['source']) && $_GET['source']) {
  168.     show_source(__FILE__);
  169.     exit;
  170. }
  171.  
  172. // How many runs?
  173. if (isset($_GET['runs'])) $runs = preg_replace('/[^0-9]/', '', $_GET['runs']);
  174.  
  175. // Execution order?
  176. if (isset($_GET['reverseExecutionOrder'])) $reverseExecutionOrder = intval($_GET['reverseExecutionOrder']);
  177.  
  178. // Prepare
  179. $baselineTimes = $functionsToCall = $times = array();
  180. $allFunctions = get_defined_functions();
  181. $functions = array_filter($allFunctions['user'], create_function('$a','return strpos($a, "version") === 0;'));
  182. if ($reverseExecutionOrder) arsort($functions);
  183. foreach ($functions as $function) {
  184.     $xAxis[] = $function;
  185.     $functionsToCall[$function] = new ReflectionFunction($function);
  186. }
  187.  
  188. // Execute
  189. foreach ($parameterSets as $setName => $parameters) {
  190.     // Description is used later on, so clone the parameters
  191.     $functionParameters = $parameters;
  192.     unset($functionParameters['description']);
  193.     for ($i = 0; $i < $runs; $i++) {
  194.         foreach ($functions as $function) {
  195.             $start = microtime(TRUE);
  196.             $result = $functionsToCall[$function]->invokeArgs($functionParameters);
  197.             $time = microtime(TRUE) - $start;
  198.             if ($function === 'version1') {
  199.                 $baselineTimes[$setName] += $time * 1000;
  200.             }
  201.             if (is_array($result)) {
  202.                 $resultObjects[$setName][$function] = array_slice($result, 0, 20, TRUE);
  203.             } else {
  204.                 $resultObjects[$setName][$function] = $result;
  205.             }
  206.             $times[$setName][$function] += $time * 1000;
  207.         }
  208.     }
  209. }
  210.  
  211. function findWinner($times) {
  212.     $averagedTimes = array();
  213.     foreach ($times as $setName => $timeData) {
  214.         foreach ($timeData as $functionName => $time) {
  215.             $averagedTimes[$functionName] += $time;
  216.         }
  217.     }
  218.     asort($averagedTimes);
  219.     return $averagedTimes;
  220. }
  221.  
  222. $averagedTimes = findWinner($times);
  223.  
  224. /**
  225.  * Format an integer as a time value
  226.  *
  227.  * @param integer $time The value to format
  228.  *
  229.  * @return string
  230.  */
  231. function printSeconds($time) {
  232.     $prefix = '';
  233.     $suffix = 'μs';
  234.     if ($time < 0) {
  235.         $time = abs($time);
  236.         $prefix = '-';
  237.     }
  238.     if ($time === 0) {
  239.         $suffix = '';
  240.     }
  241.     if ($time >= 1000) {
  242.         $time = $time / 1000;
  243.         $suffix = 'ms';
  244.     }
  245.     if ($time >= 1000) {
  246.         $time = $time / 1000;
  247.         $suffix = ' s';
  248.     }
  249.     if ($time >= 60 && $suffix === ' s') {
  250.         $time = $time / 60;
  251.         $suffix = 'min!';
  252.     }
  253.     return $prefix . sprintf("%.2f {$suffix}", $time);
  254. }
  255.  
  256. ?>
  257. <html>
  258. <head>
  259.     <title><?php  echo $testName ?> | TYPO3 Tiny Test Suite</title>
  260.     <link rel="stylesheet" href="http://wiki.typo3.org/wiki/load.php?debug=false&amp;lang=en&amp;modules=mediawiki.legacy.commonPrint%2Cshared%7Cskins.typo3vector&amp;only=styles&amp;skin=typo3vector&amp;*" />
  261.     <script src="http://code.jquery.com/jquery-2.0.3.min.js" type="text/javascript"></script>
  262.     <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js" type="text/javascript"></script>
  263.     <script src="http://code.highcharts.com/highcharts.js" type="text/javascript"></script>
  264.     <script src="http://code.highcharts.com/modules/exporting.js" type="text/javascript"></script>
  265. </head>
  266. <body>
  267. <div id="content" class="mw-body">
  268.     <h1 id="top"><?php echo $testName ?></h1>
  269.     <form action="<?php echo $_SERVER['SCRIPT_NAME'] ?>">
  270.         <label for="runs">Run the tests how many times?</label>
  271.         <input name="runs" id="runs" value="<?php echo $runs ?>"/>
  272.         <label for="runs"><a href="#help">Reverse execution order?</a></label>
  273.         <input type="checkbox" name="reverseExecutionOrder" id="reverseExecutionOrder" value="1" <?php echo ($reverseExecutionOrder) ? 'checked="checked"' : '' ?>/>
  274.         <input class="submit" type="submit" value="Go!"/>
  275.     </form>
  276.     <p>Winner using averaged times over all sets: <strong><?php
  277.             $winner = array_slice($averagedTimes, 0, 1);
  278.             echo key($winner) ?></strong> <?php echo printSeconds(current($winner) / count($times)) ?>.</p>
  279.     <?php
  280.         if (count($parameterSets) > 1) {
  281.             echo '<ul>';
  282.             foreach ($averagedTimes as $function => $time) {
  283.                 echo '<li><b>' . $function . '</b>: ',
  284.                     ' ' . printSeconds($time / count($times)) . '</li>';
  285.             }
  286.             echo '</ul>';
  287.         }
  288.     ?>
  289.     <div id="resultGraph" style="min-width: 310px; min-height: 400px; margin: 0 auto"></div>
  290.     <?php
  291.         foreach ($times as $setName => $functionData) {
  292.             echo '<h2>' , ucfirst($setName) , '</h2>',
  293.                 '<p>' , $parameterSets[$setName]['description'] , '</p>',
  294.                 '<ul>';
  295.             foreach ($functionData as $function => $time) {
  296.                 $identifier = $setName . '-' . $function;
  297.                 echo '<li><a style="text-decoration: none" href="#', $identifier, '">',
  298.                     ucfirst($function),
  299.                     '</a> ',
  300.                     ': ',
  301.                     sprintf('<span style="min-width: 33px; display: inline-block; text-align: right; font-weight: bold;">%1.2d%%</span> ', $time * 100 / $baselineTimes[$setName]),
  302.                     sprintf('<span style="min-width: 50px; display: inline-block; text-align: right; margin: 0 10px;">%s</span> ', printSeconds($time)),
  303.                     $descriptions[$function],
  304.                     '</li>';
  305.             }
  306.             echo '</ul><h3>Parameters</h3><ul>';
  307.             foreach ($parameterSets[$setName] as $key => $value) {
  308.                 if ($key !== 'description') {
  309.                     if (is_array($value)) {
  310.                         echo '<li>' , $key , ':', '</li>'; var_dump($value);
  311.                     } else {
  312.                         echo '<li>' . $key . ' = "' . (string) $value . '"</li>';
  313.                     }
  314.                 } else {
  315.                     $setDescriptions[] = $value;
  316.                 }
  317.             }
  318.             echo '</ul>';
  319.         }
  320.     ?>
  321.     <script>
  322.         /**
  323.          * Format an integer as a time value
  324.          *
  325.          * @param {String} time The value to format in microseconds.
  326.          * @param {Number} decimals The amount of decimals
  327.          *
  328.          * @return string
  329.          */
  330.         function printSeconds(time, decimals) {
  331.            decimals = typeof decimals !== 'undefined' ? decimals : 2;
  332.             var prefix = '',
  333.                 suffix = 'μs';
  334.             if (time < 0) {
  335.                 time = Math.abs(time);
  336.                 prefix = '-';
  337.             }
  338.             if (time == 0) {
  339.                 suffix = '';
  340.             }
  341.             if (time >= 1000) {
  342.                 time = time / 1000;
  343.                 suffix = 'ms';
  344.             }
  345.             if (time >= 1000) {
  346.                 time = time / 1000;
  347.                 suffix = ' s';
  348.             }
  349.             if (time >= 60 && suffix == ' s') {
  350.                 time = time / 60;
  351.                 suffix = 'min!';
  352.             }
  353.             return prefix + Highcharts.numberFormat(time, decimals) + ' ' + suffix;
  354.         }
  355.  
  356.         var baseLineTimes = [<?php echo implode(',', $baselineTimes) ?>];
  357.         var descriptions = ['<?php echo implode("','", array_map('addslashes', $descriptions)) ?>'];
  358.         var setDescriptions = ['<?php echo implode("','", array_map('addslashes', $setDescriptions)) ?>'];
  359.         Highcharts.setOptions({
  360.             colors: ['#f58006', '#f50806', '#067bf5', '#f5bc06', '#8006f5']
  361.         });
  362.         jQuery(document).ready(function($) {
  363.             $('#resultGraph').highcharts({
  364.                 chart: {
  365. //                  type: 'bar'
  366.                     zoomType: 'y'
  367.                 },
  368.                 title: {
  369.                     text: '<?php echo $testName ?>'
  370.                 },
  371.                 xAxis: {
  372.                     categories: ['<?php echo implode("','", $xAxis)  ?>'],
  373.                     title: {
  374.                         text: null
  375.                     }
  376.                 },
  377.                 yAxis: {
  378.                     min: 0,
  379.                     title: {
  380.                         text: 'Time (milliseconds)',
  381.                         align: 'high'
  382.                     },
  383.                     labels: {
  384.                         overflow: 'justify',
  385.                         formatter: function() {
  386.                             return printSeconds(this.value);
  387.                         }
  388.                     }
  389.                 },
  390.                 tooltip: {
  391.                     useHTML: true,
  392.                     formatter: function() {
  393.                         return '<strong><a style="text-decoration: none" href="#' + this.point.series.name + '-' + this.point.category + '">' + descriptions[this.point.x] + '</a></strong><br/>' +
  394.                             setDescriptions[this.series.index] + '<br/>' +
  395.                             printSeconds(this.point.y) +
  396.                             ' (' + Math.ceil(this.point.y * 100 / baseLineTimes[this.point.series.index]) + '%)';
  397.                     }
  398.                 },
  399.                 legend: {
  400.                     enabled: true
  401.                 },
  402.                 credits: {
  403.                     enabled: false
  404.                 },
  405.                 series: [
  406.                     <?php
  407.                     foreach ($times as $setName => $setTimes) {
  408.                         $series[] = "{
  409.                             name: '" . $setName . "',
  410.                             data: [" . implode(',', $setTimes) . "]
  411.                         }";
  412.                     }
  413.                     echo implode(',', $series);
  414.                     ?>
  415.                 ]
  416.             });
  417.             $('#showSourceLink').on('click', function(e) {
  418.                 e.preventDefault();
  419.                 $.ajax({
  420.                     url: '<?php echo $_SERVER['SCRIPT_NAME'] ?>?source=1',
  421.                     cache: false
  422.                 })
  423.                 .done(function(html) {
  424.                     $('.loading').hide();
  425.                     $('#sourceCode').html(html);
  426.                     $('html, body').animate({
  427.                         scrollTop: $("#source").offset().top
  428.                     }, {
  429.                         duration: 2000,
  430.                         easing: 'easeOutBounce'
  431.                     });
  432.                 });
  433.             });
  434.             $('.top').on('click', function(e) {
  435.                 e.preventDefault();
  436.                 $('html, body').animate({
  437.                     scrollTop: $("#top").offset().top
  438.                 }, {
  439.                     duration: 2000,
  440.                     easing: 'easeOutBounce'
  441.                 });
  442.             });
  443.         });
  444.     </script>
  445.     <h2>Data results</h2>
  446.     <?php
  447.         foreach ($times as $setName => $functionData) {
  448.             echo '<h3>' . ucfirst($setName) . '</h3>';
  449.             echo '<p>' . $parameterSets[$setName]['description'] . '</p>';
  450.             echo '<ul>';
  451.             foreach ($parameterSets[$setName] as $key => $value) {
  452.                 if ($key !== 'description') {
  453.                     if (is_array($value)) {
  454.                         echo '<li>' , $key , ':', '</li>'; var_dump($value);
  455.                     } else {
  456.                         echo '<li>' . $key . ' = "' . (string) $value . '"</li>';
  457.                     }
  458.                 }
  459.             }
  460.             echo '</ul>';
  461.             foreach ($functionData as $function => $time) {
  462.                 echo '<h4 id="', $setName . '-' . $function, '">', ucfirst($function), '</h4>',
  463.                     '<p>', $descriptions[$function], '</p>';
  464.                 var_dump($resultObjects[$setName][$function]);
  465.                 echo '<a href="#top" class="top" style="color: #ddd; text-decoration: none;">^ top</a>';
  466.             }
  467.         }
  468.     ?>
  469.     <div id="p-personal" role="navigation" class="">
  470.         <ul>
  471.     <?php
  472.     foreach ($resultObjects as $setName => $functionData) {
  473.         foreach ($functionData as $function => $data) {
  474.             echo '<li><a href="#' . $setName . '-' . $function . '">' . ucfirst($setName) . ' ' . ucfirst($function)  . '</a></h3>';
  475.         }
  476.     }
  477.     ?>
  478.             <li><a href="#help">Help</a></li>
  479.             <li><a href="#source">Source Code</a></li>
  480.         </ul>
  481.     </div>
  482.     <div id="help">
  483.         <h2>Help</h2>
  484.         <h3>Execution Order</h3>
  485.         <p>In some cases, the second function (non baseline) always runs faster than the baseline. Even when switching the code around. This toggle enables you to reverse the running order to check for this behaviour. Your winning function should still win whatever the execution order. If that is not the case, then this test has failed to determine what code runs faster.</p>
  486.         <a href="#top" class="top" style="color: #ddd; text-decoration: none;">^ top</a>
  487.     </div>
  488.     <div id="source">
  489.         <h2>Source Code</h2>
  490.         <pre id="sourceCode"><a href="#source" id="showSourceLink">Show the sourcecode of this file.</a></pre>
  491.         <a href="#top" class="top" style="color: #ddd; text-decoration: none;">^ top</a>
  492.     </div>
  493.     <div id="logo" style="position: absolute; top: 60px; left: 60px;"><img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAAAiCAYAAACKuC3wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJ
  494. bWFnZVJlYWR5ccllPAAABzJJREFUeNrsWwlsFUUYHh4VkEMEKaACHmAV0KTENFxaiIqK1sQDNYIS
  495. UTQRDSlH1DSIBqSgAQVijGIEjdYDREXEIEo4LSiKgFgUMKCAIK1KFQoUSv1++y/v7zCzZ1/bkP2T
  496. Lztv59jd+Wb+a/c1qKysVLGcftLAb8PKfNUQh8sYRxrkqUWGNpNweBhoI06XAiXALuBnoBBYgv77
  497. 4umvA2JBEtVlATcA13K5KVf3ADEbtPadcdju87rHgY+BURhnd0xDzUuagdAMHIYDg4HzDX3+1kll
  498. 6RjwuoOAnrje5Rjvn5iKFBGLCSYV+yxwu4eKtpFwIMT1aTHcCMyNqUgBsSB1NA75QGMffc6xnP89
  499. 1XY+Fv+SAKmP4DjNJ6kkzdGnwyns5Kn9OISxl3/FNKSAWODREP36Wc5/FWKsXTENqSG2W4h+11jO
  500. Lwo4zkFga0xDamxsGBt3PYVDUL96duMToBxo5HOc7zHGCUtda2B8iHtbAXzEjmBzseC+8Og3Asgw
  501. tD8TmAq04nCvMZ+juSsD9gLLOHzz40CeAdxGcwhczOORQ7qZnch1Ln3p+rdQuAlcAqQL/2Y58BZw
  502. 6H/TCIIogXBWiAnsC1IKDeHSh3zjfuQJjPG8pe5CYEeI+5oB5DIZY/jcFqA73Z6lTyfgFyarAqCY
  503. /FeuO5tCPJ++wgPAApc2GbwAurq0IXIeAo4a6jJpM7j03QYMoHtPhJw8kiEuE+tXFqZQG01j7aF4
  504. InNc2o4Wod/bglSTlPAEbgQ2iGuQhvkA6GXp14q1gCSVHM4iNkmO3AfM8vF8tNh+4gXpCO3i2Y6N
  505. LQo5cXdidzYyeMekCtf76L8Obbe41JOHfZEBss89hvoJXEcqco7UDi4qf7ijcIApHvedzjsvk1Ui
  506. JXFWC9M23dLvKdYMzuIgP6Uda5J07f6GAlcZxvhNVWUC2/J90yLpwmq9Qvg/3YjYNSGJTefskUny
  507. fPR/2aOe0o47DSgXbfYZ6mX4NFU8cF+GLhQVNOPyXN4FQaSEiXB8hZ7CVjtCdvRB8fsxtsuOHAHI
  508. JL2v3ZdJ3S8BirXzpAnmi9/ZROzKCOou15hxyFOf47DYpR+tvHdqwTmk3PU8l11LTtBI8XtKyOvs
  509. YLXsiK6Os4QfU8wq22uxXxfwHr4W5S5E7KYIWaMsqOM+Ll7mQUvdOJBfXkue/2RRztHCu2Eq+SZq
  510. oUZOUNmqOX5Semtee4VLHuAYl9uwmg2T6GmR4JAlihMzzrJrd7AjoIczi9lBqS3ZJOJrCu3GCns4
  511. VrTLj3gdObEttbpLRflHlzEqNFOQEeD6zUW5PMGFeREeaCB2bbaFXHLt71JV72QV3/RQQ/ybapGk
  512. 3csOzx3sbJF8CayNeI2GoqyHKvItmZd23CPKHQJcXy6e3Q6xyyOoY1fbBBLJqF/ANuNK/C6ug0RM
  513. ofAlKEEwSrO3k2rgGvLjgkNaXVvLzvba+e18XrsZL1RHViV48iu00CCo9MauHeJCbimwFCirwyzb
  514. ZM3p68HlNbywo0qmxd6SNBHlfz3GKdOyVCZpz3a8M4c65KyeK+x0YUI0ft0lM+NHpoPc9qr+ymKR
  515. tZFqc0INjN2PJ9mRtYYdZVPTusjdbssIvsee+HYmta/wjO92EhTS2VkQURUVgNy0ekzuZO33Bp6Y
  516. sELzR58NFYhzpPLr6o1Ve8cDT2gVL0QcmLIec/jDt/oo87XgfkYILXVAoJwdL8c5olBlTA3er+0F
  517. yUvsJxCeFjEs+TLvUkiXptnCVSBlhbK/b/Uj5HV2wjjjeeUexbh76gmxJzQbFuZznpaW8/Ss9BLg
  518. W0NdqZaF8nKEHLF9hqQnOCaqqjdrORzGjTCpzWe0dFcYyWaHhB6oqzq95E1RPqyqEvmFPGe2pIs8
  519. 38Jj/KaWfm5CWmemSr7o6J9m8GCXY7d9huJNNTAJuRhv72lG7P0h+vwhyq092sr6IN9e/yDKXRKW
  520. RhTjHY9qz0DqGyoWPSlxnkdbmcwIsimqqfuEJe6kt/kvRniQnSr5KiyW6mnC7i7tyOnMsPTzkiO6
  521. u24TsrXbQjwExWG3YnEciPk8Kd+I8tUu895LOFclKthHEDL9WJpwyRaVsYd7LKDXOQR9N8ZcVpPv
  522. hIdLacKBlnbDRHlpwGsMEOVtbjuWyKWVNjIAqZTgXxDzeIoc5vjSkekGW3uz5pjNNoxDb3CaGM53
  523. ZA17MkmS8LojEPUKDs95NDvGpBbEHFplooib6T0rpQPpw79XgVXApyqZ6qRs2BLDGIPY1FHflRzP
  524. Ejar5H+nyOl9zVf6D4Q9iRCojFeF/rkqfZs0mJIbMXeuQkka+l8UvcqkHDB9vWH6mnM9m0Cb0Gbs
  525. rKrnpqU8Tk5Xwu9dgThKllPKcDUHxOTC0+u6K2qZVPqP7UbGwRD9i0T/Uh/tK0T7qL7DMvaKSRVv
  526. VcmUIanqNWz2+rDjZLPVs7jtfpVMh/6pqjJP/Z1o5j8BBgADhL1q2hRfzwAAAABJRU5ErkJggg==" /></div>
  527. </div>
  528. </body>
  529. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement