//********************************************************
//
// Assignment 7 - Structures and Strings
//
// Name: John Semenuk
//
// Class: C Programming, Spring 2026
//
// Date: 29-Mar-2026
//
// Description: Program calculates overtime, gross pay, state & federal tax,
// net pay, and prints totals, averages, min/max values.
//
//********************************************************
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#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 FED_TAX_RATE 0.25
#define NAME_SIZE 20
#define TAX_STATE_SIZE 3
#define FIRST_NAME_SIZE 10
#define LAST_NAME_SIZE 10
struct name {
char firstName[FIRST_NAME_SIZE];
char lastName[LAST_NAME_SIZE];
};
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;
};
struct totals {
float total_wageRate;
float total_hours;
float total_overtimeHrs;
float total_grossPay;
float total_stateTax;
float total_fedTax;
float total_netPay;
};
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;
};
// Prototypes
float getHours(long int clockNumber);
float calcOvertimeHrs(float hours);
float calcGrossPay(float wageRate, float hours, float overtimeHrs);
void printHeader(void);
void printEmp(char firstName[], char lastName[], char taxState[], long int clockNumber,
float wageRate, float hours, float overtimeHrs, float grossPay,
float stateTax, float fedTax, float netPay);
float calcStateTax(float grossPay, char taxState[]);
float calcFedTax(float grossPay);
float calcNetPay(float grossPay, float stateTax, float fedTax);
struct totals calcEmployeeTotals(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct totals employeeTotals);
struct min_max calcEmployeeMinMax(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct min_max employeeMinMax,
int arrayIndex);
void printEmpStatistics(struct totals employeeTotals, struct min_max employeeMinMax, int theSize);
int main() {
int i;
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 }
};
struct totals employeeTotals = {0};
struct min_max employeeMinMax = {0};
for (i = 0; i < SIZE; ++i) {
employeeData[i].hours = getHours(employeeData[i].clockNumber);
employeeData[i].overtimeHrs = calcOvertimeHrs(employeeData[i].hours);
employeeData[i].grossPay = calcGrossPay(employeeData[i].wageRate, employeeData[i].hours, employeeData[i].overtimeHrs);
employeeData[i].stateTax = calcStateTax(employeeData[i].grossPay, employeeData[i].taxState);
employeeData[i].fedTax = calcFedTax(employeeData[i].grossPay);
employeeData[i].netPay = calcNetPay(employeeData[i].grossPay, employeeData[i].stateTax, employeeData[i].fedTax);
employeeTotals = calcEmployeeTotals(employeeData[i].wageRate, employeeData[i].hours, employeeData[i].overtimeHrs,
employeeData[i].grossPay, employeeData[i].stateTax,
employeeData[i].fedTax, employeeData[i].netPay, employeeTotals);
employeeMinMax = calcEmployeeMinMax(employeeData[i].wageRate, employeeData[i].hours, employeeData[i].overtimeHrs,
employeeData[i].grossPay, employeeData[i].stateTax,
employeeData[i].fedTax, employeeData[i].netPay,
employeeMinMax, i);
}
printHeader();
for (i = 0; i < SIZE; ++i) {
printEmp(employeeData[i].empName.firstName, employeeData[i].empName.lastName, employeeData[i].taxState,
employeeData[i].clockNumber, employeeData[i].wageRate, employeeData[i].hours,
employeeData[i].overtimeHrs, employeeData[i].grossPay, employeeData[i].stateTax,
employeeData[i].fedTax, employeeData[i].netPay);
}
printEmpStatistics(employeeTotals, employeeMinMax, SIZE);
return 0;
}
//**************************************************************
float getHours(long int clockNumber) {
float theHoursWorked;
printf("\nEnter hours worked by emp # %06li: ", clockNumber
); scanf("%f", &theHoursWorked
); return theHoursWorked;
}
void printHeader(void) {
printf("\n\n*** Pay Calculator ***\n"); printf("\n--------------------------------------------------------------"); printf("-------------------"); printf("\nName Tax Clock# Wage Hours OT Gross "); printf("\n--------------------------------------------------------------"); printf("-------------------"); }
void printEmp(char firstName[], char lastName[], char taxState[], long int clockNumber,
float wageRate, float hours, float overtimeHrs, float grossPay,
float stateTax, float fedTax, float netPay) {
char name[FIRST_NAME_SIZE + LAST_NAME_SIZE + 1];
printf("\n%-20.20s %-2.2s %06li %5.2f %4.1f %4.1f %7.2f %6.2f %7.2f %8.2f", name, taxState, clockNumber, wageRate, hours, overtimeHrs, grossPay, stateTax, fedTax, netPay);
}
float calcOvertimeHrs(float hours) {
return (hours > STD_HOURS) ? (hours - STD_HOURS) : 0;
}
float calcGrossPay(float wageRate, float hours, float overtimeHrs) {
float normalPay = wageRate * (hours - overtimeHrs);
float overtimePay = overtimeHrs * (OT_RATE * wageRate);
return normalPay + overtimePay;
}
float calcStateTax(float grossPay, char taxState[]) {
float tax;
taxState
[0] = toupper(taxState
[0]); taxState
[1] = toupper(taxState
[1]); if (strcmp(taxState
, "MA") == 0) tax
= grossPay
* MA_TAX_RATE
; else if (strcmp(taxState
, "NH") == 0) tax
= grossPay
* NH_TAX_RATE
; else if (strcmp(taxState
, "VT") == 0) tax
= grossPay
* VT_TAX_RATE
; else if (strcmp(taxState
, "CA") == 0) tax
= grossPay
* CA_TAX_RATE
; else tax = grossPay * DEFAULT_TAX_RATE;
return tax;
}
float calcFedTax(float grossPay) {
return grossPay * FED_TAX_RATE;
}
float calcNetPay(float grossPay, float stateTax, float fedTax) {
return grossPay - (stateTax + fedTax);
}
struct totals calcEmployeeTotals(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct totals employeeTotals) {
employeeTotals.total_wageRate += wageRate;
employeeTotals.total_hours += hours;
employeeTotals.total_overtimeHrs += overtimeHrs;
employeeTotals.total_grossPay += grossPay;
employeeTotals.total_stateTax += stateTax;
employeeTotals.total_fedTax += fedTax;
employeeTotals.total_netPay += netPay;
return employeeTotals;
}
struct min_max calcEmployeeMinMax(float wageRate, float hours, float overtimeHrs,
float grossPay, float stateTax, float fedTax,
float netPay, struct min_max employeeMinMax,
int arrayIndex) {
if (arrayIndex == 0) {
employeeMinMax.min_wageRate = employeeMinMax.max_wageRate = wageRate;
employeeMinMax.min_hours = employeeMinMax.max_hours = hours;
employeeMinMax.min_overtimeHrs = employeeMinMax.max_overtimeHrs = overtimeHrs;
employeeMinMax.min_grossPay = employeeMinMax.max_grossPay = grossPay;
employeeMinMax.min_stateTax = employeeMinMax.max_stateTax = stateTax;
employeeMinMax.min_fedTax = employeeMinMax.max_fedTax = fedTax;
employeeMinMax.min_netPay = employeeMinMax.max_netPay = netPay;
} else {
if (wageRate < employeeMinMax.min_wageRate) employeeMinMax.min_wageRate = wageRate;
if (wageRate > employeeMinMax.max_wageRate) employeeMinMax.max_wageRate = wageRate;
if (hours < employeeMinMax.min_hours) employeeMinMax.min_hours = hours;
if (hours > employeeMinMax.max_hours) employeeMinMax.max_hours = hours;
if (overtimeHrs < employeeMinMax.min_overtimeHrs) employeeMinMax.min_overtimeHrs = overtimeHrs;
if (overtimeHrs > employeeMinMax.max_overtimeHrs) employeeMinMax.max_overtimeHrs = overtimeHrs;
if (grossPay < employeeMinMax.min_grossPay) employeeMinMax.min_grossPay = grossPay;
if (grossPay > employeeMinMax.max_grossPay) employeeMinMax.max_grossPay = grossPay;
if (stateTax < employeeMinMax.min_stateTax) employeeMinMax.min_stateTax = stateTax;
if (stateTax > employeeMinMax.max_stateTax) employeeMinMax.max_stateTax = stateTax;
if (fedTax < employeeMinMax.min_fedTax) employeeMinMax.min_fedTax = fedTax;
if (fedTax > employeeMinMax.max_fedTax) employeeMinMax.max_fedTax = fedTax;
if (netPay < employeeMinMax.min_netPay) employeeMinMax.min_netPay = netPay;
if (netPay > employeeMinMax.max_netPay) employeeMinMax.max_netPay = netPay;
}
return employeeMinMax;
}
void printEmpStatistics(struct totals employeeTotals, struct min_max employeeMinMax, int theSize) {
printf("\n--------------------------------------------------------------"); printf("-------------------"); printf("\nTotals: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeTotals.total_wageRate, employeeTotals.total_hours, employeeTotals.total_overtimeHrs,
employeeTotals.total_grossPay, employeeTotals.total_stateTax, employeeTotals.total_fedTax,
employeeTotals.total_netPay);
if (theSize > 0)
printf("\nAverages: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeTotals.total_wageRate/theSize, employeeTotals.total_hours/theSize,
employeeTotals.total_overtimeHrs/theSize, employeeTotals.total_grossPay/theSize,
employeeTotals.total_stateTax/theSize, employeeTotals.total_fedTax/theSize,
employeeTotals.total_netPay/theSize);
printf("\nMinimum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeMinMax.min_wageRate, employeeMinMax.min_hours, employeeMinMax.min_overtimeHrs,
employeeMinMax.min_grossPay, employeeMinMax.min_stateTax, employeeMinMax.min_fedTax,
employeeMinMax.min_netPay);
printf("\nMaximum: %5.2f %5.1f %5.1f %7.2f %6.2f %7.2f %8.2f", employeeMinMax.max_wageRate, employeeMinMax.max_hours, employeeMinMax.max_overtimeHrs,
employeeMinMax.max_grossPay, employeeMinMax.max_stateTax, employeeMinMax.max_fedTax,
employeeMinMax.max_netPay);
}
Ly8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgovLwovLyBBc3NpZ25tZW50IDcgLSBTdHJ1Y3R1cmVzIGFuZCBTdHJpbmdzCi8vCi8vIE5hbWU6IEpvaG4gU2VtZW51awovLwovLyBDbGFzczogQyBQcm9ncmFtbWluZywgU3ByaW5nIDIwMjYKLy8KLy8gRGF0ZTogMjktTWFyLTIwMjYKLy8KLy8gRGVzY3JpcHRpb246IFByb2dyYW0gY2FsY3VsYXRlcyBvdmVydGltZSwgZ3Jvc3MgcGF5LCBzdGF0ZSAmIGZlZGVyYWwgdGF4LAovLyAgICAgICAgICAgICAgbmV0IHBheSwgYW5kIHByaW50cyB0b3RhbHMsIGF2ZXJhZ2VzLCBtaW4vbWF4IHZhbHVlcy4KLy8KLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CgojZGVmaW5lIFNJWkUgNQojZGVmaW5lIFNURF9IT1VSUyA0MC4wCiNkZWZpbmUgT1RfUkFURSAxLjUKI2RlZmluZSBNQV9UQVhfUkFURSAwLjA1CiNkZWZpbmUgTkhfVEFYX1JBVEUgMC4wCiNkZWZpbmUgVlRfVEFYX1JBVEUgMC4wNgojZGVmaW5lIENBX1RBWF9SQVRFIDAuMDcKI2RlZmluZSBERUZBVUxUX1RBWF9SQVRFIDAuMDgKI2RlZmluZSBGRURfVEFYX1JBVEUgMC4yNQojZGVmaW5lIE5BTUVfU0laRSAyMAojZGVmaW5lIFRBWF9TVEFURV9TSVpFIDMKI2RlZmluZSBGSVJTVF9OQU1FX1NJWkUgMTAKI2RlZmluZSBMQVNUX05BTUVfU0laRSAxMAoKc3RydWN0IG5hbWUgewogICAgY2hhciBmaXJzdE5hbWVbRklSU1RfTkFNRV9TSVpFXTsKICAgIGNoYXIgbGFzdE5hbWVbTEFTVF9OQU1FX1NJWkVdOwp9OwoKc3RydWN0IGVtcGxveWVlIHsKICAgIHN0cnVjdCBuYW1lIGVtcE5hbWU7CiAgICBjaGFyIHRheFN0YXRlW1RBWF9TVEFURV9TSVpFXTsKICAgIGxvbmcgaW50IGNsb2NrTnVtYmVyOwogICAgZmxvYXQgd2FnZVJhdGU7CiAgICBmbG9hdCBob3VyczsKICAgIGZsb2F0IG92ZXJ0aW1lSHJzOwogICAgZmxvYXQgZ3Jvc3NQYXk7CiAgICBmbG9hdCBzdGF0ZVRheDsKICAgIGZsb2F0IGZlZFRheDsKICAgIGZsb2F0IG5ldFBheTsKfTsKCnN0cnVjdCB0b3RhbHMgewogICAgZmxvYXQgdG90YWxfd2FnZVJhdGU7CiAgICBmbG9hdCB0b3RhbF9ob3VyczsKICAgIGZsb2F0IHRvdGFsX292ZXJ0aW1lSHJzOwogICAgZmxvYXQgdG90YWxfZ3Jvc3NQYXk7CiAgICBmbG9hdCB0b3RhbF9zdGF0ZVRheDsKICAgIGZsb2F0IHRvdGFsX2ZlZFRheDsKICAgIGZsb2F0IHRvdGFsX25ldFBheTsKfTsKCnN0cnVjdCBtaW5fbWF4IHsKICAgIGZsb2F0IG1pbl93YWdlUmF0ZTsKICAgIGZsb2F0IG1pbl9ob3VyczsKICAgIGZsb2F0IG1pbl9vdmVydGltZUhyczsKICAgIGZsb2F0IG1pbl9ncm9zc1BheTsKICAgIGZsb2F0IG1pbl9zdGF0ZVRheDsKICAgIGZsb2F0IG1pbl9mZWRUYXg7CiAgICBmbG9hdCBtaW5fbmV0UGF5OwogICAgZmxvYXQgbWF4X3dhZ2VSYXRlOwogICAgZmxvYXQgbWF4X2hvdXJzOwogICAgZmxvYXQgbWF4X292ZXJ0aW1lSHJzOwogICAgZmxvYXQgbWF4X2dyb3NzUGF5OwogICAgZmxvYXQgbWF4X3N0YXRlVGF4OwogICAgZmxvYXQgbWF4X2ZlZFRheDsKICAgIGZsb2F0IG1heF9uZXRQYXk7Cn07CgovLyBQcm90b3R5cGVzCmZsb2F0IGdldEhvdXJzKGxvbmcgaW50IGNsb2NrTnVtYmVyKTsKZmxvYXQgY2FsY092ZXJ0aW1lSHJzKGZsb2F0IGhvdXJzKTsKZmxvYXQgY2FsY0dyb3NzUGF5KGZsb2F0IHdhZ2VSYXRlLCBmbG9hdCBob3VycywgZmxvYXQgb3ZlcnRpbWVIcnMpOwp2b2lkIHByaW50SGVhZGVyKHZvaWQpOwp2b2lkIHByaW50RW1wKGNoYXIgZmlyc3ROYW1lW10sIGNoYXIgbGFzdE5hbWVbXSwgY2hhciB0YXhTdGF0ZVtdLCBsb25nIGludCBjbG9ja051bWJlciwKICAgICAgICAgICAgICBmbG9hdCB3YWdlUmF0ZSwgZmxvYXQgaG91cnMsIGZsb2F0IG92ZXJ0aW1lSHJzLCBmbG9hdCBncm9zc1BheSwKICAgICAgICAgICAgICBmbG9hdCBzdGF0ZVRheCwgZmxvYXQgZmVkVGF4LCBmbG9hdCBuZXRQYXkpOwpmbG9hdCBjYWxjU3RhdGVUYXgoZmxvYXQgZ3Jvc3NQYXksIGNoYXIgdGF4U3RhdGVbXSk7CmZsb2F0IGNhbGNGZWRUYXgoZmxvYXQgZ3Jvc3NQYXkpOwpmbG9hdCBjYWxjTmV0UGF5KGZsb2F0IGdyb3NzUGF5LCBmbG9hdCBzdGF0ZVRheCwgZmxvYXQgZmVkVGF4KTsKc3RydWN0IHRvdGFscyBjYWxjRW1wbG95ZWVUb3RhbHMoZmxvYXQgd2FnZVJhdGUsIGZsb2F0IGhvdXJzLCBmbG9hdCBvdmVydGltZUhycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgZ3Jvc3NQYXksIGZsb2F0IHN0YXRlVGF4LCBmbG9hdCBmZWRUYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG5ldFBheSwgc3RydWN0IHRvdGFscyBlbXBsb3llZVRvdGFscyk7CnN0cnVjdCBtaW5fbWF4IGNhbGNFbXBsb3llZU1pbk1heChmbG9hdCB3YWdlUmF0ZSwgZmxvYXQgaG91cnMsIGZsb2F0IG92ZXJ0aW1lSHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgZ3Jvc3NQYXksIGZsb2F0IHN0YXRlVGF4LCBmbG9hdCBmZWRUYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBuZXRQYXksIHN0cnVjdCBtaW5fbWF4IGVtcGxveWVlTWluTWF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGFycmF5SW5kZXgpOwp2b2lkIHByaW50RW1wU3RhdGlzdGljcyhzdHJ1Y3QgdG90YWxzIGVtcGxveWVlVG90YWxzLCBzdHJ1Y3QgbWluX21heCBlbXBsb3llZU1pbk1heCwgaW50IHRoZVNpemUpOwoKaW50IG1haW4oKSB7CiAgICBpbnQgaTsKICAgIHN0cnVjdCBlbXBsb3llZSBlbXBsb3llZURhdGFbU0laRV0gPSB7CiAgICAgICAgeyB7IkNvbm5pZSIsICJDb2JvbCJ9LCAiTUEiLCA5ODQwMSwgMTAuNjAgfSwKICAgICAgICB7IHsiTWFyeSIsICJBcGwifSwgIk5IIiwgNTI2NDg4LCA5Ljc1IH0sCiAgICAgICAgeyB7IkZyYW5rIiwgIkZvcnRyYW4ifSwgIlZUIiwgNzY1MzQ5LCAxMC41MCB9LAogICAgICAgIHsgeyJKZWZmIiwgIkFkYSJ9LCAiTlkiLCAzNDY0NSwgMTIuMjUgfSwKICAgICAgICB7IHsiQW50b24iLCAiUGFzY2FsIn0sICJDQSIsIDEyNzYxNSwgOC4zNSB9CiAgICB9OwoKICAgIHN0cnVjdCB0b3RhbHMgZW1wbG95ZWVUb3RhbHMgPSB7MH07CiAgICBzdHJ1Y3QgbWluX21heCBlbXBsb3llZU1pbk1heCA9IHswfTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgU0laRTsgKytpKSB7CiAgICAgICAgZW1wbG95ZWVEYXRhW2ldLmhvdXJzID0gZ2V0SG91cnMoZW1wbG95ZWVEYXRhW2ldLmNsb2NrTnVtYmVyKTsKICAgICAgICBlbXBsb3llZURhdGFbaV0ub3ZlcnRpbWVIcnMgPSBjYWxjT3ZlcnRpbWVIcnMoZW1wbG95ZWVEYXRhW2ldLmhvdXJzKTsKICAgICAgICBlbXBsb3llZURhdGFbaV0uZ3Jvc3NQYXkgPSBjYWxjR3Jvc3NQYXkoZW1wbG95ZWVEYXRhW2ldLndhZ2VSYXRlLCBlbXBsb3llZURhdGFbaV0uaG91cnMsIGVtcGxveWVlRGF0YVtpXS5vdmVydGltZUhycyk7CiAgICAgICAgZW1wbG95ZWVEYXRhW2ldLnN0YXRlVGF4ID0gY2FsY1N0YXRlVGF4KGVtcGxveWVlRGF0YVtpXS5ncm9zc1BheSwgZW1wbG95ZWVEYXRhW2ldLnRheFN0YXRlKTsKICAgICAgICBlbXBsb3llZURhdGFbaV0uZmVkVGF4ID0gY2FsY0ZlZFRheChlbXBsb3llZURhdGFbaV0uZ3Jvc3NQYXkpOwogICAgICAgIGVtcGxveWVlRGF0YVtpXS5uZXRQYXkgPSBjYWxjTmV0UGF5KGVtcGxveWVlRGF0YVtpXS5ncm9zc1BheSwgZW1wbG95ZWVEYXRhW2ldLnN0YXRlVGF4LCBlbXBsb3llZURhdGFbaV0uZmVkVGF4KTsKICAgICAgICBlbXBsb3llZVRvdGFscyA9IGNhbGNFbXBsb3llZVRvdGFscyhlbXBsb3llZURhdGFbaV0ud2FnZVJhdGUsIGVtcGxveWVlRGF0YVtpXS5ob3VycywgZW1wbG95ZWVEYXRhW2ldLm92ZXJ0aW1lSHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcGxveWVlRGF0YVtpXS5ncm9zc1BheSwgZW1wbG95ZWVEYXRhW2ldLnN0YXRlVGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcGxveWVlRGF0YVtpXS5mZWRUYXgsIGVtcGxveWVlRGF0YVtpXS5uZXRQYXksIGVtcGxveWVlVG90YWxzKTsKICAgICAgICBlbXBsb3llZU1pbk1heCA9IGNhbGNFbXBsb3llZU1pbk1heChlbXBsb3llZURhdGFbaV0ud2FnZVJhdGUsIGVtcGxveWVlRGF0YVtpXS5ob3VycywgZW1wbG95ZWVEYXRhW2ldLm92ZXJ0aW1lSHJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcGxveWVlRGF0YVtpXS5ncm9zc1BheSwgZW1wbG95ZWVEYXRhW2ldLnN0YXRlVGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVtcGxveWVlRGF0YVtpXS5mZWRUYXgsIGVtcGxveWVlRGF0YVtpXS5uZXRQYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wbG95ZWVNaW5NYXgsIGkpOwogICAgfQoKICAgIHByaW50SGVhZGVyKCk7CgogICAgZm9yIChpID0gMDsgaSA8IFNJWkU7ICsraSkgewogICAgICAgIHByaW50RW1wKGVtcGxveWVlRGF0YVtpXS5lbXBOYW1lLmZpcnN0TmFtZSwgZW1wbG95ZWVEYXRhW2ldLmVtcE5hbWUubGFzdE5hbWUsIGVtcGxveWVlRGF0YVtpXS50YXhTdGF0ZSwKICAgICAgICAgICAgICAgICBlbXBsb3llZURhdGFbaV0uY2xvY2tOdW1iZXIsIGVtcGxveWVlRGF0YVtpXS53YWdlUmF0ZSwgZW1wbG95ZWVEYXRhW2ldLmhvdXJzLAogICAgICAgICAgICAgICAgIGVtcGxveWVlRGF0YVtpXS5vdmVydGltZUhycywgZW1wbG95ZWVEYXRhW2ldLmdyb3NzUGF5LCBlbXBsb3llZURhdGFbaV0uc3RhdGVUYXgsCiAgICAgICAgICAgICAgICAgZW1wbG95ZWVEYXRhW2ldLmZlZFRheCwgZW1wbG95ZWVEYXRhW2ldLm5ldFBheSk7CiAgICB9CgogICAgcHJpbnRFbXBTdGF0aXN0aWNzKGVtcGxveWVlVG90YWxzLCBlbXBsb3llZU1pbk1heCwgU0laRSk7CgogICAgcmV0dXJuIDA7Cn0KCi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKZmxvYXQgZ2V0SG91cnMobG9uZyBpbnQgY2xvY2tOdW1iZXIpIHsKICAgIGZsb2F0IHRoZUhvdXJzV29ya2VkOwogICAgcHJpbnRmKCJcbkVudGVyIGhvdXJzIHdvcmtlZCBieSBlbXAgIyAlMDZsaTogIiwgY2xvY2tOdW1iZXIpOwogICAgc2NhbmYoIiVmIiwgJnRoZUhvdXJzV29ya2VkKTsKICAgIHJldHVybiB0aGVIb3Vyc1dvcmtlZDsKfQoKdm9pZCBwcmludEhlYWRlcih2b2lkKSB7CiAgICBwcmludGYoIlxuXG4qKiogUGF5IENhbGN1bGF0b3IgKioqXG4iKTsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tIik7CiAgICBwcmludGYoIlxuTmFtZSAgICAgICAgICAgICAgICBUYXggIENsb2NrIyBXYWdlICAgSG91cnMgIE9UICAgR3Jvc3MgIik7CiAgICBwcmludGYoIiAgU3RhdGUgIEZlZCAgICAgIE5ldCIpOwogICAgcHJpbnRmKCJcbiAgICAgICAgICAgICAgICAgICBTdGF0ZSAgICAgICAgICAgICAgICAgICAgICAgICAgIFBheSAgICIpOwogICAgcHJpbnRmKCIgIFRheCAgICBUYXggICAgICBQYXkiKTsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tIik7Cn0KCnZvaWQgcHJpbnRFbXAoY2hhciBmaXJzdE5hbWVbXSwgY2hhciBsYXN0TmFtZVtdLCBjaGFyIHRheFN0YXRlW10sIGxvbmcgaW50IGNsb2NrTnVtYmVyLAogICAgICAgICAgICAgIGZsb2F0IHdhZ2VSYXRlLCBmbG9hdCBob3VycywgZmxvYXQgb3ZlcnRpbWVIcnMsIGZsb2F0IGdyb3NzUGF5LAogICAgICAgICAgICAgIGZsb2F0IHN0YXRlVGF4LCBmbG9hdCBmZWRUYXgsIGZsb2F0IG5ldFBheSkgewogICAgY2hhciBuYW1lW0ZJUlNUX05BTUVfU0laRSArIExBU1RfTkFNRV9TSVpFICsgMV07CiAgICBzdHJjcHkobmFtZSwgZmlyc3ROYW1lKTsKICAgIHN0cmNhdChuYW1lLCAiICIpOwogICAgc3RyY2F0KG5hbWUsIGxhc3ROYW1lKTsKICAgIHByaW50ZigiXG4lLTIwLjIwcyAlLTIuMnMgICUwNmxpICU1LjJmICAlNC4xZiAgJTQuMWYgJTcuMmYgJTYuMmYgJTcuMmYgJTguMmYiLAogICAgICAgICAgIG5hbWUsIHRheFN0YXRlLCBjbG9ja051bWJlciwgd2FnZVJhdGUsIGhvdXJzLCBvdmVydGltZUhycywgZ3Jvc3NQYXksIHN0YXRlVGF4LCBmZWRUYXgsIG5ldFBheSk7Cn0KCmZsb2F0IGNhbGNPdmVydGltZUhycyhmbG9hdCBob3VycykgewogICAgcmV0dXJuIChob3VycyA+IFNURF9IT1VSUykgPyAoaG91cnMgLSBTVERfSE9VUlMpIDogMDsKfQoKZmxvYXQgY2FsY0dyb3NzUGF5KGZsb2F0IHdhZ2VSYXRlLCBmbG9hdCBob3VycywgZmxvYXQgb3ZlcnRpbWVIcnMpIHsKICAgIGZsb2F0IG5vcm1hbFBheSA9IHdhZ2VSYXRlICogKGhvdXJzIC0gb3ZlcnRpbWVIcnMpOwogICAgZmxvYXQgb3ZlcnRpbWVQYXkgPSBvdmVydGltZUhycyAqIChPVF9SQVRFICogd2FnZVJhdGUpOwogICAgcmV0dXJuIG5vcm1hbFBheSArIG92ZXJ0aW1lUGF5Owp9CgpmbG9hdCBjYWxjU3RhdGVUYXgoZmxvYXQgZ3Jvc3NQYXksIGNoYXIgdGF4U3RhdGVbXSkgewogICAgZmxvYXQgdGF4OwogICAgdGF4U3RhdGVbMF0gPSB0b3VwcGVyKHRheFN0YXRlWzBdKTsKICAgIHRheFN0YXRlWzFdID0gdG91cHBlcih0YXhTdGF0ZVsxXSk7CiAgICBpZiAoc3RyY21wKHRheFN0YXRlLCAiTUEiKSA9PSAwKSB0YXggPSBncm9zc1BheSAqIE1BX1RBWF9SQVRFOwogICAgZWxzZSBpZiAoc3RyY21wKHRheFN0YXRlLCAiTkgiKSA9PSAwKSB0YXggPSBncm9zc1BheSAqIE5IX1RBWF9SQVRFOwogICAgZWxzZSBpZiAoc3RyY21wKHRheFN0YXRlLCAiVlQiKSA9PSAwKSB0YXggPSBncm9zc1BheSAqIFZUX1RBWF9SQVRFOwogICAgZWxzZSBpZiAoc3RyY21wKHRheFN0YXRlLCAiQ0EiKSA9PSAwKSB0YXggPSBncm9zc1BheSAqIENBX1RBWF9SQVRFOwogICAgZWxzZSB0YXggPSBncm9zc1BheSAqIERFRkFVTFRfVEFYX1JBVEU7CiAgICByZXR1cm4gdGF4Owp9CgpmbG9hdCBjYWxjRmVkVGF4KGZsb2F0IGdyb3NzUGF5KSB7CiAgICByZXR1cm4gZ3Jvc3NQYXkgKiBGRURfVEFYX1JBVEU7Cn0KCmZsb2F0IGNhbGNOZXRQYXkoZmxvYXQgZ3Jvc3NQYXksIGZsb2F0IHN0YXRlVGF4LCBmbG9hdCBmZWRUYXgpIHsKICAgIHJldHVybiBncm9zc1BheSAtIChzdGF0ZVRheCArIGZlZFRheCk7Cn0KCnN0cnVjdCB0b3RhbHMgY2FsY0VtcGxveWVlVG90YWxzKGZsb2F0IHdhZ2VSYXRlLCBmbG9hdCBob3VycywgZmxvYXQgb3ZlcnRpbWVIcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGdyb3NzUGF5LCBmbG9hdCBzdGF0ZVRheCwgZmxvYXQgZmVkVGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBuZXRQYXksIHN0cnVjdCB0b3RhbHMgZW1wbG95ZWVUb3RhbHMpIHsKICAgIGVtcGxveWVlVG90YWxzLnRvdGFsX3dhZ2VSYXRlICs9IHdhZ2VSYXRlOwogICAgZW1wbG95ZWVUb3RhbHMudG90YWxfaG91cnMgKz0gaG91cnM7CiAgICBlbXBsb3llZVRvdGFscy50b3RhbF9vdmVydGltZUhycyArPSBvdmVydGltZUhyczsKICAgIGVtcGxveWVlVG90YWxzLnRvdGFsX2dyb3NzUGF5ICs9IGdyb3NzUGF5OwogICAgZW1wbG95ZWVUb3RhbHMudG90YWxfc3RhdGVUYXggKz0gc3RhdGVUYXg7CiAgICBlbXBsb3llZVRvdGFscy50b3RhbF9mZWRUYXggKz0gZmVkVGF4OwogICAgZW1wbG95ZWVUb3RhbHMudG90YWxfbmV0UGF5ICs9IG5ldFBheTsKICAgIHJldHVybiBlbXBsb3llZVRvdGFsczsKfQoKc3RydWN0IG1pbl9tYXggY2FsY0VtcGxveWVlTWluTWF4KGZsb2F0IHdhZ2VSYXRlLCBmbG9hdCBob3VycywgZmxvYXQgb3ZlcnRpbWVIcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbG9hdCBncm9zc1BheSwgZmxvYXQgc3RhdGVUYXgsIGZsb2F0IGZlZFRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IG5ldFBheSwgc3RydWN0IG1pbl9tYXggZW1wbG95ZWVNaW5NYXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYXJyYXlJbmRleCkgewogICAgaWYgKGFycmF5SW5kZXggPT0gMCkgewogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl93YWdlUmF0ZSA9IGVtcGxveWVlTWluTWF4Lm1heF93YWdlUmF0ZSA9IHdhZ2VSYXRlOwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9ob3VycyA9IGVtcGxveWVlTWluTWF4Lm1heF9ob3VycyA9IGhvdXJzOwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9vdmVydGltZUhycyA9IGVtcGxveWVlTWluTWF4Lm1heF9vdmVydGltZUhycyA9IG92ZXJ0aW1lSHJzOwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9ncm9zc1BheSA9IGVtcGxveWVlTWluTWF4Lm1heF9ncm9zc1BheSA9IGdyb3NzUGF5OwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9zdGF0ZVRheCA9IGVtcGxveWVlTWluTWF4Lm1heF9zdGF0ZVRheCA9IHN0YXRlVGF4OwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9mZWRUYXggPSBlbXBsb3llZU1pbk1heC5tYXhfZmVkVGF4ID0gZmVkVGF4OwogICAgICAgIGVtcGxveWVlTWluTWF4Lm1pbl9uZXRQYXkgPSBlbXBsb3llZU1pbk1heC5tYXhfbmV0UGF5ID0gbmV0UGF5OwogICAgfSBlbHNlIHsKICAgICAgICBpZiAod2FnZVJhdGUgPCBlbXBsb3llZU1pbk1heC5taW5fd2FnZVJhdGUpIGVtcGxveWVlTWluTWF4Lm1pbl93YWdlUmF0ZSA9IHdhZ2VSYXRlOwogICAgICAgIGlmICh3YWdlUmF0ZSA+IGVtcGxveWVlTWluTWF4Lm1heF93YWdlUmF0ZSkgZW1wbG95ZWVNaW5NYXgubWF4X3dhZ2VSYXRlID0gd2FnZVJhdGU7CiAgICAgICAgaWYgKGhvdXJzIDwgZW1wbG95ZWVNaW5NYXgubWluX2hvdXJzKSBlbXBsb3llZU1pbk1heC5taW5faG91cnMgPSBob3VyczsKICAgICAgICBpZiAoaG91cnMgPiBlbXBsb3llZU1pbk1heC5tYXhfaG91cnMpIGVtcGxveWVlTWluTWF4Lm1heF9ob3VycyA9IGhvdXJzOwogICAgICAgIGlmIChvdmVydGltZUhycyA8IGVtcGxveWVlTWluTWF4Lm1pbl9vdmVydGltZUhycykgZW1wbG95ZWVNaW5NYXgubWluX292ZXJ0aW1lSHJzID0gb3ZlcnRpbWVIcnM7CiAgICAgICAgaWYgKG92ZXJ0aW1lSHJzID4gZW1wbG95ZWVNaW5NYXgubWF4X292ZXJ0aW1lSHJzKSBlbXBsb3llZU1pbk1heC5tYXhfb3ZlcnRpbWVIcnMgPSBvdmVydGltZUhyczsKICAgICAgICBpZiAoZ3Jvc3NQYXkgPCBlbXBsb3llZU1pbk1heC5taW5fZ3Jvc3NQYXkpIGVtcGxveWVlTWluTWF4Lm1pbl9ncm9zc1BheSA9IGdyb3NzUGF5OwogICAgICAgIGlmIChncm9zc1BheSA+IGVtcGxveWVlTWluTWF4Lm1heF9ncm9zc1BheSkgZW1wbG95ZWVNaW5NYXgubWF4X2dyb3NzUGF5ID0gZ3Jvc3NQYXk7CiAgICAgICAgaWYgKHN0YXRlVGF4IDwgZW1wbG95ZWVNaW5NYXgubWluX3N0YXRlVGF4KSBlbXBsb3llZU1pbk1heC5taW5fc3RhdGVUYXggPSBzdGF0ZVRheDsKICAgICAgICBpZiAoc3RhdGVUYXggPiBlbXBsb3llZU1pbk1heC5tYXhfc3RhdGVUYXgpIGVtcGxveWVlTWluTWF4Lm1heF9zdGF0ZVRheCA9IHN0YXRlVGF4OwogICAgICAgIGlmIChmZWRUYXggPCBlbXBsb3llZU1pbk1heC5taW5fZmVkVGF4KSBlbXBsb3llZU1pbk1heC5taW5fZmVkVGF4ID0gZmVkVGF4OwogICAgICAgIGlmIChmZWRUYXggPiBlbXBsb3llZU1pbk1heC5tYXhfZmVkVGF4KSBlbXBsb3llZU1pbk1heC5tYXhfZmVkVGF4ID0gZmVkVGF4OwogICAgICAgIGlmIChuZXRQYXkgPCBlbXBsb3llZU1pbk1heC5taW5fbmV0UGF5KSBlbXBsb3llZU1pbk1heC5taW5fbmV0UGF5ID0gbmV0UGF5OwogICAgICAgIGlmIChuZXRQYXkgPiBlbXBsb3llZU1pbk1heC5tYXhfbmV0UGF5KSBlbXBsb3llZU1pbk1heC5tYXhfbmV0UGF5ID0gbmV0UGF5OwogICAgfQogICAgcmV0dXJuIGVtcGxveWVlTWluTWF4Owp9Cgp2b2lkIHByaW50RW1wU3RhdGlzdGljcyhzdHJ1Y3QgdG90YWxzIGVtcGxveWVlVG90YWxzLCBzdHJ1Y3QgbWluX21heCBlbXBsb3llZU1pbk1heCwgaW50IHRoZVNpemUpIHsKICAgIHByaW50ZigiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIpOwogICAgcHJpbnRmKCItLS0tLS0tLS0tLS0tLS0tLS0tIik7CiAgICBwcmludGYoIlxuVG90YWxzOiAgICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgICAgZW1wbG95ZWVUb3RhbHMudG90YWxfd2FnZVJhdGUsIGVtcGxveWVlVG90YWxzLnRvdGFsX2hvdXJzLCBlbXBsb3llZVRvdGFscy50b3RhbF9vdmVydGltZUhycywKICAgICAgICAgICBlbXBsb3llZVRvdGFscy50b3RhbF9ncm9zc1BheSwgZW1wbG95ZWVUb3RhbHMudG90YWxfc3RhdGVUYXgsIGVtcGxveWVlVG90YWxzLnRvdGFsX2ZlZFRheCwKICAgICAgICAgICBlbXBsb3llZVRvdGFscy50b3RhbF9uZXRQYXkpOwogICAgaWYgKHRoZVNpemUgPiAwKQogICAgICAgIHByaW50ZigiXG5BdmVyYWdlczogICAgICAgICAgICAgICAgICAgICAgICU1LjJmICU1LjFmICU1LjFmICU3LjJmICU2LjJmICU3LjJmICU4LjJmIiwKICAgICAgICAgICAgICAgZW1wbG95ZWVUb3RhbHMudG90YWxfd2FnZVJhdGUvdGhlU2l6ZSwgZW1wbG95ZWVUb3RhbHMudG90YWxfaG91cnMvdGhlU2l6ZSwKICAgICAgICAgICAgICAgZW1wbG95ZWVUb3RhbHMudG90YWxfb3ZlcnRpbWVIcnMvdGhlU2l6ZSwgZW1wbG95ZWVUb3RhbHMudG90YWxfZ3Jvc3NQYXkvdGhlU2l6ZSwKICAgICAgICAgICAgICAgZW1wbG95ZWVUb3RhbHMudG90YWxfc3RhdGVUYXgvdGhlU2l6ZSwgZW1wbG95ZWVUb3RhbHMudG90YWxfZmVkVGF4L3RoZVNpemUsCiAgICAgICAgICAgICAgIGVtcGxveWVlVG90YWxzLnRvdGFsX25ldFBheS90aGVTaXplKTsKICAgIHByaW50ZigiXG5NaW5pbXVtOiAgICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgICAgZW1wbG95ZWVNaW5NYXgubWluX3dhZ2VSYXRlLCBlbXBsb3llZU1pbk1heC5taW5faG91cnMsIGVtcGxveWVlTWluTWF4Lm1pbl9vdmVydGltZUhycywKICAgICAgICAgICBlbXBsb3llZU1pbk1heC5taW5fZ3Jvc3NQYXksIGVtcGxveWVlTWluTWF4Lm1pbl9zdGF0ZVRheCwgZW1wbG95ZWVNaW5NYXgubWluX2ZlZFRheCwKICAgICAgICAgICBlbXBsb3llZU1pbk1heC5taW5fbmV0UGF5KTsKICAgIHByaW50ZigiXG5NYXhpbXVtOiAgICAgICAgICAgICAgICAgICAgICAgICAlNS4yZiAlNS4xZiAlNS4xZiAlNy4yZiAlNi4yZiAlNy4yZiAlOC4yZiIsCiAgICAgICAgICAgZW1wbG95ZWVNaW5NYXgubWF4X3dhZ2VSYXRlLCBlbXBsb3llZU1pbk1heC5tYXhfaG91cnMsIGVtcGxveWVlTWluTWF4Lm1heF9vdmVydGltZUhycywKICAgICAgICAgICBlbXBsb3llZU1pbk1heC5tYXhfZ3Jvc3NQYXksIGVtcGxveWVlTWluTWF4Lm1heF9zdGF0ZVRheCwgZW1wbG95ZWVNaW5NYXgubWF4X2ZlZFRheCwKICAgICAgICAgICBlbXBsb3llZU1pbk1heC5tYXhfbmV0UGF5KTsKfQ==