A Look into Graffiti in New York City
Purpose:
This research hopes to uncover information about graffiti in New York City, specifically considering location, the cleaning of graffiti, and relation to median household income.
Introduction & Background:
Graffiti has become synonymous with New York City, and it is nearly impossible to visit any place on this map without encountering some form of it. It is a form of expression that grew out of tensions specific to New York in the 1960’s, and thus has become part of the city’s identity. The versions of graffiti that we see today grew as graffiti writers perfected their practice, sharing techniques along the way.
However, because of graffiti’s ties to an impoverished, grimy New York, and its often-illegal nature, it is an art form that is heavily policed. Many pieces that today’s work grew from can now only be seen through photographic documentation, if at all. Although many original works are gone, they were still integral in the formation of graffiti that exists today, and it is interesting to consider the tensions that both cultivated and hindered the art form over the years.
Today, Graffiti-Free NYC is a task force employed by the city government (a cooperative effort among the NYC Economic Development Corporation, the NYC Department of Sanitation, and the Office of the Mayor) that cleans reported instances of illegal graffiti across the city. From 2013, they have been updating a database that contains information about the location of a reported graffiti incident, the date it was reported, the status of it’s cleaning, and the date it was cleaned on. The Graffiti-Free task force is currently paused so the city can allocate more resources to fighting COVID19
This data (from January 2019 to January 2020) is available on NYC Open Data, and I wanted to see what it could tell us about graffiti today.
Considering the history of graffiti, I wanted to think about things like:
- What does a year’s worth of reported graffiti look like in New York City? Does it still dominate the city like it did in the 1960’s and 1970’s?
- Where is graffiti happening the most across the city?
- What do the demographics of neighborhoods where graffiti is heavily reported look like?
- Does the length of time it takes for Graffiti-Free NYC change from neighborhood to neighborhood?
I was also able to use American Community Survey (ACS) data to explore some of the demographics of New York City. The ACS is provided through 1 and 5 year surveys, and unlike census data, it is an estimate, not an actual count of each citizen, so it is important to take that into consideration throughout this report.
In addition to these two data sources, I used data from Bytes of the Big Apple in order to get information provided through census data at the Neighborhood Tabulation Area level, a geographical standard that is unique to New York City, and thus not included in the country-wide census.
Through the use of data visualizations and maps, I was able to answer some of these questions, and think about how this research could grow in the future.
Results:
Initial Visualizations:
This set of primary graphs and maps helped me gain more understanding about the data, and helped direct the rest of my research.
Fig. 1:
This bar chart shows the total count of real graffiti incidents reported in New York City from 2019-2020, categorized by borough. The raw data set contained information about reports where graffiti did not exist, so I did filter these out. It shows that Brooklyn had the most graffiti reported (9,131 incidents) and Staten Island had the least (263). However, it is important to consider that this count represents only the graffiti reported to the task force, and there are likely other incidents that have not been reported.

Fig. 2:
This bar chart breaks the data down further, separating incidents into “Closed” (meaning case closed, graffiti cleaned), and “Open” (meaning case still open, case unresolved). Here we see that the number of open and closed cases in each borough reflect the number of cases total, that there is not a borough that has a significant more open cases.
Fig. 3:
This bar chart showcases the average number of days it took Graffiti-Free NYC to clean an incident of graffiti from the day it was reported. By looking at each borough, we can see it took relatively the same amount of time in each borough, regardless of incident count per borough. Graffiti-Free NYC is a city run agency, so it makes sense that average cleaning time would be the same across boroughs.
Fig. 4:
This map provides a good overview of what each of these cleaned incidents looks like spatially across the city. In the bigger boroughs, the incidents are more heavily concentrated near the center of the city, and there are not nearly as many reports around the outer east and south edges of the city.

A Deeper Dive: Manhattan
This data set contained just shy of 20,000 reported incidents, and my computer was not happy with the amount of data. I decided to center my research on Manhattan, simply to cut down the number of data points. For future research, these same codes could be run for every borough.
Fig. 5:
This map shows all the reported instances of graffiti in Manhattan, color coded by if the incident was cleaned or not. It is interesting to note the amount of points congregated in certain areas like the Lower East Side, and less so in the Upper West Side area.

Fig. 6:
This map shows the median household income by census tract in Manhattan. The points represent cleaned graffiti incidents. The reported graffiti incidents are certainly congregated in the Lower East Side and neighborhoods above Central Park, which are also both areas that are primarily represented by a lower median household income. Beyond this visualization, it was difficult to complete meaningful statistical analysis at the census tract level so for my next visualizations, I have scaled up to Neighborhood Tabulation Area (NTA) for future visualizations.

Fig. 7:
This map showcases median household income (MHI) by Neighborhood Tabulation Area (NTA). It also has the amount of cleaned graffiti incidents (black), and incidents not yet cleaned by the Graffiti-Free NYC Task Force (grey). Chinatown is the neighborhood with the most reported incidents of graffiti (699 incidents) and an average MHI ($44,541.81) well below the average for neighborhood tabulation area in Manhattan. The least reported incidents (1 incident) occurred in Stuyvesant Town-Cooper Village, however this is entire NTA is a private residential development, and has its own safety force, so it is likely that instances of graffiti would be directly reported to their security force and not Graffiti-Free NYC. Considering this NTA as an outlier, the NTA with the least reported instances of graffiti would be Lincoln Square (14 incidents) with an average median household income of 12,8327.71 dollars, an average MHI that is 36,183.98 higher than the average MHI per NTA in Manhattan.

Fig. 8:
This data table showcases some important statistics for graffiti in Manhattan related to median household income.
Counting Stuyvesant Town-Cooper Village as an outlier, here is some of the information summed up, all in the scope of Neighborhood Tabulation Area (NTA):
- Average median household income: $99,467.44
- Total number of incidents in Manhattan: 4,192
- Average number of incidents in each NTA: 155
- Average number of days to clean an incident in each NTA: 128.75
- Total number of incidents cleaned in Manhattan: 2,122
- Average number of incidents cleaned per NTA: 79
- Total number of incidents not yet cleaned in Manhattan: 2,068
- Average number of cases not yet cleaned per NTA: 77
- Average percent of incidents cleaned across Manhattan: 50.62%
- Average percent of cases cleaned per NTA: 51.17%
Fig. 9:
The interactive map below visualizes some of this information:
Fig. 10:
This bar chart displays each neighborhood tabulation area’s amount of graffiti incidents reported (in order from least incidents to most). The columns are also colored to show if the NTAs average median household income is above or below the total average for Manhattan. 
Fig. 11:
This bar chart displays each NTA’s median household income, colored by if they had over or under 155 incidents of graffiti (the average for an NTA in Manhattan). The red dotted line represents the average MHI across Manhattan.

