{r} #Install Packages

```{r} #install.packages(“tidyverse”) #install.packages(“psych”) #install.packages(“ggplot2”) #install.packages(“reshape2”) #install.packages(“corrplot”) #install.packages(“ggcorrplot”) #install.packages(“caret”)



# Libraries
```{r}
library(tidyverse)
library(psych)
library(ggplot2)
library(reshape2)
library(corrplot)
library(ggcorrplot)

Read File

{r} income <- read.csv("XYZ LLC 2021 PL.csv")

View

{r} #view (income)

Structure of the Dataset

{r} str(income)

Remove First 3 Rows

{r} income <- income[-c(1:3), ]

View

{r} #view(income)

View Headers

{r} head(income)

#Column Names {r} print(colnames(income))

#Count Missing Values in Each Column {r} print(sapply(income, function(x) sum(is.na(x)))) # Eliminate the NA Rows {r} income <- na.omit(income)

View

{r} view(income)

Summary

{r} summary(income)

Structure of the New Dataset

{r} str(income)

Change The headers into a date structure

{r} Col_headers <- seq(as.Date("2022-01-01"), as.Date("2023-04-01"), by = "month")

{r} names(income)[-1] <- format(Col_headers, "%B %Y")

Bar Chart

```{r} # Extract the “Net Income” net_income <- as.numeric(income[nrow(income), -1])

Calculate the color of the bars (green if positive, red if negative)

colors <- ifelse(net_income >= 0, “green”, “red”)

Create the bar plot

barplot(net_income, col = colors, # Color the bars based on the value of net_income main = “Net Income”, xlab = “Date”, ylab = “Net Income”, names.arg = colnames(income)[-1], # Use dates as x-axis labels las = 2) # Rotate the x-axis labels

Add a legend

legend(“topright”, legend = c(“Positive”, “Negative”), fill = c(“green”, “red”))


```{r}
# Create the barplot
barplot(net_income, 
        col = colors,  # Color the bars based on the value of net_income
        main = "Net Income", 
        xlab = "Date", 
        ylab = "Net Income",
        names.arg = colnames(income)[-1],  # Use dates as x-axis labels
        las = 2)  # Rotate the x-axis labels

# Add a legend
legend("topright", 
       legend = c("Positive", "Negative"), 
       fill = c("green", "red"))

# Calculate the tendency line
tendency_line <- lm(net_income ~ seq_along(net_income))

# Plot the tendency line
abline(tendency_line, col = "blue", lty = 2)

#Line Chart

```{r} # Extract column names (months) month_names <- colnames(income)[-1] # Exclude the first column containing unit names

Extract values from the Total Rental Income row (excluding the first column)

total_income <- as.numeric(income[8, -1])

Create the line plot

plot(1:length(month_names), total_income, type = “o”, xlab = “Months”, ylab = “Total Rental Income”, main = “Total Rental Income per Month”, xaxt = “n”) # Disable x-axis labels

Add month labels on the x-axis

axis(1, at = 1:length(month_names), labels = month_names, las = 2)

```{r}
# Extract column names (months)
month_names <- colnames(income)[-1]  # Exclude the first column containing unit names

# Extract values from the Total Rental Income row (excluding the first column)
total_income <- as.numeric(income[8, -1])

# Create the line plot with nicer aesthetics
plot(1:length(month_names), total_income, type = "o", 
     xlab = "Months", ylab = "Total Rental Income (in USD)", 
     main = "Total Rental Income per Month",
     col = "blue",            # Line color
     pch = 16,                # Point shape
     lwd = 2,                 # Line width
     ylim = c(0, max(total_income) * 1.1),  # Adjust y-axis limits
     xaxt = "n")              # Disable x-axis labels

# Add month labels on the x-axis with rotated labels
axis(1, at = 1:length(month_names), labels = month_names, las = 2, cex.axis = 0.8)

# Add gridlines
grid()

# Add a legend
legend("topright", 
       legend = c("Total Rental Income"), 
       col = "blue", 
       lty = 1, 
       pch = 16, 
       cex = 0.8,
       bg = "white")

Bar Expenses Chart

{r} # Transponer el conjunto de datos para que las filas se conviertan en columnas transposed_data <- t(income) #view(transposed_data)

{r} colnames(transposed_data) <- transposed_data[1, ] transposed_data <- transposed_data[-1, ]

{r} #view(transposed_data)

