Introduction
Individuals across the globe are urged to slow the spread of COVID-19. Governments are implementing everything from mild shelter in place to extreme shoot them dead measures to control this global crisis.
All these efforts are in hopes of flattening the curve. According to this article, high peaks put a lot of pressure on health care systems which they struggle to respond to.
So what does this curve look like for my state of Virginia? I’ve seen a rising curve for the entire United States, but I’ve only seen the current number of cases for a particular day. I don’t know how this number compares to last week.
World O Meter and Bing’s Coronoavirus updates provide nice summaries, but neither of these web sites showed the trend of confirmed cases over time.
All I needed was the data. After countless searches, I stumbled upon the University of Virginia’s COVID-19 Surveillance Dashboard. It is a nice real-time dashboard that also allows one to download data. Upon inspection of the provided datasets, I found what I was looking for.
This personal project is my attempt to understand the COVID-19 curve and how the number of cases affects the shape of the curve.
Let’s get started.
Sample Data From Imported Files
| Name |
Region |
Last_Update |
Confirmed |
Deaths |
Recovered |
| Ningxia |
Mainland China |
2020-03-17 02:00:00 |
75 |
0 |
75 |
| Azerbaijan |
Azerbaijan |
2020-06-04 03:00:00 |
6260 |
76 |
3665 |
| Poland |
Poland |
2020-04-18 17:00:00 |
8742 |
347 |
981 |
| Guyana |
Guyana |
2020-04-18 00:00:00 |
63 |
6 |
9 |
| Angola |
Angola |
2020-05-01 03:00:00 |
27 |
2 |
7 |
| Nevada |
USA |
2020-06-01 03:00:00 |
8628 |
417 |
6316 |
| Mauritius |
Mauritius |
2020-05-29 03:00:00 |
334 |
10 |
322 |
| South Korea |
South Korea |
2020-05-30 12:00:00 |
11441 |
269 |
10398 |
| Belgium |
Belgium |
2020-02-18 15:00:00 |
1 |
0 |
1 |
| Jersey |
Jersey |
2020-03-14 18:00:00 |
2 |
0 |
0 |
After loading the datafile, we find the dataset contains 30599 records, 215 areas of interests with information dated from 2020-01-22 12:00:00 and 2020-06-10 10:00:00.
Globally, there are 7253278 confirmed COVID-19 cases, 411279 deaths, and 3349900 who recovered.
What does the curve look like for the US as a whole? This is the graphic we see in mainstream media. Currently there are 1985454 confirmed cases in the United States.

Seeing the big picture can be overwhelming. Let’s break it down by regions.




Fast rising curves identify those hot spots and priority regions. But what about those states that don’t show a steep rising curve? Are they of concern?
What does the Virginia curve show?


Summary of U.S. Areas of Interest
Summary of US Areas of Interest
| Name |
group |
Confirmed |
Deaths |
Recovered |
| Midwest |
| Illinois |
Midwest |
129212 |
6018 |
70558 |
| Michigan |
Midwest |
64998 |
5943 |
42041 |
| Ohio |
Midwest |
39163 |
2423 |
5090 |
| Indiana |
Midwest |
38033 |
2339 |
2159 |
| Minnesota |
Midwest |
28523 |
1228 |
24221 |
| Iowa |
Midwest |
22236 |
628 |
13514 |
| Wisconsin |
Midwest |
21308 |
661 |
14583 |
| Nebraska |
Midwest |
15918 |
189 |
7598 |
| Missouri |
Midwest |
15352 |
845 |
3511 |
| Kansas |
Midwest |
10609 |
237 |
5578 |
| South Dakota |
Midwest |
5523 |
68 |
4483 |
| North Dakota |
Midwest |
2901 |
72 |
2450 |
| Northeast |
| New York |
Northeast |
384561 |
30458 |
47715 |
| New Jersey |
Northeast |
164796 |
12303 |
3856 |
| Massachusetts |
Northeast |
103889 |
7408 |
78108 |
| Pennsylvania |
Northeast |
80870 |
6014 |
1369 |
| Connecticut |
Northeast |
44179 |
4097 |
63 |
| Rhode Island |
Northeast |
15691 |
808 |
1398 |
| Puerto Rico |
Northeast |
5185 |
142 |
850 |
| New Hampshire |
Northeast |
5132 |
294 |
3501 |
| Maine |
Northeast |
2606 |
100 |
1992 |
| Vermont |
Northeast |
1084 |
55 |
901 |
| US Virgin Islands |
Northeast |
71 |
6 |
63 |
| South |
| Texas |
South |
78130 |
1867 |
51140 |
| Florida |
South |
66000 |
2766 |
381 |
| Maryland |
South |
58904 |
2811 |
4279 |
| Georgia |
South |
53249 |
2285 |
340 |
| Virginia |
South |
51738 |
1497 |
6677 |
| Louisiana |
South |
43612 |
2957 |
33904 |
| North Carolina |
South |
37228 |
1068 |
23653 |
| Tennessee |
South |
27575 |
435 |
18017 |
| Alabama |
South |
21422 |
729 |
11395 |
| Mississippi |
South |
18123 |
847 |
11203 |
| South Carolina |
South |
15228 |
568 |
5076 |
| Kentucky |
South |
11708 |
477 |
3359 |
| Arkansas |
South |
10080 |
161 |
6875 |
| Delaware |
South |
10020 |
410 |
5888 |
| District of Columbia |
South |
9474 |
495 |
1143 |
| Oklahoma |
South |
7363 |
354 |
6080 |
| West Virginia |
South |
2179 |
84 |
1482 |
| West |
| California |
West |
137060 |
4753 |
22258 |
| Colorado |
West |
28354 |
1554 |
2404 |
| Arizona |
West |
28296 |
1076 |
174 |
| Washington |
West |
25048 |
1175 |
5156 |
| Utah |
West |
12559 |
127 |
4006 |
| Nevada |
West |
10045 |
446 |
7381 |
| New Mexico |
West |
9105 |
404 |
3699 |
| Oregon |
West |
4988 |
169 |
1894 |
| Idaho |
West |
3221 |
85 |
2509 |
| Wyoming |
West |
970 |
17 |
789 |
| Hawaii |
West |
682 |
17 |
621 |
| Alaska |
West |
573 |
11 |
389 |
| Montana |
West |
554 |
18 |
485 |
| Guam |
West |
180 |
5 |
143 |
| Northern Mariana Islands |
West |
30 |
2 |
16 |
| Note: |
|
There appears to be a discrepancy to how recoveries are recorded by state. Based upon Bing's COVID-19 stats, some of the recoveries are correct whereas others are not. |
States With Most Confirmed Cases
| Name |
# Confirmed Cases |
| New York |
384561 |
| New Jersey |
164796 |
| California |
137060 |
| Illinois |
129212 |
| Massachusetts |
103889 |
| Pennsylvania |
80870 |
| Texas |
78130 |
| Florida |
66000 |
| Michigan |
64998 |
| Maryland |
58904 |
States With The Largest Daily Change of Confirmed Cases
| Name |
Change In Number of Confirmed Cases From Yesterday |
| California |
3244 |
| Texas |
1667 |
| Florida |
1096 |
| Illinois |
797 |
| Georgia |
752 |
| North Carolina |
710 |
| New York |
668 |
| Arizona |
618 |
| Tennessee |
570 |
| Louisiana |
562 |
States With Most Deaths
| Name |
# Deaths |
| New York |
30458 |
| New Jersey |
12303 |
| Massachusetts |
7408 |
| Illinois |
6018 |
| Pennsylvania |
6014 |
| Michigan |
5943 |
| California |
4753 |
| Connecticut |
4097 |
| Louisiana |
2957 |
| Maryland |
2811 |
States With Most Recovered Cases
| Name |
# Recoveries |
| Massachusetts |
78108 |
| Illinois |
70558 |
| Texas |
51140 |
| New York |
47715 |
| Michigan |
42041 |
| Louisiana |
33904 |
| Minnesota |
24221 |
| North Carolina |
23653 |
| California |
22258 |
| Tennessee |
18017 |
| Note: |
|
Discrepancies found in how recoveries are recorded by state. |
A former colleague and Old Dominion University professor, Dr. Chuck Cartledge, provided valuable feedback on my inital attempt on analyzing this information. He also referred me to this insightful How To Tell If We’re Beating COVID-19 video.
Three key points were discussed 1) use a logarithmic scale, 2) focus on change, not absolute numbers, and 3) don’t plot against time.
Taking this into account, let’s take a look at Virginia again.
The following graphs plot the total number of confirmed cases on the x-axis (Confirmed column) and the daily change of confirmed cases (delta_confirmed column) on the y-axis.
Virginia COVID-19 Data
| Name |
Last_Update |
Confirmed |
Deaths |
Recovered |
delta_confirmed |
delta_deaths |
delta_recovered |
| Virginia |
2020-03-08 01:00:00 |
1 |
0 |
0 |
NA |
NA |
NA |
| Virginia |
2020-03-08 14:00:00 |
2 |
0 |
0 |
1 |
0 |
0 |
| Virginia |
2020-03-10 03:45:00 |
7 |
0 |
0 |
5 |
0 |
0 |
| Virginia |
2020-03-10 18:00:00 |
8 |
0 |
0 |
1 |
0 |
0 |
| Virginia |
2020-03-11 15:50:00 |
9 |
0 |
0 |
1 |
0 |
0 |
| Virginia |
2020-03-13 02:00:00 |
18 |
0 |
0 |
9 |
0 |
0 |
| Virginia |
2020-03-13 20:00:00 |
30 |
0 |
0 |
12 |
0 |
0 |
| Virginia |
2020-03-15 03:00:00 |
41 |
1 |
0 |
11 |
1 |
0 |
| Virginia |
2020-03-16 03:00:00 |
45 |
1 |
0 |
4 |
0 |
0 |
| Virginia |
2020-03-17 02:00:00 |
52 |
2 |
0 |
7 |
1 |
0 |
| Virginia |
2020-03-18 03:00:00 |
67 |
2 |
0 |
15 |
0 |
0 |
| Virginia |
2020-03-19 03:00:00 |
79 |
2 |
0 |
12 |
0 |
0 |
| Virginia |
2020-03-20 03:00:00 |
104 |
2 |
0 |
25 |
0 |
0 |
| Virginia |
2020-03-21 02:00:00 |
125 |
2 |
0 |
21 |
0 |
0 |
| Virginia |
2020-03-22 03:00:00 |
158 |
3 |
0 |
33 |
1 |
0 |
| Virginia |
2020-03-23 03:00:00 |
221 |
6 |
0 |
63 |
3 |
0 |
| Virginia |
2020-03-24 03:00:00 |
254 |
7 |
0 |
33 |
1 |
0 |
| Virginia |
2020-03-25 03:00:00 |
304 |
9 |
0 |
50 |
2 |
0 |
| Virginia |
2020-03-26 03:00:00 |
399 |
13 |
0 |
95 |
4 |
0 |
| Virginia |
2020-03-27 03:00:00 |
471 |
14 |
0 |
72 |
1 |
0 |
| Virginia |
2020-03-28 03:00:00 |
610 |
16 |
0 |
139 |
2 |
0 |
| Virginia |
2020-03-29 03:00:00 |
740 |
17 |
0 |
130 |
1 |
0 |
| Virginia |
2020-03-30 03:00:00 |
890 |
24 |
0 |
150 |
7 |
0 |
| Virginia |
2020-03-31 03:00:00 |
1020 |
25 |
0 |
130 |
1 |
0 |
| Virginia |
2020-04-01 03:00:00 |
1250 |
27 |
0 |
230 |
2 |
0 |
| Virginia |
2020-04-02 03:00:00 |
1486 |
35 |
0 |
236 |
8 |
0 |
| Virginia |
2020-04-03 03:00:00 |
1706 |
41 |
0 |
220 |
6 |
0 |
| Virginia |
2020-04-04 03:00:00 |
2012 |
47 |
0 |
306 |
6 |
0 |
| Virginia |
2020-04-05 03:00:00 |
2407 |
52 |
0 |
395 |
5 |
0 |
| Virginia |
2020-04-06 03:00:00 |
2640 |
52 |
0 |
233 |
0 |
0 |
| Virginia |
2020-04-07 03:00:00 |
2878 |
66 |
0 |
238 |
14 |
0 |
| Virginia |
2020-04-08 03:00:00 |
3335 |
66 |
2 |
457 |
0 |
2 |
| Virginia |
2020-04-09 03:00:00 |
3645 |
75 |
2 |
310 |
9 |
0 |
| Virginia |
2020-04-10 03:00:00 |
4042 |
109 |
2 |
397 |
34 |
0 |
| Virginia |
2020-04-11 03:00:00 |
4509 |
121 |
2 |
467 |
12 |
0 |
| Virginia |
2020-04-12 09:00:00 |
5077 |
130 |
2 |
568 |
9 |
0 |
| Virginia |
2020-04-13 03:00:00 |
5274 |
141 |
2 |
197 |
11 |
0 |
| Virginia |
2020-04-14 03:00:00 |
5747 |
149 |
2 |
473 |
8 |
0 |
| Virginia |
2020-04-15 03:00:00 |
6182 |
157 |
721 |
435 |
8 |
719 |
| Virginia |
2020-04-16 03:00:00 |
6500 |
195 |
721 |
318 |
38 |
0 |
| Virginia |
2020-04-17 03:00:00 |
6889 |
208 |
721 |
389 |
13 |
0 |
| Virginia |
2020-04-18 03:00:00 |
7491 |
231 |
721 |
602 |
23 |
0 |
| Virginia |
2020-04-19 03:00:00 |
8053 |
258 |
721 |
562 |
27 |
0 |
| Virginia |
2020-04-20 03:00:00 |
8542 |
277 |
721 |
489 |
19 |
0 |
| Virginia |
2020-04-21 03:00:00 |
8990 |
300 |
721 |
448 |
23 |
0 |
| Virginia |
2020-04-22 03:00:00 |
9630 |
324 |
721 |
640 |
24 |
0 |
| Virginia |
2020-04-23 03:00:00 |
10266 |
349 |
721 |
636 |
25 |
0 |
| Virginia |
2020-04-24 03:00:00 |
10998 |
373 |
721 |
732 |
24 |
0 |
| Virginia |
2020-04-25 03:00:00 |
11594 |
411 |
721 |
596 |
38 |
0 |
| Virginia |
2020-04-26 03:00:00 |
12366 |
437 |
721 |
772 |
26 |
0 |
| Virginia |
2020-04-27 03:00:00 |
12970 |
449 |
721 |
604 |
12 |
0 |
| Virginia |
2020-04-28 03:00:00 |
13538 |
460 |
721 |
568 |
11 |
0 |
| Virginia |
2020-04-29 03:00:00 |
14339 |
492 |
721 |
801 |
32 |
0 |
| Virginia |
2020-04-30 03:00:00 |
14962 |
522 |
721 |
623 |
30 |
0 |
| Virginia |
2020-05-01 03:00:00 |
15847 |
552 |
721 |
885 |
30 |
0 |
| Virginia |
2020-05-02 03:00:00 |
16902 |
581 |
721 |
1055 |
29 |
0 |
| Virginia |
2020-05-03 03:00:00 |
17738 |
617 |
721 |
836 |
36 |
0 |
| Virginia |
2020-05-04 03:00:00 |
18672 |
660 |
721 |
934 |
43 |
0 |
| Virginia |
2020-05-05 03:00:00 |
19493 |
684 |
721 |
821 |
24 |
0 |
| Virginia |
2020-05-06 03:00:00 |
20257 |
713 |
721 |
764 |
29 |
0 |
| Virginia |
2020-05-07 11:00:00 |
20257 |
713 |
2734 |
0 |
0 |
2013 |
| Virginia |
2020-05-08 03:00:00 |
21570 |
769 |
2825 |
1313 |
56 |
91 |
| Virginia |
2020-05-09 03:00:00 |
22342 |
812 |
2997 |
772 |
43 |
172 |
| Virginia |
2020-05-10 03:00:00 |
23196 |
827 |
3124 |
854 |
15 |
127 |
| Virginia |
2020-05-11 03:00:00 |
24081 |
839 |
3201 |
885 |
12 |
77 |
| Virginia |
2020-05-12 03:00:00 |
25070 |
850 |
3273 |
989 |
11 |
72 |
| Virginia |
2020-05-13 03:00:00 |
25800 |
892 |
3400 |
730 |
42 |
127 |
| Virginia |
2020-05-14 03:00:00 |
26746 |
928 |
3554 |
946 |
36 |
154 |
| Virginia |
2020-05-15 03:00:00 |
27813 |
956 |
3554 |
1067 |
28 |
0 |
| Virginia |
2020-05-16 03:00:00 |
28672 |
978 |
3805 |
859 |
22 |
251 |
| Virginia |
2020-05-17 03:00:00 |
29683 |
1003 |
3909 |
1011 |
25 |
104 |
| Virginia |
2020-05-18 03:00:00 |
30388 |
1010 |
3993 |
705 |
7 |
84 |
| Virginia |
2020-05-19 03:00:00 |
31140 |
1015 |
4107 |
752 |
5 |
114 |
| Virginia |
2020-05-20 03:00:00 |
32145 |
1042 |
4271 |
1005 |
27 |
164 |
| Virginia |
2020-05-21 03:00:00 |
32908 |
1075 |
4523 |
763 |
33 |
252 |
| Virginia |
2020-05-22 03:00:00 |
34137 |
1100 |
4778 |
1229 |
25 |
255 |
| Virginia |
2020-05-23 03:00:00 |
34950 |
1136 |
4963 |
813 |
36 |
185 |
| Virginia |
2020-05-24 03:00:00 |
35749 |
1159 |
5047 |
799 |
23 |
84 |
| Virginia |
2020-05-25 03:00:00 |
36244 |
1171 |
5102 |
495 |
12 |
55 |
| Virginia |
2020-05-26 03:00:00 |
37727 |
1208 |
5145 |
1483 |
37 |
43 |
| Virginia |
2020-05-27 03:00:00 |
39342 |
1236 |
5227 |
1615 |
28 |
82 |
| Virginia |
2020-05-28 03:00:00 |
40249 |
1281 |
5227 |
907 |
45 |
0 |
| Virginia |
2020-05-29 03:00:00 |
41401 |
1338 |
5472 |
1152 |
57 |
245 |
| Virginia |
2020-05-30 03:00:00 |
42533 |
1358 |
5472 |
1132 |
20 |
0 |
| Virginia |
2020-05-31 03:00:00 |
43611 |
1370 |
5745 |
1078 |
12 |
273 |
| Virginia |
2020-06-01 03:00:00 |
44607 |
1375 |
5868 |
996 |
5 |
123 |
| Virginia |
2020-06-02 03:00:00 |
45398 |
1392 |
5868 |
791 |
17 |
0 |
| Virginia |
2020-06-03 03:00:00 |
46239 |
1407 |
6011 |
841 |
15 |
143 |
| Virginia |
2020-06-04 03:00:00 |
46905 |
1428 |
6165 |
666 |
21 |
154 |
| Virginia |
2020-06-05 03:00:00 |
47856 |
1445 |
6284 |
951 |
17 |
119 |
| Virginia |
2020-06-06 12:00:00 |
48532 |
1454 |
6392 |
676 |
9 |
108 |
| Virginia |
2020-06-07 03:00:00 |
49397 |
1461 |
6382 |
865 |
7 |
-10 |
| Virginia |
2020-06-08 03:00:00 |
49397 |
1461 |
6382 |
0 |
0 |
0 |
| Virginia |
2020-06-09 03:00:00 |
51251 |
1478 |
6557 |
1854 |
17 |
175 |
| Virginia |
2020-06-10 03:00:00 |
51738 |
1497 |
6677 |
487 |
19 |
120 |
| Virginia |
2020-06-10 03:00:00 |
51738 |
1497 |
6677 |
0 |
0 |
0 |

