1 Introduction

A dashboard is a collection of several (interactive) graphics that allow viewers to compare a variety of data simultaneously in one place. For example, in the presidential election data, we can create a county-level election map and a state-level map and place both of them on the same graphical page and both maps are coordinated simultaneously. In other words, we can create a dashboard that displays all the views at once, rather than navigate to separate Tableau graphics.

If data in sheets and dashboards is connected to a real-time database, both sheets and dashboards will update in real-time with the latest available data from the data source. There are different types of dashboards used for different purposes.

Operational Dashboards – provide a comprehensive snapshot of the performance of a business process that allows us to incorporate a large amount of detail without using too many drill-downs.

Analytical Dashboards – use historical data to identify future trends for decision-making. Users with a level of technical understanding of data can interact with the data on an analytical dashboard.

Strategic Dashboards – track performance in relation to key performance indicators, to better align actions with strategy.

You can name other different dashboards that are used on different occasions.

2 Dashboard Design and Case Study

This section provides some details on dashboard type, designs, and implementation with a widely used data set.

2.1 Some Design Considerations

Several considerations need to be kept in mind when designing an analytical dashboard.

Audience/Users - the types of audience and target users determine the level of granularity of information and technical complexities.

Important and Related Information - what is the key information? What other information explains or augments the key information? relevant patterns impacted by the key information, etc.

Appropriate Charts - refer to the directory of graphics and maps to create individual graphics and put them together to make a dashboard. Each individual graphic should designed based on the basic principles of visual designs that include but are not limited to titles, labels, annotations, color schemes, use of marks and channels, movement, interactivity, etc.

Dashboard Layout - is about how to place different but related graphics on the appropriate spots so that the dashboard is easy to understand for users and can effectively deliver coherent information among individual charts. As a convention in analytic dashboards, the key information should be placed on the top, and supporting information should be at the bottom of the dashboards.

Filters and Animations - are good for displaying more granular information. However, they should be used only if it is necessary.

Avoid Cluttered Dashboards - It is easy to overload a dashboard designer because too much important information is worth being displayed, in particular, when a data set contains rich information. However, dashboard clutter will decrease the efficiency of delivering the key information.

2.2 Working Data Set

We use a widely used Stationery Superstore data set to illustrate the logic and common practices in designing an analytical dashboard.

SuperStore = read.csv("https://pengdsci.github.io/STA553VIZ/w10/SuperstoreOrdersData.csv")
summary(SuperStore)
     Row.ID       Order.ID          Order.Date         Ship.Date        
 Min.   :   1   Length:9994        Length:9994        Length:9994       
 1st Qu.:2499   Class :character   Class :character   Class :character  
 Median :4998   Mode  :character   Mode  :character   Mode  :character  
 Mean   :4998                                                           
 3rd Qu.:7496                                                           
 Max.   :9994                                                           
  Ship.Mode         Customer.ID        Customer.Name        Segment         
 Length:9994        Length:9994        Length:9994        Length:9994       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
   Country              City              State            Postal.Code   
 Length:9994        Length:9994        Length:9994        Min.   : 1040  
 Class :character   Class :character   Class :character   1st Qu.:23223  
 Mode  :character   Mode  :character   Mode  :character   Median :56431  
                                                          Mean   :55190  
                                                          3rd Qu.:90008  
                                                          Max.   :99301  
    Region           Product.ID          Category         Sub.Category      
 Length:9994        Length:9994        Length:9994        Length:9994       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
 Product.Name           Sales              Quantity        Discount     
 Length:9994        Min.   :    0.444   Min.   : 1.00   Min.   :0.0000  
 Class :character   1st Qu.:   17.280   1st Qu.: 2.00   1st Qu.:0.0000  
 Mode  :character   Median :   54.490   Median : 3.00   Median :0.2000  
                    Mean   :  229.858   Mean   : 3.79   Mean   :0.1562  
                    3rd Qu.:  209.940   3rd Qu.: 5.00   3rd Qu.:0.2000  
                    Max.   :22638.480   Max.   :14.00   Max.   :0.8000  
     Profit         
 Min.   :-6599.978  
 1st Qu.:    1.729  
 Median :    8.666  
 Mean   :   28.657  
 3rd Qu.:   29.364  
 Max.   : 8399.976  

There are three types of variables related to Product information, order information, and sales information. Some variables can be used as geo-variables.

2.3 Superstore Profits and Sales

The following dashboard was designed based on the following considerations:

Users/Clients: sales manager or similar roles

Key Information: Look at the process generation from different perspectives and identify the patterns for making business decisions. For example,

  • Sales KPI
  • Total revenue (profit)
  • Total sales by time period
  • Revenue per sale
  • Revenue by product types
  • Market penetration
  • Revenue generation by customer segments
  • Average customer lifetime
  • Customer satisfaction (net promotor scores, etc.)
  • Number of sales lost to competition
  • Revenue by territory (regions, customer segments, etc.)
  • Revenue by market
  • Ratio of selling cost and revenue generation
  • and more…..



Critiques and Recommendations for Improvement

  • Selection of information for visualization
  • Design perspectives
    • individual charts
    • Overall design of dashboard (layout)
    • orchestration of individual charts
    • design aesthetics

3 Tableau Story Points

Tableau can create a form of presentation of the existing individual chart so we can tell the story based on the individual Tableau charts. In terms of design, it is relatively less challenging since the story point uses a sequence of logically connected individual Tableau visual sheets to tell a data story.

Although a little design effort is needed for the story point, the same level of significant design effort needs to be put into individual visual sheets.

The following is an incomplete sample of a story point based on the previous dashboard. Each individual visual sheet should have a brief and descriptive caption about the information.


4 Assignments of This Week

This assignment focuses on Tableau dashboards and story points. You can choose a data set that has both numerical and categorical variables so you can create several charts such as histograms, scatter plots, frequency tables, pie charts, etc. using both types of variables.

4.1 The Minimum Requirements

