AESHA RATHOD
ID NO: 813512

Dataset: Supermarket Ordering, Invoicing, and Sales Analysis
Numerical variable: Meal Price
Categorical variable: 1. OrderValue vs. MealPrice, 2. OrderValue vs. CompanyName



#Create a boxplot

library(ggplot2)
Merged$MealPrice <- ifelse(is.na(Merged$MealPrice), 0, Merged$MealPrice)

ggplot(Merged, aes(x = "", y = MealPrice)) +
  geom_boxplot(fill = "grey", color = "black") +
  ggtitle("Distribution of Meal Prices with Outliers")

1. Clean the data for any outlier/extreme values using the filtering technique and create an appropriate plot to visualize the distribution of this variable. (4 marks)

q1 <- quantile(Merged$MealPrice, 0.25)
q3 <- quantile(Merged$MealPrice, 0.75)
iqr_x <- IQR(Merged$MealPrice)

data1 <- Merged[(Merged$MealPrice >= q1 - 1.5*iqr_x) & (Merged$MealPrice <= q3 + 1.5*iqr_x), ]
ggplot(data1, aes(x = "", y = MealPrice)) +
  geom_boxplot(fill = "#f2c595", color = "black") +
  labs(x = "", y = "Meal Price", title = "Boxplot of Meal Prices")


2. Continued from #1, for any outliers present in the data. Specify the criteria used to identify them and provide a logical explanation for how you handled them. (4 marks)

I applied the interquartile range (IQR) method to find outliers in the data. Any data point outside the range (Q1 - 1.5IQR, Q3 + 1.5IQR) was regarded as an outlier. I calculated the IQR by subtracting the 25th percentile (Q1) from the 75th percentile (Q3).I made the decision to remove the outliers from the dataset after finding them. This is because outliers can skew analysis and reduce the precision of statistical models. Removing outliers can increase the analysis’s accuracy and generate more insightful results.


3. Describe the shape of the data. (2 marks)
The data appears to be slightly skewed to the right according to the boxplot. The median’s proximity to the first quartile (Q1) compared to the third quartile (Q3) and the presence of a few data points above the upper whisker are indicators of this. Due appears to be a bit the box’s apparent symmetry in relation the median, the distribution also symmetrical. Outliers may be present, but they might also be affecting the data’s overall shape.


4. Based on your answer to the previous question, decide if it is appropriate to apply a transformation to your data. If no, explain why not. If yes, name the transformation applied and visualize the transformed distribution. (This video and this video may help.) (4 marks)

The data appears to be skewed or has extreme outliers, we can consider applying a transformation to normalize the data.

# Apply natural logarithm transformation
Merged$log_MealPrice <- log(Merged$MealPrice)

# Plot transformed distribution using a Boxplot
ggplot(Merged, aes(y = log_MealPrice)) +
  geom_boxplot(fill = "#a63a3b", color = "black") +
  labs(y = "Log Meal Price", title = "Boxplot of Log Meal Prices")

NA
NA


4 Watched video and tried to apply the same fucntionality to the data column i am visualizing.FOR checking purpose only

library(gridExtra)
Warning: package ‘gridExtra’ was built under R version 4.2.3
a1 <- ggplot( data = Merged, mapping = aes(x = MealPrice, fill = ..count..)) + 
  geom_histogram() + 
  scale_fill_gradient(low = "#c673bf", high = "#674064") +
  labs(fill = "Count")+
  theme(panel.background = element_rect(fill = "#f0d2e1"))
a2<- a1+scale_x_log10()
a3<-a1+scale_x_sqrt()
grid.arrange(a1,a2,a3,ncol=2,nrow=2)


5. Choose and calculate an appropriate measure of central tendency (Mean, Median, and Mode). (3 marks)

We inferred from the previous analysis that the data are positively skewed. Since it is less sensitive to extreme values than the mean in these situations, the median is typically a better indicator of central tendency.As a result, we will calculate central tendency using the median.

median(Merged$MealPrice)
[1] 8


6. Explain why you chose this as your measure of central tendency. Provide supporting evidence for your choice. (4 marks)
The data appears to be right-skewed according to the boxplot, so the median might be a better indicator of central tendency than the mean. The median is more robust in the presence of outliers because it is less impacted by extreme values.


7. Choose and calculate a measure of spread (SD, MAD or IQR) that is appropriate for your chosen measure of central tendency. Explain why you chose this as your measure of spread. (2 marks)
I previously solved on the median as the indicator of central tendency because it is less responsive to outliers and extreme values than the mean. Therefore, it is important to use a spread measure that is resistant to outliers. A reliable measure of spread that is less vulnerable to outliers than the standard deviation is the interquartile range (IQR). I will therefore calculate my spread using the IQR.

The resulting boxplot will show the median, quartiles, and any outliers present in the data.

# Calculate IQR
q1 <- quantile(Merged$MealPrice, 0.25)
q3 <- quantile(Merged$MealPrice, 0.75)
iqr_x <- q3 - q1

# Create boxplot
ggplot(Merged, aes(x="", y=MealPrice)) +
  geom_boxplot(fill = "#abc9bd", color = "black") +
  labs(x = "", y = "Meal Price", title = "Boxplot of Meal Prices") +
  scale_y_continuous(limits = c(q1 - 1.5*iqr_x, q3 + 1.5*iqr_x))


For each categorical variable:

1. Create an appropriate plot to visualize the distribution of counts for this variable. (4 marks)
The Meal price variable is continuous variable not a categorical variable so by binning the meal prices into price ranges and then creating a count plot based on the price ranges.

# Create bins for meal prices
bins <- seq(1, 450, by = 50)

# Bin the meal prices
Merged$price_range <- cut(Merged$MealPrice, bins, include.lowest = TRUE)

