- <?php 
-   
-   
- abstract class Employee 
- { 
- 	public $rank; 
-     public $boss; 
-   
-     	0 => 400,                 // Marketer 
-     	1 => 800,                 // Analyst 
-     	2 => 500,                 // Manager 
-     	3 => 200                  // Engineer 
-     ); 
-     	0 => 15, 
-     	1 => 50, 
-     	2 => 20, 
-     	3 => 5  
-     ); 
-     	0 => 150, 
-     	1 => 5, 
-     	2 => 200, 
-     	3 => 50  
-     ); 
-   
-     public function __construct( int $rank, int $boss) 
-     { 
-         $this->rank = $rank;         
-         $this->boss = $boss; 
-     } 
-   
-     public function distributing(int $rank, int $boss) 
-     { 
-   
-     	if ($rank == 2) { 
-     	    $coefficient = 1.25;     // метод для определения дальнейшего 
-         } elseif ($rank == 3) {      // коэффициента умножения зарплаты 
-     	    $coefficient = 1.5;      // исходя из ранга сотрудника 
-         } else { 
-         	$coefficient = 1; 
-         } 
-   
-         if ($boss == 1) { 
-   
-             $coefficient *= 2; 
-         } 
-   
-          return $coefficient; 
-     } 
-   
-     public function bossORNot(int $boss) 
-     { 
-     	if ($boss == 1) { 
-   
-             $forBoss = 0; 
-     	    return $forBoss;     // метод исключительно для того, чтобы в случае с  
-                                  // боссом обнулить количество написанных отчётов для него 
-         } else { 
-   
-         	$forBoss = 1; 
-     	    return $forBoss; 
-         } 
-     } 
- } 
-   
- class Marketer extends Employee 
- { 
-     public function-  getSalary (array $salary,-  int  $coefficient)
 
-     { 
- 	    $getSalary = $salary[0] * $coefficient; 
- 	    return $getSalary; 
-     } 
-     public function-  getCoffee (array $coffee,-  int  $coefficient)   // тут всё вроде понятно, 3 метода для
 
-     {                                                            // вычисления зар. платы, кофе и отчётов 
-     	$getCoffee = $coffee[0] * $coefficient;                  // правда мне не нравится то, что по сути для 
-     	return $getCoffee;                                       // всех 4 должностей написан один и тот же код 
-     }                                                            // может чёт в абстрактный стоит вынести? 
-     public function-  getReports (array $reports,-  int  $forBoss)
 
-     { 
-     	$getReports = $reports[0] * $forBoss; 
-     	return $getReports; 
-     }	 
- } 
-   
- class Analyst extends Employee 
- { 
- 	public function-  getSalary (array $salary,-  int  $coefficient)
 
-     { 
- 	    $getSalary = $salary[1] * $coefficient; 
- 	    return $getSalary; 
-     } 
-     public function-  getCoffee (array $coffee,-  int  $coefficient)
 
-     { 
-     	$getCoffee = $coffee[1] * $coefficient; 
-     	return $getCoffee; 
-     } 
-     public function-  getReports (array $reports,-  int  $forBoss)
 
-     { 
-     	$getReports = $reports[1] * $forBoss; 
-     	return $getReports; 
-     }	 
- } 
-   
- class Manager extends Employee 
- { 
- 	public function-  getSalary (array $salary,-  int  $coefficient)
 
-     { 
- 	    $getSalary = $salary[2] * $coefficient; 
- 	    return $getSalary; 
-     } 
-     public function-  getCoffee (array $coffee,-  int  $coefficient)
 
-     { 
-     	$getCoffee = $coffee[2] * $coefficient; 
-     	return $getCoffee; 
-     } 
-     public function-  getReports (array $reports,-  int  $forBoss)
 
-     { 
-     	$getReports = $reports[2] * $forBoss; 
-     	return $getReports; 
-     }	 
- } 
-   
- class Engineer extends Employee 
- { 
- 	public function-  getSalary (array $salary,-  int  $coefficient)
 
-     { 
-   
- 	    $getSalary = $salary[3] * $coefficient; 
- 	    return $getSalary; 
-     } 
-     public function-  getCoffee (array $coffee,-  int  $coefficient)
 
-     { 
-   
-     	$getCoffee = $coffee[3] * $coefficient; 
-     	return $getCoffee; 
-     } 
-     public function-  getReports (array $reports,-  int  $forBoss)
 
-     { 
-   
-     	$getReports = $reports[3] * $forBoss; 
-     	return $getReports; 
-     }	 
- } 
-   
- $departments = array(                           // просто массив со всеми отделами 
-                                                 // и кол-вом сотрудников разных должностей и ранга в них 
- 		"ме1" => 9, 
- 		"ме2" => 3, 
- 		"ме3" => 2, 
- 		"ма1" => 2, 
- 		"директорМе2" => 1 
-     ), 
-     	"ме1" => 12, 
-     	"ма1" => 6, 
-     	"ан1" => 3, 
-     	"ан2" => 2, 
-     	"директорМа2" => 1 
-     ), 
-   
-     	"ме1" => 8, 
-     	"ма1" => 15, 
-     	"ма2" => 10, 
-     	"ин1" => 2, 
-     	"директорМа3" => 1 
-     ), 
-   
-     	"ме1" => 13, 
-     	"ме2" => 5, 
-     	"ин1" => 5, 
-     	"директорМе1" => 1 
-     )    
- ); 
-   
- function padLeft($string, $length) { 
-   
-     $difference = $length - $amount; 
-     $whitespaces = str_repeat(' ', $difference);     // для таблиц 
-     $leftSide = $whitespaces . $string; 
-   
- 	return $leftSide; 
- } 
-   
- function padRight($string, $length) { 
-   
-     $difference = $length - $amount; 
-     $rightSide = $string . $whitespaces; 
-   
- 	return $rightSide; 
-   
- } 
-   
- function createEmployees() 
- { 
- 	$allEmployees = array();                // делаю двуслойный массив, распределяю всех по отделам 
- 	$buying = array();                      // тут нет никакой проверки правильности внесения сотрудников, 
-                                             // остаётся лишь внимательно ориентироваться на массив $departments 
-     $manager1 = new Manager(1, 0);          // и в соответствии с ним переносить должностя 
-     $manager2 = new Manager(2, 0); 
-     $manager3 = new Manager(3, 0); 
-     $marketer1 = new Marketer(1, 0); 
-     $directorMe2 = new Manager(2, 1); 
-   
-     array_push($buying, $manager1, $manager2, $manager3, $marketer1, $directorMe2); 
-   
-   
-     $manager1 = new Manager(1, 0); 
-     $marketer1 = new Marketer(1, 0); 
-     $analyst1 = new Analyst(1, 0); 
-     $analyst2 = new Analyst(2, 0); 
-     $directorMar2 = new Marketer(2, 1); 
-   
-     array_push($selling, $manager1, $marketer1, $analyst1, $analyst2, $directorMar2); 
-   
-   
-     $manager1 = new Manager(1, 0); 
-     $marketer1 = new Marketer(1, 0); 
-     $marketer2 = new Marketer(2, 0); 
-     $engineer1 = new Engineer(1, 0); 
-     $directorMar3 = new Marketer(3, 1); 
-   
-     array_push($ads, $manager1, $marketer1, $marketer2, $engineer1, $directorMar3); 
-   
-   
-     $manager1 = new Manager(1, 0); 
-     $manager2 = new Manager(2, 0); 
-     $engineer1 = new Engineer(1, 0); 
-     $directorMa1 = new Manager(1, 1); 
-   
-     array_push($logistics, $manager1, $manager2, $engineer1, $directorMa1); 
-   
-     array_push($allEmployees, $buying, $selling, $ads, $logistics); 
-   
-     return $allEmployees; 
-   
- } 
-   
- $employees = createEmployees(); 
-   
- function-  getAll  (array $employees, array $departments)
 