I will not give you a data set for this assignment. You can find a data set from any sources including my project data page (https://pengdsci.github.io/datasets/) that meets the following requirement.

  1. Choose a data set with at least two numerical variables so you can construct a histogram and scatter plots.

  2. The data set should have at least three categorical variables so you can create pie charts, bar plots, etc.

  3. You are expected to use at least one filter that updates all charts in the dashboard (reactive dashboard).

  4. Give a descriptive title and axis labels to individual charts and dashboards respectively.

  5. Adjust the margins of the individual chart and make the dashboard tidy and informative.

  6. Create a story point and provide informative captions for storytelling.

  7. (optional) If you have geo-information in your data set, you can create maps including animated maps.

  8. (optional) If you want to use more advanced topics such as derived variables and parameters to enhance your dashboard, you are very welcome to do so.

4.2 Submission Requirements:

  1. Publish your dashboard and story point on the Tableau Public server.

  2. Write a report using an RMD document to include both the Tableau dashboard and story-point on the same web page.

  3. You publish the report on either RPubs or placed it in your GitHub repository.

  4. update your online CV with the link to your assignment (optional).

  5. Submit the URL of your HTML report generated from RMD and make sure your RMD source is downloadable from your HTML report.

4.3 Suggested YAML Header Output Set-up

---
title: "You Report Title (concise and descriptive)"
author: "Your Name"
date: "West Chester University"
output: 
  html_document: 
    toc: yes
    toc_depth: 4
    toc_float: no
    code_folding: hide
    code_download: yes
    smooth_scroll: yes
    number_sections: yes
    theme: readable
---
      
<style type="text/css">
div#TOC li {
    list-style:none;
    background-image:none;
    background-repeat:none;
    background-position:0;
}
h1.title {
  font-size: 24px;
  color: DarkRed;
  text-align: center;
}
h4.author { 
  /* Header 4 - and the author and data headers use this too  */
  font-size: 18px;
  font-family: "Times New Roman", Times, serif;
  color: DarkRed;
  text-align: center;
}
h4.date { 
  /* Header 4 - and the author and data headers use this too  */
  font-size: 18px;
  font-family: "Times New Roman", Times, serif;
  color: DarkBlue;
  text-align: center;
}
h1 { 
    /* Header 3 - and the author and data headers use this too  */
    font-size: 22px;
    font-family: "Times New Roman", Times, serif;
    color: darkred;
    text-align: center;
}
h2 { 
    /* Header 3 - and the author and data headers use this too  */
    font-size: 18px;
    font-family: "Times New Roman", Times, serif;
    color: navy;
    text-align: left;
}
h3 { 
    /* Header 3 - and the author and data headers use this too  */
    font-size: 15px;
    font-family: "Times New Roman", Times, serif;
    color: darkred;
    font-face: bold;
    text-align: left;
}
h4 { 
    /* Header 4 - and the author and data headers use this too  */
    font-size: 18px;
    font-family: "Times New Roman", Times, serif;
    color: darkred;
    text-align: left;
}
   /* center maps using chunk option: fig.align='center' */
.html-widget {
    margin: auto;
}
</style>

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE,       
                      warning = FALSE,   
                      result = TRUE,   
                      message = FALSE,
                      comment = NA)