Discussion:
Based on the geographical and statistical analysis complete above, some conclusions about graffiti in New York can be made. As seen in fig. 1, graffiti in New York City is found in all 5 boroughs, but not spread evenly within them.
- 9,131 incidents in Brooklyn
- 4,530 incidents in Manhattan
- 3,467 incidents in the Bronx
- 2,512 incidents in Queens
- 263 incidents in Staten Island
Staten Island had the lowest count of incidents, 8,868 less than Brooklyn in fact. It is important to note that Staten Island also has a much smaller population that Brooklyn. While there are some differences in the count of incidents in each borough, fig. 2 & 3 shows that the length of time that it takes to clean any one graffiti incident is fairly similar form borough to borough. Staten Island is the only borough with more cases cleaned than not, 65% of the incidents have been cleaned. 45% of incidents in the Bronx have been cleaned, 44% in Queens, 48% in Brooklyn, and 47% in Manhattan, all of which are similar. Because Staten Island has less cases to clean overall, it would make more incidents could be cleaned. On average, it also took the least amount of days to clean a reported incident in Staten Island (117), and the most in Queens (138). A 21 day difference of average cleaning in these boroughs does not represent the 2,249 incident difference between Queens and Staten Island, likely because of Graffiti Free NYC being a city-wide task force.
Fig 4. shows the geographical distribution of reported graffiti incidents, and it becomes clear that there are “hot spots” for incidents throughout the city. Particularly, the Lower East side of Manhattan and around Williamsburg and Bushwick in Brooklyn. I also fount it interesting that points seem to form straight lines, likely along busy roads. In Brooklyn, dots appear to form Flatbush Avenue and Linden Blvd., two busy streets.
After initial analysis, I decided to focus on Manhattan. I made this choice to simplify data, and because Manhattan, Washington Heights in particular, was the birth place of graffiti as we know it today. Fig. 5 showcases a simple exploration of all incidents of reported graffiti in Manhattan, and if they have been cleaned or not. Again, the cluster on the Lower East side is prominent, along with some other small clusters. I found this interesting because graffiti in Manhattan began with artists not only in Washington Heights, but also the Lower East Side.
There was a real sentiment that graffiti was started as a form of expression for marginalized communities, looking to have a voice. “In the end, tagging my name not only underscored that “I did exist” in a town that didn’t value or even consider my existence, but that I existed outside of my very own masterpieces." – LEE, prominent graffiti writer in the 1970’s. So I wanted to explore if this was similar to today. I chose to use median household income (MHI) as a factor to compare graffiti incidents to. Fig. 7 shows each Neighborhood Tabulation Area (NTA) in Manhattan, colored by average MHI. When overlaid with reported graffiti incidents, it appears as if the darker areas (lower MHI) have more reported incidents. Lets unpack this.
Fig. 10 shows us that Chinatown and East Village have the two highest counts of graffiti incidents, and also an average median household income below that of all of Manhattan. The 4 neighborhoods with the least reported incidents all have an average median household income above that for the average of all of Manhattan. Because graffiti is not bound by zoning laws or rent prices in the way that MHI might be, it is interesting to think about these statistics geographically as well. For instance, SoHo-TriBeCa-Civic Center-Little Italy NTA has an average MHI above the whole city’s, but still has a lot of reported graffiti incidents. This NTA is very close geographically to East Village and Chinatown, and there is likely some spill over from these neighborhoods to the SoHo-TriBeCa-Civic Center-Little Italy NTA. In fact, looking at Fig. 7, it shows that the reported incidents of Graffiti are located on the west side of this NTA, which borders East Village and Chinatown.
Next Steps:
There is still a lot that can be uncovered about graffiti in New York City using data alone. After this initial research, I am thinking about major 3 ways this project could be expanded in the future.
- In depth analysis for each borough
- Explore NTA demographics further
- Census data looking at race, age, or property types
- is there a better grouping than NTA?
- What infrastructure influences graffiti? (trains, warehouses)
- Understand the relationship between present and past graffiti
- Do graffiti “hot spots” today reflect popular spots from the past?
- What other data sets can help tell this story (311 Calls)
Apendix:
My data came from 3 main sources:
- NYC Open Data
- This data set provided the information about graffiti in NYC, it contained key information about each reported incident such as: Borough an event occurred in, date it was reported, and if it was cleaned, a date for that, the NTA each event occurred in, and the point on a map where it occurred.
- I manipulated this data set to figure out if an incident was cleaned, percent of cleaned incidents (by borough and NTA), length of time it took to clean an incident once it was reported, count of incidents per borough, census tract and NTA, and other information about graffiti in New York City.
- Graffiti-Free NYC was started in 1999, and this data set was created in 2013, but there are only points available from January 10, 2019 to January 9 2020. It would be interesting to see more than one year (there were a ton of reported incidents for this year!). This data set is managed by the Department of Sanitiation.
- This data set is based on reported incidents, mostly through 311 calls. Not only does this need to be taken into consideration for this report, but, it would also be interesting to uncover more about the reprint of incidents. Who is doing the reporting, do they live in the same neighborhood as the incident they are reporting, is it strictly 311 calls?
- Bytes of the Big Apple
- Bytes of the Big Apple is managed by NYC planning to create free and accessible data about NYC.
- I used this data to manipulate other data at the Neighborhood Tabulation Area (NTA) level in New York City. NTA is geographical category specific to NYC so it is not included in raw census data. They are areas divided by City Hall depending on decennial census tract information.
- NYC Planning and Bytes of the Big Apple created a data set for information from the census that is divided at the NTA level.
- I also used this data to create outlines of geographies that were mapped, as the data set included geometries.
- American Community Survey (ACS)
- I used the 5 year American Community Survey to explore demographics of New York, and to map at the census tract level.
- Because 2020 census data has not been fully released yet, and we are now at the end of the 10 year gap between censuses, I decided to use more recent info that the ACS provides. The ACS also answers more detailed questions then the 10 year census does.
- It is important to note that the ACS is an estimation, not every citizen is contacted for every survey, and is therefore not as accurate at the 10-yr census.
LS0tCnRpdGxlOiAiTWF1ZGUgTGFWYXV0ZSIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiNpbXBvcnRpbmcgbmVjZXNzYXJ5IGxpYnJhcmllcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeSh0aWR5Y2Vuc3VzKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeSh2aXJpZGlzKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShwbG90bHkpCmxpYnJhcnkodGlncmlzKQpsaWJyYXJ5KGdncGxvdDIpCmBgYAojIEEgTG9vayBpbnRvIEdyYWZmaXRpIGluIE5ldyBZb3JrIENpdHkKIyMjIFB1cnBvc2U6IAojIyMjIFRoaXMgcmVzZWFyY2ggaG9wZXMgdG8gdW5jb3ZlciBpbmZvcm1hdGlvbiBhYm91dCBncmFmZml0aSBpbiBOZXcgWW9yayBDaXR5LCAgc3BlY2lmaWNhbGx5IGNvbnNpZGVyaW5nIGxvY2F0aW9uLCB0aGUgY2xlYW5pbmcgb2YgZ3JhZmZpdGksIGFuZCByZWxhdGlvbiB0byBtZWRpYW4gaG91c2Vob2xkIGluY29tZS4gCgojIyMgSW50cm9kdWN0aW9uICYgQmFja2dyb3VuZDoKR3JhZmZpdGkgaGFzIGJlY29tZSBzeW5vbnltb3VzIHdpdGggTmV3IFlvcmsgQ2l0eSwgYW5kIGl0IGlzIG5lYXJseSBpbXBvc3NpYmxlIHRvIHZpc2l0IGFueSBwbGFjZSBvbiB0aGlzIG1hcCB3aXRob3V0IGVuY291bnRlcmluZyBzb21lIGZvcm0gb2YgaXQuIEl0IGlzIGEgZm9ybSBvZiBleHByZXNzaW9uIHRoYXQgZ3JldyBvdXQgb2YgdGVuc2lvbnMgc3BlY2lmaWMgdG8gTmV3IFlvcmsgaW4gdGhlIDE5NjDigJlzLCBhbmQgdGh1cyBoYXMgYmVjb21lIHBhcnQgb2YgdGhlIGNpdHnigJlzIGlkZW50aXR5LiBUaGUgdmVyc2lvbnMgb2YgZ3JhZmZpdGkgdGhhdCB3ZSBzZWUgdG9kYXkgZ3JldyBhcyBncmFmZml0aSB3cml0ZXJzIHBlcmZlY3RlZCB0aGVpciBwcmFjdGljZSwgc2hhcmluZyB0ZWNobmlxdWVzIGFsb25nIHRoZSB3YXkuCgpIb3dldmVyLCBiZWNhdXNlIG9mIGdyYWZmaXRp4oCZcyB0aWVzIHRvIGFuIGltcG92ZXJpc2hlZCwgZ3JpbXkgTmV3IFlvcmssIGFuZCBpdHMgb2Z0ZW4taWxsZWdhbCBuYXR1cmUsIGl0IGlzIGFuIGFydCBmb3JtIHRoYXQgaXMgaGVhdmlseSBwb2xpY2VkLiBNYW55IHBpZWNlcyB0aGF0IHRvZGF5J3Mgd29yayBncmV3IGZyb20gY2FuIG5vdyBvbmx5IGJlIHNlZW4gdGhyb3VnaCBwaG90b2dyYXBoaWMgZG9jdW1lbnRhdGlvbiwgaWYgYXQgYWxsLiBBbHRob3VnaCBtYW55IG9yaWdpbmFsIHdvcmtzIGFyZSBnb25lLCB0aGV5IHdlcmUgc3RpbGwgaW50ZWdyYWwgaW4gdGhlIGZvcm1hdGlvbiBvZiBncmFmZml0aSB0aGF0IGV4aXN0cyB0b2RheSwgYW5kIGl0IGlzIGludGVyZXN0aW5nIHRvIGNvbnNpZGVyIHRoZSB0ZW5zaW9ucyB0aGF0IGJvdGggY3VsdGl2YXRlZCBhbmQgaGluZGVyZWQgdGhlIGFydCBmb3JtIG92ZXIgdGhlIHllYXJzLgoKVG9kYXksIFtHcmFmZml0aS1GcmVlIE5ZQ10oaHR0cHM6Ly9lZGMubnljL3Byb2dyYW0vZ3JhZmZpdGktZnJlZS1ueWMpIGlzIGEgdGFzayBmb3JjZSBlbXBsb3llZCBieSB0aGUgY2l0eSBnb3Zlcm5tZW50IChhIGNvb3BlcmF0aXZlIGVmZm9ydCBhbW9uZyB0aGUgTllDIEVjb25vbWljIERldmVsb3BtZW50IENvcnBvcmF0aW9uLCB0aGUgTllDIERlcGFydG1lbnQgb2YgU2FuaXRhdGlvbiwgYW5kIHRoZSBPZmZpY2Ugb2YgdGhlIE1heW9yKSB0aGF0IGNsZWFucyByZXBvcnRlZCBpbnN0YW5jZXMgb2YgaWxsZWdhbCBncmFmZml0aSBhY3Jvc3MgdGhlIGNpdHkuIEZyb20gMjAxMywgdGhleSBoYXZlIGJlZW4gdXBkYXRpbmcgYSBkYXRhYmFzZSB0aGF0IGNvbnRhaW5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2NhdGlvbiBvZiBhIHJlcG9ydGVkIGdyYWZmaXRpIGluY2lkZW50LCB0aGUgZGF0ZSBpdCB3YXMgcmVwb3J0ZWQsIHRoZSBzdGF0dXMgb2YgaXQncyBjbGVhbmluZywgYW5kIHRoZSBkYXRlIGl0IHdhcyBjbGVhbmVkIG9uLiAqVGhlIEdyYWZmaXRpLUZyZWUgdGFzayBmb3JjZSBpcyBjdXJyZW50bHkgcGF1c2VkIHNvIHRoZSBjaXR5IGNhbiBhbGxvY2F0ZSBtb3JlIHJlc291cmNlcyB0byBmaWdodGluZyBDT1ZJRDE5KgoKVGhpcyBkYXRhIChmcm9tIEphbnVhcnkgMjAxOSB0byBKYW51YXJ5IDIwMjApIGlzIGF2YWlsYWJsZSBvbiBbTllDIE9wZW4gRGF0YV0oaHR0cHM6Ly9kYXRhLmNpdHlvZm5ld3lvcmsudXMvQ2l0eS1Hb3Zlcm5tZW50L0RTTlktR3JhZmZpdGktVHJhY2tpbmcvZ3B3ZC1ucGFyKSwgYW5kIEkgd2FudGVkIHRvIHNlZSB3aGF0IGl0IGNvdWxkIHRlbGwgdXMgYWJvdXQgZ3JhZmZpdGkgdG9kYXkuIAoKQ29uc2lkZXJpbmcgdGhlIGhpc3Rvcnkgb2YgZ3JhZmZpdGksIEkgd2FudGVkIHRvIHRoaW5rIGFib3V0IHRoaW5ncyBsaWtlOgoKICAqICAgV2hhdCBkb2VzIGEgeWVhcidzIHdvcnRoIG9mIHJlcG9ydGVkIGdyYWZmaXRpIGxvb2sgbGlrZSBpbiBOZXcgWW9yayBDaXR5PyBEb2VzIGl0IHN0aWxsIGRvbWluYXRlIHRoZSBjaXR5ICAgICBsaWtlIGl0IGRpZCBpbiB0aGUgMTk2MCdzIGFuZCAxOTcwJ3M/IAogICogICBXaGVyZSBpcyBncmFmZml0aSBoYXBwZW5pbmcgdGhlIG1vc3QgYWNyb3NzIHRoZSBjaXR5PwogICogICBXaGF0IGRvIHRoZSBkZW1vZ3JhcGhpY3Mgb2YgbmVpZ2hib3Job29kcyB3aGVyZSBncmFmZml0aSBpcyBoZWF2aWx5IHJlcG9ydGVkIGxvb2sgbGlrZT8KICAqICAgRG9lcyB0aGUgbGVuZ3RoIG9mIHRpbWUgaXQgdGFrZXMgZm9yIEdyYWZmaXRpLUZyZWUgTllDIGNoYW5nZSBmcm9tIG5laWdoYm9yaG9vZCB0byBuZWlnaGJvcmhvb2Q/CgpJIHdhcyBhbHNvIGFibGUgdG8gdXNlIEFtZXJpY2FuIENvbW11bml0eSBTdXJ2ZXkgKEFDUykgZGF0YSB0byBleHBsb3JlIHNvbWUgb2YgdGhlIGRlbW9ncmFwaGljcyBvZiBOZXcgWW9yayBDaXR5LiBUaGUgQUNTIGlzIHByb3ZpZGVkIHRocm91Z2ggMSBhbmQgNSB5ZWFyIHN1cnZleXMsIGFuZCB1bmxpa2UgY2Vuc3VzIGRhdGEsIGl0IGlzIGFuIGVzdGltYXRlLCBub3QgYW4gYWN0dWFsIGNvdW50IG9mIGVhY2ggY2l0aXplbiwgc28gaXQgaXMgaW1wb3J0YW50IHRvIHRha2UgdGhhdCBpbnRvIGNvbnNpZGVyYXRpb24gdGhyb3VnaG91dCB0aGlzIHJlcG9ydC4gCgpJbiBhZGRpdGlvbiB0byB0aGVzZSB0d28gZGF0YSBzb3VyY2VzLCBJIHVzZWQgZGF0YSBmcm9tIFtCeXRlcyBvZiB0aGUgQmlnIEFwcGxlXShodHRwczovL3d3dzEubnljLmdvdi9zaXRlL3BsYW5uaW5nL2RhdGEtbWFwcy9vcGVuLWRhdGEvZHduLWFjcy1udGEucGFnZSkgaW4gb3JkZXIgdG8gZ2V0IGluZm9ybWF0aW9uIHByb3ZpZGVkIHRocm91Z2ggY2Vuc3VzIGRhdGEgYXQgdGhlIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEgbGV2ZWwsIGEgZ2VvZ3JhcGhpY2FsIHN0YW5kYXJkIHRoYXQgaXMgdW5pcXVlIHRvIE5ldyBZb3JrIENpdHksIGFuZCB0aHVzIG5vdCBpbmNsdWRlZCBpbiB0aGUgY291bnRyeS13aWRlIGNlbnN1cy4gCgpUaHJvdWdoIHRoZSB1c2Ugb2YgZGF0YSB2aXN1YWxpemF0aW9ucyBhbmQgbWFwcywgSSB3YXMgYWJsZSB0byBhbnN3ZXIgc29tZSBvZiB0aGVzZSBxdWVzdGlvbnMsIGFuZCB0aGluayBhYm91dCBob3cgdGhpcyByZXNlYXJjaCBjb3VsZCBncm93IGluIHRoZSBmdXR1cmUuIApgYGB7ciBzZXR1cDQsIGluY2x1ZGU9RkFMU0V9CiNpbXBvcnRpbmcgbmVjZXNzYXJ5IGRhdGEgZnJhbWVzCmdyYWZmaXRpX3Jhd19zaHAgPC0gc3RfcmVhZCgiZGF0YS9ncmFmZml0aV9yYXcuc2hwIikgI05ZQyBPcGVuIERhdGEKI2NyZWF0aW5nIGEgZGF0YWZpbGUgd2l0aG91dCBnZW9tZXRyeQpncmFmZml0aV9yYXcgPC0gc3RfZHJvcF9nZW9tZXRyeShncmFmZml0aV9yYXdfc2hwKQojZG93bmxvYWRpbmcgZnJvbSBieXRlcyBvZiB0aGUgYmlnIGFwcGxlCmNlbnN1c19kYXRhIDwtIHN0X3JlYWQoImRhdGEvbnljdDIwMTBfMjFkL255Y3QyMDEwLnNocCIpICNCeXRlcyBvZiB0aGUgQmlnIGFwcGxlCiN3b3JraW5nIHdpdGggYWNzIGRhdGEKI2NlbnN1c19hcGlfa2V5KCIzYzg5MjIwZmI0YzhjN2FmNjliNTE0MWY5ZDIzYjRiZWUxOTJiZGZjIiwgaW5zdGFsbCA9IFRSVUUsIG92ZXJ3cml0ZSA9VCkKYWNzMTkgPC0gbG9hZF92YXJpYWJsZXMoMjAxOSwgImFjczUiKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI2NyZWF0aW5nIGRhdGEgdGFibGUgd2hlcmUgaW5jaWRlbnRzIGFjdHVhbGx5IGV4aXN0ZWQKcmVhbF9ncmFmZml0aSA8LSBncmFmZml0aV9yYXcgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gTm8gZ3JhZmZpdGkgb24gcHJvcGVydHkuJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ01haWwgcmV0dXJuZWQgLyB3cm9uZyBhZGRyZXNzJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gIENhbm5vdCBsb2NhdGUgcHJvcGVydHkuJykgJT4lCiAgZmlsdGVyKEJPUk9VR0ggIT0gJ1Vuc3BlY2lmaWVkJykKCnJlYWxfZ3JhZmZpdGlfc2hwIDwtIGdyYWZmaXRpX3Jhd19zaHAgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gTm8gZ3JhZmZpdGkgb24gcHJvcGVydHkuJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ01haWwgcmV0dXJuZWQgLyB3cm9uZyBhZGRyZXNzJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gIENhbm5vdCBsb2NhdGUgcHJvcGVydHkuJykKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9CiNtYWtpbmcgZGF0YSB0YWJsZXMgdG8gbWFwOgojbWFraW5nIGRhdGEgZnJhbWVzIGZvciBlYWNoIGJvcm91Z2gKI2Nob29zaW5nIGVhY2ggcm93IGluIHRoZSBCT1JPVUdIIGNvbCBiYXNlZCBvbiBlYWNoIGJvcm91Z2gKbWFuaGF0dGFuX2dyYWZmaXR0aSA8LSBzdWJzZXQocmVhbF9ncmFmZml0aSwgQk9ST1VHSCA9PSAiTUFOSEFUVEFOIikgIzQ1MzAKYnJvb2tseW5fZ3JhZmZpdHRpIDwtIHN1YnNldChyZWFsX2dyYWZmaXRpLCBCT1JPVUdIID09ICJCUk9PS0xZTiIpICM5MTMxCnF1ZWVuc19ncmFmZml0dGkgPC0gc3Vic2V0KHJlYWxfZ3JhZmZpdGksIEJPUk9VR0ggPT0gIlFVRUVOUyIpICMyNTEyCmJyb254X2dyYWZmaXR0aSA8LSBzdWJzZXQocmVhbF9ncmFmZml0aSwgQk9ST1VHSCA9PSAiQlJPTlgiKSAjMzQ2NwpzdGF0ZW5faXNsYW5kX2dyYWZmaXR0aSA8LSBzdWJzZXQocmVhbF9ncmFmZml0aSwgQk9ST1VHSCA9PSAiU1RBVEVOIElTTEFORCIpICMyNjMKCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQojZGF0YSBmcmFtZSB3aXRoIHRoZSBjb3VudCBvZiBlYWNoIGNsZWFuZWQvdW5jbGVhbmVkIGluY2lkZW50IGluIGVhY2ggYm9yb3VnaCAKI21hbmhhdHRhbiBleGFtcGxlOiBwdWxsaW5nIGZyb20gbWFuaGF0dGFuIG9ubHkgdGFibGUKeF9tYW5oYXR0YW5fZ3JhZmZpdHRpX3N0YXR1cyA8LSBtYW5oYXR0YW5fZ3JhZmZpdHRpICU+JQogICNkZWZpbmluZyB0aGUgZ3JvdXAgYXMgU1RBVFVTIHRvIHdvcmsgZnJvbSBvbmx5IHRoYXQgY29sCiAgZ3JvdXBfYnkoU1RBVFVTKSAlPiUKICAjc3VtbWFyaWVzIGNyZWF0ZXMgYSBuZXcgZGF0YSBmcmFtZSwgY291bnRpbmcgdGhlIGRpZmZyZW50IHJvd3MgaW4gU1RBVFVTCiAgc3VtbWFyaXNlKG1hbmhhdHRhbl9jb3VudD1uKCkpCnhfYnJvb2tseW5fZ3JhZmZpdHRpX3N0YXR1cyA8LSBicm9va2x5bl9ncmFmZml0dGkgJT4lCiAgZ3JvdXBfYnkoU1RBVFVTKSAlPiUKICBzdW1tYXJpc2UoYnJvb2tseW5fY291bnQ9bigpKSAlPiUKICByaWdodF9qb2luKHhfbWFuaGF0dGFuX2dyYWZmaXR0aV9zdGF0dXMsIGJ5ID0gIlNUQVRVUyIpCiNtYWRlIG9uZSBvZiB0aGVzZSBsaXR0bGUgdGFibGVzIGZvciBlYWNoIGJvcnJvdWdoIGFuZCBqb2luZWQgdGhlbSBhbGwKeF9xdWVlbnNfZ3JhZmZpdHRpX3N0YXR1cyA8LSBxdWVlbnNfZ3JhZmZpdHRpICU+JQogIGdyb3VwX2J5KFNUQVRVUykgJT4lCiAgc3VtbWFyaXNlKHF1ZWVuc19jb3VudD1uKCkpICU+JQogIHJpZ2h0X2pvaW4oeF9icm9va2x5bl9ncmFmZml0dGlfc3RhdHVzLCBieSA9ICJTVEFUVVMiKQp4X2Jyb254X2dyYWZmaXR0aV9zdGF0dXMgPC0gYnJvbnhfZ3JhZmZpdHRpICU+JQogIGdyb3VwX2J5KFNUQVRVUykgJT4lCiAgc3VtbWFyaXNlKGJyb254X2NvdW50PW4oKSkgJT4lCiAgcmlnaHRfam9pbih4X3F1ZWVuc19ncmFmZml0dGlfc3RhdHVzLCBieSA9ICJTVEFUVVMiKQp4X3N0YXRlbl9pc2xhbmRfZ3JhZmZpdHRpX3N0YXR1cyA8LSBzdGF0ZW5faXNsYW5kX2dyYWZmaXR0aSAlPiUKICBncm91cF9ieShTVEFUVVMpICU+JQogIHN1bW1hcmlzZShzdGF0ZW5faXNsYW5kX2NvdW50PW4oKSkgJT4lCiAgcmlnaHRfam9pbih4X2Jyb254X2dyYWZmaXR0aV9zdGF0dXMsIGJ5ID0gIlNUQVRVUyIpCiNhbGwgYm9yb3Mgam9pbmVkIHdpdGggdG90YWwgbnVtYmVyIGZyb20gb3JpZ2luYWwgZGF0YSBmcmFtZQpncmFmZml0aV9jb3VudF9ib3JvIDwtIHJlYWxfZ3JhZmZpdGkgJT4lCiAgZ3JvdXBfYnkoU1RBVFVTKSAlPiUKICBzdW1tYXJpc2UodG90YWxfY291bnQ9bigpKSAlPiUKICByaWdodF9qb2luKHhfc3RhdGVuX2lzbGFuZF9ncmFmZml0dGlfc3RhdHVzLCBieSA9ICJTVEFUVVMiKQoKCgpgYGAKCiMjIyBSZXN1bHRzOgogCiMjIyMgSW5pdGlhbCBWaXN1YWxpemF0aW9uczogIApUaGlzIHNldCBvZiBwcmltYXJ5IGdyYXBocyBhbmQgbWFwcyBoZWxwZWQgbWUgZ2FpbiBtb3JlIHVuZGVyc3RhbmRpbmcgYWJvdXQgdGhlIGRhdGEsIGFuZCBoZWxwZWQgZGlyZWN0IHRoZSByZXN0IG9mIG15IHJlc2VhcmNoLgoKIyMjIyMgRmlnLiAxOgpUaGlzIGJhciBjaGFydCBzaG93cyB0aGUgdG90YWwgY291bnQgb2YgcmVhbCBncmFmZml0aSBpbmNpZGVudHMgcmVwb3J0ZWQgaW4gTmV3IFlvcmsgQ2l0eSBmcm9tIDIwMTktMjAyMCwgY2F0ZWdvcml6ZWQgYnkgYm9yb3VnaC4gVGhlIHJhdyBkYXRhIHNldCBjb250YWluZWQgaW5mb3JtYXRpb24gYWJvdXQgcmVwb3J0cyB3aGVyZSBncmFmZml0aSBkaWQgbm90IGV4aXN0LCBzbyBJIGRpZCBmaWx0ZXIgdGhlc2Ugb3V0LiBJdCBzaG93cyB0aGF0IEJyb29rbHluIGhhZCB0aGUgbW9zdCBncmFmZml0aSByZXBvcnRlZCAoOSwxMzEgaW5jaWRlbnRzKSBhbmQgU3RhdGVuIElzbGFuZCBoYWQgdGhlIGxlYXN0ICgyNjMpLiBIb3dldmVyLCBpdCBpcyBpbXBvcnRhbnQgdG8gY29uc2lkZXIgdGhhdCB0aGlzIGNvdW50IHJlcHJlc2VudHMgb25seSB0aGUgZ3JhZmZpdGkgKnJlcG9ydGVkKiB0byB0aGUgdGFzayBmb3JjZSwgYW5kIHRoZXJlIGFyZSBsaWtlbHkgb3RoZXIgaW5jaWRlbnRzIHRoYXQgaGF2ZSBub3QgYmVlbiByZXBvcnRlZC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI0FERCBSRUQgREFIRUQgTElORSBGT1IgQVZFUkFHRSBBQ0NST1NTIEFMTCBCT1JPVUdIUwpnZ3Bsb3QoZGF0YSA9IHJlYWxfZ3JhZmZpdGkpICsKICBnZW9tX2JhcihtYXBwaW5nID0gYWVzKHggPSBCT1JPVUdILCBmaWxsID0gImNvdW50IikpICsKICB0aGVtZV9idygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQk9ST1VHSCIsCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygiIzJhYmNjOSIsICIjYzQ2ZWMzIiwgIiNmMjdkMDciLCAiIzZkZTM3MyIsICIjZjVlMzQwIiksCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygiQlJPTlgiLCAiQlJPT0tMWU4iLCAiTUFOSEFUVEFOIiwgIlFVRUVOUyIsICJTVEFURU4gSVNMQU5EIikpICsKICBsYWJzKHggPSAiQm9yb3VnaCIsIHkgPSAiQ291bnQgb2YgSW5jaWRlbnRzIiwKICAgICAgIHRpdGxlID0gIlJlcG9ydGVkIEdyYWZmaXRpIEluY2lkZW50cyBpbiBOZXcgWW9yayBDaXR5IDIwMTktMjAyMCIsCiAgICAgICAjc3VidGl0bGUgPSAiQXZlcmFnZSBvZiBudW1iZXIgb2YgZGF5cyBmb3IgZWFjaCBpbmNpZGVudCBncm91cGVkIGJ5IGJvcm91Z2giLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IE5ZQyBPcGVuIERhdGEiKSAKYGBgCgojIyMjIyBGaWcuIDI6ClRoaXMgYmFyIGNoYXJ0IGJyZWFrcyB0aGUgZGF0YSBkb3duIGZ1cnRoZXIsIHNlcGFyYXRpbmcgaW5jaWRlbnRzIGludG8gIkNsb3NlZCIgKG1lYW5pbmcgY2FzZSBjbG9zZWQsIGdyYWZmaXRpIGNsZWFuZWQpLCBhbmQgIk9wZW4iIChtZWFuaW5nIGNhc2Ugc3RpbGwgb3BlbiwgY2FzZSB1bnJlc29sdmVkKS4gSGVyZSB3ZSBzZWUgdGhhdCB0aGUgbnVtYmVyIG9mIG9wZW4gYW5kIGNsb3NlZCBjYXNlcyBpbiBlYWNoIGJvcm91Z2ggcmVmbGVjdCB0aGUgbnVtYmVyIG9mIGNhc2VzIHRvdGFsLCB0aGF0IHRoZXJlIGlzIG5vdCBhIGJvcm91Z2ggdGhhdCBoYXMgYSBzaWduaWZpY2FudCBtb3JlIG9wZW4gY2FzZXMuCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9CiNSVU4gU1VNIFNUQVRTIFRPIFNFRSBESUZSRU5DRSBJTiBDTEVBTkVEIFZTIE9QRU4/PwphbGxfYm9yb19wbG90MSA8LSBnZ3Bsb3QoZGF0YSA9IGdyYWZmaXRpX2NvdW50X2Jvcm8pICsgCiAgZ2VvbV9jb2wobWFwcGluZyA9IGFlcyh4ID0gU1RBVFVTLCB5ID0gYnJvb2tseW5fY291bnQsIGZpbGwgPSAiQnJvb2tseW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJCcm9va2x5bjogIiwgYnJvb2tseW5fY291bnQpKSkgKwogIGdlb21fY29sKG1hcHBpbmcgPSBhZXMoeCA9IFNUQVRVUywgeSA9IG1hbmhhdHRhbl9jb3VudCwgZmlsbCA9ICJNYW5oYXR0YW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJNYW5oYXR0YW46ICIsIG1hbmhhdHRhbl9jb3VudCkpKSArCiAgZ2VvbV9jb2wobWFwcGluZyA9IGFlcyh4ID0gU1RBVFVTLCB5ID0gYnJvbnhfY291bnQsIGZpbGwgPSAiQnJvbngiLAogICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJCcm9ueDogIiwgYnJvbnhfY291bnQpKSkgKwogIGdlb21fY29sKG1hcHBpbmcgPSBhZXMoeCA9IFNUQVRVUywgeSA9IHF1ZWVuc19jb3VudCwgZmlsbCA9ICJRdWVlbnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJRdWVlbnM6ICIsIHF1ZWVuc19jb3VudCkpKSArCiAgZ2VvbV9jb2wobWFwcGluZyA9IGFlcyh4ID0gU1RBVFVTLCB5ID0gc3RhdGVuX2lzbGFuZF9jb3VudCwgZmlsbCA9ICJTdGF0ZW4gSXNsYW5kIiwKICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiU3RhdGVuIElzbGFuZDogIiwgc3RhdGVuX2lzbGFuZF9jb3VudCkpKSArCiAgICBzY2FsZV9maWxsX21hbnVhbChuYW1lID0gIkJvcm91Z2giLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGMoIiMxOGExNjUiLCAiIzU4MTM2ZSIsICIjMTg2Y2ExIiwgIiMxODQxYTEiLCAiIzE4YTE5OCIpLAogICAgICAgICAgICAgICAgICAgIGJyZWFrcyA9IGMoIkJyb29rbHluIiwgIk1hbmhhdHRhbiIsICJCcm9ueCIsICJRdWVlbnMiLCAiU3RhdGVuIElzbGFuZCIpKSArCiAgICBsYWJzKHggPSAiU3RhdHVzIiwgeSA9ICJDb3VudCIsCiAgICAgICB0aXRsZSA9ICJHcmFmZml0aSBJbmNpZGVudHMgYnkgQnVyb3VnaCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogTllDIE9wZW4gRGF0YSIpICsKICB0aGVtZV9idygpCgpnZ3Bsb3RseShhbGxfYm9yb19wbG90MSwgdG9vbHRpcCA9ICJ0ZXh0IikKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9CiNvbmx5IGNsZWFuZWQgZ3JhZmZpdGkgaW5jaWRlbnRzIGhhdmUgdHdvIGRhdGVzL2xlbmd0aCBvZiB0aW1lCmNsZWFuZWRfZ3JhZmZpdHRpIDwtIHJlYWxfZ3JhZmZpdGkgJT4lCiAgZmlsdGVyKFNUQVRVUyA9PSAiQ2xvc2VkIikKY2xlYW5lZF9ncmFmZml0dGlfc2hwIDwtIHJlYWxfZ3JhZmZpdGlfc2hwICU+JQogIGZpbHRlcihTVEFUVVMgPT0gIkNsb3NlZCIpCgojY3JlYXRlaW5nIGRhdGVfZGlmZiA9IENSRUFURURfREEgLSBDTE9TRURfREFUCmRhdGVzX2NsZWFuZWRfZ3JhZmZpdGkgPC0gY2xlYW5lZF9ncmFmZml0dGkgJT4lCiAgc2VsZWN0KElOQ0lERU5UX0EsIEJPUk9VR0gsIENSRUFURURfREEsIENMT1NFRF9EQVQsIENFTlNVU19UUkEpICU+JQogIG11dGF0ZShkYXRlX2RpZmYgPSBkaWZmdGltZSgoYXMuRGF0ZShDUkVBVEVEX0RBLCAiJW0vJWQvJXkiKSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcy5EYXRlKENMT1NFRF9EQVQsICIlbS8lZC8leSIpKSwgdW5pdHMgPSAnZGF5cycpKSAlPiUKICAjcmVtb3ZpbmcgdGhlIHdvcmQgJ2RhdGVzJyBmcm9tIHRoZSBjb2wKICBtdXRhdGVfYXQoImRhdGVfZGlmZiIsIHN0cl9yZXBsYWNlLCAiZGF5cyIsICIiKSAlPiUKICBtdXRhdGUoZGF0ZV9kaWZmID0gYXMubnVtZXJpYyhkYXRlX2RpZmYpKSAlPiUKICBtdXRhdGUoZGF0ZV9kaWZmID0gaWZfZWxzZShkYXRlX2RpZmYgPiAxLCAoZGF0ZV9kaWZmIC0gMzY1KSwgZGF0ZV9kaWZmKSkgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGRhdGVfZGlmZiAqICgtMSkpCmRhdGVzX2NsZWFuZWRfZ3JhZmZpdGlfc2hwIDwtIGNsZWFuZWRfZ3JhZmZpdHRpX3NocCAlPiUKICBzZWxlY3QoSU5DSURFTlRfQSwgQk9ST1VHSCwgQ1JFQVRFRF9EQSwgQ0xPU0VEX0RBVCkgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGRpZmZ0aW1lKChhcy5EYXRlKENSRUFURURfREEsICIlbS8lZC8leSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXMuRGF0ZShDTE9TRURfREFULCAiJW0vJWQvJXkiKSksIHVuaXRzID0gJ2RheXMnKSkgJT4lCiAgbXV0YXRlX2F0KCJkYXRlX2RpZmYiLCBzdHJfcmVwbGFjZSwgImRheXMiLCAiIikgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGFzLm51bWVyaWMoZGF0ZV9kaWZmKSkgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGlmX2Vsc2UoZGF0ZV9kaWZmID4gMSwgKGRhdGVfZGlmZiAtIDM2NSksIGRhdGVfZGlmZikpICU+JQogIG11dGF0ZShkYXRlX2RpZmYgPSBkYXRlX2RpZmYgKiAoLTEpKQoKI2NyZWF0aW5nIGEgZGF0YSB0YWJsZSB3aXRoIHRoZSBhdmVyYWdlIG51bWJlciBvZiBkYXlzIGl0IHRvb2sgdG8gY2xlYW4gaW4gZWFjaCBib3JvdWdoCmRhdGVzX2NsZWFuZWRfYXZlIDwtIGRhdGVzX2NsZWFuZWRfZ3JhZmZpdGkgJT4lCiAgZ3JvdXBfYnkoQk9ST1VHSCkgJT4lCiAgc3VtbWFyaXNlKGF2Z19kYXRlX2RpZmYgPSBtZWFuKGRhdGVfZGlmZiwgbmEucm0gPSBUUlVFKSkKZGF0ZXNfY2xlYW5lZF9hdmVfc2hwIDwtIGRhdGVzX2NsZWFuZWRfZ3JhZmZpdGlfc2hwICU+JQogIGdyb3VwX2J5KEJPUk9VR0gpICU+JQogIHN1bW1hcmlzZShhdmdfZGF0ZV9kaWZmID0gbWVhbihkYXRlX2RpZmYsIG5hLnJtID0gVFJVRSkpCgojb3V0bGluZSBvZiBKVVNUIGJvcm91Z2hzLCBubyBvdGhlciBpbmZvCmJvcm91Z2hfc2hwIDwtIGNlbnN1c19kYXRhICU+JQogIGdyb3VwX2J5KEJvcm9OYW1lKSAlPiUKICBzdW1tYXJpc2UoQ1RfY291bnQ9bigpKQojb3VsaW5lIG9mIGp1c3QgbWFuaGF0dGFuCk1fYm9yb3VnaF9zaHAgPC0gYm9yb3VnaF9zaHAgJT4lCiAgZmlsdGVyKEJvcm9OYW1lID09ICJNYW5oYXR0YW4iKQoKYGBgCgojIyMjIyBGaWcuIDM6ClRoaXMgYmFyIGNoYXJ0IHNob3djYXNlcyB0aGUgYXZlcmFnZSBudW1iZXIgb2YgZGF5cyBpdCB0b29rIEdyYWZmaXRpLUZyZWUgTllDIHRvIGNsZWFuIGFuIGluY2lkZW50IG9mIGdyYWZmaXRpIGZyb20gdGhlIGRheSBpdCB3YXMgcmVwb3J0ZWQuIEJ5IGxvb2tpbmcgYXQgZWFjaCBib3JvdWdoLCB3ZSBjYW4gc2VlIGl0IHRvb2sgcmVsYXRpdmVseSB0aGUgc2FtZSBhbW91bnQgb2YgdGltZSBpbiBlYWNoIGJvcm91Z2gsIHJlZ2FyZGxlc3Mgb2YgaW5jaWRlbnQgY291bnQgcGVyIGJvcm91Z2guIEdyYWZmaXRpLUZyZWUgTllDIGlzIGEgY2l0eSBydW4gYWdlbmN5LCBzbyBpdCBtYWtlcyBzZW5zZSB0aGF0IGF2ZXJhZ2UgY2xlYW5pbmcgdGltZSB3b3VsZCBiZSB0aGUgc2FtZSBhY3Jvc3MgYm9yb3VnaHMuIAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQojQUREIFJFRCBEQVNIRUQgTElORSBGT1IgT1ZFUkFMTCBBVkVSQUdFCiNQbG90IG9mIHRoZSBhdmVyYWdlIG51bWJlciBvZiBkYXlzIGZvciBlYWNoIGJvcm91Z2gKZGF0ZXNfYXZlX3Bsb3QgPC0gZ2dwbG90KCkgKwogIGdlb21fY29sKGRhdGEgPSBkYXRlc19jbGVhbmVkX2F2ZSwgbWFwcGluZyA9IGFlcyh4ID0gQk9ST1VHSCwgeSA9IGF2Z19kYXRlX2RpZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZShyb3VuZChhdmdfZGF0ZV9kaWZmKSwgImRheXMiKSkpICsKICB0aGVtZV9idygpICsKICBsYWJzKHggPSAiQm9yb3VnaCIsIHkgPSAiQXZlcmFnZSBUaW1lIHRvIENsZWFuIChEYXlzKSIsCiAgICAgICAgdGl0bGUgPSAiVGltZSB0byBDbGVhbiBHcmFmZml0aSAoZGF5cykgaW4gTmV3IFlvcmsgQ2l0eSIsCiAgICAgICAgc3VidGl0bGUgPSAiQXZlcmFnZSBvZiBudW1iZXIgb2YgZGF5cyBmb3IgZWFjaCBpbmNpZGVudCBncm91cGVkIGJ5IGJvcm91Z2giLAogICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBOWUMgT3BlbiBEYXRhIikKZ2dwbG90bHkoZGF0ZXNfYXZlX3Bsb3QsIHRvb2x0aXAgPSAidGV4dCIpCmBgYAoKIyMjIyMgRmlnLiA0OgpUaGlzIG1hcCBwcm92aWRlcyBhIGdvb2Qgb3ZlcnZpZXcgb2Ygd2hhdCBlYWNoIG9mIHRoZXNlIGNsZWFuZWQgaW5jaWRlbnRzIGxvb2tzIGxpa2Ugc3BhdGlhbGx5IGFjcm9zcyB0aGUgY2l0eS4gSW4gdGhlIGJpZ2dlciBib3JvdWdocywgdGhlIGluY2lkZW50cyBhcmUgbW9yZSBoZWF2aWx5IGNvbmNlbnRyYXRlZCBuZWFyIHRoZSBjZW50ZXIgb2YgdGhlIGNpdHksIGFuZCB0aGVyZSBhcmUgbm90IG5lYXJseSBhcyBtYW55IHJlcG9ydHMgYXJvdW5kIHRoZSBvdXRlciBlYXN0IGFuZCBzb3V0aCBlZGdlcyBvZiB0aGUgY2l0eS4KCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD05LGZpZy5oZWlnaHQ9MTB9CiNtYXAgb2YgYWxsIGNvdW50cyBvZiBkYXRhICh1c2luZyBhbGwgZGF0YSBmcmFtZXMgd2l0aCBzaHAgYXR0YWNoZWQpCmdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBib3JvdWdoX3NocCwgZmlsbCA9IE5BKSArCiAgZ2VvbV9zZihkYXRhID0gIGRhdGVzX2NsZWFuZWRfZ3JhZmZpdGlfc2hwLCBtYXBwaW5nID0gYWVzKGNvbG9yID0gZGF0ZV9kaWZmKSwKICAgICAgICAgIHNob3cubGVnZW5kID0gImRhdGVfZGlmZiIpICsKICBzY2FsZV9jb2xvcl92aXJpZGlzKG5hbWU9ImRheXMiLCBkaXJlY3Rpb249LTEpICsKICB0aGVtZV92b2lkKCkgKwogIGxhYnModGl0bGUgPSAiR3JhZmZpdGkgTGVuZ3RoIG9mIENsZWFuaW5nIChkYXlzKSIsCiAgICAgICBzdWJ0aXRsZSA9ICJBbGwgQ2xlYW5lZCBJbmNpZGVudHMgaW4gTmV3IFlvcmsgQ2l0eSIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogTllDIE9wZW5EYXRhIDIwMjEiKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI3VzaW5nIHNwYXRpYWwgZGF0YSB0byBtYXAgTWFuaGF0dGFuCiNzdWJzZXQgLSBzZWxlY3RpbmcganVzdCBtYW5oYXRhbiAKbWFuaGF0dGFuX2NsZWFuZWRfQ1Rfc2hwIDwtIHN1YnNldChjbGVhbmVkX2dyYWZmaXR0aV9zaHAsIEJPUk9VR0ggPT0gIk1BTkhBVFRBTiIpICU+JQogICNtdXRhdGUgdG8gZGVhbCB3aXRoIGNlbnN1cyBudW1iZXJzIHRoYXQgYXJlIGRlY2ltaWxlcy4uLiBtaWdodCBub3QgYmUgbmVzc2VjYXJ5IHdpdGggYml0ZXMgb2YgYmlnIGFwcGxlPwogIG11dGF0ZShDRU5TVVNfVFJBID0gaWZfZWxzZShDRU5TVVNfVFJBID4gMzEwLCAoQ0VOU1VTX1RSQS8xMDApLCBDRU5TVVNfVFJBKSkKCiNkYXRlX2RpZmYgY29sIHdpdGggZ2VvbWV0cnkKZGF0ZXNfY2xlYW5lZF9NX3NocCA8LSBtYW5oYXR0YW5fY2xlYW5lZF9DVF9zaHAgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGRpZmZ0aW1lKChhcy5EYXRlKENSRUFURURfREEsICIlbS8lZC8leSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXMuRGF0ZShDTE9TRURfREFULCAiJW0vJWQvJXkiKSksIHVuaXRzID0gJ2RheXMnKSkgJT4lCiAgbXV0YXRlX2F0KCJkYXRlX2RpZmYiLCBzdHJfcmVwbGFjZSwgImRheXMiLCAiIikgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGFzLm51bWVyaWMoZGF0ZV9kaWZmKSkgJT4lCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGlmX2Vsc2UoZGF0ZV9kaWZmID4gMSwgKGRhdGVfZGlmZiAtIDM2NSksIGRhdGVfZGlmZikpICU+JQogIG11dGF0ZShkYXRlX2RpZmYgPSBkYXRlX2RpZmYgKiAoLTEpKSAlPiUKICBtdXRhdGUoQ0VOU1VTX1RSQSA9IGFzLmNoYXJhY3RlcihDRU5TVVNfVFJBLCBuYS5ybSA9IFRSVUUpKQogICNzZWxlY3QoSU5DSURFTlRfQSwgQ1JFQVRFRF9EQSwgQ0xPU0VEX0RBVCwgZGF0ZV9kaWZmLCBDRU5TVVNfVFJBKQoKI2NlbnN1cyB0cmFjdCB3aXRoIGF2ZXJhZ2UgZGF0ZSBjb2wgYnkgQ1QKZGF0ZXNfYXZlX0NUX01fc2hwIDwtIGRhdGVzX2NsZWFuZWRfTV9zaHAgJT4lCiAgZ3JvdXBfYnkoQ0VOU1VTX1RSQSkgJT4lCiAgc3VtbWFyaXNlKGF2Z19kYXRlX2RpZmYgPSByb3VuZChtZWFuKGRhdGVfZGlmZiwgbmEucm0gPSBUUlVFKSwgMikpICU+JQogIGZpbHRlcihDRU5TVVNfVFJBICE9ICJOQSIpCgojdGhpcyBwbG90IHNob3dzIHRoZSBsZW5ndGggb2YgdGltZSBpdCB0b29rIGZvciBldmVyeSBpbmNpZGVudCByZXBvcnRlZCBpbiBNYW5oYXR0YW4gdG8gYmxlIGNsZWFuZWQKI0l0IGlzIGEgdG9uIG9mIGluZm8sIHNvIG5vdCBjdXJlbnRseSBvbiBkaXNwbGF5Cm1hbmhhdHRhbl9kYXRlX2RpZmYgPC0gZ2dwbG90KCkgKwogIGdlb21fY29sKGRhdGEgPSBkYXRlc19jbGVhbmVkX01fc2hwLCBtYXBwaW5nID0gYWVzKHggPSBJTkNJREVOVF9BLCB5ID0gZGF0ZV9kaWZmKSkgKwogIHRoZW1lX2J3KCkgKwogIGxhYnMoeCA9ICJNYW5oYXR0YW4gSW5jaWRlbnRzIiwgeSA9ICJMZW5ndGggb2YgVGltZSAoRGF5cyIpCiNtYW5oYXR0YW5fZGF0ZV9kaWZmCgojQWdhaW4sIGFsb3Qgb2YgaW5vZiwgbm90IHN1cmUgdG8gaW5jbHVkZQpDVF9kYXRlX2RpZmYgPC0gZ2dwbG90KGRhdGEgPSBkYXRlc19hdmVfQ1RfTV9zaHApICsKICBnZW9tX2NvbChtYXBwaW5nID0gYWVzKHggPSByZW9yZGVyKENFTlNVU19UUkEsYXZnX2RhdGVfZGlmZiksIHkgPSBhdmdfZGF0ZV9kaWZmKSkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT05MCxoanVzdD0xLHZqdXN0PTEpKQojQ1RfZGF0ZV9kaWZmCgojbWFraW5nIGFuIG91dGxpbmUgb2YganVzdCBNYW5oYXR0YW4KI2NlbnN1cyBkYXRhIGlzIGZyb20gYnl0ZXMgb2YgdGhlIGJpZyBhcHBsZQpNX2NlbnN1c19kYXRhX3NocCA8LSBjZW5zdXNfZGF0YSAlPiUKICBmaWx0ZXIoQm9yb05hbWUgPT0gIk1hbmhhdHRhbiIpCgojYWxsIHJlYWwgaW5jaWRlbnRzIGluIE1hbmhhdHRhbgpNX3JlYWxfZ3JhZmZpdGlfc2hwIDwtIGdyYWZmaXRpX3Jhd19zaHAgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gTm8gZ3JhZmZpdGkgb24gcHJvcGVydHkuJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ01haWwgcmV0dXJuZWQgLyB3cm9uZyBhZGRyZXNzJykgJT4lCiAgZmlsdGVyKFJFU09MVVRJT04gIT0gJ0NsZWFuaW5nIGNyZXcgZGlzcGF0Y2hlZC4gIENhbm5vdCBsb2NhdGUgcHJvcGVydHkuJykgJT4lCiAgZmlsdGVyKEJPUk9VR0ggPT0gJ01BTkhBVFRBTicpICU+JQogICNjcmVhdGluZyBhIGNvbCB0aGF0IGRpdmlkZXMgc3RhdHVzIGludG8gY2xlYW5lZCBvciBub3QKICBtdXRhdGUoY2xlYW5lZCA9IGlmX2Vsc2UoU1RBVFVTID09ICJDbG9zZWQiLCAieWVzIiwgIm5vIikpCmBgYAoKIyMjIEEgRGVlcGVyIERpdmU6IE1hbmhhdHRhbgpUaGlzIGRhdGEgc2V0IGNvbnRhaW5lZCBqdXN0IHNoeSBvZiAyMCwwMDAgcmVwb3J0ZWQgaW5jaWRlbnRzLCBhbmQgbXkgY29tcHV0ZXIgd2FzIG5vdCBoYXBweSB3aXRoIHRoZSBhbW91bnQgb2YgZGF0YS4gSSBkZWNpZGVkIHRvIGNlbnRlciBteSByZXNlYXJjaCBvbiBNYW5oYXR0YW4sIHNpbXBseSB0byBjdXQgZG93biB0aGUgbnVtYmVyIG9mIGRhdGEgcG9pbnRzLiBGb3IgZnV0dXJlIHJlc2VhcmNoLCB0aGVzZSBzYW1lIGNvZGVzIGNvdWxkIGJlIHJ1biBmb3IgZXZlcnkgYm9yb3VnaC4KCiMjIyMjIEZpZy4gNToKVGhpcyBtYXAgc2hvd3MgYWxsIHRoZSByZXBvcnRlZCBpbnN0YW5jZXMgb2YgZ3JhZmZpdGkgaW4gTWFuaGF0dGFuLCBjb2xvciBjb2RlZCBieSBpZiB0aGUgaW5jaWRlbnQgd2FzIGNsZWFuZWQgb3Igbm90LiBJdCBpcyBpbnRlcmVzdGluZyB0byBub3RlIHRoZSBhbW91bnQgb2YgcG9pbnRzIGNvbmdyZWdhdGVkIGluIGNlcnRhaW4gYXJlYXMgbGlrZSB0aGUgTG93ZXIgRWFzdCBTaWRlLCBhbmQgbGVzcyBzbyBpbiB0aGUgVXBwZXIgV2VzdCBTaWRlIGFyZWEuIAoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBmaWcud2lkdGg9OSxmaWcuaGVpZ2h0PTEwfQojRklORCBBVkUgRElGIEJFVFdFRU4gQ0xFQU5FRCBPUiBOT1QKI21hcCBvZiBieXRlcyBvZiBiaWcgYXBwbGUgMjAxMCBjZW5zdXMgdHJhY3RzIHdpdGggYWxsIGluY2lkZW50cyBvZiBncmFmZml0aSBpbiBNYW5oYXR0YW4KZ2dwbG90KCkgKwogIGdlb21fc2YoZGF0YSA9IE1fYm9yb3VnaF9zaHAsIGZpbGwgPSBOQSkgKwogIGdlb21fc2YoZGF0YSA9IE1fcmVhbF9ncmFmZml0aV9zaHAsIGFlcyhjb2xvciA9IGNsZWFuZWQsIGFscGhhID0gLjEwKSkgKwogIGd1aWRlcyhhbHBoYSA9IEZBTFNFKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoJ3llcycgPSAnIzNiYThhNicsICdubycgPSAnI2U4OWEzYScpLCBuYW1lID0gIkdyYWZmaXRpIEluY2lkZW50IENsZWFuZWQ/IikgKwogIHRoZW1lX3ZvaWQoKSArCiAgbGFicyh0aXRsZSA9ICJHcmFmZml0aSBJbmNpZGVudHMgTWFuaGF0dGFuIiwKICAgICAgIHN1YnRpdGxlID0gIk92ZXJsYXllZCBvbiBDZW5zdXMgVHJhY3QgTWFwIiwKICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBOWUMgT3BlbkRhdGEgMjAyMSB8IEJ5dGVzIG9mIHRoZSBCaWcgQXBwbGUiKQpgYGAKCmBgYHtyIHNldHVwMiwgaW5jbHVkZT1GQUxTRX0KI2ltcG9ydGluZyAyMDE5IGFjcyBkYXRhIGZvciBNYW5oYXR0YW4gCiNCMTkwMTNfMDAxIC0gRXN0aW1hdGUhIU1lZGlhbiBob3VzZWhvbGQgaW5jb21lIGluIHRoZSBwYXN0IDEyIG1vbnRocyAoaW4gMjAxOSBpbmZsYXRpb24tYWRqdXN0ZWQgZG9sbGFycykKcmF3X2luY29tZSA8LSBnZXRfYWNzKGdlb2dyYXBoeSA9ICJ0cmFjdCIsIAogICAgICAgICAgICAgIHZhcmlhYmxlcyA9ICJCMTkwMTNfMDAxIiwgCiAgICAgICAgICAgICAgc3RhdGUgPSAiTlkiLCAKICAgICAgICAgICAgICBjb3VudHkgPSAiTmV3IFlvcmsiLCAKICAgICAgICAgICAgICBnZW9tZXRyeSA9IFRSVUUsCiAgICAgICAgICAgICAgeWVhciA9IDIwMTksCiAgICAgICAgICAgICAgY2IgPSBGQUxTRSkKCiNjaGVja2luZyB0aGUgcHJvamVjdGlvbiBvZiB0aGUgY2Vuc3VzIGRhdGEgZnJhbWUKI3N0X2NycyhyYXdfaW5jb21lKSAjNDI2OQojY2hhbmdpbmcgdGhlIHByb2plY3Rpb24gb2YgdGhlIGNlbnN1cyBkYXRhIGZyYW1lCnJhd19pbmNvbWVfMjI2MyA8LSByYXdfaW5jb21lICU+JSAKICBzdF90cmFuc2Zvcm0oMjI2MykKCiNjcmVhdGluZyBmdW5jdGlvbiBhbmQgZGF0YSBzZXRzIHRvIGNsaXAgTWFuaGF0dGFuIHRvIHNob3JlIGxpbmVzCiNVc2luZyBqdXN0IHJhdyBjZW5zdXMgZGF0YSBsb29rcyB3ZWlyZApzdF9lcmFzZSA8LSBmdW5jdGlvbih4LCB5KSB7CiAgc3RfZGlmZmVyZW5jZSh4LCBzdF91bmlvbih5KSkKfQojZGF0YSBzZXQgb2Ygd2F0ZXIgYm9kaWVzIGluIE5ZQwpNX3dhdGVyIDwtIGFyZWFfd2F0ZXIoIk5ZIiwgIk5ldyBZb3JrIiwgY2xhc3MgPSAic2YiKSAlPiUKICBzdF90cmFuc2Zvcm0oMjI2MykKI2NsaXBwaW5nIHRoZSByYXcgaW5jb21lIGRhdGEgc2V0IGJ5IHRoZSB3YXRlciBib2RpZXMKTV9lcmFzZSA8LSBzdF9lcmFzZShyYXdfaW5jb21lXzIyNjMsIE1fd2F0ZXIpCmBgYAoKIyMjIyMgRmlnLiA2OgpUaGlzIG1hcCBzaG93cyB0aGUgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUgYnkgY2Vuc3VzIHRyYWN0IGluIE1hbmhhdHRhbi4gVGhlIHBvaW50cyByZXByZXNlbnQgY2xlYW5lZCBncmFmZml0aSBpbmNpZGVudHMuIFRoZSByZXBvcnRlZCBncmFmZml0aSBpbmNpZGVudHMgYXJlIGNlcnRhaW5seSBjb25ncmVnYXRlZCBpbiB0aGUgTG93ZXIgRWFzdCBTaWRlIGFuZCBuZWlnaGJvcmhvb2RzIGFib3ZlIENlbnRyYWwgUGFyaywgd2hpY2ggYXJlIGFsc28gYm90aCBhcmVhcyB0aGF0IGFyZSBwcmltYXJpbHkgcmVwcmVzZW50ZWQgYnkgYSBsb3dlciBtZWRpYW4gaG91c2Vob2xkIGluY29tZS4gQmV5b25kIHRoaXMgdmlzdWFsaXphdGlvbiwgaXQgd2FzIGRpZmZpY3VsdCB0byBjb21wbGV0ZSBtZWFuaW5nZnVsIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGF0IHRoZSBjZW5zdXMgdHJhY3QgbGV2ZWwgc28gZm9yIG15IG5leHQgdmlzdWFsaXphdGlvbnMsIEkgaGF2ZSBzY2FsZWQgdXAgdG8gTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYSAoTlRBKSBmb3IgZnV0dXJlIHZpc3VhbGl6YXRpb25zLgoKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTksZmlnLmhlaWdodD0xMH0KI21hcHBpbmcgdGhlICJlcmFzZSIgZGF0YSBzZXQgdGhhdCBpcyBjbGlwcGVkIGJ5IHRoZSBmdW5jdGlvbiwgCiNmaWxsID0gZXN0aW1hdGUgb2YgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUKZ2dwbG90KCkgKyAKICBnZW9tX3NmKGRhdGEgPSBNX2VyYXNlLCBhZXMoZmlsbCA9IGVzdGltYXRlKSwgY29sb3IgPSAiI2ZmZmZmZiIpICsgCiAgZ2VvbV9zZihkYXRhID0gTV9ib3JvdWdoX3NocCwgZmlsbCA9IE5BLCBjb2xvciA9ICIjMDAwMDAwIikgKwogIHRoZW1lX3ZvaWQoKSArIAogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG5hbWUgPSAiTWVkaWFuIEhvc2Vob2xkIEluY29tZSAoJCkiLCBsYWJlbHMgPSBzY2FsZXM6OmRvbGxhciwgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiKSArCiAgZ2VvbV9zZihkYXRhID0gTV9yZWFsX2dyYWZmaXRpX3NocCwgYWVzKGNvbG9yID0gQk9ST1VHSCwgYWxwaGEgPSAuNSkpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gJ2JsYWNrJywgbmFtZSA9ICIiLCBsYWJlbHMgPSAiR3JhZmZpdGkgSW5jaWRlbnQiKSsKICBndWlkZXMoYWxwaGEgPSBGQUxTRSwKICAgICAgICAgZmlsbCA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDEpLAogICAgICAgICBjb2xvciA9IGd1aWRlX2xlZ2VuZChvcmRlciA9IDIpKSArCiAgbGFicygKICAgIHRpdGxlID0gIk1hbmhhdHRhbiBNZWRpYW4gSG91c2Vob2xkIEluY29tZSBieSBDZW5zdXMgVHJhY3QiLAogICAgc3VidGl0bGUgPSAiKG92ZXJsYXllZCB3aXRoIHJlcG9ydGVkIGdyYWZmaXRpIGluY2lkZW50cykiLAogICAgY2FwdGlvbiA9ICJTb3VyY2U6IEFDUyAyMDE5IHwgR3JhZmZpdHRpOiBOWUMgT3BlbkRhdGEiKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI1NXSVRDSElORyBUTyBOVEEgKGZyb20gY3QpCiNkYXRhIHRhYmxlIGJhc2VkIG9uIGFjczIwMTkgb2YgTWFuaGF0dGFuIG1oaQptYW5oYXR0YW5fbWhpX3NocCA8LSBNX2VyYXNlICU+JSAjTV9lcmFzZSBpcyBmcm9tIGFjcwogICNnZXR0aW5nIHJpZCBvZiBleHRyYSBpbmZvOyB0byBqb2luIGJhc2VkIG9uIENUIGxhdGVyIGlmIG5lc3NlY2FyeQogIG11dGF0ZV9hdCgiTkFNRSIsIHN0cl9yZXBsYWNlLCAiQ2Vuc3VzIFRyYWN0ICIsICIiKSAlPiUKICBtdXRhdGVfYXQoIk5BTUUiLCBzdHJfcmVwbGFjZSwgIiwgTmV3IFlvcmsgQ291bnR5LCBOZXcgWW9yayIsICIiKSAlPiUKICAjc3RpbGwgdW5zdXJlIGlmIHRoaXMgc2hvdWxkIGJlIG51bWVyaWMuLi4KICAjbXV0YXRlKENFTlNVU19UUkEgPSBhcy5udW1lcmljKE5BTUUpKSAlPiUKICByZW5hbWUodG90YWxfbWhpID0gZXN0aW1hdGUsCiAgICAgICAgIHRvdGFsX21vZSA9IG1vZSwKICAgICAgICAgQ0VOU1VTX1RSQSA9IE5BTUUpCiNKdXN0IGdlb21ldHJ5IGFuZCBvdXRsaW5lIG9mIE5UQXMKbnRhX291dGxpbmUgPC0gTV9jZW5zdXNfZGF0YV9zaHAgJT4lCiAgZ3JvdXBfYnkoTlRBTmFtZSkgJT4lCiAgc3VtbWFyaXNlKGNvdW50PW4oKSkgJT4lCiAgc2VsZWN0KE5UQU5hbWUpCiNjcmVhdGluZyBhIGNvbCB3aXRoIGF2cmVhZ2UgZGF0ZXMgcGVyIE5UQQpkYXRlc19hdmVfTlRBX01fc2hwIDwtIGRhdGVzX2NsZWFuZWRfTV9zaHAgJT4lCiAgZ3JvdXBfYnkoTlRBKSAlPiUKICBzdW1tYXJpc2UoYXZnX2RhdGVfZGlmZl9OVEEgPSByb3VuZChtZWFuKGRhdGVfZGlmZiwgbmEucm0gPSBUUlVFKSwgMikpCgojc3BhdGlhbGx5IGpvaW5pbmcgYWxsIDMgZGF0YXNldHMKTV9OVEFfTUhJX0RBX3NocCA8LSBudGFfb3V0bGluZSAlPiUKICBzdF9qb2luKG1hbmhhdHRhbl9taGlfc2hwLCBqb2luID0gc3RfaW50ZXJzZWN0cykgJT4lCiAgZmlsdGVyKE5UQU5hbWUgIT0gJ3BhcmstY2VtZXRlcnktZXRjLU1hbmhhdHRhbicpICU+JQogIGdyb3VwX2J5KE5UQU5hbWUpICU+JQogIG11dGF0ZShOVEFfbWhpID0gcm91bmQobWVhbih0b3RhbF9taGksIG5hLnJtID0gVFJVRSksIDIpKSAlPiUKICBzdF9qb2luKGRhdGVzX2F2ZV9OVEFfTV9zaHAsIGpvaW4gPSBzdF9pbnRlcnNlY3RzKQpgYGAKIyMjIyMgRmlnLiA3OgpUaGlzIG1hcCBzaG93Y2FzZXMgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUgKE1ISSkgYnkgTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYSAoTlRBKS4gSXQgYWxzbyBoYXMgdGhlIGFtb3VudCBvZiBjbGVhbmVkIGdyYWZmaXRpIGluY2lkZW50cyAoYmxhY2spLCBhbmQgaW5jaWRlbnRzIG5vdCB5ZXQgY2xlYW5lZCBieSB0aGUgR3JhZmZpdGktRnJlZSBOWUMgVGFzayBGb3JjZSAoZ3JleSkuIENoaW5hdG93biBpcyB0aGUgbmVpZ2hib3Job29kIHdpdGggdGhlIG1vc3QgcmVwb3J0ZWQgaW5jaWRlbnRzIG9mIGdyYWZmaXRpICg2OTkgaW5jaWRlbnRzKSBhbmQgYW4gYXZlcmFnZSBNSEkgKCQ0NCw1NDEuODEpIHdlbGwgYmVsb3cgdGhlIGF2ZXJhZ2UgZm9yIG5laWdoYm9yaG9vZCB0YWJ1bGF0aW9uIGFyZWEgaW4gTWFuaGF0dGFuLiBUaGUgbGVhc3QgcmVwb3J0ZWQgaW5jaWRlbnRzICgxIGluY2lkZW50KSBvY2N1cnJlZCBpbiBTdHV5dmVzYW50IFRvd24tQ29vcGVyIFZpbGxhZ2UsIGhvd2V2ZXIgdGhpcyBpcyBlbnRpcmUgTlRBIGlzIGEgcHJpdmF0ZSByZXNpZGVudGlhbCBkZXZlbG9wbWVudCwgYW5kIGhhcyBpdHMgb3duIHNhZmV0eSBmb3JjZSwgc28gaXQgaXMgbGlrZWx5IHRoYXQgaW5zdGFuY2VzIG9mIGdyYWZmaXRpIHdvdWxkIGJlIGRpcmVjdGx5IHJlcG9ydGVkIHRvIHRoZWlyIHNlY3VyaXR5IGZvcmNlIGFuZCBub3QgR3JhZmZpdGktRnJlZSBOWUMuIENvbnNpZGVyaW5nIHRoaXMgTlRBIGFzIGFuIG91dGxpZXIsIHRoZSBOVEEgd2l0aCB0aGUgbGVhc3QgcmVwb3J0ZWQgaW5zdGFuY2VzIG9mIGdyYWZmaXRpIHdvdWxkIGJlIExpbmNvbG4gU3F1YXJlICgxNCBpbmNpZGVudHMpIHdpdGggYW4gYXZlcmFnZSBtZWRpYW4gaG91c2Vob2xkIGluY29tZSBvZiAxMiw4MzI3LjcxIGRvbGxhcnMsIGFuIGF2ZXJhZ2UgTUhJIHRoYXQgaXMgMzYsMTgzLjk4IGhpZ2hlciB0aGFuIHRoZSBhdmVyYWdlIE1ISSBwZXIgTlRBIGluIE1hbmhhdHRhbi4gCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD05LGZpZy5oZWlnaHQ9MTB9Ck1fTlRBX01ISV9EQV9zaHAgPSBzZjo6c3RfY2FzdChNX05UQV9NSElfREFfc2hwLCAiTVVMVElQT0xZR09OIikKTlRBX21oaV9wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBudGFfb3V0bGluZSwgZmlsbCA9IE5BKSArCiAgZ2VvbV9zZihkYXRhID0gTV9OVEFfTUhJX0RBX3NocCwgYWVzKGZpbGwgPSBOVEFfbWhpKSkgKwogIHRoZW1lX3ZvaWQoKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmFtZSA9ICJNZWRpYW4gSG9zZWhvbGQgSW5jb21lICgkKSIsIGxhYmVscyA9IHNjYWxlczo6ZG9sbGFyKSArCiAgZ2VvbV9zZihkYXRhID0gTV9yZWFsX2dyYWZmaXRpX3NocCwgYWVzKGNvbG9yID0gY2xlYW5lZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gLjI1KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCd5ZXMnID0gJ2JsYWNrJywgJ25vJyA9ICdncmV5NzcnKSwgbmFtZSA9ICJHcmFmZml0aSBDbGVhbmVkPyIpICsKICBndWlkZXMoYWxwaGEgPSBGQUxTRSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJNYW5oYXR0YW4gTWVkaWFuIEhvdXNlaG9sZCBJbmNvbWUgKE1ISSkKICAgIGJ5IE5laWdib3Job29kIFRhYnVsYXRpb24gQXJlYSAoTlRBKSIsCiAgICBzdWJ0aXRsZSA9ICIob3ZlcmxhaWQgd2l0aCByZXBvcnRlZCBncmFmZml0aSBpbmNpZGVudHMpIiwKICAgIGNhcHRpb24gPSAiU291cmNlOiBBQ1MgMjAxOSB8IEdyYWZmaXR0aTogTllDIE9wZW5EYXRhIikKCk5UQV9taGlfcGxvdApgYGAKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI2NvdW50IHBlciBOVEEgYXJlYQpjb3VudF9wZXJfbnRhX3NocCA8LU1fcmVhbF9ncmFmZml0aV9zaHAgJT4lCiAgZ3JvdXBfYnkoTlRBKSAlPiUKICBzdW1tYXJpc2UoY291bnQ9bigpKSAlPiUKICBmaWx0ZXIoTlRBICE9ICdOQScpICU+JSAjc29tZSBpbmNpZGVudHMgYXJlIG1pc3NpbmcgTlRBIGluZm8gKGFsb25nIHdpdGggZGF0ZSBvcGVuL2Nsb3NlZCwgbG9uZy9sYXQsIGdlb21ldHJ5KQogIGZpbHRlcihOVEEgIT0gJ3BhcmstY2VtZXRlcnktZXRjLU1hbmhhdHRhbicpICNjb3VudGVkIGFzIGFuIE5UQSwgYnV0IG5vIG9uZSBsaXZlcyBoZXJlCmBgYAoKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KI2Ryb3BwaW5nIGdlb21ldHJ5IHRvIGpvaW4gYnkgQ1QgCm1hbmhhdHRhbl9taGkgPC0gc3RfZHJvcF9nZW9tZXRyeShNX2VyYXNlKSAlPiUgI01fZXJhc2UgaXMgZnJvbSBhY3MKICAjZ2V0dGluZyByaWQgb2YgZXh0cmEgaW5mbzsgdG8gam9pbiBiYXNlZCBvbiBDVCBsYXRlciBpZiBuZXNzZWNhcnkKICBtdXRhdGVfYXQoIk5BTUUiLCBzdHJfcmVwbGFjZSwgIkNlbnN1cyBUcmFjdCAiLCAiIikgJT4lCiAgbXV0YXRlX2F0KCJOQU1FIiwgc3RyX3JlcGxhY2UsICIsIE5ldyBZb3JrIENvdW50eSwgTmV3IFlvcmsiLCAiIikgJT4lCiAgI3N0aWxsIHVuc3VyZSBpZiB0aGlzIHNob3VsZCBiZSBudW1lcmljLi4uCiAgbXV0YXRlKE5BTUUgPSBhcy5udW1lcmljKE5BTUUpKSAlPiUKICByZW5hbWUodG90YWxfbWhpID0gZXN0aW1hdGUsCiAgICAgICAgIHRvdGFsX21vZSA9IG1vZSwKICAgICAgICAgQ0VOU1VTX1RSQSA9IE5BTUUpCgpjb3VudF9wZXJfbnRhX3NocCA8LU1fcmVhbF9ncmFmZml0aV9zaHAgJT4lCiAgZ3JvdXBfYnkoTlRBKSAlPiUKICBzdW1tYXJpc2UoY291bnQ9bigpKQpgYGAKCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GLCB3YXJuaW5nPUZ9CiNjb3VudCBwZXIgTlRBIGFyZWEgKEFMTCBJTkNJREVOVFMpc3VtICh+NDAwMCkKTlRBX3N0YXRzX3JhdyA8LSBzdF9kcm9wX2dlb21ldHJ5KE1fcmVhbF9ncmFmZml0aV9zaHApJT4lIAogIGxlZnRfam9pbihtYW5oYXR0YW5fbWhpLCBieSA9ICJDRU5TVVNfVFJBIikgJT4lCiAgI2ZpbHRlcihSRVNPTFVUSU9OICE9ICdQcm9wZXJ0eSBSZXNlYXJjaCBSZXF1aXJlZCcpICU+JSAjKHRoZXNlIGluY2lkZW50cyBoYXZlIG5vIGxvY2F0aW9uKSB0aGV5IHdlcmUgc3RpbGwgcmVwb3J0ZWQgdGhvdWdoLi4uCiAgbXV0YXRlKGRhdGVfZGlmZiA9IGRpZmZ0aW1lKChhcy5EYXRlKENSRUFURURfREEsICIlbS8lZC8leSIpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFzLkRhdGUoQ0xPU0VEX0RBVCwgIiVtLyVkLyV5IikpLCB1bml0cyA9ICdkYXlzJykpICU+JQogICNyZW1vdmluZyB0aGUgd29yZCAnZGF0ZXMnIGZyb20gdGhlIGNvbAogIG11dGF0ZV9hdCgiZGF0ZV9kaWZmIiwgc3RyX3JlcGxhY2UsICJkYXlzIiwgIiIpICU+JQogIG11dGF0ZShkYXRlX2RpZmYgPSBhcy5udW1lcmljKGRhdGVfZGlmZikpICU+JQogIG11dGF0ZShkYXRlX2RpZmYgPSBpZl9lbHNlKGRhdGVfZGlmZiA+IDEsIChkYXRlX2RpZmYgLSAzNjUpLCBkYXRlX2RpZmYpKSAlPiUKICBtdXRhdGUoZGF0ZV9kaWZmID0gZGF0ZV9kaWZmICogKC0xKSkgJT4lCiAgZ3JvdXBfYnkoTlRBKSAlPiUKICBtdXRhdGUoY291bnRfTlRBPW4oKSkgJT4lCiAgZmlsdGVyKE5UQSAhPSAnTkEnKSAlPiUKICBmaWx0ZXIoTlRBICE9ICdwYXJrLWNlbWV0ZXJ5LWV0Yy1NYW5oYXR0YW4nKSAlPiUKICBtdXRhdGUoYXZnX2RhdGVfZGlmZl9OVEEgPSByb3VuZChtZWFuKGRhdGVfZGlmZiwgbmEucm0gPSBUUlVFKSwgMikpICU+JQogIG11dGF0ZShOVEFfbWhpID0gcm91bmQobWVhbih0b3RhbF9taGksIG5hLnJtID0gVFJVRSksIDIpKSAlPiUKICAjbWFyYmxlIGhpbGwtaW53b29kIGlzIG9uZSBOVEEsIHR3byBwb2ludHMoYmVsb3cpIGFyZSBpbiBicm9ueCBhY3R1YWxseQogIGZpbHRlcihDT01NVU5JVFlfICE9ICIwOCBCUk9OWCIpICNhZGRyZXNzZXMgaW4gYnJvbngsIGJ1dCBCb3JvdWdoID0gTWFuaGF0dGFuLCBtaXN0YWtlPyBvbmx5IDIgaW5jaWRlbnRzLgojQ3JlYXRpbmcgY29sdW1ucyBmb3IgbnVtYmVyIG9mIGluY2lkZW50cyBvcGVuIGFuZCBjbG9zZWQKTlRBX2Nsb3NlZCA8LSBOVEFfc3RhdHNfcmF3ICU+JQogIGdyb3VwX2J5KE5UQSwgU1RBVFVTKSAlPiUKICB0YWxseSgpICU+JQogIHJlbmFtZShjb3VudF9jbGVhbmVkID0gbikgJT4lCiAgZmlsdGVyKFNUQVRVUyA9PSAiQ2xvc2VkIikgJT4lCiAgZGlzdGluY3QoTlRBLCAua2VlcF9hbGwgPSBUUlVFKQpOVEFfb3BlbiA8LSBOVEFfc3RhdHNfcmF3ICU+JQogIGdyb3VwX2J5KE5UQSwgU1RBVFVTKSAlPiUKICB0YWxseSgpICU+JQogIHJlbmFtZShjb3VudF9vcGVuID0gbikgJT4lCiAgZmlsdGVyKFNUQVRVUyA9PSAiT3BlbiIpICU+JQogIGRpc3RpbmN0KE5UQSwgLmtlZXBfYWxsID0gVFJVRSkKTlRBX29wZW5lZF9jbG9zZWQgPC0gTlRBX2Nsb3NlZCAlPiUKICBmdWxsX2pvaW4oTlRBX29wZW4sIGJ5ID0gIk5UQSIpICU+JQogICAgZGlzdGluY3QoTlRBLCAua2VlcF9hbGwgPSBUUlVFKQpgYGAKIyMjIyMgRmlnLiA4OiAKVGhpcyBkYXRhIHRhYmxlIHNob3djYXNlcyBzb21lIGltcG9ydGFudCBzdGF0aXN0aWNzIGZvciBncmFmZml0aSBpbiBNYW5oYXR0YW4gcmVsYXRlZCB0byBtZWRpYW4gaG91c2Vob2xkIGluY29tZS4KYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQpOVEFfc3RhdHNfcHJlIDwtIE5UQV9zdGF0c19yYXcgJT4lCiAgbGVmdF9qb2luKE5UQV9vcGVuZWRfY2xvc2VkLCBieSA9ICJOVEEiKSAlPiUKICBkaXN0aW5jdChOVEEsIC5rZWVwX2FsbCA9IFRSVUUpICU+JQogIHNlbGVjdChOVEEsIGNvdW50X05UQSwgYXZnX2RhdGVfZGlmZl9OVEEsIE5UQV9taGksIGNvdW50X29wZW4sIGNvdW50X2NsZWFuZWQpCgpOVEFfc3RhdHMgPC0gTlRBX3N0YXRzX3ByZSAlPiUgCiAgbXV0YXRlKHBjdF9tYW5oYXR0YW5fY291bnQgPSByb3VuZChjb3VudF9OVEEvNDE5MiwgNCkgKjEwMCkgJT4lCiAgbXV0YXRlKHBjdF9jbGVhbmVkID0gcm91bmQoKGNvdW50X2NsZWFuZWQvY291bnRfTlRBKSwgNCkgKiAxMDApICU+JQogIGZpbHRlcihOVEEgIT0gIlN0dXl2ZXNhbnQgVG93bi1Db29wZXIgVmlsbGFnZSIpICU+JQogIG11dGF0ZShhYm92ZV9hdmdfbWhpID0gaWZfZWxzZShOVEFfbWhpID4gOTk0NjcuNDQsICJZZXMiLCAiTm8iKSkgJT4lCiAgbXV0YXRlKGFib3ZlXzEwMF9jb3VudCA9IGlmX2Vsc2UoY291bnRfTlRBID4gMTU1LCAiWWVzIiwgIk5vIikpCgpOVEFfc3RhdDIgPC0gTlRBX3N0YXRzX3ByZSAlPiUgCiAgbXV0YXRlKHBjdF9tYW5oYXR0YW5fY291bnQgPSByb3VuZChjb3VudF9OVEEvKHN1bShOVEFfc3RhdHMkY291bnRfTlRBKSksIDQpKjEwMCkgJT4lCiAgbXV0YXRlKHBjdF9jbGVhbmVkID0gcm91bmQoKGNvdW50X2NsZWFuZWQvY291bnRfTlRBKSwgNCkgKiAxMDApCiAgCnN0YXRzX2J5X05UQSA8LSBOVEFfc3RhdDIgJT4lCiAgc2VsZWN0KGNvdW50X05UQSwgYXZnX2RhdGVfZGlmZl9OVEEsIE5UQV9taGksIGNvdW50X29wZW4sIGNvdW50X2NsZWFuZWQsIHBjdF9tYW5oYXR0YW5fY291bnQsIHBjdF9jbGVhbmVkKSAlPiUKICByZW5hbWUoJ051bWJlciBvZiBJbmNpZGVudHMnID0gY291bnRfTlRBLAogICAgICAgICAnQXZlcmFnZSBEYXlzIHRvIENsZWFuJyA9IGF2Z19kYXRlX2RpZmZfTlRBLAogICAgICAgICAnQXZlcmFnZSBNSEknID0gTlRBX21oaSwKICAgICAgICAgJ0luY2lkZW50cyBOb3QgWWV0IENsZWFuZWQnID0gY291bnRfb3BlbiwKICAgICAgICAgJ0luY2lkZW50cyBDbGVhbmVkJyA9IGNvdW50X2NsZWFuZWQsCiAgICAgICAgICclIG9mIEluY2lkZW50cyBDbGVhbmVkJyA9IHBjdF9jbGVhbmVkLAogICAgICAgICAnJSBvZiBJbmNpZGVudHMgaW4gTWFuaGF0dGFuJyA9IHBjdF9tYW5oYXR0YW5fY291bnQpCgpzdGF0c19ieV9OVEEKYGBgCkNvdW50aW5nIFN0dXl2ZXNhbnQgVG93bi1Db29wZXIgVmlsbGFnZSBhcyBhbiBvdXRsaWVyLCBoZXJlIGlzIHNvbWUgb2YgdGhlIGluZm9ybWF0aW9uIHN1bW1lZCB1cCwgYWxsIGluIHRoZSBzY29wZSBvZiBOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhIChOVEEpOgoKKiBBdmVyYWdlIG1lZGlhbiBob3VzZWhvbGQgaW5jb21lOiAkOTksNDY3LjQ0CiogVG90YWwgbnVtYmVyIG9mIGluY2lkZW50cyBpbiBNYW5oYXR0YW46IDQsMTkyCiogQXZlcmFnZSBudW1iZXIgb2YgaW5jaWRlbnRzIGluIGVhY2ggTlRBOiAxNTUKKiBBdmVyYWdlIG51bWJlciBvZiBkYXlzIHRvIGNsZWFuIGFuIGluY2lkZW50IGluIGVhY2ggTlRBOiAxMjguNzUKKiBUb3RhbCBudW1iZXIgb2YgaW5jaWRlbnRzIGNsZWFuZWQgaW4gTWFuaGF0dGFuOiAyLDEyMgoqIEF2ZXJhZ2UgbnVtYmVyIG9mIGluY2lkZW50cyBjbGVhbmVkIHBlciBOVEE6IDc5CiogVG90YWwgbnVtYmVyIG9mIGluY2lkZW50cyBub3QgeWV0IGNsZWFuZWQgaW4gTWFuaGF0dGFuOiAyLDA2OAoqIEF2ZXJhZ2UgbnVtYmVyIG9mIGNhc2VzIG5vdCB5ZXQgY2xlYW5lZCBwZXIgTlRBOiA3NwoqIEF2ZXJhZ2UgcGVyY2VudCBvZiBpbmNpZGVudHMgY2xlYW5lZCBhY3Jvc3MgTWFuaGF0dGFuOiA1MC42MiUKKiBBdmVyYWdlIHBlcmNlbnQgb2YgY2FzZXMgY2xlYW5lZCBwZXIgTlRBOiA1MS4xNyUKCiMjIyMjIEZpZy4gOToKVGhlIGludGVyYWN0aXZlIG1hcCBiZWxvdyB2aXN1YWxpemVzIHNvbWUgb2YgdGhpcyBpbmZvcm1hdGlvbjoKCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KTlRBX3N0YXRzX3NocCA8LSBpbm5lcl9qb2luKE5UQV9zdGF0cywgbnRhX291dGxpbmUsIGJ5ID0gYygiTlRBIiA9ICJOVEFOYW1lIikpICU+JQogIHN0X3NldF9nZW9tZXRyeSgiZ2VvbWV0cnkiKQoKTlRBX3N0YXRzX3NocCA9IHNmOjpzdF9jYXN0KE5UQV9zdGF0c19zaHAsICJNVUxUSVBPTFlHT04iKQpudGFfb3V0bGluZSA9IHNmOjpzdF9jYXN0KG50YV9vdXRsaW5lLCAiTVVMVElQT0xZR09OIikKCk5UQV9wbG90IDwtIGdncGxvdCgpICsKICBnZW9tX3NmKGRhdGEgPSBudGFfb3V0bGluZSwgZmlsbCA9IE5BKSArCiAgZ2VvbV9zZihkYXRhID0gTlRBX3N0YXRzX3NocCwgYWVzKGZpbGwgPSAiTlRBIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJOVEE6ICIsIE5UQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+R3JhZmZpdGkgSW5jaWRlbnRzOiAiLCBjb3VudF9OVEEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPk1ISTogIiwgc2NhbGVzOjpkb2xsYXIoTlRBX21oaSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkF2ZXJhZ2UgTGVndGggb2YgVGltZSB0byBjbGVhbiBHcmFmZml0aTogIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF2Z19kYXRlX2RpZmZfTlRBLCAiZGF5cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlVucmVzbG92ZWQgR3JhZmZpdGkgSW5jaWRlbnRzOiAiLCBjb3VudF9vcGVuKSkpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSAiI2JmYmZiZiIpICsKICB0aGVtZV92b2lkKCkgKwogIGxhYnModGl0bGUgPSAiTWFuaGF0dGFuIE5laWdib3Job29kIFRhYnVsYXRpb24gQXJlYXMiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEJ5dGVzIG9mIHRoZSBCaWcgQXBwbGUgfCBOWUMgT3BlbkRhdGEgfCBBQ1MgMjAxOSIpICsKICBndWlkZXMoZmlsbCA9IEZBTFNFKQoKZ2dwbG90bHkoTlRBX3Bsb3QsIHRvb2x0aXAgPSAidGV4dCIpCgpgYGAKCgojIyMjIyBGaWcuIDEwOgpUaGlzIGJhciBjaGFydCBkaXNwbGF5cyBlYWNoIG5laWdoYm9yaG9vZCB0YWJ1bGF0aW9uIGFyZWEncyBhbW91bnQgb2YgZ3JhZmZpdGkgaW5jaWRlbnRzIHJlcG9ydGVkIChpbiBvcmRlciBmcm9tIGxlYXN0IGluY2lkZW50cyB0byBtb3N0KS4gVGhlIGNvbHVtbnMgYXJlIGFsc28gY29sb3JlZCB0byBzaG93IGlmIHRoZSBOVEFzIGF2ZXJhZ2UgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUgaXMgYWJvdmUgb3IgYmVsb3cgdGhlIHRvdGFsIGF2ZXJhZ2UgZm9yIE1hbmhhdHRhbi4gCmBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rn0KbnRhX21oaV9wbG90MSA8LSBOVEFfc3RhdHMgJT4lCiAgZmlsdGVyKE5UQSAhPSAiU3R1eXZlc2FudCBUb3duLUNvb3BlciBWaWxsYWdlIikgJT4lCiAgZ2dwbG90KCkgKwogIGdlb21fY29sKG1hcHBpbmcgPSBhZXMoeD1yZW9yZGVyKE5UQSxjb3VudF9OVEEpLCB5PWNvdW50X05UQSwgZmlsbCA9IGFib3ZlX2F2Z19taGksIGFscGhhID0gLjUwKSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoJ1llcycgPSAnIzNiYThhNicsICdObycgPSAnI2U4OWEzYScpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiIiwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJBYm92ZSBBdmVyYWdlIE1ISSBpbiBNYW5oYXR0YW4iLCAiQmVsb3cgQXZlcmFnZSBNSEkgaW4gTWFuaGF0dGFuIikpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT03NSxoanVzdD0xLHZqdXN0PTEpKSArCiAgZ3VpZGVzKGFscGhhID0gRkFMU0UpICsKICBsYWJzKHggPSAiIiwgeSA9ICJDb3VudCIsCiAgICAgICB0aXRsZSA9ICJDb3VudCBvZiBHcmFmZml0aSBJbmNpZGVudHMiLAogICAgICAgc3VidGl0bGUgPSAiUmVwb3J0ZWQgYnkgTlRBIGluIE1hbmhhdHRhbiIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQnl0ZXMgb2YgdGhlIEJpZyBBcHBsZSB8IE5ZQyBPcGVuRGF0YSIpCm50YV9taGlfcGxvdDEKYGBgCgo8YnI+IAoKIyMjIyMgRmlnLiAxMToKVGhpcyBiYXIgY2hhcnQgZGlzcGxheXMgZWFjaCBOVEEncyBtZWRpYW4gaG91c2Vob2xkIGluY29tZSwgY29sb3JlZCBieSBpZiB0aGV5IGhhZCBvdmVyIG9yIHVuZGVyIDE1NSBpbmNpZGVudHMgb2YgZ3JhZmZpdGkgKHRoZSBhdmVyYWdlIGZvciBhbiBOVEEgaW4gTWFuaGF0dGFuKS4gVGhlIHJlZCBkb3R0ZWQgbGluZSByZXByZXNlbnRzIHRoZSBhdmVyYWdlIE1ISSBhY3Jvc3MgTWFuaGF0dGFuLgoKYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9Riwgd2FybmluZz1GfQpudGFfbWhpX3Bsb3QxIDwtIE5UQV9zdGF0cyAlPiUKICBmaWx0ZXIoTlRBICE9ICJTdHV5dmVzYW50IFRvd24tQ29vcGVyIFZpbGxhZ2UiKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9jb2wobWFwcGluZyA9IGFlcyh4PU5UQSwgeT1OVEFfbWhpLCBmaWxsID0gYWJvdmVfMTAwX2NvdW50KSkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoJ1llcycgPSAnZ3JleTc3JywgJ05vJyA9ICdibGFjaycpLAogICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiIiwKICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJNb3JlIHRoYW4gMTU1IEluY2lkZW50cyIsICJMZXNzIHRoYW4gMTU1IEluY2lkZW50cyIpKSArCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDk5NDY3LjQ0KSxzaXplID0gMSwgY29sb3VyID0gIiM4ZjBhMGEiLCBsaW5ldHlwZT0iZG90dGVkIikgKyAKICBhbm5vdGF0ZSgidGV4dCIsIHg9NSwgeT0xMTkwMDAsIGxhYmVsPSAiQXZlcmFnZSBNSEkgaW4gTWFuaGF0dGFuIiwgY29sb3IgPSAiIzhmMGEwYSIsIHNpemUgPSAyLjUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChhbmdsZT03NSxoanVzdD0xLHZqdXN0PTEpKSArCiAgbGFicyh4ID0gIiIsIHkgPSAiTUhJICgkKSIsCiAgICAgICB0aXRsZSA9ICJBdmVyYWdlIE1lZGlhbiBIb3VzZWhvbGQgSW5jb21lIChNSEkpIiwKICAgICAgIHN1YnRpdGxlID0gIlJlcG9ydGVkIGJ5IE5UQSBpbiBNYW5oYXR0YW4iLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IEJ5dGVzIG9mIHRoZSBCaWcgQXBwbGUgfCBOWUMgT3BlbkRhdGEiKQpudGFfbWhpX3Bsb3QxCmBgYAoKIyMjIERpc2N1c3Npb246CkJhc2VkIG9uIHRoZSBnZW9ncmFwaGljYWwgYW5kIHN0YXRpc3RpY2FsIGFuYWx5c2lzIGNvbXBsZXRlIGFib3ZlLCBzb21lIGNvbmNsdXNpb25zIGFib3V0IGdyYWZmaXRpIGluIE5ldyBZb3JrIGNhbiBiZSBtYWRlLiBBcyBzZWVuIGluIGZpZy4gMSwgZ3JhZmZpdGkgaW4gTmV3IFlvcmsgQ2l0eSBpcyBmb3VuZCBpbiBhbGwgNSBib3JvdWdocywgYnV0IG5vdCBzcHJlYWQgZXZlbmx5IHdpdGhpbiB0aGVtLgoKKiA5LDEzMSBpbmNpZGVudHMgaW4gQnJvb2tseW4KKiA0LDUzMCBpbmNpZGVudHMgaW4gTWFuaGF0dGFuCiogMyw0NjcgaW5jaWRlbnRzIGluIHRoZSBCcm9ueAoqIDIsNTEyIGluY2lkZW50cyBpbiBRdWVlbnMKKiAyNjMgaW5jaWRlbnRzIGluIFN0YXRlbiBJc2xhbmQKClN0YXRlbiBJc2xhbmQgaGFkIHRoZSBsb3dlc3QgY291bnQgb2YgaW5jaWRlbnRzLCA4LDg2OCBsZXNzIHRoYW4gQnJvb2tseW4gaW4gZmFjdC4gSXQgaXMgaW1wb3J0YW50IHRvIG5vdGUgdGhhdCBTdGF0ZW4gSXNsYW5kIGFsc28gaGFzIGEgbXVjaCBzbWFsbGVyIHBvcHVsYXRpb24gdGhhdCBCcm9va2x5bi4gV2hpbGUgdGhlcmUgYXJlIHNvbWUgZGlmZmVyZW5jZXMgaW4gdGhlIGNvdW50IG9mIGluY2lkZW50cyBpbiBlYWNoIGJvcm91Z2gsIGZpZy4gMiAmIDMgc2hvd3MgdGhhdCB0aGUgbGVuZ3RoIG9mIHRpbWUgdGhhdCBpdCB0YWtlcyB0byBjbGVhbiBhbnkgb25lIGdyYWZmaXRpIGluY2lkZW50IGlzIGZhaXJseSBzaW1pbGFyIGZvcm0gYm9yb3VnaCB0byBib3JvdWdoLiBTdGF0ZW4gSXNsYW5kIGlzIHRoZSBvbmx5IGJvcm91Z2ggd2l0aCBtb3JlIGNhc2VzIGNsZWFuZWQgdGhhbiBub3QsIDY1JSBvZiB0aGUgaW5jaWRlbnRzIGhhdmUgYmVlbiBjbGVhbmVkLiA0NSUgb2YgaW5jaWRlbnRzIGluIHRoZSBCcm9ueCBoYXZlIGJlZW4gY2xlYW5lZCwgNDQlIGluIFF1ZWVucywgNDglIGluIEJyb29rbHluLCBhbmQgNDclIGluIE1hbmhhdHRhbiwgYWxsIG9mIHdoaWNoIGFyZSBzaW1pbGFyLiBCZWNhdXNlIFN0YXRlbiBJc2xhbmQgaGFzIGxlc3MgY2FzZXMgdG8gY2xlYW4gb3ZlcmFsbCwgaXQgd291bGQgbWFrZSBtb3JlIGluY2lkZW50cyBjb3VsZCBiZSBjbGVhbmVkLiBPbiBhdmVyYWdlLCBpdCBhbHNvIHRvb2sgdGhlIGxlYXN0IGFtb3VudCBvZiBkYXlzIHRvIGNsZWFuIGEgcmVwb3J0ZWQgaW5jaWRlbnQgaW4gU3RhdGVuIElzbGFuZCAoMTE3KSwgYW5kIHRoZSBtb3N0IGluIFF1ZWVucyAoMTM4KS4gQSAyMSBkYXkgZGlmZmVyZW5jZSBvZiBhdmVyYWdlIGNsZWFuaW5nIGluIHRoZXNlIGJvcm91Z2hzIGRvZXMgbm90IHJlcHJlc2VudCB0aGUgMiwyNDkgaW5jaWRlbnQgZGlmZmVyZW5jZSBiZXR3ZWVuIFF1ZWVucyBhbmQgU3RhdGVuIElzbGFuZCwgbGlrZWx5IGJlY2F1c2Ugb2YgR3JhZmZpdGkgRnJlZSBOWUMgYmVpbmcgYSBjaXR5LXdpZGUgdGFzayBmb3JjZS4gCgpGaWcgNC4gc2hvd3MgdGhlIGdlb2dyYXBoaWNhbCBkaXN0cmlidXRpb24gb2YgcmVwb3J0ZWQgZ3JhZmZpdGkgaW5jaWRlbnRzLCBhbmQgaXQgYmVjb21lcyBjbGVhciB0aGF0IHRoZXJlIGFyZSAiaG90IHNwb3RzIiBmb3IgaW5jaWRlbnRzIHRocm91Z2hvdXQgdGhlIGNpdHkuIFBhcnRpY3VsYXJseSwgdGhlIExvd2VyIEVhc3Qgc2lkZSBvZiBNYW5oYXR0YW4gYW5kIGFyb3VuZCBXaWxsaWFtc2J1cmcgYW5kIEJ1c2h3aWNrIGluIEJyb29rbHluLiBJIGFsc28gZm91bnQgaXQgaW50ZXJlc3RpbmcgdGhhdCBwb2ludHMgc2VlbSB0byBmb3JtIHN0cmFpZ2h0IGxpbmVzLCBsaWtlbHkgYWxvbmcgYnVzeSByb2Fkcy4gSW4gQnJvb2tseW4sIGRvdHMgYXBwZWFyIHRvIGZvcm0gRmxhdGJ1c2ggQXZlbnVlIGFuZCBMaW5kZW4gQmx2ZC4sIHR3byBidXN5IHN0cmVldHMuCgpBZnRlciBpbml0aWFsIGFuYWx5c2lzLCBJIGRlY2lkZWQgdG8gZm9jdXMgb24gTWFuaGF0dGFuLiBJIG1hZGUgdGhpcyBjaG9pY2UgdG8gc2ltcGxpZnkgZGF0YSwgYW5kIGJlY2F1c2UgTWFuaGF0dGFuLCBXYXNoaW5ndG9uIEhlaWdodHMgaW4gcGFydGljdWxhciwgd2FzIHRoZSBiaXJ0aCBwbGFjZSBvZiBncmFmZml0aSBhcyB3ZSBrbm93IGl0IHRvZGF5LiBGaWcuIDUgc2hvd2Nhc2VzIGEgc2ltcGxlIGV4cGxvcmF0aW9uIG9mIGFsbCBpbmNpZGVudHMgb2YgcmVwb3J0ZWQgZ3JhZmZpdGkgaW4gTWFuaGF0dGFuLCBhbmQgaWYgdGhleSBoYXZlIGJlZW4gY2xlYW5lZCBvciBub3QuIEFnYWluLCB0aGUgY2x1c3RlciBvbiB0aGUgTG93ZXIgRWFzdCBzaWRlIGlzIHByb21pbmVudCwgYWxvbmcgd2l0aCBzb21lIG90aGVyIHNtYWxsIGNsdXN0ZXJzLiBJIGZvdW5kIHRoaXMgaW50ZXJlc3RpbmcgYmVjYXVzZSBncmFmZml0aSBpbiBNYW5oYXR0YW4gYmVnYW4gd2l0aCBhcnRpc3RzIG5vdCBvbmx5IGluIFdhc2hpbmd0b24gSGVpZ2h0cywgYnV0IGFsc28gdGhlIExvd2VyIEVhc3QgU2lkZS4gCgpUaGVyZSB3YXMgYSByZWFsIHNlbnRpbWVudCB0aGF0IGdyYWZmaXRpIHdhcyBzdGFydGVkIGFzIGEgZm9ybSBvZiBleHByZXNzaW9uIGZvciBtYXJnaW5hbGl6ZWQgY29tbXVuaXRpZXMsIGxvb2tpbmcgdG8gaGF2ZSBhIHZvaWNlLiAqIkluIHRoZSBlbmQsIHRhZ2dpbmcgbXkgbmFtZSBub3Qgb25seSB1bmRlcnNjb3JlZCB0aGF0IOKAnEkgZGlkIGV4aXN04oCdIGluIGEgdG93biB0aGF0IGRpZG7igJl0IHZhbHVlIG9yIGV2ZW4gY29uc2lkZXIgbXkgZXhpc3RlbmNlLCBidXQgdGhhdCBJIGV4aXN0ZWQgb3V0c2lkZSBvZiBteSB2ZXJ5IG93biBtYXN0ZXJwaWVjZXMuIiogLS0gTEVFLCBwcm9taW5lbnQgZ3JhZmZpdGkgd3JpdGVyIGluIHRoZSAxOTcwJ3MuIFNvIEkgd2FudGVkIHRvIGV4cGxvcmUgaWYgdGhpcyB3YXMgc2ltaWxhciB0byB0b2RheS4gSSBjaG9zZSB0byB1c2UgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUgKE1ISSkgYXMgYSBmYWN0b3IgdG8gY29tcGFyZSBncmFmZml0aSBpbmNpZGVudHMgdG8uIEZpZy4gNyBzaG93cyBlYWNoIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEgKE5UQSkgaW4gTWFuaGF0dGFuLCBjb2xvcmVkIGJ5IGF2ZXJhZ2UgTUhJLiBXaGVuIG92ZXJsYWlkIHdpdGggcmVwb3J0ZWQgZ3JhZmZpdGkgaW5jaWRlbnRzLCBpdCBhcHBlYXJzIGFzIGlmIHRoZSBkYXJrZXIgYXJlYXMgKGxvd2VyIE1ISSkgaGF2ZSBtb3JlIHJlcG9ydGVkIGluY2lkZW50cy4gTGV0cyB1bnBhY2sgdGhpcy4gCgpGaWcuIDEwIHNob3dzIHVzIHRoYXQgQ2hpbmF0b3duIGFuZCBFYXN0IFZpbGxhZ2UgaGF2ZSB0aGUgdHdvIGhpZ2hlc3QgY291bnRzIG9mIGdyYWZmaXRpIGluY2lkZW50cywgYW5kIGFsc28gYW4gYXZlcmFnZSBtZWRpYW4gaG91c2Vob2xkIGluY29tZSBiZWxvdyB0aGF0IG9mIGFsbCBvZiBNYW5oYXR0YW4uIFRoZSA0IG5laWdoYm9yaG9vZHMgd2l0aCB0aGUgbGVhc3QgcmVwb3J0ZWQgaW5jaWRlbnRzIGFsbCBoYXZlIGFuIGF2ZXJhZ2UgbWVkaWFuIGhvdXNlaG9sZCBpbmNvbWUgYWJvdmUgdGhhdCBmb3IgdGhlIGF2ZXJhZ2Ugb2YgYWxsIG9mIE1hbmhhdHRhbi4gQmVjYXVzZSBncmFmZml0aSBpcyBub3QgYm91bmQgYnkgem9uaW5nIGxhd3Mgb3IgcmVudCBwcmljZXMgaW4gdGhlIHdheSB0aGF0IE1ISSBtaWdodCBiZSwgaXQgaXMgaW50ZXJlc3RpbmcgdG8gdGhpbmsgYWJvdXQgdGhlc2Ugc3RhdGlzdGljcyBnZW9ncmFwaGljYWxseSBhcyB3ZWxsLiBGb3IgaW5zdGFuY2UsIFNvSG8tVHJpQmVDYS1DaXZpYyBDZW50ZXItTGl0dGxlIEl0YWx5IE5UQSBoYXMgYW4gYXZlcmFnZSBNSEkgYWJvdmUgdGhlIHdob2xlIGNpdHkncywgYnV0IHN0aWxsIGhhcyBhIGxvdCBvZiByZXBvcnRlZCBncmFmZml0aSBpbmNpZGVudHMuIFRoaXMgTlRBIGlzIHZlcnkgY2xvc2UgZ2VvZ3JhcGhpY2FsbHkgdG8gRWFzdCBWaWxsYWdlIGFuZCBDaGluYXRvd24sIGFuZCB0aGVyZSBpcyBsaWtlbHkgc29tZSBzcGlsbCBvdmVyIGZyb20gdGhlc2UgbmVpZ2hib3Job29kcyB0byB0aGUgU29Iby1UcmlCZUNhLUNpdmljIENlbnRlci1MaXR0bGUgSXRhbHkgTlRBLiBJbiBmYWN0LCBsb29raW5nIGF0IEZpZy4gNywgaXQgc2hvd3MgdGhhdCB0aGUgcmVwb3J0ZWQgaW5jaWRlbnRzIG9mIEdyYWZmaXRpIGFyZSBsb2NhdGVkIG9uIHRoZSB3ZXN0IHNpZGUgb2YgdGhpcyBOVEEsIHdoaWNoIGJvcmRlcnMgRWFzdCBWaWxsYWdlIGFuZCBDaGluYXRvd24uIAoKIyMjIE5leHQgU3RlcHM6ClRoZXJlIGlzIHN0aWxsIGEgbG90IHRoYXQgY2FuIGJlIHVuY292ZXJlZCBhYm91dCBncmFmZml0aSBpbiBOZXcgWW9yayBDaXR5IHVzaW5nIGRhdGEgYWxvbmUuIEFmdGVyIHRoaXMgaW5pdGlhbCByZXNlYXJjaCwgSSBhbSB0aGlua2luZyBhYm91dCBtYWpvciAzIHdheXMgdGhpcyBwcm9qZWN0IGNvdWxkIGJlIGV4cGFuZGVkIGluIHRoZSBmdXR1cmUuCgoxLiBJbiBkZXB0aCBhbmFseXNpcyBmb3IgZWFjaCBib3JvdWdoCjIuIEV4cGxvcmUgTlRBIGRlbW9ncmFwaGljcyBmdXJ0aGVyCiAgICArIENlbnN1cyBkYXRhIGxvb2tpbmcgYXQgcmFjZSwgYWdlLCBvciBwcm9wZXJ0eSB0eXBlcwogICAgKyBpcyB0aGVyZSBhIGJldHRlciBncm91cGluZyB0aGFuIE5UQT8KICAgICsgV2hhdCBpbmZyYXN0cnVjdHVyZSBpbmZsdWVuY2VzIGdyYWZmaXRpPyAodHJhaW5zLCB3YXJlaG91c2VzKQozLiBVbmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcmVzZW50IGFuZCBwYXN0IGdyYWZmaXRpCiAgICArIERvIGdyYWZmaXRpICJob3Qgc3BvdHMiIHRvZGF5IHJlZmxlY3QgcG9wdWxhciBzcG90cyBmcm9tIHRoZSBwYXN0PwogICAgKyBXaGF0IG90aGVyIGRhdGEgc2V0cyBjYW4gaGVscCB0ZWxsIHRoaXMgc3RvcnkgKDMxMSBDYWxscykKICAKIyMjIEFwZW5kaXg6IApNeSBkYXRhIGNhbWUgZnJvbSAzIG1haW4gc291cmNlczogCgoqIFtOWUMgT3BlbiBEYXRhXShodHRwczovL2RhdGEuY2l0eW9mbmV3eW9yay51cy9DaXR5LUdvdmVybm1lbnQvRFNOWS1HcmFmZml0aS1UcmFja2luZy9ncHdkLW5wYXIpCiAgKyBUaGlzIGRhdGEgc2V0IHByb3ZpZGVkIHRoZSBpbmZvcm1hdGlvbiBhYm91dCBncmFmZml0aSBpbiBOWUMsIGl0IGNvbnRhaW5lZCBrZXkgaW5mb3JtYXRpb24gYWJvdXQgZWFjaCByZXBvcnRlZCBpbmNpZGVudCBzdWNoIGFzOiBCb3JvdWdoIGFuIGV2ZW50IG9jY3VycmVkIGluLCBkYXRlIGl0IHdhcyByZXBvcnRlZCwgYW5kIGlmIGl0IHdhcyBjbGVhbmVkLCBhIGRhdGUgZm9yIHRoYXQsIHRoZSBOVEEgZWFjaCBldmVudCBvY2N1cnJlZCBpbiwgYW5kIHRoZSBwb2ludCBvbiBhIG1hcCB3aGVyZSBpdCBvY2N1cnJlZC4gCiAgKyBJIG1hbmlwdWxhdGVkIHRoaXMgZGF0YSBzZXQgdG8gZmlndXJlIG91dCBpZiBhbiBpbmNpZGVudCB3YXMgY2xlYW5lZCwgcGVyY2VudCBvZiBjbGVhbmVkIGluY2lkZW50cyAoYnkgYm9yb3VnaCBhbmQgTlRBKSwgbGVuZ3RoIG9mIHRpbWUgaXQgdG9vayB0byBjbGVhbiBhbiBpbmNpZGVudCBvbmNlIGl0IHdhcyByZXBvcnRlZCwgY291bnQgb2YgaW5jaWRlbnRzIHBlciBib3JvdWdoLCBjZW5zdXMgdHJhY3QgYW5kIE5UQSwgYW5kIG90aGVyIGluZm9ybWF0aW9uIGFib3V0IGdyYWZmaXRpIGluIE5ldyBZb3JrIENpdHkuCiAgKyBHcmFmZml0aS1GcmVlIE5ZQyB3YXMgc3RhcnRlZCBpbiAxOTk5LCBhbmQgdGhpcyBkYXRhIHNldCB3YXMgY3JlYXRlZCBpbiAyMDEzLCBidXQgdGhlcmUgYXJlIG9ubHkgcG9pbnRzIGF2YWlsYWJsZSBmcm9tIEphbnVhcnkgMTAsIDIwMTkgdG8gSmFudWFyeSA5IDIwMjAuIEl0IHdvdWxkIGJlIGludGVyZXN0aW5nIHRvIHNlZSBtb3JlIHRoYW4gb25lIHllYXIgKHRoZXJlIHdlcmUgYSB0b24gb2YgcmVwb3J0ZWQgaW5jaWRlbnRzIGZvciB0aGlzIHllYXIhKS4gVGhpcyBkYXRhIHNldCBpcyBtYW5hZ2VkIGJ5IHRoZSBEZXBhcnRtZW50IG9mIFNhbml0aWF0aW9uLiAKICArIFRoaXMgZGF0YSBzZXQgaXMgYmFzZWQgb24gKnJlcG9ydGVkKiBpbmNpZGVudHMsIG1vc3RseSB0aHJvdWdoIDMxMSBjYWxscy4gTm90IG9ubHkgZG9lcyB0aGlzIG5lZWQgdG8gYmUgdGFrZW4gaW50byBjb25zaWRlcmF0aW9uIGZvciB0aGlzIHJlcG9ydCwgYnV0LCBpdCB3b3VsZCBhbHNvIGJlIGludGVyZXN0aW5nIHRvIHVuY292ZXIgbW9yZSBhYm91dCB0aGUgcmVwcmludCBvZiBpbmNpZGVudHMuIFdobyBpcyBkb2luZyB0aGUgcmVwb3J0aW5nLCBkbyB0aGV5IGxpdmUgaW4gdGhlIHNhbWUgbmVpZ2hib3Job29kIGFzIHRoZSBpbmNpZGVudCB0aGV5IGFyZSByZXBvcnRpbmcsCiAgaXMgaXQgc3RyaWN0bHkgMzExIGNhbGxzPwoKKiBbQnl0ZXMgb2YgdGhlIEJpZyBBcHBsZV0oaHR0cHM6Ly93d3cxLm55Yy5nb3Yvc2l0ZS9wbGFubmluZy9kYXRhLW1hcHMvb3Blbi1kYXRhL2R3bi1hY3MtbnRhLnBhZ2UpIAogICsgQnl0ZXMgb2YgdGhlIEJpZyBBcHBsZSBpcyBtYW5hZ2VkIGJ5IE5ZQyBwbGFubmluZyB0byBjcmVhdGUgZnJlZSBhbmQgYWNjZXNzaWJsZSBkYXRhIGFib3V0IE5ZQy4gCiAgKyBJIHVzZWQgdGhpcyBkYXRhIHRvIG1hbmlwdWxhdGUgb3RoZXIgZGF0YSBhdCB0aGUgTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYSAoTlRBKSBsZXZlbCBpbiBOZXcgWW9yayBDaXR5LiBOVEEgaXMgZ2VvZ3JhcGhpY2FsIGNhdGVnb3J5IHNwZWNpZmljIHRvIE5ZQyBzbyBpdCBpcyBub3QgaW5jbHVkZWQgaW4gcmF3IGNlbnN1cyBkYXRhLiBUaGV5IGFyZSBhcmVhcyBkaXZpZGVkIGJ5IENpdHkgSGFsbCBkZXBlbmRpbmcgb24gZGVjZW5uaWFsIGNlbnN1cyB0cmFjdCBpbmZvcm1hdGlvbi4gCiAgKyBOWUMgUGxhbm5pbmcgYW5kIEJ5dGVzIG9mIHRoZSBCaWcgQXBwbGUgY3JlYXRlZCBhIGRhdGEgc2V0IGZvciBpbmZvcm1hdGlvbiBmcm9tIHRoZSBjZW5zdXMgdGhhdCBpcyBkaXZpZGVkIGF0IHRoZSBOVEEgbGV2ZWwuCiAgKyBJIGFsc28gdXNlZCB0aGlzIGRhdGEgdG8gY3JlYXRlIG91dGxpbmVzIG9mIGdlb2dyYXBoaWVzIHRoYXQgd2VyZSBtYXBwZWQsIGFzIHRoZSBkYXRhIHNldCBpbmNsdWRlZCBnZW9tZXRyaWVzLiAKCiogQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSAoQUNTKQogICsgSSB1c2VkIHRoZSA1IHllYXIgQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSB0byBleHBsb3JlIGRlbW9ncmFwaGljcyBvZiBOZXcgWW9yaywgYW5kIHRvIG1hcCBhdCB0aGUgY2Vuc3VzIHRyYWN0IGxldmVsLiAKICArIEJlY2F1c2UgMjAyMCBjZW5zdXMgZGF0YSBoYXMgbm90IGJlZW4gZnVsbHkgcmVsZWFzZWQgeWV0LCBhbmQgd2UgYXJlIG5vdyBhdCB0aGUgZW5kIG9mIHRoZSAxMCB5ZWFyIGdhcCBiZXR3ZWVuIGNlbnN1c2VzLCBJIGRlY2lkZWQgdG8gdXNlIG1vcmUgcmVjZW50IGluZm8gdGhhdCB0aGUgQUNTIHByb3ZpZGVzLiBUaGUgQUNTIGFsc28gYW5zd2VycyBtb3JlIGRldGFpbGVkIHF1ZXN0aW9ucyB0aGVuIHRoZSAxMCB5ZWFyIGNlbnN1cyBkb2VzLiAKICArIEl0IGlzIGltcG9ydGFudCB0byBub3RlIHRoYXQgdGhlIEFDUyBpcyBhbiBlc3RpbWF0aW9uLCBub3QgZXZlcnkgY2l0aXplbiBpcyBjb250YWN0ZWQgZm9yIGV2ZXJ5IHN1cnZleSwgYW5kIGlzIHRoZXJlZm9yZSBub3QgYXMgYWNjdXJhdGUgYXQgdGhlIDEwLXlyIGNlbnN1cy4gCgoKCgoKCgoK