Jordan Packer

December 15, 2021


Research Overview

The Gowanus Neighborhood Plan is an 82-block redevelopment of the area surrounding the Gowanus Canal in Brooklyn, New York. The plan proposes increased residential, industrial, and commercial development for the region. After over a decade of writing, planning, and engaging with the community, the Gowanus Neighborhood Plan was approved by the City Planning Commission in the spring of 2021. Shortly after, the New York City Council passed a new law written by the Office of the Public Advocate, Intro 1572-2019-B, that requires “Racial Equity Reports” for future land use changes as part of the Uniform Land Use Review Process (ULURP). As described on the Public Advocate’s website, this law now requires “citywide equitable development data tools, which would be used to study and assess the potential racial and ethnic impact of most proposed rezonings on the neighborhood in question.” The Gowanus Neighborhood Plan is the first rezoning project to have its own Racial Equity Report under this law. As the first of its kind, it presents a unique opportunity for critical analysis.

Through quantitative and spatial analyses, the Gowanus Racial Equity Report contextualizes Gowanus as a white and wealthy neighborhood that will benefit from redevelopment, because, as it claims, the rezoning will increase racial diversity in the area.

To understand the Gowanus Racial Equity Report’s claims, I counter-analyze Gowanus demographic data using the 2020 Census. I select three different boundaries for Gowanus in my analyses: Community District Tabulation Area, Neighborhood Tabulation Area, and selected Census tracts.

Research Question: How does changing the boundaries of Gowanus yield different demographic contexts for the rezoning?

Context

In many of their analyses, the Racial Equity Report uses a large territory of Northwest Brooklyn, combining Community Board 2 and Community Board 6. However, Gowanus itself is relatively small and entirely located within the bounds of Community Board 6. The rezoning territory does overlap with Community Board 2, but only for half of a block. While combining the two community boards yields a lower margin of error in quantitative analyses, as reasoned in the report, it dilutes the central affected population of Gowanus with neighboring areas. In this way, the selected boundaries play an important role in shaping the demographic context of the Racial Equity Report.

While the new law enforcing the creation of a Racial Equity Report for land use changes has good intentions, quantitative data can be manipulated and are not objective facts. I want to open a conversation about the objectivity of quantitative data by analyzing demographic data in Gowanus within three alternative boundaries.

Three Boundaries of Gowanus

To investigate the boundaries used in the Racial Equity Report, I selected three alternative boundaries for Gowanus: Community District Tabulation Area (Community Board), Neighborhood Tabulation Area, and hand-selected census tracts that match with the Google maps definition of Gowanus. Paying attention to the placement of Gowanus Canal within these boundaries helps differentiate their sizes and shapes.

  • The Community Board level is the largest geographic size, including Park Slope, Red Hook, Gowanus, Carroll Gardens, and Cobble Hill. Moving forward, I use Community District Tabulation Area and Community Board interchangeably, as well as describe this boundary and larger ones as “Greater Gowanus.”

  • The Neighborhood Tabulation Area is slightly smaller and includes Cobble Hill, Red Hook, Carroll Gardens, and Gowanus (excluding Park Slope).

  • The smallest boundary is a hand-selection of 2020 census tracts that align with Google maps and common understandings of Gowanus: Census Tracts 77, 75, 71, 127, 119, 121, and 117. I sometimes refer to this boundary as “Gowanus proper.”

Community District Tabulation Area

Neighborhood Tabulation Area

Selected Census Tracts

Gowanus Neighborhood Plan Map

Finally, to contextualize these three alternative boundaries, below is a map of the Gowanus Neighborhood Plan rezoning territory, which most closely resembles the selected Census tracts boundary.

Data Sources and Analysis

My analyses rely on the U.S. Decennial Census 2020 demographic data. I use this data to show the population within the Greater Gowanus area as recently and precisely as possible.

The Racial Equity Report does not use the 2020 Census and instead uses data from the American Community Survey (ACS) to observe and analyze demographic, housing, and income trends. However, for smaller areas, using ACS data yields a higher margin of error. While the ACS is an estimate, the Decennial Census is a count of all residents. Because of this, the Decennial Census can be used for smaller territories. For this reason, I think it is important to use Census data for population demographics.


Results

Total Population

In the following bar chart, the population differences between the three boundaries I selected are shown.

  • The Community Board level has the largest geographic size and highest population: 168,648 in 2020.
  • The Neighborhood Tabulation Area is smaller, with a population of 109,775 in 2020.
  • The hand-selection of census tracts has a population of 24,956 in 2020.

All three boundaries grew from 2000 to 2020, but the Community Board and Neighborhood Tabulation Area have seen larger increases in population than Gowanus proper.

White Population, 2020 (3 Boundaries)

Here I explore the three boundaries to spatially visualize the population of white residents in Greater Gowanus in 2020. As is noticeable from the Community District Tabulation map, many census tracts of the neighborhood Park Slope (at the bottom right of the map) are over 70% white. When I narrow the boundary to Neighborhood Tabulation Area, the Park Slope region is no longer included. At the selected tract level, there is a more granular view of whiteness in Gowanus.

Note: In my spatial visualizations, I show the boundary of the Community Board with an orange outline and Neighborhood Tabulation Area with a red outline.

Minoritized Populations Over Time

Next, I looked at the population of minoritized communities at the largest boundary over time. I ran these analyses for two reasons: 1) to see if historically minoritized populations have been pushed out of the Gowanus area in the last two decades, and 2) to understand the longevity of communities of color in Gowanus. I start here with the population of Black residents.

Black Population, 2020 & 2000 (in Community District Tabulation Area)

Over the last twenty years, the Black population in Gowanus has remained stable. In both 2000 and 2020, Black people make up over 30% of the population in Census Tracts 71 & 127, and over 40% of Census Tract 85.

Hispanic / Latino Population, 2020 & 2000 (in Community District Tabulation Area)

Examining the Hispanic/Latino population over the last twenty years reveals a shocking change. In 2020, only two Census tracts have over 40% Hispanic/Latino people. In 2000, there were over 10. This is a sign of displacement and indicates that Greater Gowanus was a primarily Hispanic/Latino community in 2000.

Comparing Representativeness: Demographics Across the Three Boundaries

In the following bar charts, I compare Community Board, Neighborhood Tabulation Area, and Selected Tracts across four demographic populations: White, Non-White, Hispanic/Latino, and Black to check for “representativeness.” If the three boundaries were representative of Gowanus and similar to one another, we would expect to see the same percentages (height) across each boundary (column). These would be boring bar charts with equal-sized rectangles. However, that is not the case. I describe these percentages in detail below.

Beginning with the white population, there is a higher percentage of white residents at the community board level (59% in 2020) and a lower percentage in the selected tracts (51%). 51% is a very slight majority of Gowanus proper. The neighborhood tabulation area is more similar to the community board than to the selected tracts.

For Non-White residents, there is nearly a 10% percentage difference between the community board boundary and the tract level, 34.5% compared to 44.1% in 2020. This difference is even starker in 2000, 45.2% compared to 59.5% - a difference of 14.3%. Again the neighborhood tabulation area is more similar to the community board than to the selected tracts.

Strikingly, the Hispanic/Latino population within the selected tracts is 6.6% higher in 2020, and over 14% higher in 2000. In addition, this bar chart makes clear the significant drop in the Hispanic/Latino population from 2000 to 2020. At the selected Census tract level, the Hispanic/Latino population dropped from 41% to 23% over twenty years signaling trends of broader displacement. These patterns of displacement are clear across all three boundaries.

Finally, the Black population changed least across the boundaries, but was still showed a difference between the Community Board and Neighborhood Tabulation Area than the Census Tracts. In 2020, Community Board was 9.6% Black, Neighborhood Tabulation Area was 9.26% and the selected tracts were the highest at 12.6%.

Discussion

My counter-analysis of the Gowanus Racial Equity Report’s demographic data demonstrates that Gowanus is not nearly as white as the Racial Equity Report claims. The Racial Equity Report inflates white residents and erases residents of color in their demographic depiction of Gowanus. By using larger boundaries that lump in neighboring communities, Gowanus is painted as more white than it really is. In actuality, Gowanus itself is 51% white and by claiming it as a white community, the other 49% of the population is actively erased. Unfortunately, even the media has bought in to this pervasive narrative of Gowanus as a white community, as can be seen in recent publications from the New York Times and City Limits op-eds by City Council Member and rezoning proponent, Brad Lander.

Looking at longitudinal data, I discovered the alarming mass displacement of Hispanic/Latino people from Greater Gowanus. I believe this is a result of the 4th Avenue Park Slope rezoning in the early 2000s and should serve as a red flag for upcoming rezonings in the area.

While the implementation of required Racial Equity Reports through Intro 1572-2019-B legislation has good intentions, and surely can be utilized to analyze the effects of land use change applications in New York City, Racial Equity Reports are not objective facts and can be manipulated to tell a specific story. As you can see through my analysis, the Racial Equity Report curates Gowanus as a white and wealthy community that will benefit from redevelopment, because it will create more diversity. This framing overlooks the existing people of color that live in Gowanus, and in fact, erases their existence through inflating the percentage of white people in the area.

Next Steps

In collaboration with Jiray Avedisian, who counter-analyzed income and housing data presented by the Gowanus Racial Equity Report, we hope to present a joint counter-analysis to the general public and the NYC City Council. We have compiled recommendations for the Racial Equity Report’s authors and include a robust critical analysis of the Racial Equity Report (of which this quantitative analysis is just a small part). We hope to inspire community members to collect counter-data and publish their own racial equity reports, using a variety of data types: spatial, qualitative, and participatory, for example. Our project was selected as a presentation for the NYC Open Data Week 2022 conference.

In future iterations of this project:

  • In this report, I focus on trying new boundaries for Gowanus. In a future version, I would like to re-create the exact boundaries used in the Racial Equity Report and place them side by side with the selected tracts boundary. Since combining Community Board 6 and Community Board 2 is even larger than the scales I used, I imagine the results will be similar to mine, if not more striking.

  • I would like to publish a separate version of this project that is specifically made to be accessible to someone with limited data or R experience, enabling them to reproduce our results and similar results for their own neighborhood.

  • I would also like to include statistical analyses that show if the differences in population between the community board and selected tracts are statistically significant.


Methods Appendix

Data:

Population demographics: U.S. Census Bureau, Population by Race and Ethnicity, 2020 and 2000 Census retrieved November 29, 2021 using tidycensus R package:

  • Total Population
  • Total Non-Hispanic White Population
  • Total Non-Hispanic Black Population
  • Total Non-Hispanic Asian Population
  • Total Hispanic/Latinx Population
  • Other Population

Shape files:

Community District Tabulation Areas (CDTAs) NYC Open Data, Community District Tabulation Areas 2020 retrieved November 29, 2021 using NYC Open Data shape file and imported with sf R package.

Neighborhood Tabulation Areas (NTAs) NYC Open Data, Neighborhood Tabulation Areas 2020 retrieved November 29, 2021 using NYC Open Data shape file and imported with sf R package.

Selected Census Tracts NYC Open Data, Kings County, NY Census Tracts 2020: 77, 75, 71, 127, 119, 121, 117 retrieved November 29, 2021 using NYC Open Data shape file and imported with sf R package.

Methods:

Total “Other” Population is calculated as a sum of Census categories:

  • Total “American Indian and Alaska Native”
  • Total “Native Hawaiian and Other Pacific Islander”
  • Total “Some Other Race alone”

Total Non-White Population is calculated as a sum of Census categories:

  • Total Non-Hispanic Black
  • Total Non-Hispanic Asian
  • Total Hispanic/Latino
  • Total Other

Demographic proportions are calculated as the Total demographic population, such as Total Non-Hispanic White, divided by Total Population. These proportions were created for both 2020 and 2000 Census data.

Summary statistics for the bar charts were created in Excel by using writexl R package. I collated the demographic proportion data by census tract into the three boundaries discussed for 2000 and 2020 data. I then created the averages for each demographic category in Excel and re-imported the data into R through readxl R package.

Note on analysis

I pulled data from every demographic group collected by the Census, but I decided to focus on the four most frequent demographic groups: White, Black, Hispanic/Latino, and an aggregated “Non-White” category. Data on the category described by the Census as “other,” as well as “One or more races,” and Asian populations can be calculated in the same fashion as my analyses.

Sources

This project was conducted by Jordan Packer for Design and Urban Ecologies Methods 1, a course within the Design and Urban Ecologies M.S. program at the Parsons School of Design - The New School.

