<?php
/**
* classes.php
*/
class Company {
public function __construct
(array $depts) { $this->depts = $depts;
}
public function getDepts() {
return $this->depts;
}
public function getTotalStaffNumber() {
$staffNumber = 0;
foreach ($this->depts as $dept) {
$staffNumber += $dept->getStaffNumber();
}
return $staffNumber;
}
public function getTotalLaborCost() {
$laborCost = 0;
foreach ($this->depts as $dept) {
$laborCost += $dept->getLaborCost();
}
return $laborCost;
}
public function getTotalCoffeeConsumption() {
$coffee = 0;
foreach ($this->depts as $dept) {
$coffee += $dept->getCoffeeConsumption();
}
return $coffee;
}
public function getTotalPaperworkProduced() {
$paperwork = 0;
foreach ($this->depts as $dept) {
$paperwork += $dept->getPaperworkProduced();
}
return $paperwork;
}
public function getTotalCostPerPage() {
$cost = 0;
foreach ($this->depts as $dept) {
$cost += $dept->getCostPerPage();
}
return $cost;
}
public function getAverageStaffNumber() {
return round($this->getTotalStaffNumber() / count($this->depts), 2); }
public function getAverageLaborCost() {
return round($this->getTotalLaborCost() / count($this->depts), 2); }
public function getAverageCoffeeConsumption() {
return round($this->getTotalCoffeeConsumption() / count($this->depts), 2); }
public function getAveragePaperworkProduced() {
return round($this->getTotalPaperworkProduced() / count($this->depts), 2); }
public function getAverageCostPerPage() {
return round($this->getTotalCostPerPage() / count($this->depts), 2); }
/**
* should I use echo or is it better to put the entire report string in a var?
*/
public function printReport() {
$regcol = 15;
$widecol = 20;
echo padString('DEPARTMENT', $widecol) . padString('STAFF', $regcol, 'left') . padString('LABOR COST', $regcol, 'left') . padString('COFFEE DRUNK', $regcol, 'left') . padString('PAGES', $regcol, 'left') . padString('COST PER PAGE', $regcol, 'left') . "\n";
echo padString('=', $widecol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . "\n";
foreach ($this->depts as $dept) {
echo padString($dept->getName(), $widecol) . padString($dept->getStaffNumber(), $regcol, 'left') . padString($dept->getLaborCost(), $regcol, 'left') . padString($dept->getCoffeeConsumption(), $regcol, 'left') . padString($dept->getPaperworkProduced(), $regcol, 'left') . padString($dept->getCostPerPage(), $regcol, 'left') . "\n";
}
echo padString('=', $widecol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . padString('=', $regcol, 'right', '=') . "\n";
echo padString('TOTAL', $widecol) . padString($this->getTotalStaffNumber(), $regcol, 'left') . padString($this->getTotalLaborCost(), $regcol, 'left') . padString($this->getTotalCoffeeConsumption(), $regcol, 'left') . padString($this->getTotalPaperworkProduced(), $regcol, 'left') . padString($this->getTotalCostPerPage(), $regcol, 'left') . "\n";
echo padString('AVERAGE', $widecol) . padString($this->getAverageStaffNumber(), $regcol, 'left') . padString($this->getAverageLaborCost(), $regcol, 'left') . padString($this->getAverageCoffeeConsumption(), $regcol, 'left') . padString($this->getAveragePaperworkProduced(), $regcol, 'left') . padString($this->getAverageCostPerPage(), $regcol, 'left') . "\n";
}
}
class Department {
protected string $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function addToStaff(Employee $employee) {
$this->staff[] = $employee;
}
public function getStaffNumber() {
return count($this->staff); }
public function getLaborCost() {
$laborCost = 0;
foreach ($this->staff as $employee) {
$laborCost += $employee->getActualPay();
}
return $laborCost;
}
public function getCoffeeConsumption() {
$coffee = 0;
foreach ($this->staff as $employee) {
$coffee += $employee->getActualCoffeeConsumption();
}
return $coffee;
}
public function getPaperworkProduced() {
$paperwork = 0;
foreach ($this->staff as $employee) {
$paperwork += $employee->getActualPaperworkProduced();
}
return $paperwork;
}
public function getCostPerPage() {
return round($this->getLaborCost() / $this->getPaperworkProduced(), 2); }
}
abstract class Employee {
const MANAGER = "Manager";
const MARKETER = "Marketer";
const ENGINEER = "Engineer";
const ANALYST = "Analyst";
protected int $grade;
protected bool $chief;
public function __construct(int $grade, bool $chief = false) {
$this->grade = $grade;
$this->chief = $chief;
}
abstract public function getBaseRate();
abstract public function getBaseCoffeeConsumption();
abstract public function getBasePaperworkProduced();
public function getActualPay() {
$rate = $this->getBaseRate();
if ($this->grade == 2) {
$rate *= 1.25;
} elseif ($this->grade == 3) {
$rate = $rate * 1.5;
}
return $this->chief ? $rate * 2 : $rate;
}
public function getActualCoffeeConsumption() {
return $this->chief ? $this->getBaseCoffeeConsumption() * 2 : $this->getBaseCoffeeConsumption();
}
public function getActualPaperworkProduced(): int {
return $this->chief ? 0 : $this->getBasePaperworkProduced();
}
}
class Manager extends Employee {
protected $baseRate = 500;
protected $baseCoffeeConsumption = 20;
protected int $basePaperworkProduced = 200;
public function getBaseRate() {
return $this->baseRate;
}
public function getBaseCoffeeConsumption() {
return $this->baseCoffeeConsumption;
}
public function getBasePaperworkProduced() {
return $this->basePaperworkProduced;
}
}
class Marketer extends Employee {
protected $baseRate = 400;
protected $baseCoffeeConsumption = 15;
protected int $basePaperworkProduced = 150;
public function getBaseRate() {
return $this->baseRate;
}
public function getBaseCoffeeConsumption() {
return $this->baseCoffeeConsumption;
}
public function getBasePaperworkProduced() {
return $this->basePaperworkProduced;
}
}
class Engineer extends Employee {
protected $baseRate = 200;
protected $baseCoffeeConsumption = 5;
protected int $basePaperworkProduced = 50;
public function getBaseRate() {
return $this->baseRate;
}
public function getBaseCoffeeConsumption() {
return $this->baseCoffeeConsumption;
}
public function getBasePaperworkProduced() {
return $this->basePaperworkProduced;
}
}
class Analyst extends Employee {
protected $baseRate = 800;
protected $baseCoffeeConsumption = 50;
protected int $basePaperworkProduced = 5;
public function getBaseRate() {
return $this->baseRate;
}
public function getBaseCoffeeConsumption() {
return $this->baseCoffeeConsumption;
}
public function getBasePaperworkProduced() {
return $this->basePaperworkProduced;
}
}
/**
* input.php
*/
$input = [
'Purchasing' => [
[9, Employee::MANAGER, 1],
[3, Employee::MANAGER, 2],
[2, Employee::MANAGER, 3],
[2, Employee::MARKETER, 1],
[1, Employee::MANAGER, 2, true]
],
'Sales' => [
[12, Employee::MANAGER, 1],
[6, Employee::MARKETER, 1],
[3, Employee::ANALYST, 1],
[2, Employee::ANALYST, 2],
[1, Employee::MARKETER, 2, true]
],
'Advertising' => [
[15, Employee::MARKETER, 1],
[10, Employee::MARKETER, 2],
[8, Employee::MANAGER, 1],
[2, Employee::ENGINEER, 1],
[1, Employee::MARKETER, 3, true]
],
'Logistics' => [
[13, Employee::MANAGER, 1],
[5, Employee::MANAGER, 2],
[5, Employee::ENGINEER, 1],
[1, Employee::MANAGER, 1, true]
]
];
/**
* padstring.php
*/
function padString($string, $length, $side = "right", $pad = " ") {
if (strlen($string) == $length) { return $string;
} else {
$charsNeeded = $length - strlen($string); // 5 ($side == "right") ? ($string = $string . $padding) : ($string = $padding . $string);
return $string;
}
}
/**
* main.php
*/
$depts = [];
foreach ($input as $dept => $staff) {
$currentDept = new Department($dept);
foreach ($staff as $employeeGroup) {
$quantity = $employeeGroup[0];
$type = $employeeGroup[1];
$grade = $employeeGroup[2];
$chief = isset($employeeGroup[3]) ?
true : false; for ($c = 0; $c < $quantity; $c++) {
$employeeObject = new $type($grade, $chief);
$currentDept->addToStaff($employeeObject);
}
}
$depts[] = $currentDept;
}
return $depts;
}
$depts = makeDepts($input);
$company = new Company($depts);
$company->printReport();
PD9waHAKCi8qKgogKiBjbGFzc2VzLnBocAogKi8KCmNsYXNzIENvbXBhbnkgewoJcHJvdGVjdGVkIGFycmF5ICRkZXB0czsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoYXJyYXkgJGRlcHRzKSB7CgkJJHRoaXMtPmRlcHRzID0gJGRlcHRzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXREZXB0cygpIHsKCQlyZXR1cm4gJHRoaXMtPmRlcHRzOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbFN0YWZmTnVtYmVyKCkgewoJCSRzdGFmZk51bWJlciA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcHRzIGFzICRkZXB0KSB7CgkJCSRzdGFmZk51bWJlciArPSAkZGVwdC0+Z2V0U3RhZmZOdW1iZXIoKTsKCQl9CgkJcmV0dXJuICRzdGFmZk51bWJlcjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxMYWJvckNvc3QoKSB7CgkJJGxhYm9yQ29zdCA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcHRzIGFzICRkZXB0KSB7CgkJCSRsYWJvckNvc3QgKz0gJGRlcHQtPmdldExhYm9yQ29zdCgpOwoJCX0KCQlyZXR1cm4gJGxhYm9yQ29zdDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0VG90YWxDb2ZmZWVDb25zdW1wdGlvbigpIHsKCQkkY29mZmVlID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwdHMgYXMgJGRlcHQpIHsKCQkJJGNvZmZlZSArPSAkZGVwdC0+Z2V0Q29mZmVlQ29uc3VtcHRpb24oKTsKCQl9CgkJcmV0dXJuICRjb2ZmZWU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldFRvdGFsUGFwZXJ3b3JrUHJvZHVjZWQoKSB7CgkJJHBhcGVyd29yayA9IDA7CgkJZm9yZWFjaCAoJHRoaXMtPmRlcHRzIGFzICRkZXB0KSB7CgkJCSRwYXBlcndvcmsgKz0gJGRlcHQtPmdldFBhcGVyd29ya1Byb2R1Y2VkKCk7CgkJfQoJCXJldHVybiAkcGFwZXJ3b3JrOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRUb3RhbENvc3RQZXJQYWdlKCkgewoJCSRjb3N0ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwdHMgYXMgJGRlcHQpIHsKCQkJJGNvc3QgKz0gJGRlcHQtPmdldENvc3RQZXJQYWdlKCk7CgkJfQoJCXJldHVybiAkY29zdDsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXZlcmFnZVN0YWZmTnVtYmVyKCkgewoJCXJldHVybiByb3VuZCgkdGhpcy0+Z2V0VG90YWxTdGFmZk51bWJlcigpIC8gY291bnQoJHRoaXMtPmRlcHRzKSwgMik7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEF2ZXJhZ2VMYWJvckNvc3QoKSB7CgkJcmV0dXJuIHJvdW5kKCR0aGlzLT5nZXRUb3RhbExhYm9yQ29zdCgpIC8gY291bnQoJHRoaXMtPmRlcHRzKSwgMik7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEF2ZXJhZ2VDb2ZmZWVDb25zdW1wdGlvbigpIHsKCQlyZXR1cm4gcm91bmQoJHRoaXMtPmdldFRvdGFsQ29mZmVlQ29uc3VtcHRpb24oKSAvIGNvdW50KCR0aGlzLT5kZXB0cyksIDIpOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBdmVyYWdlUGFwZXJ3b3JrUHJvZHVjZWQoKSB7CgkJcmV0dXJuIHJvdW5kKCR0aGlzLT5nZXRUb3RhbFBhcGVyd29ya1Byb2R1Y2VkKCkgLyBjb3VudCgkdGhpcy0+ZGVwdHMpLCAyKTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QXZlcmFnZUNvc3RQZXJQYWdlKCkgewoJCXJldHVybiByb3VuZCgkdGhpcy0+Z2V0VG90YWxDb3N0UGVyUGFnZSgpIC8gY291bnQoJHRoaXMtPmRlcHRzKSwgMik7Cgl9CgoJLyoqCgkgKiBzaG91bGQgSSB1c2UgZWNobyBvciBpcyBpdCBiZXR0ZXIgdG8gcHV0IHRoZSBlbnRpcmUgcmVwb3J0IHN0cmluZyBpbiBhIHZhcj8KCSAqLwoJcHVibGljIGZ1bmN0aW9uIHByaW50UmVwb3J0KCkgewoJCSRyZWdjb2wgPSAxNTsKCQkkd2lkZWNvbCA9IDIwOwoKCQllY2hvIHBhZFN0cmluZygnREVQQVJUTUVOVCcsICR3aWRlY29sKSAuIHBhZFN0cmluZygnU1RBRkYnLCAkcmVnY29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCdMQUJPUiBDT1NUJywgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygnQ09GRkVFIERSVU5LJywgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygnUEFHRVMnLCAkcmVnY29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCdDT1NUIFBFUiBQQUdFJywgJHJlZ2NvbCwgJ2xlZnQnKSAuICJcbiI7CgkJZWNobyBwYWRTdHJpbmcoJz0nLCAkd2lkZWNvbCwgJ3JpZ2h0JywgJz0nKSAuIHBhZFN0cmluZygnPScsICRyZWdjb2wsICdyaWdodCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnY29sLCAncmlnaHQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ2NvbCwgJ3JpZ2h0JywgJz0nKSAuIHBhZFN0cmluZygnPScsICRyZWdjb2wsICdyaWdodCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnY29sLCAncmlnaHQnLCAnPScpIC4gIlxuIjsKCQlmb3JlYWNoICgkdGhpcy0+ZGVwdHMgYXMgJGRlcHQpIHsKCQkJZWNobyBwYWRTdHJpbmcoJGRlcHQtPmdldE5hbWUoKSwgJHdpZGVjb2wpIC4gcGFkU3RyaW5nKCRkZXB0LT5nZXRTdGFmZk51bWJlcigpLCAkcmVnY29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCRkZXB0LT5nZXRMYWJvckNvc3QoKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkZGVwdC0+Z2V0Q29mZmVlQ29uc3VtcHRpb24oKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkZGVwdC0+Z2V0UGFwZXJ3b3JrUHJvZHVjZWQoKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkZGVwdC0+Z2V0Q29zdFBlclBhZ2UoKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuICJcbiI7CgkJfQoJCWVjaG8gcGFkU3RyaW5nKCc9JywgJHdpZGVjb2wsICdyaWdodCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnY29sLCAncmlnaHQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ2NvbCwgJ3JpZ2h0JywgJz0nKSAuIHBhZFN0cmluZygnPScsICRyZWdjb2wsICdyaWdodCcsICc9JykgLiBwYWRTdHJpbmcoJz0nLCAkcmVnY29sLCAncmlnaHQnLCAnPScpIC4gcGFkU3RyaW5nKCc9JywgJHJlZ2NvbCwgJ3JpZ2h0JywgJz0nKSAuICJcbiI7CgkJZWNobyBwYWRTdHJpbmcoJ1RPVEFMJywgJHdpZGVjb2wpIC4gcGFkU3RyaW5nKCR0aGlzLT5nZXRUb3RhbFN0YWZmTnVtYmVyKCksICRyZWdjb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJHRoaXMtPmdldFRvdGFsTGFib3JDb3N0KCksICRyZWdjb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJHRoaXMtPmdldFRvdGFsQ29mZmVlQ29uc3VtcHRpb24oKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkdGhpcy0+Z2V0VG90YWxQYXBlcndvcmtQcm9kdWNlZCgpLCAkcmVnY29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCR0aGlzLT5nZXRUb3RhbENvc3RQZXJQYWdlKCksICRyZWdjb2wsICdsZWZ0JykgLiAiXG4iOwoJCWVjaG8gcGFkU3RyaW5nKCdBVkVSQUdFJywgJHdpZGVjb2wpIC4gcGFkU3RyaW5nKCR0aGlzLT5nZXRBdmVyYWdlU3RhZmZOdW1iZXIoKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkdGhpcy0+Z2V0QXZlcmFnZUxhYm9yQ29zdCgpLCAkcmVnY29sLCAnbGVmdCcpIC4gcGFkU3RyaW5nKCR0aGlzLT5nZXRBdmVyYWdlQ29mZmVlQ29uc3VtcHRpb24oKSwgJHJlZ2NvbCwgJ2xlZnQnKSAuIHBhZFN0cmluZygkdGhpcy0+Z2V0QXZlcmFnZVBhcGVyd29ya1Byb2R1Y2VkKCksICRyZWdjb2wsICdsZWZ0JykgLiBwYWRTdHJpbmcoJHRoaXMtPmdldEF2ZXJhZ2VDb3N0UGVyUGFnZSgpLCAkcmVnY29sLCAnbGVmdCcpIC4gIlxuIjsKCX0KfQoKY2xhc3MgRGVwYXJ0bWVudCB7Cglwcm90ZWN0ZWQgc3RyaW5nICRuYW1lOwoJcHJvdGVjdGVkIGFycmF5ICRzdGFmZjsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoJG5hbWUpIHsKCQkkdGhpcy0+bmFtZSA9ICRuYW1lOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXROYW1lKCkgewoJCXJldHVybiAkdGhpcy0+bmFtZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gYWRkVG9TdGFmZihFbXBsb3llZSAkZW1wbG95ZWUpIHsKCQkkdGhpcy0+c3RhZmZbXSA9ICRlbXBsb3llZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0U3RhZmZOdW1iZXIoKSB7CgkJcmV0dXJuIGNvdW50KCR0aGlzLT5zdGFmZik7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldExhYm9yQ29zdCgpIHsKCQkkbGFib3JDb3N0ID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+c3RhZmYgYXMgJGVtcGxveWVlKSB7CgkJCSRsYWJvckNvc3QgKz0gJGVtcGxveWVlLT5nZXRBY3R1YWxQYXkoKTsKCQl9CgkJcmV0dXJuICRsYWJvckNvc3Q7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldENvZmZlZUNvbnN1bXB0aW9uKCkgewoJCSRjb2ZmZWUgPSAwOwoJCWZvcmVhY2ggKCR0aGlzLT5zdGFmZiBhcyAkZW1wbG95ZWUpIHsKCQkJJGNvZmZlZSArPSAkZW1wbG95ZWUtPmdldEFjdHVhbENvZmZlZUNvbnN1bXB0aW9uKCk7CgkJfQoJCXJldHVybiAkY29mZmVlOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRQYXBlcndvcmtQcm9kdWNlZCgpIHsKCQkkcGFwZXJ3b3JrID0gMDsKCQlmb3JlYWNoICgkdGhpcy0+c3RhZmYgYXMgJGVtcGxveWVlKSB7CgkJCSRwYXBlcndvcmsgKz0gJGVtcGxveWVlLT5nZXRBY3R1YWxQYXBlcndvcmtQcm9kdWNlZCgpOwoJCX0KCQlyZXR1cm4gJHBhcGVyd29yazsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0Q29zdFBlclBhZ2UoKSB7CgkJcmV0dXJuIHJvdW5kKCR0aGlzLT5nZXRMYWJvckNvc3QoKSAvICR0aGlzLT5nZXRQYXBlcndvcmtQcm9kdWNlZCgpLCAyKTsKCX0KCQp9CgphYnN0cmFjdCBjbGFzcyBFbXBsb3llZSB7Cgljb25zdCBNQU5BR0VSID0gIk1hbmFnZXIiOwoJY29uc3QgTUFSS0VURVIgPSAiTWFya2V0ZXIiOwoJY29uc3QgRU5HSU5FRVIgPSAiRW5naW5lZXIiOwoJY29uc3QgQU5BTFlTVCA9ICJBbmFseXN0IjsKCglwcm90ZWN0ZWQgaW50ICRncmFkZTsKCXByb3RlY3RlZCBib29sICRjaGllZjsKCglwdWJsaWMgZnVuY3Rpb24gX19jb25zdHJ1Y3QoaW50ICRncmFkZSwgYm9vbCAkY2hpZWYgPSBmYWxzZSkgewoJCSR0aGlzLT5ncmFkZSA9ICRncmFkZTsKCQkkdGhpcy0+Y2hpZWYgPSAkY2hpZWY7Cgl9CgkKCWFic3RyYWN0IHB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlUmF0ZSgpOwoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGdldEJhc2VDb2ZmZWVDb25zdW1wdGlvbigpOwoJYWJzdHJhY3QgcHVibGljIGZ1bmN0aW9uIGdldEJhc2VQYXBlcndvcmtQcm9kdWNlZCgpOwoKCXB1YmxpYyBmdW5jdGlvbiBnZXRBY3R1YWxQYXkoKSB7CgkJJHJhdGUgPSAkdGhpcy0+Z2V0QmFzZVJhdGUoKTsKCQlpZiAoJHRoaXMtPmdyYWRlID09IDIpIHsKCQkJJHJhdGUgKj0gMS4yNTsKCQl9IGVsc2VpZiAoJHRoaXMtPmdyYWRlID09IDMpIHsKCQkJJHJhdGUgPSAkcmF0ZSAqIDEuNTsKCQl9CgoJCXJldHVybiAkdGhpcy0+Y2hpZWYgPyAkcmF0ZSAqIDIgOiAkcmF0ZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QWN0dWFsQ29mZmVlQ29uc3VtcHRpb24oKSB7CgkJcmV0dXJuICR0aGlzLT5jaGllZiA/ICR0aGlzLT5nZXRCYXNlQ29mZmVlQ29uc3VtcHRpb24oKSAqIDIgOiAkdGhpcy0+Z2V0QmFzZUNvZmZlZUNvbnN1bXB0aW9uKCk7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEFjdHVhbFBhcGVyd29ya1Byb2R1Y2VkKCk6IGludCB7CgkJcmV0dXJuICR0aGlzLT5jaGllZiA/IDAgOiAkdGhpcy0+Z2V0QmFzZVBhcGVyd29ya1Byb2R1Y2VkKCk7CQoJfQp9CgpjbGFzcyBNYW5hZ2VyIGV4dGVuZHMgRW1wbG95ZWUgewoJcHJvdGVjdGVkICRiYXNlUmF0ZSA9IDUwMDsKCXByb3RlY3RlZCAkYmFzZUNvZmZlZUNvbnN1bXB0aW9uID0gMjA7Cglwcm90ZWN0ZWQgaW50ICRiYXNlUGFwZXJ3b3JrUHJvZHVjZWQgPSAyMDA7CgoJcHVibGljIGZ1bmN0aW9uIGdldEJhc2VSYXRlKCkgewoJCXJldHVybiAkdGhpcy0+YmFzZVJhdGU7Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEJhc2VDb2ZmZWVDb25zdW1wdGlvbigpIHsKCQlyZXR1cm4gJHRoaXMtPmJhc2VDb2ZmZWVDb25zdW1wdGlvbjsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QmFzZVBhcGVyd29ya1Byb2R1Y2VkKCkgewoJCXJldHVybiAkdGhpcy0+YmFzZVBhcGVyd29ya1Byb2R1Y2VkOwoJfQp9CgpjbGFzcyBNYXJrZXRlciBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSA0MDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDE1OwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gMTUwOwoKCXB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlUmF0ZSgpIHsKCQlyZXR1cm4gJHRoaXMtPmJhc2VSYXRlOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlQ29mZmVlQ29uc3VtcHRpb24oKSB7CgkJcmV0dXJuICR0aGlzLT5iYXNlQ29mZmVlQ29uc3VtcHRpb247Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEJhc2VQYXBlcndvcmtQcm9kdWNlZCgpIHsKCQlyZXR1cm4gJHRoaXMtPmJhc2VQYXBlcndvcmtQcm9kdWNlZDsKCX0KfQoKY2xhc3MgRW5naW5lZXIgZXh0ZW5kcyBFbXBsb3llZSB7Cglwcm90ZWN0ZWQgJGJhc2VSYXRlID0gMjAwOwoJcHJvdGVjdGVkICRiYXNlQ29mZmVlQ29uc3VtcHRpb24gPSA1OwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gNTA7CgkKCXB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlUmF0ZSgpIHsKCQlyZXR1cm4gJHRoaXMtPmJhc2VSYXRlOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlQ29mZmVlQ29uc3VtcHRpb24oKSB7CgkJcmV0dXJuICR0aGlzLT5iYXNlQ29mZmVlQ29uc3VtcHRpb247Cgl9CgoJcHVibGljIGZ1bmN0aW9uIGdldEJhc2VQYXBlcndvcmtQcm9kdWNlZCgpIHsKCQlyZXR1cm4gJHRoaXMtPmJhc2VQYXBlcndvcmtQcm9kdWNlZDsKCX0KfQoKY2xhc3MgQW5hbHlzdCBleHRlbmRzIEVtcGxveWVlIHsKCXByb3RlY3RlZCAkYmFzZVJhdGUgPSA4MDA7Cglwcm90ZWN0ZWQgJGJhc2VDb2ZmZWVDb25zdW1wdGlvbiA9IDUwOwoJcHJvdGVjdGVkIGludCAkYmFzZVBhcGVyd29ya1Byb2R1Y2VkID0gNTsKCglwdWJsaWMgZnVuY3Rpb24gZ2V0QmFzZVJhdGUoKSB7CgkJcmV0dXJuICR0aGlzLT5iYXNlUmF0ZTsKCX0KCglwdWJsaWMgZnVuY3Rpb24gZ2V0QmFzZUNvZmZlZUNvbnN1bXB0aW9uKCkgewoJCXJldHVybiAkdGhpcy0+YmFzZUNvZmZlZUNvbnN1bXB0aW9uOwoJfQoKCXB1YmxpYyBmdW5jdGlvbiBnZXRCYXNlUGFwZXJ3b3JrUHJvZHVjZWQoKSB7CgkJcmV0dXJuICR0aGlzLT5iYXNlUGFwZXJ3b3JrUHJvZHVjZWQ7Cgl9Cn0KCi8qKgogKiBpbnB1dC5waHAKICovCgokaW5wdXQgPSBbCgknUHVyY2hhc2luZycgPT4gWwoJCVs5LCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzMsIEVtcGxveWVlOjpNQU5BR0VSLCAyXSwKCQlbMiwgRW1wbG95ZWU6Ok1BTkFHRVIsIDNdLAoJCVsyLCBFbXBsb3llZTo6TUFSS0VURVIsIDFdLAoJCVsxLCBFbXBsb3llZTo6TUFOQUdFUiwgMiwgdHJ1ZV0KCV0sCgoJJ1NhbGVzJyA9PiBbCgkJWzEyLCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzYsIEVtcGxveWVlOjpNQVJLRVRFUiwgMV0sCgkJWzMsIEVtcGxveWVlOjpBTkFMWVNULCAxXSwKCQlbMiwgRW1wbG95ZWU6OkFOQUxZU1QsIDJdLAoJCVsxLCBFbXBsb3llZTo6TUFSS0VURVIsIDIsIHRydWVdCgldLAoKCgknQWR2ZXJ0aXNpbmcnID0+IFsKCQlbMTUsIEVtcGxveWVlOjpNQVJLRVRFUiwgMV0sCgkJWzEwLCBFbXBsb3llZTo6TUFSS0VURVIsIDJdLAoJCVs4LCBFbXBsb3llZTo6TUFOQUdFUiwgMV0sCgkJWzIsIEVtcGxveWVlOjpFTkdJTkVFUiwgMV0sCgkJWzEsIEVtcGxveWVlOjpNQVJLRVRFUiwgMywgdHJ1ZV0KCV0sCgoKCSdMb2dpc3RpY3MnID0+IFsKCQlbMTMsIEVtcGxveWVlOjpNQU5BR0VSLCAxXSwKCQlbNSwgRW1wbG95ZWU6Ok1BTkFHRVIsIDJdLAoJCVs1LCBFbXBsb3llZTo6RU5HSU5FRVIsIDFdLAoJCVsxLCBFbXBsb3llZTo6TUFOQUdFUiwgMSwgdHJ1ZV0KCV0KCl07CgovKioKICogcGFkc3RyaW5nLnBocAogKi8KCmZ1bmN0aW9uIHBhZFN0cmluZygkc3RyaW5nLCAkbGVuZ3RoLCAkc2lkZSA9ICJyaWdodCIsICRwYWQgPSAiICIpIHsKCWlmIChzdHJsZW4oJHN0cmluZykgPT0gJGxlbmd0aCkgewoJCXJldHVybiAkc3RyaW5nOwoJfSBlbHNlIHsKCQkkY2hhcnNOZWVkZWQgPSAkbGVuZ3RoIC0gc3RybGVuKCRzdHJpbmcpOyAvLyA1CgkJJHBhZGRpbmcgPSBzdHJfcmVwZWF0KCRwYWQsICRjaGFyc05lZWRlZCk7CgkJKCRzaWRlID09ICJyaWdodCIpID8gKCRzdHJpbmcgPSAkc3RyaW5nIC4gJHBhZGRpbmcpIDogKCRzdHJpbmcgPSAkcGFkZGluZyAuICRzdHJpbmcpOwoJCXJldHVybiAkc3RyaW5nOwoJfQp9CgovKioKICogbWFpbi5waHAKICovCiAKIGZ1bmN0aW9uIG1ha2VEZXB0cyhhcnJheSAkaW5wdXQpOiBhcnJheSB7CgkkZGVwdHMgPSBbXTsKCWZvcmVhY2ggKCRpbnB1dCBhcyAkZGVwdCA9PiAkc3RhZmYpIHsKCQkkY3VycmVudERlcHQgPSBuZXcgRGVwYXJ0bWVudCgkZGVwdCk7CgkJZm9yZWFjaCAoJHN0YWZmIGFzICRlbXBsb3llZUdyb3VwKSB7CgkJCSRxdWFudGl0eSA9ICRlbXBsb3llZUdyb3VwWzBdOwoJCQkkdHlwZSA9ICRlbXBsb3llZUdyb3VwWzFdOwoJCQkkZ3JhZGUgPSAkZW1wbG95ZWVHcm91cFsyXTsKCQkJJGNoaWVmID0gaXNzZXQoJGVtcGxveWVlR3JvdXBbM10pID8gdHJ1ZSA6IGZhbHNlOwoJCQlmb3IgKCRjID0gMDsgJGMgPCAkcXVhbnRpdHk7ICRjKyspIHsKCQkJCSRlbXBsb3llZU9iamVjdCA9IG5ldyAkdHlwZSgkZ3JhZGUsICRjaGllZik7CgkJCQkkY3VycmVudERlcHQtPmFkZFRvU3RhZmYoJGVtcGxveWVlT2JqZWN0KTsKCQkJfQoJCX0KCQkkZGVwdHNbXSA9ICRjdXJyZW50RGVwdDsKCX0KCXJldHVybiAkZGVwdHM7Cn0KCiRkZXB0cyA9IG1ha2VEZXB0cygkaW5wdXQpOwokY29tcGFueSA9IG5ldyBDb21wYW55KCRkZXB0cyk7CgokY29tcGFueS0+cHJpbnRSZXBvcnQoKTs=