Data Filtering Criteria for Tandem A in 2023-2024 Harvest Season.

Libraries

library(dplyr)
library(pastecs)
library(ggplot2)
library(lares)

Scatter Plot Function

mapa_dispersion <- function(label_x,label_y,dataset) {
  correlacion <- round(cor(dataset[[label_x]],dataset[[label_y]]),2)
  ggplot(dataset, aes(.data[[label_x]], .data[[label_y]])) + 
    geom_point(
        color="orange",
        fill="#69b3a2",
        shape=21,
        alpha=0.5,
        size=6,
        stroke = 2
        ) +
    geom_smooth(method=lm , color="#990000", fill="#FFCF00", se=TRUE) +
    ggtitle(paste(label_y,"vrs.",label_x), subtitle = paste("Correlation: ",correlacion)) +
  xlab(label_x) + ylab(label_y)
}

Mill 1 TA Dataset

df_TA <- read.csv(file = 'Mill_1_TA.csv')

df_TA

Density Function: Mill 1 TA Speed (rpm)


# PDF
distr(df_TA,'ST55M101')


# Boxplot
ggplot(df_TA, aes(y=ST55M101)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "ST55M101 (rpm)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$ST55M101))
NA

Density Function: Mill 1 TA Torque (N*m)


# PDF
distr(df_TA,'TQ55M101')


# Boxplot
ggplot(df_TA, aes(y=TQ55M101)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "TQ55M101 (N*m)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$TQ55M101))
NA

Density Function: Mill 1 TA Power (kW)


# PDF
distr(df_TA,'JT55M101')


# Boxplot
ggplot(df_TA, aes(y=JT55M101)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "JT55M101 (kW)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$JT55M101))
NA

Density Function: Mill 1 TA Level (%)


# PDF
distr(df_TA,'LT55M101')


# Boxplot
ggplot(df_TA, aes(y=LT55M101)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "LT55M101 (%)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$LT55M101))
NA

Density Function: TA Bagasse Mass Flow (t/h)


# PDF
distr(df_TA,'WT555801')


# Boxplot
ggplot(df_TA, aes(y=WT555801)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "WT555801 (t/h)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA$WT555801))
NA

Filtering Criteria:

We first need to exclude any intentional or planned downtime of TA. This can be done by filtering the left tail of the Torque (TQ55M101) and Speed (ST55M101) distributions of the Mill 1 T, since the Mill stops completely.

We also need to filter out any unintentional or unplanned downtime of TA. This can be done by filtering the left tail of the bagasse mass flow of TA. This works because for unplanned downtime usually the first mill does not stop (because of the uncertainty of the duration of the stop). Also we can estimate the sugar cane crush rate by the bagasse mass flow coming out of the tandem (WT555801).

Scatter Plots and Correlations

Torque and Bagasse Relation Mill 1 TA

label_x <- "WT555801"
label_y <- "TQ55M101"

mapa_dispersion(label_x,label_y,df_TA)

Torque and Bagasse Mass Flow are correlated, but not perfectly. So we need to filter out observations based on these variables individually.

Torque and Power Relation Mill 1 TA

label_x <- "JT55M101"
label_y <- "TQ55M101"

mapa_dispersion(label_x,label_y,df_TA)

Torque and Mill Power are strongly correlated, almost perfectly. So there is no need to filter out observations based on these variables individually. We choose Torque since it contains information about Power and Speed simultaneously.

WT5557801 Quantiles

# Filter Dataset by Column Values:
res<-quantile(df_TA$WT555801, probs = c(0,0.25,0.5,0.75,1)) 
res
       0%       25%       50%       75%      100% 
 21.56174 132.91532 147.77292 158.52945 183.46936 

TQ55M101 Quantiles

# Filter Dataset by Column Values:
res<-quantile(df_TA$TQ55M101, probs = c(0,0.25,0.5,0.75,1)) 
res
       0%       25%       50%       75%      100% 
 226.5511 1869.4912 2092.0420 2283.7543 2579.5171 

ST55M101 Quantiles

# Filter Dataset by Column Values:
res<-quantile(df_TA$ST55M101, probs = c(0,0.25,0.5,0.75,1)) 
res
      0%      25%      50%      75%     100% 
172.5349 702.7378 746.5287 774.9827 999.9883 
# Filter Dataset by Column Values:
df_TA_filtered <- df_TA[df_TA$WT555801>=130,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) : 
  invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) : 
  attempt to use zero-length variable name
df_TA_filtered <- df_TA_filtered[df_TA_filtered$TQ55M101>=1800,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) : 
  invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) : 
  attempt to use zero-length variable name
df_TA_filtered <- df_TA_filtered[df_TA_filtered$ST55M101>=700,] # Filter by Minimum Threshold of 1st Quartile
Error in exists(cacheKey, where = .rs.WorkingDataEnv, inherits = FALSE) : 
  invalid first argument
Error in assign(cacheKey, frame, .rs.CachedDataEnv) : 
  attempt to use zero-length variable name
df_TA_filtered

Torque and Bagasse Relation Mill 1 TA (Filtered Dataset)

label_x <- "WT555801"
label_y <- "TQ55M101"

mapa_dispersion(label_x,label_y,df_TA_filtered)

Density Function: TA Bagasse Mass Flow (t/h) Filtered Distribution


# PDF
distr(df_TA_filtered,'WT555801')


# Boxplot
ggplot(df_TA_filtered, aes(y=WT555801)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "WT555801 (t/h)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$WT555801))
NA

Density Function: Mill 1 TA Torque (t/h) Filtered Distribution


# PDF
distr(df_TA_filtered,'TQ55M101')


# Boxplot
ggplot(df_TA_filtered, aes(y=WT555801)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "TQ55M101 (t/h)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$TQ55M101))
NA

Density Function: Mill 1 TA Speed (rpm) Filtered Distribution


# PDF
distr(df_TA_filtered,'ST55M101')


# Boxplot
ggplot(df_TA_filtered, aes(y=ST55M101)) + 
    geom_boxplot( 
        # custom boxes
        color="blue",
        fill="blue",
        alpha=0.2,
        
        # Notch
        notch=TRUE,
        notchwidth = 0.8,
        
        # custom outliers
        outlier.colour="red",
        outlier.fill="red",
        outlier.size=3) +
  scale_x_discrete() +
  labs(title="Boxplot",x="", y = "ST55M101 (rpm)")


# Descriptive Statistics
data.frame(Estadistica=stat.desc(df_TA_filtered$ST55M101))
NA

Filter Criteria

Filter out any points for which:

LS0tDQp0aXRsZTogIlRhbmRlbSBBIERhdGEgRmlsdGVyaW5nIENyaXRlcmlhIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMjIERhdGEgRmlsdGVyaW5nIENyaXRlcmlhIGZvciBUYW5kZW0gQSBpbiAqKjIwMjMtMjAyNCBIYXJ2ZXN0IFNlYXNvbioqLg0KDQpMaWJyYXJpZXMNCmBgYHtyfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocGFzdGVjcykNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkobGFyZXMpDQpgYGANCg0KDQojIyMgU2NhdHRlciBQbG90IEZ1bmN0aW9uDQpgYGB7cn0NCm1hcGFfZGlzcGVyc2lvbiA8LSBmdW5jdGlvbihsYWJlbF94LGxhYmVsX3ksZGF0YXNldCkgew0KICBjb3JyZWxhY2lvbiA8LSByb3VuZChjb3IoZGF0YXNldFtbbGFiZWxfeF1dLGRhdGFzZXRbW2xhYmVsX3ldXSksMikNCiAgZ2dwbG90KGRhdGFzZXQsIGFlcyguZGF0YVtbbGFiZWxfeF1dLCAuZGF0YVtbbGFiZWxfeV1dKSkgKyANCiAgICBnZW9tX3BvaW50KA0KICAgICAgICBjb2xvcj0ib3JhbmdlIiwNCiAgICAgICAgZmlsbD0iIzY5YjNhMiIsDQogICAgICAgIHNoYXBlPTIxLA0KICAgICAgICBhbHBoYT0wLjUsDQogICAgICAgIHNpemU9NiwNCiAgICAgICAgc3Ryb2tlID0gMg0KICAgICAgICApICsNCiAgICBnZW9tX3Ntb290aChtZXRob2Q9bG0gLCBjb2xvcj0iIzk5MDAwMCIsIGZpbGw9IiNGRkNGMDAiLCBzZT1UUlVFKSArDQogICAgZ2d0aXRsZShwYXN0ZShsYWJlbF95LCJ2cnMuIixsYWJlbF94KSwgc3VidGl0bGUgPSBwYXN0ZSgiQ29ycmVsYXRpb246ICIsY29ycmVsYWNpb24pKSArDQogIHhsYWIobGFiZWxfeCkgKyB5bGFiKGxhYmVsX3kpDQp9DQpgYGANCg0KIyMjIE1pbGwgMSBUQSBEYXRhc2V0DQpgYGB7cn0NCmRmX1RBIDwtIHJlYWQuY3N2KGZpbGUgPSAnTWlsbF8xX1RBLmNzdicpDQoNCmRmX1RBDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBTcGVlZCAocnBtKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnU1Q1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9U1Q1NU0xMDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiU1Q1NU0xMDEgKHJwbSkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBJFNUNTVNMTAxKSkNCg0KYGBgDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBNaWxsIDEgVEEgVG9ycXVlIChOKm0pDQpgYGB7cn0NCg0KIyBQREYNCmRpc3RyKGRmX1RBLCdUUTU1TTEwMScpDQoNCiMgQm94cGxvdA0KZ2dwbG90KGRmX1RBLCBhZXMoeT1UUTU1TTEwMSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCANCiAgICAgICAgIyBjdXN0b20gYm94ZXMNCiAgICAgICAgY29sb3I9ImJsdWUiLA0KICAgICAgICBmaWxsPSJibHVlIiwNCiAgICAgICAgYWxwaGE9MC4yLA0KICAgICAgICANCiAgICAgICAgIyBOb3RjaA0KICAgICAgICBub3RjaD1UUlVFLA0KICAgICAgICBub3RjaHdpZHRoID0gMC44LA0KICAgICAgICANCiAgICAgICAgIyBjdXN0b20gb3V0bGllcnMNCiAgICAgICAgb3V0bGllci5jb2xvdXI9InJlZCIsDQogICAgICAgIG91dGxpZXIuZmlsbD0icmVkIiwNCiAgICAgICAgb3V0bGllci5zaXplPTMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgpICsNCiAgbGFicyh0aXRsZT0iQm94cGxvdCIseD0iIiwgeSA9ICJUUTU1TTEwMSAoTiptKSIpDQoNCiMgRGVzY3JpcHRpdmUgU3RhdGlzdGljcw0KZGF0YS5mcmFtZShFc3RhZGlzdGljYT1zdGF0LmRlc2MoZGZfVEEkVFE1NU0xMDEpKQ0KDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBQb3dlciAoa1cpDQpgYGB7cn0NCg0KIyBQREYNCmRpc3RyKGRmX1RBLCdKVDU1TTEwMScpDQoNCiMgQm94cGxvdA0KZ2dwbG90KGRmX1RBLCBhZXMoeT1KVDU1TTEwMSkpICsgDQogICAgZ2VvbV9ib3hwbG90KCANCiAgICAgICAgIyBjdXN0b20gYm94ZXMNCiAgICAgICAgY29sb3I9ImJsdWUiLA0KICAgICAgICBmaWxsPSJibHVlIiwNCiAgICAgICAgYWxwaGE9MC4yLA0KICAgICAgICANCiAgICAgICAgIyBOb3RjaA0KICAgICAgICBub3RjaD1UUlVFLA0KICAgICAgICBub3RjaHdpZHRoID0gMC44LA0KICAgICAgICANCiAgICAgICAgIyBjdXN0b20gb3V0bGllcnMNCiAgICAgICAgb3V0bGllci5jb2xvdXI9InJlZCIsDQogICAgICAgIG91dGxpZXIuZmlsbD0icmVkIiwNCiAgICAgICAgb3V0bGllci5zaXplPTMpICsNCiAgc2NhbGVfeF9kaXNjcmV0ZSgpICsNCiAgbGFicyh0aXRsZT0iQm94cGxvdCIseD0iIiwgeSA9ICJKVDU1TTEwMSAoa1cpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRKVDU1TTEwMSkpDQoNCmBgYA0KDQojIyMgRGVuc2l0eSBGdW5jdGlvbjogTWlsbCAxIFRBIExldmVsICglKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnTFQ1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9TFQ1NU0xMDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiTFQ1NU0xMDEgKCUpIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQSRMVDU1TTEwMSkpDQoNCmBgYA0KDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBUQSBCYWdhc3NlIE1hc3MgRmxvdyAodC9oKQ0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQSwnV1Q1NTU4MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQSwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiV1Q1NTU4MDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBJFdUNTU1ODAxKSkNCg0KYGBgDQoNCiMjIEZpbHRlcmluZyBDcml0ZXJpYToNCldlIGZpcnN0IG5lZWQgdG8gZXhjbHVkZSBhbnkgaW50ZW50aW9uYWwgb3IgcGxhbm5lZCBkb3dudGltZSBvZiBUQS4gVGhpcyBjYW4gYmUgZG9uZSBieSBmaWx0ZXJpbmcgdGhlIGxlZnQgdGFpbCBvZiB0aGUgVG9ycXVlIChUUTU1TTEwMSkgYW5kIFNwZWVkIChTVDU1TTEwMSkgZGlzdHJpYnV0aW9ucyBvZiB0aGUgTWlsbCAxIFQsIHNpbmNlIHRoZSBNaWxsIHN0b3BzIGNvbXBsZXRlbHkuDQoNCldlIGFsc28gbmVlZCB0byBmaWx0ZXIgb3V0IGFueSB1bmludGVudGlvbmFsIG9yIHVucGxhbm5lZCBkb3dudGltZSBvZiBUQS4gVGhpcyBjYW4gYmUgZG9uZSBieSBmaWx0ZXJpbmcgdGhlIGxlZnQgdGFpbCBvZiB0aGUgYmFnYXNzZSBtYXNzIGZsb3cgb2YgVEEuIFRoaXMgd29ya3MgYmVjYXVzZSBmb3IgdW5wbGFubmVkIGRvd250aW1lIHVzdWFsbHkgdGhlIGZpcnN0IG1pbGwgZG9lcyBub3Qgc3RvcCAoYmVjYXVzZSBvZiB0aGUgdW5jZXJ0YWludHkgb2YgdGhlIGR1cmF0aW9uIG9mIHRoZSBzdG9wKS4gQWxzbyB3ZSBjYW4gZXN0aW1hdGUgdGhlIHN1Z2FyIGNhbmUgY3J1c2ggcmF0ZSBieSB0aGUgYmFnYXNzZSBtYXNzIGZsb3cgY29taW5nIG91dCBvZiB0aGUgdGFuZGVtIChXVDU1NTgwMSkuDQoNCg0KIyMjIFNjYXR0ZXIgUGxvdHMgYW5kIENvcnJlbGF0aW9ucw0KDQoqKlRvcnF1ZSBhbmQgQmFnYXNzZSBSZWxhdGlvbiBNaWxsIDEgVEEqKg0KYGBge3J9DQpsYWJlbF94IDwtICJXVDU1NTgwMSINCmxhYmVsX3kgPC0gIlRRNTVNMTAxIg0KDQptYXBhX2Rpc3BlcnNpb24obGFiZWxfeCxsYWJlbF95LGRmX1RBKQ0KYGBgDQpUb3JxdWUgYW5kIEJhZ2Fzc2UgTWFzcyBGbG93IGFyZSBjb3JyZWxhdGVkLCBidXQgbm90IHBlcmZlY3RseS4gU28gd2UgbmVlZCB0byBmaWx0ZXIgb3V0IG9ic2VydmF0aW9ucyBiYXNlZCBvbiB0aGVzZSB2YXJpYWJsZXMgaW5kaXZpZHVhbGx5Lg0KDQoqKlRvcnF1ZSBhbmQgUG93ZXIgUmVsYXRpb24gTWlsbCAxIFRBKioNCmBgYHtyfQ0KbGFiZWxfeCA8LSAiSlQ1NU0xMDEiDQpsYWJlbF95IDwtICJUUTU1TTEwMSINCg0KbWFwYV9kaXNwZXJzaW9uKGxhYmVsX3gsbGFiZWxfeSxkZl9UQSkNCmBgYA0KVG9ycXVlIGFuZCBNaWxsIFBvd2VyIGFyZSBzdHJvbmdseSBjb3JyZWxhdGVkLCBhbG1vc3QgcGVyZmVjdGx5LiBTbyB0aGVyZSBpcyBubyBuZWVkIHRvIGZpbHRlciBvdXQgb2JzZXJ2YXRpb25zIGJhc2VkIG9uIHRoZXNlIHZhcmlhYmxlcyBpbmRpdmlkdWFsbHkuIFdlIGNob29zZSBUb3JxdWUgc2luY2UgaXQgY29udGFpbnMgaW5mb3JtYXRpb24gYWJvdXQgUG93ZXIgYW5kIFNwZWVkIHNpbXVsdGFuZW91c2x5Lg0KDQojIyMgV1Q1NTU3ODAxIFF1YW50aWxlcw0KYGBge3J9DQojIEZpbHRlciBEYXRhc2V0IGJ5IENvbHVtbiBWYWx1ZXM6DQpyZXM8LXF1YW50aWxlKGRmX1RBJFdUNTU1ODAxLCBwcm9icyA9IGMoMCwwLjI1LDAuNSwwLjc1LDEpKSANCnJlcw0KYGBgDQojIyMgVFE1NU0xMDEgUXVhbnRpbGVzDQpgYGB7cn0NCiMgRmlsdGVyIERhdGFzZXQgYnkgQ29sdW1uIFZhbHVlczoNCnJlczwtcXVhbnRpbGUoZGZfVEEkVFE1NU0xMDEsIHByb2JzID0gYygwLDAuMjUsMC41LDAuNzUsMSkpIA0KcmVzDQpgYGANCiMjIyBTVDU1TTEwMSBRdWFudGlsZXMNCmBgYHtyfQ0KIyBGaWx0ZXIgRGF0YXNldCBieSBDb2x1bW4gVmFsdWVzOg0KcmVzPC1xdWFudGlsZShkZl9UQSRTVDU1TTEwMSwgcHJvYnMgPSBjKDAsMC4yNSwwLjUsMC43NSwxKSkgDQpyZXMNCmBgYA0KDQoNCmBgYHtyfQ0KIyBGaWx0ZXIgRGF0YXNldCBieSBDb2x1bW4gVmFsdWVzOg0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFbZGZfVEEkV1Q1NTU4MDE+PTEzMCxdICMgRmlsdGVyIGJ5IE1pbmltdW0gVGhyZXNob2xkIG9mIDFzdCBRdWFydGlsZQ0KZGZfVEFfZmlsdGVyZWQgPC0gZGZfVEFfZmlsdGVyZWRbZGZfVEFfZmlsdGVyZWQkVFE1NU0xMDE+PTE4MDAsXSAjIEZpbHRlciBieSBNaW5pbXVtIFRocmVzaG9sZCBvZiAxc3QgUXVhcnRpbGUNCmRmX1RBX2ZpbHRlcmVkIDwtIGRmX1RBX2ZpbHRlcmVkW2RmX1RBX2ZpbHRlcmVkJFNUNTVNMTAxPj03MDAsXSAjIEZpbHRlciBieSBNaW5pbXVtIFRocmVzaG9sZCBvZiAxc3QgUXVhcnRpbGUNCmRmX1RBX2ZpbHRlcmVkDQpgYGANCg0KKipUb3JxdWUgYW5kIEJhZ2Fzc2UgUmVsYXRpb24gTWlsbCAxIFRBIChGaWx0ZXJlZCBEYXRhc2V0KSoqDQpgYGB7cn0NCmxhYmVsX3ggPC0gIldUNTU1ODAxIg0KbGFiZWxfeSA8LSAiVFE1NU0xMDEiDQoNCm1hcGFfZGlzcGVyc2lvbihsYWJlbF94LGxhYmVsX3ksZGZfVEFfZmlsdGVyZWQpDQpgYGANCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IFRBIEJhZ2Fzc2UgTWFzcyBGbG93ICh0L2gpIEZpbHRlcmVkIERpc3RyaWJ1dGlvbg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQV9maWx0ZXJlZCwnV1Q1NTU4MDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQV9maWx0ZXJlZCwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiV1Q1NTU4MDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBX2ZpbHRlcmVkJFdUNTU1ODAxKSkNCg0KYGBgDQoNCiMjIyBEZW5zaXR5IEZ1bmN0aW9uOiBNaWxsIDEgVEEgVG9ycXVlICh0L2gpIEZpbHRlcmVkIERpc3RyaWJ1dGlvbg0KYGBge3J9DQoNCiMgUERGDQpkaXN0cihkZl9UQV9maWx0ZXJlZCwnVFE1NU0xMDEnKQ0KDQojIEJveHBsb3QNCmdncGxvdChkZl9UQV9maWx0ZXJlZCwgYWVzKHk9V1Q1NTU4MDEpKSArIA0KICAgIGdlb21fYm94cGxvdCggDQogICAgICAgICMgY3VzdG9tIGJveGVzDQogICAgICAgIGNvbG9yPSJibHVlIiwNCiAgICAgICAgZmlsbD0iYmx1ZSIsDQogICAgICAgIGFscGhhPTAuMiwNCiAgICAgICAgDQogICAgICAgICMgTm90Y2gNCiAgICAgICAgbm90Y2g9VFJVRSwNCiAgICAgICAgbm90Y2h3aWR0aCA9IDAuOCwNCiAgICAgICAgDQogICAgICAgICMgY3VzdG9tIG91dGxpZXJzDQogICAgICAgIG91dGxpZXIuY29sb3VyPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLmZpbGw9InJlZCIsDQogICAgICAgIG91dGxpZXIuc2l6ZT0zKSArDQogIHNjYWxlX3hfZGlzY3JldGUoKSArDQogIGxhYnModGl0bGU9IkJveHBsb3QiLHg9IiIsIHkgPSAiVFE1NU0xMDEgKHQvaCkiKQ0KDQojIERlc2NyaXB0aXZlIFN0YXRpc3RpY3MNCmRhdGEuZnJhbWUoRXN0YWRpc3RpY2E9c3RhdC5kZXNjKGRmX1RBX2ZpbHRlcmVkJFRRNTVNMTAxKSkNCg0KYGBgDQoNCg0KIyMjIERlbnNpdHkgRnVuY3Rpb246IE1pbGwgMSBUQSBTcGVlZCAocnBtKSBGaWx0ZXJlZCBEaXN0cmlidXRpb24NCmBgYHtyfQ0KDQojIFBERg0KZGlzdHIoZGZfVEFfZmlsdGVyZWQsJ1NUNTVNMTAxJykNCg0KIyBCb3hwbG90DQpnZ3Bsb3QoZGZfVEFfZmlsdGVyZWQsIGFlcyh5PVNUNTVNMTAxKSkgKyANCiAgICBnZW9tX2JveHBsb3QoIA0KICAgICAgICAjIGN1c3RvbSBib3hlcw0KICAgICAgICBjb2xvcj0iYmx1ZSIsDQogICAgICAgIGZpbGw9ImJsdWUiLA0KICAgICAgICBhbHBoYT0wLjIsDQogICAgICAgIA0KICAgICAgICAjIE5vdGNoDQogICAgICAgIG5vdGNoPVRSVUUsDQogICAgICAgIG5vdGNod2lkdGggPSAwLjgsDQogICAgICAgIA0KICAgICAgICAjIGN1c3RvbSBvdXRsaWVycw0KICAgICAgICBvdXRsaWVyLmNvbG91cj0icmVkIiwNCiAgICAgICAgb3V0bGllci5maWxsPSJyZWQiLA0KICAgICAgICBvdXRsaWVyLnNpemU9MykgKw0KICBzY2FsZV94X2Rpc2NyZXRlKCkgKw0KICBsYWJzKHRpdGxlPSJCb3hwbG90Iix4PSIiLCB5ID0gIlNUNTVNMTAxIChycG0pIikNCg0KIyBEZXNjcmlwdGl2ZSBTdGF0aXN0aWNzDQpkYXRhLmZyYW1lKEVzdGFkaXN0aWNhPXN0YXQuZGVzYyhkZl9UQV9maWx0ZXJlZCRTVDU1TTEwMSkpDQoNCmBgYA0KDQojIyBGaWx0ZXIgQ3JpdGVyaWENCioqRmlsdGVyIG91dCoqIGFueSBwb2ludHMgZm9yIHdoaWNoOg0KDQoqIFdUNTU1ODAxIDwgMTMwDQoqIFRRNTVNMTAxIDwgMTgwMA0KKiBTVDU1TTEwMSA8IDcwMA0KDQo=