<?php
// your code goes here
/*
Департамент закупок: 9×ме1, 3×ме2, 2×ме3, 2×ма1 + руководитель департамента ме2
Департамент продаж: 12×ме1, 6×ма1, 3×ан1, 2×ан2 + руководитель ма2
Департамент рекламы: 15×ма1, 10×ма2, 8×ме1, 2×ин1 + руководитель ма3
Департамент логистики: 13×ме1, 5×ме2, 5×ин1 + руководитель ме1
*/
class Employee {
protected $baseSalary;
protected $coffee;
protected $reports;
protected $rank;
protected $isHead;
public function __construct($rank, $isHead) {
$this->rank = $rank;
$this->isHead = $isHead;
}
public function getSalary() {
$salary = $this->baseSalary;
switch ($this->rank) {
case 2:
$salary *= 1.25;
break;
case 3:
$salary *= 1.5;
break;
}
if ($this->isHead) {
$salary *= 1.5;
}
return $salary;
}
public function setBaseSalary($newSalary) {
$this->baseSalary = $newSalary;
}
public function getCoffee() {
if ($this->isHead) {
return $this->coffee * 2;
} else {
return $this->coffee;
}
}
public function setCoffe($newCoffee) {
$this->coffee = $newCoffee;
}
public function getReports() {
if ($this->isHead) {
return 0;
} else {
return $this->reports;
}
}
public function getRank()
{
return $this->rank;
}
public function setRank($rank)
{
$this->rank = $rank;
}
public function getIsHead()
{
return $this->isHead;
}
public function setIsHead($isHead)
{
$this->isHead = $isHead;
}
}
class Manager extends Employee {
protected $baseSalary = 500;
protected $coffee = 20;
protected $reports = 200;
}
class Marketer extends Employee {
protected $baseSalary = 400;
protected $coffee = 15;
protected $reports = 150;
}
class Engineer extends Employee {
protected $baseSalary = 200;
protected $coffee = 5;
protected $reports = 50;
}
class Analyst extends Employee {
protected $baseSalary = 800;
protected $coffee = 50;
protected $reports = 5;
}
class Department {
private $name;
private $employees = array();
public function __construct($name) {
$this->name = $name;
}
function __clone() { //------------------------
foreach ($this->employees as &$employee) {
$employee = clone $employee;
} //------------------------
}
public function getName() {
return $this->name;
}
public function setName($name) {
$this->name = $name;
}
public function getCountAllEmployees() {
return count($this->employees); }
public function getAllEmployees() {
return $this->employees;
}
public function getAllSalary() {
$allSalary = 0;
foreach ($this->employees as $employee) {
$allSalary += $employee->getSalary();
}
return $allSalary;
}
public function getAllCoffee() {
$allCoffee = 0;
foreach ($this->employees as $employee) {
$allCoffee += $employee->getCoffee();
}
return $allCoffee;
}
public function getAllReports() {
$allReports = 0;
foreach ($this->employees as $employee) {
$allReports += $employee->getReports();
}
return $allReports;
}
public function addEmployees($employees) {
$this->employees = array_merge($this->employees, $employees); }
public function fireEmployee($looser) {
$fired = null;
foreach($this->employees as $key => $employee) {
if ($looser == $employee) {
$fired = $looser;
unset($this->employees[$key]); return $fired;
}
}
return null;
}
}
function createManagers($quantity, $rank, $isHead) {
for ($i = 0; $i < $quantity; $i++) {
array_push($employees, new Manager
($rank, $isHead)); }
return $employees;
}
function createMarketers($quantity, $rank, $isHead) {
for ($i = 0; $i < $quantity; $i++) {
array_push($employees, new Marketer
($rank, $isHead)); }
return $employees;
}
function createEngineers($quantity, $rank, $isHead) {
for ($i = 0; $i < $quantity; $i++) {
array_push($employees, new Engineer
($rank, $isHead)); }
return $employees;
}
function createAnalysts($quantity, $rank, $isHead) {
for ($i = 0; $i < $quantity; $i++) {
array_push($employees, new Analyst
($rank, $isHead)); }
return $employees;
}
function padRight($string, $length) {
return $string;
}
function padLeft($string, $length) {
$modString = "";
$modString .= $string;
return $modString;
}
function outputString($words) {
$col = 11;
echo padRight($words[0], $col);
for ($i = 1; $i < count($words); $i++) { echo padLeft($words[$i], $col);
}
echo "\n";
}
function outputResult($departments) {
$totalEmployees = 0;
$totalSalary = 0;
$totalCoffee = 0;
$totalReports = 0;
$totalConsumption = 0;
$words = array("Департамент", "сотр.", "тугр.", "кофе", "стр.", "тугр./стр."); outputString($words);
echo "\n";
foreach ($departments as $department) {
$employeesCount = $department->getCountAllEmployees();
$totalEmployees += $employeesCount;
$salary = $department->getAllSalary();
$totalSalary += $salary;
$coffee = $department->getAllCoffee();
$totalCoffee += $coffee;
$reports = $department->getAllReports();
$totalReports += $reports;
$consumption = round($salary / $reports, 2); $totalConsumption += $consumption;
$words = array($department->getName(), $employeesCount, $salary, $coffee, $reports, $consumption); outputString($words);
}
echo "\n";
$countDepartments = count($departments); $words = array("Среднее", $totalEmployees / $countDepartments, $totalSalary / $countDepartments, $totalCoffee / $countDepartments, $totalReports / $countDepartments, $totalConsumption / $countDepartments);
outputString($words);
$words = array("Всего", $totalEmployees, $totalSalary, $totalCoffee, $totalReports, $totalConsumption); outputString($words);
}
$employees = array_merge($employees, createManagers
(9, 1, false), createManagers
(3, 2, false), createManagers(2, 3, false), createMarketers(2, 1, false), createManagers(1, 2, true));
$purchases = new Department("Закупок");
$purchases->addEmployees($employees);
$employees = array_merge($employees, createManagers
(12, 1, false), createMarketers
(6, 1, false), createAnalysts(3, 1, false), createAnalysts(2, 2, false), createMarketers(1, 2, true));
$sales = new Department("Продаж");
$sales->addEmployees($employees);
$employees = array_merge($employees, createMarketers
(15, 1, false), createMarketers
(10, 2, false), createManagers(8, 1, false), createEngineers(2, 1, false), createMarketers(1, 3, true));
$ad = new Department("Рекламы");
$ad->addEmployees($employees);
$employees = array_merge($employees, createManagers
(13, 1, false), createManagers
(5, 2, false), createEngineers(5, 1, false), createManagers(1, 1, true));
$logistics = new Department("Логистики");
$logistics->addEmployees($employees);
outputResult($departments);
echo "\n\nАнтикризисные меры:\n\n"; //------------------------------------------------------------------------------------
$testDepartments = array();
echo "1. Сократить в каждом департаменте 40% инженеров:\n\n";
foreach ($departments as $department) {
$countEng = 0;
$testDepartment = clone $department;
$employees = $testDepartment->getAllEmployees();
foreach ($employees as $employee) {
if ($employee instanceof Engineer) {
$countEng++;
}
}
$needFire = ceil($countEng * 0.4);
for ($i = 0; $i < $needFire; $i++) {
for ($j = 0; $j < count($employees); $j++) { if ($employees[$j] instanceof Engineer && !$employees[$j]->getIsHead()) {
$testDepartment->fireEmployee($employees[$j]);
break;
}
}
}
}
outputResult($testDepartments);
echo "\n2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика:\n\n";
$testDepartments = array();
foreach ($departments as $department) {
$testDepartment = clone $department;
$employees = $testDepartment->getAllEmployees();
$haveAnals = false;
$firstAnal = null;
foreach ($employees as $employee) {
if ($employee instanceof Analyst) {
$employee->setBaseSalary(1100);
$employee->setCoffe(75);
if ($firstAnal === null) {
$haveAnals = true;
$firstAnal = $employee;
}
}
if ($employee->getIsHead() && !($employee instanceof Analyst) && $haveAnals) {
$employee->setIsHead(false);
$firstAnal->setRank(3);
$firstAnal->setIsHead(true);
}
}
}
outputResult($testDepartments);
/*echo "3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с
целью расширить их полномочия:<br><br>";*/
echo "\nОригинальная таблица:\n\n";
outputResult($departments);
PD9waHAKCi8vIHlvdXIgY29kZSBnb2VzIGhlcmUKCi8qCtCU0LXQv9Cw0YDRgtCw0LzQtdC90YIg0LfQsNC60YPQv9C+0Lo6IDnDl9C80LUxLCAzw5fQvNC1MiwgMsOX0LzQtTMsIDLDl9C80LAxICsg0YDRg9C60L7QstC+0LTQuNGC0LXQu9GMINC00LXQv9Cw0YDRgtCw0LzQtdC90YLQsCDQvNC1MgrQlNC10L/QsNGA0YLQsNC80LXQvdGCINC/0YDQvtC00LDQtjogMTLDl9C80LUxLCA2w5fQvNCwMSwgM8OX0LDQvTEsIDLDl9Cw0L0yICsg0YDRg9C60L7QstC+0LTQuNGC0LXQu9GMINC80LAyCtCU0LXQv9Cw0YDRgtCw0LzQtdC90YIg0YDQtdC60LvQsNC80Ys6IDE1w5fQvNCwMSwgMTDDl9C80LAyLCA4w5fQvNC1MSwgMsOX0LjQvTEgKyDRgNGD0LrQvtCy0L7QtNC40YLQtdC70Ywg0LzQsDMK0JTQtdC/0LDRgNGC0LDQvNC10L3RgiDQu9C+0LPQuNGB0YLQuNC60Lg6IDEzw5fQvNC1MSwgNcOX0LzQtTIsIDXDl9C40L0xICsg0YDRg9C60L7QstC+0LTQuNGC0LXQu9GMINC80LUxCiovCgplcnJvcl9yZXBvcnRpbmcoLTEpOwoKY2xhc3MgRW1wbG95ZWUgewogICAgcHJvdGVjdGVkICRiYXNlU2FsYXJ5OwogICAgcHJvdGVjdGVkICRjb2ZmZWU7CiAgICBwcm90ZWN0ZWQgJHJlcG9ydHM7CiAgICBwcm90ZWN0ZWQgJHJhbms7CiAgICBwcm90ZWN0ZWQgJGlzSGVhZDsKCiAgICBwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJHJhbmssICRpc0hlYWQpIHsKICAgICAgICAkdGhpcy0+cmFuayA9ICRyYW5rOwogICAgICAgICR0aGlzLT5pc0hlYWQgPSAkaXNIZWFkOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRTYWxhcnkoKSB7CiAgICAgICAgJHNhbGFyeSA9ICR0aGlzLT5iYXNlU2FsYXJ5OwogICAgICAgIHN3aXRjaCAoJHRoaXMtPnJhbmspIHsKICAgICAgICAgICAgY2FzZSAyOgogICAgICAgICAgICAgICAgJHNhbGFyeSAqPSAxLjI1OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgICRzYWxhcnkgKj0gMS41OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmICgkdGhpcy0+aXNIZWFkKSB7CiAgICAgICAgICAgICRzYWxhcnkgKj0gMS41OwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuICRzYWxhcnk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldEJhc2VTYWxhcnkoJG5ld1NhbGFyeSkgewogICAgICAgICR0aGlzLT5iYXNlU2FsYXJ5ID0gJG5ld1NhbGFyeTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0Q29mZmVlKCkgewogICAgICAgIGlmICgkdGhpcy0+aXNIZWFkKSB7CiAgICAgICAgICAgIHJldHVybiAkdGhpcy0+Y29mZmVlICogMjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPmNvZmZlZTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIHNldENvZmZlKCRuZXdDb2ZmZWUpIHsKICAgICAgICAkdGhpcy0+Y29mZmVlID0gJG5ld0NvZmZlZTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0UmVwb3J0cygpIHsKICAgICAgICBpZiAoJHRoaXMtPmlzSGVhZCkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gJHRoaXMtPnJlcG9ydHM7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRSYW5rKCkKICAgIHsKICAgICAgICByZXR1cm4gJHRoaXMtPnJhbms7CiAgICB9CiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0UmFuaygkcmFuaykKICAgIHsKICAgICAgICAkdGhpcy0+cmFuayA9ICRyYW5rOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIGdldElzSGVhZCgpCiAgICB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5pc0hlYWQ7CiAgICB9CiAgICBwdWJsaWMgZnVuY3Rpb24gc2V0SXNIZWFkKCRpc0hlYWQpCiAgICB7CiAgICAgICAgJHRoaXMtPmlzSGVhZCA9ICRpc0hlYWQ7CiAgICB9Cgp9CgpjbGFzcyBNYW5hZ2VyIGV4dGVuZHMgRW1wbG95ZWUgewogICAgcHJvdGVjdGVkICRiYXNlU2FsYXJ5ID0gNTAwOwogICAgcHJvdGVjdGVkICRjb2ZmZWUgPSAyMDsKICAgIHByb3RlY3RlZCAkcmVwb3J0cyA9IDIwMDsKfQoKY2xhc3MgTWFya2V0ZXIgZXh0ZW5kcyBFbXBsb3llZSB7CiAgICBwcm90ZWN0ZWQgJGJhc2VTYWxhcnkgPSA0MDA7CiAgICBwcm90ZWN0ZWQgJGNvZmZlZSA9IDE1OwogICAgcHJvdGVjdGVkICRyZXBvcnRzID0gMTUwOwp9CgpjbGFzcyBFbmdpbmVlciBleHRlbmRzIEVtcGxveWVlIHsKICAgIHByb3RlY3RlZCAkYmFzZVNhbGFyeSA9IDIwMDsKICAgIHByb3RlY3RlZCAkY29mZmVlID0gNTsKICAgIHByb3RlY3RlZCAkcmVwb3J0cyA9IDUwOwp9CgpjbGFzcyBBbmFseXN0IGV4dGVuZHMgRW1wbG95ZWUgewogICAgcHJvdGVjdGVkICRiYXNlU2FsYXJ5ID0gODAwOwogICAgcHJvdGVjdGVkICRjb2ZmZWUgPSA1MDsKICAgIHByb3RlY3RlZCAkcmVwb3J0cyA9IDU7Cn0KCmNsYXNzIERlcGFydG1lbnQgewogICAgcHJpdmF0ZSAkbmFtZTsKICAgIHByaXZhdGUgJGVtcGxveWVlcyA9IGFycmF5KCk7CgogICAgcHVibGljIGZ1bmN0aW9uIF9fY29uc3RydWN0KCRuYW1lKSB7CiAgICAgICAgJHRoaXMtPm5hbWUgPSAkbmFtZTsKICAgIH0KCiAgICBmdW5jdGlvbiBfX2Nsb25lKCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZW1wbG95ZWVzIGFzICYkZW1wbG95ZWUpIHsKICAgICAgICAgICAgJGVtcGxveWVlID0gY2xvbmUgJGVtcGxveWVlOwogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldE5hbWUoKSB7CiAgICAgICAgcmV0dXJuICR0aGlzLT5uYW1lOwogICAgfQogICAgcHVibGljIGZ1bmN0aW9uIHNldE5hbWUoJG5hbWUpIHsKICAgICAgICAkdGhpcy0+bmFtZSA9ICRuYW1lOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRDb3VudEFsbEVtcGxveWVlcygpIHsKICAgICAgICByZXR1cm4gY291bnQoJHRoaXMtPmVtcGxveWVlcyk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsbEVtcGxveWVlcygpIHsKICAgICAgICByZXR1cm4gJHRoaXMtPmVtcGxveWVlczsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZ2V0QWxsU2FsYXJ5KCkgewogICAgICAgICRhbGxTYWxhcnkgPSAwOwogICAgICAgIGZvcmVhY2ggKCR0aGlzLT5lbXBsb3llZXMgYXMgJGVtcGxveWVlKSB7CiAgICAgICAgICAgICRhbGxTYWxhcnkgKz0gJGVtcGxveWVlLT5nZXRTYWxhcnkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRhbGxTYWxhcnk7CiAgICB9CgogICAgcHVibGljIGZ1bmN0aW9uIGdldEFsbENvZmZlZSgpIHsKICAgICAgICAkYWxsQ29mZmVlID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZW1wbG95ZWVzIGFzICRlbXBsb3llZSkgewogICAgICAgICAgICAkYWxsQ29mZmVlICs9ICRlbXBsb3llZS0+Z2V0Q29mZmVlKCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAkYWxsQ29mZmVlOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBnZXRBbGxSZXBvcnRzKCkgewogICAgICAgICRhbGxSZXBvcnRzID0gMDsKICAgICAgICBmb3JlYWNoICgkdGhpcy0+ZW1wbG95ZWVzIGFzICRlbXBsb3llZSkgewogICAgICAgICAgICAkYWxsUmVwb3J0cyArPSAkZW1wbG95ZWUtPmdldFJlcG9ydHMoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuICRhbGxSZXBvcnRzOwogICAgfQoKICAgIHB1YmxpYyBmdW5jdGlvbiBhZGRFbXBsb3llZXMoJGVtcGxveWVlcykgewogICAgICAgICR0aGlzLT5lbXBsb3llZXMgPSBhcnJheV9tZXJnZSgkdGhpcy0+ZW1wbG95ZWVzLCAkZW1wbG95ZWVzKTsKICAgIH0KCiAgICBwdWJsaWMgZnVuY3Rpb24gZmlyZUVtcGxveWVlKCRsb29zZXIpIHsKICAgICAgICAkZmlyZWQgPSBudWxsOwogICAgICAgIGZvcmVhY2goJHRoaXMtPmVtcGxveWVlcyBhcyAka2V5ID0+ICRlbXBsb3llZSkgewogICAgICAgICAgICBpZiAoJGxvb3NlciA9PSAkZW1wbG95ZWUpIHsKICAgICAgICAgICAgICAgICRmaXJlZCA9ICRsb29zZXI7CiAgICAgICAgICAgICAgICB1bnNldCgkdGhpcy0+ZW1wbG95ZWVzWyRrZXldKTsKICAgICAgICAgICAgICAgIHNvcnQoJHRoaXMtPmVtcGxveWVlcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gJGZpcmVkOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBudWxsOwogICAgfQp9CgpmdW5jdGlvbiBjcmVhdGVNYW5hZ2VycygkcXVhbnRpdHksICRyYW5rLCAkaXNIZWFkKSB7CiAgICAkZW1wbG95ZWVzID0gYXJyYXkoKTsKICAgIGZvciAoJGkgPSAwOyAkaSA8ICRxdWFudGl0eTsgJGkrKykgewogICAgICAgIGFycmF5X3B1c2goJGVtcGxveWVlcywgbmV3IE1hbmFnZXIoJHJhbmssICRpc0hlYWQpKTsKICAgIH0KICAgIHJldHVybiAkZW1wbG95ZWVzOwp9CgpmdW5jdGlvbiBjcmVhdGVNYXJrZXRlcnMoJHF1YW50aXR5LCAkcmFuaywgJGlzSGVhZCkgewogICAgJGVtcGxveWVlcyA9IGFycmF5KCk7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkcXVhbnRpdHk7ICRpKyspIHsKICAgICAgICBhcnJheV9wdXNoKCRlbXBsb3llZXMsIG5ldyBNYXJrZXRlcigkcmFuaywgJGlzSGVhZCkpOwogICAgfQogICAgcmV0dXJuICRlbXBsb3llZXM7Cn0KCmZ1bmN0aW9uIGNyZWF0ZUVuZ2luZWVycygkcXVhbnRpdHksICRyYW5rLCAkaXNIZWFkKSB7CiAgICAkZW1wbG95ZWVzID0gYXJyYXkoKTsKICAgIGZvciAoJGkgPSAwOyAkaSA8ICRxdWFudGl0eTsgJGkrKykgewogICAgICAgIGFycmF5X3B1c2goJGVtcGxveWVlcywgbmV3IEVuZ2luZWVyKCRyYW5rLCAkaXNIZWFkKSk7CiAgICB9CiAgICByZXR1cm4gJGVtcGxveWVlczsKfQoKZnVuY3Rpb24gY3JlYXRlQW5hbHlzdHMoJHF1YW50aXR5LCAkcmFuaywgJGlzSGVhZCkgewogICAgJGVtcGxveWVlcyA9IGFycmF5KCk7CiAgICBmb3IgKCRpID0gMDsgJGkgPCAkcXVhbnRpdHk7ICRpKyspIHsKICAgICAgICBhcnJheV9wdXNoKCRlbXBsb3llZXMsIG5ldyBBbmFseXN0KCRyYW5rLCAkaXNIZWFkKSk7CiAgICB9CiAgICByZXR1cm4gJGVtcGxveWVlczsKfQoKZnVuY3Rpb24gcGFkUmlnaHQoJHN0cmluZywgJGxlbmd0aCkgewogICAgJHNwYWNlc0NvdW50ID0gJGxlbmd0aCAtIG1iX3N0cmxlbigkc3RyaW5nKTsKICAgICRzdHJpbmcgLj0gc3RyX3JlcGVhdCgiICIsICRzcGFjZXNDb3VudCk7CiAgICByZXR1cm4gJHN0cmluZzsKfQoKZnVuY3Rpb24gcGFkTGVmdCgkc3RyaW5nLCAkbGVuZ3RoKSB7CiAgICAkbW9kU3RyaW5nID0gIiI7CiAgICAkc3BhY2VzQ291bnQgPSAkbGVuZ3RoIC0gbWJfc3RybGVuKCRzdHJpbmcpOwogICAgJG1vZFN0cmluZyAuPSBzdHJfcmVwZWF0KCIgIiwgJHNwYWNlc0NvdW50KTsKICAgICRtb2RTdHJpbmcgLj0gJHN0cmluZzsKICAgIHJldHVybiAkbW9kU3RyaW5nOwp9CgpmdW5jdGlvbiBvdXRwdXRTdHJpbmcoJHdvcmRzKSB7CiAgICAkY29sID0gMTE7CgogICAgZWNobyBwYWRSaWdodCgkd29yZHNbMF0sICRjb2wpOwoKICAgIGZvciAoJGkgPSAxOyAkaSA8IGNvdW50KCR3b3Jkcyk7ICRpKyspIHsKICAgICAgICBlY2hvIHBhZExlZnQoJHdvcmRzWyRpXSwgJGNvbCk7CiAgICB9CiAgICBlY2hvICJcbiI7Cn0KCmZ1bmN0aW9uIG91dHB1dFJlc3VsdCgkZGVwYXJ0bWVudHMpIHsKICAgICR0b3RhbEVtcGxveWVlcyA9IDA7CiAgICAkdG90YWxTYWxhcnkgPSAwOwogICAgJHRvdGFsQ29mZmVlID0gMDsKICAgICR0b3RhbFJlcG9ydHMgPSAwOwogICAgJHRvdGFsQ29uc3VtcHRpb24gPSAwOwoKICAgICR3b3JkcyA9IGFycmF5KCLQlNC10L/QsNGA0YLQsNC80LXQvdGCIiwgItGB0L7RgtGALiIsICLRgtGD0LPRgC4iLCAi0LrQvtGE0LUiLCAi0YHRgtGALiIsICLRgtGD0LPRgC4v0YHRgtGALiIpOwogICAgb3V0cHV0U3RyaW5nKCR3b3Jkcyk7CgogICAgZWNobyBzdHJfcmVwZWF0KCItIiwgNzApOwogICAgZWNobyAiXG4iOwoKICAgIGZvcmVhY2ggKCRkZXBhcnRtZW50cyBhcyAkZGVwYXJ0bWVudCkgewoKICAgICAgICAkZW1wbG95ZWVzQ291bnQgPSAkZGVwYXJ0bWVudC0+Z2V0Q291bnRBbGxFbXBsb3llZXMoKTsKICAgICAgICAkdG90YWxFbXBsb3llZXMgKz0gJGVtcGxveWVlc0NvdW50OwoKICAgICAgICAkc2FsYXJ5ID0gJGRlcGFydG1lbnQtPmdldEFsbFNhbGFyeSgpOwogICAgICAgICR0b3RhbFNhbGFyeSArPSAkc2FsYXJ5OwoKICAgICAgICAkY29mZmVlID0gJGRlcGFydG1lbnQtPmdldEFsbENvZmZlZSgpOwogICAgICAgICR0b3RhbENvZmZlZSArPSAkY29mZmVlOwoKICAgICAgICAkcmVwb3J0cyA9ICRkZXBhcnRtZW50LT5nZXRBbGxSZXBvcnRzKCk7CiAgICAgICAgJHRvdGFsUmVwb3J0cyArPSAkcmVwb3J0czsKCiAgICAgICAgJGNvbnN1bXB0aW9uID0gcm91bmQoJHNhbGFyeSAvICRyZXBvcnRzLCAyKTsKICAgICAgICAkdG90YWxDb25zdW1wdGlvbiArPSAkY29uc3VtcHRpb247CgogICAgICAgICR3b3JkcyA9IGFycmF5KCRkZXBhcnRtZW50LT5nZXROYW1lKCksICRlbXBsb3llZXNDb3VudCwgJHNhbGFyeSwgJGNvZmZlZSwgJHJlcG9ydHMsICRjb25zdW1wdGlvbik7CiAgICAgICAgb3V0cHV0U3RyaW5nKCR3b3Jkcyk7CiAgICB9CgogICAgZWNobyAiXG4iOwoKICAgICRjb3VudERlcGFydG1lbnRzID0gY291bnQoJGRlcGFydG1lbnRzKTsKICAgICR3b3JkcyA9IGFycmF5KCLQodGA0LXQtNC90LXQtSIsICR0b3RhbEVtcGxveWVlcyAvICRjb3VudERlcGFydG1lbnRzLCAkdG90YWxTYWxhcnkgLyAkY291bnREZXBhcnRtZW50cywgJHRvdGFsQ29mZmVlIC8gJGNvdW50RGVwYXJ0bWVudHMsCiAgICAgICAgJHRvdGFsUmVwb3J0cyAvICRjb3VudERlcGFydG1lbnRzLCAkdG90YWxDb25zdW1wdGlvbiAvICRjb3VudERlcGFydG1lbnRzKTsKICAgIG91dHB1dFN0cmluZygkd29yZHMpOwoKICAgICR3b3JkcyA9IGFycmF5KCLQktGB0LXQs9C+IiwgJHRvdGFsRW1wbG95ZWVzLCAkdG90YWxTYWxhcnksICR0b3RhbENvZmZlZSwgJHRvdGFsUmVwb3J0cywgJHRvdGFsQ29uc3VtcHRpb24pOwogICAgb3V0cHV0U3RyaW5nKCR3b3Jkcyk7Cn0KCiRlbXBsb3llZXMgPSBhcnJheSgpOwokZGVwYXJ0bWVudHMgPSBhcnJheSgpOwoKJGVtcGxveWVlcyA9IGFycmF5X21lcmdlKCRlbXBsb3llZXMsIGNyZWF0ZU1hbmFnZXJzKDksIDEsIGZhbHNlKSwgY3JlYXRlTWFuYWdlcnMoMywgMiwgZmFsc2UpLAogICAgY3JlYXRlTWFuYWdlcnMoMiwgMywgZmFsc2UpLCBjcmVhdGVNYXJrZXRlcnMoMiwgMSwgZmFsc2UpLCBjcmVhdGVNYW5hZ2VycygxLCAyLCB0cnVlKSk7CgokcHVyY2hhc2VzID0gbmV3IERlcGFydG1lbnQoItCX0LDQutGD0L/QvtC6Iik7CiRwdXJjaGFzZXMtPmFkZEVtcGxveWVlcygkZW1wbG95ZWVzKTsKCmFycmF5X3B1c2goJGRlcGFydG1lbnRzLCAkcHVyY2hhc2VzKTsKCiRlbXBsb3llZXMgPSBhcnJheSgpOwokZW1wbG95ZWVzID0gYXJyYXlfbWVyZ2UoJGVtcGxveWVlcywgY3JlYXRlTWFuYWdlcnMoMTIsIDEsIGZhbHNlKSwgY3JlYXRlTWFya2V0ZXJzKDYsIDEsIGZhbHNlKSwKICAgIGNyZWF0ZUFuYWx5c3RzKDMsIDEsIGZhbHNlKSwgY3JlYXRlQW5hbHlzdHMoMiwgMiwgZmFsc2UpLCBjcmVhdGVNYXJrZXRlcnMoMSwgMiwgdHJ1ZSkpOwoKJHNhbGVzID0gbmV3IERlcGFydG1lbnQoItCf0YDQvtC00LDQtiIpOwokc2FsZXMtPmFkZEVtcGxveWVlcygkZW1wbG95ZWVzKTsKCmFycmF5X3B1c2goJGRlcGFydG1lbnRzLCAkc2FsZXMpOwoKJGVtcGxveWVlcyA9IGFycmF5KCk7CiRlbXBsb3llZXMgPSBhcnJheV9tZXJnZSgkZW1wbG95ZWVzLCBjcmVhdGVNYXJrZXRlcnMoMTUsIDEsIGZhbHNlKSwgY3JlYXRlTWFya2V0ZXJzKDEwLCAyLCBmYWxzZSksCiAgICBjcmVhdGVNYW5hZ2Vycyg4LCAxLCBmYWxzZSksIGNyZWF0ZUVuZ2luZWVycygyLCAxLCBmYWxzZSksIGNyZWF0ZU1hcmtldGVycygxLCAzLCB0cnVlKSk7CgokYWQgPSBuZXcgRGVwYXJ0bWVudCgi0KDQtdC60LvQsNC80YsiKTsKJGFkLT5hZGRFbXBsb3llZXMoJGVtcGxveWVlcyk7CgphcnJheV9wdXNoKCRkZXBhcnRtZW50cywgJGFkKTsKCiRlbXBsb3llZXMgPSBhcnJheSgpOwokZW1wbG95ZWVzID0gYXJyYXlfbWVyZ2UoJGVtcGxveWVlcywgY3JlYXRlTWFuYWdlcnMoMTMsIDEsIGZhbHNlKSwgY3JlYXRlTWFuYWdlcnMoNSwgMiwgZmFsc2UpLAogICAgY3JlYXRlRW5naW5lZXJzKDUsIDEsIGZhbHNlKSwgY3JlYXRlTWFuYWdlcnMoMSwgMSwgdHJ1ZSkpOwoKJGxvZ2lzdGljcyA9IG5ldyBEZXBhcnRtZW50KCLQm9C+0LPQuNGB0YLQuNC60LgiKTsKJGxvZ2lzdGljcy0+YWRkRW1wbG95ZWVzKCRlbXBsb3llZXMpOwoKYXJyYXlfcHVzaCgkZGVwYXJ0bWVudHMsICRsb2dpc3RpY3MpOwoKb3V0cHV0UmVzdWx0KCRkZXBhcnRtZW50cyk7CgplY2hvICJcblxu0JDQvdGC0LjQutGA0LjQt9C40YHQvdGL0LUg0LzQtdGA0Ys6XG5cbiI7IC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgokdGVzdERlcGFydG1lbnRzID0gYXJyYXkoKTsKCmVjaG8gIjEuINCh0L7QutGA0LDRgtC40YLRjCDQsiDQutCw0LbQtNC+0Lwg0LTQtdC/0LDRgNGC0LDQvNC10L3RgtC1IDQwJSDQuNC90LbQtdC90LXRgNC+0LI6XG5cbiI7Cgpmb3JlYWNoICgkZGVwYXJ0bWVudHMgYXMgJGRlcGFydG1lbnQpIHsKICAgICRjb3VudEVuZyA9IDA7CiAgICAkdGVzdERlcGFydG1lbnQgPSBjbG9uZSAkZGVwYXJ0bWVudDsKICAgICRlbXBsb3llZXMgPSAkdGVzdERlcGFydG1lbnQtPmdldEFsbEVtcGxveWVlcygpOwogICAgZm9yZWFjaCAoJGVtcGxveWVlcyBhcyAkZW1wbG95ZWUpIHsKICAgICAgICBpZiAoJGVtcGxveWVlIGluc3RhbmNlb2YgRW5naW5lZXIpIHsKICAgICAgICAgICAgJGNvdW50RW5nKys7CiAgICAgICAgfQogICAgfQoKICAgICRuZWVkRmlyZSA9IGNlaWwoJGNvdW50RW5nICogMC40KTsKCiAgICBmb3IgKCRpID0gMDsgJGkgPCAkbmVlZEZpcmU7ICRpKyspIHsKICAgICAgICBmb3IgKCRqID0gMDsgJGogPCBjb3VudCgkZW1wbG95ZWVzKTsgJGorKykgewogICAgICAgICAgICBpZiAoJGVtcGxveWVlc1skal0gaW5zdGFuY2VvZiBFbmdpbmVlciAmJiAhJGVtcGxveWVlc1skal0tPmdldElzSGVhZCgpKSB7CiAgICAgICAgICAgICAgICAkdGVzdERlcGFydG1lbnQtPmZpcmVFbXBsb3llZSgkZW1wbG95ZWVzWyRqXSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGFycmF5X3B1c2goJHRlc3REZXBhcnRtZW50cywgJHRlc3REZXBhcnRtZW50KTsKfQoKb3V0cHV0UmVzdWx0KCR0ZXN0RGVwYXJ0bWVudHMpOwoKZWNobyAiXG4yLiDQo9Cy0LXQu9C40YfQuNGC0Ywg0LIg0YbQtdC70Y/RhSDRgdGC0LjQvNGD0LvRj9GG0LjQuCDRg9C80YHRgtCy0LXQvdC90L7QuSDQtNC10Y/RgtC10LvRjNC90L7RgdGC0Lgg0LHQsNC30L7QstGD0Y4g0YHRgtCw0LLQutGDINCw0L3QsNC70LjRgtC40LrQsDpcblxuIjsKCiR0ZXN0RGVwYXJ0bWVudHMgPSBhcnJheSgpOwoKZm9yZWFjaCAoJGRlcGFydG1lbnRzIGFzICRkZXBhcnRtZW50KSB7CiAgICAkdGVzdERlcGFydG1lbnQgPSBjbG9uZSAkZGVwYXJ0bWVudDsKICAgICRlbXBsb3llZXMgPSAkdGVzdERlcGFydG1lbnQtPmdldEFsbEVtcGxveWVlcygpOwogICAgJGhhdmVBbmFscyA9IGZhbHNlOwogICAgJGZpcnN0QW5hbCA9IG51bGw7CiAgICBmb3JlYWNoICgkZW1wbG95ZWVzIGFzICRlbXBsb3llZSkgewogICAgICAgIGlmICgkZW1wbG95ZWUgaW5zdGFuY2VvZiBBbmFseXN0KSB7CiAgICAgICAgICAgICRlbXBsb3llZS0+c2V0QmFzZVNhbGFyeSgxMTAwKTsKICAgICAgICAgICAgJGVtcGxveWVlLT5zZXRDb2ZmZSg3NSk7CiAgICAgICAgICAgIGlmICgkZmlyc3RBbmFsID09PSBudWxsKSB7CiAgICAgICAgICAgICAgICAkaGF2ZUFuYWxzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICRmaXJzdEFuYWwgPSAkZW1wbG95ZWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICgkZW1wbG95ZWUtPmdldElzSGVhZCgpICYmICEoJGVtcGxveWVlIGluc3RhbmNlb2YgQW5hbHlzdCkgJiYgJGhhdmVBbmFscykgewogICAgICAgICAgICAkZW1wbG95ZWUtPnNldElzSGVhZChmYWxzZSk7CiAgICAgICAgICAgICRmaXJzdEFuYWwtPnNldFJhbmsoMyk7CiAgICAgICAgICAgICRmaXJzdEFuYWwtPnNldElzSGVhZCh0cnVlKTsKICAgICAgICB9CiAgICB9CiAgICBhcnJheV9wdXNoKCR0ZXN0RGVwYXJ0bWVudHMsICR0ZXN0RGVwYXJ0bWVudCk7Cn0KCm91dHB1dFJlc3VsdCgkdGVzdERlcGFydG1lbnRzKTsKCi8qZWNobyAiMy4g0JIg0LrQsNC20LTQvtC8INC00LXQv9Cw0YDRgtCw0LzQtdC90YLQtSDQv9C+0LLRi9GB0LjRgtGMIDUwJSAo0L7QutGA0YPQs9C70Y/RjyDQsiDQsdC+0LvRjNGI0YPRjiDRgdGC0L7RgNC+0L3Rgykg0LzQtdC90LXQtNC20LXRgNC+0LIgMS3Qs9C+INC4IDIt0LPQviDRgNCw0L3Qs9CwINC90LAg0L7QtNC40L0g0YDQsNC90LMg0YEKICAgICAgICDRhtC10LvRjNGOINGA0LDRgdGI0LjRgNC40YLRjCDQuNGFINC/0L7Qu9C90L7QvNC+0YfQuNGPOjxicj48YnI+IjsqLwplY2hvICJcbtCe0YDQuNCz0LjQvdCw0LvRjNC90LDRjyDRgtCw0LHQu9C40YbQsDpcblxuIjsKCm91dHB1dFJlc3VsdCgkZGVwYXJ0bWVudHMpOw==