Project Overview
This report describes the Tableau dashboard and story points created
for Project #4. The dashboard was built using the Sample
Superstore dataset and focuses on sales, profit, product
categories, customer segments, and geographic performance.
The purpose of the dashboard is to tell a clear business story about
which parts of the Superstore business are performing well and which
areas may need improvement. The final report embeds the Tableau Public
dashboard and five Tableau Public story points so that readers can
interact with the visualizations directly from the HTML report.
a. Narrative of the Story
The main story of this dashboard is that high sales do not
always lead to high profit. A business can generate strong
revenue while still losing money in certain product categories,
sub-categories, customer segments, or geographic areas. Because of this,
managers should evaluate both sales and profitability before making
decisions.
The dashboard begins by showing sales performance across product
categories and sub-categories. This helps identify which product groups
generate the most revenue. However, by also comparing those product
groups by profit, the dashboard shows whether revenue is actually
creating business value.
The scatter plot expands the story by showing the relationship
between sales and profit. This chart helps identify outliers, especially
product groups or customer segments with high sales but low or negative
profit. These cases may point to problems such as excessive discounting,
high shipping costs, or inefficient pricing strategies.
The histogram shows the distribution of order-level sales. This helps
explain whether total revenue is driven by many small transactions or by
a smaller number of large orders. Understanding the distribution of
sales is useful because extreme values can influence overall business
results.
The map adds a geographic perspective by showing sales or profit by
state and region. This makes it easier to identify areas where the
company performs well and areas where profit may be weaker. Regional
differences may reflect customer demand, shipping costs, product
preferences, or discounting patterns.
Finally, the customer segment chart shows which customer groups
contribute the largest share of sales. This helps managers understand
whether Consumer, Corporate, or Home Office customers are driving
business performance.
Overall, the dashboard tells a practical business story:
Superstore should not focus only on increasing sales. It should
focus on profitable growth by identifying strong product groups,
improving weak regions, and managing customer segments more
strategically.
b. Data Sources and Description
The data source used for this dashboard is the Sample
Superstore dataset. This dataset contains retail order
information, including product details, customer segments, geographic
information, sales, profit, discounts, and shipping information.
The dataset is appropriate for this project because it contains both
numerical and categorical variables. This allows the dashboard to
include the required chart types, including histograms, scatter plots,
bar charts, maps, and pie or bubble charts.
Numerical Variables
The main numerical variables used in the dashboard include:
- Sales: Revenue generated from each order.
- Profit: Profit or loss associated with each
order.
- Quantity: Number of items purchased.
- Discount: Discount applied to the order.
Categorical Variables
The main categorical variables used in the dashboard include:
- Category: Broad product group, such as Furniture,
Office Supplies, or Technology.
- Sub-Category: More specific product grouping within
each category.
- Region: Geographic region where the order
occurred.
- State: State where the customer is located.
- Segment: Customer segment, such as Consumer,
Corporate, or Home Office.
- Ship Mode: Shipping method used for the order.
Dashboard Charts
Chart 1: Sales by Category and Sub-Category
Chart type: Bar chart
Variables used: Category, Sub-Category, Sales,
Profit
This chart identifies which product groups generate the highest sales
and whether those product groups are also profitable. It helps show that
high sales do not always guarantee high profit.
Chart 2: Profit vs. Sales Scatter Plot
Chart type: Scatter plot
Variables used: Sales, Profit, Category, Segment
This chart shows the relationship between revenue and profitability.
It is useful for identifying outliers, especially areas with high sales
but low or negative profit.
Chart 3: Sales Distribution Histogram
Chart type: Histogram
Variables used: Sales
This chart shows the distribution of order-level sales. It helps
explain whether most purchases are small, medium, or large.
Chart 4: Sales or Profit by Region
Chart type: Map or filled map
Variables used: State, Region, Sales, Profit
This chart shows geographic performance patterns and helps identify
which states or regions generate strong profit and which areas may need
improvement.
Chart 5: Segment Share of Sales
Chart type: Pie chart or packed bubble chart
Variables used: Segment, Sales
This chart shows which customer segments contribute the largest share
of sales.
Interactivity and Filters
The dashboard includes interactive filters that allow users to
explore the data more deeply. The filters include:
- Region
- Category
- Segment
- Order Date
- Ship Mode
The most important global filter is Region, because
it allows users to compare performance across geographic markets. The
dashboard applies filters across the connected worksheets so that
changing one filter updates the charts together. This creates a reactive
dashboard where users can explore product, customer, and geographic
patterns together.
c. Embedding Tableau Dashboard and Story Points to the Report
Embedded Tableau Public Story Points
Story Point 1: Overall Business Performance
This story point introduces the overall purpose of the dashboard. It
provides a high-level view of Superstore performance and frames the
central business question: which parts of the company are generating
strong sales and which areas are producing weaker profitability?
Open
Story Point 1
Story Point 2: Product Performance
This story point focuses on product category and sub-category
performance. It explains which product groups generate the most sales
and whether those products are also profitable.
Open
Story Point 2
Story Point 3: Sales vs. Profit Relationship
This story point examines the relationship between sales and profit.
The scatter plot helps identify whether higher sales generally lead to
higher profit and highlights possible outliers.
Open
Story Point 3
Story Point 4: Geographic Performance
This story point adds a regional perspective to the dashboard. By
comparing sales and profit across states or regions, the viewer can see
where Superstore performs strongest and where profitability may be
weaker.
Open
Story Point 4
Story Point 5: Customer Segment Insights and Recommendations
This final story point summarizes the dashboard findings and connects
them to business recommendations. It focuses on customer segments and
explains how Superstore can use the dashboard to make better
decisions.
Open
Story Point 5
Recommendations
Based on the dashboard and story points, Superstore managers should
consider the following actions:
- Focus on product sub-categories that generate both strong sales and
strong profit.
- Investigate sub-categories with high sales but weak or negative
profit.
- Review discounting practices in low-profit product groups.
- Compare regional performance to identify markets that need
improvement.
- Use customer segment insights to target the most valuable customer
groups.
- Monitor profit ratio alongside total sales to avoid pursuing revenue
growth that does not improve profitability.
Conclusion
The Tableau dashboard provides a clear and interactive view of
Superstore performance. It shows that sales, profit, product category,
region, and customer segment must be analyzed together to make strong
business decisions. The dashboard supports the project goal by combining
multiple chart types into one interconnected visual story.
The most important conclusion is that profitable growth
matters more than sales growth alone. By using filters,
dashboards, and story points, viewers can identify where Superstore is
performing well, where it is losing profit, and where management should
focus future improvement efforts.
LS0tDQp0aXRsZTogIlByb2plY3QgIzQ6IFRhYmxlYXUgRGFzaGJvYXJkIFJlcG9ydCINCmF1dGhvcjogIktpZXJhbiBIZWZmZXJhbiINCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSwgJyVCICVkLCAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0aGVtZTogY29zbW8NCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQ0KYGBgDQoNCiMgUHJvamVjdCBPdmVydmlldw0KDQpUaGlzIHJlcG9ydCBkZXNjcmliZXMgdGhlIFRhYmxlYXUgZGFzaGJvYXJkIGFuZCBzdG9yeSBwb2ludHMgY3JlYXRlZCBmb3IgUHJvamVjdCAjNC4gVGhlIGRhc2hib2FyZCB3YXMgYnVpbHQgdXNpbmcgdGhlICoqU2FtcGxlIFN1cGVyc3RvcmUqKiBkYXRhc2V0IGFuZCBmb2N1c2VzIG9uIHNhbGVzLCBwcm9maXQsIHByb2R1Y3QgY2F0ZWdvcmllcywgY3VzdG9tZXIgc2VnbWVudHMsIGFuZCBnZW9ncmFwaGljIHBlcmZvcm1hbmNlLg0KDQpUaGUgcHVycG9zZSBvZiB0aGUgZGFzaGJvYXJkIGlzIHRvIHRlbGwgYSBjbGVhciBidXNpbmVzcyBzdG9yeSBhYm91dCB3aGljaCBwYXJ0cyBvZiB0aGUgU3VwZXJzdG9yZSBidXNpbmVzcyBhcmUgcGVyZm9ybWluZyB3ZWxsIGFuZCB3aGljaCBhcmVhcyBtYXkgbmVlZCBpbXByb3ZlbWVudC4gVGhlIGZpbmFsIHJlcG9ydCBlbWJlZHMgdGhlIFRhYmxlYXUgUHVibGljIGRhc2hib2FyZCBhbmQgZml2ZSBUYWJsZWF1IFB1YmxpYyBzdG9yeSBwb2ludHMgc28gdGhhdCByZWFkZXJzIGNhbiBpbnRlcmFjdCB3aXRoIHRoZSB2aXN1YWxpemF0aW9ucyBkaXJlY3RseSBmcm9tIHRoZSBIVE1MIHJlcG9ydC4NCg0KIyBhLiBOYXJyYXRpdmUgb2YgdGhlIFN0b3J5DQoNClRoZSBtYWluIHN0b3J5IG9mIHRoaXMgZGFzaGJvYXJkIGlzIHRoYXQgKipoaWdoIHNhbGVzIGRvIG5vdCBhbHdheXMgbGVhZCB0byBoaWdoIHByb2ZpdCoqLiBBIGJ1c2luZXNzIGNhbiBnZW5lcmF0ZSBzdHJvbmcgcmV2ZW51ZSB3aGlsZSBzdGlsbCBsb3NpbmcgbW9uZXkgaW4gY2VydGFpbiBwcm9kdWN0IGNhdGVnb3JpZXMsIHN1Yi1jYXRlZ29yaWVzLCBjdXN0b21lciBzZWdtZW50cywgb3IgZ2VvZ3JhcGhpYyBhcmVhcy4gQmVjYXVzZSBvZiB0aGlzLCBtYW5hZ2VycyBzaG91bGQgZXZhbHVhdGUgYm90aCBzYWxlcyBhbmQgcHJvZml0YWJpbGl0eSBiZWZvcmUgbWFraW5nIGRlY2lzaW9ucy4NCg0KVGhlIGRhc2hib2FyZCBiZWdpbnMgYnkgc2hvd2luZyBzYWxlcyBwZXJmb3JtYW5jZSBhY3Jvc3MgcHJvZHVjdCBjYXRlZ29yaWVzIGFuZCBzdWItY2F0ZWdvcmllcy4gVGhpcyBoZWxwcyBpZGVudGlmeSB3aGljaCBwcm9kdWN0IGdyb3VwcyBnZW5lcmF0ZSB0aGUgbW9zdCByZXZlbnVlLiBIb3dldmVyLCBieSBhbHNvIGNvbXBhcmluZyB0aG9zZSBwcm9kdWN0IGdyb3VwcyBieSBwcm9maXQsIHRoZSBkYXNoYm9hcmQgc2hvd3Mgd2hldGhlciByZXZlbnVlIGlzIGFjdHVhbGx5IGNyZWF0aW5nIGJ1c2luZXNzIHZhbHVlLg0KDQpUaGUgc2NhdHRlciBwbG90IGV4cGFuZHMgdGhlIHN0b3J5IGJ5IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNhbGVzIGFuZCBwcm9maXQuIFRoaXMgY2hhcnQgaGVscHMgaWRlbnRpZnkgb3V0bGllcnMsIGVzcGVjaWFsbHkgcHJvZHVjdCBncm91cHMgb3IgY3VzdG9tZXIgc2VnbWVudHMgd2l0aCBoaWdoIHNhbGVzIGJ1dCBsb3cgb3IgbmVnYXRpdmUgcHJvZml0LiBUaGVzZSBjYXNlcyBtYXkgcG9pbnQgdG8gcHJvYmxlbXMgc3VjaCBhcyBleGNlc3NpdmUgZGlzY291bnRpbmcsIGhpZ2ggc2hpcHBpbmcgY29zdHMsIG9yIGluZWZmaWNpZW50IHByaWNpbmcgc3RyYXRlZ2llcy4NCg0KVGhlIGhpc3RvZ3JhbSBzaG93cyB0aGUgZGlzdHJpYnV0aW9uIG9mIG9yZGVyLWxldmVsIHNhbGVzLiBUaGlzIGhlbHBzIGV4cGxhaW4gd2hldGhlciB0b3RhbCByZXZlbnVlIGlzIGRyaXZlbiBieSBtYW55IHNtYWxsIHRyYW5zYWN0aW9ucyBvciBieSBhIHNtYWxsZXIgbnVtYmVyIG9mIGxhcmdlIG9yZGVycy4gVW5kZXJzdGFuZGluZyB0aGUgZGlzdHJpYnV0aW9uIG9mIHNhbGVzIGlzIHVzZWZ1bCBiZWNhdXNlIGV4dHJlbWUgdmFsdWVzIGNhbiBpbmZsdWVuY2Ugb3ZlcmFsbCBidXNpbmVzcyByZXN1bHRzLg0KDQpUaGUgbWFwIGFkZHMgYSBnZW9ncmFwaGljIHBlcnNwZWN0aXZlIGJ5IHNob3dpbmcgc2FsZXMgb3IgcHJvZml0IGJ5IHN0YXRlIGFuZCByZWdpb24uIFRoaXMgbWFrZXMgaXQgZWFzaWVyIHRvIGlkZW50aWZ5IGFyZWFzIHdoZXJlIHRoZSBjb21wYW55IHBlcmZvcm1zIHdlbGwgYW5kIGFyZWFzIHdoZXJlIHByb2ZpdCBtYXkgYmUgd2Vha2VyLiBSZWdpb25hbCBkaWZmZXJlbmNlcyBtYXkgcmVmbGVjdCBjdXN0b21lciBkZW1hbmQsIHNoaXBwaW5nIGNvc3RzLCBwcm9kdWN0IHByZWZlcmVuY2VzLCBvciBkaXNjb3VudGluZyBwYXR0ZXJucy4NCg0KRmluYWxseSwgdGhlIGN1c3RvbWVyIHNlZ21lbnQgY2hhcnQgc2hvd3Mgd2hpY2ggY3VzdG9tZXIgZ3JvdXBzIGNvbnRyaWJ1dGUgdGhlIGxhcmdlc3Qgc2hhcmUgb2Ygc2FsZXMuIFRoaXMgaGVscHMgbWFuYWdlcnMgdW5kZXJzdGFuZCB3aGV0aGVyIENvbnN1bWVyLCBDb3Jwb3JhdGUsIG9yIEhvbWUgT2ZmaWNlIGN1c3RvbWVycyBhcmUgZHJpdmluZyBidXNpbmVzcyBwZXJmb3JtYW5jZS4NCg0KT3ZlcmFsbCwgdGhlIGRhc2hib2FyZCB0ZWxscyBhIHByYWN0aWNhbCBidXNpbmVzcyBzdG9yeTogKipTdXBlcnN0b3JlIHNob3VsZCBub3QgZm9jdXMgb25seSBvbiBpbmNyZWFzaW5nIHNhbGVzLiBJdCBzaG91bGQgZm9jdXMgb24gcHJvZml0YWJsZSBncm93dGggYnkgaWRlbnRpZnlpbmcgc3Ryb25nIHByb2R1Y3QgZ3JvdXBzLCBpbXByb3Zpbmcgd2VhayByZWdpb25zLCBhbmQgbWFuYWdpbmcgY3VzdG9tZXIgc2VnbWVudHMgbW9yZSBzdHJhdGVnaWNhbGx5LioqDQoNCiMgYi4gRGF0YSBTb3VyY2VzIGFuZCBEZXNjcmlwdGlvbg0KDQpUaGUgZGF0YSBzb3VyY2UgdXNlZCBmb3IgdGhpcyBkYXNoYm9hcmQgaXMgdGhlICoqU2FtcGxlIFN1cGVyc3RvcmUqKiBkYXRhc2V0LiBUaGlzIGRhdGFzZXQgY29udGFpbnMgcmV0YWlsIG9yZGVyIGluZm9ybWF0aW9uLCBpbmNsdWRpbmcgcHJvZHVjdCBkZXRhaWxzLCBjdXN0b21lciBzZWdtZW50cywgZ2VvZ3JhcGhpYyBpbmZvcm1hdGlvbiwgc2FsZXMsIHByb2ZpdCwgZGlzY291bnRzLCBhbmQgc2hpcHBpbmcgaW5mb3JtYXRpb24uDQoNClRoZSBkYXRhc2V0IGlzIGFwcHJvcHJpYXRlIGZvciB0aGlzIHByb2plY3QgYmVjYXVzZSBpdCBjb250YWlucyBib3RoIG51bWVyaWNhbCBhbmQgY2F0ZWdvcmljYWwgdmFyaWFibGVzLiBUaGlzIGFsbG93cyB0aGUgZGFzaGJvYXJkIHRvIGluY2x1ZGUgdGhlIHJlcXVpcmVkIGNoYXJ0IHR5cGVzLCBpbmNsdWRpbmcgaGlzdG9ncmFtcywgc2NhdHRlciBwbG90cywgYmFyIGNoYXJ0cywgbWFwcywgYW5kIHBpZSBvciBidWJibGUgY2hhcnRzLg0KDQojIyBOdW1lcmljYWwgVmFyaWFibGVzDQoNClRoZSBtYWluIG51bWVyaWNhbCB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgZGFzaGJvYXJkIGluY2x1ZGU6DQoNCi0gKipTYWxlcyoqOiBSZXZlbnVlIGdlbmVyYXRlZCBmcm9tIGVhY2ggb3JkZXIuDQotICoqUHJvZml0Kio6IFByb2ZpdCBvciBsb3NzIGFzc29jaWF0ZWQgd2l0aCBlYWNoIG9yZGVyLg0KLSAqKlF1YW50aXR5Kio6IE51bWJlciBvZiBpdGVtcyBwdXJjaGFzZWQuDQotICoqRGlzY291bnQqKjogRGlzY291bnQgYXBwbGllZCB0byB0aGUgb3JkZXIuDQoNCiMjIENhdGVnb3JpY2FsIFZhcmlhYmxlcw0KDQpUaGUgbWFpbiBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgdXNlZCBpbiB0aGUgZGFzaGJvYXJkIGluY2x1ZGU6DQoNCi0gKipDYXRlZ29yeSoqOiBCcm9hZCBwcm9kdWN0IGdyb3VwLCBzdWNoIGFzIEZ1cm5pdHVyZSwgT2ZmaWNlIFN1cHBsaWVzLCBvciBUZWNobm9sb2d5Lg0KLSAqKlN1Yi1DYXRlZ29yeSoqOiBNb3JlIHNwZWNpZmljIHByb2R1Y3QgZ3JvdXBpbmcgd2l0aGluIGVhY2ggY2F0ZWdvcnkuDQotICoqUmVnaW9uKio6IEdlb2dyYXBoaWMgcmVnaW9uIHdoZXJlIHRoZSBvcmRlciBvY2N1cnJlZC4NCi0gKipTdGF0ZSoqOiBTdGF0ZSB3aGVyZSB0aGUgY3VzdG9tZXIgaXMgbG9jYXRlZC4NCi0gKipTZWdtZW50Kio6IEN1c3RvbWVyIHNlZ21lbnQsIHN1Y2ggYXMgQ29uc3VtZXIsIENvcnBvcmF0ZSwgb3IgSG9tZSBPZmZpY2UuDQotICoqU2hpcCBNb2RlKio6IFNoaXBwaW5nIG1ldGhvZCB1c2VkIGZvciB0aGUgb3JkZXIuDQoNCiMgRGFzaGJvYXJkIENoYXJ0cw0KDQojIyBDaGFydCAxOiBTYWxlcyBieSBDYXRlZ29yeSBhbmQgU3ViLUNhdGVnb3J5DQoNCioqQ2hhcnQgdHlwZToqKiBCYXIgY2hhcnQgIA0KKipWYXJpYWJsZXMgdXNlZDoqKiBDYXRlZ29yeSwgU3ViLUNhdGVnb3J5LCBTYWxlcywgUHJvZml0ICANCg0KVGhpcyBjaGFydCBpZGVudGlmaWVzIHdoaWNoIHByb2R1Y3QgZ3JvdXBzIGdlbmVyYXRlIHRoZSBoaWdoZXN0IHNhbGVzIGFuZCB3aGV0aGVyIHRob3NlIHByb2R1Y3QgZ3JvdXBzIGFyZSBhbHNvIHByb2ZpdGFibGUuIEl0IGhlbHBzIHNob3cgdGhhdCBoaWdoIHNhbGVzIGRvIG5vdCBhbHdheXMgZ3VhcmFudGVlIGhpZ2ggcHJvZml0Lg0KDQojIyBDaGFydCAyOiBQcm9maXQgdnMuIFNhbGVzIFNjYXR0ZXIgUGxvdA0KDQoqKkNoYXJ0IHR5cGU6KiogU2NhdHRlciBwbG90ICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2FsZXMsIFByb2ZpdCwgQ2F0ZWdvcnksIFNlZ21lbnQgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiByZXZlbnVlIGFuZCBwcm9maXRhYmlsaXR5LiBJdCBpcyB1c2VmdWwgZm9yIGlkZW50aWZ5aW5nIG91dGxpZXJzLCBlc3BlY2lhbGx5IGFyZWFzIHdpdGggaGlnaCBzYWxlcyBidXQgbG93IG9yIG5lZ2F0aXZlIHByb2ZpdC4NCg0KIyMgQ2hhcnQgMzogU2FsZXMgRGlzdHJpYnV0aW9uIEhpc3RvZ3JhbQ0KDQoqKkNoYXJ0IHR5cGU6KiogSGlzdG9ncmFtICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2FsZXMgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2Ygb3JkZXItbGV2ZWwgc2FsZXMuIEl0IGhlbHBzIGV4cGxhaW4gd2hldGhlciBtb3N0IHB1cmNoYXNlcyBhcmUgc21hbGwsIG1lZGl1bSwgb3IgbGFyZ2UuDQoNCiMjIENoYXJ0IDQ6IFNhbGVzIG9yIFByb2ZpdCBieSBSZWdpb24NCg0KKipDaGFydCB0eXBlOioqIE1hcCBvciBmaWxsZWQgbWFwICANCioqVmFyaWFibGVzIHVzZWQ6KiogU3RhdGUsIFJlZ2lvbiwgU2FsZXMsIFByb2ZpdCAgDQoNClRoaXMgY2hhcnQgc2hvd3MgZ2VvZ3JhcGhpYyBwZXJmb3JtYW5jZSBwYXR0ZXJucyBhbmQgaGVscHMgaWRlbnRpZnkgd2hpY2ggc3RhdGVzIG9yIHJlZ2lvbnMgZ2VuZXJhdGUgc3Ryb25nIHByb2ZpdCBhbmQgd2hpY2ggYXJlYXMgbWF5IG5lZWQgaW1wcm92ZW1lbnQuDQoNCiMjIENoYXJ0IDU6IFNlZ21lbnQgU2hhcmUgb2YgU2FsZXMNCg0KKipDaGFydCB0eXBlOioqIFBpZSBjaGFydCBvciBwYWNrZWQgYnViYmxlIGNoYXJ0ICANCioqVmFyaWFibGVzIHVzZWQ6KiogU2VnbWVudCwgU2FsZXMgIA0KDQpUaGlzIGNoYXJ0IHNob3dzIHdoaWNoIGN1c3RvbWVyIHNlZ21lbnRzIGNvbnRyaWJ1dGUgdGhlIGxhcmdlc3Qgc2hhcmUgb2Ygc2FsZXMuDQoNCiMgSW50ZXJhY3Rpdml0eSBhbmQgRmlsdGVycw0KDQpUaGUgZGFzaGJvYXJkIGluY2x1ZGVzIGludGVyYWN0aXZlIGZpbHRlcnMgdGhhdCBhbGxvdyB1c2VycyB0byBleHBsb3JlIHRoZSBkYXRhIG1vcmUgZGVlcGx5LiBUaGUgZmlsdGVycyBpbmNsdWRlOg0KDQotIFJlZ2lvbg0KLSBDYXRlZ29yeQ0KLSBTZWdtZW50DQotIE9yZGVyIERhdGUNCi0gU2hpcCBNb2RlDQoNClRoZSBtb3N0IGltcG9ydGFudCBnbG9iYWwgZmlsdGVyIGlzICoqUmVnaW9uKiosIGJlY2F1c2UgaXQgYWxsb3dzIHVzZXJzIHRvIGNvbXBhcmUgcGVyZm9ybWFuY2UgYWNyb3NzIGdlb2dyYXBoaWMgbWFya2V0cy4gVGhlIGRhc2hib2FyZCBhcHBsaWVzIGZpbHRlcnMgYWNyb3NzIHRoZSBjb25uZWN0ZWQgd29ya3NoZWV0cyBzbyB0aGF0IGNoYW5naW5nIG9uZSBmaWx0ZXIgdXBkYXRlcyB0aGUgY2hhcnRzIHRvZ2V0aGVyLiBUaGlzIGNyZWF0ZXMgYSByZWFjdGl2ZSBkYXNoYm9hcmQgd2hlcmUgdXNlcnMgY2FuIGV4cGxvcmUgcHJvZHVjdCwgY3VzdG9tZXIsIGFuZCBnZW9ncmFwaGljIHBhdHRlcm5zIHRvZ2V0aGVyLg0KDQojIGMuIEVtYmVkZGluZyBUYWJsZWF1IERhc2hib2FyZCBhbmQgU3RvcnkgUG9pbnRzIHRvIHRoZSBSZXBvcnQNCg0KIyMgRW1iZWRkZWQgVGFibGVhdSBQdWJsaWMgRGFzaGJvYXJkDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzNzk2NTc5NScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdQcm9qZWN0IDQgVGFibGVhdSBEYXNoYm9hcmQnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxLzFfcnNzLnBuZycgc3R5bGU9J2JvcmRlcjogbm9uZScgLz4NCiAgICA8L2E+DQogIDwvbm9zY3JpcHQ+DQogIDxvYmplY3QgY2xhc3M9J3RhYmxlYXVWaXonIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCiAgICA8cGFyYW0gbmFtZT0naG9zdF91cmwnIHZhbHVlPSdodHRwcyUzQSUyRiUyRnB1YmxpYy50YWJsZWF1LmNvbSUyRicgLz4NCiAgICA8cGFyYW0gbmFtZT0nZW1iZWRfY29kZV92ZXJzaW9uJyB2YWx1ZT0nMycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc2l0ZV9yb290JyB2YWx1ZT0nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSduYW1lJyB2YWx1ZT0nUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvRGFzaGJvYXJkMScgLz4NCiAgICA8cGFyYW0gbmFtZT0ndGFicycgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0ndG9vbGJhcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc3RhdGljX2ltYWdlJyB2YWx1ZT0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxLzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM3OTY1Nzk1Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIGlmIChkaXZFbGVtZW50Lm9mZnNldFdpZHRoID4gODAwKSB7DQogICAgdml6RWxlbWVudC5zdHlsZS5taW5XaWR0aD0nMTIwMHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heFdpZHRoPScxMDAlJzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbkhlaWdodD0nMTAxNHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heEhlaWdodD0oZGl2RWxlbWVudC5vZmZzZXRXaWR0aCowLjc1KSsncHgnOw0KICB9IGVsc2UgaWYgKGRpdkVsZW1lbnQub2Zmc2V0V2lkdGggPiA1MDApIHsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbldpZHRoPScxMjAwcHgnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWF4V2lkdGg9JzEwMCUnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWluSGVpZ2h0PScxMDE0cHgnOw0KICAgIHZpekVsZW1lbnQuc3R5bGUubWF4SGVpZ2h0PShkaXZFbGVtZW50Lm9mZnNldFdpZHRoKjAuNzUpKydweCc7DQogIH0gZWxzZSB7DQogICAgdml6RWxlbWVudC5zdHlsZS5taW5XaWR0aD0nMTAxNnB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heFdpZHRoPScxMDAlJzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1pbkhlaWdodD0nMTc1MHB4JzsNCiAgICB2aXpFbGVtZW50LnN0eWxlLm1heEhlaWdodD0oZGl2RWxlbWVudC5vZmZzZXRXaWR0aCoxLjc3KSsncHgnOw0KICB9DQogIHZhciBzY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7DQogIHNjcmlwdEVsZW1lbnQuc3JjID0gJ2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL2phdmFzY3JpcHRzL2FwaS92aXpfdjEuanMnOw0KICB2aXpFbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdEVsZW1lbnQsIHZpekVsZW1lbnQpOw0KPC9zY3JpcHQ+DQoNCmBgYA0KDQpbT3BlbiB0aGUgVGFibGVhdSBQdWJsaWMgRGFzaGJvYXJkXShodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9EYXNoYm9hcmQxPzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMgRW1iZWRkZWQgVGFibGVhdSBQdWJsaWMgU3RvcnkgUG9pbnRzDQoNCiMjIFN0b3J5IFBvaW50IDE6IE92ZXJhbGwgQnVzaW5lc3MgUGVyZm9ybWFuY2UNCg0KVGhpcyBzdG9yeSBwb2ludCBpbnRyb2R1Y2VzIHRoZSBvdmVyYWxsIHB1cnBvc2Ugb2YgdGhlIGRhc2hib2FyZC4gSXQgcHJvdmlkZXMgYSBoaWdoLWxldmVsIHZpZXcgb2YgU3VwZXJzdG9yZSBwZXJmb3JtYW5jZSBhbmQgZnJhbWVzIHRoZSBjZW50cmFsIGJ1c2luZXNzIHF1ZXN0aW9uOiB3aGljaCBwYXJ0cyBvZiB0aGUgY29tcGFueSBhcmUgZ2VuZXJhdGluZyBzdHJvbmcgc2FsZXMgYW5kIHdoaWNoIGFyZWFzIGFyZSBwcm9kdWNpbmcgd2Vha2VyIHByb2ZpdGFiaWxpdHk/DQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODMzOTg5NScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTEnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTEvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTEnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkxLzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4MzM5ODk1Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgMV0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkxPzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMjIFN0b3J5IFBvaW50IDI6IFByb2R1Y3QgUGVyZm9ybWFuY2UNCg0KVGhpcyBzdG9yeSBwb2ludCBmb2N1c2VzIG9uIHByb2R1Y3QgY2F0ZWdvcnkgYW5kIHN1Yi1jYXRlZ29yeSBwZXJmb3JtYW5jZS4gSXQgZXhwbGFpbnMgd2hpY2ggcHJvZHVjdCBncm91cHMgZ2VuZXJhdGUgdGhlIG1vc3Qgc2FsZXMgYW5kIHdoZXRoZXIgdGhvc2UgcHJvZHVjdHMgYXJlIGFsc28gcHJvZml0YWJsZS4NCg0KYGBgez1odG1sfQ0KDQo8ZGl2IGNsYXNzPSd0YWJsZWF1UGxhY2Vob2xkZXInIGlkPSd2aXoxNzgyMTM4NjA2Njg2JyBzdHlsZT0ncG9zaXRpb246IHJlbGF0aXZlJz4NCiAgPG5vc2NyaXB0Pg0KICAgIDxhIGhyZWY9JyMnPg0KICAgICAgPGltZyBhbHQ9J1N0b3J5Micgc3JjPSdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9zdGF0aWMvaW1hZ2VzL1ByL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5Mi8xX3Jzcy5wbmcnIHN0eWxlPSdib3JkZXI6IG5vbmUnIC8+DQogICAgPC9hPg0KICA8L25vc2NyaXB0Pg0KICA8b2JqZWN0IGNsYXNzPSd0YWJsZWF1Vml6JyBzdHlsZT0nZGlzcGxheTpub25lOyc+DQogICAgPHBhcmFtIG5hbWU9J2hvc3RfdXJsJyB2YWx1ZT0naHR0cHMlM0ElMkYlMkZwdWJsaWMudGFibGVhdS5jb20lMkYnIC8+DQogICAgPHBhcmFtIG5hbWU9J2VtYmVkX2NvZGVfdmVyc2lvbicgdmFsdWU9JzMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3NpdGVfcm9vdCcgdmFsdWU9JycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbmFtZScgdmFsdWU9J1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5MicgLz4NCiAgICA8cGFyYW0gbmFtZT0ndGFicycgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0ndG9vbGJhcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc3RhdGljX2ltYWdlJyB2YWx1ZT0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTIvMS5wbmcnIC8+DQogICAgPHBhcmFtIG5hbWU9J2FuaW1hdGVfdHJhbnNpdGlvbicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9zdGF0aWNfaW1hZ2UnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3Bpbm5lcicgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9vdmVybGF5JyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X2NvdW50JyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdsYW5ndWFnZScgdmFsdWU9J2VuLVVTJyAvPg0KICA8L29iamVjdD4NCjwvZGl2Pg0KDQo8c2NyaXB0IHR5cGU9J3RleHQvamF2YXNjcmlwdCc+DQogIHZhciBkaXZFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpejE3ODIxMzg2MDY2ODYnKTsNCiAgdmFyIHZpekVsZW1lbnQgPSBkaXZFbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdvYmplY3QnKVswXTsNCiAgdml6RWxlbWVudC5zdHlsZS53aWR0aD0nMTAxNnB4JzsNCiAgdml6RWxlbWVudC5zdHlsZS5oZWlnaHQ9JzEwMTRweCc7DQogIHZhciBzY3JpcHRFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7DQogIHNjcmlwdEVsZW1lbnQuc3JjID0gJ2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL2phdmFzY3JpcHRzL2FwaS92aXpfdjEuanMnOw0KICB2aXpFbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdEVsZW1lbnQsIHZpekVsZW1lbnQpOw0KPC9zY3JpcHQ+DQoNCmBgYA0KDQpbT3BlbiBTdG9yeSBQb2ludCAyXShodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTI/Omxhbmd1YWdlPWVuLVVTJjpzaWQ9JjpyZWRpcmVjdD1hdXRoJjpkaXNwbGF5X2NvdW50PW4mOm9yaWdpbj12aXpfc2hhcmVfbGluaykNCg0KIyMgU3RvcnkgUG9pbnQgMzogU2FsZXMgdnMuIFByb2ZpdCBSZWxhdGlvbnNoaXANCg0KVGhpcyBzdG9yeSBwb2ludCBleGFtaW5lcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gc2FsZXMgYW5kIHByb2ZpdC4gVGhlIHNjYXR0ZXIgcGxvdCBoZWxwcyBpZGVudGlmeSB3aGV0aGVyIGhpZ2hlciBzYWxlcyBnZW5lcmFsbHkgbGVhZCB0byBoaWdoZXIgcHJvZml0IGFuZCBoaWdobGlnaHRzIHBvc3NpYmxlIG91dGxpZXJzLg0KDQpgYGB7PWh0bWx9DQoNCjxkaXYgY2xhc3M9J3RhYmxlYXVQbGFjZWhvbGRlcicgaWQ9J3ZpejE3ODIxMzg2NDcyMzUnIHN0eWxlPSdwb3NpdGlvbjogcmVsYXRpdmUnPg0KICA8bm9zY3JpcHQ+DQogICAgPGEgaHJlZj0nIyc+DQogICAgICA8aW1nIGFsdD0nU3RvcnkzJyBzcmM9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkzLzFfcnNzLnBuZycgc3R5bGU9J2JvcmRlcjogbm9uZScgLz4NCiAgICA8L2E+DQogIDwvbm9zY3JpcHQ+DQogIDxvYmplY3QgY2xhc3M9J3RhYmxlYXVWaXonIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCiAgICA8cGFyYW0gbmFtZT0naG9zdF91cmwnIHZhbHVlPSdodHRwcyUzQSUyRiUyRnB1YmxpYy50YWJsZWF1LmNvbSUyRicgLz4NCiAgICA8cGFyYW0gbmFtZT0nZW1iZWRfY29kZV92ZXJzaW9uJyB2YWx1ZT0nMycgLz4NCiAgICA8cGFyYW0gbmFtZT0nc2l0ZV9yb290JyB2YWx1ZT0nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSduYW1lJyB2YWx1ZT0nUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3RvcnkzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSd0YWJzJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSd0b29sYmFyJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzdGF0aWNfaW1hZ2UnIHZhbHVlPSdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9zdGF0aWMvaW1hZ2VzL1ByL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5My8xLnBuZycgLz4NCiAgICA8cGFyYW0gbmFtZT0nYW5pbWF0ZV90cmFuc2l0aW9uJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3N0YXRpY19pbWFnZScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9zcGlubmVyJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X292ZXJsYXknIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfY291bnQnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2xhbmd1YWdlJyB2YWx1ZT0nZW4tVVMnIC8+DQogIDwvb2JqZWN0Pg0KPC9kaXY+DQoNCjxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0Jz4NCiAgdmFyIGRpdkVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndml6MTc4MjEzODY0NzIzNScpOw0KICB2YXIgdml6RWxlbWVudCA9IGRpdkVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ29iamVjdCcpWzBdOw0KICB2aXpFbGVtZW50LnN0eWxlLndpZHRoPScxMDE2cHgnOw0KICB2aXpFbGVtZW50LnN0eWxlLmhlaWdodD0nMTAxNHB4JzsNCiAgdmFyIHNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsNCiAgc2NyaXB0RWxlbWVudC5zcmMgPSAnaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vamF2YXNjcmlwdHMvYXBpL3Zpel92MS5qcyc7DQogIHZpekVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2NyaXB0RWxlbWVudCwgdml6RWxlbWVudCk7DQo8L3NjcmlwdD4NCg0KYGBgDQoNCltPcGVuIFN0b3J5IFBvaW50IDNdKGh0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3ZpZXdzL1Byb2plY3Q0XzE3ODIxMzc2NjQyODEwL1N0b3J5Mz86bGFuZ3VhZ2U9ZW4tVVMmOnNpZD0mOnJlZGlyZWN0PWF1dGgmOmRpc3BsYXlfY291bnQ9biY6b3JpZ2luPXZpel9zaGFyZV9saW5rKQ0KDQojIyBTdG9yeSBQb2ludCA0OiBHZW9ncmFwaGljIFBlcmZvcm1hbmNlDQoNClRoaXMgc3RvcnkgcG9pbnQgYWRkcyBhIHJlZ2lvbmFsIHBlcnNwZWN0aXZlIHRvIHRoZSBkYXNoYm9hcmQuIEJ5IGNvbXBhcmluZyBzYWxlcyBhbmQgcHJvZml0IGFjcm9zcyBzdGF0ZXMgb3IgcmVnaW9ucywgdGhlIHZpZXdlciBjYW4gc2VlIHdoZXJlIFN1cGVyc3RvcmUgcGVyZm9ybXMgc3Ryb25nZXN0IGFuZCB3aGVyZSBwcm9maXRhYmlsaXR5IG1heSBiZSB3ZWFrZXIuDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODY2OTM1OCcgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTQnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTQvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTQnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk0LzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4NjY5MzU4Jyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgNF0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk0PzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMjIFN0b3J5IFBvaW50IDU6IEN1c3RvbWVyIFNlZ21lbnQgSW5zaWdodHMgYW5kIFJlY29tbWVuZGF0aW9ucw0KDQpUaGlzIGZpbmFsIHN0b3J5IHBvaW50IHN1bW1hcml6ZXMgdGhlIGRhc2hib2FyZCBmaW5kaW5ncyBhbmQgY29ubmVjdHMgdGhlbSB0byBidXNpbmVzcyByZWNvbW1lbmRhdGlvbnMuIEl0IGZvY3VzZXMgb24gY3VzdG9tZXIgc2VnbWVudHMgYW5kIGV4cGxhaW5zIGhvdyBTdXBlcnN0b3JlIGNhbiB1c2UgdGhlIGRhc2hib2FyZCB0byBtYWtlIGJldHRlciBkZWNpc2lvbnMuDQoNCmBgYHs9aHRtbH0NCg0KPGRpdiBjbGFzcz0ndGFibGVhdVBsYWNlaG9sZGVyJyBpZD0ndml6MTc4MjEzODcwNDU5MScgc3R5bGU9J3Bvc2l0aW9uOiByZWxhdGl2ZSc+DQogIDxub3NjcmlwdD4NCiAgICA8YSBocmVmPScjJz4NCiAgICAgIDxpbWcgYWx0PSdTdG9yeTUnIHNyYz0naHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vc3RhdGljL2ltYWdlcy9Qci9Qcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTUvMV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPg0KICAgIDwvYT4NCiAgPC9ub3NjcmlwdD4NCiAgPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgc3R5bGU9J2Rpc3BsYXk6bm9uZTsnPg0KICAgIDxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQogICAgPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdQcm9qZWN0NF8xNzgyMTM3NjY0MjgxMC9TdG9yeTUnIC8+DQogICAgPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J3N0YXRpY19pbWFnZScgdmFsdWU9J2h0dHBzOi8vcHVibGljLnRhYmxlYXUuY29tL3N0YXRpYy9pbWFnZXMvUHIvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk1LzEucG5nJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KICAgIDxwYXJhbSBuYW1lPSdkaXNwbGF5X3NwaW5uZXInIHZhbHVlPSd5ZXMnIC8+DQogICAgPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCiAgICA8cGFyYW0gbmFtZT0nbGFuZ3VhZ2UnIHZhbHVlPSdlbi1VUycgLz4NCiAgPC9vYmplY3Q+DQo8L2Rpdj4NCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPg0KICB2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzgyMTM4NzA0NTkxJyk7DQogIHZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07DQogIHZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMTZweCc7DQogIHZpekVsZW1lbnQuc3R5bGUuaGVpZ2h0PScxMDE0cHgnOw0KICB2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOw0KICBzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsNCiAgdml6RWxlbWVudC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHRFbGVtZW50LCB2aXpFbGVtZW50KTsNCjwvc2NyaXB0Pg0KDQpgYGANCg0KW09wZW4gU3RvcnkgUG9pbnQgNV0oaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vdmlld3MvUHJvamVjdDRfMTc4MjEzNzY2NDI4MTAvU3Rvcnk1PzpsYW5ndWFnZT1lbi1VUyY6c2lkPSY6cmVkaXJlY3Q9YXV0aCY6ZGlzcGxheV9jb3VudD1uJjpvcmlnaW49dml6X3NoYXJlX2xpbmspDQoNCiMgUmVjb21tZW5kYXRpb25zDQoNCkJhc2VkIG9uIHRoZSBkYXNoYm9hcmQgYW5kIHN0b3J5IHBvaW50cywgU3VwZXJzdG9yZSBtYW5hZ2VycyBzaG91bGQgY29uc2lkZXIgdGhlIGZvbGxvd2luZyBhY3Rpb25zOg0KDQoxLiBGb2N1cyBvbiBwcm9kdWN0IHN1Yi1jYXRlZ29yaWVzIHRoYXQgZ2VuZXJhdGUgYm90aCBzdHJvbmcgc2FsZXMgYW5kIHN0cm9uZyBwcm9maXQuDQoyLiBJbnZlc3RpZ2F0ZSBzdWItY2F0ZWdvcmllcyB3aXRoIGhpZ2ggc2FsZXMgYnV0IHdlYWsgb3IgbmVnYXRpdmUgcHJvZml0Lg0KMy4gUmV2aWV3IGRpc2NvdW50aW5nIHByYWN0aWNlcyBpbiBsb3ctcHJvZml0IHByb2R1Y3QgZ3JvdXBzLg0KNC4gQ29tcGFyZSByZWdpb25hbCBwZXJmb3JtYW5jZSB0byBpZGVudGlmeSBtYXJrZXRzIHRoYXQgbmVlZCBpbXByb3ZlbWVudC4NCjUuIFVzZSBjdXN0b21lciBzZWdtZW50IGluc2lnaHRzIHRvIHRhcmdldCB0aGUgbW9zdCB2YWx1YWJsZSBjdXN0b21lciBncm91cHMuDQo2LiBNb25pdG9yIHByb2ZpdCByYXRpbyBhbG9uZ3NpZGUgdG90YWwgc2FsZXMgdG8gYXZvaWQgcHVyc3VpbmcgcmV2ZW51ZSBncm93dGggdGhhdCBkb2VzIG5vdCBpbXByb3ZlIHByb2ZpdGFiaWxpdHkuDQoNCiMgQ29uY2x1c2lvbg0KDQpUaGUgVGFibGVhdSBkYXNoYm9hcmQgcHJvdmlkZXMgYSBjbGVhciBhbmQgaW50ZXJhY3RpdmUgdmlldyBvZiBTdXBlcnN0b3JlIHBlcmZvcm1hbmNlLiBJdCBzaG93cyB0aGF0IHNhbGVzLCBwcm9maXQsIHByb2R1Y3QgY2F0ZWdvcnksIHJlZ2lvbiwgYW5kIGN1c3RvbWVyIHNlZ21lbnQgbXVzdCBiZSBhbmFseXplZCB0b2dldGhlciB0byBtYWtlIHN0cm9uZyBidXNpbmVzcyBkZWNpc2lvbnMuIFRoZSBkYXNoYm9hcmQgc3VwcG9ydHMgdGhlIHByb2plY3QgZ29hbCBieSBjb21iaW5pbmcgbXVsdGlwbGUgY2hhcnQgdHlwZXMgaW50byBvbmUgaW50ZXJjb25uZWN0ZWQgdmlzdWFsIHN0b3J5Lg0KDQpUaGUgbW9zdCBpbXBvcnRhbnQgY29uY2x1c2lvbiBpcyB0aGF0ICoqcHJvZml0YWJsZSBncm93dGggbWF0dGVycyBtb3JlIHRoYW4gc2FsZXMgZ3Jvd3RoIGFsb25lKiouIEJ5IHVzaW5nIGZpbHRlcnMsIGRhc2hib2FyZHMsIGFuZCBzdG9yeSBwb2ludHMsIHZpZXdlcnMgY2FuIGlkZW50aWZ5IHdoZXJlIFN1cGVyc3RvcmUgaXMgcGVyZm9ybWluZyB3ZWxsLCB3aGVyZSBpdCBpcyBsb3NpbmcgcHJvZml0LCBhbmQgd2hlcmUgbWFuYWdlbWVudCBzaG91bGQgZm9jdXMgZnV0dXJlIGltcHJvdmVtZW50IGVmZm9ydHMuDQo=