```{r} library(ggplot2)

Select only the rows corresponding to expenses

expenses <- transposed_data[, c(“Bright Star Credit Union”, “Bank Charges - Other”, “Total Commission”, “Filing Fees”,“Total Electricity”, “Total Utilities”)]

Convert the selected columns to numeric

expenses <- apply(expenses, 2, as.numeric)

Calculate the sum of each expense column

total_expenses <- colSums(expenses)

Create a dataframe with the expense names and their totals

expenses_df <- data.frame(expense = names(total_expenses), total = total_expenses)

Create the bar plot with labels

ggplot(expenses_df, aes(x = expense, y = total, label = total)) + geom_bar(stat = “identity”, fill = “skyblue”) + geom_text(vjust = -0.5, size = 3) + # Add labels above the bars labs(title = “Total Expenses”, x = “Expense”, y = “Total”) + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotate x-axis labels for better readability

```{r}
# Ensure both expenses and net income have the same number of months
num_months <- min(length(month_names), length(total_expenses), length(total_income))

# Combine expenses and net income into a single dataframe
combined_data <- data.frame(
  Month = month_names[1:num_months],
  Expenses = total_expenses[1:num_months],
  Net_Income = total_income[1:num_months]
)

# Melt the data for easier plotting
combined_data <- melt(combined_data, id.vars = "Month")