What if we plotted the number of fatalities? The fatalities graphs plot the total number of deaths on the x-axis (Deaths column) and the daily change of deaths (delta_deaths column) on the y-axis.

In the video, the creator highlighted two countries exhibiting recovery curves: South Korea and China.




The video also showed Japan having a slight uptick (5:49 of the video). What does the data reveal? (Note: On 07 April 2020, Japan declares a state of emergency.)


How does the United States compare with these countries?


Finally, today (April 5, 2020), I heard that things in Italy are starting look favorable. What does the data say?



End Notes.
Minutes before first publishing this report on 03 April 2020, an article entitled Preparing For the Peak appeared in my email. What a coincidence.
I’ve received questions regarding the validity and source of the data used in this report. The source of the data is from the COVID-19 Surveillance Dashboard. They aggregated the data from numerous reliable sources.
Additional plots. Check out plots from one of these other 65 areas of interest. [If the link fails to render, right-click on it and open in a new window].
Every attempt was made to convey valid and accurate results based upon the data provided.
Stay well and be safe.
Report generated: 2020-07-10 17:30:22
LS0tDQp0aXRsZTogIkNPVklELTE5OiAgSXMgdGhlIGN1cnZlIGZsYXR0ZW5pbmc/Ig0KYXV0aG9yOiAiSm9obiBTaW51ZXMiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCmBgYHtyIGNsZWFyYWxsLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPUZBTFNFfQ0Kcm0obGlzdCA9IGxzKCkpDQpgYGANCg0KIyBJbnRyb2R1Y3Rpb24NCkluZGl2aWR1YWxzIGFjcm9zcyB0aGUgZ2xvYmUgYXJlIHVyZ2VkIHRvIHNsb3cgdGhlIHNwcmVhZCBvZiBDT1ZJRC0xOS4gIEdvdmVybm1lbnRzIGFyZSBpbXBsZW1lbnRpbmcgZXZlcnl0aGluZyBmcm9tIG1pbGQgKipzaGVsdGVyIGluIHBsYWNlKiogdG8gZXh0cmVtZSBbKnNob290IHRoZW0gZGVhZCpdKGh0dHBzOi8vd3d3LnZvYW5ld3MuY29tL3NjaWVuY2UtaGVhbHRoL2Nvcm9uYXZpcnVzLW91dGJyZWFrL3BoaWxpcHBpbmUtcHJlc2lkZW50LXNheXMtdGhvc2UtdmlvbGF0aW5nLWFudGktdmlydXMtbWVhc3VyZXMpIG1lYXN1cmVzIHRvIGNvbnRyb2wgdGhpcyBnbG9iYWwgY3Jpc2lzLg0KDQpBbGwgdGhlc2UgZWZmb3J0cyBhcmUgaW4gaG9wZXMgb2YgZmxhdHRlbmluZyB0aGUgY3VydmUuICBBY2NvcmRpbmcgdG8gdGhpcyBbYXJ0aWNsZV0oKGh0dHBzOi8vd3d3LmJpb3NwYWNlLmNvbS9hcnRpY2xlL2ZsYXR0ZW5pbmctdGhlLWN1cnZlLWNvdmlkLTE5LykpLCBoaWdoIHBlYWtzIHB1dCBhIGxvdCBvZiBwcmVzc3VyZSBvbiBoZWFsdGggY2FyZSBzeXN0ZW1zIHdoaWNoIHRoZXkgc3RydWdnbGUgdG8gcmVzcG9uZCB0by4NCg0KU28gd2hhdCBkb2VzIHRoaXMgY3VydmUgbG9vayBsaWtlIGZvciBteSBzdGF0ZSBvZiBWaXJnaW5pYT8gIEkndmUgc2VlbiBhIHJpc2luZyBjdXJ2ZSBmb3IgdGhlIGVudGlyZSBVbml0ZWQgU3RhdGVzLCBidXQgSSd2ZSBvbmx5IHNlZW4gdGhlIGN1cnJlbnQgbnVtYmVyIG9mIGNhc2VzIGZvciBhIHBhcnRpY3VsYXIgZGF5LiAgSSBkb24ndCBrbm93IGhvdyB0aGlzIG51bWJlciBjb21wYXJlcyB0byBsYXN0IHdlZWsuDQoNCltXb3JsZCBPIE1ldGVyXShodHRwczovL3d3dy53b3JsZG9tZXRlcnMuaW5mby9jb3JvbmF2aXJ1cy8pIGFuZCBbQmluZydzIENvcm9ub2F2aXJ1cyB1cGRhdGVzXShodHRwczovL3d3dy5iaW5nLmNvbS9zZWFyY2g/cT1Db3JvbmF2aXJ1cyt1cGRhdGVzKSBwcm92aWRlIG5pY2Ugc3VtbWFyaWVzLCBidXQgbmVpdGhlciBvZiB0aGVzZSB3ZWIgc2l0ZXMgc2hvd2VkIHRoZSB0cmVuZCBvZiBjb25maXJtZWQgY2FzZXMgb3ZlciB0aW1lLg0KDQpBbGwgSSBuZWVkZWQgd2FzIHRoZSBkYXRhLiAgQWZ0ZXIgY291bnRsZXNzIHNlYXJjaGVzLCBJIHN0dW1ibGVkIHVwb24gdGhlIFVuaXZlcnNpdHkgb2YgVmlyZ2luaWEncyBbQ09WSUQtMTkgU3VydmVpbGxhbmNlIERhc2hib2FyZF0oaHR0cHM6Ly9uc3NhYy5iaWkudmlyZ2luaWEuZWR1L2NvdmlkLTE5L2Rhc2hib2FyZC8pLiAgSXQgaXMgYSBuaWNlIHJlYWwtdGltZSBkYXNoYm9hcmQgdGhhdCBhbHNvIGFsbG93cyBvbmUgdG8gZG93bmxvYWQgZGF0YS4gIFVwb24gaW5zcGVjdGlvbiBvZiB0aGUgcHJvdmlkZWQgZGF0YXNldHMsIEkgZm91bmQgd2hhdCBJIHdhcyBsb29raW5nIGZvci4gIA0KDQpUaGlzIHBlcnNvbmFsIHByb2plY3QgaXMgbXkgYXR0ZW1wdCB0byB1bmRlcnN0YW5kIHRoZSBDT1ZJRC0xOSBjdXJ2ZSBhbmQgaG93IHRoZSBudW1iZXIgb2YgY2FzZXMgYWZmZWN0cyB0aGUgc2hhcGUgb2YgdGhlIGN1cnZlLg0KDQojIyMgTGV0J3MgZ2V0IHN0YXJ0ZWQuDQoNCmBgYHtyIGdldF9maWxlcywgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz1GQUxTRX0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KGdndGhlbWVzKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoa2FibGVFeHRyYSkNCg0Kb3B0aW9ucyhzY2lwZW49MTAwMDApICMgcmVtb3ZlIHNjaWVudGlmaWMgbm90YXRpb24gZnJvbSBncmFwaHMNCg0KZmlsZW5hbWUgPC0gIm5zc2FjLW5jb3YtZGF0YS1jb3VudHJ5LXN0YXRlIg0Kc3JjX2ZpbGUgPC0gcGFzdGUwKCJodHRwczovL25zc2FjLmJpaS52aXJnaW5pYS5lZHUvY292aWQtMTkvZGFzaGJvYXJkL2RhdGEvIg0KICAgICAgICAgICAgICAgICAgICwgZmlsZW5hbWUNCiAgICAgICAgICAgICAgICAgICAsICIuemlwIikNCg0KIyBNYWtlIGEgdGVtcG9yYXJ5IGZpbGUgKHRmKSBhbmQgYSB0ZW1wb3JhcnkgZm9sZGVyICh0ZGlyKQ0KdGYgPC0gdGVtcGZpbGUodG1wZGlyID0gdGRpciA8LSB0ZW1wZGlyKCkpDQoNCiMjIERvd25sb2FkIHRoZSB6aXAgZmlsZSANCmRvd25sb2FkLmZpbGUoc3JjX2ZpbGUsIHRmKQ0KDQojIyBVbnppcCBpdCBpbiB0aGUgdGVtcCBmb2xkZXINCmNzdl9maWxlcyA8LSB1bnppcCh0ZiwgZXhkaXIgPSB0ZGlyKQ0KDQpmaWxlc190b19pbXBvcnQgPC0gbGlzdC5maWxlcyhwYXN0ZTAodGRpciwiLyIsIGZpbGVuYW1lKSwgcGF0dGVybiA9ICIuY3N2IiwgZnVsbC5uYW1lcyA9IFRSVUUpDQoNCg0KIyBhcHBseSBtYXBfZGYoKSB0byBpdGVyYXRlIHJlYWRfY3N2IG92ZXIgZmlsZXMNCmRhdGEgPC0gZmlsZXNfdG9faW1wb3J0ICU+JSBtYXBfZGZyKHJlYWRfY3N2LCBjb2xfdHlwZXMgPSAiY2NjaWlpIikNCmNvbG5hbWVzKGRhdGEpIDwtIGMoIk5hbWUiLCAiUmVnaW9uIiwgIkxhc3RfVXBkYXRlIiwgIkNvbmZpcm1lZCIsICJEZWF0aHMiLCAiUmVjb3ZlcmVkIikNCmRhdGEkTGFzdF9VcGRhdGUgPC0geW1kX2htcyhkYXRhJExhc3RfVXBkYXRlKQ0KDQpgYGANCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgcmVzdWx0cyA9ICdhc2lzJ30NCnNob3dUYWJsZSA8LSBmdW5jdGlvbih0aGVEYXRhLCB0YWJsZUNhcHRpb24sIHRoZUZvb3Rub3RlPU5VTEwpIHsNCiAgaWYgKG1pc3NpbmcodGFibGVDYXB0aW9uKSkgew0KICAgIHRoZUNhcHRpb24gPC0gIkN1cnJlbnQgTnVtYmVyIG9mIEluZmVjdGlvbnMiDQogIH0gZWxzZSB7DQogICAgdGhlQ2FwdGlvbiA8LSB0YWJsZUNhcHRpb24NCiAgfQ0KICBrYWJsZSh0aGVEYXRhLCBjYXB0aW9uID0gdGhlQ2FwdGlvbikgJT4lDQogICAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICAgIHNjcm9sbF9ib3goaGVpZ2h0ID0gIjUwMHB4IikgJT4lDQogICAgZm9vdG5vdGUoZ2VuZXJhbCA9IHRoZUZvb3Rub3RlKQ0KICAgIA0KfQ0KDQpgYGANCg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCByZXN1bHRzID0gJ2FzaXMnfQ0Kc2V0LnNlZWQoNzU3KQ0KDQpzaG93VGFibGUoc2FtcGxlX24oZGF0YSwgMTApLCAiU2FtcGxlIERhdGEgRnJvbSBJbXBvcnRlZCBGaWxlcyIpDQoNCmBgYA0KDQpgYGB7ciBkYXRhX3ByZXAsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHJlc3VsdHM9RkFMU0V9DQojIGNhbGN1bGF0ZSBjYXNlICB0eXBlIGNoYW5nZSBmcm9tIHByZXZpb3VzIGRheQ0KZGF0YSA8LSBkYXRhICU+JSBncm91cF9ieShOYW1lLCBSZWdpb24pICU+JQ0KICBhcnJhbmdlKFJlZ2lvbiwgTmFtZSwgTGFzdF9VcGRhdGUpICU+JQ0KICBtdXRhdGUoZGVsdGFfY29uZmlybWVkID0gQ29uZmlybWVkIC0gbGFnKENvbmZpcm1lZCkpICU+JQ0KICBtdXRhdGUoZGVsdGFfZGVhdGhzID0gRGVhdGhzIC0gbGFnKERlYXRocykpICU+JQ0KICBtdXRhdGUoZGVsdGFfcmVjb3ZlcmVkID0gUmVjb3ZlcmVkIC0gbGFnKFJlY292ZXJlZCkpDQoNCiMgc2hvcnRlbiBuYW1lDQpkYXRhJE5hbWVbZGF0YSROYW1lID09ICJVbml0ZWQgU3RhdGVzIFZpcmdpbiBJc2xhbmRzIl0gPC0gIlVTIFZpcmdpbiBJc2xhbmRzIg0KDQptaW5fZHQgPC0gbWluKGRhdGEkTGFzdF9VcGRhdGUsIG5hLnJtPVRSVUUpDQptYXhfZHQgPC0gbWF4KGRhdGEkTGFzdF9VcGRhdGUsIG5hLnJtPVRSVUUpDQoNCmBgYA0KXCAgDQpcICANClwgIA0KDQpBZnRlciBsb2FkaW5nIHRoZSBkYXRhZmlsZSwgd2UgZmluZCB0aGUgZGF0YXNldCBjb250YWlucyAqKmByIG5yb3coZGF0YSlgKiogcmVjb3JkcywgKipgciBsZW5ndGgodW5pcXVlKGRhdGEkUmVnaW9uKSlgKiogYXJlYXMgb2YgaW50ZXJlc3RzIHdpdGggaW5mb3JtYXRpb24gZGF0ZWQgZnJvbSAqKmByIG1pbl9kdFtbMV1dYCoqIGFuZCAqKmByIG1heF9kdFtbMV1dYCoqLg0KDQpHbG9iYWxseSwgdGhlcmUgYXJlICoqYHIgc3VtKGRhdGEgJT4lICBzbGljZShjKDE6bigpKS0xKSAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoZGVsdGFfY29uZmlybWVkKSwgbmEucm09VFJVRSlgKiogY29uZmlybWVkIENPVklELTE5IGNhc2VzLCAqKmByIHN1bShkYXRhICU+JSAgc2xpY2UoYygxOm4oKSktMSkgJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KGRlbHRhX2RlYXRocyksIG5hLnJtPVRSVUUpYCoqIGRlYXRocywgYW5kICoqYHIgc3VtKGRhdGEgJT4lICBzbGljZShjKDE6bigpKS0xKSAlPiUgdW5ncm91cCgpICU+JSBzZWxlY3QoZGVsdGFfcmVjb3ZlcmVkKSwgbmEucm09VFJVRSlgKiogd2hvIHJlY292ZXJlZC4NCg0KDQpgYGB7ciB1c19kYXRhLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpkZi51cyA8LSBkYXRhICU+JSANCiAgZmlsdGVyKFJlZ2lvbiA9PSAiVVNBIikgJT4lIA0KICBzZWxlY3QoTmFtZSwgTGFzdF9VcGRhdGUsIENvbmZpcm1lZCwgRGVhdGhzLCBSZWNvdmVyZWQpICU+JQ0KICBnYXRoZXIoY2FzZV90eXBlLCB2YWx1ZSwgQ29uZmlybWVkOlJlY292ZXJlZCkNCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9DQpwbG90UmVnaW9ucyA8LSBmdW5jdGlvbih0aGVEYXRhLCBwbG90TG9nLCByZXBvcnRUaXRsZSwgZmFjZXRXcmFwKSB7DQogIHAgPC0gZ2dwbG90KHRoZURhdGEsDQogICAgICAgICAgICAgIGFlcyh4PUxhc3RfVXBkYXRlLCB5PXZhbHVlLCBjb2xvciA9IGZhY3RvcihOYW1lKSkpICsgDQogICAgZ2VvbV9wb2ludChhZXMoY29sb3IgPSBjYXNlX3R5cGUpKSArDQogICAgbGFicyh0aXRsZSA9IHJlcG9ydFRpdGxlDQogICAgICAgICAsIHggPSAiRGF0ZSBSZXBvcnRlZCINCiAgICAgICAgICwgeSA9ICIjIENhc2VzIg0KICAgICAgICAgLCBjb2xvciA9ICJDYXNlIFR5cGUiDQogICAgICAgICAsIGNhcHRpb24gPSBwYXN0ZTAoIkNyZWF0ZWQgIiwgU3lzLnRpbWUoKSkpICsNCiAgICBzY2FsZV9jb2xvcl9maXZldGhpcnR5ZWlnaHQoKSArIA0KICAgIHRoZW1lX2ZpdmV0aGlydHllaWdodCgpICsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT05MCkpDQoNCiAgaWYgKGZhY2V0V3JhcCA9PSAiWSIpIHsNCiAgICBwIDwtIHAgKyBmYWNldF93cmFwKHZhcnMoTmFtZSkpDQogIH0NCiAgDQogIGlmIChncmVwbChwYXR0ZXJuPSJebG9nWzAtOV17MSwyfSQiLCBwbG90TG9nKSkgew0KICAgIHAgPC0gcCArIHNjYWxlX3lfY29udGludW91cyh0cmFucz1wbG90TG9nKQ0KICB9DQoNCiAgcCAgDQp9DQoNCmBgYA0KDQoNCg0KYGBge3IsIGVjaG8gPSBGQUxTRX0NCk5vcnRoZWFzdCA8LSBjKCJDb25uZWN0aWN1dCIsICJNYWluZSIsICJNYXNzYWNodXNldHRzIiwgIk5ldyBIYW1wc2hpcmUiLCAiUmhvZGUgSXNsYW5kIg0KICAgICAgICAgICAgICAgLCAiVmVybW9udCIsICJOZXcgSmVyc2V5IiwgIk5ldyBZb3JrIiwgIlBlbm5zeWx2YW5pYSIsICJQdWVydG8gUmljbyINCiAgICAgICAgICAgICAgICwgIlVTIFZpcmdpbiBJc2xhbmRzIikNCk1pZHdlc3QgPC0gYygiSWxsaW5vaXMiLCAiSW5kaWFuYSIsICJNaWNoaWdhbiIsICJPaGlvIiwgIldpc2NvbnNpbiINCiAgICAgICAgICAgICAsICJJb3dhIiwgIkthbnNhcyIsICJNaW5uZXNvdGEiLCAiTWlzc291cmkiLCAiTmVicmFza2EiDQogICAgICAgICAgICAgLCAiTm9ydGggRGFrb3RhIiwgIlNvdXRoIERha290YSIpDQpTb3V0aCA8LSBjKCJEZWxhd2FyZSIsICJGbG9yaWRhIiwgIkdlb3JnaWEiLCAiTWFyeWxhbmQiLCAiTm9ydGggQ2Fyb2xpbmEiDQogICAgICAgICAgICwgIlNvdXRoIENhcm9saW5hIiwgIlZpcmdpbmlhIiwgIkRpc3RyaWN0IG9mIENvbHVtYmlhIiwgIldlc3QgVmlyZ2luaWEiLCAiQWxhYmFtYSINCiAgICAgICAgICAgLCAiS2VudHVja3kiLCAiTWlzc2lzc2lwcGkiLCAiVGVubmVzc2VlIiwgIkFya2Fuc2FzIiwgIkxvdWlzaWFuYSINCiAgICAgICAgICAgLCAiT2tsYWhvbWEiLCAiVGV4YXMiKQ0KV2VzdCA8LSBjKCJBcml6b25hIiwgIkNvbG9yYWRvIiwgIklkYWhvIiwgIk1vbnRhbmEiLCAiTmV2YWRhIg0KICAgICAgICAgICwgIk5ldyBNZXhpY28iLCAiVXRhaCIsICJXeW9taW5nIiwgIkFsYXNrYSIsICJDYWxpZm9ybmlhIg0KICAgICAgICAgICwgIkhhd2FpaSIsICJPcmVnb24iLCAiV2FzaGluZ3RvbiIsICJOb3J0aGVybiBNYXJpYW5hIElzbGFuZHMiLCAiR3VhbSIpDQoNCmBgYA0KDQoqKioNCg0KXCAgDQpcICANCg0KIyMjIyBXaGF0IGRvZXMgdGhlIGN1cnZlIGxvb2sgbGlrZSBmb3IgdGhlIFVTIGFzIGEgd2hvbGU/ICBUaGlzIGlzIHRoZSBncmFwaGljIHdlIHNlZSBpbiBtYWluc3RyZWFtIG1lZGlhLiAgQ3VycmVudGx5IHRoZXJlIGFyZSBgciBzdW0oKGRhdGEgJT4lIGZpbHRlcihOYW1lICVpbiUgYyhOb3J0aGVhc3QsIE1pZHdlc3QsIFNvdXRoLCBXZXN0KSkpWzddLCBuYS5ybSA9IFRSVUUpYCBjb25maXJtZWQgY2FzZXMgaW4gdGhlIFVuaXRlZCBTdGF0ZXMuDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9DQpwbG90UmVnaW9ucyhkZi51cyAlPiUNCiAgICAgICAgICAgICAgZmlsdGVyKE5hbWUgJWluJSBjKE1pZHdlc3QsIFNvdXRoLCBXZXN0LCBOb3J0aGVhc3QpKSAlPiUgDQogICAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUNCiAgICAgICAgICAgICAgc2VsZWN0KExhc3RfVXBkYXRlLCBjYXNlX3R5cGUsdmFsdWUpICU+JQ0KICAgICAgICAgICAgICBncm91cF9ieShMYXN0X1VwZGF0ZSwgY2FzZV90eXBlKSAlPiUNCiAgICAgICAgICAgICAgc3VtbWFyaXNlKHZhbHVlPXN1bSh2YWx1ZSwgbmEucm0gPSBUUlVFKSkNCiAgICAgICAgICAgICwgIk4iLCAiQ09WSUQtMTkgQ2FzZXMgLSBFbnRpcmUgVVMgUmVnaW9uIiwgIk4iKQ0KDQpgYGANClwgIA0KXCAgDQpcICANClwgDQpcICANClwgDQoNCiMjIyMgU2VlaW5nIHRoZSBiaWcgcGljdHVyZSBjYW4gYmUgb3ZlcndoZWxtaW5nLiAgTGV0J3MgYnJlYWsgaXQgZG93biBieSByZWdpb25zLg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04fQ0KcGxvdFJlZ2lvbnMoZGYudXMgJT4lIGZpbHRlcihOYW1lICVpbiUgTm9ydGhlYXN0KSwgIk4iLCAiQ09WSUQtMTkgQ2FzZXMgLSBOb3J0aGVzdCBSZWdpb24iLCAiWSIpDQpwbG90UmVnaW9ucyhkZi51cyAlPiUgZmlsdGVyKE5hbWUgJWluJSBNaWR3ZXN0KSwgIk4iLCAiQ09WSUQtMTkgQ2FzZXMgLSBNaWR3ZXN0IFJlZ2lvbiIsICJZIikNCnBsb3RSZWdpb25zKGRmLnVzICU+JSBmaWx0ZXIoTmFtZSAlaW4lIFNvdXRoKSwgIk4iLCAiQ09WSUQtMTkgQ2FzZXMgLSBTb3V0aCBSZWdpb24iLCAiWSIpDQpwbG90UmVnaW9ucyhkZi51cyAlPiUgZmlsdGVyKE5hbWUgJWluJSBXZXN0KSwgIk4iLCAiQ09WSUQtMTkgQ2FzZXMgLSBXZXN0IFJlZ2lvbiIsICJZIikNCg0KYGBgDQpcICANClwgIA0KXCAgDQpcIA0KXCAgDQpcIA0KDQojIyMjIyBGYXN0IHJpc2luZyBjdXJ2ZXMgaWRlbnRpZnkgdGhvc2UgKmhvdCBzcG90cyogYW5kIHByaW9yaXR5IHJlZ2lvbnMuICBCdXQgd2hhdCBhYm91dCB0aG9zZSBzdGF0ZXMgdGhhdCBkb24ndCBzaG93IGEgc3RlZXAgcmlzaW5nIGN1cnZlPyAgQXJlIHRoZXkgb2YgY29uY2Vybj8NCg0KIyMjIyMgVGhlIGFib3ZlIGdyYXBocyBncm91cCBzdGF0ZXMgYnkgcmVnaW9ucy4gIE9uZSBzdGF0ZSB3aXRoIGEgaGlnaCBudW1iZXIgb2YgY2FzZXMgY291bGQgc2tldyB0aGUgZ3JhcGggZm9yIHRoZSByZWdpb24uICBUbyB0YWtlIHRoaXMgaW50byBhY2NvdW50IGFuZCB0byBzaG93IHRoZSByYXRlIG9mIGNoYW5nZSBvdmVyIHRpbWUsIGxldCdzIHBsb3QgdGhlIGluZm9ybWF0aW9uIG9uIGEgbG9nYXJpdGhtaWMgc2NhbGUuDQoNCj4gR3JhcGhzIHdpdGggc3RlZXAgY3VydmVzIHNob3cgc3RhdGVzIGhpdCBoYXJkZXN0IGJ5IHRoZSBDT1ZJRC0xOSB2aXJ1cy4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRX0NCmNyZWF0ZUxhYmVsIDwtIGZ1bmN0aW9uKGNvdW50cnlOYW1lLCBsb2dCYXNlLCBjYXNlVHlwZT1OVUxMKSB7DQogIGlmIChtaXNzaW5nKGNhc2VUeXBlKSkgew0KICAgIGxhYmVsIDwtIHBhc3RlMCgiQ09WSUQtMTkgQ2FzZXMgLSAiLCBjb3VudHJ5TmFtZSkNCiAgfSBlbHNlIHsNCiAgICBsYWJlbCA8LSBwYXN0ZTAoIkNPVklELTE5ICIsIGNhc2VUeXBlLCAiIC0gIiwgY291bnRyeU5hbWUpDQogIH0NCg0KICAjIG9ubHkgYmFzZSBsb2dzIG9mIDIgYW5kIDEwIGFyZSBzdXBwb3J0ZWQ7IG5vdCBzdXJlIGhvdyB0bw0KICAjIHRha2UgdGhlIExvZ1tuXSB3L2luIHRoZSBicXVvdGUoKSBmdW5jdGlvbg0KICBpZiAobWlzc2luZyhsb2dCYXNlKSkgew0KICAgICMgbm8gbG9nIGxhYmVsDQogICAgYnF1b3RlKC4obGFiZWxbMV0pKQ0KICB9IGVsc2UgaWYgKGxvZ0Jhc2UgPT0gImxvZzIiKSB7DQogICAgYnF1b3RlKC4obGFiZWxbMV0pIH4gKExvZ1syXSkpDQogIH0gZWxzZSBpZiAobG9nQmFzZSA9PSAibG9nMTAiKSB7DQogICAgYnF1b3RlKC4obGFiZWxbMV0pIH4gKExvZ1sxMF0pKQ0KICB9IGVsc2UgaWYgKGdyZXBsKHBhdHRlcm49Il5sb2dbMC05XXsxLDJ9JCIsIGxvZ0Jhc2UpKSB7DQogICAgYnF1b3RlKC4obGFiZWxbMV0pIH4gKExvZykpDQogIH0NCn0NCg0KYGBgDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9DQpwbG90UmVnaW9ucyhkZi51cyAlPiUgZmlsdGVyKE5hbWUgJWluJSBOb3J0aGVhc3QpLCAibG9nMTAiLCBjcmVhdGVMYWJlbCgiTm9ydGhlc3QgUmVnaW9uIiksICJZIikNCnBsb3RSZWdpb25zKGRmLnVzICU+JSBmaWx0ZXIoTmFtZSAlaW4lIE1pZHdlc3QpLCAibG9nMTAiLCAgY3JlYXRlTGFiZWwoIk1pZHdlc3QgUmVnaW9uIiksICJZIikNCnBsb3RSZWdpb25zKGRmLnVzICU+JSBmaWx0ZXIoTmFtZSAlaW4lIFNvdXRoKSwgImxvZzEwIiwgIGNyZWF0ZUxhYmVsKCJTb3V0aCBSZWdpb24iKSwgIlkiKQ0KcGxvdFJlZ2lvbnMoZGYudXMgJT4lIGZpbHRlcihOYW1lICVpbiUgV2VzdCksICJsb2cxMCIsICBjcmVhdGVMYWJlbCgiV2VzdCBSZWdpb24iKSwgIlkiKQ0KDQpgYGANClwgIA0KXCAgDQpcICANClwgDQpcICANClwgDQoNCiMjIyMjIFdoYXQgZG9lcyB0aGUgVmlyZ2luaWEgY3VydmUgc2hvdz8NCg0KYGBge3IsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTh9DQpkZi50ZW1wIDwtIGRmLnVzICU+JSBmaWx0ZXIoTmFtZSA9PSAiVmlyZ2luaWEiKQ0KDQpwbG90UmVnaW9ucyhkZi50ZW1wLCAiTiIsIGNyZWF0ZUxhYmVsKCJWaXJnaW5pYSIpLCAiTiIpDQpwbG90UmVnaW9ucyhkZi50ZW1wLCAibG9nMTAiLCBjcmVhdGVMYWJlbCgiVmlyZ2luaWEiLCAibG9nMTAiKSwgIk4iKQ0KDQpgYGANCioqKg0KXCAgDQpcICANClwgIA0KXCANClwgIA0KXCANCg0KIyMjIyBTdW1tYXJ5IG9mIFUuUy4gQXJlYXMgb2YgSW50ZXJlc3QNCg0KYGBge3IgdGFiX3VzX3JlZ2lvbnMsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmdldF91c19yZWdpb24gPC0gZnVuY3Rpb24odGhlRGF0YSwgcmVnaW9uLCBjYXNlVHlwZSwgbGFiZWwpIHsNCiAgdGhlRGF0YSAlPiUgDQogICAgZmlsdGVyKE5hbWUgJWluJSBjKHJlZ2lvbikgJiBjYXNlX3R5cGUgJWluJSBjYXNlVHlwZSkgJT4lDQogICAgZ3JvdXBfYnkoTmFtZSwgY2FzZV90eXBlKSAlPiUNCiAgICBhcnJhbmdlKExhc3RfVXBkYXRlKSAlPiUNCiAgICBzbGljZShjKG4oKSkpICU+JQ0KICAgIG11dGF0ZShncm91cCA9IGxhYmVsKSAlPiUNCiAgICB1bmdyb3VwKCkgJT4lDQogICAgc2VsZWN0KE5hbWUsIGdyb3VwLCBjYXNlX3R5cGUsIHZhbHVlKQ0KfQ0KDQpkZi50ZW1wIDwtIGdldF91c19yZWdpb24oZGYudXMsIE1pZHdlc3QsIGMoJ0NvbmZpcm1lZCcsICdEZWF0aHMnLCAnUmVjb3ZlcmVkJyksICdNaWR3ZXN0JykNCmRmLnRlbXAgPC0gYmluZF9yb3dzKGRmLnRlbXAsIGdldF91c19yZWdpb24oZGYudXMsIFNvdXRoLCBjKCdDb25maXJtZWQnLCAnRGVhdGhzJywgJ1JlY292ZXJlZCcpLCAnU291dGgnKSkNCmRmLnRlbXAgPC0gYmluZF9yb3dzKGRmLnRlbXAsIGdldF91c19yZWdpb24oZGYudXMsIFdlc3QsIGMoJ0NvbmZpcm1lZCcsICdEZWF0aHMnLCAnUmVjb3ZlcmVkJyksICdXZXN0JykpDQpkZi50ZW1wIDwtIGJpbmRfcm93cyhkZi50ZW1wLCBnZXRfdXNfcmVnaW9uKGRmLnVzLCBOb3J0aGVhc3QsIGMoJ0NvbmZpcm1lZCcsICdEZWF0aHMnLCAnUmVjb3ZlcmVkJyksICdOb3J0aGVhc3QnKSkNCmRmLnRlbXAgPC0gZGYudGVtcCAlPiUgDQogIHNwcmVhZChjYXNlX3R5cGUsIHZhbHVlKSAlPiUNCiAgYXJyYW5nZShncm91cCwgLUNvbmZpcm1lZCkNCg0KZ2V0X3JlZ2lvbl9jb3VudCA8LSBmdW5jdGlvbih0aGVkYXRhLCB0aGVncm91cCkgew0KICBucm93KHRoZWRhdGEgJT4lIGZpbHRlcihncm91cCAlaW4lIHRoZWdyb3VwKSkNCn0NCg0KDQprYWJsZShkZi50ZW1wDQogICAgICAsIGNhcHRpb24gPSAiU3VtbWFyeSBvZiBVUyBBcmVhcyBvZiBJbnRlcmVzdCIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRikgJT4lDQogIHBhY2tfcm93cygiTWlkd2VzdCINCiAgICAgICAgICAgICwgMQ0KICAgICAgICAgICAgLCBnZXRfcmVnaW9uX2NvdW50KGRmLnRlbXAsIGMoIk1pZHdlc3QiKSkpICU+JQ0KICBwYWNrX3Jvd3MoIk5vcnRoZWFzdCINCiAgICAgICAgICAgICwgZ2V0X3JlZ2lvbl9jb3VudChkZi50ZW1wLCBjKCJNaWR3ZXN0IikpICsgMQ0KICAgICAgICAgICAgLCBnZXRfcmVnaW9uX2NvdW50KGRmLnRlbXAsIGMoIk1pZHdlc3QiLCAiTm9ydGhlYXN0IikpKSAlPiUNCiAgcGFja19yb3dzKCJTb3V0aCINCiAgICAgICAgICAgICwgZ2V0X3JlZ2lvbl9jb3VudChkZi50ZW1wLCBjKCJNaWR3ZXN0IiwgIk5vcnRoZWFzdCIpKSArIDENCiAgICAgICAgICAgICwgZ2V0X3JlZ2lvbl9jb3VudChkZi50ZW1wLCBjKCJNaWR3ZXN0IiwgIk5vcnRoZWFzdCIsICJTb3V0aCIpKSkgJT4lDQogIHBhY2tfcm93cygiV2VzdCINCiAgICAgICAgICAgICwgZ2V0X3JlZ2lvbl9jb3VudChkZi50ZW1wLCBjKCJNaWR3ZXN0IiwgIk5vcnRoZWFzdCIsICJTb3V0aCIpKSArIDENCiAgICAgICAgICAgICwgZ2V0X3JlZ2lvbl9jb3VudChkZi50ZW1wLCBjKCJNaWR3ZXN0IiwgIk5vcnRoZWFzdCIsICJTb3V0aCIsICJXZXN0IikpKSAlPiUNCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiNDAwcHgiKSAlPiUNCiAgZm9vdG5vdGUoZ2VuZXJhbCA9ICJUaGVyZSBhcHBlYXJzIHRvIGJlIGEgZGlzY3JlcGFuY3kgdG8gaG93IHJlY292ZXJpZXMgYXJlIHJlY29yZGVkIGJ5IHN0YXRlLiAgQmFzZWQgdXBvbiBCaW5nJ3MgQ09WSUQtMTkgc3RhdHMsIHNvbWUgb2YgdGhlIHJlY292ZXJpZXMgYXJlIGNvcnJlY3Qgd2hlcmVhcyBvdGhlcnMgYXJlIG5vdC4iKQ0KDQpgYGANCioqKg0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0Kc2hvd1RhYmxlKGRmLnVzICU+JQ0KICAgICAgICAgICAgZmlsdGVyKGNhc2VfdHlwZSA9PSAiQ29uZmlybWVkIiAmIE5hbWUgJWluJSBjKE1pZHdlc3QsIFNvdXRoLCBXZXN0LCBOb3J0aGVhc3QpKSAlPiUNCiAgICAgICAgICAgIGdyb3VwX2J5KFJlZ2lvbiwgTmFtZSkgJT4lDQogICAgICAgICAgICBhcnJhbmdlKFJlZ2lvbiwgTmFtZSwgTGFzdF9VcGRhdGUpICU+JQ0KICAgICAgICAgICAgc2xpY2UoYyhuKCkpKSAlPiUNCiAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUNCiAgICAgICAgICAgIHNlbGVjdChOYW1lLCB2YWx1ZSkgJT4lDQogICAgICAgICAgICBhcnJhbmdlKC12YWx1ZSkgJT4lDQogICAgICAgICAgICB0b3BfbigxMCkgJT4lDQogICAgICAgICAgICByZW5hbWUoYygnIyBDb25maXJtZWQgQ2FzZXMnID0gJ3ZhbHVlJykpDQogICAgICAgICAgLCAiU3RhdGVzIFdpdGggTW9zdCBDb25maXJtZWQgQ2FzZXMiKQ0KDQpzaG93VGFibGUoZGF0YSAlPiUNCiAgICAgICAgICAgIGZpbHRlcihOYW1lICVpbiUgYyhNaWR3ZXN0LCBTb3V0aCwgV2VzdCwgTm9ydGhlYXN0KSkgJT4lDQogICAgICAgICAgICBncm91cF9ieShSZWdpb24sIE5hbWUpICU+JQ0KICAgICAgICAgICAgYXJyYW5nZShSZWdpb24sIE5hbWUsIExhc3RfVXBkYXRlKSAlPiUNCiAgICAgICAgICAgIHNsaWNlKGMobigpLTEpKSAlPiUNCiAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUNCiAgICAgICAgICAgIHNlbGVjdChOYW1lLCBkZWx0YV9jb25maXJtZWQpICU+JQ0KICAgICAgICAgICAgYXJyYW5nZSgtZGVsdGFfY29uZmlybWVkKSAlPiUNCiAgICAgICAgICAgIHRvcF9uKDEwKSAlPiUNCiAgICAgICAgICAgIHJlbmFtZShjKCdDaGFuZ2UgSW4gTnVtYmVyIG9mIENvbmZpcm1lZCBDYXNlcyBGcm9tIFllc3RlcmRheScgPSAnZGVsdGFfY29uZmlybWVkJykpDQogICAgICAgICAgLCAiU3RhdGVzIFdpdGggVGhlIExhcmdlc3QgRGFpbHkgQ2hhbmdlIG9mIENvbmZpcm1lZCBDYXNlcyIpDQoNCnNob3dUYWJsZShkZi51cyAlPiUNCiAgICAgICAgICAgIGZpbHRlcihjYXNlX3R5cGUgPT0gIkRlYXRocyIgJiBOYW1lICVpbiUgYyhNaWR3ZXN0LCBTb3V0aCwgV2VzdCwgTm9ydGhlYXN0KSkgJT4lDQogICAgICAgICAgICBncm91cF9ieShSZWdpb24sIE5hbWUpICU+JQ0KICAgICAgICAgICAgYXJyYW5nZShSZWdpb24sIE5hbWUsIExhc3RfVXBkYXRlKSAlPiUNCiAgICAgICAgICAgIHNsaWNlKGMobigpKSkgJT4lDQogICAgICAgICAgICB1bmdyb3VwKCkgJT4lDQogICAgICAgICAgICBzZWxlY3QoTmFtZSwgdmFsdWUpICU+JQ0KICAgICAgICAgICAgYXJyYW5nZSgtdmFsdWUpICU+JQ0KICAgICAgICAgICAgdG9wX24oMTApICU+JQ0KICAgICAgICAgICAgcmVuYW1lKGMoJyMgRGVhdGhzJyA9ICd2YWx1ZScpKQ0KICAgICAgICAgICwgIlN0YXRlcyBXaXRoIE1vc3QgRGVhdGhzIikNCg0Kc2hvd1RhYmxlKGRmLnVzICU+JQ0KICAgICAgICAgICAgZmlsdGVyKGNhc2VfdHlwZSA9PSAiUmVjb3ZlcmVkIiAmIE5hbWUgJWluJSBjKE1pZHdlc3QsIFNvdXRoLCBXZXN0LCBOb3J0aGVhc3QpKSAlPiUNCiAgICAgICAgICAgIGdyb3VwX2J5KFJlZ2lvbiwgTmFtZSkgJT4lDQogICAgICAgICAgICBhcnJhbmdlKFJlZ2lvbiwgTmFtZSwgTGFzdF9VcGRhdGUpICU+JQ0KICAgICAgICAgICAgc2xpY2UoYyhuKCkpKSAlPiUNCiAgICAgICAgICAgIHVuZ3JvdXAoKSAlPiUNCiAgICAgICAgICAgIHNlbGVjdChOYW1lLCB2YWx1ZSkgJT4lDQogICAgICAgICAgICBhcnJhbmdlKC12YWx1ZSkgJT4lDQogICAgICAgICAgICB0b3BfbigxMCkgJT4lDQogICAgICAgICAgICByZW5hbWUoYygnIyBSZWNvdmVyaWVzJyA9ICd2YWx1ZScpKQ0KICAgICAgICAgICwgIlN0YXRlcyBXaXRoIE1vc3QgUmVjb3ZlcmVkIENhc2VzIg0KICAgICAgICAgICwgIkRpc2NyZXBhbmNpZXMgZm91bmQgaW4gaG93IHJlY292ZXJpZXMgYXJlIHJlY29yZGVkIGJ5IHN0YXRlLiIpDQoNCmBgYA0KKioqDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpzaG93VGFibGUoZGF0YSAlPiUNCiAgICAgICAgICAgIGFycmFuZ2UoUmVnaW9uLCBMYXN0X1VwZGF0ZSkgJT4lDQogICAgICAgICAgICB1bmdyb3VwKCkgJT4lDQogICAgICAgICAgICBncm91cF9ieShSZWdpb24pICU+JQ0KICAgICAgICAgICAgc3VtbWFyaXNlKGRlbHRhX2NvbmZpcm1lZD1zdW0oZGVsdGFfY29uZmlybWVkLCBuYS5ybSA9IFRSVUUpKSAlPiUNCiAgICAgICAgICAgIHNlbGVjdChOYW1lLCBkZWx0YV9jb25maXJtZWQpICU+JQ0KICAgICAgICAgICAgc2xpY2UoYyhuKCkpKSAlPiUNCiAgICAgICAgICAgIGFycmFuZ2UoLWRlbHRhX2NvbmZpcm1lZCkgJT4lDQogICAgICAgICAgICB0b3Bfbig1MCkgJT4lDQogICAgICAgICAgICByZW5hbWUoYygnIyBDb25maXJtZWQgQ2FzZXMnID0gJ2RlbHRhX2NvbmZpcm1lZCcpKQ0KICAgICAgICAgICwgIlJlZ2lvbnMgV2l0aCBMYXJnZXN0IE51bWJlciBvZiBDb25maXJtZWQgQ2FzZXMiKQ0KDQpgYGANCg0KXCAgDQpcICANClwgIA0KXCANClwgIA0KXCANCg0KKioqDQoNCkEgZm9ybWVyIGNvbGxlYWd1ZSBhbmQgT2xkIERvbWluaW9uIFVuaXZlcnNpdHkgcHJvZmVzc29yLCBEci4gQ2h1Y2sgQ2FydGxlZGdlLCBwcm92aWRlZCB2YWx1YWJsZSBmZWVkYmFjayBvbiBteSBpbml0YWwgYXR0ZW1wdCBvbiBhbmFseXppbmcgdGhpcyBpbmZvcm1hdGlvbi4gIEhlIGFsc28gcmVmZXJyZWQgbWUgdG8gdGhpcyBpbnNpZ2h0ZnVsIFtIb3cgVG8gVGVsbCBJZiBXZSdyZSBCZWF0aW5nIENPVklELTE5IHZpZGVvXShodHRwczovL3d3dy55b3V0dWJlLmNvbS93YXRjaD92PTU0WExYZzRmWXNjKS4gIA0KDQpUaHJlZSBrZXkgcG9pbnRzIHdlcmUgZGlzY3Vzc2VkIDEpIHVzZSBhIGxvZ2FyaXRobWljIHNjYWxlLCAyKSBmb2N1cyBvbiBjaGFuZ2UsIG5vdCBhYnNvbHV0ZSBudW1iZXJzLCBhbmQgMykgZG9uJ3QgcGxvdCBhZ2FpbnN0IHRpbWUuICANCg0KVGFraW5nIHRoaXMgaW50byBhY2NvdW50LCBsZXQncyB0YWtlIGEgbG9vayBhdCBWaXJnaW5pYSBhZ2Fpbi4NCg0KPiBUaGUgZm9sbG93aW5nIGdyYXBocyBwbG90IHRoZSB0b3RhbCBudW1iZXIgb2YgY29uZmlybWVkIGNhc2VzIG9uIHRoZSB4LWF4aXMgKCpDb25maXJtZWQqIGNvbHVtbikgYW5kIHRoZSBkYWlseSBjaGFuZ2Ugb2YgY29uZmlybWVkIGNhc2VzICgqZGVsdGFfY29uZmlybWVkKiBjb2x1bW4pIG9uIHRoZSB5LWF4aXMuDQoNCmBgYHtyLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGZpZy5hbGlnbj0nY2VudGVyJ30NCnBsb3REZWx0YSA8LSBmdW5jdGlvbih0aGVEYXRhLCByZXBvcnRUaXRsZSwgcGxvdExvZywgY2FzZVR5cGUpIHsNCiAgDQogIGlmIChjYXNlVHlwZSA9PSAiUmVjb3ZlcmVkIikgew0KICAgIHAgPC0gZ2dwbG90KHRoZURhdGEsDQogICAgICAgICAgICAgICAgYWVzKFJlY292ZXJlZCwgZGVsdGFfcmVjb3ZlcmVkKSkNCiAgfSBlbHNlIGlmIChjYXNlVHlwZSA9PSAiRGVhdGhzIikgew0KICAgIHAgPC0gZ2dwbG90KHRoZURhdGEsDQogICAgICAgICAgICAgICAgYWVzKERlYXRocywgZGVsdGFfZGVhdGhzKSkNCiAgfSBlbHNlIHsNCiAgICBwIDwtIGdncGxvdCh0aGVEYXRhLA0KICAgICAgICAgICAgICAgIGFlcyhDb25maXJtZWQsIGRlbHRhX2NvbmZpcm1lZCkpDQogIH0NCg0KICBwIDwtIHAgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgc3RhdF9zbW9vdGgoKSArDQogICAgbGFicyh0aXRsZSA9IHJlcG9ydFRpdGxlDQogICAgICAgICAsIHggPSBwYXN0ZTAoIlRvdGFsIE51bWJlciBPZiAiLCBjYXNlVHlwZSkNCiAgICAgICAgICwgeSA9IHBhc3RlMCgiUHJldmlvdXMgRGF5cyBUb3RhbCBOdW1iZXIgT2YgIiwgY2FzZVR5cGUpDQogICAgICAgICAsIGNhcHRpb24gPSBwYXN0ZTAoIkNyZWF0ZWQgIiwgU3lzLnRpbWUoKSkpICsNCiAgICBzY2FsZV9jb2xvcl9maXZldGhpcnR5ZWlnaHQoKSArIA0KICAgIHRoZW1lX2ZpdmV0aGlydHllaWdodCgpDQoNCiAgaWYgKGdyZXBsKHBhdHRlcm49Il5sb2dbMC05XXsxLDJ9JCIsIHBsb3RMb2cpKSB7DQogICAgcCA8LSBwICsgc2NhbGVfeV9jb250aW51b3VzKHRyYW5zPXBsb3RMb2cpDQogIH0NCiAgDQogIHANCn0NCg0KYGBgDQoNCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmRmLnRlbXAgPC0gZGF0YSAlPiUgDQogIGZpbHRlcihSZWdpb24gPT0gIlVTQSIgJiBOYW1lID09ICJWaXJnaW5pYSIpICU+JSANCiAgZ3JvdXBfYnkoTmFtZSkgJT4lDQogIHNlbGVjdChOYW1lLCBMYXN0X1VwZGF0ZSwgQ29uZmlybWVkLCBEZWF0aHMsIFJlY292ZXJlZA0KICAgICAgICAgLCBkZWx0YV9jb25maXJtZWQsIGRlbHRhX2RlYXRocywgZGVsdGFfcmVjb3ZlcmVkKSAlPiUNCiAgYXJyYW5nZShMYXN0X1VwZGF0ZSkNCg0Kc2hvd1RhYmxlKGRmLnRlbXAsIlZpcmdpbmlhIENPVklELTE5IERhdGEiKQ0KDQpwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICwgY3JlYXRlTGFiZWwoZGYudGVtcCROYW1lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfY29uZmlybWVkLCBuYS5ybSA9IFRSVUUpLCAiIENvbmZpcm1lZCBDYXNlcykiKSkNCiAgICAgICAgICAsICJZIg0KICAgICAgICAgICwgIkNvbmZpcm1lZCIpDQoNCmBgYA0KXCAgDQpcICANClwgIA0KXCANClwgIA0KXCANCg0KPiBXaGF0IGlmIHdlIHBsb3R0ZWQgdGhlIG51bWJlciBvZiBmYXRhbGl0aWVzPyAgVGhlIGZhdGFsaXRpZXMgZ3JhcGhzIHBsb3QgdGhlIHRvdGFsIG51bWJlciBvZiBkZWF0aHMgb24gdGhlIHgtYXhpcyAoKkRlYXRocyogY29sdW1uKSBhbmQgdGhlIGRhaWx5IGNoYW5nZSBvZiBkZWF0aHMgKCpkZWx0YV9kZWF0aHMqIGNvbHVtbikgb24gdGhlIHktYXhpcy4NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9kZWF0aHMsIG5hLnJtID0gVFJVRSksICIgRGVhdGhzKSIpKQ0KICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICwgIkRlYXRocyIpDQoNCmBgYA0KXCAgDQpcICANClwgIA0KXCANClwgIA0KXCANCg0KSW4gdGhlIHZpZGVvLCB0aGUgY3JlYXRvciBoaWdobGlnaHRlZCB0d28gY291bnRyaWVzIGV4aGliaXRpbmcgcmVjb3ZlcnkgY3VydmVzOiAgU291dGggS29yZWEgYW5kIENoaW5hLg0KDQpgYGB7ciBjaGluYV9zb3V0aF9rb3JlYV9wbG90LCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQoNCmRmLnRlbXAgPC0gZGF0YSAlPiUgDQogIGZpbHRlcihSZWdpb24gPT0gIlNvdXRoIEtvcmVhIikgJT4lIA0KICBncm91cF9ieShSZWdpb24pICU+JQ0KICBzZWxlY3QoTmFtZSwgTGFzdF9VcGRhdGUsIENvbmZpcm1lZCwgRGVhdGhzLCBSZWNvdmVyZWQNCiAgICAgICAgICwgZGVsdGFfY29uZmlybWVkLCBkZWx0YV9kZWF0aHMsIGRlbHRhX3JlY292ZXJlZCkgJT4lDQogIGFycmFuZ2UoTGFzdF9VcGRhdGUpDQoNCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9jb25maXJtZWQsIG5hLnJtID0gVFJVRSksICIgQ29uZmlybWVkIENhc2VzKSIpKQ0KICAgICAgICAgICwgIlkiDQogICAgICAgICAgLCAiQ29uZmlybWVkIikNCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9kZWF0aHMsIG5hLnJtID0gVFJVRSksICIgRGVhdGhzKSIpKQ0KICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICwgIkRlYXRocyIpDQoNCg0KZGYudGVtcCA8LSBkYXRhICU+JSANCiAgZmlsdGVyKFJlZ2lvbiA9PSAiTWFpbmxhbmQgQ2hpbmEiKSAlPiUgDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHNlbGVjdChOYW1lLCBMYXN0X1VwZGF0ZSwgQ29uZmlybWVkLCBEZWF0aHMsIFJlY292ZXJlZA0KICAgICAgICAgLCBkZWx0YV9jb25maXJtZWQsIGRlbHRhX2RlYXRocywgZGVsdGFfcmVjb3ZlcmVkKSAlPiUNCiAgYXJyYW5nZShMYXN0X1VwZGF0ZSkNCg0KcGxvdERlbHRhKGRmLnRlbXANCiAgICAgICAgICAsIGNyZWF0ZUxhYmVsKCJNYWlubGFuZCBDaGluYSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9jb25maXJtZWQsIG5hLnJtID0gVFJVRSksICIgQ29uZmlybWVkIENhc2VzKSIpKQ0KICAgICAgICAgICwgIlkiDQogICAgICAgICAgLCAiQ29uZmlybWVkIikNCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbCgiTWFpbmxhbmQgQ2hpbmEiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfZGVhdGhzLCBuYS5ybSA9IFRSVUUpLCAiIERlYXRocykiKSkNCiAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAsICJEZWF0aHMiKQ0KDQpgYGANClwgIA0KXCAgDQpcICANClwgDQpcICANClwgDQoNClRoZSB2aWRlbyBhbHNvIHNob3dlZCBKYXBhbiBoYXZpbmcgYSBzbGlnaHQgdXB0aWNrICg1OjQ5IG9mIHRoZSB2aWRlbykuICBXaGF0IGRvZXMgdGhlIGRhdGEgcmV2ZWFsPyAgKE5vdGU6ICBPbiAwNyBBcHJpbCAyMDIwLCBKYXBhbiBkZWNsYXJlcyBhIFtzdGF0ZSBvZiBlbWVyZ2VuY3ldKGh0dHBzOi8vYXBuZXdzLmNvbS82ZTUwNmM0ZjEwNTY3MGI4ZmE4ZWI1NTMxYWFkZjJjMSkuKQ0KDQpgYGB7ciBqYXBhbl9wbG90LCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpkZi50ZW1wIDwtIGRhdGEgJT4lIA0KICBmaWx0ZXIoUmVnaW9uID09ICJKYXBhbiIpICU+JSANCiAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgc2VsZWN0KE5hbWUsIExhc3RfVXBkYXRlLCBDb25maXJtZWQsIERlYXRocywgUmVjb3ZlcmVkDQogICAgICAgICAsIGRlbHRhX2NvbmZpcm1lZCwgZGVsdGFfZGVhdGhzLCBkZWx0YV9yZWNvdmVyZWQpICU+JQ0KICBhcnJhbmdlKExhc3RfVXBkYXRlKQ0KDQpwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICwgY3JlYXRlTGFiZWwoZGYudGVtcCROYW1lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfY29uZmlybWVkLCBuYS5ybSA9IFRSVUUpLCAiIENvbmZpcm1lZCBDYXNlcykiKSkNCiAgICAgICAgICAsICJZIg0KICAgICAgICAgICwgIkNvbmZpcm1lZCIpDQpwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICwgY3JlYXRlTGFiZWwoZGYudGVtcCROYW1lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfZGVhdGhzLCBuYS5ybSA9IFRSVUUpLCAiIERlYXRocykiKSkNCiAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAsICJEZWF0aHMiKQ0KDQoNCmBgYA0KXCAgDQpcICANClwgIA0KXCANClwgIA0KXCANCg0KSG93IGRvZXMgdGhlIFVuaXRlZCBTdGF0ZXMgY29tcGFyZSB3aXRoIHRoZXNlIGNvdW50cmllcz8NCg0KYGBge3IsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCmRmLnRlbXAgPC0gZGF0YSAlPiUgDQogIGZpbHRlcihSZWdpb24gPT0gIlVTQSIpICU+JSANCiAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgc2VsZWN0KE5hbWUsIExhc3RfVXBkYXRlLCBDb25maXJtZWQsIERlYXRocywgUmVjb3ZlcmVkDQogICAgICAgICAsIGRlbHRhX2NvbmZpcm1lZCwgZGVsdGFfZGVhdGhzLCBkZWx0YV9yZWNvdmVyZWQpICU+JQ0KICBhcnJhbmdlKExhc3RfVXBkYXRlKQ0KDQpwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICwgY3JlYXRlTGFiZWwoIlVTQSINCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9jb25maXJtZWQsIG5hLnJtID0gVFJVRSksICIgQ29uZmlybWVkIENhc2VzKSIpKQ0KICAgICAgICAgICwgIlkiDQogICAgICAgICAgLCAiQ29uZmlybWVkIikNCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbCgiVVNBIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsIHBhc3RlMCgiKCIsIHN1bShkZi50ZW1wJGRlbHRhX2RlYXRocywgbmEucm0gPSBUUlVFKSwgIiBEZWF0aHMpIikpDQogICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgLCAiRGVhdGhzIikNCg0KYGBgDQpcICANClwgIA0KXCAgDQpcIA0KXCAgDQpcIA0KDQpGaW5hbGx5LCB0b2RheSAoQXByaWwgNSwgMjAyMCksIEkgaGVhcmQgdGhhdCB0aGluZ3MgaW4gSXRhbHkgYXJlIHN0YXJ0aW5nIGxvb2sgW2Zhdm9yYWJsZV0oaHR0cHM6Ly93d3cuY2JzbmV3cy5jb20vbGl2ZS92aWRlby8yMDIwMDQwNTE2MjA1NC11cGRhdGUtb24taXRhbHlzLWNvcm9uYXZpcnVzLW91dGJyZWFrLykuICBXaGF0IGRvZXMgdGhlIGRhdGEgc2F5Pw0KDQpgYGB7ciwgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KZGYudGVtcCA8LSBkYXRhICU+JSANCiAgZmlsdGVyKFJlZ2lvbiA9PSAiSXRhbHkiKSAlPiUgDQogIGdyb3VwX2J5KFJlZ2lvbikgJT4lDQogIHNlbGVjdChOYW1lLCBMYXN0X1VwZGF0ZSwgQ29uZmlybWVkLCBEZWF0aHMsIFJlY292ZXJlZA0KICAgICAgICAgLCBkZWx0YV9jb25maXJtZWQsIGRlbHRhX2RlYXRocywgZGVsdGFfcmVjb3ZlcmVkKSAlPiUNCiAgYXJyYW5nZShMYXN0X1VwZGF0ZSkNCg0KcGxvdERlbHRhKGRmLnRlbXANCiAgICAgICAgICAsIGNyZWF0ZUxhYmVsKGRmLnRlbXAkTmFtZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsIHBhc3RlMCgiKCIsIHN1bShkZi50ZW1wJGRlbHRhX2NvbmZpcm1lZCwgbmEucm0gPSBUUlVFKSwgIiBDb25maXJtZWQgQ2FzZXMpIikpDQogICAgICAgICAgLCAiWSINCiAgICAgICAgICAsICJDb25maXJtZWQiKQ0KcGxvdERlbHRhKGRmLnRlbXANCiAgICAgICAgICAsIGNyZWF0ZUxhYmVsKGRmLnRlbXAkTmFtZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICAsIHBhc3RlMCgiKCIsIHN1bShkZi50ZW1wJGRlbHRhX2RlYXRocywgbmEucm0gPSBUUlVFKSwgIiBEZWF0aHMpIikpDQogICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgLCAiRGVhdGhzIikNCnBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9yZWNvdmVyZWQsIG5hLnJtID0gVFJVRSksICIgUmVjb3ZlcmVkKSIpKQ0KICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICwgIlJlY292ZXJpZXMiKQ0KDQpgYGANCg0KDQpgYGB7ciBwbG90X3VzX3JlZ2lvbnMsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCg0KIyBzYXZlIFVTIHJlZ2lvbnMgdG8gZmlsZXMNCg0KZm9yICh2YWwgaW4gYyhNaWR3ZXN0LCBTb3V0aCwgV2VzdCwgTm9ydGhlYXN0KSkgew0KICBkZi50ZW1wIDwtIGRhdGEgJT4lIA0KICAgIGZpbHRlcihSZWdpb24gPT0gIlVTQSIgJiBOYW1lID09IHZhbCkgJT4lIA0KICAgIGdyb3VwX2J5KE5hbWUpICU+JQ0KICAgIHNlbGVjdChOYW1lLCBMYXN0X1VwZGF0ZSwgQ29uZmlybWVkLCBEZWF0aHMsIFJlY292ZXJlZA0KICAgICAgICAgICAsIGRlbHRhX2NvbmZpcm1lZCwgZGVsdGFfZGVhdGhzLCBkZWx0YV9yZWNvdmVyZWQpICU+JQ0KICAgIGFycmFuZ2UoTGFzdF9VcGRhdGUpDQogIA0KICBwIDwtIHBsb3REZWx0YShkZi50ZW1wDQogICAgICAgICAgICAsIGNyZWF0ZUxhYmVsKGRmLnRlbXAkTmFtZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICAgICAgICAgICAgICAgLCBwYXN0ZTAoIigiLCBzdW0oZGYudGVtcCRkZWx0YV9jb25maXJtZWQsIG5hLnJtID0gVFJVRSksICIgQ29uZmlybWVkIENhc2VzKSIpKQ0KICAgICAgICAgICAgLCAiWSINCiAgICAgICAgICAgICwgIkNvbmZpcm1lZCIpDQogIGdnc2F2ZShmaWxlbmFtZT1wYXN0ZTAoIi4vaW1hZ2VzLyIsIGRmLnRlbXAkTmFtZSwgIl9jb25maXJtZWQucG5nIiksIGRldmljZT0icG5nIiwgcGxvdD1wKQ0KICANCiAgcCA8LSBwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfZGVhdGhzLCBuYS5ybSA9IFRSVUUpLCAiIERlYXRocykiKSkNCiAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgLCAiRGVhdGhzIikNCiAgZ2dzYXZlKGZpbGVuYW1lPXBhc3RlMCgiLi9pbWFnZXMvIiwgZGYudGVtcCROYW1lLCAiX2RlYXRocy5wbmciKSwgZGV2aWNlPSJwbmciLCBwbG90PXApDQp9DQoNCmBgYA0KDQpgYGB7ciBwbG90X2hhcHB5X3JlZ2lvbnMsIGVjaG8gPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCg0KIyBwbG90IHNlbGVjdGVkIHJlZ2lvbnMgKHRvcCAxMCBoYXBwaWVzdCBjb3VudHJpZXMpDQoNCmZvciAodmFsIGluIGMoIkZpbmxhbmQiLCAiRGVubWFyayIsICJTd2l0emVybGFuZCIsICJJY2VsYW5kIiwgIk5vcndheSINCiAgICAgICAgICAgICwgIk5ldGhlcmxhbmRzIiwgIlN3ZWRlbiIsICJOZXcgWmVhbGFuZCIsICJBdXN0cmlhIiwgIkx1eGVtYm91cmciKSkgew0KICBkZi50ZW1wIDwtIGRhdGEgJT4lIA0KICAgIGZpbHRlcihSZWdpb24gPT0gdmFsKSAlPiUgDQogICAgZ3JvdXBfYnkoUmVnaW9uKSAlPiUNCiAgICBzZWxlY3QoTmFtZSwgTGFzdF9VcGRhdGUsIENvbmZpcm1lZCwgRGVhdGhzLCBSZWNvdmVyZWQNCiAgICAgICAgICAgLCBkZWx0YV9jb25maXJtZWQsIGRlbHRhX2RlYXRocywgZGVsdGFfcmVjb3ZlcmVkKSAlPiUNCiAgICBhcnJhbmdlKExhc3RfVXBkYXRlKQ0KICANCiAgcCA8LSBwbG90RGVsdGEoZGYudGVtcA0KICAgICAgICAgICAgLCBjcmVhdGVMYWJlbChkZi50ZW1wJE5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgLCAibG9nMTAiDQogICAgICAgICAgICAgICAgICAgICAgICAgICwgcGFzdGUwKCIoIiwgc3VtKGRmLnRlbXAkZGVsdGFfY29uZmlybWVkLCBuYS5ybSA9IFRSVUUpLCAiIENvbmZpcm1lZCBDYXNlcykiKSkNCiAgICAgICAgICAgICwgIlkiDQogICAgICAgICAgICAsICJDb25maXJtZWQiKQ0KICBnZ3NhdmUoZmlsZW5hbWU9cGFzdGUwKCIuL2ltYWdlcy8iLCBkZi50ZW1wJE5hbWUsICJfY29uZmlybWVkLnBuZyIpLCBkZXZpY2U9InBuZyIsIHBsb3Q9cCkNCiAgDQogIHAgPC0gcGxvdERlbHRhKGRmLnRlbXANCiAgICAgICAgICAgICwgY3JlYXRlTGFiZWwoZGYudGVtcCROYW1lDQogICAgICAgICAgICAgICAgICAgICAgICAgICwgImxvZzEwIg0KICAgICAgICAgICAgICAgICAgICAgICAgICAsIHBhc3RlMCgiKCIsIHN1bShkZi50ZW1wJGRlbHRhX2RlYXRocywgbmEucm0gPSBUUlVFKSwgIiBEZWF0aHMpIikpDQogICAgICAgICAgICAsICJsb2cxMCINCiAgICAgICAgICAgICwgIkRlYXRocyIpDQogIGdnc2F2ZShmaWxlbmFtZT1wYXN0ZTAoIi4vaW1hZ2VzLyIsIGRmLnRlbXAkTmFtZSwgIl9kZWF0aHMucG5nIiksIGRldmljZT0icG5nIiwgcGxvdD1wKQ0KfQ0KDQpgYGANCg0KIyMjIEVuZCBOb3Rlcy4NCk1pbnV0ZXMgYmVmb3JlIGZpcnN0IHB1Ymxpc2hpbmcgdGhpcyByZXBvcnQgb24gMDMgQXByaWwgMjAyMCwgYW4gYXJ0aWNsZSBlbnRpdGxlZCBbUHJlcGFyaW5nIEZvciB0aGUgUGVha10oaHR0cHM6Ly93d3cuMTNuZXdzbm93LmNvbS9hcnRpY2xlL25ld3MvaGVhbHRoL2Nvcm9uYXZpcnVzL2hlcmVzLXdoZW4tY292aWQtMTktY291bGQtcGVhay1pbi10aGUtZG12LzI5MS00ZTE5YzU5Yi0wMzczLTQyMGMtYTUyMy1hMjA1YTdkNjBhYmUpIGFwcGVhcmVkIGluIG15IGVtYWlsLiAgV2hhdCBhIGNvaW5jaWRlbmNlLg0KDQpJJ3ZlIHJlY2VpdmVkIHF1ZXN0aW9ucyByZWdhcmRpbmcgdGhlIHZhbGlkaXR5IGFuZCBzb3VyY2Ugb2YgdGhlIGRhdGEgdXNlZCBpbiB0aGlzIHJlcG9ydC4gIFRoZSBzb3VyY2Ugb2YgdGhlIGRhdGEgaXMgZnJvbSB0aGUgW0NPVklELTE5IFN1cnZlaWxsYW5jZSBEYXNoYm9hcmRdKGh0dHBzOi8vbnNzYWMuZ2l0aHViLmlvL2NvdmlkLTE5L2Rhc2hib2FyZC8jZmFxKS4gIFRoZXkgYWdncmVnYXRlZCB0aGUgZGF0YSBmcm9tIG51bWVyb3VzIHJlbGlhYmxlIHNvdXJjZXMuDQoNCioqQWRkaXRpb25hbCBwbG90cy4qKiAgQ2hlY2sgb3V0IHBsb3RzIGZyb20gb25lIG9mIHRoZXNlIG90aGVyIFtgciBsZW5ndGgodW5pcXVlKGdzdWIoIihfY29uZmlybWVkfF9kZWF0aHMpIiwgIiIsIGxpc3QuZmlsZXMocGF0aCA9ICIuL2ltYWdlcyIsIHBhdHRlcm49IlxcLnBuZyIpKSkpYCAgYXJlYXMgb2YgaW50ZXJlc3RdKGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NoL2s0cWc5bnc1eXdmazRneS9BQUN4QVpfSWRta1AtbzAzT0FjZC1xd2ZhP2RsPTApLiBbSWYgdGhlIGxpbmsgZmFpbHMgdG8gcmVuZGVyLCByaWdodC1jbGljayBvbiBpdCBhbmQgb3BlbiBpbiBhIG5ldyB3aW5kb3ddLg0KDQpcIA0KXCAgDQpcIA0KDQpgYGANCkV2ZXJ5IGF0dGVtcHQgd2FzIG1hZGUgdG8gY29udmV5IHZhbGlkIGFuZCBhY2N1cmF0ZSByZXN1bHRzIGJhc2VkIHVwb24gdGhlIGRhdGEgcHJvdmlkZWQuDQoNClN0YXkgd2VsbCBhbmQgYmUgc2FmZS4NCg0KYGBgDQoNClwgDQpcICANClwgDQoNCiMjIyMjIyBSZXBvcnQgZ2VuZXJhdGVkOiAgYHIgU3lzLnRpbWUoKWANCg0KDQpgYGB7ciBzY3JhdGNocGFkLCBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGV2YWw9RkFMU0V9DQoNCiMgIGZpbHRlcihOYW1lICVpbiUgYyhNaWR3ZXN0LCBTb3V0aCwgV2VzdCwgTm9ydGhlYXN0KSAmIGNhc2VfdHlwZSA9PSAnQ29uZmlybWVkJykgJT4lDQoNCmRhdGEgPC0gbXV0YXRlX2F0KGRhdGEsIHZhcnMoJ05hbWUnLCAnZ3JvdXAnKSwgYXMuZmFjdG9yKQ0KDQojIFNldCBhIG51bWJlciBvZiAnZW1wdHkgYmFyJyB0byBhZGQgYXQgdGhlIGVuZCBvZiBlYWNoIGdyb3VwDQplbXB0eV9iYXIgPC0gNA0KdG9fYWRkIDwtIGRhdGEuZnJhbWUoIG1hdHJpeChOQSwgZW1wdHlfYmFyKm5sZXZlbHMoZGF0YSRncm91cCksIG5jb2woZGF0YSkpICkNCmNvbG5hbWVzKHRvX2FkZCkgPC0gY29sbmFtZXMoZGF0YSkNCnRvX2FkZCRncm91cCA8LSByZXAobGV2ZWxzKGRhdGEkZ3JvdXApLCBlYWNoPWVtcHR5X2JhcikNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdG9fYWRkKQ0KZGF0YSA8LSBkYXRhICU+JSBhcnJhbmdlKGdyb3VwKQ0KZGF0YSRpZCA8LSBzZXEoMSwgbnJvdyhkYXRhKSkNCiANCiMgR2V0IHRoZSBuYW1lIGFuZCB0aGUgeSBwb3NpdGlvbiBvZiBlYWNoIGxhYmVsDQpsYWJlbF9kYXRhIDwtIGRhdGENCm51bWJlcl9vZl9iYXIgPC0gbnJvdyhsYWJlbF9kYXRhKQ0KYW5nbGUgPC0gOTAgLSAzNjAgKiAobGFiZWxfZGF0YSRpZC0wLjUpIC9udW1iZXJfb2ZfYmFyICAgICAjIEkgc3Vic3RyYWN0IDAuNSBiZWNhdXNlIHRoZSBsZXR0ZXIgbXVzdCBoYXZlIHRoZSBhbmdsZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBiYXJzLiBOb3QgZXh0cmVtZSByaWdodCgxKSBvciBleHRyZW1lIGxlZnQgKDApDQpsYWJlbF9kYXRhJGhqdXN0IDwtIGlmZWxzZSggYW5nbGUgPCAtOTAsIDEsIDApDQpsYWJlbF9kYXRhJGFuZ2xlIDwtIGlmZWxzZShhbmdsZSA8IC05MCwgYW5nbGUrMTgwLCBhbmdsZSkNCiANCiMgTWFrZSB0aGUgcGxvdA0KcCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHg9YXMuZmFjdG9yKGlkKSwgeT12YWx1ZSwgZmlsbD1ncm91cCkpICsgICAgICAgIyBOb3RlIHRoYXQgaWQgaXMgYSBmYWN0b3IuIElmIHggaXMgbnVtZXJpYywgdGhlcmUgaXMgc29tZSBzcGFjZSBiZXR3ZWVuIHRoZSBmaXJzdCBiYXINCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBhbHBoYT0wLjUpICsNCiAgeWxpbSgtMTAwLDEyMCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90Lm1hcmdpbiA9IHVuaXQocmVwKC0xLDQpLCAiY20iKSANCiAgKSArDQogIGNvb3JkX3BvbGFyKCkgKyANCiAgZ2VvbV90ZXh0KGRhdGE9bGFiZWxfZGF0YSwgYWVzKHg9aWQsIHk9dmFsdWUrMTAsIGxhYmVsPU5hbWUsIGhqdXN0PWhqdXN0KSwgY29sb3I9ImJsYWNrIiwgZm9udGZhY2U9ImJvbGQiLGFscGhhPTAuNiwgc2l6ZT0yLjUsIGFuZ2xlPSBsYWJlbF9kYXRhJGFuZ2xlLCBpbmhlcml0LmFlcyA9IEZBTFNFICkgDQogDQpwDQoNCg0KIyAtLS0tLS0tLS0tLS0tDQoNCiMgQ3JlYXRlIGRhdGFzZXQNCmRhdGEgPC0gZGF0YS5mcmFtZSgNCiAgaW5kaXZpZHVhbD1wYXN0ZSggIk1pc3RlciAiLCBzZXEoMSw2MCksIHNlcD0iIiksDQogIGdyb3VwPWMoIHJlcCgnQScsIDEwKSwgcmVwKCdCJywgMzApLCByZXAoJ0MnLCAxNCksIHJlcCgnRCcsIDYpKSAsDQogIHZhbHVlPXNhbXBsZSggc2VxKDEwLDEwMCksIDYwLCByZXBsYWNlPVQpDQopDQogDQojIFNldCBhIG51bWJlciBvZiAnZW1wdHkgYmFyJyB0byBhZGQgYXQgdGhlIGVuZCBvZiBlYWNoIGdyb3VwDQplbXB0eV9iYXIgPC0gNA0KdG9fYWRkIDwtIGRhdGEuZnJhbWUoIG1hdHJpeChOQSwgZW1wdHlfYmFyKm5sZXZlbHMoZGF0YSRncm91cCksIG5jb2woZGF0YSkpICkNCmNvbG5hbWVzKHRvX2FkZCkgPC0gY29sbmFtZXMoZGF0YSkNCnRvX2FkZCRncm91cCA8LSByZXAobGV2ZWxzKGRhdGEkZ3JvdXApLCBlYWNoPWVtcHR5X2JhcikNCmRhdGEgPC0gcmJpbmQoZGF0YSwgdG9fYWRkKQ0KZGF0YSA8LSBkYXRhICU+JSBhcnJhbmdlKGdyb3VwKQ0KZGF0YSRpZCA8LSBzZXEoMSwgbnJvdyhkYXRhKSkNCiANCiMgR2V0IHRoZSBuYW1lIGFuZCB0aGUgeSBwb3NpdGlvbiBvZiBlYWNoIGxhYmVsDQpsYWJlbF9kYXRhIDwtIGRhdGENCm51bWJlcl9vZl9iYXIgPC0gbnJvdyhsYWJlbF9kYXRhKQ0KYW5nbGUgPC0gOTAgLSAzNjAgKiAobGFiZWxfZGF0YSRpZC0wLjUpIC9udW1iZXJfb2ZfYmFyICAgICAjIEkgc3Vic3RyYWN0IDAuNSBiZWNhdXNlIHRoZSBsZXR0ZXIgbXVzdCBoYXZlIHRoZSBhbmdsZSBvZiB0aGUgY2VudGVyIG9mIHRoZSBiYXJzLiBOb3QgZXh0cmVtZSByaWdodCgxKSBvciBleHRyZW1lIGxlZnQgKDApDQpsYWJlbF9kYXRhJGhqdXN0IDwtIGlmZWxzZSggYW5nbGUgPCAtOTAsIDEsIDApDQpsYWJlbF9kYXRhJGFuZ2xlIDwtIGlmZWxzZShhbmdsZSA8IC05MCwgYW5nbGUrMTgwLCBhbmdsZSkNCiANCiMgTWFrZSB0aGUgcGxvdA0KcCA8LSBnZ3Bsb3QoZGF0YSwgYWVzKHg9YXMuZmFjdG9yKGlkKSwgeT12YWx1ZSwgZmlsbD1ncm91cCkpICsgICAgICAgIyBOb3RlIHRoYXQgaWQgaXMgYSBmYWN0b3IuIElmIHggaXMgbnVtZXJpYywgdGhlcmUgaXMgc29tZSBzcGFjZSBiZXR3ZWVuIHRoZSBmaXJzdCBiYXINCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBhbHBoYT0wLjUpICsNCiAgeWxpbSgtMTAwLDEyMCkgKw0KICB0aGVtZV9taW5pbWFsKCkgKw0KICB0aGVtZSgNCiAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgYXhpcy50ZXh0ID0gZWxlbWVudF9ibGFuaygpLA0KICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksDQogICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICBwbG90Lm1hcmdpbiA9IHVuaXQocmVwKC0xLDQpLCAiY20iKSANCiAgKSArDQogIGNvb3JkX3BvbGFyKCkgKyANCiAgZ2VvbV90ZXh0KGRhdGE9bGFiZWxfZGF0YSwgYWVzKHg9aWQsIHk9dmFsdWUrMTAsIGxhYmVsPWluZGl2aWR1YWwsIGhqdXN0PWhqdXN0KSwgY29sb3I9ImJsYWNrIiwgZm9udGZhY2U9ImJvbGQiLGFscGhhPTAuNiwgc2l6ZT0yLjUsIGFuZ2xlPSBsYWJlbF9kYXRhJGFuZ2xlLCBpbmhlcml0LmFlcyA9IEZBTFNFICkgDQogDQpwDQopDQoNCg0KbXlEZiA8LSBkYXRhICU+JSBmaWx0ZXIoTmFtZSA9PSAiVmlyZ2luaWEiKSAlPiUgYXJyYW5nZShMYXN0X1VwZGF0ZSkgJT4lIHVuZ3JvdXAoKSAlPiUgc2VsZWN0KENvbmZpcm1lZCkNCm15RGYgPC0gRGF0YUNvbWJpbmU6OnNsaWRlKG15RGYsICJDb25maXJtZWQiLCBOZXdWYXIgPSAieExhZzEiLCBzbGlkZUJ5ID0gLTEpDQoNCm15REYgPC0gZGF0YSAlPiUNCiAgICAgICAgICAgIGZpbHRlcihOYW1lICVpbiUgYyhOb3J0aGVhc3QpKSAlPiUNCiAgICAgICAgICAgIGdyb3VwX2J5KFJlZ2lvbiwgTmFtZSkgJT4lDQogICAgICAgICAgICBhcnJhbmdlKFJlZ2lvbiwgTmFtZSwgTGFzdF9VcGRhdGUpICU+JQ0KICAgICAgICAgICAgdW5ncm91cCgpICU+JQ0KICAgICAgICAgICAgc2VsZWN0KE5hbWUsIExhc3RfVXBkYXRlLCBkZWx0YV9jb25maXJtZWQpICU+JQ0KICAgICAgICAgICAgYXJyYW5nZShOYW1lLCBMYXN0X1VwZGF0ZSkgJT4lDQogICAgICAgICAgICByZW5hbWUoRGF0ZT1MYXN0X1VwZGF0ZSwgQ2hhbmdlPWRlbHRhX2NvbmZpcm1lZCkNCg0KbXlERiRyb3dfbnVtIDwtIHNlcS5pbnQobnJvdyhteURGKSkgIA0KDQpnZXRBSU9fc3RhcnRfaWR4IDwtIGZ1bmN0aW9uKGRmLCBuYW1lKSB7DQogIGRmICU+JSBmaWx0ZXIoTmFtZSA9PSBuYW1lKSAlPiUgc2xpY2UoMSkgJT4lIHB1bGwocm93X251bSkNCn0NCg0KZ2V0QUlPX2VuZF9pZHggPC0gZnVuY3Rpb24oZGYsIG5hbWUpIHsNCiAgZGYgJT4lIGZpbHRlcihOYW1lID09IG5hbWUpICU+JSBzbGljZShuKCkpICU+JSBwdWxsKHJvd19udW0pDQp9DQoNCmthYmxlKG15REYgJT4lIHNlbGVjdChEYXRlLCBDaGFuZ2UpDQogICAgICAsIGNhcHRpb24gPSAiQ29uZmlybWVkIENhc2VzIFRyZW5kIEZvciBOb3J0aGVhc3QgUmVnaW9uIikgJT4lDQogIGthYmxlX3N0eWxpbmcoYm9vdHN0cmFwX29wdGlvbnMgPSBjKCJzdHJpcGVkIiwgImhvdmVyIiksIGZ1bGxfd2lkdGggPSBGKSAlPiUNCiAgcGFja19yb3dzKCJDb25uZWN0aWN1dCINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiQ29ubmVjdGljdXQiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiQ29ubmVjdGljdXQiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJNYWluZSINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiTWFpbmUiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiTWFpbmUiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJNYXNzYWNodXNldHRzIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJNYXNzYWNodXNldHRzIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIk1hc3NhY2h1c2V0dHMiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJOZXcgSGFtcHNoaXJlIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJOZXcgSGFtcHNoaXJlIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIk5ldyBIYW1wc2hpcmUiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJSaG9kZSBJc2xhbmQiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIlJob2RlIElzbGFuZCIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJSaG9kZSBJc2xhbmQiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJWZXJtb250Ig0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJWZXJtb250IikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIlZlcm1vbnQiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJOZXcgSmVyc2V5Ig0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJOZXcgSmVyc2V5IikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIk5ldyBKZXJzZXkiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJOZXcgWW9yayINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiTmV3IFlvcmsiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiTmV3IFlvcmsiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJQZW5uc3lsdmFuaWEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIlBlbm5zeWx2YW5pYSIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJQZW5uc3lsdmFuaWEiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJQdWVydG8gUmljbyINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiUHVlcnRvIFJpY28iKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiUHVlcnRvIFJpY28iKQ0KICAgICAgICAgICAgKSAlPiUNCiAgcGFja19yb3dzKCJVUyBWaXJnaW4gSXNsYW5kcyINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiVVMgVmlyZ2luIElzbGFuZHMiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiVVMgVmlyZ2luIElzbGFuZHMiKQ0KICAgICAgICAgICAgKSAlPiUNCiAgc2Nyb2xsX2JveChoZWlnaHQgPSAiNDAwcHgiKQ0KDQoNCm15REYuMSA8LSBteURGICU+JSBmaWx0ZXIoTmFtZSAlaW4lIGMoTWlkd2VzdCkpDQpteURGLjEgPC0gbXlERiAlPiUgZmlsdGVyKE5hbWUgJWluJSBjKFNvdXRoKSkNCm15REYuMSA8LSBteURGICU+JSBmaWx0ZXIoTmFtZSAlaW4lIGMoV2VzdCkpDQpteURGLjEgPC0gbXlERiAlPiUgZmlsdGVyKE5hbWUgJWluJSBjKE5vcnRoZWFzdCkpDQoNCmthYmxlKG15REYgJT4lIHNlbGVjdChMYXN0X1VwZGF0ZSwgZGVsdGFfY29uZmlybWVkKQ0KICAgICAgLCBjYXB0aW9uID0gIlRyZW5kIG9mIENvbmZpcm1lZCBDYXNlcyBGb3IgVVMgQXJlYXMgb2YgSW50ZXJlc3QiKSAlPiUNCiAga2FibGVfc3R5bGluZyhib290c3RyYXBfb3B0aW9ucyA9IGMoInN0cmlwZWQiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEYpICU+JQ0KICBwYWNrX3Jvd3MoIkFsYWJhbWEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkFsYWJhbWEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiQWxhYmFtYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkFsYXNrYSINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiQWxhc2thIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIkFsYXNrYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkFyaXpvbmEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkFyaXpvbmEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiQXJpem9uYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkFya2Fuc2FzIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJBcmthbnNhcyIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJBcmthbnNhcyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkNhbGlmb3JuaWEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkNhbGlmb3JuaWEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiQ2FsaWZvcm5pYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkNvbG9yYWRvIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJDb2xvcmFkbyIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJDb2xvcmFkbyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkNvbm5lY3RpY3V0Ig0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJDb25uZWN0aWN1dCIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJDb25uZWN0aWN1dCIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkRlbGF3YXJlIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJEZWxhd2FyZSIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJEZWxhd2FyZSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkRpc3RyaWN0IG9mIENvbHVtYmlhIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJEaXN0cmljdCBvZiBDb2x1bWJpYSIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJEaXN0cmljdCBvZiBDb2x1bWJpYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkZsb3JpZGEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkZsb3JpZGEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiRmxvcmlkYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkdlb3JnaWEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkdlb3JnaWEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiR2VvcmdpYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkd1YW0iDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkd1YW0iKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiR3VhbSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkhhd2FpaSINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiSGF3YWlpIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIkhhd2FpaSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIklkYWhvIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJJZGFobyIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJJZGFobyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIklsbGlub2lzIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJJbGxpbm9pcyIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJJbGxpbm9pcyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkluZGlhbmEiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIkluZGlhbmEiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiSW5kaWFuYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIklvd2EiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIklvd2EiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiSW93YSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkthbnNhcyINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiS2Fuc2FzIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIkthbnNhcyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIktlbnR1Y2t5Ig0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJLZW50dWNreSIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJLZW50dWNreSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIkxvdWlzaWFuYSINCiAgICAgICAgICAgICwgZ2V0QUlPX3N0YXJ0X2lkeChteURGLCAiTG91aXNpYW5hIikNCiAgICAgICAgICAgICwgZ2V0QUlPX2VuZF9pZHgobXlERiwgIkxvdWlzaWFuYSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIk1haW5lIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJNYWluZSIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJNYWluZSIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIk1hcnlsYW5kIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJNYXJ5bGFuZCIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJNYXJ5bGFuZCIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIk1hc3NhY2h1c2V0dHMiDQogICAgICAgICAgICAsIGdldEFJT19zdGFydF9pZHgobXlERiwgIk1hc3NhY2h1c2V0dHMiKQ0KICAgICAgICAgICAgLCBnZXRBSU9fZW5kX2lkeChteURGLCAiTWFzc2FjaHVzZXR0cyIpDQogICAgICAgICAgICApICU+JQ0KICBwYWNrX3Jvd3MoIk1pY2hpZ2FuIg0KICAgICAgICAgICAgLCBnZXRBSU9fc3RhcnRfaWR4KG15REYsICJNaWNoaWdhbiIpDQogICAgICAgICAgICAsIGdldEFJT19lbmRfaWR4KG15REYsICJNaWNoaWdhbiIpDQogICAgICAgICAgICApICU+JQ0KICBzY3JvbGxfYm94KGhlaWdodCA9ICI0MDBweCIpICU+JQ0KICBmb290bm90ZShnZW5lcmFsID0gIlRCRCIpDQoNCmBgYA==