Priority Analyses

Part 1: Global Pasture Area Has Peaked and Fallen

This section would be similar to the way the beginning of Chapter 2 is laid out now, explaining how pasture historically increased and recently began declining as production has continued increasing.

  • Global pasture area peaked in 2000 at 3301864 thousand hectares and steadily fell 2.23% to 3228200 in 2016.

  • *Add analysis about rate of annual decline since 2000 compared to rate of increase in the 16 years prior to 2000. `

  • This decline has not been homogenous across regions, but is nevertheless notable. As pasture area has declined, production of meat and milk products from grazing animals has increased 15 and 32%, respectively. (*Need to update values). This higlights a broad story of decoupling.

  • As importantly, it signifies that at least some regions of the world have seen absolute declines in pasture. These areas can provide insight in how to slow or reverse pasture expansion in regions and countries where pasture expansion poses the greatest threat .

Part 2: The Pressure to Expand Pasture Continues in Some Countries

197 codes from your data successfully matched countries in the map
12 codes from your data failed to match with a country code in the map
46 codes from the map weren't represented in your data
5 colours specified and 7 required, using interpolation to calculate colours

This section, with this and the next two graphs, highlights the “problem” - despite global improvements, there are still countries and regions where pasture is expnading today and where it may in the future with continued demand increases. This is in contrast to the current Chapter Structure where the question of future pasture declines, which the text describes as “the biggest question” is buried in section 1.2. Highlighting the problem up-front will give the reader a sense of why this is important, what the stakes are, and why they should keep reading to find potential solutions.

  • Recently, for instance, from 2000 to 2016, pasture has grown in some countries, while shrinking in others. Pasture has notably shrunk from earlier high levels almost across the world, including in countries like India and much of Europe The dramatic decline in Australia is not shown here since drop is so extreme. (See data limitations below in exploratory analysis).

  • However, pasture has expanded in the U.S., much of South America, pockets of Africa, and Kazhakstan. This highlights how although pasture expansion is not occuring in most parts of the world, it is neverthless an important threat to address in particular areas and worthy of readers’ attention.

  • Note: countries with a change (up or down) of less than 5,000 hectares are shown in white and Australia is omitted. Also, it is not immediately evident what the incrases in pasture in some areas reflect since reporting and classification can distort the data. In the U.S. for instance, As USDA notes, “between 2002 and 2012, total grazing land increased by 15 million acres…These changes were largely a result of a reclassification of most land formerly labeled as cropland pasture resulting from changes in the 2007 and 2012 Census of Agriculture questionnaire.”

  • Historically, increases in ruminant meat and milk consumption have driven large increases in production and pasture area. Total consumption of ruminant meat and milk has increased globally by 128 and 174 thousand tonnes, respectively, since 1961.

  • However, increases have been concentrated in particular countries and regions.

167 codes from your data successfully matched countries in the map
10 codes from your data failed to match with a country code in the map
76 codes from the map weren't represented in your data
3 colours specified and 6 required, using interpolation to calculate colours

  • Increases in beef meat consumption, the largest portion of global ruminant meat, appears to mostly be driven by the rapid rise in Eastern Asia (China), as well as the steady increase in South America (Especially Brazil). Per capita, beef consumption has recently risen most in South America including Brazil, as well as in parts of Western Africa, China, SE Asia and Kazhikstan. Without other changes, further rises in consumption could increase pasture expansion pressure.

  • Note: Likely need different format for area plot, maybe just showing top 5-7 regions that grew the most. Or could keep it with 4 graphs like this with each line labelled and have a 4th showing the global trend.

  • This section or the last one could include an updated version of Figure 9, showing forecasts for meat and milk demand. Ideally this would be a stacked area chart with 2 or 3 top consuming countries (like CHina) broken out to show how important their contributions are. Right afterward, whether its in this section or part 4, would follow the domestic production: consumption ratio chart (Figure 10), which highlights how trade is unlikely to meet increasing demand.

This provides a strong segue into discussing how important productivity improvements are.

Part 3: Productivity Improvements Can Mitigate & Reverse Expansion

This section would include several graphs (below) and analyses (mostly in the report already) that highlight the role of productivity in decreasing pressure on pasture expansion and meeting rising ruminant product demand where it is growing most rapidly. I think the text can be very similar to that in the reprot already, focusing on global trends (as dicussed in pages 11-14) and regional productivity trends (pages 17-21). This includes various values about pasture expansion, contraction, crop area used for feed, how much more productive the most productive coutnries are than low-productivity coutnries.

Joining, by = c("country", "year", "minor_group", "major_group")
Joining, by = c("country", "year", "minor_group", "major_group")

  • This demonstrates that the rate of improvement in meat and dairy production/unit pasture has been steadily improving, particularly in the areas where consumption is growing most - Asia and Africa, though less so in the Americas where pasture expansion is a problem. Though you might assume that milk is driving this trend, looking at the other graphs in the exploratory analyses on “Pasture per Production” illustrates that the trend just looking at meat or just looking at milk is similar to this one.

  • An alternative, which I would prefer, is to look just at recent productivity trends for sub-regions where consumption has been growing or pasture expanding such as South America, Western and Northern Africa, East Asia, SE Asia, and one reference region with high productivity such as N. America This would highlight how productivity is improving in low-productivity areas, but that it’s still not high compared to many countries and has lots of room for improvement.

  • Note: I could easily invert the axes and have this be production per hectare instead.

Increasing Yields in Low-Productivity Regions is Important

Ignoring 1 observationsIgnoring 1 observations
  • The writing here could largely be drawn from the existing report section on regional differences in yields (pages 17-21)

  • Although meat yields have grown globally, they are still low in many regions where meat demand has been growing fastest. Yields have have grown much less in most of Africa than elsewhere. And despite growing in Asia over 50%, they are still substantially below yield levels in places such as Northern America or much of Europe.

  • Additinally, yields growth in Africa has largely occured in Northern and Southern Africa, while they have stagnated in Middle, Eastern and Western Africa where consumption of meat is increasing. In Asia, a lot of the growth in yields was in Western Asia, while yields in East Asia, where a lot of the growth in demand is, have not grown much.

  • Similar trends are visible for cattle milk yields (see Exploratory analyses).

  • This indicates there is still substantial opportunity for yields to grow. Many regions have relatively low yields.

Plot: Feed Use Efficiency (from Report - Un-numbered Figure Page 20)

  • I need to replicate and add the Feed Use Efficiency graph.
  • THis graph highlights how one of the reason why yields are low is that many regions have low feed use efficiency levels compared to the most productive regions and countries….

Part 4: Increasing Yields in Pasture Expansion Hotspots Must be a Priority

  • This section would largely mirror the section in the report on forecasts, 1.2.
  • It would summarize how increasing demand and low yields could drive furhter pasture expansion in some countries or reverse global trends
  • If we dont include it in part 2, this seciton would include an updated Figure 9 from the report that shows OECD meat and milk forecasts for developing and developed countries,and the figure on meat consumption:production ratios, indicating that trade is unlikely to meet demand.
  • The key piece of this section though is an updated forecast graph (figure 11) based on the one in the report or one in an earlier memo James wrote that includes more forecasts. This highlights how productivity changes would affect global pasture area.
  • I would also like to add a new analysis that is a basic country-level pasture forecast. This would show how much pasture would increase/decrease in different countries if ruminant meat and milk consumption followed OECD-FAO forecasts (e.g. for 2025) and if production/ha pasture continued improving at current rates. The result would be a graph showing the top five or ten countries where pasture is expected to increase most (in absolute hectare terms) if productivity doesn’t accelerate. To segue to the next sections already in Chapter 2 (Section 1.3) on biodiversity etc., this graph could be a double bar chart, showing projected pasture expansion next to total forest area in the country.

Appendix: Recent Country Level CHanges in Production

197 codes from your data successfully matched countries in the map
13 codes from your data failed to match with a country code in the map
46 codes from the map weren't represented in your data
4 colours specified and 6 required, using interpolation to calculate colours

LS0tCnRpdGxlOiAiUHJpb3JpdHkgQW5hbHlzZXMgZm9yIFBhc3R1cmUiCm91dHB1dDogaHRtbF9ub3RlYm9vawpkYXRlOiAiTm92IDEzIiAKLS0tCiAgCmBgYHtyIGdsb2JhbF9vcHRpb25zLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojc2V0IGtuaXRyIGRpc3BsYXkgb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRSkKYGBgCgpgYGB7ciBTZXR1cH0KI0NPTU1FTlQgQkFDSyBJTiBBUyBORUVERUQgVE8gbmF2aWdhdGUgdG8gUGVhayBQYXN0dXJlIEZvbGRlciBiZWZvcmUgc3RhcnRpbmcKIyBzZXR3ZCgifi9Hb29nbGUgRHJpdmUgRmlsZSBTdHJlYW0vTXkgRHJpdmUvQlRJIFJlc2VhcmNoL0Zvb2QgJiBGYXJtaW5nL1BlYWsgUGFzdHVyZSIpCgojbG9hZCBwYWNrYWdlcyAKbGlicmFyeSgndGlkeXZlcnNlJykKbGlicmFyeSgnc2NhbGVzJykKbGlicmFyeSgncGxvdGx5JykKbGlicmFyeSgncndvcmxkbWFwJykKCiNzZXQgcnVsZXMgZm9yIGZvcm1hdHRpbmcgZ3JhcGhzCnBvaW50IDwtIGZvcm1hdF9mb3JtYXQoYmlnLm1hcmsgPSAiLCIsIGRlY2ltYWwubWFyayA9ICIuIiwgc2NpZW50aWZpYyA9IEZBTFNFKQpgYGAKCiMgUHJpb3JpdHkgQW5hbHlzZXMKCiMjIFBhcnQgMTogR2xvYmFsIFBhc3R1cmUgQXJlYSBIYXMgUGVha2VkIGFuZCBGYWxsZW4KYGBge3IgR2xvYmFsIFBhc3R1cmUgVHJlbmQgd2l0aG91dCBTdWRhbiBhbmQgQXVzdHJhbGlhIG5ldyB2YWx1ZXN9CiNjcmVhdGUgdGVtcG9yYXJ5IGRhdGEuZnJhbWUgd2l0aCBBdXN0cmFsaWEncyAyMDE1IGFuZCAyMDE2IHBhc3R1cmUgdmFsdWVzIGVxdWFsIHRvIDIwMTMgdmFsdWUKdGVtcCA8LSBkcGx5cjo6ZmlsdGVyKGxhbmRfYXJlYSwgaXRlbSA9PSJwYXN0dXJlIikKdGVtcCRhcmVhW3RlbXAkY291bnRyeT09IkF1c3RyYWxpYSIgJiB0ZW1wJHllYXIgJWluJSBjKDIwMTUsMjAxNildIDwtICBmaWx0ZXIobGFuZF9hcmVhLCBjb3VudHJ5PT0iQXVzdHJhbGlhIiwgeWVhcj09MjAxMywgaXRlbT09InBhc3R1cmUiKSRhcmVhCgojZmlsdGVyIG91dCBTdWRhbiBhbmQgQWdncmVnYXRlIGNvdW50cnkgZGF0YSB0byByZWdpb25hbCBsZXZlbAp0ZW1wIDwtIHRlbXAgJT4lIAogIGZpbHRlcihpdGVtID09ICJwYXN0dXJlIiwgIXN0cl9kZXRlY3QoY291bnRyeSwgIlN1ZGFuIikpICU+JQogIGRwbHlyOjpncm91cF9ieShpdGVtLCB5ZWFyLCBtYWpvcl9ncm91cCkgJT4lCiAgZHBseXI6OnN1bW1hcml6ZShhcmVhPXN1bShhcmVhKSkgJT4lIHVuZ3JvdXAoKQoKI2NyZWF0ZSBkYXRhZnJhbWUgb2Ygd29ybGQgcGFzdHVyZSBhcmVhCmdsb2JhbF9hcmVhIDwtIHN1bW1hcml6ZShncm91cF9ieSh0ZW1wLCB5ZWFyLCBpdGVtKSwgYXJlYT1zdW0oYXJlYSkpICU+JSBtdXRhdGUobWFqb3JfZ3JvdXA9IldvcmxkIikKCiNjb21iaW5lIGRhdGFmcmFtZXMgb2YgcmVnaW9uYWwgYW5kIGdsb2JhbCBhcmVhIGZvciBwbG90dGluZyBpZiBkZXNpcmVkCnRlbXBfZ2xvYmFsIDwtIGJpbmRfcm93cyh0ZW1wLCBnbG9iYWxfYXJlYSkKCiNwbG90Cmdsb2JhbF9hcmVhICU+JQogIGZpbHRlcih5ZWFyICVpbiUgYygxOTYxOjIwMTYpKSAlPiUKICBnZ3Bsb3QoKSArCiAgZ2VvbV9saW5lKGFlcyh4ID0geWVhciwgeSA9IGFyZWEpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcG9pbnQsIGxpbWl0cyA9IGMobWluKGdsb2JhbF9hcmVhJGFyZWEpLCBtYXgoZ2xvYmFsX2FyZWEkYXJlYSkpKSArCiAgbGFicyh0aXRsZSA9ICJHbG9iYWwgUGFzdHVyZSBBcmVhIEhhcyBTdGVhZGlseSBEZWNsaW5lZCBzaW5jZSAyMDAwIiwgY2FwdGlvbj0iU3VkYW4gT21pdHRlZC4gQXVzdHJhbGlhIDIwMTUtMjAxNiB2YWx1ZXMgc2V0IGVxdWFsIHRvIDIwMTMgdmFsdWUuIiwgCiAgICAgICB5ID0gIkdsb2JhbCBQYXN0dXJlIEFyZWEgKHRob3VzYW5kIGhhKSIpCgojY2FsY3VsYXRlICUgZGVjbGluZQpnbG9iYWxfcGFzdHVyZV9wZWFrIDwtIG1heChnbG9iYWxfYXJlYSRhcmVhKQpnbG9iYWxfcGFzdHVyZV9sYXRlc3QgPC0gZ2xvYmFsX2FyZWEkYXJlYVtnbG9iYWxfYXJlYSR5ZWFyPT1tYXgoZ2xvYmFsX2FyZWEkeWVhcildCmdsb2JhbF9wYXN0dXJlX3BjdF9mYWxsIDwtICgxLShnbG9iYWxfcGFzdHVyZV9sYXRlc3QvZ2xvYmFsX3Bhc3R1cmVfcGVhaykpKjEwMApgYGAKVGhpcyBzZWN0aW9uIHdvdWxkIGJlIHNpbWlsYXIgdG8gdGhlIHdheSB0aGUgYmVnaW5uaW5nIG9mIENoYXB0ZXIgMiBpcyBsYWlkIG91dCBub3csIGV4cGxhaW5pbmcgaG93IHBhc3R1cmUgaGlzdG9yaWNhbGx5IGluY3JlYXNlZCBhbmQgcmVjZW50bHkgYmVnYW4gZGVjbGluaW5nIGFzIHByb2R1Y3Rpb24gaGFzIGNvbnRpbnVlZCBpbmNyZWFzaW5nLiAKCi0gR2xvYmFsIHBhc3R1cmUgYXJlYSBwZWFrZWQgaW4gMjAwMCBhdCBgciBwcmV0dHlOdW0oZ2xvYmFsX3Bhc3R1cmVfcGVhayxmb3JtYXQ9ImQiKWAgdGhvdXNhbmQgaGVjdGFyZXMgYW5kIHN0ZWFkaWx5IGZlbGwgYHIgcm91bmQoZ2xvYmFsX3Bhc3R1cmVfcGN0X2ZhbGwsMilgJSB0byBgciBwcmV0dHlOdW0oZ2xvYmFsX3Bhc3R1cmVfbGF0ZXN0LCBmb3JtYXQ9ImQiKWAgaW4gYHIgbWF4KGdsb2JhbF9hcmVhJHllYXIpYC4gIAoKLSAqQWRkIGFuYWx5c2lzIGFib3V0IHJhdGUgb2YgYW5udWFsIGRlY2xpbmUgc2luY2UgMjAwMCBjb21wYXJlZCB0byByYXRlIG9mIGluY3JlYXNlIGluIHRoZSAxNiB5ZWFycyBwcmlvciB0byAyMDAwLiAgIGAKCi0gVGhpcyBkZWNsaW5lIGhhcyBub3QgYmVlbiBob21vZ2Vub3VzIGFjcm9zcyByZWdpb25zLCBidXQgaXMgbmV2ZXJ0aGVsZXNzIG5vdGFibGUuIEFzIHBhc3R1cmUgYXJlYSBoYXMgZGVjbGluZWQsIHByb2R1Y3Rpb24gb2YgbWVhdCBhbmQgbWlsayBwcm9kdWN0cyBmcm9tIGdyYXppbmcgYW5pbWFscyBoYXMgaW5jcmVhc2VkIDE1IGFuZCAzMiUsIHJlc3BlY3RpdmVseS4gKCpOZWVkIHRvIHVwZGF0ZSB2YWx1ZXMpLiBUaGlzIGhpZ2xpZ2h0cyBhIGJyb2FkIHN0b3J5IG9mIGRlY291cGxpbmcuCgotIEFzIGltcG9ydGFudGx5LCBpdCBzaWduaWZpZXMgdGhhdCBhdCBsZWFzdCBzb21lIHJlZ2lvbnMgb2YgdGhlIHdvcmxkIGhhdmUgc2VlbiBhYnNvbHV0ZSBkZWNsaW5lcyBpbiBwYXN0dXJlLiBUaGVzZSBhcmVhcyBjYW4gcHJvdmlkZSBpbnNpZ2h0IGluIGhvdyB0byBzbG93IG9yIHJldmVyc2UgcGFzdHVyZSBleHBhbnNpb24gaW4gcmVnaW9ucyBhbmQgY291bnRyaWVzIHdoZXJlIHBhc3R1cmUgZXhwYW5zaW9uIHBvc2VzIHRoZSBncmVhdGVzdCB0aHJlYXQgLiAgCgojIyBQYXJ0IDI6IFRoZSBQcmVzc3VyZSB0byBFeHBhbmQgUGFzdHVyZSBDb250aW51ZXMgaW4gU29tZSBDb3VudHJpZXMKYGBge3IgUmVjZW50IFBhc3R1cmUgQ2hhbmdlIEhvdHNwb3RzIC0gUHJpb3JpdHl9CiNtYXAgY2hhbmdlIGluIHBhc3R1cmUgYXJlYSBiZXR3ZWVuIHR3byB5ZWFycyBieSBjb3VudHJ5IHRvIGlkZW50aWZ5IGhvdHNwb3RzIG9mIGV4cGFuc2lvbgoKI1JFVFVSTiAgI21vdmUgdG8gY2xlYW5pbmcgZmlsZQpsYW5kX2FyZWEkY291bnRyeSA8LSByZWNvZGUobGFuZF9hcmVhJGNvdW50cnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUnVzc2lhbiBGZWRlcmF0aW9uIj0iUnVzc2lhIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2hpbmEsIG1haW5sYW5kIiA9ICJDaGluYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVTU1IiPSJSdXNzaWEiKQojRU5ECgp2aXogPC0gbGFuZF9hcmVhICU+JQogIGZpbHRlcihpdGVtPT0icGFzdHVyZSIsIHllYXIgJWluJSBjKDIwMDAsIDIwMTYpLCBjb3VudHJ5IT0iQXVzdHJhbGlhIikgJT4lCiAgc2VsZWN0KGNvdW50cnksIHllYXIsIGFyZWEpICU+JQogIHNwcmVhZChrZXkgPSB5ZWFyLCB2YWx1ZSA9IGFyZWEpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JSBzdW1tYXJpemUodmFsdWUgPSBgMjAxNmAtYDIwMDBgKSAlPiUKICBqb2luQ291bnRyeURhdGEyTWFwKGpvaW5Db2RlPSJOQU1FIiwgbmFtZUpvaW5Db2x1bW49ImNvdW50cnkiKQoKbWFwUGFyYW1zIDwtIG1hcENvdW50cnlEYXRhKHZpeiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lQ29sdW1uVG9QbG90PSJ2YWx1ZSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVGl0bGU9IkNoYW5nZSBpbiBQYXN0dXJlIEFyZWEgMjAwMC0yMDE2ICgxMDAwIGhhKSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2F0TWV0aG9kID0gYygtMjAwMDAsLTEwMDAwLC01MDAwLC01LDUsNTAwMCwxMDAwMCwxNTAwMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXJQYWxldHRlID0gYygiZGFyayBncmVlbiIsICJncmVlbiIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAicmVkIiksIGFkZExlZ2VuZCA9IEZBTFNFKSAKCmRvLmNhbGwoYWRkTWFwTGVnZW5kLCBjKG1hcFBhcmFtcywgbGVnZW5kTGFiZWxzPSJhbGwiLCBsZWdlbmRXaWR0aD0wLjUpKQoKYGBgClRoaXMgc2VjdGlvbiwgd2l0aCB0aGlzIGFuZCB0aGUgbmV4dCB0d28gZ3JhcGhzLCBoaWdobGlnaHRzIHRoZSAicHJvYmxlbSIgLSBkZXNwaXRlIGdsb2JhbCBpbXByb3ZlbWVudHMsIHRoZXJlIGFyZSBzdGlsbCBjb3VudHJpZXMgYW5kIHJlZ2lvbnMgd2hlcmUgcGFzdHVyZSBpcyBleHBuYWRpbmcgdG9kYXkgYW5kIHdoZXJlIGl0IG1heSBpbiB0aGUgZnV0dXJlIHdpdGggY29udGludWVkIGRlbWFuZCBpbmNyZWFzZXMuIFRoaXMgaXMgaW4gY29udHJhc3QgdG8gdGhlIGN1cnJlbnQgQ2hhcHRlciBTdHJ1Y3R1cmUgd2hlcmUgdGhlIHF1ZXN0aW9uIG9mIGZ1dHVyZSBwYXN0dXJlIGRlY2xpbmVzLCB3aGljaCB0aGUgdGV4dCBkZXNjcmliZXMgYXMgInRoZSBiaWdnZXN0IHF1ZXN0aW9uIiBpcyBidXJpZWQgaW4gc2VjdGlvbiAxLjIuIEhpZ2hsaWdodGluZyB0aGUgcHJvYmxlbSB1cC1mcm9udCB3aWxsIGdpdmUgdGhlIHJlYWRlciBhIHNlbnNlIG9mIHdoeSB0aGlzIGlzIGltcG9ydGFudCwgd2hhdCB0aGUgc3Rha2VzIGFyZSwgYW5kIHdoeSB0aGV5IHNob3VsZCBrZWVwIHJlYWRpbmcgdG8gZmluZCBwb3RlbnRpYWwgc29sdXRpb25zLgoKLSBSZWNlbnRseSwgZm9yIGluc3RhbmNlLCBmcm9tIDIwMDAgdG8gMjAxNiwgcGFzdHVyZSBoYXMgZ3Jvd24gaW4gc29tZSBjb3VudHJpZXMsIHdoaWxlIHNocmlua2luZyBpbiBvdGhlcnMuIFBhc3R1cmUgaGFzIG5vdGFibHkgc2hydW5rIGZyb20gZWFybGllciBoaWdoIGxldmVscyBhbG1vc3QgYWNyb3NzIHRoZSB3b3JsZCwgaW5jbHVkaW5nIGluIGNvdW50cmllcyBsaWtlIEluZGlhIGFuZCBtdWNoIG9mIEV1cm9wZSBUaGUgZHJhbWF0aWMgZGVjbGluZSBpbiBBdXN0cmFsaWEgaXMgbm90IHNob3duIGhlcmUgc2luY2UgZHJvcCBpcyBzbyBleHRyZW1lLiAoU2VlIGRhdGEgbGltaXRhdGlvbnMgYmVsb3cgaW4gZXhwbG9yYXRvcnkgYW5hbHlzaXMpLiAKCi0gSG93ZXZlciwgcGFzdHVyZSBoYXMgZXhwYW5kZWQgaW4gdGhlIFUuUy4sIG11Y2ggb2YgU291dGggQW1lcmljYSwgcG9ja2V0cyBvZiBBZnJpY2EsIGFuZCBLYXpoYWtzdGFuLiBUaGlzIGhpZ2hsaWdodHMgaG93IGFsdGhvdWdoIHBhc3R1cmUgZXhwYW5zaW9uIGlzIG5vdCBvY2N1cmluZyBpbiBtb3N0IHBhcnRzIG9mIHRoZSB3b3JsZCwgaXQgaXMgbmV2ZXJ0aGxlc3MgYW4gaW1wb3J0YW50IHRocmVhdCB0byBhZGRyZXNzIGluIHBhcnRpY3VsYXIgYXJlYXMgYW5kIHdvcnRoeSBvZiByZWFkZXJzJyBhdHRlbnRpb24uIAoKLSBOb3RlOiBjb3VudHJpZXMgd2l0aCBhIGNoYW5nZSAodXAgb3IgZG93bikgb2YgbGVzcyB0aGFuIDUsMDAwIGhlY3RhcmVzIGFyZSBzaG93biBpbiB3aGl0ZSBhbmQgQXVzdHJhbGlhIGlzIG9taXR0ZWQuIEFsc28sIGl0IGlzIG5vdCBpbW1lZGlhdGVseSBldmlkZW50IHdoYXQgdGhlIGluY3Jhc2VzIGluIHBhc3R1cmUgaW4gc29tZSBhcmVhcyByZWZsZWN0IHNpbmNlIHJlcG9ydGluZyBhbmQgY2xhc3NpZmljYXRpb24gY2FuIGRpc3RvcnQgdGhlIGRhdGEuIEluIHRoZSBVLlMuIGZvciBpbnN0YW5jZSwgQXMgVVNEQSBub3RlcywgICJiZXR3ZWVuIDIwMDIgYW5kIDIwMTIsIHRvdGFsIGdyYXppbmcgbGFuZCBpbmNyZWFzZWQgYnkgMTUgbWlsbGlvbiBhY3Jlcy4uLlRoZXNlIGNoYW5nZXMgd2VyZSBsYXJnZWx5IGEgcmVzdWx0IG9mIGEgcmVjbGFzc2lmaWNhdGlvbiBvZiBtb3N0IGxhbmQgZm9ybWVybHkgbGFiZWxlZCBhcyBjcm9wbGFuZCBwYXN0dXJlIHJlc3VsdGluZyBmcm9tIGNoYW5nZXMgaW4gdGhlIDIwMDcgYW5kIDIwMTIgQ2Vuc3VzIG9mIEFncmljdWx0dXJlIHF1ZXN0aW9ubmFpcmUuIiAKCgpgYGB7ciBUb3RhbCBDaGFuZ2UgaW4gQ29uc3VtcHRpb259Cm1lYXRfY29uc19jaGFuZ2UgPC0gY29uc3VtcHRpb25fZ2xvYmFsICU+JSAKZmlsdGVyKGl0ZW0gJWluJSBjKCJCb3ZpbmUgTWVhdCIsICJNdXR0b24gJiBHb2F0IE1lYXQiKSwgeWVhciAlaW4lIGMoMTk2MSwyMDEzKSkgJT4lCnNlbGVjdChpdGVtLCB5ZWFyLCBjb25zX3RvdGFsKSAlPiUKZ3JvdXBfYnkoeWVhcikgJT4lIHN1bW1hcml6ZSh0b3RhbD1zdW0oY29uc190b3RhbCwgbmEucm09VCkpICU+JQpzcHJlYWQoa2V5ID0geWVhciwgdmFsdWUgPSB0b3RhbCkgJT4lCm11dGF0ZShkaWZmX2Ficz0gYDIwMTNgLWAxOTYxYCwgZGlmZl9wY3Q9ICgoYDIwMTNgL2AxOTYxYCktMSkqMTAwKQoKbWlsa19jb25zX2NoYW5nZSA8LSBjb25zdW1wdGlvbl9nbG9iYWwgJT4lIApmaWx0ZXIoaXRlbSAlaW4lIGMoIkJ1dHRlciwgR2hlZSIsICJDaGVlc2UiLCAiQ3JlYW0iLCAiTWlsayAtIEV4Y2x1ZGluZyBCdXR0ZXIiKSwgeWVhciAlaW4lIGMoMTk2MSwyMDEzKSkgJT4lCnNlbGVjdChpdGVtLCB5ZWFyLCBjb25zX3RvdGFsKSAlPiUKZ3JvdXBfYnkoeWVhcikgJT4lIHN1bW1hcml6ZSh0b3RhbD1zdW0oY29uc190b3RhbCwgbmEucm09VCkpICU+JQpzcHJlYWQoa2V5ID0geWVhciwgdmFsdWUgPSB0b3RhbCkgJT4lCm11dGF0ZShkaWZmX2Ficz0gYDIwMTNgLWAxOTYxYCwgZGlmZl9wY3Q9ICgoYDIwMTNgL2AxOTYxYCktMSkqMTAwKQpgYGAKLSBIaXN0b3JpY2FsbHksIGluY3JlYXNlcyBpbiBydW1pbmFudCBtZWF0IGFuZCBtaWxrIGNvbnN1bXB0aW9uIGhhdmUgZHJpdmVuIGxhcmdlIGluY3JlYXNlcyBpbiBwcm9kdWN0aW9uIGFuZCBwYXN0dXJlIGFyZWEuIFRvdGFsIGNvbnN1bXB0aW9uIG9mIHJ1bWluYW50IG1lYXQgYW5kIG1pbGsgaGFzIGluY3JlYXNlZCBnbG9iYWxseSBieSBgciByb3VuZChtZWF0X2NvbnNfY2hhbmdlJGRpZmZfcGN0LDApYCBhbmQgYHIgcm91bmQobWlsa19jb25zX2NoYW5nZSRkaWZmX3BjdCwgMClgIHRob3VzYW5kIHRvbm5lcywgcmVzcGVjdGl2ZWx5LCBzaW5jZSAxOTYxLgoKLSBIb3dldmVyLCBpbmNyZWFzZXMgaGF2ZSBiZWVuIGNvbmNlbnRyYXRlZCBpbiBwYXJ0aWN1bGFyIGNvdW50cmllcyBhbmQgcmVnaW9ucy4KCgpgYGB7ciBNZWF0IENvbnN1bXB0aW9uIGJ5IENvdW50cnkgYW5kIFJlZ2lvbn0KI2ZpbHRlciB0byBiZWVmIGFuZCBtYXAgcmVnaW9uYWwgdHJlbmRzCmNvbnN1bXB0aW9uICU+JQpmaWx0ZXIoaXRlbT09IkJvdmluZSBNZWF0IiwgbWFqb3JfZ3JvdXAgJWluJSBjKCJBZnJpY2EiLCAiQW1lcmljYXMiLCAiQXNpYSIpKSAlPiUKZ3JvdXBfYnkobWFqb3JfZ3JvdXAsIG1pbm9yX2dyb3VwLCB5ZWFyKSAlPiUKc3VtbWFyaXplKHRvdGFsID0gc3VtKGNvbnNfdG90YWwpKSAlPiUKZ2dwbG90KCkgKwpnZW9tX2FyZWEoYWVzKHggPSB5ZWFyLCB5ID0gdG90YWwsIGdyb3VwPW1pbm9yX2dyb3VwLCBmaWxsPW1pbm9yX2dyb3VwKSkgKwpzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcG9pbnQpICsKbGFicyh0aXRsZSA9ICJSZWdpb25hbCBNZWF0IENvbnN1bXB0aW9uIiwgeSA9ICJDb25zdW1wdGlvbiBpbiAxMDAwIHRvbm5lcyIpICsKZmFjZXRfd3JhcCgufm1ham9yX2dyb3VwLCBuY29sPTIpCgojcmVjb2RlIGNvdW50cmllcyBmb3IgbWFwcGluZwpjb25zdW1wdGlvbl9tYXAgPC0gY29uc3VtcHRpb24KY29uc3VtcHRpb25fbWFwJGNvdW50cnkgPC0gYXMuZmFjdG9yKGNvbnN1bXB0aW9uX21hcCRjb3VudHJ5KQpjb25zdW1wdGlvbl9tYXAkY291bnRyeSA8LSByZWNvZGUoY29uc3VtcHRpb25fbWFwJGNvdW50cnksCiJSdXNzaWFuIEZlZGVyYXRpb24iPSJSdXNzaWEiLCAKIkNoaW5hLCBtYWlubGFuZCIgPSAiQ2hpbmEiLCAKIlVTU1IiPSJSdXNzaWEiKQoKI3Jlc2hhcGUgZGF0YSBmb3IgcGxvdHRpbmcgYW5kIG1hdGNoIHRvIG1hcCBjb3VudHJpZXMKdml6IDwtIGNvbnN1bXB0aW9uX21hcCAlPiUKZmlsdGVyKGl0ZW09PSJCb3ZpbmUgTWVhdCIsIHllYXIgJWluJSBjKDIwMDAsMjAxMykpICU+JSAgI2NhbiBjaG9vc2UgYW55IHllYXJzCnNlbGVjdChjb3VudHJ5LCB5ZWFyLCBjb25zPWNvbnNfcGNfY2FsKSAlPiUgI3JlbmFtZSB0byBtYWtlIGl0IGVhc2llciB0byBjaGFuZ2UKc3ByZWFkKGtleSA9IHllYXIsIHZhbHVlID0gY29ucykgJT4lCmdyb3VwX2J5KGNvdW50cnkpICU+JSBzdW1tYXJpemUodmFsdWUgPSBgMjAxM2AtYDIwMDBgKSAlPiUKam9pbkNvdW50cnlEYXRhMk1hcChqb2luQ29kZT0iTkFNRSIsIG5hbWVKb2luQ29sdW1uPSJjb3VudHJ5IikKCgojcGxvdAptYXBQYXJhbXMgPC0gbWFwQ291bnRyeURhdGEodml6LCBuYW1lQ29sdW1uVG9QbG90PSJ2YWx1ZSIsIAptYXBUaXRsZT0iQ2hhbmdlIGluIEJlZWYgQ29uc3VtcHRpb24gMjAwMC0yMDEzIChrY2FsL2NhcGl0YSkiLApjYXRNZXRob2QgPSBjKC0xMDAsLTUwLCAtMjUsMCwyNSw1MCwxMDApLApjb2xvdXJQYWxldHRlID0gYygiZGFyayBncmVlbiIsIndoaXRlIiwicmVkIiksCmFkZExlZ2VuZCA9IEZBTFNFKQoKZG8uY2FsbChhZGRNYXBMZWdlbmQsIGMobWFwUGFyYW1zLCBsZWdlbmRMYWJlbHM9ImFsbCIsIGxlZ2VuZFdpZHRoPTAuNSkpCgpgYGAKLSBJbmNyZWFzZXMgaW4gYmVlZiBtZWF0IGNvbnN1bXB0aW9uLCB0aGUgbGFyZ2VzdCBwb3J0aW9uIG9mIGdsb2JhbCBydW1pbmFudCBtZWF0LCBhcHBlYXJzIHRvIG1vc3RseSBiZSBkcml2ZW4gYnkgdGhlIHJhcGlkIHJpc2UgaW4gRWFzdGVybiBBc2lhIChDaGluYSksIGFzIHdlbGwgYXMgdGhlIHN0ZWFkeSBpbmNyZWFzZSBpbiBTb3V0aCBBbWVyaWNhIChFc3BlY2lhbGx5IEJyYXppbCkuIFBlciBjYXBpdGEsIGJlZWYgY29uc3VtcHRpb24gaGFzIHJlY2VudGx5IHJpc2VuIG1vc3QgaW4gU291dGggQW1lcmljYSBpbmNsdWRpbmcgQnJhemlsLCBhcyB3ZWxsIGFzIGluIHBhcnRzIG9mIFdlc3Rlcm4gQWZyaWNhLCBDaGluYSwgU0UgQXNpYSBhbmQgS2F6aGlrc3Rhbi4gV2l0aG91dCBvdGhlciBjaGFuZ2VzLCBmdXJ0aGVyIHJpc2VzIGluIGNvbnN1bXB0aW9uIGNvdWxkIGluY3JlYXNlIHBhc3R1cmUgZXhwYW5zaW9uIHByZXNzdXJlLgoKLSBOb3RlOiBMaWtlbHkgbmVlZCBkaWZmZXJlbnQgZm9ybWF0IGZvciBhcmVhIHBsb3QsIG1heWJlIGp1c3Qgc2hvd2luZyB0b3AgNS03IHJlZ2lvbnMgdGhhdCBncmV3IHRoZSBtb3N0LiBPciBjb3VsZCBrZWVwIGl0IHdpdGggNCBncmFwaHMgbGlrZSB0aGlzIHdpdGggZWFjaCBsaW5lIGxhYmVsbGVkIGFuZCBoYXZlIGEgNHRoIHNob3dpbmcgdGhlIGdsb2JhbCB0cmVuZC4KCgotIFRoaXMgc2VjdGlvbiBvciB0aGUgbGFzdCBvbmUgY291bGQgaW5jbHVkZSBhbiB1cGRhdGVkIHZlcnNpb24gb2YgRmlndXJlIDksIHNob3dpbmcgZm9yZWNhc3RzIGZvciBtZWF0IGFuZCBtaWxrIGRlbWFuZC4gSWRlYWxseSB0aGlzIHdvdWxkIGJlIGEgc3RhY2tlZCBhcmVhIGNoYXJ0IHdpdGggMiBvciAzIHRvcCBjb25zdW1pbmcgY291bnRyaWVzIChsaWtlIENIaW5hKSBicm9rZW4gb3V0IHRvIHNob3cgaG93IGltcG9ydGFudCB0aGVpciBjb250cmlidXRpb25zIGFyZS4gUmlnaHQgYWZ0ZXJ3YXJkLCB3aGV0aGVyIGl0cyBpbiB0aGlzIHNlY3Rpb24gb3IgcGFydCA0LCB3b3VsZCBmb2xsb3cgdGhlIGRvbWVzdGljIHByb2R1Y3Rpb246IGNvbnN1bXB0aW9uIHJhdGlvIGNoYXJ0IChGaWd1cmUgMTApLCB3aGljaCBoaWdobGlnaHRzIGhvdyB0cmFkZSBpcyB1bmxpa2VseSB0byBtZWV0IGluY3JlYXNpbmcgZGVtYW5kLgoKClRoaXMgcHJvdmlkZXMgYSBzdHJvbmcgc2VndWUgaW50byBkaXNjdXNzaW5nIGhvdyBpbXBvcnRhbnQgcHJvZHVjdGl2aXR5IGltcHJvdmVtZW50cyBhcmUuCgojIyBQYXJ0IDM6IFByb2R1Y3Rpdml0eSBJbXByb3ZlbWVudHMgQ2FuIE1pdGlnYXRlICYgUmV2ZXJzZSBFeHBhbnNpb24KVGhpcyBzZWN0aW9uIHdvdWxkIGluY2x1ZGUgc2V2ZXJhbCBncmFwaHMgKGJlbG93KSBhbmQgYW5hbHlzZXMgKG1vc3RseSBpbiB0aGUgcmVwb3J0IGFscmVhZHkpIHRoYXQgaGlnaGxpZ2h0IHRoZSByb2xlIG9mIHByb2R1Y3Rpdml0eSBpbiBkZWNyZWFzaW5nIHByZXNzdXJlIG9uIHBhc3R1cmUgZXhwYW5zaW9uIGFuZCBtZWV0aW5nIHJpc2luZyBydW1pbmFudCBwcm9kdWN0IGRlbWFuZCB3aGVyZSBpdCBpcyBncm93aW5nIG1vc3QgcmFwaWRseS4gSSB0aGluayB0aGUgdGV4dCBjYW4gYmUgdmVyeSBzaW1pbGFyIHRvIHRoYXQgaW4gdGhlIHJlcHJvdCBhbHJlYWR5LCBmb2N1c2luZyBvbiBnbG9iYWwgdHJlbmRzIChhcyBkaWN1c3NlZCBpbiBwYWdlcyAxMS0xNCkgYW5kIHJlZ2lvbmFsIHByb2R1Y3Rpdml0eSB0cmVuZHMgKHBhZ2VzIDE3LTIxKS4gIFRoaXMgaW5jbHVkZXMgdmFyaW91cyB2YWx1ZXMgYWJvdXQgcGFzdHVyZSBleHBhbnNpb24sIGNvbnRyYWN0aW9uLCBjcm9wIGFyZWEgdXNlZCBmb3IgZmVlZCwgaG93IG11Y2ggbW9yZSBwcm9kdWN0aXZlIHRoZSBtb3N0IHByb2R1Y3RpdmUgY291dG5yaWVzIGFyZSB0aGFuIGxvdy1wcm9kdWN0aXZpdHkgY291dG5yaWVzLiAKCmBgYHtyIFJlZ2lvbmFsIE1lYXQgYW5kIE1pbGsgUHJvZHVjdGlvbiBwZXIgUGFzdHVyZSBBcmVhIFByaW9ydHl9CiMjTU9WRSBUTyBQUkVQIEZJTEU/CiNzdW1tYXJpemUgYWxsIHJ1bWluYW50IG1lYXQKbWVhdF9zdW0gPC0gc3VtbWFyaXplKGdyb3VwX2J5KG1lYXRfcHJvZHVjdGlvbixjb3VudHJ5LHllYXIsbWlub3JfZ3JvdXAsIG1ham9yX2dyb3VwKSwgCm1faGVhZD1zdW0obV9oZWFkLCBuYS5ybT1UKSwgbV9wcm9kPXN1bShtX3Byb2QsIG5hLnJtPVQpKQoKI3N1bW1hcml6ZSBhbGwgcnVtaW5hbnQgbWlsawptaWxrX3N1bSA8LSBzdW1tYXJpemUoZ3JvdXBfYnkobWlsa19wcm9kdWN0aW9uLGNvdW50cnkseWVhcixtaW5vcl9ncm91cCwgbWFqb3JfZ3JvdXApLCAKZF9oZWFkPXN1bShkX2hlYWQsIG5hLnJtPVQpLCBkX3Byb2Q9c3VtKGRfcHJvZCwgbmEucm09VCkpCiNtZXJnZQptZWF0X21pbGsgPC0gbGVmdF9qb2luKG1lYXRfc3VtLCBtaWxrX3N1bSkgCgojc3VtIHVwIG1lYXQgYW5kIG1pbGsgcHJvZAptZWF0X21pbGskYWxsX3Byb2QgPC0gbWVhdF9taWxrJG1fcHJvZCArIG1lYXRfbWlsayRkX3Byb2QKCiNtZXJnZSBpbiBwYXN0dXJlIGFyZWEKbWVhdF9taWxrIDwtIGxlZnRfam9pbihtZWF0X21pbGssIGZpbHRlcihsYW5kX2FyZWEsaXRlbSA9PSAicGFzdHVyZSIpKQoKbWVhdF9taWxrX21ham9yX2dyb3VwIDwtIHN1bW1hcml6ZSgKZ3JvdXBfYnkobWVhdF9taWxrLCB5ZWFyLCBtYWpvcl9ncm91cCksIAphbGxfcHJvZCA9IHN1bShhcmVhLCBuYS5ybT1UKS9zdW0oYWxsX3Byb2QsIG5hLnJtPVQpLCAKbV9wcm9kID0gc3VtKGFyZWEsIG5hLnJtPVQpL3N1bShtX3Byb2QsIG5hLnJtPVQpLApkX3Byb2QgPSBzdW0oYXJlYSwgbmEucm09VCkvc3VtKGRfcHJvZCwgbmEucm09VCkpICU+JQpnYXRoZXIoa2V5ID0gcHJvZHVjdGlvbl90eXBlLCB2YWx1ZSA9IHZhbHVlLCBhbGxfcHJvZCwgbV9wcm9kLCBkX3Byb2QpCgptZWF0X21pbGtfbWFqb3JfZ3JvdXAkdmFsdWVfbm9ybSA8LSB3aXRoKG1lYXRfbWlsa19tYWpvcl9ncm91cCwgYXZlKHZhbHVlLCBwcm9kdWN0aW9uX3R5cGUsIG1ham9yX2dyb3VwLCBGVU4gPSBmdW5jdGlvbih4KSB4L3hbMV0pKSAjY3JlYXRlIGNvbHVtbiBmb3IgY2hhbmdlIGNvbXBhcmVkIHRvIDFzdCBvYnNlcnZhdGlvbiAKCiNFTkQ/CgojcGxvdAptZWF0X21pbGtfbWFqb3JfZ3JvdXAgJT4lCmZpbHRlcihwcm9kdWN0aW9uX3R5cGU9PSJhbGxfcHJvZCIsIG1ham9yX2dyb3VwIT0iRm9ybWVyIFNvdmlldCBVbmlvbiIpICU+JQpnZ3Bsb3QoKSArCmdlb21fbGluZShhZXMoeCA9IHllYXIsIHkgPSB2YWx1ZV9ub3JtLCBncm91cD1tYWpvcl9ncm91cCwgY29sb3I9bWFqb3JfZ3JvdXApKSArCnNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwb2ludCwgYnJlYWtzID0gc2VxKGZyb20gPSAxLjAsdG8gPSAwLjQsYnkgPSAtMC4xKSkgKwpsYWJzKHRpdGxlID0gIlBhc3R1cmUgQXJlYSBwZXIgVW5pdCBQcm9kdWN0aW9uIERlY2xpbmVkIGluIGFsbCBSZWdpb25zIiwgY2FwdGlvbiA9ICJGb3JtZXIgU292aWV0IFVuaW9uIE9taXR0ZWQiLCB5bGFiID0gIkNoYW5nZSBpbiBIZWN0YXJlcyBwZXIgS2cgTWVhdCArIE1pbGsgUHJvZHVjdGlvbiBmcm9tIEFsbCBSdW1pbmFudHMiKSAKYGBgCi0gVGhpcyBkZW1vbnN0cmF0ZXMgdGhhdCB0aGUgcmF0ZSBvZiBpbXByb3ZlbWVudCBpbiBtZWF0IGFuZCBkYWlyeSBwcm9kdWN0aW9uL3VuaXQgcGFzdHVyZSBoYXMgYmVlbiBzdGVhZGlseSBpbXByb3ZpbmcsIHBhcnRpY3VsYXJseSBpbiB0aGUgYXJlYXMgd2hlcmUgY29uc3VtcHRpb24gaXMgZ3Jvd2luZyBtb3N0IC0gQXNpYSBhbmQgQWZyaWNhLCB0aG91Z2ggbGVzcyBzbyBpbiB0aGUgQW1lcmljYXMgd2hlcmUgcGFzdHVyZSBleHBhbnNpb24gaXMgYSBwcm9ibGVtLiBUaG91Z2ggeW91IG1pZ2h0IGFzc3VtZSB0aGF0IG1pbGsgaXMgZHJpdmluZyB0aGlzIHRyZW5kLCBsb29raW5nIGF0IHRoZSBvdGhlciBncmFwaHMgaW4gdGhlIGV4cGxvcmF0b3J5IGFuYWx5c2VzIG9uICJQYXN0dXJlIHBlciBQcm9kdWN0aW9uIiBpbGx1c3RyYXRlcyB0aGF0IHRoZSB0cmVuZCBqdXN0IGxvb2tpbmcgYXQgbWVhdCBvciBqdXN0IGxvb2tpbmcgYXQgbWlsayBpcyBzaW1pbGFyIHRvIHRoaXMgb25lLgoKLSBBbiBhbHRlcm5hdGl2ZSwgd2hpY2ggSSB3b3VsZCBwcmVmZXIsIGlzIHRvIGxvb2sganVzdCBhdCByZWNlbnQgcHJvZHVjdGl2aXR5IHRyZW5kcyBmb3Igc3ViLXJlZ2lvbnMgd2hlcmUgY29uc3VtcHRpb24gaGFzIGJlZW4gZ3Jvd2luZyBvciBwYXN0dXJlIGV4cGFuZGluZyBzdWNoIGFzIFNvdXRoIEFtZXJpY2EsIFdlc3Rlcm4gYW5kIE5vcnRoZXJuIEFmcmljYSwgRWFzdCBBc2lhLCBTRSBBc2lhLCBhbmQgb25lIHJlZmVyZW5jZSByZWdpb24gd2l0aCBoaWdoIHByb2R1Y3Rpdml0eSBzdWNoIGFzIE4uIEFtZXJpY2EgVGhpcyB3b3VsZCBoaWdobGlnaHQgaG93IHByb2R1Y3Rpdml0eSBpcyBpbXByb3ZpbmcgaW4gbG93LXByb2R1Y3Rpdml0eSBhcmVhcywgYnV0IHRoYXQgaXQncyBzdGlsbCBub3QgaGlnaCBjb21wYXJlZCB0byBtYW55IGNvdW50cmllcyBhbmQgaGFzIGxvdHMgb2Ygcm9vbSBmb3IgaW1wcm92ZW1lbnQuICAgIAoKLSBOb3RlOiBJIGNvdWxkIGVhc2lseSBpbnZlcnQgdGhlIGF4ZXMgYW5kIGhhdmUgdGhpcyBiZSBwcm9kdWN0aW9uIHBlciBoZWN0YXJlIGluc3RlYWQuCgoKIyMjIEluY3JlYXNpbmcgWWllbGRzIGluIExvdy1Qcm9kdWN0aXZpdHkgUmVnaW9ucyBpcyBJbXBvcnRhbnQKCmBgYHtyIE1ham9yIFJlZ2lvbmFsIE1lYXQgWWllbGRzIC0gUHJpb3JpdHl9CiN3aGlsZSB3ZSBjb3VsZCBhZ2dyZWdhdGUgdXAgdGhlIGNvdW50cnkgbGV2ZWwgdmFsdWVzIHRvIHRoZSByZWdpb25hbCBsZXZlbCwgdGhlc2UgZG8gbm90IGFsaWduIHdpdGggRkFPIHJlZ2lvbmFsIHZhbHVlcyBmcm9tIHRoZWlyIHdlYnNpdGUuIFRoZXJlZm9yZSBJIHVzZSAgcmVnaW9uYWwgZGF0YSBkb3dubG9hZGVkIGZyb20gRkFPIGluc3RlYWQgYXMgZGV0YWlsZWQgaW4gdGhlIGNsZWFuX2FuZF9wcmVwX2ZpbGUuICAKCnlpZWxkX2R1bWJlbGwgPC1mdW5jdGlvbih4LCBhbmltYWwsIGZpcnN0X3lyLCBsYXN0X3lyKSB7CiAgdGVtcCA8LSB4ICU+JSBmaWx0ZXIoaXRlbT09YXMuY2hhcmFjdGVyKGFuaW1hbCksIHllYXIgJWluJSBjKGZpcnN0X3lyLGxhc3RfeXIpKSAlPiUKICAgIHNwcmVhZChrZXkgPSB5ZWFyLCB2YWx1ZT15aWVsZCkKICAKICBjb2xuYW1lcyh0ZW1wKVszOjRdIDwtIGMoImZpcnN0X3lyIiwgImxhc3RfeXIiKQogIAogIHZpeiA8LSBwbG90X2x5KHRlbXAsIGNvbG9yID0gSSgiZ3JheTgwIikpICU+JQogICAgYWRkX3NlZ21lbnRzKHggPSB+Zmlyc3RfeXIsIHhlbmQgPSB+YGxhc3RfeXJgLCB5ID0gfmNvdW50cnksIHllbmQgPSB+Y291bnRyeSwgc2hvd2xlZ2VuZCA9IEZBTFNFKSAlPiUKICAgIGFkZF9tYXJrZXJzKHggPSB+Zmlyc3RfeXIsIHkgPSB+Y291bnRyeSwgbmFtZSA9IGRlcGFyc2UoZmlyc3RfeXIpLCBjb2xvciA9IEkoInJlZCIpKSAlPiUKICAgIGFkZF9tYXJrZXJzKHggPSB+bGFzdF95ciwgeSA9IH5jb3VudHJ5LCBuYW1lID0gZGVwYXJzZShsYXN0X3lyKSwgY29sb3IgPSBJKCJncmVlbiIpKSAlPiUKICAgIGxheW91dCgKICAgICAgdGl0bGUgPSBwYXN0ZTAoIkNoYW5nZSBpbiAiLCBzdHJfdG9fdGl0bGUoYXMuY2hhcmFjdGVyKGFuaW1hbCkpLCAiIE1lYXQgWWllbGRzIiksCiAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICJZaWVsZHMgKGhnL2FuaW1hbCkiKSwKICAgICAgbWFyZ2luID0gbGlzdChsID0gNjUpKSAKICByZXR1cm4odml6KQp9CgojeWllbGRfZHVtYmVsbChtZWF0X3lpZWxkc19yZWdpb25hbF9tYWpvciwgImNhdHRsZSIsIDE5NjEsIDIwMTMpICAjY2FuIGNob29zZSBhbnkgYW5pbWFsIG9yIDIgeWVhcnMuCmBgYAoKCmBgYHtyIFJlZ2lvbmFsIE1pbm9yIE1lYXQgWWllbGRzIC0gUHJpb3JpdHl9CnlpZWxkX2R1bWJlbGwobWVhdF95aWVsZHNfcmVnaW9uYWxfbWlub3IsICJjYXR0bGUiLCAxOTYxLCAyMDEzKSAgI2NhbiBjaG9vc2UgYW55IHNpbmdsZSBhbmltYWwgb3IgMiB5ZWFycy4KYGBgCi0gVGhlIHdyaXRpbmcgaGVyZSBjb3VsZCBsYXJnZWx5IGJlIGRyYXduIGZyb20gdGhlIGV4aXN0aW5nIHJlcG9ydCBzZWN0aW9uIG9uIHJlZ2lvbmFsIGRpZmZlcmVuY2VzIGluIHlpZWxkcyAocGFnZXMgMTctMjEpCgotIEFsdGhvdWdoIG1lYXQgeWllbGRzIGhhdmUgZ3Jvd24gZ2xvYmFsbHksIHRoZXkgYXJlIHN0aWxsIGxvdyBpbiBtYW55IHJlZ2lvbnMgd2hlcmUgbWVhdCBkZW1hbmQgaGFzIGJlZW4gZ3Jvd2luZyBmYXN0ZXN0LiBZaWVsZHMgaGF2ZSBoYXZlIGdyb3duIG11Y2ggbGVzcyBpbiBtb3N0IG9mIEFmcmljYSB0aGFuIGVsc2V3aGVyZS4gQW5kIGRlc3BpdGUgZ3Jvd2luZyBpbiBBc2lhIG92ZXIgNTAlLCB0aGV5IGFyZSBzdGlsbCBzdWJzdGFudGlhbGx5IGJlbG93IHlpZWxkIGxldmVscyBpbiBwbGFjZXMgc3VjaCBhcyBOb3J0aGVybiBBbWVyaWNhIG9yIG11Y2ggb2YgRXVyb3BlLiAKCi0gQWRkaXRpbmFsbHksIHlpZWxkcyBncm93dGggaW4gQWZyaWNhIGhhcyBsYXJnZWx5IG9jY3VyZWQgaW4gTm9ydGhlcm4gYW5kIFNvdXRoZXJuIEFmcmljYSwgd2hpbGUgdGhleSBoYXZlIHN0YWduYXRlZCBpbiBNaWRkbGUsIEVhc3Rlcm4gYW5kIFdlc3Rlcm4gQWZyaWNhIHdoZXJlIGNvbnN1bXB0aW9uIG9mIG1lYXQgaXMgaW5jcmVhc2luZy4gSW4gQXNpYSwgYSBsb3Qgb2YgdGhlIGdyb3d0aCBpbiB5aWVsZHMgd2FzIGluIFdlc3Rlcm4gQXNpYSwgd2hpbGUgeWllbGRzIGluIEVhc3QgQXNpYSwgd2hlcmUgYSBsb3Qgb2YgdGhlIGdyb3d0aCBpbiBkZW1hbmQgaXMsIGhhdmUgbm90IGdyb3duIG11Y2guIAoKLSBTaW1pbGFyIHRyZW5kcyBhcmUgdmlzaWJsZSBmb3IgY2F0dGxlIG1pbGsgeWllbGRzIChzZWUgRXhwbG9yYXRvcnkgYW5hbHlzZXMpLiAKCi0gVGhpcyBpbmRpY2F0ZXMgdGhlcmUgaXMgc3RpbGwgc3Vic3RhbnRpYWwgb3Bwb3J0dW5pdHkgZm9yIHlpZWxkcyB0byBncm93LiBNYW55IHJlZ2lvbnMgaGF2ZSByZWxhdGl2ZWx5IGxvdyB5aWVsZHMuCgojIyMgUGxvdDogRmVlZCBVc2UgRWZmaWNpZW5jeSAgKGZyb20gUmVwb3J0IC0gVW4tbnVtYmVyZWQgRmlndXJlIFBhZ2UgMjApCiogSSBuZWVkIHRvIHJlcGxpY2F0ZSBhbmQgYWRkIHRoZSBGZWVkIFVzZSBFZmZpY2llbmN5IGdyYXBoLiAKLSBUSGlzIGdyYXBoIGhpZ2hsaWdodHMgaG93IG9uZSBvZiB0aGUgcmVhc29uIHdoeSB5aWVsZHMgYXJlIGxvdyBpcyB0aGF0IG1hbnkgcmVnaW9ucyBoYXZlIGxvdyBmZWVkIHVzZSBlZmZpY2llbmN5IGxldmVscyBjb21wYXJlZCB0byB0aGUgbW9zdCBwcm9kdWN0aXZlIHJlZ2lvbnMgYW5kIGNvdW50cmllcy4uLi4gCgoKIyMgUGFydCA0OiBJbmNyZWFzaW5nIFlpZWxkcyBpbiBQYXN0dXJlIEV4cGFuc2lvbiBIb3RzcG90cyBNdXN0IGJlIGEgUHJpb3JpdHkKLSBUaGlzIHNlY3Rpb24gd291bGQgbGFyZ2VseSBtaXJyb3IgdGhlIHNlY3Rpb24gaW4gdGhlIHJlcG9ydCBvbiBmb3JlY2FzdHMsIDEuMi4KLSBJdCB3b3VsZCBzdW1tYXJpemUgaG93IGluY3JlYXNpbmcgZGVtYW5kIGFuZCBsb3cgeWllbGRzIGNvdWxkIGRyaXZlIGZ1cmh0ZXIgcGFzdHVyZSBleHBhbnNpb24gaW4gc29tZSBjb3VudHJpZXMgb3IgcmV2ZXJzZSBnbG9iYWwgdHJlbmRzCi0gSWYgd2UgZG9udCBpbmNsdWRlIGl0IGluIHBhcnQgMiwgdGhpcyBzZWNpdG9uIHdvdWxkIGluY2x1ZGUgYW4gdXBkYXRlZCBGaWd1cmUgOSBmcm9tIHRoZSByZXBvcnQgdGhhdCBzaG93cyBPRUNEIG1lYXQgYW5kIG1pbGsgZm9yZWNhc3RzIGZvciBkZXZlbG9waW5nIGFuZCBkZXZlbG9wZWQgY291bnRyaWVzLGFuZCB0aGUgZmlndXJlIG9uIG1lYXQgY29uc3VtcHRpb246cHJvZHVjdGlvbiByYXRpb3MsIGluZGljYXRpbmcgdGhhdCB0cmFkZSBpcyB1bmxpa2VseSB0byBtZWV0IGRlbWFuZC4KLSBUaGUga2V5IHBpZWNlIG9mIHRoaXMgc2VjdGlvbiB0aG91Z2ggaXMgYW4gdXBkYXRlZCBmb3JlY2FzdCBncmFwaCAoZmlndXJlIDExKSBiYXNlZCBvbiB0aGUgb25lIGluIHRoZSByZXBvcnQgb3Igb25lIGluIGFuIGVhcmxpZXIgbWVtbyBKYW1lcyB3cm90ZSB0aGF0IGluY2x1ZGVzIG1vcmUgZm9yZWNhc3RzLiBUaGlzIGhpZ2hsaWdodHMgaG93IHByb2R1Y3Rpdml0eSBjaGFuZ2VzIHdvdWxkIGFmZmVjdCBnbG9iYWwgcGFzdHVyZSBhcmVhLgotIEkgd291bGQgYWxzbyBsaWtlIHRvIGFkZCBhIG5ldyBhbmFseXNpcyB0aGF0IGlzIGEgYmFzaWMgY291bnRyeS1sZXZlbCBwYXN0dXJlIGZvcmVjYXN0LiBUaGlzIHdvdWxkIHNob3cgaG93IG11Y2ggcGFzdHVyZSB3b3VsZCBpbmNyZWFzZS9kZWNyZWFzZSBpbiBkaWZmZXJlbnQgY291bnRyaWVzIGlmIHJ1bWluYW50IG1lYXQgYW5kIG1pbGsgY29uc3VtcHRpb24gZm9sbG93ZWQgT0VDRC1GQU8gZm9yZWNhc3RzIChlLmcuIGZvciAyMDI1KSBhbmQgaWYgcHJvZHVjdGlvbi9oYSBwYXN0dXJlIGNvbnRpbnVlZCBpbXByb3ZpbmcgYXQgY3VycmVudCByYXRlcy4gVGhlIHJlc3VsdCB3b3VsZCBiZSBhIGdyYXBoIHNob3dpbmcgdGhlIHRvcCBmaXZlIG9yIHRlbiBjb3VudHJpZXMgd2hlcmUgcGFzdHVyZSBpcyBleHBlY3RlZCB0byBpbmNyZWFzZSBtb3N0IChpbiBhYnNvbHV0ZSBoZWN0YXJlIHRlcm1zKSBpZiBwcm9kdWN0aXZpdHkgZG9lc24ndCBhY2NlbGVyYXRlLiBUbyBzZWd1ZSB0byB0aGUgbmV4dCBzZWN0aW9ucyBhbHJlYWR5IGluIENoYXB0ZXIgMiAoU2VjdGlvbiAxLjMpIG9uIGJpb2RpdmVyc2l0eSBldGMuLCB0aGlzIGdyYXBoIGNvdWxkIGJlIGEgZG91YmxlIGJhciBjaGFydCwgc2hvd2luZyBwcm9qZWN0ZWQgcGFzdHVyZSBleHBhbnNpb24gbmV4dCB0byB0b3RhbCBmb3Jlc3QgYXJlYSBpbiB0aGUgY291bnRyeS4KCgoKIyMgQXBwZW5kaXg6IFJlY2VudCBDb3VudHJ5IExldmVsIENIYW5nZXMgaW4gUHJvZHVjdGlvbiAKYGBge3J9CiNtYXAgY2hhbmdlIGluIHByb2R1Y3Rpb24gYmV0d2VlbiB0d28geWVhcnMgYnkgY291bnRyeSB0byBpZGVudGlmeSBob3RzcG90cyBvZiBleHBhbnNpb24KCiNSRVRVUk4gICNtb3ZlIHRvIGNsZWFuaW5nIGZpbGUKbWVhdF9wcm9kdWN0aW9uJGNvdW50cnkgPC0gcmVjb2RlKG1lYXRfcHJvZHVjdGlvbiRjb3VudHJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlJ1c3NpYW4gRmVkZXJhdGlvbiI9IlJ1c3NpYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNoaW5hLCBtYWlubGFuZCIgPSAiQ2hpbmEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVU1NSIj0iUnVzc2lhIikKI0VORAoKdml6IDwtIG1lYXRfcHJvZHVjdGlvbiAlPiUKICBmaWx0ZXIoaXRlbT09ImNhdHRsZSIsIHllYXIgJWluJSBjKDIwMDAsIDIwMTMpKSAlPiUgI2p1c3QgbWFwIGNhdHRsZSBwcm9kdWN0aW9uIGNoYW5nZSAKICBzZWxlY3QoY291bnRyeSwgeWVhciwgbV9wcm9kKSAlPiUgICNhbmFseXplIHRvbm5lcyBvZiBtZWF0IHByb2R1Y3Rpb24KICBzcHJlYWQoa2V5ID0geWVhciwgdmFsdWUgPSBtX3Byb2QpICU+JSAgCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIHN1bW1hcml6ZSh2YWx1ZSA9IChgMjAxM2AtYDIwMDBgKS8xMDAwMDApICU+JQogIGpvaW5Db3VudHJ5RGF0YTJNYXAoam9pbkNvZGU9Ik5BTUUiLCBuYW1lSm9pbkNvbHVtbj0iY291bnRyeSIpCgptYXBQYXJhbXMgPC0gbWFwQ291bnRyeURhdGEodml6LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVDb2x1bW5Ub1Bsb3Q9InZhbHVlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBUaXRsZT0iQ2hhbmdlIGluIENhdHRsZSBNZWF0IFByb2R1Y3Rpb24gMjAwMC0yMDEzIChodW5kcmVkIHRob3VzYW5kIHRvbm5lcykiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhdE1ldGhvZCA9IGMoLTEwLC01LDAsNSwxNSwyNSwzNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXJQYWxldHRlID0gYygiZGFyayBncmVlbiIsICJ3aGl0ZSIsICJvcmFuZ2UiLCAicmVkIiksIGFkZExlZ2VuZCA9IEZBTFNFKSAKCmRvLmNhbGwoYWRkTWFwTGVnZW5kLCBjKG1hcFBhcmFtcywgbGVnZW5kTGFiZWxzPSJhbGwiLCBsZWdlbmRXaWR0aD0wLjUpKQpgYGAKCg==