```
LS0tDQp0aXRsZTogIkFuYWx5dGljIERhc2hib2FyZHMgd2l0aCBUYWJsZWF1Ig0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSINCm91dHB1dDogDQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiBubw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IHJlYWRhYmxlDQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCmRpdiNUT0MgbGkgew0KICAgIGxpc3Qtc3R5bGU6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOm5vbmU7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOjA7DQp9DQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgY29sb3I6IERhcmtSZWQ7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmg0LmF1dGhvciB7IA0KICAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsgDQogICAgLyogSGVhZGVyIDMgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDIycHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgeyANCiAgICAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KaDMgeyANCiAgICAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICBmb250LWZhY2U6IGJvbGQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCmg0IHsgDQogICAgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgICBmb250LXNpemU6IDE4cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCiAgIC8qIGNlbnRlciBtYXBzIHVzaW5nIGNodW5rIG9wdGlvbjogZmlnLmFsaWduPSdjZW50ZXInICovDQouaHRtbC13aWRnZXQgew0KICAgIG1hcmdpbjogYXV0bzsNCn0NCjwvc3R5bGU+DQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gRkFMU0UsICAgDQogICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVFJVRSwgICANCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsDQogICAgICAgICAgICAgICAgICAgICAgY29tbWVudCA9IE5BKQ0KYGBgDQoNClwNCg0KDQojIEludHJvZHVjdGlvbg0KDQpBIGRhc2hib2FyZCBpcyBhIGNvbGxlY3Rpb24gb2Ygc2V2ZXJhbCAoaW50ZXJhY3RpdmUpIGdyYXBoaWNzIHRoYXQgYWxsb3cgdmlld2VycyB0byBjb21wYXJlIGEgdmFyaWV0eSBvZiBkYXRhIHNpbXVsdGFuZW91c2x5IGluIG9uZSBwbGFjZS4gRm9yIGV4YW1wbGUsIGluIHRoZSBwcmVzaWRlbnRpYWwgZWxlY3Rpb24gZGF0YSwgd2UgY2FuIGNyZWF0ZSBhIGNvdW50eS1sZXZlbCBlbGVjdGlvbiBtYXAgYW5kIGEgc3RhdGUtbGV2ZWwgbWFwIGFuZCBwbGFjZSBib3RoIG9mIHRoZW0gb24gdGhlIHNhbWUgZ3JhcGhpY2FsIHBhZ2UgYW5kIGJvdGggbWFwcyBhcmUgY29vcmRpbmF0ZWQgc2ltdWx0YW5lb3VzbHkuIEluIG90aGVyIHdvcmRzLCB3ZSBjYW4gY3JlYXRlIGEgZGFzaGJvYXJkIHRoYXQgZGlzcGxheXMgYWxsIHRoZSB2aWV3cyBhdCBvbmNlLCByYXRoZXIgdGhhbiBuYXZpZ2F0ZSB0byBzZXBhcmF0ZSBUYWJsZWF1IGdyYXBoaWNzLg0KDQpJZiBkYXRhIGluIHNoZWV0cyBhbmQgZGFzaGJvYXJkcyBpcyBjb25uZWN0ZWQgdG8gYSByZWFsLXRpbWUgZGF0YWJhc2UsIGJvdGggc2hlZXRzIGFuZCBkYXNoYm9hcmRzIHdpbGwgdXBkYXRlIGluIHJlYWwtdGltZSB3aXRoIHRoZSBsYXRlc3QgYXZhaWxhYmxlIGRhdGEgZnJvbSB0aGUgZGF0YSBzb3VyY2UuIFRoZXJlIGFyZSBkaWZmZXJlbnQgdHlwZXMgb2YgZGFzaGJvYXJkcyB1c2VkIGZvciBkaWZmZXJlbnQgcHVycG9zZXMuDQoNCioqT3BlcmF0aW9uYWwgRGFzaGJvYXJkcyoqIOKAkyBwcm92aWRlIGEgY29tcHJlaGVuc2l2ZSBzbmFwc2hvdCBvZiB0aGUgcGVyZm9ybWFuY2Ugb2YgYSBidXNpbmVzcyBwcm9jZXNzIHRoYXQgYWxsb3dzIHVzIHRvIGluY29ycG9yYXRlIGEgbGFyZ2UgYW1vdW50IG9mIGRldGFpbCB3aXRob3V0IHVzaW5nIHRvbyBtYW55IGRyaWxsLWRvd25zLg0KDQoqKkFuYWx5dGljYWwgRGFzaGJvYXJkcyoqIOKAkyB1c2UgaGlzdG9yaWNhbCBkYXRhIHRvIGlkZW50aWZ5IGZ1dHVyZSB0cmVuZHMgZm9yIGRlY2lzaW9uLW1ha2luZy4gVXNlcnMgd2l0aCBhIGxldmVsIG9mIHRlY2huaWNhbCB1bmRlcnN0YW5kaW5nIG9mIGRhdGEgY2FuIGludGVyYWN0IHdpdGggdGhlIGRhdGEgb24gYW4gYW5hbHl0aWNhbCBkYXNoYm9hcmQuDQoNCioqU3RyYXRlZ2ljIERhc2hib2FyZHMqKiDigJMgdHJhY2sgcGVyZm9ybWFuY2UgaW4gcmVsYXRpb24gdG8ga2V5IHBlcmZvcm1hbmNlIGluZGljYXRvcnMsIHRvIGJldHRlciBhbGlnbiBhY3Rpb25zIHdpdGggc3RyYXRlZ3kuIA0KDQpZb3UgY2FuIG5hbWUgb3RoZXIgZGlmZmVyZW50IGRhc2hib2FyZHMgdGhhdCBhcmUgdXNlZCBvbiBkaWZmZXJlbnQgb2NjYXNpb25zLiANCg0KDQoNCiMgRGFzaGJvYXJkIERlc2lnbiBhbmQgQ2FzZSBTdHVkeQ0KDQpUaGlzIHNlY3Rpb24gcHJvdmlkZXMgc29tZSBkZXRhaWxzIG9uIGRhc2hib2FyZCB0eXBlLCBkZXNpZ25zLCBhbmQgaW1wbGVtZW50YXRpb24gd2l0aCBhIHdpZGVseSB1c2VkIGRhdGEgc2V0Lg0KDQojIyBTb21lIERlc2lnbiBDb25zaWRlcmF0aW9ucw0KDQpTZXZlcmFsIGNvbnNpZGVyYXRpb25zIG5lZWQgdG8gYmUga2VwdCBpbiBtaW5kIHdoZW4gZGVzaWduaW5nIGFuIGFuYWx5dGljYWwgZGFzaGJvYXJkLg0KDQoqKkF1ZGllbmNlL1VzZXJzKiogLSB0aGUgdHlwZXMgb2YgYXVkaWVuY2UgYW5kIHRhcmdldCB1c2VycyBkZXRlcm1pbmUgdGhlIGxldmVsIG9mIGdyYW51bGFyaXR5IG9mIGluZm9ybWF0aW9uIGFuZCB0ZWNobmljYWwgY29tcGxleGl0aWVzLiAgIA0KDQoqKkltcG9ydGFudCBhbmQgUmVsYXRlZCBJbmZvcm1hdGlvbioqIC0gd2hhdCBpcyB0aGUga2V5IGluZm9ybWF0aW9uPyBXaGF0IG90aGVyIGluZm9ybWF0aW9uIGV4cGxhaW5zIG9yIGF1Z21lbnRzIHRoZSBrZXkgaW5mb3JtYXRpb24/IHJlbGV2YW50IHBhdHRlcm5zIGltcGFjdGVkIGJ5IHRoZSBrZXkgaW5mb3JtYXRpb24sIGV0Yy4gIA0KDQoqKkFwcHJvcHJpYXRlIENoYXJ0cyoqIC0gcmVmZXIgdG8gdGhlIGRpcmVjdG9yeSBvZiBncmFwaGljcyBhbmQgbWFwcyB0byBjcmVhdGUgaW5kaXZpZHVhbCBncmFwaGljcyBhbmQgcHV0IHRoZW0gdG9nZXRoZXIgdG8gbWFrZSBhIGRhc2hib2FyZC4gRWFjaCBpbmRpdmlkdWFsIGdyYXBoaWMgc2hvdWxkIGRlc2lnbmVkIGJhc2VkIG9uIHRoZSBiYXNpYyBwcmluY2lwbGVzIG9mIHZpc3VhbCBkZXNpZ25zIHRoYXQgaW5jbHVkZSBidXQgYXJlIG5vdCBsaW1pdGVkIHRvIHRpdGxlcywgbGFiZWxzLCBhbm5vdGF0aW9ucywgY29sb3Igc2NoZW1lcywgdXNlIG9mIG1hcmtzIGFuZCBjaGFubmVscywgbW92ZW1lbnQsIGludGVyYWN0aXZpdHksIGV0Yy4gDQoNCioqRGFzaGJvYXJkIExheW91dCoqIC0gaXMgYWJvdXQgaG93IHRvIHBsYWNlIGRpZmZlcmVudCBidXQgcmVsYXRlZCBncmFwaGljcyBvbiB0aGUgYXBwcm9wcmlhdGUgc3BvdHMgc28gdGhhdCB0aGUgZGFzaGJvYXJkIGlzIGVhc3kgdG8gdW5kZXJzdGFuZCBmb3IgdXNlcnMgYW5kIGNhbiBlZmZlY3RpdmVseSBkZWxpdmVyIGNvaGVyZW50IGluZm9ybWF0aW9uIGFtb25nIGluZGl2aWR1YWwgY2hhcnRzLiBBcyBhIGNvbnZlbnRpb24gaW4gYW5hbHl0aWMgZGFzaGJvYXJkcywgdGhlIGtleSBpbmZvcm1hdGlvbiBzaG91bGQgYmUgcGxhY2VkIG9uIHRoZSB0b3AsIGFuZCBzdXBwb3J0aW5nIGluZm9ybWF0aW9uIHNob3VsZCBiZSBhdCB0aGUgYm90dG9tIG9mIHRoZSBkYXNoYm9hcmRzLg0KDQoqKkZpbHRlcnMgYW5kIEFuaW1hdGlvbnMqKiAtIGFyZSBnb29kIGZvciBkaXNwbGF5aW5nIG1vcmUgZ3JhbnVsYXIgaW5mb3JtYXRpb24uIEhvd2V2ZXIsIHRoZXkgc2hvdWxkIGJlIHVzZWQgb25seSBpZiBpdCBpcyBuZWNlc3NhcnkuIA0KDQoqKkF2b2lkIENsdXR0ZXJlZCBEYXNoYm9hcmRzKiogLSBJdCBpcyBlYXN5IHRvIG92ZXJsb2FkIGEgZGFzaGJvYXJkIGRlc2lnbmVyIGJlY2F1c2UgdG9vIG11Y2ggaW1wb3J0YW50IGluZm9ybWF0aW9uIGlzIHdvcnRoIGJlaW5nIGRpc3BsYXllZCwgaW4gcGFydGljdWxhciwgd2hlbiBhIGRhdGEgc2V0IGNvbnRhaW5zIHJpY2ggaW5mb3JtYXRpb24uIEhvd2V2ZXIsIGRhc2hib2FyZCBjbHV0dGVyIHdpbGwgZGVjcmVhc2UgdGhlIGVmZmljaWVuY3kgb2YgZGVsaXZlcmluZyB0aGUga2V5IGluZm9ybWF0aW9uLg0KDQoNCiMjIFdvcmtpbmcgRGF0YSBTZXQNCg0KV2UgdXNlIGEgd2lkZWx5IHVzZWQgU3RhdGlvbmVyeSBTdXBlcnN0b3JlIGRhdGEgc2V0IHRvIGlsbHVzdHJhdGUgdGhlIGxvZ2ljIGFuZCBjb21tb24gcHJhY3RpY2VzIGluIGRlc2lnbmluZyBhbiBhbmFseXRpY2FsIGRhc2hib2FyZC4NCg0KYGBge3J9DQpTdXBlclN0b3JlID0gcmVhZC5jc3YoImh0dHBzOi8vcGVuZ2RzY2kuZ2l0aHViLmlvL1NUQTU1M1ZJWi93MTAvU3VwZXJzdG9yZU9yZGVyc0RhdGEuY3N2IikNCnN1bW1hcnkoU3VwZXJTdG9yZSkNCmBgYA0KVGhlcmUgYXJlIHRocmVlIHR5cGVzIG9mIHZhcmlhYmxlcyByZWxhdGVkIHRvIFByb2R1Y3QgaW5mb3JtYXRpb24sIG9yZGVyIGluZm9ybWF0aW9uLCBhbmQgc2FsZXMgaW5mb3JtYXRpb24uIFNvbWUgdmFyaWFibGVzIGNhbiBiZSB1c2VkIGFzIGdlby12YXJpYWJsZXMuDQoNCg0KIyMgU3VwZXJzdG9yZSBQcm9maXRzIGFuZCBTYWxlcw0KDQpUaGUgZm9sbG93aW5nIGRhc2hib2FyZCB3YXMgZGVzaWduZWQgYmFzZWQgb24gdGhlIGZvbGxvd2luZyBjb25zaWRlcmF0aW9uczoNCg0KKipVc2Vycy9DbGllbnRzKio6IHNhbGVzIG1hbmFnZXIgb3Igc2ltaWxhciByb2xlcw0KDQoqKktleSBJbmZvcm1hdGlvbioqOiBMb29rIGF0IHRoZSBwcm9jZXNzIGdlbmVyYXRpb24gZnJvbSBkaWZmZXJlbnQgcGVyc3BlY3RpdmVzIGFuZCBpZGVudGlmeSB0aGUgcGF0dGVybnMgZm9yIG1ha2luZyBidXNpbmVzcyBkZWNpc2lvbnMuIEZvciBleGFtcGxlLCAgDQoNCiogU2FsZXMgS1BJDQoqIFRvdGFsIHJldmVudWUgKHByb2ZpdCkNCiogVG90YWwgc2FsZXMgYnkgdGltZSBwZXJpb2QNCiogUmV2ZW51ZSBwZXIgc2FsZQ0KKiBSZXZlbnVlIGJ5IHByb2R1Y3QgdHlwZXMNCiogTWFya2V0IHBlbmV0cmF0aW9uDQoqIFJldmVudWUgZ2VuZXJhdGlvbiBieSBjdXN0b21lciBzZWdtZW50cw0KKiBBdmVyYWdlIGN1c3RvbWVyIGxpZmV0aW1lDQoqIEN1c3RvbWVyIHNhdGlzZmFjdGlvbiAobmV0IHByb21vdG9yIHNjb3JlcywgZXRjLikNCiogTnVtYmVyIG9mIHNhbGVzIGxvc3QgdG8gY29tcGV0aXRpb24NCiogUmV2ZW51ZSBieSB0ZXJyaXRvcnkgKHJlZ2lvbnMsIGN1c3RvbWVyIHNlZ21lbnRzLCBldGMuKQ0KKiBSZXZlbnVlIGJ5IG1hcmtldA0KKiBSYXRpbyBvZiBzZWxsaW5nIGNvc3QgYW5kIHJldmVudWUgZ2VuZXJhdGlvbg0KKiBhbmQgbW9yZS4uLi4uDQoNCg0KPHRhYmxlIGJvcmRlciA9IDAgYm9yZGVyY29sb3I9ImRhcmtncmVlbiIgYmdjb2xvcj0nI2Y2ZjZmNicgIHdpZHRoPTExMCUgIGFsaWduID0gY2VudGVyPg0KPHRyPg0KPHRkPg0KDQo8ZGl2IGNsYXNzPSd0YWJsZWF1UGxhY2Vob2xkZXInIGlkPSd2aXoxNzExOTM0NzcxMzQ4JyBzdHlsZT0ncG9zaXRpb246IHJlbGF0aXZlJz4NCg0KPG5vc2NyaXB0PjxhIGhyZWY9JyMnPjxpbWcgYWx0PSdTYWxlcyBhbmQgUHJvZml0IG9mIEEgU3RhdGlvbmVyeSBTdXBlcnN0b3JlICcgc3JjPSdodHRwczomIzQ3OyYjNDc7cHVibGljLnRhYmxlYXUuY29tJiM0NztzdGF0aWMmIzQ3O2ltYWdlcyYjNDc7U3UmIzQ3O1N1cGVyc3RvcmVEYXRhU3RvcnlQb2ludCYjNDc7RGFzaGJvYXJkJiM0NzsxX3Jzcy5wbmcnIHN0eWxlPSdib3JkZXI6IG5vbmUnIC8+PC9hPg0KDQo8L25vc2NyaXB0Pg0KPG9iamVjdCBjbGFzcz0ndGFibGVhdVZpeicgIHN0eWxlPSdkaXNwbGF5Om5vbmU7Jz4NCjxwYXJhbSBuYW1lPSdob3N0X3VybCcgdmFsdWU9J2h0dHBzJTNBJTJGJTJGcHVibGljLnRhYmxlYXUuY29tJTJGJyAvPiANCjxwYXJhbSBuYW1lPSdlbWJlZF9jb2RlX3ZlcnNpb24nIHZhbHVlPSczJyAvPiANCjxwYXJhbSBuYW1lPSdzaXRlX3Jvb3QnIHZhbHVlPScnIC8+DQo8cGFyYW0gbmFtZT0nbmFtZScgdmFsdWU9J1N1cGVyc3RvcmVEYXRhU3RvcnlQb2ludCYjNDc7RGFzaGJvYXJkJyAvPg0KPHBhcmFtIG5hbWU9J3RhYnMnIHZhbHVlPSdubycgLz48cGFyYW0gbmFtZT0ndG9vbGJhcicgdmFsdWU9J3llcycgLz4NCjxwYXJhbSBuYW1lPSdzdGF0aWNfaW1hZ2UnIHZhbHVlPSdodHRwczomIzQ3OyYjNDc7cHVibGljLnRhYmxlYXUuY29tJiM0NztzdGF0aWMmIzQ3O2ltYWdlcyYjNDc7U3UmIzQ3O1N1cGVyc3RvcmVEYXRhU3RvcnlQb2ludCYjNDc7RGFzaGJvYXJkJiM0NzsxLnBuZycgLz4gDQo8cGFyYW0gbmFtZT0nYW5pbWF0ZV90cmFuc2l0aW9uJyB2YWx1ZT0neWVzJyAvPg0KPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3RhdGljX2ltYWdlJyB2YWx1ZT0neWVzJyAvPg0KPHBhcmFtIG5hbWU9J2Rpc3BsYXlfc3Bpbm5lcicgdmFsdWU9J3llcycgLz4NCjxwYXJhbSBuYW1lPSdkaXNwbGF5X292ZXJsYXknIHZhbHVlPSd5ZXMnIC8+DQo8cGFyYW0gbmFtZT0nZGlzcGxheV9jb3VudCcgdmFsdWU9J3llcycgLz4NCjxwYXJhbSBuYW1lPSdsYW5ndWFnZScgdmFsdWU9J2VuLVVTJyAvPg0KPHBhcmFtIG5hbWU9J2ZpbHRlcicgdmFsdWU9J3B1Ymxpc2g9eWVzJyAvPg0KPC9vYmplY3Q+DQoNCjwvZGl2PiAgICAgICAgICAgICAgICANCg0KPHNjcmlwdCB0eXBlPSd0ZXh0L2phdmFzY3JpcHQnPiAgICAgICAgICAgICAgICAgICAgDQp2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzExOTM0NzcxMzQ4Jyk7ICAgICAgICAgICAgICAgICAgICANCnZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07ICAgICAgICAgICAgICAgICAgICANCmlmICggZGl2RWxlbWVudC5vZmZzZXRXaWR0aCA+IDgwMCApIHsgdml6RWxlbWVudC5zdHlsZS5taW5XaWR0aD0nNDIwcHgnO3ZpekVsZW1lbnQuc3R5bGUubWF4V2lkdGg9JzE1NTBweCc7dml6RWxlbWVudC5zdHlsZS53aWR0aD0nMTAwJSc7dml6RWxlbWVudC5zdHlsZS5taW5IZWlnaHQ9JzQ4N3B4Jzt2aXpFbGVtZW50LnN0eWxlLm1heEhlaWdodD0nMTA4N3B4Jzt2aXpFbGVtZW50LnN0eWxlLmhlaWdodD0oZGl2RWxlbWVudC5vZmZzZXRXaWR0aCowLjc1KSsncHgnO30gZWxzZSBpZiAoIGRpdkVsZW1lbnQub2Zmc2V0V2lkdGggPiA1MDAgKSB7IHZpekVsZW1lbnQuc3R5bGUubWluV2lkdGg9JzQyMHB4Jzt2aXpFbGVtZW50LnN0eWxlLm1heFdpZHRoPScxNTUwcHgnO3ZpekVsZW1lbnQuc3R5bGUud2lkdGg9JzEwMCUnO3ZpekVsZW1lbnQuc3R5bGUubWluSGVpZ2h0PSc0ODdweCc7dml6RWxlbWVudC5zdHlsZS5tYXhIZWlnaHQ9JzEwODdweCc7dml6RWxlbWVudC5zdHlsZS5oZWlnaHQ9KGRpdkVsZW1lbnQub2Zmc2V0V2lkdGgqMC43NSkrJ3B4Jzt9IGVsc2UgeyB2aXpFbGVtZW50LnN0eWxlLndpZHRoPScxMDAlJzt2aXpFbGVtZW50LnN0eWxlLmhlaWdodD0nMTgyN3B4Jzt9ICAgICAgICAgICAgICAgICAgICAgDQp2YXIgc2NyaXB0RWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpOyAgICAgICAgICAgICAgICAgICAgDQpzY3JpcHRFbGVtZW50LnNyYyA9ICdodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS9qYXZhc2NyaXB0cy9hcGkvdml6X3YxLmpzJzsgICAgICAgICAgICAgICAgICAgIHZpekVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoc2NyaXB0RWxlbWVudCwgdml6RWxlbWVudCk7ICAgICAgICAgICAgICAgIA0KPC9zY3JpcHQ+DQoNCjwvdGQ+DQo8L3RyPg0KPC90YWJsZT4NCg0KXA0KDQpcDQoNCioqQ3JpdGlxdWVzIGFuZCBSZWNvbW1lbmRhdGlvbnMgZm9yIEltcHJvdmVtZW50KioNClwNCg0KKiBTZWxlY3Rpb24gb2YgaW5mb3JtYXRpb24gZm9yIHZpc3VhbGl6YXRpb24NCiogRGVzaWduIHBlcnNwZWN0aXZlcw0KICArIGluZGl2aWR1YWwgY2hhcnRzDQogICsgT3ZlcmFsbCBkZXNpZ24gb2YgZGFzaGJvYXJkIChsYXlvdXQpDQogICsgb3JjaGVzdHJhdGlvbiBvZiBpbmRpdmlkdWFsIGNoYXJ0cw0KICArIGRlc2lnbiBhZXN0aGV0aWNzDQoNCg0KDQoNCiMgVGFibGVhdSBTdG9yeSBQb2ludHMNCg0KVGFibGVhdSBjYW4gY3JlYXRlIGEgZm9ybSBvZiBwcmVzZW50YXRpb24gb2YgdGhlIGV4aXN0aW5nIGluZGl2aWR1YWwgY2hhcnQgc28gd2UgY2FuIHRlbGwgdGhlIHN0b3J5IGJhc2VkIG9uIHRoZSBpbmRpdmlkdWFsIFRhYmxlYXUgY2hhcnRzLiBJbiB0ZXJtcyBvZiBkZXNpZ24sIGl0IGlzIHJlbGF0aXZlbHkgbGVzcyBjaGFsbGVuZ2luZyBzaW5jZSB0aGUgYHN0b3J5IHBvaW50YCB1c2VzIGEgc2VxdWVuY2Ugb2YgbG9naWNhbGx5IGNvbm5lY3RlZCBpbmRpdmlkdWFsIFRhYmxlYXUgdmlzdWFsIHNoZWV0cyB0byB0ZWxsIGEgZGF0YSBzdG9yeS4gDQoNCg0KQWx0aG91Z2ggYSBsaXR0bGUgZGVzaWduIGVmZm9ydCBpcyBuZWVkZWQgZm9yIHRoZSBzdG9yeSBwb2ludCwgdGhlIHNhbWUgbGV2ZWwgb2Ygc2lnbmlmaWNhbnQgZGVzaWduIGVmZm9ydCBuZWVkcyB0byBiZSBwdXQgaW50byBpbmRpdmlkdWFsIHZpc3VhbCBzaGVldHMuDQoNClRoZSBmb2xsb3dpbmcgaXMgYW4gaW5jb21wbGV0ZSBzYW1wbGUgb2YgYSBzdG9yeSBwb2ludCBiYXNlZCBvbiB0aGUgcHJldmlvdXMgZGFzaGJvYXJkLiBFYWNoIGluZGl2aWR1YWwgdmlzdWFsIHNoZWV0IHNob3VsZCBoYXZlIGEgYnJpZWYgYW5kIGRlc2NyaXB0aXZlIGNhcHRpb24gYWJvdXQgdGhlIGluZm9ybWF0aW9uLg0KDQoNClwNCg0KPHRhYmxlIGJvcmRlciA9IDAgYm9yZGVyY29sb3I9ImRhcmtncmVlbiIgYmdjb2xvcj0nI2Y2ZjZmNicgIHdpZHRoPTExMCUgIGFsaWduID0gY2VudGVyPg0KPHRyPg0KPHRkPg0KDQo8ZGl2IGNsYXNzPSd0YWJsZWF1UGxhY2Vob2xkZXInIGlkPSd2aXoxNzExNzk4ODEwNTg5JyBzdHlsZT0ncG9zaXRpb246IHJlbGF0aXZlJz4NCjxub3NjcmlwdD4NCjxhIGhyZWY9JyMnPjxpbWcgYWx0PSdTdG9yeVBvaW50ICcgc3JjPSdodHRwczomIzQ3OyYjNDc7cHVibGljLnRhYmxlYXUuY29tJiM0NztzdGF0aWMmIzQ3O2ltYWdlcyYjNDc7U3UmIzQ3O1N1cGVyc3RvcmVEYXRhU3RvcnlQb2ludCYjNDc7U3RvcnlQb2ludCYjNDc7MV9yc3MucG5nJyBzdHlsZT0nYm9yZGVyOiBub25lJyAvPjwvYT4NCjwvbm9zY3JpcHQ+DQoNCjxvYmplY3QgY2xhc3M9J3RhYmxlYXVWaXonICBzdHlsZT0nZGlzcGxheTpub25lOyc+DQo8cGFyYW0gbmFtZT0naG9zdF91cmwnIHZhbHVlPSdodHRwcyUzQSUyRiUyRnB1YmxpYy50YWJsZWF1LmNvbSUyRicgLz4gDQo8cGFyYW0gbmFtZT0nZW1iZWRfY29kZV92ZXJzaW9uJyB2YWx1ZT0nMycgLz4gDQo8cGFyYW0gbmFtZT0nc2l0ZV9yb290JyB2YWx1ZT0nJyAvPg0KPHBhcmFtIG5hbWU9J25hbWUnIHZhbHVlPSdTdXBlcnN0b3JlRGF0YVN0b3J5UG9pbnQmIzQ3O1N0b3J5UG9pbnQnIC8+DQo8cGFyYW0gbmFtZT0ndGFicycgdmFsdWU9J25vJyAvPg0KPHBhcmFtIG5hbWU9J3Rvb2xiYXInIHZhbHVlPSd5ZXMnIC8+DQo8cGFyYW0gbmFtZT0nc3RhdGljX2ltYWdlJyB2YWx1ZT0naHR0cHM6JiM0NzsmIzQ3O3B1YmxpYy50YWJsZWF1LmNvbSYjNDc7c3RhdGljJiM0NztpbWFnZXMmIzQ3O1N1JiM0NztTdXBlcnN0b3JlRGF0YVN0b3J5UG9pbnQmIzQ3O1N0b3J5UG9pbnQmIzQ3OzEucG5nJyAvPiANCjxwYXJhbSBuYW1lPSdhbmltYXRlX3RyYW5zaXRpb24nIHZhbHVlPSd5ZXMnIC8+DQo8cGFyYW0gbmFtZT0nZGlzcGxheV9zdGF0aWNfaW1hZ2UnIHZhbHVlPSd5ZXMnIC8+DQo8cGFyYW0gbmFtZT0nZGlzcGxheV9zcGlubmVyJyB2YWx1ZT0neWVzJyAvPg0KPHBhcmFtIG5hbWU9J2Rpc3BsYXlfb3ZlcmxheScgdmFsdWU9J3llcycgLz4NCjxwYXJhbSBuYW1lPSdkaXNwbGF5X2NvdW50JyB2YWx1ZT0neWVzJyAvPg0KPHBhcmFtIG5hbWU9J2xhbmd1YWdlJyB2YWx1ZT0nZW4tVVMnIC8+DQo8cGFyYW0gbmFtZT0nZmlsdGVyJyB2YWx1ZT0ncHVibGlzaD15ZXMnIC8+DQo8L29iamVjdD48L2Rpdj4gICAgICAgICAgICAgICAgDQoNCjxzY3JpcHQgdHlwZT0ndGV4dC9qYXZhc2NyaXB0Jz4gICAgICAgICAgICAgICAgICAgDQp2YXIgZGl2RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aXoxNzExNzk4ODEwNTg5Jyk7ICAgICAgICAgICAgICAgICAgICANCnZhciB2aXpFbGVtZW50ID0gZGl2RWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnb2JqZWN0JylbMF07ICAgICAgICAgICAgICAgICAgICB2aXpFbGVtZW50LnN0eWxlLndpZHRoPSc5MTZweCc7dml6RWxlbWVudC5zdHlsZS5oZWlnaHQ9JzY5MXB4JzsgICAgICAgICAgICAgICAgICAgIA0KdmFyIHNjcmlwdEVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsgICAgICAgICAgICAgICAgICAgIA0Kc2NyaXB0RWxlbWVudC5zcmMgPSAnaHR0cHM6Ly9wdWJsaWMudGFibGVhdS5jb20vamF2YXNjcmlwdHMvYXBpL3Zpel92MS5qcyc7ICAgICAgICAgICAgICAgICAgICB2aXpFbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHNjcmlwdEVsZW1lbnQsIHZpekVsZW1lbnQpOyAgICAgICAgICAgICAgIA0KPC9zY3JpcHQ+DQo8L3RkPg0KPC90cj4NCjwvdGFibGU+DQoNCg0KDQojIEFzc2lnbm1lbnRzIG9mIFRoaXMgV2Vlaw0KDQpUaGlzIGFzc2lnbm1lbnQgZm9jdXNlcyBvbiBUYWJsZWF1IGRhc2hib2FyZHMgYW5kIHN0b3J5IHBvaW50cy4gWW91IGNhbiBjaG9vc2UgYSBkYXRhIHNldCB0aGF0IGhhcyBib3RoIG51bWVyaWNhbCBhbmQgY2F0ZWdvcmljYWwgdmFyaWFibGVzIHNvIHlvdSBjYW4gY3JlYXRlIHNldmVyYWwgY2hhcnRzIHN1Y2ggYXMgaGlzdG9ncmFtcywgc2NhdHRlciBwbG90cywgZnJlcXVlbmN5IHRhYmxlcywgcGllIGNoYXJ0cywgZXRjLiB1c2luZyBib3RoIHR5cGVzIG9mIHZhcmlhYmxlcy4gDQoNCg0KDQojIyBUaGUgTWluaW11bSBSZXF1aXJlbWVudHMNCg0KSSB3aWxsIG5vdCBnaXZlIHlvdSBhIGRhdGEgc2V0IGZvciB0aGlzIGFzc2lnbm1lbnQuIFlvdSBjYW4gZmluZCBhIGRhdGEgc2V0IGZyb20gYW55IHNvdXJjZXMgaW5jbHVkaW5nIG15IHByb2plY3QgZGF0YSBwYWdlICg8aHR0cHM6Ly9wZW5nZHNjaS5naXRodWIuaW8vZGF0YXNldHMvPikgdGhhdCBtZWV0cyB0aGUgZm9sbG93aW5nIHJlcXVpcmVtZW50Lg0KDQoNCjEuIENob29zZSBhIGRhdGEgc2V0IHdpdGggYXQgbGVhc3QgdHdvIG51bWVyaWNhbCB2YXJpYWJsZXMgc28geW91IGNhbiBjb25zdHJ1Y3QgYSBoaXN0b2dyYW0gYW5kIHNjYXR0ZXIgcGxvdHMuDQoNCjIuIFRoZSBkYXRhIHNldCBzaG91bGQgaGF2ZSBhdCBsZWFzdCB0aHJlZSBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgc28geW91IGNhbiBjcmVhdGUgcGllIGNoYXJ0cywgYmFyIHBsb3RzLCBldGMuDQoNCjMuIFlvdSBhcmUgZXhwZWN0ZWQgdG8gdXNlIGF0IGxlYXN0IG9uZSBmaWx0ZXIgdGhhdCB1cGRhdGVzIGFsbCBjaGFydHMgaW4gdGhlIGRhc2hib2FyZCAocmVhY3RpdmUgZGFzaGJvYXJkKS4NCg0KNC4gR2l2ZSBhIGRlc2NyaXB0aXZlIHRpdGxlIGFuZCBheGlzIGxhYmVscyB0byBpbmRpdmlkdWFsIGNoYXJ0cyBhbmQgZGFzaGJvYXJkcyByZXNwZWN0aXZlbHkuDQoNCjUuIEFkanVzdCB0aGUgbWFyZ2lucyBvZiB0aGUgaW5kaXZpZHVhbCBjaGFydCBhbmQgbWFrZSB0aGUgZGFzaGJvYXJkIHRpZHkgYW5kIGluZm9ybWF0aXZlLg0KDQo2LiBDcmVhdGUgYSBzdG9yeSBwb2ludCBhbmQgcHJvdmlkZSBpbmZvcm1hdGl2ZSBjYXB0aW9ucyBmb3Igc3Rvcnl0ZWxsaW5nLg0KDQo3LiAob3B0aW9uYWwpIElmIHlvdSBoYXZlIGdlby1pbmZvcm1hdGlvbiBpbiB5b3VyIGRhdGEgc2V0LCB5b3UgY2FuIGNyZWF0ZSBtYXBzIGluY2x1ZGluZyBhbmltYXRlZCBtYXBzLg0KDQo4LiAob3B0aW9uYWwpIElmIHlvdSB3YW50IHRvIHVzZSBtb3JlIGFkdmFuY2VkIHRvcGljcyBzdWNoIGFzIGRlcml2ZWQgdmFyaWFibGVzIGFuZCBwYXJhbWV0ZXJzIHRvIGVuaGFuY2UgeW91ciBkYXNoYm9hcmQsIHlvdSBhcmUgdmVyeSB3ZWxjb21lIHRvIGRvIHNvLg0KDQoNCiMjIFN1Ym1pc3Npb24gUmVxdWlyZW1lbnRzOg0KDQoxLiBQdWJsaXNoIHlvdXIgZGFzaGJvYXJkIGFuZCBzdG9yeSBwb2ludCBvbiB0aGUgVGFibGVhdSBQdWJsaWMgc2VydmVyLg0KDQoyLiBXcml0ZSBhIHJlcG9ydCB1c2luZyBhbiBSTUQgZG9jdW1lbnQgdG8gaW5jbHVkZSBib3RoIHRoZSBUYWJsZWF1IGRhc2hib2FyZCBhbmQgc3RvcnktcG9pbnQgb24gdGhlIHNhbWUgd2ViIHBhZ2UuDQoNCjMuIFlvdSBwdWJsaXNoIHRoZSByZXBvcnQgb24gZWl0aGVyIFJQdWJzIG9yIHBsYWNlZCBpdCBpbiB5b3VyIEdpdEh1YiByZXBvc2l0b3J5LiANCg0KNC4gdXBkYXRlIHlvdXIgb25saW5lIENWIHdpdGggdGhlIGxpbmsgdG8geW91ciBhc3NpZ25tZW50IChvcHRpb25hbCkuDQoNCjUuIFN1Ym1pdCB0aGUgVVJMIG9mIHlvdXIgSFRNTCByZXBvcnQgZ2VuZXJhdGVkIGZyb20gUk1EIGFuZCBtYWtlIHN1cmUgeW91ciBSTUQgc291cmNlIGlzIGRvd25sb2FkYWJsZSBmcm9tIHlvdXIgSFRNTCByZXBvcnQuDQoNCiMjIFN1Z2dlc3RlZCBZQU1MIEhlYWRlciBPdXRwdXQgU2V0LXVwDQoNCmBgYGB7dmVyYmF0aW19DQotLS0NCnRpdGxlOiAiWW91IFJlcG9ydCBUaXRsZSAoY29uY2lzZSBhbmQgZGVzY3JpcHRpdmUpIg0KYXV0aG9yOiAiWW91ciBOYW1lIg0KZGF0ZTogIldlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IG5vDQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0aGVtZTogcmVhZGFibGUNCi0tLQ0KICAgICAgDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgDQogIC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgDQogIC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyANCiAgICAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IA0KICAgIC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQpoMyB7IA0KICAgIC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIGZvbnQtZmFjZTogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KaDQgeyANCiAgICAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KICAgLyogY2VudGVyIG1hcHMgdXNpbmcgY2h1bmsgb3B0aW9uOiBmaWcuYWxpZ249J2NlbnRlcicgKi8NCi5odG1sLXdpZGdldCB7DQogICAgbWFyZ2luOiBhdXRvOw0KfQ0KPC9zdHlsZT4NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEpDQpgYGANCmBgYGANCg0KDQo=