Introduction
This analysis explores waste collection and recycling performance in
New York City (NYC) using data from the Department of Sanitation (DSNY).
The key objective is to analyze temporal and spatial trends in refuse
and recycling tonnage, focusing on boroughs and community districts. The
study also evaluates recycling rates and waste composition to identify
areas for improvement in waste diversion practices.
Research Questions:
How does waste collection and recycling performance vary across
NYC boroughs and community districts over time?
Which boroughs and community districts recycle the
most/least?
What actionable insights can be drawn to improve recycling
practices and waste diversion rates?
The findings will inform potential policies and strategies to enhance
waste management across NYC.
Methods
Data Source: The primary dataset was obtained from
NYC Open Data’s DSNY Monthly Tonnage dataset, which records monthly
tonnage of refuse and recyclable materials collected by the Department
of Sanitation across NYC’s boroughs and community districts.
Steps:
Data Cleaning: The dataset was cleaned and transformed to ensure
consistency and usability.
Temporal Analysis: Aggregated yearly trends in recycling and
refuse collection were examined.
Spatial Analysis: Borough-level and community district-level
analyses were conducted using geographic data.
Waste Composition: Waste types (e.g., refuse, paper,
metal/glass/plastic) were analyzed to understand their contributions to
total waste.
Visualization: Various graphs and maps were created to visualize
trends and spatial patterns.
Summary Tables
This section summarizes key statistics for selected community
districts and boroughs.
Selected Community Districts (District 2 and 13 across all
boroughs)
Borough-Level Summary
|
Borough
|
Total Refuse (Tons)
|
Total Recycling (Tons)
|
Recycling Rate (%)
|
|
Manhattan
|
15815196
|
3151949
|
16.62
|
|
Queens
|
24908660
|
4949664
|
16.58
|
|
Staten Island
|
6459843
|
1224458
|
15.93
|
|
Brooklyn
|
28217303
|
4917786
|
14.84
|
|
Bronx
|
14484778
|
2039472
|
12.34
|
Results:
Recycling rates vary significantly across boroughs, with
Manhattan leading and Bronx lagging.
Boroughs with higher recycling rates may have more effective
waste diversion programs or greater community participation.

Temporal Analysis
This section analyzes temporal trends in waste collection and
recycling tonnage across NYC boroughs over time.

