3v4l.org

run code in 300+ PHP versions simultaneously
<?php /* * load_config() loads configuration options from a ini file located at the * path given .This file is parsed with sections enabled and the configuration * options for the main cms are located in the `[cms]' section. White and black * lists are to be provided as a single string seperated by comma (`,'). Theses * will be transformed into arrays and joined with the default list items. The * function returns a multi-dimensional array with sections (only 'cms' for now) * as keys on the first level and option names as keys in the second level. * * $config_path * string path to the configuration file to be loaded */ function load_config($config_path){ $config = parse_ini_file($config_path, true); if(!isset($config['cms'])){ $config['cms'] = array(); } // just set the timezone immediately if(isset($config['cms']['timezone'])){ date_default_timezone_set($config['cms']['timezone']); } else { date_default_timezone_set("Europe/Berlin"); } if(!isset($config['cms']['global_root_dir'])){ $config['cms']['global_root_dir'] = '/home/ps0ke/Projects/Greiner/global_root_dir/'; } if(isset($config['cms']['directory_black_list'])){ $config['cms']['directory_black_list'] = explode(',', $config['cms']['directory_black_list']); } else { $config['cms']['directory_black_list'] = array(); } $config['cms']['directory_black_list'] = array_merge( $config['cms']['directory_black_list'], array('.', '..', '.git', 'mth-cms') ); if(isset($config['cms']['file_name_black_list'])){ $config['cms']['file_name_black_list'] = explode(',', $config['cms']['file_name_black_list']); } else { $config['cms']['file_name_black_list'] = array(); } $config['cms']['file_name_black_list'] = array_merge( $config['cms']['file_name_black_list'], array('index') ); if(isset($config['cms']['file_extension_white_list'])){ $config['cms']['file_extension_white_list'] = explode(',', $config['cms']['file_extension_white_list']); } else { $config['cms']['file_extension_white_list'] = array(); } $config['cms']['file_extension_white_list'] = array_merge( $config['cms']['file_extension_white_list'], array('html') ); /* * Automatically enable `php' as a valid extension if its execution is * enabled. It would be better to use `!==' and `===' for checking for * true boolean types. This would prevent logic errors due to PHP's * automatic type conversion (e.g. a non empy string like a wrongly * splelled `false' in the config would evaluate to true). Unfortune- * nately this doesen't work and I suspect that parse_ini_file() does * not set true boolean types. */ if(!isset($config['cms']['execute_php']) || $config['cms']['execute_php'] != true ){ $config['cms']['execute_php'] = false; } if($config['cms']['execute_php'] == true){ array_push( $config['cms']['file_extension_white_list'], 'php' ); } return $config; } /* * link_from_path() generates a link (no full URL) from a path to a local file. * It defaults to the language set globally, but you can set a language manu- * ally. * * $path * the path of the file to be linked to. Starting `.' and `/' will be re- * moved. * $language * the language of the page the the link poits to. This will default to the * language set globally. Should be a two-letter country code. For now * either `en' or `de'. */ function link_from_path($path, $language=null){ /* * I am not really sure which variable to use: SCRIPT_URI and SCRIPT_URL * are not guaranteed to be available on all systems. SCRIPT_NAME seems to * be a safe choice, but I don't know how flexible and robust this is. * CONTEXT_PREFIX would probably be the best choice but is also not * available on all systems. * * relative links * - SCRIPT_NAME * - SCRIPT_URL * - CONTEXT_PREFIX * * absolute links * - SCIPT_URI */ $base = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME); $base = ltrim($base, '/'); $base = rtrim($base, '/'); if(is_null($language)){ if('en' == $GLOBALS['lang']){ $lang = 'en/'; } else { $lang = ''; } } else { if('de' == $language){ $lang = ''; } else { $lang = $language.'/'; } } $path = ltrim($path, '.'); $path = ltrim($path, '/'); return "/$base/{$lang}page/$path"; } /* * language_toggle_html_link() renders an html string containing a link to * the other language version of the page. It uses the language set globally. * Note: It does *not* check, wether the language is actually available! * * $path * defaults to the GET path, the path for the page. * $lang * defaults to the opposite of the global language. The language of the page 8 the link points to. */ function language_toggle_html_link($path=null, $lang=null){ if(is_null($path)){ $path = $GLOBALS['path']; } if(is_null($lang)){ $lang = $GLOBALS['lang']; } if('en' == $lang){ $other_lang_link = link_from_path($path, 'de'); $other_lang_display = 'Deutsch'; } else { $other_lang_link = link_from_path($path, 'en'); $other_lang_display = 'English'; } echo "<a href=\"$other_lang_link\">$other_lang_display</a>"; } /* * Returns a boolean value if the *other* language is available. This is * intended to be used in templating to only show the language toggle when * available. This function is language aware. * * $path * the path of the page to check availability for. Defaults to the global * GET path * $lang * the *current* (!) language. This function will check availability of the * *counter part* language. E.g. if $lang is 'de', * language_toggle_available() will return `true' if the page at $path is * available in 'en'! */ function language_toggle_available($path=null, $lang=null){ if(is_null($path)){ $path = $GLOBALS['path']; } if(is_null($lang)){ $lang = $GLOBALS['lang']; } if('en' == $lang){ $file = file_name_from_path($path, 'de'); } else { $file = file_name_from_path($path, 'en'); } return file_exists($file); } /* * Generates the actual file name to render from the input path. This respects * the global language value if not given otherwise and will return index.html * files for directories. * * $path * the path to create the file name for. May be a directory * $lang * if given, the filename will have this language suffix */ function file_name_from_path($path, $lang=null){ if(is_null($lang)){ $lang = $GLOBALS['lang']; } if(!file_exists($path)){ return null; } // If a directory is requested, try to serve its index.html if(is_dir($path)){ $file = rtrim($path, '/').'/index.html'; } else { $file = $path; } // Construct the english version file name. if('de' != $lang){ $info = pathinfo($file); $file = $info['dirname'].'/'.$info['filename'].".$lang.".$info['extension']; } return $file; } /* * The Node class contains a linked list of files or directories, which is * build recursivly when the object is created. * * $path * contains the path to the node, relative to the path the top-most Node * was initialized with, as a string. * $display_name * contains the name that shall be rendered. Will be set by the user. A * string. * $display_name_en * contains the render-name for the english version of the file * $display_position * is an integer index relevant for the ordering of the menu items during * rendering. Will be set by the user * $is_directory * is a boolean value wether the Node is a file or a directory; this * possibly containing sub nodes * $sub_nodes * is null if there are no sub nodes; Otherwise it is an array containing * additional Node objects. * $visible * is a boolean value wether the Node should be added to to the sub-nodes * and therefore be rendered in the navigation. It can be set by the user * via the ini configuration but defaults to true. * * $navigation_first * is a boolean value wether the Node should get the `first' class in * rendering of the navigation */ class Node { public $path; public $display_name; public $display_name_en = null; public $display_position; public $is_directory; public $sub_nodes = null; public $visible = true; private $navigation_first = false; function __construct($path){ if(!file_exists($path)){ throw new Exception("$path does not exist."); } $this->path = $path; $this->is_directory = is_dir($path); $this->sub_nodes = $this->sub_nodes(); /* * Try to parse the display information from the ini-section. Fall back * to file name if the information was not set. parse_ini_file() is * called silent to surpress warnings if file does not exist. If the * node is a file, the file is read and the first comment block is * parsed as an ini-section. */ if($this->is_directory){ $ini = @parse_ini_file($this->path.'/dir.ini'); } else { $lines = file($this->path); $ini_array = array(); foreach($lines as $line){ if("<!--\n" == $line){ continue; } else if("-->\n" == $line){ break; } else { array_push($ini_array, $line); } } $ini = @parse_ini_string(implode($ini_array)); } if(isset($ini['name'])){ $this->display_name = $ini['name']; } else { $this->display_name = pathinfo($path)['filename']; } if(isset($ini['position'])){ $this->display_position = $ini['position']; } else { $this->display_position = 1000; } if(isset($ini['visible'])){ $this->visible = $ini['visible']; } if(isset($ini['name_en'])){ $this->display_name_en = $ini['name_en']; } } /* * The build_navigation() function recursivly builds a directory tree from * the node with nested html unordered lists. It renderes content to the * page. Only top nodes for each level in the current path are shown. This * is achieved by testing the current Node path against each part of the * requested path and its parent directory incrementally. * Links will point to english version if viewed from an english version * page. * * $path * is the GET path. It is used to narrow the drill-down. Only the top * nodes in each level are shown. * $first_run * holds a boolean value wether the function is run for the first time * i. e. has been called by the programmer or if it was called as an * act of recursion by itself. */ public function build_navigation($path, $first_run=true){ $path_array = explode('/', $path); $incremental_path = "."; $visible = false; foreach($path_array as $part){ $incremental_path .= "/".$part; $visible |= dirname($this->path) == dirname($incremental_path); $visible |= dirname($this->path) == $incremental_path; } $expanded = true; if(!$first_run && $visible){ if('en' == $GLOBALS['lang'] && !is_null($this->display_name_en)){ $display_name = $this->display_name_en; } else { $display_name = $this->display_name; } $link = link_from_path($this->path); $classes = ''; if($this->navigation_first){ $classes .= 'first '; } else { $classes .= 'leaf '; } if($this->is_directory){ /* * check if the current node is a parent of the requested node * by checking if its path is a sub string of the requested * path. */ if(strpos('./'.$path, $this->path) === false){ $expanded = false; $classes .= 'collapsed '; } else { $classes .= 'expanded '; } } $classes = rtrim($classes); if('./'.$path == $this->path){ $active = ' class="active"'; } else { $active = ''; } echo "<li class=\"$classes\">"; echo "<a href=\"${link}\" title=\"$display_name\" onfocus=\"blurLink(this);\"$active>"; echo $display_name; echo "</a>\n"; } if($this->is_directory && $this->sub_nodes && $expanded){ /* * The nesting level of a navigation point is calculated simply by * counting the elements in the path. * * Wether the Node is the first in a navigation list is figured out * by using a private variable `$navigation_first' that is set for * each Node. Before recursing each sub node during rendering, the * `$first' variable is set to true, which will set every sub * node's $navigation_first. After setting it (for the first time) * $first is set to false and will set all following $navigation_ * first to false. */ $level = count(explode('/', $this->path)); echo "<ul class=\"menu level-$level\">\n"; $first = true; foreach($this->sub_nodes as $sub_node){ if(!is_null($sub_node)){ $sub_node->navigation_first = $first; $first = false; $sub_node->build_navigation($path, false); } } echo "</ul>\n"; } if(!$first_run && $visible){ echo "</li>\n"; } } /* * find_node_by_path returns the Node object correspronding to the $path. * It recursivly walks the Node-tree and checks if the path is coreect. If * it matches, the Node object is returned, null otherwise. */ public function find_node_by_path($path){ if(rtrim($this->path, '/') == rtrim('./'.$path, '/')){ return $this; } else { if($this->sub_nodes){ foreach($this->sub_nodes as $sub_node){ $ret = $sub_node->find_node_by_path($path); if(!is_null($ret)){ return $ret; } } return null; } else { return null; } } } /* * the sub_nodes() function is called by the constructor and fills the * sub_nodes property with an array of Node objects. Only valid sub_nodes * will be valid. File names and extensions are matched against various * black- and white-lists. */ private function sub_nodes(){ global $config; if($this->is_directory){ $sub_nodes = array(); foreach(glob("{$this->path}/*") as $sub_path){ $add_this_node = true; $pathinfo = pathinfo($sub_path); if(is_dir($sub_path)){ // directory name black-list if(in_array( $pathinfo['filename'], $config['cms']['directory_black_list'] ) ){ $add_this_node = false; } } else { // file extension white-list if(! in_array( $pathinfo['extension'], $config['cms']['file_extension_white_list'] ) || // file name black-list in_array( $pathinfo['filename'], $config['cms']['file_name_black_list'] ) ){ $add_this_node = false; } // exclude english versions of files if( preg_match('/\.en$/', $pathinfo['filename']) ){ $add_this_node = false; } } $new_node = new Node($sub_path); if($add_this_node && $new_node->visible){ $display_position = $new_node->display_position; while(isset($sub_nodes[$display_position])){ $display_position += 1; } $sub_nodes[$display_position] = $new_node; } } ksort($sub_nodes); return $sub_nodes; } else { return null; } } } /* * load_templated loads template files. It looks for them first in a local * directory that every user can change. If it does not find the desired * template there, it looks in a the `global_root_dir' from the config. * This should be a central directory on the webserver that only the admin * has access to. This makes updating the templates easy for thos users that * don't need customization. * * $template * the name of the template to load as a string. The file extension should * not be included here. */ function load_template($template){ global $config; /* * All global variables that hold teh cms' state must be included in this * scope to be available from within the include()ed template file. */ global $path; global $base_node; global $current_node; global $lang; $global_path = rtrim($config['cms']['global_root_dir'], '/').'/'.$template.'.html'; $local_path ="mth-cms/templates/$template.html"; if(file_exists($local_path)){ include($local_path); } else { include($global_path); } } /* * render_content() renders the content in respect to the GET path and the * globally set language. If the file does not exist or only another language is * available, it will transparently render an error page. */ function render_content(){ global $config; global $path; global $lang; $file = file_name_from_path($path); $file_de = file_name_from_path($path, 'de'); if('en' == $lang && !file_exists($file) && file_exists($file_de)){ // English version was not found, but a german version exists. load_template('error_404_other_language_available'); } else if(!file_exists($file)){ // No german version exists load_template('error_404'); } else { /* * If PHP execution is activated in the config and the file is a PHP * file, run it. Otherwise check if the file is encoded as UTF-8. If * not, try to convert it to UTF-8. Do not even try to use * mb_detect_encoding() as it just does not work at all. Therefore * try the one encoding that is expected to be used the most apart from * UTF-8: ISO-8859-15 aka Latin-9. This is the best I can do. */ if($config['cms']['execute_php'] && 'php' == pathinfo($file, PATHINFO_EXTENSION) ){ include($file); } else { $content = file_get_contents($file); if(!mb_check_encoding($content, 'UTF-8')){ $content = mb_convert_encoding($content, 'UTF-8', 'ISO-8859-15'); } echo $content; } } } /* * Renders the page title to the output. Is ment to be used in the template's * <title> tag. title() is language aware. */ function title(){ global $lang; global $path; global $current_node; if(file_exists(file_name_from_path($path))){ if('en' == $lang && !is_null($current_node->display_name_en)){ echo $current_node->display_name_en; } else { echo $current_node->display_name; } } else { if('en' == $lang){ echo "404 Page not found"; } else { echo "404 Seite nicht gefunden"; } } } /* * Renders the date of last modification of the current document to the output. * It uses the filesystem `mtime'. last_modified() is language aware. */ function last_modified(){ global $path; global $lang; $file = file_name_from_path($path); if(file_exists($file)){ $mtime = date("d.m.Y", filemtime($file)); if('en' == $lang){ echo("Last modified:&nbsp;$mtime"); } else { echo("Letzte &Auml;ndergung:&nbsp;$mtime"); } } } /* * this renders the quicklings section of the page. Mainly a convenience alias * to `load_template()'. */ function quicklinks(){ load_template('quicklinks'); } /* * renders the infloline/footer section of the page. Mainly a convenience alias * for `load_template()' */ function footer(){ load_template('footer'); } ?> <?php /* * main function that sets up all relevant global variables and calls the data * model creation and content rendering functions */ $path = $_GET['path']; if(isset($_GET['lang']) && 'en' == $_GET['lang']){ $lang = 'en'; } else { $lang = 'de'; } /* * Check if the requested file is a text file. If so, try to serve it in * the cms. Otherwise (e.g. an image) just serve it as is. */ if(file_exists(file_name_from_path($path))){ $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($finfo, $path); finfo_close($finfo); if(!is_dir($path) && !preg_match("/^text\//", $mime_type)){ header("Content-Type: $mime_type"); echo(file_get_contents($path)); exit(0); } } else { header("HTTP/1.1 404 Not Found"); } $config = load_config('mth-cms/config.ini'); $base_node = new Node('.'); /* * This tries to set the $current_node to the Node object corresponding to the * current $path. This might fail if the actual file is on a black list and * thus not added to the $base_node tree. If this is the case, we just use the * Node of the parent directory. This seems to be the best solution because * file name black listing is mostly used to exclude `index' files. */ $current_node = $base_node->find_node_by_path($path); if(is_null($current_node) && in_array( pathinfo($path)['filename'], $config['cms']['file_name_black_list'] ) ){ $current_node = $base_node->find_node_by_path(pathinfo($path)['dirname']); } // debugging //echo '<pre>'; //print_r($_GET); //print_r($base_node); //print_r($_SERVER); //print_r($current_node); //var_dump($config); //echo '</pre>'; load_template('main'); ?>

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.3.40.0100.00719.19
8.3.30.0150.00419.51
8.3.20.0080.00020.29
8.3.10.0030.00523.70
8.3.00.0040.00419.50
8.2.170.0150.00022.96
8.2.160.0110.00720.68
8.2.150.0040.00424.18
8.2.140.0000.00824.66
8.2.130.0040.00426.16
8.2.120.0070.00322.06
8.2.110.0100.00022.30
8.2.100.0030.01018.13
8.2.90.0000.00819.30
8.2.80.0000.00917.97
8.2.70.0060.00317.88
8.2.60.0080.00018.05
8.2.50.0090.00018.07
8.2.40.0080.00019.95
8.2.30.0000.00818.39
8.2.20.0050.00318.07
8.2.10.0050.00318.20
8.2.00.0030.00517.89
8.1.270.0060.00923.79
8.1.260.0030.00626.35
8.1.250.0030.00528.09
8.1.240.0030.00721.19
8.1.230.0030.01019.26
8.1.220.0050.00318.04
8.1.210.0090.00018.77
8.1.200.0030.00617.60
8.1.190.0090.00017.60
8.1.180.0040.00418.10
8.1.170.0080.00018.82
8.1.160.0040.00422.17
8.1.150.0040.00419.08
8.1.140.0000.00817.71
8.1.130.0000.00718.07
8.1.120.0040.00417.62
8.1.110.0030.00617.70
8.1.100.0000.00817.74
8.1.90.0030.00617.78
8.1.80.0050.00317.75
8.1.70.0040.00417.63
8.1.60.0050.00317.87
8.1.50.0030.00517.79
8.1.40.0080.00017.68
8.1.30.0060.00317.92
8.1.20.0030.00517.93
8.1.10.0040.00417.78
8.1.00.0040.00417.76
8.0.300.0090.00018.77
8.0.290.0080.00017.13
8.0.280.0040.00418.70
8.0.270.0000.00717.40
8.0.260.0000.00717.46
8.0.250.0000.00717.18
8.0.240.0040.00417.14
8.0.230.0040.00417.20
8.0.220.0040.00417.18
8.0.210.0050.00317.16
8.0.200.0030.00317.20
8.0.190.0030.00617.35
8.0.180.0030.00617.08
8.0.170.0030.00617.16
8.0.160.0080.00017.32
8.0.150.0000.00817.16
8.0.140.0000.00817.16
8.0.130.0930.013111.07
8.0.120.0040.00417.23
8.0.110.0000.00817.20
8.0.100.0000.00817.05
8.0.90.0000.00817.20
8.0.80.0080.00817.15
8.0.70.0000.00817.15
8.0.60.0000.00817.21
8.0.50.0030.00517.29
8.0.30.0110.01017.41
8.0.20.0170.00217.52
8.0.10.0030.00517.24
8.0.00.0070.01117.21
7.4.330.0380.01663.19
7.4.320.0000.00716.62
7.4.300.0000.00816.73
7.4.290.0040.00416.71
7.4.280.0000.00816.83
7.4.270.0020.00516.72
7.4.260.0070.00016.81
7.4.250.0000.00816.66
7.4.240.0000.00816.78
7.4.230.0070.00016.48
7.4.220.0030.01616.71
7.4.210.0060.01616.88
7.4.200.0040.00416.52
7.4.160.0040.01216.73
7.4.150.0030.01717.40
7.4.140.0080.01417.86
7.4.130.0130.01016.87
7.4.120.0090.00916.69
7.4.110.0110.00916.85
7.4.100.0130.00916.73
7.4.90.0100.01016.64
7.4.80.0110.00719.39
7.4.70.0070.01416.71
7.4.60.0120.00616.68
7.4.50.0030.00616.66
7.4.40.0070.01116.78
7.4.30.0100.00716.79
7.4.00.0060.01215.22
7.3.330.0820.020111.03
7.3.320.0940.010111.02
7.3.310.0000.00716.54
7.3.300.0050.00216.56
7.3.290.0040.01216.70
7.3.280.0070.01016.72
7.3.270.0070.01417.40
7.3.260.0140.01016.68
7.3.250.0160.00416.82
7.3.240.0150.00916.55
7.3.230.0100.01416.64
7.3.210.0100.01016.79
7.3.200.0090.01319.39
7.3.190.0090.00916.64
7.3.180.0070.01016.86
7.3.170.0000.01816.77
7.3.160.0100.00716.80
7.3.120.0070.01415.08
7.3.110.0070.00715.07
7.3.100.0110.01114.94
7.3.90.0000.01215.06
7.3.80.0040.01215.25
7.3.70.0000.01014.87
7.3.60.0120.00615.01
7.3.50.0000.01414.88
7.3.40.0030.00715.13
7.3.30.0090.00915.21
7.3.20.0080.00816.86
7.3.10.0130.00516.77
7.3.00.0130.00616.82
7.2.330.0060.01417.07
7.2.320.0100.01417.11
7.2.310.0090.00916.97
7.2.300.0060.01517.04
7.2.290.0100.00917.19
7.2.250.0040.01115.13
7.2.240.0070.01414.99
7.2.230.0060.01015.07
7.2.220.0100.00715.19
7.2.210.0070.01015.36
7.2.200.0080.00315.32
7.2.190.0090.00615.23
7.2.180.0090.00315.27
7.2.170.0080.00415.14
7.2.160.0000.01515.07
7.2.150.0110.01116.91
7.2.140.0110.00816.94
7.2.130.0120.00917.15
7.2.120.0110.00616.94
7.2.110.0140.00016.90
7.2.100.0100.00716.67
7.2.90.0070.00717.18
7.2.80.0000.01516.93
7.2.70.0040.00717.06
7.2.60.0050.00917.04
7.2.50.0070.01016.98
7.2.40.0160.00316.97
7.2.30.0070.00317.23
7.2.20.0060.00917.18
7.2.10.0060.00917.14
7.2.00.0030.01417.10
7.1.330.0000.01915.68
7.1.320.0070.01015.72
7.1.310.0070.00715.87
7.1.300.0060.00615.73
7.1.290.0000.01215.87
7.1.280.0080.01215.83
7.1.270.0060.00915.89
7.1.260.0110.00515.88
7.1.250.0000.01415.91
7.1.240.0060.01215.94
7.1.230.0060.01015.78
7.1.220.0040.00815.67
7.1.210.0100.00715.86
7.1.200.0070.00715.78
7.1.190.0100.00715.61
7.1.180.0040.01215.99
7.1.170.0040.00715.77
7.1.160.0090.00615.90
7.1.150.0090.00615.80
7.1.140.0060.00915.57
7.1.130.0090.00615.66
7.1.120.0040.00715.82
7.1.110.0040.01115.79
7.1.100.0010.01117.19
7.1.90.0000.01015.96
7.1.80.0000.00915.93
7.1.70.0070.00716.52
7.1.60.0000.01417.51
7.1.50.0070.01016.51
7.1.40.0000.01315.92
7.1.30.0090.00615.93
7.1.20.0040.01215.85
7.1.10.0120.00515.81
7.1.00.0050.04019.07
7.0.330.0030.01015.32
7.0.320.0030.01015.07
7.0.310.0070.00715.46
7.0.300.0070.00715.11
7.0.290.0030.00915.32
7.0.280.0040.01215.46
7.0.270.0030.00915.36
7.0.260.0040.01115.16
7.0.250.0030.01415.43
7.0.240.0120.00315.54
7.0.230.0030.01015.35
7.0.220.0090.00315.58
7.0.210.0030.00715.49
7.0.200.0060.00416.12
7.0.190.0030.00815.55
7.0.180.0030.00615.23
7.0.170.0030.01015.29
7.0.160.0090.00015.42
7.0.150.0070.00715.36
7.0.140.0050.04218.68
7.0.130.0070.01015.54
7.0.120.0060.00615.52
7.0.110.0090.03017.92
7.0.100.0050.04417.81
7.0.90.0080.03917.70
7.0.80.0100.04017.81
7.0.70.0100.04417.79
7.0.60.0120.02717.78
7.0.50.0110.04517.86
7.0.40.0090.02916.80
7.0.30.0070.03916.86
7.0.20.0170.04716.87
7.0.10.0100.03816.76
7.0.00.0090.03716.67
5.6.400.0000.01414.18
5.6.390.0090.00314.65
5.6.380.0100.00614.48
5.6.370.0100.00614.55
5.6.360.0090.00614.30
5.6.350.0100.00314.61
5.6.340.0040.01414.38
5.6.330.0060.00914.34
5.6.320.0110.00714.54
5.6.310.0040.01514.57
5.6.300.0060.00914.52
5.6.290.0080.00814.39
5.6.280.0070.03717.75
5.6.270.0000.01414.28
5.6.260.0100.04117.62
5.6.250.0100.02817.58
5.6.240.0080.04617.83
5.6.230.0070.03517.68
5.6.220.0080.04717.60
5.6.210.0030.04917.61
5.6.200.0080.03317.77
5.6.190.0100.04317.82
5.6.180.0070.03717.70
5.6.170.0140.03817.80
5.6.160.0070.04217.75
5.6.150.0050.05417.83
5.6.140.0070.05017.77
5.6.130.0080.04017.81
5.6.120.0110.04517.90
5.6.110.0090.03117.66
5.6.100.0120.04317.78
5.6.90.0100.05017.85
5.6.80.0120.04317.50
5.6.70.0130.04317.76
5.6.60.0140.04417.45
5.6.50.0140.04417.44
5.6.40.0160.04117.43
5.6.30.0170.03917.62
5.6.20.0090.04617.49
5.6.10.0140.03017.31
5.6.00.0080.03017.41
5.5.380.0130.03717.60
5.5.370.0110.04117.49
5.5.360.0120.04317.54
5.5.350.0050.04517.47
5.5.340.0080.05017.73
5.5.330.0130.03717.71
5.5.320.0060.04117.56
5.5.310.0060.04917.78
5.5.300.0030.05017.67
5.5.290.0110.04817.83
5.5.280.0120.03017.61
5.5.270.0070.04417.74
5.5.260.0080.05017.77
5.5.250.0090.04617.57
5.5.240.0140.04517.29
5.5.230.0120.03217.51
5.5.220.0140.04117.43
5.5.210.0050.04417.33
5.5.200.0150.03417.36
5.5.190.0150.03817.47
5.5.180.0110.04617.39
5.5.170.0140.01414.41
5.5.160.0160.04417.48
5.5.150.0130.04617.21
5.5.140.0090.04617.27
5.5.130.0180.02117.42
5.5.120.0090.02517.54
5.5.110.0090.03617.42
5.5.100.0060.02817.39
5.5.90.0090.03217.32
5.5.80.0130.02917.48
5.5.70.0080.02717.45
5.5.60.0120.02117.40
5.5.50.0110.02617.35
5.5.40.0150.02217.32
5.5.30.0070.04517.32
5.5.20.0100.02417.44
5.5.10.0060.04817.34
5.5.00.0090.03117.32
5.4.450.0540.07847.15
5.4.440.0490.07347.24
5.4.430.0540.07547.27
5.4.420.0400.07747.28
5.4.410.0270.07747.28
5.4.400.0350.05446.95
5.4.390.0430.06247.22
5.4.380.0330.07147.02
5.4.370.0440.06247.07
5.4.360.0350.06747.14
5.4.350.0280.06947.00
5.4.340.0420.05746.96
5.4.330.0670.05474.99
5.4.320.0440.06147.05
5.4.310.0370.06246.98
5.4.300.0250.07447.21
5.4.290.0380.04547.05
5.4.280.0310.05647.02
5.4.270.0460.03946.96
5.4.260.0360.04947.02
5.4.250.0370.04546.99
5.4.240.0340.06047.00
5.4.230.0310.05147.15
5.4.220.0350.04647.10
5.4.210.0370.06547.22
5.4.200.0330.05647.14
5.4.190.0350.05247.12
5.4.180.0340.04746.79
5.4.170.0350.05747.00
5.4.160.0320.05947.05
5.4.150.0390.04947.00
5.4.140.0320.06745.74
5.4.130.0330.06645.83
5.4.120.0340.05045.75
5.4.110.0410.04645.76
5.4.100.0350.04545.78
5.4.90.0350.05545.84
5.4.80.0340.05345.69
5.4.70.0320.04945.58
5.4.60.0400.05745.62
5.4.50.0370.05045.79
5.4.40.0430.04345.67
5.4.30.0280.05845.74
5.4.20.0350.04345.70
5.4.10.0300.06445.74
5.4.00.0350.04645.22

preferences:
39.52 ms | 400 KiB | 5 Q