- { 
-   
-   
-     $averageSum = 0; 
-     $averageS = 0; 
-     $averageC = 0; 
-     $averageSh = 0; 
-     $averageP = 0; 
-   
-     array_push($getIt, $buying, $selling, $ads, $logistics, $average, $total);                              
-     // снова двойной масси с распределением по отделам 
-   
-     for ($i=0; $i < 4; $i++) {  
-   
-   
-     	foreach ($departments[$i] as $amount) { 
-   
-         } 
-   
-         foreach ($employees[$i] as $employee) { // считаю зарплату, кофе, и отчёты для каждого отдела 
-   
-         	array_push($salary, $employee->getSalary($employee->salary, $employee->distributing($employee->rank, $employee->boss))); 
-   
-         	array_push($coffee, $employee->getCoffee($employee->coffee, $employee->distributing($employee->rank, $employee->boss))); 
-   
-         	array_push($sheets, $employee->getReports($employee->reports, $employee->bossORNot($employee->boss)));   
-         } 
-   
-         for ($a=0; $a < count($howMuch); $a++) {  
-   
-         	$salary[$a] *= $howMuch[$a];   // каждое из значений помножаю на соответствующее 
-         	$coffee[$a] *= $howMuch[$a];   // количество сотрудников в данном отделе на данном ранге 
-         	$sheets[$a] *= $howMuch[$a];  
-   
-         } 
-   
-         $perSheet = round($forRounding, 1); 
-   
-         $averageSum += $sum; 
-         $averageS += array_sum($salary);  // для дальнейшего показания средних рез-тов и всего вместе 
-         $averageC += array_sum($coffee);  // собираю в конце каждого цикла значения  
-         $averageSh += array_sum($sheets); // изначально вообще не задумывал собирать эти значения 
-         $averageP += $perSheet;           // именно в этой функции, да и сейчас как-то это стрёмно 
-                                           // выглядит, я считаю 
-     } 
-   
-     array_push($getIt[4], $averageSum / 4, $averageS / 4, $averageC / 4, $averageSh / 4, $averageP / 4); 
-     array_push($getIt[5], $averageSum, $averageS, $averageC, $averageSh, $averageP); 
-   
-     // я так уверенно поставил цифры 4 и 5 в верхние пуши потому, что заведомо знаю что под 
-     // этими ключами у меня будут средние и полные значения 
-     // так быть вообще не должно, тут хоть что тронешь и всё нахуй развалится, это всё из-за того 
-     // что я решил средние значения получать именно здесь 
-     return $getIt; 
- } 
-   
-   
- $getIt = getAll($employees, $departments); 
-   
- echo padRight("Департамент", 30) .  
-      padLeft("Сотр.", 10) .  
-      padLeft("Тугр.", 10) . 
-      padLeft("Кофе", 10) .                               // ну и тут уже формируется полная таблица 
-      padLeft("Стр.", 10) .  
-      padLeft("Тугр./стр.", 10) . "\n\n"; 
-   
- $names = array("Закупки","Продажи","Реклама","Логистика", "Среднее", "Всего"); 
-   
-   
- array_push($onAverage, $buying, $selling, $ads, $logistics); 
-   
- for ($i=0; $i < count($names); $i++) { 
-   
-     echo padRight($names[$i], 30); 
-   
- 	foreach ($getIt[$i] as $value) { 
-   
-    	echo padLeft($value, 10); 
-   
-     } 
-   
-    	echo "\n"; 
- } 
-   
- ?> 
				PD9waHAKCmVycm9yX3JlcG9ydGluZygtMSk7CgphYnN0cmFjdCBjbGFzcyBFbXBsb3llZQp7CglwdWJsaWMgJHJhbms7CiAgICBwdWJsaWMgJGJvc3M7CgogICAgcHVibGljICRzYWxhcnkgPSBhcnJheSgKICAgIAkwID0+IDQwMCwgICAgICAgICAgICAgICAgIC8vIE1hcmtldGVyCiAgICAJMSA9PiA4MDAsICAgICAgICAgICAgICAgICAvLyBBbmFseXN0CiAgICAJMiA9PiA1MDAsICAgICAgICAgICAgICAgICAvLyBNYW5hZ2VyCiAgICAJMyA9PiAyMDAgICAgICAgICAgICAgICAgICAvLyBFbmdpbmVlcgogICAgKTsKICAgIHB1YmxpYyAkY29mZmVlID0gYXJyYXkoCiAgICAJMCA9PiAxNSwKICAgIAkxID0+IDUwLAogICAgCTIgPT4gMjAsCiAgICAJMyA9PiA1IAogICAgKTsKICAgIHB1YmxpYyAkcmVwb3J0cyA9IGFycmF5KAogICAgCTAgPT4gMTUwLAogICAgCTEgPT4gNSwKICAgIAkyID0+IDIwMCwKICAgIAkzID0+IDUwIAogICAgKTsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoIGludCAkcmFuaywgaW50ICRib3NzKQogICAgewogICAgICAgICR0aGlzLT5yYW5rID0gJHJhbms7ICAgICAgICAKICAgICAgICAkdGhpcy0+Ym9zcyA9ICRib3NzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBkaXN0cmlidXRpbmcoaW50ICRyYW5rLCBpbnQgJGJvc3MpCiAgICB7CgogICAgCWlmICgkcmFuayA9PSAyKSB7CiAgICAJICAgICRjb2VmZmljaWVudCA9IDEuMjU7ICAgICAvLyDQvNC10YLQvtC0INC00LvRjyDQvtC/0YDQtdC00LXQu9C10L3QuNGPINC00LDQu9GM0L3QtdC50YjQtdCz0L4KICAgICAgICB9IGVsc2VpZiAoJHJhbmsgPT0gMykgeyAgICAgIC8vINC60L7RjdGE0YTQuNGG0LjQtdC90YLQsCDRg9C80L3QvtC20LXQvdC40Y8g0LfQsNGA0L/Qu9Cw0YLRiwogICAgCSAgICAkY29lZmZpY2llbnQgPSAxLjU7ICAgICAgLy8g0LjRgdGF0L7QtNGPINC40Lcg0YDQsNC90LPQsCDRgdC+0YLRgNGD0LTQvdC40LrQsAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgCSRjb2VmZmljaWVudCA9IDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoJGJvc3MgPT0gMSkgewogICAgICAgIAkKICAgICAgICAgICAgJGNvZWZmaWNpZW50ICo9IDI7CiAgICAgICAgfQoKICAgICAgICAgcmV0dXJuICRjb2VmZmljaWVudDsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gYm9zc09STm90KGludCAkYm9zcykKICAgIHsKICAgIAlpZiAoJGJvc3MgPT0gMSkgewogICAgICAgICAgICAKICAgICAgICAgICAgJGZvckJvc3MgPSAwOwogICAgCSAgICByZXR1cm4gJGZvckJvc3M7ICAgICAvLyDQvNC10YLQvtC0INC40YHQutC70Y7Rh9C40YLQtdC70YzQvdC+INC00LvRjyDRgtC+0LPQviwg0YfRgtC+0LHRiyDQsiDRgdC70YPRh9Cw0LUg0YEgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vINCx0L7RgdGB0L7QvCDQvtCx0L3Rg9C70LjRgtGMINC60L7Qu9C40YfQtdGB0YLQstC+INC90LDQv9C40YHQsNC90L3Ri9GFINC+0YLRh9GR0YLQvtCyINC00LvRjyDQvdC10LPQvgogICAgICAgIH0gZWxzZSB7CgogICAgICAgIAkkZm9yQm9zcyA9IDE7CiAgICAJICAgIHJldHVybiAkZm9yQm9zczsKICAgICAgICB9CiAgICB9Cn0KCmNsYXNzIE1hcmtldGVyIGV4dGVuZHMgRW1wbG95ZWUKewogICAgcHVibGljIGZ1bmN0aW9uIGdldFNhbGFyeShhcnJheSAkc2FsYXJ5LCBpbnQgJGNvZWZmaWNpZW50KQogICAgewoJICAgICRnZXRTYWxhcnkgPSAkc2FsYXJ5WzBdICogJGNvZWZmaWNpZW50OwoJICAgIHJldHVybiAkZ2V0U2FsYXJ5OwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIGdldENvZmZlZShhcnJheSAkY29mZmVlLCBpbnQgJGNvZWZmaWNpZW50KSAgIC8vINGC0YPRgiDQstGB0ZEg0LLRgNC+0LTQtSDQv9C+0L3Rj9GC0L3QviwgMyDQvNC10YLQvtC00LAg0LTQu9GPICAKICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDQstGL0YfQuNGB0LvQtdC90LjRjyDQt9Cw0YAuINC/0LvQsNGC0YssINC60L7RhNC1INC4INC+0YLRh9GR0YLQvtCyCiAgICAJJGdldENvZmZlZSA9ICRjb2ZmZWVbMF0gKiAkY29lZmZpY2llbnQ7ICAgICAgICAgICAgICAgICAgLy8g0L/RgNCw0LLQtNCwINC80L3QtSDQvdC1INC90YDQsNCy0LjRgtGB0Y8g0YLQviwg0YfRgtC+INC/0L4g0YHRg9GC0Lgg0LTQu9GPCiAgICAJcmV0dXJuICRnZXRDb2ZmZWU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g0LLRgdC10YUgNCDQtNC+0LvQttC90L7RgdGC0LXQuSDQvdCw0L/QuNGB0LDQvSDQvtC00LjQvSDQuCDRgtC+0YIg0LbQtSDQutC+0LQKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDQvNC+0LbQtdGCINGH0ZHRgiDQsiDQsNCx0YHRgtGA0LDQutGC0L3Ri9C5INGB0YLQvtC40YIg0LLRi9C90LXRgdGC0Lg/CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3J0cyhhcnJheSAkcmVwb3J0cywgaW50ICRmb3JCb3NzKQogICAgewogICAgCSRnZXRSZXBvcnRzID0gJHJlcG9ydHNbMF0gKiAkZm9yQm9zczsKICAgIAlyZXR1cm4gJGdldFJlcG9ydHM7CiAgICB9CQp9CgpjbGFzcyBBbmFseXN0IGV4dGVuZHMgRW1wbG95ZWUKewoJcHVibGljIGZ1bmN0aW9uIGdldFNhbGFyeShhcnJheSAkc2FsYXJ5LCBpbnQgJGNvZWZmaWNpZW50KQogICAgewoJICAgICRnZXRTYWxhcnkgPSAkc2FsYXJ5WzFdICogJGNvZWZmaWNpZW50OwoJICAgIHJldHVybiAkZ2V0U2FsYXJ5OwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIGdldENvZmZlZShhcnJheSAkY29mZmVlLCBpbnQgJGNvZWZmaWNpZW50KQogICAgewogICAgCSRnZXRDb2ZmZWUgPSAkY29mZmVlWzFdICogJGNvZWZmaWNpZW50OwogICAgCXJldHVybiAkZ2V0Q29mZmVlOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIGdldFJlcG9ydHMoYXJyYXkgJHJlcG9ydHMsIGludCAkZm9yQm9zcykKICAgIHsKICAgIAkkZ2V0UmVwb3J0cyA9ICRyZXBvcnRzWzFdICogJGZvckJvc3M7CiAgICAJcmV0dXJuICRnZXRSZXBvcnRzOwogICAgfQkKfQoKY2xhc3MgTWFuYWdlciBleHRlbmRzIEVtcGxveWVlCnsKCXB1YmxpYyBmdW5jdGlvbiBnZXRTYWxhcnkoYXJyYXkgJHNhbGFyeSwgaW50ICRjb2VmZmljaWVudCkKICAgIHsKCSAgICAkZ2V0U2FsYXJ5ID0gJHNhbGFyeVsyXSAqICRjb2VmZmljaWVudDsKCSAgICByZXR1cm4gJGdldFNhbGFyeTsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb2ZmZWUoYXJyYXkgJGNvZmZlZSwgaW50ICRjb2VmZmljaWVudCkKICAgIHsKICAgIAkkZ2V0Q29mZmVlID0gJGNvZmZlZVsyXSAqICRjb2VmZmljaWVudDsKICAgIAlyZXR1cm4gJGdldENvZmZlZTsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSZXBvcnRzKGFycmF5ICRyZXBvcnRzLCBpbnQgJGZvckJvc3MpCiAgICB7CiAgICAJJGdldFJlcG9ydHMgPSAkcmVwb3J0c1syXSAqICRmb3JCb3NzOwogICAgCXJldHVybiAkZ2V0UmVwb3J0czsKICAgIH0JCn0KCmNsYXNzIEVuZ2luZWVyIGV4dGVuZHMgRW1wbG95ZWUKewoJcHVibGljIGZ1bmN0aW9uIGdldFNhbGFyeShhcnJheSAkc2FsYXJ5LCBpbnQgJGNvZWZmaWNpZW50KQogICAgewoKCSAgICAkZ2V0U2FsYXJ5ID0gJHNhbGFyeVszXSAqICRjb2VmZmljaWVudDsKCSAgICByZXR1cm4gJGdldFNhbGFyeTsKICAgIH0KICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb2ZmZWUoYXJyYXkgJGNvZmZlZSwgaW50ICRjb2VmZmljaWVudCkKICAgIHsKCiAgICAJJGdldENvZmZlZSA9ICRjb2ZmZWVbM10gKiAkY29lZmZpY2llbnQ7CiAgICAJcmV0dXJuICRnZXRDb2ZmZWU7CiAgICB9CiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3J0cyhhcnJheSAkcmVwb3J0cywgaW50ICRmb3JCb3NzKQogICAgewoKICAgIAkkZ2V0UmVwb3J0cyA9ICRyZXBvcnRzWzNdICogJGZvckJvc3M7CiAgICAJcmV0dXJuICRnZXRSZXBvcnRzOwogICAgfQkKfQoKJGRlcGFydG1lbnRzID0gYXJyYXkoICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8g0L/RgNC+0YHRgtC+INC80LDRgdGB0LjQsiDRgdC+INCy0YHQtdC80Lgg0L7RgtC00LXQu9Cw0LzQuAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDQuCDQutC+0Lst0LLQvtC8INGB0L7RgtGA0YPQtNC90LjQutC+0LIg0YDQsNC30L3Ri9GFINC00L7Qu9C20L3QvtGB0YLQtdC5INC4INGA0LDQvdCz0LAg0LIg0L3QuNGFCgkwID0+IGFycmF5KCAgLy8g0JfQsNC60YPQv9C60LgKCQki0LzQtTEiID0+IDksCgkJItC80LUyIiA9PiAzLAoJCSLQvNC1MyIgPT4gMiwKCQki0LzQsDEiID0+IDIsCgkJItC00LjRgNC10LrRgtC+0YDQnNC1MiIgPT4gMQogICAgKSwKICAgIDEgPT4gYXJyYXkoICAvLyDQn9GA0L7QtNCw0LbQuAogICAgCSLQvNC1MSIgPT4gMTIsCiAgICAJItC80LAxIiA9PiA2LAogICAgCSLQsNC9MSIgPT4gMywKICAgIAki0LDQvTIiID0+IDIsCiAgICAJItC00LjRgNC10LrRgtC+0YDQnNCwMiIgPT4gMQogICAgKSwKCiAgICAyID0+IGFycmF5KCAgLy8g0KDQtdC60LvQsNC80LAKICAgIAki0LzQtTEiID0+IDgsCiAgICAJItC80LAxIiA9PiAxNSwKICAgIAki0LzQsDIiID0+IDEwLAogICAgCSLQuNC9MSIgPT4gMiwKICAgIAki0LTQuNGA0LXQutGC0L7RgNCc0LAzIiA9PiAxCiAgICApLAoKICAgIDMgPT4gYXJyYXkoICAvLyDQm9C+0LPQuNGB0YLQuNC60LAKICAgIAki0LzQtTEiID0+IDEzLAogICAgCSLQvNC1MiIgPT4gNSwKICAgIAki0LjQvTEiID0+IDUsCiAgICAJItC00LjRgNC10LrRgtC+0YDQnNC1MSIgPT4gMQogICAgKSAgIAopOwoKZnVuY3Rpb24gcGFkTGVmdCgkc3RyaW5nLCAkbGVuZ3RoKSB7CgoJJGFtb3VudCA9IGljb252X3N0cmxlbigkc3RyaW5nKTsKICAgICRkaWZmZXJlbmNlID0gJGxlbmd0aCAtICRhbW91bnQ7CiAgICAkd2hpdGVzcGFjZXMgPSBzdHJfcmVwZWF0KCcgJywgJGRpZmZlcmVuY2UpOyAgICAgLy8g0LTQu9GPINGC0LDQsdC70LjRhgogICAgJGxlZnRTaWRlID0gJHdoaXRlc3BhY2VzIC4gJHN0cmluZzsKCglyZXR1cm4gJGxlZnRTaWRlOwp9CgpmdW5jdGlvbiBwYWRSaWdodCgkc3RyaW5nLCAkbGVuZ3RoKSB7CgoJJGFtb3VudCA9IGljb252X3N0cmxlbigkc3RyaW5nKTsKICAgICRkaWZmZXJlbmNlID0gJGxlbmd0aCAtICRhbW91bnQ7CiAgICAkd2hpdGVzcGFjZXMgPSBzdHJfcmVwZWF0KCIgIiwgJGRpZmZlcmVuY2UpOwogICAgJHJpZ2h0U2lkZSA9ICRzdHJpbmcgLiAkd2hpdGVzcGFjZXM7CgoJcmV0dXJuICRyaWdodFNpZGU7Cgp9CgpmdW5jdGlvbiBjcmVhdGVFbXBsb3llZXMoKQp7CgkkYWxsRW1wbG95ZWVzID0gYXJyYXkoKTsgICAgICAgICAgICAgICAgLy8g0LTQtdC70LDRjiDQtNCy0YPRgdC70L7QudC90YvQuSDQvNCw0YHRgdC40LIsINGA0LDRgdC/0YDQtdC00LXQu9GP0Y4g0LLRgdC10YUg0L/QviDQvtGC0LTQtdC70LDQvAoJJGJ1eWluZyA9IGFycmF5KCk7ICAgICAgICAgICAgICAgICAgICAgIC8vINGC0YPRgiDQvdC10YIg0L3QuNC60LDQutC+0Lkg0L/RgNC+0LLQtdGA0LrQuCDQv9GA0LDQstC40LvRjNC90L7RgdGC0Lgg0LLQvdC10YHQtdC90LjRjyDRgdC+0YLRgNGD0LTQvdC40LrQvtCyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vINC+0YHRgtCw0ZHRgtGB0Y8g0LvQuNGI0Ywg0LLQvdC40LzQsNGC0LXQu9GM0L3QviDQvtGA0LjQtdC90YLQuNGA0L7QstCw0YLRjNGB0Y8g0L3QsCDQvNCw0YHRgdC40LIgJGRlcGFydG1lbnRzCiAgICAkbWFuYWdlcjEgPSBuZXcgTWFuYWdlcigxLCAwKTsgICAgICAgICAgLy8g0Lgg0LIg0YHQvtC+0YLQstC10YLRgdGC0LLQuNC4INGBINC90LjQvCDQv9C10YDQtdC90L7RgdC40YLRjCDQtNC+0LvQttC90L7RgdGC0Y8KICAgICRtYW5hZ2VyMiA9IG5ldyBNYW5hZ2VyKDIsIDApOwogICAgJG1hbmFnZXIzID0gbmV3IE1hbmFnZXIoMywgMCk7CiAgICAkbWFya2V0ZXIxID0gbmV3IE1hcmtldGVyKDEsIDApOwogICAgJGRpcmVjdG9yTWUyID0gbmV3IE1hbmFnZXIoMiwgMSk7CgogICAgYXJyYXlfcHVzaCgkYnV5aW5nLCAkbWFuYWdlcjEsICRtYW5hZ2VyMiwgJG1hbmFnZXIzLCAkbWFya2V0ZXIxLCAkZGlyZWN0b3JNZTIpOwoKICAgICRzZWxsaW5nID0gYXJyYXkoKTsKCiAgICAkbWFuYWdlcjEgPSBuZXcgTWFuYWdlcigxLCAwKTsKICAgICRtYXJrZXRlcjEgPSBuZXcgTWFya2V0ZXIoMSwgMCk7CiAgICAkYW5hbHlzdDEgPSBuZXcgQW5hbHlzdCgxLCAwKTsKICAgICRhbmFseXN0MiA9IG5ldyBBbmFseXN0KDIsIDApOwogICAgJGRpcmVjdG9yTWFyMiA9IG5ldyBNYXJrZXRlcigyLCAxKTsKCiAgICBhcnJheV9wdXNoKCRzZWxsaW5nLCAkbWFuYWdlcjEsICRtYXJrZXRlcjEsICRhbmFseXN0MSwgJGFuYWx5c3QyLCAkZGlyZWN0b3JNYXIyKTsKCiAgICAkYWRzID0gYXJyYXkoKTsKCiAgICAkbWFuYWdlcjEgPSBuZXcgTWFuYWdlcigxLCAwKTsKICAgICRtYXJrZXRlcjEgPSBuZXcgTWFya2V0ZXIoMSwgMCk7CiAgICAkbWFya2V0ZXIyID0gbmV3IE1hcmtldGVyKDIsIDApOwogICAgJGVuZ2luZWVyMSA9IG5ldyBFbmdpbmVlcigxLCAwKTsKICAgICRkaXJlY3Rvck1hcjMgPSBuZXcgTWFya2V0ZXIoMywgMSk7CgogICAgYXJyYXlfcHVzaCgkYWRzLCAkbWFuYWdlcjEsICRtYXJrZXRlcjEsICRtYXJrZXRlcjIsICRlbmdpbmVlcjEsICRkaXJlY3Rvck1hcjMpOwoKICAgICRsb2dpc3RpY3MgPSBhcnJheSgpOwoKICAgICRtYW5hZ2VyMSA9IG5ldyBNYW5hZ2VyKDEsIDApOwogICAgJG1hbmFnZXIyID0gbmV3IE1hbmFnZXIoMiwgMCk7CiAgICAkZW5naW5lZXIxID0gbmV3IEVuZ2luZWVyKDEsIDApOwogICAgJGRpcmVjdG9yTWExID0gbmV3IE1hbmFnZXIoMSwgMSk7CgogICAgYXJyYXlfcHVzaCgkbG9naXN0aWNzLCAkbWFuYWdlcjEsICRtYW5hZ2VyMiwgJGVuZ2luZWVyMSwgJGRpcmVjdG9yTWExKTsKCiAgICBhcnJheV9wdXNoKCRhbGxFbXBsb3llZXMsICRidXlpbmcsICRzZWxsaW5nLCAkYWRzLCAkbG9naXN0aWNzKTsKCiAgICByZXR1cm4gJGFsbEVtcGxveWVlczsKCn0KCiRlbXBsb3llZXMgPSBjcmVhdGVFbXBsb3llZXMoKTsKCmZ1bmN0aW9uIGdldEFsbCAoYXJyYXkgJGVtcGxveWVlcywgYXJyYXkgJGRlcGFydG1lbnRzKQp7CiAgICAkZ2V0SXQgPSBhcnJheSgpOwoKICAgICRidXlpbmcgPSBhcnJheSgpOyAgICAgICAgICAKICAgICRzZWxsaW5nID0gYXJyYXkoKTsgICAgICAgICAKICAgICRhZHMgPSBhcnJheSgpOyAgICAgICAgICAgICAgCiAgICAkbG9naXN0aWNzID0gYXJyYXkoKTsKICAgICRhdmVyYWdlID0gYXJyYXkoKTsKICAgICR0b3RhbCA9IGFycmF5KCk7CgogICAgJGF2ZXJhZ2VTdW0gPSAwOwogICAgJGF2ZXJhZ2VTID0gMDsKICAgICRhdmVyYWdlQyA9IDA7CiAgICAkYXZlcmFnZVNoID0gMDsKICAgICRhdmVyYWdlUCA9IDA7CgogICAgYXJyYXlfcHVzaCgkZ2V0SXQsICRidXlpbmcsICRzZWxsaW5nLCAkYWRzLCAkbG9naXN0aWNzLCAkYXZlcmFnZSwgJHRvdGFsKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgLy8g0YHQvdC+0LLQsCDQtNCy0L7QudC90L7QuSDQvNCw0YHRgdC4INGBINGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNC10Lwg0L/QviDQvtGC0LTQtdC70LDQvAoKICAgIGZvciAoJGk9MDsgJGkgPCA0OyAkaSsrKSB7IAoKICAgIAkkaG93TXVjaCA9IGFycmF5KCk7CiAgICAJJHNhbGFyeSA9IGFycmF5KCk7CiAgICAJJGNvZmZlZSA9IGFycmF5KCk7CiAgICAJJHNoZWV0cyA9IGFycmF5KCk7CgogICAgCWZvcmVhY2ggKCRkZXBhcnRtZW50c1skaV0gYXMgJGFtb3VudCkgewoKICAgICAgICAgICAgYXJyYXlfcHVzaCgkaG93TXVjaCwgJGFtb3VudCk7CiAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgZm9yZWFjaCAoJGVtcGxveWVlc1skaV0gYXMgJGVtcGxveWVlKSB7IC8vINGB0YfQuNGC0LDRjiDQt9Cw0YDQv9C70LDRgtGDLCDQutC+0YTQtSwg0Lgg0L7RgtGH0ZHRgtGLINC00LvRjyDQutCw0LbQtNC+0LPQviDQvtGC0LTQtdC70LAKCiAgICAgICAgCWFycmF5X3B1c2goJHNhbGFyeSwgJGVtcGxveWVlLT5nZXRTYWxhcnkoJGVtcGxveWVlLT5zYWxhcnksICRlbXBsb3llZS0+ZGlzdHJpYnV0aW5nKCRlbXBsb3llZS0+cmFuaywgJGVtcGxveWVlLT5ib3NzKSkpOwoKICAgICAgICAJYXJyYXlfcHVzaCgkY29mZmVlLCAkZW1wbG95ZWUtPmdldENvZmZlZSgkZW1wbG95ZWUtPmNvZmZlZSwgJGVtcGxveWVlLT5kaXN0cmlidXRpbmcoJGVtcGxveWVlLT5yYW5rLCAkZW1wbG95ZWUtPmJvc3MpKSk7CgogICAgICAgIAlhcnJheV9wdXNoKCRzaGVldHMsICRlbXBsb3llZS0+Z2V0UmVwb3J0cygkZW1wbG95ZWUtPnJlcG9ydHMsICRlbXBsb3llZS0+Ym9zc09STm90KCRlbXBsb3llZS0+Ym9zcykpKTsgIAogICAgICAgIH0KCiAgICAgICAgZm9yICgkYT0wOyAkYSA8IGNvdW50KCRob3dNdWNoKTsgJGErKykgeyAKCiAgICAgICAgCSRzYWxhcnlbJGFdICo9ICRob3dNdWNoWyRhXTsgICAvLyDQutCw0LbQtNC+0LUg0LjQtyDQt9C90LDRh9C10L3QuNC5INC/0L7QvNC90L7QttCw0Y4g0L3QsCDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RidC10LUKICAgICAgICAJJGNvZmZlZVskYV0gKj0gJGhvd011Y2hbJGFdOyAgIC8vINC60L7Qu9C40YfQtdGB0YLQstC+INGB0L7RgtGA0YPQtNC90LjQutC+0LIg0LIg0LTQsNC90L3QvtC8INC+0YLQtNC10LvQtSDQvdCwINC00LDQvdC90L7QvCDRgNCw0L3Qs9C1CiAgICAgICAgCSRzaGVldHNbJGFdICo9ICRob3dNdWNoWyRhXTsgCgogICAgICAgIH0KCiAgICAgICAgJHN1bSA9IGFycmF5X3N1bSgkaG93TXVjaCk7CiAgICAgICAgJGZvclJvdW5kaW5nID0gYXJyYXlfc3VtKCRzYWxhcnkpIC8gYXJyYXlfc3VtKCRzaGVldHMpOwogICAgICAgICRwZXJTaGVldCA9IHJvdW5kKCRmb3JSb3VuZGluZywgMSk7CgogICAgICAgICRhdmVyYWdlU3VtICs9ICRzdW07CiAgICAgICAgJGF2ZXJhZ2VTICs9IGFycmF5X3N1bSgkc2FsYXJ5KTsgIC8vINC00LvRjyDQtNCw0LvRjNC90LXQudGI0LXQs9C+INC/0L7QutCw0LfQsNC90LjRjyDRgdGA0LXQtNC90LjRhSDRgNC10Lct0YLQvtCyINC4INCy0YHQtdCz0L4g0LLQvNC10YHRgtC1CiAgICAgICAgJGF2ZXJhZ2VDICs9IGFycmF5X3N1bSgkY29mZmVlKTsgIC8vINGB0L7QsdC40YDQsNGOINCyINC60L7QvdGG0LUg0LrQsNC20LTQvtCz0L4g0YbQuNC60LvQsCDQt9C90LDRh9C10L3QuNGPIAogICAgICAgICRhdmVyYWdlU2ggKz0gYXJyYXlfc3VtKCRzaGVldHMpOyAvLyDQuNC30L3QsNGH0LDQu9GM0L3QviDQstC+0L7QsdGJ0LUg0L3QtSDQt9Cw0LTRg9C80YvQstCw0Lsg0YHQvtCx0LjRgNCw0YLRjCDRjdGC0Lgg0LfQvdCw0YfQtdC90LjRjwogICAgICAgICRhdmVyYWdlUCArPSAkcGVyU2hlZXQ7ICAgICAgICAgICAvLyDQuNC80LXQvdC90L4g0LIg0Y3RgtC+0Lkg0YTRg9C90LrRhtC40LgsINC00LAg0Lgg0YHQtdC50YfQsNGBINC60LDQui3RgtC+INGN0YLQviDRgdGC0YDRkdC80L3QvgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyDQstGL0LPQu9GP0LTQuNGCLCDRjyDRgdGH0LjRgtCw0Y4KICAgICAgICBhcnJheV9wdXNoKCRnZXRJdFskaV0sICRzdW0sIGFycmF5X3N1bSgkc2FsYXJ5KSwgYXJyYXlfc3VtKCRjb2ZmZWUpLCBhcnJheV9zdW0oJHNoZWV0cyksICRwZXJTaGVldCk7CiAgICB9CgogICAgYXJyYXlfcHVzaCgkZ2V0SXRbNF0sICRhdmVyYWdlU3VtIC8gNCwgJGF2ZXJhZ2VTIC8gNCwgJGF2ZXJhZ2VDIC8gNCwgJGF2ZXJhZ2VTaCAvIDQsICRhdmVyYWdlUCAvIDQpOwogICAgYXJyYXlfcHVzaCgkZ2V0SXRbNV0sICRhdmVyYWdlU3VtLCAkYXZlcmFnZVMsICRhdmVyYWdlQywgJGF2ZXJhZ2VTaCwgJGF2ZXJhZ2VQKTsKCiAgICAvLyDRjyDRgtCw0Log0YPQstC10YDQtdC90L3QviDQv9C+0YHRgtCw0LLQuNC7INGG0LjRhNGA0YsgNCDQuCA1INCyINCy0LXRgNGF0L3QuNC1INC/0YPRiNC4INC/0L7RgtC+0LzRgywg0YfRgtC+INC30LDQstC10LTQvtC80L4g0LfQvdCw0Y4g0YfRgtC+INC/0L7QtAogICAgLy8g0Y3RgtC40LzQuCDQutC70Y7Rh9Cw0LzQuCDRgyDQvNC10L3RjyDQsdGD0LTRg9GCINGB0YDQtdC00L3QuNC1INC4INC/0L7Qu9C90YvQtSDQt9C90LDRh9C10L3QuNGPCiAgICAvLyDRgtCw0Log0LHRi9GC0Ywg0LLQvtC+0LHRidC1INC90LUg0LTQvtC70LbQvdC+LCDRgtGD0YIg0YXQvtGC0Ywg0YfRgtC+INGC0YDQvtC90LXRiNGMINC4INCy0YHRkSDQvdCw0YXRg9C5INGA0LDQt9Cy0LDQu9C40YLRgdGPLCDRjdGC0L4g0LLRgdGRINC40Lct0LfQsCDRgtC+0LPQvgogICAgLy8g0YfRgtC+INGPINGA0LXRiNC40Lsg0YHRgNC10LTQvdC40LUg0LfQvdCw0YfQtdC90LjRjyDQv9C+0LvRg9GH0LDRgtGMINC40LzQtdC90L3QviDQt9C00LXRgdGMCiAgICByZXR1cm4gJGdldEl0Owp9CgoKJGdldEl0ID0gZ2V0QWxsKCRlbXBsb3llZXMsICRkZXBhcnRtZW50cyk7CgplY2hvIHBhZFJpZ2h0KCLQlNC10L/QsNGA0YLQsNC80LXQvdGCIiwgMzApIC4gCiAgICAgcGFkTGVmdCgi0KHQvtGC0YAuIiwgMTApIC4gCiAgICAgcGFkTGVmdCgi0KLRg9Cz0YAuIiwgMTApIC4KICAgICBwYWRMZWZ0KCLQmtC+0YTQtSIsIDEwKSAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vINC90YMg0Lgg0YLRg9GCINGD0LbQtSDRhNC+0YDQvNC40YDRg9C10YLRgdGPINC/0L7Qu9C90LDRjyDRgtCw0LHQu9C40YbQsAogICAgIHBhZExlZnQoItCh0YLRgC4iLCAxMCkgLiAKICAgICBwYWRMZWZ0KCLQotGD0LPRgC4v0YHRgtGALiIsIDEwKSAuICJcblxuIjsKCiRuYW1lcyA9IGFycmF5KCLQl9Cw0LrRg9C/0LrQuCIsItCf0YDQvtC00LDQttC4Iiwi0KDQtdC60LvQsNC80LAiLCLQm9C+0LPQuNGB0YLQuNC60LAiLCAi0KHRgNC10LTQvdC10LUiLCAi0JLRgdC10LPQviIpOwoKJG9uQXZlcmFnZSA9IGFycmF5KCk7CiRidXlpbmcgPSBhcnJheSgpOyAgICAgICAgICAKJHNlbGxpbmcgPSBhcnJheSgpOyAgICAgICAgIAokYWRzID0gYXJyYXkoKTsgICAgICAgICAgICAgIAokbG9naXN0aWNzID0gYXJyYXkoKTsKCmFycmF5X3B1c2goJG9uQXZlcmFnZSwgJGJ1eWluZywgJHNlbGxpbmcsICRhZHMsICRsb2dpc3RpY3MpOwogICAKZm9yICgkaT0wOyAkaSA8IGNvdW50KCRuYW1lcyk7ICRpKyspIHsKCiAgICBlY2hvIHBhZFJpZ2h0KCRuYW1lc1skaV0sIDMwKTsKCglmb3JlYWNoICgkZ2V0SXRbJGldIGFzICR2YWx1ZSkgewoKICAgCWVjaG8gcGFkTGVmdCgkdmFsdWUsIDEwKTsKCiAgICB9CgogICAJZWNobyAiXG4iOwp9CiAgCj8+