# Create the combined bar plot
ggplot(combined_data, aes(x = Month, y = value, fill = variable)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Expenses vs Net Income", x = "Month", y = "Amount") +
  scale_fill_manual(values = c("Expenses" = "skyblue", "Net_Income" = "green"), 
                    labels = c("Expenses", "Net Income")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotate x-axis labels for better readability

{r} # Extract relevant variables (expenses and income of the units) expenses <- transposed_data[, c("Bright Star Credit Union", "Bank Charges - Other", "Total Commission", "Filing Fees", "Total Electricity", "Total Utilities")] income_units <- transposed_data[, c("Unit 1115", "Unit 1126", "Unit 1215")]

{r} #View(income_units)

{r} expenses <- apply(expenses, 2, as.numeric) income_units <- apply(income_units, 2, as.numeric)

{r} # Calculate net income (total income - total expenses) net_income <- rowSums(income_units) - rowSums(expenses)

{r} # Create a data frame with predictor variables (expenses and income of the units) and the target variable (net income) model_data <- cbind(expenses, income_units, net_income) colnames(model_data) <- c("Bright_Star_Credit_Union", "Bank_Charges_Other", "Total_Commission", "Filing_Fees", "Total_Electricity", "Total_Utilities", "Unit_1115", "Unit_1126", "Unit_1215", "Net_Income")

{r} #install.packages("caret") library(caret) {r} class(model_data) {r} if (!inherits(model_data, "data.frame")) { model_data <- as.data.frame(model_data) }

{r} # Split the data into training and testing sets (80% training, 20% testing) set.seed(123) # for reproducibility train_index <- createDataPartition(model_data$Net_Income, p = 0.8, list = FALSE) train_data <- model_data[train_index, ] test_data <- model_data[-train_index, ]

{r} # Build a linear regression model net_income_model <- lm(Net_Income ~ ., data = train_data)

{r} # Evaluate the model summary(net_income_model) {r} # Make predictions on the testing set predictions <- predict(net_income_model, newdata = test_data)

{r} # Evaluate model performance (e.g., RMSE, R-squared) rmse <- sqrt(mean((test_data$Net_Income - predictions)^2)) rsquared <- cor(test_data$Net_Income, predictions)^2

{r} # Print RMSE and R-squared print(paste("RMSE:", rmse)) print(paste("R-squared:", rsquared))

{r} # Calculate residuals residuals <- residuals(net_income_model)

{r} predicted_values <- predict(net_income_model)

{r} # Create residual plot plot(predicted_values, residuals, xlab = "Predicted Values", ylab = "Residuals", main = "Residual Plot") abline(h = 0, col = "red") # Add horizontal line at y = 0

{r} # Create QQ plot qqnorm(residuals) qqline(residuals) {r} varImp(net_income_model)

```{r}

```{r}
# Ensure both expenses and net income have the same number of months
num_months <- min(length(month_names), length(total_expenses), length(total_income))

# Combine expenses and net income into a single dataframe
combined_data <- data.frame(
  Month = month_names[1:num_months],
  Expenses = total_expenses[1:num_months],
  Net_Income = total_income[1:num_months]
)

# Calculate the percentage of expenses over net income
combined_data$Expense_Percentage <- (combined_data$Expenses / combined_data$Net_Income) * 100

# Melt the data for easier plotting
combined_data <- melt(combined_data, id.vars = c("Month", "Expense_Percentage"))

# Create the combined bar plot with percentage labels
ggplot(combined_data, aes(x = Month, y = value, fill = variable)) +
  geom_bar(stat = "identity", position = "dodge") +
  geom_text(aes(label = paste(round(Expense_Percentage, 1), "%")), 
            position = position_dodge(width = 1), 
            vjust = -0.5, size = 3) +  # Add percentage labels above the bars
  labs(title = "Expenses vs Net Income", x = "Month", y = "Amount") +
  scale_fill_manual(values = c("Expenses" = "skyblue", "Net_Income" = "green"), 
                    labels = c("Expenses", "Net Income")) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Rotate x-axis labels for better readability
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyfQojSW5zdGFsbCBQYWNrYWdlcwpgYGAKCgoKYGBge3J9CiNpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQojaW5zdGFsbC5wYWNrYWdlcygicHN5Y2giKQojaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpCiNpbnN0YWxsLnBhY2thZ2VzKCJyZXNoYXBlMiIpCiNpbnN0YWxsLnBhY2thZ2VzKCJjb3JycGxvdCIpCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ2NvcnJwbG90IikKI2luc3RhbGwucGFja2FnZXMoImNhcmV0IikKCmBgYAoKCiMgTGlicmFyaWVzCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShwc3ljaCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KHJlc2hhcGUyKQpsaWJyYXJ5KGNvcnJwbG90KQpsaWJyYXJ5KGdnY29ycnBsb3QpCgpgYGAKCiMgUmVhZCBGaWxlCmBgYHtyfQppbmNvbWUgPC0gcmVhZC5jc3YoIlhZWiBMTEMgMjAyMSBQTC5jc3YiKQpgYGAKCiMgVmlldwpgYGB7cn0KI3ZpZXcgKGluY29tZSkKYGBgCgojIFN0cnVjdHVyZSBvZiB0aGUgRGF0YXNldApgYGB7cn0Kc3RyKGluY29tZSkKYGBgCgojIFJlbW92ZSBGaXJzdCAzIFJvd3MKYGBge3J9CmluY29tZSA8LSBpbmNvbWVbLWMoMTozKSwgXQpgYGAKCiMgVmlldwpgYGB7cn0KI3ZpZXcoaW5jb21lKQpgYGAKCiMgVmlldyBIZWFkZXJzCmBgYHtyfQpoZWFkKGluY29tZSkKYGBgCgojQ29sdW1uIE5hbWVzCmBgYHtyfQpwcmludChjb2xuYW1lcyhpbmNvbWUpKQpgYGAKCiNDb3VudCBNaXNzaW5nIFZhbHVlcyBpbiBFYWNoIENvbHVtbgpgYGB7cn0KcHJpbnQoc2FwcGx5KGluY29tZSwgZnVuY3Rpb24oeCkgc3VtKGlzLm5hKHgpKSkpCmBgYAojIEVsaW1pbmF0ZSB0aGUgTkEgUm93cwpgYGB7cn0KaW5jb21lIDwtIG5hLm9taXQoaW5jb21lKQpgYGAKCiMgVmlldwpgYGB7cn0KdmlldyhpbmNvbWUpCmBgYAoKIyBTdW1tYXJ5CmBgYHtyfQpzdW1tYXJ5KGluY29tZSkKYGBgCgojIFN0cnVjdHVyZSBvZiB0aGUgTmV3IERhdGFzZXQKYGBge3J9CnN0cihpbmNvbWUpCmBgYAoKIyBDaGFuZ2UgVGhlIGhlYWRlcnMgaW50byBhIGRhdGUgc3RydWN0dXJlCmBgYHtyfQpDb2xfaGVhZGVycyA8LSBzZXEoYXMuRGF0ZSgiMjAyMi0wMS0wMSIpLCBhcy5EYXRlKCIyMDIzLTA0LTAxIiksIGJ5ID0gIm1vbnRoIikKYGBgCgoKYGBge3J9Cm5hbWVzKGluY29tZSlbLTFdIDwtIGZvcm1hdChDb2xfaGVhZGVycywgIiVCICVZIikKYGBgCgojIEJhciBDaGFydApgYGB7cn0KIyBFeHRyYWN0IHRoZSAiTmV0IEluY29tZSIKbmV0X2luY29tZSA8LSBhcy5udW1lcmljKGluY29tZVtucm93KGluY29tZSksIC0xXSkKCiMgQ2FsY3VsYXRlIHRoZSBjb2xvciBvZiB0aGUgYmFycyAoZ3JlZW4gaWYgcG9zaXRpdmUsIHJlZCBpZiBuZWdhdGl2ZSkKY29sb3JzIDwtIGlmZWxzZShuZXRfaW5jb21lID49IDAsICJncmVlbiIsICJyZWQiKQoKIyBDcmVhdGUgdGhlIGJhciBwbG90CmJhcnBsb3QobmV0X2luY29tZSwgCiAgICAgICAgY29sID0gY29sb3JzLCAgIyBDb2xvciB0aGUgYmFycyBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgbmV0X2luY29tZQogICAgICAgIG1haW4gPSAiTmV0IEluY29tZSIsIAogICAgICAgIHhsYWIgPSAiRGF0ZSIsIAogICAgICAgIHlsYWIgPSAiTmV0IEluY29tZSIsCiAgICAgICAgbmFtZXMuYXJnID0gY29sbmFtZXMoaW5jb21lKVstMV0sICAjIFVzZSBkYXRlcyBhcyB4LWF4aXMgbGFiZWxzCiAgICAgICAgbGFzID0gMikgICMgUm90YXRlIHRoZSB4LWF4aXMgbGFiZWxzCgojIEFkZCBhIGxlZ2VuZApsZWdlbmQoInRvcHJpZ2h0IiwgCiAgICAgICBsZWdlbmQgPSBjKCJQb3NpdGl2ZSIsICJOZWdhdGl2ZSIpLCAKICAgICAgIGZpbGwgPSBjKCJncmVlbiIsICJyZWQiKSkKCmBgYAoKYGBge3J9CiMgQ3JlYXRlIHRoZSBiYXJwbG90CmJhcnBsb3QobmV0X2luY29tZSwgCiAgICAgICAgY29sID0gY29sb3JzLCAgIyBDb2xvciB0aGUgYmFycyBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgbmV0X2luY29tZQogICAgICAgIG1haW4gPSAiTmV0IEluY29tZSIsIAogICAgICAgIHhsYWIgPSAiRGF0ZSIsIAogICAgICAgIHlsYWIgPSAiTmV0IEluY29tZSIsCiAgICAgICAgbmFtZXMuYXJnID0gY29sbmFtZXMoaW5jb21lKVstMV0sICAjIFVzZSBkYXRlcyBhcyB4LWF4aXMgbGFiZWxzCiAgICAgICAgbGFzID0gMikgICMgUm90YXRlIHRoZSB4LWF4aXMgbGFiZWxzCgojIEFkZCBhIGxlZ2VuZApsZWdlbmQoInRvcHJpZ2h0IiwgCiAgICAgICBsZWdlbmQgPSBjKCJQb3NpdGl2ZSIsICJOZWdhdGl2ZSIpLCAKICAgICAgIGZpbGwgPSBjKCJncmVlbiIsICJyZWQiKSkKCiMgQ2FsY3VsYXRlIHRoZSB0ZW5kZW5jeSBsaW5lCnRlbmRlbmN5X2xpbmUgPC0gbG0obmV0X2luY29tZSB+IHNlcV9hbG9uZyhuZXRfaW5jb21lKSkKCiMgUGxvdCB0aGUgdGVuZGVuY3kgbGluZQphYmxpbmUodGVuZGVuY3lfbGluZSwgY29sID0gImJsdWUiLCBsdHkgPSAyKQpgYGAKCiNMaW5lIENoYXJ0CgpgYGB7cn0KIyBFeHRyYWN0IGNvbHVtbiBuYW1lcyAobW9udGhzKQptb250aF9uYW1lcyA8LSBjb2xuYW1lcyhpbmNvbWUpWy0xXSAgIyBFeGNsdWRlIHRoZSBmaXJzdCBjb2x1bW4gY29udGFpbmluZyB1bml0IG5hbWVzCgojIEV4dHJhY3QgdmFsdWVzIGZyb20gdGhlIFRvdGFsIFJlbnRhbCBJbmNvbWUgcm93IChleGNsdWRpbmcgdGhlIGZpcnN0IGNvbHVtbikKdG90YWxfaW5jb21lIDwtIGFzLm51bWVyaWMoaW5jb21lWzgsIC0xXSkKCiMgQ3JlYXRlIHRoZSBsaW5lIHBsb3QKcGxvdCgxOmxlbmd0aChtb250aF9uYW1lcyksIHRvdGFsX2luY29tZSwgdHlwZSA9ICJvIiwgCiAgICAgeGxhYiA9ICJNb250aHMiLCB5bGFiID0gIlRvdGFsIFJlbnRhbCBJbmNvbWUiLCAKICAgICBtYWluID0gIlRvdGFsIFJlbnRhbCBJbmNvbWUgcGVyIE1vbnRoIiwKICAgICB4YXh0ID0gIm4iKSAgIyBEaXNhYmxlIHgtYXhpcyBsYWJlbHMKCiMgQWRkIG1vbnRoIGxhYmVscyBvbiB0aGUgeC1heGlzCmF4aXMoMSwgYXQgPSAxOmxlbmd0aChtb250aF9uYW1lcyksIGxhYmVscyA9IG1vbnRoX25hbWVzLCBsYXMgPSAyKQoKCmBgYApgYGB7cn0KIyBFeHRyYWN0IGNvbHVtbiBuYW1lcyAobW9udGhzKQptb250aF9uYW1lcyA8LSBjb2xuYW1lcyhpbmNvbWUpWy0xXSAgIyBFeGNsdWRlIHRoZSBmaXJzdCBjb2x1bW4gY29udGFpbmluZyB1bml0IG5hbWVzCgojIEV4dHJhY3QgdmFsdWVzIGZyb20gdGhlIFRvdGFsIFJlbnRhbCBJbmNvbWUgcm93IChleGNsdWRpbmcgdGhlIGZpcnN0IGNvbHVtbikKdG90YWxfaW5jb21lIDwtIGFzLm51bWVyaWMoaW5jb21lWzgsIC0xXSkKCiMgQ3JlYXRlIHRoZSBsaW5lIHBsb3Qgd2l0aCBuaWNlciBhZXN0aGV0aWNzCnBsb3QoMTpsZW5ndGgobW9udGhfbmFtZXMpLCB0b3RhbF9pbmNvbWUsIHR5cGUgPSAibyIsIAogICAgIHhsYWIgPSAiTW9udGhzIiwgeWxhYiA9ICJUb3RhbCBSZW50YWwgSW5jb21lIChpbiBVU0QpIiwgCiAgICAgbWFpbiA9ICJUb3RhbCBSZW50YWwgSW5jb21lIHBlciBNb250aCIsCiAgICAgY29sID0gImJsdWUiLCAgICAgICAgICAgICMgTGluZSBjb2xvcgogICAgIHBjaCA9IDE2LCAgICAgICAgICAgICAgICAjIFBvaW50IHNoYXBlCiAgICAgbHdkID0gMiwgICAgICAgICAgICAgICAgICMgTGluZSB3aWR0aAogICAgIHlsaW0gPSBjKDAsIG1heCh0b3RhbF9pbmNvbWUpICogMS4xKSwgICMgQWRqdXN0IHktYXhpcyBsaW1pdHMKICAgICB4YXh0ID0gIm4iKSAgICAgICAgICAgICAgIyBEaXNhYmxlIHgtYXhpcyBsYWJlbHMKCiMgQWRkIG1vbnRoIGxhYmVscyBvbiB0aGUgeC1heGlzIHdpdGggcm90YXRlZCBsYWJlbHMKYXhpcygxLCBhdCA9IDE6bGVuZ3RoKG1vbnRoX25hbWVzKSwgbGFiZWxzID0gbW9udGhfbmFtZXMsIGxhcyA9IDIsIGNleC5heGlzID0gMC44KQoKIyBBZGQgZ3JpZGxpbmVzCmdyaWQoKQoKIyBBZGQgYSBsZWdlbmQKbGVnZW5kKCJ0b3ByaWdodCIsIAogICAgICAgbGVnZW5kID0gYygiVG90YWwgUmVudGFsIEluY29tZSIpLCAKICAgICAgIGNvbCA9ICJibHVlIiwgCiAgICAgICBsdHkgPSAxLCAKICAgICAgIHBjaCA9IDE2LCAKICAgICAgIGNleCA9IDAuOCwKICAgICAgIGJnID0gIndoaXRlIikKYGBgCgoKIyBCYXIgRXhwZW5zZXMgQ2hhcnQKYGBge3J9CiMgVHJhbnNwb25lciBlbCBjb25qdW50byBkZSBkYXRvcyBwYXJhIHF1ZSBsYXMgZmlsYXMgc2UgY29udmllcnRhbiBlbiBjb2x1bW5hcwp0cmFuc3Bvc2VkX2RhdGEgPC0gdChpbmNvbWUpCiN2aWV3KHRyYW5zcG9zZWRfZGF0YSkKYGBgCgpgYGB7cn0KY29sbmFtZXModHJhbnNwb3NlZF9kYXRhKSA8LSB0cmFuc3Bvc2VkX2RhdGFbMSwgXQp0cmFuc3Bvc2VkX2RhdGEgPC0gdHJhbnNwb3NlZF9kYXRhWy0xLCBdCmBgYAoKYGBge3J9CiN2aWV3KHRyYW5zcG9zZWRfZGF0YSkKYGBgCgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKCiMgU2VsZWN0IG9ubHkgdGhlIHJvd3MgY29ycmVzcG9uZGluZyB0byBleHBlbnNlcwpleHBlbnNlcyA8LSB0cmFuc3Bvc2VkX2RhdGFbLCBjKCJCcmlnaHQgU3RhciBDcmVkaXQgVW5pb24iLCAiQmFuayBDaGFyZ2VzIC0gT3RoZXIiLCAiVG90YWwgQ29tbWlzc2lvbiIsICJGaWxpbmcgRmVlcyIsIlRvdGFsIEVsZWN0cmljaXR5IiwgIlRvdGFsIFV0aWxpdGllcyIpXQoKIyBDb252ZXJ0IHRoZSBzZWxlY3RlZCBjb2x1bW5zIHRvIG51bWVyaWMKZXhwZW5zZXMgPC0gYXBwbHkoZXhwZW5zZXMsIDIsIGFzLm51bWVyaWMpCgojIENhbGN1bGF0ZSB0aGUgc3VtIG9mIGVhY2ggZXhwZW5zZSBjb2x1bW4KdG90YWxfZXhwZW5zZXMgPC0gY29sU3VtcyhleHBlbnNlcykKCiMgQ3JlYXRlIGEgZGF0YWZyYW1lIHdpdGggdGhlIGV4cGVuc2UgbmFtZXMgYW5kIHRoZWlyIHRvdGFscwpleHBlbnNlc19kZiA8LSBkYXRhLmZyYW1lKGV4cGVuc2UgPSBuYW1lcyh0b3RhbF9leHBlbnNlcyksIHRvdGFsID0gdG90YWxfZXhwZW5zZXMpCgojIENyZWF0ZSB0aGUgYmFyIHBsb3Qgd2l0aCBsYWJlbHMKZ2dwbG90KGV4cGVuc2VzX2RmLCBhZXMoeCA9IGV4cGVuc2UsIHkgPSB0b3RhbCwgbGFiZWwgPSB0b3RhbCkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJza3libHVlIikgKwogIGdlb21fdGV4dCh2anVzdCA9IC0wLjUsIHNpemUgPSAzKSArICAjIEFkZCBsYWJlbHMgYWJvdmUgdGhlIGJhcnMKICBsYWJzKHRpdGxlID0gIlRvdGFsIEV4cGVuc2VzIiwgeCA9ICJFeHBlbnNlIiwgeSA9ICJUb3RhbCIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICAjIFJvdGF0ZSB4LWF4aXMgbGFiZWxzIGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkKYGBgCmBgYHtyfQojIEVuc3VyZSBib3RoIGV4cGVuc2VzIGFuZCBuZXQgaW5jb21lIGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIG1vbnRocwpudW1fbW9udGhzIDwtIG1pbihsZW5ndGgobW9udGhfbmFtZXMpLCBsZW5ndGgodG90YWxfZXhwZW5zZXMpLCBsZW5ndGgodG90YWxfaW5jb21lKSkKCiMgQ29tYmluZSBleHBlbnNlcyBhbmQgbmV0IGluY29tZSBpbnRvIGEgc2luZ2xlIGRhdGFmcmFtZQpjb21iaW5lZF9kYXRhIDwtIGRhdGEuZnJhbWUoCiAgTW9udGggPSBtb250aF9uYW1lc1sxOm51bV9tb250aHNdLAogIEV4cGVuc2VzID0gdG90YWxfZXhwZW5zZXNbMTpudW1fbW9udGhzXSwKICBOZXRfSW5jb21lID0gdG90YWxfaW5jb21lWzE6bnVtX21vbnRoc10KKQoKIyBNZWx0IHRoZSBkYXRhIGZvciBlYXNpZXIgcGxvdHRpbmcKY29tYmluZWRfZGF0YSA8LSBtZWx0KGNvbWJpbmVkX2RhdGEsIGlkLnZhcnMgPSAiTW9udGgiKQoKIyBDcmVhdGUgdGhlIGNvbWJpbmVkIGJhciBwbG90CmdncGxvdChjb21iaW5lZF9kYXRhLCBhZXMoeCA9IE1vbnRoLCB5ID0gdmFsdWUsIGZpbGwgPSB2YXJpYWJsZSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZG9kZ2UiKSArCiAgbGFicyh0aXRsZSA9ICJFeHBlbnNlcyB2cyBOZXQgSW5jb21lIiwgeCA9ICJNb250aCIsIHkgPSAiQW1vdW50IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIkV4cGVuc2VzIiA9ICJza3libHVlIiwgIk5ldF9JbmNvbWUiID0gImdyZWVuIiksIAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkV4cGVuc2VzIiwgIk5ldCBJbmNvbWUiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgICMgUm90YXRlIHgtYXhpcyBsYWJlbHMgZm9yIGJldHRlciByZWFkYWJpbGl0eQoKCmBgYAoKYGBge3J9CiMgRXh0cmFjdCByZWxldmFudCB2YXJpYWJsZXMgKGV4cGVuc2VzIGFuZCBpbmNvbWUgb2YgdGhlIHVuaXRzKQpleHBlbnNlcyA8LSB0cmFuc3Bvc2VkX2RhdGFbLCBjKCJCcmlnaHQgU3RhciBDcmVkaXQgVW5pb24iLCAiQmFuayBDaGFyZ2VzIC0gT3RoZXIiLCAiVG90YWwgQ29tbWlzc2lvbiIsICJGaWxpbmcgRmVlcyIsICJUb3RhbCBFbGVjdHJpY2l0eSIsICJUb3RhbCBVdGlsaXRpZXMiKV0KaW5jb21lX3VuaXRzIDwtIHRyYW5zcG9zZWRfZGF0YVssIGMoIlVuaXQgMTExNSIsICJVbml0IDExMjYiLCAiVW5pdCAxMjE1IildIApgYGAKCmBgYHtyfQojVmlldyhpbmNvbWVfdW5pdHMpCmBgYAoKCgpgYGB7cn0KZXhwZW5zZXMgPC0gYXBwbHkoZXhwZW5zZXMsIDIsIGFzLm51bWVyaWMpCmluY29tZV91bml0cyA8LSBhcHBseShpbmNvbWVfdW5pdHMsIDIsIGFzLm51bWVyaWMpCmBgYAoKYGBge3J9CiMgQ2FsY3VsYXRlIG5ldCBpbmNvbWUgKHRvdGFsIGluY29tZSAtIHRvdGFsIGV4cGVuc2VzKQpuZXRfaW5jb21lIDwtIHJvd1N1bXMoaW5jb21lX3VuaXRzKSAtIHJvd1N1bXMoZXhwZW5zZXMpCmBgYAoKCmBgYHtyfQojIENyZWF0ZSBhIGRhdGEgZnJhbWUgd2l0aCBwcmVkaWN0b3IgdmFyaWFibGVzIChleHBlbnNlcyBhbmQgaW5jb21lIG9mIHRoZSB1bml0cykgYW5kIHRoZSB0YXJnZXQgdmFyaWFibGUgKG5ldCBpbmNvbWUpCm1vZGVsX2RhdGEgPC0gY2JpbmQoZXhwZW5zZXMsIGluY29tZV91bml0cywgbmV0X2luY29tZSkKY29sbmFtZXMobW9kZWxfZGF0YSkgPC0gYygiQnJpZ2h0X1N0YXJfQ3JlZGl0X1VuaW9uIiwgIkJhbmtfQ2hhcmdlc19PdGhlciIsICJUb3RhbF9Db21taXNzaW9uIiwgIkZpbGluZ19GZWVzIiwgIlRvdGFsX0VsZWN0cmljaXR5IiwgIlRvdGFsX1V0aWxpdGllcyIsICJVbml0XzExMTUiLCAiVW5pdF8xMTI2IiwgIlVuaXRfMTIxNSIsICJOZXRfSW5jb21lIikKYGBgCgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoImNhcmV0IikKbGlicmFyeShjYXJldCkKYGBgCmBgYHtyfQpjbGFzcyhtb2RlbF9kYXRhKQpgYGAKYGBge3J9CmlmICghaW5oZXJpdHMobW9kZWxfZGF0YSwgImRhdGEuZnJhbWUiKSkgewogIG1vZGVsX2RhdGEgPC0gYXMuZGF0YS5mcmFtZShtb2RlbF9kYXRhKQp9CmBgYAoKCgpgYGB7cn0KIyBTcGxpdCB0aGUgZGF0YSBpbnRvIHRyYWluaW5nIGFuZCB0ZXN0aW5nIHNldHMgKDgwJSB0cmFpbmluZywgMjAlIHRlc3RpbmcpCnNldC5zZWVkKDEyMykgIyBmb3IgcmVwcm9kdWNpYmlsaXR5CnRyYWluX2luZGV4IDwtIGNyZWF0ZURhdGFQYXJ0aXRpb24obW9kZWxfZGF0YSROZXRfSW5jb21lLCBwID0gMC44LCBsaXN0ID0gRkFMU0UpCnRyYWluX2RhdGEgPC0gbW9kZWxfZGF0YVt0cmFpbl9pbmRleCwgXQp0ZXN0X2RhdGEgPC0gbW9kZWxfZGF0YVstdHJhaW5faW5kZXgsIF0KYGBgCgoKYGBge3J9CiMgQnVpbGQgYSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbApuZXRfaW5jb21lX21vZGVsIDwtIGxtKE5ldF9JbmNvbWUgfiAuLCBkYXRhID0gdHJhaW5fZGF0YSkKYGBgCgoKCmBgYHtyfQojIEV2YWx1YXRlIHRoZSBtb2RlbApzdW1tYXJ5KG5ldF9pbmNvbWVfbW9kZWwpCmBgYApgYGB7cn0KIyBNYWtlIHByZWRpY3Rpb25zIG9uIHRoZSB0ZXN0aW5nIHNldApwcmVkaWN0aW9ucyA8LSBwcmVkaWN0KG5ldF9pbmNvbWVfbW9kZWwsIG5ld2RhdGEgPSB0ZXN0X2RhdGEpCmBgYAoKCmBgYHtyfQojIEV2YWx1YXRlIG1vZGVsIHBlcmZvcm1hbmNlIChlLmcuLCBSTVNFLCBSLXNxdWFyZWQpCnJtc2UgPC0gc3FydChtZWFuKCh0ZXN0X2RhdGEkTmV0X0luY29tZSAtIHByZWRpY3Rpb25zKV4yKSkKcnNxdWFyZWQgPC0gY29yKHRlc3RfZGF0YSROZXRfSW5jb21lLCBwcmVkaWN0aW9ucyleMgpgYGAKCgpgYGB7cn0KIyBQcmludCBSTVNFIGFuZCBSLXNxdWFyZWQKcHJpbnQocGFzdGUoIlJNU0U6Iiwgcm1zZSkpCnByaW50KHBhc3RlKCJSLXNxdWFyZWQ6IiwgcnNxdWFyZWQpKQpgYGAKCmBgYHtyfQojIENhbGN1bGF0ZSByZXNpZHVhbHMKcmVzaWR1YWxzIDwtIHJlc2lkdWFscyhuZXRfaW5jb21lX21vZGVsKQpgYGAKCmBgYHtyfQpwcmVkaWN0ZWRfdmFsdWVzIDwtIHByZWRpY3QobmV0X2luY29tZV9tb2RlbCkKYGBgCgoKYGBge3J9CiMgQ3JlYXRlIHJlc2lkdWFsIHBsb3QKcGxvdChwcmVkaWN0ZWRfdmFsdWVzLCByZXNpZHVhbHMsIAogICAgIHhsYWIgPSAiUHJlZGljdGVkIFZhbHVlcyIsIHlsYWIgPSAiUmVzaWR1YWxzIiwKICAgICBtYWluID0gIlJlc2lkdWFsIFBsb3QiKQphYmxpbmUoaCA9IDAsIGNvbCA9ICJyZWQiKSAgIyBBZGQgaG9yaXpvbnRhbCBsaW5lIGF0IHkgPSAwCmBgYAoKYGBge3J9CiMgQ3JlYXRlIFFRIHBsb3QKcXFub3JtKHJlc2lkdWFscykKcXFsaW5lKHJlc2lkdWFscykKYGBgCmBgYHtyfQp2YXJJbXAobmV0X2luY29tZV9tb2RlbCkKYGBgCgpgYGB7cn0KCmBgYApgYGB7cn0KIyBFbnN1cmUgYm90aCBleHBlbnNlcyBhbmQgbmV0IGluY29tZSBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBtb250aHMKbnVtX21vbnRocyA8LSBtaW4obGVuZ3RoKG1vbnRoX25hbWVzKSwgbGVuZ3RoKHRvdGFsX2V4cGVuc2VzKSwgbGVuZ3RoKHRvdGFsX2luY29tZSkpCgojIENvbWJpbmUgZXhwZW5zZXMgYW5kIG5ldCBpbmNvbWUgaW50byBhIHNpbmdsZSBkYXRhZnJhbWUKY29tYmluZWRfZGF0YSA8LSBkYXRhLmZyYW1lKAogIE1vbnRoID0gbW9udGhfbmFtZXNbMTpudW1fbW9udGhzXSwKICBFeHBlbnNlcyA9IHRvdGFsX2V4cGVuc2VzWzE6bnVtX21vbnRoc10sCiAgTmV0X0luY29tZSA9IHRvdGFsX2luY29tZVsxOm51bV9tb250aHNdCikKCiMgQ2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIGV4cGVuc2VzIG92ZXIgbmV0IGluY29tZQpjb21iaW5lZF9kYXRhJEV4cGVuc2VfUGVyY2VudGFnZSA8LSAoY29tYmluZWRfZGF0YSRFeHBlbnNlcyAvIGNvbWJpbmVkX2RhdGEkTmV0X0luY29tZSkgKiAxMDAKCiMgTWVsdCB0aGUgZGF0YSBmb3IgZWFzaWVyIHBsb3R0aW5nCmNvbWJpbmVkX2RhdGEgPC0gbWVsdChjb21iaW5lZF9kYXRhLCBpZC52YXJzID0gYygiTW9udGgiLCAiRXhwZW5zZV9QZXJjZW50YWdlIikpCgojIENyZWF0ZSB0aGUgY29tYmluZWQgYmFyIHBsb3Qgd2l0aCBwZXJjZW50YWdlIGxhYmVscwpnZ3Bsb3QoY29tYmluZWRfZGF0YSwgYWVzKHggPSBNb250aCwgeSA9IHZhbHVlLCBmaWxsID0gdmFyaWFibGUpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gImRvZGdlIikgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBwYXN0ZShyb3VuZChFeHBlbnNlX1BlcmNlbnRhZ2UsIDEpLCAiJSIpKSwgCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSwgCiAgICAgICAgICAgIHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDMpICsgICMgQWRkIHBlcmNlbnRhZ2UgbGFiZWxzIGFib3ZlIHRoZSBiYXJzCiAgbGFicyh0aXRsZSA9ICJFeHBlbnNlcyB2cyBOZXQgSW5jb21lIiwgeCA9ICJNb250aCIsIHkgPSAiQW1vdW50IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIkV4cGVuc2VzIiA9ICJza3libHVlIiwgIk5ldF9JbmNvbWUiID0gImdyZWVuIiksIAogICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIkV4cGVuc2VzIiwgIk5ldCBJbmNvbWUiKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgICMgUm90YXRlIHgtYXhpcyBsYWJlbHMgZm9yIGJldHRlciByZWFkYWJpbGl0eQoKYGBgCgo=