//********************************************************
//
// Assignment 8 - Structures and Strings and Pointers
//
// Name: Tim Ticknor
//
// Class: C Programming, Fall, 2024
//
// Date: 11/10/24
//
// Description: Program which determines overtime and
// gross pay for a set of employees with outputs sent
// to standard output (the screen).
//
// This assignment also adds the employee name, their tax state,
// and calculates the state tax, federal tax, and net pay. It
// also calculates totals, averages, minimum, and maximum values.
//
// Array and Structure references are to be replaced with
// pointer references to speed up the processing of this code.
//
// Call by Reference design (using pointers)
//
//********************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <float.h> // For FLT_MAX
// Define constants
#define SIZE 5
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define MA_TAX_RATE 0.05
#define NH_TAX_RATE 0.0
#define VT_TAX_RATE 0.06
#define CA_TAX_RATE 0.07
#define DEFAULT_TAX_RATE 0.08
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
#define TAX_STATE_SIZE 3
#define FED_TAX_RATE 0.25
// Define a structure type to store an employee name
struct name {
char firstName[FIRST_NAME_SIZE];
char lastName [LAST_NAME_SIZE];
};
// Define a structure type to store employee data
struct employee {
struct name empName;
char taxState [TAX_STATE_SIZE];
long int clockNumber;
float wageRate;
float hours;
float overtimeHrs;
float grossPay;
float stateTax;
float fedTax;
float netPay;
};
// This structure type defines the totals of all floating point items
struct totals {
float total_wageRate;
float total_hours;
float total_overtimeHrs;
float total_grossPay;
float total_stateTax;
float total_fedTax;
float total_netPay;
};
// This structure type defines the min and max values for employee data
struct min_max {
float min_wageRate;
float min_hours;
float min_overtimeHrs;
float min_grossPay;
float min_stateTax;
float min_fedTax;
float min_netPay;
float max_wageRate;
float max_hours;
float max_overtimeHrs;
float max_grossPay;
float max_stateTax;
float max_fedTax;
float max_netPay;
};
// Function prototypes
void getHours(struct employee *emp_ptr, int theSize);
void printEmp(struct employee *emp_ptr, int theSize);
void calcEmployeeTotals(struct employee *emp_ptr, struct totals *emp_totals_ptr, int theSize);
void calcEmployeeMinMax(struct employee *emp_ptr, struct min_max *emp_MinMax_ptr, int theSize);
void printHeader(void);
void calcOvertimeHrs(struct employee *emp_ptr, int theSize);
void calcGrossPay(struct employee *emp_ptr, int theSize);
void calcStateTax(struct employee *emp_ptr, int theSize);
void calcFedTax(struct employee *emp_ptr, int theSize);
void calcNetPay(struct employee *emp_ptr, int theSize);
void printEmpStatistics(struct totals *emp_totals_ptr, struct min_max *emp_MinMax_ptr, int theSize);
int main() {
// Set up a local variable to store the employee information
struct employee employeeData[SIZE] = {
{ {"Connie", "Cobol"}, "MA", 98401, 10.60},
{ {"Mary", "Apl"}, "NH", 526488, 9.75 },
{ {"Frank", "Fortran"}, "VT", 765349, 10.50 },
{ {"Jeff", "Ada"}, "NY", 34645, 12.25 },
{ {"Anton", "Pascal"},"CA",127615, 8.35 }
};
// Declare a pointer to the array of employee structures
struct employee *emp_ptr = employeeData;
// Set up structure to store totals and initialize all to zero
struct totals employeeTotals = {0, 0, 0, 0, 0, 0, 0};
struct totals *emp_totals_ptr = &employeeTotals;
// Set up structure to store min and max values and initialize all to zero or appropriate extreme values
struct min_max employeeMinMax = {
FLT_MAX, // min_wageRate
FLT_MAX, // min_hours
FLT_MAX, // min_overtimeHrs
FLT_MAX, // min_grossPay
FLT_MAX, // min_stateTax
FLT_MAX, // min_fedTax
FLT_MAX, // min_netPay
0.0, // max_wageRate
0.0, // max_hours
0.0, // max_overtimeHrs
0.0, // max_grossPay
0.0, // max_stateTax
0.0, // max_fedTax
0.0 // max_netPay
};
struct min_max *emp_minMax_ptr = &employeeMinMax;
// Call functions as needed to read and calculate information
getHours(emp_ptr, SIZE);
calcOvertimeHrs(emp_ptr, SIZE);
calcGrossPay(emp_ptr, SIZE);
calcStateTax(emp_ptr, SIZE);
calcFedTax(emp_ptr, SIZE);
calcNetPay(emp_ptr, SIZE);
calcEmployeeTotals(emp_ptr, emp_totals_ptr, SIZE);
calcEmployeeMinMax(emp_ptr, emp_minMax_ptr, SIZE);
// Print the column headers
printHeader();
// Print out final information on each employee
printEmp(emp_ptr, SIZE);
// Print the totals and averages for all float items
printEmpStatistics(emp_totals_ptr, emp_minMax_ptr, SIZE);
return 0;
}
// Function Definitions
// Function to get hours worked from user input
void getHours(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
printf("Enter hours worked for %s %s (Employee #%ld): ", emp_ptr
[i
].
empName.
firstName, emp_ptr
[i
].
empName.
lastName, emp_ptr
[i
].
clockNumber); if (scanf("%f", &emp_ptr
[i
].
hours) != 1) { printf("Invalid input. Please enter a valid number for hours.\n"); i--; // Decrement the counter to retry the input for this employee
}
}
}
// Function to calculate overtime hours
void calcOvertimeHrs(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
if (emp_ptr[i].hours > STD_HOURS) {
emp_ptr[i].overtimeHrs = emp_ptr[i].hours - STD_HOURS;
} else {
emp_ptr[i].overtimeHrs = 0.0;
}
}
}
// Function to calculate gross pay
void calcGrossPay(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
if (emp_ptr[i].hours <= STD_HOURS) {
emp_ptr[i].grossPay = emp_ptr[i].wageRate * emp_ptr[i].hours;
} else {
emp_ptr[i].grossPay = (STD_HOURS * emp_ptr[i].wageRate) + (emp_ptr[i].overtimeHrs * emp_ptr[i].wageRate * OT_RATE);
}
}
}
// Function to calculate state tax
void calcStateTax(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
if (strcmp(emp_ptr
[i
].
taxState, "MA") == 0) { emp_ptr[i].stateTax = emp_ptr[i].grossPay * MA_TAX_RATE;
} else if (strcmp(emp_ptr
[i
].
taxState, "NH") == 0) { emp_ptr[i].stateTax = emp_ptr[i].grossPay * NH_TAX_RATE;
} else if (strcmp(emp_ptr
[i
].
taxState, "VT") == 0) { emp_ptr[i].stateTax = emp_ptr[i].grossPay * VT_TAX_RATE;
} else if (strcmp(emp_ptr
[i
].
taxState, "CA") == 0) { emp_ptr[i].stateTax = emp_ptr[i].grossPay * CA_TAX_RATE;
} else {
emp_ptr[i].stateTax = emp_ptr[i].grossPay * DEFAULT_TAX_RATE;
}
}
}
// Function to calculate federal tax
void calcFedTax(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
emp_ptr[i].fedTax = emp_ptr[i].grossPay * FED_TAX_RATE;
}
}
// Function to calculate net pay
void calcNetPay(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
emp_ptr[i].netPay = emp_ptr[i].grossPay - emp_ptr[i].stateTax - emp_ptr[i].fedTax;
}
}
// Function to calculate totals
void calcEmployeeTotals(struct employee *emp_ptr, struct totals *emp_totals_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
emp_totals_ptr->total_wageRate += emp_ptr[i].wageRate;
emp_totals_ptr->total_hours += emp_ptr[i].hours;
emp_totals_ptr->total_overtimeHrs += emp_ptr[i].overtimeHrs;
emp_totals_ptr->total_grossPay += emp_ptr[i].grossPay;
emp_totals_ptr->total_stateTax += emp_ptr[i].stateTax;
emp_totals_ptr->total_fedTax += emp_ptr[i].fedTax;
emp_totals_ptr->total_netPay += emp_ptr[i].netPay;
}
}
// Function to calculate min and max values for each item
void calcEmployeeMinMax(struct employee *emp_ptr, struct min_max *emp_MinMax_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
if (emp_ptr[i].wageRate < emp_MinMax_ptr->min_wageRate) emp_MinMax_ptr->min_wageRate = emp_ptr[i].wageRate;
if (emp_ptr[i].wageRate > emp_MinMax_ptr->max_wageRate) emp_MinMax_ptr->max_wageRate = emp_ptr[i].wageRate;
if (emp_ptr[i].hours < emp_MinMax_ptr->min_hours) emp_MinMax_ptr->min_hours = emp_ptr[i].hours;
if (emp_ptr[i].hours > emp_MinMax_ptr->max_hours) emp_MinMax_ptr->max_hours = emp_ptr[i].hours;
if (emp_ptr[i].overtimeHrs < emp_MinMax_ptr->min_overtimeHrs) emp_MinMax_ptr->min_overtimeHrs = emp_ptr[i].overtimeHrs;
if (emp_ptr[i].overtimeHrs > emp_MinMax_ptr->max_overtimeHrs) emp_MinMax_ptr->max_overtimeHrs = emp_ptr[i].overtimeHrs;
if (emp_ptr[i].grossPay < emp_MinMax_ptr->min_grossPay) emp_MinMax_ptr->min_grossPay = emp_ptr[i].grossPay;
if (emp_ptr[i].grossPay > emp_MinMax_ptr->max_grossPay) emp_MinMax_ptr->max_grossPay = emp_ptr[i].grossPay;
if (emp_ptr[i].stateTax < emp_MinMax_ptr->min_stateTax) emp_MinMax_ptr->min_stateTax = emp_ptr[i].stateTax;
if (emp_ptr[i].stateTax > emp_MinMax_ptr->max_stateTax) emp_MinMax_ptr->max_stateTax = emp_ptr[i].stateTax;
if (emp_ptr[i].fedTax < emp_MinMax_ptr->min_fedTax) emp_MinMax_ptr->min_fedTax = emp_ptr[i].fedTax;
if (emp_ptr[i].fedTax > emp_MinMax_ptr->max_fedTax) emp_MinMax_ptr->max_fedTax = emp_ptr[i].fedTax;
if (emp_ptr[i].netPay < emp_MinMax_ptr->min_netPay) emp_MinMax_ptr->min_netPay = emp_ptr[i].netPay;
if (emp_ptr[i].netPay > emp_MinMax_ptr->max_netPay) emp_MinMax_ptr->max_netPay = emp_ptr[i].netPay;
}
}
// Function to print the header for output
void printHeader(void) {
printf("\n%-20s %-4s %-7s %-5s %-5s %-3s %-6s %-6s %-6s %-6s\n", "Name", "Tax", "Clock#", "Wage", "Hours", "OT", "Gross", "State", "Fed", "Net"); printf("----------------------------------------------------------------------------------------\n"); }
// Function to print employee data
void printEmp(struct employee *emp_ptr, int theSize) {
for (int i = 0; i < theSize; i++) {
printf("%-20s %-4s %-7ld %-5.2f %-5.1f %-3.1f %-6.2f %-6.2f %-6.2f %-6.2f\n", emp_ptr[i].empName.firstName, emp_ptr[i].empName.lastName, emp_ptr[i].clockNumber,
emp_ptr[i].wageRate, emp_ptr[i].hours, emp_ptr[i].overtimeHrs, emp_ptr[i].grossPay,
emp_ptr[i].stateTax, emp_ptr[i].fedTax, emp_ptr[i].netPay);
}
}
// Function to print total, averages, min and max values
void printEmpStatistics(struct totals *emp_totals_ptr, struct min_max *emp_MinMax_ptr, int theSize) {
printf("Wage: %.2f Hours: %.1f OT: %.1f Gross: %.2f State: %.2f Fed: %.2f Net: %.2f\n", emp_totals_ptr->total_wageRate, emp_totals_ptr->total_hours, emp_totals_ptr->total_overtimeHrs,
emp_totals_ptr->total_grossPay, emp_totals_ptr->total_stateTax, emp_totals_ptr->total_fedTax,
emp_totals_ptr->total_netPay);
printf("Wage: %.2f Hours: %.1f OT: %.1f Gross: %.2f State: %.2f Fed: %.2f Net: %.2f\n", emp_totals_ptr->total_wageRate / theSize,
emp_totals_ptr->total_hours / theSize,
emp_totals_ptr->total_overtimeHrs / theSize,
emp_totals_ptr->total_grossPay / theSize,
emp_totals_ptr->total_stateTax / theSize,
emp_totals_ptr->total_fedTax / theSize,
emp_totals_ptr->total_netPay / theSize);
printf("Wage: %.2f Hours: %.1f OT: %.1f Gross: %.2f State: %.2f Fed: %.2f Net: %.2f\n", emp_MinMax_ptr->min_wageRate, emp_MinMax_ptr->min_hours, emp_MinMax_ptr->min_overtimeHrs,
emp_MinMax_ptr->min_grossPay, emp_MinMax_ptr->min_stateTax, emp_MinMax_ptr->min_fedTax,
emp_MinMax_ptr->min_netPay);
printf("Wage: %.2f Hours: %.1f OT: %.1f Gross: %.2f State: %.2f Fed: %.2f Net: %.2f\n", emp_MinMax_ptr->max_wageRate, emp_MinMax_ptr->max_hours, emp_MinMax_ptr->max_overtimeHrs,
emp_MinMax_ptr->max_grossPay, emp_MinMax_ptr->max_stateTax, emp_MinMax_ptr->max_fedTax,
emp_MinMax_ptr->max_netPay);
}
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDggLSBTdHJ1Y3R1cmVzIGFuZCBTdHJpbmdzIGFuZCBQb2ludGVycwovLwovLyBOYW1lOiBUaW0gVGlja25vcgovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgRmFsbCwgMjAyNAovLwovLyBEYXRlOiAxMS8xMC8yNAovLwovLyBEZXNjcmlwdGlvbjogUHJvZ3JhbSB3aGljaCBkZXRlcm1pbmVzIG92ZXJ0aW1lIGFuZCAKLy8gZ3Jvc3MgcGF5IGZvciBhIHNldCBvZiBlbXBsb3llZXMgd2l0aCBvdXRwdXRzIHNlbnQgCi8vIHRvIHN0YW5kYXJkIG91dHB1dCAodGhlIHNjcmVlbikuCi8vCi8vIFRoaXMgYXNzaWdubWVudCBhbHNvIGFkZHMgdGhlIGVtcGxveWVlIG5hbWUsIHRoZWlyIHRheCBzdGF0ZSwKLy8gYW5kIGNhbGN1bGF0ZXMgdGhlIHN0YXRlIHRheCwgZmVkZXJhbCB0YXgsIGFuZCBuZXQgcGF5LiAgIEl0Ci8vIGFsc28gY2FsY3VsYXRlcyB0b3RhbHMsIGF2ZXJhZ2VzLCBtaW5pbXVtLCBhbmQgbWF4aW11bSB2YWx1ZXMuCi8vCi8vIEFycmF5IGFuZCBTdHJ1Y3R1cmUgcmVmZXJlbmNlcyBhcmUgdG8gYmUgcmVwbGFjZWQgd2l0aAovLyBwb2ludGVyIHJlZmVyZW5jZXMgdG8gc3BlZWQgdXAgdGhlIHByb2Nlc3Npbmcgb2YgdGhpcyBjb2RlLgovLwovLyBDYWxsIGJ5IFJlZmVyZW5jZSBkZXNpZ24gKHVzaW5nIHBvaW50ZXJzKQovLwovLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8ZmxvYXQuaD4gIC8vIEZvciBGTFRfTUFYCgovLyBEZWZpbmUgY29uc3RhbnRzCiNkZWZpbmUgU0laRSA1CiNkZWZpbmUgU1REX0hPVVJTIDQwLjAKI2RlZmluZSBPVF9SQVRFIDEuNQojZGVmaW5lIE1BX1RBWF9SQVRFIDAuMDUKI2RlZmluZSBOSF9UQVhfUkFURSAwLjAKI2RlZmluZSBWVF9UQVhfUkFURSAwLjA2CiNkZWZpbmUgQ0FfVEFYX1JBVEUgMC4wNwojZGVmaW5lIERFRkFVTFRfVEFYX1JBVEUgMC4wOAojZGVmaW5lIEZJUlNUX05BTUVfU0laRSAxMAojZGVmaW5lIExBU1RfTkFNRV9TSVpFIDEwCiNkZWZpbmUgVEFYX1NUQVRFX1NJWkUgMwojZGVmaW5lIEZFRF9UQVhfUkFURSAwLjI1CgovLyBEZWZpbmUgYSBzdHJ1Y3R1cmUgdHlwZSB0byBzdG9yZSBhbiBlbXBsb3llZSBuYW1lCnN0cnVjdCBuYW1lIHsKICAgIGNoYXIgZmlyc3ROYW1lW0ZJUlNUX05BTUVfU0laRV07CiAgICBjaGFyIGxhc3ROYW1lIFtMQVNUX05BTUVfU0laRV07Cn07CgovLyBEZWZpbmUgYSBzdHJ1Y3R1cmUgdHlwZSB0byBzdG9yZSBlbXBsb3llZSBkYXRhCnN0cnVjdCBlbXBsb3llZSB7CiAgICBzdHJ1Y3QgbmFtZSBlbXBOYW1lOwogICAgY2hhciB0YXhTdGF0ZSBbVEFYX1NUQVRFX1NJWkVdOwogICAgbG9uZyBpbnQgY2xvY2tOdW1iZXI7CiAgICBmbG9hdCB3YWdlUmF0ZTsKICAgIGZsb2F0IGhvdXJzOwogICAgZmxvYXQgb3ZlcnRpbWVIcnM7CiAgICBmbG9hdCBncm9zc1BheTsKICAgIGZsb2F0IHN0YXRlVGF4OwogICAgZmxvYXQgZmVkVGF4OwogICAgZmxvYXQgbmV0UGF5Owp9OwoKLy8gVGhpcyBzdHJ1Y3R1cmUgdHlwZSBkZWZpbmVzIHRoZSB0b3RhbHMgb2YgYWxsIGZsb2F0aW5nIHBvaW50IGl0ZW1zCnN0cnVjdCB0b3RhbHMgewogICAgZmxvYXQgdG90YWxfd2FnZVJhdGU7CiAgICBmbG9hdCB0b3RhbF9ob3VyczsKICAgIGZsb2F0IHRvdGFsX292ZXJ0aW1lSHJzOwogICAgZmxvYXQgdG90YWxfZ3Jvc3NQYXk7CiAgICBmbG9hdCB0b3RhbF9zdGF0ZVRheDsKICAgIGZsb2F0IHRvdGFsX2ZlZFRheDsKICAgIGZsb2F0IHRvdGFsX25ldFBheTsKfTsKCi8vIFRoaXMgc3RydWN0dXJlIHR5cGUgZGVmaW5lcyB0aGUgbWluIGFuZCBtYXggdmFsdWVzIGZvciBlbXBsb3llZSBkYXRhCnN0cnVjdCBtaW5fbWF4IHsKICAgIGZsb2F0IG1pbl93YWdlUmF0ZTsKICAgIGZsb2F0IG1pbl9ob3VyczsKICAgIGZsb2F0IG1pbl9vdmVydGltZUhyczsKICAgIGZsb2F0IG1pbl9ncm9zc1BheTsKICAgIGZsb2F0IG1pbl9zdGF0ZVRheDsKICAgIGZsb2F0IG1pbl9mZWRUYXg7CiAgICBmbG9hdCBtaW5fbmV0UGF5OwogICAgZmxvYXQgbWF4X3dhZ2VSYXRlOwogICAgZmxvYXQgbWF4X2hvdXJzOwogICAgZmxvYXQgbWF4X292ZXJ0aW1lSHJzOwogICAgZmxvYXQgbWF4X2dyb3NzUGF5OwogICAgZmxvYXQgbWF4X3N0YXRlVGF4OwogICAgZmxvYXQgbWF4X2ZlZFRheDsKICAgIGZsb2F0IG1heF9uZXRQYXk7Cn07CgovLyBGdW5jdGlvbiBwcm90b3R5cGVzCnZvaWQgZ2V0SG91cnMoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSk7CnZvaWQgcHJpbnRFbXAoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSk7CnZvaWQgY2FsY0VtcGxveWVlVG90YWxzKHN0cnVjdCBlbXBsb3llZSAqZW1wX3B0ciwgc3RydWN0IHRvdGFscyAqZW1wX3RvdGFsc19wdHIsIGludCB0aGVTaXplKTsKdm9pZCBjYWxjRW1wbG95ZWVNaW5NYXgoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBzdHJ1Y3QgbWluX21heCAqZW1wX01pbk1heF9wdHIsIGludCB0aGVTaXplKTsKdm9pZCBwcmludEhlYWRlcih2b2lkKTsKdm9pZCBjYWxjT3ZlcnRpbWVIcnMoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSk7CnZvaWQgY2FsY0dyb3NzUGF5KHN0cnVjdCBlbXBsb3llZSAqZW1wX3B0ciwgaW50IHRoZVNpemUpOwp2b2lkIGNhbGNTdGF0ZVRheChzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIGludCB0aGVTaXplKTsKdm9pZCBjYWxjRmVkVGF4KHN0cnVjdCBlbXBsb3llZSAqZW1wX3B0ciwgaW50IHRoZVNpemUpOwp2b2lkIGNhbGNOZXRQYXkoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSk7CnZvaWQgcHJpbnRFbXBTdGF0aXN0aWNzKHN0cnVjdCB0b3RhbHMgKmVtcF90b3RhbHNfcHRyLCBzdHJ1Y3QgbWluX21heCAqZW1wX01pbk1heF9wdHIsIGludCB0aGVTaXplKTsKCmludCBtYWluKCkgewogICAgLy8gU2V0IHVwIGEgbG9jYWwgdmFyaWFibGUgdG8gc3RvcmUgdGhlIGVtcGxveWVlIGluZm9ybWF0aW9uCiAgICBzdHJ1Y3QgZW1wbG95ZWUgZW1wbG95ZWVEYXRhW1NJWkVdID0gewogICAgICAgIHsgeyJDb25uaWUiLCAiQ29ib2wifSwgIk1BIiwgOTg0MDEsIDEwLjYwfSwKICAgICAgICB7IHsiTWFyeSIsICJBcGwifSwgIk5IIiwgNTI2NDg4LCA5Ljc1IH0sCiAgICAgICAgeyB7IkZyYW5rIiwgIkZvcnRyYW4ifSwgIlZUIiwgNzY1MzQ5LCAxMC41MCB9LAogICAgICAgIHsgeyJKZWZmIiwgIkFkYSJ9LCAiTlkiLCAzNDY0NSwgMTIuMjUgfSwKICAgICAgICB7IHsiQW50b24iLCAiUGFzY2FsIn0sIkNBIiwxMjc2MTUsIDguMzUgfQogICAgfTsKCiAgICAvLyBEZWNsYXJlIGEgcG9pbnRlciB0byB0aGUgYXJyYXkgb2YgZW1wbG95ZWUgc3RydWN0dXJlcwogICAgc3RydWN0IGVtcGxveWVlICplbXBfcHRyID0gZW1wbG95ZWVEYXRhOwoKICAgIC8vIFNldCB1cCBzdHJ1Y3R1cmUgdG8gc3RvcmUgdG90YWxzIGFuZCBpbml0aWFsaXplIGFsbCB0byB6ZXJvCiAgICBzdHJ1Y3QgdG90YWxzIGVtcGxveWVlVG90YWxzICA9IHswLCAwLCAwLCAwLCAwLCAwLCAwfTsKICAgIHN0cnVjdCB0b3RhbHMgKmVtcF90b3RhbHNfcHRyID0gJmVtcGxveWVlVG90YWxzOwoKICAgIC8vIFNldCB1cCBzdHJ1Y3R1cmUgdG8gc3RvcmUgbWluIGFuZCBtYXggdmFsdWVzIGFuZCBpbml0aWFsaXplIGFsbCB0byB6ZXJvIG9yIGFwcHJvcHJpYXRlIGV4dHJlbWUgdmFsdWVzCiAgICBzdHJ1Y3QgbWluX21heCBlbXBsb3llZU1pbk1heCA9IHsKICAgICAgICBGTFRfTUFYLCAgLy8gbWluX3dhZ2VSYXRlCiAgICAgICAgRkxUX01BWCwgIC8vIG1pbl9ob3VycwogICAgICAgIEZMVF9NQVgsICAvLyBtaW5fb3ZlcnRpbWVIcnMKICAgICAgICBGTFRfTUFYLCAgLy8gbWluX2dyb3NzUGF5CiAgICAgICAgRkxUX01BWCwgIC8vIG1pbl9zdGF0ZVRheAogICAgICAgIEZMVF9NQVgsICAvLyBtaW5fZmVkVGF4CiAgICAgICAgRkxUX01BWCwgIC8vIG1pbl9uZXRQYXkKICAgICAgICAwLjAsICAgICAgLy8gbWF4X3dhZ2VSYXRlCiAgICAgICAgMC4wLCAgICAgIC8vIG1heF9ob3VycwogICAgICAgIDAuMCwgICAgICAvLyBtYXhfb3ZlcnRpbWVIcnMKICAgICAgICAwLjAsICAgICAgLy8gbWF4X2dyb3NzUGF5CiAgICAgICAgMC4wLCAgICAgIC8vIG1heF9zdGF0ZVRheAogICAgICAgIDAuMCwgICAgICAvLyBtYXhfZmVkVGF4CiAgICAgICAgMC4wICAgICAgIC8vIG1heF9uZXRQYXkKICAgIH07CiAgICBzdHJ1Y3QgbWluX21heCAqZW1wX21pbk1heF9wdHIgPSAmZW1wbG95ZWVNaW5NYXg7CgogICAgLy8gQ2FsbCBmdW5jdGlvbnMgYXMgbmVlZGVkIHRvIHJlYWQgYW5kIGNhbGN1bGF0ZSBpbmZvcm1hdGlvbgogICAgZ2V0SG91cnMoZW1wX3B0ciwgU0laRSk7CiAgICBjYWxjT3ZlcnRpbWVIcnMoZW1wX3B0ciwgU0laRSk7CiAgICBjYWxjR3Jvc3NQYXkoZW1wX3B0ciwgU0laRSk7CiAgICBjYWxjU3RhdGVUYXgoZW1wX3B0ciwgU0laRSk7CiAgICBjYWxjRmVkVGF4KGVtcF9wdHIsIFNJWkUpOwogICAgY2FsY05ldFBheShlbXBfcHRyLCBTSVpFKTsKCiAgICBjYWxjRW1wbG95ZWVUb3RhbHMoZW1wX3B0ciwgZW1wX3RvdGFsc19wdHIsIFNJWkUpOwogICAgY2FsY0VtcGxveWVlTWluTWF4KGVtcF9wdHIsIGVtcF9taW5NYXhfcHRyLCBTSVpFKTsKCiAgICAvLyBQcmludCB0aGUgY29sdW1uIGhlYWRlcnMKICAgIHByaW50SGVhZGVyKCk7CgogICAgLy8gUHJpbnQgb3V0IGZpbmFsIGluZm9ybWF0aW9uIG9uIGVhY2ggZW1wbG95ZWUKICAgIHByaW50RW1wKGVtcF9wdHIsIFNJWkUpOwoKICAgIC8vIFByaW50IHRoZSB0b3RhbHMgYW5kIGF2ZXJhZ2VzIGZvciBhbGwgZmxvYXQgaXRlbXMKICAgIHByaW50RW1wU3RhdGlzdGljcyhlbXBfdG90YWxzX3B0ciwgZW1wX21pbk1heF9wdHIsIFNJWkUpOwoKICAgIHJldHVybiAwOwp9CgovLyBGdW5jdGlvbiBEZWZpbml0aW9ucwoKLy8gRnVuY3Rpb24gdG8gZ2V0IGhvdXJzIHdvcmtlZCBmcm9tIHVzZXIgaW5wdXQKdm9pZCBnZXRIb3VycyhzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIGludCB0aGVTaXplKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoZVNpemU7IGkrKykgewogICAgICAgIHByaW50ZigiRW50ZXIgaG91cnMgd29ya2VkIGZvciAlcyAlcyAoRW1wbG95ZWUgIyVsZCk6ICIsIGVtcF9wdHJbaV0uZW1wTmFtZS5maXJzdE5hbWUsIGVtcF9wdHJbaV0uZW1wTmFtZS5sYXN0TmFtZSwgZW1wX3B0cltpXS5jbG9ja051bWJlcik7CiAgICAgICAgaWYgKHNjYW5mKCIlZiIsICZlbXBfcHRyW2ldLmhvdXJzKSAhPSAxKSB7CiAgICAgICAgICAgIHByaW50ZigiSW52YWxpZCBpbnB1dC4gUGxlYXNlIGVudGVyIGEgdmFsaWQgbnVtYmVyIGZvciBob3Vycy5cbiIpOwogICAgICAgICAgICBpLS07ICAvLyBEZWNyZW1lbnQgdGhlIGNvdW50ZXIgdG8gcmV0cnkgdGhlIGlucHV0IGZvciB0aGlzIGVtcGxveWVlCiAgICAgICAgfQogICAgfQp9CgovLyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgb3ZlcnRpbWUgaG91cnMKdm9pZCBjYWxjT3ZlcnRpbWVIcnMoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGVTaXplOyBpKyspIHsKICAgICAgICBpZiAoZW1wX3B0cltpXS5ob3VycyA+IFNURF9IT1VSUykgewogICAgICAgICAgICBlbXBfcHRyW2ldLm92ZXJ0aW1lSHJzID0gZW1wX3B0cltpXS5ob3VycyAtIFNURF9IT1VSUzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBlbXBfcHRyW2ldLm92ZXJ0aW1lSHJzID0gMC4wOwogICAgICAgIH0KICAgIH0KfQoKLy8gRnVuY3Rpb24gdG8gY2FsY3VsYXRlIGdyb3NzIHBheQp2b2lkIGNhbGNHcm9zc1BheShzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIGludCB0aGVTaXplKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoZVNpemU7IGkrKykgewogICAgICAgIGlmIChlbXBfcHRyW2ldLmhvdXJzIDw9IFNURF9IT1VSUykgewogICAgICAgICAgICBlbXBfcHRyW2ldLmdyb3NzUGF5ID0gZW1wX3B0cltpXS53YWdlUmF0ZSAqIGVtcF9wdHJbaV0uaG91cnM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZW1wX3B0cltpXS5ncm9zc1BheSA9IChTVERfSE9VUlMgKiBlbXBfcHRyW2ldLndhZ2VSYXRlKSArIChlbXBfcHRyW2ldLm92ZXJ0aW1lSHJzICogZW1wX3B0cltpXS53YWdlUmF0ZSAqIE9UX1JBVEUpOwogICAgICAgIH0KICAgIH0KfQoKLy8gRnVuY3Rpb24gdG8gY2FsY3VsYXRlIHN0YXRlIHRheAp2b2lkIGNhbGNTdGF0ZVRheChzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIGludCB0aGVTaXplKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoZVNpemU7IGkrKykgewogICAgICAgIGlmIChzdHJjbXAoZW1wX3B0cltpXS50YXhTdGF0ZSwgIk1BIikgPT0gMCkgewogICAgICAgICAgICBlbXBfcHRyW2ldLnN0YXRlVGF4ID0gZW1wX3B0cltpXS5ncm9zc1BheSAqIE1BX1RBWF9SQVRFOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKGVtcF9wdHJbaV0udGF4U3RhdGUsICJOSCIpID09IDApIHsKICAgICAgICAgICAgZW1wX3B0cltpXS5zdGF0ZVRheCA9IGVtcF9wdHJbaV0uZ3Jvc3NQYXkgKiBOSF9UQVhfUkFURTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcChlbXBfcHRyW2ldLnRheFN0YXRlLCAiVlQiKSA9PSAwKSB7CiAgICAgICAgICAgIGVtcF9wdHJbaV0uc3RhdGVUYXggPSBlbXBfcHRyW2ldLmdyb3NzUGF5ICogVlRfVEFYX1JBVEU7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoZW1wX3B0cltpXS50YXhTdGF0ZSwgIkNBIikgPT0gMCkgewogICAgICAgICAgICBlbXBfcHRyW2ldLnN0YXRlVGF4ID0gZW1wX3B0cltpXS5ncm9zc1BheSAqIENBX1RBWF9SQVRFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVtcF9wdHJbaV0uc3RhdGVUYXggPSBlbXBfcHRyW2ldLmdyb3NzUGF5ICogREVGQVVMVF9UQVhfUkFURTsKICAgICAgICB9CiAgICB9Cn0KCi8vIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBmZWRlcmFsIHRheAp2b2lkIGNhbGNGZWRUYXgoc3RydWN0IGVtcGxveWVlICplbXBfcHRyLCBpbnQgdGhlU2l6ZSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGVTaXplOyBpKyspIHsKICAgICAgICBlbXBfcHRyW2ldLmZlZFRheCA9IGVtcF9wdHJbaV0uZ3Jvc3NQYXkgKiBGRURfVEFYX1JBVEU7CiAgICB9Cn0KCi8vIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBuZXQgcGF5CnZvaWQgY2FsY05ldFBheShzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIGludCB0aGVTaXplKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IHRoZVNpemU7IGkrKykgewogICAgICAgIGVtcF9wdHJbaV0ubmV0UGF5ID0gZW1wX3B0cltpXS5ncm9zc1BheSAtIGVtcF9wdHJbaV0uc3RhdGVUYXggLSBlbXBfcHRyW2ldLmZlZFRheDsKICAgIH0KfQoKLy8gRnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRvdGFscwp2b2lkIGNhbGNFbXBsb3llZVRvdGFscyhzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIHN0cnVjdCB0b3RhbHMgKmVtcF90b3RhbHNfcHRyLCBpbnQgdGhlU2l6ZSkgewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB0aGVTaXplOyBpKyspIHsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfd2FnZVJhdGUgKz0gZW1wX3B0cltpXS53YWdlUmF0ZTsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfaG91cnMgKz0gZW1wX3B0cltpXS5ob3VyczsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfb3ZlcnRpbWVIcnMgKz0gZW1wX3B0cltpXS5vdmVydGltZUhyczsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfZ3Jvc3NQYXkgKz0gZW1wX3B0cltpXS5ncm9zc1BheTsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfc3RhdGVUYXggKz0gZW1wX3B0cltpXS5zdGF0ZVRheDsKICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfZmVkVGF4ICs9IGVtcF9wdHJbaV0uZmVkVGF4OwogICAgICAgIGVtcF90b3RhbHNfcHRyLT50b3RhbF9uZXRQYXkgKz0gZW1wX3B0cltpXS5uZXRQYXk7CiAgICB9Cn0KCi8vIEZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSBtaW4gYW5kIG1heCB2YWx1ZXMgZm9yIGVhY2ggaXRlbQp2b2lkIGNhbGNFbXBsb3llZU1pbk1heChzdHJ1Y3QgZW1wbG95ZWUgKmVtcF9wdHIsIHN0cnVjdCBtaW5fbWF4ICplbXBfTWluTWF4X3B0ciwgaW50IHRoZVNpemUpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhlU2l6ZTsgaSsrKSB7CiAgICAgICAgaWYgKGVtcF9wdHJbaV0ud2FnZVJhdGUgPCBlbXBfTWluTWF4X3B0ci0+bWluX3dhZ2VSYXRlKSBlbXBfTWluTWF4X3B0ci0+bWluX3dhZ2VSYXRlID0gZW1wX3B0cltpXS53YWdlUmF0ZTsKICAgICAgICBpZiAoZW1wX3B0cltpXS53YWdlUmF0ZSA+IGVtcF9NaW5NYXhfcHRyLT5tYXhfd2FnZVJhdGUpIGVtcF9NaW5NYXhfcHRyLT5tYXhfd2FnZVJhdGUgPSBlbXBfcHRyW2ldLndhZ2VSYXRlOwoKICAgICAgICBpZiAoZW1wX3B0cltpXS5ob3VycyA8IGVtcF9NaW5NYXhfcHRyLT5taW5faG91cnMpIGVtcF9NaW5NYXhfcHRyLT5taW5faG91cnMgPSBlbXBfcHRyW2ldLmhvdXJzOwogICAgICAgIGlmIChlbXBfcHRyW2ldLmhvdXJzID4gZW1wX01pbk1heF9wdHItPm1heF9ob3VycykgZW1wX01pbk1heF9wdHItPm1heF9ob3VycyA9IGVtcF9wdHJbaV0uaG91cnM7CgogICAgICAgIGlmIChlbXBfcHRyW2ldLm92ZXJ0aW1lSHJzIDwgZW1wX01pbk1heF9wdHItPm1pbl9vdmVydGltZUhycykgZW1wX01pbk1heF9wdHItPm1pbl9vdmVydGltZUhycyA9IGVtcF9wdHJbaV0ub3ZlcnRpbWVIcnM7CiAgICAgICAgaWYgKGVtcF9wdHJbaV0ub3ZlcnRpbWVIcnMgPiBlbXBfTWluTWF4X3B0ci0+bWF4X292ZXJ0aW1lSHJzKSBlbXBfTWluTWF4X3B0ci0+bWF4X292ZXJ0aW1lSHJzID0gZW1wX3B0cltpXS5vdmVydGltZUhyczsKCiAgICAgICAgaWYgKGVtcF9wdHJbaV0uZ3Jvc3NQYXkgPCBlbXBfTWluTWF4X3B0ci0+bWluX2dyb3NzUGF5KSBlbXBfTWluTWF4X3B0ci0+bWluX2dyb3NzUGF5ID0gZW1wX3B0cltpXS5ncm9zc1BheTsKICAgICAgICBpZiAoZW1wX3B0cltpXS5ncm9zc1BheSA+IGVtcF9NaW5NYXhfcHRyLT5tYXhfZ3Jvc3NQYXkpIGVtcF9NaW5NYXhfcHRyLT5tYXhfZ3Jvc3NQYXkgPSBlbXBfcHRyW2ldLmdyb3NzUGF5OwoKICAgICAgICBpZiAoZW1wX3B0cltpXS5zdGF0ZVRheCA8IGVtcF9NaW5NYXhfcHRyLT5taW5fc3RhdGVUYXgpIGVtcF9NaW5NYXhfcHRyLT5taW5fc3RhdGVUYXggPSBlbXBfcHRyW2ldLnN0YXRlVGF4OwogICAgICAgIGlmIChlbXBfcHRyW2ldLnN0YXRlVGF4ID4gZW1wX01pbk1heF9wdHItPm1heF9zdGF0ZVRheCkgZW1wX01pbk1heF9wdHItPm1heF9zdGF0ZVRheCA9IGVtcF9wdHJbaV0uc3RhdGVUYXg7CgogICAgICAgIGlmIChlbXBfcHRyW2ldLmZlZFRheCA8IGVtcF9NaW5NYXhfcHRyLT5taW5fZmVkVGF4KSBlbXBfTWluTWF4X3B0ci0+bWluX2ZlZFRheCA9IGVtcF9wdHJbaV0uZmVkVGF4OwogICAgICAgIGlmIChlbXBfcHRyW2ldLmZlZFRheCA+IGVtcF9NaW5NYXhfcHRyLT5tYXhfZmVkVGF4KSBlbXBfTWluTWF4X3B0ci0+bWF4X2ZlZFRheCA9IGVtcF9wdHJbaV0uZmVkVGF4OwoKICAgICAgICBpZiAoZW1wX3B0cltpXS5uZXRQYXkgPCBlbXBfTWluTWF4X3B0ci0+bWluX25ldFBheSkgZW1wX01pbk1heF9wdHItPm1pbl9uZXRQYXkgPSBlbXBfcHRyW2ldLm5ldFBheTsKICAgICAgICBpZiAoZW1wX3B0cltpXS5uZXRQYXkgPiBlbXBfTWluTWF4X3B0ci0+bWF4X25ldFBheSkgZW1wX01pbk1heF9wdHItPm1heF9uZXRQYXkgPSBlbXBfcHRyW2ldLm5ldFBheTsKICAgIH0KfQoKLy8gRnVuY3Rpb24gdG8gcHJpbnQgdGhlIGhlYWRlciBmb3Igb3V0cHV0CnZvaWQgcHJpbnRIZWFkZXIodm9pZCkgewogICAgcHJpbnRmKCJcbiUtMjBzICUtNHMgJS03cyAlLTVzICUtNXMgJS0zcyAlLTZzICUtNnMgJS02cyAlLTZzXG4iLCAiTmFtZSIsICJUYXgiLCAiQ2xvY2sjIiwgIldhZ2UiLCAiSG91cnMiLCAiT1QiLCAiR3Jvc3MiLCAiU3RhdGUiLCAiRmVkIiwgIk5ldCIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKfQoKLy8gRnVuY3Rpb24gdG8gcHJpbnQgZW1wbG95ZWUgZGF0YQp2b2lkIHByaW50RW1wKHN0cnVjdCBlbXBsb3llZSAqZW1wX3B0ciwgaW50IHRoZVNpemUpIHsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgdGhlU2l6ZTsgaSsrKSB7CiAgICAgICAgcHJpbnRmKCIlLTIwcyAlLTRzICUtN2xkICUtNS4yZiAlLTUuMWYgJS0zLjFmICUtNi4yZiAlLTYuMmYgJS02LjJmICUtNi4yZlxuIiwKICAgICAgICAgICAgICAgZW1wX3B0cltpXS5lbXBOYW1lLmZpcnN0TmFtZSwgZW1wX3B0cltpXS5lbXBOYW1lLmxhc3ROYW1lLCBlbXBfcHRyW2ldLmNsb2NrTnVtYmVyLAogICAgICAgICAgICAgICBlbXBfcHRyW2ldLndhZ2VSYXRlLCBlbXBfcHRyW2ldLmhvdXJzLCBlbXBfcHRyW2ldLm92ZXJ0aW1lSHJzLCBlbXBfcHRyW2ldLmdyb3NzUGF5LAogICAgICAgICAgICAgICBlbXBfcHRyW2ldLnN0YXRlVGF4LCBlbXBfcHRyW2ldLmZlZFRheCwgZW1wX3B0cltpXS5uZXRQYXkpOwogICAgfQp9CgovLyBGdW5jdGlvbiB0byBwcmludCB0b3RhbCwgYXZlcmFnZXMsIG1pbiBhbmQgbWF4IHZhbHVlcwp2b2lkIHByaW50RW1wU3RhdGlzdGljcyhzdHJ1Y3QgdG90YWxzICplbXBfdG90YWxzX3B0ciwgc3RydWN0IG1pbl9tYXggKmVtcF9NaW5NYXhfcHRyLCBpbnQgdGhlU2l6ZSkgewogICAgcHJpbnRmKCJcblRvdGFsczpcbiIpOwogICAgcHJpbnRmKCJXYWdlOiAlLjJmICBIb3VyczogJS4xZiAgT1Q6ICUuMWYgIEdyb3NzOiAlLjJmICBTdGF0ZTogJS4yZiAgRmVkOiAlLjJmICBOZXQ6ICUuMmZcbiIsCiAgICAgICAgICAgZW1wX3RvdGFsc19wdHItPnRvdGFsX3dhZ2VSYXRlLCBlbXBfdG90YWxzX3B0ci0+dG90YWxfaG91cnMsIGVtcF90b3RhbHNfcHRyLT50b3RhbF9vdmVydGltZUhycywKICAgICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfZ3Jvc3NQYXksIGVtcF90b3RhbHNfcHRyLT50b3RhbF9zdGF0ZVRheCwgZW1wX3RvdGFsc19wdHItPnRvdGFsX2ZlZFRheCwKICAgICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfbmV0UGF5KTsKCiAgICBwcmludGYoIlxuQXZlcmFnZXM6XG4iKTsKICAgIHByaW50ZigiV2FnZTogJS4yZiAgSG91cnM6ICUuMWYgIE9UOiAlLjFmICBHcm9zczogJS4yZiAgU3RhdGU6ICUuMmYgIEZlZDogJS4yZiAgTmV0OiAlLjJmXG4iLAogICAgICAgICAgIGVtcF90b3RhbHNfcHRyLT50b3RhbF93YWdlUmF0ZSAvIHRoZVNpemUsCiAgICAgICAgICAgZW1wX3RvdGFsc19wdHItPnRvdGFsX2hvdXJzIC8gdGhlU2l6ZSwKICAgICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfb3ZlcnRpbWVIcnMgLyB0aGVTaXplLAogICAgICAgICAgIGVtcF90b3RhbHNfcHRyLT50b3RhbF9ncm9zc1BheSAvIHRoZVNpemUsCiAgICAgICAgICAgZW1wX3RvdGFsc19wdHItPnRvdGFsX3N0YXRlVGF4IC8gdGhlU2l6ZSwKICAgICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfZmVkVGF4IC8gdGhlU2l6ZSwKICAgICAgICAgICBlbXBfdG90YWxzX3B0ci0+dG90YWxfbmV0UGF5IC8gdGhlU2l6ZSk7CgogICAgcHJpbnRmKCJcbk1pbmltdW1zOlxuIik7CiAgICBwcmludGYoIldhZ2U6ICUuMmYgIEhvdXJzOiAlLjFmICBPVDogJS4xZiAgR3Jvc3M6ICUuMmYgIFN0YXRlOiAlLjJmICBGZWQ6ICUuMmYgIE5ldDogJS4yZlxuIiwKICAgICAgICAgICBlbXBfTWluTWF4X3B0ci0+bWluX3dhZ2VSYXRlLCBlbXBfTWluTWF4X3B0ci0+bWluX2hvdXJzLCBlbXBfTWluTWF4X3B0ci0+bWluX292ZXJ0aW1lSHJzLAogICAgICAgICAgIGVtcF9NaW5NYXhfcHRyLT5taW5fZ3Jvc3NQYXksIGVtcF9NaW5NYXhfcHRyLT5taW5fc3RhdGVUYXgsIGVtcF9NaW5NYXhfcHRyLT5taW5fZmVkVGF4LAogICAgICAgICAgIGVtcF9NaW5NYXhfcHRyLT5taW5fbmV0UGF5KTsKCiAgICBwcmludGYoIlxuTWF4aW11bXM6XG4iKTsKICAgIHByaW50ZigiV2FnZTogJS4yZiAgSG91cnM6ICUuMWYgIE9UOiAlLjFmICBHcm9zczogJS4yZiAgU3RhdGU6ICUuMmYgIEZlZDogJS4yZiAgTmV0OiAlLjJmXG4iLAogICAgICAgICAgIGVtcF9NaW5NYXhfcHRyLT5tYXhfd2FnZVJhdGUsIGVtcF9NaW5NYXhfcHRyLT5tYXhfaG91cnMsIGVtcF9NaW5NYXhfcHRyLT5tYXhfb3ZlcnRpbWVIcnMsCiAgICAgICAgICAgZW1wX01pbk1heF9wdHItPm1heF9ncm9zc1BheSwgZW1wX01pbk1heF9wdHItPm1heF9zdGF0ZVRheCwgZW1wX01pbk1heF9wdHItPm1heF9mZWRUYXgsCiAgICAgICAgICAgZW1wX01pbk1heF9wdHItPm1heF9uZXRQYXkpOwp9