# Create count plot
ggplot(Merged, aes(x = price_range, fill = price_range)) + 
  geom_bar() +
  scale_fill_brewer(palette = "Spectral") +
  theme_minimal() +
  scale_y_continuous(limits = c(0, 4000))+
  labs(x = "Price Range", y = "Count", title = "Distribution of Meal Prices")+
  theme(panel.background = element_rect(fill = "white"))


2. Create an appropriate plot to visualize the distribution of proportions for this variable. (4 marks)
Below i took the copy of the Same dataset and changed the name of the dataset Merged to MergedOrder2 Dataset for this particular datset because it effecting the whole dataset and further analysis is left.

We can use the prop.table() function to calculate the proportions and then create a bar plot to visualize the distribution of proportions for the meal price variable in the combined dataset.

library(dplyr)
# Create bins for meal prices
bins <- seq(0, 450, by = 50)

# Bin the meal prices
MergedOrders2$MealPrice <- as.numeric(as.character(MergedOrders2$MealPrice))
bins <- seq(0, 450, by = 50)
MergedOrders2$price_range <- cut(MergedOrders2$MealPrice, bins, include.lowest = TRUE)


# Group by price range and calculate proportions
merged_prop <- MergedOrders2 %>%
  group_by(price_range) %>%
  summarise(count = n()) %>%
  mutate(Proportion = count / sum(count))

# Create bar plot
ggplot(merged_prop, aes(x = price_range, y = Proportion, fill = price_range)) +
   scale_y_continuous(limits = c(0, 0.04)) +
  geom_col() +
  scale_fill_brewer(palette = "YlOrBr") +
  theme_minimal() +
  labs(x = "Price Range", y = "Proportion", title = "Distribution of Meal Prices (Proportions)")+
  theme(panel.background = element_rect(fill = "white"))


3. Discuss any unusual observations for this variable? (2 marks)
The distribution of meal prices does not contain any notable anomalies. It should be noted that the distribution may not be entirely representative of the population because the data is based on a small sample size of only 10 orders.


4. Discuss if there are too few/too many unique values? (2 marks)
While having a large number of unique values can give the data a detailed view, it can also make the data challenging to visualize and analyze.The number of unique values was decreased in this instance by grouping the meal prices into bins, which also made it simpler to see how the meal prices were distributed.All in all, the number of unique values for the MealPrice variable is not too few or too many for the purposes of this analysis.


Bivariate Analysis


For each pair of variables:

1. Create an appropriate plot to visualize the relationship between the two variables. (4 marks)
As limited number of columns in the dataset we can perform bivariate analysis on the following pairs of variables: 1. OrderValue vs. MealPrice - Relationship between Order Value and Meal Price 2. OrderValue vs. CompanyName - Distribution of Order Value by Company Name

ggplot(Merged, aes(x = OrderValue, y = MealPrice, color = OrderValue)) +
  geom_point(alpha = 0.5) +
  scale_x_continuous(labels = scales::dollar_format(scale = 0.001), limits = c(0, 10000)) +
  scale_y_continuous(labels = scales::dollar_format(scale = 0.001), limits = c(0, 500)) +
     scale_color_gradient(low = "#432c1d", high = "#ddbb9d") +
  labs(x = "Order Value", y = "Meal Price",color = "Order Value", title = "Relationship between Order Value and Meal Price")+
  theme(panel.background = element_rect(fill = "#f2ede1"),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank())

ggplot(Merged, aes(x = CompanyName, y = OrderValue, color = OrderValue)) +
  geom_point() +
  coord_flip() +
  scale_y_continuous(labels = scales::dollar_format(scale = 0.010), limits = c(0, 2500)) +
  labs(x = "Company Name", y = "Order Value", title = "Distribution of Order Value by Company Name")


2. Describe the form, direction, and strength of the observed relationship. 4 marks)

  1. OrderValue vs. MealPrice We see a strong correlation between OrderValue and MealPrice in the scatter plot of the two variables. The MealPrice rises as the OrderValue does. The points on the plot form a fairly straight line from the lower left to the upper right, suggesting that the relationship is linear.
  2. OrderValue vs. CompanyName OrderValue and CompanyName’s scatter plot reveals that there is no obvious correlation between the two variables. There is no clear pattern or trend among the points, which are dispersed throughout the story. This shows that OrderValue and CompanyName do not have a strong or significant relationship.


3. Explain what this relationship means in the context of the data. (4 marks)

  1. OrderValue vs. MealPrice This connection offers information about customers’ spending habits. Businesses can use this data to optimize their menu offerings and pricing strategy in order to boost sales. For instance, they can determine which menu items are popular with customers who place larger orders and change their selections accordingly. To entice customers to spend more while maintaining a fair meal price, they can also introduce bundle offers.

  2. OrderValue vs. CompanyName There is no particular pattern in the relationship, and the variation is not consistent. This suggests that the company of choice does not significantly affect the order value.Because of this, the relationship between OrderValue and CompanyName in the context of the data suggests that the choice of company has little to no impact on the order value.