LS0tCnRpdGxlOiAiQSBDb3VudGVyLUFuYWx5c2lzIG9mIERlbW9ncmFwaGljIERhdGEgUHJlc2VudGVkIGJ5IHRoZSBHb3dhbnVzIFJhY2lhbCBFcXVpdHkgUmVwb3J0IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc0JwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KIyMjIEpvcmRhbiBQYWNrZXIKIyMjIyMgRGVjZW1iZXIgMTUsIDIwMjEKCjxocj48YnI+CgojIyBSZXNlYXJjaCBPdmVydmlldwpUaGUgW0dvd2FudXMgTmVpZ2hib3Job29kIFBsYW5dKGh0dHBzOi8vd3d3MS5ueWMuZ292L3NpdGUvcGxhbm5pbmcvcGxhbnMvZ293YW51cy9nb3dhbnVzLWZyYW1ld29yay5wYWdlKSBpcyBhbiA4Mi1ibG9jayByZWRldmVsb3BtZW50IG9mIHRoZSBhcmVhIHN1cnJvdW5kaW5nIHRoZSBHb3dhbnVzIENhbmFsIGluIEJyb29rbHluLCBOZXcgWW9yay4gVGhlIHBsYW4gcHJvcG9zZXMgaW5jcmVhc2VkIHJlc2lkZW50aWFsLCBpbmR1c3RyaWFsLCBhbmQgY29tbWVyY2lhbCBkZXZlbG9wbWVudCBmb3IgdGhlIHJlZ2lvbi4gQWZ0ZXIgb3ZlciBhIGRlY2FkZSBvZiB3cml0aW5nLCBwbGFubmluZywgYW5kIGVuZ2FnaW5nIHdpdGggdGhlIGNvbW11bml0eSwgdGhlIEdvd2FudXMgTmVpZ2hib3Job29kIFBsYW4gd2FzIGFwcHJvdmVkIGJ5IHRoZSBDaXR5IFBsYW5uaW5nIENvbW1pc3Npb24gaW4gdGhlIHNwcmluZyBvZiAyMDIxLiBTaG9ydGx5IGFmdGVyLCB0aGUgTmV3IFlvcmsgQ2l0eSBDb3VuY2lsIHBhc3NlZCBhIG5ldyBsYXcgd3JpdHRlbiBieSB0aGUgT2ZmaWNlIG9mIHRoZSBQdWJsaWMgQWR2b2NhdGUsIFtJbnRybyAxNTcyLTIwMTktQl0oaHR0cHM6Ly9hZHZvY2F0ZS5ueWMuZ292L3ByZXNzL255Yy1jb3VuY2lsLXZvdGUtcmFjaWFsLWltcGFjdC1zdHVkeS1sZWdpc2xhdGlvbi1haW1lZC1maWdodGluZy1nZW50cmlmaWNhdGlvbi1mdW5kYW1lbnRhbGx5LWNoYW5naW5nLWxhbmQtdXNlLyksIHRoYXQgcmVxdWlyZXMgIlJhY2lhbCBFcXVpdHkgUmVwb3J0cyIgZm9yIGZ1dHVyZSBsYW5kIHVzZSBjaGFuZ2VzIGFzIHBhcnQgb2YgdGhlIFVuaWZvcm0gTGFuZCBVc2UgUmV2aWV3IFByb2Nlc3MgKFVMVVJQKS4gQXMgZGVzY3JpYmVkIG9uIHRoZSBQdWJsaWMgQWR2b2NhdGUncyBbd2Vic2l0ZV0oaHR0cHM6Ly9hZHZvY2F0ZS5ueWMuZ292L3ByZXNzL255Yy1jb3VuY2lsLXZvdGUtcmFjaWFsLWltcGFjdC1zdHVkeS1sZWdpc2xhdGlvbi1haW1lZC1maWdodGluZy1nZW50cmlmaWNhdGlvbi1mdW5kYW1lbnRhbGx5LWNoYW5naW5nLWxhbmQtdXNlLyksIHRoaXMgbGF3IG5vdyByZXF1aXJlcyAiY2l0eXdpZGUgZXF1aXRhYmxlIGRldmVsb3BtZW50IGRhdGEgdG9vbHMsIHdoaWNoIHdvdWxkIGJlIHVzZWQgdG8gc3R1ZHkgYW5kIGFzc2VzcyB0aGUgcG90ZW50aWFsIHJhY2lhbCBhbmQgZXRobmljIGltcGFjdCBvZiBtb3N0IHByb3Bvc2VkIHJlem9uaW5ncyBvbiB0aGUgbmVpZ2hib3Job29kIGluIHF1ZXN0aW9uLiIgVGhlIEdvd2FudXMgTmVpZ2hib3Job29kIFBsYW4gaXMgdGhlIGZpcnN0IHJlem9uaW5nIHByb2plY3QgdG8gaGF2ZSBpdHMgb3duIFJhY2lhbCBFcXVpdHkgUmVwb3J0IHVuZGVyIHRoaXMgbGF3LiBBcyB0aGUgZmlyc3Qgb2YgaXRzIGtpbmQsIGl0IHByZXNlbnRzIGEgdW5pcXVlIG9wcG9ydHVuaXR5IGZvciBjcml0aWNhbCBhbmFseXNpcy4gCgpUaHJvdWdoIHF1YW50aXRhdGl2ZSBhbmQgc3BhdGlhbCBhbmFseXNlcywgPGI+IHRoZSBbR293YW51cyBSYWNpYWwgRXF1aXR5IFJlcG9ydF0oaHR0cHM6Ly9jb3VuY2lsLm55Yy5nb3YvbGFuZC11c2UvcGxhbnMvZ293YW51cy1uZWlnaGJvcmhvb2QtcGxhbi1yYWNpYWwtZXF1aXR5LXJlcG9ydC1vbi1ob3VzaW5nLWFuZC1vcHBvcnR1bml0eS8pIGNvbnRleHR1YWxpemVzIEdvd2FudXMgYXMgYSB3aGl0ZSBhbmQgd2VhbHRoeSBuZWlnaGJvcmhvb2QgdGhhdCB3aWxsIGJlbmVmaXQgZnJvbSByZWRldmVsb3BtZW50LCBiZWNhdXNlLCBhcyBpdCBjbGFpbXMsIHRoZSByZXpvbmluZyB3aWxsIGluY3JlYXNlIHJhY2lhbCBkaXZlcnNpdHkgaW4gdGhlIGFyZWEuIDwvYj4KPGJyPjxicj4KVG8gdW5kZXJzdGFuZCB0aGUgR293YW51cyBSYWNpYWwgRXF1aXR5IFJlcG9ydCdzIGNsYWltcywgSSBjb3VudGVyLWFuYWx5emUgR293YW51cyBkZW1vZ3JhcGhpYyBkYXRhIHVzaW5nIHRoZSAyMDIwIENlbnN1cy4gSSBzZWxlY3QgdGhyZWUgZGlmZmVyZW50IGJvdW5kYXJpZXMgZm9yIEdvd2FudXMgaW4gbXkgYW5hbHlzZXM6IENvbW11bml0eSBEaXN0cmljdCBUYWJ1bGF0aW9uIEFyZWEsIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEsIGFuZCBzZWxlY3RlZCBDZW5zdXMgdHJhY3RzLiAKClJlc2VhcmNoIFF1ZXN0aW9uOgo8Yj5Ib3cgZG9lcyBjaGFuZ2luZyB0aGUgYm91bmRhcmllcyBvZiBHb3dhbnVzIHlpZWxkIGRpZmZlcmVudCBkZW1vZ3JhcGhpYyBjb250ZXh0cyBmb3IgdGhlIHJlem9uaW5nPzwvYj4KCgojIyBDb250ZXh0IApJbiBtYW55IG9mIHRoZWlyIGFuYWx5c2VzLCB0aGUgUmFjaWFsIEVxdWl0eSBSZXBvcnQgdXNlcyBhIGxhcmdlIHRlcnJpdG9yeSBvZiBOb3J0aHdlc3QgQnJvb2tseW4sIGNvbWJpbmluZyBDb21tdW5pdHkgQm9hcmQgMiBhbmQgQ29tbXVuaXR5IEJvYXJkIDYuIEhvd2V2ZXIsIEdvd2FudXMgaXRzZWxmIGlzIHJlbGF0aXZlbHkgc21hbGwgYW5kIGVudGlyZWx5IGxvY2F0ZWQgd2l0aGluIHRoZSBib3VuZHMgb2YgQ29tbXVuaXR5IEJvYXJkIDYuIFRoZSByZXpvbmluZyB0ZXJyaXRvcnkgZG9lcyBvdmVybGFwIHdpdGggQ29tbXVuaXR5IEJvYXJkIDIsIGJ1dCBvbmx5IGZvciBoYWxmIG9mIGEgYmxvY2suIFdoaWxlIGNvbWJpbmluZyB0aGUgdHdvIGNvbW11bml0eSBib2FyZHMgeWllbGRzIGEgbG93ZXIgbWFyZ2luIG9mIGVycm9yIGluIHF1YW50aXRhdGl2ZSBhbmFseXNlcywgYXMgcmVhc29uZWQgaW4gdGhlIHJlcG9ydCwgaXQgZGlsdXRlcyB0aGUgY2VudHJhbCBhZmZlY3RlZCBwb3B1bGF0aW9uIG9mIEdvd2FudXMgd2l0aCBuZWlnaGJvcmluZyBhcmVhcy4gSW4gdGhpcyB3YXksIHRoZSBzZWxlY3RlZCBib3VuZGFyaWVzIHBsYXkgYW4gaW1wb3J0YW50IHJvbGUgaW4gc2hhcGluZyB0aGUgZGVtb2dyYXBoaWMgY29udGV4dCBvZiB0aGUgUmFjaWFsIEVxdWl0eSBSZXBvcnQuCgpXaGlsZSB0aGUgbmV3IGxhdyBlbmZvcmNpbmcgdGhlIGNyZWF0aW9uIG9mIGEgUmFjaWFsIEVxdWl0eSBSZXBvcnQgZm9yIGxhbmQgdXNlIGNoYW5nZXMgaGFzIGdvb2QgaW50ZW50aW9ucywgcXVhbnRpdGF0aXZlIGRhdGEgY2FuIGJlIG1hbmlwdWxhdGVkIGFuZCBhcmUgbm90IG9iamVjdGl2ZSBmYWN0cy4gSSB3YW50IHRvIG9wZW4gYSBjb252ZXJzYXRpb24gYWJvdXQgdGhlIG9iamVjdGl2aXR5IG9mIHF1YW50aXRhdGl2ZSBkYXRhIGJ5IGFuYWx5emluZyBkZW1vZ3JhcGhpYyBkYXRhIGluIEdvd2FudXMgd2l0aGluIHRocmVlIGFsdGVybmF0aXZlIGJvdW5kYXJpZXMuIAoKIyMjIFRocmVlIEJvdW5kYXJpZXMgb2YgR293YW51cwpUbyBpbnZlc3RpZ2F0ZSB0aGUgYm91bmRhcmllcyB1c2VkIGluIHRoZSBSYWNpYWwgRXF1aXR5IFJlcG9ydCwgSSBzZWxlY3RlZCB0aHJlZSBhbHRlcm5hdGl2ZSBib3VuZGFyaWVzIGZvciBHb3dhbnVzOiBDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhIChDb21tdW5pdHkgQm9hcmQpLCBOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhLCBhbmQgaGFuZC1zZWxlY3RlZCBjZW5zdXMgdHJhY3RzIHRoYXQgbWF0Y2ggd2l0aCB0aGUgR29vZ2xlIG1hcHMgZGVmaW5pdGlvbiBvZiBHb3dhbnVzLiBQYXlpbmcgYXR0ZW50aW9uIHRvIHRoZSBwbGFjZW1lbnQgb2YgR293YW51cyBDYW5hbCB3aXRoaW4gdGhlc2UgYm91bmRhcmllcyBoZWxwcyBkaWZmZXJlbnRpYXRlIHRoZWlyIHNpemVzIGFuZCBzaGFwZXMuCgoqIFRoZSA8Yj5Db21tdW5pdHkgQm9hcmQ8L2I+IGxldmVsIGlzIHRoZSBsYXJnZXN0IGdlb2dyYXBoaWMgc2l6ZSwgaW5jbHVkaW5nIFBhcmsgU2xvcGUsIFJlZCBIb29rLCBHb3dhbnVzLCBDYXJyb2xsIEdhcmRlbnMsIGFuZCBDb2JibGUgSGlsbC4gTW92aW5nIGZvcndhcmQsIEkgdXNlIENvbW11bml0eSBEaXN0cmljdCBUYWJ1bGF0aW9uIEFyZWEgYW5kIENvbW11bml0eSBCb2FyZCBpbnRlcmNoYW5nZWFibHksIGFzIHdlbGwgYXMgZGVzY3JpYmUgdGhpcyBib3VuZGFyeSBhbmQgbGFyZ2VyIG9uZXMgYXMgIkdyZWF0ZXIgR293YW51cy4iCgoqIFRoZSA8Yj5OZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhPC9iPiBpcyBzbGlnaHRseSBzbWFsbGVyIGFuZCBpbmNsdWRlcyBDb2JibGUgSGlsbCwgUmVkIEhvb2ssIENhcnJvbGwgR2FyZGVucywgYW5kIEdvd2FudXMgKGV4Y2x1ZGluZyBQYXJrIFNsb3BlKS4KCiogVGhlIHNtYWxsZXN0IGJvdW5kYXJ5IGlzIGEgPGI+aGFuZC1zZWxlY3Rpb24gb2YgMjAyMCBjZW5zdXMgdHJhY3RzPC9iPiB0aGF0IGFsaWduIHdpdGggR29vZ2xlIG1hcHMgYW5kIGNvbW1vbiB1bmRlcnN0YW5kaW5ncyBvZiBHb3dhbnVzOiBDZW5zdXMgVHJhY3RzIDc3LCA3NSwgNzEsIDEyNywgMTE5LCAxMjEsIGFuZCAxMTcuIEkgc29tZXRpbWVzIHJlZmVyIHRvIHRoaXMgYm91bmRhcnkgYXMgIkdvd2FudXMgcHJvcGVyLiIKCiMjIyMgQ29tbXVuaXR5IERpc3RyaWN0IFRhYnVsYXRpb24gQXJlYQohW10oaW1hZ2VzL2NkdGEucG5nKXt3aWR0aD00MDBweH0KCiMjIyMgTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYQoKIVtdKGltYWdlcy9udGEucG5nKXt3aWR0aD00MDBweH0KCiMjIyMgU2VsZWN0ZWQgQ2Vuc3VzIFRyYWN0cwoKIVtdKGltYWdlcy9jZW5zdXN0cmFjdC5wbmcpe3dpZHRoPTQwMHB4fQoKIyMjIEdvd2FudXMgTmVpZ2hib3Job29kIFBsYW4gTWFwCgpGaW5hbGx5LCB0byBjb250ZXh0dWFsaXplIHRoZXNlIHRocmVlIGFsdGVybmF0aXZlIGJvdW5kYXJpZXMsIGJlbG93IGlzIGEgbWFwIG9mIHRoZSBbR293YW51cyBOZWlnaGJvcmhvb2QgUGxhbl0oaHR0cHM6Ly93d3cxLm55Yy5nb3Yvc2l0ZS9wbGFubmluZy9wbGFucy9nb3dhbnVzL2dvd2FudXMucGFnZSkgcmV6b25pbmcgdGVycml0b3J5LCB3aGljaCBtb3N0IGNsb3NlbHkgcmVzZW1ibGVzIHRoZSBzZWxlY3RlZCBDZW5zdXMgdHJhY3RzIGJvdW5kYXJ5LgoKIVtdKGltYWdlcy9nbnBfbWFwLmpwZyl7d2lkdGg9NDAwcHh9CgojIyBEYXRhIFNvdXJjZXMgYW5kIEFuYWx5c2lzCk15IGFuYWx5c2VzIHJlbHkgb24gdGhlIFUuUy4gRGVjZW5uaWFsIENlbnN1cyAyMDIwIGRlbW9ncmFwaGljIGRhdGEuIEkgdXNlIHRoaXMgZGF0YSB0byBzaG93IHRoZSBwb3B1bGF0aW9uIHdpdGhpbiB0aGUgR3JlYXRlciBHb3dhbnVzIGFyZWEgYXMgcmVjZW50bHkgYW5kIHByZWNpc2VseSBhcyBwb3NzaWJsZS4gCgpUaGUgUmFjaWFsIEVxdWl0eSBSZXBvcnQgZG9lcyBub3QgdXNlIHRoZSAyMDIwIENlbnN1cyBhbmQgaW5zdGVhZCB1c2VzIGRhdGEgZnJvbSB0aGUgQW1lcmljYW4gQ29tbXVuaXR5IFN1cnZleSAoQUNTKSB0byBvYnNlcnZlIGFuZCBhbmFseXplIGRlbW9ncmFwaGljLCBob3VzaW5nLCBhbmQgaW5jb21lIHRyZW5kcy4gSG93ZXZlciwgZm9yIHNtYWxsZXIgYXJlYXMsIHVzaW5nIEFDUyBkYXRhIHlpZWxkcyBhIGhpZ2hlciBtYXJnaW4gb2YgZXJyb3IuIFdoaWxlIHRoZSBBQ1MgaXMgYW4gZXN0aW1hdGUsIHRoZSBEZWNlbm5pYWwgQ2Vuc3VzIGlzIGEgY291bnQgb2YgYWxsIHJlc2lkZW50cy4gQmVjYXVzZSBvZiB0aGlzLCB0aGUgRGVjZW5uaWFsIENlbnN1cyBjYW4gYmUgdXNlZCBmb3Igc21hbGxlciB0ZXJyaXRvcmllcy4gRm9yIHRoaXMgcmVhc29uLCBJIHRoaW5rIGl0IGlzIGltcG9ydGFudCB0byB1c2UgQ2Vuc3VzIGRhdGEgZm9yIHBvcHVsYXRpb24gZGVtb2dyYXBoaWNzLjxicj48YnI+Cjxocj4KCiMjIFJlc3VsdHMKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQoKIyMgUiBQVUJTIExJTks6IGh0dHBzOi8vcnB1YnMuY29tL2pwYWNrZXIvODQ2NTE0CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRpZHljZW5zdXMpCmxpYnJhcnkoc2YpCmxpYnJhcnkoc2NhbGVzKQpsaWJyYXJ5KHZpcmlkaXMpCmxpYnJhcnkocGxvdGx5KQoKCm9wdGlvbnMoc2NpcGVuID0gOTk5KQoKI2xvYWQgYWxsIG15IHNoYXBlIGZpbGVzCmNiNl9kZW1fZGF0YV8yMCA8LSBzdF9yZWFkKCJkYXRhL291dHB1dC9jYjZfZGVtX2RhdGFfMjAuc2hwIikKY2I2X2RlbV9kYXRhXzAwIDwtIHN0X3JlYWQoImRhdGEvb3V0cHV0L2NiNl9kZW1fZGF0YV8wMC5zaHAiKQpudGE2X2RlbV9kYXRhXzIwIDwtIHN0X3JlYWQoImRhdGEvb3V0cHV0L250YTZfZGVtX2RhdGFfMjAuc2hwIikKc2VsZWN0Y3RfZGVtX2RhdGFfMjAgPC0gc3RfcmVhZCgiL1VzZXJzL2pvcmRhbnBhY2tlcjEvRG9jdW1lbnRzL1BhcnNvbnMvRkEyMS9tZXRob2RzMS9maW5hbF9wcm9qZWN0L2RhdGEvb3V0cHV0L3NlbGVjdGN0X2RlbV9kYXRhXzIwLnNocCIpCgojbG9hZCBzdW1tYXJ5IGNzdnMKZ293YW51c19zdW1tYXJ5X3BvcCA8LSByZWFkX2NzdigiZGF0YS9vdXRwdXQvZ293YW51c19zdW1tYXJ5X3BvcC5jc3YiKQpnb3dhbnVzX3N1bW1hcnlfc3RhdHMgPC0gcmVhZF9jc3YoImRhdGEvb3V0cHV0L2dvd2FudXNfc3VtbWFyeV9zdGF0cy5jc3YiKQoKI2xvYWQgYWxsIG15IGdvdmVybm1lbnQgbWFwIHNoYXBlIGZpbGVzCnJhd19jYiA8LSBzdF9yZWFkKCIvVXNlcnMvam9yZGFucGFja2VyMS9Eb2N1bWVudHMvUGFyc29ucy9GQTIxL21ldGhvZHMxL2ZpbmFsX3Byb2plY3QvZGF0YS9ueWNkdGEyMDIwXzIxZC9ueWNkdGEyMDIwLnNocCIpCnJhd19udGEgPC0gc3RfcmVhZCgiL1VzZXJzL2pvcmRhbnBhY2tlcjEvRG9jdW1lbnRzL1BhcnNvbnMvRkEyMS9tZXRob2RzMS9maW5hbF9wcm9qZWN0L2RhdGEvbnludGEyMDIwXzIxZC9ueW50YTIwMjAuc2hwIikKcmF3X2N0IDwtIHN0X3JlYWQoIi9Vc2Vycy9qb3JkYW5wYWNrZXIxL0RvY3VtZW50cy9QYXJzb25zL0ZBMjEvbWV0aG9kczEvZmluYWxfcHJvamVjdC9kYXRhL255Y3QyMDIwXzIxZC9ueWN0MjAyMC5zaHAiKQoKYGBgCgoKCgojIyMgVG90YWwgUG9wdWxhdGlvbgpJbiB0aGUgZm9sbG93aW5nIGJhciBjaGFydCwgdGhlIHBvcHVsYXRpb24gZGlmZmVyZW5jZXMgYmV0d2VlbiB0aGUgdGhyZWUgYm91bmRhcmllcyBJIHNlbGVjdGVkIGFyZSBzaG93bi4KCiogVGhlIDxiPkNvbW11bml0eSBCb2FyZDwvYj4gbGV2ZWwgaGFzIHRoZSBsYXJnZXN0IGdlb2dyYXBoaWMgc2l6ZSBhbmQgaGlnaGVzdCBwb3B1bGF0aW9uOiA8Yj4xNjgsNjQ4PC9iPiBpbiAyMDIwLiAKKiBUaGUgPGI+TmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYTwvYj4gaXMgc21hbGxlciwgd2l0aCBhIHBvcHVsYXRpb24gb2YgPGI+MTA5LDc3NTwvYj4gaW4gMjAyMC4gCiogVGhlIDxiPmhhbmQtc2VsZWN0aW9uIG9mIGNlbnN1cyB0cmFjdHM8L2I+IGhhcyBhIHBvcHVsYXRpb24gb2YgPGI+MjQsOTU2PC9iPiBpbiAyMDIwLgoKQWxsIHRocmVlIGJvdW5kYXJpZXMgZ3JldyBmcm9tIDIwMDAgdG8gMjAyMCwgYnV0IHRoZSBDb21tdW5pdHkgQm9hcmQgYW5kIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEgaGF2ZSBzZWVuIGxhcmdlciBpbmNyZWFzZXMgaW4gcG9wdWxhdGlvbiB0aGFuIEdvd2FudXMgcHJvcGVyLgoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CgojIHRvdGFsIHBvcHVsYXRpb24gaGlzdG9ncmFtCmdvd2FudXNfcG9wc3RhdHMgPC0gZ2dwbG90KGRhdGE9Z293YW51c19zdW1tYXJ5X3BvcCwgYWVzKHg9Ym91bmRhcnksIHk9dG90YWxwb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJUb3RhbCBwb3B1bGF0aW9uOiAiLCBzY2FsZXM6OmNvbW1hKHRvdGFscG9wLCBhY2N1cmFjeT0xKSkpKSArCiAgCiAgCiAgZ2VvbV9jb2woKSArCiAgI2NvdWxkIGNoYW5nZSB0aGlzICJhbmdsZSIgYmVsb3cgZnJvbSA5MCB0byAyNSBmb3IgaXQgdG8gYmUgYSBiaXQgbW9yZSByZWFkYWJsZQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbD1zY2FsZXM6OmNvbW1hX2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIHNjYWxlX3NpemVfYXJlYShsYWJlbHMgPSBjb21tYSwgbWF4X3NpemUgPSAxMCkgKwogIHNjYWxlX2ZpbGxfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkNCMDAiID0gIkNvbW11bml0eSBCb2FyZCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDQjIwIiA9ICJDb21tdW5pdHkgQm9hcmQgMjAyMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTlRBMDAiID0gIk5laWdoYm9yaG9vZCBUcmFjdCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOVEEyMCIgPSAiTmVpZ2hib3Job29kIFRyYWN0IDIwMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSQUNUMDAiID0gIlNlbGVjdGVkIFRyYWN0cyAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUUkFDVDIwIiA9ICJTZWxlY3RlZCBUcmFjdHMgMjAyMCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTI1LGhqdXN0PTEsdmp1c3Q9MC41KSkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICsgIyByZW1vdmUgZ3JpZGxpbmVzCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKHggPSAiQm91bmRhcnkgb2YgR293YW51cyIsIHkgPSAiVG90YWwgUG9wdWxhdGlvbiIsIGZpbGwgPSAiUG9wdWxhdGlvbiIpCgpnZ3Bsb3RseShnb3dhbnVzX3BvcHN0YXRzLCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgbGF5b3V0KG1hcmdpbiA9IGxpc3QgKHQgPSAxNTApLCB0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUb3RhbCBQb3B1bGF0aW9uIGluIEdyZWF0ZXIgR293YW51cycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzdXA+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2J5IENEVEEsIE5UQSwgYW5kIFNlbGVjdGVkIENlbnN1cyBUcmFjdHMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTb3VyY2U6IERlY2VubmlhbCBDZW5zdXMgMjAyMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L3N1cD4nKSkpIAoKYGBgCgoKIyMjIFdoaXRlIFBvcHVsYXRpb24sIDIwMjAgKDMgQm91bmRhcmllcykKSGVyZSBJIGV4cGxvcmUgdGhlIHRocmVlIGJvdW5kYXJpZXMgdG8gc3BhdGlhbGx5IHZpc3VhbGl6ZSB0aGUgcG9wdWxhdGlvbiBvZiB3aGl0ZSByZXNpZGVudHMgaW4gR3JlYXRlciBHb3dhbnVzIGluIDIwMjAuIEFzIGlzIG5vdGljZWFibGUgZnJvbSB0aGUgQ29tbXVuaXR5IERpc3RyaWN0IFRhYnVsYXRpb24gbWFwLCBtYW55IGNlbnN1cyB0cmFjdHMgb2YgdGhlIG5laWdoYm9yaG9vZCBQYXJrIFNsb3BlIChhdCB0aGUgYm90dG9tIHJpZ2h0IG9mIHRoZSBtYXApIGFyZSBvdmVyIDcwJSB3aGl0ZS4gV2hlbiBJIG5hcnJvdyB0aGUgYm91bmRhcnkgdG8gTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYSwgdGhlIFBhcmsgU2xvcGUgcmVnaW9uIGlzIG5vIGxvbmdlciBpbmNsdWRlZC4gQXQgdGhlIHNlbGVjdGVkIHRyYWN0IGxldmVsLCB0aGVyZSBpcyBhIG1vcmUgZ3JhbnVsYXIgdmlldyBvZiB3aGl0ZW5lc3MgaW4gR293YW51cy4KCl9Ob3RlOiBJbiBteSBzcGF0aWFsIHZpc3VhbGl6YXRpb25zLCBJIHNob3cgdGhlIGJvdW5kYXJ5IG9mIHRoZSBDb21tdW5pdHkgQm9hcmQgd2l0aCBhbiBvcmFuZ2Ugb3V0bGluZSBhbmQgTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYSB3aXRoIGEgcmVkIG91dGxpbmUuXwoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CiMjIyMgQ0RUQSAjIyMjCnBjX25od2hpdGUyMGNiIDwtIGdncGxvdCgpICArIAogIGdlb21fc2YoZGF0YSA9IGNiNl9kZW1fZGF0YV8yMCwgbWFwcGluZyA9IGFlcyhmaWxsID0gcGNfbmh3MjAsIAogICAgICAgICAgdGV4dCA9IHBhc3RlMChuYW1lICwKICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Ub3RhbCBQb3B1bGF0aW9uOiAiLCBzY2FsZXM6OmNvbW1hKHR0bHBwMjAsIGFjY3VyYWN5PTEpLAogICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlBlcmNlbnRhZ2Ugb2YgTm9uLUhpc3BhbmljIFdoaXRlOiAiLCAKICAgICAgICAgICAgICAgICAgICAgICAgc2NhbGVzOjpwZXJjZW50KHBjX25odzIwLCBhY2N1cmFjeT0xTCkpKSwKICAgICAgICAgIGNvbG9yID0gIiNmZmZmZmYiLCBsd2QgPSAuMikgKwogIHRoZW1lX3ZvaWQoKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwgLjIsIC40LCAuNiwgLjgsIDEpLAogICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgIyBuYS52YWx1ZSA9ICIjZmFmYWZhIiwKICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIsCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZT0iUGVyY2VudGFnZSBOb24tSGlzcGFuaWMgV2hpdGUiLAogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1wZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIGdlb21fc2YoZGF0YSA9IHJhd19jYiAlPiUgZmlsdGVyKENEVEEyMDIwID09ICJCSzA2IiksIGNvbG9yID0gIm9yYW5nZSIsIGx3ZCA9LjUsZmlsbCA9IE5BKQoKZ2dwbG90bHkocGNfbmh3aGl0ZTIwY2IsIHRvb2x0aXAgPSAidGV4dCIpICU+JSAKICBsYXlvdXQobWFyZ2luID0gbGlzdCAodCA9IDEwMCksIHRpdGxlID0gbGlzdCh0ZXh0ID0gcGFzdGUwKCc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RvdGFsIFBvcHVsYXRpb24gb2YgTm9uLUhpc3BhbmljIFdoaXRlIFBlb3BsZSAoMjAyMCknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKQoKYGBgCmBgYHtyIGVjaG89RiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD03fQojIyMjIE5UQSAjIyMjCnBjX25od2hpdGUyMG50YSA8LSBnZ3Bsb3QoKSAgKyAKICBnZW9tX3NmKGRhdGEgPSBudGE2X2RlbV9kYXRhXzIwLCBtYXBwaW5nID0gYWVzKGZpbGwgPSBwY19uaHcyMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMChuYW1lICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodHRscHAyMCwgYWNjdXJhY3k9MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5QZXJjZW50YWdlIG9mIE5vbi1IaXNwYW5pYyBXaGl0ZTogIiwgc2NhbGVzOjpwZXJjZW50KHBjX25odzIwLCBhY2N1cmFjeT0xTCkpKSwKICAgICAgICAgIGNvbG9yID0gIiNmZmZmZmYiLCBsd2QgPSAuMikrCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCwgMSksCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAjIG5hLnZhbHVlID0gIiNmYWZhZmEiLAogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJQZXJjZW50YWdlIE5vbi1IaXNwYW5pYyBXaGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPXBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCiAgCiAgZ2VvbV9zZihkYXRhID0gcmF3X250YSAlPiUgZmlsdGVyKE5UQTIwMjAgPT0gIkJLMDYwMSIpLCBjb2xvciA9ICJmaXJlYnJpY2szIiwgZmlsbCA9IE5BKSAKCgpnZ3Bsb3RseShwY19uaHdoaXRlMjBudGEsIHRvb2x0aXAgPSAidGV4dCIpICU+JSAKICBsYXlvdXQobWFyZ2luID0gbGlzdCAodCA9IDEwMCksIHRpdGxlID0gbGlzdCh0ZXh0ID0gcGFzdGUwKCc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RvdGFsIFBvcHVsYXRpb24gb2YgTm9uLUhpc3BhbmljIFdoaXRlIFBlb3BsZSAoMjAyMCknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKQpgYGAKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CiMjIyMgQ0VOU1VTIFRSQUNUICMjIyMKcGNfbmh3aGl0ZTIwY3QgPC0gZ2dwbG90KCkgICsgCiAgZ2VvbV9zZihkYXRhID0gc2VsZWN0Y3RfZGVtX2RhdGFfMjAsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjX25odzIwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAobmFtZSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodHRscHAyMCwgYWNjdXJhY3k9MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlBlcmNlbnRhZ2Ugb2YgTm9uLVdoaXRlOiAiLCBzY2FsZXM6OnBlcmNlbnQocGNfbmh3MjAsIGFjY3VyYWN5PTFMKSkpLAogICAgICAgICAgY29sb3IgPSAiI2ZmZmZmZiIsIGx3ZCA9IC4yKSArCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMiwgLjQsIC42LCAuOCksCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAjIG5hLnZhbHVlID0gIiNmYWZhZmEiLAogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJQZXJjZW50YWdlIE5vbi1IaXNwYW5pYyBXaGl0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPXBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCiAgZ2VvbV9zZihkYXRhID0gc2VsZWN0Y3RfZGVtX2RhdGFfMjAsIGZpbGwgPSBOQSwgY29sb3IgPSAid2hpdGUiLCBsd2QgPSAuMikKCmdncGxvdGx5KHBjX25od2hpdGUyMGN0LCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgbGF5b3V0KHRpdGxlID0gbGlzdCh0ZXh0ID0gcGFzdGUwKCc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RvdGFsIFBvcHVsYXRpb24gb2YgTm9uLUhpc3BhbmljIFdoaXRlIFBlb3BsZSAoMjAyMCknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpbiBTZWxlY3RlZCBDZW5zdXMgVHJhY3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKQpgYGAKCiMjIyA8Yj4gTWlub3JpdGl6ZWQgUG9wdWxhdGlvbnMgT3ZlciBUaW1lIDwvYj4KCk5leHQsIEkgbG9va2VkIGF0IHRoZSBwb3B1bGF0aW9uIG9mIG1pbm9yaXRpemVkIGNvbW11bml0aWVzIGF0IHRoZSBsYXJnZXN0IGJvdW5kYXJ5IG92ZXIgdGltZS4gSSByYW4gdGhlc2UgYW5hbHlzZXMgZm9yIHR3byByZWFzb25zOiAxKSB0byBzZWUgaWYgaGlzdG9yaWNhbGx5IG1pbm9yaXRpemVkIHBvcHVsYXRpb25zIGhhdmUgYmVlbiBwdXNoZWQgb3V0IG9mIHRoZSBHb3dhbnVzIGFyZWEgaW4gdGhlIGxhc3QgdHdvIGRlY2FkZXMsIGFuZCAyKSB0byB1bmRlcnN0YW5kIHRoZSBsb25nZXZpdHkgb2YgY29tbXVuaXRpZXMgb2YgY29sb3IgaW4gR293YW51cy4gSSBzdGFydCBoZXJlIHdpdGggdGhlIHBvcHVsYXRpb24gb2YgQmxhY2sgcmVzaWRlbnRzLgoKIyMjIEJsYWNrIFBvcHVsYXRpb24sIDIwMjAgJiAyMDAwIChpbiBDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhKQoKT3ZlciB0aGUgbGFzdCB0d2VudHkgeWVhcnMsIHRoZSBCbGFjayBwb3B1bGF0aW9uIGluIEdvd2FudXMgaGFzIHJlbWFpbmVkIHN0YWJsZS4gSW4gYm90aCAyMDAwIGFuZCAyMDIwLCBCbGFjayBwZW9wbGUgbWFrZSB1cCBvdmVyIDMwJSBvZiB0aGUgcG9wdWxhdGlvbiBpbiBDZW5zdXMgVHJhY3RzIDcxICYgMTI3LCBhbmQgb3ZlciA0MCUgb2YgQ2Vuc3VzIFRyYWN0IDg1LiAKCmBgYHtyIGVjaG89RiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD03fQojIyMjIENEVEEgMjAyMCAtIEJsYWNrCnBjX25oYmxhY2syMGNiIDwtIGdncGxvdCgpICArIAogIGdlb21fc2YoZGF0YSA9IGNiNl9kZW1fZGF0YV8yMCwgbWFwcGluZyA9IGFlcyhmaWxsID0gcGNfbmhiMjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKG5hbWUgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodHRscHAyMCwgYWNjdXJhY3k9MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGVyY2VudGFnZSBvZiBOb24tSGlzcGFuaWMgQmxhY2s6ICIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2FsZXM6OnBlcmNlbnQocGNfbmhiMjAsIGFjY3VyYWN5PTFMKSkpLAogICAgICAgICAgY29sb3IgPSAiI2ZmZmZmZiIsIGx3ZCA9IC4yKSsKICB0aGVtZV92b2lkKCkgKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKGJyZWFrcz1jKDAsIC4xLCAuMiwgLjMsIC40KSwKICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLAogICAgICAgICAgICAgICAgICAgICAgICMgbmEudmFsdWUgPSAiI2ZhZmFmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnRhZ2UgTm9uLUhpc3BhbmljIEJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsKICBnZW9tX3NmKGRhdGEgPSByYXdfY2IgJT4lIGZpbHRlcihDRFRBMjAyMCA9PSAiQkswNiIpLCBjb2xvciA9ICJvcmFuZ2UiLCBmaWxsID0gTkEpCgpnZ3Bsb3RseShwY19uaGJsYWNrMjBjYiwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGxheW91dCh0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUb3RhbCBQb3B1bGF0aW9uIG9mIE5vbi1IaXNwYW5pYyBCbGFjayBQZW9wbGUgKDIwMjApJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYnkgQ29tbXVuaXR5IERpc3RyaWN0IFRhYnVsYXRpb24gQXJlYScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzdXA+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NvdXJjZTogRGVjZW5uaWFsIENlbnN1cyAyMDIwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvc3VwPicpKSkKYGBgCmBgYHtyIGVjaG89RiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD03fQojIyMjIENEVEEgMjAwMCAtIEJsYWNrCnBjX25oYmxhY2swMGNiIDwtIGdncGxvdCgpICArIAogIGdlb21fc2YoZGF0YSA9IGNiNl9kZW1fZGF0YV8wMCwgbWFwcGluZyA9IGFlcyhmaWxsID0gcGNfbmhiMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAobmFtZSAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Ub3RhbCBQb3B1bGF0aW9uOiAiLCBzY2FsZXM6OmNvbW1hKHR0bHBwMDAsIGFjY3VyYWN5PTEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGVyY2VudGFnZSBvZiBOb24tSGlzcGFuaWMgQmxhY2s6ICIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYWxlczo6cGVyY2VudChwY19uaGIwMCwgYWNjdXJhY3k9MUwpKSksCiAgICAgICAgICBjb2xvciA9ICIjZmZmZmZmIiwgbHdkID0gLjIpKwogIHRoZW1lX3ZvaWQoKSArCiAgc2NhbGVfZmlsbF9kaXN0aWxsZXIoYnJlYWtzPWMoMCwgLjE1LCAuMywgLjQ1LCAuNiwgLjc1KSwKICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLAogICAgICAgICAgICAgICAgICAgICAgICMgbmEudmFsdWUgPSAiI2ZhZmFmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnRhZ2UgTm9uLUhpc3BhbmljIEJsYWNrIiwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsKICBnZW9tX3NmKGRhdGEgPSByYXdfY2IgJT4lIGZpbHRlcihDRFRBMjAyMCA9PSAiQkswNiIpLCBjb2xvciA9ICJvcmFuZ2UiLCBmaWxsID0gTkEpCgpnZ3Bsb3RseShwY19uaGJsYWNrMDBjYiwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGxheW91dCh0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUb3RhbCBQb3B1bGF0aW9uIG9mIE5vbi1IaXNwYW5pYyBCbGFjayBQZW9wbGUgKDIwMDApJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnYnkgQ29tbXVuaXR5IERpc3RyaWN0IFRhYnVsYXRpb24gQXJlYScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzdXA+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1NvdXJjZTogRGVjZW5uaWFsIENlbnN1cyAyMDAwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvc3VwPicpKSkKCmBgYAoKIyMjIEhpc3BhbmljIC8gTGF0aW5vIFBvcHVsYXRpb24sIDIwMjAgJiAyMDAwIChpbiBDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhKQpFeGFtaW5pbmcgdGhlIEhpc3BhbmljL0xhdGlubyBwb3B1bGF0aW9uIG92ZXIgdGhlIGxhc3QgdHdlbnR5IHllYXJzIHJldmVhbHMgYSAgc2hvY2tpbmcgY2hhbmdlLiBJbiAyMDIwLCBvbmx5IHR3byBDZW5zdXMgdHJhY3RzIGhhdmUgb3ZlciA0MCUgSGlzcGFuaWMvTGF0aW5vIHBlb3BsZS4gSW4gMjAwMCwgdGhlcmUgd2VyZSBvdmVyIDEwLiBUaGlzIGlzIGEgc2lnbiBvZiBkaXNwbGFjZW1lbnQgYW5kIGluZGljYXRlcyB0aGF0IEdyZWF0ZXIgR293YW51cyB3YXMgYSBwcmltYXJpbHkgSGlzcGFuaWMvTGF0aW5vIGNvbW11bml0eSBpbiAyMDAwLgoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CiMjIyMgQ0RUQSAyMDIwIC0gSGlzcGFuaWMvTGF0aW5vCgpwY19oaXNfbGF0MjBjYiA8LSBnZ3Bsb3QoKSAgKyAKICBnZW9tX3NmKGRhdGEgPSBjYjZfZGVtX2RhdGFfMjAsIG1hcHBpbmcgPSBhZXMoZmlsbCA9IHBjX2hfMjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKG5hbWUgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodHRscHAyMCwgYWNjdXJhY3k9MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UGVyY2VudGFnZSBvZiBIaXNwYW5pYy9MYXRpbm86ICIsIHNjYWxlczo6cGVyY2VudChwY19oXzIwLCBhY2N1cmFjeT0xTCkpKSwKICAgICAgICAgIGNvbG9yID0gIiNmZmZmZmYiLCBsd2QgPSAuMikrCiAgdGhlbWVfdm9pZCgpICsKICBzY2FsZV9maWxsX2Rpc3RpbGxlcihicmVha3M9YygwLCAuMSwgLjIsIC4zLCAuNCksCiAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAjIG5hLnZhbHVlID0gIiNmYWZhZmEiLAogICAgICAgICAgICAgICAgICAgICAgIG5hLnZhbHVlID0gInRyYW5zcGFyZW50IiwKICAgICAgICAgICAgICAgICAgICAgICBuYW1lPSJQZXJjZW50YWdlIEhpc3BhbmljL0xhdGlubyIsCiAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPXBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCgogIGdlb21fc2YoZGF0YSA9IHJhd19jYiAlPiUgZmlsdGVyKENEVEEyMDIwID09ICJCSzA2IiksIGNvbG9yID0gIm9yYW5nZSIsIGZpbGwgPSBOQSkKCmdncGxvdGx5KHBjX2hpc19sYXQyMGNiLCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgbGF5b3V0KHRpdGxlID0gbGlzdCh0ZXh0ID0gcGFzdGUwKCc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RvdGFsIFBvcHVsYXRpb24gb2YgSGlzcGFuaWMgJiBMYXRpbm8gUGVvcGxlICgyMDIwKScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8YnI+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzdXA+JywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2J5IENvbW11bml0eSBEaXN0cmljdCBUYWJ1bGF0aW9uIEFyZWEnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdTb3VyY2U6IERlY2VubmlhbCBDZW5zdXMgMjAyMCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L3N1cD4nKSkpCmBgYAoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CiMjIyMgQ0RUQSAyMDAwIC0gSGlzcGFuaWMvTGF0aW5vCnBjX2hpc19sYXQwMGNiIDwtIGdncGxvdCgpICArIAogIGdlb21fc2YoZGF0YSA9IGNiNl9kZW1fZGF0YV8wMCwgbWFwcGluZyA9IGFlcyhmaWxsID0gcGNfaF8wMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMChuYW1lICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodHRscHAwMCwgYWNjdXJhY3k9MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5QZXJjZW50YWdlIG9mIEhpc3BhbmljL0xhdGlubzogIiwgc2NhbGVzOjpwZXJjZW50KHBjX2hfMDAsIGFjY3VyYWN5PTFMKSkpLAogICAgICAgICAgY29sb3IgPSAiI2ZmZmZmZiIsIGx3ZCA9IC4yKSsKICB0aGVtZV92b2lkKCkgKwogIHNjYWxlX2ZpbGxfZGlzdGlsbGVyKGJyZWFrcz1jKDAsIC4yLCAuNCwgLjYsIC44LCAxKSwKICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAxLAogICAgICAgICAgICAgICAgICAgICAgICMgbmEudmFsdWUgPSAiI2ZhZmFmYSIsCiAgICAgICAgICAgICAgICAgICAgICAgbmEudmFsdWUgPSAidHJhbnNwYXJlbnQiLAogICAgICAgICAgICAgICAgICAgICAgIG5hbWU9IlBlcmNlbnRhZ2UgSGlzcGFuaWMvTGF0aW5vIiwKICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHM9cGVyY2VudF9mb3JtYXQoYWNjdXJhY3kgPSAxTCkpICsKICAKICBnZW9tX3NmKGRhdGEgPSByYXdfY2IgJT4lIGZpbHRlcihDRFRBMjAyMCA9PSAiQkswNiIpLCBjb2xvciA9ICJvcmFuZ2UiLCBmaWxsID0gTkEpCgpnZ3Bsb3RseShwY19oaXNfbGF0MDBjYiwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGxheW91dCh0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdUb3RhbCBQb3B1bGF0aW9uIG9mIEhpc3BhbmljICYgTGF0aW5vIFBlb3BsZSAoMjAwMCknLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMDAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKQpgYGAKCiMjIyBDb21wYXJpbmcgUmVwcmVzZW50YXRpdmVuZXNzOiBEZW1vZ3JhcGhpY3MgQWNyb3NzIHRoZSBUaHJlZSBCb3VuZGFyaWVzCgpJbiB0aGUgZm9sbG93aW5nIGJhciBjaGFydHMsIEkgY29tcGFyZSBDb21tdW5pdHkgQm9hcmQsIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEsIGFuZCBTZWxlY3RlZCBUcmFjdHMgYWNyb3NzIGZvdXIgZGVtb2dyYXBoaWMgcG9wdWxhdGlvbnM6IFdoaXRlLCBOb24tV2hpdGUsIEhpc3BhbmljL0xhdGlubywgYW5kIEJsYWNrIHRvIGNoZWNrIGZvciAicmVwcmVzZW50YXRpdmVuZXNzLiIgSWYgdGhlIHRocmVlIGJvdW5kYXJpZXMgd2VyZSByZXByZXNlbnRhdGl2ZSBvZiBHb3dhbnVzIGFuZCBzaW1pbGFyIHRvIG9uZSBhbm90aGVyLCB3ZSB3b3VsZCBleHBlY3QgdG8gc2VlIHRoZSBzYW1lIHBlcmNlbnRhZ2VzIChoZWlnaHQpIGFjcm9zcyBlYWNoIGJvdW5kYXJ5IChjb2x1bW4pLiBUaGVzZSB3b3VsZCBiZSBib3JpbmcgYmFyIGNoYXJ0cyB3aXRoIGVxdWFsLXNpemVkIHJlY3RhbmdsZXMuIEhvd2V2ZXIsIHRoYXQgaXMgbm90IHRoZSBjYXNlLiBJIGRlc2NyaWJlIHRoZXNlIHBlcmNlbnRhZ2VzIGluIGRldGFpbCBiZWxvdy4KCkJlZ2lubmluZyB3aXRoIHRoZSB3aGl0ZSBwb3B1bGF0aW9uLCB0aGVyZSBpcyBhIGhpZ2hlciBwZXJjZW50YWdlIG9mIHdoaXRlIHJlc2lkZW50cyBhdCB0aGUgY29tbXVuaXR5IGJvYXJkIGxldmVsICg1OSUgaW4gMjAyMCkgYW5kIGEgbG93ZXIgcGVyY2VudGFnZSBpbiB0aGUgc2VsZWN0ZWQgdHJhY3RzICg1MSUpLiA1MSUgaXMgYSB2ZXJ5IHNsaWdodCBtYWpvcml0eSBvZiBHb3dhbnVzIHByb3Blci4gVGhlIG5laWdoYm9yaG9vZCB0YWJ1bGF0aW9uIGFyZWEgaXMgbW9yZSBzaW1pbGFyIHRvIHRoZSBjb21tdW5pdHkgYm9hcmQgdGhhbiB0byB0aGUgc2VsZWN0ZWQgdHJhY3RzLgoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CgojUFJPUCBXSElURSBISVNUT0dSQU0Kd2hpdGVfcHJvcCA8LSBnZ3Bsb3QoZGF0YT1nb3dhbnVzX3N1bW1hcnlfc3RhdHMsIGFlcyh4PWJvdW5kYXJ5LCB5PXdoaXRlLGZpbGw9dG90YWxwb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiVG90YWwgUG9wdWxhdGlvbjogIiwgc2NhbGVzOjpjb21tYSh0b3RhbHBvcCwgYWNjdXJhY3k9MSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Qcm9wb3J0aW9uIG9mIFdoaXRlIFJlc2lkZW50czogIiwgc2NhbGVzOjpwZXJjZW50KHdoaXRlLCBhY2N1cmFjeT0uMSkpKSkgKwogIAogIGdlb21fY29sKCkgKwogICNjb3VsZCBjaGFuZ2UgdGhpcyAiYW5nbGUiIGJlbG93IGZyb20gOTAgdG8gMjUgZm9yIGl0IHRvIGJlIGEgYml0IG1vcmUgcmVhZGFibGUKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWw9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIHNjYWxlX2ZpbGxfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkNCMDAiID0gIkNvbW11bml0eSBCb2FyZCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDQjIwIiA9ICJDb21tdW5pdHkgQm9hcmQgMjAyMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTlRBMDAiID0gIk5laWdoYm9yaG9vZCBUcmFjdCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOVEEyMCIgPSAiTmVpZ2hib3Job29kIFRyYWN0IDIwMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSQUNUMDAiID0gIlNlbGVjdGVkIFRyYWN0cyAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUUkFDVDIwIiA9ICJTZWxlY3RlZCBUcmFjdHMgMjAyMCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTI1LGhqdXN0PTEsdmp1c3Q9LjUpKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgKyAjIHJlbW92ZSBncmlkbGluZXMKICBsYWJzKHggPSAiQm91bmRhcnkgb2YgR293YW51cyIsIHkgPSAiUHJvcG9ydGlvbiBXaGl0ZSAoJSkiLCBmaWxsID0gIlBvcHVsYXRpb24iKQoKZ2dwbG90bHkod2hpdGVfcHJvcCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGxheW91dChtYXJnaW4gPSBsaXN0ICh0ID0gMTUwKSwgdGl0bGUgPSBsaXN0KHRleHQgPSBwYXN0ZTAoJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUHJvcG9ydGlvbiBXaGl0ZSBpbiBHcmVhdGVyIEdvd2FudXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDRFRBLCBOVEEsIGFuZCBTZWxlY3RlZCBDZW5zdXMgVHJhY3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKSAKYGBgCkZvciBOb24tV2hpdGUgcmVzaWRlbnRzLCB0aGVyZSBpcyBuZWFybHkgYSAxMCUgcGVyY2VudGFnZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGNvbW11bml0eSBib2FyZCBib3VuZGFyeSBhbmQgdGhlIHRyYWN0IGxldmVsLCAzNC41JSBjb21wYXJlZCB0byA0NC4xJSBpbiAyMDIwLiBUaGlzIGRpZmZlcmVuY2UgaXMgZXZlbiBzdGFya2VyIGluIDIwMDAsIDQ1LjIlIGNvbXBhcmVkIHRvIDU5LjUlIC0gYSBkaWZmZXJlbmNlIG9mIDE0LjMlLiBBZ2FpbiB0aGUgbmVpZ2hib3Job29kIHRhYnVsYXRpb24gYXJlYSBpcyBtb3JlIHNpbWlsYXIgdG8gdGhlIGNvbW11bml0eSBib2FyZCB0aGFuIHRvIHRoZSBzZWxlY3RlZCB0cmFjdHMuIAoKYGBge3IgZWNobz1GLCBtZXNzYWdlPUYsIHdhcm5pbmc9RiwgZmlnLndpZHRoPTd9CiNQUk9QIE5PTi1XSElURSBISVNUT0dSQU0Kbm9ud2hpdGVfcHJvcCA8LSBnZ3Bsb3QoZGF0YT1nb3dhbnVzX3N1bW1hcnlfc3RhdHMsIGFlcyh4PWJvdW5kYXJ5LCB5PW5vbl93aGl0ZSxmaWxsPXRvdGFscG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodG90YWxwb3AsIGFjY3VyYWN5PTEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UHJvcG9ydGlvbiBvZiBOb24tV2hpdGUgUmVzaWRlbnRzOiAiLCBzY2FsZXM6OnBlcmNlbnQobm9uX3doaXRlLCBhY2N1cmFjeT0uMSkpKSkgKwogIAogIGdlb21fY29sKCkgKwogICNjb3VsZCBjaGFuZ2UgdGhpcyAiYW5nbGUiIGJlbG93IGZyb20gOTAgdG8gMjUgZm9yIGl0IHRvIGJlIGEgYml0IG1vcmUgcmVhZGFibGUKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWw9c2NhbGVzOjpwZXJjZW50X2Zvcm1hdChhY2N1cmFjeSA9IDFMKSkgKwogIHNjYWxlX2ZpbGxfY29udGludW91cyhsYWJlbHMgPSBjb21tYSkgKwogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIkNCMDAiID0gIkNvbW11bml0eSBCb2FyZCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDQjIwIiA9ICJDb21tdW5pdHkgQm9hcmQgMjAyMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTlRBMDAiID0gIk5laWdoYm9yaG9vZCBUcmFjdCAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOVEEyMCIgPSAiTmVpZ2hib3Job29kIFRyYWN0IDIwMjAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSQUNUMDAiID0gIlNlbGVjdGVkIFRyYWN0cyAyMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUUkFDVDIwIiA9ICJTZWxlY3RlZCBUcmFjdHMgMjAyMCIpKSArCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KGFuZ2xlPTI1LGhqdXN0PTEsdmp1c3Q9MC41KSkgKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICsgIyByZW1vdmUgZ3JpZGxpbmVzCiAgbGFicyh4ID0gIkJvdW5kYXJ5IG9mIEdvd2FudXMiLCB5ID0gIlByb3BvcnRpb24gTm9uLVdoaXRlICglKSIsIGZpbGwgPSAiUG9wdWxhdGlvbiIpCgpnZ3Bsb3RseShub253aGl0ZV9wcm9wLCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgbGF5b3V0KG1hcmdpbiA9IGxpc3QgKHQgPSAxNTApLCB0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQcm9wb3J0aW9uIE5vbi1XaGl0ZSBpbiBHcmVhdGVyIEdvd2FudXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDRFRBLCBOVEEsIGFuZCBTZWxlY3RlZCBDZW5zdXMgVHJhY3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JyApKSkKYGBgCgpTdHJpa2luZ2x5LCB0aGUgSGlzcGFuaWMvTGF0aW5vIHBvcHVsYXRpb24gd2l0aGluIHRoZSBzZWxlY3RlZCB0cmFjdHMgaXMgNi42JSBoaWdoZXIgaW4gMjAyMCwgYW5kIG92ZXIgMTQlIGhpZ2hlciBpbiAyMDAwLiBJbiBhZGRpdGlvbiwgdGhpcyBiYXIgY2hhcnQgbWFrZXMgY2xlYXIgdGhlIHNpZ25pZmljYW50IGRyb3AgaW4gdGhlIEhpc3BhbmljL0xhdGlubyBwb3B1bGF0aW9uIGZyb20gMjAwMCB0byAyMDIwLiBBdCB0aGUgc2VsZWN0ZWQgQ2Vuc3VzIHRyYWN0IGxldmVsLCB0aGUgSGlzcGFuaWMvTGF0aW5vIHBvcHVsYXRpb24gZHJvcHBlZCBmcm9tIDQxJSB0byAyMyUgb3ZlciB0d2VudHkgeWVhcnMgc2lnbmFsaW5nIHRyZW5kcyBvZiBicm9hZGVyIGRpc3BsYWNlbWVudC4gVGhlc2UgcGF0dGVybnMgb2YgZGlzcGxhY2VtZW50IGFyZSBjbGVhciBhY3Jvc3MgYWxsIHRocmVlIGJvdW5kYXJpZXMuCmBgYHtyIGVjaG89RiwgbWVzc2FnZT1GLCB3YXJuaW5nPUYsIGZpZy53aWR0aD03fQojUFJPUCBISVMgTEFUIEhJU1RPR1JBTQpoaXNsYXRfcHJvcCA8LSBnZ3Bsb3QoZGF0YT1nb3dhbnVzX3N1bW1hcnlfc3RhdHMsIGFlcyh4PWJvdW5kYXJ5LCB5PWhpc19sYXQsZmlsbD10b3RhbHBvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlMCgiVG90YWwgUG9wdWxhdGlvbjogIiwgc2NhbGVzOjpjb21tYSh0b3RhbHBvcCwgYWNjdXJhY3k9MSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UHJvcG9ydGlvbiBvZiBIaXNwYW5pYy9MYXRpbm8gUmVzaWRlbnRzOiAiLCBzY2FsZXM6OnBlcmNlbnQoaGlzX2xhdCwgIGFjY3VyYWN5PS4xKSkpKSArCiAgCiAgZ2VvbV9jb2woKSArCiAgI2NvdWxkIGNoYW5nZSB0aGlzICJhbmdsZSIgYmVsb3cgZnJvbSA5MCB0byAyNSBmb3IgaXQgdG8gYmUgYSBiaXQgbW9yZSByZWFkYWJsZQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbD1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiQ0IwMCIgPSAiQ29tbXVuaXR5IEJvYXJkIDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNCMjAiID0gIkNvbW11bml0eSBCb2FyZCAyMDIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOVEEwMCIgPSAiTmVpZ2hib3Job29kIFRyYWN0IDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5UQTIwIiA9ICJOZWlnaGJvcmhvb2QgVHJhY3QgMjAyMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFJBQ1QwMCIgPSAiU2VsZWN0ZWQgVHJhY3RzIDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSQUNUMjAiID0gIlNlbGVjdGVkIFRyYWN0cyAyMDIwIikpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9MjUsaGp1c3Q9MSx2anVzdD0wLjUpKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgKyAjIHJlbW92ZSBncmlkbGluZXMKICBsYWJzKHggPSAiQm91bmRhcnkgb2YgR293YW51cyIsIHkgPSAiUHJvcG9ydGlvbiBIaXNwYW5pYy9MYXRpbm8gKCUpIiwgZmlsbCA9ICJQb3B1bGF0aW9uIikKCmdncGxvdGx5KGhpc2xhdF9wcm9wLCB0b29sdGlwID0gInRleHQiKSAlPiUgCiAgbGF5b3V0KG1hcmdpbiA9IGxpc3QgKHQgPSAxNTApLCB0aXRsZSA9IGxpc3QodGV4dCA9IHBhc3RlMCgnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQcm9wb3J0aW9uIEhpc3BhbmljL0xhdGlubyBpbiBHcmVhdGVyIEdvd2FudXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDRFRBLCBOVEEsIGFuZCBTZWxlY3RlZCBDZW5zdXMgVHJhY3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKSAgCmBgYAoKRmluYWxseSwgdGhlIEJsYWNrIHBvcHVsYXRpb24gY2hhbmdlZCBsZWFzdCBhY3Jvc3MgdGhlIGJvdW5kYXJpZXMsIGJ1dCB3YXMgc3RpbGwgc2hvd2VkIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBDb21tdW5pdHkgQm9hcmQgYW5kIE5laWdoYm9yaG9vZCBUYWJ1bGF0aW9uIEFyZWEgdGhhbiB0aGUgQ2Vuc3VzIFRyYWN0cy4gSW4gMjAyMCwgQ29tbXVuaXR5IEJvYXJkIHdhcyA5LjYlIEJsYWNrLCBOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhIHdhcyA5LjI2JSBhbmQgdGhlIHNlbGVjdGVkIHRyYWN0cyB3ZXJlIHRoZSBoaWdoZXN0IGF0IDEyLjYlLgpgYGB7ciBlY2hvPUYsIG1lc3NhZ2U9Riwgd2FybmluZz1GLCBmaWcud2lkdGg9N30KI1BST1AgQkxBQ0sgSElTVE9HUkFNCmJsYWNrX3Byb3AgPC0gZ2dwbG90KGRhdGE9Z293YW51c19zdW1tYXJ5X3N0YXRzLCBhZXMoeD1ib3VuZGFyeSwgeT1ibGFjayxmaWxsPXRvdGFscG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIlRvdGFsIFBvcHVsYXRpb246ICIsIHNjYWxlczo6Y29tbWEodG90YWxwb3AsIGFjY3VyYWN5PTEpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+UHJvcG9ydGlvbiBvZiBCbGFjayBSZXNpZGVudHM6ICIsIHNjYWxlczo6cGVyY2VudChibGFjaywgIGFjY3VyYWN5PS4xKSkpKSArCiAgCiAgZ2VvbV9jb2woKSArCiAgI2NvdWxkIGNoYW5nZSB0aGlzICJhbmdsZSIgYmVsb3cgZnJvbSA5MCB0byAyNSBmb3IgaXQgdG8gYmUgYSBiaXQgbW9yZSByZWFkYWJsZQogIHNjYWxlX3lfY29udGludW91cyhsYWJlbD1zY2FsZXM6OnBlcmNlbnRfZm9ybWF0KGFjY3VyYWN5ID0gMUwpKSArCiAgc2NhbGVfZmlsbF9jb250aW51b3VzKGxhYmVscyA9IGNvbW1hKSArCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiQ0IwMCIgPSAiQ29tbXVuaXR5IEJvYXJkIDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNCMjAiID0gIkNvbW11bml0eSBCb2FyZCAyMDIwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOVEEwMCIgPSAiTmVpZ2hib3Job29kIFRyYWN0IDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5UQTIwIiA9ICJOZWlnaGJvcmhvb2QgVHJhY3QgMjAyMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVFJBQ1QwMCIgPSAiU2VsZWN0ZWQgVHJhY3RzIDIwMDAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRSQUNUMjAiID0gIlNlbGVjdGVkIFRyYWN0cyAyMDIwIikpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9MjUsaGp1c3Q9MSx2anVzdD0wLjUpKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgKyAjIHJlbW92ZSBncmlkbGluZXMKICBsYWJzKHggPSAiQm91bmRhcnkgb2YgR293YW51cyIsIHkgPSAiUHJvcG9ydGlvbiBCbGFjayAoJSkiLCBmaWxsID0gIlBvcHVsYXRpb24iKQoKZ2dwbG90bHkoYmxhY2tfcHJvcCwgdG9vbHRpcCA9ICJ0ZXh0IikgJT4lIAogIGxheW91dChtYXJnaW4gPSBsaXN0ICh0ID0gMTUwKSwgdGl0bGUgPSBsaXN0KHRleHQgPSBwYXN0ZTAoJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUHJvcG9ydGlvbiBCbGFjayBpbiBHcmVhdGVyIEdvd2FudXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPGJyPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICc8c3VwPicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdieSBDRFRBLCBOVEEsIGFuZCBTZWxlY3RlZCBDZW5zdXMgVHJhY3RzJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHN1cD4nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnU291cmNlOiBEZWNlbm5pYWwgQ2Vuc3VzIDIwMjAnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9zdXA+JykpKSAgCmBgYAoKIyMgRGlzY3Vzc2lvbgoKTXkgY291bnRlci1hbmFseXNpcyBvZiB0aGUgR293YW51cyBSYWNpYWwgRXF1aXR5IFJlcG9ydCdzIGRlbW9ncmFwaGljIGRhdGEgZGVtb25zdHJhdGVzIHRoYXQgR293YW51cyBpcyBub3QgbmVhcmx5IGFzIHdoaXRlIGFzIHRoZSBSYWNpYWwgRXF1aXR5IFJlcG9ydCBjbGFpbXMuIDxiPiBUaGUgUmFjaWFsIEVxdWl0eSBSZXBvcnQgaW5mbGF0ZXMgd2hpdGUgcmVzaWRlbnRzIGFuZCBlcmFzZXMgcmVzaWRlbnRzIG9mIGNvbG9yIGluIHRoZWlyIGRlbW9ncmFwaGljIGRlcGljdGlvbiBvZiBHb3dhbnVzLjwvYj4gQnkgdXNpbmcgbGFyZ2VyIGJvdW5kYXJpZXMgdGhhdCBsdW1wIGluIG5laWdoYm9yaW5nIGNvbW11bml0aWVzLCBHb3dhbnVzIGlzIHBhaW50ZWQgYXMgbW9yZSB3aGl0ZSB0aGFuIGl0IHJlYWxseSBpcy4gSW4gYWN0dWFsaXR5LCBHb3dhbnVzIGl0c2VsZiBpcyA1MSUgd2hpdGUgYW5kIGJ5IGNsYWltaW5nIGl0IGFzIGEgd2hpdGUgY29tbXVuaXR5LCB0aGUgb3RoZXIgNDklIG9mIHRoZSBwb3B1bGF0aW9uIGlzIGFjdGl2ZWx5IGVyYXNlZC4gVW5mb3J0dW5hdGVseSwgZXZlbiB0aGUgbWVkaWEgaGFzIGJvdWdodCBpbiB0byB0aGlzIHBlcnZhc2l2ZSBuYXJyYXRpdmUgb2YgR293YW51cyBhcyBhIHdoaXRlIGNvbW11bml0eSwgYXMgY2FuIGJlIHNlZW4gaW4gcmVjZW50IHB1YmxpY2F0aW9ucyBmcm9tIHRoZSBbTmV3IFlvcmsgVGltZXNdKGh0dHBzOi8vd3d3Lm55dGltZXMuY29tLzIwMjEvMTIvMTUvbnlyZWdpb24vc29oby1yZXpvbmluZy12b3RlLmh0bWwpIGFuZCBDaXR5IExpbWl0cyBbb3AtZWRzXShodHRwczovL2NpdHlsaW1pdHMub3JnLzIwMjEvMTEvMjkvb3Bpbmlvbi1nb3dhbnVzLXJlem9uaW5nLXNob3dzLWhvdy13ZS1jYW4tcGxhbi10b2dldGhlci1mb3ItYS1mYWlyZXItbnljLykgYnkgQ2l0eSBDb3VuY2lsIE1lbWJlciBhbmQgcmV6b25pbmcgcHJvcG9uZW50LCBCcmFkIExhbmRlci4KCkxvb2tpbmcgYXQgbG9uZ2l0dWRpbmFsIGRhdGEsIEkgZGlzY292ZXJlZCB0aGUgYWxhcm1pbmcgbWFzcyBkaXNwbGFjZW1lbnQgb2YgSGlzcGFuaWMvTGF0aW5vIHBlb3BsZSBmcm9tIEdyZWF0ZXIgR293YW51cy4gSSBiZWxpZXZlIHRoaXMgaXMgYSByZXN1bHQgb2YgdGhlIDR0aCBBdmVudWUgUGFyayBTbG9wZSByZXpvbmluZyBpbiB0aGUgZWFybHkgMjAwMHMgYW5kIHNob3VsZCBzZXJ2ZSBhcyBhIHJlZCBmbGFnIGZvciB1cGNvbWluZyByZXpvbmluZ3MgaW4gdGhlIGFyZWEuIAoKV2hpbGUgdGhlIGltcGxlbWVudGF0aW9uIG9mIHJlcXVpcmVkIFJhY2lhbCBFcXVpdHkgUmVwb3J0cyB0aHJvdWdoIEludHJvIDE1NzItMjAxOS1CIGxlZ2lzbGF0aW9uIGhhcyBnb29kIGludGVudGlvbnMsIGFuZCBzdXJlbHkgY2FuIGJlIHV0aWxpemVkIHRvIGFuYWx5emUgdGhlIGVmZmVjdHMgb2YgbGFuZCB1c2UgY2hhbmdlIGFwcGxpY2F0aW9ucyBpbiBOZXcgWW9yayBDaXR5LCBSYWNpYWwgRXF1aXR5IFJlcG9ydHMgYXJlIG5vdCBvYmplY3RpdmUgZmFjdHMgYW5kIGNhbiBiZSBtYW5pcHVsYXRlZCB0byB0ZWxsIGEgc3BlY2lmaWMgc3RvcnkuIEFzIHlvdSBjYW4gc2VlIHRocm91Z2ggbXkgYW5hbHlzaXMsIHRoZSBSYWNpYWwgRXF1aXR5IFJlcG9ydCBjdXJhdGVzIEdvd2FudXMgYXMgYSB3aGl0ZSBhbmQgd2VhbHRoeSBjb21tdW5pdHkgdGhhdCB3aWxsIGJlbmVmaXQgZnJvbSByZWRldmVsb3BtZW50LCBiZWNhdXNlIGl0IHdpbGwgY3JlYXRlIG1vcmUgZGl2ZXJzaXR5LiBUaGlzIGZyYW1pbmcgb3Zlcmxvb2tzIHRoZSBleGlzdGluZyBwZW9wbGUgb2YgY29sb3IgdGhhdCBsaXZlIGluIEdvd2FudXMsIGFuZCBpbiBmYWN0LCBlcmFzZXMgdGhlaXIgZXhpc3RlbmNlIHRocm91Z2ggaW5mbGF0aW5nIHRoZSBwZXJjZW50YWdlIG9mIHdoaXRlIHBlb3BsZSBpbiB0aGUgYXJlYS4KCiMjIE5leHQgU3RlcHMKSW4gY29sbGFib3JhdGlvbiB3aXRoIEppcmF5IEF2ZWRpc2lhbiwgd2hvIGNvdW50ZXItYW5hbHl6ZWQgaW5jb21lIGFuZCBob3VzaW5nIGRhdGEgIHByZXNlbnRlZCBieSB0aGUgR293YW51cyBSYWNpYWwgRXF1aXR5IFJlcG9ydCwgd2UgaG9wZSB0byBwcmVzZW50IGEgam9pbnQgY291bnRlci1hbmFseXNpcyB0byB0aGUgZ2VuZXJhbCBwdWJsaWMgYW5kIHRoZSBOWUMgQ2l0eSBDb3VuY2lsLiBXZSBoYXZlIGNvbXBpbGVkIHJlY29tbWVuZGF0aW9ucyBmb3IgdGhlIFJhY2lhbCBFcXVpdHkgUmVwb3J0J3MgYXV0aG9ycyBhbmQgaW5jbHVkZSBhIHJvYnVzdCBjcml0aWNhbCBhbmFseXNpcyBvZiB0aGUgUmFjaWFsIEVxdWl0eSBSZXBvcnQgKG9mIHdoaWNoIHRoaXMgcXVhbnRpdGF0aXZlIGFuYWx5c2lzIGlzIGp1c3QgYSBzbWFsbCBwYXJ0KS4gV2UgaG9wZSB0byBpbnNwaXJlIGNvbW11bml0eSBtZW1iZXJzIHRvIGNvbGxlY3QgY291bnRlci1kYXRhIGFuZCBwdWJsaXNoIHRoZWlyIG93biByYWNpYWwgZXF1aXR5IHJlcG9ydHMsIHVzaW5nIGEgdmFyaWV0eSBvZiBkYXRhIHR5cGVzOiBzcGF0aWFsLCBxdWFsaXRhdGl2ZSwgYW5kIHBhcnRpY2lwYXRvcnksIGZvciBleGFtcGxlLiBPdXIgcHJvamVjdCB3YXMgc2VsZWN0ZWQgYXMgYSBwcmVzZW50YXRpb24gZm9yIHRoZSBbTllDIE9wZW4gRGF0YSBXZWVrIDIwMjJdKGh0dHBzOi8vd3d3Lm9wZW4tZGF0YS5ueWMvKSBjb25mZXJlbmNlLgoKSW4gZnV0dXJlIGl0ZXJhdGlvbnMgb2YgdGhpcyBwcm9qZWN0OgoKKiBJbiB0aGlzIHJlcG9ydCwgSSBmb2N1cyBvbiB0cnlpbmcgX25ld18gYm91bmRhcmllcyBmb3IgR293YW51cy4gSW4gYSBmdXR1cmUgdmVyc2lvbiwgSSB3b3VsZCBsaWtlIHRvIHJlLWNyZWF0ZSB0aGUgZXhhY3QgYm91bmRhcmllcyB1c2VkIGluIHRoZSBSYWNpYWwgRXF1aXR5IFJlcG9ydCBhbmQgcGxhY2UgdGhlbSBzaWRlIGJ5IHNpZGUgd2l0aCB0aGUgc2VsZWN0ZWQgdHJhY3RzIGJvdW5kYXJ5LiBTaW5jZSBjb21iaW5pbmcgQ29tbXVuaXR5IEJvYXJkIDYgYW5kIENvbW11bml0eSBCb2FyZCAyIGlzIGV2ZW4gbGFyZ2VyIHRoYW4gdGhlIHNjYWxlcyBJIHVzZWQsIEkgaW1hZ2luZSB0aGUgcmVzdWx0cyB3aWxsIGJlIHNpbWlsYXIgdG8gbWluZSwgaWYgbm90IG1vcmUgc3RyaWtpbmcuCgoqIEkgd291bGQgbGlrZSB0byBwdWJsaXNoIGEgc2VwYXJhdGUgdmVyc2lvbiBvZiB0aGlzIHByb2plY3QgdGhhdCBpcyBzcGVjaWZpY2FsbHkgbWFkZSB0byBiZSBhY2Nlc3NpYmxlIHRvIHNvbWVvbmUgd2l0aCBsaW1pdGVkIGRhdGEgb3IgUiBleHBlcmllbmNlLCBlbmFibGluZyB0aGVtIHRvIHJlcHJvZHVjZSBvdXIgcmVzdWx0cyBhbmQgc2ltaWxhciByZXN1bHRzIGZvciB0aGVpciBvd24gbmVpZ2hib3Job29kLgoKKiBJIHdvdWxkIGFsc28gbGlrZSB0byBpbmNsdWRlIHN0YXRpc3RpY2FsIGFuYWx5c2VzIHRoYXQgc2hvdyBpZiB0aGUgZGlmZmVyZW5jZXMgaW4gcG9wdWxhdGlvbiBiZXR3ZWVuIHRoZSBjb21tdW5pdHkgYm9hcmQgYW5kIHNlbGVjdGVkIHRyYWN0cyBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4KCjxocj4KIyMgTWV0aG9kcyBBcHBlbmRpeAoKIyMjIERhdGE6IDxicj4KKipQb3B1bGF0aW9uIGRlbW9ncmFwaGljczoqKiBVLlMuIENlbnN1cyBCdXJlYXUsICpQb3B1bGF0aW9uIGJ5IFJhY2UgYW5kIEV0aG5pY2l0eSwgMjAyMCBhbmQgMjAwMCBDZW5zdXMqIHJldHJpZXZlZCBOb3ZlbWJlciAyOSwgMjAyMSB1c2luZyBbdGlkeWNlbnN1c10oaHR0cHM6Ly93YWxrZXItZGF0YS5jb20vdGlkeWNlbnN1cy8pIFIgcGFja2FnZToKCiogVG90YWwgUG9wdWxhdGlvbgoqIFRvdGFsIE5vbi1IaXNwYW5pYyBXaGl0ZSBQb3B1bGF0aW9uCiogVG90YWwgTm9uLUhpc3BhbmljIEJsYWNrIFBvcHVsYXRpb24KKiBUb3RhbCBOb24tSGlzcGFuaWMgQXNpYW4gUG9wdWxhdGlvbgoqIFRvdGFsIEhpc3BhbmljL0xhdGlueCBQb3B1bGF0aW9uCiogT3RoZXIgUG9wdWxhdGlvbgoKIyMjIFNoYXBlIGZpbGVzOgoKKipDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhcyAoQ0RUQXMpKiogTllDIE9wZW4gRGF0YSwgKkNvbW11bml0eSBEaXN0cmljdCBUYWJ1bGF0aW9uIEFyZWFzIDIwMjAqIHJldHJpZXZlZCBOb3ZlbWJlciAyOSwgMjAyMSB1c2luZyBbTllDIE9wZW4gRGF0YV0oaHR0cHM6Ly93d3cxLm55Yy5nb3Yvc2l0ZS9wbGFubmluZy9kYXRhLW1hcHMvb3Blbi1kYXRhL2NlbnN1cy1kb3dubG9hZC1tZXRhZGF0YS5wYWdlP3RhYj0yKSBzaGFwZSBmaWxlIGFuZCBpbXBvcnRlZCB3aXRoIFtzZl0oaHR0cHM6Ly9yLXNwYXRpYWwuZ2l0aHViLmlvL3NmLykgUiBwYWNrYWdlLgoKKipOZWlnaGJvcmhvb2QgVGFidWxhdGlvbiBBcmVhcyAoTlRBcykqKiBOWUMgT3BlbiBEYXRhLCAqTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYXMgMjAyMCogcmV0cmlldmVkIE5vdmVtYmVyIDI5LCAyMDIxIHVzaW5nIFtOWUMgT3BlbiBEYXRhXShodHRwczovL3d3dzEubnljLmdvdi9zaXRlL3BsYW5uaW5nL2RhdGEtbWFwcy9vcGVuLWRhdGEvY2Vuc3VzLWRvd25sb2FkLW1ldGFkYXRhLnBhZ2U/dGFiPTIpIHNoYXBlIGZpbGUgYW5kIGltcG9ydGVkIHdpdGggW3NmXShodHRwczovL3Itc3BhdGlhbC5naXRodWIuaW8vc2YvKSBSIHBhY2thZ2UuCgoqKlNlbGVjdGVkIENlbnN1cyBUcmFjdHMqKiBOWUMgT3BlbiBEYXRhLCAqS2luZ3MgQ291bnR5LCBOWSBDZW5zdXMgVHJhY3RzIDIwMjA6IDc3LCA3NSwgNzEsIDEyNywgMTE5LCAxMjEsIDExNyogcmV0cmlldmVkIE5vdmVtYmVyIDI5LCAyMDIxIHVzaW5nIFtOWUMgT3BlbiBEYXRhXShodHRwczovL3d3dzEubnljLmdvdi9zaXRlL3BsYW5uaW5nL2RhdGEtbWFwcy9vcGVuLWRhdGEvY2Vuc3VzLWRvd25sb2FkLW1ldGFkYXRhLnBhZ2U/dGFiPTIpIHNoYXBlIGZpbGUgYW5kIGltcG9ydGVkIHdpdGggW3NmXShodHRwczovL3Itc3BhdGlhbC5naXRodWIuaW8vc2YvKSBSIHBhY2thZ2UuCgoKIyMjIE1ldGhvZHM6IDxicj4KCioqVG90YWwgIk90aGVyIiBQb3B1bGF0aW9uKiogaXMgY2FsY3VsYXRlZCBhcyBhIHN1bSBvZiBDZW5zdXMgY2F0ZWdvcmllczoKCiogVG90YWwg4oCcQW1lcmljYW4gSW5kaWFuIGFuZCBBbGFza2EgTmF0aXZl4oCdCiogVG90YWwg4oCcTmF0aXZlIEhhd2FpaWFuIGFuZCBPdGhlciBQYWNpZmljIElzbGFuZGVy4oCdCiogVG90YWwg4oCcU29tZSBPdGhlciBSYWNlIGFsb25l4oCdCgoqKlRvdGFsIE5vbi1XaGl0ZSBQb3B1bGF0aW9uKiogaXMgY2FsY3VsYXRlZCBhcyBhIHN1bSBvZiBDZW5zdXMgY2F0ZWdvcmllczoKCiogVG90YWwgTm9uLUhpc3BhbmljIEJsYWNrCiogVG90YWwgTm9uLUhpc3BhbmljIEFzaWFuCiogVG90YWwgSGlzcGFuaWMvTGF0aW5vCiogVG90YWwgT3RoZXIgCgoqKkRlbW9ncmFwaGljIHByb3BvcnRpb25zKiogYXJlIGNhbGN1bGF0ZWQgYXMgdGhlIFRvdGFsIGRlbW9ncmFwaGljIHBvcHVsYXRpb24sIHN1Y2ggYXMgKlRvdGFsIE5vbi1IaXNwYW5pYyBXaGl0ZSwqIGRpdmlkZWQgYnkgKlRvdGFsIFBvcHVsYXRpb24uKiBUaGVzZSBwcm9wb3J0aW9ucyB3ZXJlIGNyZWF0ZWQgZm9yIGJvdGggMjAyMCBhbmQgMjAwMCBDZW5zdXMgZGF0YS4KCioqU3VtbWFyeSBzdGF0aXN0aWNzKiogZm9yIHRoZSBiYXIgY2hhcnRzIHdlcmUgY3JlYXRlZCBpbiBFeGNlbCBieSB1c2luZyBbd3JpdGV4bF0oaHR0cHM6Ly9jcmFuLnJzdHVkaW8uY29tL3dlYi9wYWNrYWdlcy93cml0ZXhsL3dyaXRleGwucGRmKSBSIHBhY2thZ2UuIEkgY29sbGF0ZWQgdGhlIGRlbW9ncmFwaGljIHByb3BvcnRpb24gZGF0YSBieSBjZW5zdXMgdHJhY3QgaW50byB0aGUgdGhyZWUgYm91bmRhcmllcyBkaXNjdXNzZWQgZm9yIDIwMDAgYW5kIDIwMjAgZGF0YS4gSSB0aGVuIGNyZWF0ZWQgdGhlIGF2ZXJhZ2VzIGZvciBlYWNoIGRlbW9ncmFwaGljIGNhdGVnb3J5IGluIEV4Y2VsIGFuZCByZS1pbXBvcnRlZCB0aGUgZGF0YSBpbnRvIFIgdGhyb3VnaCBbcmVhZHhsXShodHRwczovL3JlYWR4bC50aWR5dmVyc2Uub3JnLykgUiBwYWNrYWdlLgoKIyMjIyBOb3RlIG9uIGFuYWx5c2lzCkkgcHVsbGVkIGRhdGEgZnJvbSBldmVyeSBkZW1vZ3JhcGhpYyBncm91cCBjb2xsZWN0ZWQgYnkgdGhlIENlbnN1cywgYnV0IEkgZGVjaWRlZCB0byBmb2N1cyBvbiB0aGUgZm91ciBtb3N0IGZyZXF1ZW50IGRlbW9ncmFwaGljIGdyb3VwczogV2hpdGUsIEJsYWNrLCBIaXNwYW5pYy9MYXRpbm8sIGFuZCBhbiBhZ2dyZWdhdGVkICJOb24tV2hpdGUiIGNhdGVnb3J5LiBEYXRhIG9uIHRoZSBjYXRlZ29yeSBkZXNjcmliZWQgYnkgdGhlIENlbnN1cyBhcyAib3RoZXIsIiBhcyB3ZWxsIGFzICJPbmUgb3IgbW9yZSByYWNlcywiIGFuZCBBc2lhbiBwb3B1bGF0aW9ucyBjYW4gYmUgY2FsY3VsYXRlZCBpbiB0aGUgc2FtZSBmYXNoaW9uIGFzIG15IGFuYWx5c2VzLgoKIyMjIyBTb3VyY2VzCgoqIFtDb21tdW5pdHkgRGlzdHJpY3QgVGFidWxhdGlvbiBBcmVhXShodHRwczovL3d3dzEubnljLmdvdi9zaXRlL2Jyb29rbHluY2I2L2Fib3V0L21hcHMucGFnZSkKKiBbTmVpZ2hib3Job29kIFRhYnVsYXRpb24gQXJlYV0oaHR0cHM6Ly9kYXRhLmNpdHlvZm5ld3lvcmsudXMvQ2l0eS1Hb3Zlcm5tZW50LzIwMjAtTmVpZ2hib3Job29kLVRhYnVsYXRpb24tQXJlYXMtTlRBcy1NYXBwZWQvNGhmdC12MzU1KQoqIFtTZWxlY3RlZCBDZW5zdXMgVHJhY3RzXShodHRwczovL3d3dzIuY2Vuc3VzLmdvdi9nZW8vbWFwcy9EQzIwMjAvUEwyMC9zdDM2X255L2NlbnN1c3RyYWN0X21hcHMvYzM2MDQ3X2tpbmdzL0RDMjBDVF9DMzYwNDcucGRmKQoqIFtHb3dhbnVzIE5laWdoYm9yaG9vZCBQbGFuIE1hcF0oaHR0cHM6Ly93d3cxLm55Yy5nb3Yvc2l0ZS9wbGFubmluZy9wbGFucy9nb3dhbnVzL2dvd2FudXMucGFnZSkKKiBbR293YW51cyBOZWlnaGJvcmhvb2QgUGxhbl0oaHR0cHM6Ly93d3cxLm55Yy5nb3Yvc2l0ZS9wbGFubmluZy9wbGFucy9nb3dhbnVzL2dvd2FudXMtZnJhbWV3b3JrLnBhZ2UpCiogW0dvd2FudXMgUmFjaWFsIEVxdWl0eSBSZXBvcnRdKGh0dHBzOi8vY291bmNpbC5ueWMuZ292L2xhbmQtdXNlL3BsYW5zL2dvd2FudXMtbmVpZ2hib3Job29kLXBsYW4tcmFjaWFsLWVxdWl0eS1yZXBvcnQtb24taG91c2luZy1hbmQtb3Bwb3J0dW5pdHkvKQoqIFtJbnRybyAxNTcyLTIwMTktQl0oaHR0cHM6Ly9hZHZvY2F0ZS5ueWMuZ292L3ByZXNzL255Yy1jb3VuY2lsLXZvdGUtcmFjaWFsLWltcGFjdC1zdHVkeS1sZWdpc2xhdGlvbi1haW1lZC1maWdodGluZy1nZW50cmlmaWNhdGlvbi1mdW5kYW1lbnRhbGx5LWNoYW5naW5nLWxhbmQtdXNlLykKClRoaXMgcHJvamVjdCB3YXMgY29uZHVjdGVkIGJ5IEpvcmRhbiBQYWNrZXIgZm9yIERlc2lnbiBhbmQgVXJiYW4gRWNvbG9naWVzIE1ldGhvZHMgMSwgYSBjb3Vyc2Ugd2l0aGluIHRoZSBEZXNpZ24gYW5kIFVyYmFuIEVjb2xvZ2llcyBNLlMuIHByb2dyYW0gYXQgdGhlIFBhcnNvbnMgU2Nob29sIG9mIERlc2lnbiAtIFRoZSBOZXcgU2Nob29sLg==