The chart titled Total Recycling Trends by Borough
presents the total recycling tonnage (in tons) over time for each
borough in New York City from approximately 1990 to 2023. Here’s a
detailed analysis:
- Overall Trends
Peak Around 2000: All boroughs experienced a significant increase in
recycling tonnage during the late 1990s and peaked around 2000. This
likely corresponds to the implementation of stronger recycling programs
and initiatives in NYC.
Post-2000 Decline: Following the peak, there is a notable decline in
recycling tonnage across all boroughs, potentially due to policy
changes, reduced public participation, or fluctuations in waste
generation patterns.
Stabilization and Gradual Recovery: From around 2010 onwards,
recycling tonnage stabilizes, with some boroughs showing gradual
recovery and growth.
- Borough-Level Insights
Queens: Queens consistently leads in total recycling
tonnage over the years, reflecting strong community participation and
efficient recycling programs. The decline post-2000 is visible but less
severe compared to other boroughs.
Brooklyn: Brooklyn follows Queens in total recycling
tonnage, with similar trends but slightly lower figures. The recovery
post-2000 is more modest compared to Queens.
Manhattan: Manhattan demonstrates relatively high
recycling tonnage, but its recovery post-2000 is less pronounced
compared to Queens and Brooklyn. Manhattan’s dense population and high
waste generation might contribute to its consistent recycling
efforts.
Bronx: The Bronx has lower recycling tonnage
compared to Queens, Brooklyn, and Manhattan. Recycling tonnage shows a
steady increase until 2000, followed by a gradual decline and limited
recovery afterward.
Spatial Analysis
Total Refuse by Community District
This section examines the total refuse collected in each community
district using geospatial data and visualization. A map is created to
show the distribution of refuse across NYC.
Recycling Rates by Community District
This section focuses on the spatial patterns of recycling rates
across NYC community districts. A map for a selected year (2020)
visualizes district-level recycling performance.
Key Takeaways from Spatial Analysis
Total Refuse:
High refuse tonnage in Manhattan and Brooklyn reflects their
population density and commercial activity.
Staten Island districts produce significantly less refuse,
consistent with its lower population.
Recycling Rates:
Significant disparities exist, with Manhattan and Queens leading
and Bronx lagging.
Targeted interventions, such as infrastructure improvement and
community awareness programs, are needed for low-performing
districts.
Waste Composition
This section analyzes the proportion of waste types (refuse, paper,
metal/glass/plastic) across NYC boroughs.
The stacked bar chart displays the proportions of different types of
waste—refuse (excluding paper and MGP), paper, and metal/glass/plastic
(MGP)—as a percentage of the total waste generated by each borough. The
total height of each bar is normalized to 100%, representing the total
waste generated in that borough. The different colors indicate the
relative contribution of each waste type to the total waste.
The blue section (total_refuse_without_paper_mgp) is the largest
across all boroughs, indicating that the majority of waste is
non-recyclable refuse. This highlights the need for improving recycling
practices.
The green section (total_paper) and red section (total_mgp) represent
recyclable materials.
Manhattan and Queens have slightly higher proportions of recyclables
compared to Staten Island and the Bronx, suggesting better recycling
performance in those boroughs.
Even though Staten Island generates less waste overall, the
proportions of recyclable waste types (paper and MGP) are smaller
compared to other boroughs.
The Pie Charts allow a more detailed look at each borough individually,
making it easier to identify borough-specific trends.
Conclusion
This analysis highlights the multifaceted nature of waste management
in New York City, revealing not only borough-level disparities in
recycling performance but also the overarching dominance of
non-recyclable refuse in the city’s waste stream. While certain
boroughs, like Manhattan and Queens, show encouraging trends in
recycling efforts, the city as a whole still faces significant
challenges in transitioning towards a more sustainable and efficient
waste diversion system.
Addressing these challenges requires a coordinated strategy that
combines infrastructure improvement, targeted public awareness
campaigns, and innovative recycling policies. Boroughs lagging in
recycling rates, such as Staten Island and the Bronx, would benefit from
localized initiatives tailored to address their unique barriers to
participation.
Beyond these findings, the analysis underscores the importance of
integrating geospatial data and temporal trends into policy decisions.
These tools can help policymakers identify high-impact intervention
areas, measure the effectiveness of ongoing programs, and adapt
strategies dynamically.
Ultimately, the path forward for NYC lies in leveraging data-driven
insights to build an equitable, efficient, and sustainable waste
management system—one that minimizes environmental impact and maximizes
community engagement in recycling and waste diversion practices.
LS0tDQp0aXRsZTogIkFuYWx5c2lzIG9mIFdhc3RlIENvbGxlY3Rpb24gYW5kIFJlY3ljbGluZyBQZXJmb3JtYW5jZSBpbiBOZXcgWW9yayBDaXR5Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jOiB0cnVlDQogICAgdG9jX2RlcHRoOiAzDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBULA0KICAgICAgICAgICAgICAgICAgICAgIHF1aWV0bHkgPSBULA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGKQ0KYGBgDQojIyBJbnRyb2R1Y3Rpb24NCg0KVGhpcyBhbmFseXNpcyBleHBsb3JlcyB3YXN0ZSBjb2xsZWN0aW9uIGFuZCByZWN5Y2xpbmcgcGVyZm9ybWFuY2UgaW4gTmV3IFlvcmsgQ2l0eSAoTllDKSB1c2luZyBkYXRhIGZyb20gdGhlIERlcGFydG1lbnQgb2YgU2FuaXRhdGlvbiAoRFNOWSkuIFRoZSBrZXkgb2JqZWN0aXZlIGlzIHRvIGFuYWx5emUgdGVtcG9yYWwgYW5kIHNwYXRpYWwgdHJlbmRzIGluIHJlZnVzZSBhbmQgcmVjeWNsaW5nIHRvbm5hZ2UsIGZvY3VzaW5nIG9uIGJvcm91Z2hzIGFuZCBjb21tdW5pdHkgZGlzdHJpY3RzLiBUaGUgc3R1ZHkgYWxzbyBldmFsdWF0ZXMgcmVjeWNsaW5nIHJhdGVzIGFuZCB3YXN0ZSBjb21wb3NpdGlvbiB0byBpZGVudGlmeSBhcmVhcyBmb3IgaW1wcm92ZW1lbnQgaW4gd2FzdGUgZGl2ZXJzaW9uIHByYWN0aWNlcy4NCg0KKipSZXNlYXJjaCBRdWVzdGlvbnM6KioNCg0KMS4gSG93IGRvZXMgd2FzdGUgY29sbGVjdGlvbiBhbmQgcmVjeWNsaW5nIHBlcmZvcm1hbmNlIHZhcnkgYWNyb3NzIE5ZQyBib3JvdWdocyBhbmQgY29tbXVuaXR5IGRpc3RyaWN0cyBvdmVyIHRpbWU/DQoNCjIuIFdoaWNoIGJvcm91Z2hzIGFuZCBjb21tdW5pdHkgZGlzdHJpY3RzIHJlY3ljbGUgdGhlIG1vc3QvbGVhc3Q/DQoNCjMuIFdoYXQgYWN0aW9uYWJsZSBpbnNpZ2h0cyBjYW4gYmUgZHJhd24gdG8gaW1wcm92ZSByZWN5Y2xpbmcgcHJhY3RpY2VzIGFuZCB3YXN0ZSBkaXZlcnNpb24gcmF0ZXM/DQoNClRoZSBmaW5kaW5ncyB3aWxsIGluZm9ybSBwb3RlbnRpYWwgcG9saWNpZXMgYW5kIHN0cmF0ZWdpZXMgdG8gZW5oYW5jZSB3YXN0ZSBtYW5hZ2VtZW50IGFjcm9zcyBOWUMuDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShSU29jcmF0YSkNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KERUKQ0KbGlicmFyeSh0aWR5Y2Vuc3VzKQ0KbGlicmFyeShzZikNCmxpYnJhcnkoc2NhbGVzKQ0KbGlicmFyeSh2aXJpZGlzKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KHBsb3RseSkNCmBgYA0KIyMgTWV0aG9kcw0KDQoqKkRhdGEgU291cmNlOioqDQpUaGUgcHJpbWFyeSBkYXRhc2V0IHdhcyBvYnRhaW5lZCBmcm9tIE5ZQyBPcGVuIERhdGEncyBEU05ZIE1vbnRobHkgVG9ubmFnZSBkYXRhc2V0LCB3aGljaCByZWNvcmRzIG1vbnRobHkgdG9ubmFnZSBvZiByZWZ1c2UgYW5kIHJlY3ljbGFibGUgbWF0ZXJpYWxzIGNvbGxlY3RlZCBieSB0aGUgRGVwYXJ0bWVudCBvZiBTYW5pdGF0aW9uIGFjcm9zcyBOWUMncyBib3JvdWdocyBhbmQgY29tbXVuaXR5IGRpc3RyaWN0cy4NCg0KKipTdGVwczoqKg0KDQoxLiBEYXRhIENsZWFuaW5nOiBUaGUgZGF0YXNldCB3YXMgY2xlYW5lZCBhbmQgdHJhbnNmb3JtZWQgdG8gZW5zdXJlIGNvbnNpc3RlbmN5IGFuZCB1c2FiaWxpdHkuDQoNCjIuIFRlbXBvcmFsIEFuYWx5c2lzOiBBZ2dyZWdhdGVkIHllYXJseSB0cmVuZHMgaW4gcmVjeWNsaW5nIGFuZCByZWZ1c2UgY29sbGVjdGlvbiB3ZXJlIGV4YW1pbmVkLg0KDQozLiBTcGF0aWFsIEFuYWx5c2lzOiBCb3JvdWdoLWxldmVsIGFuZCBjb21tdW5pdHkgZGlzdHJpY3QtbGV2ZWwgYW5hbHlzZXMgd2VyZSBjb25kdWN0ZWQgdXNpbmcgZ2VvZ3JhcGhpYyBkYXRhLg0KDQo0LiBXYXN0ZSBDb21wb3NpdGlvbjogV2FzdGUgdHlwZXMgKGUuZy4sIHJlZnVzZSwgcGFwZXIsIG1ldGFsL2dsYXNzL3BsYXN0aWMpIHdlcmUgYW5hbHl6ZWQgdG8gdW5kZXJzdGFuZCB0aGVpciBjb250cmlidXRpb25zIHRvIHRvdGFsIHdhc3RlLg0KDQo1LiBWaXN1YWxpemF0aW9uOiBWYXJpb3VzIGdyYXBocyBhbmQgbWFwcyB3ZXJlIGNyZWF0ZWQgdG8gdmlzdWFsaXplIHRyZW5kcyBhbmQgc3BhdGlhbCBwYXR0ZXJucy4NCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0KYm9yb3MgPC0gc3RfcmVhZCgiQzovVXNlcnMvYXJvb2ovT25lRHJpdmUvRGVza3RvcC9jbGFzcyAxL3BhcnQyLTIwMjQxMDE0VDE0MTIxOFotMDAxL3BhcnQyL2RhdGEvcmF3L2dlby9Cb3JvdWdoIEJvdW5kYXJpZXMuZ2VvanNvbiIpDQoNCmNvbW11bml0eV9kaXN0cmljdHMgPC0gc3RfcmVhZCgiQzovVXNlcnMvYXJvb2ovT25lRHJpdmUvRGVza3RvcC9jbGFzcyAxL3BhcnQyLTIwMjQxMDE0VDE0MTIxOFotMDAxL3BhcnQyL2RhdGEvcmF3L2dlby9Db21tdW5pdHkgRGlzdHJpY3RzL2dlb19leHBvcnRfNTBmNjZkODAtNzgwMy00NjY0LWJkNTItMmIxNmY2NjlkOTUyLnNocCIpDQoNCmRhdGEgPC0gcmVhZC5zb2NyYXRhKCJodHRwczovL2RhdGEuY2l0eW9mbmV3eW9yay51cy9yZXNvdXJjZS9lYmI3LW12cDUuY3N2IikNCmBgYA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiMgRGF0YSBjbGVhbmluZyBhbmQgcHJlcGFyYXRpb24NCiMgVXNlIHNlcGFyYXRlKCkgdG8gc3BsaXQgdGhlICJtb250aCIgY29sdW1uDQpkc255X2RhdGEgPC0gZGF0YSB8Pg0KICBzZXBhcmF0ZShjb2wgPSBtb250aCwgaW50byA9IGMoInllYXIiLCAibW9udGgiKSwgc2VwID0gIiAvICIsIHJlbW92ZSA9IEZBTFNFICkgfD4NCiAgbXV0YXRlKA0KICAgIHllYXIgPSBhcy5udW1lcmljKHllYXIpLCAgICANCiAgICBtb250aCA9IGFzLm51bWVyaWMobW9udGgpLCAgDQogICAgcmVmdXNlID0gYXMubnVtZXJpYyhyZWZ1c2V0b25zY29sbGVjdGVkKSwNCiAgICBwYXBlciA9IGFzLm51bWVyaWMocGFwZXJ0b25zY29sbGVjdGVkKSwNCiAgICBtZXRhbF9nbGFzc19wbGFzdGljID0gYXMubnVtZXJpYyhtZ3B0b25zY29sbGVjdGVkKSwNCiAgICByZXNpZGVudGlhbF9vcmdhbmljID0gYXMubnVtZXJpYyhyZXNvcmdhbmljc3RvbnMpLA0KICAgIGNvbW11bml0eWRpc3RyaWN0ID0gYXMubnVtZXJpYyhjb21tdW5pdHlkaXN0cmljdCkpIA0KYGBgDQojIyBTdW1tYXJ5IFRhYmxlcw0KDQpUaGlzIHNlY3Rpb24gc3VtbWFyaXplcyBrZXkgc3RhdGlzdGljcyBmb3Igc2VsZWN0ZWQgY29tbXVuaXR5IGRpc3RyaWN0cyBhbmQgYm9yb3VnaHMuDQoNCioqU2VsZWN0ZWQgQ29tbXVuaXR5IERpc3RyaWN0cyAoRGlzdHJpY3QgMiBhbmQgMTMgYWNyb3NzIGFsbCBib3JvdWdocykqKg0KYGBge3IsIGVjaG89RkFMU0V9DQpzZWxlY3RlZF9kaXN0cmljdHMgPC0gZHNueV9kYXRhIHw+DQogIGZpbHRlcihjb21tdW5pdHlkaXN0cmljdCA9PSAyIHwgY29tbXVuaXR5ZGlzdHJpY3QgPT0gMTMpIHw+DQogIHNlbGVjdChjb21tdW5pdHlkaXN0cmljdCwgYm9yb3VnaCwgcGFwZXIsIG1ldGFsX2dsYXNzX3BsYXN0aWMsIHJlZnVzZSkgfD4NCiAgYXJyYW5nZShkZXNjKHBhcGVyKSkNCmRhdGF0YWJsZShzZWxlY3RlZF9kaXN0cmljdHMpDQpgYGANCg0KDQoqKkJvcm91Z2gtTGV2ZWwgU3VtbWFyeSoqDQpgYGB7ciwgZWNobz1GQUxTRX0NCmJvcm91Z2hfc3RhdHMgPC0gZHNueV9kYXRhIHw+DQogIGdyb3VwX2J5KGJvcm91Z2gpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICByZWN5Y2xpbmdfcmF0ZSA9IHJvdW5kKHRvdGFsX3JlY3ljbGluZyAvICh0b3RhbF9yZWZ1c2UgKyB0b3RhbF9yZWN5Y2xpbmcpICogMTAwLCAyKSl8Pg0KYXJyYW5nZShkZXNjKHJlY3ljbGluZ19yYXRlKSkNCg0KYm9yb3VnaF9zdGF0cyB8Pg0KICBrYWJsZSgNCiAgICBmb3JtYXQgPSAiaHRtbCIsIA0KICAgIGNvbC5uYW1lcyA9IGMoIkJvcm91Z2giLCAiVG90YWwgUmVmdXNlIChUb25zKSIsICJUb3RhbCBSZWN5Y2xpbmcgKFRvbnMpIiwgIlJlY3ljbGluZyBSYXRlICglKSIpLA0KICAgIGFsaWduID0gImMiKQ0KYGBgDQoqKlJlc3VsdHM6KioNCg0KKiBSZWN5Y2xpbmcgcmF0ZXMgdmFyeSBzaWduaWZpY2FudGx5IGFjcm9zcyBib3JvdWdocywgd2l0aCBNYW5oYXR0YW4gbGVhZGluZyBhbmQgQnJvbnggbGFnZ2luZy4NCg0KKiBCb3JvdWdocyB3aXRoIGhpZ2hlciByZWN5Y2xpbmcgcmF0ZXMgbWF5IGhhdmUgbW9yZSBlZmZlY3RpdmUgd2FzdGUgZGl2ZXJzaW9uIHByb2dyYW1zIG9yIGdyZWF0ZXIgY29tbXVuaXR5IHBhcnRpY2lwYXRpb24uDQpgYGB7ciwgZWNobz1GQUxTRX0NCmdncGxvdChib3JvdWdoX3N0YXRzLCBhZXMoeD1yZW9yZGVyKGJvcm91Z2gsIHJlY3ljbGluZ19yYXRlKSwgeT1yZWN5Y2xpbmdfcmF0ZSwgZmlsbD1ib3JvdWdoKSkgKw0KICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArDQogIGNvb3JkX2ZsaXAoKSArDQogIGxhYnModGl0bGUgPSAiUmVjeWNsaW5nIFJhdGVzIGJ5IEJvcm91Z2giLCB4ID0gIkJvcm91Z2giLCB5ID0gIlJlY3ljbGluZyBSYXRlICglKSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyMgVGVtcG9yYWwgQW5hbHlzaXMNCg0KVGhpcyBzZWN0aW9uIGFuYWx5emVzIHRlbXBvcmFsIHRyZW5kcyBpbiB3YXN0ZSBjb2xsZWN0aW9uIGFuZCByZWN5Y2xpbmcgdG9ubmFnZSBhY3Jvc3MgTllDIGJvcm91Z2hzIG92ZXIgdGltZS4NCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kd2FzdGVfdHJlbmRzIDwtIGRzbnlfZGF0YSB8Pg0KICBncm91cF9ieSh5ZWFyLCBib3JvdWdoKXw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKQ0KICApDQpnZ3Bsb3Qod2FzdGVfdHJlbmRzLCBhZXMoeCA9IHllYXIsIHkgPSB0b3RhbF9yZWN5Y2xpbmcsIGNvbG9yID0gYm9yb3VnaCwgZ3JvdXAgPSBib3JvdWdoKSkgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6Y29tbWEpICsNCiAgbGFicyh0aXRsZSA9ICJUb3RhbCBSZWN5Y2xpbmcgVHJlbmRzIGJ5IEJvcm91Z2giLCB4ID0gIlllYXIiLCB5ID0gIlRvdGFsIFJlY3ljbGluZyAoVG9ucykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNClRoZSBjaGFydCB0aXRsZWQgKipUb3RhbCBSZWN5Y2xpbmcgVHJlbmRzIGJ5IEJvcm91Z2gqKiBwcmVzZW50cyB0aGUgdG90YWwgcmVjeWNsaW5nIHRvbm5hZ2UgKGluIHRvbnMpIG92ZXIgdGltZSBmb3IgZWFjaCBib3JvdWdoIGluIE5ldyBZb3JrIENpdHkgZnJvbSBhcHByb3hpbWF0ZWx5IDE5OTAgdG8gMjAyMy4gSGVyZSdzIGEgZGV0YWlsZWQgYW5hbHlzaXM6DQoNCjEuIE92ZXJhbGwgVHJlbmRzDQoNClBlYWsgQXJvdW5kIDIwMDA6IEFsbCBib3JvdWdocyBleHBlcmllbmNlZCBhIHNpZ25pZmljYW50IGluY3JlYXNlIGluIHJlY3ljbGluZyB0b25uYWdlIGR1cmluZyB0aGUgbGF0ZSAxOTkwcyBhbmQgcGVha2VkIGFyb3VuZCAyMDAwLiBUaGlzIGxpa2VseSBjb3JyZXNwb25kcyB0byB0aGUgaW1wbGVtZW50YXRpb24gb2Ygc3Ryb25nZXIgcmVjeWNsaW5nIHByb2dyYW1zIGFuZCBpbml0aWF0aXZlcyBpbiBOWUMuDQoNClBvc3QtMjAwMCBEZWNsaW5lOiBGb2xsb3dpbmcgdGhlIHBlYWssIHRoZXJlIGlzIGEgbm90YWJsZSBkZWNsaW5lIGluIHJlY3ljbGluZyB0b25uYWdlIGFjcm9zcyBhbGwgYm9yb3VnaHMsIHBvdGVudGlhbGx5IGR1ZSB0byBwb2xpY3kgY2hhbmdlcywgcmVkdWNlZCBwdWJsaWMgcGFydGljaXBhdGlvbiwgb3IgZmx1Y3R1YXRpb25zIGluIHdhc3RlIGdlbmVyYXRpb24gcGF0dGVybnMuDQoNClN0YWJpbGl6YXRpb24gYW5kIEdyYWR1YWwgUmVjb3Zlcnk6IEZyb20gYXJvdW5kIDIwMTAgb253YXJkcywgcmVjeWNsaW5nIHRvbm5hZ2Ugc3RhYmlsaXplcywgd2l0aCBzb21lIGJvcm91Z2hzIHNob3dpbmcgZ3JhZHVhbCByZWNvdmVyeSBhbmQgZ3Jvd3RoLg0KDQoyLiBCb3JvdWdoLUxldmVsIEluc2lnaHRzDQoNCioqUXVlZW5zOioqDQpRdWVlbnMgY29uc2lzdGVudGx5IGxlYWRzIGluIHRvdGFsIHJlY3ljbGluZyB0b25uYWdlIG92ZXIgdGhlIHllYXJzLCByZWZsZWN0aW5nIHN0cm9uZyBjb21tdW5pdHkgcGFydGljaXBhdGlvbiBhbmQgZWZmaWNpZW50IHJlY3ljbGluZyBwcm9ncmFtcy4NClRoZSBkZWNsaW5lIHBvc3QtMjAwMCBpcyB2aXNpYmxlIGJ1dCBsZXNzIHNldmVyZSBjb21wYXJlZCB0byBvdGhlciBib3JvdWdocy4NCg0KKipCcm9va2x5bjoqKg0KQnJvb2tseW4gZm9sbG93cyBRdWVlbnMgaW4gdG90YWwgcmVjeWNsaW5nIHRvbm5hZ2UsIHdpdGggc2ltaWxhciB0cmVuZHMgYnV0IHNsaWdodGx5IGxvd2VyIGZpZ3VyZXMuDQpUaGUgcmVjb3ZlcnkgcG9zdC0yMDAwIGlzIG1vcmUgbW9kZXN0IGNvbXBhcmVkIHRvIFF1ZWVucy4NCg0KKipNYW5oYXR0YW46KioNCk1hbmhhdHRhbiBkZW1vbnN0cmF0ZXMgcmVsYXRpdmVseSBoaWdoIHJlY3ljbGluZyB0b25uYWdlLCBidXQgaXRzIHJlY292ZXJ5IHBvc3QtMjAwMCBpcyBsZXNzIHByb25vdW5jZWQgY29tcGFyZWQgdG8gUXVlZW5zIGFuZCBCcm9va2x5bi4NCk1hbmhhdHRhbidzIGRlbnNlIHBvcHVsYXRpb24gYW5kIGhpZ2ggd2FzdGUgZ2VuZXJhdGlvbiBtaWdodCBjb250cmlidXRlIHRvIGl0cyBjb25zaXN0ZW50IHJlY3ljbGluZyBlZmZvcnRzLg0KDQoqKkJyb254OioqDQpUaGUgQnJvbnggaGFzIGxvd2VyIHJlY3ljbGluZyB0b25uYWdlIGNvbXBhcmVkIHRvIFF1ZWVucywgQnJvb2tseW4sIGFuZCBNYW5oYXR0YW4uDQpSZWN5Y2xpbmcgdG9ubmFnZSBzaG93cyBhIHN0ZWFkeSBpbmNyZWFzZSB1bnRpbCAyMDAwLCBmb2xsb3dlZCBieSBhIGdyYWR1YWwgZGVjbGluZSBhbmQgbGltaXRlZCByZWNvdmVyeSBhZnRlcndhcmQuDQoNCiMjIFNwYXRpYWwgQW5hbHlzaXMNCg0KKipUb3RhbCBSZWZ1c2UgYnkgQ29tbXVuaXR5IERpc3RyaWN0KioNCg0KVGhpcyBzZWN0aW9uIGV4YW1pbmVzIHRoZSB0b3RhbCByZWZ1c2UgY29sbGVjdGVkIGluIGVhY2ggY29tbXVuaXR5IGRpc3RyaWN0IHVzaW5nIGdlb3NwYXRpYWwgZGF0YSBhbmQgdmlzdWFsaXphdGlvbi4gQSBtYXAgaXMgY3JlYXRlZCB0byBzaG93IHRoZSBkaXN0cmlidXRpb24gb2YgcmVmdXNlIGFjcm9zcyBOWUMuDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZHNueV9kYXRhYSA8LSBkc255X2RhdGEgfD4NCiAgbXV0YXRlKA0KICAgIGNvbW11bml0eWRpc3RyaWN0ID0gY2FzZV93aGVuKA0KICAgICAgYm9yb3VnaCA9PSAiTWFuaGF0dGFuIiB+IHBhc3RlMCgiMSIsIHNwcmludGYoIiUwMmQiLCBjb21tdW5pdHlkaXN0cmljdCkpLA0KICAgICAgYm9yb3VnaCA9PSAiQnJvbngiIH4gcGFzdGUwKCIyIiwgc3ByaW50ZigiJTAyZCIsIGNvbW11bml0eWRpc3RyaWN0KSksDQogICAgICBib3JvdWdoID09ICJCcm9va2x5biIgfiBwYXN0ZTAoIjMiLCBzcHJpbnRmKCIlMDJkIiwgY29tbXVuaXR5ZGlzdHJpY3QpKSwNCiAgICAgIGJvcm91Z2ggPT0gIlF1ZWVucyIgfiBwYXN0ZTAoIjQiLCBzcHJpbnRmKCIlMDJkIiwgY29tbXVuaXR5ZGlzdHJpY3QpKSwNCiAgICAgIGJvcm91Z2ggPT0gIlN0YXRlbiBJc2xhbmQiIH4gcGFzdGUwKCI1Iiwgc3ByaW50ZigiJTAyZCIsIGNvbW11bml0eWRpc3RyaWN0KSksDQogICAgICBUUlVFIH4gTkFfY2hhcmFjdGVyXyAgKSApDQoNCmRpc3RyaWN0X3JlZnVzZSA8LSBkc255X2RhdGFhIHw+DQogIGdyb3VwX2J5KGNvbW11bml0eWRpc3RyaWN0KSB8Pg0KICBzdW1tYXJpemUoDQogICAgdG90YWxfcmVmdXNlID0gc3VtKHJlZnVzZSwgbmEucm0gPSBUUlVFKQ0KICApDQoNCmRpc3RyaWN0X3JlZnVzZSA8LSBkaXN0cmljdF9yZWZ1c2UgfD4NCiAgbXV0YXRlKGNvbW11bml0eWRpc3RyaWN0ID0gYXMuY2hhcmFjdGVyKGNvbW11bml0eWRpc3RyaWN0KSkNCg0KY29tbXVuaXR5X2Rpc3RyaWN0cyA8LSBjb21tdW5pdHlfZGlzdHJpY3RzIHw+DQogIG11dGF0ZShib3JvX2NkID0gYXMuY2hhcmFjdGVyKGJvcm9fY2QpKQ0KDQpjb21tdW5pdHlfbWFwIDwtIGNvbW11bml0eV9kaXN0cmljdHMgfD4NCiAgbGVmdF9qb2luKGRpc3RyaWN0X3JlZnVzZSwgYnkgPSBjKCJib3JvX2NkIiA9ICJjb21tdW5pdHlkaXN0cmljdCIpKQ0KDQoNCm1hcF9wbG90IDwtIGdncGxvdCgpICsNCiAgIyBQbG90IGNvbW11bml0eSBkaXN0cmljdHMgd2l0aCB0b3RhbCByZWZ1c2UNCiAgZ2VvbV9zZihkYXRhID0gY29tbXVuaXR5X21hcCwgDQogICAgICAgICAgYWVzKGZpbGwgPSB0b3RhbF9yZWZ1c2UsIA0KICAgICAgICAgICAgICB0ZXh0ID0gcGFzdGUwKCJDb21tdW5pdHkgRGlzdHJpY3Q6ICIsIGJvcm9fY2QsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+VG90YWwgUmVmdXNlOiAiLCBzY2FsZXM6OmNvbW1hKHRvdGFsX3JlZnVzZSwgYWNjdXJhY3kgPSAxKSkpLCANCiAgICAgICAgICBjb2xvciA9ICJncmV5Iiwgc2l6ZSA9IDAuMDUpICsNCiAgZ2VvbV9zZihkYXRhID0gYm9yb3MsIA0KICAgICAgICAgIGNvbG9yID0gImJsYWNrIiwgZmlsbCA9IE5BLCBsd2QgPSAwLjIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2MobmFtZSA9ICJUb3RhbCBSZWZ1c2UgKFRvbnMpIiwgDQogICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IHNjYWxlczo6Y29tbWEsIA0KICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9ICJUb3RhbCBSZWZ1c2UgYnkgQ29tbXVuaXR5IERpc3RyaWN0IiwNCiAgICBzdWJ0aXRsZSA9ICJOZXcgWW9yayBDaXR5IiwNCiAgICBjYXB0aW9uID0gIlNvdXJjZTogRFNOWSBEYXRhIikNCg0KZ2dwbG90bHkobWFwX3Bsb3QsIHRvb2x0aXAgPSBjKCJib3JvX2NkIiwgInRvdGFsX3JlZnVzZSIpKQ0KDQpgYGANCg0KKipSZWN5Y2xpbmcgUmF0ZXMgYnkgQ29tbXVuaXR5IERpc3RyaWN0KioNCg0KVGhpcyBzZWN0aW9uIGZvY3VzZXMgb24gdGhlIHNwYXRpYWwgcGF0dGVybnMgb2YgcmVjeWNsaW5nIHJhdGVzIGFjcm9zcyBOWUMgY29tbXVuaXR5IGRpc3RyaWN0cy4gQSBtYXAgZm9yIGEgc2VsZWN0ZWQgeWVhciAoMjAyMCkgdmlzdWFsaXplcyBkaXN0cmljdC1sZXZlbCByZWN5Y2xpbmcgcGVyZm9ybWFuY2UuDQpgYGB7ciwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmNvbW11bml0eV90cmVuZHNfbWFwIDwtIGRzbnlfZGF0YWEgfD4NCiAgZ3JvdXBfYnkoY29tbXVuaXR5ZGlzdHJpY3QsIHllYXIpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9yZWZ1c2UgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpLA0KICAgIHRvdGFsX3JlY3ljbGluZyA9IHN1bShwYXBlciwgbWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICByZWN5Y2xpbmdfcmF0ZSA9IHJvdW5kKCh0b3RhbF9yZWN5Y2xpbmcgLyAodG90YWxfcmVmdXNlICsgdG90YWxfcmVjeWNsaW5nKSkgKiAxMDAsIDIpLA0KICAgIC5ncm91cHMgPSAiZHJvcCIpDQoNCmNvbW11bml0eV90cmVuZHNfbWFwIDwtIGNvbW11bml0eV90cmVuZHNfbWFwIHw+DQogIG11dGF0ZShjb21tdW5pdHlkaXN0cmljdCA9IGFzLmNoYXJhY3Rlcihjb21tdW5pdHlkaXN0cmljdCkpDQoNCmNvbW11bml0eV9kaXN0cmljdHMgPC0gY29tbXVuaXR5X2Rpc3RyaWN0cyB8Pg0KICBtdXRhdGUoYm9yb19jZCA9IGFzLmNoYXJhY3Rlcihib3JvX2NkKSkNCg0KY29tbXVuaXR5X21hcF90cmVuZHMgPC0gY29tbXVuaXR5X2Rpc3RyaWN0cyB8Pg0KICBsZWZ0X2pvaW4oY29tbXVuaXR5X3RyZW5kc19tYXAsIGJ5ID0gYygiYm9yb19jZCIgPSAiY29tbXVuaXR5ZGlzdHJpY3QiKSkNCg0Kc2VsZWN0ZWRfeWVhciA8LSAyMDIwDQpjb21tdW5pdHlfbWFwX3NlbGVjdGVkX3llYXIgPC0gY29tbXVuaXR5X21hcF90cmVuZHMgfD4NCiAgZmlsdGVyKHllYXIgPT0gc2VsZWN0ZWRfeWVhcikNCg0KcmVjeWNsaW5nX21hcCA8LSBnZ3Bsb3QoKSArDQogIGdlb21fc2YoZGF0YSA9IGNvbW11bml0eV9tYXBfc2VsZWN0ZWRfeWVhciwgDQogICAgICAgICAgYWVzKGZpbGwgPSByZWN5Y2xpbmdfcmF0ZSwgDQogICAgICAgICAgICAgIHRleHQgPSBwYXN0ZTAoIkNvbW11bml0eSBEaXN0cmljdDogIiwgYm9yb19jZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPlJlY3ljbGluZyBSYXRlOiAiLCByZWN5Y2xpbmdfcmF0ZSwgIiUiKSksIA0KICAgICAgICAgIGNvbG9yID0gImdyZXkiLCBzaXplID0gMC4wNSkgKw0KICBnZW9tX3NmKGRhdGEgPSBib3JvcywgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gTkEsIGx3ZCA9IDAuMikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhuYW1lID0gIlJlY3ljbGluZyBSYXRlICglKSIsIA0KICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KHNjYWxlID0gMSksIA0KICAgICAgICAgICAgICAgICAgICAgICBuYS52YWx1ZSA9ICJ0cmFuc3BhcmVudCIpICsNCiAgdGhlbWVfdm9pZCgpICsNCiAgbGFicygNCiAgICB0aXRsZSA9IHBhc3RlKCJSZWN5Y2xpbmcgUmF0ZSBieSBDb21tdW5pdHkgRGlzdHJpY3QgKCIsIHNlbGVjdGVkX3llYXIsICIpIiwgc2VwID0gIiIpLA0KICAgIHN1YnRpdGxlID0gIk5ldyBZb3JrIENpdHkiLA0KICAgIGNhcHRpb24gPSAiU291cmNlOiBEU05ZIERhdGEiKQ0KDQpnZ3Bsb3RseShyZWN5Y2xpbmdfbWFwLCB0b29sdGlwID0gYygidGV4dCIpKQ0KDQoNCmBgYA0KKipLZXkgVGFrZWF3YXlzIGZyb20gU3BhdGlhbCBBbmFseXNpcyoqDQoNClRvdGFsIFJlZnVzZToNCg0KKiBIaWdoIHJlZnVzZSB0b25uYWdlIGluIE1hbmhhdHRhbiBhbmQgQnJvb2tseW4gcmVmbGVjdHMgdGhlaXIgcG9wdWxhdGlvbiBkZW5zaXR5IGFuZCBjb21tZXJjaWFsIGFjdGl2aXR5Lg0KDQoqIFN0YXRlbiBJc2xhbmQgZGlzdHJpY3RzIHByb2R1Y2Ugc2lnbmlmaWNhbnRseSBsZXNzIHJlZnVzZSwgY29uc2lzdGVudCB3aXRoIGl0cyBsb3dlciBwb3B1bGF0aW9uLg0KDQpSZWN5Y2xpbmcgUmF0ZXM6DQoNCiogU2lnbmlmaWNhbnQgZGlzcGFyaXRpZXMgZXhpc3QsIHdpdGggTWFuaGF0dGFuIGFuZCBRdWVlbnMgbGVhZGluZyBhbmQgQnJvbnggbGFnZ2luZy4NCg0KKiBUYXJnZXRlZCBpbnRlcnZlbnRpb25zLCBzdWNoIGFzIGluZnJhc3RydWN0dXJlIGltcHJvdmVtZW50IGFuZCBjb21tdW5pdHkgYXdhcmVuZXNzIHByb2dyYW1zLCBhcmUgbmVlZGVkIGZvciBsb3ctcGVyZm9ybWluZyBkaXN0cmljdHMuDQoNCiMjIFdhc3RlIENvbXBvc2l0aW9uDQoNClRoaXMgc2VjdGlvbiBhbmFseXplcyB0aGUgcHJvcG9ydGlvbiBvZiB3YXN0ZSB0eXBlcyAocmVmdXNlLCBwYXBlciwgbWV0YWwvZ2xhc3MvcGxhc3RpYykgYWNyb3NzIE5ZQyBib3JvdWdocy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0Kd2FzdGVfY29tcG9zaXRpb24gPC0gZHNueV9kYXRhIHw+DQogIGdyb3VwX2J5KGJvcm91Z2gpIHw+DQogIHN1bW1hcml6ZSgNCiAgICB0b3RhbF9wYXBlciA9IHN1bShwYXBlciwgbmEucm0gPSBUUlVFKSwNCiAgICB0b3RhbF9tZ3AgPSBzdW0obWV0YWxfZ2xhc3NfcGxhc3RpYywgbmEucm0gPSBUUlVFKSwNCiAgICB0b3RhbF9yZWZ1c2Vfd2l0aG91dF9wYXBlcl9tZ3AgPSBzdW0ocmVmdXNlLCBuYS5ybSA9IFRSVUUpKSB8Pg0KICBwaXZvdF9sb25nZXIoDQogICAgY29scyA9IHN0YXJ0c193aXRoKCJ0b3RhbCIpLCANCiAgICBuYW1lc190byA9ICJ3YXN0ZV90eXBlIiwgDQogICAgdmFsdWVzX3RvID0gInRvbnMiKQ0KDQpnZ3Bsb3Qod2FzdGVfY29tcG9zaXRpb24sIGFlcyh4ID0gYm9yb3VnaCwgeSA9IHRvbnMsIGZpbGwgPSB3YXN0ZV90eXBlKSkgKw0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSAiZmlsbCIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudF9mb3JtYXQoKSkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIldhc3RlIENvbXBvc2l0aW9uIGJ5IEJvcm91Z2giLA0KICAgIHggPSAiQm9yb3VnaCIsDQogICAgeSA9ICJQcm9wb3J0aW9uIiwNCiAgICBmaWxsID0gIldhc3RlIFR5cGUiDQogICkgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KVGhlIHN0YWNrZWQgYmFyIGNoYXJ0IGRpc3BsYXlzIHRoZSBwcm9wb3J0aW9ucyBvZiBkaWZmZXJlbnQgdHlwZXMgb2Ygd2FzdGXigJRyZWZ1c2UgKGV4Y2x1ZGluZyBwYXBlciBhbmQgTUdQKSwgcGFwZXIsIGFuZCBtZXRhbC9nbGFzcy9wbGFzdGljIChNR1Ap4oCUYXMgYSBwZXJjZW50YWdlIG9mIHRoZSB0b3RhbCB3YXN0ZSBnZW5lcmF0ZWQgYnkgZWFjaCBib3JvdWdoLg0KVGhlIHRvdGFsIGhlaWdodCBvZiBlYWNoIGJhciBpcyBub3JtYWxpemVkIHRvIDEwMCUsIHJlcHJlc2VudGluZyB0aGUgdG90YWwgd2FzdGUgZ2VuZXJhdGVkIGluIHRoYXQgYm9yb3VnaC4gVGhlIGRpZmZlcmVudCBjb2xvcnMgaW5kaWNhdGUgdGhlIHJlbGF0aXZlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIHdhc3RlIHR5cGUgdG8gdGhlIHRvdGFsIHdhc3RlLg0KDQpUaGUgYmx1ZSBzZWN0aW9uICh0b3RhbF9yZWZ1c2Vfd2l0aG91dF9wYXBlcl9tZ3ApIGlzIHRoZSBsYXJnZXN0IGFjcm9zcyBhbGwgYm9yb3VnaHMsIGluZGljYXRpbmcgdGhhdCB0aGUgbWFqb3JpdHkgb2Ygd2FzdGUgaXMgbm9uLXJlY3ljbGFibGUgcmVmdXNlLiBUaGlzIGhpZ2hsaWdodHMgdGhlIG5lZWQgZm9yIGltcHJvdmluZyByZWN5Y2xpbmcgcHJhY3RpY2VzLg0KDQpUaGUgZ3JlZW4gc2VjdGlvbiAodG90YWxfcGFwZXIpIGFuZCByZWQgc2VjdGlvbiAodG90YWxfbWdwKSByZXByZXNlbnQgcmVjeWNsYWJsZSBtYXRlcmlhbHMuDQoNCk1hbmhhdHRhbiBhbmQgUXVlZW5zIGhhdmUgc2xpZ2h0bHkgaGlnaGVyIHByb3BvcnRpb25zIG9mIHJlY3ljbGFibGVzIGNvbXBhcmVkIHRvIFN0YXRlbiBJc2xhbmQgYW5kIHRoZSBCcm9ueCwgc3VnZ2VzdGluZyBiZXR0ZXIgcmVjeWNsaW5nIHBlcmZvcm1hbmNlIGluIHRob3NlIGJvcm91Z2hzLg0KDQpFdmVuIHRob3VnaCBTdGF0ZW4gSXNsYW5kIGdlbmVyYXRlcyBsZXNzIHdhc3RlIG92ZXJhbGwsIHRoZSBwcm9wb3J0aW9ucyBvZiByZWN5Y2xhYmxlIHdhc3RlIHR5cGVzIChwYXBlciBhbmQgTUdQKSBhcmUgc21hbGxlciBjb21wYXJlZCB0byBvdGhlciBib3JvdWdocy4NCmBgYHtyLCBlY2hvPUZBTFNFfQ0KZ2dwbG90KHdhc3RlX2NvbXBvc2l0aW9uLCBhZXMoeCA9ICIiLCB5ID0gdG9ucywgZmlsbCA9IHdhc3RlX3R5cGUpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCB3aWR0aCA9IDEpICsNCiAgY29vcmRfcG9sYXIodGhldGEgPSAieSIpICsNCiAgZmFjZXRfd3JhcCh+Ym9yb3VnaCkgKw0KICBsYWJzKA0KICAgIHRpdGxlID0gIldhc3RlIENvbXBvc2l0aW9uIGJ5IEJvcm91Z2ggKFBpZSBDaGFydHMpIiwNCiAgICB4ID0gTlVMTCwNCiAgICB5ID0gTlVMTCwNCiAgICBmaWxsID0gIldhc3RlIFR5cGUiDQogICkgKw0KICB0aGVtZV92b2lkKCkNCmBgYA0KVGhlIFBpZSBDaGFydHMgYWxsb3cgYSBtb3JlIGRldGFpbGVkIGxvb2sgYXQgZWFjaCBib3JvdWdoIGluZGl2aWR1YWxseSwgbWFraW5nIGl0IGVhc2llciB0byBpZGVudGlmeSBib3JvdWdoLXNwZWNpZmljIHRyZW5kcy4NCg0KIyMgQ29uY2x1c2lvbg0KVGhpcyBhbmFseXNpcyBoaWdobGlnaHRzIHRoZSBtdWx0aWZhY2V0ZWQgbmF0dXJlIG9mIHdhc3RlIG1hbmFnZW1lbnQgaW4gTmV3IFlvcmsgQ2l0eSwgcmV2ZWFsaW5nIG5vdCBvbmx5IGJvcm91Z2gtbGV2ZWwgZGlzcGFyaXRpZXMgaW4gcmVjeWNsaW5nIHBlcmZvcm1hbmNlIGJ1dCBhbHNvIHRoZSBvdmVyYXJjaGluZyBkb21pbmFuY2Ugb2Ygbm9uLXJlY3ljbGFibGUgcmVmdXNlIGluIHRoZSBjaXR5J3Mgd2FzdGUgc3RyZWFtLiBXaGlsZSBjZXJ0YWluIGJvcm91Z2hzLCBsaWtlIE1hbmhhdHRhbiBhbmQgUXVlZW5zLCBzaG93IGVuY291cmFnaW5nIHRyZW5kcyBpbiByZWN5Y2xpbmcgZWZmb3J0cywgdGhlIGNpdHkgYXMgYSB3aG9sZSBzdGlsbCBmYWNlcyBzaWduaWZpY2FudCBjaGFsbGVuZ2VzIGluIHRyYW5zaXRpb25pbmcgdG93YXJkcyBhIG1vcmUgc3VzdGFpbmFibGUgYW5kIGVmZmljaWVudCB3YXN0ZSBkaXZlcnNpb24gc3lzdGVtLg0KDQpBZGRyZXNzaW5nIHRoZXNlIGNoYWxsZW5nZXMgcmVxdWlyZXMgYSBjb29yZGluYXRlZCBzdHJhdGVneSB0aGF0IGNvbWJpbmVzIGluZnJhc3RydWN0dXJlIGltcHJvdmVtZW50LCB0YXJnZXRlZCBwdWJsaWMgYXdhcmVuZXNzIGNhbXBhaWducywgYW5kIGlubm92YXRpdmUgcmVjeWNsaW5nIHBvbGljaWVzLiBCb3JvdWdocyBsYWdnaW5nIGluIHJlY3ljbGluZyByYXRlcywgc3VjaCBhcyBTdGF0ZW4gSXNsYW5kIGFuZCB0aGUgQnJvbngsIHdvdWxkIGJlbmVmaXQgZnJvbSBsb2NhbGl6ZWQgaW5pdGlhdGl2ZXMgdGFpbG9yZWQgdG8gYWRkcmVzcyB0aGVpciB1bmlxdWUgYmFycmllcnMgdG8gcGFydGljaXBhdGlvbi4NCg0KQmV5b25kIHRoZXNlIGZpbmRpbmdzLCB0aGUgYW5hbHlzaXMgdW5kZXJzY29yZXMgdGhlIGltcG9ydGFuY2Ugb2YgaW50ZWdyYXRpbmcgZ2Vvc3BhdGlhbCBkYXRhIGFuZCB0ZW1wb3JhbCB0cmVuZHMgaW50byBwb2xpY3kgZGVjaXNpb25zLiBUaGVzZSB0b29scyBjYW4gaGVscCBwb2xpY3ltYWtlcnMgaWRlbnRpZnkgaGlnaC1pbXBhY3QgaW50ZXJ2ZW50aW9uIGFyZWFzLCBtZWFzdXJlIHRoZSBlZmZlY3RpdmVuZXNzIG9mIG9uZ29pbmcgcHJvZ3JhbXMsIGFuZCBhZGFwdCBzdHJhdGVnaWVzIGR5bmFtaWNhbGx5Lg0KDQpVbHRpbWF0ZWx5LCB0aGUgcGF0aCBmb3J3YXJkIGZvciBOWUMgbGllcyBpbiBsZXZlcmFnaW5nIGRhdGEtZHJpdmVuIGluc2lnaHRzIHRvIGJ1aWxkIGFuIGVxdWl0YWJsZSwgZWZmaWNpZW50LCBhbmQgc3VzdGFpbmFibGUgd2FzdGUgbWFuYWdlbWVudCBzeXN0ZW3igJRvbmUgdGhhdCBtaW5pbWl6ZXMgZW52aXJvbm1lbnRhbCBpbXBhY3QgYW5kIG1heGltaXplcyBjb21tdW5pdHkgZW5nYWdlbWVudCBpbiByZWN5Y2xpbmcgYW5kIHdhc3RlIGRpdmVyc2lvbiBwcmFjdGljZXMuDQoNCg==