4. Describe the variability that you observe in the plot and how that corresponds to the strength you calculated in #2 above. (3 marks)
This variation is probably caused by things like different meal types and different order sizes. Despite the variation, the correlation’s strength suggests that OrderValue and MealPrice have a distinct and consistent relationship, with the meal price generally rising along with order value.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQo8aDM+QUVTSEEgUkFUSE9EPGJyLz4NCiAgICBJRCBOTzogODEzNTEyIDxici8+PC9oMz4NCjxoND4NCiAgICAqKkRhdGFzZXQ6KiogU3VwZXJtYXJrZXQgT3JkZXJpbmcsIEludm9pY2luZywgYW5kIFNhbGVzIEFuYWx5c2lzPGJyLz4NCiAgICAqKk51bWVyaWNhbCB2YXJpYWJsZToqKiBNZWFsIFByaWNlPGJyLz4NCiAgICAqKkNhdGVnb3JpY2FsIHZhcmlhYmxlOioqIDEuIE9yZGVyVmFsdWUgdnMuIE1lYWxQcmljZSwgMi4gT3JkZXJWYWx1ZSB2cy4gQ29tcGFueU5hbWUNCjwvaDQ+PGJyLz48YnIvPg0KDQoNCiMqKkNyZWF0ZSBhIGJveHBsb3QqKg0KYGBge3J9DQpsaWJyYXJ5KGdncGxvdDIpDQpNZXJnZWQkTWVhbFByaWNlIDwtIGlmZWxzZShpcy5uYShNZXJnZWQkTWVhbFByaWNlKSwgMCwgTWVyZ2VkJE1lYWxQcmljZSkNCg0KZ2dwbG90KE1lcmdlZCwgYWVzKHggPSAiIiwgeSA9IE1lYWxQcmljZSkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAiZ3JleSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBnZ3RpdGxlKCJEaXN0cmlidXRpb24gb2YgTWVhbCBQcmljZXMgd2l0aCBPdXRsaWVycyIpDQpgYGANCg0KKioxLiBDbGVhbiB0aGUgZGF0YSBmb3IgYW55IG91dGxpZXIvZXh0cmVtZSB2YWx1ZXMgdXNpbmcgdGhlIGZpbHRlcmluZyB0ZWNobmlxdWUgYW5kIGNyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoaXMgdmFyaWFibGUuICg0IG1hcmtzKSoqPGJyLz4NCmBgYHtyfQ0KcTEgPC0gcXVhbnRpbGUoTWVyZ2VkJE1lYWxQcmljZSwgMC4yNSkNCnEzIDwtIHF1YW50aWxlKE1lcmdlZCRNZWFsUHJpY2UsIDAuNzUpDQppcXJfeCA8LSBJUVIoTWVyZ2VkJE1lYWxQcmljZSkNCg0KZGF0YTEgPC0gTWVyZ2VkWyhNZXJnZWQkTWVhbFByaWNlID49IHExIC0gMS41Kmlxcl94KSAmIChNZXJnZWQkTWVhbFByaWNlIDw9IHEzICsgMS41Kmlxcl94KSwgXQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGExLCBhZXMoeCA9ICIiLCB5ID0gTWVhbFByaWNlKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICIjZjJjNTk1IiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIk1lYWwgUHJpY2UiLCB0aXRsZSA9ICJCb3hwbG90IG9mIE1lYWwgUHJpY2VzIikNCmBgYA0KPGJyLz4qKjIuIENvbnRpbnVlZCBmcm9tICMxLCBmb3IgYW55IG91dGxpZXJzIHByZXNlbnQgaW4gdGhlIGRhdGEuIFNwZWNpZnkgdGhlIGNyaXRlcmlhIHVzZWQgdG8gaWRlbnRpZnkgdGhlbSBhbmQgcHJvdmlkZSBhIGxvZ2ljYWwgZXhwbGFuYXRpb24gZm9yIGhvdyB5b3UgaGFuZGxlZCB0aGVtLiAoNCBtYXJrcykqKjxici8+DQoNCkkgYXBwbGllZCB0aGUgaW50ZXJxdWFydGlsZSByYW5nZSAoSVFSKSBtZXRob2QgdG8gZmluZCBvdXRsaWVycyBpbiB0aGUgZGF0YS4gQW55IGRhdGEgcG9pbnQgb3V0c2lkZSB0aGUgcmFuZ2UgKFExIC0gMS41SVFSLCBRMyArIDEuNUlRUikgd2FzIHJlZ2FyZGVkIGFzIGFuIG91dGxpZXIuIEkgY2FsY3VsYXRlZCB0aGUgSVFSIGJ5IHN1YnRyYWN0aW5nIHRoZSAyNXRoIHBlcmNlbnRpbGUgKFExKSBmcm9tIHRoZSA3NXRoIHBlcmNlbnRpbGUgKFEzKS5JIG1hZGUgdGhlIGRlY2lzaW9uIHRvIHJlbW92ZSB0aGUgb3V0bGllcnMgZnJvbSB0aGUgZGF0YXNldCBhZnRlciBmaW5kaW5nIHRoZW0uIFRoaXMgaXMgYmVjYXVzZSBvdXRsaWVycyBjYW4gc2tldyBhbmFseXNpcyBhbmQgcmVkdWNlIHRoZSBwcmVjaXNpb24gb2Ygc3RhdGlzdGljYWwgbW9kZWxzLiBSZW1vdmluZyBvdXRsaWVycyBjYW4gaW5jcmVhc2UgdGhlIGFuYWx5c2lzJ3MgYWNjdXJhY3kgYW5kIGdlbmVyYXRlIG1vcmUgaW5zaWdodGZ1bCByZXN1bHRzLg0KDQoNCjxici8+KiozLiAgRGVzY3JpYmUgdGhlIHNoYXBlIG9mIHRoZSBkYXRhLiAoMiBtYXJrcykqKjxici8+DQpUaGUgZGF0YSBhcHBlYXJzIHRvIGJlIHNsaWdodGx5IHNrZXdlZCB0byB0aGUgcmlnaHQgYWNjb3JkaW5nIHRvIHRoZSBib3hwbG90LiBUaGUgbWVkaWFuJ3MgcHJveGltaXR5IHRvIHRoZSBmaXJzdCBxdWFydGlsZSAoUTEpIGNvbXBhcmVkIHRvIHRoZSB0aGlyZCBxdWFydGlsZSAoUTMpIGFuZCB0aGUgcHJlc2VuY2Ugb2YgYSBmZXcgZGF0YSBwb2ludHMgYWJvdmUgdGhlIHVwcGVyIHdoaXNrZXIgYXJlIGluZGljYXRvcnMgb2YgdGhpcy4gRHVlIGFwcGVhcnMgdG8gYmUgYSBiaXQgdGhlIGJveCdzIGFwcGFyZW50IHN5bW1ldHJ5IGluIHJlbGF0aW9uIHRoZSBtZWRpYW4sIHRoZSBkaXN0cmlidXRpb24gYWxzbyBzeW1tZXRyaWNhbC4gT3V0bGllcnMgbWF5IGJlIHByZXNlbnQsIGJ1dCB0aGV5IG1pZ2h0IGFsc28gYmUgYWZmZWN0aW5nIHRoZSBkYXRhJ3Mgb3ZlcmFsbCBzaGFwZS4NCg0KPGJyLz4qKjQuIEJhc2VkIG9uIHlvdXIgYW5zd2VyIHRvIHRoZSBwcmV2aW91cyBxdWVzdGlvbiwgZGVjaWRlIGlmIGl0IGlzIGFwcHJvcHJpYXRlIHRvIGFwcGx5IGEgdHJhbnNmb3JtYXRpb24gdG8geW91ciBkYXRhLiBJZiBubywgZXhwbGFpbiB3aHkgbm90LiBJZiB5ZXMsIG5hbWUgdGhlIHRyYW5zZm9ybWF0aW9uICBhcHBsaWVkIGFuZCB2aXN1YWxpemUgdGhlIHRyYW5zZm9ybWVkIGRpc3RyaWJ1dGlvbi4gKFRoaXMgdmlkZW8gYW5kIHRoaXMgdmlkZW8gbWF5IGhlbHAuKSAoNCBtYXJrcykqKg0KDQpUaGUgZGF0YSBhcHBlYXJzIHRvIGJlIHNrZXdlZCBvciBoYXMgZXh0cmVtZSBvdXRsaWVycywgd2UgY2FuIGNvbnNpZGVyIGFwcGx5aW5nIGEgdHJhbnNmb3JtYXRpb24gdG8gbm9ybWFsaXplIHRoZSBkYXRhLg0KDQpgYGB7cn0NCiMgQXBwbHkgbmF0dXJhbCBsb2dhcml0aG0gdHJhbnNmb3JtYXRpb24NCk1lcmdlZCRsb2dfTWVhbFByaWNlIDwtIGxvZyhNZXJnZWQkTWVhbFByaWNlKQ0KDQojIFBsb3QgdHJhbnNmb3JtZWQgZGlzdHJpYnV0aW9uIHVzaW5nIGEgQm94cGxvdA0KZ2dwbG90KE1lcmdlZCwgYWVzKHkgPSBsb2dfTWVhbFByaWNlKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICIjYTYzYTNiIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnMoeSA9ICJMb2cgTWVhbCBQcmljZSIsIHRpdGxlID0gIkJveHBsb3Qgb2YgTG9nIE1lYWwgUHJpY2VzIikNCg0KDQpgYGANCjxici8+Kio0IFdhdGNoZWQgdmlkZW8gYW5kIHRyaWVkIHRvIGFwcGx5IHRoZSBzYW1lIGZ1Y250aW9uYWxpdHkgdG8gdGhlIGRhdGEgY29sdW1uIGkgYW0gdmlzdWFsaXppbmcuRk9SIGNoZWNraW5nIHB1cnBvc2Ugb25seSoqDQpgYGB7cn0NCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KYTEgPC0gZ2dwbG90KCBkYXRhID0gTWVyZ2VkLCBtYXBwaW5nID0gYWVzKHggPSBNZWFsUHJpY2UsIGZpbGwgPSAuLmNvdW50Li4pKSArIA0KICBnZW9tX2hpc3RvZ3JhbSgpICsgDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiNjNjczYmYiLCBoaWdoID0gIiM2NzQwNjQiKSArDQogIGxhYnMoZmlsbCA9ICJDb3VudCIpKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAiI2YwZDJlMSIpKQ0KYTI8LSBhMStzY2FsZV94X2xvZzEwKCkNCmEzPC1hMStzY2FsZV94X3NxcnQoKQ0KZ3JpZC5hcnJhbmdlKGExLGEyLGEzLG5jb2w9Mixucm93PTIpDQpgYGANCg0KPGJyLz4qKjUuIENob29zZSBhbmQgY2FsY3VsYXRlIGFuIGFwcHJvcHJpYXRlIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeSAoTWVhbiwgTWVkaWFuLCBhbmQgTW9kZSkuICgzIG1hcmtzKSoqPGJyLz4NCg0KV2UgaW5mZXJyZWQgZnJvbSB0aGUgcHJldmlvdXMgYW5hbHlzaXMgdGhhdCB0aGUgZGF0YSBhcmUgcG9zaXRpdmVseSBza2V3ZWQuIFNpbmNlIGl0IGlzIGxlc3Mgc2Vuc2l0aXZlIHRvIGV4dHJlbWUgdmFsdWVzIHRoYW4gdGhlIG1lYW4gaW4gdGhlc2Ugc2l0dWF0aW9ucywgdGhlIG1lZGlhbiBpcyB0eXBpY2FsbHkgYSBiZXR0ZXIgaW5kaWNhdG9yIG9mIGNlbnRyYWwgdGVuZGVuY3kuQXMgYSByZXN1bHQsIHdlIHdpbGwgY2FsY3VsYXRlIGNlbnRyYWwgdGVuZGVuY3kgdXNpbmcgdGhlIG1lZGlhbi4NCmBgYHtyfQ0KbWVkaWFuKE1lcmdlZCRNZWFsUHJpY2UpDQpgYGANCjxici8+Kio2LiBFeHBsYWluIHdoeSB5b3UgY2hvc2UgdGhpcyBhcyB5b3VyIG1lYXN1cmUgb2YgY2VudHJhbCB0ZW5kZW5jeS4gUHJvdmlkZSBzdXBwb3J0aW5nIGV2aWRlbmNlIGZvciB5b3VyIGNob2ljZS4gKDQgbWFya3MpKio8YnIvPg0KVGhlIGRhdGEgYXBwZWFycyB0byBiZSByaWdodC1za2V3ZWQgYWNjb3JkaW5nIHRvIHRoZSBib3hwbG90LCBzbyB0aGUgbWVkaWFuIG1pZ2h0IGJlIGEgYmV0dGVyIGluZGljYXRvciBvZiBjZW50cmFsIHRlbmRlbmN5IHRoYW4gdGhlIG1lYW4uIFRoZSBtZWRpYW4gaXMgbW9yZSByb2J1c3QgaW4gdGhlIHByZXNlbmNlIG9mIG91dGxpZXJzIGJlY2F1c2UgaXQgaXMgbGVzcyBpbXBhY3RlZCBieSBleHRyZW1lIHZhbHVlcy4NCg0KPGJyLz4qKjcuIENob29zZSBhbmQgY2FsY3VsYXRlIGEgbWVhc3VyZSBvZiBzcHJlYWQgKFNELCBNQUQgb3IgSVFSKSB0aGF0IGlzIGFwcHJvcHJpYXRlIGZvciB5b3VyIGNob3NlbiBtZWFzdXJlIG9mIGNlbnRyYWwgdGVuZGVuY3kuIEV4cGxhaW4gd2h5IHlvdSBjaG9zZSB0aGlzIGFzIHlvdXIgbWVhc3VyZSBvZiBzcHJlYWQuICgyIG1hcmtzKSoqPGJyLz4NCkkgcHJldmlvdXNseSBzb2x2ZWQgb24gdGhlIG1lZGlhbiBhcyB0aGUgaW5kaWNhdG9yIG9mIGNlbnRyYWwgdGVuZGVuY3kgYmVjYXVzZSBpdCBpcyBsZXNzIHJlc3BvbnNpdmUgdG8gb3V0bGllcnMgYW5kIGV4dHJlbWUgdmFsdWVzIHRoYW4gdGhlIG1lYW4uIFRoZXJlZm9yZSwgaXQgaXMgaW1wb3J0YW50IHRvIHVzZSBhIHNwcmVhZCBtZWFzdXJlIHRoYXQgaXMgcmVzaXN0YW50IHRvIG91dGxpZXJzLiBBIHJlbGlhYmxlIG1lYXN1cmUgb2Ygc3ByZWFkIHRoYXQgaXMgbGVzcyB2dWxuZXJhYmxlIHRvIG91dGxpZXJzIHRoYW4gdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBpcyB0aGUgaW50ZXJxdWFydGlsZSByYW5nZSAoSVFSKS4gSSB3aWxsIHRoZXJlZm9yZSBjYWxjdWxhdGUgbXkgc3ByZWFkIHVzaW5nIHRoZSBJUVIuDQoNCg0KVGhlIHJlc3VsdGluZyBib3hwbG90IHdpbGwgc2hvdyB0aGUgbWVkaWFuLCBxdWFydGlsZXMsIGFuZCBhbnkgb3V0bGllcnMgcHJlc2VudCBpbiB0aGUgZGF0YS4NCmBgYHtyfQ0KIyBDYWxjdWxhdGUgSVFSDQpxMSA8LSBxdWFudGlsZShNZXJnZWQkTWVhbFByaWNlLCAwLjI1KQ0KcTMgPC0gcXVhbnRpbGUoTWVyZ2VkJE1lYWxQcmljZSwgMC43NSkNCmlxcl94IDwtIHEzIC0gcTENCg0KIyBDcmVhdGUgYm94cGxvdA0KZ2dwbG90KE1lcmdlZCwgYWVzKHg9IiIsIHk9TWVhbFByaWNlKSkgKw0KICBnZW9tX2JveHBsb3QoZmlsbCA9ICIjYWJjOWJkIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnMoeCA9ICIiLCB5ID0gIk1lYWwgUHJpY2UiLCB0aXRsZSA9ICJCb3hwbG90IG9mIE1lYWwgUHJpY2VzIikgKw0KICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYyhxMSAtIDEuNSppcXJfeCwgcTMgKyAxLjUqaXFyX3gpKQ0KDQpgYGANCjxici8+KipGb3IgZWFjaCBjYXRlZ29yaWNhbCB2YXJpYWJsZTogKio8YnIvPg0KPGJyLz4qKjEuIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGNvdW50cyBmb3IgdGhpcyB2YXJpYWJsZS4gKDQgbWFya3MpKio8YnIvPg0KVGhlIE1lYWwgcHJpY2UgdmFyaWFibGUgaXMgY29udGludW91cyB2YXJpYWJsZSBub3QgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSBzbyBieSBiaW5uaW5nIHRoZSBtZWFsIHByaWNlcyBpbnRvIHByaWNlIHJhbmdlcyBhbmQgdGhlbiBjcmVhdGluZyBhIGNvdW50IHBsb3QgYmFzZWQgb24gdGhlIHByaWNlIHJhbmdlcy4NCmBgYHtyfQ0KIyBDcmVhdGUgYmlucyBmb3IgbWVhbCBwcmljZXMNCmJpbnMgPC0gc2VxKDEsIDQ1MCwgYnkgPSA1MCkNCg0KIyBCaW4gdGhlIG1lYWwgcHJpY2VzDQpNZXJnZWQkcHJpY2VfcmFuZ2UgPC0gY3V0KE1lcmdlZCRNZWFsUHJpY2UsIGJpbnMsIGluY2x1ZGUubG93ZXN0ID0gVFJVRSkNCg0KIyBDcmVhdGUgY291bnQgcGxvdA0KZ2dwbG90KE1lcmdlZCwgYWVzKHggPSBwcmljZV9yYW5nZSwgZmlsbCA9IHByaWNlX3JhbmdlKSkgKyANCiAgZ2VvbV9iYXIoKSArDQogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU3BlY3RyYWwiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDQwMDApKSsNCiAgbGFicyh4ID0gIlByaWNlIFJhbmdlIiwgeSA9ICJDb3VudCIsIHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBNZWFsIFByaWNlcyIpKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAid2hpdGUiKSkNCmBgYA0KPGJyLz4qKjIuIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHByb3BvcnRpb25zIGZvciB0aGlzIHZhcmlhYmxlLiAoNCBtYXJrcykqKjxici8+DQpCZWxvdyBpIHRvb2sgdGhlIGNvcHkgb2YgdGhlIFNhbWUgZGF0YXNldCBhbmQgY2hhbmdlZCB0aGUgbmFtZSBvZiB0aGUgZGF0YXNldCBNZXJnZWQgdG8gTWVyZ2VkT3JkZXIyIERhdGFzZXQgZm9yIHRoaXMgcGFydGljdWxhciBkYXRzZXQgYmVjYXVzZSBpdCBlZmZlY3RpbmcgdGhlIHdob2xlIGRhdGFzZXQgYW5kIGZ1cnRoZXIgYW5hbHlzaXMgaXMgbGVmdC4NCg0KV2UgY2FuIHVzZSB0aGUgcHJvcC50YWJsZSgpIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgcHJvcG9ydGlvbnMgYW5kIHRoZW4gY3JlYXRlIGEgYmFyIHBsb3QgdG8gdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgcHJvcG9ydGlvbnMgZm9yIHRoZSBtZWFsIHByaWNlIHZhcmlhYmxlIGluIHRoZSBjb21iaW5lZCBkYXRhc2V0Lg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KIyBDcmVhdGUgYmlucyBmb3IgbWVhbCBwcmljZXMNCmJpbnMgPC0gc2VxKDAsIDQ1MCwgYnkgPSA1MCkNCg0KIyBCaW4gdGhlIG1lYWwgcHJpY2VzDQpNZXJnZWRPcmRlcnMyJE1lYWxQcmljZSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihNZXJnZWRPcmRlcnMyJE1lYWxQcmljZSkpDQpiaW5zIDwtIHNlcSgwLCA0NTAsIGJ5ID0gNTApDQpNZXJnZWRPcmRlcnMyJHByaWNlX3JhbmdlIDwtIGN1dChNZXJnZWRPcmRlcnMyJE1lYWxQcmljZSwgYmlucywgaW5jbHVkZS5sb3dlc3QgPSBUUlVFKQ0KDQoNCiMgR3JvdXAgYnkgcHJpY2UgcmFuZ2UgYW5kIGNhbGN1bGF0ZSBwcm9wb3J0aW9ucw0KbWVyZ2VkX3Byb3AgPC0gTWVyZ2VkT3JkZXJzMiAlPiUNCiAgZ3JvdXBfYnkocHJpY2VfcmFuZ2UpICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQ0KICBtdXRhdGUoUHJvcG9ydGlvbiA9IGNvdW50IC8gc3VtKGNvdW50KSkNCg0KIyBDcmVhdGUgYmFyIHBsb3QNCmdncGxvdChtZXJnZWRfcHJvcCwgYWVzKHggPSBwcmljZV9yYW5nZSwgeSA9IFByb3BvcnRpb24sIGZpbGwgPSBwcmljZV9yYW5nZSkpICsNCiAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKDAsIDAuMDQpKSArDQogIGdlb21fY29sKCkgKw0KICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIllsT3JCciIpICsNCiAgdGhlbWVfbWluaW1hbCgpICsNCiAgbGFicyh4ID0gIlByaWNlIFJhbmdlIiwgeSA9ICJQcm9wb3J0aW9uIiwgdGl0bGUgPSAiRGlzdHJpYnV0aW9uIG9mIE1lYWwgUHJpY2VzIChQcm9wb3J0aW9ucykiKSsNCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIndoaXRlIikpDQpgYGANCjxici8+KiozLiBEaXNjdXNzIGFueSB1bnVzdWFsIG9ic2VydmF0aW9ucyBmb3IgdGhpcyB2YXJpYWJsZT8gKDIgbWFya3MpKio8YnIvPg0KVGhlIGRpc3RyaWJ1dGlvbiBvZiBtZWFsIHByaWNlcyBkb2VzIG5vdCBjb250YWluIGFueSBub3RhYmxlIGFub21hbGllcy4gSXQgc2hvdWxkIGJlIG5vdGVkIHRoYXQgdGhlIGRpc3RyaWJ1dGlvbiBtYXkgbm90IGJlIGVudGlyZWx5IHJlcHJlc2VudGF0aXZlIG9mIHRoZSBwb3B1bGF0aW9uIGJlY2F1c2UgdGhlIGRhdGEgaXMgYmFzZWQgb24gYSBzbWFsbCBzYW1wbGUgc2l6ZSBvZiBvbmx5IDEwIG9yZGVycy4NCg0KPGJyLz4qKjQuIERpc2N1c3MgaWYgdGhlcmUgYXJlIHRvbyBmZXcvdG9vIG1hbnkgdW5pcXVlIHZhbHVlcz8gKDIgbWFya3MpKio8YnIvPg0KV2hpbGUgaGF2aW5nIGEgbGFyZ2UgbnVtYmVyIG9mIHVuaXF1ZSB2YWx1ZXMgY2FuIGdpdmUgdGhlIGRhdGEgYSBkZXRhaWxlZCB2aWV3LCBpdCBjYW4gYWxzbyBtYWtlIHRoZSBkYXRhIGNoYWxsZW5naW5nIHRvIHZpc3VhbGl6ZSBhbmQgYW5hbHl6ZS5UaGUgbnVtYmVyIG9mIHVuaXF1ZSB2YWx1ZXMgd2FzIGRlY3JlYXNlZCBpbiB0aGlzIGluc3RhbmNlIGJ5IGdyb3VwaW5nIHRoZSBtZWFsIHByaWNlcyBpbnRvIGJpbnMsIHdoaWNoIGFsc28gbWFkZSBpdCBzaW1wbGVyIHRvIHNlZSBob3cgdGhlIG1lYWwgcHJpY2VzIHdlcmUgZGlzdHJpYnV0ZWQuQWxsIGluIGFsbCwgdGhlIG51bWJlciBvZiB1bmlxdWUgdmFsdWVzIGZvciB0aGUgTWVhbFByaWNlIHZhcmlhYmxlIGlzIG5vdCB0b28gZmV3IG9yIHRvbyBtYW55IGZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBhbmFseXNpcy4NCg0KDQo8YnIvPioqQml2YXJpYXRlIEFuYWx5c2lzKio8YnIvPg0KDQo8YnIvPioqRm9yIGVhY2ggcGFpciBvZiB2YXJpYWJsZXM6Kio8YnIvPg0KPGJyLz4qKjEuIENyZWF0ZSBhbiBhcHByb3ByaWF0ZSBwbG90IHRvIHZpc3VhbGl6ZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHR3byB2YXJpYWJsZXMuICg0IG1hcmtzKSoqPGJyLz4NCkFzIGxpbWl0ZWQgbnVtYmVyIG9mIGNvbHVtbnMgaW4gdGhlIGRhdGFzZXQgd2UgY2FuIHBlcmZvcm0gYml2YXJpYXRlIGFuYWx5c2lzIG9uIHRoZSBmb2xsb3dpbmcgcGFpcnMgb2YgdmFyaWFibGVzOg0KMS4gT3JkZXJWYWx1ZSB2cy4gTWVhbFByaWNlIC0gUmVsYXRpb25zaGlwIGJldHdlZW4gT3JkZXIgVmFsdWUgYW5kIE1lYWwgUHJpY2UNCjIuIE9yZGVyVmFsdWUgdnMuIENvbXBhbnlOYW1lIC0gRGlzdHJpYnV0aW9uIG9mIE9yZGVyIFZhbHVlIGJ5IENvbXBhbnkgTmFtZQ0KDQpgYGB7cn0NCmdncGxvdChNZXJnZWQsIGFlcyh4ID0gT3JkZXJWYWx1ZSwgeSA9IE1lYWxQcmljZSwgY29sb3IgPSBPcmRlclZhbHVlKSkgKw0KICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArDQogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQoc2NhbGUgPSAwLjAwMSksIGxpbWl0cyA9IGMoMCwgMTAwMDApKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQoc2NhbGUgPSAwLjAwMSksIGxpbWl0cyA9IGMoMCwgNTAwKSkgKw0KICAgICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3cgPSAiIzQzMmMxZCIsIGhpZ2ggPSAiI2RkYmI5ZCIpICsNCiAgbGFicyh4ID0gIk9yZGVyIFZhbHVlIiwgeSA9ICJNZWFsIFByaWNlIixjb2xvciA9ICJPcmRlciBWYWx1ZSIsIHRpdGxlID0gIlJlbGF0aW9uc2hpcCBiZXR3ZWVuIE9yZGVyIFZhbHVlIGFuZCBNZWFsIFByaWNlIikrDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICIjZjJlZGUxIiksDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpDQoNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChNZXJnZWQsIGFlcyh4ID0gQ29tcGFueU5hbWUsIHkgPSBPcmRlclZhbHVlLCBjb2xvciA9IE9yZGVyVmFsdWUpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQoc2NhbGUgPSAwLjAxMCksIGxpbWl0cyA9IGMoMCwgMjUwMCkpICsNCiAgbGFicyh4ID0gIkNvbXBhbnkgTmFtZSIsIHkgPSAiT3JkZXIgVmFsdWUiLCB0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgT3JkZXIgVmFsdWUgYnkgQ29tcGFueSBOYW1lIikNCmBgYA0KDQo8YnIvPioqMi4gRGVzY3JpYmUgdGhlIGZvcm0sIGRpcmVjdGlvbiwgYW5kIHN0cmVuZ3RoIG9mIHRoZSBvYnNlcnZlZCByZWxhdGlvbnNoaXAuIDQgbWFya3MpKio8YnIvPg0KDQoxLiBPcmRlclZhbHVlIHZzLiBNZWFsUHJpY2UNCldlIHNlZSBhIHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIE9yZGVyVmFsdWUgYW5kIE1lYWxQcmljZSBpbiB0aGUgc2NhdHRlciBwbG90IG9mIHRoZSB0d28gdmFyaWFibGVzLiBUaGUgTWVhbFByaWNlIHJpc2VzIGFzIHRoZSBPcmRlclZhbHVlIGRvZXMuIFRoZSBwb2ludHMgb24gdGhlIHBsb3QgZm9ybSBhIGZhaXJseSBzdHJhaWdodCBsaW5lIGZyb20gdGhlIGxvd2VyIGxlZnQgdG8gdGhlIHVwcGVyIHJpZ2h0LCBzdWdnZXN0aW5nIHRoYXQgdGhlIHJlbGF0aW9uc2hpcCBpcyBsaW5lYXIuDQoyLiBPcmRlclZhbHVlIHZzLiBDb21wYW55TmFtZQ0KT3JkZXJWYWx1ZSBhbmQgQ29tcGFueU5hbWUncyBzY2F0dGVyIHBsb3QgcmV2ZWFscyB0aGF0IHRoZXJlIGlzIG5vIG9idmlvdXMgY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgdHdvIHZhcmlhYmxlcy4gVGhlcmUgaXMgbm8gY2xlYXIgcGF0dGVybiBvciB0cmVuZCBhbW9uZyB0aGUgcG9pbnRzLCB3aGljaCBhcmUgZGlzcGVyc2VkIHRocm91Z2hvdXQgdGhlIHN0b3J5LiBUaGlzIHNob3dzIHRoYXQgT3JkZXJWYWx1ZSBhbmQgQ29tcGFueU5hbWUgZG8gbm90IGhhdmUgYSBzdHJvbmcgb3Igc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwLg0KDQo8YnIvPioqMy4gRXhwbGFpbiB3aGF0IHRoaXMgcmVsYXRpb25zaGlwIG1lYW5zIGluIHRoZSBjb250ZXh0IG9mIHRoZSBkYXRhLiAoNCBtYXJrcykqKjxici8+DQoNCjEuIE9yZGVyVmFsdWUgdnMuIE1lYWxQcmljZSANClRoaXMgY29ubmVjdGlvbiBvZmZlcnMgaW5mb3JtYXRpb24gYWJvdXQgY3VzdG9tZXJzJyBzcGVuZGluZyBoYWJpdHMuIEJ1c2luZXNzZXMgY2FuIHVzZSB0aGlzIGRhdGEgdG8gb3B0aW1pemUgdGhlaXIgbWVudSBvZmZlcmluZ3MgYW5kIHByaWNpbmcgc3RyYXRlZ3kgaW4gb3JkZXIgdG8gYm9vc3Qgc2FsZXMuIEZvciBpbnN0YW5jZSwgdGhleSBjYW4gZGV0ZXJtaW5lIHdoaWNoIG1lbnUgaXRlbXMgYXJlIHBvcHVsYXIgd2l0aCBjdXN0b21lcnMgd2hvIHBsYWNlIGxhcmdlciBvcmRlcnMgYW5kIGNoYW5nZSB0aGVpciBzZWxlY3Rpb25zIGFjY29yZGluZ2x5LiBUbyBlbnRpY2UgY3VzdG9tZXJzIHRvIHNwZW5kIG1vcmUgd2hpbGUgbWFpbnRhaW5pbmcgYSBmYWlyIG1lYWwgcHJpY2UsIHRoZXkgY2FuIGFsc28gaW50cm9kdWNlIGJ1bmRsZSBvZmZlcnMuDQoNCjIuIE9yZGVyVmFsdWUgdnMuIENvbXBhbnlOYW1lDQpUaGVyZSBpcyBubyBwYXJ0aWN1bGFyIHBhdHRlcm4gaW4gdGhlIHJlbGF0aW9uc2hpcCwgYW5kIHRoZSB2YXJpYXRpb24gaXMgbm90IGNvbnNpc3RlbnQuIFRoaXMgc3VnZ2VzdHMgdGhhdCB0aGUgY29tcGFueSBvZiBjaG9pY2UgZG9lcyBub3Qgc2lnbmlmaWNhbnRseSBhZmZlY3QgdGhlIG9yZGVyIHZhbHVlLkJlY2F1c2Ugb2YgdGhpcywgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIE9yZGVyVmFsdWUgYW5kIENvbXBhbnlOYW1lIGluIHRoZSBjb250ZXh0IG9mIHRoZSBkYXRhIHN1Z2dlc3RzIHRoYXQgdGhlIGNob2ljZSBvZiBjb21wYW55IGhhcyBsaXR0bGUgdG8gbm8gaW1wYWN0IG9uIHRoZSBvcmRlciB2YWx1ZS4gDQoNCjxici8+Kio0LiBEZXNjcmliZSB0aGUgdmFyaWFiaWxpdHkgdGhhdCB5b3Ugb2JzZXJ2ZSBpbiB0aGUgcGxvdCBhbmQgaG93IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHN0cmVuZ3RoIHlvdSBjYWxjdWxhdGVkIGluICMyIGFib3ZlLiAoMyBtYXJrcykqKjxici8+DQpUaGlzIHZhcmlhdGlvbiBpcyBwcm9iYWJseSBjYXVzZWQgYnkgdGhpbmdzIGxpa2UgZGlmZmVyZW50IG1lYWwgdHlwZXMgYW5kIGRpZmZlcmVudCBvcmRlciBzaXplcy4gRGVzcGl0ZSB0aGUgdmFyaWF0aW9uLCB0aGUgY29ycmVsYXRpb24ncyBzdHJlbmd0aCBzdWdnZXN0cyB0aGF0IE9yZGVyVmFsdWUgYW5kIE1lYWxQcmljZSBoYXZlIGEgZGlzdGluY3QgYW5kIGNvbnNpc3RlbnQgcmVsYXRpb25zaGlwLCB3aXRoIHRoZSBtZWFsIHByaWNlIGdlbmVyYWxseSByaXNpbmcgYWxvbmcgd2l0aCBvcmRlciB2YWx1ZS4NCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=